Ejemplo n.º 1
0
    def _set_obs_ebounds(self, emin, emax):
        """
        Set energy boundaries for observation container.

        Sets the energy boundaries for all observations in the observation
        container.

        Args:
            emin: Minimum energy
            emax: Maximum energy
        """
        # Loop over all observations in container
        for obs in self._obs:

            # Get observation energy boundaries
            obs_ebounds = obs.events().ebounds()

            # Get minimum and maximum energy
            obs_emin = obs_ebounds.emin()
            obs_emax = obs_ebounds.emax()

            # Case A: bin fully contained in observation ebounds
            if obs_emin <= emin and obs_emax >= emax:
                ebounds = gammalib.GEbounds(emin, emax)

            # Case B: bin fully outside of obs ebounds
            elif emax < obs_emin or emin > obs_emax:

                # Set zero range (inspired by ctselect)
                e0 = gammalib.GEnergy(0.0, "TeV")
                ebounds = gammalib.GEbounds(e0, e0)

            # Case C:  bin partly overlapping with observation ebounds
            else:

                # Set energy range as obs ebounds were fully contained inside energy bin
                set_emin = emin
                set_emax = emax

                # Adjust energy bin to respect observation energy boundary
                if emin < obs_emin:
                    set_emin = obs_emin
                if emax > obs_emax:
                    set_emax = obs_emax

                #Set energy boundaries
                ebounds = gammalib.GEbounds(set_emin, set_emax)

            # Set energy boundaries
            obs.events().ebounds(ebounds)

        # Return
        return
Ejemplo n.º 2
0
    def _set_obs_ebounds(self, emin, emax):
        """
        Set energy boundaries for all observations in container

        Parameters
        ----------
        emin : `~gammalib.GEnergy`
            Minimum energy
        emax : `~gammalib.GEnergy`
            Maximum energy
        """
        # Loop over all observations in container
        for i, obs in enumerate(self.obs()):

            # Get energy boundaries of the observation
            obs_ebounds = self._obs_ebounds[i]

            # Get minimum and maximum energy of the observation
            obs_emin = obs_ebounds.emin()
            obs_emax = obs_ebounds.emax()

            # If [emin,emax] is fully contained in the observation energy range
            # the use [emin,emax] as energy boundaries
            if obs_emin <= emin and obs_emax >= emax:
                ebounds = gammalib.GEbounds(emin, emax)

            # ... otherwise, if [emin,emax] is completely outside the
            # observation energy range then set the energy boundaries to the
            # zero-width interval [0,0]
            elif emax < obs_emin or emin > obs_emax:
                e0 = gammalib.GEnergy(0.0, 'TeV')
                ebounds = gammalib.GEbounds(e0, e0)

            # ... otherwise, if [emin,emax] overlaps partially with the
            # observation energy range then set the energy boundaries to the
            # overlapping part
            else:
                # Set overlapping energy range
                set_emin = max(emin, obs_emin)
                set_emax = min(emax, obs_emax)

                # Set energy boundaries
                ebounds = gammalib.GEbounds(set_emin, set_emax)

            # Set the energy boundaries as the boundaries of the observation
            obs.events().ebounds(ebounds)

        # Return
        return
Ejemplo n.º 3
0
    def __init__(self, *argv):
        """
        Constructor.
        """
        # Set name
        self._name = 'csobsinfo'
        self._version = '1.1.0'

        # Initialise class members
        self._obj_dir = None
        self._compute_offset = False
        self._offsets = []
        self._zeniths = []
        self._azimuths = []
        self._pnt_ra = []
        self._pnt_dec = []
        self._ebounds = gammalib.GEbounds()
        self._gti = gammalib.GGti()

        # Initialise observation container from constructor arguments.
        self._obs, argv = self._set_input_obs(argv)

        # Initialise application by calling the appropriate class
        # constructor.
        self._init_cscript(argv)

        # Return
        return
Ejemplo n.º 4
0
def generate_background_lookup():
    """
    Generate background lookup from empty field observations
    """
    # Set filenames
    obsname = '$HESSDATA/obs/obs_off.xml'
    filename = 'off_lookup.fits'

    # Continue only if lookup table does not yet exist
    if not os.path.isfile(filename):

        # Initialise lookup table
        emin = gammalib.GEnergy(0.2, 'TeV')
        emax = gammalib.GEnergy(50.0, 'TeV')
        ebds = gammalib.GEbounds(10, emin, emax)
        lookup = gammalib.GCTAModelSpatialLookup(2.0, 0.2, ebds)

        # Load empty field observations
        obs = gammalib.GObservations(obsname)

        # Fill lookup table
        lookup.fill(obs)

        # Save lookup table
        lookup.save(filename, True)

    # Return
    return
Ejemplo n.º 5
0
    def __init__(self, *argv):
        """
        Constructor.
        """
        # Set name
        self._name = 'csspec'
        self._version = '1.1.0'

        # Initialise some members
        self._ebounds = gammalib.GEbounds()
        self._fits = None
        self._binned_mode = False
        self._srcname = ""
        self._edisp = False
        self._calc_ulimit = True
        self._calc_ts = True
        self._fix_bkg = False
        self._fix_srcs = True
        self._chatter = 2
        self._clobber = True
        self._debug = False

        # Initialise observation container from constructor arguments.
        self._obs, argv = self._set_input_obs(argv)

        # Initialise application by calling the appropriate class
        # constructor.
        self._init_cscript(argv)

        # Return
        return
