jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def integrate_rs(simfolder, f0, t, 
    natoms, p=0, nsims=5, 
    scale_energy=False, 
    return_values=False):
    """
    Carry out the reversible scaling integration

    Parameters
    ----------
    simfolder : string
        main simulation folder

    f0 : float
        initial free energy for integration

    t : float
        initial temperature

    nsims : int, optional
        number of independent switching

    scale_energy: bool, optional
        if True, scale energy with switching parameter

    Returns
    -------
    None

    Notes
    -----
    Writes the output in a file reversible_scaling.dat
    
    """
    ws = []
    p = p/(10000*160.21766208)
    
    for i in range(1, nsims+1):
        fdx, fp, fvol, flambda = np.loadtxt(os.path.join(simfolder, "ts.forward_%d.dat"%i), unpack=True, comments="#")
        bdx, bp, bvol, blambda = np.loadtxt(os.path.join(simfolder, "ts.backward_%d.dat"%i), unpack=True, comments="#")
        
        if scale_energy:
            fdx /= flambda
            bdx /= blambda

        #add pressure contribution
        fvol = fvol/natoms
        bvol = bvol/natoms
        fdx = fdx + p*fvol
        bdx = bdx + p*bvol
        
        wf = cumtrapz(fdx, flambda,initial=0)
        wb = cumtrapz(bdx[::-1], blambda[::-1],initial=0)
        w = (wf + wb) / (2*flambda)
        ws.append(w)
    

    wmean = np.mean(ws, axis=0)
    werr = np.std(ws, axis=0)
    temp = t/flambda

    f = f0/flambda + 1.5*kb*temp*np.log(flambda) + wmean

    if not return_values:
        outfile = os.path.join(simfolder, "temperature_sweep.dat")
        np.savetxt(outfile, np.column_stack((temp, f, werr)))
    else:
        return (temp, f, werr)
//  [python]
def integrate_rs(simfolder, f0, t, 
    natoms, p=0, nsims=5, 
    scale_energy=False, 
    return_values=False):
    """
    Carry out the reversible scaling integration

    Parameters
    ----------
    simfolder : string
        main simulation folder

    f0 : float
        initial free energy for integration

    t : float
        initial temperature

    nsims : int, optional
        number of independent switching

    scale_energy: bool, optional
        if True, scale energy with switching parameter

    Returns
    -------
    None

    Notes
    -----
    Writes the output in a file reversible_scaling.dat
    
    """
    ws = []
    p = p/(10000*160.21766208)
    
    for i in range(1, nsims+1):
        fdx, fp, fvol, flambda = np.loadtxt(os.path.join(simfolder, "ts.forward_%d.dat"%i), unpack=True, comments="#")
        bdx, bp, bvol, blambda = np.loadtxt(os.path.join(simfolder, "ts.backward_%d.dat"%i), unpack=True, comments="#")
        
        if scale_energy:
            fdx /= flambda
            bdx /= blambda

        #add pressure contribution
        fvol = fvol/natoms
        bvol = bvol/natoms
        fdx = fdx + p*fvol
        bdx = bdx + p*bvol
        
        wf = scipy.integrate.cumulative_trapezoid(fdx, flambda,initial=0)
        wb = scipy.integrate.cumulative_trapezoid(bdx[::-1], blambda[::-1],initial=0)
        w = (wf + wb) / (2*flambda)
        ws.append(w)
    

    wmean = np.mean(ws, axis=0)
    werr = np.std(ws, axis=0)
    temp = t/flambda

    f = f0/flambda + 1.5*kb*temp*np.log(flambda) + wmean

    if not return_values:
        outfile = os.path.join(simfolder, "temperature_sweep.dat")
        np.savetxt(outfile, np.column_stack((temp, f, werr)))
    else:
        return (temp, f, werr)
//  [python]
def log_gas_density_high(self, mstar=0.5):
        # Set up the high resolution grid.

        r = numpy.logspace(numpy.log10(self.rmin), numpy.log10(5*self.rmax), \
                1000)
        z = numpy.hstack(([0], numpy.logspace(-3., numpy.log10(5*self.rmax), \
                1000)))
        phi = numpy.array([0.,2*numpy.pi])

        # Calculate the temperature structure.

        T = self.temperature(r, phi, z, coordsys="cylindrical")[:,0,:]

        # Now make the high resolution coordinates into 3D arrays.

        r, z = numpy.meshgrid(r, z, indexing='ij')

        # Now calculate the derivative of T.

        dlogT = numpy.gradient(numpy.log(T), z[0,:]*AU, axis=1)

        # Calculate the balance of gravity and pressure

        mu = 2.37
        cs = (k*T/(mu*m_p))**0.5
        M = mstar*M_sun

        gravity = 1./cs**2 * G*M*z*AU / ((r*AU)**2 + (z*AU)**2)**1.5

        # Now vertically integrate to get -logDens.

        logDens = -scipy.integrate.cumtrapz(dlogT+gravity, x=z*AU, initial=0., \
                axis=1)

        # Get the proper normalization.

        norm = 0.5*100*self.surface_density(r[:,0]) / scipy.integrate.trapz(\
                numpy.exp(logDens), x=z*AU, axis=1)

        norm_arr = numpy.zeros(r.shape)
        for i in range(r.shape[1]):
            norm_arr[:,i] = norm

        # Finally, calculate the scaled density.

        with numpy.errstate(divide="ignore"):
            logDens += numpy.where(norm_arr > 0, numpy.log(norm_arr), -300.)

        return r, z, logDens
//  [python]
def log_gas_density_high(self, mstar=0.5):
        # Set up the high resolution grid.

        r = numpy.logspace(numpy.log10(self.rmin), numpy.log10(5*self.rmax), \
                1000)
        z = numpy.hstack(([0], numpy.logspace(-3., numpy.log10(5*self.rmax), \
                1000)))
        phi = numpy.array([0.,2*numpy.pi])

        # Calculate the temperature structure.

        T = self.temperature(r, phi, z, coordsys="cylindrical")[:,0,:]

        # Now make the high resolution coordinates into 3D arrays.

        r, z = numpy.meshgrid(r, z, indexing='ij')

        # Now calculate the derivative of T.

        dlogT = numpy.gradient(numpy.log(T), z[0,:]*AU, axis=1)

        # Calculate the balance of gravity and pressure

        mu = 2.37
        cs = (k*T/(mu*m_p))**0.5
        M = mstar*M_sun

        gravity = 1./cs**2 * G*M*z*AU / ((r*AU)**2 + (z*AU)**2)**1.5

        # Now vertically integrate to get -logDens.

        logDens = -scipy.integrate.cumulative_trapezoid(dlogT+gravity, x=z*AU, initial=0., \
                axis=1)

        # Get the proper normalization.

        norm = 0.5*100*self.surface_density(r[:,0]) / scipy.integrate.trapz(\
                numpy.exp(logDens), x=z*AU, axis=1)

        norm_arr = numpy.zeros(r.shape)
        for i in range(r.shape[1]):
            norm_arr[:,i] = norm

        # Finally, calculate the scaled density.

        with numpy.errstate(divide="ignore"):
            logDens += numpy.where(norm_arr > 0, numpy.log(norm_arr), -300.)

        return r, z, logDens
