Example #1
0
    def ctselect(self):
        # ctselect application and set parameters
        self.info("Running ctselect to cut on events")
        self.validate()
        if self.m_obs:
            filter = ct.ctselect(self.m_obs)
        else:
            filter = ct.ctselect()
        
        filter["infile"] = self.m_raw_evt               
        filter["outfile"] = self.m_evtfile  
        filter["usepnt"].boolean(self.m_usepnt) # Use pointing for map centre
        filter["ra"]  = self.m_ra
        filter["dec"]  = self.m_dec
        filter["rad"]  = self.m_roi
        filter["tmin"] = self.m_tmin
        filter["tmax"] = self.m_tmax
        filter["emin"].real(self.m_emin)
        filter["emax"].real(self.m_emax)
        filter["expr"] = ""
        filter.logFileOpen()

        filter.run()
        if not(self.m_obs):
            filter.save()

        if self.m_obs:
            # Make a deep copy of the observation that will be returned
            # (the ctbin object will go out of scope one the function is
            # left)
            self.m_obs = filter.obs().copy()
Example #2
0
 def selection_run(self,
                   input_obs_list,
                   output_obs_list,
                   tmin=0,
                   tmax=None,
                   energy=[None, None],
                   prefix='selected_',
                   log_file='ctselect.log',
                   force=False,
                   save=False):
     if tmin < 0 or tmax < 1 or tmin >= tmax:
         raise Exception("ctselect needs better tmin/tmax")
     select = ctools.ctselect()
     if isinstance(input_obs_list, gammalib.GObservations):
         select.obs(input_obs_list)
     elif os.path.isfile(input_obs_list):
         # observations list from file
         select["inobs"] = input_obs_list
     else:
         raise Exception('Cannot understand input obs list for csphagen')
     select["rad"] = "INDEF"
     select["ra"] = "INDEF"
     select["dec"] = "INDEF"
     select["tmin"] = tmin
     select["tmax"] = tmax
     select["emin"] = energy[0] if energy[0] else "INDEF"
     select["emax"] = energy[1] if energy[1] else "INDEF"
     select["prefix"] = prefix
     select["outobs"] = output_obs_list
     select["logfile"] = log_file
     if force or not os.path.isfile(output_obs_list):
         select.logFileOpen()
         select.run()
     elif os.path.isfile(output_obs_list):
         basename, ext = os.path.splitext(output_obs_list)
         if ext == '.xml':
             select = ctools.ctselect(
                 gammalib.GObservations(output_obs_list))
         else:  # .fits
             container = gammalib.GObservations()
             gcta_obs = gammalib.GCTAObservation(output_obs_list)
             container.append(gcta_obs)
             select.obs(container)
     else:
         raise Exception("Cannot proceed with ctselect")
     saved = False
     if (save and force) or (save and not os.path.isfile(output_obs_list)):
         select.save()  # why it doesn't save anytime?
         saved = True
         logger.info("Files {} created.".format(output_obs_list))
     return select
Example #3
0
    def ctselect(self, log=False, debug=False):
        '''
        Create ctselect instance with given parameters
        Parameters
        ---------
        log  : save or not the log file
        debug  : debug mode or not. This will print a lot of information
        '''
        self.info("Running ctselect to cut on events")
        if self.m_obs:
            filter = ct.ctselect(self.m_obs)
        else:
            filter = ct.ctselect()  ##

            for k in self.config.keys():
                try:
                    for kk in self.config[k].keys():
                        if filter._has_par(kk):
                            filter[kk] = self.config[k][kk]
                except:
                    if filter._has_par(k):
                        filter[k] = self.config[k]

            filter["inobs"] = join(self.workdir, self.config['file']["inobs"])
            filter["outobs"] = join(self.workdir,
                                    self.config['file']["selectedevent"])
        filter.logFileOpen()

        if self.verbose:
            print filter

        # Optionally open the log file
        if log:
            filter.logFileOpen()

        # Optionally switch-on debugging model
        if debug:
            filter["debug"].boolean(True)

        filter.run()
        if not (self.m_obs):
            filter.save()

        if self.m_obs:
            # Make a deep copy of the observation that will be returned
            # (the ctbin object will go out of scope one the function is
            # left)
            self.m_obs = filter.obs().copy()
Example #4
0
    def _select_events(self, obs):
        """
        Select events within a given RoI radius

        Parameters
        ----------
        obs : `~gammalib.GObservations()`
            Observation container

        Returns
        -------
        obs : `~gammalib.GObservations()`
            Observation container
        """
        # Setup task parameters
        select = ctools.ctselect(obs)
        select['ra'] = 'UNDEF'
        select['dec'] = 'UNDEF'
        select['rad'] = self['rad'].real()
        select['tmin'] = 'UNDEF'
        select['tmax'] = 'UNDEF'
        select['emin'] = self['emin'].real()
        select['emax'] = self['emax'].real()
        select['usethres'] = 'DEFAULT'

        # Select events
        select.run()

        # Extract observation
        obs = select.obs().copy()

        # Return observation
        return obs
Example #5
0
    def ctselect(self, log=False,debug=False, **kwargs):
        '''
        Create ctselect instance with given parameters
        Parameters
        ---------
        log  : save or not the log file
        debug  : debug mode or not. This will print a lot of information
        '''
        self.info("Running ctselect to cut on events")

        self.filter = ct.ctselect()
        self._fill_app( self.filter,log=log,debug=debug, **kwargs)

        self.filter["outobs"] = join(self.outdir,self.config['file']["selectedevent"])

        if self.verbose:
            print self.filter

        self.filter.run()

        self.filter.save()
        self.info("Saved selected events to {0:s}".format(self.filter["outobs"]))

        # change the inobs (data) to the selected data set
        self.config['file']["inobs"] = self.config['file']["selectedevent"]

        del self.filter
Example #6
0
    def test_functional(self):
        """
        Test ctselect functionnality.
        """
        # Set-up ctselect
        select = ctools.ctselect()
        select["inobs"].filename(self.events_name)
        select["outobs"].filename("selected_events.fits")
        select["ra"].real(83.63)
        select["dec"].real(22.01)
        select["rad"].real(3.0)
        select["tmin"].real(0.0)
        select["tmax"].real(1800.0)
        select["emin"].real(0.1)
        select["emax"].real(100.0)

        # Run tool
        self.test_try("Run ctselect")
        try:
            select.run()
            self.test_try_success()
        except:
            self.test_try_failure("Exception occured in ctselect.")

        # Save events
        self.test_try("Save events")
        try:
            select.save()
            self.test_try_success()
        except:
            self.test_try_failure("Exception occured in saving events.")
        
        # Return
        return
Example #7
0
    def test_functional(self):
        """
        Test ctselect functionnality.
        """
        # Set-up ctselect
        select = ctools.ctselect()
        select["inobs"]  = self.events_name
        select["outobs"] = "selected_events.fits"
        select["ra"]     = 83.63
        select["dec"]    = 22.01
        select["rad"]    = 3
        select["tmin"]   = 0
        select["tmax"]   = 1800
        select["emin"]   = 0.1
        select["emax"]   = 100

        # Run tool
        self.test_try("Run ctselect")
        try:
            select.run()
            self.test_try_success()
        except:
            self.test_try_failure("Exception occured in ctselect.")

        # Save events
        self.test_try("Save events")
        try:
            select.save()
            self.test_try_success()
        except:
            self.test_try_failure("Exception occured in saving events.")

        # Return
        return
Example #8
0
 def test_unbinned_mem(self):
     """
     Test unbinned in-memory pipeline.
     """
     # Set script parameters
     model_name           = "data/crab.xml"
     caldb                = "irf"
     irf                  = "cta_dummy_irf"
     ra                   =   83.63
     dec                  =   22.01
     rad_sim              =   10.0
     tstart               =    0.0
     tstop                = 1800.0
     emin                 =    0.1
     emax                 =  100.0
     rad_select           =    3.0
 
     # Simulate events
     sim = ctools.ctobssim()
     sim["inmodel"].filename(model_name)
     sim["caldb"].string(caldb)
     sim["irf"].string(irf)
     sim["ra"].real(ra)
     sim["dec"].real(dec)
     sim["rad"].real(rad_sim)
     sim["tmin"].real(tstart)
     sim["tmax"].real(tstop)
     sim["emin"].real(emin)
     sim["emax"].real(emax)
     self.test_try("Run ctobssim")
     try:
         sim.run()
         self.test_try_success()
     except:
         self.test_try_failure("Exception occured in ctobssim.")
 
     # Select events
     select = ctools.ctselect(sim.obs())
     select["ra"].real(ra)
     select["dec"].real(dec)
     select["rad"].real(rad_select)
     select["tmin"].real(tstart)
     select["tmax"].real(tstop)
     select["emin"].real(emin)
     select["emax"].real(emax)
     self.test_try("Run ctselect")
     try:
         select.run()
         self.test_try_success()
     except:
         self.test_try_failure("Exception occured in ctselect.")
 
     # Perform maximum likelihood fitting
     like = ctools.ctlike(select.obs())
     self.test_try("Run ctlike")
     try:
         like.run()
         self.test_try_success()
     except:
         self.test_try_failure("Exception occured in ctlike.")
Example #9
0
    def _test_python(self):
        """
        Test ctselect from Python
        """
        # Set-up ctselect
        select = ctools.ctselect()
        select['inobs'] = self._events
        select['outobs'] = 'ctselect_py1.fits'
        select['ra'] = 83.63
        select['dec'] = 22.01
        select['rad'] = 3
        select['tmin'] = 0
        select['tmax'] = 1800
        select['emin'] = 0.1
        select['emax'] = 100
        select['logfile'] = 'ctselect_py1.log'
        select['chatter'] = 2

        # Run ctselect tool
        select.logFileOpen()  # Make sure we get a log file
        select.run()
        select.save()

        # Check result file
        self._check_result_file('ctselect_py1.fits')

        # Return
        return
Example #10
0
def unbinned_pipeline(duration):
    """
    Unbinned analysis pipeline.
    """
    # Set script parameters
    model_name  = "${CTOOLS}/share/models/crab.xml"
    caldb       = "prod2"
    irf         = "South_50h"
    ra          =   83.63
    dec         =   22.01
    rad_sim     =   10.0
    tstart      =    0.0
    tstop       = duration
    emin        =    0.1
    emax        =  100.0
    rad_select  =    3.0

    # Get start CPU time
    tstart = time.clock()

    # Simulate events
    sim = ctools.ctobssim()
    sim["inmodel"].filename(model_name)
    sim["caldb"].string(caldb)
    sim["irf"].string(irf)
    sim["ra"].real(ra)
    sim["dec"].real(dec)
    sim["rad"].real(rad_sim)
    sim["tmin"].real(tstart)
    sim["tmax"].real(tstop)
    sim["emin"].real(emin)
    sim["emax"].real(emax)
    sim.run()

    # Select events
    select = ctools.ctselect(sim.obs())
    select["ra"].real(ra)
    select["dec"].real(dec)
    select["rad"].real(rad_select)
    select["tmin"].real(tstart)
    select["tmax"].real(tstop)
    select["emin"].real(emin)
    select["emax"].real(emax)
    select.run()

    # Get ctlike start CPU time
    tctlike = time.clock()

    # Perform maximum likelihood fitting
    like = ctools.ctlike(select.obs())
    like.run()

    # Get stop CPU time
    tstop    = time.clock()
    telapsed = tstop - tstart
    tctlike  = tstop - tctlike
	
    # Return
    return telapsed, tctlike
Example #11
0
def unbinned_pipeline(model_name, duration):
    """
    Unbinned analysis pipeline.
    """
    # Set script parameters
    caldb       = "prod2"
    irf         = "South_50h"
    ra          =   83.63
    dec         =   22.01
    rad_sim     =   10.0
    tstart      =    0.0
    tstop       = duration
    emin        =    0.1
    emax        =  100.0
    rad_select  =    3.0

    # Get start CPU time
    cpu_start = time.clock()

    # Simulate events
    sim = ctools.ctobssim()
    sim["inmodel"] = model_name
    sim["caldb"]   = caldb
    sim["irf"]     = irf
    sim["ra"]      = ra
    sim["dec"]     = dec
    sim["rad"]     = rad_sim
    sim["tmin"]    = tstart
    sim["tmax"]    = tstop
    sim["emin"]    = emin
    sim["emax"]    = emax
    sim.run()

    # Select events
    select = ctools.ctselect(sim.obs())
    select["ra"]   = ra
    select["dec"]  = dec
    select["rad"]  = rad_select
    select["tmin"] = tstart
    select["tmax"] = tstop
    select["emin"] = emin
    select["emax"] = emax
    select.run()

    # Get ctlike start CPU time
    cpu_ctlike = time.clock()

    # Perform maximum likelihood fitting
    like = ctools.ctlike(select.obs())
    like.run()

    # Get stop CPU time and compute elapsed times
    cpu_stop    = time.clock()
    cpu_elapsed = cpu_stop - cpu_start
    cpu_ctlike  = cpu_stop - cpu_ctlike

    # Return
    return cpu_elapsed, cpu_ctlike
def unbinned_pipeline(model_name, duration):
    """
    Unbinned analysis pipeline.
    """
    # Set script parameters
    caldb = "prod2"
    irf = "South_50h"
    ra = 83.63
    dec = 22.01
    rad_sim = 10.0
    tstart = 0.0
    tstop = duration
    emin = 0.1
    emax = 100.0
    rad_select = 3.0

    # Get start CPU time
    cpu_start = time.clock()

    # Simulate events
    sim = ctools.ctobssim()
    sim["inmodel"] = model_name
    sim["caldb"] = caldb
    sim["irf"] = irf
    sim["ra"] = ra
    sim["dec"] = dec
    sim["rad"] = rad_sim
    sim["tmin"] = tstart
    sim["tmax"] = tstop
    sim["emin"] = emin
    sim["emax"] = emax
    sim.run()

    # Select events
    select = ctools.ctselect(sim.obs())
    select["ra"] = ra
    select["dec"] = dec
    select["rad"] = rad_select
    select["tmin"] = tstart
    select["tmax"] = tstop
    select["emin"] = emin
    select["emax"] = emax
    select.run()

    # Get ctlike start CPU time
    cpu_ctlike = time.clock()

    # Perform maximum likelihood fitting
    like = ctools.ctlike(select.obs())
    like.run()

    # Get stop CPU time and compute elapsed times
    cpu_stop = time.clock()
    cpu_elapsed = cpu_stop - cpu_start
    cpu_ctlike = cpu_stop - cpu_ctlike

    # Return
    return cpu_elapsed, cpu_ctlike
def run_pipeline(obs,
                 ra=83.63,
                 dec=22.01,
                 rad=3.0,
                 emin=0.1,
                 emax=100.0,
                 tmin=0.0,
                 tmax=0.0,
                 debug=False):
    """
    Simulation and binned analysis pipeline

    Parameters
    ----------
    obs : `~gammalib.GObservations`
        Observation container
    ra : float, optional
        Right Ascension of Region of Interest centre (deg)
    dec : float, optional
        Declination of Region of Interest centre (deg)
    rad : float, optional
        Radius of Region of Interest (deg)
    emin : float, optional
        Minimum energy (TeV)
    emax : float, optional
        Maximum energy (TeV)
    tmin : float, optional
        Start time (s)
    tmax : float, optional
        Stop time (s)
    debug : bool, optional
        Debug function
    """
    # Simulate events
    sim = ctools.ctobssim(obs)
    sim['debug'] = debug
    sim.run()

    # Select events
    select = ctools.ctselect(sim.obs())
    select['ra'] = ra
    select['dec'] = dec
    select['rad'] = rad
    select['emin'] = emin
    select['emax'] = emax
    select['tmin'] = tmin
    select['tmax'] = tmax
    select['debug'] = debug
    select.run()

    # Perform maximum likelihood fitting
    like = ctools.ctlike(select.obs())
    like['debug'] = True  # Switch this always on for results in console
    like.run()

    # Return
    return
Example #14
0
    def test_unbinned_fits(self):
        """
        Test unbinned pipeline with FITS file saving
        """
        # Set script parameters
        events_name          = 'events.fits'
        selected_events_name = 'selected_events.fits'
        result_name          = 'results.xml'
        ra                   =   83.63
        dec                  =   22.01
        rad_sim              =    3.0
        rad_select           =    2.0
        tstart               =    0.0
        tstop                =  300.0
        emin                 =    1.0
        emax                 =  100.0

        # Simulate events
        sim = ctools.ctobssim()
        sim['inmodel']   = self._model
        sim['outevents'] = events_name
        sim['caldb']     = self._caldb
        sim['irf']       = self._irf
        sim['ra']        = ra
        sim['dec']       = dec
        sim['rad']       = rad_sim
        sim['tmin']      = tstart
        sim['tmax']      = tstop
        sim['emin']      = emin
        sim['emax']      = emax
        sim.execute()

        # Select events
        select = ctools.ctselect()
        select['inobs']  = events_name
        select['outobs'] = selected_events_name
        select['ra']     = ra
        select['dec']    = dec
        select['rad']    = rad_select
        select['tmin']   = tstart
        select['tmax']   = tstop
        select['emin']   = emin
        select['emax']   = emax
        select.execute()

        # Perform maximum likelihood fitting
        like = ctools.ctlike()
        like['inobs']    = selected_events_name
        like['inmodel']  = self._model
        like['outmodel'] = result_name
        like['caldb']    = self._caldb
        like['irf']      = self._irf
        like.execute()

        # Return
        return
Example #15
0
    def test_unbinned_fits(self):
        """
        Test unbinned pipeline with FITS file saving
        """
        # Set script parameters
        events_name          = 'events.fits'
        selected_events_name = 'selected_events.fits'
        result_name          = 'results.xml'
        ra                   =   83.63
        dec                  =   22.01
        rad_sim              =   10.0
        rad_select           =    3.0
        tstart               =    0.0
        tstop                =  300.0
        emin                 =    0.1
        emax                 =  100.0

        # Simulate events
        sim = ctools.ctobssim()
        sim['inmodel']   = self._model
        sim['outevents'] = events_name
        sim['caldb']     = self._caldb
        sim['irf']       = self._irf
        sim['ra']        = ra
        sim['dec']       = dec
        sim['rad']       = rad_sim
        sim['tmin']      = tstart
        sim['tmax']      = tstop
        sim['emin']      = emin
        sim['emax']      = emax
        sim.execute()

        # Select events
        select = ctools.ctselect()
        select['inobs']  = events_name
        select['outobs'] = selected_events_name
        select['ra']     = ra
        select['dec']    = dec
        select['rad']    = rad_select
        select['tmin']   = tstart
        select['tmax']   = tstop
        select['emin']   = emin
        select['emax']   = emax
        select.execute()

        # Perform maximum likelihood fitting
        like = ctools.ctlike()
        like['inobs']    = selected_events_name
        like['inmodel']  = self._model
        like['outmodel'] = result_name
        like['caldb']    = self._caldb
        like['irf']      = self._irf
        like.execute()

        # Return
        return
