Esempio n. 1
0
def _make_energy_binning(**kwargs):
    """Build the energy binning for the MDP calculation.

    While there's surely some overlap with the code in ximpol.evt.binning
    module, none of the binning methods implemented there is exactly what
    we need here---the closest being that for the modulation cube, which
    is also supporting the extra EQP binning mode that really does not make
    a lot of sense here (we don't have an event file with the column energy).
    I guess we'll just go along with some code duplication. Too bad.
    """
    ebinalg = kwargs['ebinalg']
    emin = kwargs['emin']
    emax = kwargs['emax']
    ebins = kwargs['ebins']
    ebinning = kwargs['ebinning']
    if ebinalg == 'LIN':
        ebinning = numpy.linspace(emin, emax, ebins + 1)
    elif ebinalg == 'LOG':
        ebinning = numpy.linspace(numpy.log10(emin), numpy.log10(emax),
                                  ebins + 1)
    elif ebinalg == 'FILE':
        ebinfile = self.get('ebinfile')
        assert ebinfile is not None
        ebinning = numpy.loadtxt(ebinfile)
    elif ebinalg == 'LIST':
        assert isinstance(ebinning, list)
        ebinning = numpy.array(ebinning, 'd')
    else:
        abort('ebinalg %s not implemented yet' % ebinalg)
    return ebinning
Esempio n. 2
0
 def make_binning(self):
     """Build the modulation cube binning.
     """
     ebinalg = self.get('ebinalg')
     emin = self.get('emin')
     emax = self.get('emax')
     ebins = self.get('ebins')
     if ebinalg == 'LIN':
         ebinning = numpy.linspace(emin, emax, ebins + 1)
     elif ebinalg == 'LOG':
         ebinning = numpy.linspace(numpy.log10(emin), numpy.log10(emax),
                                   ebins + 1)
     elif ebinalg == 'EQP':
         if self.get('mc'):
             energy = self.event_data['MC_ENERGY']
         else:
             energy = self.event_data['ENERGY']
         ebinning = self.equipopulated_binning(ebins, energy, emin, emax)
     elif ebinalg == 'FILE':
         ebinfile = self.get('ebinfile')
         assert ebinfile is not None
         ebinning = self.read_binning(ebinfile)
     elif ebinalg == 'LIST':
         ebinning = self.get('ebinning')
         assert isinstance(ebinning, list)
         ebinning = numpy.array(ebinning, 'd')
     else:
         abort('ebinalg %s not implemented yet' % ebinalg)
     phibinning = numpy.linspace(0, 2*numpy.pi, self.get('phibins') + 1)
     return (ebinning, phibinning)
Esempio n. 3
0
    def rvs_phi(self, energy, polarization_degree, polarization_angle):
        """Return random variates for a given array of values of energy,
        polarization degree and polarization angle.

        Arguments
        ---------
        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`.)
        """
        try:
            min_degree = polarization_degree.min()
            max_degree = polarization_degree.max()
        except AttributeError:
            # This is catching the case where the polarization degree is
            # constant and is passed through as a float.
            min_degree = max_degree = polarization_degree
        if max_degree > 1:
            abort('The polarization degree must be <= 1')
        if min_degree < 0:
            abort('The polarization degree must be >= 0')
        visibility = self(energy)*polarization_degree
        return self.generator.rvs_phi(visibility, polarization_angle)
Esempio n. 4
0
 def make_binning(self):
     """Build the modulation cube binning.
     """
     ebinalg = self.get('ebinalg')
     emin = self.get('emin')
     emax = self.get('emax')
     ebins = self.get('ebins')
     if ebinalg == 'LIN':
         ebinning = numpy.linspace(emin, emax, ebins + 1)
     elif ebinalg == 'LOG':
         ebinning = numpy.linspace(numpy.log10(emin), numpy.log10(emax),
                                   ebins + 1)
     elif ebinalg == 'EQP':
         if self.get('mc'):
             energy = self.event_data['MC_ENERGY']
         else:
             energy = self.event_data['ENERGY']
         ebinning = self.equipopulated_binning(ebins, energy, emin, emax)
     elif ebinalg == 'FILE':
         ebinfile = self.get('ebinfile')
         assert ebinfile is not None
         ebinning = self.read_binning(ebinfile)
     elif ebinalg == 'LIST':
         ebinning = self.get('ebinning')
         assert isinstance(ebinning, list)
         ebinning = numpy.array(ebinning, 'd')
     else:
         abort('ebinalg %s not implemented yet' % ebinalg)
     phibinning = numpy.linspace(0, 2 * numpy.pi, self.get('phibins') + 1)
     return (ebinning, phibinning)