//  [python]
def InductionsFromCirculation_VC_Cont(vr_bar,lambda_r,k,bSwirl,method='analytical',bHighThrustCorr=True,Cq=None):
    """ 
    Based on "Continuous formulation". Based on script fInductionCoefficientsCylinders.py
    If Cq is provided, an attempt of using it is made.
         Not recommended, results in lower Tangential inductions
         The circulation obtained from Cq is not smooth

    For now the continuous results seems a bit off on the axial induction compared to the discrete ones
    The tangential induction seem to be the same for the continuous and discrete case
    """
    # Critical values for high-thrust Spera correction
    ac   = 0.34
    Ct_c = 4*ac*(1-ac)
    misc={}
    # Safety
    if lambda_r[0]==0:
        lambda_r[0]=lambda_r[1]*0.01;
    # --- Finding Cylinders intensities
    if method.lower()=='analytical':
        if bSwirl:
            a_prime = k/(4*lambda_r**2) # NOTE: entirely determined from Gamma! Eq.(38)
            Ir=np.arange(len(k)-1,-1,-1)
            Ct_rot = -8*sciint.cumtrapz(lambda_r[Ir]**2*a_prime[Ir]**2/vr_bar[Ir], vr_bar[Ir])# Eq.(6)
            Ct_rot = np.concatenate(([0],Ct_rot))
            Ct_rot=Ct_rot[Ir];
        else:
            a_prime = k*0
            Ct_rot = k*0
        Ct_KJ  = k*(1+a_prime)
        Ct_eff = Ct_KJ-Ct_rot 
        a=np.zeros(vr_bar.shape)
        if bHighThrustCorr:
            Icorr=Ct_eff> Ct_c
            Inorm=Ct_eff<=Ct_c
            # Spera correction
            a[Icorr]=(Ct_eff[Icorr]-4*ac**2)/(4*(1-2*ac));
            a[Inorm]=1/2*(1-np.sqrt(1-Ct_eff[Inorm]))
        else:
            a=1/2*(1-np.sqrt(1-Ct_eff));

        # Using Cq
        if Cq is not None:
            a_2     = 1 - lambda_r*Cq/k
            k2      = Cq*lambda_r/(1-a)
            a_prime = k2/(4*lambda_r**2)
            misc['k_Cq'] = k2
    else:
        raise NotImplementedError('')
    misc['Ct_KJ']  = Ct_KJ
    misc['Ct_eff'] = Ct_eff
    misc['Ct_rot'] = Ct_rot
    return a,a_prime,misc
//  [python]
def InductionsFromCirculation_VC_Cont(vr_bar,lambda_r,k,bSwirl,method='analytical',bHighThrustCorr=True,Cq=None):
    """ 
    Based on "Continuous formulation". Based on script fInductionCoefficientsCylinders.py
    If Cq is provided, an attempt of using it is made.
         Not recommended, results in lower Tangential inductions
         The circulation obtained from Cq is not smooth

    For now the continuous results seems a bit off on the axial induction compared to the discrete ones
    The tangential induction seem to be the same for the continuous and discrete case
    """
    # Critical values for high-thrust Spera correction
    ac   = 0.34
    Ct_c = 4*ac*(1-ac)
    misc={}
    # Safety
    if lambda_r[0]==0:
        lambda_r[0]=lambda_r[1]*0.01;
    # --- Finding Cylinders intensities
    if method.lower()=='analytical':
        if bSwirl:
            a_prime = k/(4*lambda_r**2) # NOTE: entirely determined from Gamma! Eq.(38)
            Ir=np.arange(len(k)-1,-1,-1)
            Ct_rot = -8*sciint.cumulative_trapezoid(lambda_r[Ir]**2*a_prime[Ir]**2/vr_bar[Ir], vr_bar[Ir])# Eq.(6)
            Ct_rot = np.concatenate(([0],Ct_rot))
            Ct_rot=Ct_rot[Ir];
        else:
            a_prime = k*0
            Ct_rot = k*0
        Ct_KJ  = k*(1+a_prime)
        Ct_eff = Ct_KJ-Ct_rot 
        a=np.zeros(vr_bar.shape)
        if bHighThrustCorr:
            Icorr=Ct_eff> Ct_c
            Inorm=Ct_eff<=Ct_c
            # Spera correction
            a[Icorr]=(Ct_eff[Icorr]-4*ac**2)/(4*(1-2*ac));
            a[Inorm]=1/2*(1-np.sqrt(1-Ct_eff[Inorm]))
        else:
            a=1/2*(1-np.sqrt(1-Ct_eff));

        # Using Cq
        if Cq is not None:
            a_2     = 1 - lambda_r*Cq/k
            k2      = Cq*lambda_r/(1-a)
            a_prime = k2/(4*lambda_r**2)
            misc['k_Cq'] = k2
    else:
        raise NotImplementedError('')
    misc['Ct_KJ']  = Ct_KJ
    misc['Ct_eff'] = Ct_eff
    misc['Ct_rot'] = Ct_rot
    return a,a_prime,misc
