Belle II Software  release-08-01-10
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>
21 using std::sin;
22 using std::cos;
23 using std::sqrt;
24 
25 //root stuff
26 #include <TRandom.h>
27 
28 using namespace Belle2;
29 
30 REG_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:
71  m_pxdTrueHits.isOptional(m_pxdTrueHitsName);
72  m_svdTrueHits.isOptional(m_svdTrueHitsName);
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:
83  m_pxdTrueHitsName = m_pxdTrueHits.getName();
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:
96  m_svdTrueHitsName = m_svdTrueHits.getName();
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) { // ingore hits not comming from primary particles (e.g material effects particles)
162  if (aMcParticle == nullptr or aMcParticle->hasStatus(MCParticle::c_PrimaryParticle) == false) {
163  m_fakePXDHitCtr++;
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");
173  m_weakPXDHitCtr++;
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 arbritary 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) { // ingore hits not comming from primary particles (e.g material effects particles)
228  if (aMcParticle == nullptr or aMcParticle->hasStatus(MCParticle::c_PrimaryParticle) == false) {
229  m_fakeSVDHitCtr++;
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
241  m_weakSVDHitCtr++;
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 arbritary 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).
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
FROM * getRelatedFrom(const std::string &name="", const std::string &namedRelation="") const
Get the object from which this object has a relation.
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
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
const std::string & getName() const
Return name under which the object is saved in the DataStore.
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
REG_MODULE(arichBtest)
Register the Module.
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
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.