Ejemplo n.º 1
0
def get_hess_lightcurve(filename='pks-hess-data.csv'):
    """
    Get HESS lightcurve

    Parameters
    ----------
    filename : str, optional
        Light curve data file name

    Returns
    -------
    x, y, y_err : tuple of floats
        Energy, flux and flux error
    """
    # Open data file
    file1 = gammalib.GFilename('$CTAGITROOT/analysis/hess_dr1/%s' % filename)
    file2 = gammalib.GFilename('%s' % filename)
    if file1.exists():
        csv = gammalib.GCsv(file1,'\t')
    else:
        csv = gammalib.GCsv(file2,'\t')

    # Initialise arrays
    x     = []
    y     = []
    y_err = []

    # Loop over data
    for row in range(csv.nrows()):
        x.append(float(csv[row,0])+1.0/(24.0*60.0))
        y.append(float(csv[row,1])*1.0e-9)
        y_err.append((float(csv[row,2])-float(csv[row,1]))*1.0e-9)

    # Return
    return x,y,y_err
Ejemplo n.º 2
0
    def __init__(self, *argv):
        """
        Constructor.

        Parameters
        ----------
        argv : list of str
            List of IRAF command line parameter strings of the form
            ``parameter=3``.
        """
        # Set name and version
        self._name    = 'csobsdef'
        self._version = '1.1.0'

        # Initialise class members
        self._obs    = gammalib.GObservations()
        self._pntdef = gammalib.GCsv()
        self._tmin   = 0.0

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

        # Return
        return
Ejemplo n.º 3
0
def plot_butterfly(filename, ax, color, label):

    csv = gammalib.GCsv(filename)

    # Initialise arrays to be filled
    butterfly_x = []
    butterfly_y = []
    line_x = []
    line_y = []

    # Loop over rows of the file
    nrows = csv.nrows()
    for row in range(nrows):
        # Get conversion coefficient
        conv = csv.real(row, 0) * csv.real(row, 0) * gammalib.MeV2erg

        # Compute upper edge of confidence band
        butterfly_x.append(csv.real(row, 0) / 1.0e6)  # TeV
        butterfly_y.append(csv.real(row, 2) * conv)

        # Set line values
        line_x.append(csv.real(row, 0) / 1.0e6)  # TeV
        line_y.append(csv.real(row, 1) * conv)

    # Loop over the rows backwards to compute the lower edge of the
    # confidence band
    for row in range(nrows):
        index = nrows - 1 - row
        conv = csv.real(index, 0) * csv.real(index, 0) * gammalib.MeV2erg
        butterfly_x.append(csv.real(index, 0) / 1.0e6)
        low_error = max(csv.real(index, 3) * conv, 1e-26)
        butterfly_y.append(low_error)

    ax.plot(line_x, line_y, color=color, ls='-', label=label)
    ax.fill(butterfly_x, butterfly_y, color=color, alpha=0.4)
Ejemplo n.º 4
0
    def _check_runlist(self, filename, runs=1):
        """
        Check run list file

        Parameters
        ----------
        filename : str
            Run list file name
        runs : int, optional
            Expected number of runs in runlist file
        """
        # Open run list file as CSV file
        runlist = gammalib.GCsv(filename)

        # Check dimensions
        self.test_value(runlist.nrows(), runs,
                        'Check for number of runs in runlist file')
        if runs > 0:
            self.test_value(runlist.ncols(), 1,
                            'Check for single column in runlist file')
            self.test_value(runlist[0, 0], '15000',
                            'Check for run ID in runlist file')

        # Return
        return
Ejemplo n.º 5
0
def read_sensitivity(filename):
    """
    Read sensitivity information from CSV file

    Parameters
    ----------
    filename : str
        Name of CSV file

    Returns
    -------
    sensitivity : dict
        Dictionary with sensitivity information
    """
    # Read filename
    csv = gammalib.GCsv(filename, ',')

    # Create dictionnary
    sensitivity = {}
    for column in range(csv.ncols()):
        name = csv[0, column].rstrip('\r')
        values = []
        for row in range(csv.nrows() - 1):
            values.append(float(csv[row + 1, column]))
        sensitivity[name] = values

    # Check where file contains differential or integral sensitivity
    mode = 'Integral'
    if sensitivity.has_key('emax'):
        emax_ref = -1.0
        for value in sensitivity['emax']:
            if emax_ref < 0.0:
                emax_ref = value
            elif emax_ref != value:
                mode = 'Differential'
                break

    # Add mode
    sensitivity['mode'] = mode

    # Add linear energy values
    if mode == 'Differential':
        if sensitivity.has_key('loge'):
            name = 'energy'
            values = []
            for value in sensitivity['loge']:
                values.append(math.pow(10.0, value))
            sensitivity[name] = values
    else:
        if sensitivity.has_key('emin'):
            name = 'energy'
            values = []
            for value in sensitivity['emin']:
                values.append(value)
            sensitivity[name] = values

    # Return
    return sensitivity
Ejemplo n.º 6
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
Ejemplo n.º 7
0
    def _check_pull_file(self, filename):
        """
        Check pull file
        """
        # Open pull file as CSV file
        pulls = gammalib.GCsv(filename)

        # Check dimensions
        self.test_value(pulls.nrows(), 4, 'Check for 4 rows in pull file')

        # Return
        return
Ejemplo n.º 8
0
    def _check_result_file(self, filename):
        """
        Check result file
        """
        # Open result file as CSV file
        results = gammalib.GCsv(filename, ',')

        # Check dimensions
        self.test_value(results.nrows(), 2, 'Check for 2 rows in TS file')
        self.test_value(results.ncols(), 14, 'Check for 14 columns in TS file')

        # Return
        return
Ejemplo n.º 9
0
    def _create_tbounds(self):
        """
        Creates phase bins

        Returns
        -------
        phbins : `[]`
            List of phase bins
        """
        # Initialise Good Time Intervals
        phbins = []

        # Get algorithm to use for defining the time intervals. Possible
        # values are "FILE" or "LIN". This is enforced at
        # parameter file level, hence no checking is needed.
        algorithm = self['phbinalg'].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['phbinfile'].filename()

            # Load  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 phase bins. No header row is expected.
            csv = gammalib.GCsv(filename)
            for i in range(csv.nrows()):
                phmin = csv.real(i, 0)
                phmax = csv.real(i, 1)
                phbins.append([phmin, phmax])

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

            # Get start and stop time and number of time bins
            nbins = self['phbins'].integer()

            # Compute time step and setup the GTIs
            ph_step = 1.0 / float(nbins)
            for i in range(nbins):
                phmin = i * ph_step
                phmax = (i + 1) * ph_step
                phbins.append([phmin, phmax])

        # Return Good Time Intervals
        return phbins
Ejemplo n.º 10
0
    def _check_result_file(self, filename):
        """
        Check result file
        """
        # Open result file as CSV file
        results = gammalib.GCsv(filename)

        # Check dimensions
        self.test_value(results.nrows(), 100,
                        'Check for 100 rows in butterfly file')
        self.test_value(results.ncols(), 4,
                        'Check for 4 columns in butterfly file')

        # Return
        return
Ejemplo n.º 11
0
    def _check_result_file(self, filename, nrows=2):
        """
        Check result file
        """
        # Open result file as CSV file
        results = gammalib.GCsv(filename, ',')

        # Check dimensions
        self.test_value(results.nrows(), nrows,
                        'Check number of rows in sensitivity file')
        self.test_value(results.ncols(), 10,
                        'Check number of columns in sensitivity file')

        # Return
        return
Ejemplo n.º 12
0
    def _check_runlist(self, filename):
        """
        Check run list file.
        """
        # Open run list file as CSV file
        runlist = gammalib.GCsv(filename)

        # Check dimensions
        self.test_value(runlist.ncols(), 1,
                        'Check for single column in runlist file')
        self.test_value(runlist.nrows(), 1,
                        'Check for single row in runlist file')
        self.test_assert(runlist[0,0] == '0',
                         'Check for value "0" in runlist file')
        
        # Return
        return