//  [python]
def _from_raw_scale_weight(raw_weight: List[float], time_elapsed_target: List[float], approximate_to: List[float], scale_hint: float) -> List[float]:
        """
        trimming: infer extraction phase, which best fits to the scaled erroneous gravimetric flow
        **: supposedly, heater test phase / flush phase
        --: extraction phase (including PI stages)
        ***---------------------------------------******** => raw, cumulative weight values
           <trim_begin ---------------- -trim_end>         => inferred extraction phase
           [-------------------------------------]         => scaled baseline (erroneous gravimetric flow)
        """
        COMPARE_CUMULATIVE_WEIGHT = False

        def sqerr_trimmed_scaled_weight(args: List):  # trim_samples_begin, -trim_samples_end, scale_factor
            trim_begin = round(args[0])
            trim_end = round(-args[1])
            scale = args[2]
            trimmed = raw_weight[trim_begin:trim_end]
            # downsample high freq weight samples to number of time samples
            downsampled = resample(trimmed, len(time_elapsed_target), window=40.0)
            scaled_cumulative = integration.cumtrapz([scale * v for v in approximate_to], time_elapsed_target)
            return sum((v0 - v1) ** 2 for (v0, v1) in zip(downsampled, scaled_cumulative))
        # minimize squared error between trimmed, downsampled cumulative weight <> scaled cumulative weight
        # adjusting trimming range(begin, end), and weight correction factor
        trim_opt = optimize.minimize(sqerr_trimmed_scaled_weight, [100, 35, scale_hint], method='Nelder-Mead')
        if trim_opt.status == 0:
            print('Raw gravimetric flow estimation: Trim[%.02f, -%.02f], x%.02f' % (trim_opt.x[0], trim_opt.x[1], trim_opt.x[2]))
        else:
            raise RuntimeError('Optimization for gravimetric flow estimation failed!')
        if COMPARE_CUMULATIVE_WEIGHT:
            scaled = [trim_opt.x[2] * v for v in approximate_to]
            plt.plot(time_elapsed_target, [0.0] + [v for v in integration.cumtrapz(scaled, time_elapsed_target)], label='weight scaled (g/s)')

        weight_trimmed = raw_weight[round(trim_opt.x[0]):round(-trim_opt.x[1])]
        # downsample inferred extraction phase then remove some FFT artifacts
        downsampled = list(map(lambda v: 0 if v < 0.05 else v, resample(weight_trimmed, len(time_elapsed_target), window=42.0)))

        if COMPARE_CUMULATIVE_WEIGHT:
            _t = list()
            for i in range(len(time_elapsed_target)):
                _t.append(time_elapsed_target[-1] / len(time_elapsed_target) * i)
            plt.plot(_t, downsampled, label='derived weight (g/s)')
            plt.legend()

        derivative = list()
        dt = time_elapsed_target[-1] / len(time_elapsed_target)
        for w0, w1 in zip(downsampled[:-1], downsampled[1:]):
            dw = max(0, w1 - w0)
            derivative.append(dw / dt)
        print('WARNING: shot now weighs %.02fg' % integration.trapz(derivative, dx=dt))
        return [0.0] + derivative
//  [python]
def _from_raw_scale_weight(raw_weight: List[float], time_elapsed_target: List[float], approximate_to: List[float], scale_hint: float) -> List[float]:
        """
        trimming: infer extraction phase, which best fits to the scaled erroneous gravimetric flow
        **: supposedly, heater test phase / flush phase
        --: extraction phase (including PI stages)
        ***---------------------------------------******** => raw, cumulative weight values
           <trim_begin ---------------- -trim_end>         => inferred extraction phase
           [-------------------------------------]         => scaled baseline (erroneous gravimetric flow)
        """
        COMPARE_CUMULATIVE_WEIGHT = False

        def sqerr_trimmed_scaled_weight(args: List):  # trim_samples_begin, -trim_samples_end, scale_factor
            trim_begin = round(args[0])
            trim_end = round(-args[1])
            scale = args[2]
            trimmed = raw_weight[trim_begin:trim_end]
            # downsample high freq weight samples to number of time samples
            downsampled = resample(trimmed, len(time_elapsed_target), window=40.0)
            scaled_cumulative = integration.cumulative_trapezoid([scale * v for v in approximate_to], time_elapsed_target)
            return sum((v0 - v1) ** 2 for (v0, v1) in zip(downsampled, scaled_cumulative))
        # minimize squared error between trimmed, downsampled cumulative weight <> scaled cumulative weight
        # adjusting trimming range(begin, end), and weight correction factor
        trim_opt = optimize.minimize(sqerr_trimmed_scaled_weight, [100, 35, scale_hint], method='Nelder-Mead')
        if trim_opt.status == 0:
            print('Raw gravimetric flow estimation: Trim[%.02f, -%.02f], x%.02f' % (trim_opt.x[0], trim_opt.x[1], trim_opt.x[2]))
        else:
            raise RuntimeError('Optimization for gravimetric flow estimation failed!')
        if COMPARE_CUMULATIVE_WEIGHT:
            scaled = [trim_opt.x[2] * v for v in approximate_to]
            plt.plot(time_elapsed_target, [0.0] + [v for v in integration.cumulative_trapezoid(scaled, time_elapsed_target)], label='weight scaled (g/s)')

        weight_trimmed = raw_weight[round(trim_opt.x[0]):round(-trim_opt.x[1])]
        # downsample inferred extraction phase then remove some FFT artifacts
        downsampled = list(map(lambda v: 0 if v < 0.05 else v, resample(weight_trimmed, len(time_elapsed_target), window=42.0)))

        if COMPARE_CUMULATIVE_WEIGHT:
            _t = list()
            for i in range(len(time_elapsed_target)):
                _t.append(time_elapsed_target[-1] / len(time_elapsed_target) * i)
            plt.plot(_t, downsampled, label='derived weight (g/s)')
            plt.legend()

        derivative = list()
        dt = time_elapsed_target[-1] / len(time_elapsed_target)
        for w0, w1 in zip(downsampled[:-1], downsampled[1:]):
            dw = max(0, w1 - w0)
            derivative.append(dw / dt)
        print('WARNING: shot now weighs %.02fg' % integration.trapz(derivative, dx=dt))
        return [0.0] + derivative
//  [python]
def log_number_density_high(self, mstar=0.5, gas=0):
        # Get the high resolution gas density in cylindrical coordinates.

        r, z, logrho_gas = self.log_gas_density_high(mstar=mstar)

        logn_H2 = logrho_gas + numpy.log(0.8 / (2.37*m_p))

        if gas < 0:
            return r, z, logn_H2
        else:
            # Take account of the abundance.

            logn = logn_H2 + numpy.log(self.abundance[gas])

            # Account for freezeout as well.

            T = self.temperature(r[:,0], numpy.array([0.,2*numpy.pi]), z[0,:], \
                    coordsys="cylindrical")[:,0,:]

            frozen = T < self.freezeout[gas]

            # Account for photodissociation.

            n_H2 = numpy.exp(logn_H2)

            cumn = -scipy.integrate.cumtrapz(n_H2[:,::-1], x=z[:,::-1]*AU, \
                    axis=1, initial=0.)[:,::-1]

            dissociated = cumn < 0.79 * 1.59e21 / 0.706

            # Now actually reduce the density.

            logn[numpy.logical_or(frozen, dissociated)] += numpy.log(1.0e-8)

            return r, z, logn
//  [python]
def log_number_density_high(self, mstar=0.5, gas=0):
        # Get the high resolution gas density in cylindrical coordinates.

        r, z, logrho_gas = self.log_gas_density_high(mstar=mstar)

        logn_H2 = logrho_gas + numpy.log(0.8 / (2.37*m_p))

        if gas < 0:
            return r, z, logn_H2
        else:
            # Take account of the abundance.

            logn = logn_H2 + numpy.log(self.abundance[gas])

            # Account for freezeout as well.

            T = self.temperature(r[:,0], numpy.array([0.,2*numpy.pi]), z[0,:], \
                    coordsys="cylindrical")[:,0,:]

            frozen = T < self.freezeout[gas]

            # Account for photodissociation.

            n_H2 = numpy.exp(logn_H2)

            cumn = -scipy.integrate.cumulative_trapezoid(n_H2[:,::-1], x=z[:,::-1]*AU, \
                    axis=1, initial=0.)[:,::-1]

            dissociated = cumn < 0.79 * 1.59e21 / 0.706

            # Now actually reduce the density.

            logn[numpy.logical_or(frozen, dissociated)] += numpy.log(1.0e-8)

            return r, z, logn
