Пример #1
0
    def _create_fits_table(self, results):
        """
        Creates FITS binary table containing phase curve results

        Parameters
        ----------
        results : list of dict
            List of result dictionaries

        Returns
        -------
        table : `~gammalib.GFitsBinTable`
            FITS binary table containing phase curve
        """
        # Determine number of rows in FITS table
        nrows = len(results)

        # Create FITS Table with extension "PHASECURVE"
        table = gammalib.GFitsBinTable(nrows)
        table.extname('PHASECURVE')

        # Append phase columns
        ioutils.append_result_column(table, results, 'PHASE_MIN', '', 'phmin')
        ioutils.append_result_column(table, results, 'PHASE_MAX', '', 'phmax')

        # Append parameter columns
        ioutils.append_model_par_column(table,
                                        self.obs().models()[self._srcname],
                                        results)

        # Return table
        return table
Пример #2
0
def create_cif_table():
    """
    Create Calibration Database Index File binary table
    """
    # Create binary table
    table = gammalib.GFitsBinTable()

    # Append columns. Reference: CAL/GEN/92-008
    table.append(gammalib.GFitsTableStringCol("TELESCOP", 0, 10))
    table.append(gammalib.GFitsTableStringCol("INSTRUME", 0, 10))
    table.append(gammalib.GFitsTableStringCol("DETNAM", 0, 20))
    table.append(gammalib.GFitsTableStringCol("FILTER", 0, 10))
    table.append(gammalib.GFitsTableStringCol("CAL_DEV", 0, 20))
    table.append(gammalib.GFitsTableStringCol("CAL_DIR", 0, 70))
    table.append(gammalib.GFitsTableStringCol("CAL_FILE", 0, 40))
    table.append(gammalib.GFitsTableStringCol("CAL_CLAS", 0, 3))
    table.append(gammalib.GFitsTableStringCol("CAL_DTYP", 0, 4))
    table.append(gammalib.GFitsTableStringCol("CAL_CNAM", 0, 20))
    table.append(gammalib.GFitsTableStringCol("CAL_CBD", 0, 70, 9))
    table.append(gammalib.GFitsTableShortCol("CAL_XNO", 0))
    table.append(gammalib.GFitsTableStringCol("CAL_VSD", 0, 10))
    table.append(gammalib.GFitsTableStringCol("CAL_VST", 0, 8))
    table.append(gammalib.GFitsTableDoubleCol("REF_TIME", 0))
    table.append(gammalib.GFitsTableShortCol("CAL_QUAL", 0))
    table.append(gammalib.GFitsTableStringCol("CAL_DATE", 0, 8))
    table.append(gammalib.GFitsTableStringCol("CAL_DESC", 0, 70))

    # Set keywords. Reference: CAL/GEN/92-008
    table.extname("CIF")
    table.card("CIFVERSN", "1992a", "Version of CIF format")

    # Return table
    return table
Пример #3
0
    def _create_fits_table(self, results):
        """
        Creates FITS binary table containing light curve results.

        Args:
            results: List of result dictionaries.

        Returns:
            FITS binary table containing light curve.
        """
        # Determine number of rows in FITS table
        nrows = len(results)

        # Create FITS Table with extension "LIGHTCURVE"
        table = gammalib.GFitsBinTable(nrows)
        table.extname("LIGHTCURVE")

        # Append time columns
        mjd = gammalib.GFitsTableDoubleCol("MJD", nrows)
        e_mjd = gammalib.GFitsTableDoubleCol("e_MJD", nrows)
        mjd.unit("days")
        e_mjd.unit("days")
        for i, result in enumerate(results):
            mjd[i] = result["mjd"]
            e_mjd[i] = result["e_mjd"]
        table.append(mjd)
        table.append(e_mjd)

        # Create parameter columns
        for par in self._obs.models()[self._srcname]:
            if par.is_free():
                name = par.name()
                e_name = "e_" + par.name()
                col = gammalib.GFitsTableDoubleCol(name, nrows)
                e_col = gammalib.GFitsTableDoubleCol(e_name, nrows)
                col.unit(par.unit())
                e_col.unit(par.unit())
                for i, result in enumerate(results):
                    col[i] = result['values'][name]
                    e_col[i] = result['values'][e_name]
                table.append(col)
                table.append(e_col)

        # Append Test Statistic column
        ts = gammalib.GFitsTableDoubleCol("TS", nrows)
        for i, result in enumerate(results):
            ts[i] = result["ts"]
        table.append(ts)

        # Append upper limit column
        ulimit = gammalib.GFitsTableDoubleCol("UpperLimit", nrows)
        ulimit.unit("ph/cm2/s")
        for i, result in enumerate(results):
            ulimit[i] = result['ulimit']
        table.append(ulimit)

        # Return table
        return table
