def calcCosThetaStar(j1, j2): """docstring for calcCosThetaStar""" tmpCM1 = j1 + j2 tmpJ1 = TLorentzVector() tmpJ2 = TLorentzVector() tmpJ1.SetPtEtaPhiE(j1.Pt(), j1.Eta(), j1.Phi(), j1.E()) tmpJ2.SetPtEtaPhiE(j2.Pt(), j2.Eta(), j2.Phi(), j2.E()) tmpJ1.Boost(-tmpCM1.BoostVector()) tmpJ2.Boost(-tmpCM1.BoostVector()) tmpV1 = TVector3(tmpJ1.X(), tmpJ1.Y(), tmpJ1.Z()) tmpV2 = TVector3(tmpJ2.X(), tmpJ2.Y(), tmpJ2.Z()) #cosThetaStar1 = abs( ( ( pairoff08[1].Px() * pairoff08[2].Px() ) + ( pairoff08[1].Py() * pairoff08[2].Py() ) + ( pairoff08[1].Pz() * pairoff08[2].Pz() ) ) / ( pairoff08[1].E() * pairoff08[2].E() ) ) cosThetaStar = abs(tmpV1.CosTheta()) return cosThetaStar
def position_aftr_boost(df, args): #args must have 4 elements xyzt or pxpypzE px, py, pz = getXYZ(df, args) E = DfToNp(df[[args[3]]].dropna(axis=0)) l = TLorentzVector() with np.nditer([px, py, pz, E, None, None, None]) as it: for pi, pj, pk, el, x, y, z in it: l.SetPxPyPzE(pi, pj, pk, el) #p = math.hypot(pi,pj) #p = math.hypot(pk,p) bi = pi / el bj = pj / el bk = pk / el #print(b) l.Boost(-bi, -bj, -bk) z[...] = l.X() y[...] = l.Y() z[...] = l.Z() return (it.operands[4], it.operands[5], it.operands[6])
def fitmZ(self): dilepton = False diele = False dimu = False if self.leptons[0].pdgId() + self.leptons[1].pdgId() == 0 and \ abs( self.leptons[0].pdgId() - self.leptons[1].pdgId()) > 20 : dilepton = True #if not(dilepton) : return -99. diele = abs(self.leptons[0].pdgId() - self.leptons[1].pdgId()) == 22 dimu = abs(self.leptons[0].pdgId() - self.leptons[1].pdgId()) == 26 l1 = TLorentzVector(self.leptons[0].px(), self.leptons[0].py(), self.leptons[0].pz(), self.leptons[0].energy()) l2 = TLorentzVector(self.leptons[1].px(), self.leptons[1].py(), self.leptons[1].pz(), self.leptons[1].energy()) c12 = l1.Vect().Dot(l2.Vect()) / l1.P() / l2.P() st1 = l1.Pt() / l1.P() st2 = l2.Pt() / l2.P() m12 = (l1 + l2).M() / sqrt(l1.E() * l2.E()) fac = 91.188 / (l1 + l2).M() energies = [l1.E() * fac, l2.E() * fac] measts = [l1.E(), l2.E()] def chi2(e): def breitw2(m, m0, g0): m02 = m0 * m0 g02 = g0 * g0 delta = m * m - m02 return m02 * g02 / (delta * delta + g02 * m02) def breitw(m, m0, g0): delta = m - m0 return m0 * g0 / (delta * delta + g0 * m0) chi2 = 0. fudge = 1. mz = m12 * sqrt(e[0] * e[1]) mzm = m12 * sqrt(measts[0] * measts[1]) #mz = sqrt(2.*e[0]*e[1]*(1.-c12)) #print 'mz = ',mz sigma1 = 0 sigma2 = 0 if dimu: chi2 = ( 1./measts[0]-1./e[0] ) * ( 1./measts[0]-1./e[0] ) / (st1*st1) \ + ( 1./measts[1]-1./e[1] ) * ( 1./measts[1]-1./e[1] ) / (st2*st2) chi2 /= 25E-8 sigma1 = 5E-4 * 5E-4 * e[0] * e[0] * e[0] * e[0] * st1 * st1 sigma2 = 5E-4 * 5E-4 * e[1] * e[1] * e[0] * e[0] * st2 * st2 fudge = 0.5 elif diele: sigma1 = (0.155 * 0.155 + 0.043 * 0.043 * e[0] + 0.02 * 0.02 * e[0] * e[0]) sigma2 = (0.155 * 0.155 + 0.043 * 0.043 * e[1] + 0.02 * 0.02 * e[1] * e[1]) chi2 = (measts[0]-e[0])*(measts[0]-e[0]) / sigma1 \ + (measts[1]-e[1])*(measts[1]-e[1]) / sigma2 fudge = 2.0 else: sigma1 = (0.5 * 0.5 * e[0] / st1 + 0.04 * 0.04 * e[0] * e[0]) sigma2 = (0.5 * 0.5 * e[1] / st2 + 0.04 * 0.04 * e[1] * e[1]) chi2 = (measts[0]-e[0])*(measts[0]-e[0]) / sigma1 \ + (measts[1]-e[1])*(measts[1]-e[1]) / sigma2 fudge = 1.0 #print 'chi2 partial = ',chi2 sigmaM = mz * mz * (sigma1 / (e[0] * e[0]) + sigma2 / (e[1] * e[1])) / 4. #chi2 = (mzm-mz)*(mzm-mz)/sigmaM self.chi2partiel = copy.copy(chi2) chi2 -= fudge * log(breitw2(mz, 91.188, 2.497)) * sqrt(sigmaM) / 2.497 self.chi2total = copy.copy(chi2) #if diele: # print 'chi2 partie/complet = ',dimu,diele,mz,mzm,sqrt(sigma1),sqrt(sigma2),sqrt(sigmaM),self.chi2partiel,self.chi2total return chi2 def fillDerivatives(funga): def deriv(funga, gamma, i, epsilon): g = deepcopy(gamma) g[i] += epsilon chip = funga(g) g[i] -= 2. * epsilon chim = funga(g) g[i] += epsilon return (chip - chim) / (2. * epsilon) def deriv2(funga, gamma, i, j, epsilon, mu): g = deepcopy(gamma) g[i] += epsilon derp = deriv(funga, g, j, mu) g[i] -= 2. * epsilon derm = deriv(funga, g, j, mu) g[i] += epsilon return (derp - derm) / (2. * epsilon) rows = [] deri = [] for i in range(len(energies)): column = [] for j in range(len(energies)): column.append(deriv2(funga, energies, i, j, 0.001, 0.001)) rows.append(column) deri.append(deriv(funga, energies, i, 0.001)) return array(rows), array(deri) from numpy import array, linalg, dot, add from copy import deepcopy #print chi2(energies) Delta = 1E9 t = 0 while Delta > 1E-3 and t < 200: #print "iteration ",t t += 1 d2, d = fillDerivatives(chi2) delta = linalg.solve(d2, d) Delta = abs(delta[0]) + abs(delta[1]) #print '------------------- ' #print 'Delta = ',Delta Ki2 = chi2(energies) factor = 1. for i in range(len(energies)): #print i, energies[i], delta[i], d[i] if abs(delta[i]) > energies[i] / 10.: factor = min(factor, energies[i] / 10. / abs(delta[i])) delta = map(lambda x: x * factor, delta) def chinew(funga, gamma, delta): gnew = deepcopy(gamma) for i, g in enumerate(gamma): gnew[i] -= delta[i] return funga(gnew) - Ki2 while chinew(chi2, energies, delta) > 1E-5: delta = map(lambda x: -x * 0.6, delta) #print ' ' for i in range(len(energies)): energies[i] -= delta[i] if t >= 199: print 'Warning - reached iteration ', t print diele, dimu, chi2(energies) for i in range(len(energies)): print i, energies[i], delta[i], d[i] #print t, chi2(energies) l1 *= energies[0] / l1.E() l2 *= energies[1] / l2.E() #if not(dimu): # m12 = (l1+l2).M() # l1 *= sqrt(91.188/m12) # l2 *= sqrt(91.188/m12) #print self.leptons[0] p41 = self.leptons[0].p4() p41.SetPxPyPzE(l1.X(), l1.Y(), l1.Z(), l1.T()) self.leptons[0].setP4(p41) #print self.leptons[1] p42 = self.leptons[1].p4() p42.SetPxPyPzE(l2.X(), l2.Y(), l2.Z(), l2.T()) self.leptons[1].setP4(p42) return chi2(energies)
def multiple_scattering(particle, detector_element, field): '''This function computes the scattering of a particle while propagating through the detector. As described in the pdg booklet, Passage of particles through matter, multiple scattering through small angles. the direction of a charged particle is modified. This function takes a particle (that has been propagated until the detector element where it will be scattered) and the detector element responsible for the scattering. The magnetic field has to be specified in order to create the new trajectory. Then this function computes the new direction, randomly choosen according to Moliere's theory of multiple scattering (see pdg booklet) and replaces the initial path of the particle by this new scattered path. The particle can now be propagated in the next part of the detector. ''' if not particle.q(): return # reject particles that could not be extrapolated to detector element # (particle created too late, out of the detector element) surface_in = '{}_in'.format(detector_element.name) surface_out = '{}_out'.format(detector_element.name) if not surface_in in particle.path.points or \ not surface_out in particle.path.points: return #TODOCOLIN : check usage of private attributes in_point = particle.path.points[surface_in] out_point = particle.path.points[surface_out] phi_in = particle.path.phi(in_point.X(), in_point.Y()) phi_out = particle.path.phi(out_point.X(), out_point.Y()) t_scat = particle.path.time_at_phi((phi_in + phi_out) * 0.5) # compute p4_t = p4 at t_scat : p4_0 = particle.path.p4.Clone() p4tx = p4_0.X()*math.cos(particle.path.omega*t_scat)\ + p4_0.Y()*math.sin(particle.path.omega*t_scat) p4ty =-p4_0.X()*math.sin(particle.path.omega*t_scat)\ + p4_0.Y()*math.cos(particle.path.omega*t_scat) p4tz = p4_0.Z() p4tt = p4_0.T() p4_t = TLorentzVector(p4tx, p4ty, p4tz, p4tt) # now, p4t will be modified with respect to the multiple scattering # first one has to determine theta_0 the width of the gaussian : P = p4_t.Vect().Dot(p4_t.Vect().Unit()) deltat = particle.path.time_at_phi(phi_out) - particle.path.time_at_phi( phi_in) x = abs(particle.path.path_length(deltat)) X_0 = detector_element.material.x0 theta_0 = 1.0 * 13.6e-3 / (1.0 * particle.path.speed / constants.c * P) * abs(particle.path.charge) theta_0 *= (1.0 * x / X_0)**(1.0 / 2) * (1 + 0.038 * math.log(1.0 * x / X_0)) # now, make p4_t change due to scattering : theta_space = random.gauss(0, theta_0 * 2.0**(1.0 / 2)) psi = constants.pi * random.uniform(0, 1) #double checked p3i = p4_t.Vect().Clone() e_z = TVector3(0, 0, 1) #first rotation : theta, in the xy plane a = p3i.Cross(e_z) #this may change the sign, but randomly, as the sign of theta already is p4_t.Rotate(theta_space, a) #second rotation : psi (isotropic around initial direction) p4_t.Rotate(psi, p3i.Unit()) # creating new helix, ref at scattering point : helix_new_t = Helix(field, particle.path.charge, p4_t, particle.path.point_at_time(t_scat)) # now, back to t=0 p4sx = p4_t.X()*math.cos(-particle.path.omega*t_scat)\ + p4_t.Y()*math.sin(-particle.path.omega*t_scat) p4sy =-p4_t.X()*math.sin(-particle.path.omega*t_scat)\ + p4_t.Y()*math.cos(-particle.path.omega*t_scat) p4sz = p4_t.Z() p4st = p4_t.T() p4_scat = TLorentzVector(p4sx, p4sy, p4sz, p4st) # creating new helix, ref at new t0 point : helix_new_0 = Helix(field, particle.path.charge, p4_scat, helix_new_t.point_at_time(-t_scat)) # replacing the particle's path with the scatterd one : particle.set_path(helix_new_0, option='w')
def get_gen_kin(rootfile): intree = rfile.Get('kin') d = tree2array(intree) Px = d['Px_FinalState'] Py = d['Py_FinalState'] Pz = d['Pz_FinalState'] E = d['E_FinalState'] Px_beam = d['Px_Beam'] Py_beam = d['Py_Beam'] Pz_beam = d['Pz_Beam'] E_beam = d['E_Beam'] #get numpy arrays to save later mproton = np.zeros_like(Px) metap = np.zeros_like(Px) mpi0 = np.zeros_like(Px) metaprimepi0 = np.zeros_like(Px) beam_energy = np.zeros_like(Px) cos_theta = np.zeros_like(Px) #declare TLorentzVector Beam_P4 = TLorentzVector() Proton_P4 = TLorentzVector() Etaprime_P4 = TLorentzVector() Pi0_P4 = TLorentzVector() Etaprimepi0_P4 = TLorentzVector() #declare stuff to convert to GJ frame boostGJ = TVector3() Beam_P4_GJ = TLorentzVector() Proton_P4_GJ = TLorentzVector() Etaprime_P4_GJ = TLorentzVector() Pi0_P4_GJ = TLorentzVector() Etaprimepi0_P4_GJ = TLorentzVector() z_GJ = TVector3() z_hat_GJ = TVector3() y_GJ = TVector3() y_hat_GJ = TVector3() x_hat_GJ = TVector3() vetaprime = TVector3() for i in range(len(Px)): #for i in range(100): #m = np.sqrt(E[i][0]**2 - (Px[i][0]**2 + Py[i][0]**2 + Pz[i][0]**2)) #metap[i] = m #get TLorentzVector vectors Beam_P4.SetPxPyPzE(Px_beam[i], Py_beam[i], Pz_beam[i], E_beam[i]) Proton_P4.SetPxPyPzE(Px[i][0], Py[i][0], Pz[i][0], E[i][0]) Etaprime_P4.SetPxPyPzE(Px[i][1], Py[i][1], Pz[i][1], E[i][1]) Pi0_P4.SetPxPyPzE(Px[i][2], Py[i][2], Pz[i][2], E[i][2]) #do stuff here Etaprimepi0_P4 = Etaprime_P4 + Pi0_P4 #get the boost vector boostGJ = (-1) * (Etaprimepi0_P4.Vect()) * (1.0 / Etaprimepi0_P4.E()) Beam_P4_GJ = Beam_P4 Proton_P4_GJ = Proton_P4 Etaprime_P4_GJ = Etaprime_P4 Pi0_P4_GJ = Pi0_P4 Etaprimepi0_P4_GJ = Etaprimepi0_P4 #boost vectors to GJ frame Beam_P4_GJ.Boost(boostGJ) Proton_P4_GJ.Boost(boostGJ) Etaprime_P4_GJ.Boost(boostGJ) Pi0_P4_GJ.Boost(boostGJ) Etaprimepi0_P4_GJ.Boost(boostGJ) z_GJ.SetXYZ(Beam_P4_GJ.X(), Beam_P4_GJ.Y(), Beam_P4_GJ.Z()) z_hat_GJ = z_GJ.Unit() y_GJ = Beam_P4.Vect().Cross(Etaprimepi0_P4.Vect()) y_hat_GJ = y_GJ.Unit() x_hat_GJ = y_hat_GJ.Cross(z_hat_GJ) vetaprime.SetXYZ(Etaprime_P4_GJ.Vect() * x_hat_GJ, Etaprime_P4_GJ.Vect() * y_hat_GJ, Etaprime_P4_GJ.Vect() * z_hat_GJ) cos_theta[i] = vetaprime.CosTheta() mproton[i] = Proton_P4.M() metap[i] = Etaprime_P4.M() mpi0[i] = Pi0_P4.M() metaprimepi0[i] = Etaprimepi0_P4.M() beam_energy[i] = Beam_P4.E() return np.savez( '/Users/rupeshdotel/analysis/work/pi0pippimeta/data/MC/check_events.npz', mproton=mproton, metap=metap, mpi0=mpi0, metaprimepi0=metaprimepi0, cos_theta=cos_theta, beam_energy=beam_energy)