Ejemplo n.º 6
0
def show_events(events, xmlname, duration, emin, emax, ebins=30):
    """
    Show events using matplotlib.
    """
    # Create figure
    plt.figure(1)
    plt.title("MC simulated event spectrum (" + str(emin) + '-' + str(emax) + " TeV)")

    # Setup energy range covered by data
    ebds = gammalib.GEbounds(ebins, gammalib.GEnergy(emin, "TeV"),
                                    gammalib.GEnergy(emax, "TeV"))

    # Create energy axis
    energy = []
    for i in range(ebds.size()):
        energy.append(ebds.elogmean(i).TeV())

    # Fill histogram
    counts = [0.0 for i in range(ebds.size())]
    for event in events:
        index = ebds.index(event.energy())
        counts[index] = counts[index] + 1.0

    # Create error bars
    error = [math.sqrt(c) for c in counts]

    # Get model values
    sum    = 0.0
    models = gammalib.GModels(xmlname)
    m      = models[0]
    model  = []
    t = gammalib.GTime()
    for i in range(ebds.size()):
        eval   = ebds.elogmean(i)
        ewidth = ebds.emax(i) - ebds.emin(i)
        f      = m.npred(eval, t, obs) * ewidth.MeV() * duration
        sum   += f
        model.append(f)
    print(str(sum) + " events expected from spectrum (integration).")

    # Plot data
    plt.loglog(energy, counts, 'ro')
    plt.errorbar(energy, counts, error, fmt=None, ecolor='r')

    # Plot model
    plt.plot(energy, model, 'b-')

    # Set axes
    plt.xlabel("Energy (TeV)")
    plt.ylabel("Number of events")

    # Notify
    print("PLEASE CLOSE WINDOW TO CONTINUE ...")

    # Show plot
    plt.show()

    # Return
    return
Ejemplo n.º 7
0
def plot_spectrum(model, emin=0.01, emax=100.0, enumbins=100, plotfile=''):
    """
    Plot spectral model component

    Parameters
    ----------
    model : `~gammalib.GModel`
        Model
    emin : float, optional
        Minimum energy (TeV)
    emax : float, optional
        Maximum energy (TeV)
    enumbins : integer, optional
        Number of energy bins
    plotfile : str, optional
        Name of plot file
    """
    # Get spectral component
    spectrum = model.spectral()

    # Setup energy axis
    e_min = gammalib.GEnergy(emin, 'TeV')
    e_max = gammalib.GEnergy(emax, 'TeV')
    ebounds = gammalib.GEbounds(enumbins, e_min, e_max)

    # Setup model plot
    x = []
    y = []
    min = 1.0e30
    max = 0.0
    for i in range(enumbins):
        energy = ebounds.elogmean(i)
        value = spectrum.eval(energy)
        if value > max:
            max = value
        if value < min:
            min = value
        x.append(energy.TeV())
        y.append(value)

    # Show spectrum
    plt.figure()
    plt.title(model.name() + ' (' + spectrum.type() + ')')
    plt.loglog()
    plt.grid()
    plt.loglog(x, y, color='red')
    plt.xlabel('Energy (TeV)')
    plt.ylabel(r'dN/dE (ph s$^{-1}$ cm$^{-2}$ MeV$^{-1}$)')
    #plt.ylim([min,max])

    # Show spectrum or save it into file
    if len(plotfile) > 0:
        plt.savefig(plotfile)
    else:
        plt.show()

    # Return
    return
Ejemplo n.º 8
0
    def _check_ebounds(self, filename, bins):
        """
        Check energy boundaries file
        """
        # Load energy boundaries file
        ebounds = gammalib.GEbounds(filename)

        # Check number of energy boundaries
        self.test_value(ebounds.size(), bins)

        # Return
        return
Ejemplo n.º 9
0
    def __init__(self, *argv):
        """
        Constructor
        """
        # Initialise application by calling the appropriate class constructor
        self._init_csobservation(self.__class__.__name__, ctools.__version__, argv)

        # Set members
        self._ebounds = gammalib.GEbounds()

        # Return
        return
Ejemplo n.º 10
0
    def _get_parameters(self):
        """
        Get user parameters from parfile.
        """
        # Set observation if not done before
        if self._obs == None or self._obs.size() == 0:
            self._obs = self._set_obs()

        # Set models if we have none
        if self._obs.models().size() == 0:
            self._obs.models(self["inmodel"].filename())

        # Get source name
        self._srcname = self["srcname"].string()

        # Read further parameters
        self._outfile = self["outfile"].filename()
        self._emin = self["emin"].real()
        self._emax = self["emax"].real()
        self._bins = self["bins"].integer()

        # Read parameters for binned if requested
        self._enumbins = self["enumbins"].integer()
        if not self._enumbins == 0:
            self._npix = self["npix"].integer()
            self._binsz = self["binsz"].real()

        # Read remaining parameters
        self._edisp = self["edisp"].boolean()
        self._ts_thres = self["sigma"].real() * self["sigma"].real()
        self._max_iter = self["max_iter"].integer()
        self._num_avg = self["num_avg"].integer()
        self._type = self["type"].string()

        # Set some fixed parameters
        self._debug = self["debug"].boolean()  # Debugging in client tools

        # Derive some parameters
        self._ebounds = gammalib.GEbounds(self._bins,
                                          gammalib.GEnergy(self._emin, "TeV"),
                                          gammalib.GEnergy(self._emax, "TeV"))

        # Write input parameters into logger
        if self._logTerse():
            self._log_parameters()
            self._log("\n")

        # Return
        return
Ejemplo n.º 11
0
    def _get_parameters(self):
        """
        Get user parameters from parfile
        """
        # Set observation if not done before
        if self.obs().size() == 0:
            self.obs(self._set_obs(self['emin'].real(), self['emax'].real()))

        # Set observation statistic
        self._set_obs_statistic(gammalib.toupper(self['statistic'].string()))

        # Set models if we have none
        if self.obs().models().size() == 0:
            self.obs().models(self['inmodel'].filename())

        # Get source name
        self._srcname = self['srcname'].string()

        # Read further parameters
        emin = self['emin'].real()
        emax = self['emax'].real()
        bins = self['bins'].integer()

        # Query parameters for binned if requested
        enumbins = self['enumbins'].integer()
        if not enumbins == 0:
            self['npix'].integer()
            self['binsz'].real()

        # Query input parameters
        self['sigma'].real()
        self['max_iter'].integer()
        self['type'].string()
        self['outfile'].filename()
        self['edisp'].boolean()
        self['debug'].boolean()

        # Derive some parameters
        self._ebounds = gammalib.GEbounds(bins, gammalib.GEnergy(emin, 'TeV'),
                                          gammalib.GEnergy(emax, 'TeV'))

        #  Write input parameters into logger
        self._log_parameters(gammalib.TERSE)

        # Set number of processes for multiprocessing
        self._nthreads = mputils.nthreads(self)

        # Return
        return
