irf.mrf

class ximpol.irf.mrf.XMDPRecord(mdp, min_energy, max_energy, mu_effective, num_signal, num_bkg=0)[source]

Small utility class to keep track

ximpol.irf.mrf.mdp99(mu_effective, num_signal, num_bkg=0.0)[source]

Return the MDP at the 99% confidence level.

Note that the function returns numpy.nan if the number of signal events is zero.

Parameters:
  • mu_effective (float or array) – The effective (i.e., weighted over the count spectrum) modulation factor.
  • num_signal (float or array) – The number of signal events.
  • num_bkg (float or array) – The number of background events.
class ximpol.irf.mrf.xAzimuthalResponseGenerator[source]

Random number generator for the azimuthal response of the polarimeter.

Here is the basic underlying math. Typically the response of a polarimeter to monochromatic, linearly polarized incident radiation is of the form:

N(\phi) = A + B \cos^2(\phi - \phi_0).

This can be conveniently rewritten in term of the overall normalization (i.e., the total number of events) and the visibility of the modulation, defined as

\xi = \frac{N_\text{max} - N_\text{min}}
{N_\text{max} + N_\text{min}} = \frac{B}{2A + B}

(the visibility can also be characterized as the fraction of modulated events in a given distribution, as can be readily demonstrated, and it is the quantity that the detector is effectively measuring). The angular response now becomes

N(\phi) = \frac{N_0}{\pi} \left[
\frac{(1 - \xi)}{2} + \xi \cos^2(\phi - \phi_0)
\right].

For completeness, the visibility, the modulation factor and the polarization degree for a monocromatic source are related to each other through:

\xi(E, t) = P(E, t) \times \mu(E)

(i.e., at any given energy the modulation factor is the visibility of the modulation of the detector response for 100% linearly polarized incident radiation).

In terms of throwing random numbers, the phase is a trivial constant that can be added after the fact (modulo 2pi), so effectively the relevant probability density function is

\text{pdf}(\phi) = \frac{1}{\pi} \left[
\frac{(1 - \xi)}{2} + \xi \cos^2(\phi) \right],

../_images/test_azimuthal_resp_pdf.png

The corresponding cumulative distribution function is

\text{cdf}(\phi) = \frac{1}{2\pi} \left(
\phi + \frac{\xi}{2}\sin{(2\phi)} \right),

and it is unfortunate that it cannot be inverted, otherwise we would have no need to interpolate for generating random numbers according to this distribution.

../_images/test_azimuthal_resp_cdf.png

From the prospecive of the code, this generator is a standard xUnivariateAuxGenerator where the azimuthal angle is our random variable and the visbility is our auxiliary variable. For any given value of the visibility, a vertical slice is providing the corresponding one-dimensional pdf.

../_images/test_azimuthal_resp_generator.png

The class also provide facilities to fit a histogram to recover the underlying modulation visibility and phase.

Example

>>> import numpy
>>> from ximpol.utils.matplotlib_ import pyplot as plt
>>> from ximpol.irf.mrf import xAzimuthalResponseGenerator
>>>
>>> generator = xAzimuthalResponseGenerator()
>>> visibility = numpy.full(1000000, 0.5)
>>> phase = numpy.radians(45.)
>>> phi = generator.rvs_phi(visibility, phase)
>>> hist = plt.hist(phi, bins=numpy.linspace(0, 2*numpy.pi, 100),
                    histtype='step', label='Random angles')
>>> fit_results = generator.fit_histogram(hist)
>>> fit_results.plot()
>>> plt.show()
../_images/test_azimuthal_resp_rvs.png
classmethod cdf(phi, visibility)[source]

Evaluate the underlying one-dimensional cdf for a given value of the visibility, and assuming that the phase of the modulation is zero.

Parameters:
  • phi (float or array) – The (independent) azimuthal angle variable, in radians.
  • visibility (float or array) – The visibility of the modulation, in [0–1].

Warning

We could overload the build_vpppf method for the class using this, since we have an analytic expression. (This function is effectively not used at the moment.)

classmethod fit_function(phi, visibility, phase, normalization)[source]

Convenience function (with the phase back in) to allow histogram fitting.

classmethod fit_histogram(histogram, fit_normalization=False)[source]

Fit an azimuthal histogram.

classmethod pdf(phi, visibility)[source]

Evaluate the underlying one-dimensional pdf for a given value of the visibility, and assuming that the phase of the modulation is zero.

Parameters:
  • phi (float or array) – The (independent) azimuthal angle variable, in radians.
  • visibility (float or array) – The visibility of the modulation, in [0–1].
rvs_phi(visibility, phase)[source]

Generate random variates for any visibility and phase values.

