jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def PsiWiggle(self, N, absorber, donor, x=None, t=None):
        """
        Equation 2.19 in the manual.
        """

        if self.pf['tables_discrete_gen']:
            raise NotImplemented('help')
        else:

            Ej = self.E_th[donor]

            # Otherwise, continuous spectrum
            if self.pf['photon_conserving']:
                integrand = lambda E: \
                    self.esec.DepositionFraction(x, E=E-Ej, channel=absorber) * \
                    self.src.Spectrum(E, t = t) * \
                    np.exp(-self.SpecificOpticalDepth(E, N)[0])
            #else:
            #    integrand = lambda E: PhotoIonizationCrossSection(E, species) * \
            #        self.src.Spectrum(E, t = t) * \
            #        np.exp(-self.SpecificOpticalDepth(E, ncol)[0])
            #        / self.E_th[absorber]

            # Integrate over energies in lookup table
            c = self.E >= max(Ej, self.src.Emin)
            c &= self.E <= self.src.Emax
            samples = np.array([integrand(E) for E in self.E[c]])[..., 0]

            integral = simps(samples, self.E[c])

        if not self.pf['photon_conserving']:
            integral *= self.E_th[absorber]

        return integral
//  [python]
def PsiWiggle(self, N, absorber, donor, x=None, t=None):
        """
        Equation 2.19 in the manual.
        """

        if self.pf['tables_discrete_gen']:
            raise NotImplemented('help')
        else:

            Ej = self.E_th[donor]

            # Otherwise, continuous spectrum
            if self.pf['photon_conserving']:
                integrand = lambda E: \
                    self.esec.DepositionFraction(x, E=E-Ej, channel=absorber) * \
                    self.src.Spectrum(E, t = t) * \
                    np.exp(-self.SpecificOpticalDepth(E, N)[0])
            #else:
            #    integrand = lambda E: PhotoIonizationCrossSection(E, species) * \
            #        self.src.Spectrum(E, t = t) * \
            #        np.exp(-self.SpecificOpticalDepth(E, ncol)[0])
            #        / self.E_th[absorber]

            # Integrate over energies in lookup table
            c = self.E >= max(Ej, self.src.Emin)
            c &= self.E <= self.src.Emax
            samples = np.array([integrand(E) for E in self.E[c]])[..., 0]

            integral = sp.integrate.simpson(samples, self.E[c])

        if not self.pf['photon_conserving']:
            integral *= self.E_th[absorber]

        return integral
//  [python]
def calc_tec(coords, attrs, variables, verbose=False):
    '''
    A routine to calculate the 2D VTEC.
    To perform these calculations, electron density ("e-") must be one of
    the available data types.
    '''
    import scipy.integrate as integ

    if 'e-' in variables.keys() or 'e-                   (/m3)' in\
            variables.keys():
        if 'e-' in variables.keys():
            e_key = 'e-'
        elif 'e-                   (/m3)' in variables.keys():
            e_key = 'e-                   (/m3)'
        temp = np.array(variables[e_key] * 1.0e-16)
        variables['VTEC'] = np.zeros((attrs['nLat'], attrs['nLon']),
                                     dtype=np.float64)
        for ilon in range(attrs['nLon']):
            for ilat in range(attrs['nLat']):
                # Integrate electron density over altitude, not including
                # ghost cells
                vtec = integ.simps(temp[2:-2, ilat, ilon],
                                   coords['height'][2:-2]*1000, "avg")
                variables['VTEC'][ilat, ilon] = vtec
    elif verbose:
        print('e-!', variables.keys())
    return variables
//  [python]
def calc_tec(coords, attrs, variables, verbose=False):
    '''
    A routine to calculate the 2D VTEC.
    To perform these calculations, electron density ("e-") must be one of
    the available data types.
    '''
    import scipy.integrate as integ

    if 'e-' in variables.keys() or 'e-                   (/m3)' in\
            variables.keys():
        if 'e-' in variables.keys():
            e_key = 'e-'
        elif 'e-                   (/m3)' in variables.keys():
            e_key = 'e-                   (/m3)'
        temp = np.array(variables[e_key] * 1.0e-16)
        variables['VTEC'] = np.zeros((attrs['nLat'], attrs['nLon']),
                                     dtype=np.float64)
        for ilon in range(attrs['nLon']):
            for ilat in range(attrs['nLat']):
                # Integrate electron density over altitude, not including
                # ghost cells
                vtec = integ.simpson(temp[2:-2, ilat, ilon],
                                   coords['height'][2:-2]*1000, "avg")
                variables['VTEC'][ilat, ilon] = vtec
    elif verbose:
        print('e-!', variables.keys())
    return variables
//  [python]
def plot_pdf(x,ypts,bin_width=1.0,scale=1.0,efficiency=1.0,axes=None,fmt='-',subranges=None,linewidth=1,linecolor=None,label=None):

    y = None
    plot = None

    if axes==None:
        axes=plt.gca()

    if subranges!= None:
        totnorm = 0.0
        srnorms = []
        y = []
        plot = []
        for srx,sr in zip(srxs,subranges):
            sry = np.ones(len(srx))
            norm = integrate.simps(sry,x=srx)
            srnorms.append(norm)
            totnorm += norm

        for tot_sry,norm,srx,sr in zip(tot_srys,srnorms,srxs,subranges):
            sry = np.ones(len(srx))
            norm /= totnorm

            ypts = np.ones(len(srx))
            ytemp,plottemp = plot_pdf(srx,ypts,bin_width=bin_width,scale=norm*scale,fmt=fmt,axes=axes)
            y.append(ytemp)
            plot.append(plottemp)
            #tot_sry += y


    else:
        y = np.array(ypts)
        y *= efficiency

        # Normalize to 1.0
        normalization = integrate.simps(y,x=x)
        y /= normalization

        #print "exp int: ",integrate.simps(y,x=x)
        #y *= (scale*bin_width)*efficiency
        y *= (scale*bin_width)

        if linecolor is not None:
            plot = axes.plot(x,y,fmt,linewidth=linewidth,color=linecolor,label=label)
        else:
            plot = axes.plot(x,y,fmt,linewidth=linewidth,label=label)
        #ytot += y
        #ax0.plot(x,ytot,'b',linewidth=3)

    return y,plot
