Commit 698bf587ea4dff6858d72e8620ea93926380c286

Authored by Jürgen Knödlseder
1 parent a6fc9fa3

Integrate csworkflow script and add unit test.

cscripts/Makefile.am
... ... @@ -2,26 +2,70 @@
2 2  
3 3 # Scripts to be distributed in $(pyexecdir)/cscripts
4 4 pythonscripts = __init__.py \
5   - cspull.py cssens.py cstsdist.py cscaldb.py csresmap.py \
6   - csobsdef.py csspec.py cslightcrv.py csobsinfo.py \
7   - csinfo.py csmodelinfo.py csmodelmerge.py cstsmapmerge.py \
8   - csroot2caldb.py csobs2caldb.py \
9   - csfindobs.py csiactcopy.py csiactdata.py csiactobs.py \
  5 + cscaldb.py \
  6 + csinfo.py \
  7 + cslightcrv.py \
  8 + csmodelinfo.py \
  9 + csmodelmerge.py \
  10 + csobs2caldb.py \
  11 + csobsdef.py \
  12 + csobsinfo.py \
  13 + cspull.py \
  14 + csresmap.py \
  15 + csroot2caldb.py \
  16 + cssens.py \
  17 + csspec.py \
  18 + cstsdist.py \
  19 + cstsmapmerge.py \
  20 + csworkflow.py \
  21 + csfindobs.py \
  22 + csiactcopy.py \
  23 + csiactdata.py \
  24 + csiactobs.py \
10 25 obsutils.py
11 26  
12 27 # Parfiles to be distributed in $(prefix)/syspfiles
13   -parfiles = cspull.par cssens.par cstsdist.par cscaldb.par csresmap.par \
14   - csobsdef.par csspec.par cslightcrv.par csobsinfo.par \
15   - csmodelinfo.par csmodelmerge.par cstsmapmerge.par \
16   - csroot2caldb.par csobs2caldb.par \
17   - csfindobs.par csiactcopy.par csiactdata.par csiactobs.par
  28 +parfiles = cscaldb.par \
  29 + cslightcrv.par \
  30 + csmodelinfo.par \
  31 + csmodelmerge.par \
  32 + csobs2caldb.par \
  33 + csobsdef.par \
  34 + csobsinfo.par \
  35 + cspull.par \
  36 + csresmap.par \
  37 + csroot2caldb.par \
  38 + cssens.par \
  39 + csspec.par \
  40 + cstsdist.par \
  41 + cstsmapmerge.par \
  42 + csworkflow.par \
  43 + csfindobs.par \
  44 + csiactcopy.par \
  45 + csiactdata.par \
  46 + csiactobs.par
18 47  
19 48 # Scripts for which symbolic links will be created in bindir
20   -linkscripts = cspull cssens cstsdist cscaldb csresmap \
21   - csobsdef csspec cslightcrv csobsinfo \
22   - csinfo csmodelinfo csmodelmerge cstsmapmerge \
23   - csroot2caldb csobs2caldb \
24   - csfindobs csiactcopy csiactdata csiactobs
  49 +linkscripts = cscaldb \
  50 + csinfo \
  51 + cslightcrv \
  52 + csmodelinfo \
  53 + csmodelmerge \
  54 + csobs2caldb \
  55 + csobsdef \
  56 + csobsinfo \
  57 + cspull \
  58 + csresmap \
  59 + csroot2caldb \
  60 + cssens \
  61 + csspec \
  62 + cstsdist \
  63 + cstsmapmerge \
  64 + csworkflow \
  65 + csfindobs \
  66 + csiactcopy \
  67 + csiactdata \
  68 + csiactobs
25 69  
26 70 # Test scripts to be distributed in $(pyexecdir)/cscripts/tests
27 71 testscripts = tests/__init__.py \
... ... @@ -35,6 +79,7 @@ testscripts = tests/__init__.py \
35 79 ../test/test_csobsinfo.py \
36 80 ../test/test_cspull.py \
37 81 ../test/test_csroot2caldb.py \
  82 + ../test/test_csworkflow.py \
