Пример #1
0
def print_values_gammalib():
    """Print some Gammalib model values that can be used for unit tests.
    
    Gammalib uses normalised PDFs, i.e. eval() returns probability / steradian
    so that the integral is one.
    """
    import numpy as np
    import gammalib

    # We need some dummy variables
    center = gammalib.GSkyDir()
    center.radec_deg(0, 0)
    energy = gammalib.GEnergy()
    time = gammalib.GTime()

    FWHM_TO_SIGMA = 1. / np.sqrt(8 * np.log(2))
    g = gammalib.GModelSpatialRadialGauss(
        center, PIX_TO_DEG * FWHM_TO_SIGMA * GAUSS_FWHM)
    d = gammalib.GModelSpatialRadialDisk(center, PIX_TO_DEG * DISK_R0)
    s = gammalib.GModelSpatialRadialShell(center, PIX_TO_DEG * SHELL_R0,
                                          PIX_TO_DEG * SHELL_WIDTH)

    models = [('g', g), ('d', d), ('s', s)]
    for name, model in models:
        for theta in THETAS:
            theta_radians = np.radians(PIX_TO_DEG * theta)
            gammalib_value = model.eval(theta_radians, energy, time)
            sherpa_value = INTEGRAL * gammalib_value * np.radians(
                PIX_TO_DEG)**2
            print name, theta, sherpa_value
Пример #2
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
Пример #3
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
def set_tmin_for_next_pointing(tmin,
                               duration,
                               array='South',
                               sunzenith=105.0,
                               moonzenith=90.0,
                               skip_days=6.0):
    """
    Set start time for next pointing

    Adds duration and 2 min for slew, and takes care of day and night. It is
    assumed that the night lasts from [0,10] and the day lasts from [10,24]

    Parameters
    ----------
    tmin : float
        Start time of current pointing (sec)
    duration : float
        Duration of current pointing (sec)
    array : str, optional
        Array
    sunzenith : float, optional
        Sun zenith angle constraint (deg)
    moonzenith : float, optional
        Moon zenith angle constraint (deg)
    skip_days : float, optional
        Number of days to skip after Sun rise

    Returns
    -------
    tmin : float
        Start time of new pointing
    """
    # Set time
    tref = gammalib.GTimeReference(51544.5, 's', 'TT', 'LOCAL')
    time = gammalib.GTime(tmin, tref)

    # Add duration and 2 min for slew
    time += duration + 120.0

    # If the Sun or the Moon is above zenith angle limit then increment
    # time until the Sun and the Moon is again below the limit
    add_days = skip_days
    while True:
        sun = zenith_sun(time, array=array)
        moon = zenith_moon(time, array=array)
        if sun < sunzenith and add_days > 0.0:
            time += 86400.0 * add_days
            add_days = 0.0
        if sun < sunzenith or moon < moonzenith:
            time += 240.0  # Add 4 min and check again
        else:
            break

    # Convert back to seconds
    tmin = time.convert(tref)

    # Return start time
    return tmin
Пример #5
0
def plot_lookup(filename, ax, nengs=300, nthetas=300):
    """
    Plot lookup table

    Parameters
    ----------
    filename : str
        Lookup table filename
    ax : figure
        Subplot
    nengs : int, optional
        Number of energies
    nthetas : int, optional
        Number of offset angles
    """
    # Load lookup table
    lookup = gammalib.GCTAModelSpatialLookup(filename)
    table = lookup.table()

    # Get boundaries
    axis_eng = table.axis('ENERG')
    axis_theta = table.axis('THETA')
    emin = table.axis_lo(axis_eng, 0)
    emax = table.axis_hi(axis_eng, table.axis_bins(axis_eng) - 1)
    tmin = table.axis_lo(axis_theta, 0)
    tmax = table.axis_hi(axis_theta, table.axis_bins(axis_theta) - 1)

    # Use log energies
    emin = math.log10(emin)
    emax = math.log10(emax)

    # Set axes
    denergy = (emax - emin) / (nengs - 1)
    dtheta = (tmax - tmin) / (nthetas - 1)
    logenergies = [emin + i * denergy for i in range(nengs)]
    thetas = [tmax - i * dtheta for i in range(nthetas)]

    # Initialise image
    image = []

    # Set event time
    time = gammalib.GTime()

    # Loop over offset angles
    for theta in thetas:

        # Set event direction
        dir = gammalib.GCTAInstDir(theta * gammalib.deg2rad, 0.0)

        # Initialise row
        row = []

        # Loop over energies
        for logenergy in logenergies:

            # Set event energy
            energy = gammalib.GEnergy()
            energy.log10TeV(logenergy)

            # Get lookup table value
            value = lookup.eval(dir, energy, time)

            # Append value
            row.append(value)

        # Append row
        image.append(row)

    # Plot image
    c = ax.imshow(image,
                  extent=[emin, emax, tmin, tmax],
                  cmap=plt.get_cmap('jet'),
                  aspect=0.8)
    cbar = plt.colorbar(c, orientation='vertical', shrink=0.7)
    cbar.set_label('sr$^{-1}$', labelpad=-22, y=-0.05, rotation=0)

    # Plot title and axis
    ax.set_xlabel('log10(E/TeV)', fontsize=12)
    ax.set_ylabel('Offset angle (deg)', fontsize=12)

    # Return
    return
