Commit 16f51af681e5497d317a1af9873768710f7f38aa

Authored by Michael Mayer
1 parent 2bab4887

Added cstssplit (code, docs, test)

cscripts/Makefile.am
@@ -22,6 +22,7 @@ pythonscripts = __init__.py \ @@ -22,6 +22,7 @@ pythonscripts = __init__.py \
22 csiactcopy.py \ 22 csiactcopy.py \
23 csiactdata.py \ 23 csiactdata.py \
24 csiactobs.py \ 24 csiactobs.py \
  25 + cstssplit.py \
25 obsutils.py 26 obsutils.py
26 27
27 # Parfiles to be distributed in $(prefix)/syspfiles 28 # Parfiles to be distributed in $(prefix)/syspfiles
@@ -43,6 +44,7 @@ parfiles = cscaldb.par \ @@ -43,6 +44,7 @@ parfiles = cscaldb.par \
43 csfindobs.par \ 44 csfindobs.par \
44 csiactcopy.par \ 45 csiactcopy.par \
45 csiactdata.par \ 46 csiactdata.par \
  47 + cstssplit.par \
46 csiactobs.par 48 csiactobs.par
47 49
48 # Scripts for which symbolic links will be created in bindir 50 # Scripts for which symbolic links will be created in bindir
@@ -65,6 +67,7 @@ linkscripts = cscaldb \ @@ -65,6 +67,7 @@ linkscripts = cscaldb \
65 csfindobs \ 67 csfindobs \
66 csiactcopy \ 68 csiactcopy \
67 csiactdata \ 69 csiactdata \
  70 + cstssplit \
68 csiactobs 71 csiactobs
69 72
70 # Test scripts to be distributed in $(pyexecdir)/cscripts/tests 73 # Test scripts to be distributed in $(pyexecdir)/cscripts/tests
@@ -88,6 +91,7 @@ testscripts = tests/__init__.py \ @@ -88,6 +91,7 @@ testscripts = tests/__init__.py \
88 ../test/test_csfindobs.py \ 91 ../test/test_csfindobs.py \
89 ../test/test_csiactcopy.py \ 92 ../test/test_csiactcopy.py \
90 ../test/test_csiactdata.py \ 93 ../test/test_csiactdata.py \
  94 + ../test/test_cstssplit.py \
91 ../test/test_csiactobs.py 95 ../test/test_csiactobs.py
92 96
93 # Test data to be distributed in $(pyexecdir)/cscripts/tests/data 97 # Test data to be distributed in $(pyexecdir)/cscripts/tests/data
cscripts/__init__.py.in
@@ -40,6 +40,7 @@ __all__ = [ @@ -40,6 +40,7 @@ __all__ = [
40 "cstsdist", 40 "cstsdist",
41 "cstsmapmerge", 41 "cstsmapmerge",
42 "csworkflow", 42 "csworkflow",
  43 + "cstssplit",
43 "obsutils" 44 "obsutils"
44 ] 45 ]
45 if cur_version > req_version: 46 if cur_version > req_version:
@@ -65,6 +66,7 @@ from cscripts.csspec import csspec @@ -65,6 +66,7 @@ from cscripts.csspec import csspec
65 from cscripts.cstsdist import cstsdist 66 from cscripts.cstsdist import cstsdist
66 from cscripts.cstsmapmerge import cstsmapmerge 67 from cscripts.cstsmapmerge import cstsmapmerge
67 from cscripts.csworkflow import csworkflow 68 from cscripts.csworkflow import csworkflow
  69 +from cscripts.cstssplit import cstssplit
