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