SND@LHC Software
Loading...
Searching...
No Matches
MufluxDigi.py
Go to the documentation of this file.
1from __future__ import print_function
2from __future__ import division
3from builtins import range
4import os
5import ROOT
6import global_variables
7import shipunit as u
8from array import array
9
10stop = ROOT.TVector3()
11start = ROOT.TVector3()
12
13deadChannelsForMC = [10112001, 20112003, 30002041, 30012026, 30102025, 30112013, 30112018, 40012014]
14ineffiency = {1:0.1,2:0.1,3:0.1,4:0.1,5:0.1}
15
16# defining constants for rpc properties
17STRIP_XWIDTH = 0.8625 # internal STRIP V, WIDTH, in cm
18EXT_STRIP_XWIDTH_L = 0.9625 # nominal (R&L) and Left measured external STRIP V, WIDTH, in cm (beam along z, out from the V plane)
19EXT_STRIP_XWIDTH_R = 0.86 # measured Right external STRIP V, WIDTH,in cm (beam along z, out from the V plane)
20V_STRIP_OFF = 0.200
21NR_VER_STRIPS = 184
22total_width = (NR_VER_STRIPS - 2) * STRIP_XWIDTH + EXT_STRIP_XWIDTH_L + EXT_STRIP_XWIDTH_R + (NR_VER_STRIPS - 1) * V_STRIP_OFF
23reduced_width = total_width - (EXT_STRIP_XWIDTH_L + EXT_STRIP_XWIDTH_R)
24
25# function for calculating the strip number from a coordinate, for MuonTagger / RPC
26def StripX(x):
27 if x < -total_width/2. or x > total_width/2.:
28 print("WARNING: x coordinate outside sensitive volume!",x)
29 if x < -total_width/2. + EXT_STRIP_XWIDTH_L + V_STRIP_OFF/2. : strip_x = 184
30 elif x > total_width/2. - EXT_STRIP_XWIDTH_R - V_STRIP_OFF/2. : strip_x = 1
31 else:
32 x_start = x - total_width/2. + EXT_STRIP_XWIDTH_R
33 strip_x = -int(x_start/reduced_width*182.)+1
34 if not (0 < strip_x <= NR_VER_STRIPS-1):
35 print("WARNING: X strip outside range!",x,strip_x)
36 strip_x = 0
37 return int(strip_x)
38
39def StripY(y):
40 STRIP_YWIDTH = 0.8625 # internal STRIP H, WIDTH, in cm
41 EXT_STRIP_YWIDTH = 0.3 # measured external STRIP H, WIDTH, in cm
42 H_STRIP_OFF = 0.1983
43 NR_HORI_STRIPS = 116
44 total_height = (NR_HORI_STRIPS - 2) * STRIP_YWIDTH + 2 * EXT_STRIP_YWIDTH + (NR_HORI_STRIPS - 1) * H_STRIP_OFF
45 y_start = total_height / 2.
46 strip_y = (y_start - EXT_STRIP_YWIDTH + 1.5 * STRIP_YWIDTH + H_STRIP_OFF - y)//(STRIP_YWIDTH + H_STRIP_OFF)
47 if not (0 < strip_y <= NR_HORI_STRIPS):
48 print("WARNING: Y strip outside range!")
49 strip_y = 0
50 return int(strip_y)
51
53 " convert FairSHiP MC hits / digitized hits to measurements"
54 def __init__(self,fout):
55
56 self.iEvent = 0
57
58 outdir=os.getcwd()
59 outfile=outdir+"/"+fout
60 self.fn = ROOT.TFile(fout,'update')
61 self.sTree = self.fn.cbmsim
62
63 # event header
64 self.header = ROOT.FairEventHeader()
65 self.eventHeader = self.sTree.Branch("ShipEventHeader",self.header,32000,1)
66 self.digiMufluxSpectrometer = ROOT.TClonesArray("MufluxSpectrometerHit")
67 self.digiMufluxSpectrometerBranch = self.sTree.Branch("Digi_MufluxSpectrometerHits",self.digiMufluxSpectrometer,32000,1)
68 self.digiLateMufluxSpectrometer = ROOT.TClonesArray("MufluxSpectrometerHit")
69 self.digiLateMufluxSpectrometerBranch = self.sTree.Branch("Digi_LateMufluxSpectrometerHits",self.digiMufluxSpectrometer,32000,1)
70 #muon taggger
71 if self.sTree.GetBranch("MuonTaggerPoint"):
72 self.digiMuonTagger = ROOT.TClonesArray("MuonTaggerHit")
73 self.digiMuonTaggerBranch = self.sTree.Branch("Digi_MuonTaggerHits", self.digiMuonTagger, 32000, 1)
74 # setup random number generator
75 ROOT.gRandom.SetSeed()
76 self.PDG = ROOT.TDatabasePDG.Instance()
77 # for the digitizing and reconstruction step
78 self.v_drift = global_variables.ShipGeo['MufluxSpectrometer']['v_drift']
79 self.sigma_spatial = global_variables.ShipGeo['MufluxSpectrometer']['sigma_spatial']
80 self.viewangle = global_variables.ShipGeo['MufluxSpectrometer']['ViewvAngle']
81
82 self.gMan = ROOT.gGeoManager
83
84 def digitize(self):
85
86 self.sTree.t0 = ROOT.gRandom.Rndm()*1*u.microsecond
87 self.header.SetEventTime( self.sTree.t0 )
88 self.header.SetRunId( self.sTree.MCEventHeader.GetRunID() )
89 self.header.SetMCEntryNumber( self.sTree.MCEventHeader.GetEventID() ) # counts from 1
90 self.eventHeader.Fill()
91 self.digiMufluxSpectrometer.Delete()
92 self.digiLateMufluxSpectrometer.Delete()
96 self.digiMuonTagger.Delete() # produces a lot of warnings, rpc station 0
98 self.digiMuonTaggerBranch.Fill()
99
100 def digitizeMuonTagger(self, fake_clustering=False):
101
102 station = 0
103 strip = 0
104 nav = ROOT.gGeoManager.GetCurrentNavigator()
105 DetectorID = set() # set of detector ids - already deduplicated
106 for MuonTaggerHit in self.sTree.MuonTaggerPoint:
107 # getting rpc nodes, name and matrix
108 detID = MuonTaggerHit.GetDetectorID()
109 s = str(detID//10000)
110 nav.cd('/VMuonBox_1/VSensitive'+s+'_'+s)
111 # translation from top to MuonBox_1
112 point = array('d', [
113 MuonTaggerHit.GetX(),
114 MuonTaggerHit.GetY(),
115 MuonTaggerHit.GetZ(), 1])
116 # translation to local frame
117 point_local = array('d', [0, 0, 0, 1])
118 nav.MasterToLocal(point, point_local)
119
120 xcoord = point_local[0]
121 ycoord = point_local[1]
122
123 # identify individual rpcs
124 station = detID//10000
125 if station not in range(1, 6): # limiting the range of rpcs
126 print("WARNING: Invalid RPC number, something's wrong with the geometry ",station)
127
128 # calculate strip
129 # x gives vertical direction
130 direction = 1
131 strip = StripX(xcoord)
132 if not strip:
133 continue
134 # sampling number of strips around the exact strip for emulating clustering
135 detectorid = station*10000 + direction*1000 + strip
136 DetectorID.add(detectorid)
137 if fake_clustering:
138 s = ROOT.gRandom.Poisson(2)
139 if ROOT.gRandom.Rndm() < 0.5: strip = strip - int(s/2)
140 else: strip = strip + int(s/2)
141 for i in range(0, s):
142 detectorid = station*10000 + direction*1000 + strip + i
143 DetectorID.add(detectorid)
144
145 # y gives horizontal direction
146 direction = 0
147 strip = StripY(ycoord)
148 if not strip:
149 continue
150 # sampling number of strips around the exact strip for emulating clustering
151 detectorid = station*10000 + direction*1000 + strip
152 DetectorID.add(detectorid)
153 if fake_clustering:
154 s = ROOT.gRandom.Poisson(2)
155 if ROOT.gRandom.Rndm() < 0.5: strip = strip - int(s/2)
156 else: strip = strip + int(s/2)
157 for i in range(0, s):
158 detectorid = station*10000 + direction*1000 + strip + i
159 DetectorID.add(detectorid)
160
161 self.digiMuonTagger.Expand(len(DetectorID))
162 for index, detID in enumerate(DetectorID):
163 hit = ROOT.MuonTaggerHit(detID, 0)
164 self.digiMuonTagger[index] = hit
165
166 if fake_clustering:
167 # cluster size loop - plotting the cluster size distribution
168 cluster_size = list()
169 DetectorID_list = list(DetectorID) # turn set into list to allow indexing
170 DetectorID_list.sort() # sorting the list
171 if len(DetectorID_list) > 1:
172 clusters = [[DetectorID_list[0]]]
173 for x in DetectorID_list[1:]:
174 if abs(x - clusters[-1][-1]) <= 1:
175 clusters[-1].append(x)
176 else:
177 clusters.append([x])
178 cluster_size = [len(x) for x in clusters]
179
181
182 # digitize FairSHiP MC hits
183 index = 0
184 hitsPerDetId = {}
185
186 for aMCPoint in self.sTree.MufluxSpectrometerPoint:
187 aHit = ROOT.MufluxSpectrometerHit(aMCPoint,self.sTree.t0)
188 aHit.setValid()
189 if index>0 and self.digiMufluxSpectrometer.GetSize() == index: self.digiMufluxSpectrometer.Expand(index+1000)
190 self.digiMufluxSpectrometer[index]=aHit
191 detID = aHit.GetDetectorID()
192 if detID in hitsPerDetId:
193 if self.digiMufluxSpectrometer[hitsPerDetId[detID]].tdc() > aHit.tdc():
194 # second hit with smaller tdc
195 self.digiMufluxSpectrometer[hitsPerDetId[detID]].setInvalid()
196 hitsPerDetId[detID] = index
197 else:
198 hitsPerDetId[detID] = index
199 if aMCPoint.GetDetectorID() in deadChannelsForMC: aHit.setInvalid()
200 station = int(aMCPoint.GetDetectorID()//10000000)
201 if ROOT.gRandom.Rndm() < ineffiency[station]: aHit.setInvalid()
202 index+=1
203
204 def finish(self):
205 print('finished writing tree')
206 self.sTree.Write()
set(INCLUDE_DIRECTORIES ${SYSTEM_INCLUDE_DIRECTORIES} ${VMC_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/shipdata ${CMAKE_SOURCE_DIR}/shipLHC ${CMAKE_SOURCE_DIR}/analysis/cuts ${CMAKE_SOURCE_DIR}/analysis/tools ${FMT_INCLUDE_DIR}) include_directories($
Definition CMakeLists.txt:1
__init__(self, fout)
Definition MufluxDigi.py:54
digitizeMuonTagger(self, fake_clustering=False)