Commit a63b9b9249bf6083b38125855a687a59591e562b

Authored by Luigi Tibaldo
1 parent b8ffb0f0

Implement Off runs (unit test not working)

cscripts/csphagen.par
... ... @@ -17,6 +17,7 @@
17 17 # Input and output parameters
18 18 #============================
19 19 inobs, f, a, obs.xml,,, "Input event list or observation definition XML file"
  20 +inobsoff, f, a, obs_off.xml,,, "Input Off event list or observation definition XML file"
20 21 inmodel, f, a, NONE,,, "Input model definition XML file (if NONE, use point source)"
21 22 srcname, s, a, Crab,,, "Source name"
22 23 caldb, s, a, prod2,,, "Calibration database"
... ... @@ -46,10 +47,10 @@ width, r, a, 0.2,0,180, "Width of source region rectangle (deg)"
46 47 height, r, a, 0.2,0,180, "Height of source region rectangle (deg)"
47 48 posang, r, a, 0.0,-360,360, "Position angle of source region rectangle (deg)"
48 49 srcregfile, f, a, on.reg,,, "Source region file (ds9 or FITS WCS)"
49   -bkgmethod, s, a, REFLECTED,REFLECTED|CUSTOM,, "Method for background estimation"
  50 +bkgmethod, s, a, REFLECTED,REFLECTED|CUSTOM|OFF,, "Method for background estimation"
50 51 bkgregfile, f, a, bkg.reg,,, "Background regions file (ds9 or FITS WCS)"
51   -bkgregmin, i, h, 2,1,1000, "Minimum number of background regions"
52   -bkgregskip, i, h, 1,0,10, "Number of background regions to skip next to On region"
  52 +bkgregmin, i, h, 2,1,1000, "Minimum number of background regions for REFLECTED method"
  53 +bkgregskip, i, h, 1,0,10, "Number of background regions to skip next to On region for REFLECTED method"
53 54 use_model_bkg, b, h, yes,,, "Use background model?"
54 55 maxoffset, r, h, 4.0,,, "Maximum offset of source from camera center to accept observation"
55 56 stack, b, a, no,,, "Stack multiple observations into single PHA, ARF and RMF files?"
... ...
cscripts/csphagen.py
... ... @@ -43,6 +43,7 @@ class csphagen(ctools.csobservation):
43 43 self._init_csobservation(self.__class__.__name__, ctools.__version__, argv)
44 44  
45 45 # Initialise other variables
  46 + self._obs_off = gammalib.GObservations()
46 47 self._ebounds = gammalib.GEbounds()
47 48 self._etruebounds = gammalib.GEbounds()
48 49 self._src_dir = gammalib.GSkyDir()
... ... @@ -74,6 +75,7 @@ class csphagen(ctools.csobservation):
74 75 """
75 76 # Set pickled dictionary
76 77 state = {'base' : ctools.csobservation.__getstate__(self),
  78 + 'obs_off' : self._obs_off,
77 79 'ebounds' : self._ebounds,
78 80 'etruebounds' : self._etruebounds,
79 81 'src_dir' : self._src_dir,
... ... @@ -103,6 +105,7 @@ class csphagen(ctools.csobservation):
103 105 Pickled instance
104 106 """
105 107 ctools.csobservation.__setstate__(self, state['base'])
  108 + self._obs_off = state['obs_off']
106 109 self._ebounds = state['ebounds']
107 110 self._etruebounds = state['etruebounds']
108 111 self._src_dir = state['src_dir']
... ... @@ -205,21 +208,17 @@ class csphagen(ctools.csobservation):
205 208 # Return region container
206 209 return regs
207 210  
208   - def _get_parameters_bkgmethod_reflected(self):
  211 + def _get_source_parameters(self):
209 212 """
210   - Get parameters for REFLECTED background method
  213 + Get parameters to define source/On region
211 214 """
  215 +