Example #16
0
def run_pipeline(obs, ra=83.63, dec=22.01, rad=3.0,
                 emin=0.1, emax=100.0,
                 tmin=0.0, tmax=0.0,
                 model="${CTOOLS}/share/models/crab.xml",
                 caldb="prod2", irf="South_50h",
                 debug=False):
    """
    Simulation and unbinned analysis pipeline.

    Keywords:
     ra    - RA of cube centre [deg] (default: 83.63)
     dec   - DEC of cube centre [deg] (default: 22.01)
     rad   - Selection radius [deg] (default: 3.0)
     emin  - Minimum energy of cube [TeV] (default: 0.1)
     emax  - Maximum energy of cube [TeV] (default: 100.0)
     tmin  - Start time [MET] (default: 0.0)
     tmax  - Stop time [MET] (default: 0.0)
     model - Model Xml file
     caldb - Calibration database path (default: "dummy")
     irf   - Instrument response function (default: cta_dummy_irf)
     debug - Enable debugging (default: False)
    """
    # Get model

    # Simulate events
    sim = ctools.ctobssim(obs)
    sim["debug"]     = debug
    sim["outevents"] = "obs.xml"
    sim.execute()

    # Select events
    select = ctools.ctselect()
    select["inobs"]  = "obs.xml"
    select["outobs"] = "obs_selected.xml"
    select["ra"]     = ra
    select["dec"]    = dec
    select["rad"]    = rad
    select["emin"]   = emin
    select["emax"]   = emax
    select["tmin"]   = tmin
    select["tmax"]   = tmax
    select["debug"]  = debug
    select.execute()

    # Perform maximum likelihood fitting
    like = ctools.ctlike()
    like["inobs"]    = "obs_selected.xml"
    like["inmodel"]  = model
    like["outmodel"] = "fit_results.xml"
    like["caldb"]    = caldb
    like["irf"]      = irf
    like["debug"]    = True # Switch this always on for results in console
    like.execute()

    # Return
    return
Example #17
0
 def ctselect(self, RA, DEC):
     select = ctools.ctselect()
     select["inobs"] = 'events.fits'
     select["outobs"] = 'selected_events.fits'
     select["ra"] = RA
     select["dec"] = DEC
     select["rad"] = 5
     select["tmin"] = '2020-01-01T00:00:00'
     select["tmax"] = '2020-01-01T01:00:00'
     select["emin"] = 0.3
     select["emax"] = 150.0
     select.run()
     select.save()
Example #18
0
    def test_unbinned_mem(self):
        """
        Test unbinned in-memory pipeline
        """
        # Set script parameters
        ra         =   83.63
        dec        =   22.01
        rad_sim    =    3.0
        rad_select =    2.0
        tstart     =    0.0
        tstop      =  300.0
        emin       =    1.0
        emax       =  100.0

        # Simulate events
        sim = ctools.ctobssim()
        sim['inmodel'] = self._model
        sim['caldb']   = self._caldb
        sim['irf']     = self._irf
        sim['ra']      = ra
        sim['dec']     = dec
        sim['rad']     = rad_sim
        sim['tmin']    = tstart
        sim['tmax']    = tstop
        sim['emin']    = emin
        sim['emax']    = emax
        sim.run()

        # Select events
        select = ctools.ctselect(sim.obs())
        select['ra']   = ra
        select['dec']  = dec
        select['rad']  = rad_select
        select['tmin'] = tstart
        select['tmax'] = tstop
        select['emin'] = emin
        select['emax'] = emax
        select.run()

        # Perform maximum likelihood fitting
        like = ctools.ctlike(select.obs())
        like.run()

        # Return
        return
Example #19
0
    def test_unbinned_mem(self):
        """
        Test unbinned in-memory pipeline
        """
        # Set script parameters
        ra         =   83.63
        dec        =   22.01
        rad_sim    =   10.0
        rad_select =    3.0
        tstart     =    0.0
        tstop      =  300.0
        emin       =    0.1
        emax       =  100.0

        # Simulate events
        sim = ctools.ctobssim()
        sim['inmodel'] = self._model
        sim['caldb']   = self._caldb
        sim['irf']     = self._irf
        sim['ra']      = ra
        sim['dec']     = dec
        sim['rad']     = rad_sim
        sim['tmin']    = tstart
        sim['tmax']    = tstop
        sim['emin']    = emin
        sim['emax']    = emax
        sim.run()

        # Select events
        select = ctools.ctselect(sim.obs())
        select['ra']   = ra
        select['dec']  = dec
        select['rad']  = rad_select
        select['tmin'] = tstart
        select['tmax'] = tstop
        select['emin'] = emin
        select['emax'] = emax
        select.run()

        # Perform maximum likelihood fitting
        like = ctools.ctlike(select.obs())
        like.run()

        # Return
        return
Example #20
0
def run_pipeline(obs, ra=83.63, dec=22.01, rad=3.0, \
                 emin=0.1, emax=100.0, \
                 tmin=0.0, tmax=0.0, \
                 debug=False):
    """
    Simulation and unbinned analysis pipeline.

    Keywords:
     ra    - RA of cube centre [deg] (default: 83.63)
     dec   - DEC of cube centre [deg] (default: 22.01)
     rad   - Selection radius [deg] (default: 3.0)
     emin  - Minimum energy of cube [TeV] (default: 0.1)
     emax  - Maximum energy of cube [TeV] (default: 100.0)
     tmin  - Start time [MET] (default: 0.0)
     tmax  - Stop time [MET] (default: 0.0)
     debug - Enable debugging (default: False)
    """
    # Simulate events
    sim = ctools.ctobssim(obs)
    sim["debug"].boolean(debug)
    sim.run()

    # Select events
    select = ctools.ctselect(sim.obs())
    select["ra"].real(ra)
    select["dec"].real(dec)
    select["rad"].real(rad)
    select["emin"].real(emin)
    select["emax"].real(emax)
    select["tmin"].real(tmin)
    select["tmax"].real(tmax)
    select["debug"].boolean(debug)
    select.run()

    # Perform maximum likelihood fitting
    like = ctools.ctlike(select.obs())
    like["debug"].boolean(True) # Switch this always on for results in console
    like.run()
	
    # Return
    return
Example #21
0
def select_events(events_file, selected_file, tmax=100, force=0):
    if tmax < 1:
        print("need tmax > 0 to select events")
        exit(1)
    log_file = os.path.join(os.path.dirname(selected_file),
                            "ctselect_" + str(tmax) + ".log")
    if not os.path.isfile(selected_file) or force == 1:
        select = ctools.ctselect()
        select.clear()
        select["inobs"] = events_file
        select["rad"] = "INDEF"
        select["tmin"] = 0
        select["tmax"] = tmax
        select["emin"] = "INDEF"
        select["emax"] = "INDEF"
        select["outobs"] = selected_file
        select["logfile"] = log_file
        select.logFileOpen()
        select.run()
        select.save()
        sys.stderr.write("File '%s' created.\n" % selected_file)
    return True
def select_events(obs, emin='UNDEF', emax='UNDEF', rad=2.0):
    """
    Select events within a given RoI radius

    Parameters
    ----------
    obs : `~gammalib.GObservations`
        Observation container
    emin : float, optional
        Minimum energy (TeV)
    emax : float, optional
        Maximum energy (TeV)
    rad : float, optional
        Radial selection radius (deg)

    Returns
    -------
    obs : `~gammalib.GObservations`
        Observation container
    """
    # Setup task parameters
    select = ctools.ctselect(obs)
    select['ra'] = 'UNDEF'
    select['dec'] = 'UNDEF'
    select['rad'] = rad
    select['tmin'] = 'UNDEF'
    select['tmax'] = 'UNDEF'
    select['emin'] = emin
    select['emax'] = emax
    select['usethres'] = 'DEFAULT'

    # Select events
    select.run()

    # Extract observation
    obs = select.obs().copy()

    # Return observation
    return obs
Example #23
0
def selectData(cfg):
    """
    Select data with ctselect
    """
    outputdir = cfg.getValue('general', 'outputdir')
    select = ctools.ctselect()
    select["inobs"] = outputdir + '/' + cfg.getValue('csiactobs', 'obs_output')
    select["outobs"] = outputdir + '/' + cfg.getValue('ctselect', 'output')
    select["ra"] = cfg.getValue('model', 'coords', 'ra')
    select["dec"] = cfg.getValue('model', 'coords', 'dec')
    select["rad"] = cfg.getValue('ctselect', 'radius')
    select["emin"] = cfg.getValue('ctselect', 'emin')
    select["emax"] = cfg.getValue('ctselect', 'emax')
    select["tmin"] = cfg.getValue('ctselect', 'tmin')
    select["tmax"] = cfg.getValue('ctselect', 'tmax')
    select["usethres"] = cfg.getValue('ctselect', 'usethres')
    if cfg.getValue('general', 'debug') is True:
        select["debug"] = True

    #select["prefix"] = outputdir + '/' + 'selected_'
    select.run()
    select.save()

    os.system("mv selected_events_*.fits " + outputdir + "/.")
def phase_events(name, lon, lat, rad=0.2, lc=True):
    """
    Phase events

    Parameters
    ----------
    name : string
        Source name
    lon : float
        Galactic longitude of binary (deg)
    lat : float
        Galactic latitude of binary (deg)
    rad : float, optional
        Angular cut (deg)
    lc : bool, optional
        Use light curve
    """
    # Dump header
    print('Phase events')

    # Enter working directory
    cwd = enter_wd(name)

    # Set filenames
    if lc:
        suffix = ''
    else:
        suffix = '_const'
    inxml = 'gps_obs_simulated%s.xml' % (suffix)
    outxml = 'gps_obs_phased%s.xml' % (suffix)
    prefix = 'phased%s/' % (suffix)
    outxml2 = 'gps_obs_selected_phased%s.xml' % (suffix)
    prefix2 = 'selected_phased%s/' % (suffix)

    # Continue only if phased events do not exist
    if not os.path.isfile(outxml):

        # Create directory
        try:
            os.makedirs('phased%s' % suffix)
        except:
            pass

        # Setup task parameters
        phase = ctools.ctphase()
        phase['inobs'] = inxml
        phase['outobs'] = outxml
        phase['prefix'] = prefix
        phase['inmodel'] = 'gps_models.xml'
        phase['srcname'] = name
        phase.logFileOpen()

        # Phase events
        phase.execute()

    # Continue only if selected phased events do not exist
    if not os.path.isfile(outxml2):

        # Create directory
        try:
            os.makedirs('selected_phased%s' % suffix)
        except:
            pass

        # Set source position
        dir = gammalib.GSkyDir()
        dir.lb_deg(lon, lat)

        # Setup task parameters
        select = ctools.ctselect()
        select['inobs'] = outxml
        select['outobs'] = outxml2
        select['prefix'] = prefix2
        select['usepnt'] = False
        select['ra'] = dir.ra_deg()
        select['dec'] = dir.dec_deg()
        select['rad'] = rad
        select['emin'] = 'NONE'
        select['emax'] = 'NONE'
        select['tmin'] = 'NONE'
        select['tmax'] = 'NONE'
        select.logFileOpen()

        # Select events
        select.execute()

    # Exit working directory
    exit_wd(cwd)

    # Return
    return
Example #25
0
    plt.title(r'Gamma-Ray Annihilation Spectrum: $m_{\chi}$ = %s' %
              str(dm_mass))
    plt.xlabel(r'Energy $\left \{ log_{10} \mathrm{TeV} \right \}$')
    plt.ylabel(
        r'$\frac{dN}{dE} \left \{ \frac{1}{s*cm^{2}*\mathrm{TeV}} \right \}$')
    plt.xscale('log')
    plt.yscale('log')
    plt.ylim([ymin, ymax])
    plt.savefig('logs/spec.png', dpi=100)
    plt.clf()

halo_fits_tot_jfactor = veripy.read_halo_jfactor_fits(halo_fits)

print(get_time(), 'starting ctselect')
t3 = time.time()
sel = ctools.ctselect(obs)
sel['usepnt'] = True
sel['ra'] = sgra.ra_deg()  # 'NONE'
sel['dec'] = sgra.dec_deg()  # 'NONE'
sel['rad'] = span / 2  # 'NONE'
sel['tmin'] = 0.0
sel['tmax'] = 0.0
sel['emin'] = emin
sel['emax'] = emax
sel['logfile'] = 'logs/ctselect.log'
sel.logFileOpen()
sel.run()
sel.logFileClose()
t4 = time.time()
printstat('%.1f seconds to run ctselect' % (t4 - t3))
Example #26
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
Example #27
0
 def test_unbinned_fits(self):
     """
     Test unbinned pipeline with FITS file saving.
     """
     # Set script parameters
     model_name           = "data/crab.xml"
     events_name          = "events.fits"
     selected_events_name = "selected_events.fits"
     result_name          = "results.xml"
     caldb                = "irf"
     irf                  = "cta_dummy_irf"
     ra                   =   83.63
     dec                  =   22.01
     rad_sim              =   10.0
     tstart               =    0.0
     tstop                = 1800.0
     emin                 =    0.1
     emax                 =  100.0
     rad_select           =    3.0
 
     # Simulate events
     sim = ctools.ctobssim()
     sim["inmodel"].filename(model_name)
     sim["outevents"].filename(events_name)
     sim["caldb"].string(caldb)
     sim["irf"].string(irf)
     sim["ra"].real(ra)
     sim["dec"].real(dec)
     sim["rad"].real(rad_sim)
     sim["tmin"].real(tstart)
     sim["tmax"].real(tstop)
     sim["emin"].real(emin)
     sim["emax"].real(emax)
     self.test_try("Execute ctobssim")
     try:
         sim.execute()
         self.test_try_success()
     except:
         self.test_try_failure("Exception occured in ctobssim.")
 
     # Select events
     select = ctools.ctselect()
     select["inobs"].filename(events_name)
     select["outobs"].filename(selected_events_name)
     select["ra"].real(ra)
     select["dec"].real(dec)
     select["rad"].real(rad_select)
     select["tmin"].real(tstart)
     select["tmax"].real(tstop)
     select["emin"].real(emin)
     select["emax"].real(emax)
     self.test_try("Execute ctselect")
     try:
         select.execute()
         self.test_try_success()
     except:
         self.test_try_failure("Exception occured in ctselect.")
 
     # Perform maximum likelihood fitting
     like = ctools.ctlike()
     like["inobs"].filename(selected_events_name)
     like["inmodel"].filename(model_name)
     like["outmodel"].filename(result_name)
     like["caldb"].string(caldb)
     like["irf"].string(irf)
     self.test_try("Execute ctlike")
     try:
         like.execute()
         self.test_try_success()
     except:
         self.test_try_failure("Exception occured in ctlike.")
def run_pipeline(obs, ra=83.63, dec=22.01, rad=3.0,
                 emin=0.1, emax=100.0,
                 tmin=0.0, tmax=0.0,
                 model='data/crab.xml',
                 caldb='prod2', irf='South_0.5h',
                 debug=False):
    """
    Simulation and unbinned analysis pipeline

    Parameters
    ----------
    obs : `~gammalib.GObservations`
        Observation container
    ra : float, optional
        Right Ascension of Region of Interest centre (deg)
    dec : float, optional
        Declination of Region of Interest centre (deg)
    rad : float, optional
        Radius of Region of Interest (deg)
    emin : float, optional
        Minimum energy (TeV)
    emax : float, optional
        Maximum energy (TeV)
    tmin : float, optional
        Start time (s)
    tmax : float, optional
        Stop time (s)
    model : str, optional
        Model definition XML file
    caldb : str, optional
        Calibration database path
    irf : str, optional
        Instrument response function
    debug : bool, optional
        Debug function
    """
    # Get model

    # Simulate events
    sim = ctools.ctobssim(obs)
    sim['debug']     = debug
    sim['outevents'] = 'obs.xml'
    sim.execute()

    # Select events
    select = ctools.ctselect()
    select['inobs']  = 'obs.xml'
    select['outobs'] = 'obs_selected.xml'
    select['ra']     = ra
    select['dec']    = dec
    select['rad']    = rad
    select['emin']   = emin
    select['emax']   = emax
    select['tmin']   = tmin
    select['tmax']   = tmax
    select['debug']  = debug
    select.execute()

    # Perform maximum likelihood fitting
    like = ctools.ctlike()
    like['inobs']    = 'obs_selected.xml'
    like['inmodel']  = model
    like['outmodel'] = 'fit_results.xml'
    like['caldb']    = caldb
    like['irf']      = irf
    like['debug']    = True # Switch this always on for results in console
    like.execute()

    # Return
    return