Пример #4
0
    def _residuals_table(self, obs_id, ebounds, counts, model, residuals):
        """
        Create a Fits Table and store counts, model, and residuals

        Parameters
        ----------
        obs_id : str
            Observation id
        ebounds : `~gammalib.GEbounds'
            Energy boundaries
        counts : `~gammalib.GNdarray'
            Counts spectrum
        model : `~gammalib.GNdarray'
            Model spectrum
        residuals : `~gammalib.GNdarray'
            Residual spectrum

        Returns
        -------
        table : `~gammalib.GFitsBinTable'
            Residual spectrum as FITS binary table
        """
        # Create FITS table columns
        nrows = ebounds.size()
        energy_low = gammalib.GFitsTableDoubleCol('Emin', nrows)
        energy_high = gammalib.GFitsTableDoubleCol('Emax', nrows)
        counts_col = gammalib.GFitsTableDoubleCol('Counts', nrows)
        model_col = gammalib.GFitsTableDoubleCol('Model', nrows)
        resid_col = gammalib.GFitsTableDoubleCol('Residuals', nrows)
        energy_low.unit('TeV')
        energy_high.unit('TeV')

        # Fill FITS table columns
        for i in range(nrows):
            energy_low[i] = ebounds.emin(i).TeV()
            energy_high[i] = ebounds.emax(i).TeV()
            counts_col[i] = counts[i]
            model_col[i] = model[i]
            resid_col[i] = residuals[i]

        # Initialise FITS Table with extension set to obs id
        table = gammalib.GFitsBinTable(nrows)
        table.extname('RESIDUALS' + obs_id)

        # Add Header card to specify algorithm used for residual computation
        table.card('ALGORITHM', self['algorithm'].string(),
                   'Algorithm used for computation of residuals')

        # Append filled columns to fits table
        table.append(energy_low)
        table.append(energy_high)
        table.append(counts_col)
        table.append(model_col)
        table.append(resid_col)

        # Return binary table
        return table
Пример #5
0
    def create_cif(self):
        """
        Create Calibration Index File (CIF) extension in CIF FITS file.

        Parameters:
         None
        Keywords:
         None
        """
        # Create binary table
        table = gammalib.GFitsBinTable()

        # Set boundary

        # Attach columns. Reference: CAL/GEN/92-008
        table.append(gammalib.GFitsTableStringCol("TELESCOP", 0, 10))
        table.append(gammalib.GFitsTableStringCol("INSTRUME", 0, 10))
        table.append(gammalib.GFitsTableStringCol("DETNAM", 0, 20))
        table.append(gammalib.GFitsTableStringCol("FILTER", 0, 10))
        table.append(gammalib.GFitsTableStringCol("CAL_DEV", 0, 20))
        table.append(gammalib.GFitsTableStringCol("CAL_DIR", 0, 70))
        table.append(gammalib.GFitsTableStringCol("CAL_FILE", 0, 40))
        table.append(gammalib.GFitsTableStringCol("CAL_CLAS", 0, 3))
        table.append(gammalib.GFitsTableStringCol("CAL_DTYP", 0, 4))
        table.append(gammalib.GFitsTableStringCol("CAL_CNAM", 0, 20))
        table.append(gammalib.GFitsTableStringCol("CAL_CBD", 0, 70, 9))
        table.append(gammalib.GFitsTableShortCol("CAL_XNO", 0))
        table.append(gammalib.GFitsTableStringCol("CAL_VSD", 0, 10))
        table.append(gammalib.GFitsTableStringCol("CAL_VST", 0, 8))
        table.append(gammalib.GFitsTableDoubleCol("REF_TIME", 0))
        table.append(gammalib.GFitsTableShortCol("CAL_QUAL", 0))
        table.append(gammalib.GFitsTableStringCol("CAL_DATE", 0, 8))
        table.append(gammalib.GFitsTableStringCol("CAL_DESC", 0, 70))

        # Set keywords. Reference: CAL/GEN/92-008
        table.extname("CIF")
        table.card("CIFVERSN", "1992a", "Version of CIF format")

        # Attach table to FITS file. Note that at this moment the
        # FITS table gets connected to the FITS file. Yet since
        # nothing was yet written to the FITS file, we cannot read
        # anything from it.
        self.cif.append(table)

        # Return
        return