//  [python]
def plot_pdf(x,ypts,bin_width=1.0,scale=1.0,efficiency=1.0,axes=None,fmt='-',subranges=None,linewidth=1,linecolor=None,label=None):

    y = None
    plot = None

    if axes==None:
        axes=plt.gca()

    if subranges!= None:
        totnorm = 0.0
        srnorms = []
        y = []
        plot = []
        for srx,sr in zip(srxs,subranges):
            sry = np.ones(len(srx))
            norm = integrate.simpson(sry,x=srx)
            srnorms.append(norm)
            totnorm += norm

        for tot_sry,norm,srx,sr in zip(tot_srys,srnorms,srxs,subranges):
            sry = np.ones(len(srx))
            norm /= totnorm

            ypts = np.ones(len(srx))
            ytemp,plottemp = plot_pdf(srx,ypts,bin_width=bin_width,scale=norm*scale,fmt=fmt,axes=axes)
            y.append(ytemp)
            plot.append(plottemp)
            #tot_sry += y


    else:
        y = np.array(ypts)
        y *= efficiency

        # Normalize to 1.0
        normalization = integrate.simpson(y,x=x)
        y /= normalization

        #print "exp int: ",integrate.simps(y,x=x)
        #y *= (scale*bin_width)*efficiency
        y *= (scale*bin_width)

        if linecolor is not None:
            plot = axes.plot(x,y,fmt,linewidth=linewidth,color=linecolor,label=label)
        else:
            plot = axes.plot(x,y,fmt,linewidth=linewidth,label=label)
        #ytot += y
        #ax0.plot(x,ytot,'b',linewidth=3)

    return y,plot
//  [python]
def binave_array(x, y, dlnx, D=2, nbin=100):
    """
    Assumes dlnx << np.diff(x).
    Performs the forward bin average in dimension D.
    ::math::
        \\bar{y} = \\frac{1}{d\\ln x} \\int_{\\ln x}^{\\ln x+d\\ln x} x^D y(x)
    """
    X = np.linspace(0.0, dlnx, nbin)
    x2d, X2d = np.meshgrid(x,X)
    arg = x2d*np.exp(X2d)
    y2d = ius(x, y)(arg)
    
    nom = integrate.simps(arg**D, X, axis=0)
    
    ybar = integrate.simps(y2d*arg**D, X, axis=0)/nom
    
    return ybar
//  [python]
def binave_array(x, y, dlnx, D=2, nbin=100):
    """
    Assumes dlnx << np.diff(x).
    Performs the forward bin average in dimension D.
    ::math::
        \\bar{y} = \\frac{1}{d\\ln x} \\int_{\\ln x}^{\\ln x+d\\ln x} x^D y(x)
    """
    X = np.linspace(0.0, dlnx, nbin)
    x2d, X2d = np.meshgrid(x,X)
    arg = x2d*np.exp(X2d)
    y2d = ius(x, y)(arg)
    
    nom = integrate.simpson(arg**D, X, axis=0)
    
    ybar = integrate.simpson(y2d*arg**D, X, axis=0)/nom
    
    return ybar
//  [python]
def plot_pdf_from_lambda(func,bin_width=1.0,scale=1.0,efficiency=None,axes=None,fmt='-',linewidth=1,subranges=None,label=None):

    y = None
    plot = None
    srxs = None

    if axes==None:
        axes=plt.gca()

    if subranges!=None:

        srxs = []
        tot_srys = []
        for sr in subranges:
            srxs.append(np.linspace(sr[0],sr[1],1000))
            tot_srys.append(np.zeros(1000))

        totnorm = 0.0
        srnorms = []
        y = []
        plot = []
        for srx,sr in zip(srxs,subranges):
            sry = func(srx)

            # Work in the efficiency
            eff = 1.0
            if efficiency!=None:
                eff = efficiency(srx)
            sry *= eff

            norm = integrate.simps(sry,x=srx)
            srnorms.append(norm)
            totnorm += norm

        for tot_sry,norm,srx,sr in zip(tot_srys,srnorms,srxs,subranges):
            norm /= totnorm

            ypts = func(srx)

            # Work in the efficiency
            eff = 1.0
            if efficiency!=None:
                eff = efficiency(srx)
            ypts *= eff

            #print "norm*scale: ",norm*scale
            ytemp,plottemp = plot_pdf(srx,ypts,bin_width=bin_width,scale=norm*scale,fmt=fmt,axes=axes,linewidth=linewidth,label=label)
            y.append(ytemp)
            plot.append(plottemp)
            #tot_sry += y


    return y,plot,srxs
//  [python]
def plot_pdf_from_lambda(func,bin_width=1.0,scale=1.0,efficiency=None,axes=None,fmt='-',linewidth=1,subranges=None,label=None):

    y = None
    plot = None
    srxs = None

    if axes==None:
        axes=plt.gca()

    if subranges!=None:

        srxs = []
        tot_srys = []
        for sr in subranges:
            srxs.append(np.linspace(sr[0],sr[1],1000))
            tot_srys.append(np.zeros(1000))

        totnorm = 0.0
        srnorms = []
        y = []
        plot = []
        for srx,sr in zip(srxs,subranges):
            sry = func(srx)

            # Work in the efficiency
            eff = 1.0
            if efficiency!=None:
                eff = efficiency(srx)
            sry *= eff

            norm = integrate.simpson(sry,x=srx)
            srnorms.append(norm)
            totnorm += norm

        for tot_sry,norm,srx,sr in zip(tot_srys,srnorms,srxs,subranges):
            norm /= totnorm

            ypts = func(srx)

            # Work in the efficiency
            eff = 1.0
            if efficiency!=None:
                eff = efficiency(srx)
            ypts *= eff

            #print "norm*scale: ",norm*scale
            ytemp,plottemp = plot_pdf(srx,ypts,bin_width=bin_width,scale=norm*scale,fmt=fmt,axes=axes,linewidth=linewidth,label=label)
            y.append(ytemp)
            plot.append(plottemp)
            #tot_sry += y


    return y,plot,srxs
//  [python]
def f_lnlike(p, pool):
    print(p)

    # p are the three parameters of the fit
    # the slope (p[0])
    # the intercept (p[1])
    # and the intrinsic scatter (p[2])

    Nmod = 200
    dt = np.linspace(-4, 4, Nmod)  # in units of meas. uncert.
    et = df['e_v0'].to_numpy().reshape(Nobs, 1)  # meas. uncert.
    # t is unknown x_true
    t = np.outer(df['v0'].to_numpy().reshape(Nobs, 1), np.ones(Nmod))
    t += np.outer(et, dt)

    # one has to use the correct prior for x_true or results will be biased
    pt = ((min_x < t) & (t <= max_x))/(max_x - min_x)

    m = p[0]
    n = p[1]
    s = p[2]

    loc_true = np.ones((2, Nobs, Nmod))
    loc_true[0, :] = t
    loc_true[1, :] = m * t + n

    scale_true = [et, s]

    p_xy = like.p(loc_true, scale_true, pool=pool)

    p_x = scipy.stats.norm.pdf(dt) / et
    p_y_x = (scipy.integrate.simps(p_xy * pt, t, axis=1) /
             scipy.integrate.simps(p_x * pt, t, axis=1))
    p_res = p_y_x

    if  np.any(p_res <= 0):
        ln_p_res = -1e3
    else:
        ln_p_res = np.sum(np.log(p_res))

    return ln_p_res
