def _test_pickeling(self): """ Test csphagen pickeling """ # Perform pickeling tests of empty class self._pickeling(cscripts.csphagen()) # Set-up csphagen phagen = cscripts.csphagen() phagen['inobs'] = self._myevents1 phagen['inmodel'] = 'NONE' phagen['caldb'] = self._caldb phagen['irf'] = self._irf phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['coordsys'] = 'CEL' phagen['ra'] = 83.633 phagen['dec'] = 22.0145 phagen['rad'] = 0.2 phagen['stack'] = False phagen['inexclusion'] = self._exclusion phagen['bkgmethod'] = 'REFLECTED' phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['outobs'] = 'csphagen_py1_obs_pickle.xml' phagen['outmodel'] = 'csphagen_py1_model_pickle.xml' phagen['prefix'] = 'csphagen_py1_pickle' phagen['logfile'] = 'csphagen_py1_pickle.log' phagen['chatter'] = 1 # Perform pickeling tests of filled class obj = self._pickeling(phagen) # Run csspec script and save light curve obj.logFileOpen() # Make sure we get a log file obj.run() obj.save() # Check result files self._check_output('csphagen_py1_pickle', self._nbins, self._nreg_with_excl) self._check_outobs('csphagen_py1_obs_pickle.xml', 1) # Return return
def csphagen_run(ev_file, force=0): working_dir = os.path.dirname(ev_file) log_file = os.path.join(working_dir, "csphagen.log") output_model_file = os.path.join(working_dir, "onoff_result.xml") output_obs_def = os.path.join(working_dir, "onoff_obs.xml") if not os.path.isfile(output_obs_def) or not os.path.isfile( output_model_file) or force == 1: phagen = cscripts.csphagen() phagen.clear() phagen["inobs"] = ev_file phagen["inmodel"] = OBJ["model"] phagen["srcname"] = OBJ["name"] phagen["caldb"] = "prod2" phagen["irf"] = "South_0.5h" phagen["ebinalg"] = "LIN" phagen["emin"] = ENERGY["min"] phagen["emax"] = ENERGY["max"] phagen["enumbins"] = 1 phagen["coordsys"] = "CEL" phagen["ra"] = OBJ["ra"] phagen["dec"] = OBJ["dec"] phagen["rad"] = 0.2 phagen["stack"] = False phagen["bkgmethod"] = "REFLECTED" phagen["outobs"] = output_obs_def phagen["outmodel"] = output_model_file phagen["prefix"] = os.path.join(working_dir, "onoff") phagen["logfile"] = log_file phagen.logFileOpen() phagen.run() phagen.save() sys.stderr.write("File '%s' created.\n" % output_obs_def) sys.stderr.write("File '%s' created.\n" % output_model_file) return {"obs": output_obs_def, "model": output_model_file}
def onoff_filegen(inobs, inmodel, srcname, outobs, outmodel, prefix, ebinalg, emin, emax, enumbins, ra, dec, rad, caldb=None, irf=None, inexclusion=None, bkgregmin=2, bkgregskip=1, use_model_bkg=True, maxoffset=4.0, stack=True, etruemin=0.01, etruemax=300, etruebins=30, logfile=None, silent=False): """ Compute ON OFF regions. See http://cta.irap.omp.eu/ctools/users/reference_manual/ctskymap.html Parameters ---------- - Outputs -------- - onoff files are created - onoff cscript is output """ onoff = cscripts.csphagen() # Input event list or observation definition XML file. onoff['inobs'] = inobs # Input model XML file (if NONE a point source at the centre of the source region is used). onoff['inmodel'] = inmodel # Name of the source in the source model XML file which should be used for ARF computation. onoff['srcname'] = srcname # Calibration database. if caldb is not None: onoff['caldb'] = caldb else: onoff['caldb'] = 'NONE' # Instrument response function. if irf is not None: onoff['irf'] = irf else: onoff['irf'] = 'NONE' # Optional FITS file containing a WCS map that defines sky regions not to be used for background estimation if inexclusion is not None: onoff['inexclusion'] = inexclusion # Output observation definition XML file. onoff['outobs'] = outobs # Output model XML file. onoff['outmodel'] = outmodel # Prefix of the file name for output PHA, ARF, RMF, XML, and DS9 region files. onoff['prefix'] = prefix # Algorithm for defining energy bins. onoff['ebinalg'] = ebinalg # Lower energy value for first energy bin (in TeV) if LIN or LOG energy binning algorithms are used. onoff['emin'] = emin # Upper energy value for last energy bin (in TeV) if LIN or LOG energy binning algorithms are used. onoff['emax'] = emax # Number of energy bins if LIN or LOG energy binning algorithms are used. onoff['enumbins'] = enumbins # Name of the file containing the energy binning definition ## onoff['ebinfile'] [file] # Exponent of the power law for POW energy binning. ## onoff['ebingamma'] [real] # Shape of the source region. So far only CIRCLE exists which defines a circular region around location onoff['srcshape'] = 'CIRCLE' # Coordinate system (CEL - celestial, GAL - galactic). onoff['coordsys'] = 'CEL' # Right Ascension of source region centre (deg). onoff['ra'] = ra # Declination of source region centre (deg). onoff['dec'] = dec # Radius of source region circle (deg). onoff['rad'] = rad # Source region file (ds9 or FITS WCS map). onoff['srcregfile'] = 'NONE' # Method for background estimation onoff['bkgmethod'] = 'REFLECTED' # Background regions file (ds9 or FITS WCS map). onoff['bkgregfile'] = 'NONE' # Minimum number of background regions that are required for an observation. onoff['bkgregmin'] = bkgregmin # Number of background regions that should be skipped next to the On regions. onoff['bkgregskip'] = bkgregskip # Specifies whether the background model should be used for the computation of the alpha parameter onoff['use_model_bkg'] = use_model_bkg # Maximum offset in degrees of source from camera center to accept the observation. onoff['maxoffset'] = maxoffset # Specifies whether multiple observations should be stacked or whether run-wise files should be produced onoff['stack'] = stack # Minimum true energy (TeV). onoff['etruemin'] = etruemin # Maximum true energy (TeV). onoff['etruemax'] = etruemax # Number of bins per decade for true energy bins. onoff['etruebins'] = etruebins if logfile is not None: onoff['logfile'] = logfile if logfile is not None: onoff.logFileOpen() onoff.execute() if logfile is not None: onoff.logFileClose() if not silent: print(onoff) print('') return onoff
def prepare_onoff(obsname, srcmodel, spec, bkgname, emin=0.3, emax=50.0, ebins=20, alpha=1.0): """ Prepare On/Off observations Parameters ---------- obsname : str Observation definition XML file srcmodel : str Source model spec : str Spectral model bkgname : str Background model definition XML file emin : float, optional Minimum energy (TeV) emax : float, optional Maximum energy (TeV) ebins : int, optional Number of energy bins alpha : float, optional Template map scaling factor """ # Load observations obs = gammalib.GObservations(obsname) # Set source models models = set_model(srcmodel, spec, bkgname, alpha=alpha) # Attach models obs.models(models) # Set source model if srcmodel == 'map': if alpha == 1.0: _srcmodel = srcmodel else: _srcmodel = 'map%.2f' % alpha else: _srcmodel = srcmodel # Loop over statistics for statistic in ['wstat', 'cstat']: # Set background model usage if statistic == 'wstat': use_model_bkg = False else: use_model_bkg = True # Loop over joint/stacking for method in ['joint', 'stacked']: # Set stacking flag if method == 'joint': stack = False else: stack = True # Set filenames outobs = 'obs_rx_selected_onoff-%s%2.2d_%s_%s.xml' % \ (method, ebins, statistic, _srcmodel) outmodel = 'model_rx_onoff-%s%2.2d_%s_%s.xml' % \ (method, ebins, statistic, _srcmodel) prefix = 'onoff-%s%2.2d_%s_%s' % \ (method, ebins, statistic, _srcmodel) logfile = 'obs_rx_selected_onoff-%s%2.2d_%s_%s.log' % \ (method, ebins, statistic, _srcmodel) # Continue only if observation definition file does not exist if not os.path.isfile(outobs): # Generate source and background region files create_region_maps() # Setup task parameters csphagen = cscripts.csphagen(obs) csphagen['srcname'] = 'RX J1713.7-3946' csphagen['ebinalg'] = 'LOG' csphagen['emin'] = emin csphagen['emax'] = emax csphagen['enumbins'] = ebins csphagen['coordsys'] = 'CEL' csphagen['stack'] = stack csphagen['use_model_bkg'] = use_model_bkg csphagen['bkgmethod'] = 'CUSTOM' csphagen['bkgregmin'] = 1 csphagen['srcregfile'] = 'rx_srcreg_map.fits' csphagen['bkgregfile'] = 'rx_bkgreg_map.fits' csphagen['etruemin'] = 0.1 csphagen['etruemax'] = 100.0 csphagen['etruebins'] = 300 csphagen['outobs'] = outobs csphagen['outmodel'] = outmodel csphagen['prefix'] = prefix csphagen['logfile'] = logfile csphagen['debug'] = True csphagen['chatter'] = 4 csphagen.logFileOpen() # Generate On/Off data csphagen.execute() # Continue only if model definition file exists if os.path.isfile(outmodel): # If we have a cstat model then set the node values and scales # for all nodes to unity and remove all spectral nodes above # 10 TeV from background model to cope with limited statistics # in case we have a joint fit if statistic == 'cstat': models = gammalib.GModels(outmodel) elim = gammalib.GEnergy(10.0, 'TeV') for model in models: if model.type() == 'CTABackground': nodes = model.spectral() for i in range(nodes.nodes() - 1, -1, -1): if method == 'joint' and nodes.energy( i) > elim: nodes.remove(i) else: nodes[i * 2 + 1].scale(1.0) nodes[i * 2 + 1].value(1.0) models.save(outmodel) # Return return
def grb_simulation(sim_in, config_in, model_xml, fits_header_0, counter): """ Function to handle the GRB simulation. :param sim_in: the yaml file for the simulation (unpacked as a dict of dicts) :param config_in: the yaml file for the job handling (unpacked as a dict of dicts) :param model_xml: the XML model name for the source under analysis :param fits_header_0: header for the fits file of the GRB model to use. Used in the visibility calculation :param counter: integer number. counts the id of the source realization :return: significance obtained with the activated detection methods """ src_name = model_xml.split('/')[-1].split('model_')[1][:-4] print(src_name, counter) ctools_pipe_path = create_path(config_in['exe']['software_path']) ctobss_params = sim_in['ctobssim'] seed = int(counter)*10 # PARAMETERS FROM THE CTOBSSIM sim_t_min = u.Quantity(ctobss_params['time']['t_min']).to_value(u.s) sim_t_max = u.Quantity(ctobss_params['time']['t_max']).to_value(u.s) sim_e_min = u.Quantity(ctobss_params['energy']['e_min']).to_value(u.TeV) sim_e_max = u.Quantity(ctobss_params['energy']['e_max']).to_value(u.TeV) sim_rad = ctobss_params['radius'] models = sim_in['source'] source_type = models['type'] if source_type == "GRB": phase_path = "/" + models['phase'] elif source_type == "GW": phase_path = "" output_path = create_path(sim_in['output']['path'] + phase_path + '/' + src_name) save_simulation = ctobss_params['save_simulation'] with open(f"{output_path}/GRB-{src_name}_seed-{seed}.txt", "w") as f: f.write(f"GRB,seed,time_start,time_end,sigma_lima,sqrt_TS_onoff,sqrt_TS_std\n") # VISIBILITY PART # choose between AUTO mode (use visibility) and MANUAL mode (manually insert IRF) simulation_mode = sim_in['IRF']['mode'] if simulation_mode == "auto": print("using visibility to get IRFs") # GRB information from the fits header ra = fits_header_0['RA'] dec = fits_header_0['DEC'] t0 = Time(fits_header_0['GRBJD']) irf_dict = sim_in['IRF'] site = irf_dict['site'] obs_condition = Observability(site=site) obs_condition.set_irf(irf_dict) t_zero_mode = ctobss_params['time']['t_zero'].lower() if t_zero_mode == "VIS": # check if the source is visible one day after the onset of the source print("time starts when source becomes visible") obs_condition.Proposal_obTime = 86400 condition_check = obs_condition.check(RA=ra, DEC=dec, t_start=t0) elif t_zero_mode == "ONSET": print("time starts from the onset of the GRB") condition_check = obs_condition.check(RA=ra, DEC=dec, t_start=t0, t_min=sim_t_min, t_max=sim_t_max) else: print(f"Choose some proper mode between 'VIS' and 'ONSET'. {t_zero_mode} is not a valid one.") sys.exit() # NO IRF in AUTO mode ==> No simulation! == EXIT! if len(condition_check) == 0: f.write(f"{src_name},{seed}, -1, -1, -1, -1, -1\n") sys.exit() elif simulation_mode == "manual": print("manual picking IRF") # find proper IRF name irf = IRFPicker(sim_in, ctools_pipe_path) name_irf = irf.irf_pick() backgrounds_path = create_path(ctobss_params['bckgrnd_path']) fits_background_list = glob.glob( f"{backgrounds_path}/{irf.prod_number}_{irf.prod_version}_{name_irf}/background*.fits") if len(fits_background_list) == 0: print(f"No background for IRF {name_irf}") sys.exit() fits_background_list = sorted(fits_background_list, key=sort_background) background_fits = fits_background_list[int(counter) - 1] obs_back = gammalib.GCTAObservation(background_fits) else: print(f"wrong input for IRF - mode. Input is {simulation_mode}. Use 'auto' or 'manual' instead") sys.exit() if irf.prod_number == "3b" and irf.prod_version == 0: caldb = "prod3b" else: caldb = f'prod{irf.prod_number}-v{irf.prod_version}' # source simulation sim = ctools.ctobssim() sim['inmodel'] = model_xml sim['caldb'] = caldb sim['irf'] = name_irf sim['ra'] = 0.0 sim['dec'] = 0.0 sim['rad'] = sim_rad sim['tmin'] = sim_t_min sim['tmax'] = sim_t_max sim['emin'] = sim_e_min sim['emax'] = sim_e_max sim['seed'] = seed sim.run() obs = sim.obs() # # move the source photons from closer to (RA,DEC)=(0,0), where the background is located # for event in obs[0].events(): # # ra_evt = event.dir().dir().ra() # dec_evt = event.dir().dir().dec() # ra_evt_deg = event.dir().dir().ra_deg() # dec_evt_deg = event.dir().dir().dec_deg() # # ra_corrected = (ra_evt_deg - ra_pointing)*np.cos(dec_evt) # dec_corrected = dec_evt_deg - dec_pointing # event.dir().dir().radec_deg(ra_corrected, dec_corrected) # append all background events to GRB ones ==> there's just one observation and not two for event in obs_back.events(): obs[0].events().append(event) # ctselect to save data on disk if save_simulation: event_list_path = create_path(f"{ctobss_params['output_path']}/{src_name}/") #obs.save(f"{event_list_path}/event_list_source-{src_name}_seed-{seed:03}.fits") select_time = ctools.ctselect(obs) select_time['rad'] = sim_rad select_time['tmin'] = sim_t_min select_time['tmax'] = sim_t_max select_time['emin'] = sim_e_min select_time['emax'] = sim_e_max select_time['outobs'] = f"{event_list_path}/event_list_source-{src_name}_{seed:03}.fits" select_time.run() sys.exit() # delete all 70+ models from the obs def file...not needed any more obs.models(gammalib.GModels()) # CTSELECT select_time = sim_in['ctselect']['time_cut'] slices = int(select_time['t_slices']) if slices == 0: times = [sim_t_min, sim_t_max] times_start = times[:-1] times_end = times[1:] elif slices > 0: time_mode = select_time['mode'] if time_mode == "log": times = np.logspace(np.log10(sim_t_min), np.log10(sim_t_max), slices + 1, endpoint=True) elif time_mode == "lin": times = np.linspace(sim_t_min, sim_t_max, slices + 1, endpoint=True) else: print(f"{time_mode} not valid. Use 'log' or 'lin' ") sys.exit() if select_time['obs_mode'] == "iter": times_start = times[:-1] times_end = times[1:] elif select_time['obs_mode'] == "cumul": times_start = np.repeat(times[0], slices) # this is to use the same array structure for the loop times_end = times[1:] elif select_time['obs_mode'] == "all": begins, ends = np.meshgrid(times[:-1], times[1:]) mask_times = begins < ends times_start = begins[mask_times].ravel() times_end = ends[mask_times].ravel() else: print(f"obs_mode: {select_time['obs_mode']} not supported") sys.exit() else: print(f"value {slices} not supported...check yaml file") sys.exit() # ------------------------------------ # ----- TIME LOOP STARTS HERE -------- # ------------------------------------ ctlike_mode = sim_in['detection'] mode_1 = ctlike_mode['counts'] mode_2 = ctlike_mode['ctlike-onoff'] mode_3 = ctlike_mode['ctlike-std'] for t_in, t_end in zip(times_start, times_end): sigma_onoff = 0 sqrt_ts_like_onoff = 0 sqrt_ts_like_std = 0 print("-----------------------------") print(f"t_in: {t_in:.2f}, t_end: {t_end:.2f}") # different ctlikes (onoff or std) need different files. # will be appended here and used later on for the final likelihood dict_obs_select_time = {} # perform time selection for this specific time bin select_time = ctools.ctselect(obs) select_time['rad'] = sim_rad select_time['tmin'] = t_in select_time['tmax'] = t_end select_time['emin'] = sim_e_min select_time['emax'] = sim_e_max select_time.run() if mode_1: fits_temp_title = f"skymap_{seed}_{t_in:.2f}_{t_end:.2f}.fits" pars_counts = ctlike_mode['pars_counts'] scale = float(pars_counts['scale']) npix = 2*int(sim_rad/scale) skymap = ctools.ctskymap(select_time.obs().copy()) skymap['emin'] = sim_e_min skymap['emax'] = sim_e_max skymap['nxpix'] = npix skymap['nypix'] = npix skymap['binsz'] = scale skymap['proj'] = 'TAN' skymap['coordsys'] = 'CEL' skymap['xref'] = 0 skymap['yref'] = 0 skymap['bkgsubtract'] = 'RING' skymap['roiradius'] = pars_counts['roiradius'] skymap['inradius'] = pars_counts['inradius'] skymap['outradius'] = pars_counts['outradius'] skymap['iterations'] = pars_counts['iterations'] skymap['threshold'] = pars_counts['threshold'] skymap['outmap'] = fits_temp_title skymap.execute() input_fits = fits.open(fits_temp_title) datain = input_fits[2].data datain[np.isnan(datain)] = 0.0 datain[np.isinf(datain)] = 0.0 sigma_onoff = np.max(datain) os.remove(fits_temp_title) if mode_3: dict_obs_select_time['std'] = select_time.obs().copy() if mode_2: onoff_time_sel = cscripts.csphagen(select_time.obs().copy()) onoff_time_sel['inmodel'] = 'NONE' onoff_time_sel['ebinalg'] = 'LOG' onoff_time_sel['emin'] = sim_e_min onoff_time_sel['emax'] = sim_e_max onoff_time_sel['enumbins'] = 30 onoff_time_sel['coordsys'] = 'CEL' onoff_time_sel['ra'] = 0.0 onoff_time_sel['dec'] = 0.5 onoff_time_sel['rad'] = 0.2 onoff_time_sel['bkgmethod'] = 'REFLECTED' onoff_time_sel['use_model_bkg'] = False onoff_time_sel['stack'] = False onoff_time_sel.run() dict_obs_select_time['onoff'] = onoff_time_sel.obs().copy() del onoff_time_sel # print(f"sigma ON/OFF: {sigma_onoff:.2f}") if mode_2 or mode_3: # Low Energy PL fitting # to be saved in this dict dict_pl_ctlike_out = {} e_min_pl_ctlike = 0.030 e_max_pl_ctlike = 0.080 # simple ctobssim copy and select for ctlike-std select_pl_ctlike = ctools.ctselect(select_time.obs().copy()) select_pl_ctlike['rad'] = 3 select_pl_ctlike['tmin'] = t_in select_pl_ctlike['tmax'] = t_end select_pl_ctlike['emin'] = e_min_pl_ctlike select_pl_ctlike['emax'] = e_max_pl_ctlike select_pl_ctlike.run() # create test source src_dir = gammalib.GSkyDir() src_dir.radec_deg(0, 0.5) spatial = gammalib.GModelSpatialPointSource(src_dir) # create and append source spectral model spectral = gammalib.GModelSpectralPlaw() spectral['Prefactor'].value(5.5e-16) spectral['Prefactor'].scale(1e-16) spectral['Index'].value(-2.6) spectral['Index'].scale(-1.0) spectral['PivotEnergy'].value(50000) spectral['PivotEnergy'].scale(1e3) model_src = gammalib.GModelSky(spatial, spectral) model_src.name('PL_fit_temp') model_src.tscalc(True) spectral_back = gammalib.GModelSpectralPlaw() spectral_back['Prefactor'].value(1.0) spectral_back['Prefactor'].scale(1.0) spectral_back['Index'].value(0) spectral_back['PivotEnergy'].value(300000) spectral_back['PivotEnergy'].scale(1e6) if mode_2: back_model = gammalib.GCTAModelIrfBackground() back_model.instruments('CTAOnOff') back_model.name('Background') back_model.spectral(spectral_back.copy()) onoff_pl_ctlike_lima = cscripts.csphagen(select_pl_ctlike.obs().copy()) onoff_pl_ctlike_lima['inmodel'] = 'NONE' onoff_pl_ctlike_lima['ebinalg'] = 'LOG' onoff_pl_ctlike_lima['emin'] = e_min_pl_ctlike onoff_pl_ctlike_lima['emax'] = e_max_pl_ctlike onoff_pl_ctlike_lima['enumbins'] = 30 onoff_pl_ctlike_lima['coordsys'] = 'CEL' onoff_pl_ctlike_lima['ra'] = 0.0 onoff_pl_ctlike_lima['dec'] = 0.5 onoff_pl_ctlike_lima['rad'] = 0.2 onoff_pl_ctlike_lima['bkgmethod'] = 'REFLECTED' onoff_pl_ctlike_lima['use_model_bkg'] = False onoff_pl_ctlike_lima['stack'] = False onoff_pl_ctlike_lima.run() onoff_pl_ctlike_lima.obs().models(gammalib.GModels()) onoff_pl_ctlike_lima.obs().models().append(model_src.copy()) onoff_pl_ctlike_lima.obs().models().append(back_model.copy()) like_pl = ctools.ctlike(onoff_pl_ctlike_lima.obs()) like_pl['refit'] = True like_pl.run() dict_pl_ctlike_out['onoff'] = like_pl.obs().copy() del onoff_pl_ctlike_lima del like_pl if mode_3: models_ctlike_std = gammalib.GModels() models_ctlike_std.append(model_src.copy()) back_model = gammalib.GCTAModelIrfBackground() back_model.instruments('CTA') back_model.name('Background') back_model.spectral(spectral_back.copy()) models_ctlike_std.append(back_model) # save models xmlmodel_PL_ctlike_std = 'test_model_PL_ctlike_std.xml' models_ctlike_std.save(xmlmodel_PL_ctlike_std) del models_ctlike_std like_pl = ctools.ctlike(select_pl_ctlike.obs().copy()) like_pl['inmodel'] = xmlmodel_PL_ctlike_std like_pl['refit'] = True like_pl.run() dict_pl_ctlike_out['std'] = like_pl.obs().copy() del like_pl del spatial del spectral del model_src del select_pl_ctlike # EXTENDED CTLIKE for key in dict_obs_select_time.keys(): likelihood_pl_out = dict_pl_ctlike_out[key] selected_data = dict_obs_select_time[key] pref_out_pl = likelihood_pl_out.models()[0]['Prefactor'].value() index_out_pl = likelihood_pl_out.models()[0]['Index'].value() pivot_out_pl = likelihood_pl_out.models()[0]['PivotEnergy'].value() expplaw = gammalib.GModelSpectralExpPlaw() expplaw['Prefactor'].value(pref_out_pl) expplaw['Index'].value(index_out_pl) expplaw['PivotEnergy'].value(pivot_out_pl) expplaw['CutoffEnergy'].value(80e3) if key == "onoff": selected_data.models()[0].name(src_name) selected_data.models()[0].tscalc(True) selected_data.models()[0].spectral(expplaw.copy()) like = ctools.ctlike(selected_data) like['refit'] = True like.run() ts = like.obs().models()[0].ts() if ts > 0: sqrt_ts_like_onoff = np.sqrt(like.obs().models()[0].ts()) else: sqrt_ts_like_onoff = 0 del like if key == "std": models_fit_ctlike = gammalib.GModels() # create test source src_dir = gammalib.GSkyDir() src_dir.radec_deg(0, 0.5) spatial = gammalib.GModelSpatialPointSource(src_dir) # append spatial and spectral models model_src = gammalib.GModelSky(spatial, expplaw.copy()) model_src.name('Source_fit') model_src.tscalc(True) models_fit_ctlike.append(model_src) # create and append background back_model = gammalib.GCTAModelIrfBackground() back_model.instruments('CTA') back_model.name('Background') spectral_back = gammalib.GModelSpectralPlaw() spectral_back['Prefactor'].value(1.0) spectral_back['Prefactor'].scale(1.0) spectral_back['Index'].value(0) spectral_back['PivotEnergy'].value(300000) spectral_back['PivotEnergy'].scale(1e6) back_model.spectral(spectral_back) models_fit_ctlike.append(back_model) # save models input_ctlike_xml = "model_GRB_fit_ctlike_in.xml" models_fit_ctlike.save(input_ctlike_xml) del models_fit_ctlike like = ctools.ctlike(selected_data) like['inmodel'] = input_ctlike_xml like['refit'] = True like.run() ts = like.obs().models()[0].ts() if ts > 0: sqrt_ts_like_std = np.sqrt(like.obs().models()[0].ts()) else: sqrt_ts_like_std = 0 del like # E_cut_off = like.obs().models()[0]['CutoffEnergy'].value() # E_cut_off_error = like.obs().models()[0]['CutoffEnergy'].error() # print(f"sqrt(TS) {key}: {np.sqrt(ts_like):.2f}") # print(f"E_cut_off {key}: {E_cut_off:.2f} +- {E_cut_off_error:.2f}") del dict_pl_ctlike_out f.write(f"{src_name},{seed},{t_in:.2f},{t_end:.2f},{sigma_onoff:.2f},{sqrt_ts_like_onoff:.2f},{sqrt_ts_like_std:.2f}\n") del dict_obs_select_time del select_time
def _test_python(self): """ Test csphagen from Python """ # Same test as from command line phagen = cscripts.csphagen() phagen['inobs'] = self._myevents1 phagen['inmodel'] = 'NONE' phagen['caldb'] = self._caldb phagen['irf'] = self._irf phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['coordsys'] = 'CEL' phagen['ra'] = 83.633 phagen['dec'] = 22.0145 phagen['rad'] = 0.2 phagen['stack'] = False phagen['inexclusion'] = self._exclusion phagen['bkgmethod'] = 'REFLECTED' phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['outobs'] = 'csphagen_py1_obs.xml' phagen['outmodel'] = 'csphagen_py1_model.xml' phagen['prefix'] = 'csphagen_py1' phagen['logfile'] = 'csphagen_py1.log' phagen['chatter'] = 1 # Execute script phagen.execute() # Check output self._check_output('csphagen_py1', self._nbins, self._nreg_with_excl) self._check_outobs('csphagen_py1_obs.xml', 1) # Now test without exclusion region phagen = cscripts.csphagen() phagen['inobs'] = self._myevents1 phagen['inmodel'] = 'NONE' phagen['caldb'] = self._caldb phagen['irf'] = self._irf phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['coordsys'] = 'CEL' phagen['ra'] = 83.633 phagen['dec'] = 22.0145 phagen['rad'] = 0.2 phagen['stack'] = False phagen['bkgmethod'] = 'REFLECTED' phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['outobs'] = 'csphagen_py2_obs.xml' phagen['outmodel'] = 'csphagen_py2_model.xml' phagen['prefix'] = 'csphagen_py2' phagen['logfile'] = 'csphagen_py2.log' phagen['chatter'] = 2 # Execute script phagen.execute() # Check output self._check_output('csphagen_py2', self._nbins, self._nreg_wo_excl) self._check_outobs('csphagen_py2_obs.xml', 1) # Test with multiple input observations, no stacking # Create observation container obs = gammalib.GObservations() for s, events in enumerate([self._myevents1, self._myevents2]): run = gammalib.GCTAObservation(events) run.id(str(s + 1)) run.response(self._irf, gammalib.GCaldb('cta', self._caldb)) obs.append(run) # Setup csphagen phagen = cscripts.csphagen(obs) phagen['inmodel'] = 'NONE' phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['coordsys'] = 'CEL' phagen['ra'] = 83.633 phagen['dec'] = 22.0145 phagen['rad'] = 0.2 phagen['stack'] = False phagen['inexclusion'] = self._exclusion phagen['bkgmethod'] = 'REFLECTED' phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['outobs'] = 'csphagen_py3_obs.xml' phagen['outmodel'] = 'csphagen_py3_model.xml' phagen['prefix'] = 'csphagen_py3' phagen['logfile'] = 'csphagen_py3.log' phagen['chatter'] = 3 # Run script phagen.execute() # Check output for s in range(2): self._check_output('csphagen_py3_' + str(s + 1), self._nbins, self._nreg_mul[s]) self._check_outobs('csphagen_py3_obs.xml', 2) # Setup csphagen for test with multiple input observations and stacking phagen = cscripts.csphagen(obs) phagen['inmodel'] = 'NONE' phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['coordsys'] = 'CEL' phagen['ra'] = 83.633 phagen['dec'] = 22.0145 phagen['rad'] = 0.2 phagen['stack'] = True phagen['inexclusion'] = self._exclusion phagen['bkgmethod'] = 'REFLECTED' phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['outobs'] = 'csphagen_py4_obs.xml' phagen['outmodel'] = 'csphagen_py4_model.xml' phagen['prefix'] = 'csphagen_py4' phagen['logfile'] = 'csphagen_py4.log' phagen['chatter'] = 4 # Execute script phagen.execute() # Check output for s in range(2): self._check_output('csphagen_py4_stacked', self._nbins, 0, check_regions=False) self._check_outobs('csphagen_py4_obs.xml', 1) # Setup csphagen for test with custom On and Off regions provided phagen = cscripts.csphagen() phagen['inobs'] = self._myevents1 phagen['inmodel'] = 'NONE' phagen['caldb'] = self._caldb phagen['irf'] = self._irf phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['bkgmethod'] = 'CUSTOM' phagen['srcregfile'] = self._regfile_src phagen['bkgregfile'] = self._regfile_bkg phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['stack'] = False phagen['outobs'] = 'csphagen_py5_obs.xml' phagen['outmodel'] = 'csphagen_py5_model.xml' phagen['prefix'] = 'csphagen_py5' phagen['logfile'] = 'csphagen_py5.log' phagen['chatter'] = 2 # Execute script phagen.execute() # Check output self._check_output('csphagen_py5', self._nbins, self._nreg_bkg_reg) self._check_outobs('csphagen_py5_obs.xml', 1) # Append off regions to observation container for run in obs: run.off_regions(gammalib.GSkyRegions(self._regfile_bkg)) # Setup csphagen for test with multiple input observations and stacking phagen = cscripts.csphagen(obs) phagen['inmodel'] = 'NONE' phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['coordsys'] = 'CEL' phagen['stack'] = True phagen['inexclusion'] = self._exclusion phagen['bkgmethod'] = 'CUSTOM' phagen['srcregfile'] = self._regfile_src phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['outobs'] = 'csphagen_py6_obs.xml' phagen['outmodel'] = 'csphagen_py6_model.xml' phagen['prefix'] = 'csphagen_py6' phagen['logfile'] = 'csphagen_py6.log' phagen['chatter'] = 4 # Execute script phagen.execute() # Check output for s in range(2): self._check_output('csphagen_py6_stacked', self._nbins, 0, check_regions=False) self._check_outobs('csphagen_py6_obs.xml', 1) # Return return
def _test_python(self): """ Test csphagen from Python """ # Same test as from command line phagen = cscripts.csphagen() phagen['inobs'] = self._myevents1 phagen['caldb'] = self._caldb phagen['irf'] = self._irf phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['coordsys'] = 'CEL' phagen['ra'] = 83.633 phagen['dec'] = 22.0145 phagen['rad'] = 0.2 phagen['stack'] = False phagen['inexclusion'] = self._exclusion phagen['bkgmethod'] = 'REFLECTED' phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['outobs'] = 'csphagen_py1.xml' phagen['prefix'] = 'csphagen_py1' phagen['logfile'] = 'csphagen_py1.log' phagen['chatter'] = 1 # Execute script phagen.execute() # Check output self._check_output('csphagen_py1', self._nbins, self._nreg_with_excl) self._check_outobs('csphagen_py1', 1) # Now test without exclusion region phagen = cscripts.csphagen() phagen['inobs'] = self._myevents1 phagen['caldb'] = self._caldb phagen['irf'] = self._irf phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['coordsys'] = 'CEL' phagen['ra'] = 83.633 phagen['dec'] = 22.0145 phagen['rad'] = 0.2 phagen['stack'] = False phagen['bkgmethod'] = 'REFLECTED' phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['outobs'] = 'csphagen_py2.xml' phagen['prefix'] = 'csphagen_py2' phagen['logfile'] = 'csphagen_py2.log' phagen['chatter'] = 2 # Execute script phagen.execute() # Check output self._check_output('csphagen_py2', self._nbins, self._nreg_wo_excl) self._check_outobs('csphagen_py2', 1) # Test with multiple input observations, no stacking # Create observation container obs = gammalib.GObservations() for s, events in enumerate([self._myevents1, self._myevents2]): run = gammalib.GCTAObservation(events) run.id(str(s + 1)) run.response(self._irf, gammalib.GCaldb('cta', self._caldb)) obs.append(run) # Setup csphagen phagen = cscripts.csphagen(obs) phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['coordsys'] = 'CEL' phagen['ra'] = 83.633 phagen['dec'] = 22.0145 phagen['rad'] = 0.2 phagen['stack'] = False phagen['inexclusion'] = self._exclusion phagen['bkgmethod'] = 'REFLECTED' phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['outobs'] = 'csphagen_py3.xml' phagen['prefix'] = 'csphagen_py3' phagen['logfile'] = 'csphagen_py3.log' phagen['chatter'] = 3 # Run script phagen.execute() # Check output for s in range(2): self._check_output('csphagen_py3_' + str(s + 1), self._nbins, self._nreg_mul[s]) self._check_outobs('csphagen_py3', 2) # Setup csphagen for test with multiple input observations and stacking phagen = cscripts.csphagen(obs) phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['coordsys'] = 'CEL' phagen['ra'] = 83.633 phagen['dec'] = 22.0145 phagen['rad'] = 0.2 phagen['stack'] = True phagen['inexclusion'] = self._exclusion phagen['bkgmethod'] = 'REFLECTED' phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['outobs'] = 'csphagen_py4.xml' phagen['prefix'] = 'csphagen_py4' phagen['logfile'] = 'csphagen_py4.log' phagen['chatter'] = 4 # Execute script phagen.execute() # Check output for s in range(2): self._check_output('csphagen_py4_stacked', self._nbins, 0, check_regions=False) self._check_outobs('csphagen_py4', 1) # Setup csphagen for test with custom On and Off regions provided phagen = cscripts.csphagen() phagen['inobs'] = self._myevents1 phagen['caldb'] = self._caldb phagen['irf'] = self._irf phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['bkgmethod'] = 'CUSTOM' phagen['srcregfile'] = self._regfile_src phagen['bkgregfile'] = self._regfile_bkg phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['stack'] = False phagen['outobs'] = 'csphagen_py5.xml' phagen['prefix'] = 'csphagen_py5' phagen['logfile'] = 'csphagen_py5.log' phagen['chatter'] = 2 # Execute script phagen.execute() # Check output self._check_output('csphagen_py5', self._nbins, self._nreg_bkg_reg) self._check_outobs('csphagen_py5', 1) # Append off regions to observation container for run in obs: run.off_regions(gammalib.GSkyRegions(self._regfile_bkg)) # Setup csphagen for test with multiple input observations and stacking phagen = cscripts.csphagen(obs) phagen['ebinalg'] = 'LOG' phagen['emin'] = 0.1 phagen['emax'] = 100.0 phagen['enumbins'] = self._nbins phagen['coordsys'] = 'CEL' phagen['stack'] = True phagen['inexclusion'] = self._exclusion phagen['bkgmethod'] = 'CUSTOM' phagen['srcregfile'] = self._regfile_src phagen['etruemin'] = 0.05 phagen['etruemax'] = 150.0 phagen['etruebins'] = 5 phagen['outobs'] = 'csphagen_py6.xml' phagen['prefix'] = 'csphagen_py6' phagen['logfile'] = 'csphagen_py6.log' phagen['chatter'] = 4 # Execute script phagen.execute() # Check output for s in range(2): self._check_output('csphagen_py6_stacked', self._nbins, 0, check_regions=False) self._check_outobs('csphagen_py6', 1) # Return return
def prepare_onoff(obsname, srcmodel, spec, bkgname, emin=0.70, emax=10.0, ebins=20): """ Prepare On/Off observations Parameters ---------- obsname : str Observation definition XML file srcmodel : str Source model spec : str Spectral model bkgname : str Background model definition XML file emin : float, optional Minimum energy (TeV) emax : float, optional Maximum energy (TeV) ebins : int, optional Number of energy bins """ # Set Txxx value thresmin = emin*1000.0 # Load observations obs = gammalib.GObservations(obsname) # Set source models models = set_model(srcmodel, spec, bkgname) # Attach models obs.models(models) # Loop over statistics for statistic in ['wstat','cstat']: # Set background model usage if statistic == 'wstat': use_model_bkg = False else: use_model_bkg = True # Loop over joint/stacking for method in ['joint','stacked']: # Set stacking flag if method == 'joint': stack = False else: stack = True # Set filenames outobs = 'obs_pks_t%3.3d_selected_onoff-%s%2.2d_%s_%s.xml' % \ (thresmin, method, ebins, statistic, srcmodel) outmodel = 'model_pks_t%3.3d_onoff-%s%2.2d_%s_%s.xml' % \ (thresmin, method, ebins, statistic, srcmodel) prefix = 't%3.3d_onoff-%s%2.2d_%s_%s' % \ (thresmin, method, ebins, statistic, srcmodel) logfile = 'obs_pks_t%3.3d_selected_onoff-%s%2.2d_%s_%s.log' % \ (thresmin, method, ebins, statistic, srcmodel) # Continue only if observation definition file does not exist if not os.path.isfile(outobs): # Setup task parameters csphagen = cscripts.csphagen(obs) csphagen['srcname'] = 'PKS 2155-304' csphagen['ebinalg'] = 'LOG' csphagen['emin'] = emin csphagen['emax'] = emax csphagen['enumbins'] = ebins csphagen['coordsys'] = 'CEL' csphagen['ra'] = 329.71694 csphagen['dec'] = -30.22559 csphagen['rad'] = 0.2 csphagen['stack'] = stack csphagen['use_model_bkg'] = use_model_bkg csphagen['bkgmethod'] = 'REFLECTED' csphagen['etruemin'] = 0.1 csphagen['etruemax'] = 100.0 csphagen['etruebins'] = 300 csphagen['outobs'] = outobs csphagen['outmodel'] = outmodel csphagen['prefix'] = prefix csphagen['logfile'] = logfile csphagen.logFileOpen() # Generate On/Off data csphagen.execute() # Return return
def get_onoff_obs(cls, obs): """ Create On/Off observations container from given observations Parameters ---------- cls : `~ctools.cscript` cscript class obs : `~gammalib.GObservations` Observation container Returns ------- onoff_obs : `~gammalib.GObservations` Observation container with On/Off observations """ # Write header if cls._logExplicit(): cls._log.header3('Creating On/Off observations') # Create On/Off observations phagen = cscripts.csphagen(obs) phagen['inexclusion'] = cls['inexclusion'].value() phagen['emin'] = cls['emin'].real() phagen['emax'] = cls['emax'].real() phagen['enumbins'] = cls['enumbins'].integer() phagen['ebinalg'] = 'LOG' phagen['srcshape'] = cls['srcshape'].string() phagen['coordsys'] = cls['coordsys'].string() if cls['coordsys'].string() == 'CEL': phagen['ra'] = cls['xref'].real() phagen['dec'] = cls['yref'].real() elif cls['coordsys'].string() == 'GAL': phagen['glon'] = cls['xref'].real() phagen['glat'] = cls['yref'].real() if cls['srcshape'].string() == 'CIRCLE': phagen['rad'] = cls['rad'].real() phagen['bkgmethod'] = cls['bkgmethod'].string() if cls['bkgmethod'].string() == 'REFLECTED': phagen['bkgregmin'] = cls['bkgregmin'].integer() phagen['maxoffset'] = cls['maxoffset'].real() phagen['stack'] = True phagen['etruemin'] = cls['etruemin'].real() phagen['etruemax'] = cls['etruemax'].real() phagen['etruebins'] = cls['etruebins'].integer() phagen['chatter'] = cls['chatter'].integer() phagen['clobber'] = cls['clobber'].boolean() phagen['debug'] = cls['debug'].boolean() phagen.run() # Clone resulting observation container onoff_obs = phagen.obs().copy() # On/Off observations are created with CSTAT as default statistic # We will change this to the user choice if cls['statistic'].string() == 'DEFAULT': pass else: for observation in onoff_obs: observation.statistic(cls['statistic'].string()) # Return On/Off oberservation container return onoff_obs
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 csphagen_run(self, input_obs_list, input_model=None, source_rad=0.2, energy=[None, None], output_obs_list='onoff_obs.xml', output_model='onoff_result.xml', log_file='csphagen.log', prefix='onoff', ebinalg="LIN", enumbins=1, stacked=False, force=False, save=False): phagen = cscripts.csphagen() if isinstance(input_obs_list, gammalib.GObservations): phagen.obs(input_obs_list) if input_model is not None: phagen.obs().models(input_model) elif os.path.isfile(input_obs_list): # observations list from file phagen["inobs"] = input_obs_list phagen["inmodel"] = input_model else: raise Exception('Cannot understand input obs list for csphagen') phagen["srcname"] = self.name phagen["caldb"] = self.caldb phagen["irf"] = self.irf phagen["ebinalg"] = ebinalg phagen["emin"] = energy[0] if energy[0] else self.energy_min phagen["emax"] = energy[1] if energy[1] else self.energy_max phagen["enumbins"] = enumbins phagen["coordsys"] = "CEL" phagen["ra"] = self.ra phagen["dec"] = self.dec phagen["rad"] = source_rad phagen["stack"] = stacked phagen["bkgmethod"] = "REFLECTED" phagen["outobs"] = output_obs_list phagen["outmodel"] = output_model phagen["prefix"] = prefix phagen["logfile"] = log_file phagen["nthreads"] = self.nthreads if force or not os.path.isfile(output_obs_list) or not os.path.isfile( output_model): phagen.logFileOpen() phagen.run() elif os.path.isfile(output_obs_list) and os.path.isfile(output_model): onoff_obs = gammalib.GObservations(output_obs_list) onoff_obs.models(gammalib.GModels(output_model)) phagen = cscripts.csphagen(onoff_obs) else: raise Exception("Cannot proceed with csphagen") saved = False if (save and force) or (save and not os.path.isfile(output_obs_list)) or ( save and not os.path.isfile(output_model)): phagen.save() saved = True logger.info("Files {}, {} created.".format(output_obs_list, output_model)) return phagen
# Now, if the user request to generate an OnOff observation # we use csphagen to handle this if args.is_onoff: print( "\t\tStarting calculation of On-Off files using csphagen app") onoffname = auxMan.createname( args.outpath , \ '{:s}OnOffObs.xml'.format( thisrunID ) ) onoffmodelname = auxMan.createname( args.outpath ,\ '{:s}OnOffModel.xml'.format( thisrunID ) ) prefix = os.path.join( args.outpath ,\ '{:s}OnOff'.format( thisrunID ) ) onoffgen = cscripts.csphagen() onoffgen['inobs'] = obsname onoffgen['inmodel'] = args.inmodel onoffgen['srcname'] = args.gname onoffgen['caldb'] = args.caldb onoffgen['irf'] = args.irf onoffgen['outobs'] = onoffname onoffgen['outmodel'] = onoffmodelname onoffgen['ebinalg'] = 'LOG' onoffgen['emin'] = args.emin onoffgen['emax'] = args.emax onoffgen['enumbins'] = args.enumbins onoffgen['coordsys'] = 'CEL' onoffgen['ra'] = args.ROIra onoffgen['dec'] = args.ROIdec
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 prepare_onoff(obsname, inmodel, srcmodel, spec, bkgname, rad=0.2, emin=0.381, emax=40.0, ebins=40): """ Prepare On/Off observations Parameters ---------- obsname : str Observation definition XML file inmodel : str Input model definition XML file srcmodel : str Source model spec : str Spectral model bkgname : str Background model definition XML file rad : float, optional Selection radius (deg) emin : float, optional Minimum energy (TeV) emax : float, optional Maximum energy (TeV) ebins : int, optional Number of energy bins """ # Load observations obs = gammalib.GObservations(obsname) # Load model models = gammalib.GModels(inmodel) # Attach models obs.models(models) # Set radius string radstr = '_%.2f' % rad # Loop over statistics for statistic in ['wstat', 'cstat']: # Set background model usage if statistic == 'wstat': use_model_bkg = False else: use_model_bkg = True # Loop over joint/stacking for method in ['joint', 'stacked']: # Set stacking flag if method == 'joint': stack = False else: stack = True # Set filenames outobs = 'obs_msh_selected_onoff-%s%2.2d_%s_%s%s.xml' % \ (method, ebins, statistic, srcmodel, radstr) outmodel = 'model_msh_onoff-%s%2.2d_%s_%s%s.xml' % \ (method, ebins, statistic, srcmodel, radstr) prefix = 'onoff-%s%2.2d_%s_%s%s' % \ (method, ebins, statistic, srcmodel, radstr) logfile = 'obs_msh_selected_onoff-%s%2.2d_%s_%s%s.log' % \ (method, ebins, statistic, srcmodel, radstr) # Continue only if observation definition file does not exist if not os.path.isfile(outobs): # Setup task parameters csphagen = cscripts.csphagen(obs) csphagen['srcname'] = 'MSH 15-52' csphagen['ebinalg'] = 'LOG' csphagen['emin'] = emin csphagen['emax'] = emax csphagen['enumbins'] = ebins csphagen['coordsys'] = 'CEL' csphagen['ra'] = 228.547 csphagen['dec'] = -59.174 csphagen['rad'] = rad csphagen['stack'] = stack csphagen['use_model_bkg'] = use_model_bkg csphagen['bkgmethod'] = 'REFLECTED' csphagen['bkgregmin'] = 2 csphagen['bkgregskip'] = 1 csphagen['etruemin'] = 0.1 csphagen['etruemax'] = 100.0 csphagen['etruebins'] = 300 csphagen['outobs'] = outobs csphagen['outmodel'] = outmodel csphagen['prefix'] = prefix csphagen['logfile'] = logfile csphagen.logFileOpen() # Generate On/Off data csphagen.execute() # Continue only if model definition file exists if os.path.isfile(outmodel): # If we have a cstat model then set the node values and scales # for all nodes to unity and remove all spectral nodes above # 6 TeV from background model to cope with limited statistics # in case we have a joint fit if statistic == 'cstat': models = gammalib.GModels(outmodel) elim = gammalib.GEnergy(6.0, 'TeV') for model in models: if model.type() == 'CTABackground': nodes = model.spectral() for i in range(nodes.nodes() - 1, -1, -1): if method == 'joint' and nodes.energy( i) > elim: nodes.remove(i) else: nodes[i * 2 + 1].scale(1.0) nodes[i * 2 + 1].value(1.0) models.save(outmodel) # Return return