Commit add41cca75fdc1eab5a96277758d977b7db06a81

Authored by Jürgen Knödlseder
1 parent 14d95915

Integrate branch

cscripts/Makefile.am
... ... @@ -152,7 +152,8 @@ testdata = $(top_srcdir)/test/data/crab.xml \
152 152 $(top_srcdir)/test/data/models_spectral.xml \
153 153 $(top_srcdir)/test/data/model_filefunction.txt \
154 154 $(top_srcdir)/test/data/model_map.fits.gz \
155   - $(top_srcdir)/test/data/model_mapcube.fits.gz
  155 + $(top_srcdir)/test/data/model_mapcube.fits.gz \
  156 + $(top_srcdir)/test/data/iact_runlist.dat
156 157  
157 158 # Test data to be distributed in $(pyexecdir)/cscripts/tests/data/iactdata
158 159 testiactdata = $(top_srcdir)/test/data/iactdata/hdu-index.fits.gz \
... ...
cscripts/csiactobs.py
... ... @@ -47,9 +47,10 @@ class csiactobs(ctools.cscript):
47 47 """
48 48 # Set name and version
49 49 self._name = 'csiactobs'
50   - self._version = '1.1.0'
  50 + self._version = '1.2.0'
51 51  
52 52 # Initialise some members
  53 + self._obs = gammalib.GObservations()
53 54 self._ebounds = gammalib.GEbounds()
54 55 self._datapath = os.getenv('VHEFITS','')
55 56 self._inmodels = gammalib.GModels()
... ... @@ -59,8 +60,8 @@ class csiactobs(ctools.cscript):
59 60 self._runlist = []
60 61 self._runlistfile = gammalib.GFilename()
61 62 self._bkgpars = 0
62   - self._outmodel = gammalib.GFilename()
63   - self._outobs = gammalib.GFilename()
  63 + #self._outmodel = gammalib.GFilename()
  64 + #self._outobs = gammalib.GFilename()
64 65 self._master_indx = ''
65 66 self._use_bkg_scale = False
66 67 self._ev_hiera = ['']
... ... @@ -80,8 +81,7 @@ class csiactobs(ctools.cscript):
80 81 self._subdir = ''
81 82 self._debug = False
82 83  
83   - # Initialise application by calling the appropriate class
84   - # constructor.
  84 + # Initialise application by calling the appropriate class constructor
85 85 self._init_cscript(argv)
86 86  
87 87 # Return
... ... @@ -91,7 +91,7 @@ class csiactobs(ctools.cscript):
91 91 # Private methods
92 92 def _get_parameters(self):
93 93 """
94   - Get parameters from parfile and setup the observation.
  94 + Get parameters from parfile and setup the observation
