diff --git a/ChangeLog b/ChangeLog index 78996f0..56f6353 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,9 @@ -2018-01-23 +2018-01-24 * Version 1.5.0 released ======================== + Add tmin and tmax parameters to csobsselect (#2297) Change DATE_OBS, DATE_END, TIME_OBS and TIME_END FITS keywords into DATA-OBS, DATE-END, TIME-OBS and TIME-END Add CUSTOM background method to csphagen script (#2284) diff --git a/NEWS b/NEWS index d5c0c97..ac69d02 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -23 January 2018 +24 January 2018 Introduction @@ -235,7 +235,7 @@ None csobsselect - Select observations --------------------------------- -None +Add tmin and tmax parameters to allow selection of observation by time (#2297). csphagen - Generate On/Off observations diff --git a/cscripts/csobsselect.par b/cscripts/csobsselect.par index 5a6a80e..ef298a3 100644 --- a/cscripts/csobsselect.par +++ b/cscripts/csobsselect.par @@ -31,6 +31,8 @@ glat, r, a, -5.79,-90,90, "Galactic latitude of selection centre (deg)" rad, r, a, 5.0,0,180, "Radius of selection circle (deg)" width, r, a, 10.0,0,360, "Width of selection box (deg)" height, r, a, 10.0,0,180, "Height of selection box (deg)" +tmin, t, a, NONE,,, "Start time (UTC string, JD, MJD or MET in seconds)" +tmax, t, a, NONE,,, "Stop time (UTC string, JD, MJD or MET in seconds)" # # Standard parameters diff --git a/cscripts/csobsselect.py b/cscripts/csobsselect.py index 470f8a0..e873019 100755 --- a/cscripts/csobsselect.py +++ b/cscripts/csobsselect.py @@ -2,7 +2,7 @@ # ========================================================================== # Selects observations from an observation definition XML file # -# Copyright (C) 2016-2017 Juergen Knoedlseder +# Copyright (C) 2016-2018 Juergen Knoedlseder # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -68,6 +68,9 @@ class csobsselect(ctools.csobservation): self['width'].real() self['height'].real() + # Query time interval + self._get_gti() + # Query ahead output model filename if self._read_ahead(): self['outobs'].filename() @@ -83,7 +86,34 @@ class csobsselect(ctools.csobservation): # Return return - def _select_observation(self, obs): + def _log_selection(self, obs, msg): + """ + Log observation selection + + Parameters + ---------- + obs : `~gammalib.GObservation` + Observation + msg : str + Message + """ + # Set observation name + if len(obs.name()) > 0: + name = obs.name() + else: + name = 'Observation' + + # Prepend obervation ID + if len(obs.id()) > 0: + msg = obs.id()+' '+msg + + # Log observation selection + self._log_value(gammalib.NORMAL, name, msg) + + # Return + return + + def _select_observation(self, obs, gti): """ Select observation @@ -91,6 +121,8 @@ class csobsselect(ctools.csobservation): ---------- obs : `~gammalib.GObservation` Observation + gti : `~gammalib.GGti` + Good time intervals Returns ------- @@ -103,14 +135,27 @@ class csobsselect(ctools.csobservation): # Continue only if observation is a CTA observation if obs.classname() == 'GCTAObservation': - # Get selection type - pntselect = self['pntselect'].string() + # Get observation start and stop time + obs_gti = obs.gti() + tstart = obs_gti.tstart() + tstop = obs_gti.tstop() + + # If the observation is not within the time selection then skip it + if gti.size() > 0 and not gti.contains(tstart) and \ + not gti.contains(tstop): + self._log_selection(obs, 'outside time interval') - # Dispatch according to selection type - if pntselect == 'CIRCLE': - select = self._select_circle(obs) + # ... otherwise select spatially else: - select = self._select_box(obs) + + # Get selection type + pntselect = self['pntselect'].string() + + # Dispatch according to selection type + if pntselect == 'CIRCLE': + select = self._select_circle(obs) + else: + select = self._select_box(obs) # Return selection flag return select @@ -150,18 +195,8 @@ class csobsselect(ctools.csobservation): select = False msg = 'outside selection circle' - # Set observation name - if len(obs.name()) > 0: - name = obs.name() - else: - name = 'Observation' - - # Prepend obervation ID - if len(obs.id()) > 0: - msg = obs.id()+' '+msg - # Log observation selection - self._log_value(gammalib.NORMAL, name, msg) + self._log_selection(obs, msg) # Return selection flag return select @@ -240,18 +275,8 @@ class csobsselect(ctools.csobservation): select = True msg = 'inside selection box' - # Set observation name - if len(obs.name()) > 0: - name = obs.name() - else: - name = 'Observation' - - # Prepend obervation ID - if len(obs.id()) > 0: - msg = obs.id()+' '+msg - # Log observation selection - self._log_value(gammalib.NORMAL, name, msg) + self._log_selection(obs, msg) # Return selection flag return select @@ -269,6 +294,9 @@ class csobsselect(ctools.csobservation): # Get parameters self._get_parameters() + # Get Good Time Interval (empty if no time selection is applied) + gti = self._get_gti() + # Initialise empty observation container for selected observations selected_obs = gammalib.GObservations() @@ -282,7 +310,7 @@ class csobsselect(ctools.csobservation): for obs in self.obs(): # If observation is selected then append observation - if self._select_observation(obs): + if self._select_observation(obs, gti): selected_obs.append(obs) # Copy selected observations into observation diff --git a/doc/source/admin/release_history/1.5.rst b/doc/source/admin/release_history/1.5.rst index b39b584..6687787 100644 --- a/doc/source/admin/release_history/1.5.rst +++ b/doc/source/admin/release_history/1.5.rst @@ -12,6 +12,9 @@ In particular, this release provides: * Support of classical IACT analysis * Specifcation of times in various formats (UTC, MJD, JD, MET) +* Spectrum generation for non-IACT data +* Generation of residual spectra +* Jupyter notebooks Bug fixes @@ -28,6 +31,8 @@ Bug fixes Improvements ------------ +* [`2297 `_] - + Add ``tmin`` and ``tmax`` parameters to :ref:`csobsselect` * [`2295 `_] - Add ``ctools::time_reference`` constant and remove ``ctools::time_reference()`` method @@ -78,6 +83,7 @@ New features * [`1864 `_] - Use t-type parameters for all ``tmin`` and ``tmax`` parameters + Clean up -------- diff --git a/doc/source/users/reference_manual/csobsselect.rst b/doc/source/users/reference_manual/csobsselect.rst index 2645e08..e05a77f 100644 --- a/doc/source/users/reference_manual/csobsselect.rst +++ b/doc/source/users/reference_manual/csobsselect.rst @@ -10,9 +10,9 @@ Synopsis -------- This script selects all observations from an observation definiton XML file that -have pointings within a specified selection region and writes these observations -into a new observation definition XML file. Possible selection regions are a -circle and a box, either in Galactic or Celestial coordinates. +have pointings within a specified selection region and time interval and writes +these observations into a new observation definition XML file. Possible selection +regions are a circle and a box, either in Galactic or Celestial coordinates. General parameters @@ -51,6 +51,16 @@ General parameters ``height [real]`` Height of selection box (degrees). +``tmin [time]`` + Start time (UTC string, JD, MJD or time in seconds). + If ``INDEF``, ``NONE``, ``UNDEF`` or ``UNDEFINED`` is passed as value, no time + selection will be performed. + +``tmax [time]`` + Stop time (UTC string, JD, MJD or time in seconds). + If ``INDEF``, ``NONE``, ``UNDEF`` or ``UNDEFINED`` is passed as value, no time + selection will be performed. + Standard parameters ------------------- diff --git a/doc/source/users/tutorials/1dc/first_select_obs.rst b/doc/source/users/tutorials/1dc/first_select_obs.rst index 1f6779b..381aacc 100644 --- a/doc/source/users/tutorials/1dc/first_select_obs.rst +++ b/doc/source/users/tutorials/1dc/first_select_obs.rst @@ -41,6 +41,7 @@ You do this with the :ref:`csobsselect` script by typing: Galactic longitude of selection centre (deg) (0-360) [184.56] 0.0 Galactic latitude of selection centre (deg) (-90-90) [-5.79] 0.0 Radius of selection circle (deg) (0-180) [5.0] 3.0 + Start time (UTC string, JD, MJD or MET in seconds) [NONE] Output observation definition XML file [outobs.xml] obs.xml You selected ``CIRCLE`` as the shape of the pointing selection region, diff --git a/test/test_csobsselect.py b/test/test_csobsselect.py index 760d40a..91b95ea 100755 --- a/test/test_csobsselect.py +++ b/test/test_csobsselect.py @@ -72,7 +72,7 @@ class Test(test): cmd = csobsselect+' inobs="'+self._events+'"'+ \ ' outobs="csobsselect_cmd1.xml"'+ \ ' pntselect="CIRCLE" coordsys="CEL" ra=83.63'+ \ - ' dec=22.01 rad=5.0'+ \ + ' dec=22.01 rad=5.0 tmin=NONE tmax=NONE'+ \ ' logfile="csobsselect_cmd1.log" chatter=1' # Check if execution was successful @@ -86,7 +86,7 @@ class Test(test): cmd = csobsselect+' inobs="observation_that_does_not_exist.xml"'+ \ ' outobs="csobsselect_cmd2.xml"'+ \ ' pntselect="CIRCLE" coordsys="CEL" ra=83.63'+ \ - ' dec=22.01 rad=5.0'+ \ + ' dec=22.01 rad=5.0 tmin=NONE tmax=NONE'+ \ ' logfile="csobsselect_cmd2.log" debug=yes chatter=2' # Check if execution failed @@ -121,12 +121,14 @@ class Test(test): # Now set csobsselect parameters obsselect['inobs'] = self._events - obsselect['outobs'] = 'csobsselect_py1.xml' obsselect['pntselect'] = 'CIRCLE' obsselect['coordsys'] = 'CEL' obsselect['ra'] = 83.63 obsselect['dec'] = 22.01 obsselect['rad'] = 5.0 + obsselect['tmin'] = 'NONE' + obsselect['tmax'] = 'NONE' + obsselect['outobs'] = 'csobsselect_py1.xml' obsselect['logfile'] = 'csobsselect_py1.log' obsselect['chatter'] = 2 @@ -139,12 +141,14 @@ class Test(test): self._check_observation_file('csobsselect_py1.xml', 1) # Execute csobsselect script again, now in Galactic coordinates - obsselect['outobs'] = 'csobsselect_py2.xml' obsselect['pntselect'] = 'CIRCLE' obsselect['coordsys'] = 'GAL' obsselect['glon'] = 184.56 obsselect['glat'] = -5.79 obsselect['rad'] = 5.0 + obsselect['tmin'] = 'NONE' + obsselect['tmax'] = 'NONE' + obsselect['outobs'] = 'csobsselect_py2.xml' obsselect['logfile'] = 'csobsselect_py2.log' obsselect['chatter'] = 3 obsselect.logFileOpen() # Needed to get a new log file @@ -154,13 +158,15 @@ class Test(test): self._check_observation_file('csobsselect_py2.xml', 1) # Execute csobsselect script again, now a box in Galactic coordinates - obsselect['outobs'] = 'csobsselect_py3.xml' obsselect['pntselect'] = 'BOX' obsselect['coordsys'] = 'GAL' obsselect['glon'] = 184.56 obsselect['glat'] = -5.79 obsselect['width'] = 5.0 obsselect['height'] = 5.0 + obsselect['tmin'] = 'NONE' + obsselect['tmax'] = 'NONE' + obsselect['outobs'] = 'csobsselect_py3.xml' obsselect['logfile'] = 'csobsselect_py3.log' obsselect['chatter'] = 4 obsselect.logFileOpen() # Needed to get a new log file @@ -170,13 +176,15 @@ class Test(test): self._check_observation_file('csobsselect_py3.xml', 1) # Execute csobsselect script again, now a box in celestial coordinates - obsselect['outobs'] = 'csobsselect_py4.xml' obsselect['pntselect'] = 'BOX' obsselect['coordsys'] = 'CEL' obsselect['ra'] = 83.63 obsselect['dec'] = 22.01 obsselect['width'] = 5.0 obsselect['height'] = 5.0 + obsselect['tmin'] = 'NONE' + obsselect['tmax'] = 'NONE' + obsselect['outobs'] = 'csobsselect_py4.xml' obsselect['logfile'] = 'csobsselect_py4.log' obsselect['chatter'] = 4 obsselect.logFileOpen() # Needed to get a new log file @@ -185,6 +193,24 @@ class Test(test): # Check model file self._check_observation_file('csobsselect_py4.xml', 1) + # Execute csobsselect script again, now with time selection + obsselect['pntselect'] = 'BOX' + obsselect['coordsys'] = 'CEL' + obsselect['ra'] = 83.63 + obsselect['dec'] = 22.01 + obsselect['width'] = 5.0 + obsselect['height'] = 5.0 + obsselect['tmin'] = 0.0 + obsselect['tmax'] = 100.0 + obsselect['outobs'] = 'csobsselect_py5.xml' + obsselect['logfile'] = 'csobsselect_py5.log' + obsselect['chatter'] = 4 + obsselect.logFileOpen() # Needed to get a new log file + obsselect.execute() + + # Check model file + self._check_observation_file('csobsselect_py5.xml', 0) + # Return return