def ComputeUL(self, Fit): """Compute an Upper Limit using either the profil or integral method See the ST cicerone for more information on the 2 method""" self._log('UpperLimit', 'Compute upper Limit') #Index given by the user print "Assumed index is ", self.config['UpperLimit']['SpectralIndex'] IdGamma = utils.getParamIndx(Fit, self.obs.srcname, 'Index') Fit[IdGamma] = -self.config['UpperLimit']['SpectralIndex']#set the index Fit[IdGamma].setFree(0)#the variable index is frozen to compute the UL import scipy.stats cl = float(self.config['UpperLimit']['cl']) delta = 0.5*scipy.stats.chi2.isf(1-2*(cl-0.5), 1) print cl,' ',delta if self.config['UpperLimit']['Method'] == "Profile": #The method is Profile import UpperLimits ulobject = UpperLimits.UpperLimits(Fit) ul, _ = ulobject[self.obs.srcname].compute(emin=self.obs.Emin, emax=self.obs.Emax,delta=delta) #delta=2.71 / 2) print "Upper limit using Profile method: " print ulobject[self.obs.srcname].results if self.config['UpperLimit']['Method'] == "Integral": #The method is Integral import IntegralUpperLimit ul, _ = IntegralUpperLimit.calc_int(Fit, self.obs.srcname, cl=cl, verbosity=0) print "Upper limit using Integral method: ", ul return ul #Return the result. This is an ul on the integral flux in ph/cm2/s
def EnvelopeUL(self, Fit): """Compute the envelope UL. An UL is computed for different index and the maximum is taken at each energy. This is usefull when the source index is not know or can not be constrain by theoritical argument The index range form 1.5 to 2.5""" import IntegralUpperLimit self._log('EnvelopeUL', 'Compute upper limit envelope') PhIndex = Fit.par_index(self.obs.srcname, 'Index') Nbp = 20 #Make Nbp computations Npgraph = 100#The graph has Npgraph points ener = np.logspace(np.log10(self.obs.Emin), np.log10(self.obs.Emax), Npgraph)#the array containing the energy Ulenv = np.array(Npgraph * [0.])#the array containing the UL value for i in xrange(Nbp): indx = -1.5 - i / (Nbp - 1.) Fit[PhIndex] = indx Fit.freeze(PhIndex)#Freeze the index #Use either the profile or the integral method if self.config['UpperLimit']['Method'] == "Profile": ul = UpperLimits.UpperLimits(Fit) source_ul = ul[self.obs.srcname] ul_val, _ = source_ul.compute(emin=self.obs.Emin, emax=self.obs.Emax, delta=2.71 / 2) if self.config['UpperLimit']['Method'] == "Integral": ul_val, _ = IntegralUpperLimit.calc_int(Fit, self.obs.srcname, verbosity=0) print "Index = ", indx, " UL = ", ul_val #small print for j in xrange(Npgraph): model_name = Fit.model.srcs[self.obs.srcname].spectrum().genericName() #compute the DNDE value. The computation change is #the model is PowerLaw or PowerLaw2 #Note : Other model are not taken into account #and no UL will be computed if model_name == 'PowerLaw2': newUl = ul_val * (indx + 1) * pow(ener[j], indx + 2) / (pow(self.obs.Emax, indx + 1) - pow(self.obs.Emin, indx + 1)) elif model_name == 'PowerLaw': IdEScale = utils.getParamIndx(Fit, self.obs.srcname, 'Scale') Escale = Fit[IdEScale].value() newUl = ul_val * pow(ener[j] / Escale, indx + 2) Ulenv[j] = max(Ulenv[j], newUl) print print "Result of the UL envelope" for j in xrange(Npgraph): print ener[j], " ", Ulenv[j]