Пример #6
0
    def _create_fits_table(self, results):
        """
        Creates FITS binary table containing light curve results

        Parameters
        ----------
        results : list of dict
            List of result dictionaries

        Returns
        -------
        table : `~gammalib.GFitsBinTable`
            FITS binary table containing light curve
        """
        # Determine number of rows in FITS table
        nrows = len(results)

        # Create FITS Table with extension "LIGHTCURVE"
        table = gammalib.GFitsBinTable(nrows)
        table.extname('LIGHTCURVE')

        # Append time columns
        ioutils.append_result_column(table, results, 'MJD', 'days', 'mjd')
        ioutils.append_result_column(table, results, 'e_MJD', 'days', 'e_mjd')

        # Append parameter columns
        ioutils.append_model_par_column(table,
                                        self.obs().models()[self._srcname],
                                        results)

        # Append Test Statistic column "TS"
        ioutils.append_result_column(table, results, 'TS', '', 'ts')

        # Append upper limit columns
        ioutils.append_result_column(table, results, 'DiffUpperLimit',
                                     'ph/cm2/s/MeV', 'ul_diff')
        ioutils.append_result_column(table, results, 'FluxUpperLimit',
                                     'ph/cm2/s', 'ul_flux')
        ioutils.append_result_column(table, results, 'EFluxUpperLimit',
                                     'erg/cm2/s', 'ul_eflux')

        # Return table
        return table
