Example #1
0
def survey_single():
    """
    Creates a single observation survey for test purposes.
    """
    # Allocate observation container
    obs = gammalib.GObservations()

    # Set single pointing at galactic centre
    pntdir = gammalib.GSkyDir()
    pntdir.lb_deg(0.0, 0.0)
    run = obsutils.set_obs(pntdir)
    obs.append(run)

    # Define single point source with Crab flux at galactic centre
    center = gammalib.GSkyDir()
    center.lb_deg(0.0, 0.0)
    point_spatial  = gammalib.GModelSpatialPointSource(center)
    point_spectrum = crab_spec()
    point          = gammalib.GModelSky(point_spatial, point_spectrum)
    point.name('GC source')

    # Create model container
    models = gammalib.GModels()
    models.append(point)
    obs.models(models)

    # Return observation container
    return obs
Example #2
0
def set_lmc(hours=250.0, lst=True):
    """
    Setup LMC KSP.

    Parameters
    ----------
    hours : float, optional
        Total observation duration (h)
    lst : bool, optional
        Use LSTs

    Returns
    -------
    obsdef : list of dict
        List of pointing definitions
    """
    # Initialise observation definition
    obsdef = []

    # Set LMC centre
    centre = gammalib.GSkyDir()
    centre.radec_deg(80.0, -69.0)

    # Set offset angle and number of pointings
    offset = 1.0 # degrees
    n_pnt  = 12

    # Prepare computations
    dphi     = 360.0/n_pnt
    duration = hours*3600.0/float(n_pnt)

    # Loop over pointings
    for ipnt in range(n_pnt):

        # Compute pointing direction
        pnt = centre.copy()
        pnt.rotate_deg(ipnt*dphi, offset)
        lon = pnt.l_deg()
        lat = pnt.b_deg()

        # Set positions and duration
        obs = {'lon': lon, 'lat': lat, 'duration': duration}

        # Add IRF
        caldb = 'prod2'
        if lst:
            irf = 'South_50h'
        else:
            irf = 'South_50h'
        obs['caldb'] = caldb
        obs['irf']   = irf

        # Append observation
        obsdef.append(obs)

    # Dump statistics
    print('Number of pointings: %d (%.2f s)' % (n_pnt,duration))

    # Return observation definition
    return obsdef
Example #3
0
    def _get_parameters(self):
        """
        Get parameters from parfile and setup the observation
        """
        # Get parameters
        if self.obs().size() == 0:
            self._require_inobs('csobsinfo::get_parameters')
            self.obs(self._get_observations(False))

        # Initialise object position
        self._obj_dir = gammalib.GSkyDir()

        # Get (optional) offset parameters
        self._compute_offset = self['offset'].boolean()
        if self._compute_offset:
            ra = self['ra'].real()
            dec = self['dec'].real()
            self._obj_dir.radec_deg(ra, dec)

        # Read ahead DS9 filename
        if self._read_ahead():
            self['outds9file'].query()

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

        # Return
        return
Example #4
0
    def _query_src_direction(self):
        """
        Set up the source direction parameter
        """
        # Initialise source direction
        self._src_dir = gammalib.GSkyDir()

        # Get coordinate systel
        coordsys = self['coordsys'].string()

        # If coordinate system is celestial then query "ra" and "dec"
        if coordsys == 'CEL':
            ra = self['ra'].real()
            dec = self['dec'].real()
            self._src_dir.radec_deg(ra, dec)

        # ... otherwise, if coordinate system is galactic then query "glon"
        # and "glat"
        elif coordsys == 'GAL':
            glon = self['glon'].real()
            glat = self['glat'].real()
            self._src_dir.lb_deg(glon, glat)

        # Return
        return
Example #5
0
def set_map(obsdef, radius=2.0):
    """
    Set map from observation definition dictionary

    Parameters
    ----------
    obsdef : list of dict
        List of pointing definitions
    """
    # Create sky map
    map = gammalib.GSkyMap('CAR', 'GAL', 340.0, 0.0, -0.1, 0.1, 950, 100)

    # Loop over observations
    for obs in obsdef:

        # Set sky region
        centre   = gammalib.GSkyDir()
        centre.lb_deg(obs['lon'], obs['lat'])
        circle   = gammalib.GSkyRegionCircle(centre, radius)
        region   = gammalib.GSkyRegionMap(circle)
        exposure = region.map().copy()
        exposure *= obs['duration']/3600.0

        # Add sky region
        map += exposure

    # Return map
    return map
Example #6
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
def create_region_maps(rad_on=0.6, rad_off=[0.8, 1.0]):
    """
    Create region maps

    Parameters
    ----------
    rad_on : float, optional
        On region radius (deg)
    rad_off : list of float, optional
        Off region minimum and maximum radius (deg)
    """
    # Set centre
    centre = gammalib.GSkyDir()
    centre.radec_deg(258.1125, -39.6867)

    # Create sky maps
    srcreg = gammalib.GSkyMap('TAN', 'CEL', 258.1125, -39.6867, 0.01, 0.01,
                              300, 300)
    bkgreg = gammalib.GSkyMap('TAN', 'CEL', 258.1125, -39.6867, 0.01, 0.01,
                              300, 300)

    # Fill sky map
    for i in range(srcreg.npix()):
        rad = centre.dist_deg(srcreg.inx2dir(i))
        if rad <= rad_on:
            srcreg[i] = 1
        if rad > rad_off[0] and rad < rad_off[1]:
            bkgreg[i] = 1

    # Save maps
    srcreg.save('rx_srcreg_map.fits', True)
    bkgreg.save('rx_bkgreg_map.fits', True)

    # Return
    return