Ejemplo n.º 13
0
    def __init__(self, *argv):
        """
        Constructor

        Parameters
        ----------
        argv : list of str
            List of IRAF command line parameter strings of the form
            ``parameter=3``.
        """
        # Initialise application by calling the base class constructor
        self._init_cscript(self.__class__.__name__, ctools.__version__, argv)

        # Initialise class members
        self._obs = gammalib.GObservations()
        self._pntdef = gammalib.GCsv()
        self._tmin = 0.0

        # Return
        return
Ejemplo n.º 14
0
    def _check_result_file(self, filename, nrows=3, ncols=9):
        """
        Check result file

        Parameters
        ----------
        filename : str
            Name of result file
        nrows : int, optional
            Required number of rows
        ncols : int, optional
            Required number of columns
        """
        # Open result file as CSV file
        results = gammalib.GCsv(filename, ',')

        # Check dimensions
        self.test_value(results.nrows(), nrows, 'Check rows in TS file')
        self.test_value(results.ncols(), ncols, 'Check columns in TS file')

        # Return
        return
Ejemplo n.º 15
0
def plot_butterfly(filename, plotfile):
    """
    Plot butterfly diagram

    Parameters
    ----------
    filename : str
        Butterfly CSV file
    plotfile : str
        Plot filename
    """
    # Read butterfly file
    csv = gammalib.GCsv(filename)

    # Initialise arrays to be filled
    butterfly_x = []
    butterfly_y = []
    line_x = []
    line_y = []

    # Loop over rows of the file
    nrows = csv.nrows()
    for row in range(nrows):

        # Get conversion coefficient
        conv = csv.real(row, 0) * csv.real(row, 0) * gammalib.MeV2erg

        # Compute upper edge of confidence band
        butterfly_x.append(csv.real(row, 0) / 1.0e6)  # TeV
        butterfly_y.append(csv.real(row, 2) * conv)

        # Set line values
        line_x.append(csv.real(row, 0) / 1.0e6)  # TeV
        line_y.append(csv.real(row, 1) * conv)

    # Loop over the rows backwards to compute the lower edge of the
    # confidence band
    for row in range(nrows):
        index = nrows - 1 - row
        conv = csv.real(index, 0) * csv.real(index, 0) * gammalib.MeV2erg
        butterfly_x.append(csv.real(index, 0) / 1.0e6)
        low_error = max(csv.real(index, 3) * conv, 1e-26)
        butterfly_y.append(low_error)

    # Plot the butterfly and spectral line
    plt.figure()
    plt.loglog()
    plt.grid()
    plt.plot(line_x, line_y, color='black', ls='-')
    plt.fill(butterfly_x, butterfly_y, color='green', alpha=0.5)
    plt.xlabel('Energy (TeV)')
    plt.ylabel(r'E$^2$ $\times$ dN/dE (erg cm$^{-2}$ s$^{-1}$)')

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

    # Return
    return
Ejemplo n.º 16
0
    def _test_python(self):
        """
        Test csphasecrv from Python
        """
        # Set-up unbinned csphasecrv
        pcrv = cscripts.csphasecrv()
        pcrv['inobs'] = self._phased_events
        pcrv['inmodel'] = self._model
        pcrv['srcname'] = 'Crab'
        pcrv['caldb'] = self._caldb
        pcrv['irf'] = self._irf
        pcrv['phbinalg'] = 'LIN'
        pcrv['phbins'] = 2
        pcrv['method'] = '3D'
        pcrv['enumbins'] = 0
        pcrv['emin'] = 1.0
        pcrv['emax'] = 100.0
        pcrv['outfile'] = 'csphasecrv_py1.fits'
        pcrv['logfile'] = 'csphasecrv_py1.log'
        pcrv['chatter'] = 2
        pcrv['publish'] = True

        # Run csphasecrv script and save phase curve
        pcrv.logFileOpen()  # Make sure we get a log file
        pcrv.run()
        pcrv.save()

        # Check phase curve
        self._check_phase_curve('csphasecrv_py1.fits', 2)

        # Now use FILE as time bin algorithm. For this we need first to
        # create an ASCII file. We use now 2 phase bins. The ASCII file
        # is saved into the file "csphasecrv_py2.dat".
        csv = gammalib.GCsv(2, 2)
        phmin = 0.0
        phdelta = 1.0 / float(csv.nrows())
        for i in range(csv.nrows()):
            csv[i, 0] = '%.5f' % (phmin + i * phdelta)
            csv[i, 1] = '%.5f' % (phmin + (i + 1) * phdelta)
        csv.save('csphasecrv_py2.dat', ' ', True)

        # Set-up unbinned csphasecrv
        pcrv = cscripts.csphasecrv()
        pcrv['inobs'] = self._phased_events
        pcrv['inmodel'] = self._model
        pcrv['srcname'] = 'Crab'
        pcrv['caldb'] = self._caldb
        pcrv['irf'] = self._irf
        pcrv['phbinalg'] = 'FILE'
        pcrv['phbinfile'] = 'csphasecrv_py2.dat'
        pcrv['method'] = '3D'
        pcrv['enumbins'] = 0
        pcrv['emin'] = 1.0
        pcrv['emax'] = 100.0
        pcrv['outfile'] = 'csphasecrv_py2.fits'
        pcrv['logfile'] = 'csphasecrv_py2.log'
        pcrv['chatter'] = 3

        # Execute csphasecrv script
        pcrv.logFileOpen()  # Make sure we get a log file
        pcrv.execute()

        # Check phase curve
        self._check_phase_curve('csphasecrv_py2.fits', csv.nrows())

        # Now we setup an observation container on input. We attached the
        # model to the observation container so that csphasecrv should
        # no longer query for the parameter.
        cta = gammalib.GCTAObservation(self._phased_events)
        obs = gammalib.GObservations()
        obs.append(cta)
        obs.models(self._model)

        # Set-up unbinned csphasecrv from observation container. Now use
        # the GTI algorithm so that we test all timing algorithms.
        pcrv = cscripts.csphasecrv(obs)
        pcrv['srcname'] = 'Crab'
        pcrv['caldb'] = self._caldb
        pcrv['irf'] = self._irf
        pcrv['phbinalg'] = 'LIN'
        pcrv['phbins'] = 2
        pcrv['method'] = '3D'
        pcrv['enumbins'] = 0
        pcrv['emin'] = 1.0
        pcrv['emax'] = 100.0
        pcrv['outfile'] = 'csphasecrv_py3.fits'
        pcrv['logfile'] = 'csphasecrv_py3.log'
        pcrv['chatter'] = 4

        # Execute csphasecrv script
        pcrv.logFileOpen()  # Make sure we get a log file
        pcrv.execute()

        # Check phase curve
        self._check_phase_curve('csphasecrv_py3.fits', 2)

        # Binned csphasecrv
        pcrv = cscripts.csphasecrv()
        pcrv['inobs'] = self._phased_events
        pcrv['inmodel'] = self._model
        pcrv['srcname'] = 'Crab'
        pcrv['caldb'] = self._caldb
        pcrv['irf'] = self._irf
        pcrv['phbinalg'] = 'LIN'
        pcrv['phbins'] = 2
        pcrv['method'] = '3D'
        pcrv['emin'] = 1.0
        pcrv['emax'] = 100.0
        pcrv['enumbins'] = 2
        pcrv['coordsys'] = 'CEL'
        pcrv['proj'] = 'TAN'
        pcrv['xref'] = 83.63
        pcrv['yref'] = 22.01
        pcrv['nxpix'] = 10
        pcrv['nypix'] = 10
        pcrv['binsz'] = 0.04
        pcrv['outfile'] = 'csphasecrv_py4.fits'
        pcrv['logfile'] = 'csphasecrv_py4.log'
        pcrv['chatter'] = 4

        # Execute csphasecrv script
        pcrv.logFileOpen()  # Make sure we get a log file
        pcrv.execute()

        # Check phase curve
        self._check_phase_curve('csphasecrv_py4.fits', 2)

        # On/Off csphasecrv
        pcrv = cscripts.csphasecrv()
        pcrv['inobs'] = self._offaxis_events
        pcrv['inmodel'] = self._model_onoff
        pcrv['srcname'] = 'Crab'
        pcrv['caldb'] = self._caldb
        pcrv['irf'] = self._irf
        pcrv['phbinalg'] = 'LIN'
        pcrv['phbins'] = 2
        pcrv['method'] = 'ONOFF'
        pcrv['statistic'] = 'WSTAT'
        pcrv['emin'] = 1.0
        pcrv['emax'] = 100.0
        pcrv['enumbins'] = 2
        pcrv['coordsys'] = 'CEL'
        pcrv['xref'] = 83.63
        pcrv['yref'] = 22.01
        pcrv['rad'] = 0.2
        pcrv['etruemin'] = 1.0
        pcrv['etruemax'] = 100.0
        pcrv['etruebins'] = 5
        pcrv['outfile'] = 'csphasecrv_py5.fits'
        pcrv['logfile'] = 'csphasecrv_py5.log'
        pcrv['chatter'] = 4

        # Execute csphasecrv script
        pcrv.logFileOpen()  # Make sure we get a log file
        pcrv.execute()

        # Check phase curve
        self._check_phase_curve('csphasecrv_py5.fits', 2)

        # Set-up csphasecrv without multiprocessing
        pcrv = cscripts.csphasecrv()
        pcrv['inobs'] = self._phased_events
        pcrv['inmodel'] = self._model
        pcrv['srcname'] = 'Crab'
        pcrv['caldb'] = self._caldb
        pcrv['irf'] = self._irf
        pcrv['phbinalg'] = 'LIN'
        pcrv['phbins'] = 2
        pcrv['method'] = '3D'
        pcrv['enumbins'] = 0
        pcrv['emin'] = 1.0
        pcrv['emax'] = 100.0
        pcrv['outfile'] = 'csphasecrv_py6.fits'
        pcrv['logfile'] = 'csphasecrv_py6.log'
        pcrv['chatter'] = 2
        pcrv['publish'] = True
        pcrv['nthreads'] = 1

        # Run csphasecrv script and save phase curve
        pcrv.logFileOpen()  # Make sure we get a log file
        pcrv.run()
        pcrv.save()

        # Check phase curve
        self._check_phase_curve('csphasecrv_py6.fits', 2)

        # Return
        return