95 95 """
96 96 # Set data path
97 97 if self._datapath == '':
... ... @@ -105,7 +105,7 @@ class csiactobs(ctools.cscript):
105 105 self._datapath = gammalib.expand_env(self._datapath)
106 106  
107 107 # Read FITS production
108   - self._prodname = self['prodname'].string()
  108 + self._prodname = self['prodname'].string()
109 109  
110 110 # Read runlist file if list not already filled
111 111 if len(self._runlist) == 0:
... ... @@ -125,13 +125,12 @@ class csiactobs(ctools.cscript):
125 125 runfile.close()
126 126  
127 127 # Read number of background parameters
128   - self._bkgpars = self['bkgpars'].integer()
129   -
130   - # Output model file
131   - self._outmodel = self['outmodel'].filename()
132   -
133   - # Observation outfile
134   - self._outobs = self['outobs'].filename()
  128 + self._bkgpars = self['bkgpars'].integer()
  129 +
  130 + # Query ahead output parameters
  131 + if self._read_ahead():
  132 + self['outmodel'].filename()
  133 + self['outobs'].filename()
135 134  
136 135 # Master index file name
137 136 self._master_indx = self['master_indx'].string()
... ... @@ -227,30 +226,6 @@ class csiactobs(ctools.cscript):
227 226 # Return
228 227 return
229 228  
230   - def runlist(self, runlist):
231   - """
232   - Set observation list
233   -
234   - Parameters
235   - ----------
236   - runlist : list
237   - List of observation IDs
238   - """
239   -
240   - # Check if convertable to a python list
241   - try:
242   -
243   - # Store a copy of input argument
244   - self._runlist = list(runlist)
245   -
246   - except:
247   -
248   - # raise error if wrong type detected
249   - raise RuntimeError('Argument of csiactobs.runlist() must be of type "list"')
250   -
251   - # Return
252   - return
253   -
254 229 def _background_spectrum(self, prefactor, index, emin = 0.01, emax = 100.0):
255 230 """
256 231 Create a background spectrum model dependent on user parameters
... ... @@ -767,17 +742,64 @@ class csiactobs(ctools.cscript):
767 742  
768 743 def save(self):
769 744 """
770   - Save model definition XML file
  745 + Save observation definition and model definition XML file
771 746 """
772   - # Save observation XML file
773   - self._xml.save(self._outobs)
  747 + # Write header
  748 + if self._logTerse():
  749 + self._log('\n')
  750 + self._log.header1('Save XML files')
  751 +
  752 + # Get filenames
  753 + outobs = self['outobs'].filename()
  754 + outmodel = self['outmodel'].filename()
  755 +
  756 + # Log file name
  757 + if self._logTerse():
  758 + self._log(gammalib.parformat('Obs. definition XML file'))
  759 + self._log(outobs.url())
  760 + self._log('\n')
  761 +
  762 + # Save observation definition XML file
  763 + self._xml.save(outobs.url())
  764 +
  765 + # Log file name
  766 + if self._logTerse():
  767 + self._log(gammalib.parformat('Model definiton XML file'))
  768 + self._log(outmodel.url())
  769 + self._log('\n')
774 770  
775 771 # Save model XML file
776   - self._models.save(self._outmodel)
  772 + self._models.save(outmodel.url())
777 773  
778 774 # Return
779 775 return
780 776  
  777 + def runlist(self, runlist):
  778 + """
  779 + Set runlist
  780 +
  781 + Parameters
  782 + ----------
  783 + runlist : list
  784 + List of observation IDs
  785 +
  786 + Raises
  787 + ------
  788 + RuntimeError
  789 + Input runlist is not a Python list
  790 + """
  791 + # If the runlist is convertable to a Python list then store the
  792 + # runlist in the class
  793 + try:
  794 + self._runlist = list(runlist)
  795 +
  796 + # ... otherwise raise an exception
  797 + except:
  798 + raise RuntimeError('Argument is not a Python list')
  799 +
  800 + # Return
  801 + return
  802 +
781 803 def ebounds(self):
782 804 """
783 805 Return runlist energy boundaries
... ... @@ -787,20 +809,20 @@ class csiactobs(ctools.cscript):
787 809  
788 810 def obs(self):
789 811 """
790   - Returns GObservations object
  812 + Return observations container
