62#define G_IRF "GSPIResponse::irf(GEvent&, GSource&, GObservation&)"
63#define G_NROI "GSPIResponse::nroi(GModelSky&, GEnergy&, GTime&, "\
65#define G_EBOUNDS "GSPIResponse::ebounds(GEnergy&)"
66#define G_SET "GSPIResponse::set(const GSPIObservation& obs)"
67#define G_LOAD_IRF "GSPIResponse::load_irf(GFilename&)"
68#define G_LOAD_IRFS "GSPIResponse::load_irfs(int&)"
73#define G_IRF_RADIAL_PROJECTION
74#define G_IRF_ELLIPTICAL_PROJECTION
75#define G_IRF_DIFFUSE_PROJECTION
269 if (spi_obs == NULL) {
270 std::string cls = std::string(
typeid(&obs).name());
271 std::string msg =
"Observation of type \""+cls+
"\" is not an "
272 "INTEGRAL/SPI observation. Please specify an "
273 "INTEGRAL/SPI observation as argument.";
280 std::string msg =
"INTEGRAL/SPI observation does not contain a valid "
281 "event cube. Please specify an observation with an "
282 "event cube as argument.";
289 std::string cls = std::string(
typeid(&event).name());
290 std::string msg =
"Event of type \""+cls+
"\" is not an INTEGRAL/SPI "
291 "event. Please specify an INTEGRAL/SPI event as "
308 #if defined(G_NAN_CHECK)
310 std::cout <<
"*** ERROR: GSPIResponse::irf:";
311 std::cout <<
" NaN/Inf encountered";
312 std::cout <<
" (irf=" <<
irf;
314 std::cout << std::endl;
342 const int& ireg)
const
370 int ieng = bin.
iebin();
373 int map = idet + (ireg + ieng * nreg) * ndet;
376 int ix_left = int(xpix);
377 int ix_right = ix_left + 1;
378 int iy_top = int(ypix);
379 int iy_bottom = iy_top + 1;
382 double wgt_right = xpix - double(ix_left);
383 double wgt_left = 1.0 - wgt_right;
384 double wgt_bottom = ypix - double(iy_top);
385 double wgt_top = 1.0 - wgt_bottom;
388 int inx_1 = ix_left + iy_top * nx;
389 int inx_2 = ix_right + iy_top * nx;
390 int inx_3 = ix_left + iy_bottom * nx;
391 int inx_4 = ix_right + iy_bottom * nx;
394 double wgt_1 = wgt_left * wgt_top;
395 double wgt_2 = wgt_right * wgt_top;
396 double wgt_3 = wgt_left * wgt_bottom;
397 double wgt_4 = wgt_right * wgt_bottom;
433 const GTime& obsTime,
437 std::string msg =
"Spatial integration of sky model over the data space "
438 "is not implemented.";
463 std::string msg =
"Energy dispersion not implemented.";
511 int neng = cube->
naxis(2);
515 irfs.
nmaps(ndet * nreg * neng);
516 irfs.
shape(ndet, nreg, neng);
520 for (
int ieng = 0; ieng < neng; ++ieng) {
523 double emin = cube->
ebounds().emin(ieng).keV();
524 double emax = cube->
ebounds().emax(ieng).keV();
541 for (
int idet = 0; idet < ndet; ++idet) {
542 for (
int ireg = 0; ireg < nreg; ++ireg) {
543 int map_irf = idet + ireg * ndet;
544 int map_irfs = idet + (ireg + ieng * nreg) * ndet;
545 for (
int i = 0; i < npix; ++i) {
546 irfs(i, map_irfs) =
irf(i, map_irf);
631 GFits fits(filename);
661 fits.
saveto(filename, clobber);
693 result.append(
"=== GSPIResponse ===");
703 result.append(
"] deg");
707 result.append(
"] deg");
837 int num = table.
nrows();
843 for (
int i = 0; i < num; ++i) {
892 int num = table.
nrows();
898 std::string unit =
"keV";
900 unit = table.
string(
"TUNIT1");
904 for (
int i = 0; i < num; ++i) {
938 for (
int i = 0; i < num; ++i) {
976 table.
card(
"ENERGY",
m_energy_keV,
"[keV] IRF line energy (0 for continuum IRF)");
977 table.
card(
"DLOGE",
m_dlogE,
"Logarithmic step size for continuum IRF");
978 table.
card(
"GAMMA",
m_gamma,
"Power-law index for continuum IRF");
992 for (
int i = 0; i < num; ++i) {
995 col_energy.
unit(
"keV");
1024 GFits fits(irfname);
1030 int naxis1 = image->
integer(
"NAXIS1");
1031 int naxis2 = image->
integer(
"NAXIS2");
1032 int naxis3 = image->
integer(
"NAXIS3");
1033 int naxis4 = image->
integer(
"NAXIS4");
1034 double crval2 = image->
real(
"CRVAL2");
1035 double crval3 = image->
real(
"CRVAL3");
1036 double crpix2 = image->
real(
"CRPIX2");
1037 double crpix3 = image->
real(
"CRPIX3");
1038 double cdelt2 = image->
real(
"CDELT2");
1039 double cdelt3 = image->
real(
"CDELT3");
1048 double wcs_xmax = wcs_xmin + double(naxis2-1) * wcs_xbin;
1049 double wcs_ymax = wcs_ymin + double(naxis3-1) * wcs_ybin;
1050 double wcs_xpix_max = double(naxis2-1);
1051 double wcs_ypix_max = double(naxis3-1);
1070 if ((std::abs(wcs_xmin -
m_wcs_xmin) > 1.0e-6) ||
1071 (std::abs(wcs_ymin -
m_wcs_ymin) > 1.0e-6) ||
1072 (std::abs(wcs_xbin -
m_wcs_xbin) > 1.0e-6) ||
1073 (std::abs(wcs_ybin -
m_wcs_ybin) > 1.0e-6) ||
1074 (std::abs(wcs_xmax -
m_wcs_xmax) > 1.0e-6) ||
1075 (std::abs(wcs_ymax -
m_wcs_ymax) > 1.0e-6) ||
1078 std::string msg =
"Inconsistent IRFs encountered in file \""+
1079 irfname.
url()+
"\". Please specify a response "
1080 "group where all IRFs have the same definition.";
1090 int nmap = naxis1 * naxis4;
1094 GSkyMap irf(
"ARC",
"CEL", crval2, crval3, cdelt2, cdelt3, naxis2, naxis3, nmap);
1097 for (
int ix = 0; ix < naxis2; ++ix) {
1098 for (
int iy = 0; iy < naxis3; ++iy) {
1099 for (
int idet = 0; idet < naxis1; ++idet) {
1100 for (
int ireg = 0; ireg < naxis4; ++ireg) {
1101 int index = ix + iy * naxis2;
1102 int map = idet + ireg * naxis1;
1103 irf(index,map) = image->
pixel(idet, ix, iy, ireg);
1110 irf.shape(naxis1, naxis4);
1145 std::string msg =
"No response grouping table found in file \""+
1147 "response grouping file.";
1155 for (
int i_irf = 0; i_irf < num_irfs; ++i_irf) {
1160 for (
int i_irf = 0; i_irf < num_irfs; ++i_irf) {
1164 (*grp)[
"MEMBER_LOCATION"]->string(i_irf);
1170 int num_regions = (region == -1) ?
irf.shape()[1] : 1;
1190 int ndet =
irf.shape()[0];
1193 for (
int i_region = 0; i_region < num_regions; ++i_region) {
1196 for (
int i_det = 0; i_det < num_det; ++i_det) {
1199 int map_irf =
m_detids[i_det] + i_region * ndet;
1200 int map_irfs = i_det + (i_region + i_irf * num_regions) * num_det;
1203 for (
int i = 0, iy = 0; iy < ny; ++iy) {
1204 for (
int ix = 0; ix < nx; ++ix, ++i) {
1242 #if defined(G_DEBUG_COMPUTE_IRF)
1243 std::cout <<
"GSPIResponse::compute_irf:" << std::endl;
1244 std::cout <<
"- emin = " << emin <<
" keV" << std::endl;
1245 std::cout <<
"- emax = " << emax <<
" keV" << std::endl;
1246 std::cout <<
"- npix = " << npix << std::endl;
1247 std::cout <<
"- ndet = " << ndet << std::endl;
1248 std::cout <<
"- nreg = " << nreg << std::endl;
1253 irf.nmaps(ndet * nreg);
1254 irf.shape(ndet, nreg);
1261 double log_emin = std::log10(emin);
1262 double log_emax = std::log10(emax);
1263 double log_ewidth = log_emax - log_emin;
1267 double wgt0 = 1.0 /
irf_weight(beta, log_emin, log_emax);
1271 int num_int = (
m_dlogE > DBL_MIN) ?
int(log_ewidth /
m_dlogE + 0.5) : 1;
1275 double log_estep = log_ewidth / num_int;
1278 #if defined(G_DEBUG_COMPUTE_IRF)
1279 std::cout <<
"- log_emin = " << log_emin << std::endl;
1280 std::cout <<
"- log_emax = " << log_emax << std::endl;
1281 std::cout <<
"- log_ewidth = " << log_ewidth << std::endl;
1282 std::cout <<
"- beta = " << beta << std::endl;
1283 std::cout <<
"- wgt0 = " << wgt0 << std::endl;
1284 std::cout <<
"- num_int = " << num_int << std::endl;
1285 std::cout <<
"- log_estep = " << log_estep << std::endl;
1286 double wgt_check = 0.0;
1290 for (
int i_int = 0; i_int < num_int; ++i_int) {
1293 double log_emin_bin = log_emin + i_int * log_estep;
1294 double log_emax_bin = log_emin_bin + log_estep;
1296 (log_emin_bin + log_emax_bin));
1299 double wgt =
irf_weight(beta, log_emin_bin, log_emax_bin) * wgt0;
1309 #if defined(G_DEBUG_COMPUTE_IRF)
1310 wgt_check += wgt_low + wgt_up;
1314 for (
int idet = 0; idet < ndet; ++idet) {
1315 for (
int ireg = 0; ireg < nreg; ++ireg) {
1316 int map = idet + ireg * ndet;
1317 int map_low = map + irf_low * ndet * nreg;
1318 int map_up = map + irf_up * ndet * nreg;
1319 for (
int i = 0; i < npix; ++i) {
1320 irf(i, map) += wgt_low *
m_irfs(i, map_low) +
1321 wgt_up *
m_irfs(i, map_up);
1329 #if defined(G_DEBUG_COMPUTE_IRF)
1330 std::cout <<
"- wgt_check = " << wgt_check <<
" (should be 1)" << std::endl;
1346 for (
int idet = 0; idet < ndet; ++idet) {
1347 for (
int ireg = 0; ireg < nreg; ++ireg) {
1348 int map = idet + ireg * ndet;
1349 int map_low = map + irf_low * ndet * nreg;
1350 int map_up = map + irf_up * ndet * nreg;
1351 for (
int i = 0; i < npix; ++i) {
1352 irf(i, map) = wgt_low *
m_irfs(i, map_low) +
1353 wgt_up *
m_irfs(i, map_up);
1359 #if defined(G_DEBUG_COMPUTE_IRF)
1360 std::cout <<
"- wgt_low = " << wgt_low << std::endl;
1361 std::cout <<
"- wgt_up = " << wgt_up << std::endl;
1362 std::cout <<
"- wgt_low+wgt_up = " << wgt_low+wgt_up;
1363 std::cout <<
" (should be 1)" << std::endl;
1383 int naxis1 = image->
integer(
"NAXIS1");
1384 int naxis2 = image->
integer(
"NAXIS2");
1385 double crval1 = image->
real(
"CRVAL1");
1386 double crval2 = image->
real(
"CRVAL2");
1387 double crpix1 = image->
real(
"CRPIX1");
1388 double crpix2 = image->
real(
"CRPIX2");
1389 double cdelt1 = image->
real(
"CDELT1");
1390 double cdelt2 = image->
real(
"CDELT2");
1432 int npt = cube->
naxis(0);
1433 int ndet = cube->
naxis(1);
1436 for (
int ipt = 0; ipt < npt; ++ipt) {
1437 for (
int idet = 0; idet < ndet; ++idet) {
1443 std::vector<int>::iterator it = find(
m_detids.begin(),
m_detids.end(), detid);
1469 int npt = cube->
naxis(0);
1478 for (
int ipt = 0; ipt < npt; ++ipt) {
1525 const double* livetimes,
1534 int ix_left = int(xpix);
1535 int ix_right = ix_left + 1;
1536 int iy_top = int(ypix);
1537 int iy_bottom = iy_top + 1;
1540 double wgt_right = xpix - double(ix_left);
1541 double wgt_left = 1.0 - wgt_right;
1542 double wgt_bottom = ypix - double(iy_top);
1543 double wgt_top = 1.0 - wgt_bottom;
1546 int inx_1 = ix_left + iy_top * nx;
1547 int inx_2 = ix_right + iy_top * nx;
1548 int inx_3 = ix_left + iy_bottom * nx;
1549 int inx_4 = ix_right + iy_bottom * nx;
1552 double wgt_1 = wgt_left * wgt_top;
1553 double wgt_2 = wgt_right * wgt_top;
1554 double wgt_3 = wgt_left * wgt_bottom;
1555 double wgt_4 = wgt_right * wgt_bottom;
1561 for (
int idet = 0; idet < cube->
m_num_det; ++idet) {
1564 if (livetimes[idet] > 0.0) {
1570 for (
int ieng = 0; ieng < cube->
m_num_ebin; ++ieng, ++idst) {
1573 int map = detid + (ireg + ieng * nreg) * ndet;
1576 (*irf)[idst] =
m_irfs(inx_1, map) * wgt_1 +
1577 m_irfs(inx_2, map) * wgt_2 +
1578 m_irfs(inx_3, map) * wgt_3 +
1579 m_irfs(inx_4, map) * wgt_4;
1582 if ((*
irf)[idst] < 0.0) {
1592 for (
int ieng = 0; ieng < cube->
m_num_ebin; ++ieng, ++idst) {
1643 const double& emax)
const
1649 if (std::abs(beta) < DBL_MIN) {
1650 weight = (emax - emin);
1698 for (
int ipt = 0; ipt < cube->
m_num_pt; ++ipt) {
1720 irf_vector(cube, xpix, ypix, 0, livetimes, &wrk_irf);
1723 for (
int i = 0, idst = ipt * nirf; i < nirf; ++i, ++idst) {
1724 irfs[idst] = wrk_irf[i];
1762 #if defined(G_DEBUG_IRF_TIMING)
1766 #if defined(G_IRF_RADIAL_PROJECTION)
1767 #if defined(G_DEBUG_IRF_TIMING)
1768 std::cout <<
"GSPIResponse::irf_radial - projection" << std::endl;
1772 static const GTime time;
1786 for (
int ipt = 0; ipt < cube->
m_num_pt; ++ipt) {
1790 double centre_distance = this->
zenith(ipt, radial->
dir());
1804 for (
int inx = 0; inx <
irf.nxy; ++inx) {
1807 if (
irf.zero[inx]) {
1818 if (theta < radial->theta_max()) {
1821 double model = radial->
eval(theta, energy, time);
1827 model *=
irf.solidangle[inx];
1830 for (
int idet = 0, idst = ipt *
irf.nirf; idet < cube->
m_num_det; ++idet) {
1833 if (livetimes[idet] > 0.0) {
1836 for (
int ieng = 0; ieng < cube->
m_num_ebin; ++ieng, ++idst) {
1842 irfs[idst] +=
m_irfs(inx, map) * model;
1865 #if defined(G_DEBUG_IRF_TIMING)
1866 std::cout <<
"GSPIResponse::irf_radial - numerical integration" << std::endl;
1869 static const int iter_rho = 6;
1870 static const int iter_omega = 6;
1885 double rho_min = 0.0;
1886 double rho_max = radial->
theta_max() - 1.0e-12;
1891 if (rho_min < rho_max) {
1901 GMatrix rot = (ry * rz).transpose();
1904 for (
int ipt = 0; ipt < cube->
m_num_pt; ++ipt) {
1908 double centre_distance = this->
zenith(ipt, radial->
dir());
1933 wrk_irfs = integral.
romberg(rho_min, rho_max, iter_rho);
1936 for (
int i = 0, idst = ipt * nirf; i < nirf; ++i, ++idst) {
1937 irfs[idst] = wrk_irfs[i];
1948 #if defined(G_DEBUG_IRF_TIMING)
1950 std::cout <<
"GSPIResponse::irf_radial consumed " << celapse;
1951 std::cout <<
" seconds of CPU time." << std::endl;
1984 #if defined(G_DEBUG_IRF_TIMING)
1988 #if defined(G_IRF_ELLIPTICAL_PROJECTION)
1989 #if defined(G_DEBUG_IRF_TIMING)
1990 std::cout <<
"GSPIResponse::irf_elliptical - projection" << std::endl;
1994 static const GTime time;
2008 for (
int ipt = 0; ipt < cube->
m_num_pt; ++ipt) {
2012 double centre_distance = this->
zenith(ipt, elliptical->
dir());
2026 for (
int inx = 0; inx <
irf.nxy; ++inx) {
2029 if (
irf.zero[inx]) {
2037 double theta = elliptical->
dir().
dist(
irf.dir);
2040 if (theta < elliptical->theta_max()) {
2047 double model = elliptical->
eval(theta, posang, energy, time);
2053 model *=
irf.solidangle[inx];
2056 for (
int idet = 0, idst = ipt *
irf.nirf; idet < cube->
m_num_det; ++idet) {
2059 if (livetimes[idet] > 0.0) {
2062 for (
int ieng = 0; ieng < cube->
m_num_ebin; ++ieng, ++idst) {
2068 irfs[idst] +=
m_irfs(inx, map) * model;
2091 #if defined(G_DEBUG_IRF_TIMING)
2092 std::cout <<
"GSPIResponse::irf_elliptical - numerical integration" << std::endl;
2095 static const int iter_rho = 6;
2096 static const int iter_omega = 6;
2111 double rho_min = 0.0;
2112 double rho_max = elliptical->
theta_max() - 1.0e-6;
2117 if (rho_min < rho_max) {
2127 GMatrix rot = (ry * rz).transpose();
2130 for (
int ipt = 0; ipt < cube->
m_num_pt; ++ipt) {
2134 double centre_distance = this->
zenith(ipt, elliptical->
dir());
2158 wrk_irfs = integral.
romberg(rho_min, rho_max, iter_rho);
2161 for (
int i = 0, idst = ipt * nirf; i < nirf; ++i, ++idst) {
2162 irfs[idst] = wrk_irfs[i];
2173 #if defined(G_DEBUG_IRF_TIMING)
2175 std::cout <<
"GSPIResponse::irf_elliptical consumed " << celapse;
2176 std::cout <<
" seconds of CPU time." << std::endl;
2208 #if defined(G_DEBUG_IRF_TIMING)
2212 #if defined(G_IRF_DIFFUSE_PROJECTION)
2213 #if defined(G_DEBUG_IRF_TIMING)
2214 std::cout <<
"GSPIResponse::irf_diffuse - projection" << std::endl;
2217 static const GTime time;
2231 for (
int ipt = 0; ipt < cube->
m_num_pt; ++ipt) {
2241 for (
int inx = 0; inx <
irf.nxy; ++inx) {
2244 if (
irf.zero[inx]) {
2252 int idst0 = ipt *
irf.nirf;
2255 for (
int ieng = 0; ieng < cube->
m_num_ebin; ++ieng) {
2261 double model = diffuse->
eval(photon);
2267 model *=
irf.solidangle[inx];
2270 for (
int idet = 0, idst = idst0 + ieng; idet < cube->
m_num_det; ++idet) {
2273 if (livetimes[idet] > 0.0) {
2279 irfs[idst] +=
m_irfs(inx, map) * model;
2296 #if defined(G_DEBUG_IRF_TIMING)
2297 std::cout <<
"GSPIResponse::irf_diffuse - not projection" << std::endl;
2318 for (
int k = 0; k < nevents; ++k) {
2324 GEnergy srcEng =
event.energy();
2325 GTime srcTime =
event.time();
2339 #if defined(G_DEBUG_IRF_TIMING)
2341 std::cout <<
"GSPIResponse::irf_diffuse consumed " << celapse;
2342 std::cout <<
" seconds of CPU time." << std::endl;
2380 int nsky = map.
npix();
2386 std::vector<GSkyDir> mapDirs(nsky);
2387 for (
int isky = 0; isky < nsky; ++isky) {
2388 mapDirs[isky] = map.
inx2dir(isky);
2392 for (
int ipt = 0; ipt < cube->
m_num_pt; ++ipt) {
2395 for (
int isky = 0; isky < nsky; ++isky) {
2398 double value = map(isky);
2431 irf_vector(cube, xpix, ypix, 0, livetimes, &wrk_irf);
2434 for (
int i = 0, idst = ipt * nirf; i < nirf; ++i, ++idst) {
2435 (*irfs)[idst] += wrk_irf[i] * value;
2495 for (
int idet = 0; idet < cube->
m_num_det; ++idet) {
2500 irf->zero = std::vector<bool>(
irf->nxy,
true);
2501 for (
int inx = 0; inx <
irf->nxy; ++inx) {
2502 for (
int idet = 0; idet < cube->
m_num_det; ++idet) {
2503 for (
int ieng = 0; ieng < cube->
m_num_ebin; ++ieng) {
2504 int map =
irf->detids[idet] + (
irf->ireg + ieng *
irf->nreg) *
irf->ndet;
2505 if (
m_irfs(inx, map) > 0.0) {
2506 irf->zero[inx] =
false;
2510 if (!
irf->zero[inx]) {
2524 for (
int iy = 0, inx = 0; iy <
irf->ny; ++iy) {
2528 double ypix2 = ypix * ypix;
2531 for (
int ix = 0; ix <
irf->nx; ++ix, ++inx) {
2537 irf->zeniths[inx] = std::sqrt(xpix*xpix + ypix2);
2538 irf->azimuths[inx] = std::atan2(ypix, xpix);
2539 irf->sin_zeniths[inx] = std::sin(
irf->zeniths[inx]);
2540 irf->cos_zeniths[inx] = std::cos(
irf->zeniths[inx]);
2581 irf->rot = (ry * rz).transpose();
2615 double cos_phi = std::cos(
azimuth);
2616 double sin_phi = std::sin(
azimuth);
2619 GVector native(-cos_phi *
irf->sin_zeniths[inx],
2620 sin_phi *
irf->sin_zeniths[inx],
2621 irf->cos_zeniths[inx]);
2627 irf->dir.celvector(vector);
2630 #if defined(G_DEBUG_IRF_SKYDIR)
2631 double zenith_check = this->
zenith(ipt,
irf->dir);
2632 double azimuth_check = this->
azimuth(ipt,
irf->dir);
2635 int ix = inx %
irf->nx;
2636 int iy = inx /
irf->nx;
2637 if ((std::abs(
double(ix)-xpix_check) > 1.0e-3) ||
2638 (std::abs(
double(iy)-ypix_check) > 1.0e-3)) {
2639 std::cout <<
"*** Bad coordinate transformation: (";
2640 std::cout << ix <<
"," << iy <<
") differs from (";
2641 std::cout << xpix_check <<
"," << ypix_check <<
")" << std::endl;
Energy boundaries class interface definition.
Energy container class definition.
Exception handler interface definition.
FITS binary table class definition.
FITS table double column class interface definition.
FITS table short integer column class interface definition.
FITS file class interface definition.
Integration class for set of functions interface definition.
Generic matrix class definition.
Sky 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.
Node array class interface definition.
INTEGRAL/SPI event bin class definition.
INTEGRAL/SPI event bin container class definition.
INTEGRAL/SPI observation class definition.
INTEGRAL/SPI instrument response function class definition.
Vector class interface definition.
Energy boundaries container class.
void read(const GFitsTable &table)
Read energy boundaries from FITS table.
void append(const GEnergy &emin, const GEnergy &emax)
Append energy interval.
void clear(void)
Clear energy boundaries.
bool is_empty(void) const
Signal if there are no energy boundaries.
void write(GFits &file, const std::string &extname=gammalib::extname_ebounds, const std::string &unit="keV") const
Write energy boundaries into FITS object.
Class that handles energies in a unit independent way.
double keV(void) const
Return energy in keV.
Abstract interface for the event classes.
void ebounds(const GEbounds &ebounds)
Set energy boundaries.
virtual int size(void) const =0
std::string path(void) const
Return access path.
std::string url(void) const
Return Uniform Resource Locator (URL)
void clear(void)
Clear file name.
bool has_card(const int &cardno) const
Check existence of header card.
const std::string & extname(void) const
Return extension name.
double real(const std::string &keyname) const
Return card value as double precision.
std::string string(const std::string &keyname) const
Return card value as string.
GFitsHeaderCard & card(const int &cardno)
Return header card.
int integer(const std::string &keyname) const
Return card value as integer.
Abstract FITS image base class.
virtual double pixel(const int &ix) const =0
Abstract interface for FITS table column.
virtual int integer(const int &row, const int &inx=0) const =0
virtual double real(const int &row, const int &inx=0) const =0
void unit(const std::string &unit)
Set column unit.
FITS table double column.
FITS table short integer column.
Abstract interface for FITS table.
GFitsTableCol * append(const GFitsTableCol &column)
Append column to the table.
const int & nrows(void) const
Return number of rows in table.
void saveto(const GFilename &filename, const bool &clobber=false)
Saves to specified FITS file.
bool contains(const int &extno) const
Check if HDU exists in FITS file.
GFitsHDU * append(const GFitsHDU &hdu)
Append HDU to FITS file.
GFitsImage * image(const int &extno)
Get pointer to image HDU.
void close(void)
Close FITS file.
GFitsTable * table(const int &extno)
Get pointer to table HDU.
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.
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.
virtual double eval(const double &theta, const double &posangle, const GEnergy &energy, const GTime &time, const bool &gradients=false) const =0
const GSkyDir & dir(void) const
Return position of elliptical spatial model.
std::string coordsys(void) const
Return coordinate system.
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
virtual double eval(const double &theta, const GEnergy &energy, const GTime &time, const bool &gradients=false) const =0
const GSkyDir & dir(void) const
Return position of radial spatial model.
const std::string & name(void) const
Return parameter name.
void set_value(const double &value) const
Set indices and weighting factors for interpolation.
const int & inx_right(void) const
Returns right node index.
const int & inx_left(void) const
Returns left node index.
void reserve(const int &num)
Reserves space for nodes in node array.
const double & wgt_right(void) const
Returns right node weight.
const double & wgt_left(void) const
Returns left node weight.
void clear(void)
Clear node array.
int size(void) const
Return number of nodes in node array.
void append(const double &node)
Append one node to array.
Abstract observation base class.
virtual GEvents * events(void)
Return events.
Class that handles photons.
const GSkyDir & dir(void) const
Return photon sky direction.
const GEnergy & energy(void) const
Return photon energy.
Abstract instrument response base class.
virtual double irf_diffuse(const GEvent &event, const GSource &source, const GObservation &obs) const
Return instrument response to diffuse source.
void init_members(void)
Initialise class members.
void free_members(void)
Delete class members.
virtual GResponse & operator=(const GResponse &rsp)
Assignment operator.
INTEGRAL/SPI event bin class.
const int & ipt(void) const
Return event bin pointing index.
const int & iebin(void) const
Return event bin energy index.
virtual const GSPIInstDir & dir(void) const
Return instrument direction.
const double & livetime(void) const
Return livetime of event bin.
INTEGRAL/SPI event bin container class.
const GSPIInstDir & dir(const int &ipt, const int &idet) const
Return instrument direction.
const GSkyDir & spi_z(const int &ipt) const
Return SPI Z direction.
double * m_livetime
Livetime array.
virtual int naxis(const int &axis) const
Return number of bins in axis.
GEnergy * m_energy
Energy array.
int m_num_pt
Number of pointings.
int * m_detid
Detector ID of event cube ADD!!!!
int m_num_ebin
Number of energy bins.
int m_num_det
Number of detectors.
const GSkyDir & spi_x(const int &ipt) const
Return SPI X direction (pointing direction)
void detid(const int &detid)
Set detector identifier.
INTEGRAL/SPI observation class.
INTEGRAL/SPI instrument response function class.
void irf_init(const GObservation &obs, GSPIResponseIrf *irf) const
Initialise structure for projection computation of response.
double m_wcs_xpix_max
Maximum X pixel index.
void set_detids(const GSPIEventCube *cube)
Set vector of detector identifiers used by the observation.
virtual GSPIResponse & operator=(const GSPIResponse &rsp)
Assignment operator.
void write(GFits &fits) const
Write SPI response into FITS object.
int irf_map(const int &idet, const int &ieng, const GSPIResponseIrf *irf) const
Return map index for detector and energy index.
void irf_skydir(const int &ipt, const int &inx, GSPIResponseIrf *irf) const
Set sky direction for pointing and IRF pixel index.
virtual GVector irf_radial(const GModelSky &model, const GObservation &obs, GMatrix *gradients=NULL) const
Return instrument response to radial source sky model.
virtual GVector irf_ptsrc(const GModelSky &model, const GObservation &obs, GMatrix *gradients=NULL) const
Return instrument response to point source sky model.
virtual GVector irf_elliptical(const GModelSky &model, const GObservation &obs, GMatrix *gradients=NULL) const
Return instrument response to elliptical source sky model.
double m_wcs_xbin
X value bin size (radians)
void save(const GFilename &filename, const bool &clobber=false) const
Save SPI response into file.
GSkyMap m_irfs
IRFs stored as sky map.
GNodeArray m_energies
Node array of IRF energies.
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.
double irf_weight(const double &beta, const double &emin, const double &emax) const
Compute weight of logarithmic energy bin.
double m_wcs_ymin
Minimum Y value (radians)
virtual std::string print(const GChatter &chatter=NORMAL) const
Print INTEGRAL/SPI response information.
double m_wcs_ybin
Y value bin size (radians)
void set_wcs(const GFitsImage *image)
Set IRF image limits.
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.
void read(const GFits &fits)
Read SPI response from FITS object.
GSkyMap compute_irf(const double &emin, const double &emax) const
Compute as sky map.
virtual double irf(const GEvent &event, const GPhoton &photon, const GObservation &obs) const
Return value of INTEGRAL/SPI instrument response for a photon.
GSkyMap load_irf(const GFilename &rspname) const
Load IRF as sky map.
std::vector< GSkyDir > m_spix
SPI pointing direction.
double m_dlogE
Logarithmic energy step for IRF band.
void write_detids(GFits &fits) const
Write detector identifiers into FITS object.
void init_members(void)
Initialise class members.
virtual ~GSPIResponse(void)
Destructor.
double azimuth(const int &ipt, const GSkyDir &dir) const
Return azimuth angle of sky direction for pointing in radians.
void copy_members(const GSPIResponse &rsp)
Copy class members.
std::vector< int > m_detids
Vector of detector IDs.
virtual GVector irf_diffuse(const GModelSky &model, const GObservation &obs, GMatrix *gradients=NULL) const
Return instrument response to diffuse source sky model.
void free_members(void)
Delete class members.
GFilename m_rspname
File name of response group.
void write_energies(GFits &fits) const
Write energies into FITS object.
void load(const GFilename &filename)
Load SPI response from file.
double m_wcs_ypix_max
Maximum Y pixel index.
double m_gamma
Power-law spectral index for IRF band.
void read_detids(const GFits &fits)
Read detector identifiers from FITS object.
void set_cache(const GSPIEventCube *cube)
Set computation cache.
int irf_detid(const int &detid) const
Convert detector identifier into IRF detector identifier.
double zenith(const int &ipt, const GSkyDir &dir) const
Return zenith angle of sky direction for pointing in radians.
double m_wcs_xmax
Maximum X value (radians)
double m_wcs_ymax
Maximum Y value (radians)
void irf_rot_matrix(const int &ipt, GSPIResponseIrf *irf) const
Set rotation matrix for pointing.
void irf_vector(const GSPIEventCube *cube, const double &xpix, const double &ypix, const int &ireg, const double *livetimes, GVector *irf) const
Fill vector of INTEGRAL/SPI instrument response for IRF pixel.
virtual GSPIResponse * clone(void) const
Clone instance.
double m_wcs_xmin
Minimum X value (radians)
double m_energy_keV
IRF line energy (optional)
GEbounds m_ebounds
Energy bounaries of IRF.
double m_max_zenith
Maximum zenith angle (radians)
void read_energies(const GFits &fits)
Read energies from FITS object.
GSPIResponse(void)
Void constructor.
virtual void clear(void)
Clear instance.
const GFilename & rspname(void) const
Get response group file name.
bool m_has_wcs
Has WCS information.
virtual GEbounds ebounds(const GEnergy &obsEnergy) const
Return true energy boundaries for a specific observed energy.
void set(const GSPIObservation &obs, const GEnergy &energy=GEnergy())
Set response for a specific observation.
std::vector< double > m_posang
Position angle of Y axis (CEL, radians)
void load_irfs(const int ®ion)
Load Instrument Response Functions.
void irf_diffuse_map(const GModelSpatialDiffuseMap *diffuse, const GObservation &obs, GVector *irfs, GMatrix *gradients=NULL) const
Return instrument response to diffuse map sky model.
double dec_deg(void) const
Returns Declination in degrees.
double ra_deg(void) const
Returns Right Ascension in degrees.
double dist(const GSkyDir &dir) const
Compute angular distance between sky directions in radians.
double posang(const GSkyDir &dir, const std::string &coordsys="CEL") const
Compute position angle between sky directions in radians.
double solidangle(const int &index) const
Returns solid angle of pixel.
const int & nmaps(void) const
Returns number of maps.
void clear(void)
Clear instance.
GSkyDir inx2dir(const int &index) const
Returns sky direction of pixel.
const int & nx(void) const
Returns number of pixels in x coordinate.
void read(const GFitsHDU &hdu)
Read skymap from FITS HDU.
const int & npix(void) const
Returns number of pixels.
const int & ny(void) const
Returns number of pixels in y coordinate.
GFitsHDU * write(GFits &file, const std::string &extname="") const
Write sky map into FITS file.
const std::vector< int > & shape(void) const
Returns shape of maps.
Class that handles gamma-ray sources.
Kernel for rho angle integration of elliptical models.
Kernel for rho angle integration of radial models.
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.
const std::string extname_ebounds
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
int spi_num_hdus(const GFits &fits, const std::string &extname)
Return number of HDU versions.
double get_current_clock(void)
Get current clock in seconds.
const GFitsTable * spi_hdu(const GFits &fits, const std::string &extname, const int &extver=1)
Return FITS table.
const std::string extname_energies
Defintion of SPI helper classes for vector response.