Ejemplo n.º 12
0
    def __init__(self, *argv):
        """
        Constructor
        """
        # Initialise application by calling the appropriate class constructor
        self._init_csobservation(self.__class__.__name__, ctools.__version__,
                                 argv)

        # Initialise other variables
        self._ebounds = gammalib.GEbounds()
        self._etruebounds = gammalib.GEbounds()
        self._src_dir = gammalib.GSkyDir()
        self._src_reg = gammalib.GSkyRegions()
        self._models = gammalib.GModels()
        self._srcname = ''
        self._bkg_regs = []
        self._excl_reg = None
        self._has_exclusion = False
        self._srcshape = ''
        self._rad = 0.0
        self._nthreads = 0

        # Return
        return
Ejemplo n.º 13
0
    def __init__(self, *argv):
        """
        Constructor
        """
        # Initialise application by calling the base class constructor
        self._init_cscript(self.__class__.__name__, ctools.__version__, argv)

        # Initialise some members
        self._obs = gammalib.GObservations()
        self._ebounds = gammalib.GEbounds()
        self._datapath = os.getenv('VHEFITS', '')
        self._prodname = ''
        self._xml = gammalib.GXml()
        self._models = gammalib.GModels()
        self._runlist = []
        self._runlistfile = gammalib.GFilename()
        self._bkgpars = 0
        self._master_indx = ''
        self._use_bkg_scale = False
        self._ev_hiera = ['']
        self._aeff_hiera = ['']
        self._psf_hiera = ['']
        self._bkg_hiera = ['']
        self._edisp_hiera = ['']
        self._bkg_mod_hiera = ['']
        self._bkg_gauss_norm = 1.0
        self._bkg_gauss_index = 0.0
        self._bkg_gauss_sigma = 1.0
        self._bkg_aeff_index = 0.0
        self._bkg_aeff_norm = 1.0
        self._bkg_range_factor = 1.0
        self._hdu_index = ''
        self._obs_index = ''
        self._subdir = ''
        self._debug = False

        # Initialise empty observation definition XML file
        self._xml.append(
            gammalib.GXmlElement('observation_list '
                                 'title="observation list"'))

        # Append an observation list to XML instance
        self._xml.append(
            gammalib.GXmlElement('observation_list title="observation list"'))
        self._xml_obslist = self._xml.element('observation_list', 0)

        # Return
        return
Ejemplo n.º 14
0
def createobs(ra=86.171648, dec=-1.4774586, rad=5.0,
              emin=0.1, emax=100.0, duration=360000.0, deadc=0.95,
              ):
    obs = gammalib.GCTAObservation()

    # Set pointing direction
    pntdir = gammalib.GSkyDir()
    pntdir.radec_deg(ra, dec)
    pnt = gammalib.GCTAPointing()
    pnt.dir(pntdir)
    obs.pointing(pnt)

    # Set ROI
    roi = gammalib.GCTARoi()
    instdir = gammalib.GCTAInstDir()
    instdir.dir(pntdir)
    roi.centre(instdir)
    roi.radius(rad)

    # Set GTI
    gti = gammalib.GGti()
    start = gammalib.GTime(0.0)
    stop = gammalib.GTime(duration)
    gti.append(start, stop)

    # Set energy boundaries
    ebounds = gammalib.GEbounds()
    e_min = gammalib.GEnergy()
    e_max = gammalib.GEnergy()
    e_min.TeV(emin)
    e_max.TeV(emax)
    ebounds.append(e_min, e_max)

    # Allocate event list
    events = gammalib.GCTAEventList()
    events.roi(roi)
    events.gti(gti)
    events.ebounds(ebounds)
    obs.events(events)

    # Set ontime, livetime, and deadtime correction factor
    obs.ontime(duration)
    obs.livetime(duration * deadc)
    obs.deadc(deadc)

    # Return observation
    return obs
def generate_background_lookup(obslist=None, suffix=''):
    """
    Generate background lookup from empty field observations

    Parameters
    ----------
    obslist : list of int, optional
        Indices of observations to use
    suffix : str, optional
        Background lookup file suffix
    """
    # Set filenames
    obsname = '$HESSDATA/obs/obs_off.xml'
    filename = 'bkg_lookup%s.fits' % suffix

    # Continue only if lookup table does not yet exist
    if not os.path.isfile(filename):

        # Initialise lookup table
        emin = gammalib.GEnergy(0.2, 'TeV')
        emax = gammalib.GEnergy(50.0, 'TeV')
        ebds = gammalib.GEbounds(10, emin, emax)
        lookup = gammalib.GCTAModelSpatialLookup(2.0, 0.2, ebds)

        # Load empty field observations
        obs = gammalib.GObservations(obsname)

        # If an observation list was specified then exclude observations
        # in list
        if obslist != None:
            newobs = gammalib.GObservations()
            for i, run in enumerate(obs):
                if i not in obslist:
                    newobs.append(run)
                else:
                    print('Exclude %s' % (run.id()))
            obs = newobs
            print('%d observations in lookup table' % (len(obs)))

        # Fill lookup table
        lookup.fill(obs)

        # Save lookup table
        lookup.save(filename, True)

    # Return
    return
Ejemplo n.º 16
0
    def __init__(self, *argv):
        """
        Constructor
        """
        # Initialise application by calling the appropriate class constructor
        self._init_csobservation(self.__class__.__name__, ctools.__version__, argv)

        # Initialise data members
        self._ebounds     = gammalib.GEbounds()
        self._fits        = None
        self._binned_mode = False
        self._onoff_mode  = False
        self._method      = 'AUTO'
        self._nthreads    = 0

        # Return
        return