def zenith_moon(time, array='South'):
    """
    Compute zenith angle of the Moon at a given time

    Parameters
    ----------
    time : `~gammalib.GTime()`
        Time for which the Moon zenith angle is to be computed
    array : string, optional
        Array site

    Returns
    -------
    zenith : float
        Moon zenith angle in (degrees)
    """
    # Compute Right Ascension and Declination of Moon in degrees and convert
    # the Declination into radians
    moon = gammalib.GSkyDir()
    moon.moon(time)

    # Get zenith angle
    zenith = zenith_dir(time, moon, array=array)

    # Return zenith angle
    return zenith
Example #9
0
def bin2gammalib(filename, flux_thresh, outdir):
    data = open(filename).readlines()

    # convert phasogram to numpy array
    phasogram = np.genfromtxt(data[14:])

    # only include model if peak in lightcurve is > threshold
    if np.max(phasogram[:, 2]) > flux_thresh:

        # final name
        num = int(data[0].split('#')[-1])
        name = 'bin{:03d}'.format(num)

        # spatial model
        # read Galactic longitude
        lon = float(data[1].split('   ')[-1])
        # Galactic latitude is random with Gaussian distribution with 95% containment at bmax
        lat = np.random.normal(0, bmax / 2)
        src_dir = gammalib.GSkyDir()
        src_dir.lb_deg(lon, lat)
        spatial = gammalib.GModelSpatialPointSource(src_dir)

        # spectral model
        # average flux in ph/cm2/s
        f0 = np.average(phasogram[:, 1])
        # convert to differential flux at eref in ph/cm2/s/MeV
        n0 = (gamma - 1) * f0 / eref
        spectral = gammalib.GModelSpectralPlaw(
            n0, -gamma, gammalib.GEnergy(np.double(eref), 'MeV'))

        # orbital phase model
        # create phasogram file
        fname = 'phasecurve_' + name + '.fits'
        phasogram_file(phasogram, outdir + fname, outdir)
        # period in days
        per = float(data[4].split(' ')[-1])
        # convert to frequency in s
        per *= 86400
        f0 = 1 / per
        temporal = gammalib.GModelTemporalPhaseCurve(
            gammalib.GFilename(fname),
            t0,
            np.random.random(),  # phase at t0 randomly drawn
            f0,
            0.,
            0.,  # orbit is stable, no derivatives
            1.,
            True)  # normalized so that spectral model represents average flux

        # assemble final model
        model = gammalib.GModelSky(spatial, spectral, temporal)
        model.name(name)

    else:
        # empty model
        lat = 0.
        model = gammalib.GModelSky()

    return model, lat
def set_patch(tmin, xmin, xmax, duration, array):
    obsdef = []

    # set as many observations as allowed by total duration time and observation length
    n_pnt = int(duration / obs_time) - 2  # - 2 to allow for margin in get_positions
    xstep = 2 * (xmax - xmin) / n_pnt
    pointings = get_positions(xmin, xmax, nrows, step, fixed_xstep=xstep)

    # Set observations
    total_duration = 0
    for pnt in pointings:
        # Set positions, start time and duration
        obs = {'lon': pnt['x'], 'lat': pnt['y'], 'rad': rad, \
               'tmin': tmin, 'duration': obs_time * 3600.}

        # Update start time for next pointing
        tmin = set_tmin_for_next_pointing(tmin, obs_time * 3600.)

        # Find Dec for pointing
        pnt_dir = gammalib.GSkyDir()
        pnt_dir.lb_deg(pnt['x'], pnt['y'])
        dec = pnt_dir.dec_deg()

        # Automatic IRF setting
        # Set geographic latitude of array
        if array == 'North':
            geolat = +28.7569
        else:
            geolat = -24.58
        # Compute best possible zenith angle
        zenith = abs(dec - geolat)
        # Assign IRF zenith
        if zenith < 30.0:
            irfz = 20
        elif zenith < 50.0:
            irfz = 40
        else:
            irfz = 60
        irf = '{}_z{}_50h'.format(array, irfz)

        # Set IRF information
        obs['caldb'] = caldb
        obs['irf'] = irf

        # Append observation
        obsdef.append(obs)

        # Add to total duration
        total_duration += obs_time

    # check that total duration is preserved
    if total_duration == duration:
        pass
    else:
        print(
            'WARNING: total duration of {} h and requested observation of {} do not match'.format(
                total_duration, duration))

    return obsdef
Example #11
0
def set_irf(site, obs, caldb, lst=True):
    """
    Setup Instrument Response Function

    Parameters
    ----------
    site : str
        Array site (either 'South' or 'North')
    obs : dict
        Dictionary with pointing information
    caldb : str
        Calibration database
    lst : bool, optional
        Use LSTs

    Returns
    -------
    irf : str
        IRF name
    """
    # Handle 'prod2'
    if caldb == 'prod2':
        if site == 'North':
            irf = 'North_50h'
        else:
            irf = 'South_50h'

    # Handle 'prod3' and 'prod3b'
    else:

        # Compute Right Ascension and Declination of pointing
        pnt = gammalib.GSkyDir()
        pnt.lb_deg(obs['lon'], obs['lat'])
        #ra  = pnt.ra_deg()
        dec = pnt.dec_deg()

        # Set geographic latitude of array
        if site == 'North':
            geolat = +28.7569
        else:
            geolat = -24.58

        # Compute best possible zenith angle
        zenith = abs(dec - geolat)

        # Set IRF
        if site == 'North':
            irf = 'North'
        else:
            irf = 'South'
        if zenith < 30.0:
            irf += '_z20'
        else:
            irf += '_z40'
        irf += '_50h'

    # Return IRF
    return irf
