Commit a2954be5a38c12152d65aec5c1d0202fab1bdafe

Authored by Jürgen Knödlseder
2 parents 6f3d5e5a 561d0ed4

Merge branch '1335-write-csresmap' into integration

Conflicts:
	scripts/csresmap.py
ChangeLog
1 -2014-10-10 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu> 1 +2014-10-15 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu>
2 2
3 * Version 0.8.0 released 3 * Version 0.8.0 released
4 ======================== 4 ========================
5 5
6 Clean-up public interface 6 Clean-up public interface
7 - Adapt to GammaLib 0.9.0 interface  
8 - Introduce ctool base class  
9 - ctbin now always merges event lists into a single counts cube  
10 - ctmodel now always creates a single model cube 7 + Adapt to GammaLib 0.9.0 interface
11 Add ctexpcube tool (generates exposure cube) 8 Add ctexpcube tool (generates exposure cube)
12 Add ctpsfcube tool (generates PSF cube) 9 Add ctpsfcube tool (generates PSF cube)
13 Add ctbkgcube tool (generates background cube) 10 Add ctbkgcube tool (generates background cube)
14 Add ctcubemask tool (masks event bins in event cube) 11 Add ctcubemask tool (masks event bins in event cube)
15 Add cttsmap tool (generates TS map) 12 Add cttsmap tool (generates TS map)
  13 + Add csresmap script (generates residual map)
  14 + Introduce ctool base class
  15 + ctbin now always merges event lists into a single counts cube
  16 + ctmodel now always creates a single model cube
16 Support energy dispersion in ctobssim, ctlike and ctmodel 17 Support energy dispersion in ctobssim, ctlike and ctmodel
17 Correct ctobssim for thread safety 18 Correct ctobssim for thread safety
18 Correctly apply time references in ctselect 19 Correctly apply time references in ctselect
@@ -2,7 +2,7 @@ New Features and Important Changes in ctools 00-08-00 @@ -2,7 +2,7 @@ New Features and Important Changes in ctools 00-08-00
2 2
3 Author(s) : Juergen Knoedlseder 3 Author(s) : Juergen Knoedlseder
4 4
5 -10 October 2014 5 +15 October 2014
6 6
7 7
8 1. Introduction 8 1. Introduction
@@ -192,6 +192,9 @@ The following functions have been added to obsutils: @@ -192,6 +192,9 @@ The following functions have been added to obsutils:
192 * spectrum() generates spectral points by fitting a source model in 192 * spectrum() generates spectral points by fitting a source model in
193 specified energy bins. 193 specified energy bins.
194 194
  195 +Add the csresmap script that uses ctbin and ctmodel to generate a
  196 +residual counts cube for a given model.
  197 +
195 198
196 18. caldb 199 18. caldb
197 --------- 200 ---------
pyext/ctmodel.i
@@ -49,6 +49,7 @@ public: @@ -49,6 +49,7 @@ public:
49 void save(void); 49 void save(void);
50 const GObservations& obs(void) const; 50 const GObservations& obs(void) const;
51 const GCTAEventCube& cube(void) const; 51 const GCTAEventCube& cube(void) const;
  52 + void cube(const GCTAEventCube& cube);
52 }; 53 };
53 54
54 55
scripts/csresmap.py
1 #! /usr/bin/env python 1 #! /usr/bin/env python
2 # ========================================================================== 2 # ==========================================================================
3 -# This script generates a residual map. 3 +# Residual map generation script.
4 # 4 #
5 # Copyright (C) 2014 Michael Mayer 5 # Copyright (C) 2014 Michael Mayer
6 # 6 #
@@ -18,18 +18,17 @@ @@ -18,18 +18,17 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
21 -from ctools import *  
22 -from gammalib import * 21 +import ctools
  22 +import gammalib
23 import sys 23 import sys
24 -import csv  
25 -import math  
26 import tempfile 24 import tempfile
  25 +import os