Ejemplo n.º 17
0
    def __init__(self, *argv):
        """
        Constructor.
        """
        # Set name and version
        self._name = 'csiactobs'
        self._version = '1.1.0'

        # Initialise some members
        self._ebounds = gammalib.GEbounds()
        self._datapath = os.getenv('VHEFITS', '')
        self._inmodels = gammalib.GModels()
        self._prodname = ''
        self._xml = gammalib.GXml()
        self._models = gammalib.GModels()
        self._runlist = []
        self._runlistfile = gammalib.GFilename()
        self._bkgpars = 0
        self._outmodel = gammalib.GFilename()
        self._outobs = gammalib.GFilename()
        self._master_indx = ''
        self._use_bkg_scale = False
        self._ev_hiera = ['']
        self._aeff_hiera = ['']
        self._psf_hiera = ['']
        self._bkg_hiera = ['']
        self._edisp_hiera = ['']
        self._bkg_mod_hiera = ['']
        self._bkg_gauss_norm = 1.0
        self._bkg_gauss_index = 0.0
        self._bkg_gauss_sigma = 1.0
        self._bkg_aeff_index = 0.0
        self._bkg_aeff_norm = 1.0
        self._bkg_range_factor = 1.0
        self._hdu_index = ''
        self._obs_index = ''
        self._subdir = ''
        self._debug = False

        # Initialise application by calling the appropriate class
        # constructor.
        self._init_cscript(argv)

        # Return
        return
Ejemplo n.º 18
0
    def __init__(self, *argv):
        """
        Constructor.
        """
        # Initialise application by calling the appropriate class constructor
        self._init_csobservation(self.__class__.__name__, ctools.__version__,
                                 argv)

        # Initialise class members
        self._ebounds = gammalib.GEbounds()
        self._obs_ebounds = []
        self._srcname = ''
        self._ra = None
        self._dec = None
        self._log_clients = False
        self._models = gammalib.GModels()
        self._nthreads = 0

        # Return
        return
Ejemplo n.º 19
0
    def __init__(self, *argv):
        """
        Constructor.
        """
        # Initialise application by calling the appropriate class constructor
        self._init_csobservation(self.__class__.__name__, ctools.__version__,
                                 argv)

        # Initialise class members
        self._obj_dir = None
        self._compute_offset = False
        self._offsets = []
        self._zeniths = []
        self._azimuths = []
        self._pnt_ra = []
        self._pnt_dec = []
        self._ebounds = gammalib.GEbounds()
        self._gti = gammalib.GGti()

        # Return
        return
Ejemplo n.º 20
0
def plot_spectrum(model_file, emin=0.03, emax=150.0, enumbins=100):
    models = gammalib.GModels(model_file)
    spectral_model = models["Crab"].spectral()
    e_min = gammalib.GEnergy(emin, "TeV")
    e_max = gammalib.GEnergy(emax, "TeV")
    ebounds = gammalib.GEbounds(enumbins, e_min, e_max)

    x = []
    y = []
    for i in range(enumbins):
        energy = ebounds.elogmean(i)
        value = spectral_model.eval(energy)
        x.append(energy.TeV())
        y.append(value)

    plt.figure()
    plt.title(models["Crab"].name() + " (" + spectral_model.type() + ")")
    plt.grid()
    plt.loglog(x, y, color="red")
    plt.xlabel("Energy (TeV)")
    plt.ylabel("dN/dE ph/cm²/s/MeV")
    plt.show()
Ejemplo n.º 21
0
    def __init__(self, *argv):
        """
        Constructor.
        """
        # Set name
        self._name = "cssens"
        self._version = "1.1.0"

        # Initialise class members
        self._obs = gammalib.GObservations()
        self._ebounds = gammalib.GEbounds()
        self._obs_ebounds = []
        self._srcname = ""
        self._outfile = gammalib.GFilename()
        self._ra = None
        self._dec = None
        self._edisp = False
        self._emin = 0.020
        self._emax = 200.0
        self._bins = 21
        self._enumbins = 0
        self._npix = 200
        self._binsz = 0.05
        self._type = "Differential"
        self._ts_thres = 25.0
        self._max_iter = 50
        self._num_avg = 3
        self._log_clients = False
        self._debug = False

        # Initialise application by calling the appropriate class
        # constructor.
        self._init_cscript(argv)

        # Return
        return
Ejemplo n.º 22
0
    def _etrue_ebounds(self):
        """
        Set true energy boundaries

        Returns
        -------
        ebounds : `~gammalib.GEbounds()`
            True energy boundaries
        """
        # Determine minimum and maximum energies
        emin = self._ebounds.emin() * 0.5
        emax = self._ebounds.emax() * 1.2
        if emin.TeV() < self['etruemin'].real():
            emin = gammalib.GEnergy(self['etruemin'].real(), 'TeV')
        if emax.TeV() > self['etruemax'].real():
            emax = gammalib.GEnergy(self['etruemax'].real(), 'TeV')

        # Determine number of energy bins
        n_decades = (emax.log10TeV() - emin.log10TeV())
        n_bins = int(n_decades * float(self['etruebins'].integer()) + 0.5)
        if n_bins < 1:
            n_bins = 1

        # Set energy boundaries
        ebounds = gammalib.GEbounds(n_bins, emin, emax)

        # Write header
        self._log_header1(gammalib.TERSE, 'True energy binning')

        # Log true energy bins
        for i in range(ebounds.size()):
            value = '%s - %s' % (str(ebounds.emin(i)), str(ebounds.emax(i)))
            self._log_value(gammalib.TERSE, 'Bin %d' % (i + 1), value)

        # Return energy boundaries
        return ebounds
