Commit 0181f9405a1230e051919bed65524cae4fa9c22c

Authored by Jürgen Knödlseder
1 parent f662447a

Add csobs2caldb unit tests and change user parameter interface.

cscripts/Makefile.am
@@ -27,10 +27,12 @@ linkscripts = cspull cssens cstsdist cscaldb csresmap \ @@ -27,10 +27,12 @@ linkscripts = cspull cssens cstsdist cscaldb csresmap \
27 testscripts = tests/__init__.py \ 27 testscripts = tests/__init__.py \
28 ../test/test_python_cscripts.py \ 28 ../test/test_python_cscripts.py \
29 ../test/test_cscaldb.py \ 29 ../test/test_cscaldb.py \
  30 + ../test/test_csobs2caldb.py \
30 ../test/test_cslightcrv.py 31 ../test/test_cslightcrv.py
31 32
32 # Test data to be distributed in $(pyexecdir)/cscripts/tests/data 33 # Test data to be distributed in $(pyexecdir)/cscripts/tests/data
33 testdata = ../test/data/crab.xml \ 34 testdata = ../test/data/crab.xml \
  35 + ../test/data/obs_unbinned.xml \
34 ../test/data/crab_events.fits.gz \ 36 ../test/data/crab_events.fits.gz \
35 ../test/data/crab_cntmap.fits.gz \ 37 ../test/data/crab_cntmap.fits.gz \
36 ../test/data/exclusion.reg 38 ../test/data/exclusion.reg
cscripts/csobs2caldb.par
@@ -15,11 +15,13 @@ @@ -15,11 +15,13 @@
15 # # 15 # #
16 ############################################################################# 16 #############################################################################
17 # 17 #
18 -# General parameters  
19 -#=================== 18 +# Input and output parameters
  19 +#============================
