Commit cfe3f28204f9d2665a79a22a8d49d182e33392ca
1 parent
06ae0bbb
Add csebins script (#1976)
Showing
11 changed files
with
619 additions
and
6 deletions
ChangeLog
| 1 | -2017-03-21 | 1 | +2017-03-22 |
| 2 | 2 | ||
| 3 | * Version 1.3.0 released | 3 | * Version 1.3.0 released |
| 4 | ======================== | 4 | ======================== |
| 5 | 5 | ||
| 6 | + Add csebins script (#1976) | ||
| 6 | Take into account RoI in ctskymap and use numerical integration for IRF (#1975) | 7 | Take into account RoI in ctskymap and use numerical integration for IRF (#1975) |
| 7 | Set local language to english (#1370) | 8 | Set local language to english (#1370) |
| 8 | Enhance logfile output of csroot2caldb script | 9 | Enhance logfile output of csroot2caldb script |
NEWS
| 1 | New Features and Important Changes in ctools 1.3.0.dev1 | 1 | New Features and Important Changes in ctools 1.3.0.dev1 |
| 2 | 2 | ||
| 3 | -21 March 2017 | 3 | +22 March 2017 |
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | Introduction | 6 | Introduction |
| @@ -112,7 +112,10 @@ None | @@ -112,7 +112,10 @@ None | ||
| 112 | 112 | ||
| 113 | cscripts | 113 | cscripts |
| 114 | -------- | 114 | -------- |
| 115 | -None | 115 | +The csebins script has been added that generates an energy boundaries |
| 116 | +extension that can be used for a stacked analysis. The energy boundaries | ||
| 117 | +are set as function of the variation in the effective area and background | ||
| 118 | +rates of the Instrument Response Function (#1976). | ||
| 116 | 119 | ||
| 117 | 120 | ||
| 118 | Examples | 121 | Examples |
cscripts/Makefile.am
| @@ -22,6 +22,7 @@ | @@ -22,6 +22,7 @@ | ||
| 22 | # Scripts to be distributed in $(pyexecdir)/cscripts | 22 | # Scripts to be distributed in $(pyexecdir)/cscripts |
| 23 | pythonscripts = $(top_builddir)/cscripts/__init__.py \ | 23 | pythonscripts = $(top_builddir)/cscripts/__init__.py \ |
| 24 | $(srcdir)/cscaldb.py \ | 24 | $(srcdir)/cscaldb.py \ |
| 25 | + $(srcdir)/csebins.py \ | ||
| 25 | $(srcdir)/csinfo.py \ | 26 | $(srcdir)/csinfo.py \ |
| 26 | $(srcdir)/cslightcrv.py \ | 27 | $(srcdir)/cslightcrv.py \ |
| 27 | $(srcdir)/csmodelinfo.py \ | 28 | $(srcdir)/csmodelinfo.py \ |
| @@ -53,6 +54,7 @@ pythonscripts = $(top_builddir)/cscripts/__init__.py \ | @@ -53,6 +54,7 @@ pythonscripts = $(top_builddir)/cscripts/__init__.py \ | ||
| 53 | 54 | ||
| 54 | # Parfiles to be distributed in $(prefix)/syspfiles | 55 | # Parfiles to be distributed in $(prefix)/syspfiles |
| 55 | parfiles = $(srcdir)/cscaldb.par \ | 56 | parfiles = $(srcdir)/cscaldb.par \ |
| 57 | + $(srcdir)/csebins.par \ | ||
| 56 | $(srcdir)/cslightcrv.par \ | 58 | $(srcdir)/cslightcrv.par \ |
| 57 | $(srcdir)/csmodelinfo.par \ | 59 | $(srcdir)/csmodelinfo.par \ |
| 58 | $(srcdir)/csmodelmerge.par \ | 60 | $(srcdir)/csmodelmerge.par \ |
| @@ -79,6 +81,7 @@ parfiles = $(srcdir)/cscaldb.par \ | @@ -79,6 +81,7 @@ parfiles = $(srcdir)/cscaldb.par \ | ||
| 79 | 81 | ||
| 80 | # Scripts for which symbolic links will be created in bindir | 82 | # Scripts for which symbolic links will be created in bindir |
| 81 | linkscripts = cscaldb \ | 83 | linkscripts = cscaldb \ |
| 84 | + csebins \ | ||
| 82 | csinfo \ | 85 | csinfo \ |
| 83 | cslightcrv \ | 86 | cslightcrv \ |
| 84 | csmodelinfo \ | 87 | csmodelinfo \ |
cscripts/__init__.py.in
| @@ -25,6 +25,7 @@ cur_version = sys.version_info | @@ -25,6 +25,7 @@ cur_version = sys.version_info | ||
| 25 | # List all scripts in this module | 25 | # List all scripts in this module |
| 26 | __all__ = [ | 26 | __all__ = [ |
| 27 | "cscaldb", | 27 | "cscaldb", |
| 28 | + "csebins", | ||
| 28 | "csinfo", | 29 | "csinfo", |
| 29 | "cslightcrv", | 30 | "cslightcrv", |
| 30 | "csmodelinfo", | 31 | "csmodelinfo", |
| @@ -59,6 +60,7 @@ if cur_version > req_version: | @@ -59,6 +60,7 @@ if cur_version > req_version: | ||
| 59 | # Import | 60 | # Import |
| 60 | from cscripts.cscaldb import cscaldb | 61 | from cscripts.cscaldb import cscaldb |
| 61 | from cscripts.csinfo import csinfo | 62 | from cscripts.csinfo import csinfo |
| 63 | +from cscripts.csebins import csebins | ||
| 62 | from cscripts.cslightcrv import cslightcrv | 64 | from cscripts.cslightcrv import cslightcrv |
| 63 | from cscripts.csmodelinfo import csmodelinfo | 65 | from cscripts.csmodelinfo import csmodelinfo |
| 64 | from cscripts.csmodelmerge import csmodelmerge | 66 | from cscripts.csmodelmerge import csmodelmerge |
cscripts/csebins.par
0 → 100644
| 1 | +############################################################################# | ||
| 2 | +# # | ||
| 3 | +# CTA Science Analysis Tools # | ||
| 4 | +# # | ||
| 5 | +# ------------------------------------------------------------------------- # | ||
| 6 | +# # | ||
| 7 | +# File: csebins.par # | ||
| 8 | +# # | ||
| 9 | +# Author: Juergen Knoedlseder # | ||
| 10 | +# Jurgen.Knodlseder@irap.omp.eu # | ||
| 11 | +# IRAP # | ||
| 12 | +# # | ||
| 13 | +# Purpose: Parameter file for the csebins script # | ||
| 14 | +# # | ||
| 15 | +############################################################################# | ||
| 16 | +# | ||
| 17 | +# Input and output parameters | ||
| 18 | +#============================ | ||
| 19 | +inobs, f, a, NONE,,, "Input observation definition XML file" | ||
| 20 | +caldb, s, a, prod2,,, "Calibration database" | ||
| 21 | +irf, s, a, South_0.5h,,, "Instrument response function" | ||
| 22 | +outfile, f, a, ebounds.fits,,, "Output energy boundaries file" | ||
| 23 | + | ||
| 24 | +# | ||
| 25 | +# Script parameters | ||
| 26 | +#================== | ||
| 27 | +emin, r, a, 0.02,,, "Minimum energy (TeV)" | ||
| 28 | +emax, r, a, 300.0,,, "Maximum energy (TeV)" | ||
| 29 | +aeffthres, r, h, 0.2,,, "Fractional effective area change threshold" | ||
| 30 | +bkgthres, r, h, 0.5,,, "Fractional background rate change threshold" | ||
| 31 | + | ||
| 32 | +# | ||
| 33 | +# Standard parameters | ||
| 34 | +#==================== | ||
| 35 | +chatter, i, h, 2,0,4, "Chattiness of output" | ||
| 36 | +clobber, b, h, yes,,, "Overwrite existing output files with new output files?" | ||
| 37 | +debug, b, h, no,,, "Debugging mode activated" | ||
| 38 | +mode, s, h, ql,,, "Mode of automatic parameters" | ||
| 39 | +logfile, f, h, csebins.log,,, "Log filename" |
cscripts/csebins.py
0 → 100755
| 1 | +#! /usr/bin/env python | ||
| 2 | +# ========================================================================== | ||
| 3 | +# Generates energy boundaries for stacked analysis | ||
| 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 math | ||
| 23 | +import gammalib | ||
| 24 | +import ctools | ||
| 25 | +#from cscripts import obsutils | ||
| 26 | + | ||
| 27 | + | ||
| 28 | +# ============= # | ||
| 29 | +# csebins class # | ||
| 30 | +# ============= # | ||
| 31 | +class csebins(ctools.cscript): | ||
| 32 | + """ | ||
| 33 | + Generates energy boundaries for stacked analysis | ||
| 34 | + """ | ||
| 35 | + | ||
| 36 | + # Constructor | ||
| 37 | + def __init__(self, *argv): | ||
| 38 | + """ | ||
| 39 | + Constructor | ||
| 40 | + """ | ||
| 41 | + # Set name and version | ||
| 42 | + self._name = 'csebins' | ||
| 43 | + self._version = '1.0.0' | ||
| 44 | + | ||
| 45 | + # Set members | ||
| 46 | + self._ebounds = gammalib.GEbounds() | ||
| 47 | + | ||
| 48 | + # Initialise observation container from constructor arguments. | ||
| 49 | + self._obs, argv = self._set_input_obs(argv) | ||
| 50 | + | ||
| 51 | + # Initialise script by calling the appropriate class constructor. | ||
| 52 | + self._init_cscript(argv) | ||
| 53 | + | ||
| 54 | + # Return | ||
| 55 | + return | ||
| 56 | + | ||
| 57 | + | ||
| 58 | + # Private methods | ||
| 59 | + def _get_parameters(self): | ||
| 60 | + """ | ||
| 61 | + Get parameters from parfile | ||
| 62 | + """ | ||
| 63 | + # Initialise observation container if it is currently empty | ||
| 64 | + if self._obs.size() == 0: | ||
| 65 | + | ||
| 66 | + # Query "inobs" parameter | ||
| 67 | + filename = self['inobs'].filename() | ||
| 68 | + | ||
| 69 | + # If an observation definition file was provided then load it, | ||
| 70 | + # otherwise build a single observation with response information | ||
| 71 | + if self._is_valid_filename(filename): | ||
| 72 | + self._obs = gammalib.GObservations(filename) | ||
| 73 | + else: | ||
| 74 | + cta = gammalib.GCTAObservation() | ||
| 75 | + caldb = gammalib.GCaldb('cta', self['caldb'].string()) | ||
| 76 | + rsp = gammalib.GCTAResponseIrf(self['irf'].string(), caldb) | ||
| 77 | + cta.response(rsp) | ||
| 78 | + self._obs.append(cta) | ||
| 79 | + | ||
| 80 | + # Query input parameters | ||
| 81 | + self['emin'].real() | ||
| 82 | + self['emax'].real() | ||
| 83 | + self['aeffthres'].real() | ||
| 84 | + self['bkgthres'].real() | ||
| 85 | + | ||
| 86 | + # Query ahead output model filename | ||
| 87 | + if self._read_ahead(): | ||
| 88 | + self['outfile'].filename() | ||
| 89 | + | ||
| 90 | + # Write input parameters into logger | ||
| 91 | + self._log_parameters(gammalib.TERSE) | ||
| 92 | + | ||
| 93 | + # Return | ||
| 94 | + return | ||
| 95 | + | ||
| 96 | + def _insert_energy(self, responses, energy, comment): | ||
| 97 | + """ | ||
| 98 | + Set energy boundaries for one CTA observation | ||
| 99 | + | ||
| 100 | + Parameters | ||
| 101 | + ---------- | ||
| 102 | + responses : list of dict | ||
| 103 | + List of response dictionaries | ||
| 104 | + energy : float | ||
| 105 | + Energy to insert (TeV) | ||
| 106 | + comment : str | ||
| 107 | + Reason for energy insertion | ||
| 108 | + """ | ||
| 109 | + # Set thresholds of all response components | ||
| 110 | + logE = math.log10(energy) | ||
| 111 | + for rsp in responses: | ||
| 112 | + rsp['thres'] = rsp['irf'](logE, 0.0, 0.0) | ||
| 113 | + | ||
| 114 | + # Convert energy into gammalib energy | ||
| 115 | + eng = gammalib.GEnergy(energy, 'TeV') | ||
| 116 | + | ||
| 117 | + # Set insertion message | ||
| 118 | + msg = str(energy)+' TeV' | ||
| 119 | + if len(comment) > 0: | ||
| 120 | + msg += ' ('+comment+')' | ||
| 121 | + | ||
| 122 | + # If energy boundaries are empty then append an energy interval | ||
| 123 | + # with zero size ... | ||
| 124 | + if self._ebounds.size() == 0: | ||
| 125 | + | ||
| 126 | + # Append energy interval with zero size | ||
| 127 | + self._ebounds.append(eng, eng) | ||
| 128 | + | ||
| 129 | + # Log first energy boundary | ||
| 130 | + self._log_value(gammalib.NORMAL, 'First boundary', msg) | ||
| 131 | + | ||
| 132 | + # ... otherwise append an interval | ||
| 133 | + elif self._ebounds.size() > 0: | ||
| 134 | + | ||
| 135 | + # If current boundaries have zero size then recover boundary energy, | ||
| 136 | + # remove boundary, and append a boundary of non-zero size | ||
| 137 | + if self._ebounds.emin() == self._ebounds.emax(): | ||
| 138 | + | ||
| 139 | + # Recover old energy, remove boundary and append new boundary | ||
| 140 | + emin = self._ebounds.emin().copy() # Because emin becomes zero after remove | ||
| 141 | + emax = eng | ||
| 142 | + self._ebounds.remove(0) | ||
| 143 | + self._ebounds.append(emin, emax) | ||
| 144 | + | ||
| 145 | + # Log other energy boundary | ||
| 146 | + self._log_value(gammalib.NORMAL, 'Boundary', msg) | ||
| 147 | + | ||
| 148 | + else: | ||
| 149 | + | ||
| 150 | + # Use old emax as new emin. Only append if interval is non zero | ||
| 151 | + emin = self._ebounds.emax() | ||
| 152 | + if emin < eng: | ||
| 153 | + self._ebounds.append(emin, eng) | ||
| 154 | + | ||
| 155 | + # Log other energy boundary | ||
| 156 | + self._log_value(gammalib.NORMAL, 'Boundary', msg) | ||
| 157 | + | ||
| 158 | + # Return | ||
| 159 | + return | ||
| 160 | + | ||
| 161 | + def _set_ebounds(self, obs): | ||
| 162 | + """ | ||
| 163 | + Set energy boundaries for one CTA observation | ||
| 164 | + | ||
| 165 | + Parameters | ||
| 166 | + ---------- | ||
| 167 | + obs : `~gammalib.GObservations` | ||
| 168 | + CTA observation | ||
| 169 | + """ | ||
| 170 | + # Get parameters | ||
| 171 | + emin = self['emin'].real() | ||
| 172 | + emax = self['emax'].real() | ||
| 173 | + aeffthres = self['aeffthres'].real() | ||
| 174 | + bkgthres = self['bkgthres'].real() | ||
| 175 | + | ||
| 176 | + # Build list of response dictionaries | ||
| 177 | + responses = [] | ||
| 178 | + | ||
| 179 | + # Loop over all observations | ||
| 180 | + for run in obs: | ||
| 181 | + | ||
| 182 | + # Get response name | ||
| 183 | + mission = run.response().caldb().mission() | ||
| 184 | + instrument = run.response().caldb().instrument() | ||
| 185 | + rspname = run.response().rspname() | ||
| 186 | + name = '%s::%s::%s' % (mission, instrument, rspname) | ||
| 187 | + | ||
| 188 | + # If response name exists already then examine next observation | ||
| 189 | + exists = False | ||
| 190 | + for rsp in responses: | ||
| 191 | + if rsp['name'] == name: | ||
| 192 | + exists = True | ||
| 193 | + break | ||
| 194 | + if exists: | ||
| 195 | + continue | ||
| 196 | + | ||
| 197 | + # Append effective area and background template to list | ||
| 198 | + aeff = {'name': name, 'type': 'Aeff', | ||
| 199 | + 'irf': run.response().aeff(), 'thres': 0.0} | ||
| 200 | + bkg = {'name': name, 'type': 'Background', | ||
| 201 | + 'irf': run.response().background(), 'thres': 0.0} | ||
| 202 | + responses.append(aeff) | ||
| 203 | + responses.append(bkg) | ||
| 204 | + | ||
| 205 | + # Log response name | ||
| 206 | + self._log_value(gammalib.NORMAL, 'Append response', '%s (%s) [%s]' % | ||
| 207 | + (rspname, instrument, mission)) | ||
| 208 | + | ||
| 209 | + # Setup energy vector in log10(TeV) | ||
| 210 | + logEs = [math.log10(1.0e-3*float(i)) for i in range(int(emin*1000),int(emax*1000))] | ||
| 211 | + | ||
| 212 | + # Loop over all energies | ||
| 213 | + for logE in logEs: | ||
| 214 | + | ||
| 215 | + # Loop over all response components | ||
| 216 | + for rsp in responses: | ||
| 217 | + | ||
| 218 | + # Get IRF value | ||
| 219 | + irf = rsp['irf'](logE, 0.0, 0.0) | ||
| 220 | + | ||
| 221 | + # Get threshold | ||
| 222 | + if rsp['type'] == 'Aeff': | ||
| 223 | + threshold = aeffthres | ||
| 224 | + else: | ||
| 225 | + threshold = bkgthres | ||
| 226 | + | ||
| 227 | + # If threshold is zero and response is positive then insert | ||
| 228 | + # an energy ... | ||
| 229 | + if rsp['thres'] == 0.0 and irf > 0.0: | ||
| 230 | + self._insert_energy(responses, math.pow(10.0, logE), rsp['type']) | ||
| 231 | + break | ||
| 232 | + | ||
| 233 | + # ... otherwise if threshold is not zero then check whether | ||
| 234 | + # the fractional change exceeds the threshold | ||
| 235 | + elif rsp['thres'] != 0.0: | ||
| 236 | + f = irf/rsp['thres'] | ||
| 237 | + if 1.0-f > threshold or f-1.0 > threshold: | ||
| 238 | + self._insert_energy(responses, math.pow(10.0, logE), rsp['type']) | ||
| 239 | + break | ||
| 240 | + | ||
| 241 | + # Insert energy at end of range | ||
| 242 | + self._insert_energy(responses, emax, 'End of range') | ||
| 243 | + | ||
| 244 | + # Log number of energy boundaries | ||
| 245 | + self._log_value(gammalib.NORMAL, 'Number of boundaries', self._ebounds.size()) | ||
| 246 | + | ||
| 247 | + # Return | ||
| 248 | + return | ||
| 249 | + | ||
| 250 | + | ||
| 251 | + # Public methods | ||
| 252 | + def run(self): | ||
| 253 | + """ | ||
| 254 | + Run the script | ||
| 255 | + """ | ||
| 256 | + # Switch screen logging on in debug mode | ||
| 257 | + if self._logDebug(): | ||
| 258 | + self._log.cout(True) | ||
| 259 | + | ||
| 260 | + # Get parameters | ||
| 261 | + self._get_parameters() | ||
| 262 | + | ||
| 263 | + # Write observation into logger | ||
| 264 | + self._log_observations(gammalib.NORMAL, self._obs, 'Input observation') | ||
| 265 | + | ||
| 266 | + # Write header | ||
| 267 | + self._log_header1(gammalib.TERSE, 'Define energy boundaries') | ||
| 268 | + | ||
| 269 | + # Define energy boundaries for observation container | ||
| 270 | + self._set_ebounds(self._obs) | ||
| 271 | + | ||
| 272 | + # Return | ||
| 273 | + return | ||
| 274 | + | ||
| 275 | + def execute(self): | ||
| 276 | + """ | ||
| 277 | + Execute the script | ||
| 278 | + """ | ||
| 279 | + # Open logfile | ||
| 280 | + self.logFileOpen() | ||
| 281 | + | ||
| 282 | + # Read ahead output parameters | ||
| 283 | + self._read_ahead(True) | ||
| 284 | + | ||
| 285 | + # Run the scrip | ||
| 286 | + self.run() | ||
| 287 | + | ||
| 288 | + # Save energy boundaries | ||
| 289 | + self.save() | ||
| 290 | + | ||
| 291 | + # Return | ||
| 292 | + return | ||
| 293 | + | ||
| 294 | + def save(self): | ||
| 295 | + """ | ||
| 296 | + Save energy boundaries | ||
| 297 | + """ | ||
| 298 | + # Write header | ||
| 299 | + self._log_header1(gammalib.TERSE, 'Save energy boundaries') | ||
| 300 | + | ||
| 301 | + # Get energy boundaries filename | ||
| 302 | + outfile = self['outfile'].filename() | ||
| 303 | + | ||
| 304 | + # Log file name | ||
| 305 | + self._log_value(gammalib.NORMAL, 'Energy boundaries file', outfile.url()) | ||
| 306 | + | ||
| 307 | + # Save energy boundaries | ||
| 308 | + self._ebounds.save(outfile, self._clobber()) | ||
| 309 | + | ||
| 310 | + # Return | ||
| 311 | + return | ||
| 312 | + | ||
| 313 | + def ebounds(self): | ||
| 314 | + """ | ||
| 315 | + Return energy boundaries | ||
| 316 | + | ||
| 317 | + Returns | ||
| 318 | + ------- | ||
| 319 | + ebounds : `~gammalib.GEbounds()` | ||
| 320 | + Energy boundaries | ||
| 321 | + """ | ||
| 322 | + # Return | ||
| 323 | + return self._ebounds | ||
| 324 | + | ||
| 325 | + | ||
| 326 | +# ======================== # | ||
| 327 | +# Main routine entry point # | ||
| 328 | +# ======================== # | ||
| 329 | +if __name__ == '__main__': | ||
| 330 | + | ||
| 331 | + # Create instance of application | ||
| 332 | + app = csebins(sys.argv) | ||
| 333 | + | ||
| 334 | + # Execute application | ||
| 335 | + app.execute() |
doc/source/users/reference_manual/csebins.rst
0 → 100644
| 1 | +.. _csebins: | ||
| 2 | + | ||
| 3 | +csebins | ||
| 4 | +======= | ||
| 5 | + | ||
| 6 | +Generates energy boundaries for stacked analysis. | ||
| 7 | + | ||
| 8 | + | ||
| 9 | +Synopsis | ||
| 10 | +-------- | ||
| 11 | + | ||
| 12 | +This script generates the energy bounaries for a stacked analysis by inspecting | ||
| 13 | +the variation in the effective area and the background template of the response | ||
| 14 | +functions. The script takes either an observation definition XML file or a | ||
| 15 | +specific instrument response function on input. | ||
| 16 | + | ||
| 17 | +csebins writes an energy boundary extension into a FITS file. | ||
| 18 | + | ||
| 19 | + | ||
| 20 | +General parameters | ||
| 21 | +------------------ | ||
| 22 | + | ||
| 23 | +``inobs [file]`` | ||
| 24 | + Input observation definition XML file. | ||
| 25 | + | ||
| 26 | +``caldb [string]`` | ||
| 27 | + Calibration database. | ||
| 28 | + | ||
| 29 | +``irf [string]`` | ||
| 30 | + Instrumental response function. | ||
| 31 | + | ||
| 32 | +``outfile [file]`` | ||
| 33 | + Name of the energy boundary output file. | ||
| 34 | + | ||
| 35 | +``emin [real]`` | ||
| 36 | + Lower energy limit of energy boundaries (in TeV). | ||
| 37 | + | ||
| 38 | +``emax [real]`` | ||
| 39 | + Upper energy limit of energy boundaries (in TeV). | ||
| 40 | + | ||
| 41 | +``(aeffthres = 0.2) [real]`` | ||
| 42 | + Fractional change in effective area that leads to insertion of a new energy | ||
| 43 | + boundary. | ||
| 44 | + | ||
| 45 | +``(bkgthres = 0.5) [real]`` | ||
| 46 | + Fractional change in background rate that leads to insertion of a new energy | ||
| 47 | + boundary. | ||
| 48 | + | ||
| 49 | + | ||
| 50 | +Standard parameters | ||
| 51 | +------------------- | ||
| 52 | + | ||
| 53 | +``(chatter = 2) [integer]`` | ||
| 54 | + Verbosity of the executable: | ||
| 55 | + chatter = 0: no information will be logged | ||
| 56 | + | ||
| 57 | + chatter = 1: only errors will be logged | ||
| 58 | + | ||
| 59 | + chatter = 2: errors and actions will be logged | ||
| 60 | + | ||
| 61 | + chatter = 3: report about the task execution | ||
| 62 | + | ||
| 63 | + chatter = 4: detailed report about the task execution | ||
| 64 | + | ||
| 65 | +``(clobber = yes) [boolean]`` | ||
| 66 | + Specifies whether an existing energy boundaries output file should be overwritten. | ||
| 67 | + | ||
| 68 | +``(debug = no) [boolean]`` | ||
| 69 | + Enables debug mode. In debug mode the executable will dump any log file output to the console. | ||
| 70 | + | ||
| 71 | +``(mode = ql) [string]`` | ||
| 72 | + Mode of automatic parameters (default is "ql", i.e. "query and learn"). | ||
| 73 | + | ||
| 74 | +``(logfile = csebins.log) [filename]`` | ||
| 75 | + Log filename. | ||
| 76 | + | ||
| 77 | + | ||
| 78 | +Related tools or scripts | ||
| 79 | +------------------------ | ||
| 80 | + | ||
| 81 | +:doc:`ctbin` | ||
| 82 | +:doc:`ctexpcube` | ||
| 83 | +:doc:`ctpsfcube` | ||
| 84 | +:doc:`ctedispcube` | ||
| 85 | +:doc:`ctbkgcube` |
doc/source/users/reference_manual/cslightcrv.rst
| @@ -46,7 +46,7 @@ General parameters | @@ -46,7 +46,7 @@ General parameters | ||
| 46 | Applies energy dispersion to response computation. | 46 | Applies energy dispersion to response computation. |
| 47 | 47 | ||
| 48 | ``outfile [file]`` | 48 | ``outfile [file]`` |
| 49 | - Name of the source spectrum output file. | 49 | + Name of the light curve output file. |
| 50 | 50 | ||
| 51 | ``(tbinalg = GTI) <FILE|LIN|GTI> [string]`` | 51 | ``(tbinalg = GTI) <FILE|LIN|GTI> [string]`` |
| 52 | Algorithm for defining time bins. | 52 | Algorithm for defining time bins. |
| @@ -125,7 +125,7 @@ Standard parameters | @@ -125,7 +125,7 @@ Standard parameters | ||
| 125 | chatter = 4: detailed report about the task execution | 125 | chatter = 4: detailed report about the task execution |
| 126 | 126 | ||
| 127 | ``(clobber = yes) [boolean]`` | 127 | ``(clobber = yes) [boolean]`` |
| 128 | - Specifies whether an existing source spectrum output file should be overwritten. | 128 | + Specifies whether an existing light curve output file should be overwritten. |
| 129 | 129 | ||
| 130 | ``(debug = no) [boolean]`` | 130 | ``(debug = no) [boolean]`` |
| 131 | Enables debug mode. In debug mode the executable will dump any log file output to the console. | 131 | Enables debug mode. In debug mode the executable will dump any log file output to the console. |
doc/source/users/reference_manual/index.rst
| @@ -40,6 +40,7 @@ cscripts | @@ -40,6 +40,7 @@ cscripts | ||
| 40 | :maxdepth: 1 | 40 | :maxdepth: 1 |
| 41 | 41 | ||
| 42 | cscaldb --- Lists available instrument response functions <cscaldb> | 42 | cscaldb --- Lists available instrument response functions <cscaldb> |
| 43 | + csebins --- Generates energy boundaries for stacked analysis <csebins> | ||
| 43 | cslightcrv --- Computes lightcurve <cslightcrv> | 44 | cslightcrv --- Computes lightcurve <cslightcrv> |
| 44 | csmodelinfo --- Shows model container content <csmodelinfo> | 45 | csmodelinfo --- Shows model container content <csmodelinfo> |
| 45 | csmodelmerge --- Merges several model containers into one file <csmodelmerge> | 46 | csmodelmerge --- Merges several model containers into one file <csmodelmerge> |
test/test_csebins.py
0 → 100755
| 1 | +#! /usr/bin/env python | ||
| 2 | +# ========================================================================== | ||
| 3 | +# This scripts performs unit tests for the cslightcrv script. | ||
| 4 | +# | ||
| 5 | +# Copyright (C) 2016-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 gammalib | ||
| 22 | +import cscripts | ||
| 23 | +from testing import test | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +# ============================= # | ||
| 27 | +# Test class for csebins script # | ||
| 28 | +# ============================= # | ||
| 29 | +class Test(test): | ||
| 30 | + """ | ||
| 31 | + Test class for csebins script | ||
| 32 | + | ||
| 33 | + This test class makes unit tests for the csebins script by using it from | ||
| 34 | + the command line and from Python. | ||
| 35 | + """ | ||
| 36 | + | ||
| 37 | + # Constructor | ||
| 38 | + def __init__(self): | ||
| 39 | + """ | ||
| 40 | + Constructor | ||
| 41 | + """ | ||
| 42 | + # Call base class constructor | ||
| 43 | + test.__init__(self) | ||
| 44 | + | ||
| 45 | + # Return | ||
| 46 | + return | ||
| 47 | + | ||
| 48 | + # Set test functions | ||
| 49 | + def set(self): | ||
| 50 | + """ | ||
| 51 | + Set all test functions. | ||
| 52 | + """ | ||
| 53 | + # Set test name | ||
| 54 | + self.name('csebins') | ||
| 55 | + | ||
| 56 | + # Append tests | ||
| 57 | + self.append(self._test_cmd, 'Test csebins on command line') | ||
| 58 | + self.append(self._test_python, 'Test csebins from Python') | ||
| 59 | + | ||
| 60 | + # Return | ||
| 61 | + return | ||
| 62 | + | ||
| 63 | + # Test csebins on command line | ||
| 64 | + def _test_cmd(self): | ||
| 65 | + """ | ||
| 66 | + Test csebins on the command line. | ||
| 67 | + """ | ||
| 68 | + # Set script name | ||
| 69 | + cslightcrv = self._script('csebins') | ||
| 70 | + | ||
| 71 | + # Setup cslightcrv command | ||
| 72 | + cmd = cslightcrv+' inobs="NONE"'+ \ | ||
| 73 | + ' caldb="'+self._caldb+'" irf="'+self._irf+'"'+ \ | ||
| 74 | + ' emin=0.1 emax=100.0'+ \ | ||
| 75 | + ' outfile="csebins_cmd1.fits"'+ \ | ||
| 76 | + ' logfile="csebins_cmd1.log" chatter=1' | ||
| 77 | + | ||
| 78 | + # Check if execution of wrong command fails | ||
| 79 | + self.test_assert(self._execute('command_that_does_not_exist') != 0, | ||
| 80 | + 'Self test of test script') | ||
| 81 | + | ||
| 82 | + # Check if execution was successful | ||
| 83 | + self.test_assert(self._execute(cmd) == 0, | ||
| 84 | + 'Check successful execution from command line') | ||
| 85 | + | ||
| 86 | + # Check energy boundaries | ||
| 87 | + self._check_ebounds('csebins_cmd1.fits', 33) | ||
| 88 | + | ||
| 89 | + # Setup cslightcrv command | ||
| 90 | + cmd = cslightcrv+' inobs="NONE"'+ \ | ||
| 91 | + ' caldb="Database_that_does_not_exist" irf="'+self._irf+'"'+ \ | ||
| 92 | + ' emin=0.1 emax=100.0'+ \ | ||
| 93 | + ' outfile="csebins_cmd2.fits"'+ \ | ||
| 94 | + ' logfile="csebins_cmd2.log" chatter=1' | ||
| 95 | + | ||
| 96 | + # Check if execution failed | ||
| 97 | + self.test_assert(self._execute(cmd) != 0, | ||
| 98 | + 'Check invalid input file when executed from command line') | ||
| 99 | + | ||
| 100 | + # Return | ||
| 101 | + return | ||
| 102 | + | ||
| 103 | + # Test csebins from Python | ||
| 104 | + def _test_python(self): | ||
| 105 | + """ | ||
| 106 | + Test csebins from Python | ||
| 107 | + """ | ||
| 108 | + # Set-up csebins | ||
| 109 | + ebins = cscripts.csebins() | ||
| 110 | + ebins['inobs'] = 'NONE' | ||
| 111 | + ebins['caldb'] = self._caldb | ||
| 112 | + ebins['irf'] = self._irf | ||
| 113 | + ebins['emin'] = 0.1 | ||
| 114 | + ebins['emax'] = 100.0 | ||
| 115 | + ebins['outfile'] = 'csebins_py1.fits' | ||
| 116 | + ebins['logfile'] = 'csebins_py1.log' | ||
| 117 | + ebins['chatter'] = 2 | ||
| 118 | + | ||
| 119 | + # Run csebins script and energy boundaries | ||
| 120 | + ebins.logFileOpen() # Make sure we get a log file | ||
| 121 | + ebins.run() | ||
| 122 | + ebins.save() | ||
| 123 | + | ||
| 124 | + # Check energy boundaries | ||
| 125 | + self._check_ebounds('csebins_py1.fits', 33) | ||
| 126 | + | ||
| 127 | + # Return | ||
| 128 | + return | ||
| 129 | + | ||
| 130 | + # Check energy boundaries result file | ||
| 131 | + def _check_ebounds(self, filename, bins): | ||
| 132 | + """ | ||
| 133 | + Check energy boundaries file | ||
| 134 | + """ | ||
| 135 | + # Load energy boundaries file | ||
| 136 | + ebounds = gammalib.GEbounds(filename) | ||
| 137 | + | ||
| 138 | + # Check number of energy boundaries | ||
| 139 | + self.test_value(ebounds.size(), bins) | ||
| 140 | + | ||
| 141 | + # Return | ||
| 142 | + return |
test/test_python_cscripts.py
| @@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
| 2 | # ========================================================================== | 2 | # ========================================================================== |
| 3 | # This scripts performs unit tests for cscripts | 3 | # This scripts performs unit tests for cscripts |
| 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 |
| @@ -25,6 +25,7 @@ import cscripts | @@ -25,6 +25,7 @@ import cscripts | ||
| 25 | sys.path.append(os.path.dirname(os.path.abspath(__file__))) | 25 | sys.path.append(os.path.dirname(os.path.abspath(__file__))) |
| 26 | import test_cscript | 26 | import test_cscript |
| 27 | import test_cscaldb | 27 | import test_cscaldb |
| 28 | +import test_csebins | ||
| 28 | import test_csfindobs | 29 | import test_csfindobs |
| 29 | import test_csinfo | 30 | import test_csinfo |
| 30 | import test_cslightcrv | 31 | import test_cslightcrv |
| @@ -113,6 +114,7 @@ def test(installed=False, debug=False): | @@ -113,6 +114,7 @@ def test(installed=False, debug=False): | ||
| 113 | # Define list of test suites | 114 | # Define list of test suites |
| 114 | tests = [test_cscript.Test(), | 115 | tests = [test_cscript.Test(), |
| 115 | test_cscaldb.Test(), | 116 | test_cscaldb.Test(), |
| 117 | + test_csebins.Test(), | ||
| 116 | test_csinfo.Test(), | 118 | test_csinfo.Test(), |
| 117 | test_cslightcrv.Test(), | 119 | test_cslightcrv.Test(), |
| 118 | test_csmodelinfo.Test(), | 120 | test_csmodelinfo.Test(), |