def grb_simulation(sim_in, config_in, model_xml, fits_header_0, counter):
    """
    Function to handle the GRB simulation.
    :param sim_in: the yaml file for the simulation (unpacked as a dict of dicts)
    :param config_in: the yaml file for the job handling (unpacked as a dict of dicts)
    :param model_xml: the XML model name for the source under analysis
    :param fits_header_0: header for the fits file of the GRB model to use. Used in the visibility calculation
    :param counter: integer number. counts the id of the source realization
    :return: significance obtained with the activated detection methods
    """

    src_name = model_xml.split('/')[-1].split('model_')[1][:-4]
    print(src_name, counter)

    ctools_pipe_path = create_path(config_in['exe']['software_path'])
    ctobss_params = sim_in['ctobssim']

    seed = int(counter)*10

    # PARAMETERS FROM THE CTOBSSIM
    sim_t_min = u.Quantity(ctobss_params['time']['t_min']).to_value(u.s)
    sim_t_max = u.Quantity(ctobss_params['time']['t_max']).to_value(u.s)
    sim_e_min = u.Quantity(ctobss_params['energy']['e_min']).to_value(u.TeV)
    sim_e_max = u.Quantity(ctobss_params['energy']['e_max']).to_value(u.TeV)
    sim_rad = ctobss_params['radius']

    models = sim_in['source']
    source_type = models['type']

    if source_type == "GRB":
        phase_path = "/" + models['phase']
    elif source_type == "GW":
        phase_path = ""

    output_path = create_path(sim_in['output']['path'] + phase_path + '/' + src_name)

    save_simulation = ctobss_params['save_simulation']

    with open(f"{output_path}/GRB-{src_name}_seed-{seed}.txt", "w") as f:
        f.write(f"GRB,seed,time_start,time_end,sigma_lima,sqrt_TS_onoff,sqrt_TS_std\n")
        # VISIBILITY PART
        # choose between AUTO mode (use visibility) and MANUAL mode (manually insert IRF)
        simulation_mode = sim_in['IRF']['mode']

        if simulation_mode == "auto":
            print("using visibility to get IRFs")

            # GRB information from the fits header
            ra = fits_header_0['RA']
            dec = fits_header_0['DEC']
            t0 = Time(fits_header_0['GRBJD'])

            irf_dict = sim_in['IRF']
            site = irf_dict['site']
            obs_condition = Observability(site=site)
            obs_condition.set_irf(irf_dict)

            t_zero_mode = ctobss_params['time']['t_zero'].lower()

            if t_zero_mode == "VIS":
                # check if the source is visible one day after the onset of the source
                print("time starts when source becomes visible")
                obs_condition.Proposal_obTime = 86400
                condition_check = obs_condition.check(RA=ra, DEC=dec, t_start=t0)

            elif t_zero_mode == "ONSET":
                print("time starts from the onset of the GRB")
                condition_check = obs_condition.check(RA=ra, DEC=dec, t_start=t0, t_min=sim_t_min, t_max=sim_t_max)

            else:
                print(f"Choose some proper mode between 'VIS' and 'ONSET'. {t_zero_mode} is not a valid one.")
                sys.exit()

            # NO IRF in AUTO mode ==> No simulation! == EXIT!
            if len(condition_check) == 0:
                f.write(f"{src_name},{seed}, -1, -1, -1, -1, -1\n")
                sys.exit()

        elif simulation_mode == "manual":
            print("manual picking IRF")

            # find proper IRF name
            irf = IRFPicker(sim_in, ctools_pipe_path)
            name_irf = irf.irf_pick()

            backgrounds_path = create_path(ctobss_params['bckgrnd_path'])
            fits_background_list = glob.glob(
                f"{backgrounds_path}/{irf.prod_number}_{irf.prod_version}_{name_irf}/background*.fits")

            if len(fits_background_list) == 0:
                print(f"No background for IRF {name_irf}")
                sys.exit()

            fits_background_list = sorted(fits_background_list, key=sort_background)
            background_fits = fits_background_list[int(counter) - 1]
            obs_back = gammalib.GCTAObservation(background_fits)

        else:
            print(f"wrong input for IRF - mode. Input is {simulation_mode}. Use 'auto' or 'manual' instead")
            sys.exit()

        if irf.prod_number == "3b" and irf.prod_version == 0:
            caldb = "prod3b"
        else:
            caldb = f'prod{irf.prod_number}-v{irf.prod_version}'

        # source simulation
        sim = ctools.ctobssim()
        sim['inmodel'] = model_xml
        sim['caldb'] = caldb
        sim['irf'] = name_irf
        sim['ra'] = 0.0
        sim['dec'] = 0.0
        sim['rad'] = sim_rad
        sim['tmin'] = sim_t_min
        sim['tmax'] = sim_t_max
        sim['emin'] = sim_e_min
        sim['emax'] = sim_e_max
        sim['seed'] = seed
        sim.run()

        obs = sim.obs()

        # # move the source photons from closer to (RA,DEC)=(0,0), where the background is located
        # for event in obs[0].events():
        #     # ra_evt = event.dir().dir().ra()
        #     dec_evt = event.dir().dir().dec()
        #     ra_evt_deg = event.dir().dir().ra_deg()
        #     dec_evt_deg = event.dir().dir().dec_deg()
        #
        #     ra_corrected = (ra_evt_deg - ra_pointing)*np.cos(dec_evt)
        #     dec_corrected = dec_evt_deg - dec_pointing
        #     event.dir().dir().radec_deg(ra_corrected, dec_corrected)

        # append all background events to GRB ones ==> there's just one observation and not two
        for event in obs_back.events():
            obs[0].events().append(event)

        # ctselect to save data on disk
        if save_simulation:
            event_list_path = create_path(f"{ctobss_params['output_path']}/{src_name}/")
            #obs.save(f"{event_list_path}/event_list_source-{src_name}_seed-{seed:03}.fits")

            select_time = ctools.ctselect(obs)
            select_time['rad'] = sim_rad
            select_time['tmin'] = sim_t_min
            select_time['tmax'] = sim_t_max
            select_time['emin'] = sim_e_min
            select_time['emax'] = sim_e_max
            select_time['outobs'] = f"{event_list_path}/event_list_source-{src_name}_{seed:03}.fits"
            select_time.run()
            sys.exit()

        # delete all 70+ models from the obs def file...not needed any more
        obs.models(gammalib.GModels())

        # CTSELECT
        select_time = sim_in['ctselect']['time_cut']
        slices = int(select_time['t_slices'])

        if slices == 0:
            times = [sim_t_min, sim_t_max]
            times_start = times[:-1]
            times_end = times[1:]
        elif slices > 0:
            time_mode = select_time['mode']
            if time_mode == "log":
                times = np.logspace(np.log10(sim_t_min), np.log10(sim_t_max), slices + 1, endpoint=True)
            elif time_mode == "lin":
                times = np.linspace(sim_t_min, sim_t_max, slices + 1, endpoint=True)
            else:
                print(f"{time_mode} not valid. Use 'log' or 'lin' ")
                sys.exit()

            if select_time['obs_mode'] == "iter":
                times_start = times[:-1]
                times_end = times[1:]
            elif select_time['obs_mode'] == "cumul":
                times_start = np.repeat(times[0], slices)         # this is to use the same array structure for the loop
                times_end = times[1:]
            elif select_time['obs_mode'] == "all":
                begins, ends = np.meshgrid(times[:-1], times[1:])
                mask_times = begins < ends
                times_start = begins[mask_times].ravel()
                times_end = ends[mask_times].ravel()
            else:
                print(f"obs_mode: {select_time['obs_mode']} not supported")
                sys.exit()

        else:
            print(f"value {slices} not supported...check yaml file")
            sys.exit()

        # ------------------------------------
        # ----- TIME LOOP STARTS HERE --------
        # ------------------------------------

        ctlike_mode = sim_in['detection']
        mode_1 = ctlike_mode['counts']
        mode_2 = ctlike_mode['ctlike-onoff']
        mode_3 = ctlike_mode['ctlike-std']

        for t_in, t_end in zip(times_start, times_end):
            sigma_onoff = 0
            sqrt_ts_like_onoff = 0
            sqrt_ts_like_std = 0
            print("-----------------------------")
            print(f"t_in: {t_in:.2f}, t_end: {t_end:.2f}")

            # different ctlikes (onoff or std) need different files.
            # will be appended here and used later on for the final likelihood
            dict_obs_select_time = {}

            # perform time selection for this specific time bin
            select_time = ctools.ctselect(obs)
            select_time['rad'] = sim_rad
            select_time['tmin'] = t_in
            select_time['tmax'] = t_end
            select_time['emin'] = sim_e_min
            select_time['emax'] = sim_e_max
            select_time.run()

            if mode_1:
                fits_temp_title = f"skymap_{seed}_{t_in:.2f}_{t_end:.2f}.fits"
                pars_counts = ctlike_mode['pars_counts']
                scale = float(pars_counts['scale'])
                npix = 2*int(sim_rad/scale)
                skymap = ctools.ctskymap(select_time.obs().copy())
                skymap['emin'] = sim_e_min
                skymap['emax'] = sim_e_max
                skymap['nxpix'] = npix
                skymap['nypix'] = npix
                skymap['binsz'] = scale
                skymap['proj'] = 'TAN'
                skymap['coordsys'] = 'CEL'
                skymap['xref'] = 0
                skymap['yref'] = 0
                skymap['bkgsubtract'] = 'RING'
                skymap['roiradius'] = pars_counts['roiradius']
                skymap['inradius'] = pars_counts['inradius']
                skymap['outradius'] = pars_counts['outradius']
                skymap['iterations'] = pars_counts['iterations']
                skymap['threshold'] = pars_counts['threshold']
                skymap['outmap'] = fits_temp_title
                skymap.execute()

                input_fits = fits.open(fits_temp_title)
                datain = input_fits[2].data
                datain[np.isnan(datain)] = 0.0
                datain[np.isinf(datain)] = 0.0

                sigma_onoff = np.max(datain)
                os.remove(fits_temp_title)

            if mode_3:
                dict_obs_select_time['std'] = select_time.obs().copy()

            if mode_2:
                onoff_time_sel = cscripts.csphagen(select_time.obs().copy())
                onoff_time_sel['inmodel'] = 'NONE'
                onoff_time_sel['ebinalg'] = 'LOG'
                onoff_time_sel['emin'] = sim_e_min
                onoff_time_sel['emax'] = sim_e_max
                onoff_time_sel['enumbins'] = 30
                onoff_time_sel['coordsys'] = 'CEL'
                onoff_time_sel['ra'] = 0.0
                onoff_time_sel['dec'] = 0.5
                onoff_time_sel['rad'] = 0.2
                onoff_time_sel['bkgmethod'] = 'REFLECTED'
                onoff_time_sel['use_model_bkg'] = False
                onoff_time_sel['stack'] = False
                onoff_time_sel.run()

                dict_obs_select_time['onoff'] = onoff_time_sel.obs().copy()

                del onoff_time_sel

                # print(f"sigma ON/OFF: {sigma_onoff:.2f}")

            if mode_2 or mode_3:

                # Low Energy PL fitting
                # to be saved in this dict
                dict_pl_ctlike_out = {}

                e_min_pl_ctlike = 0.030
                e_max_pl_ctlike = 0.080

                # simple ctobssim copy and select for ctlike-std
                select_pl_ctlike = ctools.ctselect(select_time.obs().copy())
                select_pl_ctlike['rad'] = 3
                select_pl_ctlike['tmin'] = t_in
                select_pl_ctlike['tmax'] = t_end
                select_pl_ctlike['emin'] = e_min_pl_ctlike
                select_pl_ctlike['emax'] = e_max_pl_ctlike
                select_pl_ctlike.run()

                # create test source
                src_dir = gammalib.GSkyDir()
                src_dir.radec_deg(0, 0.5)
                spatial = gammalib.GModelSpatialPointSource(src_dir)

                # create and append source spectral model
                spectral = gammalib.GModelSpectralPlaw()
                spectral['Prefactor'].value(5.5e-16)
                spectral['Prefactor'].scale(1e-16)
                spectral['Index'].value(-2.6)
                spectral['Index'].scale(-1.0)
                spectral['PivotEnergy'].value(50000)
                spectral['PivotEnergy'].scale(1e3)
                model_src = gammalib.GModelSky(spatial, spectral)
                model_src.name('PL_fit_temp')
                model_src.tscalc(True)

                spectral_back = gammalib.GModelSpectralPlaw()
                spectral_back['Prefactor'].value(1.0)
                spectral_back['Prefactor'].scale(1.0)
                spectral_back['Index'].value(0)
                spectral_back['PivotEnergy'].value(300000)
                spectral_back['PivotEnergy'].scale(1e6)

                if mode_2:
                    back_model = gammalib.GCTAModelIrfBackground()
                    back_model.instruments('CTAOnOff')
                    back_model.name('Background')
                    back_model.spectral(spectral_back.copy())

                    onoff_pl_ctlike_lima = cscripts.csphagen(select_pl_ctlike.obs().copy())
                    onoff_pl_ctlike_lima['inmodel'] = 'NONE'
                    onoff_pl_ctlike_lima['ebinalg'] = 'LOG'
                    onoff_pl_ctlike_lima['emin'] = e_min_pl_ctlike
                    onoff_pl_ctlike_lima['emax'] = e_max_pl_ctlike
                    onoff_pl_ctlike_lima['enumbins'] = 30
                    onoff_pl_ctlike_lima['coordsys'] = 'CEL'
                    onoff_pl_ctlike_lima['ra'] = 0.0
                    onoff_pl_ctlike_lima['dec'] = 0.5
                    onoff_pl_ctlike_lima['rad'] = 0.2
                    onoff_pl_ctlike_lima['bkgmethod'] = 'REFLECTED'
                    onoff_pl_ctlike_lima['use_model_bkg'] = False
                    onoff_pl_ctlike_lima['stack'] = False
                    onoff_pl_ctlike_lima.run()

                    onoff_pl_ctlike_lima.obs().models(gammalib.GModels())
                    onoff_pl_ctlike_lima.obs().models().append(model_src.copy())
                    onoff_pl_ctlike_lima.obs().models().append(back_model.copy())

                    like_pl = ctools.ctlike(onoff_pl_ctlike_lima.obs())
                    like_pl['refit'] = True
                    like_pl.run()
                    dict_pl_ctlike_out['onoff'] = like_pl.obs().copy()
                    del onoff_pl_ctlike_lima
                    del like_pl

                if mode_3:
                    models_ctlike_std = gammalib.GModels()
                    models_ctlike_std.append(model_src.copy())
                    back_model = gammalib.GCTAModelIrfBackground()
                    back_model.instruments('CTA')
                    back_model.name('Background')
                    back_model.spectral(spectral_back.copy())
                    models_ctlike_std.append(back_model)

                    # save models
                    xmlmodel_PL_ctlike_std = 'test_model_PL_ctlike_std.xml'
                    models_ctlike_std.save(xmlmodel_PL_ctlike_std)
                    del models_ctlike_std

                    like_pl = ctools.ctlike(select_pl_ctlike.obs().copy())
                    like_pl['inmodel'] = xmlmodel_PL_ctlike_std
                    like_pl['refit'] = True
                    like_pl.run()
                    dict_pl_ctlike_out['std'] = like_pl.obs().copy()
                    del like_pl

                del spatial
                del spectral
                del model_src
                del select_pl_ctlike

                # EXTENDED CTLIKE
                for key in dict_obs_select_time.keys():
                    likelihood_pl_out = dict_pl_ctlike_out[key]
                    selected_data = dict_obs_select_time[key]

                    pref_out_pl = likelihood_pl_out.models()[0]['Prefactor'].value()
                    index_out_pl = likelihood_pl_out.models()[0]['Index'].value()
                    pivot_out_pl = likelihood_pl_out.models()[0]['PivotEnergy'].value()

                    expplaw = gammalib.GModelSpectralExpPlaw()
                    expplaw['Prefactor'].value(pref_out_pl)
                    expplaw['Index'].value(index_out_pl)
                    expplaw['PivotEnergy'].value(pivot_out_pl)
                    expplaw['CutoffEnergy'].value(80e3)

                    if key == "onoff":
                        selected_data.models()[0].name(src_name)
                        selected_data.models()[0].tscalc(True)
                        selected_data.models()[0].spectral(expplaw.copy())

                        like = ctools.ctlike(selected_data)
                        like['refit'] = True
                        like.run()
                        ts = like.obs().models()[0].ts()
                        if ts > 0:
                            sqrt_ts_like_onoff = np.sqrt(like.obs().models()[0].ts())
                        else:
                            sqrt_ts_like_onoff = 0

                        del like

                    if key == "std":
                        models_fit_ctlike = gammalib.GModels()

                        # create test source
                        src_dir = gammalib.GSkyDir()
                        src_dir.radec_deg(0, 0.5)
                        spatial = gammalib.GModelSpatialPointSource(src_dir)

                        # append spatial and spectral models
                        model_src = gammalib.GModelSky(spatial, expplaw.copy())
                        model_src.name('Source_fit')
                        model_src.tscalc(True)
                        models_fit_ctlike.append(model_src)

                        # create and append background
                        back_model = gammalib.GCTAModelIrfBackground()
                        back_model.instruments('CTA')
                        back_model.name('Background')
                        spectral_back = gammalib.GModelSpectralPlaw()
                        spectral_back['Prefactor'].value(1.0)
                        spectral_back['Prefactor'].scale(1.0)
                        spectral_back['Index'].value(0)
                        spectral_back['PivotEnergy'].value(300000)
                        spectral_back['PivotEnergy'].scale(1e6)
                        back_model.spectral(spectral_back)
                        models_fit_ctlike.append(back_model)

                        # save models
                        input_ctlike_xml = "model_GRB_fit_ctlike_in.xml"
                        models_fit_ctlike.save(input_ctlike_xml)
                        del models_fit_ctlike

                        like = ctools.ctlike(selected_data)
                        like['inmodel'] = input_ctlike_xml
                        like['refit'] = True
                        like.run()
                        ts = like.obs().models()[0].ts()
                        if ts > 0:
                            sqrt_ts_like_std = np.sqrt(like.obs().models()[0].ts())
                        else:
                            sqrt_ts_like_std = 0

                        del like

                    # E_cut_off = like.obs().models()[0]['CutoffEnergy'].value()
                    # E_cut_off_error = like.obs().models()[0]['CutoffEnergy'].error()

                    # print(f"sqrt(TS) {key}: {np.sqrt(ts_like):.2f}")
                    # print(f"E_cut_off {key}: {E_cut_off:.2f} +- {E_cut_off_error:.2f}")
                del dict_pl_ctlike_out

            f.write(f"{src_name},{seed},{t_in:.2f},{t_end:.2f},{sigma_onoff:.2f},{sqrt_ts_like_onoff:.2f},{sqrt_ts_like_std:.2f}\n")
            del dict_obs_select_time
            del select_time