def show_residuals(obslist=None,
                   emin=0.2,
                   emax=20.0,
                   ebins=20,
                   npix=200,
                   binsz=0.02,
                   suffix=''):
    """
    Show residuals for all OFF observations

    Parameters
    ----------
    obslist : list of ints, optional
        Index of observations to stack
    emin : float, optional
        Minimum energy (TeV)
    emax : float, optional
        Maximum energy (TeV)
    ebins : int, optional
        Number of energy bins
    npix : int, optional
        Number of spatial pixels
    binsz : float, optional
        Spatial bin size
    suffix : str, optional
        Plot filename suffix
    """
    # Set XML filename
    obsname = '$HESSDATA/obs/obs_off.xml'

    # Generate background lookup
    generate_background_lookup(obslist=obslist, suffix=suffix)

    # If observation list is specified and suffix is empty then build suffix
    if obslist != None and suffix == '':
        for obs in obslist:
            suffix += '_%2.2d' % obs

    # Set stacked cube filenames
    cntfile = 'off_stacked_counts%s.fits' % (suffix)
    modfile = 'off_stacked_model%s.fits' % (suffix)

    # If stacked cubes exist then load them
    if os.path.isfile(cntfile) and os.path.isfile(modfile):
        cntcube_stacked = gammalib.GCTAEventCube(cntfile)
        modcube_stacked = gammalib.GCTAEventCube(modfile)

    # ... otherwise generate them
    else:

        # Define counts and model cubes for stacking
        map = gammalib.GSkyMap('TAN', 'CEL', 0.0, 0.0, -binsz, binsz, npix,
                               npix, ebins)
        ebds = gammalib.GEbounds(ebins, gammalib.GEnergy(emin, 'TeV'),
                                 gammalib.GEnergy(emax, 'TeV'))
        gti = gammalib.GGti(gammalib.GTime(0.0, 's'), gammalib.GTime(1.0, 's'))
        cntcube_stacked = gammalib.GCTAEventCube(map, ebds, gti)
        modcube_stacked = gammalib.GCTAEventCube(map, ebds, gti)

        # Load observations
        inobs = gammalib.GObservations(obsname)

        # Loop over runs in observations
        for i, run in enumerate(inobs):

            # If an observation list is defined then skip observation if it
            # is not in list
            if obslist != None:
                if i not in obslist:
                    continue

            # Build observation container with single run
            obs = gammalib.GObservations()
            obs.append(run)

            # Select events
            obs = select_events(obs, emin=emin, emax=emax)

            # Generate background model
            models = get_bkg_model(obs, suffix=suffix)

            # Attach models to observation container
            obs.models(models)

            # Create counts cube
            cntcube = create_cntcube(obs,
                                     emin=emin,
                                     emax=emax,
                                     ebins=ebins,
                                     npix=npix,
                                     binsz=binsz)

            # Create model cube
            modcube = create_modcube(obs, cntcube)

            # Stack cubes
            cntcube_stacked = stack_cube(cntcube_stacked, cntcube)
            modcube_stacked = stack_cube(modcube_stacked, modcube)

            # Stop after first run
            #break

        # Save cubes
        cntcube_stacked.save(cntfile, True)
        modcube_stacked.save(modfile, True)

    # Plot stacked cubes
    plot(cntcube_stacked, modcube_stacked, suffix=suffix)
    plot_sectors(cntcube_stacked, modcube_stacked, suffix=suffix)
    plot_radial_profiles(cntcube_stacked, modcube_stacked, suffix=suffix)

    # Return
    return
