Commit 9dd6c7493b90309626e6ee3e4fd7853143fb6321

Authored by Jürgen Knödlseder
1 parent d04d0a7a

Replace ASCII output files by FITS files in cstsdist (#1707)

@@ -307,7 +307,7 @@ None @@ -307,7 +307,7 @@ None
307 307
308 cstsdist - Computes Test Statistic distribution 308 cstsdist - Computes Test Statistic distribution
309 ----------------------------------------------- 309 -----------------------------------------------
310 -None 310 +The ASCII output file was replaced by a FITS file (#1707).
311 311
312 312
313 cstsmapmerge - Merge Test Statistic maps 313 cstsmapmerge - Merge Test Statistic maps
@@ -361,9 +361,9 @@ regions (#3248). @@ -361,9 +361,9 @@ regions (#3248).
361 361
362 Examples 362 Examples
363 -------- 363 --------
364 -The show_butterfly, show_pull_evolution.py, show_pull_histogram.py and  
365 -show_sensitivity.py scripts were adapted to deal also with FITS output files  
366 -(#1707). 364 +The show_butterfly, show_pull_evolution.py, show_pull_histogram.py,
  365 +show_sensitivity.py and show_ts_distribution.py scripts were adapted to deal
  366 +also with FITS output files (#1707).
367 367
368 368
369 caldb 369 caldb
cscripts/Makefile.am
@@ -214,6 +214,7 @@ testdata = $(top_srcdir)/test/data/crab.xml \ @@ -214,6 +214,7 @@ testdata = $(top_srcdir)/test/data/crab.xml \
214 $(top_srcdir)/test/data/residual_onoff.fits \ 214 $(top_srcdir)/test/data/residual_onoff.fits \
215 $(top_srcdir)/test/data/lightcurve.fits \ 215 $(top_srcdir)/test/data/lightcurve.fits \
216 $(top_srcdir)/test/data/ts.dat \ 216 $(top_srcdir)/test/data/ts.dat \
  217 + $(top_srcdir)/test/data/ts.fits \
217 $(top_srcdir)/test/data/models_spatial.xml \ 218 $(top_srcdir)/test/data/models_spatial.xml \
218 $(top_srcdir)/test/data/models_spectral.xml \ 219 $(top_srcdir)/test/data/models_spectral.xml \
219 $(top_srcdir)/test/data/model_filefunction.txt \ 220 $(top_srcdir)/test/data/model_filefunction.txt \
cscripts/cspull.py
@@ -476,7 +476,6 @@ class cspull(ctools.csobservation): @@ -476,7 +476,6 @@ class cspull(ctools.csobservation):
476 # If multiprocessing was used then recover results and put them 476 # If multiprocessing was used then recover results and put them
477 # into the log file 477 # into the log file
478 if self._nthreads > 1: 478 if self._nthreads > 1:
479 - #result = poolresults[i][0]  
480 results.append(poolresults[i][0]) 479 results.append(poolresults[i][0])
481 self._log_string(gammalib.TERSE, poolresults[i][1]['log'], False) 480 self._log_string(gammalib.TERSE, poolresults[i][1]['log'], False)
482 481
cscripts/cstsdist.par
@@ -27,7 +27,7 @@ caldb, s, a, prod2,,, "Calibration database" @@ -27,7 +27,7 @@ caldb, s, a, prod2,,, "Calibration database"
27 irf, s, a, South_0.5h,,, "Instrument response function" 27 irf, s, a, South_0.5h,,, "Instrument response function"
28 edisp, b, h, no,,, "Apply energy dispersion?" 28 edisp, b, h, no,,, "Apply energy dispersion?"
29 deadc, r, h, 0.98,0,1, "Deadtime correction factor" 29 deadc, r, h, 0.98,0,1, "Deadtime correction factor"
30 -outfile, f, a, ts.dat,,, "Output Test Statistic distribution file" 30 +outfile, f, a, ts.fits,,, "Output Test Statistic distribution FITS file"
31 31
32 # 32 #
33 # Script parameters 33 # Script parameters
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-2018 Juergen Knoedlseder 5 +# Copyright (C) 2011-2021 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
@@ -45,6 +45,7 @@ class cstsdist(ctools.csobservation): @@ -45,6 +45,7 @@ class cstsdist(ctools.csobservation):
45 45
46 # Initialise some members 46 # Initialise some members
47 self._srcname = '' 47 self._srcname = ''
  48 + self._fits = None
48 self._log_clients = False 49 self._log_clients = False
49 self._model = None 50 self._model = None
50 self._nthreads = 0 51 self._nthreads = 0
@@ -65,6 +66,7 @@ class cstsdist(ctools.csobservation): @@ -65,6 +66,7 @@ class cstsdist(ctools.csobservation):
65 # Set pickled dictionary 66 # Set pickled dictionary
66 state = {'base' : ctools.csobservation.__getstate__(self), 67 state = {'base' : ctools.csobservation.__getstate__(self),
67 'srcname' : self._srcname, 68 'srcname' : self._srcname,
  69 + 'fits' : self._fits,
68 'log_clients' : self._log_clients, 70 'log_clients' : self._log_clients,
69 'model' : self._model, 71 'model' : self._model,
70 'nthreads' : self._nthreads} 72 'nthreads' : self._nthreads}
@@ -83,6 +85,7 @@ class cstsdist(ctools.csobservation): @@ -83,6 +85,7 @@ class cstsdist(ctools.csobservation):
83 """ 85 """
84 ctools.csobservation.__setstate__(self, state['base']) 86 ctools.csobservation.__setstate__(self, state['base'])
85 self._srcname = state['srcname'] 87 self._srcname = state['srcname']
  88 + self._fits = state['fits']
86 self._log_clients = state['log_clients'] 89 self._log_clients = state['log_clients']
87 self._model = state['model'] 90 self._model = state['model']
88 self._nthreads = state['nthreads'] 91 self._nthreads = state['nthreads']
@@ -113,7 +116,10 @@ class cstsdist(ctools.csobservation): @@ -113,7 +116,10 @@ class cstsdist(ctools.csobservation):
113 self['edisp'].boolean() 116 self['edisp'].boolean()
114 self['ntrials'].integer() 117 self['ntrials'].integer()
115 self['debug'].boolean() 118 self['debug'].boolean()
116 - self['outfile'].filename() 119 +
  120 + # Read ahead output parameters
  121 + if self._read_ahead():
  122 + self['outfile'].filename()
117 123
118 # Write input parameters into logger 124 # Write input parameters into logger
119 self._log_parameters(gammalib.TERSE) 125 self._log_parameters(gammalib.TERSE)
@@ -261,14 +267,14 @@ class cstsdist(ctools.csobservation): @@ -261,14 +267,14 @@ class cstsdist(ctools.csobservation):
261 if par.is_free(): 267 if par.is_free():
262 268
263 # Set parameter name 269 # Set parameter name
264 - name = model_name+"_"+par.name() 270 + name = model_name + '_' + par.name()
265 271
266 # Append value 272 # Append value
267 colnames.append(name) 273 colnames.append(name)
268 values[name] = par.value() 274 values[name] = par.value()
269 275
270 # Append error 276 # Append error
271 - name = 'e_'+name 277 + name = name+'_error'
272 colnames.append(name) 278 colnames.append(name)
273 values[name] = par.error() 279 values[name] = par.error()
274 280
@@ -278,6 +284,75 @@ class cstsdist(ctools.csobservation): @@ -278,6 +284,75 @@ class cstsdist(ctools.csobservation):
278 # Return 284 # Return
279 return result 285 return result
280 286
  287 + def _create_fits(self, results):
  288 + """
  289 + Create FITS file from results
  290 +
  291 + Parameters
  292 + ----------
  293 + results : list of dict
  294 + List of result dictionaries
  295 + """
  296 + # Gather headers for parameter columns
  297 + headers = []
  298 + for colname in results[0]['colnames']:
  299 + if colname != 'TS' and colname != 'Nevents' and \
  300 + colname != 'Npred':
  301 + headers.append(colname)
  302 +
  303 + # Create FITS table columns
  304 + nrows = len(results)
  305 + ts = gammalib.GFitsTableDoubleCol('TS', nrows)
  306 + nevents = gammalib.GFitsTableDoubleCol('NEVENTS', nrows)
  307 + npred = gammalib.GFitsTableDoubleCol('NPRED', nrows)
  308 + ts.unit('')
  309 + nevents.unit('counts')
  310 + npred.unit('counts')
  311 + columns = []
  312 + for header in headers:
  313 + name = gammalib.toupper(header)
  314 + column = gammalib.GFitsTableDoubleCol(name, nrows)
  315 + column.unit('')
  316 + columns.append(column)
  317 +
  318 + # Fill FITS table columns
  319 + for i, result in enumerate(results):
  320 + ts[i] = result['values']['TS']
  321 + nevents[i] = result['values']['Nevents']
  322 + npred[i] = result['values']['Npred']
  323 + for k, column in enumerate(columns):
  324 + column[i] = result['values'][headers[k]]
  325 +
  326 + # Initialise FITS Table with extension "TS_DISTRIBUTION"
  327 + table = gammalib.GFitsBinTable(nrows)
  328 + table.extname('TS_DISTRIBUTION')
  329 +
  330 + # Add keywors for compatibility with gammalib.GMWLSpectrum
  331 + table.card('INSTRUME', 'CTA', 'Name of Instrument')
  332 + table.card('TELESCOP', 'CTA', 'Name of Telescope')
  333 +
  334 + # Stamp header
  335 + self._stamp(table)
  336 +
  337 + # Add script keywords
  338 + table.card('NTRIALS', self['ntrials'].integer(), 'Number of trials')
  339 + table.card('STAT', self['statistic'].string(), 'Optimization statistic')
  340 + table.card('EDISP', self['edisp'].boolean(), 'Use energy dispersion?')
  341 +
  342 + # Append filled columns to fits table
  343 + table.append(ts)
  344 + table.append(nevents)
  345 + table.append(npred)
  346 + for column in columns:
  347 + table.append(column)
  348 +
  349 + # Create the FITS file now
  350 + self._fits = gammalib.GFits()
  351 + self._fits.append(table)
  352 +
  353 + # Return
  354 + return
  355 +
281 356
282 # Public methods 357 # Public methods
283 def run(self): 358 def run(self):
@@ -306,6 +381,9 @@ class cstsdist(ctools.csobservation): @@ -306,6 +381,9 @@ class cstsdist(ctools.csobservation):
306 # Get number of trials 381 # Get number of trials
307 ntrials = self['ntrials'].integer() 382 ntrials = self['ntrials'].integer()
308 383
  384 + # Initialise results
  385 + results = []
  386 +
309 # If more than a single thread is requested then use multiprocessing 387 # If more than a single thread is requested then use multiprocessing
310 if self._nthreads > 1: 388 if self._nthreads > 1:
311 args = [(self, '_trial', i) for i in range(ntrials)] 389 args = [(self, '_trial', i) for i in range(ntrials)]
@@ -317,16 +395,20 @@ class cstsdist(ctools.csobservation): @@ -317,16 +395,20 @@ class cstsdist(ctools.csobservation):
317 # If multiprocessing was used then recover results and put them 395 # If multiprocessing was used then recover results and put them
318 # into the log file 396 # into the log file
319 if self._nthreads > 1: 397 if self._nthreads > 1:
320 - result = poolresults[i][0] 398 + results.append(poolresults[i][0])
321 self._log_string(gammalib.TERSE, poolresults[i][1]['log'], False) 399 self._log_string(gammalib.TERSE, poolresults[i][1]['log'], False)
322 400
323 # ... otherwise make a trial now 401 # ... otherwise make a trial now
324 else: 402 else:
  403 +
  404 + # Run trial
325 result = self._trial(i) 405 result = self._trial(i)
326 406
327 - # Write out trial result  
328 - ioutils.write_csv_row(self['outfile'].filename().url(), i,  
329 - result['colnames'], result['values']) 407 + # Append results
  408 + results.append(result)
  409 +
  410 + # Create FITS file
  411 + self._create_fits(results)
330 412
331 # Return 413 # Return
332 return 414 return
@@ -346,6 +428,38 @@ class cstsdist(ctools.csobservation): @@ -346,6 +428,38 @@ class cstsdist(ctools.csobservation):
346 # Return 428 # Return
347 return 429 return
348 430
  431 + def save(self):
  432 + """
  433 + Save TS distribution FITS file
  434 + """
  435 + # Write header
  436 + self._log_header1(gammalib.TERSE, 'Save TS distribution')
  437 +
  438 + # Continue only if FITS file is valid
  439 + if self._fits != None:
  440 +
  441 + # Get outmap parameter
  442 + outfile = self['outfile'].filename()
  443 +
  444 + # Log file name
  445 + self._log_value(gammalib.NORMAL, 'TS distribution file', outfile.url())
  446 +
  447 + # Save TS distribution
  448 + self._fits.saveto(outfile, self['clobber'].boolean())
  449 +
  450 + # Return
  451 + return
  452 +
  453 + def ts_distribution(self):
  454 + """
  455 + Return TS distribution FITS file
  456 +
  457 + Returns:
  458 + FITS file containing TS distribution
  459 + """
  460 + # Return
  461 + return self._fits
  462 +
349 463
350 # ======================== # 464 # ======================== #
351 # Main routine entry point # 465 # Main routine entry point #
doc/source/users/reference_manual/cspull.rst
@@ -74,7 +74,7 @@ General parameters @@ -74,7 +74,7 @@ General parameters
74 Average deadtime correction factor. 74 Average deadtime correction factor.
75 75
76 ``outfile [file]`` 76 ``outfile [file]``
77 - ASCII file containing the individual pull values. 77 + Output pull distribution FITS ASCII file.
78 78
79 ``ntrials [integer]`` 79 ``ntrials [integer]``
80 Number of samples for generating the pull distribution. 80 Number of samples for generating the pull distribution.
doc/source/users/reference_manual/cstsdist.rst
@@ -20,11 +20,10 @@ be performed in parallel over as many processes as the number of CPUs available @@ -20,11 +20,10 @@ be performed in parallel over as many processes as the number of CPUs available
20 machine. The maximum number of parallel processes can be set by the user through the 20 machine. The maximum number of parallel processes can be set by the user through the
21 ``nthreads`` hidden parameter. 21 ``nthreads`` hidden parameter.
22 22
23 -:ref:`cstsdist` will create an ASCII file in comma-separated value (CSV) format,  
24 -containing one row per TS computation. The first row is a header row providing  
25 -the column names. The following rows give the TS value, the log-likelihood  
26 -values of the fit with or without the source, the number of observed and  
27 -fitted events, as well as the values and errors for all fitted parameters. 23 +:ref:`cstsdist` will create on output a FITS file containing a table with one row
  24 +per TS computation. The columns in the table comprise the TS value, the number
  25 +of observed and fitted events, and the values and errors for all fitted
  26 +parameters.
28 27
29 From the output file, TS distribution plots can be generated using for 28 From the output file, TS distribution plots can be generated using for
30 example the ``show_ts_distribution.py`` script in the examples folder. The 29 example the ``show_ts_distribution.py`` script in the examples folder. The
@@ -74,7 +73,7 @@ General parameters @@ -74,7 +73,7 @@ General parameters
74 Average deadtime correction factor. 73 Average deadtime correction factor.
75 74
76 ``outfile [file]`` 75 ``outfile [file]``
77 - Output ASCII file containing the TS distribution values. 76 + Output TS distribution FITS file.
78 77
79 ``ntrials [integer]`` 78 ``ntrials [integer]``
80 Number of Monte Carlo samples. 79 Number of Monte Carlo samples.
doc/source/users/reference_manual/ctbutterfly.rst
@@ -68,7 +68,7 @@ General parameters @@ -68,7 +68,7 @@ General parameters
68 Applies energy dispersion to response computation. 68 Applies energy dispersion to response computation.
69 69
70 ``outfile [file]`` 70 ``outfile [file]``
71 - Output butterfly ASCII file name. 71 + Output butterfly FITS file.
72 72
73 ``(fit = no) [boolean]`` 73 ``(fit = no) [boolean]``
74 Performs maximum likelihood fitting of input model ignoring any provided 74 Performs maximum likelihood fitting of input model ignoring any provided
examples/show_pull_evolution.py
@@ -51,8 +51,8 @@ def read_pull_distribution(filename, parname): @@ -51,8 +51,8 @@ def read_pull_distribution(filename, parname):
51 51
52 Returns 52 Returns
53 ------- 53 -------
54 - pulls : dict  
55 - Dictionary with pull distribution 54 + pulls : list of floats
  55 + List with pull distribution
56 """ 56 """
57 # Read pull distribution dependent on file type 57 # Read pull distribution dependent on file type
58 fname = gammalib.GFilename(filename) 58 fname = gammalib.GFilename(filename)
@@ -81,8 +81,8 @@ def read_pull_distribution_fits(filename, parname): @@ -81,8 +81,8 @@ def read_pull_distribution_fits(filename, parname):
81 81
82 Returns 82 Returns
83 ------- 83 -------
84 - pulls : dict  
85 - Dictionary with pull distribution 84 + pulls : list of floats
  85 + List with pull distribution
86 """ 86 """
87 # Open FITS file 87 # Open FITS file
88 fits = gammalib.GFits(filename) 88 fits = gammalib.GFits(filename)
examples/show_pull_histogram.py
@@ -51,8 +51,8 @@ def read_pull_distribution(filename, parname): @@ -51,8 +51,8 @@ def read_pull_distribution(filename, parname):
51 51
52 Returns 52 Returns
53 ------- 53 -------
54 - pulls : dict  
55 - Dictionary with pull distribution 54 + pulls : list of floats
  55 + List with pull distribution
56 """ 56 """
57 # Read pull distribution dependent on file type 57 # Read pull distribution dependent on file type
58 fname = gammalib.GFilename(filename) 58 fname = gammalib.GFilename(filename)
@@ -81,8 +81,8 @@ def read_pull_distribution_fits(filename, parname): @@ -81,8 +81,8 @@ def read_pull_distribution_fits(filename, parname):
81 81
82 Returns 82 Returns
83 ------- 83 -------
84 - pulls : dict  
85 - Dictionary with pull distribution 84 + pulls : list of floats
  85 + List with pull distribution
86 """ 86 """
87 # Open FITS file 87 # Open FITS file
88 fits = gammalib.GFits(filename) 88 fits = gammalib.GFits(filename)
examples/show_ts_distribution.py
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 # ========================================================================== 2 # ==========================================================================
3 # Display TS distribution generated by cstsdist 3 # Display TS distribution generated by cstsdist
4 # 4 #
5 -# Copyright (C) 2011-2020 Jurgen Knodlseder 5 +# Copyright (C) 2011-2021 Jurgen Knodlseder
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
@@ -33,13 +33,84 @@ try: @@ -33,13 +33,84 @@ try:
33 except ImportError: 33 except ImportError:
34 print('This script needs the "numpy" module') 34 print('This script needs the "numpy" module')
35 sys.exit() 35 sys.exit()
  36 +import gammalib
36 import cscripts 37 import cscripts
37 38
38 39
39 # ==================== # 40 # ==================== #
40 # Read TS distribution # 41 # Read TS distribution #
41 # ==================== # 42 # ==================== #
42 -def read_ts(filename, tsname='TS'): 43 +def read_ts_distribution(filename):
  44 + """
  45 + Read TS distribution
  46 +
  47 + Parameters
  48 + ----------
  49 + filename : str
  50 + Name of FITS or CSV file
  51 + parname : str
  52 + Parameter name
  53 +
  54 + Returns
  55 + -------
  56 + ts : list of floats
  57 + List with TS distribution
  58 + """
  59 + # Read TS distribution dependent on file type
  60 + fname = gammalib.GFilename(filename)
  61 + if fname.is_fits():
  62 + ts = read_ts_distribution_fits(filename)
  63 + else:
  64 + ts = read_ts_distribution_csv(filename)
  65 +
  66 + # Return ts
  67 + return ts
  68 +
  69 +
  70 +# =================================== #
  71 +# Read TS distribution from FITS file #
  72 +# =================================== #
  73 +def read_ts_distribution_fits(filename):
  74 + """
  75 + Read TS distribution from FITS file
  76 +
  77 + Parameters
  78 + ----------
  79 + filename : str
  80 + Name of FITS file
  81 + parname : str
  82 + Parameter name
  83 +
  84 + Returns
  85 + -------
  86 + ts : list of floats
  87 + List with TS distribution
  88 + """
  89 + # Open FITS file
  90 + fits = gammalib.GFits(filename)
  91 +
  92 + # Get TS distribution table
  93 + table = fits.table('TS_DISTRIBUTION')
  94 +
  95 + # Get relevant column
  96 + column = table['TS']
  97 +
  98 + # Initialise vector
  99 + ts = []
  100 +
  101 + # Fill vectors
  102 + nrows = table.nrows()
  103 + for row in range(nrows):
  104 + ts.append(column[row])
  105 +
  106 + # Return TS distribution
  107 + return ts
  108 +
  109 +
  110 +# ==================== #
  111 +# Read TS distribution #
  112 +# ==================== #
  113 +def read_ts_distribution_csv(filename, tsname='TS'):
43 """ 114 """
44 Read TS distribution values from CSV file 115 Read TS distribution values from CSV file
45 116
@@ -52,8 +123,8 @@ def read_ts(filename, tsname='TS'): @@ -52,8 +123,8 @@ def read_ts(filename, tsname='TS'):
52 123
53 Returns 124 Returns
54 ------- 125 -------
55 - a : `numpy.array`  
56 - Array of TS values 126 + values : list of floats
  127 + List with TS distribution
57 """ 128 """
58 # Initialise list 129 # Initialise list
59 values = [] 130 values = []
@@ -82,11 +153,8 @@ def read_ts(filename, tsname='TS'): @@ -82,11 +153,8 @@ def read_ts(filename, tsname='TS'):
82 # Flag that first row has been passed 153 # Flag that first row has been passed
83 first = False 154 first = False
84 155
85 - # Create numpy array  
86 - a = np.array(values)  
87 -  
88 - # Return array  
89 - return a 156 + # Return TS values
  157 + return values
90 158
91 159
92 # =========== # 160 # =========== #
@@ -309,9 +377,11 @@ def show_ts_distribution(): @@ -309,9 +377,11 @@ def show_ts_distribution():
309 disttype = options[4]['value'] 377 disttype = options[4]['value']
310 plotfile = options[5]['value'] 378 plotfile = options[5]['value']
311 379
312 - # Read values from CSV file  
313 - values = read_ts(args[0], tsname=tsname)  
314 - print('%d values read.' % len(values)) 380 + # Read TS distribution from file
  381 + ts = read_ts_distribution(args[0])
  382 +
  383 + # Create Numpy array
  384 + values = np.array(ts)
315 385
316 # Show histogram 386 # Show histogram
317 if disttype == 'pdf': 387 if disttype == 'pdf':
test/data/ts.fits 0 → 100644
No preview for this file type
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-2018 Juergen Knoedlseder 5 +# Copyright (C) 2016-2021 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
@@ -83,7 +83,7 @@ class Test(test): @@ -83,7 +83,7 @@ class Test(test):
83 ' inmodel="'+self._model+'" srcname="Crab"'+ \ 83 ' inmodel="'+self._model+'" srcname="Crab"'+ \
84 ' caldb="'+self._caldb+'" irf="'+self._irf+'"'+ \ 84 ' caldb="'+self._caldb+'" irf="'+self._irf+'"'+ \
85 ' ntrials=2 '+ \ 85 ' ntrials=2 '+ \
86 - ' outfile="cstsdist_cmd1.dat"'+ \ 86 + ' outfile="cstsdist_cmd1.fits"'+ \
87 ' logfile="cstsdist_cmd1.log" chatter=2' 87 ' logfile="cstsdist_cmd1.log" chatter=2'
88 88
89 # Check if execution was successful 89 # Check if execution was successful
@@ -91,14 +91,14 @@ class Test(test): @@ -91,14 +91,14 @@ class Test(test):
91 'Check successful execution from command line') 91 'Check successful execution from command line')
92 92
93 # Check result file 93 # Check result file
94 - self._check_result_file('cstsdist_cmd1.dat') 94 + self._check_result_file('cstsdist_cmd1.fits')
95 95
96 # Setup cstsdist command 96 # Setup cstsdist command
97 cmd = cstsdist+' inobs="event_file_that_does_not_exist.xml"'+ \ 97 cmd = cstsdist+' inobs="event_file_that_does_not_exist.xml"'+ \
98 ' inmodel="'+self._model+'" srcname="Crab"'+ \ 98 ' inmodel="'+self._model+'" srcname="Crab"'+ \
99 ' caldb="'+self._caldb+'" irf="'+self._irf+'"'+ \ 99 ' caldb="'+self._caldb+'" irf="'+self._irf+'"'+ \
100 ' ntrials=2 '+ \ 100 ' ntrials=2 '+ \
101 - ' outfile="cstsdist_cmd2.dat"'+ \ 101 + ' outfile="cstsdist_cmd2.fits"'+ \
102 ' logfile="cstsdist_cmd2.log" chatter=2' 102 ' logfile="cstsdist_cmd2.log" chatter=2'
103 103
104 # Check if execution failed 104 # Check if execution failed
@@ -124,7 +124,7 @@ class Test(test): @@ -124,7 +124,7 @@ class Test(test):
124 tsdist['caldb'] = self._caldb 124 tsdist['caldb'] = self._caldb
125 tsdist['irf'] = self._irf 125 tsdist['irf'] = self._irf
126 tsdist['ntrials'] = 2 126 tsdist['ntrials'] = 2
127 - tsdist['outfile'] = 'cstsdist_py1.dat' 127 + tsdist['outfile'] = 'cstsdist_py1.fits'
128 tsdist['logfile'] = 'cstsdist_py1.log' 128 tsdist['logfile'] = 'cstsdist_py1.log'
129 tsdist['chatter'] = 3 129 tsdist['chatter'] = 3
130 130
@@ -134,7 +134,7 @@ class Test(test): @@ -134,7 +134,7 @@ class Test(test):
134 tsdist.save() 134 tsdist.save()
135 135
136 # Check TS distribution file 136 # Check TS distribution file
137 - self._check_result_file('cstsdist_py1.dat') 137 + self._check_result_file('cstsdist_py1.fits')
138 138
139 # Return 139 # Return
140 return 140 return
@@ -154,7 +154,7 @@ class Test(test): @@ -154,7 +154,7 @@ class Test(test):
154 tsdist['caldb'] = self._caldb 154 tsdist['caldb'] = self._caldb
155 tsdist['irf'] = self._irf 155 tsdist['irf'] = self._irf
156 tsdist['ntrials'] = 2 156 tsdist['ntrials'] = 2
157 - tsdist['outfile'] = 'cstsdist_py2.dat' 157 + tsdist['outfile'] = 'cstsdist_py2.fits'
158 tsdist['logfile'] = 'cstsdist_py2.log' 158 tsdist['logfile'] = 'cstsdist_py2.log'
159 tsdist['chatter'] = 4 159 tsdist['chatter'] = 4
160 160
@@ -163,7 +163,7 @@ class Test(test): @@ -163,7 +163,7 @@ class Test(test):
163 tsdist.execute() 163 tsdist.execute()
164 164
165 # Check TS distribution file 165 # Check TS distribution file
166 - self._check_result_file('cstsdist_py2.dat') 166 + self._check_result_file('cstsdist_py2.fits')
167 167
168 # Return 168 # Return
169 return 169 return
@@ -178,7 +178,7 @@ class Test(test): @@ -178,7 +178,7 @@ class Test(test):
178 tsdist['inmodel'] = self._stacked_model 178 tsdist['inmodel'] = self._stacked_model
179 tsdist['srcname'] = 'Crab' 179 tsdist['srcname'] = 'Crab'
180 tsdist['ntrials'] = 2 180 tsdist['ntrials'] = 2
181 - tsdist['outfile'] = 'cstsdist_py3.dat' 181 + tsdist['outfile'] = 'cstsdist_py3.fits'
182 tsdist['logfile'] = 'cstsdist_py3.log' 182 tsdist['logfile'] = 'cstsdist_py3.log'
183 tsdist['chatter'] = 4 183 tsdist['chatter'] = 4
184 184
@@ -187,7 +187,7 @@ class Test(test): @@ -187,7 +187,7 @@ class Test(test):
187 tsdist.execute() 187 tsdist.execute()
188 188
189 # Check TS distribution file 189 # Check TS distribution file
190 - self._check_result_file('cstsdist_py3.dat') 190 + self._check_result_file('cstsdist_py3.fits')
191 191
192 # Return 192 # Return
193 return 193 return
@@ -209,7 +209,7 @@ class Test(test): @@ -209,7 +209,7 @@ class Test(test):
209 tsdist['irf'] = self._irf 209 tsdist['irf'] = self._irf
210 tsdist['ntrials'] = 2 210 tsdist['ntrials'] = 2
211 tsdist['nthreads'] = 1 # This tests at the same time no multiprocessing 211 tsdist['nthreads'] = 1 # This tests at the same time no multiprocessing
212 - tsdist['outfile'] = 'cstsdist_py1_pickle.dat' 212 + tsdist['outfile'] = 'cstsdist_py1_pickle.fits'
213 tsdist['logfile'] = 'cstsdist_py1_pickle.log' 213 tsdist['logfile'] = 'cstsdist_py1_pickle.log'
214 tsdist['chatter'] = 3 214 tsdist['chatter'] = 3
215 215
@@ -222,13 +222,13 @@ class Test(test): @@ -222,13 +222,13 @@ class Test(test):
222 obj.save() 222 obj.save()
223 223
224 # Check TS distribution file 224 # Check TS distribution file
225 - self._check_result_file('cstsdist_py1_pickle.dat') 225 + self._check_result_file('cstsdist_py1_pickle.fits')
226 226
227 # Return 227 # Return
228 return 228 return
229 229
230 # Check result file 230 # Check result file
231 - def _check_result_file(self, filename, nrows=3, ncols=9): 231 + def _check_result_file(self, filename, nrows=2, ncols=9):
232 """ 232 """
233 Check result file 233 Check result file
234 234
@@ -241,12 +241,13 @@ class Test(test): @@ -241,12 +241,13 @@ class Test(test):
241 ncols : int, optional 241 ncols : int, optional
242 Required number of columns 242 Required number of columns
243 """ 243 """
244 - # Open result file as CSV file  
245 - results = gammalib.GCsv(filename, ',') 244 + # Open pull file as FITS file
  245 + fits = gammalib.GFits(filename)
  246 + table = fits.table('TS_DISTRIBUTION')
246 247
247 # Check dimensions 248 # Check dimensions
248 - self.test_value(results.nrows(), nrows, 'Check rows in TS file')  
249 - self.test_value(results.ncols(), ncols, 'Check columns in TS file') 249 + self.test_value(table.nrows(), nrows, 'Check rows in TS file')
  250 + self.test_value(table.ncols(), ncols, 'Check columns in TS file')
250 251
251 # Return 252 # Return
252 return 253 return
test/test_examples.py.in
@@ -460,14 +460,21 @@ class Test(gammalib.GPythonTestSuite): @@ -460,14 +460,21 @@ class Test(gammalib.GPythonTestSuite):
460 Test show_ts_distribution 460 Test show_ts_distribution
461 """ 461 """
462 # Set arguments 462 # Set arguments
463 - args = ('-n 100 -p example_show_ts_distribution1.eps %s/ts.dat' % 463 + args = ('-n 100 -p example_show_ts_distribution_csv1.eps %s/ts.dat' %
464 self._datadir) 464 self._datadir)
465 465
466 # Execute script 466 # Execute script
467 self._execute_python('show_ts_distribution', args=args) 467 self._execute_python('show_ts_distribution', args=args)
468 468
469 # Set arguments 469 # Set arguments
470 - args = ('-n 100 -t cdf -p example_show_ts_distribution2.eps %s/ts.dat' % 470 + args = ('-n 100 -t cdf -p example_show_ts_distribution_csv2.eps %s/ts.dat' %
  471 + self._datadir)
  472 +
  473 + # Execute script
  474 + self._execute_python('show_ts_distribution', args=args)
  475 +
  476 + # Set arguments
  477 + args = ('-n 100 -p example_show_ts_distribution_fits.eps %s/ts.fits' %
471 self._datadir) 478 self._datadir)
472 479
473 # Execute script 480 # Execute script