SND@LHC Software
Loading...
Searching...
No Matches
Scifi_monitoring.Scifi_residuals Class Reference
Inheritance diagram for Scifi_monitoring.Scifi_residuals:
Collaboration diagram for Scifi_monitoring.Scifi_residuals:

Public Member Functions

 Init (self, options, monitor)
 
 ExecuteEvent (self, event)
 
 Plot (self)
 

Public Attributes

 unbiased
 
 M
 
 projs
 
 parallelToZ
 
 OT
 
 nav
 
 trackTask
 
 xing
 
 zExVeto
 
 zEx
 
 res
 

Detailed Description

Definition at line 165 of file Scifi_monitoring.py.

Member Function Documentation

◆ ExecuteEvent()

Scifi_monitoring.Scifi_residuals.ExecuteEvent (   self,
  event 
)

Definition at line 219 of file Scifi_monitoring.py.

219 def ExecuteEvent(self,event):
220 h = self.M.h
221 W = self.M.Weight
222 nav = self.nav
223 if not hasattr(event,"Cluster_Scifi"):
224 self.trackTask.scifiCluster()
225 clusters = self.trackTask.clusScifi
226 else:
227 clusters = event.Cluster_Scifi
228# overall tracking
229 MufiTracks = []
230 ScifiTracks = []
231 k = -1
232 for theTrack in self.M.Reco_MuonTracks:
233 k+=1
234 fitStatus = theTrack.getFitStatus()
235 if not fitStatus.isFitConverged(): continue
236 if theTrack.GetUniqueID()==1: ScifiTracks.append(k)
237 if theTrack.GetUniqueID()==3: MufiTracks.append(k)
238 if len(MufiTracks)==0 or len(ScifiTracks)==0: return
239 vetoHits = []
240 k = -1
241 for aHit in event.Digi_MuFilterHits:
242 k+=1
243 Minfo = self.M.MuFilter_PlaneBars(aHit.GetDetectorID())
244 s,l,bar = Minfo['station'],Minfo['plane'],Minfo['bar']
245 if s>1: continue
246 X = aHit.GetAllSignals()
247 if len(X)<5: continue # number of fired SiPMs
248 vetoHits.append(k)
249 xExTag,yExTag = -10000,-10000
250 for kMu in MufiTracks:
251 theTrack = self.M.Reco_MuonTracks[kMu]
252 fstate = theTrack.getFittedState()
253 posT,momT = fstate.getPos(),fstate.getMom()
254 slopeXT = momT.X()/momT.Z()
255 slopeYT = momT.Y()/momT.Z()
256 if not abs(slopeXT)<0.1 or not abs(slopeYT)<0.1: continue
257 lam = (self.zEx-posT.z())/momT.z()
258 yExTag = posT.y()+lam*momT.y()
259 xExTag = posT.x()+lam*momT.x()
260 # eventually require hit in veto to remove ghost tracks
261 if xExTag < -9000: return
262 ok = False
263 for k in vetoHits:
264 aHit = event.Digi_MuFilterHits[k]
265 self.M.MuFilter.GetPosition(aHit.GetDetectorID(),A,B)
266# calculate DOCA
267 lam = (self.zExVeto-posT.z())/momT.z()
268 xExV,yExV = posT.x()+lam*momT.x(),posT.y()+lam*momT.y()
269 pq = A-posT
270 uCrossv= (B-A).Cross(momT)
271 doca = pq.Dot(uCrossv)/uCrossv.Mag()
272 if abs(doca)<self.res:
273 ok=True
274 break
275 if not ok: return
276 # DS track confirmed by Veto hit
277
278 theTrack = False
279 for theTrack in self.M.Reco_MuonTracks:
280 if theTrack.GetUniqueID()==1:
281 fitStatus = theTrack.getFitStatus()
282 if fitStatus.isFitConverged():
283 state = theTrack.getFittedState()
284 pos = state.getPos()
285 mom = state.getMom()
286 slopeX = mom.X()/mom.Z()
287 slopeY = mom.Y()/mom.Z()
288 rc = h[detector+'trackChi2/ndof'].Fill(fitStatus.getChi2()/(fitStatus.getNdf()+1E-10),fitStatus.getNdf())
289 '''
290 self.M.fillHist2(detector+'trackSlopes',slopeX*1000-pos.X()/48.2,slopeY*1000-pos.Y()/48.2)
291 self.M.fillHist2(detector+'trackSlopesXL',slopeX-pos.X()/48200,slopeY-pos.Y()/48200)
292 self.M.fillHist2(detector+'trackPos',pos.X(),pos.Y())
293 if abs(slopeX)<0.1 and abs(slopeY)<0.1: self.M.fillHist2(detector+'trackPosBeam',pos.X(),pos.Y())
294 '''
295
296 if not theTrack: return
297
298 sortedClusters={}
299 for aCl in clusters:
300 so = aCl.GetFirst()//100000
301 if not so in sortedClusters: sortedClusters[so]=[]
302 sortedClusters[so].append(aCl)
303# select events with clusters in each plane for making residuals
304 if len(sortedClusters)<10: return
305 goodEvent = True
306 for s in sortedClusters:
307 if len(sortedClusters[s])>3:
308 goodEvent=False
309 break
310 if not goodEvent: return
311
312 for s in range(1,6):
313 if self.unbiased:
314# build trackCandidate
315 hitlist = {}
316 if self.unbiased or s==1:
317 k=0
318 Nproj = {0:0,1:0}
319 for so in sortedClusters:
320 if so//10 == s and self.unbiased: continue
321 Nproj[so%2]+=1
322 for x in sortedClusters[so]:
323 hitlist[k] = x
324 k+=1
325 if Nproj[0]<3 or Nproj[1]<3: continue
326 theTrack = self.trackTask.fitTrack(hitlist)
327 if not hasattr(theTrack,"getFittedState"): continue
328# check residuals
329 fitStatus = theTrack.getFitStatus()
330 if not fitStatus.isFitConverged():
331 theTrack.Delete()
332 continue
333# confirm track with DS track
334 fstate = theTrack.getFittedState()
335 pos,mom = fstate.getPos(),fstate.getMom()
336 lam = (self.zExVeto-pos.z())/mom.z()
337 yEx = pos.y()+lam*mom.y()
338 xEx = pos.x()+lam*mom.x()
339 dx = xExTag-xEx
340 dy = yExTag-yEx
341 rc = h['dx'].Fill(dx)
342 rc = h['dy'].Fill(dy)
343 if abs(dy)>self.res or abs(dx)>self.res:
344 if self.unbiased: continue
345 else: break
346
347# test plane
348 for o in range(2):
349 testPlane = s*10+o
350 z = self.M.zPos['Scifi'][testPlane]
351 rep = ROOT.genfit.RKTrackRep(13)
352 state = ROOT.genfit.StateOnPlane(rep)
353# find closest track state
354 mClose = 0
355 mZmin = 999999.
356 for m in range(0,theTrack.getNumPointsWithMeasurement()):
357 st = ROOT.getFittedState(theTrack,m)
358 if not st: break
359 Pos = st.getPos()
360 if abs(z-Pos.z())<mZmin:
361 mZmin = abs(z-Pos.z())
362 mClose = m
363 if mZmin>10000:
364 print("something wrong here with measurements",mClose,mZmin,theTrack.getNumPointsWithMeasurement())
365 break
366 fstate = theTrack.getFittedState(mClose)
367 pos,mom = fstate.getPos(),fstate.getMom()
368 rep.setPosMom(state,pos,mom)
369 NewPosition = ROOT.TVector3(0., 0., z) # assumes that plane in global coordinates is perpendicular to z-axis, which is not true for TI18 geometry.
370 rep.extrapolateToPlane(state, NewPosition, parallelToZ )
371 pos = state.getPos()
372 xEx,yEx = pos.x(),pos.y()
373 rc = h['track_Scifi'+str(testPlane)].Fill(xEx,yEx,W)
374 for aCl in sortedClusters[testPlane]:
375 aCl.GetPosition(A,B)
376 detID = aCl.GetFirst()
377 channel = detID%1000 + ((detID%10000)//1000)*128 + (detID%100000//10000)*512
378# calculate DOCA
379 pq = A-pos
380 uCrossv= (B-A).Cross(mom)
381 doca = pq.Dot(uCrossv)/uCrossv.Mag()
382 rc = h['resC'+self.projs[o]+'_Scifi'+str(testPlane)].Fill(doca/u.um,channel,W)
383 rc = h['res'+self.projs[o]+'_Scifi'+str(testPlane)].Fill(doca/u.um,W)
384 rc = h['resX'+self.projs[o]+'_Scifi'+str(testPlane)].Fill(doca/u.um,xEx,W)
385 rc = h['resY'+self.projs[o]+'_Scifi'+str(testPlane)].Fill(doca/u.um,yEx,W)
386
387 if self.unbiased: theTrack.Delete()
388
389# analysis and plots
void GetPosition(Int_t id, TVector3 &vLeft, TVector3 &vRight)
Definition MuFilter.cxx:639

◆ Init()

Scifi_monitoring.Scifi_residuals.Init (   self,
  options,
  monitor 
)

Definition at line 167 of file Scifi_monitoring.py.

167 def Init(self,options,monitor):
168 NbinsRes = options.ScifiNbinsRes
169 xmin = options.Scifixmin
170 alignPar = options.ScifialignPar
171 self.unbiased = options.ScifiResUnbiased
172
173 self.M = monitor
174 h = self.M.h
175 self.projs = {1:'V',0:'H'}
176 self.parallelToZ = ROOT.TVector3(0., 0., 1.)
177 run = ROOT.FairRunAna.Instance()
178 ioman = ROOT.FairRootManager.Instance()
179 self.OT = ioman.GetSink().GetOutTree()
180 self.nav = ROOT.gGeoManager.GetCurrentNavigator()
181 self.trackTask = self.M.FairTasks['simpleTracking']
182 if not self.trackTask: self.trackTask = run.GetTask('houghTransform')
183
184 for s in range(1,6):
185 for o in range(2):
186 for p in self.projs:
187 proj = self.projs[p]
188 xmax = -xmin
189 ut.bookHist(h,'res'+proj+'_Scifi'+str(s*10+o),'residual '+proj+str(s*10+o)+'; [#mum]',NbinsRes,xmin,xmax)
190 ut.bookHist(h,'resX'+proj+'_Scifi'+str(s*10+o),'residual '+proj+str(s*10+o)+'; [#mum]',NbinsRes,xmin,xmax,100,-50.,0.)
191 ut.bookHist(h,'resY'+proj+'_Scifi'+str(s*10+o),'residual '+proj+str(s*10+o)+'; [#mum]',NbinsRes,xmin,xmax,100,10.,60.)
192 ut.bookHist(h,'resC'+proj+'_Scifi'+str(s*10+o),'residual '+proj+str(s*10+o)+'; [#mum]',NbinsRes,xmin,xmax,128*4*3,-0.5,128*4*3-0.5)
193 ut.bookHist(h,'track_Scifi'+str(s*10+o),'track x/y '+str(s*10+o)+'; x [cm]; y [cm]',80,-70.,10.,80,0.,80.)
194 ut.bookHist(h,'dx','DS track X - scifi X; X[cm]',100,-20.,20.)
195 ut.bookHist(h,'dy','DS track Y - scifi Y; Y[cm]',100,-20.,20.)
196
197 ut.bookHist(h,detector+'trackChi2/ndof','track chi2/ndof vs ndof; #chi^{2}/Ndof; Ndof',100,0,100,20,0,20)
198# type of crossing, check for b1only,b2nob1,nobeam
199 self.xing = {'':True,'B1only':False,'B2noB1':False,'noBeam':False}
200 '''
201 for xi in self.xing:
202 if not self.M.fsdict and not self.M.hasBunchInfo and xi!='': continue
203 ut.bookHist(h,detector+'trackSlopes'+xi,'track slope; x/z [mrad]; y/z [mrad]',1000,-100,100,1000,-100,100)
204 ut.bookHist(h,detector+'trackSlopesXL'+xi,'track slope; x/z [rad]; y/z [rad]',2200,-1.1,1.1,2200,-1.1,1.1)
205 ut.bookHist(h,detector+'trackPos'+xi,'track pos; x [cm]; y [cm]',100,-90,10.,80,0.,80.)
206 ut.bookHist(h,detector+'trackPosBeam'+xi,'beam track pos slopes<0.1rad; x [cm]; y [cm]',100,-90,10.,80,0.,80.)
207 for item in h:
208 if isinstance(h[item], ROOT.TH2) and (item.find('trackPos')>0 or item.find('trackSlopes')>0):
209 h[item].SetTitleOffset(1.1, 'Y')
210 '''
211 if alignPar:
212 for x in alignPar:
213 self.M.Scifi.SetConfPar(x,alignPar[x])
214
215 self.zExVeto = self.M.zPos['MuFilter'][10]
216 self.zEx = self.M.zPos['Scifi'][10]
217 self.res = 10.
218
void SetConfPar(TString name, Float_t value)
Definition Scifi.h:46

◆ Plot()

Scifi_monitoring.Scifi_residuals.Plot (   self)

Definition at line 390 of file Scifi_monitoring.py.

390 def Plot(self):
391 h = self.M.h
392 P = {'':'','X':'colz','Y':'colz','C':'colz'}
393 Par = {'mean':1,'sigma':2}
394 h['globalPos'] = {'meanH':ROOT.TGraphErrors(),'sigmaH':ROOT.TGraphErrors(),'meanV':ROOT.TGraphErrors(),'sigmaV':ROOT.TGraphErrors()}
395 h['globalPosM'] = {'meanH':ROOT.TGraphErrors(),'sigmaH':ROOT.TGraphErrors(),'meanV':ROOT.TGraphErrors(),'sigmaV':ROOT.TGraphErrors()}
396 for x in h['globalPosM']:
397 h['globalPos'][x].SetMarkerStyle(21)
398 h['globalPos'][x].SetMarkerColor(ROOT.kBlue)
399 h['globalPosM'][x].SetMarkerStyle(21)
400 h['globalPosM'][x].SetMarkerColor(ROOT.kBlue)
401 globalPos = h['globalPos']
402 for proj in P:
403 ut.bookCanvas(h,'scifiRes'+proj,'',1600,1900,2,5)
404 k=1
405 j = {0:0,1:0}
406 for s in range(1,6):
407 for o in range(2):
408 so = s*10+o
409 tc = h['scifiRes'+proj].cd(k)
410 k+=1
411 hname = 'res'+proj+self.projs[o]+'_Scifi'+str(so)
412 h[hname].Draw(P[proj])
413 if proj == '':
414 rc = h[hname].Fit('gaus','SQ')
415 fitResult = rc.Get()
416 if not fitResult: continue
417 for p in Par:
418 globalPos[p+self.projs[o]].SetPoint(s-1,s,fitResult.Parameter(Par[p]))
419 globalPos[p+self.projs[o]].SetPointError(s-1,0.5,fitResult.ParError(1))
420 if proj == 'C':
421 for m in range(3):
422 h[hname+str(m)] = h[hname].ProjectionX(hname+str(m),m*512,m*512+512)
423 rc = h[hname+str(m)].Fit('gaus','SQ0')
424 fitResult = rc.Get()
425 if not fitResult: continue
426 for p in Par:
427 h['globalPosM'][p+self.projs[o]].SetPoint(j[o], s*10+m, fitResult.Parameter(Par[p]))
428 h['globalPosM'][p+self.projs[o]].SetPointError(j[o],0.5,fitResult.ParError(1))
429 j[o]+=1
430
431 S = ctypes.c_double()
432 M = ctypes.c_double()
433 h['alignPar'] = {}
434 alignPar = h['alignPar']
435 for p in globalPos:
436 ut.bookCanvas(h,p,p,750,750,1,1)
437 tc = h[p].cd()
438 globalPos[p].SetTitle(p+';station; offset [#mum]')
439 globalPos[p].Draw("ALP")
440 if p.find('mean')==0:
441 for n in range(globalPos[p].GetN()):
442 rc = globalPos[p].GetPoint(n,S,M)
443 print("station %i: offset %s = %5.2F um"%(S.value,p[4:5],M.value))
444 s = int(S.value*10)
445 if p[4:5] == "V": s+=1
446 alignPar["Scifi/LocD"+str(s)] = M.value
447
448 ut.bookCanvas(h,'mean&sigma',"mean and sigma",1200,1200,2,2)
449 k=1
450 for p in h['globalPosM']:
451 ut.bookCanvas(h,p+'M',p,750,750,1,1)
452 tc = h[p+'M'].cd()
453 h['globalPosM'][p].SetTitle(p+';mat ; offset [#mum]')
454 h['globalPosM'][p].Draw("ALP")
455 tc = h['mean&sigma'].cd(k)
456 h['globalPosM'][p].Draw("ALP")
457 k+=1
458 if p.find('mean')==0:
459 for n in range(h['globalPosM'][p].GetN()):
460 rc = h['globalPosM'][p].GetPoint(n,S,M)
461 print("station %i: offset %s = %5.2F um"%(S.value,p[4:5],M.value))
462 s = int(S.value*10)
463 if p[4:5] == "V": s+=1
464 alignPar["Scifi/LocM"+str(s)] = M.value
465 T = ['mean&sigma']
466 for proj in P: T.append('scifiRes'+proj)
467 for canvas in T:
468 self.M.myPrint(self.M.h[canvas],"Scifi-"+canvas,subdir='scifi/expert')
469 '''
470 for xi in self.xing:
471 if not self.M.fsdict and not self.M.hasBunchInfo and xi!='': continue
472 tname = detector+'trackDir'+xi
473 ut.bookCanvas(h,tname,"track directions",1600,1800,3,2)
474 h[tname].cd(1)
475 rc = h[detector+'trackSlopes'+xi].Draw('colz')
476 h[tname].cd(2)
477 rc = h[detector+'trackSlopes'+xi].ProjectionX("slopeX"+xi)
478 rc.Draw()
479 rc.SetTitle('track X slope')
480 h[tname].cd(3)
481 rc = h[detector+'trackSlopes'+xi].ProjectionY("slopeY"+xi)
482 rc.Draw()
483 rc.SetTitle('track Y slope')
484 h[tname].cd(4)
485 rc = h[detector+'trackSlopesXL'+xi].Draw('colz')
486 h[tname].cd(5)
487 rc = h[detector+'trackSlopesXL'+xi].ProjectionX("slopeXL"+xi)
488 rc.Draw()
489 rc.SetTitle('track X slope')
490 h[tname].cd(6)
491 rc = h[detector+'trackSlopesXL'+xi].ProjectionY("slopeYL"+xi)
492 rc.Draw()
493 rc.SetTitle('track Y slope')
494 if x=='': self.M.myPrint(self.M.h[tname],tname,subdir='scifi/shifter')
495 else: self.M.myPrint(self.M.h[tname],tname,subdir='scifi/shifter/'+xi)
496 tname = detector+'TtrackPos'+xi
497 ut.bookCanvas(h,tname,"track position first state",600,1200,1,2)
498 h[tname].cd(1)
499 rc = h[detector+'trackPosBeam'+xi].Draw('colz')
500 h[tname].cd(2)
501 rc = h[detector+'trackPos'+xi].Draw('colz')
502 if x=='': self.M.myPrint(self.M.h[tname],detector+'trackPos'+xi,subdir='scifi/shifter')
503 else: self.M.myPrint(self.M.h[tname],detector+'trackPos'+xi,subdir='scifi/shifter/'+xi)
504 '''
505

Member Data Documentation

◆ M

Scifi_monitoring.Scifi_residuals.M

Definition at line 173 of file Scifi_monitoring.py.

◆ nav

Scifi_monitoring.Scifi_residuals.nav

Definition at line 180 of file Scifi_monitoring.py.

◆ OT

Scifi_monitoring.Scifi_residuals.OT

Definition at line 179 of file Scifi_monitoring.py.

◆ parallelToZ

Scifi_monitoring.Scifi_residuals.parallelToZ

Definition at line 176 of file Scifi_monitoring.py.

◆ projs

Scifi_monitoring.Scifi_residuals.projs

Definition at line 175 of file Scifi_monitoring.py.

◆ res

Scifi_monitoring.Scifi_residuals.res

Definition at line 217 of file Scifi_monitoring.py.

◆ trackTask

Scifi_monitoring.Scifi_residuals.trackTask

Definition at line 181 of file Scifi_monitoring.py.

◆ unbiased

Scifi_monitoring.Scifi_residuals.unbiased

Definition at line 171 of file Scifi_monitoring.py.

◆ xing

Scifi_monitoring.Scifi_residuals.xing

Definition at line 199 of file Scifi_monitoring.py.

◆ zEx

Scifi_monitoring.Scifi_residuals.zEx

Definition at line 216 of file Scifi_monitoring.py.

◆ zExVeto

Scifi_monitoring.Scifi_residuals.zExVeto

Definition at line 215 of file Scifi_monitoring.py.


The documentation for this class was generated from the following file: