Commit 4fdb5ce125d6f7e365771e3f5d791158051abc55

Authored by Jürgen Knödlseder
1 parent b030e64d

Revise cstsdist parameters (#1567)

The cstsdist parameter interface is now much simpler, requiring on input either an unbinned, binned or stacked observation. If an observation definition XML file is provided it is assumed that the file only contains event lists.
ChangeLog
@@ -26,6 +26,7 @@ @@ -26,6 +26,7 @@
26 Add "NODES" method to csspec to support non-CTA analysis (#1927) 26 Add "NODES" method to csspec to support non-CTA analysis (#1927)
27 Use t-type parameters for all "tmin" and "tmax" parameters (#1864) 27 Use t-type parameters for all "tmin" and "tmax" parameters (#1864)
28 Set OBS_ID in ctobssim (#1836) 28 Set OBS_ID in ctobssim (#1836)
  29 + Revise cstsdist parameters (#1567)
29 Add ctbutterfly::butterfly() method (#1512) 30 Add ctbutterfly::butterfly() method (#1512)
30 31
31 32
@@ -319,8 +319,14 @@ The script now derives from the csobservation base class. A "statistic" @@ -319,8 +319,14 @@ The script now derives from the csobservation base class. A "statistic"
319 parameter was added to allow setting the optimizer statistic for the Test 319 parameter was added to allow setting the optimizer statistic for the Test
320 Statistic distribution generation (#2237). 320 Statistic distribution generation (#2237).
321 321
322 -Use t-type parameters for "tmin" and "tmax" to all specifying times in various  
323 -formats (#1864). 322 +The parameter interface was considerably revised, in particular the following
  323 +parameters were removed: "ra", "dec", "rad", "coordsys", "proj", "emin",
  324 +"emax", "enumbins", "tmin", "tmax", "npix" and "binsz". The "inobs" parameter
  325 +is now always queried. The script now reads in an observation or an observation
  326 +container and derives the TS distribution for a source based on that observation
  327 +container. So far the script supports unbinned, binned and stacked observations.
  328 +If an observation definition XML file is specified the script assumes that all
  329 +observations are event lists (#1567).
324 330
325 331
326 cstsmapmerge - Merge Test Statistic maps 332 cstsmapmerge - Merge Test Statistic maps
cscripts/cstsdist.par
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 # 16 #
17 # Input and output parameters 17 # Input and output parameters
18 #============================ 18 #============================
19 -inobs, f, h, NONE,,, "Input event list, counts cube, or observation definition XML file" 19 +inobs, f, a, events.fits,,, "Input event list, counts cube, or observation definition XML file"
20 inmodel, f, a, $CTOOLS/share/models/crab.xml,,, "Input model definition XML file" 20 inmodel, f, a, $CTOOLS/share/models/crab.xml,,, "Input model definition XML file"
21 srcname, s, a, Crab,,, "Source name" 21 srcname, s, a, Crab,,, "Source name"
22 expcube, f, a, NONE,,, "Input exposure cube file" 22 expcube, f, a, NONE,,, "Input exposure cube file"
@@ -33,18 +33,6 @@ outfile, f, a, ts.dat,,, "Output Test Statistic distribution file" @@ -33,18 +33,6 @@ outfile, f, a, ts.dat,,, "Output Test Statistic distribution file"
33 # Script parameters 33 # Script parameters
34 #================== 34 #==================
35 ntrials, i, a, 10,,, "Number of trials" 35 ntrials, i, a, 10,,, "Number of trials"
36 -ra, r, a, 83.63,0,360, "RA of pointing (degrees)"  
37 -dec, r, a, 22.01,-90,90, "Dec of pointing (degrees)"  
38 -rad, r, h, 5.0,0,180, "Radius of ROI (degrees)"  
39 -coordsys, s, a, CEL,CEL|GAL,, "Coordinate system (CEL - celestial, GAL - galactic)"  
40 -proj, s, a, TAN,AIT|AZP|CAR|GLS|MER|MOL|SFL|SIN|STG|TAN,, "Projection method"  
41 -emin, r, a, 0.1,,, "Lower energy limit (TeV)"  
42 -emax, r, a, 100.0,,, "Upper energy limit (TeV)"  
43 -enumbins, i, a, 0,,, "Number of energy bins (0=unbinned)"  
44 -tmin, t, a, 2020-01-01T00:00:00,,, "Start time (UTC string, JD, MJD or MET in seconds)"  
45 -tmax, t, a, 2020-01-01T00:30:00,,, "Stop time (UTC string, JD, MJD or MET in seconds)"  
46 -npix, i, a, 200,,, "Number of pixels for binned"  
47 -binsz, r, a, 0.05,,, "Pixel size for binned (degrees/pixel)"  
48 statistic, s, h, DEFAULT,DEFAULT|CSTAT|WSTAT|CHI2,, "Optimization statistic" 36 statistic, s, h, DEFAULT,DEFAULT|CSTAT|WSTAT|CHI2,, "Optimization statistic"
49 37
50 # 38 #
cscripts/cstsdist.py
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 # ========================================================================== 2 # ==========================================================================
3 # Generates the TS distribution for a particular model 3 # Generates the TS distribution for a particular model
4 # 4 #
5 -# Copyright (C) 2011-2017 Juergen Knoedlseder 5 +# Copyright (C) 2011-2018 Juergen Knoedlseder
6 # 6 #
7 # This program is free software: you can redistribute it and/or modify 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 8 # it under the terms of the GNU General Public License as published by
@@ -37,7 +37,7 @@ class cstsdist(ctools.csobservation): @@ -37,7 +37,7 @@ class cstsdist(ctools.csobservation):
37 # Constructor 37 # Constructor
38 def __init__(self, *argv): 38 def __init__(self, *argv):
39 """ 39 """
40 - Constructor. 40 + Constructor
41 """ 41 """
42 # Initialise application by calling the appropriate class constructor 42 # Initialise application by calling the appropriate class constructor
43 self._init_csobservation(self.__class__.__name__, ctools.__version__, argv) 43 self._init_csobservation(self.__class__.__name__, ctools.__version__, argv)
@@ -45,6 +45,7 @@ class cstsdist(ctools.csobservation): @@ -45,6 +45,7 @@ class cstsdist(ctools.csobservation):
45 # Initialise some members 45 # Initialise some members
46 self._srcname = '' 46 self._srcname = ''
47 self._log_clients = False 47 self._log_clients = False
  48 + self._model = None
48 49
49 # Return 50 # Return
50 return 51 return
@@ -65,13 +66,6 @@ class cstsdist(ctools.csobservation): @@ -65,13 +66,6 @@ class cstsdist(ctools.csobservation):
65 # Get source name 66 # Get source name
66 self._srcname = self['srcname'].string() 67 self._srcname = self['srcname'].string()
67 68
68 - # Query parameters for binned if requested  
69 - if self['enumbins'].integer() != 0:  
70 - self['npix'].integer()  
71 - self['binsz'].real()  
72 - self['coordsys'].string()  
73 - self['proj'].string()  
74 -  
75 # Set models if we have none 69 # Set models if we have none
76 if self.obs().models().size() == 0: 70 if self.obs().models().size() == 0:
77 self.obs().models(self['inmodel'].filename()) 71 self.obs().models(self['inmodel'].filename())
@@ -79,15 +73,73 @@ class cstsdist(ctools.csobservation): @@ -79,15 +73,73 @@ class cstsdist(ctools.csobservation):
79 # Query parameters 73 # Query parameters
80 self['edisp'].boolean() 74 self['edisp'].boolean()
81 self['ntrials'].integer() 75 self['ntrials'].integer()
82 - self['outfile'].filename() 76 +
83 self['debug'].boolean() 77 self['debug'].boolean()
84 78
  79 + # Read ahead output parameters
  80 + #if self._read_ahead():
  81 + # self['outfile'].filename()
  82 + self['outfile'].filename()
  83 +
85 # Write input parameters into logger 84 # Write input parameters into logger
86 self._log_parameters(gammalib.TERSE) 85 self._log_parameters(gammalib.TERSE)
87 86
88 # Return 87 # Return
89 return 88 return
90 89
  90 + def _sim(self, seed):
  91 + """
  92 + Return a simulated observation container
  93 +
  94 + Parameters
  95 + ----------
  96 + seed : int
  97 + Random number generator seed
  98 +
  99 + Returns
  100 + -------
  101 + sim : `~gammalib.GObservations`
  102 + Simulated observation container
  103 + """
  104 + # If observation is a counts cube then simulate events from the counts
  105 + # cube model ...
  106 + if self.obs().size() == 1 and self.obs()[0].eventtype() == 'CountsCube':
  107 +
  108 + # If no counts cube model exists then compute it now
  109 + if self._model == None:
  110 + model = ctools.ctmodel(self.obs())
  111 + model['debug'] = self['debug'].boolean()
  112 + model['chatter'] = self['chatter'].integer()
  113 + model.run()
  114 + self._model = model.cube().copy() # Save copy for persistence
  115 +
  116 + # Allocate random number generator
  117 + ran = gammalib.GRan()
  118 +
  119 + # Get copy of model map
  120 + counts = self._model.counts().copy()
  121 +
  122 + # Randomize counts
  123 + for i in range(counts.npix()):
  124 + counts[i] = ran.poisson(counts[i])
  125 +
  126 + # Copy observations
  127 + sim = self.obs().copy()
  128 +
  129 + # Set counts map
  130 + sim[0].events().counts(counts)
  131 +
  132 + # ... otherwise simuate events from the observation container (works
  133 + # only for event lists
  134 + else:
  135 + sim = obsutils.sim(self.obs(),
  136 + seed = seed,
  137 + log = self._log_clients,
  138 + debug = self['debug'].boolean())
  139 +
  140 + # Return simulated observation
  141 + return sim
  142 +
91 def _trial(self, seed): 143 def _trial(self, seed):
92 """ 144 """
93 Create the TS for a single trial 145 Create the TS for a single trial
@@ -105,29 +157,8 @@ class cstsdist(ctools.csobservation): @@ -105,29 +157,8 @@ class cstsdist(ctools.csobservation):
105 # Write header 157 # Write header
106 self._log_header2(gammalib.EXPLICIT, 'Trial %d' % (seed+1)) 158 self._log_header2(gammalib.EXPLICIT, 'Trial %d' % (seed+1))
107 159
108 - # Set default binned parameters  
109 - coordsys = 'CEL'  
110 - proj = 'TAN'  
111 - npix = 0  
112 - binsz = 0.0  
113 -  
114 - # If binned analysis is requested the read the binned parameters  
115 - if self['enumbins'].integer() != 0:  
116 - npix = self['npix'].integer()  
117 - binsz = self['binsz'].real()  
118 - coordsys = self['coordsys'].string()  
119 - proj = self['proj'].string()  
120 -  
121 # Simulate events 160 # Simulate events
122 - sim = obsutils.sim(self.obs(),  
123 - nbins = self['enumbins'].integer(),  
124 - seed = seed,  
125 - proj = proj,  
126 - coord = coordsys,  
127 - binsz = binsz,  
128 - npix = npix,  
129 - log = self._log_clients,  
130 - debug = self['debug'].boolean()) 161 + sim = self._sim(seed)
131 162
132 # Determine number of events in simulation 163 # Determine number of events in simulation
133 nevents = 0.0 164 nevents = 0.0
@@ -160,7 +191,7 @@ class cstsdist(ctools.csobservation): @@ -160,7 +191,7 @@ class cstsdist(ctools.csobservation):
160 for model in models: 191 for model in models:
161 self._log_value(gammalib.EXPLICIT, 'Model', model.name()) 192 self._log_value(gammalib.EXPLICIT, 'Model', model.name())
162 for par in model: 193 for par in model:
163 - self._log_string(gammalib.EXPLICIT, str(par)+'\n') 194 + self._log_string(gammalib.EXPLICIT, str(par))
164 elif self._logNormal(): 195 elif self._logNormal():
165 name = 'Trial %d' % seed 196 name = 'Trial %d' % seed
166 value = 'TS=%.3f Prefactor=%e +/- %e' % \ 197 value = 'TS=%.3f Prefactor=%e +/- %e' % \
doc/source/users/reference_manual/cstsdist.rst
@@ -15,9 +15,6 @@ sets. The Test Statistics is defined as twice the log-likelihood difference @@ -15,9 +15,6 @@ sets. The Test Statistics is defined as twice the log-likelihood difference
15 that is obtained when fitting simulated data with and without a given 15 that is obtained when fitting simulated data with and without a given
16 source model component. 16 source model component.
17 17
18 -This script either performs an unbinned or a binned simulation, stacked  
19 -analysis is not yet supported.  
20 -  
21 cstsdist will create an ASCII file in comma-separated value (CSV) format, 18 cstsdist will create an ASCII file in comma-separated value (CSV) format,
22 containing one row per TS computation. The first row is a header row providing 19 containing one row per TS computation. The first row is a header row providing
23 the column names. The following rows give the TS value, the log-likelihood 20 the column names. The following rows give the TS value, the log-likelihood
@@ -26,13 +23,18 @@ fitted events, as well as the values and errors for all fitted parameters. @@ -26,13 +23,18 @@ fitted events, as well as the values and errors for all fitted parameters.
26 23
27 From the output file, TS distribution plots can be generated using for 24 From the output file, TS distribution plots can be generated using for
28 example the ``show_ts_distribution.py`` script in the examples folder. The 25 example the ``show_ts_distribution.py`` script in the examples folder. The
29 -script require matplotlib for plotting. 26 +script requires matplotlib for plotting.
  27 +
  28 +.. warning::
  29 + This script does not work for On/Off observations. If an observation
  30 + definition XML file is specified the script assumes that all observations
  31 + are event lists.
30 32
31 33
32 General parameters 34 General parameters
33 ------------------ 35 ------------------
34 36
35 -``(inobs = NONE) [file]`` 37 +``inobs [file]``
36 Input event list, counts cube or observation definition XML file. 38 Input event list, counts cube or observation definition XML file.
37 39
38 ``inmodel [file]`` 40 ``inmodel [file]``
@@ -72,42 +74,6 @@ General parameters @@ -72,42 +74,6 @@ General parameters
72 ``ntrials [integer]`` 74 ``ntrials [integer]``
73 Number of Monte Carlo samples. 75 Number of Monte Carlo samples.
74 76
75 -``ra [real]``  
76 - Right Ascension of CTA pointing (J2000, in degrees).  
77 -  
78 -``dec [real]``  
79 - Declination of CTA pointing (J2000, in degrees).  
80 -  
81 -``(rad = 5.0) [real]``  
82 - ROI radius (in degrees).  
83 -  
84 -``coordsys <CEL|GAL> [string]``  
85 - Coordinate system (CEL - celestial, GAL - galactic).  
86 -  
87 -``proj <AIT|AZP|CAR|GLS|MER|MOL|SFL|SIN|STG|TAN> [string]``  
88 - Projection method.  
89 -  
90 -``emin [real]``  
91 - Lower energy limit (in TeV).  
92 -  
93 -``emax [real]``  
94 - Upper energy limit (in TeV).  
95 -  
96 -``enumbins [integer]``  
97 - Number of energy bins (0=unbinned).  
98 -  
99 -``tmin [time]``  
100 - Start time (UTC string, JD, MJD or MET in seconds).  
101 -  
102 -``tmax [time]``  
103 - Stop time (UTC string, JD, MJD or MET in seconds).  
104 -  
105 -``npix [integer]``  
106 - Number of pixels for binned analysis.  
107 -  
108 -``binsz [real]``  
109 - Pixel size for binned analysis.  
110 -  
111 ``(statistic = DEFAULT) <DEFAULT|CSTAT|WSTAT|CHI2> [string]`` 77 ``(statistic = DEFAULT) <DEFAULT|CSTAT|WSTAT|CHI2> [string]``
112 Optimization statistic. ``DEFAULT`` uses the default statistic for all 78 Optimization statistic. ``DEFAULT`` uses the default statistic for all
113 observations, which is ``CSTAT`` or the statistic specified in the 79 observations, which is ``CSTAT`` or the statistic specified in the
src/Makefile.am
@@ -100,7 +100,7 @@ help-install: @@ -100,7 +100,7 @@ help-install:
100 echo "$(INSTALL_DATA) $$file $(DESTDIR)$(datadir)/help/$$helpname" ; \ 100 echo "$(INSTALL_DATA) $$file $(DESTDIR)$(datadir)/help/$$helpname" ; \
101 $(INSTALL_DATA) "$$file" $(DESTDIR)$(datadir)/help/"$$helpname" ; \ 101 $(INSTALL_DATA) "$$file" $(DESTDIR)$(datadir)/help/"$$helpname" ; \
102 sed -i.bak -e 's/``//g' -e 's/`//g' -e 's/:ref://g' -e 's/:doc://g' \ 102 sed -i.bak -e 's/``//g' -e 's/`//g' -e 's/:ref://g' -e 's/:doc://g' \
103 - -e 's/.. note::/Note/g' -e '1d' \ 103 + -e 's/.. note::/Note/g' -e 's/.. warning::/Warning/g' -e '1d' \
104 $(DESTDIR)$(datadir)/help/"$$helpname" ; \ 104 $(DESTDIR)$(datadir)/help/"$$helpname" ; \
105 rm -rf $(DESTDIR)$(datadir)/help/"$$helpname".bak ; \ 105 rm -rf $(DESTDIR)$(datadir)/help/"$$helpname".bak ; \
106 done 106 done
test/test_cstsdist.py
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 # ========================================================================== 2 # ==========================================================================
3 # This scripts performs unit tests for the cstsdist script. 3 # This scripts performs unit tests for the cstsdist script.
4 # 4 #
5 -# Copyright (C) 2016-2017 Juergen Knoedlseder 5 +# Copyright (C) 2016-2018 Juergen Knoedlseder
6 # 6 #
7 # This program is free software: you can redistribute it and/or modify 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 8 # it under the terms of the GNU General Public License as published by
@@ -42,6 +42,10 @@ class Test(test): @@ -42,6 +42,10 @@ class Test(test):
42 # Call base class constructor 42 # Call base class constructor
43 test.__init__(self) 43 test.__init__(self)
44 44
  45 + # Set members
  46 + self._stacked_inobs = self._datadir + '/obs_stacked.xml'
  47 + self._stacked_model = self._datadir + '/crab_bkgcube.xml'
  48 +
45 # Return 49 # Return
46 return 50 return
47 51
@@ -55,7 +59,12 @@ class Test(test): @@ -55,7 +59,12 @@ class Test(test):
55 59
56 # Append tests 60 # Append tests
57 self.append(self._test_cmd, 'Test cstsdist on command line') 61 self.append(self._test_cmd, 'Test cstsdist on command line')
58 - self.append(self._test_python, 'Test cstsdist from Python') 62 + self.append(self._test_python_unbinned,
  63 + 'Test cstsdist from Python in unbinned mode')
  64 + self.append(self._test_python_binned,
  65 + 'Test cstsdist from Python in binned mode')
  66 + self.append(self._test_python_stacked,
  67 + 'Test cstsdist from Python in stacked mode')
59 68
60 # Return 69 # Return
61 return 70 return
@@ -69,12 +78,10 @@ class Test(test): @@ -69,12 +78,10 @@ class Test(test):
69 cstsdist = self._script('cstsdist') 78 cstsdist = self._script('cstsdist')
70 79
71 # Setup cstsdist command 80 # Setup cstsdist command
72 - cmd = cstsdist+' inmodel="'+self._model+'"'+ \  
73 - ' srcname="Crab"'+ \ 81 + cmd = cstsdist+' inobs="'+self._events+'"'+ \
  82 + ' inmodel="'+self._model+'" srcname="Crab"'+ \
74 ' caldb="'+self._caldb+'" irf="'+self._irf+'"'+ \ 83 ' caldb="'+self._caldb+'" irf="'+self._irf+'"'+ \
75 - ' ntrials=1 ra=83.63 dec=22.01 emin=0.1 emax=100.0'+ \  
76 - ' enumbins=0 tmin=0.0 tmax=1800.0 rad=5.0 npix=200 npix=200'+ \  
77 - ' binsz=0.05'+ \ 84 + ' ntrials=2 '+ \
78 ' outfile="cstsdist_cmd1.dat"'+ \ 85 ' outfile="cstsdist_cmd1.dat"'+ \
79 ' logfile="cstsdist_cmd1.log" chatter=2' 86 ' logfile="cstsdist_cmd1.log" chatter=2'
80 87
@@ -90,14 +97,12 @@ class Test(test): @@ -90,14 +97,12 @@ class Test(test):
90 self._check_result_file('cstsdist_cmd1.dat') 97 self._check_result_file('cstsdist_cmd1.dat')
91 98
92 # Setup cstsdist command 99 # Setup cstsdist command
93 - cmd = cstsdist+' inmodel="model_that_does_not_exist.xml"'+ \  
94 - ' srcname="Crab"'+ \ 100 + cmd = cstsdist+' inobs="event_file_that_does_not_exist.xml"'+ \
  101 + ' inmodel="'+self._model+'" srcname="Crab"'+ \
95 ' caldb="'+self._caldb+'" irf="'+self._irf+'"'+ \ 102 ' caldb="'+self._caldb+'" irf="'+self._irf+'"'+ \
96 - ' ntrials=1 ra=83.63 dec=22.01 emin=0.1 emax=100.0'+ \  
97 - ' enumbins=0 tmin=0.0 tmax=1800.0 rad=5.0 npix=200 npix=200'+ \  
98 - ' binsz=0.05'+ \ 103 + ' ntrials=1 '+ \
99 ' outfile="cstsdist_cmd2.dat"'+ \ 104 ' outfile="cstsdist_cmd2.dat"'+ \
100 - ' logfile="cstsdist_cmd2.log" debug=yes chatter=2' 105 + ' logfile="cstsdist_cmd2.log" chatter=2'
101 106
102 # Check if execution failed 107 # Check if execution failed
103 self.test_assert(self._execute(cmd) != 0, 108 self.test_assert(self._execute(cmd) != 0,
@@ -110,25 +115,18 @@ class Test(test): @@ -110,25 +115,18 @@ class Test(test):
110 return 115 return
111 116
112 # Test cstsdist from Python 117 # Test cstsdist from Python
113 - def _test_python(self): 118 + def _test_python_unbinned(self):
114 """ 119 """
115 Test cstsdist from Python 120 Test cstsdist from Python
116 """ 121 """
117 - # Set-up cstsdist 122 + # Set-up cstsdist for event list
118 tsdist = cscripts.cstsdist() 123 tsdist = cscripts.cstsdist()
  124 + tsdist['inobs'] = self._events
119 tsdist['inmodel'] = self._model 125 tsdist['inmodel'] = self._model
120 tsdist['srcname'] = 'Crab' 126 tsdist['srcname'] = 'Crab'
121 tsdist['caldb'] = self._caldb 127 tsdist['caldb'] = self._caldb
122 tsdist['irf'] = self._irf 128 tsdist['irf'] = self._irf
123 - tsdist['ntrials'] = 1  
124 - tsdist['ra'] = 83.63  
125 - tsdist['dec'] = 22.01  
126 - tsdist['emin'] = 0.1  
127 - tsdist['emax'] = 100.0  
128 - tsdist['enumbins'] = 0  
129 - tsdist['tmin'] = 0.0  
130 - tsdist['tmax'] = 1800.0  
131 - tsdist['rad'] = 5.0 129 + tsdist['ntrials'] = 2
132 tsdist['outfile'] = 'cstsdist_py1.dat' 130 tsdist['outfile'] = 'cstsdist_py1.dat'
133 tsdist['logfile'] = 'cstsdist_py1.log' 131 tsdist['logfile'] = 'cstsdist_py1.log'
134 tsdist['chatter'] = 3 132 tsdist['chatter'] = 3
@@ -144,8 +142,61 @@ class Test(test): @@ -144,8 +142,61 @@ class Test(test):
144 # Return 142 # Return
145 return 143 return
146 144
  145 + def _test_python_binned(self):
  146 + """
  147 + Test cstsdist from Python
  148 + """
  149 + # Set-up cstsdist for counts cube
  150 + tsdist = cscripts.cstsdist()
  151 + tsdist['inobs'] = self._cntcube
  152 + tsdist['inmodel'] = self._model
  153 + tsdist['srcname'] = 'Crab'
  154 + tsdist['expcube'] = 'NONE'
  155 + tsdist['psfcube'] = 'NONE'
  156 + tsdist['bkgcube'] = 'NONE'
  157 + tsdist['caldb'] = self._caldb
  158 + tsdist['irf'] = self._irf
  159 + tsdist['ntrials'] = 2
  160 + tsdist['outfile'] = 'cstsdist_py2.dat'
  161 + tsdist['logfile'] = 'cstsdist_py2.log'
  162 + tsdist['chatter'] = 4
  163 +
  164 + # Run cstsdist script
  165 + tsdist.logFileOpen() # Make sure we get a log file
  166 + tsdist.execute()
  167 +
  168 + # Check pull distribution file
  169 + self._check_result_file('cstsdist_py2.dat')
  170 +
  171 + # Return
  172 + return
  173 +
  174 + def _test_python_stacked(self):
  175 + """
  176 + Test cstsdist from Python
  177 + """
  178 + # Set-up cstsdist for stacked cube
  179 + tsdist = cscripts.cstsdist()
  180 + tsdist['inobs'] = self._stacked_inobs
  181 + tsdist['inmodel'] = self._stacked_model
  182 + tsdist['srcname'] = 'Crab'
  183 + tsdist['ntrials'] = 2
  184 + tsdist['outfile'] = 'cstsdist_py3.dat'
  185 + tsdist['logfile'] = 'cstsdist_py3.log'
  186 + tsdist['chatter'] = 4
  187 +
  188 + # Run cstsdist script
  189 + tsdist.logFileOpen() # Make sure we get a log file
  190 + tsdist.execute()
  191 +
  192 + # Check pull distribution file
  193 + self._check_result_file('cstsdist_py3.dat')
  194 +
  195 + # Return
  196 + return
  197 +
147 # Check result file 198 # Check result file
148 - def _check_result_file(self, filename, ncols=9): 199 + def _check_result_file(self, filename, nrows=3, ncols=9):
149 """ 200 """
150 Check result file 201 Check result file
151 202
@@ -153,6 +204,8 @@ class Test(test): @@ -153,6 +204,8 @@ class Test(test):
153 ---------- 204 ----------
154 filename : str 205 filename : str
155 Name of result file 206 Name of result file
  207 + nrows : int, optional
  208 + Required number of rows
156 ncols : int, optional 209 ncols : int, optional
157 Required number of columns 210 Required number of columns
158 """ 211 """
@@ -160,7 +213,7 @@ class Test(test): @@ -160,7 +213,7 @@ class Test(test):
160 results = gammalib.GCsv(filename, ',') 213 results = gammalib.GCsv(filename, ',')
161 214
162 # Check dimensions 215 # Check dimensions
163 - self.test_value(results.nrows(), 2, 'Check rows in TS file') 216 + self.test_value(results.nrows(), nrows, 'Check rows in TS file')
164 self.test_value(results.ncols(), ncols, 'Check columns in TS file') 217 self.test_value(results.ncols(), ncols, 'Check columns in TS file')
165 218
166 # Return 219 # Return