Commit 51c989497196f4f357e23ed1b8c2b16ce886ec77

Authored by Michael Mayer
1 parent 23dd86c9

Adapted ctools to handle observation type consistently

scripts/cslightcrv.py
@@ -107,7 +107,7 @@ class cslightcrv(ctools.cscript): @@ -107,7 +107,7 @@ class cslightcrv(ctools.cscript):
107 pars.append(gammalib.GApplicationPar("bkgcube","s","a","NONE","","","Background cube file (only needed for stacked analysis)")) 107 pars.append(gammalib.GApplicationPar("bkgcube","s","a","NONE","","","Background cube file (only needed for stacked analysis)"))
108 pars.append(gammalib.GApplicationPar("caldb","s","a","prod2","","","Calibration database")) 108 pars.append(gammalib.GApplicationPar("caldb","s","a","prod2","","","Calibration database"))
109 pars.append(gammalib.GApplicationPar("irf","s","a","South_50h","","","Instrument response function")) 109 pars.append(gammalib.GApplicationPar("irf","s","a","South_50h","","","Instrument response function"))
110 - pars.append(gammalib.GApplicationPar("tbinalg","s","h","GTI","FILE|LIN|GTI","", "Algorithm for defining time bins")) 110 + pars.append(gammalib.GApplicationPar("tbinalg","s","a","GTI","FILE|LIN|GTI","", "Algorithm for defining time bins"))
111 pars.append(gammalib.GApplicationPar("tmin","r","a","51544.5","","days","Lightcurve start time [MJD]")) 111 pars.append(gammalib.GApplicationPar("tmin","r","a","51544.5","","days","Lightcurve start time [MJD]"))
112 pars.append(gammalib.GApplicationPar("tmax","r","a","51544.6","","days","Lightcurve stop time [MJD]")) 112 pars.append(gammalib.GApplicationPar("tmax","r","a","51544.6","","days","Lightcurve stop time [MJD]"))
113 pars.append(gammalib.GApplicationPar("tbins","i","a","5","","","Number of time bins")) 113 pars.append(gammalib.GApplicationPar("tbins","i","a","5","","","Number of time bins"))
src/ctbin/ctbin.cpp
@@ -257,6 +257,17 @@ void ctbin::run(void) @@ -257,6 +257,17 @@ void ctbin::run(void)
257 } 257 }
258 } 258 }
259 259
  260 + // Skip observation if we don't have an unbinned observation
  261 + if (obs->eventtype() != "EventList") {
  262 +
  263 + // Log that we skip the this observation
  264 + if (logTerse()) {
  265 + log << "Warning: Skipping binned observation \""+obs->name()+"\"";
  266 + log << std::endl;
  267 + }
  268 + continue;
  269 + }
  270 +
260 // Fill the cube 271 // Fill the cube
261 fill_cube(obs); 272 fill_cube(obs);
262 273
@@ -561,11 +572,25 @@ void ctbin::obs_cube(void) @@ -561,11 +572,25 @@ void ctbin::obs_cube(void)
561 // Attach event cube to CTA observation 572 // Attach event cube to CTA observation
562 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]); 573 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]);
563 if (obs != NULL) { 574 if (obs != NULL) {
564 - obs->events(this->cube());  
565 - obs->eventfile("");  
566 - }  
567 575
568 - } 576 + // Only change the event type if we had an unbinned observation
  577 + if (obs->eventtype() == "EventList") {
  578 +
  579 + obs->events(this->cube());
  580 + obs->eventfile("");
  581 + } // endif: observation was unbinned
  582 + else { // input observation was binned and skipped
  583 +
  584 + // Create new and empty cube
  585 + GCTAEventCube cube = GCTAEventCube(m_cube, m_ebounds, obs->gti());
  586 +
  587 + // Assign empty cube to have a new binned observation
  588 + obs->events(cube);
  589 + }
  590 +
  591 + } // endif: obervation was valid
  592 +
  593 + } // endif: we only had one observation in the container