20 inobs, f, a, obs.xml,,, "Observation definition XML file" 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 index, i, h, 0,,, "Index of observation to be used from XML file" 25 index, i, h, 0,,, "Index of observation to be used from XML file"
24 26
25 # 27 #
cscripts/csobs2caldb.py
1 #!/usr/bin/env python 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 # Copyright (C) 2015-2016 Michael Mayer 5 # Copyright (C) 2015-2016 Michael Mayer
6 # 6 #
@@ -30,7 +30,7 @@ import datetime @@ -30,7 +30,7 @@ import datetime
30 # ================= # 30 # ================= #
31 class csobs2caldb(ctools.cscript): 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 The creation of a calibration database entry is useful for performing 35 The creation of a calibration database entry is useful for performing
36 simulations for current Imaging Air Cherenkov Telescopes (IACTs). 36 simulations for current Imaging Air Cherenkov Telescopes (IACTs).
@@ -50,17 +50,17 @@ class csobs2caldb(ctools.cscript): @@ -50,17 +50,17 @@ class csobs2caldb(ctools.cscript):
50 self._version = "1.1.0" 50 self._version = "1.1.0"
51 51
52 # Initialise members 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 self._base_dir = "" 57 self._base_dir = ""
60 self._cal_dir = "" 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 self._init_cscript(argv) 64 self._init_cscript(argv)
65 65
66 # Return 66 # Return
@@ -70,36 +70,64 @@ class csobs2caldb(ctools.cscript): @@ -70,36 +70,64 @@ class csobs2caldb(ctools.cscript):
70 # Private methods 70 # Private methods
71 def _get_parameters(self): 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 # Get observation 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 if not self._observation.classname() == "GCTAObservation": 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 if not self._observation.response().classname() == "GCTAResponseIrf": 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 # Return 132 # Return
105 return 133 return
@@ -122,10 +150,11 @@ class csobs2caldb(ctools.cscript): @@ -122,10 +150,11 @@ class csobs2caldb(ctools.cscript):
122 fname_edisp = rsp.edisp().filename() 150 fname_edisp = rsp.edisp().filename()
123 fname_bkg = rsp.background().filename() 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 self._log(gammalib.parformat("Effective area")) 156 self._log(gammalib.parformat("Effective area"))
128 - self._log(repr(fname_aeff)) 157 + self._log(fname_aeff.url())
129 self._log("\n") 158 self._log("\n")
130 self._log(gammalib.parformat("Point spread function")) 159 self._log(gammalib.parformat("Point spread function"))
131 self._log(fname_psf.url()) 160 self._log(fname_psf.url())
@@ -142,15 +171,35 @@ class csobs2caldb(ctools.cscript): @@ -142,15 +171,35 @@ class csobs2caldb(ctools.cscript):
142 fits_psf = gammalib.GFits(fname_psf) 171 fits_psf = gammalib.GFits(fname_psf)
143 fits_edisp = gammalib.GFits(fname_edisp) 172 fits_edisp = gammalib.GFits(fname_edisp)
144 fits_bkg = gammalib.GFits(fname_bkg) 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 # Create empty FITS file 181 # Create empty FITS file
147 fits = gammalib.GFits() 182 fits = gammalib.GFits()
148 183
149 # Append IRF component to FITS file 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 # Return fits file 204 # Return fits file
156 return fits 205 return fits
@@ -235,7 +284,7 @@ class csobs2caldb(ctools.cscript): @@ -235,7 +284,7 @@ class csobs2caldb(ctools.cscript):
235 284
236 # Set element 285 # Set element
237 table["TELESCOP"][row] = self._mission 286 table["TELESCOP"][row] = self._mission
238 - table["INSTRUME"][row] = self._instrument 287 + table["INSTRUME"][row] = self._caldb
239 table["DETNAM"][row] = "NONE" 288 table["DETNAM"][row] = "NONE"
240 table["FILTER"][row] = "NONE" 289 table["FILTER"][row] = "NONE"
241 table["CAL_DEV"][row] = "ONLINE" 290 table["CAL_DEV"][row] = "ONLINE"
@@ -245,7 +294,7 @@ class csobs2caldb(ctools.cscript): @@ -245,7 +294,7 @@ class csobs2caldb(ctools.cscript):
245 table["CAL_VST"][row] = time.split(".")[0] 294 table["CAL_VST"][row] = time.split(".")[0]
246 table["REF_TIME"][row] = 51544.0 295 table["REF_TIME"][row] = 51544.0
247 table["CAL_QUAL"][row] = 0 296 table["CAL_QUAL"][row] = 0
248 - table["CAL_CBD"][row] = "NAME("+self._rspname+")" 297 + table["CAL_CBD"][row] = "NAME("+self["irf"].string()+")"
249 table["CAL_DATE"][row] = today.replace("-","/")[2:] 298 table["CAL_DATE"][row] = today.replace("-","/")[2:]
250 table["CAL_DIR"][row] = self._cal_dir 299 table["CAL_DIR"][row] = self._cal_dir
251 table["CAL_FILE"][row] = self._outfile 300 table["CAL_FILE"][row] = self._outfile
@@ -253,22 +302,30 @@ class csobs2caldb(ctools.cscript): @@ -253,22 +302,30 @@ class csobs2caldb(ctools.cscript):
253 # Add effective area information 302 # Add effective area information
254 row = row_index-4 303 row = row_index-4
255 table["CAL_CNAM"][row] = "EFF_AREA" 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 # Add point spread function information 307 # Add point spread function information
259 row = row_index-3 308 row = row_index-3
260 table["CAL_CNAM"][row] = "RPSF" 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 # Add energy dispersion information 312 # Add energy dispersion information
264 row = row_index-2 313 row = row_index-2
265 table["CAL_CNAM"][row] = "EDISP" 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 # Add background information 317 # Add background information
269 row = row_index-1 318 row = row_index-1
270 table["CAL_CNAM"][row] = "BGD" 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 # Return CIF FITS file 330 # Return CIF FITS file
274 return cif 331 return cif
@@ -283,34 +340,40 @@ class csobs2caldb(ctools.cscript): @@ -283,34 +340,40 @@ class csobs2caldb(ctools.cscript):
283 self._log.header2("Creating directory structure") 340 self._log.header2("Creating directory structure")
284 341
285 # Create calibration database 342 # Create calibration database
286 - caldb = gammalib.GCaldb() 343 + caldb = gammalib.GCaldb(self["rootdir"].string())
287 344
288 # Set calibration directory 345 # Set calibration directory
289 self._cal_dir = "data" 346 self._cal_dir = "data"
290 self._cal_dir += "/"+self._mission.lower() 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 # Set absolute path 351 # Set absolute path
295 self._base_dir = caldb.rootdir() +"/data" 352 self._base_dir = caldb.rootdir() +"/data"
296 self._base_dir += "/"+self._mission.lower() 353 self._base_dir += "/"+self._mission.lower()
297 - self._base_dir += "/"+self._instrument.lower() 354 + self._base_dir += "/"+self._caldb.lower()
298 355
299 # Set directory for irf file 356 # Set directory for irf file
300 self._rsp_dir = caldb.rootdir() + "/" + self._cal_dir 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 if not os.path.isdir(self._rsp_dir): 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 os.makedirs(self._rsp_dir) 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 # Return 378 # Return
316 return 379 return
@@ -330,8 +393,7 @@ class csobs2caldb(ctools.cscript): @@ -330,8 +393,7 @@ class csobs2caldb(ctools.cscript):
330 393
331 # Write input parameters and header into logger 394 # Write input parameters and header into logger
332 if self._logTerse(): 395 if self._logTerse():
333 - self._log_parameters()  
334 - self._log("\n\n") 396 + self._log("\n")
335 self._log.header1("Creating CALDB entry") 397 self._log.header1("Creating CALDB entry")
336 398
337 # Create directory structure 399 # Create directory structure
@@ -359,7 +421,7 @@ class csobs2caldb(ctools.cscript): @@ -359,7 +421,7 @@ class csobs2caldb(ctools.cscript):
359 filename = self._rsp_dir + "/" + self._outfile 421 filename = self._rsp_dir + "/" + self._outfile
360 422
361 # Write filenames into logger 423 # Write filenames into logger
362 - if self._logTerse(): 424 + if self._logNormal():
363 self._log(gammalib.parformat("CALDB index file")) 425 self._log(gammalib.parformat("CALDB index file"))
364 self._log(self._caldb_inx.filename().url()) 426 self._log(self._caldb_inx.filename().url())
365 self._log("\n") 427 self._log("\n")
@@ -368,10 +430,10 @@ class csobs2caldb(ctools.cscript): @@ -368,10 +430,10 @@ class csobs2caldb(ctools.cscript):
368 self._log("\n") 430 self._log("\n")
369 431
370 # Save caldb index file 432 # Save caldb index file
371 - self._caldb_inx.save(self._clobber) 433 + self._caldb_inx.save(self._clobber())
372 434
373 # Save response file 435 # Save response file
374 - self._irf_fits.saveto(filename, self._clobber) 436 + self._irf_fits.saveto(filename, self._clobber())
375 437
376 # Return 438 # Return
377 return 439 return
@@ -381,7 +443,7 @@ class csobs2caldb(ctools.cscript): @@ -381,7 +443,7 @@ class csobs2caldb(ctools.cscript):
381 Execute the script. 443 Execute the script.
382 """ 444 """
383 # Open logfile 445 # Open logfile
384 - self._logFileOpen() 446 + self.logFileOpen()
385 447
386 # Run the script 448 # Run the script
387 self.run() 449 self.run()
doc/source/reference_manual/csobs2caldb.rst
@@ -28,12 +28,18 @@ General parameters @@ -28,12 +28,18 @@ General parameters
28 ``inobs [file]`` 28 ``inobs [file]``
29 Input event list, counts cube or observation definition XML file. 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 ``(outirfs = irf_file.fits) [file]`` 37 ``(outirfs = irf_file.fits) [file]``
35 Output IRF file name. 38 Output IRF file name.
36 39
  40 +``(rootdir = ) [string]``
  41 + Optional CALDB root directory.
  42 +