Ejemplo n.º 24
0
    def run(self):
        """
        Run the script

        Raises
        ------
        RuntimeError
            Invalid pointing definition file format
        """
        # Switch screen logging on in debug mode
        if self._logDebug():
            self._log.cout(True)

        # Get parameters
        self._get_parameters()

        # Write header into logger
        self._log_header1(gammalib.TERSE,
                          'Creating observation definition XML file')

        # Load pointing definition file if it is not already set. Extract
        # the number of columns and pointings
        if self._pntdef.size() == 0:
            self._pntdef = gammalib.GCsv(self['inpnt'].filename(), ',')
        ncols = self._pntdef.ncols()
        npnt = self._pntdef.nrows() - 1

        # Raise an exception if there is no header information
        if self._pntdef.nrows() < 1:
            raise RuntimeError('No header found in pointing definition file.')

        # Clear observation container
        self._obs.clear()

        # Initialise observation identifier counter
        identifier = 1

        # Extract header columns from pointing definition file and put them
        # into a list
        header = []
        for col in range(ncols):
            header.append(self._pntdef[0, col])

        # Loop over all pointings
        for pnt in range(npnt):

            # Set pointing definition CSV file row index
            row = pnt + 1

            # Create empty CTA observation
            obs = gammalib.GCTAObservation()

            # Set observation name. If no observation name was given then
            # use "None".
            if 'name' in header:
                name = self._pntdef[row, header.index('name')]
            else:
                name = self['name'].string()
            obs.name(name)

            # Set observation identifier. If no observation identified was
            # given the use the internal counter.
            if 'id' in header:
                obsid = self._pntdef[row, header.index('id')]
            else:
                obsid = '%6.6d' % identifier
                identifier += 1
            obs.id(obsid)

            # Set pointing. Either use "ra" and "dec" or "lon" and "lat".
            # If none of these pairs are given then raise an exception.
            if 'ra' in header and 'dec' in header:
                ra = float(self._pntdef[row, header.index('ra')])
                dec = float(self._pntdef[row, header.index('dec')])
                pntdir = gammalib.GSkyDir()
                pntdir.radec_deg(ra, dec)
            elif 'lon' in header and 'lat' in header:
                lon = float(self._pntdef[row, header.index('lon')])
                lat = float(self._pntdef[row, header.index('lat')])
                pntdir = gammalib.GSkyDir()
                pntdir.lb_deg(lon, lat)
            else:
                raise RuntimeError('No (ra,dec) or (lon,lat) columns '
                                   'found in pointing definition file.')
            obs.pointing(gammalib.GCTAPointing(pntdir))

            # Set response function. If no "caldb" or "irf" information is
            # provided then use the user parameter values.
            if 'caldb' in header:
                caldb = self._pntdef[row, header.index('caldb')]
            else:
                caldb = self['caldb'].string()
            if 'irf' in header:
                irf = self._pntdef[row, header.index('irf')]
            else:
                irf = self['irf'].string()
            if caldb != '' and irf != '':
                obs = self._set_irf(obs, caldb, irf)

            # Set deadtime correction factor. If no information is provided
            # then use the user parameter value "deadc".
            if 'deadc' in header:
                deadc = float(self._pntdef[row, header.index('deadc')])
            else:
                deadc = self['deadc'].real()
            obs.deadc(deadc)

            # Set Good Time Interval. If no information is provided then use
            # the user parameter values "tmin" and "duration".
            if 'tmin' in header:
                self._tmin = float(self._pntdef[row, header.index('tmin')])
            if 'duration' in header:
                duration = float(self._pntdef[row, header.index('duration')])
            else:
                duration = self['duration'].real()
            tref = gammalib.GTimeReference(self['mjdref'].real(), 's')
            tmin = self._tmin
            tmax = self._tmin + duration
            gti = gammalib.GGti(tref)
            tstart = gammalib.GTime(tmin, tref)
            tstop = gammalib.GTime(tmax, tref)
            self._tmin = tmax
            gti.append(tstart, tstop)
            obs.ontime(gti.ontime())
            obs.livetime(gti.ontime() * deadc)

            # Set Energy Boundaries. If no "emin" or "emax" information is
            # provided then use the user parameter values in case they are
            # valid.
            has_emin = False
            has_emax = False
            if 'emin' in header:
                emin = float(self._pntdef[row, header.index('emin')])
                has_emin = True
            else:
                if self['emin'].is_valid():
                    emin = self['emin'].real()
                    has_emin = True
            if 'emax' in header:
                emax = float(self._pntdef[row, header.index('emax')])
                has_emax = True
            else:
                if self['emax'].is_valid():
                    emax = self['emax'].real()
                    has_emax = True
            has_ebounds = has_emin and has_emax
            if has_ebounds:
                ebounds = gammalib.GEbounds(gammalib.GEnergy(emin, 'TeV'),
                                            gammalib.GEnergy(emax, 'TeV'))

            # Set ROI. If no ROI radius is provided then use the user
            # parameters "rad".
            has_roi = False
            if 'rad' in header:
                rad = float(self._pntdef[row, header.index('rad')])
                has_roi = True
            else:
                if self['rad'].is_valid():
                    rad = self['rad'].real()
                    has_roi = True
            if has_roi:
                roi = gammalib.GCTARoi(gammalib.GCTAInstDir(pntdir), rad)

            # Create an empty event list
            event_list = gammalib.GCTAEventList()
            event_list.gti(gti)

            # If available, set the energy boundaries and the ROI
            if has_ebounds:
                event_list.ebounds(ebounds)
            if has_roi:
                event_list.roi(roi)

            # Attach event list to CTA observation
            obs.events(event_list)

            # Write observation into logger
            name = obs.instrument() + ' observation'
            value = 'Name="%s" ID="%s"' % (obs.name(), obs.id())
            self._log_value(gammalib.NORMAL, name, value)
            self._log_string(gammalib.EXPLICIT, str(obs) + '\n')

            # Append observation
            self._obs.append(obs)

        # Return
        return
Ejemplo n.º 25
0
def set_obs(pntdir, tstart=0.0, duration=1800.0, deadc=0.95, \
            emin=0.1, emax=100.0, rad=5.0, \
            irf="South_50h", caldb="prod2", id="000000"):
    """
    Set a single CTA observation.
    
    The function sets a single CTA observation containing an empty CTA
    event list. By looping over this function you can add CTA observations
    to the observation container.

    Args:
        pntdir: Pointing direction [GSkyDir]

    Kwargs:
        tstart:   Start time (seconds) (default: 0.0)
        duration: Duration of observation (seconds) (default: 1800.0)
        deadc:    Deadtime correction factor (default: 0.95)
        emin:     Minimum event energy (TeV) (default: 0.1)
        emax:     Maximum event energy (TeV) (default: 100.0)
        rad:      ROI radius used for analysis (deg) (default: 5.0)
        irf:      Instrument response function (default: "South_50h")
        caldb:    Calibration database path (default: "prod2")
        id:       Run identifier (default: "000000")
    """
    # Allocate CTA observation
    obs_cta = gammalib.GCTAObservation()

    # Set calibration database
    db = gammalib.GCaldb()
    if (gammalib.dir_exists(caldb)):
        db.rootdir(caldb)
    else:
        db.open("cta", caldb)

    # Set pointing direction
    pnt = gammalib.GCTAPointing()
    pnt.dir(pntdir)
    obs_cta.pointing(pnt)

    # Set ROI
    roi = gammalib.GCTARoi()
    instdir = gammalib.GCTAInstDir()
    instdir.dir(pntdir)
    roi.centre(instdir)
    roi.radius(rad)

    # Set GTI
    gti = gammalib.GGti()
    gti.append(gammalib.GTime(tstart), gammalib.GTime(tstart + duration))

    # Set energy boundaries
    ebounds = gammalib.GEbounds(gammalib.GEnergy(emin, "TeV"),
                                gammalib.GEnergy(emax, "TeV"))

    # Allocate event list
    events = gammalib.GCTAEventList()
    events.roi(roi)
    events.gti(gti)
    events.ebounds(ebounds)
    obs_cta.events(events)

    # Set instrument response
    obs_cta.response(irf, db)

    # Set ontime, livetime, and deadtime correction factor
    obs_cta.ontime(duration)
    obs_cta.livetime(duration * deadc)
    obs_cta.deadc(deadc)
    obs_cta.id(id)

    # Return CTA observation
    return obs_cta