Example #30
0
    def run_ana_dataprep(self, obsID=None):
        """
        This function is used to prepare the data to the 
        analysis.
        
        Parameters
        ----------
        - obsID (str): list of obsID to be used in data preparation. 
        By default, all of the are used.
        
        """

        #----- Check binned/stacked
        if self.method_binned == False:
            self.method_stack = False

        #----- Create the output directory if needed
        if not os.path.exists(self.output_dir):
            os.mkdir(self.output_dir)

        #----- Make sure the map definition is ok
        if self.map_UsePtgRef:
            self._match_cluster_to_pointing(
            )  # Cluster map defined using pointings
            self._match_anamap_to_pointing(
            )  # Analysis map defined using pointings

        #----- Get the obs ID to run
        obsID = self._check_obsID(obsID)
        if not self.silent:
            print('----- ObsID to be analysed: ' + str(obsID))
            print('')
        self.obs_setup.match_bkg_id()  # make sure Bkg are unique

        #----- Observation definition file
        self.obs_setup.write_pnt(self.output_dir + '/Ana_Pnt.def', obsid=obsID)
        self.obs_setup.run_csobsdef(self.output_dir + '/Ana_Pnt.def',
                                    self.output_dir + '/Ana_ObsDef.xml')

        #----- Get the events xml file for the considered obsID
        self._write_new_xmlevent_from_obsid(
            self.output_dir + '/Events.xml',
            self.output_dir + '/Ana_Events.xml', obsID)

        #----- Data selection
        sel = ctools.ctselect()
        sel['inobs'] = self.output_dir + '/Ana_Events.xml'
        sel['outobs'] = self.output_dir + '/Ana_EventsSelected.xml'
        sel['prefix'] = self.output_dir + '/Ana_Selected'
        sel['usepnt'] = False
        sel['ra'] = self.map_coord.icrs.ra.to_value('deg')
        sel['dec'] = self.map_coord.icrs.dec.to_value('deg')
        sel['rad'] = self.map_fov.to_value('deg') * np.sqrt(2) / 2.0
        sel['forcesel'] = True
        sel['emin'] = self.spec_emin.to_value('TeV')
        sel['emax'] = self.spec_emax.to_value('TeV')
        if self.time_tmin is not None:
            sel['tmin'] = self.time_tmin
        else:
            sel['tmin'] = 'NONE'
        if self.time_tmax is not None:
            sel['tmax'] = self.time_tmax
        else:
            sel['tmax'] = 'NONE'
        sel['phase'] = 'NONE'
        sel['expr'] = ''
        sel['usethres'] = 'NONE'
        sel['logfile'] = self.output_dir + '/Ana_EventsSelected_log.txt'
        sel['chatter'] = 2

        sel.logFileOpen()
        sel.execute()
        sel.logFileClose()

        if not self.silent:
            print(sel)
            print('')

        #----- Model
        map_template_fov = np.amin(self.cluster.map_fov.to_value('deg'))
        if (not self.silent) and (
                2 * self.cluster.theta_truncation.to_value('deg') >
                map_template_fov):
            print(
                'WARNING: the cluster extent is larger than the model map field of view.'
            )
            print(
                '         The recovered normalization will thus be biased low.'
            )
            print('')

        self._make_model(prefix='Ana_Model_Input',
                         obsID=obsID)  # Compute the model files

        #----- Binning (needed even if unbinned likelihood)
        for stacklist in [True, False]:
            ctscube = cubemaking.counts_cube(self.output_dir,
                                             self.map_reso,
                                             self.map_coord,
                                             self.map_fov,
                                             self.spec_emin,
                                             self.spec_emax,
                                             self.spec_enumbins,
                                             self.spec_ebinalg,
                                             stack=stacklist,
                                             logfile=self.output_dir +
                                             '/Ana_Countscube_log.txt',
                                             silent=self.silent)

        expcube = cubemaking.exp_cube(self.output_dir,
                                      self.map_reso,
                                      self.map_coord,
                                      self.map_fov,
                                      self.spec_emin,
                                      self.spec_emax,
                                      self.spec_enumbins,
                                      self.spec_ebinalg,
                                      logfile=self.output_dir +
                                      '/Ana_Expcube_log.txt',
                                      silent=self.silent)
        psfcube = cubemaking.psf_cube(self.output_dir,
                                      self.map_reso,
                                      self.map_coord,
                                      self.map_fov,
                                      self.spec_emin,
                                      self.spec_emax,
                                      self.spec_enumbins,
                                      self.spec_ebinalg,
                                      logfile=self.output_dir +
                                      '/Ana_Psfcube_log.txt',
                                      silent=self.silent)
        bkgcube = cubemaking.bkg_cube(self.output_dir,
                                      logfile=self.output_dir +
                                      '/Ana_Bkgcube_log.txt',
                                      silent=self.silent)

        if self.spec_edisp:
            edcube = cubemaking.edisp_cube(self.output_dir,
                                           self.map_coord,
                                           self.map_fov,
                                           self.spec_emin,
                                           self.spec_emax,
                                           self.spec_enumbins,
                                           self.spec_ebinalg,
                                           logfile=self.output_dir +
                                           '/Ana_Edispcube_log.txt',
                                           silent=self.silent)
