Commit 75b1cd4290a1e949993dd7e9a17083d27534b4e6

Authored by Jürgen Knödlseder
1 parent 19567f9c

Add H.E.S.S. background lookup to models and enhance csbkgmodel unit test

cscripts/Makefile.am
... ... @@ -235,7 +235,8 @@ testdata = $(top_srcdir)/test/data/crab.xml \
235 235 $(top_srcdir)/test/data/onoff_rmf2.fits.gz \
236 236 $(top_srcdir)/test/data/model_crab_radialacceptance.xml \
237 237 $(top_srcdir)/test/data/sigdist_map.fits.gz \
238   - $(top_srcdir)/test/data/variability.fits.gz
  238 + $(top_srcdir)/test/data/variability.fits.gz \
  239 + $(top_srcdir)/test/data/hess_bkg_lookup.fits
239 240  
240 241 # Test data to be distributed in $(pyexecdir)/cscripts/tests/data/iactdata
241 242 testiactdata = $(top_srcdir)/test/data/iactdata/hdu-index.fits.gz \
... ...
cscripts/csbkgmodel.py
... ... @@ -30,7 +30,6 @@ class csbkgmodel(ctools.csobservation):
30 30 """
31 31 Generates background model
32 32 """
33   -
34 33 # Constructor
35 34 def __init__(self, *argv):
36 35 """
... ... @@ -46,7 +45,7 @@ class csbkgmodel(ctools.csobservation):
46 45 # Return
47 46 return
48 47  
49   - # State methods por pickling
  48 + # __getstate__ method for pickling
50 49 def __getstate__(self):
51 50 """
52 51 Extend ctools.csobservation getstate method to include some members
... ... @@ -64,6 +63,7 @@ class csbkgmodel(ctools.csobservation):
64 63 # Return pickled dictionary
65 64 return state
66 65  
  66 + # __setstate__ method for pickling