68 from cscripts import obsutils 70 from cscripts import obsutils
69 if cur_version > req_version: 71 if cur_version > req_version:
70 from cscripts.csfindobs import csfindobs 72 from cscripts.csfindobs import csfindobs
cscripts/cstssplit.par 0 → 100644
  1 +#############################################################################
  2 +# #
  3 +# CTA Science Analysis Tools #
  4 +# #
  5 +# ------------------------------------------------------------------------- #
  6 +# #
  7 +# File: cstssplit.par #
  8 +# Version: 1.1.0 #
  9 +# #
  10 +# Author: Michael Mayer #
  11 +# michael.mayer@physik.hu-berlin.de #
  12 +# HU Berlin #
  13 +# #
  14 +# Purpose: Parameter file for the cttsmap application #
  15 +# #
  16 +#############################################################################
  17 +#
  18 +# General parameters
  19 +#===================
  20 +inobs, f, a, "events.fits",,, "Input event list, counts cube or observation definition XML file"
  21 +inmodel, f, a, "$CTOOLS/share/models/crab.xml",,, "Input model XML file"
  22 +srcname, s, a, "Crab",,, "Test source name"
  23 +expcube, f, a, "NONE",,, "Input exposure cube file (only needed for stacked analysis)"
  24 +psfcube, f, a, "NONE",,, "Input PSF cube file (only needed for stacked analysis)"
  25 +edispcube, f, a, "NONE",,, "Input energy dispersion cube file (only needed for stacked analysis)"
  26 +bkgcube, f, a, "NONE",,, "Input background cube file (only needed for stacked analysis)"
  27 +caldb, s, a, "prod2",,, "Calibration database"
  28 +irf, s, a, "South_0.5h",,, "Instrument response function"
  29 +edisp, b, h, no,,, "Apply energy dispersion?"
  30 +outmap, f, a, "tsmap.fits",,, "Output Test Statistic map file"
  31 +bins_per_job, i, a, 5,,, "Number of TS map bins per running job"
  32 +compute_null, b, a, yes,,,"Compute null hypothesis first?"
  33 +outfile, f, a, "commands.txt",,, "ASCII file containing all commands"
  34 +
  35 +#
  36 +# Spatial binning parameters
  37 +#===========================
  38 +usepnt, b, h, no,,, "Use pointing instead of xref/yref parameters?"
  39 +nxpix, i, a, 200,,, "Size of the X axis in pixels"
  40 +nypix, i, a, 200,,, "Size of the Y axis in pixels"
  41 +binsz, r, a, 0.02,,, "Image scale (in degrees/pixel)"
  42 +coordsys, s, a, "CEL", CEL|GAL,,"Coordinate system (CEL - celestial, GAL - galactic)"
  43 +xref, r, a, 83.63,0,360, "First coordinate of image center in degrees (RA or galactic l)"
  44 +yref, r, a, 22.01,-90,90, "Second coordinate of image center in degrees (DEC or galactic b)"
  45 +proj, s, a, "CAR", AIT|AZP|CAR|MER|MOL|STG|TAN,, "Projection method"
  46 +
  47 +#
  48 +# Standard parameters
  49 +#====================
  50 +publish, b, h, no,,, "Publish Test Statistic map on VO Hub?"
  51 +chatter, i, h, 2,0,4, "Chattiness of output"
  52 +clobber, b, h, yes,,, "Overwrite existing output files with new output files?"
  53 +debug, b, h, no,,, "Debugging mode activated"
  54 +mode, s, h, "ql",,, "Mode of automatic parameters"
  55 +logfile, f, h, "cstssplit.log",,, "Log filename"
