Commit 0ffbb73c6488a74dc3316a2daaeacc676f5e749c

Authored by Jürgen Knödlseder
1 parent ff3e3615

Reduce code duplication

cscripts/cslightcrv.py
@@ -106,30 +106,10 @@ class cslightcrv(ctools.cscript): @@ -106,30 +106,10 @@ class cslightcrv(ctools.cscript):
106 # Get time boundaries 106 # Get time boundaries
107 self._tbins = self._create_tbounds() 107 self._tbins = self._create_tbounds()
108 108
109 - # Set stacked analysis flag to True if the requested number of  
110 - # energy bins is positive. Otherwise an unbinned analysis will  
111 - # be done and the stacked analysis flag will be set to False.  
112 - if self['enumbins'].integer() > 0:  
113 - self._stacked = True  
114 - else:  
115 - self._stacked = False  
116 -  
117 - # Make sure that remaining user parameters are queried now. We  
118 - # do not store the actual parameter values as we do not want  
119 - # too many instance attributes with enhances the maintenance  
120 - # costs.  
121 - self['emin'].real()  
122 - self['emax'].real()  
123 - if self._stacked:  
124 - self['coordsys'].string()  
125 - self['proj'].string()  
126 - self['xref'].real()  
127 - self['yref'].real()  
128 - self['nxpix'].integer()  
129 - self['nypix'].integer()  
130 - self['binsz'].real()  
131 -  
132 - # Do the same for the hidden parameters, just in case 109 + # Set stacked analysis flag and query relevant user parameters
  110 + self._stacked = self._is_stacked()
  111 +
  112 + # Query the hidden parameters, just in case
133 self['edisp'].boolean() 113 self['edisp'].boolean()
134 self['calc_ulim'].boolean() 114 self['calc_ulim'].boolean()
135 self['calc_ts'].boolean() 115 self['calc_ts'].boolean()
@@ -428,57 +408,11 @@ class cslightcrv(ctools.cscript): @@ -428,57 +408,11 @@ class cslightcrv(ctools.cscript):
428 obs : `~gammalib.GObservations` 408 obs : `~gammalib.GObservations`
429 Observation container where the first observation is a binned observation 409 Observation container where the first observation is a binned observation
430 """ 410 """
431 - # Header  
432 - if self._logExplicit():  
433 - self._log.header3('Binning events')  
434 -  
435 - # Bin events  
436 - cntcube = ctools.ctbin(obs)  
437 - cntcube['usepnt'] = False  
438 - cntcube['ebinalg'] = 'LOG'  
439 - cntcube['xref'] = self['xref'].real()  
440 - cntcube['yref'] = self['yref'].real()  
441 - cntcube['binsz'] = self['binsz'].real()  
442 - cntcube['nxpix'] = self['nxpix'].integer()  
443 - cntcube['nypix'] = self['nypix'].integer()  
444 - cntcube['enumbins'] = self['enumbins'].integer()  
445 - cntcube['emin'] = self['emin'].real()  
446 - cntcube['emax'] = self['emax'].real()  
447 - cntcube['coordsys'] = self['coordsys'].string()  
448 - cntcube['proj'] = self['proj'].string()  
449 - cntcube.run()  
450 -  
451 - # Header  
452 - if self._logExplicit():  
453 - self._log.header3('Creating stacked response')  
454 -  
455 - # Get stacked response  
456 - response = obsutils.get_stacked_response(obs,  
457 - self['xref'].real(),  
458 - self['yref'].real(),  
459 - binsz=self['binsz'].real(),  
460 - nxpix=self['nxpix'].integer(),  
461 - nypix=self['nypix'].integer(),  
462 - emin=self['emin'].real(),  
463 - emax=self['emax'].real(),  
464 - enumbins=self['enumbins'].integer(),  
465 - edisp=self['edisp'].boolean(),  
466 - coordsys=self['coordsys'].string(),  
467 - proj=self['proj'].string())  
468 -  
469 - # Retrieve a new oberservation container  
470 - new_obs = cntcube.obs().copy()  
471 -  
472 - # Set stacked response  
473 - if self['edisp'].boolean():  
474 - new_obs[0].response(response['expcube'], response['psfcube'],  
475 - response['edispcube'], response['bkgcube'])  
476 - else:  
477 - new_obs[0].response(response['expcube'], response['psfcube'],  
478 - response['bkgcube'])  
479 -  
480 - # Get new models  
481 - models = response['models'] 411 + # Get new observation container with binned observation
  412 + new_obs = obsutils.get_stacked_obs(self, obs)
  413 +
  414 + # Extract models
  415 + models = new_obs.models()