Пример #7
0
    def _make_caldb_index(self):
        """
        Creates an IRF index FITS file.
        """
        # Write header into logger
        if self._logTerse():
            self._log("\n")
            self._log.header2("Creating database index file")

        # Open calibration database index
        indx_file = self._base_dir+"/caldb.indx"
        
        # Open index file (or create one if it does not exist)
        cif = gammalib.GFits(indx_file, True)
        
        # Retrieve "CIF" table
        if cif.contains("CIF"):
            table = cif.table("CIF")

        # ... or create binary table if no "CIF" table exists yet
        else:       

            # Create empty binary table
            bintable = gammalib.GFitsBinTable()
            bintable.extname("CIF")
            bintable.card("CIFVERSN", "1992a", "Version of CIF format")     

            # Append table to FITS file and recover a reference to the
            # appended table
            table = cif.append(bintable)
            
            # Attach columns. Reference: CAL/GEN/92-008
            table.append(gammalib.GFitsTableStringCol("TELESCOP", 0, 10))
            table.append(gammalib.GFitsTableStringCol("INSTRUME", 0, 10))
            table.append(gammalib.GFitsTableStringCol("DETNAM", 0, 20))
            table.append(gammalib.GFitsTableStringCol("FILTER", 0, 10))
            table.append(gammalib.GFitsTableStringCol("CAL_DEV", 0, 20))
            table.append(gammalib.GFitsTableStringCol("CAL_DIR", 0, 70))
            table.append(gammalib.GFitsTableStringCol("CAL_FILE", 0, 40))
            table.append(gammalib.GFitsTableStringCol("CAL_CLAS", 0, 3))
            table.append(gammalib.GFitsTableStringCol("CAL_DTYP", 0, 4))
            table.append(gammalib.GFitsTableStringCol("CAL_CNAM", 0, 20))
            table.append(gammalib.GFitsTableStringCol("CAL_CBD", 0, 70, 9))
            table.append(gammalib.GFitsTableShortCol("CAL_XNO", 0))
            table.append(gammalib.GFitsTableStringCol("CAL_VSD", 0, 10))
            table.append(gammalib.GFitsTableStringCol("CAL_VST", 0, 8))
            table.append(gammalib.GFitsTableDoubleCol("REF_TIME", 0))
            table.append(gammalib.GFitsTableShortCol("CAL_QUAL", 0))
            table.append(gammalib.GFitsTableStringCol("CAL_DATE", 0, 8))
            table.append(gammalib.GFitsTableStringCol("CAL_DESC", 0, 70))

        # Check if output config already exist
        has_config = False
        row_index = -1
        for caldir in table["CAL_DIR"]:
            row_index += 1
            if caldir == self._cal_dir:
                has_config = True
                break
         
        # Create columns if not available   
        if not has_config:           
            # Append 4 rows to CIF extension
            table.append_rows(4)
            row_index = table.nrows()
        else:
            row_index += 4

        # Add generic information for these 4 rows
        for i in range(4):

            # Set row number
            row = i + row_index-4

            # Set date
            now = str(datetime.datetime.now())
            today, time = now.split()
            
            # Set element
            table["TELESCOP"][row] = self._mission
            table["INSTRUME"][row] = self._caldb
            table["DETNAM"][row]   = "NONE"
            table["FILTER"][row]   = "NONE"
            table["CAL_DEV"][row]  = "ONLINE"
            table["CAL_CLAS"][row] = "BCF"
            table["CAL_DTYP"][row] = "DATA"
            table["CAL_VSD"][row]  = today
            table["CAL_VST"][row]  = time.split(".")[0]
            table["REF_TIME"][row] = 51544.0
            table["CAL_QUAL"][row] = 0
            table["CAL_CBD"][row]  = "NAME("+self["irf"].string()+")"
            table["CAL_DATE"][row] = today.replace("-","/")[2:]
            table["CAL_DIR"][row]  = self._cal_dir
            table["CAL_FILE"][row] = self._outfile

        # Add effective area information
        row = row_index-4
        table["CAL_CNAM"][row] = "EFF_AREA"
        table["CAL_DESC"][row] = self._caldb+" effective area"

        # Add point spread function information
        row = row_index-3
        table["CAL_CNAM"][row] = "RPSF"
        table["CAL_DESC"][row] = self._caldb+" point spread function"
        
        # Add energy dispersion information
        row = row_index-2
        table["CAL_CNAM"][row] = "EDISP"
        table["CAL_DESC"][row] = self._caldb+" energy dispersion"

        # Add background information
        row = row_index-1
        table["CAL_CNAM"][row] = "BGD"
        table["CAL_DESC"][row] = self._caldb+" background"

        # Log resulting FITS table and header
        if self._logNormal():
            self._log(str(table))
            self._log("\n")
        if self._logExplicit():
            self._log(str(table.header()))
            self._log("\n")
        
        # Return CIF FITS file
        return cif