569 594
570 // ... otherwise put a single CTA observation in container 595 // ... otherwise put a single CTA observation in container
571 else { 596 else {
src/ctbkgcube/ctbkgcube.cpp
@@ -308,7 +308,7 @@ void ctbkgcube::run(void) @@ -308,7 +308,7 @@ void ctbkgcube::run(void)
308 m_obs.models(m_bkgmdl); 308 m_obs.models(m_bkgmdl);
309 309
310 // Fill background cube from observations 310 // Fill background cube from observations
311 - m_background.fill(m_obs); 311 + m_background.fill(m_obs, &log);
312 312
313 // Create a background model for the output background cube and append 313 // Create a background model for the output background cube and append
314 // that model to the input model in place of the original 314 // that model to the input model in place of the original
src/ctexpcube/ctexpcube.cpp
@@ -248,7 +248,7 @@ void ctexpcube::run(void) @@ -248,7 +248,7 @@ void ctexpcube::run(void)
248 } 248 }
249 249
250 // Fill exposure 250 // Fill exposure
251 - m_expcube.fill(m_obs); 251 + m_expcube.fill(m_obs, &log);
252 252
253 // Restore energy dispersion flag for all CTA observations 253 // Restore energy dispersion flag for all CTA observations
254 for (int i = 0; i < m_obs.size(); ++i) { 254 for (int i = 0; i < m_obs.size(); ++i) {
src/ctmodel/ctmodel.cpp
@@ -427,7 +427,7 @@ void ctmodel::get_parameters(void) @@ -427,7 +427,7 @@ void ctmodel::get_parameters(void)
427 // If there are no observations in container then load them via user 427 // If there are no observations in container then load them via user
428 // parameters 428 // parameters
429 if (m_obs.size() == 0) { 429 if (m_obs.size() == 0) {
430 - get_obs(); 430 + m_obs = get_observations();
431 } 431 }
432 432
433 // Read model definition file if required 433 // Read model definition file if required
@@ -505,126 +505,6 @@ void ctmodel::get_parameters(void) @@ -505,126 +505,6 @@ void ctmodel::get_parameters(void)
505 505
506 506
507 /***********************************************************************//** 507 /***********************************************************************//**
508 - * @brief Get observation container  
509 - *  
510 - * Get an observation container according to the user parameters. The method  
511 - * supports loading of a individual FITS file or an observation definition  
512 - * file in XML format. If the input filename is empty, parameters are read  
513 - * to build a CTA observation from scratch.  
514 - ***************************************************************************/  
515 -void ctmodel::get_obs(void)  
516 -{  
517 - // Get the filename from the input parameters  
518 - std::string filename = (*this)["inobs"].filename();  
519 -  
520 - // If no observation definition file has been specified then read all  
521 - // parameters that are necessary to create an observation from scratch  
522 - if ((filename == "NONE") || (gammalib::strip_whitespace(filename) == "")) {  
523 -  
524 - // Get response cube filenames  
525 - std::string expcube = (*this)["expcube"].filename();  
526 - std::string psfcube = (*this)["psfcube"].filename();  
527 - std::string bkgcube = (*this)["bkgcube"].filename();  
528 -  
529 - // If the filenames are valid then build an observation from cube  
530 - // response information  
531 - if ((expcube != "NONE") && (psfcube != "NONE") && (bkgcube != "NONE") &&  
532 - (gammalib::strip_whitespace(expcube) != "") &&  
533 - (gammalib::strip_whitespace(psfcube) != "") &&  
534 - (gammalib::strip_whitespace(bkgcube) != "")) {  
535 -  
536 - // Get exposure, PSF and background cubes  
537 - GCTACubeExposure exposure(expcube);  
538 - GCTACubePsf psf(psfcube);  
539 - GCTACubeBackground background(bkgcube);  
540 -  
541 - // Create energy boundaries  
542 - GEbounds ebounds = create_ebounds();  
543 -  
544 - // Create dummy sky map cube  
545 - GSkymap map("CAR","GAL",0.0,0.0,1.0,1.0,1,1,ebounds.size());  
546 - m_append_cube = true;  
547 -  
548 - // Create event cube  
549 - GCTAEventCube cube(map, ebounds, exposure.gti());  
550 -  
551 - // Create CTA observation  
552 - GCTAObservation cta;  
553 - cta.events(cube);  
554 - cta.response(exposure, psf, background);  
555 -  
556 - // Append observation to container  
557 - m_obs.append(cta);  
558 -  
559 - } // endif: cube response information was available  
560 -  
561 - // ... otherwise build an observation from IRF response information  
562 - else {  
563 -  
564 - // Create CTA observation  
565 - GCTAObservation cta = create_cta_obs();  
566 -  
567 - // Set response  
568 - set_obs_response(&cta);  
569 -  
570 - // Append observation to container  
571 - m_obs.append(cta);  
572 -  
573 - }  
574 -  
575 - } // endif: filename was "NONE" or ""  
576 -  
577 - // ... otherwise we have a file name  
578 - else {  
579 -  
580 - // If file is a FITS file then create an empty CTA observation  
581 - // and load file into observation  
582 - if (gammalib::is_fits(filename)) {  
583 -  
584 - // Allocate empty CTA observation  
585 - GCTAObservation cta;  
586 -  
587 - // Load data  
588 - cta.load(filename);  
589 -  
590 - // Set response  
591 - set_obs_response(&cta);  
592 -  
593 - // Append observation to container  
594 - m_obs.append(cta);  
595 -  
596 - // Signal that no XML file should be used for storage  
597 - m_use_xml = false;  
598 -  
599 - }  
600 -  
601 - // ... otherwise load file into observation container  
602 - else {  
603 -  
604 - // Load observations from XML file  
605 - m_obs.load(filename);  
606 -  
607 - // For all observations that have no response, set the response  
608 - // from the task parameters  
609 - set_response(m_obs);  
610 -  
611 - // Set observation boundary parameters (emin, emax, rad)  
612 - set_obs_bounds(m_obs);  
613 -  
614 - // Signal that XML file should be used for storage  
615 - m_use_xml = true;  
616 -  
617 - } // endelse: file was an XML file  
618 -  
619 - }  
620 -  
621 - // Return  
622 - return;  
623 -  
624 -}  
625 -  
626 -  
627 -/***********************************************************************//**  
628 * @brief Fill model into model cube 508 * @brief Fill model into model cube
629 * 509 *
630 * @param[in] obs CTA observation. 510 * @param[in] obs CTA observation.
src/ctmodel/ctmodel.hpp
@@ -79,7 +79,6 @@ protected: @@ -79,7 +79,6 @@ protected:
79 void copy_members(const ctmodel& app); 79 void copy_members(const ctmodel& app);
80 void free_members(void); 80 void free_members(void);
81 void get_parameters(void); 81 void get_parameters(void);
82 - void get_obs(void);  
83 void fill_cube(const GCTAObservation* obs); 82 void fill_cube(const GCTAObservation* obs);
84 bool has_cube(void) const; 83 bool has_cube(void) const;
85 84
src/ctobssim/ctobssim.cpp
@@ -340,6 +340,17 @@ void ctobssim::run(void) @@ -340,6 +340,17 @@ void ctobssim::run(void)
340 } 340 }
341 } 341 }
342 342
  343 + // Skip observation if we don't have an unbinned observation
  344 + if (obs->eventtype() != "EventList") {
  345 +
  346 + // Log that we skip the this observation
  347 + if (logTerse()) {
  348 + log << "Warning: Skipping binned observation \""+obs->name()+"\"";
  349 + log << std::endl;
  350 + }
  351 + continue;
  352 + }
  353 +
343 // Work on a clone of the CTA observation. This makes sure that 354 // Work on a clone of the CTA observation. This makes sure that
344 // any memory allocated for computing (for example a response 355 // any memory allocated for computing (for example a response
345 // cache) is properly de-allocated on exit of this run 356 // cache) is properly de-allocated on exit of this run
src/ctpsfcube/ctpsfcube.cpp
@@ -247,7 +247,7 @@ void ctpsfcube::run(void) @@ -247,7 +247,7 @@ void ctpsfcube::run(void)
247 } 247 }
248 248
249 // Fill PSF 249 // Fill PSF
250 - m_psfcube.fill(m_obs); 250 + m_psfcube.fill(m_obs, &log);
251 251
252 // Restore energy dispersion flag for all CTA observations 252 // Restore energy dispersion flag for all CTA observations
253 for (int i = 0; i < m_obs.size(); ++i) { 253 for (int i = 0; i < m_obs.size(); ++i) {
src/ctselect/ctselect.cpp
@@ -268,6 +268,17 @@ void ctselect::run(void) @@ -268,6 +268,17 @@ void ctselect::run(void)
268 // Save event file name (for possible saving) 268 // Save event file name (for possible saving)
269 m_infiles[i] = obs->eventfile(); 269 m_infiles[i] = obs->eventfile();
270 270
  271 + // Skip observation if we don't have an unbinned observation
  272 + if (obs->eventtype() != "EventList") {
  273 +
  274 + // Log that we skip the this observation
  275 + if (logTerse()) {
  276 + log << "Warning: Skipping binned observation \""+obs->name()+"\"";
  277 + log << std::endl;
  278 + }
  279 + continue;
  280 + }
  281 +
271 // Fall through in case that the event file is empty 282 // Fall through in case that the event file is empty
272 if (obs->events()->size() == 0) { 283 if (obs->events()->size() == 0) {
273 if (logTerse()) { 284 if (logTerse()) {
@@ -1218,28 +1229,33 @@ void ctselect::save_event_list(const GCTAObservation* obs, @@ -1218,28 +1229,33 @@ void ctselect::save_event_list(const GCTAObservation* obs,
1218 // Save only if observation is valid 1229 // Save only if observation is valid
1219 if (obs != NULL) { 1230 if (obs != NULL) {
1220 1231
1221 - // Save observation into FITS file  
1222 - obs->save(outfile, clobber());  
1223 -  
1224 - // Copy all extensions other than EVENTS and GTI from the input to  
1225 - // the output event list. The EVENTS and GTI extensions are written  
1226 - // by the save method, all others that may eventually be present  
1227 - // have to be copied by hand.  
1228 - GFits infits(infile);  
1229 - GFits outfits(outfile);  
1230 - for (int extno = 1; extno < infits.size(); ++extno) {  
1231 - GFitsHDU* hdu = infits.at(extno);  
1232 - if (hdu->extname() != "EVENTS" && hdu->extname() != "GTI") {  
1233 - outfits.append(*hdu); 1232 + // Save only if we have an event list
  1233 + if (obs->eventtype() == "EventList") {
  1234 +
  1235 + // Save observation into FITS file
  1236 + obs->save(outfile, clobber());
  1237 +
  1238 + // Copy all extensions other than EVENTS and GTI from the input to
  1239 + // the output event list. The EVENTS and GTI extensions are written
  1240 + // by the save method, all others that may eventually be present
  1241 + // have to be copied by hand.
  1242 + GFits infits(infile);
  1243 + GFits outfits(outfile);
  1244 + for (int extno = 1; extno < infits.size(); ++extno) {
  1245 + GFitsHDU* hdu = infits.at(extno);
  1246 + if (hdu->extname() != "EVENTS" && hdu->extname() != "GTI") {
  1247 + outfits.append(*hdu);
  1248 + }
1234 } 1249 }
1235 - }  
1236 1250
1237 - // Close input file  
1238 - infits.close(); 1251 + // Close input file
  1252 + infits.close();
  1253 +
  1254 + // Save file to disk and close it (we need both operations)
  1255 + outfits.save(true);
  1256 + outfits.close();
1239 1257
1240 - // Save file to disk and close it (we need both operations)  
1241 - outfits.save(true);  
1242 - outfits.close(); 1258 + } // endif: observation was unbinned
1243 1259
1244 } // endif: observation was valid 1260 } // endif: observation was valid
1245 1261
src/ctskymap/ctskymap.cpp
@@ -263,6 +263,17 @@ void ctskymap::run(void) @@ -263,6 +263,17 @@ void ctskymap::run(void)
263 } 263 }
264 } 264 }
265 265
  266 + // Skip observation if we don't have an unbinned observation
  267 + if (obs->eventtype() != "EventList") {
  268 +
  269 + // Log that we skip the this observation
  270 + if (logTerse()) {
  271 + log << "Warning: Skipping binned observation \""+obs->name()+"\"";
  272 + log << std::endl;
  273 + }
  274 + continue;
  275 + }
  276 +
266 // Map events into sky map 277 // Map events into sky map
267 map_events(obs); 278 map_events(obs);
268 279