Source code for ixpeobssim.binning.detector

# Copyright (C) 2015--2022, the ixpeobssim team.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

"""Binning data products in detector coordinates.

from __future__ import print_function, division

from import fits
import numpy

from ixpeobssim.binning.base import xEventBinningBase, xBinnedFileBase
from ixpeobssim.core.hist import xGpdMap2d
from ixpeobssim.instrument.gpd import gpd_map_binning, GPD_PHYSICAL_HALF_SIDE_X,\
from ixpeobssim.utils.logging_ import logger

# pylint: disable=invalid-name, attribute-defined-outside-init, too-few-public-methods
# pylint: disable=no-member, arguments-differ

[docs] class xEventBinningARMAP(xEventBinningBase): """Class for ARMAP binning. """ INTENT = 'rate per unit area map in detector coordinates' SUPPORTED_KWARGS = ['npix']
[docs] def process_data(self): """Convenience function factoring out the code in common with the corresponding EFLUX class---see the overloaded method in there. Here we are binning the event position in detector coordinates and dividing by the livetime and the bin area. The function returns a n x n array of area rate values to be written in the output file. """ detx, dety = self.event_file.det_position_data() xbinning, ybinning = gpd_map_binning(GPD_PHYSICAL_HALF_SIDE_X, GPD_PHYSICAL_HALF_SIDE_Y, self.get('npix')) bin_area = (xbinning[1] - xbinning[0]) * (ybinning[1] - ybinning[0]) rate, _, _ = numpy.histogram2d(detx, dety, bins=(xbinning, ybinning)) rate /= self.event_file.livetime() * bin_area return rate
[docs] def bin_(self): """Overloaded method. """ rate = self.process_data() primary_hdu = self.build_primary_hdu(rate) primary_hdu.add_keyword('TOTCNTS', self.event_file.num_events(), 'total counts in the original photon list') hdu_list = fits.HDUList([primary_hdu]) self.write_output_file(hdu_list)
[docs] class xBinnedAreaRateMap(xBinnedFileBase): """Display interface to binned ARMAP files. """ Z_TITLE = 'Dead-time corrected rate [Hz mm$^{-2}$]' def _read_data(self): """Overloaded method. """ = self.hdu_list['PRIMARY'].data.T self.counts = self.hdu_list['PRIMARY'].header['TOTCNTS'] def __iadd__(self, other): """Overloaded method for ARMAP binned data addition. Note that, given the peculiarity of this binned data product (we are typically interested in the area rate per detector) we are doing a weighted average of the input data based on the number of counts for each DU in the original event list. """ self._check_iadd(other) = ( * self.counts + * other.counts) /\ (self.counts + other.counts) self.counts += other.counts return self
[docs] def plot(self): """Plot the data. """ threshold = 0.1 sel =[ > threshold *]'Average = %.3f (threshold = %.3f), maximum = %.3f', sel.mean(), threshold, sel.max()) npix =[0] hist = xGpdMap2d(npix, zlabel=self.Z_TITLE) hist.set_content(, / * self.counts) hist.plot()
[docs] class xEventBinningEFLUX(xEventBinningARMAP): """Class for EFLUX binning. """ INTENT = 'energy-flux map in detector coordinates'
[docs] def process_data(self): """Overloaded method. Here we are just multiplying by the average measured event energy. """ rate = xEventBinningARMAP.process_data(self) rate *= self.event_file.energy_data(mc=False).mean() return rate
[docs] class xBinnedAreaEnergyFluxMap(xBinnedAreaRateMap): """Display interface to binned EFLUX files. """ Z_TITLE = 'Dead-time corrected energy flux [keV mm$^{-2}$ s$^{-1}$]'