Commit 371a3061b8ef88c6cc2707e3911197ce8cb971df

Authored by Michael Mayer
1 parent 2b3d392a

Added option to store errors in cttsmap

cscripts/cstsmapmerge.py
@@ -46,7 +46,7 @@ class cstsmapmerge(ctools.cscript): @@ -46,7 +46,7 @@ class cstsmapmerge(ctools.cscript):
46 self._files = None 46 self._files = None
47 self._in_filename = '' 47 self._in_filename = ''
48 self._tsmap = gammalib.GSkyMap() # Empty sky map 48 self._tsmap = gammalib.GSkyMap() # Empty sky map
49 - self._statusmap = gammalib.GSkyMap() # Empty sky map 49 + self._progressmap = gammalib.GSkyMap() # Empty sky map
50 self._maps = [] 50 self._maps = []
51 self._mapnames = [] 51 self._mapnames = []
52 self._merged_files = [] 52 self._merged_files = []
@@ -136,11 +136,11 @@ class cstsmapmerge(ctools.cscript): @@ -136,11 +136,11 @@ class cstsmapmerge(ctools.cscript):
136 # Open FITS file 136 # Open FITS file
137 fits = gammalib.GFits(fitsfile) 137 fits = gammalib.GFits(fitsfile)
138 138
139 - # Read TS and status maps 139 + # Read TS and progress maps
140 self._tsmap = gammalib.GSkyMap() 140 self._tsmap = gammalib.GSkyMap()
141 self._tsmap.read(fits[0]) 141 self._tsmap.read(fits[0])
142 - self._statusmap = gammalib.GSkyMap()  
143 - self._statusmap.read(fits["STATUS MAP"]) 142 + self._progressmap = gammalib.GSkyMap()
  143 + self._progressmap.read(fits["PROGRESS MAP"])
144 144
145 # Get other maps 145 # Get other maps
146 self._maps = [] 146 self._maps = []
@@ -149,8 +149,8 @@ class cstsmapmerge(ctools.cscript): @@ -149,8 +149,8 @@ class cstsmapmerge(ctools.cscript):
149 # Loop over extensions 149 # Loop over extensions
150 for hdu in fits: 150 for hdu in fits:
151 151
152 - # Leave out primary and status extension  
153 - if hdu.extname() != "IMAGE" and hdu.extname() != "STATUS MAP": 152 + # Leave out primary and progress extension
  153 + if hdu.extname() != "IMAGE" and hdu.extname() != "PROGRESS MAP":
154 154
155 # Add present maps 155 # Add present maps
156 skymap = gammalib.GSkyMap() 156 skymap = gammalib.GSkyMap()
@@ -174,11 +174,11 @@ class cstsmapmerge(ctools.cscript): @@ -174,11 +174,11 @@ class cstsmapmerge(ctools.cscript):
174 # Open FITS file 174 # Open FITS file
175 fits = gammalib.GFits(fitsfile) 175 fits = gammalib.GFits(fitsfile)
176 176
177 - # Read TS and status maps 177 + # Read TS and progress maps
178 add_tsmap = gammalib.GSkyMap() 178 add_tsmap = gammalib.GSkyMap()
179 add_tsmap.read(fits[0]) 179 add_tsmap.read(fits[0])
180 - add_statusmap = gammalib.GSkyMap()  
181 - add_statusmap.read(fits["STATUS MAP"]) 180 + add_progressmap = gammalib.GSkyMap()
  181 + add_progressmap.read(fits["PROGRESS MAP"])
182 182
183 # Get other maps 183 # Get other maps
184 add_maps = [] 184 add_maps = []
@@ -186,8 +186,8 @@ class cstsmapmerge(ctools.cscript): @@ -186,8 +186,8 @@ class cstsmapmerge(ctools.cscript):
186 # Loop over extensions 186 # Loop over extensions
187 for hdu in fits: 187 for hdu in fits:
188 188
189 - # Leave out primary and status extension  
190 - if hdu.extname() != "IMAGE" and hdu.extname() != "STATUS MAP": 189 + # Leave out primary and progress extension
  190 + if hdu.extname() != "IMAGE" and hdu.extname() != "PROGRESS MAP":
