Belle II Software development
SVDValidationTTreeStrip.py
1#!/usr/bin/env python3
2
3
10
11"""
12<header>
13 <description>
14 This module is used for the SVD validation.
15 It gets information about digits, saving
16 in a ttree in a ROOT file.
17 </description>
18 <noexecute>SVD validation helper class</noexecute>
19</header>
20"""
21import xml.etree.ElementTree as ET
22
23import basf2 as b2
24
25# Some ROOT tools
26import ROOT
27from ROOT import Belle2 # noqa: make Belle2 namespace available
28from ROOT import gROOT, addressof
29
30# Define a ROOT struct to hold output data in the TTree
31gROOT.ProcessLine('struct EventDataStrip {\
32 int sensor_id;\
33 int layer;\
34 int ladder;\
35 int sensor;\
36 int sensor_type;\
37 int strip_dir;\
38 float strip_charge;\
39 int strip_noise;\
40 };')
41
42from ROOT import EventDataStrip # noqa
43
44
45class SVDValidationTTreeStrip(b2.Module):
46 '''class to create the strip ttree'''
47
48 def __init__(self):
49 """Initialize the module"""
50
51 super().__init__()
52
53 self.file = ROOT.TFile('../SVDValidationTTreeStrip.root', 'recreate')
54
55 self.tree = ROOT.TTree('tree', 'Event data of SVD validation events')
56
57 self.data = EventDataStrip()
58
59 # Declare tree branches
60 for key in EventDataStrip.__dict__:
61 if '__' not in key:
62 formstring = '/F'
63 if isinstance(self.data.__getattribute__(key), int):
64 formstring = '/I'
65 self.tree.Branch(key, addressof(self.data, key), key + formstring)
66
67 def event(self):
68 """Find digit with a cluster and save needed information"""
69 # Before starting iterating on clusters gets noise value from xml file
70 # so that it doesn't have to be repeated for every digit
71 tree = ET.parse(Belle2.FileSystem.findFile('svd/data/SVD-Components.xml'))
72 root = tree.getroot()
73 for sensor in root.findall('Sensor'):
74 if sensor.get('type') == 'Layer3':
75 if len(sensor.findall('Active')) == 1:
76 active = sensor.find('Active')
77 NoiseULayer3 = int(active.find('ElectronicNoiseU').text)
78 NoiseVLayer3 = int(active.find('ElectronicNoiseV').text)
79 for sensorbase in root.iter('SensorBase'):
80 if sensorbase.get('type') == 'Barrel':
81 active = sensorbase.find('Active')
82 NoiseUBarrel = int(active.find('ElectronicNoiseU').text)
83 NoiseVBarrel = int(active.find('ElectronicNoiseV').text)
84 elif sensorbase.get('type') == 'Slanted':
85 active = sensorbase.find('Active')
86 NoiseUSlanted = int(active.find('ElectronicNoiseU').text)
87 NoiseVSlanted = int(active.find('ElectronicNoiseV').text)
88
89 # Start with clusters and use the relation to get the corresponding
90 # digits
91 clusters = Belle2.PyStoreArray('SVDClusters')
92 for cluster in clusters:
93
94 cls_strip_ids = []
95
96 cluster_truehits = cluster.getRelationsTo('SVDTrueHits')
97 # We want only clusters with exactly one associated TrueHit
98 if len(cluster_truehits) != 1:
99 continue
100 digits = cluster.getRelationsTo('SVDRecoDigits')
101
102 # get all the strip IDs of this cluster
103 for digit in digits:
104 if digit.getCellID() not in cls_strip_ids:
105 cls_strip_ids.append(digit.getCellID())
106
107 # get the strip charge as the highest charge among its digits
108 for strip_id in cls_strip_ids:
109 # print("strip_id is : " + str(strip_id))
110 strip_charge = 0
111 for digit in digits:
112 if strip_id != digit.getCellID():
113 continue
114
115 # print("this digit's charge: " + str(digit.getCharge()))
116
117 if (digit.getCharge() > strip_charge):
118 strip_charge = digit.getCharge()
119
120 # Sensor identification
121 sensorID = cluster.getSensorID()
122 self.data.sensor_id = int(sensorID)
123 sensorNum = sensorID.getSensorNumber()
124 self.data.sensor = sensorNum
125 layerNum = sensorID.getLayerNumber()
126 self.data.layer = layerNum
127 if (layerNum == 3):
128 sensorType = 1
129 else:
130 if (sensorNum == 1):
131 sensorType = 0
132 else:
133 sensorType = 1
134 self.data.sensor_type = sensorType
135 ladderNum = sensorID.getLadderNumber()
136 self.data.ladder = ladderNum
137 self.data.strip_charge = strip_charge
138 # Find what noise value should be used
139 # depending on layer and sensor number
140 if digit.isUStrip():
141 strip_dir = 0
142 if (layerNum == 3):
143 noise = NoiseULayer3
144 else:
145 if (sensorNum == 1):
146 noise = NoiseUSlanted
147 else:
148 noise = NoiseUBarrel
149 else:
150 strip_dir = 1
151 if (layerNum == 3):
152 noise = NoiseVLayer3
153 else:
154 if (sensorNum == 1):
155 noise = NoiseVSlanted
156 else:
157 noise = NoiseVBarrel
158 self.data.strip_dir = strip_dir
159 self.data.strip_noise = noise
160 # Fill tree
161 self.file.cd()
162 self.tree.Fill()
163
164 def terminate(self):
165 """Close the output file. """
166 self.file.cd()
167 self.file.Write()
168 self.file.Close()
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
Definition: FileSystem.cc:151
A (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:72