Пример #6
0
    def _create_tbounds(self):
        """
        Creates light curve time bins.

        The method reads the following user parameters:
            tbinalg:  Time binning algorithm
            tbinfile: Time binning file (FITS or ASCII)
            tmin:     Start time (MJD)
            tmax:     Stop time (MJD)
            tbins:    Number of time bins

        Returns:
            Light curve bins in form of a GTI.
        """
        # Initialise Good Time Intervals
        gti = gammalib.GGti()

        # Get algorithm to use for defining the time intervals
        algorithm = self["tbinalg"].string()

        # Handle a FITS or a ASCII file for time bin definition
        if algorithm == "FILE":

            # Get the filename
            filename = self["tbinfile"].filename()

            # If the file a FITS file then load GTIs
            if filename.is_fits():
                gti.load(filename)

            # ... otherwise load file as CSV ASCII file
            csv = gammalib.GCsv(filename)
            for i in range(csv.nrows()):
                tmin = gammalib.GTime()
                tmax = gammalib.GTime()
                tmin.mjd(csv.real(i, 0))
                tmax.mjd(csv.real(i, 1))
                gti.append(tmin, tmax)

        # Handle linear time binning
        elif algorithm == "LIN":

            # Get start and stop time and number of time bins
            time_min = self["tmin"].real()
            time_max = self["tmax"].real()
            nbins = self["tbins"].integer()

            # Compute time step and setup time intervals
            time_step = (time_max - time_min) / float(nbins)
            for i in range(nbins):
                tmin = gammalib.GTime()
                tmax = gammalib.GTime()
                tmin.mjd(time_min + i * time_step)
                tmax.mjd(time_min + (i + 1) * time_step)
                gti.append(tmin, tmax)

        # Handle usage of observation GTIs
        elif algorithm == "GTI":

            # Append the GTIs of all observations
            for obs in self._obs:
                for i in range(obs.events().gti().size()):
                    gti.append(obs.events().gti().tstart(i),
                               obs.events().gti().tstop(i))

        # ... otherwise raise an exception (this should never occur)
        else:
            raise AttributeError('Paramter tbinalg="' + algorithm +
                                 '" unknown. '
                                 'Must be one of "FILE", "LIN" or "GTI".')

        # Return Good Time Intervals
        return gti
Пример #7
0
        shutil.copyfile(halo_fits_tmp2, halo_fits)

    printstat('halo_fits: ' + os.path.basename(halo_fits))
    spatial = GModelSpatialDiffuseMap(halo_fits)
    spatial['Normalization'].fix()
    jfactor = veripy.read_halo_jfactor_fits(halo_fits)
    printstat(
        os.path.basename(halo_fits) + ' loaded into GModelSpatialDiffuseMap()')

    amin, amax, anpts = 1e-2, 8, 80
    adelta_log = (log10(amax) - log10(amin)) / (anpts - 1)
    angs = [pow(10, log10(amin) + i * adelta_log) for i in range(anpts)]

    photon = gammalib.GPhoton()
    photon.energy(GEnergy(1, 'TeV'))
    photon.time(gammalib.GTime(0, 'sec'))
    svals = [[] for j in range(4)]
    for j in range(4):
        for i in range(anpts):
            skydir = gammalib.GSkyDir()
            if j == 0: skydir.lb_deg(sgra.l_deg() + angs[i], sgra.b_deg())
            elif j == 1: skydir.lb_deg(sgra.l_deg() - angs[i], sgra.b_deg())
            elif j == 2: skydir.lb_deg(sgra.l_deg(), sgra.b_deg() + angs[i])
            elif j == 3: skydir.lb_deg(sgra.l_deg(), sgra.b_deg() - angs[i])
            photon.dir(skydir)
            val = spatial.eval(photon)
            svals[j] += [val]

    fig = plt.figure()
    fax = fig.add_subplot(111)
    #for j in range(4) :
