Commit a8e080d463c2d6e583c642acba691474a3ead48b

Authored by Jürgen Knödlseder
1 parent c957f640

Add initial version of csobsdef script.

doc/source/reference_manual/csobsdef.rst 0 → 100644
  1 +.. _csobsdef:
  2 +
  3 +csobsdef
  4 +========
  5 +
  6 +Generates an observation definition file.
  7 +
  8 +
  9 +Synopsis
  10 +--------
  11 +
  12 +Generates an observation definition file.
  13 +
  14 +
  15 +General parameters
  16 +------------------
  17 +
  18 +``inpnt [file]``
  19 + Pointing definition ASCII file in colon separated values format.
  20 +
  21 +``outobs [file]``
  22 + Output Observation Definition XML file.
  23 +
  24 +``caldb [string]``
  25 + Calibration database.
  26 +
  27 +``irf [string]``
  28 + Instrumental response function.
  29 +
  30 +``emin [real]``
  31 + Lower energy limit of events (in TeV).
  32 +
  33 +``emax [real]``
  34 + Upper energy limit of events (in TeV).
  35 +
  36 +``duration [real]``
  37 + Duration of observation (in seconds).
  38 +
  39 +``rad [real]``
  40 + ROI radius (in degrees).
  41 +
  42 +``(deadc = 0.95) [real]``
  43 + Average deadtime correction factor.
  44 +
  45 +
  46 +Standard parameters
  47 +-------------------
  48 +
  49 +``(chatter = 2) [integer]``
  50 + Verbosity of the executable:
  51 + chatter = 0: no information will be logged
  52 +
  53 + chatter = 1: only errors will be logged
  54 +
  55 + chatter = 2: errors and actions will be logged
  56 +
  57 + chatter = 3: report about the task execution
  58 +
  59 + chatter = 4: detailed report about the task execution
  60 +
  61 +``(clobber = yes) [boolean]``
  62 + Specifies whether an existing output counts cube should be overwritten.
  63 +
  64 +``(debug = no) [boolean]``
  65 + Enables debug mode. In debug mode the executable will dump any log file output to the console.
  66 +
  67 +``(mode = ql) [string]``
  68 + Mode of automatic parameters (default is "ql", i.e. "query and learn").
  69 +
  70 +``(logfile = csobsdef.log) [string]``
  71 + Log filename.
  72 +
  73 +
  74 +Related tools
  75 +-------------
  76 +
  77 +None
... ...
doc/source/reference_manual/index.rst
... ... @@ -36,6 +36,7 @@ cscripts
36 36 :maxdepth: 1
37 37  
38 38 cscaldb --- Lists available instrument response functions <cscaldb>
  39 + csobsdef --- Generates observation definition file <csobsdef>
39 40 cspull --- Generates pull distribution <cspull>
40 41 cssens --- Computes CTA sensitivity <cssens>
41 42 csresmap --- Generates residual map <csresmap>
... ...
scripts/Makefile.am
... ... @@ -6,11 +6,13 @@ binscripts = cta_kb_bkgrates.py cta_root2irf.py cta_make_nodes.py \
6 6  
7 7 # Scripts to be distributed in pythondir
8 8 pythonscripts = cspull.py cssens.py cstsdist.py cscaldb.py csresmap.py \
  9 + csobsdef.py \
9 10 lsmodel.py \
10 11 obsutils.py
11 12  
12 13 # Scripts for which symbolic links will be created in bindir
13   -linkscripts = cspull cssens cstsdist cscaldb csresmap\
  14 +linkscripts = cspull cssens cstsdist cscaldb csresmap \
  15 + csobsdef \