//  [python]
def f_lnlike(p, pool):
    print(p)

    # p are the three parameters of the fit
    # the slope (p[0])
    # the intercept (p[1])
    # and the intrinsic scatter (p[2])

    Nmod = 200
    dt = np.linspace(-4, 4, Nmod)  # in units of meas. uncert.
    et = df['e_v0'].to_numpy().reshape(Nobs, 1)  # meas. uncert.
    # t is unknown x_true
    t = np.outer(df['v0'].to_numpy().reshape(Nobs, 1), np.ones(Nmod))
    t += np.outer(et, dt)

    # one has to use the correct prior for x_true or results will be biased
    pt = ((min_x < t) & (t <= max_x))/(max_x - min_x)

    m = p[0]
    n = p[1]
    s = p[2]

    loc_true = np.ones((2, Nobs, Nmod))
    loc_true[0, :] = t
    loc_true[1, :] = m * t + n

    scale_true = [et, s]

    p_xy = like.p(loc_true, scale_true, pool=pool)

    p_x = scipy.stats.norm.pdf(dt) / et
    p_y_x = (scipy.integrate.simpson(p_xy * pt, t, axis=1) /
             scipy.integrate.simpson(p_x * pt, t, axis=1))
    p_res = p_y_x

    if  np.any(p_res <= 0):
        ln_p_res = -1e3
    else:
        ln_p_res = np.sum(np.log(p_res))

    return ln_p_res
//  [python]
def _get_wp_aniso(r, xi0, xi2, xi4, beta, pimax, dlnrp = 0.):
    # Numerator of Eq. (48) of arxiv: 1206.6890 using mutipole expansion of anisotropic xi including Kaiser effect in Eq. (51) of the same paper.


    rpi = np.logspace(-3, np.log10(pimax), 300) # Ok binning for 1% accuracy.

    rp2, rpi2 = np.meshgrid(r, rpi)

    s = (rp2**2+rpi2**2)**0.5
    mu= rpi2/s

    xi0s = (1+2.0/3.0*beta+1.0/5.0*beta**2)*ius(r, xi0)(s)
    xi2s = (4.0/3.0*beta+4.0/7.0*beta**2)*ius(r, xi2)(s)
    xi4s = 8.0/35.0*beta**2*ius(r, xi4)(s)

    p0 = 1
    p2 = eval_legendre(2, mu)
    p4 = eval_legendre(4, mu)

    xi_aniso = 2*(xi0s*p0+xi2s*p2+xi4s*p4)

    wp_aniso = simps(xi_aniso, rpi, axis=0)

    if dlnrp > 0.0:
        wp_aniso = binave_array(r, wp_aniso, dlnrp)
    return wp_aniso
//  [python]
def _get_wp_aniso(r, xi0, xi2, xi4, beta, pimax, dlnrp = 0.):
    # Numerator of Eq. (48) of arxiv: 1206.6890 using mutipole expansion of anisotropic xi including Kaiser effect in Eq. (51) of the same paper.


    rpi = np.logspace(-3, np.log10(pimax), 300) # Ok binning for 1% accuracy.

    rp2, rpi2 = np.meshgrid(r, rpi)

    s = (rp2**2+rpi2**2)**0.5
    mu= rpi2/s

    xi0s = (1+2.0/3.0*beta+1.0/5.0*beta**2)*ius(r, xi0)(s)
    xi2s = (4.0/3.0*beta+4.0/7.0*beta**2)*ius(r, xi2)(s)
    xi4s = 8.0/35.0*beta**2*ius(r, xi4)(s)

    p0 = 1
    p2 = eval_legendre(2, mu)
    p4 = eval_legendre(4, mu)

    xi_aniso = 2*(xi0s*p0+xi2s*p2+xi4s*p4)

    wp_aniso = scipy.integrate.simpson(xi_aniso, rpi, axis=0)

    if dlnrp > 0.0:
        wp_aniso = binave_array(r, wp_aniso, dlnrp)
    return wp_aniso
//  [python]
def calcRadiatedEnergy(time, mag_abs, P_0m=840.0):
    """ Calculate the radiated energy given the light curve.

    Arguments:
        time: [ndarray] Time of individual magnitude measurement (s).
        mag_abs: [nadrray] Absolute magnitudes (i.e. apparent meteor magnitudes @100km).

    Keyword arguments:
        P_0m: [float] Power output of a zero absolute magnitude meteor. 840W by default, as that is the R
            bandpass for a T = 4500K black body meteor. See: Weryk & Brown, 2013 - "Simultaneous radar and 
            video meteors - II. Photometry and ionisation" for more details.

    Return:
        initens_int: [float] Total radiated energy (J).

    """


    # Calculate the intensities from absolute magnitudes
    intens = P_0m*10**(-0.4*mag_abs)

    # # Interpolate I
    # intens_interpol = scipy.interpolate.PchipInterpolator(time, intens)

    # x_data = np.linspace(np.min(time), np.max(time), 1000)
    # plt.plot(x_data, intens_interpol(x_data))
    # plt.scatter(time, intens/(velocity**2))
    # plt.show()

    # Integrate the interpolated I
    #intens_int = intens_interpol.integrate(np.min(time), np.max(time))
    intens_int = scipy.integrate.simps(intens, time)

    return intens_int
//  [python]
def calcRadiatedEnergy(time, mag_abs, P_0m=840.0):
    """ Calculate the radiated energy given the light curve.

    Arguments:
        time: [ndarray] Time of individual magnitude measurement (s).
        mag_abs: [nadrray] Absolute magnitudes (i.e. apparent meteor magnitudes @100km).

    Keyword arguments:
        P_0m: [float] Power output of a zero absolute magnitude meteor. 840W by default, as that is the R
            bandpass for a T = 4500K black body meteor. See: Weryk & Brown, 2013 - "Simultaneous radar and 
            video meteors - II. Photometry and ionisation" for more details.

    Return:
        initens_int: [float] Total radiated energy (J).

    """


    # Calculate the intensities from absolute magnitudes
    intens = P_0m*10**(-0.4*mag_abs)

    # # Interpolate I
    # intens_interpol = scipy.interpolate.PchipInterpolator(time, intens)

    # x_data = np.linspace(np.min(time), np.max(time), 1000)
    # plt.plot(x_data, intens_interpol(x_data))
    # plt.scatter(time, intens/(velocity**2))
    # plt.show()

    # Integrate the interpolated I
    #intens_int = intens_interpol.integrate(np.min(time), np.max(time))
    intens_int = scipy.integrate.simpson(intens, time)

    return intens_int
