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,6 +169,10 @@ class csiactdata(ctools.cscript): | ||
| 169 | self.log("Not available") | 169 | self.log("Not available") |
| 170 | self.log("\n") | 170 | self.log("\n") |
| 171 | 171 | ||
| 172 | + | ||
| 173 | + self.log("\n") | ||
| 174 | + self.log.header2("Available data configs") | ||
| 175 | + | ||
| 172 | # Loop over configs and log available configs | 176 | # Loop over configs and log available configs |
| 173 | for config in configs: | 177 | for config in configs: |
| 174 | 178 |
cscripts/csiactobs.py
| @@ -43,10 +43,10 @@ class csiactobs(ctools.cscript): | @@ -43,10 +43,10 @@ class csiactobs(ctools.cscript): | ||
| 43 | """ | 43 | """ |
| 44 | # Set name and version | 44 | # Set name and version |
| 45 | self.name = "csiactobs" | 45 | self.name = "csiactobs" |
| 46 | - self.version = "1.0.0" | 46 | + self.version = "1.1.0" |
| 47 | 47 | ||
| 48 | # Initialise some members | 48 | # Initialise some members |
| 49 | - self.m_erange = gammalib.GEbounds() | 49 | + self.m_ebounds = gammalib.GEbounds() |
| 50 | self.datapath = os.getenv("VHEFITS","") | 50 | self.datapath = os.getenv("VHEFITS","") |
| 51 | self.inmodels = None | 51 | self.inmodels = None |
| 52 | self.outobs = "obs.xml" | 52 | self.outobs = "obs.xml" |
| @@ -127,7 +127,11 @@ class csiactobs(ctools.cscript): | @@ -127,7 +127,11 @@ class csiactobs(ctools.cscript): | ||
| 127 | 127 | ||
| 128 | if self.datapath == "": | 128 | if self.datapath == "": |
| 129 | self.datapath = self["datapath"].string() | 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 | # Expand environment | 135 | # Expand environment |
| 132 | self.datapath = gammalib.expand_env(self.datapath) | 136 | self.datapath = gammalib.expand_env(self.datapath) |
| 133 | 137 | ||
| @@ -190,9 +194,9 @@ class csiactobs(ctools.cscript): | @@ -190,9 +194,9 @@ class csiactobs(ctools.cscript): | ||
| 190 | 194 | ||
| 191 | # Check HDUs | 195 | # Check HDUs |
| 192 | if self.m_hdu_index == "" or self.m_obs_index == "": | 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 | if not gammalib.is_fits(self.m_hdu_index+"[HDU_INDEX]"): | 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 | # Check for existence of "BKG_SCALE" in the observation index file if required | 201 | # Check for existence of "BKG_SCALE" in the observation index file if required |
| 198 | if self.m_use_bkg_scale: | 202 | if self.m_use_bkg_scale: |
| @@ -213,7 +217,7 @@ class csiactobs(ctools.cscript): | @@ -213,7 +217,7 @@ class csiactobs(ctools.cscript): | ||
| 213 | # Return | 217 | # Return |
| 214 | return | 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 | # Handle constant spectral model | 222 | # Handle constant spectral model |
| 219 | if index == 0.0 and self.m_bkgpars <= 1: | 223 | if index == 0.0 and self.m_bkgpars <= 1: |
| @@ -258,7 +262,7 @@ class csiactobs(ctools.cscript): | @@ -258,7 +262,7 @@ class csiactobs(ctools.cscript): | ||
| 258 | 262 | ||
| 259 | # Create spectral model and energy values | 263 | # Create spectral model and energy values |
| 260 | spec = gammalib.GModelSpectralNodes() | 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 | for i in range(bounds.size()): | 266 | for i in range(bounds.size()): |
| 263 | energy = bounds.elogmean(i) | 267 | energy = bounds.elogmean(i) |
| 264 | value = plaw.eval(energy, gammalib.GTime()) | 268 | value = plaw.eval(energy, gammalib.GTime()) |
| @@ -274,7 +278,7 @@ class csiactobs(ctools.cscript): | @@ -274,7 +278,7 @@ class csiactobs(ctools.cscript): | ||
| 274 | # Return spectrum | 278 | # Return spectrum |
| 275 | return spec | 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 | # handle IrfBackground | 283 | # handle IrfBackground |
| 280 | if bkgtype == "irf": | 284 | if bkgtype == "irf": |
| @@ -287,7 +291,7 @@ class csiactobs(ctools.cscript): | @@ -287,7 +291,7 @@ class csiactobs(ctools.cscript): | ||
| 287 | bck = gammalib.GCTAModelIrfBackground(spec) | 291 | bck = gammalib.GCTAModelIrfBackground(spec) |
| 288 | 292 | ||
| 289 | # Set AeffBackground | 293 | # Set AeffBackground |
| 290 | - elif self.bkgtype == "aeff": | 294 | + elif bkgtype == "aeff": |
| 291 | 295 | ||
| 292 | prefactor = bkg_scale * self.m_bkg_aeff_norm | 296 | prefactor = bkg_scale * self.m_bkg_aeff_norm |
| 293 | spec = self.background_spectrum(obs_id, prefactor, self.m_bkg_aeff_index, emin, emax) | 297 | spec = self.background_spectrum(obs_id, prefactor, self.m_bkg_aeff_index, emin, emax) |
| @@ -296,7 +300,7 @@ class csiactobs(ctools.cscript): | @@ -296,7 +300,7 @@ class csiactobs(ctools.cscript): | ||
| 296 | bck = gammalib.GCTAModelAeffBackground(spec) | 300 | bck = gammalib.GCTAModelAeffBackground(spec) |
| 297 | 301 | ||
| 298 | # Set Gaussian Background | 302 | # Set Gaussian Background |
| 299 | - elif self.bkgtype == "gauss": | 303 | + elif bkgtype == "gauss": |
| 300 | prefactor = bkg_scale * self.m_bkg_gauss_norm | 304 | prefactor = bkg_scale * self.m_bkg_gauss_norm |
| 301 | spec = self.background_spectrum(obs_id, prefactor, self.m_bkg_gauss_index, emin, emax) | 305 | spec = self.background_spectrum(obs_id, prefactor, self.m_bkg_gauss_index, emin, emax) |
| 302 | radial = gammalib.GCTAModelRadialGauss(self.m_bkg_gauss_sigma) | 306 | radial = gammalib.GCTAModelRadialGauss(self.m_bkg_gauss_sigma) |
| @@ -323,11 +327,11 @@ class csiactobs(ctools.cscript): | @@ -323,11 +327,11 @@ class csiactobs(ctools.cscript): | ||
| 323 | # Return model | 327 | # Return model |
| 324 | return model | 328 | return model |
| 325 | 329 | ||
| 326 | - def erange(self): | 330 | + def ebounds(self): |
| 327 | """ | 331 | """ |
| 328 | Returns runlist energy range | 332 | Returns runlist energy range |
| 329 | """ | 333 | """ |
| 330 | - return self.m_erange | 334 | + return self.m_ebounds |
| 331 | 335 | ||
| 332 | def execute(self): | 336 | def execute(self): |
| 333 | """ | 337 | """ |
| @@ -359,7 +363,7 @@ class csiactobs(ctools.cscript): | @@ -359,7 +363,7 @@ class csiactobs(ctools.cscript): | ||
| 359 | self.log("\n") | 363 | self.log("\n") |
| 360 | 364 | ||
| 361 | # Initialise empty models | 365 | # Initialise empty models |
| 362 | - self.models = gammalib.GModels() | 366 | + self.models = gammalib.GModels() |
| 363 | 367 | ||
| 364 | # Initialise empty xml file and append an observation list | 368 | # Initialise empty xml file and append an observation list |
| 365 | self.xml = gammalib.GXml() | 369 | self.xml = gammalib.GXml() |
| @@ -380,23 +384,25 @@ class csiactobs(ctools.cscript): | @@ -380,23 +384,25 @@ class csiactobs(ctools.cscript): | ||
| 380 | runlist.append('') | 384 | runlist.append('') |
| 381 | runfile.close() | 385 | runfile.close() |
| 382 | 386 | ||
| 383 | - # Loop over runs | ||
| 384 | # Log output | 387 | # Log output |
| 385 | if self.logTerse(): | 388 | if self.logTerse(): |
| 386 | self.log("\n") | 389 | self.log("\n") |
| 387 | - self.log.header1("Looping over runs") | 390 | + self.log.header1("Looping over "+str(len(runlist))+" runs") |
| 388 | 391 | ||
| 389 | # Initialise energy range values for logging | 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 | for obs_id in runlist: | 396 | for obs_id in runlist: |
| 394 | 397 | ||
| 398 | + # Create selection string | ||
| 395 | obs_selection = "[OBS_ID=="+str(obs_id)+"]" | 399 | obs_selection = "[OBS_ID=="+str(obs_id)+"]" |
| 396 | 400 | ||
| 401 | + # Open HDU index file | ||
| 397 | hduindx = gammalib.GFits(self.m_hdu_index+"[HDU_INDEX]"+obs_selection) | 402 | hduindx = gammalib.GFits(self.m_hdu_index+"[HDU_INDEX]"+obs_selection) |
| 398 | hduindx_hdu = hduindx["HDU_INDEX"] | 403 | hduindx_hdu = hduindx["HDU_INDEX"] |
| 399 | 404 | ||
| 405 | + # Initialise files and hdu names | ||
| 400 | eventfile = aefffile = psffile = edispfile = bkgfile = "" | 406 | eventfile = aefffile = psffile = edispfile = bkgfile = "" |
| 401 | eventhdu = aeffhdu = "" | 407 | eventhdu = aeffhdu = "" |
| 402 | 408 | ||
| @@ -481,10 +487,13 @@ class csiactobs(ctools.cscript): | @@ -481,10 +487,13 @@ class csiactobs(ctools.cscript): | ||
| 481 | bkgfile += "["+hduindx_hdu["HDU_NAME"][index]+"]" | 487 | bkgfile += "["+hduindx_hdu["HDU_NAME"][index]+"]" |
| 482 | if not gammalib.is_fits(bkgfile): | 488 | if not gammalib.is_fits(bkgfile): |
| 483 | if self.logTerse(): | 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 | bkgfile = "" | 491 | bkgfile = "" |
| 486 | bkg_mod_hierarchy.remove("irf") | 492 | bkg_mod_hierarchy.remove("irf") |
| 487 | 493 | ||
| 494 | + # Close hdu index file | ||
| 495 | + hduindx.close() | ||
| 496 | + | ||
| 488 | # Handle background scale information if available | 497 | # Handle background scale information if available |
| 489 | bkg_scale = 1.0 | 498 | bkg_scale = 1.0 |
| 490 | if self.m_use_bkg_scale: | 499 | if self.m_use_bkg_scale: |
| @@ -505,24 +514,27 @@ class csiactobs(ctools.cscript): | @@ -505,24 +514,27 @@ class csiactobs(ctools.cscript): | ||
| 505 | aeff_fits = gammalib.GFits(aefffile) | 514 | aeff_fits = gammalib.GFits(aefffile) |
| 506 | aeff_table = aeff_fits[aeffhdu] | 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 | # Close Aeff fits file | 532 | # Close Aeff fits file |
| 518 | aeff_fits.close() | 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 | # Logging | 538 | # Logging |
| 527 | if self.logTerse(): | 539 | if self.logTerse(): |
| 528 | self.log("Adding observation "+str(obs_id)+" (\""+object_name+"\")\n") | 540 | self.log("Adding observation "+str(obs_id)+" (\""+object_name+"\")\n") |
| @@ -570,20 +582,25 @@ class csiactobs(ctools.cscript): | @@ -570,20 +582,25 @@ class csiactobs(ctools.cscript): | ||
| 570 | obs.append(edisp) | 582 | obs.append(edisp) |
| 571 | obs.append(bck) | 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 | # Continue only if there are observations available | 585 | # Continue only if there are observations available |
| 577 | if lib.size(): | 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 | if self.logTerse(): | 589 | if self.logTerse(): |
| 584 | self.log("\n") | 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 | self.log("\n") | 604 | self.log("\n") |
| 588 | 605 | ||
| 589 | else: | 606 | else: |
| @@ -615,6 +632,7 @@ class csiactobs(ctools.cscript): | @@ -615,6 +632,7 @@ class csiactobs(ctools.cscript): | ||
| 615 | # Return | 632 | # Return |
| 616 | return | 633 | return |
| 617 | 634 | ||
| 635 | + | ||
| 618 | # ======================== # | 636 | # ======================== # |
| 619 | # Main routine entry point # | 637 | # Main routine entry point # |
| 620 | # ======================== # | 638 | # ======================== # |