def SignalShape(x, par): ''' :param x: x[0]: x position x[1]: y position :param par: par[0]: number of peaks par[1]: mean bkg signal par[2]: peak height in percent of bkg par[3]: peak1 x position par[4]: peak1 y position par[5]: peak1 sigma in x par[6]: peak1 sigma in y ... par[3+4*n]: peakn x position par[4+4*n]: peakn y position par[5+4*n]: peakn sigma in x par[6+4*n]: peakn sigma in y :return: ''' norm = par[1] * par[2] result = par[1] if par[1] == 0: norm = 1 for i in range(int(par[0])): result += norm * TMath.Gaus(x[0], par[3 + 4 * i], par[5 + 4 * i]) * TMath.Gaus(x[1], par[4 + 4 * i], par[6 + 4 * i]) return result
def langaufun(x, par): ''' Fit parameters: par[0]=Width (scale) parameter of Landau density par[1]=Most Probable (MP, location) parameter of Landau density par[2]=Total area (integral -inf to inf, normalization constant) par[3]=Width (sigma) of convoluted Gaussian function In the Landau distribution (represented by the CERNLIB approximation), the maximum is located at x=-0.22278298 with the location parameter=0. This shift is corrected within this function, so that the actual maximum is identical to the MP parameter. ''' # control constants ns = 100 # number of convolution steps sc = 5.0 # convolution extends to +-sc Gaussian sigmas # MP shift correction mpc = par[1] - mpshift * par[0] xlow = x[0] - sc * par[3] xupp = x[0] + sc * par[3] step = (xupp - xlow) / ns sumup = 0 for i in range(1, ns / 2): xx = xlow + (i - 0.5) * step fland = TMath.Landau(xx, mpc, par[0]) / par[0] sumup += fland * TMath.Gaus(x[0], xx, par[3]) xx = xupp - (i - .5) * step fland = TMath.Landau(xx, mpc, par[0]) / par[0] sumup += fland * TMath.Gaus(x[0], xx, par[3]) return par[2] * step * sumup * invsq2pi / par[3]
def ManualHitDistribution(x, par): ''' Probability density function for hit distribution based on 6 2d gaussian in a rectangular pattern. The PDF is NOT normalized to 1 :param x: array, x[0]: x position, x[1]: y position :param par: parameter array; :return: ''' result = 0.1 # bkg norm = 1. sigma = 0.04 for i in range(len(par) / 2): result += norm * TMath.Gaus(x[0], par[2 * i], sigma) * TMath.Gaus(x[1], par[2 * i + 1], sigma) return result
def DoubleGaus(x, par): ''' Sum of two Gaussian functions with same mean and different sigma Parameters ---------- - x: function variable - par: function parameters par[0]: normalisation par[1]: mean par[2]: first sigma par[3]: second sigma par[4]: fraction of integral in second Gaussian ''' firstGaus = TMath.Gaus(x[0], par[1], par[2], True) secondGaus = TMath.Gaus(x[0], par[1], par[3], True) return par[0] * ((1 - par[4]) * firstGaus + par[4] * secondGaus)
def langaufun(x, par): """Convoluted Landau and Gaussian Fitting Function source: https://root.cern.ch/root/html/tutorials/fit/langaus.C.html translated to python by Benjamin Rottler ([email protected]) parameters: par[0] = Width (scale) parameter of Landau density par[1] = Most Probable (MP, location) parameter of Landau density par[2] = Total area (integral -inf to inf, normalization constant) par[3] = Width (sigma) of convoluted Gaussian function In the Landau distribution (represented by the CERNLIB approximation), the maximum is located at x=-0.22278298 with the location parameter=0. This shift is corrected within this function, so that the actual maximum is identical to the MP parameter. """ # numeric constants invsq2pi = (2 * pi)**(-1 / 2) mpshift = -0.22278298 # Landau maximum location # control constants np = 500 # number of convolution steps sc = 5 # convolution extends to +-sc Guassion sigmas # mp shift correction mpc = par[1] - mpshift * par[0] # range of convolution integral xlow, xupp = x[0] - sc * par[3], x[0] + sc * par[3] # Convolution integral of Landau and Gaussion by sum i = 1 step = (xupp - xlow) / np s = 0 while i <= np / 2: xx = xlow + (i - 0.5) * step fland = TMath.Landau(xx, mpc, par[0]) / par[0] s += fland * TMath.Gaus(x[0], xx, par[3]) xx = xupp - (i - 0.5) * step fland = TMath.Landau(xx, mpc, par[0]) / par[0] s += fland * TMath.Gaus(x[0], xx, par[3]) i += 1 return (par[2] * step * s * invsq2pi / par[3])
def DoublePeakSingleGaus(x, par): ''' Sum of two Gaussian functions with different mean and sigma Parameters ---------- - x: function variable - par: function parameters par[0]: normalisation first peak par[1]: mean first peak par[2]: sigma first peak par[3]: normalisation second peak par[4]: mean second peak par[5]: sigma second peak ''' firstGaus = par[0] * TMath.Gaus(x[0], par[1], par[2], True) secondGaus = par[3] * TMath.Gaus(x[0], par[4], par[5], True) return firstGaus + secondGaus
def ffunc_DDPIPI(x, par): ''' function for correlated breit wigner: e+e- --> pipiDD with convoluted Gaussian function''' sum = 0. X = x[0] sigma_gaus = 1.6 * 0.001 xlow = X - 5. * sigma_gaus xup = X + 5. * sigma_gaus step = (xup - xlow) / 100. for i in range(1, 50): xx = xlow + (i - 0.5) * step ffun = func_DDPIPI(xx, par) sum += ffun * TMath.Gaus(X, xx, sigma_gaus) xx = xup - +(i - 0.5) * step ffun = func_DDPIPI(xx, par) sum += ffun * TMath.Gaus(X, xx, sigma_gaus) return sum * step * GeV_2_sigma / sigma_gaus
def DoublePeakDoubleGaus(x, par): ''' Sum of a double Gaussian function and a single Gaussian function Parameters ---------- - x: function variable - par: function parameters par[0]: normalisation first peak par[1]: mean first peak par[2]: first sigma first peak par[3]: second sigma first peak par[4]: fraction of integral in second Gaussian first peak par[5]: normalisation second peak par[6]: mean second peak par[7]: sigma second peak ''' firstGaus = TMath.Gaus(x[0], par[1], par[2], True) secondGaus = TMath.Gaus(x[0], par[1], par[3], True) thirdGaus = par[5] * TMath.Gaus(x[0], par[6], par[7], True) return par[0] * ( (1 - par[4]) * firstGaus + par[4] * secondGaus) + thirdGaus
def SingleGaus(x, par): ''' Gaussian function Parameters ---------- - x: function variable - par: function parameters par[0]: normalisation par[1]: mean par[2]: sigma ''' return par[0] * TMath.Gaus(x[0], par[1], par[2], True)
def __call__(self, x, par): out = 0 t = (x[0] - par[1]) / par[2] if (par[0] < 0): t = -t absAlpha = TMath.Abs(par[3]) if (t >= -absAlpha): out = par[0] * TMath.Exp(-0.5 * t * t) else: a = TMath.Power(par[4] / absAlpha, par[4]) * TMath.Exp( -0.5 * absAlpha * absAlpha) b = par[4] / absAlpha - absAlpha out = par[0] * (a / TMath.Power(b - t, par[4])) out = out + par[5] * TMath.Gaus(x[0], par[1], par[6]) return out
def myFitFunc(x=None, par=None): return par[0] * TMath.Gaus(x[0], par[1], par[2], kFALSE)
def __call__(self, x, par): out = par[0] * (1 - par[1] * x[0]) * (x[0]**( -par[2])) + par[3] * TMath.Gaus(x[0], par[4], par[5]) return out
def __call__(self, x, par): x1 = par[0] * TMath.Power(x[0] - 60, -par[1]) x2 = TMath.Exp(-1.0 * (TMath.Power(par[2] * (x[0] - 60), 2))) out = x1 * x2 + par[3] * TMath.Gaus(x[0], par[4], par[5]) return out
def __call__(self, x, par): x1 = par[0] * TMath.Power(x[0], -par[1]) x2 = TMath.Exp(-par[2] * x[0]) out = x1 * x2 + par[3] * TMath.Gaus(x[0], par[4], par[5]) return out
def __call__(self, x, par): out = (par[0] * TMath.Gaus(x[0], par[1], par[2])) + par[3] * (x[0]**-par[4]) return out
def __call__(self, x, par): x1 = par[0] * TMath.Power(x[0], -par[1]) x2 = TMath.Exp(-par[2] * x[0]) x3 = TMath.Exp(-par[3] * x[0] * x[0]) return x1 * x2 * x3 + par[4] * TMath.Gaus(x[0], par[5], par[6])
def NoisePlusLandauGaus(x, par): #p_noise comes from a template histogram and is normalized to 1.0 p_noise = 0 if (x[0] >= 0 and x[0] < 2): p_noise = 0.0219891 elif (x[0] >= 2 and x[0] < 4): p_noise = 0.120234 elif (x[0] >= 4 and x[0] < 6): p_noise = 0.201533 elif (x[0] >= 6 and x[0] < 8): p_noise = 0.208594 elif (x[0] >= 8 and x[0] < 10): p_noise = 0.150293 elif (x[0] >= 10 and x[0] < 12): p_noise = 0.103087 elif (x[0] >= 12 and x[0] < 14): p_noise = 0.0691951 elif (x[0] >= 14 and x[0] < 16): p_noise = 0.0490216 elif (x[0] >= 16 and x[0] < 18): p_noise = 0.0344967 elif (x[0] >= 18 and x[0] < 20): p_noise = 0.0217874 elif (x[0] >= 20 and x[0] < 22): p_noise = 0.0117006 elif (x[0] >= 22 and x[0] < 24): p_noise = 0.00484164 else: p_noise = 0.003228 #p_landau = TMath.Landau(x[0],par[2],par[3],False) invsq2pi = 0.3989422804014 # (2 pi)^(-1/2) mpshift = -0.22278298 # Landau maximum location np = 500.0 # number of convolution steps sc = 5.0 # convolution extends to +-sc Gaussian sigmas #integral result sum = 0.0 #MP shift correction mpc = par[2] - mpshift * par[3] #Range of convolution integral xlow = x[0] - sc * par[4] xupp = x[0] + sc * par[4] step = (xupp - xlow) / np #Convolution integral of Landau and Gaussian by sum for i in range(1, int(np / 2) + 1): xx = xlow + (i - .5) * step fland = TMath.Landau(xx, mpc, par[3]) / par[3] sum += fland * TMath.Gaus(x[0], xx, par[4]) xx = xupp - (i - .5) * step fland = TMath.Landau(xx, mpc, par[3]) / par[3] sum += fland * TMath.Gaus(x[0], xx, par[4]) p_landauGaus = step * sum * invsq2pi / par[4] return par[0] * ((1 - par[1]) * p_noise + par[1] * p_landauGaus)
def __call__( self, x, par ): out=par[0] * TMath.Gaus(x[0],par[1],par[2]) return out;
sys.exit() FONLLVar = ['central', 'min', 'max'] hPromptD0, hPromptLcpK0s, hPromptLcpKpi, hPromptLcpiL = ({} for _ in range(4)) inFile = TFile.Open(args.inFileName) for var in FONLLVar: hPromptD0[var] = inFile.Get(f'hD0Kpipred_{var}') hPromptD0[var].Scale(1. / args.BRD0) hPromptLcpK0s[var] = inFile.Get(f'hLcK0sppred_{var}') hPromptLcpKpi[var] = inFile.Get(f'hLcpkpipred_{var}') for iPt in range(1, hPromptD0['central'].GetNbinsX() + 1): for var in FONLLVar: pT = hPromptD0[var].GetBinCenter(iPt) crossSec = hPromptD0[var].GetBinContent(iPt) factor = 0.11 + 4.68735e-01 * TMath.Gaus( pT, 1, 4.90037) # parametrised from 5.02 TeV measurement hPromptLcpK0s[var].SetBinContent(iPt, factor * crossSec * args.BRpK0s) hPromptLcpKpi[var].SetBinContent(iPt, factor * crossSec * args.BRpKpi) outFileName = args.inFileName.replace('.root', '_Mod.root') os.system(f'cp {args.inFileName} {outFileName}') outFile = TFile.Open(outFileName, 'update') for var in FONLLVar: hPromptLcpK0s[var].Write(hPromptLcpK0s[var].GetName(), TObject.kOverwrite) hPromptLcpKpi[var].Write(hPromptLcpKpi[var].GetName(), TObject.kOverwrite) outFile.Close()
def func_DDPIPI(x, par): ''' function for correlated breit wigner: e+e- --> DDpipi ''' xx = x[0] return par[0] * pow(xx, -2) * TMath.Exp( -1 * par[1] * (xx - 4.015)) + par[2] * TMath.Gaus(xx, par[3], par[4])
def AddToField(X, B, S0, Sigma, Integral): "Add gaussian to field" for i in range(len(X)): B[i] += Integral * TMath.Gaus(X[i], S0, Sigma, True)