//  [python]
def get_power_spectrum(X,fs,slow_band):
    total_sample_number=X.shape[0]
    channel=X.shape[1]
    print('channel',channel)
    points_per_signal=X.shape[2]
    sample_holder=[]
    for sample_number in range(0,total_sample_number):
        data_channel_holder=[]
        for each_channel in range(0,channel):
            #print("data_channel_holder",data_channel_holder)
            each_signal=X[sample_number,each_channel,:]
            Pxx_den = signal.periodogram(each_signal, fs,scaling="spectrum")[1]
            rate_equi=(points_per_signal/fs)
            #delta power 0-4Hz
            indexs=get_index_band(rate_equi,0,4)
            #delta_power=Pxx_den[indexs[0]:indexs[1]]
            delta_power=scipy.integrate.simps(Pxx_den[indexs[0]:indexs[1]])
            #theta power 4-7hz
            indexs=get_index_band(rate_equi,4,8)
            #print(1,indexs)
            theta_power=scipy.integrate.simps(Pxx_den[indexs[0]:indexs[1]])
            #Alpha power 8-15hz
            indexs=get_index_band(rate_equi,8,16)
            #print(2,indexs)
            alpha_power=scipy.integrate.simps(Pxx_den[indexs[0]:indexs[1]])
            #beta power 16-31hz
            indexs=get_index_band(rate_equi,16,32)
            #print(3,indexs)
            beta_power=scipy.integrate.simps(Pxx_den[indexs[0]:indexs[1]])

            total_power=delta_power+theta_power+alpha_power+beta_power
            if slow_band:
                data_channel_holder=np.hstack([data_channel_holder,
                                    delta_power/total_power,
                                    theta_power/total_power])
            else:
                data_channel_holder=np.hstack([data_channel_holder,
                                    alpha_power/total_power,
                                    beta_power/total_power])

            #print(data_channel_holder)
        if(sample_number==0):
            sample_holder=data_channel_holder
        else:
            sample_holder=np.vstack([sample_holder,data_channel_holder])
    return sample_holder
//  [python]
def get_power_spectrum(X,fs,slow_band):
    total_sample_number=X.shape[0]
    channel=X.shape[1]
    print('channel',channel)
    points_per_signal=X.shape[2]
    sample_holder=[]
    for sample_number in range(0,total_sample_number):
        data_channel_holder=[]
        for each_channel in range(0,channel):
            #print("data_channel_holder",data_channel_holder)
            each_signal=X[sample_number,each_channel,:]
            Pxx_den = signal.periodogram(each_signal, fs,scaling="spectrum")[1]
            rate_equi=(points_per_signal/fs)
            #delta power 0-4Hz
            indexs=get_index_band(rate_equi,0,4)
            #delta_power=Pxx_den[indexs[0]:indexs[1]]
            delta_power=scipy.integrate.simpson(Pxx_den[indexs[0]:indexs[1]])
            #theta power 4-7hz
            indexs=get_index_band(rate_equi,4,8)
            #print(1,indexs)
            theta_power=scipy.integrate.simpson(Pxx_den[indexs[0]:indexs[1]])
            #Alpha power 8-15hz
            indexs=get_index_band(rate_equi,8,16)
            #print(2,indexs)
            alpha_power=scipy.integrate.simpson(Pxx_den[indexs[0]:indexs[1]])
            #beta power 16-31hz
            indexs=get_index_band(rate_equi,16,32)
            #print(3,indexs)
            beta_power=scipy.integrate.simpson(Pxx_den[indexs[0]:indexs[1]])

            total_power=delta_power+theta_power+alpha_power+beta_power
            if slow_band:
                data_channel_holder=np.hstack([data_channel_holder,
                                    delta_power/total_power,
                                    theta_power/total_power])
            else:
                data_channel_holder=np.hstack([data_channel_holder,
                                    alpha_power/total_power,
                                    beta_power/total_power])

            #print(data_channel_holder)
        if(sample_number==0):
            sample_holder=data_channel_holder
        else:
            sample_holder=np.vstack([sample_holder,data_channel_holder])
    return sample_holder
//  [python]
def get_integrated_correlation(self, array):
        """
        compute the autocorrelation and integrate it wrt time

        Args:
            array (numpy.ndarray): input numpy array

        Returns:
            integrated autocorrelation
        """
        auto_corr_full = np.correlate(array, array,mode="full")
        auto_corr = auto_corr_full[auto_corr_full.size / 2:]
        time = self.lammpsrun.traj_timesteps
        return sp_integrate.simps(auto_corr, time)
//  [python]
def get_integrated_correlation(self, array):
        """
        compute the autocorrelation and integrate it wrt time

        Args:
            array (numpy.ndarray): input numpy array

        Returns:
            integrated autocorrelation
        """
        auto_corr_full = np.correlate(array, array,mode="full")
        auto_corr = auto_corr_full[auto_corr_full.size / 2:]
        time = self.lammpsrun.traj_timesteps
        return sp_integrate.simpson(auto_corr, time)
//  [python]
def normalised_hilleret_energy(energy, sigmafit=1.0828, mufit=1.6636):
    out = 1. / (energy * sigmafit * np.sqrt(2 * np.pi)) * np.exp(-(np.log(energy) - mufit)**2 / (2 * sigmafit**2))
    area = scipy.integrate.simps(out, energy)
    return out / area
//  [python]
def normalised_hilleret_energy(energy, sigmafit=1.0828, mufit=1.6636):
    out = 1. / (energy * sigmafit * np.sqrt(2 * np.pi)) * np.exp(-(np.log(energy) - mufit)**2 / (2 * sigmafit**2))
    area = scipy.integrate.simpson(out, energy)
    return out / area
//  [python]
def test_energy_conservation(em, tolerance_pc, npol=None, subset=16):
    """test energy conservation

    :param em: the electromagnetic model that has been set up
    :param tolerance_pc: relative tolerance
"""

    # Default test is for 2 pol matrix
    if npol is None:
        npol = 2

    mu = np.linspace(-1, 1, 128)

    ft_even_phase = em.ft_even_phase(mu, mu, m_max=0, npol=npol)

    for pol in [0, 1]:
        for inc in range(len(mu))[::subset]:

            # Put phase information back - arbitrary phi difference is zero so cos dphi, cos (2*dphi) = 1
            #p_sum, p_err = scipy.integrate.quad(phase_fn_int, 0, 2. * np.pi, args=(inc, pol, em, mu, npol)) # not needed as we already use m=0
            
            p11_12 = np.sum(ft_even_phase[:, pol, 0, :, inc], axis=0)
            p_sum = 2 * np.pi * scipy.integrate.simps(p11_12, mu)
            phase_integral = p_sum / (4. * np.pi)
            print ('Test failed for incidence__polarization_angle_number: ', inc, pol)  # Only prints if test fails
            print ('Integrated phase function is: ', phase_integral)  # Only prints if test fails
            print ('Scattering coefficient is: ', em.ks)  # Only prints if test fails
            assert abs(phase_integral - em.ks) < tolerance_pc * em.ks
