Commit 9e70368c21c40e581a77f1247852fb52ecfbbfdd

Authored by Jürgen Knödlseder
1 parent a1e90215

Enable usage of ctmodel on stacked cubes.

src/ctmodel/ctmodel.cpp
... ... @@ -365,7 +365,8 @@ void ctmodel::init_members(void)
365 365 m_obs.clear();
366 366 m_cube.clear();
367 367 m_gti.clear();
368   - m_has_cube = false;
  368 + m_has_cube = false;
  369 + m_append_cube = false;
369 370  
370 371 // Return
371 372 return;
... ... @@ -384,10 +385,11 @@ void ctmodel::copy_members(const ctmodel& app)
384 385 m_apply_edisp = app.m_apply_edisp;
385 386  
386 387 // Copy protected members
387   - m_obs = app.m_obs;
388   - m_cube = app.m_cube;
389   - m_gti = app.m_gti;
390   - m_has_cube = app.m_has_cube;
  388 + m_obs = app.m_obs;
  389 + m_cube = app.m_cube;
  390 + m_gti = app.m_gti;
  391 + m_has_cube = app.m_has_cube;
  392 + m_append_cube = app.m_append_cube;
391 393  
392 394 // Return
393 395 return;
... ... @@ -412,10 +414,13 @@ void ctmodel::free_members(void)
412 414 ***************************************************************************/
413 415 void ctmodel::get_parameters(void)
414 416 {
  417 + // Reset cube append flag
  418 + m_append_cube = false;
  419 +
415 420 // If there are no observations in container then load them via user
416 421 // parameters
417 422 if (m_obs.size() == 0) {
418   - m_obs = get_observations();
  423 + get_obs();
419 424 }
420 425  
421 426 // Read model definition file if required
... ... @@ -468,10 +473,145 @@ void ctmodel::get_parameters(void)
468 473 m_outcube = (*this)["outcube"].filename();
469 474 }
470 475  
  476 + // If cube should be appended to first observation then do that now.
  477 + // This is a kluge that makes sure that the cube is passed as part
  478 + // of the observation in case that a cube response is used. The kluge
  479 + // is needed because the GCTACubeSourceDiffuse::set method needs to
  480 + // get the full event cube from the observation.
  481 + if (m_append_cube) {
  482 +
  483 + //TODO: Check that energy boundaries are compatible
  484 +
  485 + // Attach GTI of observations to model cube
  486 + m_cube.gti(m_obs[0]->events()->gti());
  487 +
  488 + // Attach model cube to observations
  489 + m_obs[0]->events(m_cube);
  490 +
  491 + } // endif: cube was scheduled for appending
  492 +
471 493 // Return
472 494 return;
473 495 }
474 496  
  497 +
  498 +/***********************************************************************//**
  499 + * @brief Get observation container
  500 + *
  501 + * Get an observation container according to the user parameters. The method
  502 + * supports loading of a individual FITS file or an observation definition
  503 + * file in XML format. If the input filename is empty, parameters are read
  504 + * to build a CTA observation from scratch.
  505 + ***************************************************************************/
  506 +void ctmodel::get_obs(void)
  507 +{
  508 + // Get the filename from the input parameters
  509 + std::string filename = (*this)["inobs"].filename();
  510 +
  511 + // If no observation definition file has been specified then read all
  512 + // parameters that are necessary to create an observation from scratch
  513 + if ((filename == "NONE") || (gammalib::strip_whitespace(filename) == "")) {
  514 +
  515 + // Get response cube filenames
  516 + std::string expcube = (*this)["expcube"].filename();
  517 + std::string psfcube = (*this)["psfcube"].filename();
  518 +
  519 + // If the filenames are valid then build an observation from cube
  520 + // response information
  521 + if ((expcube != "NONE") && (psfcube != "NONE") &&
  522 + (gammalib::strip_whitespace(expcube) != "") &&
  523 + (gammalib::strip_whitespace(psfcube) != "")) {
  524 +
  525 + // Get exposure and PSF cubes
  526 + GCTACubeExposure exposure(expcube);
  527 + GCTACubePsf psf(psfcube);
  528 +
  529 + // Create energy boundaries
  530 + GEbounds ebounds = create_ebounds();
  531 +
  532 + // Create dummy sky map cube
  533 + GSkymap map("CAR","GAL",0.0,0.0,1.0,1.0,1,1,ebounds.size());
  534 + m_append_cube = true;
  535 +
  536 + // Create event cube
  537 + GCTAEventCube cube(map, ebounds, exposure.gti());
  538 +
  539 + // Create CTA observation
  540 + GCTAObservation cta;
  541 + cta.events(cube);
  542 + cta.response(exposure, psf);
  543 +
  544 + // Append observation to container
  545 + m_obs.append(cta);
  546 +
  547 + } // endif: cube response information was available
  548 +
  549 + // ... otherwise build an observation from IRF response information
  550 + else {
  551 +
  552 + // Create CTA observation
  553 + GCTAObservation cta = create_cta_obs();
  554 +
  555 + // Set response
  556 + set_obs_response(&cta);
  557 +
  558 + // Append observation to container
  559 + m_obs.append(cta);
  560 +
  561 + }
  562 +
  563 + } // endif: filename was "NONE" or ""
  564 +
  565 + // ... otherwise we have a file name
  566 + else {
  567 +
  568 + // If file is a FITS file then create an empty CTA observation
  569 + // and load file into observation
  570 + if (gammalib::is_fits(filename)) {
  571 +
  572 + // Allocate empty CTA observation
  573 + GCTAObservation cta;
  574 +
  575 + // Load data
  576 + cta.load(filename);
  577 +
  578 + // Set response
  579 + set_obs_response(&cta);
  580 +
  581 + // Append observation to container
  582 + m_obs.append(cta);
  583 +
  584 + // Signal that no XML file should be used for storage
  585 + m_use_xml = false;
  586 +
  587 + }
  588 +
  589 + // ... otherwise load file into observation container
  590 + else {
  591 +
  592 + // Load observations from XML file
  593 + m_obs.load(filename);
  594 +
  595 + // For all observations that have no response, set the response
  596 + // from the task parameters
  597 + set_response(m_obs);
  598 +
  599 + // Set observation boundary parameters (emin, emax, rad)
  600 + set_obs_bounds(m_obs);
  601 +
  602 + // Signal that XML file should be used for storage
  603 + m_use_xml = true;
  604 +
  605 + } // endelse: file was an XML file
  606 +
  607 + }
  608 +
  609 + // Return
  610 + return;
  611 +
  612 +}
  613 +
  614 +
