Commit 0b326d4d27cad519dd0769d62ac37db94c890b22

Authored by L. Tibaldo
1 parent 97afb37d

debugging

cscripts/csresspec.par
... ... @@ -32,11 +32,11 @@ outfile, f, a, resspec.fits,,, "Output residual spectrum file"
32 32 # Script parameters
33 33 #==================
34 34 statistic, s, h, DEFAULT,DEFAULT|CSTAT|WSTAT|CHI2,, "Optimization statistic"
35   -components b, h, no,,, "Calculate model for individual components"
  35 +components,b, h, no,,, "Calculate model for individual components"
36 36 ebinalg, s, h, LOG,LIN|LOG|FILE,, "Binning algorithm"
37 37 emin, r, a, 0.1,,, "Lower energy limit (TeV)"
38 38 emax, r, a, 100.0,,, "Upper energy limit (TeV)"
39   -enumbins, i, h, 20,,, "Number of model cube energy bins"
  39 +enumbins, i, a, 20,,, "Number of model cube energy bins"
40 40 ebinfile, f, a, NONE,,, "Name of the file containing the energy bin definition"
41 41 stack, b, a, no,,, "Stack observations"
42 42 coordsys, s, a, CEL,CEL|GAL,, "Coordinate System"
... ... @@ -46,7 +46,7 @@ yref, r, a, 22.01,-90,90, "Second coordinate of image/source region center
46 46 nxpix, i, a, 200,,, "Size of the X axis in pixels"
47 47 nypix, i, a, 200,,, "Size of the Y axis in pixels"
48 48 binsz, r, a, 0.02,,, "Pixel size (deg/pixel)"
49   -mask b, a, no,,, "Mask data to calculate residuals in ROI"
  49 +mask, b, a, no,,, "Mask data to calculate residuals in ROI"
50 50 ra, r, a, 83.63,0,360, "RA for ROI centre (degrees)"
51 51 dec, r, a, 22.01,-90,90, "Dec for ROI centre (degrees)"
52 52 rad, r, a, 3.0,0,180, "Radius of ROI (degrees)"
... ...
cscripts/csresspec.py
... ... @@ -23,6 +23,7 @@ import ctools
23 23 from cscripts import obsutils
24 24 import sys
25 25  
  26 +
26 27 # =============== #
27 28 # csresspec class #
28 29 # =============== #
... ... @@ -108,12 +109,12 @@ class csresspec(ctools.csobservation):
108 109 self['emax'].real()
109 110 self['enumbins'].integer()
110 111 msg = 'User defined energy binning will be used for %s unbinned observations.' % n_unbinned
111   - self._log_value(gammalib.TERSE, msg)
  112 + self._log_string(gammalib.TERSE, msg)
112 113 if n_cta > n_unbinned:
113 114 n_notunbin = n_cta - n_unbinned
114 115 msg = 'The intrinsic binning will be used for the remaining %s CTA observations.' % (
115 116 n_notunbin)
116   - self._log_value(gammalib.TERSE, msg)
  117 + self._log_string(gammalib.TERSE, msg)
117 118  
118 119 # If there is more than one observation, and observations are all
119 120 # unbinned or all onoff query user to know if they wish stacked results
... ... @@ -121,13 +122,13 @@ class csresspec(ctools.csobservation):
121 122 n_unbinned == self.obs().size() or n_onoff == self.obs().size()):
122 123 self._stack = self['stack'].boolean()
123 124 # If we are to stack event lists query parameters for cube creation
124   - if n_unbinned == self.obs().size():
  125 + if self._stack and n_unbinned == self.obs().size():
125 126 self['coordsys'].string()
126 127 self['proj'].string()
127 128 self['xref'].real()
128 129 self['yref'].real()
129   - self['nxpix'].real()
130   - self['nypix'].real()
  130 + self['nxpix'].integer()
  131 + self['nypix'].integer()
131 132 self['binsz'].real()
132 133  
133 134 # If we are not using a precomputed model and no models are available
... ... @@ -144,13 +145,14 @@ class csresspec(ctools.csobservation):
144 145 self['ra'].real()
145 146 self['dec'].real()
146 147 self['rad'].real()
  148 + self['regfile'].filename()
