/***********************************************************************//** * @brief Test binned observation handling ***************************************************************************/ void TestGCTAObservation::test_binned_obs(void) { // Set filenames const std::string file1 = "test_cta_obs_binned.xml"; // Declare observations GObservations obs; GCTAObservation run; // Load binned CTA observation test_try("Load unbinned CTA observation"); try { run.load_binned(cta_cntmap); run.response(cta_irf,cta_caldb); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test XML loading test_try("Test XML loading"); try { obs = GObservations(cta_bin_xml); obs.save(file1); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Exit test return; }
/***********************************************************************//** * @brief Test unbinned optimizer ***************************************************************************/ void TestGCTAOptimize::test_unbinned_optimizer(void) { // Declare observations GObservations obs; GCTAObservation run; // Load unbinned CTA observation test_try("Load unbinned CTA observation"); try { run.load_unbinned(cta_events); run.response(cta_irf,cta_caldb); obs.append(run); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Load models from XML file obs.models(cta_model_xml); // Perform LM optimization double fit_results[] = {83.6331, 0, 22.0145, 0, 5.656246512e-16, 1.91458426e-17, -2.484100472, -0.02573396361, 300000, 0, 1, 0, 2.993705325, 0.03572658413, 6.490832107e-05, 1.749021094e-06, -1.833584022, -0.01512223495, 1000000, 0, 1, 0}; test_try("Perform LM optimization"); try { GOptimizerLM opt; opt.max_iter(100); obs.optimize(opt); test_try_success(); for (int i = 0, j = 0; i < obs.models().size(); ++i) { GModel* model = obs.models()[i]; for (int k = 0; k < model->size(); ++k) { GModelPar& par = (*model)[k]; std::string msg = "Verify optimization result for " + par.print(); test_value(par.real_value(), fit_results[j++], 5.0e-5, msg); test_value(par.real_error(), fit_results[j++], 5.0e-5, msg); } } } catch (std::exception &e) { test_try_failure(e); } // Exit test return; }
/*************************************************************************** * @brief GSkyRegionCircle_construct ***************************************************************************/ void TestGSky::test_GSkyRegionCircle_construct(void) { // Define region for comparison GSkyDir refdir_radeczerozero = GSkyDir(); refdir_radeczerozero.radec_deg(0,0); double refradius = 10.; // Test constructing: test_try("Test constructor"); try { GSkyRegionCircle circle(refdir_radeczerozero,refradius); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test constructing with radius 0 test_try("Test constructor2"); try { GSkyRegionCircle circle(refdir_radeczerozero,-1); test_try_failure(); } catch (GException::invalid_argument &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test constructing with radius 0 test_try("Test radius assignment after"); try { GSkyRegionCircle circle(refdir_radeczerozero,refradius); circle.radius(-1.0); test_try_failure(); } catch (GException::invalid_argument &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Check radius assignment GSkyRegionCircle refregion(refdir_radeczerozero,refradius); double refradius_check = refregion.radius(); test_value(refradius,refradius_check,1.0e-10, "Test radius assignment"); // Check solid angle assignment double solidangle_check = refregion.solidangle(); double solidangle = 2*gammalib::pi*(1- std::cos(refradius /180 * gammalib::pi)); test_value(solidangle_check,solidangle,1.0e-10, "Test solid angle assignment"); //exit test return; }
/***********************************************************************//** * @brief Test binned optimizer ***************************************************************************/ void TestGCTAOptimize::test_binned_optimizer(void) { // Declare observations GObservations obs; GCTAObservation run; // Load binned CTA observation test_try("Load binned CTA observation"); try { run.load_binned(cta_cntmap); run.response(cta_irf,cta_caldb); obs.append(run); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Load models from XML file obs.models(cta_model_xml); // Perform LM optimization double fit_results[] = {83.6331, 0, 22.0145, 0, 5.616410411e-16, 1.904730785e-17, -2.481781246, -0.02580905077, 300000, 0, 1, 0, 2.933677595, 0.06639644824, 6.550723074e-05, 1.945714239e-06, -1.833781187, -0.0161464076, 1000000, 0, 1, 0}; test_try("Perform LM optimization"); try { GOptimizerLM opt; opt.max_iter(100); obs.optimize(opt); test_try_success(); for (int i = 0, j = 0; i < obs.models().size(); ++i) { GModel* model = obs.models()[i]; for (int k = 0; k < model->size(); ++k) { GModelPar& par = (*model)[k]; std::string msg = "Verify optimization result for " + par.print(); test_value(par.real_value(), fit_results[j++], 5.0e-5, msg); test_value(par.real_error(), fit_results[j++], 5.0e-5, msg); } } } catch (std::exception &e) { test_try_failure(e); } // Exit test return; }
/*************************************************************************** * @brief Test GSkyRegions input and output ***************************************************************************/ void TestGSky::test_GSkyRegions_io(void) { // Set filenames const std::string filename = "data/test_circle_region.reg"; // Allocate regions GSkyRegions regions; // Test regions loading test_try("Test regions loading"); try { regions.load(filename); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Check if region was loaded correctly GSkyRegionCircle* circle = dynamic_cast<GSkyRegionCircle*>(regions[0]); test_assert(circle->type() == "Circle", "Region is not a circle"); test_value(circle->radius(), 10.0, 1.0e-10); test_value(circle->ra(), 0.1, 1.0e-10); test_value(circle->dec(), -35.6, 1.0e-10); // Test regions saving test_try("Test regions saving"); try { regions.save("region.reg"); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test regions reloading test_try("Test regions reloading"); try { regions.load("region.reg"); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Check if region was loaded correctly circle = dynamic_cast<GSkyRegionCircle*>(regions[0]); test_assert(circle->type() == "Circle", "Region is not a circle"); test_value(circle->radius(), 10.0, 1.0e-10); test_value(circle->ra(), 0.1, 1.0e-10); test_value(circle->dec(), -35.6, 1.0e-10); // Exit test return; }
/***********************************************************************//** * @brief Test binned optimizer * * @param[in] datadir Directory of test data. * @param[in] irf Instrument response function. * @param[in] fit_results Expected fit result. * * Verifies the ability optimize binned Fermi/LAT data. ***************************************************************************/ void TestGLATOptimize::test_one_binned_optimizer(const std::string& datadir, const std::string& irf, const double* fit_results) { // Set filenames 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_model_xml = datadir+"/source_model.xml"; // Setup GObservations for optimizing GObservations obs; GLATObservation run; test_try("Setup for optimization"); try { run.load_binned(lat_srcmap, lat_expmap, lat_ltcube); run.response(irf, lat_caldb); obs.append(run); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Load models from XML file obs.models(lat_model_xml); // Setup LM optimizer test_try("Perform LM optimization"); try { GOptimizerLM opt; opt.max_iter(1000); obs.optimize(opt); obs.errors(opt); test_try_success(); for (int i = 0, j = 0; i < obs.models().size(); ++i) { const GModel* model = obs.models()[i]; for (int k = 0; k < model->size(); ++k) { GModelPar par = (*model)[k]; std::string msg = "Verify optimization result for " + par.print(); test_value(par.value(), fit_results[j++], 5.0e-5, msg); test_value(par.error(), fit_results[j++], 5.0e-5, msg); } } } catch (std::exception &e) { test_try_failure(e); } // Exit test return; }
/*************************************************************************** * @brief GSkymap_wcs_construct ***************************************************************************/ void TestGSky::test_GSkymap_wcs_construct(void) { // Set precision double eps = 1.0e-5; // Test void constructor test_try("Test void constructor"); try { GSkymap map; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test non-Healpix constructors test_try("Test non-Healpix constructors"); try { GSkymap map1("CAR", "GAL", 0.0, 0.0, 1.0, 1.0, 100, 100); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test CAR projection test_try("Test CAR projection"); try { GSkymap map1("CAR", "GAL", 138.817, 37.293, 0.521, 0.931, 100, 100); GSkyDir dir; for (int l = -180; l < 180; ++l) { for (int b = -90; b < 90; ++b) { dir.lb_deg(double(l),double(b)); GSkyPixel pixel = map1.dir2pix(dir); GSkyDir dir_back = map1.pix2dir(pixel); double dist = dir.dist_deg(dir_back); if (dist > eps) { throw exception_failure("Sky direction differs: dir="+dir.print()+" pixel="+pixel.print()+" dir_back"+ dir_back.print()+" dist="+gammalib::str(dist)+" deg"); } } } test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Exit test return; }
/***********************************************************************//** * @brief Test value assignment ***************************************************************************/ void TestGMatrixSymmetric::assign_values(void) { // Setup 3x3 matrix GMatrixSymmetric test(3,3); // Assignment individual values for (int i = 0; i < 3; ++i) { for (int k = 0; k < 3; ++k) { double value = i*2.0 + k*2.0; test(i,k) = value; } } // Check assignment of individual values for (int i = 0; i < 3; ++i) { for (int k = 0; k < 3; ++k) { double value = i*2.0 + k*2.0; test_value(test(i,k), value, 1.0e-10, "Test matrix element assignment"); } } // Check value assignment const double ref = 37.89; test = ref; for (int i = 0; i < 3; ++i) { for (int k = 0; k < 3; ++k) { test_value(test(i,k), ref, 1.0e-10, "Test matrix element assignment"); } } // Verify range checking #ifdef G_RANGE_CHECK test_try("Verify range checking"); try { test.at(3,3) = 1.0; test_try_failure("Expected GException::out_of_range exception."); } catch (GException::out_of_range &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } #endif // Return return; }
/***********************************************************************//** * @brief Notice when a try block failed * * @param[in] e Exception. * * @exception GException::test_nested_try_error * Test case index is out of range. * * @see test_try_sucess() * @see test_try(const std::string& name) * @see test_try_failure(const std::string& message, const std::string& type) * * Call this method in a catch block. * * Example: * test_try("Test a try block"); * try { * ... //someting to test * test_try_success(); * } * catch(exception& e) { * test_try_failure(e); * } ***************************************************************************/ void GTestSuite::test_try_failure(const std::exception& e) { // Extract message of exception and class name test_try_failure(e.what(), typeid(e).name()); // Return return; }
/***********************************************************************//** * @brief Test matrix allocation ***************************************************************************/ void TestGSymMatrix::alloc_matrix(void) { // Allocate zero matrix. The allocation should fail. test_try("Allocate zero matrix"); try { GSymMatrix test(0,0); test_try_failure("Expected GException::empty exception."); } catch (GException::empty &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Return return; }
/***********************************************************************//** * @brief Test one specific response * * @param[in] irf Instrument response function. * * Verifies the ability to load and to save Fermi/LAT response functions. ***************************************************************************/ void TestGLATResponse::test_one_response(const std::string& irf) { // Set FITS filename std::string fitsfile = "test_rsp_" + irf + ".fits"; // Remove FITS file std::string cmd = "rm -rf " + fitsfile; system(cmd.c_str()); // Try loading the response test_try("Test loading the response"); try { GLATResponse rsp; rsp.caldb(lat_caldb); std::cout << "."; rsp.load(irf+"::front"); std::cout << "."; rsp.load(irf+"::back"); std::cout << "."; rsp.load(irf); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Try saving the response test_try("Test saving the response"); try { GLATResponse rsp; rsp.caldb(lat_caldb); rsp.load(irf); rsp.save(fitsfile); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Return return; }
/***********************************************************************//** * @brief Test XML loading/saving **************************************************************************/ void TestGXml::test_GXml_load(void) { // Test loading test_try("Test loading"); try { GXml xml; xml.load(m_xml_file); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test saving test_try("Test saving"); try { GXml xml; xml.load(m_xml_file); xml.save("test.xml"); xml.load("test.xml"); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test loading of saved XML document test_try("Test loading of saved XML document"); try { GXml xml; xml.load("test.xml"); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Return return; }
/***********************************************************************//** * @brief Test GPhotons ***************************************************************************/ void TestGObservation::test_photons(void) { // Test void constructor test_try("Void constructor"); try { GPhotons photons; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Manipulate GPhotons starting from an empty object GPhotons photons; test_value(photons.size(), 0, "GPhotons should have zero size."); test_assert(photons.is_empty(), "GPhotons should be empty."); // Add one photon photons.append(GPhoton()); test_value(photons.size(), 1, "GPhotons should have 1 photon."); test_assert(!photons.is_empty(), "GPhotons should not be empty."); // Remove photon photons.remove(0); test_value(photons.size(), 0, "GPhotons should have zero size."); test_assert(photons.is_empty(), "GPhotons should be empty."); // Append two photons photons.append(GPhoton()); photons.append(GPhoton()); test_value(photons.size(), 2, "GPhotons should have 2 photons."); test_assert(!photons.is_empty(), "GPhotons should not be empty."); // Clear object photons.clear(); test_value(photons.size(), 0, "GPhotons should have zero size."); test_assert(photons.is_empty(), "GPhotons should be empty."); // Insert two photons photons.insert(0, GPhoton()); photons.insert(0, GPhoton()); test_value(photons.size(), 2, "GPhotons should have 2 photons."); test_assert(!photons.is_empty(), "GPhotons should not be empty."); // Extend photons photons.extend(photons); test_value(photons.size(), 4, "GPhotons should have 4 photons."); test_assert(!photons.is_empty(), "GPhotons should not be empty."); // Return return; }
/***********************************************************************//** * @brief Test GTimes ***************************************************************************/ void TestGObservation::test_times(void) { // Test void constructor test_try("Void constructor"); try { GTimes times; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Manipulate GTimes starting from an empty object GTimes times; test_value(times.size(), 0, "GTimes should have zero size."); test_assert(times.is_empty(), "GTimes should be empty."); // Add a time times.append(GTime()); test_value(times.size(), 1, "GTimes should have 1 time."); test_assert(!times.is_empty(), "GTimes should not be empty."); // Remove time times.remove(0); test_value(times.size(), 0, "GTimes should have zero size."); test_assert(times.is_empty(), "GTimes should be empty."); // Append two times times.append(GTime()); times.append(GTime()); test_value(times.size(), 2, "GTimes should have 2 times."); test_assert(!times.is_empty(), "GTimes should not be empty."); // Clear object times.clear(); test_value(times.size(), 0, "GTimes should have zero size."); test_assert(times.is_empty(), "GTimes should be empty."); // Insert two times times.insert(0, GTime()); times.insert(0, GTime()); test_value(times.size(), 2, "GTimes should have 2 times."); test_assert(!times.is_empty(), "GTimes should not be empty."); // Extend times times.extend(times); test_value(times.size(), 4, "GTimes should have 4 times."); test_assert(!times.is_empty(), "GTimes should not be empty."); // Return return; }
/***********************************************************************//** * @brief Test CTA response handling ***************************************************************************/ void TestGCTAResponse::test_response(void) { // Test CTA response loading test_try("Test CTA response loading"); try { // Load response GCTAResponse rsp; rsp.caldb(cta_caldb); rsp.load(cta_irf); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Return return; }
/***********************************************************************//** * @brief Test GGti ***************************************************************************/ void TestGObservation::test_gti(void) { // Test void constructor test_try("Void constructor"); try { GGti gti; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Manipulate GTIs starting from an empty object GGti gti; test_value(gti.size(), 0, "GGti should have zero size."); test_assert(gti.is_empty(), "GGti should be empty."); test_value(gti.tstart().secs(), 0.0, 1.0e-10, "Start time should be 0."); test_value(gti.tstop().secs(), 0.0, 1.0e-10, "Stop time should be 0."); // Add empty interval gti.append(GTime(1.0), GTime(1.0)); test_value(gti.size(), 0, "GGti should have zero size."); test_assert(gti.is_empty(), "GGti should be empty."); test_value(gti.tstart().secs(), 0.0, 1.0e-10, "Start time should be 0."); test_value(gti.tstop().secs(), 0.0, 1.0e-10, "Stop time should be 0."); // Add one interval gti.append(GTime(1.0), GTime(10.0)); test_value(gti.size(), 1, "GGti should have 1 interval."); test_assert(!gti.is_empty(), "GGti should not be empty."); test_value(gti.tstart().secs(), 1.0, 1.0e-10, "Start time should be 1."); test_value(gti.tstop().secs(), 10.0, 1.0e-10, "Stop time should be 10."); // Remove interval gti.remove(0); test_value(gti.size(), 0, "GGti should have zero size."); test_assert(gti.is_empty(), "GGti should be empty."); test_value(gti.tstart().secs(), 0.0, 1.0e-10, "Start time should be 0."); test_value(gti.tstop().secs(), 0.0, 1.0e-10, "Stop time should be 0."); // Append two overlapping intervals gti.append(GTime(1.0), GTime(100.0)); gti.append(GTime(10.0), GTime(1000.0)); test_value(gti.size(), 2, "GGti should have 2 intervals."); test_assert(!gti.is_empty(), "GGti should not be empty."); test_value(gti.tstart().secs(), 1.0, 1.0e-10, "Start time should be 1."); test_value(gti.tstop().secs(), 1000.0, 1.0e-10, "Stop time should be 1000."); // Clear object gti.clear(); test_value(gti.size(), 0, "GGti should have zero size."); test_assert(gti.is_empty(), "GGti should be empty."); test_value(gti.tstart().secs(), 0.0, 1.0e-10, "Start time should be 0."); test_value(gti.tstop().secs(), 0.0, 1.0e-10, "Stop time should be 0."); // Append two overlapping intervals in inverse order gti.clear(); gti.append(GTime(10.0), GTime(1000.0)); gti.append(GTime(1.0), GTime(100.0)); test_value(gti.size(), 2, "GGti should have 2 intervals."); test_assert(!gti.is_empty(), "GGti should not be empty."); test_value(gti.tstart().secs(), 1.0, 1.0e-10, "Start time should be 1."); test_value(gti.tstop().secs(), 1000.0, 1.0e-10, "Stop time should be 1000."); // Insert two overlapping intervals gti.clear(); gti.insert(GTime(1.0), GTime(100.0)); gti.insert(GTime(10.0), GTime(1000.0)); test_value(gti.size(), 2, "GGti should have 2 intervals."); test_assert(!gti.is_empty(), "GGti should not be empty."); test_value(gti.tstart().secs(), 1.0, 1.0e-10, "Start time should be 1."); test_value(gti.tstop().secs(), 1000.0, 1.0e-10, "Stop time should be 1000."); // Insert two overlapping intervals in inverse order gti.clear(); gti.insert(GTime(10.0), GTime(1000.0)); gti.insert(GTime(1.0), GTime(100.0)); test_value(gti.size(), 2, "GGti should have 2 intervals."); test_assert(!gti.is_empty(), "GGti should not be empty."); test_value(gti.tstart().secs(), 1.0, 1.0e-10, "Start time should be 1."); test_value(gti.tstop().secs(), 1000.0, 1.0e-10, "Stop time should be 1000."); // Merge two overlapping intervals gti.clear(); gti.merge(GTime(1.0), GTime(100.0)); gti.merge(GTime(10.0), GTime(1000.0)); test_value(gti.size(), 1, "GGti should have 1 interval."); test_assert(!gti.is_empty(), "GGti should not be empty."); test_value(gti.tstart().secs(), 1.0, 1.0e-10, "Start time should be 1."); test_value(gti.tstop().secs(), 1000.0, 1.0e-10, "Stop time should be 1000."); // Merge two overlapping intervals in inverse order gti.clear(); gti.merge(GTime(10.0), GTime(1000.0)); gti.merge(GTime(1.0), GTime(100.0)); test_value(gti.size(), 1, "GGti should have 1 interval."); test_assert(!gti.is_empty(), "GGti should not be empty."); test_value(gti.tstart().secs(), 1.0, 1.0e-10, "Start time should be 1."); test_value(gti.tstop().secs(), 1000.0, 1.0e-10, "Stop time should be 1000."); // Check extension gti.clear(); gti.append(GTime(1.0), GTime(10.0)); gti.append(GTime(10.0), GTime(100.0)); GGti ext; ext.append(GTime(100.0), GTime(1000.0)); gti.extend(ext); test_value(gti.size(), 3, "GGti should have 3 intervals."); test_assert(!gti.is_empty(), "GGti should not be empty."); test_value(gti.tstart(0).secs(), 1.0, 1.0e-10, "Bin 0 start time should be 1."); test_value(gti.tstart(1).secs(), 10.0, 1.0e-10, "Bin 1 start time should be 10."); test_value(gti.tstart(2).secs(), 100.0, 1.0e-10, "Bin 2 start time should be 100."); test_value(gti.tstop(0).secs(), 10.0, 1.0e-10, "Bin 0 stop time should be 10."); test_value(gti.tstop(1).secs(), 100.0, 1.0e-10, "Bin 1 stop time should be 100."); test_value(gti.tstop(2).secs(), 1000.0, 1.0e-10, "Bin 2 stop time should be 1000."); test_value(gti.tstart().secs(), 1.0, 1.0e-10, "Start time should be 1."); test_value(gti.tstop().secs(), 1000.0, 1.0e-10, "Stop time should be 1000."); // Return return; }
/***********************************************************************//** * @brief Test Cholesky decomposition ***************************************************************************/ void TestGMatrixSparse::matrix_cholesky(void) { // Setup matrix for Cholesky decomposition GMatrixSparse chol_test(5,5); chol_test(0,0) = 1.0; chol_test(0,1) = 0.2; chol_test(0,2) = 0.2; chol_test(0,3) = 0.2; chol_test(0,4) = 0.2; chol_test(1,0) = 0.2; chol_test(2,0) = 0.2; chol_test(3,0) = 0.2; chol_test(4,0) = 0.2; chol_test(1,1) = 1.0; chol_test(2,2) = 1.0; chol_test(3,3) = 1.0; chol_test(4,4) = 1.0; // Try to solve now (should not work) test_try("Try Cholesky solver without factorisation"); try { GVector vector(5); vector = chol_test.cholesky_solver(vector); test_try_failure("Expected GException::matrix_not_factorised exception."); } catch (GException::matrix_not_factorised &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Perform Cholesky decomposition GMatrixSparse cd = chol_test.cholesky_decompose(); // Test Cholesky solver (first test) GVector e0(5); GVector a0(5); e0[0] = 1.0; a0[0] = 1.0; a0[1] = 0.2; a0[2] = 0.2; a0[3] = 0.2; a0[4] = 0.2; GVector s0 = cd.cholesky_solver(a0); double res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 1"); // Test Cholesky solver (second test) e0[0] = 0.0; e0[1] = 1.0; a0[0] = 0.2; a0[1] = 1.0; a0[2] = 0.0; a0[3] = 0.0; a0[4] = 0.0; s0 = cd.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 2"); // Test Cholesky solver (third test) e0[1] = 0.0; e0[2] = 1.0; a0[1] = 0.0; a0[2] = 1.0; s0 = cd.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 3"); // Test Cholesky solver (forth test) e0[2] = 0.0; e0[3] = 1.0; a0[2] = 0.0; a0[3] = 1.0; s0 = cd.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 4"); // Test Cholesky solver (fifth test) e0[3] = 0.0; e0[4] = 1.0; a0[3] = 0.0; a0[4] = 1.0; s0 = cd.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 5"); // Setup matrix for Cholesky decomposition with zero row/col GMatrixSparse chol_test_zero(6,6); chol_test_zero(0,0) = 1.0; chol_test_zero(0,1) = 0.2; chol_test_zero(0,2) = 0.2; chol_test_zero(0,4) = 0.2; chol_test_zero(0,5) = 0.2; chol_test_zero(1,0) = 0.2; chol_test_zero(2,0) = 0.2; chol_test_zero(4,0) = 0.2; chol_test_zero(5,0) = 0.2; chol_test_zero(1,1) = 1.0; chol_test_zero(2,2) = 1.0; chol_test_zero(4,4) = 1.0; chol_test_zero(5,5) = 1.0; // Test compressed Cholesky decomposition GMatrixSparse cd_zero = chol_test_zero.cholesky_decompose(); // Test compressed Cholesky solver (first test) e0 = GVector(6); a0 = GVector(6); e0[0] = 1.0; a0[0] = 1.0; a0[1] = 0.2; a0[2] = 0.2; a0[4] = 0.2; a0[5] = 0.2; s0 = cd_zero.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 1"); // Test compressed Cholesky solver (second test) e0[0] = 0.0; e0[1] = 1.0; a0[0] = 0.2; a0[1] = 1.0; a0[2] = 0.0; a0[4] = 0.0; a0[5] = 0.0; s0 = cd_zero.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 2"); // Test compressed Cholesky solver (third test) e0[1] = 0.0; e0[2] = 1.0; a0[1] = 0.0; a0[2] = 1.0; s0 = cd_zero.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 3"); // Test compressed Cholesky solver (forth test) e0[2] = 0.0; e0[4] = 1.0; a0[2] = 0.0; a0[4] = 1.0; s0 = cd_zero.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 4"); // Test compressed Cholesky solver (fifth test) e0[4] = 0.0; e0[5] = 1.0; a0[4] = 0.0; a0[5] = 1.0; s0 = cd_zero.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 5"); // Setup matrix for Cholesky decomposition with zero row/col (unsymmetric case) GMatrixSparse chol_test_zero2(6,5); chol_test_zero2(0,0) = 1.0; chol_test_zero2(0,1) = 0.2; chol_test_zero2(0,2) = 0.2; chol_test_zero2(0,3) = 0.2; chol_test_zero2(0,4) = 0.2; chol_test_zero2(1,0) = 0.2; chol_test_zero2(2,0) = 0.2; chol_test_zero2(4,0) = 0.2; chol_test_zero2(5,0) = 0.2; chol_test_zero2(1,1) = 1.0; chol_test_zero2(2,2) = 1.0; chol_test_zero2(4,3) = 1.0; chol_test_zero2(5,4) = 1.0; // Test compressed Cholesky decomposition (unsymmetric case) GMatrixSparse cd_zero2 = chol_test_zero2.cholesky_decompose(); // Test compressed Cholesky solver (unsymmetric case) e0 = GVector(5); a0 = GVector(6); e0[0] = 1.0; a0[0] = 1.0; a0[1] = 0.2; a0[2] = 0.2; a0[4] = 0.2; a0[5] = 0.2; s0 = cd_zero2.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test unsymmetric compressed cholesky_solver() method - 1"); // Test compressed Cholesky solver (unsymmetric case) e0[0] = 0.0; e0[1] = 1.0; a0[0] = 0.2; a0[1] = 1.0; a0[2] = 0.0; a0[4] = 0.0; a0[5] = 0.0; s0 = cd_zero2.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test unsymmetric compressed cholesky_solver() method - 2"); // Test compressed Cholesky solver (unsymmetric case) e0[1] = 0.0; e0[2] = 1.0; a0[1] = 0.0; a0[2] = 1.0; s0 = cd_zero2.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test unsymmetric compressed cholesky_solver() method - 3"); // Test compressed Cholesky solver (unsymmetric case) e0[2] = 0.0; e0[3] = 1.0; a0[2] = 0.0; a0[4] = 1.0; s0 = cd_zero2.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test unsymmetric compressed cholesky_solver() method - 4"); // Test compressed Cholesky solver (unsymmetric case) e0[3] = 0.0; e0[4] = 1.0; a0[4] = 0.0; a0[5] = 1.0; s0 = cd_zero2.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test unsymmetric compressed cholesky_solver() method - 5"); // Test Cholesky inverter (inplace) GMatrixSparse unit(5,5); unit(0,0) = 1.0; unit(1,1) = 1.0; unit(2,2) = 1.0; unit(3,3) = 1.0; unit(4,4) = 1.0; GMatrixSparse chol_test_inv = chol_test.cholesky_invert(); GMatrixSparse ci_product = chol_test * chol_test_inv; GMatrixSparse ci_residuals = ci_product - unit; res = (ci_residuals.abs()).max(); test_value(res, 0.0, 1.0e-15, "Test Cholesky inverter"); // Test Cholesky inverter /* chol_test_inv = chol_test.cholesky_invert(); ci_product = chol_test * chol_test_inv; ci_residuals = ci_product - unit; res = (ci_residuals.abs()).max(); test_value(res, 0.0, 1.0e-15, "Test Cholesky inverter"); */ // Test Cholesky inverter for compressed matrix unit = GMatrixSparse(6,6); unit(0,0) = 1.0; unit(1,1) = 1.0; unit(2,2) = 1.0; unit(4,4) = 1.0; unit(5,5) = 1.0; GMatrixSparse chol_test_zero_inv = chol_test_zero.cholesky_invert(); GMatrixSparse ciz_product = chol_test_zero * chol_test_zero_inv; GMatrixSparse ciz_residuals = ciz_product - unit; res = (ciz_residuals.abs()).max(); test_value(res, 0.0, 1.0e-15, "Test compressed matrix Cholesky inverter"); // Return return; }
/***********************************************************************//** * @brief Test matrix arithmetics * * Tests matrix arithmetics. ***************************************************************************/ void TestGMatrixSparse::matrix_arithmetics(void) { // -GMatrixSparse GMatrixSparse test = -m_test; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, -1.0, 0.0), "Test -GMatrixSparse", "Unexpected result matrix:\n"+test.print()); // GMatrixSparse += GMatrixSparse test = m_test; test += m_test; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 2.0, 0.0), "Test GMatrixSparse += GMatrixSparse", "Unexpected result matrix:\n"+test.print()); // GMatrixSparse -= GMatrixSparse test = m_test; test -= m_test; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 0.0, 0.0), "Test GMatrixSparse -= GMatrixSparse", "Unexpected result matrix:\n"+test.print()); // GMatrixSparse *= 3.0 test = m_test; test *= 3.0; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 3.0, 0.0), "Test GMatrixSparse *= 3.0", "Unexpected result matrix:\n"+test.print()); // GMatrixSparse /= 3.0 test = m_test; test /= 3.0; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 1.0/3.0, 0.0), "Test GMatrixSparse /= 3.0", "Unexpected result matrix:\n"+test.print()); // GMatrixSparse + GMatrixSparse test = m_test + m_test; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 2.0, 0.0), "Test GMatrixSparse + GMatrixSparse", "Unexpected result matrix:\n"+test.print()); // GMatrixSparse - GMatrixSparse test = m_test - m_test; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 0.0, 0.0), "Test GMatrixSparse - GMatrixSparse", "Unexpected result matrix:\n"+test.print()); // GMatrixSparse * 3.0 test = m_test * 3.0; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 3.0, 0.0), "Test GMatrixSparse * 3.0", "Unexpected result matrix:\n"+test.print()); // 3.0 * GMatrixSparse test = 3.0 * m_test; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 3.0, 0.0), "Test 3.0 * GMatrixSparse", "Unexpected result matrix:\n"+test.print()); // GMatrixSparse / 3.0 test = m_test / 3.0; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 1.0/3.0, 0.0), "Test GMatrixSparse / 3.0", "Unexpected result matrix:\n"+test.print()); // Test invalid matrix addition test_try("Test invalid matrix addition"); try { test = m_test; test += m_bigger; test_try_failure("Expected GException::matrix_mismatch exception."); } catch (GException::matrix_mismatch &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Return return; }
/***********************************************************************//** * @brief Test matrix operations * * Tests matrix*vector and matrix*matrix multiplication operations. ***************************************************************************/ void TestGMatrixSparse::matrix_operations(void) { // Perform vector multiplication GVector test1 = m_test * v_test; // Check result GVector ref1(g_rows); for (int i = 0; i < g_elements; ++i) { ref1[g_row[i]] += g_matrix[i] * v_test[g_col[i]]; } bool result = true; for (int i = 0; i < g_rows; ++i) { if (ref1[i] != test1[i]) { result = false; break; } } // Test if original matrix and result vector are correct test_assert(check_matrix(m_test), "Test source matrix"); test_assert(result, "Test matrix*vector multiplication", "Found:\n"+test1.print()+"\nExpected:\n"+ref1.print()); // Test incompatible vector multiplication test_try("Test incompatible matrix*vector multiplication"); try { GVector test2 = m_bigger * v_test; test_try_failure("Expected GException::matrix_vector_mismatch exception."); } catch (GException::matrix_vector_mismatch &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test matrix multiplication GMatrixSparse test3 = m_test * m_test.transpose(); // Check if the result matrix is as expected GMatrixSparse ref3(g_rows, g_rows); for (int row = 0; row < g_rows; ++row) { for (int col = 0; col < g_rows; ++col) { double value = 0.0; for (int i = 0; i < g_cols; ++i) { double ref_value_1 = 0.0; double ref_value_2 = 0.0; for (int k = 0; k < g_elements; ++k) { if (g_row[k] == row && g_col[k] == i) { ref_value_1 = g_matrix[k]; break; } } for (int k = 0; k < g_elements; ++k) { if (g_row[k] == col && g_col[k] == i) { ref_value_2 = g_matrix[k]; break; } } value += ref_value_1 * ref_value_2; } ref3(row,col) = value; if (test3(row,col) != value) { result = false; break; } } } // Test if original matrix and result matrix are correct test_assert(check_matrix(m_test), "Test source matrix"); test_assert(result, "Test matrix multiplication", "Found:\n"+test3.print()+"\nExpected:\n"+ref3.print()); test_value(test3.rows(), g_rows, "Test number of rows of result matrix"); test_value(test3.columns(), g_rows, "Test number of columns of result matrix"); // Test incompatible matrix multiplication test_try("Test incompatible matrix multiplication"); try { GMatrixSparse test4 = m_bigger * m_test; test_try_failure("Expected GException::matrix_mismatch exception."); } catch (GException::matrix_mismatch &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test another incompatible matrix multiplication test_try("Test incompatible matrix multiplication"); try { GMatrixSparse test5 = m_bigger * m_test; test_try_failure("Expected GException::matrix_mismatch exception."); } catch (GException::matrix_mismatch &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Return return; }
/***********************************************************************//** * @brief Test unbinned observation handling for a specific dataset * * @param[in] datadir Directory of test data. * * Verifies the ability to handle unbinned Fermi/LAT data. ***************************************************************************/ void TestGLATObservation::test_one_unbinned_obs(const std::string& datadir) { // Set filenames std::string lat_ft1 = datadir+"/ft1.fits"; std::string lat_ft2 = datadir+"/ft2.fits"; std::string lat_unbin_xml = datadir+"/obs_unbinned.xml"; std::string file1 = "test_lat_obs_unbinned.xml"; // Declare observations GObservations obs; GLATObservation run; // Determine number of events in FT1 file GFits ft1(lat_ft1); int nevents = ft1.table("EVENTS")->nrows(); ft1.close(); // Try loading event list GLATEventList list(lat_ft1); test_value(list.number(), nevents, "Test number of events in list."); // Load unbinned LAT observation test_try("Load unbinned LAT observation"); try { run.load_unbinned(lat_ft1, lat_ft2, ""); 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 const GEvents *ptr = run.events(); int num = 0; for (int i = 0; i < ptr->size(); ++i) { num++; } test_value(num, nevents, 1.0e-20, "Test event iterator"); // Test XML loading test_try("Test XML loading"); try { setenv("CALDB", lat_caldb.c_str(), 1); obs = GObservations(lat_unbin_xml); obs.save(file1); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Exit test return; }
/***********************************************************************//** * @brief Test unbinned observation handling ***************************************************************************/ void TestGCTAObservation::test_unbinned_obs(void) { // Set filenames const std::string file1 = "test_cta_obs_unbinned.xml"; // Declare observations GObservations obs; GCTAObservation run; // Load unbinned CTA observation test_try("Load unbinned CTA observation"); try { run.load_unbinned(cta_events); run.response(cta_irf,cta_caldb); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Add observation (twice) to data test_try("Load unbinned CTA observation"); try { obs.append(run); obs.append(run); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Loop over all events using iterators int num = 0; for (GObservations::iterator event = obs.begin(); event != obs.end(); ++event) { num++; } test_value(num, 8794, 1.0e-20, "Test observation iterator"); // Loop over all events using iterator num = 0; GCTAEventList *ptr = static_cast<GCTAEventList*>(const_cast<GEvents*>(run.events())); for (GCTAEventList::iterator event = ptr->begin(); event != ptr->end(); ++event) { num++; } test_value(num, 4397, 1.0e-20, "Test event iterator"); // Test XML loading test_try("Test XML loading"); try { obs = GObservations(cta_unbin_xml); obs.save(file1); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Exit test return; }
/***********************************************************************//** * @brief Test matrix arithmetics * * Tests matrix arithmetics. ***************************************************************************/ void TestGSymMatrix::matrix_arithmetics(void) { // -GSymMatrix GSymMatrix test = -m_test; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, -1.0, 0.0), "Test -GSymMatrix", test.print()); // GSymMatrix += GSymMatrix test = m_test; test += m_test; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 2.0, 0.0), "Test GSymMatrix += GSymMatrix", test.print()); // GSymMatrix -= GSymMatrix test = m_test; test -= m_test; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 0.0, 0.0), "Test GSymMatrix -= GSymMatrix", test.print()); // GSymMatrix *= 3.0 test = m_test; test *= 3.0; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 3.0, 0.0), "Test GSymMatrix *= 3.0", test.print()); // GSymMatrix /= 3.0 test = m_test; test /= 3.0; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 1.0/3.0, 0.0), "Test GSymMatrix /= 3.0", test.print()); // GSymMatrix + GSymMatrix test = m_test + m_test; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 2.0, 0.0), "Test GSymMatrix + GSymMatrix", test.print()); // GSymMatrix - GSymMatrix test = m_test - m_test; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 0.0, 0.0), "Test GSymMatrix - GSymMatrix", test.print()); // GSymMatrix * 3.0 test = m_test * 3.0; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 3.0, 0.0), "Test GSymMatrix * 3.0", test.print()); // 3.0 * GSymMatrix test = 3.0 * m_test; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 3.0, 0.0), "Test 3.0 * GSymMatrix", test.print()); // GSymMatrix / 3.0 test = m_test / 3.0; test_assert(check_matrix(m_test), "Test source matrix"); test_assert(check_matrix(test, 1.0/3.0, 0.0), "Test GSymMatrix / 3.0", test.print()); // Test invalid matrix addition test_try("Test invalid matrix addition"); try { test = m_test; test += m_bigger; test_try_failure("Expected GException::matrix_mismatch exception."); } catch (GException::matrix_mismatch &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Return return; }
/***********************************************************************//** * @brief Test matrix operations * * Tests matrix*vector and matrix*matrix multiplication operations. ***************************************************************************/ void TestGSymMatrix::matrix_operations(void) { // Perform vector multiplication GVector test1 = m_test * v_test; // Check if the result vector is as expected GVector ref1 = test1; bool result = true; for (int row = 0; row < g_rows; ++row) { double value = 0.0; for (int col = 0; col < g_cols; ++col) { value += g_matrix[col+row*g_cols] * g_vector[col]; } ref1[row] = value; if (test1[row] != value) { result = false; break; } } // Test if original matrix and result vector are correct test_assert(check_matrix(m_test), "Test source matrix"); test_assert(result, "Test matrix*vector multiplication", "Found:\n"+test1.print()+"\nExpected:\n"+ref1.print()); // Test incompatible vector multiplication test_try("Test incompatible matrix*vector multiplication"); try { GVector test2 = m_bigger * v_test; test_try_failure(); } catch (GException::matrix_vector_mismatch &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test matrix multiplication GSymMatrix test3 = m_test * m_test; // Check if the result matrix is as expected GSymMatrix ref3 = test3; result = true; for (int row = 0; row < test3.rows(); ++row) { for (int col = 0; col < test3.cols(); ++col) { double value = 0.0; for (int i = 0; i < g_cols; ++i) { value += g_matrix[i+row*g_cols] * g_matrix[i+col*g_cols]; } ref3(row,col) = value; if (test3(row,col) != value) { result = false; break; } } } // Test if original matrix and result matrix are correct test_assert(check_matrix(m_test), "Test source matrix"); test_assert(result, "Test matrix multiplication", "Found:\n"+test3.print()+"\nExpected:\n"+ref3.print()); test_assert(test3.rows() == g_rows, "Test number of rows of result matrix"); test_assert(test3.cols() == g_cols, "Test number of columns of result matrix"); // Test incompatible matrix multiplication test_try("Test incompatible matrix multiplication"); try { GSymMatrix test4 = m_test * m_bigger; test_try_failure("Expected GException::matrix_mismatch exception."); } catch (GException::matrix_mismatch &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test another incompatible matrix multiplication test_try("Test incompatible matrix multiplication"); try { GSymMatrix test5 = m_bigger * m_test; test_try_failure("Expected GException::matrix_mismatch exception."); } catch (GException::matrix_mismatch &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Return return; }
/***********************************************************************//** * @brief Test GTimeReference ***************************************************************************/ void TestGObservation::test_time_reference(void) { // Test void constructor test_try("Void constructor"); try { GTimeReference reference; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test copy constructor test_try("Copy constructor"); try { GTimeReference reference; GTimeReference reference2(reference); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test reference constructor test_try("Reference constructor"); try { GTimeReference reference(55197.0, "s", "TT", "LOCAL"); test_try_success(); test_value(reference.mjdref(), 55197.0); test_assert(reference.timeunit() == "s", "Time unit was \""+reference.timeunit()+"\", expected \"s\""); test_assert(reference.timesys() == "TT", "Time system was \""+reference.timesys()+"\", expected \"TT\""); test_assert(reference.timeref() == "LOCAL", "Time reference was \""+reference.timeref()+"\", expected \"LOCAL\""); } catch (std::exception &e) { test_try_failure(e); } // Test reference constructor test_try("Reference constructor (split reference)"); try { GTimeReference reference(55197, 0.000766018518519, "s", "TT", "LOCAL"); test_try_success(); test_value(reference.mjdref(), 55197.000766018518519); test_assert(reference.timeunit() == "s", "Time unit was \""+reference.timeunit()+"\", expected \"s\""); test_assert(reference.timesys() == "TT", "Time system was \""+reference.timesys()+"\", expected \"TT\""); test_assert(reference.timeref() == "LOCAL", "Time reference was \""+reference.timeref()+"\", expected \"LOCAL\""); } catch (std::exception &e) { test_try_failure(e); } // Test FITS file writing GTimeReference reference(55197.000766018518519, "s", "TT", "LOCAL"); GFits fits; GFitsBinTable table; reference.write(table); fits.append(table); fits.saveto("test_time_reference.fits", true); fits.close(); // Read back from FITS file and check values fits.open("test_time_reference.fits"); const GFitsTable& hdu = *fits.table(1); GTimeReference value(hdu); fits.close(); test_value(value.mjdref(), reference.mjdref()); test_value(value.mjdrefi(), reference.mjdrefi()); test_value(value.mjdreff(), reference.mjdreff()); test_assert(value.timeunit() == reference.timeunit(), "Time unit was \""+value.timeunit()+"\", expected "+reference.timeunit()+"."); test_assert(value.timesys() == reference.timesys(), "Time system was \""+value.timesys()+"\", expected "+reference.timesys()+"."); test_assert(value.timeref() == reference.timeref(), "Time reference was \""+value.timeref()+"\", expected "+reference.timeref()+"."); // Return return; }
/***********************************************************************//** * @brief Test GTime ***************************************************************************/ void TestGObservation::test_time(void) { // Test void constructor test_try("Void constructor"); try { GTime time; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test copy constructor test_try("Copy constructor"); try { GTime time; GTime time2(time); test_try_success(); test_assert(time == time2, "Time differs after using copy constructor."); } catch (std::exception &e) { test_try_failure(e); } // Test time constructor (seconds) test_try("Time constructor (seconds)"); try { GTime time(1800.01); test_try_success(); test_value(time.secs(), 1800.01); test_value(time.days(), 1800.01/86400.0); } catch (std::exception &e) { test_try_failure(e); } // Test time constructor (days) test_try("Time constructor (days)"); try { GTime time(41.7, "days"); test_try_success(); test_value(time.days(), 41.7); test_value(time.secs(), 41.7*86400.0); } catch (std::exception &e) { test_try_failure(e); } // Test access methods double mjd_ref = 55197.000766018518519; double jd_ref = 2455197.500766018518519; double t = 123456.789; GTime time(t); test_value(time.jd(), t/86400.0 + jd_ref); test_value(time.mjd(), t/86400.0 + mjd_ref); test_value(time.secs(), t); test_value(time.days(), t/86400.0); // Test set method time.jd(57.9); test_value(time.jd(), 57.9); time.mjd(57.9); test_value(time.mjd(), 57.9); time.secs(57.9); test_value(time.secs(), 57.9); time.days(57.9); test_value(time.days(), 57.9); // Test convert method time.secs(t); test_value(time.convert(GTimeReference(55197.000766018518519, "days", "TT", "LOCAL")), t/86400.0); test_value(time.convert(GTimeReference(0.0, "s", "TT", "LOCAL")), t + mjd_ref*86400.0, 1.0e-6); //!< Poor precision on OpenSolaris // Test set method time.set(12.3, GTimeReference(55197.000766018518519, "days", "TT", "LOCAL")); test_value(time.days(), 12.3); time.set(12.3, GTimeReference(0.0, "secs", "TT", "LOCAL")); test_value(time.secs(), 12.3 - mjd_ref*86400.0); // Test operators GTime a(13.72); GTime b(6.28); test_value((a+b).secs(), 20.00); test_value((a-b).secs(), 7.44); test_value((a*3.3).secs(), 45.276); test_value((3.3*a).secs(), 45.276); test_value((a/13.72).secs(), 1.0); test_assert(a == a, "Equality operator corrupt."); test_assert(a != b, "Non-equality operator corrupt."); test_assert(a > b, "Greater than operator corrupt."); test_assert(a >= b, "Greater than or equal operator corrupt."); test_assert(b < a, "Less than operator corrupt."); test_assert(b <= a, "Less than or equal operator corrupt."); // Return return; }
/***********************************************************************//** * @brief Test matrix allocation ***************************************************************************/ void TestGMatrixSparse::alloc_matrix(void) { // Allocate zero matrix. The allocation should fail. test_try("Allocate zero matrix"); try { GMatrixSparse test(0,0); test_try_failure("Expected GException::empty exception."); } catch (GException::empty &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Setup a symmetric sparse matrix int size = 30; GMatrixSparse symmetric(size,size); for (int i = 0; i < size; i+=2) { for (int j = 0; j < size; j+=2) { symmetric(i,j) = 1.0+i+j; } } // Convert to GMatrix test_try("Test symmetric GMatrix conversion"); try { GMatrix cnv_matrix = GMatrix(symmetric); GMatrixSparse back_matrix = GMatrixSparse(cnv_matrix); test_assert((symmetric == back_matrix), "Test symmetric GMatrixSparse - GMatrix conversion", "Found:\n"+back_matrix.print()+"\nExpected:\n"+symmetric.print()); test_try_success(); } catch (GException::empty &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test GMatrix conversion test_try("Test GMatrix conversion"); try { GMatrix cnv_matrix = GMatrix(m_test); GMatrixSparse back_matrix = GMatrixSparse(cnv_matrix); test_assert((m_test == back_matrix), "Test GMatrixSparse - GMatrix conversion", "Found:\n"+back_matrix.print()+"\nExpected:\n"+m_test.print()); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test GMatrixSparse <-> GMatrixSymmetric conversion test_try("Test GMatrixSymmetric conversion"); try { GMatrixSymmetric cnv_sym = GMatrixSymmetric(symmetric); GMatrixSparse back_sym = GMatrixSparse(cnv_sym); test_assert((symmetric == back_sym), "Test GMatrixSparse - GMatrixSymmetric conversion", "Found:\n"+back_sym.print()+"\nExpected:\n"+symmetric.print()); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test invalid GMatrixSparse <-> GMatrixSymmetric conversion test_try("Test invalid GMatrixSymmetric conversion"); try { GMatrixSymmetric bad_sym = GMatrixSymmetric(m_test); test_try_failure("Expected GException::matrix_not_symmetric exception."); } catch (GException::matrix_not_symmetric &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Return return; }
/***********************************************************************//** * @brief Test GEnergies ***************************************************************************/ void TestGObservation::test_energies(void) { // Test void constructor test_try("Void constructor"); try { GEnergies energies; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Manipulate GEnergies starting from an empty object GEnergies energies; test_value(energies.size(), 0, "GEnergies should have zero size."); test_assert(energies.is_empty(), "GEnergies should be empty."); // Add an energy energies.append(GEnergy()); test_value(energies.size(), 1, "GEnergies should have 1 energy."); test_assert(!energies.is_empty(), "GEnergies should not be empty."); // Remove energy energies.remove(0); test_value(energies.size(), 0, "GEnergies should have zero size."); test_assert(energies.is_empty(), "GEnergies should be empty."); // Append two energies energies.append(GEnergy()); energies.append(GEnergy()); test_value(energies.size(), 2, "GEnergies should have 2 energies."); test_assert(!energies.is_empty(), "GEnergies should not be empty."); // Clear object energies.clear(); test_value(energies.size(), 0, "GEnergies should have zero size."); test_assert(energies.is_empty(), "GEnergies should be empty."); // Insert two energies energies.insert(0, GEnergy()); energies.insert(0, GEnergy()); test_value(energies.size(), 2, "GEnergies should have 2 energies."); test_assert(!energies.is_empty(), "GEnergies should not be empty."); // Extend energies energies.extend(energies); test_value(energies.size(), 4, "GEnergies should have 4 energies."); test_assert(!energies.is_empty(), "GEnergies should not be empty."); // Create 4 energies energies.clear(); for (int i = 0; i < 4; ++i) { energies.append(GEnergy(double(i), "MeV")); } for (int i = 0; i < 4; ++i) { test_value(energies[i].MeV(), double(i)); } // Save and reload energies test_try("Saving and loading"); try { energies.save("test_energies.fits", true); energies.clear(); energies.load("test_energies.fits"); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } for (int i = 0; i < 4; ++i) { test_value(energies[i].MeV(), double(i)); } // Test load constructor test_try("Load constructor"); try { GEnergies energies2("test_energies.fits"); for (int i = 0; i < 4; ++i) { test_value(energies[i].MeV(), double(i)); } test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Return return; }
/***********************************************************************//** * @brief Test value assignment ***************************************************************************/ void TestGMatrixSparse::assign_values(void) { // Setup 3x3 matrix GMatrixSparse test(3,3); // Assignment individual values for (int i = 0; i < 3; ++i) { for (int k = 0; k < 3; ++k) { double value = i*2.0 + k*2.0; test(i,k) = value; } } // Check assignment of individual values for (int i = 0; i < 3; ++i) { for (int k = 0; k < 3; ++k) { double value = i*2.0 + k*2.0; test_value(test(i,k), value, 1.0e-10, "Test matrix element assignment"); } } // Check value assignment const double ref = 37.89; test = ref; for (int i = 0; i < 3; ++i) { for (int k = 0; k < 3; ++k) { test_value(test(i,k), ref, 1.0e-10, "Test matrix element assignment"); } } test = 0.0; for (int i = 0; i < 3; ++i) { for (int k = 0; k < 3; ++k) { test_value(test(i,k), 0.0, 1.0e-10, "Test matrix element assignment"); } } // Verify range checking #ifdef G_RANGE_CHECK test_try("Verify range checking"); try { test.at(3,3) = 1.0; test_try_failure("Expected GException::out_of_range exception."); } catch (GException::out_of_range &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } #endif // Setup 10x10 matrix and keep for reference GMatrixSparse sparse(10,10); for (int i = 3; i < 5; ++i) { sparse(i,i) = 5.0; } GMatrixSparse initial = sparse; GMatrixSparse reference = sparse; // Insert column into 10 x 10 matrix using large matrix stack and the // add_col(GVector) method sparse.stack_init(100,50); GVector column(10); for (int j = 0; j < 10; ++j) { int col = int(0.8 * j + 0.5); // This allows that some columns are twice if (col > 9) col -= 10; // This avoids overflow int i_min = (j < 2) ? 0 : j-2; int i_max = (j > 8) ? 10 : j+2; column = 0.0; for (int i = i_min; i < i_max; ++i) { column[i] = (i+1)*1; reference(i,col) += column[i]; } sparse.add_to_column(col, column); } sparse.stack_destroy(); test_assert((sparse == reference), "Test stack fill with large stack using add_col(GVector) method", "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print()); // Insert column into 10 x 10 matrix using small matrix stack and the // add_col(GVector) method sparse = initial; sparse.stack_init(100,3); for (int j = 0; j < 10; ++j) { int col = int(0.8 * j + 0.5); // This allows that some columns are twice if (col > 9) col -= 10; // This avoids overflow int i_min = (j < 2) ? 0 : j-2; int i_max = (j > 8) ? 10 : j+2; column = 0.0; for (int i = i_min; i < i_max; ++i) { column[i] = (i+1)*1; } sparse.add_to_column(col, column); } sparse.stack_destroy(); test_assert((sparse == reference), "Test stack fill with small stack using add_col(GVector) method", "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print()); // Insert column into 10 x 10 matrix using tiny matrix stack and the // add_col(GVector) method sparse = initial; sparse.stack_init(8,3); for (int j = 0; j < 10; ++j) { int col = int(0.8 * j + 0.5); // This allows that some columns are twice if (col > 9) col -= 10; // This avoids overflow int i_min = (j < 2) ? 0 : j-2; int i_max = (j > 8) ? 10 : j+2; column = 0.0; for (int i = i_min; i < i_max; ++i) { column[i] = (i+1)*1; } sparse.add_to_column(col, column); } sparse.stack_destroy(); test_assert((sparse == reference), "Test stack fill with tiny stack using add_col(GVector) method", "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print()); // Insert column into 10 x 10 matrix using no matrix stack and the // add_col(GVector) method sparse = initial; for (int j = 0; j < 10; ++j) { int col = int(0.8 * j + 0.5); // This allows that some columns are twice if (col > 9) col -= 10; // This avoids overflow int i_min = (j < 2) ? 0 : j-2; int i_max = (j > 8) ? 10 : j+2; column = 0.0; for (int i = i_min; i < i_max; ++i) { column[i] = (i+1)*1; } sparse.add_to_column(col, column); } sparse.stack_destroy(); test_assert((sparse == reference), "Test fill using add_col(GVector) method", "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print()); // Set-up workspace for compressed column adding double* wrk_data = new double[10]; int* wrk_row = new int[10]; // Compressed tests test_try("Verify compressed column add_col() method"); try { // Insert column into 10 x 10 matrix using large matrix stack and the // compressed column add_col() method sparse = initial; reference = initial; sparse.stack_init(100,50); for (int j = 0; j < 10; ++j) { int col = int(0.8 * j + 0.5); // This allows that some columns are twice if (col > 9) col -= 10; // This avoids overflow int inx = 0; int i_min = (j < 3) ? 0 : j-3; int i_max = (j > 8) ? 10 : j+2; for (int i = i_min; i < i_max; ++i) { wrk_data[inx] = (i+1)*3.7; wrk_row[inx] = i; reference(i,col) += wrk_data[inx]; inx++; } sparse.add_to_column(col, wrk_data, wrk_row, inx); } sparse.stack_destroy(); test_assert((sparse == reference), "Test stack fill with large stack using compressed add_col() method", "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print()); // Insert column into 10 x 10 matrix using small matrix stack and the // compressed column add_col() method sparse = initial; sparse.stack_init(100,2); for (int j = 0; j < 10; ++j) { int col = int(0.8 * j + 0.5); // This allows that some columns are twice if (col > 9) col -= 10; // This avoids overflow int inx = 0; int i_min = (j < 3) ? 0 : j-3; int i_max = (j > 8) ? 10 : j+2; for (int i = i_min; i < i_max; ++i) { wrk_data[inx] = (i+1)*3.7; wrk_row[inx] = i; inx++; } sparse.add_to_column(col, wrk_data, wrk_row, inx); } sparse.stack_destroy(); test_assert((sparse == reference), "Test stack fill with small stack using compressed add_col() method", "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print()); // Insert column into 10 x 10 matrix using tiny matrix stack and the // compressed column add_col() method sparse = initial; sparse.stack_init(3,2); for (int j = 0; j < 10; ++j) { int col = int(0.8 * j + 0.5); // This allows that some columns are twice if (col > 9) col -= 10; // This avoids overflow int inx = 0; int i_min = (j < 3) ? 0 : j-3; int i_max = (j > 8) ? 10 : j+2; for (int i = i_min; i < i_max; ++i) { wrk_data[inx] = (i+1)*3.7; wrk_row[inx] = i; inx++; } sparse.add_to_column(col, wrk_data, wrk_row, inx); } sparse.stack_destroy(); test_assert((sparse == reference), "Test stack fill with tiny stack using compressed add_col() method", "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print()); // Insert column into 10 x 10 matrix using no matrix stack and the // compressed column add_col() method sparse = initial; for (int j = 0; j < 10; ++j) { int col = int(0.8 * j + 0.5); // This allows that some columns are twice if (col > 9) col -= 10; // This avoids overflow int inx = 0; int i_min = (j < 3) ? 0 : j-3; int i_max = (j > 8) ? 10 : j+2; for (int i = i_min; i < i_max; ++i) { wrk_data[inx] = (i+1)*3.7; wrk_row[inx] = i; inx++; } sparse.add_to_column(col, wrk_data, wrk_row, inx); } sparse.stack_destroy(); test_assert((sparse == reference), "Test fill using compressed add_col() method", "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print()); // Signal success test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Free workspace delete [] wrk_data; delete [] wrk_row; // Return return; }
/***********************************************************************//** * @brief Test GEbounds ***************************************************************************/ void TestGObservation::test_ebounds(void) { // Test void constructor test_try("Void constructor"); try { GEbounds ebds; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Manipulate energy boudaries starting from an empty object GEbounds ebds; test_value(ebds.size(), 0, "GEbounds should have zero size."); test_assert(ebds.is_empty(), "GEbounds should be empty."); test_value(ebds.emin().MeV(), 0.0, 1.0e-10, "Minimum energy should be 0."); test_value(ebds.emax().MeV(), 0.0, 1.0e-10, "Maximum energy should be 0."); // Add empty interval ebds.append(GEnergy(1.0, "MeV"), GEnergy(1.0, "MeV")); test_value(ebds.size(), 0, "GEbounds should have zero size."); test_assert(ebds.is_empty(), "GEbounds should be empty."); test_value(ebds.emin().MeV(), 0.0, 1.0e-10, "Minimum energy should be 0."); test_value(ebds.emax().MeV(), 0.0, 1.0e-10, "Maximum energy should be 0."); // Add one interval ebds.append(GEnergy(1.0, "MeV"), GEnergy(10.0, "MeV")); test_value(ebds.size(), 1, "GEbounds should have 1 element."); test_assert(!ebds.is_empty(), "GEbounds should not be empty."); test_value(ebds.emin().MeV(), 1.0, 1.0e-10, "Minimum energy should be 1."); test_value(ebds.emax().MeV(), 10.0, 1.0e-10, "Maximum energy should be 10."); // Remove interval ebds.remove(0); test_value(ebds.size(), 0, "GEbounds should have zero size."); test_assert(ebds.is_empty(), "GEbounds should be empty."); test_value(ebds.emin().MeV(), 0.0, 1.0e-10, "Minimum energy should be 0."); test_value(ebds.emax().MeV(), 0.0, 1.0e-10, "Maximum energy should be 0."); // Append two overlapping intervals ebds.append(GEnergy(1.0, "MeV"), GEnergy(100.0, "MeV")); ebds.append(GEnergy(10.0, "MeV"), GEnergy(1000.0, "MeV")); test_value(ebds.size(), 2, "GEbounds should have 2 elements."); test_assert(!ebds.is_empty(), "GEbounds should not be empty."); test_value(ebds.emin().MeV(), 1.0, 1.0e-10, "Minimum energy should be 1."); test_value(ebds.emax().MeV(), 1000.0, 1.0e-10, "Maximum energy should be 1000."); // Clear object ebds.clear(); test_value(ebds.size(), 0, "GEbounds should have zero size."); test_assert(ebds.is_empty(), "GEbounds should be empty."); test_value(ebds.emin().MeV(), 0.0, 1.0e-10, "Minimum energy should be 0."); test_value(ebds.emax().MeV(), 0.0, 1.0e-10, "Maximum energy should be 0."); // Append two overlapping intervals in inverse order ebds.clear(); ebds.append(GEnergy(10.0, "MeV"), GEnergy(1000.0, "MeV")); ebds.append(GEnergy(1.0, "MeV"), GEnergy(100.0, "MeV")); test_value(ebds.size(), 2, "GEbounds should have 2 elements."); test_assert(!ebds.is_empty(), "GEbounds should not be empty."); test_value(ebds.emin().MeV(), 1.0, 1.0e-10, "Minimum energy should be 1."); test_value(ebds.emax().MeV(), 1000.0, 1.0e-10, "Maximum energy should be 1000."); // Insert two overlapping intervals ebds.clear(); ebds.insert(GEnergy(1.0, "MeV"), GEnergy(100.0, "MeV")); ebds.insert(GEnergy(10.0, "MeV"), GEnergy(1000.0, "MeV")); test_value(ebds.size(), 2, "GEbounds should have 2 elements."); test_assert(!ebds.is_empty(), "GEbounds should not be empty."); test_value(ebds.emin().MeV(), 1.0, 1.0e-10, "Minimum energy should be 1."); test_value(ebds.emax().MeV(), 1000.0, 1.0e-10, "Maximum energy should be 1000."); // Insert two overlapping intervals in inverse order ebds.clear(); ebds.insert(GEnergy(10.0, "MeV"), GEnergy(1000.0, "MeV")); ebds.insert(GEnergy(1.0, "MeV"), GEnergy(100.0, "MeV")); test_value(ebds.size(), 2, "GEbounds should have 2 elements."); test_assert(!ebds.is_empty(), "GEbounds should not be empty."); test_value(ebds.emin().MeV(), 1.0, 1.0e-10, "Minimum energy should be 1."); test_value(ebds.emax().MeV(), 1000.0, 1.0e-10, "Maximum energy should be 1000."); // Merge two overlapping intervals ebds.clear(); ebds.merge(GEnergy(1.0, "MeV"), GEnergy(100.0, "MeV")); ebds.merge(GEnergy(10.0, "MeV"), GEnergy(1000.0, "MeV")); test_value(ebds.size(), 1, "GEbounds should have 1 element."); test_assert(!ebds.is_empty(), "GEbounds should not be empty."); test_value(ebds.emin().MeV(), 1.0, 1.0e-10, "Minimum energy should be 1."); test_value(ebds.emax().MeV(), 1000.0, 1.0e-10, "Maximum energy should be 1000."); // Merge two overlapping intervals in inverse order ebds.clear(); ebds.merge(GEnergy(10.0, "MeV"), GEnergy(1000.0, "MeV")); ebds.merge(GEnergy(1.0, "MeV"), GEnergy(100.0, "MeV")); test_value(ebds.size(), 1, "GEbounds should have 1 element."); test_assert(!ebds.is_empty(), "GEbounds should not be empty."); test_value(ebds.emin().MeV(), 1.0, 1.0e-10, "Minimum energy should be 1."); test_value(ebds.emax().MeV(), 1000.0, 1.0e-10, "Maximum energy should be 1000."); // Check linear boundaries ebds.clear(); ebds.set_lin(2, GEnergy(1.0, "MeV"), GEnergy(3.0, "MeV")); test_value(ebds.size(), 2, "GEbounds should have 2 elements."); test_assert(!ebds.is_empty(), "GEbounds should not be empty."); test_value(ebds.emin(0).MeV(), 1.0, 1.0e-10, "Bin 0 minimum energy should be 1."); test_value(ebds.emin(1).MeV(), 2.0, 1.0e-10, "Bin 1 minimum energy should be 2."); test_value(ebds.emax(0).MeV(), 2.0, 1.0e-10, "Bin 0 maximum energy should be 2."); test_value(ebds.emax(1).MeV(), 3.0, 1.0e-10, "Bin 1 maximum energy should be 3."); test_value(ebds.emin().MeV(), 1.0, 1.0e-10, "Minimum energy should be 1."); test_value(ebds.emax().MeV(), 3.0, 1.0e-10, "Maximum energy should be 3."); // Check logarithmic boundaries ebds.clear(); ebds.set_log(2, GEnergy(1.0, "MeV"), GEnergy(100.0, "MeV")); test_value(ebds.size(), 2, "GEbounds should have 2 elements."); test_assert(!ebds.is_empty(), "GEbounds should not be empty."); test_value(ebds.emin(0).MeV(), 1.0, 1.0e-10, "Bin 0 minimum energy should be 1."); test_value(ebds.emin(1).MeV(), 10.0, 1.0e-10, "Bin 1 minimum energy should be 10."); test_value(ebds.emax(0).MeV(), 10.0, 1.0e-10, "Bin 0 maximum energy should be 10."); test_value(ebds.emax(1).MeV(), 100.0, 1.0e-10, "Bin 1 maximum energy should be 100."); test_value(ebds.emin().MeV(), 1.0, 1.0e-10, "Minimum energy should be 1."); test_value(ebds.emax().MeV(), 100.0, 1.0e-10, "Maximum energy should be 100."); // Check boundary extension GEbounds ext(1, GEnergy(100.0, "MeV"), GEnergy(1000.0, "MeV")); ebds.extend(ext); test_value(ebds.size(), 3, "GEbounds should have 3 elements."); test_assert(!ebds.is_empty(), "GEbounds should not be empty."); test_value(ebds.emin(0).MeV(), 1.0, 1.0e-10, "Bin 0 minimum energy should be 1."); test_value(ebds.emin(1).MeV(), 10.0, 1.0e-10, "Bin 1 minimum energy should be 10."); test_value(ebds.emin(2).MeV(), 100.0, 1.0e-10, "Bin 2 minimum energy should be 100."); test_value(ebds.emax(0).MeV(), 10.0, 1.0e-10, "Bin 0 maximum energy should be 10."); test_value(ebds.emax(1).MeV(), 100.0, 1.0e-10, "Bin 1 maximum energy should be 100."); test_value(ebds.emax(2).MeV(), 1000.0, 1.0e-10, "Bin 1 maximum energy should be 1000."); test_value(ebds.emin().MeV(), 1.0, 1.0e-10, "Minimum energy should be 1."); test_value(ebds.emax().MeV(), 1000.0, 1.0e-10, "Maximum energy should be 1000."); // 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; }