//  [python]
def cumtrapz(self, axis=-1, fudge_factor=None, initial=0):
        """Cumulatively integrate field over a single axis

        Args:
            axis (str, int): axis name or index
            fudge_factor (callable): function that is called with
                func(data, crd_arr), where crd_arr is shaped. This is
                useful for including parts of the jacobian, like
                sin(theta) dtheta.
            initial (float): Initial value

        Returns:
            Field
        """
        ret = None

        try:
            from scipy.integrate import cumtrapz as _sp_cumtrapz

            if axis in self.crds.axes:
                axis = self.crds.axes.index(axis)
            assert isinstance(axis, (int, np.integer))
            crd_arr = self.get_crd(axis, shaped=True)

            try:
                crd_arr = np.expand_dims(crd_arr, axis=self.nr_comp)
                if self.nr_comp > axis:
                    fld_axis = axis
                else:
                    fld_axis = axis + 1
            except TypeError:
                fld_axis = axis

            if fudge_factor is None:
                arr = self.data
            else:
                arr = self.data * fudge_factor(self.data, crd_arr)

            ret = viscid.empty_like(self)
            ret.data = _sp_cumtrapz(arr, crd_arr.reshape(-1), axis=fld_axis,
                                    initial=initial)
        except ImportError:
            viscid.logger.error("Scipy is required to perform cumtrapz")
            raise

        return ret
//  [python]
def cumtrapz(self, axis=-1, fudge_factor=None, initial=0):
        """Cumulatively integrate field over a single axis

        Args:
            axis (str, int): axis name or index
            fudge_factor (callable): function that is called with
                func(data, crd_arr), where crd_arr is shaped. This is
                useful for including parts of the jacobian, like
                sin(theta) dtheta.
            initial (float): Initial value

        Returns:
            Field
        """
        ret = None

        try:
            from scipy.integrate import cumulative_trapezoid as _sp_cumtrapz

            if axis in self.crds.axes:
                axis = self.crds.axes.index(axis)
            assert isinstance(axis, (int, np.integer))
            crd_arr = self.get_crd(axis, shaped=True)

            try:
                crd_arr = np.expand_dims(crd_arr, axis=self.nr_comp)
                if self.nr_comp > axis:
                    fld_axis = axis
                else:
                    fld_axis = axis + 1
            except TypeError:
                fld_axis = axis

            if fudge_factor is None:
                arr = self.data
            else:
                arr = self.data * fudge_factor(self.data, crd_arr)

            ret = viscid.empty_like(self)
            ret.data = _sp_cumtrapz(arr, crd_arr.reshape(-1), axis=fld_axis,
                                    initial=initial)
        except ImportError:
            viscid.logger.error("Scipy is required to perform cumtrapz")
            raise

        return ret
//  [python]
def mock_cdf(x, normalize=True):
    """CDF of mock SFRs w/ errors relative to SF sequence."""
    sel_SFR_mock = (y_mock >= f_detection * e_y_mock)
    fsel = np.sum(sel_SFR_mock)/len(sel_SFR_mock)
    hist, bin_edges = np.histogram(
        np.log10(y_mock[sel_SFR_mock]/mu_mock[sel_SFR_mock]),
        np.linspace(-5.5, 2., 500), density=True)
    bin_center = 0.5*(bin_edges[1:] + bin_edges[:-1])
    hist = np.convolve(hist, np.ones((5,))/5., mode='same')
    add = 0
    if not normalize:
        hist *= fsel
        add = (1-fsel)
    cum_hist = scipy.integrate.cumtrapz(hist, bin_center, initial=0) + add
    return np.interp(x, bin_center, cum_hist)
//  [python]
def mock_cdf(x, normalize=True):
    """CDF of mock SFRs w/ errors relative to SF sequence."""
    sel_SFR_mock = (y_mock >= f_detection * e_y_mock)
    fsel = np.sum(sel_SFR_mock)/len(sel_SFR_mock)
    hist, bin_edges = np.histogram(
        np.log10(y_mock[sel_SFR_mock]/mu_mock[sel_SFR_mock]),
        np.linspace(-5.5, 2., 500), density=True)
    bin_center = 0.5*(bin_edges[1:] + bin_edges[:-1])
    hist = np.convolve(hist, np.ones((5,))/5., mode='same')
    add = 0
    if not normalize:
        hist *= fsel
        add = (1-fsel)
    cum_hist = scipy.integrate.cumulative_trapezoid(hist, bin_center, initial=0) + add
    return np.interp(x, bin_center, cum_hist)
//  [python]
def calc_gint(r, beta):
    """ Calculate the Jeans velocity anisotropy integral g(r) defined as:
    .. math::
        g(r) = exp( 2 \int beta(r) / r dr )

    where:
        beta(r) is the velocity anisotropy
        r is the 3d radius
    """
    # check if r is equally spaced
    dr = r[1] - r[0]
    if np.any(np.abs(np.diff(r) - dr) > 1e-6):
        g = np.exp(integrate.cumtrapz(2 * beta / r, x=r))
    else:
        g = np.exp(integrate.cumtrapz(2 * beta / r, dx=dr))
    g = np.append(g, g[-1])
    return g
//  [python]
def calc_gint(r, beta):
    """ Calculate the Jeans velocity anisotropy integral g(r) defined as:
    .. math::
        g(r) = exp( 2 \int beta(r) / r dr )

    where:
        beta(r) is the velocity anisotropy
        r is the 3d radius
    """
    # check if r is equally spaced
    dr = r[1] - r[0]
    if np.any(np.abs(np.diff(r) - dr) > 1e-6):
        g = np.exp(integrate.cumulative_trapezoid(2 * beta / r, x=r))
    else:
        g = np.exp(integrate.cumulative_trapezoid(2 * beta / r, dx=dr))
    g = np.append(g, g[-1])
    return g
//  [python]
def set_filling(h,filling=0.5,nk=10,extrae=0.,delta=1e-1):
    """
    Set the filling of a Hamiltonian
    - nk = 10, number of kpoints in each direction
    - filling = 0.5, filling of the lattice
    - extrae = 0.0, number of extra electrons
    """
    if h.has_eh: # quick workaround
        ef = h.get_fermi4filling(filling,nk=nk) # fermi energy
        h.add_onsite(-ef)
        return
    fill = filling + extrae/h.intra.shape[0] # filling
    n = h.intra.shape[0]
    use_kpm = False
    if n>algebra.maxsize: # use the KPM method
        use_kpm = True
        print("Using KPM in set_filling")
    if use_kpm: # use KPM
        es,ds = h.get_dos(energies=np.linspace(-5.0,5.0,1000),
                use_kpm=True,delta=delta,nk=nk,random=False)
        from scipy.integrate import cumtrapz
        di = cumtrapz(ds,es)
        ei = (es[0:len(es)-1] + es[1:len(es)])/2.
        di /= di[len(di)-1] # normalize
        from scipy.interpolate import interp1d
        f = interp1d(di,ei) # interpolating function
        efermi = f(fill) # get the fermi energy
    else: # dense Hamiltonian, use ED
        es = eigenvalues(h,nk=nk,notime=True)
        efermi = get_fermi_energy(es,fill)
    h.shift_fermi(-efermi)