212 216 # Get source shape
213 217 self._srcshape = self['srcshape'].string()
214 218  
215 219 # Query source direction
216 220 self._query_src_direction()
217 221  
218   - # Query minimum number of background regions and number of
219   - # background regions to skip next to On region
220   - self['bkgregmin'].integer()
221   - self['bkgregskip'].integer()
222   -
223 222 # If source shape is a circle the append GSkyRegionCircle
224 223 if self._srcshape == 'CIRCLE':
225 224  
... ... @@ -240,8 +239,21 @@ class csphagen(ctools.csobservation):
240 239 self._reg_height,
241 240 self._reg_posang))
242 241  
243   - # Query usage of background model
244   - self['use_model_bkg'].boolean()
  242 + # Return
  243 + return
  244 +
  245 + def _get_parameters_bkgmethod_reflected(self):
  246 + """
  247 + Get parameters for REFLECTED background method
  248 + """
  249 +
  250 + # Query parameters for source/On region definition
  251 + self._get_source_parameters()
  252 +
  253 + # Query minimum number of background regions and
  254 + # number of background regions to skip next to On region
  255 + self['bkgregmin'].integer()
  256 + self['bkgregskip'].integer()
245 257  
246 258 # Return
247 259 return
... ... @@ -284,6 +296,58 @@ class csphagen(ctools.csobservation):
284 296 # Return
285 297 return
286 298  
  299 + def _get_parameters_bkgmethod_off(self):
  300 + """
  301 + Get parameters for OFF background method
  302 +
  303 + Raises
  304 + ------
  305 + RuntimeError
  306 + On and Off observations must have same size
  307 + """
  308 +
  309 + # Set up Off observations
  310 + # If there are no Off observations in container then load them via user parameters
  311 + if self.obs_off().is_empty():
  312 + filename = self['inobsoff'].filename()
  313 + # If it is a FITS file load into observation and append to container
  314 + if gammalib.GFilename(filename).is_fits():
  315 + self._obs_off.append(gammalib.GCTAObservation(filename))
  316 + # Otherwise load file into container
  317 + else:
  318 + self._obs_off.load(filename)
  319 +
  320 + # Check that size of On and Off observations are the same, otherwise throw error
  321 + if self.obs().size() != self._obs_off.size():
  322 + raise RuntimeError('On and Off observations must have the same size')
  323 +
  324 + # Loop through observations
  325 + for obs in self.obs_off():
  326 + # Check that observation is event list, otherwise throw error
  327 + if obs.eventtype() != "EventList":
  328 + raise RuntimeError('Off observations must be event lists')
  329 + # Check that they have response, otherwise assign based on user parameter
  330 + if obs.has_response() == False:
  331 + database = self["caldb"].string()
  332 + irf = self["irf"].string()
  333 + # xml element for response
  334 + response_xml = "parameter name=\"Calibration\"" +\
  335 + " database=\"" + database + "\"" +\
  336 + " response=\"" + irf + "\""
  337 + print(response_xml)
  338 + xml = gammalib.GXmlElement()
  339 + xml.append(response_xml)
  340 + print(xml)
  341 + # define response and assign to observation
  342 + response = gammalib.GCTAResponseIrf(xml)
  343 + obs.response(response)
  344 +
  345 + # Query parameters for source/On region definition
  346 + self._get_source_parameters()
  347 +
  348 + # Return
  349 + return
  350 +