37 ``(index = 0) [integer]`` 43 ``(index = 0) [integer]``
38 Index of observation to be used from XML file. 44 Index of observation to be used from XML file.
39 45
test/test_cscripts.sh.in
@@ -77,14 +77,15 @@ $ECHO -n &quot;Test csobs2caldb: &quot; @@ -77,14 +77,15 @@ $ECHO -n &quot;Test csobs2caldb: &quot;
77 chmod +x @abs_top_srcdir@/cscripts/csobs2caldb.py 77 chmod +x @abs_top_srcdir@/cscripts/csobs2caldb.py
78 @PYTHON_COVERAGE@@abs_top_srcdir@/cscripts/csobs2caldb.py \ 78 @PYTHON_COVERAGE@@abs_top_srcdir@/cscripts/csobs2caldb.py \
79 inobs="data/obs_unbinned.xml" \ 79 inobs="data/obs_unbinned.xml" \
80 - rspname="test_irfs" \ 80 + caldb="cta" \
  81 + irf="Standard" \
81 chatter=4 > csobs2caldb.log 82 chatter=4 > csobs2caldb.log
82 $ECHO -n "." 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 then 85 then
85 $ECHO -n "." 86 $ECHO -n "."
86 else 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 exit 1 89 exit 1
89 fi 90 fi
90 $ECHO " ok" 91 $ECHO " ok"
@@ -282,7 +283,7 @@ chmod +x @abs_top_srcdir@/cscripts/cspull.py @@ -282,7 +283,7 @@ chmod +x @abs_top_srcdir@/cscripts/cspull.py
282 outfile="pull.dat" \ 283 outfile="pull.dat" \
283 ntrials="3" \ 284 ntrials="3" \
284 caldb="cta" \ 285 caldb="cta" \
285 - irf="test_irfs" \ 286 + irf="Standard" \
286 ra=83.6331 \ 287 ra=83.6331 \
287 dec=22.0145 \ 288 dec=22.0145 \
288 emin=0.1 \ 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 #! /usr/bin/env python 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 # Copyright (C) 2016 Juergen Knoedlseder 5 # Copyright (C) 2016 Juergen Knoedlseder
6 # 6 #
@@ -24,6 +24,7 @@ import gammalib @@ -24,6 +24,7 @@ import gammalib
24 import cscripts 24 import cscripts
25 sys.path.append(os.path.dirname(os.path.abspath(__file__))) 25 sys.path.append(os.path.dirname(os.path.abspath(__file__)))
26 import test_cscaldb 26 import test_cscaldb
  27 +import test_csobs2caldb