791 813 """
792   - # Initialise observations
793   - obs = gammalib.GObservations()
  814 + # Clear observations
  815 + self._obs.clear()
794 816  
795 817 # Read observations if XML is filled
796 818 if self._xml.size():
797   - obs.read(self._xml)
  819 + self._obs.read(self._xml)
798 820  
799 821 # Assign models
800   - obs.models(self._models)
  822 + self._obs.models(self._models)
801 823  
802 824 # Return observations
803   - return obs
  825 + return self._obs
804 826  
805 827  
806 828 # ======================== #
... ...
test/data/iact_runlist.dat 0 → 100644
  1 +0
... ...
test/test_csiactdata.py
1 1 #! /usr/bin/env python
2 2 # ==========================================================================
3   -# This scripts performs unit tests for the csiactdata script.
  3 +# This scripts performs unit tests for the csiactdata script
4 4 #
5 5 # Copyright (C) 2016 Juergen Knoedlseder
6 6 #
... ...
test/test_csiactobs.py
1 1 #! /usr/bin/env python
2 2 # ==========================================================================
3   -# This scripts performs unit tests for the csiactobs script.
  3 +# This scripts performs unit tests for the csiactobs script
4 4 #
5 5 # Copyright (C) 2016 Juergen Knoedlseder
6 6 #
... ... @@ -44,6 +44,7 @@ class Test(test):
44 44  
45 45 # Set data members
46 46 self._datapath = self._datadir + '/iactdata'
  47 + self._runlist = self._datadir + '/iact_runlist.dat'
47 48  
48 49 # Return
49 50 return
... ... @@ -74,10 +75,10 @@ class Test(test):
74 75 # Setup csiactobs command
75 76 cmd = csiactobs+' datapath="'+self._datapath+'"'+ \
76 77 ' prodname="unit-test"'+ \
77   - ' infile="runlist_cmd1.dat"'+ \
  78 + ' infile="'+self._runlist+'"'+ \
78 79 ' bkgpars=1'+\
79   - ' outobs="obs_iactobs_cmd1.xml"'+ \
80   - ' outmodel="bkg_iactobs_cmd1.xml"'+ \
  80 + ' outobs="csiactobs_obs_cmd1.xml"'+ \
  81 + ' outmodel="csiactobs_bgd_cmd1.xml"'+ \
81 82 ' logfile="csiactobs_cmd1.log" chatter=1'
82 83  
83 84 # Check if execution of wrong command fails
... ... @@ -89,18 +90,18 @@ class Test(test):
89 90 'Check successful execution from command line')
90 91  
91 92 # Check observation definition XML file
92   - self._check_obsdef('obs_iactobs_cmd1.xml')
  93 + self._check_obsdef('csiactobs_obs_cmd1.xml')
93 94  
94 95 # Check model definition XML file
95   - self._check_moddef('bkg_iactobs_cmd1.xml')
  96 + self._check_moddef('csiactobs_bgd_cmd1.xml')
96 97  
97 98 # Setup csiactobs command
98 99 cmd = csiactobs+' datapath="data_path_that_does_not_exist"'+ \
99 100 ' prodname="unit-test"'+ \
100   - ' infile="runlist_cmd1.dat"'+ \
  101 + ' infile="'+self._runlist+'"'+ \
101 102 ' bkgpars=1'+\
102   - ' outobs="obs_iactobs_cmd2.xml"'+ \
103   - ' outmodel="bkg_iactobs_cmd2.xml"'+ \
  103 + ' outobs="csiactobs_obs_cmd2.xml"'+ \
  104 + ' outmodel="csiactobs_bgd_cmd2.xml"'+ \
104 105 ' logfile="csiactobs_cmd2.log" chatter=1'
105 106  
106 107 # Check if execution failed
... ... @@ -110,10 +111,10 @@ class Test(test):
110 111 # Setup csiactobs command
111 112 cmd = csiactobs+' datapath="'+self._datapath+'"'+ \
112 113 ' prodname="unit-test-doesnt-exist"'+ \
113   - ' infile="runlist_cmd1.dat"'+ \
  114 + ' infile="'+self._runlist+'"'+ \
114 115 ' bkgpars=1'+\
115   - ' outobs="obs_iactobs_cmd3.xml"'+ \
116   - ' outmodel="bkg_iactobs_cmd3.xml"'+ \
  116 + ' outobs="csiactobs_obs_cmd3.xml"'+ \
  117 + ' outmodel="csiactobs_bgd_cmd3.xml"'+ \
117 118 ' logfile="csiactobs_cmd3.log" chatter=1'
118 119  
119 120 # Check if execution failed
... ... @@ -132,10 +133,10 @@ class Test(test):
132 133 iactobs = cscripts.csiactobs()
133 134 iactobs['datapath'] = self._datapath
134 135 iactobs['prodname'] = 'unit-test'
135   - iactobs['infile'] = 'runlist_py1.dat'
  136 + iactobs['infile'] = self._runlist
136 137 iactobs['bkgpars'] = 1
137   - iactobs['outobs'] = 'obs_iactobs_py1.xml'
138   - iactobs['outmodel'] = 'bkg_iactobs_py1.xml'
  138 + iactobs['outobs'] = 'csiactobs_obs_py1.xml'
  139 + iactobs['outmodel'] = 'csiactobs_bgd_py1.xml'
139 140 iactobs['logfile'] = 'csiactobs_py1.log'
140 141 iactobs['chatter'] = 2
141 142  
... ... @@ -145,21 +146,21 @@ class Test(test):
145 146 iactobs.save()
146 147  
147 148 # Check observation definition XML file
148   - self._check_obsdef('obs_iactobs_py1.xml')
  149 + self._check_obsdef('csiactobs_obs_py1.xml')
149 150  
150 151 # Check model definition XML file
151   - self._check_moddef('bkg_iactobs_py1.xml')
  152 + self._check_moddef('csiactobs_bgd_py1.xml')
152 153  
153 154 # Create test runlist
154 155 runlist = ['0']
155 156  
156   - # Set-up csiactobs - part 2 (set runlist via function, 2 background pars)
  157 + # Set-up csiactobs using a runlist with 2 background parameters
157 158 iactobs = cscripts.csiactobs()
158 159 iactobs['datapath'] = self._datapath
159 160 iactobs['prodname'] = 'unit-test'
160 161 iactobs['bkgpars'] = 2
161   - iactobs['outobs'] = 'obs_iactobs_py2.xml'
162   - iactobs['outmodel'] = 'bkg_iactobs_py2.xml'
  162 + iactobs['outobs'] = 'csiactobs_obs_py2.xml'
  163 + iactobs['outmodel'] = 'csiactobs_bgd_py2.xml'
163 164 iactobs['logfile'] = 'csiactobs_py2.log'
164 165 iactobs['chatter'] = 3
165 166 iactobs.runlist(runlist)
... ... @@ -170,71 +171,63 @@ class Test(test):
170 171 iactobs.save()
171 172  
172 173 # Test return functions
173   - obs = iactobs.obs()
174   - ebounds = iactobs.ebounds()
175   -
176   - self.test_assert(obs.size() == 1,
177   - 'Check output observation container')
178   - self.test_assert(ebounds.size() == 0,
179   - 'Check output energy boundaries container')
  174 + self.test_value(iactobs.obs().size(), 1,
  175 + 'Check number of observations in container')
  176 + self.test_value(iactobs.ebounds().size(), 0,
  177 + 'Check number of energy boundaries')
180 178  
181 179 # Check observation definition XML file
182   - self._check_obsdef('obs_iactobs_py2.xml')
  180 + self._check_obsdef('csiactobs_obs_py2.xml')
183 181  
184 182 # Check model definition XML file
185   - self._check_moddef('bkg_iactobs_py2.xml')
  183 + self._check_moddef('csiactobs_bgd_py2.xml')
186 184  
187   - # Set-up csiactobs - part 3 (use a large number of free parameters, aeff background)
  185 + # Set-up csiactobs with a large number of free parameters and "aeff"
  186 + # background
188 187 iactobs = cscripts.csiactobs()
189 188 iactobs['datapath'] = self._datapath
190 189 iactobs['prodname'] = 'unit-test'
191   - iactobs['infile'] = 'runlist_py1.dat'
  190 + iactobs['infile'] = self._runlist
192 191 iactobs['bkgpars'] = 8
193 192 iactobs['bkg_mod_hiera'] = 'aeff'
194   - iactobs['outobs'] = 'obs_iactobs_py3.xml'
195   - iactobs['outmodel'] = 'bkg_iactobs_py3.xml'
  193 + iactobs['outobs'] = 'csiactobs_obs_py3.xml'
  194 + iactobs['outmodel'] = 'csiactobs_bgd_py3.xml'
196 195 iactobs['logfile'] = 'csiactobs_py3.log'
197 196 iactobs['chatter'] = 4
198 197  
199   - # Run csiactobs script and save run list
200   - iactobs.logFileOpen() # Make sure we get a log file
201   - iactobs.run()
202   - iactobs.save()
  198 + # Execute csiactobs script
  199 + iactobs.execute()
203 200  
204 201 # Check observation definition XML file
205   - self._check_obsdef('obs_iactobs_py3.xml')
  202 + self._check_obsdef('csiactobs_obs_py3.xml')
206 203  
207 204 # Check model definition XML file
208   - self._check_moddef('bkg_iactobs_py3.xml')
  205 + self._check_moddef('csiactobs_bgd_py3.xml')
209 206  
210   - # Set-up csiactobs - part 4 (use a Gauss background and inmodel parameter)
  207 + # Set-up csiactobs with a "gauss" background and "inmodel" parameter
211 208 iactobs = cscripts.csiactobs()
212 209 iactobs['datapath'] = self._datapath
213   - iactobs['inmodel'] = 'results.xml'
  210 + iactobs['inmodel'] = self._model
214 211 iactobs['prodname'] = 'unit-test'
215   - iactobs['infile'] = 'runlist_py1.dat'
  212 + iactobs['infile'] = self._runlist
216 213 iactobs['bkgpars'] = 1
217 214 iactobs['bkg_mod_hiera'] = 'gauss'
218 215 iactobs['outobs'] = 'NONE'
219 216 iactobs['outmodel'] = 'NONE'
220 217 iactobs['logfile'] = 'csiactobs_py4.log'
221   - iactobs['chatter'] = 2
  218 + iactobs['chatter'] = 4
222 219  
223 220 # Run csiactobs script
224 221 iactobs.logFileOpen() # Make sure we get a log file
225 222 iactobs.run()
226 223  
227   - # Get observations and models
228   - observations = iactobs.obs()
229   - models = observations.models()
230   -
231   - # Check number of models
232   - self.test_assert(models.size() == 3,
233   - 'Check for three models in container')
234   -
235 224 # Check number of observations
236   - self.test_assert(observations.size() == 1,
237   - 'Check for one observation in container')
  225 + self.test_value(iactobs.obs().size(), 1,
  226 + 'Check number of observations in container')
  227 +
  228 + # Check number of models
  229 + self.test_value(iactobs.obs().models().size(), 3,
  230 + 'Check number of models in container')
238 231  
239 232 # Return
240 233 return
... ... @@ -253,34 +246,26 @@ class Test(test):
253 246 # Check number of observations
254 247 self.test_value(obs.size(), 1,
255 248 'Check for single observation in XML file')
256   - self.test_assert(obs[0].eventfile().file() == 'events.fits.gz',
257   - 'Check event file name')
258   - self.test_assert(obs[0].eventfile().extname() == 'EVENTS',
259   - 'Check event extension name')
260   - self.test_assert(rsp.aeff().filename().file() ==
261   - 'irf_file.fits.gz',
262   - 'Check effective area name')
263   - self.test_assert(rsp.aeff().filename().extname() ==
264   - 'EFFECTIVE AREA',
265   - 'Check effective area extension name')
266   - self.test_assert(rsp.psf().filename().file() ==
267   - 'irf_file.fits.gz',
268   - 'Check point spread function name')
269   - self.test_assert(rsp.psf().filename().extname() ==
270   - 'POINT SPREAD FUNCTION',
271   - 'Check point spread function extension name')
272   - self.test_assert(rsp.edisp().filename().file() ==
273   - 'irf_file.fits.gz',
274   - 'Check energy dispersion name')
275   - self.test_assert(rsp.edisp().filename().extname() ==
276   - 'ENERGY DISPERSION',
277   - 'Check energy dispersion extension name')
278   - self.test_assert(rsp.background().filename().file() ==
279   - 'irf_file.fits.gz',
280   - 'Check background name')
281   - self.test_assert(rsp.background().filename().extname() ==
282   - 'BACKGROUND',
283   - 'Check background extension name')
  249 + self.test_value(obs[0].eventfile().file(), 'events.fits.gz',
  250 + 'Check event file name')
  251 + self.test_value(obs[0].eventfile().extname(), 'EVENTS',
  252 + 'Check event extension name')
  253 + self.test_value(rsp.aeff().filename().file(), 'irf_file.fits.gz',
  254 + 'Check effective area file name')
  255 + self.test_value(rsp.aeff().filename().extname(), 'EFFECTIVE AREA',
  256 + 'Check effective area extension name')
  257 + self.test_value(rsp.psf().filename().file(), 'irf_file.fits.gz',
  258 + 'Check point spread function file name')
  259 + self.test_value(rsp.psf().filename().extname(), 'POINT SPREAD FUNCTION',
  260 + 'Check point spread function extension name')
  261 + self.test_value(rsp.edisp().filename().file(), 'irf_file.fits.gz',
  262 + 'Check energy dispersion file name')
  263 + self.test_value(rsp.edisp().filename().extname(), 'ENERGY DISPERSION',
  264 + 'Check energy dispersion extension name')
  265 + self.test_value(rsp.background().filename().file(), 'irf_file.fits.gz',
  266 + 'Check background file name')
  267 + self.test_value(rsp.background().filename().extname(), 'BACKGROUND',
  268 + 'Check background extension name')
284 269  
285 270 # Return
286 271 return
... ...