Пример #8
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
Пример #9
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
Пример #10
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
        if self._logTerse():
            self._log('\n')
            self._log.header1('Creating observation definition XML file')

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

        # Throw an exception is 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()
        identifier = 1

        # Extract header from pointing definition file
        header = []
        for col in range(ncols):
            header.append(self._pntdef[0,col])

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

            # Set row index
            row = pnt + 1

            # Create CTA observation
            obs = gammalib.GCTAObservation()

            # Set observation name
            if 'name' in header:
                name = self._pntdef[row, header.index('name')]
            else:
                name = 'None'
            obs.name(name)

            # Set identifier
            if 'id' in header:
                id_ = self._pntdef[row, header.index('id')]
            else:
                id_ = '%6.6d' % identifier
                identifier += 1
            obs.id(id_)

            # Set pointing
            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 '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_response(obs, caldb, irf)

            # Set deadtime correction factor
            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 'duration' in header:
                duration = float(self._pntdef[row, header.index('duration')])
            else:
                duration = self['duration'].real()
            tmin       = self._tmin
            tmax       = self._tmin + duration
            gti        = gammalib.GGti(self._time_reference())
            tstart     = gammalib.GTime(tmin, self._time_reference())
            tstop      = gammalib.GTime(tmax, self._time_reference())
            self._tmin = tmax
            gti.append(tstart, tstop)
            obs.ontime(gti.ontime())
            obs.livetime(gti.ontime()*deadc)

            # Set Energy Boundaries
            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
            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
            list_ = gammalib.GCTAEventList()
            list_.gti(gti)

            # Set optional information
            if has_ebounds:
                list_.ebounds(ebounds)
            if has_roi:
                list_.roi(roi)

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

            # Write observation into logger
            if self._logExplicit():
                self._log(str(obs))
                self._log('\n')
            elif self._logTerse():
                self._log(gammalib.parformat(obs.instrument()+' observation'))
                self._log('Name="'+obs.name()+'" ')
                self._log('ID="'+obs.id()+'"\n')

            # Append observation
            self._obs.append(obs)

        # Return
        return
Пример #11
0
def modmap(obs, eref=0.1, proj="TAN", coord="GAL", xval=0.0, yval=0.0, \
           binsz=0.05, nxpix=200, nypix=200, \
           outname="modmap.fits"):
    """
    Make model map for a given reference energy by combining all observations.
    The model map will be evaluated for a given reference energy 'eref' and will
    be given in units of [counts/(sr MeV s)].

    Parameters:
     obs     - Observation container
    Keywords:
     eref    - Reference energy for which model is created [TeV] (default: 0.1)
     proj    - Projection type (e.g. TAN, CAR, STG, ...) (default: TAN)
     coord   - Coordinate type (GAL, CEL) (default: GAL)
     xval    - Reference longitude value [deg] (default: 0.0)
     yval    - Reference latitude value [deg] (default: 0.0)
     binsz   - Pixel size [deg/pixel] (default: 0.05)
     nxpix   - Number of pixels in X direction (default: 200)
     nypix   - Number of pixels in Y direction (default: 200)
     outname - Model map FITS filename (default: modmap.fits)
    """
    # Allocate model map
    map = gammalib.GSkyMap(proj, coord, xval, yval, -binsz, binsz, nxpix,
                           nypix, 1)

    # Set reference energy, time and direction. The time is not initialised and is
    # in fact not used (as the IRF is assumed to be time independent for now).
    # The sky direction is set later using the pixel values.
    energy = gammalib.GEnergy()
    time = gammalib.GTime()
    instdir = gammalib.GCTAInstDir()
    energy.TeV(eref)

    # Loop over all map pixels
    for pixel in range(map.npix()):

        # Get sky direction
        skydir = map.inx2dir(pixel)
        instdir.dir(skydir)

        # Create event atom for map pixel
        atom = gammalib.GCTAEventAtom()
        atom.dir(instdir)
        atom.energy(energy)
        atom.time(time)

        # Initialise model value
        value = 0.0

        # Loop over all observations
        for run in obs:
            value += obs.models().eval(atom, run)

        # Set map value
        map[pixel] = value

    # Save sky map
    map.save(outname, True)

    # Return model map
    return map
Пример #12
0
from astropy.io import fits
import os
from utils import *

# convert binary population model from txt format provided by Guillaume
# to gammalib format

# some additional binary population parameters not in the files (see README in binpop)
# spectral index
gamma = 2.5
# maximum latitude
bmax = 2.
# threshold energy for lightcurve (MeV)
eref = 1.e6
# reference time for phasogram
t0 = gammalib.GTime()
t0.mjd(51544.5)


def phasogram_file(phases, fname, outdir):
    # derive normalization from flux
    norm = phases[:, 1] / np.max(phases[:, 1])

    # create fits columns and put them into table
    phase = fits.Column(name='PHASE', format='D', array=phases[:, 0])
    norm = fits.Column(name='NORM', format='D', array=norm)
    tbhdu = fits.BinTableHDU.from_columns([phase, norm])
    tbhdu.verify('fix')

    # write file
    tbhdu.writeto(fname, overwrite=True)