38 83 ../test/test_csfindobs.py \
39 84 ../test/test_csiactcopy.py \
40 85 ../test/test_csiactdata.py \
... ... @@ -55,7 +100,8 @@ testdata = ../test/data/crab.xml \
55 100 ../test/data/model_cube_background.xml \
56 101 ../test/data/model_cube_background2.xml \
57 102 ../test/data/crab_bkgcube.xml \
58   - ../test/data/irf.root
  103 + ../test/data/irf.root \
  104 + ../test/data/workflow.xml
59 105  
60 106 # Test data to be distributed in $(pyexecdir)/cscripts/tests/iactdata
61 107 testiactdata = ../test/iactdata/hdu-index.fits.gz \
... ...
cscripts/__init__.py.in
... ... @@ -39,7 +39,7 @@ __all__ = [
39 39 "csspec",
40 40 "cstsdist",
41 41 "cstsmapmerge",
42   - "csfindobs",
  42 + "csworkflow",
43 43 "obsutils"
44 44 ]
45 45 if cur_version > req_version:
... ... @@ -64,6 +64,7 @@ from cscripts.cssens import cssens
64 64 from cscripts.csspec import csspec
65 65 from cscripts.cstsdist import cstsdist
66 66 from cscripts.cstsmapmerge import cstsmapmerge
  67 +from cscripts.csworkflow import csworkflow
67 68 from cscripts import obsutils
68 69 if cur_version > req_version:
69 70 from cscripts.csfindobs import csfindobs
... ...
cscripts/cscaldb.py
... ... @@ -206,16 +206,6 @@ class cscaldb(ctools.cscript):
206 206 """
207 207 Execute the script.
208 208 """
209   - # Run the script
210   - self.run()
211   -
212   - # Return
213   - return
214   -
215   - def execute(self):
216   - """
217   - Execute the script.
218   - """
219 209 # Open logfile
220 210 self.logFileOpen()
221 211  
... ...
cscripts/csworkflow.par 0 → 100644
  1 +#############################################################################
  2 +# #
  3 +# CTA Science Analysis Tools #
  4 +# #
  5 +# ------------------------------------------------------------------------- #
  6 +# #
  7 +# File: csworkflow.par #
  8 +# Version: 1.0.0 #
  9 +# #
  10 +# Author: Juergen Knoedlseder #
  11 +# Jurgen.Knodlseder@irap.omp.eu #
  12 +# IRAP #
  13 +# #
  14 +# Purpose: Parameter file for the csworkflow script #
  15 +# #
  16 +#############################################################################
  17 +#
  18 +# Input parameters
  19 +#=================
  20 +inflow, f, h, workflow.xml,,, "Input workflow XML file"
  21 +
  22 +#
  23 +# Standard parameters
  24 +#====================
  25 +chatter, i, h, 2,0,4, "Chattiness of output"
  26 +clobber, b, h, yes,,, "Overwrite existing output files with new output files?"
  27 +debug, b, h, no,,, "Debugging mode activated"
  28 +mode, s, h, ql,,, "Mode of automatic parameters"
  29 +logfile, f, h, csworkflow.log,,, "Log filename"
... ...
cscripts/csworkflow.py
1 1 #! /usr/bin/env python
2 2 # ==========================================================================
3   -# This script executes a workflow defined in an XML file.
  3 +# Executes analysis workflow
4 4 #
5 5 # Copyright (C) 2016 Juergen Knoedlseder
6 6 #
... ... @@ -29,138 +29,77 @@ import sys
29 29 # ================ #
30 30 class csworkflow(ctools.cscript):
31 31 """
  32 + Executes an analysis workflow.
  33 +
  34 + The ``csworkflow`` script executes an analysis workflow defined in an
  35 + XML file.
32 36 """
  37 +
  38 + # Constructor
33 39 def __init__(self, *argv):
34 40 """
35 41 Constructor.
  42 +
  43 + Parameters
  44 + ----------
  45 + argv : list of str
  46 + List of IRAF command line parameter strings of the form
  47 + ``parameter=3``.
  48 +
  49 + Raises
  50 + ------
  51 + TypeError
  52 + An invalid number of command line arguments was provided.
36 53 """
37 54 # Set name and version
38   - self.name = "csworkflow"
39   - self.version = "1.0.0"
  55 + self._name = 'csworkflow'
  56 + self._version = '1.0.0'
