61#define G_CONVOLVE "GResponse::convolve(GModelSky&, GObservation&, "\
63#define G_IRF_RADIAL "GResponse::irf_radial(GEvent&, GSource&,"\
65#define G_IRF_ELLIPTICAL "GResponse::irf_elliptical(GEvent&, GSource&,"\
67#define G_IRF_DIFFUSE "GResponse::irf_diffuse(GEvent&, GSource&,"\
189 const bool& grad)
const
192 static const int iter = 6;
201 GTime srcTime =
event.time();
236 if (etrue_max > etrue_min) {
239 edisp_kerns integrand(
this, &obs, &model, &event, srcTime, grad);
246 array += integral.
romberg(etrue_min, etrue_max);
256 prob = array[index++];
263 for (
int i = 0; i < model.
spectral()->size(); ++i) {
283 for (
int i = 0; i < model.
scales(); ++i) {
301 GEnergy srcEng =
event.energy();
304 prob =
eval_prob(model, event, srcEng, srcTime, obs, grad);
309 #if defined(G_NAN_CHECK)
311 std::cout <<
"*** ERROR: GResponse::convolve:";
312 std::cout <<
" NaN/Inf encountered";
313 std::cout <<
" (prob=" << prob;
314 std::cout <<
", event=" << event;
315 std::cout <<
", srcTime=" << srcTime;
316 std::cout <<
")" << std::endl;
351 static const int iter = 6;
354 int npars = model.
size();
358 bool grad = (gradients != NULL);
364 int ncolumns = (nevents > 0) ? npars : 0;
365 if (gradients->
columns() != ncolumns) {
367 "columns in gradient matrix differs from expected "
369 "specify compatible arguments.";
374 int nrows = (ncolumns > 0) ? nevents : 0;
375 if (gradients->
rows() != nrows) {
377 "rows in gradient matrix differs from expected "
379 "specify compatible arguments.";
397 tmp_gradients =
new GVector[npars];
398 for (
int i = 0; i < npars; ++i) {
399 tmp_gradients[i] =
GVector(nevents);
410 for (
int k = 0; k < nevents; ++k) {
416 GTime srcTime =
event.time();
442 if (etrue_max > etrue_min) {
445 edisp_kerns integrand(
this, &obs, &model, &event, srcTime, grad);
452 array += integral.
romberg(etrue_min, etrue_max);
462 probs[k] = array[index++];
475 for (
int i = 0; i < n_spec; ++i) {
478 tmp_gradients[offset+i][k] = array[index++];
485 int offset = n_spat + n_spec;
486 for (
int i = 0; i < n_temp; ++i) {
489 tmp_gradients[offset+i][k] = array[index++];
496 int offset = n_spat + n_spec + n_temp;
497 for (
int i = 0; i < model.
scales(); ++i) {
501 tmp_gradients[offset+i][k] = array[index++];
510 #if defined(G_NAN_CHECK)
512 std::cout <<
"*** ERROR: GResponse::convolve:";
513 std::cout <<
" NaN/Inf encountered";
514 std::cout <<
" (probs[" << k <<
"]=" << probs[k];
515 std::cout <<
", event=" << event;
516 std::cout <<
", srcTime=" << srcTime;
517 std::cout <<
")" << std::endl;
527 for (
int i = 0; i < npars; ++i) {
528 gradients->
column(i, tmp_gradients[i]);
532 delete [] tmp_gradients;
604 std::string name = obs.
id() +
":" + source.
name();
606 const GEnergy& ereco =
event.energy();
701 int npars = model.
size();
711 std::string cache_id = obs.
id() +
":" + model.
name();
871 double irf = this->
irf(event, photon, obs);
931 double theta_min = 0.0;
932 double theta_max = model->
theta_max() - 1.0e-12;
937 if (theta_max > theta_min) {
947 GMatrix rot = (ry * rz).transpose();
967 #if defined(G_NAN_CHECK)
969 std::cout <<
"*** ERROR: GResponse::irf_radial:";
970 std::cout <<
" NaN/Inf encountered";
971 std::cout <<
" (irf=" <<
irf;
972 std::cout <<
", theta_min=" << theta_min;
973 std::cout <<
", theta_max=" << theta_max <<
")";
974 std::cout << std::endl;
1038 double theta_min = 0.0;
1039 double theta_max = model->
theta_max() - 1.0e-6;
1044 if (theta_max > theta_min) {
1054 GMatrix rot = (ry * rz).transpose();
1074 #if defined(G_NAN_CHECK)
1076 std::cout <<
"*** ERROR: GResponse::irf_elliptical:";
1077 std::cout <<
" NaN/Inf encountered";
1078 std::cout <<
" (irf=" <<
irf;
1079 std::cout <<
", theta_min=" << theta_min;
1080 std::cout <<
", theta_max=" << theta_max <<
")";
1081 std::cout << std::endl;
1145 for (
int i = 0; i < skymap.
npix(); ++i) {
1148 double value = skymap(i);
1159 GPhoton photon(srcDir, srcEng, srcTime);
1180 for (
int i = 0; i < skymap.
npix(); ++i) {
1186 GPhoton photon(srcDir, srcEng, srcTime);
1189 double value = cube->
eval(photon);
1211 double dx = 360.0 / double(nx);
1212 double dy = 180.0 / double(ny);
1213 GSkyMap skymap =
GSkyMap(
"CAR",
"CEL", 0.0, 0.0, -dx, dy, nx, ny);
1220 for (
int i = 0; i < skymap.
npix(); ++i) {
1226 GPhoton photon(srcDir, srcEng, srcTime);
1229 double value = model->
eval(photon);
1274 for (
int i = 0; i < composite->
components(); ++i) {
1280 std::string name = source.
name() +
":" + composite->
name(i);
1323 for (
int k = 0; k < nevents; ++k) {
1329 GEnergy srcEng =
event.energy();
1330 GTime srcTime =
event.time();
1336 irfs[k] = this->
irf_ptsrc(event, source, obs);
1367 for (
int k = 0; k < nevents; ++k) {
1373 GEnergy srcEng =
event.energy();
1374 GTime srcTime =
event.time();
1380 irfs[k] = this->
irf_radial(event, source, obs);
1411 for (
int k = 0; k < nevents; ++k) {
1417 GEnergy srcEng =
event.energy();
1418 GTime srcTime =
event.time();
1458 for (
int k = 0; k < nevents; ++k) {
1464 GEnergy srcEng =
event.energy();
1465 GTime srcTime =
event.time();
1474 if (gradients != NULL) {
1475 (*gradients)(k,0) = (value.
is_free()) ? irfs[k] * value.
scale() : 0.0;
1519 for (
int i = 0; i < composite->
components(); ++i) {
1540 if (gradients != NULL) {
1543 for (
int j = 0; j < spatial->
size(); ++j, ++ipar) {
1544 for (
int k = 0; k < nevents; ++k) {
1545 (*gradients)(k,ipar) = spat_gradients(k,j);
1550 double scale = (composite->
normalize() &&
sum != 0.0) ?
1556 for (
int k = 0; k < nevents; ++k) {
1557 (*gradients)(k,ipar) = (composite->
scale(i)->
is_free()) ?
irf[k] * scale : 0.0;
1600 const GTime& srcTime,
1602 const bool& grad)
const
1608 if (model.
spatial() != NULL) {
1624 double spec = (model.
spectral() != NULL)
1626 double temp = (model.
temporal() != NULL)
1630 prob = spec * temp *
irf * scale;
1637 double fact = temp *
irf * scale;
1640 (*model.
spectral())[i].factor_gradient((*model.
spectral())[i].factor_gradient() * fact);
1647 double fact = spec *
irf * scale;
1650 (*model.
temporal())[i].factor_gradient((*model.
temporal())[i].factor_gradient() * fact);
1657 for (
int i = 0; i < model.
scales(); ++i) {
1658 double g_scale = 0.0;
1671 #if defined(G_NAN_CHECK)
1673 std::cout <<
"*** ERROR: GResponse::eval_prob:";
1674 std::cout <<
" NaN/Inf encountered";
1675 std::cout <<
" (prob=" << prob;
1676 std::cout <<
", spec=" << spec;
1677 std::cout <<
", temp=" << temp;
1678 std::cout <<
", irf=" <<
irf;
1679 std::cout <<
")" << std::endl;
1692 (*model.
spectral())[i].factor_gradient(0.0);
1699 (*model.
temporal())[i].factor_gradient(0.0);
1705 for (
int i = 0; i < model.
scales(); ++i) {
1740 int npars = model.
size();
1744 bool grad = (gradients != NULL);
1750 if (model.
spatial() != NULL) {
1763 GVector* tmp_gradients = NULL;
1765 tmp_gradients =
new GVector[npars];
1766 for (
int i = 0; i < npars; ++i) {
1767 tmp_gradients[i] =
GVector(nevents);
1772 for (
int k = 0; k < nevents; ++k) {
1775 double spat = probs[k];
1784 GEnergy srcEng =
event.energy();
1785 GTime srcTime =
event.time();
1788 double spec = (model.
spectral() != NULL)
1791 double temp = (model.
temporal() != NULL)
1796 probs[k] = spat * spec * temp * scale;
1807 if (model.
spatial() != NULL) {
1808 double fact = spec * temp * scale;
1809 for (
int i = 0; i < n_spat; ++i) {
1810 tmp_gradients[i][k] = spat_gradients(k,i) * fact;
1816 int offset = n_spat;
1817 double fact = spat * temp * scale;
1818 for (
int i = 0; i < n_spec; ++i) {
1819 tmp_gradients[offset+i][k] =
1820 (*(model.
spectral()))[i].factor_gradient() * fact;
1826 int offset = n_spat + n_spec;
1827 double fact = spat * spec * scale;
1828 for (
int i = 0; i < n_temp; ++i) {
1829 tmp_gradients[offset+i][k] =
1830 (*(model.
temporal()))[i].factor_gradient() * fact;
1836 int offset = n_spat + n_spec + n_temp;
1837 double fact = spat * spec * temp;
1838 for (
int i = 0; i < model.
scales(); ++i) {
1840 double g_scale = 0.0;
1843 tmp_gradients[offset+i][k] = par.
scale() * fact;
1854 #if defined(G_NAN_CHECK)
1856 std::cout <<
"*** ERROR: GResponse::eval_prob:";
1857 std::cout <<
" NaN/Inf encountered";
1858 std::cout <<
" (probs[" << k <<
"]=" << probs[k];
1859 std::cout <<
", spat=" << spat;
1860 std::cout <<
")" << std::endl;
1870 for (
int i = 0; i < npars; ++i) {
1871 gradients->
column(i, tmp_gradients[i]);
1875 delete [] tmp_gradients;
1899 const bool& grad)
const
1907 for (
int i = 0; i < model.
spectral()->size(); ++i) {
1923 for (
int i = 0; i < model.
scales(); ++i) {
1956 const GTime& srcTime,
2034 if (gauss != NULL) {
2037 const double width = 5.0;
2042 GEnergy ebound_min = mean - width * sigma;
2043 GEnergy ebound_max = mean + width * sigma;
2046 if (ebound_min.
MeV() < 0.0) {
2047 ebound_min.
MeV(0.0);
2049 if (ebound_max.
MeV() < 0.0) {
2050 ebound_max.
MeV(0.0);
2054 if (ebound_max > ebound_min) {
2086 kernels[index++] = m_parent->eval_prob(*m_model, *m_event,
2087 srcEng, m_srcTime, *m_obs,
2093 for (
int i = 0; i < m_pars.size(); ++i, ++index) {
2094 kernels[index] = m_pars[i]->factor_gradient();
2099 #if defined(G_NAN_CHECK)
2101 std::cout <<
"*** ERROR: GResponse::edisp_kern::eval";
2102 std::cout <<
"(etrue=" << etrue <<
"): NaN/Inf encountered";
2103 std::cout <<
" (value=" << kernels[0] <<
")" << std::endl;
2131 double model = m_model->eval(theta, *m_srcEng, *m_srcTime);
2137 double phi_min = 0.0;
2154 irf = integral.
romberg(phi_min, phi_max, m_iter_phi) *
2155 model * std::sin(theta);
2178 double cos_phi = std::cos(phi);
2179 double sin_phi = std::sin(phi);
2180 GVector native(-cos_phi*m_sin_theta, sin_phi*m_sin_theta, m_cos_theta);
2183 GVector vector = (*m_rot) * native;
2189 GPhoton photon(dir, *m_srcEng, *m_srcTime);
2192 double irf = m_rsp->irf(*m_event, photon, *m_obs);
2218 double phi_min = 0.0;
2236 irf = integral.
romberg(phi_min, phi_max, m_iter_phi) * std::sin(theta);
2260 double model = m_model->eval(m_theta, phi, *m_srcEng, *m_srcTime);
2266 double cos_phi = std::cos(phi);
2267 double sin_phi = std::sin(phi);
2268 GVector native(-cos_phi*m_sin_theta, sin_phi*m_sin_theta, m_cos_theta);
2271 GVector vector = (*m_rot) * native;
2277 GPhoton photon(dir, *m_srcEng, *m_srcTime);
2280 irf = m_rsp->irf(*m_event, photon, *m_obs) * model;
Energy boundaries class interface definition.
Energy value class definition.
Abstract event base class definition.
Exception handler interface definition.
Integration class interface definition.
Integration class for set of functions interface definition.
Mathematical function definitions.
Sparse matrix class definition.
Generic matrix class definition.
Sky model class interface definition.
Spatial composite model class interface definition.
Spatial map cube model class interface definition.
Spatial map model class interface definition.
Abstract diffuse spatial model base 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.
Gaussian spectral model class interface definition.
Abstract observation base class interface definition.
Abstract response base class definition.
Sky map class definition.
Time class interface definition.
@ GMODEL_SPATIAL_ELLIPTICAL
@ GMODEL_SPATIAL_COMPOSITE
@ GMODEL_SPATIAL_POINT_SOURCE
double sum(const GVector &vector)
Computes vector sum.
Vector class interface definition.
Energy boundaries container class.
const GEnergy & emax(void) const
Return maximum energy of all intervals.
void append(const GEnergy &emin, const GEnergy &emax)
Append energy interval.
int size(void) const
Return number of energy boundaries.
const GEnergy & emin(void) const
Return minimum energy of all intervals.
Class that handles energies in a unit independent way.
double MeV(void) const
Return energy in MeV.
Abstract interface for the event classes.
virtual const GEnergy & energy(void) const =0
virtual int size(void) const =0
Abstract instrument direction base class.
GIntegral class interface definition.
double romberg(std::vector< double > bounds, const int &order=5)
Perform Romberg integration.
void fixed_iter(const int &iter)
Set fixed number of iterations.
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.
const int & rows(void) const
Return number of matrix rows.
const int & columns(void) const
Return number of matrix columns.
Sparse matrix class interface definition.
virtual GVector column(const int &column) const
Extract column as vector from matrix.
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.
GModelSpectral * spectral(void) const
Return spectral model component.
GModelTemporal * temporal(void) const
Return temporal model component.
GModelSpatial * spatial(void) const
Return spatial model component.
const GModelSpatial * component(const int &index) const
Returns pointer to spatial component element.
const GModelPar * scale(const int &index) const
Returns scale parameter of spatial component.
int components(void) const
Return number of model components.
double sum_of_scales(void) const
Returns sum of all model scales.
const bool & normalize(void) const
Return normalisation flag.
std::string name(const int &index) const
Returns names of spatial component.
const GSkyMap & cube(void) const
Get map cube.
virtual double eval(const GPhoton &photon, const bool &gradients=false) const
Evaluate function.
const GSkyMap & map(void) const
Get map.
Abstract diffuse spatial model base class.
virtual double eval(const GPhoton &photon, const bool &gradients=false) const =0
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.
const GSkyDir & dir(void) const
Return position of point source.
Abstract radial spatial model base class.
virtual double theta_max(void) const =0
const GSkyDir & dir(void) const
Return position of radial spatial model.
Abstract spatial model base class.
bool has_free_pars(void) const
Checks if the spatial model has free parameters.
virtual GClassCode code(void) const =0
int size(void) const
Return number of parameters.
Gaussian spectral model class.
GEnergy mean(void) const
Return mean energy.
GEnergy sigma(void) const
Return energy width.
virtual double eval(const GEnergy &srcEng, const GTime &srcTime=GTime(), const bool &gradients=false) const =0
int size(void) const
Return number of parameters.
virtual double eval(const GTime &srcTime, const bool &gradients=false) const =0
int size(void) const
Return number of parameters.
GModelPar & scale(const int &index)
Returns reference to scale parameter by index.
bool has_scales(void) const
Signals that model has scales.
int size(void) const
Return number of parameters in model.
const std::string & name(void) const
Return parameter name.
int scales(void) const
Return number of scale parameters in model.
Abstract observation base class.
virtual GEvents * events(void)
Return events.
virtual std::string instrument(void) const =0
void id(const std::string &id)
Set observation identifier.
bool is_free(void) const
Signal if parameter is free.
const double & scale(void) const
Return parameter scale.
bool has_grad(void) const
Signal if parameter gradient is computed analytically.
const double & factor_gradient(void) const
Return parameter factor gradient.
double value(void) const
Return parameter value.
const std::string & name(void) const
Return parameter name.
Class that handles photons.
bool contains(const std::string &name, const GEnergy &ereco, const GEnergy &etrue, double *value=NULL) const
Check if cache contains a value for specific parameters.
void remove(const std::string &name)
Remove cache for source.
void set(const std::string &name, const GEnergy &ereco, const GEnergy &etrue, const double &value)
Set cache value.
void clear(void)
Clear response cache.
bool contains(const std::string &cache_id, GVector *irfs=NULL) const
Check if cache contains a value for specific parameters.
void remove(const std::string &cache_id)
Remove cache.
void clear(void)
Clear response vector cache.
void set(const std::string &cache_id, const GVector &vector)
Set cache value.
const GEvent * m_event
Event.
const GResponse * m_parent
Response.
std::vector< GModelPar * > m_pars
Parameter pointers.
GVector eval(const double &etrue)
Evaluate energy dispersion integration kernel.
bool m_grad
Gradient flag.
int m_size
Array of values and gradients.
const GModelSky * m_model
Sky model.
edisp_kerns(const GResponse *parent, const GObservation *obs, const GModelSky *model, const GEvent *event, const GTime &srcTime, const bool &grad)
Constructor for energy dispersion integration kernels class.
GTime m_srcTime
True arrival time.
const GObservation * m_obs
Observation.
double eval(const double &phi)
Azimuth angle integration kernel for elliptical model.
double eval(const double &phi)
Zenith angle integration kernel for elliptical model.
double eval(const double &phi)
Azimuth angle integration kernel for radial model.
double eval(const double &phi)
Zenith angle integration kernel for radial model.
Abstract instrument response base class.
GResponseCache m_irf_cache
GVector eval_probs(const GModelSky &model, const GObservation &obs, GMatrixSparse *gradients=NULL) const
Convolve sky model with the instrument response.
virtual double irf_spatial(const GEvent &event, const GSource &source, const GObservation &obs) const
Return instrument response integrated over the spatial model.
int m_irf_elliptical_iter_theta
Elliptical model integration theta iterations.
int m_irf_radial_iter_phi
Radial model integration phi iterations.
void copy_members(const GResponse &rsp)
Copy class members.
virtual ~GResponse(void)
Destructor.
virtual double irf_ptsrc(const GEvent &event, const GSource &source, const GObservation &obs) const
Return instrument response to point source.
GResponseCache m_nroi_cache
double eval_prob(const GModelSky &model, const GEvent &event, const GEnergy &srcEng, const GTime &srcTime, const GObservation &obs, const bool &grad) const
Convolve sky model with the instrument response.
virtual double irf(const GEvent &event, const GPhoton &photon, const GObservation &obs) const =0
GResponse(void)
Void constructor.
virtual double convolve(const GModelSky &model, const GEvent &event, const GObservation &obs, const bool &grad=true) const
Convolve sky model with the instrument response.
virtual double irf_radial(const GEvent &event, const GSource &source, const GObservation &obs) const
Return instrument response to radial source.
GEbounds ebounds_model(const GModelSky &model) const
Return true energy intervals for sky model.
int size_edisp_vector(const GModelSky &model, const GObservation &obs, const bool &grad) const
Return size of vector for energy dispersion computation.
virtual void remove_response_cache(const std::string &cache_id)
Remove response cache for specific observation and model.
int m_irf_elliptical_iter_phi
Elliptical model integration phi iterations.
bool m_use_nroi_cache
Control usage of nroi cache.
virtual GEbounds ebounds(const GEnergy &obsEng) const =0
virtual double irf_elliptical(const GEvent &event, const GSource &source, const GObservation &obs) const
Return instrument response to elliptical source.
virtual double irf_diffuse(const GEvent &event, const GSource &source, const GObservation &obs) const
Return instrument response to diffuse source.
virtual bool use_edisp(void) const =0
GResponseVectorCache m_irf_vector_cache
void init_members(void)
Initialise class members.
void free_members(void)
Delete class members.
bool m_use_irf_cache
Control usage of irf cache.
virtual double irf_composite(const GEvent &event, const GSource &source, const GObservation &obs) const
Return instrument response to composite source.
virtual GResponse & operator=(const GResponse &rsp)
Assignment operator.
double m_irf_diffuse_resolution
Angular resolution for diffuse model.
int m_irf_radial_iter_theta
Radial model integration theta iterations.
double dec_deg(void) const
Returns Declination in degrees.
double ra_deg(void) const
Returns Right Ascension in degrees.
double solidangle(const int &index) const
Returns solid angle of pixel.
GSkyDir inx2dir(const int &index) const
Returns sky direction of pixel.
const int & npix(void) const
Returns number of pixels.
Class that handles gamma-ray sources.
const GEnergy & energy(void) const
Return photon energy.
const std::string & name(void) const
Return model name.
const GTime & time(void) const
Return photon arrival time.
const GModelSpatial * model(void) const
Return spatial model component.
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.