Ejemplo n.º 17
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
Ejemplo n.º 18
0
def plot_spectrum_butterfly(specfile, butterfile, fmt='o', color='red'):
    """
    Plot sensitivity data

    Parameters
    ----------
    specfile : str
        Name of spectrum FITS file
    butterfile : str
        Name of butterfly FITS file
    fmt : str
        Symbol format
    color : str
        Symbol color
    """
    # Read spectrum file
    fits = gammalib.GFits(specfile)
    table = fits.table(1)
    c_energy = table['Energy']
    c_ed = table['ed_Energy']
    c_eu = table['eu_Energy']
    c_flux = table['Flux']
    c_eflux = table['e_Flux']
    c_ts = table['TS']
    c_upper = table['UpperLimit']

    # Read butterfly file
    csv = gammalib.GCsv(butterfile)

    # Initialise arrays to be filled
    energies = []
    flux = []
    ed_engs = []
    eu_engs = []
    e_flux = []
    ul_energies = []
    ul_ed_engs = []
    ul_eu_engs = []
    ul_flux = []
    butterfly_x = []
    butterfly_y = []
    line_x = []
    line_y = []

    # Loop over rows of the file
    nrows = table.nrows()
    for row in range(nrows):

        # Get Test Statistic, flux and flux error
        ts = c_ts.real(row)
        flx = c_flux.real(row)
        e_flx = c_eflux.real(row)

        # If Test Statistic is larger than 9 and flux error is smaller than
        # flux then append flux plots ...
        if ts > 9.0 and e_flx < flx:
            energies.append(c_energy.real(row))
            flux.append(c_flux.real(row))
            ed_engs.append(c_ed.real(row))
            eu_engs.append(c_eu.real(row))
            e_flux.append(c_eflux.real(row))

        # ... otherwise append upper limit
        else:
            ul_energies.append(c_energy.real(row))
            ul_flux.append(c_upper.real(row))
            ul_ed_engs.append(c_ed.real(row))
            ul_eu_engs.append(c_eu.real(row))

    # Set upper limit errors
    yerr = [0.6 * x for x in ul_flux]

    # Loop over rows of the file
    nrows = csv.nrows()
    for row in range(nrows):

        # Compute upper edge of confidence band
        butterfly_x.append(csv.real(row, 0) / 1.0e6)  # TeV
        butterfly_y.append(
            csv.real(row, 2) * csv.real(row, 0) * csv.real(row, 0) *
            gammalib.MeV2erg)

        # Set line values
        line_x.append(csv.real(row, 0) / 1.0e6)  # TeV
        line_y.append(
            csv.real(row, 1) * csv.real(row, 0) * csv.real(row, 0) *
            gammalib.MeV2erg)

    # Loop over the rows backwards to compute the lower edge of the
    # confidence band
    for row in range(nrows):
        index = nrows - 1 - row
        butterfly_x.append(csv.real(index, 0) / 1.0e6)
        low_error = max(
            csv.real(index, 3) * csv.real(index, 0) * csv.real(index, 0) *
            gammalib.MeV2erg, 1e-26)
        butterfly_y.append(low_error)

    # Plot the spectrum
    plt.errorbar(energies,
                 flux,
                 yerr=e_flux,
                 xerr=[ed_engs, eu_engs],
                 fmt=fmt,
                 color=color,
                 markeredgecolor=color)
    plt.errorbar(ul_energies,
                 ul_flux,
                 xerr=[ul_ed_engs, ul_eu_engs],
                 yerr=yerr,
                 uplims=True,
                 fmt=fmt,
                 color=color,
                 markeredgecolor=color)

    # Plot the butterfly
    plt.plot(line_x, line_y, color='black', ls='-')
    plt.fill(butterfly_x, butterfly_y, color='green', alpha=0.5)

    # Return
    return
Ejemplo n.º 19
0
    def _test_python(self):
        """
        Test csobsdef from Python
        """
        # Set-up csobsdef
        obsdef = cscripts.csobsdef()
        obsdef['inpnt'] = self._pntdef
        obsdef['outobs'] = 'csobsdef_py1.xml'
        obsdef['caldb'] = self._caldb
        obsdef['irf'] = self._irf
        obsdef['emin'] = 0.1
        obsdef['emax'] = 100.0
        obsdef['duration'] = 1800.0
        obsdef['rad'] = 5.0
        obsdef['logfile'] = 'csobsdef_py1.log'
        obsdef['chatter'] = 2

        # Run csobsdef script and save XML file
        obsdef.logFileOpen()  # Make sure we get a log file
        obsdef.run()
        obsdef.save()

        # Check model file
        self._check_obsdef_file('csobsdef_py1.xml')

        # Set-up csobsdef
        obsdef = cscripts.csobsdef()
        obsdef['inpnt'] = self._pntdef
        obsdef['outobs'] = 'csobsdef_py2.xml'
        obsdef['caldb'] = self._caldb
        obsdef['irf'] = self._irf
        obsdef['emin'] = 0.1
        obsdef['emax'] = 100.0
        obsdef['duration'] = 1800.0
        obsdef['rad'] = 5.0
        obsdef['logfile'] = 'csobsdef_py2.log'
        obsdef['chatter'] = 3

        # Execute csobsdef script
        obsdef.execute()

        # Check model file
        self._check_obsdef_file('csobsdef_py2.xml')

        # Load CSV table
        csv = gammalib.GCsv(self._pntdef, ',')

        # Set-up csobsdef
        obsdef = cscripts.csobsdef()
        obsdef.pntdef(csv)
        obsdef['outobs'] = 'csobsdef_py3.xml'
        obsdef['caldb'] = self._caldb
        obsdef['irf'] = self._irf
        obsdef['emin'] = 0.1
        obsdef['emax'] = 100.0
        obsdef['duration'] = 1800.0
        obsdef['rad'] = 5.0
        obsdef['logfile'] = 'csobsdef_py3.log'
        obsdef['chatter'] = 4

        # Execute csobsdef script
        obsdef.execute()

        # Check model file
        self._check_obsdef_file('csobsdef_py3.xml')

        # Return
        return
