542def myEventLoop(n):
543 global ecalReconstructed
544 rc = sTree.GetEntry(n)
545
546 measCut = measCutFK
547 if sTree.GetBranch("FitTracks_PR"):
548 sTree.FitTracks = sTree.FitTracks_PR
549 measCut = measCutPR
550 if sTree.GetBranch("fitTrack2MC_PR"): sTree.fitTrack2MC = sTree.fitTrack2MC_PR
551 if sTree.GetBranch("Particles_PR"): sTree.Particles = sTree.Particles_PR
552 if not checkHNLorigin(sTree): return
553 if not sTree.MCTrack.GetEntries()>1: wg = 1.
554 else: wg = sTree.MCTrack[1].GetWeight()
555 if not wg>0.: wg=1.
556
557
558 if hasattr(sTree,"EcalClusters"):
559 if calReco: ecalReconstructed.Delete()
560 else: ecalReconstructed = sTree.EcalReconstructed
561 for x in caloTasks:
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():
568 aP = None
569 else: aP = sTree.MCTrack[mMax]
570 if aP:
571 tmp = PDG.GetParticle(aP.GetPdgCode())
572 if tmp: pName = 'ecalReconstructed_'+tmp.GetName()
573 else: pName = 'ecalReconstructed_'+str(aP.GetPdgCode())
574 else:
575 pName = 'ecalReconstructed_unknown'
576 if pName not in h:
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)
579
580 for fT in sTree.FitTracks:
582 if rc:
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())
587 if tName not in h:
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() )
596
597 for aClus in sTree.EcalClusters:
598 rc = h['ecalClusters'].Fill(aClus.X()/u.m,aClus.Y()/u.m,aClus.Energy()/u.GeV)
599 mMax,frac = ecalCluster2MC(aClus)
600
601 if mMax>0:
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())
606 else:
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)
610
611
612 hitlist = {}
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)
623
624 trID = ahit.GetTrackID()
625 if not trID < 0 :
626 if trID in hitlist: hitlist[trID]+=1
627 else: hitlist[trID]=1
628 for tr in hitlist: h['meanhits'].Fill(hitlist[tr])
629 key = -1
630 fittedTracks = {}
631 for atrack in sTree.FitTracks:
632 key+=1
633
634 if not checkFiducialVolume(sTree,key,dy): continue
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
642
643 rchi2 = fitStatus.getChi2()
644 prob = ROOT.TMath.Prob(rchi2,int(nmeas))
645 h['prob'].Fill(prob)
646 chi2 = rchi2/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()
659
660 Ptruth,Ptruthx,Ptruthy,Ptruthz = getPtruthFirst(sTree,mcPartKey)
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)
671
672 trackDir = fittedState.getDir()
673 trackPos = fittedState.getPos()
674 vx = ROOT.TVector3()
675 mcPart.GetStartVertex(vx)
676 t = 0
677 for i in range(3): t += trackDir(i)*(vx(i)-trackPos(i))
678 dist = 0
679 for i in range(3): dist += (vx(i)-trackPos(i)-t*trackDir(i))**2
680 dist = ROOT.TMath.Sqrt(dist)
681 h['IP'].Fill(dist)
682
683
684 for HNL in sTree.Particles:
685 t1,t2 = HNL.GetDaughter(0),HNL.GetDaughter(1)
686
687 if not checkFiducialVolume(sTree,t1,dy) or not checkFiducialVolume(sTree,t2,dy) : continue
688 checkMeasurements = True
689
690 for tr in [t1,t2]:
691 fitStatus = sTree.FitTracks[tr].getFitStatus()
692 nmeas = fitStatus.getNdf()
693 if nmeas < measCut: checkMeasurements = False
694 if not checkMeasurements: continue
695
696 if not match2HNL(HNL): continue
697 HNLPos = ROOT.TLorentzVector()
698 HNL.ProductionVertex(HNLPos)
699 HNLMom = ROOT.TLorentzVector()
700 HNL.Momentum(HNLMom)
701 doca = HNL.GetDoca()
702
703
704
705
706 if not isInFiducial(HNLPos.X(),HNLPos.Y(),HNLPos.Z()): continue
707 h['Doca'].Fill(doca)
708 if doca > docaCut : continue
709 tr = ROOT.TVector3(0,0,ShipGeo.target.z0)
710
711
713 rc = h['pi0Mass'].Fill(pi0.M())
714 if abs(pi0.M()-0.135)>0.02: continue
715
716 HNLwithPi0 = HNLMom + pi0
717 dist = ImpactParameter(tr,HNLPos,HNLwithPi0)
718 mass = HNLwithPi0.M()
719 h['IP0_pi0'].Fill(dist)
720 h['IP0/mass_pi0'].Fill(mass,dist)
721 h['HNL_pi0'].Fill(mass)
722
723 dist = ImpactParameter(tr,HNLPos,HNLMom)
724 mass = HNLMom.M()
725 h['IP0'].Fill(dist)
726 h['IP0/mass'].Fill(mass,dist)
727 h['HNL'].Fill(mass)
728 h['HNLw'].Fill(mass,wg)
729
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])
738
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 = {},{},{},{}
744
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())
755 try:
756 rep1.extrapolateToPoint(state1, newPos, False)
757 rep2.extrapolateToPoint(state2, newPos, False)
758 mom1,mom2 = rep1.getMom(state1),rep2.getMom(state2)
759 except:
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())
764 h['oa'].Fill(oa)
765
766 covX = HNL.GetCovV()
767 dist = HNL.GetDoca()
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]) )
771
772
773 if hasattr(ShipGeo,"TimeDet"):
774 for fT in sTree.FitTracks:
776 if rc:
777 for aPoint in sTree.TimeDetPoint:
778 h['extrapTimeDetX'].Fill(pos.X()-aPoint.GetX())
779 h['extrapTimeDetY'].Fill(pos.Y()-aPoint.GetY())
780
findPi0(sTree, secVertex)