This is essentially calling the underlying xUnivariateAuxGenerator.rvs() method passing the visibility array as an argument and adding the phase array (modulo 2pi) to the output.

Parameters:
  • visibility (array) – An array of visibility values. (The function returns an equal-length array of phi values.)
  • phase (float or array) – The phase of the modulation. (This can either be a vector or an array of the same length as visibility.)
class ximpol.irf.mrf.xBinTableHDUMODFRESP(data=None, keywords=[], comments=[])[source]

Binary table for the MODFRESP extension of a mrf file.

class ximpol.irf.mrf.xMDPTable(observation_time)[source]

Small utility class to store a set MDP values evaluated in energy bins.

add_row(mdp, min_energy, max_energy, mu_effective, num_signal, num_bkg=0)[source]

Add a row to the MDP table.

mdp_values()[source]

Return the MDP values in the various energy bins.

class ximpol.irf.mrf.xModulationFactor(mrf_file_path)[source]

Class describing the modulation factor.

The effective area is essentially a linear spline, with built-in facilities for evaluation and plotting.

Parameters:mrf_file_path (str) – The path to the .mrf FITS file containing the modulation response table.

To zero-th order, an xModulationFactor instance is an object capable of evaluating itself in a point or in a grid of points, and capable of plotting itself.

Example

>>> import os
>>> import numpy
>>> from ximpol import XIMPOL_IRF
>>>
>>> file_path = os.path.join(XIMPOL_IRF,'fits','xipe_baseline.mrf')
>>> modf = xModulationFactor(file_path)
>>> x = numpy.arange(1, 10, 1)
>>> print(modf(x))
>>> modf.view()

More interestingly, it can generate random phi values, given a vector of event energies and corresponding vectors (or simple floats) representing the polarization degree and angle corresponding to the energies themselves. Internally, any xModulationFactor has an xAzimuthalResponseGenerator object and when the xModulationFactor.rvs_phi() method is called, the polarization degree is multiplied by the modulation factor of the detector, evaluated at the right energy, and converted into a visibility value, after which the underlying xAzimuthalResponseGenerator.rvs_phi() is called.

Example

>>> import os
>>> import numpy
>>> from ximpol import XIMPOL_IRF
>>>
>>> file_path = os.path.join(XIMPOL_IRF,'fits','xipe_baseline.mrf')
>>> modf = xModulationFactor(file_path)
>>> # Throw 100000 random energy values.
>>> energy = numpy.random.uniform(1, 10, 100000)
>>> # This will create an array of 100000 phi values where the visibility
>>> # of the modulation is tracking the modulation factor of the polarimeter
>>> # (the phase is constant at 45 degrees).
>>> phi = modf.rvs_phi(energy, 1., numpy.radians(45))
rvs_phi(energy, polarization_degree, polarization_angle)[source]

Return random variates for a given array of values of energy, polarization degree and polarization angle.

Parameters:
  • energy (array) – An array of energy values. (The function returns an equal-length array of phi values.)
  • polarization_degree (array or float) – The polarization degree, in [0–1]. (This can either be a vector or an array of the same length as energy.)
  • polarization_angle (array or float) – The polarization angle, in radians. (This can either be a vector or an array of the same length as energy.)
view(show=True, **kwargs)[source]

Overloaded method for the xpirfview application.

weighted_average(energy)[source]

Return the weighted average of the mudulation factor given an array of energies.

mu_{rm eff} =

Parameters:energy (array) – An array of energy values.
class ximpol.irf.mrf.xModulationFitResults(popt, pcov, chisquare, ndof)[source]

Small convenience class encapsulating the result of a fit to an azimuthal angle distribution.

This includes facilities for plotting and annotating the best-fit model (e.g., overlaying it onto the underlying fitted histogram).

latex()[source]

LaTeX formatting.

plot(show=False, stat=True, text_size=15, simple_stat=False, **options)[source]

Plot the fit results.

set_polarization(modulation_factor)[source]
class ximpol.irf.mrf.xStokesAccumulator[source]

Small utility class implementing the event-by-event analysis dexcribed in https://arxiv.org/abs/1409.6214

fill(phi)[source]

Fill the accumulator with one or more values of measured azimuthal directions.

Parameters:phi (float or array) – The (independent) azimuthal angle variable, in radians.
phase()[source]

Return the current accumulated phase and associated undertainty. Based on eq 22.

polarization_frac(mu)[source]

Return the polarization fraction given the visibility divided by effective mu.

q()[source]

Return the normalized Q parameter (11b).

reset()[source]

Reset the Stokes parameters.

u()[source]

Return the normalized U parameter (11a).

visibility()[source]

Return the current accumulated visibility and associated uncertainty. Recall that the visibility is the polarization fraction times the modulation function. The polarization function comes from eq 21 and here we set the modulation function to 1.