Пример #13
0
def createobs(ra=86.171648, dec=-1.4774586, rad=5.0,
              emin=0.1, emax=100.0, duration=360000.0, deadc=0.95,
              irf="South_50h", caldb="prod2"):
    """
    Create CTA observation.
    """
    # Allocate CTA observation
    obs = gammalib.GCTAObservation()

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

    # 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 instrument response
    obs.response(irf, db)

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

    # Return observation
    return obs    
Пример #14
0
    for ra in ra_list:
        dec = dec_list[number - 1]
        filename = 'events_' + 'LMC_' + modelname + '_KSP' + '0' + str(
            number) + '.fits'
        eventfile = gammalib.GFilename(filename)

        sim = ctools.ctobssim()
        sim["inmodel"] = model
        sim["seed"] = number + rndseed
        sim["outevents"] = filename
        sim["caldb"] = caldb_
        sim["irf"] = irf_
        sim["ra"] = ra
        sim["dec"] = dec
        sim["rad"] = rad
        sim["tmin"] = gammalib.GTime(tstart)
        sim["tmax"] = gammalib.GTime(tstart + duration)
        sim["emin"] = emin
        sim["emax"] = emax
        sim["debug"] = True
        sim.execute()

        #STORE THE OBSERVATION IN GObservations Class and store it in the .xml output file.

        #Allocate CTA observation
        obs = gammalib.GCTAObservation()
        #Set pointing direction
        pntdir = gammalib.GSkyDir()
        pntdir.radec_deg(ra, dec)

        pnt = gammalib.GCTAPointing()
