Commit 152493f86c0342a85aabb0c88ee0da2b2856d5e9

Authored by Jürgen Knödlseder
2 parents a2090093 fe07c6cf

Merge branch 'integration' into 1920-fix-cslightcrv

# Conflicts:
#	NEWS
1 New Features and Important Changes in ctools 1.2.0 1 New Features and Important Changes in ctools 1.2.0
2 2
3 -12 December 2016 3 +26 January 2017
4 4
5 5
6 Introduction 6 Introduction
@@ -195,6 +195,9 @@ in particular the "PhotonFlux" and "EnergyFlux" names (#1832). @@ -195,6 +195,9 @@ in particular the "PhotonFlux" and "EnergyFlux" names (#1832).
195 195
196 The class now derives from ctlikelihood (#1828). 196 The class now derives from ctlikelihood (#1828).
197 197
  198 +The tool now makes sure that the intensity parameter of the source of interest
  199 +is free in the model optimisation that preceeds the upper limit computation.
  200 +
198 201
199 cterror - Likelihood profile error computation 202 cterror - Likelihood profile error computation
200 ---------------------------------------------- 203 ----------------------------------------------
@@ -235,10 +238,14 @@ Add cssrcdetect script to detect sources in a sky map (#1617). @@ -235,10 +238,14 @@ Add cssrcdetect script to detect sources in a sky map (#1617).
235 The "ds9file" parameters were changed to "outds9file" to be consistent with 238 The "ds9file" parameters were changed to "outds9file" to be consistent with
236 the naming conventions. 239 the naming conventions.
237 240
  241 +Improve the upper limit computation in the cslightcrv script. Now all source
  242 +parameters, except the source intensity, are set to the initial values given
  243 +in the model definition file for upper limit computation.
  244 +
238 245
239 Examples 246 Examples
240 -------- 247 --------
241 -None 248 +Add show_lightcurve script to display a light curve.
242 249
243 250
244 caldb 251 caldb
cscripts/Makefile.am
@@ -166,6 +166,7 @@ testdata = $(top_srcdir)/test/data/crab.xml \ @@ -166,6 +166,7 @@ testdata = $(top_srcdir)/test/data/crab.xml \
166 $(top_srcdir)/test/data/sensitivity_integral.dat \ 166 $(top_srcdir)/test/data/sensitivity_integral.dat \
167 $(top_srcdir)/test/data/skymap.fits \ 167 $(top_srcdir)/test/data/skymap.fits \
168 $(top_srcdir)/test/data/spectrum.fits \ 168 $(top_srcdir)/test/data/spectrum.fits \
  169 + $(top_srcdir)/test/data/lightcurve.fits \
169 $(top_srcdir)/test/data/ts.dat \ 170 $(top_srcdir)/test/data/ts.dat \
170 $(top_srcdir)/test/data/models_spatial.xml \ 171 $(top_srcdir)/test/data/models_spatial.xml \
171 $(top_srcdir)/test/data/models_spectral.xml \ 172 $(top_srcdir)/test/data/models_spectral.xml \
cscripts/cslightcrv.py
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 # ========================================================================== 2 # ==========================================================================
3 # Generates a lightcurve. 3 # Generates a lightcurve.
4 # 4 #
5 -# Copyright (C) 2014-2016 Michael Mayer 5 +# Copyright (C) 2014-2017 Michael Mayer
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
@@ -69,7 +69,7 @@ class cslightcrv(ctools.cscript): @@ -69,7 +69,7 @@ class cslightcrv(ctools.cscript):
69 """ 69 """
70 # Set name 70 # Set name
71 self._name = 'cslightcrv' 71 self._name = 'cslightcrv'
72 - self._version = '1.2.0' 72 + self._version = '1.3.0'
73 73
74 # Initialise some members 74 # Initialise some members
75 self._srcname = '' 75 self._srcname = ''
@@ -335,18 +335,26 @@ class cslightcrv(ctools.cscript): @@ -335,18 +335,26 @@ class cslightcrv(ctools.cscript):
335 table.append(ts) 335 table.append(ts)
336 336
337 # Append upper limit column "UpperLimit" 337 # Append upper limit column "UpperLimit"
338 - ulimit = gammalib.GFitsTableDoubleCol('UpperLimit', nrows)  
339 - ulimit.unit('ph/cm2/s') 338 + ul_diff = gammalib.GFitsTableDoubleCol('DiffUpperLimit', nrows)
  339 + ul_flux = gammalib.GFitsTableDoubleCol('FluxUpperLimit', nrows)
  340 + ul_eflux = gammalib.GFitsTableDoubleCol('EFluxUpperLimit', nrows)
  341 + ul_diff.unit('ph/cm2/s/MeV')
  342 + ul_flux.unit('ph/cm2/s')
  343 + ul_eflux.unit('erg/cm2/s')
340 for i, result in enumerate(results): 344 for i, result in enumerate(results):
341 - ulimit[i] = result['ulimit']  
342 - table.append(ulimit) 345 + ul_diff[i] = result['ul_diff']
  346 + ul_flux[i] = result['ul_flux']
  347 + ul_eflux[i] = result['ul_eflux']
  348 + table.append(ul_diff)
  349 + table.append(ul_flux)
  350 + table.append(ul_eflux)
343 351
344 # Return table 352 # Return table
345 return table 353 return table
346 354
347 def _compute_ulimit(self, obs): 355 def _compute_ulimit(self, obs):
348 """ 356 """
349 - Computes upper flux limit 357 + Computes upper limit
350 358
351 Parameters 359 Parameters
352 ---------- 360 ----------
@@ -355,35 +363,57 @@ class cslightcrv(ctools.cscript): @@ -355,35 +363,57 @@ class cslightcrv(ctools.cscript):
355 363
356 Returns 364 Returns
357 ------- 365 -------
358 - ulimit : float  
359 - Upper flux limit (-1.0 of not computed) 366 + ul_diff, ul_flux, ul_eflux : tuple of float
  367 + Upper limits, -1.0 of not computed
360 """ 368 """
361 # Initialise upper flux limit 369 # Initialise upper flux limit
362 - ulimit_value = -1.0  
363 - 370 + ul_diff = -1.0
  371 + ul_flux = -1.0
  372 + ul_eflux = -1.0
  373 +
364 # Perform computation only if requested 374 # Perform computation only if requested
365 if self['calc_ulim'].boolean(): 375 if self['calc_ulim'].boolean():
366 376
367 # Write header in logger 377 # Write header in logger
368 if self._logExplicit(): 378 if self._logExplicit():
369 - self._log.header3('Computing upper flux limit')  
370 -  
371 - # Create upper limit object  
372 - ulimit = ctools.ctulimit(obs)  
373 - ulimit['srcname'] = self._srcname  
374 - ulimit['eref'] = 1.0  
375 -  
376 - # Try to run upper limit and catch any exceptions 379 + self._log.header3('Computing upper limit')
  380 +
  381 + # Create copy of observations
  382 + cpy_obs = obs.copy()
  383 +
  384 + # Fix parameters of source of interest in copy of observations.
  385 + # This assures that the original spectral parameters and position
  386 + # are used in the upper limit search. The ctulimit tool makes sure
  387 + # that the flux parameter is freed when needed.
  388 + source = cpy_obs.models()[self._srcname]
  389 + for par in source:
  390 + if par.is_free():
  391 + par.fix()
  392 +
  393 + # Create instance of upper limit tool
  394 + ulimit = ctools.ctulimit(cpy_obs)
  395 + ulimit['srcname'] = self._srcname
  396 + ulimit['eref'] = 1.0
  397 + ulimit['emin'] = self['emin'].real()
  398 + ulimit['emax'] = self['emax'].real()
  399 + ulimit['sigma_min'] = 0.0
  400 + ulimit['sigma_max'] = 3.0
  401 +
  402 + # Try to run upper limit tool and catch any exceptions
377 try: 403 try:
378 ulimit.run() 404 ulimit.run()
379 - ulimit_value = ulimit.flux_ulimit() 405 + ul_diff = ulimit.diff_ulimit()
  406 + ul_flux = ulimit.flux_ulimit()
  407 + ul_eflux = ulimit.eflux_ulimit()
380 except: 408 except:
381 if self._logTerse(): 409 if self._logTerse():
382 - self._log('Upper limit flux calculation failed.\n')  
383 - ulimit_value = -1.0 410 + self._log('Upper limit calculation failed.\n')
  411 + ul_diff = -1.0
  412 + ul_flux = -1.0
  413 + ul_eflux = -1.0
384 414
385 - # Return upper limit  
386 - return ulimit_value 415 + # Return upper limit tuple
  416 + return ul_diff, ul_flux, ul_eflux
387 417
388 def _bin_observation(self, obs): 418 def _bin_observation(self, obs):
389 """ 419 """
@@ -517,7 +547,9 @@ class cslightcrv(ctools.cscript): @@ -517,7 +547,9 @@ class cslightcrv(ctools.cscript):
517 result = {'mjd': tmean.mjd(), 547 result = {'mjd': tmean.mjd(),
518 'e_mjd': twidth / gammalib.sec_in_day, 548 'e_mjd': twidth / gammalib.sec_in_day,
519 'ts': 0.0, 549 'ts': 0.0,
520 - 'ulimit': 0.0, 550 + 'ul_diff': 0.0,
  551 + 'ul_flux': 0.0,
  552 + 'ul_eflux': 0.0,
521 'pars': pars, 553 'pars': pars,
522 'values': {}} 554 'values': {}}
523 555
@@ -581,9 +613,12 @@ class cslightcrv(ctools.cscript): @@ -581,9 +613,12 @@ class cslightcrv(ctools.cscript):
581 result['values']['e_'+par] = source[par].error() 613 result['values']['e_'+par] = source[par].error()
582 614
583 # Calculate upper limit (-1 if not computed) 615 # Calculate upper limit (-1 if not computed)
584 - ulimit_value = self._compute_ulimit(like.obs())  
585 - if ulimit_value > 0.0:  
586 - result['ulimit'] = ulimit_value 616 + #ul_diff, ul_flux, ul_eflux = self._compute_ulimit(like.obs())
  617 + ul_diff, ul_flux, ul_eflux = self._compute_ulimit(obs)
  618 + if ul_diff > 0.0:
  619 + result['ul_diff'] = ul_diff
  620 + result['ul_flux'] = ul_flux
  621 + result['ul_eflux'] = ul_eflux
587 622
588 # Extract Test Statistic value 623 # Extract Test Statistic value
589 if self['calc_ts'].boolean(): 624 if self['calc_ts'].boolean():
@@ -601,9 +636,13 @@ class cslightcrv(ctools.cscript): @@ -601,9 +636,13 @@ class cslightcrv(ctools.cscript):
601 unit = source[par].unit() 636 unit = source[par].unit()
602 self._log_value(gammalib.NORMAL, par, 637 self._log_value(gammalib.NORMAL, par,
603 str(value)+' +/- '+str(error)+' '+unit) 638 str(value)+' +/- '+str(error)+' '+unit)
604 - if result['ulimit'] > 0.0: 639 + if ul_diff > 0.0:
  640 + self._log_value(gammalib.NORMAL, 'Upper flux limit',
  641 + str(result['ul_diff'])+' ph/cm2/s/MeV')
  642 + self._log_value(gammalib.NORMAL, 'Upper flux limit',
  643 + str(result['ul_flux'])+' ph/cm2/s')
605 self._log_value(gammalib.NORMAL, 'Upper flux limit', 644 self._log_value(gammalib.NORMAL, 'Upper flux limit',
606 - str(result['ulimit'])+' ph/cm2/s') 645 + str(result['ul_eflux'])+' erg/cm2/s')
607 if self['calc_ts'].boolean(): 646 if self['calc_ts'].boolean():
608 self._log_value(gammalib.NORMAL, 'Test Statistic', result['ts']) 647 self._log_value(gammalib.NORMAL, 'Test Statistic', result['ts'])
609 648
cscripts/csroot2caldb.py
@@ -146,7 +146,7 @@ class csroot2caldb(ctools.cscript): @@ -146,7 +146,7 @@ class csroot2caldb(ctools.cscript):
146 def _make_dirs(self, version, irf): 146 def _make_dirs(self, version, irf):
147 """ 147 """
148 Generate CALDB directory structure for one observation identifier 148 Generate CALDB directory structure for one observation identifier
149 - 149 +
150 The structure is given by 150 The structure is given by
151 151
152 data/<tel>/<inst>/bcf/<obsid> 152 data/<tel>/<inst>/bcf/<obsid>
@@ -227,7 +227,7 @@ class csroot2caldb(ctools.cscript): @@ -227,7 +227,7 @@ class csroot2caldb(ctools.cscript):
227 def _open(self, irf, ds): 227 def _open(self, irf, ds):
228 """ 228 """
229 Open existing or create new calibration 229 Open existing or create new calibration
230 - 230 +
231 The actual version will put all calibrations in the same file, although 231 The actual version will put all calibrations in the same file, although
232 each part of the response function will have its own logical name. We 232 each part of the response function will have its own logical name. We
233 can thus easily modify the script to put each calibration information 233 can thus easily modify the script to put each calibration information
@@ -322,7 +322,7 @@ class csroot2caldb(ctools.cscript): @@ -322,7 +322,7 @@ class csroot2caldb(ctools.cscript):
322 def _open_hdu(self, fits, extname, name, doc, irf): 322 def _open_hdu(self, fits, extname, name, doc, irf):
323 """ 323 """
324 Open HDU 324 Open HDU
325 - 325 +
326 Opens a FITS binary table with given "extname". If HDU does not exist 326 Opens a FITS binary table with given "extname". If HDU does not exist
327 in the FITS file it will be created and appended to the FITS file. 327 in the FITS file it will be created and appended to the FITS file.
328 328
@@ -534,10 +534,9 @@ class csroot2caldb(ctools.cscript): @@ -534,10 +534,9 @@ class csroot2caldb(ctools.cscript):
534 def _root2ea(self, tfile, irf, ds): 534 def _root2ea(self, tfile, irf, ds):
535 """ 535 """
536 Translate ROOT to CALDB effective area extension 536 Translate ROOT to CALDB effective area extension
537 - 537 +
538 The following ROOT histograms are used: 538 The following ROOT histograms are used:
539 - EffectiveAreaEtrue_offaxis -> EFFAREA 539 - EffectiveAreaEtrue_offaxis -> EFFAREA
540 - - EffectiveArea_offaxis -> EFFAREA_RECO  
541 540
542 Parameters 541 Parameters
543 ---------- 542 ----------
@@ -555,16 +554,13 @@ class csroot2caldb(ctools.cscript): @@ -555,16 +554,13 @@ class csroot2caldb(ctools.cscript):
555 554
556 # Get relevant ROOT histograms 555 # Get relevant ROOT histograms
557 etrue = tfile.Get('EffectiveAreaEtrue_offaxis') 556 etrue = tfile.Get('EffectiveAreaEtrue_offaxis')
558 - ereco = tfile.Get('EffectiveArea_offaxis')  
559 557
560 # If requested then normalize the 2D histogram on the on-axis 1D 558 # If requested then normalize the 2D histogram on the on-axis 1D
561 # histogram. This assures that the 2D histogram has the same on-axis 559 # histogram. This assures that the 2D histogram has the same on-axis
562 # effective area dependence as the 1D histogram. 560 # effective area dependence as the 1D histogram.
563 if self['norm1d'].boolean(): 561 if self['norm1d'].boolean():
564 etrue_1D = tfile.Get('EffectiveAreaEtrue') 562 etrue_1D = tfile.Get('EffectiveAreaEtrue')
565 - ereco_1D = tfile.Get('EffectiveArea')  
566 self._renorm_onaxis(etrue, etrue_1D) 563 self._renorm_onaxis(etrue, etrue_1D)
567 - self._renorm_onaxis(ereco, ereco_1D)  
568 564
569 # If requested then rebin the effective area Etrue histogram. This 565 # If requested then rebin the effective area Etrue histogram. This
570 # increases the number of bins by a factor 10. 566 # increases the number of bins by a factor 10.
@@ -589,17 +585,6 @@ class csroot2caldb(ctools.cscript): @@ -589,17 +585,6 @@ class csroot2caldb(ctools.cscript):
589 for ieng in range(neng): 585 for ieng in range(neng):
590 value = etrue.GetBinContent(ieng+1,ioff+1) * eascale 586 value = etrue.GetBinContent(ieng+1,ioff+1) * eascale
591 etrue.SetBinContent(ieng+1,ioff+1,value) 587 etrue.SetBinContent(ieng+1,ioff+1,value)
592 - neng = ereco.GetXaxis().GetNbins()  
593 - noffset = ereco.GetYaxis().GetNbins()  
594 - for ioff in range(noffset):  
595 - for ieng in range(neng):  
596 - value = ereco.GetBinContent(ieng+1,ioff+1) * eascale  
597 - ereco.SetBinContent(ieng+1,ioff+1,value)  
598 -  
599 - # Set boundaries (use Ereco boundaries)  
600 - #bounds = self._make_2D(ereco, ds['HDU_EA'], None, 'm2')  
601 - #for b in bounds:  
602 - # irf['EA_BOUNDS'].append(b)  
603 588
604 # Write boundary keywords 589 # Write boundary keywords
605 self._set_cif_keywords(ds['HDU_EA'], irf['EA_NAME'], 590 self._set_cif_keywords(ds['HDU_EA'], irf['EA_NAME'],
@@ -608,16 +593,13 @@ class csroot2caldb(ctools.cscript): @@ -608,16 +593,13 @@ class csroot2caldb(ctools.cscript):
608 # Create "EFFAREA" data column 593 # Create "EFFAREA" data column
609 self._make_2D(etrue, ds['HDU_EA'], 'EFFAREA', 'm2') 594 self._make_2D(etrue, ds['HDU_EA'], 'EFFAREA', 'm2')
610 595
611 - # Create "EFFAREA_RECO" data column  
612 - self._make_2D(ereco, ds['HDU_EA'], 'EFFAREA_RECO', 'm2')  
613 -  
614 # Return 596 # Return
615 return 597 return
616 598
617 def _root2psf(self, tfile, irf, ds): 599 def _root2psf(self, tfile, irf, ds):
618 """ 600 """
619 Translate ROOT to CALDB point spread function extension 601 Translate ROOT to CALDB point spread function extension
620 - 602 +
621 Parameters 603 Parameters
622 ---------- 604 ----------
623 tfile : `~ROOT.TFile` 605 tfile : `~ROOT.TFile`
@@ -646,7 +628,7 @@ class csroot2caldb(ctools.cscript): @@ -646,7 +628,7 @@ class csroot2caldb(ctools.cscript):
646 def _root2psf_gauss(self, tfile, irf, ds): 628 def _root2psf_gauss(self, tfile, irf, ds):
647 """ 629 """
648 Translate ROOT to CALDB point spread function extension 630 Translate ROOT to CALDB point spread function extension
649 - 631 +
650 The following ROOT histograms are used: 632 The following ROOT histograms are used:
651 - 1/(2*pi*SIGMA_1) -> SCALE 633 - 1/(2*pi*SIGMA_1) -> SCALE
652 - AngRes_offaxis -> SIGMA_1 (scaling: 1/0.8) 634 - AngRes_offaxis -> SIGMA_1 (scaling: 1/0.8)
@@ -729,7 +711,7 @@ class csroot2caldb(ctools.cscript): @@ -729,7 +711,7 @@ class csroot2caldb(ctools.cscript):
729 def _root2psf_king(self, tfile, irf, ds): 711 def _root2psf_king(self, tfile, irf, ds):
730 """ 712 """
731 Translate ROOT to CALDB point spread function extension 713 Translate ROOT to CALDB point spread function extension
732 - 714 +
733 The following ROOT histograms are used: 715 The following ROOT histograms are used:
734 - AngRes_offaxis 716 - AngRes_offaxis
735 - AngRes80_offaxis 717 - AngRes80_offaxis
@@ -853,7 +835,7 @@ class csroot2caldb(ctools.cscript): @@ -853,7 +835,7 @@ class csroot2caldb(ctools.cscript):
853 def _root2edisp(self, tfile, irf, ds): 835 def _root2edisp(self, tfile, irf, ds):
854 """ 836 """
855 Translate ROOT to CALDB energy dispersion extension 837 Translate ROOT to CALDB energy dispersion extension
856 - 838 +
857 The following ROOT histograms are used: 839 The following ROOT histograms are used:
858 - EestOverEtrue_offaxis -> MATRIX 840 - EestOverEtrue_offaxis -> MATRIX
859 841
@@ -892,7 +874,7 @@ class csroot2caldb(ctools.cscript): @@ -892,7 +874,7 @@ class csroot2caldb(ctools.cscript):
892 def _root2bgd(self, tfile, irf, ds): 874 def _root2bgd(self, tfile, irf, ds):
893 """ 875 """
894 Translate ROOT to CALDB background extension. 876 Translate ROOT to CALDB background extension.
895 - 877 +
896 The following ROOT histograms are used: 878 The following ROOT histograms are used:
897 - BGRatePerSqDeg_offaxis -> BGD 879 - BGRatePerSqDeg_offaxis -> BGD
898 880
@@ -945,7 +927,7 @@ class csroot2caldb(ctools.cscript): @@ -945,7 +927,7 @@ class csroot2caldb(ctools.cscript):
945 def _append_column_axis(self, hdu, name, unit, axis, log=False): 927 def _append_column_axis(self, hdu, name, unit, axis, log=False):
946 """ 928 """
947 Append column of ROOT axis values to HDU 929 Append column of ROOT axis values to HDU
948 - 930 +
949 Parameters 931 Parameters
950 ---------- 932 ----------
951 hdu : `~gammalib.GFitsHDU` 933 hdu : `~gammalib.GFitsHDU`
@@ -991,7 +973,7 @@ class csroot2caldb(ctools.cscript): @@ -991,7 +973,7 @@ class csroot2caldb(ctools.cscript):
991 def _append_column_values(self, hdu, name, unit, values): 973 def _append_column_values(self, hdu, name, unit, values):
992 """ 974 """
993 Append column of values to HDU 975 Append column of values to HDU
994 - 976 +
995 Parameters 977 Parameters
996 ---------- 978 ----------
997 hdu : `~gammalib.GFitsHDU` 979 hdu : `~gammalib.GFitsHDU`
@@ -1089,7 +1071,7 @@ class csroot2caldb(ctools.cscript): @@ -1089,7 +1071,7 @@ class csroot2caldb(ctools.cscript):
1089 for ioff in range(noffset): 1071 for ioff in range(noffset):
1090 value = hist2D_copy.GetBinContent(ieng+1,ioff+1) / onaxis 1072 value = hist2D_copy.GetBinContent(ieng+1,ioff+1) / onaxis
1091 hist2D_copy.SetBinContent(ieng+1,ioff+1,value) 1073 hist2D_copy.SetBinContent(ieng+1,ioff+1,value)
1092 - 1074 +
1093 # Put back the energy dependence 1075 # Put back the energy dependence
1094 for ieng in range(neng): 1076 for ieng in range(neng):
1095 onaxis = hist1D.GetBinContent(ieng+1) 1077 onaxis = hist1D.GetBinContent(ieng+1)
@@ -1324,7 +1306,7 @@ class csroot2caldb(ctools.cscript): @@ -1324,7 +1306,7 @@ class csroot2caldb(ctools.cscript):
1324 def _make_2D(self, array, hdu, name, unit, scale=1.0): 1306 def _make_2D(self, array, hdu, name, unit, scale=1.0):
1325 """ 1307 """
1326 Make 2D data column as function of energy and offset angle 1308 Make 2D data column as function of energy and offset angle
1327 - 1309 +
1328 If the HDU has already the energy and offset angle columns, this method 1310 If the HDU has already the energy and offset angle columns, this method
1329 will simply add another data column. If name==None, the method will not 1311 will simply add another data column. If name==None, the method will not
1330 append any data column. 1312 append any data column.
@@ -1381,7 +1363,7 @@ class csroot2caldb(ctools.cscript): @@ -1381,7 +1363,7 @@ class csroot2caldb(ctools.cscript):
1381 def _make_3D(self, array, hdu, name, unit): 1363 def _make_3D(self, array, hdu, name, unit):
1382 """ 1364 """
1383 Make 3D data column as function of DETX, DETY and energy 1365 Make 3D data column as function of DETX, DETY and energy
1384 - 1366 +
1385 If the HDU has already the energy and offset angle columns, this method 1367 If the HDU has already the energy and offset angle columns, this method
1386 will simply add another data column. If name==None, the method will not 1368 will simply add another data column. If name==None, the method will not
1387 append any data column. 1369 append any data column.
@@ -1471,7 +1453,7 @@ class csroot2caldb(ctools.cscript): @@ -1471,7 +1453,7 @@ class csroot2caldb(ctools.cscript):
1471 def _make_3D_migra(self, array, hdu, name, unit, scale=1.0): 1453 def _make_3D_migra(self, array, hdu, name, unit, scale=1.0):
1472 """ 1454 """
1473 Make 3D data column as function of ETRUE, MIGRA and THETA 1455 Make 3D data column as function of ETRUE, MIGRA and THETA
1474 - 1456 +
1475 If the HDU has already the energy and offset angle columns, this method 1457 If the HDU has already the energy and offset angle columns, this method
1476 will simply add another data column. If name==None, the method will not 1458 will simply add another data column. If name==None, the method will not
1477 append any data column. 1459 append any data column.
dev/macosx-package.sh 0 → 100755
  1 +#!/bin/bash -f
  2 +# ==========================================================================
  3 +# ctools Mac OS X package creation
  4 +#
  5 +# Copyright (C) 2017 Sylvie Brau-Nogué
  6 +#
  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
  9 +# the Free Software Foundation, either version 3 of the License, or
  10 +# (at your option) any later version.
  11 +#
  12 +# This program is distributed in the hope that it will be useful,
  13 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 +# GNU General Public License for more details.
  16 +#
  17 +# You should have received a copy of the GNU General Public License
  18 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
  19 +#
  20 +# ==========================================================================
  21 +
  22 +# ============================================= #
  23 +# Get ctools/GammaLib version from command line #
  24 +# ============================================= #
  25 +if [ $# -ne 1 ] ; then
  26 + echo "Please specify ctools/GammaLib version in the form x.y.z"
  27 + exit 1
  28 +fi
  29 +VERSION=$1
  30 +
  31 +
  32 +# =============================== #
  33 +# Set software component versions #
  34 +# =============================== #
  35 +CFITSIO=cfitsio3410
  36 +NCURSES=ncurses-6.0
  37 +READLINE=readline-7.0
  38 +GAMMALIB=gammalib-$VERSION
  39 +CTOOLS=ctools-$VERSION
  40 +
  41 +
  42 +# ============== #
  43 +# Set parameters #
  44 +# ============== #
  45 +WRKDIR=$PWD/osxpackage
  46 +INSTALLDIR=$WRKDIR/install
  47 +SRCDIR=$WRKDIR/src
  48 +PKGDIR=$WRKDIR/pkg
  49 +PRODDIR=$WRKDIR/prod
  50 +PLISTFILE=$PKGDIR/$CTOOLS-components.plist
  51 +DISTFILE=$PRODDIR/$CTOOLS.dist
  52 +DMGFILE=$WRKDIR/$CTOOLS-macosx10.7.dmg
  53 +
  54 +
  55 +# ====================== #
  56 +# Clean package creation #
  57 +# ====================== #
  58 +rm -rf $INSTALLDIR
  59 +rm -rf $PKGDIR
  60 +rm -rf $PRODDIR
  61 +rm -rf $DMGFILE
  62 +
  63 +
  64 +# ============================= #
  65 +# Create package directory tree #
  66 +# ============================= #
  67 +mkdir -p $SRCDIR
  68 +mkdir -p $PKGDIR
  69 +mkdir -p $PRODDIR
  70 +
  71 +
  72 +# Make sure that wget is installed
  73 +# TODO: If not installed, execute "brew install wget"
  74 +
  75 +
  76 +# =============== #
  77 +# Install ncurses #
  78 +# =============== #
  79 +cd $SRCDIR
  80 +if [ ! -d "$NCURSES" ]; then
  81 + wget https://ftp.gnu.org/pub/gnu/ncurses/$NCURSES.tar.gz
  82 + tar xvfz $NCURSES.tar.gz
  83 +fi
  84 +cd $NCURSES
  85 +./configure --prefix=$INSTALLDIR --with-shared
  86 +make
  87 +make install
  88 +
  89 +
  90 +# ================ #
  91 +# Install readline #
  92 +# ================ #
  93 +cd $SRCDIR
  94 +if [ ! -d "$READLINE" ]; then
  95 + wget https://ftp.gnu.org/pub/gnu/readline/$READLINE.tar.gz
  96 + tar xvfz $READLINE.tar.gz
  97 +fi
  98 +cd $READLINE
  99 +./configure --prefix=$INSTALLDIR
  100 +make
  101 +make install
  102 +
  103 +
  104 +# =============== #
  105 +# Install cfitsio #
  106 +# =============== #
  107 +cd $SRCDIR
  108 +if [ ! -d "cfitsio" ]; then
  109 + wget http://heasarc.gsfc.nasa.gov/FTP/software/fitsio/c/$CFITSIO.tar.gz
  110 + tar xvfz $CFITSIO.tar.gz
  111 +fi
  112 +cd cfitsio
  113 +./configure --prefix=$INSTALLDIR
  114 +make shared
  115 +make install
  116 +
  117 +
  118 +# ================ #
  119 +# Install GammaLib #
  120 +# ================ #
  121 +cd $SRCDIR
  122 +if [ ! -d "$GAMMALIB" ]; then
  123 + wget http://cta.irap.omp.eu/ctools/releases/gammalib/$GAMMALIB.tar.gz
  124 + tar xvfz $GAMMALIB.tar.gz
  125 +fi
  126 +cd $GAMMALIB
  127 +./configure --prefix=$INSTALLDIR
  128 +make
  129 +make install
  130 +
  131 +
  132 +# ============== #
  133 +# Install ctools #
  134 +# ============== #
  135 +cd $SRCDIR
  136 +if [ ! -d "$CTOOLS" ]; then
  137 + wget http://cta.irap.omp.eu/ctools/releases/ctools/$CTOOLS.tar.gz
  138 + tar xvfz $CTOOLS.tar.gz
  139 +fi
  140 +cd $CTOOLS
  141 +./configure --prefix=$INSTALLDIR
  142 +make
  143 +make install
  144 +
  145 +
  146 +# ====================== #
  147 +# Build Mac OS X package #
  148 +# ====================== #
  149 +pkgbuild --analyze --root $INSTALLDIR $PLISTFILE
  150 +pkgbuild --identifier cta.irap.omp.eu.ctools.pkg \
  151 + --version $VERSION \
  152 + --root $INSTALLDIR \
  153 + --install-location /usr/local/gamma \
  154 + --component-plist $PLISTFILE \
  155 + $PKGDIR/$CTOOLS.pkg
  156 +
  157 +
  158 +# ====================== #
  159 +# Build Mac OS X product #
  160 +# ====================== #
  161 +# Analyse existing package
  162 +productbuild --synthesize \
  163 + --package $PKGDIR/$CTOOLS.pkg \
  164 + $DISTFILE
  165 +
  166 +# Add information to dist file
  167 +sed -i '' '$ i \
  168 +<license file="COPYING"/>\
  169 +<title>'$CTOOLS'</title>\
  170 +<organization>irap.omp.eu</organization>\
  171 +<description>CTA Science Analysis Tools</description>\
  172 +' "$PRODDIR/$CTOOLS.dist"
  173 +
  174 +# Build product
  175 +productbuild --distribution $DISTFILE \
  176 + --version $VERSION \
  177 + --resources $SRCDIR/$CTOOLS \
  178 + --package-path $PKGDIR \
  179 + $PRODDIR/$CTOOLS.pkg
  180 +
  181 +# Add additional files to production folder
  182 +cp $SRCDIR/$CTOOLS/COPYING $PRODDIR/License.txt
  183 +
  184 +# Add ReadMe
  185 +/bin/cat <<EOM >$PRODDIR/ReadMe.txt
  186 +This package will install
  187 +
  188 + ctools-$VERSION and gammalib-$VERSION
  189 +
  190 +for Mac OS X 10.7 or later.
  191 +
  192 +Installation requires approximately 260 MB of disk space. The package
  193 +will be installed in the directory /usr/local/gamma, hence you need
  194 +administrator privileges to do the install.
  195 +
  196 +Simply click on the installer package and follow the instructions.
  197 +The installation will take less than one minute.
  198 +
  199 +After installing the package, you have to initialise the ctools
  200 +environment. This will be done by invoking an initialisation script
  201 +that can be found in the /usr/local/gamma/bin directory.
  202 +
  203 +To invoke this script you need to add the following to your .bashrc
  204 +or $HOME/.profile script:
  205 +
  206 + export CTOOLS=/usr/local/gamma
  207 + source \$CTOOLS/bin/gammalib-init.sh
  208 +
  209 +If you use C shell or a variant then add the following to your
  210 +.cshrc or .tcshrc script:
  211 +
  212 + setenv CTOOLS /usr/local/gamma
  213 + source \$CTOOLS/bin/gammalib-init.csh
  214 +
  215 +More information on ctools can be found at
  216 +http://cta.irap.omp.eu/ctools/.
  217 +
  218 +If you encounter problems in installing or using this package, please
  219 +send your error report to jurgen.knodlseder@irap.omp.eu. In your report,
  220 +please specify your Mac OS X version and Python version and the problem
  221 +you're facing.
  222 +EOM
  223 +
  224 +
  225 +
  226 +# ==================== #
  227 +# Create Mac OS X disk #
  228 +# ==================== #
  229 +hdiutil create -volname $CTOOLS \
  230 + -srcfolder $PRODDIR/$CTOOLS.pkg \
  231 + -srcfolder $PRODDIR/License.txt \
  232 + -srcfolder $PRODDIR/ReadMe.txt \
  233 + $DMGFILE
examples/Makefile.am
@@ -39,6 +39,7 @@ scripts = README.md \ @@ -39,6 +39,7 @@ scripts = README.md \
39 show_response.py \ 39 show_response.py \
40 show_sensitivity.py \ 40 show_sensitivity.py \
41 show_spectrum.py \ 41 show_spectrum.py \
  42 + show_lightcurve.py \
42 show_ts_distribution.py \ 43 show_ts_distribution.py \
43 show_obs.py 44 show_obs.py
44 45
examples/README.md
@@ -70,5 +70,8 @@ the ctools. @@ -70,5 +70,8 @@ the ctools.
70 `show_spectrum.py` 70 `show_spectrum.py`
71 > Displays spectrum generated by the csspec script. 71 > Displays spectrum generated by the csspec script.
72 72
  73 +`show_lightcurve.py`
  74 +> Displays lightcurve generated by the cslightcrv script.
  75 +
73 `show_ts_distribution.py` 76 `show_ts_distribution.py`
74 > Displays Test Statistic histograms generated using the cstsdist script. 77 > Displays Test Statistic histograms generated using the cstsdist script.
examples/show_lightcurve.py 0 → 100755
  1 +#! /usr/bin/env python
  2 +# ==========================================================================
  3 +# Display lightcurve generated by cslightcrv
  4 +#
  5 +# Copyright (C) 2017 Juergen Knoedlseder
  6 +#
  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
  9 +# the Free Software Foundation, either version 3 of the License, or
  10 +# (at your option) any later version.
  11 +#
  12 +# This program is distributed in the hope that it will be useful,
  13 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 +# GNU General Public License for more details.
  16 +#
  17 +# You should have received a copy of the GNU General Public License
  18 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
  19 +#
  20 +# ==========================================================================
  21 +import sys
  22 +import gammalib
  23 +import cscripts
  24 +try:
  25 + import matplotlib.pyplot as plt
  26 + plt.figure()
  27 + plt.close()
  28 +except (ImportError, RuntimeError):
  29 + print('This script needs the "matplotlib" module')
  30 + sys.exit()
  31 +
  32 +
  33 +# =============== #
  34 +# Plot lightcurve #
  35 +# =============== #
  36 +def plot_lightcurve(filename, plotfile):
  37 + """
  38 + Plot lightcurve
  39 +
  40 + Parameters
  41 + ----------
  42 + filename : str
  43 + Name of lightcurve FITS file
  44 + plotfile : str
  45 + Plot file name
  46 + """
  47 + # Read spectrum file
  48 + fits = gammalib.GFits(filename)
  49 + table = fits.table(1)
  50 + c_mjd = table['MJD']
  51 + c_emjd = table['e_MJD']
  52 + c_flux = table['EnergyFlux']
  53 + c_eflux = table['e_EnergyFlux']
  54 + c_ts = table['TS']
  55 + c_upper = table['EFluxUpperLimit']
  56 +
  57 + # Initialise arrays to be filled
  58 + mjd = []
  59 + e_mjd = []
  60 + flux = []
  61 + e_flux = []
  62 + ul_mjd = []
  63 + ul_e_mjd = []
  64 + ul_flux = []
  65 + ul_e_flux = []
  66 +
  67 + # Loop over rows of the file
  68 + nrows = table.nrows()
  69 + for row in range(nrows):
  70 +
  71 + # Get Test Statistic, flux and flux error
  72 + ts = c_ts.real(row)
  73 + flx = c_flux.real(row)
  74 + e_flx = c_eflux.real(row)
  75 +
  76 + # If Test Statistic is larger than 9 and twice the flux error is
  77 + # smaller than the flux, then append flux point ...
  78 + if ts > 9.0 and 2.0*e_flx < flx:
  79 + mjd.append(c_mjd.real(row))
  80 + e_mjd.append(c_emjd.real(row))
  81 + flux.append(c_flux.real(row))
  82 + e_flux.append(c_eflux.real(row))
  83 +
  84 + # ... otherwise append upper limit
  85 + else:
  86 + ul_mjd.append(c_mjd.real(row))
  87 + ul_e_mjd.append(c_emjd.real(row))
  88 + ul_flux.append(c_upper.real(row))
  89 + ul_e_flux.append(0.5*c_upper.real(row))
  90 +
  91 + # Plot the spectrum
  92 + plt.figure()
  93 + plt.semilogy()
  94 + plt.grid()
  95 + plt.errorbar(mjd, flux, yerr=e_flux, xerr=[e_mjd, e_mjd],
  96 + fmt='ro')
  97 + plt.errorbar(ul_mjd, ul_flux, xerr=[ul_e_mjd, ul_e_mjd],
  98 + yerr=ul_e_flux, uplims=True, fmt='ro')
  99 + plt.xlabel('MJD (days)')
  100 + plt.ylabel(r'E $\times$ dN/dE (erg cm$^{-2}$ s$^{-1}$)')
  101 +
  102 + # Show figure
  103 + if len(plotfile) > 0:
  104 + plt.savefig(plotfile)
  105 + else:
  106 + plt.show()
  107 +
  108 + # Return
  109 + return
  110 +
  111 +
  112 +# =============== #
  113 +# Show lightcurve #
  114 +# =============== #
  115 +def show_lightcurve():
  116 + """
  117 + Show lightcurve
  118 + """
  119 + # Set usage string
  120 + usage = 'show_lightcurve.py [-p plotfile] [file]'
  121 +
  122 + # Set default options
  123 + options = [{'option': '-p', 'value': ''}]
  124 +
  125 + # Get arguments and options from command line arguments
  126 + args, options = cscripts.ioutils.get_args_options(options, usage)
  127 +
  128 + # Extract script parameters from options
  129 + plotfile = options[0]['value']
  130 +
  131 + # Plot lightcurve
  132 + plot_lightcurve(args[0], plotfile)
  133 +
  134 + # Return
  135 + return
  136 +
  137 +
  138 +# ======================== #
  139 +# Main routine entry point #
  140 +# ======================== #
  141 +if __name__ == '__main__':
  142 +
  143 + # Show lightcurve
  144 + show_lightcurve()
examples/show_spectrum.py
@@ -35,7 +35,7 @@ except (ImportError, RuntimeError): @@ -35,7 +35,7 @@ except (ImportError, RuntimeError):
35 # ============= # 35 # ============= #
36 def plot_spectrum(filename, plotfile): 36 def plot_spectrum(filename, plotfile):
37 """ 37 """
38 - Plot sensitivity data 38 + Plot spectrum
39 39
40 Parameters 40 Parameters
41 ---------- 41 ----------
src/ctulimit/ctulimit.cpp
@@ -248,6 +248,9 @@ void ctulimit::run(void) @@ -248,6 +248,9 @@ void ctulimit::run(void)
248 // Write header into logger 248 // Write header into logger
249 log_header1(TERSE, "Compute best-fit likelihood"); 249 log_header1(TERSE, "Compute best-fit likelihood");
250 250
  251 + // Make sure that requested model parameters is free
  252 + m_model_par->free();
  253 +
251 // Optimize and save best log-likelihood 254 // Optimize and save best log-likelihood
252 m_obs.optimize(m_opt); 255 m_obs.optimize(m_opt);
253 m_obs.errors(m_opt); 256 m_obs.errors(m_opt);
@@ -610,6 +613,9 @@ void ctulimit::ulimit_bisection(const double&amp; min, const double&amp; max) @@ -610,6 +613,9 @@ void ctulimit::ulimit_bisection(const double&amp; min, const double&amp; max)
610 if (std::abs(eval_mid) < m_tol) { 613 if (std::abs(eval_mid) < m_tol) {
611 break; 614 break;
612 } 615 }
  616 + if (std::abs(wrk_max-wrk_min) < m_tol) {
  617 + break;
  618 + }
613 619
614 // Change boundaries for further iteration 620 // Change boundaries for further iteration
615 if (eval_mid > 0.0) { 621 if (eval_mid > 0.0) {
test/data/lightcurve.fits 0 → 100644
No preview for this file type
test/test_cslightcrv.py
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 # ========================================================================== 2 # ==========================================================================
3 # This scripts performs unit tests for the cslightcrv script. 3 # This scripts performs unit tests for the cslightcrv script.
4 # 4 #
5 -# Copyright (C) 2016 Juergen Knoedlseder 5 +# Copyright (C) 2016-2017 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
@@ -239,7 +239,8 @@ class Test(test): @@ -239,7 +239,8 @@ class Test(test):
239 """ 239 """
240 # Expected column names 240 # Expected column names
241 cols = ['MJD', 'e_MJD', 'Prefactor', 'e_Prefactor', 241 cols = ['MJD', 'e_MJD', 'Prefactor', 'e_Prefactor',
242 - 'Index', 'e_Index', 'TS', 'UpperLimit'] 242 + 'Index', 'e_Index', 'TS', 'DiffUpperLimit',
  243 + 'FluxUpperLimit', 'EFluxUpperLimit']
243 244
244 # Open FITS file 245 # Open FITS file
245 fits = gammalib.GFits(filename) 246 fits = gammalib.GFits(filename)
test/test_examples.py.in
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 # ========================================================================== 2 # ==========================================================================
3 # Performs unit tests for the ctools example scripts 3 # Performs unit tests for the ctools example scripts
4 # 4 #
5 -# Copyright (C) 2016 Juergen Knoedlseder 5 +# Copyright (C) 2016-2017 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
@@ -128,6 +128,8 @@ class Test(gammalib.GPythonTestSuite): @@ -128,6 +128,8 @@ class Test(gammalib.GPythonTestSuite):
128 'Test show_sensitivity.py') 128 'Test show_sensitivity.py')
129 self.append(self.test_show_spectrum, 129 self.append(self.test_show_spectrum,
130 'Test show_spectrum.py') 130 'Test show_spectrum.py')
  131 + self.append(self.test_show_lightcurve,
  132 + 'Test show_lightcurve.py')
131 self.append(self.test_show_ts_distribution, 133 self.append(self.test_show_ts_distribution,
132 'Test ts_distribution.py') 134 'Test ts_distribution.py')
133 self.append(self.test_show_obs, 135 self.append(self.test_show_obs,
@@ -401,6 +403,20 @@ class Test(gammalib.GPythonTestSuite): @@ -401,6 +403,20 @@ class Test(gammalib.GPythonTestSuite):
401 # Return 403 # Return
402 return 404 return
403 405
  406 + # Test show_lightcurve
  407 + def test_show_lightcurve(self):
  408 + """
  409 + Test show_lightcurve
  410 + """
  411 + # Set arguments
  412 + args = '-p example_show_lightcurve.eps %s/lightcurve.fits' % self._datadir
  413 +
  414 + # Execute script
  415 + self._execute_python('show_lightcurve', args=args)
  416 +
  417 + # Return
  418 + return
  419 +
404 # Test show_ts_distribution 420 # Test show_ts_distribution
405 def test_show_ts_distribution(self): 421 def test_show_ts_distribution(self):
406 """ 422 """