52 #define G_IRF "GSPIResponse::irf(GEvent&, GSource&, GObservation&)"
53 #define G_NROI "GSPIResponse::nroi(GModelSky&, GEnergy&, GTime&, "\
55 #define G_EBOUNDS "GSPIResponse::ebounds(GEnergy&)"
56 #define G_SET "GSPIResponse::set(const GSPIObservation& obs)"
57 #define G_LOAD_IRF "GSPIResponse::load_irf(GFilename&)"
58 #define G_LOAD_IRFS "GSPIResponse::load_irfs(int&)"
254 if (spi_obs == NULL) {
255 std::string cls = std::string(
typeid(&obs).name());
256 std::string msg =
"Observation of type \""+cls+
"\" is not an "
257 "INTEGRAL/SPI observation. Please specify an "
258 "INTEGRAL/SPI observation as argument.";
265 std::string msg =
"INTEGRAL/SPI observation does not contain a valid "
266 "event cube. Please specify an observation with an "
267 "event cube as argument.";
274 std::string cls = std::string(
typeid(&event).name());
275 std::string msg =
"Event of type \""+cls+
"\" is not an INTEGRAL/SPI "
276 "event. Please specify an INTEGRAL/SPI event as "
293 #if defined(G_NAN_CHECK)
295 std::cout <<
"*** ERROR: GSPIResponse::irf:";
296 std::cout <<
" NaN/Inf encountered";
297 std::cout <<
" (irf=" <<
irf;
299 std::cout << std::endl;
327 const int& ireg)
const
355 int ieng = bin.
iebin();
358 int map = idet + (ireg + ieng * nreg) * ndet;
361 int ix_left = int(xpix);
362 int ix_right = ix_left + 1;
363 int iy_top = int(ypix);
364 int iy_bottom = iy_top + 1;
367 double wgt_right = xpix - double(ix_left);
368 double wgt_left = 1.0 - wgt_right;
369 double wgt_bottom = ypix - double(iy_top);
370 double wgt_top = 1.0 - wgt_bottom;
373 int inx_1 = ix_left + iy_top * nx;
374 int inx_2 = ix_right + iy_top * nx;
375 int inx_3 = ix_left + iy_bottom * nx;
376 int inx_4 = ix_right + iy_bottom * nx;
379 double wgt_1 = wgt_left * wgt_top;
380 double wgt_2 = wgt_right * wgt_top;
381 double wgt_3 = wgt_left * wgt_bottom;
382 double wgt_4 = wgt_right * wgt_bottom;
385 irf =
m_irfs(inx_1, map) * wgt_1;
386 irf +=
m_irfs(inx_2, map) * wgt_2;
387 irf +=
m_irfs(inx_3, map) * wgt_3;
388 irf +=
m_irfs(inx_4, map) * wgt_4;
418 const GTime& obsTime,
422 std::string msg =
"Spatial integration of sky model over the data space "
423 "is not implemented.";
448 std::string msg =
"Energy dispersion not implemented.";
493 int neng = cube->
naxis(2);
497 irfs.
nmaps(ndet * nreg * neng);
498 irfs.
shape(ndet, nreg, neng);
502 for (
int ieng = 0; ieng < neng; ++ieng) {
505 double emin = cube->
ebounds().emin(ieng).keV();
506 double emax = cube->
ebounds().emax(ieng).keV();
512 if (m_energy_keV < emin || m_energy_keV > emax) {
523 for (
int idet = 0; idet < ndet; ++idet) {
524 for (
int ireg = 0; ireg < nreg; ++ireg) {
525 int map_irf = idet + ireg * ndet;
526 int map_irfs = idet + (ireg + ieng * nreg) * ndet;
527 for (
int i = 0; i < npix; ++i) {
528 irfs(i, map_irfs) =
irf(i, map_irf);
613 GFits fits(filename);
643 fits.
saveto(filename, clobber);
675 result.append(
"=== GSPIResponse ===");
685 result.append(
"] deg");
689 result.append(
"] deg");
819 int num = table.
nrows();
825 for (
int i = 0; i < num; ++i) {
874 int num = table.
nrows();
880 std::string unit =
"keV";
882 unit = table.
string(
"TUNIT1");
886 for (
int i = 0; i < num; ++i) {
920 for (
int i = 0; i < num; ++i) {
958 table.
card(
"ENERGY",
m_energy_keV,
"[keV] IRF line energy (0 for continuum IRF)");
959 table.
card(
"DLOGE",
m_dlogE,
"Logarithmic step size for continuum IRF");
960 table.
card(
"GAMMA",
m_gamma,
"Power-law index for continuum IRF");
974 for (
int i = 0; i < num; ++i) {
977 col_energy.
unit(
"keV");
1006 GFits fits(irfname);
1012 int naxis1 = image->
integer(
"NAXIS1");
1013 int naxis2 = image->
integer(
"NAXIS2");
1014 int naxis3 = image->
integer(
"NAXIS3");
1015 int naxis4 = image->
integer(
"NAXIS4");
1016 double crval2 = image->
real(
"CRVAL2");
1017 double crval3 = image->
real(
"CRVAL3");
1018 double crpix2 = image->
real(
"CRPIX2");
1019 double crpix3 = image->
real(
"CRPIX3");
1020 double cdelt2 = image->
real(
"CDELT2");
1021 double cdelt3 = image->
real(
"CDELT3");
1030 double wcs_xmax = wcs_xmin + double(naxis2-1) * wcs_xbin;
1031 double wcs_ymax = wcs_ymin + double(naxis3-1) * wcs_ybin;
1032 double wcs_xpix_max = double(naxis2-1);
1033 double wcs_ypix_max = double(naxis3-1);
1060 std::string msg =
"Inconsistent IRFs encountered in file \""+
1061 irfname.
url()+
"\". Please specify a response "
1062 "group where all IRFs have the same definition.";
1072 int nmap = naxis1 * naxis4;
1076 GSkyMap irf(
"ARC",
"CEL", crval2, crval3, cdelt2, cdelt3, naxis2, naxis3, nmap);
1079 for (
int ix = 0; ix < naxis2; ++ix) {
1080 for (
int iy = 0; iy < naxis3; ++iy) {
1081 for (
int idet = 0; idet < naxis1; ++idet) {
1082 for (
int ireg = 0; ireg < naxis4; ++ireg) {
1083 int index = ix + iy * naxis2;
1084 int map = idet + ireg * naxis1;
1085 irf(index,map) = image->
pixel(idet, ix, iy, ireg);
1092 irf.
shape(naxis1, naxis4);
1127 std::string msg =
"No response grouping table found in file \""+
1129 "response grouping file.";
1137 for (
int i_irf = 0; i_irf < num_irfs; ++i_irf) {
1142 for (
int i_irf = 0; i_irf < num_irfs; ++i_irf) {
1146 (*grp)[
"MEMBER_LOCATION"]->string(i_irf);
1152 int num_regions = (region == -1) ? irf.
shape()[1] : 1;
1172 int ndet = irf.
shape()[0];
1175 for (
int i_region = 0; i_region < num_regions; ++i_region) {
1178 for (
int i_det = 0; i_det < num_det; ++i_det) {
1181 int map_irf =
m_detids[i_det] + i_region * ndet;
1182 int map_irfs = i_det + (i_region + i_irf * num_regions) * num_det;
1185 for (
int i = 0, iy = 0; iy < ny; ++iy) {
1186 for (
int ix = 0; ix < nx; ++ix, ++i) {
1224 #if defined(G_DEBUG_COMPUTE_IRF)
1225 std::cout <<
"GSPIResponse::compute_irf:" << std::endl;
1226 std::cout <<
"- emin = " << emin <<
" keV" << std::endl;
1227 std::cout <<
"- emax = " << emax <<
" keV" << std::endl;
1228 std::cout <<
"- npix = " << npix << std::endl;
1229 std::cout <<
"- ndet = " << ndet << std::endl;
1230 std::cout <<
"- nreg = " << nreg << std::endl;
1235 irf.
nmaps(ndet * nreg);
1236 irf.
shape(ndet, nreg);
1245 double log_ewidth = log_emax - log_emin;
1249 double wgt0 = 1.0 /
irf_weight(beta, log_emin, log_emax);
1253 int num_int = (
m_dlogE > DBL_MIN) ?
int(log_ewidth /
m_dlogE + 0.5) : 1;
1257 double log_estep = log_ewidth / num_int;
1260 #if defined(G_DEBUG_COMPUTE_IRF)
1261 std::cout <<
"- log_emin = " << log_emin << std::endl;
1262 std::cout <<
"- log_emax = " << log_emax << std::endl;
1263 std::cout <<
"- log_ewidth = " << log_ewidth << std::endl;
1264 std::cout <<
"- beta = " << beta << std::endl;
1265 std::cout <<
"- wgt0 = " << wgt0 << std::endl;
1266 std::cout <<
"- num_int = " << num_int << std::endl;
1267 std::cout <<
"- log_estep = " << log_estep << std::endl;
1268 double wgt_check = 0.0;
1272 for (
int i_int = 0; i_int < num_int; ++i_int) {
1275 double log_emin_bin = log_emin + i_int * log_estep;
1276 double log_emax_bin = log_emin_bin + log_estep;
1278 (log_emin_bin + log_emax_bin));
1281 double wgt =
irf_weight(beta, log_emin_bin, log_emax_bin) * wgt0;
1291 #if defined(G_DEBUG_COMPUTE_IRF)
1292 wgt_check += wgt_low + wgt_up;
1296 for (
int idet = 0; idet < ndet; ++idet) {
1297 for (
int ireg = 0; ireg < nreg; ++ireg) {
1298 int map = idet + ireg * ndet;
1299 int map_low = map + irf_low * ndet * nreg;
1300 int map_up = map + irf_up * ndet * nreg;
1301 for (
int i = 0; i < npix; ++i) {
1302 irf(i, map) += wgt_low *
m_irfs(i, map_low) +
1303 wgt_up *
m_irfs(i, map_up);
1311 #if defined(G_DEBUG_COMPUTE_IRF)
1312 std::cout <<
"- wgt_check = " << wgt_check <<
" (should be 1)" << std::endl;
1328 for (
int idet = 0; idet < ndet; ++idet) {
1329 for (
int ireg = 0; ireg < nreg; ++ireg) {
1330 int map = idet + ireg * ndet;
1331 int map_low = map + irf_low * ndet * nreg;
1332 int map_up = map + irf_up * ndet * nreg;
1333 for (
int i = 0; i < npix; ++i) {
1334 irf(i, map) = wgt_low *
m_irfs(i, map_low) +
1335 wgt_up *
m_irfs(i, map_up);
1341 #if defined(G_DEBUG_COMPUTE_IRF)
1342 std::cout <<
"- wgt_low = " << wgt_low << std::endl;
1343 std::cout <<
"- wgt_up = " << wgt_up << std::endl;
1344 std::cout <<
"- wgt_low+wgt_up = " << wgt_low+wgt_up;
1345 std::cout <<
" (should be 1)" << std::endl;
1365 int naxis1 = image->
integer(
"NAXIS1");
1366 int naxis2 = image->
integer(
"NAXIS2");
1367 double crval1 = image->
real(
"CRVAL1");
1368 double crval2 = image->
real(
"CRVAL2");
1369 double crpix1 = image->
real(
"CRPIX1");
1370 double crpix2 = image->
real(
"CRPIX2");
1371 double cdelt1 = image->
real(
"CDELT1");
1372 double cdelt2 = image->
real(
"CDELT2");
1414 int npt = cube->
naxis(0);
1415 int ndet = cube->
naxis(1);
1418 for (
int ipt = 0; ipt < npt; ++ipt) {
1419 for (
int idet = 0; idet < ndet; ++idet) {
1425 std::vector<int>::iterator it = find(
m_detids.begin(),
m_detids.end(), detid);
1451 int npt = cube->
naxis(0);
1460 for (
int ipt = 0; ipt < npt; ++ipt) {
1491 if (irf_detid >= 123) {
1494 else if (irf_detid >= 104) {
1497 else if (irf_detid >= 85) {
1515 const double& emax)
const
1522 weight = (emax - emin);
void unit(const std::string &unit)
Set column unit.
int size(void) const
Return number of nodes in node array.
double m_wcs_xmin
Minimum X value (radians)
double m_wcs_ymax
Maximum Y value (radians)
FITS table double column class interface definition.
Abstract FITS image base class.
GFitsTable * table(const int &extno)
Get pointer to table HDU.
double azimuth(const int &ipt, const GSkyDir &dir) const
Return azimuth angle of sky direction for pointing in radians.
virtual void clear(void)
Clear instance.
GSkyMap m_irfs
IRFs stored as sky map.
bool contains(const int &extno) const
Check if HDU exists in FITS file.
bool has_card(const int &cardno) const
Check existence of header card.
const int & ny(void) const
Returns number of pixels in y coordinate.
const GSkyDir & spi_z(const int &ipt) const
Return SPI Z direction.
Point source spatial model class interface definition.
void set_cache(const GSPIEventCube *cube)
Set computation cache.
const GSkyDir & spi_x(const int &ipt) const
Return SPI X direction (pointing direction)
double m_max_zenith
Maximum zenith angle (radians)
const GSPIInstDir & dir(const int &ipt, const int &idet) const
Return instrument direction.
GVector abs(const GVector &vector)
Computes absolute of vector elements.
std::vector< GSkyDir > m_spix
SPI pointing direction.
void ebounds(const GEbounds &ebounds)
Set energy boundaries.
void append(const GEnergy &emin, const GEnergy &emax)
Append energy interval.
GVector cos(const GVector &vector)
Computes cosine of vector elements.
const double & livetime(void) const
Return livetime of event bin.
double m_energy_keV
IRF line energy (optional)
Abstract interface for the event classes.
const double & wgt_left(void) const
Returns left node weight.
virtual GEbounds ebounds(const GEnergy &obsEnergy) const
Return true energy boundaries for a specific observed energy.
virtual ~GSPIResponse(void)
Destructor.
void clear(void)
Clear node array.
void reserve(const int &num)
Reserves space for nodes in node array.
GFitsTableCol * append(const GFitsTableCol &column)
Append column to the table.
INTEGRAL/SPI event bin container class definition.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print INTEGRAL/SPI response information.
void read(const GFitsTable &table)
Read energy boundaries from FITS table.
void write_detids(GFits &fits) const
Write detector identifiers into FITS object.
void detid(const int &detid)
Set detector identifier.
int spi_num_hdus(const GFits &fits, const std::string &extname)
Return number of HDU versions.
FITS file class interface definition.
void set_value(const double &value) const
Set indices and weighting factors for interpolation.
virtual const GSPIInstDir & dir(void) const
Return instrument direction.
double m_wcs_ybin
Y value bin size (radians)
void init_members(void)
Initialise class members.
void read(const GFitsHDU &hdu)
Read skymap from FITS HDU.
const std::vector< int > & shape(void) const
Returns shape of maps.
virtual double irf(const GEvent &event, const GPhoton &photon, const GObservation &obs) const
Return value of INTEGRAL/SPI instrument response for a photon.
void write(GFits &file, const std::string &extname=gammalib::extname_ebounds, const std::string &unit="keV") const
Write energy boundaries into FITS object.
int irf_detid(const int &detid) const
Convert detector identifier into IRF detector identifier.
double m_dlogE
Logarithmic energy step for IRF band.
bool is_notanumber(const double &x)
Signal if argument is not a number.
void write_energies(GFits &fits) const
Write energies into FITS object.
Class that handles photons.
bool is_infinite(const double &x)
Signal if argument is infinite.
void set_wcs(const GFitsImage *image)
Set IRF image limits.
INTEGRAL/SPI event bin container class.
virtual GSPIResponse * clone(void) const
Clone instance.
void saveto(const GFilename &filename, const bool &clobber=false)
Saves to specified FITS file.
double real(const std::string &keyname) const
Return card value as double precision.
double zenith(const int &ipt, const GSkyDir &dir) const
Return zenith angle of sky direction for pointing in radians.
std::string path(void) const
Return access path.
Node array class interface definition.
void read_detids(const GFits &fits)
Read detector identifiers from FITS object.
void copy_members(const GSPIResponse &rsp)
Copy class members.
const double & wgt_right(void) const
Returns right node weight.
Energy boundaries container class.
double m_wcs_xpix_max
Maximum X pixel index.
const GFilename & rspname(void) const
Get response group file name.
void set_detids(const GSPIEventCube *cube)
Set vector of detector identifiers used by the observation.
const int & nmaps(void) const
Returns number of maps.
double m_wcs_xmax
Maximum X value (radians)
GFitsHDU * write(GFits &file, const std::string &extname="") const
Write sky map into FITS file.
Energy container class definition.
Abstract interface for FITS table column.
void read_energies(const GFits &fits)
Read energies from FITS object.
const GFitsTable * spi_hdu(const GFits &fits, const std::string &extname, const int &extver=1)
Return FITS table.
double m_wcs_xbin
X value bin size (radians)
const int & ipt(void) const
Return event bin pointing index.
bool is_empty(void) const
Signal if there are no energy boundaries.
virtual double pixel(const int &ix) const =0
virtual GSPIResponse & operator=(const GSPIResponse &rsp)
Assignment operator.
const std::string extname_ebounds
std::vector< int > m_detids
Vector of detector IDs.
GSkyMap compute_irf(const double &emin, const double &emax) const
Compute as sky map.
double irf_weight(const double &beta, const double &emin, const double &emax) const
Compute weight of logarithmic energy bin.
void save(const GFilename &filename, const bool &clobber=false) const
Save SPI response into file.
void load_irfs(const int ®ion)
Load Instrument Response Functions.
Abstract interface for FITS table.
GNodeArray m_energies
Node array of IRF energies.
double m_wcs_ymin
Minimum Y value (radians)
int integer(const std::string &keyname) const
Return card value as integer.
const int & inx_left(void) const
Returns left node index.
GSkyMap load_irf(const GFilename &rspname) const
Load IRF as sky map.
void clear(void)
Clear instance.
double irf_value(const GSkyDir &srcDir, const GSPIEventBin &bin, const int &ireg) const
Return value of INTEGRAL/SPI instrument response for sky direction and event bin. ...
Abstract observation base class.
INTEGRAL/SPI instrument response function class definition.
const std::string & extname(void) const
Return extension name.
void clear(void)
Clear energy boundaries.
double m_wcs_ypix_max
Maximum Y pixel index.
const int & inx_right(void) const
Returns right node index.
const int & nrows(void) const
Return number of rows in table.
void free_members(void)
Delete class members.
const std::string extname_energies
std::vector< double > m_posang
Position angle of Y axis (CEL, radians)
INTEGRAL/SPI observation class.
virtual GResponse & operator=(const GResponse &rsp)
Assignment operator.
double posang(const GSkyDir &dir, const std::string &coordsys="CEL") const
Compute position angle between sky directions in radians.
const int & iebin(void) const
Return event bin energy index.
GFitsImage * image(const int &extno)
Get pointer to image HDU.
std::string url(void) const
Return Uniform Resource Locator (URL)
virtual int integer(const int &row, const int &inx=0) const =0
void clear(void)
Clear file name.
virtual double real(const int &row, const int &inx=0) const =0
INTEGRAL/SPI observation class definition.
double keV(void) const
Return energy in keV.
GSPIResponse(void)
Void constructor.
GVector sin(const GVector &vector)
Computes sine of vector elements.
virtual GEvents * events(void)
Return events.
std::string string(const std::string &keyname) const
Return card value as string.
const GEnergy & energy(void) const
Return photon energy.
Energy boundaries class interface definition.
INTEGRAL/SPI event bin class.
Exception handler interface definition.
void read(const GFits &fits)
Read SPI response from FITS object.
GFilename m_rspname
File name of response group.
GEbounds m_ebounds
Energy bounaries of IRF.
GFitsHDU * append(const GFitsHDU &hdu)
Append HDU to FITS file.
INTEGRAL/SPI instrument response function class.
FITS binary table class definition.
const int & nx(void) const
Returns number of pixels in x coordinate.
double m_gamma
Power-law spectral index for IRF band.
bool m_has_wcs
Has WCS information.
GVector exp(const GVector &vector)
Computes exponential of vector elements.
FITS table short integer column class interface definition.
virtual int naxis(const int &axis) const
Return number of bins in axis.
FITS table short integer column.
void init_members(void)
Initialise class members.
void load(const GFilename &filename)
Load SPI response from file.
Abstract instrument response base class.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
void append(const double &node)
Append one node to array.
const int & npix(void) const
Returns number of pixels.
void write(GFits &fits) const
Write SPI response into FITS object.
INTEGRAL/SPI event bin class definition.
virtual double nroi(const GModelSky &model, const GEnergy &obsEng, const GTime &obsTime, const GObservation &obs) const
Return integral of event probability for a given sky model over ROI.
GFitsHeaderCard & card(const int &cardno)
Return header card.
void close(void)
Close FITS file.
void free_members(void)
Delete class members.
const GSkyDir & dir(void) const
Return photon sky direction.
FITS table double column.
GVector log10(const GVector &vector)
Computes base10 logarithm of vector elements.
Class that handles energies in a unit independent way.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
void set(const GSPIObservation &obs, const GEnergy &energy=GEnergy())
Set response for a specific observation.