145 planesPerProjection = {0:0,1:0}
148 stations[s*10+p] = {}
149 clusPerStation[s*10+p] = 0
153 detID = aCl.GetFirst()
154 if detID//10000 < 3:
continue
162 stations[plane][k] = aCl
163 clusPerStation[plane] +=1
164 for p
in clusPerStation:
165 if clusPerStation[p]>0:
166 planesPerProjection[p%2]+=1
169 if planesPerProjection[1]<self.
DSnPlanes or planesPerProjection[0]<self.
DSnPlanes:
return trackCandidates
170 if self.
DSnPlanes==2
and (planesPerProjection[1]==2
or planesPerProjection[0]==2):
172 for p
in clusPerStation:
173 if clusPerStation[p]>1:
176 if failed:
return trackCandidates
179 for k
in stations[p]: hitlist[k] = stations[p][k]
180 trackCandidates.append(hitlist)
181 return trackCandidates
183 for p
in clusPerStation:
184 if clusPerStation[p]>self.
DSnHits:
return trackCandidates
193 for proj
in range(2):
195 if not plane%2==proj:
continue
196 if clusPerStation[s*10+plane]==1:
199 if seed < 0:
return trackCandidates
200 combinations[proj] = {}
201 for kA
in stations[seed]:
202 clA = stations[seed][kA]
207 if not p2%2==proj:
continue
209 if planeB == seed:
continue
210 l = len(stations[planeB])
211 if l>0: clInPlane[planeB] = l
212 srt = sorted(clInPlane)
213 if len(stations[srt[0]])+len(stations[srt[1]]) > self.
DSnHits+1:
return trackCandidates
215 for kB
in stations[planeB]:
216 clB = stations[planeB][kB]
221 lam = delBA[1]/delBA[2]
222 b = posA[1]-lam*posA[2]
224 lam = delBA[0]/delBA[2]
225 b = posA[0]-lam*posA[2]
227 if not p3%2==proj:
continue
229 if planeC == seed
or planeC == planeB:
continue
230 for kC
in stations[planeC]:
231 clC = stations[planeC][kC]
235 if proj==0: res = abs(eX-posC[1])
236 else: res = abs(eX-posC[0])
237 if proj==0: combinations[proj][res] = [[seed,kA],[planeB,kB],[planeC,kC]]
240 if not p4%2==proj:
continue
242 if planeD == seed
or planeD == planeB
or planeD == planeC:
continue
243 if len(stations[planeD])==0:
244 combinations[proj][res] = [[seed,kA],[planeB,kB],[planeC,kC]]
245 for kD
in stations[planeD]:
246 clD = stations[planeD][kD]
250 if proj==0: res+= abs(eX-posD[1])
251 else: res+= abs(eX-posD[0])
252 combinations[proj][res] = [[seed,kA],[planeB,kB],[planeC,kC],[planeD,kD]]
254 srt = sorted(combinations[proj])[0]
255 for x
in combinations[proj][srt]:
256 hitlist[x[1]] = stations[x[0]][x[1]]
257 trackCandidates.append(hitlist)
258 return trackCandidates
266 projClusters = {0:{},1:{}}
269 stations[s*10+o] = []
272 detID = cl.GetFirst()
274 o = (detID//100000)%10
276 stations[s*10+o].append(detID)
277 projClusters[o][detID] = [cl,k]
285 if len(stations[s*10+o]) > self.
nClusters:
286 ignore.append(s*10+o)
287 elif len(stations[s*10+o]) > 0 :
289 nclusters+=len(stations[s*10+o])
291 if len(check[0])<self.
nPlanes or len(check[1])<self.
nPlanes:
return trackCandidates
299 sortedClusters[o]=sorted(projClusters[o])
304 for detID
in sortedClusters[o]:
306 if (s*10+o)
in ignore:
continue
309 projClusters[o][detID][0].GetPosition(A,B)
311 if o==0: y = (A[1]+B[1])/2.
312 else: y = (A[0]+B[0])/2.
313 points[detID] = [z,y]
319 mean[s][n]=mean[s][n]/mean[s][2]
320 g.AddPoint(mean[s][0],mean[s][1])
321 rc = g.Fit(
'pol1',
'SQ')
322 fun = g.GetFunction(
'pol1')
326 res = abs(y-fun.Eval(z))/self.
sigma
328 k = projClusters[o][detID][1]
329 hitlist[k] = projClusters[o][detID][0]
331 if check[0]>2
and check[1]>2:
332 trackCandidates.append(hitlist)
333 return trackCandidates
339 for k
in range(self.
event.Digi_ScifiHits.GetEntries()):
340 d = self.
event.Digi_ScifiHits[k]
341 if not d.isValid():
continue
342 hitDict[d.GetDetectorID()] = k
343 hitList = list(hitDict.keys())
349 last = len(hitList)-1
350 hitvector = ROOT.std.vector(
"sndScifiHit*")()
351 for i
in range(len(hitList)):
352 if i==0
and len(hitList)>1:
continue
358 if not neighbour
or c==hitList[last]:
362 for aHit
in tmp: hitvector.push_back( self.
event.Digi_ScifiHits[hitDict[aHit]])
363 aCluster = ROOT.sndCluster(first,N,hitvector,self.
scifiDet,
False)
364 clusters.append(aCluster)
370 hitvector.push_back( self.
event.Digi_ScifiHits[hitDict[c]])
371 aCluster = ROOT.sndCluster(c,1,hitvector,self.
scifiDet,
False)
372 clusters.append(aCluster)
378 for nHit
in range(self.
event.Digi_ScifiHits.GetEntries()):
379 if self.
event.Digi_ScifiHits[nHit].GetDetectorID()==c.GetFirst():
385 for k
in range(self.
event.Digi_MuFilterHits.GetEntries()):
386 d = self.
event.Digi_MuFilterHits[k]
387 if (d.GetDetectorID()//10000)<3
or (
not d.isValid()):
continue
388 hitDict[d.GetDetectorID()] = k
389 hitList = list(hitDict.keys())
395 last = len(hitList)-1
396 hitvector = ROOT.std.vector(
"MuFilterHit*")()
397 for i
in range(len(hitList)):
398 if i==0
and len(hitList)>1:
continue
401 if (c-cprev)==1
or (c-cprev)==2:
404 if not neighbour
or c==hitList[last]
or c%1000==59:
408 for aHit
in tmp: hitvector.push_back( self.
event.Digi_MuFilterHits[hitDict[aHit]])
409 aCluster = ROOT.sndCluster(first,N,hitvector,self.
mufiDet,
False)
410 clusters.append(aCluster)
416 hitvector.push_back( self.
event.Digi_MuFilterHits[hitDict[c]])
417 aCluster = ROOT.sndCluster(c,1,hitvector,self.
mufiDet,
False)
418 clusters.append(aCluster)
421 for c
in clusters: self.
clusMufi.Add(c)
458 posM = ROOT.TVector3(0, 0, 0.)
459 momM = ROOT.TVector3(0,0,100.)
462 covM = ROOT.TMatrixDSym(6)
465 if hasattr(aCl,
"GetFirst"):
466 detID = aCl.GetFirst()
468 detID = aCl.GetDetectorID()
473 for i
in range(3): covM[i][i] = res*res
474 for i
in range(3,6): covM[i][i] = ROOT.TMath.Power(res / (4.*2.) / ROOT.TMath.Sqrt(3), 2)
475 rep = ROOT.genfit.RKTrackRep(13)
478 state = ROOT.genfit.MeasuredStateOnPlane(rep)
479 rep.setPosMomCov(state, posM, momM, covM)
482 seedState = ROOT.TVectorD(6)
483 seedCov = ROOT.TMatrixDSym(6)
484 rep.get6DStateCov(state, seedState, seedCov)
485 theTrack = ROOT.genfit.Track(rep, seedState, seedCov)
490 A,B = ROOT.TVector3(),ROOT.TVector3()
493 if hasattr(aCl,
"GetFirst"):
494 detID = aCl.GetFirst()
497 if detID<40000: detSys=3
499 detID = aCl.GetDetectorID()
501 if detID<40000: detSys=3
502 if detSys==3: self.
mufiDet.GetPosition(detID,A,B)
503 if detSys==1: self.
scifiDet.GetSiPMPosition(detID,A,B)
505 tmp = array(
'd',[A[0],A[1],A[2],B[0],B[1],B[2],distance])
506 unSortedList[A[2]] = [ROOT.TVectorD(7,tmp),detID,k,detSys]
507 sorted_z=list(unSortedList.keys())
510 tp = ROOT.genfit.TrackPoint()
511 hitCov = ROOT.TMatrixDSym(7)
512 detSys = unSortedList[z][3]
522 hitCov[6][6] = res*res
523 measurement = ROOT.genfit.WireMeasurement(unSortedList[z][0],hitCov,1,6,tp)
524 measurement.setMaxDistance(maxDis)
525 measurement.setDetId(unSortedList[z][1])
526 measurement.setHitId(unSortedList[z][2])
527 tp.addRawMeasurement(measurement)
528 theTrack.insertPoint(tp)
529 if not theTrack.checkConsistency():
530 print(
"track not consistent")
534 self.
fitter.processTrack(theTrack)
535 fitStatus = theTrack.getFitStatus()
536 if self.
Debug: print(
"Fit result: converged chi2 Ndf",fitStatus.isFitConverged(),fitStatus.getChi2(),fitStatus.getNdf())
537 if not fitStatus.isFitConverged()
and 0>1:
541 chi2 = fitStatus.getChi2()/(fitStatus.getNdf()+1E-15)
542 fittedState = theTrack.getFittedState()
543 P = fittedState.getMomMag()
544 print(
"track fitted Ndf #Meas P",fitStatus.getNdf(), theTrack.getNumPointsWithMeasurement(),P)
545 for p
in theTrack.getPointsWithMeasurement():
546 rawM = p.getRawMeasurement()
547 info = p.getFitterInfo()
548 if not info:
continue
549 detID = rawM.getDetId()
550 print(detID,
"weights",info.getWeights()[0],info.getWeights()[1],fitStatus.getNdf())
554 if theTrack.GetUniqueID()>1:
return False
555 fitStatus = theTrack.getFitStatus()
556 if not fitStatus.isFitConverged() :
return [100,-100]
557 state = ROOT.getFittedState(theTrack,0)
562 pos1 = ROOT.TVector3(pos.x()+lam*mom.x(),pos.y()+lam*mom.y(),self.
firstScifi_z)
566 for nM
in range(theTrack.getNumPointsWithMeasurement()):
567 state = ROOT.getFittedState(theTrack,nM)
568 if not state:
continue
569 posM = state.getPos()
570 M = theTrack.getPointWithMeasurement(nM)
571 W = M.getRawMeasurement()
576 self.
scifiDet.GetSiPMPosition(detID,A,B)
577 if aHit.isVertical(): X = B-posM
581 corTime = self.
scifiDet.GetCorrectedTime(detID, aCl.GetTime(), 0)
582 trajLength = (posM-pos1).Mag()
583 T = corTime - L - trajLength/u.speedOfLight
584 self.
Tline.AddPoint(trajLength,T)
585 rc = self.
Tline.Fit(
'pol1',
'SQ')
587 slope = fitResult.Parameter(1)
588 return [slope,slope/(fitResult.ParError(1)+1E-13),fitResult.Parameter(0)]
590 def multipleTrackCandidates(self,planesWithClusters=10,nMaxCl=8,dGap=0.2,dMax=0.8,dMax3=0.8,ovMax = 1,doublet=True,debug=False):
591 A,B = ROOT.TVector3(),ROOT.TVector3()
593 h[
'trackCand'] = {0:{},1:{}}
594 h[
'sortedClusters'] = {}
595 sortedClusters = h[
'sortedClusters']
599 so = aCl.GetFirst()//100000
600 if not so
in sortedClusters:
601 sortedClusters[so]=[]
603 if aCl.GetFirst()//100000%10 == 0: pos = A[1]
605 sortedClusters[so].append([pos,A[2],aCl])
607 if len(sortedClusters)<planesWithClusters:
return
609 h[
'mergedClusters'] = {}
610 mergedClusters = h[
'mergedClusters']
611 for so
in sortedClusters:
613 mergedClusters[so]=[]
614 for k
in range(len(sortedClusters[so])):
615 pos[k] = sortedClusters[so][k][0]
616 sorted_pos = sorted(pos.items(), key=
lambda x: x[1])
618 for i
in range(len(sorted_pos)):
620 aClobj = sortedClusters[so][x[0]]
623 mergedClusters[so].append( [aClobj[0],aClobj[1],[aClobj[2]]] )
625 prevPos = mergedClusters[so][merged][0]
627 if pos-prevPos > dGap:
629 mergedClusters[so].append( [aClobj[0],aClobj[1],[aClobj[2]]] )
631 N = len(mergedClusters[so][merged][2])
632 newPos = (prevPos*N+pos)/(N+1)
633 mergedClusters[so][merged][0]=newPos
634 mergedClusters[so][merged][2].append(aClobj[2])
636 for so
in mergedClusters:
637 if len(mergedClusters[so]) > nMaxCl:
return
638 if len(mergedClusters[so]) < 2:
return
640 if debug: print(
'-------- p=',p)
644 for j1
in range(1,5):
645 h[
'doublet'][j1] = {}
646 for k1
in range(len(mergedClusters[j1*10+p])):
647 aCl1 = mergedClusters[j1*10+p][k1]
648 h[
'doublet'][j1][k1] = []
650 for k2
in range(len(mergedClusters[j2*10+p])):
651 aCl2 = mergedClusters[j2*10+p][k2]
653 if debug: print(j1,j2,
'x1',aCl1[0],
'x2',aCl2[0],
'D',D)
654 if abs(D ) > dMax:
continue
655 h[
'doublet'][j1][k1].append(10*j2+k2)
656 if len(h[
'doublet'][j1][k1]) == 0
and j2<5:
658 for k2
in range(len(mergedClusters[j2*10+p])):
659 aCl2 = mergedClusters[j2*10+p][k2]
661 if debug: print(j1,j2,
'x1',aCl1[0],
'x2',aCl2[0],
'D',D)
662 if abs(D ) > dMax:
continue
663 h[
'doublet'][j1][k1].append(10*j2+k2)
664 h[
'trackCand'][p] = {}
666 for k1
in h[
'doublet'][j1]:
669 for k0
in h[
'doublet'][1]:
670 for sk0
in h[
'doublet'][1][k0]:
674 if alreadyUsed:
continue
675 trackId = (k1+1)*10**(j1-1)
676 if debug: print(j1,k1,trackId)
677 for sk2
in h[
'doublet'][j1][k1]:
680 trackId = (k1+1)*10**(j1-1) + (k2+1)*10**(j2-1)
681 if debug: print(j2,k2,trackId)
682 for sk3
in h[
'doublet'][j2][k2]:
686 trackId = (k1+1)*10**(j1-1) + (k2+1)*10**(j2-1) + (k3+1)*10**(j3-1)
687 if debug: print(j3,k3,trackId)
688 for sk4
in h[
'doublet'][j3][k3]:
691 trackId = (k1+1)*10**(j1-1) + (k2+1)*10**(j2-1) + (k3+1)*10**(j3-1) + (k4+1)*10**(j4-1)
692 if debug: print(j4,k4,trackId)
695 for sk5
in h[
'doublet'][j4][k4]:
699 trackId = (k1+1)*10**(j1-1) + (k2+1)*10**(j2-1) + (k3+1)*10**(j3-1) + (k4+1)*10**(j4-1) + (k5+1)*10**(j5-1)
700 h[
'trackCand'][p][trackId] = ROOT.TGraph()
702 h[
'trackCand'][p][trackId] = ROOT.TGraph()
703 for trackId
in h[
'trackCand'][p]:
706 k = (trackId//10**(s-1))%10-1
709 aCl = mergedClusters[s*10+p][k]
710 h[
'trackCand'][p][trackId].SetPoint(N,aCl[1],aCl[0])
713 for k1
in range(len(mergedClusters[10+p])):
714 aCl1 = mergedClusters[10+p][k1]
715 for k2
in range(len(mergedClusters[20+p])):
716 aCl2 = mergedClusters[20+p][k2]
718 if debug: print(2,
'x1',aCl1[0],
'x2',aCl2[0],
'D',D)
719 if abs(D) > dMax:
continue
720 for k3
in range(len(mergedClusters[30+p])):
721 aCl3 = mergedClusters[30+p][k3]
722 D3 = 2*D+aCl1[0]-aCl3[0]
723 if debug: print(3,
'x1',aCl1[0],
'x2',aCl2[0],
'x3',aCl3[0],
'D',D,
'D3',D3)
724 if abs(D3) > dMax3:
continue
725 trackId = 1000+100*k3+10*k2+k1
727 h[
'trackCand'][p][trackId]=ROOT.TGraph()
728 h[
'trackCand'][p][trackId].SetPoint(0,aCl1[1],aCl1[0])
729 h[
'trackCand'][p][trackId].SetPoint(1,aCl2[1],aCl2[0])
730 h[
'trackCand'][p][trackId].SetPoint(2,aCl3[1],aCl3[0])
731 extr4 = h[
'trackCand'][p][trackId].Eval(aCl3[1]+self.
dZ)
732 for k4
in range(len(mergedClusters[40+p])):
733 aCl4 = mergedClusters[40+p][k4]
735 if debug: print(4,
'D4',D4,
'x4',aCl4[0],
'extr',extr4)
736 if abs(D4) > dMax3:
continue
737 trackId = 10000+1000*k4+100*k3+10*k2+k1
739 if debug: print(4,trackId)
740 h[
'trackCand'][p][trackId] = h[
'trackCand'][p][trackId3].Clone()
741 h[
'trackCand'][p][trackId].SetPoint(3,aCl4[1],aCl4[0])
742 extr5 = h[
'trackCand'][p][trackId].Eval(aCl4[1]+self.
dZ)
743 for k5
in range(len(mergedClusters[50+p])):
744 aCl5 = mergedClusters[50+p][k5]
746 if debug: print(5,
'D5',D5,
'x5',aCl5[0],
'extr',extr5)
747 if abs(D5) > dMax3:
continue
748 trackId = 100000+10000*k5+1000*k4+100*k3+10*k2+k1
749 h[
'trackCand'][p][trackId] = h[
'trackCand'][p][trackId4].Clone()
750 h[
'trackCand'][p][trackId].SetPoint(4,aCl5[1],aCl5[0])
751 if debug: print(
'final',trackId)
754if more than 2 clusters are shared by a track, take the track with better chi2
756 h[
'cloneCand'] = {0:[],1:[]}
757 discarded = h[
'cloneCand']
759 keys = list(h[
'trackCand'][p])
760 for k1
in range( len(keys)-1):
761 if keys[k1] < 100000
and not doublet:
continue
762 if keys[k1]
in discarded[p]:
continue
763 if doublet: test1 = str(keys[k1]).zfill(5)
764 else: test1 = str(keys[k1]%100000).zfill(5)
765 for k2
in range(k1+1,len(keys) ):
766 if keys[k2] < 100000
and not doublet:
continue
767 if keys[k2]
in discarded[p]:
continue
768 if doublet: test2 = str(keys[k2]).zfill(5)
769 else: test2 = str(keys[k2]%100000).zfill(5)
772 if test1[i]==test2[i]: ov+=1
774 if doublet
and test1.find(
'0')<0
and not test2.find(
'0')<0: discarded[p].append(keys[k2])
775 elif doublet
and test2.find(
'0')<0
and not test1.find(
'0')<0: discarded[p].append(keys[k1])
777 rc1 = h[
'trackCand'][p][keys[k1]].Fit(
'pol1',
'QS')
778 rc2 = h[
'trackCand'][p][keys[k2]].Fit(
'pol1',
'QS')
779 if rc1.Get().Chi2() < rc2.Get().Chi2(): discarded[p].append(keys[k2])
780 else: discarded[p].append(keys[k1])