Belle II Software  release-05-01-25
PXDValidationTTree.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 import sys
5 import math
6 from basf2 import *
7 
8 # Some ROOT tools
9 import ROOT
10 from ROOT import Belle2
11 from ROOT import gROOT, AddressOf
12 
13 # Define a ROOT struct to hold output data in the TTree.
14 gROOT.ProcessLine('struct EventData {\
15  long exp;\
16  long run;\
17  unsigned long evt;\
18  int vxd_id;\
19  int layer;\
20  int ladder;\
21  int sensor;\
22  int truehit_index;\
23  int cluster_index;\
24  int pixel_type;\
25  float truehit_u;\
26  float truehit_v;\
27  float truehit_EntryW;\
28  float truehit_ExitW;\
29  float truehit_LossMomentum;\
30  float truehit_time;\
31  float truehit_charge;\
32  float theta_u;\
33  float theta_v;\
34  float cluster_u;\
35  float cluster_v;\
36  float cluster_uEtaPosition;\
37  float cluster_vEtaPosition;\
38  float cluster_uError;\
39  float cluster_vError;\
40  float cluster_rho;\
41  float cluster_charge;\
42  float cluster_seed;\
43  float cluster_size;\
44  float cluster_uSize;\
45  float cluster_vSize;\
46  float cluster_uPull;\
47  float cluster_vPull;\
48 };'
49  )
50 
51 from ROOT import EventData
52 
53 
54 class PXDValidationTTree(Module):
55 
56  """
57  A simple module to check the reconstruction of PXDTrueHits.
58  This module writes its output to a ROOT tree.
59  Primary goal is supporting of validation plots
60  """
61 
62  def __init__(self):
63  """Initialize the module"""
64 
65  super(PXDValidationTTree, self).__init__()
66 
67  self.file = ROOT.TFile('PXDValidationTTreeOutput.root', 'recreate')
68 
69  self.tree = ROOT.TTree('tree', 'Event data of PXD simulation')
70 
71  self.h_consts = ROOT.TH1F('h_consts', 'Constances', 12, 0, 12)
72  self.h_consts.GetXaxis().SetBinLabel(1, 'Sensor thicknes [cm] (0.0075)')
73  self.h_consts.GetXaxis().SetBinLabel(2, 'Pitch in u - all sensors [cm] (0.005)')
74  self.h_consts.GetXaxis().SetBinLabel(3, 'Pitch in v, layer 1 small pitch [cm] (0.0055)')
75  self.h_consts.GetXaxis().SetBinLabel(4, 'Pitch in v, layer 1 large pitch [cm] (0.006)')
76  self.h_consts.GetXaxis().SetBinLabel(5, 'Pitch in v, layer 2 small pitch [cm] (0.007)')
77  self.h_consts.GetXaxis().SetBinLabel(6, 'Pitch in v, layer 2 large pitch [cm] (0.0085)')
78  self.h_consts.GetXaxis().SetBinLabel(7, 'Number of cells in u, all layers (250)')
79  self.h_consts.GetXaxis().SetBinLabel(8, 'Number of cells in v, layer 1 small pitch (256)')
80  self.h_consts.GetXaxis().SetBinLabel(9, 'Number of cells in v, layer 1 large pitch (512)')
81  self.h_consts.GetXaxis().SetBinLabel(10, 'Number of cells in v, layer 2 small pitch (256)')
82  self.h_consts.GetXaxis().SetBinLabel(11, 'Number of cells in v, layer 2 large pitch (512)')
83  self.h_consts.GetXaxis().SetBinLabel(12, 'Noise of digits of sensors [electrons] (200)')
84 
85  self.data = EventData()
86  # Declare tree branches
87  for key in EventData.__dict__:
88  if '__' not in key:
89  formstring = '/F'
90  if isinstance(self.data.__getattribute__(key), int):
91  formstring = '/I'
92  self.tree.Branch(key, AddressOf(self.data, key), key + formstring)
93 
94  def beginRun(self):
95  """ Does nothing """
96 
97  def event(self):
98  """Find clusters with a truehit and save needed information."""
99 
100  # Start with clusters and use the relation to get the corresponding
101  # digits and truehits.
102  pxd_clusters = Belle2.PyStoreArray('PXDClusters')
103  WrtS1Pitch = 0
104  WrtS2Pitch = 0
105  VCellsSplit = 256
106  DigitNoise = 200
107 # belle2xmlFile = open('Belle2.xml', 'r')
108 # belle2xml = belle2xmlFile.read()
109 # belle2xmlFile.close()
110  for cluster in pxd_clusters:
111  cluster_truehits = cluster.getRelationsTo('PXDTrueHits')
112 
113  # Here we ask only for clusters with exactly one TrueHit.
114  if len(cluster_truehits) != 1:
115  continue
116 
117  for truehit in cluster_truehits:
118  # Now let's store some data
119  # Event identification
120  self.data.exp = Belle2.PyStoreObj('EventMetaData').obj().getExperiment()
121  self.data.run = Belle2.PyStoreObj('EventMetaData').obj().getRun()
122  self.data.evt = Belle2.PyStoreObj('EventMetaData').obj().getEvent()
123  # Sesnor identification
124  vxd_id = truehit.getSensorID()
125  self.data.vxd_id = vxd_id.getID()
126  self.data.layer = vxd_id.getLayerNumber()
127  self.data.ladder = vxd_id.getLadderNumber()
128  self.data.sensor = vxd_id.getSensorNumber()
129  sensor_info = Belle2.VXD.GeoCache.get(vxd_id)
130  UPitch = sensor_info.getUPitch()
131  VPitch = sensor_info.getVPitch(truehit.getV())
132  if vxd_id.getLayerNumber() == 1:
133  if vxd_id.getSensorNumber() == 1:
134  if WrtS1Pitch == 0:
135  self.h_consts.SetBinContent(1, sensor_info.getThickness())
136  self.h_consts.SetBinContent(2, sensor_info.getUPitch())
137  self.h_consts.SetBinContent(3, sensor_info.getVPitch(-2.0))
138  self.h_consts.SetBinContent(4, sensor_info.getVPitch(+2.0))
139  self.h_consts.SetBinContent(7, sensor_info.getUCells())
140  self.h_consts.SetBinContent(8, VCellsSplit)
141  self.h_consts.SetBinContent(9, sensor_info.getVCells() - VCellsSplit)
142  self.h_consts.SetBinContent(12, DigitNoise)
143  WrtS1Pitch = 1
144  if vxd_id.getLayerNumber() == 2:
145  if vxd_id.getSensorNumber() == 1:
146  if WrtS2Pitch == 0:
147  self.h_consts.SetBinContent(5, sensor_info.getVPitch(-2.0))
148  self.h_consts.SetBinContent(6, sensor_info.getVPitch(+2.0))
149  self.h_consts.SetBinContent(10, VCellsSplit)
150  self.h_consts.SetBinContent(11, sensor_info.getVCells() - VCellsSplit)
151  WrtS2Pitch = 1
152  self.data.pixel_type = (vxd_id.getLayerNumber() - 1) * 2
153  if vxd_id.getLayerNumber() == 1:
154  if VPitch > 0.0058:
155  self.data.pixel_type += 1
156  if vxd_id.getLayerNumber() == 2:
157  if VPitch > 0.0080:
158  self.data.pixel_type += 1
159  # Hit identification
160  self.data.truehit_index = truehit.getArrayIndex()
161  self.data.cluster_index = cluster.getArrayIndex()
162  # Get sensor geometry information
163  sensor_info = Belle2.VXD.GeoCache.get(vxd_id)
164  thickness = sensor_info.getThickness()
165  # TrueHit information
166  self.data.truehit_u = truehit.getU()
167  self.data.truehit_v = truehit.getV()
168  self.data.truehit_EntryW = truehit.getEntryW()
169  self.data.truehit_ExitW = truehit.getExitW()
170  self.data.truehit_LossMomentum = truehit.getEntryMomentum().Mag() - truehit.getExitMomentum().Mag()
171  self.data.truehit_time = truehit.getGlobalTime()
172  self.data.truehit_charge = truehit.getEnergyDep()
173  self.data.theta_u = math.atan2(truehit.getExitU() - truehit.getEntryU(), thickness)
174  self.data.theta_v = math.atan2(truehit.getExitV() - truehit.getEntryV(), thickness)
175  # Cluster information
176  self.data.cluster_u = cluster.getU()
177  self.data.cluster_v = cluster.getV()
178  self.data.cluster_uError = cluster.getUSigma()
179  self.data.cluster_vError = cluster.getVSigma()
180  self.data.cluster_rho = cluster.getRho()
181  self.data.cluster_charge = cluster.getCharge()
182  self.data.cluster_seed = cluster.getSeedCharge()
183  self.data.cluster_size = cluster.getSize()
184  self.data.cluster_uSize = cluster.getUSize()
185  self.data.cluster_vSize = cluster.getVSize()
186  self.data.cluster_uEtaPosition = \
187  0.5 + (cluster.getU() - sensor_info.getUCellPosition(sensor_info.getUCellID(cluster.getU()))) / UPitch
188  self.data.cluster_vEtaPosition = \
189  0.5 + (cluster.getV() - sensor_info.getVCellPosition(sensor_info.getVCellID(cluster.getV()))) / VPitch
190  self.data.cluster_uPull = (cluster.getU() - truehit.getU()) / cluster.getUSigma()
191  self.data.cluster_vPull = (cluster.getV() - truehit.getV()) / cluster.getVSigma()
192  # Fill tree
193  self.file.cd()
194  self.tree.Fill()
195 
196  def terminate(self):
197  """ Close the output file."""
198 
199  self.h_consts.GetListOfFunctions().Add(ROOT.TNamed('Description', 'Transfer of some basic constances to root '
200  'for later procesing.'))
201  self.h_consts.GetListOfFunctions().Add(ROOT.TNamed('Check', 'Validation: Check differences to reference plot, '
202  'must be no change.'))
203 
204  self.file.cd()
205  self.file.Write()
206  # self.h_consts.Write()
207  self.file.Flush()
208  self.file.Close()
PXDValidationTTree.PXDValidationTTree.__init__
def __init__(self)
Definition: PXDValidationTTree.py:62
Belle2::VXD::GeoCache::get
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
Definition: GeoCache.h:141
PXDValidationTTree.PXDValidationTTree.event
def event(self)
Definition: PXDValidationTTree.py:97
Belle2::PyStoreObj
a (simplified) python wrapper for StoreObjPtr.
Definition: PyStoreObj.h:69
PXDValidationTTree.PXDValidationTTree.h_consts
h_consts
Histogram for constances.
Definition: PXDValidationTTree.py:71
PXDValidationTTree.PXDValidationTTree.beginRun
def beginRun(self)
Definition: PXDValidationTTree.py:94
Belle2::getRun
static ExpRun getRun(map< ExpRun, pair< double, double >> runs, double t)
Get exp number + run number from time.
Definition: Splitter.cc:262
PXDValidationTTree.PXDValidationTTree.data
data
Instance of EventData class.
Definition: PXDValidationTTree.py:85
PXDValidationTTree.PXDValidationTTree.file
file
Output ROOT file.
Definition: PXDValidationTTree.py:67
PXDValidationTTree.PXDValidationTTree.terminate
def terminate(self)
Definition: PXDValidationTTree.py:196
PXDValidationTTree.PXDValidationTTree.tree
tree
TTree for output data.
Definition: PXDValidationTTree.py:69
Belle2::PyStoreArray
a (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:58
PXDValidationTTree.PXDValidationTTree
Definition: PXDValidationTTree.py:54