fitting.profile module

Module with functions to fit profiles, such as bunch line densities

  • TODO: improve treatment of the baseline

  • TODO: improve the implementation of options as dict and **kwargs

  • TODO: For all fitting function, add formula and default initial guess for the fit

  • TODO: detail options for each function, especially for fitting

  • TODO: include the changes from interfaces.beam.analytic_distribution

Authors

Alexandre Lasheen, Juan F. Esteban Mueller, Markus Schwarz

blond_common.fitting.profile.FWHM(time_array, data_array, level=0.5, fitOpt=None, plotOpt=None)[source]

Function to compute the Full-Width at Half Maximum for a given profile. The Maximum corresponds to the numerical maximum of the data_array.

TODO: add an option to use peakValue to get the Maximum, to have the option to get an averaged value of the maximum (e.g. at >95%)

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

  • level (float) – Optional: The ratio from the maximum for which the width of the profile is returned Default is 0.5, as for Half of the Maximum

Returns

  • center (float) – The center of the Width at Half Maximum, in the units of time_array

  • fwhm (float) – The Full Width at Half Maximum, in the units of time_array NB: if the “level” option is set to any other value than 0.5, the output corresponds to the full width at the specified “level” of the maximum

Example

>>> ''' We generate a Gaussian distribution and get its FWHM '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import gaussian
>>> from blond_common.fitting.profile import FWHM
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = gaussian(time_array, *[amplitude, position, length])
>>>
>>> center, fwhm = FWHM(time_array, data_array)
class blond_common.fitting.profile.FitOptions(bunchLengthFactor=1.0, bunchPositionOffset=0.0, nPointsNoise=3, fitInitialParameters=None, bounds=None, fittingRoutine='curve_fit', method='Powell', options=None, residualFunction=None, extraOptions=None)[source]

Bases: object

class blond_common.fitting.profile.PlotOptions(figname='Bunch profile', clf=True, interactive=True, legend=True)[source]

Bases: object

blond_common.fitting.profile.RMS(time_array, data_array, fitOpt=None)[source]

Function to compute the mean and root mean square (RMS) of a profile.

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

Returns

  • mean (float) – The mean position of the profile, in time_array units

  • rms (float) – The rms length of the profile, in time_array units

Example

>>> ''' We generate a Gaussian distribution and get mean and rms '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import gaussian
>>> from blond_common.fitting.profile import RMS
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = gaussian(time_array, *[amplitude, position, length])
>>>
>>> mean_position, rms_length = RMS(time_array, data_array)
blond_common.fitting.profile.arbitrary_profile_fit(time_array, data_array, profile_fit_function, fitOpt, plotOpt=None)[source]

Function to fit a given profile with a user defined arbitrary profile.

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

  • profile_fit_function (function) – User defined function to fit the input data_array. The function should have the input arguments (time_array, *fit_parameters) and returns a profile_array which will be compared to data_array

Returns

fitted_parameters – The fitted parameters, in the same order as defined by the user in his profile_fit_function

Return type

np.array

Example

>>> ''' We generate a Gaussian profile and fit it, in this example we use
>>> the same Gaussian function used to generate the input profile '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import Gaussian
>>> from blond_common.fitting.profile import arbitrary_profile_fit
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = Gaussian(
>>>    time_array, *[amplitude, position, length])
>>>
>>> amplitude, position, full_length = arbitrary_profile_fit(
>>>    time_array, data_array, Gaussian)
blond_common.fitting.profile.binomial_amplitude2_fit(time_array, data_array, fitOpt=None, plotOpt=None)[source]

Function to fit a given profile with a Binomial profile, with exponent 2 (binomial density in phase space).

The function returns the parameters of a Binomial amplitude profile with exponent 2 as defined in blond_common.interfaces.beam.analytic_distribution.binomialAmplitude2

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

Returns

  • amplitude (float) – The amplitude of the profile, in data_array units

  • position (float) – The central position of the profile, in time_array units

  • full_length (float) – The full length of the profile, in time_array units

Example

>>> ''' We generate a Binomial amplitude 2 distribution and fit it '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import binomialAmplitude2
>>> from blond_common.fitting.profile import binomial_amplitude2_fit
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = binomial_amplitude2(
>>>    time_array, *[amplitude, position, length, exponent])
>>>
>>> amplitude, position, full_length = binomial_amplitude2_fit(
>>>    time_array, data_array)
blond_common.fitting.profile.binomial_amplitudeN_fit(time_array, data_array, fitOpt=None, plotOpt=None)[source]