Example #31
0
def sim_select_like(sim_yaml, jobs_in, model_xml, background_fits, counter):
    """

    :param sim_yaml:
    :param jobs_in:
    :param model_xml:
    :param background_fits:
    :param counter:
    :return:
    """
    #print("----------------------------")
    print(model_xml.split('/')[-1], counter)

    config_in = yaml.safe_load(open(jobs_in))
    ctools_pipe_path = create_path(config_in['exe']['software_path'])

    sim_in = yaml.safe_load(open(sim_yaml))
    ctobss_params = sim_in['ctobssim']

    # find proper IRF name
    irf = IRFPicker(sim_in, ctools_pipe_path)
    name_irf = irf.irf_pick()

    if irf.prod_version == "3b" and irf.prod_number == 0:
        caldb = "prod3b"
    else:
        caldb = f'prod{irf.prod_number}-v{irf.prod_version}'

    # loading background (this is a way of doing it without saving any file)
    # output.save("name.xml") to save the file
    obs_def = gammalib.GObservations()

    background_id = f"{str(int(counter) + 1).zfill(6)}"

    output = gammalib.GXml()
    level0 = gammalib.GXmlElement('observation_list title="observation library"')
    level1 = gammalib.GXmlElement(f'observation name="name_source" id="{background_id}" instrument="CTA"')
    level2 = gammalib.GXmlElement(f'parameter name="EventList"  file="{background_fits}"')
    level1.append(level2)
    level0.append(level1)
    output.append(level0)

    obs_def.read(output)

    seed = int(counter)*10

    # do the simulation
    sim = ctools.ctobssim()
    sim['inmodel'] = model_xml
    sim['caldb'] = caldb
    sim['irf'] = name_irf
    sim['ra'] = 0
    sim['dec'] = 0
    sim['rad'] = ctobss_params['radius']
    sim['tmin'] = u.Quantity(ctobss_params['time']['t_min']).to_value(u.s)
    sim['tmax'] = u.Quantity(ctobss_params['time']['t_max']).to_value(u.s)
    sim['emin'] = u.Quantity(ctobss_params['energy']['e_min']).to_value(u.TeV)
    sim['emax'] = u.Quantity(ctobss_params['energy']['e_max']).to_value(u.TeV)
    sim['seed'] = seed
    sim.run()

    obs_def.append(sim.obs()[0])

    # for obs in obs_def:
    #     print(obs.id(), obs.nobserved())

    select = ctools.ctselect(obs_def)
    select['rad'] = 3
    select['tmin'] = 0
    select['tmax'] = 50
    select['emin'] = 0.05
    select['emax'] = 1.0
    select.run()
                                        print('\n')
                                        print(
                                            f'\tstarting values for inteval {m + 1}: ON - {on_reg_counts} ; OFF - {off_reg_counts}'
                                        )
                                        # excluding energy ranges below the threshold associated with zenith angle
                                        if en_steps[m] >= sim_e_min:
                                            r = reg_rad[m]
                                            print(f'\tregion radius: {r}')
                                            e_start = en_steps[m]
                                            e_stop = en_steps[m + 1]
                                            # print (sim_e_min)
                                            print(
                                                f'\tEnergy interval: {e_start},{e_stop}'
                                            )
                                            # print(f'position on:{x[0]},{y[0]}')
                                            select = ctools.ctselect()
                                            select[
                                                'inobs'] = 'events_full_GRB.fits'
                                            select['usepnt'] = False
                                            select['ra'] = x[0]
                                            select['dec'] = y[0]
                                            select['rad'] = r
                                            select['tmin'] = t_slice_start
                                            select['tmax'] = t_slice_stop
                                            select['emin'] = e_start
                                            select['emax'] = e_stop
                                            select.run()
                                            on_reg_counts += select.obs(
                                            ).nobserved()

                                            print(
Example #33
0
def spectrum(obs, source, ebounds):
    """
    Returns spectral points in the given binning for the passed observations
    and source.

    Please note that specpoints can make spectra for any given spectral
    model, as long as it has a "Prefactor" or "Integral" parameter which
    scales the function
    
    Parameters:
     obs     - Observation container
     source  - Source name for which spectrum should be computed
     ebounds - GEbounds energy boundaries
    Keywords:
     None
    """
    # Check if parameters Prefactor or Integral exist to scale mdoel
    normpar  = "Prefactor"
    srcmodel = obs.models()[source]
    if not srcmodel.has_par(normpar):
        if srcmodel.has_par("Integral"):
            normpar = "Integral"
        else:
            print("Error: your spectral model of "+source+"does not"+\
                  "have a scaling parameter named 'Prefactor'"+\
                  " or 'Integral'")
            return
            
    # Fix all parameters except prefactor
    opt_spectral = srcmodel.spectral()
    for model in obs.models():
        for par in range(model.size()):
            model[par].fix()
    opt_spectral[normpar].free()
    
    # Define spectrum dictionary, units are in format readable by astropy
    spec = {"energy":{"value":[],"eu_value":[],"ed_value":[],"unit":"none"},
            "flux"  :{"value":[],"eu_value":[],"ed_value":[],"unit":"none"},
            "TS"    :{"value":[],"eu_value":[],"ed_value":[],"unit":"none"}}
    
    # Loop over energy bins, fit and write result to spectrum
    for i in range(len(ebounds)):

        # Get logarithmic bin center and flux value of all energy fit 
        ecenter = ebounds.elogmean(i)
        allflux = opt_spectral.eval(ecenter, gammalib.GTime(0.0))

        # Clone observations and reset energy thresholds
        select = ctools.ctselect(obs)
        select["ra"].value("UNDEF")
        select["dec"].value("UNDEF")
        select["rad"].value("UNDEF")
        select["tmin"].real(0.0)
        select["tmax"].real(0.0)
        select["emin"].real(ebounds.emin(i).TeV())
        select["emax"].real(ebounds.emax(i).TeV())
        select.run()
        
        # Refit and write out to spectrum
        binlike         = fit(select.obs(), log=False, debug=False, edisp=False)
        binopt_spectral = binlike.obs().models()[source].spectral()
        binflux         = binopt_spectral.eval(ecenter, gammalib.GTime(0.0))
        if binopt_spectral[normpar].value() > 0.0:
            relerr = binopt_spectral[normpar].error()/binopt_spectral[normpar].value()
        else:
            relerr = 0.0

        # Store and convert to TeV from MeV
        spec["energy"]["value"].append(ecenter.TeV())
        spec["energy"]["ed_value"].append(ecenter.TeV()-ebounds.emin(i).TeV())
        spec["energy"]["eu_value"].append(ebounds.emax(i).TeV()-ecenter.TeV())
        spec["energy"]["unit"] = "TeV"
        
        spec["flux"]["value"].append(binflux*1.0e6)
        spec["flux"]["ed_value"].append(relerr*binflux*1.0e6)
        spec["flux"]["eu_value"].append(relerr*binflux*1.0e6)
        spec["flux"]["unit"] = "ph/cm2/s/TeV"
        
        spec["TS"]["value"].append(binlike.obs().models()[source].ts())
    
    # Return spectrum
    return spec
Example #34
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 observation into logger
        self._log_observations(gammalib.NORMAL, self.obs(), 'Observation')

        # Get time boundaries
        tmin = self._tbins.tstart(0)
        tmax = self._tbins.tstop(self._tbins.size() - 1)

        # Select events
        select = ctools.ctselect(self.obs())
        select['emin'] = self['emin'].real()
        select['emax'] = self['emax'].real()
        select['tmin'] = tmin.convert(ctools.time_reference)
        select['tmax'] = tmax.convert(ctools.time_reference)
        select['rad'] = 'UNDEFINED'
        select['ra'] = 'UNDEFINED'
        select['dec'] = 'UNDEFINED'
        select.run()

        # Extract observations
        self.obs(select.obs().copy())

        # Write observation into logger
        self._log_header1(
            gammalib.TERSE,
            gammalib.number('Selected observation', len(self.obs())))

        # Adjust model parameters dependent on user parameters
        self._adjust_model_pars()

        # Write header
        self._log_header1(gammalib.TERSE, 'Generate lightcurve')

        # Initialise list of result dictionaries
        results = []

        # Get source parameters
        pars = self._get_free_par_names()

        # Loop over time bins
        for i in range(self._tbins.size()):

            # Get time boundaries
            tmin = self._tbins.tstart(i)
            tmax = self._tbins.tstop(i)

            # Write time bin into header
            self._log_header2(gammalib.TERSE,
                              'MJD %f - %f ' % (tmin.mjd(), tmax.mjd()))

            # Compute time bin center and time width
            twidth = 0.5 * (tmax - tmin)  # in seconds
            tmean = tmin + twidth

            # Initialise result dictionary
            result = {
                'mjd': tmean.mjd(),
                'e_mjd': twidth / gammalib.sec_in_day,
                'ts': 0.0,
                'ul_diff': 0.0,
                'ul_flux': 0.0,
                'ul_eflux': 0.0,
                'pars': pars,
                'values': {}
            }

            # Log information
            self._log_header3(gammalib.EXPLICIT, 'Selecting events')

            # Select events
            select = ctools.ctselect(self.obs())
            select['emin'] = self['emin'].real()
            select['emax'] = self['emax'].real()
            select['tmin'] = tmin.convert(ctools.time_reference)
            select['tmax'] = tmax.convert(ctools.time_reference)
            select['rad'] = 'UNDEFINED'
            select['ra'] = 'UNDEFINED'
            select['dec'] = 'UNDEFINED'
            select.run()

            # Retrieve observation
            obs = select.obs()

            # Deal with stacked and On/Off Observations
            if self._stacked or self._onoff:

                # If a stacked analysis is requested bin the events
                # and compute the stacked response functions and setup
                # an observation container with a single stacked observation.
                if self._stacked:
                    new_obs = obsutils.get_stacked_obs(self, obs)

                # ... otherwise if On/Off analysis is requested generate
                # the On/Off observations and response
                elif self._onoff:
                    new_obs = obsutils.get_onoff_obs(self, obs)

                # Extract models
                models = new_obs.models()

                # Fix background models if required
                if self['fix_bkg'].boolean():
                    for model in models:
                        if model.classname() != 'GModelSky':
                            for par in model:
                                par.fix()

                # Put back models
                new_obs.models(models)

                # Continue with new oberservation container
                obs = new_obs

            # Header
            self._log_header3(gammalib.EXPLICIT, 'Fitting the data')

            # Do maximum likelihood model fitting
            if obs.size() > 0:
                like = ctools.ctlike(obs)
                like['edisp'] = self['edisp'].boolean()
                like.run()

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

                    # Signal skipping of bin
                    self._log_value(gammalib.TERSE, 'Warning',
                                    'No event in this time bin, skip bin.')

                    # Set all results to 0
                    for par in pars:
                        result['values'][par] = 0.0
                        result['values']['e_' + par] = 0.0

                    # Append result
                    results.append(result)

                    # Continue with next time bin
                    continue

                # Retrieve model fitting results for source of interest
                source = like.obs().models()[self._srcname]

                # Extract parameter values
                for par in pars:
                    result['values'][par] = source[par].value()
                    result['values']['e_' + par] = source[par].error()

                # Calculate upper limit (-1 if not computed)
                #ul_diff, ul_flux, ul_eflux = self._compute_ulimit(like.obs())
                ul_diff, ul_flux, ul_eflux = self._compute_ulimit(obs)
                if ul_diff > 0.0:
                    result['ul_diff'] = ul_diff
                    result['ul_flux'] = ul_flux
                    result['ul_eflux'] = ul_eflux

                # Extract Test Statistic value
                if self['calc_ts'].boolean():
                    result['ts'] = source.ts()

                # Append result to list of dictionaries
                results.append(result)

                # Log results for this time bin
                self._log.header3('Results')
                pars = self._get_free_par_names()
                for par in pars:
                    value = source[par].value()
                    error = source[par].error()
                    unit = source[par].unit()
                    self._log_value(
                        gammalib.NORMAL, par,
                        str(value) + ' +/- ' + str(error) + ' ' + unit)
                if ul_diff > 0.0:
                    self._log_value(gammalib.NORMAL, 'Upper flux limit',
                                    str(result['ul_diff']) + ' ph/cm2/s/MeV')
                    self._log_value(gammalib.NORMAL, 'Upper flux limit',
                                    str(result['ul_flux']) + ' ph/cm2/s')
                    self._log_value(gammalib.NORMAL, 'Upper flux limit',
                                    str(result['ul_eflux']) + ' erg/cm2/s')
                if self['calc_ts'].boolean():
                    self._log_value(gammalib.NORMAL, 'Test Statistic',
                                    result['ts'])

            # Otherwise, if observations size is 0, signal bin is skipped and
            # fill results table with zeros
            else:
                self._log_value(
                    gammalib.TERSE, 'Warning',
                    'No observations available in this time bin, '
                    'skip bin.')

                # Set all results to 0
                for par in pars:
                    result['values'][par] = 0.0
                    result['values']['e_' + par] = 0.0

                # Append result
                results.append(result)

                # Continue with next time bin
                continue

        # Create FITS table from results
        table = self._create_fits_table(results)

        # Create FITS file and append FITS table to FITS file
        self._fits = gammalib.GFits()
        self._fits.append(table)

        # Optionally publish light curve
        if self['publish'].boolean():
            self.publish()

        # Return
        return
Example #35
0
def pipeline(model_name):
    """
    Unbinned analysis pipeline - keep intermediate results in memory.

    This function implements an analysis pipeline that successively calls
    ctobssim, ctselect and ctlike without saving the intermediate results as
    FITS files on disk. All data is only hold in memory.
    """
    # Set script parameters
    caldb       = "prod2"
    irf         = "South_50h"
    ra          =   83.63
    dec         =   22.01
    rad_sim     =   10.0
    tstart      =    0.0
    tstop       = 1800.0
    emin        =    0.1
    emax        =  100.0
    rad_select  =    3.0

    # Write model name
    print("*** Model: "+model_name+" ************************************")

    # Initialise timing
    wall_seconds = 0.0
    cpu_seconds  = 0.0

    # Simulate events
    sim = ctools.ctobssim()
    sim["inmodel"] = model_name
    sim["caldb"]   = caldb
    sim["irf"]     = irf
    sim["ra"]      = ra
    sim["dec"]     = dec
    sim["rad"]     = rad_sim
    sim["tmin"]    = tstart
    sim["tmax"]    = tstop
    sim["emin"]    = emin
    sim["emax"]    = emax
    sim.run()

    # Select events
    select = ctools.ctselect(sim.obs())
    select["ra"]   = ra
    select["dec"]  = dec
    select["rad"]  = rad_select
    select["tmin"] = tstart
    select["tmax"] = tstop
    select["emin"] = emin
    select["emax"] = emax
    select.run()

    # Perform maximum likelihood fitting
    like = ctools.ctlike(select.obs())
    like.run()

    # Show model fitting results
    print(like.obs().models()[0])

    # Return
    return
Example #36
0
    def _test_python(self):
        """
        Test ctselect from Python
        """
        # Allocate empty ctselect tool
        select = ctools.ctselect()

        # Check that empty ctselect tool holds an empty observation
        self._check_obs(select.obs(), nobs=0)

        # Check that saving does nothing
        select['outobs'] = 'ctselect_py0.fits'
        select['logfile'] = 'ctselect_py0.log'
        select.logFileOpen()
        select.save()
        self.test_assert(not os.path.isfile('ctselect_py0.fits'),
                         'Check that no event list has been created')

        # Check that clearing does not lead to an exception or segfault
        select.clear()

        # Now set ctselect parameters
        select['inobs'] = self._events
        select['rad'] = 1.0
        select['tmin'] = '2020-01-01T00:01:10'
        select['tmax'] = '2020-01-01T00:03:40'
        select['emin'] = 2.0
        select['emax'] = 80.0
        select['outobs'] = 'ctselect_py1.fits'
        select['logfile'] = 'ctselect_py1.log'
        select['chatter'] = 2

        # Run ctselect tool
        select.logFileOpen()  # Make sure we get a log file
        select.run()
        select.save()

        # Check result file
        self._check_result_file('ctselect_py1.fits')

        # Copy ctselect tool
        cpy_select = select.copy()

        # Check observation of ctselect copy
        self._check_obs(cpy_select.obs())

        # Execute copy of ctselect tool again, now with a higher chatter
        # level than before and without any selection. Since the tools
        # still holds the same selected observation container from before
        # the number of events will be identical.
        cpy_select['rad'] = 'NONE'
        cpy_select['tmin'] = 'NONE'
        cpy_select['tmax'] = 'NONE'
        cpy_select['emin'] = 'NONE'
        cpy_select['emax'] = 'NONE'
        cpy_select['outobs'] = 'ctselect_py2.fits'
        cpy_select['logfile'] = 'ctselect_py2.log'
        cpy_select['chatter'] = 3
        cpy_select['publish'] = True
        cpy_select.logFileOpen()  # Needed to get a new log file
        cpy_select.execute()

        # Check result file
        self._check_result_file('ctselect_py2.fits')

        # Execute again the copy of ctselect tool again, now manually specifying the
        # RoI centres. We also set the minimum values
        # to valid event selections, but since the maximum values are still
        # 'NONE', no event selections should occur.
        cpy_select['usepnt'] = False
        cpy_select['ra'] = 83.63
        cpy_select['dec'] = 22.01
        cpy_select['tmin'] = '2020-01-01T00:01:10'
        cpy_select['emin'] = 2.0
        cpy_select['usethres'] = 'USER'
        cpy_select['outobs'] = 'ctselect_py3.fits'
        cpy_select['logfile'] = 'ctselect_py3.log'
        cpy_select['chatter'] = 4
        cpy_select.logFileOpen()  # Needed to get a new log file
        cpy_select.execute()

        # Check result file
        self._check_result_file('ctselect_py3.fits')

        # Now clear copy of ctselect tool
        cpy_select.clear()

        # Check that cleared ctselect tool holds no observations and events
        self._check_obs(cpy_select.obs(), nobs=0)

        # Get mixed observation container
        obs = self._obs_mixed()

        # Attach response function to first observation which is the
        # event list. This is necessary to run the ctselect tool with
        # "DEFAULT" thresholds.
        obs[0].response('South_0.5h', gammalib.GCaldb('cta', 'prod2'))

        # Setup ctselect tool from observation container. An energy range
        # beyond the energies covered in the event file is specified, hence
        # an empty event list will be saved.
        select = ctools.ctselect(obs)
        select['rad'] = 1.0
        select['tmin'] = '2020-01-01T00:01:10'
        select['tmax'] = '2020-01-01T00:03:40'
        select['emin'] = 120.0
        select['emax'] = 130.0
        select['expr'] = 'DETX == 0'
        select['usethres'] = 'DEFAULT'  # Has no impact as IRF has no keywords
        select['outobs'] = 'ctselect_py4.fits'
        select['logfile'] = 'ctselect_py4.log'
        select['chatter'] = 3

        # Execute tool
        select.logFileOpen()  # Needed to get a new log file
        select.execute()

        # Check result file
        self._check_result_file('ctselect_py4.fits', nevents=0)

        # Setup ctselect tool for an invalid event file
        select = ctools.ctselect()
        select['inobs'] = self._invalid_events
        select['rad'] = 1.0
        select['tmin'] = '2020-01-01T00:01:10'
        select['tmax'] = '2020-01-01T00:03:40'
        select['emin'] = 2.0
        select['emax'] = 80.0
        select['outobs'] = 'ctselect_py5.fits'
        select['logfile'] = 'ctselect_py5.log'
        select['chatter'] = 3

        # Execute tool
        select.logFileOpen()  # Needed to get a new log file
        self.test_try('Test invalid event file')
        try:
            select.execute()
            self.test_try_failure('Exception not thrown')
        except ValueError:
            self.test_try_success()

        # Setup ctselect tool from event list with extension name. The "emax"
        # value should be ignored.
        select = ctools.ctselect()
        select['inobs'] = self._events + '[EVENTS]'
        select['rad'] = 1.0
        select['tmin'] = '2020-01-01T00:01:10'
        select['tmax'] = '2020-01-01T00:03:40'
        select['emin'] = 2.0
        select['emax'] = 0.0  # Signals that "emax" should be ignored
        select['outobs'] = 'ctselect_py6.fits'
        select['logfile'] = 'ctselect_py6.log'
        select['chatter'] = 3

        # Execute tool
        select.logFileOpen()  # Needed to get a new log file
        select.execute()

        # Check result file
        self._check_result_file('ctselect_py6.fits')

        # Now ignore the "emin" value.
        select = ctools.ctselect()
        select['inobs'] = self._events + '[EVENTS]'
        select['rad'] = 1.0
        select['tmin'] = '2020-01-01T00:01:10'
        select['tmax'] = '2020-01-01T00:03:40'
        select['emin'] = 0.0  # Signals that "emin" should be ignored
        select['emax'] = 80.0
        select['outobs'] = 'ctselect_py7.fits'
        select['logfile'] = 'ctselect_py7.log'
        select['chatter'] = 3

        # Execute tool
        select.logFileOpen()  # Needed to get a new log file
        select.execute()

        # Check result file
        self._check_result_file('ctselect_py7.fits', nevents=60)

        # Now set "emin > emax"
        select['emin'] = 150.0
        select['emax'] = 80.0
        select['outobs'] = 'ctselect_py8.fits'
        select['logfile'] = 'ctselect_py8.log'
        select['chatter'] = 3

        # Execute tool
        select.logFileOpen()  # Needed to get a new log file
        select.execute()

        # Check result file
        self._check_result_file('ctselect_py8.fits', nevents=0)

        # Setup ctselect tool with an RoI that is displaced and of the same
        # size as the original RoI. This should cause an exception to occur
        select = ctools.ctselect()
        select['inobs'] = self._events
        select['usepnt'] = False
        select['ra'] = 83.63
        select['dec'] = 24.01
        select['rad'] = 2.0
        select['tmin'] = '2020-01-01T00:01:10'
        select['tmax'] = '2020-01-01T00:03:40'
        select['emin'] = 2.0
        select['emax'] = 80.0
        select['outobs'] = 'ctselect_py9.fits'
        select['logfile'] = 'ctselect_py9.log'
        select['chatter'] = 3

        # Execute tool
        select.logFileOpen()  # Needed to get a new log file
        self.test_try('Testing selection of invalid RoI')
        try:
            select.execute()
            self.test_try_failure('Exception not thrown')
        except ValueError:
            self.test_try_success()

        # Now force selection and verify that the execution succeeds
        select['forcesel'] = True
        select['outobs'] = 'ctselect_py10.fits'
        select['logfile'] = 'ctselect_py10.log'

        # Execute tool
        select.logFileOpen()  # Needed to get a new log file
        select.execute()

        # Check result file
        self._check_result_file('ctselect_py10.fits', nevents=31, rad=2.0)

        # Finally test a custom defined RoI enclosed in the original one
        select = ctools.ctselect()
        select['inobs'] = self._events
        select['usepnt'] = False
        select['ra'] = 83.63
        select['dec'] = 24.01
        select['rad'] = 0.4
        select['tmin'] = '2020-01-01T00:01:10'
        select['tmax'] = '2020-01-01T00:03:40'
        select['emin'] = 2.0
        select['emax'] = 80.0
        select['outobs'] = 'ctselect_py11.fits'
        select['logfile'] = 'ctselect_py11.log'
        select['chatter'] = 3

        # Execute tool
        select.logFileOpen()  # Needed to get a new log file
        select.execute()

        # Check result file
        self._check_result_file('ctselect_py11.fits',
                                nevents=1,
                                dec=24.01,
                                rad=0.4)

        # Now test phase cut
        select = ctools.ctselect()
        select['inobs'] = self._phased_events
        select['rad'] = 1.0
        select['tmin'] = 'INDEF'
        select['tmax'] = 'INDEF'
        select['emin'] = 1.0
        select['emax'] = 100.0
        select['phase'] = '0.1:0.4,0.6:0.8'
        select['outobs'] = 'ctselect_py12.fits'
        select['logfile'] = 'ctselect_py12.log'
        select['chatter'] = 2

        # Run ctselect tool
        select.logFileOpen()  # Make sure we get a log file
        select.execute()

        # Check result file
        self._check_result_file('ctselect_py12.fits', nevents=365, dec=22.01)

        # Now test another phase cut
        select = ctools.ctselect()
        select['inobs'] = self._phased_events
        select['rad'] = 1.0
        select['tmin'] = 'INDEF'
        select['tmax'] = 'INDEF'
        select['emin'] = 1.0
        select['emax'] = 100.0
        select['phase'] = '0.8:0.3'
        select['outobs'] = 'ctselect_py13.fits'
        select['logfile'] = 'ctselect_py13.log'
        select['chatter'] = 2

        # Run ctselect tool
        select.logFileOpen()  # Make sure we get a log file
        select.execute()

        # Check result file
        self._check_result_file('ctselect_py13.fits', nevents=395, dec=22.01)

        # Test invalid minimum phase value
        self.test_try('Test invalid minimum phase value')
        try:
            select['phase'] = '-0.1:0.3'
            select['outobs'] = 'ctselect_py14.fits'
            select['logfile'] = 'ctselect_py14.log'
            select.logFileOpen()
            select.execute()
            self.test_try_failure('Exception not thrown for "-0.1:0.3"')
        except ValueError:
            self.test_try_success()

        # Test invalid minimum phase value
        self.test_try('Test invalid minimum phase value')
        try:
            select['phase'] = '1.1:0.3'
            select['outobs'] = 'ctselect_py15.fits'
            select['logfile'] = 'ctselect_py15.log'
            select.logFileOpen()
            select.execute()
            self.test_try_failure('Exception not thrown for "1.1:0.3"')
        except ValueError:
            self.test_try_success()

        # Test invalid maximum phase value
        self.test_try('Test invalid maximum phase value')
        try:
            select['phase'] = '0.1:-0.3'
            select['outobs'] = 'ctselect_py16.fits'
            select['logfile'] = 'ctselect_py16.log'
            select.logFileOpen()
            select.execute()
            self.test_try_failure('Exception not thrown for "0.1:-0.3"')
        except ValueError:
            self.test_try_success()

        # Test invalid maximum phase value
        self.test_try('Test invalid maximum phase value')
        try:
            select['phase'] = '0.1:1.1'
            select['outobs'] = 'ctselect_py17.fits'
            select['logfile'] = 'ctselect_py17.log'
            select.logFileOpen()
            select.execute()
            self.test_try_failure('Exception not thrown for "0.1:1.1"')
        except ValueError:
            self.test_try_success()

        # Test invalid phase string
        self.test_try('Test invalid phase string')
        try:
            select['phase'] = '0.1:'
            select['outobs'] = 'ctselect_py18.fits'
            select['logfile'] = 'ctselect_py18.log'
            select.logFileOpen()
            select.execute()
            self.test_try_failure('Exception not thrown for "0.1:"')
        except ValueError:
            self.test_try_success()

        # Test invalid phase string
        self.test_try('Test invalid phase string')
        try:
            select['phase'] = ':1.0'
            select['outobs'] = 'ctselect_py19.fits'
            select['logfile'] = 'ctselect_py19.log'
            select.logFileOpen()
            select.execute()
            self.test_try_failure('Exception not thrown for ":1.0"')
        except ValueError:
            self.test_try_success()

        # Test invalid phase string
        self.test_try('Test invalid phase string')
        try:
            select['phase'] = '0.1-1.0'
            select['outobs'] = 'ctselect_py20.fits'
            select['logfile'] = 'ctselect_py20.log'
            select.logFileOpen()
            select.execute()
            self.test_try_failure('Exception not thrown for "0.1-1.0"')
        except ValueError:
            self.test_try_success()

        # Return
        return
Example #37
0
    def _phase_bin(self, phbin):

        # Write time bin into header
        self._log_header2(gammalib.TERSE,
                          'PHASE %f - %f' % (phbin[0], phbin[1]))

        # Select events
        select = ctools.ctselect(self.obs().copy())
        select['emin'] = self['emin'].real()
        select['emax'] = self['emax'].real()
        select['tmin'] = 'UNDEFINED'
        select['tmax'] = 'UNDEFINED'
        select['rad'] = 'UNDEFINED'
        select['ra'] = 'UNDEFINED'
        select['dec'] = 'UNDEFINED'
        select['expr'] = 'PHASE>' + str(phbin[0]) + ' && PHASE<' + str(
            phbin[1])
        select.run()

        # Set phase string
        phstr = str(phbin[0]) + '-' + str(phbin[1])

        # Add phase to observation id
        for i in range(0, select.obs().size()):
            oldid = select.obs()[i].id()
            select.obs()[i].id(oldid + '_' + phstr)
        obs = select.obs()

        # If an On/Off analysis is requested generate the On/Off observations
        if self._onoff:
            obs = obsutils.get_onoff_obs(self, select.obs(), nthreads=1)

        # ... otherwise, if stacked analysis is requested then bin the
        # events and compute the stacked response functions and setup
        # an observation container with a single stacked observation.
        elif self._stacked:
            obs = obsutils.get_stacked_obs(self, select.obs())

        # Header
        self._log_header3(gammalib.EXPLICIT, 'Fitting the data')

        # The On/Off analysis can produce empty observation containers,
        # e.g., when on-axis observations are used. To avoid ctlike asking
        # for a new observation container (or hang, if in interactive mode)
        # we'll run ctlike only if the size is >0
        if obs.size() > 0:

            # Do maximum likelihood model fitting
            like = ctools.ctlike(obs)
            like['edisp'] = self['edisp'].boolean()
            like['nthreads'] = 1  # Avoids OpenMP conflict
            like.run()

            # Renormalize models to phase selection
            # TODO move the scaling from the temporal to the spectral component
            for model in like.obs().models():
                scaled_norm = model['Normalization'].value() / (phbin[1] -
                                                                phbin[0])
                model['Normalization'].value(scaled_norm)

            # Store fit model
            fitmodels = like.obs().models().copy()

        # ... otherwise we set an empty model container
        else:
            self._log_string(
                gammalib.TERSE, 'PHASE %f - %f: no observations available'
                ' for fitting' % (phbin[0], phbin[1]))

            # Set empty models container
            fitmodels = gammalib.GModels()

        # Set results
        result = {'phstr': phstr, 'fitmodels': fitmodels}

        # Return results
        return result
Example #38
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 observation into logger
        if self._logTerse():
            self._log("\n")
            self._log.header1("Observation")
            self._log(str(self._obs))
            self._log("\n")

        # Adjust model parameters dependent on user parameters
        self._adjust_model_pars()

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

        # Initialise list of result dictionaries
        results = []

        # Get source parameters
        pars = self._get_free_par_names()

        # Loop over time bins
        for i in range(self._tbins.size()):

            # Get time boundaries
            tmin = self._tbins.tstart(i)
            tmax = self._tbins.tstop(i)

            # Write time bin into header
            if self._logTerse():
                self._log.header2("MJD " + str(tmin.mjd()) + "-" +
                                  str(tmax.mjd()))

            # Compute time bin center and time width
            twidth = 0.5 * (tmax - tmin)  # in seconds
            tmean = tmin + twidth

            # Initialise result dictionary
            result = {
                'mjd': tmean.mjd(),
                'e_mjd': twidth / gammalib.sec_in_day,
                'ts': 0.0,
                'ulimit': 0.0,
                'pars': pars,
                'values': {}
            }

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

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

            # Retrieve observation
            obs = select.obs()

            # If a stacked analysis is requested then bin the events
            # and compute the stacked response functions and setup
            # an observation container with a single stacked observation.
            if self._stacked:
                obs = self._bin_observation(obs)

            # Header
            if self._logExplicit():
                self._log.header3("Fitting the data")

            # Do maximum likelihood model fitting
            like = ctools.ctlike(obs)
            like["edisp"] = self["edisp"].boolean()
            like.run()

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

                # Signal skipping of bin
                if self._logTerse():
                    self._log(gammalib.parformat("Warning"))
                    self._log("No event in this time bin, skip bin.\n")

                # Set all results to 0
                for par in pars:
                    result['values'][par] = 0.0
                    result['values']["e_" + par] = 0.0

                # Append result
                results.append(result)

                # Continue with next time bin
                continue

            # Retrieve model fitting results for source of interest
            source = like.obs().models()[self._srcname]

            # Extract parameter values
            for par in pars:
                result['values'][par] = source.spectral()[par].value()
                result['values']["e_" + par] = source.spectral()[par].error()

            # Calculate upper limit (-1 if not computed)
            ulimit_value = self._compute_ulimit(like.obs())
            if ulimit_value > 0.0:
                result['ulimit'] = ulimit_value

            # Extract Test Statistic value
            if self["calc_ts"].boolean():
                result['ts'] = source.ts()

            # Append result to list of dictionaries
            results.append(result)

            # Log results for this time bin
            if self._logNormal():
                self._log.header3("Results")
                pars = self._get_free_par_names()
                for par in pars:
                    value = source.spectral()[par].value()
                    error = source.spectral()[par].error()
                    unit = source.spectral()[par].unit()
                    self._log(gammalib.parformat(par))
                    self._log(str(value))
                    self._log(" +/- ")
                    self._log(str(error))
                    self._log(" ")
                    self._log(unit)
                    self._log("\n")
                if result['ulimit'] > 0.0:
                    self._log(gammalib.parformat("Upper flux limit"))
                    self._log(str(result['ulimit']) + " ph/cm2/s\n")
                if self["calc_ts"].boolean():
                    self._log(gammalib.parformat("Test Statistic"))
                    self._log(str(result['ts']) + "\n")

        # Create FITS table from results
        table = self._create_fits_table(results)

        # Create FITS file and append FITS table to FITS file
        self._fits = gammalib.GFits()
        self._fits.append(table)

        # Return
        return
Example #39
0
    def _select_obs(self, emin, emax):
        """
        Select observations for energy interval

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

        Returns
        -------
        obs : `~gammalib.GObservations`
            Observation container
        """
        # Use ctcubemask for binned analysis
        if self._binned_mode:

            # Write header
            self._log_header3(gammalib.EXPLICIT, '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()

            # If chatter level is verbose and debugging is requested then
            # switch also on the debug model in ctcubemask
            if self._logVerbose() and self._logDebug():
                cubemask['debug'] = True

            # Select layers
            cubemask.run()

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

        # Use ...
        elif self._onoff_mode:

            # Write header
            self._log_header3(gammalib.EXPLICIT, 'Filtering PHA, ARF and RMF')

            # Initialise observation container
            obs = gammalib.GObservations()

            # Loop over all input observations and select energy bins for
            # all On/Off observations
            for run in self.obs():
                if run.classname() == 'GCTAOnOffObservation':
                    obs.append(self._select_onoff_obs(run, emin, emax))

            # Append models
            obs.models(self.obs().models())

        # Use ctselect for unbinned analysis
        else:

            # Write header
            self._log_header3(gammalib.EXPLICIT, 'Selecting events')

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

            # If chatter level is verbose and debugging is requested then
            # switch also on the debug model in ctselect
            if self._logVerbose() and self._logDebug():
                select['debug'] = True

            # Run ctselect
            select.run()

            # Retrieve observation
            obs = select.obs().copy()

        # Return observation container
        return obs
Example #40
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 input parameters into logger
        if self.logTerse():
            self.log_parameters()
            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.m_srcname:
                if self.m_calc_ts:
                    model.tscalc(True)
                
            elif self.m_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.m_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 lightcurve")      
        
        # Initialise FITS Table with extension "LIGHTCURVE"
        table = gammalib.GFitsBinTable(self.m_tbins.size())
        table.extname("LIGHTCURVE")
        
        # 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        
        MJD = gammalib.GFitsTableDoubleCol("MJD", self.m_tbins.size())
        MJD.unit("days")
        e_MJD = gammalib.GFitsTableDoubleCol("e_MJD", self.m_tbins.size())
        e_MJD.unit("days")
        
        # Create a FITS column for every free parameter
        columns = []
        for par in self.obs.models()[self.m_srcname]:
            if par.is_free():
                col = gammalib.GFitsTableDoubleCol(par.name(), self.m_tbins.size())
                col.unit(par.unit())
                columns.append(col)
                e_col = gammalib.GFitsTableDoubleCol("e_"+par.name(), self.m_tbins.size())
                e_col.unit(par.unit())
                columns.append(e_col)
        
        # Create TS and upper limit columns
        TSvalues    = gammalib.GFitsTableDoubleCol("TS", self.m_tbins.size())
        ulim_values = gammalib.GFitsTableDoubleCol("UpperLimit", self.m_tbins.size())
        ulim_values.unit("ph/cm2/s")

        # Loop over energy bins
        for i in range(self.m_tbins.size()):

            # Log information
            if self.logTerse():
                self.log("\n")
                self.log.header2("Time bin "+str(i))

            # Get time boundaries
            tmin = self.m_tbins.tstart(i)
            tmax = self.m_tbins.tstop(i)
            
            # Compute time bin center and time width
            tmean   = (tmin + tmax)
            tmean  *= 0.5
            twidth  = (tmax - tmin)
            twidth *= 0.5 

            # Store time as MJD
            MJD[i] = tmean.mjd()
            e_MJD[i] = twidth.days()
            
            # Log information
            if self.logExplicit():
                self.log.header3("Selecting events")
                     
            # Select events
            select = ctools.ctselect(self.obs)
            select["emin"].real(self.m_emin)    
            select["emax"].real(self.m_emax) 
            select["tmin"].real(tmin.convert(select.time_reference()))
            select["tmax"].real(tmax.convert(select.time_reference()))
            select["rad"].value("UNDEFINED")
            select["ra"].value("UNDEFINED")
            select["dec"].value("UNDEFINED")
            select.run()  

            # Retrieve observation
            obs = select.obs()
             
            # Binned analysis
            if self.m_binned:

                # Header
                if self.logTerse():
                    self.log.header3("Binning events")
                
                # Bin events
                bin = ctools.ctbin(select.obs())
                bin["usepnt"].boolean(False)
                bin["ebinalg"].string("LOG")
                bin["xref"].real(self.m_xref)
                bin["yref"].real(self.m_yref)
                bin["binsz"].real(self.m_binsz)
                bin["nxpix"].integer(self.m_nxpix)
                bin["nypix"].integer(self.m_nypix)
                bin["enumbins"].integer(self.m_ebins)
                bin["emin"].real(self.m_emin)
                bin["emax"].real(self.m_emax)        
                bin["coordsys"].string(self.m_coordsys)
                bin["proj"].string(self.m_proj)            
                bin.run()
                
                # Header
                if self.logTerse():
                    self.log.header3("Creating exposure cube")
                
                # Create exposure cube
                expcube = ctools.ctexpcube(select.obs())
                expcube["incube"].filename("NONE")
                expcube["usepnt"].boolean(False)
                expcube["ebinalg"].string("LOG")
                expcube["xref"].real(self.m_xref)
                expcube["yref"].real(self.m_yref)
                expcube["binsz"].real(self.m_binsz)
                expcube["nxpix"].integer(self.m_nxpix)
                expcube["nypix"].integer(self.m_nypix)
                expcube["enumbins"].integer(self.m_ebins)
                expcube["emin"].real(self.m_emin)
                expcube["emax"].real(self.m_emax)   
                expcube["coordsys"].string(self.m_coordsys)
                expcube["proj"].string(self.m_proj)               
                expcube.run()
                
                # Header
                if self.logTerse():
                    self.log.header3("Creating PSF cube")
                
                # Create psf cube
                psfcube = ctools.ctpsfcube(select.obs())
                psfcube["incube"].filename("NONE")
                psfcube["usepnt"].boolean(False)
                psfcube["ebinalg"].string("LOG")
                psfcube["xref"].real(self.m_xref)
                psfcube["yref"].real(self.m_yref)
                psfcube["binsz"].real(self.m_binsz)
                psfcube["nxpix"].integer(self.m_nxpix)
                psfcube["nypix"].integer(self.m_nypix)
                psfcube["enumbins"].integer(self.m_ebins)
                psfcube["emin"].real(self.m_emin)
                psfcube["emax"].real(self.m_emax)    
                psfcube["coordsys"].string(self.m_coordsys)
                psfcube["proj"].string(self.m_proj)               
                psfcube.run()
                
                # Header
                if self.logTerse():
                    self.log.header3("Creating background cube")
                
                # Create background cube
                bkgcube = ctools.ctbkgcube(select.obs())
                bkgcube["incube"].filename("NONE")
                bkgcube["usepnt"].boolean(False)
                bkgcube["ebinalg"].string("LOG")
                bkgcube["xref"].real(self.m_xref)
                bkgcube["yref"].real(self.m_yref)
                bkgcube["binsz"].real(self.m_binsz)
                bkgcube["nxpix"].integer(self.m_nxpix)
                bkgcube["nypix"].integer(self.m_nypix)
                bkgcube["enumbins"].integer(self.m_ebins)
                bkgcube["emin"].real(self.m_emin)
                bkgcube["emax"].real(self.m_emax)   
                bkgcube["coordsys"].string(self.m_coordsys)
                bkgcube["proj"].string(self.m_proj)                
                bkgcube.run()
                
                # Set new binned observation
                obs = bin.obs()
                
                # Set precomputed binned response
                obs[0].response(expcube.expcube(), psfcube.psfcube(), bkgcube.bkgcube())

                # Get new models
                models = bkgcube.models()
                
                # Fix background models if required
                if self.m_fix_bkg:
                    for model in models:
                        if not model.classname() == "GModelSky":
                            for par in model:
                                par.fix()
                                
                # Set new models to binned observation           
                obs.models(models)
                
            # Header
            if self.logTerse():
                self.log.header3("Performing fit")
                             
            # Likelihood
            like = ctools.ctlike(obs)
            like.run()
            
            # Skip bin if no event was present
            if like.obs().logL() == 0.0:
                
                # Log information
                if self.logTerse():
                    self.log("No event in this time bin. Bin is skipped\n")

                # Set all values to 0
                for col in columns:
                    col[i] = 0.0
                TSvalues[i]    = 0.0
                ulim_values[i] = 0.0
                continue
                         
            # Get results
            fitted_models = like.obs().models()
            source        = fitted_models[self.m_srcname]

            # Calculate Upper Limit            
            ulimit_value = -1.0
            if self.m_calc_ulimit:
                
                # Logging information
                if self.logTerse():
                    self.log.header3("Computing upper limit")
                  
                # Create upper limit object  
                ulimit = ctools.ctulimit(like.obs())
                ulimit["srcname"].string(self.m_srcname)
                ulimit["eref"].real(1.0)
                
                # Try to run upper limit and catch exceptions
                try:
                    ulimit.run()
                    ulimit_value = ulimit.flux_ulimit()
                except:
                    if self.logTerse():
                        self.log("Upper limit calculation failed\n")
                    ulimit_value = -1.0
            
            # Get TS value
            TS = -1.0
            if self.m_calc_ts:
                TS = source.ts() 
            
            # Set values for storage
            TSvalues[i] = TS
            
            # Set FITS column values
            for col in columns:
                if "e_" == col.name()[:2]:
                    col[i] = source.spectral()[col.name()[2:]].error()
                else:
                    col[i] = source.spectral()[col.name()].value()
            
            # Store upper limit value if available
            if ulimit_value > 0.0:
                ulim_values[i] = ulimit_value
         
            # Log information
            if self.logExplicit(): 
                self.log.header3("Results of bin "+str(i)+": MJD "+str(tmin.mjd())+"-"+str(tmax.mjd()))
                for col in columns:
                    if "e_" == col.name()[:2]:
                        continue
                    value = source.spectral()[col.name()].value()
                    error = source.spectral()[col.name()].error()
                    unit = source.spectral()[col.name()].unit()
                    self.log(" > "+col.name()+": "+str(value)+" +- "+str(error)+" "+unit+"\n")
                if self.m_calc_ts and TSvalues[i] > 0.0:
                    self.log(" > TS = "+str(TS)+" \n")
                if self.m_calc_ulimit and ulim_values[i] > 0.0:
                    self.log(" > UL = "+str(ulim_values[i])+" [ph/cm2/s]")
                self.log("\n")

        # Append filles columns to fits table    
        table.append(MJD)
        table.append(e_MJD)
        for col in columns:
            table.append(col)
        table.append(TSvalues)
        table.append(ulim_values)
        
        # Create the FITS file now
        self.fits = gammalib.GFits()
        self.fits.append(table)
            
        # Return
        return
Example #41
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 input parameters into logger
        if self.logTerse():
            self.log_parameters()
            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.m_srcname:
                for par in model:
                    if par.is_free() and self.logExplicit():
                        self.log(" Fixing \""+par.name()+"\"\n")
                    par.fix()
                if par.is_fixed() and self.logExplicit():
                    self.log(" Freeing \""+par.name()+"\"\n")
                model.spectral()[0].free()
                if self.m_calc_ts:
                    model.tscalc(True)
                
            elif self.m_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.m_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")      
        
        # Initialise FITS Table with extension "SPECTRUM"
        table = gammalib.GFitsBinTable(self.m_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
        energy      = gammalib.GFitsTableDoubleCol("Energy", self.m_ebounds.size())
        energy.unit("TeV")
        energy_low  = gammalib.GFitsTableDoubleCol("ed_Energy", self.m_ebounds.size())
        energy_low.unit("TeV")
        energy_high  = gammalib.GFitsTableDoubleCol("eu_Energy", self.m_ebounds.size())
        energy_high.unit("TeV")
        flux        = gammalib.GFitsTableDoubleCol("Flux", self.m_ebounds.size())
        flux.unit("erg/cm2/s")
        flux_err    = gammalib.GFitsTableDoubleCol("e_Flux", self.m_ebounds.size())
        flux_err.unit("erg/cm2/s")
        TSvalues    = gammalib.GFitsTableDoubleCol("TS", self.m_ebounds.size())
        ulim_values = gammalib.GFitsTableDoubleCol("UpperLimit", self.m_ebounds.size())
        ulim_values.unit("erg/cm2/s")

        # Loop over energy bins
        for i in range(self.m_ebounds.size()):

            # Log information
            if self.logTerse():
                self.log("\n")
                self.log.header2("Energy bin "+str(i))

            # Get energy boundaries
            emin      = self.m_ebounds.emin(i)
            emax      = self.m_ebounds.emax(i)
            elogmean  = self.m_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()
            
            # Log information
            if self.logExplicit():
                    self.log.header3("Selecting events")
            
            # Select events
            select = ctools.ctselect(self.obs)
            select["emin"].real(emin.TeV())    
            select["emax"].real(emax.TeV()) 
            select["tmin"].value("UNDEFINED")
            select["tmax"].value("UNDEFINED")
            select["rad"].value("UNDEFINED")
            select["ra"].value("UNDEFINED")
            select["dec"].value("UNDEFINED")
            select.run()  

            # Retrieve observation
            obs = select.obs()

            # Binned analysis
            if self.m_binned:

                # Header
                if self.logTerse():
                    self.log.header3("Binning events")
                
                # Bin events
                bin = ctools.ctbin(select.obs())
                bin["usepnt"].boolean(False)
                bin["ebinalg"].string("LOG")
                bin["xref"].real(self.m_xref)
                bin["yref"].real(self.m_yref)
                bin["binsz"].real(self.m_binsz)
                bin["nxpix"].integer(self.m_nxpix)
                bin["nypix"].integer(self.m_nypix)
                bin["enumbins"].integer(self.m_ebins)
                bin["emin"].real(emin.TeV())
                bin["emax"].real(emax.TeV())        
                bin["coordsys"].string(self.m_coordsys)
                bin["proj"].string(self.m_proj)            
                bin.run()
                
                # Header
                if self.logTerse():
                    self.log.header3("Creating exposure cube")
                
                # Create exposure cube
                expcube = ctools.ctexpcube(select.obs())
                expcube["incube"].filename("NONE")
                expcube["usepnt"].boolean(False)
                expcube["ebinalg"].string("LOG")
                expcube["xref"].real(self.m_xref)
                expcube["yref"].real(self.m_yref)
                expcube["binsz"].real(self.m_binsz)
                expcube["nxpix"].integer(self.m_nxpix)
                expcube["nypix"].integer(self.m_nypix)
                expcube["enumbins"].integer(self.m_ebins)
                expcube["emin"].real(emin.TeV())
                expcube["emax"].real(emax.TeV()) 
                expcube["coordsys"].string(self.m_coordsys)
                expcube["proj"].string(self.m_proj)               
                expcube.run()
                
                # Header
                if self.logTerse():
                    self.log.header3("Creating PSF cube")
                
                # Create psf cube
                psfcube = ctools.ctpsfcube(select.obs())
                psfcube["incube"].filename("NONE")
                psfcube["usepnt"].boolean(False)
                psfcube["ebinalg"].string("LOG")
                psfcube["xref"].real(self.m_xref)
                psfcube["yref"].real(self.m_yref)
                psfcube["binsz"].real(self.m_binsz)
                psfcube["nxpix"].integer(self.m_nxpix)
                psfcube["nypix"].integer(self.m_nypix)
                psfcube["enumbins"].integer(self.m_ebins)
                psfcube["emin"].real(emin.TeV())
                psfcube["emax"].real(emax.TeV())  
                psfcube["coordsys"].string(self.m_coordsys)
                psfcube["proj"].string(self.m_proj)               
                psfcube.run()
                
                # Header
                if self.logTerse():
                    self.log.header3("Creating background cube")
                
                # Create background cube
                bkgcube = ctools.ctbkgcube(select.obs())
                bkgcube["incube"].filename("NONE")
                bkgcube["usepnt"].boolean(False)
                bkgcube["ebinalg"].string("LOG")
                bkgcube["xref"].real(self.m_xref)
                bkgcube["yref"].real(self.m_yref)
                bkgcube["binsz"].real(self.m_binsz)
                bkgcube["nxpix"].integer(self.m_nxpix)
                bkgcube["nypix"].integer(self.m_nypix)
                bkgcube["enumbins"].integer(self.m_ebins)
                bkgcube["emin"].real(emin.TeV())
                bkgcube["emax"].real(emax.TeV()) 
                bkgcube["coordsys"].string(self.m_coordsys)
                bkgcube["proj"].string(self.m_proj)                
                bkgcube.run()
                
                # Set new binned observation
                obs = bin.obs()
                
                # Set precomputed binned response
                obs[0].response(expcube.expcube(), psfcube.psfcube(), bkgcube.bkgcube())

                # Get new models
                models = bkgcube.models()
                
                # Fix background models if required
                if self.m_fix_bkg:
                    for model in models:
                        if not model.classname() == "GModelSky":
                            for par in model:
                                par.fix()
                                
                # Set new models to binned observation           
                obs.models(models)
                
            # Header
            if self.logTerse():
                self.log.header3("Performing fit")
                             
            # Likelihood
            like = ctools.ctlike(obs)
            like.run()
            
            # Skip bin if no event was present
            if like.obs().logL() == 0.0:
                
                # Log information
                if self.logTerse():
                    self.log("No event in this bin. Bin is skipped\n")

                # Set all values to 0
                flux[i]        = 0.0
                flux_err[i]    = 0.0
                TSvalues[i]    = 0.0
                ulim_values[i] = 0.0
                continue
                         
            # Get results
            fitted_models = like.obs().models()
            source        = fitted_models[self.m_srcname]

            # Calculate Upper Limit            
            ulimit_value = -1.0
            if self.m_calc_ulimit:
                
                # Logging information
                if self.logTerse():
                    self.log.header3("Computing upper limit")
                  
                # Create upper limit object  
                ulimit = ctools.ctulimit(like.obs())
                ulimit["srcname"].string(self.m_srcname)
                ulimit["eref"].real(elogmean.TeV())
                
                # Try to run upper limit and catch exceptions
                try:
                    ulimit.run()
                    ulimit_value = ulimit.diff_ulimit()
                except:
                    if self.logTerse():
                        self.log("Upper limit calculation failed\n")
                    ulimit_value = -1.0
            
            # Get TS value
            TS = -1.0
            if self.m_calc_ts:
                TS = source.ts() 
              
            # Get differential flux    
            fitted_flux = source.spectral().eval(elogmean,gammalib.GTime())
            
            # 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
            
            # 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.logExplicit(): 
                self.log("Bin "+str(i)+" ["+str(emin.TeV())+"-"+str(emax.TeV())+"] TeV: ")
                self.log("Flux = "+str(flux[i]))
                self.log(" +- "+str(flux_err[i])+" [erg/cm2/s]")
                if self.m_calc_ts and TSvalues[i] > 0.0:
                    self.log(", TS = "+str(TS))
                if self.m_calc_ulimit and ulim_values[i] > 0.0:
                    self.log(", UL = "+str(ulim_values[i])+" [erg/cm2/s]")
                self.log("\n")

        # Append filles 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)
        
        # Create the FITS file now
        self.fits = gammalib.GFits()
        self.fits.append(table)
            
        # Return
        return
Example #42
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 observation into logger
        self._log_observations(gammalib.NORMAL, self.obs(), 'Observation')
        
        # Store and clear observations to split them into phase bins
        orig_obs = self.obs().copy()
        
        # Dictionary to save phase fitted models
        self._fitmodels = {}

        # Write header
        self._log_header1(gammalib.TERSE, 'Generate phase curve')

        # Loop over all phases
        for phbin in self._phbins:

            # Write time bin into header
            self._log_header2(gammalib.TERSE, 'PHASE %f - %f' %
                              (phbin[0], phbin[1]))

            # Select events
            select = ctools.ctselect(orig_obs)
            select['emin'] = self['emin'].real()
            select['emax'] = self['emax'].real()
            select['tmin'] = 'UNDEFINED'
            select['tmax'] = 'UNDEFINED'
            select['rad']  = 'UNDEFINED'
            select['ra']   = 'UNDEFINED'
            select['dec']  = 'UNDEFINED'
            select['expr'] = 'PHASE>'+str(phbin[0])+' && PHASE<'+str(phbin[1])
            select.run()

            # Set phase string
            phstr = str(phbin[0]) + '-' + str(phbin[1])

            # Add phase to observation id
            for i in range(0,select.obs().size()):
                oldid = select.obs()[i].id()
                select.obs()[i].id(oldid+'_'+phstr)
            obs = select.obs()
            
            # If an On/Off analysis is requested generate the On/Off observations
            if self._onoff:
                obs = obsutils.get_onoff_obs(self, select.obs())

            # ... otherwise, if stacked analysis is requested then bin the
            # events and compute the stacked response functions and setup
            # an observation container with a single stacked observation.
            elif self._stacked:
                obs = obsutils.get_stacked_obs(self, select.obs())

            # Header
            self._log_header3(gammalib.EXPLICIT, 'Fitting the data')

            # The On/Off analysis can produce empty observation containers,
            # e.g., when on-axis observations are used. To avoid ctlike asking
            # for a new observation container (or hang, if in interactive mode)
            # we'll run ctlike only if the size is >0
            if obs.size() > 0:

                # Do maximum likelihood model fitting
                like = ctools.ctlike(obs)
                like['edisp'] = self['edisp'].boolean()
                like.run()

                # Renormalize models to phase selection
                # TODO move the scaling from the temporal to the spectral component
                for model in like.obs().models():
                    scaled_norm = model['Normalization'].value()/(phbin[1]-phbin[0])
                    model['Normalization'].value(scaled_norm)

                # Store fit model
                self._fitmodels[phstr] = like.obs().models().copy()

            # ... otherwise we set an empty model container
            else:
                self._log_string(gammalib.TERSE,
                                 'PHASE %f - %f: no observations available'
                                 ' for fitting' %(phbin[0], phbin[1]))

                # Set empty models container
                self._fitmodels[phstr] = gammalib.GModels()

        # Create FITS file
        self._create_fits()

        # Optionally publish phase curve
        if self['publish'].boolean():
            self.publish()

        # Return
        return
Example #43
0
def prepare(obsname, bkgname, rad=2.0, emin=0.3, emax=50.0, ebins=20):
    """
    Prepare events for analysis

    Parameters
    ----------
    obsname : str
        Observation definition XML file
    bkgname : str
        Background model definition XML file
    rad : float, optional
        Selection radius (degrees)
    emin : float, optional
        Minimum energy for analysis (TeV)
    emax : float, optional
        Maximum energy for analysis (TeV)
    ebins : int, optional
        Number of energy bins
    """
    # Set filenames
    cntcube = 'rx_stacked%2.2d_cntcube.fits' % ebins
    expcube = 'rx_stacked%2.2d_expcube.fits' % ebins
    psfcube = 'rx_stacked%2.2d_psfcube.fits' % ebins
    edispcube = 'rx_stacked%2.2d_edispcube.fits' % ebins
    bkgcube = 'rx_stacked%2.2d_bkgcube.fits' % ebins
    obsname_binned = add_attribute(obsname, '_binned%2.2d' % ebins)
    bkgname_stacked = add_attribute(bkgname, '_stacked')
    obsname_stacked = add_attribute(obsname, '_stacked%2.2d' % ebins)
    obsname_stacked_edisp = add_attribute(obsname_stacked, '_edisp')

    # Generate background lookup
    generate_background_lookup()

    # Continue only if selected events do not exist
    if not os.path.isfile(obsname):

        # Setup task parameters
        select = ctools.ctselect()
        select['inobs'] = '$HESSDATA/obs/obs_rx.xml'
        select['outobs'] = obsname
        select['ra'] = 'UNDEF'
        select['dec'] = 'UNDEF'
        select['rad'] = rad
        select['tmin'] = 'UNDEF'
        select['tmax'] = 'UNDEF'
        select['emin'] = emin
        select['emax'] = emax
        select['usethres'] = 'DEFAULT'
        select['logfile'] = 'rx_hess_select_events.log'
        select.logFileOpen()

        # Select events
        select.execute()

    # Continue only if background model does not exist
    if not os.path.isfile(bkgname):

        # Setup task parameters
        bkg = cscripts.csbkgmodel()
        bkg['inobs'] = '$HESSDATA/obs/obs_rx.xml'
        bkg['outmodel'] = bkgname
        bkg['instrument'] = 'HESS'
        bkg['spatial'] = 'LOOKUP'
        bkg['slufile'] = 'off_lookup.fits'
        bkg['gradient'] = True
        bkg['spectral'] = 'NODES'
        bkg['ebinalg'] = 'LOG'
        bkg['emin'] = emin
        bkg['emax'] = 30.0
        bkg['enumbins'] = 8
        bkg['runwise'] = True
        bkg['rad'] = rad
        bkg['logfile'] = 'rx_hess_create_background.log'
        bkg.logFileOpen()

        # Generate background model
        bkg.execute()

    # Continue only if counts cube does not exist
    if not os.path.isfile(cntcube):

        # Setup task parameters
        ctbin = ctools.ctbin()
        ctbin['inobs'] = obsname
        ctbin['outobs'] = cntcube
        ctbin['ebinalg'] = 'LOG'
        ctbin['emin'] = emin
        ctbin['emax'] = emax
        ctbin['enumbins'] = ebins
        ctbin['coordsys'] = 'CEL'
        ctbin['proj'] = 'TAN'
        ctbin['xref'] = 258.1125
        ctbin['yref'] = -39.6867
        ctbin['nxpix'] = 300
        ctbin['nypix'] = 300
        ctbin['binsz'] = 0.02
        ctbin['logfile'] = 'rx_hess_create_cntcube.log'
        ctbin.logFileOpen()

        # Generate counts cube
        ctbin.execute()

    # Continue only if counts cubes for binned analysis do not exist
    if not os.path.isfile(obsname_binned):

        # Setup task parameters
        ctbin = ctools.ctbin()
        ctbin['inobs'] = obsname
        ctbin['outobs'] = obsname_binned
        ctbin['stack'] = False
        ctbin['usepnt'] = True
        ctbin['ebinalg'] = 'LOG'
        ctbin['emin'] = emin
        ctbin['emax'] = emax
        ctbin['enumbins'] = ebins
        ctbin['coordsys'] = 'CEL'
        ctbin['proj'] = 'TAN'
        ctbin['nxpix'] = 200
        ctbin['nypix'] = 200
        ctbin['binsz'] = 0.02
        ctbin['logfile'] = 'rx_hess_create_cntcube_binned.log'
        ctbin.logFileOpen()

        # Generate counts cubes
        ctbin.execute()

    # Continue only if exposure cube does not exist
    if not os.path.isfile(expcube):

        # Setup task parameters
        ctexpcube = ctools.ctexpcube()
        ctexpcube['inobs'] = obsname
        ctexpcube['incube'] = 'NONE'
        ctexpcube['ebinalg'] = 'LOG'
        ctexpcube['emin'] = 0.1  # Full energy range
        ctexpcube['emax'] = 100.0  # Full energy range
        ctexpcube['enumbins'] = 300  # Factor ~3 oversampling of IRF
        ctexpcube['coordsys'] = 'CEL'
        ctexpcube['proj'] = 'TAN'
        ctexpcube['xref'] = 258.1125
        ctexpcube['yref'] = -39.6867
        ctexpcube['nxpix'] = 300
        ctexpcube['nypix'] = 300
        ctexpcube['binsz'] = 0.02
        ctexpcube['outcube'] = expcube
        ctexpcube['logfile'] = 'rx_hess_create_expcube.log'
        ctexpcube.logFileOpen()

        # Generate exposure cube
        ctexpcube.execute()

    # Continue only if PSF cube does not exist
    if not os.path.isfile(psfcube):

        # Setup task parameters
        ctpsfcube = ctools.ctpsfcube()
        ctpsfcube['inobs'] = obsname
        ctpsfcube['incube'] = 'NONE'
        ctpsfcube['ebinalg'] = 'LOG'
        ctpsfcube['emin'] = 0.1  # Full energy range
        ctpsfcube['emax'] = 100.0  # Full energy range
        ctpsfcube['enumbins'] = 300  # Factor ~3 oversampling of IRF
        ctpsfcube['coordsys'] = 'CEL'
        ctpsfcube['proj'] = 'TAN'
        ctpsfcube['xref'] = 258.1125
        ctpsfcube['yref'] = -39.6867
        ctpsfcube['nxpix'] = 30
        ctpsfcube['nypix'] = 30
        ctpsfcube['binsz'] = 0.2
        ctpsfcube['amax'] = 0.7  # Full H.E.S.S. PSF range
        ctpsfcube['anumbins'] = 300  # Factor ~2 oversampling of IRF
        ctpsfcube['outcube'] = psfcube
        ctpsfcube['logfile'] = 'rx_hess_create_psfcube.log'
        ctpsfcube.logFileOpen()

        # Generate PSF cube
        ctpsfcube.execute()

    # Continue only if energy dispersion cube does not exist
    if not os.path.isfile(edispcube):

        # Setup task parameters
        ctedispcube = ctools.ctedispcube()
        ctedispcube['inobs'] = obsname
        ctedispcube['incube'] = 'NONE'
        ctedispcube['ebinalg'] = 'LOG'
        ctedispcube['emin'] = 0.1  # Full energy range
        ctedispcube['emax'] = 100.0  # Full energy range
        ctedispcube['enumbins'] = 300  # Factor ~3 oversampling of IRF
        ctedispcube['coordsys'] = 'CEL'
        ctedispcube['proj'] = 'TAN'
        ctedispcube['xref'] = 258.1125
        ctedispcube['yref'] = -39.6867
        ctedispcube['nxpix'] = 30
        ctedispcube['nypix'] = 30
        ctedispcube['binsz'] = 0.2
        ctedispcube['migramax'] = 5.0
        ctedispcube['migrabins'] = 300
        ctedispcube['outcube'] = edispcube
        ctedispcube['logfile'] = 'rx_hess_create_edispcube.log'
        ctedispcube.logFileOpen()

        # Generate energy dispersion cube
        ctedispcube.execute()

    # Continue only if background cube does not exist
    if not os.path.isfile(bkgcube):

        # Setup task parameters
        ctbkgcube = ctools.ctbkgcube()
        ctbkgcube['inobs'] = obsname
        ctbkgcube['incube'] = cntcube
        ctbkgcube['inmodel'] = bkgname
        ctbkgcube['outcube'] = bkgcube
        ctbkgcube['outmodel'] = bkgname_stacked
        ctbkgcube['logfile'] = 'rx_hess_create_bkgcube.log'
        ctbkgcube.logFileOpen()

        # Generate background cube
        ctbkgcube.execute()

    # Continue only if stacked observation definition XML file does not
    # exist
    if not os.path.isfile(obsname_stacked):

        # Build stacked observation
        run = gammalib.GCTAObservation(cntcube, expcube, psfcube, bkgcube)
        run.name('RX J1713.7-3946')
        run.instrument('HESS')

        # Append to observation container
        obs = gammalib.GObservations()
        obs.append(run)

        # Save observation container
        obs.save(obsname_stacked)

    # Continue only if stacked observation definition XML file with energy
    # energy dispersion enabled does not exist
    if not os.path.isfile(obsname_stacked_edisp):

        # Build stacked observation
        run = gammalib.GCTAObservation(cntcube, expcube, psfcube, edispcube,
                                       bkgcube)
        run.name('RX J1713.7-3946')
        run.instrument('HESS')

        # Append to observation container
        obs = gammalib.GObservations()
        obs.append(run)

        # Save observation container
        obs.save(obsname_stacked_edisp)

    # Continue only if stacked model definition XML file does exist
    if os.path.isfile(bkgname_stacked):

        # Load model definition XML files
        joint = gammalib.GModels(bkgname)
        stacked = gammalib.GModels(bkgname_stacked)

        # Get spectral component of joint file and remplace it as spectral
        # component of stacked file
        spectrum = joint[0].spectral()
        for i in range(spectrum.nodes()):
            spectrum.intensity(i, 1.0)
        spectrum.autoscale()
        stacked[0].spectral(spectrum)

        # Save stacked model
        stacked.save(bkgname_stacked)

    # Return
    return
Example #44
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 input parameters into logger
        if self.logTerse():
            self.log_parameters()
            self.log("\n")

        # Write spectral binning into header
        if self.logTerse():
            self.log("\n")
            self.log.header1("Spectral binning")
            if self.m_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.m_ebounds.size()):
                self.log.parformat("Bin "+str(i+1))
                self.log(str(self.m_ebounds.emin(i)))
                self.log(" - ")
                self.log(str(self.m_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.m_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.m_calc_ts:
                    model.tscalc(True)

            elif self.m_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.m_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.m_ebounds))    

        # Initialise FITS Table with extension "SPECTRUM"
        table = gammalib.GFitsBinTable(self.m_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
        energy       = gammalib.GFitsTableDoubleCol("Energy", self.m_ebounds.size())
        energy_low   = gammalib.GFitsTableDoubleCol("ed_Energy", self.m_ebounds.size())
        energy_high  = gammalib.GFitsTableDoubleCol("eu_Energy", self.m_ebounds.size())
        flux         = gammalib.GFitsTableDoubleCol("Flux", self.m_ebounds.size())
        flux_err     = gammalib.GFitsTableDoubleCol("e_Flux", self.m_ebounds.size())
        TSvalues     = gammalib.GFitsTableDoubleCol("TS", self.m_ebounds.size())
        ulim_values  = gammalib.GFitsTableDoubleCol("UpperLimit", self.m_ebounds.size())
        Npred_values = gammalib.GFitsTableDoubleCol("Npred", self.m_ebounds.size())
        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(self.m_ebounds.size()):

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

            # Get energy boundaries
            emin      = self.m_ebounds.emin(i)
            emax      = self.m_ebounds.emax(i)
            elogmean  = self.m_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.m_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.m_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.m_srcname]

            # Calculate Upper Limit            
            ulimit_value = -1.0
            if self.m_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.m_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.m_calc_ts:
                TS = source.ts() 

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

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

            # 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.m_calc_ulimit and ulim_values[i] > 0.0:
                    self.log(" [< "+str(ulim_values[i])+"]")
                self.log(" erg/cm2/s")
                if self.m_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
Example #45
0
def pipeline(model_name):
    """
    Unbinned in-memory analysis pipeline

    This function implements an analysis pipeline that successively calls
    ctobssim, ctselect and ctlike without saving the intermediate results as
    FITS files on disk. All data is only hold in memory.
    """
    # Set script parameters
    caldb = 'prod2'
    irf = 'South_0.5h'
    ra = 83.63
    dec = 22.01
    rad_sim = 5.0
    tstart = 0.0
    tstop = 180.0
    emin = 0.1
    emax = 100.0
    rad_select = 3.0

    # Write model name
    print('*** Model: ' + model_name + ' ************************************')

    # Initialise timing
    wall_seconds = 0.0
    cpu_seconds = 0.0

    # Simulate events
    sim = ctools.ctobssim()
    sim['inmodel'] = model_name
    sim['caldb'] = caldb
    sim['irf'] = irf
    sim['ra'] = ra
    sim['dec'] = dec
    sim['rad'] = rad_sim
    sim['tmin'] = tstart
    sim['tmax'] = tstop
    sim['emin'] = emin
    sim['emax'] = emax
    sim.run()

    # Select events
    select = ctools.ctselect(sim.obs())
    select['ra'] = ra
    select['dec'] = dec
    select['rad'] = rad_select
    select['tmin'] = tstart
    select['tmax'] = tstop
    select['emin'] = emin
    select['emax'] = emax
    select.run()

    # Perform maximum likelihood fitting
    like = ctools.ctlike(select.obs())
    like.run()

    # Show model fitting results
    print(like.obs().models()[0])

    # Return
    return
Example #46
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 observation into logger
        self._log_observations(gammalib.NORMAL, self.obs(), 'Observation')

        # Get time boundaries
        tmin = self._tbins.tstart(0)
        tmax = self._tbins.tstop(self._tbins.size()-1)

        # Select events
        select = ctools.ctselect(self.obs())
        select['emin'] = self['emin'].real()
        select['emax'] = self['emax'].real()
        select['tmin'] = tmin.convert(ctools.time_reference)
        select['tmax'] = tmax.convert(ctools.time_reference)
        select['rad']  = 'UNDEFINED'
        select['ra']   = 'UNDEFINED'
        select['dec']  = 'UNDEFINED'
        select.run()

        # Extract observations
        self.obs(select.obs().copy())

        # Write observation into logger
        self._log_header1(gammalib.TERSE,
                          gammalib.number('Selected observation',
                                          len(self.obs())))

        # Adjust model parameters dependent on user parameters
        self._adjust_model_pars()

        # Write header
        self._log_header1(gammalib.TERSE, 'Generate lightcurve')

        # Initialise list of result dictionaries
        results = []

        # Get source parameters
        pars = self._get_free_par_names()

        # Loop over time bins
        for i in range(self._tbins.size()):

            # Get time boundaries
            tmin = self._tbins.tstart(i)
            tmax = self._tbins.tstop(i)

            # Write time bin into header
            self._log_header2(gammalib.TERSE, 'MJD %f - %f ' %
                              (tmin.mjd(), tmax.mjd()))

            # Compute time bin center and time width
            twidth = 0.5 * (tmax - tmin) # in seconds
            tmean  = tmin + twidth

            # Initialise result dictionary
            result = {'mjd': tmean.mjd(),
                      'e_mjd': twidth / gammalib.sec_in_day,
                      'ts': 0.0,
                      'ul_diff': 0.0,
                      'ul_flux': 0.0,
                      'ul_eflux': 0.0,
                      'pars': pars,
                      'values': {}}

            # Log information
            self._log_header3(gammalib.EXPLICIT, 'Selecting events')

            # Select events
            select = ctools.ctselect(self.obs())
            select['emin'] = self['emin'].real()
            select['emax'] = self['emax'].real()
            select['tmin'] = tmin.convert(ctools.time_reference)
            select['tmax'] = tmax.convert(ctools.time_reference)
            select['rad']  = 'UNDEFINED'
            select['ra']   = 'UNDEFINED'
            select['dec']  = 'UNDEFINED'
            select.run()

            # Retrieve observation
            obs = select.obs()

            # Deal with stacked and On/Off Observations
            if self._stacked or self._onoff:

                # If a stacked analysis is requested bin the events
                # and compute the stacked response functions and setup
                # an observation container with a single stacked observation.
                if self._stacked:
                    new_obs = obsutils.get_stacked_obs(self, obs)

                # ... otherwise if On/Off analysis is requested generate
                # the On/Off observations and response
                elif self._onoff:
                    new_obs = obsutils.get_onoff_obs(self, obs)

                # Extract models
                models = new_obs.models()

                # Fix background models if required
                if self['fix_bkg'].boolean():
                    for model in models:
                        if model.classname() != 'GModelSky':
                            for par in model:
                                par.fix()

                # Put back models
                new_obs.models(models)

                # Continue with new oberservation container
                obs = new_obs

            # Header
            self._log_header3(gammalib.EXPLICIT, 'Fitting the data')

            # Do maximum likelihood model fitting
            if obs.size() > 0:
                like = ctools.ctlike(obs)
                like['edisp'] = self['edisp'].boolean()
                like.run()

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

                    # Signal skipping of bin
                    self._log_value(gammalib.TERSE, 'Warning',
                                    'No event in this time bin, skip bin.')

                    # Set all results to 0
                    for par in pars:
                        result['values'][par]      = 0.0
                        result['values']['e_'+par] = 0.0

                    # Append result
                    results.append(result)

                    # Continue with next time bin
                    continue

                # Retrieve model fitting results for source of interest
                source = like.obs().models()[self._srcname]

                # Extract parameter values
                for par in pars:
                    result['values'][par]      = source[par].value()
                    result['values']['e_'+par] = source[par].error()

                # Calculate upper limit (-1 if not computed)
                #ul_diff, ul_flux, ul_eflux = self._compute_ulimit(like.obs())
                ul_diff, ul_flux, ul_eflux = self._compute_ulimit(obs)
                if ul_diff > 0.0:
                    result['ul_diff']  = ul_diff
                    result['ul_flux']  = ul_flux
                    result['ul_eflux'] = ul_eflux

                # Extract Test Statistic value
                if self['calc_ts'].boolean():
                    result['ts'] = source.ts()

                # Append result to list of dictionaries
                results.append(result)

                # Log results for this time bin
                self._log.header3('Results')
                pars = self._get_free_par_names()
                for par in pars:
                    value = source[par].value()
                    error = source[par].error()
                    unit  = source[par].unit()
                    self._log_value(gammalib.NORMAL, par,
                                    str(value)+' +/- '+str(error)+' '+unit)
                if ul_diff > 0.0:
                    self._log_value(gammalib.NORMAL, 'Upper flux limit',
                                    str(result['ul_diff'])+' ph/cm2/s/MeV')
                    self._log_value(gammalib.NORMAL, 'Upper flux limit',
                                    str(result['ul_flux'])+' ph/cm2/s')
                    self._log_value(gammalib.NORMAL, 'Upper flux limit',
                                    str(result['ul_eflux'])+' erg/cm2/s')
                if self['calc_ts'].boolean():
                    self._log_value(gammalib.NORMAL, 'Test Statistic', result['ts'])

            # Otherwise, if observations size is 0, signal bin is skipped and
            # fill results table with zeros
            else:
                self._log_value(gammalib.TERSE, 'Warning',
                                'No observations available in this time bin, '
                                'skip bin.')

                # Set all results to 0
                for par in pars:
                    result['values'][par]        = 0.0
                    result['values']['e_' + par] = 0.0

                # Append result
                results.append(result)

                # Continue with next time bin
                continue

        # Create FITS table from results
        table = self._create_fits_table(results)

        # Create FITS file and append FITS table to FITS file
        self._fits = gammalib.GFits()
        self._fits.append(table)

        # Optionally publish light curve
        if self['publish'].boolean():
            self.publish()

        # Return
        return
Example #47
0
    def _select_obs(self, emin, emax):
        """
        Select observations for energy interval

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

        Returns
        -------
        obs : `~gammalib.GObservations`
            Observation container
        """
        # Use ctcubemask for binned analysis
        if self._binned_mode:

            # Write header
            self._log_header3(gammalib.EXPLICIT, '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().copy()

        # Use ...
        elif self._onoff_mode:

            # Write header
            self._log_header3(gammalib.EXPLICIT, 'Filtering PHA, ARF and RMF')

            # Initialise observation container
            obs = gammalib.GObservations()

            # Loop over all input observations and select energy bins for
            # all On/Off observations
            for run in self.obs():
                if run.classname() == 'GCTAOnOffObservation':
                    obs.append(self._select_onoff_obs(run, emin, emax))

            # Append models
            obs.models(self.obs().models())

        # Use ctselect for unbinned analysis
        else:

            # Write header
            self._log_header3(gammalib.EXPLICIT, 'Selecting events')

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

            # Retrieve observation
            obs = select.obs().copy()

        # Return observation container
        return obs
Example #48
0
    def run_pipeline(self, debug=False, seed=0):
        """
		Test unbinned pipeline with FITS file saving
		"""
        # Set script parameters
        events_name = 'events.fits'
        cubefile_name = ''
        selected_events_name = 'selected_events.fits'
        result_name = 'results.xml'

        if self.simfilename and self.eventfilename:
            print('error')
            exit(10)

        ############ Simulate events

        if self.simfilename:

            # Setup simulation model
            if self.simfilename:
                self.obs.models(gammalib.GModels(self.simfilename))

            if self.runconf.WorkInMemory == 0:
                print('# Generate simulated event list on disk')
                # Simulate events on disk
                sim = ctools.ctobssim(self.obs)
                sim['outevents'] = events_name
                sim['debug'] = debug
                sim['seed'] = seed
                sim.execute()
                self.eventfilename = events_name

            if self.runconf.WorkInMemory == 1:
                print('# Generate simulated event list in memory')
                # Simulate events on memory
                sim = ctools.ctobssim(self.obs)
                sim['debug'] = debug
                sim['seed'] = seed
                sim.run()

        #if self.runfilename is not present
        #   import into DB if any
        #	exit(0)

        ############ Get events from DB

        if not self.simfilename and not self.eventfilename:
            #load from DB
            print('# Load event list from DB')

            #write selected_events_name
            if self.runconf.timeref_timesys == 'tt':
                tstart_tt = self.runconf.tmin
                tstop_tt = self.runconf.tmax
            if self.runconf.timeref_timesys == 'mjd':
                tstart_tt = Utility.convert_mjd_to_tt(self.runconf.tmin)
                tstop_tt = Utility.convert_mjd_to_tt(self.runconf.tmax)

            #tstart_tt = self.runconf.tmin
            #tstop_tt = self.runconf.tmax
            observationid = self.obsconf.id
            print("tstart" + str(tstart_tt))
            print("tstop" + str(tstart_tt))
            print(self.runconf.timeref_timesys)

            conf_dictionary = get_path_conf()

            path_base_fits = conf_dictionary['path_base_fits']
            tref_mjd = self.runconf.timeref

            if self.runconf.roi_frame == 'fk5':
                obs_ra = self.obsconf.roi_ra
                obs_dec = self.obsconf.roi_dec
            else:
                exit(10)

            emin = self.runconf.emin
            emax = self.runconf.emax
            fov = self.obsconf.roi_fov
            instrumentname = self.obsconf.instrument

            datarepository_dictionary = get_data_repository(instrumentname)
            datarepositoryid = datarepository_dictionary['datarepositoryid']

            print("before write fits")
            print(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
            events_name = write_fits(tstart_tt, tstop_tt, observationid,
                                     datarepositoryid, path_base_fits,
                                     tref_mjd, obs_ra, obs_dec, emin, emax,
                                     180, instrumentname)
            print("after write fits")
            print(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])

            print("fitsname" + events_name)
            if self.runconf.WorkInMemory == 2:
                print('# Load event list from disk')
                #Load events from fits file on memory
                sim = ctools.ctobssim(self.obs)
                events = sim.obs()[0].events()
                for event in events:
                    print(event)

                #events.load(events_name)
                events.load(selected_events_name)

        ############ Select events

        if self.runconf.WorkInMemory == 1:
            print('# Select event list in memory')
            select = ctools.ctselect(sim.obs())

        #using file
        if self.runconf.WorkInMemory == 0:
            print('# Select event list from disk')
            select = ctools.ctselect()
            select['inobs'] = events_name
            select['outobs'] = selected_events_name

        select['ra'] = self.runconf.roi_ra
        select['dec'] = self.runconf.roi_dec
        select['rad'] = self.runconf.roi_ringrad
        select['tmin'] = 'MJD ' + str(self.runconf.tmin)
        #select['tmin']   = 'INDEF'
        #select['tmin'] = 0.0
        #select['tmin'] = 'MJD 55197.0007660185'
        #select['tmax']   = self.runconf.tmax
        #select['tmax']   = 'INDEF'
        select['tmax'] = 'MJD ' + str(self.runconf.tmax)
        #select['tmax']   = 55197.0007660185 + self.runconf.tmax / 86400.
        select['emin'] = self.runconf.emin
        select['emax'] = self.runconf.emax

        if self.runconf.WorkInMemory == 1:
            select.run()

        if self.runconf.WorkInMemory == 0:
            select.execute()

        print("after select events")
        print(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])

        #print(self.runconf.roi_ra)
        #print(self.runconf.roi_dec)
        #print(self.obsconf.obs_fov)
        #print(self.runconf.tmin)
        #print(self.runconf.tmax)
        #print(self.runconf.emin)
        #print(self.runconf.emax)
        #print(select.obs()[0])
        print("select --")
        print(select)
        print("select --")

        if self.runconf.WorkInMemory == 2:
            print('# Load event list from disk')
            #Load events from fits file on memory
            sim = ctools.ctobssim(self.obs)
            events = sim.obs()[0].events()
            for event in events:
                print(event)

            #events.load(events_name)
            events.load(selected_events_name)

        print('Event list generated ----------------------')
        if self.runconf.WorkInMemory == 0:
            print(self.obs)
            print("obs --")
            print(self.obs[0])
            print("obs 0 --")
            localobs = self.obs

        if self.runconf.WorkInMemory == 1:
            print(select.obs())
            print(select.obs()[0])
            localobs = select.obs()

        for run in localobs:

            print('run ---' + selected_events_name)
            print("before ctbin")
            print(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])

            print(run)

            # Create container with a single observation
            container = gammalib.GObservations()
            container.append(run)

            if self.runconf.MakeCtsMap == 1:
                cubefile_name = 'cube.fits'
                #event file in memory or read from fits file on memory
                if self.runconf.WorkInMemory == 1:
                    bin = ctools.ctbin(container)

                if self.runconf.WorkInMemory == 0:
                    #event file on disk
                    bin = ctools.ctbin()
                    bin['inobs'] = selected_events_name

                #make binned map on disk
                bin['outcube'] = cubefile_name

                #common configs
                bin['ebinalg'] = self.runconf.cts_ebinalg
                bin['emin'] = self.runconf.emin
                bin['emax'] = self.runconf.emax
                bin['enumbins'] = self.runconf.cts_enumbins
                bin['nxpix'] = ceil(self.runconf.roi_ringrad * 2 /
                                    self.runconf.cts_binsz)
                bin['nypix'] = ceil(self.runconf.roi_ringrad * 2 /
                                    self.runconf.cts_binsz)
                bin['binsz'] = self.runconf.cts_binsz
                bin['coordsys'] = self.runconf.cts_coordsys
                bin['usepnt'] = self.runconf.cts_usepnt  # Use pointing for map centre
                bin['proj'] = self.runconf.cts_proj
                bin['xref'] = self.runconf.roi_ra
                bin['yref'] = self.runconf.roi_dec
                print("-- bin")
                print(bin)
                #make binned map on disk
                if self.runconf.WorkInMemory == 0:
                    bin.execute()
                    # Set observation ID if make binned map on disk
                    bin.obs()[0].id(cubefile_name)
                    bin.obs()[0].eventfile(cubefile_name)
                    os.system('mkdir -p ' + self.runconf.resdir)
                    shutil.copy(
                        './cube.fits', self.runconf.resdir + '/' +
                        self.runconf.runprefix + '_cube.fits')

                    if self.runconf.CtsMapToPng == 1:
                        title = 'OBS ' + str(
                            self.obsconf.id) + ' / MJD ' + str(
                                self.runconf.tmin) + ' - ' + 'MJD ' + str(
                                    self.runconf.tmax)
                        SkyImage.display(cubefile_name, "sky1.png", 2, title)
                        #SkyImage.dispalywithds9_cts1(cubefile_name, "sky2", 10)
                        #copy results
                        os.system('mkdir -p ' + self.runconf.resdir)
                        shutil.copy(
                            './sky1.png', self.runconf.resdir + '/' +
                            self.runconf.runprefix + '_sky1.png')

                #make binned map on memory
                if self.runconf.WorkInMemory == 1:
                    bin.run()

                # Append result to observations
                #localobs.extend(bin.obs())
            print("after ctbin")
            print(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
            #print(obs)
            #print(obs[0])
            print(str(self.obsconf.caldb))

            #hypothesis builders
            #3GHextractor
            # 3GH Extractor code
            if self.runconf.HypothesisGenerator3GH and cubefile_name:
                self.analysisfilename = CTA3GHextractor_wrapper.extract_source(
                    cubefile_name)
                print(self.analysisfilename)
                #cv2.waitKey(0)
                print('HypothesisGeneratorEG3')

            #eseguire MLE
            print('analysisfilename: ' + self.analysisfilename)
            if self.analysisfilename:
                print('before MLE')
                print(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])

                # Perform maximum likelihood fitting

                if self.runconf.WorkInMemory == 1:
                    like = ctools.ctlike(select.obs())

                if self.runconf.WorkInMemory == 0:
                    like = ctools.ctlike()

                    if (self.runconf.binned == "1"):
                        like['inobs'] = cubefile_name
                        like['expcube'] = "NONE"
                        like['psfcube'] = "NONE"
                        like['edispcube'] = "NONE"
                        like['bkgcube'] = "NONE"
                        like['statistic'] = "CHI2"

                    if (self.runconf.binned == "0"):
                        like['inobs'] = selected_events_name
                        like['statistic'] = "DEFAULT"

                like['inmodel'] = self.analysisfilename
                like['outmodel'] = result_name
                like['caldb'] = str(self.obsconf.caldb)
                like['irf'] = self.obsconf.irf

                like.execute()
                print(like)
                logL = like.opt().value()
                print(like.obs().models())

                print("after MLE")
                print(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])

                # insert logL into results.xml
                tree = etree.parse(result_name)
                contentnav = tree.find(".//source[@type='PointSource']")
                #contentdiv = contentnav.getparent()
                #contentnav.set("ts",str(logL))
                contentnav.set("runid", str(self.runconf.runid))
                #print(etree.tostring(tree,encoding="unicode",pretty_print=True))
                f = open(result_name, 'w')
                f.write(
                    etree.tostring(tree, encoding="unicode",
                                   pretty_print=True))
                f.close()

                os.system('mkdir -p ' + self.runconf.resdir)
                shutil.copy(
                    './results.xml', self.runconf.resdir + '/' +
                    self.runconf.runprefix + '_results.xml')

                if self.runconf.deleterun == "1":
                    cmd = 'rm -r ' + self.runconf.rundir
                    os.system(cmd)

            if self.runconf.HypothesisGenerator3GH:
                CTA3GHextractor_wrapper.print_graphs(self.simfilename,
                                                     result_name,
                                                     self.analysisfilename)
                #cv2.destroyAllWindows()
                print('HypothesisGeneratorEG3')

        # Return
        return