27 26
28 27
29 # ============== # 28 # ============== #
30 # cstsdist class # 29 # cstsdist class #
31 # ============== # 30 # ============== #
32 -class csresmap(GApplication): 31 +class csresmap(gammalib.GApplication):
33 """ 32 """
34 This class implements the creation of a residual map. It derives 33 This class implements the creation of a residual map. It derives
35 from the GammaLib::GApplication class which provides support for parameter 34 from the GammaLib::GApplication class which provides support for parameter
@@ -45,14 +44,17 @@ class csresmap(GApplication): @@ -45,14 +44,17 @@ class csresmap(GApplication):
45 self.version = "0.1.0" 44 self.version = "0.1.0"
46 45
47 # Initialise some members 46 # Initialise some members
48 - self.obs = None  
49 - self.algorithm = "SUB" 47 + self.obs = None
  48 + self.algorithm = "SUB"
  49 + self.resmap = None
50 50
51 # Initialise some members 51 # Initialise some members
52 - if isinstance(argv[0],GObservations): 52 + if isinstance(argv[0],gammalib.GObservations):
53 self.obs = argv[0] 53 self.obs = argv[0]
  54 + argv = argv[1:]
54 else: 55 else:
55 - self.obs = GObservations() 56 + self.obs = gammalib.GObservations()
  57 + self.obs.clear()