Function to fit a given profile with a Binomial profile (binomial amplitude in phase space).

The function returns the parameters of a Binomial profile as defined in blond_common.interfaces.beam.analytic_distribution.binomialAmplitudeN

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

Returns

  • amplitude (float) – The amplitude of the profile, in data_array units

  • position (float) – The central position of the profile, in time_array units

  • full_length (float) – The full length of the profile, in time_array units

  • exponent (float) – The exponent of the Binomial profile

Example

>>> ''' We generate a Binomial distribution and fit it '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import binomialAmplitudeN
>>> from blond_common.fitting.profile import binomial_amplitudeN_fit
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>> exponent = 2.5
>>>
>>> data_array = binomialAmplitudeN(
>>>    time_array, *[amplitude, position, length, exponent])
>>>
>>> amplitude, position, full_length, exponent = binomial_amplitudeN_fit(
>>>    time_array, data_array)
blond_common.fitting.profile.binomial_from_width_LUT_generation(levels=[0.8, 0.2], exponent_min=0.5, exponent_max=10.0, exponent_distrib='logspace', exponent_npoints=100, exponent_array=None)[source]

Function to create the lookup table (LUT) for the binomial_from_width_ratio function.

TODO: return error if exponent_min<0.5

Parameters
  • levels (list or np.array with 2 elements) – Optional: The levels at which the width of the profile is used to evaluate the parameters of the fitting binomial profile. Default is [0.8, 0.2]

  • exponent_min (float) – Optional: The smallest exponent to consider for the binomial profile Default is 0.5 (NB: cannot be smaller than 0.5)

  • exponent_max (float) – Optional: The largest exponent to consider for the binomial profile Default is 10. (NB: a higher value is necessary for Gaussian profiles)

  • exponent_distrib (str) –

    Optional: Define how the exponent array of the LUT is distributed The possible settings are:

    • logspace: uses np.logspace (default)

    • linspace: uses np.linspace

  • exponent_npoints (int) – Optional: The number of points for the lookup table Default is 100

  • exponent_array (list or np.array) – Optional: This option replaces and discards all the other optional inputs

Returns

  • exponent_array (np.array) – The expected binomial profile exponent corresponding to the ratio of the Full-Widths for the specified levels

  • ratio_FW (np.array) – The ratio of the Full-Widths corresponding to the exponent_array for the specified levels

  • levels (list) – The levels at which the width of the profile is used to evaluate the parameters of the fitting binomial profile.

Example

>>> ''' We generate a Gaussian distribution and get mean and rms '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import gaussian
>>> from blond_common.fitting.profile import binomial_from_width_ratio
>>> from blond_common.fitting.profile import _binomial_from_width_LUT_generation
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = gaussian(time_array, *[amplitude, position, length])
>>>
>>> position, full_length, exponent = binomial_from_width_ratio(
>>>    time_array, data_array)
>>>
>>> # For a gaussian profile, the exponent of the corresponding binomial
>>> # profile is infinity, higher values of exponents are required in the
>>> # lookup table to have a better evaluation.
>>>
>>> new_LUT = _binomial_from_width_LUT_generation(
>>>    exponentMin=100, exponentMax=10000)
>>>
>>> position, full_length, exponent = binomial_from_width_ratio(
>>>    time_array, data_array, ratio_LUT=new_LUT)
blond_common.fitting.profile.binomial_from_width_ratio(time_array, data_array, levels=[0.8, 0.2], ratio_LUT=None, fitOpt=None, plotOpt=None)[source]

Function to evaluate the parameters of a binomial function, as defined in blond_common.interfaces.beam.analytic_distribution.binomial_amplitude, by using the width of the profile at two different levels as input.

The function returns the parameters of a binomial profile as defined in blond_common.interfaces.beam.analytic_distribution.binomial_amplitude

TODO: check if rms should be in the return list as well

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

  • levels (list or np.array with 2 elements) – Optional: The levels at which the width of the profile is used to evaluate the parameters of the fitting binomial profile. Default is [0.8, 0.2]

  • ratio_LUT (output from _binomial_from_width_LUT_generation) – Optional: The function uses internally a lookup table obtained from the _binomial_from_width_LUT_generation function to evaluate the binomial parameters. The lookup table can be pre-calculated and passed directly for efficiency purposes, if the function is used several times in a row.

Returns

  • amplitude (float) – The amplitude of the binomial profile, in data_array units

  • position (float) – The central position of the profile, assumed to be binomial, in time_array units

  • full_length (float) – The full length of the profile, assumed to be binomial, in time_array units

  • exponent (float) – The exponent of the profile, assumed to be binomial

