Commit 706e318f0551e239951821e28ddd02a442680bf9

Authored by Michael Mayer
1 parent 51c98949

Modified ctmodel following the discussions on #1439. In addition, csresmap was a…

…lso modified consistently, csresmap can now also take two maps (cnt and model) as input and compute the residuals directly. The algorithm parameter has been made unhidden
scripts/csresmap.py
... ... @@ -101,6 +101,8 @@ class csresmap(ctools.cscript):
101 101 # Create default parfile
102 102 pars = gammalib.GApplicationPars()
103 103 pars.append(gammalib.GApplicationPar("inobs","f","a","events.fits","","","Event list, counts cube, or observation definition file"))
  104 + pars.append(gammalib.GApplicationPar("cntcube","f","h","NONE","","","Input model cube (generated with ctmodel)"))
  105 + pars.append(gammalib.GApplicationPar("modcube","f","h","NONE","","","Input counts cube (generated with ctbin)"))
104 106 pars.append(gammalib.GApplicationPar("inmodel","f","a","$CTOOLS/share/models/crab.xml","","","Source model"))
105 107 pars.append(gammalib.GApplicationPar("outmap","f","a","resmap.fits","","","Output residual map"))
106 108 pars.append(gammalib.GApplicationPar("caldb","s","a","prod2","","","Calibration database"))
... ... @@ -117,7 +119,7 @@ class csresmap(ctools.cscript):
117 119 pars.append(gammalib.GApplicationPar("nxpix","i","a","200","","","Size of the X axis in pixels"))
118 120 pars.append(gammalib.GApplicationPar("nypix","i","a","200","","","Size of the Y axis in pixels"))
119 121 pars.append(gammalib.GApplicationPar("binsz","r","a","0.02","","","Pixel size (deg/pixel)"))
120   - pars.append(gammalib.GApplicationPar("algorithm","s","h","SUBDIV","SUB|SUBDIV|SUBDIVSQRT","","Residual map computation algorithm"))
  122 + pars.append(gammalib.GApplicationPar("algorithm","s","a","SUBDIV","SUB|SUBDIV|SUBDIVSQRT","","Residual map computation algorithm"))
