Beispiel #1
0
    def __init__(self, d1, d2, L12=2859.0):
        """
        Calculates the angular resolution for a two slit collimation
        system.

        Parameters
        ----------
        d1 : float
            slit 1 opening
        d2 : float
            slit 2 opening
        L12 : float
            distance between slits
        """

        alpha = (d1 + d2) / 2.0 / L12
        beta = abs(d1 - d2) / 2.0 / L12

        self.alpha = alpha
        self.beta = beta

        c = (alpha - beta) / 2 / alpha
        d = (alpha + beta) / 2 / alpha
        self.rv = stats.trapz(c, d, -alpha, 2 * alpha)
        self.width = alpha
    def correlation_time(self):
        """ Use the inferred covariance matrix to compute and estimate of the correlation time
        by approximating the width of correlation for a central knot with it's neighbors. """

        ## Select a central knot
        i_mid = int(len(self.knots) / 2)

        ## Compute a normalized distribution
        distribution = np.abs(self.cov[i_mid][1:-1])
        distribution = distribution / trapz(distribution, x=self.knots)

        ## Compute the mean and variance
        avg = self.knots[i_mid - 1]
        var = trapz(distribution * (self.knots**2), x=self.knots) - avg**2

        return np.sqrt(var)
Beispiel #3
0
    def __init__(
            self,
            model,
            angle,
            L12=2859,
            footprint=60,
            L2S=120,
            dtheta=3.3,  # angular resolution
            lo_wavelength=2.8,
            hi_wavelength=18,
            dlambda=3.3,
            rebin=2):
        self.model = model

        # turn off resolution smearing
        self.model.dq = 0
        self.bkg = model.bkg.value
        self.angle = angle

        # the fractional width of a square wavelength resolution
        self.dlambda = dlambda / 100.
        self.rebin = rebin / 100.
        self.wavelength_bins = calculate_wavelength_bins(
            lo_wavelength, hi_wavelength, rebin)
        # nominal Q values
        bin_centre = 0.5 * (self.wavelength_bins[1:] +
                            self.wavelength_bins[:-1])
        self.q = general.q(angle, bin_centre)

        # keep a tally of the direct and reflected beam
        self.direct_beam = np.zeros((self.wavelength_bins.size - 1))
        self.reflected_beam = np.zeros((self.wavelength_bins.size - 1))

        # wavelength generator
        a = PN('PLP0000711.nx.hdf')
        q, i, di = a.process(normalise=False,
                             normalise_bins=False,
                             rebin_percent=0,
                             lo_wavelength=lo_wavelength,
                             hi_wavelength=hi_wavelength)
        q = q.squeeze()
        i = i.squeeze()
        self.spectrum_dist = SpectrumDist(q, i)

        # angular resolution generator, based on a trapezoidal distribution
        # The slit settings are the optimised set typically used in an
        # experiment
        self.dtheta = dtheta / 100.
        self.footprint = footprint
        s1, s2 = general.slit_optimiser(footprint,
                                        self.dtheta,
                                        angle=angle,
                                        L2S=L2S,
                                        L12=L12,
                                        verbose=False)
        div, alpha, beta = general.div(s1, s2, L12=L12)
        self.angular_dist = trapz(c=(alpha - beta) / 2. / alpha,
                                  d=(alpha + beta) / 2. / alpha,
                                  loc=-alpha,
                                  scale=2 * alpha)
Beispiel #4
0
    def time_form_gen(self):
        earlyt = .2
        latet = 13.
        midt1 = .4
        midt2 = 4.

        # if param already set on object instantiation, leave it alone
        if 'tf' in self.override:
            self.FSPS_args['tf'] = self.override['tf']
        elif self.tform_key == 'trapz':
            width = self.time0 - earlyt
            tformtrap = stats.trapz(loc=earlyt,
                                    scale=width,
                                    c=(midt1 - earlyt) / width,
                                    d=(midt2 - earlyt) / width)
            tformtrap.random_state = self.RS
            self.FSPS_args['tf'] = tformtrap.rvs()
        elif self.tform_key == 'log':
            self.FSPS_args['tf'] = 10.**self.RS.uniform(low=np.log10(earlyt),
                                                        high=np.log10(latet))
        elif self.tform_key == 'loglinmix':
            # 25-75 mix between log-uniform and lin-uniform
            if np.random.rand() < .25:
                self.FSPS_args['tf'] = 10.**self.RS.uniform(
                    low=np.log10(earlyt), high=np.log10(latet))
            else:
                self.FSPS_args['tf'] = self.RS.uniform(low=earlyt, high=latet)
        elif self.tform_key == 'norm':
            # normal distribution
            tf_min, tf_max = earlyt, latet
            tf_mean = 5.
            tf_std = 4.
            tf_a, tf_b = (tf_min - tf_mean) / tf_std, (tf_max -
                                                       tf_mean) / tf_std
            tf_dist = stats.truncnorm(a=tf_a,
                                      b=tf_b,
                                      loc=tf_mean,
                                      scale=tf_std)
            self.FSPS_args['tf'] = tf_dist.rvs(None, random_state=self.RS)
        else:
            self.FSPS_args['tf'] = self.RS.uniform(low=earlyt, high=latet)