40 57  
41 58 # Set members
42   - self.workflow = gammalib.GXml()
43   - self.actors = []
44   -
45   - # Make sure that parfile exists
46   - self.parfile()
47   -
48   - # Initialise application
49   - if len(argv) == 0:
50   - ctools.cscript.__init__(self, self.name, self.version)
51   - elif len(argv) ==1:
52   - ctools.cscript.__init__(self, self.name, self.version, *argv)
53   - else:
54   - raise TypeError("Invalid number of arguments given.")
  59 + self._workflow = gammalib.GXml()
  60 + self._actors = []
55 61  
56   - # Set logger properties
57   - self.log_header()
58   - self.log.date(True)
  62 + # Initialise application by calling the appropriate class constructor
  63 + self._init_cscript(argv)
59 64  
60 65 # Return
61 66 return
62 67  
63   - def __del__(self):
64   - """
65   - Destructor.
66   - """
67   - # Return
68   - return
69 68  
70   - def parfile(self):
71   - """
72   - Check if parfile exists. If parfile does not exist then create a
73   - default parfile. This kluge avoids shipping the cscript with a parfile.
74   - """
75   - # Set parfile name
76   - parfile = self.name+".par"
77   -
78   - # Load parfile or create one
79   - try:
80   - pars = gammalib.GApplicationPars(parfile)
81   - except:
82   - # Signal if parfile was not found
83   - print("Parfile "+parfile+" not found. Create default parfile.")
84   -
85   - # Create default parfile
86   - pars = gammalib.GApplicationPars()
87   - pars.append(gammalib.GApplicationPar("inflow","f","h","test/data/workflow.xml","","","Input workflow XML file"))
88   - pars.append_standard()
89   - pars.append(gammalib.GApplicationPar("logfile","f","h","csworkflow.log","","","Log filename"))
90   - pars.save(parfile)
91   -
92   - # Return
93   - return
  69 + # Private methods
  70 + #
  71 + # Query all user parameters
  72 + def _get_parameters(self):
94 73  
95   - def get_parameters(self):
96   - """
97   - Get parameters from parfile.
98   - """
99 74 # Load workflow XML file
100   - xmlfile = self["inflow"].filename()
101   - self.workflow = gammalib.GXml(xmlfile.url())
102   -
103   - # Return
104   - return
105   -
106   - def execute(self):
107   - """
108   - Execute the script.
109   - """
110   - # Run the script
111   - self.run()
112   -
113   - # Return
114   - return
115   -
116   - def run(self):
117   - """
118   - Run the script.
119   - """
120   - # Switch screen logging on in debug mode
121   - if self.logDebug():
122   - self.log.cout(True)
123   -
124   - # Get parameters
125   - self.get_parameters()
  75 + xmlfile = self['inflow'].filename()
  76 + self._workflow = gammalib.GXml(xmlfile.url())
126 77  
127 78 # Write input parameters into logger
128   - if self.logTerse():
129   - self.log_parameters()
130   - self.log("\n")
131   -
132   - # Parse XML file
133   - if self.logTerse():
134   - self.log("\n")
135   - self.log.header1("Parse workflow XML file")
136   - self.parse_workflow()
137   -
138   - # Execute workflow
139   - if self.logTerse():
140   - self.log("\n")
141   - self.log.header1("Execute workflow")
142   - self.execute_workflow()
  79 + if self._logTerse():
  80 + self._log_parameters()
  81 + self._log('\n')
143 82  
144 83 # Return
145 84 return
146 85  
147   - def parse_workflow(self):
148   - """
149   - """
  86 + # Parse the workflow XML file
  87 + def _parse_workflow(self):
  88 +
150 89 # Get workflow
151   - workflow = self.workflow.element("workflow")
  90 + workflow = self._workflow.element('workflow')
152 91  
153 92 # Get number of actors
154   - num_actors = workflow.elements("actor")
  93 + num_actors = workflow.elements('actor')
155 94  
156 95 # Initialise actors
157   - self.actors = []
  96 + self._actors = []