191 191
192 # Add present maps 192 # Add present maps
193 skymap = gammalib.GSkyMap() 193 skymap = gammalib.GSkyMap()
@@ -208,10 +208,10 @@ class cstsmapmerge(ctools.cscript): @@ -208,10 +208,10 @@ class cstsmapmerge(ctools.cscript):
208 for i in range(self._tsmap.npix()): 208 for i in range(self._tsmap.npix()):
209 209
210 # Consider only bins that have been computed 210 # Consider only bins that have been computed
211 - if add_statusmap[i] > 0.5: 211 + if add_progressmap[i] > 0.5:
212 212
213 # Raise exception if this bin has already been computed 213 # Raise exception if this bin has already been computed
214 - if self._statusmap[i] > 0.5 and not self._overwrite: 214 + if self._progressmap[i] > 0.5 and not self._overwrite:
215 msg = "Attempt to merge bin which apparently has "+\ 215 msg = "Attempt to merge bin which apparently has "+\
216 "already been merged. File \""+fitsfile+"\" "+\ 216 "already been merged. File \""+fitsfile+"\" "+\
217 "contains already merged bins. Set hidden "+\ 217 "contains already merged bins. Set hidden "+\
@@ -221,8 +221,8 @@ class cstsmapmerge(ctools.cscript): @@ -221,8 +221,8 @@ class cstsmapmerge(ctools.cscript):
221 # Copy TS values 221 # Copy TS values
222 self._tsmap[i] = add_tsmap[i] 222 self._tsmap[i] = add_tsmap[i]
223 223
224 - # Copy status  
225 - self._statusmap[i] = add_statusmap[i] 224 + # Copy progress
  225 + self._progressmap[i] = add_progressmap[i]
226 226
227 # Loop over maps and copy entries 227 # Loop over maps and copy entries
228 for j in range(len(self._maps)): 228 for j in range(len(self._maps)):
@@ -241,12 +241,12 @@ class cstsmapmerge(ctools.cscript): @@ -241,12 +241,12 @@ class cstsmapmerge(ctools.cscript):
241 Returns: 241 Returns:
242 Number of pixels for which TS has been computed. 242 Number of pixels for which TS has been computed.
243 """ 243 """
244 - # Get status map for this file  
245 - status = gammalib.GSkyMap(fitsfile+"[STATUS MAP]") 244 + # Get progress map for this file
  245 + progress = gammalib.GSkyMap(fitsfile+"[PROGRESS MAP]")
246 246
247 # Count number of pixels with TS status set 247 # Count number of pixels with TS status set
248 count = 0 248 count = 0
249 - for pix in status: 249 + for pix in progress:
250 if pix > 0.5: 250 if pix > 0.5:
251 count += 1 251 count += 1
252 252
@@ -275,7 +275,7 @@ class cstsmapmerge(ctools.cscript): @@ -275,7 +275,7 @@ class cstsmapmerge(ctools.cscript):
275 file0 = "" 275 file0 = ""
276 self._merged_files = [] 276 self._merged_files = []
277 277
278 - # Test files for the entry status map. Use the first one to appear 278 + # Test files for the entry progress map. Use the first one to appear
279 # useful 279 # useful
280 for fitsfile in self._files: 280 for fitsfile in self._files:
281 281
@@ -290,8 +290,8 @@ class cstsmapmerge(ctools.cscript): @@ -290,8 +290,8 @@ class cstsmapmerge(ctools.cscript):
290 # Open FITS file 290 # Open FITS file
291 fits = gammalib.GFits(fitsfile) 291 fits = gammalib.GFits(fitsfile)
292 292
293 - # If file contains a status map then use it  
294 - if fits.contains("STATUS MAP"): 293 + # If file contains a progress map then use it
  294 + if fits.contains("PROGRESS MAP"):