Example #49
0
obsselect.execute()

obsselect = cscripts.csobsselect()
obsselect['inobs'] = '$CTADATA/obs/obs_gc_baseline.xml'
obsselect['pntselect'] = 'CIRCLE'
obsselect['coordsys'] = 'GAL'
obsselect['glon'] = 0.0
obsselect['glat'] = 0.0
obsselect['rad'] = 5.0
obsselect['tmin'] = 'NONE'
obsselect['tmax'] = 'NONE'
obsselect['outobs'] = 'obs_gc.xml'
obsselect["debug"] = debug
obsselect.execute()

select = ctools.ctselect()
select['inobs'] = 'obs_gps.xml'
select['ra'] = 'NONE'
select['dec'] = 'NONE'
select['rad'] = 'NONE'
select['tmin'] = 'NONE'
select['tmax'] = 'NONE'
select['emin'] = 0.1
select['emax'] = 100.0
select['outobs'] = 'obs_selected_gps.xml'
select["debug"] = debug
select.execute()

select = ctools.ctselect()
select['inobs'] = 'obs_gc.xml'
select['ra'] = 'NONE'
Example #50
0
def pipeline(model_name):
    """
    Unbinned in-memory analysis pipeline

    This function implements an analysis pipeline that successively calls
    ctobssim, ctselect and ctlike without saving the intermediate results as
    FITS files on disk. All data is only hold in memory.
    """
    # Set script parameters
    caldb       = 'prod2'
    irf         = 'South_0.5h'
    ra          =   83.63
    dec         =   22.01
    rad_sim     =    5.0
    tstart      =    0.0
    tstop       =  180.0
    emin        =    0.1
    emax        =  100.0
    rad_select  =    3.0

    # Write model name
    print('*** Model: '+model_name+' ************************************')

    # Initialise timing
    wall_seconds = 0.0
    cpu_seconds  = 0.0

    # Simulate events
    sim = ctools.ctobssim()
    sim['inmodel'] = model_name
    sim['caldb']   = caldb
    sim['irf']     = irf
    sim['ra']      = ra
    sim['dec']     = dec
    sim['rad']     = rad_sim
    sim['tmin']    = tstart
    sim['tmax']    = tstop
    sim['emin']    = emin
    sim['emax']    = emax
    sim.run()

    # Select events
    select = ctools.ctselect(sim.obs())
    select['ra']   = ra
    select['dec']  = dec
    select['rad']  = rad_select
    select['tmin'] = tstart
    select['tmax'] = tstop
    select['emin'] = emin
    select['emax'] = emax
    select.run()

    # Perform maximum likelihood fitting
    like = ctools.ctlike(select.obs())
    like.run()

    # Show model fitting results
    print(like.obs().models()[0])

    # Return
    return