diff --git a/Katerina/AnalyseThat.py b/Katerina/AnalyseThat.py index b60fd8a..30ad33b 100644 --- a/Katerina/AnalyseThat.py +++ b/Katerina/AnalyseThat.py @@ -12,6 +12,8 @@ fiducialCut = False measCut = 25 +ROOT.gROOT.SetBatch(1) + try: opts, args = getopt.getopt(sys.argv[1:], "n:f:g:A:Y:i", ["nEvents=","geoFile="]) except getopt.GetoptError: diff --git a/Katerina/LoopAnalyse.py b/Katerina/LoopAnalyse.py index 19d115c..36ed9c9 100644 --- a/Katerina/LoopAnalyse.py +++ b/Katerina/LoopAnalyse.py @@ -318,6 +318,9 @@ for n in range(nEvents): rc = self.tree.GetEntry(n) + print + print " HO GETTATO L'ENTRY ", n + print self.stat['total'] +=1 # ------------------- MCTracks -----------------------------------------------------------# diff --git a/Katerina/StrawHits.py b/Katerina/StrawHits.py index 21415c3..06fb6a4 100644 --- a/Katerina/StrawHits.py +++ b/Katerina/StrawHits.py @@ -421,32 +421,41 @@ continue posM, momM, covM = self.__prepareIniPosMomCov(trID,old) - + + rep = ROOT.genfit.RKTrackRep(pdg) stateSmeared = ROOT.genfit.MeasuredStateOnPlane(rep) rep.setPosMomCov(stateSmeared, posM, momM, covM) + print "ELENA" + posM.Print() + momM.Print() + covM.Print() seedState = ROOT.TVectorD(6) seedCov = ROOT.TMatrixDSym(6) rep.get6DStateCov(stateSmeared, seedState, seedCov) - + rep.Print() fitTrack[trID] = ROOT.genfit.Track(rep, seedState, seedCov) + print + print + fitTrack[trID].Print() ROOT.SetOwnership(fitTrack[trID], False) if(self.__debug>2): print "preparing measurements for track ID", trID self.__prepareWireMeasurements(trID, fitTrack[trID]) + self.__fitter.Print() if not fitTrack[trID].checkConsistency(): - print 'Problem with track before fit, not consistent',self.fitTrack[atrack] - continue + print 'Problem with track before fit, not consistent',self.fitTrack[atrack] + continue try: self.__fitter.processTrack(fitTrack[trID]) # processTrackWithRep(fitTrack[atrack],rep,True) except: - print "genfit failed to fit track" - continue + print "genfit failed to fit track" + continue if not fitTrack[trID].checkConsistency(): - print 'Problem with track after fit, not consistent',self.fitTrack[atrack] - continue + print 'Problem with track after fit, not consistent',self.fitTrack[atrack] + continue stat = fitTrack[trID].getFitStatus() if not stat.isFitConverged() : continue @@ -457,7 +466,7 @@ #print " pos:", " ".join("{:10.4f}".format(f.getPos()(ii)) for ii in range(0,3)), #print " mom:", " ".join("{:10.4f}".format(f.getMom()(ii)) for ii in range(0,3)) self.__reFitTracks.addNewTrack(trID, f.getPos(), f.getDir(), f.getMomMag(), - stat.getNdf(), stat.getChi2()) + stat.getNdf(), stat.getChi2()) @@ -478,30 +487,33 @@ self.__reFitTracks.Vertex.Print() self.__docaEval.append(self.__reFitTracks.Doca) for tid in fitTrack : - try: - state = fitTrack[tid].getFittedState() - except: - print "can't get fittedState" - flag = -1 - vPosEx = ROOT.TVector3(0,0,0) - vMomEx = ROOT.TVector3(0,0,0) - try : - state.extrapolateToPoint(self.__reFitTracks.Vertex) - except : - flag = -1 - print "track exctrapolation failed!tid: ", tid - if (flag > 0 ) : # - status = fitTrack[tid].getFitStatus() - #print "extr track ", tid, - #print " pos:", " ".join("{:10.4f}".format(state.getPos()(ii)) for ii in range(0,3)), - #print " mom:", " ".join("{:10.4f}".format(state.getMom()(ii)) for ii in range(0,3)) - self.__reFitTracks.addNewTrack(trID, state.getPos(), state.getDir(), state.getMomMag(), - status.getNdf(), status.getChi2(), verb=False) + try: + state = fitTrack[tid].getFittedState() + except: + print "can't get fittedState" + flag = -1 + vPosEx = ROOT.TVector3(0,0,0) + vMomEx = ROOT.TVector3(0,0,0) + try : + state.extrapolateToPoint(self.__reFitTracks.Vertex) + except : + flag = -1 + print "track exctrapolation failed!tid: ", tid + if (flag > 0 ) : # + status = fitTrack[tid].getFitStatus() + #print "extr track ", tid, + #print " pos:", " ".join("{:10.4f}".format(state.getPos()(ii)) for ii in range(0,3)), + #print " mom:", " ".join("{:10.4f}".format(state.getMom()(ii)) for ii in range(0,3)) + self.__reFitTracks.addNewTrack(trID, state.getPos(), state.getDir(), state.getMomMag(), + status.getNdf(), status.getChi2(), verb=False) # FIX temporary self.__reFitTracks.createVertex(newFitTrIDs[0], newFitTrIDs[1], flag) self.__reFitTracks.Vertex.SetY(iniY) theStep+=1 twoTacks = ( len(self.__reFitTracks.getTrIDs())==2 ) + + if len(newFitTrIDs): + assert(False) return len(newFitTrIDs) diff --git a/KaterinaLight/FitTrackInfo.py b/KaterinaLight/FitTrackInfo.py new file mode 100644 index 0000000..1241dcb --- /dev/null +++ b/KaterinaLight/FitTrackInfo.py @@ -0,0 +1,169 @@ +import ROOT,os,sys,getopt +import rootUtils as ut +import shipunit as u + +class FitTrackInfo(object): + + def __init__(self, tree, debug=0): + self.tree = tree + self.debug = debug + self.count = 0 + self.Momentum = {} + self.Direction = {} + self.Position = {} + self.__info = {} + self.Vertex = None + self.Doca = None + # 0 orig, 1 refit, -1 failed refit + self.vertexEFlag = 0 + + def clean(self): + self.count = 0 + self.Momentum.clear() + self.Direction.clear() + self.Position.clear() + self.__info.clear() + self.Vertex = None + self.Doca = None + + def Print(self): + print "FitTrackInfo:" + for tid in self.__info: + print "\t", tid, "{:10.4f}".format(self.__info[tid]['Ndf']), "{:10.4f}".format(self.__info[tid]['Chi2']), + print " pos:", " ".join("{:10.4f}".format(self.Position[tid](ii)) for ii in range(0,3)), + print " mom:", " ".join("{:10.4f}".format(self.Direction[tid](ii)*self.Momentum[tid]) for ii in range(0,3)), + print " P:", "{:10.4f}".format(self.Momentum[tid]) + + ## \brief returns list of keys #__info . + # \return list of MCtrackIDs of fitted tracks. + def getTrIDs(self): + trID = [] + for tid in self.__info: + trID.append(tid) + return trID + + def getNtracks(self) : + return len(self.__info) + + def getChi2Ndf(self, tid): + return self.__info[tid]['Chi2']/self.__info[tid]['Ndf'] + + def getNdf(self, tid): + return self.__info[tid]['Ndf'] + + def compareTracks(self, tid, Pos, Dir, Pval): + false2 = (Pos==None or Dir==None or Pval==None) + false1 = (not tid in self.__info) + if (false2 and false1): return True + if (false2 or false1): return False + return ( (self.Direction[tid]==Dir) and (self.Position[tid]==Pos) and (self.Momentum[tid]==Pval) ) + + + def getPosDirPval(self, tid): + if not tid in self.__info: return None, None, None + return self.Position[tid], self.Direction[tid], self.Momentum[tid] + + def getVertex(self) : + return self.Vertex + + def getDoca(self): + return self.Doca + + def myVertex2(self, t1,t2): + deltaPos =(self.Position[t1]-self.Position[t2]) # A1-A2 + dotDir = self.Direction[t1].Dot(self.Direction[t2]) # a1.a2 + crossDir = self.Direction[t1].Cross(self.Direction[t2]) # a1xa2 + uPerpend = crossDir*(1./crossDir.Mag()) # (a1xa2)/|a1xa2| from a1 to a2 + + minDist = deltaPos.Dot(uPerpend) # (A1-A2).(a1xa2)/|a1xa2| + + # A1 + a1*t1 + (minDist * uPerpend) is (A1 + a1*t1) projected to the plane: + # 1) A2+a2*t2 belons to the plane, + # 2) A1+a1*t1 is parallel to the plane + # cross at t1,t2: A1+a1*t1+(minDist*uPerpend) = A2+a2*t2 + t2X = self.Direction[t2].X() + if (t2X == 0) : t2X = 0.00000000001 + a2a = self.Direction[t2].Y()/t2X + alpha = deltaPos - minDist*uPerpend + nomin = alpha.Y() - a2a*alpha.X() + denom = a2a*self.Direction[t1].X() - self.Direction[t1].Y() + s1 = nomin/denom + s2 = ( alpha.X() + self.Direction[t1].X()*s1 ) / t2X#self.Direction[t2].X() + vec1 = self.Position[t1]+s1*self.Direction[t1] + vec2 = self.Position[t2]+s2*self.Direction[t2] + ave = (vec1+vec2)*0.5 + dif = vec1-vec2 + debugNeed = False + if(abs(abs(minDist)-dif.Mag())>0.00000001): + print "myVertex2 - problem:" + debugNeed = True + if(self.debug>2 or debugNeed): + for tid in (t1,t2): + print str(tid)+": Pos : ", "".join(str(self.Position[tid](ii)) +" " for ii in range(0,3)), + print "\t\tMom : ", "".join(str(self.Direction[tid](ii))+" " for ii in range(0,3)) + print "uPerpend: ","".join(str(uPerpend(ii))+" " for ii in range(0,3)) + if(self.debug>0 or debugNeed): + print "fit vertex: -> 1st poing : ", vec1.X(), vec1.Y(), vec1.Z() + print "fit vertex: -> 2nd point : ", vec2.X(), vec2.Y(), vec2.Z() + print "fit vertex: -> average : ", ave.X(), ave.Y(), ave.Z() + print "distance", abs(minDist), dif.Mag() + return ave, abs(minDist) + + + def readEvent(self): + self.clean() + indx = -1 + for atrack in self.tree.FitTracks: + # kill tracks outside fiducial volume + # if not checkFiducialVolume(sTree,key,dy): continue + fitStatus = atrack.getFitStatus() + if not fitStatus.isFitConverged() : continue + + indx+=1 + mcTrID = self.tree.fitTrack2MC[indx] + + self.__info[mcTrID] = {} + self.__info[mcTrID]['Ndf'] = fitStatus.getNdf() + self.__info[mcTrID]['Chi2'] = fitStatus.getChi2() + + fittedState = atrack.getFittedState() + self.Momentum[mcTrID] = fittedState.getMomMag() + self.Direction[mcTrID] = fittedState.getDir() + self.Position[mcTrID] = fittedState.getPos() + + if(indx>0): + if(indx==1): + self.createVertex(self.__info.keys()[0], self.__info.keys()[1]) + else: + pass + #print "More than 2 fitterd tracks" + return len(self.__info) + + def createVertex(self, tid1, tid2, flag=0): + if( (tid1 in self.__info) and (tid2 in self.__info) ): + self.Vertex, self.Doca = self.myVertex2(tid1, tid2) + self.vertexEFlag = flag + + + def addNewTrack(self, mcTrID, position, direction, Pval, ndf, chi2, verb = True): + if (verb and mcTrID in self.Momentum): + print "FotTrackInfo WARNING - trID ", mcTrID, "already filled! Will rewrite all records for this trID!" + + self.__info[mcTrID]={} + self.__info[mcTrID]['Ndf'] = ndf + self.__info[mcTrID]['Chi2'] = chi2 + + self.Momentum[mcTrID] = Pval + self.Direction[mcTrID] = direction + self.Position[mcTrID] = position + + + def deleteTrack(self, mcTrID): + if mcTrID in self.__info: + del self.__info[mcTrID] + if mcTrID in self.Momentum: + del self.Momentum[mcTrID] + if mcTrID in self.Direction: + del self.Direction[mcTrID] + if mcTrID in self.Position: + del self.Position[mcTrID] \ No newline at end of file diff --git a/KaterinaLight/RecoSettings.py b/KaterinaLight/RecoSettings.py new file mode 100644 index 0000000..ffc3578 --- /dev/null +++ b/KaterinaLight/RecoSettings.py @@ -0,0 +1,25 @@ +# Removed unused imported modules + +import ROOT +import shipunit as u + +""" +Parameter settings for reconstruction +""" + +## min number of hits to produce a track +trackMinNofHits = 25 +trackMinNofStations = 3 +chi2CutOff = 4. +dy = 10.0 +VertexMaxZcut = 2500*u.cm +VertexExtrSteps = 5 +PDG = ROOT.TDatabasePDG.Instance() + +def chargePDG(pdg): + if not PDG.GetParticle(pdg): return + return PDG.GetParticle(pdg).Charge()/(3.) + +def checkEllipticAcc(vec): + Rsq = (vec.X()/(2.45*u.m) )**2 + (vec.Y()/((dy/2.-0.05)*u.m) )**2 + return ( Rsq<1 ) \ No newline at end of file diff --git a/KaterinaLight/StrawHits.py b/KaterinaLight/StrawHits.py new file mode 100644 index 0000000..7092ba7 --- /dev/null +++ b/KaterinaLight/StrawHits.py @@ -0,0 +1,548 @@ +import ROOT,os,sys,getopt +import rootUtils as ut +import shipunit as u +from pythia8_conf import addHNLtoROOT +from array import array + +import RecoSettings +from FitTrackInfo import FitTrackInfo + + +######################################################################## +class StrawHits(object): + """StrawHit class""" + def __init__(self, tree, modules, resolution, debug=0, mhistdict=None, ship_geo=None): + ## root tree to be read. + self.__tree = tree + ## geometry description modules. + self.__modules = modules + ## debug level [0,3] + self.__debug = debug + ## hit resolition + self.__resolution = resolution + ## {MCtrackID : [{'pos':TVector3, 'det':detID, 'dw':distance to wire, 'smdw': smeared dw} where [TVector3] list of each hit position. Created if MCtrackID>0. + self.__trackHits = {} + ## + self.__oldSmearedHits ={} + ## {MCtrackID : {X : TVector3}} where x='entry' or 'exit', TVector3 coordinates of last or first hit. + ## Created for tracks with more than #RecoSettings .trackMinNofHits hits. + self.__trackEdgeHits = {} + ## {MCtrackID : number of hits at Z<0 (veto tracker)}. + self.__vetoHits = {} + ## {MCtrackID: number of crossed stations (exclude veto tracker)}. + self.__nStations = {} + ## root random engent for hit smearing (see #__hitSmear). + self.__random = ROOT.TRandom() + ROOT.gRandom.SetSeed(13) + #fitter = ROOT.genfit.KalmanFitter() + #fitter = ROOT.genfit.KalmanFitterRefTrack() + self.__fitter = ROOT.genfit.DAF() + # refitted traks + self.__reFitTracks = FitTrackInfo(tree=None, debug = self.__debug) + self.__docaEval = [] + + if (mhistdict and ship_geo) : + fm = ROOT.genfit.FieldManager.getInstance() + # copy from python/shipDet_conf.py + sbf = ROOT.ShipBellField("wilfried", ship_geo.Bfield.max,ship_geo.Bfield.z,2,ship_geo.Yheight/2.*u.m ) + for i in range (0,300): + z = 1000. + i*10 + pvec3 = ROOT.TVector3(0,0,z) + fx = ROOT.Double(0) + fy = ROOT.Double(0) + fz = ROOT.Double(0) + #fvec3f = fm.getField().get(pvec3) + fm.getField().get(0,0,z,fx,fy,fz) + fvec3f = ROOT.TVector3(fx,fy,fz) + + fvec3s = ROOT.TVector3( sbf.GetBx(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBy(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBz(pvec3.X(),pvec3.Y(),pvec3.Z())) + + #print z, " ".join("{:10.4f}".format(fvec3f(ii)) for ii in range(0,3)), + #print "\t", " ".join("{:10.4f}".format(fvec3s(ii)) for ii in range(0,3)) + mhistdict['magZfit'].Fill(z,fvec3f.Mag()) + mhistdict['magZsim'].Fill(z,fvec3s.Mag()) + + zdict = {1:2500., 2:2800., 3:3000.} + for zi in zdict: + for xi in range (-30, 30): + for yi in range (-30,30): + x = xi*10. + y = yi*10. + pvec3 = ROOT.TVector3(x, y, zdict[zi]) + fx = ROOT.Double(0) + fy = ROOT.Double(0) + fz = ROOT.Double(0) + #fvec3f = fm.getField().get(pvec3) + fm.getField().get(x,y,zdict[zi],fx,fy,fz) + fvec3f = ROOT.TVector3(fx,fy,fz) + + fvec3s = ROOT.TVector3( sbf.GetBx(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBy(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBz(pvec3.X(),pvec3.Y(),pvec3.Z())) + #print x, " ", y, " ", zdict[zi], + #print "\t", " ".join("{:10.4f}".format(fvec3f(ii)) for ii in range(0,3)), + #print "\t", " ".join("{:10.4f}".format(fvec3s(ii)) for ii in range(0,3)) + mhistdict['magXY'+str(zi)+"fit"].Fill(x, y,fvec3f.Mag()) + mhistdict['magXY'+str(zi)+"sim"].Fill(x, y,fvec3s.Mag()) +######################################################################## + + + ## \brief to be called for each new event (called in #readEvent()) + # cleans all dictionaries (#__trackHits, #__trackEdgeHits, #__vetoHits, #__nStations). + def __clean(self): + self.__trackHits.clear() + self.__oldSmearedHits.clear() + self.__trackEdgeHits.clear() + self.__vetoHits.clear() + self.__nStations.clear() + self.__docaEval = [] +######################################################################## + + + ## \brief returns list of keys #__trackEdgeHits (MCtrackIDs>0 with more than #RecoSettings .trackMinNofHits hits). + # \return list of MCtrackIDs of "good" tracks. + def getTrIDs(self): + trID = [] + for tid in self.__trackEdgeHits: + trID.append(tid) + return trID +######################################################################## + + + ## \brief returns list of keys #__trackHits (MCtrackIDs>0. + # \return list of MCtrackIDs of MC assigned tracks. + def getTrIDsALL(self): + trID = [] + for tid in self.__trackEdgeHits: + trID.append(tid) + return trID +######################################################################## + + + ## \brief returns list of keys #__reFitTracks. + # \return list of MCtrackIDs of "good" tracks. + def getReFitTrIDs(self): + return self.__reFitTracks.getTrIDs() +######################################################################## + + + def getReFitChi2Ndf(self,tid): + return self.__reFitTracks.getChi2Ndf(tid) +######################################################################## + + + def getReFitNdf(self,tid): + return self.__reFitTracks.getNdf(tid) + + + +######################################################################## + ## \brief returns vertex (if number of tracks!=2 will return None!). + # \return new vertex (if number of tracks!=2 will return None!). + def getReFitVertex(self): + return self.__reFitTracks.getVertex() +######################################################################## + + + +######################################################################## + ## \brief returns doca's of given extrapolation steps (size is defined in #RecoSettings .VertexExtrSteps). + # \param step - extrapolation (max step is defined in #RecoSettings .VertexExtrSteps) + # \return doca's of given extrapolation steps. (if number of tracks!=2 will return None!). + def getStepDoca(self, step): + if ( step>RecoSettings.VertexExtrSteps or (not self.__reFitTracks.Vertex) ) : return None + return self.__docaEval[step] +######################################################################## + + +######################################################################## + ## \brief doca's of the last extrapolation step. + # \return doca of the last extrapolation step (if number of tracks!=2 will return None!). + def getDoca(self): + return self.__docaEval[RecoSettings.VertexExtrSteps-1] +######################################################################## + + + ## \brief for a given track id returns position, direction and momentum value of the track. + # \param tid - MCtrackID. + # \return position (TVector3), direction (TVector3) and momentum value of the track. + def getReFitPosDirPval(self, tid): + return self.__reFitTracks.getPosDirPval(tid) +######################################################################## + + + ## \brief returns number of hits in proper tracker stations (Z>0) calculated from #__trackHits and #__vetoHits. + # \param tid - MCtrackID. + # \return number of hits in proper tracker stations (Z>0). + def getNofPHits(self, tid): + return len(self.__trackHits[tid]) - self.__vetoHits[tid] +######################################################################## + + + ## \brief returns TVector3 of a tracker entry hit (Z>0) from #__trackEdgeHits. + # \param tid - MCtrackID. + # \return position of a tracker entry hit (Z>0) from #__trackEdgeHits. + def getStartHit(self, tid): + return self.__trackEdgeHits[tid]['entry'] +######################################################################## + + + ## \brief returns number of hits with Z<0 of #__trackHits. + # \param tid - MCtrackID. + # \return number of hits with Z<0 of #__trackHits. + def checkVetoHits(self, tid): + vh = 0 + if tid in self.__vetoHits: + vh = self.__vetoHits[tid] + return vh +######################################################################## + + + def PrintNewTracks(self): + print "new Fits: ", + self.__reFitTracks.Print() +######################################################################## + + + def compareFitTracks(self, tid, theFitTracks): + pos, direct, pval = theFitTracks.getPosDirPval(tid) + return self.__reFitTracks.compareTracks(tid, pos, direct, pval) + +######################################################################## + ## \brief returns a dictionary {xtop, ytop, z, ybot, ybot, z, dist} for a smeared hit. + # \param tid - MCtrackID. + # \param hid - hit index of #__trackHits + # \param new - to generate new smearing (True) or get from SmearedHits (det.position still recalculated!) + # \return a dictionary {xtop, ytop, z, ybot, ybot, z, dist} for a smeared hit. + def __hitSmear(self,tid,hid, new=False): + top = ROOT.TVector3() + bot = ROOT.TVector3() + dw = self.__trackHits[tid][hid]['dw'] + detID = self.__trackHits[tid][hid]['det'] + + self.__modules["Strawtubes"].StrawEndPoints(detID,bot,top) + + if( new ): + smear = abs(self.__random.Gaus(dw, self.__resolution)) + else: + smear = self.__trackHits[tid][hid]['smdw'] + smearedHit = {'xtop':top.x(),'ytop':top.y(),'z':top.z(),'xbot':bot.x(),'ybot':bot.y(),'z':bot.z(),'dist':smear} + + if(self.__debug>2): + print "\tsmear :", "".join("{:8.2f}".format(self.__trackHits[tid][hid]['pos'](ii)) for ii in range(0,3)), + print "{:6.2f}".format(dw), + print "\t(xt,xb, yt, yb, z, dw) : ", + for x in ['xtop','xbot', 'ytop','ybot','z', 'dist']: + print "".join("{:8.2f}".format(smearedHit[x])), + print "" + return smearedHit +######################################################################## + + + ## \brief to be called per each event. Fills #__trackHits, #__trackEdgeHits, #__vetoHits, #__nStations. + # \return number of "good" tracks (size of #__trackEdgeHits) + def readEvent(self): + self.__clean() + toSort = [] # list of MCtrackID which has unsorted hits (I saw also hits from different tracks assigned to the same MCtrackID) + stationList = {} # {MCtrackID:[stations]} + + # loop over all hits and fill __trackHits[MCtrackID] + hindx = -1 + for ahit in self.__tree.strawtubesPoint: + detID = ahit.GetDetectorID() + trID = ahit.GetTrackID() + + # get old smearing + hindx +=1 + origSmHit = self.__tree.SmearedHits.At(hindx) + if( (abs(ahit.GetZ()-origSmHit[3])>0.8) or (abs(ahit.dist2Wire()-origSmHit[7])>0.2) ): + print "problem getting smeared his, but do not change anything" + print "=>", ahit.GetZ(), origSmHit[3], ahit.dist2Wire(), origSmHit[7] + # m = array('d',[i,sm['xtop'],sm['ytop'],sm['z'],sm['xbot'],sm['ybot'],sm['z'],sm['dist']]) + + #=> + if(trID<0): continue # these are hits not assigned to MC track because low E cut + + if (not self.__trackHits.has_key(trID)): + self.__trackHits[trID] = [] + stationList[trID] = [] + + hinfo = {} + hinfo['pos'] = ROOT.TVector3(ahit.GetX(), ahit.GetY(), ahit.GetZ()) + hinfo['det'] = ahit.GetDetectorID() + hinfo['dw'] = ahit.dist2Wire() + hinfo['smdw'] = origSmHit[7] + self.__trackHits[trID].append(hinfo) + + lastIndx = len(self.__trackHits[trID])-1 + if( self.__trackHits[trID][lastIndx]['pos'].Z() < self.__trackHits[trID][lastIndx-1]['pos'].Z() ): + if( not trID in toSort): + toSort.append(trID) + if(self.__debug>0): print "StrawHitsEntry: wrong order of hits for track ", trID + + station = int(ahit.GetDetectorID()/10000000) + if station > 4 : continue + if ( not station in stationList[trID]) : stationList[trID].append(station) + + # sort + for trID in toSort: + if(self.__debug>0): print "StrawHitsEntry: will sort hits for track ", trID + if(self.__debug>2): + print "\t\thits to be sorted" + for hinfo in self.__trackHits[trID]: + vec3 = hinfo['pos'] + print "\t\t\t\t", vec3.X(), "\t", vec3.Y(), "\t", vec3.Z(), hinfo['dw'] + self.__trackHits[trID].sort(key=lambda x: x['pos'].Z(), reverse=False) + if(self.__debug>2): + print "\t\thits after sorting" + for hinfo in self.__trackHits[trID]: + vec3 = hinfo['pos'] + print "\t\t\t\t", vec3.X(), "\t", vec3.Y(), "\t", vec3.Z(), hinfo['dw'] + + # fill self.__nStations + for trID in self.__trackHits: + self.__nStations[trID] = len(stationList[trID]) + if(self.__debug>0): + print "Number of crossed stations (trID:n)", trID, " : ", self.__nStations[trID] + + # find entry and exit positions + for trID in self.__trackHits: + if(self.__debug>1): + print "hits for trID ", trID + for hinfo in self.__trackHits[trID]: + vec3 = hinfo['pos'] + print "\t", vec3.X(), "\t", vec3.Y(), "\t", vec3.Z(), hinfo['dw'] + if(self.__debug>0): print "start/stop position for hits of track ", trID + #find number of vetoTracker hits + firstHit = 0 + nHits = len(self.__trackHits[trID]) + while( firstHit + # the EdgeHits are filled only if nHits(stations1-4)>25 + if( (firstHitRecoSettings.trackMinNofHits) ): + self.__trackEdgeHits[trID] = {} + self.__trackEdgeHits[trID]['entry'] = self.__trackHits[trID][firstHit]['pos'] + self.__trackEdgeHits[trID]['exit'] = self.__trackHits[trID][-1]['pos'] + self.__vetoHits[trID] = firstHit + if(self.__debug>0): + for pos in self.__trackEdgeHits[trID]: + vec3 = self.__trackEdgeHits[trID][pos] + print "\t", pos, vec3.X(), "\t", vec3.Y(), "\t", vec3.Z() + elif( self.__debug>0): print "not set due to small number of hits" + + return len(self.__trackEdgeHits) +######################################################################## + + + + + + def __getIniDir(self,trID): + v1 = self.__trackEdgeHits[trID]['entry'] + i2 = self.__vetoHits[trID]+1 + if( len(self.__trackHits[trID])>i2 ): + v2 = self.__trackHits[trID][i2]['pos'] + dv = v2-v1 + else: + dv = ROOT.TVector3(0., 0., 1.) + if(self.__debug>0): + print "trying to get initial direction having just one hit, will set (0,0,1)" + return dv*(1./dv.Mag()) + + + def __prepareIniPosMomCov(self, tid, original=True): + if ( original ) : + pos = ROOT.TVector3(0, 0, 0) + mom = ROOT.TVector3(0,0,3.*u.GeV) + cov = ROOT.TMatrixDSym(6) + resolution = self.__resolution + for i in range(3): cov[i][i] = resolution*resolution + cov[0][0]=resolution*resolution*100. + nM = self.getNofPHits(tid) + for i in range(3,6): cov[i][i] = ROOT.TMath.pow(resolution / nM / ROOT.TMath.sqrt(3), 2) + else: + pos = self.__trackEdgeHits[tid]['entry'] + mom = self.__getIniDir(tid) + cov = ROOT.TMatrixDSym(6) + resolution = self.__resolution + for i in range(3): cov[i][i] = resolution*resolution + cov[0][0]=resolution*resolution*100. + nM = self.getNofPHits(tid) + for i in range(3,6): cov[i][i] = ROOT.TMath.pow(resolution / nM / ROOT.TMath.sqrt(3), 2) + return pos, mom, cov +######################################################################## + + + + def __prepareWireMeasurements(self, tid, fTrack): + #WireMeasurement::WireMeasurement(const TVectorD& rawHitCoords, + # const TMatrixDSym& rawHitCov, + # int detId, + # int hitId, + # genfit::TrackPoint* trackPoint) + # per each proper hit TMP ??? does it make sense to do for tracks with __vetoHits>0??? + #self.__measurements4fit[trID] = [] + for hindx in range (self.__vetoHits[tid], len(self.__trackHits[tid])): + sm = self.__hitSmear(tid,hindx) + mVector = ROOT.TVectorD(7,array('d',[sm['xtop'],sm['ytop'],sm['z'],sm['xbot'],sm['ybot'],sm['z'],sm['dist']])) + #self.__measurements4fit[trID].push_back(mVector) + + hitCov = ROOT.TMatrixDSym(7) + hitCov[6][6] = self.__resolution*self.__resolution + + tp = ROOT.genfit.TrackPoint(fTrack) # note how the point is told which track it belongs to + measurement = ROOT.genfit.WireMeasurement(mVector,hitCov,1,6,tp) # the measurement is told which trackpoint it belongs to + # print measurement.getMaxDistance() + measurement.setMaxDistance(0.5*u.cm) + #measurement.setLeftRightResolution(-1) + tp.addRawMeasurement(measurement) # package measurement in the TrackPoint + if(self.__debug>2): + tp.Print() + fTrack.insertPoint(tp) # add point to Track + + + +######################################################################## + ## \brief fix for more than 2 track case - cleans self.__reFitTracks - \b to \b be \b optimized + # calculates (linearly) vertex from all combinations and finds the two givin best doca + def __cleanTracksToFormVertex(self): + newFitTrIDs = self.__reFitTracks.getTrIDs() + thelist = [] + for tid1 in newFitTrIDs: + for tid2 in newFitTrIDs: + if tid2<=tid1 : continue + v, doca = self.__reFitTracks.myVertex2(tid1, tid2) + thelist.append([doca, tid1,tid2]) + thelist.sort() + for tid in newFitTrIDs: + if ( (tid!=thelist[0][1]) and (tid!=thelist[0][2]) ): + self.__reFitTracks.deleteTrack(tid) + +######################################################################## + def FitTracks(self, old=True): + + self.__reFitTracks.clean() + + fitTrack = {} + #self.__measurements4fit = {} + nTrack = -1 + + + for trID in self.__trackEdgeHits : # these are already tracks with large number of hits + #print "track entry", self.__trackEdgeHits[tid]['entry']. + #print "mfield: ", ROOT + + # minimal requirements on number of crossed stations + if ( self.__nStations2): print "preparing measurements for track ID", trID + self.__prepareWireMeasurements(trID, fitTrack[trID]) + + + if not fitTrack[trID].checkConsistency(): + print 'Problem with track before fit, not consistent',self.fitTrack[atrack] + continue + try: self.__fitter.processTrack(fitTrack[trID]) # processTrackWithRep(fitTrack[atrack],rep,True) + except: + print "genfit failed to fit track" + continue + if not fitTrack[trID].checkConsistency(): + print 'Problem with track after fit, not consistent',self.fitTrack[atrack] + continue + + stat = fitTrack[trID].getFitStatus() + if not stat.isFitConverged() : continue + f = fitTrack[trID].getFittedState() + if( (stat.getNdf()>0) and (self.__vetoHits[trID]==0) ): + self.__reFitTracks.addNewTrack(trID, f.getPos(), f.getDir(), f.getMomMag(), + stat.getNdf(), stat.getChi2()) + if(self.__debug>0): + print "for track ", trID, + print " pos:", " ".join("{:10.4f}".format(f.getPos()(ii)) for ii in range(0,3)), + print " mom:", " ".join("{:10.4f}".format(f.getMom()(ii)) for ii in range(0,3)) + + + + newFitTrIDs = self.__reFitTracks.getTrIDs() + + # FIXme! make it more reasonable way and optimize! + if len(newFitTrIDs)>2: + if(self.__debug>0): + print "cleaning large multiplicity event!\nbefore:" + self.__reFitTracks.Print() + + self.__cleanTracksToFormVertex() + + if(self.__debug>0): + print "cleaning large multiplicity event!\nafter:" + self.__reFitTracks.Print() + + newFitTrIDs = self.__reFitTracks.getTrIDs() + if len(newFitTrIDs)>2: + print "track re-fitting finds more than 2 tracks and was not able to clean the event - skipping" + return len(newFitTrIDs) + + twoTracks = ( len(newFitTrIDs)==2 ) + theStep = 0 + self.__docaEval = [] + if (twoTracks) : + self.__reFitTracks.createVertex(newFitTrIDs[0], newFitTrIDs[1], flag=0) # original + iniDoca = self.__reFitTracks.Doca + iniY = self.__reFitTracks.Vertex.Y() + while ( theStep1): + print "==>vertex ", theStep, " ", self.__reFitTracks.Doca + self.__reFitTracks.Vertex.Print() + self.__docaEval.append(self.__reFitTracks.Doca) + for tid in newFitTrIDs : + try: + state = fitTrack[tid].getFittedState() + except: + print "can't get fittedState" + flag = -1 + vPosEx = ROOT.TVector3(0,0,0) + vMomEx = ROOT.TVector3(0,0,0) + try : + state.extrapolateToPoint(self.__reFitTracks.Vertex) + except : + flag = -1 + print "track exctrapolation failed!tid: ", tid + if (flag > 0 ) : # + status = fitTrack[tid].getFitStatus() + #print "=>", tid, status.getNdf() + #print "extr track ", tid, + #print " pos:", " ".join("{:10.4f}".format(state.getPos()(ii)) for ii in range(0,3)), + #print " mom:", " ".join("{:10.4f}".format(state.getMom()(ii)) for ii in range(0,3)) + self.__reFitTracks.addNewTrack(tid, state.getPos(), state.getDir(), state.getMomMag(), + status.getNdf(), status.getChi2(), verb=False) + # FIX temporary + self.__reFitTracks.createVertex(newFitTrIDs[0], newFitTrIDs[1], flag) + self.__reFitTracks.Vertex.SetY(iniY) + theStep+=1 + twoTacks = ( len(self.__reFitTracks.getTrIDs())==2 ) + return len(newFitTrIDs) + + diff --git a/SWforYandex/KaterinaLight/FitTrackInfo.py b/SWforYandex/KaterinaLight/FitTrackInfo.py new file mode 100644 index 0000000..2b7fa33 --- /dev/null +++ b/SWforYandex/KaterinaLight/FitTrackInfo.py @@ -0,0 +1,158 @@ +import ROOT,os,sys,getopt +import rootUtils as ut +import shipunit as u + +class FitTrackInfo(object): + + def __init__(self, tree, debug=0): + self.tree = tree + self.debug = debug + self.count = 0 + self.Momentum = {} + self.Direction = {} + self.Position = {} + self.__info = {} + self.Vertex = None + self.Doca = None + # 0 orig, 1 refit, -1 failed refit + self.vertexEFlag = 0 + + def clean(self): + self.count = 0 + self.Momentum.clear() + self.Direction.clear() + self.Position.clear() + self.__info.clear() + self.Vertex = None + self.Doca = None + + def Print(self): + print "FitTrackInfo:" + for tid in self.__info: + print "\t", tid, "{:10.4f}".format(self.__info[tid]['Ndf']), "{:10.4f}".format(self.__info[tid]['Chi2']), + print " pos:", " ".join("{:10.4f}".format(self.Position[tid](ii)) for ii in range(0,3)), + print " mom:", " ".join("{:10.4f}".format(self.Direction[tid](ii)*self.Momentum[tid]) for ii in range(0,3)), + print " P:", "{:10.4f}".format(self.Momentum[tid]) + + ## \brief returns list of keys #__info . + # \return list of MCtrackIDs of fitted tracks. + def getTrIDs(self): + trID = [] + for tid in self.__info: + trID.append(tid) + return trID + + def getNtracks(self) : + return len(self.__info) + + def getChi2Ndf(self, tid): + return self.__info[tid]['Chi2']/self.__info[tid]['Ndf'] + + def getNdf(self, tid): + return self.__info[tid]['Ndf'] + + def compareTracks(self, tid, Pos, Dir, Pval): + false2 = (Pos==None or Dir==None or Pval==None) + false1 = (not tid in self.__info) + if (false2 and false1): return True + if (false2 or false1): return False + return ( (self.Direction[tid]==Dir) and (self.Position[tid]==Pos) and (self.Momentum[tid]==Pval) ) + + + def getPosDirPval(self, tid): + if not tid in self.__info: return None, None, None + return self.Position[tid], self.Direction[tid], self.Momentum[tid] + + def getVertex(self) : + return self.Vertex + + def getDoca(self): + return self.Doca + + def myVertex2(self, t1,t2): + deltaPos =(self.Position[t1]-self.Position[t2]) # A1-A2 + dotDir = self.Direction[t1].Dot(self.Direction[t2]) # a1.a2 + crossDir = self.Direction[t1].Cross(self.Direction[t2]) # a1xa2 + uPerpend = crossDir*(1./crossDir.Mag()) # (a1xa2)/|a1xa2| from a1 to a2 + + minDist = deltaPos.Dot(uPerpend) # (A1-A2).(a1xa2)/|a1xa2| + + # A1 + a1*t1 + (minDist * uPerpend) is (A1 + a1*t1) projected to the plane: + # 1) A2+a2*t2 belons to the plane, + # 2) A1+a1*t1 is parallel to the plane + # cross at t1,t2: A1+a1*t1+(minDist*uPerpend) = A2+a2*t2 + t2X = self.Direction[t2].X() + if (t2X == 0) : t2X = 0.00000000001 + a2a = self.Direction[t2].Y()/t2X + alpha = deltaPos - minDist*uPerpend + nomin = alpha.Y() - a2a*alpha.X() + denom = a2a*self.Direction[t1].X() - self.Direction[t1].Y() + s1 = nomin/denom + s2 = ( alpha.X() + self.Direction[t1].X()*s1 ) / t2X#self.Direction[t2].X() + vec1 = self.Position[t1]+s1*self.Direction[t1] + vec2 = self.Position[t2]+s2*self.Direction[t2] + ave = (vec1+vec2)*0.5 + dif = vec1-vec2 + debugNeed = False + if(abs(abs(minDist)-dif.Mag())>0.00000001): + print "myVertex2 - problem:" + debugNeed = True + if(self.debug>2 or debugNeed): + for tid in (t1,t2): + print str(tid)+": Pos : ", "".join(str(self.Position[tid](ii)) +" " for ii in range(0,3)), + print "\t\tMom : ", "".join(str(self.Direction[tid](ii))+" " for ii in range(0,3)) + print "uPerpend: ","".join(str(uPerpend(ii))+" " for ii in range(0,3)) + if(self.debug>1 or debugNeed): + print "fit vertex: -> 1st poing : ", vec1.X(), vec1.Y(), vec1.Z() + print "fit vertex: -> 2nd point : ", vec2.X(), vec2.Y(), vec2.Z() + print "fit vertex: -> average : ", ave.X(), ave.Y(), ave.Z() + print "distance", abs(minDist), dif.Mag() + return ave, abs(minDist) + + + def readEvent(self): + self.clean() + indx = -1 + for atrack in self.tree.FitTracks: + # kill tracks outside fiducial volume + # if not checkFiducialVolume(sTree,key,dy): continue + fitStatus = atrack.getFitStatus() + if not fitStatus.isFitConverged() : continue + + indx+=1 + mcTrID = self.tree.fitTrack2MC[indx] + + self.__info[mcTrID] = {} + self.__info[mcTrID]['Ndf'] = fitStatus.getNdf() + self.__info[mcTrID]['Chi2'] = fitStatus.getChi2() + + fittedState = atrack.getFittedState() + self.Momentum[mcTrID] = fittedState.getMomMag() + self.Direction[mcTrID] = fittedState.getDir() + self.Position[mcTrID] = fittedState.getPos() + + if(indx>0): + if(indx==1): + self.createVertex(self.__info.keys()[0], self.__info.keys()[1]) + else: + pass + #print "More than 2 fitterd tracks" + return len(self.__info) + + def createVertex(self, tid1, tid2, flag=0): + if( (tid1 in self.__info) and (tid2 in self.__info) ): + self.Vertex, self.Doca = self.myVertex2(tid1, tid2) + self.vertexEFlag = flag + + def addNewTrack(self, mcTrID, position, direction, Pval, ndf, chi2, verb = True): + if (verb and mcTrID in self.Momentum): + print "FotTrackInfo WARNING - trID ", mcTrID, "already filled! Will rewrite all records for this trID!" + + self.__info[mcTrID]={} + self.__info[mcTrID]['Ndf'] = ndf + self.__info[mcTrID]['Chi2'] = chi2 + + self.Momentum[mcTrID] = Pval + self.Direction[mcTrID] = direction + self.Position[mcTrID] = position + \ No newline at end of file diff --git a/SWforYandex/KaterinaLight/RecoSettings.py b/SWforYandex/KaterinaLight/RecoSettings.py new file mode 100644 index 0000000..ffc3578 --- /dev/null +++ b/SWforYandex/KaterinaLight/RecoSettings.py @@ -0,0 +1,25 @@ +# Removed unused imported modules + +import ROOT +import shipunit as u + +""" +Parameter settings for reconstruction +""" + +## min number of hits to produce a track +trackMinNofHits = 25 +trackMinNofStations = 3 +chi2CutOff = 4. +dy = 10.0 +VertexMaxZcut = 2500*u.cm +VertexExtrSteps = 5 +PDG = ROOT.TDatabasePDG.Instance() + +def chargePDG(pdg): + if not PDG.GetParticle(pdg): return + return PDG.GetParticle(pdg).Charge()/(3.) + +def checkEllipticAcc(vec): + Rsq = (vec.X()/(2.45*u.m) )**2 + (vec.Y()/((dy/2.-0.05)*u.m) )**2 + return ( Rsq<1 ) \ No newline at end of file diff --git a/SWforYandex/KaterinaLight/StrawHits.py b/SWforYandex/KaterinaLight/StrawHits.py new file mode 100644 index 0000000..ca9b692 --- /dev/null +++ b/SWforYandex/KaterinaLight/StrawHits.py @@ -0,0 +1,516 @@ +import ROOT,os,sys,getopt +import rootUtils as ut +import shipunit as u +from pythia8_conf import addHNLtoROOT +from array import array + +import RecoSettings +from FitTrackInfo import FitTrackInfo + + +######################################################################## +class StrawHits(object): + """StrawHit class""" + def __init__(self, tree, modules, resolution, debug=0, mhistdict=None, ship_geo=None): + ## root tree to be read. + self.__tree = tree + ## geometry description modules. + self.__modules = modules + ## debug level [0,3] + self.__debug = debug + ## hit resolition + self.__resolution = resolution + ## {MCtrackID : [{'pos':TVector3, 'det':detID, 'dw':distance to wire, 'smdw': smeared dw} where [TVector3] list of each hit position. Created if MCtrackID>0. + self.__trackHits = {} + ## + self.__oldSmearedHits ={} + ## {MCtrackID : {X : TVector3}} where x='entry' or 'exit', TVector3 coordinates of last or first hit. + ## Created for tracks with more than #RecoSettings .trackMinNofHits hits. + self.__trackEdgeHits = {} + ## {MCtrackID : number of hits at Z<0 (veto tracker)}. + self.__vetoHits = {} + ## {MCtrackID: number of crossed stations (exclude veto tracker)}. + self.__nStations = {} + ## root random engent for hit smearing (see #__hitSmear). + self.__random = ROOT.TRandom() + ROOT.gRandom.SetSeed(13) + #fitter = ROOT.genfit.KalmanFitter() + #fitter = ROOT.genfit.KalmanFitterRefTrack() + self.__fitter = ROOT.genfit.DAF() + # refitted traks + self.__reFitTracks = FitTrackInfo(tree=None, debug = self.__debug) + self.__docaEval = [] + + if (mhistdict and ship_geo) : + fm = ROOT.genfit.FieldManager.getInstance() + # copy from python/shipDet_conf.py + sbf = ROOT.ShipBellField("wilfried", ship_geo.Bfield.max,ship_geo.Bfield.z,2,ship_geo.Yheight/2.*u.m ) + for i in range (0,300): + z = 1000. + i*10 + pvec3 = ROOT.TVector3(0,0,z) + fx = ROOT.Double(0) + fy = ROOT.Double(0) + fz = ROOT.Double(0) + #fvec3f = fm.getField().get(pvec3) + fm.getField().get(0,0,z,fx,fy,fz) + fvec3f = ROOT.TVector3(fx,fy,fz) + + fvec3s = ROOT.TVector3( sbf.GetBx(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBy(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBz(pvec3.X(),pvec3.Y(),pvec3.Z())) + + #print z, " ".join("{:10.4f}".format(fvec3f(ii)) for ii in range(0,3)), + #print "\t", " ".join("{:10.4f}".format(fvec3s(ii)) for ii in range(0,3)) + mhistdict['magZfit'].Fill(z,fvec3f.Mag()) + mhistdict['magZsim'].Fill(z,fvec3s.Mag()) + + zdict = {1:2500., 2:2800., 3:3000.} + for zi in zdict: + for xi in range (-30, 30): + for yi in range (-30,30): + x = xi*10. + y = yi*10. + pvec3 = ROOT.TVector3(x, y, zdict[zi]) + fx = ROOT.Double(0) + fy = ROOT.Double(0) + fz = ROOT.Double(0) + #fvec3f = fm.getField().get(pvec3) + fm.getField().get(x,y,zdict[zi],fx,fy,fz) + fvec3f = ROOT.TVector3(fx,fy,fz) + + fvec3s = ROOT.TVector3( sbf.GetBx(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBy(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBz(pvec3.X(),pvec3.Y(),pvec3.Z())) + #print x, " ", y, " ", zdict[zi], + #print "\t", " ".join("{:10.4f}".format(fvec3f(ii)) for ii in range(0,3)), + #print "\t", " ".join("{:10.4f}".format(fvec3s(ii)) for ii in range(0,3)) + mhistdict['magXY'+str(zi)+"fit"].Fill(x, y,fvec3f.Mag()) + mhistdict['magXY'+str(zi)+"sim"].Fill(x, y,fvec3s.Mag()) +######################################################################## + + + ## \brief to be called for each new event (called in #readEvent()) + # cleans all dictionaries (#__trackHits, #__trackEdgeHits, #__vetoHits, #__nStations). + def __clean(self): + self.__trackHits.clear() + self.__oldSmearedHits.clear() + self.__trackEdgeHits.clear() + self.__vetoHits.clear() + self.__nStations.clear() + self.__docaEval = [] +######################################################################## + + + ## \brief returns list of keys #__trackEdgeHits (MCtrackIDs>0 with more than #RecoSettings .trackMinNofHits hits). + # \return list of MCtrackIDs of "good" tracks. + def getTrIDs(self): + trID = [] + for tid in self.__trackEdgeHits: + trID.append(tid) + return trID +######################################################################## + + + ## \brief returns list of keys #__trackHits (MCtrackIDs>0. + # \return list of MCtrackIDs of MC assigned tracks. + def getTrIDsALL(self): + trID = [] + for tid in self.__trackEdgeHits: + trID.append(tid) + return trID +######################################################################## + + + ## \brief returns list of keys #__reFitTracks. + # \return list of MCtrackIDs of "good" tracks. + def getReFitTrIDs(self): + return self.__reFitTracks.getTrIDs() +######################################################################## + + + def getReFitChi2Ndf(self,tid): + return self.__reFitTracks.getChi2Ndf(tid) +######################################################################## + + + def getReFitNdf(self,tid): + return self.__reFitTracks.getNdf(tid) + + + +######################################################################## + ## \brief returns vertex (if number of tracks!=2 will return None!). + # \return new vertex (if number of tracks!=2 will return None!). + def getReFitVertex(self): + return self.__reFitTracks.getVertex() +######################################################################## + + + +######################################################################## + ## \brief returns doca's of given extrapolation steps (size is defined in #RecoSettings .VertexExtrSteps). + # \param step - extrapolation (max step is defined in #RecoSettings .VertexExtrSteps) + # \return doca's of given extrapolation steps. (if number of tracks!=2 will return None!). + def getStepDoca(self, step): + if ( step>RecoSettings.VertexExtrSteps or (not self.__reFitTracks.Vertex) ) : return None + return self.__docaEval[step] +######################################################################## + + +######################################################################## + ## \brief doca's of the last extrapolation step. + # \return doca of the last extrapolation step (if number of tracks!=2 will return None!). + def getDoca(self): + return self.__docaEval[RecoSettings.VertexExtrSteps-1] +######################################################################## + + + ## \brief for a given track id returns position, direction and momentum value of the track. + # \param tid - MCtrackID. + # \return position (TVector3), direction (TVector3) and momentum value of the track. + def getReFitPosDirPval(self, tid): + return self.__reFitTracks.getPosDirPval(tid) +######################################################################## + + + ## \brief returns number of hits in proper tracker stations (Z>0) calculated from #__trackHits and #__vetoHits. + # \param tid - MCtrackID. + # \return number of hits in proper tracker stations (Z>0). + def getNofPHits(self, tid): + return len(self.__trackHits[tid]) - self.__vetoHits[tid] +######################################################################## + + + ## \brief returns TVector3 of a tracker entry hit (Z>0) from #__trackEdgeHits. + # \param tid - MCtrackID. + # \return position of a tracker entry hit (Z>0) from #__trackEdgeHits. + def getStartHit(self, tid): + return self.__trackEdgeHits[tid]['entry'] +######################################################################## + + + ## \brief returns number of hits with Z<0 of #__trackHits. + # \param tid - MCtrackID. + # \return number of hits with Z<0 of #__trackHits. + def checkVetoHits(self, tid): + vh = 0 + if tid in self.__vetoHits: + vh = self.__vetoHits[tid] + return vh +######################################################################## + + + def PrintNewTracks(self): + print "new Fits: ", + self.__reFitTracks.Print() +######################################################################## + + + def compareFitTracks(self, tid, theFitTracks): + pos, direct, pval = theFitTracks.getPosDirPval(tid) + return self.__reFitTracks.compareTracks(tid, pos, direct, pval) + +######################################################################## + ## \brief returns a dictionary {xtop, ytop, z, ybot, ybot, z, dist} for a smeared hit. + # \param tid - MCtrackID. + # \param hid - hit index of #__trackHits + # \param new - to generate new smearing (True) or get from SmearedHits (det.position still recalculated!) + # \return a dictionary {xtop, ytop, z, ybot, ybot, z, dist} for a smeared hit. + def __hitSmear(self,tid,hid, new=False): + top = ROOT.TVector3() + bot = ROOT.TVector3() + dw = self.__trackHits[tid][hid]['dw'] + detID = self.__trackHits[tid][hid]['det'] + + self.__modules["Strawtubes"].StrawEndPoints(detID,bot,top) + + if( new ): + smear = abs(self.__random.Gaus(dw, self.__resolution)) + else: + smear = self.__trackHits[tid][hid]['smdw'] + smearedHit = {'xtop':top.x(),'ytop':top.y(),'z':top.z(),'xbot':bot.x(),'ybot':bot.y(),'z':bot.z(),'dist':smear} + + if(self.__debug>2): + print "\tsmear :", "".join("{:8.2f}".format(self.__trackHits[tid][hid]['pos'](ii)) for ii in range(0,3)), + print "{:6.2f}".format(dw), + print "\t(xt,xb, yt, yb, z, dw) : ", + for x in ['xtop','xbot', 'ytop','ybot','z', 'dist']: + print "".join("{:8.2f}".format(smearedHit[x])), + print "" + return smearedHit +######################################################################## + + + ## \brief to be called per each event. Fills #__trackHits, #__trackEdgeHits, #__vetoHits, #__nStations. + # \return number of "good" tracks (size of #__trackEdgeHits) + def readEvent(self): + self.__clean() + toSort = [] # list of MCtrackID which has unsorted hits (I saw also hits from different tracks assigned to the same MCtrackID) + stationList = {} # {MCtrackID:[stations]} + + # loop over all hits and fill __trackHits[MCtrackID] + hindx = -1 + for ahit in self.__tree.strawtubesPoint: + detID = ahit.GetDetectorID() + trID = ahit.GetTrackID() + + # get old smearing + hindx +=1 + origSmHit = self.__tree.SmearedHits.At(hindx) + if( (abs(ahit.GetZ()-origSmHit[3])>0.8) or (abs(ahit.dist2Wire()-origSmHit[7])>0.2) ): + print "problem getting smeared his, but do not change anything" + print "=>", ahit.GetZ(), origSmHit[3], ahit.dist2Wire(), origSmHit[7] + # m = array('d',[i,sm['xtop'],sm['ytop'],sm['z'],sm['xbot'],sm['ybot'],sm['z'],sm['dist']]) + + #=> + if(trID<0): continue # these are hits not assigned to MC track because low E cut + + if (not self.__trackHits.has_key(trID)): + self.__trackHits[trID] = [] + stationList[trID] = [] + + hinfo = {} + hinfo['pos'] = ROOT.TVector3(ahit.GetX(), ahit.GetY(), ahit.GetZ()) + hinfo['det'] = ahit.GetDetectorID() + hinfo['dw'] = ahit.dist2Wire() + hinfo['smdw'] = origSmHit[7] + self.__trackHits[trID].append(hinfo) + + lastIndx = len(self.__trackHits[trID])-1 + if( self.__trackHits[trID][lastIndx]['pos'].Z() < self.__trackHits[trID][lastIndx-1]['pos'].Z() ): + if( not trID in toSort): + toSort.append(trID) + if(self.__debug>0): print "StrawHitsEntry: wrong order of hits for track ", trID + + station = int(ahit.GetDetectorID()/10000000) + if station > 4 : continue + if ( not station in stationList[trID]) : stationList[trID].append(station) + + # sort + for trID in toSort: + if(self.__debug>0): print "StrawHitsEntry: will sort hits for track ", trID + if(self.__debug>2): + print "\t\thits to be sorted" + for hinfo in self.__trackHits[trID]: + vec3 = hinfo['pos'] + print "\t\t\t\t", vec3.X(), "\t", vec3.Y(), "\t", vec3.Z(), hinfo['dw'] + self.__trackHits[trID].sort(key=lambda x: x['pos'].Z(), reverse=False) + if(self.__debug>2): + print "\t\thits after sorting" + for hinfo in self.__trackHits[trID]: + vec3 = hinfo['pos'] + print "\t\t\t\t", vec3.X(), "\t", vec3.Y(), "\t", vec3.Z(), hinfo['dw'] + + # fill self.__nStations + for trID in self.__trackHits: + self.__nStations[trID] = len(stationList[trID]) + if(self.__debug>0): + print "Number of crossed stations (trID:n)", trID, " : ", self.__nStations[trID] + + # find entry and exit positions + for trID in self.__trackHits: + if(self.__debug>1): + print "hits for trID ", trID + for hinfo in self.__trackHits[trID]: + vec3 = hinfo['pos'] + print "\t", vec3.X(), "\t", vec3.Y(), "\t", vec3.Z(), hinfo['dw'] + if(self.__debug>0): print "start/stop position for hits of track ", trID + #find number of vetoTracker hits + firstHit = 0 + nHits = len(self.__trackHits[trID]) + while( firstHit + # the EdgeHits are filled only if nHits(stations1-4)>25 + if( (firstHitRecoSettings.trackMinNofHits) ): + self.__trackEdgeHits[trID] = {} + self.__trackEdgeHits[trID]['entry'] = self.__trackHits[trID][firstHit]['pos'] + self.__trackEdgeHits[trID]['exit'] = self.__trackHits[trID][-1]['pos'] + self.__vetoHits[trID] = firstHit + if(self.__debug>0): + for pos in self.__trackEdgeHits[trID]: + vec3 = self.__trackEdgeHits[trID][pos] + print "\t", pos, vec3.X(), "\t", vec3.Y(), "\t", vec3.Z() + elif( self.__debug>0): print "not set due to small number of hits" + + return len(self.__trackEdgeHits) +######################################################################## + + + + + + def __getIniDir(self,trID): + v1 = self.__trackEdgeHits[trID]['entry'] + i2 = self.__vetoHits[trID]+1 + if( len(self.__trackHits[trID])>i2 ): + v2 = self.__trackHits[trID][i2]['pos'] + dv = v2-v1 + else: + dv = ROOT.TVector3(0., 0., 1.) + if(self.__debug>0): + print "trying to get initial direction having just one hit, will set (0,0,1)" + return dv*(1./dv.Mag()) + + + def __prepareIniPosMomCov(self, tid, original=True): + if ( original ) : + pos = ROOT.TVector3(0, 0, 0) + mom = ROOT.TVector3(0,0,3.*u.GeV) + cov = ROOT.TMatrixDSym(6) + resolution = self.__resolution + for i in range(3): cov[i][i] = resolution*resolution + cov[0][0]=resolution*resolution*100. + nM = self.getNofPHits(tid) + for i in range(3,6): cov[i][i] = ROOT.TMath.pow(resolution / nM / ROOT.TMath.sqrt(3), 2) + else: + pos = self.__trackEdgeHits[tid]['entry'] + mom = self.__getIniDir(tid) + cov = ROOT.TMatrixDSym(6) + resolution = self.__resolution + for i in range(3): cov[i][i] = resolution*resolution + cov[0][0]=resolution*resolution*100. + nM = self.getNofPHits(tid) + for i in range(3,6): cov[i][i] = ROOT.TMath.pow(resolution / nM / ROOT.TMath.sqrt(3), 2) + return pos, mom, cov +######################################################################## + + + + def __prepareWireMeasurements(self, tid, fTrack): + #WireMeasurement::WireMeasurement(const TVectorD& rawHitCoords, + # const TMatrixDSym& rawHitCov, + # int detId, + # int hitId, + # genfit::TrackPoint* trackPoint) + # per each proper hit TMP ??? does it make sense to do for tracks with __vetoHits>0??? + #self.__measurements4fit[trID] = [] + for hindx in range (self.__vetoHits[tid], len(self.__trackHits[tid])): + sm = self.__hitSmear(tid,hindx) + mVector = ROOT.TVectorD(7,array('d',[sm['xtop'],sm['ytop'],sm['z'],sm['xbot'],sm['ybot'],sm['z'],sm['dist']])) + #self.__measurements4fit[trID].push_back(mVector) + + hitCov = ROOT.TMatrixDSym(7) + hitCov[6][6] = self.__resolution*self.__resolution + + tp = ROOT.genfit.TrackPoint(fTrack) # note how the point is told which track it belongs to + measurement = ROOT.genfit.WireMeasurement(mVector,hitCov,1,6,tp) # the measurement is told which trackpoint it belongs to + # print measurement.getMaxDistance() + measurement.setMaxDistance(0.5*u.cm) + #measurement.setLeftRightResolution(-1) + tp.addRawMeasurement(measurement) # package measurement in the TrackPoint + if(self.__debug>2): + tp.Print() + fTrack.insertPoint(tp) # add point to Track + + + + + + +######################################################################## + def FitTracks(self, old=True): + + self.__reFitTracks.clean() + + fitTrack = {} + #self.__measurements4fit = {} + nTrack = -1 + + + for trID in self.__trackEdgeHits : # these are already tracks with large number of hits + #print "track entry", self.__trackEdgeHits[tid]['entry']. + #print "mfield: ", ROOT + + # minimal requirements on number of crossed stations + if ( self.__nStations2): print "preparing measurements for track ID", trID + self.__prepareWireMeasurements(trID, fitTrack[trID]) + + + if not fitTrack[trID].checkConsistency(): + print 'Problem with track before fit, not consistent',self.fitTrack[atrack] + continue + try: self.__fitter.processTrack(fitTrack[trID]) # processTrackWithRep(fitTrack[atrack],rep,True) + except: + print "genfit failed to fit track" + continue + if not fitTrack[trID].checkConsistency(): + print 'Problem with track after fit, not consistent',self.fitTrack[atrack] + continue + + stat = fitTrack[trID].getFitStatus() + if not stat.isFitConverged() : continue + f = fitTrack[trID].getFittedState() + if(stat.getNdf()>0): + self.__reFitTracks.addNewTrack(trID, f.getPos(), f.getDir(), f.getMomMag(), + stat.getNdf(), stat.getChi2()) + if(self.__debug>0): + print "for track ", trID, + print " pos:", " ".join("{:10.4f}".format(f.getPos()(ii)) for ii in range(0,3)), + print " mom:", " ".join("{:10.4f}".format(f.getMom()(ii)) for ii in range(0,3)) + + #print "--------->", self.__reFitTracks.getTrIDs() + newFitTrIDs = self.__reFitTracks.getTrIDs() + twoTracks = ( len(newFitTrIDs)==2 ) + theStep = 0 + self.__docaEval = [] + if (twoTracks) : + self.__reFitTracks.createVertex(newFitTrIDs[0], newFitTrIDs[1], flag=0) # original + iniDoca = self.__reFitTracks.Doca + iniY = self.__reFitTracks.Vertex.Y() + while ( theStep1): + print "==>vertex ", theStep, " ", self.__reFitTracks.Doca + self.__reFitTracks.Vertex.Print() + self.__docaEval.append(self.__reFitTracks.Doca) + for tid in newFitTrIDs : + try: + state = fitTrack[tid].getFittedState() + except: + print "can't get fittedState" + flag = -1 + vPosEx = ROOT.TVector3(0,0,0) + vMomEx = ROOT.TVector3(0,0,0) + try : + state.extrapolateToPoint(self.__reFitTracks.Vertex) + except : + flag = -1 + print "track exctrapolation failed!tid: ", tid + if (flag > 0 ) : # + status = fitTrack[tid].getFitStatus() + #print "=>", tid, status.getNdf() + #print "extr track ", tid, + #print " pos:", " ".join("{:10.4f}".format(state.getPos()(ii)) for ii in range(0,3)), + #print " mom:", " ".join("{:10.4f}".format(state.getMom()(ii)) for ii in range(0,3)) + self.__reFitTracks.addNewTrack(tid, state.getPos(), state.getDir(), state.getMomMag(), + status.getNdf(), status.getChi2(), verb=False) + # FIX temporary + self.__reFitTracks.createVertex(newFitTrIDs[0], newFitTrIDs[1], flag) + self.__reFitTracks.Vertex.SetY(iniY) + theStep+=1 + twoTacks = ( len(self.__reFitTracks.getTrIDs())==2 ) + return len(newFitTrIDs) + + diff --git a/SWforYandex/lookAtGeo.py b/SWforYandex/lookAtGeo.py new file mode 100755 index 0000000..b9e3de7 --- /dev/null +++ b/SWforYandex/lookAtGeo.py @@ -0,0 +1,154 @@ +import ROOT,os,sys,getopt,time +import shipunit as u +import shipRoot_conf +from ShipGeoConfig import ConfigRegistry +from ROOT import * + +# function to prepare two dictionaries: one that has the node names as key and the related intex +# in the nodes array as value and the other one with key and value swapped. +def prepareNodeDictionaries(nodes): + # key: index, value: name of the node + nodeDict_index = {} + # key: name of the node, value: index + nodeDict_name = {} + for (i,n) in enumerate(nodes): + #print i,n.GetName() + nodeDict_index[i]=n.GetName() + nodeDict_name[n.GetName()]=i + return {'nodeDict_index':nodeDict_index, 'nodeDict_name':nodeDict_name} + +# function to print the node names and their index. Usefull to search the name of the element you would like +# to study if you don't know it by heart. Then the name can be used with the other functions for the specific studies. +def searchForNodes(inputFile, volName = None): + r = loadGeometry(inputFile) + fGeo = r['fGeo'] + ## Get the top volume + fGeo = ROOT.gGeoManager + + if volName is None: + tv = fGeo.GetTopVolume() + else: + tv = fGeo.GetVolume(volName) + + nodes = tv.GetNodes() + for (i,n) in enumerate(nodes): + print i,n.GetName() + +def searchForNodes2(inputFile,volName=None): + r = loadGeometry(inputFile) + fGeo = r['fGeo'] + ## Get the top volume + #fGeo = ROOT.gGeoManager + if volName is None: + tv = fGeo.GetTopVolume() + else: + tv = fGeo.GetVolume(volName) + + nodes = tv.GetNodes() + for (i,n) in enumerate(nodes): + print i,n.GetName(),findPositionElement(n)['z'],findDimentionBoxElement(n)['z'] + +def searchForNodes2_xyz(inputFile, volName=None): + r = loadGeometry(inputFile) + fGeo = r['fGeo'] + ## Get the top volume + #fGeo = ROOT.gGeoManager + if volName is None: + tv = fGeo.GetTopVolume() + else: + tv = fGeo.GetVolume(volName) + nodes = tv.GetNodes() + for (i,n) in enumerate(nodes): + print i,n.GetName() + print " x: ", findPositionElement(n)['x'],findDimentionBoxElement(n)['x'] + print " y: ", findPositionElement(n)['y'],findDimentionBoxElement(n)['y'] + print " z: ", findPositionElement(n)['z'],findDimentionBoxElement(n)['z'] + +# basic function to be called to load the geometry from a file +def loadGeometry(inputFile): + dy = float( inputFile.split("/")[-1].split(".")[1]) + + ShipGeo = ConfigRegistry.loadpy("$FAIRSHIP/geometry/geometry_config.py", Yheight = dy ) + # init geometry and mag. field + ShipGeo = ConfigRegistry.loadpy("$FAIRSHIP/geometry/geometry_config.py", Yheight = dy ) + # -----Create geometry---------------------------------------------- + import shipDet_conf + + tgeom = ROOT.TGeoManager("Geometry", "Geane geometry") + geofile = inputFile.replace('ship.','geofile_full.').replace('_rec.','.') + print geofile + gMan = tgeom.Import(geofile) + fGeo = ROOT.gGeoManager + return {'fGeo':fGeo,'gMan':gMan, 'ShipGeo':ShipGeo} + +def getNode(nodeName,fGeo=None, volName=None): + if fGeo is None: + r = loadGeometry(inputFile) + fGeo = r['fGeo'] + if volName is None: + tv = fGeo.GetTopVolume() + else: + tv = fGeo.GetVolume(volName) + + nodes = tv.GetNodes() + dicts = prepareNodeDictionaries(nodes) + return nodes[dicts['nodeDict_name'][nodeName]] + +def findDimentionBoxElement(node): + ## GetDZ() etc gives you half of the dimention + sh = node.GetVolume().GetShape() + return {'x':sh.GetDX(), + 'y':sh.GetDY(), + 'z':sh.GetDZ()} + +def findPositionElement(node): + pos = node.GetMatrix().GetTranslation() + + return {'x':pos[0], + 'y':pos[1], + 'z':pos[2]} + +## inputFile: file used from which I would like to retrive the geometry used +## myNodes_name: geometrical elements I would like to analyse (find the position) +def findPositionGeoElement(inputFile, myNodes_name, volName=None): + + r = loadGeometry(inputFile) + fGeo = r['fGeo'] + #volumes = gMan.GetListOfVolumes() + #for v in volumes: + # print v.GetName(), v.GetNumber() + + ## Get the top volume + if volName is None: + tv = fGeo.GetTopVolume() + else: + tv = fGeo.GetVolume(volName) + + nodes = tv.GetNodes() + + tmp = prepareNodeDictionaries(nodes) + nodeDict_name = tmp['nodeDict_name'] + res = {} + for nd_name in myNodes_name: + nd_index = nodeDict_name[nd_name] + nd = nodes[nd_index] + pos = findPositionElement(nd) + dims = findDimentionBoxElement(nd) + res[nd_name]={'z':pos['z'], + 'dimZ':dims['z'], + 'node':nd, + 'dimX':dims['x'], + 'dimY':dims['y']} + return res + +#inputFile = "../data/neutrino661/ship.10.0.Genie-TGeant4_D.root" +##searchForNodes(inputFile) + +### nodes name to be looked at +#myNodes_name = ["volLayer2_%s"%i for i in xrange(0,12)] +#myGeoEl = findPositionGeoElement(inputFile, myNodes_name) +#print myGeoEl + +##print myGeoEl["volLayer2_0"]['z'],myGeoEl["volLayer2_11"]['z'] +##print myGeoEl["volLayer2_11"]['z']-myGeoEl["volLayer2_0"]['z'] + diff --git a/SWforYandex/ntuple_nuVeto_small.py b/SWforYandex/ntuple_nuVeto_small.py new file mode 100644 index 0000000..ba14d4e --- /dev/null +++ b/SWforYandex/ntuple_nuVeto_small.py @@ -0,0 +1,633 @@ +import sys, re, getopt +from array import array +from ROOT import * + +fileName, fileNameGeo, outputFileName, sampleType, jobID = None, None, None, None, None +maxevents = 0 +verbose = True +# Energy deposit threshold for the liquid scintillator +threshold = 0.045 + +# Parse commandline inputs +try: + opts, args = getopt.getopt(sys.argv[1:], "n:t:f:o:v:j:", ['Ethr=']) +except getopt.GetoptError: + # print help information and exit: + print '\tUSAGE: -f inputfile.root -o outputfile.root -t sampleType (sig, nuBg or cosmics) -n maxevents -v verbose (0 or 1) -j jobID (0 to ...) ' + sys.exit() +for o, a in opts: + if o in ("-f",): + fileName = a + if o in ("-o",): + outputFileName = a + if o in ("-n",): + print "-n",a + maxevents = int(a) + if o in ("-j",): + print "-j",a + jobID = int(a) + if o in ("-t",): + sampleType = str(a) + if o in ("-v",): + verbose = bool(int(a)) + if o in ("--Ethr=",): + threshold = float(a) + +fileNameGeo = fileName.replace('ship', 'geofile_full') + +def namestr(obj, namespace=globals()): + return [name for name in namespace if namespace[name] is obj] + +for item in [fileName, fileNameGeo, outputFileName, sampleType]: + if not item: + print '\tFATAL! %s not defined!'%namestr(item)[0] + sys.exit() + +for item in [fileName, fileNameGeo, outputFileName, sampleType, maxevents, verbose, threshold]: + print '\tINFO: %s set to %s'%(namestr(item)[0], item) + +# Load SHiP (LHCb) style +gROOT.ProcessLine(".x mystyle.C") +# Obsolete debug flags +oldGeo = False +ON = True +# Load PDG database +pdg = TDatabasePDG.Instance() +# Add elements to PDG database +import pythia8_conf +pythia8_conf.addHNLtoROOT() +# TODO: MAKE THIS A DICTIONARY AND DE-VERBOSIZE IT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 +if not(pdg.GetParticle(1000010020)): + pdg.AddParticle("Deuteron","Deuteron", 1.875613e+00, kTRUE, 0,3,"Ion",1000010020) + pdg.AddAntiParticle("AntiDeuteron", - 1000010020) +if not(pdg.GetParticle(1000010030)): + pdg.AddParticle("Triton","Triton", 2.808921e+00, kFALSE, 3.885235e+17,3,"Ion",1000010030); + pdg.AddAntiParticle("AntiTriton", - 1000010030); +if not(pdg.GetParticle(1000020040) ): + pdg.AddParticle("Alpha","Alpha",3.727379e+00,kFALSE,0,6,"Ion",1000020040); + pdg.AddAntiParticle("AntiAlpha", - 1000020040); +if not(pdg.GetParticle(1000020030) ): + pdg.AddParticle("HE3","HE3",2.808391e+00,kFALSE,0,6,"Ion",1000020030); + pdg.AddAntiParticle("AntiHE3", -1000020030); +if not(pdg.GetParticle(1000030070) ): + print "TO BE CHECKED the data insert for Li7Nucleus" + pdg.AddParticle("Li7Nucleus","Li7Nucleus",3.727379e+00/4.*7.,kFALSE,0,0,"Boson",1000030070); +if not(pdg.GetParticle(1000060120) ): + print "ERROR: random values insert for C12Nucleus" + pdg.AddParticle("C12Nucleus","C12Nucleus",0.1,kFALSE,0,0,"Isotope",1000060120); +if not(pdg.GetParticle(1000030060) ): + print "ERROR: random values insert for Li6Nucleus" + pdg.AddParticle("Li6Nucleus","Li6Nucleus",6.015121,kFALSE,0,0,"Isotope",1000030060); +if not(pdg.GetParticle(1000070140) ): + print "ERROR: random values insert for for N14" + pdg.AddParticle("N14","N14",0.1,kTRUE,0,0,"Isotope",1000070140); +if not(pdg.GetParticle(1000050100) ): + print "TO BE CHECKED the data insert for B10" + pdg.AddParticle("B10","B10",10.0129370,kTRUE,0,0,"Isotope",1000050100); +if not(pdg.GetParticle(1000020060) ): + print "TO BE CHECKED the data insert for He6" + pdg.AddParticle("He6","He6",6.0188891,kFALSE,806.7e-3,0,"Isotope",1000020060); +if not(pdg.GetParticle(1000040080) ): + print "TO BE CHECKED the data insert for Be8" + pdg.AddParticle("Be8","Be8",8.00530510,kFALSE,6.7e-17,0,"Isotope",1000040080); +if not(pdg.GetParticle(1000030080) ): + print "TO BE CHECKED the data insert for Li8" + pdg.AddParticle("Li8","Li8",8.002248736,kTRUE,178.3e-3,0,"Isotope",1000030080); +if not(pdg.GetParticle(1000040170) ): + print "ERROR: didn't find what is it particle with code 1000040170, random number inserted!" + pdg.AddParticle("None","None",0.1,kFALSE,0,0,"Isotope",1000040170); +if not(pdg.GetParticle(1000040100) ): + print "TO BE CHECKED the data insert for Be10" + pdg.AddParticle("Be10","Be10",10.0135338,kTRUE,5.004e+9,0,"Isotope",1000040100); +if not(pdg.GetParticle(1000040070) ): + print "TO BE CHECKED the data insert for Be7" + pdg.AddParticle("Be7","Be7",11.021658,kTRUE,13.81,0,"Isotope",1000040070); +if not(pdg.GetParticle(1000230470) ): + print "ERROR: didn't find what is it particle with code 1000230470, random number inserted!" + pdg.AddParticle("None2","None2",0.1,kFALSE,0,0,"Isotope",1000230470); +if not(pdg.GetParticle(1000080170) ): + print "ERROR: didn't find what is it particle with code 1000080170, random number inserted!" + pdg.AddParticle("None3","None3",0.1,kFALSE,0,0,"Isotope",1000080170); +if not(pdg.GetParticle(1000240500) ): + print "ERROR: didn't find what is it particle with code 1000240500, random number inserted!" + pdg.AddParticle("None4","None4",0.1,kFALSE,0,0,"Isotope",1000240500); +if not(pdg.GetParticle(1000210450) ): + print "ERROR: didn't find what is it particle with code 1000210450, random number inserted (Sc45Nucleus)!" + pdg.AddParticle("Sc45Nucleus","Sc45Nucleus",0.1,kFALSE,0,0,"Isotope",1000210450); +if not(pdg.GetParticle(1000040090) ): + print "TO BE CHECKED the data insert for Be9" + pdg.AddParticle("Be9","Be9",9.0121822,kFALSE,0,0,"Isotope",1000040090); +if not(pdg.GetParticle(1000080160) ): + print "TO BE CHECKED the data insert for O16" + pdg.AddParticle("O16","O16",15.99491461956,kFALSE,0,0,"Isotope",1000080160); +if not(pdg.GetParticle(1000220460) ): + print "TO BE CHECKED the data insert for Ar40" + pdg.AddParticle("Ar40","Ar40",39.9623831225,kFALSE,0,0,"Isotope",1000220460); +if not(pdg.GetParticle(1000050110) ): + print "TO BE CHECKED the data insert for B11" + pdg.AddParticle("B11","B11",11.0093054,kFALSE,0,0,"Isotope",1000050110); + +def PrintEventPart(particles,pdg): + print "Particles in the event:" + for (pid,part) in enumerate(particles): + print pid, pdg.GetParticle(part.GetPdgCode()).GetName(), part.GetMotherId() + print + +def PrintRPChits(rpc,pdg): + print "Hits in:" + for (ix,RPCpt) in enumerate(rpc): + tmpName = pdg.GetParticle(RPCpt.PdgCode()) + print ix,RPCpt.GetZ(), tmpName, RPCpt.GetTrackID() , fGeo.FindNode(RPCpt.GetX(),RPCpt.GetY(),RPCpt.GetZ()).GetVolume().GetName() + print + +# weight computation moved to offlineForBarbara.py + +def addVect(t,name,vectType): + vect = vector(vectType)() + t.Branch( name, vect ) + return t, vect + +def addVar(t,name,varType): + var = array(varType,[-999]) + t.Branch(name,var,name+"/"+varType.upper()) + return t, var + +def putToZero(var): + var[0] = 0 + +def getPartName(partId): + return pdg.GetParticle(partId).GetName() + +def lookingForDecay(particles): + decayMotherList = [] + for p in particles: + mID = p.GetMotherId() + if mID>=0 and not (mID in decayMotherList): + decayMotherList.append(mID) + decayPartIndex.push_back(mID) + decayPartID.push_back(particles[mID].GetPdgCode()) + decayPartStrID.push_back(pdg.GetParticle(particles[mID].GetPdgCode()).GetName()) + decayPos_x.push_back(p.GetStartX()) + decayPos_y.push_back(p.GetStartY()) + decayPos_z.push_back(p.GetStartZ()) + decayMother.push_back(particles[mID].GetMotherId()) + decayP.push_back(p.GetP()) + +def wasFired(indexKids, detPoints, detPos, hitCharges, hitTrackId, checkOn, pointVects=None, Ethr=0): + # + def lookingForHits(detPoints,flag,flag_eff,nstat,nstat_eff,indexKids,Eloss,Ethr,hitCharges, hitTrackId): + charges = [] + trackids = [] + if hitCharges is None: + assert(hitTrackId is None) + for pos in detPos: + foundStat = False + foundStat_eff = False + for hit in detPoints: + if (indexKids is None) or (hit.GetTrackID() in indexKids): + # check if it is in one of the considered active layer + if pos[0]<=hit.GetZ()<=pos[1]: + Eloss += hit.GetEnergyLoss() + hitID = hit.GetTrackID() + if not hitID in trackids and not hitCharges is None: + if hit.PdgCode()>100000: + charges.append(9) + else: + charges.append(int(pdg.GetParticle(hit.PdgCode()).Charge())) + trackids.append(hitID) + hitCharges.push_back(charges[-1]) + hitTrackId.push_back(trackids[-1]) + if pointVects is not None: + pointVects[0].push_back(hit.GetX()) + pointVects[1].push_back(hit.GetY()) + pointVects[2].push_back(hit.GetZ()) + flag = True + foundStat = True + eff_val = gRandom.Uniform(0.,1.) + if eff_val<0.9: + flag_eff = flag_eff or True + foundStat_eff = True + else: + flag_eff = flag_eff or False + if foundStat: + nstat+=1 + if foundStat_eff: + nstat_eff+=1 + particles = 0 + flag_Ethr = Eloss>=Ethr + return flag, flag_eff, nstat, nstat_eff, Eloss, flag_Ethr,particles + # + # Now in partKidTrackID I should have the trackID connected to my charged particles + flag_eff = False + flag = False + nstat = 0 + nstat_eff = 0 + Eloss = 0 + flag,flag_eff,nstat,nstat_eff,Eloss,flag_Ethr,particles = lookingForHits(detPoints,flag,flag_eff,nstat,nstat_eff,indexKids,Eloss,Ethr,hitCharges, hitTrackId) + if flag==False and checkOn: + print "To be study event %s"%entry + return flag, flag_eff, nstat, nstat_eff, flag_Ethr, particles + +def convertion(tmpName): + if "Rib" in tmpName: tmpName = "Rib" + elif "LiSc" in tmpName: tmpName= "LiSc" + elif "Tr" in tmpName: tmpName = "Tr" + elif "Startplate" in tmpName: tmpName = "Startplate" + elif re.search("T\d+O", tmpName): tmpName = "TO" + elif re.search("T\d+I", tmpName): tmpName = "TI" + elif "Endplate" in tmpName: tmpName = "Endplate" + elif "volCoil" in tmpName: tmpName = "volCoil" + elif "volFeYoke" in tmpName: tmpName = "volFeYoke" + elif "gas" in tmpName: tmpName = "gas" + elif "wire" in tmpName: tmpName == "wire" + elif "VetoTimeDet" in tmpName: tmpName = "upstreamVeto" + elif "Veto" in tmpName: tmpName = "strawVeto" + return tmpName + +def wasFired_node(indexKids, detPoints, detVolNames, hitCharges, hitTrackId, checkOn, pointVects=None, Ethr=0): + # + def lookingForHits(detPoints,flag,hitCharges, hitTrackId): + if hitCharges is None: + assert(hitTrackId is None) + for hit in detPoints: + if (indexKids is None) or (hit.GetTrackID() in indexKids): + tmpName = fGeo.FindNode(hit.GetX(),hit.GetY(),hit.GetZ()).GetVolume().GetName() + tmpName = convertion(tmpName) + if hit.GetZ()>8000: + continue + if tmpName in detVolNames: + ## trick to remove the case of the tracking system the hits in the gas or straw from the straw-veto: + if 'trackingSystem' in detVolNames and hit.GetZ()<0: + continue + if "strawVetoSystem" in detVolNames and hit.GetZ()>0: + continue + if "upstreamVeto" in detVolNames and not(hit.GetZ()>= upstreamVetoPos[0][0] and hit.GetZ()<=upstreamVetoPos[0][1]): + continue + # check if it is in one of the considered active layer + if True: #pos[0]<=hit.GetZ()<=pos[1]: + flag = True + return flag + # + # Now in partKidTrackID I should have the trackID connected to my charged particles + flag = False + flag = lookingForHits(detPoints,flag,hitCharges, hitTrackId) + if flag==False and checkOn: + print "To be study event %s"%entry + return flag + + +""" Main program """ + +# Open file +f = TFile(fileName) +t = f.Get("cbmsim") + +totentries = t.GetEntries() +if verbose: + print + print + print "Program started, reading %s from %s"%(t.GetName(), fileName) +if (maxevents>0) and (maxevents < totentries): + entries = maxevents +else: + entries = totentries +if verbose: + print "Requested to process %s events out of %s in tree"%(entries, totentries) + +# Load geometry +from lookAtGeo import * +r = loadGeometry(fileNameGeo) +fGeo = r['fGeo'] + +# Functions by Elena for offline selection +# (Also includes another dictionary of all geometry nodes) +import offlineForBarbara as offline +offline.loadNodes(fGeo) +offline.ShipGeo = r['ShipGeo'] +offline.initBField(fileNameGeo) +offline.sh = offline.StrawHits(t, offline.modules, offline.ShipGeo.straw.resol, 0, None, offline.ShipGeo) +offline.pdg = pdg + +# Handle geometry +# Names of useful geometry nodes +myNodes_name = ["VetoTimeDet_1"] +myNodes_name += ["Tr%s_%s"%(i,i) for i in xrange(1,5)] +myNodes_name += ["Veto_5"] +# Positions of selected nodes +myGeoEl = findPositionGeoElement(fileNameGeo, myNodes_name,None) +# Places where a neutrino can interact +lastPassive_nodeName = ["volIron_23"] +OPERA_nodeName = ["volIron", "volRPC", "volHPT","volArm2MS","volFeYokes","volCoil","volFeYoke"]#["volIron_%s"%i for i in xrange(12,24)]+["volRpc_%s"%i for i in xrange(11,22)]+["volArm2MS_1"] +entrance_nodeName = ["T1Lid"]#['T1lid_1'] +volumeIn_nodeName = ["TI"]#['T%sI'%i for i in [1,2,3,5]] +volumeOut_nodeName = ["TO"]#['T%sO'%i for i in [1,2,3,5]] +OPERA_volNames = ["volIron","volRpc","volHPT"] +strawVeto_volNames = ["Veto"] +# Z positions of the VETO and tracking systems +Tracking = [myGeoEl["Tr1_1"]['z']-myGeoEl["Tr1_1"]['dimZ'],myGeoEl["Tr4_4"]['z']+myGeoEl["Tr4_4"]['dimZ']] +upstreamVeto = [myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ'],myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']] +trackStationsPos = [[myGeoEl["Tr%s_%s"%(i,i)]['z']-myGeoEl["Tr%s_%s"%(i,i)]['dimZ'],myGeoEl["Tr%s_%s"%(i,i)]['z']+myGeoEl["Tr%s_%s"%(i,i)]['dimZ']] for i in xrange(1,5)] +strawVetoPos = [[myGeoEl["Veto_5"]['z']-myGeoEl["Veto_5"]['dimZ'],myGeoEl["Veto_5"]['z']+myGeoEl["Veto_5"]['dimZ']]] +vetoWall = [[myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']+0.001,myGeoEl["Tr%s_%s"%(i,i)]['z']-myGeoEl["Tr%s_%s"%(i,i)]['dimZ']]]#myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']+6000.]] +upstreamVetoPos = [[myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ'],myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']]] +RPCstationsPos = [[-3500,myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ']-0.5]] +# Places where a neutrino can interact (some duplicates?) +trackStationsPos_node = ["Tr", "gas", "straw", 'trackingSystem'] +## should be that this does not work since it could be that hits are also assigned to gas or straw +strawVetoPos_node = ["strawVeto", "gas", "straw", "strawVetoSystem"] +vetoWall_node = ["LiSc","cave","Rib","TI","TO","Tr","strawVeto"] +upstreamVetoPos_node = ["upstreamVeto","cave"] +RPCstationsPos_node = ["volRpc","volMagneticSpectrometer","volIron","volHPT"] +# Printout positions +print "OPERApos: ",RPCstationsPos +print "trackingPos: ",trackStationsPos +print "strawVetoPos: ",strawVetoPos +print "scintPos: ",vetoWall +print "upstreamVetoPos: ",upstreamVetoPos + +# Prepare output ntuple +nf = TFile(outputFileName,"RECREATE") +nt = TTree("t","t") +# Event number -------------------------------------------- +nt, event = addVar(nt, 'event','i') +# Neutrino information ------------------------------------ +nt, nNu = addVar(nt, 'nNu', 'i') +nt, isPrimary = addVar(nt, 'isPrimary','i') +nt, startZ_nu = addVar(nt, 'startZ_nu', 'f') +nt, startY_nu = addVar(nt, 'startY_nu', 'f') +nt, startX_nu = addVar(nt, 'startX_nu', 'f') +nt, nuE = addVar(nt, 'nuE', 'f') +nt, weight = addVar(nt, 'weight', 'f') +# Interaction element code -------------------------------- +## 0: last passive material opera-mu-system +## 1: two windows around liquid scintillator +## 2: along vaccum tank +## 3: along all OPERA +## 4: between the two entrance windows +## 5: along vacuum tank outer window +## 6: along vacuum tank inner window +## 999: wrong OPERA place ## needed until we have the new production +## -1: anything else, but what???? #it should never been present +nt, interactionElement = addVar(nt, 'interactionElement','i') +# Neutrino daughters -------------------------------------- +# Do the particles come from a neutrino? +nt, nPart_fromNu = addVar(nt, 'nPart_fromNu', 'i') +nt, idPart_fromNu = addVect(nt, 'idPart_fromNu', 'int') +#nt, idStrPart_fromNu = addVect(nt, 'idStrPart_fromNu', 'string') +# Do charged particles come from a neutrino? +nt, nChargedPart_fromNu = addVar(nt, 'nChargedPart_fromNu', 'i') +nt, idChargedPart_fromNu = addVect(nt, 'idChargedPart_fromNu', 'int') +#nt, idStrChargedPart_fromNu = addVect(nt, 'idStrChargedPart_fromNu', 'string') +# Do neutral particles come from a neutrino? +nt, nNeutrPart_fromNu = addVar(nt, 'nNeutrPart_fromNu', 'i') +nt, idNeutrPart_fromNu = addVect(nt, 'idNeutrPart_fromNu', 'int') +#nt, idStrNeutrPart_fromNu = addVect(nt, 'idStrNeutrPart_fromNu', 'string') +# RPC ----------------------------------------------------- +# In case something (no matter if it comes from the nu-interaction kids) fired the RPC +nt, RPCany = addVar(nt,'RPCany', 'i' ) +# accounting for an eff. of each station of 90% +nt, RPCany_eff = addVar(nt,'RPCany_eff', 'i' ) +# upstreamVeto -------------------------------------------- +nt, upstreamVetoany = addVar(nt,'upstreamVetoAny', 'i' ) +# accounting for an eff. of each station of 90% +nt, upstreamVetoany_eff = addVar(nt,'upstreamVetoAny_eff', 'i' ) +# scintVeto ----------------------------------------------- +## In case something (no matter if it comes from the nu-interaction kids) fired the surroundin walls +nt, scintVetoAny = addVar(nt,'scintVetoAny', 'i' ) +nt, scintVetoAny_eff = addVar(nt,'scintVetoAny_eff', 'i' ) +# strawVeto ----------------------------------------------- +# In case something (no matter if it comes from the nu-interaction kids) fired the strawVeto +nt, strawVetoAny = addVar(nt,'strawVetoAny', 'i' ) +nt, strawVetoAny_eff = addVar(nt,'strawVetoAny_eff', 'i' ) +# TrackSyst ----------------------------------------------- +# only the case of anything fired it is considered, obviously +nt, TrackSyst = addVar(nt, "TrackSyst", 'i') +nt, TrackSyst_eff = addVar(nt, "TrackSyst_eff", 'i') +# VETO and tracking systems with thresholds --------------- +nt, strawVetoAny_Ethr = addVar(nt,"strawVetoAny_Ethr","i") +nt, scintVetoAny_Ethr = addVar(nt,"scintVetoAny_Ethr","i") +nt, upstreamVetoAny_Ethr = addVar(nt,"upstreamVetoAny_Ethr","i") +nt, RPCany_Ethr = addVar(nt,"RPCany_Ethr","i") +nt, TrackSyst_Ethr = addVar(nt, "TrackSyst_Ethr", "i") +# Decay information --------------------------------------- +nt, decayPartIndex = addVect(nt, "decayPartIndex", "float") +nt, decayPartID = addVect(nt, "decayPartID", "float") +nt, decayPartStrID = addVect(nt, "decayPartStrID", "string") +nt, decayPos_x = addVect(nt, "decayPos_x", "float") +nt, decayPos_y = addVect(nt, "decayPos_y", "float") +nt, decayPos_z = addVect(nt, "decayPos_z", "float") +nt, decayMother = addVect(nt, "decayMother", "float") +nt, decayP = addVect(nt,"decayP","float") +# Is this a NC interaction? ------------------------------- +nt, NC = addVar(nt, "NC", "i") +# Store where the neutrino interacted --------------------- +#nt, nuInteractionNode = addVect(nt, "nuInteractionNode", "string") +nt, nuIntNumSimpl = addVar(nt,"nuIntNumSimpl","i") +dictNodeNames = {'volIron':0, 'cave':1, 'LiSc':2, 'Startplate':3, 'TI':4, 'rockD':5, 'Endplate':6, 'Rib':7, 'volFeYoke':8, 'volHPT':9, 'TO':10, 'volRpc':11, 'volCoil':12, 'T1Lid':13, 'straw':14, 'strawVeto':15, 'volBase':16, 'Tr':17, 'gas':18, 'wire':19, 'others':20} +# Was the event reconstructed? ---------------------------- +nt, recoed = addVar(nt, "recoed","i") +# How many candidates in the reco event? ------------------ +nt, nRecoed = addVar(nt, "nRecoed","i") +# Add stuff for online selection -------------------------- +offline.addOfflineToTree(nt) + +# Now loop on the tree +# t = original tree +# nt = new tree +for entry in xrange(entries): + if not (entry%1000): + print "\tProcessing entry %s of %s..."%(entry,entries) + t.GetEntry(entry) + event[0] = entry+(jobID*entries) + particles = t.MCTrack + rpc = t.ShipRpcPoint + scint = t.vetoPoint + strawPoints = t.strawtubesPoint + vetoScint = t.vetoPoint + recoParts = t.Particles + # initialize containers + putToZero(nNu) + putToZero(nPart_fromNu) + putToZero(nChargedPart_fromNu) + putToZero(nNeutrPart_fromNu) + idPart_fromNu.clear() + idChargedPart_fromNu.clear() + idNeutrPart_fromNu.clear() + #idStrPart_fromNu.clear() + #idStrChargedPart_fromNu.clear() + #idStrNeutrPart_fromNu.clear() + decayPartIndex.clear() + decayPartID.clear() + decayPartStrID.clear() + decayPos_x.clear() + decayPos_y.clear() + decayPos_z.clear() + decayMother.clear() + decayP.clear() + #nuInteractionNode.clear() + primaryDone=False + isPrimary[0] = int(False) + lookingForDecay(particles) + nRecoed[0] = 0 + recoed[0] = 0 + # Which one is the "primary" particle? + if sampleType=="nuBg" or sampleType == "cosmics": + startPartRange = [0] + primaryMum = -1 + elif sampleType=="sig": + startPartRange = [1] + primaryMum = 0 + # Look at the primary particle + ip = startPartRange[0] + skipEvent=False + # Were there any hit in the tracking stations? + TrackSyst[0],TrackSyst_eff[0],dummy,dummy,TrackSyst_Ethr[0], dummy = wasFired(None, strawPoints, trackStationsPos, None, None, checkOn=False, pointVects=None)#[strawPoint_x, strawPoint_y, strawPoint_z] ) + # If no, skip this event + if TrackSyst[0]==0: + skipEvent=True + #print "i am jumping this one" + continue + # exit from loop on particles + #break + # Select the primary MC particle + part = particles[ip] + pdgPart = pdg.GetParticle(part.GetPdgCode()) + if sampleType=="nuBg": + assert("nu" in pdgPart.GetName()) + ## Looking for a neutrino: it should have the correct pdg code and it should not have a mother + #if (("nu" in pdgPart.GetName())):# and part.GetMotherId()==-1): # commented out by elena + ## (and de-indented the following block) + ## Starting the counter of how many particles were produced by the interaction of this specific nu + for recoP in recoParts: + nRecoed[0] += 1 + #offline.pushOfflineByParticle(t, recoP) + if nRecoed[0]>0: + recoed[0]=1 + else: + skipEvent=True + continue + #break + nNu[0]+=1 + if part.GetMotherId()==primaryMum: + assert(primaryDone==False) + primaryDone=True + isPrimary[0] = int(True) + assert(len(idPart_fromNu)==0) + assert(len(idNeutrPart_fromNu)==0) + else: + continue + # Where did this guy interact? + tmpName = fGeo.FindNode(part.GetStartX(),part.GetStartY(),part.GetStartZ()).GetVolume().GetName() + #nuInteractionNode.push_back(tmpName) + tmpName = convertion(tmpName) + if not tmpName in dictNodeNames: + tmpName = "others" + nuIntNumSimpl[0] = dictNodeNames[tmpName] + # Store interaction point coordinates + startZ_nu[0] = part.GetStartZ() + startY_nu[0] = part.GetStartY() + startX_nu[0] = part.GetStartX() + # Primary particle information + nuE[0] = part.GetEnergy() + # Looking for particles produced by the neutrino interaction + interacted = False + partKidsId = [] + NC[0] = 0 + + # Add information for offline selection + # (mainly signal normalisation and zeroing of particle-wise arrays) + ntr, nref = offline.pushOfflineByEvent(t, vetoScint, sampleType, verbose, threshold) + for recoP in recoParts: + offline.pushOfflineByParticle(t, recoP, ntr, nref) + + # Loop on MCTracks + for ip2 in xrange(0,len(particles)): + part2 = particles[ip2] + # exit if we have reached the empty part of the array + if not (type(part2)==type(ShipMCTrack())): + break + if part2.GetMotherId()==ip: + interacted = True + part2Id = part2.GetPdgCode() + partKidsId.append(part2Id) + # Was this a neutral current interaction? + if not (pdg.GetParticle(part2.GetPdgCode()) == None) and ("nu" in pdg.GetParticle(part2.GetPdgCode()).GetName()) and (part2.GetMotherId()==0): + NC[0] = 1 + nPart_fromNu[0]+=1 + idPart_fromNu.push_back(part2Id) + if pdg.GetParticle(part2.GetPdgCode()) == None: + part2Name = str(part2Id) + else: + part2Name = getPartName(part2Id) + #idStrPart_fromNu.push_back(part2Name) + # Counting how many particles produced by the nu-interaction are charged or neutral + if (pdg.GetParticle(part2.GetPdgCode())) == None or (int(fabs(pdg.GetParticle(part2Id).Charge()))==int(0)): + nNeutrPart_fromNu[0]+=1 + idNeutrPart_fromNu.push_back(part2Id) + #idStrNeutrPart_fromNu.push_back(part2Name) + else: + nChargedPart_fromNu[0]+=1 + idChargedPart_fromNu.push_back(part2Id) + #idStrChargedPart_fromNu.push_back(part2Name) + # How many are produced by the interaction in the last passive element of the "opera-mu system"? + # Finding out the "interaction element code" + part2Z = part2.GetStartZ() + part2X = part2.GetStartX() + part2Y = part2.GetStartY() + somewhere = False + nodeName = fGeo.FindNode(part2X,part2Y,part2Z).GetName() + if nodeName in lastPassive_nodeName: + somewhere = True + interactionElement[0] = 0 + intElName = 'OPERA' + # To know if it was in the full OPERA-system (excluded last passive) + if tmpName in OPERA_nodeName and somewhere==False: + somewhere = True + interactionElement[0] = 3 + intElName = 'OPERA' + # To know if it was between the two windows + if tmpName in entrance_nodeName: + assert(somewhere==False) + somewhere = True + interactionElement[0] = 1 + # Vacuum tank outer window + if tmpName in volumeIn_nodeName and somewhere==False: + interactionElement[0] = 5 + somewhere = True + # Vacuum tank inner window + elif nodeName in volumeOut_nodeName and somewhere==False: + interactionElement[0] = 6 + somewhere = True + # Vacuum tank ribs + if "Rib" in tmpName: + interactionElement[0] = 7 + # Somewhere else + if somewhere==False: + interactionElement[0] = -1 + # End loop on MCTracks + # Should be changed to avoid entering in the loop if there isn't anything in the tracking + if skipEvent: + continue + strawVetoAny[0],strawVetoAny_eff[0],dummy,dummy,strawVetoAny_Ethr[0],dummy = wasFired(None, strawPoints, strawVetoPos,None,None, checkOn=False, pointVects=None)#[strawVetoPoint_x, strawVetoPoint_y, strawVetoPoint_z]) + upstreamVetoany[0], upstreamVetoany_eff[0], dummy,dummy, upstreamVetoAny_Ethr[0],dummy = wasFired(None, vetoScint, upstreamVetoPos, None, None, checkOn=False, pointVects=None)#[upstreamVetoPoint_x, upstreamVetoPoint_y, upstreamVetoPoint_z]) + RPCany[0], RPCany_eff[0],dummy,dummy, RPCany_Ethr[0],dummy = wasFired(None, rpc, RPCstationsPos, None, None, checkOn=False, pointVects=None)#[rpcPoint_x, rpcPoint_y, rpcPoint_z]) + scintVetoAny[0], scintVetoAny_eff[0], dummy,dummy, scintVetoAny_Ethr[0],dummy = wasFired(None, vetoScint, vetoWall, None, None, checkOn=False, pointVects=None, Ethr=threshold) + #assert(len(idStrPart_fromNu)==len(idPart_fromNu)) + #assert(len(idStrChargedPart_fromNu)==len(idChargedPart_fromNu)) + #assert(len(idStrNeutrPart_fromNu)==len(idNeutrPart_fromNu)) + #assert(len(idStrPart_fromNu)==nChargedPart_fromNu[0]+nNeutrPart_fromNu[0]) + #assert(len(idStrChargedPart_fromNu)==nChargedPart_fromNu[0]) + #assert(len(idStrNeutrPart_fromNu)==nNeutrPart_fromNu[0]) + if not primaryDone: + print "It looks like there is no primary nu interacting" + PrintEventPart(particles,pdg) + sys.exit() + weight[0] = offline.findWeight(sampleType, NC[0], nuE[0], part, entries, pdgPart.GetName(), ON)#calcWeight(NC[0], nuE[0], part.GetWeight(), entries, pdgPart.GetName(), ON) + nt.Fill() + # End loop on tree +nt.Write() +nf.Save() +nf.Close() +f.Close() +print "Output wrote to %s"%outputFileName +print "Number of events with vertex outside Veto_5-500 - Tr4_4: %s"%offline.num_bad_z diff --git a/SWforYandex/offlineForBarbara.py b/SWforYandex/offlineForBarbara.py new file mode 100644 index 0000000..3c46d45 --- /dev/null +++ b/SWforYandex/offlineForBarbara.py @@ -0,0 +1,643 @@ +from lookAtGeo import * +import tools +import shipunit as u +from ShipGeoConfig import ConfigRegistry +import shipDet_conf + +from operator import mul, add + +import sys +sys.path.append('KaterinaLight/') +from StrawHits import StrawHits +## Use it like: +# f = TFile(fileName) +# t = f.Get("cbmsim") +# sh = offline.StrawHits(t, offline.shipDet_conf.configure(offline.__run, r['ShipGeo']), r['ShipGeo'].straw.resol, 0, None, r['ShipGeo']) +# t.GetEntry(58) +# sh.readEvent() +# sh.FitTracks() + +#dy = 10. +# init geometry and mag. field +#ShipGeo = ConfigRegistry.loadpy("$FAIRSHIP/geometry/geometry_config.py", Yheight = dy ) + + +def searchForNodes3_xyz_dict(fGeo, verbose=False): + from tools import findPositionElement, findDimentionBoxElement, findPositionElement2 + d = {} + #r = loadGeometry(inputFile) + #fGeo = r['fGeo'] + ## Get the top volume + #fGeo = ROOT.gGeoManager + tv = fGeo.GetTopVolume() + topnodes = tv.GetNodes() + for (j,topn) in enumerate(topnodes): + # top volumes + if verbose: + print j, topn.GetName() + print " x: ", findPositionElement(topn)['x'],findDimentionBoxElement(topn)['x'] + print " y: ", findPositionElement(topn)['y'],findDimentionBoxElement(topn)['y'] + print " z: ", findPositionElement(topn)['z'],findDimentionBoxElement(topn)['z'] + d[topn.GetName()] = {'x': {}, 'y':{}, 'z':{}, 'r':{}} + d[topn.GetName()]['x']['pos'] = findPositionElement(topn)['x'] + d[topn.GetName()]['x']['dim'] = findDimentionBoxElement(topn)['x'] + d[topn.GetName()]['y']['pos'] = findPositionElement(topn)['y'] + d[topn.GetName()]['y']['dim'] = findDimentionBoxElement(topn)['y'] + d[topn.GetName()]['z']['pos'] = findPositionElement(topn)['z'] + d[topn.GetName()]['z']['dim'] = findDimentionBoxElement(topn)['z'] + if topn.GetVolume().GetShape().IsCylType(): + d[topn.GetName()]['r']['pos'] = findPositionElement(topn)['r'] + d[topn.GetName()]['r']['dim'] = findDimentionBoxElement(topn)['r'] + else: + d[topn.GetName()]['r']['pos'] = 0. + d[topn.GetName()]['r']['dim'] = 0. + # First children + nodes = topn.GetNodes() + if nodes: + topPos = topn.GetMatrix().GetTranslation() + for (i,n) in enumerate(nodes): + if verbose: + print j, topn.GetName(), i, n.GetName() + print " x: ", findPositionElement2(n,topPos)['x'],findDimentionBoxElement(n)['x'] + print " y: ", findPositionElement2(n,topPos)['y'],findDimentionBoxElement(n)['y'] + print " z: ", findPositionElement2(n,topPos)['z'],findDimentionBoxElement(n)['z'] + d[n.GetName()] = {'x': {}, 'y':{}, 'z':{}, 'r':{}} + d[n.GetName()]['x']['pos'] = findPositionElement2(n,topPos)['x'] + d[n.GetName()]['x']['dim'] = findDimentionBoxElement(n)['x'] + d[n.GetName()]['y']['pos'] = findPositionElement2(n,topPos)['y'] + d[n.GetName()]['y']['dim'] = findDimentionBoxElement(n)['y'] + d[n.GetName()]['z']['pos'] = findPositionElement2(n,topPos)['z'] + d[n.GetName()]['z']['dim'] = findDimentionBoxElement(n)['z'] + if n.GetVolume().GetShape().IsCylType(): + d[n.GetName()]['r']['pos'] = findPositionElement2(n,topPos)['r'] + d[n.GetName()]['r']['dim'] = findDimentionBoxElement(n)['r'] + else: + d[n.GetName()]['r']['pos'] = 0. + d[n.GetName()]['r']['dim'] = 0. + # Second children + cnodes = n.GetNodes() + if cnodes: + localpos = n.GetMatrix().GetTranslation() + localToGlobal = [] + for i in xrange(3): + localToGlobal.append(localpos[i]+topPos[i]) + for (k,cn) in enumerate(cnodes): + if verbose: + print j, topn.GetName(), i, n.GetName(), k, cn.GetName() + print " x: ", findPositionElement2(cn,localToGlobal)['x'],findDimentionBoxElement(cn)['x'] + print " y: ", findPositionElement2(cn,localToGlobal)['y'],findDimentionBoxElement(cn)['y'] + print " z: ", findPositionElement2(cn,localToGlobal)['z'],findDimentionBoxElement(cn)['z'] + d[cn.GetName()] = {'x': {}, 'y':{}, 'z':{}, 'r':{}} + d[cn.GetName()]['x']['pos'] = findPositionElement2(cn,localToGlobal)['x'] + d[cn.GetName()]['x']['dim'] = findDimentionBoxElement(cn)['x'] + d[cn.GetName()]['y']['pos'] = findPositionElement2(cn,localToGlobal)['y'] + d[cn.GetName()]['y']['dim'] = findDimentionBoxElement(cn)['y'] + d[cn.GetName()]['z']['pos'] = findPositionElement2(cn,localToGlobal)['z'] + d[cn.GetName()]['z']['dim'] = findDimentionBoxElement(cn)['z'] + if cn.GetVolume().GetShape().IsCylType(): + d[cn.GetName()]['r']['pos'] = findPositionElement2(cn,localToGlobal)['r'] + d[cn.GetName()]['r']['dim'] = findDimentionBoxElement(cn)['r'] + else: + d[cn.GetName()]['r']['pos'] = 0. + d[cn.GetName()]['r']['dim'] = 0. + return d + + +ff = ROOT.TFile("histoForWeights.root") +h_GioHans = ff.Get("h_Gio") +def calcWeightNu(NC, E, w, entries, nuName, ON=True): + # Only for neutrinos and antineutrinos + if not ON: + return 1 + if "bar" in nuName: + reduction = 0.5 + flux = 1.#6.98e+11 * 2.e+20 / 5.e+13 + else: + reduction = 1. + flux = 1.#1.09e+12 * 2.e+20/ 5.e+13 + crossSec = 6.7e-39*E * reduction + NA = 6.022e+23 + binN = h_GioHans.GetXaxis().FindBin(E) + return crossSec * flux * h_GioHans.GetBinContent(binN) * w * NA #/ entries + + +def findWeight(sampleType, NC, E, MCTrack, entries, nuName, ON): + if sampleType == 'nuBg': + return calcWeightNu(NC, E, MCTrack.GetWeight(), entries, nuName, ON) + elif sampleType == 'sig': + return MCTrack.GetWeight() # for the acceptance, multiply by normalization + elif sampleType == 'cosmics': + return MCTrack.GetWeight() # multiply by 1.e6 / 200. + + + +def hasStrawStations(event, trackId, listOfWantedStraws): + ok = [False]*len(listOfWantedStraws) + positions = [ (nodes[det]['z']['pos'] - nodes[det]['z']['dim'], nodes[det]['z']['pos'] + nodes[det]['z']['dim'] ) for det in listOfWantedStraws ] + for hit in event.strawtubesPoint: + if hit.GetTrackID() == trackId: + for (i,det) in enumerate(listOfWantedStraws): + if (positions[i][0] < hit.GetZ() < positions[i][1]) and tools.inEllipse(hit.GetX(), hit.GetY(), 250., 500.): + ok[i] = True + return bool(reduce(mul, ok, 1)) + +def hasGoodStrawStations(event, trackId): + #ok = [False]*2 + okupstream = [False]*2 + okdownstream = [False]*2 + upstream = [ (nodes[det]['z']['pos'] - nodes[det]['z']['dim'], nodes[det]['z']['pos'] + nodes[det]['z']['dim'] ) for det in ['Tr1_1', 'Tr2_2'] ] + downstream = [ (nodes[det]['z']['pos'] - nodes[det]['z']['dim'], nodes[det]['z']['pos'] + nodes[det]['z']['dim'] ) for det in ['Tr3_3', 'Tr4_4'] ] + for hit in event.strawtubesPoint: + if hit.GetTrackID() == trackId: + for i in xrange(2): + if (upstream[i][0] < hit.GetZ() < upstream[i][1]) and tools.inEllipse(hit.GetX(), hit.GetY(), 250., 500.): + okupstream[i] = True + if (downstream[i][0] < hit.GetZ() < downstream[i][1]) and tools.inEllipse(hit.GetX(), hit.GetY(), 250., 500.): + okdownstream[i] = True + ok = [ bool(reduce(mul, l, 1)) for l in [okupstream, okdownstream] ] + return bool(reduce(add, ok, 0)) + +def findHNLvertex(event): + for t in event.MCTrack: + if t.GetMotherId() == 1: + return t.GetStartZ() + return False + +def has_muon_station(event, trackId, station): + zIn = nodes['muondet%s_1'%(station-1)]['z']['pos'] - nodes['muondet%s_1'%(station-1)]['z']['dim'] + zOut = nodes['muondet%s_1'%(station-1)]['z']['pos'] + nodes['muondet%s_1'%(station-1)]['z']['dim'] + for hit in event.muonPoint: + if hit.GetTrackID() == trackId: + if zIn <= hit.GetZ() <= zOut: + return True + return False + +def hasEcalDeposit(event, trackId, ELossThreshold): + ELoss = 0. + for hit in event.EcalPoint: + if hit.GetTrackID() == trackId: + ELoss += hit.GetEnergyLoss() + if ELoss >= ELossThreshold: + return True + return False + +def hasMuons(event, trackId): + m1 = 0 + m2 = 0 + m3 = 0 + m4 = 0 + for ahit in event.muonPoint: + if ahit.GetTrackID() == trackId: + detID = ahit.GetDetectorID() + if(detID == 476) : + m1 += 1 + if(detID == 477) : + m2 += 1 + if(detID == 478) : + m3 += 1 + if(detID == 479) : + m4 += 1 + return [bool(m1), bool(m2), bool(m3), bool(m4)] + +def myVertex(t1,t2,PosDir): + # closest distance between two tracks + # d = |pq . u x v|/|u x v| + a = ROOT.TVector3(PosDir[t1][0](0) ,PosDir[t1][0](1), PosDir[t1][0](2)) + u = ROOT.TVector3(PosDir[t1][1](0),PosDir[t1][1](1),PosDir[t1][1](2)) + c = ROOT.TVector3(PosDir[t2][0](0) ,PosDir[t2][0](1), PosDir[t2][0](2)) + v = ROOT.TVector3(PosDir[t2][1](0),PosDir[t2][1](1),PosDir[t2][1](2)) + pq = a-c + uCrossv = u.Cross(v) + dist = pq.Dot(uCrossv)/(uCrossv.Mag()+1E-8) + # u.a - u.c + s*|u|**2 - u.v*t = 0 + # v.a - v.c + s*v.u - t*|v|**2 = 0 + E = u.Dot(a) - u.Dot(c) + F = v.Dot(a) - v.Dot(c) + A,B = u.Mag2(), -u.Dot(v) + C,D = u.Dot(v), -v.Mag2() + t = -(C*E-A*F)/(B*C-A*D) + X = c.x()+v.x()*t + Y = c.y()+v.y()*t + Z = c.z()+v.z()*t + # sT = ROOT.gROOT.FindAnything('cbmsim') + #print 'test2 ',X,Y,Z,dist + #print 'truth',sTree.MCTrack[2].GetStartX(),sTree.MCTrack[2].GetStartY(),sTree.MCTrack[2].GetStartZ() + return X,Y,Z,abs(dist) + +def addFullInfoToTree(elenaTree): + elenaTree, DaughtersPt = tools.AddVect(elenaTree, 'DaughtersPt', 'float') + elenaTree, DaughtersChi2 = tools.AddVect(elenaTree, 'DaughtersChi2', 'float') + elenaTree, DaughtersNPoints = tools.AddVect(elenaTree, 'DaughtersNPoints', 'int') + elenaTree, DaughtersTruthProdX = tools.AddVect(elenaTree, 'DaughtersTruthProdX', 'float') + elenaTree, DaughtersTruthProdY = tools.AddVect(elenaTree, 'DaughtersTruthProdY', 'float') + elenaTree, DaughtersTruthProdZ = tools.AddVect(elenaTree, 'DaughtersTruthProdZ', 'float') + elenaTree, DaughtersTruthPDG = tools.AddVect(elenaTree, 'DaughtersTruthPDG', 'int') + elenaTree, DaughtersTruthMotherPDG = tools.AddVect(elenaTree, 'DaughtersTruthMotherPDG', 'int') + elenaTree, DaughtersFitConverged = tools.AddVect(elenaTree, 'DaughtersFitConverged', 'int') + elenaTree, straw_x = tools.AddVect(elenaTree, 'straw_x', 'float') + elenaTree, straw_y = tools.AddVect(elenaTree, 'straw_y', 'float') + elenaTree, straw_z = tools.AddVect(elenaTree, 'straw_z', 'float') + elenaTree, muon_x = tools.AddVect(elenaTree, 'muon_x', 'float') + elenaTree, muon_y = tools.AddVect(elenaTree, 'muon_y', 'float') + elenaTree, muon_z = tools.AddVect(elenaTree, 'muon_z', 'float') + elenaTree, ecal_x = tools.AddVect(elenaTree, 'ecal_x', 'float') + elenaTree, ecal_y = tools.AddVect(elenaTree, 'ecal_y', 'float') + elenaTree, ecal_z = tools.AddVect(elenaTree, 'ecal_z', 'float') + elenaTree, hcal_x = tools.AddVect(elenaTree, 'hcal_x', 'float') + elenaTree, hcal_y = tools.AddVect(elenaTree, 'hcal_y', 'float') + elenaTree, hcal_z = tools.AddVect(elenaTree, 'hcal_z', 'float') + elenaTree, veto5_x = tools.AddVect(elenaTree, 'veto5_x', 'float') + elenaTree, veto5_y = tools.AddVect(elenaTree, 'veto5_y', 'float') + elenaTree, veto5_z = tools.AddVect(elenaTree, 'veto5_z', 'float') + elenaTree, liquidscint_x = tools.AddVect(elenaTree, 'liquidscint_x', 'float') + elenaTree, liquidscint_y = tools.AddVect(elenaTree, 'liquidscint_y', 'float') + elenaTree, liquidscint_z = tools.AddVect(elenaTree, 'liquidscint_z', 'float') + elenaTree, DOCA = tools.AddVar(elenaTree, 'DOCA', 'float') + elenaTree, vtxx = tools.AddVar(elenaTree, 'vtxx', 'float') + elenaTree, vtxy = tools.AddVar(elenaTree, 'vtxy', 'float') + elenaTree, vtxz = tools.AddVar(elenaTree, 'vtxz', 'float') + elenaTree, IP0 = tools.AddVar(elenaTree, 'IP0', 'float') + elenaTree, Mass = tools.AddVar(elenaTree, 'Mass', 'float') + elenaTree, Pt = tools.AddVar(elenaTree, 'Pt', 'float') + elenaTree, P = tools.AddVar(elenaTree, 'P', 'float') + elenaTree, NParticles = tools.AddVar(elenaTree, 'NParticles', 'int') + elenaTree, HNLw = tools.AddVar(elenaTree, 'HNLw', 'float') + elenaTree, NuWeight = tools.AddVar(elenaTree, 'NuWeight', 'float') + elenaTree, EventNumber = tools.AddVar(elenaTree, 'EventNumber', 'int') + elenaTree, DaughterMinPt = tools.AddVar(elenaTree, 'DaughterMinPt', 'float') + elenaTree, DaughterMinP = tools.AddVar(elenaTree, 'DaughterMinP', 'float') + elenaTree, DaughtersAlwaysIn = tools.AddVar(elenaTree, 'DaughtersAlwaysIn', 'int') + elenaTree, BadTruthVtx = tools.AddVar(elenaTree, 'BadTruthVtx', 'int') + +DaughtersFitConverged, DOCA, vtxx, vtxy, vtxz, IP0, HasEcal = None, None, None, None, None, None, None +NoB_DOCA, NoB_vtxx, NoB_vtxy, NoB_vtxz, NoB_IP0 = None, None, None, None, None +DaughtersAlwaysIn, BadTruthVtx, Has1Muon1, Has1Muon2, Has2Muon1, Has2Muon2 = None, None, None, None, None, None +MaxDaughtersRedChi2, MinDaughtersNdf = None, None +NoB_MaxDaughtersRedChi2, NoB_MinDaughtersNdf = None, None +DaughtersMinP, DaughtersMinPt, Mass, P, Pt = None, None, None, None, None +NoB_DaughtersMinP, NoB_DaughtersMinPt, NoB_Mass, NoB_P, NoB_Pt = None, None, None, None, None + +def addOfflineToTree(elenaTree): + global DaughtersFitConverged, DOCA, vtxx, vtxy, vtxz, IP0, HasEcal + global NoB_DOCA, NoB_vtxx, NoB_vtxy, NoB_vtxz, NoB_IP0 + global DaughtersAlwaysIn, BadTruthVtx, Has1Muon1, Has1Muon2, Has2Muon1, Has2Muon2 + global MaxDaughtersRedChi2, MinDaughtersNdf, HNLw, NuWeight, NoB_MaxDaughtersRedChi2, NoB_MinDaughtersNdf + global DaughtersMinP, DaughtersMinPt, Mass, P, Pt + global NoB_DaughtersMinP, NoB_DaughtersMinPt, NoB_Mass, NoB_P, NoB_Pt + elenaTree, DaughtersFitConverged = tools.AddVect(elenaTree, 'DaughtersFitConverged', 'int') # + elenaTree, DOCA = tools.AddVect(elenaTree, 'DOCA', 'float') # + elenaTree, NoB_DOCA = tools.AddVect(elenaTree, 'NoB_DOCA', 'float') # + elenaTree, vtxx = tools.AddVect(elenaTree, 'vtxx', 'float') # + elenaTree, vtxy = tools.AddVect(elenaTree, 'vtxy', 'float') # + elenaTree, vtxz = tools.AddVect(elenaTree, 'vtxz', 'float') # + elenaTree, NoB_vtxx = tools.AddVect(elenaTree, 'NoB_vtxx', 'float') # + elenaTree, NoB_vtxy = tools.AddVect(elenaTree, 'NoB_vtxy', 'float') # + elenaTree, NoB_vtxz = tools.AddVect(elenaTree, 'NoB_vtxz', 'float') # + elenaTree, IP0 = tools.AddVect(elenaTree, 'IP0', 'float') # + elenaTree, NoB_IP0 = tools.AddVect(elenaTree, 'NoB_IP0', 'float') # + #elenaTree, NParticles = tools.AddVar(elenaTree, 'NParticles', 'int') # + elenaTree, DaughtersAlwaysIn = tools.AddVect(elenaTree, 'DaughtersAlwaysIn', 'int') # + elenaTree, BadTruthVtx = tools.AddVect(elenaTree, 'BadTruthVtx', 'int') # + elenaTree, Has1Muon1 = tools.AddVect(elenaTree, 'Has1Muon1', 'int') # + elenaTree, Has1Muon2 = tools.AddVect(elenaTree, 'Has1Muon2', 'int') # + elenaTree, Has2Muon1 = tools.AddVect(elenaTree, 'Has2Muon1', 'int') # + elenaTree, Has2Muon2 = tools.AddVect(elenaTree, 'Has2Muon2', 'int') # + elenaTree, HasEcal = tools.AddVect(elenaTree, 'HasEcal', 'int') # + elenaTree, MaxDaughtersRedChi2 = tools.AddVect(elenaTree, 'MaxDaughtersRedChi2', 'float') # + elenaTree, MinDaughtersNdf = tools.AddVect(elenaTree, 'MinDaughtersNdf', 'int') # + elenaTree, NoB_MaxDaughtersRedChi2 = tools.AddVect(elenaTree, 'NoB_MaxDaughtersRedChi2', 'float') # + elenaTree, NoB_MinDaughtersNdf = tools.AddVect(elenaTree, 'NoB_MinDaughtersNdf', 'int') # + elenaTree, DaughtersMinP = tools.AddVect(elenaTree, 'DaughtersMinP', 'float') + elenaTree, DaughtersMinPt = tools.AddVect(elenaTree, 'DaughtersMinPt', 'float') + elenaTree, P = tools.AddVect(elenaTree, 'P', 'float') + elenaTree, Pt = tools.AddVect(elenaTree, 'Pt', 'float') + elenaTree, Mass = tools.AddVect(elenaTree, 'Mass', 'float') + elenaTree, NoB_DaughtersMinP = tools.AddVect(elenaTree, 'NoB_DaughtersMinP', 'float') + elenaTree, NoB_DaughtersMinPt = tools.AddVect(elenaTree, 'NoB_DaughtersMinPt', 'float') + elenaTree, NoB_P = tools.AddVect(elenaTree, 'NoB_P', 'float') + elenaTree, NoB_Pt = tools.AddVect(elenaTree, 'NoB_Pt', 'float') + elenaTree, NoB_Mass = tools.AddVect(elenaTree, 'NoB_Mass', 'float') + # Add liquid scintillator segmentation + tools.makeLSsegments(nodes, elenaTree) + +nodes = None +def loadNodes(fGeo): + global nodes + nodes = searchForNodes3_xyz_dict(fGeo) + +num_bad_z = 0 + +def signalNormalisationZ(tree, datatype, verbose): + # By event + # Uses MC truth!! + global BadTruthVtx, num_bad_z + tools.PutToZero(BadTruthVtx) + z_hnl_vtx = findHNLvertex(tree) + bad_z = False + if not z_hnl_vtx: + if "sig" in datatype: + print 'ERROR: hnl vertex not found!' + ii = 0 + for g in tree.MCTrack: + ii +=1 + if ("sig" in datatype) and ii < 3: + pass + elif ("sig" in datatype) and ii >= 3: + sys.exit() + if not (nodes['Veto_5']['z']['pos']-nodes['Veto_5']['z']['dim']-500. < z_hnl_vtx < nodes['Tr4_4']['z']['pos']+nodes['Tr4_4']['z']['dim']): + bad_z = True + num_bad_z += 1 + if "sig" in datatype: + print z_hnl_vtx + tools.Push(BadTruthVtx, int(bad_z)) + +def nParticles(tree): + # By event + global NParticles + np = 0 + for HNL in tree.Particles: + np += 1 + tools.PutToZero(NParticles); tools.Push(NParticles, np) + +def hasEcalAndMuons(tree, particle): + # By particle + global Has1Muon1, Has1Muon2, Has2Muon1 + global Has2Muon2, HasEcal + flag2Muon1 = False + flag2Muon2 = False + flag1Muon1 = False + flag1Muon2 = False + flagEcal = False + t1,t2 = tree.fitTrack2MC[particle.GetDaughter(0)], tree.fitTrack2MC[particle.GetDaughter(1)] + # AND or OR? + if ( has_muon_station(tree, t1, 1) and has_muon_station(tree, t2, 1) ): + flag2Muon1 = True + if ( has_muon_station(tree, t1, 2) and has_muon_station(tree, t2, 2) ): + flag2Muon2 = True + if ( has_muon_station(tree, t1, 1) or has_muon_station(tree, t2, 1) ): + flag1Muon1 = True + if ( has_muon_station(tree, t1, 2) or has_muon_station(tree, t2, 2) ): + flag1Muon2 = True + # This also work, but may be slower + #muons1 = hasMuons(tree, t1) + #muons2 = hasMuons(tree, t2) + #if muons1[0] or muons2[0]: flag1Muon1 = True + #if muons1[1] or muons2[1]: flag1Muon2 = True + #if muons1[0] and muons2[0]: flag2Muon1 = True + #if muons1[1] and muons2[1]: flag2Muon2 = True + if ( hasEcalDeposit(tree, t1, 150.*u.MeV) or hasEcalDeposit(tree, t2, 150.*u.MeV) ): + flagEcal = True + tools.Push(Has2Muon1, int(flag2Muon1)) + tools.Push(Has2Muon2, int(flag2Muon2)) + tools.Push(Has1Muon1, int(flag1Muon1)) + tools.Push(Has1Muon2, int(flag1Muon2)) + tools.Push(HasEcal, int(flagEcal)) + +def chi2Ndf(tree, particle, ntr, nref): + # By particle + global MaxDaughtersRedChi2, MinDaughtersNdf + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + if ntr>1 and nref==2:#nf>1 + t1r,t2r = sh.getReFitTrIDs()[0], sh.getReFitTrIDs()[1] + chi2red_1 = sh.getReFitChi2Ndf(t1r) + ndf_1 = int(round(sh.getReFitNdf(t1r))) + chi2red_2 = sh.getReFitChi2Ndf(t2r) + ndf_2 = int(round(sh.getReFitNdf(t2r))) + reducedChi2 = [chi2red_1, chi2red_2] + ndfs = [ndf_1, ndf_2] + # if the refit didn't work + if (ntr<2) or (nref!=2) or (not ndf_1) or (not ndf_2) or (not chi2red_1) or (not chi2red_2): + reducedChi2 = [] + ndfs = [] + for tr in [t1,t2]: + x = tree.FitTracks[tr] + ndfs.append( int(round(x.getFitStatus().getNdf())) ) + reducedChi2.append( x.getFitStatus().getChi2()/x.getFitStatus().getNdf() ) + tools.Push(MaxDaughtersRedChi2, max(reducedChi2)) + tools.Push(MinDaughtersNdf, min(ndfs)) + + +def NoB_chi2Ndf(tree, particle): + # By particle + global NoB_MaxDaughtersRedChi2, NoB_MinDaughtersNdf, DaughtersFitConverged + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + reducedChi2 = [] + ndfs = [] + converged = [] + for tr in [t1,t2]: + x = tree.FitTracks[tr] + ndfs.append( int(round(x.getFitStatus().getNdf())) ) + reducedChi2.append( x.getFitStatus().getChi2()/x.getFitStatus().getNdf() ) + converged.append( x.getFitStatus().isFitConverged() ) + tools.Push(NoB_MaxDaughtersRedChi2, max(reducedChi2)) + tools.Push(NoB_MinDaughtersNdf, min(ndfs)) + tools.Push( DaughtersFitConverged, int(converged[0]*converged[1]) ) + +def NoB_kinematics(tree, particle): + global NoB_DaughtersMinP, NoB_DaughtersMinPt, NoB_P, NoB_Pt, NoB_Mass + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + dp, dpt = [], [] + for tr in [t1, t2]: + x = tree.FitTracks[tr] + xx = x.getFittedState() + dp.append(xx.getMom().Mag()); dpt.append(xx.getMom().Pt()) + tools.Push(NoB_DaughtersMinP, min(dp)) + tools.Push(NoB_DaughtersMinPt, min(dpt)) + HNLMom = ROOT.TLorentzVector() + particle.Momentum(HNLMom) + tools.Push(NoB_Mass, HNLMom.M()) + tools.Push(NoB_Pt, HNLMom.Pt()) + tools.Push(NoB_P, HNLMom.P()) + +def goodBehavedTracks(tree, particle): + # By particle + # Uses MC truth!! + global DaughtersAlwaysIn + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + accFlag = True + for tr in [t1,t2]: + mctrid = tree.fitTrack2MC[tr] + if not hasGoodStrawStations(tree, mctrid): + accFlag = False + tools.Push(DaughtersAlwaysIn, int(accFlag)) + +def NoB_vertexInfo(tree, particle): + # By particle + global NoB_vtxx, NoB_vtxy, NoB_vtxz + global NoB_IP0, NoB_DOCA + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + PosDir = {} + for tr in [t1,t2]: + xx = tree.FitTracks[tr].getFittedState() + PosDir[tr] = [xx.getPos(),xx.getDir()] + xv,yv,zv,doca = myVertex(t1,t2,PosDir) + tools.Push(NoB_DOCA, doca) + tools.Push(NoB_vtxx, xv); tools.Push(NoB_vtxy, yv); tools.Push(NoB_vtxz, zv) + # impact parameter to target + HNLPos = ROOT.TLorentzVector() + particle.ProductionVertex(HNLPos) + HNLMom = ROOT.TLorentzVector() + particle.Momentum(HNLMom) + tr = ROOT.TVector3(0,0,ShipGeo.target.z0) + t = 0 + for i in range(3): t += HNLMom(i)/HNLMom.P()*(tr(i)-HNLPos(i)) + ip = 0 + for i in range(3): ip += (tr(i)-HNLPos(i)-t*HNLMom(i)/HNLMom.P())**2 + ip = ROOT.TMath.Sqrt(ip) + tools.Push(NoB_IP0, ip) + + +def kinematics(tree, particle, ntr, nref): + global DaughtersMinP, DaughtersMinPt, P, Pt, Mass + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + dminpt, dminp = 0., 0. + + if ntr>1 and nref==2: + t1r,t2r = sh.getReFitTrIDs()[0], sh.getReFitTrIDs()[1] + Pos1, Dir1, Mom1= sh.getReFitPosDirPval(t1r) + Pos2, Dir2, Mom2= sh.getReFitPosDirPval(t2r) + mass1 = pdg.GetParticle(tree.FitTracks[t1].getFittedState().getPDG()).Mass() + mass2 = pdg.GetParticle(tree.FitTracks[t2].getFittedState().getPDG()).Mass() + LV1 = ROOT.TLorentzVector(Mom1*Dir1, ROOT.TMath.Sqrt( mass1*mass1 + Mom1*Mom1 )) + LV2 = ROOT.TLorentzVector(Mom2*Dir2, ROOT.TMath.Sqrt( mass2*mass2 + Mom2*Mom2 )) + HNLMom = LV1+LV2 + if LV1 and LV2: + dminpt = min([LV1.Pt(), LV2.Pt()]) + dminp = min([LV1.P(), LV2.P()]) + + if (ntr<2) or (nref!=2) or (not dminp) or (not dminpt) or (not HNLMom): + dp, dpt = [], [] + for tr in [t1, t2]: + x = tree.FitTracks[tr] + xx = x.getFittedState() + dp.append(xx.getMom().Mag()); dpt.append(xx.getMom().Pt()) + dminpt = min(dpt) + dminp = min(dp) + HNLMom = ROOT.TLorentzVector() + particle.Momentum(HNLMom) + tools.Push(DaughtersMinP, dminp) + tools.Push(DaughtersMinPt, dminpt) + tools.Push(Mass, HNLMom.M()) + tools.Push(Pt, HNLMom.Pt()) + tools.Push(P, HNLMom.P()) + +def vertexInfo(tree, particle, ntr, nref): + # By particle + global vtxx, vtxy, vtxz + global IP0, DOCA + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + + if ntr>1 and nref==2:#nf>1 + assert( len(sh.getReFitTrIDs())==2 ) + t1r,t2r = sh.getReFitTrIDs()[0], sh.getReFitTrIDs()[1] + #print tree.fitTrack2MC[t1], t1r, tree.fitTrack2MC[t2], t2r + #print ntr, nref, len(sh._StrawHits__docaEval) + doca = sh.getDoca()#sh._StrawHits__docaEval[-1]#getDoca() + v = sh.getReFitVertex() + if v and doca: + xv = v.X(); yv = v.Y(); zv = v.Z() + Pos1, Dir1, Mom1= sh.getReFitPosDirPval(t1r) + Pos2, Dir2, Mom2= sh.getReFitPosDirPval(t2r) + mass1 = pdg.GetParticle(tree.FitTracks[t1].getFittedState().getPDG()).Mass() + mass2 = pdg.GetParticle(tree.FitTracks[t2].getFittedState().getPDG()).Mass() + LV1 = ROOT.TLorentzVector(Mom1*Dir1, ROOT.TMath.Sqrt( mass1*mass1 + Mom1*Mom1 )) + LV2 = ROOT.TLorentzVector(Mom2*Dir2, ROOT.TMath.Sqrt( mass2*mass2 + Mom2*Mom2 )) + HNLMom = LV1+LV2 + + # If something went wrong, take the standard values + if (ntr<2) or (nref!=2) or (not v) or (not doca) or (not HNLMom):#(nf<2) + PosDir = {} + for tr in [t1,t2]: + xx = tree.FitTracks[tr].getFittedState() + PosDir[tr] = [xx.getPos(),xx.getDir()] + xv,yv,zv,doca = myVertex(t1,t2,PosDir) + HNLMom = ROOT.TLorentzVector() + particle.Momentum(HNLMom) + + tools.Push(DOCA, doca) + tools.Push(vtxx, xv); tools.Push(vtxy, yv); tools.Push(vtxz, zv) + + # impact parameter to target + #HNLPos = ROOT.TLorentzVector() + #particle.ProductionVertex(HNLPos) + HNLPos = ROOT.TVector3(xv, yv, zv) + tr = ROOT.TVector3(0,0,ShipGeo.target.z0) + t = 0 + for i in range(3): t += HNLMom(i)/HNLMom.P()*(tr(i)-HNLPos(i)) + ip = 0 + for i in range(3): ip += (tr(i)-HNLPos(i)-t*HNLMom(i)/HNLMom.P())**2 + ip = ROOT.TMath.Sqrt(ip) + tools.Push(IP0, ip) + + +def prepareFillingsByParticle(): + # By event + global DaughtersAlwaysIn, DaughtersFitConverged, MinDaughtersNdf, MaxDaughtersRedChi2 + global NoB_MinDaughtersNdf, NoB_MaxDaughtersRedChi2 + global Has1Muon1, Has1Muon2, Has2Muon1, Has2Muon2, HasEcal + global vtxx, vtxy, vtxz, IP0, DOCA + global NoB_vtxx, NoB_vtxy, NoB_vtxz, NoB_IP0, NoB_DOCA + global DaughtersMinP, DaughtersMinPt, Mass, P, Pt + global NoB_DaughtersMinP, NoB_DaughtersMinPt, NoB_Mass, NoB_P, NoB_Pt + tools.PutToZero(DaughtersAlwaysIn) + tools.PutToZero(Has2Muon1); tools.PutToZero(Has2Muon2); tools.PutToZero(HasEcal) + tools.PutToZero(Has1Muon1); tools.PutToZero(Has1Muon2) + tools.PutToZero(DOCA) + tools.PutToZero(vtxx); tools.PutToZero(vtxy); tools.PutToZero(vtxz) + tools.PutToZero(IP0) + tools.PutToZero(NoB_DOCA) + tools.PutToZero(NoB_vtxx); tools.PutToZero(NoB_vtxy); tools.PutToZero(NoB_vtxz) + tools.PutToZero(NoB_IP0) + tools.PutToZero(MinDaughtersNdf); tools.PutToZero(MaxDaughtersRedChi2) + tools.PutToZero(NoB_MinDaughtersNdf); tools.PutToZero(NoB_MaxDaughtersRedChi2) + tools.PutToZero(DaughtersFitConverged) + tools.PutToZero(DaughtersMinP); tools.PutToZero(DaughtersMinPt) + tools.PutToZero(P); tools.PutToZero(Pt); tools.PutToZero(Mass) + tools.PutToZero(NoB_DaughtersMinP); tools.PutToZero(NoB_DaughtersMinPt) + tools.PutToZero(NoB_P); tools.PutToZero(NoB_Pt); tools.PutToZero(NoB_Mass) + ntr = sh.readEvent() + nref = 0 + if ntr>1: + nref = sh.FitTracks() + #print ntr, nref + return ntr, nref + + +def pushOfflineByEvent(tree, vetoPoints, datatype, verbose, threshold): + # True HNL decay vertex (only for signal normalisation) + signalNormalisationZ(tree, datatype, verbose) + ## Number of particles + #nParticles(tree) + # Empties arrays filled by particle + ntr, nref = prepareFillingsByParticle() + # Liquid scintillator segments + global nodes + tools.hitSegments(vetoPoints, nodes, threshold) + return ntr, nref + +def pushOfflineByParticle(tree, particle, ntr, nref): + hasEcalAndMuons(tree, particle) + goodBehavedTracks(tree, particle) + NoB_chi2Ndf(tree, particle) + chi2Ndf(tree, particle, ntr, nref) + NoB_vertexInfo(tree, particle) + vertexInfo(tree, particle, ntr, nref) + NoB_kinematics(tree, particle) + kinematics(tree, particle, ntr, nref) + +fM, tgeom, gMan, geoMat, matEff, modules, run = None, None, None, None, None, None, None + +def initBField(fileNameGeo): + global fM, tgeom, gMan, geoMat, matEff, modules, run, sh + run = ROOT.FairRunSim() + modules = shipDet_conf.configure(run,ShipGeo) + tgeom = ROOT.TGeoManager("Geometry", "Geane geometry") + gMan = tgeom.Import(fileNameGeo) + geoMat = ROOT.genfit.TGeoMaterialInterface() + matEff = ROOT.genfit.MaterialEffects.getInstance() + matEff.init(geoMat) + bfield = ROOT.genfit.BellField(ShipGeo.Bfield.max, ShipGeo.Bfield.z, 2, ShipGeo.Yheight/2.) + fM = ROOT.genfit.FieldManager.getInstance() + fM.init(bfield) + +pdg, sh = None, None \ No newline at end of file diff --git a/SWforYandex/tools.py b/SWforYandex/tools.py new file mode 100755 index 0000000..b1b25c0 --- /dev/null +++ b/SWforYandex/tools.py @@ -0,0 +1,355 @@ +#from elena import * +import math +from array import array +from collections import OrderedDict +import ROOT + +def findDimentionBoxElement(node): + sh = node.GetVolume().GetShape() + if sh.IsCylType(): + #print node.GetName(), " is a cylinder", sh.GetRmin(), sh.GetRmax() + if sh.HasRmin(): + r = (sh.GetRmax() - sh.GetRmin()) + else: + r = 0. + return {'x':sh.GetDX(), + 'y':sh.GetDY(), + 'z':sh.GetDZ(), + 'r':r} + return {'x':sh.GetDX(), + 'y':sh.GetDY(), + 'z':sh.GetDZ()} + +def findPositionElement(node): + pos = node.GetMatrix().GetTranslation() + sh = node.GetVolume().GetShape() + if sh.IsCylType(): + if sh.HasRmin(): + r = (sh.GetRmax() - sh.GetRmin())/2. + else: + r = sh.GetRmax() + return {'x':pos[0], + 'y':pos[1], + 'z':pos[2], + 'r':r} + return {'x':pos[0], + 'y':pos[1], + 'z':pos[2]} + +def findPositionElement2(node,topPos): + local_pos = node.GetMatrix().GetTranslation() + pos = [] + for i in xrange(3): + pos.append(local_pos[i]+topPos[i]) + sh = node.GetVolume().GetShape() + if sh.IsCylType(): + if sh.HasRmin(): + r = (sh.GetRmax() - sh.GetRmin())/2. + else: + r = sh.GetRmax() + return {'x':pos[0], + 'y':pos[1], + 'z':pos[2], + 'r':r} + return {'x':pos[0], + 'y':pos[1], + 'z':pos[2]} + +def findDimentionBoxElement2(node,top): + sh = node.GetVolume().GetShape() + if sh.IsCylType(): + #print node.GetName(), " is a cylinder", sh.GetRmin(), sh.GetRmax() + if sh.HasRmin(): + r = (sh.GetRmax() - sh.GetRmin()) + else: + r = 0. + return {'x':sh.GetDX(), + 'y':sh.GetDY(), + 'z':sh.GetDZ(), + 'r':r} + return {'x':sh.GetDX(), + 'y':sh.GetDY(), + 'z':sh.GetDZ()} + +# Custom sorting +def sortNodesBy(nodes, coord='z', what='pos', printdict=True): + d = OrderedDict(sorted(nodes.items(), key = lambda item: item[1][coord][what])) + if printdict: + print + print + print "Nodes by %s %s:"%(coord, what) + for node in d.keys(): + print node, '\t\t', (d[node][coord]['pos']-d[node][coord]['dim'])/100., ' m', '\t', 2*d[node][coord]['dim']/100., ' m' + return d + +def retrieveMCParticleInfo(sTree, key): + mcPartKey = sTree.fitTrack2MC[key] + mcPart = sTree.MCTrack[mcPartKey] + if not mcPart: + print "Error in retrieveMCParticleInfo" + sys.exit() + mother = sTree.MCTrack[mcPart.GetMotherId()] + #print mcPartKey, mcPart, mcPart.GetMotherId(), mother + try: + mumId = mother.GetPdgCode() + except: + mumId = 0 + return int(mcPart.GetPdgCode()), int(mumId), mcPart.GetStartX(), mcPart.GetStartY(), mcPart.GetStartZ() + + +def AddVect(t,name,vectType): + vect = ROOT.vector(vectType)() + t.Branch( name, vect ) + return t, vect + +def AddVar(t,name,varType): + var = array(varType[0],[-999]) + t.Branch(name,var,name+"/"+varType.upper()) + return t, var + +def PutToZero(var): + if not isinstance(var, array): + var.clear() + else: + var[0] = 0 + +def Push(leaf, value): + if not isinstance(leaf, array): + leaf.push_back(value) + else: + leaf[0] = value + + +def wasFired(indexKids, detPoints, detPos, pointsVects=None, Ethr=0): + def lookingForHits(detPoints,flag,nstat,nstat_eff,indexKids,Eloss,Ethr): + for hit in detPoints: + if (indexKids is None) or (hit.GetTrackID() in indexKids): + #print RPChit.GetTrackID(), t_ID + # check if it is in one of the considered active layer + for pos in detPos: + if pos[0]<=hit.GetZ()<=pos[1]: + Eloss += hit.GetEnergyLoss() + #print pos, hit.GetZ() + if pointsVects is not None: + pointsVects[0].push_back(hit.GetX()) + pointsVects[1].push_back(hit.GetY()) + pointsVects[2].push_back(hit.GetZ()) + + flag = True + nstat+=1 + #eff_val = gRandom.Uniform(0.,1.) + #if eff_val<0.9: + # flag_eff = flag_eff or True + # nstat_eff+=1 + #else: + # flag_eff = flag_eff or False + flag_Ethr = Eloss>=Ethr + return flag, nstat, nstat_eff, Eloss, flag_Ethr + # Now in partKidTrackID I should have the trackID connected to my charged particles + #flag_eff = False + flag = False + nstat = 0 + nstat_eff = 0 + Eloss = 0 + flag,nstat,nstat_eff,Eloss,flag_Ethr = lookingForHits(detPoints,flag,nstat,nstat_eff,indexKids,Eloss,Ethr) + #if flag==False and checkOn: + #print "To be study event %s"%entry + #PrintEventPart(particles,pdg) + #PrintRPChits(detPoints,pdg) + #print + #print + #assert(False) + #return flag, flag_eff, nstat, nstat_eff, flag_Ethr + return flag, flag_Ethr + + +#ff = ROOT.TFile("histoForWeights.root","read") +#h_GioHans = ff.Get("h_Gio") + +def calcWeight(E, w, entries, nuName, weightHist): + if "bar" in nuName: + reduction = 0.5 + flux = 6.98e+11 * 2.e+20 / 5.e+13 + else: + reduction = 1. + flux = 1.09e+12 * 2.e+20/ 5.e+13 + crossSec = 6.7e-39*E * reduction + NA = 6.022e+23 + binN = weightHist.GetXaxis().FindBin(E) + return crossSec * flux * weightHist.GetBinContent(binN) * w * NA / entries + + +def calcWeightOldNtuple(x,y,z, E, nodes, entries, weightHist, datatype): + if 'sig' in datatype: + return -999 + params = {'OPERA': {'material':'Fe','lenght':60.,}, + 'window1': {'material':'Fe','lenght':nodes["lidT1O_1"]['z']['dim']}, + 'window2': {'material':'Al','lenght':nodes["lidT1I_1"]['z']['dim']}, + 'volumeOut': {'material':'Fe','lenght':30.,}, + 'volumeIn': {'material':'Al','lenght':8.}} + materialPars = {'Fe':{'A':55.847, #g/mol # fuori + 'rho': 7874 * 1.e+3/1.e+6,#g/cm3 + }, + 'Al':{'A':26.98, #g/mol # dentro + 'rho': 2700 * 1.e+3/1.e+6 #g/cm3 + }} + perc = {'OPERA':0.33, + 'window1':0.015, + 'window2':0.015, + 'volumeOut':0.32, + 'volumeIn':0.32} + intElName = interactionElement(x,y,z, nodes) + #print intElName + NA = 6.022e+23 + material = params[intElName]['material'] + crossSec = 8.8e-39*E #1.5e-38*fabs(E) ##3./2*(1.2+0.35)*1.e-38*fabs(E) + flux = 2.e+18#5.e+16 + L = params[intElName]['lenght'] + rho = materialPars[material]['rho'] + n_element = perc[intElName]*entries + binN = weightHist.GetXaxis().FindBin(E) + weight = crossSec * NA * rho * L * flux / n_element * weightHist.GetBinContent(binN) + return weight + +def interactionElement(x,y,z, nodes): + # window1 + if nodes["lidT1O_1"]['z']['pos']-nodes["lidT1O_1"]['z']['dim'] < z < nodes["lidT1O_1"]['z']['pos']+nodes["lidT1O_1"]['z']['dim']: + return "window1" + # window2 + if nodes["lidT1I_1"]['z']['pos']-nodes["lidT1I_1"]['z']['dim'] < z < nodes["lidT1I_1"]['z']['pos']+nodes["lidT1I_1"]['z']['dim']: + return "window2" + # vacuum tank borders + if nodes["lidT1O_1"]['z']['pos']+nodes["lidT1O_1"]['z']['dim'] < z < nodes["lidT6O_1"]['z']['pos']+nodes["lidT6O_1"]['z']['dim']: # include le lid x la parte fuori ma non x la parte dentro + if inInnerLid(x,y,z, nodes): + return "volumeIn" + else: + return "volumeOut" + # opera + try: + minz, maxz = nodes["volIron_12"]['z']['pos']-nodes["volIron_12"]['z']['dim'], nodes["volIron_24"]['z']['pos']+nodes["volIron_24"]['z']['dim'] + except KeyError: + try: + minz, maxz = nodes["volLayer_11"]['z']['pos']-nodes["volLayer_11"]['z']['dim'], nodes["volLayer_0"]['z']['pos']+nodes["volLayer_0"]['z']['dim'] + except KeyError: + # Pazienza esaurita, ora lo hanno chiamato "volMagneticSpectrometer_1" ed e' lungo piu' di 9m!!! + try: + minz, maxz = nodes["volMagneticSpectrometer_1"]['z']['pos']-nodes["volMagneticSpectrometer_1"]['z']['dim'], nodes["volMagneticSpectrometer_1"]['z']['pos']+nodes["volMagneticSpectrometer_1"]['z']['dim'] + except KeyError: + print "Cannot find OPERA" + sys.exit() + #if nodes["volIron_12"]['z']['pos']-nodes["volIron_12"]['z']['dim'] < z < nodes["volIron_24"]['z']['pos']+nodes["volIron_24"]['z']['dim']: + #if nodes["volLayer_11"]['z']['pos']-nodes["volLayer_11"]['z']['dim'] < z < nodes["volLayer_0"]['z']['pos']+nodes["volLayer_0"]['z']['dim']: + if minz < z < maxz: + return "OPERA" + + +def inInnerLid(x,y,z, nodes): + if nodes["lidT1I_1"]['z']['pos']-nodes["lidT1I_1"]['z']['dim'] < z < nodes["lidT6I_1"]['z']['pos']+nodes["lidT6I_1"]['z']['dim']: + if z < nodes["Veto_5"]['z']['pos']-nodes["Veto_5"]['z']['dim']: + a,b = nodes['T1I_1']['x']['dim'], nodes['T1I_1']['y']['dim'] # smaller part of the tank (first 5 m) + else: + a,b = nodes['T2I_1']['x']['dim'], nodes['T2I_1']['y']['dim'] # larger part of the tank + if inEllipse(x,y,a,b): + return True + return False + + +def inEllipse(x,y,a,b): + if ( (x*x)/(a*a) + (y*y)/(b*b) ) < 1.: + return True + return False + +def pointInEllipse(point,a,b): + x = point.X() + y = point.Y() + return inEllipse(x,y,a,b) + +listOfHitLSSegments = None +numberOfHitLSSegments = None +zstarts = [] +zends = [] +lsNames = [] +Nz, Nphi, nBins = None, None, None +Nphi = 16 +dphi = 2.*math.pi/Nphi +phistart = dphi/2. +zin, zout = None, None +zstepsize = None +# To hold the energy loss +EnergyDeposits = [] +abig = None +asmall = None +b = None + +def makeLSsegments(nodes, tree, savelist=False): + global zstarts, zends, lsNames, Nz, Nphi, nBins, zin, zout, zstepsize + global abig, asmall, b + abig = 250.#nodes['T2LiSc_1_1']['x']['dim'] + asmall = 186.#nodes['T1LiSc_1_1']['x']['dim'] + b = 500.#nodes['T2LiSc_1_1']['y']['dim'] + #print abig, asmall, b + for node in nodes.keys(): + if 'LiSc' in node: + zstarts.append(nodes[node]['z']['pos']-nodes[node]['z']['dim']) + zends.append(nodes[node]['z']['pos']+nodes[node]['z']['dim']) + lsNames.append(node) + # ATTENTION! there is some superposition in z + # To keep it clean & easy, we will do the segmentation + # as Martin first suggested, i.e. by hands!!! + # It cannot be so bad... + zstarts.sort() + zends.sort() + #Nz = len(zstarts) + zin = min(zstarts) + zout =max(zends) + #print 'zstart: ', zin, 'zend: ', zout + zstepsize = 100. + Nz = int(math.ceil((zout-zin)/zstepsize)) + #print Nphi, Nz, nBins + nBins = Nphi*Nz + # Init energy deposit to 0. + for i in xrange(nBins): + EnergyDeposits.append(0.) + global listOfHitLSSegments, numberOfHitLSSegments, EnergyDeposits + if savelist: + tree, listOfHitLSSegments = AddVect(tree, 'listOfHitLSSegments', 'int') + tree, numberOfHitLSSegments = AddVar(tree, 'numberOfHitLSSegments', 'int') + +def hitSegments(vetoPoints, nodes, threshold, savelist=False): + global listOfHitLSSegments, numberOfHitLSSegments, EnergyDeposits + global abig, asmall, b, phistart, dphi, Nphi, nBins, zin, zout + # Init energy deposit to 0. + for i in xrange(nBins): + EnergyDeposits[i]=0. + endsmall = nodes['T1Endplate_1']['z']['pos']+nodes['T1Endplate_1']['z']['dim'] + #print 'endsmall: ', endsmall + #print 'nBins: ', nBins, 'len(list): ',len(EnergyDeposits) + for hit in vetoPoints: + z = hit.GetZ() + if (z<(nodes['VetoTimeDet_1']['z']['pos']+nodes['VetoTimeDet_1']['z']['dim']) + or z > zout): + continue + x = hit.GetX() + y = hit.GetY() + a = abig + if z < endsmall: + a = asmall + phi = ROOT.TMath.ATan2(a*y,b*x)+2*math.pi + zbin = ROOT.TMath.FloorNint((z-zin)/zstepsize) + phibin = ROOT.TMath.FloorNint((phi+phistart)/dphi)%Nphi + iBin = zbin*Nphi+phibin + try: + EnergyDeposits[iBin] += hit.GetEnergyLoss() + except: + print 'hitSegments: could not find bin ', iBin + print x, y, z + sys.exit() + nHit = 0 + for iBin in xrange(nBins): + if EnergyDeposits[iBin] > threshold: + nHit +=1 + if savelist: + Push(listOfHitLSSegments, int(iBin)) + Push(numberOfHitLSSegments, nHit) + + diff --git a/ana_newNtuple.py b/ana_newNtuple.py new file mode 100644 index 0000000..26f13b8 --- /dev/null +++ b/ana_newNtuple.py @@ -0,0 +1,204 @@ +from ROOT import * +gROOT.ProcessLine(".x mystyle.C") + +'''f = TFile("ntupleStudy_tot_debug_nu_highFlux2.root") +t = f.Get("t") +#fanti = TFile("ntupleStudy_tot_debug_antinu_highFlux2.root") +#tanti = f.Get("t") +fanti = TFile("ntupleStudy_tot_debug_nu_highFlux2.root") +tanti = fanti.Get("t") +''' + +#f = TFile("/afs/cern.ch/work/b/bstora/data/fromAnalysis/ntupleStudy_highFlux_nu_77_77.root ") +#t = f.Get("t") +fanti = TFile("/afs/cern.ch/work/b/bstora/data/fromAnalysis/ntupleStudy_highFlux_antinu_76_78.root") +tanti = fanti.Get("t") + +f = TFile("/afs/cern.ch/work/b/bstora/ShipAna_Barbara_nu.root") +t = f.Get("t") + +plotFolder = "/afs/cern.ch/work/b/bstora/plots/nuBackground/" + +dictNodeNames = {'volIron':0, 'cave':1, 'LiSc':2, 'Startplate':3, 'TI':4, 'rockD':5, 'Endplate':6, 'Rib':7, 'volFeYoke':8, 'volHPT':9, 'TO':10, 'volRpc':11, 'volCoil':12, 'T1Lid':13, 'straw':14, 'strawVeto':15, 'volBase':16, 'Tr':17, 'gas':18, 'wire':19, 'others':20} + +dictNodeNames2 = {0:'volIron', 1:'cave', 2:'LiSc', 3:'Startplate', 4:'TI', 5:'rockD', 6:'Endplate', 7:'Rib', 8:'volFeYoke', 9:'volHPT', 10:'TO', 11:'volRpc', 12:'volCoil', 13:'T1Lid', 14:'straw', 15:'strawVeto', 16:'volBase', 17:'Tr', 18:'gas', 19:'wire', 20:'others'} + +def makePlotLabel(t, var, cut, cname, label=True): + t.Draw(var, cut) + h = t.GetHistogram() + nbins = h.GetNbinsX() + h_id = TH1F("h_id>>h_%s"%cname, "h_id", nbins, 0, nbins) + if label: + h_id.LabelsOption("U") + for i in xrange(1,nbins+1): + h_id.SetBinContent(i,h.GetBinContent(i)) + if label: + h_id.GetXaxis().SetBinLabel(i, dictNodeNames2[int(h.GetBinCenter(i))]) + + n = h_id.GetSum() + c = None + if not cname is None: + c = TCanvas(cname,cname) + h_id.Draw() + c.Print(plotFolder+c.GetName()+".eps") + c.Print(plotFolder+c.GetName()+".pdf") + return c, h_id, n + +c, h, nW = makePlotLabel(t,"event", "(isPrimary==1)*weight",None,False) +c, h, nantiW = makePlotLabel(tanti,"event", "(isPrimary==1)*weight",None,False) + + +c, h, nreco_nu = makePlotLabel(t,"nuIntNumSimpl", "nRecoed>0","AllRecoEd_nu") +c, h, nreco_noLS_nu = makePlotLabel(t,"nuIntNumSimpl", "nRecoed>0 && (scintVetoAny==0 || scintVetoAny_Ethr==0)","RecoEd_noLS_nu") + +c, h, nreco_antinu =makePlotLabel(tanti,"nuIntNumSimpl", "nRecoed>0","AllRecoEd_antinu") +c, h, nreco_noLS_antinu =makePlotLabel(tanti,"nuIntNumSimpl", "nRecoed>0 && (scintVetoAny==0 || scintVetoAny_Ethr==0)","RecoEd_noLS_antinu") + +c, h, nrecoW_nu = makePlotLabel(t,"nuIntNumSimpl", "(nRecoed>0)*weight","AllRecoEd_nu") +c, h, nrecoW_noLS_nu = makePlotLabel(t,"nuIntNumSimpl", "(nRecoed>0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))*weight","RecoEd_noLS_nu") + +c, h, nrecoW_antinu =makePlotLabel(tanti,"nuIntNumSimpl", "(nRecoed>0)*weight","AllRecoEd_antinu") +c, h, nrecoW_noLS_antinu =makePlotLabel(tanti,"nuIntNumSimpl", "(nRecoed>0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))*weight","RecoEd_noLS_antinu") + +colorNu = "blue" +colorAnti = "green" +print +print "*****************" +print + +t_tot = t.GetEntries() +tanti_tot = tanti.GetEntries() + +print "Few numbers reweighed (entries): " +print " \\begin{itemize}" +print " \\item Total $\\nu$ entries: %0.f (%s)"%(nW,t_tot) +print " \\begin{itemize} \\item \\textcolor{%s}{Reconstructed: %.0f (%s)} \\end{itemize}"%(colorNu, nrecoW_nu, nreco_nu) +print " \\item Total $\\bar{\\nu}$ entries: %.0f (%s)"%(nantiW,tanti_tot) +print " \\begin{itemize} \\item \\textcolor{%s}{Reconstructed: %.0f (%s)} \end{itemize}"%(colorAnti, nrecoW_antinu, nreco_antinu) +print " \\end{itemize}" + +print +print "*****************" +print + +print "Events not vetoed by the LS, no requirements on the other systems (entries in brackets): " +print " \\begin{itemize}" +print " \\item Total $\\nu$ entries: %0.f (%s)"%(nW,t.GetEntries()) +print " \\begin{itemize} \\item \\textcolor{%s}{Reconstructed: %.0f (%s)} \\end{itemize}"%(colorNu,nrecoW_noLS_nu,nreco_noLS_nu) +print " \\item Total $\\bar{\\nu}$ entries: %0.f (%s)"%(nantiW,tanti.GetEntries()) +print " \\begin{itemize} \\item \\textcolor{%s}{Reconstructed: %.0f (%s)} \end{itemize}"%(colorAnti, nrecoW_noLS_antinu, nreco_noLS_antinu) +print " \\end{itemize}" + +print +print "*****************" +print + +c, h, nreco_nu_allVeto = makePlotLabel(t,"nuIntNumSimpl", "(nRecoed>0 && (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)","reco_nu_allVeto") +c, h, nreco_antinu_allVeto =makePlotLabel(tanti,"nuIntNumSimpl", "(nRecoed>0 && (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)","reco_antinu_allVeto") +c, h, nrecoW_nu_allVeto = makePlotLabel(t,"nuIntNumSimpl", "(nRecoed>0 && (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)*weight","recoW_nu_allVeto") +c, h, nrecoW_antinu_allVeto =makePlotLabel(tanti,"nuIntNumSimpl", "(nRecoed>0 && (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)*weight","recoW_antinu_allVeto") + + +c, h, nnu_allVeto90 = makePlotLabel(t,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny_eff==0 && upstreamVetoAny_eff==0 && RPCany_eff==0 && TrackSyst==1)","nu_allVeto90") +c, h, nantinu_allVeto90 =makePlotLabel(tanti,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny_eff==0 && upstreamVetoAny_eff==0 && RPCany_eff==0 && TrackSyst==1)","antinu_allVeto90") +c, h, nW_nu_allVeto90 = makePlotLabel(t,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny_eff==0 && upstreamVetoAny_eff==0 && RPCany_eff==0 && TrackSyst==1)*weight","W_nu_allVeto90") +c, h, nW_antinu_allVeto90 =makePlotLabel(tanti,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny_eff==0 && upstreamVetoAny_eff==0 && RPCany_eff==0 && TrackSyst==1)*weight","W_antinu_allVeto90") + +c, h, nnu_allVeto = makePlotLabel(t,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)","nu_allVeto") +c, h, nantinu_allVeto =makePlotLabel(tanti,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)","antinu_allVeto") +c, h, nW_nu_allVeto = makePlotLabel(t,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)*weight","W_nu_allVeto") +c, h, nW_antinu_allVeto =makePlotLabel(tanti,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)*weight","W_antinu_allVeto") + +print +print "*****************" +print + +print "Reweighted events with number of entries in the ntuple in brackets" +print "\\begin{itemize}" +print "\\item Number of interacting \\textcolor{%s}{$\\nu_\\mu$ %.0f (%s)} and \\textcolor{%s}{$\\bar{\\nu_\\mu}$ %.0f (%s)}"%(colorNu, nW, t.GetEntries(), colorAnti, nantiW, tanti.GetEntries()) +print "\\item Applying all the veto systems (E-threshold for the LS at 15MeV): \\textcolor{%s}{ %.0f (%s)} \\textcolor{%s}{ %.0f (%s)}"%(colorNu, nW_nu_allVeto,nnu_allVeto, colorAnti, nW_antinu_allVeto,nantinu_allVeto) +print " \\begin{itemize} \\item In case each system is with $0.9$ efficiency: \\textcolor{%s}{ %.0f (%s)} \\textcolor{%s}{ %.0f (%s)} \\end{itemize}"%(colorNu, nW_nu_allVeto90,nnu_allVeto90, colorAnti, nW_antinu_allVeto90,nantinu_allVeto90) +print " \item Applying reconstruction:\\textcolor{%s}{ %.0f (%s)} \\textcolor{%s}{ %.0f (%s)} "%(colorNu, nrecoW_nu_allVeto,nreco_nu_allVeto, colorAnti, nrecoW_antinu_allVeto,nreco_antinu_allVeto) +# \item Applying offline selection: () +print "\\end{itemize}" + +print +print "*****************" +print + +print +print "*****************" +print + +c, h, nnu_noOPERA = makePlotLabel(t,"event", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && upstreamVetoAny==0 && TrackSyst==1)",None,False) +c, h, nWnu_noOPERA = makePlotLabel(t,"event", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && upstreamVetoAny==0 && TrackSyst==1)*weight",None,False) + +c, h, nnu_noUpstream = makePlotLabel(t,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && RPCany==0 && TrackSyst==1)",None,False) +c, h, nWnu_noUpstream = makePlotLabel(t,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && RPCany==0 && TrackSyst==1)*weight",None,False) + +c, h, nnu_noStraw = makePlotLabel(t,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)",None,False) +c, h, nWnu_noStraw = makePlotLabel(t,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)*weight",None,False) + +c, h, nantinu_noOPERA = makePlotLabel(tanti,"event", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && upstreamVetoAny==0 && TrackSyst==1)",None,False) +c, h, nWantinu_noOPERA = makePlotLabel(tanti,"event", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && upstreamVetoAny==0 && TrackSyst==1)*weight",None,False) + +c, h, nantinu_noUpstream = makePlotLabel(tanti,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && RPCany==0 && TrackSyst==1)",None,False) +c, h, nWantinu_noUpstream = makePlotLabel(tanti,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && strawVetoAny==0 && RPCany==0 && TrackSyst==1)*weight",None,False) + +c, h, nantinu_noStraw = makePlotLabel(tanti,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)",None,False) +c, h, nWantinu_noStraw = makePlotLabel(tanti,"nuIntNumSimpl", "( (scintVetoAny==0 || scintVetoAny_Ethr==0) && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)*weight",None,False) + +c, h, nantinu_noLS = makePlotLabel(tanti,"nuIntNumSimpl", "(strawVetoAny==0 && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)",None,False) +c, h, nWantinu_noLS = makePlotLabel(tanti,"nuIntNumSimpl", "( strawVetoAny==0 && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)*weight",None,False) +c, h, nnu_noLS = makePlotLabel(t,"nuIntNumSimpl", "(strawVetoAny==0 && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)",None,False) +c, h, nWnu_noLS = makePlotLabel(t,"nuIntNumSimpl", "( strawVetoAny==0 && upstreamVetoAny==0 && RPCany==0 && TrackSyst==1)*weight",None,False) + + +c, h, nWantinu_tracking = makePlotLabel(tanti,"event", "(TrackSyst==1)*weight",None,False) +c, h, nantinu_tracking = makePlotLabel(tanti,"event", " (TrackSyst==1)",None,False) +c, h, nWnu_tracking = makePlotLabel(t,"event", "(TrackSyst==1)*weight",None,False) +c, h, nnu_tracking = makePlotLabel(t,"event", "(TrackSyst==1)",None,False) + + +print +print "*****************" +print + +print "\\begin{frame}[c]{Effect of each singular system}" +print " \\begin{itemize}" +print "\\item Requiring at least 1 hit in the tracking station: \\textcolor{%s}{ %.0f (%s)} \\textcolor{%s}{ %.0f (%s)}"%(colorNu,nWnu_tracking, nnu_tracking,colorAnti, nWantinu_tracking, nantinu_tracking) +print " \\item No OPERA-system: \\textcolor{%s}{ %.0f (%s)} \\textcolor{%s}{ %.0f (%s)}"%(colorNu,nWnu_noOPERA,nnu_noOPERA,colorAnti,nWantinu_noOPERA,nantinu_noOPERA ) +print " \\item No upstream-veto: \\textcolor{%s}{ %.0f (%s)} \\textcolor{%s}{ %.0f (%s)}"%(colorNu,nWnu_noUpstream,nnu_noUpstream,colorAnti,nWantinu_noUpstream,nantinu_noUpstream) +print " \\item No straw-veto: \\textcolor{%s}{ %.0f (%s)} \\textcolor{%s}{ %.0f (%s)}" %(colorNu,nWnu_noStraw,nnu_noStraw,colorAnti,nWantinu_noStraw,nantinu_noStraw ) +print " \\item No LS: \\textcolor{%s}{ %.0f (%s)} \\textcolor{%s}{ %.0f (%s)}" %(colorNu,nWnu_noLS,nnu_noLS,colorAnti,nWantinu_noLS,nantinu_noLS) + +print " \\end{itemize}" +print +print "*****************" +print + +# +#### everything vetoed by the upstream is at very very high y +#### as long as the opera system is used as veto-system we can just build an upstream detector between 400<|y|<600 +#c, h, n = makePlotLabel("upstreamVetoPoint_y", "(isPrimary==1 && strawVetoAny==0 && RPCany==0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))*weight",,False) +# t.Draw("upstreamVetoPoint_y", "(isPrimary==1 && RPCany_eff==0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))*weight") +# t.Draw("upstreamVetoPoint_y", "(isPrimary==1 && strawVetoAny==0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))*weight") +# ### upstream veto serve principalmente, come atteso, a togliere il background provenienti dal ferro (yokes, ... ) di OPERA +# +## Somehow it does not work: +#c, h, n = makePlotLabel(t,"upstreamVetoPoint_y", "(isPrimary==1 && upstreamVetoAny==1 && strawVetoAny_eff==0 && RPCany_eff==0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))*weight", "upstreamVeto_noOthers_nu",False) +#c, h, n = makePlotLabel(tanti,"upstreamVetoPoint_y", "(isPrimary==1 && upstreamVetoAny==1 && strawVetoAny_eff==0 && RPCany_eff==0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))*weight", "upstreamVeto_noOthers_antinu",False) +# DO: +# >>> t.Draw("upstreamVetoPoint_y", "(isPrimary==1 && upstreamVetoAny==1 && strawVetoAny_eff==0 && RPCany_eff==0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))*weight") +# >>> tanti.Draw("upstreamVetoPoint_y", "(isPrimary==1 && upstreamVetoAny==1 && strawVetoAny_eff==0 && RPCany_eff==0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))*weight") + +c, h, n_reco_Upstream_noOthers_nu = makePlotLabel(t,"event", "(recoed>0 && isPrimary==1 && upstreamVetoAny==1 && strawVetoAny_eff==0 && RPCany_eff==0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))", None,False) +c, h, n_reco_Upstream_noOthers_antinu = makePlotLabel(tanti,"event", "(recoed>0 &&isPrimary==1 && upstreamVetoAny==1 && strawVetoAny_eff==0 && RPCany_eff==0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))", None,False) +if n_reco_Upstream_noOthers_nu>0: + c, h, nW_reco_Upstream_noOthers_nu = makePlotLabel(t,"event", "(recoed>0 &&isPrimary==1 && upstreamVetoAny==1 && strawVetoAny_eff==0 && RPCany_eff==0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))*weight", None,False) +if n_reco_Upstream_noOthers_antinu>0: + c, h, nW_reco_Upstream_noOthers_antinu = makePlotLabel(tanti,"event", "(recoed>0 &&isPrimary==1 && upstreamVetoAny==1 && strawVetoAny_eff==0 && RPCany_eff==0 && (scintVetoAny==0 || scintVetoAny_Ethr==0))*weight", None,False) +print "Number of events veto-able by the upstream-veto that are reconstructed, but not vetoed by the strawVeto or the OPERA-system " +print "nu: %s "%(n_reco_Upstream_noOthers_nu) +print "anti-nu: %s"%(n_reco_Upstream_noOthers_antinu) + diff --git a/distribsForHNLandBG_byEvent.py b/distribsForHNLandBG_byEvent.py index dcca120..92991a2 100755 --- a/distribsForHNLandBG_byEvent.py +++ b/distribsForHNLandBG_byEvent.py @@ -9,115 +9,110 @@ pdg = r.TDatabasePDG.Instance() def addPlot(key, x_axis, tree, string, cuts=None): - if not cuts: - tree.Draw(string+'>>h1') - else: - tree.Draw(string+'>>h1', cuts) - plots[key] = r.gDirectory.Get('h1') - plots[key].GetXaxis().SetTitle(x_axis) - plots[key].SetTitle(key) - plots[key].SetName(key) - c1 = r.TCanvas(); c1.cd() - if "IP" in key or "Mass" in key or "DOCA" in key or "dChi2" in key: - c1.SetLogy() - plots[key].Draw() - c1.Print('accPlots/%s.pdf'%key) - c1.Print('accPlots/%s.png'%key) - key += "-WEIGHTED" - if 'bg' in key or ('nu' in key and key != 'mumunu'): - if not cuts: - tree.Draw(string+'>>h1', "NuWeight") - else: - cuts = "NuWeight*("+cuts+")" - tree.Draw(string+'>>h1', cuts) - plots[key] = r.gDirectory.Get('h1') - plots[key].GetXaxis().SetTitle(x_axis) - plots[key].SetTitle(key) - plots[key].SetName(key) - c1 = r.TCanvas(); c1.cd() - if "IP" in key or "Mass" in key or "DOCA" in key or "dChi2" in key: - c1.SetLogy() - plots[key].Draw() - c1.Print('accPlots/%s.pdf'%key) - c1.Print('accPlots/%s.png'%key) - elif 'cosmics' in key: - if not cuts: - tree.Draw(string+'>>h1',"HNLw*1.e6/200.") - else: - cuts = "HNLw*1.e6/200.*("+cuts+")" - tree.Draw(string+'>>h1', cuts) - plots[key] = r.gDirectory.Get('h1') - plots[key].GetXaxis().SetTitle(x_axis) - plots[key].SetTitle(key) - plots[key].SetName(key) - c1 = r.TCanvas(); c1.cd() - if "IP" in key or "Mass" in key or "DOCA" in key or "dChi2" in key: - c1.SetLogy() - plots[key].Draw() - c1.Print('accPlots/%s.pdf'%key) - c1.Print('accPlots/%s.png'%key) - else: - if not cuts: - tree.Draw(string+'>>h1',"HNLw") - else: - cuts = "HNLw*("+cuts+")" - tree.Draw(string+'>>h1', cuts) - plots[key] = r.gDirectory.Get('h1') - plots[key].GetXaxis().SetTitle(x_axis) - plots[key].SetTitle(key) - plots[key].SetName(key) - c1 = r.TCanvas(); c1.cd() - if "IP" in key or "Mass" in key or "DOCA" in key or "dChi2" in key: - c1.SetLogy() - plots[key].Draw() - c1.Print('accPlots/%s.pdf'%key) - c1.Print('accPlots/%s.png'%key) + if not cuts: + tree.Draw(string+'>>h1') + else: + tree.Draw(string+'>>h1', cuts) + plots[key] = r.gDirectory.Get('h1') + plots[key].GetXaxis().SetTitle(x_axis) + plots[key].SetTitle(key) + plots[key].SetName(key) + c1 = r.TCanvas(); c1.cd() + if "IP" in key or "Mass" in key or "DOCA" in key or "dChi2" in key: + c1.SetLogy() + plots[key].Draw() + c1.Print('accPlots/%s.pdf'%key) + c1.Print('accPlots/%s.png'%key) + key += "-WEIGHTED" + if 'bg' in key or ('nu' in key and key != 'mumunu'): + if not cuts: + tree.Draw(string+'>>h1', "NuWeight") + else: + cuts = "NuWeight*("+cuts+")" + tree.Draw(string+'>>h1', cuts) + plots[key] = r.gDirectory.Get('h1') + plots[key].GetXaxis().SetTitle(x_axis) + plots[key].SetTitle(key) + plots[key].SetName(key) + c1 = r.TCanvas(); c1.cd() + if "IP" in key or "Mass" in key or "DOCA" in key or "dChi2" in key: + c1.SetLogy() + plots[key].Draw() + c1.Print('accPlots/%s.pdf'%key) + c1.Print('accPlots/%s.png'%key) + elif 'cosmics' in key: + if not cuts: + tree.Draw(string+'>>h1',"HNLw*1.e6/200.") + else: + cuts = "HNLw*1.e6/200.*("+cuts+")" + tree.Draw(string+'>>h1', cuts) + plots[key] = r.gDirectory.Get('h1') + plots[key].GetXaxis().SetTitle(x_axis) + plots[key].SetTitle(key) + plots[key].SetName(key) + c1 = r.TCanvas(); c1.cd() + if "IP" in key or "Mass" in key or "DOCA" in key or "dChi2" in key: + c1.SetLogy() + plots[key].Draw() + c1.Print('accPlots/%s.pdf'%key) + c1.Print('accPlots/%s.png'%key) + else: + if not cuts: + tree.Draw(string+'>>h1',"HNLw") + else: + cuts = "HNLw*("+cuts+")" + tree.Draw(string+'>>h1', cuts) + plots[key] = r.gDirectory.Get('h1') + plots[key].GetXaxis().SetTitle(x_axis) + plots[key].SetTitle(key) + plots[key].SetName(key) + c1 = r.TCanvas(); c1.cd() + if "IP" in key or "Mass" in key or "DOCA" in key or "dChi2" in key: + c1.SetLogy() + plots[key].Draw() + c1.Print('accPlots/%s.pdf'%key) + c1.Print('accPlots/%s.png'%key) -fpimu = r.TFile('../DATA/NewPIMU/ShipAna.root','read')#r.TFile('../DATA/MUPI/ShipAna.root','read') -pimu = fpimu.Get('ShipAna') +fpimu = r.TFile('../DATA/NewPIMU/ShipAna_Barbara_wholeStat.root','read')#r.TFile('../DATA/MUPI/ShipAna.root','read') +pimu = fpimu.Get('t') pimu_geo = tools.searchForNodes3_xyz_dict('../DATA/NewPIMU/geofile_full.10.0.Pythia8-TGeant4-1.0GeV-008.root')#'../DATA/MUPI/geofile_full.10.0.Pythia8-TGeant4-1.0GeV-008-2985556.root') -fmumunu = r.TFile('../DATA/NewMUMUNU/ShipAna.root','read')#r.TFile('../DATA/MUMUNU/ShipAna.root','read') -mumunu = fmumunu.Get('ShipAna') +fmumunu = r.TFile('../DATA/NewMUMUNU/ShipAna_Barbara_wholeStat.root','read')#r.TFile('../DATA/MUMUNU/ShipAna.root','read') +mumunu = fmumunu.Get('t') mumunu_geo = tools.searchForNodes3_xyz_dict('../DATA/NewMUMUNU/geofile_full.10.0.Pythia8-TGeant4-1.0GeV-008-mumunu.root')#'../DATA/MUMUNU/geofile_full.10.0.Pythia8-TGeant4-1.0GeV-008-TOTAL.root') -ftiny = r.TFile('../DATA/SmallHNLs/ShipAna.root', 'read') -tiny = ftiny.Get('ShipAna') +ftiny = r.TFile('../DATA/SmallHNLs/ShipAna_Barbara_wholeStat.root', 'read') +tiny = ftiny.Get('t') tiny_geo = tools.searchForNodes3_xyz_dict('../DATA/SmallHNLs/geofile_full.10.0.Pythia8-TGeant4-0.1GeV-011.root') -#fbg = r.TFile('../DATA/KLONG/ShipAna.root','read') -#bg = fbg.Get('ShipAna') -#bg_geo = tools.searchForNodes2_xyz_dict('../DATA/KLONG/geofile_full.10.0.Genie-TGeant4_70cc30nc.root') - -fcosmics = r.TFile('../DATA/Cosmics/ShipAna.root','read') -cosmics = fcosmics.Get('ShipAna') -cosmics_geo = tools.searchForNodes2_xyz_dict('../DATA/Cosmics/geofile_full.Signal.10.0.Cosmics3.25.1-8.root') - -fnubar = r.TFile('../DATA/NewKLONG/ShipAna_nubar.root','read')#'../DATA/NewKLONG/ShipAna74-75_nubar.root','read') -nubar = fnubar.Get('ShipAna') -nubar_geo = tools.searchForNodes3_xyz_dict('../DATA/NewKLONG/geofile_full.10.0.Genie-TGeant4_nubar.root')#neutrino74-75.root') - -fnu = r.TFile('../DATA/NewKLONG/ShipAna_nu.root','read')#'../DATA/NewKLONG/ShipAna77_nu.root','read') -nu = fnu.Get('ShipAna') -nu_geo = tools.searchForNodes3_xyz_dict('../DATA/NewKLONG/geofile_full.10.0.Genie-TGeant4_nu.root')#neutrino77.root') +#fcosmics = r.TFile('../DATA/Cosmics/ShipAna.root','read') +#cosmics = fcosmics.Get('ShipAna') +#cosmics_geo = tools.searchForNodes2_xyz_dict('../DATA/Cosmics/geofile_full.Signal.10.0.Cosmics3.25.1-8.root') +# +#fnubar = r.TFile('../DATA/NewKLONG/ShipAna_nubar.root','read')#'../DATA/NewKLONG/ShipAna74-75_nubar.root','read') +#nubar = fnubar.Get('ShipAna') +#nubar_geo = tools.searchForNodes3_xyz_dict('../DATA/NewKLONG/geofile_full.10.0.Genie-TGeant4_nubar.root')#neutrino74-75.root') +# +#fnu = r.TFile('../DATA/NewKLONG/ShipAna_nu.root','read')#'../DATA/NewKLONG/ShipAna77_nu.root','read') +#nu = fnu.Get('ShipAna') +#nu_geo = tools.searchForNodes3_xyz_dict('../DATA/NewKLONG/geofile_full.10.0.Genie-TGeant4_nu.root')#neutrino77.root') # For a correct normalisation, we subtract the events that have an HNL vertex produced outside of the 60m fiducial volume studies = { - 'pimu': {'data':pimu, 'geo':pimu_geo, 'seen':[], 'ntot':20000-4175},#1000}, - 'mumunu': {'data':mumunu, 'geo':mumunu_geo, 'seen':[], 'ntot':20000-4125},#7000}, - 'tiny': {'data': tiny, 'geo':tiny_geo, 'seen':[], 'ntot':20000-4498}, - #'bg': {'data':bg, 'geo':bg_geo, 'ntot':142856},#99999}#199998 - 'cosmics': {'data':cosmics, 'geo':cosmics_geo, 'seen':[], 'ntot':cosmics.GetEntriesFast()}, - 'nubar': {'data': nubar, 'geo':nubar_geo, 'seen':[], 'ntot':99999*2},#99999*2}, - 'nu': {'data': nu, 'geo':nu_geo, 'seen':[], 'ntot':99999*2}#99999} + 'pimu': {'data':pimu, 'geo':pimu_geo, 'seen':[], 'ntot':20000-136},#1000}, + 'mumunu': {'data':mumunu, 'geo':mumunu_geo, 'seen':[], 'ntot':20000-289},#7000}, + 'tiny': {'data': tiny, 'geo':tiny_geo, 'seen':[], 'ntot':20000-66}, + #'cosmics': {'data':cosmics, 'geo':cosmics_geo, 'seen':[], 'ntot':cosmics.GetEntriesFast()}, + #'nubar': {'data': nubar, 'geo':nubar_geo, 'seen':[], 'ntot':99999*2},#99999*2}, + #'nu': {'data': nu, 'geo':nu_geo, 'seen':[], 'ntot':99999*2}#99999} } -print 'Found %s entries in the cosmics file'%cosmics.GetEntriesFast() +#print 'Found %s entries in the cosmics file'%cosmics.GetEntriesFast() # Cuts: # - z_vertex in [vol[0]+5m, straw[0]] @@ -126,10 +121,35 @@ # - DOCA < 10 cm # - has no veto? +class MyParticle(object): + """ Simulating an ntuple filled by particle from one filled by event :) """ + def __init__(self, event, index): + self.EventNumber = event.event + self.DaughtersFitConverged = [event.DaughtersFitConverged[index], event.DaughtersFitConverged[index]] + chi2red = [event.MaxDaughtersRedChi2[index], event.MaxDaughtersRedChi2[index]] + ndf = [event.MinDaughtersNdf[index], event.MinDaughtersNdf[index]] + self.DaughtersChi2 = [chi2red[i]*ndf[i] for i in xrange(len(ndf))] + self.DaughtersNPoints = ndf + self.DOCA = event.DOCA[index] + self.vtxz = event.vtxz[index] + self.vtxy = event.vtxy[index] + self.vtxx = event.vtxx[index] + self.IP0 = event.IP0[index] + self.BadTruthVtx = event.BadTruthVtx + self.NParticles = event.nRecoed + self.DaughtersAlwaysIn = event.DaughtersAlwaysIn[index] + self.Has1Muon1 = event.Has1Muon1[index] + self.Has2Muon1 = event.Has2Muon1[index] + self.Has1Muon2 = event.Has1Muon2[index] + self.Has2Muon2 = event.Has2Muon2[index] + self.HasEcal = event.HasEcal[index] + self.HNLw = event.weight + class Cuts(object): - def __init__(self, cutConfigList, study): + def __init__(self, cutConfigList, study, byEvent=True): + self.byEvent = byEvent self.cutList = [] try: for (index,cutConfig) in enumerate(cutConfigList): @@ -137,28 +157,34 @@ except BaseException,e: print "cutConfigList badly set: %r" %e def process(self, eventList): - for event in eventList: - for cut in self.cutList: - if not cut.count(event): break + if self.byEvent: + for event in eventList: + for index in xrange(event.nRecoed): + for cut in self.cutList: + if not cut.count(MyParticle(event, index)): break + else: + for event in eventList: + for cut in self.cutList: + if not cut.count(event): break return self def select(self, event, imax): - for i in xrange(imax): - if not self.cutList[i].selection(event, self.cutList[i].study, self.cutList[i].params): - return False - return True + for i in xrange(imax): + if not self.cutList[i].selection(event, self.cutList[i].study, self.cutList[i].params): + return False + return True class Cut(object): def __init__(self, cutCollection, index, cutName, study, params): - self.cutCollection = cutCollection - self.index = index - self.name = cutName - self.params = params - self.study = study - self.total = 0 - self.weight = 0 - self.eventNumbers = [] - self.duplicates = [] - self.selection = self.__get(cutName) + self.cutCollection = cutCollection + self.index = index + self.name = cutName + self.params = params + self.study = study + self.total = 0 + self.weight = 0 + self.eventNumbers = [] + self.duplicates = [] + self.selection = self.__get(cutName) def __get(self, cutName): name = "cut_"+cutName if hasattr(self,name): @@ -177,193 +203,226 @@ self.weight += self.compute_weight(event, self.study) self.eventNumbers.append(event.EventNumber) else: - self.duplicates.append(event.EventNumber) + self.duplicates.append(event.EventNumber) return True else : return False except BaseException,e: print "Error performing %r: %r" %(self.name,e) def cut_fit_converged(self, event, study, params): - return fit_converged(event) + return fit_converged(event) def cut_chi2(self, event, study, params): return chi2_cut(event,params['chi2max']) def cut_has_muons(self, event, study, params): - for station in params['stations']: - if not has_muon_station(event, study, station): - return False - return True + for station in params['stations']: + if not has_muon_station(event, study, station): + return False + return True def cut_doca(self, event, study, params): - return doca_cut(event, params['docamax']) + return doca_cut(event, params['docamax']) def cut_z(self, event, study, params): - return z_cut(event, study) + return z_cut(event, study) def cut_normalization(self, event, study, params): - return goodTruthVtx(event, study) + return goodTruthVtx(event, study) def cut_good_tracks(self, event, study, params): - return goodTrack(event) + return goodTrack(event) def cut_ip(self, event, study, params): - return ip_cut(event, params['ipmax']) + return ip_cut(event, params['ipmax']) def cut_vtx_in_ellipse(self, event, study, params): - return vtxInAcceptance(event, study) + return vtxInAcceptance(event, study) + def cut_vtxSq_in_ellipse(self, event, study, params): + return vtxSqInAcceptance(event, study) def cut_n_candidates(self, event, study, params): - #print self.cutCollection.cutList[self.index-1].name - if (event.EventNumber in self.cutCollection.cutList[self.index-1].duplicates): - #if self.cutCollection.select(event, self.index): - return nParticles_cut(event, params['nmax']) - return True + #print self.cutCollection.cutList[self.index-1].name + if (event.EventNumber in self.cutCollection.cutList[self.index-1].duplicates): + #if self.cutCollection.select(event, self.index): + return nParticles_cut(event, params['nmax']) + return True + def cut_has_ecal(self, event, study, params): + return has_ecalDeposit(event) + def cut_has_n_muons_in(self, event, study, params): + return has_n_muons_in_station(event, params['n'], params['station']) def compute_weight(self, event, study): - return weight(event, study) + return weight(event, study) def fit_converged(event): - flags = event.DaughtersFitConverged - if np.product(flags): - return True - return False + flags = event.DaughtersFitConverged + if np.product(flags): + return True + return False def chi2_cut(event, chi2max): - chi2 = event.DaughtersChi2 - n = event.DaughtersNPoints - for i in xrange(len(n)): - if not n[i]: - print event.EventNumber - return False - if chi2[i]/n[i] > chi2max: - return False - return True + chi2 = event.DaughtersChi2 + n = event.DaughtersNPoints + for i in xrange(len(n)): + if not n[i]: + print event.EventNumber + return False + if chi2[i]/n[i] > chi2max: + return False + return True def has_muon_station(event, study, station): - zIn = studies[study]['geo']['muondet%s_1'%(station-1)]['z']['pos'] - studies[study]['geo']['muondet%s_1'%(station-1)]['z']['dim'] - zOut = studies[study]['geo']['muondet%s_1'%(station-1)]['z']['pos'] + studies[study]['geo']['muondet%s_1'%(station-1)]['z']['dim'] - for z in event.muon_z: - if zIn <= z <= zOut: - return True - return False + zIn = studies[study]['geo']['muondet%s_1'%(station-1)]['z']['pos'] - studies[study]['geo']['muondet%s_1'%(station-1)]['z']['dim'] + zOut = studies[study]['geo']['muondet%s_1'%(station-1)]['z']['pos'] + studies[study]['geo']['muondet%s_1'%(station-1)]['z']['dim'] + for z in event.muon_z: + if zIn <= z <= zOut: + return True + return False + +def has_n_muons_in_station(event, n, station): + if n>2: + print "has_n_muons_in_station ERROR: we have maximum 2 tracks!!" + sys.exit() + if station>2: + print "has_n_muons_in_station ERROR: we looked only at the first and second stations!!" + sys.exit() + if n==1 and station==1: + return event.Has1Muon1 + if n==2 and station==1: + return event.Has2Muon1 + if n==1 and station==2: + return event.Has1Muon2 + if n==2 and station==2: + return event.Has2Muon2 + +def has_ecalDeposit(event): + return event.HasEcal + def doca_cut(event, doca_max): - if event.DOCA < doca_max: - return True - return False + if event.DOCA < doca_max: + return True + return False def z_cut(event, study): - z = event.vtxz - #try: - # minz = studies[study]['geo']['lidT1I_1']['z']['pos'] + studies[study]['geo']['lidT1I_1']['z']['dim'] + 500. - # maxz = studies[study]['geo']['lidT6I_1']['z']['pos'] - studies[study]['geo']['lidT6I_1']['z']['dim'] - #except: - minz = studies[study]['geo']['Veto_5']['z']['pos'] + studies[study]['geo']['Veto_5']['z']['dim'] + 0.01 - maxz = studies[study]['geo']['Tr1_1']['z']['pos'] - studies[study]['geo']['Tr1_1']['z']['dim'] - 0.01 - if minz < z < maxz: - return True - return False + z = event.vtxz + #try: + # minz = studies[study]['geo']['lidT1I_1']['z']['pos'] + studies[study]['geo']['lidT1I_1']['z']['dim'] + 500. + # maxz = studies[study]['geo']['lidT6I_1']['z']['pos'] - studies[study]['geo']['lidT6I_1']['z']['dim'] + #except: + minz = studies[study]['geo']['Veto_5']['z']['pos'] + studies[study]['geo']['Veto_5']['z']['dim'] + 0.01 + maxz = studies[study]['geo']['Tr1_1']['z']['pos'] - studies[study]['geo']['Tr1_1']['z']['dim'] - 0.01 + if minz < z < maxz: + return True + return False def goodTruthVtx(event, study): - if study in ['pimu', 'mumunu', 'tiny']: - if not event.BadTruthVtx: - return True - return True + if study in ['pimu', 'mumunu', 'tiny']: + if not event.BadTruthVtx: + return True + return True def nParticles_cut(event, nmax): - if event.NParticles > nmax: - return False - return True + if event.NParticles > nmax: + return False + return True # This checks that: # - there is at least one tracking station before and one after the magnet # - hits in these tracking stations are within a 5x10m ellipse def goodTrack(event): - if event.DaughtersAlwaysIn: - return True - return False + if event.DaughtersAlwaysIn: + return True + return False def ip_cut(event, maxip): - if event.IP0 < maxip: - return True - return False + if event.IP0 < maxip: + return True + return False def nothing_in_veto5(event): - if len(event.veto5_x) > 0: - return False - return True + if len(event.veto5_x) > 0: + return False + return True def nothing_in_liquidscint(event): - if len(event.liquidscint_x) > 0: - return False - return True + if len(event.liquidscint_x) > 0: + return False + return True def something_in_muon(event): - if len(event.muon_x) > 0: - return True - return False + if len(event.muon_x) > 0: + return True + return False def something_in_ecal(event): - if len(event.ecal_x) > 0: - return True - return False + if len(event.ecal_x) > 0: + return True + return False def vtxInAcceptance(event, study): - x = event.vtxx - y = event.vtxy - #if 'cosmics' in study or 'bg' in study: - # print study, x, y - return tools.inEllipse(x,y,500./2,1000./2) + x = event.vtxx + y = event.vtxy + #if 'cosmics' in study or 'bg' in study: + # print study, x, y + return tools.inEllipse(x,y,500./2,1000./2) + +def vtxSqInAcceptance(event, study): + xSq = event.vtxxSqr + ySq = event.vtxySqr + #if 'cosmics' in study or 'bg' in study: + # print study, x, y + return tools.inEllipse(r.TMath.Sqrt(xSq), r.TMath.Sqrt(ySq), 500./2, 1000./2) def weight(event, study): - #if event.EventNumber not in studies[study]['seen']: - #studies[study]['seen'].append(event.EventNumber) - if ('bg' in study) or (study == 'nu' or study == 'nubar'): - w = event.NuWeight - elif 'cosmics' in study: - w = event.HNLw * 1.e6 / 200. - elif study in ['pimu', 'mumunu', 'tiny']: - w = event.HNLw / studies[study]['ntot'] - else: - print 'WEIGHTING ERROR: ', study - sys.exit() - #else: - # w = 0. - #if study in ['pimu', 'mumunu', 'tiny']: - # print study, event.EventNumber, event.NParticles - return w + #if event.EventNumber not in studies[study]['seen']: + #studies[study]['seen'].append(event.EventNumber) + if ('bg' in study) or (study == 'nu' or study == 'nubar'): + w = event.NuWeight + elif 'cosmics' in study: + w = event.HNLw * 1.e6 / 200. + elif study in ['pimu', 'mumunu', 'tiny']: + w = event.HNLw / studies[study]['ntot'] + else: + print 'WEIGHTING ERROR: ', study + sys.exit() + #else: + # w = 0. + #if study in ['pimu', 'mumunu', 'tiny']: + # print study, event.EventNumber, event.NParticles + return w def computeResidualWeight(filename=None): - if not filename: - filename = "forElena_nu_notVetoed.txt" - fScan = file(filename) - lines = fScan.readlines() - sample = nu - s = 'nu' - if ('bar' in filename) or ('anti' in filename): - sample = nubar - s = 'nubar' - lines = lines[3:-1] - events = [] - for line in lines: - events.append(int(line.rsplit("*")[1].replace(" ",""))) - count_reco = 0 - count = 0 - weighted_count = 0. - print "unvetoed: ", len(events) - print "total Reconstructed: ", sample.GetEntriesFast() - for event in sample: - if event.EventNumber in events: - count_reco +=1 - if (fit_converged(event) and chi2_cut(event, 5.) and z_cut(event, s) and vtxInAcceptance(event, s) - and goodTrack(event) and doca_cut(event, 30) and has_muon_station(event, s, 1) - and has_muon_station(event, s, 2) and ip_cut(event, 250.)): - #if True:#fit_converged(event): #and doca_cut(event, 50.) and ip_cut(event, 250.) and z_cut(event, 'nu') and vtxInAcceptance(event, 'nu'): - #print event.EventNumber, 'mothers: ', event.DaughtersTruthMotherPDG[0], event.DaughtersTruthMotherPDG[1] - print event.EventNumber - print 'mothers: ', event.DaughtersTruthMotherPDG[0], event.DaughtersTruthMotherPDG[1] - #print event.DOCA, event.IP0, event.DaughtersChi2[0]/event.DaughtersNPoints[0], event.DaughtersChi2[1]/event.DaughtersNPoints[1], event.DaughtersTruthPDG[0], event.DaughtersTruthPDG[1] - print "tracks: ", event.DaughtersTruthPDG[0], event.DaughtersTruthPDG[1] - print "vtx: ", event.vtxx, event.vtxy, event.vtxz - print 'DOCA, IP: ', event.DOCA, event.IP0 - #print tools.interactionElement(event.DaughtersTruthProdX[0], event.DaughtersTruthProdY[0], event.DaughtersTruthProdZ[0], nu_geo), tools.interactionElement(event.DaughtersTruthProdX[1], event.DaughtersTruthProdY[1], event.DaughtersTruthProdZ[1],nu_geo) - count +=1 - weighted_count += event.NuWeight - print "Reconstructed: %s"%count_reco - return count, weighted_count + if not filename: + filename = "forElena_nu_notVetoed.txt" + fScan = file(filename) + lines = fScan.readlines() + sample = nu + s = 'nu' + if ('bar' in filename) or ('anti' in filename): + sample = nubar + s = 'nubar' + lines = lines[3:-1] + events = [] + for line in lines: + events.append(int(line.rsplit("*")[1].replace(" ",""))) + count_reco = 0 + count = 0 + weighted_count = 0. + print "unvetoed: ", len(events) + print "total Reconstructed: ", sample.GetEntriesFast() + for event in sample: + if event.EventNumber in events: + count_reco +=1 + if (fit_converged(event) and chi2_cut(event, 5.) and z_cut(event, s) and vtxInAcceptance(event, s) + and goodTrack(event) and doca_cut(event, 30) and has_muon_station(event, s, 1) + and has_muon_station(event, s, 2) and ip_cut(event, 250.)): + #if True:#fit_converged(event): #and doca_cut(event, 50.) and ip_cut(event, 250.) and z_cut(event, 'nu') and vtxInAcceptance(event, 'nu'): + #print event.EventNumber, 'mothers: ', event.DaughtersTruthMotherPDG[0], event.DaughtersTruthMotherPDG[1] + print event.EventNumber + print 'mothers: ', event.DaughtersTruthMotherPDG[0], event.DaughtersTruthMotherPDG[1] + #print event.DOCA, event.IP0, event.DaughtersChi2[0]/event.DaughtersNPoints[0], event.DaughtersChi2[1]/event.DaughtersNPoints[1], event.DaughtersTruthPDG[0], event.DaughtersTruthPDG[1] + print "tracks: ", event.DaughtersTruthPDG[0], event.DaughtersTruthPDG[1] + print "vtx: ", event.vtxx, event.vtxy, event.vtxz + print 'DOCA, IP: ', event.DOCA, event.IP0 + #print tools.interactionElement(event.DaughtersTruthProdX[0], event.DaughtersTruthProdY[0], event.DaughtersTruthProdZ[0], nu_geo), tools.interactionElement(event.DaughtersTruthProdX[1], event.DaughtersTruthProdY[1], event.DaughtersTruthProdZ[1],nu_geo) + count +=1 + weighted_count += event.NuWeight + print "Reconstructed: %s"%count_reco + return count, weighted_count def latex_float(f): float_str = "{0:.3g}".format(f) @@ -373,349 +432,420 @@ else: return float_str + +class cutsWithDraw(object): + def __init__(self): + self.noB = '' + cutEllipse = "( (vtxx*vtxx)/(250.*250.) + (vtxy*vtxy)/(500.*500.) ) < 1." + def setNoB(self, noB): + # to ignore or take into account Katerina's modifications + self.noB = noB + def doca(self, th, noB=self.noB): + return " Sum$(%sDOCA < %s) "%(noB, th) + def ip(self, th, noB=self.noB): + return " Sum$(%sIP0 < %s) "%(noB, th) + def z(self, zmin, zmax, noB=self.noB): + return " Sum$(%svtxz > %s) && Sum$(%svtxz < %s) "%(noB, zmin, noB, zmax) + def ellipse(self, a, b): + return " Sum$(( (vtxx*vtxx)/(%s*%s) + (vtxy*vtxy)/(%s*%s) ) < 1.) "%(a,a,b,b) + def converged(self): + return " Sum$(DaughtersFitConverged==1) " + def goodtracks(self): + return " Sum$(DaughtersAlwaysIn==1) " + def redChi2(self, th, noB=self.noB): + return " Sum$(%sMaxDaughtersRedChi2<%s) "%(noB, th) + def ndf(self, th, noB=self.noB): + return " Sum$(%sMinDaughtersNdf>%s) "%(noB, th) + def muon1(self, num): + return " Sum$(Has%sMuon1==1) "%num + def muon2(self, num): + return " Sum$(Has%sMuon2==1) "%num + +def countWithDraw(): + t = studies['pimu']['data'] + geo = studies['pimu']['geo'] + ntot = studies['pimu']['ntot'] + tc = cutsWithDraw() + zmin = geo['Veto_5']['z']['pos']+geo['Veto_5']['z']['dim'] + zmin = geo['Tr1_1']['z']['pos']-geo['Tr1_1']['z']['dim'] + cuts = [ tc.converged(), tc.redChi2(5.), tc.z(zmin, zmax), tc.ellipse(250., 500.), tc.goodtracks(), + tc.doca(30.), tc.ip(250.), tc.muon1(1), tc.muon2(1) ] + cutnames = [ "converged", "chi2/n<5", "z", "ellipse", "good tracks", "doca<30", "ip<250", "muon1", "muon2" ] + entries = [] + weights = [] + print + for i,cut in enumerate(cuts): + n = t.Draw("event", "&&".join([c for c in cuts[:i]])) + t.Draw("event","weight*("+"&&".join([c for c in cuts[:i]])+")") + w = t.GetHistogram().GetSum() / ntot + entries.append(n) + weights.append(w) + print cutname[i], '\t\t', n, '\t', w + print + + + +# per particle cutConfigList = [ {'name': 'normalization', 'params':{}}, - {'name': 'fit_converged', 'params':{}}, - {'name': 'chi2', 'params':{'chi2max':5.}}, - {'name': 'z', 'params':{}}, - {'name': 'vtx_in_ellipse','params':{}}, - {'name': 'good_tracks', 'params':{}}, - {'name': 'doca', 'params':{'docamax':50.}}, - {'name': 'ip', 'params':{'ipmax':500.}}, - {'name': 'has_muons', 'params':{'stations':[1,2]}}, - {'name': 'doca', 'params':{'docamax':30.}}, - {'name': 'ip', 'params':{'ipmax':250.}}, - {'name': 'n_candidates', 'params':{'nmax':1}}, + {'name': 'fit_converged', 'params':{}}, + {'name': 'chi2', 'params':{'chi2max':5.}}, + {'name': 'z', 'params':{}}, + {'name': 'vtx_in_ellipse','params':{}}, + {'name': 'good_tracks', 'params':{}}, + {'name': 'doca', 'params':{'docamax':50.}}, + {'name': 'ip', 'params':{'ipmax':500.}}, + {'name': 'has_muons', 'params':{'stations':[1,2]}}, + {'name': 'doca', 'params':{'docamax':30.}}, + {'name': 'ip', 'params':{'ipmax':250.}}, + {'name': 'n_candidates', 'params':{'nmax':1}}, ] +# new analysis sw - per event +cutConfigList = [ {'name': 'normalization', 'params':{}}, + {'name': 'fit_converged', 'params':{}}, + {'name': 'chi2', 'params':{'chi2max':5.}}, + {'name': 'z', 'params':{}}, + {'name': 'vtx_in_ellipse', 'params':{}}, + {'name': 'good_tracks', 'params':{}}, + {'name': 'doca', 'params':{'docamax':50.}}, + {'name': 'ip', 'params':{'ipmax':500.}}, + {'name': 'has_n_muons_in', 'params':{'n':1,'station':1}}, + {'name': 'has_n_muons_in', 'params':{'n':1,'station':2}}, + {'name': 'has_ecal', 'params':{}}, + {'name': 'doca', 'params':{'docamax':30.}}, + {'name': 'ip', 'params':{'ipmax':250.}}, +] + + def numbers_v2(): - mycuts, results = {}, {} - for study in studies: - print 'Reading %s...'%study - mycuts[study] = Cuts(cutConfigList, study).process(studies[study]['data']) - for cut in mycuts[study].cutList: - print '%s\t%s\t%s\t%s'%(cut.name, cut.total, len(cut.eventNumbers), cut.weight) - results[study] = {} - results[study]['numbers']=[ cut.total for cut in mycuts[study].cutList[1:] ] - results[study]['numbersWithWeights']=[ cut.weight for cut in mycuts[study].cutList[1:] ] - print - print 'Events with more than one particle:' - for entry in mycuts[study].cutList[-2].duplicates: #[ x for x in mycuts[study].cutList[-1].eventNumbers if mycuts[study].cutList[-1].eventNumbers.count(x) > 1 ]: - for tr in studies[study]['data']: - if tr.EventNumber == entry: - if mycuts[study].select(tr, len(mycuts[study].cutList)-1): - print tr.EventNumber, tr.vtxz, tr.IP0, [pdg.GetParticle(code).GetName() for code in tr.DaughtersTruthPDG] - print - print - return results + mycuts, results = {}, {} + for study in studies: + print 'Reading %s...'%study + mycuts[study] = Cuts(cutConfigList, study).process(studies[study]['data']) + for cut in mycuts[study].cutList: + print '%s\t%s\t%s\t%s'%(cut.name, cut.total, len(cut.eventNumbers), cut.weight) + results[study] = {} + results[study]['numbers']=[ cut.total for cut in mycuts[study].cutList[1:] ] + results[study]['numbersWithWeights']=[ cut.weight for cut in mycuts[study].cutList[1:] ] + print + #print 'Events with more than one particle:' + #for entry in mycuts[study].cutList[-2].duplicates: #[ x for x in mycuts[study].cutList[-1].eventNumbers if mycuts[study].cutList[-1].eventNumbers.count(x) > 1 ]: + # for tr in studies[study]['data']: + # if tr.EventNumber == entry: + # if mycuts[study].select(tr, len(mycuts[study].cutList)-1): + # print tr.EventNumber, tr.vtxz, tr.IP0, [pdg.GetParticle(code).GetName() for code in tr.DaughtersTruthPDG] + #print + print + return results def makeTex(results): - print - print 'Background:' - print '\t\\begin{table}' - print '\t\\centering Backgrounds: \\tiny' - print '\t\t\\begin{tabular}{|l|c|c|c|c|c|c|}' - print '\t\t\t\\hline' - print '\t\t\tCut & Weighted $\\nu$ & $\\nu$ entries & Weighted $\\bar{\\nu}$ & $\\bar{\\nu}$ entries & Weighted cosmics & cosmics entries \\\\' - print '\t\t\t\\hline' - cuts = ['Track fit converged', '$\chi^2/n < 5$', '$z_{in}+5~\\text{m} < z_{vtx} < z_{out}$', '$z_{vtx} \in $ ellipse', 'Tracks $\in$ ellipse', 'DOCA $<$ 50 cm', - 'IP $<$ 5 m', 'Muon1 \& Muon2', 'DOCA $<$ 30 cm', 'IP $<$ 2.5 m', '$N_{candidates} = 1$'] - for i in xrange(len(results['nu']['numbers'])): - print '\t\t\t', cuts[i], ' & ', '%s'%latex_float(results['nu']['numbersWithWeights'][i]), ' & ', '%s'%results['nu']['numbers'][i], ' & ',\ - '%s'%latex_float(results['nubar']['numbersWithWeights'][i]), ' & ', '%s'%results['nubar']['numbers'][i], ' & ',\ - '%s'%latex_float(results['cosmics']['numbersWithWeights'][i]), ' & ', '%s'%results['cosmics']['numbers'][i], '\\\\ ' - print '\t\t\t\\hline' - print '\t\t\\end{tabular}' - print '\t\\end{table}' - print - print 'Signal:' - print '\t\\begin{table}' - print '\t\\centering Signal: \\tiny' - print '\t\t\\begin{tabular}{|l|c|c|c|c|c|c|}' - print '\t\t\t\\hline' - print '\t\t\tCut & $\\mathcal{A}(\\pi\\mu)$ & $\\pi\\mu$ entries & $\\mathcal{A}(\\mu\\mu\\nu)$ & $\\mu\\mu\\nu$ entries & $\\mathcal{A}(ee\\nu)$ & $ee\\nu$ entries \\\\' - print '\t\t\t\\hline' - cuts = ['Track fit converged', '$\chi^2/n < 5$', '$z_{in}+5~\\text{m} < z_{vtx} < z_{out}$', '$z_{vtx} \in $ ellipse', 'Tracks $\in$ ellipse', 'DOCA $<$ 50 cm', - 'IP $<$ 5 m', 'Muon1 \& Muon2', 'DOCA $<$ 30 cm', 'IP $<$ 2.5 m', '$N_{candidates} = 1$'] - for i in xrange(len(results['nu']['numbers'])): - print '\t\t\t', cuts[i], ' & ', '%s'%latex_float(results['pimu']['numbersWithWeights'][i]), ' & ', '%s'%results['pimu']['numbers'][i], ' & ',\ - '%s'%latex_float(results['mumunu']['numbersWithWeights'][i]), ' & ', '%s'%results['mumunu']['numbers'][i], ' & ',\ - '%s'%latex_float(results['tiny']['numbersWithWeights'][i]), ' & ', '%s'%results['tiny']['numbers'][i], '\\\\ ' - print '\t\t\t\\hline' - print '\t\t\\end{tabular}' - print '\t\\end{table}' - print + print + print 'Background:' + print '\t\\begin{table}' + print '\t\\centering Backgrounds: \\tiny' + print '\t\t\\begin{tabular}{|l|c|c|c|c|c|c|}' + print '\t\t\t\\hline' + print '\t\t\tCut & Weighted $\\nu$ & $\\nu$ entries & Weighted $\\bar{\\nu}$ & $\\bar{\\nu}$ entries & Weighted cosmics & cosmics entries \\\\' + print '\t\t\t\\hline' + cuts = ['Track fit converged', '$\chi^2/n < 5$', '$z_{in}+5~\\text{m} < z_{vtx} < z_{out}$', '$z_{vtx} \in $ ellipse', 'Tracks $\in$ ellipse', 'DOCA $<$ 50 cm', + 'IP $<$ 5 m', 'Muon1 \& Muon2', 'DOCA $<$ 30 cm', 'IP $<$ 2.5 m', '$N_{candidates} = 1$'] + for i in xrange(len(results['nu']['numbers'])): + print '\t\t\t', cuts[i], ' & ', '%s'%latex_float(results['nu']['numbersWithWeights'][i]), ' & ', '%s'%results['nu']['numbers'][i], ' & ',\ + '%s'%latex_float(results['nubar']['numbersWithWeights'][i]), ' & ', '%s'%results['nubar']['numbers'][i], ' & ',\ + '%s'%latex_float(results['cosmics']['numbersWithWeights'][i]), ' & ', '%s'%results['cosmics']['numbers'][i], '\\\\ ' + print '\t\t\t\\hline' + print '\t\t\\end{tabular}' + print '\t\\end{table}' + print + print 'Signal:' + print '\t\\begin{table}' + print '\t\\centering Signal: \\tiny' + print '\t\t\\begin{tabular}{|l|c|c|c|c|c|c|}' + print '\t\t\t\\hline' + print '\t\t\tCut & $\\mathcal{A}(\\pi\\mu)$ & $\\pi\\mu$ entries & $\\mathcal{A}(\\mu\\mu\\nu)$ & $\\mu\\mu\\nu$ entries & $\\mathcal{A}(ee\\nu)$ & $ee\\nu$ entries \\\\' + print '\t\t\t\\hline' + cuts = ['Track fit converged', '$\chi^2/n < 5$', '$z_{in}+5~\\text{m} < z_{vtx} < z_{out}$', '$z_{vtx} \in $ ellipse', 'Tracks $\in$ ellipse', 'DOCA $<$ 50 cm', + 'IP $<$ 5 m', 'Muon1 \& Muon2', 'DOCA $<$ 30 cm', 'IP $<$ 2.5 m', '$N_{candidates} = 1$'] + for i in xrange(len(results['nu']['numbers'])): + print '\t\t\t', cuts[i], ' & ', '%s'%latex_float(results['pimu']['numbersWithWeights'][i]), ' & ', '%s'%results['pimu']['numbers'][i], ' & ',\ + '%s'%latex_float(results['mumunu']['numbersWithWeights'][i]), ' & ', '%s'%results['mumunu']['numbers'][i], ' & ',\ + '%s'%latex_float(results['tiny']['numbersWithWeights'][i]), ' & ', '%s'%results['tiny']['numbers'][i], '\\\\ ' + print '\t\t\t\\hline' + print '\t\t\\end{tabular}' + print '\t\\end{table}' + print def numbers_for_TP(): - results = {} - for s in ['pimu', 'mumunu', 'tiny', 'nu', 'nubar', 'cosmics']:#studies: - print 'Reading %s...'%s - t = studies[s]['data'] - ntot = t.GetEntriesFast() - nAfterCuts = [0]*10 - nAfterCuts_weighted = [0.]*10 - initialEventNums = [] - eventNums = [] - for event in t: - w = weight(event,s) # e' importante fare questa cosa a monte, x come e' definita la funzione! - if fit_converged(event) and goodTruthVtx(event,s): - nAfterCuts[0] +=1 - nAfterCuts_weighted[0] += w - initialEventNums.append(int(event.EventNumber)) - if chi2_cut(event, 5.): - nAfterCuts[1]+=1 - nAfterCuts_weighted[1]+=w - if z_cut(event, s):#chi2_cut(event, 5): - nAfterCuts[1+1] += 1 - nAfterCuts_weighted[1+1] += w - if vtxInAcceptance(event, s):#goodTrack(event): - nAfterCuts[2+1] +=1 - nAfterCuts_weighted[2+1] +=w - #if 'cosmics' in s: - # print 'mothers: ', event.DaughtersTruthMotherPDG[0], event.DaughtersTruthMotherPDG[1] - # print "tracks: ", event.DaughtersTruthPDG[0], event.DaughtersTruthPDG[1] - # print "p candidate: ", event.P, "\t IP: ", event.IP0 - # print "pt candidate: ", event.Pt - if goodTrack(event):#doca_cut(event, 50): - nAfterCuts[3+1] +=1 - nAfterCuts_weighted[3+1] +=w - if doca_cut(event, 50):#vtxInAcceptance(event, s): - nAfterCuts[4+1]+=1 - nAfterCuts_weighted[4+1]+=w - if has_muon_station(event, s, 1) and has_muon_station(event, s, 2):#ip_cut(event,500):#something_in_muon(event): - nAfterCuts[5+1] +=1 - nAfterCuts_weighted[5+1] +=w - if doca_cut(event, 30.):#something_in_ecal(event): - nAfterCuts[6+1] +=1 - nAfterCuts_weighted[6+1] +=w - if ip_cut(event, 500.): - nAfterCuts[7+1] +=1 - nAfterCuts_weighted[7+1] +=w - if ip_cut(event, 250.): - nAfterCuts[8+1] +=1 - nAfterCuts_weighted[8+1] +=w - eventNums.append(int(event.EventNumber)) - studies[s]['seen'].append(event.EventNumber) + results = {} + for s in ['pimu', 'mumunu', 'tiny', 'nu', 'nubar', 'cosmics']:#studies: + print 'Reading %s...'%s + t = studies[s]['data'] + ntot = t.GetEntriesFast() + nAfterCuts = [0]*10 + nAfterCuts_weighted = [0.]*10 + initialEventNums = [] + eventNums = [] + for event in t: + w = weight(event,s) # e' importante fare questa cosa a monte, x come e' definita la funzione! + if fit_converged(event) and goodTruthVtx(event,s): + nAfterCuts[0] +=1 + nAfterCuts_weighted[0] += w + initialEventNums.append(int(event.EventNumber)) + if chi2_cut(event, 5.): + nAfterCuts[1]+=1 + nAfterCuts_weighted[1]+=w + if z_cut(event, s):#chi2_cut(event, 5): + nAfterCuts[1+1] += 1 + nAfterCuts_weighted[1+1] += w + if vtxInAcceptance(event, s):#goodTrack(event): + nAfterCuts[2+1] +=1 + nAfterCuts_weighted[2+1] +=w + #if 'cosmics' in s: + # print 'mothers: ', event.DaughtersTruthMotherPDG[0], event.DaughtersTruthMotherPDG[1] + # print "tracks: ", event.DaughtersTruthPDG[0], event.DaughtersTruthPDG[1] + # print "p candidate: ", event.P, "\t IP: ", event.IP0 + # print "pt candidate: ", event.Pt + if goodTrack(event):#doca_cut(event, 50): + nAfterCuts[3+1] +=1 + nAfterCuts_weighted[3+1] +=w + if doca_cut(event, 50):#vtxInAcceptance(event, s): + nAfterCuts[4+1]+=1 + nAfterCuts_weighted[4+1]+=w + if has_muon_station(event, s, 1) and has_muon_station(event, s, 2):#ip_cut(event,500):#something_in_muon(event): + nAfterCuts[5+1] +=1 + nAfterCuts_weighted[5+1] +=w + if doca_cut(event, 30.):#something_in_ecal(event): + nAfterCuts[6+1] +=1 + nAfterCuts_weighted[6+1] +=w + if ip_cut(event, 500.): + nAfterCuts[7+1] +=1 + nAfterCuts_weighted[7+1] +=w + if ip_cut(event, 250.): + nAfterCuts[8+1] +=1 + nAfterCuts_weighted[8+1] +=w + eventNums.append(int(event.EventNumber)) + studies[s]['seen'].append(event.EventNumber) - print '%s \t survived particles: '%s, nAfterCuts, ' of %s total'%ntot - print '%s \t weighted survived particles: '%s, nAfterCuts_weighted, ' of %s total'%ntot - results[s] = {} - results[s]['ntot']=studies[s]['ntot'] - results[s]['numbers']=nAfterCuts - results[s]['numbersWithWeights']=nAfterCuts_weighted - results[s]['listOfSurvivors']=list(set(eventNums)) - studies[s]['listOfSurvivors']=list(set(eventNums)) - results[s]['listOfRecoed']=list(set(initialEventNums)) - studies[s]['listOfRecoed']=list(set(initialEventNums)) - print - for s in ['pimu', 'mumunu', 'tiny']:#studies.keys():#['pimu', 'mumunu', 'bg']: - for lst in results[s]: - if not ('Survivors' in lst) and not ('Recoed' in lst): - print s,list,results[s][lst] - print - print 'Events with surviving nu: %s \t with nubar: %s'%(len(results['nu']['listOfSurvivors']), len(results['nubar']['listOfSurvivors'])) - print - print 'Background:' - print '\t\\begin{table}' - print '\t\\centering Backgrounds: \\tiny' - print '\t\t\\begin{tabular}{|l|c|c|c|c|c|c|}' - print '\t\t\t\\hline' - print '\t\t\tCut & Weighted $\\nu$ & $\\nu$ entries & Weighted $\\bar{\\nu}$ & $\\bar{\\nu}$ entries & Weighted cosmics & cosmics entries \\\\' - print '\t\t\t\\hline' - cuts = ['Track fit converged', '$\chi^2/n < 5$', '$z_{in}+5~\\text{m} < z_{vtx} < z_{out}$', '$z_{vtx} \in $ ellipse', 'Tracks $\in$ ellipse', 'DOCA $<$ 50 cm', - 'Muon1 \& Muon2', 'DOCA $<$ 30 cm', 'IP $<$ 5 m', 'IP $<$ 2.5 m'] - for i in xrange(len(results['nu']['numbers'])): - print '\t\t\t', cuts[i], ' & ', '%s'%latex_float(results['nu']['numbersWithWeights'][i]), ' & ', '%s'%results['nu']['numbers'][i], ' & ',\ - '%s'%latex_float(results['nubar']['numbersWithWeights'][i]), ' & ', '%s'%results['nubar']['numbers'][i], ' & ',\ - '%s'%latex_float(results['cosmics']['numbersWithWeights'][i]), ' & ', '%s'%results['cosmics']['numbers'][i], '\\\\ ' - print '\t\t\t\\hline' - print '\t\t\\end{tabular}' - print '\t\\end{table}' - print 'Signal:' - print '\t\\begin{table}' - print '\t\\centering Signal: \\tiny' - print '\t\t\\begin{tabular}{|l|c|c|c|c|c|c|}' - print '\t\t\t\\hline' - print '\t\t\tCut & $\\mathcal{A}(\\pi\\mu)$ & $\\pi\\mu$ entries & $\\mathcal{A}(\\mu\\mu\\nu)$ & $\\mu\\mu\\nu$ entries & $\\mathcal{A}(ee\\nu)$ & $ee\\nu$ entries \\\\' - print '\t\t\t\\hline' - cuts = ['Track fit converged', '$\chi^2/n < 5$', '$z_{in}+5~\\text{m} < z_{vtx} < z_{out}$', '$z_{vtx} \in $ ellipse', 'Tracks $\in$ ellipse', 'DOCA $<$ 50 cm', - 'Muon1 \& Muon2', 'DOCA $<$ 30 cm', 'IP $<$ 5 m', 'IP $<$ 2.5 m'] - for i in xrange(len(results['nu']['numbers'])): - print '\t\t\t', cuts[i], ' & ', '%s'%latex_float(results['pimu']['numbersWithWeights'][i]), ' & ', '%s'%results['pimu']['numbers'][i], ' & ',\ - '%s'%latex_float(results['mumunu']['numbersWithWeights'][i]), ' & ', '%s'%results['mumunu']['numbers'][i], ' & ',\ - '%s'%latex_float(results['tiny']['numbersWithWeights'][i]), ' & ', '%s'%results['tiny']['numbers'][i], '\\\\ ' - print '\t\t\t\\hline' - print '\t\t\\end{tabular}' - print '\t\\end{table}' - print - out = {'pimu':[], 'mumunu':[], 'tiny':[]} - for s in ['pimu', 'mumunu', 'tiny']: - for event in studies[s]['data']: - if event.EventNumber in studies[s]['listOfSurvivors']: - if event.NParticles > 1: - out[s].append(event.EventNumber) - #print s, event.EventNumber, event.NParticles, r.gGeoManager.FindNode(event.vtxx, event.vtxy, event.vtxz).GetName() - print s, list(set(out[s])) + print '%s \t survived particles: '%s, nAfterCuts, ' of %s total'%ntot + print '%s \t weighted survived particles: '%s, nAfterCuts_weighted, ' of %s total'%ntot + results[s] = {} + results[s]['ntot']=studies[s]['ntot'] + results[s]['numbers']=nAfterCuts + results[s]['numbersWithWeights']=nAfterCuts_weighted + results[s]['listOfSurvivors']=list(set(eventNums)) + studies[s]['listOfSurvivors']=list(set(eventNums)) + results[s]['listOfRecoed']=list(set(initialEventNums)) + studies[s]['listOfRecoed']=list(set(initialEventNums)) + print + for s in ['pimu', 'mumunu', 'tiny']:#studies.keys():#['pimu', 'mumunu', 'bg']: + for lst in results[s]: + if not ('Survivors' in lst) and not ('Recoed' in lst): + print s,list,results[s][lst] + print + print 'Events with surviving nu: %s \t with nubar: %s'%(len(results['nu']['listOfSurvivors']), len(results['nubar']['listOfSurvivors'])) + print + print 'Background:' + print '\t\\begin{table}' + print '\t\\centering Backgrounds: \\tiny' + print '\t\t\\begin{tabular}{|l|c|c|c|c|c|c|}' + print '\t\t\t\\hline' + print '\t\t\tCut & Weighted $\\nu$ & $\\nu$ entries & Weighted $\\bar{\\nu}$ & $\\bar{\\nu}$ entries & Weighted cosmics & cosmics entries \\\\' + print '\t\t\t\\hline' + cuts = ['Track fit converged', '$\chi^2/n < 5$', '$z_{in}+5~\\text{m} < z_{vtx} < z_{out}$', '$z_{vtx} \in $ ellipse', 'Tracks $\in$ ellipse', 'DOCA $<$ 50 cm', + 'Muon1 \& Muon2', 'DOCA $<$ 30 cm', 'IP $<$ 5 m', 'IP $<$ 2.5 m'] + for i in xrange(len(results['nu']['numbers'])): + print '\t\t\t', cuts[i], ' & ', '%s'%latex_float(results['nu']['numbersWithWeights'][i]), ' & ', '%s'%results['nu']['numbers'][i], ' & ',\ + '%s'%latex_float(results['nubar']['numbersWithWeights'][i]), ' & ', '%s'%results['nubar']['numbers'][i], ' & ',\ + '%s'%latex_float(results['cosmics']['numbersWithWeights'][i]), ' & ', '%s'%results['cosmics']['numbers'][i], '\\\\ ' + print '\t\t\t\\hline' + print '\t\t\\end{tabular}' + print '\t\\end{table}' + print 'Signal:' + print '\t\\begin{table}' + print '\t\\centering Signal: \\tiny' + print '\t\t\\begin{tabular}{|l|c|c|c|c|c|c|}' + print '\t\t\t\\hline' + print '\t\t\tCut & $\\mathcal{A}(\\pi\\mu)$ & $\\pi\\mu$ entries & $\\mathcal{A}(\\mu\\mu\\nu)$ & $\\mu\\mu\\nu$ entries & $\\mathcal{A}(ee\\nu)$ & $ee\\nu$ entries \\\\' + print '\t\t\t\\hline' + cuts = ['Track fit converged', '$\chi^2/n < 5$', '$z_{in}+5~\\text{m} < z_{vtx} < z_{out}$', '$z_{vtx} \in $ ellipse', 'Tracks $\in$ ellipse', 'DOCA $<$ 50 cm', + 'Muon1 \& Muon2', 'DOCA $<$ 30 cm', 'IP $<$ 5 m', 'IP $<$ 2.5 m'] + for i in xrange(len(results['nu']['numbers'])): + print '\t\t\t', cuts[i], ' & ', '%s'%latex_float(results['pimu']['numbersWithWeights'][i]), ' & ', '%s'%results['pimu']['numbers'][i], ' & ',\ + '%s'%latex_float(results['mumunu']['numbersWithWeights'][i]), ' & ', '%s'%results['mumunu']['numbers'][i], ' & ',\ + '%s'%latex_float(results['tiny']['numbersWithWeights'][i]), ' & ', '%s'%results['tiny']['numbers'][i], '\\\\ ' + print '\t\t\t\\hline' + print '\t\t\\end{tabular}' + print '\t\\end{table}' + print + out = {'pimu':[], 'mumunu':[], 'tiny':[]} + for s in ['pimu', 'mumunu', 'tiny']: + for event in studies[s]['data']: + if event.EventNumber in studies[s]['listOfSurvivors']: + if event.NParticles > 1: + out[s].append(event.EventNumber) + #print s, event.EventNumber, event.NParticles, r.gGeoManager.FindNode(event.vtxx, event.vtxy, event.vtxz).GetName() + print s, list(set(out[s])) - + def badEvents(): - numbers_for_TP() - hnpnu_recoed = r.TH1F('np nu recoed', 'np nu recoed', 60, 0, 59) - hnpnu_survivors = r.TH1F('np nu survived', 'np nu survived', 60, 0, 59) - seen = [] - for part in studies['nu']['data']: - if not (part.EventNumber in seen): - if part.EventNumber in studies['nu']['listOfSurvivors']: - hnpnu_survivors.Fill(part.NParticles) - if part.EventNumber in studies['nu']['listOfRecoed']: - hnpnu_recoed.Fill(part.NParticles) - seen.append(part.EventNumber) - #c1 = r.TCanvas(); c1.cd() - #hnpnu.Draw() - #c1.Print('badEvents_nu_nparticles.png') - hnpnubar_recoed = r.TH1F('np nubar recoed', 'np nubar recoed', 60, 0, 59) - hnpnubar_survivors = r.TH1F('np nubar survived', 'np nubar survived', 60, 0, 59) - seen = [] - for part in studies['nubar']['data']: - if not (part.EventNumber in seen): - if part.EventNumber in studies['nubar']['listOfSurvivors']: - hnpnubar_survivors.Fill(part.NParticles) - if part.EventNumber in studies['nubar']['listOfRecoed']: - hnpnubar_recoed.Fill(part.NParticles) - seen.append(part.EventNumber) - #c1 = r.TCanvas(); c1.cd() - #hnpnubar.Draw() - #c1.Print('badEvents_nubar_nparticles.png') - hnpnu_recoed.SetLineColor(r.kBlack); hnpnu_recoed.SetMarkerColor(r.kBlack) - hnpnu_survivors.SetLineColor(r.kMagenta); hnpnu_survivors.SetMarkerColor(r.kMagenta) - c1 = r.TCanvas(); c1.cd() - hnpnu_recoed.DrawNormalized('p'); hnpnu_survivors.DrawNormalized('p same') - c1.Print('nuAndNubar/nu_recoed_and_survived.png') - c1.Print('nuAndNubar/nu_recoed_and_survived.pdf') - c1.Close() - hnpnubar_recoed.SetLineColor(r.kBlack); hnpnubar_recoed.SetMarkerColor(r.kBlack) - hnpnubar_survivors.SetLineColor(r.kMagenta); hnpnubar_survivors.SetMarkerColor(r.kMagenta) - c1 = r.TCanvas(); c1.cd() - hnpnubar_recoed.DrawNormalized('p'); hnpnubar_survivors.DrawNormalized('p same') - c1.Print('nuAndNubar/nubar_recoed_and_survived.png') - c1.Print('nuAndNubar/nubar_recoed_and_survived.pdf') - c1.Close() - hnpnu_recoed.SetLineColor(r.kBlue); hnpnu_recoed.SetMarkerColor(r.kBlue) - hnpnubar_recoed.SetLineColor(r.kGreen); hnpnubar_recoed.SetMarkerColor(r.kGreen) - c1 = r.TCanvas(); c1.cd() - hnpnu_recoed.DrawNormalized('p'); hnpnubar_recoed.DrawNormalized('p same') - c1.Print('nuAndNubar/nu_and_nubar_recoed.png') - c1.Print('nuAndNubar/nu_and_nubar_recoed.pdf') - c1.Close() - hnpnu_survivors.SetLineColor(r.kBlue); hnpnu_survivors.SetMarkerColor(r.kBlue) - hnpnubar_survivors.SetLineColor(r.kGreen); hnpnubar_survivors.SetMarkerColor(r.kGreen) - c1 = r.TCanvas(); c1.cd() - hnpnu_survivors.DrawNormalized('p'); hnpnubar_survivors.DrawNormalized('p same') - c1.Print('nuAndNubar/nu_and_nubar_survived.png') - c1.Print('nuAndNubar/nu_and_nubar_survived.pdf') - c1.Close() + numbers_for_TP() + hnpnu_recoed = r.TH1F('np nu recoed', 'np nu recoed', 60, 0, 59) + hnpnu_survivors = r.TH1F('np nu survived', 'np nu survived', 60, 0, 59) + seen = [] + for part in studies['nu']['data']: + if not (part.EventNumber in seen): + if part.EventNumber in studies['nu']['listOfSurvivors']: + hnpnu_survivors.Fill(part.NParticles) + if part.EventNumber in studies['nu']['listOfRecoed']: + hnpnu_recoed.Fill(part.NParticles) + seen.append(part.EventNumber) + #c1 = r.TCanvas(); c1.cd() + #hnpnu.Draw() + #c1.Print('badEvents_nu_nparticles.png') + hnpnubar_recoed = r.TH1F('np nubar recoed', 'np nubar recoed', 60, 0, 59) + hnpnubar_survivors = r.TH1F('np nubar survived', 'np nubar survived', 60, 0, 59) + seen = [] + for part in studies['nubar']['data']: + if not (part.EventNumber in seen): + if part.EventNumber in studies['nubar']['listOfSurvivors']: + hnpnubar_survivors.Fill(part.NParticles) + if part.EventNumber in studies['nubar']['listOfRecoed']: + hnpnubar_recoed.Fill(part.NParticles) + seen.append(part.EventNumber) + #c1 = r.TCanvas(); c1.cd() + #hnpnubar.Draw() + #c1.Print('badEvents_nubar_nparticles.png') + hnpnu_recoed.SetLineColor(r.kBlack); hnpnu_recoed.SetMarkerColor(r.kBlack) + hnpnu_survivors.SetLineColor(r.kMagenta); hnpnu_survivors.SetMarkerColor(r.kMagenta) + c1 = r.TCanvas(); c1.cd() + hnpnu_recoed.DrawNormalized('p'); hnpnu_survivors.DrawNormalized('p same') + c1.Print('nuAndNubar/nu_recoed_and_survived.png') + c1.Print('nuAndNubar/nu_recoed_and_survived.pdf') + c1.Close() + hnpnubar_recoed.SetLineColor(r.kBlack); hnpnubar_recoed.SetMarkerColor(r.kBlack) + hnpnubar_survivors.SetLineColor(r.kMagenta); hnpnubar_survivors.SetMarkerColor(r.kMagenta) + c1 = r.TCanvas(); c1.cd() + hnpnubar_recoed.DrawNormalized('p'); hnpnubar_survivors.DrawNormalized('p same') + c1.Print('nuAndNubar/nubar_recoed_and_survived.png') + c1.Print('nuAndNubar/nubar_recoed_and_survived.pdf') + c1.Close() + hnpnu_recoed.SetLineColor(r.kBlue); hnpnu_recoed.SetMarkerColor(r.kBlue) + hnpnubar_recoed.SetLineColor(r.kGreen); hnpnubar_recoed.SetMarkerColor(r.kGreen) + c1 = r.TCanvas(); c1.cd() + hnpnu_recoed.DrawNormalized('p'); hnpnubar_recoed.DrawNormalized('p same') + c1.Print('nuAndNubar/nu_and_nubar_recoed.png') + c1.Print('nuAndNubar/nu_and_nubar_recoed.pdf') + c1.Close() + hnpnu_survivors.SetLineColor(r.kBlue); hnpnu_survivors.SetMarkerColor(r.kBlue) + hnpnubar_survivors.SetLineColor(r.kGreen); hnpnubar_survivors.SetMarkerColor(r.kGreen) + c1 = r.TCanvas(); c1.cd() + hnpnu_survivors.DrawNormalized('p'); hnpnubar_survivors.DrawNormalized('p same') + c1.Print('nuAndNubar/nu_and_nubar_survived.png') + c1.Print('nuAndNubar/nu_and_nubar_survived.pdf') + c1.Close() def do_my_studies(): - results = {} - for s in studies: - print 'Reading %s...'%s - t = studies[s]['data'] - ntot = t.GetEntriesFast() - nAfterCuts = [0]*10 - nAfterCuts_weighted = [0.]*10 - for event in t: - w = weight(event,s) - if fit_converged(event): - nAfterCuts[0] += 1 - nAfterCuts_weighted[0] += w - if chi2_cut(event,25): - nAfterCuts[1] +=1 - nAfterCuts_weighted[1] +=w - #if chi2_cut(event,15): - if chi2_cut(event,5): - nAfterCuts[2]+=1 - nAfterCuts_weighted[2]+=w - if doca_cut(event, 50.): - nAfterCuts[2+1] += 1 - nAfterCuts_weighted[2+1] += w - if doca_cut(event, 30.): - nAfterCuts[3+1]+=1 - nAfterCuts_weighted[3+1]+=w - if z_cut(event, s): - nAfterCuts[4+1] += 1 - nAfterCuts_weighted[4+1] += w - if ip_cut(event,500.): - nAfterCuts[5+1]+=1 - nAfterCuts_weighted[5+1]+=w - if ip_cut(event,250.): - nAfterCuts[6+1]+=1 - nAfterCuts_weighted[6+1]+=w - if nothing_in_veto5(event): - nAfterCuts[7+1] += 1 - nAfterCuts_weighted[7+1] += w - if nothing_in_liquidscint(event): - nAfterCuts[8+1] += 1 - nAfterCuts_weighted[8+1] += w - print '%s \t survived particles: '%s, nAfterCuts, ' of %s total'%ntot - print '%s \t weighted survived particles: '%s, nAfterCuts_weighted, ' of %s total'%ntot - results[s] = {} - results[s]['ntot']=studies[s]['ntot'] - results[s]['numbers']=nAfterCuts - results[s]['numbersWithWeights']=nAfterCuts_weighted - addPlot(s+'-0cuts-IP', 'Impact parameter to target [cm]', t, 'IP0') - addPlot(s+'-0cuts-Mass', 'Reco inv. mass', t, 'Mass' ) - addPlot(s+'-0cuts-dPt', 'Tracks Pt', t, 'DaughtersPt' ) - addPlot(s+'-0cuts-P','Reconstructed Momentum', t, 'P') - addPlot(s+'-0cuts-Pt', 'Reconstructed Pt', t, 'Pt') - addPlot(s+'-0cuts-PtOverP', 'Reconstructed Pt/P', t, 'Pt/P') - addPlot(s+'-0cuts-dMinP', 'Min Tracks P', t, 'DaughterMinP' ) - addPlot(s+'-0cuts-dMinPt', 'Min Tracks Pt', t, 'DaughterMinPt' ) - addPlot(s+'-0cuts-VtxZ', 'Reco vertex z position [cm]', t, 'vtxz' ) - addPlot(s+'-0cuts-DOCA', 'Daughter tracks DOCA [cm]', t, 'DOCA' ) - addPlot(s+'-0cuts-dChi2', 'Daughter tracks #chi^{2}/n', t, 'DaughtersChi2/DaughtersNPoints' ) - #cut = "DaughtersChi2<25*DaughtersNPoints" - cut = "DaughtersChi2<5*DaughtersNPoints" - addPlot(s+'-chi2cut-IP', 'Impact parameter to target [cm]', t, 'IP0', cut) - addPlot(s+'-chi2cut-Mass', 'Reco inv. mass', t, 'Mass' , cut) - addPlot(s+'-chi2cut-dPt', 'Tracks Pt', t, 'DaughtersPt' , cut) - addPlot(s+'-chi2cut-P', 'Reconstructed Momentum', t, 'P', cut) - addPlot(s+'-chi2cut-Pt','Reconstructed Pt', t, 'Pt', cut) - addPlot(s+'-chi2cut-PtOverP', 'Reconstructed Pt/P', t, 'Pt/P', cut) - addPlot(s+'-chi2cut-dMinP', 'Min Tracks P', t, 'DaughterMinP' , cut ) - addPlot(s+'-chi2cut-dMinPt', 'Min Tracks Pt', t, 'DaughterMinPt' , cut ) - addPlot(s+'-chi2cut-VtxZ', 'Reco vertex z position [cm]', t, 'vtxz' , cut) - addPlot(s+'-chi2cut-DOCA', 'Daughter tracks DOCA [cm]', t, 'DOCA' , cut) - cut += " && DOCA < 25" - addPlot(s+'-chi2andDOCAcuts-IP', 'Impact parameter to target [cm]', t, 'IP0', cut) - addPlot(s+'-chi2andDOCAcuts-Mass', 'Reco inv. mass', t, 'Mass' , cut) - addPlot(s+'-chi2andDOCAcuts-P','Reconstructed Momentum', t, 'P', cut) - addPlot(s+'-chi2andDOCAcuts-Pt','Reconstructed Pt', t, 'Pt', cut) - addPlot(s+'-chi2andDOCAcuts-PtOverP', 'Reconstructed Pt/P', t, 'Pt/P', cut) - addPlot(s+'-chi2andDOCAcuts-dPt', 'Tracks Pt', t, 'DaughtersPt' , cut) - addPlot(s+'-chi2andDOCAcuts-dMinP', 'Min Tracks P', t, 'DaughterMinP' , cut ) - addPlot(s+'-chi2andDOCAcuts-dMinPt', 'Min Tracks Pt', t, 'DaughterMinPt' , cut ) - addPlot(s+'-chi2andDOCAcuts-VtxZ', 'Reco vertex z position [cm]', t, 'vtxz' , cut) - #try: - # minz = studies[s]['geo']['lidT1I_1']['z']['pos'] + studies[s]['geo']['lidT1I_1']['z']['dim'] + 500. - # maxz = studies[s]['geo']['lidT6I_1']['z']['pos'] - studies[s]['geo']['lidT6I_1']['z']['dim'] - #except: - minz = studies[s]['geo']['Veto_5']['z']['pos'] + studies[s]['geo']['Veto_5']['z']['dim'] - maxz = studies[s]['geo']['Tr1_1']['z']['pos'] + studies[s]['geo']['Tr1_1']['z']['dim'] - cut += " && vtxz > %s && vtxz < %s"%(minz, maxz) - addPlot(s+'-chi2andDOCAandZcuts-IP', 'Impact parameter to target [cm]', t, 'IP0', cut) - addPlot(s+'-chi2andDOCAandZcuts-Mass', 'Reco inv. mass', t, 'Mass' , cut) - addPlot(s+'-chi2andDOCAandZcuts-P','Reconstructed Momentum', t, 'P', cut) - addPlot(s+'-chi2andDOCAandZcuts-Pt','Reconstructed Pt', t, 'Pt', cut) - addPlot(s+'-chi2andDOCAandZcuts-PtOverP', 'Reconstructed Pt/P', t, 'Pt/P', cut) - addPlot(s+'-chi2andDOCAandZcuts-dPt', 'Tracks Pt', t, 'DaughtersPt' , cut) - addPlot(s+'-chi2andDOCAandZcuts-dMinP', 'Min Tracks P', t, 'DaughterMinP' , cut ) - addPlot(s+'-chi2andDOCAandZcuts-dMinPt', 'Min Tracks Pt', t, 'DaughterMinPt' , cut ) - addPlot(s+'-chi2andDOCAandZcuts-VtxZ', 'Reco vertex z position [cm]', t, 'vtxz' , cut) - - - for s in studies.keys():#['pimu', 'mumunu', 'bg']: - for list in results[s]: - print s,list,results[s][list] + results = {} + for s in studies: + print 'Reading %s...'%s + t = studies[s]['data'] + ntot = t.GetEntriesFast() + nAfterCuts = [0]*10 + nAfterCuts_weighted = [0.]*10 + for event in t: + w = weight(event,s) + if fit_converged(event): + nAfterCuts[0] += 1 + nAfterCuts_weighted[0] += w + if chi2_cut(event,25): + nAfterCuts[1] +=1 + nAfterCuts_weighted[1] +=w + #if chi2_cut(event,15): + if chi2_cut(event,5): + nAfterCuts[2]+=1 + nAfterCuts_weighted[2]+=w + if doca_cut(event, 50.): + nAfterCuts[2+1] += 1 + nAfterCuts_weighted[2+1] += w + if doca_cut(event, 30.): + nAfterCuts[3+1]+=1 + nAfterCuts_weighted[3+1]+=w + if z_cut(event, s): + nAfterCuts[4+1] += 1 + nAfterCuts_weighted[4+1] += w + if ip_cut(event,500.): + nAfterCuts[5+1]+=1 + nAfterCuts_weighted[5+1]+=w + if ip_cut(event,250.): + nAfterCuts[6+1]+=1 + nAfterCuts_weighted[6+1]+=w + if nothing_in_veto5(event): + nAfterCuts[7+1] += 1 + nAfterCuts_weighted[7+1] += w + if nothing_in_liquidscint(event): + nAfterCuts[8+1] += 1 + nAfterCuts_weighted[8+1] += w + print '%s \t survived particles: '%s, nAfterCuts, ' of %s total'%ntot + print '%s \t weighted survived particles: '%s, nAfterCuts_weighted, ' of %s total'%ntot + results[s] = {} + results[s]['ntot']=studies[s]['ntot'] + results[s]['numbers']=nAfterCuts + results[s]['numbersWithWeights']=nAfterCuts_weighted + addPlot(s+'-0cuts-IP', 'Impact parameter to target [cm]', t, 'IP0') + addPlot(s+'-0cuts-Mass', 'Reco inv. mass', t, 'Mass' ) + addPlot(s+'-0cuts-dPt', 'Tracks Pt', t, 'DaughtersPt' ) + addPlot(s+'-0cuts-P','Reconstructed Momentum', t, 'P') + addPlot(s+'-0cuts-Pt', 'Reconstructed Pt', t, 'Pt') + addPlot(s+'-0cuts-PtOverP', 'Reconstructed Pt/P', t, 'Pt/P') + addPlot(s+'-0cuts-dMinP', 'Min Tracks P', t, 'DaughterMinP' ) + addPlot(s+'-0cuts-dMinPt', 'Min Tracks Pt', t, 'DaughterMinPt' ) + addPlot(s+'-0cuts-VtxZ', 'Reco vertex z position [cm]', t, 'vtxz' ) + addPlot(s+'-0cuts-DOCA', 'Daughter tracks DOCA [cm]', t, 'DOCA' ) + addPlot(s+'-0cuts-dChi2', 'Daughter tracks #chi^{2}/n', t, 'DaughtersChi2/DaughtersNPoints' ) + #cut = "DaughtersChi2<25*DaughtersNPoints" + cut = "DaughtersChi2<5*DaughtersNPoints" + addPlot(s+'-chi2cut-IP', 'Impact parameter to target [cm]', t, 'IP0', cut) + addPlot(s+'-chi2cut-Mass', 'Reco inv. mass', t, 'Mass' , cut) + addPlot(s+'-chi2cut-dPt', 'Tracks Pt', t, 'DaughtersPt' , cut) + addPlot(s+'-chi2cut-P', 'Reconstructed Momentum', t, 'P', cut) + addPlot(s+'-chi2cut-Pt','Reconstructed Pt', t, 'Pt', cut) + addPlot(s+'-chi2cut-PtOverP', 'Reconstructed Pt/P', t, 'Pt/P', cut) + addPlot(s+'-chi2cut-dMinP', 'Min Tracks P', t, 'DaughterMinP' , cut ) + addPlot(s+'-chi2cut-dMinPt', 'Min Tracks Pt', t, 'DaughterMinPt' , cut ) + addPlot(s+'-chi2cut-VtxZ', 'Reco vertex z position [cm]', t, 'vtxz' , cut) + addPlot(s+'-chi2cut-DOCA', 'Daughter tracks DOCA [cm]', t, 'DOCA' , cut) + cut += " && DOCA < 25" + addPlot(s+'-chi2andDOCAcuts-IP', 'Impact parameter to target [cm]', t, 'IP0', cut) + addPlot(s+'-chi2andDOCAcuts-Mass', 'Reco inv. mass', t, 'Mass' , cut) + addPlot(s+'-chi2andDOCAcuts-P','Reconstructed Momentum', t, 'P', cut) + addPlot(s+'-chi2andDOCAcuts-Pt','Reconstructed Pt', t, 'Pt', cut) + addPlot(s+'-chi2andDOCAcuts-PtOverP', 'Reconstructed Pt/P', t, 'Pt/P', cut) + addPlot(s+'-chi2andDOCAcuts-dPt', 'Tracks Pt', t, 'DaughtersPt' , cut) + addPlot(s+'-chi2andDOCAcuts-dMinP', 'Min Tracks P', t, 'DaughterMinP' , cut ) + addPlot(s+'-chi2andDOCAcuts-dMinPt', 'Min Tracks Pt', t, 'DaughterMinPt' , cut ) + addPlot(s+'-chi2andDOCAcuts-VtxZ', 'Reco vertex z position [cm]', t, 'vtxz' , cut) + #try: + # minz = studies[s]['geo']['lidT1I_1']['z']['pos'] + studies[s]['geo']['lidT1I_1']['z']['dim'] + 500. + # maxz = studies[s]['geo']['lidT6I_1']['z']['pos'] - studies[s]['geo']['lidT6I_1']['z']['dim'] + #except: + minz = studies[s]['geo']['Veto_5']['z']['pos'] + studies[s]['geo']['Veto_5']['z']['dim'] + maxz = studies[s]['geo']['Tr1_1']['z']['pos'] + studies[s]['geo']['Tr1_1']['z']['dim'] + cut += " && vtxz > %s && vtxz < %s"%(minz, maxz) + addPlot(s+'-chi2andDOCAandZcuts-IP', 'Impact parameter to target [cm]', t, 'IP0', cut) + addPlot(s+'-chi2andDOCAandZcuts-Mass', 'Reco inv. mass', t, 'Mass' , cut) + addPlot(s+'-chi2andDOCAandZcuts-P','Reconstructed Momentum', t, 'P', cut) + addPlot(s+'-chi2andDOCAandZcuts-Pt','Reconstructed Pt', t, 'Pt', cut) + addPlot(s+'-chi2andDOCAandZcuts-PtOverP', 'Reconstructed Pt/P', t, 'Pt/P', cut) + addPlot(s+'-chi2andDOCAandZcuts-dPt', 'Tracks Pt', t, 'DaughtersPt' , cut) + addPlot(s+'-chi2andDOCAandZcuts-dMinP', 'Min Tracks P', t, 'DaughterMinP' , cut ) + addPlot(s+'-chi2andDOCAandZcuts-dMinPt', 'Min Tracks Pt', t, 'DaughterMinPt' , cut ) + addPlot(s+'-chi2andDOCAandZcuts-VtxZ', 'Reco vertex z position [cm]', t, 'vtxz' , cut) + + + for s in studies.keys():#['pimu', 'mumunu', 'bg']: + for list in results[s]: + print s,list,results[s][list] diff --git a/newGen/KaterinaLight/FitTrackInfo.py b/newGen/KaterinaLight/FitTrackInfo.py new file mode 100644 index 0000000..e4ef874 --- /dev/null +++ b/newGen/KaterinaLight/FitTrackInfo.py @@ -0,0 +1,169 @@ +import ROOT,os,sys,getopt +import rootUtils as ut +import shipunit as u + +class FitTrackInfo(object): + + def __init__(self, tree, debug=0): + self.tree = tree + self.debug = debug + self.count = 0 + self.Momentum = {} + self.Direction = {} + self.Position = {} + self.__info = {} + self.Vertex = None + self.Doca = None + # 0 orig, 1 refit, -1 failed refit + self.vertexEFlag = 0 + + def clean(self): + self.count = 0 + self.Momentum.clear() + self.Direction.clear() + self.Position.clear() + self.__info.clear() + self.Vertex = None + self.Doca = None + + def Print(self): + print "FitTrackInfo:" + for tid in self.__info: + print "\t", tid, "{:10.4f}".format(self.__info[tid]['Ndf']), "{:10.4f}".format(self.__info[tid]['Chi2']), + print " pos:", " ".join("{:10.4f}".format(self.Position[tid](ii)) for ii in range(0,3)), + print " mom:", " ".join("{:10.4f}".format(self.Direction[tid](ii)*self.Momentum[tid]) for ii in range(0,3)), + print " P:", "{:10.4f}".format(self.Momentum[tid]) + + ## \brief returns list of keys #__info . + # \return list of MCtrackIDs of fitted tracks. + def getTrIDs(self): + trID = [] + for tid in self.__info: + trID.append(tid) + return trID + + def getNtracks(self) : + return len(self.__info) + + def getChi2Ndf(self, tid): + return self.__info[tid]['Chi2']/self.__info[tid]['Ndf'] + + def getNdf(self, tid): + return self.__info[tid]['Ndf'] + + def compareTracks(self, tid, Pos, Dir, Pval): + false2 = (Pos==None or Dir==None or Pval==None) + false1 = (not tid in self.__info) + if (false2 and false1): return True + if (false2 or false1): return False + return ( (self.Direction[tid]==Dir) and (self.Position[tid]==Pos) and (self.Momentum[tid]==Pval) ) + + + def getPosDirPval(self, tid): + if not tid in self.__info: return None, None, None + return self.Position[tid], self.Direction[tid], self.Momentum[tid] + + def getVertex(self) : + return self.Vertex + + def getDoca(self): + return self.Doca + + def myVertex2(self, t1,t2): + deltaPos =(self.Position[t1]-self.Position[t2]) # A1-A2 + dotDir = self.Direction[t1].Dot(self.Direction[t2]) # a1.a2 + crossDir = self.Direction[t1].Cross(self.Direction[t2]) # a1xa2 + uPerpend = crossDir*(1./crossDir.Mag()) # (a1xa2)/|a1xa2| from a1 to a2 + + minDist = deltaPos.Dot(uPerpend) # (A1-A2).(a1xa2)/|a1xa2| + + # A1 + a1*t1 + (minDist * uPerpend) is (A1 + a1*t1) projected to the plane: + # 1) A2+a2*t2 belons to the plane, + # 2) A1+a1*t1 is parallel to the plane + # cross at t1,t2: A1+a1*t1+(minDist*uPerpend) = A2+a2*t2 + t2X = self.Direction[t2].X() + if (t2X == 0) : t2X = 0.00000000001 + a2a = self.Direction[t2].Y()/t2X + alpha = deltaPos - minDist*uPerpend + nomin = alpha.Y() - a2a*alpha.X() + denom = a2a*self.Direction[t1].X() - self.Direction[t1].Y() + s1 = nomin/denom + s2 = ( alpha.X() + self.Direction[t1].X()*s1 ) / t2X#self.Direction[t2].X() + vec1 = self.Position[t1]+s1*self.Direction[t1] + vec2 = self.Position[t2]+s2*self.Direction[t2] + ave = (vec1+vec2)*0.5 + dif = vec1-vec2 + debugNeed = False + if(abs(abs(minDist)-dif.Mag())>0.00000001): + print "myVertex2 - problem:" + debugNeed = True + if(self.debug>2 or debugNeed): + for tid in (t1,t2): + print str(tid)+": Pos : ", "".join(str(self.Position[tid](ii)) +" " for ii in range(0,3)), + print "\t\tMom : ", "".join(str(self.Direction[tid](ii))+" " for ii in range(0,3)) + print "uPerpend: ","".join(str(uPerpend(ii))+" " for ii in range(0,3)) + if(self.debug>0 or debugNeed): + print "fit vertex: -> 1st poing : ", vec1.X(), vec1.Y(), vec1.Z() + print "fit vertex: -> 2nd point : ", vec2.X(), vec2.Y(), vec2.Z() + print "fit vertex: -> average : ", ave.X(), ave.Y(), ave.Z() + print "distance", abs(minDist), dif.Mag() + return ave, abs(minDist) + + + def readEvent(self): + self.clean() + indx = -1 + for atrack in self.tree.FitTracks: + # kill tracks outside fiducial volume + # if not checkFiducialVolume(sTree,key,dy): continue + fitStatus = atrack.getFitStatus() + if not fitStatus.isFitConverged() : continue + + indx+=1 + mcTrID = self.tree.fitTrack2MC[indx] + + self.__info[mcTrID] = {} + self.__info[mcTrID]['Ndf'] = fitStatus.getNdf() + self.__info[mcTrID]['Chi2'] = fitStatus.getChi2() + + fittedState = atrack.getFittedState() + self.Momentum[mcTrID] = fittedState.getMomMag() + self.Direction[mcTrID] = fittedState.getDir() + self.Position[mcTrID] = fittedState.getPos() + + if(indx>0): + if(indx==1): + self.createVertex(self.__info.keys()[0], self.__info.keys()[1]) + else: + pass + #print "More than 2 fitterd tracks" + return len(self.__info) + + def createVertex(self, tid1, tid2, flag=0): + if( (tid1 in self.__info) and (tid2 in self.__info) ): + self.Vertex, self.Doca = self.myVertex2(tid1, tid2) + self.vertexEFlag = flag + + + def addNewTrack(self, mcTrID, position, direction, Pval, ndf, chi2, verb = True): + if (verb and mcTrID in self.Momentum): + print "FotTrackInfo WARNING - trID ", mcTrID, "already filled! Will rewrite all records for this trID!" + + self.__info[mcTrID]={} + self.__info[mcTrID]['Ndf'] = ndf + self.__info[mcTrID]['Chi2'] = chi2 + + self.Momentum[mcTrID] = Pval + self.Direction[mcTrID] = direction + self.Position[mcTrID] = position + + + def deleteTrack(self, mcTrID): + if mcTrID in self.__info: + del self.__info[mcTrID] + if mcTrID in self.Momentum: + del self.Momentum[mcTrID] + if mcTrID in self.Direction: + del self.Direction[mcTrID] + if mcTrID in self.Position: + del self.Position[mcTrID] \ No newline at end of file diff --git a/newGen/KaterinaLight/RecoSettings.py b/newGen/KaterinaLight/RecoSettings.py new file mode 100644 index 0000000..ffc3578 --- /dev/null +++ b/newGen/KaterinaLight/RecoSettings.py @@ -0,0 +1,25 @@ +# Removed unused imported modules + +import ROOT +import shipunit as u + +""" +Parameter settings for reconstruction +""" + +## min number of hits to produce a track +trackMinNofHits = 25 +trackMinNofStations = 3 +chi2CutOff = 4. +dy = 10.0 +VertexMaxZcut = 2500*u.cm +VertexExtrSteps = 5 +PDG = ROOT.TDatabasePDG.Instance() + +def chargePDG(pdg): + if not PDG.GetParticle(pdg): return + return PDG.GetParticle(pdg).Charge()/(3.) + +def checkEllipticAcc(vec): + Rsq = (vec.X()/(2.45*u.m) )**2 + (vec.Y()/((dy/2.-0.05)*u.m) )**2 + return ( Rsq<1 ) \ No newline at end of file diff --git a/newGen/KaterinaLight/StrawHits.py b/newGen/KaterinaLight/StrawHits.py new file mode 100644 index 0000000..964a76b --- /dev/null +++ b/newGen/KaterinaLight/StrawHits.py @@ -0,0 +1,548 @@ +import ROOT,os,sys,getopt +import rootUtils as ut +import shipunit as u +from pythia8_conf import addHNLtoROOT +from array import array + +import RecoSettings +from FitTrackInfo import FitTrackInfo + + +######################################################################## +class StrawHits(object): + """StrawHit class""" + def __init__(self, tree, modules, resolution, debug=0, mhistdict=None, ship_geo=None): + ## root tree to be read. + self.__tree = tree + ## geometry description modules. + self.__modules = modules + ## debug level [0,3] + self.__debug = debug + ## hit resolition + self.__resolution = resolution + ## {MCtrackID : [{'pos':TVector3, 'det':detID, 'dw':distance to wire, 'smdw': smeared dw} where [TVector3] list of each hit position. Created if MCtrackID>0. + self.__trackHits = {} + ## + self.__oldSmearedHits ={} + ## {MCtrackID : {X : TVector3}} where x='entry' or 'exit', TVector3 coordinates of last or first hit. + ## Created for tracks with more than #RecoSettings .trackMinNofHits hits. + self.__trackEdgeHits = {} + ## {MCtrackID : number of hits at Z<0 (veto tracker)}. + self.__vetoHits = {} + ## {MCtrackID: number of crossed stations (exclude veto tracker)}. + self.__nStations = {} + ## root random engent for hit smearing (see #__hitSmear). + self.__random = ROOT.TRandom() + ROOT.gRandom.SetSeed(13) + #fitter = ROOT.genfit.KalmanFitter() + #fitter = ROOT.genfit.KalmanFitterRefTrack() + self.__fitter = ROOT.genfit.DAF() + # refitted traks + self.__reFitTracks = FitTrackInfo(tree=None, debug = self.__debug) + self.__docaEval = [] + + if (mhistdict and ship_geo) : + fm = ROOT.genfit.FieldManager.getInstance() + # copy from python/shipDet_conf.py + sbf = ROOT.ShipBellField("wilfried", ship_geo.Bfield.max,ship_geo.Bfield.z,2,ship_geo.Yheight/2.*u.m ) + for i in range (0,300): + z = 1000. + i*10 + pvec3 = ROOT.TVector3(0,0,z) + fx = ROOT.Double(0) + fy = ROOT.Double(0) + fz = ROOT.Double(0) + #fvec3f = fm.getField().get(pvec3) + fm.getField().get(0,0,z,fx,fy,fz) + fvec3f = ROOT.TVector3(fx,fy,fz) + + fvec3s = ROOT.TVector3( sbf.GetBx(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBy(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBz(pvec3.X(),pvec3.Y(),pvec3.Z())) + + #print z, " ".join("{:10.4f}".format(fvec3f(ii)) for ii in range(0,3)), + #print "\t", " ".join("{:10.4f}".format(fvec3s(ii)) for ii in range(0,3)) + mhistdict['magZfit'].Fill(z,fvec3f.Mag()) + mhistdict['magZsim'].Fill(z,fvec3s.Mag()) + + zdict = {1:2500., 2:2800., 3:3000.} + for zi in zdict: + for xi in range (-30, 30): + for yi in range (-30,30): + x = xi*10. + y = yi*10. + pvec3 = ROOT.TVector3(x, y, zdict[zi]) + fx = ROOT.Double(0) + fy = ROOT.Double(0) + fz = ROOT.Double(0) + #fvec3f = fm.getField().get(pvec3) + fm.getField().get(x,y,zdict[zi],fx,fy,fz) + fvec3f = ROOT.TVector3(fx,fy,fz) + + fvec3s = ROOT.TVector3( sbf.GetBx(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBy(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBz(pvec3.X(),pvec3.Y(),pvec3.Z())) + #print x, " ", y, " ", zdict[zi], + #print "\t", " ".join("{:10.4f}".format(fvec3f(ii)) for ii in range(0,3)), + #print "\t", " ".join("{:10.4f}".format(fvec3s(ii)) for ii in range(0,3)) + mhistdict['magXY'+str(zi)+"fit"].Fill(x, y,fvec3f.Mag()) + mhistdict['magXY'+str(zi)+"sim"].Fill(x, y,fvec3s.Mag()) +######################################################################## + + + ## \brief to be called for each new event (called in #readEvent()) + # cleans all dictionaries (#__trackHits, #__trackEdgeHits, #__vetoHits, #__nStations). + def __clean(self): + self.__trackHits.clear() + self.__oldSmearedHits.clear() + self.__trackEdgeHits.clear() + self.__vetoHits.clear() + self.__nStations.clear() + self.__docaEval = [] +######################################################################## + + + ## \brief returns list of keys #__trackEdgeHits (MCtrackIDs>0 with more than #RecoSettings .trackMinNofHits hits). + # \return list of MCtrackIDs of "good" tracks. + def getTrIDs(self): + trID = [] + for tid in self.__trackEdgeHits: + trID.append(tid) + return trID +######################################################################## + + + ## \brief returns list of keys #__trackHits (MCtrackIDs>0. + # \return list of MCtrackIDs of MC assigned tracks. + def getTrIDsALL(self): + trID = [] + for tid in self.__trackEdgeHits: + trID.append(tid) + return trID +######################################################################## + + + ## \brief returns list of keys #__reFitTracks. + # \return list of MCtrackIDs of "good" tracks. + def getReFitTrIDs(self): + return self.__reFitTracks.getTrIDs() +######################################################################## + + + def getReFitChi2Ndf(self,tid): + return self.__reFitTracks.getChi2Ndf(tid) +######################################################################## + + + def getReFitNdf(self,tid): + return self.__reFitTracks.getNdf(tid) + + + +######################################################################## + ## \brief returns vertex (if number of tracks!=2 will return None!). + # \return new vertex (if number of tracks!=2 will return None!). + def getReFitVertex(self): + return self.__reFitTracks.getVertex() +######################################################################## + + + +######################################################################## + ## \brief returns doca's of given extrapolation steps (size is defined in #RecoSettings .VertexExtrSteps). + # \param step - extrapolation (max step is defined in #RecoSettings .VertexExtrSteps) + # \return doca's of given extrapolation steps. (if number of tracks!=2 will return None!). + def getStepDoca(self, step): + if ( step>RecoSettings.VertexExtrSteps or (not self.__reFitTracks.Vertex) ) : return None + return self.__docaEval[step] +######################################################################## + + +######################################################################## + ## \brief doca's of the last extrapolation step. + # \return doca of the last extrapolation step (if number of tracks!=2 will return None!). + def getDoca(self): + return self.__docaEval[RecoSettings.VertexExtrSteps-1] +######################################################################## + + + ## \brief for a given track id returns position, direction and momentum value of the track. + # \param tid - MCtrackID. + # \return position (TVector3), direction (TVector3) and momentum value of the track. + def getReFitPosDirPval(self, tid): + return self.__reFitTracks.getPosDirPval(tid) +######################################################################## + + + ## \brief returns number of hits in proper tracker stations (Z>0) calculated from #__trackHits and #__vetoHits. + # \param tid - MCtrackID. + # \return number of hits in proper tracker stations (Z>0). + def getNofPHits(self, tid): + return len(self.__trackHits[tid]) - self.__vetoHits[tid] +######################################################################## + + + ## \brief returns TVector3 of a tracker entry hit (Z>0) from #__trackEdgeHits. + # \param tid - MCtrackID. + # \return position of a tracker entry hit (Z>0) from #__trackEdgeHits. + def getStartHit(self, tid): + return self.__trackEdgeHits[tid]['entry'] +######################################################################## + + + ## \brief returns number of hits with Z<0 of #__trackHits. + # \param tid - MCtrackID. + # \return number of hits with Z<0 of #__trackHits. + def checkVetoHits(self, tid): + vh = 0 + if tid in self.__vetoHits: + vh = self.__vetoHits[tid] + return vh +######################################################################## + + + def PrintNewTracks(self): + print "new Fits: ", + self.__reFitTracks.Print() +######################################################################## + + + def compareFitTracks(self, tid, theFitTracks): + pos, direct, pval = theFitTracks.getPosDirPval(tid) + return self.__reFitTracks.compareTracks(tid, pos, direct, pval) + +######################################################################## + ## \brief returns a dictionary {xtop, ytop, z, ybot, ybot, z, dist} for a smeared hit. + # \param tid - MCtrackID. + # \param hid - hit index of #__trackHits + # \param new - to generate new smearing (True) or get from SmearedHits (det.position still recalculated!) + # \return a dictionary {xtop, ytop, z, ybot, ybot, z, dist} for a smeared hit. + def __hitSmear(self,tid,hid, new=False): + top = ROOT.TVector3() + bot = ROOT.TVector3() + dw = self.__trackHits[tid][hid]['dw'] + detID = self.__trackHits[tid][hid]['det'] + + self.__modules["Strawtubes"].StrawEndPoints(detID,bot,top) + + if( new ): + smear = abs(self.__random.Gaus(dw, self.__resolution)) + else: + smear = self.__trackHits[tid][hid]['smdw'] + smearedHit = {'xtop':top.x(),'ytop':top.y(),'z':top.z(),'xbot':bot.x(),'ybot':bot.y(),'z':bot.z(),'dist':smear} + + if(self.__debug>2): + print "\tsmear :", "".join("{:8.2f}".format(self.__trackHits[tid][hid]['pos'](ii)) for ii in range(0,3)), + print "{:6.2f}".format(dw), + print "\t(xt,xb, yt, yb, z, dw) : ", + for x in ['xtop','xbot', 'ytop','ybot','z', 'dist']: + print "".join("{:8.2f}".format(smearedHit[x])), + print "" + return smearedHit +######################################################################## + + + ## \brief to be called per each event. Fills #__trackHits, #__trackEdgeHits, #__vetoHits, #__nStations. + # \return number of "good" tracks (size of #__trackEdgeHits) + def readEvent(self): + self.__clean() + toSort = [] # list of MCtrackID which has unsorted hits (I saw also hits from different tracks assigned to the same MCtrackID) + stationList = {} # {MCtrackID:[stations]} + + # loop over all hits and fill __trackHits[MCtrackID] + hindx = -1 + for ahit in self.__tree.strawtubesPoint: + detID = ahit.GetDetectorID() + trID = ahit.GetTrackID() + + # get old smearing + hindx +=1 + origSmHit = self.__tree.SmearedHits.At(hindx) + if( (abs(ahit.GetZ()-origSmHit[3])>0.8) or (abs(ahit.dist2Wire()-origSmHit[7])>0.2) ): + print "problem getting smeared his, but do not change anything" + print "=>", ahit.GetZ(), origSmHit[3], ahit.dist2Wire(), origSmHit[7] + # m = array('d',[i,sm['xtop'],sm['ytop'],sm['z'],sm['xbot'],sm['ybot'],sm['z'],sm['dist']]) + + #=> + if(trID<0): continue # these are hits not assigned to MC track because low E cut + + if (not self.__trackHits.has_key(trID)): + self.__trackHits[trID] = [] + stationList[trID] = [] + + hinfo = {} + hinfo['pos'] = ROOT.TVector3(ahit.GetX(), ahit.GetY(), ahit.GetZ()) + hinfo['det'] = ahit.GetDetectorID() + hinfo['dw'] = ahit.dist2Wire() + hinfo['smdw'] = origSmHit[7] + self.__trackHits[trID].append(hinfo) + + lastIndx = len(self.__trackHits[trID])-1 + if( self.__trackHits[trID][lastIndx]['pos'].Z() < self.__trackHits[trID][lastIndx-1]['pos'].Z() ): + if( not trID in toSort): + toSort.append(trID) + if(self.__debug>0): print "StrawHitsEntry: wrong order of hits for track ", trID + + station = int(ahit.GetDetectorID()/10000000) + if station > 4 : continue + if ( not station in stationList[trID]) : stationList[trID].append(station) + + # sort + for trID in toSort: + if(self.__debug>0): print "StrawHitsEntry: will sort hits for track ", trID + if(self.__debug>2): + print "\t\thits to be sorted" + for hinfo in self.__trackHits[trID]: + vec3 = hinfo['pos'] + print "\t\t\t\t", vec3.X(), "\t", vec3.Y(), "\t", vec3.Z(), hinfo['dw'] + self.__trackHits[trID].sort(key=lambda x: x['pos'].Z(), reverse=False) + if(self.__debug>2): + print "\t\thits after sorting" + for hinfo in self.__trackHits[trID]: + vec3 = hinfo['pos'] + print "\t\t\t\t", vec3.X(), "\t", vec3.Y(), "\t", vec3.Z(), hinfo['dw'] + + # fill self.__nStations + for trID in self.__trackHits: + self.__nStations[trID] = len(stationList[trID]) + if(self.__debug>0): + print "Number of crossed stations (trID:n)", trID, " : ", self.__nStations[trID] + + # find entry and exit positions + for trID in self.__trackHits: + if(self.__debug>1): + print "hits for trID ", trID + for hinfo in self.__trackHits[trID]: + vec3 = hinfo['pos'] + print "\t", vec3.X(), "\t", vec3.Y(), "\t", vec3.Z(), hinfo['dw'] + if(self.__debug>0): print "start/stop position for hits of track ", trID + #find number of vetoTracker hits + firstHit = 0 + nHits = len(self.__trackHits[trID]) + while( firstHit + # the EdgeHits are filled only if nHits(stations1-4)>25 + if( (firstHitRecoSettings.trackMinNofHits) ): + self.__trackEdgeHits[trID] = {} + self.__trackEdgeHits[trID]['entry'] = self.__trackHits[trID][firstHit]['pos'] + self.__trackEdgeHits[trID]['exit'] = self.__trackHits[trID][-1]['pos'] + self.__vetoHits[trID] = firstHit + if(self.__debug>0): + for pos in self.__trackEdgeHits[trID]: + vec3 = self.__trackEdgeHits[trID][pos] + print "\t", pos, vec3.X(), "\t", vec3.Y(), "\t", vec3.Z() + elif( self.__debug>0): print "not set due to small number of hits" + + return len(self.__trackEdgeHits) +######################################################################## + + + + + + def __getIniDir(self,trID): + v1 = self.__trackEdgeHits[trID]['entry'] + i2 = self.__vetoHits[trID]+1 + if( len(self.__trackHits[trID])>i2 ): + v2 = self.__trackHits[trID][i2]['pos'] + dv = v2-v1 + else: + dv = ROOT.TVector3(0., 0., 1.) + if(self.__debug>0): + print "trying to get initial direction having just one hit, will set (0,0,1)" + return dv*(1./dv.Mag()) + + + def __prepareIniPosMomCov(self, tid, original=True): + if ( original ) : + pos = ROOT.TVector3(0, 0, 0) + mom = ROOT.TVector3(0,0,3.*u.GeV) + cov = ROOT.TMatrixDSym(6) + resolution = self.__resolution + for i in range(3): cov[i][i] = resolution*resolution + cov[0][0]=resolution*resolution*100. + nM = self.getNofPHits(tid) + for i in range(3,6): cov[i][i] = ROOT.TMath.pow(resolution / nM / ROOT.TMath.sqrt(3), 2) + else: + pos = self.__trackEdgeHits[tid]['entry'] + mom = self.__getIniDir(tid) + cov = ROOT.TMatrixDSym(6) + resolution = self.__resolution + for i in range(3): cov[i][i] = resolution*resolution + cov[0][0]=resolution*resolution*100. + nM = self.getNofPHits(tid) + for i in range(3,6): cov[i][i] = ROOT.TMath.pow(resolution / nM / ROOT.TMath.sqrt(3), 2) + return pos, mom, cov +######################################################################## + + + + def __prepareWireMeasurements(self, tid, fTrack): + #WireMeasurement::WireMeasurement(const TVectorD& rawHitCoords, + # const TMatrixDSym& rawHitCov, + # int detId, + # int hitId, + # genfit::TrackPoint* trackPoint) + # per each proper hit TMP ??? does it make sense to do for tracks with __vetoHits>0??? + #self.__measurements4fit[trID] = [] + for hindx in range (self.__vetoHits[tid], len(self.__trackHits[tid])): + sm = self.__hitSmear(tid,hindx) + mVector = ROOT.TVectorD(7,array('d',[sm['xtop'],sm['ytop'],sm['z'],sm['xbot'],sm['ybot'],sm['z'],sm['dist']])) + #self.__measurements4fit[trID].push_back(mVector) + + hitCov = ROOT.TMatrixDSym(7) + hitCov[6][6] = self.__resolution*self.__resolution + + tp = ROOT.genfit.TrackPoint(fTrack) # note how the point is told which track it belongs to + measurement = ROOT.genfit.WireMeasurement(mVector,hitCov,1,6,tp) # the measurement is told which trackpoint it belongs to + # print measurement.getMaxDistance() + measurement.setMaxDistance(0.5*u.cm) + #measurement.setLeftRightResolution(-1) + tp.addRawMeasurement(measurement) # package measurement in the TrackPoint + if(self.__debug>2): + tp.Print() + fTrack.insertPoint(tp) # add point to Track + + + +######################################################################## + ## \brief fix for more than 2 track case - cleans self.__reFitTracks - \b to \b be \b optimized + # calculates (linearly) vertex from all combinations and finds the two givin best doca + def __cleanTracksToFormVertex(self): + newFitTrIDs = self.__reFitTracks.getTrIDs() + thelist = [] + for tid1 in newFitTrIDs: + for tid2 in newFitTrIDs: + if tid2<=tid1 : continue + v, doca = self.__reFitTracks.myVertex2(tid1, tid2) + thelist.append([doca, tid1,tid2]) + thelist.sort() + for tid in newFitTrIDs: + if ( (tid!=thelist[0][1]) and (tid!=thelist[0][2]) ): + self.__reFitTracks.deleteTrack(tid) + +######################################################################## + def FitTracks(self, old=True): + + self.__reFitTracks.clean() + + fitTrack = {} + #self.__measurements4fit = {} + nTrack = -1 + + + for trID in self.__trackEdgeHits : # these are already tracks with large number of hits + #print "track entry", self.__trackEdgeHits[tid]['entry']. + #print "mfield: ", ROOT + + # minimal requirements on number of crossed stations + if ( self.__nStations2): print "preparing measurements for track ID", trID + self.__prepareWireMeasurements(trID, fitTrack[trID]) + + + if not fitTrack[trID].checkConsistency(): + print 'Problem with track before fit, not consistent',self.fitTrack[atrack] + continue + try: self.__fitter.processTrack(fitTrack[trID]) # processTrackWithRep(fitTrack[atrack],rep,True) + except: + print "genfit failed to fit track" + continue + if not fitTrack[trID].checkConsistency(): + print 'Problem with track after fit, not consistent',self.fitTrack[atrack] + continue + + stat = fitTrack[trID].getFitStatus() + if not stat.isFitConverged() : continue + f = fitTrack[trID].getFittedState() + if( (stat.getNdf()>0) and (self.__vetoHits[trID]==0) ): + self.__reFitTracks.addNewTrack(trID, f.getPos(), f.getDir(), f.getMomMag(), + stat.getNdf(), stat.getChi2()) + if(self.__debug>0): + print "for track ", trID, + print " pos:", " ".join("{:10.4f}".format(f.getPos()(ii)) for ii in range(0,3)), + print " mom:", " ".join("{:10.4f}".format(f.getMom()(ii)) for ii in range(0,3)) + + + + newFitTrIDs = self.__reFitTracks.getTrIDs() + + # FIXme! make it more reasonable way and optimize! + if len(newFitTrIDs)>2: + if(self.__debug>0): + print "cleaning large multiplicity event!\nbefore:" + self.__reFitTracks.Print() + + self.__cleanTracksToFormVertex() + + if(self.__debug>0): + print "cleaning large multiplicity event!\nafter:" + self.__reFitTracks.Print() + + newFitTrIDs = self.__reFitTracks.getTrIDs() + if len(newFitTrIDs)>2: + print "track re-fitting finds more than 2 tracks and was not able to clean the event - skipping" + return len(newFitTrIDs) + + twoTracks = ( len(newFitTrIDs)==2 ) + theStep = 0 + self.__docaEval = [] + if (twoTracks) : + self.__reFitTracks.createVertex(newFitTrIDs[0], newFitTrIDs[1], flag=0) # original + iniDoca = self.__reFitTracks.Doca + iniY = self.__reFitTracks.Vertex.Y() + while ( theStep1): + print "==>vertex ", theStep, " ", self.__reFitTracks.Doca + self.__reFitTracks.Vertex.Print() + self.__docaEval.append(self.__reFitTracks.Doca) + for tid in newFitTrIDs : + try: + state = fitTrack[tid].getFittedState() + except: + print "can't get fittedState" + flag = -1 + vPosEx = ROOT.TVector3(0,0,0) + vMomEx = ROOT.TVector3(0,0,0) + try : + state.extrapolateToPoint(self.__reFitTracks.Vertex) + except : + flag = -1 + print "track exctrapolation failed!tid: ", tid + if (flag > 0 ) : # + status = fitTrack[tid].getFitStatus() + #print "=>", tid, status.getNdf() + #print "extr track ", tid, + #print " pos:", " ".join("{:10.4f}".format(state.getPos()(ii)) for ii in range(0,3)), + #print " mom:", " ".join("{:10.4f}".format(state.getMom()(ii)) for ii in range(0,3)) + self.__reFitTracks.addNewTrack(tid, state.getPos(), state.getDir(), state.getMomMag(), + status.getNdf(), status.getChi2(), verb=False) + # FIX temporary + self.__reFitTracks.createVertex(newFitTrIDs[0], newFitTrIDs[1], flag) + self.__reFitTracks.Vertex.SetY(iniY) + theStep+=1 + twoTacks = ( len(self.__reFitTracks.getTrIDs())==2 ) + return len(newFitTrIDs) + + diff --git a/newGen/histoForWeights_antinu.root b/newGen/histoForWeights_antinu.root new file mode 100644 index 0000000..20568cd --- /dev/null +++ b/newGen/histoForWeights_antinu.root Binary files differ diff --git a/newGen/histoForWeights_nu.root b/newGen/histoForWeights_nu.root new file mode 100644 index 0000000..bf00134 --- /dev/null +++ b/newGen/histoForWeights_nu.root Binary files differ diff --git a/newGen/lookAtGeo.py b/newGen/lookAtGeo.py new file mode 100644 index 0000000..b9e3de7 --- /dev/null +++ b/newGen/lookAtGeo.py @@ -0,0 +1,154 @@ +import ROOT,os,sys,getopt,time +import shipunit as u +import shipRoot_conf +from ShipGeoConfig import ConfigRegistry +from ROOT import * + +# function to prepare two dictionaries: one that has the node names as key and the related intex +# in the nodes array as value and the other one with key and value swapped. +def prepareNodeDictionaries(nodes): + # key: index, value: name of the node + nodeDict_index = {} + # key: name of the node, value: index + nodeDict_name = {} + for (i,n) in enumerate(nodes): + #print i,n.GetName() + nodeDict_index[i]=n.GetName() + nodeDict_name[n.GetName()]=i + return {'nodeDict_index':nodeDict_index, 'nodeDict_name':nodeDict_name} + +# function to print the node names and their index. Usefull to search the name of the element you would like +# to study if you don't know it by heart. Then the name can be used with the other functions for the specific studies. +def searchForNodes(inputFile, volName = None): + r = loadGeometry(inputFile) + fGeo = r['fGeo'] + ## Get the top volume + fGeo = ROOT.gGeoManager + + if volName is None: + tv = fGeo.GetTopVolume() + else: + tv = fGeo.GetVolume(volName) + + nodes = tv.GetNodes() + for (i,n) in enumerate(nodes): + print i,n.GetName() + +def searchForNodes2(inputFile,volName=None): + r = loadGeometry(inputFile) + fGeo = r['fGeo'] + ## Get the top volume + #fGeo = ROOT.gGeoManager + if volName is None: + tv = fGeo.GetTopVolume() + else: + tv = fGeo.GetVolume(volName) + + nodes = tv.GetNodes() + for (i,n) in enumerate(nodes): + print i,n.GetName(),findPositionElement(n)['z'],findDimentionBoxElement(n)['z'] + +def searchForNodes2_xyz(inputFile, volName=None): + r = loadGeometry(inputFile) + fGeo = r['fGeo'] + ## Get the top volume + #fGeo = ROOT.gGeoManager + if volName is None: + tv = fGeo.GetTopVolume() + else: + tv = fGeo.GetVolume(volName) + nodes = tv.GetNodes() + for (i,n) in enumerate(nodes): + print i,n.GetName() + print " x: ", findPositionElement(n)['x'],findDimentionBoxElement(n)['x'] + print " y: ", findPositionElement(n)['y'],findDimentionBoxElement(n)['y'] + print " z: ", findPositionElement(n)['z'],findDimentionBoxElement(n)['z'] + +# basic function to be called to load the geometry from a file +def loadGeometry(inputFile): + dy = float( inputFile.split("/")[-1].split(".")[1]) + + ShipGeo = ConfigRegistry.loadpy("$FAIRSHIP/geometry/geometry_config.py", Yheight = dy ) + # init geometry and mag. field + ShipGeo = ConfigRegistry.loadpy("$FAIRSHIP/geometry/geometry_config.py", Yheight = dy ) + # -----Create geometry---------------------------------------------- + import shipDet_conf + + tgeom = ROOT.TGeoManager("Geometry", "Geane geometry") + geofile = inputFile.replace('ship.','geofile_full.').replace('_rec.','.') + print geofile + gMan = tgeom.Import(geofile) + fGeo = ROOT.gGeoManager + return {'fGeo':fGeo,'gMan':gMan, 'ShipGeo':ShipGeo} + +def getNode(nodeName,fGeo=None, volName=None): + if fGeo is None: + r = loadGeometry(inputFile) + fGeo = r['fGeo'] + if volName is None: + tv = fGeo.GetTopVolume() + else: + tv = fGeo.GetVolume(volName) + + nodes = tv.GetNodes() + dicts = prepareNodeDictionaries(nodes) + return nodes[dicts['nodeDict_name'][nodeName]] + +def findDimentionBoxElement(node): + ## GetDZ() etc gives you half of the dimention + sh = node.GetVolume().GetShape() + return {'x':sh.GetDX(), + 'y':sh.GetDY(), + 'z':sh.GetDZ()} + +def findPositionElement(node): + pos = node.GetMatrix().GetTranslation() + + return {'x':pos[0], + 'y':pos[1], + 'z':pos[2]} + +## inputFile: file used from which I would like to retrive the geometry used +## myNodes_name: geometrical elements I would like to analyse (find the position) +def findPositionGeoElement(inputFile, myNodes_name, volName=None): + + r = loadGeometry(inputFile) + fGeo = r['fGeo'] + #volumes = gMan.GetListOfVolumes() + #for v in volumes: + # print v.GetName(), v.GetNumber() + + ## Get the top volume + if volName is None: + tv = fGeo.GetTopVolume() + else: + tv = fGeo.GetVolume(volName) + + nodes = tv.GetNodes() + + tmp = prepareNodeDictionaries(nodes) + nodeDict_name = tmp['nodeDict_name'] + res = {} + for nd_name in myNodes_name: + nd_index = nodeDict_name[nd_name] + nd = nodes[nd_index] + pos = findPositionElement(nd) + dims = findDimentionBoxElement(nd) + res[nd_name]={'z':pos['z'], + 'dimZ':dims['z'], + 'node':nd, + 'dimX':dims['x'], + 'dimY':dims['y']} + return res + +#inputFile = "../data/neutrino661/ship.10.0.Genie-TGeant4_D.root" +##searchForNodes(inputFile) + +### nodes name to be looked at +#myNodes_name = ["volLayer2_%s"%i for i in xrange(0,12)] +#myGeoEl = findPositionGeoElement(inputFile, myNodes_name) +#print myGeoEl + +##print myGeoEl["volLayer2_0"]['z'],myGeoEl["volLayer2_11"]['z'] +##print myGeoEl["volLayer2_11"]['z']-myGeoEl["volLayer2_0"]['z'] + diff --git a/newGen/ntuple_nuVeto_small.py b/newGen/ntuple_nuVeto_small.py new file mode 100644 index 0000000..d1f8f23 --- /dev/null +++ b/newGen/ntuple_nuVeto_small.py @@ -0,0 +1,637 @@ +import sys, re, getopt +from array import array +from ROOT import * + +fileName, fileNameGeo, outputFileName, sampleType, jobID = None, None, None, None, None +maxevents = 0 +verbose = True +# Energy deposit threshold for the liquid scintillator +threshold = 0.045 + +# Parse commandline inputs +try: + opts, args = getopt.getopt(sys.argv[1:], "n:t:f:o:v:j:", ['Ethr=']) +except getopt.GetoptError: + # print help information and exit: + print '\tUSAGE: -f inputfile.root -o outputfile.root -t sampleType (sig, nuBg or cosmics) -n maxevents -v verbose (0 or 1) -j jobID (0 to ...) ' + sys.exit() +for o, a in opts: + if o in ("-f",): + fileName = a + if o in ("-o",): + outputFileName = a + if o in ("-n",): + print "-n",a + maxevents = int(a) + if o in ("-j",): + print "-j",a + jobID = long(a) + if o in ("-t",): + sampleType = str(a) + if o in ("-v",): + verbose = bool(int(a)) + if o in ("--Ethr=",): + threshold = float(a) + +fileNameGeo = fileName.replace('ship', 'geofile_full').replace("_rec","") + +def namestr(obj, namespace=globals()): + return [name for name in namespace if namespace[name] is obj] + +for item in [fileName, fileNameGeo, outputFileName, sampleType]: + if not item: + print '\tFATAL! %s not defined!'%namestr(item)[0] + sys.exit() + +for item in [fileName, fileNameGeo, outputFileName, sampleType, maxevents, verbose, threshold]: + print '\tINFO: %s set to %s'%(namestr(item)[0], item) + +# Load SHiP (LHCb) style +gROOT.ProcessLine(".x mystyle.C") +# Obsolete debug flags +oldGeo = False +ON = True +# Load PDG database +pdg = TDatabasePDG.Instance() +# Add elements to PDG database +import pythia8_conf +pythia8_conf.addHNLtoROOT() +# TODO: MAKE THIS A DICTIONARY AND DE-VERBOSIZE IT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 +if not(pdg.GetParticle(1000010020)): + pdg.AddParticle("Deuteron","Deuteron", 1.875613e+00, kTRUE, 0,3,"Ion",1000010020) + pdg.AddAntiParticle("AntiDeuteron", - 1000010020) +if not(pdg.GetParticle(1000010030)): + pdg.AddParticle("Triton","Triton", 2.808921e+00, kFALSE, 3.885235e+17,3,"Ion",1000010030); + pdg.AddAntiParticle("AntiTriton", - 1000010030); +if not(pdg.GetParticle(1000020040) ): + pdg.AddParticle("Alpha","Alpha",3.727379e+00,kFALSE,0,6,"Ion",1000020040); + pdg.AddAntiParticle("AntiAlpha", - 1000020040); +if not(pdg.GetParticle(1000020030) ): + pdg.AddParticle("HE3","HE3",2.808391e+00,kFALSE,0,6,"Ion",1000020030); + pdg.AddAntiParticle("AntiHE3", -1000020030); +if not(pdg.GetParticle(1000030070) ): + print "TO BE CHECKED the data insert for Li7Nucleus" + pdg.AddParticle("Li7Nucleus","Li7Nucleus",3.727379e+00/4.*7.,kFALSE,0,0,"Boson",1000030070); +if not(pdg.GetParticle(1000060120) ): + print "ERROR: random values insert for C12Nucleus" + pdg.AddParticle("C12Nucleus","C12Nucleus",0.1,kFALSE,0,0,"Isotope",1000060120); +if not(pdg.GetParticle(1000030060) ): + print "ERROR: random values insert for Li6Nucleus" + pdg.AddParticle("Li6Nucleus","Li6Nucleus",6.015121,kFALSE,0,0,"Isotope",1000030060); +if not(pdg.GetParticle(1000070140) ): + print "ERROR: random values insert for for N14" + pdg.AddParticle("N14","N14",0.1,kTRUE,0,0,"Isotope",1000070140); +if not(pdg.GetParticle(1000050100) ): + print "TO BE CHECKED the data insert for B10" + pdg.AddParticle("B10","B10",10.0129370,kTRUE,0,0,"Isotope",1000050100); +if not(pdg.GetParticle(1000020060) ): + print "TO BE CHECKED the data insert for He6" + pdg.AddParticle("He6","He6",6.0188891,kFALSE,806.7e-3,0,"Isotope",1000020060); +if not(pdg.GetParticle(1000040080) ): + print "TO BE CHECKED the data insert for Be8" + pdg.AddParticle("Be8","Be8",8.00530510,kFALSE,6.7e-17,0,"Isotope",1000040080); +if not(pdg.GetParticle(1000030080) ): + print "TO BE CHECKED the data insert for Li8" + pdg.AddParticle("Li8","Li8",8.002248736,kTRUE,178.3e-3,0,"Isotope",1000030080); +if not(pdg.GetParticle(1000040170) ): + print "ERROR: didn't find what is it particle with code 1000040170, random number inserted!" + pdg.AddParticle("None","None",0.1,kFALSE,0,0,"Isotope",1000040170); +if not(pdg.GetParticle(1000040100) ): + print "TO BE CHECKED the data insert for Be10" + pdg.AddParticle("Be10","Be10",10.0135338,kTRUE,5.004e+9,0,"Isotope",1000040100); +if not(pdg.GetParticle(1000040070) ): + print "TO BE CHECKED the data insert for Be7" + pdg.AddParticle("Be7","Be7",11.021658,kTRUE,13.81,0,"Isotope",1000040070); +if not(pdg.GetParticle(1000230470) ): + print "ERROR: didn't find what is it particle with code 1000230470, random number inserted!" + pdg.AddParticle("None2","None2",0.1,kFALSE,0,0,"Isotope",1000230470); +if not(pdg.GetParticle(1000080170) ): + print "ERROR: didn't find what is it particle with code 1000080170, random number inserted!" + pdg.AddParticle("None3","None3",0.1,kFALSE,0,0,"Isotope",1000080170); +if not(pdg.GetParticle(1000240500) ): + print "ERROR: didn't find what is it particle with code 1000240500, random number inserted!" + pdg.AddParticle("None4","None4",0.1,kFALSE,0,0,"Isotope",1000240500); +if not(pdg.GetParticle(1000210450) ): + print "ERROR: didn't find what is it particle with code 1000210450, random number inserted (Sc45Nucleus)!" + pdg.AddParticle("Sc45Nucleus","Sc45Nucleus",0.1,kFALSE,0,0,"Isotope",1000210450); +if not(pdg.GetParticle(1000040090) ): + print "TO BE CHECKED the data insert for Be9" + pdg.AddParticle("Be9","Be9",9.0121822,kFALSE,0,0,"Isotope",1000040090); +if not(pdg.GetParticle(1000080160) ): + print "TO BE CHECKED the data insert for O16" + pdg.AddParticle("O16","O16",15.99491461956,kFALSE,0,0,"Isotope",1000080160); +if not(pdg.GetParticle(1000220460) ): + print "TO BE CHECKED the data insert for Ar40" + pdg.AddParticle("Ar40","Ar40",39.9623831225,kFALSE,0,0,"Isotope",1000220460); +if not(pdg.GetParticle(1000050110) ): + print "TO BE CHECKED the data insert for B11" + pdg.AddParticle("B11","B11",11.0093054,kFALSE,0,0,"Isotope",1000050110); + +def PrintEventPart(particles,pdg): + print "Particles in the event:" + for (pid,part) in enumerate(particles): + print pid, pdg.GetParticle(part.GetPdgCode()).GetName(), part.GetMotherId() + print + +def PrintRPChits(rpc,pdg): + print "Hits in:" + for (ix,RPCpt) in enumerate(rpc): + tmpName = pdg.GetParticle(RPCpt.PdgCode()) + print ix,RPCpt.GetZ(), tmpName, RPCpt.GetTrackID() , fGeo.FindNode(RPCpt.GetX(),RPCpt.GetY(),RPCpt.GetZ()).GetVolume().GetName() + print + +# weight computation moved to offlineForBarbara.py + +def addVect(t,name,vectType): + vect = vector(vectType)() + t.Branch( name, vect ) + return t, vect + +def addVar(t,name,varType): + var = array(varType,[-999]) + t.Branch(name,var,name+"/"+varType.upper()) + return t, var + +def putToZero(var): + var[0] = 0 + +def getPartName(partId): + return pdg.GetParticle(partId).GetName() + +def lookingForDecay(particles): + decayMotherList = [] + for p in particles: + mID = p.GetMotherId() + if mID>=0 and not (mID in decayMotherList): + decayMotherList.append(mID) + decayPartIndex.push_back(mID) + decayPartID.push_back(particles[mID].GetPdgCode()) + decayPartStrID.push_back(pdg.GetParticle(particles[mID].GetPdgCode()).GetName()) + decayPos_x.push_back(p.GetStartX()) + decayPos_y.push_back(p.GetStartY()) + decayPos_z.push_back(p.GetStartZ()) + decayMother.push_back(particles[mID].GetMotherId()) + decayP.push_back(p.GetP()) + +def wasFired(indexKids, detPoints, detPos, hitCharges, hitTrackId, checkOn, pointVects=None, Ethr=0): + # + def lookingForHits(detPoints,flag,flag_eff,nstat,nstat_eff,indexKids,Eloss,Ethr,hitCharges, hitTrackId): + charges = [] + trackids = [] + if hitCharges is None: + assert(hitTrackId is None) + for pos in detPos: + foundStat = False + foundStat_eff = False + for hit in detPoints: + if (indexKids is None) or (hit.GetTrackID() in indexKids): + # check if it is in one of the considered active layer + if pos[0]<=hit.GetZ()<=pos[1]: + Eloss += hit.GetEnergyLoss() + hitID = hit.GetTrackID() + if not hitID in trackids and not hitCharges is None: + if hit.PdgCode()>100000: + charges.append(9) + else: + charges.append(int(pdg.GetParticle(hit.PdgCode()).Charge())) + trackids.append(hitID) + hitCharges.push_back(charges[-1]) + hitTrackId.push_back(trackids[-1]) + if pointVects is not None: + pointVects[0].push_back(hit.GetX()) + pointVects[1].push_back(hit.GetY()) + pointVects[2].push_back(hit.GetZ()) + flag = True + foundStat = True + eff_val = gRandom.Uniform(0.,1.) + if eff_val<0.9: + flag_eff = flag_eff or True + foundStat_eff = True + else: + flag_eff = flag_eff or False + if foundStat: + nstat+=1 + if foundStat_eff: + nstat_eff+=1 + particles = 0 + flag_Ethr = Eloss>=Ethr + return flag, flag_eff, nstat, nstat_eff, Eloss, flag_Ethr,particles + # + # Now in partKidTrackID I should have the trackID connected to my charged particles + flag_eff = False + flag = False + nstat = 0 + nstat_eff = 0 + Eloss = 0 + flag,flag_eff,nstat,nstat_eff,Eloss,flag_Ethr,particles = lookingForHits(detPoints,flag,flag_eff,nstat,nstat_eff,indexKids,Eloss,Ethr,hitCharges, hitTrackId) + if flag==False and checkOn: + print "To be study event %s"%entry + return flag, flag_eff, nstat, nstat_eff, flag_Ethr, particles + +def convertion(tmpName): + if "Rib" in tmpName: tmpName = "Rib" + elif "LiSc" in tmpName: tmpName= "LiSc" + elif "Tr" in tmpName: tmpName = "Tr" + elif "Startplate" in tmpName: tmpName = "Startplate" + elif re.search("T\d+O", tmpName): tmpName = "TO" + elif re.search("T\d+I", tmpName): tmpName = "TI" + elif "Endplate" in tmpName: tmpName = "Endplate" + elif "volCoil" in tmpName: tmpName = "volCoil" + elif "volFeYoke" in tmpName: tmpName = "volFeYoke" + elif "gas" in tmpName: tmpName = "gas" + elif "wire" in tmpName: tmpName == "wire" + elif "VetoTimeDet" in tmpName: tmpName = "upstreamVeto" + elif "Veto" in tmpName: tmpName = "strawVeto" + return tmpName + +def wasFired_node(indexKids, detPoints, detVolNames, hitCharges, hitTrackId, checkOn, pointVects=None, Ethr=0): + # + def lookingForHits(detPoints,flag,hitCharges, hitTrackId): + if hitCharges is None: + assert(hitTrackId is None) + for hit in detPoints: + if (indexKids is None) or (hit.GetTrackID() in indexKids): + tmpName = fGeo.FindNode(hit.GetX(),hit.GetY(),hit.GetZ()).GetVolume().GetName() + tmpName = convertion(tmpName) + if hit.GetZ()>8000: + continue + if tmpName in detVolNames: + ## trick to remove the case of the tracking system the hits in the gas or straw from the straw-veto: + if 'trackingSystem' in detVolNames and hit.GetZ()<0: + continue + if "strawVetoSystem" in detVolNames and hit.GetZ()>0: + continue + if "upstreamVeto" in detVolNames and not(hit.GetZ()>= upstreamVetoPos[0][0] and hit.GetZ()<=upstreamVetoPos[0][1]): + continue + # check if it is in one of the considered active layer + if True: #pos[0]<=hit.GetZ()<=pos[1]: + flag = True + return flag + # + # Now in partKidTrackID I should have the trackID connected to my charged particles + flag = False + flag = lookingForHits(detPoints,flag,hitCharges, hitTrackId) + if flag==False and checkOn: + print "To be study event %s"%entry + return flag + + +""" Main program """ + +# Open file +f = TFile(fileName) +t = f.Get("cbmsim") + +totentries = t.GetEntries() +if verbose: + print + print + print "Program started, reading %s from %s"%(t.GetName(), fileName) +if (maxevents>0) and (maxevents < totentries): + entries = maxevents +else: + entries = totentries +if verbose: + print "Requested to process %s events out of %s in tree"%(entries, totentries) + +# Load geometry +from lookAtGeo import * +r = loadGeometry(fileNameGeo) +fGeo = r['fGeo'] + +# Functions by Elena for offline selection +# (Also includes another dictionary of all geometry nodes) +import offlineForBarbara as offline +offline.loadNodes(fGeo) +offline.ShipGeo = r['ShipGeo'] +offline.initBField(fileNameGeo) +offline.sh = offline.StrawHits(t, offline.modules, offline.ShipGeo.straw.resol, 0, None, offline.ShipGeo) +offline.pdg = pdg + +# Handle geometry +# Names of useful geometry nodes +myNodes_name = ["VetoTimeDet_1"] +myNodes_name += ["Tr%s_%s"%(i,i) for i in xrange(1,5)] +myNodes_name += ["Veto_5"] +# Positions of selected nodes +myGeoEl = findPositionGeoElement(fileNameGeo, myNodes_name,None) +# Places where a neutrino can interact +lastPassive_nodeName = ["volIron_23"] +OPERA_nodeName = ["volIron", "volRPC", "volHPT","volArm2MS","volFeYokes","volCoil","volFeYoke"]#["volIron_%s"%i for i in xrange(12,24)]+["volRpc_%s"%i for i in xrange(11,22)]+["volArm2MS_1"] +entrance_nodeName = ["T1Lid"]#['T1lid_1'] +volumeIn_nodeName = ["TI"]#['T%sI'%i for i in [1,2,3,5]] +volumeOut_nodeName = ["TO"]#['T%sO'%i for i in [1,2,3,5]] +OPERA_volNames = ["volIron","volRpc","volHPT"] +strawVeto_volNames = ["Veto"] +# Z positions of the VETO and tracking systems +Tracking = [myGeoEl["Tr1_1"]['z']-myGeoEl["Tr1_1"]['dimZ'],myGeoEl["Tr4_4"]['z']+myGeoEl["Tr4_4"]['dimZ']] +upstreamVeto = [myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ'],myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']] +trackStationsPos = [[myGeoEl["Tr%s_%s"%(i,i)]['z']-myGeoEl["Tr%s_%s"%(i,i)]['dimZ'],myGeoEl["Tr%s_%s"%(i,i)]['z']+myGeoEl["Tr%s_%s"%(i,i)]['dimZ']] for i in xrange(1,5)] +strawVetoPos = [[myGeoEl["Veto_5"]['z']-myGeoEl["Veto_5"]['dimZ'],myGeoEl["Veto_5"]['z']+myGeoEl["Veto_5"]['dimZ']]] +vetoWall = [[myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']+0.001,myGeoEl["Tr%s_%s"%(i,i)]['z']-myGeoEl["Tr%s_%s"%(i,i)]['dimZ']]]#myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']+6000.]] +upstreamVetoPos = [[myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ'],myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']]] +RPCstationsPos = [[-3500,myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ']-0.5]] +# Places where a neutrino can interact (some duplicates?) +trackStationsPos_node = ["Tr", "gas", "straw", 'trackingSystem'] +## should be that this does not work since it could be that hits are also assigned to gas or straw +strawVetoPos_node = ["strawVeto", "gas", "straw", "strawVetoSystem"] +vetoWall_node = ["LiSc","cave","Rib","TI","TO","Tr","strawVeto"] +upstreamVetoPos_node = ["upstreamVeto","cave"] +RPCstationsPos_node = ["volRpc","volMagneticSpectrometer","volIron","volHPT"] +# Printout positions +print "OPERApos: ",RPCstationsPos +print "trackingPos: ",trackStationsPos +print "strawVetoPos: ",strawVetoPos +print "scintPos: ",vetoWall +print "upstreamVetoPos: ",upstreamVetoPos + +# Prepare output ntuple +nf = TFile(outputFileName,"RECREATE") +nt = TTree("t","t") +# Event number -------------------------------------------- +nt, event = addVar(nt, 'event','i') +# Neutrino information ------------------------------------ +nt, nNu = addVar(nt, 'nNu', 'i') +nt, isPrimary = addVar(nt, 'isPrimary','i') +nt, startZ_nu = addVar(nt, 'startZ_nu', 'f') +nt, startY_nu = addVar(nt, 'startY_nu', 'f') +nt, startX_nu = addVar(nt, 'startX_nu', 'f') +nt, nuE = addVar(nt, 'nuE', 'f') +nt, weight = addVar(nt, 'weight', 'f') +# Interaction element code -------------------------------- +## 0: last passive material opera-mu-system +## 1: two windows around liquid scintillator +## 2: along vaccum tank +## 3: along all OPERA +## 4: between the two entrance windows +## 5: along vacuum tank outer window +## 6: along vacuum tank inner window +## 999: wrong OPERA place ## needed until we have the new production +## -1: anything else, but what???? #it should never been present +nt, interactionElement = addVar(nt, 'interactionElement','i') +# Neutrino daughters -------------------------------------- +# Do the particles come from a neutrino? +nt, nPart_fromNu = addVar(nt, 'nPart_fromNu', 'i') +nt, idPart_fromNu = addVect(nt, 'idPart_fromNu', 'int') +#nt, idStrPart_fromNu = addVect(nt, 'idStrPart_fromNu', 'string') +# Do charged particles come from a neutrino? +nt, nChargedPart_fromNu = addVar(nt, 'nChargedPart_fromNu', 'i') +nt, idChargedPart_fromNu = addVect(nt, 'idChargedPart_fromNu', 'int') +#nt, idStrChargedPart_fromNu = addVect(nt, 'idStrChargedPart_fromNu', 'string') +# Do neutral particles come from a neutrino? +nt, nNeutrPart_fromNu = addVar(nt, 'nNeutrPart_fromNu', 'i') +nt, idNeutrPart_fromNu = addVect(nt, 'idNeutrPart_fromNu', 'int') +#nt, idStrNeutrPart_fromNu = addVect(nt, 'idStrNeutrPart_fromNu', 'string') +# RPC ----------------------------------------------------- +# In case something (no matter if it comes from the nu-interaction kids) fired the RPC +nt, RPCany = addVar(nt,'RPCany', 'i' ) +# accounting for an eff. of each station of 90% +nt, RPCany_eff = addVar(nt,'RPCany_eff', 'i' ) +# upstreamVeto -------------------------------------------- +nt, upstreamVetoany = addVar(nt,'upstreamVetoAny', 'i' ) +# accounting for an eff. of each station of 90% +nt, upstreamVetoany_eff = addVar(nt,'upstreamVetoAny_eff', 'i' ) +# scintVeto ----------------------------------------------- +## In case something (no matter if it comes from the nu-interaction kids) fired the surroundin walls +nt, scintVetoAny = addVar(nt,'scintVetoAny', 'i' ) +nt, scintVetoAny_eff = addVar(nt,'scintVetoAny_eff', 'i' ) +# strawVeto ----------------------------------------------- +# In case something (no matter if it comes from the nu-interaction kids) fired the strawVeto +nt, strawVetoAny = addVar(nt,'strawVetoAny', 'i' ) +nt, strawVetoAny_eff = addVar(nt,'strawVetoAny_eff', 'i' ) +# TrackSyst ----------------------------------------------- +# only the case of anything fired it is considered, obviously +nt, TrackSyst = addVar(nt, "TrackSyst", 'i') +nt, TrackSyst_eff = addVar(nt, "TrackSyst_eff", 'i') +# VETO and tracking systems with thresholds --------------- +nt, strawVetoAny_Ethr = addVar(nt,"strawVetoAny_Ethr","i") +nt, scintVetoAny_Ethr = addVar(nt,"scintVetoAny_Ethr","i") +nt, upstreamVetoAny_Ethr = addVar(nt,"upstreamVetoAny_Ethr","i") +nt, RPCany_Ethr = addVar(nt,"RPCany_Ethr","i") +nt, TrackSyst_Ethr = addVar(nt, "TrackSyst_Ethr", "i") +# Decay information --------------------------------------- +nt, decayPartIndex = addVect(nt, "decayPartIndex", "float") +nt, decayPartID = addVect(nt, "decayPartID", "float") +nt, decayPartStrID = addVect(nt, "decayPartStrID", "string") +nt, decayPos_x = addVect(nt, "decayPos_x", "float") +nt, decayPos_y = addVect(nt, "decayPos_y", "float") +nt, decayPos_z = addVect(nt, "decayPos_z", "float") +nt, decayMother = addVect(nt, "decayMother", "float") +nt, decayP = addVect(nt,"decayP","float") +# Is this a NC interaction? ------------------------------- +nt, NC = addVar(nt, "NC", "i") +# Store where the neutrino interacted --------------------- +#nt, nuInteractionNode = addVect(nt, "nuInteractionNode", "string") +nt, nuIntNumSimpl = addVar(nt,"nuIntNumSimpl","i") +dictNodeNames = {'volIron':0, 'cave':1, 'LiSc':2, 'Startplate':3, 'TI':4, 'rockD':5, 'Endplate':6, 'Rib':7, 'volFeYoke':8, 'volHPT':9, 'TO':10, 'volRpc':11, 'volCoil':12, 'T1Lid':13, 'straw':14, 'strawVeto':15, 'volBase':16, 'Tr':17, 'gas':18, 'wire':19, 'others':20} +# Was the event reconstructed? ---------------------------- +nt, recoed = addVar(nt, "recoed","i") +# How many candidates in the reco event? ------------------ +nt, nRecoed = addVar(nt, "nRecoed","i") +# Add stuff for online selection -------------------------- +offline.addOfflineToTree(nt) +# Leaf for job ID +nt, jID = addVar(nt, "jobID", "l") + +# Now loop on the tree +# t = original tree +# nt = new tree +for entry in xrange(entries): + if not (entry%1000): + print "\tProcessing entry %s of %s..."%(entry,entries) + t.GetEntry(entry) + putToZero(jID) + jID[0] = jobID + event[0] = entry #+(jobID*entries) + particles = t.MCTrack + rpc = t.ShipRpcPoint + scint = t.vetoPoint + strawPoints = t.strawtubesPoint + vetoScint = t.vetoPoint + recoParts = t.Particles + # initialize containers + putToZero(nNu) + putToZero(nPart_fromNu) + putToZero(nChargedPart_fromNu) + putToZero(nNeutrPart_fromNu) + idPart_fromNu.clear() + idChargedPart_fromNu.clear() + idNeutrPart_fromNu.clear() + #idStrPart_fromNu.clear() + #idStrChargedPart_fromNu.clear() + #idStrNeutrPart_fromNu.clear() + decayPartIndex.clear() + decayPartID.clear() + decayPartStrID.clear() + decayPos_x.clear() + decayPos_y.clear() + decayPos_z.clear() + decayMother.clear() + decayP.clear() + #nuInteractionNode.clear() + primaryDone=False + isPrimary[0] = int(False) + lookingForDecay(particles) + nRecoed[0] = 0 + recoed[0] = 0 + # Which one is the "primary" particle? + if sampleType=="nuBg" or sampleType == "cosmics": + startPartRange = [0] + primaryMum = -1 + elif sampleType=="sig": + startPartRange = [1] + primaryMum = 0 + # Look at the primary particle + ip = startPartRange[0] + skipEvent=False + # Were there any hit in the tracking stations? + TrackSyst[0],TrackSyst_eff[0],dummy,dummy,TrackSyst_Ethr[0], dummy = wasFired(None, strawPoints, trackStationsPos, None, None, checkOn=False, pointVects=None)#[strawPoint_x, strawPoint_y, strawPoint_z] ) + # If no, skip this event + if TrackSyst[0]==0: + skipEvent=True + #print "i am jumping this one" + continue + # exit from loop on particles + #break + # Select the primary MC particle + part = particles[ip] + pdgPart = pdg.GetParticle(part.GetPdgCode()) + if sampleType=="nuBg": + assert("nu" in pdgPart.GetName()) + ## Looking for a neutrino: it should have the correct pdg code and it should not have a mother + #if (("nu" in pdgPart.GetName())):# and part.GetMotherId()==-1): # commented out by elena + ## (and de-indented the following block) + ## Starting the counter of how many particles were produced by the interaction of this specific nu + for recoP in recoParts: + nRecoed[0] += 1 + #offline.pushOfflineByParticle(t, recoP) + if nRecoed[0]>0: + recoed[0]=1 + else: + skipEvent=True + continue + #break + nNu[0]+=1 + if part.GetMotherId()==primaryMum: + assert(primaryDone==False) + primaryDone=True + isPrimary[0] = int(True) + assert(len(idPart_fromNu)==0) + assert(len(idNeutrPart_fromNu)==0) + else: + continue + # Where did this guy interact? + tmpName = fGeo.FindNode(part.GetStartX(),part.GetStartY(),part.GetStartZ()).GetVolume().GetName() + #nuInteractionNode.push_back(tmpName) + tmpName = convertion(tmpName) + if not tmpName in dictNodeNames: + tmpName = "others" + nuIntNumSimpl[0] = dictNodeNames[tmpName] + # Store interaction point coordinates + startZ_nu[0] = part.GetStartZ() + startY_nu[0] = part.GetStartY() + startX_nu[0] = part.GetStartX() + # Primary particle information + nuE[0] = part.GetEnergy() + # Looking for particles produced by the neutrino interaction + interacted = False + partKidsId = [] + NC[0] = 0 + + # Add information for offline selection + # (mainly signal normalisation and zeroing of particle-wise arrays) + ntr, nref = offline.pushOfflineByEvent(t, vetoScint, sampleType, verbose, threshold) + for recoP in recoParts: + offline.pushOfflineByParticle(t, recoP, ntr, nref) + + # Loop on MCTracks + for ip2 in xrange(0,len(particles)): + part2 = particles[ip2] + # exit if we have reached the empty part of the array + if not (type(part2)==type(ShipMCTrack())): + break + if part2.GetMotherId()==ip: + interacted = True + part2Id = part2.GetPdgCode() + partKidsId.append(part2Id) + # Was this a neutral current interaction? + if not (pdg.GetParticle(part2.GetPdgCode()) == None) and ("nu" in pdg.GetParticle(part2.GetPdgCode()).GetName()) and (part2.GetMotherId()==0): + NC[0] = 1 + nPart_fromNu[0]+=1 + idPart_fromNu.push_back(part2Id) + if pdg.GetParticle(part2.GetPdgCode()) == None: + part2Name = str(part2Id) + else: + part2Name = getPartName(part2Id) + #idStrPart_fromNu.push_back(part2Name) + # Counting how many particles produced by the nu-interaction are charged or neutral + if (pdg.GetParticle(part2.GetPdgCode())) == None or (int(fabs(pdg.GetParticle(part2Id).Charge()))==int(0)): + nNeutrPart_fromNu[0]+=1 + idNeutrPart_fromNu.push_back(part2Id) + #idStrNeutrPart_fromNu.push_back(part2Name) + else: + nChargedPart_fromNu[0]+=1 + idChargedPart_fromNu.push_back(part2Id) + #idStrChargedPart_fromNu.push_back(part2Name) + # How many are produced by the interaction in the last passive element of the "opera-mu system"? + # Finding out the "interaction element code" + part2Z = part2.GetStartZ() + part2X = part2.GetStartX() + part2Y = part2.GetStartY() + somewhere = False + nodeName = fGeo.FindNode(part2X,part2Y,part2Z).GetName() + if nodeName in lastPassive_nodeName: + somewhere = True + interactionElement[0] = 0 + intElName = 'OPERA' + # To know if it was in the full OPERA-system (excluded last passive) + if tmpName in OPERA_nodeName and somewhere==False: + somewhere = True + interactionElement[0] = 3 + intElName = 'OPERA' + # To know if it was between the two windows + if tmpName in entrance_nodeName: + assert(somewhere==False) + somewhere = True + interactionElement[0] = 1 + # Vacuum tank outer window + if tmpName in volumeIn_nodeName and somewhere==False: + interactionElement[0] = 5 + somewhere = True + # Vacuum tank inner window + elif nodeName in volumeOut_nodeName and somewhere==False: + interactionElement[0] = 6 + somewhere = True + # Vacuum tank ribs + if "Rib" in tmpName: + interactionElement[0] = 7 + # Somewhere else + if somewhere==False: + interactionElement[0] = -1 + # End loop on MCTracks + # Should be changed to avoid entering in the loop if there isn't anything in the tracking + if skipEvent: + continue + strawVetoAny[0],strawVetoAny_eff[0],dummy,dummy,strawVetoAny_Ethr[0],dummy = wasFired(None, strawPoints, strawVetoPos,None,None, checkOn=False, pointVects=None)#[strawVetoPoint_x, strawVetoPoint_y, strawVetoPoint_z]) + upstreamVetoany[0], upstreamVetoany_eff[0], dummy,dummy, upstreamVetoAny_Ethr[0],dummy = wasFired(None, vetoScint, upstreamVetoPos, None, None, checkOn=False, pointVects=None)#[upstreamVetoPoint_x, upstreamVetoPoint_y, upstreamVetoPoint_z]) + RPCany[0], RPCany_eff[0],dummy,dummy, RPCany_Ethr[0],dummy = wasFired(None, rpc, RPCstationsPos, None, None, checkOn=False, pointVects=None)#[rpcPoint_x, rpcPoint_y, rpcPoint_z]) + scintVetoAny[0], scintVetoAny_eff[0], dummy,dummy, scintVetoAny_Ethr[0],dummy = wasFired(None, vetoScint, vetoWall, None, None, checkOn=False, pointVects=None, Ethr=threshold) + #assert(len(idStrPart_fromNu)==len(idPart_fromNu)) + #assert(len(idStrChargedPart_fromNu)==len(idChargedPart_fromNu)) + #assert(len(idStrNeutrPart_fromNu)==len(idNeutrPart_fromNu)) + #assert(len(idStrPart_fromNu)==nChargedPart_fromNu[0]+nNeutrPart_fromNu[0]) + #assert(len(idStrChargedPart_fromNu)==nChargedPart_fromNu[0]) + #assert(len(idStrNeutrPart_fromNu)==nNeutrPart_fromNu[0]) + if not primaryDone: + print "It looks like there is no primary nu interacting" + PrintEventPart(particles,pdg) + sys.exit() + weight[0] = offline.findWeight(sampleType, NC[0], nuE[0], part, entries, pdgPart.GetName(), ON)#calcWeight(NC[0], nuE[0], part.GetWeight(), entries, pdgPart.GetName(), ON) + nt.Fill() + # End loop on tree +nt.Write() +nf.Save() +nf.Close() +f.Close() +print "Output wrote to %s"%outputFileName +print "Number of events with vertex outside Veto_5-500 - Tr4_4: %s"%offline.num_bad_z diff --git a/newGen/offlineForBarbara.py b/newGen/offlineForBarbara.py new file mode 100644 index 0000000..9fe706e --- /dev/null +++ b/newGen/offlineForBarbara.py @@ -0,0 +1,652 @@ +from lookAtGeo import * +import tools +import shipunit as u +from ShipGeoConfig import ConfigRegistry +import shipDet_conf + +from operator import mul, add + +import sys +sys.path.append('KaterinaLight/') +from StrawHits import StrawHits +## Use it like: +# f = TFile(fileName) +# t = f.Get("cbmsim") +# sh = offline.StrawHits(t, offline.shipDet_conf.configure(offline.__run, r['ShipGeo']), r['ShipGeo'].straw.resol, 0, None, r['ShipGeo']) +# t.GetEntry(58) +# sh.readEvent() +# sh.FitTracks() + +#dy = 10. +# init geometry and mag. field +#ShipGeo = ConfigRegistry.loadpy("$FAIRSHIP/geometry/geometry_config.py", Yheight = dy ) + + +def searchForNodes3_xyz_dict(fGeo, verbose=False): + from tools import findPositionElement, findDimentionBoxElement, findPositionElement2 + d = {} + #r = loadGeometry(inputFile) + #fGeo = r['fGeo'] + ## Get the top volume + #fGeo = ROOT.gGeoManager + tv = fGeo.GetTopVolume() + topnodes = tv.GetNodes() + for (j,topn) in enumerate(topnodes): + # top volumes + if verbose: + print j, topn.GetName() + print " x: ", findPositionElement(topn)['x'],findDimentionBoxElement(topn)['x'] + print " y: ", findPositionElement(topn)['y'],findDimentionBoxElement(topn)['y'] + print " z: ", findPositionElement(topn)['z'],findDimentionBoxElement(topn)['z'] + d[topn.GetName()] = {'x': {}, 'y':{}, 'z':{}, 'r':{}} + d[topn.GetName()]['x']['pos'] = findPositionElement(topn)['x'] + d[topn.GetName()]['x']['dim'] = findDimentionBoxElement(topn)['x'] + d[topn.GetName()]['y']['pos'] = findPositionElement(topn)['y'] + d[topn.GetName()]['y']['dim'] = findDimentionBoxElement(topn)['y'] + d[topn.GetName()]['z']['pos'] = findPositionElement(topn)['z'] + d[topn.GetName()]['z']['dim'] = findDimentionBoxElement(topn)['z'] + if topn.GetVolume().GetShape().IsCylType(): + d[topn.GetName()]['r']['pos'] = findPositionElement(topn)['r'] + d[topn.GetName()]['r']['dim'] = findDimentionBoxElement(topn)['r'] + else: + d[topn.GetName()]['r']['pos'] = 0. + d[topn.GetName()]['r']['dim'] = 0. + # First children + nodes = topn.GetNodes() + if nodes: + topPos = topn.GetMatrix().GetTranslation() + for (i,n) in enumerate(nodes): + if verbose: + print j, topn.GetName(), i, n.GetName() + print " x: ", findPositionElement2(n,topPos)['x'],findDimentionBoxElement(n)['x'] + print " y: ", findPositionElement2(n,topPos)['y'],findDimentionBoxElement(n)['y'] + print " z: ", findPositionElement2(n,topPos)['z'],findDimentionBoxElement(n)['z'] + d[n.GetName()] = {'x': {}, 'y':{}, 'z':{}, 'r':{}} + d[n.GetName()]['x']['pos'] = findPositionElement2(n,topPos)['x'] + d[n.GetName()]['x']['dim'] = findDimentionBoxElement(n)['x'] + d[n.GetName()]['y']['pos'] = findPositionElement2(n,topPos)['y'] + d[n.GetName()]['y']['dim'] = findDimentionBoxElement(n)['y'] + d[n.GetName()]['z']['pos'] = findPositionElement2(n,topPos)['z'] + d[n.GetName()]['z']['dim'] = findDimentionBoxElement(n)['z'] + if n.GetVolume().GetShape().IsCylType(): + d[n.GetName()]['r']['pos'] = findPositionElement2(n,topPos)['r'] + d[n.GetName()]['r']['dim'] = findDimentionBoxElement(n)['r'] + else: + d[n.GetName()]['r']['pos'] = 0. + d[n.GetName()]['r']['dim'] = 0. + # Second children + cnodes = n.GetNodes() + if cnodes: + localpos = n.GetMatrix().GetTranslation() + localToGlobal = [] + for i in xrange(3): + localToGlobal.append(localpos[i]+topPos[i]) + for (k,cn) in enumerate(cnodes): + if verbose: + print j, topn.GetName(), i, n.GetName(), k, cn.GetName() + print " x: ", findPositionElement2(cn,localToGlobal)['x'],findDimentionBoxElement(cn)['x'] + print " y: ", findPositionElement2(cn,localToGlobal)['y'],findDimentionBoxElement(cn)['y'] + print " z: ", findPositionElement2(cn,localToGlobal)['z'],findDimentionBoxElement(cn)['z'] + d[cn.GetName()] = {'x': {}, 'y':{}, 'z':{}, 'r':{}} + d[cn.GetName()]['x']['pos'] = findPositionElement2(cn,localToGlobal)['x'] + d[cn.GetName()]['x']['dim'] = findDimentionBoxElement(cn)['x'] + d[cn.GetName()]['y']['pos'] = findPositionElement2(cn,localToGlobal)['y'] + d[cn.GetName()]['y']['dim'] = findDimentionBoxElement(cn)['y'] + d[cn.GetName()]['z']['pos'] = findPositionElement2(cn,localToGlobal)['z'] + d[cn.GetName()]['z']['dim'] = findDimentionBoxElement(cn)['z'] + if cn.GetVolume().GetShape().IsCylType(): + d[cn.GetName()]['r']['pos'] = findPositionElement2(cn,localToGlobal)['r'] + d[cn.GetName()]['r']['dim'] = findDimentionBoxElement(cn)['r'] + else: + d[cn.GetName()]['r']['pos'] = 0. + d[cn.GetName()]['r']['dim'] = 0. + return d + + +ff_nu = ROOT.TFile("histoForWeights_nu.root") +h_GioHans_nu = ff_nu.Get("h_Gio") + +ff_antinu = ROOT.TFile("histoForWeights_antinu.root") +h_GioHans_antinu = ff_antinu.Get("h_Gio") + +def calcWeightNu(NC, E, w, entries, nuName, ON=True): + # Only for neutrinos and antineutrinos + if not ON: + return 1 + if "bar" in nuName: + reduction = 0.5 + flux = 1.#6.98e+11 * 2.e+20 / 5.e+13 + h_GioHans = h_GioHans_antinu + else: + reduction = 1. + flux = 1.#1.09e+12 * 2.e+20/ 5.e+13 + h_GioHans = h_GioHans_nu + + crossSec = 6.7e-39*E * reduction + NA = 6.022e+23 + binN = h_GioHans.GetXaxis().FindBin(E) + return crossSec * flux * h_GioHans.GetBinContent(binN) * w * NA #/ entries + + +def findWeight(sampleType, NC, E, MCTrack, entries, nuName, ON): + if sampleType == 'nuBg': + return calcWeightNu(NC, E, MCTrack.GetWeight(), entries, nuName, ON) + elif sampleType == 'sig': + return MCTrack.GetWeight() # for the acceptance, multiply by normalization + elif sampleType == 'cosmics': + return MCTrack.GetWeight() # multiply by 1.e6 / 200. + + + +def hasStrawStations(event, trackId, listOfWantedStraws): + ok = [False]*len(listOfWantedStraws) + positions = [ (nodes[det]['z']['pos'] - nodes[det]['z']['dim'], nodes[det]['z']['pos'] + nodes[det]['z']['dim'] ) for det in listOfWantedStraws ] + for hit in event.strawtubesPoint: + if hit.GetTrackID() == trackId: + for (i,det) in enumerate(listOfWantedStraws): + if (positions[i][0] < hit.GetZ() < positions[i][1]) and tools.inEllipse(hit.GetX(), hit.GetY(), 250., 500.): + ok[i] = True + return bool(reduce(mul, ok, 1)) + +def hasGoodStrawStations(event, trackId): + #ok = [False]*2 + okupstream = [False]*2 + okdownstream = [False]*2 + upstream = [ (nodes[det]['z']['pos'] - nodes[det]['z']['dim'], nodes[det]['z']['pos'] + nodes[det]['z']['dim'] ) for det in ['Tr1_1', 'Tr2_2'] ] + downstream = [ (nodes[det]['z']['pos'] - nodes[det]['z']['dim'], nodes[det]['z']['pos'] + nodes[det]['z']['dim'] ) for det in ['Tr3_3', 'Tr4_4'] ] + for hit in event.strawtubesPoint: + if hit.GetTrackID() == trackId: + for i in xrange(2): + if (upstream[i][0] < hit.GetZ() < upstream[i][1]) and tools.inEllipse(hit.GetX(), hit.GetY(), 250., 500.): + okupstream[i] = True + if (downstream[i][0] < hit.GetZ() < downstream[i][1]) and tools.inEllipse(hit.GetX(), hit.GetY(), 250., 500.): + okdownstream[i] = True + ok = [ bool(reduce(mul, l, 1)) for l in [okupstream, okdownstream] ] + return bool(reduce(add, ok, 0)) + +def findHNLvertex(event): + for t in event.MCTrack: + if t.GetMotherId() == 1: + return t.GetStartZ() + return False + +def has_muon_station(event, trackId, station): + zIn = nodes['muondet%s_1'%(station-1)]['z']['pos'] - nodes['muondet%s_1'%(station-1)]['z']['dim'] + zOut = nodes['muondet%s_1'%(station-1)]['z']['pos'] + nodes['muondet%s_1'%(station-1)]['z']['dim'] + for hit in event.muonPoint: + if hit.GetTrackID() == trackId: + if zIn <= hit.GetZ() <= zOut: + return True + return False + +def hasEcalDeposit(event, trackId, ELossThreshold): + ELoss = 0. + for hit in event.EcalPoint: + if hit.GetTrackID() == trackId: + ELoss += hit.GetEnergyLoss() + if ELoss >= ELossThreshold: + return True + return False + +def hasMuons(event, trackId): + m1 = 0 + m2 = 0 + m3 = 0 + m4 = 0 + for ahit in event.muonPoint: + if ahit.GetTrackID() == trackId: + detID = ahit.GetDetectorID() + if(detID == 476) : + m1 += 1 + if(detID == 477) : + m2 += 1 + if(detID == 478) : + m3 += 1 + if(detID == 479) : + m4 += 1 + return [bool(m1), bool(m2), bool(m3), bool(m4)] + +def myVertex(t1,t2,PosDir): + # closest distance between two tracks + # d = |pq . u x v|/|u x v| + a = ROOT.TVector3(PosDir[t1][0](0) ,PosDir[t1][0](1), PosDir[t1][0](2)) + u = ROOT.TVector3(PosDir[t1][1](0),PosDir[t1][1](1),PosDir[t1][1](2)) + c = ROOT.TVector3(PosDir[t2][0](0) ,PosDir[t2][0](1), PosDir[t2][0](2)) + v = ROOT.TVector3(PosDir[t2][1](0),PosDir[t2][1](1),PosDir[t2][1](2)) + pq = a-c + uCrossv = u.Cross(v) + dist = pq.Dot(uCrossv)/(uCrossv.Mag()+1E-8) + # u.a - u.c + s*|u|**2 - u.v*t = 0 + # v.a - v.c + s*v.u - t*|v|**2 = 0 + E = u.Dot(a) - u.Dot(c) + F = v.Dot(a) - v.Dot(c) + A,B = u.Mag2(), -u.Dot(v) + C,D = u.Dot(v), -v.Mag2() + t = -(C*E-A*F)/(B*C-A*D) + X = c.x()+v.x()*t + Y = c.y()+v.y()*t + Z = c.z()+v.z()*t + # sT = ROOT.gROOT.FindAnything('cbmsim') + #print 'test2 ',X,Y,Z,dist + #print 'truth',sTree.MCTrack[2].GetStartX(),sTree.MCTrack[2].GetStartY(),sTree.MCTrack[2].GetStartZ() + return X,Y,Z,abs(dist) + +def addFullInfoToTree(elenaTree): + elenaTree, DaughtersPt = tools.AddVect(elenaTree, 'DaughtersPt', 'float') + elenaTree, DaughtersChi2 = tools.AddVect(elenaTree, 'DaughtersChi2', 'float') + elenaTree, DaughtersNPoints = tools.AddVect(elenaTree, 'DaughtersNPoints', 'int') + elenaTree, DaughtersTruthProdX = tools.AddVect(elenaTree, 'DaughtersTruthProdX', 'float') + elenaTree, DaughtersTruthProdY = tools.AddVect(elenaTree, 'DaughtersTruthProdY', 'float') + elenaTree, DaughtersTruthProdZ = tools.AddVect(elenaTree, 'DaughtersTruthProdZ', 'float') + elenaTree, DaughtersTruthPDG = tools.AddVect(elenaTree, 'DaughtersTruthPDG', 'int') + elenaTree, DaughtersTruthMotherPDG = tools.AddVect(elenaTree, 'DaughtersTruthMotherPDG', 'int') + elenaTree, DaughtersFitConverged = tools.AddVect(elenaTree, 'DaughtersFitConverged', 'int') + elenaTree, straw_x = tools.AddVect(elenaTree, 'straw_x', 'float') + elenaTree, straw_y = tools.AddVect(elenaTree, 'straw_y', 'float') + elenaTree, straw_z = tools.AddVect(elenaTree, 'straw_z', 'float') + elenaTree, muon_x = tools.AddVect(elenaTree, 'muon_x', 'float') + elenaTree, muon_y = tools.AddVect(elenaTree, 'muon_y', 'float') + elenaTree, muon_z = tools.AddVect(elenaTree, 'muon_z', 'float') + elenaTree, ecal_x = tools.AddVect(elenaTree, 'ecal_x', 'float') + elenaTree, ecal_y = tools.AddVect(elenaTree, 'ecal_y', 'float') + elenaTree, ecal_z = tools.AddVect(elenaTree, 'ecal_z', 'float') + elenaTree, hcal_x = tools.AddVect(elenaTree, 'hcal_x', 'float') + elenaTree, hcal_y = tools.AddVect(elenaTree, 'hcal_y', 'float') + elenaTree, hcal_z = tools.AddVect(elenaTree, 'hcal_z', 'float') + elenaTree, veto5_x = tools.AddVect(elenaTree, 'veto5_x', 'float') + elenaTree, veto5_y = tools.AddVect(elenaTree, 'veto5_y', 'float') + elenaTree, veto5_z = tools.AddVect(elenaTree, 'veto5_z', 'float') + elenaTree, liquidscint_x = tools.AddVect(elenaTree, 'liquidscint_x', 'float') + elenaTree, liquidscint_y = tools.AddVect(elenaTree, 'liquidscint_y', 'float') + elenaTree, liquidscint_z = tools.AddVect(elenaTree, 'liquidscint_z', 'float') + elenaTree, DOCA = tools.AddVar(elenaTree, 'DOCA', 'float') + elenaTree, vtxx = tools.AddVar(elenaTree, 'vtxx', 'float') + elenaTree, vtxy = tools.AddVar(elenaTree, 'vtxy', 'float') + elenaTree, vtxz = tools.AddVar(elenaTree, 'vtxz', 'float') + elenaTree, IP0 = tools.AddVar(elenaTree, 'IP0', 'float') + elenaTree, Mass = tools.AddVar(elenaTree, 'Mass', 'float') + elenaTree, Pt = tools.AddVar(elenaTree, 'Pt', 'float') + elenaTree, P = tools.AddVar(elenaTree, 'P', 'float') + elenaTree, NParticles = tools.AddVar(elenaTree, 'NParticles', 'int') + elenaTree, HNLw = tools.AddVar(elenaTree, 'HNLw', 'float') + elenaTree, NuWeight = tools.AddVar(elenaTree, 'NuWeight', 'float') + elenaTree, EventNumber = tools.AddVar(elenaTree, 'EventNumber', 'int') + elenaTree, DaughterMinPt = tools.AddVar(elenaTree, 'DaughterMinPt', 'float') + elenaTree, DaughterMinP = tools.AddVar(elenaTree, 'DaughterMinP', 'float') + elenaTree, DaughtersAlwaysIn = tools.AddVar(elenaTree, 'DaughtersAlwaysIn', 'int') + elenaTree, BadTruthVtx = tools.AddVar(elenaTree, 'BadTruthVtx', 'int') + +DaughtersFitConverged, DOCA, vtxx, vtxy, vtxz, IP0, HasEcal = None, None, None, None, None, None, None +NoB_DOCA, NoB_vtxx, NoB_vtxy, NoB_vtxz, NoB_IP0 = None, None, None, None, None +DaughtersAlwaysIn, BadTruthVtx, Has1Muon1, Has1Muon2, Has2Muon1, Has2Muon2 = None, None, None, None, None, None +MaxDaughtersRedChi2, MinDaughtersNdf = None, None +NoB_MaxDaughtersRedChi2, NoB_MinDaughtersNdf = None, None +DaughtersMinP, DaughtersMinPt, Mass, P, Pt = None, None, None, None, None +NoB_DaughtersMinP, NoB_DaughtersMinPt, NoB_Mass, NoB_P, NoB_Pt = None, None, None, None, None + +def addOfflineToTree(elenaTree): + global DaughtersFitConverged, DOCA, vtxx, vtxy, vtxz, IP0, HasEcal + global NoB_DOCA, NoB_vtxx, NoB_vtxy, NoB_vtxz, NoB_IP0 + global DaughtersAlwaysIn, BadTruthVtx, Has1Muon1, Has1Muon2, Has2Muon1, Has2Muon2 + global MaxDaughtersRedChi2, MinDaughtersNdf, HNLw, NuWeight, NoB_MaxDaughtersRedChi2, NoB_MinDaughtersNdf + global DaughtersMinP, DaughtersMinPt, Mass, P, Pt + global NoB_DaughtersMinP, NoB_DaughtersMinPt, NoB_Mass, NoB_P, NoB_Pt + elenaTree, DaughtersFitConverged = tools.AddVect(elenaTree, 'DaughtersFitConverged', 'int') # + elenaTree, DOCA = tools.AddVect(elenaTree, 'DOCA', 'float') # + elenaTree, NoB_DOCA = tools.AddVect(elenaTree, 'NoB_DOCA', 'float') # + elenaTree, vtxx = tools.AddVect(elenaTree, 'vtxxSqr', 'float') # + elenaTree, vtxy = tools.AddVect(elenaTree, 'vtxySqr', 'float') # + elenaTree, vtxz = tools.AddVect(elenaTree, 'vtxz', 'float') # + elenaTree, NoB_vtxx = tools.AddVect(elenaTree, 'NoB_vtxxSqr', 'float') # + elenaTree, NoB_vtxy = tools.AddVect(elenaTree, 'NoB_vtxySqr', 'float') # + elenaTree, NoB_vtxz = tools.AddVect(elenaTree, 'NoB_vtxz', 'float') # + elenaTree, IP0 = tools.AddVect(elenaTree, 'IP0', 'float') # + elenaTree, NoB_IP0 = tools.AddVect(elenaTree, 'NoB_IP0', 'float') # + #elenaTree, NParticles = tools.AddVar(elenaTree, 'NParticles', 'int') # + elenaTree, DaughtersAlwaysIn = tools.AddVect(elenaTree, 'DaughtersAlwaysIn', 'int') # + elenaTree, BadTruthVtx = tools.AddVect(elenaTree, 'BadTruthVtx', 'int') # + elenaTree, Has1Muon1 = tools.AddVect(elenaTree, 'Has1Muon1', 'int') # + elenaTree, Has1Muon2 = tools.AddVect(elenaTree, 'Has1Muon2', 'int') # + elenaTree, Has2Muon1 = tools.AddVect(elenaTree, 'Has2Muon1', 'int') # + elenaTree, Has2Muon2 = tools.AddVect(elenaTree, 'Has2Muon2', 'int') # + elenaTree, HasEcal = tools.AddVect(elenaTree, 'HasEcal', 'int') # + elenaTree, MaxDaughtersRedChi2 = tools.AddVect(elenaTree, 'MaxDaughtersRedChi2', 'float') # + elenaTree, MinDaughtersNdf = tools.AddVect(elenaTree, 'MinDaughtersNdf', 'int') # + elenaTree, NoB_MaxDaughtersRedChi2 = tools.AddVect(elenaTree, 'NoB_MaxDaughtersRedChi2', 'float') # + elenaTree, NoB_MinDaughtersNdf = tools.AddVect(elenaTree, 'NoB_MinDaughtersNdf', 'int') # + elenaTree, DaughtersMinP = tools.AddVect(elenaTree, 'DaughtersMinP', 'float') + elenaTree, DaughtersMinPt = tools.AddVect(elenaTree, 'DaughtersMinPt', 'float') + elenaTree, P = tools.AddVect(elenaTree, 'P', 'float') + elenaTree, Pt = tools.AddVect(elenaTree, 'Pt', 'float') + elenaTree, Mass = tools.AddVect(elenaTree, 'Mass', 'float') + elenaTree, NoB_DaughtersMinP = tools.AddVect(elenaTree, 'NoB_DaughtersMinP', 'float') + elenaTree, NoB_DaughtersMinPt = tools.AddVect(elenaTree, 'NoB_DaughtersMinPt', 'float') + elenaTree, NoB_P = tools.AddVect(elenaTree, 'NoB_P', 'float') + elenaTree, NoB_Pt = tools.AddVect(elenaTree, 'NoB_Pt', 'float') + elenaTree, NoB_Mass = tools.AddVect(elenaTree, 'NoB_Mass', 'float') + # Add liquid scintillator segmentation + tools.makeLSsegments(nodes, elenaTree) + +nodes = None +def loadNodes(fGeo): + global nodes + nodes = searchForNodes3_xyz_dict(fGeo) + +num_bad_z = 0 + +def signalNormalisationZ(tree, datatype, verbose): + # By event + # Uses MC truth!! + global BadTruthVtx, num_bad_z + tools.PutToZero(BadTruthVtx) + z_hnl_vtx = findHNLvertex(tree) + bad_z = False + if not z_hnl_vtx: + if "sig" in datatype: + print 'ERROR: hnl vertex not found!' + ii = 0 + for g in tree.MCTrack: + ii +=1 + if ("sig" in datatype) and ii < 3: + pass + elif ("sig" in datatype) and ii >= 3: + sys.exit() + if not (nodes['Veto_5']['z']['pos']-nodes['Veto_5']['z']['dim']-500. < z_hnl_vtx < nodes['Tr4_4']['z']['pos']+nodes['Tr4_4']['z']['dim']): + bad_z = True + num_bad_z += 1 + if "sig" in datatype: + print z_hnl_vtx + tools.Push(BadTruthVtx, int(bad_z)) + +def nParticles(tree): + # By event + global NParticles + np = 0 + for HNL in tree.Particles: + np += 1 + tools.PutToZero(NParticles); tools.Push(NParticles, np) + +def hasEcalAndMuons(tree, particle): + # By particle + global Has1Muon1, Has1Muon2, Has2Muon1 + global Has2Muon2, HasEcal + flag2Muon1 = False + flag2Muon2 = False + flag1Muon1 = False + flag1Muon2 = False + flagEcal = False + t1,t2 = tree.fitTrack2MC[particle.GetDaughter(0)], tree.fitTrack2MC[particle.GetDaughter(1)] + # AND or OR? + if ( has_muon_station(tree, t1, 1) and has_muon_station(tree, t2, 1) ): + flag2Muon1 = True + if ( has_muon_station(tree, t1, 2) and has_muon_station(tree, t2, 2) ): + flag2Muon2 = True + if ( has_muon_station(tree, t1, 1) or has_muon_station(tree, t2, 1) ): + flag1Muon1 = True + if ( has_muon_station(tree, t1, 2) or has_muon_station(tree, t2, 2) ): + flag1Muon2 = True + # This also work, but may be slower + #muons1 = hasMuons(tree, t1) + #muons2 = hasMuons(tree, t2) + #if muons1[0] or muons2[0]: flag1Muon1 = True + #if muons1[1] or muons2[1]: flag1Muon2 = True + #if muons1[0] and muons2[0]: flag2Muon1 = True + #if muons1[1] and muons2[1]: flag2Muon2 = True + if ( hasEcalDeposit(tree, t1, 150.*u.MeV) or hasEcalDeposit(tree, t2, 150.*u.MeV) ): + flagEcal = True + tools.Push(Has2Muon1, int(flag2Muon1)) + tools.Push(Has2Muon2, int(flag2Muon2)) + tools.Push(Has1Muon1, int(flag1Muon1)) + tools.Push(Has1Muon2, int(flag1Muon2)) + tools.Push(HasEcal, int(flagEcal)) + +def chi2Ndf(tree, particle, ntr, nref): + # By particle + global MaxDaughtersRedChi2, MinDaughtersNdf + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + if ntr>1 and nref==2:#nf>1 + t1r,t2r = sh.getReFitTrIDs()[0], sh.getReFitTrIDs()[1] + chi2red_1 = sh.getReFitChi2Ndf(t1r) + ndf_1 = int(round(sh.getReFitNdf(t1r))) + chi2red_2 = sh.getReFitChi2Ndf(t2r) + ndf_2 = int(round(sh.getReFitNdf(t2r))) + reducedChi2 = [chi2red_1, chi2red_2] + ndfs = [ndf_1, ndf_2] + # if the refit didn't work + if (ntr<2) or (nref!=2) or (not ndf_1) or (not ndf_2) or (not chi2red_1) or (not chi2red_2): + reducedChi2 = [] + ndfs = [] + for tr in [t1,t2]: + x = tree.FitTracks[tr] + ndfs.append( int(round(x.getFitStatus().getNdf())) ) + reducedChi2.append( x.getFitStatus().getChi2()/x.getFitStatus().getNdf() ) + tools.Push(MaxDaughtersRedChi2, max(reducedChi2)) + tools.Push(MinDaughtersNdf, min(ndfs)) + + +def NoB_chi2Ndf(tree, particle): + # By particle + global NoB_MaxDaughtersRedChi2, NoB_MinDaughtersNdf, DaughtersFitConverged + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + reducedChi2 = [] + ndfs = [] + converged = [] + for tr in [t1,t2]: + x = tree.FitTracks[tr] + ndfs.append( int(round(x.getFitStatus().getNdf())) ) + reducedChi2.append( x.getFitStatus().getChi2()/x.getFitStatus().getNdf() ) + converged.append( x.getFitStatus().isFitConverged() ) + tools.Push(NoB_MaxDaughtersRedChi2, max(reducedChi2)) + tools.Push(NoB_MinDaughtersNdf, min(ndfs)) + tools.Push( DaughtersFitConverged, int(converged[0]*converged[1]) ) + +def NoB_kinematics(tree, particle): + global NoB_DaughtersMinP, NoB_DaughtersMinPt, NoB_P, NoB_Pt, NoB_Mass + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + dp, dpt = [], [] + for tr in [t1, t2]: + x = tree.FitTracks[tr] + xx = x.getFittedState() + dp.append(xx.getMom().Mag()); dpt.append(xx.getMom().Pt()) + tools.Push(NoB_DaughtersMinP, min(dp)) + tools.Push(NoB_DaughtersMinPt, min(dpt)) + HNLMom = ROOT.TLorentzVector() + particle.Momentum(HNLMom) + tools.Push(NoB_Mass, HNLMom.M()) + tools.Push(NoB_Pt, HNLMom.Pt()) + tools.Push(NoB_P, HNLMom.P()) + +def goodBehavedTracks(tree, particle): + # By particle + # Uses MC truth!! + global DaughtersAlwaysIn + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + accFlag = True + for tr in [t1,t2]: + mctrid = tree.fitTrack2MC[tr] + if not hasGoodStrawStations(tree, mctrid): + accFlag = False + tools.Push(DaughtersAlwaysIn, int(accFlag)) + +def NoB_vertexInfo(tree, particle): + # By particle + global NoB_vtxx, NoB_vtxy, NoB_vtxz + global NoB_IP0, NoB_DOCA + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + PosDir = {} + for tr in [t1,t2]: + xx = tree.FitTracks[tr].getFittedState() + PosDir[tr] = [xx.getPos(),xx.getDir()] + xv,yv,zv,doca = myVertex(t1,t2,PosDir) + tools.Push(NoB_DOCA, doca) + #tools.Push(NoB_vtxx, xv); tools.Push(NoB_vtxy, yv); tools.Push(NoB_vtxz, zv) + tools.Push(NoB_vtxx, xv*xv); tools.Push(NoB_vtxy, yv*yv); tools.Push(NoB_vtxz, zv) + # impact parameter to target + HNLPos = ROOT.TLorentzVector() + particle.ProductionVertex(HNLPos) + HNLMom = ROOT.TLorentzVector() + particle.Momentum(HNLMom) + tr = ROOT.TVector3(0,0,ShipGeo.target.z0) + t = 0 + for i in range(3): t += HNLMom(i)/HNLMom.P()*(tr(i)-HNLPos(i)) + ip = 0 + for i in range(3): ip += (tr(i)-HNLPos(i)-t*HNLMom(i)/HNLMom.P())**2 + ip = ROOT.TMath.Sqrt(ip) + tools.Push(NoB_IP0, ip) + + +def kinematics(tree, particle, ntr, nref): + global DaughtersMinP, DaughtersMinPt, P, Pt, Mass + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + dminpt, dminp = 0., 0. + + if ntr>1 and nref==2: + t1r,t2r = sh.getReFitTrIDs()[0], sh.getReFitTrIDs()[1] + Pos1, Dir1, Mom1= sh.getReFitPosDirPval(t1r) + Pos2, Dir2, Mom2= sh.getReFitPosDirPval(t2r) + mass1 = pdg.GetParticle(tree.FitTracks[t1].getFittedState().getPDG()).Mass() + mass2 = pdg.GetParticle(tree.FitTracks[t2].getFittedState().getPDG()).Mass() + LV1 = ROOT.TLorentzVector(Mom1*Dir1, ROOT.TMath.Sqrt( mass1*mass1 + Mom1*Mom1 )) + LV2 = ROOT.TLorentzVector(Mom2*Dir2, ROOT.TMath.Sqrt( mass2*mass2 + Mom2*Mom2 )) + HNLMom = LV1+LV2 + if LV1 and LV2: + dminpt = min([LV1.Pt(), LV2.Pt()]) + dminp = min([LV1.P(), LV2.P()]) + + if (ntr<2) or (nref!=2) or (not dminp) or (not dminpt) or (not HNLMom): + dp, dpt = [], [] + for tr in [t1, t2]: + x = tree.FitTracks[tr] + xx = x.getFittedState() + dp.append(xx.getMom().Mag()); dpt.append(xx.getMom().Pt()) + dminpt = min(dpt) + dminp = min(dp) + HNLMom = ROOT.TLorentzVector() + particle.Momentum(HNLMom) + tools.Push(DaughtersMinP, dminp) + tools.Push(DaughtersMinPt, dminpt) + tools.Push(Mass, HNLMom.M()) + tools.Push(Pt, HNLMom.Pt()) + tools.Push(P, HNLMom.P()) + +def vertexInfo(tree, particle, ntr, nref): + # By particle + global vtxx, vtxy, vtxz + global IP0, DOCA + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + + if ntr>1 and nref==2:#nf>1 + assert( len(sh.getReFitTrIDs())==2 ) + t1r,t2r = sh.getReFitTrIDs()[0], sh.getReFitTrIDs()[1] + #print tree.fitTrack2MC[t1], t1r, tree.fitTrack2MC[t2], t2r + #print ntr, nref, len(sh._StrawHits__docaEval) + doca = sh.getDoca()#sh._StrawHits__docaEval[-1]#getDoca() + v = sh.getReFitVertex() + if v and doca: + xv = v.X(); yv = v.Y(); zv = v.Z() + Pos1, Dir1, Mom1= sh.getReFitPosDirPval(t1r) + Pos2, Dir2, Mom2= sh.getReFitPosDirPval(t2r) + mass1 = pdg.GetParticle(tree.FitTracks[t1].getFittedState().getPDG()).Mass() + mass2 = pdg.GetParticle(tree.FitTracks[t2].getFittedState().getPDG()).Mass() + LV1 = ROOT.TLorentzVector(Mom1*Dir1, ROOT.TMath.Sqrt( mass1*mass1 + Mom1*Mom1 )) + LV2 = ROOT.TLorentzVector(Mom2*Dir2, ROOT.TMath.Sqrt( mass2*mass2 + Mom2*Mom2 )) + HNLMom = LV1+LV2 + + # If something went wrong, take the standard values + if (ntr<2) or (nref!=2) or (not v) or (not doca) or (not HNLMom):#(nf<2) + PosDir = {} + for tr in [t1,t2]: + xx = tree.FitTracks[tr].getFittedState() + PosDir[tr] = [xx.getPos(),xx.getDir()] + xv,yv,zv,doca = myVertex(t1,t2,PosDir) + HNLMom = ROOT.TLorentzVector() + particle.Momentum(HNLMom) + + tools.Push(DOCA, doca) + #tools.Push(vtxx, xv); tools.Push(vtxy, yv); tools.Push(vtxz, zv) + tools.Push(vtxx, xv*xv); tools.Push(vtxy, yv*yv); tools.Push(vtxz, zv) + + # impact parameter to target + #HNLPos = ROOT.TLorentzVector() + #particle.ProductionVertex(HNLPos) + HNLPos = ROOT.TVector3(xv, yv, zv) + tr = ROOT.TVector3(0,0,ShipGeo.target.z0) + t = 0 + for i in range(3): t += HNLMom(i)/HNLMom.P()*(tr(i)-HNLPos(i)) + ip = 0 + for i in range(3): ip += (tr(i)-HNLPos(i)-t*HNLMom(i)/HNLMom.P())**2 + ip = ROOT.TMath.Sqrt(ip) + tools.Push(IP0, ip) + + +def prepareFillingsByParticle(): + # By event + global DaughtersAlwaysIn, DaughtersFitConverged, MinDaughtersNdf, MaxDaughtersRedChi2 + global NoB_MinDaughtersNdf, NoB_MaxDaughtersRedChi2 + global Has1Muon1, Has1Muon2, Has2Muon1, Has2Muon2, HasEcal + global vtxx, vtxy, vtxz, IP0, DOCA + global NoB_vtxx, NoB_vtxy, NoB_vtxz, NoB_IP0, NoB_DOCA + global DaughtersMinP, DaughtersMinPt, Mass, P, Pt + global NoB_DaughtersMinP, NoB_DaughtersMinPt, NoB_Mass, NoB_P, NoB_Pt + tools.PutToZero(DaughtersAlwaysIn) + tools.PutToZero(Has2Muon1); tools.PutToZero(Has2Muon2); tools.PutToZero(HasEcal) + tools.PutToZero(Has1Muon1); tools.PutToZero(Has1Muon2) + tools.PutToZero(DOCA) + tools.PutToZero(vtxx); tools.PutToZero(vtxy); tools.PutToZero(vtxz) + tools.PutToZero(IP0) + tools.PutToZero(NoB_DOCA) + tools.PutToZero(NoB_vtxx); tools.PutToZero(NoB_vtxy); tools.PutToZero(NoB_vtxz) + tools.PutToZero(NoB_IP0) + tools.PutToZero(MinDaughtersNdf); tools.PutToZero(MaxDaughtersRedChi2) + tools.PutToZero(NoB_MinDaughtersNdf); tools.PutToZero(NoB_MaxDaughtersRedChi2) + tools.PutToZero(DaughtersFitConverged) + tools.PutToZero(DaughtersMinP); tools.PutToZero(DaughtersMinPt) + tools.PutToZero(P); tools.PutToZero(Pt); tools.PutToZero(Mass) + tools.PutToZero(NoB_DaughtersMinP); tools.PutToZero(NoB_DaughtersMinPt) + tools.PutToZero(NoB_P); tools.PutToZero(NoB_Pt); tools.PutToZero(NoB_Mass) + ntr = sh.readEvent() + nref = 0 + if ntr>1: + nref = sh.FitTracks() + #print ntr, nref + return ntr, nref + + +def pushOfflineByEvent(tree, vetoPoints, datatype, verbose, threshold): + # True HNL decay vertex (only for signal normalisation) + signalNormalisationZ(tree, datatype, verbose) + ## Number of particles + #nParticles(tree) + # Empties arrays filled by particle + ntr, nref = prepareFillingsByParticle() + # Liquid scintillator segments + global nodes + tools.hitSegments(vetoPoints, nodes, threshold) + return ntr, nref + +def pushOfflineByParticle(tree, particle, ntr, nref): + hasEcalAndMuons(tree, particle) + goodBehavedTracks(tree, particle) + NoB_chi2Ndf(tree, particle) + chi2Ndf(tree, particle, ntr, nref) + NoB_vertexInfo(tree, particle) + vertexInfo(tree, particle, ntr, nref) + NoB_kinematics(tree, particle) + kinematics(tree, particle, ntr, nref) + +fM, tgeom, gMan, geoMat, matEff, modules, run = None, None, None, None, None, None, None + +def initBField(fileNameGeo): + global fM, tgeom, gMan, geoMat, matEff, modules, run, sh + run = ROOT.FairRunSim() + modules = shipDet_conf.configure(run,ShipGeo) + tgeom = ROOT.TGeoManager("Geometry", "Geane geometry") + gMan = tgeom.Import(fileNameGeo) + geoMat = ROOT.genfit.TGeoMaterialInterface() + matEff = ROOT.genfit.MaterialEffects.getInstance() + matEff.init(geoMat) + bfield = ROOT.genfit.BellField(ShipGeo.Bfield.max, ShipGeo.Bfield.z, 2, ShipGeo.Yheight/2.) + fM = ROOT.genfit.FieldManager.getInstance() + fM.init(bfield) + +pdg, sh = None, None diff --git a/newGen/tools.py b/newGen/tools.py new file mode 100755 index 0000000..7de72c0 --- /dev/null +++ b/newGen/tools.py @@ -0,0 +1,363 @@ +#from elena import * +import math +from array import array +from collections import OrderedDict +import ROOT + +def findDimentionBoxElement(node): + sh = node.GetVolume().GetShape() + if sh.IsCylType(): + #print node.GetName(), " is a cylinder", sh.GetRmin(), sh.GetRmax() + if sh.HasRmin(): + r = (sh.GetRmax() - sh.GetRmin()) + else: + r = 0. + return {'x':sh.GetDX(), + 'y':sh.GetDY(), + 'z':sh.GetDZ(), + 'r':r} + return {'x':sh.GetDX(), + 'y':sh.GetDY(), + 'z':sh.GetDZ()} + +def findPositionElement(node): + pos = node.GetMatrix().GetTranslation() + sh = node.GetVolume().GetShape() + if sh.IsCylType(): + if sh.HasRmin(): + r = (sh.GetRmax() - sh.GetRmin())/2. + else: + r = sh.GetRmax() + return {'x':pos[0], + 'y':pos[1], + 'z':pos[2], + 'r':r} + return {'x':pos[0], + 'y':pos[1], + 'z':pos[2]} + +def findPositionElement2(node,topPos): + local_pos = node.GetMatrix().GetTranslation() + pos = [] + for i in xrange(3): + pos.append(local_pos[i]+topPos[i]) + sh = node.GetVolume().GetShape() + if sh.IsCylType(): + if sh.HasRmin(): + r = (sh.GetRmax() - sh.GetRmin())/2. + else: + r = sh.GetRmax() + return {'x':pos[0], + 'y':pos[1], + 'z':pos[2], + 'r':r} + return {'x':pos[0], + 'y':pos[1], + 'z':pos[2]} + +def findDimentionBoxElement2(node,top): + sh = node.GetVolume().GetShape() + if sh.IsCylType(): + #print node.GetName(), " is a cylinder", sh.GetRmin(), sh.GetRmax() + if sh.HasRmin(): + r = (sh.GetRmax() - sh.GetRmin()) + else: + r = 0. + return {'x':sh.GetDX(), + 'y':sh.GetDY(), + 'z':sh.GetDZ(), + 'r':r} + return {'x':sh.GetDX(), + 'y':sh.GetDY(), + 'z':sh.GetDZ()} + +# Custom sorting +def sortNodesBy(nodes, coord='z', what='pos', printdict=True): + d = OrderedDict(sorted(nodes.items(), key = lambda item: item[1][coord][what])) + if printdict: + print + print + print "Nodes by %s %s:"%(coord, what) + for node in d.keys(): + print node, '\t\t', (d[node][coord]['pos']-d[node][coord]['dim'])/100., ' m', '\t', 2*d[node][coord]['dim']/100., ' m' + return d + +def retrieveMCParticleInfo(sTree, key): + mcPartKey = sTree.fitTrack2MC[key] + mcPart = sTree.MCTrack[mcPartKey] + if not mcPart: + print "Error in retrieveMCParticleInfo" + sys.exit() + mother = sTree.MCTrack[mcPart.GetMotherId()] + #print mcPartKey, mcPart, mcPart.GetMotherId(), mother + try: + mumId = mother.GetPdgCode() + except: + mumId = 0 + return int(mcPart.GetPdgCode()), int(mumId), mcPart.GetStartX(), mcPart.GetStartY(), mcPart.GetStartZ() + + +def AddVect(t,name,vectType): + vect = ROOT.vector(vectType)() + t.Branch( name, vect ) + return t, vect + +def AddVar(t,name,varType): + var = array(varType[0],[-999]) + t.Branch(name,var,name+"/"+varType.upper()) + return t, var + +def PutToZero(var): + if not isinstance(var, array): + var.clear() + else: + var[0] = 0 + +def Push(leaf, value): + if not isinstance(leaf, array): + leaf.push_back(value) + else: + leaf[0] = value + + +def wasFired(indexKids, detPoints, detPos, pointsVects=None, Ethr=0): + def lookingForHits(detPoints,flag,nstat,nstat_eff,indexKids,Eloss,Ethr): + for hit in detPoints: + if (indexKids is None) or (hit.GetTrackID() in indexKids): + #print RPChit.GetTrackID(), t_ID + # check if it is in one of the considered active layer + for pos in detPos: + if pos[0]<=hit.GetZ()<=pos[1]: + Eloss += hit.GetEnergyLoss() + #print pos, hit.GetZ() + if pointsVects is not None: + pointsVects[0].push_back(hit.GetX()) + pointsVects[1].push_back(hit.GetY()) + pointsVects[2].push_back(hit.GetZ()) + + flag = True + nstat+=1 + #eff_val = gRandom.Uniform(0.,1.) + #if eff_val<0.9: + # flag_eff = flag_eff or True + # nstat_eff+=1 + #else: + # flag_eff = flag_eff or False + flag_Ethr = Eloss>=Ethr + return flag, nstat, nstat_eff, Eloss, flag_Ethr + # Now in partKidTrackID I should have the trackID connected to my charged particles + #flag_eff = False + flag = False + nstat = 0 + nstat_eff = 0 + Eloss = 0 + flag,nstat,nstat_eff,Eloss,flag_Ethr = lookingForHits(detPoints,flag,nstat,nstat_eff,indexKids,Eloss,Ethr) + #if flag==False and checkOn: + #print "To be study event %s"%entry + #PrintEventPart(particles,pdg) + #PrintRPChits(detPoints,pdg) + #print + #print + #assert(False) + #return flag, flag_eff, nstat, nstat_eff, flag_Ethr + return flag, flag_Ethr + + +#ff = ROOT.TFile("histoForWeights.root","read") +#h_GioHans = ff.Get("h_Gio") + +def calcWeight(E, w, entries, nuName, weightHist): + if "bar" in nuName: + reduction = 0.5 + flux = 6.98e+11 * 2.e+20 / 5.e+13 + else: + reduction = 1. + flux = 1.09e+12 * 2.e+20/ 5.e+13 + crossSec = 6.7e-39*E * reduction + NA = 6.022e+23 + binN = weightHist.GetXaxis().FindBin(E) + return crossSec * flux * weightHist.GetBinContent(binN) * w * NA / entries + + +def calcWeightOldNtuple(x,y,z, E, nodes, entries, weightHist, datatype): + if 'sig' in datatype: + return -999 + params = {'OPERA': {'material':'Fe','lenght':60.,}, + 'window1': {'material':'Fe','lenght':nodes["lidT1O_1"]['z']['dim']}, + 'window2': {'material':'Al','lenght':nodes["lidT1I_1"]['z']['dim']}, + 'volumeOut': {'material':'Fe','lenght':30.,}, + 'volumeIn': {'material':'Al','lenght':8.}} + materialPars = {'Fe':{'A':55.847, #g/mol # fuori + 'rho': 7874 * 1.e+3/1.e+6,#g/cm3 + }, + 'Al':{'A':26.98, #g/mol # dentro + 'rho': 2700 * 1.e+3/1.e+6 #g/cm3 + }} + perc = {'OPERA':0.33, + 'window1':0.015, + 'window2':0.015, + 'volumeOut':0.32, + 'volumeIn':0.32} + intElName = interactionElement(x,y,z, nodes) + #print intElName + NA = 6.022e+23 + material = params[intElName]['material'] + crossSec = 8.8e-39*E #1.5e-38*fabs(E) ##3./2*(1.2+0.35)*1.e-38*fabs(E) + flux = 2.e+18#5.e+16 + L = params[intElName]['lenght'] + rho = materialPars[material]['rho'] + n_element = perc[intElName]*entries + binN = weightHist.GetXaxis().FindBin(E) + weight = crossSec * NA * rho * L * flux / n_element * weightHist.GetBinContent(binN) + return weight + +def interactionElement(x,y,z, nodes): + # window1 + if nodes["lidT1O_1"]['z']['pos']-nodes["lidT1O_1"]['z']['dim'] < z < nodes["lidT1O_1"]['z']['pos']+nodes["lidT1O_1"]['z']['dim']: + return "window1" + # window2 + if nodes["lidT1I_1"]['z']['pos']-nodes["lidT1I_1"]['z']['dim'] < z < nodes["lidT1I_1"]['z']['pos']+nodes["lidT1I_1"]['z']['dim']: + return "window2" + # vacuum tank borders + if nodes["lidT1O_1"]['z']['pos']+nodes["lidT1O_1"]['z']['dim'] < z < nodes["lidT6O_1"]['z']['pos']+nodes["lidT6O_1"]['z']['dim']: # include le lid x la parte fuori ma non x la parte dentro + if inInnerLid(x,y,z, nodes): + return "volumeIn" + else: + return "volumeOut" + # opera + try: + minz, maxz = nodes["volIron_12"]['z']['pos']-nodes["volIron_12"]['z']['dim'], nodes["volIron_24"]['z']['pos']+nodes["volIron_24"]['z']['dim'] + except KeyError: + try: + minz, maxz = nodes["volLayer_11"]['z']['pos']-nodes["volLayer_11"]['z']['dim'], nodes["volLayer_0"]['z']['pos']+nodes["volLayer_0"]['z']['dim'] + except KeyError: + # Pazienza esaurita, ora lo hanno chiamato "volMagneticSpectrometer_1" ed e' lungo piu' di 9m!!! + try: + minz, maxz = nodes["volMagneticSpectrometer_1"]['z']['pos']-nodes["volMagneticSpectrometer_1"]['z']['dim'], nodes["volMagneticSpectrometer_1"]['z']['pos']+nodes["volMagneticSpectrometer_1"]['z']['dim'] + except KeyError: + print "Cannot find OPERA" + sys.exit() + #if nodes["volIron_12"]['z']['pos']-nodes["volIron_12"]['z']['dim'] < z < nodes["volIron_24"]['z']['pos']+nodes["volIron_24"]['z']['dim']: + #if nodes["volLayer_11"]['z']['pos']-nodes["volLayer_11"]['z']['dim'] < z < nodes["volLayer_0"]['z']['pos']+nodes["volLayer_0"]['z']['dim']: + if minz < z < maxz: + return "OPERA" + + +def inInnerLid(x,y,z, nodes): + if nodes["lidT1I_1"]['z']['pos']-nodes["lidT1I_1"]['z']['dim'] < z < nodes["lidT6I_1"]['z']['pos']+nodes["lidT6I_1"]['z']['dim']: + if z < nodes["Veto_5"]['z']['pos']-nodes["Veto_5"]['z']['dim']: + a,b = nodes['T1I_1']['x']['dim'], nodes['T1I_1']['y']['dim'] # smaller part of the tank (first 5 m) + else: + a,b = nodes['T2I_1']['x']['dim'], nodes['T2I_1']['y']['dim'] # larger part of the tank + if inEllipse(x,y,a,b): + return True + return False + + +def inEllipse(x,y,a,b): + if ( (x*x)/(a*a) + (y*y)/(b*b) ) < 1.: + return True + return False + +def pointInEllipse(point,a,b): + x = point.X() + y = point.Y() + return inEllipse(x,y,a,b) + +listOfHitLSSegments = None +numberOfHitLSSegments = None +numberOfHitLSSegments_th15 = None +zstarts = [] +zends = [] +lsNames = [] +Nz, Nphi, nBins = None, None, None +Nphi = 16 +dphi = 2.*math.pi/Nphi +phistart = dphi/2. +zin, zout = None, None +zstepsize = None +# To hold the energy loss +EnergyDeposits = [] +abig = None +asmall = None +b = None + +def makeLSsegments(nodes, tree, savelist=False): + global zstarts, zends, lsNames, Nz, Nphi, nBins, zin, zout, zstepsize + global abig, asmall, b + abig = 250.#nodes['T2LiSc_1_1']['x']['dim'] + asmall = 186.#nodes['T1LiSc_1_1']['x']['dim'] + b = 500.#nodes['T2LiSc_1_1']['y']['dim'] + #print abig, asmall, b + for node in nodes.keys(): + if 'LiSc' in node: + zstarts.append(nodes[node]['z']['pos']-nodes[node]['z']['dim']) + zends.append(nodes[node]['z']['pos']+nodes[node]['z']['dim']) + lsNames.append(node) + # ATTENTION! there is some superposition in z + # To keep it clean & easy, we will do the segmentation + # as Martin first suggested, i.e. by hands!!! + # It cannot be so bad... + zstarts.sort() + zends.sort() + #Nz = len(zstarts) + zin = min(zstarts) + zout =max(zends) + #print 'zstart: ', zin, 'zend: ', zout + zstepsize = 100. + Nz = int(math.ceil((zout-zin)/zstepsize)) + #print Nphi, Nz, nBins + nBins = Nphi*Nz + # Init energy deposit to 0. + for i in xrange(nBins): + EnergyDeposits.append(0.) + global listOfHitLSSegments, numberOfHitLSSegments, EnergyDeposits + global numberOfHitLSSegments_th15 + if savelist: + tree, listOfHitLSSegments = AddVect(tree, 'listOfHitLSSegments', 'int') + tree, numberOfHitLSSegments = AddVar(tree, 'numberOfHitLSSegments', 'int') + tree, numberOfHitLSSegments_th15 = AddVar(tree, 'numberOfHitLSSegments_th15', 'int') + +def hitSegments(vetoPoints, nodes, threshold, savelist=False): + global listOfHitLSSegments, numberOfHitLSSegments, EnergyDeposits + global abig, asmall, b, phistart, dphi, Nphi, nBins, zin, zout + global numberOfHitLSSegments_th15 + # Init energy deposit to 0. + for i in xrange(nBins): + EnergyDeposits[i]=0. + endsmall = nodes['T1Endplate_1']['z']['pos']+nodes['T1Endplate_1']['z']['dim'] + #print 'endsmall: ', endsmall + #print 'nBins: ', nBins, 'len(list): ',len(EnergyDeposits) + for hit in vetoPoints: + z = hit.GetZ() + if (z<(nodes['VetoTimeDet_1']['z']['pos']+nodes['VetoTimeDet_1']['z']['dim']) + or z > zout): + continue + x = hit.GetX() + y = hit.GetY() + a = abig + if z < endsmall: + a = asmall + phi = ROOT.TMath.ATan2(a*y,b*x)+2*math.pi + zbin = ROOT.TMath.FloorNint((z-zin)/zstepsize) + phibin = ROOT.TMath.FloorNint((phi+phistart)/dphi)%Nphi + iBin = zbin*Nphi+phibin + try: + EnergyDeposits[iBin] += hit.GetEnergyLoss() + except: + print 'hitSegments: could not find bin ', iBin + print x, y, z + sys.exit() + nHit = 0 + nHit_th15 = 0 + for iBin in xrange(nBins): + if EnergyDeposits[iBin] > 0.015: + nHit_th15 +=1 + if EnergyDeposits[iBin] > threshold: + nHit +=1 + if savelist: + Push(listOfHitLSSegments, int(iBin)) + Push(numberOfHitLSSegments, nHit) + Push(numberOfHitLSSegments_th15, nHit_th15) + + diff --git a/ntuple_nuVeto_small.py b/ntuple_nuVeto_small.py index 82d86d2..ba14d4e 100644 --- a/ntuple_nuVeto_small.py +++ b/ntuple_nuVeto_small.py @@ -2,33 +2,37 @@ from array import array from ROOT import * -fileName, fileNameGeo, outputFileName, sampleType = None, None, None, None +fileName, fileNameGeo, outputFileName, sampleType, jobID = None, None, None, None, None maxevents = 0 verbose = True # Energy deposit threshold for the liquid scintillator -threshold = 0.015 +threshold = 0.045 # Parse commandline inputs try: - opts, args = getopt.getopt(sys.argv[1:], "n:t:f:o:v:", ['Ethr=']) + opts, args = getopt.getopt(sys.argv[1:], "n:t:f:o:v:j:", ['Ethr=']) except getopt.GetoptError: # print help information and exit: - print '\tUSAGE: -f inputfile.root -o outputfile.root -t sampleType (sig, nuBg or cosmics) -n maxevents -v verbose (0 or 1)' + print '\tUSAGE: -f inputfile.root -o outputfile.root -t sampleType (sig, nuBg or cosmics) -n maxevents -v verbose (0 or 1) -j jobID (0 to ...) ' sys.exit() for o, a in opts: - if o in ("-f"): + if o in ("-f",): fileName = a - if o in ("-o"): + if o in ("-o",): outputFileName = a - if o in ("-n"): + if o in ("-n",): + print "-n",a maxevents = int(a) - if o in ("-t"): + if o in ("-j",): + print "-j",a + jobID = int(a) + if o in ("-t",): sampleType = str(a) - if o in ("-v"): + if o in ("-v",): verbose = bool(int(a)) - if o in ("--Ethr="): + if o in ("--Ethr=",): threshold = float(a) - + fileNameGeo = fileName.replace('ship', 'geofile_full') def namestr(obj, namespace=globals()): @@ -277,6 +281,7 @@ # Open file f = TFile(fileName) t = f.Get("cbmsim") + totentries = t.GetEntries() if verbose: print @@ -299,7 +304,9 @@ import offlineForBarbara as offline offline.loadNodes(fGeo) offline.ShipGeo = r['ShipGeo'] -offline.initBField() +offline.initBField(fileNameGeo) +offline.sh = offline.StrawHits(t, offline.modules, offline.ShipGeo.straw.resol, 0, None, offline.ShipGeo) +offline.pdg = pdg # Handle geometry # Names of useful geometry nodes @@ -431,7 +438,7 @@ if not (entry%1000): print "\tProcessing entry %s of %s..."%(entry,entries) t.GetEntry(entry) - event[0] = entry + event[0] = entry+(jobID*entries) particles = t.MCTrack rpc = t.ShipRpcPoint scint = t.vetoPoint @@ -478,6 +485,7 @@ # If no, skip this event if TrackSyst[0]==0: skipEvent=True + #print "i am jumping this one" continue # exit from loop on particles #break @@ -492,7 +500,7 @@ ## Starting the counter of how many particles were produced by the interaction of this specific nu for recoP in recoParts: nRecoed[0] += 1 - offline.pushOfflineByParticle(t, recoP) + #offline.pushOfflineByParticle(t, recoP) if nRecoed[0]>0: recoed[0]=1 else: @@ -525,9 +533,13 @@ interacted = False partKidsId = [] NC[0] = 0 + # Add information for offline selection # (mainly signal normalisation and zeroing of particle-wise arrays) - offline.pushOfflineByEvent(t, vetoScint, sampleType, verbose, threshold) + ntr, nref = offline.pushOfflineByEvent(t, vetoScint, sampleType, verbose, threshold) + for recoP in recoParts: + offline.pushOfflineByParticle(t, recoP, ntr, nref) + # Loop on MCTracks for ip2 in xrange(0,len(particles)): part2 = particles[ip2] diff --git a/ntuple_nuVeto_small_elena.py b/ntuple_nuVeto_small_elena.py new file mode 100644 index 0000000..423bcb0 --- /dev/null +++ b/ntuple_nuVeto_small_elena.py @@ -0,0 +1,629 @@ +import sys, re, getopt +from array import array +from ROOT import * + +fileName, fileNameGeo, outputFileName, sampleType, jobID = None, None, None, None, None +maxevents = 0 +verbose = True +# Energy deposit threshold for the liquid scintillator +threshold = 0.015 + +# Parse commandline inputs +try: + opts, args = getopt.getopt(sys.argv[1:], "n:t:f:o:v:j:", ['Ethr=']) +except getopt.GetoptError: + # print help information and exit: + print '\tUSAGE: -f inputfile.root -o outputfile.root -t sampleType (sig, nuBg or cosmics) -n maxevents -v verbose (0 or 1) -j jobID (0 to ...) ' + sys.exit() +for o, a in opts: + if o in ("-f",): + fileName = a + if o in ("-o",): + outputFileName = a + if o in ("-n",): + print "-n",a + maxevents = int(a) + if o in ("-j",): + print "-j",a + jobID = int(a) + if o in ("-t",): + sampleType = str(a) + if o in ("-v",): + verbose = bool(int(a)) + if o in ("--Ethr=",): + threshold = float(a) + +fileNameGeo = fileName.replace('ship', 'geofile_full') + +def namestr(obj, namespace=globals()): + return [name for name in namespace if namespace[name] is obj] + +for item in [fileName, fileNameGeo, outputFileName, sampleType]: + if not item: + print '\tFATAL! %s not defined!'%namestr(item)[0] + sys.exit() + +for item in [fileName, fileNameGeo, outputFileName, sampleType, maxevents, verbose, threshold]: + print '\tINFO: %s set to %s'%(namestr(item)[0], item) + +# Load SHiP (LHCb) style +gROOT.ProcessLine(".x mystyle.C") +# Obsolete debug flags +oldGeo = False +ON = True +# Load PDG database +pdg = TDatabasePDG.Instance() +# Add elements to PDG database +import pythia8_conf +pythia8_conf.addHNLtoROOT() +# TODO: MAKE THIS A DICTIONARY AND DE-VERBOSIZE IT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 +if not(pdg.GetParticle(1000010020)): + pdg.AddParticle("Deuteron","Deuteron", 1.875613e+00, kTRUE, 0,3,"Ion",1000010020) + pdg.AddAntiParticle("AntiDeuteron", - 1000010020) +if not(pdg.GetParticle(1000010030)): + pdg.AddParticle("Triton","Triton", 2.808921e+00, kFALSE, 3.885235e+17,3,"Ion",1000010030); + pdg.AddAntiParticle("AntiTriton", - 1000010030); +if not(pdg.GetParticle(1000020040) ): + pdg.AddParticle("Alpha","Alpha",3.727379e+00,kFALSE,0,6,"Ion",1000020040); + pdg.AddAntiParticle("AntiAlpha", - 1000020040); +if not(pdg.GetParticle(1000020030) ): + pdg.AddParticle("HE3","HE3",2.808391e+00,kFALSE,0,6,"Ion",1000020030); + pdg.AddAntiParticle("AntiHE3", -1000020030); +if not(pdg.GetParticle(1000030070) ): + print "TO BE CHECKED the data insert for Li7Nucleus" + pdg.AddParticle("Li7Nucleus","Li7Nucleus",3.727379e+00/4.*7.,kFALSE,0,0,"Boson",1000030070); +if not(pdg.GetParticle(1000060120) ): + print "ERROR: random values insert for C12Nucleus" + pdg.AddParticle("C12Nucleus","C12Nucleus",0.1,kFALSE,0,0,"Isotope",1000060120); +if not(pdg.GetParticle(1000030060) ): + print "ERROR: random values insert for Li6Nucleus" + pdg.AddParticle("Li6Nucleus","Li6Nucleus",6.015121,kFALSE,0,0,"Isotope",1000030060); +if not(pdg.GetParticle(1000070140) ): + print "ERROR: random values insert for for N14" + pdg.AddParticle("N14","N14",0.1,kTRUE,0,0,"Isotope",1000070140); +if not(pdg.GetParticle(1000050100) ): + print "TO BE CHECKED the data insert for B10" + pdg.AddParticle("B10","B10",10.0129370,kTRUE,0,0,"Isotope",1000050100); +if not(pdg.GetParticle(1000020060) ): + print "TO BE CHECKED the data insert for He6" + pdg.AddParticle("He6","He6",6.0188891,kFALSE,806.7e-3,0,"Isotope",1000020060); +if not(pdg.GetParticle(1000040080) ): + print "TO BE CHECKED the data insert for Be8" + pdg.AddParticle("Be8","Be8",8.00530510,kFALSE,6.7e-17,0,"Isotope",1000040080); +if not(pdg.GetParticle(1000030080) ): + print "TO BE CHECKED the data insert for Li8" + pdg.AddParticle("Li8","Li8",8.002248736,kTRUE,178.3e-3,0,"Isotope",1000030080); +if not(pdg.GetParticle(1000040170) ): + print "ERROR: didn't find what is it particle with code 1000040170, random number inserted!" + pdg.AddParticle("None","None",0.1,kFALSE,0,0,"Isotope",1000040170); +if not(pdg.GetParticle(1000040100) ): + print "TO BE CHECKED the data insert for Be10" + pdg.AddParticle("Be10","Be10",10.0135338,kTRUE,5.004e+9,0,"Isotope",1000040100); +if not(pdg.GetParticle(1000040070) ): + print "TO BE CHECKED the data insert for Be7" + pdg.AddParticle("Be7","Be7",11.021658,kTRUE,13.81,0,"Isotope",1000040070); +if not(pdg.GetParticle(1000230470) ): + print "ERROR: didn't find what is it particle with code 1000230470, random number inserted!" + pdg.AddParticle("None2","None2",0.1,kFALSE,0,0,"Isotope",1000230470); +if not(pdg.GetParticle(1000080170) ): + print "ERROR: didn't find what is it particle with code 1000080170, random number inserted!" + pdg.AddParticle("None3","None3",0.1,kFALSE,0,0,"Isotope",1000080170); +if not(pdg.GetParticle(1000240500) ): + print "ERROR: didn't find what is it particle with code 1000240500, random number inserted!" + pdg.AddParticle("None4","None4",0.1,kFALSE,0,0,"Isotope",1000240500); +if not(pdg.GetParticle(1000210450) ): + print "ERROR: didn't find what is it particle with code 1000210450, random number inserted (Sc45Nucleus)!" + pdg.AddParticle("Sc45Nucleus","Sc45Nucleus",0.1,kFALSE,0,0,"Isotope",1000210450); +if not(pdg.GetParticle(1000040090) ): + print "TO BE CHECKED the data insert for Be9" + pdg.AddParticle("Be9","Be9",9.0121822,kFALSE,0,0,"Isotope",1000040090); +if not(pdg.GetParticle(1000080160) ): + print "TO BE CHECKED the data insert for O16" + pdg.AddParticle("O16","O16",15.99491461956,kFALSE,0,0,"Isotope",1000080160); +if not(pdg.GetParticle(1000220460) ): + print "TO BE CHECKED the data insert for Ar40" + pdg.AddParticle("Ar40","Ar40",39.9623831225,kFALSE,0,0,"Isotope",1000220460); +if not(pdg.GetParticle(1000050110) ): + print "TO BE CHECKED the data insert for B11" + pdg.AddParticle("B11","B11",11.0093054,kFALSE,0,0,"Isotope",1000050110); + +def PrintEventPart(particles,pdg): + print "Particles in the event:" + for (pid,part) in enumerate(particles): + print pid, pdg.GetParticle(part.GetPdgCode()).GetName(), part.GetMotherId() + print + +def PrintRPChits(rpc,pdg): + print "Hits in:" + for (ix,RPCpt) in enumerate(rpc): + tmpName = pdg.GetParticle(RPCpt.PdgCode()) + print ix,RPCpt.GetZ(), tmpName, RPCpt.GetTrackID() , fGeo.FindNode(RPCpt.GetX(),RPCpt.GetY(),RPCpt.GetZ()).GetVolume().GetName() + print + +# weight computation moved to offlineForBarbara.py + +def addVect(t,name,vectType): + vect = vector(vectType)() + t.Branch( name, vect ) + return t, vect + +def addVar(t,name,varType): + var = array(varType,[-999]) + t.Branch(name,var,name+"/"+varType.upper()) + return t, var + +def putToZero(var): + var[0] = 0 + +def getPartName(partId): + return pdg.GetParticle(partId).GetName() + +def lookingForDecay(particles): + decayMotherList = [] + for p in particles: + mID = p.GetMotherId() + if mID>=0 and not (mID in decayMotherList): + decayMotherList.append(mID) + decayPartIndex.push_back(mID) + decayPartID.push_back(particles[mID].GetPdgCode()) + decayPartStrID.push_back(pdg.GetParticle(particles[mID].GetPdgCode()).GetName()) + decayPos_x.push_back(p.GetStartX()) + decayPos_y.push_back(p.GetStartY()) + decayPos_z.push_back(p.GetStartZ()) + decayMother.push_back(particles[mID].GetMotherId()) + decayP.push_back(p.GetP()) + +def wasFired(indexKids, detPoints, detPos, hitCharges, hitTrackId, checkOn, pointVects=None, Ethr=0): + # + def lookingForHits(detPoints,flag,flag_eff,nstat,nstat_eff,indexKids,Eloss,Ethr,hitCharges, hitTrackId): + charges = [] + trackids = [] + if hitCharges is None: + assert(hitTrackId is None) + for pos in detPos: + foundStat = False + foundStat_eff = False + for hit in detPoints: + if (indexKids is None) or (hit.GetTrackID() in indexKids): + # check if it is in one of the considered active layer + if pos[0]<=hit.GetZ()<=pos[1]: + Eloss += hit.GetEnergyLoss() + hitID = hit.GetTrackID() + if not hitID in trackids and not hitCharges is None: + if hit.PdgCode()>100000: + charges.append(9) + else: + charges.append(int(pdg.GetParticle(hit.PdgCode()).Charge())) + trackids.append(hitID) + hitCharges.push_back(charges[-1]) + hitTrackId.push_back(trackids[-1]) + if pointVects is not None: + pointVects[0].push_back(hit.GetX()) + pointVects[1].push_back(hit.GetY()) + pointVects[2].push_back(hit.GetZ()) + flag = True + foundStat = True + eff_val = gRandom.Uniform(0.,1.) + if eff_val<0.9: + flag_eff = flag_eff or True + foundStat_eff = True + else: + flag_eff = flag_eff or False + if foundStat: + nstat+=1 + if foundStat_eff: + nstat_eff+=1 + particles = 0 + flag_Ethr = Eloss>=Ethr + return flag, flag_eff, nstat, nstat_eff, Eloss, flag_Ethr,particles + # + # Now in partKidTrackID I should have the trackID connected to my charged particles + flag_eff = False + flag = False + nstat = 0 + nstat_eff = 0 + Eloss = 0 + flag,flag_eff,nstat,nstat_eff,Eloss,flag_Ethr,particles = lookingForHits(detPoints,flag,flag_eff,nstat,nstat_eff,indexKids,Eloss,Ethr,hitCharges, hitTrackId) + if flag==False and checkOn: + print "To be study event %s"%entry + return flag, flag_eff, nstat, nstat_eff, flag_Ethr, particles + +def convertion(tmpName): + if "Rib" in tmpName: tmpName = "Rib" + elif "LiSc" in tmpName: tmpName= "LiSc" + elif "Tr" in tmpName: tmpName = "Tr" + elif "Startplate" in tmpName: tmpName = "Startplate" + elif re.search("T\d+O", tmpName): tmpName = "TO" + elif re.search("T\d+I", tmpName): tmpName = "TI" + elif "Endplate" in tmpName: tmpName = "Endplate" + elif "volCoil" in tmpName: tmpName = "volCoil" + elif "volFeYoke" in tmpName: tmpName = "volFeYoke" + elif "gas" in tmpName: tmpName = "gas" + elif "wire" in tmpName: tmpName == "wire" + elif "VetoTimeDet" in tmpName: tmpName = "upstreamVeto" + elif "Veto" in tmpName: tmpName = "strawVeto" + return tmpName + +def wasFired_node(indexKids, detPoints, detVolNames, hitCharges, hitTrackId, checkOn, pointVects=None, Ethr=0): + # + def lookingForHits(detPoints,flag,hitCharges, hitTrackId): + if hitCharges is None: + assert(hitTrackId is None) + for hit in detPoints: + if (indexKids is None) or (hit.GetTrackID() in indexKids): + tmpName = fGeo.FindNode(hit.GetX(),hit.GetY(),hit.GetZ()).GetVolume().GetName() + tmpName = convertion(tmpName) + if hit.GetZ()>8000: + continue + if tmpName in detVolNames: + ## trick to remove the case of the tracking system the hits in the gas or straw from the straw-veto: + if 'trackingSystem' in detVolNames and hit.GetZ()<0: + continue + if "strawVetoSystem" in detVolNames and hit.GetZ()>0: + continue + if "upstreamVeto" in detVolNames and not(hit.GetZ()>= upstreamVetoPos[0][0] and hit.GetZ()<=upstreamVetoPos[0][1]): + continue + # check if it is in one of the considered active layer + if True: #pos[0]<=hit.GetZ()<=pos[1]: + flag = True + return flag + # + # Now in partKidTrackID I should have the trackID connected to my charged particles + flag = False + flag = lookingForHits(detPoints,flag,hitCharges, hitTrackId) + if flag==False and checkOn: + print "To be study event %s"%entry + return flag + + +""" Main program """ + +# Open file +f = TFile(fileName) +t = f.Get("cbmsim") + +totentries = t.GetEntries() +if verbose: + print + print + print "Program started, reading %s from %s"%(t.GetName(), fileName) +if (maxevents>0) and (maxevents < totentries): + entries = maxevents +else: + entries = totentries +if verbose: + print "Requested to process %s events out of %s in tree"%(entries, totentries) + +# Load geometry +from lookAtGeo import * +r = loadGeometry(fileNameGeo) +fGeo = r['fGeo'] + +# Functions by Elena for offline selection +# (Also includes another dictionary of all geometry nodes) +import offlineForBarbara as offline +offline.loadNodes(fGeo) +offline.ShipGeo = r['ShipGeo'] +offline.initBField(fileNameGeo) + +# Handle geometry +# Names of useful geometry nodes +myNodes_name = ["VetoTimeDet_1"] +myNodes_name += ["Tr%s_%s"%(i,i) for i in xrange(1,5)] +myNodes_name += ["Veto_5"] +# Positions of selected nodes +myGeoEl = findPositionGeoElement(fileNameGeo, myNodes_name,None) +# Places where a neutrino can interact +lastPassive_nodeName = ["volIron_23"] +OPERA_nodeName = ["volIron", "volRPC", "volHPT","volArm2MS","volFeYokes","volCoil","volFeYoke"]#["volIron_%s"%i for i in xrange(12,24)]+["volRpc_%s"%i for i in xrange(11,22)]+["volArm2MS_1"] +entrance_nodeName = ["T1Lid"]#['T1lid_1'] +volumeIn_nodeName = ["TI"]#['T%sI'%i for i in [1,2,3,5]] +volumeOut_nodeName = ["TO"]#['T%sO'%i for i in [1,2,3,5]] +OPERA_volNames = ["volIron","volRpc","volHPT"] +strawVeto_volNames = ["Veto"] +# Z positions of the VETO and tracking systems +Tracking = [myGeoEl["Tr1_1"]['z']-myGeoEl["Tr1_1"]['dimZ'],myGeoEl["Tr4_4"]['z']+myGeoEl["Tr4_4"]['dimZ']] +upstreamVeto = [myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ'],myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']] +trackStationsPos = [[myGeoEl["Tr%s_%s"%(i,i)]['z']-myGeoEl["Tr%s_%s"%(i,i)]['dimZ'],myGeoEl["Tr%s_%s"%(i,i)]['z']+myGeoEl["Tr%s_%s"%(i,i)]['dimZ']] for i in xrange(1,5)] +strawVetoPos = [[myGeoEl["Veto_5"]['z']-myGeoEl["Veto_5"]['dimZ'],myGeoEl["Veto_5"]['z']+myGeoEl["Veto_5"]['dimZ']]] +vetoWall = [[myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']+0.001,myGeoEl["Tr%s_%s"%(i,i)]['z']-myGeoEl["Tr%s_%s"%(i,i)]['dimZ']]]#myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']+6000.]] +upstreamVetoPos = [[myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ'],myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']]] +RPCstationsPos = [[-3500,myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ']-0.5]] +# Places where a neutrino can interact (some duplicates?) +trackStationsPos_node = ["Tr", "gas", "straw", 'trackingSystem'] +## should be that this does not work since it could be that hits are also assigned to gas or straw +strawVetoPos_node = ["strawVeto", "gas", "straw", "strawVetoSystem"] +vetoWall_node = ["LiSc","cave","Rib","TI","TO","Tr","strawVeto"] +upstreamVetoPos_node = ["upstreamVeto","cave"] +RPCstationsPos_node = ["volRpc","volMagneticSpectrometer","volIron","volHPT"] +# Printout positions +print "OPERApos: ",RPCstationsPos +print "trackingPos: ",trackStationsPos +print "strawVetoPos: ",strawVetoPos +print "scintPos: ",vetoWall +print "upstreamVetoPos: ",upstreamVetoPos + +# Prepare output ntuple +nf = TFile(outputFileName,"RECREATE") +nt = TTree("t","t") +# Event number -------------------------------------------- +nt, event = addVar(nt, 'event','i') +# Neutrino information ------------------------------------ +nt, nNu = addVar(nt, 'nNu', 'i') +nt, isPrimary = addVar(nt, 'isPrimary','i') +nt, startZ_nu = addVar(nt, 'startZ_nu', 'f') +nt, startY_nu = addVar(nt, 'startY_nu', 'f') +nt, startX_nu = addVar(nt, 'startX_nu', 'f') +nt, nuE = addVar(nt, 'nuE', 'f') +nt, weight = addVar(nt, 'weight', 'f') +# Interaction element code -------------------------------- +## 0: last passive material opera-mu-system +## 1: two windows around liquid scintillator +## 2: along vaccum tank +## 3: along all OPERA +## 4: between the two entrance windows +## 5: along vacuum tank outer window +## 6: along vacuum tank inner window +## 999: wrong OPERA place ## needed until we have the new production +## -1: anything else, but what???? #it should never been present +nt, interactionElement = addVar(nt, 'interactionElement','i') +# Neutrino daughters -------------------------------------- +# Do the particles come from a neutrino? +nt, nPart_fromNu = addVar(nt, 'nPart_fromNu', 'i') +nt, idPart_fromNu = addVect(nt, 'idPart_fromNu', 'int') +#nt, idStrPart_fromNu = addVect(nt, 'idStrPart_fromNu', 'string') +# Do charged particles come from a neutrino? +nt, nChargedPart_fromNu = addVar(nt, 'nChargedPart_fromNu', 'i') +nt, idChargedPart_fromNu = addVect(nt, 'idChargedPart_fromNu', 'int') +#nt, idStrChargedPart_fromNu = addVect(nt, 'idStrChargedPart_fromNu', 'string') +# Do neutral particles come from a neutrino? +nt, nNeutrPart_fromNu = addVar(nt, 'nNeutrPart_fromNu', 'i') +nt, idNeutrPart_fromNu = addVect(nt, 'idNeutrPart_fromNu', 'int') +#nt, idStrNeutrPart_fromNu = addVect(nt, 'idStrNeutrPart_fromNu', 'string') +# RPC ----------------------------------------------------- +# In case something (no matter if it comes from the nu-interaction kids) fired the RPC +nt, RPCany = addVar(nt,'RPCany', 'i' ) +# accounting for an eff. of each station of 90% +nt, RPCany_eff = addVar(nt,'RPCany_eff', 'i' ) +# upstreamVeto -------------------------------------------- +nt, upstreamVetoany = addVar(nt,'upstreamVetoAny', 'i' ) +# accounting for an eff. of each station of 90% +nt, upstreamVetoany_eff = addVar(nt,'upstreamVetoAny_eff', 'i' ) +# scintVeto ----------------------------------------------- +## In case something (no matter if it comes from the nu-interaction kids) fired the surroundin walls +nt, scintVetoAny = addVar(nt,'scintVetoAny', 'i' ) +nt, scintVetoAny_eff = addVar(nt,'scintVetoAny_eff', 'i' ) +# strawVeto ----------------------------------------------- +# In case something (no matter if it comes from the nu-interaction kids) fired the strawVeto +nt, strawVetoAny = addVar(nt,'strawVetoAny', 'i' ) +nt, strawVetoAny_eff = addVar(nt,'strawVetoAny_eff', 'i' ) +# TrackSyst ----------------------------------------------- +# only the case of anything fired it is considered, obviously +nt, TrackSyst = addVar(nt, "TrackSyst", 'i') +nt, TrackSyst_eff = addVar(nt, "TrackSyst_eff", 'i') +# VETO and tracking systems with thresholds --------------- +nt, strawVetoAny_Ethr = addVar(nt,"strawVetoAny_Ethr","i") +nt, scintVetoAny_Ethr = addVar(nt,"scintVetoAny_Ethr","i") +nt, upstreamVetoAny_Ethr = addVar(nt,"upstreamVetoAny_Ethr","i") +nt, RPCany_Ethr = addVar(nt,"RPCany_Ethr","i") +nt, TrackSyst_Ethr = addVar(nt, "TrackSyst_Ethr", "i") +# Decay information --------------------------------------- +nt, decayPartIndex = addVect(nt, "decayPartIndex", "float") +nt, decayPartID = addVect(nt, "decayPartID", "float") +nt, decayPartStrID = addVect(nt, "decayPartStrID", "string") +nt, decayPos_x = addVect(nt, "decayPos_x", "float") +nt, decayPos_y = addVect(nt, "decayPos_y", "float") +nt, decayPos_z = addVect(nt, "decayPos_z", "float") +nt, decayMother = addVect(nt, "decayMother", "float") +nt, decayP = addVect(nt,"decayP","float") +# Is this a NC interaction? ------------------------------- +nt, NC = addVar(nt, "NC", "i") +# Store where the neutrino interacted --------------------- +#nt, nuInteractionNode = addVect(nt, "nuInteractionNode", "string") +nt, nuIntNumSimpl = addVar(nt,"nuIntNumSimpl","i") +dictNodeNames = {'volIron':0, 'cave':1, 'LiSc':2, 'Startplate':3, 'TI':4, 'rockD':5, 'Endplate':6, 'Rib':7, 'volFeYoke':8, 'volHPT':9, 'TO':10, 'volRpc':11, 'volCoil':12, 'T1Lid':13, 'straw':14, 'strawVeto':15, 'volBase':16, 'Tr':17, 'gas':18, 'wire':19, 'others':20} +# Was the event reconstructed? ---------------------------- +nt, recoed = addVar(nt, "recoed","i") +# How many candidates in the reco event? ------------------ +nt, nRecoed = addVar(nt, "nRecoed","i") +# Add stuff for online selection -------------------------- +offline.addOfflineToTree(nt) + +# Now loop on the tree +# t = original tree +# nt = new tree +for entry in xrange(entries): + if not (entry%1000): + print "\tProcessing entry %s of %s..."%(entry,entries) + t.GetEntry(entry) + event[0] = entry+(jobID*entries) + particles = t.MCTrack + rpc = t.ShipRpcPoint + scint = t.vetoPoint + strawPoints = t.strawtubesPoint + vetoScint = t.vetoPoint + recoParts = t.Particles + # initialize containers + putToZero(nNu) + putToZero(nPart_fromNu) + putToZero(nChargedPart_fromNu) + putToZero(nNeutrPart_fromNu) + idPart_fromNu.clear() + idChargedPart_fromNu.clear() + idNeutrPart_fromNu.clear() + #idStrPart_fromNu.clear() + #idStrChargedPart_fromNu.clear() + #idStrNeutrPart_fromNu.clear() + decayPartIndex.clear() + decayPartID.clear() + decayPartStrID.clear() + decayPos_x.clear() + decayPos_y.clear() + decayPos_z.clear() + decayMother.clear() + decayP.clear() + #nuInteractionNode.clear() + primaryDone=False + isPrimary[0] = int(False) + lookingForDecay(particles) + nRecoed[0] = 0 + recoed[0] = 0 + # Which one is the "primary" particle? + if sampleType=="nuBg" or sampleType == "cosmics": + startPartRange = [0] + primaryMum = -1 + elif sampleType=="sig": + startPartRange = [1] + primaryMum = 0 + # Look at the primary particle + ip = startPartRange[0] + skipEvent=False + # Were there any hit in the tracking stations? + TrackSyst[0],TrackSyst_eff[0],dummy,dummy,TrackSyst_Ethr[0], dummy = wasFired(None, strawPoints, trackStationsPos, None, None, checkOn=False, pointVects=None)#[strawPoint_x, strawPoint_y, strawPoint_z] ) + # If no, skip this event + if TrackSyst[0]==0: + skipEvent=True + continue + # exit from loop on particles + #break + # Select the primary MC particle + part = particles[ip] + pdgPart = pdg.GetParticle(part.GetPdgCode()) + if sampleType=="nuBg": + assert("nu" in pdgPart.GetName()) + ## Looking for a neutrino: it should have the correct pdg code and it should not have a mother + #if (("nu" in pdgPart.GetName())):# and part.GetMotherId()==-1): # commented out by elena + ## (and de-indented the following block) + ## Starting the counter of how many particles were produced by the interaction of this specific nu + for recoP in recoParts: + nRecoed[0] += 1 + #offline.pushOfflineByParticle(t, recoP) + if nRecoed[0]>0: + recoed[0]=1 + else: + skipEvent=True + continue + #break + nNu[0]+=1 + if part.GetMotherId()==primaryMum: + assert(primaryDone==False) + primaryDone=True + isPrimary[0] = int(True) + assert(len(idPart_fromNu)==0) + assert(len(idNeutrPart_fromNu)==0) + else: + continue + # Where did this guy interact? + tmpName = fGeo.FindNode(part.GetStartX(),part.GetStartY(),part.GetStartZ()).GetVolume().GetName() + #nuInteractionNode.push_back(tmpName) + tmpName = convertion(tmpName) + if not tmpName in dictNodeNames: + tmpName = "others" + nuIntNumSimpl[0] = dictNodeNames[tmpName] + # Store interaction point coordinates + startZ_nu[0] = part.GetStartZ() + startY_nu[0] = part.GetStartY() + startX_nu[0] = part.GetStartX() + # Primary particle information + nuE[0] = part.GetEnergy() + # Looking for particles produced by the neutrino interaction + interacted = False + partKidsId = [] + NC[0] = 0 + # Add information for offline selection + # (mainly signal normalisation and zeroing of particle-wise arrays) + offline.pushOfflineByEvent(t, vetoScint, sampleType, verbose, threshold) + for recoP in recoParts: + offline.pushOfflineByParticle(t, recoP) + + # Loop on MCTracks + for ip2 in xrange(0,len(particles)): + part2 = particles[ip2] + # exit if we have reached the empty part of the array + if not (type(part2)==type(ShipMCTrack())): + break + if part2.GetMotherId()==ip: + interacted = True + part2Id = part2.GetPdgCode() + partKidsId.append(part2Id) + # Was this a neutral current interaction? + if not (pdg.GetParticle(part2.GetPdgCode()) == None) and ("nu" in pdg.GetParticle(part2.GetPdgCode()).GetName()) and (part2.GetMotherId()==0): + NC[0] = 1 + nPart_fromNu[0]+=1 + idPart_fromNu.push_back(part2Id) + if pdg.GetParticle(part2.GetPdgCode()) == None: + part2Name = str(part2Id) + else: + part2Name = getPartName(part2Id) + #idStrPart_fromNu.push_back(part2Name) + # Counting how many particles produced by the nu-interaction are charged or neutral + if (pdg.GetParticle(part2.GetPdgCode())) == None or (int(fabs(pdg.GetParticle(part2Id).Charge()))==int(0)): + nNeutrPart_fromNu[0]+=1 + idNeutrPart_fromNu.push_back(part2Id) + #idStrNeutrPart_fromNu.push_back(part2Name) + else: + nChargedPart_fromNu[0]+=1 + idChargedPart_fromNu.push_back(part2Id) + #idStrChargedPart_fromNu.push_back(part2Name) + # How many are produced by the interaction in the last passive element of the "opera-mu system"? + # Finding out the "interaction element code" + part2Z = part2.GetStartZ() + part2X = part2.GetStartX() + part2Y = part2.GetStartY() + somewhere = False + nodeName = fGeo.FindNode(part2X,part2Y,part2Z).GetName() + if nodeName in lastPassive_nodeName: + somewhere = True + interactionElement[0] = 0 + intElName = 'OPERA' + # To know if it was in the full OPERA-system (excluded last passive) + if tmpName in OPERA_nodeName and somewhere==False: + somewhere = True + interactionElement[0] = 3 + intElName = 'OPERA' + # To know if it was between the two windows + if tmpName in entrance_nodeName: + assert(somewhere==False) + somewhere = True + interactionElement[0] = 1 + # Vacuum tank outer window + if tmpName in volumeIn_nodeName and somewhere==False: + interactionElement[0] = 5 + somewhere = True + # Vacuum tank inner window + elif nodeName in volumeOut_nodeName and somewhere==False: + interactionElement[0] = 6 + somewhere = True + # Vacuum tank ribs + if "Rib" in tmpName: + interactionElement[0] = 7 + # Somewhere else + if somewhere==False: + interactionElement[0] = -1 + # End loop on MCTracks + # Should be changed to avoid entering in the loop if there isn't anything in the tracking + if skipEvent: + continue + strawVetoAny[0],strawVetoAny_eff[0],dummy,dummy,strawVetoAny_Ethr[0],dummy = wasFired(None, strawPoints, strawVetoPos,None,None, checkOn=False, pointVects=None)#[strawVetoPoint_x, strawVetoPoint_y, strawVetoPoint_z]) + upstreamVetoany[0], upstreamVetoany_eff[0], dummy,dummy, upstreamVetoAny_Ethr[0],dummy = wasFired(None, vetoScint, upstreamVetoPos, None, None, checkOn=False, pointVects=None)#[upstreamVetoPoint_x, upstreamVetoPoint_y, upstreamVetoPoint_z]) + RPCany[0], RPCany_eff[0],dummy,dummy, RPCany_Ethr[0],dummy = wasFired(None, rpc, RPCstationsPos, None, None, checkOn=False, pointVects=None)#[rpcPoint_x, rpcPoint_y, rpcPoint_z]) + scintVetoAny[0], scintVetoAny_eff[0], dummy,dummy, scintVetoAny_Ethr[0],dummy = wasFired(None, vetoScint, vetoWall, None, None, checkOn=False, pointVects=None, Ethr=threshold) + #assert(len(idStrPart_fromNu)==len(idPart_fromNu)) + #assert(len(idStrChargedPart_fromNu)==len(idChargedPart_fromNu)) + #assert(len(idStrNeutrPart_fromNu)==len(idNeutrPart_fromNu)) + #assert(len(idStrPart_fromNu)==nChargedPart_fromNu[0]+nNeutrPart_fromNu[0]) + #assert(len(idStrChargedPart_fromNu)==nChargedPart_fromNu[0]) + #assert(len(idStrNeutrPart_fromNu)==nNeutrPart_fromNu[0]) + if not primaryDone: + print "It looks like there is no primary nu interacting" + PrintEventPart(particles,pdg) + sys.exit() + weight[0] = offline.findWeight(sampleType, NC[0], nuE[0], part, entries, pdgPart.GetName(), ON)#calcWeight(NC[0], nuE[0], part.GetWeight(), entries, pdgPart.GetName(), ON) + nt.Fill() + # End loop on tree +nt.Write() +nf.Save() +nf.Close() +f.Close() +print "Output wrote to %s"%outputFileName +print "Number of events with vertex outside Veto_5-500 - Tr4_4: %s"%offline.num_bad_z diff --git a/ntuple_nuVeto_small_newGen_backup b/ntuple_nuVeto_small_newGen_backup new file mode 100644 index 0000000..5dde43b --- /dev/null +++ b/ntuple_nuVeto_small_newGen_backup @@ -0,0 +1,633 @@ +import sys, re, getopt +from array import array +from ROOT import * + +fileName, fileNameGeo, outputFileName, sampleType, jobID = None, None, None, None, None +maxevents = 0 +verbose = True +# Energy deposit threshold for the liquid scintillator +threshold = 0.045 + +# Parse commandline inputs +try: + opts, args = getopt.getopt(sys.argv[1:], "n:t:f:o:v:j:", ['Ethr=']) +except getopt.GetoptError: + # print help information and exit: + print '\tUSAGE: -f inputfile.root -o outputfile.root -t sampleType (sig, nuBg or cosmics) -n maxevents -v verbose (0 or 1) -j jobID (0 to ...) ' + sys.exit() +for o, a in opts: + if o in ("-f",): + fileName = a + if o in ("-o",): + outputFileName = a + if o in ("-n",): + print "-n",a + maxevents = int(a) + if o in ("-j",): + print "-j",a + jobID = int(a) + if o in ("-t",): + sampleType = str(a) + if o in ("-v",): + verbose = bool(int(a)) + if o in ("--Ethr=",): + threshold = float(a) + +fileNameGeo = fileName.replace('ship', 'geofile_full').replace("_rec","") + +def namestr(obj, namespace=globals()): + return [name for name in namespace if namespace[name] is obj] + +for item in [fileName, fileNameGeo, outputFileName, sampleType]: + if not item: + print '\tFATAL! %s not defined!'%namestr(item)[0] + sys.exit() + +for item in [fileName, fileNameGeo, outputFileName, sampleType, maxevents, verbose, threshold]: + print '\tINFO: %s set to %s'%(namestr(item)[0], item) + +# Load SHiP (LHCb) style +gROOT.ProcessLine(".x mystyle.C") +# Obsolete debug flags +oldGeo = False +ON = True +# Load PDG database +pdg = TDatabasePDG.Instance() +# Add elements to PDG database +import pythia8_conf +pythia8_conf.addHNLtoROOT() +# TODO: MAKE THIS A DICTIONARY AND DE-VERBOSIZE IT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 +if not(pdg.GetParticle(1000010020)): + pdg.AddParticle("Deuteron","Deuteron", 1.875613e+00, kTRUE, 0,3,"Ion",1000010020) + pdg.AddAntiParticle("AntiDeuteron", - 1000010020) +if not(pdg.GetParticle(1000010030)): + pdg.AddParticle("Triton","Triton", 2.808921e+00, kFALSE, 3.885235e+17,3,"Ion",1000010030); + pdg.AddAntiParticle("AntiTriton", - 1000010030); +if not(pdg.GetParticle(1000020040) ): + pdg.AddParticle("Alpha","Alpha",3.727379e+00,kFALSE,0,6,"Ion",1000020040); + pdg.AddAntiParticle("AntiAlpha", - 1000020040); +if not(pdg.GetParticle(1000020030) ): + pdg.AddParticle("HE3","HE3",2.808391e+00,kFALSE,0,6,"Ion",1000020030); + pdg.AddAntiParticle("AntiHE3", -1000020030); +if not(pdg.GetParticle(1000030070) ): + print "TO BE CHECKED the data insert for Li7Nucleus" + pdg.AddParticle("Li7Nucleus","Li7Nucleus",3.727379e+00/4.*7.,kFALSE,0,0,"Boson",1000030070); +if not(pdg.GetParticle(1000060120) ): + print "ERROR: random values insert for C12Nucleus" + pdg.AddParticle("C12Nucleus","C12Nucleus",0.1,kFALSE,0,0,"Isotope",1000060120); +if not(pdg.GetParticle(1000030060) ): + print "ERROR: random values insert for Li6Nucleus" + pdg.AddParticle("Li6Nucleus","Li6Nucleus",6.015121,kFALSE,0,0,"Isotope",1000030060); +if not(pdg.GetParticle(1000070140) ): + print "ERROR: random values insert for for N14" + pdg.AddParticle("N14","N14",0.1,kTRUE,0,0,"Isotope",1000070140); +if not(pdg.GetParticle(1000050100) ): + print "TO BE CHECKED the data insert for B10" + pdg.AddParticle("B10","B10",10.0129370,kTRUE,0,0,"Isotope",1000050100); +if not(pdg.GetParticle(1000020060) ): + print "TO BE CHECKED the data insert for He6" + pdg.AddParticle("He6","He6",6.0188891,kFALSE,806.7e-3,0,"Isotope",1000020060); +if not(pdg.GetParticle(1000040080) ): + print "TO BE CHECKED the data insert for Be8" + pdg.AddParticle("Be8","Be8",8.00530510,kFALSE,6.7e-17,0,"Isotope",1000040080); +if not(pdg.GetParticle(1000030080) ): + print "TO BE CHECKED the data insert for Li8" + pdg.AddParticle("Li8","Li8",8.002248736,kTRUE,178.3e-3,0,"Isotope",1000030080); +if not(pdg.GetParticle(1000040170) ): + print "ERROR: didn't find what is it particle with code 1000040170, random number inserted!" + pdg.AddParticle("None","None",0.1,kFALSE,0,0,"Isotope",1000040170); +if not(pdg.GetParticle(1000040100) ): + print "TO BE CHECKED the data insert for Be10" + pdg.AddParticle("Be10","Be10",10.0135338,kTRUE,5.004e+9,0,"Isotope",1000040100); +if not(pdg.GetParticle(1000040070) ): + print "TO BE CHECKED the data insert for Be7" + pdg.AddParticle("Be7","Be7",11.021658,kTRUE,13.81,0,"Isotope",1000040070); +if not(pdg.GetParticle(1000230470) ): + print "ERROR: didn't find what is it particle with code 1000230470, random number inserted!" + pdg.AddParticle("None2","None2",0.1,kFALSE,0,0,"Isotope",1000230470); +if not(pdg.GetParticle(1000080170) ): + print "ERROR: didn't find what is it particle with code 1000080170, random number inserted!" + pdg.AddParticle("None3","None3",0.1,kFALSE,0,0,"Isotope",1000080170); +if not(pdg.GetParticle(1000240500) ): + print "ERROR: didn't find what is it particle with code 1000240500, random number inserted!" + pdg.AddParticle("None4","None4",0.1,kFALSE,0,0,"Isotope",1000240500); +if not(pdg.GetParticle(1000210450) ): + print "ERROR: didn't find what is it particle with code 1000210450, random number inserted (Sc45Nucleus)!" + pdg.AddParticle("Sc45Nucleus","Sc45Nucleus",0.1,kFALSE,0,0,"Isotope",1000210450); +if not(pdg.GetParticle(1000040090) ): + print "TO BE CHECKED the data insert for Be9" + pdg.AddParticle("Be9","Be9",9.0121822,kFALSE,0,0,"Isotope",1000040090); +if not(pdg.GetParticle(1000080160) ): + print "TO BE CHECKED the data insert for O16" + pdg.AddParticle("O16","O16",15.99491461956,kFALSE,0,0,"Isotope",1000080160); +if not(pdg.GetParticle(1000220460) ): + print "TO BE CHECKED the data insert for Ar40" + pdg.AddParticle("Ar40","Ar40",39.9623831225,kFALSE,0,0,"Isotope",1000220460); +if not(pdg.GetParticle(1000050110) ): + print "TO BE CHECKED the data insert for B11" + pdg.AddParticle("B11","B11",11.0093054,kFALSE,0,0,"Isotope",1000050110); + +def PrintEventPart(particles,pdg): + print "Particles in the event:" + for (pid,part) in enumerate(particles): + print pid, pdg.GetParticle(part.GetPdgCode()).GetName(), part.GetMotherId() + print + +def PrintRPChits(rpc,pdg): + print "Hits in:" + for (ix,RPCpt) in enumerate(rpc): + tmpName = pdg.GetParticle(RPCpt.PdgCode()) + print ix,RPCpt.GetZ(), tmpName, RPCpt.GetTrackID() , fGeo.FindNode(RPCpt.GetX(),RPCpt.GetY(),RPCpt.GetZ()).GetVolume().GetName() + print + +# weight computation moved to offlineForBarbara.py + +def addVect(t,name,vectType): + vect = vector(vectType)() + t.Branch( name, vect ) + return t, vect + +def addVar(t,name,varType): + var = array(varType,[-999]) + t.Branch(name,var,name+"/"+varType.upper()) + return t, var + +def putToZero(var): + var[0] = 0 + +def getPartName(partId): + return pdg.GetParticle(partId).GetName() + +def lookingForDecay(particles): + decayMotherList = [] + for p in particles: + mID = p.GetMotherId() + if mID>=0 and not (mID in decayMotherList): + decayMotherList.append(mID) + decayPartIndex.push_back(mID) + decayPartID.push_back(particles[mID].GetPdgCode()) + decayPartStrID.push_back(pdg.GetParticle(particles[mID].GetPdgCode()).GetName()) + decayPos_x.push_back(p.GetStartX()) + decayPos_y.push_back(p.GetStartY()) + decayPos_z.push_back(p.GetStartZ()) + decayMother.push_back(particles[mID].GetMotherId()) + decayP.push_back(p.GetP()) + +def wasFired(indexKids, detPoints, detPos, hitCharges, hitTrackId, checkOn, pointVects=None, Ethr=0): + # + def lookingForHits(detPoints,flag,flag_eff,nstat,nstat_eff,indexKids,Eloss,Ethr,hitCharges, hitTrackId): + charges = [] + trackids = [] + if hitCharges is None: + assert(hitTrackId is None) + for pos in detPos: + foundStat = False + foundStat_eff = False + for hit in detPoints: + if (indexKids is None) or (hit.GetTrackID() in indexKids): + # check if it is in one of the considered active layer + if pos[0]<=hit.GetZ()<=pos[1]: + Eloss += hit.GetEnergyLoss() + hitID = hit.GetTrackID() + if not hitID in trackids and not hitCharges is None: + if hit.PdgCode()>100000: + charges.append(9) + else: + charges.append(int(pdg.GetParticle(hit.PdgCode()).Charge())) + trackids.append(hitID) + hitCharges.push_back(charges[-1]) + hitTrackId.push_back(trackids[-1]) + if pointVects is not None: + pointVects[0].push_back(hit.GetX()) + pointVects[1].push_back(hit.GetY()) + pointVects[2].push_back(hit.GetZ()) + flag = True + foundStat = True + eff_val = gRandom.Uniform(0.,1.) + if eff_val<0.9: + flag_eff = flag_eff or True + foundStat_eff = True + else: + flag_eff = flag_eff or False + if foundStat: + nstat+=1 + if foundStat_eff: + nstat_eff+=1 + particles = 0 + flag_Ethr = Eloss>=Ethr + return flag, flag_eff, nstat, nstat_eff, Eloss, flag_Ethr,particles + # + # Now in partKidTrackID I should have the trackID connected to my charged particles + flag_eff = False + flag = False + nstat = 0 + nstat_eff = 0 + Eloss = 0 + flag,flag_eff,nstat,nstat_eff,Eloss,flag_Ethr,particles = lookingForHits(detPoints,flag,flag_eff,nstat,nstat_eff,indexKids,Eloss,Ethr,hitCharges, hitTrackId) + if flag==False and checkOn: + print "To be study event %s"%entry + return flag, flag_eff, nstat, nstat_eff, flag_Ethr, particles + +def convertion(tmpName): + if "Rib" in tmpName: tmpName = "Rib" + elif "LiSc" in tmpName: tmpName= "LiSc" + elif "Tr" in tmpName: tmpName = "Tr" + elif "Startplate" in tmpName: tmpName = "Startplate" + elif re.search("T\d+O", tmpName): tmpName = "TO" + elif re.search("T\d+I", tmpName): tmpName = "TI" + elif "Endplate" in tmpName: tmpName = "Endplate" + elif "volCoil" in tmpName: tmpName = "volCoil" + elif "volFeYoke" in tmpName: tmpName = "volFeYoke" + elif "gas" in tmpName: tmpName = "gas" + elif "wire" in tmpName: tmpName == "wire" + elif "VetoTimeDet" in tmpName: tmpName = "upstreamVeto" + elif "Veto" in tmpName: tmpName = "strawVeto" + return tmpName + +def wasFired_node(indexKids, detPoints, detVolNames, hitCharges, hitTrackId, checkOn, pointVects=None, Ethr=0): + # + def lookingForHits(detPoints,flag,hitCharges, hitTrackId): + if hitCharges is None: + assert(hitTrackId is None) + for hit in detPoints: + if (indexKids is None) or (hit.GetTrackID() in indexKids): + tmpName = fGeo.FindNode(hit.GetX(),hit.GetY(),hit.GetZ()).GetVolume().GetName() + tmpName = convertion(tmpName) + if hit.GetZ()>8000: + continue + if tmpName in detVolNames: + ## trick to remove the case of the tracking system the hits in the gas or straw from the straw-veto: + if 'trackingSystem' in detVolNames and hit.GetZ()<0: + continue + if "strawVetoSystem" in detVolNames and hit.GetZ()>0: + continue + if "upstreamVeto" in detVolNames and not(hit.GetZ()>= upstreamVetoPos[0][0] and hit.GetZ()<=upstreamVetoPos[0][1]): + continue + # check if it is in one of the considered active layer + if True: #pos[0]<=hit.GetZ()<=pos[1]: + flag = True + return flag + # + # Now in partKidTrackID I should have the trackID connected to my charged particles + flag = False + flag = lookingForHits(detPoints,flag,hitCharges, hitTrackId) + if flag==False and checkOn: + print "To be study event %s"%entry + return flag + + +""" Main program """ + +# Open file +f = TFile(fileName) +t = f.Get("cbmsim") + +totentries = t.GetEntries() +if verbose: + print + print + print "Program started, reading %s from %s"%(t.GetName(), fileName) +if (maxevents>0) and (maxevents < totentries): + entries = maxevents +else: + entries = totentries +if verbose: + print "Requested to process %s events out of %s in tree"%(entries, totentries) + +# Load geometry +from lookAtGeo import * +r = loadGeometry(fileNameGeo) +fGeo = r['fGeo'] + +# Functions by Elena for offline selection +# (Also includes another dictionary of all geometry nodes) +import offlineForBarbara as offline +offline.loadNodes(fGeo) +offline.ShipGeo = r['ShipGeo'] +offline.initBField(fileNameGeo) +offline.sh = offline.StrawHits(t, offline.modules, offline.ShipGeo.straw.resol, 0, None, offline.ShipGeo) +offline.pdg = pdg + +# Handle geometry +# Names of useful geometry nodes +myNodes_name = ["VetoTimeDet_1"] +myNodes_name += ["Tr%s_%s"%(i,i) for i in xrange(1,5)] +myNodes_name += ["Veto_5"] +# Positions of selected nodes +myGeoEl = findPositionGeoElement(fileNameGeo, myNodes_name,None) +# Places where a neutrino can interact +lastPassive_nodeName = ["volIron_23"] +OPERA_nodeName = ["volIron", "volRPC", "volHPT","volArm2MS","volFeYokes","volCoil","volFeYoke"]#["volIron_%s"%i for i in xrange(12,24)]+["volRpc_%s"%i for i in xrange(11,22)]+["volArm2MS_1"] +entrance_nodeName = ["T1Lid"]#['T1lid_1'] +volumeIn_nodeName = ["TI"]#['T%sI'%i for i in [1,2,3,5]] +volumeOut_nodeName = ["TO"]#['T%sO'%i for i in [1,2,3,5]] +OPERA_volNames = ["volIron","volRpc","volHPT"] +strawVeto_volNames = ["Veto"] +# Z positions of the VETO and tracking systems +Tracking = [myGeoEl["Tr1_1"]['z']-myGeoEl["Tr1_1"]['dimZ'],myGeoEl["Tr4_4"]['z']+myGeoEl["Tr4_4"]['dimZ']] +upstreamVeto = [myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ'],myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']] +trackStationsPos = [[myGeoEl["Tr%s_%s"%(i,i)]['z']-myGeoEl["Tr%s_%s"%(i,i)]['dimZ'],myGeoEl["Tr%s_%s"%(i,i)]['z']+myGeoEl["Tr%s_%s"%(i,i)]['dimZ']] for i in xrange(1,5)] +strawVetoPos = [[myGeoEl["Veto_5"]['z']-myGeoEl["Veto_5"]['dimZ'],myGeoEl["Veto_5"]['z']+myGeoEl["Veto_5"]['dimZ']]] +vetoWall = [[myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']+0.001,myGeoEl["Tr%s_%s"%(i,i)]['z']-myGeoEl["Tr%s_%s"%(i,i)]['dimZ']]]#myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']+6000.]] +upstreamVetoPos = [[myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ'],myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']]] +RPCstationsPos = [[-3500,myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ']-0.5]] +# Places where a neutrino can interact (some duplicates?) +trackStationsPos_node = ["Tr", "gas", "straw", 'trackingSystem'] +## should be that this does not work since it could be that hits are also assigned to gas or straw +strawVetoPos_node = ["strawVeto", "gas", "straw", "strawVetoSystem"] +vetoWall_node = ["LiSc","cave","Rib","TI","TO","Tr","strawVeto"] +upstreamVetoPos_node = ["upstreamVeto","cave"] +RPCstationsPos_node = ["volRpc","volMagneticSpectrometer","volIron","volHPT"] +# Printout positions +print "OPERApos: ",RPCstationsPos +print "trackingPos: ",trackStationsPos +print "strawVetoPos: ",strawVetoPos +print "scintPos: ",vetoWall +print "upstreamVetoPos: ",upstreamVetoPos + +# Prepare output ntuple +nf = TFile(outputFileName,"RECREATE") +nt = TTree("t","t") +# Event number -------------------------------------------- +nt, event = addVar(nt, 'event','i') +# Neutrino information ------------------------------------ +nt, nNu = addVar(nt, 'nNu', 'i') +nt, isPrimary = addVar(nt, 'isPrimary','i') +nt, startZ_nu = addVar(nt, 'startZ_nu', 'f') +nt, startY_nu = addVar(nt, 'startY_nu', 'f') +nt, startX_nu = addVar(nt, 'startX_nu', 'f') +nt, nuE = addVar(nt, 'nuE', 'f') +nt, weight = addVar(nt, 'weight', 'f') +# Interaction element code -------------------------------- +## 0: last passive material opera-mu-system +## 1: two windows around liquid scintillator +## 2: along vaccum tank +## 3: along all OPERA +## 4: between the two entrance windows +## 5: along vacuum tank outer window +## 6: along vacuum tank inner window +## 999: wrong OPERA place ## needed until we have the new production +## -1: anything else, but what???? #it should never been present +nt, interactionElement = addVar(nt, 'interactionElement','i') +# Neutrino daughters -------------------------------------- +# Do the particles come from a neutrino? +nt, nPart_fromNu = addVar(nt, 'nPart_fromNu', 'i') +nt, idPart_fromNu = addVect(nt, 'idPart_fromNu', 'int') +#nt, idStrPart_fromNu = addVect(nt, 'idStrPart_fromNu', 'string') +# Do charged particles come from a neutrino? +nt, nChargedPart_fromNu = addVar(nt, 'nChargedPart_fromNu', 'i') +nt, idChargedPart_fromNu = addVect(nt, 'idChargedPart_fromNu', 'int') +#nt, idStrChargedPart_fromNu = addVect(nt, 'idStrChargedPart_fromNu', 'string') +# Do neutral particles come from a neutrino? +nt, nNeutrPart_fromNu = addVar(nt, 'nNeutrPart_fromNu', 'i') +nt, idNeutrPart_fromNu = addVect(nt, 'idNeutrPart_fromNu', 'int') +#nt, idStrNeutrPart_fromNu = addVect(nt, 'idStrNeutrPart_fromNu', 'string') +# RPC ----------------------------------------------------- +# In case something (no matter if it comes from the nu-interaction kids) fired the RPC +nt, RPCany = addVar(nt,'RPCany', 'i' ) +# accounting for an eff. of each station of 90% +nt, RPCany_eff = addVar(nt,'RPCany_eff', 'i' ) +# upstreamVeto -------------------------------------------- +nt, upstreamVetoany = addVar(nt,'upstreamVetoAny', 'i' ) +# accounting for an eff. of each station of 90% +nt, upstreamVetoany_eff = addVar(nt,'upstreamVetoAny_eff', 'i' ) +# scintVeto ----------------------------------------------- +## In case something (no matter if it comes from the nu-interaction kids) fired the surroundin walls +nt, scintVetoAny = addVar(nt,'scintVetoAny', 'i' ) +nt, scintVetoAny_eff = addVar(nt,'scintVetoAny_eff', 'i' ) +# strawVeto ----------------------------------------------- +# In case something (no matter if it comes from the nu-interaction kids) fired the strawVeto +nt, strawVetoAny = addVar(nt,'strawVetoAny', 'i' ) +nt, strawVetoAny_eff = addVar(nt,'strawVetoAny_eff', 'i' ) +# TrackSyst ----------------------------------------------- +# only the case of anything fired it is considered, obviously +nt, TrackSyst = addVar(nt, "TrackSyst", 'i') +nt, TrackSyst_eff = addVar(nt, "TrackSyst_eff", 'i') +# VETO and tracking systems with thresholds --------------- +nt, strawVetoAny_Ethr = addVar(nt,"strawVetoAny_Ethr","i") +nt, scintVetoAny_Ethr = addVar(nt,"scintVetoAny_Ethr","i") +nt, upstreamVetoAny_Ethr = addVar(nt,"upstreamVetoAny_Ethr","i") +nt, RPCany_Ethr = addVar(nt,"RPCany_Ethr","i") +nt, TrackSyst_Ethr = addVar(nt, "TrackSyst_Ethr", "i") +# Decay information --------------------------------------- +nt, decayPartIndex = addVect(nt, "decayPartIndex", "float") +nt, decayPartID = addVect(nt, "decayPartID", "float") +nt, decayPartStrID = addVect(nt, "decayPartStrID", "string") +nt, decayPos_x = addVect(nt, "decayPos_x", "float") +nt, decayPos_y = addVect(nt, "decayPos_y", "float") +nt, decayPos_z = addVect(nt, "decayPos_z", "float") +nt, decayMother = addVect(nt, "decayMother", "float") +nt, decayP = addVect(nt,"decayP","float") +# Is this a NC interaction? ------------------------------- +nt, NC = addVar(nt, "NC", "i") +# Store where the neutrino interacted --------------------- +#nt, nuInteractionNode = addVect(nt, "nuInteractionNode", "string") +nt, nuIntNumSimpl = addVar(nt,"nuIntNumSimpl","i") +dictNodeNames = {'volIron':0, 'cave':1, 'LiSc':2, 'Startplate':3, 'TI':4, 'rockD':5, 'Endplate':6, 'Rib':7, 'volFeYoke':8, 'volHPT':9, 'TO':10, 'volRpc':11, 'volCoil':12, 'T1Lid':13, 'straw':14, 'strawVeto':15, 'volBase':16, 'Tr':17, 'gas':18, 'wire':19, 'others':20} +# Was the event reconstructed? ---------------------------- +nt, recoed = addVar(nt, "recoed","i") +# How many candidates in the reco event? ------------------ +nt, nRecoed = addVar(nt, "nRecoed","i") +# Add stuff for online selection -------------------------- +offline.addOfflineToTree(nt) + +# Now loop on the tree +# t = original tree +# nt = new tree +for entry in xrange(entries): + if not (entry%1000): + print "\tProcessing entry %s of %s..."%(entry,entries) + t.GetEntry(entry) + event[0] = entry+(jobID*entries) + particles = t.MCTrack + rpc = t.ShipRpcPoint + scint = t.vetoPoint + strawPoints = t.strawtubesPoint + vetoScint = t.vetoPoint + recoParts = t.Particles + # initialize containers + putToZero(nNu) + putToZero(nPart_fromNu) + putToZero(nChargedPart_fromNu) + putToZero(nNeutrPart_fromNu) + idPart_fromNu.clear() + idChargedPart_fromNu.clear() + idNeutrPart_fromNu.clear() + #idStrPart_fromNu.clear() + #idStrChargedPart_fromNu.clear() + #idStrNeutrPart_fromNu.clear() + decayPartIndex.clear() + decayPartID.clear() + decayPartStrID.clear() + decayPos_x.clear() + decayPos_y.clear() + decayPos_z.clear() + decayMother.clear() + decayP.clear() + #nuInteractionNode.clear() + primaryDone=False + isPrimary[0] = int(False) + lookingForDecay(particles) + nRecoed[0] = 0 + recoed[0] = 0 + # Which one is the "primary" particle? + if sampleType=="nuBg" or sampleType == "cosmics": + startPartRange = [0] + primaryMum = -1 + elif sampleType=="sig": + startPartRange = [1] + primaryMum = 0 + # Look at the primary particle + ip = startPartRange[0] + skipEvent=False + # Were there any hit in the tracking stations? + TrackSyst[0],TrackSyst_eff[0],dummy,dummy,TrackSyst_Ethr[0], dummy = wasFired(None, strawPoints, trackStationsPos, None, None, checkOn=False, pointVects=None)#[strawPoint_x, strawPoint_y, strawPoint_z] ) + # If no, skip this event + if TrackSyst[0]==0: + skipEvent=True + #print "i am jumping this one" + continue + # exit from loop on particles + #break + # Select the primary MC particle + part = particles[ip] + pdgPart = pdg.GetParticle(part.GetPdgCode()) + if sampleType=="nuBg": + assert("nu" in pdgPart.GetName()) + ## Looking for a neutrino: it should have the correct pdg code and it should not have a mother + #if (("nu" in pdgPart.GetName())):# and part.GetMotherId()==-1): # commented out by elena + ## (and de-indented the following block) + ## Starting the counter of how many particles were produced by the interaction of this specific nu + for recoP in recoParts: + nRecoed[0] += 1 + #offline.pushOfflineByParticle(t, recoP) + if nRecoed[0]>0: + recoed[0]=1 + else: + skipEvent=True + continue + #break + nNu[0]+=1 + if part.GetMotherId()==primaryMum: + assert(primaryDone==False) + primaryDone=True + isPrimary[0] = int(True) + assert(len(idPart_fromNu)==0) + assert(len(idNeutrPart_fromNu)==0) + else: + continue + # Where did this guy interact? + tmpName = fGeo.FindNode(part.GetStartX(),part.GetStartY(),part.GetStartZ()).GetVolume().GetName() + #nuInteractionNode.push_back(tmpName) + tmpName = convertion(tmpName) + if not tmpName in dictNodeNames: + tmpName = "others" + nuIntNumSimpl[0] = dictNodeNames[tmpName] + # Store interaction point coordinates + startZ_nu[0] = part.GetStartZ() + startY_nu[0] = part.GetStartY() + startX_nu[0] = part.GetStartX() + # Primary particle information + nuE[0] = part.GetEnergy() + # Looking for particles produced by the neutrino interaction + interacted = False + partKidsId = [] + NC[0] = 0 + + # Add information for offline selection + # (mainly signal normalisation and zeroing of particle-wise arrays) + ntr, nref = offline.pushOfflineByEvent(t, vetoScint, sampleType, verbose, threshold) + for recoP in recoParts: + offline.pushOfflineByParticle(t, recoP, ntr, nref) + + # Loop on MCTracks + for ip2 in xrange(0,len(particles)): + part2 = particles[ip2] + # exit if we have reached the empty part of the array + if not (type(part2)==type(ShipMCTrack())): + break + if part2.GetMotherId()==ip: + interacted = True + part2Id = part2.GetPdgCode() + partKidsId.append(part2Id) + # Was this a neutral current interaction? + if not (pdg.GetParticle(part2.GetPdgCode()) == None) and ("nu" in pdg.GetParticle(part2.GetPdgCode()).GetName()) and (part2.GetMotherId()==0): + NC[0] = 1 + nPart_fromNu[0]+=1 + idPart_fromNu.push_back(part2Id) + if pdg.GetParticle(part2.GetPdgCode()) == None: + part2Name = str(part2Id) + else: + part2Name = getPartName(part2Id) + #idStrPart_fromNu.push_back(part2Name) + # Counting how many particles produced by the nu-interaction are charged or neutral + if (pdg.GetParticle(part2.GetPdgCode())) == None or (int(fabs(pdg.GetParticle(part2Id).Charge()))==int(0)): + nNeutrPart_fromNu[0]+=1 + idNeutrPart_fromNu.push_back(part2Id) + #idStrNeutrPart_fromNu.push_back(part2Name) + else: + nChargedPart_fromNu[0]+=1 + idChargedPart_fromNu.push_back(part2Id) + #idStrChargedPart_fromNu.push_back(part2Name) + # How many are produced by the interaction in the last passive element of the "opera-mu system"? + # Finding out the "interaction element code" + part2Z = part2.GetStartZ() + part2X = part2.GetStartX() + part2Y = part2.GetStartY() + somewhere = False + nodeName = fGeo.FindNode(part2X,part2Y,part2Z).GetName() + if nodeName in lastPassive_nodeName: + somewhere = True + interactionElement[0] = 0 + intElName = 'OPERA' + # To know if it was in the full OPERA-system (excluded last passive) + if tmpName in OPERA_nodeName and somewhere==False: + somewhere = True + interactionElement[0] = 3 + intElName = 'OPERA' + # To know if it was between the two windows + if tmpName in entrance_nodeName: + assert(somewhere==False) + somewhere = True + interactionElement[0] = 1 + # Vacuum tank outer window + if tmpName in volumeIn_nodeName and somewhere==False: + interactionElement[0] = 5 + somewhere = True + # Vacuum tank inner window + elif nodeName in volumeOut_nodeName and somewhere==False: + interactionElement[0] = 6 + somewhere = True + # Vacuum tank ribs + if "Rib" in tmpName: + interactionElement[0] = 7 + # Somewhere else + if somewhere==False: + interactionElement[0] = -1 + # End loop on MCTracks + # Should be changed to avoid entering in the loop if there isn't anything in the tracking + if skipEvent: + continue + strawVetoAny[0],strawVetoAny_eff[0],dummy,dummy,strawVetoAny_Ethr[0],dummy = wasFired(None, strawPoints, strawVetoPos,None,None, checkOn=False, pointVects=None)#[strawVetoPoint_x, strawVetoPoint_y, strawVetoPoint_z]) + upstreamVetoany[0], upstreamVetoany_eff[0], dummy,dummy, upstreamVetoAny_Ethr[0],dummy = wasFired(None, vetoScint, upstreamVetoPos, None, None, checkOn=False, pointVects=None)#[upstreamVetoPoint_x, upstreamVetoPoint_y, upstreamVetoPoint_z]) + RPCany[0], RPCany_eff[0],dummy,dummy, RPCany_Ethr[0],dummy = wasFired(None, rpc, RPCstationsPos, None, None, checkOn=False, pointVects=None)#[rpcPoint_x, rpcPoint_y, rpcPoint_z]) + scintVetoAny[0], scintVetoAny_eff[0], dummy,dummy, scintVetoAny_Ethr[0],dummy = wasFired(None, vetoScint, vetoWall, None, None, checkOn=False, pointVects=None, Ethr=threshold) + #assert(len(idStrPart_fromNu)==len(idPart_fromNu)) + #assert(len(idStrChargedPart_fromNu)==len(idChargedPart_fromNu)) + #assert(len(idStrNeutrPart_fromNu)==len(idNeutrPart_fromNu)) + #assert(len(idStrPart_fromNu)==nChargedPart_fromNu[0]+nNeutrPart_fromNu[0]) + #assert(len(idStrChargedPart_fromNu)==nChargedPart_fromNu[0]) + #assert(len(idStrNeutrPart_fromNu)==nNeutrPart_fromNu[0]) + if not primaryDone: + print "It looks like there is no primary nu interacting" + PrintEventPart(particles,pdg) + sys.exit() + weight[0] = offline.findWeight(sampleType, NC[0], nuE[0], part, entries, pdgPart.GetName(), ON)#calcWeight(NC[0], nuE[0], part.GetWeight(), entries, pdgPart.GetName(), ON) + nt.Fill() + # End loop on tree +nt.Write() +nf.Save() +nf.Close() +f.Close() +print "Output wrote to %s"%outputFileName +print "Number of events with vertex outside Veto_5-500 - Tr4_4: %s"%offline.num_bad_z diff --git a/ntuple_nuVeto_small_newGen_backup.py b/ntuple_nuVeto_small_newGen_backup.py new file mode 100644 index 0000000..5dde43b --- /dev/null +++ b/ntuple_nuVeto_small_newGen_backup.py @@ -0,0 +1,633 @@ +import sys, re, getopt +from array import array +from ROOT import * + +fileName, fileNameGeo, outputFileName, sampleType, jobID = None, None, None, None, None +maxevents = 0 +verbose = True +# Energy deposit threshold for the liquid scintillator +threshold = 0.045 + +# Parse commandline inputs +try: + opts, args = getopt.getopt(sys.argv[1:], "n:t:f:o:v:j:", ['Ethr=']) +except getopt.GetoptError: + # print help information and exit: + print '\tUSAGE: -f inputfile.root -o outputfile.root -t sampleType (sig, nuBg or cosmics) -n maxevents -v verbose (0 or 1) -j jobID (0 to ...) ' + sys.exit() +for o, a in opts: + if o in ("-f",): + fileName = a + if o in ("-o",): + outputFileName = a + if o in ("-n",): + print "-n",a + maxevents = int(a) + if o in ("-j",): + print "-j",a + jobID = int(a) + if o in ("-t",): + sampleType = str(a) + if o in ("-v",): + verbose = bool(int(a)) + if o in ("--Ethr=",): + threshold = float(a) + +fileNameGeo = fileName.replace('ship', 'geofile_full').replace("_rec","") + +def namestr(obj, namespace=globals()): + return [name for name in namespace if namespace[name] is obj] + +for item in [fileName, fileNameGeo, outputFileName, sampleType]: + if not item: + print '\tFATAL! %s not defined!'%namestr(item)[0] + sys.exit() + +for item in [fileName, fileNameGeo, outputFileName, sampleType, maxevents, verbose, threshold]: + print '\tINFO: %s set to %s'%(namestr(item)[0], item) + +# Load SHiP (LHCb) style +gROOT.ProcessLine(".x mystyle.C") +# Obsolete debug flags +oldGeo = False +ON = True +# Load PDG database +pdg = TDatabasePDG.Instance() +# Add elements to PDG database +import pythia8_conf +pythia8_conf.addHNLtoROOT() +# TODO: MAKE THIS A DICTIONARY AND DE-VERBOSIZE IT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 +if not(pdg.GetParticle(1000010020)): + pdg.AddParticle("Deuteron","Deuteron", 1.875613e+00, kTRUE, 0,3,"Ion",1000010020) + pdg.AddAntiParticle("AntiDeuteron", - 1000010020) +if not(pdg.GetParticle(1000010030)): + pdg.AddParticle("Triton","Triton", 2.808921e+00, kFALSE, 3.885235e+17,3,"Ion",1000010030); + pdg.AddAntiParticle("AntiTriton", - 1000010030); +if not(pdg.GetParticle(1000020040) ): + pdg.AddParticle("Alpha","Alpha",3.727379e+00,kFALSE,0,6,"Ion",1000020040); + pdg.AddAntiParticle("AntiAlpha", - 1000020040); +if not(pdg.GetParticle(1000020030) ): + pdg.AddParticle("HE3","HE3",2.808391e+00,kFALSE,0,6,"Ion",1000020030); + pdg.AddAntiParticle("AntiHE3", -1000020030); +if not(pdg.GetParticle(1000030070) ): + print "TO BE CHECKED the data insert for Li7Nucleus" + pdg.AddParticle("Li7Nucleus","Li7Nucleus",3.727379e+00/4.*7.,kFALSE,0,0,"Boson",1000030070); +if not(pdg.GetParticle(1000060120) ): + print "ERROR: random values insert for C12Nucleus" + pdg.AddParticle("C12Nucleus","C12Nucleus",0.1,kFALSE,0,0,"Isotope",1000060120); +if not(pdg.GetParticle(1000030060) ): + print "ERROR: random values insert for Li6Nucleus" + pdg.AddParticle("Li6Nucleus","Li6Nucleus",6.015121,kFALSE,0,0,"Isotope",1000030060); +if not(pdg.GetParticle(1000070140) ): + print "ERROR: random values insert for for N14" + pdg.AddParticle("N14","N14",0.1,kTRUE,0,0,"Isotope",1000070140); +if not(pdg.GetParticle(1000050100) ): + print "TO BE CHECKED the data insert for B10" + pdg.AddParticle("B10","B10",10.0129370,kTRUE,0,0,"Isotope",1000050100); +if not(pdg.GetParticle(1000020060) ): + print "TO BE CHECKED the data insert for He6" + pdg.AddParticle("He6","He6",6.0188891,kFALSE,806.7e-3,0,"Isotope",1000020060); +if not(pdg.GetParticle(1000040080) ): + print "TO BE CHECKED the data insert for Be8" + pdg.AddParticle("Be8","Be8",8.00530510,kFALSE,6.7e-17,0,"Isotope",1000040080); +if not(pdg.GetParticle(1000030080) ): + print "TO BE CHECKED the data insert for Li8" + pdg.AddParticle("Li8","Li8",8.002248736,kTRUE,178.3e-3,0,"Isotope",1000030080); +if not(pdg.GetParticle(1000040170) ): + print "ERROR: didn't find what is it particle with code 1000040170, random number inserted!" + pdg.AddParticle("None","None",0.1,kFALSE,0,0,"Isotope",1000040170); +if not(pdg.GetParticle(1000040100) ): + print "TO BE CHECKED the data insert for Be10" + pdg.AddParticle("Be10","Be10",10.0135338,kTRUE,5.004e+9,0,"Isotope",1000040100); +if not(pdg.GetParticle(1000040070) ): + print "TO BE CHECKED the data insert for Be7" + pdg.AddParticle("Be7","Be7",11.021658,kTRUE,13.81,0,"Isotope",1000040070); +if not(pdg.GetParticle(1000230470) ): + print "ERROR: didn't find what is it particle with code 1000230470, random number inserted!" + pdg.AddParticle("None2","None2",0.1,kFALSE,0,0,"Isotope",1000230470); +if not(pdg.GetParticle(1000080170) ): + print "ERROR: didn't find what is it particle with code 1000080170, random number inserted!" + pdg.AddParticle("None3","None3",0.1,kFALSE,0,0,"Isotope",1000080170); +if not(pdg.GetParticle(1000240500) ): + print "ERROR: didn't find what is it particle with code 1000240500, random number inserted!" + pdg.AddParticle("None4","None4",0.1,kFALSE,0,0,"Isotope",1000240500); +if not(pdg.GetParticle(1000210450) ): + print "ERROR: didn't find what is it particle with code 1000210450, random number inserted (Sc45Nucleus)!" + pdg.AddParticle("Sc45Nucleus","Sc45Nucleus",0.1,kFALSE,0,0,"Isotope",1000210450); +if not(pdg.GetParticle(1000040090) ): + print "TO BE CHECKED the data insert for Be9" + pdg.AddParticle("Be9","Be9",9.0121822,kFALSE,0,0,"Isotope",1000040090); +if not(pdg.GetParticle(1000080160) ): + print "TO BE CHECKED the data insert for O16" + pdg.AddParticle("O16","O16",15.99491461956,kFALSE,0,0,"Isotope",1000080160); +if not(pdg.GetParticle(1000220460) ): + print "TO BE CHECKED the data insert for Ar40" + pdg.AddParticle("Ar40","Ar40",39.9623831225,kFALSE,0,0,"Isotope",1000220460); +if not(pdg.GetParticle(1000050110) ): + print "TO BE CHECKED the data insert for B11" + pdg.AddParticle("B11","B11",11.0093054,kFALSE,0,0,"Isotope",1000050110); + +def PrintEventPart(particles,pdg): + print "Particles in the event:" + for (pid,part) in enumerate(particles): + print pid, pdg.GetParticle(part.GetPdgCode()).GetName(), part.GetMotherId() + print + +def PrintRPChits(rpc,pdg): + print "Hits in:" + for (ix,RPCpt) in enumerate(rpc): + tmpName = pdg.GetParticle(RPCpt.PdgCode()) + print ix,RPCpt.GetZ(), tmpName, RPCpt.GetTrackID() , fGeo.FindNode(RPCpt.GetX(),RPCpt.GetY(),RPCpt.GetZ()).GetVolume().GetName() + print + +# weight computation moved to offlineForBarbara.py + +def addVect(t,name,vectType): + vect = vector(vectType)() + t.Branch( name, vect ) + return t, vect + +def addVar(t,name,varType): + var = array(varType,[-999]) + t.Branch(name,var,name+"/"+varType.upper()) + return t, var + +def putToZero(var): + var[0] = 0 + +def getPartName(partId): + return pdg.GetParticle(partId).GetName() + +def lookingForDecay(particles): + decayMotherList = [] + for p in particles: + mID = p.GetMotherId() + if mID>=0 and not (mID in decayMotherList): + decayMotherList.append(mID) + decayPartIndex.push_back(mID) + decayPartID.push_back(particles[mID].GetPdgCode()) + decayPartStrID.push_back(pdg.GetParticle(particles[mID].GetPdgCode()).GetName()) + decayPos_x.push_back(p.GetStartX()) + decayPos_y.push_back(p.GetStartY()) + decayPos_z.push_back(p.GetStartZ()) + decayMother.push_back(particles[mID].GetMotherId()) + decayP.push_back(p.GetP()) + +def wasFired(indexKids, detPoints, detPos, hitCharges, hitTrackId, checkOn, pointVects=None, Ethr=0): + # + def lookingForHits(detPoints,flag,flag_eff,nstat,nstat_eff,indexKids,Eloss,Ethr,hitCharges, hitTrackId): + charges = [] + trackids = [] + if hitCharges is None: + assert(hitTrackId is None) + for pos in detPos: + foundStat = False + foundStat_eff = False + for hit in detPoints: + if (indexKids is None) or (hit.GetTrackID() in indexKids): + # check if it is in one of the considered active layer + if pos[0]<=hit.GetZ()<=pos[1]: + Eloss += hit.GetEnergyLoss() + hitID = hit.GetTrackID() + if not hitID in trackids and not hitCharges is None: + if hit.PdgCode()>100000: + charges.append(9) + else: + charges.append(int(pdg.GetParticle(hit.PdgCode()).Charge())) + trackids.append(hitID) + hitCharges.push_back(charges[-1]) + hitTrackId.push_back(trackids[-1]) + if pointVects is not None: + pointVects[0].push_back(hit.GetX()) + pointVects[1].push_back(hit.GetY()) + pointVects[2].push_back(hit.GetZ()) + flag = True + foundStat = True + eff_val = gRandom.Uniform(0.,1.) + if eff_val<0.9: + flag_eff = flag_eff or True + foundStat_eff = True + else: + flag_eff = flag_eff or False + if foundStat: + nstat+=1 + if foundStat_eff: + nstat_eff+=1 + particles = 0 + flag_Ethr = Eloss>=Ethr + return flag, flag_eff, nstat, nstat_eff, Eloss, flag_Ethr,particles + # + # Now in partKidTrackID I should have the trackID connected to my charged particles + flag_eff = False + flag = False + nstat = 0 + nstat_eff = 0 + Eloss = 0 + flag,flag_eff,nstat,nstat_eff,Eloss,flag_Ethr,particles = lookingForHits(detPoints,flag,flag_eff,nstat,nstat_eff,indexKids,Eloss,Ethr,hitCharges, hitTrackId) + if flag==False and checkOn: + print "To be study event %s"%entry + return flag, flag_eff, nstat, nstat_eff, flag_Ethr, particles + +def convertion(tmpName): + if "Rib" in tmpName: tmpName = "Rib" + elif "LiSc" in tmpName: tmpName= "LiSc" + elif "Tr" in tmpName: tmpName = "Tr" + elif "Startplate" in tmpName: tmpName = "Startplate" + elif re.search("T\d+O", tmpName): tmpName = "TO" + elif re.search("T\d+I", tmpName): tmpName = "TI" + elif "Endplate" in tmpName: tmpName = "Endplate" + elif "volCoil" in tmpName: tmpName = "volCoil" + elif "volFeYoke" in tmpName: tmpName = "volFeYoke" + elif "gas" in tmpName: tmpName = "gas" + elif "wire" in tmpName: tmpName == "wire" + elif "VetoTimeDet" in tmpName: tmpName = "upstreamVeto" + elif "Veto" in tmpName: tmpName = "strawVeto" + return tmpName + +def wasFired_node(indexKids, detPoints, detVolNames, hitCharges, hitTrackId, checkOn, pointVects=None, Ethr=0): + # + def lookingForHits(detPoints,flag,hitCharges, hitTrackId): + if hitCharges is None: + assert(hitTrackId is None) + for hit in detPoints: + if (indexKids is None) or (hit.GetTrackID() in indexKids): + tmpName = fGeo.FindNode(hit.GetX(),hit.GetY(),hit.GetZ()).GetVolume().GetName() + tmpName = convertion(tmpName) + if hit.GetZ()>8000: + continue + if tmpName in detVolNames: + ## trick to remove the case of the tracking system the hits in the gas or straw from the straw-veto: + if 'trackingSystem' in detVolNames and hit.GetZ()<0: + continue + if "strawVetoSystem" in detVolNames and hit.GetZ()>0: + continue + if "upstreamVeto" in detVolNames and not(hit.GetZ()>= upstreamVetoPos[0][0] and hit.GetZ()<=upstreamVetoPos[0][1]): + continue + # check if it is in one of the considered active layer + if True: #pos[0]<=hit.GetZ()<=pos[1]: + flag = True + return flag + # + # Now in partKidTrackID I should have the trackID connected to my charged particles + flag = False + flag = lookingForHits(detPoints,flag,hitCharges, hitTrackId) + if flag==False and checkOn: + print "To be study event %s"%entry + return flag + + +""" Main program """ + +# Open file +f = TFile(fileName) +t = f.Get("cbmsim") + +totentries = t.GetEntries() +if verbose: + print + print + print "Program started, reading %s from %s"%(t.GetName(), fileName) +if (maxevents>0) and (maxevents < totentries): + entries = maxevents +else: + entries = totentries +if verbose: + print "Requested to process %s events out of %s in tree"%(entries, totentries) + +# Load geometry +from lookAtGeo import * +r = loadGeometry(fileNameGeo) +fGeo = r['fGeo'] + +# Functions by Elena for offline selection +# (Also includes another dictionary of all geometry nodes) +import offlineForBarbara as offline +offline.loadNodes(fGeo) +offline.ShipGeo = r['ShipGeo'] +offline.initBField(fileNameGeo) +offline.sh = offline.StrawHits(t, offline.modules, offline.ShipGeo.straw.resol, 0, None, offline.ShipGeo) +offline.pdg = pdg + +# Handle geometry +# Names of useful geometry nodes +myNodes_name = ["VetoTimeDet_1"] +myNodes_name += ["Tr%s_%s"%(i,i) for i in xrange(1,5)] +myNodes_name += ["Veto_5"] +# Positions of selected nodes +myGeoEl = findPositionGeoElement(fileNameGeo, myNodes_name,None) +# Places where a neutrino can interact +lastPassive_nodeName = ["volIron_23"] +OPERA_nodeName = ["volIron", "volRPC", "volHPT","volArm2MS","volFeYokes","volCoil","volFeYoke"]#["volIron_%s"%i for i in xrange(12,24)]+["volRpc_%s"%i for i in xrange(11,22)]+["volArm2MS_1"] +entrance_nodeName = ["T1Lid"]#['T1lid_1'] +volumeIn_nodeName = ["TI"]#['T%sI'%i for i in [1,2,3,5]] +volumeOut_nodeName = ["TO"]#['T%sO'%i for i in [1,2,3,5]] +OPERA_volNames = ["volIron","volRpc","volHPT"] +strawVeto_volNames = ["Veto"] +# Z positions of the VETO and tracking systems +Tracking = [myGeoEl["Tr1_1"]['z']-myGeoEl["Tr1_1"]['dimZ'],myGeoEl["Tr4_4"]['z']+myGeoEl["Tr4_4"]['dimZ']] +upstreamVeto = [myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ'],myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']] +trackStationsPos = [[myGeoEl["Tr%s_%s"%(i,i)]['z']-myGeoEl["Tr%s_%s"%(i,i)]['dimZ'],myGeoEl["Tr%s_%s"%(i,i)]['z']+myGeoEl["Tr%s_%s"%(i,i)]['dimZ']] for i in xrange(1,5)] +strawVetoPos = [[myGeoEl["Veto_5"]['z']-myGeoEl["Veto_5"]['dimZ'],myGeoEl["Veto_5"]['z']+myGeoEl["Veto_5"]['dimZ']]] +vetoWall = [[myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']+0.001,myGeoEl["Tr%s_%s"%(i,i)]['z']-myGeoEl["Tr%s_%s"%(i,i)]['dimZ']]]#myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']+6000.]] +upstreamVetoPos = [[myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ'],myGeoEl["VetoTimeDet_1"]['z']+myGeoEl["VetoTimeDet_1"]['dimZ']]] +RPCstationsPos = [[-3500,myGeoEl["VetoTimeDet_1"]['z']-myGeoEl["VetoTimeDet_1"]['dimZ']-0.5]] +# Places where a neutrino can interact (some duplicates?) +trackStationsPos_node = ["Tr", "gas", "straw", 'trackingSystem'] +## should be that this does not work since it could be that hits are also assigned to gas or straw +strawVetoPos_node = ["strawVeto", "gas", "straw", "strawVetoSystem"] +vetoWall_node = ["LiSc","cave","Rib","TI","TO","Tr","strawVeto"] +upstreamVetoPos_node = ["upstreamVeto","cave"] +RPCstationsPos_node = ["volRpc","volMagneticSpectrometer","volIron","volHPT"] +# Printout positions +print "OPERApos: ",RPCstationsPos +print "trackingPos: ",trackStationsPos +print "strawVetoPos: ",strawVetoPos +print "scintPos: ",vetoWall +print "upstreamVetoPos: ",upstreamVetoPos + +# Prepare output ntuple +nf = TFile(outputFileName,"RECREATE") +nt = TTree("t","t") +# Event number -------------------------------------------- +nt, event = addVar(nt, 'event','i') +# Neutrino information ------------------------------------ +nt, nNu = addVar(nt, 'nNu', 'i') +nt, isPrimary = addVar(nt, 'isPrimary','i') +nt, startZ_nu = addVar(nt, 'startZ_nu', 'f') +nt, startY_nu = addVar(nt, 'startY_nu', 'f') +nt, startX_nu = addVar(nt, 'startX_nu', 'f') +nt, nuE = addVar(nt, 'nuE', 'f') +nt, weight = addVar(nt, 'weight', 'f') +# Interaction element code -------------------------------- +## 0: last passive material opera-mu-system +## 1: two windows around liquid scintillator +## 2: along vaccum tank +## 3: along all OPERA +## 4: between the two entrance windows +## 5: along vacuum tank outer window +## 6: along vacuum tank inner window +## 999: wrong OPERA place ## needed until we have the new production +## -1: anything else, but what???? #it should never been present +nt, interactionElement = addVar(nt, 'interactionElement','i') +# Neutrino daughters -------------------------------------- +# Do the particles come from a neutrino? +nt, nPart_fromNu = addVar(nt, 'nPart_fromNu', 'i') +nt, idPart_fromNu = addVect(nt, 'idPart_fromNu', 'int') +#nt, idStrPart_fromNu = addVect(nt, 'idStrPart_fromNu', 'string') +# Do charged particles come from a neutrino? +nt, nChargedPart_fromNu = addVar(nt, 'nChargedPart_fromNu', 'i') +nt, idChargedPart_fromNu = addVect(nt, 'idChargedPart_fromNu', 'int') +#nt, idStrChargedPart_fromNu = addVect(nt, 'idStrChargedPart_fromNu', 'string') +# Do neutral particles come from a neutrino? +nt, nNeutrPart_fromNu = addVar(nt, 'nNeutrPart_fromNu', 'i') +nt, idNeutrPart_fromNu = addVect(nt, 'idNeutrPart_fromNu', 'int') +#nt, idStrNeutrPart_fromNu = addVect(nt, 'idStrNeutrPart_fromNu', 'string') +# RPC ----------------------------------------------------- +# In case something (no matter if it comes from the nu-interaction kids) fired the RPC +nt, RPCany = addVar(nt,'RPCany', 'i' ) +# accounting for an eff. of each station of 90% +nt, RPCany_eff = addVar(nt,'RPCany_eff', 'i' ) +# upstreamVeto -------------------------------------------- +nt, upstreamVetoany = addVar(nt,'upstreamVetoAny', 'i' ) +# accounting for an eff. of each station of 90% +nt, upstreamVetoany_eff = addVar(nt,'upstreamVetoAny_eff', 'i' ) +# scintVeto ----------------------------------------------- +## In case something (no matter if it comes from the nu-interaction kids) fired the surroundin walls +nt, scintVetoAny = addVar(nt,'scintVetoAny', 'i' ) +nt, scintVetoAny_eff = addVar(nt,'scintVetoAny_eff', 'i' ) +# strawVeto ----------------------------------------------- +# In case something (no matter if it comes from the nu-interaction kids) fired the strawVeto +nt, strawVetoAny = addVar(nt,'strawVetoAny', 'i' ) +nt, strawVetoAny_eff = addVar(nt,'strawVetoAny_eff', 'i' ) +# TrackSyst ----------------------------------------------- +# only the case of anything fired it is considered, obviously +nt, TrackSyst = addVar(nt, "TrackSyst", 'i') +nt, TrackSyst_eff = addVar(nt, "TrackSyst_eff", 'i') +# VETO and tracking systems with thresholds --------------- +nt, strawVetoAny_Ethr = addVar(nt,"strawVetoAny_Ethr","i") +nt, scintVetoAny_Ethr = addVar(nt,"scintVetoAny_Ethr","i") +nt, upstreamVetoAny_Ethr = addVar(nt,"upstreamVetoAny_Ethr","i") +nt, RPCany_Ethr = addVar(nt,"RPCany_Ethr","i") +nt, TrackSyst_Ethr = addVar(nt, "TrackSyst_Ethr", "i") +# Decay information --------------------------------------- +nt, decayPartIndex = addVect(nt, "decayPartIndex", "float") +nt, decayPartID = addVect(nt, "decayPartID", "float") +nt, decayPartStrID = addVect(nt, "decayPartStrID", "string") +nt, decayPos_x = addVect(nt, "decayPos_x", "float") +nt, decayPos_y = addVect(nt, "decayPos_y", "float") +nt, decayPos_z = addVect(nt, "decayPos_z", "float") +nt, decayMother = addVect(nt, "decayMother", "float") +nt, decayP = addVect(nt,"decayP","float") +# Is this a NC interaction? ------------------------------- +nt, NC = addVar(nt, "NC", "i") +# Store where the neutrino interacted --------------------- +#nt, nuInteractionNode = addVect(nt, "nuInteractionNode", "string") +nt, nuIntNumSimpl = addVar(nt,"nuIntNumSimpl","i") +dictNodeNames = {'volIron':0, 'cave':1, 'LiSc':2, 'Startplate':3, 'TI':4, 'rockD':5, 'Endplate':6, 'Rib':7, 'volFeYoke':8, 'volHPT':9, 'TO':10, 'volRpc':11, 'volCoil':12, 'T1Lid':13, 'straw':14, 'strawVeto':15, 'volBase':16, 'Tr':17, 'gas':18, 'wire':19, 'others':20} +# Was the event reconstructed? ---------------------------- +nt, recoed = addVar(nt, "recoed","i") +# How many candidates in the reco event? ------------------ +nt, nRecoed = addVar(nt, "nRecoed","i") +# Add stuff for online selection -------------------------- +offline.addOfflineToTree(nt) + +# Now loop on the tree +# t = original tree +# nt = new tree +for entry in xrange(entries): + if not (entry%1000): + print "\tProcessing entry %s of %s..."%(entry,entries) + t.GetEntry(entry) + event[0] = entry+(jobID*entries) + particles = t.MCTrack + rpc = t.ShipRpcPoint + scint = t.vetoPoint + strawPoints = t.strawtubesPoint + vetoScint = t.vetoPoint + recoParts = t.Particles + # initialize containers + putToZero(nNu) + putToZero(nPart_fromNu) + putToZero(nChargedPart_fromNu) + putToZero(nNeutrPart_fromNu) + idPart_fromNu.clear() + idChargedPart_fromNu.clear() + idNeutrPart_fromNu.clear() + #idStrPart_fromNu.clear() + #idStrChargedPart_fromNu.clear() + #idStrNeutrPart_fromNu.clear() + decayPartIndex.clear() + decayPartID.clear() + decayPartStrID.clear() + decayPos_x.clear() + decayPos_y.clear() + decayPos_z.clear() + decayMother.clear() + decayP.clear() + #nuInteractionNode.clear() + primaryDone=False + isPrimary[0] = int(False) + lookingForDecay(particles) + nRecoed[0] = 0 + recoed[0] = 0 + # Which one is the "primary" particle? + if sampleType=="nuBg" or sampleType == "cosmics": + startPartRange = [0] + primaryMum = -1 + elif sampleType=="sig": + startPartRange = [1] + primaryMum = 0 + # Look at the primary particle + ip = startPartRange[0] + skipEvent=False + # Were there any hit in the tracking stations? + TrackSyst[0],TrackSyst_eff[0],dummy,dummy,TrackSyst_Ethr[0], dummy = wasFired(None, strawPoints, trackStationsPos, None, None, checkOn=False, pointVects=None)#[strawPoint_x, strawPoint_y, strawPoint_z] ) + # If no, skip this event + if TrackSyst[0]==0: + skipEvent=True + #print "i am jumping this one" + continue + # exit from loop on particles + #break + # Select the primary MC particle + part = particles[ip] + pdgPart = pdg.GetParticle(part.GetPdgCode()) + if sampleType=="nuBg": + assert("nu" in pdgPart.GetName()) + ## Looking for a neutrino: it should have the correct pdg code and it should not have a mother + #if (("nu" in pdgPart.GetName())):# and part.GetMotherId()==-1): # commented out by elena + ## (and de-indented the following block) + ## Starting the counter of how many particles were produced by the interaction of this specific nu + for recoP in recoParts: + nRecoed[0] += 1 + #offline.pushOfflineByParticle(t, recoP) + if nRecoed[0]>0: + recoed[0]=1 + else: + skipEvent=True + continue + #break + nNu[0]+=1 + if part.GetMotherId()==primaryMum: + assert(primaryDone==False) + primaryDone=True + isPrimary[0] = int(True) + assert(len(idPart_fromNu)==0) + assert(len(idNeutrPart_fromNu)==0) + else: + continue + # Where did this guy interact? + tmpName = fGeo.FindNode(part.GetStartX(),part.GetStartY(),part.GetStartZ()).GetVolume().GetName() + #nuInteractionNode.push_back(tmpName) + tmpName = convertion(tmpName) + if not tmpName in dictNodeNames: + tmpName = "others" + nuIntNumSimpl[0] = dictNodeNames[tmpName] + # Store interaction point coordinates + startZ_nu[0] = part.GetStartZ() + startY_nu[0] = part.GetStartY() + startX_nu[0] = part.GetStartX() + # Primary particle information + nuE[0] = part.GetEnergy() + # Looking for particles produced by the neutrino interaction + interacted = False + partKidsId = [] + NC[0] = 0 + + # Add information for offline selection + # (mainly signal normalisation and zeroing of particle-wise arrays) + ntr, nref = offline.pushOfflineByEvent(t, vetoScint, sampleType, verbose, threshold) + for recoP in recoParts: + offline.pushOfflineByParticle(t, recoP, ntr, nref) + + # Loop on MCTracks + for ip2 in xrange(0,len(particles)): + part2 = particles[ip2] + # exit if we have reached the empty part of the array + if not (type(part2)==type(ShipMCTrack())): + break + if part2.GetMotherId()==ip: + interacted = True + part2Id = part2.GetPdgCode() + partKidsId.append(part2Id) + # Was this a neutral current interaction? + if not (pdg.GetParticle(part2.GetPdgCode()) == None) and ("nu" in pdg.GetParticle(part2.GetPdgCode()).GetName()) and (part2.GetMotherId()==0): + NC[0] = 1 + nPart_fromNu[0]+=1 + idPart_fromNu.push_back(part2Id) + if pdg.GetParticle(part2.GetPdgCode()) == None: + part2Name = str(part2Id) + else: + part2Name = getPartName(part2Id) + #idStrPart_fromNu.push_back(part2Name) + # Counting how many particles produced by the nu-interaction are charged or neutral + if (pdg.GetParticle(part2.GetPdgCode())) == None or (int(fabs(pdg.GetParticle(part2Id).Charge()))==int(0)): + nNeutrPart_fromNu[0]+=1 + idNeutrPart_fromNu.push_back(part2Id) + #idStrNeutrPart_fromNu.push_back(part2Name) + else: + nChargedPart_fromNu[0]+=1 + idChargedPart_fromNu.push_back(part2Id) + #idStrChargedPart_fromNu.push_back(part2Name) + # How many are produced by the interaction in the last passive element of the "opera-mu system"? + # Finding out the "interaction element code" + part2Z = part2.GetStartZ() + part2X = part2.GetStartX() + part2Y = part2.GetStartY() + somewhere = False + nodeName = fGeo.FindNode(part2X,part2Y,part2Z).GetName() + if nodeName in lastPassive_nodeName: + somewhere = True + interactionElement[0] = 0 + intElName = 'OPERA' + # To know if it was in the full OPERA-system (excluded last passive) + if tmpName in OPERA_nodeName and somewhere==False: + somewhere = True + interactionElement[0] = 3 + intElName = 'OPERA' + # To know if it was between the two windows + if tmpName in entrance_nodeName: + assert(somewhere==False) + somewhere = True + interactionElement[0] = 1 + # Vacuum tank outer window + if tmpName in volumeIn_nodeName and somewhere==False: + interactionElement[0] = 5 + somewhere = True + # Vacuum tank inner window + elif nodeName in volumeOut_nodeName and somewhere==False: + interactionElement[0] = 6 + somewhere = True + # Vacuum tank ribs + if "Rib" in tmpName: + interactionElement[0] = 7 + # Somewhere else + if somewhere==False: + interactionElement[0] = -1 + # End loop on MCTracks + # Should be changed to avoid entering in the loop if there isn't anything in the tracking + if skipEvent: + continue + strawVetoAny[0],strawVetoAny_eff[0],dummy,dummy,strawVetoAny_Ethr[0],dummy = wasFired(None, strawPoints, strawVetoPos,None,None, checkOn=False, pointVects=None)#[strawVetoPoint_x, strawVetoPoint_y, strawVetoPoint_z]) + upstreamVetoany[0], upstreamVetoany_eff[0], dummy,dummy, upstreamVetoAny_Ethr[0],dummy = wasFired(None, vetoScint, upstreamVetoPos, None, None, checkOn=False, pointVects=None)#[upstreamVetoPoint_x, upstreamVetoPoint_y, upstreamVetoPoint_z]) + RPCany[0], RPCany_eff[0],dummy,dummy, RPCany_Ethr[0],dummy = wasFired(None, rpc, RPCstationsPos, None, None, checkOn=False, pointVects=None)#[rpcPoint_x, rpcPoint_y, rpcPoint_z]) + scintVetoAny[0], scintVetoAny_eff[0], dummy,dummy, scintVetoAny_Ethr[0],dummy = wasFired(None, vetoScint, vetoWall, None, None, checkOn=False, pointVects=None, Ethr=threshold) + #assert(len(idStrPart_fromNu)==len(idPart_fromNu)) + #assert(len(idStrChargedPart_fromNu)==len(idChargedPart_fromNu)) + #assert(len(idStrNeutrPart_fromNu)==len(idNeutrPart_fromNu)) + #assert(len(idStrPart_fromNu)==nChargedPart_fromNu[0]+nNeutrPart_fromNu[0]) + #assert(len(idStrChargedPart_fromNu)==nChargedPart_fromNu[0]) + #assert(len(idStrNeutrPart_fromNu)==nNeutrPart_fromNu[0]) + if not primaryDone: + print "It looks like there is no primary nu interacting" + PrintEventPart(particles,pdg) + sys.exit() + weight[0] = offline.findWeight(sampleType, NC[0], nuE[0], part, entries, pdgPart.GetName(), ON)#calcWeight(NC[0], nuE[0], part.GetWeight(), entries, pdgPart.GetName(), ON) + nt.Fill() + # End loop on tree +nt.Write() +nf.Save() +nf.Close() +f.Close() +print "Output wrote to %s"%outputFileName +print "Number of events with vertex outside Veto_5-500 - Tr4_4: %s"%offline.num_bad_z diff --git a/offlineForBarbara.py b/offlineForBarbara.py index 71ce6d4..3c46d45 100644 --- a/offlineForBarbara.py +++ b/offlineForBarbara.py @@ -4,8 +4,6 @@ from ShipGeoConfig import ConfigRegistry import shipDet_conf -__run = ROOT.FairRunSim() - from operator import mul, add import sys @@ -108,7 +106,7 @@ ff = ROOT.TFile("histoForWeights.root") h_GioHans = ff.Get("h_Gio") def calcWeightNu(NC, E, w, entries, nuName, ON=True): - # Only for neutrinos and antineutrinos + # Only for neutrinos and antineutrinos if not ON: return 1 if "bar" in nuName: @@ -124,12 +122,12 @@ def findWeight(sampleType, NC, E, MCTrack, entries, nuName, ON): - if sampleType == 'nuBg': - return calcWeightNu(NC, E, MCTrack.GetWeight(), entries, nuName, ON) - elif sampleType == 'sig': - return MCTrack.GetWeight() # for the acceptance, multiply by normalization - elif sampleType == 'cosmics': - return MCTrack.GetWeight() # multiply by 1.e6 / 200. + if sampleType == 'nuBg': + return calcWeightNu(NC, E, MCTrack.GetWeight(), entries, nuName, ON) + elif sampleType == 'sig': + return MCTrack.GetWeight() # for the acceptance, multiply by normalization + elif sampleType == 'cosmics': + return MCTrack.GetWeight() # multiply by 1.e6 / 200. @@ -166,22 +164,22 @@ return False def has_muon_station(event, trackId, station): - zIn = nodes['muondet%s_1'%(station-1)]['z']['pos'] - nodes['muondet%s_1'%(station-1)]['z']['dim'] - zOut = nodes['muondet%s_1'%(station-1)]['z']['pos'] + nodes['muondet%s_1'%(station-1)]['z']['dim'] - for hit in event.muonPoint: - if hit.GetTrackID() == trackId: - if zIn <= hit.GetZ() <= zOut: - return True - return False + zIn = nodes['muondet%s_1'%(station-1)]['z']['pos'] - nodes['muondet%s_1'%(station-1)]['z']['dim'] + zOut = nodes['muondet%s_1'%(station-1)]['z']['pos'] + nodes['muondet%s_1'%(station-1)]['z']['dim'] + for hit in event.muonPoint: + if hit.GetTrackID() == trackId: + if zIn <= hit.GetZ() <= zOut: + return True + return False def hasEcalDeposit(event, trackId, ELossThreshold): - ELoss = 0. - for hit in event.EcalPoint: - if hit.GetTrackID() == trackId: - ELoss += hit.GetEnergyLoss() - if ELoss >= ELossThreshold: - return True - return False + ELoss = 0. + for hit in event.EcalPoint: + if hit.GetTrackID() == trackId: + ELoss += hit.GetEnergyLoss() + if ELoss >= ELossThreshold: + return True + return False def hasMuons(event, trackId): m1 = 0 @@ -189,16 +187,16 @@ m3 = 0 m4 = 0 for ahit in event.muonPoint: - if ahit.GetTrackID() == trackId: - detID = ahit.GetDetectorID() - if(detID == 476) : - m1 += 1 - if(detID == 477) : - m2 += 1 - if(detID == 478) : - m3 += 1 - if(detID == 479) : - m4 += 1 + if ahit.GetTrackID() == trackId: + detID = ahit.GetDetectorID() + if(detID == 476) : + m1 += 1 + if(detID == 477) : + m2 += 1 + if(detID == 478) : + m3 += 1 + if(detID == 479) : + m4 += 1 return [bool(m1), bool(m2), bool(m3), bool(m4)] def myVertex(t1,t2,PosDir): @@ -227,64 +225,76 @@ return X,Y,Z,abs(dist) def addFullInfoToTree(elenaTree): - elenaTree, DaughtersPt = tools.AddVect(elenaTree, 'DaughtersPt', 'float') - elenaTree, DaughtersChi2 = tools.AddVect(elenaTree, 'DaughtersChi2', 'float') - elenaTree, DaughtersNPoints = tools.AddVect(elenaTree, 'DaughtersNPoints', 'int') - elenaTree, DaughtersTruthProdX = tools.AddVect(elenaTree, 'DaughtersTruthProdX', 'float') - elenaTree, DaughtersTruthProdY = tools.AddVect(elenaTree, 'DaughtersTruthProdY', 'float') - elenaTree, DaughtersTruthProdZ = tools.AddVect(elenaTree, 'DaughtersTruthProdZ', 'float') - elenaTree, DaughtersTruthPDG = tools.AddVect(elenaTree, 'DaughtersTruthPDG', 'int') - elenaTree, DaughtersTruthMotherPDG = tools.AddVect(elenaTree, 'DaughtersTruthMotherPDG', 'int') - elenaTree, DaughtersFitConverged = tools.AddVect(elenaTree, 'DaughtersFitConverged', 'int') - elenaTree, straw_x = tools.AddVect(elenaTree, 'straw_x', 'float') - elenaTree, straw_y = tools.AddVect(elenaTree, 'straw_y', 'float') - elenaTree, straw_z = tools.AddVect(elenaTree, 'straw_z', 'float') - elenaTree, muon_x = tools.AddVect(elenaTree, 'muon_x', 'float') - elenaTree, muon_y = tools.AddVect(elenaTree, 'muon_y', 'float') - elenaTree, muon_z = tools.AddVect(elenaTree, 'muon_z', 'float') - elenaTree, ecal_x = tools.AddVect(elenaTree, 'ecal_x', 'float') - elenaTree, ecal_y = tools.AddVect(elenaTree, 'ecal_y', 'float') - elenaTree, ecal_z = tools.AddVect(elenaTree, 'ecal_z', 'float') - elenaTree, hcal_x = tools.AddVect(elenaTree, 'hcal_x', 'float') - elenaTree, hcal_y = tools.AddVect(elenaTree, 'hcal_y', 'float') - elenaTree, hcal_z = tools.AddVect(elenaTree, 'hcal_z', 'float') - elenaTree, veto5_x = tools.AddVect(elenaTree, 'veto5_x', 'float') - elenaTree, veto5_y = tools.AddVect(elenaTree, 'veto5_y', 'float') - elenaTree, veto5_z = tools.AddVect(elenaTree, 'veto5_z', 'float') - elenaTree, liquidscint_x = tools.AddVect(elenaTree, 'liquidscint_x', 'float') - elenaTree, liquidscint_y = tools.AddVect(elenaTree, 'liquidscint_y', 'float') - elenaTree, liquidscint_z = tools.AddVect(elenaTree, 'liquidscint_z', 'float') - elenaTree, DOCA = tools.AddVar(elenaTree, 'DOCA', 'float') - elenaTree, vtxx = tools.AddVar(elenaTree, 'vtxx', 'float') - elenaTree, vtxy = tools.AddVar(elenaTree, 'vtxy', 'float') - elenaTree, vtxz = tools.AddVar(elenaTree, 'vtxz', 'float') - elenaTree, IP0 = tools.AddVar(elenaTree, 'IP0', 'float') - elenaTree, Mass = tools.AddVar(elenaTree, 'Mass', 'float') - elenaTree, Pt = tools.AddVar(elenaTree, 'Pt', 'float') - elenaTree, P = tools.AddVar(elenaTree, 'P', 'float') - elenaTree, NParticles = tools.AddVar(elenaTree, 'NParticles', 'int') - elenaTree, HNLw = tools.AddVar(elenaTree, 'HNLw', 'float') - elenaTree, NuWeight = tools.AddVar(elenaTree, 'NuWeight', 'float') - elenaTree, EventNumber = tools.AddVar(elenaTree, 'EventNumber', 'int') - elenaTree, DaughterMinPt = tools.AddVar(elenaTree, 'DaughterMinPt', 'float') - elenaTree, DaughterMinP = tools.AddVar(elenaTree, 'DaughterMinP', 'float') - elenaTree, DaughtersAlwaysIn = tools.AddVar(elenaTree, 'DaughtersAlwaysIn', 'int') - elenaTree, BadTruthVtx = tools.AddVar(elenaTree, 'BadTruthVtx', 'int') + elenaTree, DaughtersPt = tools.AddVect(elenaTree, 'DaughtersPt', 'float') + elenaTree, DaughtersChi2 = tools.AddVect(elenaTree, 'DaughtersChi2', 'float') + elenaTree, DaughtersNPoints = tools.AddVect(elenaTree, 'DaughtersNPoints', 'int') + elenaTree, DaughtersTruthProdX = tools.AddVect(elenaTree, 'DaughtersTruthProdX', 'float') + elenaTree, DaughtersTruthProdY = tools.AddVect(elenaTree, 'DaughtersTruthProdY', 'float') + elenaTree, DaughtersTruthProdZ = tools.AddVect(elenaTree, 'DaughtersTruthProdZ', 'float') + elenaTree, DaughtersTruthPDG = tools.AddVect(elenaTree, 'DaughtersTruthPDG', 'int') + elenaTree, DaughtersTruthMotherPDG = tools.AddVect(elenaTree, 'DaughtersTruthMotherPDG', 'int') + elenaTree, DaughtersFitConverged = tools.AddVect(elenaTree, 'DaughtersFitConverged', 'int') + elenaTree, straw_x = tools.AddVect(elenaTree, 'straw_x', 'float') + elenaTree, straw_y = tools.AddVect(elenaTree, 'straw_y', 'float') + elenaTree, straw_z = tools.AddVect(elenaTree, 'straw_z', 'float') + elenaTree, muon_x = tools.AddVect(elenaTree, 'muon_x', 'float') + elenaTree, muon_y = tools.AddVect(elenaTree, 'muon_y', 'float') + elenaTree, muon_z = tools.AddVect(elenaTree, 'muon_z', 'float') + elenaTree, ecal_x = tools.AddVect(elenaTree, 'ecal_x', 'float') + elenaTree, ecal_y = tools.AddVect(elenaTree, 'ecal_y', 'float') + elenaTree, ecal_z = tools.AddVect(elenaTree, 'ecal_z', 'float') + elenaTree, hcal_x = tools.AddVect(elenaTree, 'hcal_x', 'float') + elenaTree, hcal_y = tools.AddVect(elenaTree, 'hcal_y', 'float') + elenaTree, hcal_z = tools.AddVect(elenaTree, 'hcal_z', 'float') + elenaTree, veto5_x = tools.AddVect(elenaTree, 'veto5_x', 'float') + elenaTree, veto5_y = tools.AddVect(elenaTree, 'veto5_y', 'float') + elenaTree, veto5_z = tools.AddVect(elenaTree, 'veto5_z', 'float') + elenaTree, liquidscint_x = tools.AddVect(elenaTree, 'liquidscint_x', 'float') + elenaTree, liquidscint_y = tools.AddVect(elenaTree, 'liquidscint_y', 'float') + elenaTree, liquidscint_z = tools.AddVect(elenaTree, 'liquidscint_z', 'float') + elenaTree, DOCA = tools.AddVar(elenaTree, 'DOCA', 'float') + elenaTree, vtxx = tools.AddVar(elenaTree, 'vtxx', 'float') + elenaTree, vtxy = tools.AddVar(elenaTree, 'vtxy', 'float') + elenaTree, vtxz = tools.AddVar(elenaTree, 'vtxz', 'float') + elenaTree, IP0 = tools.AddVar(elenaTree, 'IP0', 'float') + elenaTree, Mass = tools.AddVar(elenaTree, 'Mass', 'float') + elenaTree, Pt = tools.AddVar(elenaTree, 'Pt', 'float') + elenaTree, P = tools.AddVar(elenaTree, 'P', 'float') + elenaTree, NParticles = tools.AddVar(elenaTree, 'NParticles', 'int') + elenaTree, HNLw = tools.AddVar(elenaTree, 'HNLw', 'float') + elenaTree, NuWeight = tools.AddVar(elenaTree, 'NuWeight', 'float') + elenaTree, EventNumber = tools.AddVar(elenaTree, 'EventNumber', 'int') + elenaTree, DaughterMinPt = tools.AddVar(elenaTree, 'DaughterMinPt', 'float') + elenaTree, DaughterMinP = tools.AddVar(elenaTree, 'DaughterMinP', 'float') + elenaTree, DaughtersAlwaysIn = tools.AddVar(elenaTree, 'DaughtersAlwaysIn', 'int') + elenaTree, BadTruthVtx = tools.AddVar(elenaTree, 'BadTruthVtx', 'int') DaughtersFitConverged, DOCA, vtxx, vtxy, vtxz, IP0, HasEcal = None, None, None, None, None, None, None +NoB_DOCA, NoB_vtxx, NoB_vtxy, NoB_vtxz, NoB_IP0 = None, None, None, None, None DaughtersAlwaysIn, BadTruthVtx, Has1Muon1, Has1Muon2, Has2Muon1, Has2Muon2 = None, None, None, None, None, None MaxDaughtersRedChi2, MinDaughtersNdf = None, None +NoB_MaxDaughtersRedChi2, NoB_MinDaughtersNdf = None, None +DaughtersMinP, DaughtersMinPt, Mass, P, Pt = None, None, None, None, None +NoB_DaughtersMinP, NoB_DaughtersMinPt, NoB_Mass, NoB_P, NoB_Pt = None, None, None, None, None def addOfflineToTree(elenaTree): global DaughtersFitConverged, DOCA, vtxx, vtxy, vtxz, IP0, HasEcal + global NoB_DOCA, NoB_vtxx, NoB_vtxy, NoB_vtxz, NoB_IP0 global DaughtersAlwaysIn, BadTruthVtx, Has1Muon1, Has1Muon2, Has2Muon1, Has2Muon2 - global MaxDaughtersRedChi2, MinDaughtersNdf, HNLw, NuWeight + global MaxDaughtersRedChi2, MinDaughtersNdf, HNLw, NuWeight, NoB_MaxDaughtersRedChi2, NoB_MinDaughtersNdf + global DaughtersMinP, DaughtersMinPt, Mass, P, Pt + global NoB_DaughtersMinP, NoB_DaughtersMinPt, NoB_Mass, NoB_P, NoB_Pt elenaTree, DaughtersFitConverged = tools.AddVect(elenaTree, 'DaughtersFitConverged', 'int') # elenaTree, DOCA = tools.AddVect(elenaTree, 'DOCA', 'float') # + elenaTree, NoB_DOCA = tools.AddVect(elenaTree, 'NoB_DOCA', 'float') # elenaTree, vtxx = tools.AddVect(elenaTree, 'vtxx', 'float') # elenaTree, vtxy = tools.AddVect(elenaTree, 'vtxy', 'float') # elenaTree, vtxz = tools.AddVect(elenaTree, 'vtxz', 'float') # + elenaTree, NoB_vtxx = tools.AddVect(elenaTree, 'NoB_vtxx', 'float') # + elenaTree, NoB_vtxy = tools.AddVect(elenaTree, 'NoB_vtxy', 'float') # + elenaTree, NoB_vtxz = tools.AddVect(elenaTree, 'NoB_vtxz', 'float') # elenaTree, IP0 = tools.AddVect(elenaTree, 'IP0', 'float') # + elenaTree, NoB_IP0 = tools.AddVect(elenaTree, 'NoB_IP0', 'float') # #elenaTree, NParticles = tools.AddVar(elenaTree, 'NParticles', 'int') # elenaTree, DaughtersAlwaysIn = tools.AddVect(elenaTree, 'DaughtersAlwaysIn', 'int') # elenaTree, BadTruthVtx = tools.AddVect(elenaTree, 'BadTruthVtx', 'int') # @@ -295,13 +305,25 @@ elenaTree, HasEcal = tools.AddVect(elenaTree, 'HasEcal', 'int') # elenaTree, MaxDaughtersRedChi2 = tools.AddVect(elenaTree, 'MaxDaughtersRedChi2', 'float') # elenaTree, MinDaughtersNdf = tools.AddVect(elenaTree, 'MinDaughtersNdf', 'int') # + elenaTree, NoB_MaxDaughtersRedChi2 = tools.AddVect(elenaTree, 'NoB_MaxDaughtersRedChi2', 'float') # + elenaTree, NoB_MinDaughtersNdf = tools.AddVect(elenaTree, 'NoB_MinDaughtersNdf', 'int') # + elenaTree, DaughtersMinP = tools.AddVect(elenaTree, 'DaughtersMinP', 'float') + elenaTree, DaughtersMinPt = tools.AddVect(elenaTree, 'DaughtersMinPt', 'float') + elenaTree, P = tools.AddVect(elenaTree, 'P', 'float') + elenaTree, Pt = tools.AddVect(elenaTree, 'Pt', 'float') + elenaTree, Mass = tools.AddVect(elenaTree, 'Mass', 'float') + elenaTree, NoB_DaughtersMinP = tools.AddVect(elenaTree, 'NoB_DaughtersMinP', 'float') + elenaTree, NoB_DaughtersMinPt = tools.AddVect(elenaTree, 'NoB_DaughtersMinPt', 'float') + elenaTree, NoB_P = tools.AddVect(elenaTree, 'NoB_P', 'float') + elenaTree, NoB_Pt = tools.AddVect(elenaTree, 'NoB_Pt', 'float') + elenaTree, NoB_Mass = tools.AddVect(elenaTree, 'NoB_Mass', 'float') # Add liquid scintillator segmentation tools.makeLSsegments(nodes, elenaTree) nodes = None def loadNodes(fGeo): - global nodes - nodes = searchForNodes3_xyz_dict(fGeo) + global nodes + nodes = searchForNodes3_xyz_dict(fGeo) num_bad_z = 0 @@ -313,24 +335,24 @@ z_hnl_vtx = findHNLvertex(tree) bad_z = False if not z_hnl_vtx: - if "sig" in datatype: - print 'ERROR: hnl vertex not found!' - ii = 0 - for g in tree.MCTrack: - ii +=1 - if ("sig" in datatype) and ii < 3: - pass - elif ("sig" in datatype) and ii >= 3: - sys.exit() + if "sig" in datatype: + print 'ERROR: hnl vertex not found!' + ii = 0 + for g in tree.MCTrack: + ii +=1 + if ("sig" in datatype) and ii < 3: + pass + elif ("sig" in datatype) and ii >= 3: + sys.exit() if not (nodes['Veto_5']['z']['pos']-nodes['Veto_5']['z']['dim']-500. < z_hnl_vtx < nodes['Tr4_4']['z']['pos']+nodes['Tr4_4']['z']['dim']): - bad_z = True - num_bad_z += 1 - if "sig" in datatype: - print z_hnl_vtx + bad_z = True + num_bad_z += 1 + if "sig" in datatype: + print z_hnl_vtx tools.Push(BadTruthVtx, int(bad_z)) def nParticles(tree): - # By event + # By event global NParticles np = 0 for HNL in tree.Particles: @@ -338,100 +360,247 @@ tools.PutToZero(NParticles); tools.Push(NParticles, np) def hasEcalAndMuons(tree, particle): - # By particle - global Has1Muon1, Has1Muon2, Has2Muon1 - global Has2Muon2, HasEcal - flag2Muon1 = False - flag2Muon2 = False - flag1Muon1 = False - flag1Muon2 = False - flagEcal = False - t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) - # AND or OR? - if ( has_muon_station(tree, t1, 1) and has_muon_station(tree, t2, 1) ): - flag2Muon1 = True - if ( has_muon_station(tree, t1, 2) and has_muon_station(tree, t2, 2) ): - flag2Muon2 = True - if ( has_muon_station(tree, t1, 1) or has_muon_station(tree, t2, 1) ): - flag1Muon1 = True - if ( has_muon_station(tree, t1, 2) or has_muon_station(tree, t2, 2) ): - flag1Muon2 = True - if ( hasEcalDeposit(tree, t1, 150.*u.MeV) or hasEcalDeposit(tree, t2, 150.*u.MeV) ): - flagEcal = True - tools.Push(Has2Muon1, int(flag2Muon1)) - tools.Push(Has2Muon2, int(flag2Muon2)) - tools.Push(Has1Muon1, int(flag1Muon1)) - tools.Push(Has1Muon2, int(flag1Muon2)) - tools.Push(HasEcal, int(flagEcal)) + # By particle + global Has1Muon1, Has1Muon2, Has2Muon1 + global Has2Muon2, HasEcal + flag2Muon1 = False + flag2Muon2 = False + flag1Muon1 = False + flag1Muon2 = False + flagEcal = False + t1,t2 = tree.fitTrack2MC[particle.GetDaughter(0)], tree.fitTrack2MC[particle.GetDaughter(1)] + # AND or OR? + if ( has_muon_station(tree, t1, 1) and has_muon_station(tree, t2, 1) ): + flag2Muon1 = True + if ( has_muon_station(tree, t1, 2) and has_muon_station(tree, t2, 2) ): + flag2Muon2 = True + if ( has_muon_station(tree, t1, 1) or has_muon_station(tree, t2, 1) ): + flag1Muon1 = True + if ( has_muon_station(tree, t1, 2) or has_muon_station(tree, t2, 2) ): + flag1Muon2 = True + # This also work, but may be slower + #muons1 = hasMuons(tree, t1) + #muons2 = hasMuons(tree, t2) + #if muons1[0] or muons2[0]: flag1Muon1 = True + #if muons1[1] or muons2[1]: flag1Muon2 = True + #if muons1[0] and muons2[0]: flag2Muon1 = True + #if muons1[1] and muons2[1]: flag2Muon2 = True + if ( hasEcalDeposit(tree, t1, 150.*u.MeV) or hasEcalDeposit(tree, t2, 150.*u.MeV) ): + flagEcal = True + tools.Push(Has2Muon1, int(flag2Muon1)) + tools.Push(Has2Muon2, int(flag2Muon2)) + tools.Push(Has1Muon1, int(flag1Muon1)) + tools.Push(Has1Muon2, int(flag1Muon2)) + tools.Push(HasEcal, int(flagEcal)) -def chi2Ndf(tree, particle): - # By particle - global MaxDaughtersRedChi2, MinDaughtersNdf, DaughtersFitConverged - t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) - reducedChi2 = [] - ndfs = [] - converged = [] - for tr in [t1,t2]: - x = tree.FitTracks[tr] - ndfs.append( int(round(x.getFitStatus().getNdf())) ) - reducedChi2.append( x.getFitStatus().getChi2()/x.getFitStatus().getNdf() ) - converged.append( x.getFitStatus().isFitConverged() ) - tools.Push(MaxDaughtersRedChi2, max(reducedChi2)) - tools.Push(MinDaughtersNdf, min(ndfs)) - tools.Push( DaughtersFitConverged, int(converged[0]*converged[1]) ) +def chi2Ndf(tree, particle, ntr, nref): + # By particle + global MaxDaughtersRedChi2, MinDaughtersNdf + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + if ntr>1 and nref==2:#nf>1 + t1r,t2r = sh.getReFitTrIDs()[0], sh.getReFitTrIDs()[1] + chi2red_1 = sh.getReFitChi2Ndf(t1r) + ndf_1 = int(round(sh.getReFitNdf(t1r))) + chi2red_2 = sh.getReFitChi2Ndf(t2r) + ndf_2 = int(round(sh.getReFitNdf(t2r))) + reducedChi2 = [chi2red_1, chi2red_2] + ndfs = [ndf_1, ndf_2] + # if the refit didn't work + if (ntr<2) or (nref!=2) or (not ndf_1) or (not ndf_2) or (not chi2red_1) or (not chi2red_2): + reducedChi2 = [] + ndfs = [] + for tr in [t1,t2]: + x = tree.FitTracks[tr] + ndfs.append( int(round(x.getFitStatus().getNdf())) ) + reducedChi2.append( x.getFitStatus().getChi2()/x.getFitStatus().getNdf() ) + tools.Push(MaxDaughtersRedChi2, max(reducedChi2)) + tools.Push(MinDaughtersNdf, min(ndfs)) - + +def NoB_chi2Ndf(tree, particle): + # By particle + global NoB_MaxDaughtersRedChi2, NoB_MinDaughtersNdf, DaughtersFitConverged + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + reducedChi2 = [] + ndfs = [] + converged = [] + for tr in [t1,t2]: + x = tree.FitTracks[tr] + ndfs.append( int(round(x.getFitStatus().getNdf())) ) + reducedChi2.append( x.getFitStatus().getChi2()/x.getFitStatus().getNdf() ) + converged.append( x.getFitStatus().isFitConverged() ) + tools.Push(NoB_MaxDaughtersRedChi2, max(reducedChi2)) + tools.Push(NoB_MinDaughtersNdf, min(ndfs)) + tools.Push( DaughtersFitConverged, int(converged[0]*converged[1]) ) + +def NoB_kinematics(tree, particle): + global NoB_DaughtersMinP, NoB_DaughtersMinPt, NoB_P, NoB_Pt, NoB_Mass + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + dp, dpt = [], [] + for tr in [t1, t2]: + x = tree.FitTracks[tr] + xx = x.getFittedState() + dp.append(xx.getMom().Mag()); dpt.append(xx.getMom().Pt()) + tools.Push(NoB_DaughtersMinP, min(dp)) + tools.Push(NoB_DaughtersMinPt, min(dpt)) + HNLMom = ROOT.TLorentzVector() + particle.Momentum(HNLMom) + tools.Push(NoB_Mass, HNLMom.M()) + tools.Push(NoB_Pt, HNLMom.Pt()) + tools.Push(NoB_P, HNLMom.P()) + def goodBehavedTracks(tree, particle): - # By particle - # Uses MC truth!! - global DaughtersAlwaysIn - t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) - accFlag = True - for tr in [t1,t2]: - mctrid = tree.fitTrack2MC[tr] - if not hasGoodStrawStations(tree, mctrid): - accFlag = False - tools.Push(DaughtersAlwaysIn, int(accFlag)) + # By particle + # Uses MC truth!! + global DaughtersAlwaysIn + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + accFlag = True + for tr in [t1,t2]: + mctrid = tree.fitTrack2MC[tr] + if not hasGoodStrawStations(tree, mctrid): + accFlag = False + tools.Push(DaughtersAlwaysIn, int(accFlag)) -def vertexInfo(tree, particle): - # By particle - global vtxx, vtxy, vtxz - global IP0, DOCA - t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) - PosDir = {} - for tr in [t1,t2]: - xx = tree.FitTracks[tr].getFittedState() - PosDir[tr] = [xx.getPos(),xx.getDir()] - xv,yv,zv,doca = myVertex(t1,t2,PosDir) - tools.Push(DOCA, doca) - tools.Push(vtxx, xv); tools.Push(vtxy, yv); tools.Push(vtxz, zv) - # impact parameter to target - HNLPos = ROOT.TLorentzVector() - particle.ProductionVertex(HNLPos) - HNLMom = ROOT.TLorentzVector() - particle.Momentum(HNLMom) - tr = ROOT.TVector3(0,0,ShipGeo.target.z0) - t = 0 - for i in range(3): t += HNLMom(i)/HNLMom.P()*(tr(i)-HNLPos(i)) - ip = 0 - for i in range(3): ip += (tr(i)-HNLPos(i)-t*HNLMom(i)/HNLMom.P())**2 - ip = ROOT.TMath.Sqrt(ip) - tools.Push(IP0, ip) +def NoB_vertexInfo(tree, particle): + # By particle + global NoB_vtxx, NoB_vtxy, NoB_vtxz + global NoB_IP0, NoB_DOCA + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + PosDir = {} + for tr in [t1,t2]: + xx = tree.FitTracks[tr].getFittedState() + PosDir[tr] = [xx.getPos(),xx.getDir()] + xv,yv,zv,doca = myVertex(t1,t2,PosDir) + tools.Push(NoB_DOCA, doca) + tools.Push(NoB_vtxx, xv); tools.Push(NoB_vtxy, yv); tools.Push(NoB_vtxz, zv) + # impact parameter to target + HNLPos = ROOT.TLorentzVector() + particle.ProductionVertex(HNLPos) + HNLMom = ROOT.TLorentzVector() + particle.Momentum(HNLMom) + tr = ROOT.TVector3(0,0,ShipGeo.target.z0) + t = 0 + for i in range(3): t += HNLMom(i)/HNLMom.P()*(tr(i)-HNLPos(i)) + ip = 0 + for i in range(3): ip += (tr(i)-HNLPos(i)-t*HNLMom(i)/HNLMom.P())**2 + ip = ROOT.TMath.Sqrt(ip) + tools.Push(NoB_IP0, ip) + + +def kinematics(tree, particle, ntr, nref): + global DaughtersMinP, DaughtersMinPt, P, Pt, Mass + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + dminpt, dminp = 0., 0. + + if ntr>1 and nref==2: + t1r,t2r = sh.getReFitTrIDs()[0], sh.getReFitTrIDs()[1] + Pos1, Dir1, Mom1= sh.getReFitPosDirPval(t1r) + Pos2, Dir2, Mom2= sh.getReFitPosDirPval(t2r) + mass1 = pdg.GetParticle(tree.FitTracks[t1].getFittedState().getPDG()).Mass() + mass2 = pdg.GetParticle(tree.FitTracks[t2].getFittedState().getPDG()).Mass() + LV1 = ROOT.TLorentzVector(Mom1*Dir1, ROOT.TMath.Sqrt( mass1*mass1 + Mom1*Mom1 )) + LV2 = ROOT.TLorentzVector(Mom2*Dir2, ROOT.TMath.Sqrt( mass2*mass2 + Mom2*Mom2 )) + HNLMom = LV1+LV2 + if LV1 and LV2: + dminpt = min([LV1.Pt(), LV2.Pt()]) + dminp = min([LV1.P(), LV2.P()]) + + if (ntr<2) or (nref!=2) or (not dminp) or (not dminpt) or (not HNLMom): + dp, dpt = [], [] + for tr in [t1, t2]: + x = tree.FitTracks[tr] + xx = x.getFittedState() + dp.append(xx.getMom().Mag()); dpt.append(xx.getMom().Pt()) + dminpt = min(dpt) + dminp = min(dp) + HNLMom = ROOT.TLorentzVector() + particle.Momentum(HNLMom) + tools.Push(DaughtersMinP, dminp) + tools.Push(DaughtersMinPt, dminpt) + tools.Push(Mass, HNLMom.M()) + tools.Push(Pt, HNLMom.Pt()) + tools.Push(P, HNLMom.P()) + +def vertexInfo(tree, particle, ntr, nref): + # By particle + global vtxx, vtxy, vtxz + global IP0, DOCA + t1,t2 = particle.GetDaughter(0),particle.GetDaughter(1) + + if ntr>1 and nref==2:#nf>1 + assert( len(sh.getReFitTrIDs())==2 ) + t1r,t2r = sh.getReFitTrIDs()[0], sh.getReFitTrIDs()[1] + #print tree.fitTrack2MC[t1], t1r, tree.fitTrack2MC[t2], t2r + #print ntr, nref, len(sh._StrawHits__docaEval) + doca = sh.getDoca()#sh._StrawHits__docaEval[-1]#getDoca() + v = sh.getReFitVertex() + if v and doca: + xv = v.X(); yv = v.Y(); zv = v.Z() + Pos1, Dir1, Mom1= sh.getReFitPosDirPval(t1r) + Pos2, Dir2, Mom2= sh.getReFitPosDirPval(t2r) + mass1 = pdg.GetParticle(tree.FitTracks[t1].getFittedState().getPDG()).Mass() + mass2 = pdg.GetParticle(tree.FitTracks[t2].getFittedState().getPDG()).Mass() + LV1 = ROOT.TLorentzVector(Mom1*Dir1, ROOT.TMath.Sqrt( mass1*mass1 + Mom1*Mom1 )) + LV2 = ROOT.TLorentzVector(Mom2*Dir2, ROOT.TMath.Sqrt( mass2*mass2 + Mom2*Mom2 )) + HNLMom = LV1+LV2 + + # If something went wrong, take the standard values + if (ntr<2) or (nref!=2) or (not v) or (not doca) or (not HNLMom):#(nf<2) + PosDir = {} + for tr in [t1,t2]: + xx = tree.FitTracks[tr].getFittedState() + PosDir[tr] = [xx.getPos(),xx.getDir()] + xv,yv,zv,doca = myVertex(t1,t2,PosDir) + HNLMom = ROOT.TLorentzVector() + particle.Momentum(HNLMom) + + tools.Push(DOCA, doca) + tools.Push(vtxx, xv); tools.Push(vtxy, yv); tools.Push(vtxz, zv) + + # impact parameter to target + #HNLPos = ROOT.TLorentzVector() + #particle.ProductionVertex(HNLPos) + HNLPos = ROOT.TVector3(xv, yv, zv) + tr = ROOT.TVector3(0,0,ShipGeo.target.z0) + t = 0 + for i in range(3): t += HNLMom(i)/HNLMom.P()*(tr(i)-HNLPos(i)) + ip = 0 + for i in range(3): ip += (tr(i)-HNLPos(i)-t*HNLMom(i)/HNLMom.P())**2 + ip = ROOT.TMath.Sqrt(ip) + tools.Push(IP0, ip) def prepareFillingsByParticle(): - # By event - global DaughtersAlwaysIn, DaughtersFitConverged, MinDaughtersNdf, MaxDaughtersRedChi2 - global Has1Muon1, Has1Muon2, Has2Muon1, Has2Muon2, HasEcal - global vtxx, vtxy, vtxz, IP0, DOCA - tools.PutToZero(DaughtersAlwaysIn) - tools.PutToZero(Has2Muon1); tools.PutToZero(Has2Muon2); tools.PutToZero(HasEcal) - tools.PutToZero(Has1Muon1); tools.PutToZero(Has1Muon2) - tools.PutToZero(DOCA) - tools.PutToZero(vtxx); tools.PutToZero(vtxy); tools.PutToZero(vtxz) - tools.PutToZero(IP0) - tools.PutToZero(MinDaughtersNdf); tools.PutToZero(MaxDaughtersRedChi2) - tools.PutToZero(DaughtersFitConverged) + # By event + global DaughtersAlwaysIn, DaughtersFitConverged, MinDaughtersNdf, MaxDaughtersRedChi2 + global NoB_MinDaughtersNdf, NoB_MaxDaughtersRedChi2 + global Has1Muon1, Has1Muon2, Has2Muon1, Has2Muon2, HasEcal + global vtxx, vtxy, vtxz, IP0, DOCA + global NoB_vtxx, NoB_vtxy, NoB_vtxz, NoB_IP0, NoB_DOCA + global DaughtersMinP, DaughtersMinPt, Mass, P, Pt + global NoB_DaughtersMinP, NoB_DaughtersMinPt, NoB_Mass, NoB_P, NoB_Pt + tools.PutToZero(DaughtersAlwaysIn) + tools.PutToZero(Has2Muon1); tools.PutToZero(Has2Muon2); tools.PutToZero(HasEcal) + tools.PutToZero(Has1Muon1); tools.PutToZero(Has1Muon2) + tools.PutToZero(DOCA) + tools.PutToZero(vtxx); tools.PutToZero(vtxy); tools.PutToZero(vtxz) + tools.PutToZero(IP0) + tools.PutToZero(NoB_DOCA) + tools.PutToZero(NoB_vtxx); tools.PutToZero(NoB_vtxy); tools.PutToZero(NoB_vtxz) + tools.PutToZero(NoB_IP0) + tools.PutToZero(MinDaughtersNdf); tools.PutToZero(MaxDaughtersRedChi2) + tools.PutToZero(NoB_MinDaughtersNdf); tools.PutToZero(NoB_MaxDaughtersRedChi2) + tools.PutToZero(DaughtersFitConverged) + tools.PutToZero(DaughtersMinP); tools.PutToZero(DaughtersMinPt) + tools.PutToZero(P); tools.PutToZero(Pt); tools.PutToZero(Mass) + tools.PutToZero(NoB_DaughtersMinP); tools.PutToZero(NoB_DaughtersMinPt) + tools.PutToZero(NoB_P); tools.PutToZero(NoB_Pt); tools.PutToZero(NoB_Mass) + ntr = sh.readEvent() + nref = 0 + if ntr>1: + nref = sh.FitTracks() + #print ntr, nref + return ntr, nref def pushOfflineByEvent(tree, vetoPoints, datatype, verbose, threshold): @@ -440,18 +609,35 @@ ## Number of particles #nParticles(tree) # Empties arrays filled by particle - prepareFillingsByParticle() + ntr, nref = prepareFillingsByParticle() # Liquid scintillator segments global nodes tools.hitSegments(vetoPoints, nodes, threshold) + return ntr, nref -def pushOfflineByParticle(tree, particle): - hasEcalAndMuons(tree, particle) - goodBehavedTracks(tree, particle) - chi2Ndf(tree, particle) - vertexInfo(tree, particle) +def pushOfflineByParticle(tree, particle, ntr, nref): + hasEcalAndMuons(tree, particle) + goodBehavedTracks(tree, particle) + NoB_chi2Ndf(tree, particle) + chi2Ndf(tree, particle, ntr, nref) + NoB_vertexInfo(tree, particle) + vertexInfo(tree, particle, ntr, nref) + NoB_kinematics(tree, particle) + kinematics(tree, particle, ntr, nref) -def initBField(): +fM, tgeom, gMan, geoMat, matEff, modules, run = None, None, None, None, None, None, None + +def initBField(fileNameGeo): + global fM, tgeom, gMan, geoMat, matEff, modules, run, sh + run = ROOT.FairRunSim() + modules = shipDet_conf.configure(run,ShipGeo) + tgeom = ROOT.TGeoManager("Geometry", "Geane geometry") + gMan = tgeom.Import(fileNameGeo) + geoMat = ROOT.genfit.TGeoMaterialInterface() + matEff = ROOT.genfit.MaterialEffects.getInstance() + matEff.init(geoMat) bfield = ROOT.genfit.BellField(ShipGeo.Bfield.max, ShipGeo.Bfield.z, 2, ShipGeo.Yheight/2.) fM = ROOT.genfit.FieldManager.getInstance() fM.init(bfield) + +pdg, sh = None, None \ No newline at end of file diff --git a/pleaseRunMe/FitTrackInfo.py b/pleaseRunMe/FitTrackInfo.py new file mode 100644 index 0000000..9e979be --- /dev/null +++ b/pleaseRunMe/FitTrackInfo.py @@ -0,0 +1,158 @@ +import ROOT,os,sys,getopt +import rootUtils as ut +import shipunit as u + +class FitTrackInfo(object): + + def __init__(self, tree, debug=0): + self.tree = tree + self.debug = debug + self.count = 0 + self.Momentum = {} + self.Direction = {} + self.Position = {} + self.__info = {} + self.Vertex = None + self.Doca = None + # 0 orig, 1 refit, -1 failed refit + self.vertexEFlag = 0 + + def clean(self): + self.count = 0 + self.Momentum.clear() + self.Direction.clear() + self.Position.clear() + self.__info.clear() + self.Vertex = None + self.Doca = None + + def Print(self): + print "FitTrackInfo:" + for tid in self.__info: + print "\t", tid, "{:10.4f}".format(self.__info[tid]['Ndf']), "{:10.4f}".format(self.__info[tid]['Chi2']), + print " pos:", " ".join("{:10.4f}".format(self.Position[tid](ii)) for ii in range(0,3)), + print " mom:", " ".join("{:10.4f}".format(self.Direction[tid](ii)*self.Momentum[tid]) for ii in range(0,3)), + print " P:", "{:10.4f}".format(self.Momentum[tid]) + + ## \brief returns list of keys #__info . + # \return list of MCtrackIDs of fitted tracks. + def getTrIDs(self): + trID = [] + for tid in self.__info: + trID.append(tid) + return trID + + def getNtracks(self) : + return len(self.__info) + + def getChi2Ndf(self, tid): + return self.__info[tid]['Chi2']/self.__info[tid]['Ndf'] + + def getNdf(self, tid): + return self.__info[tid]['Ndf'] + + def compareTracks(self, tid, Pos, Dir, Pval): + false2 = (Pos==None or Dir==None or Pval==None) + false1 = (not tid in self.__info) + if (false2 and false1): return True + if (false2 or false1): return False + return ( (self.Direction[tid]==Dir) and (self.Position[tid]==Pos) and (self.Momentum[tid]==Pval) ) + + + def getPosDirPval(self, tid): + if not tid in self.__info: return None, None, None + return self.Position[tid], self.Direction[tid], self.Momentum[tid] + + def getVertex(self) : + return self.Vertex + + def getDoca(self): + return self.Doca + + def myVertex2(self, t1,t2): + deltaPos =(self.Position[t1]-self.Position[t2]) # A1-A2 + dotDir = self.Direction[t1].Dot(self.Direction[t2]) # a1.a2 + crossDir = self.Direction[t1].Cross(self.Direction[t2]) # a1xa2 + uPerpend = crossDir*(1./crossDir.Mag()) # (a1xa2)/|a1xa2| from a1 to a2 + + minDist = deltaPos.Dot(uPerpend) # (A1-A2).(a1xa2)/|a1xa2| + + # A1 + a1*t1 + (minDist * uPerpend) is (A1 + a1*t1) projected to the plane: + # 1) A2+a2*t2 belons to the plane, + # 2) A1+a1*t1 is parallel to the plane + # cross at t1,t2: A1+a1*t1+(minDist*uPerpend) = A2+a2*t2 + t2X = self.Direction[t2].X() + if (t2X == 0) : t2X = 0.00000000001 + a2a = self.Direction[t2].Y()/t2X + alpha = deltaPos - minDist*uPerpend + nomin = alpha.Y() - a2a*alpha.X() + denom = a2a*self.Direction[t1].X() - self.Direction[t1].Y() + s1 = nomin/denom + s2 = ( alpha.X() + self.Direction[t1].X()*s1 ) / t2X#self.Direction[t2].X() + vec1 = self.Position[t1]+s1*self.Direction[t1] + vec2 = self.Position[t2]+s2*self.Direction[t2] + ave = (vec1+vec2)*0.5 + dif = vec1-vec2 + debugNeed = False + if(abs(abs(minDist)-dif.Mag())>0.00000001): + print "myVertex2 - problem:" + debugNeed = True + if(self.debug>2 or debugNeed): + for tid in (t1,t2): + print str(tid)+": Pos : ", "".join(str(self.Position[tid](ii)) +" " for ii in range(0,3)), + print "\t\tMom : ", "".join(str(self.Direction[tid](ii))+" " for ii in range(0,3)) + print "uPerpend: ","".join(str(uPerpend(ii))+" " for ii in range(0,3)) + if(self.debug>0 or debugNeed): + print "fit vertex: -> 1st poing : ", vec1.X(), vec1.Y(), vec1.Z() + print "fit vertex: -> 2nd point : ", vec2.X(), vec2.Y(), vec2.Z() + print "fit vertex: -> average : ", ave.X(), ave.Y(), ave.Z() + print "distance", abs(minDist), dif.Mag() + return ave, abs(minDist) + + + def readEvent(self): + self.clean() + indx = -1 + for atrack in self.tree.FitTracks: + # kill tracks outside fiducial volume + # if not checkFiducialVolume(sTree,key,dy): continue + fitStatus = atrack.getFitStatus() + if not fitStatus.isFitConverged() : continue + + indx+=1 + mcTrID = self.tree.fitTrack2MC[indx] + + self.__info[mcTrID] = {} + self.__info[mcTrID]['Ndf'] = fitStatus.getNdf() + self.__info[mcTrID]['Chi2'] = fitStatus.getChi2() + + fittedState = atrack.getFittedState() + self.Momentum[mcTrID] = fittedState.getMomMag() + self.Direction[mcTrID] = fittedState.getDir() + self.Position[mcTrID] = fittedState.getPos() + + if(indx>0): + if(indx==1): + self.createVertex(self.__info.keys()[0], self.__info.keys()[1]) + else: + pass + #print "More than 2 fitterd tracks" + return len(self.__info) + + def createVertex(self, tid1, tid2, flag=0): + if( (tid1 in self.__info) and (tid2 in self.__info) ): + self.Vertex, self.Doca = self.myVertex2(tid1, tid2) + self.vertexEFlag = flag + + def addNewTrack(self, mcTrID, position, direction, Pval, ndf, chi2, verb = True): + if (verb and mcTrID in self.Momentum): + print "FotTrackInfo WARNING - trID ", mcTrID, "already filled! Will rewrite all records for this trID!" + + self.__info[mcTrID]={} + self.__info[mcTrID]['Ndf'] = ndf + self.__info[mcTrID]['Chi2'] = chi2 + + self.Momentum[mcTrID] = Pval + self.Direction[mcTrID] = direction + self.Position[mcTrID] = position + \ No newline at end of file diff --git a/pleaseRunMe/RecoSettings.py b/pleaseRunMe/RecoSettings.py new file mode 100644 index 0000000..57a6b22 --- /dev/null +++ b/pleaseRunMe/RecoSettings.py @@ -0,0 +1,23 @@ +import ROOT,os,sys,getopt +import rootUtils as ut +import shipunit as u +""" +Parameter settings for reconstruction +""" + +## min number of hits to produce a track +trackMinNofHits = 25 +trackMinNofStations = 3 +chi2CutOff = 4. +dy = 10.0 +VertexMaxZcut = 2500*u.cm +VertexExtrSteps = 5 +PDG = ROOT.TDatabasePDG.Instance() + +def chargePDG(pdg): + if not PDG.GetParticle(pdg): return + return PDG.GetParticle(pdg).Charge()/(3.) + +def checkEllipticAcc(vec): + Rsq = (vec.X()/(2.45*u.m) )**2 + (vec.Y()/((dy/2.-0.05)*u.m) )**2 + return ( Rsq<1 ) diff --git a/pleaseRunMe/StrawHits.py b/pleaseRunMe/StrawHits.py new file mode 100644 index 0000000..4c0bbb0 --- /dev/null +++ b/pleaseRunMe/StrawHits.py @@ -0,0 +1,520 @@ +import ROOT,os,sys,getopt +import rootUtils as ut +import shipunit as u +from pythia8_conf import addHNLtoROOT +from array import array + +import RecoSettings +from FitTrackInfo import FitTrackInfo + + +######################################################################## +class StrawHits(object): + """StrawHit class""" + def __init__(self, tree, modules, resolution, debug=0, mhistdict=None, ship_geo=None): + ## root tree to be read. + self.__tree = tree + ## geometry description modules. + self.__modules = modules + ## debug level [0,3] + self.__debug = debug + ## hit resolition + self.__resolution = resolution + ## {MCtrackID : [{'pos':TVector3, 'det':detID, 'dw':distance to wire, 'smdw': smeared dw} where [TVector3] list of each hit position. Created if MCtrackID>0. + self.__trackHits = {} + ## + self.__oldSmearedHits ={} + ## {MCtrackID : {X : TVector3}} where x='entry' or 'exit', TVector3 coordinates of last or first hit. + ## Created for tracks with more than #RecoSettings .trackMinNofHits hits. + self.__trackEdgeHits = {} + ## {MCtrackID : number of hits at Z<0 (veto tracker)}. + self.__vetoHits = {} + ## {MCtrackID: number of crossed stations (exclude veto tracker)}. + self.__nStations = {} + ## root random engent for hit smearing (see #__hitSmear). + self.__random = ROOT.TRandom() + ROOT.gRandom.SetSeed(13) + #fitter = ROOT.genfit.KalmanFitter() + #fitter = ROOT.genfit.KalmanFitterRefTrack() + self.__fitter = ROOT.genfit.DAF() + # refitted traks + self.__reFitTracks = FitTrackInfo(tree=None, debug = self.__debug) + self.__docaEval = [] + + if (mhistdict and ship_geo) : + fm = ROOT.genfit.FieldManager.getInstance() + # copy from python/shipDet_conf.py + sbf = ROOT.ShipBellField("wilfried", ship_geo.Bfield.max,ship_geo.Bfield.z,2,ship_geo.Yheight/2.*u.m ) + for i in range (0,300): + z = 1000. + i*10 + pvec3 = ROOT.TVector3(0,0,z) + fx = ROOT.Double(0) + fy = ROOT.Double(0) + fz = ROOT.Double(0) + #fvec3f = fm.getField().get(pvec3) + fm.getField().get(0,0,z,fx,fy,fz) + fvec3f = ROOT.TVector3(fx,fy,fz) + + fvec3s = ROOT.TVector3( sbf.GetBx(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBy(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBz(pvec3.X(),pvec3.Y(),pvec3.Z())) + + #print z, " ".join("{:10.4f}".format(fvec3f(ii)) for ii in range(0,3)), + #print "\t", " ".join("{:10.4f}".format(fvec3s(ii)) for ii in range(0,3)) + mhistdict['magZfit'].Fill(z,fvec3f.Mag()) + mhistdict['magZsim'].Fill(z,fvec3s.Mag()) + + zdict = {1:2500., 2:2800., 3:3000.} + for zi in zdict: + for xi in range (-30, 30): + for yi in range (-30,30): + x = xi*10. + y = yi*10. + pvec3 = ROOT.TVector3(x, y, zdict[zi]) + fx = ROOT.Double(0) + fy = ROOT.Double(0) + fz = ROOT.Double(0) + #fvec3f = fm.getField().get(pvec3) + fm.getField().get(x,y,zdict[zi],fx,fy,fz) + fvec3f = ROOT.TVector3(fx,fy,fz) + + fvec3s = ROOT.TVector3( sbf.GetBx(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBy(pvec3.X(),pvec3.Y(),pvec3.Z()),sbf.GetBz(pvec3.X(),pvec3.Y(),pvec3.Z())) + #print x, " ", y, " ", zdict[zi], + #print "\t", " ".join("{:10.4f}".format(fvec3f(ii)) for ii in range(0,3)), + #print "\t", " ".join("{:10.4f}".format(fvec3s(ii)) for ii in range(0,3)) + mhistdict['magXY'+str(zi)+"fit"].Fill(x, y,fvec3f.Mag()) + mhistdict['magXY'+str(zi)+"sim"].Fill(x, y,fvec3s.Mag()) +######################################################################## + + + ## \brief to be called for each new event (called in #readEvent()) + # cleans all dictionaries (#__trackHits, #__trackEdgeHits, #__vetoHits, #__nStations). + def __clean(self): + self.__trackHits.clear() + self.__oldSmearedHits.clear() + self.__trackEdgeHits.clear() + self.__vetoHits.clear() + self.__nStations.clear() + self.__docaEval = [] +######################################################################## + + + ## \brief returns list of keys #__trackEdgeHits (MCtrackIDs>0 with more than #RecoSettings .trackMinNofHits hits). + # \return list of MCtrackIDs of "good" tracks. + def getTrIDs(self): + trID = [] + for tid in self.__trackEdgeHits: + trID.append(tid) + return trID +######################################################################## + + + ## \brief returns list of keys #__trackHits (MCtrackIDs>0. + # \return list of MCtrackIDs of MC assigned tracks. + def getTrIDsALL(self): + trID = [] + for tid in self.__trackEdgeHits: + trID.append(tid) + return trID +######################################################################## + + + ## \brief returns list of keys #__reFitTracks. + # \return list of MCtrackIDs of "good" tracks. + def getReFitTrIDs(self): + return self.__reFitTracks.getTrIDs() +######################################################################## + + + def getReFitChi2Ndf(self,tid): + return self.__reFitTracks.getChi2Ndf(tid) +######################################################################## + + + def getReFitNdf(self,tid): + return self.__reFitTracks.getNdf(tid) + + + +######################################################################## + ## \brief returns vertex (if number of tracks!=2 will return None!). + # \return new vertex (if number of tracks!=2 will return None!). + def getReFitVertex(self): + return self.__reFitTracks.getVertex() +######################################################################## + + + +######################################################################## + ## \brief returns doca's of each extrapolation steps (size is defined in #RecoSettings .VertexExtrSteps). + # \return new vertex (if number of tracks!=2 will return None!). + def getStepDoca(self, step): + if ( step>RecoSettings.VertexExtrSteps or (not self.__reFitTracks.Vertex) ) : return None + return self.__docaEval[step] +######################################################################## + + + ## \brief returns vertex (if number of tracks!=2 will return None!). + # \return new vertex (if number of tracks!=2 will return None!). + def getReFitPosDirPval(self, tid): + return self.__reFitTracks.getPosDirPval(tid) +######################################################################## + + + ## \brief returns number of hits in proper tracker stations (Z>0) calculated from #__trackHits and #__vetoHits. + # \param tid - MCtrackID. + # \return number of hits in proper tracker stations (Z>0). + def getNofPHits(self, tid): + return len(self.__trackHits[tid]) - self.__vetoHits[tid] +######################################################################## + + + ## \brief returns TVector3 of a tracker entry hit (Z>0) from #__trackEdgeHits. + # \param tid - MCtrackID. + # \return position of a tracker entry hit (Z>0) from #__trackEdgeHits. + def getStartHit(self, tid): + return self.__trackEdgeHits[tid]['entry'] +######################################################################## + + + ## \brief returns number of hits with Z<0 of #__trackHits. + # \param tid - MCtrackID. + # \return number of hits with Z<0 of #__trackHits. + def checkVetoHits(self, tid): + vh = 0 + if tid in self.__vetoHits: + vh = self.__vetoHits[tid] + return vh +######################################################################## + + + def PrintNewTracks(self): + print "new Fits: ", + self.__reFitTracks.Print() +######################################################################## + + + def compareFitTracks(self, tid, theFitTracks): + pos, direct, pval = theFitTracks.getPosDirPval(tid) + return self.__reFitTracks.compareTracks(tid, pos, direct, pval) + +######################################################################## + ## \brief returns a dictionary {xtop, ytop, z, ybot, ybot, z, dist} for a smeared hit. + # \param tid - MCtrackID. + # \param hid - hit index of #__trackHits + # \param new - to generate new smearing (True) or get from SmearedHits (det.position still recalculated!) + # \return a dictionary {xtop, ytop, z, ybot, ybot, z, dist} for a smeared hit. + def __hitSmear(self,tid,hid, new=False): + top = ROOT.TVector3() + bot = ROOT.TVector3() + dw = self.__trackHits[tid][hid]['dw'] + detID = self.__trackHits[tid][hid]['det'] + + self.__modules["Strawtubes"].StrawEndPoints(detID,bot,top) + + if( new ): + smear = abs(self.__random.Gaus(dw, self.__resolution)) + else: + smear = self.__trackHits[tid][hid]['smdw'] + smearedHit = {'xtop':top.x(),'ytop':top.y(),'z':top.z(),'xbot':bot.x(),'ybot':bot.y(),'z':bot.z(),'dist':smear} + + if(self.__debug>2): + print "\tsmear :", "".join("{:8.2f}".format(self.__trackHits[tid][hid]['pos'](ii)) for ii in range(0,3)), + print "{:6.2f}".format(dw), + print "\t(xt,xb, yt, yb, z, dw) : ", + for x in ['xtop','xbot', 'ytop','ybot','z', 'dist']: + print "".join("{:8.2f}".format(smearedHit[x])), + print "" + return smearedHit +######################################################################## + + + ## \brief to be called per each event. Fills #__trackHits, #__trackEdgeHits, #__vetoHits, #__nStations. + # \return number of "good" tracks (size of #__trackEdgeHits) + def readEvent(self): + self.__clean() + toSort = [] # list of MCtrackID which has unsorted hits (I saw also hits from different tracks assigned to the same MCtrackID) + stationList = {} # {MCtrackID:[stations]} + + # loop over all hits and fill __trackHits[MCtrackID] + hindx = -1 + for ahit in self.__tree.strawtubesPoint: + detID = ahit.GetDetectorID() + trID = ahit.GetTrackID() + + # get old smearing + hindx +=1 + origSmHit = self.__tree.SmearedHits.At(hindx) + if( (abs(ahit.GetZ()-origSmHit[3])>0.8) or (abs(ahit.dist2Wire()-origSmHit[7])>0.2) ): + print "problem getting smeared his, but do not change anything" + print "=>", ahit.GetZ(), origSmHit[3], ahit.dist2Wire(), origSmHit[7] + # m = array('d',[i,sm['xtop'],sm['ytop'],sm['z'],sm['xbot'],sm['ybot'],sm['z'],sm['dist']]) + + #=> + if(trID<0): continue # these are hits not assigned to MC track because low E cut + + if (not self.__trackHits.has_key(trID)): + self.__trackHits[trID] = [] + stationList[trID] = [] + + hinfo = {} + hinfo['pos'] = ROOT.TVector3(ahit.GetX(), ahit.GetY(), ahit.GetZ()) + hinfo['det'] = ahit.GetDetectorID() + hinfo['dw'] = ahit.dist2Wire() + hinfo['smdw'] = origSmHit[7] + self.__trackHits[trID].append(hinfo) + + lastIndx = len(self.__trackHits[trID])-1 + if( self.__trackHits[trID][lastIndx]['pos'].Z() < self.__trackHits[trID][lastIndx-1]['pos'].Z() ): + if( not trID in toSort): + toSort.append(trID) + if(self.__debug>0): print "StrawHitsEntry: wrong order of hits for track ", trID + + station = int(ahit.GetDetectorID()/10000000) + if station > 4 : continue + if ( not station in stationList[trID]) : stationList[trID].append(station) + + # sort + for trID in toSort: + if(self.__debug>0): print "StrawHitsEntry: will sort hits for track ", trID + if(self.__debug>2): + print "\t\thits to be sorted" + for hinfo in self.__trackHits[trID]: + vec3 = hinfo['pos'] + print "\t\t\t\t", vec3.X(), "\t", vec3.Y(), "\t", vec3.Z(), hinfo['dw'] + self.__trackHits[trID].sort(key=lambda x: x['pos'].Z(), reverse=False) + if(self.__debug>2): + print "\t\thits after sorting" + for hinfo in self.__trackHits[trID]: + vec3 = hinfo['pos'] + print "\t\t\t\t", vec3.X(), "\t", vec3.Y(), "\t", vec3.Z(), hinfo['dw'] + + # fill self.__nStations + for trID in self.__trackHits: + self.__nStations[trID] = len(stationList[trID]) + if(self.__debug>0): + print "Number of crossed stations (trID:n)", trID, " : ", self.__nStations[trID] + + # find entry and exit positions + for trID in self.__trackHits: + if(self.__debug>1): + print "hits for trID ", trID + for hinfo in self.__trackHits[trID]: + vec3 = hinfo['pos'] + print "\t", vec3.X(), "\t", vec3.Y(), "\t", vec3.Z(), hinfo['dw'] + if(self.__debug>0): print "start/stop position for hits of track ", trID + #find number of vetoTracker hits + firstHit = 0 + nHits = len(self.__trackHits[trID]) + while( firstHit + # the EdgeHits are filled only if nHits(stations1-4)>25 + if( (firstHitRecoSettings.trackMinNofHits) ): + self.__trackEdgeHits[trID] = {} + self.__trackEdgeHits[trID]['entry'] = self.__trackHits[trID][firstHit]['pos'] + self.__trackEdgeHits[trID]['exit'] = self.__trackHits[trID][-1]['pos'] + self.__vetoHits[trID] = firstHit + if(self.__debug>0): + for pos in self.__trackEdgeHits[trID]: + vec3 = self.__trackEdgeHits[trID][pos] + print "\t", pos, vec3.X(), "\t", vec3.Y(), "\t", vec3.Z() + elif( self.__debug>0): print "not set due to small number of hits" + + return len(self.__trackEdgeHits) +######################################################################## + + + + + + def __getIniDir(self,trID): + v1 = self.__trackEdgeHits[trID]['entry'] + i2 = self.__vetoHits[trID]+1 + if( len(self.__trackHits[trID])>i2 ): + v2 = self.__trackHits[trID][i2]['pos'] + dv = v2-v1 + else: + dv = ROOT.TVector3(0., 0., 1.) + if(self.__debug>0): + print "trying to get initial direction having just one hit, will set (0,0,1)" + return dv*(1./dv.Mag()) + + + def __prepareIniPosMomCov(self, tid, original=True): + if ( original ) : + pos = ROOT.TVector3(0, 0, 0) + mom = ROOT.TVector3(0,0,3.*u.GeV) + cov = ROOT.TMatrixDSym(6) + resolution = self.__resolution + for i in range(3): cov[i][i] = resolution*resolution + cov[0][0]=resolution*resolution*100. + nM = self.getNofPHits(tid) + for i in range(3,6): cov[i][i] = ROOT.TMath.pow(resolution / nM / ROOT.TMath.sqrt(3), 2) + else: + pos = self.__trackEdgeHits[tid]['entry'] + mom = self.__getIniDir(tid) + cov = ROOT.TMatrixDSym(6) + resolution = self.__resolution + for i in range(3): cov[i][i] = resolution*resolution + cov[0][0]=resolution*resolution*100. + nM = self.getNofPHits(tid) + for i in range(3,6): cov[i][i] = ROOT.TMath.pow(resolution / nM / ROOT.TMath.sqrt(3), 2) + return pos, mom, cov +######################################################################## + + + + def __prepareWireMeasurements(self, tid, fTrack): + #WireMeasurement::WireMeasurement(const TVectorD& rawHitCoords, + # const TMatrixDSym& rawHitCov, + # int detId, + # int hitId, + # genfit::TrackPoint* trackPoint) + # per each proper hit TMP ??? does it make sense to do for tracks with __vetoHits>0??? + #self.__measurements4fit[trID] = [] + for hindx in range (self.__vetoHits[tid], len(self.__trackHits[tid])): + sm = self.__hitSmear(tid,hindx) + mVector = ROOT.TVectorD(7,array('d',[sm['xtop'],sm['ytop'],sm['z'],sm['xbot'],sm['ybot'],sm['z'],sm['dist']])) + #self.__measurements4fit[trID].push_back(mVector) + + hitCov = ROOT.TMatrixDSym(7) + hitCov[6][6] = self.__resolution*self.__resolution + + tp = ROOT.genfit.TrackPoint(fTrack) # note how the point is told which track it belongs to + measurement = ROOT.genfit.WireMeasurement(mVector,hitCov,1,6,tp) # the measurement is told which trackpoint it belongs to + # print measurement.getMaxDistance() + measurement.setMaxDistance(0.5*u.cm) + #measurement.setLeftRightResolution(-1) + tp.addRawMeasurement(measurement) # package measurement in the TrackPoint + if(self.__debug>2): + tp.Print() + fTrack.insertPoint(tp) # add point to Track + + + + + + +######################################################################## + def FitTracks(self, old=True): + + self.__reFitTracks.clean() + + fitTrack = {} + #self.__measurements4fit = {} + nTrack = -1 + + + for trID in self.__trackEdgeHits : # these are already tracks with large number of hits + #print "track entry", self.__trackEdgeHits[tid]['entry']. + #print "mfield: ", ROOT + if(self.__debug>0): + print "ELENA Number of crossed stations (trID:n)", trID, " : ", self.__nStations[trID] + print self.__trackEdgeHits[trID]['entry'].Z() + + # minimal requirements on number of crossed stations + if ( self.__nStations2): print "preparing measurements for track ID", trID + self.__prepareWireMeasurements(trID, fitTrack[trID]) + if not fitTrack[trID].checkConsistency(): + print 'Problem with track before fit, not consistent',self.fitTrack[atrack] + continue + try: self.__fitter.processTrack(fitTrack[trID]) # processTrackWithRep(fitTrack[atrack],rep,True) + except: + print "genfit failed to fit track" + continue + if not fitTrack[trID].checkConsistency(): + print 'Problem with track after fit, not consistent',self.fitTrack[atrack] + continue + + stat = fitTrack[trID].getFitStatus() + if not stat.isFitConverged() : continue + f = fitTrack[trID].getFittedState() + + #if(self.__debug>0): + #print "for track ", trID, + #print " pos:", " ".join("{:10.4f}".format(f.getPos()(ii)) for ii in range(0,3)), + #print " mom:", " ".join("{:10.4f}".format(f.getMom()(ii)) for ii in range(0,3)) + self.__reFitTracks.addNewTrack(trID, f.getPos(), f.getDir(), f.getMomMag(), + stat.getNdf(), stat.getChi2()) + + + + + newFitTrIDs = self.__reFitTracks.getTrIDs() + twoTracks = ( len(newFitTrIDs)==2 ) + theStep = 0 + self.__docaEval = [] + if (twoTracks) : + self.__reFitTracks.createVertex(newFitTrIDs[0], newFitTrIDs[1], flag=0) # original + iniDoca = self.__reFitTracks.Doca + iniY = self.__reFitTracks.Vertex.Y() + while ( theStep1): + print "==>vertex ", theStep, " ", self.__reFitTracks.Doca + self.__reFitTracks.Vertex.Print() + self.__docaEval.append(self.__reFitTracks.Doca) + for tid in fitTrack : + try: + state = fitTrack[tid].getFittedState() + except: + print "can't get fittedState" + flag = -1 + vPosEx = ROOT.TVector3(0,0,0) + vMomEx = ROOT.TVector3(0,0,0) + try : + state.extrapolateToPoint(self.__reFitTracks.Vertex) + except : + flag = -1 + print "track exctrapolation failed!tid: ", tid + if (flag > 0 ) : # + status = fitTrack[tid].getFitStatus() + #print "extr track ", tid, + #print " pos:", " ".join("{:10.4f}".format(state.getPos()(ii)) for ii in range(0,3)), + #print " mom:", " ".join("{:10.4f}".format(state.getMom()(ii)) for ii in range(0,3)) + self.__reFitTracks.addNewTrack(trID, state.getPos(), state.getDir(), state.getMomMag(), + status.getNdf(), status.getChi2(), verb=False) + # FIX temporary + self.__reFitTracks.createVertex(newFitTrIDs[0], newFitTrIDs[1], flag) + self.__reFitTracks.Vertex.SetY(iniY) + theStep+=1 + twoTacks = ( len(self.__reFitTracks.getTrIDs())==2 ) + return len(newFitTrIDs) + + diff --git a/pleaseRunMe/pleaseRunMe.py b/pleaseRunMe/pleaseRunMe.py new file mode 100644 index 0000000..68a69c5 --- /dev/null +++ b/pleaseRunMe/pleaseRunMe.py @@ -0,0 +1,52 @@ +import ROOT +from ShipGeoConfig import ConfigRegistry +import shipDet_conf +from StrawHits import StrawHits + + +fileName = "ship.10.0.Pythia8-TGeant4_rec.root" +geoFile = fileName.replace('ship.','geofile_full.').replace('_rec.','.') +f = ROOT.TFile(fileName) +t = f.Get("cbmsim") + +dy = 10. + +ShipGeo = ConfigRegistry.loadpy("$FAIRSHIP/geometry/geometry_config.py", Yheight = dy ) +run = ROOT.FairRunSim() +modules = shipDet_conf.configure(run,ShipGeo) +tgeom = ROOT.TGeoManager("Geometry", "Geane geometry") +gMan = tgeom.Import(geoFile) +geoMat = ROOT.genfit.TGeoMaterialInterface() +ROOT.genfit.MaterialEffects.getInstance().init(geoMat) +volDict = {} +i=0 +for x in ROOT.gGeoManager.GetListOfVolumes(): + volDict[i]=x.GetName() + i+=1 + +bfield = ROOT.genfit.BellField(ShipGeo.Bfield.max ,ShipGeo.Bfield.z,2, ShipGeo.Yheight/2.) +fM = ROOT.genfit.FieldManager.getInstance() +fM.init(bfield) + + +sh = StrawHits(t, modules, ShipGeo.straw.resol, 0) + + +for i in xrange(min([t.GetEntries(), 50])): + t.GetEntry(i) + + if sh.readEvent()<2 : continue + + if sh.FitTracks()<2 : continue + + vertex3 = sh.getReFitVertex() + doca = sh.getDoca() + for tid in sh.getReFitTrIDs(): + vPos3, vDir3, MomVal = sh.getReFitPosDirPval(tid) + moment3 = vDir3*MomVal + ndf = sh.getReFitNdf(tid) + redChi2 = sh.getReFitChi2Ndf(tid) + print "track MCid {0:4} ndf {1:8.2f} redChi2: {2:8.2f} momVal {3:8.2f} vector".format(tid, ndf, redChi2, MomVal), + print "".join("{:8.2f}".format(moment3(ii)) for ii in range(0,3)) + print "\tvertex doca, v.x, v.y. v.z : {0:8.2f}".format(doca), + print "".join("{:8.2f}".format(vertex3(ii)) for ii in range(0,3)) \ No newline at end of file diff --git a/tools.py b/tools.py index b1b25c0..7de72c0 100755 --- a/tools.py +++ b/tools.py @@ -266,6 +266,7 @@ listOfHitLSSegments = None numberOfHitLSSegments = None +numberOfHitLSSegments_th15 = None zstarts = [] zends = [] lsNames = [] @@ -311,13 +312,16 @@ for i in xrange(nBins): EnergyDeposits.append(0.) global listOfHitLSSegments, numberOfHitLSSegments, EnergyDeposits + global numberOfHitLSSegments_th15 if savelist: tree, listOfHitLSSegments = AddVect(tree, 'listOfHitLSSegments', 'int') tree, numberOfHitLSSegments = AddVar(tree, 'numberOfHitLSSegments', 'int') + tree, numberOfHitLSSegments_th15 = AddVar(tree, 'numberOfHitLSSegments_th15', 'int') def hitSegments(vetoPoints, nodes, threshold, savelist=False): global listOfHitLSSegments, numberOfHitLSSegments, EnergyDeposits global abig, asmall, b, phistart, dphi, Nphi, nBins, zin, zout + global numberOfHitLSSegments_th15 # Init energy deposit to 0. for i in xrange(nBins): EnergyDeposits[i]=0. @@ -345,11 +349,15 @@ print x, y, z sys.exit() nHit = 0 + nHit_th15 = 0 for iBin in xrange(nBins): + if EnergyDeposits[iBin] > 0.015: + nHit_th15 +=1 if EnergyDeposits[iBin] > threshold: nHit +=1 if savelist: Push(listOfHitLSSegments, int(iBin)) Push(numberOfHitLSSegments, nHit) + Push(numberOfHitLSSegments_th15, nHit_th15)