Example #12
0
def write_obsdef(filename, obsdef, idstart):
    """
    Write observation definition dictionary

    Parameters
    ----------
    filename : str
        Observation definition file name
    obsdef : list of dict
        List of pointing definitions
    idstart : int
        First identifier of observation definition file
    """
    # Open file
    f = open(filename, 'w')

    # Write header
    f.write('id,ra,dec,tmin,duration,caldb,irf,emin,emax\n')

    # Initialise identifier
    obsid = idstart

    # Loop over pointings
    for obs in obsdef:

        # If we have lon,lat then convert into RA,Dec
        if 'lon' in obs and 'lat' in obs:
            lon = obs['lon']
            lat = obs['lat']
            pnt = gammalib.GSkyDir()
            pnt.lb_deg(lon,lat)
            ra  = pnt.ra_deg()
            dec = pnt.dec_deg()
        else:
            ra  = obs['ra']
            dec = obs['dec']

        # Set site dependent energy thresholds
        if 'South' in obs['irf']:
            emin =   0.030
            emax = 160.0
        else:
            emin =  0.030
            emax = 50.0

        # Write information
        f.write('%6.6d,%8.4f,%8.4f,%.4f,%.4f,%s,%s,%.3f,%.1f\n' %
                (obsid, ra, dec, obs['tmin'], obs['duration'], obs['caldb'], \
                 obs['irf'], emin, emax))

        # Increment identifier
        obsid += 1

    # Close file
    f.close()

    # Return
    return
Example #13
0
    def _set_obs(self, lpnt=0.0, bpnt=0.0, emin=0.1, emax=100.0):
        """
        Set an observation container.

        Kwargs:
            lpnt: Galactic longitude of pointing [deg] (default: 0.0)
            bpnt: Galactic latitude of pointing [deg] (default: 0.0)
            emin: Minimum energy [TeV] (default: 0.1)
            emax: Maximum energy [TeV] (default: 100.0)

        Returns:
            Observation container.
        """
        # If an observation was provided on input then load it from XML
        # file
        filename = self["inobs"].filename()
        if filename != "NONE" and filename != "":
            obs = self._get_observations()

        # ... otherwise allocate a single observation
        else:

            # Read relevant user parameters
            caldb = self["caldb"].string()
            irf = self["irf"].string()
            deadc = self["deadc"].real()
            duration = self["duration"].real()
            rad = self["rad"].real()

            # Allocate observation container
            obs = gammalib.GObservations()

            # Set single pointing
            pntdir = gammalib.GSkyDir()
            pntdir.lb_deg(lpnt, bpnt)

            # Create CTA observation
            run = obsutils.set_obs(pntdir,
                                   caldb=caldb,
                                   irf=irf,
                                   duration=duration,
                                   deadc=deadc,
                                   emin=emin,
                                   emax=emax,
                                   rad=rad)

            # Append observation to container
            obs.append(run)

            # Set source position
            offset = self["offset"].real()
            pntdir.lb_deg(lpnt, bpnt + offset)
            self._ra = pntdir.ra_deg()
            self._dec = pntdir.dec_deg()

        # Return observation container
        return obs
Example #14
0
def set_hgps(pointings, exposure=28.0*60.0, caldb='hess'):
    """
    Setup H.E.S.S. Galactic plane survey

    Parameters
    ----------
    pointings : list of dict
        HGPS pointings

    Returns
    -------
    obsdef : list of dict
        List of pointing definitions
    """
    # Initialise observation definition
    obsdef = []

    # Initialise start time in seconds (1-1-2021)
    tmin = 7671.0 * 86400.0

    # Set geographic latitude of H.E.S.S. array
    geolat = -23.27178

    # Loop over all pointings
    for pointing in pointings:

        # Compute Right Ascension and Declination of pointing
        pnt = gammalib.GSkyDir()
        pnt.lb_deg(pointing['lon'], pointing['lat'])
        ra  = pnt.ra_deg()
        dec = pnt.dec_deg()

        # Compute best possible zenith angle
        zenith = abs(dec - geolat)

        # Set IRF
        irf = 'dummy'

        # Set positions, start time and duration
        obs = {'lon': pointing['lon'], \
               'lat': pointing['lat'], \
               'tmin': tmin, \
               'duration': exposure,
               'zenith': zenith,
               'caldb': caldb,
               'irf': irf}

        # Update start time for next pointing; add 2 min for slew
        tmin += exposure + 120.0

        # Append observation
        obsdef.append(obs)

    # Return observation definition
    return obsdef
Example #15
0
def get_pointings(filename):
    """
    Extract pointings from CSV file

    Parameters
    ----------
    filename : str
        File name of observation definition CSV file

    Returns
    -------
    pnt : list of dict
        Pointings
    """
    # Initialise pointings
    pnt = []

    # Open CSV file
    csv = gammalib.GCsv(filename, ',')

    # Loop over rows
    for i in range(csv.nrows()):

        # Skip header
        if i == 0:
            continue

        # Extract information
        id = csv[i, 1]
        lon = float(csv[i, 2])
        lat = float(csv[i, 3])
        tstart = float(csv[i, 5])
        duration = float(csv[i, 6])
        irf = csv[i, 8]
        zenith = float(csv[i, 11])

        # Convert direction
        dir = gammalib.GSkyDir()
        dir.lb_deg(lon, lat)

        # Derive attributes
        south = 'South' in irf

        # Create entry
        entry = {'id': id, 'l': lon, 'b': lat,
                 'ra': dir.ra_deg(), 'dec': dir.dec_deg(),
                 'time': tstart, 'duration': duration, \
                 'zenith': zenith, 'south': south}

        # Append pointing
        pnt.append(entry)

    # Return pointings
    return pnt