67 67 def __setstate__(self, state):
68 68 """
69 69 Extend ctools.csobservation setstate method to include some members
... ... @@ -102,8 +102,9 @@ class csbkgmodel(ctools.csobservation):
102 102 self['smax'].real()
103 103 if spatial == 'LOOKUP':
104 104 self['slufile'].filename()
105   - if spatial == 'LOOKUP' or spatial == 'GAUSS' or \
106   - spatial == 'GAUSS(E)' or spatial == 'PROFILE':
  105 + if spatial == 'LOOKUP' or spatial == 'GAUSS' or \
  106 + spatial == 'GAUSS(E)' or spatial == 'PROFILE' or \
  107 + spatial == 'POLYNOM':
107 108 self['gradient'].boolean()
108 109 spectral = self['spectral'].string()
109 110 if spectral == 'NODES':
... ... @@ -178,133 +179,74 @@ class csbkgmodel(ctools.csobservation):
178 179 spectral = gammalib.GModelSpectralPlaw(1.0e-13, -2.5, epivot)
179 180 model = gammalib.GCTAModelAeffBackground(spectral)
180 181  
181   - # Handle LOOKUP model
182   - elif self['spatial'].string() == 'LOOKUP':
183   -
184   - # Set spatial model
185   - factor1 = gammalib.GCTAModelSpatialLookup(self['slufile'].filename())
186   -
187   - # Optionally add gradient
188   - if self['gradient'].boolean():
189   - spatial = gammalib.GCTAModelSpatialMultiplicative()
190   - factor2 = gammalib.GCTAModelSpatialGradient()
191   - spatial.append(factor1)
192   - spatial.append(factor2)
193   - else:
194   - spatial = factor1
195   -
196   - # Set spectral model
197   - epivot = gammalib.GEnergy(1.0, 'TeV')
198   - spectral = gammalib.GModelSpectralPlaw(3.0e-4, -1.5, epivot)
199   - spectral['Prefactor'].min(1.0e-8)
200   -
201   - # Set background model
202   - model = gammalib.GCTAModelBackground(spatial, spectral)
203   -
204   - # Handle GAUSS model
205   - elif self['spatial'].string() == 'GAUSS':
206   -
207   - # Set spatial model
208   - factor1 = gammalib.GCTAModelRadialGauss(3.0)
209   - factor1['Sigma'].min(sigma_min)
210   - factor1['Sigma'].max(sigma_max)
211   -
212   - # Optionally add gradient
213   - if self['gradient'].boolean():
214   - spatial = gammalib.GCTAModelSpatialMultiplicative()
215   - factor2 = gammalib.GCTAModelSpatialGradient()
216   - spatial.append(factor1)
217   - spatial.append(factor2)
218   - else:
219   - spatial = factor1
  182 + # Handle other models
  183 + else:
220 184  
221   - # Set spectral model
222   - epivot = gammalib.GEnergy(1.0, 'TeV')
223   - spectral = gammalib.GModelSpectralPlaw(3.0e-4, -1.5, epivot)
224   - spectral['Prefactor'].min(1.0e-8)
  185 + # Handle LOOKUP model
  186 + if self['spatial'].string() == 'LOOKUP':
225 187  
226   - # Set background model
227   - model = gammalib.GCTAModelBackground(spatial, spectral)
  188 + # Set spatial model
  189 + factor1 = gammalib.GCTAModelSpatialLookup(self['slufile'].filename())
228 190  
229   - # Handle GAUSS(E) model
230   - elif self['spatial'].string() == 'GAUSS(E)':
  191 + # Handle GAUSS model
  192 + elif self['spatial'].string() == 'GAUSS':
231 193  
232   - # Set spatial model
233   - if self['snumbins'].integer() == 1:
  194 + # Set spatial model
234 195 factor1 = gammalib.GCTAModelRadialGauss(3.0)
235 196 factor1['Sigma'].min(sigma_min)
236 197 factor1['Sigma'].max(sigma_max)
237   - else:
238   - emin = gammalib.GEnergy(self['smin'].real(), 'TeV')
239   - emax = gammalib.GEnergy(self['smax'].real(), 'TeV')
240   - energies = gammalib.GEnergies(self['snumbins'].integer(), emin, emax)
241   - spectrum = gammalib.GModelSpectralConst(3.0)
242   - nodes = gammalib.GModelSpectralNodes(spectrum, energies)
243   - for i in range(nodes.nodes()):
244   - nodes[i*2+1].min(sigma_min)
245   - nodes[i*2+1].max(sigma_max)
246   - nodes.autoscale()
247   - factor1 = gammalib.GCTAModelSpatialGaussSpectrum(nodes)
248 198  
249   - # Optionally add gradient
250   - if self['gradient'].boolean():
251   - spatial = gammalib.GCTAModelSpatialMultiplicative()
252   - factor2 = gammalib.GCTAModelSpatialGradient()
253   - spatial.append(factor1)
254   - spatial.append(factor2)
255   - else:
256   - spatial = factor1
257   -
258   - # Set spectral model
259   - epivot = gammalib.GEnergy(1.0, 'TeV')
260   - spectral = gammalib.GModelSpectralPlaw(3.0e-4, -1.5, epivot)
261   - spectral['Prefactor'].min(1.0e-8)
262   -
263   - # Set background model
264   - model = gammalib.GCTAModelBackground(spatial, spectral)
265   -
266   - # Handle PROFILE model
267   - elif self['spatial'].string() == 'PROFILE':
268   -
269   - # Set spatial model
270   - factor1 = gammalib.GCTAModelRadialProfile(2.0, 4.0, 5.0)
271   - factor1['Width'].min(1.0)
272   - factor1['Width'].max(10.0)
273   - factor1['Core'].min(1.0)
274   - factor1['Core'].max(10.0)
275   - factor1['Tail'].min(-10.0)
276   - factor1['Tail'].max(10.0)
277   - factor1['Tail'].free()
278   -
279   - # Optionally add gradient
280   - if self['gradient'].boolean():
281   - spatial = gammalib.GCTAModelSpatialMultiplicative()
282   - factor2 = gammalib.GCTAModelSpatialGradient()
283   - spatial.append(factor1)
284   - spatial.append(factor2)
  199 + # Handle GAUSS(E) model
  200 + elif self['spatial'].string() == 'GAUSS(E)':
  201 +
  202 + # Set spatial model. If a single energy bin is specified then
  203 + # use the GAUSS model. Otherwise allocate a node spectrum for
  204 + # the energy nodes of GAUSS(E).
  205 + if self['snumbins'].integer() == 1:
  206 + factor1 = gammalib.GCTAModelRadialGauss(3.0)
  207 + factor1['Sigma'].min(sigma_min)
  208 + factor1['Sigma'].max(sigma_max)
  209 + else:
  210 + emin = gammalib.GEnergy(self['smin'].real(), 'TeV')
  211 + emax = gammalib.GEnergy(self['smax'].real(), 'TeV')
  212 + energies = gammalib.GEnergies(self['snumbins'].integer(), emin, emax)
  213 + spectrum = gammalib.GModelSpectralConst(3.0)
  214 + nodes = gammalib.GModelSpectralNodes(spectrum, energies)
  215 + for i in range(nodes.nodes()):
  216 + nodes[i*2+1].min(sigma_min)
  217 + nodes[i*2+1].max(sigma_max)
  218 + nodes.autoscale()
  219 + factor1 = gammalib.GCTAModelSpatialGaussSpectrum(nodes)
  220 +
  221 + # Handle PROFILE model
  222 + elif self['spatial'].string() == 'PROFILE':
  223 +
  224 + # Set spatial model
  225 + factor1 = gammalib.GCTAModelRadialProfile(2.0, 4.0, 5.0)
  226 + factor1['Width'].min(1.0)
  227 + factor1['Width'].max(10.0)
  228 + factor1['Core'].min(1.0)
  229 + factor1['Core'].max(10.0)
  230 + factor1['Tail'].min(1.0)
  231 + factor1['Tail'].max(10.0)
  232 + factor1['Tail'].free()
  233 +
  234 + # Handle POLYNOM model
  235 + elif self['spatial'].string() == 'POLYNOM':
  236 +
  237 + # Set spatial model
  238 + factor1 = gammalib.GCTAModelRadialPolynom([1.0, -0.1, +0.1])
  239 + factor1['Coeff0'].min(0.1)
  240 + factor1['Coeff0'].max(10.0)
  241 + factor1['Coeff0'].fix()
  242 + factor1['Coeff1'].min(-10.0)
  243 + factor1['Coeff1'].max(10.0)
  244 + factor1['Coeff2'].min(-10.0)
  245 + factor1['Coeff2'].max(10.0)
  246 +
  247 + # Any other strings (should never occur)
285 248 else:
286   - spatial = factor1
287   -
288   - # Set spectral model
289   - epivot = gammalib.GEnergy(1.0, 'TeV')
290   - spectral = gammalib.GModelSpectralPlaw(3.0e-4, -1.5, epivot)
291   - spectral['Prefactor'].min(1.0e-8)
292   -
293   - # Set background model
294   - model = gammalib.GCTAModelBackground(spatial, spectral)
295   -
296   - # Handle POLYNOM model
297   - elif self['spatial'].string() == 'POLYNOM':
298   -
299   - # Set spatial model
300   - factor1 = gammalib.GCTAModelRadialPolynom([1.0, -0.1, +0.1])
301   - factor1['Coeff0'].min(0.1)
302   - factor1['Coeff0'].max(10.0)
303   - factor1['Coeff0'].fix()
304   - factor1['Coeff1'].min(-10.0)
305   - factor1['Coeff1'].max(10.0)
306   - factor1['Coeff2'].min(-10.0)
307   - factor1['Coeff2'].max(10.0)
  249 + model = None
308 250  
309 251 # Optionally add gradient
310 252 if self['gradient'].boolean():
... ... @@ -323,10 +265,6 @@ class csbkgmodel(ctools.csobservation):
323 265 # Set background model
324 266 model = gammalib.GCTAModelBackground(spatial, spectral)
325 267  
326   - # Any other strings (should never occur)
327   - else:
328   - model = None
329   -
330 268 # Set background name and instrument
331 269 if model is not None:
332 270 model.name('Background')
... ...
models/Makefile.am
... ... @@ -37,7 +37,8 @@ models = 1dc_howto.xml \
37 37 crab_profile.xml \
38 38 disk.xml \
39 39 gauss.xml \
40   - shell.xml
  40 + shell.xml \
  41 + hess_bkg_lookup.fits
41 42  
42 43 # Install models
43 44 modelsdir = $(datadir)/models
... ...
models/hess_bkg_lookup.fits 0 → 100644
No preview for this file type
test/data/hess_bkg_lookup.fits 0 → 100644
No preview for this file type
test/test_csbkgmodel.py
... ... @@ -45,6 +45,7 @@ class Test(test):
45 45 # Set test datasets and parameters
46 46 self._myevents1 = self._datadir + '/crab_offaxis1.fits'
47 47 self._myevents2 = self._datadir + '/crab_offaxis2.fits'
  48 + self._lookup = self._datadir + '/hess_bkg_lookup.fits'
48 49  
49 50 # Return
50 51 return
... ... @@ -250,6 +251,114 @@ class Test(test):
250 251 # Check background model
251 252 self._check_bkg_model('csbkgmodel_py5.xml', nmodels=2)
252 253  
  254 + # Test GAUSS(E) spatial model
  255 + bkgmodel = cscripts.csbkgmodel()
  256 + bkgmodel['inobs'] = self._events
  257 + bkgmodel['caldb'] = self._caldb
  258 + bkgmodel['irf'] = self._irf
  259 + bkgmodel['instrument'] = 'CTA'
  260 + bkgmodel['spatial'] = 'GAUSS(E)'
  261 + bkgmodel['snumbins'] = 2
  262 + bkgmodel['smin'] = 1.0
  263 + bkgmodel['smax'] = 10.0
  264 + bkgmodel['gradient'] = True
  265 + bkgmodel['spectral'] = 'NODES'
  266 + bkgmodel['ebinalg'] = 'LOG'
  267 + bkgmodel['emin'] = 1.0
  268 + bkgmodel['emax'] = 100.0
  269 + bkgmodel['enumbins'] = 8
  270 + bkgmodel['runwise'] = True
  271 + bkgmodel['rad'] = 2.0
  272 + bkgmodel['chatter'] = 2
  273 + bkgmodel['outmodel'] = 'csbkgmodel_py6.xml'
  274 + bkgmodel['logfile'] = 'csbkgmodel_py6.log'
  275 +
  276 + # Run csbkgmodel script and save background model
  277 + bkgmodel.logFileOpen() # Make sure we get a log file
  278 + bkgmodel.execute()
  279 +
  280 + # Check background model
  281 + self._check_bkg_model('csbkgmodel_py6.xml')
  282 +
  283 + # Test LOOKUP spatial model
  284 + bkgmodel = cscripts.csbkgmodel()
  285 + bkgmodel['inobs'] = self._events
  286 + bkgmodel['caldb'] = self._caldb
  287 + bkgmodel['irf'] = self._irf
  288 + bkgmodel['instrument'] = 'CTA'
  289 + bkgmodel['spatial'] = 'LOOKUP'
  290 + bkgmodel['slufile'] = self._lookup
  291 + bkgmodel['gradient'] = True
  292 + bkgmodel['spectral'] = 'NODES'
  293 + bkgmodel['ebinalg'] = 'LOG'
  294 + bkgmodel['emin'] = 1.0
  295 + bkgmodel['emax'] = 100.0
  296 + bkgmodel['enumbins'] = 8
  297 + bkgmodel['runwise'] = True
  298 + bkgmodel['rad'] = 2.0
  299 + bkgmodel['chatter'] = 2
  300 + bkgmodel['outmodel'] = 'csbkgmodel_py7.xml'
  301 + bkgmodel['logfile'] = 'csbkgmodel_py7.log'
  302 +
  303 + # Run csbkgmodel script and save background model
  304 + bkgmodel.logFileOpen() # Make sure we get a log file
  305 + bkgmodel.execute()
  306 +
  307 + # Check background model
  308 + self._check_bkg_model('csbkgmodel_py7.xml')
  309 +
  310 + # Test PROFILE spatial model
  311 + bkgmodel = cscripts.csbkgmodel()
  312 + bkgmodel['inobs'] = self._events
  313 + bkgmodel['caldb'] = self._caldb
  314 + bkgmodel['irf'] = self._irf
  315 + bkgmodel['instrument'] = 'CTA'
  316 + bkgmodel['spatial'] = 'PROFILE'
  317 + bkgmodel['gradient'] = True
  318 + bkgmodel['spectral'] = 'NODES'
  319 + bkgmodel['ebinalg'] = 'LOG'
  320 + bkgmodel['emin'] = 1.0
  321 + bkgmodel['emax'] = 100.0
  322 + bkgmodel['enumbins'] = 8
  323 + bkgmodel['runwise'] = True
  324 + bkgmodel['rad'] = 2.0
  325 + bkgmodel['chatter'] = 2
  326 + bkgmodel['outmodel'] = 'csbkgmodel_py8.xml'
  327 + bkgmodel['logfile'] = 'csbkgmodel_py8.log'
  328 +
  329 + # Run csbkgmodel script and save background model
  330 + bkgmodel.logFileOpen() # Make sure we get a log file
  331 + bkgmodel.execute()
  332 +
  333 + # Check background model
  334 + self._check_bkg_model('csbkgmodel_py8.xml')
  335 +
  336 + # Test POLYNOM spatial model
  337 + bkgmodel = cscripts.csbkgmodel()
  338 + bkgmodel['inobs'] = self._events
  339 + bkgmodel['caldb'] = self._caldb
  340 + bkgmodel['irf'] = self._irf
  341 + bkgmodel['instrument'] = 'CTA'
  342 + bkgmodel['spatial'] = 'POLYNOM'
  343 + bkgmodel['gradient'] = True
  344 + bkgmodel['spectral'] = 'NODES'
  345 + bkgmodel['ebinalg'] = 'LOG'
  346 + bkgmodel['emin'] = 1.0
  347 + bkgmodel['emax'] = 100.0
  348 + bkgmodel['enumbins'] = 8
  349 + bkgmodel['runwise'] = True
  350 + bkgmodel['rad'] = 2.0
  351 + bkgmodel['chatter'] = 2
  352 + bkgmodel['outmodel'] = 'csbkgmodel_py9.xml'
  353 + bkgmodel['logfile'] = 'csbkgmodel_py9.log'
  354 +
  355 + # Run csbkgmodel script and save background model
  356 + bkgmodel.logFileOpen() # Make sure we get a log file
  357 + bkgmodel.execute()
  358 +
  359 + # Check background model
  360 + self._check_bkg_model('csbkgmodel_py9.xml')
  361 +
253 362 # Return
254 363 return
255 364  
... ...