295 fits.close() 295 fits.close()
296 file0 = fitsfile 296 file0 = fitsfile
297 if self._logTerse(): 297 if self._logTerse():
@@ -308,14 +308,14 @@ class cstsmapmerge(ctools.cscript): @@ -308,14 +308,14 @@ class cstsmapmerge(ctools.cscript):
308 if self._logExplicit(): 308 if self._logExplicit():
309 self._log(gammalib.parformat("Skip file")) 309 self._log(gammalib.parformat("Skip file"))
310 self._log(fitsfile) 310 self._log(fitsfile)
311 - self._log(" (no \"STATUS MAP\" extension)\n") 311 + self._log(" (no \"PROGRESS MAP\" extension)\n")
312 continue 312 continue
313 313
314 # Signal if no suitable file was found 314 # Signal if no suitable file was found
315 if file0 == "": 315 if file0 == "":
316 if self._logTerse(): 316 if self._logTerse():
317 self._log("None of the provided files seems to be a sliced " 317 self._log("None of the provided files seems to be a sliced "
318 - "TS map file (none has a \"STATUS MAP\" " 318 + "TS map file (none has a \"PROGRESS MAP\" "
319 "extension).\n") 319 "extension).\n")
320 320
321 # ... otherwise merge files 321 # ... otherwise merge files
@@ -347,13 +347,13 @@ class cstsmapmerge(ctools.cscript): @@ -347,13 +347,13 @@ class cstsmapmerge(ctools.cscript):
347 # Open FITS file 347 # Open FITS file
348 fits = gammalib.GFits(fitsfile) 348 fits = gammalib.GFits(fitsfile)
349 349
350 - # Skip if file does not contain status map  
351 - if not fits.contains("STATUS MAP"): 350 + # Skip if file does not contain progress map
  351 + if not fits.contains("PROGRESS MAP"):
352 fits.close() 352 fits.close()
353 if self._logExplicit(): 353 if self._logExplicit():
354 self._log(gammalib.parformat("Skip file")) 354 self._log(gammalib.parformat("Skip file"))
355 self._log(fitsfile) 355 self._log(fitsfile)
356 - self._log(" (no \"STATUS MAP\" extension)\n") 356 + self._log(" (no \"PROGRESS MAP\" extension)\n")
357 continue 357 continue
358 358
359 # Close FITS file 359 # Close FITS file
@@ -410,15 +410,15 @@ class cstsmapmerge(ctools.cscript): @@ -410,15 +410,15 @@ class cstsmapmerge(ctools.cscript):
410 410
411 # Check if map is fully done 411 # Check if map is fully done
412 done = True 412 done = True
413 - for pix in self._statusmap: 413 + for pix in self._progressmap:
414 if pix < 0.5: 414 if pix < 0.5:
415 done = False 415 done = False
416 break 416 break
417 417
418 - # Write status map if we are not done yet 418 + # Write progress map if we are not done yet
419 if not done: 419 if not done:
420 - self._statusmap.write(fits)  
421 - fits[fits.size()-1].extname("STATUS MAP") 420 + self._progressmap.write(fits)
  421 + fits[fits.size()-1].extname("PROGRESS MAP")
422 422
423 # Save FITS file 423 # Save FITS file
424 fits.saveto(outmap, self._clobber()) 424 fits.saveto(outmap, self._clobber())
cscripts/cstsmapsplit.par
@@ -27,6 +27,7 @@ bkgcube, f, a, NONE,,, &quot;Input background cube file (only needed for stacke @@ -27,6 +27,7 @@ bkgcube, f, a, NONE,,, &quot;Input background cube file (only needed for stacke
27 caldb, s, a, prod2,,, "Calibration database" 27 caldb, s, a, prod2,,, "Calibration database"
28 irf, s, a, South_0.5h,,, "Instrument response function" 28 irf, s, a, South_0.5h,,, "Instrument response function"
29 edisp, b, h, no,,, "Apply energy dispersion?" 29 edisp, b, h, no,,, "Apply energy dispersion?"
  30 +errors, b, h, no,,, "Compute/store parameter errors?"
30 outmap, f, a, tsmap.fits,,, "Output Test Statistic map file" 31 outmap, f, a, tsmap.fits,,, "Output Test Statistic map file"
31 bins_per_job, i, a, 5,,, "Number of TS map bins per task" 32 bins_per_job, i, a, 5,,, "Number of TS map bins per task"
32 compute_null, b, a, yes,,,"Compute null hypothesis first?" 33 compute_null, b, a, yes,,,"Compute null hypothesis first?"
src/cttsmap/cttsmap.cpp
@@ -315,6 +315,14 @@ void cttsmap::run(void) @@ -315,6 +315,14 @@ void cttsmap::run(void)
315 // Optimize observation container 315 // Optimize observation container
316 m_obs.optimize(*opt); 316 m_obs.optimize(*opt);
317 317
  318 + // Compute errors if necessary
  319 + if (m_errors) {
  320 + m_obs.errors(*opt);
  321 + }
  322 +
  323 + // Get status of optimization
  324 + int status = opt->status();
  325 +
318 // Retrieve the Likelihood value 326 // Retrieve the Likelihood value
319 double logL1 = -(opt->value()); 327 double logL1 = -(opt->value());
320 328
@@ -326,6 +334,7 @@ void cttsmap::run(void) @@ -326,6 +334,7 @@ void cttsmap::run(void)
326 log << " TS value ....: "; 334 log << " TS value ....: ";
327 log << ts << std::endl; 335 log << ts << std::endl;
328 } 336 }
  337 +