//  [python]
def test_energy_conservation(em, tolerance_pc, npol=None, subset=16):
    """test energy conservation

    :param em: the electromagnetic model that has been set up
    :param tolerance_pc: relative tolerance
"""

    # Default test is for 2 pol matrix
    if npol is None:
        npol = 2

    mu = np.linspace(-1, 1, 128)

    ft_even_phase = em.ft_even_phase(mu, mu, m_max=0, npol=npol)

    for pol in [0, 1]:
        for inc in range(len(mu))[::subset]:

            # Put phase information back - arbitrary phi difference is zero so cos dphi, cos (2*dphi) = 1
            #p_sum, p_err = scipy.integrate.quad(phase_fn_int, 0, 2. * np.pi, args=(inc, pol, em, mu, npol)) # not needed as we already use m=0
            
            p11_12 = np.sum(ft_even_phase[:, pol, 0, :, inc], axis=0)
            p_sum = 2 * np.pi * scipy.integrate.simpson(p11_12, mu)
            phase_integral = p_sum / (4. * np.pi)
            print ('Test failed for incidence__polarization_angle_number: ', inc, pol)  # Only prints if test fails
            print ('Integrated phase function is: ', phase_integral)  # Only prints if test fails
            print ('Scattering coefficient is: ', em.ks)  # Only prints if test fails
            assert abs(phase_integral - em.ks) < tolerance_pc * em.ks
//  [python]
zarr = np.arange(10, 50, 0.1)

pl.semilogy(zarr, pop.fcoll(zarr), color='k', lw=3, alpha=0.5)

new_fcoll = []

j = np.argmin(np.abs(pop.halos.tab_M - 1e8))

for z in zarr:
    i = np.argmin(np.abs(pop.halos.z - z))
    fcoll_mgtm1 = pop.halos.tab_mgtm[i,j] / pop.halos.MF.mean_density0
    
    dndm = pop.halos.tab_dndm[i,j]
    M = pop.halos.tab_M
    
    ok = M >= 1e8
    
    dndlnm = dndm * M
    
    #fcoll_mgtm2 = np.trapz(dndlnm, x=np.log(M)) / pop.halos.MF.mean_density0
    fcoll_mgtm2 = simps(dndlnm[ok], x=np.log(M[ok])) / pop.halos.MF.mean_density0
        
    print('{0!s} {1!s} {2!s}'.format(z, fcoll_mgtm1, fcoll_mgtm2))#, fcoll
    
    new_fcoll.append(fcoll_mgtm2)
//  [python]
zarr = np.arange(10, 50, 0.1)

pl.semilogy(zarr, pop.fcoll(zarr), color='k', lw=3, alpha=0.5)

new_fcoll = []

j = np.argmin(np.abs(pop.halos.tab_M - 1e8))

for z in zarr:
    i = np.argmin(np.abs(pop.halos.z - z))
    fcoll_mgtm1 = pop.halos.tab_mgtm[i,j] / pop.halos.MF.mean_density0
    
    dndm = pop.halos.tab_dndm[i,j]
    M = pop.halos.tab_M
    
    ok = M >= 1e8
    
    dndlnm = dndm * M
    
    #fcoll_mgtm2 = np.trapz(dndlnm, x=np.log(M)) / pop.halos.MF.mean_density0
    fcoll_mgtm2 = sp.integrate.simpson(dndlnm[ok], x=np.log(M[ok])) / pop.halos.MF.mean_density0
        
    print('{0!s} {1!s} {2!s}'.format(z, fcoll_mgtm1, fcoll_mgtm2))#, fcoll
    
    new_fcoll.append(fcoll_mgtm2)
//  [python]
def P_R_rain_soft(p, R: float, n: int = None) -> float:

    if n is None:
        n = p.n

    def integrand(t: np.ndarray) -> np.ndarray:
        arr = (np.sin(np.pi / (2 * p.tau_h) * t) ** 2) \
              * (np.exp(-2 * p.alpha * (R - ((c * t) / 2)))) \
              * inverse_square_modified(p, R, t) \
              * xsi_loop(p, R - ((c * t) / 2)) \
              * np.heaviside(p.r_0 - R + (c * t) / 2, 0)

        return arr

    start = 0
    stop = 2 * p.tau_h

    x = np.linspace(start, stop, n)
    y = integrand(x)

    integral = scipy_integrate.simps(y, x)

    return p.c_a * p.p_0 * p.beta * integral
//  [python]
def P_R_rain_soft(p, R: float, n: int = None) -> float:

    if n is None:
        n = p.n

    def integrand(t: np.ndarray) -> np.ndarray:
        arr = (np.sin(np.pi / (2 * p.tau_h) * t) ** 2) \
              * (np.exp(-2 * p.alpha * (R - ((c * t) / 2)))) \
              * inverse_square_modified(p, R, t) \
              * xsi_loop(p, R - ((c * t) / 2)) \
              * np.heaviside(p.r_0 - R + (c * t) / 2, 0)

        return arr

    start = 0
    stop = 2 * p.tau_h

    x = np.linspace(start, stop, n)
    y = integrand(x)

    integral = scipy.integrate.simpson(y, x)

    return p.c_a * p.p_0 * p.beta * integral
//  [python]
def I_Tb(params):
    (u, vz, n_Delta, T, C, Delta2, dz) = params
    dI = n_Delta * np.exp(- (u - (vz))**2 / (2.*Delta2))
    dI[np.where(dI != dI)] = 0.
    I = 1./(C * np.sqrt(2.*np.pi)) * integrate.simps(dI, dx=dz, axis=0)
    return I
//  [python]
def I_Tb(params):
    (u, vz, n_Delta, T, C, Delta2, dz) = params
    dI = n_Delta * np.exp(- (u - (vz))**2 / (2.*Delta2))
    dI[np.where(dI != dI)] = 0.
    I = 1./(C * np.sqrt(2.*np.pi)) * integrate.simpson(dI, dx=dz, axis=0)
    return I
