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 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 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -198,8 +198,11 @@ void ctbin::clear(void)
198 198 /***********************************************************************//**
199 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 207 void ctbin::execute(void)
205 208 {
... ... @@ -220,14 +223,20 @@ void ctbin::execute(void)
220 223  
221 224 /***********************************************************************//**
222 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 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 236 log.cout(true);
  237 + }
229 238  
230   - // Get parameters
  239 + // Get task parameters
231 240 get_parameters();
232 241  
233 242 // Write parameters into logger
... ... @@ -239,25 +248,35 @@ void ctbin::run(void)
239 248 // Write observation(s) into logger
240 249 if (logTerse()) {
241 250 log << std::endl;
242   - if (m_obs.size() > 1)
  251 + if (m_obs.size() > 1) {
243 252 log.header1("Observations");
244   - else
  253 + }
  254 + else {
245 255 log.header1("Observation");
  256 + }
246 257 log << m_obs << std::endl;
247 258 }
248 259  
249 260 // Write header
250 261 if (logTerse()) {
251 262 log << std::endl;
252   - if (m_obs.size() > 1)
  263 + if (m_obs.size() > 1) {
253 264 log.header1("Bin observations");
254   - else
  265 + }
  266 + else {
255 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 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 280 // Get CTA observation
262 281 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(&m_obs[i]);
263 282  
... ... @@ -266,12 +285,20 @@ void ctbin::run(void)
266 285  
267 286 // Write header for observation
268 287 if (logTerse()) {
269   - if (obs->name().length() > 1)
  288 + if (obs->name().length() > 1) {
270 289 log.header3("Observation "+obs->name());
271   - else
  290 + }
  291 + else {
272 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 302 // Bin events into counts map
276 303 bin_events(obs);
277 304  
... ... @@ -279,13 +306,21 @@ void ctbin::run(void)
279 306  
280 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 315 // Write observation(s) into logger
283 316 if (logTerse()) {
284 317 log << std::endl;
285   - if (m_obs.size() > 1)
  318 + if (m_obs.size() > 1) {
286 319 log.header1("Binned observations");
287   - else
  320 + }
  321 + else {
288 322 log.header1("Binned observation");
  323 + }
289 324 log << m_obs << std::endl;
290 325 }
291 326  
... ... @@ -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 349 void ctbin::save(void)
303 350 {
304 351 // Write header
305 352 if (logTerse()) {
306 353 log << std::endl;
307   - if (m_obs.size() > 1)
  354 + if (m_obs.size() > 1) {
308 355 log.header1("Save observations");
309   - else
  356 + }
  357 + else {
310 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 372 // Return
343 373 return;
... ... @@ -362,13 +392,34 @@ void ctbin::get_parameters(void)
362 392 // Get name of CTA events file
363 393 m_evfile = (*this)["evfile"].filename();
364 394  
365   - // Load unbinned CTA observation
  395 + // Allocate CTA observation
366 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 423 // Use the xref and yref parameters for binning (otherwise the
373 424 // pointing direction(s) is/are used)
374 425 m_xref = (*this)["xref"].real();
... ... @@ -405,6 +456,10 @@ void ctbin::get_parameters(void)
405 456 * and replaces the event list by the counts map in the observation. The
406 457 * energy boundaries of the counts map are also stored in the observation's
407 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 464 void ctbin::bin_events(GCTAObservation* obs)
410 465 {
... ... @@ -413,8 +468,9 @@ void ctbin::bin_events(GCTAObservation* obs)
413 468  
414 469 // Make sure that the observation holds a CTA event list. If this
415 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 472 throw GException::no_list(G_BIN_EVENTS);
  473 + }
418 474  
419 475 // Setup energy range covered by data
420 476 GEnergy emin;
... ... @@ -541,9 +597,9 @@ void ctbin::init_members(void)
541 597 // Initialise members
542 598 m_evfile.clear();
543 599 m_outfile.clear();
  600 + m_prefix.clear();
544 601 m_proj.clear();
545 602 m_coordsys.clear();
546   - m_obs.clear();
547 603 m_emin = 0.0;
548 604 m_emax = 0.0;
549 605 m_enumbins = 0;
... ... @@ -553,6 +609,11 @@ void ctbin::init_members(void)
553 609 m_nxpix = 0;
554 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 617 // Set logger properties
557 618 log.date(true);
558 619  
... ... @@ -571,9 +632,9 @@ void ctbin::copy_members(const ctbin&amp; app)
571 632 // Copy attributes
572 633 m_evfile = app.m_evfile;
573 634 m_outfile = app.m_outfile;
  635 + m_prefix = app.m_prefix;
574 636 m_proj = app.m_proj;
575 637 m_coordsys = app.m_coordsys;
576   - m_obs = app.m_obs;
577 638 m_emin = app.m_emin;
578 639 m_emax = app.m_emax;
579 640 m_enumbins = app.m_enumbins;
... ... @@ -583,6 +644,11 @@ void ctbin::copy_members(const ctbin&amp; app)
583 644 m_nxpix = app.m_nxpix;
584 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 652 // Return
587 653 return;
588 654 }
... ... @@ -594,8 +660,125 @@ void ctbin::copy_members(const ctbin&amp; app)
594 660 void ctbin::free_members(void)
595 661 {
596 662 // Write separator into logger
597   - if (logTerse())
  663 + if (logTerse()) {
598 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 783 // Return
601 784 return;
... ...
src/ctbin/ctbin.hpp
1 1 /***************************************************************************
2 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 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -41,7 +41,11 @@
41 41 *
42 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 50 class ctbin : public GApplication {
47 51 public:
... ... @@ -66,26 +70,34 @@ public:
66 70  
67 71 protected:
68 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 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 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 103 #endif /* CTBIN_HPP */
... ...
src/ctbin/ctbin.par
... ... @@ -5,10 +5,10 @@
5 5 # ------------------------------------------------------------------------- #
6 6 # #
7 7 # File: ctbin.par #
8   -# Version: 00-02-02 #
  8 +# Version: 00-03-00 #
9 9 # #
10 10 # Author: Jurgen Knodlseder #
11   -# knodlseder@cesr.fr #
  11 +# Jurgen.Knodlseder@irap.omp.eu #
12 12 # IRAP #
13 13 # #
14 14 # Purpose: Parameter file for the ctbin application #
... ... @@ -17,8 +17,9 @@
17 17 #
18 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 24 # Energy binning parameters
24 25 #==========================
... ...