147 149  
148 150 # Unless all observations are On/Off, or we are using precomputed model
149 151 # maps query whether to use energy dispersion
150 152 if n_onoff == n_cta or self._use_maps:
151 153 msg = 'Energy dispersion is applied based on the input data/model ' \
152 154 + 'and not according to the edisp parameter'
153   - self._log_value(gammalib.TERSE, msg)
  155 + self._log_string(gammalib.TERSE, msg)
154 156 else:
155 157 self['edisp'].boolean()
156 158  
... ... @@ -180,13 +182,13 @@ class csresspec(ctools.csobservation):
180 182 # If On/Off use the GCTAOnOffObservation constructor
181 183 if self.obs()[0].classname() == 'GCTAOnOffObservation':
182 184 msg = 'Stacking %s On/Off observations.' % (self.obs().size())
183   - self._log_value(gammalib.TERSE, msg)
  185 + self._log_string(gammalib.TERSE, msg)
184 186 stacked_obs = gammalib.GCTAOnOffObservation(self.obs())
185 187  
186 188 # If event list then bin observations
187 189 elif self.obs()[0].classname() == 'GCTAObservation':
188 190 msg = 'Stacking %s event lists.' % (self.obs().size())
189   - self._log_value(gammalib.TERSE, msg)
  191 + self._log_string(gammalib.TERSE, msg)
190 192 stacked_obs = obsutils.get_stacked_obs(self, self.obs())
191 193  
192 194 # Return
... ... @@ -227,25 +229,43 @@ class csresspec(ctools.csobservation):
227 229 cntcube['emax'] = self['emax'].real()
228 230 cntcube.run()
229 231  
230   - # Retrieve a new oberservation container
  232 + # Retrieve the binned observation container
231 233 binned_obs = cntcube.obs().copy()
232 234  
233   - # Retrieve models
234   - models = obs.models()
  235 + # Compute binned response
  236 + response = obsutils.get_stacked_response(obs, ra, dec,
  237 + binsz=0.02,
  238 + nxpix=npix,
  239 + nypix=npix,
  240 + coordsys='CEL',
  241 + proj='TAN',
  242 + emin=self['emin'].real(),
  243 + emax=self['emax'].real(),
  244 + edisp=self['edisp'].boolean())
  245 +
  246 + if self['edisp'].boolean():
  247 + binned_obs[0].response(response['expcube'], response['psfcube'],
  248 + response['edispcube'], response['bkgcube'])
  249 + else:
  250 + binned_obs[0].response(response['expcube'], response['psfcube'],
  251 + response['bkgcube'])
235 252  
236   - # Set models for new oberservation container
  253 + # Get new models
  254 + models = response['models']
  255 +
  256 + # Set models for observation container
237 257 binned_obs.models(models)
238 258  
239 259 # Check if energy boundaries provided by user extend beyond
240 260 # the content of the event list
241   - if self['emin'].real() > obs[0].emin().TeV:
  261 + if self['emin'].real() > obs[0].events().emin().TeV():
242 262 emin = 'INDEF'
243 263 else:
244   - emin = obs[0].emin().TeV
245   - if self['emax'].real() < obs[0].emax().TeV:
  264 + emin = obs[0].events().emin().TeV()
  265 + if self['emax'].real() < obs[0].events().emax().TeV():
246 266 emax = 'INDEF'
247 267 else:
248   - emax = obs[0].emax().TeV
  268 + emax = obs[0].events().emax().TeV()