Пример #15
0
def set(RA=83.63,
        DEC=22.01,
        tstart=0.0,
        duration=1800.0,
        deadc=0.95,
        emin=0.1,
        emax=100.0,
        rad=5.0,
        irf="cta_dummy_irf",
        caldb="$GAMMALIB/share/caldb/cta"):
    """
    Create one CTA observation

    Copied from ctools/scripts/obsutils.py and modified a bit.
    """
    # Allocate CTA observation
    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(tstart)
    stop = gammalib.GTime(tstart + 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 instrument response
    obs.response(irf, caldb)

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

    # Return observation
    return obs
Пример #16
0
    def _get_sensitivity(self, emin, emax, bkg_model, full_model):
        """
        Determine sensitivity for given observations.

        Args:
            emin:       Minimum energy for fitting and flux computation
            emax:       Maximum energy for fitting and flux computation
            bkg_model:  Background model
            full_model: Source model

        Returns:
            Result dictionary
        """
        # Set TeV->erg conversion factor
        tev2erg = 1.6021764

        # Set energy boundaries
        self._set_obs_ebounds(emin, emax)

        # Determine energy boundaries from first observation in the container
        loge = math.log10(math.sqrt(emin.TeV() * emax.TeV()))
        e_mean = math.pow(10.0, loge)
        erg_mean = e_mean * tev2erg

        # Compute Crab unit (this is the factor with which the Prefactor needs
        # to be multiplied to get 1 Crab
        crab_flux = self._get_crab_flux(emin, emax)
        src_flux = full_model[self._srcname].spectral().flux(emin, emax)
        crab_unit = crab_flux / src_flux

        # Write header
        if self._logTerse():
            self._log("\n")
            self._log.header2("Energies: " + str(emin) + " - " + str(emax))
            self._log.parformat("Crab flux")
            self._log(crab_flux)
            self._log(" ph/cm2/s\n")
            self._log.parformat("Source model flux")
            self._log(src_flux)
            self._log(" ph/cm2/s\n")
            self._log.parformat("Crab unit factor")
            self._log(crab_unit)
            self._log("\n")

        # Initialise loop
        crab_flux_value = []
        photon_flux_value = []
        energy_flux_value = []
        sensitivity_value = []
        iterations = 0
        test_crab_flux = 0.1  # Initial test flux in Crab units (100 mCrab)

        # Loop until we break
        while True:

            # Update iteration counter
            iterations += 1

            # Write header
            if self._logExplicit():
                self._log.header2("Iteration " + str(iterations))

            # Set source model. crab_prefactor is the Prefactor that
            # corresponds to 1 Crab
            src_model = full_model.copy()
            crab_prefactor = src_model[self._srcname]['Prefactor'].value() * \
                             crab_unit
            src_model[self._srcname]['Prefactor'].value(crab_prefactor * \
                             test_crab_flux)
            self._obs.models(src_model)

            # Simulate events
            sim = obsutils.sim(self._obs,
                               nbins=self._enumbins,
                               seed=iterations,
                               binsz=self._binsz,
                               npix=self._npix,
                               log=self._log_clients,
                               debug=self._debug,
                               edisp=self._edisp)

            # Determine number of events in simulation
            nevents = 0.0
            for run in sim:
                nevents += run.events().number()

            # Write simulation results
            if self._logExplicit():
                self._log.header3("Simulation")
                self._log.parformat("Number of simulated events")
                self._log(nevents)
                self._log("\n")

            # Fit background only
            sim.models(bkg_model)
            like = obsutils.fit(sim,
                                log=self._log_clients,
                                debug=self._debug,
                                edisp=self._edisp)
            result_bgm = like.obs().models().copy()
            LogL_bgm = like.opt().value()
            npred_bgm = like.obs().npred()

            # Assess quality based on a comparison between Npred and Nevents
            quality_bgm = npred_bgm - nevents

            # Write background fit results
            if self._logExplicit():
                self._log.header3("Background model fit")
                self._log.parformat("log likelihood")
                self._log(LogL_bgm)
                self._log("\n")
                self._log.parformat("Number of predicted events")
                self._log(npred_bgm)
                self._log("\n")
                self._log.parformat("Fit quality")
                self._log(quality_bgm)
                self._log("\n")

            # Write model fit results
            if self._logExplicit():
                for model in result_bgm:
                    self._log.parformat("Model")
                    self._log(model.name())
                    self._log("\n")
                    for par in model:
                        self._log(str(par) + "\n")

            # Fit background and test source
            sim.models(src_model)
            like = obsutils.fit(sim,
                                log=self._log_clients,
                                debug=self._debug,
                                edisp=self._edisp)
            result_all = like.obs().models().copy()
            LogL_all = like.opt().value()
            npred_all = like.obs().npred()
            ts = 2.0 * (LogL_bgm - LogL_all)

            # Assess quality based on a comparison between Npred and Nevents
            quality_all = npred_all - nevents

            # Write background and test source fit results
            if self._logExplicit():
                self._log.header3("Background and test source model fit")
                self._log.parformat("Test statistics")
                self._log(ts)
                self._log("\n")
                self._log.parformat("log likelihood")
                self._log(LogL_all)
                self._log("\n")
                self._log.parformat("Number of predicted events")
                self._log(npred_all)
                self._log("\n")
                self._log.parformat("Fit quality")
                self._log(quality_all)
                self._log("\n")
                #
                for model in result_all:
                    self._log.parformat("Model")
                    self._log(model.name())
                    self._log("\n")
                    for par in model:
                        self._log(str(par) + "\n")

            # Start over if TS was non-positive
            if ts <= 0.0:
                if self._logExplicit():
                    self._log("Non positive TS. Start over.\n")
                continue

            # Get fitted Crab, photon and energy fluxes
            crab_flux     = result_all[self._srcname]['Prefactor'].value() / \
                            crab_prefactor
            #crab_flux_err = result_all[self._srcname]['Prefactor'].error() / \
            #                crab_prefactor
            photon_flux = result_all[self._srcname].spectral().flux(emin, emax)
            energy_flux = result_all[self._srcname].spectral().eflux(
                emin, emax)

            # Compute differential sensitivity in unit erg/cm2/s
            energy = gammalib.GEnergy(e_mean, "TeV")
            time = gammalib.GTime()
            sensitivity = result_all[self._srcname].spectral().eval(energy, time) * \
                          e_mean*erg_mean * 1.0e6

            # Compute flux correction factor based on average TS
            correct = 1.0
            if ts > 0:
                correct = math.sqrt(self._ts_thres / ts)

            # Compute extrapolated fluxes
            crab_flux = correct * crab_flux
            photon_flux = correct * photon_flux
            energy_flux = correct * energy_flux
            sensitivity = correct * sensitivity
            crab_flux_value.append(crab_flux)
            photon_flux_value.append(photon_flux)
            energy_flux_value.append(energy_flux)
            sensitivity_value.append(sensitivity)

            # Write background and test source fit results
            if self._logExplicit():
                self._log.parformat("Photon flux")
                self._log(photon_flux)
                self._log(" ph/cm2/s\n")
                self._log.parformat("Energy flux")
                self._log(energy_flux)
                self._log(" erg/cm2/s\n")
                self._log.parformat("Crab flux")
                self._log(crab_flux * 1000.0)
                self._log(" mCrab\n")
                self._log.parformat("Differential sensitivity")
                self._log(sensitivity)
                self._log(" erg/cm2/s\n")
                for model in result_all:
                    self._log.parformat("Model")
                    self._log(model.name())
                    self._log("\n")
                    for par in model:
                        self._log(str(par) + "\n")
            elif self._logTerse():
                self._log.parformat("Iteration " + str(iterations))
                self._log("TS=")
                self._log(ts)
                self._log(" ")
                self._log("corr=")
                self._log(correct)
                self._log("  ")
                self._log(photon_flux)
                self._log(" ph/cm2/s = ")
                self._log(energy_flux)
                self._log(" erg/cm2/s = ")
                self._log(crab_flux * 1000.0)
                self._log(" mCrab = ")
                self._log(sensitivity)
                self._log(" erg/cm2/s\n")

            # Compute sliding average of extrapolated fitted prefactor,
            # photon and energy flux. This damps out fluctuations and
            # improves convergence
            crab_flux = 0.0
            photon_flux = 0.0
            energy_flux = 0.0
            sensitivity = 0.0
            num = 0.0
            for k in range(self._num_avg):
                inx = len(crab_flux_value) - k - 1
                if inx >= 0:
                    crab_flux += crab_flux_value[inx]
                    photon_flux += photon_flux_value[inx]
                    energy_flux += energy_flux_value[inx]
                    sensitivity += sensitivity_value[inx]
                    num += 1.0
            crab_flux /= num
            photon_flux /= num
            energy_flux /= num
            sensitivity /= num

            # Compare average flux to last average
            if iterations > self._num_avg:
                if test_crab_flux > 0:
                    ratio = crab_flux / test_crab_flux

                    # We have 2 convergence criteria:
                    # 1. The average flux does not change
                    # 2. The flux correction factor is small
                    if ratio   >= 0.99 and ratio   <= 1.01 and \
                       correct >= 0.9  and correct <= 1.1:
                        if self._logTerse():
                            self._log(" Converged (" + str(ratio) + ")\n")
                        break
                else:
                    if self._logTerse():
                        self._log(" Flux is zero.\n")
                    break

            # Use average for next iteration
            test_crab_flux = crab_flux

            # Exit loop if number of trials exhausted
            if (iterations >= self._max_iter):
                if self._logTerse():
                    self._log(" Test ended after " + str(self._max_iter) +
                              " iterations.\n")
                break

        # Write fit results
        if self._logTerse():
            self._log.header3("Fit results")
            self._log.parformat("Test statistics")
            self._log(ts)
            self._log("\n")
            self._log.parformat("Photon flux")
            self._log(photon_flux)
            self._log(" ph/cm2/s\n")
            self._log.parformat("Energy flux")
            self._log(energy_flux)
            self._log(" erg/cm2/s\n")
            self._log.parformat("Crab flux")
            self._log(crab_flux * 1000.0)
            self._log(" mCrab\n")
            self._log.parformat("Differential sensitivity")
            self._log(sensitivity)
            self._log(" erg/cm2/s\n")
            self._log.parformat("Number of simulated events")
            self._log(nevents)
            self._log("\n")
            self._log.header3("Background and test source model fitting")
            self._log.parformat("log likelihood")
            self._log(LogL_all)
            self._log("\n")
            self._log.parformat("Number of predicted events")
            self._log(npred_all)
            self._log("\n")
            for model in result_all:
                self._log.parformat("Model")
                self._log(model.name())
                self._log("\n")
                for par in model:
                    self._log(str(par) + "\n")
            self._log.header3("Background model fit")
            self._log.parformat("log likelihood")
            self._log(LogL_bgm)
            self._log("\n")
            self._log.parformat("Number of predicted events")
            self._log(npred_bgm)
            self._log("\n")
            for model in result_bgm:
                self._log.parformat("Model")
                self._log(model.name())
                self._log("\n")
                for par in model:
                    self._log(str(par) + "\n")

        # Restore energy boundaries of observation container
        for i, obs in enumerate(self._obs):
            obs.events().ebounds(self._obs_ebounds[i])

        # Store result
        result = {'loge': loge, 'emin': emin.TeV(), 'emax': emax.TeV(), \
                  'crab_flux': crab_flux, 'photon_flux': photon_flux, \
                  'energy_flux': energy_flux, \
                  'sensitivity': sensitivity}

        # Return result
        return result
Пример #17
0
        thiseref = args.mass / 4.0

    e_ref = gammalib.GEnergy(thiseref, 'TeV')
    e_min = gammalib.GEnergy(args.emin, 'TeV')
    e_max = gammalib.GEnergy(args.emax, 'TeV')

    #   Get expected dmflux at reference energy
    #   for all sources in Models
    theo_flux = 0.0

    for nameSource in nameSources:

        spec = models[nameSource].spectral()

        flux = spec.eval(e_ref, gammalib.GTime())
        theo_flux += flux

    print('\t* dF/dE(@ {:.2f} TeV): {:.3e} ph/(MeV cm**2 s)'.format(
        thiseref, theo_flux))

    #   Creating th fits file to save all the relevant results
    dmfits = gammalib.GFits()

    #   Creating table with number of rows equal to the number of sims
    table = gammalib.GFitsBinTable(args.nsims)

    #   Creating columns for every parameter to save
    col_runID = gammalib.GFitsTableShortCol('RunID', args.nsims)
    col_events = gammalib.GFitsTableDoubleCol('CubeEvents', args.nsims)
    # col_oevents = gammalib.GFitsTableDoubleCol( 'ObsEvents' , args.nsims )
Пример #18
0
    def _test_get_stacked_response(self):
        """
        Test get_stacked_response() function
        """
        # Set-up observation container
        obs = self._setup_sim()

        # 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(), 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(), 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 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(), 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(), 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, 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(), 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(), 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')

        # Return
        return
Пример #19
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
Пример #20
0
    def _create_tbounds(self):
        """
        Creates light curve time bins

        Returns
        -------
        gti : `~gammalib.GGti`
            Light curve bins in form of Good Time Intervals
        """
        # Initialise Good Time Intervals
        gti = gammalib.GGti()

        # Get algorithm to use for defining the time intervals. Possible
        # values are "FILE", "LIN" and "GTI". This is enforced at
        # parameter file level, hence no checking is needed.
        algorithm = self['tbinalg'].string()

        # If the algorithm is "FILE" then handle a FITS or an ASCII file for
        # the time bin definition
        if algorithm == 'FILE':

            # Get the filename
            filename = self['tbinfile'].filename()

            # If the file a FITS file then load GTIs directly
            if filename.is_fits():
                gti.load(filename)

            # ... otherwise load file the ASCII file as CSV file and construct
            # the GTIs from the rows of the CSV file. It is expected that the
            # CSV file has two columns containing the "START" and "STOP"
            # values of the time bins. No header row is expected.
            csv = gammalib.GCsv(filename)
            for i in range(csv.nrows()):
                tmin = gammalib.GTime()
                tmax = gammalib.GTime()
                tmin.mjd(csv.real(i, 0))
                tmax.mjd(csv.real(i, 1))
                gti.append(tmin, tmax)

        # If the algorithm is "LIN" then use a linear time binning, defined by
        # the "tmin", "tmax" and "tbins" user parameters
        elif algorithm == 'LIN':

            # Get start and stop time and number of time bins
            time_min = self['tmin'].time(ctools.time_reference)
            time_max = self['tmax'].time(ctools.time_reference)
            nbins = self['tbins'].integer()

            # Compute time step in seconds and setup the GTIs
            time_step = (time_max - time_min) / float(nbins)
            for i in range(nbins):
                tmin = time_min + i * time_step
                tmax = time_min + (i + 1) * time_step
                gti.append(tmin, tmax)

        # If the algorithm is "GTI" then extract the GTIs from the observations
        # in the container and use them for the light curve time binning
        elif algorithm == 'GTI':

            # Append the GTIs of all observations
            for obs in self.obs():
                for i in range(obs.events().gti().size()):
                    gti.append(obs.events().gti().tstart(i),
                               obs.events().gti().tstop(i))

        # Return Good Time Intervals
        return gti
Пример #21
0
    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(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)
Пример #22
0
def set_obs(pntdir, tstart=0.0, duration=1800.0, deadc=0.98, \
            emin=0.1, emax=100.0, rad=5.0, \
            irf='South_50h', caldb='prod2', obsid='000000'):
    """
    Set a single CTA observation
    
    The function sets a single CTA observation containing an empty CTA
    event list. By looping over this function CTA observations can be
    added to the observation container.

    Parameters
    ----------
    pntdir : `~gammalib.GSkyDir`
        Pointing direction
    tstart : float, optional
        Start time (s)
    duration : float, optional
        Duration of observation (s)
    deadc : float, optional
        Deadtime correction factor
    emin : float, optional
        Minimum event energy (TeV)
    emax : float, optional
        Maximum event energy (TeV)
    rad : float, optional
        ROI radius used for analysis (deg)
    irf : str, optional
        Instrument response function
    caldb : str, optional
        Calibration database path
    obsid : str, optional
        Observation identifier

    Returns
    -------
    obs : `~gammalib.GCTAObservation`
        CTA observation
    """
    # Allocate CTA observation
    obs = gammalib.GCTAObservation()

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

    # Set pointing direction for CTA observation
    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()
    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()

    # Set ROI, GTI and energy boundaries for event list
    events.roi(roi)
    events.gti(gti)
    events.ebounds(ebounds)

    # Set the event list as the events for CTA observation
    obs.events(events)

    # Set instrument response for CTA observation
    obs.response(irf, db)

    # Set ontime, livetime, and deadtime correction factor for CTA observation
    obs.ontime(duration)
    obs.livetime(duration * deadc)
    obs.deadc(deadc)
    obs.id(obsid)

    # Return CTA observation
    return obs
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
def schedule_observations_v3(obsdef,
                             tstart,
                             dl_min=1.0,
                             dl_max=5.0,
                             array='South',
                             skip_days=6.0,
                             dzenith_max=5.0):
    """
    Schedule observations

    Parameters
    ----------
    obsdef : list of dict
        Observation definition
    tstart : float
        Start time (s)
    dl_min : float, optional
        Minimum longitude step (deg)
    dl_max : float, optional
        Maximum longitude step (deg)
    array : string
        Array site ('South' or 'North')
    skip_days : float, optional
        Number of days to skip after Sun rise

    Returns
    -------
    obsdef : list of dict
        Scheduled observation definition
    """
    # Initialise statistics
    nobs = len(obsdef)
    last_lon = 1000.0
    last_lat = 0.0
    lon_min_step = dl_min
    lon_max_step = dl_max
    n_blocked = 0

    # Initialise time
    time = set_tmin_for_next_pointing(tstart,
                                      0.0,
                                      array=array,
                                      skip_days=skip_days)

    # Initialise scheduled observation definitions
    scheduled_obsdef = []

    # Schedule observations until all are treated
    while len(scheduled_obsdef) < nobs:

        # Find next valid observation with smallest zenith angle
        max_zenith = 0.0
        min_zenith = 180.0
        min_dzenith = 180.0
        for obs in obsdef:

            # Consider next non-scheduled observation
            if not obs['scheduled']:

                # If latitude is comparable then skip observation. This leads
                # to a toggle between the positive and negative latitudes of
                # the two-row pattern
                if abs(obs['lat'] - last_lat) < 0.1:
                    continue

                # If longitude difference is smaller than minimum longitude
                # step then skip observation
                if last_lon != 1000.0:
                    if obs['lon'] - last_lon < lon_min_step:
                        continue

                # If longitude difference is larger than maximum longitude
                # step the skip step
                if last_lon != 1000.0:
                    if obs['lon'] - last_lon > lon_max_step:
                        continue

                # Compute zenith angle
                dir = gammalib.GSkyDir()
                dir.lb_deg(obs['lon'], obs['lat'])
                tref = gammalib.GTimeReference(51544.5, 's', 'TT', 'LOCAL')
                gtime = gammalib.GTime(time, tref)
                zenith = zenith_dir(gtime, dir, array=array)

                # Compute zenith distance from culmination
                dzenith = zenith - obs['best_zenith']

                # If zenith distance from culmination is worse by dzenith_max
                # deg then skip pointing
                if dzenith > dzenith_max:
                    continue

                # Keep pointing with smallest distance from culmination
                if dzenith < min_dzenith:
                    min_dzenith = dzenith
                    min_zenith = zenith
                    max_zenith = obs['maxzenith']
                    min_obs = obs

        # If an observation with an acceptable zenith angle was found then
        # use it
        if min_dzenith < dzenith_max:

            # Set time and duration
            min_obs['tmin'] = time

            # Set zenith angle
            min_obs['zenith'] = min_zenith

            # Assign IRF zenith
            if min_zenith < 30.0:
                irfz = 20
            elif min_zenith < 50.0:
                irfz = 40
            else:
                irfz = 60
            irf = '{}_z{}_50h'.format(array, irfz)

            # Set IRF information
            min_obs['irf'] = irf

            # Schedule observation
            scheduled_obsdef.append(min_obs)

            # Update last pointing
            last_lon = min_obs['lon']
            last_lat = min_obs['lat']

            # Dump
            gtime = gammalib.GTime(time, tref)
            print('%8.3f %8.3f %8.3f  %4d/%4d  %s %s' %
                  (min_obs['lon'], min_obs['lat'], min_zenith,
                   len(scheduled_obsdef), nobs, gtime.utc(), min_obs['name']))

            # Signal that observation was scheduled
            min_obs['scheduled'] = True

        # ... otherwise remove the longitude and latitude constraints
        else:
            # Remove constraints
            last_lon = 1000.0
            last_lat = 0.0

            # Log number of blocks
            n_blocked += 1

            # If blocked for more than 5000 iterations signal
            if n_blocked > 5000:
                print('WARNING: Scheduling blocked')
                for obs in obsdef:
                    if not obs['scheduled']:
                        print('- %s %.2f %.2f %.2f %.2f' %
                              (obs['name'], obs['lon'], obs['lat'],
                               obs['best_zenith'], obs['maxzenith']))
                break

        # Increment time for next pointing
        time = set_tmin_for_next_pointing(time,
                                          obs_time * 3600.0,
                                          array=array,
                                          skip_days=skip_days)

    # Return scheduled observation
    return scheduled_obsdef