cscripts/cstssplit.py 0 → 100755
  1 +#!/usr/bin/env python
  2 +# ==========================================================================
  3 +# Create commands to split TS map computation
  4 +#
  5 +# Copyright (C) 2016 Michael Mayer
  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 sys
  22 +import os
  23 +import math
  24 +import gammalib
  25 +import ctools
  26 +
  27 +
  28 +# ============== #
  29 +# cstssplit class #
  30 +# ============== #
  31 +class cstssplit(ctools.cscript):
  32 + """
  33 + Generates commands to split TS map computation
  34 +
  35 + This class implements the creation of file containing commands to split
  36 + the computation of a TS map into several machines. It derives from
  37 + the ctools.cscript class which provides support for parameter files,
  38 + command line arguments, and logging. In that way the Python script
  39 + behaves just as a regular ctool.
  40 + """
  41 +
  42 + # Consructor
  43 + def __init__(self, *argv):
  44 + """
  45 + Constructor.
  46 + """
  47 +
  48 + # Set name
  49 + self._name = 'cstssplit'
  50 + self._version = '1.1.0'
  51 + self._outmap = gammalib.GFilename()
  52 + self._bins_per_job = 0
  53 + self._compute_null = False
  54 + self._outfile = gammalib.GFilename()
  55 + self._map = gammalib.GSkyMap()
  56 + self._cmd = []
  57 +
  58 + # Initialise observation container from constructor arguments.
  59 + self._obs, argv = self._set_input_obs(argv)
  60 +
  61 + # Initialise application by calling the appropriate class
  62 + # constructor.
  63 + self._init_cscript(argv)
  64 +
  65 + # Return
  66 + return
  67 +
  68 +
  69 + # Private methods
  70 + def _get_parameters(self):
  71 + """
  72 + Get parameters from parfile and setup the observation.
  73 + """
  74 +
  75 + # If there are no observations in container then get some ...
  76 + if self._obs.size() == 0:
  77 + self._obs = self._get_observations()
  78 +
  79 + # Set models if we have none
  80 + if self._obs.models().size() == 0:
  81 + self._obs.models(self['inmodel'].filename())
  82 +
  83 + # Get TS map paramters
  84 + self._map = self._create_map(self._obs)
  85 + self._srcname = self['srcname'].string()
  86 + self._outmap = self['outmap'].filename()
  87 +
  88 + # Get additional parameters
  89 + self._bins_per_job = self['bins_per_job'].integer()
  90 + self._compute_null = self['compute_null'].boolean()
  91 + self._outfile = self['outfile'].filename()
  92 +
  93 + # Write input parameters into logger
  94 + if self._logTerse():
  95 + self._log_parameters()
  96 + self._log('\n')
  97 +
  98 + # Return
  99 + return
  100 +
  101 +
  102 + def _compute_null_hypothesis(self):
  103 + """
  104 + Compute null hypothesis
  105 +
  106 + Returns:
  107 + Log-likelihood of null hypothesis
  108 + """
  109 +
  110 + # Store original models
  111 + models_orig = self._obs.models()
  112 +
  113 + # Get models instance
  114 + models0 = self._obs.models()
  115 +
  116 + # Remove test source
  117 + models0.remove(self._srcname)
  118 +
  119 + # Initialise optimizer
  120 + opt = gammalib.GOptimizerLM()
  121 +
  122 + # Set models for null hypothesis
  123 + self._obs.models(models0)
  124 +
  125 + # Optimise observation container
  126 + self._obs.optimize(opt)
  127 +
  128 + # Set original models to container
  129 + self._obs.models(models_orig)
  130 +
  131 + # Return optimised log-likelihood of null hypothesis
  132 + return -(opt.value())
  133 +
  134 +
  135 + def run(self):
  136 + """
  137 + Run the script.
  138 + """
  139 +
  140 + # Switch screen logging on in debug mode
  141 + if self._logDebug():
  142 + self._log.cout(True)
  143 +
  144 + # Get parameters
  145 + self._get_parameters()
  146 +
  147 + # Write information into logger
  148 + if self._logTerse():
  149 + self._log('\n')
  150 + self._log.header1('Test source')
  151 + model = self._obs.models()[self._srcname]
  152 + self._log(str(model))
  153 + self._log('\n')
  154 +
  155 + # Set log-likelihood to zero
  156 + logL0 = 0.0
  157 +
  158 + # Pre-compute null hypothesis if requested
  159 + if self._compute_null:
  160 +
  161 + # Write information into logger
  162 + if self._logTerse():
  163 + self._log('\n')
  164 + self._log.header1('Compute null hypothesis')
  165 +
  166 + # Compute null hypothesis
  167 + logL0 = self._compute_null_hypothesis()
  168 +
  169 + # Write likelihood into logger
  170 + if self._logTerse():
  171 + self._log(gammalib.parformat('Source removed'))
  172 + self._log(self._srcname)
  173 + self._log('\n')
  174 + self._log(gammalib.parformat('Log-likelihood'))
  175 + self._log(repr(logL0))
  176 + self._log('\n')
  177 +
  178 + # Get parameters of TS map ctool
  179 + pars = gammalib.GApplicationPars('cttsmap.par')
  180 +
  181 + # Compute total number of jobs
  182 + nbins = self._map.npix()
  183 + njobs = int(math.ceil(float(nbins) / float(self._bins_per_job)) + 0.1)
  184 +
  185 + # Set parameters to be skipped now, we will deal with them later
  186 + skip_pars = ['binmin', 'binmax', 'logL0', 'outmap', 'logfile']
  187 +
  188 + # Set tool name for computation
  189 + base_command = 'cttsmap'
  190 +
  191 + # Write information into logger
  192 + if self._logTerse():
  193 + self._log('\n')
  194 + self._log.header1('Create commands')
  195 + self._log(gammalib.parformat('Number of cttsmap calls'))
  196 + self._log(str(njobs))
  197 + self._log('\n')
  198 +
  199 + # Loop over TS map parameters
  200 + for par in pars:
  201 +
  202 + # Skip if we deal with them later
  203 + if par.name() in skip_pars:
  204 + continue
  205 +
  206 + # Skip if they need to be queried
  207 + # This way we ensure we pass only parameters
  208 + # that were queried before
  209 + if self[par.name()].is_query():
  210 + continue
  211 +
  212 + # Set TS map parameter according to input from
  213 + # this script
  214 + par.value(self[par.name()].value())
  215 +
  216 + # Append command to set parameter
  217 + base_command += ' ' + par.name() + '=' + par.value()
  218 +
  219 + # Append null hypothesis parameter
  220 + base_command += ' logL0=' + repr(logL0)
  221 +
  222 + # Set binning to start from zero
  223 + binmin = 0
  224 + binmax = 0
  225 +
  226 + # Clear command sequence
  227 + self._cmd = []
  228 +
  229 + # Loop over jobs and create commands
  230 + for job in range(njobs):
  231 +
  232 + # Set specific outmap file name
  233 + outmap = self._outmap.url().replace('.fits', '_'+str(job)+'.fits')
  234 +
  235 + # Set bin numbers to be computed in this job
  236 + binmin = binmax
  237 + binmax = binmin + self._bins_per_job
  238 + if binmax > nbins:
  239 + binmax = nbins
  240 +
  241 + # Complete command by binning parameters
  242 + sliced_command = base_command + ' binmin='+str(binmin)+' binmax='+str(binmax)
  243 + sliced_command += ' outmap='+outmap + ' logfile='+outmap.replace('.fits','.log')
  244 +
  245 + # Append command to list of commands
  246 + self._cmd.append(sliced_command)
  247 +
  248 + # Write information into logger
  249 + if self._logExplicit():
  250 + self._log('\n')
  251 + self._log.header2('Commands')
  252 + for cmd in self._cmd:
  253 + self._log(cmd)
  254 + self._log('\n')
  255 + self._log('\n')
  256 +
  257 + # Return
  258 + return
  259 +
  260 +
  261 + def execute(self):
  262 + """
  263 + Execute the script.
  264 + """
  265 +
  266 + # Run the script
  267 + self.run()
  268 +
  269 + # Save results
  270 + self.save()
  271 +
  272 + # Return
  273 + return
  274 +
  275 +
  276 + def save(self):
  277 + """
  278 + Save commands to ASCII file
  279 + """
  280 +
  281 + # Open file
  282 + f = open(self._outfile.url(), 'w')
  283 +
  284 + # Write commands to file
  285 + for cmd in self._cmd:
  286 + f.write(cmd + '\n')
  287 +
  288 + # Close file
  289 + f.close()
  290 +
  291 + # Return
  292 + return
  293 +# ======================== #
  294 +# Main routine entry point #
  295 +# ======================== #
  296 +if __name__ == '__main__':
  297 + """
  298 + Generates splitted TS map commands
  299 + """
  300 +
  301 + # Create instance of application
  302 + app = cstssplit(sys.argv)
  303 +
  304 + # Execute application
  305 + app.execute()
  306 +
  307 +#