249 269  
250 270 # Put ROI and E bound info in dictionary
251 271 info = {'was_list': True, 'roi_ra': ra, 'roi_dec': dec, 'roi_rad': rad,
... ... @@ -254,47 +274,6 @@ class csresspec(ctools.csobservation):
254 274 # Return new oberservation container
255 275 return binned_obs, info
256 276  
257   - def _add_binned_response(self, obs):
258   - """
259   - Add response to binned observation
260   - :param obs: `~gammalib.GObservations' observation container
261   - :return: obs: `~gammalib.GObservations' observation container with response
262   - """
263   -
264   - # use counts cube to extract geometry
265   - cube = obs[0].events()
266   - proj = cube.counts().projection()
267   -
268   - response = obsutils.get_stacked_response(obs,
269   - proj.crval(0),
270   - proj.crval(1),
271   - binsz=max(abs(proj.cdelt(0)),
272   - abs(proj.cdelt(1))),
273   - # always ensures coverage of whole cube
274   - nxpix=cube.nx(),
275   - nypix=cube.ny(),
276   - coordsys=proj.coordsys(),
277   - proj=proj.code(),
278   - emin=cube.emin().TeV(),
279   - emax=cube.emax().TeV(),
280   - edisp=self['edisp'].boolean())
281   -
282   - if self['edisp'].boolean():
283   - obs[0].response(response['expcube'], response['psfcube'],
284   - response['edispcube'], response['bkgcube'])
285   - else:
286   - obs[0].response(response['expcube'], response['psfcube'],
287   - response['bkgcube'])
288   -
289   - # Get new models
290   - models = response['models']
291   -
292   - # Set models for observation container
293   - obs.models(models)
294   -
295   - # Return observation container
296   - return obs
297   -
298 277 def _masked_cube(self, cube, ra, dec, rad, emin='INDEF', emax='INDEF',
299 278 regfile='NONE'):
300 279 """
... ... @@ -325,7 +304,9 @@ class csresspec(ctools.csobservation):
325 304 cubemask['regfile'] = regfile
326 305 cubemask.run()
327 306  
328   - return cubemask.cube()
  307 + # Return
  308 + # Note: we return a copy to avoid memory leaks in SWIG
  309 + return cubemask.cube().copy()
329 310  
330 311 def _cube_to_spectrum(self, cube, evlist_info):
331 312 """
... ... @@ -352,8 +333,8 @@ class csresspec(ctools.csobservation):
352 333 regfile=self['regfile'])
353 334  
354 335 # Extract skymap and clip at 0 to null masked areas
355   - counts = cube.counts()
356   - counts = counts.clip(0)
  336 + counts = cube.counts().copy()
  337 + counts = counts.clip(0.)