482 416
483 # Fix background models if required 417 # Fix background models if required
484 if self['fix_bkg'].boolean(): 418 if self['fix_bkg'].boolean():
@@ -487,7 +421,7 @@ class cslightcrv(ctools.cscript): @@ -487,7 +421,7 @@ class cslightcrv(ctools.cscript):
487 for par in model: 421 for par in model:
488 par.fix() 422 par.fix()
489 423
490 - # Set models for new oberservation container 424 + # Put back models
491 new_obs.models(models) 425 new_obs.models(models)
492 426
493 # Return new oberservation container 427 # Return new oberservation container
cscripts/csphasecrv.py
@@ -91,33 +91,13 @@ class csphasecrv(ctools.cscript): @@ -91,33 +91,13 @@ class csphasecrv(ctools.cscript):
91 # Get source name 91 # Get source name
92 self._srcname = self['srcname'].string() 92 self._srcname = self['srcname'].string()
93 93
94 - # Get time boundaries 94 + # Get phase boundaries
95 self._phbins = self._create_tbounds() 95 self._phbins = self._create_tbounds()
96 96
97 - # Set stacked analysis flag to True if the requested number of  
98 - # energy bins is positive. Otherwise an unbinned analysis will  
99 - # be done and the stacked analysis flag will be set to False.  
100 - if self['enumbins'].integer() > 0:  
101 - self._stacked = True  
102 - else:  
103 - self._stacked = False  
104 -  
105 - # Make sure that remaining user parameters are queried now. We  
106 - # do not store the actual parameter values as we do not want  
107 - # too many instance attributes with enhances the maintenance  
108 - # costs.  
109 - self['emin'].real()  
110 - self['emax'].real()  
111 - if self._stacked:  
112 - self['coordsys'].string()  
113 - self['proj'].string()  
114 - self['xref'].real()  
115 - self['yref'].real()  
116 - self['nxpix'].integer()  
117 - self['nypix'].integer()  
118 - self['binsz'].real()  
119 -  
120 - # Do the same for the hidden parameters, just in case 97 + # Set stacked analysis flag and query relevant user parameters
  98 + self._stacked = self._is_stacked()
  99 +
  100 + # Query the hidden parameters, just in case
121 self['edisp'].boolean() 101 self['edisp'].boolean()
122 102
123 # Read ahead output parameters 103 # Read ahead output parameters
@@ -181,78 +161,6 @@ class csphasecrv(ctools.cscript): @@ -181,78 +161,6 @@ class csphasecrv(ctools.cscript):
181 # Return Good Time Intervals 161 # Return Good Time Intervals
182 return phbins 162 return phbins
183 163
184 - def _bin_observation(self, obs):  
185 - """  
186 - Bin an observation if a binned analysis was requested  
187 -  
188 - Parameters  
189 - ----------  
190 - obs : `~gammalib.GObservations`  
191 - Observation container  
192 -  
193 - Returns  
194 - -------  
195 - obs : `~gammalib.GObservations`  
196 - Observation container where the first observation is a binned observation  
197 - """  
198 - # Header  
199 - if self._logExplicit():  
200 - self._log.header3('Binning events')  
201 -  
202 - # Bin events  
203 - cntcube = ctools.ctbin(obs)  
204 - cntcube['usepnt'] = False  
205 - cntcube['ebinalg'] = 'LOG'  
206 - cntcube['xref'] = self['xref'].real()  
207 - cntcube['yref'] = self['yref'].real()  
208 - cntcube['binsz'] = self['binsz'].real()  
209 - cntcube['nxpix'] = self['nxpix'].integer()  
210 - cntcube['nypix'] = self['nypix'].integer()  
211 - cntcube['enumbins'] = self['enumbins'].integer()  
212 - cntcube['emin'] = self['emin'].real()  
213 - cntcube['emax'] = self['emax'].real()  
214 - cntcube['coordsys'] = self['coordsys'].string()  
215 - cntcube['proj'] = self['proj'].string()  
216 - cntcube.run()  
217 -  
218 - # Header  
219 - if self._logExplicit():  
220 - self._log.header3('Creating stacked response')  
221 -  
222 - # Get stacked response  
223 - response = obsutils.get_stacked_response(obs,  
224 - self['xref'].real(),  
225 - self['yref'].real(),  
226 - binsz=self['binsz'].real(),  
227 - nxpix=self['nxpix'].integer(),  
228 - nypix=self['nypix'].integer(),  
229 - emin=self['emin'].real(),  
230 - emax=self['emax'].real(),  
231 - enumbins=self['enumbins'].integer(),  
232 - edisp=self['edisp'].boolean(),  
233 - coordsys=self['coordsys'].string(),  
234 - proj=self['proj'].string())  
235 -  
236 - # Retrieve a new oberservation container  
237 - new_obs = cntcube.obs().copy()  
238 -  
239 - # Set stacked response  
240 - if self['edisp'].boolean():  
241 - new_obs[0].response(response['expcube'], response['psfcube'],  
242 - response['edispcube'], response['bkgcube'])  
243 - else:  
244 - new_obs[0].response(response['expcube'], response['psfcube'],  
245 - response['bkgcube'])  
246 -  
247 - # Get new models  
248 - models = response['models']  
249 -  
250 - # Set models for new oberservation container  
251 - new_obs.models(models)  
252 -  
253 - # Return new oberservation container  
254 - return new_obs  
255 -  
256 def _get_free_par_names(self): 164 def _get_free_par_names(self):
257 """ 165 """
258 Return list of free parameter names 166 Return list of free parameter names
@@ -469,7 +377,8 @@ class csphasecrv(ctools.cscript): @@ -469,7 +377,8 @@ class csphasecrv(ctools.cscript):
469 # and compute the stacked response functions and setup 377 # and compute the stacked response functions and setup
470 # an observation container with a single stacked observation. 378 # an observation container with a single stacked observation.
471 if self._stacked: 379 if self._stacked:
472 - obs = self._bin_observation(select.obs()) 380 + #obs = self._bin_observation(select.obs())
  381 + obs = obsutils.get_stacked_obs(self, select.obs())