Esempio n. 5
0
def xpmdp(**kwargs):
    """Calculate the MDP.
    """
    logger.info('Loading the instrument response functions...')
    aeff = load_arf(kwargs['irfname'])
    modf = load_mrf(kwargs['irfname'])
    module_name = os.path.basename(kwargs['configfile']).replace('.py', '')
    ROI_MODEL = imp.load_source(module_name, kwargs['configfile']).ROI_MODEL
    logger.info(ROI_MODEL)

    # This is copied from xpobbsim and should probably be factored out.
    # Actually, this should be a method of the ROI class. TBD
    if kwargs['tstart'] < ROI_MODEL.min_validity_time():
        kwargs['tstart'] = ROI_MODEL.min_validity_time()
        logger.info('Simulation start time set to %s...' % kwargs['tstart'])
    tstop = kwargs['tstart'] + kwargs['duration']
    if tstop > ROI_MODEL.max_validity_time():
        tstop = ROI_MODEL.max_validity_time()
        logger.info('Simulation stop time set to %s...' % tstop)
    kwargs['tstop'] = tstop
    observation_time = kwargs['tstop'] - kwargs['tstart']

    # This is copied from roi.py and should probably be factored out.
    # Again, the ROI class should be able to sum the count spectra of all the
    # component and expose the result.
    sources = ROI_MODEL.values()
    if len(sources) > 1:
        abort('Multiple sources not implemented, yet.')
    source = sources[0]
    if isinstance(source, xPeriodicPointSource):
        psamples = numpy.linspace(kwargs['phasemin'], kwargs['phasemax'], 100)
        logger.info('Sampling phases: %s' % psamples)
        count_spectrum = xCountSpectrum(source.energy_spectrum,
                                        aeff,
                                        psamples,
                                        scale=observation_time)
        time_integrated_spectrum = count_spectrum.build_time_integral()
    else:
        tsamples = source.sampling_time(kwargs['tstart'], kwargs['tstop'])
        logger.info('Sampling times: %s' % tsamples)
        count_spectrum = xCountSpectrum(source.energy_spectrum, aeff, tsamples)
        time_integrated_spectrum = count_spectrum.build_time_integral()

    # Thuis should be a callable method in the binning module.
    ebinning = _make_binning(kwargs['ebinalg'], kwargs['emin'], kwargs['emax'],
                             kwargs['ebins'], kwargs['ebinning'])

    # And this might be implemented in the irf.mrf module.
    _x = time_integrated_spectrum.x
    _y = time_integrated_spectrum.y * modf(_x)
    mu_spectrum = xInterpolatedUnivariateSplineLinear(_x, _y)

    for _emin, _emax in zip(ebinning[:-1], ebinning[1:]) +\
        [(ebinning[0], ebinning[-1])]:
        num_counts = count_spectrum.num_expected_counts(emin=_emin, emax=_emax)
        mu_average = mu_spectrum.integral(_emin, _emax) / num_counts
        mdp = 4.29 / mu_average / numpy.sqrt(num_counts)
        logger.info('%.2f--%.2f keV: %d counts in %d s, mu %.3f, MDP %.2f%%' %\
                    (_emin, _emax, num_counts, observation_time, mu_average,
                     100*mdp))
Esempio n. 6
0
def mapped_column_density_HI(ra, dec, map_name='LAB'):
    """Return the mapped H_I column density at a given position in the sky.

    The value is read from one of the available input maps. Note that the
    data in the maps are stored in Galactic coordinates, while we're
    giving Celestial coordinates in input, here---the transformation is
    handled internally.

    Arguments
    ---------
    ra : float
        Right ascension of the source (in decimal degrees).

    dec: float
        Declination of the source (in decimal degrees).

    map: str
        The HI column density map to use. Can be either 'LAB' (LAB survey)
        or 'DL' (Dickey & Lockman).
    """
    # Make sure the map name makes sense.
    assert map_name in ['LAB', 'DL']
    # Transform from Celestial to Galactic coordinates.
    gal_coords = SkyCoord(ra, dec, unit='deg').galactic
    l, b = gal_coords.l.degree, gal_coords.b.degree
    # Open the selected input FITS map and grab the values.
    file_path = os.path.join(XIMPOL_SRCMODEL,'fits','h1_nh_%s.fits' % map_name)
    if not os.path.exists(file_path):
        abort('Could not find %s' % file_path)
    hdu_list = fits.open(file_path)
    _wcs = WCS(hdu_list[0].header)
    _data = hdu_list[0].data
    row, col = [int(item) for item in _wcs.wcs_world2pix(l, b, 1)]
    return _data[col, row]