Example

>>> ''' We generate a Gaussian distribution and get mean and rms '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import gaussian
>>> from blond_common.fitting.profile import binomial_from_width_ratio
>>> from blond_common.fitting.profile import _binomial_from_width_LUT_generation
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = gaussian(time_array, *[amplitude, position, length])
>>>
>>> amplitude, position, full_length, exponent = binomial_from_width_ratio(
>>>    time_array, data_array)
>>>
>>> # For a gaussian profile, the exponent of the corresponding binomial
>>> # profile is infinity, higher values of exponents are required in the
>>> # lookup table to have a better evaluation.
>>>
>>> new_LUT = _binomial_from_width_LUT_generation(
>>>    exponentMin=100, exponentMax=10000)
>>>
>>> amplitude, position, full_length, exponent = binomial_from_width_ratio(
>>>    time_array, data_array, ratio_LUT=new_LUT)
blond_common.fitting.profile.cosine_fit(time_array, data_array, fitOpt=None, plotOpt=None)[source]

Function to fit a given profile with a Cosine profile.

The function returns the parameters of a Cosine profile as defined in blond_common.interfaces.beam.analytic_distribution.cosine

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

Returns

  • amplitude (float) – The amplitude of the profile, in data_array units

  • position (float) – The central position of the profile, in time_array units

  • full_length (float) – The full length of the profile, in time_array units

Example

>>> ''' We generate a Cosine profile and fit it '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import cosine
>>> from blond_common.fitting.profile import cosine_fit
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = cosine(
>>>    time_array, *[amplitude, position, length])
>>>
>>> amplitude, position, full_length = cosine_fit(
>>>    time_array, data_array)
blond_common.fitting.profile.cosine_squared_fit(time_array, data_array, fitOpt=None, plotOpt=None)[source]

Function to fit a given profile with a Cosine Squared profile.

The function returns the parameters of a Cosine Squared profile as defined in blond_common.interfaces.beam.analytic_distribution.cosineSquared

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

Returns

  • amplitude (float) – The amplitude of the profile, in data_array units

  • position (float) – The central position of the profile, in time_array units

  • full_length (float) – The full length of the profile, in time_array units

Example

>>> ''' We generate a Cosine profile and fit it '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import cosineSquared
>>> from blond_common.fitting.profile import cosine_squared_fit
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = cosineSquared(
>>>    time_array, *[amplitude, position, length])
>>>
>>> amplitude, position, full_length = cosine_squared_fit(
>>>    time_array, data_array)
blond_common.fitting.profile.gaussian_fit(time_array, data_array, fitOpt=None, plotOpt=None)[source]

Function to fit a given profile with a Gaussian profile.

The function returns the parameters of a Gaussian profile as defined in blond_common.interfaces.beam.analytic_distribution.Gaussian

TODO: update with the new analytic_distribution implementation

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

Returns

  • amplitude (float) – The amplitude of the profile, in data_array units

  • position (float) – The central position of the profile, in time_array units

  • rms_length (float) – The rms length of the profile, in time_array units

Example

>>> ''' We generate a Gaussian profile and fit it '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import gaussian
>>> from blond_common.fitting.profile import gaussian_fit
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = gaussian(time_array, *[amplitude, position, length])
>>>
>>> amplitude, position, rms_length = gaussian_fit(
>>>    time_array, data_array)
blond_common.fitting.profile.generalized_gaussian_fit(time_array, data_array, fitOpt=None, plotOpt=None)[source]

Function to fit a given profile with a Generalized Gaussian profile.

The function returns the parameters of a Generalized Gaussian profile as defined in blond_common.interfaces.beam.analytic_distribution.generalizedGaussian

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

Returns

  • amplitude (float) – The amplitude of the profile, in data_array units

  • position (float) – The central position of the profile, in time_array units

  • rms_length (float) – The rms length of the profile, in time_array units

  • exponent (float) – The exponent of the Generalized Gaussian profile

Example