14 16 lsmodel
15 17  
16 18 # Distribute scripts
... ...
scripts/csobsdef.py 0 → 100755
  1 +#! /usr/bin/env python
  2 +# ==========================================================================
  3 +# Generation of an observation definition file.
  4 +#
  5 +# Copyright (C) 2015 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 ctools
  23 +import sys
  24 +
  25 +
  26 +# ============== #
  27 +# csobsdef class #
  28 +# ============== #
  29 +class csobsdef(ctools.cscript):
  30 + """
  31 + The csobsdef class generates an observation definition file from a
  32 + pointing list.
  33 + """
  34 + def __init__(self, *argv):
  35 + """
  36 + Constructor.
  37 + """
  38 + # Set name and version
  39 + self.name = "csobsdef"
  40 + self.version = "1.0.0"
  41 +
  42 + # Initialise class members
  43 + self.obs = gammalib.GObservations()
  44 + self.inpnt = ""
  45 + self.tmin = 0.0
  46 + self.outfile = ""
  47 + self.chatter = 2
  48 + self.clobber = True
  49 + self.debug = False
  50 + self.read_ahead = False
  51 +
  52 + # Make sure that parfile exists
  53 + file = self.parfile()
  54 +
  55 + # Initialise application
  56 + if len(argv) == 0:
  57 + ctools.cscript.__init__(self, self.name, self.version)
  58 + elif len(argv) ==1:
  59 + ctools.cscript.__init__(self, self.name, self.version, *argv)
  60 + else:
  61 + raise TypeError("Invalid number of arguments given.")
  62 +
  63 + # Set logger properties
  64 + self.log_header()
  65 + self.log.date(True)
  66 +
  67 + # Return
  68 + return
  69 +
  70 + def __del__(self):
  71 + """
  72 + Destructor.
  73 + """
  74 + # Return
  75 + return
  76 +
  77 + def parfile(self):
  78 + """
  79 + Check if parfile exists. If parfile does not exist then create a
  80 + default parfile. This kluge avoids shipping the cscript with a parfile.
  81 + """
  82 + # Set parfile name
  83 + parfile = self.name+".par"
  84 +
  85 + # Test parfile existence, and create parfile if it does not exist
  86 + try:
  87 + pars = gammalib.GApplicationPars(parfile)
  88 + except:
  89 + # Signal that parfile was not found
  90 + print("Parfile \""+parfile+"\" not found. Create default parfile.")
  91 +
  92 + # Create default parfile
  93 + pars = gammalib.GApplicationPars()
  94 + pars.append(gammalib.GApplicationPar("inpnt","f","a","NONE","","","Pointing definition file"))
  95 + pars.append(gammalib.GApplicationPar("outobs","f","a","obs.xml","","","Output observation definition file"))
  96 + pars.append(gammalib.GApplicationPar("caldb","s","a","dummy","","","Calibration database"))
  97 + pars.append(gammalib.GApplicationPar("irf","s","a","cta_dummy_irf","","","Instrument response function"))
  98 + pars.append(gammalib.GApplicationPar("emin","r","a","0.1","","","Lower energy limit (TeV)"))
  99 + pars.append(gammalib.GApplicationPar("emax","r","a","100.0","","","Upper energy limit (TeV)"))
  100 + pars.append(gammalib.GApplicationPar("duration","r","a","1800.0","","","Pointing duration"))
  101 + pars.append(gammalib.GApplicationPar("rad","r","a","5.0","","","Radius of ROI (degrees)"))
  102 + pars.append(gammalib.GApplicationPar("deadc","r","h","0.95","","","Deadtime correction factor"))
  103 + pars.append_standard()
  104 + pars.append(gammalib.GApplicationPar("logfile","f","h","csobsdef.log","","","Log filename"))
  105 + pars.save(parfile)
  106 +
  107 + # Return
  108 + return
  109 +
  110 + def get_parameters(self):
  111 + """
  112 + Get parameters from parfile.
  113 + """
  114 + # Read parameters
  115 + self.inpnt = self["inpnt"].filename()
  116 +
  117 + # Read ahead parameters
  118 + if self.read_ahead:
  119 + self.outfile = self["outobs"].filename()
  120 +
  121 + # Set some fixed parameters
  122 + self.chatter = self["chatter"].integer()
  123 + self.clobber = self["clobber"].boolean()
  124 + self.debug = self["debug"].boolean()
  125 +
  126 + # Return
  127 + return
  128 +
  129 + def execute(self):
  130 + """
  131 + Execute the script.
  132 + """
  133 + # Set read ahead flag
  134 + self.read_ahead = True
  135 +
  136 + # Run the script
  137 + self.run()
  138 +
  139 + # Save observation definition file
  140 + self.obs.save(self.outfile)
  141 +
  142 + # Return
  143 + return
  144 +
  145 + def run(self):
  146 + """
  147 + Run the script.
  148 + """
  149 + # Switch screen logging on in debug mode
  150 + if self.logDebug():
  151 + self.log.cout(True)
  152 +
  153 + # Get parameters
  154 + self.get_parameters()
  155 +
  156 + # Write input parameters into logger
  157 + if self.logTerse():
  158 + self.log_parameters()
  159 + self.log("\n")
  160 +
  161 + # Load pointing definition file
  162 + pntdef = gammalib.GCsv(self.inpnt, ",")
  163 + ncols = pntdef.ncols()
  164 + npnt = pntdef.nrows()-1
  165 +
  166 + # Throw an exception is there is no header information
  167 + if pntdef.nrows() < 1:
  168 + raise gammalib.GException.invalid_value(self.name,
  169 + "No header found in pointing definition file.")
  170 +
  171 + # Clear observation container
  172 + self.obs.clear()
  173 + self.id = 1
  174 +
  175 + # Extract header from pointing definition file
  176 + header = []
  177 + for col in range(ncols):
  178 + header.append(pntdef[0,col])
  179 +
  180 + # Loop over all pointings
  181 + for pnt in range(npnt):
  182 +
  183 + # Set row index
  184 + row = pnt + 1
  185 +
  186 + # Create CTA observation
  187 + obs = gammalib.GCTAObservation()
  188 +
  189 + # Set observation name
  190 + if "name" in header:
  191 + name = pntdef[row, header.index("name")]
  192 + else:
  193 + name = "None"
  194 + obs.name(name)
  195 +
  196 + # Set identifier
  197 + if "id" in header:
  198 + id = pntdef[row, header.index("id")]
  199 + else:
  200 + id = "%6.6d" % self.id
  201 + self.id += 1
  202 + obs.id(id)
  203 +
  204 + # Set pointing
  205 + if "ra" in header and "dec" in header:
  206 + ra = float(pntdef[row, header.index("ra")])
  207 + dec = float(pntdef[row, header.index("dec")])
  208 + pntdir = gammalib.GSkyDir()
  209 + pntdir.radec_deg(ra,dec)
  210 + elif "lon" in header and "lat" in header:
  211 + lon = float(pntdef[row, header.index("lon")])
  212 + lat = float(pntdef[row, header.index("lat")])
  213 + pntdir = gammalib.GSkyDir()
  214 + pntdir.lb_deg(lon,lat)
  215 + else:
  216 + raise gammalib.GException.invalid_value(self.name,
  217 + "No (ra,dec) or (lon,lat) columns found in pointing"
  218 + " definition file.")
  219 + obs.pointing(gammalib.GCTAPointing(pntdir))
  220 +
  221 + # Set response function
  222 + if "caldb" in header:
  223 + caldb = pntdef[row, header.index("caldb")]
  224 + else:
  225 + caldb = self["caldb"].string()
  226 + if "irf" in header:
  227 + irf = pntdef[row, header.index("irf")]
  228 + else:
  229 + irf = self["irf"].string()
  230 + cal = gammalib.GCaldb()
  231 + if gammalib.dir_exists(caldb):
  232 + cal.rootdir(database)
  233 + else:
  234 + cal.open("cta", caldb)
  235 + obs.response(irf, cal);
  236 +
  237 + # Set deadtime correction factor
  238 + if "deadc" in header:
  239 + deadc = float(pntdef[row, header.index("deadc")])
  240 + else:
  241 + deadc = self["deadc"].real()
  242 + obs.deadc(deadc)
  243 +
  244 + # Set Good Time Interval
  245 + if "duration" in header:
  246 + duration = float(pntdef[row, header.index("duration")])
  247 + else:
  248 + duration = self["duration"].real()
  249 + tmin = self.tmin
  250 + tmax = self.tmin + duration
  251 + gti = gammalib.GGti(self.time_reference())
  252 + tstart = gammalib.GTime(tmin, self.time_reference())
  253 + tstop = gammalib.GTime(tmax, self.time_reference())
  254 + self.tmin = tmax
  255 + gti.append(tstart, tstop)
  256 + obs.ontime(gti.ontime())
  257 + obs.livetime(gti.ontime()*deadc)
  258 +
  259 + # Set Energy Boundaries
  260 + if "emin" in header:
  261 + emin = float(pntdef[row, header.index("emin")])
  262 + else:
  263 + emin = self["emin"].real()
  264 + if "emax" in header:
  265 + emax = float(pntdef[row, header.index("emax")])
  266 + else:
  267 + emax = self["emax"].real()
  268 + ebounds = gammalib.GEbounds(gammalib.GEnergy(emin, "TeV"),
  269 + gammalib.GEnergy(emax, "TeV"))
  270 +
  271 + # Set ROI
  272 + if "rad" in header:
  273 + rad = float(pntdef[row, header.index("rad")])
  274 + else:
  275 + rad = self["rad"].real()
  276 + roi = gammalib.GCTARoi(gammalib.GCTAInstDir(pntdir), rad)
  277 +
  278 + # Create an empty event list
  279 + list = gammalib.GCTAEventList()
  280 + list.roi(roi)
  281 + list.gti(gti)
  282 + list.ebounds(ebounds)
  283 +
  284 + # Attach event list to CTA observation
  285 + obs.events(list)
  286 +
  287 + # Append observation
  288 + self.obs.append(obs)
  289 +
  290 + # Return
  291 + return
  292 +
  293 + def __define_observation(self, header, pntdef, ipnt):
  294 + """
  295 + Define one oberservation.
  296 + """
  297 + # Create CTA observation
  298 + obs = gammalib.GCTAObservation()
  299 +
  300 + # Return observation
  301 + return obs
  302 +
  303 +
  304 +# ======================== #
  305 +# Main routine entry point #
  306 +# ======================== #
  307 +if __name__ == '__main__':
  308 + """
  309 + Generates observation definition file.
  310 + """
  311 + # Create instance of application
  312 + app = csobsdef(sys.argv)
  313 +
  314 + # Open logfile
  315 + app.logFileOpen()
  316 +
  317 + # Execute application
  318 + app.execute()
  319 +
0 320 \ No newline at end of file
... ...