Esempio n. 7
0
def xpviewbin(file_path):
    """Quick FITS image viewer.
    """
    try:
        binalg = fits.open(file_path)[0].header['BINALG']
    except Exception as e:
        abort('Could not determine file type (%s)' % e)
    VIEW_DICT[binalg](file_path).plot(show=True)
Esempio n. 8
0
def xpirfview(file_path):
    """Quick FITS image viewer.
    """
    file_ext = file_path.split('.').pop()
    if not file_ext in CLASS_DICT.keys():
        abort('Unrecognized file extension (.%s)' % file_ext)
    irf = CLASS_DICT[file_ext](file_path)
    irf.plot()
Esempio n. 9
0
def xpviewbin(file_path):
    """Quick FITS image viewer.
    """
    try:
        binalg = fits.open(file_path)[0].header['BINALG']
    except Exception as e:
        abort('Could not determine file type (%s)' % e)
    VIEW_DICT[binalg](file_path).plot(show=True)
Esempio n. 10
0
def xpirfview(file_path):
    """Quick FITS image viewer.
    """
    file_ext = file_path.split('.').pop()
    if not file_ext in CLASS_DICT.keys():
        abort('Unrecognized file extension (.%s)' % file_ext)
    irf = CLASS_DICT[file_ext](file_path)
    irf.plot()
Esempio n. 11
0
def xpmdp(**kwargs):
    """Calculate the MDP.
    """
    logger.info('Loading the instrument response functions...')
    aeff = load_arf(kwargs['irfname'])
    modf = load_mrf(kwargs['irfname'])
    module_name = os.path.basename(kwargs['configfile']).replace('.py', '')
    ROI_MODEL = imp.load_source(module_name, kwargs['configfile']).ROI_MODEL
    logger.info(ROI_MODEL)

    # This is copied from xpobbsim and should probably be factored out.
    # Actually, this should be a method of the ROI class. TBD
    if kwargs['tstart'] < ROI_MODEL.min_validity_time():
        kwargs['tstart'] = ROI_MODEL.min_validity_time()
        logger.info('Simulation start time set to %s...' % kwargs['tstart'])
    tstop = kwargs['tstart'] + kwargs['duration']
    if tstop > ROI_MODEL.max_validity_time():
        tstop = ROI_MODEL.max_validity_time()
        logger.info('Simulation stop time set to %s...' % tstop)
    kwargs['tstop'] = tstop
    observation_time = kwargs['tstop'] - kwargs['tstart']

    # This is copied from roi.py and should probably be factored out.
    # Again, the ROI class should be able to sum the count spectra of all the
    # component and expose the result.
    sources = ROI_MODEL.values()
    if len(sources) > 1:
        abort('Multiple sources not implemented, yet.')
    source = sources[0]
    if isinstance(source, xPeriodicPointSource):
        psamples = numpy.linspace(kwargs['phasemin'], kwargs['phasemax'], 100)
        logger.info('Sampling phases: %s' % psamples)
        count_spectrum = xCountSpectrum(source.energy_spectrum, aeff, psamples,
                                        scale=observation_time)
        time_integrated_spectrum = count_spectrum.build_time_integral()
    else:
        tsamples = source.sampling_time(kwargs['tstart'], kwargs['tstop'])
        logger.info('Sampling times: %s' % tsamples)
        count_spectrum = xCountSpectrum(source.energy_spectrum, aeff, tsamples)
        time_integrated_spectrum = count_spectrum.build_time_integral()

    # Thuis should be a callable method in the binning module.
    ebinning =_make_binning(kwargs['ebinalg'], kwargs['emin'], kwargs['emax'],
                            kwargs['ebins'], kwargs['ebinning'])

    # And this might be implemented in the irf.mrf module.
    _x = time_integrated_spectrum.x
    _y = time_integrated_spectrum.y*modf(_x)
    mu_spectrum = xInterpolatedUnivariateSplineLinear(_x, _y)

    for _emin, _emax in zip(ebinning[:-1], ebinning[1:]) +\
        [(ebinning[0], ebinning[-1])]:
        num_counts = count_spectrum.num_expected_counts(emin=_emin, emax=_emax)
        mu_average = mu_spectrum.integral(_emin, _emax)/num_counts
        mdp = 4.29/mu_average/numpy.sqrt(num_counts)
        logger.info('%.2f--%.2f keV: %d counts in %d s, mu %.3f, MDP %.2f%%' %\
                    (_emin, _emax, num_counts, observation_time, mu_average,
                     100*mdp))
