Commit db226c73e7d6915f2f3af074044c4cc978f49f23

Authored by Jürgen Knödlseder
1 parent 833ce7f7

ctbin now always merges event lists into a single counts cube.

WARNING: The philosophy behind the ctbin tool changed fundamentally!

ctbin now always produces a single counts cube on output. If a single event list is specified on input, the functionnality is basically unchanged. If multiple event lists are specified, however, events are now merged into a single counts cube file. No observation definition XML file is written anymore!

So far, ctbin still writes pointing information in the counts cube, although this is not necessarily meaningful if merging event lists with different pointings. In the long run, pointing information will be summarized in a pointings definition file, and will be removed from the counts cube header. The logic is that the pointing definition is set to the map centre. This is only identical to the pointing in case of binning a single event list and using the usepnt=yes option (or specifying the pointing manually as the xref and yref parameters).
ChangeLog
1 -2014-07-10 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu> 1 +2014-07-18 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu>
2 2
3 * Version 0.8.0 released 3 * Version 0.8.0 released
4 ======================== 4 ========================
5 5
  6 + ctbin now always merges event lists into a single counts cube
6 Add ctexpcube tool 7 Add ctexpcube tool
7 Support energy dispersion in ctobssim, ctlike and ctmodel 8 Support energy dispersion in ctobssim, ctlike and ctmodel
8 Correct ctobssim for thread safety 9 Correct ctobssim for thread safety
@@ -2,7 +2,7 @@ New Features and Important Changes in ctools 00-08-00 @@ -2,7 +2,7 @@ New Features and Important Changes in ctools 00-08-00
2 2
3 Author(s) : Juergen Knoedlseder 3 Author(s) : Juergen Knoedlseder
4 4
5 -10 July 2014 5 +18 July 2014
6 6
7 7
8 1. Introduction 8 1. Introduction
@@ -40,7 +40,22 @@ when iterating over ctselect (#1149). @@ -40,7 +40,22 @@ when iterating over ctselect (#1149).
40 40
41 6. ctbin - CTA event binning 41 6. ctbin - CTA event binning
42 ---------------------------- 42 ----------------------------
43 -None 43 +WARNING: The philosophy behind the ctbin tool changed fundamentally!
  44 +
  45 +ctbin now always produces a single counts cube on output. If a single
  46 +event list is specified on input, the functionnality is basically
  47 +unchanged. If multiple event lists are specified, however, events are
  48 +now merged into a single counts cube file. No observation definition
  49 +XML file is written anymore!
  50 +
  51 +So far, ctbin still writes pointing information in the counts cube,
  52 +although this is not necessarily meaningful if merging event lists
  53 +with different pointings. In the long run, pointing information will
  54 +be summarized in a pointings definition file, and will be removed
  55 +from the counts cube header. The logic is that the pointing definition
  56 +is set to the map centre. This is only identical to the pointing in
  57 +case of binning a single event list and using the usepnt=yes option
  58 +(or specifying the pointing manually as the xref and yref parameters).
44 59
45 60
46 7. ctlike - CTA maximum likelihood fitting 61 7. ctlike - CTA maximum likelihood fitting
pyext/ctbin.i
1 /*************************************************************************** 1 /***************************************************************************
2 * ctbin - CTA data binning tool * 2 * ctbin - CTA data binning tool *
3 * ----------------------------------------------------------------------- * 3 * ----------------------------------------------------------------------- *
4 - * copyright (C) 2010-2013 by Juergen Knoedlseder * 4 + * copyright (C) 2010-2014 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 *
@@ -50,8 +50,11 @@ public: @@ -50,8 +50,11 @@ public:
50 void run(void); 50 void run(void);
51 void save(void); 51 void save(void);
52 const GObservations& obs(void) const; 52 const GObservations& obs(void) const;
  53 + GCTAEventCube cube(void) const;
53 void get_parameters(void); 54 void get_parameters(void);
54 - void bin_events(GCTAObservation* obs); 55 + void init_cube(void);
  56 + void fill_cube(GCTAObservation* obs);
  57 + void obs_cube(void);
55 }; 58 };
56 59
57 60
src/ctbin/ctbin.cpp
@@ -34,10 +34,14 @@ @@ -34,10 +34,14 @@
34 34
35 /* __ Method name definitions ____________________________________________ */ 35 /* __ Method name definitions ____________________________________________ */
36 #define G_BIN_EVENTS "ctbin::bin_events(GCTAObservation*)" 36 #define G_BIN_EVENTS "ctbin::bin_events(GCTAObservation*)"
  37 +#define G_GET_EBOUNDS "ctbin::get_ebounds()"
  38 +#define G_INIT_CUBE "ctbin::init_cube()"
  39 +#define G_FILL_CUBE "ctbin::fill_cube(GCTAObservation*)"
37 40
38 /* __ Debug definitions __________________________________________________ */ 41 /* __ Debug definitions __________________________________________________ */
39 42
40 /* __ Coding definitions _________________________________________________ */ 43 /* __ Coding definitions _________________________________________________ */
  44 +#define G_MERGE_EVENTS
41 45
42 46
43 /*========================================================================== 47 /*==========================================================================
@@ -270,6 +274,11 @@ void ctbin::run(void) @@ -270,6 +274,11 @@ void ctbin::run(void)
270 // Initialise observation counter 274 // Initialise observation counter
271 int n_observations = 0; 275 int n_observations = 0;
272 276
  277 + // Compile option: if cube merging is requested, initialise the cube
  278 + #if defined(G_MERGE_EVENTS)
  279 + init_cube();
  280 + #endif
  281 +
273 // Loop over all observations in the container 282 // Loop over all observations in the container
274 for (int i = 0; i < m_obs.size(); ++i) { 283 for (int i = 0; i < m_obs.size(); ++i) {
275 284
@@ -298,13 +307,25 @@ void ctbin::run(void) @@ -298,13 +307,25 @@ void ctbin::run(void)
298 // Save event file name (for possible saving) 307 // Save event file name (for possible saving)
299 m_infiles[i] = obs->eventfile(); 308 m_infiles[i] = obs->eventfile();
300 309
301 - // Bin events into counts map 310 + // Compile option: if cube merging is requested, fill the cube;
  311 + // otherwise just bin the events
  312 + #if defined(G_MERGE_EVENTS)
  313 + fill_cube(obs);
  314 + #else
302 bin_events(obs); 315 bin_events(obs);
  316 + #endif
303 317
304 } // endif: CTA observation found 318 } // endif: CTA observation found
305 319
306 } // endfor: looped over observations 320 } // endfor: looped over observations
307 321
  322 + // Compile option: if cube merging is requested, set a single cube in
  323 + // the observation container
  324 + #if defined(G_MERGE_EVENTS)
  325 + obs_cube();
  326 + n_observations = 1;
  327 + #endif
  328 +
308 // If more than a single observation has been handled then make sure 329 // If more than a single observation has been handled then make sure
309 // that an XML file will be used for storage 330 // that an XML file will be used for storage
310 if (n_observations > 1) { 331 if (n_observations > 1) {
@@ -358,6 +379,12 @@ void ctbin::save(void) @@ -358,6 +379,12 @@ void ctbin::save(void)
358 } 379 }
359 } 380 }
360 381
  382 + // Compile option: if merging was requested, always save into a single
  383 + // FITS file
  384 + #if defined(G_MERGE_EVENTS)
  385 + save_fits();
  386 + #else
  387 +
361 /* 388 /*
362 // Case A: Save counts map(s) and XML metadata information 389 // Case A: Save counts map(s) and XML metadata information
363 if (m_use_xml) { 390 if (m_use_xml) {
@@ -371,6 +398,7 @@ void ctbin::save(void) @@ -371,6 +398,7 @@ void ctbin::save(void)
371 398
372 // Always save FITS and an XML summary 399 // Always save FITS and an XML summary
373 save_xml(); 400 save_xml();
  401 + #endif
374 402
375 // Return 403 // Return
376 return; 404 return;
@@ -423,11 +451,6 @@ void ctbin::get_parameters(void) @@ -423,11 +451,6 @@ void ctbin::get_parameters(void)
423 451
424 } 452 }
425 453
426 - // Use the xref and yref parameters for binning (otherwise the  
427 - // pointing direction(s) is/are used)  
428 - //m_xref = (*this)["xref"].real();  
429 - //m_yref = (*this)["yref"].real();  
430 -  
431 } // endif: there was no observation in the container 454 } // endif: there was no observation in the container
432 455
433 // Get parameters 456 // Get parameters
@@ -436,7 +459,12 @@ void ctbin::get_parameters(void) @@ -436,7 +459,12 @@ void ctbin::get_parameters(void)
436 m_xref = (*this)["xref"].real(); 459 m_xref = (*this)["xref"].real();
437 m_yref = (*this)["yref"].real(); 460 m_yref = (*this)["yref"].real();
438 } 461 }
439 - m_ebinalg = (*this)["ebinalg"].string(); 462 + m_proj = (*this)["proj"].string();
  463 + m_coordsys = (*this)["coordsys"].string();
  464 + m_binsz = (*this)["binsz"].real();
  465 + m_nxpix = (*this)["nxpix"].integer();
  466 + m_nypix = (*this)["nypix"].integer();
  467 + m_ebinalg = (*this)["ebinalg"].string();
440 468
441 // If we have the binning given by a file then read filename 469 // If we have the binning given by a file then read filename
442 if (m_ebinalg == "FILE") { 470 if (m_ebinalg == "FILE") {
@@ -449,11 +477,6 @@ void ctbin::get_parameters(void) @@ -449,11 +477,6 @@ void ctbin::get_parameters(void)
449 m_emax = (*this)["emax"].real(); 477 m_emax = (*this)["emax"].real();
450 m_enumbins = (*this)["enumbins"].integer(); 478 m_enumbins = (*this)["enumbins"].integer();
451 } 479 }
452 - m_proj = (*this)["proj"].string();  
453 - m_coordsys = (*this)["coordsys"].string();  
454 - m_binsz = (*this)["binsz"].real();  
455 - m_nxpix = (*this)["nxpix"].integer();  
456 - m_nypix = (*this)["nypix"].integer();  
457 480
458 // Optionally read ahead parameters so that they get correctly 481 // Optionally read ahead parameters so that they get correctly
459 // dumped into the log file 482 // dumped into the log file
@@ -664,6 +687,206 @@ void ctbin::bin_events(GCTAObservation* obs) @@ -664,6 +687,206 @@ void ctbin::bin_events(GCTAObservation* obs)
664 } 687 }
665 688
666 689
  690 +/***********************************************************************//**
  691 + * @brief Initialise counts cube information
  692 + *
  693 + * @exception GException::invalid_value
  694 + * No valid CTA observation found to derive the counts cube
  695 + * map centre.
  696 + *
  697 + * Initialises the skymap, energy boundaries and GTI for a counts cube.
  698 + ***************************************************************************/
  699 +void ctbin::init_cube(void)
  700 +{
  701 + // Initialse cube information
  702 + m_ontime = 0.0;
  703 + m_livetime = 0.0;
  704 + m_cube.clear();
  705 + m_ebounds.clear();
  706 + m_gti.clear();
  707 +
  708 + // Set event cube centre, either from the user parameters or from the
  709 + // pointing
  710 + double xref = m_xref;
  711 + double yref = m_yref;
  712 + if (m_usepnt) {
  713 +
  714 + // Dummy: get pointing from first observation. Ultimately, we want
  715 + // to get the pointing from a kind of average
  716 + bool found = false;
  717 + for (int i = 0; i < m_obs.size(); ++i) {
  718 + GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
  719 + if (obs != NULL) {
  720 + const GCTAPointing& pnt = obs->pointing();
  721 + if (gammalib::toupper(m_coordsys) == "GAL") {
  722 + xref = pnt.dir().l_deg();
  723 + yref = pnt.dir().b_deg();
  724 + }
  725 + else {
  726 + xref = pnt.dir().ra_deg();
  727 + yref = pnt.dir().dec_deg();
  728 + }
  729 + found = true;
  730 + break;
  731 + }
  732 + }
  733 +
  734 + // Signal if no pointing is found
  735 + if (!found) {
  736 + std::string msg = "No valid CTA observation has been found in "
  737 + "observation list, hence no pointing information "
  738 + "could be extracted. Use the \"usepnt=no\" "
  739 + "option and specify pointing explicitly when "
  740 + "running ctbin.";
  741 + throw GException::invalid_value(G_INIT_CUBE, msg);
  742 + }
  743 +
  744 + } // endif: used pointing
  745 +
  746 + // Create skymap
  747 + m_cube = GSkymap(m_proj, m_coordsys,
  748 + xref, yref, -m_binsz, m_binsz,
  749 + m_nxpix, m_nypix, m_enumbins);
  750 +
  751 + // Set energy boundaries
  752 + get_ebounds();
  753 +
  754 + // Return
  755 + return;
  756 +}
  757 +
  758 +
  759 +/***********************************************************************//**
  760 + * @brief Fill events into counts cube
  761 + *
  762 + * @param[in] obs CTA observation.
  763 + *
  764 + * @exception GException::no_list
  765 + * No event list found in observation.
  766 + *
  767 + * Fills the events from an event list in the counts cube setup by init_cube.
  768 + ***************************************************************************/
  769 +void ctbin::fill_cube(GCTAObservation* obs)
  770 +{
  771 + // Continue only if observation pointer is valid
  772 + if (obs != NULL) {
  773 +
  774 + // Make sure that the observation holds a CTA event list. If this
  775 + // is not the case then throw an exception.
  776 + if (dynamic_cast<const GCTAEventList*>(obs->events()) == NULL) {
  777 + throw GException::no_list(G_BIN_EVENTS);
  778 + }
  779 +
  780 + // Initialise binning statistics
  781 + int num_outside_map = 0;
  782 + int num_outside_ebds = 0;
  783 + int num_in_map = 0;
  784 +
  785 + // Fill sky map
  786 + GCTAEventList* events =
  787 + static_cast<GCTAEventList*>(const_cast<GEvents*>(obs->events()));
  788 + for (int i = 0; i < events->size(); ++i) {
  789 +
  790 + // Get event
  791 + GCTAEventAtom* event = (*events)[i];
  792 +
  793 + // Determine sky pixel
  794 + GCTAInstDir* inst = (GCTAInstDir*)&(event->dir());
  795 + GSkyDir dir = inst->dir();
  796 + GSkyPixel pixel = m_cube.dir2pix(dir);
  797 +
  798 + // Skip if pixel is out of range
  799 + if (pixel.x() < -0.5 || pixel.x() > (m_nxpix-0.5) ||
  800 + pixel.y() < -0.5 || pixel.y() > (m_nypix-0.5)) {
  801 + num_outside_map++;
  802 + continue;
  803 + }
  804 +
  805 + // Determine energy bin. Skip if we are outside the energy range
  806 + int index = m_ebounds.index(event->energy());
  807 + if (index == -1) {
  808 + num_outside_ebds++;
  809 + continue;
  810 + }
  811 +
  812 + // Fill event in skymap
  813 + m_cube(pixel, index) += 1.0;
  814 + num_in_map++;
  815 +
  816 + } // endfor: looped over all events
  817 +
  818 + // Append GTIs
  819 + m_gti.extend(events->gti());
  820 +
  821 + // Update ontime and livetime
  822 + m_ontime += obs->ontime();
  823 + m_livetime += obs->livetime();
  824 +
  825 + // Log filling results
  826 + if (logTerse()) {
  827 + log << gammalib::parformat("Events in list");
  828 + log << obs->events()->size() << std::endl;
  829 + log << gammalib::parformat("Events in cube");
  830 + log << num_in_map << std::endl;
  831 + log << gammalib::parformat("Events outside cube area");
  832 + log << num_outside_map << std::endl;
  833 + log << gammalib::parformat("Events outside energy bins");
  834 + log << num_outside_ebds << std::endl;
  835 + }
  836 +
  837 + // Log cube
  838 + if (logExplicit()) {
  839 + log.header1("Counts cube");
  840 + log << m_cube << std::endl;
  841 + }
  842 +
  843 + } // endif: observation was valid
  844 +
  845 + // Return
  846 + return;
  847 +}
  848 +
  849 +
  850 +/***********************************************************************//**
  851 + * @brief Put cube as single element in observation container.
  852 + ***************************************************************************/
  853 +void ctbin::obs_cube(void)
  854 +{
  855 + // Clear observation container
  856 + m_obs.clear();
  857 +
  858 + // Allocate CTA observation. We need this to make sure that all
  859 + // attributes are set correctly
  860 + GCTAObservation obs;
  861 +
  862 + // Attach event cube to CTA observation
  863 + obs.events(this->cube());
  864 +
  865 + // Set map centre as pointing
  866 + GSkyPixel pixel(0.5*double(m_cube.nx()), 0.5*double(m_cube.ny()));
  867 + GSkyDir centre = m_cube.pix2dir(pixel);
  868 + GCTAPointing pointing(centre);
  869 +
  870 + // Compute deadtime correction
  871 + double deadc = (m_ontime > 0.0) ? m_livetime / m_ontime : 0.0;
  872 +
  873 + // Set CTA observation attributes
  874 + obs.pointing(pointing);
  875 + obs.obs_id(0);
  876 + obs.ra_obj(centre.ra_deg()); //!< Dummy
  877 + obs.dec_obj(centre.dec_deg()); //!< Dummy
  878 + obs.ontime(m_ontime);
  879 + obs.livetime(m_livetime);
  880 + obs.deadc(deadc);
  881 +
  882 + // Append observation to container
  883 + m_obs.append(obs);
  884 +
  885 + // Return
  886 + return;
  887 +}
  888 +
  889 +
667 /*========================================================================== 890 /*==========================================================================
668 = = 891 = =
669 = Private methods = 892 = Private methods =
@@ -698,6 +921,11 @@ void ctbin::init_members(void) @@ -698,6 +921,11 @@ void ctbin::init_members(void)
698 m_infiles.clear(); 921 m_infiles.clear();
699 m_use_xml = false; 922 m_use_xml = false;
700 m_read_ahead = false; 923 m_read_ahead = false;
  924 + m_cube.clear();
  925 + m_ebounds.clear();
  926 + m_gti.clear();
  927 + m_ontime = 0.0;
  928 + m_livetime = 0.0;
701 929
702 // Set logger properties 930 // Set logger properties
703 log.date(true); 931 log.date(true);
@@ -737,6 +965,11 @@ void ctbin::copy_members(const ctbin&amp; app) @@ -737,6 +965,11 @@ void ctbin::copy_members(const ctbin&amp; app)
737 m_infiles = app.m_infiles; 965 m_infiles = app.m_infiles;
738 m_use_xml = app.m_use_xml; 966 m_use_xml = app.m_use_xml;
739 m_read_ahead = app.m_read_ahead; 967 m_read_ahead = app.m_read_ahead;
  968 + m_cube = app.m_cube;
  969 + m_ebounds = app.m_ebounds;
  970 + m_gti = app.m_gti;
  971 + m_ontime = app.m_ontime;
  972 + m_livetime = app.m_livetime;
740 973
741 // Return 974 // Return
742 return; 975 return;
@@ -759,6 +992,83 @@ void ctbin::free_members(void) @@ -759,6 +992,83 @@ void ctbin::free_members(void)
759 992
760 993
761 /***********************************************************************//** 994 /***********************************************************************//**
  995 + * @brief Get the energy boundaries
  996 + *
  997 + * @exception GException::invalid_value
  998 + * No valid energy boundary extension found.
  999 + *
  1000 + * Get the energy boundaries according to the user parameters. The method
  1001 + * supports loading of energy boundary information from the EBOUNDS or
  1002 + * ENERGYBINS extension, or setting energy boundaries using a linear
  1003 + * or logarithmical spacing.
  1004 + *
  1005 + * @todo Ultimately this method should go in a support library as it is
  1006 + * used by several ctools.
  1007 + ***************************************************************************/
  1008 +void ctbin::get_ebounds(void)
  1009 +{
  1010 + // Initialse energy boundary information
  1011 + m_ebounds.clear();
  1012 +
  1013 + // Check whether energy binning information should be read from a FITS
  1014 + // file ...
  1015 + if (m_ebinalg == "FILE") {
  1016 +
  1017 + // Open energy boundary file using the EBOUNDS or ENERGYBINS
  1018 + // extension. Throw an exception if opening fails.
  1019 + GFits file(m_ebinfile);
  1020 + if (file.contains("EBOUNDS")) {
  1021 + file.close();
  1022 + m_ebounds.load(m_ebinfile,"EBOUNDS");
  1023 + }
  1024 + else if (file.contains("ENERGYBINS")) {
  1025 + file.close();
  1026 + m_ebounds.load(m_ebinfile,"ENERGYBINS");
  1027 + }
  1028 + else {
  1029 + file.close();
  1030 + std::string msg = "No extension with name \"EBOUNDS\" or"
  1031 + " \"ENERGYBINS\" found in FITS file"
  1032 + " \""+m_ebinfile+"\".\n"
  1033 + "An \"EBOUNDS\" or \"ENERGYBINS\" extension"
  1034 + " is required if the parameter \"ebinalg\""
  1035 + " is set to \"FILE\".";
  1036 + throw GException::invalid_value(G_BIN_EVENTS, msg);
  1037 + }
  1038 +
  1039 + // Set enumbins parameter to number of ebounds
  1040 + m_enumbins = m_ebounds.size();
  1041 +
  1042 + } // endif: ebinalg was "FILE"
  1043 +
  1044 + // ... otherwise use a linear or a logarithmically-spaced energy binning
  1045 + else {
  1046 +
  1047 + // Initialise log mode for ebinning
  1048 + bool log = true;
  1049 +
  1050 + // check if algorithm is linear
  1051 + if (m_ebinalg == "LIN") {
  1052 + log = false;
  1053 + }
  1054 +
  1055 + // todo: should we also check if m_ebinalg is "LOG"
  1056 + // and throw an exception if neither LIN/LOG/FILE
  1057 + // is given?
  1058 +
  1059 + // Setup energy range covered by data
  1060 + GEnergy emin(m_emin, "TeV");
  1061 + GEnergy emax(m_emax, "TeV");
  1062 + m_ebounds = GEbounds(m_enumbins, emin, emax, log);
  1063 +
  1064 + } //endif: ebinalg was not "FILE"
  1065 +
  1066 + // Return
  1067 + return;
  1068 +}
  1069 +
  1070 +
  1071 +/***********************************************************************//**
762 * @brief Set output file name. 1072 * @brief Set output file name.
763 * 1073 *
764 * @param[in] index Index of input file. 1074 * @param[in] index Index of input file.
src/ctbin/ctbin.hpp
@@ -33,7 +33,7 @@ @@ -33,7 +33,7 @@
33 33
34 /* __Definitions _________________________________________________________ */ 34 /* __Definitions _________________________________________________________ */
35 #define CTBIN_NAME "ctbin" 35 #define CTBIN_NAME "ctbin"
36 -#define CTBIN_VERSION "00-04-00" 36 +#define CTBIN_VERSION "00-05-00"
37 37
38 38
39 /***********************************************************************//** 39 /***********************************************************************//**
@@ -41,11 +41,24 @@ @@ -41,11 +41,24 @@
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 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. 44 + * This class bins CTA event list(s) into a single counts cube. The class
  45 + * can operate on predefined observation containers, on individual event list
  46 + * FITS files, and on observation definition XML files.
  47 + *
  48 + * If multiple event lists are specified in the observation container or the
  49 + * XML definition file, the class will merge these events into a single
  50 + * counts cube.
  51 + *
  52 + * Results are stored in an observation container that can be written to disk
  53 + * in form of a single FITS file.
  54 + *
  55 + * WARNING: Note that the pointing direction of the counts cube will be set
  56 + * to the skymap centre used for the counts cube definition. If usepnt=yes
  57 + * is used, the pointing direction will be extracted from the first
  58 + * observation encountered in the list. Ultimately, pointing direction
  59 + * information should not be removed from the counts cube and exposure and
  60 + * PSF cubes should be used for response computation. This is however not
  61 + * yet fully implemented.
49 ***************************************************************************/ 62 ***************************************************************************/
50 class ctbin : public GApplication { 63 class ctbin : public GApplication {
51 public: 64 public:
@@ -65,20 +78,27 @@ public: @@ -65,20 +78,27 @@ public:
65 void run(void); 78 void run(void);
66 void save(void); 79 void save(void);
67 const GObservations& obs(void) const; 80 const GObservations& obs(void) const;
  81 + GCTAEventCube cube(void) const;
68 void get_parameters(void); 82 void get_parameters(void);
69 - void bin_events(GCTAObservation* obs); 83 + void init_cube(void);
  84 + void fill_cube(GCTAObservation* obs);
  85 + void obs_cube(void);
70 86
71 protected: 87 protected:
72 // Protected methods 88 // Protected methods
73 void init_members(void); 89 void init_members(void);
74 void copy_members(const ctbin& app); 90 void copy_members(const ctbin& app);
75 void free_members(void); 91 void free_members(void);
  92 + void get_ebounds(void);
76 std::string set_outfile_name(const int index) const; 93 std::string set_outfile_name(const int index) const;
77 void save_fits(void); 94 void save_fits(void);
78 void save_xml(void); 95 void save_xml(void);
79 void save_counts_map(const GCTAObservation* obs, 96 void save_counts_map(const GCTAObservation* obs,
80 const std::string& outfile) const; 97 const std::string& outfile) const;
81 98
  99 + // Obsolete methods (to be reomved later)
  100 + void bin_events(GCTAObservation* obs);
  101 +
82 // User parameters 102 // User parameters
83 std::string m_evfile; //!< Input event list or XML file 103 std::string m_evfile; //!< Input event list or XML file
84 std::string m_outfile; //!< Output counts map or XML file 104 std::string m_outfile; //!< Output counts map or XML file
@@ -102,6 +122,11 @@ protected: @@ -102,6 +122,11 @@ protected:
102 std::vector<std::string> m_infiles; //!< Input event filenames 122 std::vector<std::string> m_infiles; //!< Input event filenames
103 bool m_use_xml; //!< Use XML file instead of FITS file 123 bool m_use_xml; //!< Use XML file instead of FITS file
104 bool m_read_ahead; //!< Read ahead parameters 124 bool m_read_ahead; //!< Read ahead parameters
  125 + GSkymap m_cube; //!< Event cube
  126 + GEbounds m_ebounds; //!< Energy boundaries
  127 + GGti m_gti; //!< Good time intervals
  128 + double m_ontime; //!< Total ontime
  129 + double m_livetime; //!< Total livetime
105 }; 130 };
106 131
107 /***********************************************************************//** 132 /***********************************************************************//**
@@ -115,4 +140,22 @@ const GObservations&amp; ctbin::obs(void) const @@ -115,4 +140,22 @@ const GObservations&amp; ctbin::obs(void) const
115 return m_obs; 140 return m_obs;
116 } 141 }
117 142
  143 +
  144 +/***********************************************************************//**
  145 + * @brief Return event cube
  146 + *
  147 + * @return Event cube
  148 + *
  149 + * Returns a CTA event cube built from the ctbin member information.
  150 + ***************************************************************************/
  151 +inline
  152 +GCTAEventCube ctbin::cube(void) const
  153 +{
  154 + // Build event cube
  155 + GCTAEventCube cube(m_cube, m_ebounds, m_gti);
  156 +
  157 + // Return cube
  158 + return cube;
  159 +}
  160 +
118 #endif /* CTBIN_HPP */ 161 #endif /* CTBIN_HPP */
src/ctbin/ctbin.par
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 # ------------------------------------------------------------------------- # 5 # ------------------------------------------------------------------------- #
6 # # 6 # #
7 # File: ctbin.par # 7 # File: ctbin.par #
8 -# Version: 00-04-00 # 8 +# Version: 00-05-00 #
9 # # 9 # #
10 # Author: Jurgen Knodlseder # 10 # Author: Jurgen Knodlseder #
11 # Jurgen.Knodlseder@irap.omp.eu # 11 # Jurgen.Knodlseder@irap.omp.eu #