//  [python]
def calculate_pressure_integral(integrand, pressure):
    """ Calculates the vertical integral (in pressure coordinates) of an array
    
        input:
        ------
            integrand     : the quantity to integrate.  The vertical dimension is assumed to be the first index.
            
            pressure      : the pressure (either a vector or an array of the same shape as integrand).  Units should be [Pa].
            
        output:
        -------
        
            integral      : the approximated integral of integrand (same shape as integrand, but missing the leftmost
                            dimension of integrand).
                            
            For integrand $F(p)$, this function approximates
            
            $$ -\frac{1}{g} \int\limits^{p_s}_0 F(p) dp $$
            
    """
    # set necessary constants
    one_over_negative_g = -1./9.80665 # m/s^2
    
    # determine whether pressure needs to be broadcast to the same shape as integrand
    # check if the dimensions of integrand and pressure don't match
    if not all( [s1 == s2 for s1,s2 in zip(integrand.shape,pressure.shape)] ):
        
        # try broadcasting pressure to the proper shape
        try:
            pressure3d = np.ones(integrand.shape)*pressure[:,np.newaxis,np.newaxis]
        except:
            raise ValueError("pressure cannot be broadcast to the shape of integrand. shape(pressure) = {}, and shape(integrand) = {}".format(pressure.shape,integrand.shape))
    
    # if they do, then simply set pressure3d to pressure
    else:
        pressure3d = pressure
        
    
    # calculate the integral
    # ( fill in any missing values with 0)
    integral = scipy.integrate.simps(np.ma.filled(integrand,0),pressure,axis=0)
    
    # scale the integral and return
    return one_over_negative_g*integral
//  [python]
def calculate_pressure_integral(integrand, pressure):
    """ Calculates the vertical integral (in pressure coordinates) of an array
    
        input:
        ------
            integrand     : the quantity to integrate.  The vertical dimension is assumed to be the first index.
            
            pressure      : the pressure (either a vector or an array of the same shape as integrand).  Units should be [Pa].
            
        output:
        -------
        
            integral      : the approximated integral of integrand (same shape as integrand, but missing the leftmost
                            dimension of integrand).
                            
            For integrand $F(p)$, this function approximates
            
            $$ -\frac{1}{g} \int\limits^{p_s}_0 F(p) dp $$
            
    """
    # set necessary constants
    one_over_negative_g = -1./9.80665 # m/s^2
    
    # determine whether pressure needs to be broadcast to the same shape as integrand
    # check if the dimensions of integrand and pressure don't match
    if not all( [s1 == s2 for s1,s2 in zip(integrand.shape,pressure.shape)] ):
        
        # try broadcasting pressure to the proper shape
        try:
            pressure3d = np.ones(integrand.shape)*pressure[:,np.newaxis,np.newaxis]
        except:
            raise ValueError("pressure cannot be broadcast to the shape of integrand. shape(pressure) = {}, and shape(integrand) = {}".format(pressure.shape,integrand.shape))
    
    # if they do, then simply set pressure3d to pressure
    else:
        pressure3d = pressure
        
    
    # calculate the integral
    # ( fill in any missing values with 0)
    integral = scipy.integrate.simpson(np.ma.filled(integrand,0),pressure,axis=0)
    
    # scale the integral and return
    return one_over_negative_g*integral
//  [python]
def get_log_like(self):
        """
        Return the value of the log-likelihood with the current values for the
        parameters
        """

        log_l = 0.0

        # Evaluate once for all
        all_yy = np.split(
            self._likelihood_model.get_total_flux(self._all_xx), self._splits
        )

        for i, interval_container in enumerate(self._active_containers):

            # Get integral of model between start and stop for this interval
            # xx = np.logspace(np.log10(interval_container.start),
            #                  np.log10(interval_container.stop),
            #                  interval_container.n_integration_points)
            #
            # yy = self._likelihood_model.get_total_flux(xx)
            #
            # assert np.allclose(yy, all_yy[i])
            xx = self._all_xx_split[i]
            yy = all_yy[i]

            length = interval_container.stop - interval_container.start

            expected_flux = old_div(scipy.integrate.simps(yy, xx), length)

            this_log_l = interval_container(expected_flux)

            log_l += this_log_l

        return log_l
//  [python]
def get_log_like(self):
        """
        Return the value of the log-likelihood with the current values for the
        parameters
        """

        log_l = 0.0

        # Evaluate once for all
        all_yy = np.split(
            self._likelihood_model.get_total_flux(self._all_xx), self._splits
        )

        for i, interval_container in enumerate(self._active_containers):

            # Get integral of model between start and stop for this interval
            # xx = np.logspace(np.log10(interval_container.start),
            #                  np.log10(interval_container.stop),
            #                  interval_container.n_integration_points)
            #
            # yy = self._likelihood_model.get_total_flux(xx)
            #
            # assert np.allclose(yy, all_yy[i])
            xx = self._all_xx_split[i]
            yy = all_yy[i]

            length = interval_container.stop - interval_container.start

            expected_flux = old_div(scipy.integrate.simpson(yy, xx), length)

            this_log_l = interval_container(expected_flux)

            log_l += this_log_l

        return log_l
//  [python]
def get_abundance_matrix(self):

        self.abundance_matrix = np.sum(self.abundance_tensor,axis=0)
        self.n_z = integrate.simps(self.abundance_matrix,self.obs_select_vec)

        if self.cnc_params["convolve_nz"] == True:

            self.n_z = convolve_1d(self.redshift_vec,self.n_z,sigma=self.cnc_params["sigma_nz"],type="fft")
//  [python]
def get_abundance_matrix(self):

        self.abundance_matrix = np.sum(self.abundance_tensor,axis=0)
        self.n_z = integrate.simpson(self.abundance_matrix,self.obs_select_vec)

        if self.cnc_params["convolve_nz"] == True:

            self.n_z = convolve_1d(self.redshift_vec,self.n_z,sigma=self.cnc_params["sigma_nz"],type="fft")
//  [python]
sp1 = fig1.add_subplot(2, 2, 1)
sp2 = fig1.add_subplot(2, 2, 2)
sp3 = fig1.add_subplot(2, 2, 3)
sp4 = fig1.add_subplot(2, 2, 4)