Esempio n. 12
0
def xpmdp(**kwargs):
    """Calculate the MDP.
    """
    logger.info('Loading the instrument response functions...')
    aeff = load_arf(kwargs['irfname'])
    modf = load_mrf(kwargs['irfname'])
    module_name = os.path.basename(kwargs['configfile']).replace('.py', '')
    ROI_MODEL = imp.load_source(module_name, kwargs['configfile']).ROI_MODEL
    logger.info(ROI_MODEL)

    # This is copied from xpobbsim and should probably be factored out.
    # Actually, this should be a method of the ROI class. TBD
    if kwargs['tstart'] < ROI_MODEL.min_validity_time():
        kwargs['tstart'] = ROI_MODEL.min_validity_time()
        logger.info('Simulation start time set to %s...' % kwargs['tstart'])
    tstop = kwargs['tstart'] + kwargs['duration']
    if tstop > ROI_MODEL.max_validity_time():
        tstop = ROI_MODEL.max_validity_time()
        logger.info('Simulation stop time set to %s...' % tstop)
    kwargs['tstop'] = tstop

    # This is copied from roi.py and should probably be factored out.
    # Again, the ROI class should be able to sum the count spectra of all the
    # component and expose the result.
    sources = ROI_MODEL.values()
    if len(sources) > 1:
        abort('Multiple sources not implemented, yet.')
    source = sources[0]
    if isinstance(source, xPeriodicPointSource):
        observation_time = kwargs['tstop'] - kwargs['tstart']
        psamples = numpy.linspace(kwargs['phasemin'], kwargs['phasemax'], 100)
        logger.info('Sampling phases: %s' % psamples)
        count_spectrum = xCountSpectrum(source.energy_spectrum, aeff, psamples,
                                        source.column_density, source.redshift,
                                        scale_factor=observation_time)
    else:
        tsamples = source.sampling_time(kwargs['tstart'], kwargs['tstop'])
        logger.info('Sampling times: %s' % tsamples)
        count_spectrum = xCountSpectrum(source.energy_spectrum, aeff, tsamples,
                                        source.column_density, source.redshift)

    # Do the actual work.
    ebinning =_make_energy_binning(**kwargs)
    mdp_table = count_spectrum.build_mdp_table(ebinning, modf)
    logger.info(mdp_table)
    file_path = kwargs['outfile']
    if file_path is not None:
        logger.info('Writing output file path %s...' % file_path)
        open(file_path, 'w').write('%s\n\n%s' % (kwargs, mdp_table))
        logger.info('Done.')
    return mdp_table
Esempio n. 13
0
 def make_binning(self):
     """Build the light-curve binning.
     """
     tbinalg = self.get('tbinalg')
     tstart = self.get('tstart')
     tstop = self.get('tstop')
     tbins = self.get('tbins')
     if tbinalg == 'LIN':
         return numpy.linspace(tstart, tstop, tbins + 1)
     elif tbinalg == 'LOG':
         return numpy.logspace(numpy.log10(tstart), numpy.log10(tstop),
                               tbins + 1)
     elif tbinalg == 'FILE':
         tbinfile = self.get('tbinfile')
         assert tbinfile is not None
         return self.read_binning(tbinfile)
     abort('tbinalg %s not implemented yet' % tbinalg)
Esempio n. 14
0
 def make_binning(self):
     """Build the light-curve binning.
     """
     tbinalg = self.get('tbinalg')
     tstart = self.get('tstart')
     tstop = self.get('tstop')
     tbins = self.get('tbins')
     if tbinalg == 'LIN':
         return numpy.linspace(tstart, tstop, tbins + 1)
     elif tbinalg == 'LOG':
         return numpy.logspace(numpy.log10(tstart), numpy.log10(tstop),
                               tbins + 1)
     elif tbinalg == 'FILE':
         tbinfile = self.get('tbinfile')
         assert tbinfile is not None
         return self.read_binning(tbinfile)
     abort('tbinalg %s not implemented yet' % tbinalg)