Пример #8
0
    def _create_fits(self, results):
        """
        Create FITS file

        Parameters
        ----------
        results : list of dict
            List of result dictionaries
        """
        # Create FITS table columns
        nrows = self._ebounds.size()
        energy = gammalib.GFitsTableDoubleCol('Energy', nrows)
        energy_low = gammalib.GFitsTableDoubleCol('ed_Energy', nrows)
        energy_high = gammalib.GFitsTableDoubleCol('eu_Energy', nrows)
        flux = gammalib.GFitsTableDoubleCol('Flux', nrows)
        flux_err = gammalib.GFitsTableDoubleCol('e_Flux', nrows)
        TSvalues = gammalib.GFitsTableDoubleCol('TS', nrows)
        ulim_values = gammalib.GFitsTableDoubleCol('UpperLimit', nrows)
        Npred_values = gammalib.GFitsTableDoubleCol('Npred', nrows)
        energy.unit('TeV')
        energy_low.unit('TeV')
        energy_high.unit('TeV')
        flux.unit('erg/cm2/s')
        flux_err.unit('erg/cm2/s')
        ulim_values.unit('erg/cm2/s')

        # File FITS table columns
        for i, result in enumerate(results):
            energy[i] = result['energy']
            energy_low[i] = result['energy_low']
            energy_high[i] = result['energy_high']
            flux[i] = result['flux']
            flux_err[i] = result['flux_err']
            TSvalues[i] = result['TS']
            ulim_values[i] = result['ulimit']
            Npred_values[i] = result['Npred']

        # Initialise FITS Table with extension "SPECTRUM"
        table = gammalib.GFitsBinTable(nrows)
        table.extname('SPECTRUM')

        # Add Header for compatibility with gammalib.GMWLSpectrum
        table.card('INSTRUME', 'CTA', 'Name of Instrument')
        table.card('TELESCOP', 'CTA', 'Name of Telescope')

        # Append filled columns to fits table
        table.append(energy)
        table.append(energy_low)
        table.append(energy_high)
        table.append(flux)
        table.append(flux_err)
        table.append(TSvalues)
        table.append(ulim_values)
        table.append(Npred_values)

        # Create the FITS file now
        self._fits = gammalib.GFits()
        self._fits.append(table)

        # Return
        return
Пример #9
0
    def _create_fits(self, result):
        """
        Create fits file

        Parameters
        ----------
        result: Dictionary with results obtained from fit
        """

        #   Create columns (just one row ><'!)
        #   This will change when adding loop over different masses
        #   and/or channels
        #   By now, hard-coding the number of rows, 1
        nrows = 1
        energy = gammalib.GFitsTableDoubleCol('RefEnergy', nrows)
        flux = gammalib.GFitsTableDoubleCol('Flux', nrows)
        flux_err = gammalib.GFitsTableDoubleCol('EFlux', nrows)
        TSvalues = gammalib.GFitsTableDoubleCol('TS', nrows)
        ulim_values = gammalib.GFitsTableDoubleCol('UpperLimit', nrows)
        # sigma_lim    = gammalib.GFitsTableDoubleCol( 'ULCrossSection' , nrows )
        # sigma_ref    = gammalib.GFitsTableDoubleCol( 'RefCrossSection' , nrows )
        sc_factor = gammalib.GFitsTableDoubleCol('ScaleFactor', nrows)

        energy.unit('TeV')
        flux.unit('erg/cm2/s')
        flux_err.unit('erg/cm2/s')
        ulim_values.unit('erg/cm2/s')
        # sigma_lim.unit( 'cm3/s' )
        # sigma_ref.unit( 'cm3/s' )

        #   Fill fits
        energy[0] = result['energy']
        flux[0] = result['flux']
        flux_err[0] = result['flux_err']
        TSvalues[0] = result['TS']
        ulim_values[0] = result['ulimit']
        # sigma_lim[ 0 ]   = result[ 'sigma_lim' ]
        # sigma_ref[ 0 ]   = result[ 'sigma_ref' ]
        sc_factor[0] = result['sc_factor']

        #   Initialise FITS Table with extension "DMATTER"
        table = gammalib.GFitsBinTable(nrows)
        table.extname('DMATTER')

        #   Add Header for compatibility with gammalib.GMWLSpectrum
        table.card('INSTRUME', 'CTA', 'Name of Instrument')
        table.card('TELESCOP', 'CTA', 'Name of Telescope')

        #   Append filled columns to fits table
        table.append(energy)
        table.append(flux)
        table.append(flux_err)
        table.append(TSvalues)
        table.append(ulim_values)
        # table.append( sigma_lim )
        # table.append( sigma_ref )
        table.append(sc_factor)

        #   Create the FITS file now
        self._fits = gammalib.GFits()
        self._fits.append(table)

        #   Return
        return
