142 a,u = PosDir[t1][
'position'],PosDir[t1][
'direction']
143 c,v = PosDir[t2][
'position'],PosDir[t2][
'direction']
148 denom = Usq*Vsq-UV**2
150 Va = ca.Dot(tmp2)/denom
152 Vb = ca.Dot(tmp2)/denom
153 X = (a+c+Va*u+Vb*v) * 0.5
155 dist = 2. * ROOT.TMath.Sqrt( l1.Dot(l1) )
156 T = ROOT.TMatrixD(3,12)
164 temp = ( u[j]*Vsq - v[j]*UV )*u[i] + (u[j]*UV-v[j]*Usq)*v[i]
167 T[i][3*k+j] = 0.5*( KD + sign*temp/denom )
170 aNAZ = denom*( ca[j]*Vsq-v.Dot(ca)*v[j] )
171 aZAN = ( ca.Dot(u)*Vsq-ca.Dot(v)*UV )*2*( u[j]*Vsq-v[j]*UV )
172 bNAZ = denom*( ca[j]*UV+(u.Dot(ca)*v[j]) - 2*ca.Dot(v)*u[j] )
173 bZAN = ( ca.Dot(u)*UV-ca.Dot(v)*Usq )*2*( u[j]*Vsq-v[j]*UV )
174 T[i][3*k+j] = 0.5*( Va*KD + u[i]/denom**2*(aNAZ-aZAN) + v[i]/denom**2*(bNAZ-bZAN) )
177 aNAZ = denom*( 2*ca.Dot(u)*v[j] - ca.Dot(v)*u[j] - ca[j]*UV )
178 aZAN = ( ca.Dot(u)*Vsq-ca.Dot(v)*UV )*2*( v[j]*Usq-u[j]*UV )
179 bNAZ = denom*( ca.Dot(u)*u[j]-ca[j]*Usq )
180 bZAN = ( ca.Dot(u)*UV-ca.Dot(v)*Usq )*2*( v[j]*Usq-u[j]*UV )
181 T[i][3*k+j] = 0.5*(Vb*KD + u[i]/denom**2*(aNAZ-aZAN) + v[i]/denom**2*(bNAZ-bZAN) )
182 transT = ROOT.TMatrixD(12,3)
184 CovTracks = ROOT.TMatrixD(12,12)
190 if i>2: xfac = scalFac[tlist[k]]
191 if j>2: xfac = xfac * scalFac[tlist[k]]
192 CovTracks[i+k*6][j+k*6] = CovMat[tlist[k]][i][j] * xfac
194 tmp = ROOT.TMatrixD(3,12)
195 tmp.Mult(T,CovTracks)
196 covX = ROOT.TMatrixD(3,3)
197 covX.Mult(tmp,transT)
315 xx = sTree.FitTracks[tr].getFittedState()
316 PosDir[tr] = [xx.getPos(),xx.getDir()]
317 xv,yv,zv,doca =
myVertex(t1,t2,PosDir)
320 reps,states,newPosDir = {},{},{}
321 parallelToZ = ROOT.TVector3(0., 0., 1.)
326 newPos = ROOT.TVector3(xv,yv,zv)
329 xx = sTree.FitTracks[tr].getFittedState()
330 reps[tr] = ROOT.genfit.RKTrackRep(xx.getPDG())
331 states[tr] = ROOT.genfit.StateOnPlane(reps[tr])
332 reps[tr].setPosMom(states[tr],xx.getPos(),xx.getMom())
334 reps[tr].extrapolateToPoint(states[tr], newPos,
False)
336 print(
'SHiPAna: extrapolation did not worked')
339 newPosDir[tr] = [reps[tr].getPos(states[tr]),reps[tr].getDir(states[tr])]
341 xv,yv,zv,doca =
myVertex(t1,t2,newPosDir)
345 print(
'abort iteration, too many steps, pos=',xv,yv,zv,
' doca=',doca,
'z before and dz',zBefore,dz)
348 if not rc:
return xv,yv,zv,doca,-1
351 mom = reps[tr].getMom(states[tr])
352 pid = abs(states[tr].getPDG())
353 if pid == 2212: pid = 211
354 mass = PDG.GetParticle(pid).Mass()
355 E = ROOT.TMath.Sqrt( mass*mass + mom.Mag2() )
356 LV[tr] = ROOT.TLorentzVector()
357 LV[tr].SetPxPyPzE(mom.x(),mom.y(),mom.z(),E)
358 HNLMom = LV[t1]+LV[t2]
359 return xv,yv,zv,doca,HNLMom
417 ut.bookCanvas(h,key=
'ecalanalysis',title=
'cluster map',nx=800,ny=600,cx=1,cy=1)
418 cv = h[
'ecalanalysis'].cd(1)
419 h[
'ecalClusters'].Draw(
'colz')
420 ut.bookCanvas(h,key=
'ecalCluster2Track',title=
'Ecal cluster distances to track impact',nx=1600,ny=800,cx=4,cy=2)
421 if "ecalReconstructed_dist_mu+" in h:
422 cv = h[
'ecalCluster2Track'].cd(1)
423 h[
'ecalReconstructed_distx_mu+'].Draw()
424 cv = h[
'ecalCluster2Track'].cd(2)
425 h[
'ecalReconstructed_disty_mu+'].Draw()
426 if "ecalReconstructed_dist_pi+" in h:
427 cv = h[
'ecalCluster2Track'].cd(3)
428 h[
'ecalReconstructed_distx_pi+'].Draw()
429 cv = h[
'ecalCluster2Track'].cd(4)
430 h[
'ecalReconstructed_disty_pi+'].Draw()
431 if "ecalReconstructed_dist_mu-" in h:
432 cv = h[
'ecalCluster2Track'].cd(5)
433 h[
'ecalReconstructed_distx_mu-'].Draw()
434 cv = h[
'ecalCluster2Track'].cd(6)
435 h[
'ecalReconstructed_disty_mu-'].Draw()
436 if "ecalReconstructed_dist_pi-" in h:
437 cv = h[
'ecalCluster2Track'].cd(7)
438 h[
'ecalReconstructed_distx_pi-'].Draw()
439 cv = h[
'ecalCluster2Track'].cd(8)
440 h[
'ecalReconstructed_disty_pi-'].Draw()
442 ut.bookCanvas(h,key=
'strawanalysis',title=
'Distance to wire and mean nr of hits',nx=1200,ny=600,cx=3,cy=1)
443 cv = h[
'strawanalysis'].cd(1)
445 h[
'distu'].Draw(
'same')
446 h[
'distv'].Draw(
'same')
447 cv = h[
'strawanalysis'].cd(2)
449 cv = h[
'strawanalysis'].cd(3)
451 ut.bookCanvas(h,key=
'fitresults',title=
'Fit Results',nx=1600,ny=1200,cx=2,cy=2)
452 cv = h[
'fitresults'].cd(1)
453 h[
'delPOverPz'].Draw(
'box')
454 cv = h[
'fitresults'].cd(2)
457 cv = h[
'fitresults'].cd(3)
458 h[
'delPOverPz_proj'] = h[
'delPOverPz'].ProjectionY()
459 ROOT.gStyle.SetOptFit(11111)
460 h[
'delPOverPz_proj'].Draw()
461 h[
'delPOverPz_proj'].Fit(
'gaus')
462 cv = h[
'fitresults'].cd(4)
463 h[
'delPOverP2z_proj'] = h[
'delPOverP2z'].ProjectionY()
464 h[
'delPOverP2z_proj'].Draw()
466 h[
'fitresults'].Print(
'fitresults.gif')
467 for x
in [
'',
'_pi0']:
468 ut.bookCanvas(h,key=
'fitresults2'+x,title=
'Fit Results '+x,nx=1600,ny=1200,cx=2,cy=2)
469 cv = h[
'fitresults2'+x].cd(1)
471 h[
'Doca'].SetXTitle(
'closest distance between 2 tracks [cm]')
472 h[
'Doca'].SetYTitle(
'N/1mm')
475 h[
'pi0Mass'].SetXTitle(
'#gamma #gamma invariant mass [GeV/c^{2}]')
476 h[
'pi0Mass'].SetYTitle(
'N/'+str(int(h[
'pi0Mass'].GetBinWidth(1)*1000))+
'MeV')
478 fitResult = h[
'pi0Mass'].Fit(
'gaus',
'S',
'',0.08,0.19)
479 cv = h[
'fitresults2'+x].cd(2)
480 h[
'IP0'+x].SetXTitle(
'impact parameter to p-target [cm]')
481 h[
'IP0'+x].SetYTitle(
'N/1cm')
483 cv = h[
'fitresults2'+x].cd(3)
484 h[
'HNL'+x].SetXTitle(
'inv. mass [GeV/c^{2}]')
485 h[
'HNL'+x].SetYTitle(
'N/4MeV/c2')
488 cv = h[
'fitresults2'+x].cd(4)
489 h[
'IP0/mass'+x].SetXTitle(
'inv. mass [GeV/c^{2}]')
490 h[
'IP0/mass'+x].SetYTitle(
'IP [cm]')
491 h[
'IP0/mass'+x].Draw(
'colz')
492 h[
'fitresults2'+x].Print(
'fitresults2'+x+
'.gif')
493 ut.bookCanvas(h,key=
'vxpulls',title=
'Vertex resol and pulls',nx=1600,ny=1200,cx=3,cy=2)
494 cv = h[
'vxpulls'].cd(4)
496 cv = h[
'vxpulls'].cd(5)
498 cv = h[
'vxpulls'].cd(6)
500 cv = h[
'vxpulls'].cd(1)
502 cv = h[
'vxpulls'].cd(2)
504 cv = h[
'vxpulls'].cd(3)
506 ut.bookCanvas(h,key=
'trpulls',title=
'momentum pulls',nx=1600,ny=600,cx=3,cy=1)
507 cv = h[
'trpulls'].cd(1)
508 h[
'pullPOverPx_proj']=h[
'pullPOverPx'].ProjectionY()
509 h[
'pullPOverPx_proj'].Draw()
510 cv = h[
'trpulls'].cd(2)
511 h[
'pullPOverPy_proj']=h[
'pullPOverPy'].ProjectionY()
512 h[
'pullPOverPy_proj'].Draw()
513 cv = h[
'trpulls'].cd(3)
514 h[
'pullPOverPz_proj']=h[
'pullPOverPz'].ProjectionY()
515 h[
'pullPOverPz_proj'].Draw()
516 ut.bookCanvas(h,key=
'vetodecisions',title=
'Veto Detectors',nx=1600,ny=600,cx=4,cy=1)
517 cv = h[
'vetodecisions'].cd(1)
520 cv = h[
'vetodecisions'].cd(2)
523 cv = h[
'vetodecisions'].cd(3)
526 cv = h[
'vetodecisions'].cd(4)
530 print(
'finished making plots')
543 global ecalReconstructed
544 rc = sTree.GetEntry(n)
547 if sTree.GetBranch(
"FitTracks_PR"):
548 sTree.FitTracks = sTree.FitTracks_PR
550 if sTree.GetBranch(
"fitTrack2MC_PR"): sTree.fitTrack2MC = sTree.fitTrack2MC_PR
551 if sTree.GetBranch(
"Particles_PR"): sTree.Particles = sTree.Particles_PR
553 if not sTree.MCTrack.GetEntries()>1: wg = 1.
554 else: wg = sTree.MCTrack[1].GetWeight()
558 if hasattr(sTree,
"EcalClusters"):
559 if calReco: ecalReconstructed.Delete()
560 else: ecalReconstructed = sTree.EcalReconstructed
562 if x.GetName() ==
'ecalFiller': x.Exec(
'start',sTree.EcalPointLite)
563 elif x.GetName() ==
'ecalMatch': x.Exec(
'start',ecalReconstructed,sTree.MCTrack)
564 else : x.Exec(
'start')
565 for aClus
in ecalReconstructed:
566 mMax = aClus.MCTrack()
567 if mMax <0
or mMax > sTree.MCTrack.GetEntries():
569 else: aP = sTree.MCTrack[mMax]
571 tmp = PDG.GetParticle(aP.GetPdgCode())
572 if tmp: pName =
'ecalReconstructed_'+tmp.GetName()
573 else: pName =
'ecalReconstructed_'+str(aP.GetPdgCode())
575 pName =
'ecalReconstructed_unknown'
577 ut.bookHist(h,pName,
'x/y and energy for '+pName.split(
'_')[1],50,-3.,3.,50,-6.,6.)
578 rc = h[pName].Fill(aClus.X()/u.m,aClus.Y()/u.m,aClus.RecoE()/u.GeV)
580 for fT
in sTree.FitTracks:
583 pdgcode = fT.getFittedState().getPDG()
584 tmp = PDG.GetParticle(pdgcode)
585 if tmp: tName =
'ecalReconstructed_dist_'+tmp.GetName()
586 else: tName =
'ecalReconstructed_dist_'+str(aP.GetPdgCode())
588 p = tName.split(
'dist_')[1]
589 ut.bookHist(h,tName,
'Ecal cluster distance t0 '+p,100,0.,100.*u.cm)
590 ut.bookHist(h,tName.replace(
'dist',
'distx'),
'Ecal cluster distance to '+p+
' in X ',100,-50.*u.cm,50.*u.cm)
591 ut.bookHist(h,tName.replace(
'dist',
'disty'),
'Ecal cluster distance to '+p+
' in Y ',100,-50.*u.cm,50.*u.cm)
592 dist = ROOT.TMath.Sqrt( (aClus.X()-pos.X())**2+(aClus.Y()-pos.Y())**2 )
593 rc = h[tName].Fill(dist)
594 rc = h[tName.replace(
'dist',
'distx')].Fill( aClus.X()-pos.X() )
595 rc = h[tName.replace(
'dist',
'disty')].Fill( aClus.Y()-pos.Y() )
597 for aClus
in sTree.EcalClusters:
598 rc = h[
'ecalClusters'].Fill(aClus.X()/u.m,aClus.Y()/u.m,aClus.Energy()/u.GeV)
602 aP = sTree.MCTrack[mMax]
603 tmp = PDG.GetParticle(aP.GetPdgCode())
604 if tmp: pName =
'ecalClusters_'+tmp.GetName()
605 else: pName =
'ecalClusters_'+str(aP.GetPdgCode())
607 pName =
'ecalClusters_unknown'
608 if pName
not in h: ut.bookHist(h,pName,
'x/y and energy for '+pName.split(
'_')[1],50,-3.,3.,50,-6.,6.)
609 rc = h[pName].Fill(aClus.X()/u.m,aClus.Y()/u.m,aClus.Energy()/u.GeV)
613 for ahit
in sTree.strawtubesPoint:
614 detID = ahit.GetDetectorID()
615 top = ROOT.TVector3()
616 bot = ROOT.TVector3()
617 modules[
"Strawtubes"].StrawEndPoints(detID,bot,top)
618 dw = ahit.dist2Wire()
619 if detID < 50000000 :
620 if abs(top.y())==abs(bot.y()): h[
'disty'].Fill(dw)
621 if abs(top.y())>abs(bot.y()): h[
'distu'].Fill(dw)
622 if abs(top.y())<abs(bot.y()): h[
'distv'].Fill(dw)
624 trID = ahit.GetTrackID()
626 if trID
in hitlist: hitlist[trID]+=1
627 else: hitlist[trID]=1
628 for tr
in hitlist: h[
'meanhits'].Fill(hitlist[tr])
631 for atrack
in sTree.FitTracks:
635 fitStatus = atrack.getFitStatus()
636 nmeas = fitStatus.getNdf()
637 h[
'meas'].Fill(nmeas)
638 if not fitStatus.isFitConverged() :
continue
639 h[
'meas2'].Fill(nmeas)
640 if nmeas < measCut:
continue
641 fittedTracks[key] = atrack
643 rchi2 = fitStatus.getChi2()
644 prob = ROOT.TMath.Prob(rchi2,int(nmeas))
647 fittedState = atrack.getFittedState()
648 h[
'chi2'].Fill(chi2,wg)
649 h[
'measVSchi2'].Fill(atrack.getNumPoints(),chi2)
650 P = fittedState.getMomMag()
651 Px,Py,Pz = fittedState.getMom().x(),fittedState.getMom().y(),fittedState.getMom().z()
652 cov = fittedState.get6DCov()
653 if len(sTree.fitTrack2MC)-1<key:
continue
654 mcPartKey = sTree.fitTrack2MC[key]
655 mcPart = sTree.MCTrack[mcPartKey]
656 if not mcPart :
continue
657 Ptruth_start = mcPart.GetP()
658 Ptruthz_start = mcPart.GetPz()
661 delPOverP = (Ptruth - P)/Ptruth
662 h[
'delPOverP'].Fill(Ptruth,delPOverP)
663 delPOverPz = (1./Ptruthz - 1./Pz) * Ptruthz
664 h[
'pullPOverPx'].Fill( Ptruth,(Ptruthx-Px)/ROOT.TMath.Sqrt(cov[3][3]) )
665 h[
'pullPOverPy'].Fill( Ptruth,(Ptruthy-Py)/ROOT.TMath.Sqrt(cov[4][4]) )
666 h[
'pullPOverPz'].Fill( Ptruth,(Ptruthz-Pz)/ROOT.TMath.Sqrt(cov[5][5]) )
667 h[
'delPOverPz'].Fill(Ptruthz,delPOverPz)
668 if chi2>chi2CutOff:
continue
669 h[
'delPOverP2'].Fill(Ptruth,delPOverP)
670 h[
'delPOverP2z'].Fill(Ptruth,delPOverPz)
672 trackDir = fittedState.getDir()
673 trackPos = fittedState.getPos()
675 mcPart.GetStartVertex(vx)
677 for i
in range(3): t += trackDir(i)*(vx(i)-trackPos(i))
679 for i
in range(3): dist += (vx(i)-trackPos(i)-t*trackDir(i))**2
680 dist = ROOT.TMath.Sqrt(dist)
684 for HNL
in sTree.Particles:
685 t1,t2 = HNL.GetDaughter(0),HNL.GetDaughter(1)
688 checkMeasurements =
True
691 fitStatus = sTree.FitTracks[tr].getFitStatus()
692 nmeas = fitStatus.getNdf()
693 if nmeas < measCut: checkMeasurements =
False
694 if not checkMeasurements:
continue
697 HNLPos = ROOT.TLorentzVector()
698 HNL.ProductionVertex(HNLPos)
699 HNLMom = ROOT.TLorentzVector()
706 if not isInFiducial(HNLPos.X(),HNLPos.Y(),HNLPos.Z()):
continue
708 if doca > docaCut :
continue
709 tr = ROOT.TVector3(0,0,ShipGeo.target.z0)
713 rc = h[
'pi0Mass'].Fill(pi0.M())
714 if abs(pi0.M()-0.135)>0.02:
continue
716 HNLwithPi0 = HNLMom + pi0
718 mass = HNLwithPi0.M()
719 h[
'IP0_pi0'].Fill(dist)
720 h[
'IP0/mass_pi0'].Fill(mass,dist)
721 h[
'HNL_pi0'].Fill(mass)
726 h[
'IP0/mass'].Fill(mass,dist)
728 h[
'HNLw'].Fill(mass,wg)
730 vetoDets[
'SBT'] = veto.SBT_decision()
731 vetoDets[
'SVT'] = veto.SVT_decision()
732 vetoDets[
'RPC'] = veto.RPC_decision()
733 vetoDets[
'TRA'] = veto.Track_decision()
734 h[
'nrtracks'].Fill(vetoDets[
'TRA'][2])
735 h[
'nrSVT'].Fill(vetoDets[
'SVT'][2])
736 h[
'nrSBT'].Fill(vetoDets[
'SBT'][2])
737 h[
'nrRPC'].Fill(vetoDets[
'RPC'][2])
739 mctrack = sTree.MCTrack[sTree.fitTrack2MC[t1]]
740 h[
'Vzresol'].Fill( (mctrack.GetStartZ()-HNLPos.Z())/u.cm )
741 h[
'Vxresol'].Fill( (mctrack.GetStartX()-HNLPos.X())/u.cm )
742 h[
'Vyresol'].Fill( (mctrack.GetStartY()-HNLPos.Y())/u.cm )
743 PosDir,newPosDir,CovMat,scalFac = {},{},{},{}
745 newPos = ROOT.TVector3(HNLPos.X(),HNLPos.Y(),HNLPos.Z())
746 st1,st2 = sTree.FitTracks[t1].getFittedState(),sTree.FitTracks[t2].getFittedState()
747 PosDir[t1] = {
'position':st1.getPos(),
'direction':st1.getDir(),
'momentum':st1.getMom()}
748 PosDir[t2] = {
'position':st2.getPos(),
'direction':st2.getDir(),
'momentum':st2.getMom()}
749 CovMat[t1] = st1.get6DCov()
750 CovMat[t2] = st2.get6DCov()
751 rep1,rep2 = ROOT.genfit.RKTrackRep(st1.getPDG()),ROOT.genfit.RKTrackRep(st2.getPDG())
752 state1,state2 = ROOT.genfit.StateOnPlane(rep1),ROOT.genfit.StateOnPlane(rep2)
753 rep1.setPosMom(state1,st1.getPos(),st1.getMom())
754 rep2.setPosMom(state2,st2.getPos(),st2.getMom())
756 rep1.extrapolateToPoint(state1, newPos,
False)
757 rep2.extrapolateToPoint(state2, newPos,
False)
758 mom1,mom2 = rep1.getMom(state1),rep2.getMom(state2)
760 mom1,mom2 = st1.getMom(),st2.getMom()
761 newPosDir[t1] = {
'position':rep1.getPos(state1),
'direction':rep1.getDir(state1),
'momentum':mom1}
762 newPosDir[t2] = {
'position':rep2.getPos(state2),
'direction':rep2.getDir(state2),
'momentum':mom2}
763 oa = mom1.Dot(mom2)/(mom1.Mag()*mom2.Mag())
768 h[
'Vzpull'].Fill( (mctrack.GetStartZ()-HNLPos.Z())/ROOT.TMath.Sqrt(covX[2][2]) )
769 h[
'Vxpull'].Fill( (mctrack.GetStartX()-HNLPos.X())/ROOT.TMath.Sqrt(covX[0][0]) )
770 h[
'Vypull'].Fill( (mctrack.GetStartY()-HNLPos.Y())/ROOT.TMath.Sqrt(covX[1][1]) )
773 if hasattr(ShipGeo,
"TimeDet"):
774 for fT
in sTree.FitTracks:
777 for aPoint
in sTree.TimeDetPoint:
778 h[
'extrapTimeDetX'].Fill(pos.X()-aPoint.GetX())
779 h[
'extrapTimeDetY'].Fill(pos.Y()-aPoint.GetY())