329 else if (logTerse()) { 338 else if (logTerse()) {
330 log << "TS for bin number "; 339 log << "TS for bin number ";
331 log << i; 340 log << i;
@@ -345,12 +354,26 @@ void cttsmap::run(void) @@ -345,12 +354,26 @@ void cttsmap::run(void)
345 // Extract fitted test source parameters 354 // Extract fitted test source parameters
346 if (m_testsource != NULL) { 355 if (m_testsource != NULL) {
347 for (int j = 0; j < m_mapnames.size(); ++j) { 356 for (int j = 0; j < m_mapnames.size(); ++j) {
348 - m_maps[j](i) = (*testsource)[m_mapnames[j]].value(); 357 +
  358 + // Set parameter value and error maps
  359 + if (m_mapnames[j].substr(0,2) == "e_") {
  360 +
  361 + // Get Parameter name by removing the error prefix
  362 + std::string parname = m_mapnames[j].substr(2, m_mapnames[j].size());
  363 + m_maps[j](i) = (*testsource)[parname].error();
  364 +
  365 + }
  366 + else {
  367 + m_maps[j](i) = (*testsource)[m_mapnames[j]].value();
  368 + }
349 } 369 }
350 } 370 }
351 371
352 - // Set status of bin to true  
353 - m_statusmap(i) = 1.0; 372 + // Set Fit status of the bin
  373 + m_statusmap(i) = status;
  374 +
  375 + // Add bin to progress map
  376 + m_progressmap(i) = 1.0;
354 377
355 // Remove model from container 378 // Remove model from container
356 models.remove(m_srcname); 379 models.remove(m_srcname);
@@ -417,10 +440,14 @@ void cttsmap::save(void) @@ -417,10 +440,14 @@ void cttsmap::save(void)
417 fits[i+1]->extname(m_mapnames[i]); 440 fits[i+1]->extname(m_mapnames[i]);
418 } 441 }
419 442
  443 + // Write Fit status map
  444 + m_statusmap.write(fits);
  445 + fits[fits.size()-1]->extname("FITSTATUS");
  446 +
420 // Add computation log if not all bins are computed 447 // Add computation log if not all bins are computed
421 if (m_binmin != -1 || m_binmax != -1) { 448 if (m_binmin != -1 || m_binmax != -1) {
422 - m_statusmap.write(fits);  
423 - fits[m_mapnames.size()+1]->extname("STATUS MAP"); 449 + m_progressmap.write(fits);
  450 + fits[m_mapnames.size()+1]->extname("PROGRESS MAP");
424 } 451 }
425 452
426 // Save FITS file 453 // Save FITS file
@@ -482,6 +509,7 @@ void cttsmap::init_members(void) @@ -482,6 +509,7 @@ void cttsmap::init_members(void)
482 m_outmap.clear(); 509 m_outmap.clear();
483 m_apply_edisp = false; 510 m_apply_edisp = false;
484 m_publish = false; 511 m_publish = false;
  512 + m_errors = false;
485 513
486 // Initialise protected members 514 // Initialise protected members
487 m_obs.clear(); 515 m_obs.clear();
@@ -490,6 +518,7 @@ void cttsmap::init_members(void) @@ -490,6 +518,7 @@ void cttsmap::init_members(void)
490 m_logL0 = 0.0; 518 m_logL0 = 0.0;
491 m_tsmap.clear(); 519 m_tsmap.clear();
492 m_statusmap.clear(); 520 m_statusmap.clear();
  521 + m_progressmap.clear();