475 615 /***********************************************************************//**
476 616 * @brief Fill model into model cube
477 617 *
... ... @@ -515,6 +655,7 @@ void ctmodel::fill_cube(const GCTAObservation* obs)
515 655  
516 656 // Compute model value for cube bin
517 657 double model = m_obs.models().eval(*bin, *obs) * bin->size();
  658 + //double model = m_obs.models().eval(*bin, *ptr) * bin->size();
518 659  
519 660 // Add model to actual value
520 661 value += model;
... ...
src/ctmodel/ctmodel.hpp
... ... @@ -78,6 +78,7 @@ protected:
78 78 void copy_members(const ctmodel& app);
79 79 void free_members(void);
80 80 void get_parameters(void);
  81 + void get_obs(void);
81 82 void fill_cube(const GCTAObservation* obs);
82 83 bool has_cube(void) const;
83 84  
... ... @@ -86,10 +87,11 @@ protected:
86 87 bool m_apply_edisp; //!< Apply energy dispersion?
87 88  
88 89 // Protected members
89   - GObservations m_obs; //!< Observation container
90   - GCTAEventCube m_cube; //!< Model cube
91   - GGti m_gti; //!< Model cube GTIs
92   - bool m_has_cube; //!< Signal if cube has been set or loaded
  90 + GObservations m_obs; //!< Observation container
  91 + GCTAEventCube m_cube; //!< Model cube
  92 + GGti m_gti; //!< Model cube GTIs
  93 + bool m_has_cube; //!< Signal if cube has been set or loaded
  94 + bool m_append_cube; //!< Signal that cube should be appended
93 95 };
94 96  
95 97  
... ...
src/support/ctool.cpp
... ... @@ -304,7 +304,7 @@ GObservations ctool::get_observations(const bool&amp; get_response)
304 304 if (get_response) {
305 305  
306 306 // Set response
307   - set_obs_response(&cta_obs);
  307 + set_obs_response(&cta_obs);
308 308  
309 309 } // endif: response was required
310 310  
... ...
test/test_ctmodel.py
... ... @@ -70,6 +70,8 @@ class Test(gammalib.GPythonTestSuite):
70 70 model["outcube"].filename("modmap.fits")
71 71 model["inmodel"].filename(self.model_name)
72 72 model["inobs"].filename("NONE")
  73 + model["expcube"].filename("NONE")
  74 + model["psfcube"].filename("NONE")
73 75 model["caldb"].string(self.caldb)
74 76 model["irf"].string(self.irf)
75 77 model["rad"].real(5.0)
... ...
test/test_ctools.sh
... ... @@ -218,10 +218,12 @@ else
218 218 exit 1
219 219 fi
220 220 #
221   -# Run 3
  221 +# Run 2
222 222 $ctmodel inobs="NONE" \
223 223 incube="NONE" \
224 224 outcube="modmap3.fits" \
  225 + expcube="NONE" \
  226 + psfcube="NONE" \
225 227 caldb="irf" \
226 228 irf="cta_dummy_irf" \
227 229 inmodel="data/crab.xml" \
... ... @@ -249,7 +251,7 @@ else
249 251 exit 1
250 252 fi
251 253 #
252   -# Run 2
  254 +# Run 3
253 255 $ctmodel inobs="cntmap2.fits" \
254 256 incube="cntmap2.fits" \
255 257 outcube="modmap2.fits" \
... ...