Ejemplo n.º 26
0
    def _background_spectrum(self,
                             run,
                             prefactor,
                             index,
                             emin=0.01,
                             emax=100.0):

        # Handle constant spectral model
        if index == 0.0 and self._bkgpars <= 1:
            spec = gammalib.GModelSpectralConst()
            spec['Normalization'].min(prefactor / self._bkg_range_factor)
            spec['Normalization'].max(prefactor * self._bkg_range_factor)
            spec['Normalization'].value(prefactor)
            if self._bkgpars == 0:
                spec['Normalization'].fix()
            else:
                spec['Normalization'].free()

        else:

            # Create power law model
            if self._bkgpars <= 2:
                e = gammalib.GEnergy(1.0, 'TeV')
                spec = gammalib.GModelSpectralPlaw(prefactor, index, e)

                # Set parameter ranges
                spec[0].min(prefactor / self._bkg_range_factor)
                spec[0].max(prefactor * self._bkg_range_factor)
                spec[1].scale(1)
                spec[1].min(-5.0)
                spec[1].max(5.0)

                # Set number of free parameters
                if self._bkgpars == 0:
                    spec[0].fix()
                    spec[1].fix()
                elif self._bkgpars == 1:
                    spec[0].free()
                    spec[1].fix()
                else:
                    spec[0].free()
                    spec[1].free()

            else:

                # Create reference powerlaw
                plaw = gammalib.GModelSpectralPlaw(
                    prefactor, index, gammalib.GEnergy(1.0, 'TeV'))

                # Create spectral model and energy values
                spec = gammalib.GModelSpectralNodes()
                bounds = gammalib.GEbounds(self._bkgpars,
                                           gammalib.GEnergy(emin, 'TeV'),
                                           gammalib.GEnergy(emax, 'TeV'), True)
                for i in range(bounds.size()):
                    energy = bounds.elogmean(i)
                    value = plaw.eval(energy, gammalib.GTime())
                    spec.append(energy, value)
                for par in spec:

                    if 'Energy' in par.name():
                        par.fix()
                    elif 'Intensity' in par.name():
                        value = par.value()
                        par.scale(value)
                        par.min(value / self._bkg_range_factor)
                        par.max(value * self._bkg_range_factor)

        # Return spectrum
        return spec
Ejemplo n.º 27
0
    def _select_onoff_obs(self, obs, emin, emax):
        """
        Select an energy interval from one CTA On/Off observation

        Parameters
        ----------
        obs : `~gammalib.GCTAOnOffObservation`
            Minimum energy
        emin : `~gammalib.GEnergy()`
            Minimum energy
        emax : `~gammalib.GEnergy()`
            Maximum energy

        Returns
        -------
        obs : `~gammalib.GCTAOnOffObservation`
            CTA On/Off observation
        """
        # Select energy bins in etrue and ereco. All etrue energy bins are
        # selected. A 0.1% margin is added for reconstructed energies to
        # accomodate for rounding errors.
        etrue = obs.rmf().etrue()
        ereco = gammalib.GEbounds()
        itrue = [i for i in range(obs.rmf().etrue().size())]
        ireco = []
        for i in range(obs.rmf().emeasured().size()):
            ereco_bin_min = obs.rmf().emeasured().emin(i)
            ereco_bin_max = obs.rmf().emeasured().emax(i)
            if ereco_bin_min * 1.001 >= emin and ereco_bin_max * 0.999 <= emax:
                ereco.append(ereco_bin_min, ereco_bin_max)
                ireco.append(i)

        # Extract PHA
        pha_on = gammalib.GPha(ereco)
        pha_off = gammalib.GPha(ereco)
        pha_on.exposure(obs.on_spec().exposure())
        pha_off.exposure(obs.on_spec().exposure())
        for idst, isrc in enumerate(ireco):
            # On
            pha_on[idst] = obs.on_spec()[isrc]
            pha_on.areascal(idst, obs.on_spec().areascal(isrc))
            pha_on.backscal(idst, obs.on_spec().backscal(isrc))
            # Off
            pha_off[idst] = obs.off_spec()[isrc]
            pha_off.areascal(idst, obs.off_spec().areascal(isrc))
            pha_off.backscal(idst, obs.off_spec().backscal(isrc))

        # Extract BACKRESP
        pha_backresp = obs.off_spec()['BACKRESP']
        backresp = []
        for idst, isrc in enumerate(ireco):
            backresp.append(pha_backresp[isrc])
        pha_off.append('BACKRESP', backresp)

        # Extract ARF
        arf = gammalib.GArf(etrue)
        for idst, isrc in enumerate(itrue):
            arf[idst] = obs.arf()[isrc]

        # Extract RMF
        rmf = gammalib.GRmf(etrue, ereco)
        for idst_true, isrc_true in enumerate(itrue):
            for idst_reco, isrc_reco in enumerate(ireco):
                rmf[idst_true, idst_reco] = obs.rmf()[isrc_true, isrc_reco]

        # Set On/Off observations
        obsid = obs.id()
        statistic = obs.statistic()
        instrument = obs.instrument()
        obs = gammalib.GCTAOnOffObservation(pha_on, pha_off, arf, rmf)
        obs.id(obsid)
        obs.statistic(statistic)
        obs.instrument(instrument)

        # Return observation
        return obs