Example #16
0
def set_obs_patterns(pattern, ra=83.6331, dec=22.0145, offset=1.5):
    """
    Sets a number of standard patterns
    
    Parameters
    ----------
    pattern : str
        Observation pattern ("single", "four")
    ra : float, optional
        Right Ascension of pattern centre (deg)
    dec : float, optional
        Declination of pattern centre (deg)
    offset : float, optional
        Offset from pattern centre (deg)

    Returns
    -------
    obsdeflist : list
        Observation definition list
    """
    # Initialise observation definition list
    obsdeflist = []

    # If the pattern is a single observation then append the Right Ascension
    # and Declination to the observation definition list
    if pattern == 'single':
        obsdef = {'ra': ra, 'dec': dec}
        obsdeflist.append(obsdef)

    # ... otherwise, if the pattern is four observations then append four
    # observations offset by a certain amount from the pattern centre to the
    # observation definition list
    elif pattern == 'four':

        # Set pattern centre
        centre = gammalib.GSkyDir()
        centre.radec_deg(ra, dec)

        # Append pointings
        for phi in [0.0, 90.0, 180.0, 270.0]:
            pntdir = centre.copy()
            pntdir.rotate_deg(phi, offset)
            obsdeflist.append({'ra': pntdir.ra_deg(), 'dec': pntdir.dec_deg()})

    # ... otherwise raise an exception since we have an unknown pattern
    else:
        msg = 'Observation pattern "%s" not recognized.' % (pattern)
        raise RuntimeError(msg)

    # Return observation definition list
    return obsdeflist
Example #17
0
def survey_gplane(lrange=10, lstep=2):
    """
    Creates a single observation survey for test purposes.

    Keywords:
     lrange - Longitude range (integer deg)
     lstep  - Longitude step size (integer deg)
    """
    # Allocate observation container
    obs = gammalib.GObservations()

    # Loop over longitudes
    for l in range(-lrange,lrange+lstep,lstep):

        # Set pointing
        pntdir = gammalib.GSkyDir()
        pntdir.lb_deg(l, 0.0)
        run = obsutils.set_obs(pntdir)
        run.id(str(l))
        obs.append(run)

    # Define single point source with Crab flux at galactic centre
    center = gammalib.GSkyDir()
    center.lb_deg(0.0, 0.0)
    point_spatial  = gammalib.GModelSpatialPointSource(center)
    point_spectrum = crab_spec()
    point          = gammalib.GModelSky(point_spatial, point_spectrum)
    point.name('GC source')

    # Create model container
    models = gammalib.GModels()
    models.append(point)
    obs.models(models)

    # Return observation container
    return obs
def write_obsdef(filename, obsdef, idstart, emin, emax):
    """
    Write observation definition file

    Parameters
    ----------
    filename : str
        Observation definition file name
    obsdef : list of dict
        List of pointing definitions
    idstart : int
        First identifier of observation definition file
    emin : float
        Minimum energy (TeV)
    emax : float
        Maximum energy (TeV)
    """
    # Open file
    f = open(filename, 'w')

    # Write header
    f.write('name,id,lon,lat,rad,tmin,duration,caldb,irf,emin,emax,zenith\n')

    # Initialise identifier
    obsid = idstart

    # Loop over pointings
    for obs in obsdef:

        # We have lon,lat then convert into RA,Dec
        lon = obs['lon']
        lat = obs['lat']
        pnt = gammalib.GSkyDir()
        pnt.lb_deg(lon, lat)
        ra = pnt.ra_deg()
        dec = pnt.dec_deg()

        # Write information
        f.write('%s,%6.6d,%8.4f,%8.4f,%8.4f,%.4f,%.4f,%s,%s,%.3f,%.1f,%.2f\n' %
                (obs['name'], obsid, obs['lon'], obs['lat'], obs['rad'],
                 obs['tmin'], obs['duration'], obs['caldb'], obs['irf'], emin,
                 emax, obs['zenith']))

        # Increment identifier
        obsid += 1

    # Close file
    f.close()
Example #19
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
Example #20
0
def create_models():
    """
    """
    # Create model container
    models = gammalib.GModels()
    
    # Create a power law model for the Crab
    crabdir = gammalib.GSkyDir()
    crabdir.radec_deg(83.6331, 22.0145)
    spatial  = gammalib.GModelSpatialPointSource(crabdir)
    energy   = gammalib.GEnergy(100.0, "MeV")
    spectral = gammalib.GModelSpectralPlaw(5.7e-16, -2.48, energy)
    model    = gammalib.GModelSky(spatial, spectral)
    models.append(model)
    
    # Return models
    return models
Example #21
0
    def open_observation(self, obsfilename):

        print('Open observation')

        obs = gammalib.GObservations()

        self.obsconf = ObservationConfiguration(obsfilename,
                                                self.runconf.timesys,
                                                self.runconf.timeunit,
                                                self.runconf.skyframeref,
                                                self.runconf.skyframeunitref)
        print(self.obsconf.caldb)

        pntdir = gammalib.GSkyDir()

        in_pnttype = self.obsconf.point_frame
        print(in_pnttype)
        if in_pnttype == 'fk5':
            pntdir.radec_deg(self.obsconf.point_ra, self.obsconf.point_dec)

        #if in_pnttype == 'equatorial' :
        #pntdir.radec_deg(self.obs_ra, self.obs_dec)

        #if in_pnttype == 'galactic' :
        #	pntdir.radec_deg(self.in_l, self.in_b)

        #pntdir.radec_deg(self.obsconf.obs_point_ra, self.obsconf.obs_point_dec)

        tstart = self.obsconf.tstart - self.runconf.timeref
        print(tstart)
        if self.runconf.timeref_timesys == 'mjd':
            tstart = tstart * 86400.

        print("TSTART " + str(tstart))

        obs1 = obsutils.set_obs(pntdir, tstart, self.obsconf.duration, 1.0, \
         self.obsconf.emin, self.obsconf.emax, self.obsconf.roi_fov, \
         self.obsconf.irf, self.obsconf.caldb, self.obsconf.id)

        print(obs1)

        obs.append(obs1)

        #print(obs1)
        return obs