Ejemplo n.º 20
0
def showSpectrum(cfg, spectrum, show_butterfly=True):
    """
    Generate spectrum (points + butterfly)
    """

    outputdir = cfg.getValue('general', 'outputdir')

    if has_matplotlib == False:
        Utilities.warning('No matplotlib module ==> EXIT!!!')
        return

    #################################################################
    ### Taken from $CTOOLS/share/examples/python/make_spectrum.py ###
    #################################################################
    # Read spectrum file
    table = spectrum.table(1)
    c_energy = table["Energy"]
    c_ed = table["ed_Energy"]
    c_eu = table["eu_Energy"]
    c_flux = table["Flux"]
    c_eflux = table["e_Flux"]
    c_ts = table["TS"]
    c_upper = table["UpperLimit"]

    # Initialise arrays to be filled
    energies = []
    flux = []
    ed_engs = []
    eu_engs = []
    e_flux = []
    ul_energies = []
    ul_ed_engs = []
    ul_eu_engs = []
    ul_flux = []

    # Loop over rows of the file
    nrows = table.nrows()
    for row in range(nrows):

        # Get TS
        ts = c_ts.real(row)
        flx = c_flux.real(row)
        e_flx = c_eflux.real(row)

        # Switch
        if ts > 9.0 and e_flx < flx:

            # Add information
            energies.append(c_energy.real(row))
            flux.append(c_flux.real(row))
            ed_engs.append(c_ed.real(row))
            eu_engs.append(c_eu.real(row))
            e_flux.append(c_eflux.real(row))

        #
        else:

            # Add information
            ul_energies.append(c_energy.real(row))
            ul_flux.append(c_upper.real(row))
            ul_ed_engs.append(c_ed.real(row))
            ul_eu_engs.append(c_eu.real(row))

    # Create figure
    plt.figure()
    plt.title("Crab spectrum")

    # Plot the spectrum
    plt.loglog()
    plt.grid()
    plt.errorbar(energies,
                 flux,
                 yerr=e_flux,
                 xerr=[ed_engs, eu_engs],
                 fmt='ro')
    if len(ul_energies) > 0:
        plt.errorbar(ul_energies,
                     ul_flux,
                     xerr=[ul_ed_engs, ul_eu_engs],
                     yerr=1.0e-11,
                     uplims=True,
                     fmt='ro')
    plt.xlabel("Energy (TeV)")
    plt.ylabel(r"dN/dE (erg cm$^{-2}$ s$^{-1}$)")

    if show_butterfly is True:
        ##################################################################
        ### Taken from $CTOOLS/share/examples/python/show_butterfly.py ###
        ##################################################################
        # Read given butterfly file
        filename = outputdir + '/' + cfg.getValue('ctbutterfly', 'output')
        csv = gammalib.GCsv(filename)

        # Initialise arrays to be filled
        butterfly_x = []
        butterfly_y = []
        line_x = []
        line_y = []

        # Loop over rows of the file
        nrows = csv.nrows()
        for row in range(nrows):

            # Compute upper edge of confidence band
            butterfly_x.append(csv.real(row, 0) * 1.e-6)  # JLK MeV -> TeV
            # butterfly_y.append(csv.real(row,2)*1.e6) ## JLK MeV -> TeV
            scale = csv.real(row, 0) * csv.real(row, 0) * 1.e-6 * 1.6
            # JLK MeV -> TeV -> erg
            butterfly_y.append(csv.real(row, 2) * scale)

            # Set line values
            line_x.append(csv.real(row, 0) * 1.e-6)  # JLK MeV -> TeV
            line_y.append(csv.real(row, 1) * scale)  # JLK MeV -> TeV -> erg

        # Loop over the rows backwards to compute the lower edge
        # of the confidence band
        for row in range(nrows):

            index = nrows - 1 - row
            butterfly_x.append(csv.real(index, 0) * 1.e-6)  # JLK MeV -> TeV
            scale = csv.real(index, 0) * csv.real(index, 0) * 1.e-6 * 1.6
            low_error = csv.real(index, 3) * scale  # JLK MeV -> TeV -> erg

            if low_error < 1e-26:
                low_error = 1e-26
            butterfly_y.append(low_error)

        plt.fill(butterfly_x, butterfly_y, color='green', alpha=0.5)
        plt.plot(line_x, line_y, color='black', ls='-')

    plt.autoscale(tight=True)

    outputdir = cfg.getValue('general', 'outputdir')
    plt.savefig(outputdir + '/' + cfg.getValue('plots', 'spec_outfile'))