158 97  
159 98 # Loop over all actors
160 99 for i in range(num_actors):
161 100  
162 101 # Get actor
163   - actor = workflow.element("actor", i)
  102 + actor = workflow.element('actor', i)
164 103  
165 104 # Initialise parameters and input actors
166 105 input_parameters = []
... ... @@ -169,40 +108,40 @@ class csworkflow(ctools.cscript):
169 108 output_actors = []
170 109  
171 110 # Get actor attributes
172   - name = actor.attribute("name")
173   - tool = actor.attribute("tool")
  111 + name = actor.attribute('name')
  112 + tool = actor.attribute('tool')
174 113  
175 114 # Get actor input parameters
176   - if actor.elements("input") > 0:
177   - actor_inputs = actor.element("input")
178   - num_inputs = actor_inputs.elements("parameter")
  115 + if actor.elements('input') > 0:
  116 + actor_inputs = actor.element('input')
  117 + num_inputs = actor_inputs.elements('parameter')
179 118 for k in range(num_inputs):
180   - input = actor_inputs.element("parameter", k)
181   - input_name = input.attribute("name")
182   - input_value = input.attribute("value")
183   - input_actor = input.attribute("actor")
  119 + input = actor_inputs.element('parameter', k)
  120 + input_name = input.attribute('name')
  121 + input_value = input.attribute('value')
  122 + input_actor = input.attribute('actor')
184 123 parameter = {'name': input_name, \
185 124 'value': input_value, \
186 125 'actor': input_actor}
187 126 input_parameters.append(parameter)
188   - if input_actor != "":
  127 + if input_actor != '':
189 128 if input_actor not in input_actors:
190 129 input_actors.append(input_actor)
191 130  
192 131 # Get actor output parameters
193   - if actor.elements("output") > 0:
194   - actor_output = actor.element("output")
195   - num_outputs = actor_output.elements("parameter")
  132 + if actor.elements('output') > 0:
  133 + actor_output = actor.element('output')
  134 + num_outputs = actor_output.elements('parameter')
196 135 for k in range(num_outputs):
197   - output = actor_output.element("parameter", k)
198   - output_name = output.attribute("name")
199   - output_value = output.attribute("value")
200   - output_actor = output.attribute("actor")
  136 + output = actor_output.element('parameter', k)
  137 + output_name = output.attribute('name')
  138 + output_value = output.attribute('value')
  139 + output_actor = output.attribute('actor')
201 140 parameter = {'name': output_name, \
202 141 'value': output_value, \
203 142 'actor': output_actor}
204 143 output_parameters.append(parameter)
205   - if output_actor != "":
  144 + if output_actor != '':
206 145 if output_actor not in output_actors:
207 146 output_actors.append(output_actor)
208 147  
... ... @@ -225,55 +164,55 @@ class csworkflow(ctools.cscript):
225 164 'status': status}
226 165  
227 166 # Append entry
228   - self.actors.append(entry)
  167 + self._actors.append(entry)
229 168  
230 169 # Log information about actors
231   - if self.logNormal():
232   - self.log.parformat("Actor \""+name+"\"")
233   - self.log(tool)
234   - self.log("\n")
  170 + if self._logNormal():
  171 + self._log.parformat('Actor "'+name+'"')
  172 + self._log(tool)
  173 + self._log('\n')
235 174 if num_inputs == 0:
236   - self.log.parformat(" Predecessor")
237   - self.log("none\n")
  175 + self._log.parformat(' Predecessor')
  176 + self._log('none\n')
238 177 else:
239 178 if num_inputs == 1:
240   - self.log.parformat(" Predecessor")
  179 + self._log.parformat(' Predecessor')
241 180 else:
242   - self.log.parformat(" Predecessors")
  181 + self._log.parformat(' Predecessors')
243 182 for k in range(num_inputs):
244 183 if k > 0:
245   - self.log(", ")
246   - self.log("\""+input_actors[k]+"\"")
247   - self.log("\n")
  184 + self._log(', ')
  185 + self._log('"'+input_actors[k]+'"')
  186 + self._log('\n')
