Commit 4100ccb57291b93d1c214c47ae6697c0f33c1d6d

Authored by knodlseder
1 parent 8bfc3d73

Supports now also reading of observations from an observation definition XML file.

src/ctbin/ctbin.cpp
1 /*************************************************************************** 1 /***************************************************************************
2 * ctbin - CTA data binning tool * 2 * ctbin - CTA data binning tool *
3 * ----------------------------------------------------------------------- * 3 * ----------------------------------------------------------------------- *
4 - * copyright (C) 2010-2011 by Juergen Knoedlseder * 4 + * copyright (C) 2010-2012 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- * 5 * ----------------------------------------------------------------------- *
6 * * 6 * *
7 * This program is free software: you can redistribute it and/or modify * 7 * This program is free software: you can redistribute it and/or modify *
@@ -198,8 +198,11 @@ void ctbin::clear(void) @@ -198,8 +198,11 @@ void ctbin::clear(void)
198 /***********************************************************************//** 198 /***********************************************************************//**
199 * @brief Execute application 199 * @brief Execute application
200 * 200 *
201 - * This method bins the events data into a counts maps and saves the counts  
202 - * map into a FITS file. 201 + * This is the main execution method of the ctbin class. It is invoked when
  202 + * the executable is called from command line.
  203 + *
  204 + * The method reads the task parameters, bins the event list(s) into counts
  205 + * map(s), and writes the results into FITS files on disk.
203 ***************************************************************************/ 206 ***************************************************************************/
204 void ctbin::execute(void) 207 void ctbin::execute(void)
205 { 208 {
@@ -220,14 +223,20 @@ void ctbin::execute(void) @@ -220,14 +223,20 @@ void ctbin::execute(void)
220 223
221 /***********************************************************************//** 224 /***********************************************************************//**
222 * @brief Bin the event data 225 * @brief Bin the event data
  226 + *
  227 + * This method loops over all observations found in the observation conatiner
  228 + * and bins all events from the event list(s) into counts map(s). Note that
  229 + * each event list is binned in a separate counts map, hence no summing of
  230 + * events is done.
223 ***************************************************************************/ 231 ***************************************************************************/
224 void ctbin::run(void) 232 void ctbin::run(void)
225 { 233 {
226 - // Switch screen logging on in debug mode  
227 - if (logDebug()) 234 + // If we're in debug mode then all output is also dumped on the screen
  235 + if (logDebug()) {
228 log.cout(true); 236 log.cout(true);
  237 + }
229 238
230 - // Get parameters 239 + // Get task parameters
231 get_parameters(); 240 get_parameters();
232 241
233 // Write parameters into logger 242 // Write parameters into logger
@@ -239,25 +248,35 @@ void ctbin::run(void) @@ -239,25 +248,35 @@ void ctbin::run(void)
239 // Write observation(s) into logger 248 // Write observation(s) into logger
240 if (logTerse()) { 249 if (logTerse()) {
241 log << std::endl; 250 log << std::endl;
242 - if (m_obs.size() > 1) 251 + if (m_obs.size() > 1) {
243 log.header1("Observations"); 252 log.header1("Observations");
244 - else 253 + }
  254 + else {
245 log.header1("Observation"); 255 log.header1("Observation");
  256 + }
246 log << m_obs << std::endl; 257 log << m_obs << std::endl;
247 } 258 }
248 259
249 // Write header 260 // Write header
250 if (logTerse()) { 261 if (logTerse()) {
251 log << std::endl; 262 log << std::endl;
252 - if (m_obs.size() > 1) 263 + if (m_obs.size() > 1) {
253 log.header1("Bin observations"); 264 log.header1("Bin observations");
254 - else 265 + }
  266 + else {
255 log.header1("Bin observation"); 267 log.header1("Bin observation");
  268 + }
256 } 269 }
257 270
258 - // Loop over all observation in the container 271 + // Initialise observation counter
  272 + int n_observations = 0;
  273 +
  274 + // Loop over all observations in the container
259 for (int i = 0; i < m_obs.size(); ++i) { 275 for (int i = 0; i < m_obs.size(); ++i) {
260 276
  277 + // Initialise event input and output filenames
  278 + m_infiles.push_back("");
  279 +
261 // Get CTA observation 280 // Get CTA observation
262 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(&m_obs[i]); 281 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(&m_obs[i]);
263 282
@@ -266,12 +285,20 @@ void ctbin::run(void) @@ -266,12 +285,20 @@ void ctbin::run(void)
266 285
267 // Write header for observation 286 // Write header for observation
268 if (logTerse()) { 287 if (logTerse()) {
269 - if (obs->name().length() > 1) 288 + if (obs->name().length() > 1) {
270 log.header3("Observation "+obs->name()); 289 log.header3("Observation "+obs->name());
271 - else 290 + }
  291 + else {
272 log.header3("Observation"); 292 log.header3("Observation");
  293 + }
273 } 294 }
274 295
  296 + // Increment number of observations
  297 + n_observations++;
  298 +
  299 + // Save event file name (for possible saving)
  300 + m_infiles[i] = obs->eventfile();
  301 +
275 // Bin events into counts map 302 // Bin events into counts map
276 bin_events(obs); 303 bin_events(obs);
277 304
@@ -279,13 +306,21 @@ void ctbin::run(void) @@ -279,13 +306,21 @@ void ctbin::run(void)
279 306
280 } // endfor: looped over observations 307 } // endfor: looped over observations
281 308
  309 + // If more than a single observation has been handled then make sure
  310 + // that an XML file will be used for storage
  311 + if (n_observations > 1) {
  312 + m_use_xml = true;
  313 + }
  314 +
282 // Write observation(s) into logger 315 // Write observation(s) into logger
283 if (logTerse()) { 316 if (logTerse()) {
284 log << std::endl; 317 log << std::endl;
285 - if (m_obs.size() > 1) 318 + if (m_obs.size() > 1) {
286 log.header1("Binned observations"); 319 log.header1("Binned observations");
287 - else 320 + }
  321 + else {
288 log.header1("Binned observation"); 322 log.header1("Binned observation");
  323 + }
289 log << m_obs << std::endl; 324 log << m_obs << std::endl;
290 } 325 }
291 326
@@ -295,49 +330,44 @@ void ctbin::run(void) @@ -295,49 +330,44 @@ void ctbin::run(void)
295 330
296 331
297 /***********************************************************************//** 332 /***********************************************************************//**
298 - * @brief Save observation 333 + * @brief Save counts map(s)
299 * 334 *
300 - * This method saves the counts map(s) into (a) FITS file(s). 335 + * This method saves the counts map(s) into FITS file(s). There are two
  336 + * modes, depending on the m_use_xml flag.
  337 + *
  338 + * If m_use_xml is true, all counts map(s) will be saved into FITS files,
  339 + * where the output filenames are constructued from the input filenames by
  340 + * prepending the m_prefix string to name. Any path information will be
  341 + * stripped form the input name, hence event files will be written into the
  342 + * local working directory (unless some path information is present
  343 + * in the prefix). In addition, an XML file will be created that gathers
  344 + * the filename information for the counts map(s). If an XML file was present
  345 + * on input, all metadata information will be copied from this input file.
  346 + *
  347 + * If m_use_xml is false, the counts map will be saved into a FITS file.
301 ***************************************************************************/ 348 ***************************************************************************/
302 void ctbin::save(void) 349 void ctbin::save(void)
303 { 350 {
304 // Write header 351 // Write header
305 if (logTerse()) { 352 if (logTerse()) {
306 log << std::endl; 353 log << std::endl;
307 - if (m_obs.size() > 1) 354 + if (m_obs.size() > 1) {
308 log.header1("Save observations"); 355 log.header1("Save observations");
309 - else 356 + }
  357 + else {
310 log.header1("Save observation"); 358 log.header1("Save observation");
  359 + }
311 } 360 }
312 361
313 - // Get output filename  
314 - m_outfile = (*this)["outfile"].filename();  
315 -  
316 - // Loop over all observations in the container  
317 - int file_num = 0;  
318 - for (int i = 0; i < m_obs.size(); ++i) {  
319 -  
320 - // Get CTA observation  
321 - GCTAObservation* obs = dynamic_cast<GCTAObservation*>(&m_obs[i]);  
322 -  
323 - // Save only if observation is a CTA observation  
324 - if (obs != NULL) {  
325 -  
326 - // Set filename. If more than one file will be created an  
327 - // index "_xxx" will be appended.  
328 - std::string filename = m_outfile;  
329 - if (file_num > 0)  
330 - filename += "_"+str(file_num);  
331 -  
332 - // Save file  
333 - obs->save(filename, clobber());  
334 -  
335 - // Increment file number  
336 - file_num++;  
337 -  
338 - } // endif: observation was a CTA observation 362 + // Case A: Save counts map(s) and XML metadata information
  363 + if (m_use_xml) {
  364 + save_xml();
  365 + }
339 366
340 - } // endfor: looped over files 367 + // Case B: Save counts map as FITS file
  368 + else {
  369 + save_fits();
  370 + }
341 371
342 // Return 372 // Return
343 return; 373 return;
@@ -362,13 +392,34 @@ void ctbin::get_parameters(void) @@ -362,13 +392,34 @@ void ctbin::get_parameters(void)
362 // Get name of CTA events file 392 // Get name of CTA events file
363 m_evfile = (*this)["evfile"].filename(); 393 m_evfile = (*this)["evfile"].filename();
364 394
365 - // Load unbinned CTA observation 395 + // Allocate CTA observation
366 GCTAObservation obs; 396 GCTAObservation obs;
367 - obs.load_unbinned(m_evfile);  
368 397
369 - // Append CTA observation to container  
370 - m_obs.append(obs); 398 + // Try first to open as FITS file
  399 + try {
  400 +
  401 + // Load event list in CTA observation
  402 + obs.load_unbinned(m_evfile);
  403 +
  404 + // Append CTA observation to container
  405 + m_obs.append(obs);
  406 +
  407 + // Signal that no XML file should be used for storage
  408 + m_use_xml = false;
  409 +
  410 + }
371 411
  412 + // ... otherwise try to open as XML file
  413 + catch (GException::fits_open_error) {
  414 +
  415 + // Load observations from XML file
  416 + m_obs.load(m_evfile);
  417 +
  418 + // Signal that XML file should be used for storage
  419 + m_use_xml = true;
  420 +
  421 + }
  422 +
372 // Use the xref and yref parameters for binning (otherwise the 423 // Use the xref and yref parameters for binning (otherwise the
373 // pointing direction(s) is/are used) 424 // pointing direction(s) is/are used)
374 m_xref = (*this)["xref"].real(); 425 m_xref = (*this)["xref"].real();
@@ -405,6 +456,10 @@ void ctbin::get_parameters(void) @@ -405,6 +456,10 @@ void ctbin::get_parameters(void)
405 * and replaces the event list by the counts map in the observation. The 456 * and replaces the event list by the counts map in the observation. The
406 * energy boundaries of the counts map are also stored in the observation's 457 * energy boundaries of the counts map are also stored in the observation's
407 * energy boundary member. 458 * energy boundary member.
  459 + *
  460 + * If the reference values for the map centre (m_xref, m_yref) are 9999.0,
  461 + * the pointing direction of the observation is taken as the map centre.
  462 + * Otherwise, the specified reference value is used.
408 ***************************************************************************/ 463 ***************************************************************************/
409 void ctbin::bin_events(GCTAObservation* obs) 464 void ctbin::bin_events(GCTAObservation* obs)
410 { 465 {
@@ -413,8 +468,9 @@ void ctbin::bin_events(GCTAObservation* obs) @@ -413,8 +468,9 @@ void ctbin::bin_events(GCTAObservation* obs)
413 468
414 // Make sure that the observation holds a CTA event list. If this 469 // Make sure that the observation holds a CTA event list. If this
415 // is not the case then throw an exception. 470 // is not the case then throw an exception.
416 - if (dynamic_cast<const GCTAEventList*>(obs->events()) == NULL) 471 + if (dynamic_cast<const GCTAEventList*>(obs->events()) == NULL) {
417 throw GException::no_list(G_BIN_EVENTS); 472 throw GException::no_list(G_BIN_EVENTS);
  473 + }
418 474
419 // Setup energy range covered by data 475 // Setup energy range covered by data
420 GEnergy emin; 476 GEnergy emin;
@@ -541,9 +597,9 @@ void ctbin::init_members(void) @@ -541,9 +597,9 @@ void ctbin::init_members(void)
541 // Initialise members 597 // Initialise members
542 m_evfile.clear(); 598 m_evfile.clear();
543 m_outfile.clear(); 599 m_outfile.clear();
  600 + m_prefix.clear();
544 m_proj.clear(); 601 m_proj.clear();
545 m_coordsys.clear(); 602 m_coordsys.clear();
546 - m_obs.clear();  
547 m_emin = 0.0; 603 m_emin = 0.0;
548 m_emax = 0.0; 604 m_emax = 0.0;
549 m_enumbins = 0; 605 m_enumbins = 0;
@@ -553,6 +609,11 @@ void ctbin::init_members(void) @@ -553,6 +609,11 @@ void ctbin::init_members(void)
553 m_nxpix = 0; 609 m_nxpix = 0;
554 m_nypix = 0; 610 m_nypix = 0;
555 611
  612 + // Initialise protected members
  613 + m_obs.clear();
  614 + m_infiles.clear();
  615 + m_use_xml = false;
  616 +
556 // Set logger properties 617 // Set logger properties
557 log.date(true); 618 log.date(true);
558 619
@@ -571,9 +632,9 @@ void ctbin::copy_members(const ctbin&amp; app) @@ -571,9 +632,9 @@ void ctbin::copy_members(const ctbin&amp; app)
571 // Copy attributes 632 // Copy attributes
572 m_evfile = app.m_evfile; 633 m_evfile = app.m_evfile;
573 m_outfile = app.m_outfile; 634 m_outfile = app.m_outfile;
  635 + m_prefix = app.m_prefix;
574 m_proj = app.m_proj; 636 m_proj = app.m_proj;
575 m_coordsys = app.m_coordsys; 637 m_coordsys = app.m_coordsys;
576 - m_obs = app.m_obs;  
577 m_emin = app.m_emin; 638 m_emin = app.m_emin;
578 m_emax = app.m_emax; 639 m_emax = app.m_emax;
579 m_enumbins = app.m_enumbins; 640 m_enumbins = app.m_enumbins;
@@ -583,6 +644,11 @@ void ctbin::copy_members(const ctbin&amp; app) @@ -583,6 +644,11 @@ void ctbin::copy_members(const ctbin&amp; app)
583 m_nxpix = app.m_nxpix; 644 m_nxpix = app.m_nxpix;
584 m_nypix = app.m_nypix; 645 m_nypix = app.m_nypix;
585 646
  647 + // Copy protected members
  648 + m_obs = app.m_obs;
  649 + m_infiles = app.m_infiles;
  650 + m_use_xml = app.m_use_xml;
  651 +
586 // Return 652 // Return
587 return; 653 return;
588 } 654 }
@@ -594,8 +660,125 @@ void ctbin::copy_members(const ctbin&amp; app) @@ -594,8 +660,125 @@ void ctbin::copy_members(const ctbin&amp; app)
594 void ctbin::free_members(void) 660 void ctbin::free_members(void)
595 { 661 {
596 // Write separator into logger 662 // Write separator into logger
597 - if (logTerse()) 663 + if (logTerse()) {
598 log << std::endl; 664 log << std::endl;
  665 + }
  666 +
  667 + // Return
  668 + return;
  669 +}
  670 +
  671 +
  672 +/***********************************************************************//**
  673 + * @brief Set output file name.
  674 + *
  675 + * @param[in] filename Input file name.
  676 + *
  677 + * This method converts an input filename into an output filename by
  678 + * prepending the prefix specified by m_prefix to the input filename. Any
  679 + * path will be stripped from the input filename.
  680 + ***************************************************************************/
  681 +std::string ctbin::set_outfile_name(const std::string& filename) const
  682 +{
  683 + // Split input filename into path elements
  684 + std::vector<std::string> elements = split(filename, "/");
  685 +
  686 + // The last path element is the filename
  687 + std::string outname = m_prefix + elements[elements.size()-1];
  688 +
  689 + // Return output filename
  690 + return outname;
  691 +}
  692 +
  693 +
  694 +/***********************************************************************//**
  695 + * @brief Save counts map in FITS format.
  696 + *
  697 + * Save the counts map as a FITS file. The filename of the FITS file is
  698 + * specified by the m_outfile member.
  699 + ***************************************************************************/
  700 +void ctbin::save_fits(void)
  701 +{
  702 + // Get output filename
  703 + m_outfile = (*this)["outfile"].value();
  704 +
  705 + // Get CTA observation from observation container
  706 + GCTAObservation* obs = dynamic_cast<GCTAObservation*>(&m_obs[0]);
  707 +
  708 + // Save event list
  709 + save_counts_map(obs, m_outfile);
  710 +
  711 + // Return
  712 + return;
  713 +}
  714 +
  715 +
  716 +/***********************************************************************//**
  717 + * @brief Save counts map(s) in XML format.
  718 + *
  719 + * Save the counts map(s) into FITS files and write the file path information
  720 + * into a XML file. The filename of the XML file is specified by the
  721 + * m_outfile member, the filename(s) of the counts map(s) are built by
  722 + * prepending the prefix given by the m_prefix member to the input counts
  723 + * map(s) filenames. Any path present in the input filename will be stripped,
  724 + * i.e. the counts map(s) will be written in the local working directory
  725 + * (unless a path is specified in the m_prefix member).
  726 + ***************************************************************************/
  727 +void ctbin::save_xml(void)
  728 +{
  729 + // Get output filename and prefix
  730 + m_outfile = (*this)["outfile"].value();
  731 + m_prefix = (*this)["prefix"].value();
  732 +
  733 + // Loop over all observation in the container
  734 + for (int i = 0; i < m_obs.size(); ++i) {
  735 +
  736 + // Get CTA observation
  737 + GCTAObservation* obs = dynamic_cast<GCTAObservation*>(&m_obs[i]);
  738 +
  739 + // Handle only CTA observations
  740 + if (obs != NULL) {
  741 +
  742 + // Set event output file name
  743 + std::string outfile = set_outfile_name(m_infiles[i]);
  744 +
  745 + // Store output file name in observation
  746 + obs->eventfile(outfile);
  747 +
  748 + // Save event list
  749 + save_counts_map(obs, outfile);
  750 +
  751 + } // endif: observation was a CTA observations
  752 +
  753 + } // endfor: looped over observations
  754 +
  755 + // Save observations in XML file
  756 + m_obs.save(m_outfile);
  757 +
  758 + // Return
  759 + return;
  760 +}
  761 +
  762 +
  763 +/***********************************************************************//**
  764 + * @brief Save a single counts map into a FITS file
  765 + *
  766 + * @param[in] obs Pointer to CTA observation.
  767 + * @param[in] outfile Output file name.
  768 + *
  769 + * This method saves a single counts map into a FITS file. The method does
  770 + * nothing if the observation pointer is not valid.
  771 + ***************************************************************************/
  772 +void ctbin::save_counts_map(const GCTAObservation* obs,
  773 + const std::string& outfile) const
  774 +{
  775 + // Save only if observation is valid
  776 + if (obs != NULL) {
  777 +
  778 + // Save observation into FITS file
  779 + obs->save(outfile, clobber());
  780 +
  781 + } // endif: observation was valid
599 782
600 // Return 783 // Return
601 return; 784 return;
src/ctbin/ctbin.hpp
1 /*************************************************************************** 1 /***************************************************************************
2 * ctbin - CTA data binning tool * 2 * ctbin - CTA data binning tool *
3 * ----------------------------------------------------------------------- * 3 * ----------------------------------------------------------------------- *
4 - * copyright (C) 2010-2011 by Juergen Knoedlseder * 4 + * copyright (C) 2010-2012 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- * 5 * ----------------------------------------------------------------------- *
6 * * 6 * *
7 * This program is free software: you can redistribute it and/or modify * 7 * This program is free software: you can redistribute it and/or modify *
@@ -41,7 +41,11 @@ @@ -41,7 +41,11 @@
41 * 41 *
42 * @brief CTA data binning tool interface defintion 42 * @brief CTA data binning tool interface defintion
43 * 43 *
44 - * This class bins CTA events into a counts map. 44 + * This class bins CTA event list(s) into a counts map(s). The class can
  45 + * operate on predefined observation containers, on individual event list
  46 + * FITS files, and on observation definition XML files. Results are stored
  47 + * in an observation container that can be written to disk in form of FITS
  48 + * files (counts maps) and an updated observation definition file.
45 ***************************************************************************/ 49 ***************************************************************************/
46 class ctbin : public GApplication { 50 class ctbin : public GApplication {
47 public: 51 public:
@@ -66,26 +70,34 @@ public: @@ -66,26 +70,34 @@ public:
66 70
67 protected: 71 protected:
68 // Protected methods 72 // Protected methods
69 - void init_members(void);  
70 - void copy_members(const ctbin& app);  
71 - void free_members(void); 73 + void init_members(void);
  74 + void copy_members(const ctbin& app);
  75 + void free_members(void);
  76 + std::string set_outfile_name(const std::string& filename) const;
  77 + void save_fits(void);
  78 + void save_xml(void);
  79 + void save_counts_map(const GCTAObservation* obs,
  80 + const std::string& outfile) const;
72 81
73 // User parameters 82 // User parameters
74 - std::string m_evfile; //!< Input event list  
75 - std::string m_outfile; //!< Output counts map  
76 - double m_emin; //!< Lower energy  
77 - double m_emax; //!< Upper energy  
78 - int m_enumbins; //!< Number of energy bins  
79 - std::string m_proj; //!< WCS projection  
80 - std::string m_coordsys; //!< Coordinate system  
81 - double m_xref; //!< Longitude reference coordinate  
82 - double m_yref; //!< Latitude reference coordinate  
83 - double m_binsz; //!< Pixel size  
84 - int m_nxpix; //!< Number of pixels in longitude  
85 - int m_nypix; //!< Number of pixels in latitude 83 + std::string m_evfile; //!< Input event list or XML file
  84 + std::string m_outfile; //!< Output counts map or XML file
  85 + std::string m_prefix; //!< Prefix for multiple counts maps
  86 + double m_emin; //!< Lower energy
  87 + double m_emax; //!< Upper energy
  88 + int m_enumbins; //!< Number of energy bins
  89 + std::string m_proj; //!< WCS projection
  90 + std::string m_coordsys; //!< Coordinate system
  91 + double m_xref; //!< Longitude reference coordinate
  92 + double m_yref; //!< Latitude reference coordinate
  93 + double m_binsz; //!< Pixel size
  94 + int m_nxpix; //!< Number of pixels in longitude
  95 + int m_nypix; //!< Number of pixels in latitude
86 96
87 // Protected members 97 // Protected members
88 - GObservations m_obs; //!< Observation container 98 + GObservations m_obs; //!< Observation container
  99 + std::vector<std::string> m_infiles; //!< Input event filenames
  100 + bool m_use_xml; //!< Use XML file instead of FITS file
89 }; 101 };
90 102
91 #endif /* CTBIN_HPP */ 103 #endif /* CTBIN_HPP */
src/ctbin/ctbin.par
@@ -5,10 +5,10 @@ @@ -5,10 +5,10 @@
5 # ------------------------------------------------------------------------- # 5 # ------------------------------------------------------------------------- #
6 # # 6 # #
7 # File: ctbin.par # 7 # File: ctbin.par #
8 -# Version: 00-02-02 # 8 +# Version: 00-03-00 #
9 # # 9 # #
10 # Author: Jurgen Knodlseder # 10 # Author: Jurgen Knodlseder #
11 -# knodlseder@cesr.fr # 11 +# Jurgen.Knodlseder@irap.omp.eu #
12 # IRAP # 12 # IRAP #
13 # # 13 # #
14 # Purpose: Parameter file for the ctbin application # 14 # Purpose: Parameter file for the ctbin application #
@@ -17,8 +17,9 @@ @@ -17,8 +17,9 @@
17 # 17 #
18 # General parameters 18 # General parameters
19 #=================== 19 #===================
20 -evfile, f, a, "test/data/crab_events.fits.gz",,,"Event data file name"  
21 -outfile, f, a, "cntmap.fits",,, "Output file name" 20 +evfile, f, a, "test/data/crab_events.fits.gz",,,"Event list or observation definition file"
  21 +outfile, f, a, "cntmap.fits",,, "Counts map or observation definition file"
  22 +prefix, s, h, "cntmap_",,,"Prefix for counts maps in observation definition file"
22 # 23 #
23 # Energy binning parameters 24 # Energy binning parameters
24 #========================== 25 #==========================