Commit 0181f9405a1230e051919bed65524cae4fa9c22c
1 parent
f662447a
Add csobs2caldb unit tests and change user parameter interface.
Showing
7 changed files
with
339 additions
and
80 deletions
cscripts/Makefile.am
| ... | ... | @@ -27,10 +27,12 @@ linkscripts = cspull cssens cstsdist cscaldb csresmap \ |
| 27 | 27 | testscripts = tests/__init__.py \ |
| 28 | 28 | ../test/test_python_cscripts.py \ |
| 29 | 29 | ../test/test_cscaldb.py \ |
| 30 | + ../test/test_csobs2caldb.py \ | |
| 30 | 31 | ../test/test_cslightcrv.py |
| 31 | 32 | |
| 32 | 33 | # Test data to be distributed in $(pyexecdir)/cscripts/tests/data |
| 33 | 34 | testdata = ../test/data/crab.xml \ |
| 35 | + ../test/data/obs_unbinned.xml \ | |
| 34 | 36 | ../test/data/crab_events.fits.gz \ |
| 35 | 37 | ../test/data/crab_cntmap.fits.gz \ |
| 36 | 38 | ../test/data/exclusion.reg | ... | ... |
cscripts/csobs2caldb.par
| ... | ... | @@ -15,11 +15,13 @@ |
| 15 | 15 | # # |
| 16 | 16 | ############################################################################# |
| 17 | 17 | # |
| 18 | -# General parameters | |
| 19 | -#=================== | |
| 18 | +# Input and output parameters | |
| 19 | +#============================ | |
| 20 | 20 | inobs, f, a, obs.xml,,, "Observation definition XML file" |
| 21 | -rspname, s, a, NONE,,, "Response output name (e.g. Zenith50)" | |
| 22 | -outirfs, f, h, irf_file.fits,,, "Output IRF file name" | |
| 21 | +caldb, s, a, cta,,, "Calibration database" | |
| 22 | +irf, s, a, Standard,,, "Instrument response function (e.g. Standard)" | |
| 23 | +outfile, f, h, irf_file.fits,,, "Output IRF file name" | |
| 24 | +rootdir, s, h, ,,, "Optional CALDB root directory" | |
| 23 | 25 | index, i, h, 0,,, "Index of observation to be used from XML file" |
| 24 | 26 | |
| 25 | 27 | # | ... | ... |
cscripts/csobs2caldb.py
| 1 | 1 | #!/usr/bin/env python |
| 2 | 2 | # ========================================================================== |
| 3 | -# Generation of an caldb entry from general IACT observation. | |
| 3 | +# Creates a calibration database entry for an IACT observation. | |
| 4 | 4 | # |
| 5 | 5 | # Copyright (C) 2015-2016 Michael Mayer |
| 6 | 6 | # |
| ... | ... | @@ -30,7 +30,7 @@ import datetime |
| 30 | 30 | # ================= # |
| 31 | 31 | class csobs2caldb(ctools.cscript): |
| 32 | 32 | """ |
| 33 | - Creates a calibration database entry for an observation. | |
| 33 | + Creates a calibration database entry for an IACT observation. | |
| 34 | 34 | |
| 35 | 35 | The creation of a calibration database entry is useful for performing |
| 36 | 36 | simulations for current Imaging Air Cherenkov Telescopes (IACTs). |
| ... | ... | @@ -50,17 +50,17 @@ class csobs2caldb(ctools.cscript): |
| 50 | 50 | self._version = "1.1.0" |
| 51 | 51 | |
| 52 | 52 | # Initialise members |
| 53 | - self._obs = [] # Observation container | |
| 54 | - self._observation = None | |
| 55 | - self._mission = "CTA" | |
| 56 | - self._instrument = "" | |
| 57 | - self._rspname = "" | |
| 58 | - self._outfile = "" | |
| 53 | + self._observation = gammalib.GCTAObservation() | |
| 54 | + self._mission = "cta" | |
| 55 | + self._caldb = "cta" | |
| 56 | + self._outfile = gammalib.GFilename("irf_file.fits") | |
| 59 | 57 | self._base_dir = "" |
| 60 | 58 | self._cal_dir = "" |
| 59 | + | |
| 60 | + # Initialise observation container from constructor arguments. | |
| 61 | + self._obs, argv = self._set_input_obs(argv) | |
| 61 | 62 | |
| 62 | - # Initialise application by calling the appropriate class | |
| 63 | - # constructor. | |
| 63 | + # Initialise script by calling the appropriate class constructor. | |
| 64 | 64 | self._init_cscript(argv) |
| 65 | 65 | |
| 66 | 66 | # Return |
| ... | ... | @@ -70,36 +70,64 @@ class csobs2caldb(ctools.cscript): |
| 70 | 70 | # Private methods |
| 71 | 71 | def _get_parameters(self): |
| 72 | 72 | """ |
| 73 | - Get parameters from parfile and setup the observation. | |
| 73 | + Get parameters from parfile. | |
| 74 | + | |
| 75 | + Raises: | |
| 76 | + ValueError, IndexError, & RuntimeError. | |
| 74 | 77 | """ |
| 75 | - # Load observation container | |
| 76 | - self._obs = gammalib.GObservations(self["inobs"].filename()) | |
| 78 | + # Load observation container from "inobs" parameter in case that | |
| 79 | + # the observation container is still empty. | |
| 80 | + if self._obs.is_empty(): | |
| 81 | + self._obs = gammalib.GObservations(self["inobs"].filename()) | |
| 82 | + | |
| 83 | + # Raise an exception if the observation container is empty | |
| 84 | + if self._obs.is_empty(): | |
| 85 | + raise ValueError('No or empty observation provided for ' | |
| 86 | + 'parameter "inobs".') | |
| 77 | 87 | |
| 78 | - # Get index of observation to be used (0=default) | |
| 79 | - inx = self["index"].integer() | |
| 88 | + # Get index of observation to be used | |
| 89 | + index = self["index"].integer() | |
| 90 | + | |
| 91 | + # Raise an exception if the index is not valid | |
| 92 | + if index < 0 or index >= self._obs.size(): | |
| 93 | + raise IndexError('Parameter "index=%d" outside the validity ' | |
| 94 | + 'range [0,%d].' % (index, self._obs.size())) | |
| 80 | 95 | |
| 81 | 96 | # Get observation |
| 82 | - self._observation = self._obs[inx] | |
| 83 | - | |
| 84 | - # Get instrument name | |
| 85 | - self._instrument = self._observation.instrument() | |
| 86 | - | |
| 87 | - # Get config and file name | |
| 88 | - self._rspname = self["rspname"].string() | |
| 89 | - self._outfile = self["outirfs"].filename() | |
| 90 | - | |
| 91 | - # Make sure we have a cta observation | |
| 97 | + self._observation = self._obs[index] | |
| 98 | + | |
| 99 | + # Make sure we have a CTA observation | |
| 92 | 100 | if not self._observation.classname() == "GCTAObservation": |
| 93 | - raise RuntimeError("Input observation not of type "+ | |
| 94 | - "\"GCTAObservation\".") | |
| 101 | + raise RuntimeError('Input observation not of type ' | |
| 102 | + '"GCTAObservation".') | |
| 95 | 103 | |
| 96 | - # Make sure we have an irf response | |
| 104 | + # Make sure we have an IRF response associated with the CTA | |
| 105 | + # observation | |
| 97 | 106 | if not self._observation.response().classname() == "GCTAResponseIrf": |
| 98 | - raise RuntimeError("Response of input observation not of "+ | |
| 99 | - "type \"GCTAResponseIrf\".") | |
| 107 | + raise RuntimeError('Response of input observation not of ' | |
| 108 | + 'type "GCTAResponseIrf".') | |
| 109 | + | |
| 110 | + # Get calibration database name. If the "caldb" parameter is "NONE" | |
| 111 | + # or empty then use the instrument name from the observation as | |
| 112 | + # calibration database name. | |
| 113 | + self._caldb = self["caldb"].string() | |
| 114 | + if (self._caldb == "NONE" or len(self._caldb) == 0): | |
| 115 | + self._caldb = self._observation.instrument().lower() | |
| 116 | + | |
| 117 | + # Get instrument response function file name | |
| 118 | + self._outfile = self["outfile"].filename() | |
| 119 | + | |
| 120 | + # Make sure that remaining user parameters are queried now. We | |
| 121 | + # do not store the actual parameter values as we do not want | |
| 122 | + # too many instance attributes with enhances the maintenance | |
| 123 | + # costs. | |
| 124 | + self["irf"].string() | |
| 125 | + self["rootdir"].string() | |
| 100 | 126 | |
| 101 | - # Get other parameters | |
| 102 | - self._clobber = self["clobber"].boolean() | |
| 127 | + # Write input parameters and header into logger | |
| 128 | + if self._logTerse(): | |
| 129 | + self._log_parameters() | |
| 130 | + self._log("\n") | |
| 103 | 131 | |
| 104 | 132 | # Return |
| 105 | 133 | return |
| ... | ... | @@ -122,10 +150,11 @@ class csobs2caldb(ctools.cscript): |
| 122 | 150 | fname_edisp = rsp.edisp().filename() |
| 123 | 151 | fname_bkg = rsp.background().filename() |
| 124 | 152 | |
| 125 | - # Log filename instances | |
| 126 | - if self._logTerse(): | |
| 153 | + # Log filenames | |
| 154 | + if self._logNormal(): | |
| 155 | + self._log.header3("IRF input files") | |
| 127 | 156 | self._log(gammalib.parformat("Effective area")) |
| 128 | - self._log(repr(fname_aeff)) | |
| 157 | + self._log(fname_aeff.url()) | |
| 129 | 158 | self._log("\n") |
| 130 | 159 | self._log(gammalib.parformat("Point spread function")) |
| 131 | 160 | self._log(fname_psf.url()) |
| ... | ... | @@ -142,15 +171,35 @@ class csobs2caldb(ctools.cscript): |
| 142 | 171 | fits_psf = gammalib.GFits(fname_psf) |
| 143 | 172 | fits_edisp = gammalib.GFits(fname_edisp) |
| 144 | 173 | fits_bkg = gammalib.GFits(fname_bkg) |
| 174 | + | |
| 175 | + # Get extension names | |
| 176 | + ext_aeff = fname_aeff.extname("EFFECTIVE AREA") | |
| 177 | + ext_psf = fname_psf.extname("POINT SPREAD FUNCTION") | |
| 178 | + ext_edisp = fname_edisp.extname("ENERGY DISPERSION") | |
| 179 | + ext_bkg = fname_bkg.extname("BACKGROUND") | |
| 145 | 180 | |
| 146 | 181 | # Create empty FITS file |
| 147 | 182 | fits = gammalib.GFits() |
| 148 | 183 | |
| 149 | 184 | # Append IRF component to FITS file |
| 150 | - fits.append(fits_aeff[fname_aeff.extname("EFFECTIVE AREA")]) | |
| 151 | - fits.append(fits_psf[fname_psf.extname("POINT SPREAD FUNCTION")]) | |
| 152 | - fits.append(fits_edisp[fname_edisp.extname("ENERGY DISPERSION")]) | |
| 153 | - fits.append(fits_bkg[fname_bkg.extname("BACKGROUND")]) | |
| 185 | + fits.append(fits_aeff[ext_aeff]) | |
| 186 | + fits.append(fits_psf[ext_psf]) | |
| 187 | + fits.append(fits_edisp[ext_edisp]) | |
| 188 | + fits.append(fits_bkg[ext_bkg]) | |
| 189 | + | |
| 190 | + # Log resulting FITS file | |
| 191 | + if self._logNormal(): | |
| 192 | + self._log(str(fits)) | |
| 193 | + self._log("\n") | |
| 194 | + if self._logExplicit(): | |
| 195 | + self._log(str(fits[ext_aeff].header())) | |
| 196 | + self._log("\n") | |
| 197 | + self._log(str(fits[ext_psf].header())) | |
| 198 | + self._log("\n") | |
| 199 | + self._log(str(fits[ext_edisp].header())) | |
| 200 | + self._log("\n") | |
| 201 | + self._log(str(fits[ext_bkg].header())) | |
| 202 | + self._log("\n") | |
| 154 | 203 | |
| 155 | 204 | # Return fits file |
| 156 | 205 | return fits |
| ... | ... | @@ -235,7 +284,7 @@ class csobs2caldb(ctools.cscript): |
| 235 | 284 | |
| 236 | 285 | # Set element |
| 237 | 286 | table["TELESCOP"][row] = self._mission |
| 238 | - table["INSTRUME"][row] = self._instrument | |
| 287 | + table["INSTRUME"][row] = self._caldb | |
| 239 | 288 | table["DETNAM"][row] = "NONE" |
| 240 | 289 | table["FILTER"][row] = "NONE" |
| 241 | 290 | table["CAL_DEV"][row] = "ONLINE" |
| ... | ... | @@ -245,7 +294,7 @@ class csobs2caldb(ctools.cscript): |
| 245 | 294 | table["CAL_VST"][row] = time.split(".")[0] |
| 246 | 295 | table["REF_TIME"][row] = 51544.0 |
| 247 | 296 | table["CAL_QUAL"][row] = 0 |
| 248 | - table["CAL_CBD"][row] = "NAME("+self._rspname+")" | |
| 297 | + table["CAL_CBD"][row] = "NAME("+self["irf"].string()+")" | |
| 249 | 298 | table["CAL_DATE"][row] = today.replace("-","/")[2:] |
| 250 | 299 | table["CAL_DIR"][row] = self._cal_dir |
| 251 | 300 | table["CAL_FILE"][row] = self._outfile |
| ... | ... | @@ -253,22 +302,30 @@ class csobs2caldb(ctools.cscript): |
| 253 | 302 | # Add effective area information |
| 254 | 303 | row = row_index-4 |
| 255 | 304 | table["CAL_CNAM"][row] = "EFF_AREA" |
| 256 | - table["CAL_DESC"][row] = self._instrument+" effective area" | |
| 305 | + table["CAL_DESC"][row] = self._caldb+" effective area" | |
| 257 | 306 | |
| 258 | 307 | # Add point spread function information |
| 259 | 308 | row = row_index-3 |
| 260 | 309 | table["CAL_CNAM"][row] = "RPSF" |
| 261 | - table["CAL_DESC"][row] = self._instrument+" point spread function" | |
| 310 | + table["CAL_DESC"][row] = self._caldb+" point spread function" | |
| 262 | 311 | |
| 263 | 312 | # Add energy dispersion information |
| 264 | 313 | row = row_index-2 |
| 265 | 314 | table["CAL_CNAM"][row] = "EDISP" |
| 266 | - table["CAL_DESC"][row] = self._instrument+" energy dispersion" | |
| 315 | + table["CAL_DESC"][row] = self._caldb+" energy dispersion" | |
| 267 | 316 | |
| 268 | 317 | # Add background information |
| 269 | 318 | row = row_index-1 |
| 270 | 319 | table["CAL_CNAM"][row] = "BGD" |
| 271 | - table["CAL_DESC"][row] = self._instrument+" background" | |
| 320 | + table["CAL_DESC"][row] = self._caldb+" background" | |
| 321 | + | |
| 322 | + # Log resulting FITS table and header | |
| 323 | + if self._logNormal(): | |
| 324 | + self._log(str(table)) | |
| 325 | + self._log("\n") | |
| 326 | + if self._logExplicit(): | |
| 327 | + self._log(str(table.header())) | |
| 328 | + self._log("\n") | |
| 272 | 329 | |
| 273 | 330 | # Return CIF FITS file |
| 274 | 331 | return cif |
| ... | ... | @@ -283,34 +340,40 @@ class csobs2caldb(ctools.cscript): |
| 283 | 340 | self._log.header2("Creating directory structure") |
| 284 | 341 | |
| 285 | 342 | # Create calibration database |
| 286 | - caldb = gammalib.GCaldb() | |
| 343 | + caldb = gammalib.GCaldb(self["rootdir"].string()) | |
| 287 | 344 | |
| 288 | 345 | # Set calibration directory |
| 289 | 346 | self._cal_dir = "data" |
| 290 | 347 | self._cal_dir += "/"+self._mission.lower() |
| 291 | - self._cal_dir += "/"+self._instrument.lower() | |
| 292 | - self._cal_dir += "/bcf/"+self._rspname | |
| 348 | + self._cal_dir += "/"+self._caldb.lower() | |
| 349 | + self._cal_dir += "/bcf/"+self["irf"].string() | |
| 293 | 350 | |
| 294 | 351 | # Set absolute path |
| 295 | 352 | self._base_dir = caldb.rootdir() +"/data" |
| 296 | 353 | self._base_dir += "/"+self._mission.lower() |
| 297 | - self._base_dir += "/"+self._instrument.lower() | |
| 354 | + self._base_dir += "/"+self._caldb.lower() | |
| 298 | 355 | |
| 299 | 356 | # Set directory for irf file |
| 300 | 357 | self._rsp_dir = caldb.rootdir() + "/" + self._cal_dir |
| 358 | + | |
| 359 | + # Log resulting FITS table | |
| 360 | + if self._logNormal(): | |
| 361 | + self._log(gammalib.parformat("Calibration directory")) | |
| 362 | + self._log(self._cal_dir) | |
| 363 | + self._log("\n") | |
| 364 | + self._log(gammalib.parformat("Base directory")) | |
| 365 | + self._log(self._base_dir) | |
| 366 | + self._log("\n") | |
| 367 | + if not os.path.isdir(self._rsp_dir): | |
| 368 | + self._log(gammalib.parformat("IRF directory")) | |
| 369 | + else: | |
| 370 | + self._log(gammalib.parformat("IRF directory (existing)")) | |
| 371 | + self._log(self._rsp_dir) | |
| 372 | + self._log("\n") | |
| 301 | 373 | |
| 302 | - # Create directories and log information | |
| 374 | + # Create IRF directory is it does not yet exist | |
| 303 | 375 | if not os.path.isdir(self._rsp_dir): |
| 304 | - if self._logExplicit(): | |
| 305 | - self._log(gammalib.parformat("Directory")) | |
| 306 | - self._log(self._rsp_dir) | |
| 307 | - self._log("\n") | |
| 308 | 376 | os.makedirs(self._rsp_dir) |
| 309 | - else: | |
| 310 | - if self._logExplicit(): | |
| 311 | - self._log(gammalib.parformat("Directory (existing)")) | |
| 312 | - self._log(self._rsp_dir) | |
| 313 | - self._log("\n") | |
| 314 | 377 | |
| 315 | 378 | # Return |
| 316 | 379 | return |
| ... | ... | @@ -330,8 +393,7 @@ class csobs2caldb(ctools.cscript): |
| 330 | 393 | |
| 331 | 394 | # Write input parameters and header into logger |
| 332 | 395 | if self._logTerse(): |
| 333 | - self._log_parameters() | |
| 334 | - self._log("\n\n") | |
| 396 | + self._log("\n") | |
| 335 | 397 | self._log.header1("Creating CALDB entry") |
| 336 | 398 | |
| 337 | 399 | # Create directory structure |
| ... | ... | @@ -359,7 +421,7 @@ class csobs2caldb(ctools.cscript): |
| 359 | 421 | filename = self._rsp_dir + "/" + self._outfile |
| 360 | 422 | |
| 361 | 423 | # Write filenames into logger |
| 362 | - if self._logTerse(): | |
| 424 | + if self._logNormal(): | |
| 363 | 425 | self._log(gammalib.parformat("CALDB index file")) |
| 364 | 426 | self._log(self._caldb_inx.filename().url()) |
| 365 | 427 | self._log("\n") |
| ... | ... | @@ -368,10 +430,10 @@ class csobs2caldb(ctools.cscript): |
| 368 | 430 | self._log("\n") |
| 369 | 431 | |
| 370 | 432 | # Save caldb index file |
| 371 | - self._caldb_inx.save(self._clobber) | |
| 433 | + self._caldb_inx.save(self._clobber()) | |
| 372 | 434 | |
| 373 | 435 | # Save response file |
| 374 | - self._irf_fits.saveto(filename, self._clobber) | |
| 436 | + self._irf_fits.saveto(filename, self._clobber()) | |
| 375 | 437 | |
| 376 | 438 | # Return |
| 377 | 439 | return |
| ... | ... | @@ -381,7 +443,7 @@ class csobs2caldb(ctools.cscript): |
| 381 | 443 | Execute the script. |
| 382 | 444 | """ |
| 383 | 445 | # Open logfile |
| 384 | - self._logFileOpen() | |
| 446 | + self.logFileOpen() | |
| 385 | 447 | |
| 386 | 448 | # Run the script |
| 387 | 449 | self.run() | ... | ... |
doc/source/reference_manual/csobs2caldb.rst
| ... | ... | @@ -28,12 +28,18 @@ General parameters |
| 28 | 28 | ``inobs [file]`` |
| 29 | 29 | Input event list, counts cube or observation definition XML file. |
| 30 | 30 | |
| 31 | -``rspname [string]`` | |
| 32 | - Response output name (e.g. Zenith50). | |
| 31 | +``caldb [string]`` | |
| 32 | + Calibration database. | |
| 33 | + | |
| 34 | +``irf [string]`` | |
| 35 | + Instrument response function (e.g. Standard). | |
| 33 | 36 | |
| 34 | 37 | ``(outirfs = irf_file.fits) [file]`` |
| 35 | 38 | Output IRF file name. |
| 36 | 39 | |
| 40 | +``(rootdir = ) [string]`` | |
| 41 | + Optional CALDB root directory. | |
| 42 | + | |
| 37 | 43 | ``(index = 0) [integer]`` |
| 38 | 44 | Index of observation to be used from XML file. |
| 39 | 45 | ... | ... |
test/test_cscripts.sh.in
| ... | ... | @@ -77,14 +77,15 @@ $ECHO -n "Test csobs2caldb: " |
| 77 | 77 | chmod +x @abs_top_srcdir@/cscripts/csobs2caldb.py |
| 78 | 78 | @PYTHON_COVERAGE@@abs_top_srcdir@/cscripts/csobs2caldb.py \ |
| 79 | 79 | inobs="data/obs_unbinned.xml" \ |
| 80 | - rspname="test_irfs" \ | |
| 80 | + caldb="cta" \ | |
| 81 | + irf="Standard" \ | |
| 81 | 82 | chatter=4 > csobs2caldb.log |
| 82 | 83 | $ECHO -n "." |
| 83 | -if [ -s "$CALDB/data/cta/cta/bcf/test_irfs/irf_file.fits" ] | |
| 84 | +if [ -s "$CALDB/data/cta/cta/bcf/Standard/irf_file.fits" ] | |
| 84 | 85 | then |
| 85 | 86 | $ECHO -n "." |
| 86 | 87 | else |
| 87 | - $ECHO " $CALDB/data/cta/cta/bcf/test_irfs/irf_file.fits file is not valid" | |
| 88 | + $ECHO " $CALDB/data/cta/cta/bcf/Standard/irf_file.fits file is not valid" | |
| 88 | 89 | exit 1 |
| 89 | 90 | fi |
| 90 | 91 | $ECHO " ok" |
| ... | ... | @@ -282,7 +283,7 @@ chmod +x @abs_top_srcdir@/cscripts/cspull.py |
| 282 | 283 | outfile="pull.dat" \ |
| 283 | 284 | ntrials="3" \ |
| 284 | 285 | caldb="cta" \ |
| 285 | - irf="test_irfs" \ | |
| 286 | + irf="Standard" \ | |
| 286 | 287 | ra=83.6331 \ |
| 287 | 288 | dec=22.0145 \ |
| 288 | 289 | emin=0.1 \ | ... | ... |
test/test_csobs2caldb.py
0 → 100755
| 1 | +#! /usr/bin/env python | |
| 2 | +# ========================================================================== | |
| 3 | +# This scripts performs unit tests for the csobs2caldb script. | |
| 4 | +# | |
| 5 | +# Copyright (C) 2016 Juergen Knoedlseder | |
| 6 | +# | |
| 7 | +# This program is free software: you can redistribute it and/or modify | |
| 8 | +# it under the terms of the GNU General Public License as published by | |
| 9 | +# the Free Software Foundation, either version 3 of the License, or | |
| 10 | +# (at your option) any later version. | |
| 11 | +# | |
| 12 | +# This program is distributed in the hope that it will be useful, | |
| 13 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | +# GNU General Public License for more details. | |
| 16 | +# | |
| 17 | +# You should have received a copy of the GNU General Public License | |
| 18 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 19 | +# | |
| 20 | +# ========================================================================== | |
| 21 | +import os | |
| 22 | +import gammalib | |
| 23 | +import cscripts | |
| 24 | + | |
| 25 | + | |
| 26 | +# ================================= # | |
| 27 | +# Test class for csobs2caldb script # | |
| 28 | +# ================================= # | |
| 29 | +class Test(gammalib.GPythonTestSuite): | |
| 30 | + """ | |
| 31 | + Test class for csobs2caldb script. | |
| 32 | + | |
| 33 | + This test class makes unit tests for the csobs2caldb script by using it | |
| 34 | + from the command line and from Python. | |
| 35 | + """ | |
| 36 | + | |
| 37 | + # Constructor | |
| 38 | + def __init__(self): | |
| 39 | + """ | |
| 40 | + Constructor. | |
| 41 | + """ | |
| 42 | + # Call base class constructor | |
| 43 | + gammalib.GPythonTestSuite.__init__(self) | |
| 44 | + | |
| 45 | + # Set members | |
| 46 | + self._inobs = "data/obs_unbinned.xml" | |
| 47 | + | |
| 48 | + # Clean calibration database | |
| 49 | + os.system("rm -rf caldb >/dev/null 2>&1") | |
| 50 | + os.system("mkdir -p caldb >/dev/null 2>&1") | |
| 51 | + | |
| 52 | + # Return | |
| 53 | + return | |
| 54 | + | |
| 55 | + # Set test functions | |
| 56 | + def set(self): | |
| 57 | + """ | |
| 58 | + Set all test functions. | |
| 59 | + """ | |
| 60 | + # Set test name | |
| 61 | + self.name("csobs2caldb") | |
| 62 | + | |
| 63 | + # Append tests | |
| 64 | + self.append(self._test_cmd, "Test csobs2caldb on command line") | |
| 65 | + self.append(self._test_python, "Test csobs2caldb from Python") | |
| 66 | + | |
| 67 | + # Return | |
| 68 | + return | |
| 69 | + | |
| 70 | + # Test csobs2caldb on command line | |
| 71 | + def _test_cmd(self): | |
| 72 | + """ | |
| 73 | + Test csobs2caldb on the command line. | |
| 74 | + """ | |
| 75 | + # Kluge to set the command (installed version has no README file) | |
| 76 | + if os.path.isfile("README"): | |
| 77 | + csobs2caldb = "../cscripts/csobs2caldb.py" | |
| 78 | + else: | |
| 79 | + csobs2caldb = "csobs2caldb" | |
| 80 | + | |
| 81 | + # Setup csobs2caldb command | |
| 82 | + cmd = csobs2caldb+' inobs="'+self._inobs+'"'+ \ | |
| 83 | + ' caldb="cta" irf="Cmd1" rootdir="caldb"'+ \ | |
| 84 | + ' logfile="csobs2caldb_cmd1.log" chatter=1' | |
| 85 | + | |
| 86 | + # Execute csobs2caldb, make sure we catch any exception | |
| 87 | + try: | |
| 88 | + rc = os.system(cmd+" >/dev/null 2>&1") | |
| 89 | + except: | |
| 90 | + pass | |
| 91 | + | |
| 92 | + # Check if execution was successful | |
| 93 | + self.test_assert(rc == 0, | |
| 94 | + "Successful csobs2caldb execution on command line") | |
| 95 | + | |
| 96 | + # Check response | |
| 97 | + self._check_response("cta", "Cmd1") | |
| 98 | + | |
| 99 | + # Setup csobs2caldb command | |
| 100 | + cmd = csobs2caldb+' inobs="xml_file_that_does_not_exist.xml"'+ \ | |
| 101 | + ' caldb="cta" irf="Cmd2" rootdir="caldb"'+ \ | |
| 102 | + ' logfile="csobs2caldb_cmd2.log"' | |
| 103 | + | |
| 104 | + # Execute csobs2caldb, make sure we catch any exception | |
| 105 | + try: | |
| 106 | + rc = os.system(cmd+" >/dev/null 2>&1") | |
| 107 | + except: | |
| 108 | + pass | |
| 109 | + | |
| 110 | + # Check if execution failed | |
| 111 | + self.test_assert(rc != 0, | |
| 112 | + "Failure of csobs2caldb execution on command line") | |
| 113 | + | |
| 114 | + # Return | |
| 115 | + return | |
| 116 | + | |
| 117 | + # Test csobs2caldb from Python | |
| 118 | + def _test_python(self): | |
| 119 | + """ | |
| 120 | + Test csobs2caldb from Python. | |
| 121 | + """ | |
| 122 | + # Set-up csobs2caldb using "inobs" parameter | |
| 123 | + irf = cscripts.csobs2caldb() | |
| 124 | + irf["inobs"] = self._inobs | |
| 125 | + irf["caldb"] = "cta" | |
| 126 | + irf["irf"] = "Py1" | |
| 127 | + irf["rootdir"] = "caldb" | |
| 128 | + irf["logfile"] = "csobs2caldb_py1.log" | |
| 129 | + irf["chatter"] = 2 | |
| 130 | + | |
| 131 | + # Run csobs2caldb script and save IRF | |
| 132 | + irf.logFileOpen() # Make sure we get a log file | |
| 133 | + irf.run() | |
| 134 | + irf.save() | |
| 135 | + | |
| 136 | + # Check response | |
| 137 | + self._check_response("cta", "Py1") | |
| 138 | + | |
| 139 | + # Load observation container | |
| 140 | + obs = gammalib.GObservations(self._inobs) | |
| 141 | + | |
| 142 | + # Set-up csobs2caldb using observation container | |
| 143 | + irf = cscripts.csobs2caldb(obs) | |
| 144 | + irf["caldb"] = "cta" | |
| 145 | + irf["irf"] = "Py2" | |
| 146 | + irf["rootdir"] = "caldb" | |
| 147 | + irf["logfile"] = "csobs2caldb_py2.log" | |
| 148 | + irf["chatter"] = 3 | |
| 149 | + | |
| 150 | + # Execute csobs2caldb script | |
| 151 | + irf.execute() | |
| 152 | + | |
| 153 | + # Check response | |
| 154 | + self._check_response("cta", "Py2") | |
| 155 | + | |
| 156 | + # Return | |
| 157 | + return | |
| 158 | + | |
| 159 | + # Check response | |
| 160 | + def _check_response(self, caldb, irf): | |
| 161 | + """ | |
| 162 | + Check response. | |
| 163 | + """ | |
| 164 | + # Open calibration database | |
| 165 | + db = gammalib.GCaldb("caldb") | |
| 166 | + db.open("cta", caldb) | |
| 167 | + | |
| 168 | + # Get filenames of response components | |
| 169 | + expr = "NAME("+irf+")" | |
| 170 | + aeff = gammalib.GFilename(db.filename("","","EFF_AREA","","",expr)) | |
| 171 | + psf = gammalib.GFilename(db.filename("","","RPSF","","",expr)) | |
| 172 | + edisp = gammalib.GFilename(db.filename("","","EDISP","","",expr)) | |
| 173 | + bgd = gammalib.GFilename(db.filename("","","BGD","","",expr)) | |
| 174 | + | |
| 175 | + # Check whether files exist | |
| 176 | + self.test_assert(aeff.exists(), "Effective area file exists") | |
| 177 | + self.test_assert(psf.exists(), "Point spread function file exists") | |
| 178 | + self.test_assert(edisp.exists(), "Energy dispersion file exists") | |
| 179 | + self.test_assert(bgd.exists(), "Background file exists") | |
| 180 | + | |
| 181 | + # Return | |
| 182 | + return | ... | ... |
test/test_python_cscripts.py
| 1 | 1 | #! /usr/bin/env python |
| 2 | 2 | # ========================================================================== |
| 3 | -# This scripts performs unit tests for cscripts used from Python. | |
| 3 | +# This scripts performs unit tests for cscripts. | |
| 4 | 4 | # |
| 5 | 5 | # Copyright (C) 2016 Juergen Knoedlseder |
| 6 | 6 | # |
| ... | ... | @@ -24,6 +24,7 @@ import gammalib |
| 24 | 24 | import cscripts |
| 25 | 25 | sys.path.append(os.path.dirname(os.path.abspath(__file__))) |
| 26 | 26 | import test_cscaldb |
| 27 | +import test_csobs2caldb | |
| 27 | 28 | import test_cslightcrv |
| 28 | 29 | |
| 29 | 30 | |
| ... | ... | @@ -32,21 +33,24 @@ import test_cslightcrv |
| 32 | 33 | # ================== # |
| 33 | 34 | def test(installed=False): |
| 34 | 35 | """ |
| 35 | - Perform unit testing for Python interface. | |
| 36 | + Perform cscripts unit testing. | |
| 36 | 37 | """ |
| 37 | 38 | # Allocate test suite container |
| 38 | - suites = gammalib.GTestSuites("cscripts Python module unit testing") | |
| 39 | + suites = gammalib.GTestSuites("cscripts unit testing") | |
| 39 | 40 | |
| 40 | 41 | # Allocate test suites and append them to the container |
| 41 | - suite_cscaldb = test_cscaldb.Test() | |
| 42 | - suite_cslightcrv = test_cslightcrv.Test() | |
| 42 | + suite_cscaldb = test_cscaldb.Test() | |
| 43 | + suite_csobs2caldb = test_csobs2caldb.Test() | |
| 44 | + suite_cslightcrv = test_cslightcrv.Test() | |
| 43 | 45 | |
| 44 | 46 | # Setup unit tests |
| 45 | 47 | suite_cscaldb.set() |
| 48 | + suite_csobs2caldb.set() | |
| 46 | 49 | suite_cslightcrv.set() |
| 47 | 50 | |
| 48 | 51 | # Append tests to container |
| 49 | 52 | suites.append(suite_cscaldb) |
| 53 | + suites.append(suite_csobs2caldb) | |
| 50 | 54 | suites.append(suite_cslightcrv) |
| 51 | 55 | |
| 52 | 56 | # If we have an installed version then create a temporary directory and | ... | ... |