def ChangeModel(comp, E1, E2, name, Pref, Gamma): """Change the spectral model of a source called name to allow a fit between E1 and E2 If the spectral model is PowerLaw, the prefactor is updated if not the model is change to PowerLaw. The index is frozen in all cases""" # if approximated Gamma is outside of bounds set it to limit Gamma_min = -5 Gamma_max = 0.5 Gamma = min(max(Gamma_min, Gamma), Gamma_max) Eav = utils.GetE0(E1, E2) spectrum = comp.logLike.getSource(name).getSrcFuncs()['Spectrum'] spectrum.getParam('Prefactor').setBounds(1e-5, 1e5) spectrum.getParam('Prefactor').setScale(utils.fluxScale(Pref)) spectrum.getParam('Prefactor').setValue(utils.fluxNorm(Pref)) spectrum.getParam('Index').setBounds(Gamma_min, Gamma_max) spectrum.getParam('Index').setValue(Gamma) spectrum.getParam('Index').setFree(0) spectrum.getParam('Scale').setValue(Eav) spectrum.getParam('Scale').setBounds(20, 3e6) return comp
def ChangeModel(Fit, E1, E2, name, Pref, Gamma): """Change the spectral model of a source called name to allow a fit between E1 and E2 If the spectral model is PowerLaw, the prefactor is updated if not the model is change to PowerLaw. The index is frozen in all cases""" Eav = utils.GetE0(E1, E2) # Set Parameters Fit.logLike.getSource(name).getSrcFuncs()['Spectrum'].getParam('Prefactor').setBounds(1e-5,1e5) Fit.logLike.getSource(name).getSrcFuncs()['Spectrum'].getParam('Prefactor').setScale(utils.fluxScale(Pref)) Fit.logLike.getSource(name).getSrcFuncs()['Spectrum'].getParam('Prefactor').setValue(utils.fluxNorm(Pref)) Gamma_min=-5 Gamma_max=0 # if approximated Gamma is outside of bounds set it to limit if Gamma < Gamma_min: Gamma = Gamma_min elif Gamma > Gamma_max: Gamma = Gamma_max Fit.logLike.getSource(name).getSrcFuncs()['Spectrum'].getParam('Index').setBounds(Gamma_min,Gamma_max) Fit.logLike.getSource(name).getSrcFuncs()['Spectrum'].getParam('Index').setValue(Gamma) Fit.logLike.getSource(name).getSrcFuncs()['Spectrum'].getParam('Index').setFree(0) Fit.logLike.getSource(name).getSrcFuncs()['Spectrum'].getParam('Scale').setValue(Eav) Fit.logLike.getSource(name).getSrcFuncs()['Spectrum'].getParam('Scale').setBounds(20,3e6) return Fit
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'] 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 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
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'] # Check if it is an energy bin, so we won't take the pivot energy from the catalog is_energy_bin = 1 if 'Ebin' in config['file']['tag'] else 0 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'] == "": Iso = utils.GetIso(config["event"]["evclass"], config["event"]["evtype"]) try: if not (os.path.isfile(Iso)): raise IOError except IOError: 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') freeshape = srclist[i].get('IsFreeShape') spectype = srclist[i].get('SpectrumType') extendedName = srclist[i].get('ExtendedName') # Check the spectrum model if spectype.strip() == "PowerLaw": if (ebl == None): energyscale = utils.GetE0( emin, emax) if is_energy_bin else srclist[i].get('scale') addPSPowerLaw1(lib, name, ra, dec, "None", emin=emin, emax=emax, eflux=energyscale, flux_free=free, flux_value=srclist[i].get('flux'), index_free=freeshape, index_value=srclist[i].get('index'), extendedName=extendedName) if (ebl != None): addPSLogparabola(lib, name, ra, dec, ebl, emin=emin, emax=emax, norm_free=free, norm_value=srclist[i].get('flux'), alpha_free=freeshape, 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=freeshape, index_value=srclist[i].get('index'), extendedName=extendedName) elif spectype.strip() == "LogParabola": addPSLogparabola(lib, name, ra, dec, ebl, enorm=srclist[i].get('scale'), emin=emin, emax=emax, norm_free=free, norm_value=srclist[i].get('flux'), alpha_free=freeshape, alpha_value=abs(srclist[i].get('index')), beta_free=freeshape, beta_value=srclist[i].get('beta'), extendedName=extendedName) elif spectype.strip( ) == "PLExpCutoff" or spectype == "PLSuperExpCutoff" or spectype == "PLSuperExpCutoff2": addPSPLSuperExpCutoff(lib, name, ra, dec, ebl, emin=emin, emax=emax, eflux=srclist[i].get('scale'), flux_free=free, flux_value=srclist[i].get('flux'), index1_free=freeshape, index1_value=srclist[i].get('index'), cutoff_free=freeshape, cutoff_value=srclist[i].get('cutoff'), extendedName=extendedName) elif spectype.strip() == "BrokenPowerLaw": addPSBrokenPowerLaw2(lib, name, ra, dec, ebl, emin=emin, emax=emax, flux_value=1.6, flux_scale=1e-6, 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