62#define G_IRF "GCOMResponse::irf(GEvent&, GPhoton&, GObservation&)"
63#define G_IRF_SPATIAL "GCOMResponse::irf_spatial(GEvent&, GSource&, "\
65#define G_NROI "GCOMResponse::nroi(GModelSky&, GEnergy&, GTime&, "\
67#define G_EBOUNDS "GCOMResponse::ebounds(GEnergy&)"
68#define G_IRF_PTSRC "GCOMResponse::irf_ptsrc(GModelSky&, GObservation&, "\
70#define G_IRF_RADIAL "GCOMResponse::irf_radial(GModelSky&, GObservation&, "\
72#define G_IRF_ELLIPTICAL "GCOMResponse::irf_elliptical(GModelSky&, "\
73 " GObservation&, GMatrix*)"
74#define G_IRF_DIFFUSE "GCOMResponse::irf_diffuse(GModelSky&, GObservation&, "\
135 const std::string& iaqname) :
GResponse()
291 if (observation == NULL) {
292 std::string cls = std::string(
typeid(&obs).name());
293 std::string msg =
"Observation of type \""+cls+
"\" is not a COMPTEL "
294 "observations. Please specify a COMPTEL observation "
302 std::string cls = std::string(
typeid(&cube).name());
303 std::string msg =
"Event cube of type \""+cls+
"\" is not a COMPTEL "
304 "event cube. Please specify a COMPTEL event cube "
312 std::string cls = std::string(
typeid(&event).name());
313 std::string msg =
"Event of type \""+cls+
"\" is not a COMPTEL event. "
314 "Please specify a COMPTEL event as argument.";
320 std::string msg =
"COMPTEL response is empty. Please initialise the "
321 "response with an \"IAQ\".";
325 std::string msg =
"COMPTEL response has a zero Phigeo bin size. "
326 "Please initialise the response with a valid "
352 int iphigeo = int(phirat);
353 double eps = phirat - iphigeo - 0.5;
358 iaq = (1.0 + eps) *
m_iaq[i] - eps *
m_iaq[i-1];
361 iaq = (1.0 - eps) *
m_iaq[i] + eps *
m_iaq[i+1];
366 iaq = (1.0 - eps) *
m_iaq[i] + eps *
m_iaq[i+1];
369 iaq = (1.0 + eps) *
m_iaq[i] - eps *
m_iaq[i-1];
379 double drg = observation->
drg().
map()(obsDir.
dir(), iphibar);
382 double drx = observation->
drx().
map()(srcDir);
385 double ontime = observation->
ontime();
394 irf = iaq * drg * drx / (ontime * tofcor) * phasecor;
405 #if defined(G_NAN_CHECK)
407 std::cout <<
"*** ERROR: GCOMResponse::irf:";
408 std::cout <<
" NaN/Inf encountered";
409 std::cout <<
" (irf=" <<
irf;
410 std::cout <<
", iaq=" << iaq;
411 std::cout <<
", drg=" << drg;
412 std::cout <<
", drx=" << drx;
414 std::cout << std::endl;
439 const GTime& obsTime,
443 std::string msg =
"Spatial integration of sky model over the data space "
444 "is not implemented.";
467 std::string msg =
"Energy dispersion not implemented.";
528 GFits fits(filename);
578 if (image.
naxis() == 2) {
603 m_iaq.assign(size, 0.0);
606 for (
int i = 0; i < size; ++i) {
620 double phigeo = iphigeo * phigeo_bin + phigeo_min;
621 double omega = omega0 * std::sin(phigeo);
658 image(iphigeo, iphibar) =
m_iaq[i] * omega;
663 image.
card(
"CTYPE1",
"Phigeo",
"Geometrical scatter angle");
665 "[deg] Geometrical scatter angle for reference bin");
667 "[deg] Geometrical scatter angle bin size");
669 "Reference bin of geometrical scatter angle");
670 image.
card(
"CTYPE2",
"Phibar",
"Compton scatter angle");
672 "[deg] Compton scatter angle for reference bin");
675 "Reference bin of Compton scatter angle");
676 image.
card(
"BUNIT",
"Probability per bin",
"Unit of bins");
677 image.
card(
"TELESCOP",
"GRO",
"Name of telescope");
678 image.
card(
"INSTRUME",
"COMPTEL",
"Name of instrument");
679 image.
card(
"ORIGIN",
"GammaLib",
"Origin of FITS file");
680 image.
card(
"OBSERVER",
"Unknown",
"Observer that created FITS file");
704 result.append(
"=== GCOMResponse ===");
847 if (obs_ptr == NULL) {
848 std::string cls = std::string(
typeid(&obs).name());
849 std::string msg =
"Observation of type \""+cls+
"\" is not a COMPTEL "
850 "observations. Please specify a COMPTEL observation "
858 std::string msg =
"Observation \""+obs.
name()+
"\" ("+obs.
id()+
") does "
859 "not contain a COMPTEL event cube. Please specify "
860 "a COMPTEL observation containing and event cube.";
866 std::string msg =
"COMPTEL response is empty. Please initialise the "
867 "response with an \"IAQ\".";
871 std::string msg =
"COMPTEL response has a zero Phigeo bin size. "
872 "Please initialise the response with a valid "
879 int nphibar = cube->
naxis(2);
880 int nevents = cube->
size();
885 std::string msg =
"DRE has "+
gammalib::str(nphibar)+
" Phibar layers "
887 "bins. Please specify a compatible IAQ.";
899 double iaq_norm = obs_ptr->
drx().
map()(srcDir) * obs_ptr->
deadc() /
907 for (
int ipix = 0; ipix < npix; ++ipix) {
920 double phigeo = srcDir.
dist_deg(phigeoDir);
924 int iphigeo = int(phirat);
925 double eps = phirat - iphigeo - 0.5;
932 for (
int iphibar = 0; iphibar < nphibar; ++iphibar) {
943 iaq = (1.0 + eps) *
m_iaq[i] - eps *
m_iaq[i-1];
946 iaq = (1.0 - eps) *
m_iaq[i] + eps *
m_iaq[i+1];
951 iaq = (1.0 - eps) *
m_iaq[i] + eps *
m_iaq[i+1];
954 iaq = (1.0 + eps) *
m_iaq[i] - eps *
m_iaq[i-1];
962 int idri = ipix + iphibar * npix;
965 double irf = iaq * drg[idri] * iaq_norm;
1012 static const int iter_rho = 5;
1013 static const int iter_omega = 5;
1017 if (obs_ptr == NULL) {
1018 std::string cls = std::string(
typeid(&obs).name());
1019 std::string msg =
"Observation of type \""+cls+
"\" is not a COMPTEL "
1020 "observations. Please specify a COMPTEL observation "
1028 std::string msg =
"Observation \""+obs.
name()+
"\" ("+obs.
id()+
") does "
1029 "not contain a COMPTEL event cube. Please specify "
1030 "a COMPTEL observation containing and event cube.";
1035 if (
m_iaq.empty()) {
1036 std::string msg =
"COMPTEL response is empty. Please initialise the "
1037 "response with an \"IAQ\".";
1041 std::string msg =
"COMPTEL response has a zero Phigeo bin size. "
1042 "Please initialise the response with a valid "
1055 const double& theta_max = radial->
theta_max() - 1.0e-12;
1059 int nphibar = cube->
naxis(2);
1060 int nevents = cube->
size();
1065 std::string msg =
"DRE has "+
gammalib::str(nphibar)+
" Phibar layers "
1067 "bins. Please specify a compatible IAQ.";
1077 double phigeo_max = phigeo_min + phigeo_bin *
m_phigeo_bins;
1082 double iaq_norm = obs_ptr->
deadc() /
1091 GMatrix rot = (ry * rz).transpose();
1094 for (
int ipix = 0; ipix < npix; ++ipix) {
1107 double zeta = phigeoDir.
dist(model_dir);
1110 double rho_min = (zeta > phigeo_max) ? zeta - phigeo_max : 0.0;
1111 double rho_max = zeta + phigeo_max;
1112 if (rho_min > theta_max) {
1113 rho_min = theta_max;
1115 if (rho_max > theta_max) {
1116 rho_max = theta_max;
1120 if (rho_max > rho_min) {
1142 irf = integral.
romberg(rho_min, rho_max, iter_rho);
1145 for (
int iphibar = 0; iphibar < nphibar; ++iphibar) {
1146 int idri = ipix + iphibar * npix;
1147 irfs[idri] =
irf[iphibar] * drg[idri] * iaq_norm;
1183 static const int iter_rho = 5;
1184 static const int iter_omega = 5;
1188 if (obs_ptr == NULL) {
1189 std::string cls = std::string(
typeid(&obs).name());
1190 std::string msg =
"Observation of type \""+cls+
"\" is not a COMPTEL "
1191 "observations. Please specify a COMPTEL observation "
1199 std::string msg =
"Observation \""+obs.
name()+
"\" ("+obs.
id()+
") does "
1200 "not contain a COMPTEL event cube. Please specify "
1201 "a COMPTEL observation containing and event cube.";
1206 if (
m_iaq.empty()) {
1207 std::string msg =
"COMPTEL response is empty. Please initialise the "
1208 "response with an \"IAQ\".";
1212 std::string msg =
"COMPTEL response has a zero Phigeo bin size. "
1213 "Please initialise the response with a valid "
1223 const GSkyDir& model_dir = elliptical->
dir();
1224 const double& theta_max = elliptical->
theta_max();
1228 int nphibar = cube->
naxis(2);
1229 int nevents = cube->
size();
1234 std::string msg =
"DRE has "+
gammalib::str(nphibar)+
" Phibar layers "
1236 "bins. Please specify a compatible IAQ.";
1246 double phigeo_max = phigeo_min + phigeo_bin *
m_phigeo_bins;
1251 double iaq_norm = obs_ptr->
deadc() /
1260 GMatrix rot = (ry * rz).transpose();
1263 for (
int ipix = 0; ipix < npix; ++ipix) {
1276 double zeta = phigeoDir.
dist(model_dir);
1279 double rho_min = (zeta > phigeo_max) ? zeta - phigeo_max : 0.0;
1280 double rho_max = zeta + phigeo_max;
1281 if (rho_min > theta_max) {
1282 rho_min = theta_max;
1284 if (rho_max > theta_max) {
1285 rho_max = theta_max;
1289 if (rho_max > rho_min) {
1311 irf = integral.
romberg(rho_min, rho_max, iter_rho);
1314 for (
int iphibar = 0; iphibar < nphibar; ++iphibar) {
1315 int idri = ipix + iphibar * npix;
1316 irfs[idri] =
irf[iphibar] * drg[idri] * iaq_norm;
1365 if (obs_ptr == NULL) {
1366 std::string cls = std::string(
typeid(&obs).name());
1367 std::string msg =
"Observation of type \""+cls+
"\" is not a COMPTEL "
1368 "observations. Please specify a COMPTEL observation "
1376 std::string msg =
"Observation \""+obs.
name()+
"\" ("+obs.
id()+
") does "
1377 "not contain a COMPTEL event cube. Please specify "
1378 "a COMPTEL observation containing and event cube.";
1383 if (
m_iaq.empty()) {
1384 std::string msg =
"COMPTEL response is empty. Please initialise the "
1385 "response with an \"IAQ\".";
1389 std::string msg =
"COMPTEL response has a zero Phigeo bin size. "
1390 "Please initialise the response with a valid "
1397 int nphibar = cube->
naxis(2);
1398 int nevents = cube->
size();
1403 std::string msg =
"DRE has "+
gammalib::str(nphibar)+
" Phibar layers "
1405 "bins. Please specify a compatible IAQ.";
1415 double omega0 = 2.0 * std::sin(0.5 * phigeo_bin);
1420 double iaq_norm = obs_ptr->
deadc() /
1425 for (
int ipix = 0; ipix < npix; ++ipix) {
1441 double phigeo = phigeo_min + double(iphigeo) * phigeo_bin;
1442 double sin_phigeo = std::sin(phigeo);
1447 int naz = int(length / phigeo_bin + 0.5);
1454 double omega = omega0 * az_step * sin_phigeo;
1458 for (
int iaz = 0; iaz < naz; ++iaz, az += az_step) {
1462 skyDir.
rotate(az, phigeo);
1476 if (intensity == 0.0) {
1481 intensity *= drx(skyDir);
1487 for (
int iphibar = 0; iphibar < nphibar; ++iphibar) {
1493 double iaq =
m_iaq[i];
1501 int idri = ipix + iphibar * npix;
1504 double irf = iaq * drg[idri] * iaq_norm * intensity;
COMPTEL event bin class interface definition.
COMPTEL event bin container class interface definition.
COMPTEL instrument direction class definition.
COMPTEL observation class interface definition.
COMPTEL instrument response function class interface definition.
Calibration database class interface definition.
Energy value class definition.
Abstract event base class definition.
Single precision FITS image class definition.
Abstract FITS image base class definition.
FITS file class interface definition.
Integration class for set of functions interface definition.
Mathematical function definitions.
Generic matrix class definition.
Sky model class interface definition.
Abstract elliptical spatial model base class interface definition.
Point source spatial model class interface definition.
Abstract radial spatial model base class interface definition.
Constant spectral model class interface definition.
Abstract observation base class interface definition.
Time class interface definition.
Vector class interface definition.
const double & phase_correction(void) const
Return pulsar phase correction factor.
const double & tof_correction(void) const
Return ToF correction factor.
const GSkyMap & map(void) const
Return DRI sky map.
virtual const GTime & time(void) const
Return time of event bin.
virtual const GCOMInstDir & dir(void) const
Return instrument direction of event bin.
virtual const GEnergy & energy(void) const
Return energy of event bin.
COMPTEL event bin container class.
virtual int size(void) const
Return number of bins in event cube.
const GCOMDri & dre(void) const
Return reference to DRE data.
virtual int naxis(const int &axis) const
Return number of bins in axis.
Interface for the COMPTEL instrument direction class.
void dir(const GSkyDir &dir)
Set event scatter direction.
void phibar(const double &phibar)
Set event Compton scatter angle.
Interface class for COMPTEL observations.
virtual double ontime(void) const
Return ontime.
virtual double deadc(const GTime &time=GTime()) const
Return deadtime correction factor.
const GCOMDri & drx(void) const
Return exposure.
const GCOMDri & drg(void) const
Return geometry factors.
Interface for the COMPTEL instrument response function.
virtual double irf(const GEvent &event, const GPhoton &photon, const GObservation &obs) const
Return value of instrument response function.
void free_members(void)
Delete class members.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print COMPTEL response information.
virtual GVector irf_ptsrc(const GModelSky &model, const GObservation &obs, GMatrix *gradients=NULL) const
Return instrument response to point source.
int m_phigeo_bins
Number of Phigeo bins.
double m_phibar_min
Phigeo value of first bin (deg)
void write(GFitsImageFloat &image) const
Write COMPTEL response into FITS image.
GCOMResponse(void)
Void constructor.
virtual GVector irf_radial(const GModelSky &model, const GObservation &obs, GMatrix *gradients=NULL) const
Return instrument response to radial source.
int m_phibar_bins
Number of Phibar bins.
const std::string & rspname(void) const
Return response name.
double m_phibar_bin_size
Phigeo binsize (deg)
void copy_members(const GCOMResponse &rsp)
Copy class members.
std::vector< double > m_iaq
IAQ array.
double m_phigeo_min
Phigeo value of first bin (deg)
virtual ~GCOMResponse(void)
Destructor.
virtual GVector irf_elliptical(const GModelSky &model, const GObservation &obs, GMatrix *gradients=NULL) const
Return instrument response to elliptical source.
const GCaldb & caldb(void) const
Return calibration database.
double m_phibar_ref_value
Phigeo reference value (deg)
void read(const GFitsImage &hdu)
Read COMPTEL response from FITS image.
double m_phigeo_ref_value
Phigeo reference value (deg)
std::string m_rspname
Response name.
virtual GEbounds ebounds(const GEnergy &obsEnergy) const
Return true energy boundaries for a specific observed energy.
GCaldb m_caldb
Calibration database.
void init_members(void)
Initialise class members.
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.
virtual void clear(void)
Clear instance.
double m_phigeo_ref_pixel
Phigeo reference pixel (starting from 1)
double m_phigeo_bin_size
Phigeo binsize (deg)
virtual GVector irf_diffuse(const GModelSky &model, const GObservation &obs, GMatrix *gradients=NULL) const
Return instrument response to diffuse source.
virtual GCOMResponse * clone(void) const
Clone instance.
double m_phibar_ref_pixel
Phigeo reference pixel (starting from 1)
virtual GCOMResponse & operator=(const GCOMResponse &rsp)
Assignment operator.
void load(const std::string &rspname)
Load COMPTEL response.
Calibration database class.
std::string rootdir(void) const
Return path to CALDB root directory.
GFilename filename(const std::string &detector, const std::string &filter, const std::string &codename, const std::string &date, const std::string &time, const std::string &expr)
Return calibration file name based on selection parameters.
void clear(void)
Clear calibration database.
std::string print(const GChatter &chatter=NORMAL) const
Print calibration database information.
Energy boundaries container class.
Class that handles energies in a unit independent way.
Abstract interface for the event classes.
bool is_fits(void) const
Checks whether file is a FITS file.
bool exists(void) const
Checks whether file exists.
bool is_empty(void) const
Signal if filename is empty.
double real(const std::string &keyname) const
Return card value as double precision.
GFitsHeaderCard & card(const int &cardno)
Return header card.
Single precision FITS image class.
Abstract FITS image base class.
virtual double pixel(const int &ix) const =0
int naxes(const int &axis) const
Return dimension of an image axis.
const int & naxis(void) const
Return dimension of image.
GFitsImage * image(const int &extno)
Get pointer to image HDU.
void close(void)
Close FITS file.
Integration class for set of functions.
GVector romberg(std::vector< double > bounds, const int &order=5)
Perform Romberg integration.
void fixed_iter(const int &iter)
Set fixed number of iterations.
Generic matrix class definition.
void eulerz(const double &angle)
Set Euler rotation matrix around z axis.
void eulery(const double &angle)
Set Euler rotation matrix around y axis.
GModelSpatial * spatial(void) const
Return spatial model component.
Abstract elliptical spatial model base class.
const GSkyDir & dir(void) const
Return position of elliptical spatial model.
virtual double theta_max(void) const =0
Point source spatial model.
Abstract radial spatial model base class.
virtual double theta_max(void) const =0
const GSkyDir & dir(void) const
Return position of radial spatial model.
virtual double eval(const GPhoton &photon, const bool &gradients=false) const =0
Abstract observation base class.
virtual GEvents * events(void)
Return events.
virtual double deadc(const GTime &time=GTime()) const =0
void name(const std::string &name)
Set observation name.
void id(const std::string &id)
Set observation identifier.
Class that handles photons.
const GTime & time(void) const
Return photon time.
const GSkyDir & dir(void) const
Return photon sky direction.
Abstract instrument response base class.
void init_members(void)
Initialise class members.
void free_members(void)
Delete class members.
virtual GResponse & operator=(const GResponse &rsp)
Assignment operator.
double dec_deg(void) const
Returns Declination in degrees.
double ra_deg(void) const
Returns Right Ascension in degrees.
double dist_deg(const GSkyDir &dir) const
Compute angular distance between sky directions in degrees.
void rotate(const double &phi, const double &theta)
Rotate sky direction by zenith and azimuth angle.
double dist(const GSkyDir &dir) const
Compute angular distance between sky directions in radians.
bool contains(const GSkyDir &dir) const
Checks if sky direction falls in map.
const double * pixels(void) const
Returns pointer to pixel data.
Kernel for rho angle integration of elliptical models.
Kernel for rho angle integration of radial models.
Defintion of COMPTEL helper classes for vector response.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
bool is_infinite(const double &x)
Signal if argument is infinite.
bool is_notanumber(const double &x)
Signal if argument is not a number.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
std::string filepath(const std::string &pathname, const std::string &filename)
Build file path from path name and file name.