//  [python]
def set_filling(h,filling=0.5,nk=10,extrae=0.,delta=1e-1):
    """
    Set the filling of a Hamiltonian
    - nk = 10, number of kpoints in each direction
    - filling = 0.5, filling of the lattice
    - extrae = 0.0, number of extra electrons
    """
    if h.has_eh: # quick workaround
        ef = h.get_fermi4filling(filling,nk=nk) # fermi energy
        h.add_onsite(-ef)
        return
    fill = filling + extrae/h.intra.shape[0] # filling
    n = h.intra.shape[0]
    use_kpm = False
    if n>algebra.maxsize: # use the KPM method
        use_kpm = True
        print("Using KPM in set_filling")
    if use_kpm: # use KPM
        es,ds = h.get_dos(energies=np.linspace(-5.0,5.0,1000),
                use_kpm=True,delta=delta,nk=nk,random=False)
        from scipy.integrate import cumulative_trapezoid
        di = cumulative_trapezoid(ds,es)
        ei = (es[0:len(es)-1] + es[1:len(es)])/2.
        di /= di[len(di)-1] # normalize
        from scipy.interpolate import interp1d
        f = interp1d(di,ei) # interpolating function
        efermi = f(fill) # get the fermi energy
    else: # dense Hamiltonian, use ED
        es = eigenvalues(h,nk=nk,notime=True)
        efermi = get_fermi_energy(es,fill)
    h.shift_fermi(-efermi)
//  [python]
def delo_intensity(dx=np.array([1.]),j=np.array([1.,0.,0.,0.]),a=np.array([1.,0.,0.,0.]),rho=np.array([0.,0.,0.]),I0=np.array([0.,0.,0.,0.]),thin=1e-2):
    x = np.append(0.,np.cumsum(dx))
#    if len(dx) < 2:
#        dx = x
#    else:
#        dx = np.append(x[0],x[1:]-x[0:-1])
    if len(np.shape(a)) < 2:
# reform a,rho,j arrays to be of right size
        a = np.tile(a,len(x)).reshape(len(x),4)
        rho = np.tile(rho,len(x)).reshape(len(x),3)
        j = np.tile(j,len(x)).reshape(len(x),4)
        
#    ki4 = np.transpose(np.tile(a[:,0],4).reshape(4,len(x)))
    i = np.zeros((len(x),4)); Q = np.zeros((len(x),4,4)); P = np.zeros((len(x),4)); im = np.zeros((len(x),4,4))
    QQ = np.zeros((len(x),4,4)); PP = np.zeros((len(x),4)); imm = np.zeros((len(x),4,4)); ii = np.zeros((len(x),4))
#    i[0,:] = I0
#    tau = -(scipy.integrate.cumtrapz(x[-1]-x,a[::-1,0]))[::-1]
    tau = np.append(0.,-scipy.integrate.cumtrapz(a[:,0],x[::-1]))
#    delta = a[:,0]*dx
    delta = tau[1:] - tau[0:-1]
    E = np.exp(-delta)
    F = 1.-E
    G = (1.-(1.+delta)*E)/delta
# opt thin version to avoid errors from 1/delta w/ delta --> 0
    Gt = 0.5*delta
    Ft = delta
    Et = 1.-delta
# integration is from deepest point out for starting intensity I0
    i[-1,:] = I0; ii[-1,:] = I0; iprev = I0; iprevt = I0
    for k in (range(len(x)-1))[::-1]:
#        print 'k: ',k,len(F),len(G),len(delta)
        K = opacity_matrix(a[k,:],rho[k,:])
        K1 = opacity_matrix(a[k+1,:],rho[k+1,:])
        Sp = j[k,:]/a[k,0]
        Sp1 = j[k+1,:]/a[k+1,0]
        Kp = K/a[k,0]-np.identity(4); Kp1 = K1/a[k+1,0]-np.identity(4)
        matrix,imatrix = invert_delo_matrix(F[k],G[k],Kp)
        mt,imt = invert_delo_matrix_thin(dx[k],K,a[k,0],delta[k])
        pt = calc_delo_P(imatrix,F[k],G[k],Sp,Sp1)
        qt = calc_delo_Q(imatrix,E[k],F[k],G[k],Kp1)
        ptt = calc_delo_P_thin(imt,dx[k],j[k,:],j[k+1,:],a[k,0],a[k+1,0])
        qtt = calc_delo_Q_thin(imt,dx[k],a[k,0],a[k+1,0],K1)
        mtt,imtt = invert_delo_matrix(Ft[k],Gt[k],Kp)
#        pttt = calc_delo_P(imatrix,Ft[k],Gt[k],Sp,Sp1)
#        qttt = calc_delo_Q(imatrix,Et[k],Ft[k],Gt[k],Kp1)
        if delta[k] > thin:
            i[k,:] = pt + qt.dot(iprev)
        else:
            i[k,:] = ptt + qtt.dot(iprev)
        P[k,:] = pt
        Q[k,:,:] = qt
        im[k,:,:] = imatrix
        imm[k,:,:] = imt
        QQ[k,:,:] = qtt
        PP[k,:] = ptt
        iprev = i[k,:]
        iprevt = ii[k,:]
        
    return i,Q,P,im,delta,dx,QQ,PP,imm,ii
//  [python]
def delo_intensity(dx=np.array([1.]),j=np.array([1.,0.,0.,0.]),a=np.array([1.,0.,0.,0.]),rho=np.array([0.,0.,0.]),I0=np.array([0.,0.,0.,0.]),thin=1e-2):
    x = np.append(0.,np.cumsum(dx))
#    if len(dx) < 2:
#        dx = x
#    else:
#        dx = np.append(x[0],x[1:]-x[0:-1])
    if len(np.shape(a)) < 2:
# reform a,rho,j arrays to be of right size
        a = np.tile(a,len(x)).reshape(len(x),4)
        rho = np.tile(rho,len(x)).reshape(len(x),3)
        j = np.tile(j,len(x)).reshape(len(x),4)
        
#    ki4 = np.transpose(np.tile(a[:,0],4).reshape(4,len(x)))
    i = np.zeros((len(x),4)); Q = np.zeros((len(x),4,4)); P = np.zeros((len(x),4)); im = np.zeros((len(x),4,4))
    QQ = np.zeros((len(x),4,4)); PP = np.zeros((len(x),4)); imm = np.zeros((len(x),4,4)); ii = np.zeros((len(x),4))