56 self.outfile = "" 58 self.outfile = ""
57 59
58 # Make sure that parfile exists 60 # Make sure that parfile exists
@@ -60,9 +62,9 @@ class csresmap(GApplication): @@ -60,9 +62,9 @@ class csresmap(GApplication):
60 62
61 # Initialise application 63 # Initialise application
62 if len(argv) == 0: 64 if len(argv) == 0:
63 - GApplication.__init__(self, self.name, self.version) 65 + gammalib.GApplication.__init__(self, self.name, self.version)
64 elif len(argv) ==1: 66 elif len(argv) ==1:
65 - GApplication.__init__(self, self.name, self.version, argv[1:]) 67 + gammalib.GApplication.__init__(self, self.name, self.version, *argv)
66 else: 68 else:
67 raise TypeError("Invalid number of arguments given.") 69 raise TypeError("Invalid number of arguments given.")
68 70
@@ -93,32 +95,32 @@ class csresmap(GApplication): @@ -93,32 +95,32 @@ class csresmap(GApplication):
93 parfile = self.name+".par" 95 parfile = self.name+".par"
94 96
95 try: 97 try:
96 - pars = GApplicationPars(parfile) 98 + pars = gammalib.GApplicationPars(parfile)
97 except: 99 except:
98 # Signal if parfile was not found 100 # Signal if parfile was not found
99 sys.stdout.write("Parfile "+parfile+" not found. Create default parfile.\n") 101 sys.stdout.write("Parfile "+parfile+" not found. Create default parfile.\n")
100 102
101 # Create default parfile 103 # Create default parfile
102 - pars = GApplicationPars()  
103 - pars.append(GApplicationPar("infile","f","h","obs.xml","","","Observation definition"))  
104 - pars.append(GApplicationPar("srcmdl","f","h","crab.xml","","","model file name"))  
105 - pars.append(GApplicationPar("outfile","f","h","resmap.fits","","","Output file name"))  
106 - pars.append(GApplicationPar("binfile","f","h","binned.fits","","","Output binned file name"))  
107 - pars.append(GApplicationPar("modfile","f","h","model.fits","","","Output model file name"))  
108 - pars.append(GApplicationPar("caldb","s","a","$GAMMALIB/share/caldb/cta","","","Calibration database"))  
109 - pars.append(GApplicationPar("irf","s","a","cta_dummy_irf","","","Instrument response function"))  
110 - pars.append(GApplicationPar("emin","r","h","0.1","0.0","","Lower energy limit (TeV)"))  
111 - pars.append(GApplicationPar("emax","r","h","100.0","0.0","","Upper energy limit (TeV)"))  
112 - pars.append(GApplicationPar("enumbins","i","h","20","","","Number of energy bins"))  
113 - pars.append(GApplicationPar("ebinalg","s","h","LOG","LIN|LOG|FILE","","Binning algorithm"))  
114 - pars.append(GApplicationPar("coordsys","s","a","CEL","CEL|GAL","","Coordinate System"))  
115 - pars.append(GApplicationPar("proj","s","a","TAN","AIT|AZP|CAR|MER|STG|TAN","","Projection method e.g. AIT|AZP|CAR|MER|STG|TAN"))  
116 - pars.append(GApplicationPar("xref","r","a","83.6331","","","First coordinate of image center in degrees (RA or galactic l)"))  
117 - pars.append(GApplicationPar("yref","r","a","22.01","","","Second coordinate of image center in degrees (DEC or galactic b)"))  
118 - pars.append(GApplicationPar("nxpix","i","h","200","","","Size of the X axis in pixels"))  
119 - pars.append(GApplicationPar("nypix","i","h","200","","","Size of the Y axis in pixels"))  
120 - pars.append(GApplicationPar("binsz","r","h","0.05","","","Pixel size (deg/pixel)"))  
121 - pars.append(GApplicationPar("algorithm","s","h","SUBDIV","SUB|SUBDIV|SUBDIVSQRT","","Residualmap algorithm")) 104 + pars = gammalib.GApplicationPars()
  105 + pars.append(gammalib.GApplicationPar("infile","f","a","obs.xml","","","Observation definition"))
  106 + pars.append(gammalib.GApplicationPar("srcmdl","f","a","crab.xml","","","model file name"))
  107 + pars.append(gammalib.GApplicationPar("outfile","f","a","resmap.fits","","","Output file name"))
  108 + pars.append(gammalib.GApplicationPar("binfile","f","h","binned.fits","","","Output binned file name"))
  109 + pars.append(gammalib.GApplicationPar("modfile","f","h","model.fits","","","Output model file name"))
  110 + pars.append(gammalib.GApplicationPar("caldb","s","a","$GAMMALIB/share/caldb/cta","","","Calibration database"))
  111 + pars.append(gammalib.GApplicationPar("irf","s","a","cta_dummy_irf","","","Instrument response function"))
  112 + pars.append(gammalib.GApplicationPar("emin","r","h","0.1","0.0","","Lower energy limit (TeV)"))
  113 + pars.append(gammalib.GApplicationPar("emax","r","h","100.0","0.0","","Upper energy limit (TeV)"))
  114 + pars.append(gammalib.GApplicationPar("enumbins","i","h","20","","","Number of energy bins"))
  115 + pars.append(gammalib.GApplicationPar("ebinalg","s","h","LOG","LIN|LOG|FILE","","Binning algorithm"))
  116 + pars.append(gammalib.GApplicationPar("coordsys","s","a","CEL","CEL|GAL","","Coordinate System"))
  117 + pars.append(gammalib.GApplicationPar("proj","s","a","TAN","AIT|AZP|CAR|MER|STG|TAN","","Projection method e.g. AIT|AZP|CAR|MER|STG|TAN"))
  118 + pars.append(gammalib.GApplicationPar("xref","r","a","83.6331","","","First coordinate of image center in degrees (RA or galactic l)"))
  119 + pars.append(gammalib.GApplicationPar("yref","r","a","22.01","","","Second coordinate of image center in degrees (DEC or galactic b)"))
  120 + pars.append(gammalib.GApplicationPar("nxpix","i","h","200","","","Size of the X axis in pixels"))
  121 + pars.append(gammalib.GApplicationPar("nypix","i","h","200","","","Size of the Y axis in pixels"))
  122 + pars.append(gammalib.GApplicationPar("binsz","r","h","0.05","","","Pixel size (deg/pixel)"))
  123 + pars.append(gammalib.GApplicationPar("algorithm","s","h","SUBDIV","SUB|SUBDIV|SUBDIVSQRT","","Residualmap algorithm"))
