Belle II Software  release-05-01-25
SVDValidationTTree.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 """
5 <header>
6  <contact> G. Caria, gcaria@student.unimelb.edu.au </contact>
7  <description>
8  This module is used for the SVD validation.
9  It gets information about truehits and clusters, saving
10  in a ttree in a ROOT file.
11  </description>
12 </header>
13 """
14 import sys
15 import math
16 
17 from basf2 import *
18 
19 # Some ROOT tools
20 import ROOT
21 from ROOT import Belle2
22 from ROOT import gROOT, AddressOf
23 from ROOT import PyConfig
24 from ROOT import TVector3
25 
26 # Define a ROOT struct to hold output data in the TTree
27 gROOT.ProcessLine('struct EventData {\
28  int sensor_id;\
29  int layer;\
30  int ladder;\
31  int sensor;\
32  int sensor_type;\
33  int strip_dir;\
34  float strip_pitch;\
35  float cluster_theta;\
36  float cluster_phi;\
37  float cluster_position;\
38  float cluster_positionSigma;\
39  float cluster_clsTime;\
40  float cluster_clsTimeSigma;\
41  float cluster_charge;\
42  float cluster_seedCharge;\
43  float cluster_size;\
44  float cluster_snr;\
45  float cluster_interstripPosition;\
46  float cluster_pull;\
47  float cluster_residual;\
48  float truehit_position;\
49  float truehit_interstripPosition;\
50  float truehit_deposEnergy;\
51  float truehit_lossmomentum;\
52  float truehit_time;\
53  };')
54 
55 from ROOT import EventData
56 
57 
58 class SVDValidationTTree(Module):
59  '''class to produced the validation ttree '''
60 
61  def __init__(self):
62  """Initialize the module"""
63 
64  super(SVDValidationTTree, self).__init__()
65 
66  self.file = ROOT.TFile('../SVDValidationTTree.root', 'recreate')
67  '''Output ROOT file'''
68  self.tree = ROOT.TTree('tree', 'Event data of SVD validation events')
69  '''TTrees for output data'''
70  self.data = EventData()
71  '''Instance of the EventData class'''
72 
73  # Declare tree branches
74  for key in EventData.__dict__:
75  if '__' not in key:
76  formstring = '/F'
77  if isinstance(self.data.__getattribute__(key), int):
78  formstring = '/I'
79  self.tree.Branch(key, AddressOf(self.data, key), key + formstring)
80 
81  def beginRun(self):
82  """ Does nothing """
83 
84  def event(self):
85  """Find clusters with a truehit and save needed information"""
86 
87  # Start with clusters and use the relation to get the corresponding
88  # digit and truehits
89  clusters = Belle2.PyStoreArray('SVDClusters')
90  for cluster in clusters:
91  cluster_truehits = cluster.getRelationsTo('SVDTrueHits')
92  # We want only clusters with exactly one associated TrueHit
93  if len(cluster_truehits) != 1:
94  continue
95  for truehit in cluster_truehits:
96  sensorInfo = Belle2.VXD.GeoCache.get(cluster.getSensorID())
97  # Let's store some data
98  # Sensor identification
99  sensorID = cluster.getSensorID()
100  self.data.sensor_id = int(sensorID)
101  sensorNum = sensorID.getSensorNumber()
102  self.data.sensor = sensorNum
103  layerNum = sensorID.getLayerNumber()
104  self.data.layer = layerNum
105  if (layerNum == 3):
106  sensorType = 1
107  else:
108  if (sensorNum == 1):
109  sensorType = 0
110  else:
111  sensorType = 1
112  self.data.sensor_type = sensorType
113  ladderNum = sensorID.getLadderNumber()
114  self.data.ladder = ladderNum
115  # Cluster information
116  self.data.cluster_clsTime = cluster.getClsTime()
117  self.data.cluster_clsTimeSigma = cluster.getClsTimeSigma()
118  self.data.cluster_charge = cluster.getCharge()
119  self.data.cluster_seedCharge = cluster.getSeedCharge()
120  self.data.cluster_size = cluster.getSize()
121  self.data.cluster_snr = cluster.getSNR()
122  cluster_position = cluster.getPosition()
123  if cluster.isUCluster():
124  cluster_position = cluster.getPosition(truehit.getV())
125  # Interstrip position calculations
126  if cluster.isUCluster():
127  strip_dir = 0
128  strip_pitch = sensorInfo.getUPitch(truehit.getV())
129  else:
130  strip_dir = 1
131  strip_pitch = sensorInfo.getVPitch(truehit.getU())
132  self.data.strip_dir = strip_dir
133  self.data.strip_pitch = strip_pitch
134  cluster_interstripPosition = cluster_position % strip_pitch / strip_pitch
135  self.data.cluster_interstripPosition = cluster_interstripPosition
136  # theta and phi definitions
137  if cluster.isUCluster():
138  uPos = cluster_position
139  vPos = 0
140  else:
141  uPos = 0
142  vPos = cluster_position
143  localPosition = TVector3(uPos, vPos, 0) # sensor center at (0, 0, 0)
144  globalPosition = sensorInfo.pointToGlobal(localPosition, True)
145  x = globalPosition[0]
146  y = globalPosition[1]
147  z = globalPosition[2]
148  # see https://d2comp.kek.jp/record/242?ln=en for the Belle II
149  # coordinate system and related variables
150  rho = math.sqrt(x * x + y * y)
151  r = math.sqrt(x * x + y * y + z * z)
152  # get theta as arccosine(z/r)
153  thetaRadians = math.acos(z / r)
154  theta = (thetaRadians * 180) / math.pi
155  # get phi as arccosine(x/rho)
156  phiRadians = math.acos(x / rho)
157  if y < 0:
158  phi = 360 - (phiRadians * 180) / math.pi
159  else:
160  phi = (phiRadians * 180) / math.pi
161  self.data.cluster_theta = theta
162  self.data.cluster_phi = phi
163  # Pull calculations
164  clusterPos = cluster_position
165  clusterPosSigma = cluster.getPositionSigma()
166  if cluster.isUCluster():
167  truehitPos = truehit.getU()
168  else:
169  truehitPos = truehit.getV()
170  cluster_residual = clusterPos - truehitPos
171  cluster_pull = cluster_residual / clusterPosSigma
172  self.data.cluster_position = clusterPos
173  self.data.cluster_positionSigma = clusterPosSigma
174  self.data.cluster_residual = cluster_residual
175  self.data.cluster_pull = cluster_pull
176  # Truehit information
177  self.data.truehit_position = truehitPos
178  truehit_interstripPosition = truehitPos % strip_pitch / strip_pitch
179  self.data.truehit_interstripPosition = truehit_interstripPosition
180  self.data.truehit_deposEnergy = truehit.getEnergyDep()
181  self.data.truehit_lossmomentum = truehit.getEntryMomentum().Mag() - truehit.getExitMomentum().Mag()
182  self.data.truehit_time = truehit.getGlobalTime()
183  # Fill tree
184  self.file.cd()
185  self.tree.Fill()
186 
187  def terminate(self):
188  """Close the output file. """
189  self.file.cd()
190  self.file.Write()
191  self.file.Close()
SVDValidationTTree.SVDValidationTTree.data
data
Definition: SVDValidationTTree.py:70
SVDValidationTTree.SVDValidationTTree.event
def event(self)
Definition: SVDValidationTTree.py:84
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
SVDValidationTTree.SVDValidationTTree.beginRun
def beginRun(self)
Definition: SVDValidationTTree.py:81
SVDValidationTTree.SVDValidationTTree.terminate
def terminate(self)
Definition: SVDValidationTTree.py:187
SVDValidationTTree.SVDValidationTTree
Definition: SVDValidationTTree.py:58
Belle2::PyStoreArray
a (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:58
SVDValidationTTree.SVDValidationTTree.file
file
Definition: SVDValidationTTree.py:66
SVDValidationTTree.SVDValidationTTree.tree
tree
Definition: SVDValidationTTree.py:68
SVDValidationTTree.SVDValidationTTree.__init__
def __init__(self)
Definition: SVDValidationTTree.py:61