>>> ''' We generate a Generalized Gaussian profile and fit it '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import generalizedGaussian
>>> from blond_common.fitting.profile import generalized_gaussian_fit
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>> exponent = 2.5
>>>
>>> data_array = generalizedGaussian(
>>>    time_array, *[amplitude, position, length, exponent])
>>>
>>> amplitude, position, rms_length, exponent = generalized_gaussian_fit(
>>>    time_array, data_array)
blond_common.fitting.profile.integrated_profile(time_array, data_array, method='sum', fitOpt=None, plotOpt=None)[source]

Function to compute the integrated bunch profile.

TODO: use the blond_common.maths package for integration functions

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

  • method (str) –

    The method used to do the integration, the possible inputs are:

    • ”sum”: uses np.sum (default)

    • ”trapz”: uses np.trapz

Returns

integrated_value – The integrated bunch profile, in the units of time_array*data_array

Return type

float

Example

>>> ''' We generate a Gaussian distribution and get the integrated
>>> profile '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import gaussian
>>> from blond_common.fitting.profile import integrated_profile
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = gaussian(time_array, *[amplitude, position, length])
>>>
>>> integrated_value = integrated_profile(time_array, data_array)
blond_common.fitting.profile.parabolic_amplitude_fit(time_array, data_array, fitOpt=None, plotOpt=None)[source]

Function to fit a given profile with a Parabolic profile (parabolic amplitude density in phase space).

The function returns the parameters of a Parabolic amplitude profile as defined in blond_common.interfaces.beam.analytic_distribution.parabolicAmplitude

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

Returns

  • amplitude (float) – The amplitude of the profile, in data_array units

  • position (float) – The central position of the profile, in time_array units

  • full_length (float) – The full length of the profile, in time_array units

Example

>>> ''' We generate a Parabolic amplitude distribution and fit it '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import parabolicAmplitude
>>> from blond_common.fitting.profile import parabolic_amplitude_fit
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = parabolicAmplitude(
>>>    time_array, *[amplitude, position, length, exponent])
>>>
>>> amplitude, position, full_length = parabolic_amplitude_fit(
>>>    time_array, data_array)
blond_common.fitting.profile.parabolic_line_fit(time_array, data_array, fitOpt=None, plotOpt=None)[source]

Function to fit a given profile with a Parabolic profile (parabolic line density).

The function returns the parameters of a Parabolic profile as defined in blond_common.interfaces.beam.analytic_distribution.parabolicLine

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

Returns

  • amplitude (float) – The amplitude of the profile, in data_array units

  • position (float) – The central position of the profile, in time_array units

  • full_length (float) – The full length of the profile, in time_array units

Example

>>> ''' We generate a Parabolic profile and fit it '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import parabolicLine
>>> from blond_common.fitting.profile import parabolic_line_fit
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = parabolicLine(
>>>    time_array, *[amplitude, position, length, exponent])
>>>
>>> amplitude, position, full_length = parabolic_line_fit(
>>>    time_array, data_array)
blond_common.fitting.profile.peak_value(time_array, data_array, level=1.0, fitOpt=None, plotOpt=None)[source]

Function to get the peak amplitude of the profile. If a “level” is passed, the function averages the points above the speicifed “level”.

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

  • level (float) – Optional: The ratio of the maximum above which the profile is averaged Default is 1.0 to return the numerical maximum

Returns

  • position (float) – The position of the peak value, in the units of time_array

  • amplitude (float) – The peak amplitude, in the units of the data_array NB: if the “level” option is set to any other value than 1.0, the output corresponds to the peak, averaged for the points above the specified “level” of the maximum

Example

>>> ''' We generate a Gaussian distribution and get its peak amplitude '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import gaussian
>>> from blond_common.fitting.profile import peak_value
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = gaussian(time_array, *[amplitude, position, length])
>>>
>>> peak_position, amplitude = peak_value(time_array, data_array)
blond_common.fitting.profile.waterbag_fit(time_array, data_array, fitOpt=None, plotOpt=None)[source]

Function to fit a given profile with a Waterbag profile.

The function returns the parameters of a Waterbag profile as defined in blond_common.interfaces.beam.analytic_distribution.waterbag

Parameters
  • time_array (list or np.array) – The input time

  • data_array (list or np.array) – The input profile

Returns

  • amplitude (float) – The amplitude of the profile, in data_array units

  • position (float) – The central position of the profile, in time_array units

  • full_length (float) – The full length of the profile, in time_array units

Example

>>> ''' We generate a Waterbag profile and fit it '''
>>> import numpy as np
>>> from blond_common.interfaces.beam.analytic_distribution import waterbag
>>> from blond_common.fitting.profile import waterbag_fit
>>>
>>> time_array = np.arange(0, 25e-9, 0.1e-9)
>>>
>>> amplitude = 1.
>>> position = 13e-9
>>> length = 2e-9
>>>
>>> data_array = waterbag(
>>>    time_array, *[amplitude, position, length, exponent])
>>>
>>> amplitude, position, full_length = waterbag_fit(
>>>    time_array, data_array)