122 pars.append_standard() 124 pars.append_standard()
123 pars.save(parfile) 125 pars.save(parfile)
124 126
@@ -133,9 +135,27 @@ class csresmap(GApplication): @@ -133,9 +135,27 @@ class csresmap(GApplication):
133 135
134 # Set observation if not done before 136 # Set observation if not done before
135 if self.obs.size() == 0: 137 if self.obs.size() == 0:
136 - self.obs = GObservations(self["infile"].filename)  
137 - self.m_irf = self["irf"].string()  
138 - self.m_caldb = self["caldb"].string() 138 +
  139 + obsfile = self["infile"].filename()
  140 + try:
  141 +
  142 + self.obs = gammalib.GObservations(obsfile)
  143 + except:
  144 + self.obs.clear()
  145 + observation = gammalib.GCTAObservation()
  146 + observation.load(obsfile)
  147 +
  148 + self.m_irf = self["irf"].string()
  149 + self.m_caldb = self["caldb"].string()
  150 +
  151 + caldb = gammalib.GCaldb()
  152 + if os.path.isdir(self.m_caldb):
  153 + caldb.rootdir(self.m_caldb)
  154 + else:
  155 + caldb.open("cta",self. m_caldb)
  156 +
  157 + observation.response(self.m_irf, caldb);
  158 + self.obs.append(observation)
139 159
140 # Check for models in the container 160 # Check for models in the container
141 # read models from file if there were none 161 # read models from file if there were none
@@ -185,6 +205,9 @@ class csresmap(GApplication): @@ -185,6 +205,9 @@ class csresmap(GApplication):
185 """ 205 """
186 # Run the script 206 # Run the script
187 self.run() 207 self.run()
  208 +
  209 + # Save residual map
  210 + self.resmap.save(self.m_outfile, self.m_clobber)
188 211
189 # Return 212 # Return
190 return 213 return
@@ -218,7 +241,8 @@ class csresmap(GApplication): @@ -218,7 +241,8 @@ class csresmap(GApplication):
218 self.log.header1("Generate binned map") 241 self.log.header1("Generate binned map")
219 242
220 # Create countsmap 243 # Create countsmap
221 - bin = ctbin(self.obs) 244 + bin = ctools.ctbin(self.obs)
  245 + bin["debug"].boolean(True)
222 bin["nxpix"].integer(self.m_nxpix) 246 bin["nxpix"].integer(self.m_nxpix)
223 bin["nypix"].integer(self.m_nypix) 247 bin["nypix"].integer(self.m_nypix)
224 bin["proj"].string(self.m_proj) 248 bin["proj"].string(self.m_proj)
@@ -231,75 +255,59 @@ class csresmap(GApplication): @@ -231,75 +255,59 @@ class csresmap(GApplication):
231 bin["emax"].real(self.m_emax) 255 bin["emax"].real(self.m_emax)
232 bin["binsz"].real(self.m_binsz) 256 bin["binsz"].real(self.m_binsz)
233 bin["clobber"].boolean(self.m_clobber) 257 bin["clobber"].boolean(self.m_clobber)
234 - if not self.m_binfile == "NONE":  
235 - bin["outfile"].filename(self.m_binfile)  
236 - else:  
237 - os,filename = tempfile.mkstemp()  
238 - bin["outfile"].filename(filename)  
239 - bin.execute() 258 + bin.run()
  259 +
  260 + # Store counts map as residual map. Note that we need a
  261 + # special construct here to avoid memory leaks. This seems
  262 + # to be a SWIG feature as SWIG creates a new object when
  263 + # calling bin.cube()
  264 + #residualmap = bin.cube().map()
  265 + counts_cube = bin.cube()
  266 + self.resmap = counts_cube.map().copy()
  267 + self.resmap.stack_maps()
240 268
241 # Write header 269 # Write header
242 if self.logTerse(): 270 if self.logTerse():
243 self.log("\n") 271 self.log("\n")
244 self.log.header1("Generate model map") 272 self.log.header1("Generate model map")
245 273
246 - # create model map  
247 - model = ctmodel(self.obs)  
248 - model["infile"].filename(bin["outfile"].filename()) 274 + # Create model map
  275 + model = ctools.ctmodel(self.obs)
  276 + model["debug"].boolean(True)
  277 + model.cube(bin.cube())