248 187  
249 188 # Return
250 189 return
251 190  
252   - def execute_workflow(self):
253   - """
254   - """
  191 + # Execute a workflow
  192 + def _execute_workflow(self):
  193 +
255 194 # Continue while there are actors
256   - while len(self.actors) > 0:
  195 + while len(self._actors) > 0:
257 196  
258 197 # Find actors which are ready
259 198 num_executed = 0
260   - for actor in self.actors:
  199 + for actor in self._actors:
261 200  
262 201 # If actor is ready then execute it
263 202 if actor['status'] == 'ready':
264 203  
265 204 # Log execution start
266   - if self.logNormal():
267   - self.log.parformat("Execute actor")
268   - self.log("\""+actor['name']+"\"\n")
  205 + if self._logNormal():
  206 + self._log.parformat('Execute actor')
  207 + self._log('"'+actor['name']+'"\n')
269 208  
270 209 # Execute actor
271   - self.execute_actor(actor)
  210 + self._execute_actor(actor)
272 211  
273 212 # Log execution finish
274   - if self.logNormal():
275   - self.log.parformat("Finished actor execution")
276   - self.log("\""+actor['name']+"\"\n")
  213 + if self._logNormal():
  214 + self._log.parformat('Finished actor execution')
  215 + self._log('"'+actor['name']+'"\n')
277 216  
278 217 # Set actor status to finished
279 218 actor['status'] = 'finished'
... ... @@ -286,12 +225,12 @@ class csworkflow(ctools.cscript):
286 225 break
287 226  
288 227 # Update actor status
289   - for actor in self.actors:
  228 + for actor in self._actors:
290 229 if actor['status'] != 'finished':
291 230 input_actors = actor['input_actors']
292 231 ready = True
293 232 for input_actor in input_actors:
294   - a = self.get_actor(input_actor)
  233 + a = self._get_actor(input_actor)
295 234 if a['status'] != 'finished':
296 235 ready = False
297 236 break
... ... @@ -301,29 +240,28 @@ class csworkflow(ctools.cscript):
301 240 # Return
302 241 return
303 242  
304   - def execute_actor(self, actor):
305   - """
306   - Excute an actor.
307   - """
  243 + # Execute an actor
  244 + def _execute_actor(self, actor):
  245 +
308 246 # Log input parameters
309   - if self.logNormal():
  247 + if self._logNormal():
310 248 pars = actor['input_parameters']
311 249 for par in pars:
312   - self.log.parformat(" Input parameter")
313   - self.log(par['name'])
314   - self.log("=")
315   - self.log(self.get_parameter_value(par))
316   - self.log("\n")
  250 + self._log.parformat(' Input parameter')
  251 + self._log(par['name'])
  252 + self._log('=')
  253 + self._log(self._get_parameter_value(par))
  254 + self._log('\n')
317 255  
318 256 # Log output parameters
319   - if self.logNormal():
  257 + if self._logNormal():
320 258 pars = actor['output_parameters']
321 259 for par in pars:
322   - self.log.parformat(" Output parameter")
323   - self.log(par['name'])
324   - self.log("=")
325   - self.log(self.get_parameter_value(par))
326   - self.log("\n")
  260 + self._log.parformat(' Output parameter')
  261 + self._log(par['name'])
  262 + self._log('=')
  263 + self._log(self._get_parameter_value(par))
  264 + self._log('\n')
327 265  
328 266 # Set actor tool
329 267 if 'tool' in actor:
... ... @@ -333,8 +271,8 @@ class csworkflow(ctools.cscript):
333 271 elif tool[:2] == 'cs':
334 272 tool_eval = 'cscripts.'+tool+'()'
335 273 else:
336   - tool_eval = ""
337   - if tool_eval == "":
  274 + tool_eval = ''
  275 + if tool_eval == '':
338 276 return
339 277  
340 278 # Create actor tool object
... ... @@ -344,14 +282,14 @@ class csworkflow(ctools.cscript):
344 282 pars = actor['input_parameters']
345 283 for par in pars:
346 284 app_par = object[par['name']]
347   - app_par.value(self.get_parameter_value(par))
  285 + app_par.value(self._get_parameter_value(par))