def create_model(flux, index=-2.48, fitidx=False):
    """
    Add standard CTA background model to observations container.
    We use a simple power law here, scaled to Konrad's E configuration
    performance table.

    Parameters:
     flux - Flux in Crab units
    """
    # Define background model
    bgd_radial = gammalib.GCTAModelRadialGauss(3.0)
    bgd_spectrum = gammalib.GModelSpectralPlaw(61.8, -1.85)
    bgd_spectrum["Prefactor"].scale(1.0e-6)
    bgd_spectrum["PivotEnergy"].value(1.0)
    bgd_spectrum["PivotEnergy"].scale(1.0e6)
    if fitidx:
        bgd_spectrum["Index"].free()
    else:
        bgd_spectrum["Index"].fix()
    bgd_model = gammalib.GCTAModelRadialAcceptance(bgd_radial, bgd_spectrum)
    bgd_model.name("Background")
    bgd_model.instruments("CTA")

    # Define source spectrum
    location = gammalib.GSkyDir()
    location.radec_deg(83.6331, 22.0145)
    src_spatial = gammalib.GModelSpatialPtsrc(location)
    src_spectrum = gammalib.GModelSpectralPlaw(flux, index)
    src_spectrum["Prefactor"].scale(5.7e-16)
    src_spectrum["PivotEnergy"].value(0.3)
    src_spectrum["PivotEnergy"].scale(1.0e6)
    if fitidx:
        src_spectrum["Index"].free()
    else:
        src_spectrum["Index"].fix()
    src_model = gammalib.GModelPointSource(src_spatial, src_spectrum)
    src_model.name("Test")

    # Add models to container
    models = gammalib.GModels()
    models.append(bgd_model)
    models.append(src_model)

    # Return model container
    return models
Example #23
0
    def _setup_sim(self, two=False):
        """
        Setup method for sim() function test
        """
        # Set-up observation container
        pnt = gammalib.GSkyDir()
        pnt.radec_deg(83.6331, 22.0145)
        obs = gammalib.GObservations()
        run = obsutils.set_obs(pnt, duration=20.0, emin=1.0, emax=10.0)
        run.id('0')
        obs.append(run)
        if two:
            run.id('1')
            obs.append(run)

        # Append model
        obs.models(gammalib.GModels(self._model))

        # Return
        return obs
Example #24
0
def write_obsdef(filename, obsdef):
    """
    Write observation definition file

    Parameters
    ----------
    filename : str
        Observation definition file name
    obsdef : list of dict
        List of pointing definitions
    """
    # Open file
    file = open(filename, 'w')

    # Write header
    file.write('ra,dec,duration,caldb,irf\n')

    # Loop over pointings
    for obs in obsdef:

        # If we have lon,lat then convert into RA,Dec
        if 'lon' in obs and 'lat' in obs:
            lon = obs['lon']
            lat = obs['lat']
            dir = gammalib.GSkyDir()
            dir.lb_deg(lon,lat)
            ra  = dir.ra_deg()
            dec = dir.dec_deg()
        else:
            ra  = obs['ra']
            dec = obs['dec']

        # Write information
        file.write('%8.4f,%8.4f,%.4f,%s,%s\n' %
                   (ra, dec, obs['duration'], obs['caldb'], obs['irf']))

    # Close file
    file.close()

    # Return
    return
Example #25
0
    def _select_circle(self, obs):
        """
        Select observation in a pointing circle

        Parameters
        ----------
        obs : `~gammalib.GCTAObservation`
            CTA observation

        Returns
        -------
        select : bool
            Observation selection flag
        """
        # Get coordinate system of selection circle
        coordsys = self['coordsys'].string()

        # Get pointing direction
        pnt = obs.pointing().dir()

        # Set selection circle centre
        centre = gammalib.GSkyDir()
        if coordsys == 'CEL':
            centre.radec_deg(self['ra'].real(), self['dec'].real())
        else:
            centre.lb_deg(self['glon'].real(), self['glat'].real())

        # Set selection flag according to distance
        if centre.dist_deg(pnt) <= self['rad'].real():
            select = True
            msg    = 'inside selection circle'
        else:
            select = False
            msg    = 'outside selection circle'

        # Log observation selection
        self._log_selection(obs, msg)

        # Return selection flag
        return select
Example #26
0
    def _test_set_obs(self):
        """
        Test set_obs() function
        """
        # Setup pointing direction
        pnt = gammalib.GSkyDir()
        pnt.radec_deg(83.63, 22.51)

        # Setup one CTA observation
        res = obsutils.set_obs(pnt, emin=1.0, emax=10.0)

        # Check result
        self.test_value(res.eventtype(), 'EventList', 'Check event type')
        self.test_value(res.events().ebounds().emin().TeV(), 1.0,
                        'Check minimum energy')
        self.test_value(res.events().ebounds().emax().TeV(), 10.0,
                        'Check maximum energy')
        self.test_value(res.pointing().dir().ra_deg(), 83.63,
                        'Check pointing Right Ascension')
        self.test_value(res.pointing().dir().dec_deg(), 22.51,
                        'Check pointing declination')

        # Setup one CTA observation for local caldb directory
        res = obsutils.set_obs(pnt, caldb=self._datadir, irf='irf_file.fits',
                               emin=1.0, emax=10.0)

        # Check result
        self.test_value(res.eventtype(), 'EventList', 'Check event type')
        self.test_value(res.events().ebounds().emin().TeV(), 1.0,
                        'Check minimum energy')
        self.test_value(res.events().ebounds().emax().TeV(), 10.0,
                        'Check maximum energy')
        self.test_value(res.pointing().dir().ra_deg(), 83.63,
                        'Check pointing Right Ascension')
        self.test_value(res.pointing().dir().dec_deg(), 22.51,
                        'Check pointing declination')

        # Return
        return