249 model["clobber"].boolean(self.m_clobber) 278 model["clobber"].boolean(self.m_clobber)
250 - if not self.m_modfile == "NONE":  
251 - model["outfile"].filename(self.m_modfile)  
252 - else:  
253 - os,filename = tempfile.mkstemp()  
254 - model["outfile"].filename(filename)  
255 - model.execute() 279 + model.run()
256 280
257 # Get model map into GSkymap object 281 # Get model map into GSkymap object
258 - modelmap = GSkymap(model["outfile"].filename()) 282 + modelmap = model.cube().map()
259 modelmap.stack_maps() 283 modelmap.stack_maps()
260 -  
261 - # Initialise resiudalmap from countmap  
262 - residualmap = GSkymap(bin["outfile"].filename())  
263 - residualmap.stack_maps()  
264 284
265 -  
266 -  
267 -  
268 - # continue calculations depending on given algorithm 285 + # Continue calculations depending on given algorithm
269 if self.m_algorithm == "SUB": 286 if self.m_algorithm == "SUB":
270 287
271 # Subtract maps 288 # Subtract maps
272 - residualmap -= modelmap 289 + self.resmap -= modelmap
273 290
274 elif self.m_algorithm == "SUBDIV": 291 elif self.m_algorithm == "SUBDIV":
275 292
276 # Subtract and divide by model map 293 # Subtract and divide by model map
277 - residualmap -= modelmap  
278 - residualmap /= modelmap 294 + self.resmap -= modelmap
  295 + self.resmap /= modelmap
279 296
280 elif self.m_algorithm == "SUBDIVSQRT": 297 elif self.m_algorithm == "SUBDIVSQRT":
281 298
282 # subtract and divide by sqrt of model map 299 # subtract and divide by sqrt of model map
283 - residualmap -= modelmap  
284 - residualmap /= modelmap.sqrt() 300 + self.resmap -= modelmap
  301 + self.resmap /= modelmap.sqrt()
285 302
286 else: 303 else:
287 304
288 - # Rais error if algorithm is unkown 305 + # Raise error if algorithm is unkown
289 raise TypeError("Algorithm \""+self.m_algorithm+"\" not known") 306 raise TypeError("Algorithm \""+self.m_algorithm+"\" not known")
290 307
291 - # Save files  
292 - residualmap.save(self.m_outfile,self.m_clobber)  
293 -  
294 - # Remove binned and model files in case they shouldnt be saved  
295 - if self.m_binfile == "NONE":  
296 - os.remove(bin["outfile"].filename())  
297 - if self.m_modfile == "NONE":  
298 - os.remove(model["outfile"].filename())  
299 -  
300 # Return 308 # Return
301 return 309 return
302 - 310 +
303 311
304 # ======================== # 312 # ======================== #
305 # Main routine entry point # 313 # Main routine entry point #
src/ctmodel/ctmodel.cpp
@@ -246,8 +246,10 @@ void ctmodel::run(void) @@ -246,8 +246,10 @@ void ctmodel::run(void)
246 log.header1("Generate model cube"); 246 log.header1("Generate model cube");
247 } 247 }
248 248
249 - // Initialise counts cube  
250 - init_cube(); 249 + // Initialise counts cube if cube has not yet been set
  250 + if (!has_cube()) {
  251 + init_cube();
  252 + }
251 253
252 // Loop over all observations in the container 254 // Loop over all observations in the container
253 for (int i = 0; i < m_obs.size(); ++i) { 255 for (int i = 0; i < m_obs.size(); ++i) {
@@ -320,6 +322,31 @@ void ctmodel::save(void) @@ -320,6 +322,31 @@ void ctmodel::save(void)
320 } 322 }
321 323
322 324
  325 +/***********************************************************************//**
  326 + * @brief Set model cube
  327 + *
  328 + * @param[in] cube Model cube.
  329 + *
  330 + * Set model cube and set all cube bins to zero.
  331 + ***************************************************************************/
  332 +void ctmodel::cube(const GCTAEventCube& cube)
  333 +{
  334 + // Set cube
  335 + m_cube = cube;
  336 +
  337 + // Set all cube bins to zero
  338 + for (int i = 0; i < m_cube.size(); ++i) {
  339 + m_cube[i]->counts(0.0);
  340 + }
  341 +
  342 + // Signal that cube has been set
  343 + m_has_cube = true;
  344 +
  345 + // Return
  346 + return;
  347 +}
  348 +
  349 +