493 m_mapnames.clear(); 522 m_mapnames.clear();
494 m_maps.clear(); 523 m_maps.clear();
495 m_testsource = NULL; 524 m_testsource = NULL;
@@ -511,16 +540,18 @@ void cttsmap::copy_members(const cttsmap&amp; app) @@ -511,16 +540,18 @@ void cttsmap::copy_members(const cttsmap&amp; app)
511 m_outmap = app.m_outmap; 540 m_outmap = app.m_outmap;
512 m_apply_edisp = app.m_apply_edisp; 541 m_apply_edisp = app.m_apply_edisp;
513 m_publish = app.m_publish; 542 m_publish = app.m_publish;
  543 + m_errors = app.m_errors;
514 544
515 // Copy protected members 545 // Copy protected members
516 - m_binmin = app.m_binmin;  
517 - m_binmax = app.m_binmax;  
518 - m_logL0 = app.m_logL0;  
519 - m_obs = app.m_obs;  
520 - m_tsmap = app.m_tsmap;  
521 - m_mapnames = app.m_mapnames;  
522 - m_maps = app.m_maps;  
523 - m_statusmap = app.m_statusmap; 546 + m_binmin = app.m_binmin;
  547 + m_binmax = app.m_binmax;
  548 + m_logL0 = app.m_logL0;
  549 + m_obs = app.m_obs;
  550 + m_tsmap = app.m_tsmap;
  551 + m_mapnames = app.m_mapnames;
  552 + m_maps = app.m_maps;
  553 + m_statusmap = app.m_statusmap;
  554 + m_progressmap = app.m_progressmap;
524 555
525 // Clone protected members 556 // Clone protected members
526 m_testsource = (app.m_testsource != NULL) ? app.m_testsource->clone() : NULL; 557 m_testsource = (app.m_testsource != NULL) ? app.m_testsource->clone() : NULL;
@@ -612,6 +643,9 @@ void cttsmap::get_parameters(void) @@ -612,6 +643,9 @@ void cttsmap::get_parameters(void)
612 // Create sky map based on task parameters 643 // Create sky map based on task parameters
613 GSkyMap map = create_map(m_obs); 644 GSkyMap map = create_map(m_obs);
614 645
  646 + // Check if errors should be computed
  647 + m_errors = (*this)["errors"].boolean();
  648 +
615 // Initialise maps from user parameters 649 // Initialise maps from user parameters
616 init_maps(map); 650 init_maps(map);
617 651
@@ -650,9 +684,11 @@ void cttsmap::init_maps(const GSkyMap&amp; map) @@ -650,9 +684,11 @@ void cttsmap::init_maps(const GSkyMap&amp; map)
650 684
651 // Initialise map information 685 // Initialise map information
652 m_statusmap.clear(); 686 m_statusmap.clear();
  687 + m_progressmap.clear();
653 688
654 - // Create status map  
655 - m_statusmap = GSkyMap(map); 689 + // Create status map and progress map
  690 + m_statusmap = GSkyMap(map);
  691 + m_progressmap = GSkyMap(map);
