Commit 706e318f0551e239951821e28ddd02a442680bf9
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
Showing
4 changed files
with
179 additions
and
66 deletions
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& 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
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 | ... | ... |