Commit 152493f86c0342a85aabb0c88ee0da2b2856d5e9

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

Merge branch 'integration' into 1920-fix-cslightcrv

# Conflicts:
#	NEWS
1 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 6 Introduction
... ... @@ -195,6 +195,9 @@ in particular the "PhotonFlux" and "EnergyFlux" names (#1832).
195 195  
196 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 202 cterror - Likelihood profile error computation
200 203 ----------------------------------------------
... ... @@ -235,10 +238,14 @@ Add cssrcdetect script to detect sources in a sky map (#1617).
235 238 The "ds9file" parameters were changed to "outds9file" to be consistent with
236 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 246 Examples
240 247 --------
241   -None
  248 +Add show_lightcurve script to display a light curve.
242 249  
243 250  
244 251 caldb
... ...
cscripts/Makefile.am
... ... @@ -166,6 +166,7 @@ testdata = $(top_srcdir)/test/data/crab.xml \
166 166 $(top_srcdir)/test/data/sensitivity_integral.dat \
167 167 $(top_srcdir)/test/data/skymap.fits \
168 168 $(top_srcdir)/test/data/spectrum.fits \
  169 + $(top_srcdir)/test/data/lightcurve.fits \
169 170 $(top_srcdir)/test/data/ts.dat \
170 171 $(top_srcdir)/test/data/models_spatial.xml \
171 172 $(top_srcdir)/test/data/models_spectral.xml \
... ...
cscripts/cslightcrv.py
... ... @@ -2,7 +2,7 @@
2 2 # ==========================================================================
3 3 # Generates a lightcurve.
4 4 #
5   -# Copyright (C) 2014-2016 Michael Mayer
  5 +# Copyright (C) 2014-2017 Michael Mayer
6 6 #
7 7 # This program is free software: you can redistribute it and/or modify
8 8 # it under the terms of the GNU General Public License as published by
... ... @@ -69,7 +69,7 @@ class cslightcrv(ctools.cscript):
69 69 """
70 70 # Set name
71 71 self._name = 'cslightcrv'
72   - self._version = '1.2.0'
  72 + self._version = '1.3.0'
73 73  
74 74 # Initialise some members
75 75 self._srcname = ''
... ... @@ -335,18 +335,26 @@ class cslightcrv(ctools.cscript):
335 335 table.append(ts)
336 336  
337 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 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 352 # Return table
345 353 return table
346 354  
347 355 def _compute_ulimit(self, obs):
348 356 """
349   - Computes upper flux limit
  357 + Computes upper limit
350 358  
351 359 Parameters
352 360 ----------
... ... @@ -355,35 +363,57 @@ class cslightcrv(ctools.cscript):
355 363  
356 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 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 374 # Perform computation only if requested
365 375 if self['calc_ulim'].boolean():
366 376  
367 377 # Write header in logger
368 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 403 try:
378 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 408 except:
381 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 418 def _bin_observation(self, obs):
389 419 """
... ... @@ -517,7 +547,9 @@ class cslightcrv(ctools.cscript):
517 547 result = {'mjd': tmean.mjd(),
518 548 'e_mjd': twidth / gammalib.sec_in_day,
519 549 'ts': 0.0,
520   - 'ulimit': 0.0,
  550 + 'ul_diff': 0.0,
  551 + 'ul_flux': 0.0,
  552 + 'ul_eflux': 0.0,
521 553 'pars': pars,
522 554 'values': {}}
523 555  
... ... @@ -581,9 +613,12 @@ class cslightcrv(ctools.cscript):
581 613 result['values']['e_'+par] = source[par].error()
582 614  
583 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 623 # Extract Test Statistic value
589 624 if self['calc_ts'].boolean():
... ... @@ -601,9 +636,13 @@ class cslightcrv(ctools.cscript):
601 636 unit = source[par].unit()
602 637 self._log_value(gammalib.NORMAL, par,
603 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 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 646 if self['calc_ts'].boolean():
608 647 self._log_value(gammalib.NORMAL, 'Test Statistic', result['ts'])
609 648  
... ...
cscripts/csroot2caldb.py
... ... @@ -146,7 +146,7 @@ class csroot2caldb(ctools.cscript):
146 146 def _make_dirs(self, version, irf):
147 147 """
148 148 Generate CALDB directory structure for one observation identifier
149   -
  149 +
150 150 The structure is given by
151 151  
152 152 data/<tel>/<inst>/bcf/<obsid>
... ... @@ -227,7 +227,7 @@ class csroot2caldb(ctools.cscript):
227 227 def _open(self, irf, ds):
228 228 """
229 229 Open existing or create new calibration
230   -
  230 +
231 231 The actual version will put all calibrations in the same file, although
232 232 each part of the response function will have its own logical name. We
233 233 can thus easily modify the script to put each calibration information
... ... @@ -322,7 +322,7 @@ class csroot2caldb(ctools.cscript):
322 322 def _open_hdu(self, fits, extname, name, doc, irf):
323 323 """
324 324 Open HDU
325   -
  325 +
326 326 Opens a FITS binary table with given "extname". If HDU does not exist
327 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 534 def _root2ea(self, tfile, irf, ds):
535 535 """
536 536 Translate ROOT to CALDB effective area extension
537   -
  537 +
538 538 The following ROOT histograms are used:
539 539 - EffectiveAreaEtrue_offaxis -> EFFAREA
540   - - EffectiveArea_offaxis -> EFFAREA_RECO
541 540  
542 541 Parameters
543 542 ----------
... ... @@ -555,16 +554,13 @@ class csroot2caldb(ctools.cscript):
555 554  
556 555 # Get relevant ROOT histograms
557 556 etrue = tfile.Get('EffectiveAreaEtrue_offaxis')
558   - ereco = tfile.Get('EffectiveArea_offaxis')
559 557  
560 558 # If requested then normalize the 2D histogram on the on-axis 1D
561 559 # histogram. This assures that the 2D histogram has the same on-axis
562 560 # effective area dependence as the 1D histogram.
563 561 if self['norm1d'].boolean():
564 562 etrue_1D = tfile.Get('EffectiveAreaEtrue')
565   - ereco_1D = tfile.Get('EffectiveArea')
566 563 self._renorm_onaxis(etrue, etrue_1D)
567   - self._renorm_onaxis(ereco, ereco_1D)
568 564  
569 565 # If requested then rebin the effective area Etrue histogram. This
570 566 # increases the number of bins by a factor 10.
... ... @@ -589,17 +585,6 @@ class csroot2caldb(ctools.cscript):
589 585 for ieng in range(neng):
590 586 value = etrue.GetBinContent(ieng+1,ioff+1) * eascale
591 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 589 # Write boundary keywords
605 590 self._set_cif_keywords(ds['HDU_EA'], irf['EA_NAME'],
... ... @@ -608,16 +593,13 @@ class csroot2caldb(ctools.cscript):
608 593 # Create "EFFAREA" data column
609 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 596 # Return
615 597 return
616 598  
617 599 def _root2psf(self, tfile, irf, ds):
618 600 """
619 601 Translate ROOT to CALDB point spread function extension
620   -
  602 +
621 603 Parameters
622 604 ----------
623 605 tfile : `~ROOT.TFile`
... ... @@ -646,7 +628,7 @@ class csroot2caldb(ctools.cscript):
646 628 def _root2psf_gauss(self, tfile, irf, ds):
647 629 """
648 630 Translate ROOT to CALDB point spread function extension
649   -
  631 +
650 632 The following ROOT histograms are used:
651 633 - 1/(2*pi*SIGMA_1) -> SCALE
652 634 - AngRes_offaxis -> SIGMA_1 (scaling: 1/0.8)
... ... @@ -729,7 +711,7 @@ class csroot2caldb(ctools.cscript):
729 711 def _root2psf_king(self, tfile, irf, ds):
730 712 """
731 713 Translate ROOT to CALDB point spread function extension
732   -
  714 +
733 715 The following ROOT histograms are used:
734 716 - AngRes_offaxis
735 717 - AngRes80_offaxis
... ... @@ -853,7 +835,7 @@ class csroot2caldb(ctools.cscript):
853 835 def _root2edisp(self, tfile, irf, ds):
854 836 """
855 837 Translate ROOT to CALDB energy dispersion extension
856   -
  838 +
857 839 The following ROOT histograms are used:
858 840 - EestOverEtrue_offaxis -> MATRIX
859 841  
... ... @@ -892,7 +874,7 @@ class csroot2caldb(ctools.cscript):
892 874 def _root2bgd(self, tfile, irf, ds):
893 875 """
894 876 Translate ROOT to CALDB background extension.
895   -
  877 +
896 878 The following ROOT histograms are used:
897 879 - BGRatePerSqDeg_offaxis -> BGD
898 880  
... ... @@ -945,7 +927,7 @@ class csroot2caldb(ctools.cscript):
945 927 def _append_column_axis(self, hdu, name, unit, axis, log=False):
946 928 """
947 929 Append column of ROOT axis values to HDU
948   -
  930 +
949 931 Parameters
950 932 ----------
951 933 hdu : `~gammalib.GFitsHDU`
... ... @@ -991,7 +973,7 @@ class csroot2caldb(ctools.cscript):
991 973 def _append_column_values(self, hdu, name, unit, values):
992 974 """
993 975 Append column of values to HDU
994   -
  976 +
995 977 Parameters
996 978 ----------
997 979 hdu : `~gammalib.GFitsHDU`
... ... @@ -1089,7 +1071,7 @@ class csroot2caldb(ctools.cscript):
1089 1071 for ioff in range(noffset):
1090 1072 value = hist2D_copy.GetBinContent(ieng+1,ioff+1) / onaxis
1091 1073 hist2D_copy.SetBinContent(ieng+1,ioff+1,value)
1092   -
  1074 +
1093 1075 # Put back the energy dependence
1094 1076 for ieng in range(neng):
1095 1077 onaxis = hist1D.GetBinContent(ieng+1)
... ... @@ -1324,7 +1306,7 @@ class csroot2caldb(ctools.cscript):
1324 1306 def _make_2D(self, array, hdu, name, unit, scale=1.0):
1325 1307 """
1326 1308 Make 2D data column as function of energy and offset angle
1327   -
  1309 +
1328 1310 If the HDU has already the energy and offset angle columns, this method
1329 1311 will simply add another data column. If name==None, the method will not
1330 1312 append any data column.
... ... @@ -1381,7 +1363,7 @@ class csroot2caldb(ctools.cscript):
1381 1363 def _make_3D(self, array, hdu, name, unit):
1382 1364 """
1383 1365 Make 3D data column as function of DETX, DETY and energy
1384   -
  1366 +
1385 1367 If the HDU has already the energy and offset angle columns, this method
1386 1368 will simply add another data column. If name==None, the method will not
1387 1369 append any data column.
... ... @@ -1471,7 +1453,7 @@ class csroot2caldb(ctools.cscript):
1471 1453 def _make_3D_migra(self, array, hdu, name, unit, scale=1.0):
1472 1454 """
1473 1455 Make 3D data column as function of ETRUE, MIGRA and THETA
1474   -
  1456 +
1475 1457 If the HDU has already the energy and offset angle columns, this method
1476 1458 will simply add another data column. If name==None, the method will not
1477 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 39 show_response.py \
40 40 show_sensitivity.py \
41 41 show_spectrum.py \
  42 + show_lightcurve.py \
42 43 show_ts_distribution.py \
43 44 show_obs.py
44 45  
... ...
examples/README.md
... ... @@ -70,5 +70,8 @@ the ctools.
70 70 `show_spectrum.py`
71 71 > Displays spectrum generated by the csspec script.
72 72  
  73 +`show_lightcurve.py`
  74 +> Displays lightcurve generated by the cslightcrv script.
  75 +
73 76 `show_ts_distribution.py`
74 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 35 # ============= #
36 36 def plot_spectrum(filename, plotfile):
37 37 """
38   - Plot sensitivity data
  38 + Plot spectrum
39 39  
40 40 Parameters
41 41 ----------
... ...
src/ctulimit/ctulimit.cpp
... ... @@ -248,6 +248,9 @@ void ctulimit::run(void)
248 248 // Write header into logger
249 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 254 // Optimize and save best log-likelihood
252 255 m_obs.optimize(m_opt);
253 256 m_obs.errors(m_opt);
... ... @@ -610,6 +613,9 @@ void ctulimit::ulimit_bisection(const double&amp; min, const double&amp; max)
610 613 if (std::abs(eval_mid) < m_tol) {
611 614 break;
612 615 }
  616 + if (std::abs(wrk_max-wrk_min) < m_tol) {
  617 + break;
  618 + }
613 619  
614 620 // Change boundaries for further iteration
615 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 2 # ==========================================================================
3 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 7 # This program is free software: you can redistribute it and/or modify
8 8 # it under the terms of the GNU General Public License as published by
... ... @@ -239,7 +239,8 @@ class Test(test):
239 239 """
240 240 # Expected column names
241 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 245 # Open FITS file
245 246 fits = gammalib.GFits(filename)
... ...
test/test_examples.py.in
... ... @@ -2,7 +2,7 @@
2 2 # ==========================================================================
3 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 7 # This program is free software: you can redistribute it and/or modify
8 8 # it under the terms of the GNU General Public License as published by
... ... @@ -128,6 +128,8 @@ class Test(gammalib.GPythonTestSuite):
128 128 'Test show_sensitivity.py')
129 129 self.append(self.test_show_spectrum,
130 130 'Test show_spectrum.py')
  131 + self.append(self.test_show_lightcurve,
  132 + 'Test show_lightcurve.py')
131 133 self.append(self.test_show_ts_distribution,
132 134 'Test ts_distribution.py')
133 135 self.append(self.test_show_obs,
... ... @@ -401,6 +403,20 @@ class Test(gammalib.GPythonTestSuite):
401 403 # Return
402 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 420 # Test show_ts_distribution
405 421 def test_show_ts_distribution(self):
406 422 """
... ...