348 286 object[par['name']] = app_par
349 287  
350 288 # Set actor output parameters
351 289 pars = actor['output_parameters']
352 290 for par in pars:
353 291 app_par = object[par['name']]
354   - app_par.value(self.get_parameter_value(par))
  292 + app_par.value(self._get_parameter_value(par))
355 293 object[par['name']] = app_par
356 294  
357 295 # Execute actor
... ... @@ -361,60 +299,94 @@ class csworkflow(ctools.cscript):
361 299 # Return
362 300 return
363 301  
364   - def get_parameter_value(self, par):
365   - """
366   - Get the parameter value from the respective actor.
367   - """
  302 + # Get the parameter value from the respective actor
  303 + def _get_parameter_value(self, par):
  304 +
368 305 # If the actor is empty then simply return the value
369   - if (par['actor'] == ""):
  306 + if (par['actor'] == ''):
370 307 value = par['value']
371 308  
372 309 # ... otherwise get the value from the actor
373 310 else:
374 311 found = False
375   - actor = self.get_actor(par['actor'])
  312 + actor = self._get_actor(par['actor'])
376 313 for output in actor['output_parameters']:
377 314 if output['name'] == par['value']:
378 315 value = output['value']
379 316 found = True
380 317 break
381 318 if not found:
382   - msg = "Parameter \""+par['value']+"\" is not an output "\
383   - "parameter of actor \""+par['actor']+"\"."
  319 + msg = 'Parameter "'+par['value']+'" is not an output '+ \
  320 + 'parameter of actor "'+par['actor']+'".'
384 321 raise RuntimeError(msg)
385 322  
386 323 # Return value
387 324 return value
388 325  
389   - def get_actor(self, name):
390   - """
391   - Get the actor with the specified name.
392   - """
  326 + # Get the actor with the specified name
  327 + def _get_actor(self, name):
  328 +
393 329 # Return actor with specified name
394   - for actor in self.actors:
  330 + for actor in self._actors:
395 331 if actor['name'] == name:
396 332 return actor
397 333  
398 334 # Throw an exception
399   - msg = "Actor \""+name+"\" not found."
  335 + msg = 'Actor "'+name+'" not found.'
400 336 raise RuntimeError(msg)
401 337  
402 338 # Return
403 339 return
404 340  
405 341  
  342 + # Public methods
  343 + def run(self):
  344 + """
  345 + Run the script.
  346 + """
  347 + # Switch screen logging on in debug mode
  348 + if self._logDebug():
  349 + self._log.cout(True)
  350 +
  351 + # Get parameters
  352 + self._get_parameters()
  353 +
  354 + # Parse XML file
  355 + if self._logTerse():
  356 + self._log('\n')
  357 + self._log.header1('Parse workflow XML file')
  358 + self._parse_workflow()
  359 +
  360 + # Execute workflow
  361 + if self._logTerse():
  362 + self._log('\n')
  363 + self._log.header1('Execute workflow')
  364 + self._execute_workflow()
  365 +
  366 + # Return
  367 + return
  368 +
  369 + def execute(self):
  370 + """
  371 + Execute the script.
  372 + """
  373 + # Open logfile
  374 + self.logFileOpen()
  375 +
  376 + # Run the script
  377 + self.run()
  378 +
  379 + # Return
  380 + return
  381 +
  382 +
406 383 # ======================== #
407 384 # Main routine entry point #
408 385 # ======================== #
409 386 if __name__ == '__main__':
410   - """
411   - Executes workflow.
412   - """
  387 +
413 388 # Create instance of application
414 389 app = csworkflow(sys.argv)
415 390  
416   - # Open logfile
417   - app.logFileOpen()
418   -
419 391 # Execute application
420 392 app.execute()
... ...
test/data/workflow.xml
... ... @@ -46,7 +46,7 @@
46 46 <parameter name="logfile" value="ctobssim.log" />
47 47 </input>
48 48 <output>
49   - <parameter name="outevents" value="events.fits" />
  49 + <parameter name="outevents" value="wf_events.fits" />
