/***********************************************************************//** * @brief Read LAT source map from HDU. * * @param[in] hdu Image HDU. * * @exception GLATException::wcs_incompatible * Source map not compatible with sky map * * This method reads a LAT source map from a FITS image. The source map is * stored in a GSkyMap object and is given in units of counts/pixel/MeV. ***************************************************************************/ void GLATEventCube::read_srcmap(const GFitsImage& hdu) { // Allocate skymap GSkyMap* map = new GSkyMap; // Read skymap map->read(hdu); // Check that source map sky projection is consistent with counts // map sky projection if (*(m_map.projection()) != *(map->projection())) { throw GLATException::wcs_incompatible(G_READ_SRCMAP, hdu.extname()); } // Check that source map dimension is consistent with counts map // dimension if (m_map.nx() != map->nx() || m_map.ny() != map->ny()) { throw GLATException::wcs_incompatible(G_READ_SRCMAP, hdu.extname()); } // Check that source map has required number of energy bins if (m_map.nmaps()+1 != map->nmaps()) { throw GLATException::wcs_incompatible(G_READ_SRCMAP, hdu.extname()); } // Append source map to list of maps m_srcmap.push_back(map); m_srcmap_names.push_back(hdu.extname()); // Return return; }
/***********************************************************************//** * @brief Read COMPTEL response from FITS image. * * @param[in] image FITS image. * * Read the COMPTEL response from IAQ FITS file and convert the IAQ values * into a probability per steradian. ***************************************************************************/ void GCOMResponse::read(const GFitsImage& image) { // Store IAQ dimensions m_phigeo_bins = image.naxes(0); m_phibar_bins = image.naxes(1); // Store IAQ axes definitions m_phigeo_ref_value = image.real("CRVAL1"); m_phigeo_ref_pixel = image.real("CRPIX1"); m_phigeo_bin_size = image.real("CDELT1"); m_phibar_ref_value = image.real("CRVAL2"); m_phibar_ref_pixel = image.real("CRPIX2"); m_phibar_bin_size = image.real("CDELT2"); // Get axes minima (values of first bin) m_phigeo_min = m_phigeo_ref_value + (1.0-m_phigeo_ref_pixel) * m_phigeo_bin_size; m_phibar_min = m_phibar_ref_value + (1.0-m_phibar_ref_pixel) * m_phibar_bin_size; // Compute IAQ size. Continue only if size is positive int size = m_phigeo_bins * m_phibar_bins; if (size > 0) { // Allocate memory for IAQ m_iaq.assign(size, 0.0); // Copy over IAQ values for (int i = 0; i < size; ++i) { m_iaq[i] = image.pixel(i); } } // endif: size was positive // Convert IAQ matrix from probability per Phigeo bin into a // probability per steradian double omega0 = gammalib::fourpi * std::sin(0.5 * m_phigeo_bin_size * gammalib::deg2rad); for (int iphigeo = 0; iphigeo < m_phigeo_bins; ++iphigeo) { double phigeo = iphigeo * m_phigeo_bin_size + m_phigeo_min; double omega = omega0 * std::sin(phigeo * gammalib::deg2rad); for (int iphibar = 0; iphibar < m_phibar_bins; ++iphibar) { m_iaq[iphigeo+iphibar*m_phigeo_bins] /= omega; } } // Return return; }
/***********************************************************************//** * @brief Test binned observation handling for a specific dataset * * @param[in] datadir Directory of test data. * @param[in] irf Instrument response function. * * Verifies the ability to handle binned Fermi/LAT data. ***************************************************************************/ void TestGLATObservation::test_one_binned_obs(const std::string& datadir, const std::string& irf) { // Set filenames std::string lat_cntmap = datadir+"/cntmap.fits"; std::string lat_srcmap = datadir+"/srcmap.fits"; std::string lat_expmap = datadir+"/binned_expmap.fits"; std::string lat_ltcube = datadir+"/ltcube.fits"; std::string lat_bin_xml = datadir+"/obs_binned.xml"; std::string file1 = "test_lat_obs_binned.xml"; // Declare observations GObservations obs; GLATObservation run; // Determine number of bins and events in counts map GFits cntmap(lat_cntmap); GFitsImage* image = cntmap.image(0); double nevents = 0.0; int nsize = image->size(); for (int i = 0; i < nsize; ++i) { nevents += image->pixel(i); } cntmap.close(); // Try loading event list GLATEventCube cube(lat_cntmap); test_value(cube.number(), nevents, "Test number of events in cube."); // Load LAT binned observation from counts map test_try("Load LAT binned observation"); try { run.load_binned(lat_cntmap, "", ""); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Reload LAT binned observation from source map test_try("Reload LAT binned observation"); try { run.load_binned(lat_srcmap, "", ""); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Add observation (twice) to data test_try("Append observation twice"); try { run.id("0001"); obs.append(run); run.id("0002"); obs.append(run); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Loop over all events using iterator const GEvents* events = run.events(); int num = 0; int sum = 0; for (int i = 0; i < events->size(); ++i) { num++; sum += (int)((*events)[i]->counts()); } test_value(sum, nevents, 1.0e-20, "Test event iterator (counts)"); test_value(num, nsize, 1.0e-20, "Test event iterator (bins)"); // Test mean PSF test_try("Test mean PSF"); try { run.load_binned(lat_srcmap, lat_expmap, lat_ltcube); run.response(irf, lat_caldb); GSkyDir dir; GLATMeanPsf psf(dir, run); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test XML loading test_try("Test XML loading"); try { setenv("CALDB", lat_caldb.c_str(), 1); obs = GObservations(lat_bin_xml); obs.save(file1); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Exit test return; }