Example #27
0
def set_obs_patterns(pattern, ra=83.6331, dec=22.0145, offset=1.5):
    """
    Sets a number of standard patterns.

    Parameters:
     pattern - Observation pattern. Possible options are:
               - "single": single pointing
               - "four": four pointings 'offset' around pattern centre

    Keywords:
     ra      - Right Ascension of pattern centre [deg] (default: 83.6331)
     dec     - Declination of pattern centre [deg] (default: 22.0145)
     offset  - Offset from pattern centre [deg] (default: 1.5)
    """
    # Initialise observation definition list
    obsdeflist = []

    # Add patterns
    if pattern == "single":
        obsdef = {'ra': ra, 'dec': dec}
        obsdeflist.append(obsdef)
    elif pattern == "four":
        # Set pattern centre
        centre = gammalib.GSkyDir()
        centre.radec_deg(ra, dec)

        # Append pointings
        for phi in [0.0, 90.0, 180.0, 270.0]:
            pntdir = centre.copy()
            pntdir.rotate_deg(phi, offset)
            obsdeflist.append({'ra': pntdir.ra_deg(), 'dec': pntdir.dec_deg()})
    else:
        print("Warning: Observation pattern '" + str(pattern) +
              "' not recognized.")

    # Return observation definition list
    return obsdeflist
Example #28
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
def residual_radial(cntcube, modcube, ebins=4, rad=2.0, dr=0.1):
    """
    Determine radial residuals

    Parameters
    ----------
    cntcube : `~gammalib.GCTAEventCube`
        Counts cube
    modcube : `~gammalib.GCTAEventCube`
        Model cube
    ebins : int, optional
        Number of energy bins
    rad : float, optional
        Maximum radius
    dr : float, optional
        Radius binsize

    Returns
    -------
    residual : dict
        Residual dictionary
    """
    # Extract energy boundaries
    ebounds = cntcube.ebounds().copy()

    # Extract counts and model cubes sky maps
    cnt = cntcube.counts()
    mod = modcube.counts()

    # Define radius axis
    nr = int(rad / dr + 0.5)
    radius = [(r + 0.5) * dr for r in range(nr)]

    # Define energy binning
    nebins = ebounds.size()
    debins = float(ebins) / float(nebins)

    # Initialise result arrays
    counts = [[0.0 for r in range(nr)] for e in range(ebins)]
    model = [[0.0 for r in range(nr)] for e in range(ebins)]
    pixels = [[0.0 for r in range(nr)] for e in range(ebins)]

    # Initialise centre direction
    centre = gammalib.GSkyDir()
    centre.radec_deg(0.0, 0.0)

    # Loop over cube pixels
    for k in range(cnt.npix()):

        # Compute theta angle (deg)
        theta = centre.dist_deg(cnt.inx2dir(k))

        # Get radius index
        ir = int(theta / dr)

        # Skip pixel if it is not inside radius axis
        if ir < 0 or ir >= nr:
            continue

        # Loop over energies
        for i in range(nebins):

            # Get energy index
            ie = int(float(i) * debins)

            # Skip layer if it is not inside energy bins
            if ie < 0 or ie >= ebins:
                continue

            # Add cube content to array
            counts[ie][ir] += cnt[k, i]
            model[ie][ir] += mod[k, i]
            pixels[ie][ir] += 1.0

    # Build result dictionary
    residual = []
    for ie in range(ebins):

        # Compute normalised arrays
        rad_array = []
        counts_array = []
        error_array = []
        model_array = []
        residual_array = []
        for ir in range(nr):
            if pixels[ie][ir] > 0.0:
                if model[ie][ir] > 0.0:
                    if counts[ie][ir] > 0.0:
                        res = math.sqrt(
                            2.0 * (counts[ie][ir] *
                                   math.log(counts[ie][ir] / model[ie][ir]) +
                                   model[ie][ir] - counts[ie][ir]))
                    else:
                        res = model[ie][ir]
                    if counts[ie][ir] < model[ie][ir]:
                        res *= -1.0
                else:
                    res = 0.0
                rad_array.append(radius[ir])
                counts_array.append(counts[ie][ir] / pixels[ie][ir])
                error_array.append(math.sqrt(counts[ie][ir]) / pixels[ie][ir])
                model_array.append(model[ie][ir] / pixels[ie][ir])
                residual_array.append(res)

        # Build result dictionary
        iemin = int(ie / debins + 0.5)
        iemax = int((ie + 1) / debins - 0.5)
        result = {
            'emin': ebounds.emin(iemin).TeV(),
            'emax': ebounds.emax(iemax).TeV(),
            'radius': rad_array,
            'counts': counts_array,
            'error': error_array,
            'model': model_array,
            'residual': residual_array
        }

        # Append dictionary
        residual.append(result)

    # Return residual
    return residual