for i_ct, ct in enumerate(cos_theta_test):
    thiscol = ms.colorprog(i_ct, len(cos_theta_test))
    label = 'costheta=%.2f' % ct

    areats = scipy.integrate.simps(extract_ene_hist['true'][:, i_ct], extract_ene_hist['emit_ene_g_hist'])
    areae = scipy.integrate.simps(extract_ene_hist['elast'][:, i_ct], extract_ene_hist['emit_ene_g_hist'])
    arear = scipy.integrate.simps(extract_ene_hist['rediff'][:, i_ct], extract_ene_hist['emit_ene_g_hist'])
    areaab = scipy.integrate.simps(extract_ene_hist['absorb'][:, i_ct], extract_ene_hist['emit_ene_g_hist'])

    sp1.plot(extract_ene_hist['emit_ene_g_hist'], extract_ene_hist['true'][:, i_ct] / areats, color=thiscol, label=label, alpha=alpha, linewidth=linewid, marker='o')
    sp2.plot(extract_ene_hist['emit_ene_g_hist'], extract_ene_hist['elast'][:, i_ct] / areae, color=thiscol, label=label, alpha=alpha, linewidth=linewid, marker='o')
    sp3.plot(extract_ene_hist['emit_ene_g_hist'], extract_ene_hist['rediff'][:, i_ct] / arear, color=thiscol, label=label, alpha=alpha, linewidth=linewid, marker='o')
    sp4.plot(extract_ene_hist['emit_ene_g_hist'], extract_ene_hist['absorb'][:, i_ct] / areaab, color=thiscol, label=label, alpha=alpha, linewidth=linewid, marker='o')
//  [python]
sp1 = fig1.add_subplot(2, 2, 1)
sp2 = fig1.add_subplot(2, 2, 2)
sp3 = fig1.add_subplot(2, 2, 3)
sp4 = fig1.add_subplot(2, 2, 4)

for i_ct, ct in enumerate(cos_theta_test):
    thiscol = ms.colorprog(i_ct, len(cos_theta_test))
    label = 'costheta=%.2f' % ct

    areats = scipy.integrate.simpson(extract_ene_hist['true'][:, i_ct], extract_ene_hist['emit_ene_g_hist'])
    areae = scipy.integrate.simpson(extract_ene_hist['elast'][:, i_ct], extract_ene_hist['emit_ene_g_hist'])
    arear = scipy.integrate.simpson(extract_ene_hist['rediff'][:, i_ct], extract_ene_hist['emit_ene_g_hist'])
    areaab = scipy.integrate.simpson(extract_ene_hist['absorb'][:, i_ct], extract_ene_hist['emit_ene_g_hist'])

    sp1.plot(extract_ene_hist['emit_ene_g_hist'], extract_ene_hist['true'][:, i_ct] / areats, color=thiscol, label=label, alpha=alpha, linewidth=linewid, marker='o')
    sp2.plot(extract_ene_hist['emit_ene_g_hist'], extract_ene_hist['elast'][:, i_ct] / areae, color=thiscol, label=label, alpha=alpha, linewidth=linewid, marker='o')
    sp3.plot(extract_ene_hist['emit_ene_g_hist'], extract_ene_hist['rediff'][:, i_ct] / arear, color=thiscol, label=label, alpha=alpha, linewidth=linewid, marker='o')
    sp4.plot(extract_ene_hist['emit_ene_g_hist'], extract_ene_hist['absorb'][:, i_ct] / areaab, color=thiscol, label=label, alpha=alpha, linewidth=linewid, marker='o')
//  [python]
def get_log_lik_extreme_value(self,obs_max=None):

        if self.n_tot is None:

            self.get_number_counts()

        n_obs = self.n_obs

        if obs_max is None:

            obs_max = self.catalogue.obs_select_max

        if self.cnc_params["non_validated_clusters"] == True:

            n_obs = n_obs + self.n_obs_fd

        obs_select_vec_interp = np.linspace(obs_max,self.cnc_params["obs_select_max"],100)
        n_interp = np.interp(obs_select_vec_interp,self.obs_select_vec,n_obs)
        n_theory = integrate.simps(n_interp,obs_select_vec_interp)

        log_lik = -n_theory

        return log_lik
//  [python]
def get_log_lik_extreme_value(self,obs_max=None):

        if self.n_tot is None:

            self.get_number_counts()

        n_obs = self.n_obs

        if obs_max is None:

            obs_max = self.catalogue.obs_select_max

        if self.cnc_params["non_validated_clusters"] == True:

            n_obs = n_obs + self.n_obs_fd

        obs_select_vec_interp = np.linspace(obs_max,self.cnc_params["obs_select_max"],100)
        n_interp = np.interp(obs_select_vec_interp,self.obs_select_vec,n_obs)
        n_theory = integrate.simpson(n_interp,obs_select_vec_interp)

        log_lik = -n_theory

        return log_lik
//  [python]
def eval_extreme_value_quantities(self):

        self.log_lik_ev_eval = np.zeros(len(self.obs_select_vec))

        for i in range(0,len(self.obs_select_vec)):

            self.log_lik_ev_eval[i] = self.get_log_lik_extreme_value(obs_max=self.obs_select_vec[i])

        self.lik_ev_eval = np.exp(self.log_lik_ev_eval)

        self.obs_select_max_pdf = np.gradient(self.lik_ev_eval,self.obs_select_vec)
        self.obs_select_max_mean = integrate.simps(self.obs_select_max_pdf*self.obs_select_vec,self.obs_select_vec)
        self.obs_select_max_std = np.sqrt(integrate.simps(self.obs_select_max_pdf*(self.obs_select_vec-self.obs_select_max_mean)**2,self.obs_select_vec))
//  [python]
def eval_extreme_value_quantities(self):

        self.log_lik_ev_eval = np.zeros(len(self.obs_select_vec))

        for i in range(0,len(self.obs_select_vec)):

            self.log_lik_ev_eval[i] = self.get_log_lik_extreme_value(obs_max=self.obs_select_vec[i])

        self.lik_ev_eval = np.exp(self.log_lik_ev_eval)

        self.obs_select_max_pdf = np.gradient(self.lik_ev_eval,self.obs_select_vec)
        self.obs_select_max_mean = integrate.simpson(self.obs_select_max_pdf*self.obs_select_vec,self.obs_select_vec)
        self.obs_select_max_std = np.sqrt(integrate.simpson(self.obs_select_max_pdf*(self.obs_select_vec-self.obs_select_max_mean)**2,self.obs_select_vec))
//  [python]
def integrate_profile_y(self):
        """
        Integrate profile_y values using scipy.integrate.simpson() function.
        """
        self.profile_integ = integrate.simps(
            self.profile_y, x=self.profile_x, dx=self.profile_dx
        )
//  [python]
def integrate_profile_y(self):
        """
        Integrate profile_y values using scipy.integrate.simpson() function.
        """
        self.profile_integ = integrate.simpson(
            self.profile_y, x=self.profile_x, dx=self.profile_dx
        )
