SND@LHC Software
Loading...
Searching...
No Matches
ScifiCTR.py
Go to the documentation of this file.
1import os,atexit
2import shipunit as u
3import rootUtils as ut
4import ROOT
5import ctypes
6import pickle
7import SndlhcGeo
8from array import array
9def pyExit():
10 print("Make suicide until solution found for freezing")
11 os.system('kill '+str(os.getpid()))
12atexit.register(pyExit)
13
14# supress on-screen histogram drawing
15ROOT.gROOT.SetBatch(ROOT.kTRUE)
16
17A,B=ROOT.TVector3(),ROOT.TVector3()
18
19def FCN(npar, gin, f, par, iflag):
20#calculate chisquare
21 chisq = 0
22 X = ROOT.gROOT.FindObjectAny('commonBlock')
23 for matH in range(nMats):
24 for matV in range(nMats):
25 tdiff = X.GetBinContent(matH*10+matV)
26 d = tdiff - (par[matH] - par[matV+nMats])
27 chisq += d**2
28 f.value = chisq
29 return
30
31def FCNS(npar, gin, f, par, iflag):
32#calculate chisquare
33 chisq = 0
34 X = ROOT.gROOT.FindObjectAny('commonBlock')
35 for s1 in range(1, nStations+1):
36 for s2 in range(s1+1, nStations+1):
37 tdiff = X.GetBinContent(s1*10+s2)
38 d = tdiff - (par[s2-1] - par[s1-1])
39 chisq += d**2
40 f.value = chisq
41 return
42
43class Scifi_CTR(ROOT.FairTask):
44 " time resolution comparing X/Y in same station"
45 def Init(self,monitor):
46 self.M = monitor
47 h = self.M.h
48 self.projs = {1:'V',0:'H'}
49
50 # setup geometry
51 if (options.geoFile).find('../')<0: self.snd_geo = SndlhcGeo.GeoInterface(options.path+options.geoFile)
52 else: self.snd_geo = SndlhcGeo.GeoInterface(options.geoFile[3:])
53 self.MuFilter = self.snd_geo.modules['MuFilter']
54 self.Scifi = self.snd_geo.modules['Scifi']
55
56 self.tag = monitor.iteration
57 tag = self.tag
58 for s in range(1, nStations+1):
59 ut.bookHist(h,'CTR_Scifi'+str(s)+tag,'CTR '+str(s)+tag+'; dt [ns]; ',100,-5.,5.)
60 ut.bookHist(h,'CTR_Scifi_beam'+str(s)+tag,'CTR beam'+str(s)+tag+'; dt [ns]; ',100,-5.,5.)
61 ut.bookHist(h,'dT_posxV'+str(s)+tag,'; x [cm]; dt [ns]',100,-50.,-30., 100,-5.,5.)
62 ut.bookHist(h,'dT_posxH'+str(s)+tag,'; x [cm]; dt [ns]',100,-50.,-30., 100,-5.,5.)
63 ut.bookHist(h,'dT_posyH'+str(s)+tag,'; y [cm]; dt [ns]',100,35,55., 100,-5.,5.)
64 ut.bookHist(h,'dT_posyV'+str(s)+tag,'; y [cm]; dt [ns]',100,35,55., 100,-5.,5.)
65 ut.bookHist(h,'CTR_timeH_posy_Scifi'+str(s)+tag,'CTR '+str(s)+tag+'; y [cm]; cluster time [ns]; ',100,35,55,100,-5.,15.)
66 ut.bookHist(h,'CTR_timeV_posy_Scifi'+str(s)+tag,'CTR '+str(s)+tag+'; y [cm]; cluster time [ns]; ',100,35,55,100,-5.,15.)
67
68 for matH in range(nMats):
69 for matV in range(nMats):
70 ut.bookHist(h,'CTR_Scifi'+str(s*100+10*matH+matV)+tag,'CTR '+str(s)+tag+'; dt [ns]; ',100,-5.,5.)
71 ut.bookHist(h,'CTR_Scifi_beam'+str(s*100+10*matH+matV)+tag,'CTR beam'+str(s)+tag+'; dt [ns]; ',100,-5.,5.)
72
73 # For the testbeam 2024, perform time alignment per channel in Scifi 2H
74 if s==2 and channelTimeAlignment==1:
75 for arr in range(nSiPMArrays):
76 for chan in range(nChannelsPerSiPMArray):
77 detid = int(s*1e6+0*1e5+matH*1e4+arr*1e3+chan)
78 ut.bookHist(h,'CTR_ScifiMat'+str(detid)+tag,'CTR mat '+str(detid)+tag+'; dt [ns]; ',100,-5.,5.)
79
80 for p in self.projs:
81 ut.bookHist(h,'res'+str(s)+self.projs[p],'d; [cm]; ',100,-1.,1.)
82 ut.bookHist(h,'resX'+str(s)+self.projs[p],'d; [cm]; ',100,-1.,1.)
83 ut.bookHist(h,'extrap'+str(s)+self.projs[p],'SiPM distance; L [cm]; ',100,0.,50.)
84
85 for s1 in range(1, nStations):
86 for s2 in range(s1+1, nStations+1):
87 ut.bookHist(h,'CTR_ScifiStation'+str(s1*10+s2)+tag,'CTR station'+str(s1*10+s2)+'; dt [ns]; ',100,-5.,5.)
88 ut.bookHist(h,'CTR_ScifiStation_beam'+str(s1*10+s2)+tag,'CTR station beam'+str(s1*10+s2)+'; dt [ns]; ',100,-5.,5.)
89
90 if channelTimeAlignment==1 and tag == "v0prime":
92 for s in range(1, nStations+1):
93 if nMats == 1 :
94 self.tdcScifiStationCalib[s] = [0,{'H': [0, {arr: {ch: 0 for ch in range(nChannelsPerSiPMArray)} for arr in range(nSiPMArrays)},],\
95 'V': [0, {arr: {ch: 0 for ch in range(nChannelsPerSiPMArray)} for arr in range(nSiPMArrays)},],},]
96 if nMats == 3:
97 self.tdcScifiStationCalib[s] = [0,{'H':{0:0,1:0,2:0},'V':{0:0,1:0,2:0}}]
98 elif channelTimeAlignment==0 and tag == "v0":
99 self.tdcScifiStationCalib = {}
100 for s in range(1, nStations+1):
101 if nMats == 1 :
102 self.tdcScifiStationCalib[s] = [0,{'H':{0:0},'V':{0:0}}]
103 if nMats == 3:
104 self.tdcScifiStationCalib[s] = [0,{'H':{0:0,1:0,2:0},'V':{0:0,1:0,2:0}}]
105 else:
106 with open('ScifiTimeAlignment_'+self.tag, 'rb') as fh:
107 self.tdcScifiStationCalib = pickle.load(fh)
108
109 self.V = M.Scifi.GetConfParF("Scifi/signalSpeed")
110
111 def ExecuteEvent(self,event):
112 h = self.M.h
113 tag = self.tag
114 DetID2Key={}
115 for nHit in range(event.Digi_ScifiHits.GetEntries()):
116 DetID2Key[event.Digi_ScifiHits[nHit].GetDetectorID()] = nHit
117
118 for aTrack in self.M.Reco_MuonTracks:
119 if not aTrack.GetUniqueID()==1: continue
120 fitStatus = aTrack.getFitStatus()
121 if not fitStatus.isFitConverged(): continue
122 state = aTrack.getFittedState()
123 mom = state.getMom()
124 slopeX = mom.X()/mom.Z()
125 slopeY = mom.Y()/mom.Z()
126 sortedClusters={}
127#
128 pos = {}
129 for s in range(1, nStations+1): sortedClusters[s] = {'H':[],'V':[]}
130 for nM in range(aTrack.getNumPointsWithMeasurement()):
131 state = aTrack.getFittedState(nM)
132 Meas = aTrack.getPointWithMeasurement(nM)
133 W = Meas.getRawMeasurement()
134 clkey = W.getHitId()
135 aCl = self.M.trackTask.clusScifi[clkey]
136 aHit = event.Digi_ScifiHits[DetID2Key[aCl.GetFirst()]]
137 detID = aCl.GetFirst()
138 s = detID//1000000
139 aCl.GetPosition(A,B)
140 mat = (detID//10000)%10
141 if aHit.isVertical():
142 L = B[1]-state.getPos()[1]
143 sortedClusters[s]['V'].append( [clkey,L,B[0],state.getPos()[1],mat,(A[2]+B[2])/2.,state.getPos()[0],aCl.GetFirst(),aCl.GetTime()] )
144 rc = h['res'+str(s)+'V'].Fill( (A[0]+B[0])/2.-state.getPos()[0])
145 else:
146 L = A[0]-state.getPos()[0]
147 sortedClusters[s]['H'].append( [clkey,L,A[1],state.getPos()[0],mat,(A[2]+B[2])/2.,state.getPos()[1],aCl.GetFirst(),aCl.GetTime()] )
148 rc = h['res'+str(s)+'H'].Fill( (A[1]+B[1])/2.-state.getPos()[1])
149 # find station with exactly 1 x and 1 y cluster:
150 for s in range(1, nStations+1):
151 if not (len(sortedClusters[s]['V']) * len(sortedClusters[s]['H']) ) ==1: continue
152 timeCorr = {}
153 for proj in ['V','H']:
154 clkey = sortedClusters[s][proj][0][0]
155 aCl = self.M.trackTask.clusScifi[clkey]
156 L = sortedClusters[s][proj][0][1]
157 rc = h['extrap'+str(s)+proj].Fill(abs(L))
158 time = aCl.GetTime() # Get time in ns, use fastest TDC of cluster
159 if M.options.check: time = self.M.Scifi.GetCorrectedTime(aCl.GetFirst(),aCl.GetTime(),0)
160 mat = sortedClusters[s][proj][0][4]
161 sipm_array = int(sortedClusters[s][proj][0][7]/1000)%10
162 sipm_channel = sortedClusters[s][proj][0][7]%1000
163 if channelTimeAlignment==1 and s==2 and proj=='H':# apply the corrections per channel
164 time-= self.tdcScifiStationCalib[s][1][proj][1][sipm_array][sipm_channel]
165 time-= self.tdcScifiStationCalib[s][1][proj][mat]
166 time-= self.tdcScifiStationCalib[s][0]
167 timeCorr[proj] = time - abs(L)/self.V
168 # print(s,proj,time,L,L/self.V)
169 dt = timeCorr['H'] - timeCorr['V']
170 rc = h['CTR_Scifi'+str(s)+tag].Fill(dt)
171 for proj in ['V','H']:
172 if proj=='V': o=1
173 else: o=0
174 if channelTimeAlignment==1 and s==2 and proj=='H': # plots for the corrections per channel
175 rc = h['CTR_ScifiMat'+str(sortedClusters[s][proj][0][7])+tag].Fill(dt)
176 rc=h['dT_posxV'+str(s)+tag].Fill(sortedClusters[s]['V'][0][6],dt)
177 rc=h['dT_posxH'+str(s)+tag].Fill(sortedClusters[s]['H'][0][3],dt)
178 rc=h['dT_posyH'+str(s)+tag].Fill(sortedClusters[s]['H'][0][6], dt)
179 rc=h['dT_posyV'+str(s)+tag].Fill(sortedClusters[s]['V'][0][3], dt)
180 rc=h['CTR_timeH_posy_Scifi'+str(s)+tag].Fill(sortedClusters[s]['H'][0][6], sortedClusters[s][proj][0][8])
181 rc=h['CTR_timeV_posy_Scifi'+str(s)+tag].Fill(sortedClusters[s]['V'][0][3],sortedClusters[s][proj][0][8])
182
183 matH,matV = sortedClusters[s]['H'][0][4],sortedClusters[s]['V'][0][4]
184 rc = h['CTR_Scifi'+str(100*s+10*matH+matV)+tag].Fill(dt)
185 if abs(slopeX)<0.1 and abs(slopeY)<0.1:
186 rc = h['CTR_Scifi_beam'+str(s)+tag].Fill(dt)
187 rc = h['CTR_Scifi_beam'+str(100*s+10*matH+matV)+tag].Fill(dt)
188 dR = sortedClusters[s]['V'][0][2] - sortedClusters[s]['H'][0][3]
189 rc = h['resX'+str(s)+'V'].Fill(dR)
190 dR = sortedClusters[s]['H'][0][2]-sortedClusters[s]['V'][0][3]
191 rc = h['resX'+str(s)+'H'].Fill(dR)
192
193 if tag!='v0' and tag!='v0prime':
194 stationTimes = {}
195 for s in range(1, nStations+1):
196 if not (len(sortedClusters[s]['V']) * len(sortedClusters[s]['H']) ) ==1: continue
197 sTime = 0
198 for proj in ['V','H']:
199 clkey = sortedClusters[s][proj][0][0]
200 aCl = self.M.trackTask.clusScifi[clkey]
201 L = sortedClusters[s][proj][0][1]
202 time = aCl.GetTime() # Get time in ns, use fastest TDC of cluster
203 if M.options.check: time = self.M.Scifi.GetCorrectedTime(aCl.GetFirst(),aCl.GetTime(),0)
204 mat = sortedClusters[s][proj][0][4]
205 time-= self.tdcScifiStationCalib[s][1][proj][mat]
206 time-= self.tdcScifiStationCalib[s][0]
207 time-= abs(L)/self.V
208 sTime += time
209 stationTimes[s] = [sTime/2.,(sortedClusters[s]['H'][0][5] + sortedClusters[s]['V'][0][5])/2.]
210 for s1 in range(1, nStations):
211 if not s1 in stationTimes: continue
212 for s2 in range(s1+1, nStations+1):
213 if not s2 in stationTimes: continue
214 dT = stationTimes[s2][0] - stationTimes[s1][0]
215# correct for slope
216 dZ = stationTimes[s2][1] - stationTimes[s1][1]
217 dL = dZ * ROOT.TMath.Sqrt( slopeX**2+slopeY**2+1 )
218 if slopeY>0.1: dL = -dL # cosmics from the back
219 dT -= dL / u.speedOfLight
220 rc = h['CTR_ScifiStation'+str(s1*10+s2)+tag].Fill(dT)
221 if abs(slopeX)<0.1 and abs(slopeY)<0.1:
222 rc = h['CTR_ScifiStation_beam'+str(s1*10+s2)+tag].Fill(dT)
223
224 def Plot(self):
225 h = self.M.h
226 tag = self.tag
227
228 if channelTimeAlignment==1:
229 for s in range(1, nStations+1):
230 for proj in ['H','V']:
231 if proj=='H': o=0
232 else: o=1
233 if s!=2 or proj!='H': continue
234 ut.bookCanvas(h,'CTR_mats'+str(s)+proj+tag,'CTR'+tag,1800,1200,32,16)
235 j=1
236 for mat in range(nMats):
237 for arr in range(nSiPMArrays):
238 for chan in range(nChannelsPerSiPMArray):
239 tc = h['CTR_mats'+str(s)+proj+tag].cd(j)
240 j+=1
241 histo = h['CTR_ScifiMat'+str(int(1e6*s+1e5*o+1e4*mat+1e3*arr+chan))+tag]
242 if 1: #histo.GetEntries()>3:
243 histo.Draw()
244
245 if tag!='v0prime':
246 for b in ['','_beam']:
247 ut.bookCanvas(h,'CTR'+b+tag,'CTR'+tag,1800,1200,3,2)
248 for s in range(1, nStations+1):
249 tc = h['CTR'+b+tag].cd(s)
250 histo = h['CTR_Scifi'+b+str(s)+tag]
251 rc = histo.Fit('gaus','SQ')
252 tc.Update()
253 stats = histo.FindObject('stats')
254 stats.SetOptFit(1111111)
255 stats.SetX1NDC(0.62)
256 stats.SetY1NDC(0.63)
257 stats.SetX2NDC(0.98)
258 stats.SetY2NDC(0.94)
259 histo.Draw()
260
261 for s in range(1, nStations+1):
262 ut.bookCanvas(h,'CTRM'+str(s)+b+tag,'CTR per mat combi',1800,1200,3,3)
263 j = 1
264 for matH in range(nMats):
265 for matV in range(nMats):
266 tc = h['CTRM'+str(s)+b+tag].cd(j)
267 j+=1
268 histo = h['CTR_Scifi'+b+str(100*s+10*matH+matV)+tag]
269 histo.Fit('gaus','SQ')
270 tc.Update()
271 stats = histo.FindObject('stats')
272 stats.SetOptFit(1111111)
273 stats.SetX1NDC(0.62)
274 stats.SetY1NDC(0.63)
275 stats.SetX2NDC(0.98)
276 stats.SetY2NDC(0.94)
277 histo.Draw()
278
279 if tag!='v0':
280 for b in ['','_beam']:
281 ut.bookCanvas(h,'CTRS'+b,'CTR per station combination'+tag,1800,1200,5,2)
282 k=1
283 for s1 in range(1, nStations):
284 for s2 in range(s1+1, nStations+1):
285 tc = h['CTRS'+b].cd(k)
286 k+=1
287 histo = h['CTR_ScifiStation'+b+str(s1*10+s2)+tag]
288 histo.Draw()
289 histo.Fit('gaus','SQ')
290 tc.Update()
291 stats = histo.FindObject('stats')
292 stats.SetOptFit(1111111)
293 stats.SetX1NDC(0.62)
294 stats.SetY1NDC(0.63)
295 stats.SetX2NDC(0.98)
296 stats.SetY2NDC(0.94)
297 histo.Draw()
298
300 self.meanAndSigma = {}
301 h = self.M.h
302 tag = self.tag
303 ut.bookHist(h,'cor')
304 for b in ['','_beam']:
305 self.meanAndSigma[b]={}
306 for s in range(1, nStations+1):
307 for matH in range(nMats):
308 for matV in range(nMats):
309 key = 100*s+10*matH+matV
310 histo = h['CTR_Scifi'+b+str(key)+tag]
311 Fun = histo.GetFunction('gaus')
312 self.meanAndSigma[b][key] = [Fun.GetParameter(1),Fun.GetParameter(2)]
313
314 def minimizeMat(self,b=""):
315 h = self.M.h
316 tag = self.tag
317 ut.bookHist(h,'commonBlock_mat','',4000,0.,4000.)
318
319 for s in range(1, nStations+1):
320 for proj in ['H', 'V']:
321 # only done for SciFi 2H in the tb_24 setup
322 if s!=2 or proj!='H': continue
323 if proj=='H': o=0
324 else: o=1
325 for mat in range(nMats):
326 for arr in range(nSiPMArrays):
327 for chan in range(nChannelsPerSiPMArray):
328 key = int(1e6*s+1e5*o+1e4*mat+1e3*arr+chan)
329 histo = h[ 'CTR_ScifiMat'+str(key)+tag]# was here
330 if histo.GetEntries()==0: continue
331 dt=histo.GetMean()
332 h['commonBlock_mat'].SetBinContent(1000*arr+chan,dt)
333 self.tdcScifiStationCalib[s][1][proj][1][arr][chan]=dt
334 print('corrections', proj, arr, chan, self.tdcScifiStationCalib[s][1][proj][1][arr][chan])
335
336 with open('ScifiTimeAlignment_v0', 'wb') as fh:
337 pickle.dump(self.tdcScifiStationCalib, fh)
338
339 def minimize(self,b=""):
340 h = self.M.h
342 ut.bookHist(h,'commonBlock','',100,0.,100.)
343
344 for s in range(1, nStations+1):
345 for matH in range(nMats):
346 for matV in range(nMats):
347 key = 100*s+10*matH+matV
348 dt = self.meanAndSigma[b][key][0]
349 h['commonBlock'].SetBinContent(matH*10+matV,dt)
350 npar = 2*nMats
351 ierflg = ctypes.c_int(0)
352 vstart = array('d',[0]*npar)
353 gMinuit = ROOT.TMinuit(npar)
354 gMinuit.SetFCN(FCN)
355 gMinuit.SetErrorDef(1.0)
356 gMinuit.SetMaxIterations(10000)
357 err = 1E-3
358 p = 0
359 for proj in ['H','V']:
360 for m in range(nMats):
361 name = "s"+str(s)+proj+str(m)
362 gMinuit.mnparm(p, name, vstart[p], err, 0.,0.,ierflg)
363 p+=1
364 gMinuit.FixParameter(0)
365 strat = array('d',[0])
366 gMinuit.mnexcm("SET STR",strat,1,ierflg) # 0 faster, 2 more reliable
367 gMinuit.mnexcm("SIMPLEX",vstart,npar,ierflg)
368 gMinuit.mnexcm("MIGRAD",vstart,npar,ierflg)
369
370 cor = ctypes.c_double(0)
371 ecor = ctypes.c_double(0)
372 p = 0
373 for proj in ['H','V']:
374 for m in range(nMats):
375 rc = gMinuit.GetParameter(p,cor,ecor)
376 p+=1
377 self.tdcScifiStationCalib[s][1][proj][m] = cor.value
378
379 with open('ScifiTimeAlignment_v1', 'wb') as fh:
380 pickle.dump(self.tdcScifiStationCalib, fh)
381
382 def minimizeStation(self,b=""):
383 h = self.M.h
384 tag = self.tag
386 self.meanAndSigmaStation[b]={}
387 for s1 in range(1, nStations+1):
388 for s2 in range(s1+1, nStations+1):
389 key = s1*10+s2
390 histo = h[ 'CTR_ScifiStation'+b+str(key)+tag]
391 Fun = histo.GetFunction('gaus')
392 self.meanAndSigmaStation[b][key] = [Fun.GetParameter(1),Fun.GetParameter(2)]
393 for s1 in range(1, nStations+1):
394 for s2 in range(s1+1, nStations+1):
395 key = 10*s1+s2
396 dt = self.meanAndSigmaStation[b][key][0]
397 h['commonBlock'].SetBinContent(key,dt)
398 npar = nStations
399 ierflg = ctypes.c_int(0)
400 vstart = array('d',[0]*npar)
401 gMinuit = ROOT.TMinuit(npar)
402 gMinuit.SetFCN(FCNS)
403 gMinuit.SetErrorDef(1.0)
404 gMinuit.SetMaxIterations(10000)
405 err = 1E-3
406 p = 0
407 for s in range(1, nStations+1):
408 name = "station"+str(s)
409 gMinuit.mnparm(p, name, vstart[p], err, 0.,0.,ierflg)
410 p+=1
411 gMinuit.FixParameter(0)
412 strat = array('d',[0])
413 gMinuit.mnexcm("SET STR",strat,1,ierflg) # 0 faster, 2 more reliable
414 gMinuit.mnexcm("SIMPLEX",vstart,npar,ierflg)
415 gMinuit.mnexcm("MIGRAD",vstart,npar,ierflg)
416
417 cor = ctypes.c_double(0)
418 ecor = ctypes.c_double(0)
419 for s in range(1, nStations+1):
420 rc = gMinuit.GetParameter(s-1,cor,ecor)
421 self.tdcScifiStationCalib[s][0] = cor.value
422
423 with open('ScifiTimeAlignment_v2', 'wb') as fh:
424 pickle.dump(self.tdcScifiStationCalib, fh)
425
426class Scifi_TimeOfTracks(ROOT.FairTask):
427 " dt versus dz"
428 def Init(self,monitor):
429 self.M = monitor
430 self.trackTask = self.M.FairTasks['simpleTracking']
431 h = self.M.h
432 self.V = M.Scifi.GetConfParF("Scifi/signalSpeed")
433 ut.bookHist(M.h,'dTvsZ','dT versus dL; dL/0.5cm [cm];dT/100ps [ns]',140,0.,70.,120,-6.,6.)
434 ut.bookHist(M.h,'dTvsZ_beam','dT versus dL, beam dL/0.5cm [cm];dT/100ps [ns]',140,0.,70.,120,-6.,6.)
435 with open('ScifiTimeAlignment_v2', 'rb') as fh:
436 self.tdcScifiStationCalib = pickle.load(fh)
437
438 def ExecuteEvent(self,event):
439 h = self.M.h
440 for aTrack in self.M.Reco_MuonTracks:
441 if not aTrack.GetUniqueID()==1: continue
442 fitStatus = aTrack.getFitStatus()
443 if not fitStatus.isFitConverged(): continue
444 state = aTrack.getFittedState()
445 mom = state.getMom()
446 slopeX = mom.X()/mom.Z()
447 slopeY = mom.Y()/mom.Z()
448 sortedClusters={}
449 DetID2Key={}
450 for nHit in range(event.Digi_ScifiHits.GetEntries()):
451 DetID2Key[event.Digi_ScifiHits[nHit].GetDetectorID()] = nHit
452#
453 pos = {}
454 for s in range(1, nStations+1): sortedClusters[s] = {'H':[],'V':[]}
455 for nM in range(aTrack.getNumPointsWithMeasurement()):
456 state = aTrack.getFittedState(nM)
457 Meas = aTrack.getPointWithMeasurement(nM)
458 W = Meas.getRawMeasurement()
459 clkey = W.getHitId()
460 aCl = self.trackTask.clusScifi[clkey]
461 aHit = event.Digi_ScifiHits[DetID2Key[aCl.GetFirst()]]
462 s = aCl.GetFirst()//1000000
463 aCl.GetPosition(A,B)
464 mat = (aCl.GetFirst()//10000)%10
465
466 if aHit.isVertical():
467 L = B[1]-state.getPos()[1]
468 sortedClusters[s]['V'].append( [clkey,L,B[0],state.getPos()[1],mat,(A[2]+B[2])/2.,state.getPos()[0],aCl.GetFirst(),aCl.GetTime()] )
469 else:
470 L = A[0]-state.getPos()[0]
471 sortedClusters[s]['H'].append( [clkey,L,A[1],state.getPos()[0],mat,(A[2]+B[2])/2.,state.getPos()[1],aCl.GetFirst(),aCl.GetTime()] )
472 stationTimes = {}
473 for s in range(1, nStations+1):
474 if not (len(sortedClusters[s]['V']) * len(sortedClusters[s]['H']) ) ==1: continue
475 sTime = 0
476 for proj in ['V','H']:
477 clkey = sortedClusters[s][proj][0][0]
478 aCl = self.trackTask.clusScifi[clkey]
479 L = sortedClusters[s][proj][0][1]
480 time = aCl.GetTime() # Get time in ns, use fastest TDC of cluster
481 mat = sortedClusters[s][proj][0][4]
482 sipm_array = int(sortedClusters[s][proj][0][7]/1000)%10
483 sipm_channel = sortedClusters[s][proj][0][7]%1000
484 if channelTimeAlignment==1 and s==2 and proj=='H':# apply the corrections per channel
485 time-= self.tdcScifiStationCalib[s][1][proj][1][sipm_array][sipm_channel]
486 time-= self.tdcScifiStationCalib[s][1][proj][mat] # correct as function of station / projection / mat
487 time-= self.tdcScifiStationCalib[s][0] # internal station calibration
488 time-= abs(L)/self.V
489
490# cross check
491 # corTime = self.M.Scifi.GetCorrectedTime(aCl.GetFirst(),aCl.GetTime(),abs(L) )
492 # print('test',aCl.GetTime(),time,corTime)
493
494 sTime += time
495 stationTimes[s] = [sTime/2.,(sortedClusters[s]['H'][0][5] + sortedClusters[s]['V'][0][5])/2.]
496 # require station 1 to be present which defines T0
497 if not 1 in stationTimes: continue
498
499 T0 = stationTimes[1][0]
500 Z0 = stationTimes[1][1]
501 for s in stationTimes:
502 if s == 1: continue
503 dZ = stationTimes[s][1]-Z0
504 dT = stationTimes[s][0]-T0
505 dL = dZ * ROOT.TMath.Sqrt( slopeX**2+slopeY**2+1 )
506 # if slopeY>0.1: dL = -dL # cosmics from the back
507 # dT -= dL / u.speedOfLight
508 rc = h['dTvsZ'].Fill(dL,dT)
509 if abs(slopeX)<0.1 and abs(slopeY)<0.1:
510 rc = h['dTvsZ_beam'].Fill(dL,dT)
511
512
513
514 def Plot(self):
515 h = self.M.h
516 ut.bookCanvas(h,'Tscifi','',1800,1200,2,1)
517 h['Tscifi'].cd(1)
518 h['dTvsZ'].Draw('colz')
519 h['Tscifi'].cd(2)
520 h['dTvsZ_beam'].Draw('colz')
521
522class histStore():
523 h = {}
524 xCheck = ''
525
526if __name__ == '__main__':
527 import Monitor
528 import SndlhcTracking
529 from argparse import ArgumentParser
530 parser = ArgumentParser()
531 parser.add_argument("--server", dest="server", help="xrootd server",default=os.environ["EOSSHIP"])
532 parser.add_argument("-r", "--runNumber", dest="runNumber", help="run number", type=int,default=-1)
533 parser.add_argument("-p", "--path", dest="path", help="path to data",required=False,default="/eos/experiment/sndlhc/convertedData/physics/2022/")
534 parser.add_argument("-P", "--partition", dest="partition", help="partition of data", type=int,required=False,default=-1)
535 parser.add_argument("-f", "--inputFile", dest="fname", help="file name", type=str,default=None,required=False)
536 parser.add_argument("-g", "--geoFile", dest="geoFile", help="file name", type=str,default="geofile_sndlhc_TI18_V0_2022.root",required=False)
537 parser.add_argument("-c", "--command", dest="command", help="command",required=False,default="")
538 parser.add_argument("-o", dest="check", help="use corrected times",action='store_true',default=False)
539 parser.add_argument("-M", "--online", dest="online", help="online mode",default=False,action='store_true')
540 parser.add_argument("--interactive", dest="interactive", action='store_true',default=False)
541 parser.add_argument("-n", "--nEvents", dest="nEvents", help="number of events", default=-1,type=int)
542
543 options = parser.parse_args()
544 options.trackType = 'Scifi'
545
546 FairTasks = []
548 trackTask.SetName('simpleTracking')
549 FairTasks.append(trackTask)
550 M = Monitor.Monitoring(options,FairTasks)
551 nMats = M.Scifi.GetConfParI("Scifi/nmats")
552 nStations = M.Scifi.GetConfParI("Scifi/nscifi")
553 nChannelsPerSiPMArray = M.Scifi.GetConfParI("Scifi/nsipm_channels")
554 nSiPMArrays = M.Scifi.GetConfParI("Scifi/nsipm_mat")
555 channelTimeAlignment = M.Scifi.GetConfParI("Scifi/channelTimeAlignment")
556
557 if options.nEvents <0: options.nEvents = M.GetEntries()
558 if options.command == "full":
559 task = Scifi_CTR()
560 # channel alignment for testbeam 2024 - needed for station 2H
561 if channelTimeAlignment==1:
562# mat alignment
563 M.iteration = 'v0prime'
564 task.Init(M)
565 for n in range(options.nEvents):
566 event = M.GetEvent(n)
567 task.ExecuteEvent(event)
568 task.Plot()
569 task.minimizeMat(b="")
570# the usual plane and station alignment
571# plane alignment
572 M.iteration = 'v0'
573 task.Init(M)
574 for n in range(options.nEvents):
575 event = M.GetEvent(n)
576 task.ExecuteEvent(event)
577 task.Plot()
578 task.minimize(b="") # all tracks, not yet enough stats for beam tracks
579# cross check and station alignment
580 M.iteration = 'v1'
581 task.Init(M)
582 for n in range(options.nEvents):
583 event = M.GetEvent(n)
584 task.ExecuteEvent(event)
585 task.Plot()
586# nw minimize the station alignments
587 task.minimizeStation(b="")
588
589# cross check
590 M.iteration = 'v2'
591 task.Init(M)
592 for n in range(options.nEvents):
593 event = M.GetEvent(n)
594 task.ExecuteEvent(event)
595 task.Plot()
596 ut.writeHists(M.h,'ScifiTimeCalibration.root',plusCanvas=True)
597
598 for s in range(1, nStations+1):
599 C = task.tdcScifiStationCalib[s]
600 if nMats == 1 :
601 print ("station %1i %5.2F H: %5.2F V: %5.2F "%( s, C[0],C[1]['H'][0],C[1]['V'][0] ) )
602 if nMats == 3 :
603 print ("station %1i %5.2F H: %5.2F %5.2F %5.2F V: %5.2F %5.2F %5.2F "%( s, C[0],C[1]['H'][0], C[1]['H'][1], C[1]['H'][2],C[1]['V'][0], C[1]['V'][1], C[1]['V'][2] ) )
604 for s in range(1, nStations+1):
605 C = task.tdcScifiStationCalib[s]
606 if nMats == 1 :
607 print ("station %1i %5.3F*u.ns, %5.3F*u.ns, %5.3F*u.ns "%( s, C[0],C[1]['H'][0],C[1]['V'][0] ) )
608 if nMats == 3 :
609 print ("station %1i %5.3F*u.ns, %5.3F*u.ns, %5.3F*u.ns, %5.3F*u.ns, %5.3F*u.ns, %5.3F*u.ns, %5.3F*u.ns "%( s, C[0],C[1]['H'][0], C[1]['H'][1], C[1]['H'][2],C[1]['V'][0], C[1]['V'][1], C[1]['V'][2] ) )
610
611if options.command == "full" or options.command == "check":
612# final test
614 taskT.Init(M)
615 for n in range(options.nEvents):
616 event = M.GetEvent(n)
617 taskT.ExecuteEvent(event)
618 taskT.Plot()
619 for s in range(1, nStations+1):
620 C = taskT.tdcScifiStationCalib[s]
621 if nMats == 1 :
622 print ("station %1i %5.2F H: %5.2F V: %5.2F "%( s, C[0],C[1]['H'][0],C[1]['V'][0] ) )
623 if nMats == 3 :
624 print ("station %1i %5.2F H: %5.2F %5.2F %5.2F V: %5.2F %5.2F %5.2F "%( s, C[0],C[1]['H'][0], C[1]['H'][1], C[1]['H'][2],C[1]['V'][0], C[1]['V'][1], C[1]['V'][2] ) )
625 for s in range(1, nStations+1):
626 C = taskT.tdcScifiStationCalib[s]
627 if nMats == 1 :
628 print ("station %1i %5.3F*u.ns, %5.3F*u.ns, %5.3F*u.ns "%( s, C[0],C[1]['H'][0],C[1]['V'][0] ) )
629 if nMats == 3 :
630 print ("station %1i %5.3F*u.ns, %5.3F*u.ns, %5.3F*u.ns, %5.3F*u.ns, %5.3F*u.ns, %5.3F*u.ns, %5.3F*u.ns "%( s, C[0],C[1]['H'][0], C[1]['H'][1], C[1]['H'][2],C[1]['V'][0], C[1]['V'][1], C[1]['V'][2] ) )
631
Init(self, monitor)
Definition ScifiCTR.py:45
minimizeMat(self, b="")
Definition ScifiCTR.py:314
ExecuteEvent(self, event)
Definition ScifiCTR.py:111
minimizeStation(self, b="")
Definition ScifiCTR.py:382
ExtractMeanAndSigma(self)
Definition ScifiCTR.py:299
Double_t GetCorrectedTime(Int_t fDetectorID, Double_t rawTime, Double_t L)
Definition Scifi.cxx:614
FCN(npar, gin, f, par, iflag)
Definition ScifiCTR.py:19
FCNS(npar, gin, f, par, iflag)
Definition ScifiCTR.py:31
pyExit()
Definition ScifiCTR.py:9