Belle II Software  release-06-00-14
SVDClusterizerModule.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 <svd/modules/svdReconstruction/SVDClusterizerModule.h>
10 
11 #include <framework/datastore/DataStore.h>
12 #include <framework/datastore/RelationArray.h>
13 #include <framework/datastore/RelationIndex.h>
14 #include <framework/logging/Logger.h>
15 #include <framework/core/Environment.h>
16 
17 #include <svd/geometry/SensorInfo.h>
18 #include <svd/dataobjects/SVDEventInfo.h>
19 
20 #include <svd/reconstruction/SVDReconstructionBase.h>
21 
22 #include <svd/reconstruction/SVDRecoTimeFactory.h>
23 #include <svd/reconstruction/SVDRecoChargeFactory.h>
24 #include <svd/reconstruction/SVDRecoPositionFactory.h>
25 
26 
27 using namespace std;
28 using namespace Belle2;
29 using namespace Belle2::SVD;
30 
31 
32 //-----------------------------------------------------------------
33 // Register the Module
34 //-----------------------------------------------------------------
35 REG_MODULE(SVDClusterizer)
36 
37 //-----------------------------------------------------------------
38 // Implementation
39 //-----------------------------------------------------------------
40 
42  m_cutSeed(5.0), m_cutAdjacent(3.0), m_useDB(true)
43 {
44  //Set module properties
45  setDescription("This module produces SVDClusters from SVDShaperDigits, providing 1-D hit position, charge and time on SVD sensors.");
46  setPropertyFlags(c_ParallelProcessingCertified);
47 
48  // 1. Collections.
49  addParam("ShaperDigits", m_storeShaperDigitsName,
50  "SVDShaperDigits collection name.", string(""));
51  addParam("Clusters", m_storeClustersName,
52  "SVDCluster collection name.", string(""));
53  addParam("SVDTrueHits", m_storeTrueHitsName,
54  "TrueHit collection name.", string(""));
55  addParam("MCParticles", m_storeMCParticlesName,
56  "MCParticles collection name.", string(""));
57 
58  // 2. Clustering
59  addParam("AdjacentSN", m_cutAdjacent,
60  "minimum SNR for strips to be considered for clustering. Overwritten by the dbobject, unless you set useDB = False.",
61  m_cutAdjacent);
62  addParam("returnClusterRawTime", m_returnRawClusterTime,
63  "if True, returns the raw cluster time (to be used for time calibration).",
64  m_returnRawClusterTime);
65  addParam("SeedSN", m_cutSeed,
66  "minimum SNR for strips to be considered as cluster seed. Overwritten by the dbobject, unless you set useDB = False.", m_cutSeed);
67  addParam("ClusterSN", m_cutCluster,
68  "minimum value of the SNR of the cluster. Overwritten by the dbobject, unless you set useDB = False.", m_cutCluster);
69  addParam("timeAlgorithm6Samples", m_timeRecoWith6SamplesAlgorithm,
70  "cluster-time reconstruction algorithm for the 6-sample DAQ mode: CoG6 = 6-sample CoG (default), CoG3 = 3-sample CoG, ELS3 = 3-sample ELS. Overwritten by the dbobject, unless you set useDB = False.",
71  m_timeRecoWith6SamplesAlgorithm);
72  addParam("timeAlgorithm3Samples", m_timeRecoWith3SamplesAlgorithm,
73  "cluster-time reconstruction algorithm for the 3-sample DAQ mode: CoG6 = 6-sample CoG, CoG3 = 3-sample CoG (default), ELS3 = 3-sample ELS. Overwritten by the dbobject, unless you set useDB = False.",
74  m_timeRecoWith3SamplesAlgorithm);
75  addParam("chargeAlgorithm6Samples", m_chargeRecoWith6SamplesAlgorithm,
76  "cluster-charge reconstruction algorithm for 6-sample DAQ mode: MaxSample (default), SumSamples, ELS3 = 3-sample ELS. Overwritten by the dbobject, unless you set useDB = False.",
77  m_chargeRecoWith6SamplesAlgorithm);
78  addParam("chargeAlgorithm3Samples", m_chargeRecoWith3SamplesAlgorithm,
79  "cluster-charge reconstruction algorithm for 3-sample DAQ mode: MaxSample (default), SumSamples, ELS3 = 3-sample ELS. Overwritten by the dbobject, unless you set useDB = False.",
80  m_chargeRecoWith3SamplesAlgorithm);
81  addParam("positionAlgorithm6Samples", m_positionRecoWith6SamplesAlgorithm,
82  "cluster-position reconstruction algorithm for 6-sample DAQ mode: old (default), CoGOnly. Overwritten by the dbobject, unless you set useDB = False.",
83  m_positionRecoWith6SamplesAlgorithm);
84  addParam("positionAlgorithm3Samples", m_positionRecoWith3SamplesAlgorithm,
85  "cluster-position reconstruction algorithm for 3-sample DAQ mode: old (default), CoGOnly. Overwritten by the dbobject, unless you set useDB = False.",
86  m_positionRecoWith3SamplesAlgorithm);
87 
88  addParam("stripTimeAlgorithm6Samples", m_stripTimeRecoWith6SamplesAlgorithm,
89  "strip-time reconstruction algorithm used for cluster position reconstruction for the 6-sample DAQ mode: dontdo = not done (default), CoG6 = 6-sample CoG, CoG3 = 3-sample CoG, ELS3 = 3-sample ELS. Overwritten by the dbobject, unless you set useDB = False.",
90  m_stripTimeRecoWith6SamplesAlgorithm);
91  addParam("stripTimeAlgorithm3Samples", m_stripTimeRecoWith3SamplesAlgorithm,
92  "strip-time reconstruction algorithm used for cluster position reconstruction for the 3-sample DAQ mode: dontdo = not done (default), CoG6 = 6-sample CoG, CoG3 = 3-sample CoG, ELS3 = 3-sample ELS. Overwritten by the dbobject, unless you set useDB = False.",
93  m_stripTimeRecoWith3SamplesAlgorithm);
94  addParam("stripChargeAlgorithm6Samples", m_stripChargeRecoWith6SamplesAlgorithm,
95  "strip-charge reconstruction algorithm used for cluster position reconstruction for the 6-sample DAQ mode: dontdo = not done, MaxSample, SumSamples, ELS3 = 3-sample ELS. Overwritten by the dbobject, unless you set useDB = False.",
96  m_stripChargeRecoWith6SamplesAlgorithm);
97  addParam("stripChargeAlgorithm3Samples", m_stripChargeRecoWith3SamplesAlgorithm,
98  "strip-charge reconstruction algorithm used for cluster position reconstruction for the 3-sample DAQ mode: dontdo = not done, MaxSample, SumSamples, ELS3 = 3-sample ELS. Overwritten by the dbobject, unless you set useDB = False.",
99  m_stripChargeRecoWith3SamplesAlgorithm);
100 
101  addParam("useDB", m_useDB,
102  "if False, use clustering and reconstruction configuration module parameters", m_useDB);
103 
104 }
105 
106 void SVDClusterizerModule::beginRun()
107 {
108  if (m_useDB) {
109  if (!m_recoConfig.isValid())
110  B2FATAL("no valid configuration found for SVD reconstruction");
111  else
112  B2INFO("SVDRecoConfiguration: from now on we are using " << m_recoConfig->get_uniqueID());
113 
114  m_timeRecoWith6SamplesAlgorithm = m_recoConfig->getTimeRecoWith6Samples();
115  m_timeRecoWith3SamplesAlgorithm = m_recoConfig->getTimeRecoWith3Samples();
116  m_chargeRecoWith6SamplesAlgorithm = m_recoConfig->getChargeRecoWith6Samples();
117  m_chargeRecoWith3SamplesAlgorithm = m_recoConfig->getChargeRecoWith3Samples();
118  m_positionRecoWith6SamplesAlgorithm = m_recoConfig->getPositionRecoWith6Samples();
119  m_positionRecoWith3SamplesAlgorithm = m_recoConfig->getPositionRecoWith3Samples();
120 
121  //strip algorithms
122  m_stripTimeRecoWith6SamplesAlgorithm = m_recoConfig->getStripTimeRecoWith6Samples();
123  m_stripTimeRecoWith3SamplesAlgorithm = m_recoConfig->getStripTimeRecoWith3Samples();
124  m_stripChargeRecoWith6SamplesAlgorithm = m_recoConfig->getStripChargeRecoWith6Samples();
125  m_stripChargeRecoWith3SamplesAlgorithm = m_recoConfig->getStripChargeRecoWith3Samples();
126 
127  }
128  //check that all algorithms are available, otherwise use the default one
129  SVDReconstructionBase recoBase;
130 
131  if (!recoBase.isTimeAlgorithmAvailable(m_timeRecoWith6SamplesAlgorithm)) {
132  B2WARNING("cluster time algorithm " << m_timeRecoWith6SamplesAlgorithm << " is NOT available, using CoG3");
133  m_timeRecoWith6SamplesAlgorithm = "CoG3";
134  };
135 
136  if (!recoBase.isTimeAlgorithmAvailable(m_timeRecoWith3SamplesAlgorithm)) {
137  B2WARNING("cluster time algorithm " << m_timeRecoWith3SamplesAlgorithm << " is NOT available, using CoG3");
138  m_timeRecoWith3SamplesAlgorithm = "CoG3";
139  };
140  if (!recoBase.isChargeAlgorithmAvailable(m_chargeRecoWith6SamplesAlgorithm)) {
141  B2WARNING("cluster charge algorithm " << m_chargeRecoWith6SamplesAlgorithm << " is NOT available, using MaxSample");
142  m_chargeRecoWith6SamplesAlgorithm = "MaxSample";
143  };
144  if (!recoBase.isChargeAlgorithmAvailable(m_chargeRecoWith3SamplesAlgorithm)) {
145  B2WARNING("cluster charge algorithm " << m_chargeRecoWith3SamplesAlgorithm << " is NOT available, using MaxSample");
146  m_chargeRecoWith3SamplesAlgorithm = "MaxSample";
147  };
148  if (!recoBase.isPositionAlgorithmAvailable(m_positionRecoWith6SamplesAlgorithm)) {
149  B2WARNING("cluster position algorithm " << m_positionRecoWith6SamplesAlgorithm << " is NOT available, using OldDefault");
150  m_positionRecoWith6SamplesAlgorithm = "OldDefault";
151  };
152  if (!recoBase.isPositionAlgorithmAvailable(m_positionRecoWith3SamplesAlgorithm)) {
153  B2WARNING("cluster position algorithm " << m_positionRecoWith3SamplesAlgorithm << " is NOT available, using OldDefault");
154  m_positionRecoWith3SamplesAlgorithm = "OldDefault";
155  };
156 
157 
158  m_time6SampleClass = SVDRecoTimeFactory::NewTime(m_timeRecoWith6SamplesAlgorithm, m_returnRawClusterTime);
159  m_time3SampleClass = SVDRecoTimeFactory::NewTime(m_timeRecoWith3SamplesAlgorithm, m_returnRawClusterTime);
160  m_charge6SampleClass = SVDRecoChargeFactory::NewCharge(m_chargeRecoWith6SamplesAlgorithm);
161  m_charge3SampleClass = SVDRecoChargeFactory::NewCharge(m_chargeRecoWith3SamplesAlgorithm);
162  m_position6SampleClass = SVDRecoPositionFactory::NewPosition(m_positionRecoWith6SamplesAlgorithm);
163  m_position6SampleClass->set_stripChargeAlgo(m_stripChargeRecoWith6SamplesAlgorithm);
164  m_position6SampleClass->set_stripTimeAlgo(m_stripTimeRecoWith6SamplesAlgorithm);
165  m_position3SampleClass = SVDRecoPositionFactory::NewPosition(m_positionRecoWith3SamplesAlgorithm);
166  m_position3SampleClass->set_stripChargeAlgo(m_stripChargeRecoWith3SamplesAlgorithm);
167  m_position3SampleClass->set_stripTimeAlgo(m_stripTimeRecoWith3SamplesAlgorithm);
168 
169  string israwtime = "";
170  if (m_returnRawClusterTime) israwtime = " (raw)";
171  B2INFO("SVD 6-sample DAQ, cluster time algorithm: " << m_timeRecoWith6SamplesAlgorithm << israwtime <<
172  ", cluster charge algorithm: " <<
173  m_chargeRecoWith6SamplesAlgorithm << ", cluster position algorithm: " << m_positionRecoWith6SamplesAlgorithm);
174  B2INFO(" with strip charge reconstructed with " << m_stripChargeRecoWith6SamplesAlgorithm << " and strip time reconstructed with "
175  <<
176  m_stripTimeRecoWith6SamplesAlgorithm);
177 
178  B2INFO("SVD 3-sample DAQ, cluster time algorithm: " << m_timeRecoWith3SamplesAlgorithm << israwtime <<
179  ", cluster charge algorithm: " <<
180  m_chargeRecoWith3SamplesAlgorithm << ", cluster position algorithm: " << m_positionRecoWith3SamplesAlgorithm);
181  B2INFO(" with strip charge reconstructed with " << m_stripChargeRecoWith3SamplesAlgorithm << " and strip time reconstructed with "
182  <<
183  m_stripTimeRecoWith3SamplesAlgorithm);
184 }
185 
186 void SVDClusterizerModule::initialize()
187 {
188  //Register collections
189  m_storeClusters.registerInDataStore(m_storeClustersName, DataStore::c_ErrorIfAlreadyRegistered);
190  m_storeDigits.isRequired(m_storeShaperDigitsName);
191  m_storeTrueHits.isOptional(m_storeTrueHitsName);
192  m_storeMCParticles.isOptional(m_storeMCParticlesName);
193 
194  RelationArray relClusterDigits(m_storeClusters, m_storeDigits);
195  RelationArray relClusterTrueHits(m_storeClusters, m_storeTrueHits);
196  RelationArray relClusterMCParticles(m_storeClusters, m_storeMCParticles);
197  RelationArray relDigitTrueHits(m_storeDigits, m_storeTrueHits);
198  RelationArray relDigitMCParticles(m_storeDigits, m_storeMCParticles);
199 
200  relClusterDigits.registerInDataStore();
201 
202  //Relations to simulation objects only if the ancestor relations exist
203  if (relDigitTrueHits.isOptional())
204  relClusterTrueHits.registerInDataStore();
205 
206  if (relDigitMCParticles.isOptional())
207  relClusterMCParticles.registerInDataStore();
208 
209  //Store names to speed up creation later
210  m_storeClustersName = m_storeClusters.getName();
211  m_storeShaperDigitsName = m_storeDigits.getName();
212  m_storeTrueHitsName = m_storeTrueHits.getName();
213  m_storeMCParticlesName = m_storeMCParticles.getName();
214 
215  m_relClusterShaperDigitName = relClusterDigits.getName();
216  m_relClusterTrueHitName = relClusterTrueHits.getName();
217  m_relClusterMCParticleName = relClusterMCParticles.getName();
218  m_relShaperDigitTrueHitName = relDigitTrueHits.getName();
219  m_relShaperDigitMCParticleName = relDigitMCParticles.getName();
220 
221  // Report:
222  B2DEBUG(20, "SVDClusterizer Parameters (in default system unit, *=cannot be set directly):");
223 
224  B2DEBUG(20, " 1. COLLECTIONS:");
225  B2DEBUG(20, " --> MCParticles: " << m_storeMCParticlesName);
226  B2DEBUG(20, " --> SVDShaperDigits: " << m_storeShaperDigitsName);
227  B2DEBUG(20, " --> SVDClusters: " << m_storeClustersName);
228  B2DEBUG(20, " --> SVDTrueHits: " << m_storeTrueHitsName);
229  B2DEBUG(20, " 2. RELATIONS:");
230  B2DEBUG(20, " --> DigitMCRel: " << m_relShaperDigitMCParticleName);
231  B2DEBUG(20, " --> ClusterMCRel: " << m_relClusterMCParticleName);
232  B2DEBUG(20, " --> ClusterDigitRel: " << m_relClusterShaperDigitName);
233  B2DEBUG(20, " --> DigitTrueRel: " << m_relShaperDigitTrueHitName);
234  B2DEBUG(20, " --> ClusterTrueRel: " << m_relClusterTrueHitName);
235  B2DEBUG(20, " 3. CLUSTERING:");
236  B2DEBUG(20, " --> Neighbour cut: " << m_cutAdjacent);
237  B2DEBUG(20, " --> Seed cut: " << m_cutSeed);
238 }
239 
240 
241 
242 void SVDClusterizerModule::event()
243 {
244  int nDigits = m_storeDigits.getEntries();
245  if (nDigits == 0)
246  return;
247 
248  m_storeClusters.clear();
249 
250 
251  RelationArray relClusterMCParticle(m_storeClusters, m_storeMCParticles,
252  m_relClusterMCParticleName);
253  if (relClusterMCParticle) relClusterMCParticle.clear();
254 
255  RelationArray relClusterDigit(m_storeClusters, m_storeDigits,
256  m_relClusterShaperDigitName);
257  if (relClusterDigit) relClusterDigit.clear();
258 
259  RelationArray relClusterTrueHit(m_storeClusters, m_storeTrueHits,
260  m_relClusterTrueHitName);
261  if (relClusterTrueHit) relClusterTrueHit.clear();
262 
263  if (m_useDB) {
264  m_cutSeed = m_ClusterCal.getMinSeedSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
265  m_cutAdjacent = m_ClusterCal.getMinAdjSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
266  m_cutCluster = m_ClusterCal.getMinClusterSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
267  }
268 
269  //create a dummy cluster just to start
270  RawCluster rawCluster(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip(), m_cutSeed, m_cutAdjacent,
271  m_storeShaperDigitsName);
272 
273  //loop over the SVDShaperDigits
274  for (const SVDShaperDigit& currentDigit : m_storeDigits) {
275 
276  //retrieve the VxdID, sensor and cellID of the current ShaperDigit
277  VxdID thisSensorID = currentDigit.getSensorID();
278  bool thisSide = currentDigit.isUStrip();
279  int thisCellID = currentDigit.getCellID();
280 
281  if (m_useDB) {
282  m_cutSeed = m_ClusterCal.getMinSeedSNR(thisSensorID, thisSide);
283  m_cutAdjacent = m_ClusterCal.getMinAdjSNR(thisSensorID, thisSide);
284  m_cutCluster = m_ClusterCal.getMinClusterSNR(thisSensorID, thisSide);
285  }
286 
287  //Ignore digits with insufficient signal
288  float thisNoise = m_NoiseCal.getNoise(thisSensorID, thisSide, thisCellID);
289  int thisCharge = currentDigit.getMaxADCCounts();
290  B2DEBUG(20, "Noise = " << thisNoise << " ADC, MaxSample = " << thisCharge << " ADC");
291 
292  if ((float)thisCharge / thisNoise < m_cutAdjacent)
293  continue;
294 
295  //this strip has a sufficient S/N
296  StripInRawCluster aStrip;
297  aStrip.shaperDigitIndex = currentDigit.getArrayIndex();
298  aStrip.maxSample = thisCharge;
299  aStrip.cellID = thisCellID;
300  aStrip.noise = thisNoise;
301  aStrip.samples = currentDigit.getSamples();
302 
303  //try to add the strip to the existing cluster
304  if (! rawCluster.add(thisSensorID, thisSide, aStrip)) {
305 
306  //if the strip is not added, write the cluster, if present and good:
307  if ((rawCluster.getSize() > 0) && (rawCluster.isGoodRawCluster()))
308  finalizeCluster(rawCluster);
309 
310  //prepare for the next cluster:
311  rawCluster = RawCluster(thisSensorID, thisSide, m_cutSeed, m_cutAdjacent, m_storeShaperDigitsName);
312 
313  //start another cluster:
314  if (! rawCluster.add(thisSensorID, thisSide, aStrip))
315  B2WARNING("this state is forbidden!!");
316 
317  }
318  } //exit loop on ShaperDigits
319 
320  //write the last cluster, if good
321  if ((rawCluster.getSize() > 0) && (rawCluster.isGoodRawCluster()))
322  finalizeCluster(rawCluster);
323 
324  B2DEBUG(20, "Number of clusters: " << m_storeClusters.getEntries());
325 }
326 
327 
328 void SVDClusterizerModule::finalizeCluster(Belle2::SVD::RawCluster& rawCluster)
329 {
330 
331  VxdID sensorID = rawCluster.getSensorID();
332  bool isU = rawCluster.isUSide();
333  int size = rawCluster.getSize();
334 
335  //first take Event Informations:
336  StoreObjPtr<SVDEventInfo> temp_eventinfo("SVDEventInfo");
337  std::string m_svdEventInfoName = "SVDEventInfo";
338  if (!temp_eventinfo.isValid())
339  m_svdEventInfoName = "SVDEventInfoSim";
340  StoreObjPtr<SVDEventInfo> eventinfo(m_svdEventInfoName);
341  if (!eventinfo) B2ERROR("No SVDEventInfo!");
342 
343  m_numberOfAcquiredSamples = eventinfo->getNSamples();
344 
345  //--------------
346  // CLUSTER RECO
347  //--------------
348  double time = std::numeric_limits<double>::quiet_NaN();
349  double timeError = std::numeric_limits<double>::quiet_NaN();
350  int firstFrame = std::numeric_limits<int>::quiet_NaN();
351 
352  double charge = std::numeric_limits<double>::quiet_NaN();
353  double seedCharge = std::numeric_limits<float>::quiet_NaN();
354  double SNR = std::numeric_limits<double>::quiet_NaN();
355 
356  double position = std::numeric_limits<float>::quiet_NaN();
357  double positionError = std::numeric_limits<float>::quiet_NaN();
358 
359 
360  if (m_numberOfAcquiredSamples == 6) {
361 
362  //time
363  m_time6SampleClass->computeClusterTime(rawCluster, time, timeError, firstFrame);
364  //charge
365  m_charge6SampleClass->computeClusterCharge(rawCluster, charge, SNR, seedCharge);
366 
367  //position
368  m_position6SampleClass->computeClusterPosition(rawCluster, position, positionError);
369  } else if (m_numberOfAcquiredSamples == 3) {
370  //time
371  m_time3SampleClass->computeClusterTime(rawCluster, time, timeError, firstFrame);
372 
373  //charge
374  m_charge3SampleClass->computeClusterCharge(rawCluster, charge, SNR, seedCharge);
375 
376  //position
377  m_position3SampleClass->computeClusterPosition(rawCluster, position, positionError);
378 
379  } else //we should never get here!
380  B2FATAL("SVD Reconstruction not available for this cluster (unrecognized or not supported number of acquired APV samples!!");
381 
382  // now go into FTSW time reference frame
383  time = eventinfo->getTimeInFTSWReference(time, firstFrame);
384 
385  //apply the Lorentz Shift Correction
386  position = applyLorentzShiftCorrection(position, sensorID, isU);
387 
388  //append the new cluster to the StoreArray...
389  if (SNR > m_cutCluster) {
390  m_storeClusters.appendNew(sensorID, isU, position, positionError, time, timeError, charge, seedCharge, size, SNR, -1,
391  firstFrame);
392 
393  B2DEBUG(20, "CLUSTER SIZE = " << size);
394  B2DEBUG(20, " time = " << time << ", timeError = " << timeError << ", firstframe = " << firstFrame);
395  B2DEBUG(20, " charge = " << charge << ", SNR = " << SNR << ", seedCharge = " << seedCharge);
396  B2DEBUG(20, " position = " << position << ", positionError = " << positionError);
397 
398  //..and write relations
399  writeClusterRelations(rawCluster);
400  }
401 }
402 
403 void SVDClusterizerModule::writeClusterRelations(Belle2::SVD::RawCluster& rawCluster)
404 {
405  RelationArray relClusterDigit(m_storeClusters, m_storeDigits, m_relClusterShaperDigitName);
406 
407  RelationArray relClusterMCParticle(m_storeClusters, m_storeMCParticles, m_relClusterMCParticleName);
408  RelationArray relClusterTrueHit(m_storeClusters, m_storeTrueHits, m_relClusterTrueHitName);
409 
410  RelationIndex<SVDShaperDigit, MCParticle> relDigitMCParticle(m_storeDigits, m_storeMCParticles, m_relShaperDigitMCParticleName);
411  RelationIndex<SVDShaperDigit, SVDTrueHit> relDigitTrueHit(m_storeDigits, m_storeTrueHits, m_relShaperDigitTrueHitName);
412 
413 
414  //register relation between ShaperDigit and Cluster
415  int clsIndex = m_storeClusters.getEntries() - 1;
416 
417  map<int, float> mc_relations;
418  map<int, float> truehit_relations;
419 
420  vector<pair<int, float> > digit_weights;
421  digit_weights.reserve(m_storeClusters[clsIndex]->getSize());
422 
423  std::vector<StripInRawCluster> strips = rawCluster.getStripsInRawCluster();
424 
425  for (const auto& strip : strips) {
426 
427  //Fill map with MCParticle relations
428  if (relDigitMCParticle) {
430  for (relMC_type& mcRel : relDigitMCParticle.getElementsFrom(m_storeDigits[strip.shaperDigitIndex])) {
431  //negative weights are from ignored particles, we don't like them and
432  //thus ignore them :D
433  if (mcRel.weight < 0) continue;
434  mc_relations[mcRel.indexTo] += mcRel.weight;
435  };
436  };
437  //Fill map with SVDTrueHit relations
438  if (relDigitTrueHit) {
439  typedef const RelationIndex<SVDShaperDigit, SVDTrueHit>::Element relTrueHit_type;
440  for (relTrueHit_type& trueRel : relDigitTrueHit.getElementsFrom(m_storeDigits[strip.shaperDigitIndex])) {
441  //negative weights are from ignored particles, we don't like them and
442  //thus ignore them :D
443  if (trueRel.weight < 0) continue;
444  truehit_relations[trueRel.indexTo] += trueRel.weight;
445  };
446  };
447 
448  digit_weights.push_back(make_pair(strip.shaperDigitIndex, strip.maxSample));
449  }
450 
451  //Create Relations to this Digit
452  if (!mc_relations.empty()) {
453  relClusterMCParticle.add(clsIndex, mc_relations.begin(), mc_relations.end());
454  }
455  if (!truehit_relations.empty()) {
456  relClusterTrueHit.add(clsIndex, truehit_relations.begin(), truehit_relations.end());
457  }
458 
459  relClusterDigit.add(clsIndex, digit_weights.begin(), digit_weights.end());
460 
461 }
462 
463 double SVDClusterizerModule::applyLorentzShiftCorrection(double position, VxdID vxdID, bool isU)
464 {
465 
466  //Lorentz shift correction - PATCHED
467  //NOTE: layer 3 is upside down with respect to L4,5,6 in the real data (real SVD), but _not_ in the simulation. We need to change the sign of the Lorentz correction on L3 only if reconstructing data, i.e. if Environment::Instance().isMC() is FALSE.
468 
469  const SensorInfo& sensorInfo = dynamic_cast<const SensorInfo&>(VXD::GeoCache::get(vxdID));
470 
471  bool isMC = Environment::Instance().isMC();
472 
473  if ((vxdID.getLayerNumber() == 3) && ! isMC)
474  position += sensorInfo.getLorentzShift(isU, position);
475  else
476  position -= sensorInfo.getLorentzShift(isU, position);
477 
478  return position;
479 }
480 void SVDClusterizerModule::endRun()
481 {
482 
483  delete m_time6SampleClass;
484  delete m_time3SampleClass;
485  delete m_charge6SampleClass;
486  delete m_charge3SampleClass;
487  delete m_position6SampleClass;
488  delete m_position3SampleClass;
489 
490 }
Base class for Modules.
Definition: Module.h:72
Low-level class to create/modify relations between StoreArrays.
Definition: RelationArray.h:62
void add(index_type from, index_type to, weight_type weight=1.0)
Add a new element to the relation.
void clear() override
Clear all elements from the relation.
Provides access to fast ( O(log n) ) bi-directional lookups on a specified relation.
Definition: RelationIndex.h:76
range_from getElementsFrom(const FROM *from) const
Return a range of all elements pointing from the given object.
The SVD ShaperDigit class.
Class representing a raw cluster candidate during clustering of the SVD.
Definition: RawCluster.h:33
bool add(VxdID vxdID, bool isUside, struct StripInRawCluster &aStrip)
Add a Strip to the current cluster.
Definition: RawCluster.cc:54
bool isUSide() const
Definition: RawCluster.h:85
VxdID getSensorID() const
Definition: RawCluster.h:80
const std::vector< StripInRawCluster > getStripsInRawCluster() const
Definition: RawCluster.h:110
Class to check whether the reconstruction algorithms are available or not.
bool isChargeAlgorithmAvailable(TString chargeAlg)
bool isTimeAlgorithmAvailable(TString timeAlg)
bool isPositionAlgorithmAvailable(TString positionAlg)
Specific implementation of SensorInfo for SVD Sensors which provides additional sensor specific infor...
Definition: SensorInfo.h:25
const TVector3 & getLorentzShift(double uCoord, double vCoord) const
Calculate Lorentz shift along a given coordinate in a magnetic field at a given position.
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.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
bool isValid() const
Check whether the object was created.
Definition: StoreObjPtr.h:110
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
baseType getLayerNumber() const
Get the layer id.
Definition: VxdID.h:96
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Namespace to encapsulate code needed for simulation and reconstrucion of the SVD.
Definition: GeoSVDCreator.h:23
Abstract base class for different kinds of events.
RelationElement::weight_type weight
weight of the relation.
structure containing the relevant informations of each strip of the raw cluster
Definition: RawCluster.h:20
Belle2::SVDShaperDigit::APVFloatSamples samples
ADC of the acquired samples.
Definition: RawCluster.h:25
int shaperDigitIndex
index of the shaper digit
Definition: RawCluster.h:21
int maxSample
ADC max of the acquired samples.
Definition: RawCluster.h:23