Esempio n. 15
0
def _make_binning(ebinalg, emin=1., emax=10., ebins=5, ebinning=None):
    """Build the modulation cube binning.

    Warning
    -------
    This is copied from evt/binning.py and should be factored out.
    """
    if ebinalg == 'LIN':
        ebinning = numpy.linspace(emin, emax, ebins + 1)
    elif ebinalg == 'LOG':
        ebinning = numpy.linspace(numpy.log10(emin), numpy.log10(emax),
                                  ebins + 1)
    #elif ebinalg == 'FILE':
    #    ebinfile = self.get('ebinfile')
    #    assert ebinfile is not None
    #    ebinning = self.read_binning(ebinfile)
    elif ebinalg == 'LIST':
        assert isinstance(ebinning, list)
        ebinning = numpy.array(ebinning, 'd')
    else:
        abort('ebinalg %s not implemented yet' % ebinalg)
    return ebinning
Esempio n. 16
0
def _make_binning(ebinalg, emin=1., emax=10., ebins=5, ebinning=None):
    """Build the modulation cube binning.

    Warning
    -------
    This is copied from evt/binning.py and should be factored out.
    """
    if ebinalg == 'LIN':
        ebinning = numpy.linspace(emin, emax, ebins + 1)
    elif ebinalg == 'LOG':
        ebinning = numpy.linspace(numpy.log10(emin), numpy.log10(emax),
                                  ebins + 1)
    #elif ebinalg == 'FILE':
    #    ebinfile = self.get('ebinfile')
    #    assert ebinfile is not None
    #    ebinning = self.read_binning(ebinfile)
    elif ebinalg == 'LIST':
        assert isinstance(ebinning, list)
        ebinning = numpy.array(ebinning, 'd')
    else:
        abort('ebinalg %s not implemented yet' % ebinalg)
    return ebinning
Esempio n. 17
0
    def __init__(self, num_samples=1000):
        """Constructor.

        Arguments
        ---------
        num_samples : int
            The number of data points used to sample (logarithmically) the
            photon energies when tabulating the absorption cross section
            internally.
        """
        file_path = os.path.join(XIMPOL_SRCMODEL, 'ascii', 'XsecFitParam.txt')
        if not os.path.exists(file_path):
            abort('Could not find %s' % file_path)
        # Read the data from file and calculate the minimum and maximum
        # energies.
        e_lo, e_hi, c0, c1, c2 = numpy.loadtxt(file_path, delimiter=',',
                                               unpack=True)
        emin = e_lo[0]
        emax = e_hi[-1]
        # Sample the energy logarithmically between emin and emax.
        _x = numpy.logspace(numpy.log10(emin), numpy.log10(emax), num_samples)
        # Here comes the interesting part---the cross section is tabulated
        # by means of a set of piecewise quadratic functions, and the
        # three coefficients are provided in each energy bin. We do some
        # magic with the numpy.digitize() function, returning for each value
        # in _x its bin index in the original table. Note that we need to
        # clip the array removing negative numbers, as the double log/exp
        # operations done in defining the binning where driving the first
        # index to -1.
        _bin = (numpy.digitize(_x, e_lo) - 1).clip(min=0)
        # Calculate the cross section values---compact, isn't it?
        _y = 1.0e-24*(c0[_bin] + c1[_bin]*_x + c2[_bin]*(_x**2.))/(_x**3.)
        # And, finally, build the basic spline underlying the model.
        _fmt = dict(xname='Energy', xunits='keV', yname='$\\sigma_{abs}$',
                    yunits='cm$^2$')
        self.xsection = xInterpolatedUnivariateSplineLinear(_x, _y, **_fmt)
Esempio n. 18
0
def check_input_file(file_path, extension=None):
    """Make sure that an input file exists (and, optionally, has the right
    extension).

    Note that we abort the execution with no mercy if anything fails.
    """
    if not os.path.exists(file_path):
        abort('Input file %s does not exists' % file_path)
    if not os.path.isfile(file_path):
        abort('Input file %s is not a file' % file_path)
    if extension is not None and not file_path.endswith('.%s' % extension):
        abort('Input file %s is not a .%s file' % (file_path, extension))
Esempio n. 19
0
def check_input_file(file_path, extension=None):
    """Make sure that an input file exists (and, optionally, has the right
    extension).

    Note that we abort the execution with no mercy if anything fails.
    """
    if not os.path.exists(file_path):
        abort('Input file %s does not exists' % file_path)
    if not os.path.isfile(file_path):
        abort('Input file %s is not a file' % file_path)
    if extension is not None and not file_path.endswith('.%s' % extension):
        abort('Input file %s is not a .%s file' % (file_path, extension))