287 351 def _get_parameters_bkgmethod(self):
288 352 """
289 353 Get background method parameters
... ... @@ -296,9 +360,12 @@ class csphagen(ctools.csobservation):
296 360 self._get_parameters_bkgmethod_reflected()
297 361 elif bkgmethod == 'CUSTOM':
298 362 self._get_parameters_bkgmethod_custom()
  363 + elif bkgmethod == 'OFF':
  364 + self._get_parameters_bkgmethod_off()
299 365  
300 366 # Query parameters that are needed for all background methods
301 367 self['maxoffset'].real()
  368 + self['use_model_bkg'].boolean()
302 369  
303 370 # Return
304 371 return
... ... @@ -351,9 +418,9 @@ class csphagen(ctools.csobservation):
351 418 else:
352 419 self._has_exclusion = False
353 420  
354   - # Query remaining parameters
355   - self['use_model_bkg'].boolean()
356   - self['stack'].boolean()
  421 + # If there are multiple observations query whether to stack them
  422 + if self.obs().size() > 1:
  423 + self['stack'].boolean()
357 424  
358 425 # Query ahead output parameters
359 426 if (self._read_ahead()):
... ... @@ -361,11 +428,6 @@ class csphagen(ctools.csobservation):
361 428 self['outmodel'].filename()
362 429 self['prefix'].string()
363 430  
364   - # If there are no observations in container then get them from the
365   - # parameter file
366   - if self.obs().is_empty():
367   - self.obs(self._get_observations(False))
368   -
369 431 # Get background method parameters (have to come after setting up of
370 432 # observations)
371 433 self._get_parameters_bkgmethod()
... ... @@ -459,14 +521,6 @@ class csphagen(ctools.csobservation):
459 521 if self._srcshape == 'CIRCLE':
460 522 msg += ' (circle rad=%.3f).' % (self._rad)
461 523 self._log_string(gammalib.NORMAL, msg)
462   -
463   - # Skip observation if it is pointed too far from the source
464   - elif offset >= self['maxoffset'].real():
465   - msg = ' Skip because observation is pointed at %.3f deg >= '\
466   - '"maxoffset=%.3f" from source.' \
467   - % (offset, self['maxoffset'].real())
468   - self._log_string(gammalib.NORMAL, msg)
469   -
470 524 # ... otherwise
471 525 else:
472 526 posang = pnt_dir.posang_deg(self._src_dir)
... ... @@ -474,7 +528,6 @@ class csphagen(ctools.csobservation):
474 528  
475 529 # Determine number of background regions to skip
476 530 N_skip = self['bkgregskip'].integer()
477   - N_start = 1 + N_skip
478 531 N_lim = 1 + 2 * N_skip
479 532  
480 533 # Compute the angular separation of reflected regions wrt
... ... @@ -532,13 +585,78 @@ class csphagen(ctools.csobservation):
532 585 regions.append(region)
533 586 dphi += alpha
534 587  
535   - # Log number of reflected regions
536   - msg = ' Use %d reflected regions.' % (regions.size())
537   - self._log_string(gammalib.NORMAL, msg)
  588 + # Check again that we have enough background regions
  589 + # now that we have checked for overlap with exclusion region
  590 + if regions.size() >= self['bkgregmin'].integer():
  591 + # Log number of reflected regions
  592 + msg = ' Use %d reflected regions.' % (regions.size())
  593 + self._log_string(gammalib.NORMAL, msg)
  594 + # Otherwise log observation skipped and return empty region container
  595 + else:
  596 + msg = ' Skip because the number %d of regions' \
  597 + 'for background estimation not overlapping ' \
  598 + 'with the exclusion region is smaller than ' \
  599 + '"bkgregmin"=%d.' % (bkg_reg.size(), self['bkgregmin'].integer())
  600 + self._log_string(gammalib.NORMAL, msg)
  601 + regions = gammalib.GSkyRegions()
538 602  
539 603 # Return reflected regions
540 604 return regions
541 605  
  606 + def _instrument_regions(self, obs, obs_off):
  607 + """
  608 + Calculate background region in Off observation that corresponds to the source region
  609 + in the On observation in instrument coordinates
  610 +
  611 + Parameters
  612 + ----------
  613 + obs : `~gammalib.GCTAObservation()`
  614 + On CTA observation
  615 + obs_off : `~gammalib.GCTAObservation()`
  616 + Off CTA observation
  617 +
  618 + Returns
  619 + -------
  620 + regions : `~gammalib.GSkyRegions`
  621 + Container with background region
  622 + """
  623 + # Initialise region container
  624 + regions = gammalib.GSkyRegions()
  625 +
  626 + # Convert source position in On observation to instrument coordinates
  627 + instdir = obs.pointing().instdir(self._src_dir)
  628 +
  629 + # Convert instrument position to sky direction for Off observation
  630 + off_dir = obs_off.pointing().skydir(instdir)
  631 +
  632 + # Build region according to shape specified by user
  633 + # If circle
  634 + if self._srcshape == 'CIRCLE':
  635 + region = gammalib.GSkyRegionCircle(off_dir, self._rad)
  636 + # ... otherwise if rectangle
  637 + elif self._srcshape == 'RECT':
  638 + # Instrument coordinates take sky direction as reference
  639 + # so no need to change the position angle
  640 + region = gammalib.GSkyRegionRectangle(off_dir,
  641 + self._reg_width,
  642 + self._reg_height,
  643 + self._reg_posang)
  644 +
  645 + # Check if background region overlaps with exclusion region
  646 + is_valid = True
  647 + if self._has_exclusion:
  648 + if self._excl_reg.overlaps(region):
  649 + # Signal region overlap
  650 + msg = ' Background region overlaps with ' \
  651 + 'exclusion region.'
  652 + self._log_string(gammalib.EXPLICIT, msg)
  653 + is_valid = False
  654 + # ... otherwise store region in container
  655 + regions.append(region)
  656 +
  657 + # Return
  658 + return regions
  659 +
542 660 def _set_models(self, results):
543 661 """
544 662 Set models for On/Off fitting
... ... @@ -587,7 +705,7 @@ class csphagen(ctools.csobservation):
587 705 # observations
588 706 for result in results:
589 707 if model.is_valid(result['instrument'], result['id']):
590   - if result['bkg_reg'].size() >= self['bkgregmin'].integer():
  708 + if result['bkg_reg'].size() > 0:
