Belle II Software development
VXDSimpleClusterizerModule.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/VXDTFHelperTools/VXDSimpleClusterizerModule.h>
10#include <vxd/geometry/SensorInfoBase.h>
11#include <vxd/geometry/GeoCache.h>
12
13#include <framework/datastore/StoreObjPtr.h>
14#include <framework/dataobjects/EventMetaData.h>
15#include <framework/logging/Logger.h>
16
17//C++ std lib
18#include <vector>
19#include <string>
20#include <cmath>
21using std::sin;
22using std::cos;
23using std::sqrt;
24
25//root stuff
26#include <TRandom.h>
27
28using namespace Belle2;
29
30REG_MODULE(VXDSimpleClusterizer);
31
33{
35
36
37 setDescription("The VXDSimpleClusterizerModule generates PXD/SVD Clusters using TrueHits. Energy-deposit threshold and gaussian smearing can be chosen, non-primary-particles can be filtered as well. Its purpose is fast clusterizing for tracking test procedures, using standardized PXD/SVD-Cluster");
39
40 addParam("energyThresholdU", m_energyThresholdU,
41 "particles with energy deposit in U lower than this will not create a cluster in SVD (GeV)", double(17.4E-6));
42 addParam("energyThresholdV", m_energyThresholdV,
43 "particles with energy deposit in V lower than this will not create a cluster in SVD (GeV)", double(28.6E-6));
44 addParam("energyThreshold", m_energyThreshold,
45 "particles with energy deposit lower than this will not create a cluster in PXD (GeV)", double(7E-6));
46 addParam("onlyPrimaries", m_onlyPrimaries, "if true use only primary particles from the generator no particles created by Geant4",
47 false);
48 addParam("uniSigma", m_uniSigma,
49 "you can define the sigma of the smearing. Standard value is the sigma of the unifom distribution for 0-1: 1/sqrt(12)",
50 double(1. / sqrt(12.)));
51 addParam("setMeasSigma", m_setMeasSigma,
52 "if positive value (in cm) is given it will be used as the sigma to smear the Clusters otherwise pitch/uniSigma will be used",
53 -1.0);
54 addParam("PXDTrueHits", m_pxdTrueHitsName,
55 "PXDTrueHit collection name", std::string(""));
56 addParam("SVDTrueHits", m_svdTrueHitsName,
57 "SVDTrueHit collection name", std::string(""));
58 addParam("MCParticles", m_mcParticlesName,
59 "MCParticle collection name", std::string(""));
60 addParam("PXDClusters", m_pxdClustersName,
61 "PXDCluster collection name", std::string(""));
62 addParam("SVDClusters", m_svdClustersName,
63 "SVDCluster collection name", std::string(""));
64}
65
66
68{
69 //input containers:
73
74 // initializing StoreArrays for clusters. needed to give them the names set by parameters
77
78 if (m_pxdTrueHits.isOptional() == true) {
79
80 //Relations to cluster objects only if the ancestor relations exist:
84
85 if (m_mcParticles.isOptional() == true) {
88 }
89 }
90
91 if (m_svdTrueHits.isOptional() == true) {
92
93 //Relations to cluster objects only if the ancestor relations exist:
97
98 if (m_mcParticles.isOptional() == true) {
101 }
102 }
103}
104
105
106
108{
109 std::string paramValue;
110 if (m_onlyPrimaries == true) {
111 paramValue = "true, means that there are no secondary hits (for 1-track events this means no ghost hits guaranteed)";
112 } else {
113 paramValue = "false, means that secondary hits can occur and increase the rate of ghost hits";
114 }
115 B2INFO("VXDSimpleClusterizer: parameter onlyPrimaries is set to " << paramValue);
116
118}
119
120
121
123{
124 // counter for cases when a trueHit god discarded:
125 int discardedPXDEdeposit = 0, discardedSVDEdeposit = 0, discardedPXDFake = 0, discardedSVDFake = 0;
126
127 const StoreObjPtr<EventMetaData> eventMetaDataPtr("EventMetaData", DataStore::c_Event);
128
129 B2DEBUG(5, "******* VXDSimpleClusterizerModule processing event number: " << eventMetaDataPtr->getEvent() << " *******");
130
131
132 //check all the input containers. First: MCParticles
133 int nMcParticles = m_mcParticles.getEntries();
134 if (nMcParticles == 0) {B2DEBUG(21, "MCTrackFinder: MCParticlesCollection is empty!");}
135 //PXD
136 int nPxdTrueHits = m_pxdTrueHits.getEntries();
137 if (nPxdTrueHits == 0) {B2DEBUG(21, "MCTrackFinder: PXDHitsCollection is empty!");}
138 //SVD
139 int nSvdTrueHits = m_svdTrueHits.getEntries();
140 if (nSvdTrueHits == 0) {B2DEBUG(21, "MCTrackFinder: SVDHitsCollection is empty!");}
141 B2DEBUG(27, "found " << nMcParticles << "/" << nPxdTrueHits << "/" << nSvdTrueHits << " mcParticles, pxdTrueHits, svdTrueHits");
142
143
144 double sigmaU = m_setMeasSigma;
145 double sigmaV = m_setMeasSigma;
146
147
149 for (unsigned int currentTrueHit = 0; int (currentTrueHit) not_eq nPxdTrueHits; ++currentTrueHit) {
150 B2DEBUG(27, "begin PXD current TrueHit: " << currentTrueHit << " of nPxdTrueHits total: " << nPxdTrueHits);
151
152 const PXDTrueHit* aPxdTrueHit = m_pxdTrueHits[currentTrueHit];
153 const MCParticle* aMcParticle = aPxdTrueHit->getRelatedFrom<MCParticle>();
154 unsigned int particleID = std::numeric_limits<unsigned int>::max();
155
156 if (aMcParticle != nullptr) { particleID = aMcParticle->getArrayIndex(); }
157
158 double energy = aPxdTrueHit->getEnergyDep();
159
160
161 if (m_onlyPrimaries == true) { // ignore hits not coming from primary particles (e.g material effects particles)
162 if (aMcParticle == nullptr or aMcParticle->hasStatus(MCParticle::c_PrimaryParticle) == false) {
164 discardedPXDFake++;
165 continue; // jump to next pxdTrueHit
166 }
167 }
168
169 B2DEBUG(21, " PXD, current TrueHit " << currentTrueHit << " connected to " << particleID << " has an energy deposit of " <<
170 energy * 1000.0 << "MeV ");
171 if (energy < m_energyThreshold) { //ignore hit if energy deposit is too small
172 B2DEBUG(21, " PXD, TrueHit discarded because of energy deposit too small");
174 discardedPXDEdeposit++;
175 continue;
176 }
177
178 //smear the pxdTrueHit and get needed variables for storing
179 VxdID aVXDId = aPxdTrueHit->getSensorID();
180 double uTrue = aPxdTrueHit->getU();
181 double vTrue = aPxdTrueHit->getV();
182 double u = -20;
183 double v = -20;
184 if (m_setMeasSigma < 0.0) {
185 const VXD::SensorInfoBase* sensorInfo = &VXD::GeoCache::getInstance().getSensorInfo(aVXDId);
186 sigmaU = sensorInfo->getUPitch(uTrue) * m_uniSigma;
187 sigmaV = sensorInfo->getVPitch(vTrue) * m_uniSigma;
188 }
189 B2DEBUG(27, "sigU sigV: " << sigmaU << " " << sigmaV);
190
191 if (m_setMeasSigma != 0) {
192 u = gRandom->Gaus(uTrue, sigmaU);
193 v = gRandom->Gaus(vTrue, sigmaV);
194 } else {
195 u = uTrue;
196 v = vTrue;
197 }
198
199 if (m_setMeasSigma == 0 and m_uniSigma == 0) {
200 // in this case, the hits will not be smeared, but still we need some measurement error-values to be able to do some fitting... WARNING currently arbitrary values here, better solution recommended!
201 sigmaU = 0.000001;
202 sigmaV = 0.000001;
203 }
204
205 // Save as new 2D-PXD-cluster
206 PXDCluster* newCluster = m_pxdClusters.appendNew(aVXDId, u, v, sigmaU, sigmaV, 0, 1, 1, 1, 1, 1, 1, 1);
207 // add relations
208 newCluster->addRelationTo(m_pxdTrueHits[currentTrueHit]);
209
210 if (particleID != std::numeric_limits<unsigned int>::max()) {
211 newCluster->addRelationTo(m_mcParticles[particleID]);
212 B2DEBUG(20, "mcParticle " << particleID << " has " << aMcParticle->getRelationsTo<PXDCluster>().size() <<
213 " relations to PXD clusters");
214 }
215 }
216
217
218
220 for (unsigned int currentTrueHit = 0; int (currentTrueHit) not_eq nSvdTrueHits; ++currentTrueHit) {
221 B2DEBUG(27, "begin SVD current TrueHit: " << currentTrueHit << " of nSvdTrueHits total: " << nSvdTrueHits);
222
223 const SVDTrueHit* aSvdTrueHit = m_svdTrueHits[currentTrueHit];
224 const MCParticle* aMcParticle = aSvdTrueHit->getRelatedFrom<MCParticle>();
225 unsigned int particleID = std::numeric_limits<unsigned int>::max();
226
227 if (m_onlyPrimaries == true) { // ignore hits not coming from primary particles (e.g material effects particles)
228 if (aMcParticle == nullptr or aMcParticle->hasStatus(MCParticle::c_PrimaryParticle) == false) {
230 discardedSVDFake++;
231 continue; // jump to next svdTrueHit
232 }
233 }
234
235 if (aMcParticle != nullptr) { particleID = aMcParticle->getArrayIndex(); }
236 double energy = aSvdTrueHit->getEnergyDep();
237
238 B2DEBUG(21, " SVD, current TrueHit " << currentTrueHit << " connected to " << particleID << " has an energy deposit of " <<
239 energy * 1000.0 << "MeV ");
240 if (energy < (m_energyThresholdU + m_energyThresholdV)) { //ignore hit if energy deposity is too snall
242 discardedSVDEdeposit++;
243 B2DEBUG(21, " SVD, TrueHit discarded because of energy deposit too small");
244 continue;
245 }
246
247
248 // smear the SvdTrueHit and get needed variables for storing
249 VxdID aVXDId = aSvdTrueHit->getSensorID();
250 double uTrue = aSvdTrueHit->getU();
251 double vTrue = aSvdTrueHit->getV();
252 double u = -20;
253 double v = -20;
254 if (m_setMeasSigma < 0.0) {
255 const VXD::SensorInfoBase* sensorInfo = &VXD::GeoCache::getInstance().getSensorInfo(aVXDId);
256 sigmaU = sensorInfo->getUPitch(uTrue) * m_uniSigma;
257 sigmaV = sensorInfo->getVPitch(vTrue) * m_uniSigma;
258 }
259 B2DEBUG(25, "sigU sigV: " << sigmaU << " " << sigmaV);
260
261 if (m_setMeasSigma != 0) {
262 u = gRandom->Gaus(uTrue, sigmaU);
263 v = gRandom->Gaus(vTrue, sigmaV);
264 } else {
265 u = uTrue;
266 v = vTrue;
267 }
268
269 if (m_setMeasSigma == 0) {
270 // in this case, the hits will not be smeared, but still we need some measurement error-values to be able to do some fitting... WARNING currently arbitrary values here, better solution recommended!
271 sigmaU = 0.000001;
272 sigmaV = 0.000001;
273 }
274
275 // Save as two new 1D-SVD-clusters
276 double timeStamp = m_svdTrueHits[currentTrueHit]->getGlobalTime();
277
278 SVDCluster* newClusterU = m_svdClusters.appendNew(aVXDId, true, u, sigmaU, timeStamp, 0, 1, 1,
279 3, 1); // in a typical situation 3-5 Strips are excited per Hit -> set to 3
280 // add relations to u-cluster
281 newClusterU->addRelationTo(m_svdTrueHits[currentTrueHit]);
282
283 SVDCluster* newClusterV = m_svdClusters.appendNew(aVXDId, false, v, sigmaV, timeStamp, 0, 1, 1, 3, 1);
284 // add relations to v-cluster
285 newClusterV->addRelationTo(m_svdTrueHits[currentTrueHit]);
286
287 if (particleID != std::numeric_limits<unsigned int>::max()) {
288 newClusterU->addRelationTo(m_mcParticles[particleID]);
289 newClusterV->addRelationTo(m_mcParticles[particleID]);
290 B2DEBUG(20, "mcParticle " << particleID << " has " << aMcParticle->getRelationsTo<SVDCluster>().size() <<
291 " relations to SVD clusters");
292 }
293
294 }
295
296 B2DEBUG(20, "------------------------------------------------------");
297
298 B2DEBUG(20, "VXDSimpleClusterizerModule: Number of PXDHits: " << nPxdTrueHits);
299 B2DEBUG(20, "VXDSimpleClusterizerModule: Number of SVDDHits: " << nSvdTrueHits);
300 B2DEBUG(20, "VXDSimpleClusterizerModule: total Number of MCParticles: " << nMcParticles);
301 B2DEBUG(20, "pxdClusters.getEntries()" << m_pxdClusters.getEntries());
302 B2DEBUG(20, "svdClusters.getEntries()" << m_svdClusters.getEntries());
303 B2DEBUG(20, "------------------------------------------------------");
304
305 B2DEBUG(20, "VXDSimpleClusterizer - event " << eventMetaDataPtr->getEvent() << ":\n" << "of " << nPxdTrueHits << "/" << nSvdTrueHits
306 << " PXD-/SVDTrueHits, " << discardedPXDEdeposit << "/" << discardedSVDEdeposit << " hits were discarded bec. of low E-deposit & "
307 << discardedPXDFake << "/" << discardedSVDFake << " hits were discarded bec. of being a fake. " << m_pxdClusters.getEntries() << "/"
308 << m_svdClusters.getEntries() << " Clusters were stored.\n");
309}
310
311
312
314{
315 B2INFO("VXDSimpleClusterizerModule::EndRun:\nSimpleClusterizerModule discarded " << m_weakPXDHitCtr << " PXDTrueHits and " <<
316 m_weakSVDHitCtr << " SVDTrueHits because of low E-deposit-threshold and discarded " << m_fakePXDHitCtr << " PXDTrueHits and " <<
317 m_fakeSVDHitCtr << " SVDTrueHits because they were fake");
318}
R E
internal precision of FFTW codelets
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition: DataStore.h:72
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
Definition: DataStore.h:59
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:47
bool hasStatus(unsigned short int bitmask) const
Return if specific status bit is set.
Definition: MCParticle.h:129
int getArrayIndex() const
Get 0-based index of the particle in the corresponding MCParticle list.
Definition: MCParticle.h:244
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
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:30
Class PXDTrueHit - Records of tracks that either enter or leave the sensitive volume.
Definition: PXDTrueHit.h:31
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
FROM * getRelatedFrom(const std::string &name="", const std::string &namedRelation="") const
Get the object from which this object has a relation.
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:29
Class SVDTrueHit - Records of tracks that either enter or leave the sensitive volume.
Definition: SVDTrueHit.h:33
const std::string & getName() const
Return name under which the object is saved in the DataStore.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:140
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
std::string m_svdTrueHitsName
SVDTrueHit collection name.
std::string m_svdClustersName
SVDCluster collection name.
int m_fakePXDHitCtr
counts PXDHits which were not caused by a primary partice
double m_energyThreshold
set energy threshold for PXDClusters in GeV (standard is 7E-6)
double m_energyThresholdV
set energy threshold for SVDClusters in v-direction in GeV (standard is 28.6E-6)
StoreArray< SVDTrueHit > m_svdTrueHits
the storeArray for svdTrueHits as member, is faster than recreating link for each event
StoreArray< PXDTrueHit > m_pxdTrueHits
the storeArray for pxdTrueHits as member, is faster than recreating link for each event
void initialize() override
Initialize the Module.
double m_uniSigma
you can define the sigma of the smearing.
std::string m_mcParticlesName
MCParticle collection name.
StoreArray< SVDCluster > m_svdClusters
the storeArray for svdClusters as member, is faster than recreating link for each event
void event() override
This method is the core of the module.
void endRun() override
This method is called if the current run ends.
int m_weakPXDHitCtr
counts PXDHits whose energy deposit is lower than energyThreshold
int m_weakSVDHitCtr
counts SVDHits whose energy deposit is lower than energyThreshold
std::string m_pxdClustersName
PXDCluster collection name.
double m_setMeasSigma
if positive value (in cm) is given it will be used as the sigma to smear the Clusters otherwise pitch...
void beginRun() override
Called when entering a new run.
void InitializeVariables()
initialize variables to avoid nondeterministic behavior
std::string m_pxdTrueHitsName
PXDTrueHit collection name.
StoreArray< PXDCluster > m_pxdClusters
the storeArray for pxdClusters as member, is faster than recreating link for each event
StoreArray< MCParticle > m_mcParticles
the storeArray for mcParticles as member, is faster than recreating link for each event
bool m_onlyPrimaries
set True if you do not want to have hits by secondary particles
VXDSimpleClusterizerModule()
Constructor of the module.
int m_fakeSVDHitCtr
counts SVDHits which were not caused by a primary partice
double m_energyThresholdU
set energy threshold for SVDClusters in u-direction in GeV (standard is 17.4E-6)
float getV() const
Return local v coordinate of hit.
Definition: VXDTrueHit.h:76
float getEnergyDep() const
Return energy deposited during traversal of sensor.
Definition: VXDTrueHit.h:92
VxdID getSensorID() const
Return the Sensor ID.
Definition: VXDTrueHit.h:70
float getU() const
Return local u coordinate of hit.
Definition: VXDTrueHit.h:74
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne to the SensorInfo of a given SensorID.
Definition: GeoCache.cc:67
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:214
Base class to provide Sensor Information for PXD and SVD.
double getUPitch(double v=0) const
Return the pitch of the sensor.
double getVPitch(double v=0) const
Return the pitch of the sensor.
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
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
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.