Commit de1ac1d091652e44a3b4a4c51a1bfd5278b613f6
1 parent
c621f113
Improved error handling and fixed some bugs
Showing
2 changed files
with
63 additions
and
41 deletions
cscripts/csiactdata.py
| ... | ... | @@ -169,6 +169,10 @@ class csiactdata(ctools.cscript): |
| 169 | 169 | self.log("Not available") |
| 170 | 170 | self.log("\n") |
| 171 | 171 | |
| 172 | + | |
| 173 | + self.log("\n") | |
| 174 | + self.log.header2("Available data configs") | |
| 175 | + | |
| 172 | 176 | # Loop over configs and log available configs |
| 173 | 177 | for config in configs: |
| 174 | 178 | ... | ... |
cscripts/csiactobs.py
| ... | ... | @@ -43,10 +43,10 @@ class csiactobs(ctools.cscript): |
| 43 | 43 | """ |
| 44 | 44 | # Set name and version |
| 45 | 45 | self.name = "csiactobs" |
| 46 | - self.version = "1.0.0" | |
| 46 | + self.version = "1.1.0" | |
| 47 | 47 | |
| 48 | 48 | # Initialise some members |
| 49 | - self.m_erange = gammalib.GEbounds() | |
| 49 | + self.m_ebounds = gammalib.GEbounds() | |
| 50 | 50 | self.datapath = os.getenv("VHEFITS","") |
| 51 | 51 | self.inmodels = None |
| 52 | 52 | self.outobs = "obs.xml" |
| ... | ... | @@ -127,7 +127,11 @@ class csiactobs(ctools.cscript): |
| 127 | 127 | |
| 128 | 128 | if self.datapath == "": |
| 129 | 129 | self.datapath = self["datapath"].string() |
| 130 | - | |
| 130 | + | |
| 131 | + # Check for input models | |
| 132 | + if not self["inmodel"].filename() == "NONE": | |
| 133 | + self.inmodels = gammalib.GModels(self["inmodel"].filename()) | |
| 134 | + | |
| 131 | 135 | # Expand environment |
| 132 | 136 | self.datapath = gammalib.expand_env(self.datapath) |
| 133 | 137 | |
| ... | ... | @@ -190,9 +194,9 @@ class csiactobs(ctools.cscript): |
| 190 | 194 | |
| 191 | 195 | # Check HDUs |
| 192 | 196 | if self.m_hdu_index == "" or self.m_obs_index == "": |
| 193 | - raise RuntimeError("FITS data store \""+self.m_prodname+"\" not available. Run csiactdata to get a list of available storage names") | |
| 197 | + raise RuntimeError("*** ERROR: FITS data store \""+self.m_prodname+"\" not available. Run csiactdata to get a list of available storage names") | |
| 194 | 198 | if not gammalib.is_fits(self.m_hdu_index+"[HDU_INDEX]"): |
| 195 | - raise RuntimeError("HDU index file \""+self.m_hdu_index+"[HDU_INDEX]\" for FITS data store \""+self.m_prodname+"\" not available. Check your master index file or run csiactdata to get a list of available storage names.") | |
| 199 | + raise RuntimeError("*** ERROR: HDU index file \""+self.m_hdu_index+"[HDU_INDEX]\" for FITS data store \""+self.m_prodname+"\" not available. Check your master index file or run csiactdata to get a list of available storage names.") | |
| 196 | 200 | |
| 197 | 201 | # Check for existence of "BKG_SCALE" in the observation index file if required |
| 198 | 202 | if self.m_use_bkg_scale: |
| ... | ... | @@ -213,7 +217,7 @@ class csiactobs(ctools.cscript): |
| 213 | 217 | # Return |
| 214 | 218 | return |
| 215 | 219 | |
| 216 | - def background_spectrum(self, run, prefactor, index, emin, emax): | |
| 220 | + def background_spectrum(self, run, prefactor, index, emin = 0.01, emax = 100.0): | |
| 217 | 221 | |
| 218 | 222 | # Handle constant spectral model |
| 219 | 223 | if index == 0.0 and self.m_bkgpars <= 1: |
| ... | ... | @@ -258,7 +262,7 @@ class csiactobs(ctools.cscript): |
| 258 | 262 | |
| 259 | 263 | # Create spectral model and energy values |
| 260 | 264 | spec = gammalib.GModelSpectralNodes() |
| 261 | - bounds = gammalib.GEbounds(self.bkgpars,gammalib.GEnergy(emin,"TeV"),gammalib.GEnergy(emax,"TeV"),True) | |
| 265 | + bounds = gammalib.GEbounds(self.m_bkgpars,gammalib.GEnergy(emin,"TeV"),gammalib.GEnergy(emax,"TeV"), True) | |
| 262 | 266 | for i in range(bounds.size()): |
| 263 | 267 | energy = bounds.elogmean(i) |
| 264 | 268 | value = plaw.eval(energy, gammalib.GTime()) |
| ... | ... | @@ -274,7 +278,7 @@ class csiactobs(ctools.cscript): |
| 274 | 278 | # Return spectrum |
| 275 | 279 | return spec |
| 276 | 280 | |
| 277 | - def iact_background(self, telescope, obs_id, bkg_scale, bkgtype, emin=0.1, emax=100): | |
| 281 | + def iact_background(self, telescope, obs_id, bkg_scale, bkgtype, emin=0.01, emax=100): | |
| 278 | 282 | |
| 279 | 283 | # handle IrfBackground |
| 280 | 284 | if bkgtype == "irf": |
| ... | ... | @@ -287,7 +291,7 @@ class csiactobs(ctools.cscript): |
| 287 | 291 | bck = gammalib.GCTAModelIrfBackground(spec) |
| 288 | 292 | |
| 289 | 293 | # Set AeffBackground |
| 290 | - elif self.bkgtype == "aeff": | |
| 294 | + elif bkgtype == "aeff": | |
| 291 | 295 | |
| 292 | 296 | prefactor = bkg_scale * self.m_bkg_aeff_norm |
| 293 | 297 | spec = self.background_spectrum(obs_id, prefactor, self.m_bkg_aeff_index, emin, emax) |
| ... | ... | @@ -296,7 +300,7 @@ class csiactobs(ctools.cscript): |
| 296 | 300 | bck = gammalib.GCTAModelAeffBackground(spec) |
| 297 | 301 | |
| 298 | 302 | # Set Gaussian Background |
| 299 | - elif self.bkgtype == "gauss": | |
| 303 | + elif bkgtype == "gauss": | |
| 300 | 304 | prefactor = bkg_scale * self.m_bkg_gauss_norm |
| 301 | 305 | spec = self.background_spectrum(obs_id, prefactor, self.m_bkg_gauss_index, emin, emax) |
| 302 | 306 | radial = gammalib.GCTAModelRadialGauss(self.m_bkg_gauss_sigma) |
| ... | ... | @@ -323,11 +327,11 @@ class csiactobs(ctools.cscript): |
| 323 | 327 | # Return model |
| 324 | 328 | return model |
| 325 | 329 | |
| 326 | - def erange(self): | |
| 330 | + def ebounds(self): | |
| 327 | 331 | """ |
| 328 | 332 | Returns runlist energy range |
| 329 | 333 | """ |
| 330 | - return self.m_erange | |
| 334 | + return self.m_ebounds | |
| 331 | 335 | |
| 332 | 336 | def execute(self): |
| 333 | 337 | """ |
| ... | ... | @@ -359,7 +363,7 @@ class csiactobs(ctools.cscript): |
| 359 | 363 | self.log("\n") |
| 360 | 364 | |
| 361 | 365 | # Initialise empty models |
| 362 | - self.models = gammalib.GModels() | |
| 366 | + self.models = gammalib.GModels() | |
| 363 | 367 | |
| 364 | 368 | # Initialise empty xml file and append an observation list |
| 365 | 369 | self.xml = gammalib.GXml() |
| ... | ... | @@ -380,23 +384,25 @@ class csiactobs(ctools.cscript): |
| 380 | 384 | runlist.append('') |
| 381 | 385 | runfile.close() |
| 382 | 386 | |
| 383 | - # Loop over runs | |
| 384 | 387 | # Log output |
| 385 | 388 | if self.logTerse(): |
| 386 | 389 | self.log("\n") |
| 387 | - self.log.header1("Looping over runs") | |
| 390 | + self.log.header1("Looping over "+str(len(runlist))+" runs") | |
| 388 | 391 | |
| 389 | 392 | # Initialise energy range values for logging |
| 390 | - runlist_emin = 100.0 | |
| 391 | - runlist_emax = 0.0 | |
| 393 | + self.m_ebounds.clear() | |
| 392 | 394 | |
| 395 | + # Loop over runs | |
| 393 | 396 | for obs_id in runlist: |
| 394 | 397 | |
| 398 | + # Create selection string | |
| 395 | 399 | obs_selection = "[OBS_ID=="+str(obs_id)+"]" |
| 396 | 400 | |
| 401 | + # Open HDU index file | |
| 397 | 402 | hduindx = gammalib.GFits(self.m_hdu_index+"[HDU_INDEX]"+obs_selection) |
| 398 | 403 | hduindx_hdu = hduindx["HDU_INDEX"] |
| 399 | 404 | |
| 405 | + # Initialise files and hdu names | |
| 400 | 406 | eventfile = aefffile = psffile = edispfile = bkgfile = "" |
| 401 | 407 | eventhdu = aeffhdu = "" |
| 402 | 408 | |
| ... | ... | @@ -481,10 +487,13 @@ class csiactobs(ctools.cscript): |
| 481 | 487 | bkgfile += "["+hduindx_hdu["HDU_NAME"][index]+"]" |
| 482 | 488 | if not gammalib.is_fits(bkgfile): |
| 483 | 489 | if self.logTerse(): |
| 484 | - self.log("Warning: observation "+str(obs_id)+" has no background information in \""+bkgfile+"\". IRF background cannot be used\n") | |
| 490 | + self.log("Warning: observation "+str(obs_id)+" has no background information (file=\""+bkgfile+"\"). IRF background cannot be used\n") | |
| 485 | 491 | bkgfile = "" |
| 486 | 492 | bkg_mod_hierarchy.remove("irf") |
| 487 | 493 | |
| 494 | + # Close hdu index file | |
| 495 | + hduindx.close() | |
| 496 | + | |
| 488 | 497 | # Handle background scale information if available |
| 489 | 498 | bkg_scale = 1.0 |
| 490 | 499 | if self.m_use_bkg_scale: |
| ... | ... | @@ -505,24 +514,27 @@ class csiactobs(ctools.cscript): |
| 505 | 514 | aeff_fits = gammalib.GFits(aefffile) |
| 506 | 515 | aeff_table = aeff_fits[aeffhdu] |
| 507 | 516 | |
| 508 | - # Initialise energy range in case no threshold is available | |
| 509 | - run_emin = 0.1 | |
| 510 | - run_emax = 100.0 | |
| 517 | + # Set energy range from header keyword if present | |
| 518 | + if aeff_table.has_card("LO_THRES") and aeff_table.has_card("HI_THRES"): | |
| 519 | + | |
| 520 | + # Get safe energy range | |
| 521 | + run_emin = gammalib.GEnergy(aeff_table.real("LO_THRES"), "TeV") | |
| 522 | + run_emax = gammalib.GEnergy(aeff_table.real("HI_THRES"), "TeV") | |
| 523 | + | |
| 524 | + # Append to ebounds | |
| 525 | + self.m_ebounds.append(run_emin, run_emax) | |
| 511 | 526 | |
| 512 | - # Set energy range from heady keywords | |
| 513 | - if aeff_table.has_card("LO_THRES") and aeff_table.has_card["HI_THRES"]: | |
| 514 | - run_emin = aeff_table.real("LO_THRES") | |
| 515 | - run_emax = aeff_table.real("HI_THRES") | |
| 527 | + else: | |
| 528 | + # Set default values for energy range | |
| 529 | + run_emin = gammalib.GEnergy(10,"GeV") | |
| 530 | + run_emax = gammalib.GEnergy(100,"TeV") | |
| 516 | 531 | |
| 517 | 532 | # Close Aeff fits file |
| 518 | 533 | aeff_fits.close() |
| 519 | - | |
| 520 | - # Adapt runlist energy range if necessary | |
| 521 | - if run_emin < runlist_emin: | |
| 522 | - runlist_emin = run_emin | |
| 523 | - if run_emax > runlist_emax: | |
| 524 | - runlist_emax = run_emax | |
| 525 | - | |
| 534 | + | |
| 535 | + # Append instrumental background model | |
| 536 | + self.models.append(self.iact_background(telescope, obs_id, bkg_scale, bkg_mod_hierarchy[0], run_emin.TeV(), run_emax.TeV())) | |
| 537 | + | |
| 526 | 538 | # Logging |
| 527 | 539 | if self.logTerse(): |
| 528 | 540 | self.log("Adding observation "+str(obs_id)+" (\""+object_name+"\")\n") |
| ... | ... | @@ -570,20 +582,25 @@ class csiactobs(ctools.cscript): |
| 570 | 582 | obs.append(edisp) |
| 571 | 583 | obs.append(bck) |
| 572 | 584 | |
| 573 | - # Append instrumental background model | |
| 574 | - self.models.append(self.iact_background(telescope, obs_id, bkg_scale, bkg_mod_hierarchy[0], run_emin, run_emax)) | |
| 575 | - | |
| 576 | 585 | # Continue only if there are observations available |
| 577 | 586 | if lib.size(): |
| 578 | 587 | |
| 579 | - # Store energy range as member | |
| 580 | - self.m_erange = gammalib.GEbounds(gammalib.GEnergy(runlist_emin,"TeV"),gammalib.GEnergy(runlist_emax,"TeV")) | |
| 581 | - | |
| 582 | - # Write energy range into log file | |
| 588 | + # Log header of energy range | |
| 583 | 589 | if self.logTerse(): |
| 584 | 590 | self.log("\n") |
| 585 | - self.log("Eenrgy range of obervation list: ") | |
| 586 | - self.log(("% 3.2f" % runlist_emin)+" - "+("% 3.2f" % runlist_emax)+" TeV") | |
| 591 | + self.log.header3("Eenrgy range of obervation list: ") | |
| 592 | + | |
| 593 | + # Logging if energy range is available | |
| 594 | + if self.m_ebounds.size() > 0: | |
| 595 | + | |
| 596 | + # Write energy range into log file | |
| 597 | + self.log(str(self.m_ebounds.emin())+" - "+str(self.m_ebounds.emax())) | |
| 598 | + self.log("\n") | |
| 599 | + | |
| 600 | + else: | |
| 601 | + | |
| 602 | + # Write 'not available' into log file | |
| 603 | + self.log("not available") | |
| 587 | 604 | self.log("\n") |
| 588 | 605 | |
| 589 | 606 | else: |
| ... | ... | @@ -615,6 +632,7 @@ class csiactobs(ctools.cscript): |
| 615 | 632 | # Return |
| 616 | 633 | return |
| 617 | 634 | |
| 635 | + | |
| 618 | 636 | # ======================== # |
| 619 | 637 | # Main routine entry point # |
| 620 | 638 | # ======================== # | ... | ... |