Ejemplo n.º 28
0
    def _set_ebounds(self):
        """
        Set energy boundaries
        """
        # If we are in binned or On/Off mode then align the energy boundaries
        # with the cube of RMF spectrum
        if self._binned_mode or self._onoff_mode:

            # Initialise energy boundaries for spectrum
            self._ebounds = gammalib.GEbounds()

            # Create energy boundaries according to user parameters
            ebounds = self._create_ebounds()

            # Extract binned energy boundaries from first observation in
            # container. This assumes that all observations have the same
            # energy binning. But even if this is not the case, the script
            # should work reasonably well since for each observation the
            # relevant energy bins will be selected.
            if self._binned_mode:
                cube_ebounds = self.obs()[0].events().ebounds()
            else:
                cube_ebounds = self.obs()[0].rmf().emeasured()

            # Loop over user energy boundaries and collect all energy bins
            # that overlap
            for i in range(ebounds.size()):

                # Extract minimum and maximum energy of user energy bin,
                # including some rounding tolerance
                emin = ebounds.emin(i).TeV() * 0.999  # Rounding tolerance
                emax = ebounds.emax(i).TeV() * 1.001  # Rounding tolerance

                # Set number of overlapping energy bins
                nbins = 0

                # Search first cube bin that is comprised within user energy
                # bin
                emin_value = -1.0
                for k in range(cube_ebounds.size()):
                    if cube_ebounds.emin(k).TeV() >= emin and \
                       cube_ebounds.emax(k).TeV() <= emax:
                        emin_value = cube_ebounds.emin(k).TeV()
                        break
                if emin_value < 0.0:
                    continue

                # Search last cube bin that is comprised within user energy bin
                for k in range(cube_ebounds.size()):
                    if cube_ebounds.emin(k).TeV() >= emin and \
                       cube_ebounds.emax(k).TeV() <= emax:
                        emax_value = cube_ebounds.emax(k).TeV()
                        nbins += 1

                # Append energy bin if there are overlapping bins in the
                # counts cube
                if nbins > 0:
                    self._ebounds.append(gammalib.GEnergy(emin_value, 'TeV'),
                                         gammalib.GEnergy(emax_value, 'TeV'))

            # Raise an exception if there are no overlapping layers
            if (len(self._ebounds) == 0):
                msg = 'Energy range ['+str(cube_ebounds.emin())+ \
                      ', '+str(cube_ebounds.emax())+'] of counts '+ \
                      'cube does not overlap with specified energy '+ \
                      'range ['+ \
                      str(ebounds.emin())+', '+str(ebounds.emax())+'].'+ \
                      ' Specify overlapping energy range.'
                raise RuntimeError(msg)

        # Unbinned mode
        else:
            self._ebounds = self._create_ebounds()

        # Return
        return
Ejemplo n.º 29
0
    roi = gammalib.GCTARoi()
    instdir = gammalib.GCTAInstDir()
    instdir.dir(pntdir)
    roi.centre(instdir)
    roi.radius(rad)

    #Set GTI

    gti = gammalib.GGti()
    start = gammalib.GTime(tstart)
    stop = gammalib.GTime(tstart + duration)
    gti.append(start, stop)

    #Set Energy Boundaries
    ebounds = gammalib.GEbounds()
    e_min = gammalib.GEnergy(emin, 'TeV')
    e_max = gammalib.GEnergy(emax, 'TeV')
    ebounds.append(e_min, e_max)

    #Allocate event list
    events = gammalib.GCTAEventList(eventfile)
    obs.eventfile(eventfile)
    events.roi(roi)
    events.gti(gti)
    events.ebounds(ebounds)
    obs.events(events)

    #Set instrument response
    obs.response(irf, caldb)
Ejemplo n.º 30
0
    def _background_spectrum(self, prefactor, index, emin=0.01, emax=100.0):
        """
        Create a background spectrum model dependent on user parameters
        
        Parameters
        ----------
        prefactor : float
            Power law prefactor of spectral model
        index : float
            Power law index of spectral model
        emin : float
            Minimum energy (in case a spectral node function is required)
        emax : float
            Maximum energy (in case a spectral node function is required)
        
        Returns
        -------
        spec : `~gammalib.GModelSpectral()`
            Spectral model for the background shape     
        """
        # Handle constant spectral model
        if index == 0.0 and self._bkgpars <= 1:
            spec = gammalib.GModelSpectralConst()

            # Set parameter range
            spec['Normalization'].min(prefactor / self._bkg_range_factor)
            spec['Normalization'].max(prefactor * self._bkg_range_factor)
            spec['Normalization'].value(prefactor)

            # Freeze or release normalisation parameter
            if self._bkgpars == 0:
                spec['Normalization'].fix()
            else:
                spec['Normalization'].free()

        else:

            # Create power law model
            if self._bkgpars <= 2:

                # Set Power Law model with arbitrary pivot energy
                pivot = gammalib.GEnergy(1.0, 'TeV')
                spec = gammalib.GModelSpectralPlaw(prefactor, index, pivot)

                # Set parameter ranges
                spec[0].min(prefactor / self._bkg_range_factor)
                spec[0].max(prefactor * self._bkg_range_factor)
                spec[1].scale(1)
                spec[1].min(-5.0)
                spec[1].max(5.0)

                # Set number of free parameters
                if self._bkgpars == 0:
                    spec[0].fix()
                    spec[1].fix()
                elif self._bkgpars == 1:
                    spec[0].free()
                    spec[1].fix()
                else:
                    spec[0].free()
                    spec[1].free()

            else:

                # Create reference powerlaw
                pivot = gammalib.GEnergy(1.0, 'TeV')
                plaw = gammalib.GModelSpectralPlaw(prefactor, index, pivot)

                # Create spectral model and energy values
                spec = gammalib.GModelSpectralNodes()

                # Create logarithmic energy nodes
                bounds = gammalib.GEbounds(self._bkgpars,
                                           gammalib.GEnergy(emin, 'TeV'),
                                           gammalib.GEnergy(emax, 'TeV'), True)

                # Loop over bounds and set intensity value
                for i in range(bounds.size()):
                    energy = bounds.elogmean(i)
                    value = plaw.eval(energy)

                    # Append energy, value - tuple to node function
                    spec.append(energy, value)

                # Loop over parameters
                for par in spec:

                    # Fix energy nodes
                    if 'Energy' in par.name():
                        par.fix()

                    # Release intensity nodes
                    elif 'Intensity' in par.name():
                        value = par.value()
                        par.scale(value)
                        par.min(value / self._bkg_range_factor)
                        par.max(value * self._bkg_range_factor)

        # Return spectrum
        return spec