def get_config(infile, configspec=join(CONFIG_DIR, 'default.conf')): """Parse config file, and in addition: - include default options - exit with an error if a required option is missing""" config = ConfigObj(infile, configspec=configspec, file_error=True) validator = Validator() # @todo: I'm not sure we always want to copy all default options here results = config.validate(validator, copy=True) mes = Loggin.Message() utils.Checkevtclass(config['event']['evclass']) if results != True: for (section_list, key, _) in flatten_errors(config, results): if key is not None: mes.warning( 'The "%s" key in the section "%s" failed validation' % (key, ', '.join(section_list))) else: mes.warning('The following section was missing:%s ' % ', '.join(section_list)) mes.warning(' Please check your config file for missing ' 'and wrong options!') mes.error('Config file is not valid.') return config
def GetIRFS(evtclass, evttype): from enrico import Loggin mes = Loggin.Message() classirfs = { 1: "P8R2_TRANSIENT100A", 2: "P8R2_TRANSIENT100E", 4: "P8R2_TRANSIENT100", 8: "P8R2_TRANSIENT020E", 16: "P8R2_TRANSIENT020", 32: "P8R2_TRANSIENT010E", 64: "P8R2_TRANSIENT010", 128: "P8R2_SOURCE", 256: "P8R2_CLEAN", 521: "P8R2_ULTRACLEAN", 1024: "P8R2_ULTRACLEANVETO", 32768: "P8R2_TRANSIENT100S", 65536: "P8R2_TRANSIENT015S", 16777216: "P8R2_LLE" } result = [] val = evttype while val > 0: deno = GetSDC(val) result.append(2**deno) val = val - result[-1] typ = [] for t in result: typ.append(typeirfs[t]) classirf = classirfs[evtclass] + "_V6" #mes.info("Using IRFS for: class %s and type %s" %(str(classirf),str(typ))) return classirf, typ
def Print(indices,config,ra,dec,proba,energy,time): mes = Loggin.Message() mes.info("Energy\tAngular Sep\tProba\tTime") mes.info("[MeV] \t[Degrees]") for i in xrange(min(config['srcprob']['numberPhoton'],indices.size)): angSep = calcAngSepDeg(config['target']["ra"],config['target']["dec"],ra[indices[indices.size-1-i]],dec[indices[indices.size-1-i]]) print "%2.3e\t%2.3f\t\t%2.5f\t%2.1f"%(energy[indices[indices.size-1-i]],angSep,proba[indices[indices.size-1-i]],time[indices[indices.size-1-i]])
def Runsrcprob(config): config['space']['rad'] = config['srcprob']['rad'] Obs = Observation(config['out'], config, tag="srcprob") _log("Summary") Obs.printSum() if config['srcprob']['FitsGeneration'] =='yes': _log("Select data") Obs.FirstCut() if config['analysis']['ComputeDiffrsp'] == 'yes': _log("Compute diffuse responses") Obs.DiffResps() _log("Run gtsrcprob") Obs.SrcProb() probfile=fits.open(Obs.Probfile) srclist = open(config['srcprob']['srclist'],"r").readlines() for src in srclist: proba = probfile[1].data.field(string.split(src)[0]) energy = probfile[1].data.field("ENERGY") ra = probfile[1].data.field("RA") dec = probfile[1].data.field("DEC") time = probfile[1].data.field("TIME") indices = energy.argsort() mes = Loggin.Message() mes.info( "Results sorted by decreasing energy") Print(indices,config,ra,dec,proba,energy,time) print mes.info( "Results sorted by decreasing probability") indices = proba.argsort() Print(indices,config,ra,dec,proba,energy,time)
def GetIRFS(evtclass, evttype, addversion=True): from enrico import Loggin mes = Loggin.Message() classirfs = { 1: "P8R3_TRANSIENT100A", 2: "P8R3_TRANSIENT100E", 4: "P8R3_TRANSIENT100", 8: "P8R3_TRANSIENT020E", 16: "P8R3_TRANSIENT020", 32: "P8R3_TRANSIENT010E", 64: "P8R3_TRANSIENT010", 128: "P8R3_SOURCE", 256: "P8R3_CLEAN", 521: "P8R3_ULTRACLEAN", 1024: "P8R3_ULTRACLEANVETO", 32768: "P8R3_TRANSIENT100S", 65536: "P8R3_TRANSIENT015S", 16777216: "P8R3_LLE" } result = [] val = evttype while val > 0: deno = GetSDC(val) result.append(2**deno) val = val - result[-1] typ = [] for t in result: typ.append(typeirfs[t]) # P8R3_SOURCE_V2 is the irf, but iso_P8R3_SOURCE_V2_()_V2.txt does not exist, # instead it is _V6_()_V2.txt. We need to get around this inconsistency. if (addversion): classirf = classirfs[evtclass] + "_V2" else: classirf = classirfs[evtclass] #mes.info("Using IRFS for: class %s and type %s" %(str(classirf),str(typ))) return classirf, typ
def Checkevtclass(evclass): classirfs = { 1: "P8R2_TRANSIENT100A", 2: "P8R2_TRANSIENT100E", 4: "P8R2_TRANSIENT100", 8: "P8R2_TRANSIENT020E", 16: "P8R2_TRANSIENT020", 32: "P8R2_TRANSIENT010E", 64: "P8R2_TRANSIENT010", 128: "P8R2_SOURCE", 256: "P8R2_CLEAN", 521: "P8R2_ULTRACLEAN", 1024: "P8R2_ULTRACLEANVETO", 32768: "P8R2_TRANSIENT100S", 65536: "P8R2_TRANSIENT015S", 16777216: "P8R2_LLE" } try: tmp = classirfs[evclass] except: from enrico import Loggin mes = Loggin.Message() mes.error("evclass value in config file not valid")
Obs = Observation(folder, config) utils._log('SUMMARY: ') Obs.printSum() FitRunner = FitMaker(Obs, config) if config["findsrc"]["FitsGeneration"]== "yes": config['analysis']['likelihood'] = 'unbinned' FitRunner.GenerateFits() FitRunner._log('gtfindsrc', 'Optimize source position') os.system("rm "+utils._dump_findsrcout(config)) Obs.FindSource() try: update_reg(config) except: pass if __name__ == '__main__': import sys try: infile = sys.argv[1] except: from enrico import Loggin mes = Loggin.Message() mes.error('Config file not found.') FindSrc(infile)
def WriteXml(lib, doc, srclist, config): from enrico import Loggin mes = Loggin.Message() """Fill and write the library of sources into an XML file""" emin = config['energy']['emin'] emax = config['energy']['emax'] Galname = "GalDiffModel" Isoname = "IsoDiffModel" #test if the user provides diffuse files. if not use the default one if config['model']['diffuse_gal_dir'] == "": Gal_dir = env.DIFFUSE_DIR else: Gal_dir = config['model']['diffuse_gal_dir'] if config['model']['diffuse_iso_dir'] == "": Iso_dir = env.DIFFUSE_DIR else: Iso_dir = config['model']['diffuse_iso_dir'] if config['model']['diffuse_gal'] == "": Gal = Gal_dir + "/" + env.DIFFUSE_GAL else: Gal = Gal_dir + "/" + config['model']['diffuse_gal'] if config['model']['diffuse_iso'] == "": try: Iso = utils.GetIso(config["event"]["evclass"], config["event"]["evtype"]) if not (os.path.isfile(Iso)): raise RuntimeError except: mes.warning("Cannot guess Iso file, please have a look") Iso = Iso_dir + "/" + env.DIFFUSE_ISO_SOURCE else: Iso = Iso_dir + "/" + config['model']['diffuse_iso'] #add diffuse sources addDiffusePL(lib, Iso, free=1, value=1.0, max=10.0, min=1.0, name=Isoname) addGalprop(lib, Gal, free=1, value=1.0, scale=1.0, max=10.0, min=.010, name=Galname) print "Iso model file ", Iso print "Galactic model file ", Gal # loop over the list of sources and add it to the library for i in xrange(len(srclist)): name = srclist[i].get('name') ra = srclist[i].get('ra') dec = srclist[i].get('dec') free = srclist[i].get('IsFree') spectype = srclist[i].get('SpectrumType') extendedName = srclist[i].get('ExtendedName') # Check the spectrum model if spectype == "PowerLaw": addPSPowerLaw1(lib, name, ra, dec, eflux=srclist[i].get('scale'), flux_free=free, flux_value=srclist[i].get('flux'), index_free=free, index_value=srclist[i].get('index'), extendedName=extendedName) if spectype == "PowerLaw2": addPSPowerLaw2(lib, name, ra, dec, emin=emin, emax=emax, flux_free=free, flux_value=srclist[i].get('flux'), index_free=free, index_value=srclist[i].get('index'), extendedName=extendedName) if spectype == "LogParabola": addPSLogparabola(lib, name, ra, dec, enorm=srclist[i].get('scale'), norm_free=free, norm_value=srclist[i].get('flux'), alpha_free=free, alpha_value=abs(srclist[i].get('index')), beta_free=free, beta_value=srclist[i].get('beta'), extendedName=extendedName) if spectype == "PLExpCutoff" or spectype == "PLSuperExpCutoff": addPSPLSuperExpCutoff(lib, name, ra, dec, eflux=srclist[i].get('scale'), flux_free=free, flux_value=srclist[i].get('flux'), index1_free=free, index1_value=srclist[i].get('index'), cutoff_free=free, cutoff_value=srclist[i].get('cutoff'), extendedName=extendedName) folder = config['out'] os.system('mkdir -p ' + folder) output = config['file']['xml'] mes.info("write the Xml file in " + output) open(output, 'w').write(doc.toprettyxml(' ')) #save it
def GetlistFromFits(config, catalog): from enrico import Loggin mes = Loggin.Message() """Read the config and catalog file and generate the list of sources to include""" #Get the informations for the config file srcname = config['target']['name'] ra_src = config['target']['ra'] dec_src = config['target']['dec'] ra_space = config['space']['xref'] dec_space = config['space']['yref'] emin = config['energy']['emin'] roi = config['space']['rad'] + 2 max_radius = config['model']['max_radius'] min_significance = config['model']['min_significance'] model = config['target']['spectrum'] if model == "Generic": mes.warning("Generic model found. Will turn it to PowerLaw") model = "PowerLaw" #read the catalog file cfile = pyfits.open(catalog) data = cfile[1].data names = data.field('Source_Name') ra = data.field('RAJ2000') dec = data.field('DEJ2000') flux = data.field('Flux_Density') pivot = data.field('Pivot_Energy') index = data.field('Spectral_Index') try: # valid for the 2FGH, not for the 1FHL cutoff = data.field('Cutoff') beta = data.field('beta') spectype = data.field('SpectrumType') except: cutoff = np.zeros(names.size) beta = np.zeros(names.size) spectype = np.array(names.size * ["PowerLaw"]) pivot *= 1e3 ## energy in the 1FHL are in GeV flux *= 1e3 try: extendedName = data.field('Extended_Source_Name') extendedfits = cfile[5].data.field('Spatial_Filename') extendedsrcname = cfile[5].data.field('Source_Name') except: mes.warning( "Cannot find the extended source list: please check the xml") extendedName = np.array(names.size * [""]) extendedsrcname = [] sigma = data.field('Signif_Avg') sources = [] Nfree = 0 Nextended = 0 #loop over all the sources of the catalog for i in xrange(len(names)): #distance from the center of the maps rspace = utils.calcAngSepDeg(float(ra[i]), float(dec[i]), ra_space, dec_space) #distance for the target rsrc = utils.calcAngSepDeg(float(ra[i]), float(dec[i]), ra_src, dec_src) j = 0 extended_fitsfilename = "" for extname in extendedsrcname: if extname == extendedName[i]: extended_fitsfilename = extendedfits[j] j += 1 # if the source has a separation less than 0.1deg to the target and has # the same model type as the one we want to use, insert as our target # with our given coordinates if rsrc < .1 and sigma[i] > min_significance and spectype[ i] == model and extended_fitsfilename == "": Nfree += 1 sources.insert( 0, { 'name': srcname, 'ra': ra_src, 'dec': dec_src, 'flux': flux[i], 'index': -index[i], 'scale': pivot[i], 'cutoff': cutoff[i], 'beta': beta[i], 'IsFree': 1, 'SpectrumType': spectype[i], 'ExtendedName': extended_fitsfilename }) elif rsrc < max_radius and rsrc > .1 and sigma[i] > min_significance: # if the source is close to the target : add it as a free source Nfree += 1 sources.append({ 'name': names[i], 'ra': ra[i], 'dec': dec[i], 'flux': flux[i], 'index': -index[i], 'scale': pivot[i], 'cutoff': cutoff[i], 'beta': beta[i], 'IsFree': 1, 'SpectrumType': spectype[i], 'ExtendedName': extended_fitsfilename }) if not (extended_fitsfilename == ""): mes.info("Adding extended source " + extendedName[i] + ", Catalogue name is " + names[i]) Nextended += 1 else: # if the source is inside the ROI: add it as a frozen source if rspace < roi and rsrc > .1 and sigma[i] > min_significance: sources.append({ 'name': names[i], 'ra': ra[i], 'dec': dec[i], 'flux': flux[i], 'index': -index[i], 'scale': pivot[i], 'cutoff': cutoff[i], 'beta': beta[i], 'IsFree': 0, 'SpectrumType': spectype[i], 'ExtendedName': extended_fitsfilename }) if not (extended_fitsfilename == ""): mes.info("Adding extended source " + extendedName[i] + ", Catalogue name is " + names[i]) Nextended += 1 # if the target has not been added from catalog, add it now if sources[0]['name'] != srcname: Nfree += 1 #add the target to the list of sources in first position sources.insert( 0, { 'name': srcname, 'ra': ra_src, 'dec': dec_src, 'flux': 1e-9, 'index': -2, 'scale': emin, 'cutoff': 1e4, 'beta': 0.1, 'IsFree': 1, 'SpectrumType': model, 'ExtendedName': "" }) mes.info("Summary of the XML model generation") print "Add ", len(sources), " sources in the ROI of ", roi, "(", config[ 'space']['rad'], "+ 2 ) degrees" print Nfree, " sources have free parameters inside ", max_radius, " degrees" print Nextended, " source(s) is (are) extended" #save log of the genration of the xml save = "catalog: " + catalog + "\n" save += "Add " + str( len(sources)) + " sources in the ROI of " + str(roi) + "(" + str( config['space']['rad']) + "+ 2 ) degrees\n" save += " sources have free parameters inside " + str( max_radius) + " degrees\n" save += str(Nextended) + " source(s) is (are) extended\n" savexml = open( config['out'] + '/' + config['target']['name'] + "_" + config['target']['spectrum'] + "_generation.log", "w") savexml.write(save) savexml.close() return sources
def PlotDataPoints(config,pars): """Collect the data points/UL and generate a TGraph for the points and a list of TArrow for the UL. All is SED format""" #Preparation + declaration of arrays arrows = [] NEbin = int(config['Ebin']['NumEnergyBins']) lEmax = np.log10(float(config['energy']['emax'])) lEmin = np.log10(float(config['energy']['emin'])) Epoint = np.zeros(NEbin) EpointErrp = np.zeros(NEbin) EpointErrm = np.zeros(NEbin) Fluxpoint = np.zeros(NEbin) FluxpointErrp = np.zeros(NEbin) FluxpointErrm = np.zeros(NEbin) ener = np.logspace(lEmin, lEmax, NEbin + 1) mes = Loggin.Message() mes.info("Save Ebin results in ",pars.PlotName+".Ebin.dat") dumpfile = open(pars.PlotName+".Ebin.dat",'w') dumpfile.write("# Energy (MeV)\tEmin (MeV)\tEmax (MeV)\tE**2. dN/dE (erg.cm-2s-1)\tGaussianError\tMinosNegativeError\tMinosPositiveError\n") from enrico.constants import EbinPath for i in xrange(NEbin):#Loop over the energy bins E = int(pow(10, (np.log10(ener[i + 1]) + np.log10(ener[i])) / 2)) filename = (config['out'] + '/'+EbinPath+str(NEbin)+'/' + config['target']['name'] + "_" + str(i) + ".conf") try:#read the config file of each data points CurConf = get_config(filename) mes.info("Reading "+filename) results = utils.ReadResult(CurConf) except: mes.warning("cannot read the Results of energy "+ str(E)) continue #fill the energy arrays Epoint[i] = E EpointErrm[i] = E - results.get("Emin") EpointErrp[i] = results.get("Emax") - E dprefactor = 0 #Compute the flux or the UL (in SED format) if results.has_key('Ulvalue'): PrefUl = utils.Prefactor(results.get("Ulvalue"),results.get("Index"), results.get("Emin"),results.get("Emax"),E) Fluxpoint[i] = MEV_TO_ERG * PrefUl * Epoint[i] ** 2 arrows.append(ROOT.TArrow(Epoint[i], Fluxpoint[i], Epoint[i], Fluxpoint[i] * 0.5, 0.02, "|>")) else : #Not an UL : compute points + errors Fluxpoint[i] = MEV_TO_ERG * results.get("Prefactor") * Epoint[i] ** 2 dprefactor = results.get("dPrefactor") try: down = abs(results.get("dPrefactor-")) up = results.get("dPrefactor+") if down==0 or up ==0 : mes.error("cannot get Error value") FluxpointErrp[i] = MEV_TO_ERG * up * Epoint[i] ** 2 FluxpointErrm[i] = MEV_TO_ERG * down * Epoint[i] ** 2 except: try: err = MEV_TO_ERG * dprefactor * Epoint[i] ** 2 FluxpointErrp[i] = err FluxpointErrm[i] = err except: pass mes.info("Energy bins results") print "Energy = ",Epoint[i] print "E**2. dN/dE = ",Fluxpoint[i]," + ",FluxpointErrp[i]," - ",FluxpointErrm[i] #Save the data point in a ascii file dumpfile.write(str(Epoint[i])+"\t"+str(results.get("Emin"))+"\t"+str( results.get("Emax"))+"\t"+str(Fluxpoint[i])+"\t"+str( MEV_TO_ERG * dprefactor * Epoint[i] ** 2)+"\t"+str(FluxpointErrm[i])+"\t"+str(FluxpointErrp[i])+"\n") #create a TGraph for the points tgpoint = ROOT.TGraphAsymmErrors(NEbin, Epoint, Fluxpoint, EpointErrm, EpointErrp, FluxpointErrm, FluxpointErrp) tgpoint.SetMarkerStyle(20) dumpfile.close() return tgpoint, arrows
def PrepareEbin(Fit, FitRunner, sedresult=None): """ Prepare the computation of spectral point in energy bins by i) removing the weak sources (TS<1) # not true ii) updating the config file (option and energy) and save it in a new ascii file iii) changing the spectral model and saving it in a new xml file. A list of the ascii files is returned""" mes = Loggin.Message() NEbin = int(FitRunner.config['Ebin']['NumEnergyBins']) config = FitRunner.config config['verbose'] = 'no' #Be quiet #Replace the evt file with the fits file produced before #in order to speed up the production of the fits files config['file']['event'] = FitRunner.obs.eventcoarse #update the config to allow the fit in energy bins config['UpperLimit']['envelope'] = 'no' config['Ebin']['NumEnergyBins'] = '0' #no new bin in energy! config['target']['redshift'] = '0' #Disable EBL correction config['out'] = FitRunner.config['out'] + '/' + EbinPath + str(NEbin) config['Spectrum']['ResultPlots'] = 'no' #no SED plot/modelmap #copy the chose of the user for the enery bin computing config['Spectrum']['FitsGeneration'] = config['Ebin']['FitsGeneration'] config['UpperLimit']['TSlimit'] = config['Ebin']['TSEnergyBins'] tag = FitRunner.config['file']['tag'] lEmax = np.log10(float(FitRunner.config['energy']['emax'])) lEmin = np.log10(float(FitRunner.config['energy']['emin'])) utils._log("Preparing submission of fit into energy bins") print(" Emin = ", float(FitRunner.config['energy']['emin']), " Emax = ", float(FitRunner.config['energy']['emax']), " Nbins = ", NEbin) if config['Ebin']['DistEbins'] in ['TS', 'mix'] and sedresult != None: # Make the bins equispaced in sum(SED/SEDerr) - using the butterfly ipo = 0 iTS = sedresult.SED / sedresult.Err TScumula = 0 TSperbin = 1. * sum(iTS) / NEbin ener = [10**lEmin] while ipo < len(sedresult.E) - 1: TScumula += iTS[ipo] if TScumula / TSperbin > 1: ener.append(sedresult.E[ipo]) TScumula -= TSperbin ipo += 1 ener.append(10**lEmax) ener = np.array(ener) # intermediate approach (between both TS-spaced and logE spaced) if config['Ebin']['DistEbins'] == 'mix': ener = 0.5 * (ener + np.logspace(lEmin, lEmax, NEbin + 1)) else: # Make the bins equispaced in logE (standard) ener = np.logspace(lEmin, lEmax, NEbin + 1) os.system("mkdir -p " + config['out']) paramsfile = [] srcname = FitRunner.config['target']['name'] if config['UpperLimit']['TSlimit'] > Fit.Ts(srcname): utils._log('Re-optimize', False) print "An upper limit has been computed. The fit need to be re-optmized" Fit.optimize(0) Pref = utils.ApproxPref(Fit, ener, srcname) Gamma = utils.ApproxGamma(Fit, ener, srcname) Model_type = Fit.model.srcs[srcname].spectrum().genericName() # if the model is not PowerLaw : change the model if not (Model_type == 'PowerLaw'): for comp in Fit.components: comp.logLike.getSource(srcname).setSpectrum( "PowerLaw") #Change model config['target']['spectrum'] = "PowerLaw" xmltag_list = [""] #handle summed like analysis if config['ComponentAnalysis']['FrontBack'] == "yes": xmltag_list = ["_FRONT", "_BACK"] mes.info("Splitting Front/Back events") elif config['ComponentAnalysis']['PSF'] == "yes": xmltag_list = ["_PSF0", "_PSF1", "_PSF2"] mes.info("Splitting PSF events") elif config['ComponentAnalysis']['EDISP'] == "yes": xmltag_list = ["_EDISP0", "_EDISP1", "_EDISP2", "_EDISP3"] mes.info("Splitting EDISP events") for ibin in xrange(NEbin): #Loop over the energy bins E = utils.GetE0(ener[ibin + 1], ener[ibin]) mes.info("Submitting # " + str(ibin) + " at energy " + str(E)) #Update the model for the bin for comp, xmltag in zip(Fit.components, xmltag_list): NewFitObject = ChangeModel(comp, ener[ibin], ener[ibin + 1], srcname, Pref[ibin], Gamma[ibin]) Xmlname = (config['out'] + "/" + srcname + "_" + str(ibin) + xmltag + ".xml") NewFitObject.writeXml(Xmlname) # dump the corresponding xml file config['file']['xml'] = Xmlname.replace(xmltag, "") #update the energy bounds config['energy']['emin'] = str(ener[ibin]) config['energy']['emax'] = str(ener[ibin + 1]) config['energy']['decorrelation_energy'] = "no" # Change the spectral index to follow the Estimated Gamma # if approximated Gamma is outside of bounds set it to limit Gamma_min = -5 Gamma_max = 0.5 config['UpperLimit']['SpectralIndex'] = -min( max(Gamma_min, Gamma[ibin]), Gamma_max) config['file']['tag'] = tag + '_Ebin' + str(NEbin) + '_' + str(ibin) filename = config['target']['name'] + "_" + str(ibin) + ".conf" paramsfile.append(filename) config.write(open(config['out'] + '/' + paramsfile[ibin], 'w')) #save the config file in a ascii file return paramsfile
def GetlistFromFits(config, catalog): from enrico import Loggin mes = Loggin.Message() """Read the config and catalog file and generate the list of sources to include""" #Get the informations for the config file srcname = config['target']['name'] ra_src = config['target']['ra'] dec_src = config['target']['dec'] redshift = config['target']['redshift'] ebl_model = config['target']['ebl_model'] ra_space = config['space']['xref'] dec_space = config['space']['yref'] emin = config['energy']['emin'] roi = config['space']['rad']+2 max_radius = config['model']['max_radius'] min_significance = config['model']['min_significance'] model = config['target']['spectrum'] if model == "Generic": mes.warning("Generic model found. Will turn it to PowerLaw") model = "PowerLaw" #read the catalog file cfile = fits.open(catalog) data = cfile[1].data names = data.field('Source_Name') ra = data.field('RAJ2000') dec = data.field('DEJ2000') flux = data.field('Flux_Density') pivot = data.field('Pivot_Energy') spectype = data.field('SpectrumType') is8yr = 'FL8Y' in cfile[1].header['CDS-NAME'] try : # valid for the 2FGH, not for the 1FHL if is8yr: spectype = data.field('SpectrumType') index = np.zeros(names.size) cutoff = np.zeros(names.size) expfac = np.zeros(names.size) beta = np.zeros(names.size) for k,spec in enumerate(spectype): if spec == 'PowerLaw': index[k] = data.field('PL_Index')[k] if spec == 'LogParabola': index[k] = data.field('LP_Index')[k] beta[k] = data.field('LP_beta')[k] if spec == 'PLSuperExpCutoff2': # From the makeFL8Yxml.py script index[k] = data.field('PLEC_Index')[k] expfac = data.field('PLEC_Expfactor')[k] expind = data.field('PLEC_Exp_Index')[k] cutoff[k] =(1./expfac)**(1./expind) #cutoff = data.field('Cutoff') #beta = data.field('LP_beta') else: index = data.field('Spectral_Index') cutoff = data.field('Cutoff') beta = data.field('beta') except : raise index = data.field('Spectral_Index') cutoff = np.zeros(names.size) beta = np.zeros(names.size) spectype = np.array(names.size*["PowerLaw"]) pivot *= 1e3 ## energy in the 1FHL are in GeV flux *= 1e3 try : extendedName = data.field('Extended_Source_Name') if is8yr: extendedfits = cfile[2].data.field('Spatial_Filename') extendedsrcname = cfile[2].data.field('Source_Name') else: extendedfits = cfile[5].data.field('Spatial_Filename') extendedsrcname = cfile[5].data.field('Source_Name') except: raise mes.warning("Cannot find the extended source list: please check the xml") extendedName = np.array(names.size*[""]) extendedsrcname = [] sigma = data.field('Signif_Avg') sources = [] Nfree = 0 Nextended = 0 #loop over all the sources of the catalog for i in xrange(len(names)): #distance from the center of the maps rspace = utils.calcAngSepDeg(float(ra[i]), float(dec[i]), ra_space, dec_space) #distance for the target rsrc = utils.calcAngSepDeg(float(ra[i]), float(dec[i]), ra_src, dec_src) j=0 extended_fitsfilename = "" for extname in extendedsrcname: if extname == extendedName[i]: extended_fitsfilename = extendedfits[j] j+=1 # if the source has a separation less than 0.1deg to the target and has # the same model type as the one we want to use, insert as our target # with our given coordinates if rsrc < .1 and sigma[i] > min_significance and spectype[i] == model and extended_fitsfilename=="": Nfree += 1 mes.info("Adding [free] target source, Catalog name is %s, dist is %.2f and TS is %.2f" %(names[i],rsrc,sigma[i]) ) sources.insert(0,{'name': srcname, 'ra': ra_src, 'dec': dec_src, 'flux': flux[i], 'index': -index[i], 'scale': pivot[i], 'cutoff': cutoff[i], 'beta': beta[i], 'IsFree': 1, 'SpectrumType': spectype[i], 'ExtendedName': extended_fitsfilename}) elif rsrc < max_radius and rsrc > .1 and sigma[i] > min_significance: # if the source is close to the target : add it as a free source Nfree += 1 mes.info("Adding [free] source, Catalog name is %s, dist is %.2f and TS is %.2f" %(names[i],rsrc,sigma[i]) ) if not(extended_fitsfilename==""): if not os.path.isfile(extended_fitsfilename): mes.warning("Filename %s for extended source %s does not exist. Skipping." %(extended_fitsfilename,extendedName[i])) continue mes.info("Adding extended source "+extendedName[i]+", Catalogue name is "+names[i]) Nextended+=1 sources.append({'name': names[i], 'ra': ra[i], 'dec': dec[i], 'flux': flux[i], 'index': -index[i], 'scale': pivot[i], 'cutoff': cutoff[i], 'beta': beta[i], 'IsFree': 1, 'SpectrumType': spectype[i], 'ExtendedName': extended_fitsfilename}) # srcs that were kept fixed in the 3FGL: add them as fixed srcs elif rspace < roi and sigma[i] == -np.inf: mes.info("Adding [fixed in 3FGL] source, Catalog name is %s, dist is %.2f and TS is %.2f" %(names[i],rspace,sigma[i]) ) if not(extended_fitsfilename==""): if not os.path.isfile(extended_fitsfilename): mes.warning("Filename %s for extended source %s does not exist. Skipping." %(extended_fitsfilename,extendedName[i])) continue mes.info("Adding extended source "+extendedName[i]+", Catalogue name is "+names[i]) Nextended+=1 sources.append({'name': names[i], 'ra': ra[i], 'dec': dec[i], 'flux': flux[i], 'index': -index[i], 'scale': pivot[i], 'cutoff': cutoff[i], 'beta': beta[i], 'IsFree': 0, 'SpectrumType': spectype[i],'ExtendedName': extended_fitsfilename}) else: # if the source is inside the ROI: add it as a frozen source if rspace < roi and rsrc > .1 and sigma[i] > min_significance: mes.info("Adding [fixed] source, Catalog name is %s, dist is %.2f and TS is %.2f" %(names[i],rsrc,sigma[i]) ) if not(extended_fitsfilename==""): if not os.path.isfile(extended_fitsfilename): mes.warning("Filename %s for extended source %s does not exist. Skipping." %(extended_fitsfilename,extendedName[i])) continue mes.info("Adding extended source "+extendedName[i]+", Catalogue name is "+names[i]) Nextended+=1 sources.append({'name': names[i], 'ra': ra[i], 'dec': dec[i], 'flux': flux[i], 'index': -index[i], 'scale': pivot[i], 'cutoff': cutoff[i], 'beta': beta[i], 'IsFree': 0, 'SpectrumType': spectype[i],'ExtendedName': extended_fitsfilename}) # if the target has not been added from catalog, add it now if sources[0]['name']!=srcname: Nfree += 1 #add the target to the list of sources in first position sources.insert(0,{'name':srcname, 'ra': ra_src, 'dec': dec_src, 'flux': 1e-9, 'index':-2, 'scale': emin, 'cutoff': 1e4, 'beta': 0.1, 'IsFree': 1, 'SpectrumType': model,'ExtendedName': ""}) mes.info("Summary of the XML model generation") print "Add ", len(sources), " sources in the ROI of ", roi, "(",config['space']['rad'],"+ 2 ) degrees" print Nfree, " sources have free parameters inside ", max_radius, " degrees" print Nextended, " source(s) is (are) extended" #save log of the generation of the xml save = "catalog: "+catalog+"\n" save += "Add "+str(len(sources))+" sources in the ROI of "+str(roi)+ "("+str(config['space']['rad'])+"+ 2 ) degrees\n" save += " sources have free parameters inside "+str(max_radius)+" degrees\n" save += str(Nextended)+" source(s) is (are) extended\n" savexml = open(config['out']+'/'+ config['target']['name']+"_"+config['target']['spectrum']+"_generation.log","w") savexml.write(save) savexml.close() return sources
def query_config(): import os """Make a new config object, asking the user for required options""" config = ConfigObj(indent_type='\t') mes = Loggin.Message() mes.info('Please provide the following required options [default] :') config['out'] = os.getcwd() out = raw_input('Output directory [' + config['out'] + '] : ') if not (out == ''): config['out'] = out # Informations about the source config['target'] = {} config['target']['name'] = raw_input('Target Name : ') config['target']['ra'] = raw_input('Right Ascension: ') config['target']['dec'] = raw_input('Declination: ') config['target']['redshift'] = '0' redshift = raw_input('redshift, no effect if null [0] : ') if not (redshift == ''): config['target']['redshift'] = redshift config['target']['ebl_model'] = raw_input( 'ebl model to used\n' '0=Kneiske, 1=Primack05, 2=Kneiske_HighUV, 3=Stecker05, ' '4=Franceschini, 5=Finke, 6=Gilmore : ') message = ( 'Options are : PowerLaw, PowerLaw2, LogParabola, ' 'PLExpCutoff, Generic\nGeneric is design to allow the user to fit with non-supported models\n' 'EBL absorption can be added for PowerLaw2, LogParabola, PLExpCutoff\n' 'Spectral Model [PowerLaw] : ') config['target']['spectrum'] = 'PowerLaw' model = raw_input(message) if not (model == ''): config['target']['spectrum'] = model # informations about the ROI config['space'] = {} config['space']['xref'] = config['target']['ra'] config['space']['yref'] = config['target']['dec'] config['space']['rad'] = '15' roi = raw_input('ROI Size [15] : ') if not (roi == ''): config['space']['rad'] = roi # informations about the input files config['file'] = {} if USE_FULLMISSION_SPACECRAFT: config['file'][ 'spacecraft'] = DOWNLOAD_DIR + '/lat_spacecraft_merged.fits' else: config['file']['spacecraft'] = '@' + DOWNLOAD_DIR + '/spacecraft.lis' ft2 = raw_input('FT2 file [' + config['file']['spacecraft'] + '] : ') if not (ft2 == ''): config['file']['spacecraft'] = ft2 config['file']['event'] = DOWNLOAD_DIR + '/events.lis' ft1list = raw_input('FT1 list of files [' + config['file']['event'] + '] : ') if not (ft1list == ''): config['file']['event'] = ft1list config['file']['xml'] = config['out'] + '/' + config['target'][ 'name'] + '_' + config['target']['spectrum'] + '_model.xml' tag = raw_input('tag [LAT_Analysis] : ') if not (tag == ''): config['file']['tag'] = tag else: config['file']['tag'] = 'LAT_Analysis' # informations about the time config['time'] = {} tmin = raw_input('Start time [-1=START] : ') ft2 = config['file']['spacecraft'] if not (tmin == '') and float(tmin) >= 0: config['time']['tmin'] = tmin else: config['time']['tmin'] = get_times_from_spacecraft(ft2, target=['tmin'])[0] tmax = raw_input('End time [-1=END] : ') if not (tmax == '') and float(tmax) >= 0: config['time']['tmax'] = tmax else: config['time']['tmax'] = get_times_from_spacecraft(ft2, target=['tmax'])[1] # informations about the energy config['energy'] = {} emin = raw_input('Emin [100] : ') if not (emin == ''): config['energy']['emin'] = emin else: config['energy']['emin'] = '100' emax = raw_input('Emax [300000] : ') if not (emax == ''): config['energy']['emax'] = emax else: config['energy']['emax'] = '300000' # informations about the event class config['event'] = {} irfs = raw_input('IRFs [CALDB] : ') if not (irfs == ''): config['event']['irfs'] = irfs else: config['event']['irfs'] = 'CALDB' if irfs == '': ok = False while not (ok): evclass = raw_input('evclass [128] : ') if not (evclass == ''): config['event']['evclass'] = evclass else: config['event']['evclass'] = '128' evtype = raw_input('evtype [3] : ') if not (evtype == ''): config['event']['evtype'] = evtype else: config['event']['evtype'] = '3' print "Corresponding IRFs\t=\t", utils.GetIRFS( float(config['event']['evclass']), float(config['event']['evtype'])) ans = raw_input('Is this ok? [y] : ') if ans == "y" or ans == '': ok = True config['analysis'] = {} zmax = utils.GetZenithCut(float(config['event']['evclass']), float(config['event']['evtype']), float(config['energy']['emin'])) print "Corresponding zmax = ", zmax config["analysis"]["zmax"] = zmax return get_config(config)
def Contour(config): # ROOT.gROOT.SetBatch(ROOT.kTRUE) # cres = ROOT.TCanvas("Contour") config["Spectrum"]["FitsGeneration"] = "no" parname1 = config["Contours"]["parname1"] parname2 = config["Contours"]["parname2"] FitRunner,Fit = RunGTlike.GenAnalysisObjects(config) spectrum = Fit[FitRunner.obs.srcname].funcs['Spectrum'] ParName = spectrum.paramNames mes = Loggin.Message() mes.info("Computing Contours for "+parname1+" and "+parname2) ### Check part !!!! findpar2 = findpar1 = False for par in ParName : #Loop over the parameters to check if par == parname1: findpar1 = True if not(spectrum.getParam(par).isFree()): mes.error(parname1+" is not a free parameter") if par == parname2: findpar2 = True if not(spectrum.getParam(par).isFree()): mes.error(parname2+" is not a free parameter") if not(findpar1): mes.error(parname1+" is not a valid parameter") if not(findpar2): mes.error(parname2+" is not a valid parameter") bestloglike = Fit.fit(0,covar=False,optimizer=config['fitting']['optimizer']) print spectrum print "Min LogLikelihood =",bestloglike ## get values ParValue1 = spectrum.getParam(parname1).value() ParError1 = spectrum.getParam(parname1).error() bmin1,bmax1 = spectrum.getParam(parname1).getBounds() bmin1 = max(bmin1,ParValue1-20*ParError1) bmax1 = min(bmax1,ParValue1+20*ParError1) ParValue2 = spectrum.getParam(parname2).value() ParError2 = spectrum.getParam(parname2).error() bmin2,bmax2 = spectrum.getParam(parname2).getBounds() bmin2 = max(bmin2,ParValue2-20*ParError2) bmax2 = min(bmax2,ParValue2+20*ParError2) N = 100 param2 = numpy.zeros(N) loglike = ROOT.TH2F("loglike","Contours (68%, 95%, 99%)",N,bmin1,bmax1,N,bmin2,bmax2) spectrum.getParam(parname2).setFree(0) mes.info("Boundaries for "+parname1+" ["+str(bmin1)+","+str(bmax1)+"]") mes.info("Boundaries for "+parname2+" ["+str(bmin2)+","+str(bmax2)+"]") for i in xrange(N): param2[i] = bmin2 + (bmax2-bmin2)*i/(N-1.) spectrum.getParam(parname2).setValue(param2[i]) param1,ll = MakeScan(Fit,spectrum,parname1,bmin1,bmax1,config['fitting']['optimizer'],N) for j in xrange(N): loglike.Fill(param1[j],param2[i],ll[j]) os.system("mkdir -p "+config["out"]+"/"+cst.ScanPath) cres = ROOT.TCanvas("Contours") loglike.SetMinimum(bestloglike); loglike.SetMaximum(bestloglike+3); loglike.SetXTitle(parname1); loglike.SetYTitle(parname2); loglike.SetStats(000) loglike.SetContour(3) loglike.SetContourLevel(0,bestloglike+0.5) loglike.SetContourLevel(1,bestloglike+4./2.) loglike.SetContourLevel(2,bestloglike+6.63/2.) loglike.Draw("CONT1"); tgrres = ROOT.TGraphErrors(2,array.array('f',[ParValue1,ParValue1]),array.array('f',[ParValue2,ParValue2]),array.array('f',[ParError1,ParError1]),array.array('f',[ParError2,ParError2])) tgrres.Draw(".pz") cres.Print(config["out"]+"/"+cst.ScanPath+ "/Contours_"+parname1+"_"+parname2+".eps") cres.Print(config["out"]+"/"+cst.ScanPath+ "/Contours_"+parname1+"_"+parname2+".C") cres.Print(config["out"]+"/"+cst.ScanPath+ "/Contours_"+parname1+"_"+parname2+".png") mes.success("Scan Performed")
def WriteXml(lib, doc, srclist, config): from enrico import Loggin mes = Loggin.Message() """Fill and write the library of sources into an XML file""" emin = config['energy']['emin'] emax = config['energy']['emax'] Galname = "GalDiffModel" Isoname = "IsoDiffModel" #test if the user provides diffuse files. if not use the default one if config['model']['diffuse_gal_dir'] == "": Gal_dir = env.DIFFUSE_DIR else: Gal_dir = config['model']['diffuse_gal_dir'] if config['model']['diffuse_iso_dir'] == "": Iso_dir = env.DIFFUSE_DIR else: Iso_dir = config['model']['diffuse_iso_dir'] if config['model']['diffuse_gal'] == "": Gal = Gal_dir + "/" + env.DIFFUSE_GAL else: Gal = Gal_dir + "/" + config['model']['diffuse_gal'] if config['model']['diffuse_iso'] == "": try : Iso = utils.GetIso(config["event"]["evclass"],config["event"]["evtype"]) if not(os.path.isfile(Iso)): raise RuntimeError except: mes.warning("Cannot find Iso file %s, please have a look. Switching to default one" %Iso) Iso = Iso_dir + "/" + env.DIFFUSE_ISO_SOURCE else: Iso = Iso_dir + "/" + config['model']['diffuse_iso'] #add diffuse sources addDiffusePL(lib, Iso, free=1, value=1.0, max=10.0, min=1.0, name=Isoname) addGalprop(lib, Gal, free=1, value=1.0, scale=1.0, max=10.0, min=.010, name=Galname) print "Iso model file ",Iso print "Galactic model file ",Gal yesnodict = {} for y in ['yes',True,'true',1,1.0,'1','1.0']: yesnodict[y] = 1 for n in ['no',False,'false',0,0.0,'0','0.0']: yesnodict[n] = 0 try: ebldict = {} ebldict['tau_norm'] = 1.0 ebldict['free_redshift'] = 0 # NOTE:ToDo ebldict['free_tau_norm'] = yesnodict[config['target']['fit_tau']] ebldict['redshift'] = float(config['target']['redshift']) ebldict['model'] = int(config['target']['ebl_model']) if ebldict['redshift'] < 1.e-3: ebldict = None except NameError: ebldict = None # loop over the list of sources and add it to the library for i in xrange(len(srclist)): name = srclist[i].get('name') if (name == config['target']['name']): ebl = ebldict else: ebl = None ra = srclist[i].get('ra') dec = srclist[i].get('dec') free = srclist[i].get('IsFree') spectype = srclist[i].get('SpectrumType') extendedName = srclist[i].get('ExtendedName') # Check the spectrum model if spectype.strip() == "PowerLaw": if (ebl==None): addPSPowerLaw1(lib, name, ra, dec, "None", eflux=srclist[i].get('scale'), flux_free=free, flux_value=srclist[i].get('flux'), index_free=free, index_value=srclist[i].get('index'),extendedName=extendedName) if (ebl!=None): addPSLogparabola(lib, name, ra, dec, ebl, norm_free=free, norm_value=srclist[i].get('flux'), alpha_free=free, alpha_value=abs(srclist[i].get('index')), beta_free=0, beta_min=0, beta_max=0, beta_value=0,extendedName=extendedName) elif spectype.strip() == "PowerLaw2": addPSPowerLaw2(lib, name, ra, dec, ebl, emin=emin, emax=emax, flux_free=free, flux_value=srclist[i].get('flux'), index_free=free, index_value=srclist[i].get('index'),extendedName=extendedName) elif spectype.strip() == "LogParabola": addPSLogparabola(lib, name, ra, dec, ebl, enorm=srclist[i].get('scale'), norm_free=free, norm_value=srclist[i].get('flux'), alpha_free=free, alpha_value=abs(srclist[i].get('index')), beta_free=free, beta_value=srclist[i].get('beta'),extendedName=extendedName) elif spectype.strip() == "PLExpCutoff" or spectype == "PLSuperExpCutoff" or spectype == "PLSuperExpCutoff2": addPSPLSuperExpCutoff(lib, name, ra, dec, ebl, eflux=srclist[i].get('scale'), flux_free=free, flux_value=srclist[i].get('flux'), index1_free=free, index1_value=srclist[i].get('index'), cutoff_free=free, cutoff_value=srclist[i].get('cutoff'),extendedName=extendedName) else: print('Warning!!!, unknown model %s' %spectype.strip()) folder = config['out'] utils.mkdir_p(folder) output = config['file']['xml'] mes.info("write the Xml file in "+output) open(output, 'w').write(doc.toprettyxml(' '))#save it
def PrepareEbin(Fit, FitRunner): """ Prepare the computation of spectral point in energy bins by i) removing the weak sources (TS<1) # not true ii) updating the config file (option and energy) and save it in a new ascii file iii) changing the spectral model and saving it in a new xml file. A list of the ascii files is returned""" NEbin = int(FitRunner.config['Ebin']['NumEnergyBins']) config = FitRunner.config config['verbose'] = 'no' #Be quiet #Replace the evt file with the fits file produced before #in order to speed up the production of the fits files config['file']['event'] = FitRunner.obs.eventcoarse #update the config to allow the fit in energy bins config['UpperLimit']['envelope'] = 'no' config['Ebin']['NumEnergyBins'] = '0' #no new bin in energy! config['target']['redshift'] = '0' #Disable EBL correction config['out'] = FitRunner.config['out'] + '/' + EbinPath + str(NEbin) config['Spectrum']['ResultPlots'] = 'no' #no SED plot/modelmap #copy the chose of the user for the enery bin computing config['Spectrum']['FitsGeneration'] = config['Ebin']['FitsGeneration'] config['UpperLimit']['TSlimit'] = config['Ebin']['TSEnergyBins'] tag = FitRunner.config['file']['tag'] lEmax = np.log10(float(FitRunner.config['energy']['emax'])) lEmin = np.log10(float(FitRunner.config['energy']['emin'])) utils._log("Preparing submission of fit into energy bins") print(" Emin = ", float(FitRunner.config['energy']['emin']), " Emax = ", float(FitRunner.config['energy']['emax']), " Nbins = ", NEbin) ener = np.logspace(lEmin, lEmax, NEbin + 1) os.system("mkdir -p " + config['out']) paramsfile = [] srcname = FitRunner.config['target']['name'] if config['UpperLimit']['TSlimit'] > Fit.Ts(srcname): utils._log('Re-optimize', False) print "An upper limit has been computed. The fit need to be re-optmized" Fit.optimize(0) Pref = utils.ApproxPref(Fit, ener, srcname) Gamma = utils.ApproxGamma(Fit, ener, srcname) Model_type = Fit.model.srcs[srcname].spectrum().genericName() # if the model is not PowerLaw : change the model if not (Model_type == 'PowerLaw'): for comp in Fit.components: comp.logLike.getSource(srcname).setSpectrum( "PowerLaw") #Change model config['target']['spectrum'] = "PowerLaw" for ibin in xrange(NEbin): #Loop over the energy bins E = utils.GetE0(ener[ibin + 1], ener[ibin]) from enrico import Loggin mes = Loggin.Message() mes.info("Submition # " + str(ibin) + " at energy " + str(E)) #Update the model for the bin NewFitObject = ChangeModel(Fit, ener[ibin], ener[ibin + 1], srcname, Pref[ibin], Gamma[ibin]) Xmlname = (config['out'] + "/" + srcname + "_" + str(ibin) + ".xml") NewFitObject.writeXml(Xmlname) # dump the corresponding xml file config['file']['xml'] = Xmlname #update the energy bounds config['energy']['emin'] = str(ener[ibin]) config['energy']['emax'] = str(ener[ibin + 1]) config['energy']['decorrelation_energy'] = "no" # Change the spectral index to follow the Estimated Gamma # if approximated Gamma is outside of bounds set it to limit Gamma_min = -5 Gamma_max = 0.5 config['UpperLimit']['SpectralIndex'] = -min( max(Gamma_min, Gamma[ibin]), Gamma_max) config['file']['tag'] = tag + '_Ebin' + str(NEbin) + '_' + str(ibin) filename = config['target']['name'] + "_" + str(ibin) + ".conf" paramsfile.append(filename) config.write(open(config['out'] + '/' + paramsfile[ibin], 'w')) #save the config file in a ascii file return paramsfile
def PrepareEbin(Fit, FitRunner, sedresult=None): """ Prepare the computation of spectral point in energy bins by i) removing the weak sources (TS<1) # not true ii) updating the config file (option and energy) and save it in a new ascii file iii) changing the spectral model and saving it in a new xml file. A list of the ascii files is returned""" mes = Loggin.Message() NEbin = int(FitRunner.config['Ebin']['NumEnergyBins']) config = FitRunner.config config['verbose'] = 'no' #Be quiet #Replace the evt file with the fits file produced before #in order to speed up the production of the fits files config['file']['event'] = FitRunner.obs.eventcoarse #update the config to allow the fit in energy bins config['UpperLimit']['envelope'] = 'no' config['Ebin']['NumEnergyBins'] = '0' #no new bin in energy! config['target']['redshift'] = '0' #Disable EBL correction config['out'] = FitRunner.config['out'] + '/' + EbinPath + str(NEbin) config['Spectrum']['ResultPlots'] = 'no' #no SED plot/modelmap #copy the chose of the user for the enery bin computing config['Spectrum']['FitsGeneration'] = config['Ebin']['FitsGeneration'] config['UpperLimit']['TSlimit'] = config['Ebin']['TSEnergyBins'] tag = FitRunner.config['file']['tag'] Emax = float(FitRunner.config['energy']['emax']) Emin = float(FitRunner.config['energy']['emin']) lEmax = np.log10(Emax) lEmin = np.log10(Emin) utils._log("Preparing submission of fit into energy bins") print("Emin = {0} MeV".format(Emin), "Emax = {0} MeV".format(Emax), "Nbins = {0}".format(NEbin)) ener = utils.string_to_list(config['Ebin']['DistEbins']) if ener is None: if (config['ComponentAnalysis']['FGL4'] == 'yes' or config['Ebin']['DistEbins'] == 'FGL4'): ener = np.asarray([50, 1e2, 3e2, 1e3, 3e3, 1e4, 3e4, 3e5]) NEbin = len(ener) - 1 elif config['Ebin']['DistEbins'] in ['TS', 'mix' ] and sedresult != None: # Make the bins equispaced in sum(SED/SEDerr) - using the butterfly ipo = 0 iTS = sedresult.SED / sedresult.Err TScumula = 0 TSperbin = 1. * sum(iTS) / NEbin ener = [10**lEmin] while ipo < len(sedresult.E) - 1: TScumula += iTS[ipo] if TScumula / TSperbin > 1: ener.append(sedresult.E[ipo]) TScumula -= TSperbin ipo += 1 ener.append(10**lEmax) ener = np.array(ener) # intermediate approach (between both TS-spaced and logE spaced) if config['Ebin']['DistEbins'] == 'mix': ener = 0.5 * (ener + np.logspace(lEmin, lEmax, NEbin + 1)) else: # Make the bins equispaced in logE (standard) ener = np.logspace(lEmin, lEmax, NEbin + 1) # 1. Remove bins that are out of the range covered by the data # 2. Limit the bin extend to the range covered by the data. # Get elements strictly above threshold +1 element to the left for the left side # Get elements strictly below limit +1 element to the right side. # example. [1,2,3,4,5] -> if Emin=3.4, Emax=3.9 we want to keep [3.4,3.9]. ener = np.asarray(ener) print("Energy bins (before energy cuts): {0}".format(str(ener))) if len(ener) == 0: print("** Warning: energy bin array is empty") return (None) available_left = ener > Emin # In the example FFFTT -> [4,5] for k, use in enumerate(available_left[:-1]): if not use and available_left[k + 1]: available_left[k] = True # In the example FFTTT -> [3,5] available_right = ener < Emax # In the example TTTFF -> [1,3] for k, use in enumerate(available_right[1:]): if not use and available_right[k]: available_right[k + 1] = True # In the example TTTTF -> [1,4] available = available_left * available_right ener = ener[available] # In the example FFTTF -> [3,4] # Limit the range to the real energies that are covered by our data # If the energy bins are well placed this should not do anything. ener[0] = np.max([Emin, ener[0]]) ener[-1] = np.min([Emax, ener[-1]]) NEbin = len(ener) - 1 print("Energy bins (after energy cuts): {0}".format(str(ener))) if len(ener) == 0: print("** Warning: energy bin array is empty") return (None) utils.mkdir_p(config['out']) paramsfile = [] srcname = FitRunner.config['target']['name'] try: TSsrc = Fit.Ts(srcname) except RuntimeError: TSsrc = 0 if config['UpperLimit']['TSlimit'] > TSsrc: utils._log('Re-optimize', False) print "An upper limit has been computed. The fit need to be re-optimized" Fit.optimize(0) Pref = utils.ApproxPref(Fit, ener, srcname) Gamma = utils.ApproxGamma(Fit, ener, srcname) Model_type = Fit.model.srcs[srcname].spectrum().genericName() # if the model is not PowerLaw : change the model if not (Model_type == 'PowerLaw'): for comp in Fit.components: comp.logLike.getSource(srcname).setSpectrum( "PowerLaw") #Change model config['target']['spectrum'] = "PowerLaw" xmltag_list = [""] #handle summed like analysis if config['ComponentAnalysis']['FrontBack'] == "yes": xmltag_list = ["_FRONT", "_BACK"] mes.info("Splitting Front/Back events") elif config['ComponentAnalysis']['PSF'] == "yes": xmltag_list = ["_PSF0", "_PSF1", "_PSF2", "_PSF3"] mes.info("Splitting PSF events") elif config['ComponentAnalysis']['EDISP'] == "yes": xmltag_list = ["_EDISP0", "_EDISP1", "_EDISP2", "_EDISP3"] mes.info("Splitting EDISP events") elif config['ComponentAnalysis']['FGL4'] == "yes": from catalogComponents import evtnum, energybins, pixelsizes xmltag_list = [] for ebin_i in energybins: for k, evt in enumerate(evtnum): #if pixelsizes[ebin_i][k] > 0: try: xmltag_list.append("_{0}_En{1}".format( utils.typeirfs[k], ebin_i)) except KeyError: continue for ibin in xrange(NEbin): #Loop over the energy bins E = utils.GetE0(ener[ibin + 1], ener[ibin]) mes.info("Submitting # " + str(ibin) + " at energy " + str(E)) #Update the model for the bin for comp, xmltag in zip(Fit.components, xmltag_list): NewFitObject = ChangeModel(comp, ener[ibin], ener[ibin + 1], srcname, Pref[ibin], Gamma[ibin]) Xmlname = (config['out'] + "/" + srcname + "_" + str(ibin) + xmltag + ".xml") NewFitObject.writeXml(Xmlname) # dump the corresponding xml file config['file']['xml'] = Xmlname.replace(xmltag, "") #update the energy bounds config['energy']['emin'] = str(ener[ibin]) config['energy']['emax'] = str(ener[ibin + 1]) config['energy']['decorrelation_energy'] = "no" # Change the spectral index to follow the Estimated Gamma # if approximated Gamma is outside of bounds set it to limit Gamma_min = -5 Gamma_max = -0.501 Gamma_bin = -max(min(Gamma_max, Gamma[ibin]), Gamma_min) config['Spectrum']['FrozenSpectralIndex'] = Gamma_bin config['UpperLimit']['SpectralIndex'] = Gamma_bin config['file']['tag'] = tag + '_Ebin' + str(NEbin) + '_' + str(ibin) filename = config['target']['name'] + "_" + str(ibin) + ".conf" paramsfile.append(filename) config.write(open(config['out'] + '/' + filename, 'w')) #save the config file in a ascii file return paramsfile