591 709 use_model = True
592 710 break
593 711  
... ... @@ -699,7 +817,7 @@ class csphagen(ctools.csobservation):
699 817 # Return energy boundaries
700 818 return ebounds
701 819  
702   - def _set_background_regions(self, obs):
  820 + def _set_background_regions(self, obs, obs_off=None):
703 821 """
704 822 Set background regions for an observation
705 823  
... ... @@ -716,7 +834,7 @@ class csphagen(ctools.csobservation):
716 834 # Initialise empty background regions for this observation
717 835 bkg_reg = gammalib.GSkyRegions()
718 836  
719   - # If reflected background is requested then created reflected
  837 + # If reflected background is requested then create reflected
720 838 # background regions
721 839 if self['bkgmethod'].string() == 'REFLECTED':
722 840 bkg_reg = self._reflected_regions(obs)
... ... @@ -728,6 +846,11 @@ class csphagen(ctools.csobservation):
728 846 elif self['bkgmethod'].string() == 'CUSTOM':
729 847 bkg_reg = obs.off_regions().copy()
730 848  
  849 + # ... otherwise if dedicated Off runs are use then
  850 + # use background region that correspond to the same instrument coordinates
  851 + if self['bkgmethod'].string() == 'OFF':
  852 + bkg_reg = self._instrument_regions(obs,obs_off)
  853 +
731 854 # Return background regions
732 855 return bkg_reg
733 856  
... ... @@ -750,6 +873,13 @@ class csphagen(ctools.csobservation):
750 873 bkg_reg = None
751 874 obs = self.obs()[i]
752 875  
  876 + # Retrieve dedicated Off observation if it exists
  877 + if not self.obs_off().is_empty():
  878 + obs_off = self.obs_off()[i]
  879 + # Otherwise use the same as On
  880 + else:
  881 + obs_off = self.obs()[i]
  882 +
753 883 # Log header
754 884 self._log_header3(gammalib.NORMAL,'%s observation "%s"' % \
755 885 (obs.instrument(), obs.id()))
... ... @@ -768,32 +898,43 @@ class csphagen(ctools.csobservation):
768 898 msg = ' Background model not used, assume constant backround rate.'
769 899 self._log_string(gammalib.NORMAL, msg)
770 900  
771   - # Set background regions for this observation
772   - bkg_reg = self._set_background_regions(obs)
  901 + # Get offset angle of source
  902 + pnt_dir = obs.pointing().dir()
  903 + offset = pnt_dir.dist_deg(self._src_dir)
773 904  
774   - # If there are background regions then create On/Off observation
775   - # and append it to the output container
776   - if bkg_reg.size() >= self['bkgregmin'].integer():
  905 + # Skip observation if it is pointed too far from the source
  906 + if offset >= self['maxoffset'].real():
  907 + msg = ' Skip because observation is pointed at %.3f deg >= ' \
  908 + '"maxoffset=%.3f" from source.' \
  909 + % (offset, self['maxoffset'].real())
  910 + self._log_string(gammalib.NORMAL, msg)
  911 + # ... otherwise continue to process
  912 + else:
777 913  
778   - # Create On/Off observation
779   - onoff = gammalib.GCTAOnOffObservation(obs,
780   - self._models,
781   - self._srcname,
782   - self._etruebounds,
783   - self._ebounds,
784   - self._src_reg,
785   - bkg_reg,
786   - use_model_bkg)
  914 + # Set background regions for this observation
  915 + bkg_reg = self._set_background_regions(obs,obs_off)
787 916  
788   - # Set On/Off observation ID
789   - onoff.id(obs.id())
  917 + # If there are any background regions then create On/Off observation
  918 + # and append it to the output container
  919 + if bkg_reg.size() >= 0:
790 920  
791   - # Otherwise log observation skipped
792   - else:
793   - msg = ' Skip because the number %d of regions ' \
794   - 'for background estimation is smaller than ' \
795   - '"bkgregmin"=%d.' % (bkg_reg.size(), self['bkgregmin'].integer())
796   - self._log_string(gammalib.NORMAL, msg)
  921 + # Create On/Off observation
  922 + onoff = gammalib.GCTAOnOffObservation(obs, obs_off,
  923 + self._models,
  924 + self._srcname,
  925 + self._etruebounds,
  926 + self._ebounds,
  927 + self._src_reg,
  928 + bkg_reg,
  929 + use_model_bkg)
  930 +
  931 + # Set On/Off observation ID
  932 + onoff.id(obs.id())
  933 +
  934 + # Otherwise log observation skipped
  935 + else:
  936 + msg = ' Skip because no valid Off regions could be determined'
  937 + self._log_string(gammalib.NORMAL, msg)
797 938  
798 939 # Construct dictionary with results
799 940 result = {'onoff' : onoff,
... ... @@ -854,6 +995,8 @@ class csphagen(ctools.csobservation):
854 995  
855 996 # Write observation into logger
856 997 self._log_observations(gammalib.NORMAL, self.obs(), 'Observation')
  998 + if not self.obs_off().is_empty():
  999 + self._log_observations(gammalib.NORMAL, self._obs_off, 'Off Observation')
857 1000  
858 1001 # Set true energy bins
859 1002 self._etruebounds = self._etrue_ebounds()
... ... @@ -1032,6 +1175,27 @@ class csphagen(ctools.csobservation):
1032 1175 # Return
1033 1176 return self._excl_reg
1034 1177  
  1178 + def obs_off(self, obs=None):
  1179 + """
  1180 + Return and optionally set the Off observations
  1181 +
  1182 + Parameters
  1183 + ----------
  1184 + obs : `~gammalib.GCTAObservations`
  1185 + Off observations container
  1186 +
  1187 + Returns
  1188 + -------
  1189 + observation container : `~gammalib.GCTAObservations`
  1190 + Off observations container
  1191 + """
  1192 + # If an observation container is provided then set the Off observations ...
  1193 + if obs is not None:
  1194 + self._obs_off = obs
  1195 +
  1196 + # Return
  1197 + return self._obs_off
  1198 +
1035 1199  
1036 1200 # ======================== #
1037 1201 # Main routine entry point #
... ...
doc/source/users/reference_manual/csphagen.rst
... ... @@ -17,17 +17,16 @@ the OGIP format normally used in X-ray astronomy (PHA, ARF, RMF),
17 17 If the ``bkgmethod`` parameter is ``REFLECTED``, the script will use an On region
18 18 shape defined by the ``srcshape`` parameter and generate reflected regions by
19 19 placing regions of the same shape that are reflected with respect to the
20   -pointing direction. So far circular and rectangular regions are supported.
21   -Circular regions are defined by a center that is specified by the ``ra`` and
22   -``dec`` parameters if ``coordsys=CEL`` or the ``glon`` and ``glat`` parameters if
  20 +pointing direction within the same observation. So far circular and
  21 +rectangular regions are supported. Circular regions are defined by a
  22 +center that is specified by the ``ra`` and ``dec`` parameters if
  23 +``coordsys=CEL`` or the ``glon`` and ``glat`` parameters if
23 24 ``coordsys=GAL``, and a radius that is specified by the ``rad`` parameter.
24 25 Rectangular regions are defined by a center, again specified by either the
25 26 ``ra`` and ``dec`` or the ``glon`` and ``glat`` parameters, a ``width`` parameter,
26 27 a ``height`` parameter and a ``posang`` parameter that specified the position
27 28 angle measured counter clockwise from celestial North. Note that the ``height``
28   -axis is pointing in the direction of the position angle. Reflected regions are
29   -only generated for offset angles with respect to the pointing direction that are
30   -smaller than the value specified by the ``maxoffset`` parameter. If less than
  29 +axis is pointing in the direction of the position angle. If less than
31 30 ``bkgregmin`` reflected regions can be found because the offset angle between
32 31 source and pointing direction is too small, the observation will be skipped.
33 32 Regions to be excluded for background determination can be specified using a
... ... @@ -44,7 +43,7 @@ respectively. Both parameters accept either a ds9 region file or a sky map where
44 43 all non-zero pixel values define a region. In case that an observation definition
45 44 XML file is specified as input using the ``inobs``, background region files can
46 45 be specified separately for each observation using the ``OffRegions`` parameter
47   -in the format
  46 +in the format.
48 47  
49 48 .. code-block:: xml
50 49  
... ... @@ -53,6 +52,16 @@ in the format
53 52 ...
54 53 </observation>
55 54  
  55 +Finally, if ``bkgmethod=OFF`` is specified, the background regions
  56 +will be taken from independent Off observations given by the
  57 +``inobsoff`` parameter. The On region can be defined in the same way
  58 +as for ``bkgmethod=REFLECTED``, and the Off regions are the
  59 +corresponding regions in instrument coordinates from the Off observations.
  60 +
  61 +For all background estimation methods only observations with a
  62 +pointing direction at an offset smaller than ``maxoffset`` from the
  63 +source are used.
  64 +
56 65 :ref:`csphagen` supports multiprocessing. By default each event list will be treated
57 66 in parallel over as many processes as the number of CPUs available on your
58 67 machine. The maximum number of parallel processes can be set by the user through the
... ... @@ -78,6 +87,11 @@ General parameters
78 87 ``inobs [file]``
79 88 Input event list or observation definition XML file.
80 89  
  90 +``inobsoff [file]``
  91 + Input event list or observation definition XML file for dedicated
  92 + Off observations. The number of observations must be the same as
  93 + for ``inobs``.
  94 +
81 95 ``inmodel [file]``
82 96 Input model XML file (if ``NONE`` a point source at the centre of the
83 97 source region is used).
... ... @@ -172,7 +186,7 @@ General parameters
172 186 ``srcregfile [file]``
173 187 Source region file (ds9 or FITS WCS map).
174 188  
175   -``bkgmethod <REFLECTED|CUSTOM> [string]``
  189 +``bkgmethod <REFLECTED|CUSTOM|OFF> [string]``
176 190 Method for background estimation:
177 191  
178 192 - ``REFLECTED``: background is evaluated in regions with the same shape as
... ... @@ -184,18 +198,25 @@ General parameters
184 198 observations specified in the observation definition XML file the name of
185 199 the region file will be extracted from the ``OffRegions`` parameter that
186 200 needs to be specified for each observation in the observation definition
187   - XML file. Off region files can be either ds9 region files or FITS WCS maps.
  201 + XML file. Off region files can be either ds9 region files or
  202 + FITS WCS maps.
  203 +
  204 + - ``OFF``: background is evaluated from dedicated Off
  205 + observations in regions that correspond to the source region
  206 + in the On observations in instrument coordinates.
188 207  
189 208 ``bkgregfile [file]``
190 209 Background regions file (ds9 or FITS WCS map).
191 210  
192 211 ``(bkgregmin = 2) [integer]``
193   - Minimum number of background regions that are required for an observation.
  212 + Minimum number of background regions that are required for an
  213 + observation when the ``REFLECTED`` background estimation is used.
194 214 If this number of background regions is not available the observation is
195 215 skipped.
196 216  
197 217 ``(bkgregskip = 1) [integer]``
198   - Number of background regions that should be skipped next to the On regions.
  218 + Number of background regions that should be skipped next to the On
  219 + region when the ``REFLECTED`` background estimation is used.
199 220 Typically, one region is skipped so that the Off regions are taken sufficiently
200 221 distant from the On region, but in some cases it may be useful to keep the
201 222 background regions next to the On region.
... ...
test/data/background_events.fits 0 โ†’ 100644
No preview for this file type
test/test_csphagen.py
... ... @@ -46,6 +46,7 @@ class Test(test):
46 46 self._myevents1 = self._datadir + '/crab_offaxis1.fits'
47 47 self._myevents2 = self._datadir + '/crab_offaxis2.fits'
48 48 self._exclusion = self._datadir + '/crab_exclusion.fits'
  49 + self._offevents = self._datadir + '/background_events.fits'
49 50 self._nreg_with_excl = 5
50 51 self._nreg_wo_excl = 8
51 52 self._nreg_bkg_reg = 5
... ... @@ -414,6 +415,101 @@ class Test(test):
414 415 self._check_output('csphagen_py8', self._nbins, 9)
415 416 self._check_outobs('csphagen_py8_obs.xml', 1)
416 417  
  418 + # Setup csphagen for test with dedicated Off observations
  419 + phagen = cscripts.csphagen()
  420 + phagen['inobs'] = self._myevents1
  421 + phagen['inobsoff'] = self._offevents
  422 + phagen['inmodel'] = 'NONE'
  423 + phagen['caldb'] = self._caldb
  424 + phagen['irf'] = self._irf
  425 + phagen['ebinalg'] = 'LOG'
  426 + phagen['emin'] = 0.1
  427 + phagen['emax'] = 100.0
  428 + phagen['enumbins'] = self._nbins
  429 + phagen['bkgmethod'] = 'OFF'
  430 + phagen['etruemin'] = 0.05
  431 + phagen['etruemax'] = 150.0
  432 + phagen['etruebins'] = 5
  433 + phagen['stack'] = False
  434 + phagen['outobs'] = 'csphagen_py9_obs.xml'
  435 + phagen['outmodel'] = 'csphagen_py9_model.xml'
  436 + phagen['prefix'] = 'csphagen_py9'
  437 + phagen['logfile'] = 'csphagen_py9.log'
  438 + phagen['chatter'] = 2
  439 +
  440 + # Execute script
  441 + phagen.execute()
  442 +
  443 + # Check output
  444 + self._check_output('csphagen_py9', self._nbins, 1)
  445 + self._check_outobs('csphagen_py9_obs.xml', 1)
  446 +
  447 + # Setup csphagen for test with dedicated Off observations
  448 + # and exclusion region
  449 + phagen = cscripts.csphagen()
  450 + phagen['inobs'] = self._myevents1
  451 + phagen['inobsoff'] = self._offevents
  452 + phagen['inmodel'] = 'NONE'
  453 + phagen['caldb'] = self._caldb
  454 + phagen['irf'] = self._irf
  455 + phagen['ebinalg'] = 'LOG'
  456 + phagen['emin'] = 0.1
  457 + phagen['emax'] = 100.0
  458 + phagen['enumbins'] = self._nbins
  459 + phagen['inexclusion'] = self._exclusion
  460 + phagen['bkgmethod'] = 'OFF'
  461 + phagen['etruemin'] = 0.05
  462 + phagen['etruemax'] = 150.0
  463 + phagen['etruebins'] = 5
  464 + phagen['stack'] = False
  465 + phagen['outobs'] = 'csphagen_py10_obs.xml'
  466 + phagen['outmodel'] = 'csphagen_py10_model.xml'
  467 + phagen['prefix'] = 'csphagen_py10'
  468 + phagen['logfile'] = 'csphagen_py10.log'
  469 + phagen['chatter'] = 2
  470 +
  471 + # Execute script
  472 + phagen.execute()
  473 +
  474 + # Check output
  475 + self._check_output('csphagen_py10', self._nbins, 1)
  476 + self._check_outobs('csphagen_py10_obs.xml', 1)
  477 +
  478 + # Test with multiple input observations and dedicated Off runs
  479 + # Create Off observation container
  480 + obs_off = gammalib.GObservations()
  481 + for s, events in enumerate([self._offevents, self._offevents]):
  482 + run = gammalib.GCTAObservation(events)
  483 + run.id(str(s + 1))
  484 + run.response(self._irf, gammalib.GCaldb('cta', self._caldb))
  485 + obs_off.append(run)
  486 +
  487 + # Setup csphagen
  488 + phagen = cscripts.csphagen(obs)
  489 + phagen.obs_off(obs_off)
  490 + phagen['inmodel'] = 'NONE'
  491 + phagen['ebinalg'] = 'LOG'
  492 + phagen['emin'] = 0.1
  493 + phagen['emax'] = 100.0
  494 + phagen['enumbins'] = self._nbins
  495 + phagen['bkgmethod'] = 'OFF'
  496 + phagen['etruemin'] = 0.05
  497 + phagen['etruemax'] = 150.0
  498 + phagen['etruebins'] = 5
  499 + phagen['stack'] = False
  500 + phagen['outobs'] = 'csphagen_py11_obs.xml'
  501 + phagen['outmodel'] = 'csphagen_py11_model.xml'
  502 + phagen['prefix'] = 'csphagen_py11'
  503 + phagen['logfile'] = 'csphagen_py11.log'
  504 + phagen['chatter'] = 2
  505 +
  506 + # Execute script
  507 + phagen.execute()
  508 +
  509 + # Check output
  510 + self._check_output('csphagen_py11', self._nbins, 1)
  511 + self._check_outobs('csphagen_py11_obs.xml', 1)
  512 +
417 513 # Return
418 514 return
419 515  
... ...