121 123 pars.append_standard()
122 124 pars.append(gammalib.GApplicationPar("logfile","f","h","csresmap.log","","","Log filename"))
123 125 pars.save(parfile)
... ... @@ -131,30 +133,58 @@ class csresmap(ctools.cscript):
131 133 """
132 134 # Get parameters
133 135  
134   - # Set observation if not done before
135   - if self.obs.size() == 0:
136   - self.require_inobs("csresmap.get_parameters()")
137   - self.obs = self.get_observations()
138   -
139   - # Set models if we have none
140   - if self.obs.models().size() == 0:
141   - self.obs.models(self["inmodel"].filename())
142   -
143   - # Read other parameters
144   - self.m_outfile = self["outmap"].filename()
145   - self.m_xref = self["xref"].real()
146   - self.m_yref = self["yref"].real()
147   - self.m_emin = self["emin"].real()
148   - self.m_emax = self["emax"].real()
149   - self.m_enumbins = self["enumbins"].integer()
150   - self.m_ebinalg = self["ebinalg"].string()
151   - self.m_coordsys = self["coordsys"].string()
152   - self.m_proj = self["proj"].string()
153   - self.m_nxpix = self["nxpix"].integer()
154   - self.m_nypix = self["nypix"].integer()
155   - self.m_binsz = self["binsz"].real()
  136 + # Initialise some flags
  137 + self.m_use_maps = False
  138 + self.m_skip_binning = False
  139 +
  140 + # First check for cntcube and modcube parameters
  141 + self.m_cntcube = self["cntcube"].filename()
  142 + self.m_modcube = self["modcube"].filename()
  143 + if not (self.m_cntcube == "NONE" or self.m_modcube == "NONE"):
  144 +
  145 + # Signal that we can use the maps directly without ctbin and ctmodel
  146 + self.m_use_maps = True
  147 +
  148 + # If not two maps are given, proceed to set up observation
  149 + if not self.m_use_maps:
  150 +
  151 + # Set observation if not done before
  152 + if self.obs.size() == 0:
  153 + self.require_inobs("csresmap.get_parameters()")
  154 + self.obs = self.get_observations()
  155 +
  156 + # Check if we have exactly one binned CTA observation
  157 + if self.obs.size() == 1:
  158 +
  159 + if self.obs[0].classname() == "GCTAObservation":
  160 + if self.obs[0].eventtype() == "CountsCube":
  161 + # Skip ctbin step later on
  162 + self.m_skip_binning = True
  163 +
  164 +
  165 + # Set models if we have none
  166 + if self.obs.models().size() == 0:
  167 + self.obs.models(self["inmodel"].filename())
  168 +
  169 + # Skip query for spatial parameters if a binning is provided in the observation
  170 + if not self.m_skip_binning:
  171 + # Read other parameters
  172 + self.m_xref = self["xref"].real()
  173 + self.m_yref = self["yref"].real()
  174 + self.m_emin = self["emin"].real()
  175 + self.m_emax = self["emax"].real()
  176 + self.m_enumbins = self["enumbins"].integer()
  177 + self.m_ebinalg = self["ebinalg"].string()
  178 + self.m_coordsys = self["coordsys"].string()
  179 + self.m_proj = self["proj"].string()
  180 + self.m_nxpix = self["nxpix"].integer()
  181 + self.m_nypix = self["nypix"].integer()
  182 + self.m_binsz = self["binsz"].real()
  183 +
  184 + # Read necessary parameters
  185 + self.m_outfile = self["outmap"].filename()
156 186 self.m_algorithm = self["algorithm"].string()
157   -
  187 +
158 188 # Set some fixed parameters
159 189 self.m_log = False # Logging in client tools
160 190 self.m_chatter = self["chatter"].integer()
... ... @@ -210,53 +240,76 @@ class csresmap(ctools.cscript):
210 240 self.log(str(self.obs))
211 241 self.log("\n")
212 242  
213   - # Write header
214   - if self.logTerse():
215   - self.log("\n")
216   - self.log.header1("Generate binned map (ctbin)")
217   -
218   - # Create countsmap
219   - bin = ctools.ctbin(self.obs)
220   - bin["nxpix"].integer(self.m_nxpix)
221   - bin["nypix"].integer(self.m_nypix)
222   - bin["proj"].string(self.m_proj)
223   - bin["coordsys"].string(self.m_coordsys)
224   - bin["xref"].real(self.m_xref)
225   - bin["yref"].real(self.m_yref)
226   - bin["enumbins"].integer(self.m_enumbins)
227   - bin["ebinalg"].string(self.m_ebinalg)
228   - bin["emin"].real(self.m_emin)
229   - bin["emax"].real(self.m_emax)
230   - bin["binsz"].real(self.m_binsz)
231   - bin["chatter"].integer(self.m_chatter)
232   - bin["clobber"].boolean(self.m_clobber)
233   - bin["debug"].boolean(self.m_debug)
234   - bin.run()
  243 + countmap = gammalib.GSkymap()
  244 + modelmap = gammalib.GSkymap()
  245 +
  246 + # Use input file directly if given
  247 + if self.m_use_maps:
  248 + countmap = gammalib.GSkymap(self["cntcube"].filename())
  249 + modelmap = gammalib.GSkymap(self["modcube"].filename())
  250 +
  251 + else:
  252 +
  253 + cta_counts_cube = gammalib.GCTAEventCube()
  254 +
  255 + if self.m_skip_binning:
  256 + cta_counts_cube = gammalib.GCTAEventCube(self.obs[0].events().clone())
235 257  
  258 + else:
  259 +
  260 + # Write header
  261 + if self.logTerse():
  262 + self.log("\n")
  263 + self.log.header1("Generate binned map (ctbin)")
  264 +
  265 + # Create countsmap
  266 + bin = ctools.ctbin(self.obs)
  267 + bin["nxpix"].integer(self.m_nxpix)
  268 + bin["nypix"].integer(self.m_nypix)
  269 + bin["proj"].string(self.m_proj)
  270 + bin["coordsys"].string(self.m_coordsys)
  271 + bin["xref"].real(self.m_xref)
  272 + bin["yref"].real(self.m_yref)
  273 + bin["enumbins"].integer(self.m_enumbins)
  274 + bin["ebinalg"].string(self.m_ebinalg)
  275 + bin["emin"].real(self.m_emin)
  276 + bin["emax"].real(self.m_emax)
  277 + bin["binsz"].real(self.m_binsz)
  278 + bin["chatter"].integer(self.m_chatter)
  279 + bin["clobber"].boolean(self.m_clobber)
  280 + bin["debug"].boolean(self.m_debug)
  281 + bin.run()
  282 +
  283 + # Retrieve counts cube
  284 + cta_counts_cube = bin.cube()
  285 +
  286 + # Assign GCTAEventCube to skymap
  287 + countmap = cta_counts_cube.map()
  288 +
  289 + # Write header
  290 + if self.logTerse():
  291 + self.log("\n")
  292 + self.log.header1("Generate model map (ctmodel)")
  293 +
  294 + # Create model map
  295 + model = ctools.ctmodel(self.obs)
  296 + model.cube(cta_counts_cube)
  297 + model["chatter"].integer(self.m_chatter)
  298 + model["clobber"].boolean(self.m_clobber)
  299 + model["debug"].boolean(self.m_debug)
  300 + model.run()
  301 +
  302 + # Get model map into GSkymap object
  303 + modelmap = model.cube().map().copy()
  304 +
  305 +
236 306 # Store counts map as residual map. Note that we need a
237 307 # special construct here to avoid memory leaks. This seems
238 308 # to be a SWIG feature as SWIG creates a new object when
239 309 # calling bin.cube()
240   - #residualmap = bin.cube().map()
241   - counts_cube = bin.cube()
242   - self.resmap = counts_cube.map().copy()
  310 + #residualmap = bin.cube().map()
  311 + self.resmap = countmap.copy()
243 312 self.resmap.stack_maps()
244   -
245   - # Write header
246   - if self.logTerse():
247   - self.log("\n")
248   - self.log.header1("Generate model map (ctmodel)")
249   -
250   - # Create model map
251   - model = ctools.ctmodel(self.obs)
252   - model.cube(bin.cube())
253   - model["chatter"].integer(self.m_chatter)
254   - model["clobber"].boolean(self.m_clobber)
255   - model["debug"].boolean(self.m_debug)
256   - model.run()
257   -
258   - # Get model map into GSkymap object
259   - modelmap = model.cube().map()
260 313 modelmap.stack_maps()
261 314  
262 315 # Continue calculations depending on given algorithm
... ...
src/ctmodel/ctmodel.cpp
... ... @@ -270,9 +270,34 @@ void ctmodel::run(void)
270 270 }
271 271 }
272 272  
  273 + // Fill cube and leave loop if we are binned mode (meaning we only have
  274 + // one binned observation)
  275 + if (m_binned && m_obs.size() == 1) {
  276 + fill_cube(obs);
  277 + break;
  278 + }
  279 +
  280 + // Skip observation if we don't have an unbinned observation
  281 + if (obs->eventtype() != "EventList") {
  282 +
  283 + // Log that we skip the this observation
  284 + if (logTerse()) {
  285 + log << "Warning: Skipping binned observation \""+obs->name()+"\"";
  286 + log << std::endl;
  287 + }
  288 + continue;
  289 + }
  290 +
  291 +
273 292 // Fill the cube
274 293 fill_cube(obs);
275 294  
  295 + // Leave loop if we are binned mode (meaning we only have
  296 + // one binned observation
  297 + if (m_binned && m_obs.size() == 1) {
  298 + break;
  299 + }
  300 +
276 301 // Dispose events to free memory if event file exists on disk
277 302 if (obs->eventfile().length() > 0 &&
278 303 gammalib::file_exists(obs->eventfile())) {
... ... @@ -374,6 +399,7 @@ void ctmodel::init_members(void)
374 399 m_gti.clear();
375 400 m_has_cube = false;
376 401 m_append_cube = false;
  402 + m_binned = false;
377 403  
378 404 // Return
379 405 return;
... ... @@ -397,6 +423,7 @@ void ctmodel::copy_members(const ctmodel&amp; app)
397 423 m_gti = app.m_gti;
398 424 m_has_cube = app.m_has_cube;
399 425 m_append_cube = app.m_append_cube;
  426 + m_binned = app.m_binned;
400 427  
401 428 // Return
402 429 return;
... ... @@ -430,6 +457,36 @@ void ctmodel::get_parameters(void)
430 457 m_obs = get_observations();
431 458 }
432 459  
  460 + // Check if we got excactly one binned CTA observation
  461 + if (m_obs.size() == 1) {
  462 +
  463 + // Get CTA observation
  464 + GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]);
  465 +
  466 + // Continue only if observation is a CTA observation
  467 + if (obs != NULL) {
  468 +
  469 + // Check for binned observation
  470 + if (obs->eventtype() == "CountsCube") {
  471 +
  472 + // Set cube from binned observation
  473 + GCTAEventCube* evtcube = dynamic_cast<GCTAEventCube*>(const_cast<GEvents*>(obs->events()));
  474 +
  475 + cube(*evtcube);
  476 +
  477 + // Signal that cube has been set
  478 + m_has_cube = true;
  479 +
  480 + // Signal that we are in binned mode
  481 + m_binned = true;
  482 +
  483 + } // endif: observation was binned
  484 +
  485 + } // endif: observation was CTA
  486 +
  487 + } // endif: had exactly one observation
  488 +
  489 +
433 490 // Read model definition file if required
434 491 if (m_obs.models().size() == 0) {
435 492  
... ... @@ -583,3 +640,4 @@ void ctmodel::fill_cube(const GCTAObservation* obs)
583 640 // Return
584 641 return;
585 642 }
  643 +
... ...
src/ctmodel/ctmodel.hpp
... ... @@ -92,6 +92,7 @@ protected:
92 92 GGti m_gti; //!< Model cube GTIs
93 93 bool m_has_cube; //!< Signal if cube has been set or loaded
94 94 bool m_append_cube; //!< Signal that cube should be appended
  95 + bool m_binned; //!< Signals that we are in binned mode
95 96 };
96 97  
97 98  
... ...
test/test_cscripts.sh.in
... ... @@ -182,7 +182,8 @@ chmod +x @abs_top_srcdir@/scripts/csresmap.py
182 182 xref=83.63 \
183 183 yref=22.01 \
184 184 proj="CAR" \
185   - binsz=0.05 > csresmap.log
  185 + binsz=0.05 \
  186 + algorithm="SUBDIV" > csresmap.log
186 187 $ECHO -n "."
187 188 if [ -s "resmap.fits" ]
188 189 then
... ...