27 import test_cslightcrv 28 import test_cslightcrv
28 29
29 30
@@ -32,21 +33,24 @@ import test_cslightcrv @@ -32,21 +33,24 @@ import test_cslightcrv
32 # ================== # 33 # ================== #
33 def test(installed=False): 34 def test(installed=False):
34 """ 35 """
35 - Perform unit testing for Python interface. 36 + Perform cscripts unit testing.
36 """ 37 """
37 # Allocate test suite container 38 # Allocate test suite container
38 - suites = gammalib.GTestSuites("cscripts Python module unit testing") 39 + suites = gammalib.GTestSuites("cscripts unit testing")
39 40
40 # Allocate test suites and append them to the container 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 # Setup unit tests 46 # Setup unit tests
45 suite_cscaldb.set() 47 suite_cscaldb.set()
  48 + suite_csobs2caldb.set()
46 suite_cslightcrv.set() 49 suite_cslightcrv.set()
47 50
48 # Append tests to container 51 # Append tests to container
49 suites.append(suite_cscaldb) 52 suites.append(suite_cscaldb)
  53 + suites.append(suite_csobs2caldb)
50 suites.append(suite_cslightcrv) 54 suites.append(suite_cslightcrv)
51 55
52 # If we have an installed version then create a temporary directory and 56 # If we have an installed version then create a temporary directory and