Beispiel #5
0
    def __init__(
        self,
        model,
        angle,
        L12=2859,
        footprint=60,
        L2S=120,
        dtheta=3.3,
        lo_wavelength=2.8,
        hi_wavelength=18,
        dlambda=3.3,
        rebin=2,
        gravity=False,
        force_gaussian=False,
        force_uniform_wavelength=False,
    ):
        self.model = model

        self.bkg = model.bkg.value
        self.angle = angle

        # dlambda refers to the FWHM of the gaussian approximation to a uniform
        # distribution. The full width of the uniform distribution is
        # dlambda/0.68.
        self.dlambda = dlambda / 100.0
        # the rebin percentage refers to the full width of the bins. You have to
        # multiply this value by 0.68 to get the equivalent contribution to the
        # resolution function.
        self.rebin = rebin / 100.0
        self.wavelength_bins = calculate_wavelength_bins(
            lo_wavelength, hi_wavelength, rebin
        )
        bin_centre = 0.5 * (
            self.wavelength_bins[1:] + self.wavelength_bins[:-1]
        )

        # angular deviation due to gravity
        # --> no correction for gravity affecting width of angular resolution
        elevations = 0
        if gravity:
            speeds = general.wavelength_velocity(bin_centre)
            # trajectories through slits for different wavelengths
            trajectories = pm.find_trajectory(L12 / 1000.0, 0, speeds)
            # elevation at sample
            elevations = pm.elevation(
                trajectories, speeds, (L12 + L2S) / 1000.0
            )

        # nominal Q values
        self.q = general.q(angle - elevations, bin_centre)

        # keep a tally of the direct and reflected beam
        self.direct_beam = np.zeros((self.wavelength_bins.size - 1))
        self.reflected_beam = np.zeros((self.wavelength_bins.size - 1))

        # beam monitor counts for normalisation
        self.bmon_direct = 0
        self.bmon_reflect = 0

        self.gravity = gravity

        # wavelength generator
        self.force_uniform_wavelength = force_uniform_wavelength
        if force_uniform_wavelength:
            self.spectrum_dist = uniform(
                loc=lo_wavelength - 1, scale=hi_wavelength - lo_wavelength + 1
            )
        else:
            a = PN("PLP0000711.nx.hdf")
            q, i, di = a.process(
                normalise=False,
                normalise_bins=False,
                rebin_percent=0.5,
                lo_wavelength=max(0, lo_wavelength - 1),
                hi_wavelength=hi_wavelength + 1,
            )
            q = q.squeeze()
            i = i.squeeze()
            self.spectrum_dist = SpectrumDist(q, i)

        self.force_gaussian = force_gaussian

        # angular resolution generator, based on a trapezoidal distribution
        # The slit settings are the optimised set typically used in an
        # experiment. dtheta/theta refers to the FWHM of a Gaussian
        # approximation to a trapezoid.

        # stores the q vectors contributing towards each datapoint
        self._res_kernel = {}
        self._min_samples = 0

        self.dtheta = dtheta / 100.0
        self.footprint = footprint
        self.angle = angle
        self.L2S = L2S
        self.L12 = L12
        s1, s2 = general.slit_optimiser(
            footprint,
            self.dtheta,
            angle=angle,
            L2S=L2S,
            L12=L12,
            verbose=False,
        )
        div, alpha, beta = general.div(s1, s2, L12=L12)
        self.div, self.s1, self.s2 = s1, s2, div

        if force_gaussian:
            self.angular_dist = norm(scale=div / 2.3548)
        else:
            self.angular_dist = trapz(
                c=(alpha - beta) / 2.0 / alpha,
                d=(alpha + beta) / 2.0 / alpha,
                loc=-alpha,
                scale=2 * alpha,
            )
Beispiel #6
0
c, d = 0.2, 0.8
mean, var, skew, kurt = trapz.stats(c, d, moments='mvsk')

# Display the probability density function (``pdf``):

x = np.linspace(trapz.ppf(0.01, c, d), trapz.ppf(0.99, c, d), 100)
ax.plot(x, trapz.pdf(x, c, d), 'r-', lw=5, alpha=0.6, label='trapz pdf')

# Alternatively, the distribution object can be called (as a function)
# to fix the shape, location and scale parameters. This returns a "frozen"
# RV object holding the given parameters fixed.

# Freeze the distribution and display the frozen ``pdf``:

rv = trapz(c, d)
ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

# Check accuracy of ``cdf`` and ``ppf``:

vals = trapz.ppf([0.001, 0.5, 0.999], c, d)
np.allclose([0.001, 0.5, 0.999], trapz.cdf(vals, c, d))
# True

# Generate random numbers:

r = trapz.rvs(c, d, size=1000)

# And compare the histogram:

ax.hist(r, normed=True, histtype='stepfilled', alpha=0.2)