Ejemplo n.º 21
0
def plot_spectrum(specfile, butterfile1, butterfile2, ax, fmt='ro'):
    """
    Plot sensitivity data

    Parameters
    ----------
    specfile : str
        Name of spectrum FITS file
    butterfile1 : str
        Name of first butterfly text file
    butterfile2 : str
        Name of second butterfly text file
    ax : pyplot
        Subplot
    fmt : str
        Format string
    """
    # Read spectrum file
    fits = gammalib.GFits(specfile)
    table = fits.table(1)
    c_energy = table['Energy']
    c_ed = table['ed_Energy']
    c_eu = table['eu_Energy']
    c_flux = table['Flux']
    c_eflux = table['e_Flux']
    c_ts = table['TS']
    c_upper = table['UpperLimit']

    # Read butterfly files
    csv1 = gammalib.GCsv(butterfile1)
    csv2 = gammalib.GCsv(butterfile2)

    # Initialise arrays to be filled
    energies = []
    flux = []
    ed_engs = []
    eu_engs = []
    e_flux = []
    ul_energies = []
    ul_ed_engs = []
    ul_eu_engs = []
    ul_flux = []
    butterfly1_x = []
    butterfly1_y = []
    butterfly2_x = []
    butterfly2_y = []
    line1_x = []
    line1_y = []
    line2_x = []
    line2_y = []

    # Loop over rows of the file
    nrows = table.nrows()
    for row in range(nrows):

        # Get Test Statistic, flux and flux error
        ts = c_ts.real(row)
        flx = c_flux.real(row)
        e_flx = c_eflux.real(row)

        # If Test Statistic is larger than 9 and flux error is smaller than
        # flux then append flux plots ...
        if ts > -99999.0 and e_flx < flx and e_flx > 0.0:
            energies.append(c_energy.real(row))
            flux.append(c_flux.real(row))
            ed_engs.append(c_ed.real(row))
            eu_engs.append(c_eu.real(row))
            e_flux.append(c_eflux.real(row))

        # ... otherwise append upper limit
        else:
            ul_energies.append(c_energy.real(row))
            ul_flux.append(c_upper.real(row))
            ul_ed_engs.append(c_ed.real(row))
            ul_eu_engs.append(c_eu.real(row))

    # Set upper limit errors
    yerr = [0.6 * x for x in ul_flux]

    # Loop over rows of the first butterfly file
    nrows = csv1.nrows()
    for row in range(nrows):

        # Limit values to positive
        value = csv1.real(row, 2)
        if value < 1e-40:
            value = 1e-40

        # Compute upper edge of confidence band
        butterfly1_x.append(csv1.real(row, 0) / 1.0e6)  # TeV
        butterfly1_y.append(value * csv1.real(row, 0) * csv1.real(row, 0) *
                            gammalib.MeV2erg)

        # Set line values
        line1_x.append(csv1.real(row, 0) / 1.0e6)  # TeV
        line1_y.append(
            csv1.real(row, 1) * csv1.real(row, 0) * csv1.real(row, 0) *
            gammalib.MeV2erg)

    # Loop over the rows backwards to compute the lower edge of the
    # confidence band
    for row in range(nrows):
        index = nrows - 1 - row
        butterfly1_x.append(csv1.real(index, 0) / 1.0e6)
        low_error = max(
            csv1.real(index, 3) * csv1.real(index, 0) * csv1.real(index, 0) *
            gammalib.MeV2erg, 1e-26)
        butterfly1_y.append(low_error)

    # Loop over rows of the second butterfly file
    nrows = csv2.nrows()
    for row in range(nrows):

        # Limit values to positive
        value = csv2.real(row, 2)
        if value < 1e-40:
            value = 1e-40

        # Compute upper edge of confidence band
        butterfly2_x.append(csv2.real(row, 0) / 1.0e6)  # TeV
        butterfly2_y.append(value * csv2.real(row, 0) * csv2.real(row, 0) *
                            gammalib.MeV2erg)

        # Set line values
        line2_x.append(csv2.real(row, 0) / 1.0e6)  # TeV
        line2_y.append(
            csv2.real(row, 1) * csv2.real(row, 0) * csv2.real(row, 0) *
            gammalib.MeV2erg)

    # Loop over the rows backwards to compute the lower edge of the
    # confidence band
    for row in range(nrows):
        index = nrows - 1 - row
        butterfly2_x.append(csv2.real(index, 0) / 1.0e6)
        low_error = max(
            csv2.real(index, 3) * csv2.real(index, 0) * csv2.real(index, 0) *
            gammalib.MeV2erg, 1e-26)
        butterfly2_y.append(low_error)

    # Plot the spectrum
    ax.errorbar(energies,
                flux,
                yerr=e_flux,
                xerr=[ed_engs, eu_engs],
                fmt=fmt,
                label='ctools')
    ax.errorbar(ul_energies,
                ul_flux,
                xerr=[ul_ed_engs, ul_eu_engs],
                yerr=yerr,
                uplims=True,
                fmt=fmt,
                label='_nolegend_')

    # Plot MSH 15-52 SED
    engs, ebins, flux, e_flux = msh_sed()
    ax.errorbar(engs,
                flux,
                yerr=e_flux,
                fmt='bo',
                label='Aharonian et al. (2005)')

    # Plot MSH 15-52 spectrum from Dubois (2009)
    dubois_x = [i * 0.1 + 0.2 for i in range(1000)]
    dubois_y = []
    for x in dubois_x:
        y = 7.13e-12 * math.pow(x, -2.06) * math.exp(-x / 11.9)
        dubois_y.append(y * x * x * gammalib.MeV2erg * 1.0e6)
    ax.plot(dubois_x, dubois_y, color='blue', ls='-', label='Dubois (2009)')

    # Plot MSH 15-52 spectrum from HGPS
    #hgps_x = [i*0.1+0.2 for i in range(1000)]
    #hgps_y = []
    #for x in hgps_x:
    #    y = 6.859766e-12 * math.pow(x, -2.0507) * math.exp(-x/19.2)
    #    hgps_y.append(y*x*x*gammalib.MeV2erg*1.0e6)
    #ax.plot(hgps_x, hgps_y, color='blue', ls='-', label='HGPS')

    # Plot the first butterfly
    ax.plot(line1_x, line1_y, color='red', ls='--')
    ax.fill(butterfly1_x, butterfly1_y, color='lightsalmon', alpha=0.5)

    # Plot the second butterfly
    ax.plot(line2_x, line2_y, color='red', ls='-')
    ax.fill(butterfly2_x, butterfly2_y, color='salmon', alpha=0.5)

    # Resort labels
    handles, labels = ax.get_legend_handles_labels()
    order = [1, 2, 0]

    # Add legend
    ax.legend([handles[idx] for idx in order], [labels[idx] for idx in order])

    # Return
    return
Ejemplo n.º 22
0
    def _test_python(self):
        """
        Test cslightcrv from Python
        """
        # Set-up unbinned cslightcrv
        lcrv = cscripts.cslightcrv()
        lcrv['inobs'] = self._events
        lcrv['inmodel'] = self._model
        lcrv['srcname'] = 'Crab'
        lcrv['caldb'] = self._caldb
        lcrv['irf'] = self._irf
        lcrv['tbinalg'] = 'LIN'
        lcrv['tmin'] = 51544.50
        lcrv['tmax'] = 51544.53
        lcrv['tbins'] = 3
        lcrv['enumbins'] = 0
        lcrv['emin'] = 0.1
        lcrv['emax'] = 100.0
        lcrv['outfile'] = 'cslightcrv_py1.fits'
        lcrv['logfile'] = 'cslightcrv_py1.log'
        lcrv['chatter'] = 2

        # Run cslightcrv script and save light curve
        lcrv.logFileOpen()  # Make sure we get a log file
        lcrv.run()
        lcrv.save()

        # Check light curve
        self._check_light_curve('cslightcrv_py1.fits', 3)

        # Now use FILE as time bin algorithm. For this we need first to
        # create an ASCII file. We use now 6 time bins. The ASCII file
        # is saved into the file "lightcurve_py2.dat".
        csv = gammalib.GCsv(2, 2)
        tmin = 51544.50
        tdelta = 0.01
        for i in range(csv.nrows()):
            csv[i, 0] = '%.5f' % (tmin + i * tdelta)
            csv[i, 1] = '%.5f' % (tmin + (i + 1) * tdelta)
        csv.save('cslightcrv_py2.dat', ' ', True)

        # Set-up unbinned cslightcrv
        lcrv = cscripts.cslightcrv()
        lcrv['inobs'] = self._events
        lcrv['inmodel'] = self._model
        lcrv['srcname'] = 'Crab'
        lcrv['caldb'] = self._caldb
        lcrv['irf'] = self._irf
        lcrv['tbinalg'] = 'FILE'
        lcrv['tbinfile'] = 'cslightcrv_py2.dat'
        lcrv['enumbins'] = 0
        lcrv['emin'] = 0.1
        lcrv['emax'] = 100.0
        lcrv['fix_bkg'] = True
        lcrv['outfile'] = 'cslightcrv_py2.fits'
        lcrv['logfile'] = 'cslightcrv_py2.log'
        lcrv['chatter'] = 3

        # Execute cslightcrv script
        lcrv.execute()

        # Check light curve
        self._check_light_curve('cslightcrv_py2.fits', 2)

        # Now we setup an observation container on input. We attached the
        # model to the observation container so that cslightcrv should
        # no longer query for the parameter.
        cta = gammalib.GCTAObservation(self._events)
        obs = gammalib.GObservations()
        obs.append(cta)
        obs.models(self._model)

        # Set-up unbinned cslightcrv from observation container. Now use
        # the GTI algorithm so that we test all timing algorithms.
        lcrv = cscripts.cslightcrv(obs)
        lcrv['srcname'] = 'Crab'
        lcrv['caldb'] = self._caldb
        lcrv['irf'] = self._irf
        lcrv['tbinalg'] = 'GTI'
        lcrv['enumbins'] = 0
        lcrv['emin'] = 0.1
        lcrv['emax'] = 100.0
        lcrv['outfile'] = 'cslightcrv_py3.fits'
        lcrv['logfile'] = 'cslightcrv_py3.log'
        lcrv['chatter'] = 4

        # Execute cslightcrv script
        lcrv.execute()

        # Check light curve
        self._check_light_curve('cslightcrv_py3.fits', 1)

        # Finally we set-up a binned cslightcrv
        lcrv = cscripts.cslightcrv()
        lcrv['inobs'] = self._events
        lcrv['inmodel'] = self._model
        lcrv['srcname'] = 'Crab'
        lcrv['caldb'] = self._caldb
        lcrv['irf'] = self._irf
        lcrv['tbinalg'] = 'LIN'
        lcrv['tmin'] = 51544.50
        lcrv['tmax'] = 51544.53
        lcrv['tbins'] = 2
        lcrv['emin'] = 0.1
        lcrv['emax'] = 100.0
        lcrv['enumbins'] = 10
        lcrv['coordsys'] = 'CEL'
        lcrv['proj'] = 'TAN'
        lcrv['xref'] = 83.63
        lcrv['yref'] = 22.01
        lcrv['nxpix'] = 20
        lcrv['nypix'] = 20
        lcrv['binsz'] = 0.02
        lcrv['outfile'] = 'cslightcrv_py4.fits'
        lcrv['logfile'] = 'cslightcrv_py4.log'
        lcrv['chatter'] = 4

        # Execute cslightcrv script
        lcrv.execute()

        # Check light curve
        self._check_light_curve('cslightcrv_py4.fits', 2)

        # Return
        return