357 338  
358 339 # Convert skymap into GNdarray count spectrum
359 340 counts = counts.total_counts()
... ... @@ -372,7 +353,7 @@ class csresspec(ctools.csobservation):
372 353 :return: `~gammalib.GFitsBinTable'
373 354 """
374 355 # Create FITS table columns
375   - nrows = self._ebounds.size()
  356 + nrows = ebounds.size()
376 357 energy_low = gammalib.GFitsTableDoubleCol('ed_Energy', nrows)
377 358 energy_high = gammalib.GFitsTableDoubleCol('eu_Energy', nrows)
378 359 counts_col = gammalib.GFitsTableDoubleCol('Counts', nrows)
... ... @@ -391,6 +372,9 @@ class csresspec(ctools.csobservation):
391 372  
392 373 # Initialise FITS Table with extension set to obs id
393 374 table = gammalib.GFitsBinTable(nrows)
  375 + # If name not empty add leading blank
  376 + if obs_id != '':
  377 + obs_id = ' ' + obs_id
394 378 table.extname('RESIDUALS ' + obs_id)
395 379  
396 380 # Add Header card to specify algorithm used for residual computation
... ... @@ -402,7 +386,7 @@ class csresspec(ctools.csobservation):
402 386 table.append(energy_high)
403 387 table.append(counts_col)
404 388 table.append(model_col)
405   - table.append(residuals)
  389 + table.append(resid_col)
406 390  
407 391 return table
408 392  
... ... @@ -427,8 +411,8 @@ class csresspec(ctools.csobservation):
427 411 column = gammalib.GFitsTableDoubleCol(name, table.nrows())
428 412  
429 413 # Fill data
430   - for s, value in enumerate(data):
431   - column[i] = data[i]
  414 + for i, value in enumerate(data):
  415 + column[i] = value
432 416  
433 417 # Append new column to table
434 418 table.append(column)
... ... @@ -456,45 +440,36 @@ class csresspec(ctools.csobservation):
456 440 self.obs(self._stack_observations())
457 441  
458 442 # Loop over observations and calculate residuals
459   - for s, obs in enumerate(self.obs()):
  443 + for s, observation in enumerate(self.obs()):
460 444  
461 445 # Retrieve and store obs id
462   - obs_id = obs.id()
463   - # If observation id is empty replace with incremental number
464   - if obs_id == '':
  446 + obs_id = observation.id()
  447 + # If observation id is empty and there is more than one observation
  448 + # replace with incremental number
  449 + if obs_id == '' and self.obs().size() > 1:
465 450 obs_id = str(s)
466 451  
467 452 # Turn into observation container and assign models
468   - obs = gammalib.GObservations(obs)
  453 + obs = gammalib.GObservations()
  454 + obs.append(observation)
469 455 obs.models(self.obs().models())
470 456  
471   - # if 3D observations
  457 + # if 3D observation
472 458 if obs[0].classname() == 'GCTAObservation':
473 459  
474 460 ## Prepare Observations
475 461  
476 462 # If already binned set the evlist_info dictionary to have
477 463 # attribute was_list False
478   - was_list = False
479 464 if obs[0].eventtype() == 'CountsCube':
480 465 evlist_info = {'was_list': False}
481 466 # Otherwise bin now
482 467 else:
483 468 # we remember if we binned an event list
484 469 # so that we can mask only the ROI for residual calculation
485   - was_list = True
486   - obs, evlist_info = self._bin_evlist(
487   - obs)
488   -
489   - # If binned response is present or model cube provided pass
490   - if obs[0].has_response() or self._use_maps:
491   - pass
492   - # Otherwise calculate binned response now
493   - else:
494   - obs = self._add_binned_response(obs)
  470 + obs, evlist_info = self._bin_evlist(obs)
495 471  
496 472 ## Calculate Model and residuals
497   -
498 473 # If model cube is provided load it
499 474 if self._use_maps:
500 475 modcube = gammalib.GCTAEventCube(self['inmodel'].filename())
... ... @@ -522,13 +497,13 @@ class csresspec(ctools.csobservation):
522 497 residuals)
523 498  
524 499 ## Calculate models of individual components if requested
525   - if self._components:
  500 + if self['components'].boolean():
526 501 for component in obs.models():
527   - # Extract component name and set model cube models to
  502 + # Set model cube models to
528 503 # individual component
529   - name = component.name()
530   - component = gammalib.GModels(component)
531   - modelcube.obs().models(component)
  504 + model_cont = gammalib.GModels()
  505 + model_cont.append(component)
  506 + modelcube.obs().models(model_cont)
532 507  
533 508 # Run model cube
534 509 modelcube.run()
... ... @@ -538,7 +513,8 @@ class csresspec(ctools.csobservation):
538 513 model = self._cube_to_spectrum(modcube, evlist_info)
539 514  
540 515 # append component to table
541   - table = self._append_column(table, name, model)
  516 + table = self._append_column(table, component.name(),
  517 + model)
542 518  
543 519 # otherwise, if On/Off
544 520 elif obs[0].classname() == 'GCTAOnOffObservation':
... ... @@ -561,7 +537,6 @@ class csresspec(ctools.csobservation):
561 537  
562 538 # Continue only if FITS file is valid
563 539 if self._fits != None:
564   -
565 540 # Get outfile parameter
566 541 outfile = self['outfile'].filename()
567 542  
... ... @@ -574,11 +549,11 @@ class csresspec(ctools.csobservation):
574 549 # Return
575 550 return
576 551  
  552 +
577 553 # ======================== #
578 554 # Main routine entry point #
579 555 # ======================== #
580 556 if __name__ == '__main__':
581   -
582 557 # Create instance of application
583 558 app = csresspec(sys.argv)
584 559  
... ...
cscripts/obsutils.py
... ... @@ -909,7 +909,7 @@ def residuals(cls,counts,model):
909 909 # Compute significance map
910 910 residuals *= 2.0
911 911 residuals = residuals.sqrt()
912   - residuals = residuals * sign
  912 + residuals *= sign
913 913  
914 914 # Raise exception if algorithm is unknown
915 915 else:
... ...