diff --git a/ChangeLog b/ChangeLog index 449d256..66fef8e 100755 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,9 @@ -2018-11-16 +2018-11-22 * Version 1.6.0 released ======================== + ctbkgcube now requires an input counts cube (#2763) CTA background rates are now per ontime (#2758) Apply event bin weighting in ctmodel for stacked computation (#2721) Enable ctbin to produce counts cubes for a joint binned analysis (#2714) diff --git a/NEWS b/NEWS index f314b1f..cbc6c6d 100755 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ New Features and Important Changes in ctools 1.6.0 -16 November 2018 +22 November 2018 Introduction @@ -83,6 +83,11 @@ Copy the time reference from the first input observation (#2054). ctbkgcube - CTA background cube generation ------------------------------------------ +The tool now required a counts cube on input, either specified via the +ctbkgcube::cntcube() method or the "incube" parameter. This assures that the +background cube has the same dimension as the counts cube. All spatial and +spectral binning parameters were removed from the parameter file (#2763). + Add ctbkgcube::cntcube() method so that a counts cube be specified as instance before running the tool. This avoids storing the counts cube on disk if the counts cube definition should be used to generate a background diff --git a/cscripts/obsutils.py b/cscripts/obsutils.py index f775403..fa29e85 100755 --- a/cscripts/obsutils.py +++ b/cscripts/obsutils.py @@ -185,14 +185,10 @@ def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, # proper background cube. cntcube = binning.cube() - # Get stacked response (use pointing for map centre) - response = get_stacked_response(obssim.obs(), None, None, - binsz=binsz, nxpix=npix, nypix=npix, - emin=emin, emax=emax, enumbins=nbins, + # Get stacked response + response = get_stacked_response(obssim.obs(), cntcube, edisp=edisp, - coordsys=coord, proj=proj, addbounds=addbounds, - cntcube=cntcube, log=log, debug=debug, chatter=chatter) @@ -519,50 +515,24 @@ def set_observations(ra, dec, rad, tstart, duration, emin, emax, irf, caldb, # ==================== # # Get stacked response # # ==================== # -def get_stacked_response(obs, xref, yref, binsz=0.05, nxpix=200, nypix=200, - emin=0.1, emax=100.0, enumbins=20, edisp=False, - coordsys='GAL', proj='TAN', addbounds=False, - cntcube=None, log=False, debug=False, chatter=2): +def get_stacked_response(obs, cntcube, edisp=False, addbounds=False, + log=False, debug=False, chatter=2): """ Get stacked response cubes - The number of energies bins are set to at least 30 bins per decade, and - the "enumbins" parameter is only used if the number of bins is larger - than 30 bins per decade. - - If the xref or yref arguments are "None" the response cube centre will be - determined from the pointing information in the observation container. + The number of energies bins are set to at least 30 bins per decade, unless + the counts cube has more energy bins per decade. Parameters ---------- obs : `~gammalib.GObservations` Observation container - xref : float - Right Ascension or Galactic longitude of response centre (deg) - yref : float - Declination or Galactic latitude of response centre (deg) - binsz : float, optional - Pixel size (deg/pixel) - nxpix : int, optional - Number of pixels in X direction - nypix : int, optional - Number of pixels in Y direction - emin : float, optional - Minimum energy (TeV) - emax : float, optional - Maximum energy (TeV) - enumbins : int, optional - Number of energy bins + cntcube : `~gammalib.GCTAEventCube` + Counts cube edisp : bool, optional Apply energy dispersion? - coordsys : str, optional - Coordinate system - proj : str, optional - Projection addbounds : bool, optional Add boundaries at observation energies - cntcube : `~gammalib.GCTAEventCube`, optional - Counts cube log : bool, optional Create log file(s) debug : bool, optional @@ -575,26 +545,32 @@ def get_stacked_response(obs, xref, yref, binsz=0.05, nxpix=200, nypix=200, result : dict Dictionary of response cubes """ - # If no xref and yref arguments have been specified then use the pointing - # information - if xref == None or yref == None: - usepnt = True - else: - usepnt = False + # Derive binning parameters from counts cube + xref = cntcube.counts().projection().crval(0) + yref = cntcube.counts().projection().crval(1) + binsz = cntcube.counts().projection().cdelt(1) + coordsys = cntcube.counts().projection().coordsys() + proj = cntcube.counts().projection().code() + nxpix = cntcube.nx() + nypix = cntcube.ny() + emin = cntcube.emin().TeV() + emax = cntcube.emax().TeV() + ebins = cntcube.ebins() + + # Translate coordinate system + if coordsys == 'EQU': + coordsys = 'CEL' # Set energy limits, with larger etrue limits for the case that energy # dispersion is requested if edisp: - _emin = 0.5 * emin - _emax = 1.5 * emax - else: - _emin = emin - _emax = emax + emin *= 0.5 + emax *= 1.5 # Set number of energy bins to at least 30 per energy decade - _enumbins = int((math.log10(_emax) - math.log10(_emin)) * 30.0) - if enumbins > _enumbins: - _enumbins = enumbins + enumbins = int((math.log10(emax) - math.log10(emin)) * 30.0) + if ebins > enumbins: + enumbins = ebins # Compute spatial binning for point spread function and energy dispersion # cubes. The spatial binning is 10 times coarser than the spatial binning @@ -606,22 +582,20 @@ def get_stacked_response(obs, xref, yref, binsz=0.05, nxpix=200, nypix=200, # Create exposure cube expcube = ctools.ctexpcube(obs) expcube['incube'] = 'NONE' - expcube['usepnt'] = usepnt expcube['ebinalg'] = 'LOG' + expcube['xref'] = xref + expcube['yref'] = yref expcube['binsz'] = binsz expcube['nxpix'] = nxpix expcube['nypix'] = nypix - expcube['enumbins'] = _enumbins - expcube['emin'] = _emin - expcube['emax'] = _emax + expcube['enumbins'] = enumbins + expcube['emin'] = emin + expcube['emax'] = emax expcube['coordsys'] = coordsys expcube['proj'] = proj expcube['addbounds'] = addbounds expcube['debug'] = debug expcube['chatter'] = chatter - if not usepnt: - expcube['xref'] = xref - expcube['yref'] = yref if log: expcube.logFileOpen() expcube.run() @@ -629,22 +603,20 @@ def get_stacked_response(obs, xref, yref, binsz=0.05, nxpix=200, nypix=200, # Create point spread function cube psfcube = ctools.ctpsfcube(obs) psfcube['incube'] = 'NONE' - psfcube['usepnt'] = usepnt psfcube['ebinalg'] = 'LOG' + psfcube['xref'] = xref + psfcube['yref'] = yref psfcube['binsz'] = psf_binsz psfcube['nxpix'] = psf_nxpix psfcube['nypix'] = psf_nypix - psfcube['enumbins'] = _enumbins - psfcube['emin'] = _emin - psfcube['emax'] = _emax + psfcube['enumbins'] = enumbins + psfcube['emin'] = emin + psfcube['emax'] = emax psfcube['coordsys'] = coordsys psfcube['proj'] = proj psfcube['addbounds'] = addbounds psfcube['debug'] = debug psfcube['chatter'] = chatter - if not usepnt: - psfcube['xref'] = xref - psfcube['yref'] = yref if log: psfcube.logFileOpen() psfcube.run() @@ -653,26 +625,9 @@ def get_stacked_response(obs, xref, yref, binsz=0.05, nxpix=200, nypix=200, # for the counts cube since no interpolation should be actually done # for the background cube. bkgcube = ctools.ctbkgcube(obs) - if cntcube != None: - bkgcube.cntcube(cntcube) - else: - bkgcube['incube'] = 'NONE' - bkgcube['ebinalg'] = 'LOG' - bkgcube['binsz'] = binsz - bkgcube['nxpix'] = nxpix - bkgcube['nypix'] = nypix - bkgcube['enumbins'] = enumbins - bkgcube['emin'] = emin - bkgcube['emax'] = emax - bkgcube['coordsys'] = coordsys - bkgcube['proj'] = proj - if not usepnt: - bkgcube['xref'] = xref - bkgcube['yref'] = yref - bkgcube['usepnt'] = usepnt - bkgcube['addbounds'] = addbounds - bkgcube['debug'] = debug - bkgcube['chatter'] = chatter + bkgcube.cntcube(cntcube) + bkgcube['debug'] = debug + bkgcube['chatter'] = chatter if log: bkgcube.logFileOpen() bkgcube.run() @@ -681,22 +636,20 @@ def get_stacked_response(obs, xref, yref, binsz=0.05, nxpix=200, nypix=200, if edisp: edispcube = ctools.ctedispcube(obs) edispcube['incube'] = 'NONE' - edispcube['usepnt'] = usepnt edispcube['ebinalg'] = 'LOG' + edispcube['xref'] = xref + edispcube['yref'] = yref edispcube['binsz'] = psf_binsz edispcube['nxpix'] = psf_nxpix edispcube['nypix'] = psf_nypix - edispcube['enumbins'] = _enumbins - edispcube['emin'] = _emin - edispcube['emax'] = _emax + edispcube['enumbins'] = enumbins + edispcube['emin'] = emin + edispcube['emax'] = emax edispcube['coordsys'] = coordsys edispcube['proj'] = proj edispcube['addbounds'] = addbounds edispcube['debug'] = debug edispcube['chatter'] = chatter - if not usepnt: - edispcube['xref'] = xref - edispcube['yref'] = yref if log: edispcube.logFileOpen() edispcube.run() @@ -756,26 +709,14 @@ def get_stacked_obs(cls, obs): # Store counts cube so that we can use it to build the background # cube - cube = cntcube.cube().copy() + cube = cntcube.cube() # Write header if cls._logExplicit(): cls._log.header3('Creating stacked response') # Get stacked response - response = get_stacked_response(obs, - cls['xref'].real(), - cls['yref'].real(), - binsz=cls['binsz'].real(), - nxpix=cls['nxpix'].integer(), - nypix=cls['nypix'].integer(), - emin=cls['emin'].real(), - emax=cls['emax'].real(), - enumbins=cls['enumbins'].integer(), - edisp=cls['edisp'].boolean(), - coordsys=cls['coordsys'].string(), - proj=cls['proj'].string(), - cntcube=cube) + response = get_stacked_response(obs, cube, edisp=cls['edisp'].boolean()) # Retrieve a new oberservation container new_obs = cntcube.obs().copy() diff --git a/doc/source/admin/release_history/1.6.rst b/doc/source/admin/release_history/1.6.rst index 9967f14..76413c1 100644 --- a/doc/source/admin/release_history/1.6.rst +++ b/doc/source/admin/release_history/1.6.rst @@ -43,6 +43,8 @@ Bug fixes Improvements ------------ +* [`2763 `_] - + :ref:`ctbkgcube` now requires an input counts cube * [`2714 `_] - Enable :ref:`ctbin` to produce counts cubes for a joint binned analysis. Rename ``outcube`` to ``outobs`` parameter. diff --git a/doc/source/users/reference_manual/ctbkgcube.rst b/doc/source/users/reference_manual/ctbkgcube.rst index e7f0d54..9ef5c46 100755 --- a/doc/source/users/reference_manual/ctbkgcube.rst +++ b/doc/source/users/reference_manual/ctbkgcube.rst @@ -18,21 +18,14 @@ background counts in each background cube bin. :ref:`ctbkgcube` requires on input the event list or observation definition file that has been used in the generation of the counts cube using :doc:`ctbin`. - -To assure consistency between an existing counts cube and the -corresponding background cube, it is recommended to specify the counts -cube as ``incube`` parameter. This will instruct ctbkgcube to extract the -background cube definition (such as sky coordinates and projection, number -of pixels, pixel scale, energy binning) from the counts cube. - -Note that there should at least be 25 bins per energy decade in the background -cube to assure that the energy dependence of the background rate is sufficiently -well sampled (in particular at low energies). +To assure consistency between an existing counts cube and the +corresponding background cube, the counts cube needs also to be specified via +the ``incube`` parameter. :ref:`ctbkgcube` generates a background cube FITS file comprising two extensions. The primary extension contains a 3-dimensional image that contains the -background cube values. The next extension named ``ENERGIES`` contains a -binary table that defines the energies of the background cube. +background cube values. The next extension named ``EBOUNDS`` contains a +binary table that defines the energy boundaries of the background cube. :ref:`ctbkgcube` generates also an output model XML file that can serve as input for a maximum likelihood analysis. The output model XML file is a copy of @@ -53,12 +46,12 @@ General parameters ``inobs [file]`` Input event list or observation definition XML file. -``inmodel [file]`` - Input model XML file. - ``incube [file]`` Input counts cube file to extract background cube definition. +``inmodel [file]`` + Input model XML file. + ``caldb [string]`` Calibration database. @@ -71,55 +64,6 @@ General parameters ``outmodel [file]`` Output model XML file. -``ebinalg [string]`` - Algorithm for defining energy bins. For ``FILE``, the energy bins are defined - in a FITS file that is specified by the ``ebinfile`` parameter, for ``LIN`` - and ``LOG`` there will be ``enumbins`` energy bins spaced linearly or - logarithmically between ``emin`` and ``emax``, respectively. - -``emin [real]`` - Lower energy value for first energy bin (in TeV) if ``LIN`` or ``LOG`` - energy binning algorithms are used. - -``emax [real]`` - Upper energy value for last energy bin (in TeV) if ``LIN`` or ``LOG`` - energy binning algorithms are used. - -``enumbins [integer]`` - Number of energy bins if ``LIN`` or ``LOG`` energy binning algorithms are - used. - -``ebinfile [file]`` - Name of the file containing the energy binning definition if ``ebinalg=FILE``. - You may use :ref:`csebins` to generate a file with appropriate energy binning. - -``(addbounds = no) [boolean]`` - Add energies to the background cube at the observation energy boundaries? - -``(usepnt = no) [boolean]`` - Use CTA pointing direction for cube centre instead of xref/yref parameters? - -``nxpix [integer]`` - Number of cube bins in Right Ascension or Galactic longitude. - -``nypix [integer]`` - Number of cube bins in Declination or Galactic latitude. - -``binsz [real]`` - Cube bin size (in degrees/pixel). - -``coordsysL [string]`` - Coordinate system (CEL - celestial, GAL - galactic). - -``proj [string]`` - Projection method. - -``xref [real]`` - Right Ascension / Galactic longitude of cube centre (J2000, in degrees). - -``yref [real]`` - Declination / Galactic latitude of cube centre (J2000, in degrees). - Standard parameters ------------------- diff --git a/src/ctbkgcube/ctbkgcube.cpp b/src/ctbkgcube/ctbkgcube.cpp index b6b3bed..6d99048 100755 --- a/src/ctbkgcube/ctbkgcube.cpp +++ b/src/ctbkgcube/ctbkgcube.cpp @@ -438,7 +438,6 @@ void ctbkgcube::init_members(void) // Initialise user parameters m_outcube.clear(); m_outmodel.clear(); - m_addbounds = true; m_publish = false; m_chatter = static_cast(2); @@ -463,7 +462,6 @@ void ctbkgcube::copy_members(const ctbkgcube& app) // Copy user parameters m_outmodel = app.m_outmodel; m_outcube = app.m_outcube; - m_addbounds = app.m_addbounds; m_publish = app.m_publish; m_chatter = app.m_chatter; @@ -500,17 +498,9 @@ void ctbkgcube::get_parameters(void) // event lists, but do not accept counts cubes. setup_observations(m_obs, true, true, false); - // If there is a valid event cube than use it for construction. - // Otherwise check if "incube" file name is valid then use the specified - // counts cube. Otherwise create a counts cube from the user - // parameters + // If no counts cube exists then load one from the "incube" filename if (m_cube.size() == 0) { - if ((*this)["incube"].is_valid()) { - m_cube = GCTAEventCube((*this)["incube"].filename()); - } - else { - m_cube = create_cube(m_obs); - } + m_cube = GCTAEventCube((*this)["incube"].filename()); } // Define background cube @@ -520,9 +510,8 @@ void ctbkgcube::get_parameters(void) setup_models(m_obs); // Get remaining parameters - m_addbounds = (*this)["addbounds"].boolean(); - m_publish = (*this)["publish"].boolean(); - m_chatter = static_cast((*this)["chatter"].integer()); + m_publish = (*this)["publish"].boolean(); + m_chatter = static_cast((*this)["chatter"].integer()); // If needed later, query output filenames now if (read_ahead()) { diff --git a/src/ctbkgcube/ctbkgcube.hpp b/src/ctbkgcube/ctbkgcube.hpp index d8fa505..450d84f 100755 --- a/src/ctbkgcube/ctbkgcube.hpp +++ b/src/ctbkgcube/ctbkgcube.hpp @@ -73,7 +73,6 @@ protected: // User parameters GFilename m_outcube; //!< Filename of output cube GFilename m_outmodel; //!< Filename of output XML model - bool m_addbounds; //!< Add energies at boundaries? bool m_publish; //!< Publish background cube? GChatter m_chatter; //!< Chattiness diff --git a/src/ctbkgcube/ctbkgcube.par b/src/ctbkgcube/ctbkgcube.par index acd03c2..8e2a06c 100755 --- a/src/ctbkgcube/ctbkgcube.par +++ b/src/ctbkgcube/ctbkgcube.par @@ -17,36 +17,14 @@ # General parameters #=================== inobs, f, a, NONE,,, "Input event list or observation definition XML file" +incube, f, a, cntcube.fits,,, "Input counts cube file to extract background cube definition" inmodel, f, a, NONE,,, "Input model definition XML file" -incube, f, a, NONE,,, "Input counts cube file to extract background cube definition" caldb, s, a, prod2,,, "Calibration database" irf, s, a, South_0.5h,,, "Instrument response function" outcube, f, a, bkgcube.fits,,, "Output background cube file" outmodel, f, a, NONE,,, "Output model definition XML file" # -# Energy binning parameters -#========================== -ebinalg, s, a, LOG,FILE|LIN|LOG,, "Algorithm for defining energy bins" -emin, r, a, 0.1,,, "Lower energy limit (TeV)" -emax, r, a, 100.0,,, "Upper energy limit (TeV)" -enumbins, i, a, 20,1,200, "Number of energy bins" -ebinfile, f, a, NONE,,, "Name of the file containing the energy bin definition" -addbounds, b, h, no,,, "Add energies at observation energy boundaries?" - -# -# Spatial binning parameters -#=========================== -usepnt, b, h, no,,, "Use pointing instead of xref/yref parameters?" -nxpix, i, a, 200,,, "Size of the X axis in pixels" -nypix, i, a, 200,,, "Size of the Y axis in pixels" -binsz, r, a, 0.02,,, "Image scale (in degrees/pixel)" -coordsys, s, a, CEL, CEL|GAL,,"Coordinate system (CEL - celestial, GAL - galactic)" -proj, s, a, CAR, AIT|AZP|CAR|GLS|MER|MOL|SFL|SIN|STG|TAN,, "Projection method" -xref, r, a, 83.63,0,360, "First coordinate of image center in degrees (RA or galactic l)" -yref, r, a, 22.51,-90,90, "Second coordinate of image center in degrees (DEC or galactic b)" - -# # Standard parameters #==================== publish, b, h, no,,, "Publish sky map on VO Hub?" diff --git a/test/test_ctbkgcube.py b/test/test_ctbkgcube.py index 9bc8cc3..f9ea1c5 100755 --- a/test/test_ctbkgcube.py +++ b/test/test_ctbkgcube.py @@ -67,14 +67,11 @@ class Test(test): # Setup ctbkgcube command cmd = ctbkgcube+' inobs="'+self._events+'"'+ \ + ' incube="'+self._cntcube+'"'+ \ ' inmodel="'+self._model+'"'+ \ - ' incube="NONE"'+ \ ' outcube="ctbkgcube_cmd1.fits"'+ \ ' outmodel="ctbkgcube_cmd1.xml"'+ \ ' caldb="'+self._caldb+'" irf="'+self._irf+'"'+ \ - ' ebinalg="LOG" emin=1.0 emax=100.0 enumbins=5'+ \ - ' nxpix=10 nypix=10 binsz=0.4'+ \ - ' coordsys="CEL" proj="CAR" xref=83.63 yref=22.01'+ \ ' logfile="ctbkgcube_cmd1.log" chatter=1' # Check if execution was successful @@ -86,14 +83,11 @@ class Test(test): # Setup ctbkgcube command cmd = ctbkgcube+' inobs="event_file_that_does_not_exist.fits"'+ \ + ' incube="'+self._cntcube+'"'+ \ ' inmodel="'+self._model+'"'+ \ - ' incube="NONE"'+ \ ' outcube="ctbkgcube_cmd2.fits"'+ \ ' outmodel="ctbkgcube_cmd2.xml"'+ \ ' caldb="'+self._caldb+'" irf="'+self._irf+'"'+ \ - ' ebinalg="LOG" emin=1.0 emax=100.0 enumbins=5'+ \ - ' nxpix=10 nypix=10 binsz=0.4'+ \ - ' coordsys="CEL" proj="CAR" xref=83.63 yref=22.01'+ \ ' logfile="ctbkgcube_cmd2.log" debug=yes chatter=1' # Check if execution failed @@ -153,21 +147,10 @@ class Test(test): # Now set ctbkgcube parameters bkgcube['inobs'] = self._events + bkgcube['incube'] = self._cntcube bkgcube['inmodel'] = self._model - bkgcube['incube'] = 'NONE' bkgcube['caldb'] = self._caldb bkgcube['irf'] = self._irf - bkgcube['ebinalg'] = 'LOG' - bkgcube['emin'] = 1.0 - bkgcube['emax'] = 100.0 - bkgcube['enumbins'] = 5 - bkgcube['nxpix'] = 10 - bkgcube['nypix'] = 10 - bkgcube['binsz'] = 0.4 - bkgcube['coordsys'] = 'CEL' - bkgcube['proj'] = 'CAR' - bkgcube['xref'] = 83.63 - bkgcube['yref'] = 22.01 bkgcube['outcube'] = 'ctbkgcube_py3.fits' bkgcube['outmodel'] = 'ctbkgcube_py3.xml' bkgcube['logfile'] = 'ctbkgcube_py3.log' @@ -189,15 +172,12 @@ class Test(test): self._check_models(cpy_bkgcube.models()) # Execute copy of ctbkgcube tool again, now with a higher chatter - # level than before. In addition, use counts cube to define the - # background cube - cpy_bkgcube['incube'] = self._cntcube - cpy_bkgcube['outcube'] = 'ctbkgcube_py4.fits' - cpy_bkgcube['outmodel'] = 'ctbkgcube_py4.xml' - cpy_bkgcube['logfile'] = 'ctbkgcube_py4.log' - cpy_bkgcube['chatter'] = 3 - cpy_bkgcube['publish'] = True - cpy_bkgcube['addbounds'] = True + # level than before. In addition, publish the background cube. + cpy_bkgcube['outcube'] = 'ctbkgcube_py4.fits' + cpy_bkgcube['outmodel'] = 'ctbkgcube_py4.xml' + cpy_bkgcube['logfile'] = 'ctbkgcube_py4.log' + cpy_bkgcube['chatter'] = 3 + cpy_bkgcube['publish'] = True cpy_bkgcube.logFileOpen() # Make sure we get a log file cpy_bkgcube.execute() @@ -218,25 +198,13 @@ class Test(test): # Set-up ctbkgcube from observation container bkgcube = ctools.ctbkgcube(obs) - bkgcube['incube'] = '' - bkgcube['caldb'] = self._caldb - bkgcube['irf'] = self._irf - bkgcube['ebinalg'] = 'LOG' - bkgcube['emin'] = 0.2 - bkgcube['emax'] = 150.0 - bkgcube['enumbins'] = 5 - bkgcube['nxpix'] = 10 - bkgcube['nypix'] = 10 - bkgcube['binsz'] = 0.4 - bkgcube['coordsys'] = 'CEL' - bkgcube['proj'] = 'CAR' - bkgcube['xref'] = 83.63 - bkgcube['yref'] = 22.01 - bkgcube['outcube'] = 'ctbkgcube_py5.fits' - bkgcube['outmodel'] = 'ctbkgcube_py5.xml' - bkgcube['logfile'] = 'ctbkgcube_py5.log' - bkgcube['addbounds'] = True - bkgcube['chatter'] = 4 + bkgcube['incube'] = self._cntcube + bkgcube['caldb'] = self._caldb + bkgcube['irf'] = self._irf + bkgcube['outcube'] = 'ctbkgcube_py5.fits' + bkgcube['outmodel'] = 'ctbkgcube_py5.xml' + bkgcube['logfile'] = 'ctbkgcube_py5.log' + bkgcube['chatter'] = 4 # Execute ctbkgcube tool bkgcube.logFileOpen() # Make sure we get a log file @@ -306,6 +274,6 @@ class Test(test): """ # Check number of models self.test_value(models.size(), nmodels, 'Check number of models') - + # Return return diff --git a/test/test_obsutils.py b/test/test_obsutils.py index 051a69f..63a9e49 100755 --- a/test/test_obsutils.py +++ b/test/test_obsutils.py @@ -379,7 +379,7 @@ class Test(test): # Setup one CTA observation res = obsutils.set_obs(pnt, emin=1.0, emax=10.0) - + # Check result self.test_value(res.eventtype(), 'EventList', 'Check event type') self.test_value(res.events().ebounds().emin().TeV(), 1.0, @@ -498,94 +498,75 @@ class Test(test): # Set-up observation container obs = self._setup_sim() - # Get stacked response with xref/yref set - res = obsutils.get_stacked_response(obs, 83.6331, 22.0145, - coordsys='CEL', - binsz=0.1, nxpix=10, nypix=10, - emin=1.0, emax=100.0, enumbins=5, - edisp=False) + # Set-up counts cube + map = gammalib.GSkyMap('CAR','CEL',83.6331,22.0145,0.1,0.1,10,10,5) + emin = gammalib.GEnergy(0.1, 'TeV') + emax = gammalib.GEnergy(100.0, 'TeV') + ebds = gammalib.GEbounds(5, emin, emax) + tmin = gammalib.GTime(0.0) + tmax = gammalib.GTime(1000.0) + gti = gammalib.GGti(tmin, tmax) + cntcube = gammalib.GCTAEventCube(map, ebds, gti) + + # Get stacked response + res = obsutils.get_stacked_response(obs, cntcube, edisp=False) # Check result self.test_value(res['expcube'].cube().npix(), 100, 'Check number of exposure cube pixels') - self.test_value(res['expcube'].cube().nmaps(), 61, + self.test_value(res['expcube'].cube().nmaps(), 91, 'Check number of exposure cube maps') self.test_value(res['psfcube'].cube().npix(), 4, 'Check number of PSF cube pixels') - self.test_value(res['psfcube'].cube().nmaps(), 12200, + self.test_value(res['psfcube'].cube().nmaps(), 18200, 'Check number of PSF cube maps') self.test_value(res['bkgcube'].cube().npix(), 100, 'Check number of background cube pixels') self.test_value(res['bkgcube'].cube().nmaps(), 5, 'Check number of background cube maps') - # Get stacked response with None xref/yref - res = obsutils.get_stacked_response(obs, None, None, - coordsys='CEL', - binsz=0.1, nxpix=10, nypix=10, - emin=1.0, emax=100.0, enumbins=5, - edisp=False) + # Get stacked response with energy dispersion + res = obsutils.get_stacked_response(obs, cntcube, edisp=True) # Check result self.test_value(res['expcube'].cube().npix(), 100, 'Check number of exposure cube pixels') - self.test_value(res['expcube'].cube().nmaps(), 61, + self.test_value(res['expcube'].cube().nmaps(), 105, 'Check number of exposure cube maps') self.test_value(res['psfcube'].cube().npix(), 4, 'Check number of PSF cube pixels') - self.test_value(res['psfcube'].cube().nmaps(), 12200, + self.test_value(res['psfcube'].cube().nmaps(), 21000, 'Check number of PSF cube maps') self.test_value(res['bkgcube'].cube().npix(), 100, 'Check number of background cube pixels') self.test_value(res['bkgcube'].cube().nmaps(), 5, 'Check number of background cube maps') + self.test_value(res['edispcube'].cube().npix(), 4, + 'Check number of energy dispersion cube pixels') + self.test_value(res['edispcube'].cube().nmaps(), 10500, + 'Check number of energy dispersion cube maps') + + # Set-up counts cube with large number of energy bins + ebds = gammalib.GEbounds(100, emin, emax) + cntcube = gammalib.GCTAEventCube(map, ebds, gti) # Get stacked response with xref/yref set and large number of energy bins - res = obsutils.get_stacked_response(obs, 83.6331, 22.0145, - coordsys='CEL', - binsz=0.1, nxpix=10, nypix=10, - emin=1.0, emax=100.0, enumbins=100, - edisp=False) + res = obsutils.get_stacked_response(obs, cntcube, edisp=False) # Check result self.test_value(res['expcube'].cube().npix(), 100, 'Check number of exposure cube pixels') - self.test_value(res['expcube'].cube().nmaps(), 101, + self.test_value(res['expcube'].cube().nmaps(), 91, 'Check number of exposure cube maps') self.test_value(res['psfcube'].cube().npix(), 4, 'Check number of PSF cube pixels') - self.test_value(res['psfcube'].cube().nmaps(), 20200, + self.test_value(res['psfcube'].cube().nmaps(), 18200, 'Check number of PSF cube maps') self.test_value(res['bkgcube'].cube().npix(), 100, 'Check number of background cube pixels') self.test_value(res['bkgcube'].cube().nmaps(), 100, 'Check number of background cube maps') - # Get stacked response with energy dispersion - res = obsutils.get_stacked_response(obs, 83.6331, 22.0145, - coordsys='CEL', - binsz=0.1, nxpix=10, nypix=10, - emin=1.0, emax=100.0, enumbins=5, - edisp=True) - - # Check result - self.test_value(res['expcube'].cube().npix(), 100, - 'Check number of exposure cube pixels') - self.test_value(res['expcube'].cube().nmaps(), 75, - 'Check number of exposure cube maps') - self.test_value(res['psfcube'].cube().npix(), 4, - 'Check number of PSF cube pixels') - self.test_value(res['psfcube'].cube().nmaps(), 15000, - 'Check number of PSF cube maps') - self.test_value(res['bkgcube'].cube().npix(), 100, - 'Check number of background cube pixels') - self.test_value(res['bkgcube'].cube().nmaps(), 5, - 'Check number of background cube maps') - self.test_value(res['edispcube'].cube().npix(), 4, - 'Check number of energy dispersion cube pixels') - self.test_value(res['edispcube'].cube().nmaps(), 7500, - 'Check number of energy dispersion cube maps') - # Return return