#    i[0,:] = I0
#    tau = -(scipy.integrate.cumtrapz(x[-1]-x,a[::-1,0]))[::-1]
    tau = np.append(0.,-scipy.integrate.cumulative_trapezoid(a[:,0],x[::-1]))
#    delta = a[:,0]*dx
    delta = tau[1:] - tau[0:-1]
    E = np.exp(-delta)
    F = 1.-E
    G = (1.-(1.+delta)*E)/delta
# opt thin version to avoid errors from 1/delta w/ delta --> 0
    Gt = 0.5*delta
    Ft = delta
    Et = 1.-delta
# integration is from deepest point out for starting intensity I0
    i[-1,:] = I0; ii[-1,:] = I0; iprev = I0; iprevt = I0
    for k in (range(len(x)-1))[::-1]:
#        print 'k: ',k,len(F),len(G),len(delta)
        K = opacity_matrix(a[k,:],rho[k,:])
        K1 = opacity_matrix(a[k+1,:],rho[k+1,:])
        Sp = j[k,:]/a[k,0]
        Sp1 = j[k+1,:]/a[k+1,0]
        Kp = K/a[k,0]-np.identity(4); Kp1 = K1/a[k+1,0]-np.identity(4)
        matrix,imatrix = invert_delo_matrix(F[k],G[k],Kp)
        mt,imt = invert_delo_matrix_thin(dx[k],K,a[k,0],delta[k])
        pt = calc_delo_P(imatrix,F[k],G[k],Sp,Sp1)
        qt = calc_delo_Q(imatrix,E[k],F[k],G[k],Kp1)
        ptt = calc_delo_P_thin(imt,dx[k],j[k,:],j[k+1,:],a[k,0],a[k+1,0])
        qtt = calc_delo_Q_thin(imt,dx[k],a[k,0],a[k+1,0],K1)
        mtt,imtt = invert_delo_matrix(Ft[k],Gt[k],Kp)
#        pttt = calc_delo_P(imatrix,Ft[k],Gt[k],Sp,Sp1)
#        qttt = calc_delo_Q(imatrix,Et[k],Ft[k],Gt[k],Kp1)
        if delta[k] > thin:
            i[k,:] = pt + qt.dot(iprev)
        else:
            i[k,:] = ptt + qtt.dot(iprev)
        P[k,:] = pt
        Q[k,:,:] = qt
        im[k,:,:] = imatrix
        imm[k,:,:] = imt
        QQ[k,:,:] = qtt
        PP[k,:] = ptt
        iprev = i[k,:]
        iprevt = ii[k,:]
        
    return i,Q,P,im,delta,dx,QQ,PP,imm,ii
//  [python]
def extract_glottal_signal(x, fs):
    """Extract the glottal flow and the glottal flow derivative signals

    :param x: data from the speech signal.
    :param fs: sampling frequency
    :returns: glottal signal
    :returns: derivative  of the glottal signal
    :returns: glottal closure instants

    >>> from scipy.io.wavfile import read
    >>> glottal=Glottal()
    >>> file_audio="../audios/001_a1_PCGITA.wav"
    >>> fs, data_audio=read(audio)
    >>> glottal, g_iaif, GCIs=glottal.extract_glottal_signal(data_audio, fs)

    """
    winlen = int(0.025*fs)
    winshift = int(0.005*fs)
    x = x-np.mean(x)
    x = x/float(np.max(np.abs(x)))
    GCIs = se_vq_varf0(x, fs)
    g_iaif = np.zeros(len(x))
    glottal = np.zeros(len(x))

    if GCIs is None:
        sys.warn("not enought voiced segments were found to compute GCI")
        return glottal, g_iaif, GCIs

    start = 0
    stop = int(start+winlen)
    win = np.hanning(winlen)

    while stop <= len(x):

        x_frame = x[start:stop]
        pGCIt = np.where((GCIs > start) & (GCIs < stop))[0]
        GCIt = GCIs[pGCIt]-start

        g_iaif_f = iaif(x_frame, fs, GCIt)
        glottal_f = cumtrapz(g_iaif_f, dx=1/fs)
        glottal_f = np.hstack((glottal[start], glottal_f))
        g_iaif[start:stop] = g_iaif[start:stop]+g_iaif_f*win
        glottal[start:stop] = glottal[start:stop]+glottal_f*win
        start = start+winshift
        stop = start+winlen
    g_iaif = g_iaif-np.mean(g_iaif)
    g_iaif = g_iaif/max(abs(g_iaif))

    glottal = glottal-np.mean(glottal)
    glottal = glottal/max(abs(glottal))
    glottal = glottal-np.mean(glottal)
    glottal = glottal/max(abs(glottal))

    return glottal, g_iaif, GCIs
//  [python]
def extract_glottal_signal(x, fs):
    """Extract the glottal flow and the glottal flow derivative signals

    :param x: data from the speech signal.
    :param fs: sampling frequency
    :returns: glottal signal
    :returns: derivative  of the glottal signal
    :returns: glottal closure instants

    >>> from scipy.io.wavfile import read
    >>> glottal=Glottal()
    >>> file_audio="../audios/001_a1_PCGITA.wav"
    >>> fs, data_audio=read(audio)
    >>> glottal, g_iaif, GCIs=glottal.extract_glottal_signal(data_audio, fs)

    """
    winlen = int(0.025*fs)
    winshift = int(0.005*fs)
    x = x-np.mean(x)
    x = x/float(np.max(np.abs(x)))
    GCIs = se_vq_varf0(x, fs)
    g_iaif = np.zeros(len(x))
    glottal = np.zeros(len(x))

    if GCIs is None:
        sys.warn("not enought voiced segments were found to compute GCI")
        return glottal, g_iaif, GCIs

    start = 0
    stop = int(start+winlen)
    win = np.hanning(winlen)

    while stop <= len(x):

        x_frame = x[start:stop]
        pGCIt = np.where((GCIs > start) & (GCIs < stop))[0]
        GCIt = GCIs[pGCIt]-start

        g_iaif_f = iaif(x_frame, fs, GCIt)
        glottal_f = scipy.integrate.cumulative_trapezoid(g_iaif_f, dx=1/fs)
        glottal_f = np.hstack((glottal[start], glottal_f))
        g_iaif[start:stop] = g_iaif[start:stop]+g_iaif_f*win
        glottal[start:stop] = glottal[start:stop]+glottal_f*win
        start = start+winshift
        stop = start+winlen
    g_iaif = g_iaif-np.mean(g_iaif)
    g_iaif = g_iaif/max(abs(g_iaif))

    glottal = glottal-np.mean(glottal)
    glottal = glottal/max(abs(glottal))
    glottal = glottal-np.mean(glottal)
    glottal = glottal/max(abs(glottal))

    return glottal, g_iaif, GCIs
//  [python]
def _raw_calc_arias_intensity(acc, dt):
    from scipy.integrate import cumtrapz
    return np.pi / (2 * 9.81) * cumtrapz(acc ** 2, dx=dt, initial=0)
