def ctlike_binned(events_name, cntmap_name, emin, emax, enumbins, nxpix, nypix, binsz, ra, dec, IRF, CALDB, outfile): """ Copied and modified from ctools/examples/make_binned_analysis.py """ # Bin the events first bin = ctools.ctbin() # We need this to explicitely open the log file in Python mode bin.logFileOpen() bin["evfile"].filename(events_name) bin["outfile"].filename(cntmap_name) bin["emin"].real(emin) bin["emax"].real(emax) bin["enumbins"].integer(enumbins) bin["nxpix"].integer(nxpix) bin["nypix"].integer(nypix) bin["binsz"].real(binsz) bin["coordsys"].string('GAL') bin["xref"].real(ra) bin["yref"].real(dec) bin["proj"].string('CAR') bin.execute() # Perform maximum likelihood fitting like = ctools.ctlike() like.logFileOpen() like["infile"].filename(cntmap_name) like["srcmdl"].filename('$CTOOLS/share/models/crab.xml') like["outmdl"].filename(outfile) like["caldb"].string(CALDB) like["irf"].string(IRF) like.execute()
def ctbin(self,obsXml= None, log=False,debug=False, **kwargs): ''' Create ctbin 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 ctbin to create count map") self.bin = ct.ctbin() self._fill_app( self.bin,log=log,debug=debug, **kwargs) self.bin["outcube"] = join(self.outdir,self.config['file']["cntcube"]) if self.verbose: print self.bin # Run ctbin application. This will loop over all observations in # the container and bin the events in counts maps self.bin.run() self.bin.save() self.info("Saved counts cube to {0:s}".format(self.bin["outcube"])) self.bin
def ctbinning_run(ev_file, force=0): working_dir = os.path.dirname(ev_file) cnt_file = os.path.join(working_dir, "cntcube.fits") log_file = os.path.join(working_dir, "ctbin.log") if not os.path.isfile(cnt_file) or force == 1: binning = ctools.ctbin() binning.clear() binning["inobs"] = ev_file binning["outobs"] = cnt_file binning["xref"] = OBJ["ra"] binning["yref"] = OBJ["dec"] binning["ebinalg"] = "LOG" binning["emin"] = ENERGY["min"] binning["emax"] = ENERGY["max"] binning["enumbins"] = 20 binning["nxpix"] = 500 binning["nypix"] = 500 binning["binsz"] = 0.01 binning["coordsys"] = "CEL" binning["proj"] = "CAR" binning["logfile"] = log_file binning.logFileOpen() binning.run() binning.save() sys.stderr.write("File '%s' created.\n" % cnt_file) return cnt_file
def ctbin(self, log=False, debug=False): ''' Create ctbin 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 ctbin to create count map") if self.m_obs: bin = ct.ctbin(self.m_obs) else: bin = ct.ctbin() for k in self.config.keys(): try: for kk in self.config[k].keys(): if bin._has_par(kk): bin[kk] = self.config[k][kk] except: if bin._has_par(k): bin[k] = self.config[k] bin["inobs"] = join(self.workdir, self.config['file']["selectedevent"]) bin["outcube"] = join(self.workdir, self.config['file']["cube"]) # Optionally open the log file if log: bin.logFileOpen() # Optionally switch-on debugging model if debug: bin["debug"].boolean(True) if self.verbose: print bin # Run ctbin application. This will loop over all observations in # the container and bin the events in counts maps bin.run() bin.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 = bin.obs().copy()
def run_pipeline(obs, emin=0.1, emax=100.0, enumbins=20, nxpix=200, nypix=200, binsz=0.02, coordsys="CEL", proj="CAR", debug=False): """ Simulation and binned analysis pipeline. Keywords: emin - Minimum energy of cube [TeV] (default: 0.1) emax - Maximum energy of cube [TeV] (default: 100.0) enumbins - Number of energy bins in cube (default: 20) nxpix - Number of RA pixels in cube (default: 200) nypix - Number of DEC pixels in cube (default: 200) binsz - Spatial cube bin size [deg] (default: 0.02) coordsys - Cube coordinate system (CEL or GAL) proj - Cube World Coordinate System (WCS) projection debug - Enable debugging (default: False) """ # Simulate events sim = ctools.ctobssim(obs) sim["debug"] = debug sim.run() # Bin events by looping over all observations in the container obs = gammalib.GObservations() obs.models(sim.obs().models()) for run in sim.obs(): # Create container with a single observation container = gammalib.GObservations() container.append(run) # Bin events for that observation bin = ctools.ctbin(container) bin["ebinalg"] = "LOG" bin["emin"] = emin bin["emax"] = emax bin["enumbins"] = enumbins bin["nxpix"] = nxpix bin["nypix"] = nypix bin["binsz"] = binsz bin["coordsys"] = coordsys bin["usepnt"] = True bin["proj"] = proj bin.run() # Append result to observations obs.extend(bin.obs()) # Perform maximum likelihood fitting like = ctools.ctlike(obs) like["debug"] = True # Switch this always on for results in console like.run() # Return return
def create_cntcube(obs, emin=None, emax=None, ebins=20, npix=200, binsz=0.02): """ Create counts cube Parameters ---------- obs : `~gammalib.GObservations` Observation container emin : float, optional Minimum energy (TeV) emax : float, optional Maximum energy (TeV) ebins : int, optional Number of energy bins npix : int, optional Number of spatial pixels in x and y binsz : float, optional Spatial pixels bin size (deg) Returns ------- cntcube : `~gammalib.GCTAEventCube` Counts cube """ # Get energy range for observation if emin == None: emin = obs[0].ebounds().emin().TeV() if emax == None: emax = obs[0].ebounds().emax().TeV() # Setup task parameters ctbin = ctools.ctbin(obs) ctbin['ebinalg'] = 'LOG' ctbin['emin'] = emin ctbin['emax'] = emax ctbin['enumbins'] = ebins ctbin['coordsys'] = 'CEL' ctbin['proj'] = 'TAN' ctbin['usepnt'] = True ctbin['nxpix'] = npix ctbin['nypix'] = npix ctbin['binsz'] = binsz # Generate counts cube ctbin.run() # Extract counts cube cntcube = ctbin.cube().copy() # Return counts cube return cntcube
def ctbin(self,log=False,debug=False): # ctbin application and set parameters self.validate() self.info("Running ctbin to create count map") if self.m_obs: bin = ct.ctbin(self.m_obs) else: bin = ct.ctbin() bin["evfile"] = self.m_evtfile bin["outfile"] = self.m_cntfile bin["ebinalg"].string(self.m_ebinalg) bin["emin"].real(self.m_emin) bin["emax"].real(self.m_emax) Nbdecade = log10(self.m_emax)-log10(self.m_emin)#Compute the number of decade bin["enumbins"].integer(int(self.m_enumbins*Nbdecade)) bin["usepnt"].boolean(self.m_usepnt) # Use pointing for map centre bin["nxpix"].integer(self.m_nxpix) bin["nypix"].integer(self.m_nypix) bin["binsz"].real(self.m_binsz) bin["coordsys"].string(self.m_coordsys) bin["proj"].string(self.m_proj) # Optionally open the log file if log: bin.logFileOpen() # Optionally switch-on debugging model if debug: bin["debug"].boolean(True) # Run ctbin application. This will loop over all observations in # the container and bin the events in counts maps bin.execute() 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 = bin.obs().copy()
def sim(src="cCrab"): #bkg, Crabbkg "Simulates acceptance ccube and model cube" print 30 * "-" + "\n", "Simulating", src + "\n" + 30 * "-" #Simulate observation sim = ctools.ctobssim() sim["inmodel"] = modeldir + src + ".xml" sim["outevents"] = outdir + "events_" + src + ".fits" sim["caldb"] = caldb sim["irf"] = irf sim["ra"] = ra sim["dec"] = dec sim["rad"] = 10.0 sim["tmin"] = 0.0 sim["tmax"] = tsim sim["emin"] = emin sim["emax"] = emax sim["edisp"] = False sim.execute() #Bin data into a cube ctbin = ctools.ctbin() ctbin["inobs"] = outdir + "events_" + src + ".fits" ctbin["outcube"] = outdir + "ccube_" + src + ".fits" ctbin["ebinalg"] = "LOG" ctbin["emin"] = emin ctbin["emax"] = emax ctbin["enumbins"] = enumbins ctbin["nxpix"] = npix ctbin["nypix"] = npix ctbin["binsz"] = binsz ctbin["coordsys"] = "CEL" ctbin["xref"] = ra ctbin["yref"] = dec ctbin["proj"] = "AIT" ctbin.execute() #Create model cube ctmodel = ctools.ctmodel() ctmodel["inobs"] = outdir + "events_" + src + ".fits" ctmodel["inmodel"] = modeldir + src + ".xml" ctmodel["incube"] = outdir + "ccube_" + src + ".fits" ctmodel["caldb"] = "prod2" ctmodel["caldb"] = caldb ctmodel["irf"] = irf ctmodel["outcube"] = outdir + "mcube_" + src + ".fits" ctmodel["edisp"] = False ctmodel.execute()
def create_count_cube(): """ Create counts cube """ # Allocate ctbin application and set parameters bin = ctools.ctbin() bin['inobs'] = 'test/data/crab_events.fits' bin['outcube'] = 'test/data/crab_cntmap.fits' bin['ebinalg'] = 'LOG' bin['emin'] = 1.0 bin['emax'] = 100.0 bin['enumbins'] = 5 bin['usepnt'] = True # Use pointing for map centre bin['nxpix'] = 20 bin['nypix'] = 20 bin['binsz'] = 0.2 bin['coordsys'] = 'CEL' bin['proj'] = 'TAN' bin.execute() # Return return
def test_functional(self): """ Test ctbin functionnality. """ # Set-up ctbin bin = ctools.ctbin() bin["inobs"] = self.events_name bin["outcube"] = "cntmap.fits" bin["ebinalg"] = "LOG" bin["emin"] = 0.1 bin["emax"] = 100.0 bin["enumbins"] = 20 bin["nxpix"] = 200 bin["nypix"] = 200 bin["binsz"] = 0.02 bin["coordsys"] = "CEL" bin["proj"] = "CAR" bin["xref"] = 83.63 bin["yref"] = 22.01 # Run tool self.test_try("Run ctbin") try: bin.run() self.test_try_success() except: self.test_try_failure("Exception occured in ctbin.") # Save counts cube self.test_try("Save counts cube") try: bin.save() self.test_try_success() except: self.test_try_failure("Exception occured in saving counts cube.") # Return return
def test_functional(self): """ Test ctbin functionnality. """ # Set-up ctbin bin = ctools.ctbin() bin["inobs"].filename(self.events_name) bin["outcube"].filename("cntmap.fits") bin["ebinalg"].string("LOG") bin["emin"].real(0.1) bin["emax"].real(100.0) bin["enumbins"].integer(20) bin["nxpix"].integer(200) bin["nypix"].integer(200) bin["binsz"].real(0.02) bin["coordsys"].string("CEL") bin["proj"].string("CAR") bin["xref"].real(83.63) bin["yref"].real(22.01) # Run tool self.test_try("Run ctbin") try: bin.run() self.test_try_success() except: self.test_try_failure("Exception occured in ctbin.") # Save counts cube self.test_try("Save counts cube") try: bin.save() self.test_try_success() except: self.test_try_failure("Exception occured in saving counts cube.") # Return return
def binData(cfg): """ bin data with ctbin """ outputdir = cfg.getValue('general', 'outputdir') if cfg.getValue('general', 'anatype') == 'binned': bdata = ctools.ctbin() bdata["inobs"] = outputdir + '/' + cfg.getValue('ctselect', 'output') bdata["outcube"] = outputdir + '/' + cfg.getValue('ctbin', 'output') bdata["ebinalg"] = "LOG" bdata["emin"] = cfg.getValue('ctselect', 'emin') bdata["emax"] = cfg.getValue('ctselect', 'emax') bdata["enumbins"] = cfg.getValue('ctbin', 'enumbins') bdata["nxpix"] = cfg.getValue('ctbin', 'nxpix') bdata["nypix"] = cfg.getValue('ctbin', 'nypix') bdata["binsz"] = cfg.getValue('ctbin', 'binsz') bdata["coordsys"] = "CEL" bdata["proj"] = "AIT" bdata["xref"] = cfg.getValue('model', 'coords', 'ra') bdata["yref"] = cfg.getValue('model', 'coords', 'dec') if cfg.getValue('general', 'debug') is True: bdata["debug"] = True bdata.run() bdata.save()
def stacked_pipeline(model_name, duration): """ Stacked 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 enumbins = 40 nxpix = 200 nypix = 200 binsz = 0.02 coordsys = "CEL" proj = "CAR" # 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() # Bin events into counts map bin = ctools.ctbin(sim.obs()) bin["ebinalg"] = "LOG" bin["emin"] = emin bin["emax"] = emax bin["enumbins"] = enumbins bin["nxpix"] = nxpix bin["nypix"] = nypix bin["binsz"] = binsz bin["coordsys"] = coordsys bin["proj"] = proj bin["xref"] = ra bin["yref"] = dec bin.run() # Create exposure cube expcube = ctools.ctexpcube(sim.obs()) expcube["incube"] = "NONE" expcube["caldb"] = caldb expcube["irf"] = irf expcube["ebinalg"] = "LOG" expcube["emin"] = emin expcube["emax"] = emax expcube["enumbins"] = enumbins expcube["nxpix"] = nxpix expcube["nypix"] = nypix expcube["binsz"] = binsz expcube["coordsys"] = coordsys expcube["proj"] = proj expcube["xref"] = ra expcube["yref"] = dec expcube.run() # Create PSF cube psfcube = ctools.ctpsfcube(sim.obs()) psfcube["incube"] = "NONE" psfcube["caldb"] = caldb psfcube["irf"] = irf psfcube["ebinalg"] = "LOG" psfcube["emin"] = emin psfcube["emax"] = emax psfcube["enumbins"] = enumbins psfcube["nxpix"] = 10 psfcube["nypix"] = 10 psfcube["binsz"] = 1.0 psfcube["coordsys"] = coordsys psfcube["proj"] = proj psfcube["xref"] = ra psfcube["yref"] = dec psfcube.run() # Create background cube bkgcube = ctools.ctbkgcube(sim.obs()) bkgcube["incube"] = "NONE" bkgcube["ebinalg"] = "LOG" bkgcube["emin"] = emin bkgcube["emax"] = emax bkgcube["enumbins"] = enumbins bkgcube["nxpix"] = 10 bkgcube["nypix"] = 10 bkgcube["binsz"] = 1.0 bkgcube["coordsys"] = coordsys bkgcube["proj"] = proj bkgcube["xref"] = ra bkgcube["yref"] = dec bkgcube.run() # Attach background model to observation container bin.obs().models(bkgcube.models()) # Set Exposure and Psf cube for first CTA observation # (ctbin will create an observation with a single container) bin.obs()[0].response(expcube.expcube(), psfcube.psfcube(), bkgcube.bkgcube()) # Get ctlike start CPU time cpu_ctlike = time.clock() # Perform maximum likelihood fitting like = ctools.ctlike(bin.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(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") # Use input file directly if given if self._use_maps: countmap = gammalib.GSkyMap(self["inobs"].filename()) modelmap = gammalib.GSkyMap(self._modcube) else: # ... if self._skip_binning: cta_counts_cube = gammalib.GCTAEventCube(self._obs[0].events().clone()) # ... else: # Write header if self._logTerse(): self._log("\n") self._log.header1("Generate binned map (ctbin)") # Create countsmap bin = ctools.ctbin(self._obs) bin["nxpix"].integer(self._nxpix) bin["nypix"].integer(self._nypix) bin["proj"].string(self._proj) bin["coordsys"].string(self._coordsys) bin["xref"].real(self._xref) bin["yref"].real(self._yref) bin["enumbins"].integer(self._enumbins) bin["ebinalg"].string(self._ebinalg) bin["emin"].real(self._emin) bin["emax"].real(self._emax) bin["binsz"].real(self._binsz) bin["chatter"].integer(self._chatter) bin["clobber"].boolean(self._clobber) bin["debug"].boolean(self._debug) bin.run() # Retrieve counts cube cta_counts_cube = bin.cube() # Assign GCTAEventCube to skymap countmap = cta_counts_cube.counts() # Write header if self._logTerse(): self._log("\n") self._log.header1("Generate model map (ctmodel)") # Create model map model = ctools.ctmodel(self._obs) model.cube(cta_counts_cube) model["chatter"].integer(self._chatter) model["clobber"].boolean(self._clobber) model["debug"].boolean(self._debug) model["edisp"].boolean(self._edisp) model.run() # Get model map into GSkyMap object modelmap = model.cube().counts().copy() # Store counts map as residual map. Note that we need a # special construct here to avoid memory leaks. This seems # to be a SWIG feature as SWIG creates a new object when # calling bin.cube() #residualmap = bin.cube().counts() self._resmap = countmap.copy() self._resmap.stack_maps() modelmap.stack_maps() # Continue calculations depending on given algorithm if self._algorithm == "SUB": # Subtract maps self._resmap -= modelmap elif self._algorithm == "SUBDIV": # Subtract and divide by model map self._resmap -= modelmap self._resmap /= modelmap #for pixel in modelmap: # if pixel != 0.0: # pixel = 1.0/pixel #self._resmap *= modelmap elif self._algorithm == "SUBDIVSQRT": # subtract and divide by sqrt of model map self._resmap -= modelmap self._resmap /= modelmap.sqrt() #for pixel in modelmap: # if pixel != 0.0: # pixel = 1.0/math.sqrt(pixel) #self._resmap *= modelmap else: # Raise error if algorithm is unkown raise TypeError("Algorithm \""+self._algorithm+"\" not known") # Optionally publish map if self._publish: self.publish() # Return return
def stacked_pipeline(duration): """ Cube-style 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 enumbins = 20 nxpix = 200 nypix = 200 binsz = 0.02 coordsys = "CEL" proj = "CAR" # 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() # Bin events into counts map bin = ctools.ctbin(sim.obs()) bin["ebinalg"].string("LOG") bin["emin"].real(emin) bin["emax"].real(emax) bin["enumbins"].integer(enumbins) bin["nxpix"].integer(nxpix) bin["nypix"].integer(nypix) bin["binsz"].real(binsz) bin["coordsys"].string(coordsys) bin["proj"].string(proj) bin["xref"].real(ra) bin["yref"].real(dec) bin.run() # Create exposure cube expcube = ctools.ctexpcube(sim.obs()) expcube["incube"].filename("NONE") expcube["caldb"].string(caldb) expcube["irf"].string(irf) expcube["ebinalg"].string("LOG") expcube["emin"].real(emin) expcube["emax"].real(emax) expcube["enumbins"].integer(enumbins) expcube["nxpix"].integer(nxpix) expcube["nypix"].integer(nypix) expcube["binsz"].real(binsz) expcube["coordsys"].string(coordsys) expcube["proj"].string(proj) expcube["xref"].real(ra) expcube["yref"].real(dec) expcube.run() # Create PSF cube psfcube = ctools.ctpsfcube(sim.obs()) psfcube["incube"].filename("NONE") psfcube["caldb"].string(caldb) psfcube["irf"].string(irf) psfcube["ebinalg"].string("LOG") psfcube["emin"].real(emin) psfcube["emax"].real(emax) psfcube["enumbins"].integer(enumbins) psfcube["nxpix"].integer(10) psfcube["nypix"].integer(10) psfcube["binsz"].real(1.0) psfcube["coordsys"].string(coordsys) psfcube["proj"].string(proj) psfcube["xref"].real(ra) psfcube["yref"].real(dec) psfcube.run() # Create background cube bkgcube = ctools.ctbkgcube(sim.obs()) bkgcube["incube"].filename("NONE") bkgcube["ebinalg"].string("LOG") bkgcube["emin"].real(emin) bkgcube["emax"].real(emax) bkgcube["enumbins"].integer(enumbins) bkgcube["nxpix"].integer(10) bkgcube["nypix"].integer(10) bkgcube["binsz"].real(1.0) bkgcube["coordsys"].string(coordsys) bkgcube["proj"].string(proj) bkgcube["xref"].real(ra) bkgcube["yref"].real(dec) bkgcube.run() # Attach background model to observation container bin.obs().models(bkgcube.models()) # Set Exposure and Psf cube for first CTA observation # (ctbin will create an observation with a single container) bin.obs()[0].response(expcube.expcube(), psfcube.psfcube(), bkgcube.bkgcube()) # Get ctlike start CPU time tctlike = time.clock() # Perform maximum likelihood fitting like = ctools.ctlike(bin.obs()) like.run() # Get stop CPU time tstop = time.clock() telapsed = tstop - tstart tctlike = tstop - tctlike # Return return telapsed, tctlike
#Move observations to destination folder.Observations are simulated and stored in the present folder, but I prefer to store them somewhere else, so I move them there. for src_dir, dirs, files in os.walk(PATH_HERE): dst_dir = PATH_OBS if not os.path.exists(dst_dir): os.makedirs(dst_dir) for file in files: src_file = os.path.join(PATH_HERE, file) dst_file = os.path.join(PATH_OBS, file) if file.endswith('.fits'): if os.path.exists(dst_file): os.remove(dst_file) shutil.move(src_file, PATH_OBS) # BIN THE DATA binn = ctools.ctbin() binn["inobs"] = outfile binn["outcube"] = cntcube binn["coordsys"] = "CEL" binn["proj"] = "CAR" binn["ebinalg"] = "LOG" binn["xref"] = centerx binn["yref"] = centery binn["nxpix"] = nxpix binn["nypix"] = nypix binn["binsz"] = binsz binn["enumbins"] = enumbins binn["emin"] = emin binn["emax"] = emax binn["debug"] = True binn.execute()
def run_pipeline(obs, ra=83.63, dec=22.01, emin=0.1, emax=100.0, enumbins=20, nxpix=200, nypix=200, binsz=0.02, coordsys='CEL', proj='CAR', model='data/crab.xml', caldb='prod2', irf='South_0.5h', debug=False): """ Simulation and stacked analysis pipeline Parameters ---------- obs : `~gammalib.GObservations` Observation container ra : float, optional Right Ascension of counts cube centre (deg) dec : float, optional Declination of Region of counts cube centre (deg) emin : float, optional Minimum energy (TeV) emax : float, optional Maximum energy (TeV) enumbins : int, optional Number of energy bins nxpix : int, optional Number of pixels in X axis nypix : int, optional Number of pixels in Y axis binsz : float, optional Pixel size (deg) coordsys : str, optional Coordinate system proj : str, optional Coordinate projection model : str, optional Model definition XML file caldb : str, optional Calibration database path irf : str, optional Instrument response function debug : bool, optional Debug function """ # Simulate events sim = ctools.ctobssim(obs) sim['debug'] = debug sim['outevents'] = 'obs.xml' sim.execute() # Bin events into counts map bin = ctools.ctbin() bin['inobs'] = 'obs.xml' bin['outcube'] = 'cntcube.fits' bin['ebinalg'] = 'LOG' bin['emin'] = emin bin['emax'] = emax bin['enumbins'] = enumbins bin['nxpix'] = nxpix bin['nypix'] = nypix bin['binsz'] = binsz bin['coordsys'] = coordsys bin['proj'] = proj bin['xref'] = ra bin['yref'] = dec bin['debug'] = debug bin.execute() # Create exposure cube expcube = ctools.ctexpcube() expcube['inobs'] = 'obs.xml' expcube['incube'] = 'cntcube.fits' expcube['outcube'] = 'expcube.fits' expcube['caldb'] = caldb expcube['irf'] = irf expcube['ebinalg'] = 'LOG' expcube['emin'] = emin expcube['emax'] = emax expcube['enumbins'] = enumbins expcube['nxpix'] = nxpix expcube['nypix'] = nypix expcube['binsz'] = binsz expcube['coordsys'] = coordsys expcube['proj'] = proj expcube['xref'] = ra expcube['yref'] = dec expcube['debug'] = debug expcube.execute() # Create PSF cube psfcube = ctools.ctpsfcube() psfcube['inobs'] = 'obs.xml' psfcube['incube'] = 'NONE' psfcube['outcube'] = 'psfcube.fits' psfcube['caldb'] = caldb psfcube['irf'] = irf psfcube['ebinalg'] = 'LOG' psfcube['emin'] = emin psfcube['emax'] = emax psfcube['enumbins'] = enumbins psfcube['nxpix'] = 10 psfcube['nypix'] = 10 psfcube['binsz'] = 1.0 psfcube['coordsys'] = coordsys psfcube['proj'] = proj psfcube['xref'] = ra psfcube['yref'] = dec psfcube['debug'] = debug psfcube.execute() # Create background cube bkgcube = ctools.ctbkgcube() bkgcube['inobs'] = 'obs.xml' bkgcube['inmodel'] = model bkgcube['incube'] = 'NONE' bkgcube['outcube'] = 'bkgcube.fits' bkgcube['outmodel'] = 'model_bkg.xml' bkgcube['caldb'] = caldb bkgcube['irf'] = irf bkgcube['ebinalg'] = 'LOG' bkgcube['emin'] = emin bkgcube['emax'] = emax bkgcube['enumbins'] = enumbins bkgcube['nxpix'] = 10 bkgcube['nypix'] = 10 bkgcube['binsz'] = 1.0 bkgcube['coordsys'] = coordsys bkgcube['proj'] = proj bkgcube['xref'] = ra bkgcube['yref'] = dec bkgcube['debug'] = debug bkgcube.execute() # Perform maximum likelihood fitting like = ctools.ctlike() like['inobs'] = 'cntcube.fits' like['inmodel'] = 'model_bkg.xml' like['outmodel'] = 'fit_results.xml' like['expcube'] = 'expcube.fits' like['psfcube'] = 'psfcube.fits' like['bkgcube'] = 'bkgcube.fits' like['caldb'] = caldb like['irf'] = irf like['debug'] = True # Switch this always on for results in console like.execute() # Return return
def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, emin=None, emax=None, nbins=0, onsrc=None, onrad=0.2, addbounds=False, binsz=0.05, npix=200, proj='TAN', coord='GAL'): """ Simulate events for all observations in the container Simulate events for all observations using ctobssim. If the number of energy bins is positive, the events are binned into a counts cube using ctbin. If multiple observations are simulated, the counts cube is a stacked cube and the corresponding response cubes are computed using ctexpcube, ctpsfcube, ctbkgcube and optionally ctedispcube. The response cubes are attached to the first observation in the container, which normally is the observation with the counts cube. Parameters ---------- obs : `~gammalib.GObservations` Observation container without events log : bool, optional Create log file(s) debug : bool, optional Create console dump? chatter : int, optional Chatter level edisp : bool, optional Apply energy dispersion? seed : int, optional Seed value for simulations emin : float, optional Minimum energy of counts cube for binned (TeV) emax : float, optional Maximum energy of counts cube for binned (TeV) nbins : int, optional Number of energy bins (0=unbinned) onsrc : str, optional Name of source for On region (None if no On/Off obs. is used) onrad : float, optional Radius for On region (deg) addbounds : bool, optional Add boundaries at observation energies binsz : float, optional Pixel size for binned simulation (deg/pixel) npix : int, optional Number of pixels in X and Y for binned simulation proj : str, optional Projection for binned simulation coord : str, optional Coordinate system for binned simulation Returns ------- obs : `~gammalib.GObservations` Observation container filled with simulated events """ # Allocate ctobssim application and set parameters obssim = ctools.ctobssim(obs) obssim['seed'] = seed obssim['edisp'] = edisp obssim['chatter'] = chatter obssim['debug'] = debug # Optionally open the log file if log: obssim.logFileOpen() # Run ctobssim application. This will loop over all observations in the # container and simulation the events for each observation. Note that # events are not added together, they still apply to each observation # separately. obssim.run() # Binned option? if nbins > 0: # If energy boundaries are not given then determine the minimum and # the maximum energies from all observations and use these values # as energy boundaries. The energy boundaries are given in TeV. if emin == None or emax == None: emin = 1.0e30 emax = 0.0 for run in obssim.obs(): emin = min(run.events().ebounds().emin().TeV(), emin) emax = max(run.events().ebounds().emax().TeV(), emax) # If a On source is specified then create On/Off observations if onsrc != None: # Extract source position from model model = obssim.obs().models()[onsrc] ra = model['RA'].value() dec = model['DEC'].value() # Allocate csphagen application and set parameters phagen = cscripts.csphagen(obssim.obs()) phagen['ebinalg'] = 'LOG' phagen['emin'] = emin phagen['emax'] = emax phagen['enumbins'] = nbins phagen['coordsys'] = 'CEL' phagen['ra'] = ra phagen['dec'] = dec phagen['rad'] = onrad phagen['stack'] = False phagen['inexclusion'] = 'NONE' phagen['bkgmethod'] = 'REFLECTED' # Optionally open the log file if log: phagen.logFileOpen() # Run csphagen application phagen.run() # Make a deep copy of the observation that will be returned # (the csphagen object will go out of scope one the function is # left) obs = phagen.obs().copy() # ... otherwise use binned observations else: # Allocate ctbin application and set parameters binning = ctools.ctbin(obssim.obs()) binning['ebinalg'] = 'LOG' binning['emin'] = emin binning['emax'] = emax binning['enumbins'] = nbins binning['usepnt'] = True # Use pointing for map centre binning['nxpix'] = npix binning['nypix'] = npix binning['binsz'] = binsz binning['coordsys'] = coord binning['proj'] = proj binning['chatter'] = chatter binning['debug'] = debug # Optionally open the log file if log: binning.logFileOpen() # Run ctbin application. This will loop over all observations in # the container and bin the events in counts maps binning.run() # If we have multiple input observations then create stacked response # cubes and append them to the observation if len(obssim.obs()) > 1: # Get stacked response (use pointing for map centre) response = get_stacked_response(obssim.obs(), None, None, binsz=binsz, nxpix=npix, nypix=npix, emin=emin, emax=emax, enumbins=nbins, edisp=edisp, coordsys=coord, proj=proj, addbounds=addbounds, log=log, debug=debug, chatter=chatter) # Set stacked response if edisp: binning.obs()[0].response(response['expcube'], response['psfcube'], response['edispcube'], response['bkgcube']) else: binning.obs()[0].response(response['expcube'], response['psfcube'], response['bkgcube']) # Set new models binning.obs().models(response['models']) # Make a deep copy of the observation that will be returned # (the ctbin object will go out of scope one the function is # left) obs = binning.obs().copy() else: # Make a deep copy of the observation that will be returned # (the ctobssim object will go out of scope one the function is # left) obs = obssim.obs().copy() # Delete the simulation del obssim # Return observation container return obs
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
def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, emin=None, emax=None, nbins=0, onsrc=None, onrad=0.2, addbounds=False, binsz=0.05, npix=200, proj='TAN', coord='GAL'): """ Simulate events for all observations in the container Simulate events for all observations using ctobssim. If the number of energy bins is positive, the events are binned into a counts cube using ctbin. If multiple observations are simulated, the counts cube is a stacked cube and the corresponding response cubes are computed using ctexpcube, ctpsfcube, ctbkgcube and optionally ctedispcube. The response cubes are attached to the first observation in the container, which normally is the observation with the counts cube. Parameters ---------- obs : `~gammalib.GObservations` Observation container without events log : bool, optional Create log file(s) debug : bool, optional Create console dump? chatter : int, optional Chatter level edisp : bool, optional Apply energy dispersion? seed : int, optional Seed value for simulations emin : float, optional Minimum energy of counts cube for binned (TeV) emax : float, optional Maximum energy of counts cube for binned (TeV) nbins : int, optional Number of energy bins (0=unbinned) onsrc : str, optional Name of source for On region (None if no On/Off obs. is used) onrad : float, optional Radius for On region (deg) addbounds : bool, optional Add boundaries at observation energies binsz : float, optional Pixel size for binned simulation (deg/pixel) npix : int, optional Number of pixels in X and Y for binned simulation proj : str, optional Projection for binned simulation coord : str, optional Coordinate system for binned simulation Returns ------- obs : `~gammalib.GObservations` Observation container filled with simulated events """ # Allocate ctobssim application and set parameters obssim = ctools.ctobssim(obs) obssim['seed'] = seed obssim['edisp'] = edisp obssim['chatter'] = chatter obssim['debug'] = debug # Optionally open the log file if log: obssim.logFileOpen() # Run ctobssim application. This will loop over all observations in the # container and simulation the events for each observation. Note that # events are not added together, they still apply to each observation # separately. obssim.run() # Binned option? if nbins > 0: # If energy boundaries are not given then determine the minimum and # the maximum energies from all observations and use these values # as energy boundaries. The energy boundaries are given in TeV. if emin == None or emax == None: emin = 1.0e30 emax = 0.0 for run in obssim.obs(): emin = min(run.events().ebounds().emin().TeV(), emin) emax = max(run.events().ebounds().emax().TeV(), emax) # If a On source is specified then create On/Off observations if onsrc != None: # Extract source position from model model = obssim.obs().models()[onsrc] ra = model['RA'].value() dec = model['DEC'].value() # Allocate csphagen application and set parameters phagen = cscripts.csphagen(obssim.obs()) phagen['ebinalg'] = 'LOG' phagen['emin'] = emin phagen['emax'] = emax phagen['enumbins'] = nbins phagen['coordsys'] = 'CEL' phagen['ra'] = ra phagen['dec'] = dec phagen['rad'] = onrad phagen['stack'] = False phagen['inexclusion'] = 'NONE' # Optionally open the log file if log: phagen.logFileOpen() # Run csphagen application phagen.run() # Make a deep copy of the observation that will be returned # (the csphagen object will go out of scope one the function is # left) obs = phagen.obs().copy() # ... otherwise use binned observations else: # Allocate ctbin application and set parameters binning = ctools.ctbin(obssim.obs()) binning['ebinalg'] = 'LOG' binning['emin'] = emin binning['emax'] = emax binning['enumbins'] = nbins binning['usepnt'] = True # Use pointing for map centre binning['nxpix'] = npix binning['nypix'] = npix binning['binsz'] = binsz binning['coordsys'] = coord binning['proj'] = proj binning['chatter'] = chatter binning['debug'] = debug # Optionally open the log file if log: binning.logFileOpen() # Run ctbin application. This will loop over all observations in # the container and bin the events in counts maps binning.run() # If we have multiple input observations then create stacked response # cubes and append them to the observation if len(obssim.obs()) > 1: # Get stacked response (use pointing for map centre) response = get_stacked_response(obssim.obs(), None, None, binsz=binsz, nxpix=npix, nypix=npix, emin=emin, emax=emax, enumbins=nbins, edisp=edisp, coordsys=coord, proj=proj, addbounds=addbounds, log=log, debug=debug, chatter=chatter) # Set stacked response if edisp: binning.obs()[0].response(response['expcube'], response['psfcube'], response['edispcube'], response['bkgcube']) else: binning.obs()[0].response(response['expcube'], response['psfcube'], response['bkgcube']) # Set new models binning.obs().models(response['models']) # Make a deep copy of the observation that will be returned # (the ctbin object will go out of scope one the function is # left) obs = binning.obs().copy() else: # Make a deep copy of the observation that will be returned # (the ctobssim object will go out of scope one the function is # left) obs = obssim.obs().copy() # Delete the simulation del obssim # Return observation container return obs
def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, nbins=31, binsz=0.02, npix=50, proj="CAR", coord="CEL", outfile=""): """ Simulate events for all observations in the container. Parameters: obs - Observation container Keywords: log - Create log file(s) debug - Create console dump? edisp - Apply energy dispersion? seed - Seed value for simulations (default: 0) nbins - Number of energy bins (default: 0=unbinned) binsz - Pixel size for binned simulation (deg/pixel) npix - Number of pixels in X and Y for binned simulation """ # Allocate ctobssim application and set parameters sim = ctools.ctobssim(obs) sim["seed"] = seed sim["edisp"] = edisp sim["outevents"] = outfile sim['nthreads'] = 2 # Optionally open the log file if log: sim.logFileOpen() # Optionally switch-on debugging model if debug: sim["debug"] = True # Set chatter level sim["chatter"] = chatter # Run ctobssim application. This will loop over all observations in the # container and simulation the events for each observation. Note that # events are not added together, they still apply to each observation # separately. sim.run() # Binned option? if nbins > 0: # Determine common energy boundaries for observations emin = None emax = None for run in sim.obs(): run_emin = run.events().ebounds().emin().TeV() run_emax = run.events().ebounds().emax().TeV() if emin == None: emin = run_emin elif run_emin > emin: emin = run_emin if emax == None: emax = run_emax elif run_emax > emax: emax = run_emax # Allocate ctbin application and set parameters bin = ctools.ctbin(sim.obs()) bin["ebinalg"] = "LOG" bin["emin"] = emin bin["emax"] = emax bin["enumbins"] = nbins bin["usepnt"] = True # Use pointing for map centre bin["nxpix"] = npix bin["nypix"] = npix bin["binsz"] = binsz bin["coordsys"] = coord bin["proj"] = proj bin['nthreads'] = 2 # Optionally open the log file if log: bin.logFileOpen() # Optionally switch-on debugging model if debug: bin["debug"] = True # Set chatter level bin["chatter"] = chatter # Run ctbin application. This will loop over all observations in # the container and bin the events in counts maps bin.run() # Make a deep copy of the observation that will be returned # (the ctbin object will go out of scope one the function is # left) obs = bin.obs().copy() else: # Make a deep copy of the observation that will be returned # (the ctobssim object will go out of scope one the function is # left) obs = sim.obs().copy() # Optionally save file if (len(outfile) > 0): sim.save() # Delete the simulation del sim # Return observation container return obs
def get_stacked_obs(cls, obs): """ Bin an observation and return an observation container with a single binned observation Parameters ---------- cls : `~ctools.cscript` cscript class obs : `~gammalib.GObservations` Observation container Returns ------- obs : `~gammalib.GObservations` Observation container where the first observation is a binned observation """ # Write header if cls._logExplicit(): cls._log.header3('Binning events') # Bin events cntcube = ctools.ctbin(obs) cntcube['usepnt'] = False cntcube['ebinalg'] = 'LOG' cntcube['xref'] = cls['xref'].real() cntcube['yref'] = cls['yref'].real() cntcube['binsz'] = cls['binsz'].real() cntcube['nxpix'] = cls['nxpix'].integer() cntcube['nypix'] = cls['nypix'].integer() cntcube['enumbins'] = cls['enumbins'].integer() cntcube['emin'] = cls['emin'].real() cntcube['emax'] = cls['emax'].real() cntcube['coordsys'] = cls['coordsys'].string() cntcube['proj'] = cls['proj'].string() cntcube.run() # Write header if cls._logExplicit(): cls._log.header3('Creating stacked response') # Get stacked response response = get_stacked_response(obs, cls['xref'].real(), cls['yref'].real(), binsz=cls['binsz'].real(), nxpix=cls['nxpix'].integer(), nypix=cls['nypix'].integer(), emin=cls['emin'].real(), emax=cls['emax'].real(), enumbins=cls['enumbins'].integer(), edisp=cls['edisp'].boolean(), coordsys=cls['coordsys'].string(), proj=cls['proj'].string()) # Retrieve a new oberservation container new_obs = cntcube.obs().copy() # Set stacked response if cls['edisp'].boolean(): new_obs[0].response(response['expcube'], response['psfcube'], response['edispcube'], response['bkgcube']) else: new_obs[0].response(response['expcube'], response['psfcube'], response['bkgcube']) # Get new models models = response['models'] # Set models for new oberservation container new_obs.models(models) # Return new oberservation container return new_obs
def run_pipeline(obs, ra=83.63, dec=22.01, emin=0.1, emax=100.0, \ enumbins=20, nxpix=200, nypix=200, binsz=0.02, \ coordsys="CEL", proj="CAR", debug=False): """ Simulation and stacked analysis pipeline. Keywords: ra - RA of cube centre [deg] (default: 83.6331) dec - DEC of cube centre [deg] (default: 22.0145) emin - Minimum energy of cube [TeV] (default: 0.1) emax - Maximum energy of cube [TeV] (default: 100.0) enumbins - Number of energy bins in cube (default: 20) nxpix - Number of RA pixels in cube (default: 200) nypix - Number of DEC pixels in cube (default: 200) binsz - Spatial cube bin size [deg] (default: 0.02) coordsys - Cube coordinate system (CEL or GAL) proj - Cube World Coordinate System (WCS) projection debug - Enable debugging (default: False) """ # Simulate events sim = ctools.ctobssim(obs) sim["debug"].boolean(debug) sim.run() # Bin events into counts map bin = ctools.ctbin(sim.obs()) bin["ebinalg"].string("LOG") bin["emin"].real(emin) bin["emax"].real(emax) bin["enumbins"].integer(enumbins) bin["nxpix"].integer(nxpix) bin["nypix"].integer(nypix) bin["binsz"].real(binsz) bin["coordsys"].string(coordsys) bin["proj"].string(proj) bin["xref"].real(ra) bin["yref"].real(dec) bin["debug"].boolean(debug) bin.run() # Create exposure cube expcube = ctools.ctexpcube(sim.obs()) expcube["incube"].filename("NONE") expcube["ebinalg"].string("LOG") expcube["emin"].real(emin) expcube["emax"].real(emax) expcube["enumbins"].integer(enumbins) expcube["nxpix"].integer(nxpix) expcube["nypix"].integer(nypix) expcube["binsz"].real(binsz) expcube["coordsys"].string(coordsys) expcube["proj"].string(proj) expcube["xref"].real(ra) expcube["yref"].real(dec) expcube["debug"].boolean(debug) expcube.run() # Create PSF cube psfcube = ctools.ctpsfcube(sim.obs()) psfcube["incube"].filename("NONE") psfcube["ebinalg"].string("LOG") psfcube["emin"].real(emin) psfcube["emax"].real(emax) psfcube["enumbins"].integer(enumbins) psfcube["nxpix"].integer(10) psfcube["nypix"].integer(10) psfcube["binsz"].real(1.0) psfcube["coordsys"].string(coordsys) psfcube["proj"].string(proj) psfcube["xref"].real(ra) psfcube["yref"].real(dec) psfcube["debug"].boolean(debug) psfcube.run() # Create background cube bkgcube = ctools.ctbkgcube(sim.obs()) bkgcube["incube"].filename("NONE") bkgcube["ebinalg"].string("LOG") bkgcube["emin"].real(emin) bkgcube["emax"].real(emax) bkgcube["enumbins"].integer(enumbins) bkgcube["nxpix"].integer(10) bkgcube["nypix"].integer(10) bkgcube["binsz"].real(1.0) bkgcube["coordsys"].string(coordsys) bkgcube["proj"].string(proj) bkgcube["xref"].real(ra) bkgcube["yref"].real(dec) bkgcube["debug"].boolean(debug) bkgcube.run() # Attach background model to observation container bin.obs().models(bkgcube.models()) # Set Exposure and Psf cube for first CTA observation # (ctbin will create an observation with a single container) bin.obs()[0].response(expcube.expcube(), psfcube.psfcube(), bkgcube.bkgcube()) # Perform maximum likelihood fitting like = ctools.ctlike(bin.obs()) like["debug"].boolean(True) # Switch this always on for results in console like.run() # Return return
def run_pipeline(obs, ra=83.63, dec=22.01, emin=0.1, emax=100.0, \ enumbins=20, nxpix=200, nypix=200, binsz=0.02, \ coordsys="CEL", proj="CAR", \ model="${CTOOLS}/share/models/crab.xml", \ caldb="prod2", irf="South_50h", \ debug=False): """ Simulation and stacked analysis pipeline. Keywords: ra - RA of cube centre [deg] (default: 83.6331) dec - DEC of cube centre [deg] (default: 22.0145) emin - Minimum energy of cube [TeV] (default: 0.1) emax - Maximum energy of cube [TeV] (default: 100.0) enumbins - Number of energy bins in cube (default: 20) nxpix - Number of RA pixels in cube (default: 200) nypix - Number of DEC pixels in cube (default: 200) binsz - Spatial cube bin size [deg] (default: 0.02) coordsys - Cube coordinate system (CEL or GAL) proj - Cube World Coordinate System (WCS) projection debug - Enable debugging (default: False) """ # Simulate events sim = ctools.ctobssim(obs) sim["debug"].boolean(debug) sim["outevents"].filename("obs.xml") sim.execute() # Bin events into counts map bin = ctools.ctbin() bin["inobs"].filename("obs.xml") bin["outcube"].filename("cntcube.fits") bin["ebinalg"].string("LOG") bin["emin"].real(emin) bin["emax"].real(emax) bin["enumbins"].integer(enumbins) bin["nxpix"].integer(nxpix) bin["nypix"].integer(nypix) bin["binsz"].real(binsz) bin["coordsys"].string(coordsys) bin["proj"].string(proj) bin["xref"].real(ra) bin["yref"].real(dec) bin["debug"].boolean(debug) bin.execute() # Create exposure cube expcube = ctools.ctexpcube() expcube["inobs"].filename("obs.xml") expcube["incube"].filename("cntcube.fits") expcube["outcube"].filename("expcube.fits") expcube["caldb"].string(caldb) expcube["irf"].string(irf) expcube["ebinalg"].string("LOG") expcube["emin"].real(emin) expcube["emax"].real(emax) expcube["enumbins"].integer(enumbins) expcube["nxpix"].integer(nxpix) expcube["nypix"].integer(nypix) expcube["binsz"].real(binsz) expcube["coordsys"].string(coordsys) expcube["proj"].string(proj) expcube["xref"].real(ra) expcube["yref"].real(dec) expcube["debug"].boolean(debug) expcube.execute() # Create PSF cube psfcube = ctools.ctpsfcube() psfcube["inobs"].filename("obs.xml") psfcube["incube"].filename("NONE") psfcube["outcube"].filename("psfcube.fits") psfcube["caldb"].string(caldb) psfcube["irf"].string(irf) psfcube["ebinalg"].string("LOG") psfcube["emin"].real(emin) psfcube["emax"].real(emax) psfcube["enumbins"].integer(enumbins) psfcube["nxpix"].integer(10) psfcube["nypix"].integer(10) psfcube["binsz"].real(1.0) psfcube["coordsys"].string(coordsys) psfcube["proj"].string(proj) psfcube["xref"].real(ra) psfcube["yref"].real(dec) psfcube["debug"].boolean(debug) psfcube.execute() # Create background cube bkgcube = ctools.ctbkgcube() bkgcube["inobs"].filename("obs.xml") bkgcube["inmodel"].filename(model) bkgcube["incube"].filename("cntcube.fits") bkgcube["outcube"].filename("bkgcube.fits") bkgcube["outmodel"].filename("model_bkg.xml") bkgcube["caldb"].string(caldb) bkgcube["irf"].string(irf) bkgcube["ebinalg"].string("LOG") bkgcube["emin"].real(emin) bkgcube["emax"].real(emax) bkgcube["enumbins"].integer(enumbins) bkgcube["nxpix"].integer(10) bkgcube["nypix"].integer(10) bkgcube["binsz"].real(1.0) bkgcube["coordsys"].string(coordsys) bkgcube["proj"].string(proj) bkgcube["xref"].real(ra) bkgcube["yref"].real(dec) bkgcube["debug"].boolean(debug) bkgcube.execute() # Perform maximum likelihood fitting like = ctools.ctlike() like["inobs"].filename("cntcube.fits") like["inmodel"].filename("model_bkg.xml") like["outmodel"].filename("fit_results.xml") like["expcube"].filename("expcube.fits") like["psfcube"].filename("psfcube.fits") like["bkgcube"].filename("bkgcube.fits") like["caldb"].string(caldb) like["irf"].string(irf) like["debug"].boolean(True) # Switch this always on for results in console like.execute() # Return return
def _bin_observation(self, obs): """ Bin an observation is a binned analysis was requested. Args: obs: Observation container. Returns: Observation container with a binned. """ # Header if self._logExplicit(): self._log.header3("Binning events") # Bin events cntcube = ctools.ctbin(obs) cntcube["usepnt"] = False cntcube["ebinalg"] = "LOG" cntcube["xref"] = self["xref"].real() cntcube["yref"] = self["yref"].real() cntcube["binsz"] = self["binsz"].real() cntcube["nxpix"] = self["nxpix"].integer() cntcube["nypix"] = self["nypix"].integer() cntcube["enumbins"] = self["enumbins"].integer() cntcube["emin"] = self["emin"].real() cntcube["emax"] = self["emax"].real() cntcube["coordsys"] = self["coordsys"].string() cntcube["proj"] = self["proj"].string() cntcube.run() # Header if self._logExplicit(): self._log.header3("Creating exposure cube") # Create exposure cube expcube = ctools.ctexpcube(obs) expcube["incube"] = "NONE" expcube["usepnt"] = False expcube["ebinalg"] = "LOG" expcube["xref"] = self["xref"].real() expcube["yref"] = self["yref"].real() expcube["binsz"] = self["binsz"].real() expcube["nxpix"] = self["nxpix"].integer() expcube["nypix"] = self["nypix"].integer() expcube["enumbins"] = self["enumbins"].integer() expcube["emin"] = self["emin"].real() expcube["emax"] = self["emax"].real() expcube["coordsys"] = self["coordsys"].string() expcube["proj"] = self["proj"].string() expcube.run() # Header if self._logExplicit(): self._log.header3("Creating point spread function cube") # Compute spatial binning for point spread function and # energy dispersion cubes binsz = 10.0 * self["binsz"].real() nxpix = self["nxpix"].integer() // 10 # Make sure result is int nypix = self["nypix"].integer() // 10 # Make sure result is int if nxpix < 2: nxpix = 2 if nypix < 2: nypix = 2 # Create point spread function cube psfcube = ctools.ctpsfcube(obs) psfcube["incube"] = "NONE" psfcube["usepnt"] = False psfcube["ebinalg"] = "LOG" psfcube["xref"] = self["xref"].real() psfcube["yref"] = self["yref"].real() psfcube["binsz"] = binsz psfcube["nxpix"] = nxpix psfcube["nypix"] = nypix psfcube["enumbins"] = self["enumbins"].integer() psfcube["emin"] = self["emin"].real() psfcube["emax"] = self["emax"].real() psfcube["coordsys"] = self["coordsys"].string() psfcube["proj"] = self["proj"].string() psfcube.run() # Check if we need to include energy dispersion if self["edisp"].boolean(): # Header if self._logExplicit(): self._log.header3("Creating energy dispersion cube") # Create energy dispersion cube edispcube = ctools.ctedispcube(obs) edispcube["incube"] = "NONE" edispcube["usepnt"] = False edispcube["ebinalg"] = "LOG" edispcube["xref"] = self["xref"].real() edispcube["yref"] = self["yref"].real() edispcube["binsz"] = binsz edispcube["nxpix"] = nxpix edispcube["nypix"] = nypix edispcube["enumbins"] = self["enumbins"].integer() edispcube["emin"] = self["emin"].real() edispcube["emax"] = self["emax"].real() edispcube["coordsys"] = self["coordsys"].string() edispcube["proj"] = self["proj"].string() edispcube.run() # Header if self._logExplicit(): self._log.header3("Creating background cube") # Create background cube bkgcube = ctools.ctbkgcube(obs) bkgcube["incube"] = "NONE" bkgcube["usepnt"] = False bkgcube["ebinalg"] = "LOG" bkgcube["xref"] = self["xref"].real() bkgcube["yref"] = self["yref"].real() bkgcube["binsz"] = self["binsz"].real() bkgcube["nxpix"] = self["nxpix"].integer() bkgcube["nypix"] = self["nypix"].integer() bkgcube["enumbins"] = self["enumbins"].integer() bkgcube["emin"] = self["emin"].real() bkgcube["emax"] = self["emax"].real() bkgcube["coordsys"] = self["coordsys"].string() bkgcube["proj"] = self["proj"].string() bkgcube.run() # Retrieve a new oberservation container new_obs = cntcube.obs().copy() # Get new models models = bkgcube.models() # Set stacked response if self["edisp"].boolean(): new_obs[0].response(expcube.expcube(), psfcube.psfcube(), edispcube.edispcube(), bkgcube.bkgcube()) else: new_obs[0].response(expcube.expcube(), psfcube.psfcube(), bkgcube.bkgcube()) # Fix background models if required if self["fix_bkg"].boolean(): for model in models: if model.classname() != "GModelSky": for par in model: par.fix() # Set models for new oberservation container new_obs.models(models) # Return new oberservation container return new_obs
def _test_python(self): """ Test ctbin from Python """ # Allocate ctbin binning = ctools.ctbin() # Check that empty ctbin has an empty observation container and counts # cube self.test_value( binning.obs().size(), 0, 'Check that empty ctbin has an empty observation container') self.test_value(binning.cubes(), 0, 'Check that empty ctbin has an empty counts cube') # Check that saving does not nothing binning['logfile'] = 'ctbin_py0.log' binning['outobs'] = 'ctbin_py0.fits' binning.logFileOpen() binning.save() self.test_assert(not os.path.isfile('ctbin_py0.fits'), 'Check that no counts cube has been created') # Check that publishing does not lead to an exception or segfault binning.publish() # Check that clearing does not lead to an exception or segfault binning.clear() # Now set ctbin parameters binning['inobs'] = self._events binning['outobs'] = 'ctbin_py1.fits' binning['ebinalg'] = 'LOG' binning['emin'] = 1.0 binning['emax'] = 100.0 binning['enumbins'] = 10 binning['nxpix'] = 40 binning['nypix'] = 40 binning['binsz'] = 0.1 binning['coordsys'] = 'CEL' binning['proj'] = 'CAR' binning['xref'] = 83.63 binning['yref'] = 22.01 binning['logfile'] = 'ctbin_py1.log' binning['chatter'] = 2 # Run ctbin tool binning.logFileOpen() binning.run() # Check content of observation container and counts cube self._check_observation(binning, 245) self._check_cube(binning.cube(), 245) # Copy ctbin tool cpy_bin = binning.copy() # Check content of observation container and counts cube self._check_observation(cpy_bin, 245) self._check_cube(cpy_bin.cube(), 245) # Run copy of ctbin tool again cpy_bin['logfile'] = 'ctbin_py2.log' cpy_bin['chatter'] = 3 cpy_bin.logFileOpen() cpy_bin.run() # Check content of observation container and number of counts cubes. # There should be a single binned observation in the observation # container, which is the one that was produced in the run before. # Since ctbin finds no unbinned observation in the container, the # number of cubes should be zero. self._check_observation(cpy_bin, 245) self.test_value(cpy_bin.cubes(), 0, 'Check that there are no counts cubes') # Save counts cube binning.save() # Load counts cube and check content evt = gammalib.GCTAEventCube('ctbin_py1.fits') self._check_cube(evt, 245) # Now clear ctbin tool binning.clear() # Check that cleared ctbin has an empty observation container and # counts cube self.test_value( binning.obs().size(), 0, 'Check that empty ctbin has an empty observation container') self.test_value(binning.cubes(), 0, 'Check that empty ctbin has an empty counts cube') # Prepare observation container for stacking of events into a # single counts cube obs = self._obs_events() # Set-up ctbin using an observation container binning = ctools.ctbin(obs) binning['outobs'] = 'ctbin_py3.fits' binning['ebinalg'] = 'LOG' binning['emin'] = 1.0 binning['emax'] = 100.0 binning['enumbins'] = 10 binning['nxpix'] = 40 binning['nypix'] = 40 binning['binsz'] = 0.1 binning['coordsys'] = 'CEL' binning['proj'] = 'CAR' binning['xref'] = 83.63 binning['yref'] = 22.01 binning['publish'] = True binning['logfile'] = 'ctbin_py3.log' binning['chatter'] = 3 # Execute ctbin tool binning.logFileOpen() binning.execute() # Check content of observation and cube (need multiplier=3 since # three identical observations have been appended) self._check_observation(binning, 245, multiplier=3) self._check_cube(binning.cube(), 245, multiplier=3) # Load counts cube and check content. evt = gammalib.GCTAEventCube('ctbin_py3.fits') self._check_cube(evt, 245, multiplier=3) # Now go for a fully Pythonic version with all parameters being # specified in a dictionary pars = { 'inobs': self._events, 'ebinalg': 'LIN', 'emin': 1.0, 'emax': 100.0, 'enumbins': 10, 'nxpix': 40, 'nypix': 40, 'binsz': 0.1, 'coordsys': 'CEL', 'proj': 'CAR', 'xref': 83.63, 'yref': 22.01, 'outobs': 'ctbin_py4.fits', 'logfile': 'ctbin_py4.log', 'chatter': 2 } binning = ctools.ctbin() binning.pardict(pars) binning.logFileOpen() binning.execute() # Load counts cube and check content evt = gammalib.GCTAEventCube('ctbin_py4.fits') self._check_cube(evt, 245) # Test unstacked version binning = ctools.ctbin() binning['inobs'] = self._inobs_two binning['stack'] = False binning['prefix'] = 'cntcube_py5_' binning['ebinalg'] = 'LOG' binning['emin'] = 1.0 binning['emax'] = 100.0 binning['enumbins'] = 10 binning['nxpix'] = 40 binning['nypix'] = 40 binning['binsz'] = 0.1 binning['coordsys'] = 'CEL' binning['proj'] = 'CAR' binning['xref'] = 83.63 binning['yref'] = 22.01 binning['outobs'] = 'ctbin_py5.xml' binning['logfile'] = 'ctbin_py5.log' binning['chatter'] = 2 binning.logFileOpen() binning.run() # Check individual cubes self._check_cube(binning.cube(0), 245) self._check_cube(binning.cube(1), 245) # Save counts cube binning.save() # Load observations obs = gammalib.GObservations('ctbin_py5.xml') self.test_value(obs.size(), 2, 'Check number of output observations') # Check counts cubes evt = obs[0].events() self._check_cube(evt, 245) evt = obs[1].events() self._check_cube(evt, 245) # Load counts cubes and check content evt = gammalib.GCTAEventCube('cntcube_py5_cta_00001.fits') self._check_cube(evt, 245) evt = gammalib.GCTAEventCube('cntcube_py5_cta_00002.fits') self._check_cube(evt, 245) # Return return
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
def _test_python(self): """ Test ctbin from Python """ # Set-up ctbin bin = ctools.ctbin() bin['inobs'] = self._events bin['outcube'] = 'cntmap.fits' bin['ebinalg'] = 'LOG' bin['emin'] = 0.1 bin['emax'] = 100.0 bin['enumbins'] = 20 bin['nxpix'] = 200 bin['nypix'] = 200 bin['binsz'] = 0.02 bin['coordsys'] = 'CEL' bin['proj'] = 'CAR' bin['xref'] = 83.63 bin['yref'] = 22.01 bin['logfile'] = 'ctbin_py1.log' bin['chatter'] = 2 # Run ctbin tool #bin.logFileOpen() # Make sure we get a log file, but this leads # to a segmentation fault on Linux, e.g. CentOS 6. # see issue #1823 (need to fix that) bin.run() # Check content of observation and cube self._check_observation(bin, 5542) self._check_cube(bin.cube(), 5542) # Test copy constructor cpy_bin = bin.copy() # Check content of observation and cube self._check_observation(cpy_bin, 5542) self._check_cube(cpy_bin.cube(), 5542) # Run copy of ctbin tool again cpy_bin['logfile'] = 'ctbin_py2.log' cpy_bin['chatter'] = 3 cpy_bin.run() # Check content of observation and cube. We expect now an empty # event cube as on input the observation is binned, and any binned # observation will be skipped, hence the counts cube should be # empty. self._check_observation(cpy_bin, 0) self._check_cube(cpy_bin.cube(), 0) # Save counts cube bin.save() # Load counts cube and check content. evt = gammalib.GCTAEventCube('cntmap.fits') self._check_cube(evt, 5542) # Prepare observation container for stacked analysis cta = gammalib.GCTAObservation(self._events) obs = gammalib.GObservations() cta.id('0001') obs.append(cta) cta.id('0002') obs.append(cta) cta.id('0003') obs.append(cta) # Set-up ctbin using an observation container bin = ctools.ctbin(obs) bin['outcube'] = 'cntmap.fits' bin['ebinalg'] = 'LOG' bin['emin'] = 0.1 bin['emax'] = 100.0 bin['enumbins'] = 20 bin['nxpix'] = 200 bin['nypix'] = 200 bin['binsz'] = 0.02 bin['coordsys'] = 'CEL' bin['proj'] = 'CAR' bin['xref'] = 83.63 bin['yref'] = 22.01 bin['logfile'] = 'ctbin_py3.log' bin['chatter'] = 4 # Run ctbin tool bin.logFileOpen() # Make sure we get a log file bin.run() # Check content of observation and cube (need multiplier=3 since # three identical observations have been appended) self._check_observation(bin, 5542, multiplier=3) self._check_cube(bin.cube(), 5542, multiplier=3) # Set-up ctbin using an observation container bin = ctools.ctbin(obs) bin['outcube'] = 'cntmap2.fits' bin['ebinalg'] = 'LOG' bin['emin'] = 0.1 bin['emax'] = 100.0 bin['enumbins'] = 20 bin['nxpix'] = 200 bin['nypix'] = 200 bin['binsz'] = 0.02 bin['coordsys'] = 'CEL' bin['proj'] = 'CAR' bin['xref'] = 83.63 bin['yref'] = 22.01 bin['logfile'] = 'ctbin_py4.log' bin['chatter'] = 4 # Execute ctbin tool bin.execute() # Load counts cube and check content. evt = gammalib.GCTAEventCube('cntmap2.fits') self._check_cube(evt, 5542, multiplier=3) # Return return
def binned_pipeline(model_name, duration): """ Binned 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 enumbins = 40 nxpix = 200 nypix = 200 binsz = 0.02 coordsys = "CEL" proj = "CAR" # 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() # Bin events into counts map bin = ctools.ctbin(sim.obs()) bin["ebinalg"] = "LOG" bin["emin"] = emin bin["emax"] = emax bin["enumbins"] = enumbins bin["nxpix"] = nxpix bin["nypix"] = nypix bin["binsz"] = binsz bin["coordsys"] = coordsys bin["xref"] = ra bin["yref"] = dec bin["proj"] = proj bin.run() # Get ctlike start CPU time cpu_ctlike = time.clock() # Perform maximum likelihood fitting like = ctools.ctlike(bin.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, emin=0.1, emax=100.0, enumbins=20, nxpix=200, nypix=200, binsz=0.02, coordsys='CEL', proj='CAR', debug=False): """ Simulation and binned analysis pipeline Parameters ---------- obs : `~gammalib.GObservations` Observation container emin : float, optional Minimum energy (TeV) emax : float, optional Maximum energy (TeV) enumbins : int, optional Number of energy bins nxpix : int, optional Number of pixels in X axis nypix : int, optional Number of pixels in Y axis binsz : float, optional Pixel size (deg) coordsys : str, optional Coordinate system proj : str, optional Coordinate projection debug : bool, optional Debug function """ # Simulate events sim = ctools.ctobssim(obs) sim['debug'] = debug sim.run() # Bin events by looping over all observations in the container obs = gammalib.GObservations() obs.models(sim.obs().models()) for run in sim.obs(): # Create container with a single observation container = gammalib.GObservations() container.append(run) # Bin events for that observation bin = ctools.ctbin(container) bin['ebinalg'] = 'LOG' bin['emin'] = emin bin['emax'] = emax bin['enumbins'] = enumbins bin['nxpix'] = nxpix bin['nypix'] = nypix bin['binsz'] = binsz bin['coordsys'] = coordsys bin['usepnt'] = True bin['proj'] = proj bin.run() # Append result to observations obs.extend(bin.obs()) # Perform maximum likelihood fitting like = ctools.ctlike(obs) like['debug'] = True # Switch this always on for results in console like.run() # Return return
def sim(obs, log=False, debug=False, seed=0, nbins=0, binsz=0.05, npix=200): """ Simulate events for all observations in the container. Parameters: obs - Observation container Keywords: log - Create log file(s) debug - Create screen dump seed - Seed value for simulations (default: 0) nbins - Number of energy bins (default: 0=unbinned) binsz - Pixel size for binned simulation (deg/pixel) npix - Number of pixels in X and Y for binned simulation """ # Allocate ctobssim application and set parameters sim = ctools.ctobssim(obs) sim['seed'].integer(seed) # Optionally open the log file if log: sim.logFileOpen() # Optionally switch-on debugging model if debug: sim["debug"].boolean(True) # Run ctobssim application. This will loop over all observations in the # container and simulation the events for each observation. Note that # events are not added together, they still apply to each observation # separately. sim.run() # Binned option? if nbins > 0: # Determine common energy boundaries for observations emin = None emax = None for run in sim.obs(): run_emin = run.events().ebounds().emin().TeV() run_emax = run.events().ebounds().emax().TeV() if emin == None: emin = run_emin elif run_emin > emin: emin = run_emin if emax == None: emax = run_emax elif run_emax > emax: emax = run_emax # Allocate ctbin application and set parameters bin = ctools.ctbin(sim.obs()) bin["ebinalg"].string("LOG") bin["emin"].real(emin) bin["emax"].real(emax) bin["enumbins"].integer(nbins) bin["usepnt"].boolean(True) # Use pointing for map centre bin["nxpix"].integer(npix) bin["nypix"].integer(npix) bin["binsz"].real(binsz) bin["coordsys"].string("GAL") bin["proj"].string("TAN") # Optionally open the log file if log: bin.logFileOpen() # Optionally switch-on debugging model if debug: bin["debug"].boolean(True) # Run ctbin application. This will loop over all observations in # the container and bin the events in counts maps bin.run() # Make a deep copy of the observation that will be returned # (the ctbin object will go out of scope one the function is # left) obs = bin.obs().copy() else: # Make a deep copy of the observation that will be returned # (the ctobssim object will go out of scope one the function is # left) obs = sim.obs().copy() # Delete the simulation del sim # Return observation container return obs
def counts_cube(output_dir, map_reso, map_coord, map_fov, emin, emax, enumbins, ebinalg, stack=True, logfile=None, silent=False): """ Compute counts cube. http://cta.irap.omp.eu/ctools/users/reference_manual/ctbin.html Parameters ---------- - output_dir (str): directory where to get input files and save outputs - map_reso (float): the resolution of the map (can be an astropy.unit object, or in deg) - map_coord (float): a skycoord object that give the center of the map - map_fov (float): the field of view of the map (can be an astropy.unit object, or in deg) - emin/emax (float): min and max energy in TeV - enumbins (int): the number of energy bins - ebinalg (str): the energy binning algorithm - stack (bool): do we use stacking of individual event files or not - silent (bool): use this keyword to print information Outputs -------- - Ana_Countscube.fits: the fits file cubed data, in case stack is requested - Ana_Countscube.xml: the xml file cubed data, in case stack is not requested - Ana_Countscubecta_{obsIDs}.fits: the fits files of individual event files cubed data, in case stack is not requested """ npix = utilities.npix_from_fov_def(map_fov, map_reso) ctscube = ctools.ctbin() ctscube['inobs'] = output_dir + '/Ana_EventsSelected.xml' if stack: ctscube['outobs'] = output_dir + '/Ana_Countscube.fits' else: ctscube['outobs'] = output_dir + '/Ana_Countscube.xml' ctscube['stack'] = stack ctscube['prefix'] = output_dir + '/Ana_Countscube' ctscube['ebinalg'] = ebinalg ctscube['emin'] = emin.to_value('TeV') ctscube['emax'] = emax.to_value('TeV') ctscube['enumbins'] = enumbins ctscube['ebinfile'] = 'NONE' ctscube['usepnt'] = False ctscube['nxpix'] = npix ctscube['nypix'] = npix ctscube['binsz'] = map_reso.to_value('deg') ctscube['coordsys'] = 'CEL' ctscube['proj'] = 'TAN' ctscube['xref'] = map_coord.icrs.ra.to_value('deg') ctscube['yref'] = map_coord.icrs.dec.to_value('deg') if logfile is not None: ctscube['logfile'] = logfile if logfile is not None: ctscube.logFileOpen() ctscube.execute() if logfile is not None: ctscube.logFileClose() if not silent: print(ctscube) print('') return ctscube
def run_pipeline(obs, ra=83.63, dec=22.01, emin=0.1, emax=100.0, enumbins=20, nxpix=200, nypix=200, binsz=0.02, coordsys='CEL', proj='CAR', debug=False): """ Simulation and stacked analysis pipeline Parameters ---------- obs : `~gammalib.GObservations` Observation container ra : float, optional Right Ascension of counts cube centre (deg) dec : float, optional Declination of Region of counts cube centre (deg) emin : float, optional Minimum energy (TeV) emax : float, optional Maximum energy (TeV) enumbins : int, optional Number of energy bins nxpix : int, optional Number of pixels in X axis nypix : int, optional Number of pixels in Y axis binsz : float, optional Pixel size (deg) coordsys : str, optional Coordinate system proj : str, optional Coordinate projection debug : bool, optional Debug function """ # Simulate events sim = ctools.ctobssim(obs) sim['debug'] = debug sim.run() # Bin events into counts map bin = ctools.ctbin(sim.obs()) bin['ebinalg'] = 'LOG' bin['emin'] = emin bin['emax'] = emax bin['enumbins'] = enumbins bin['nxpix'] = nxpix bin['nypix'] = nypix bin['binsz'] = binsz bin['coordsys'] = coordsys bin['proj'] = proj bin['xref'] = ra bin['yref'] = dec bin['debug'] = debug bin.run() # Create exposure cube expcube = ctools.ctexpcube(sim.obs()) expcube['incube'] = 'NONE' expcube['ebinalg'] = 'LOG' expcube['emin'] = emin expcube['emax'] = emax expcube['enumbins'] = enumbins expcube['nxpix'] = nxpix expcube['nypix'] = nypix expcube['binsz'] = binsz expcube['coordsys'] = coordsys expcube['proj'] = proj expcube['xref'] = ra expcube['yref'] = dec expcube['debug'] = debug expcube.run() # Create PSF cube psfcube = ctools.ctpsfcube(sim.obs()) psfcube['incube'] = 'NONE' psfcube['ebinalg'] = 'LOG' psfcube['emin'] = emin psfcube['emax'] = emax psfcube['enumbins'] = enumbins psfcube['nxpix'] = 10 psfcube['nypix'] = 10 psfcube['binsz'] = 1.0 psfcube['coordsys'] = coordsys psfcube['proj'] = proj psfcube['xref'] = ra psfcube['yref'] = dec psfcube['debug'] = debug psfcube.run() # Create background cube bkgcube = ctools.ctbkgcube(sim.obs()) bkgcube['incube'] = 'NONE' bkgcube['ebinalg'] = 'LOG' bkgcube['emin'] = emin bkgcube['emax'] = emax bkgcube['enumbins'] = enumbins bkgcube['nxpix'] = 10 bkgcube['nypix'] = 10 bkgcube['binsz'] = 1.0 bkgcube['coordsys'] = coordsys bkgcube['proj'] = proj bkgcube['xref'] = ra bkgcube['yref'] = dec bkgcube['debug'] = debug bkgcube.run() # Attach background model to observation container bin.obs().models(bkgcube.models()) # Set Exposure and Psf cube for first CTA observation # (ctbin will create an observation with a single container) bin.obs()[0].response(expcube.expcube(), psfcube.psfcube(), bkgcube.bkgcube()) # Perform maximum likelihood fitting like = ctools.ctlike(bin.obs()) like['debug'] = True # Switch this always on for results in console like.run() # Return return
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") # Use input file directly if given if self.m_use_maps: countmap = gammalib.GSkyMap(self["inobs"].filename()) modelmap = gammalib.GSkyMap(self.m_modcube) else: if self.m_skip_binning: cta_counts_cube = gammalib.GCTAEventCube(self.obs[0].events().clone()) else: # Write header if self.logTerse(): self.log("\n") self.log.header1("Generate binned map (ctbin)") # Create countsmap bin = ctools.ctbin(self.obs) bin["nxpix"].integer(self.m_nxpix) bin["nypix"].integer(self.m_nypix) bin["proj"].string(self.m_proj) bin["coordsys"].string(self.m_coordsys) bin["xref"].real(self.m_xref) bin["yref"].real(self.m_yref) bin["enumbins"].integer(self.m_enumbins) bin["ebinalg"].string(self.m_ebinalg) bin["emin"].real(self.m_emin) bin["emax"].real(self.m_emax) bin["binsz"].real(self.m_binsz) bin["chatter"].integer(self.m_chatter) bin["clobber"].boolean(self.m_clobber) bin["debug"].boolean(self.m_debug) bin.run() # Retrieve counts cube cta_counts_cube = bin.cube() # Assign GCTAEventCube to skymap countmap = cta_counts_cube.map() # Write header if self.logTerse(): self.log("\n") self.log.header1("Generate model map (ctmodel)") # Create model map model = ctools.ctmodel(self.obs) model.cube(cta_counts_cube) model["chatter"].integer(self.m_chatter) model["clobber"].boolean(self.m_clobber) model["debug"].boolean(self.m_debug) model["edisp"].boolean(self.m_edisp) model.run() # Get model map into GSkyMap object modelmap = model.cube().map().copy() # Store counts map as residual map. Note that we need a # special construct here to avoid memory leaks. This seems # to be a SWIG feature as SWIG creates a new object when # calling bin.cube() #residualmap = bin.cube().map() self.resmap = countmap.copy() self.resmap.stack_maps() modelmap.stack_maps() # Continue calculations depending on given algorithm if self.m_algorithm == "SUB": # Subtract maps self.resmap -= modelmap elif self.m_algorithm == "SUBDIV": # Subtract and divide by model map self.resmap -= modelmap self.resmap /= modelmap #for pixel in modelmap: # if pixel != 0.0: # pixel = 1.0/pixel #self.resmap *= modelmap elif self.m_algorithm == "SUBDIVSQRT": # subtract and divide by sqrt of model map self.resmap -= modelmap self.resmap /= modelmap.sqrt() #for pixel in modelmap: # if pixel != 0.0: # pixel = 1.0/math.sqrt(pixel) #self.resmap *= modelmap else: # Raise error if algorithm is unkown raise TypeError("Algorithm \""+self.m_algorithm+"\" not known") # Return return
def run_pipeline(obs, ra=83.63, dec=22.01, emin=0.1, emax=100.0, enumbins=20, nxpix=200, nypix=200, binsz=0.02, coordsys="CEL", proj="CAR", model="${CTOOLS}/share/models/crab.xml", caldb="prod2", irf="South_50h", debug=False): """ Simulation and stacked analysis pipeline. Keywords: ra - RA of cube centre [deg] (default: 83.6331) dec - DEC of cube centre [deg] (default: 22.0145) emin - Minimum energy of cube [TeV] (default: 0.1) emax - Maximum energy of cube [TeV] (default: 100.0) enumbins - Number of energy bins in cube (default: 20) nxpix - Number of RA pixels in cube (default: 200) nypix - Number of DEC pixels in cube (default: 200) binsz - Spatial cube bin size [deg] (default: 0.02) coordsys - Cube coordinate system (CEL or GAL) proj - Cube World Coordinate System (WCS) projection debug - Enable debugging (default: False) """ # Simulate events sim = ctools.ctobssim(obs) sim["debug"] = debug sim["outevents"] = "obs.xml" sim.execute() # Bin events into counts map bin = ctools.ctbin() bin["inobs"] = "obs.xml" bin["outcube"] = "cntcube.fits" bin["ebinalg"] = "LOG" bin["emin"] = emin bin["emax"] = emax bin["enumbins"] = enumbins bin["nxpix"] = nxpix bin["nypix"] = nypix bin["binsz"] = binsz bin["coordsys"] = coordsys bin["proj"] = proj bin["xref"] = ra bin["yref"] = dec bin["debug"] = debug bin.execute() # Create exposure cube expcube = ctools.ctexpcube() expcube["inobs"] = "obs.xml" expcube["incube"] = "cntcube.fits" expcube["outcube"] = "expcube.fits" expcube["caldb"] = caldb expcube["irf"] = irf expcube["ebinalg"] = "LOG" expcube["emin"] = emin expcube["emax"] = emax expcube["enumbins"] = enumbins expcube["nxpix"] = nxpix expcube["nypix"] = nypix expcube["binsz"] = binsz expcube["coordsys"] = coordsys expcube["proj"] = proj expcube["xref"] = ra expcube["yref"] = dec expcube["debug"] = debug expcube.execute() # Create PSF cube psfcube = ctools.ctpsfcube() psfcube["inobs"] = "obs.xml" psfcube["incube"] = "NONE" psfcube["outcube"] = "psfcube.fits" psfcube["caldb"] = caldb psfcube["irf"] = irf psfcube["ebinalg"] = "LOG" psfcube["emin"] = emin psfcube["emax"] = emax psfcube["enumbins"] = enumbins psfcube["nxpix"] = 10 psfcube["nypix"] = 10 psfcube["binsz"] = 1.0 psfcube["coordsys"] = coordsys psfcube["proj"] = proj psfcube["xref"] = ra psfcube["yref"] = dec psfcube["debug"] = debug psfcube.execute() # Create background cube bkgcube = ctools.ctbkgcube() bkgcube["inobs"] = "obs.xml" bkgcube["inmodel"] = model bkgcube["incube"] = "cntcube.fits" bkgcube["outcube"] = "bkgcube.fits" bkgcube["outmodel"] = "model_bkg.xml" bkgcube["caldb"] = caldb bkgcube["irf"] = irf bkgcube["ebinalg"] = "LOG" bkgcube["emin"] = emin bkgcube["emax"] = emax bkgcube["enumbins"] = enumbins bkgcube["nxpix"] = 10 bkgcube["nypix"] = 10 bkgcube["binsz"] = 1.0 bkgcube["coordsys"] = coordsys bkgcube["proj"] = proj bkgcube["xref"] = ra bkgcube["yref"] = dec bkgcube["debug"] = debug bkgcube.execute() # Perform maximum likelihood fitting like = ctools.ctlike() like["inobs"] = "cntcube.fits" like["inmodel"] = "model_bkg.xml" like["outmodel"] = "fit_results.xml" like["expcube"] = "expcube.fits" like["psfcube"] = "psfcube.fits" like["bkgcube"] = "bkgcube.fits" like["caldb"] = caldb like["irf"] = irf like["debug"] = True # Switch this always on for results in console like.execute() # Return return
def binned_pipeline(duration): """ Binned 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 enumbins = 20 nxpix = 200 nypix = 200 binsz = 0.02 coordsys = "CEL" proj = "CAR" # 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() # Bin events into counts map bin = ctools.ctbin(sim.obs()) bin["ebinalg"].string("LOG") bin["emin"].real(emin) bin["emax"].real(emax) bin["enumbins"].integer(enumbins) bin["nxpix"].integer(nxpix) bin["nypix"].integer(nypix) bin["binsz"].real(binsz) bin["coordsys"].string(coordsys) bin["xref"].real(ra) bin["yref"].real(dec) bin["proj"].string(proj) bin.run() # Get ctlike start CPU time tctlike = time.clock() # Perform maximum likelihood fitting like = ctools.ctlike(bin.obs()) like.run() # Get stop CPU time tstop = time.clock() telapsed = tstop - tstart tctlike = tstop - tctlike # Return return telapsed, tctlike
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
sim['irf'] = irf sim['outevents'] = 'events_nu_' + 's_' + irf + '_' + str( int(tobscta)) + 's_' + str(i + 1) + '.fits' sim['ra'] = ra sim['dec'] = dec sim['rad'] = 5.0 sim['tmin'] = '2020-05-31T12:00:00' sim['tmax'] = '2020-05-31T12:10:00' sim['emin'] = emin sim['emax'] = emax sim['maxrate'] = 1.0e9 sim['debug'] = debug sim['edisp'] = edisp sim.execute() c_bin = ctools.ctbin() c_bin['inobs'] = 'events_nu_' + 's_' + irf + '_' + str( int(tobscta)) + 's_' + str(i + 1) + '.fits' c_bin['xref'] = ra c_bin['yref'] = dec c_bin['proj'] = 'CAR' c_bin['coordsys'] = 'CEL' c_bin['binsz'] = binz c_bin['nxpix'] = x_pixs c_bin['nypix'] = y_pixs c_bin['ebinalg'] = 'LOG' c_bin['emin'] = emin c_bin['emax'] = emax c_bin['enumbins'] = n_bins c_bin['outcube'] = 'cube_' + str(i + 1) + '.fits' c_bin['debug'] = debug
sim['outevents'] = 'events_nu_' + irf + '_' + str( int(tobscta)) + 's_' + str(i + 1) + '.fits' sim['ra'] = ra sim['dec'] = dec sim['rad'] = 5.0 sim['tmin'] = '2020-05-31T12:00:00' sim['tmax'] = '2020-05-31T12:10:00' sim['emin'] = 0.02 sim['emax'] = 199.0 sim['maxrate'] = 1.0e9 sim['seed'] = nuseed sim['debug'] = debug sim['edisp'] = edisp sim.execute() binning = ctools.ctbin() binning['inobs'] = 'events_nu_' + irf + '_' + str( int(tobscta)) + 's_' + str(i + 1) + '.fits' binning['xref'] = ra binning['yref'] = dec binning['coordsys'] = 'CEL' binning['proj'] = 'CAR' binning['binsz'] = 0.02 binning['nxpix'] = 500 binning['nypix'] = 500 binning['ebinalg'] = 'LOG' binning['emin'] = 0.02 binning['emax'] = 199.0 binning['enumbins'] = 40 binning['outcube'] = 'cntcube_nu_' + irf + '_' + str( int(tobscta)) + 's_' + str(i + 1) + '.fits'
def run_pipeline(obs, emin=0.1, emax=100.0, \ enumbins=20, nxpix=200, nypix=200, binsz=0.02, \ coordsys="CEL", proj="CAR", \ model="${CTOOLS}/share/models/crab.xml", \ caldb="prod2", irf="South_50h", \ debug=False): """ Simulation and binned analysis pipeline. Keywords: emin - Minimum energy of cube [TeV] (default: 0.1) emax - Maximum energy of cube [TeV] (default: 100.0) enumbins - Number of energy bins in cube (default: 20) nxpix - Number of RA pixels in cube (default: 200) nypix - Number of DEC pixels in cube (default: 200) binsz - Spatial cube bin size [deg] (default: 0.02) coordsys - Cube coordinate system (CEL or GAL) proj - Cube World Coordinate System (WCS) projection model - Model Xml file caldb - Calibration database path (default: "dummy") irf - Instrument response function (default: cta_dummy_irf) debug - Enable debugging (default: False) """ # Simulate events sim = ctools.ctobssim(obs) sim["debug"].boolean(debug) sim["outevents"].filename("obs.xml") sim.execute() # Bin events by looping over all observations in the container sim_obs = gammalib.GObservations("obs.xml") obs = gammalib.GObservations() for run in sim_obs: # Get event filename and set counts cube filename eventfile = run.eventfile() cubefile = "cube_"+eventfile # Bin events for that observation bin = ctools.ctbin() bin["inobs"].filename(eventfile) bin["outcube"].filename(cubefile) bin["ebinalg"].string("LOG") bin["emin"].real(emin) bin["emax"].real(emax) bin["enumbins"].integer(enumbins) bin["nxpix"].integer(nxpix) bin["nypix"].integer(nypix) bin["binsz"].real(binsz) bin["coordsys"].string(coordsys) bin["usepnt"].boolean(True) bin["proj"].string(proj) bin.execute() # Set observation ID bin.obs()[0].id(cubefile) bin.obs()[0].eventfile(cubefile) # Append result to observations obs.extend(bin.obs()) # Save XML file xml = gammalib.GXml() obs.write(xml) xml.save("obs_cube.xml") # Perform maximum likelihood fitting like = ctools.ctlike() like["inobs"].filename("obs_cube.xml") like["inmodel"].filename(model) like["outmodel"].filename("fit_results.xml") like["expcube"].filename("NONE") like["psfcube"].filename("NONE") like["bkgcube"].filename("NONE") like["caldb"].string(caldb) like["irf"].string(irf) like["debug"].boolean(True) # Switch this always on for results in console like.execute() # Return return
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
def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, emin=None, emax=None, nbins=0, binsz=0.05, npix=200, proj='TAN', coord='GAL'): """ Simulate events for all observations in the container Parameters ---------- obs : `~gammalib.GObservations` Observation container without events log : bool, optional Create log file(s) debug : bool, optional Create console dump? chatter : int, optional Chatter level edisp : bool, optional Apply energy dispersion? seed : int, integer Seed value for simulations emin : float, optional Minimum energy of counts cube for binned (TeV) emax : float, optional Maximum energy of counts cube for binned (TeV) nbins : int, optional Number of energy bins (0=unbinned) binsz : float, optional Pixel size for binned simulation (deg/pixel) npix : int, optional Number of pixels in X and Y for binned simulation proj : str, optional Projection for binned simulation coord : str, optional Coordinate system for binned simulation Returns ------- obs : `~gammalib.GObservations` Observation container filled with simulated events """ # Allocate ctobssim application and set parameters sim = ctools.ctobssim(obs) sim['seed'] = seed sim['edisp'] = edisp sim['chatter'] = chatter sim['debug'] = debug # Optionally open the log file if log: sim.logFileOpen() # Run ctobssim application. This will loop over all observations in the # container and simulation the events for each observation. Note that # events are not added together, they still apply to each observation # separately. sim.run() # Binned option? if nbins > 0: # If energy boundaries are not given then determine common energy # boundaries for all observations if emin == None or emax == None: emin = None emax = None for run in sim.obs(): run_emin = run.events().ebounds().emin().TeV() run_emax = run.events().ebounds().emax().TeV() if emin == None: emin = run_emin elif run_emin > emin: emin = run_emin if emax == None: emax = run_emax elif run_emax > emax: emax = run_emax # Allocate ctbin application and set parameters bin = ctools.ctbin(sim.obs()) bin['ebinalg'] = 'LOG' bin['emin'] = emin bin['emax'] = emax bin['enumbins'] = nbins bin['usepnt'] = True # Use pointing for map centre bin['nxpix'] = npix bin['nypix'] = npix bin['binsz'] = binsz bin['coordsys'] = coord bin['proj'] = proj bin['chatter'] = chatter bin['debug'] = debug # Optionally open the log file if log: bin.logFileOpen() # Run ctbin application. This will loop over all observations in # the container and bin the events in counts maps bin.run() # Make a deep copy of the observation that will be returned # (the ctbin object will go out of scope one the function is # left) obs = bin.obs().copy() else: # Make a deep copy of the observation that will be returned # (the ctobssim object will go out of scope one the function is # left) obs = sim.obs().copy() # Delete the simulation del sim # Return observation container return obs
def stackedPipeline( name="Crab", obsfile="index.xml", l=0.01, b=0.01, emin=0.1, emax=100.0, enumbins=20, nxpix=200, nypix=200, binsz=0.02, coordsys="CEL", proj="CAR", caldb="prod2", irf="acdc1a", debug=False, inmodel="Crab", outmodel="results", ): """ Simulation and stacked analysis pipeline Parameters ---------- obs : `~gammalib.GObservations` Observation container ra : float, optional Right Ascension of counts cube centre (deg) dec : float, optional Declination of Region of counts cube centre (deg) emin : float, optional Minimum energy (TeV) emax : float, optional Maximum energy (TeV) enumbins : int, optional Number of energy bins nxpix : int, optional Number of pixels in X axis nypix : int, optional Number of pixels in Y axis binsz : float, optional Pixel size (deg) coordsys : str, optional Coordinate system proj : str, optional Coordinate projection debug : bool, optional Debug function """ # Bin events into counts map bin = ctools.ctbin() bin["inobs"] = obsfile bin["ebinalg"] = "LOG" bin["emin"] = emin bin["emax"] = emax bin["enumbins"] = enumbins bin["nxpix"] = nxpix bin["nypix"] = nypix bin["binsz"] = binsz bin["coordsys"] = coordsys bin["proj"] = proj bin["xref"] = l bin["yref"] = b bin["debug"] = debug bin["outobs"] = "cntcube.fits" bin.execute() print("Datacube : done!") # Create exposure cube expcube = ctools.ctexpcube() # expcube['incube']=bin.obs() expcube["inobs"] = obsfile expcube["incube"] = "NONE" expcube["ebinalg"] = "LOG" expcube["caldb"] = caldb expcube["irf"] = irf expcube["emin"] = emin expcube["emax"] = emax expcube["enumbins"] = enumbins expcube["nxpix"] = nxpix expcube["nypix"] = nypix expcube["binsz"] = binsz expcube["coordsys"] = coordsys expcube["proj"] = proj expcube["xref"] = l expcube["yref"] = b expcube["debug"] = debug expcube["outcube"] = "cube_exp.fits" expcube.execute() print("Expcube : done!") # Create PSF cube psfcube = ctools.ctpsfcube() psfcube["inobs"] = obsfile psfcube["incube"] = "NONE" psfcube["ebinalg"] = "LOG" psfcube["caldb"] = caldb psfcube["irf"] = irf psfcube["emin"] = emin psfcube["emax"] = emax psfcube["enumbins"] = enumbins psfcube["nxpix"] = 10 psfcube["nypix"] = 10 psfcube["binsz"] = 1.0 psfcube["coordsys"] = coordsys psfcube["proj"] = proj psfcube["xref"] = l psfcube["yref"] = b psfcube["debug"] = debug psfcube["outcube"] = "psf_cube.fits" psfcube.execute() print("Psfcube : done!") edispcube = ctools.ctedispcube() edispcube["inobs"] = obsfile edispcube["ebinalg"] = "LOG" edispcube["incube"] = "NONE" edispcube["caldb"] = caldb edispcube["irf"] = irf edispcube["xref"] = l edispcube["yref"] = b edispcube["proj"] = proj edispcube["coordsys"] = coordsys edispcube["binsz"] = 1.0 edispcube["nxpix"] = 10 edispcube["nypix"] = 10 edispcube["emin"] = emin edispcube["emax"] = emax edispcube["enumbins"] = enumbins edispcube["outcube"] = "edisp_cube.fits" edispcube["debug"] = debug edispcube.execute() print("Edispcube : done!") # Create background cube bkgcube = ctools.ctbkgcube() bkgcube["inobs"] = obsfile bkgcube["incube"] = "cntcube.fits" bkgcube["caldb"] = caldb bkgcube["irf"] = irf bkgcube["debug"] = debug bkgcube["inmodel"] = str(inmodel) bkgcube["outcube"] = "bkg_cube.fits" bkgcube["outmodel"] = "bkg_cube.xml" bkgcube.execute() print("Bkgcube : done!") # Fix the instrumental background parameters bkgcube.models()["BackgroundModel"]["Prefactor"].fix() bkgcube.models()["BackgroundModel"]["Index"].fix() # # # Attach background model to observation container bin.obs().models(bkgcube.models()) # # # # Set Exposure and Psf cube for first CTA observation # # (ctbin will create an observation with a single container) bin.obs()[0].response(expcube.expcube(), psfcube.psfcube(), edispcube.edispcube(), bkgcube.bkgcube()) # Perform maximum likelihood fitting like = ctools.ctlike(bin.obs()) # like['inmodel']='bkg_cube.xml' like["edisp"] = True # like['edispcube'] = 'edisp_cube.fits' # like['expcube'] = 'cube_exp.fits' # like['psfcube'] = 'psf_cube.fits' # like['bkgcube'] = 'bkg_cube.fits' like["outmodel"] = str(outmodel) # like['outcovmat']=inmodel+'_covmat.txt' like["debug"] = debug # Switch this always on for results in console # like['statistic']='CSTAT' like.execute() print("Likelihood : done!") # Set the best-fit models (from ctlike) for the counts cube bin.obs().models(like.obs().models()) # Obtain the best-fit butterfly try: butterfly = ctools.ctbutterfly(bin.obs()) butterfly["srcname"] = name butterfly["inmodel"] = str(outmodel) butterfly["edisp"] = True butterfly["emin"] = emin butterfly["emax"] = emax butterfly["outfile"] = str(outmodel.parent) + "/" + str( outmodel.stem) + ".txt" butterfly[ "debug"] = debug # Switch this always on for results in console # like['statistic']='CSTAT' butterfly.execute() print("Butterfly : done!") except: print("I COULDN'T CALCULATE THE BUTTERFLY....") # Extract the spectrum try: csspec = cscripts.csspec(bin.obs()) csspec["srcname"] = name csspec["inmodel"] = str(outmodel) csspec["method"] = "AUTO" csspec["ebinalg"] = "LOG" csspec["emin"] = emin csspec["emax"] = emax csspec["enumbins"] = 10 csspec["edisp"] = True csspec["outfile"] = str(outmodel.parent) + "/" + str( outmodel.stem) + ".fits" csspec["debug"] = debug # Switch this always on for results in console csspec.execute() print("Csspec : done!") except: print("I COULDN'T CALCULATE THE SPECTRUM....") # Return return
def _test_python(self): """ Test ctbin from Python """ # Allocate ctbin binning = ctools.ctbin() # Check that empty ctbin has an empty observation container and counts # cube self.test_value(binning.obs().size(), 0, 'Check that empty ctbin has an empty observation container') self.test_value(binning.cube().size(), 0, 'Check that empty ctbin has an empty counts cube') # Check that saving does not nothing binning['logfile'] = 'ctbin_py0.log' binning['outcube'] = 'ctbin_py0.fits' binning.logFileOpen() binning.save() self.test_assert(not os.path.isfile('ctbin_py0.fits'), 'Check that no counts cube has been created') # Check that publishing does not lead to an exception or segfault binning.publish() # Check that clearing does not lead to an exception or segfault binning.clear() # Now set ctbin parameters binning['inobs'] = self._events binning['outcube'] = 'ctbin_py1.fits' binning['ebinalg'] = 'LOG' binning['emin'] = 0.1 binning['emax'] = 100.0 binning['enumbins'] = 10 binning['nxpix'] = 40 binning['nypix'] = 40 binning['binsz'] = 0.1 binning['coordsys'] = 'CEL' binning['proj'] = 'CAR' binning['xref'] = 83.63 binning['yref'] = 22.01 binning['logfile'] = 'ctbin_py1.log' binning['chatter'] = 2 # Run ctbin tool binning.logFileOpen() binning.run() # Check content of observation container and counts cube self._check_observation(binning, 3105) self._check_cube(binning.cube(), 3105) # Copy ctbin tool cpy_bin = binning.copy() # Check content of observation container and counts cube self._check_observation(cpy_bin, 3105) self._check_cube(cpy_bin.cube(), 3105) # Run copy of ctbin tool again cpy_bin['logfile'] = 'ctbin_py2.log' cpy_bin['chatter'] = 3 cpy_bin.logFileOpen() cpy_bin.run() # Check content of observation container and counts cube. Now an empty # event cube is expected since on input the observation is binned, and # any binned observation will be skipped. self._check_observation(cpy_bin, 0) self._check_cube(cpy_bin.cube(), 0) # Save counts cube binning.save() # Load counts cube and check content evt = gammalib.GCTAEventCube('ctbin_py1.fits') self._check_cube(evt, 3105) # Now clear ctbin tool binning.clear() # Check that cleared ctbin has an empty observation container and # counts cube self.test_value(binning.obs().size(), 0, 'Check that empty ctbin has an empty observation container') self.test_value(binning.cube().size(), 0, 'Check that empty ctbin has an empty counts cube') # Prepare observation container for stacking of events into a # single counts cube obs = self._obs_events() # Set-up ctbin using an observation container binning = ctools.ctbin(obs) binning['outcube'] = 'ctbin_py3.fits' binning['ebinalg'] = 'LOG' binning['emin'] = 0.1 binning['emax'] = 100.0 binning['enumbins'] = 10 binning['nxpix'] = 40 binning['nypix'] = 40 binning['binsz'] = 0.1 binning['coordsys'] = 'CEL' binning['proj'] = 'CAR' binning['xref'] = 83.63 binning['yref'] = 22.01 binning['publish'] = True binning['logfile'] = 'ctbin_py3.log' binning['chatter'] = 3 # Execute ctbin tool binning.logFileOpen() binning.execute() # Check content of observation and cube (need multiplier=3 since # three identical observations have been appended) self._check_observation(binning, 3105, multiplier=3) self._check_cube(binning.cube(), 3105, multiplier=3) # Load counts cube and check content. evt = gammalib.GCTAEventCube('ctbin_py3.fits') self._check_cube(evt, 3105, multiplier=3) # And finally go for a fully Pythonic version with all parameters # being specified in a dictionary pars = {'inobs': self._events, 'ebinalg': 'LIN', 'emin': 0.1, 'emax': 100.0, 'enumbins': 10, 'nxpix': 40, 'nypix': 40, 'binsz': 0.1, 'coordsys': 'CEL', 'proj': 'CAR', 'xref': 83.63, 'yref': 22.01, 'outcube': 'ctbin_py4.fits', 'logfile': 'ctbin_py4.log', 'chatter': 2} binning = ctools.ctbin() binning.pardict(pars) binning.logFileOpen() binning.execute() # Load counts cube and check content evt = gammalib.GCTAEventCube('ctbin_py4.fits') self._check_cube(evt, 3105) # Return return
def run_pipeline(obs, emin=0.1, emax=100.0, enumbins=20, nxpix=200, nypix=200, binsz=0.02, coordsys='CEL', proj='CAR', model='data/crab.xml', caldb='prod2', irf='South_0.5h', debug=False): """ Simulation and binned analysis pipeline Parameters ---------- obs : `~gammalib.GObservations` Observation container emin : float, optional Minimum energy (TeV) emax : float, optional Maximum energy (TeV) enumbins : int, optional Number of energy bins nxpix : int, optional Number of pixels in X axis nypix : int, optional Number of pixels in Y axis binsz : float, optional Pixel size (deg) coordsys : str, optional Coordinate system proj : str, optional Coordinate projection model : str, optional Model definition XML file caldb : str, optional Calibration database path irf : str, optional Instrument response function debug : bool, optional Debug function """ # Simulate events sim = ctools.ctobssim(obs) sim['debug'] = debug sim['outevents'] = 'obs.xml' sim.execute() # Bin events by looping over all observations in the container sim_obs = gammalib.GObservations('obs.xml') obs = gammalib.GObservations() for run in sim_obs: # Get event filename and set counts cube filename eventfile = run.eventfile().url() cubefile = 'cube_'+eventfile # Bin events for that observation bin = ctools.ctbin() bin['inobs'] = eventfile bin['outcube'] = cubefile bin['ebinalg'] = 'LOG' bin['emin'] = emin bin['emax'] = emax bin['enumbins'] = enumbins bin['nxpix'] = nxpix bin['nypix'] = nypix bin['binsz'] = binsz bin['coordsys'] = coordsys bin['usepnt'] = True bin['proj'] = proj bin.execute() # Set observation ID bin.obs()[0].id(cubefile) bin.obs()[0].eventfile(cubefile) # Append result to observations obs.extend(bin.obs()) # Save XML file xml = gammalib.GXml() obs.write(xml) xml.save('obs_cube.xml') # Perform maximum likelihood fitting like = ctools.ctlike() like['inobs'] = 'obs_cube.xml' like['inmodel'] = model like['outmodel'] = 'fit_results.xml' like['expcube'] = 'NONE' like['psfcube'] = 'NONE' like['bkgcube'] = 'NONE' like['caldb'] = caldb like['irf'] = irf like['debug'] = True # Switch this always on for results in console like.execute() # Return return
def run_pipeline(obs, ra=83.63, dec=22.01, emin=0.1, emax=100.0, enumbins=20, nxpix=200, nypix=200, binsz=0.02, coordsys="CEL", proj="CAR", debug=False): """ Simulation and stacked analysis pipeline. Keywords: ra - RA of cube centre [deg] (default: 83.6331) dec - DEC of cube centre [deg] (default: 22.0145) emin - Minimum energy of cube [TeV] (default: 0.1) emax - Maximum energy of cube [TeV] (default: 100.0) enumbins - Number of energy bins in cube (default: 20) nxpix - Number of RA pixels in cube (default: 200) nypix - Number of DEC pixels in cube (default: 200) binsz - Spatial cube bin size [deg] (default: 0.02) coordsys - Cube coordinate system (CEL or GAL) proj - Cube World Coordinate System (WCS) projection debug - Enable debugging (default: False) """ # Simulate events sim = ctools.ctobssim(obs) sim["debug"] = debug sim.run() # Bin events into counts map bin = ctools.ctbin(sim.obs()) bin["ebinalg"] = "LOG" bin["emin"] = emin bin["emax"] = emax bin["enumbins"] = enumbins bin["nxpix"] = nxpix bin["nypix"] = nypix bin["binsz"] = binsz bin["coordsys"] = coordsys bin["proj"] = proj bin["xref"] = ra bin["yref"] = dec bin["debug"] = debug bin.run() # Create exposure cube expcube = ctools.ctexpcube(sim.obs()) expcube["incube"] = "NONE" expcube["ebinalg"] = "LOG" expcube["emin"] = emin expcube["emax"] = emax expcube["enumbins"] = enumbins expcube["nxpix"] = nxpix expcube["nypix"] = nypix expcube["binsz"] = binsz expcube["coordsys"] = coordsys expcube["proj"] = proj expcube["xref"] = ra expcube["yref"] = dec expcube["debug"] = debug expcube.run() # Create PSF cube psfcube = ctools.ctpsfcube(sim.obs()) psfcube["incube"] = "NONE" psfcube["ebinalg"] = "LOG" psfcube["emin"] = emin psfcube["emax"] = emax psfcube["enumbins"] = enumbins psfcube["nxpix"] = 10 psfcube["nypix"] = 10 psfcube["binsz"] = 1.0 psfcube["coordsys"] = coordsys psfcube["proj"] = proj psfcube["xref"] = ra psfcube["yref"] = dec psfcube["debug"] = debug psfcube.run() # Create background cube bkgcube = ctools.ctbkgcube(sim.obs()) bkgcube["incube"] = "NONE" bkgcube["ebinalg"] = "LOG" bkgcube["emin"] = emin bkgcube["emax"] = emax bkgcube["enumbins"] = enumbins bkgcube["nxpix"] = 10 bkgcube["nypix"] = 10 bkgcube["binsz"] = 1.0 bkgcube["coordsys"] = coordsys bkgcube["proj"] = proj bkgcube["xref"] = ra bkgcube["yref"] = dec bkgcube["debug"] = debug bkgcube.run() # Attach background model to observation container bin.obs().models(bkgcube.models()) # Set Exposure and Psf cube for first CTA observation # (ctbin will create an observation with a single container) bin.obs()[0].response(expcube.expcube(), psfcube.psfcube(), bkgcube.bkgcube()) # Perform maximum likelihood fitting like = ctools.ctlike(bin.obs()) like["debug"] = True # Switch this always on for results in console like.run() # Return return
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') # If a counts and model cube are specified then load them as sky map if self._use_maps: countmap = gammalib.GSkyMap(self['inobs'].filename()) modelmap = gammalib.GSkyMap(self['modcube'].filename()) # ... otherwise build a counts cube and model cube else: # Do not build counts cube if we have already one in the observation # container if self._skip_binning: cta_counts_cube = gammalib.GCTAEventCube(self.obs()[0].events()) # ... otherwise generate one now from the event list else: # Write header self._log_header1(gammalib.TERSE, 'Generate binned map (ctbin)') # Create countsmap binning = ctools.ctbin(self.obs()) binning['xref'] = self['xref'].real() binning['yref'] = self['yref'].real() binning['proj'] = self['proj'].string() binning['coordsys'] = self['coordsys'].string() binning['ebinalg'] = self['ebinalg'].string() binning['nxpix'] = self['nxpix'].integer() binning['nypix'] = self['nypix'].integer() binning['binsz'] = self['binsz'].real() if self['ebinalg'].string() == 'FILE': binning['ebinfile'] = self['ebinfile'].filename().file() else: binning['enumbins'] = self['enumbins'].integer() binning['emin'] = self['emin'].real() binning['emax'] = self['emax'].real() binning['chatter'] = self['chatter'].integer() binning['clobber'] = self['clobber'].boolean() binning['debug'] = self['debug'].boolean() binning.run() # Retrieve counts cube cta_counts_cube = binning.cube() # Assign GCTAEventCube to skymap countmap = cta_counts_cube.counts() # Write header self._log_header1(gammalib.TERSE, 'Generate model map (ctmodel)') # Create model map model = ctools.ctmodel(self.obs()) model.cube(cta_counts_cube) model['chatter'] = self['chatter'].integer() model['clobber'] = self['clobber'].boolean() model['debug'] = self['debug'].boolean() model['edisp'] = self['edisp'].boolean() model.run() # Get model map into GSkyMap object modelmap = model.cube().counts().copy() # Calculate residual maps # Note that we need a special # construct here to avoid memory leaks. This seems to be a SWIG feature # as SWIG creates a new object when calling binning.cube() countmap1 = countmap.copy() countmap1.stack_maps() modelmap.stack_maps() self._resmap = obsutils.residuals(self,countmap1,modelmap) # Optionally publish map if self['publish'].boolean(): self.publish() # Return return
def _bin_evlist(self, obs): """ Turn single event list into counts cube Parameters ---------- obs : `~gammalib.GObservations` Observation container with single event list Returns ------- obs, info : `~gammalib.GObservations`, dict Binned observation container and dictionary with event list ROI and energy range information """ # Retrieve information about ROI in event list roi = obs[0].roi() ra = roi.centre().dir().ra_deg() dec = roi.centre().dir().dec_deg() rad = roi.radius() # We will cover the whole ROI with 0.02 deg binning npix = int(2.0 * rad / 0.02) + 1 # Log binning of events self._log_string(gammalib.EXPLICIT, 'Binning events') # Bin events cntcube = ctools.ctbin(obs) cntcube['xref'] = ra cntcube['yref'] = dec cntcube['binsz'] = 0.02 cntcube['nxpix'] = npix cntcube['nypix'] = npix cntcube['proj'] = 'TAN' cntcube['coordsys'] = 'CEL' cntcube['ebinalg'] = self['ebinalg'].string() if self['ebinalg'].string() == 'FILE': cntcube['ebinfile'] = self['ebinfile'].filename() else: cntcube['enumbins'] = self['enumbins'].integer() cntcube['emin'] = self['emin'].real() cntcube['emax'] = self['emax'].real() cntcube.run() # Retrieve the binned observation container binned_obs = cntcube.obs().copy() # Check if energy boundaries provided by user extend beyond the # content of the event list if self['emin'].real() > obs[0].events().emin().TeV(): emin = 'INDEF' else: emin = obs[0].events().emin().TeV() if self['emax'].real() < obs[0].events().emax().TeV(): emax = 'INDEF' else: emax = obs[0].events().emax().TeV() # Log energy range self._log_value(gammalib.EXPLICIT, 'Minimum energy (TeV)', emin) self._log_value(gammalib.EXPLICIT, 'Maximum energy (TeV)', emax) # Put ROI and E bound info in dictionary info = { 'was_list': True, 'roi_ra': ra, 'roi_dec': dec, 'roi_rad': rad, 'emin': emin, 'emax': emax } # Return new oberservation container return binned_obs, info