Пример #10
0
    for nameSource in nameSources:

        spec = models[nameSource].spectral()

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

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

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

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

    #   Creating columns for every parameter to save
    col_runID = gammalib.GFitsTableShortCol('RunID', args.nsims)
    col_events = gammalib.GFitsTableDoubleCol('CubeEvents', args.nsims)
    # col_oevents = gammalib.GFitsTableDoubleCol( 'ObsEvents' , args.nsims )
    col_ts = gammalib.GFitsTableDoubleCol('TS', args.nsims)
    col_ulflux = gammalib.GFitsTableDoubleCol('ULFlux', args.nsims)
    col_scale = gammalib.GFitsTableDoubleCol('ScaleFactor', args.nsims)

    if is_anna_or_decs:

        col_cs = gammalib.GFitsTableDoubleCol('LogCrossSection', args.nsims)

    else:
Пример #11
0
    def run(self):
        """
        Run the script.
        """
        # Switch screen logging on in debug mode
        if self._logDebug():
            self._log.cout(True)

        # Get parameters
        self._get_parameters()

        # Write spectral binning into header
        if self._logTerse():
            self._log("\n")
            self._log.header1("Spectral binning")
            if self._binned_mode:
                cube_ebounds = self._obs[0].events().ebounds()
                self._log.parformat("Counts cube energy range")
                self._log(str(cube_ebounds.emin()))
                self._log(" - ")
                self._log(str(cube_ebounds.emax()))
                self._log("\n")
            for i in range(self._ebounds.size()):
                self._log.parformat("Bin " + str(i + 1))
                self._log(str(self._ebounds.emin(i)))
                self._log(" - ")
                self._log(str(self._ebounds.emax(i)))
                self._log("\n")

        # Write observation into logger
        if self._logTerse():
            self._log("\n")
            self._log.header1("Observation")
            self._log(str(self._obs))
            self._log("\n")

        # Write header
        if self._logTerse():
            self._log("\n")
            self._log.header1("Adjust model parameters")

        # Adjust model parameters dependent on input user parameters
        for model in self._obs.models():

            # Set TS flag for all models to false.
            # Source of interest will be set to true later
            model.tscalc(False)

            # Log model name
            if self._logExplicit():
                self._log.header3(model.name())

            # Deal with the source of interest
            if model.name() == self._srcname:
                for par in model:
                    if par.is_free() and self._logExplicit():
                        self._log(" Fixing \"" + par.name() + "\"\n")
                    par.fix()
                normpar = model.spectral()[0]
                if normpar.is_fixed() and self._logExplicit():
                    self._log(" Freeing \"" + normpar.name() + "\"\n")
                normpar.free()
                if self._calc_ts:
                    model.tscalc(True)

            elif self._fix_bkg and not model.classname() == "GModelSky":
                for par in model:
                    if par.is_free() and self._logExplicit():
                        self._log(" Fixing \"" + par.name() + "\"\n")
                    par.fix()

            elif self._fix_srcs and model.classname() == "GModelSky":
                for par in model:
                    if par.is_free() and self._logExplicit():
                        self._log(" Fixing \"" + par.name() + "\"\n")
                    par.fix()

        # Write header
        if self._logTerse():
            self._log("\n")
            self._log.header1("Generate spectrum")
            self._log(str(self._ebounds))

        # Initialise FITS Table with extension "SPECTRUM"
        table = gammalib.GFitsBinTable(self._ebounds.size())
        table.extname("SPECTRUM")

        # Add Header for compatibility with gammalib.GMWLSpectrum
        table.card("INSTRUME", "CTA", "Name of Instrument")
        table.card("TELESCOP", "CTA", "Name of Telescope")

        # Create FITS table columns
        nrows = self._ebounds.size()
        energy = gammalib.GFitsTableDoubleCol("Energy", nrows)
        energy_low = gammalib.GFitsTableDoubleCol("ed_Energy", nrows)
        energy_high = gammalib.GFitsTableDoubleCol("eu_Energy", nrows)
        flux = gammalib.GFitsTableDoubleCol("Flux", nrows)
        flux_err = gammalib.GFitsTableDoubleCol("e_Flux", nrows)
        TSvalues = gammalib.GFitsTableDoubleCol("TS", nrows)
        ulim_values = gammalib.GFitsTableDoubleCol("UpperLimit", nrows)
        Npred_values = gammalib.GFitsTableDoubleCol("Npred", nrows)
        energy.unit("TeV")
        energy_low.unit("TeV")
        energy_high.unit("TeV")
        flux.unit("erg/cm2/s")
        flux_err.unit("erg/cm2/s")
        ulim_values.unit("erg/cm2/s")

        # Loop over energy bins
        for i in range(nrows):

            # Log information
            if self._logExplicit():
                self._log("\n")
                self._log.header2("Energy bin " + str(i + 1))

            # Get energy boundaries
            emin = self._ebounds.emin(i)
            emax = self._ebounds.emax(i)
            elogmean = self._ebounds.elogmean(i)
            elogmean2 = elogmean.MeV() * elogmean.MeV()

            # Store energy as TeV
            energy[i] = elogmean.TeV()

            # Store energy errors
            energy_low[i] = (elogmean - emin).TeV()
            energy_high[i] = (emax - elogmean).TeV()

            # Use ctselect for unbinned analysis
            if not self._binned_mode:

                # Log information
                if self._logExplicit():
                    self._log.header3("Selecting events")

                # Select events
                select = ctools.ctselect(self._obs)
                select["emin"] = emin.TeV()
                select["emax"] = emax.TeV()
                select["tmin"] = "UNDEFINED"
                select["tmax"] = "UNDEFINED"
                select["rad"] = "UNDEFINED"
                select["ra"] = "UNDEFINED"
                select["dec"] = "UNDEFINED"
                select.run()

                # Retrieve observation
                obs = select.obs()

            # Use ctcubemask for binned analysis
            else:

                # Header
                if self._logExplicit():
                    self._log.header3("Filtering cube")

                # Select layers
                cubemask = ctools.ctcubemask(self._obs)
                cubemask["regfile"] = "NONE"
                cubemask["ra"] = "UNDEFINED"
                cubemask["dec"] = "UNDEFINED"
                cubemask["rad"] = "UNDEFINED"
                cubemask["emin"] = emin.TeV()
                cubemask["emax"] = emax.TeV()
                cubemask.run()

                # Set new binned observation
                obs = cubemask.obs()

            # Header
            if self._logExplicit():
                self._log.header3("Performing fit")

            # Likelihood
            like = ctools.ctlike(obs)
            like["edisp"] = self._edisp
            like.run()

            # Skip bin if no event was present
            if like.obs().logL() == 0.0:

                # Log information
                if self._logExplicit():
                    self._log("No event in this bin. ")
                    self._log("Likelihood is zero. ")
                    self._log("Bin is skipped.")

                # Set all values to 0
                flux[i] = 0.0
                flux_err[i] = 0.0
                TSvalues[i] = 0.0
                ulim_values[i] = 0.0
                Npred_values[i] = 0.0
                continue

            # Get results
            fitted_models = like.obs().models()
            source = fitted_models[self._srcname]

            # Calculate Upper Limit
            ulimit_value = -1.0
            if self._calc_ulimit:

                # Logging information
                if self._logExplicit():
                    self._log.header3("Computing upper limit")

                # Create upper limit object
                ulimit = ctools.ctulimit(like.obs())
                ulimit["srcname"] = self._srcname
                ulimit["eref"] = elogmean.TeV()

                # Try to run upper limit and catch exceptions
                try:
                    ulimit.run()
                    ulimit_value = ulimit.diff_ulimit()
                except:
                    if self._logExplicit():
                        self._log("Upper limit calculation failed.")
                    ulimit_value = -1.0

            # Get TS value
            TS = -1.0
            if self._calc_ts:
                TS = source.ts()

            # Compute Npred value (only works for unbinned analysis)
            Npred = 0.0
            if not self._binned_mode:
                for observation in like.obs():
                    Npred += observation.npred(source)

            # Get differential flux
            fitted_flux = source.spectral().eval(elogmean)

            # Compute flux error
            parvalue = source.spectral()[0].value()
            rel_error = source.spectral()[0].error() / parvalue
            e_flux = fitted_flux * rel_error

            # Set values for storage
            TSvalues[i] = TS

            # Set npred values
            Npred_values[i] = Npred

            # Convert fluxes to nuFnu
            flux[i] = fitted_flux * elogmean2 * gammalib.MeV2erg
            flux_err[i] = e_flux * elogmean2 * gammalib.MeV2erg
            if ulimit_value > 0.0:
                ulim_values[i] = ulimit_value * elogmean2 * gammalib.MeV2erg

            # Log information
            if self._logTerse():
                self._log("\n")
                self._log.parformat("Bin " + str(i + 1))
                self._log(str(flux[i]))
                self._log(" +/- ")
                self._log(str(flux_err[i]))
                if self._calc_ulimit and ulim_values[i] > 0.0:
                    self._log(" [< " + str(ulim_values[i]) + "]")
                self._log(" erg/cm2/s")
                if self._calc_ts and TSvalues[i] > 0.0:
                    self._log(" (TS = " + str(TS) + ")")

        # Append filled columns to fits table
        table.append(energy)
        table.append(energy_low)
        table.append(energy_high)
        table.append(flux)
        table.append(flux_err)
        table.append(TSvalues)
        table.append(ulim_values)
        table.append(Npred_values)

        # Create the FITS file now
        self._fits = gammalib.GFits()
        self._fits.append(table)

        # Return
        return