doc/source/users/reference_manual/cstssplit.rst 0 → 100644
  1 +.. _cstssplit:
  2 +
  3 +cstssplit
  4 +=======
  5 +
  6 +Generate commands to split TS map computation
  7 +
  8 +
  9 +Synopsis
  10 +--------
  11 +
  12 +This tool allows to generate a command sequence in order to compute a
  13 +Test Statistic (TS) map using e.g. several machines. The command sequence
  14 +is stored in an ASCII file. Each line contains an individual command.
  15 +Each command will call the tool :ref:`cttsmap` with the appropriate parameters.
  16 +To split the computation, each TS map that is computed has a suffix to the filename
  17 +according to the number of the command. The resulting individual TS maps can then be
  18 +merged via :ref:`cstsmapmerge`.
  19 +
  20 +
  21 +General parameters
  22 +------------------
  23 +
  24 +``inobs [file]``
  25 + Input event list, counts cube or observation definition XML file.
  26 +
  27 +``inmodel [file]``
  28 + Input model XML file.
  29 +
  30 +``srcname [string]``
  31 + Name of source model for which the TS map should be computed.
  32 +
  33 +``expcube [file]``
  34 + Input exposure cube file (only needed for stacked analysis).
  35 +
  36 +``psfcube [file]``
  37 + Input PSF cube file (only needed for stacked analysis).
  38 +
  39 +``bkgcube [file]``
  40 + Input background cube file (only needed for stacked analysis).
  41 +
  42 +``caldb [string]``
  43 + Calibration database.
  44 +
  45 +``irf [string]``
  46 + Instrumental response function.
  47 +
  48 +``(edisp = no) [boolean]``
  49 + Applies energy dispersion to response computation.
  50 +
  51 +``outmap [file]``
  52 + Output Test Statistic map file.
  53 +
  54 +``(usepnt = no) [boolean]``
  55 + Use CTA pointing direction for map centre instead of xref/yref parameters?
  56 +
  57 +``nxpix [integer]``
  58 + Number of map pixels in Right Ascension or Galactic longitude.
  59 +
  60 +``nypix [integer]``
  61 + Number of map pixels in Declination or Galactic latitude.
  62 +
  63 +``binsz [real]``
  64 + Map pixel size (in degrees/pixel).
  65 +
  66 +``coordsys <CEL|GAL> [string]``
  67 + Coordinate system (CEL - celestial, GAL - galactic).
  68 +
  69 +``xref [real]``
  70 + Right Ascension / Galactic longitude of map centre (J2000, in degrees).
  71 +
  72 +``yref [real]``
  73 + Declination / Galactic latitude of map centre (J2000, in degrees).
  74 +
  75 +``proj <AIT|AZP|CAR|MER|MOL|STG|TAN> [string]``
  76 + Projection method.
  77 +
  78 +``bins_per_job [integer]``
  79 + Number of bins of the TS map that should be computed within one command
  80 +
  81 +``compute_null [boolean]``
  82 + Pre-computes the null hypothesis globally and passes the value to the individual commands
  83 + If 'false', the null hypothesis will be computed in each run of :ref:`cttsmap` individually.
  84 +
  85 +``outfile [file]``
  86 + Output ASCII file name where the commands are written to.
  87 +
  88 +
  89 +Standard parameters
  90 +-------------------
  91 +
  92 +``(publish = no) [boolean]``
  93 + Specifies whether the TS map should be published on VO Hub.
  94 +
  95 +``(chatter = 2) [integer]``
  96 + Verbosity of the executable:
  97 + chatter = 0: no information will be logged
  98 +
  99 + chatter = 1: only errors will be logged
  100 +
  101 + chatter = 2: errors and actions will be logged
  102 +
  103 + chatter = 3: report about the task execution
  104 +
  105 + chatter = 4: detailed report about the task execution
  106 +
  107 +``(clobber = yes) [boolean]``
  108 + Specifies whether an existing output TS map file should be overwritten.
  109 +
  110 +``(debug = no) [boolean]``
  111 + Enables debug mode. In debug mode the executable will dump any log file output to the console.
  112 +
  113 +``(mode = ql) [string]``
  114 + Mode of automatic parameters (default is "ql", i.e. "query and learn").
  115 +
  116 +``(logfile = cttsmap.log) [string]``
  117 + Name of log file.
  118 +
  119 +
  120 +Related tools or scripts
  121 +------------------------
  122 +
  123 +:ref:`cttsmap`
  124 +:ref:`cstsmapmerge`
  125 +
  126 +
