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 cointains: 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
54{
55}
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 double d0 = uncertainHelix.getD0();
105 double z0 = uncertainHelix.getZ0();
106
107 // selection on recoTracks
108 if (p.Perp() < m_ptSelection || std::fabs(p.Z()) < m_absPzSelection) continue;
109
111 if (std::fabs(d0) > m_absD0Selection || std::fabs(z0) > m_absZ0Selection) continue;
112 }
113
114 // use outgoing/ingoing arm time to compute SVD EventT0
115 // if both outgoing and ingoing are estimated we take the smallest one
116 // else if only outgoing or only ingoing is computed we use the only one available
117 // the probability that the ingoing arm is an outgoing arm wrongly classified is higher than the probability that it is a real ingoing arm
118 outgoingArmTime = recoTrack.getOutgoingArmTime();
119 ingoingArmTime = recoTrack.getIngoingArmTime();
120 outgoingArmTimeError = recoTrack.getOutgoingArmTimeError();
121 ingoingArmTimeError = recoTrack.getIngoingArmTimeError();
122 bool hasOutgoingArm = recoTrack.hasOutgoingArmTime();
123 bool hasIngoingArm = recoTrack.hasIngoingArmTime();
124
125 // check if it has both ingoing and outgoing arms
126 if (hasOutgoingArm && hasIngoingArm) {
127 // consider the smallest arm time
128 if (outgoingArmTime <= ingoingArmTime) {
129 armTimeSum += outgoingArmTime * recoTrack.getNSVDHitsOfOutgoingArm();
130 armTimeErrSum += outgoingArmTimeError * outgoingArmTimeError * recoTrack.getNSVDHitsOfOutgoingArm() *
131 (recoTrack.getNSVDHitsOfOutgoingArm() - 1);
132 numberOfSVDClusters += recoTrack.getNSVDHitsOfOutgoingArm();
133 } else {
134 armTimeSum += ingoingArmTime * recoTrack.getNSVDHitsOfIngoingArm();
135 armTimeErrSum += ingoingArmTimeError * ingoingArmTimeError * recoTrack.getNSVDHitsOfIngoingArm() *
136 (recoTrack.getNSVDHitsOfIngoingArm() - 1);
137 numberOfSVDClusters += recoTrack.getNSVDHitsOfIngoingArm();
138 }
139 numberOfRecoTracksUsed += 1;
140 } else if (hasOutgoingArm && !hasIngoingArm) { // check if it has only outgoing arm
141 armTimeSum += outgoingArmTime * recoTrack.getNSVDHitsOfOutgoingArm();
142 armTimeErrSum += outgoingArmTimeError * outgoingArmTimeError * recoTrack.getNSVDHitsOfOutgoingArm() *
143 (recoTrack.getNSVDHitsOfOutgoingArm() - 1);
144 numberOfSVDClusters += recoTrack.getNSVDHitsOfOutgoingArm();
145 numberOfRecoTracksUsed += 1;
146 } else if (!hasOutgoingArm && hasIngoingArm) { // check if it has only ingoing arm
147 armTimeSum += ingoingArmTime * recoTrack.getNSVDHitsOfIngoingArm();
148 armTimeErrSum += ingoingArmTimeError * ingoingArmTimeError * recoTrack.getNSVDHitsOfIngoingArm() *
149 (recoTrack.getNSVDHitsOfIngoingArm() - 1);
150 numberOfSVDClusters += recoTrack.getNSVDHitsOfIngoingArm();
151 numberOfRecoTracksUsed += 1;
152 } else continue;
153 }
154
155
156 // 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
157 if ((numberOfRecoTracksUsed == 0) || !(m_eventT0.isValid())) return;
158
159 // otherwise, eventT0 is the average of outgoing/ingoing arm time
160 // that are estimated using SVD clusters associated to recoTracks
161 evtT0 = armTimeSum / numberOfSVDClusters;
162 quality = numberOfSVDClusters;
163
164 // now compute the error
165 if (numberOfSVDClusters > 1)
166 evtT0Err = std::sqrt(armTimeErrSum / (numberOfSVDClusters * (numberOfSVDClusters - 1)));
167 else
168 evtT0Err = std::sqrt(armTimeErrSum);
169
170 // and finally set a temporary EventT0
171 EventT0::EventT0Component evtT0Component(evtT0, evtT0Err, Const::SVD, m_algorithm, quality);
172 m_eventT0->addTemporaryEventT0(evtT0Component);
173 m_eventT0->setEventT0(evtT0Component);
174
175}
176
178{
179
180 const ROOT::Math::XYZVector& position = recoTrack.getPositionSeed();
181 const B2Vector3D& momentum = recoTrack.getMomentumSeed();
182 const TMatrixDSym& covariance = recoTrack.getSeedCovariance();
183 short int charge = recoTrack.getChargeSeed();
184 if (charge < 0) charge = -1;
185 else charge = 1;
186 const float pValue = float(std::numeric_limits<double>::quiet_NaN());
187 const float bField = Belle2::BFieldManager::getFieldInTesla(ROOT::Math::XYZVector(0, 0, 0)).Z();
188
189 const UncertainHelix uncertainHelix(position, momentum, charge, bField, covariance, pValue);
190
191 return uncertainHelix;
192}
static ROOT::Math::XYZVector getFieldInTesla(const ROOT::Math::XYZVector &pos)
return the magnetic field at a given position in Tesla.
Definition: BFieldManager.h:61
Base class for Modules.
Definition: Module.h:72
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
@ 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:611
ROOT::Math::XYZVector getPositionSeed() const
Return the position seed stored in the reco track. ATTENTION: This is not the fitted position.
Definition: RecoTrack.h:480
short int getChargeSeed() const
Return the charge seed stored in the reco track. ATTENTION: This is not the fitted charge.
Definition: RecoTrack.h:508
ROOT::Math::XYZVector getMomentumSeed() const
Return the momentum seed stored in the reco track. ATTENTION: This is not the fitted momentum.
Definition: RecoTrack.h:487
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.
DBObjPtr< SVDEventT0Configuration > m_svdEventT0Config
SVD EventT0 Reconstruction Configuration payload.
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.
virtual ~SVDEventT0EstimatorModule()
default destructor
bool m_useDB
To compute EvetT0, use configuration of selections stored in the DB.
SVDEventT0EstimatorModule()
Constructor defining the parameters.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
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