//  [python]
def _raw_calc_arias_intensity(acc, dt):
    from scipy.integrate import cumulative_trapezoid
    return np.pi / (2 * 9.81) * cumulative_trapezoid(acc ** 2, dx=dt, initial=0)
//  [python]
def _estimate_lean(self):
        """Add estimates of lean angle using measurements of accelerometer
        and gyroscope. For the accelerometer calculation, the system is
        assumed static.
        """
        data_ax = self.get_field_data('mpu6050.accelerometer_x')
        data_ay = self.get_field_data('mpu6050.accelerometer_y')
        data_az = self.get_field_data('mpu6050.accelerometer_z')
        data_axayaz = np.vstack([data_ax, data_ay, data_az])
        magnitude = np.apply_along_axis(np.linalg.norm, 0, data_axayaz)
        self.dtype_c['lean_accel'] = np.float32
        #self.data_c['lean_accel']= np.arcsin(data_ax / magnitude) * 180 / np.pi
        self.data_c['lean_accel']= np.arcsin(data_ax / magnitude)

        data_gyro = self.get_field_data('mpu6050.gyroscope_x')
        data_time = self.get_field_data('system_time_s')
        self.dtype_c['lean_gyro'] = np.float32
        init_lean = self.get_field_data('lean_accel')[0]
        self.data_c['lean_gyro'] = (scipy.integrate.cumtrapz(data_gyro,
                                                             data_time,
                                                             initial=0) +
                                    init_lean)
//  [python]
def _estimate_lean(self):
        """Add estimates of lean angle using measurements of accelerometer
        and gyroscope. For the accelerometer calculation, the system is
        assumed static.
        """
        data_ax = self.get_field_data('mpu6050.accelerometer_x')
        data_ay = self.get_field_data('mpu6050.accelerometer_y')
        data_az = self.get_field_data('mpu6050.accelerometer_z')
        data_axayaz = np.vstack([data_ax, data_ay, data_az])
        magnitude = np.apply_along_axis(np.linalg.norm, 0, data_axayaz)
        self.dtype_c['lean_accel'] = np.float32
        #self.data_c['lean_accel']= np.arcsin(data_ax / magnitude) * 180 / np.pi
        self.data_c['lean_accel']= np.arcsin(data_ax / magnitude)

        data_gyro = self.get_field_data('mpu6050.gyroscope_x')
        data_time = self.get_field_data('system_time_s')
        self.dtype_c['lean_gyro'] = np.float32
        init_lean = self.get_field_data('lean_accel')[0]
        self.data_c['lean_gyro'] = (scipy.integrate.cumulative_trapezoid(data_gyro,
                                                             data_time,
                                                             initial=0) +
                                    init_lean)
//  [python]
def __integrate_dxdt_hat_matrix__(dxdt_hat, dt):
    """
    :param dxdt_hat:
    :param dt:
    :return:
    """
    #assert isinstance(dxdt_hat, np.matrix)
    if len(dxdt_hat.shape) == 1:
        dxdt_hat = np.reshape(dxdt_hat, [1, len(dxdt_hat)])
    x = np.array(scipy.integrate.cumtrapz(dxdt_hat, axis=1))
    first_value = x[:, 0:1] - np.mean(dxdt_hat[:, 0:1], axis=1).reshape(dxdt_hat.shape[0], 1)
    x = np.hstack((first_value, x))*dt
    return x
//  [python]
def __integrate_dxdt_hat_matrix__(dxdt_hat, dt):
    """
    :param dxdt_hat:
    :param dt:
    :return:
    """
    #assert isinstance(dxdt_hat, np.matrix)
    if len(dxdt_hat.shape) == 1:
        dxdt_hat = np.reshape(dxdt_hat, [1, len(dxdt_hat)])
    x = np.array(scipy.integrate.cumulative_trapezoid(dxdt_hat, axis=1))
    first_value = x[:, 0:1] - np.mean(dxdt_hat[:, 0:1], axis=1).reshape(dxdt_hat.shape[0], 1)
    x = np.hstack((first_value, x))*dt
    return x
//  [python]
def ana_likelihood(self, rv, leff, fakedata, errors, model, prior,mylikelihood=mcmc.LogLikelihood, covariance_model_funct=None, otherp=None):
        ll = mylikelihood(xvals=leff, yvals=fakedata, errors=errors,model = model, flatprior=prior, covariance_model_funct=covariance_model_funct)

        like = np.zeros_like(rv)
        for i in range(len(rv)):
            like[i] = np.exp(ll([rv[i]]))
            #print(rv[i],ll([rv[i]]),like[i])
            maxL = rv[like == np.max(like)]
            cumint = scipy.integrate.cumtrapz(like, x=rv)
            cumint = cumint / np.max(cumint)
            onesigma = np.interp(0.68, cumint, rv[1:])
        if otherp:
            other = np.interp(otherp, cumint, rv[1:])
            return like, cumint, onesigma, other, maxL
        else:
            return like, cumint, onesigma, maxL
//  [python]
def ana_likelihood(self, rv, leff, fakedata, errors, model, prior,mylikelihood=mcmc.LogLikelihood, covariance_model_funct=None, otherp=None):
        ll = mylikelihood(xvals=leff, yvals=fakedata, errors=errors,model = model, flatprior=prior, covariance_model_funct=covariance_model_funct)

        like = np.zeros_like(rv)
        for i in range(len(rv)):
            like[i] = np.exp(ll([rv[i]]))
            #print(rv[i],ll([rv[i]]),like[i])
            maxL = rv[like == np.max(like)]
            cumint = scipy.integrate.cumulative_trapezoid(like, x=rv)
            cumint = cumint / np.max(cumint)
            onesigma = np.interp(0.68, cumint, rv[1:])
        if otherp:
            other = np.interp(otherp, cumint, rv[1:])
            return like, cumint, onesigma, other, maxL
        else:
            return like, cumint, onesigma, maxL
//  [python]
def calc_cav(acc_sig):
    """
    Calculates the Cumulative Absolute velocity

    ref:
    Electrical Power Research Institute. Standardization of the Cumulative
    Absolute Velocity. 1991. EPRI TR-100082-1'2, Palo Alto, California.
    """
    from scipy.integrate import cumtrapz
    abs_acc = np.abs(acc_sig.values)
    return cumtrapz(abs_acc, dx=acc_sig.dt, initial=0)
//  [python]
def calc_cav(acc_sig):
    """
    Calculates the Cumulative Absolute velocity

    ref:
    Electrical Power Research Institute. Standardization of the Cumulative
    Absolute Velocity. 1991. EPRI TR-100082-1'2, Palo Alto, California.
    """
    from scipy.integrate import cumulative_trapezoid
    abs_acc = np.abs(acc_sig.values)
    return cumulative_trapezoid(abs_acc, dx=acc_sig.dt, initial=0)