def append_fhl(models, bmax,
                bin_models, bin_dict, bin_distx, bin_disty, bin_radr, bin_frlog,
                snr_models, snr_dict, snr_distx, snr_disty, snr_radr, snr_frlog,
                isnr_models, isnr_dict, isnr_distx, isnr_disty, isnr_radr, isnr_frlog,
                dist_sigma=3., sig50_thresh=3., eph_thresh=100.):
    """
    Append missing models from Fermi high-energy catalog to gammalib model container
    :param models: ~gammalib.GModels, gammalib model container
    :param bmax: float, maximum latitude of models to include
    :param dist_sigma: float, minimum distance in sigma's from pre-existing source to add as new
    :param sig50_thresh: float, threshold sigma on significance above 50 GeV to apply
    :param eph_thresh: float, minimum energy of detected photons required
    :return: result: dictionary
    """
    # filter FHL table based on latitude and hardness
    # hard sources are seleted based on significance above 50 GeV and highest photon energy
    # calculate significance above 50 GeV
    sig50 = np.sqrt(np.sum(np.power(fhl['Sqrt_TS_Band'][:,2:], 2),axis=1))
    # filter
    fsources = fhl[(np.abs(fhl['GLAT']) <= bmax) & (sig50 >= sig50_thresh) & (
                fhl['HEP_Energy'] >= eph_thresh)]

    # prepare new gammalib model container
    newpt = 0
    newext = 0
    n_bin_del = 0
    n_snr_del = 0
    n_isnr_del = 0
    newmodels = gammalib.GModels()
    # keep track also of artificial cutoffs
    ecut_pwn = []
    ecut_snr = []
    ecut_unid = []
    ecut_agn = []
    n_ecut_pwn = 0
    n_ecut_snr = 0
    n_ecut_agn = 0
    n_ecut_unid = 0

    msg = ''

    # loop over fermi sources
    for fsource in fsources:
        # assume source is new
        new = 1
        # fermi source position as gammalib.GSkyDir
        fdir = gammalib.GSkyDir()
        ra = np.double(fsource['RAJ2000'])
        dec = np.double(fsource['DEJ2000'])
        fdir.radec_deg(ra, dec)
        ######################################### treat pointlike sources for Fermi ###########
        if fsource['Extended_Source_Name'] == '':
            # case of sources pointlike for Fermi
            # loop over gammalib container and determine closest neighbor
            # initialize at 1000
            dist_min = 1000.
            for source in models:
                dir = get_model_dir(source)
                dist = fdir.dist_deg(dir)
                dist_min = np.minimum(dist, dist_min)
            if dist_min < dist_sigma * fsource['Conf_95_SemiMajor'] / 2:
                # closeby source foud in container, source will not be added
                new = 0
            else:
                # source will be added to container, set spatial model
                spatial = gammalib.GModelSpatialPointSource(fdir)
                newpt += 1
        ######################################### treat extended sources for Fermi ############
        else:
            # retrieve Fermi extended source radius
            ext_fsource = ext_fhl[ext_fhl['Source_Name'] == fsource['Extended_Source_Name']][0]
            fradius = np.double(ext_fsource['Model_SemiMajor'])
            # "corrected" distance, i.e, centre distance - radius of source
            # initialize at 1000
            dist_corr = 1000.
            for source in models:
                dir = get_model_dir(source)
                dist = fdir.dist_deg(dir)
                # get source radius according to model used
                radius = get_model_radius(source)
                # use as radius the max between Fermi and model
                radius = np.maximum(fradius,radius)
                # subtract from distance the max radius
                dist -= radius
                dist_corr = np.minimum(dist,dist_corr)
            if dist_corr < 0.:
                # overlapping source foud in container, source will not be added
                new = 0
            else:
                # source will be added to container, set spatial model
                fradius2 = np.double(ext_fsource['Model_SemiMinor'])
                fpangle = np.double(ext_fsource['Model_PosAng'])
                # retrieve Fermi spatial model to set it in container
                if ext_fsource['Model_Form'] == 'Disk':
                    if fradius2 == fradius:
                        spatial = gammalib.GModelSpatialRadialDisk(fdir,fradius)
                    else:
                        spatial = gammalib.GModelSpatialEllipticalDisk(fdir, fradius, fradius2, fpangle)
                elif ext_fsource['Model_Form'] == '2D Gaussian':
                    if fradius2 == fradius:
                        spatial = gammalib.GModelSpatialRadialGauss(fdir,fradius)
                    else:
                        spatial = gammalib.GModelSpatialEllipticalGauss(fdir, fradius, fradius2, fpangle)
                elif ext_fsource['Model_Form'] == 'Ring':
                    spatial = gammalib.GModelSpatialRadialShell(fdir,fradius, fradius2)
                elif ext_fsource['Model_Form'] == 'Map':
                    print('{} modeled by spatial template, which is not implemented, skip'.format(fsource['Source_Name']))
                    new = 0
                else:
                    print('{} modeled by model type {}, which is not implemented, skip'.format(fsource['Source_Name'],ext_fsource['Model_Form']))
                    new = 0
                if new == 1:
                    newext +=1
        ######################################### spectra #####################################
        if new == 1:
            # spectral model
            eref = gammalib.GEnergy(np.double(fsource['Pivot_Energy']), 'GeV')
            norm = np.double(fsource['Flux_Density'])
            norm *= 1.e-3  # ph GeV-1 -> ph MeV-1
            # use power law model only if signifcance of curvature < 1
            # this avoids extrapolating hard power laws not justified by the data
            if fsource['Signif_Curve'] < 1:
                index = np.double(fsource['PowerLaw_Index'])
                if index < 2.4:
                    # correction for fake pevatrons
                    if fsource['CLASS'] == 'PWN' or fsource['CLASS'] == 'pwn':
                        # dummy model to obtain search radius
                        mod = gammalib.GModelSky(spatial, gammalib.GModelSpectralPlaw())
                        # search radius
                        rad = get_model_radius(mod) + 0.2
                        # set cutoff
                        ecut = get_cutoff(ra, dec, 'PSR', rad_search=rad)
                        ecut_pwn.append(ecut)
                        n_ecut_pwn += 1
                    elif fsource['CLASS'] == 'SNR' or fsource['CLASS'] == 'snr':
                        gname = fsource['ASSOC1']
                        if 'SNR' in gname:
                            pass
                        else:
                            gname = None
                        # compute cutoff
                        # we use default value for particle spectral index because measurements are highly uncertain
                        ecut = get_cutoff(ra, dec, 'SNR', name=gname)
                        ecut_snr.append(ecut)
                        n_ecut_snr += 1
                    elif fsource['CLASS'] == 'bll' or fsource['CLASS'] == 'bcu' or fsource['CLASS'] == 'fsrq':
                        ecut = get_cutoff(ra, dec, 'AGN', z = fsource['Redshift'])
                        ecut_agn.append(ecut)
                        n_ecut_agn += 1
                    else:
                        if fsource['CLASS'] == '' or fsource['CLASS'] == 'unknown':
                            pass
                        else:
                            # set warning if we have hard source of unexpected type
                            msg += 'FHL source {} of type {} has an unxepctedly hard spectrum ' \
                                  'with index {}. We are setting a random artificial cutoff\n'.format(
                                fsource['Source_Name'], fsource['CLASS'], index)
                            print(msg)
                        ecut = get_cutoff(ra, dec, 'UNID')
                        ecut_unid.append(ecut)
                        n_ecut_unid += 1
                    ecut = gammalib.GEnergy(np.double(ecut), 'TeV')
                    spectral = gammalib.GModelSpectralExpPlaw(norm, -index, eref, ecut)
                else:
                    spectral = gammalib.GModelSpectralPlaw(norm, -index, eref)
            else:
                index = np.double(fsource['Spectral_Index'])
                curvature = np.double(fsource['beta'])
                spectral = gammalib.GModelSpectralLogParabola(norm, -index, eref, curvature)
            # assemble model and append to container
            model = gammalib.GModelSky(spatial, spectral)
            model.name(fsource['Source_Name'])
            newmodels.append(model)
            # delete synthetic sources as needed
            if fsource['CLASS'] == 'HMB' or fsource['CLASS'] == 'hmb' or fsource['CLASS'] == 'BIN' or fsource['CLASS'] == 'bin':
                rname, bin_dict, distx, disty, radr, frlog = find_source_to_delete(bin_dict, fdir.l_deg(),
                                                        fdir.b_deg(), get_model_radius(model),
                                                        flux_Crab(model,1.,1000.))
                bin_models.remove(rname)
                n_bin_del += 1
                bin_distx.append(distx)
                bin_disty.append(disty)
                bin_radr.append(radr)
                bin_frlog.append(frlog)
            elif fsource['CLASS'] == 'PWN' or fsource['CLASS'] == 'pwn' or fsource['CLASS'] == 'spp':
                # implement synthetic PWNe here
                pass
            elif fsource['CLASS'] == 'SNR' or fsource['CLASS'] == 'snr':
                # determine if snr is interacting
                assoc = snr_class[snr_class['ASSOC1'] == fsource['ASSOC1']]
                if assoc[0]['is int'] == 'yes':
                    # interacting
                    rname, isnr_dict, distx, disty, radr, frlog = find_source_to_delete(isnr_dict,
                                                                                 fdir.l_deg(),
                                                                                 fdir.b_deg(), get_model_radius(model),
                                                                                 flux_Crab(model, 1.,1000.))
                    isnr_models.remove(rname)
                    n_isnr_del += 1
                    isnr_distx.append(distx)
                    isnr_disty.append(disty)
                    isnr_radr.append(radr)
                    isnr_frlog.append(frlog)
                else:
                    # young
                    rname, snr_dict, distx, disty, radr, frlog = find_source_to_delete(snr_dict,
                                                                                  fdir.l_deg(),
                                                                                  fdir.b_deg(), get_model_radius(model),
                                                                                  flux_Crab(model,1.,1000.))
                    snr_models.remove(rname)
                    n_snr_del += 1
                    snr_distx.append(distx)
                    snr_disty.append(disty)
                    snr_radr.append(radr)
                    snr_frlog.append(frlog)
            else:
                pass
        else:
            # source already present, skip
            pass

    # add new models to original container
    for model in newmodels:
        models.append(model)

    # assemble output in dictionary
    result = { 'models' : models, 'newpt' : newpt, 'newext' : newext,
               'ecut_pwn' : ecut_pwn, 'ecut_snr' : ecut_snr, 'ecut_agn' : ecut_agn,
               'ecut_unid' : ecut_unid, 'n_ecut_pwn' : n_ecut_pwn, 'n_ecut_snr' : n_ecut_snr,
               'n_ecut_agn' : n_ecut_agn, 'n_ecut_unid' : n_ecut_unid, 'msg' : msg,
               'bin_models' : bin_models, 'bin_dict' : bin_dict, 'n_bin_del' : n_bin_del,
               'bin_distx' : bin_distx, 'bin_disty' : bin_disty, 'bin_radr' : bin_radr, 'bin_frlog' : bin_frlog,
               'snr_models': snr_models, 'snr_dict': snr_dict, 'n_snr_del': n_snr_del,
               'snr_distx': snr_distx, 'snr_disty': snr_disty, 'snr_radr': snr_radr, 'snr_frlog': snr_frlog,
               'isnr_models': isnr_models, 'isnr_dict': isnr_dict, 'n_isnr_del': n_isnr_del,
               'isnr_distx': isnr_distx, 'isnr_disty': isnr_disty, 'isnr_radr': isnr_radr, 'isnr_frlog': isnr_frlog
    }

    return result