Пример #12
0
    def _create_fits(self, results) :
        """
        Create fits file

        Parameters
        ----------
        result: Dictionary with results obtained from fit
        """

        #   Create columns (><'! Now, added for n mass points')
        nrows = len(self._masses)

        e_min        = gammalib.GFitsTableDoubleCol('MinEnergy', nrows)
        e_max        = gammalib.GFitsTableDoubleCol('MaxEnergy', nrows)
        mass         = gammalib.GFitsTableDoubleCol('Mass', nrows)
        flux         = gammalib.GFitsTableDoubleCol('Flux', nrows)
        flux_err     = gammalib.GFitsTableDoubleCol('EFlux', nrows)
        slogl        = gammalib.GFitsTableDoubleCol('LogL', nrows)
        TSvalues     = gammalib.GFitsTableDoubleCol('TS', nrows)
        ulim_values  = gammalib.GFitsTableDoubleCol('UpperLimit', nrows)
        sigma_lim    = gammalib.GFitsTableDoubleCol('ULCrossSection', nrows)
        sigma_ref    = gammalib.GFitsTableDoubleCol('RefCrossSection', nrows)
        sc_factor    = gammalib.GFitsTableDoubleCol('ScaleFactor', nrows)

        e_min.unit('TeV')
        e_max.unit('TeV')
        mass.unit('TeV')
        flux.unit('erg/cm2/s')
        flux_err.unit('erg/cm2/s')
        ulim_values.unit('1/cm2/s')
        sigma_lim.unit('cm3/s')
        sigma_ref.unit('cm3/s')

        #   Fill fits
        for i, result in enumerate(results) :

            e_min[i]       = result['e_min']
            e_max[i]       = result['e_max']
            mass[i]        = result['mass']
            flux[i]        = result['flux']
            flux_err[i]    = result['flux_err']
            slogl[i]       = result['logL']
            TSvalues[i]    = result['TS']
            ulim_values[i] = result['ulimit']
            sigma_lim[i]   = result['sigma_lim']
            sigma_ref[i]   = result['sigma_ref']
            sc_factor[i]   = result['sc_factor']

        #   Initialise FITS Table with extension "DMATTER"
        table = gammalib.GFitsBinTable(nrows)
        table.extname('DMATTER')

        #   Add Header for compatibility with gammalib.GMWLSpectrum
        table.card('INSTRUME', 'CTA', 'Name of Instrument')
        table.card('TELESCOP', 'CTA', 'Name of Telescope')

        #   Append filled columns to fits table
        table.append(e_min)
        table.append(e_max)
        table.append(mass)
        table.append(flux)
        table.append(flux_err)
        table.append(slogl)
        table.append(TSvalues)
        table.append(ulim_values)
        table.append(sigma_lim)
        table.append(sigma_ref)
        table.append(sc_factor)

        #   Create the FITS file now
        self._fits = gammalib.GFits()
        self._fits.append(table)

        #   Return
        return