656 692
657 // Initialise maps of free parameters 693 // Initialise maps of free parameters
658 if (m_testsource != NULL) { 694 if (m_testsource != NULL) {
@@ -671,6 +707,16 @@ void cttsmap::init_maps(const GSkyMap&amp; map) @@ -671,6 +707,16 @@ void cttsmap::init_maps(const GSkyMap&amp; map)
671 707
672 // Store parameter name 708 // Store parameter name
673 m_mapnames.push_back((*m_testsource)[i].name()); 709 m_mapnames.push_back((*m_testsource)[i].name());
  710 +
  711 + // Add parameter errors if requested
  712 + if (m_errors) {
  713 +
  714 + // Add sky map for fit error of the free parameter
  715 + m_maps.push_back(map);
  716 +
  717 + // Store name of parameter error
  718 + m_mapnames.push_back("e_" + (*m_testsource)[i].name());
  719 + }
674 720
675 } // endfor: looped over all model parameters 721 } // endfor: looped over all model parameters
676 722
src/cttsmap/cttsmap.hpp
@@ -89,6 +89,7 @@ protected: @@ -89,6 +89,7 @@ protected:
89 GFilename m_outmap; //!< Output TS map file name 89 GFilename m_outmap; //!< Output TS map file name
90 bool m_apply_edisp; //!< Apply energy dispersion? 90 bool m_apply_edisp; //!< Apply energy dispersion?
91 bool m_publish; //!< Publish TS map? 91 bool m_publish; //!< Publish TS map?
  92 + bool m_errors; //!< Compute and store parameter errors?
92 93
93 // Parameters to control speed and job splitting 94 // Parameters to control speed and job splitting
94 int m_binmin; //!< Map bin number from which computation should start 95 int m_binmin; //!< Map bin number from which computation should start
@@ -98,7 +99,8 @@ protected: @@ -98,7 +99,8 @@ protected:
98 // Protected members 99 // Protected members
99 GObservations m_obs; //!< Observation container 100 GObservations m_obs; //!< Observation container
100 GSkyMap m_tsmap; //!< TS map 101 GSkyMap m_tsmap; //!< TS map
101 - GSkyMap m_statusmap; //!< Map of computed bins 102 + GSkyMap m_statusmap; //!< Map of optimizer fit status
  103 + GSkyMap m_progressmap; //!< Map of computed bins
102 std::vector<std::string> m_mapnames; //!< Names of free parameters 104 std::vector<std::string> m_mapnames; //!< Names of free parameters
103 std::vector<GSkyMap> m_maps; //!< Sky maps for each free parameter 105 std::vector<GSkyMap> m_maps; //!< Sky maps for each free parameter
104 GModel* m_testsource; //!< Pointer to test source for TS computation 106 GModel* m_testsource; //!< Pointer to test source for TS computation
src/cttsmap/cttsmap.par
@@ -27,6 +27,7 @@ bkgcube, f, a, &quot;NONE&quot;,,, &quot;Input background cube file (only needed for stacked @@ -27,6 +27,7 @@ bkgcube, f, a, &quot;NONE&quot;,,, &quot;Input background cube file (only needed for stacked
27 caldb, s, a, "prod2",,, "Calibration database" 27 caldb, s, a, "prod2",,, "Calibration database"
28 irf, s, a, "South_0.5h",,, "Instrument response function" 28 irf, s, a, "South_0.5h",,, "Instrument response function"
29 edisp, b, h, no,,, "Apply energy dispersion?" 29 edisp, b, h, no,,, "Apply energy dispersion?"
  30 +errors, b, h, no,,, "Compute/store parameter errors?"
30 outmap, f, a, "tsmap.fits",,, "Output Test Statistic map file" 31 outmap, f, a, "tsmap.fits",,, "Output Test Statistic map file"
31 32
32 # 33 #
test/data/tsmap_0.fits
No preview for this file type
test/data/tsmap_1.fits
No preview for this file type
test/test_cttsmap.py
@@ -96,6 +96,20 @@ class Test(test): @@ -96,6 +96,20 @@ class Test(test):
96 # Check if execution failed 96 # Check if execution failed
97 self.test_assert(self._execute(cmd) != 0, 97 self.test_assert(self._execute(cmd) != 0,
98 'Check invalid input file when executed from command line') 98 'Check invalid input file when executed from command line')
  99 +
  100 + # Setup cttsmap command
  101 + cmd = cttsmap+' inobs="'+self._events+'"'+ \
  102 + ' inmodel="'+self._model+'" srcname="Crab"'+ \
  103 + ' caldb="'+self._caldb+'" irf="'+self._irf+'"'+ \
  104 + ' errors=yes'+ \
  105 + ' outmap="cttsmap_cmd1.fits"'+ \
  106 + ' nxpix=5 nypix=5 binsz=0.02'+ \
  107 + ' coordsys="CEL" proj="CAR" xref=83.63 yref=22.01'+ \
  108 + ' logfile="cttsmap_cmd1.log" chatter=1'
  109 +
  110 + # Check if execution was successful
  111 + self.test_assert(self._execute(cmd) == 0,
  112 + 'Check successful execution from command line')
99 113
100 # Return 114 # Return
101 return 115 return