50 50 </output>
51 51 </actor>
52 52 <actor name="ctselect" tool="ctselect">
... ... @@ -70,7 +70,7 @@
70 70 <parameter name="logfile" value="ctselect.log" />
71 71 </input>
72 72 <output>
73   - <parameter name="outobs" value="selected_events.fits" />
  73 + <parameter name="outobs" value="wf_selected_events.fits" />
74 74 </output>
75 75 </actor>
76 76 <actor name="ctlike" tool="ctlike">
... ... @@ -93,37 +93,7 @@
93 93 <parameter name="logfile" value="ctlike.log" />
94 94 </input>
95 95 <output>
96   - <parameter name="outmodel" value="crab_results.xml" />
97   - </output>
98   - </actor>
99   - <actor name="csspec" tool="csspec">
100   - <input>
101   - <parameter name="inobs" value="outobs" actor="ctselect" />
102   - <parameter name="inmodel" value="outmodel" actor="ctlike" />
103   - <parameter name="srcname" value="target" actor="input" />
104   - <parameter name="expcube" value="NONE" />
105   - <parameter name="psfcube" value="NONE" />
106   - <parameter name="bkgcube" value="NONE" />
107   - <parameter name="caldb" value="caldb" actor="input" />
108   - <parameter name="irf" value="irf" actor="input" />
109   - <parameter name="edisp" value="edisp" actor="input" />
110   - <parameter name="emin" value="emin" actor="input" />
111   - <parameter name="emax" value="emax" actor="input" />
112   - <parameter name="enumbins" value="10" />
113   - <parameter name="ebinalg" value="LOG" />
114   - <parameter name="ebinfile" value="NONE" />
115   - <parameter name="calc_ts" value="yes" />
116   - <parameter name="calc_ulim" value="yes" />
117   - <parameter name="fix_srcs" value="yes" />
118   - <parameter name="fix_bkg" value="no" />
119   - <parameter name="chatter" value="chatter" actor="input" />
120   - <parameter name="clobber" value="clobber" actor="input" />
121   - <parameter name="debug" value="debug" actor="input" />
122   - <parameter name="mode" value="mode" actor="input" />
123   - <parameter name="logfile" value="csspec.log" />
124   - </input>
125   - <output>
126   - <parameter name="outfile" value="spectrum.fits" />
  96 + <parameter name="outmodel" value="wf_crab_results.xml" />