323 /*========================================================================== 350 /*==========================================================================
324 = = 351 = =
325 = Private methods = 352 = Private methods =
@@ -362,6 +389,7 @@ void ctmodel::init_members(void) @@ -362,6 +389,7 @@ void ctmodel::init_members(void)
362 m_cube.clear(); 389 m_cube.clear();
363 m_ebounds.clear(); 390 m_ebounds.clear();
364 m_gti.clear(); 391 m_gti.clear();
  392 + m_has_cube = false;
365 393
366 // Return 394 // Return
367 return; 395 return;
@@ -406,6 +434,7 @@ void ctmodel::copy_members(const ctmodel&amp; app) @@ -406,6 +434,7 @@ void ctmodel::copy_members(const ctmodel&amp; app)
406 m_cube = app.m_cube; 434 m_cube = app.m_cube;
407 m_ebounds = app.m_ebounds; 435 m_ebounds = app.m_ebounds;
408 m_gti = app.m_gti; 436 m_gti = app.m_gti;
  437 + m_has_cube = app.m_has_cube;
409 438
410 // Return 439 // Return
411 return; 440 return;
@@ -431,7 +460,9 @@ void ctmodel::free_members(void) @@ -431,7 +460,9 @@ void ctmodel::free_members(void)
431 void ctmodel::get_parameters(void) 460 void ctmodel::get_parameters(void)
432 { 461 {
433 // Read input and optionally output cube filenames 462 // Read input and optionally output cube filenames
434 - m_infile = (*this)["infile"].filename(); 463 + if (!has_cube()) {
  464 + m_infile = (*this)["infile"].filename();
  465 + }
435 if (read_ahead()) { 466 if (read_ahead()) {
436 m_outfile = (*this)["outfile"].filename(); 467 m_outfile = (*this)["outfile"].filename();
437 } 468 }
@@ -482,7 +513,8 @@ void ctmodel::get_parameters(void) @@ -482,7 +513,8 @@ void ctmodel::get_parameters(void)
482 513
483 // If no cube file has been specified then read all parameters that 514 // If no cube file has been specified then read all parameters that
484 // are necessary to create the cube from scratch (see method init_cube) 515 // are necessary to create the cube from scratch (see method init_cube)
485 - if ((m_infile == "NONE") || (gammalib::strip_whitespace(m_infile) == "")) { 516 + if ((!has_cube()) &&
  517 + ((m_infile == "NONE") || (gammalib::strip_whitespace(m_infile) == ""))) {
486 m_ebinalg = (*this)["ebinalg"].string(); 518 m_ebinalg = (*this)["ebinalg"].string();
487 if (m_ebinalg == "FILE") { 519 if (m_ebinalg == "FILE") {
488 m_ebinfile = (*this)["ebinfile"].filename(); 520 m_ebinfile = (*this)["ebinfile"].filename();
@@ -670,6 +702,9 @@ void ctmodel::init_cube(void) @@ -670,6 +702,9 @@ void ctmodel::init_cube(void)
670 702
671 } 703 }
672 704
  705 + // Signal that cube has been set
  706 + m_has_cube = true;
  707 +
673 // Return 708 // Return
674 return; 709 return;
675 } 710 }
@@ -738,7 +773,7 @@ void ctmodel::fill_cube(const GCTAObservation* obs) @@ -738,7 +773,7 @@ void ctmodel::fill_cube(const GCTAObservation* obs)
738 if (logTerse()) { 773 if (logTerse()) {
739 log << gammalib::parformat("Model events in cube"); 774 log << gammalib::parformat("Model events in cube");
740 log << sum << std::endl; 775 log << sum << std::endl;
741 - log << gammalib::parformat("Cube bins outside energy range"); 776 + log << gammalib::parformat("Bins outside energy range");
742 log << num_outside_ebds << std::endl; 777 log << num_outside_ebds << std::endl;
743 } 778 }
744 779
src/ctmodel/ctmodel.hpp
@@ -70,6 +70,7 @@ public: @@ -70,6 +70,7 @@ public:
70 void save(void); 70 void save(void);
71 const GObservations& obs(void) const; 71 const GObservations& obs(void) const;
72 const GCTAEventCube& cube(void) const; 72 const GCTAEventCube& cube(void) const;
  73 + void cube(const GCTAEventCube& cube);
73 74
74 protected: 75 protected:
75 // Protected methods 76 // Protected methods
@@ -80,6 +81,7 @@ protected: @@ -80,6 +81,7 @@ protected:
80 void setup_obs(void); 81 void setup_obs(void);
81 void init_cube(void); 82 void init_cube(void);
82 void fill_cube(const GCTAObservation* obs); 83 void fill_cube(const GCTAObservation* obs);
  84 + bool has_cube(void) const;
83 85
84 // User parameters 86 // User parameters
85 std::string m_infile; //!< Input counts cube 87 std::string m_infile; //!< Input counts cube
@@ -112,13 +114,14 @@ protected: @@ -112,13 +114,14 @@ protected:
112 GCTAEventCube m_cube; //!< Model cube 114 GCTAEventCube m_cube; //!< Model cube
113 GEbounds m_ebounds; //!< Energy boundaries 115 GEbounds m_ebounds; //!< Energy boundaries
114 GGti m_gti; //!< Model cube GTIs 116 GGti m_gti; //!< Model cube GTIs
  117 + bool m_has_cube; //!< Signal if cube has been set or loaded
115 }; 118 };
116 119
117 120
118 /***********************************************************************//** 121 /***********************************************************************//**
119 * @brief Return observation container 122 * @brief Return observation container
120 * 123 *
121 - * @return Reference to observation container 124 + * @return Reference to observation container.
122 ***************************************************************************/ 125 ***************************************************************************/
123 inline 126 inline
124 const GObservations& ctmodel::obs(void) const 127 const GObservations& ctmodel::obs(void) const
@@ -130,7 +133,7 @@ const GObservations&amp; ctmodel::obs(void) const @@ -130,7 +133,7 @@ const GObservations&amp; ctmodel::obs(void) const
130 /***********************************************************************//** 133 /***********************************************************************//**
131 * @brief Return model cube 134 * @brief Return model cube
132 * 135 *
133 - * @return Reference to model cube 136 + * @return Reference to model cube.
134 ***************************************************************************/ 137 ***************************************************************************/
135 inline 138 inline
136 const GCTAEventCube& ctmodel::cube(void) const 139 const GCTAEventCube& ctmodel::cube(void) const
@@ -138,4 +141,16 @@ const GCTAEventCube&amp; ctmodel::cube(void) const @@ -138,4 +141,16 @@ const GCTAEventCube&amp; ctmodel::cube(void) const
138 return m_cube; 141 return m_cube;
139 } 142 }
140 143
  144 +
  145 +/***********************************************************************//**
  146 + * @brief Signal if cube has been set or loaded
  147 + *
  148 + * @return True if cube has been set or loaded.
  149 + ***************************************************************************/
  150 +inline
  151 +bool ctmodel::has_cube(void) const
  152 +{
  153 + return m_has_cube;
  154 +}
  155 +