473 382
474 # Header 383 # Header
475 if self._logExplicit(): 384 if self._logExplicit():
cscripts/obsutils.py
@@ -639,3 +639,82 @@ def get_stacked_response(obs, xref, yref, binsz=0.05, nxpix=200, nypix=200, @@ -639,3 +639,82 @@ def get_stacked_response(obs, xref, yref, binsz=0.05, nxpix=200, nypix=200,
639 639
640 # Return response cubes 640 # Return response cubes
641 return response 641 return response
  642 +
  643 +
  644 +# ================================= #
  645 +# Get stacked observation container #
  646 +# ================================= #
  647 +def get_stacked_obs(cls, obs):
  648 + """
  649 + Bin an observation and return an observation container with a single
  650 + binned observation
  651 +
  652 + Parameters
  653 + ----------
  654 + cls : `~ctools.cscript`
  655 + cscript class
  656 + obs : `~gammalib.GObservations`
  657 + Observation container
  658 +
  659 + Returns
  660 + -------
  661 + obs : `~gammalib.GObservations`
  662 + Observation container where the first observation is a binned observation
  663 + """
  664 + # Write header
  665 + if cls._logExplicit():
  666 + cls._log.header3('Binning events')
  667 +
  668 + # Bin events
  669 + cntcube = ctools.ctbin(obs)
  670 + cntcube['usepnt'] = False
  671 + cntcube['ebinalg'] = 'LOG'
  672 + cntcube['xref'] = cls['xref'].real()
  673 + cntcube['yref'] = cls['yref'].real()
  674 + cntcube['binsz'] = cls['binsz'].real()
  675 + cntcube['nxpix'] = cls['nxpix'].integer()
  676 + cntcube['nypix'] = cls['nypix'].integer()
  677 + cntcube['enumbins'] = cls['enumbins'].integer()
  678 + cntcube['emin'] = cls['emin'].real()
  679 + cntcube['emax'] = cls['emax'].real()
  680 + cntcube['coordsys'] = cls['coordsys'].string()
  681 + cntcube['proj'] = cls['proj'].string()
  682 + cntcube.run()
  683 +
  684 + # Write header
  685 + if cls._logExplicit():
  686 + cls._log.header3('Creating stacked response')
  687 +
  688 + # Get stacked response
  689 + response = get_stacked_response(obs,
  690 + cls['xref'].real(),
  691 + cls['yref'].real(),
  692 + binsz=cls['binsz'].real(),
  693 + nxpix=cls['nxpix'].integer(),
  694 + nypix=cls['nypix'].integer(),
  695 + emin=cls['emin'].real(),
  696 + emax=cls['emax'].real(),
  697 + enumbins=cls['enumbins'].integer(),
  698 + edisp=cls['edisp'].boolean(),
  699 + coordsys=cls['coordsys'].string(),
  700 + proj=cls['proj'].string())
  701 +
  702 + # Retrieve a new oberservation container
  703 + new_obs = cntcube.obs().copy()
  704 +
  705 + # Set stacked response
  706 + if cls['edisp'].boolean():
  707 + new_obs[0].response(response['expcube'], response['psfcube'],
  708 + response['edispcube'], response['bkgcube'])
  709 + else:
  710 + new_obs[0].response(response['expcube'], response['psfcube'],
  711 + response['bkgcube'])
  712 +
  713 + # Get new models
  714 + models = response['models']
  715 +
  716 + # Set models for new oberservation container
  717 + new_obs.models(models)
  718 +
  719 + # Return new oberservation container
  720 + return new_obs
pyext/ctool.i
@@ -99,6 +99,7 @@ public: @@ -99,6 +99,7 @@ public:
99 %rename(_get_pointing) get_pointing; 99 %rename(_get_pointing) get_pointing;
100 %rename(_get_skydir) get_skydir; 100 %rename(_get_skydir) get_skydir;
101 %rename(_set_outfile_name) set_outfile_name; 101 %rename(_set_outfile_name) set_outfile_name;
  102 + %rename(_is_stacked) is_stacked;
102 %rename(_set_response) set_response; 103 %rename(_set_response) set_response;
103 %rename(_set_edisp) set_edisp; 104 %rename(_set_edisp) set_edisp;
104 %rename(_restore_edisp) restore_edisp; 105 %rename(_restore_edisp) restore_edisp;
@@ -143,6 +144,9 @@ public: @@ -143,6 +144,9 @@ public:
143 GSkyDir get_skydir(void); 144 GSkyDir get_skydir(void);
144 std::string set_outfile_name(const std::string& filename); 145 std::string set_outfile_name(const std::string& filename);
145 146
  147 + // Protected methods that query user parameters
  148 + bool is_stacked(void);
  149 +
146 // Protected support methods 150 // Protected support methods
147 void set_response(GObservations& obs); 151 void set_response(GObservations& obs);
148 std::vector<bool> set_edisp(GObservations& obs, const bool& edisp) const; 152 std::vector<bool> set_edisp(GObservations& obs, const bool& edisp) const;
src/support/ctool.cpp
@@ -1156,6 +1156,45 @@ std::string ctool::set_outfile_name(const std::string&amp; filename) @@ -1156,6 +1156,45 @@ std::string ctool::set_outfile_name(const std::string&amp; filename)
1156 1156
1157 1157
1158 /***********************************************************************//** 1158 /***********************************************************************//**
  1159 + * @brief Query user parameters for stacked analysis
  1160 + *
  1161 + * @return True if a stacked analysis should be done.
  1162 + *
  1163 + * Queries the user parameters "emin", "emax" and "enumbins", and if
  1164 + * "enumbins" is positive, signal that a stacked analysis is requested. In
  1165 + * that case, also the "coordsys", "proj", "xref", "yref", "nxpix", "nypix"
  1166 + * and "binsz" parameters are queried.
  1167 + *
  1168 + * Using this method assures that the parameters are always queried in the
  1169 + * same order.
  1170 + ***************************************************************************/
  1171 +bool ctool::is_stacked(void)
  1172 +{
  1173 + // First query the minimum and maximum energies
  1174 + (*this)["emin"].real();
  1175 + (*this)["emax"].real();
  1176 +
  1177 + // Now query the number of energy bins and set the stacked flag
  1178 + bool stacked = ((*this)["enumbins"].integer() > 0) ? true : false;
  1179 +
  1180 + // If a stacked analysis is requested then query the spatial definition
  1181 + // of the cube
  1182 + if (stacked) {
  1183 + (*this)["coordsys"].string();
  1184 + (*this)["proj"].string();
  1185 + (*this)["xref"].real();
  1186 + (*this)["yref"].real();
  1187 + (*this)["nxpix"].integer();
  1188 + (*this)["nypix"].integer();
  1189 + (*this)["binsz"].real();
  1190 + }
  1191 +
  1192 + // Return stacked flag
  1193 + return stacked;
  1194 +}
  1195 +
  1196 +
  1197 +/***********************************************************************//**
1159 * @brief Set response for all CTA observations in container 1198 * @brief Set response for all CTA observations in container
1160 * 1199 *
1161 * @param[in,out] obs Observation container 1200 * @param[in,out] obs Observation container
src/support/ctool.hpp
@@ -102,6 +102,9 @@ protected: @@ -102,6 +102,9 @@ protected:
102 GSkyDir get_skydir(void); 102 GSkyDir get_skydir(void);
103 std::string set_outfile_name(const std::string& filename); 103 std::string set_outfile_name(const std::string& filename);
104 104
  105 + // Protected methods that query user parameters
  106 + bool is_stacked(void);
  107 +
105 // Protected methods for logging 108 // Protected methods for logging
106 void log_observations(const GChatter& chatter, 109 void log_observations(const GChatter& chatter,
107 const GObservations& obs, 110 const GObservations& obs,