doc/source/users/reference_manual/index.rst
@@ -50,7 +50,9 @@ cscripts @@ -50,7 +50,9 @@ cscripts
50 cssens --- Computes CTA sensitivity <cssens> 50 cssens --- Computes CTA sensitivity <cssens>
51 csspec --- Computes spectral points <csspec> 51 csspec --- Computes spectral points <csspec>
52 cstsdist --- Generates TS distribution <cstsdist> 52 cstsdist --- Generates TS distribution <cstsdist>
  53 + cstssplit --- Creates commands to slice the ts map computations <cstssplit>
53 cstsmapmerge --- Merges slices from ts map computations <cstsmapmerge> 54 cstsmapmerge --- Merges slices from ts map computations <cstsmapmerge>
  55 +
54 56
55 57
56 Scripts to manage an IACT database 58 Scripts to manage an IACT database
test/test_cstssplit.py 0 → 100755
  1 +#! /usr/bin/env python
  2 +# ==========================================================================
  3 +# This scripts performs unit tests for the cstssplit script.
  4 +#
  5 +# Copyright (C) 2016 Michael Mayer
  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 cstssplit script #
  28 +# =============================== #
  29 +class Test(gammalib.GPythonTestSuite):
  30 + """
  31 + Test class for cstssplit script.
  32 +
  33 + This test class makes unit tests for the csstsplit 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('cstssplit')
  55 +
  56 + # Append tests
  57 + self.append(self._test_cmd, "Test cstssplit on command line")
  58 + #self.append(self._test_python, "Test cstssplit from Python")
  59 +
  60 + # Return
  61 + return
  62 +
  63 + # Test cstssplit on command line
  64 + def _test_cmd(self):
  65 + """
  66 + Test cstssplit on the command line.
  67 + """
  68 + # Kluge to set the command (installed version has no README file)
  69 + if os.path.isfile("README.md"):
  70 + cstssplit = "../cscripts/cstssplit.py"
  71 + else:
  72 + cstssplit = "cstssplit"
  73 +
  74 + # Setup cstssplit command
  75 + cmd = cstssplit+' inobs="selected_events.fits"'+ \
  76 + ' inmodel="data/crab.xml"'+ \
  77 + ' srcname="Crab"'+ \
  78 + ' caldb="irf"'+ \
  79 + ' irf="cta_dummy_irf"'+ \
  80 + ' outmap="tsmap.fits"'+ \
  81 + ' nxpix=5'+ \
  82 + ' nypix=5'+ \
  83 + ' binsz=0.05'+ \
  84 + ' coordsys="CEL"'+ \
  85 + ' xref=83.63'+ \
  86 + ' yref=22.01'+ \
  87 + ' proj="CAR"'+ \
  88 + ' compute_null=yes'+ \
  89 + ' bins_per_job=5'+ \
  90 + ' outfile="tsmap_cmds1.txt"'
  91 +
  92 +
  93 + # Execute cstssplit, make sure we catch any exception
  94 + try:
  95 + rc = os.system(cmd+" >/dev/null 2>&1")
  96 + except:
  97 + pass
  98 +
  99 + # Check if execution was successful
  100 + self.test_assert(rc == 0,
  101 + "Successful cstsssplit execution on command line")
  102 +
  103 + # Check observation definition XML file
  104 + self._check_cmdfile('tsmap_cmds1.txt')
  105 +
  106 + # Setup cstssplit command
  107 + cmd = cstssplit+' inobs="selected_events.fits"'+ \
  108 + ' inmodel="data/crab.xml"'+ \
  109 + ' srcname="Does_not_exist"'+ \
  110 + ' caldb="irf"'+ \
  111 + ' irf="cta_dummy_irf"'+ \
  112 + ' outmap="tsmap.fits"'+ \
  113 + ' nxpix=5'+ \
  114 + ' nypix=5'+ \
  115 + ' binsz=0.05'+ \
  116 + ' coordsys="CEL"'+ \
  117 + ' xref=83.63'+ \
  118 + ' yref=22.01'+ \
  119 + ' proj="CAR"'+ \
  120 + ' compute_null=yes'+ \
  121 + ' bins_per_job=5'+ \
  122 + ' outfile="tsmap_cmds2.txt"'
  123 +
  124 +
  125 + # Execute cstssplit, make sure we catch any exception
  126 + try:
  127 + rc = os.system(cmd+" >/dev/null 2>&1")
  128 + except:
  129 + pass
  130 +
  131 + # Check if execution failed
  132 + self.test_assert(rc != 0,
  133 + "Failure of cstssplit execution on command line")
  134 +
  135 + # Return
  136 + return
  137 +
  138 + # Test cstssplit from Python
  139 + def _test_python(self):
  140 + """
  141 + Test cstssplit from Python.
  142 + """
  143 + # Set-up cstssplit
  144 + tssplit = cscripts.cstssplit()
  145 + tssplit['inobs'] = 'obs_selected.xml'
  146 + tssplit['inmodel'] = 'data/crab.xml'
  147 + tssplit['xref'] = 83.6331
  148 + tssplit['yref'] = 22.01
  149 + tssplit['coordsys'] = 'CEL'
  150 + tssplit['proj'] = 'CAR'
  151 + tssplit['binsz'] = 0.05
  152 + tssplit['nxpix'] = 5
  153 + tssplit['nypix'] = 5
  154 + tssplit['compute_null'] = False
  155 + tssplit['bins_per_job'] = 5
  156 + tssplit['outfile'] = 'tsmap_cmd_py1.txt'
  157 +
  158 +
  159 + # Run cstssplit script and save run list
  160 + tssplit.logFileOpen() # Make sure we get a log file
  161 + tssplit.run()
  162 + tssplit.save()
  163 +
  164 + # Check observation definition XML file
  165 + self._check_cmdfile('tsmap_cmd_py1.txt')
  166 +
  167 + # Return
  168 + return
  169 +
  170 + # Check observation definition XML file
  171 + def _check_cmdfile(self, filename):
  172 + """
  173 + Check ascii files containing commands
  174 + """
  175 +
  176 + # Create file name instance
  177 + fname = gammalib.GFilename(filename)
  178 +
  179 + # Check if execution was successful
  180 + self.test_assert(fname.exists(),
  181 + "Output of cstssplit exists")
  182 +
  183 + # Return
  184 + return
test/test_python_cscripts.py
@@ -42,6 +42,7 @@ import test_csworkflow @@ -42,6 +42,7 @@ import test_csworkflow
42 import test_csiactcopy 42 import test_csiactcopy
43 import test_csiactdata 43 import test_csiactdata
44 import test_csiactobs 44 import test_csiactobs
  45 +import test_cstssplit
45 46
46 47
47 # ================== # 48 # ================== #
@@ -113,6 +114,7 @@ def test(installed=False, debug=False): @@ -113,6 +114,7 @@ def test(installed=False, debug=False):
113 suite_cstsdist = test_cstsdist.Test() 114 suite_cstsdist = test_cstsdist.Test()
114 suite_cstsmapmerge = test_cstsmapmerge.Test() 115 suite_cstsmapmerge = test_cstsmapmerge.Test()
115 suite_csworkflow = test_csworkflow.Test() 116 suite_csworkflow = test_csworkflow.Test()
  117 + suite_cstssplit = test_cstssplit.Test()
116 118
117 # Setup unit tests 119 # Setup unit tests
118 suite_cscaldb.set() 120 suite_cscaldb.set()
@@ -130,6 +132,7 @@ def test(installed=False, debug=False): @@ -130,6 +132,7 @@ def test(installed=False, debug=False):
130 suite_cstsdist.set() 132 suite_cstsdist.set()
131 suite_cstsmapmerge.set() 133 suite_cstsmapmerge.set()
132 suite_csworkflow.set() 134 suite_csworkflow.set()
  135 + suite_cstssplit.set()
133 136
134 # Append tests to container 137 # Append tests to container
135 suites.append(suite_cscaldb) 138 suites.append(suite_cscaldb)
@@ -147,6 +150,7 @@ def test(installed=False, debug=False): @@ -147,6 +150,7 @@ def test(installed=False, debug=False):
147 suites.append(suite_cstsdist) 150 suites.append(suite_cstsdist)
148 suites.append(suite_cstsmapmerge) 151 suites.append(suite_cstsmapmerge)
149 suites.append(suite_csworkflow) 152 suites.append(suite_csworkflow)
  153 + suites.append(suite_cstssplit)
150 154
151 # Append tests for Python 2.6+ (the IACT cscripts depend on the json 155 # Append tests for Python 2.6+ (the IACT cscripts depend on the json
152 # module which is only available since Python 2.6+ 156 # module which is only available since Python 2.6+