//  [python]
def stepresponse(self):
        """Step respose of RTD"""
        return cumtrapz(self.exitage, self.time, initial=0)
//  [python]
def stepresponse(self):
        """Step respose of RTD"""
        return cumulative_trapezoid(self.exitage, self.time, initial=0)
//  [python]
def stepresponse_norm(self):
        """Normalized step respose of RTD"""
        return cumtrapz(self.exitage_norm, self.time, initial=0)
//  [python]
def stepresponse_norm(self):
        """Normalized step respose of RTD"""
        return cumulative_trapezoid(self.exitage_norm, self.time, initial=0)
//  [python]
def calc_isv(acc_sig):
    """
    Calculates the integral of the squared velocity

    See Kokusho (2013)
    :return:
    """
    from scipy.integrate import cumtrapz
    return cumtrapz(acc_sig.velocity ** 2, dx=acc_sig.dt, initial=0)
//  [python]
def calc_isv(acc_sig):
    """
    Calculates the integral of the squared velocity

    See Kokusho (2013)
    :return:
    """
    from scipy.integrate import cumulative_trapezoid
    return cumulative_trapezoid(acc_sig.velocity ** 2, dx=acc_sig.dt, initial=0)
//  [python]
def get_channel(self, mother, daughter=None):
        """Reponse function :math:`f(y)` or :math:`g(y)` as
        defined in the note.

        Returns :math:`f(y)` or :math:`g(y)` if a daughter
        index is provided. If the inclusive channel has a redistribution,
        :math:`h(x,y)` will be returned

        Args:
            mother (int): mother nucleus(on)
            daughter (int, optional): daughter nucleus(on)

        Returns:
            (numpy.array) Reponse function on self._ygrid_tab
        """
        from scipy import integrate

        cs_model = self.cross_section
        egrid, cross_section = None, None

        if daughter is not None:
            if (mother, daughter) in self.incl_diff_idcs:
                egrid, cross_section = cs_model.incl_diff(mother, daughter)
            elif (mother, daughter) in self.incl_idcs:
                egrid, cross_section = cs_model.incl(mother, daughter)
            else:
                raise Exception(
                    'Unknown inclusive channel {:} -> {:} for this model'.
                    format(mother, daughter))
        else:
            egrid, cross_section = cs_model.nonel(mother)

    # note that cumtrapz works also for 2d-arrays and will integrate along axis = 1
        integral = integrate.cumtrapz(egrid * cross_section, x=egrid)
        ygrid = egrid[1:] / 2.

        return ygrid, integral / (2 * ygrid**2)
//  [python]
def get_channel(self, mother, daughter=None):
        """Reponse function :math:`f(y)` or :math:`g(y)` as
        defined in the note.

        Returns :math:`f(y)` or :math:`g(y)` if a daughter
        index is provided. If the inclusive channel has a redistribution,
        :math:`h(x,y)` will be returned

        Args:
            mother (int): mother nucleus(on)
            daughter (int, optional): daughter nucleus(on)

        Returns:
            (numpy.array) Reponse function on self._ygrid_tab
        """
        from scipy import integrate

        cs_model = self.cross_section
        egrid, cross_section = None, None

        if daughter is not None:
            if (mother, daughter) in self.incl_diff_idcs:
                egrid, cross_section = cs_model.incl_diff(mother, daughter)
            elif (mother, daughter) in self.incl_idcs:
                egrid, cross_section = cs_model.incl(mother, daughter)
            else:
                raise Exception(
                    'Unknown inclusive channel {:} -> {:} for this model'.
                    format(mother, daughter))
        else:
            egrid, cross_section = cs_model.nonel(mother)

    # note that cumtrapz works also for 2d-arrays and will integrate along axis = 1
        integral = integrate.cumulative_trapezoid(egrid * cross_section, x=egrid)
        ygrid = egrid[1:] / 2.

        return ygrid, integral / (2 * ygrid**2)
//  [python]
def _precompute_interpolators(self):
        """Interpolate each response function and store interpolators.

        Uses :func:`prince_cr.util.get_interp_object` as interpolator.
        This might result in too many knots and can be subject to
        future optimization.
        """

        info(2, 'Computing interpolators for response functions')

        info(5, 'Nonelastic response functions f(y)')
        self.nonel_intp = {}
        for mother in self.nonel_idcs:
            self.nonel_intp[mother] = get_interp_object(
                *self.get_channel(mother))

        info(5, 'Inclusive (boost conserving) response functions g(y)')
        self.incl_intp = {}
        for mother, daughter in self.incl_idcs:
            self.incl_intp[(mother, daughter)] = get_interp_object(
                *self.get_channel(mother, daughter))

        info(5, 'Inclusive (redistributed) response functions h(y)')
        self.incl_diff_intp = {}
        for mother, daughter in self.incl_diff_idcs:
            ygr, rfunc = self.get_channel(mother, daughter)
            self.incl_diff_intp[(mother, daughter)] = get_2Dinterp_object(
                self.xcenters, ygr, rfunc, self.cross_section.xbins)

            from scipy.integrate import cumtrapz
            integral = cumtrapz(rfunc, ygr, axis=1,initial=0)
            integral = cumtrapz(integral, self.xcenters, axis=0,initial=0)

            self.incl_diff_intp_integral[(mother, daughter)] = get_2Dinterp_object(
                self.xcenters, ygr, integral, self.cross_section.xbins)
//  [python]
def _precompute_interpolators(self):
        """Interpolate each response function and store interpolators.

        Uses :func:`prince_cr.util.get_interp_object` as interpolator.
        This might result in too many knots and can be subject to
        future optimization.
        """

        info(2, 'Computing interpolators for response functions')

        info(5, 'Nonelastic response functions f(y)')
        self.nonel_intp = {}
        for mother in self.nonel_idcs:
            self.nonel_intp[mother] = get_interp_object(
                *self.get_channel(mother))

        info(5, 'Inclusive (boost conserving) response functions g(y)')
        self.incl_intp = {}
        for mother, daughter in self.incl_idcs:
            self.incl_intp[(mother, daughter)] = get_interp_object(
                *self.get_channel(mother, daughter))

        info(5, 'Inclusive (redistributed) response functions h(y)')
        self.incl_diff_intp = {}
        for mother, daughter in self.incl_diff_idcs:
            ygr, rfunc = self.get_channel(mother, daughter)
            self.incl_diff_intp[(mother, daughter)] = get_2Dinterp_object(
                self.xcenters, ygr, rfunc, self.cross_section.xbins)

            from scipy.integrate import cumulative_trapezoid
            integral = cumulative_trapezoid(rfunc, ygr, axis=1,initial=0)
            integral = cumulative_trapezoid(integral, self.xcenters, axis=0,initial=0)

            self.incl_diff_intp_integral[(mother, daughter)] = get_2Dinterp_object(
                self.xcenters, ygr, integral, self.cross_section.xbins)