141 #endif /* CTMODEL_HPP */ 156 #endif /* CTMODEL_HPP */
test/test_cscripts.sh.in
@@ -131,3 +131,32 @@ else @@ -131,3 +131,32 @@ else
131 exit 1 131 exit 1
132 fi 132 fi
133 $ECHO " ok" 133 $ECHO " ok"
  134 +
  135 +#
  136 +# Test csresmap
  137 +# =============
  138 +$ECHO @ECHO_N@ "Test csresmap: "
  139 +chmod +x @abs_top_srcdir@/scripts/csresmap.py
  140 +@abs_top_srcdir@/scripts/csresmap.py \
  141 + infile="data/crab_events.fits" \
  142 + outfile="resmap.fits" \
  143 + srcmdl="data/crab.xml" \
  144 + caldb="irf" \
  145 + irf="cta_dummy_irf" \
  146 + nxpix=50 \
  147 + nypix=50 \
  148 + binsz=0.02 \
  149 + coordsys="CEL" \
  150 + xref=83.63 \
  151 + yref=22.01 \
  152 + proj="CAR" \
  153 + binsz=0.05 > csresmap.log
  154 +$ECHO @ECHO_N@ "."
  155 +if [ -s "resmap.fits" ]
  156 +then
  157 + $ECHO @ECHO_N@ "."
  158 +else
  159 + $ECHO " resmap.fits file is not valid"
  160 + exit 1
  161 +fi
  162 +$ECHO " ok"