Ejemplo n.º 23
0
# Script entry #
# ============ #
if __name__ == '__main__':

    # Check for given butterfly file
    if len(sys.argv) < 2:
        sys.exit('Usage: show_butterfly.py butterfly.txt [file]')

    # Check if plotting in file is requested
    plotfile = ''
    if len(sys.argv) == 3:
        plotfile = sys.argv[2]

    # Read given butterfly file
    filename = sys.argv[1]
    csv = gammalib.GCsv(filename)

    # Initialise arrays to be filled
    butterfly_x = []
    butterfly_y = []
    line_x = []
    line_y = []

    # Loop over rows of the file
    nrows = csv.nrows()
    for row in range(nrows):

        # Compute upper edge of confidence band
        butterfly_x.append(csv.real(row, 0))
        butterfly_y.append(csv.real(row, 2))
def plot_spectrum(specfile, butterfile, ax, fmt='ro'):
    """
    Plot sensitivity data

    Parameters
    ----------
    specfile : str
        Name of spectrum FITS file
    butterfile : str
        Name of butterfly FITS file
    ax : plt
        Frame
    fmt : str, optional
        Format for ctools points
    """
    # Read spectrum file    
    fits     = gammalib.GFits(specfile)
    table    = fits.table(1)
    c_energy = table['Energy']
    c_ed     = table['ed_Energy']
    c_eu     = table['eu_Energy']
    c_flux   = table['Flux']
    c_eflux  = table['e_Flux']
    c_ts     = table['TS']
    c_upper  = table['UpperLimit']

    # Read butterfly file
    csv = gammalib.GCsv(butterfile)

    # Initialise arrays to be filled
    energies    = []
    flux        = []
    ed_engs     = []
    eu_engs     = []
    e_flux      = []
    ul_energies = []
    ul_ed_engs  = []
    ul_eu_engs  = []
    ul_flux     = []
    butterfly_x = []
    butterfly_y = []
    line_x      = []
    line_y      = []

    # Loop over rows of the file
    nrows = table.nrows()
    for row in range(nrows):

        # Get Test Statistic, flux and flux error
        ts    = c_ts.real(row)
        flx   = c_flux.real(row)
        e_flx = c_eflux.real(row)

        # If Test Statistic is larger than 9 and flux error is smaller than
        # flux then append flux plots ...
        if ts > -99999.0 and e_flx < flx and e_flx > 0.0:
            energies.append(c_energy.real(row))
            flux.append(c_flux.real(row))
            ed_engs.append(c_ed.real(row))
            eu_engs.append(c_eu.real(row))
            e_flux.append(c_eflux.real(row))

        # ... otherwise append upper limit
        else:
            ul_energies.append(c_energy.real(row))
            ul_flux.append(c_upper.real(row))
            ul_ed_engs.append(c_ed.real(row))
            ul_eu_engs.append(c_eu.real(row))

    # Set upper limit errors
    yerr = [0.6 * x for x in ul_flux]

    # Loop over rows of the file
    nrows = csv.nrows()
    for row in range(nrows):

        # Limit values to positive
        value = csv.real(row,2)
        if value < 1e-40:
            value = 1e-40

        # Compute upper edge of confidence band
        butterfly_x.append(csv.real(row,0)/1.0e6) # TeV
        butterfly_y.append(value*csv.real(row,0)*csv.real(row,0)*gammalib.MeV2erg)

        # Set line values
        line_x.append(csv.real(row,0)/1.0e6) # TeV
        line_y.append(csv.real(row,1)*csv.real(row,0)*csv.real(row,0)*gammalib.MeV2erg)

    # Loop over the rows backwards to compute the lower edge of the
    # confidence band
    for row in range(nrows):
        index = nrows - 1 - row
        butterfly_x.append(csv.real(index,0)/1.0e6)
        low_error = max(csv.real(index,3)*csv.real(index,0)*csv.real(index,0)*gammalib.MeV2erg, 1e-26)
        butterfly_y.append(low_error)

    # Plot PKS 2155-304 SED
    engs, pks, e_pks = pks_sed()
    ax.errorbar(engs, pks, yerr=e_pks, fmt='bo', label='Aharonian et al. (2009)')
    ax.errorbar([6.90492], [9.76439e-12], yerr=0.6*9.76439e-12, uplims=True,
                fmt='bo', label='_nolegend_')

    # Plot the spectrum
    ax.errorbar(energies, flux, yerr=e_flux, xerr=[ed_engs, eu_engs],
                 fmt=fmt, label='ctools')
    ax.errorbar(ul_energies, ul_flux, xerr=[ul_ed_engs, ul_eu_engs],
                yerr=yerr, uplims=True, fmt=fmt, label='_nolegend_')

    # Plot the butterfly
    ax.plot(line_x, line_y, color='red',ls='-')
    ax.fill(butterfly_x, butterfly_y, color='salmon', alpha=0.5)

    # Resort labels
    handles, labels = ax.get_legend_handles_labels()
    order           = [1,0]

    # Add legend
    ax.legend([handles[idx] for idx in order],[labels[idx] for idx in order], loc='upper right')

    # Return
    return