//  [python]
def cosine_content(pca_space, i):
    """Measure the cosine content of the PCA projection.

    The cosine content of pca projections can be used as an indicator if a
    simulation is converged. Values close to 1 are an indicator that the
    simulation isn't converged. For values below 0.7 no statement can be made.
    If you use this function please cite :footcite:p:`BerkHess2002`.


    Parameters
    ----------
    pca_space : array, shape (number of frames, number of components)
        The PCA space to be analyzed.
    i : int
        The index of the pca_component projection to be analyzed.

    Returns
    -------
    A float reflecting the cosine content of the ith projection in the PCA
    space. The output is bounded by 0 and 1, with 1 reflecting an agreement
    with cosine while 0 reflects complete disagreement.

    References
    ----------
    .. footbibliography::

    """

    t = np.arange(len(pca_space))
    T = len(pca_space)
    cos = np.cos(np.pi * t * (i + 1) / T)
    return ((2.0 / T) * (s.simps(cos*pca_space[:, i])) ** 2 /
            s.simps(pca_space[:, i] ** 2))
//  [python]
def cosine_content(pca_space, i):
    """Measure the cosine content of the PCA projection.

    The cosine content of pca projections can be used as an indicator if a
    simulation is converged. Values close to 1 are an indicator that the
    simulation isn't converged. For values below 0.7 no statement can be made.
    If you use this function please cite :footcite:p:`BerkHess2002`.


    Parameters
    ----------
    pca_space : array, shape (number of frames, number of components)
        The PCA space to be analyzed.
    i : int
        The index of the pca_component projection to be analyzed.

    Returns
    -------
    A float reflecting the cosine content of the ith projection in the PCA
    space. The output is bounded by 0 and 1, with 1 reflecting an agreement
    with cosine while 0 reflects complete disagreement.

    References
    ----------
    .. footbibliography::

    """

    t = np.arange(len(pca_space))
    T = len(pca_space)
    cos = np.cos(np.pi * t * (i + 1) / T)
    return ((2.0 / T) * (scipy.integrate.simpson(cos*pca_space[:, i])) ** 2 /
            scipy.integrate.simpson(pca_space[:, i] ** 2))
//  [python]
def do_average(L, x, S):
    AVG = []
    XX = []
    for xx in x:
        if xx - L / 2.0 < x[0]:
            continue
        if xx + L / 2.0 > x[-1]:
            continue
        XX.append(xx)
        # print('step',xx)
        tmp_x = np.arange(xx - L / 2.0, xx + L / 2.0, 0.001)
        # x=np.arange(xx-L/2.0, xx+L/2.0,0.1)
        tmp_y = S(tmp_x)
        # intg2=np.trapz(tmp_y,tmp_x,tmp_x[1]-tmp_x[0])/L
        # intg2=integrate.quad(S, xx-L/2.0, xx+L/2.0)[0] / L
        # intg2=integrate.quad(S, xx-L/2.0, xx+L/2.0)[0] / L
        # print('tmp_x[1]-tmp_x[0]',tmp_x[1]-tmp_x[0])
        intg2 = integrate.trapz(tmp_y, tmp_x) / L
        # print('intg',int)
        AVG.append(intg2)  # integration
    #        print("int ", integrate.quad(S, xx-L/2.0, xx+L/2.0))
    return XX, AVG
//  [python]
def do_average(L, x, S):
    AVG = []
    XX = []
    for xx in x:
        if xx - L / 2.0 < x[0]:
            continue
        if xx + L / 2.0 > x[-1]:
            continue
        XX.append(xx)
        # print('step',xx)
        tmp_x = np.arange(xx - L / 2.0, xx + L / 2.0, 0.001)
        # x=np.arange(xx-L/2.0, xx+L/2.0,0.1)
        tmp_y = S(tmp_x)
        # intg2=np.trapz(tmp_y,tmp_x,tmp_x[1]-tmp_x[0])/L
        # intg2=integrate.quad(S, xx-L/2.0, xx+L/2.0)[0] / L
        # intg2=integrate.quad(S, xx-L/2.0, xx+L/2.0)[0] / L
        # print('tmp_x[1]-tmp_x[0]',tmp_x[1]-tmp_x[0])
        intg2 = integrate.simpson(tmp_y, tmp_x, tmp_x[1] - tmp_x[0]) / L
        # print('intg',int)
        AVG.append(intg2)  # integration
    #        print("int ", integrate.quad(S, xx-L/2.0, xx+L/2.0))
    return XX, AVG
//  [python]
def integrate(
        self: T,
        *,
        domain: Optional[DomainRange] = None,
    ) -> NDArrayFloat:
        """
        Integration of the FData object.

        The integration is performed over the whole domain. Thus, for a
        function of several variables this will be a multiple integral.

        For a vector valued function the vector of integrals will be
        returned.

        Args:
            domain: Domain range where we want to integrate.
                By default is None as we integrate on the whole domain.

        Returns:
            NumPy array of size (``n_samples``, ``dim_codomain``)
            with the integrated data.

        Examples:
            >>> fdata = FDataGrid([1,2,4,5,8], range(5))
            >>> fdata.integrate()
            array([[ 15.]])
        """
        if domain is not None:
            data = self.restrict(domain)
        else:
            data = self

        integrand = data.data_matrix

        for g in data.grid_points[::-1]:
            integrand = scipy.integrate.simps(
                integrand,
                x=g,
                axis=-2,
            )

        return integrand
//  [python]
def integrate(
        self: T,
        *,
        domain: Optional[DomainRange] = None,
    ) -> NDArrayFloat:
        """
        Integration of the FData object.

        The integration is performed over the whole domain. Thus, for a
        function of several variables this will be a multiple integral.

        For a vector valued function the vector of integrals will be
        returned.

        Args:
            domain: Domain range where we want to integrate.
                By default is None as we integrate on the whole domain.

        Returns:
            NumPy array of size (``n_samples``, ``dim_codomain``)
            with the integrated data.

        Examples:
            >>> fdata = FDataGrid([1,2,4,5,8], range(5))
            >>> fdata.integrate()
            array([[ 15.]])
        """
        if domain is not None:
            data = self.restrict(domain)
        else:
            data = self

        integrand = data.data_matrix

        for g in data.grid_points[::-1]:
            integrand = scipy.integrate.simpson(
                integrand,
                x=g,
                axis=-2,
            )

        return integrand
//  [python]
def price(self, strike, spot, texp, cp=1):
        fwd, df, divf = self._fwd_factor(spot, texp)

        kk = strike/fwd
        log_kk = np.log(kk)

        dx = self.x_lim/self.n_x
        xx = np.arange(self.n_x + 1)[:, None]*dx  # the final value x_lim is excluded
        yy = (np.exp(-log_kk*xx*1j)*self.mgf_logprice(xx*1j + 0.5, texp)).real/(xx**2 + 0.25)
        int_val = spint.simpson(yy, dx=dx, axis=0)
        if np.isscalar(kk):
            int_val = int_val[0]
        price = np.where(cp > 0, 1, kk) - np.sqrt(kk)/np.pi*int_val
        return df*fwd*price