127 97 </output>
128 98 </actor>
129 99 </workflow>
... ...
test/test_csworkflow.py 0 → 100755
  1 +#! /usr/bin/env python
  2 +# ==========================================================================
  3 +# This scripts performs unit tests for the csworkflow 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 csworkflow script #
  28 +# ================================ #
  29 +class Test(gammalib.GPythonTestSuite):
  30 + """
  31 + Test class for csworkflow script.
  32 +
  33 + This test class makes unit tests for the cslightcrv 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 + # Return
  46 + return
  47 +
  48 + # Set test functions
  49 + def set(self):
  50 + """
  51 + Set all test functions.
  52 + """
  53 + # Set test name
  54 + self.name('csworkflow')
  55 +
  56 + # Append tests
  57 + self.append(self._test_cmd, 'Test csworkflow on command line')
  58 + self.append(self._test_python, 'Test csworkflow from Python')
  59 +
  60 + # Return
  61 + return
  62 +
  63 + # Test csworkflow on command line
  64 + def _test_cmd(self):
  65 +
  66 + # Kluge to set the command (installed version has no README file)
  67 + if os.path.isfile('README'):
  68 + csworkflow = '../cscripts/csworkflow.py'
  69 + else:
  70 + csworkflow = 'csworkflow'
  71 +
  72 + # Remove result file
  73 + gammalib.GFilename('wf_crab_results.xml').remove()
  74 +
  75 + # Setup csworkflow command
  76 + cmd = csworkflow+' inflow="data/workflow.xml"'+ \
  77 + ' logfile="csworkflow_cmd1.log" chatter=1'
  78 +
  79 + # Execute csworkflow, make sure we catch any exception
  80 + try:
  81 + rc = os.system(cmd+" >/dev/null 2>&1")
  82 + except:
  83 + pass
  84 +
  85 + # Check if execution was successful
  86 + self.test_assert(rc == 0,
  87 + 'Successful csworkflow execution on command line')
  88 +
  89 + # Check fit result
  90 + self._check_fit_result('wf_crab_results.xml')
  91 +
  92 + # Return
  93 + return
  94 +
  95 + # Test csworkflow from Python
  96 + def _test_python(self):
  97 +
  98 + # Remove result file
  99 + gammalib.GFilename('wf_crab_results.xml').remove()
  100 +
  101 + # Set-up csworkflow
  102 + workflow = cscripts.csworkflow()
  103 + workflow['inflow'] = 'data/workflow.xml'
  104 + workflow['logfile'] = 'csworkflow_py1.log'
  105 + workflow['chatter'] = 2
  106 +
  107 + # Run script
  108 + workflow.logFileOpen() # Make sure we get a log file
  109 + workflow.run()
  110 +
  111 + # Check fit result
  112 + self._check_fit_result('wf_crab_results.xml')
  113 +
  114 + # Remove result file
  115 + gammalib.GFilename('wf_crab_results.xml').remove()
  116 +
  117 + # Set-up csworkflow
  118 + workflow = cscripts.csworkflow()
  119 + workflow['inflow'] = 'data/workflow.xml'
  120 + workflow['logfile'] = 'csworkflow_py2.log'
  121 + workflow['chatter'] = 3
  122 +
  123 + # Execute script
  124 + workflow.execute()
  125 +
  126 + # Check fit result
  127 + self._check_fit_result('wf_crab_results.xml')
  128 +
  129 + # Return
  130 + return
  131 +
  132 + # Check fit result XML values
  133 + def _check_fit_result(self, filename):
  134 +
  135 + # Load fit results
  136 + models = gammalib.GModels(filename)
  137 +
  138 + # Check fit result values
  139 + self.test_value(models['Crab'][2].value(),
  140 + 5.73787e-16, 1.0e-5, 'Crab prefactor')
  141 + self.test_value(models['Crab'][3].value(),
  142 + -2.47386, 1.0e-5, 'Crab index')
  143 + self.test_value(models['CTABackgroundModel'][0].value(),
  144 + 1.01414, 1.0e-5, 'Background model prefactor')
  145 + self.test_value(models['CTABackgroundModel'][1].value(),
  146 + 0.00242827, 1.0e-5, 'Background model index')
  147 +
  148 + # Return
  149 + return
... ...
test/test_python_cscripts.py
... ... @@ -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_csfindobs
27 28 import test_cslightcrv
28 29 import test_csmodelinfo
29 30 import test_csmodelmerge
... ... @@ -32,10 +33,10 @@ import test_csobsdef
32 33 import test_csobsinfo
33 34 import test_cspull
34 35 import test_csroot2caldb
35   -import test_csfindobs
36 36 import test_csiactcopy
37 37 import test_csiactdata
38 38 import test_csiactobs
  39 +import test_csworkflow
39 40  
40 41  
41 42 # ================== #
... ... @@ -94,6 +95,7 @@ def test(installed=False, debug=False):
94 95 suite_csobsinfo = test_csobsinfo.Test()
95 96 suite_cspull = test_cspull.Test()
96 97 suite_csroot2caldb = test_csroot2caldb.Test()
  98 + suite_csworkflow = test_csworkflow.Test()
97 99  
98 100 # Setup unit tests
99 101 suite_cscaldb.set()
... ... @@ -105,6 +107,7 @@ def test(installed=False, debug=False):
105 107 suite_csobsinfo.set()
106 108 suite_cspull.set()
107 109 suite_csroot2caldb.set()
  110 + suite_csworkflow.set()
108 111  
109 112 # Append tests to container
110 113 suites.append(suite_cscaldb)
... ... @@ -116,6 +119,7 @@ def test(installed=False, debug=False):
116 119 suites.append(suite_csobsinfo)
117 120 suites.append(suite_cspull)
118 121 suites.append(suite_csroot2caldb)
  122 + suites.append(suite_csworkflow)
119 123  
120 124 # Append tests for Python 2.6+ (the IACT cscripts depend on the json
121 125 # module which is only available since Python 2.6+
... ...