Ejemplo n.º 25
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
Ejemplo n.º 26
0
    def run(self):
        """
        Run the script

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

        # Get parameters
        self._get_parameters()

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

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

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

        # Clear observation container
        self._obs.clear()

        # Initialise observation identifier counter
        identifier = 1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            # Append observation
            self._obs.append(obs)

        # Return
        return
Ejemplo n.º 27
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
Ejemplo n.º 28
0
    def _test_python(self):
        """
        Test cslightcrv from Python
        """
        # Set-up unbinned cslightcrv
        lcrv = cscripts.cslightcrv()
        lcrv['inobs'] = self._events
        lcrv['inmodel'] = self._model
        lcrv['srcname'] = 'Crab'
        lcrv['caldb'] = self._caldb
        lcrv['irf'] = self._irf
        lcrv['tbinalg'] = 'LIN'
        lcrv['tmin'] = '2020-01-01T00:00:00'
        lcrv['tmax'] = '2020-01-01T00:05:00'
        lcrv['tbins'] = 2
        lcrv['method'] = '3D'
        lcrv['enumbins'] = 0
        lcrv['emin'] = 1.0
        lcrv['emax'] = 100.0
        lcrv['outfile'] = 'cslightcrv_py1.fits'
        lcrv['logfile'] = 'cslightcrv_py1.log'
        lcrv['chatter'] = 2
        lcrv['publish'] = True

        # Run cslightcrv script and save light curve
        lcrv.logFileOpen()  # Make sure we get a log file
        lcrv.run()
        lcrv.save()

        # Check light curve
        self._check_light_curve('cslightcrv_py1.fits', 2)

        # Now use FILE as time bin algorithm. For this we need first to
        # create an ASCII file. We use now 2 time bins. The ASCII file
        # is saved into the file "lightcurve_py2.dat".
        csv = gammalib.GCsv(2, 2)
        tmin = 58849.00
        tdelta = 0.0017361
        for i in range(csv.nrows()):
            csv[i, 0] = '%.5f' % (tmin + i * tdelta)
            csv[i, 1] = '%.5f' % (tmin + (i + 1) * tdelta)
        csv.save('cslightcrv_py2.dat', ' ', True)

        # Set-up unbinned cslightcrv
        lcrv = cscripts.cslightcrv()
        lcrv['inobs'] = self._events
        lcrv['inmodel'] = self._model
        lcrv['srcname'] = 'Crab'
        lcrv['caldb'] = self._caldb
        lcrv['irf'] = self._irf
        lcrv['tbinalg'] = 'FILE'
        lcrv['tbinfile'] = 'cslightcrv_py2.dat'
        lcrv['method'] = '3D'
        lcrv['enumbins'] = 0
        lcrv['emin'] = 1.0
        lcrv['emax'] = 100.0
        lcrv['fix_bkg'] = True
        lcrv['outfile'] = 'cslightcrv_py2.fits'
        lcrv['logfile'] = 'cslightcrv_py2.log'
        lcrv['chatter'] = 3

        # Execute cslightcrv script
        lcrv.execute()

        # Check light curve
        self._check_light_curve('cslightcrv_py2.fits', 2)

        # Now we setup an observation container on input. We attached the
        # model to the observation container so that cslightcrv should
        # no longer query for the parameter.
        cta = gammalib.GCTAObservation(self._events)
        obs = gammalib.GObservations()
        obs.append(cta)
        obs.models(self._model)

        # Set-up unbinned cslightcrv from observation container. Now use
        # the GTI algorithm so that we test all timing algorithms.
        lcrv = cscripts.cslightcrv(obs)
        lcrv['srcname'] = 'Crab'
        lcrv['caldb'] = self._caldb
        lcrv['irf'] = self._irf
        lcrv['tbinalg'] = 'GTI'
        lcrv['method'] = '3D'
        lcrv['enumbins'] = 0
        lcrv['emin'] = 1.0
        lcrv['emax'] = 100.0
        lcrv['outfile'] = 'cslightcrv_py3.fits'
        lcrv['logfile'] = 'cslightcrv_py3.log'
        lcrv['chatter'] = 4

        # Execute cslightcrv script
        lcrv.execute()

        # Check light curve
        self._check_light_curve('cslightcrv_py3.fits', 1)

        # Binned cslightcrv
        lcrv = cscripts.cslightcrv()
        lcrv['inobs'] = self._events
        lcrv['inmodel'] = self._model
        lcrv['srcname'] = 'Crab'
        lcrv['caldb'] = self._caldb
        lcrv['irf'] = self._irf
        lcrv['tbinalg'] = 'LIN'
        lcrv['tmin'] = '2020-01-01T00:00:00'
        lcrv['tmax'] = '2020-01-01T00:05:00'
        lcrv['tbins'] = 2
        lcrv['method'] = '3D'
        lcrv['emin'] = 1.0
        lcrv['emax'] = 100.0
        lcrv['enumbins'] = 3
        lcrv['coordsys'] = 'CEL'
        lcrv['proj'] = 'TAN'
        lcrv['xref'] = 83.63
        lcrv['yref'] = 22.01
        lcrv['nxpix'] = 10
        lcrv['nypix'] = 10
        lcrv['binsz'] = 0.04
        lcrv['outfile'] = 'cslightcrv_py4.fits'
        lcrv['logfile'] = 'cslightcrv_py4.log'
        lcrv['chatter'] = 4

        # Execute cslightcrv script
        lcrv.execute()

        # Check light curve
        self._check_light_curve('cslightcrv_py4.fits', 2)

        # cslightcrv with classical analysis
        lcrv = cscripts.cslightcrv()
        lcrv['inobs'] = self._offaxis_events
        lcrv['inmodel'] = self._model_onoff
        lcrv['srcname'] = 'Crab'
        lcrv['caldb'] = self._caldb
        lcrv['irf'] = self._irf
        lcrv['tbinalg'] = 'LIN'
        lcrv['tmin'] = '2020-01-01T00:00:00'
        lcrv['tmax'] = '2020-01-01T00:05:00'
        lcrv['tbins'] = 2
        lcrv['method'] = 'ONOFF'
        lcrv['use_model_bkg'] = False  # Needed even if WSTAT
        lcrv['emin'] = 1.0
        lcrv['emax'] = 100.0
        lcrv['enumbins'] = 2
        lcrv['coordsys'] = 'CEL'
        lcrv['xref'] = 83.63
        lcrv['yref'] = 22.01
        lcrv['rad'] = 0.2
        lcrv['etruemin'] = 1.0
        lcrv['etruemax'] = 100.0
        lcrv['etruebins'] = 5
        lcrv['statistic'] = 'WSTAT'
        lcrv['outfile'] = 'cslightcrv_py5.fits'
        lcrv['logfile'] = 'cslightcrv_py5.log'
        lcrv['chatter'] = 4

        # Execute cslightcrv script
        lcrv.execute()

        # Check light curve
        self._check_light_curve('cslightcrv_py5.fits', 2)

        # Set-up cslightcrv without multiprocessing
        lcrv = cscripts.cslightcrv()
        lcrv['inobs'] = self._events
        lcrv['inmodel'] = self._model
        lcrv['srcname'] = 'Crab'
        lcrv['caldb'] = self._caldb
        lcrv['irf'] = self._irf
        lcrv['tbinalg'] = 'LIN'
        lcrv['tmin'] = '2020-01-01T00:00:00'
        lcrv['tmax'] = '2020-01-01T00:05:00'
        lcrv['tbins'] = 2
        lcrv['method'] = '3D'
        lcrv['enumbins'] = 0
        lcrv['emin'] = 1.0
        lcrv['emax'] = 100.0
        lcrv['outfile'] = 'cslightcrv_py6.fits'
        lcrv['logfile'] = 'cslightcrv_py6.log'
        lcrv['chatter'] = 2
        lcrv['publish'] = True
        lcrv['nthreads'] = 1

        # Run cslightcrv script and save light curve
        lcrv.logFileOpen()  # Make sure we get a log file
        lcrv.run()
        lcrv.save()

        # Check light curve
        self._check_light_curve('cslightcrv_py6.fits', 2)

        # Return
        return
Ejemplo n.º 29
0
def plot_spectrum(specfile, butterfile, ax, fmt='ro', color='green'):
    """
    Plot sensitivity data

    Parameters
    ----------
    specfile : str
        Name of spectrum FITS file
    butterfile : str
        Name of butterfly FITS file
    ax : pyplot
        Subplot
    fmt : str
        Format string
    color : str
        Color string
    """
    # Read spectrum file
    fits     = gammalib.GFits(specfile)
    table    = fits.table(1)
    c_energy = table['Energy']
    c_ed     = table['ed_Energy']
    c_eu     = table['eu_Energy']
    c_flux   = table['Flux']
    c_eflux  = table['e_Flux']
    c_ts     = table['TS']
    c_upper  = table['UpperLimit']

    # Read butterfly file
    csv = gammalib.GCsv(butterfile)

    # Initialise arrays to be filled
    energies    = []
    flux        = []
    ed_engs     = []
    eu_engs     = []
    e_flux      = []
    ul_energies = []
    ul_ed_engs  = []
    ul_eu_engs  = []
    ul_flux     = []
    butterfly_x = []
    butterfly_y = []
    line_x      = []
    line_y      = []

    # Loop over rows of the file
    nrows = table.nrows()
    for row in range(nrows):

        # Get Test Statistic, flux and flux error
        ts    = c_ts.real(row)
        flx   = c_flux.real(row)
        e_flx = c_eflux.real(row)

        # If Test Statistic is larger than 9 and flux error is smaller than
        # flux then append flux plots ...
        if ts > -99999.0 and e_flx < flx and e_flx > 0.0:
            energies.append(c_energy.real(row))
            flux.append(c_flux.real(row))
            ed_engs.append(c_ed.real(row))
            eu_engs.append(c_eu.real(row))
            e_flux.append(c_eflux.real(row))

        # ... otherwise append upper limit
        else:
            ul_energies.append(c_energy.real(row))
            ul_flux.append(c_upper.real(row))
            ul_ed_engs.append(c_ed.real(row))
            ul_eu_engs.append(c_eu.real(row))

    # Set upper limit errors
    yerr = [0.6 * x for x in ul_flux]

    # Loop over rows of the file
    nrows = csv.nrows()
    for row in range(nrows):

        # Limit values to positive
        value = csv.real(row,2)
        if value < 1e-40:
            value = 1e-40

        # Compute upper edge of confidence band
        butterfly_x.append(csv.real(row,0)/1.0e6) # TeV
        butterfly_y.append(value*csv.real(row,0)*csv.real(row,0)*gammalib.MeV2erg)

        # Set line values
        line_x.append(csv.real(row,0)/1.0e6) # TeV
        line_y.append(csv.real(row,1)*csv.real(row,0)*csv.real(row,0)*gammalib.MeV2erg)

    # Loop over the rows backwards to compute the lower edge of the
    # confidence band
    for row in range(nrows):
        index = nrows - 1 - row
        butterfly_x.append(csv.real(index,0)/1.0e6)
        low_error = max(csv.real(index,3)*csv.real(index,0)*csv.real(index,0)*gammalib.MeV2erg, 1e-20)
        butterfly_y.append(low_error)

    # Plot the spectrum
    ax.errorbar(energies, flux, yerr=e_flux, xerr=[ed_engs, eu_engs],
                fmt=fmt, label='ctools')
    ax.errorbar(ul_energies, ul_flux, xerr=[ul_ed_engs, ul_eu_engs],
                yerr=yerr, uplims=True, fmt=fmt, label='_nolegend_')

    # Plot Crab SED from Aharonian et al. (2006a)
    hess_x = [i*0.1+0.4 for i in range(400)]
    hess_y = []
    for x in hess_x:
        y = 3.84e-11 * math.pow(x, -2.41) * math.exp(-x/15.1)
        hess_y.append(y*x*x*gammalib.MeV2erg*1.0e6)
    ax.plot(hess_x, hess_y, color='blue', ls='-', label='Aharonian et al. (2006a)')

    # Plot Crab SED from Nigro et al. (2019)
    nigro_x = [i*0.1+0.4 for i in range(400)]
    nigro_y = []
    for x in nigro_x:
        y = 4.47e-11 * math.pow(x, -2.39 - 0.16 * math.log(x))
        nigro_y.append(y*x*x*gammalib.MeV2erg*1.0e6)
    ax.plot(nigro_x, nigro_y, color='green', ls='-', label='Nigro et al. (2019)')

    # Plot the butterfly
    ax.plot(line_x, line_y, color='red', ls='-')
    ax.fill(butterfly_x, butterfly_y, color='salmon', alpha=0.5)

    # Resort labels
    handles, labels = ax.get_legend_handles_labels()
    order           = [2,0,1]

    # Add legend
    ax.legend([handles[idx] for idx in order],[labels[idx] for idx in order])

    # Return
    return
Ejemplo n.º 30
0
def plot_spectrum(specfile, butterfile, ax, fmt='ro', fermi=False):
    """
    Plot sensitivity data

    Parameters
    ----------
    specfile : str
        Name of spectrum FITS file
    butterfile : str
        Name of butterfly FITS file
    ax : pyplot
        Subplot
    fmt : str
        Format string
    """
    # Read spectrum file    
    fits     = gammalib.GFits(specfile)
    table    = fits.table(1)
    c_energy = table['Energy']
    c_ed     = table['ed_Energy']
    c_eu     = table['eu_Energy']
    c_flux   = table['Flux']
    c_eflux  = table['e_Flux']
    c_ts     = table['TS']
    c_upper  = table['UpperLimit']

    # Read butterfly file
    csv = gammalib.GCsv(butterfile)

    # Initialise arrays to be filled
    energies    = []
    flux        = []
    ed_engs     = []
    eu_engs     = []
    e_flux      = []
    ul_energies = []
    ul_ed_engs  = []
    ul_eu_engs  = []
    ul_flux     = []
    butterfly_x = []
    butterfly_y = []
    line_x      = []
    line_y      = []

    # Loop over rows of the file
    nrows = table.nrows()
    for row in range(nrows):

        # Get Test Statistic, flux and flux error
        ts    = c_ts.real(row)
        flx   = c_flux.real(row)
        e_flx = c_eflux.real(row)

        # If Test Statistic is larger than 9 and flux error is smaller than
        # flux then append flux plots ...
        if ts > -99999.0 and e_flx < flx and e_flx > 0.0:
            energies.append(c_energy.real(row))
            flux.append(c_flux.real(row))
            ed_engs.append(c_ed.real(row))
            eu_engs.append(c_eu.real(row))
            e_flux.append(c_eflux.real(row))

        # ... otherwise append upper limit
        else:
            ul_energies.append(c_energy.real(row))
            ul_flux.append(c_upper.real(row))
            ul_ed_engs.append(c_ed.real(row))
            ul_eu_engs.append(c_eu.real(row))

    # Set upper limit errors
    yerr = [0.6 * x for x in ul_flux]

    # Loop over rows of the file
    nrows = csv.nrows()
    for row in range(nrows):

        # Limit values to positive
        value = csv.real(row,2)
        if value < 1e-40:
            value = 1e-40

        # Compute upper edge of confidence band
        butterfly_x.append(csv.real(row,0)/1.0e6) # TeV
        butterfly_y.append(value*csv.real(row,0)*csv.real(row,0)*gammalib.MeV2erg)

        # Set line values
        line_x.append(csv.real(row,0)/1.0e6) # TeV
        line_y.append(csv.real(row,1)*csv.real(row,0)*csv.real(row,0)*gammalib.MeV2erg)

    # Loop over the rows backwards to compute the lower edge of the
    # confidence band
    for row in range(nrows):
        index = nrows - 1 - row
        butterfly_x.append(csv.real(index,0)/1.0e6)
        low_error = max(csv.real(index,3)*csv.real(index,0)*csv.real(index,0)*gammalib.MeV2erg, 1e-26)
        butterfly_y.append(low_error)

    # Plot the spectrum
    ax.errorbar(energies, flux, yerr=e_flux, xerr=[ed_engs, eu_engs],
                fmt=fmt, label='ctools')
    ax.errorbar(ul_energies, ul_flux, xerr=[ul_ed_engs, ul_eu_engs],
                yerr=yerr, uplims=True, fmt=fmt, label='_nolegend_')

    # Plot RX J1713 SED
    #engs, ergs, yerrs = rx_sed_2006()
    #engs, ergs, yerrs = rx_sed_2011()
    engs, ergs, yerrs = rx_sed_2018()
    ax.errorbar(engs, ergs, yerr=yerrs, fmt='bo', label='H.E.S.S. collaboration et al. (2018)')

    # Plot RX J1713 Fermi-LAT SED
    if fermi:
        engs, ergs, xerrs, yerrs = rx_fermi_sed_2018()
        ax.errorbar(engs, ergs, xerr=xerrs, yerr=yerrs, fmt='go', label='Fermi-LAT')

	# Plot spectral law from publication
    if fermi:
        abdalla_x = [i*0.001+0.001 for i in range(40000)]
    else:
        abdalla_x = [i*0.1+0.2 for i in range(400)]
    abdalla_y = []
    for x in abdalla_x:
        y = 2.3e-11 * math.pow(x, -2.06) * math.exp(-x/12.9)
        abdalla_y.append(y*x*x*gammalib.MeV2erg*1.0e6)
    ax.plot(abdalla_x, abdalla_y, color='b', ls='-', label='_nolegend_')

    # Plot the butterfly
    ax.plot(line_x, line_y, color='red', ls='-')
    ax.fill(butterfly_x, butterfly_y, color='salmon', alpha=0.5)

    # Add legend
    ax.legend()

    # Return
    return