def _iact_background(self, telescope, obs_id, bkg_scale, bkgtype, emin=0.01, emax=100): # handle IrfBackground if bkgtype == 'irf': prefactor = 1.0 index = 0.0 prefactor *= bkg_scale spec = self._background_spectrum(obs_id, prefactor, index, emin, emax) # Create background model instance bck = gammalib.GCTAModelIrfBackground(spec) # Set AeffBackground elif bkgtype == 'aeff': prefactor = bkg_scale * self._bkg_aeff_norm spec = self._background_spectrum(obs_id, prefactor, self._bkg_aeff_index, emin, emax) # Create background model instance bck = gammalib.GCTAModelAeffBackground(spec) # Set Gaussian Background elif bkgtype == 'gauss': prefactor = bkg_scale * self._bkg_gauss_norm spec = self._background_spectrum(obs_id, prefactor, self._bkg_gauss_index, emin, emax) radial = gammalib.GCTAModelRadialGauss(self._bkg_gauss_sigma) bck = gammalib.GCTAModelRadialAcceptance(radial, spec) else: msg = 'Background type "' + self._bkgtype + '" unsupported' raise RuntimeError(msg) # Copy model model = bck.clone() # Assign specific run id model.ids(str(obs_id)) # Assign instrument model.instruments(telescope) # Set name (arbitrary) model.name('bkg_' + str(obs_id)) # Turn off TS calculation for background model model.tscalc(False) # Return model return model
def _set_bkg(self, modeltype): """ Set background model Parameters ---------- modeltype : str Model type ('IRF', 'AEFF', 'CUBE' or 'RACC') Returns ------- model : `~gammalib.GModelData()` Background model """ # Pivot energy epivot = gammalib.GEnergy(1.0, 'TeV') # Set background model if modeltype == 'IRF': spectral = gammalib.GModelSpectralPlaw(1.0, 0.0, epivot) model = gammalib.GCTAModelIrfBackground(spectral) elif modeltype == 'AEFF': spectral = gammalib.GModelSpectralPlaw(1.0e-13, -2.5, epivot) model = gammalib.GCTAModelAeffBackground(spectral) elif modeltype == 'CUBE': spectral = gammalib.GModelSpectralPlaw(1.0, 0.0, epivot) model = gammalib.GCTAModelCubeBackground(spectral) elif modeltype == 'RACC': radial = gammalib.GCTAModelRadialGauss(3.0) spectral = gammalib.GModelSpectralPlaw(1.0e-4, -2.5, epivot) model = gammalib.GCTAModelRadialAcceptance(radial, spectral) else: model = None # Set background name if model is not None: model.name('Background') # Return model return model
def _generate_initial_model(self, sigma_min=2.0, sigma_max=1000.0): """ Generate initial background model Parameters ---------- sigma_min : float, optional Minimum sigma sigma_max : float, optional Maximum sigma Returns ------- model : `~gammalib.GModelData()` Background model """ # Handle IRF model if self['spatial'].string() == 'IRF': epivot = gammalib.GEnergy(1.0, 'TeV') spectral = gammalib.GModelSpectralPlaw(1.0, 0.0, epivot) model = gammalib.GCTAModelIrfBackground(spectral) # Handle AEFF model elif self['spatial'].string() == 'AEFF': epivot = gammalib.GEnergy(1.0, 'TeV') spectral = gammalib.GModelSpectralPlaw(1.0e-13, -2.5, epivot) model = gammalib.GCTAModelAeffBackground(spectral) # Handle other models else: # Handle LOOKUP model if self['spatial'].string() == 'LOOKUP': # Set spatial model factor1 = gammalib.GCTAModelSpatialLookup( self['slufile'].filename()) # Handle GAUSS model elif self['spatial'].string() == 'GAUSS': # Set spatial model factor1 = gammalib.GCTAModelRadialGauss(3.0) factor1['Sigma'].min(sigma_min) factor1['Sigma'].max(sigma_max) # Handle GAUSS(E) model elif self['spatial'].string() == 'GAUSS(E)': # Set spatial model. If a single energy bin is specified then # use the GAUSS model. Otherwise allocate a node spectrum for # the energy nodes of GAUSS(E). if self['snumbins'].integer() == 1: factor1 = gammalib.GCTAModelRadialGauss(3.0) factor1['Sigma'].min(sigma_min) factor1['Sigma'].max(sigma_max) else: emin = gammalib.GEnergy(self['smin'].real(), 'TeV') emax = gammalib.GEnergy(self['smax'].real(), 'TeV') energies = gammalib.GEnergies(self['snumbins'].integer(), emin, emax) spectrum = gammalib.GModelSpectralConst(3.0) nodes = gammalib.GModelSpectralNodes(spectrum, energies) for i in range(nodes.nodes()): nodes[i * 2 + 1].min(sigma_min) nodes[i * 2 + 1].max(sigma_max) nodes.autoscale() factor1 = gammalib.GCTAModelSpatialGaussSpectrum(nodes) # Handle PROFILE model elif self['spatial'].string() == 'PROFILE': # Set spatial model factor1 = gammalib.GCTAModelRadialProfile(2.0, 4.0, 5.0) factor1['Width'].min(1.0) factor1['Width'].max(10.0) factor1['Core'].min(1.0) factor1['Core'].max(10.0) factor1['Tail'].min(1.0) factor1['Tail'].max(10.0) factor1['Tail'].free() # Handle POLYNOM model elif self['spatial'].string() == 'POLYNOM': # Set spatial model factor1 = gammalib.GCTAModelRadialPolynom([1.0, -0.1, +0.1]) factor1['Coeff0'].min(0.1) factor1['Coeff0'].max(10.0) factor1['Coeff0'].fix() factor1['Coeff1'].min(-10.0) factor1['Coeff1'].max(10.0) factor1['Coeff2'].min(-10.0) factor1['Coeff2'].max(10.0) # Any other strings (should never occur) else: model = None # Optionally add gradient if self['gradient'].boolean(): spatial = gammalib.GCTAModelSpatialMultiplicative() factor2 = gammalib.GCTAModelSpatialGradient() spatial.append(factor1) spatial.append(factor2) else: spatial = factor1 # Set spectral model epivot = gammalib.GEnergy(1.0, 'TeV') spectral = gammalib.GModelSpectralPlaw(3.0e-4, -1.5, epivot) spectral['Prefactor'].min(1.0e-8) # Set background model model = gammalib.GCTAModelBackground(spatial, spectral) # Set background name and instrument if model is not None: model.name('Background') model.instruments(self._instrument) # Return model return model
def background(model_tot, bkg_dict_in, setID=True): """ Build a ctools model for the background. Parameters ---------- - model_tot: a gammalib.GModels object - bkg_dict (dictionary): the dictionary that contain the background properties (from class Background). In case of multiple background this can be a list. - setID (bool): decide to set or not an ID in the bkg model Outputs -------- - the model is updated to include the background """ #---------- Get the number of background if type(bkg_dict_in) == list: Nbkg = len(bkg_dict_in) else: Nbkg = 1 #---------- Add all bkg models for i in range(Nbkg): #---------- Select the background from the list or not if type(bkg_dict_in) == list: bkg_dict = bkg_dict_in[i] else: bkg_dict = bkg_dict_in #----- Spectral model # PowerLaw if bkg_dict.spectral['type'] == 'PowerLaw': prefact = bkg_dict.spectral['param']['Prefactor']['value'] index = bkg_dict.spectral['param']['Index']['value'] pivot = gammalib.GEnergy( bkg_dict.spectral['param']['PivotEnergy']['value'].to_value( 'TeV'), 'TeV') spectral = gammalib.GModelSpectralPlaw(prefact, index, pivot) # PowerLawExpCutoff elif bkg_dict.spectral['type'] == 'PowerLawExpCutoff': prefact = bkg_dict.spectral['param']['Prefactor']['value'] index = bkg_dict.spectral['param']['Index']['value'] pivot = gammalib.GEnergy( bkg_dict.spectral['param']['PivotEnergy']['value'].to_value( 'TeV'), 'TeV') cutoff = gammalib.GEnergy( bkg_dict.spectral['param']['Cutoff']['value'].to_value('TeV'), 'TeV') spectral = gammalib.GModelSpectralExpPlaw(prefact, index, pivot, cutoff) # Error else: raise ValueError('Spectral model not available') # Parameter management spectral = manage_parameters(bkg_dict.spectral['param'], spectral) #----- Spatial model # CTAIrfBackground if bkg_dict.spatial['type'] == 'CTAIrfBackground': #----- Overal model for each source model = gammalib.GCTAModelIrfBackground(spectral) # Error else: raise ValueError('Spatial model not avaiable') #----- Append model model.name(bkg_dict.name) model.instruments(bkg_dict.instrument) if setID: if bkg_dict.obsid is not None: model.ids(bkg_dict.obsid) model_tot.append(model)
shutil.copy(filepath + filename, './') # replace file with the one in output directory model.spatial(gammalib.GModelSpatialDiffuseMap(filename)) # append model to container models.append(model) ncomp += 1 msg = 'Added {} interstellar emission components\n'.format(ncomp) print(msg) outfile.write(msg) # add CTA background # power law spectral correction with pivot energy at 1 TeV spectral = gammalib.GModelSpectralPlaw(1, 0, gammalib.GEnergy(1, 'TeV')) # Irf Background bkgmodel = gammalib.GCTAModelIrfBackground(spectral) bkgmodel.name('Background') bkgmodel.instruments('CTA') # append to models models.append(bkgmodel) print('Added background model') outfile.write('Added background model\n') # save models models.save('models_gps.xml') # close report file outfile.close() # save diagnostic plots ax1.legend(fontsize=5)
def gw_simulation(sim_in, config_in, model_xml, fits_model, counter): """ :param sim_in: :param config_in: :param model_xml: :param fits_model: :param counter: :return: """ src_name = fits_model.split("/")[-1][:-5] run_id, merger_id = src_name.split('_') fits_header_0 = fits.open(fits_model)[0].header ra_src = fits_header_0['RA'] dec_src = fits_header_0['DEC'] coordinate_source = SkyCoord(ra=ra_src * u.deg, dec=dec_src * u.deg, frame="icrs") src_yaml = sim_in['source'] point_path = create_path(src_yaml['pointings_path']) opt_point_path = f"{point_path}/optimized_pointings" ctools_pipe_path = create_path(config_in['exe']['software_path']) ctobss_params = sim_in['ctobssim'] seed = int(counter)*10 # # PARAMETERS FROM THE CTOBSSIM 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'] output_path = create_path(sim_in['output']['path'] + f"/{src_name}/seed-{seed:03}") irf_dict = sim_in['IRF'] site = irf_dict['site'] detection = sim_in['detection'] significance_map = detection['skymap_significance'] srcdetect_ctlike = detection['srcdetect_likelihood'] save_simulation = ctobss_params['save_simulation'] try: mergers_data = pd.read_csv( f"{point_path}/BNS-GW-Time_onAxis5deg.txt", sep=" ") except FileNotFoundError: print("merger data not present. check that the text file with the correct pointings is in the 'pointings' folder!") sys.exit() filter_mask = (mergers_data["run"] == run_id) & (mergers_data["MergerID"] == f"Merger{merger_id}") merger_onset_data = mergers_data[filter_mask] time_onset_merger = merger_onset_data['Time'].values[0] with open(f"{output_path}/GW-{src_name}_seed-{seed:03}_site-{site}.txt", "w") as f: f.write(f"GW_name\tRA_src\tDEC_src\tseed\tpointing_id\tsrc_to_point\tsrc_in_point\tra_point\tdec_point\tradius\ttime_start\ttime_end\tsignificanceskymap\tsigmasrcdetectctlike\n") try: file_name = f"{opt_point_path}/{run_id}_Merger{merger_id}_GWOptimisation_v3.txt" pointing_data = pd.read_csv( file_name, header=0, sep=",") except FileNotFoundError: print("File not found\n") sys.exit() RA_data = pointing_data['RA(deg)'] DEC_data = pointing_data['DEC(deg)'] times = pointing_data['Observation Time UTC'] durations = pointing_data['Duration'] # LOOP OVER POINTINGS for index in range(0, len(pointing_data)): RA_point = RA_data[index] DEC_point = DEC_data[index] coordinate_pointing = SkyCoord( ra=RA_point * u.degree, dec=DEC_point * u.degree, frame="icrs" ) src_from_pointing = coordinate_pointing.separation(coordinate_source) t_in_point = Time(times[index]) obs_condition = Observability(site=site) obs_condition.set_irf(irf_dict) obs_condition.Proposal_obTime = 10 obs_condition.TimeOffset = 0 obs_condition.Steps_observability = 10 condition_check = obs_condition.check(RA=RA_point, DEC=DEC_point, t_start=t_in_point) # once the IRF has been chosen, the times are shifted # this is a quick and dirty solution to handle the times in ctools...not elegant for sure t_in_point = (Time(times[index]) - Time(time_onset_merger)).to(u.s) t_end_point = t_in_point + durations[index] * u.s if len(condition_check) == 0: print(f"Source Not Visible in pointing {index}") f.write( f"{src_name}\t{ra_src}\t{dec_src}\t{seed}\t{index}\t{src_from_pointing.value:.2f}\t{src_from_pointing.value < sim_rad}\t{RA_point}\t{DEC_point}\t{sim_rad}\t{t_in_point.value:.2f}\t{t_end_point.value:.2f}\t -1 \t -1\n") continue name_irf = condition_check['IRF_name'][0] irf = condition_check['IRF'][0] # model loading if irf.prod_number == "3b" and irf.prod_version == 0: caldb = "prod3b" else: caldb = f'prod{irf.prod_number}-v{irf.prod_version}' # simulation sim = ctools.ctobssim() sim['inmodel'] = model_xml sim['caldb'] = caldb sim['irf'] = name_irf sim['ra'] = RA_point sim['dec'] = DEC_point sim['rad'] = sim_rad sim['tmin'] = t_in_point.value sim['tmax'] = t_end_point.value sim['emin'] = sim_e_min sim['emax'] = sim_e_max sim['seed'] = seed if save_simulation: event_list_path = create_path(f"{ctobss_params['output_path']}/{src_name}/seed-{seed:03}/") sim['outevents'] = f"{event_list_path}/event_list_source-{src_name}_seed-{seed:03}_pointingID-{index}.fits" sim.execute() f.write( f"{src_name}\t{ra_src}\t{dec_src}\t{seed}\t{index}\t{src_from_pointing.value:.2f}\t{src_from_pointing.value < sim_rad}\t{RA_point}\t{DEC_point}\t{sim_rad}\t{t_in_point.value:.2f}\t{t_end_point.value:.2f}\t -1 \t -1\n" ) continue else: sim.run() obs = sim.obs() obs.models(gammalib.GModels()) # ctskymap sigma_onoff = -1 sqrt_ts_like = -1 if significance_map: pars_skymap = detection['parameters_skymap'] scale = float(pars_skymap['scale']) npix = 2 * int(sim_rad / scale) fits_temp_title = f"{output_path}/GW-skymap_point-{index}_{seed}.fits" skymap = ctools.ctskymap(obs.copy()) skymap['proj'] = 'CAR' skymap['coordsys'] = 'CEL' skymap['xref'] = RA_point skymap['yref'] = DEC_point skymap['binsz'] = scale skymap['nxpix'] = npix skymap['nypix'] = npix skymap['emin'] = sim_e_min skymap['emax'] = sim_e_max skymap['bkgsubtract'] = 'RING' skymap['roiradius'] = pars_skymap['roiradius'] skymap['inradius'] = pars_skymap['inradius'] skymap['outradius'] = pars_skymap['outradius'] skymap['iterations'] = pars_skymap['iterations'] skymap['threshold'] = pars_skymap['threshold'] skymap['outmap'] = fits_temp_title skymap.execute() input_fits = fits.open(fits_temp_title) datain = input_fits['SIGNIFICANCE'].data datain[np.isnan(datain)] = 0.0 datain[np.isinf(datain)] = 0.0 sigma_onoff = np.max(datain) if pars_skymap['remove_fits']: os.remove(fits_temp_title) if srcdetect_ctlike: pars_detect = detection['parameters_detect'] scale = float(pars_detect['scale']) npix = 2 * int(sim_rad / scale) skymap = ctools.ctskymap(obs.copy()) skymap['proj'] = 'TAN' skymap['coordsys'] = 'CEL' skymap['xref'] = RA_point skymap['yref'] = DEC_point skymap['binsz'] = scale skymap['nxpix'] = npix skymap['nypix'] = npix skymap['emin'] = sim_e_min skymap['emax'] = sim_e_max skymap['bkgsubtract'] = 'NONE' skymap.run() # cssrcdetect srcdetect = cscripts.cssrcdetect(skymap.skymap().copy()) srcdetect['srcmodel'] = 'POINT' srcdetect['bkgmodel'] = 'NONE' srcdetect['corr_kern'] = 'GAUSSIAN' srcdetect['threshold'] = pars_detect['threshold'] srcdetect['corr_rad'] = pars_detect['correlation'] srcdetect.run() models = srcdetect.models() # if there's some detection we can do the likelihood. # Spectral model is a PL and the spatial model is the one from cssrcdetect if len(models) > 0: hotspot = models['Src001'] ra_hotspot = hotspot['RA'].value() dec_hotspot = hotspot['DEC'].value() models_ctlike = gammalib.GModels() src_dir = gammalib.GSkyDir() src_dir.radec_deg(ra_hotspot, dec_hotspot) spatial = gammalib.GModelSpatialPointSource(src_dir) 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_GW') model_src.tscalc(True) models_ctlike.append(model_src) 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 = gammalib.GCTAModelIrfBackground() back_model.instruments('CTA') back_model.name('Background') back_model.spectral(spectral_back.copy()) models_ctlike.append(back_model) xmlmodel_PL_ctlike_std = f"{output_path}/model_PL_ctlike_std_seed-{seed}_pointing-{index}.xml" models_ctlike.save(xmlmodel_PL_ctlike_std) like_pl = ctools.ctlike(obs.copy()) like_pl['inmodel'] = xmlmodel_PL_ctlike_std like_pl['caldb'] = caldb like_pl['irf'] = name_irf like_pl.run() ts = -like_pl.obs().models()[0].ts() if ts > 0: sqrt_ts_like = np.sqrt(ts) else: sqrt_ts_like = 0 if pars_detect['remove_xml']: os.remove(xmlmodel_PL_ctlike_std) f.write( f"{src_name}\t{ra_src}\t{dec_src}\t{seed}\t{index}\t{src_from_pointing.value:.2f}\t{src_from_pointing.value < sim_rad}\t{RA_point:.2f}\t{DEC_point:.2f}\t{sim_rad}\t{t_in_point:.2f}\t{t_end_point:.2f}\t{sigma_onoff:.2f}\t{sqrt_ts_like}\n")
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 _iact_background(self, telescope, obs_id, bkg_scale, bkgtype, emin=0.01, emax=100): """ Create an IACT background model Parameters ---------- telescope : str Name of telescope obs_id : str Observation ID bkg_scale : float Background scaling factor bkgtype : str Type of background (irf,aeff, or gauss) Returns ------- model : `~gammalib.GModelData()` Background model for IACT observation """ # Handle IrfBackground if bkgtype == 'irf': # Set parameters to have a constant spectral model prefactor = 1.0 index = 0.0 prefactor *= bkg_scale # Create background spectrum spec = self._background_spectrum(prefactor, index, emin, emax) # Create background model bck = gammalib.GCTAModelIrfBackground(spec) # Set AeffBackground elif bkgtype == 'aeff': # Set background components prefactor = bkg_scale * self._bkg_aeff_norm spec = self._background_spectrum(prefactor, self._bkg_aeff_index, emin, emax) # Create background model bck = gammalib.GCTAModelAeffBackground(spec) # Set Gaussian Background elif bkgtype == 'gauss': # Set background components prefactor = bkg_scale * self._bkg_gauss_norm spec = self._background_spectrum(prefactor, self._bkg_gauss_index, emin, emax) radial = gammalib.GCTAModelRadialGauss(self._bkg_gauss_sigma) # Create background model bck = gammalib.GCTAModelRadialAcceptance(radial, spec) else: msg = 'Background type "' + bkgtype + '" unsupported' raise RuntimeError(msg) # Copy model model = bck.clone() # Assign specific run id model.ids(str(obs_id)) # Assign instrument model.instruments(telescope) # Set name (arbitrary) model.name('bkg_' + str(obs_id)) # Turn off TS calculation for background model model.tscalc(False) # Return model return model