Belle II Software development
SVDEventT0EstimatorModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <tracking/modules/eventTimeExtractor/SVDEventT0EstimatorModule.h>
10#include <framework/datastore/RelationArray.h>
11#include <framework/geometry/B2Vector3.h>
12#include <framework/dataobjects/EventT0.h>
13#include <tracking/dataobjects/RecoTrack.h>
14#include <tracking/dbobjects/SVDEventT0Configuration.h>
15
16#include <cmath>
17
18
19using namespace Belle2;
20
21//-----------------------------------------------------------------
22// Register the Module
23//-----------------------------------------------------------------
24REG_MODULE(SVDEventT0Estimator);
25
26//-----------------------------------------------------------------
27// Implementation
28//-----------------------------------------------------------------
29
31{
32 setDescription("This module estimates the EventT0 as the average of cluster time of SVD clusters associated to tracks. The EventT0 is set to NaN if there are not RecoTracks or there are not SVD clusters associated to tracks or RecoTrack pt < ptMin OR RecoTrack pz < pzMin. The EventT0 estimated is added to the temporaryEventT0s to the StoreObjPtr as EventT0Component that contains: eventT0, eventT0_error, detector=SVD, algorithm, quality.");
34
35 //* Definition of input parameters */
36 addParam("RecoTracks", m_recoTracksName, "Name of the StoreArray with the input RecoTracks", std::string(""));
37 addParam("EventT0", m_eventT0Name, "Name of the StoreObjPtr with the input EventT0", std::string(""));
38 addParam("ptMinSelection", m_ptSelection, "Cut on minimum transverse momentum pt for RecoTrack selection", m_ptSelection);
39 addParam("absPzMinSelection", m_absPzSelection,
40 "Cut on minimum absolute value of the longitudinal momentum, abs(pz), for RecoTrack selection",
42 addParam("absD0Selection", m_absD0Selection,
43 "Cut on maximum absolute value of the d0 for RecoTrack selection", m_absD0Selection);
44 addParam("absZ0Selection", m_absZ0Selection,
45 "Cut on maximum absolute value of the z0 for RecoTrack selection", m_absZ0Selection);
46 addParam("selectTracksFromIP", m_selectTracksFromIP,
47 "Apply the selection based on the absolute values of d0 and z0 to select tracks from the IP to compute SVDEventT0",
49 addParam("useDB", m_useDB, "To compute EvetT0, use configuration of selections stored in the DB", m_useDB);
50}
51
52
56
57
59{
60 B2DEBUG(20, "RecoTracks: " << m_recoTracksName);
61 B2DEBUG(20, "EventT0: " << m_eventT0Name);
62
64 m_eventT0.registerInDataStore();
66}
67
69{
70 if (m_useDB) {
71 if (!m_svdEventT0Config.isValid())
72 B2FATAL("no valid configuration found for SVD EventT0 computation");
73 else
74 B2DEBUG(20, "SVDEventT0Configuration: from now on we are using " << m_svdEventT0Config->get_uniqueID());
75
76
77 m_selectTracksFromIP = m_svdEventT0Config->getSelectTracksFromIP();
78 m_ptSelection = m_svdEventT0Config->getMinimumPtSelection();
79 m_absPzSelection = m_svdEventT0Config->getAbsPzSelection();
80 m_absD0Selection = m_svdEventT0Config->getAbsD0Selection();
81 m_absZ0Selection = m_svdEventT0Config->getAbsZ0Selection();
82 }
83}
84
86{
87
88 double evtT0 = std::numeric_limits<double>::quiet_NaN();
89 double evtT0Err = std::numeric_limits<double>::quiet_NaN();
90 double armTimeSum = 0;
91 double armTimeErrSum = 0;
92 double quality = std::numeric_limits<double>::quiet_NaN();
93 int numberOfSVDClusters = 0;
94 int numberOfRecoTracksUsed = 0;
95 float outgoingArmTime = 0;
96 float ingoingArmTime = 0;
97 float outgoingArmTimeError = 0;
98 float ingoingArmTimeError = 0;
99
100 // loop on recotracks
101 for (auto& recoTrack : m_recoTracks) {
102 const B2Vector3D& p = recoTrack.getMomentumSeed();
103 const UncertainHelix uncertainHelix = constructUncertainHelix(recoTrack);
104 // cppcheck-suppress variableScope ; declaration kept at this scope for readability
105 double d0 = uncertainHelix.getD0();
106 // cppcheck-suppress variableScope ; declaration kept at this scope for readability
107 double z0 = uncertainHelix.getZ0();
108
109 // selection on recoTracks
110 if (p.Perp() < m_ptSelection || std::fabs(p.Z()) < m_absPzSelection) continue;
111
113 if (std::fabs(d0) > m_absD0Selection || std::fabs(z0) > m_absZ0Selection) continue;
114 }
115
116 // use outgoing/ingoing arm time to compute SVD EventT0
117 // if both outgoing and ingoing are estimated we take the smallest one
118 // else if only outgoing or only ingoing is computed we use the only one available
119 // the probability that the ingoing arm is an outgoing arm wrongly classified is higher than the probability that it is a real ingoing arm
120 outgoingArmTime = recoTrack.getOutgoingArmTime();
121 ingoingArmTime = recoTrack.getIngoingArmTime();
122 outgoingArmTimeError = recoTrack.getOutgoingArmTimeError();
123 ingoingArmTimeError = recoTrack.getIngoingArmTimeError();
124 bool hasOutgoingArm = recoTrack.hasOutgoingArmTime();
125 bool hasIngoingArm = recoTrack.hasIngoingArmTime();
126
127 // check if it has both ingoing and outgoing arms
128 if (hasOutgoingArm && hasIngoingArm) {
129 // consider the smallest arm time
130 if (outgoingArmTime <= ingoingArmTime) {
131 armTimeSum += outgoingArmTime * recoTrack.getNSVDHitsOfOutgoingArm();
132 armTimeErrSum += outgoingArmTimeError * outgoingArmTimeError * recoTrack.getNSVDHitsOfOutgoingArm() *
133 (recoTrack.getNSVDHitsOfOutgoingArm() - 1);
134 numberOfSVDClusters += recoTrack.getNSVDHitsOfOutgoingArm();
135 } else {
136 armTimeSum += ingoingArmTime * recoTrack.getNSVDHitsOfIngoingArm();
137 armTimeErrSum += ingoingArmTimeError * ingoingArmTimeError * recoTrack.getNSVDHitsOfIngoingArm() *
138 (recoTrack.getNSVDHitsOfIngoingArm() - 1);
139 numberOfSVDClusters += recoTrack.getNSVDHitsOfIngoingArm();
140 }
141 numberOfRecoTracksUsed += 1;
142 } else if (hasOutgoingArm && !hasIngoingArm) { // check if it has only outgoing arm
143 armTimeSum += outgoingArmTime * recoTrack.getNSVDHitsOfOutgoingArm();
144 armTimeErrSum += outgoingArmTimeError * outgoingArmTimeError * recoTrack.getNSVDHitsOfOutgoingArm() *
145 (recoTrack.getNSVDHitsOfOutgoingArm() - 1);
146 numberOfSVDClusters += recoTrack.getNSVDHitsOfOutgoingArm();
147 numberOfRecoTracksUsed += 1;
148 } else if (!hasOutgoingArm && hasIngoingArm) { // check if it has only ingoing arm
149 armTimeSum += ingoingArmTime * recoTrack.getNSVDHitsOfIngoingArm();
150 armTimeErrSum += ingoingArmTimeError * ingoingArmTimeError * recoTrack.getNSVDHitsOfIngoingArm() *
151 (recoTrack.getNSVDHitsOfIngoingArm() - 1);
152 numberOfSVDClusters += recoTrack.getNSVDHitsOfIngoingArm();
153 numberOfRecoTracksUsed += 1;
154 } else continue;
155 }
156
157
158 // do nothing if no recoTracks are used (no outgoing/ingoing arm time exists = no SVD clusters associated to tracks exist), or if EventT0 is not valid
159 if ((numberOfRecoTracksUsed == 0) || !(m_eventT0.isValid())) return;
160
161 // otherwise, eventT0 is the average of outgoing/ingoing arm time
162 // that are estimated using SVD clusters associated to recoTracks
163 evtT0 = armTimeSum / numberOfSVDClusters;
164 quality = numberOfSVDClusters;
165
166 // now compute the error
167 if (numberOfSVDClusters > 1)
168 evtT0Err = std::sqrt(armTimeErrSum / (numberOfSVDClusters * (numberOfSVDClusters - 1)));
169 else
170 evtT0Err = std::sqrt(armTimeErrSum);
171
172 // and finally set a temporary EventT0
173 EventT0::EventT0Component evtT0Component(evtT0, evtT0Err, Const::SVD, m_algorithm, quality);
174 m_eventT0->addTemporaryEventT0(evtT0Component);
175 m_eventT0->setEventT0(evtT0Component);
176
177}
178
180{
181
182 const ROOT::Math::XYZVector& position = recoTrack.getPositionSeed();
183 const B2Vector3D& momentum = recoTrack.getMomentumSeed();
184 const TMatrixDSym& covariance = recoTrack.getSeedCovariance();
185 short int charge = recoTrack.getChargeSeed();
186 if (charge < 0) charge = -1;
187 else charge = 1;
188 const float pValue = float(std::numeric_limits<double>::quiet_NaN());
189 const float bField = Belle2::BFieldManager::getFieldInTesla(ROOT::Math::XYZVector(0, 0, 0)).Z();
190
191 const UncertainHelix uncertainHelix(position, momentum, charge, bField, covariance, pValue);
192
193 return uncertainHelix;
194}
static ROOT::Math::XYZVector getFieldInTesla(const ROOT::Math::XYZVector &pos)
return the magnetic field at a given position in Tesla.
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition Module.cc:208
Module()
Constructor.
Definition Module.cc:30
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition Module.h:80
This is the Reconstruction Event-Data Model Track.
Definition RecoTrack.h:79
const TMatrixDSym & getSeedCovariance() const
Return the covariance matrix of the seed. ATTENTION: This is not the fitted covariance.
Definition RecoTrack.h:609
ROOT::Math::XYZVector getPositionSeed() const
Return the position seed stored in the reco track. ATTENTION: This is not the fitted position.
Definition RecoTrack.h:478
short int getChargeSeed() const
Return the charge seed stored in the reco track. ATTENTION: This is not the fitted charge.
Definition RecoTrack.h:506
ROOT::Math::XYZVector getMomentumSeed() const
Return the momentum seed stored in the reco track. ATTENTION: This is not the fitted momentum.
Definition RecoTrack.h:485
double m_absPzSelection
Cut on abs(pz) for RecoTrack selection.
StoreObjPtr< EventT0 > m_eventT0
EventT0 StoreObjPtr.
bool m_selectTracksFromIP
Apply the selection based on the absolute values of d0 and z0 to select tracks from the IP to compute...
double m_absD0Selection
Cut on abs(d0), in cm, for RecoTrack selection.
virtual void initialize() override
Initialize the SVDEventT0Estimator.
std::string m_algorithm
name of the algorithm used to evaluate SVD-eventT0
virtual void event() override
This method is the core of the SVDEventT0Estimator.
double m_absZ0Selection
Cut on abs(z0), in cm, for RecoTrack selection.
std::string m_recoTracksName
name of RecoTracks StoreArray
double m_ptSelection
Cut on pt for RecoTrack selection.
virtual ~SVDEventT0EstimatorModule() override
default destructor
DBObjPtr< SVDEventT0Configuration > m_svdEventT0Config
SVD EventT0 Reconstruction Configuration payload.
static const UncertainHelix constructUncertainHelix(const RecoTrack &recoTrack)
return the UncertainHelix from the seed quantities of the RecoTrack
std::string m_eventT0Name
name of StoreObj EventT0
StoreArray< RecoTrack > m_recoTracks
RecoTracks StoreArray.
bool m_useDB
To compute EvetT0, use configuration of selections stored in the DB.
SVDEventT0EstimatorModule()
Constructor defining the parameters.
This class represents an ideal helix in perigee parameterization including the covariance matrix of t...
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition B2Vector3.h:522
Abstract base class for different kinds of events.
Structure for storing the extracted event t0s together with its detector and its uncertainty.
Definition EventT0.h:33