Belle II Software  release-08-01-10
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 #include <TRandom.h>
27 
28 #include <math.h>
29 
30 using namespace std;
31 using namespace Belle2;
32 using namespace Belle2::SVD;
33 
34 
35 //-----------------------------------------------------------------
36 // Register the Module
37 //-----------------------------------------------------------------
38 REG_MODULE(SVDClusterizer);
39 
40 //-----------------------------------------------------------------
41 // Implementation
42 //-----------------------------------------------------------------
43 
44 SVDClusterizerModule::SVDClusterizerModule() : Module(),
45  m_cutSeed(5.0), m_cutAdjacent(3.0), m_useDB(true)
46 {
47  //Set module properties
48  setDescription("This module produces SVDClusters from SVDShaperDigits, providing 1-D hit position, charge and time on SVD sensors.");
50 
51  // 1. Collections.
52  addParam("EventInfo", m_svdEventInfoName,
53  "SVDEventInfo collection name.", string("SVDEventInfo"));
54  addParam("ShaperDigits", m_storeShaperDigitsName,
55  "SVDShaperDigits collection name.", string(""));
56  addParam("Clusters", m_storeClustersName,
57  "SVDCluster collection name.", string(""));
58  addParam("SVDTrueHits", m_storeTrueHitsName,
59  "TrueHit collection name.", string(""));
60  addParam("MCParticles", m_storeMCParticlesName,
61  "MCParticles collection name.", string(""));
62 
63  // 2. Clustering
64  addParam("AdjacentSN", m_cutAdjacent,
65  "minimum SNR for strips to be considered for clustering. Overwritten by the dbobject, unless you set useDB = False.",
67  addParam("returnClusterRawTime", m_returnRawClusterTime,
68  "if True, returns the raw cluster time (to be used for time calibration).",
70  addParam("shiftSVDClusterTime", m_shiftSVDClusterTime,
71  "if True, applies SVDCluster time shift based on cluster-size.", m_shiftSVDClusterTime);
72  addParam("SeedSN", m_cutSeed,
73  "minimum SNR for strips to be considered as cluster seed. Overwritten by the dbobject, unless you set useDB = False.", m_cutSeed);
74  addParam("ClusterSN", m_cutCluster,
75  "minimum value of the SNR of the cluster. Overwritten by the dbobject, unless you set useDB = False.", m_cutCluster);
76  addParam("timeAlgorithm6Samples", m_timeRecoWith6SamplesAlgorithm,
77  "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.",
79  addParam("timeAlgorithm3Samples", m_timeRecoWith3SamplesAlgorithm,
80  "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.",
82  addParam("chargeAlgorithm6Samples", m_chargeRecoWith6SamplesAlgorithm,
83  "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.",
85  addParam("chargeAlgorithm3Samples", m_chargeRecoWith3SamplesAlgorithm,
86  "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.",
88  addParam("positionAlgorithm6Samples", m_positionRecoWith6SamplesAlgorithm,
89  "cluster-position reconstruction algorithm for 6-sample DAQ mode: old (default), CoGOnly. Overwritten by the dbobject, unless you set useDB = False.",
91  addParam("positionAlgorithm3Samples", m_positionRecoWith3SamplesAlgorithm,
92  "cluster-position reconstruction algorithm for 3-sample DAQ mode: old (default), CoGOnly. Overwritten by the dbobject, unless you set useDB = False.",
94 
95  addParam("stripTimeAlgorithm6Samples", m_stripTimeRecoWith6SamplesAlgorithm,
96  "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.",
98  addParam("stripTimeAlgorithm3Samples", m_stripTimeRecoWith3SamplesAlgorithm,
99  "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.",
101  addParam("stripChargeAlgorithm6Samples", m_stripChargeRecoWith6SamplesAlgorithm,
102  "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.",
104  addParam("stripChargeAlgorithm3Samples", m_stripChargeRecoWith3SamplesAlgorithm,
105  "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.",
107 
108  addParam("useDB", m_useDB,
109  "if False, use clustering and reconstruction configuration module parameters", m_useDB);
110 
111 }
112 
114 {
115  if (m_useDB) {
116  if (!m_recoConfig.isValid())
117  B2FATAL("no valid configuration found for SVD reconstruction");
118  else
119  B2DEBUG(20, "SVDRecoConfiguration: from now on we are using " << m_recoConfig->get_uniqueID());
120 
121  m_timeRecoWith6SamplesAlgorithm = m_recoConfig->getTimeRecoWith6Samples();
122  //m_timeRecoWith6SamplesAlgorithm = "ELS3";
123  //m_timeRecoWith3SamplesAlgorithm = "ELS3";
124  m_timeRecoWith3SamplesAlgorithm = m_recoConfig->getTimeRecoWith3Samples();
125  m_chargeRecoWith6SamplesAlgorithm = m_recoConfig->getChargeRecoWith6Samples();
126  m_chargeRecoWith3SamplesAlgorithm = m_recoConfig->getChargeRecoWith3Samples();
127  m_positionRecoWith6SamplesAlgorithm = m_recoConfig->getPositionRecoWith6Samples();
128  m_positionRecoWith3SamplesAlgorithm = m_recoConfig->getPositionRecoWith3Samples();
129 
130  //strip algorithms
131  m_stripTimeRecoWith6SamplesAlgorithm = m_recoConfig->getStripTimeRecoWith6Samples();
132  m_stripTimeRecoWith3SamplesAlgorithm = m_recoConfig->getStripTimeRecoWith3Samples();
133  m_stripChargeRecoWith6SamplesAlgorithm = m_recoConfig->getStripChargeRecoWith6Samples();
134  m_stripChargeRecoWith3SamplesAlgorithm = m_recoConfig->getStripChargeRecoWith3Samples();
135 
136  }
137  //check that all algorithms are available, otherwise use the default one
138  SVDReconstructionBase recoBase;
139 
141  B2WARNING("cluster time algorithm " << m_timeRecoWith6SamplesAlgorithm << " is NOT available, using CoG3");
143  };
144 
146  B2WARNING("cluster time algorithm " << m_timeRecoWith3SamplesAlgorithm << " is NOT available, using CoG3");
148  };
150  B2WARNING("cluster charge algorithm " << m_chargeRecoWith6SamplesAlgorithm << " is NOT available, using MaxSample");
151  m_chargeRecoWith6SamplesAlgorithm = "MaxSample";
152  };
154  B2WARNING("cluster charge algorithm " << m_chargeRecoWith3SamplesAlgorithm << " is NOT available, using MaxSample");
155  m_chargeRecoWith3SamplesAlgorithm = "MaxSample";
156  };
158  B2WARNING("cluster position algorithm " << m_positionRecoWith6SamplesAlgorithm << " is NOT available, using OldDefault");
160  };
162  B2WARNING("cluster position algorithm " << m_positionRecoWith3SamplesAlgorithm << " is NOT available, using OldDefault");
164  };
165 
166 
177 
178  string israwtime = "";
179  if (m_returnRawClusterTime) israwtime = " (raw)";
180  B2INFO("SVD 6-sample DAQ, cluster time algorithm: " << m_timeRecoWith6SamplesAlgorithm << israwtime <<
181  ", cluster charge algorithm: " <<
182  m_chargeRecoWith6SamplesAlgorithm << ", cluster position algorithm: " << m_positionRecoWith6SamplesAlgorithm);
183  B2INFO(" with strip charge reconstructed with " << m_stripChargeRecoWith6SamplesAlgorithm << " and strip time reconstructed with "
184  <<
186 
187  B2INFO("SVD 3-sample DAQ, cluster time algorithm: " << m_timeRecoWith3SamplesAlgorithm << israwtime <<
188  ", cluster charge algorithm: " <<
189  m_chargeRecoWith3SamplesAlgorithm << ", cluster position algorithm: " << m_positionRecoWith3SamplesAlgorithm);
190  B2INFO(" with strip charge reconstructed with " << m_stripChargeRecoWith3SamplesAlgorithm << " and strip time reconstructed with "
191  <<
193 }
194 
196 {
197  //Register collections
202 
203  RelationArray relClusterDigits(m_storeClusters, m_storeDigits);
204  RelationArray relClusterTrueHits(m_storeClusters, m_storeTrueHits);
205  RelationArray relClusterMCParticles(m_storeClusters, m_storeMCParticles);
206  RelationArray relDigitTrueHits(m_storeDigits, m_storeTrueHits);
207  RelationArray relDigitMCParticles(m_storeDigits, m_storeMCParticles);
208 
209  relClusterDigits.registerInDataStore();
210 
211  //Relations to simulation objects only if the ancestor relations exist
212  if (relDigitTrueHits.isOptional())
213  relClusterTrueHits.registerInDataStore();
214 
215  if (relDigitMCParticles.isOptional())
216  relClusterMCParticles.registerInDataStore();
217 
218  //Store names to speed up creation later
223 
224  m_relClusterShaperDigitName = relClusterDigits.getName();
225  m_relClusterTrueHitName = relClusterTrueHits.getName();
226  m_relClusterMCParticleName = relClusterMCParticles.getName();
227  m_relShaperDigitTrueHitName = relDigitTrueHits.getName();
228  m_relShaperDigitMCParticleName = relDigitMCParticles.getName();
229 
230  // Report:
231  B2DEBUG(20, "SVDClusterizer Parameters (in default system unit, *=cannot be set directly):");
232 
233  B2DEBUG(20, " 1. COLLECTIONS:");
234  B2DEBUG(20, " --> MCParticles: " << m_storeMCParticlesName);
235  B2DEBUG(20, " --> SVDShaperDigits: " << m_storeShaperDigitsName);
236  B2DEBUG(20, " --> SVDClusters: " << m_storeClustersName);
237  B2DEBUG(20, " --> SVDTrueHits: " << m_storeTrueHitsName);
238  B2DEBUG(20, " 2. RELATIONS:");
239  B2DEBUG(20, " --> DigitMCRel: " << m_relShaperDigitMCParticleName);
240  B2DEBUG(20, " --> ClusterMCRel: " << m_relClusterMCParticleName);
241  B2DEBUG(20, " --> ClusterDigitRel: " << m_relClusterShaperDigitName);
242  B2DEBUG(20, " --> DigitTrueRel: " << m_relShaperDigitTrueHitName);
243  B2DEBUG(20, " --> ClusterTrueRel: " << m_relClusterTrueHitName);
244  B2DEBUG(20, " 3. CLUSTERING:");
245  B2DEBUG(20, " --> Neighbour cut: " << m_cutAdjacent);
246  B2DEBUG(20, " --> Seed cut: " << m_cutSeed);
247 }
248 
249 
250 
252 {
253  int nDigits = m_storeDigits.getEntries();
254  if (nDigits == 0)
255  return;
256 
258 
259 
260  RelationArray relClusterMCParticle(m_storeClusters, m_storeMCParticles,
262  if (relClusterMCParticle) relClusterMCParticle.clear();
263 
266  if (relClusterDigit) relClusterDigit.clear();
267 
268  RelationArray relClusterTrueHit(m_storeClusters, m_storeTrueHits,
270  if (relClusterTrueHit) relClusterTrueHit.clear();
271 
272  if (m_useDB) {
273  m_cutSeed = m_ClusterCal.getMinSeedSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
274  m_cutAdjacent = m_ClusterCal.getMinAdjSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
275  m_cutCluster = m_ClusterCal.getMinClusterSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
276  }
277 
278  //create a dummy cluster just to start
279  RawCluster rawCluster(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip(), m_cutSeed, m_cutAdjacent,
281 
282  //loop over the SVDShaperDigits
283  for (const SVDShaperDigit& currentDigit : m_storeDigits) {
284 
285  //retrieve the VxdID, sensor and cellID of the current ShaperDigit
286  VxdID thisSensorID = currentDigit.getSensorID();
287  bool thisSide = currentDigit.isUStrip();
288  int thisCellID = currentDigit.getCellID();
289 
290  if (m_useDB) {
291  m_cutSeed = m_ClusterCal.getMinSeedSNR(thisSensorID, thisSide);
292  m_cutAdjacent = m_ClusterCal.getMinAdjSNR(thisSensorID, thisSide);
293  m_cutCluster = m_ClusterCal.getMinClusterSNR(thisSensorID, thisSide);
294  }
295 
296  //Ignore digits with insufficient signal
297  float thisNoise = m_NoiseCal.getNoise(thisSensorID, thisSide, thisCellID);
298  int thisCharge = currentDigit.getMaxADCCounts();
299  B2DEBUG(20, "Noise = " << thisNoise << " ADC, MaxSample = " << thisCharge << " ADC");
300 
301  if ((float)thisCharge / thisNoise < m_cutAdjacent)
302  continue;
303 
304  //this strip has a sufficient S/N
305  StripInRawCluster aStrip;
306  aStrip.shaperDigitIndex = currentDigit.getArrayIndex();
307  aStrip.maxSample = thisCharge;
308  aStrip.cellID = thisCellID;
309  aStrip.noise = thisNoise;
310  aStrip.samples = currentDigit.getSamples();
311 
312  //try to add the strip to the existing cluster
313  if (! rawCluster.add(thisSensorID, thisSide, aStrip)) {
314 
315  //if the strip is not added, write the cluster, if present and good:
316  if ((rawCluster.getSize() > 0) && (rawCluster.isGoodRawCluster()))
317  finalizeCluster(rawCluster);
318 
319  //prepare for the next cluster:
320  rawCluster = RawCluster(thisSensorID, thisSide, m_cutSeed, m_cutAdjacent, m_storeShaperDigitsName);
321 
322  //start another cluster:
323  if (! rawCluster.add(thisSensorID, thisSide, aStrip))
324  B2WARNING("this state is forbidden!!");
325 
326  }
327  } //exit loop on ShaperDigits
328 
329  //write the last cluster, if good
330  if ((rawCluster.getSize() > 0) && (rawCluster.isGoodRawCluster()))
331  finalizeCluster(rawCluster);
332 
333  B2DEBUG(20, "Number of clusters: " << m_storeClusters.getEntries());
334 }
335 
336 
338 {
339 
340  VxdID sensorID = rawCluster.getSensorID();
341  bool isU = rawCluster.isUSide();
342  int size = rawCluster.getSize();
343 
344  //first take Event Informations:
346  if (!temp_eventinfo.isValid())
347  m_svdEventInfoName = "SVDEventInfoSim";
349  if (!eventinfo) B2ERROR("No SVDEventInfo!");
350  eventinfo->setAPVClock(m_hwClock);
351 
352 
353  m_numberOfAcquiredSamples = eventinfo->getNSamples();
354 
355  //--------------
356  // CLUSTER RECO
357  //--------------
358  double time = std::numeric_limits<double>::quiet_NaN();
359  double timeError = std::numeric_limits<double>::quiet_NaN();
360  int firstFrame = std::numeric_limits<int>::quiet_NaN();
361 
362  double charge = std::numeric_limits<double>::quiet_NaN();
363  double seedCharge = std::numeric_limits<float>::quiet_NaN();
364  double SNR = std::numeric_limits<double>::quiet_NaN();
365 
366  double position = std::numeric_limits<float>::quiet_NaN();
367  double positionError = std::numeric_limits<float>::quiet_NaN();
368 
369 
370  if (m_numberOfAcquiredSamples == 6) {
371 
372  //time
373  m_time6SampleClass->computeClusterTime(rawCluster, time, timeError, firstFrame);
374  //charge
375  m_charge6SampleClass->computeClusterCharge(rawCluster, charge, SNR, seedCharge);
376 
377  //position
378  m_position6SampleClass->computeClusterPosition(rawCluster, position, positionError);
379  } else if (m_numberOfAcquiredSamples == 3) {
380  //time
381  m_time3SampleClass->computeClusterTime(rawCluster, time, timeError, firstFrame);
382 
383  //charge
384  m_charge3SampleClass->computeClusterCharge(rawCluster, charge, SNR, seedCharge);
385 
386  //position
387  m_position3SampleClass->computeClusterPosition(rawCluster, position, positionError);
388 
389  } else //we should never get here!
390  B2FATAL("SVD Reconstruction not available for this cluster (unrecognized or not supported number of acquired APV samples!!");
391 
392  // now go into FTSW time reference frame
393  time = eventinfo->getTimeInFTSWReference(time, firstFrame);
394 
395  //apply the Lorentz Shift Correction
396  position = applyLorentzShiftCorrection(position, sensorID, isU);
397 
398  //append the new cluster to the StoreArray...
399  if (SNR > m_cutCluster) {
400  m_storeClusters.appendNew(sensorID, isU, position, positionError, time, timeError, charge, seedCharge, size, SNR, -1,
401  firstFrame);
402 
403  B2DEBUG(20, "CLUSTER SIZE = " << size);
404  B2DEBUG(20, " time = " << time << ", timeError = " << timeError << ", firstframe = " << firstFrame);
405  B2DEBUG(20, " charge = " << charge << ", SNR = " << SNR << ", seedCharge = " << seedCharge);
406  B2DEBUG(20, " position = " << position << ", positionError = " << positionError);
407 
408  //..and write relations
409  writeClusterRelations(rawCluster);
410 
411  //alter cluster position and time on MC to match resolution measured on data
412  bool isMC = Environment::Instance().isMC();
413  if (isMC) {
416  } else {
417  if (m_svdClusterTimeShifter.isValid() &&
421  }
422  }
423  }
424 }
425 
427 {
429 
432 
435 
436 
437  //register relation between ShaperDigit and Cluster
438  int clsIndex = m_storeClusters.getEntries() - 1;
439 
440  map<int, float> mc_relations;
441  map<int, float> truehit_relations;
442 
443  vector<pair<int, float> > digit_weights;
444  digit_weights.reserve(m_storeClusters[clsIndex]->getSize());
445 
446  std::vector<StripInRawCluster> strips = rawCluster.getStripsInRawCluster();
447 
448  for (const auto& strip : strips) {
449 
450  //Fill map with MCParticle relations
451  if (relDigitMCParticle) {
453  for (relMC_type& mcRel : relDigitMCParticle.getElementsFrom(m_storeDigits[strip.shaperDigitIndex])) {
454  //negative weights are from ignored particles, we don't like them and
455  //thus ignore them :D
456  if (mcRel.weight < 0) continue;
457  mc_relations[mcRel.indexTo] += mcRel.weight;
458  };
459  };
460  //Fill map with SVDTrueHit relations
461  if (relDigitTrueHit) {
462  typedef const RelationIndex<SVDShaperDigit, SVDTrueHit>::Element relTrueHit_type;
463  for (relTrueHit_type& trueRel : relDigitTrueHit.getElementsFrom(m_storeDigits[strip.shaperDigitIndex])) {
464  //negative weights are from ignored particles, we don't like them and
465  //thus ignore them :D
466  if (trueRel.weight < 0) continue;
467  truehit_relations[trueRel.indexTo] += trueRel.weight;
468  };
469  };
470 
471  digit_weights.push_back(make_pair(strip.shaperDigitIndex, strip.maxSample));
472  }
473 
474  //Create Relations to this Digit
475  if (!mc_relations.empty()) {
476  relClusterMCParticle.add(clsIndex, mc_relations.begin(), mc_relations.end());
477  }
478  if (!truehit_relations.empty()) {
479  relClusterTrueHit.add(clsIndex, truehit_relations.begin(), truehit_relations.end());
480  }
481 
482  relClusterDigit.add(clsIndex, digit_weights.begin(), digit_weights.end());
483 
484 }
485 
486 double SVDClusterizerModule::applyLorentzShiftCorrection(double position, VxdID vxdID, bool isU)
487 {
488 
489  //Lorentz shift correction - PATCHED
490  //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.
491 
492  const SensorInfo& sensorInfo = dynamic_cast<const SensorInfo&>(VXD::GeoCache::get(vxdID));
493 
494  bool isMC = Environment::Instance().isMC();
495 
496  if ((vxdID.getLayerNumber() == 3) && ! isMC)
497  position += sensorInfo.getLorentzShift(isU, position);
498  else
499  position -= sensorInfo.getLorentzShift(isU, position);
500 
501  return position;
502 }
503 
505 {
506  // alter the position of the last cluster in the array
507  int clsIndex = m_storeClusters.getEntries() - 1;
508 
509  // get the necessary information on the cluster
510  float clsPosition = m_storeClusters[clsIndex]->getPosition();
511  VxdID sensorID = m_storeClusters[clsIndex]->getSensorID();
512  bool isU = m_storeClusters[clsIndex]->isUCluster();
513  int layerNum = sensorID.getLayerNumber();
514 
515  // get the first true hit in the array
516  SVDTrueHit* trueHit = m_storeClusters[clsIndex]->getRelatedTo<SVDTrueHit>(m_storeTrueHitsName);
517 
518  // get the track's incident angle
519  double trkAngle = 0.;
520 
521  // check if cluster has associated true hit
522  if (trueHit) {
523  double trkLength = isU ? trueHit->getExitU() - trueHit->getEntryU() : trueHit->getExitV() - trueHit->getEntryV();
524  double trkHeight = std::abs(trueHit->getExitW() - trueHit->getEntryW());
525  trkAngle = atan2(trkLength, trkHeight);
526  }
527 
528  // get the appropriate sigma to alter the position
529  double sigma = m_mcPositionFudgeFactor.getFudgeFactor(sensorID, isU, trkAngle);
530 
531  // do the job
532  float fudgeFactor = (float) gRandom->Gaus(0., sigma);
533  m_storeClusters[clsIndex]->setPosition(clsPosition + fudgeFactor);
534 
535  B2DEBUG(20, "Layer number: " << layerNum << ", is U side: " << isU << ", track angle: " << trkAngle << ", sigma: " << sigma <<
536  ", cluster position: " << clsPosition << ", fudge factor: " << fudgeFactor);
537 }
538 
540 {
541  // alter the time of the last cluster in the array
542  int clsIndex = m_storeClusters.getEntries() - 1;
543 
544  // get the necessary information on the cluster
545  float clsTime = m_storeClusters[clsIndex]->getClsTime();
546  VxdID sensorID = m_storeClusters[clsIndex]->getSensorID();
547  bool isU = m_storeClusters[clsIndex]->isUCluster();
548 
549  // get the appropriate sigma to alter the time
550  double sigma = m_mcTimeFudgeFactor.getFudgeFactor(sensorID, isU);
551 
552  // do the job
553  float fudgeFactor = (float) gRandom->Gaus(0., sigma);
554  m_storeClusters[clsIndex]->setClsTime(clsTime + fudgeFactor);
555 
556  B2DEBUG(20, "Layer number: " << sensorID.getLayerNumber() << ", is U side: " << isU << ", sigma: " << sigma <<
557  ", cluster time: " << clsTime << ", fudge factor: " << fudgeFactor);
558 }
559 
561 {
562  // alter the time of the last cluster in the array
563  int clsIndex = m_storeClusters.getEntries() - 1;
564 
565  // get the necessary information on the cluster
566  float clsTime = m_storeClusters[clsIndex]->getClsTime();
567 
568  TString algo = m_timeRecoWith6SamplesAlgorithm;
570 
571  clsTime -= m_svdClusterTimeShifter->getClusterTimeShift(algo,
572  m_storeClusters[clsIndex]->getSensorID().getLayerNumber(),
573  m_storeClusters[clsIndex]->getSensorID().getSensorNumber(),
574  m_storeClusters[clsIndex]->isUCluster(),
575  m_storeClusters[clsIndex]->getSize());
576 
577  m_storeClusters[clsIndex]->setClsTime(clsTime);
578 }
579 
581 {
582 
583  delete m_time6SampleClass;
584  delete m_time3SampleClass;
585  delete m_charge6SampleClass;
586  delete m_charge3SampleClass;
587  delete m_position6SampleClass;
588  delete m_position3SampleClass;
589 
590 }
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition: DataStore.h:72
bool isMC() const
Do we have generated, not real data?
Definition: Environment.cc:54
static Environment & Instance()
Static method to get a reference to the Environment instance.
Definition: Environment.cc:28
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
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.
double getMinClusterSNR(const Belle2::VxdID &sensorID, const bool &isU) const
Return the minimum SNR for the cluster.
double getMinSeedSNR(const Belle2::VxdID &sensorID, const bool &isU) const
Return the minimum SNR for the seed.
Definition: SVDClustering.h:55
double getMinAdjSNR(const Belle2::VxdID &sensorID, const bool &isU) const
Return the minimum SNR for the adjacent.
Definition: SVDClustering.h:77
double getFudgeFactor(const Belle2::VxdID &sensorID, const bool &isU, const double &trkAngle) const
Return the MC fudge factor.
double getFudgeFactor(const Belle2::VxdID &sensorID, const bool &isU) const
Return the MC fudge factor.
float getNoise(const VxdID &sensorID, const bool &isU, const unsigned short &strip) const
This is the method for getting the noise.
The SVD ShaperDigit class.
Class SVDTrueHit - Records of tracks that either enter or leave the sensitive volume.
Definition: SVDTrueHit.h:33
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
virtual void computeClusterCharge(Belle2::SVD::RawCluster &rawCluster, double &charge, double &SNR, double &seedCharge)=0
computes the cluster charge, SNR and seedCharge
void set_stripChargeAlgo(const std::string &user_stripChargeAlgo)
set which algorithm to use for strip charge in cluster position reconstruction
virtual void computeClusterPosition(Belle2::SVD::RawCluster &rawCluster, double &position, double &positionError)=0
computes the cluster position and position error
void set_stripTimeAlgo(const std::string &user_stripTimeAlgo)
set which algorithm to use for strip time in cluster position reconstruction, 'dontdo' will skip it
virtual void computeClusterTime(Belle2::SVD::RawCluster &rawCluster, double &time, double &timeError, int &firstFrame)=0
computes the cluster time, timeError and FirstFrame
std::string m_stripChargeRecoWith3SamplesAlgorithm
string storing the strip charge reconstruction algorithm for cluster reconstruction in 3-sample DAQ m...
double applyLorentzShiftCorrection(double position, VxdID vxdID, bool isU)
returns the position of the cluster after lorentz shift correction
SVDClusterCharge * m_charge6SampleClass
cluster charge class for the 6-sample acquisition mode
SVDClusterCharge * m_charge3SampleClass
cluster charge class for the 3-sample acquisition mode
SVDClusterPosition * m_position3SampleClass
cluster position class for the 3-sample acquisition mode
StoreArray< SVDTrueHit > m_storeTrueHits
Collection of SVDTrueHits.
StoreArray< SVDShaperDigit > m_storeDigits
Collection of SVDShaperDigits.
std::string m_relShaperDigitMCParticleName
Name of the relation between SVDShaperDigits and MCParticles.
DBObjPtr< SVDClusterTimeShifter > m_svdClusterTimeShifter
SVDCluster time shift.
void initialize() override
Initialize the module.
StoreArray< MCParticle > m_storeMCParticles
Collection of MCParticles.
SVDMCClusterPositionFudgeFactor m_mcPositionFudgeFactor
SVDMCClusterPositionFudgeFactor db object.
std::string m_storeShaperDigitsName
Name of the collection to use for the SVDShaperDigits.
void event() override
does the actual clustering
SVDNoiseCalibrations m_NoiseCal
SVDNoise calibrations db object.
void endRun() override
delete pointers
double m_cutCluster
Cluster cut in units of m_elNoise, not included (yet?)
std::string m_storeTrueHitsName
Name of the collection to use for the SVDTrueHits.
SVDClustering m_ClusterCal
SVDCluster calibrations db object.
SVDClusterTime * m_time6SampleClass
cluster time class for the 6-sample acquisition mode
std::string m_storeMCParticlesName
Name of the collection to use for the MCParticles.
bool m_shiftSVDClusterTime
if true applies SVDCluster time shift based on cluster-size
void alterClusterPosition()
alter the cluster position (applied on MC to match resolution measured on data)
void writeClusterRelations(const Belle2::SVD::RawCluster &rawCluster)
writes the relations of the SVDClusters with the other StoreArrays
std::string m_chargeRecoWith6SamplesAlgorithm
string storing the cluster charge reconstruction algorithm in 6-sample DAQ mode
std::string m_chargeRecoWith3SamplesAlgorithm
string storing the cluster charge reconstruction algorithm in 3-sample DAQ mode
int m_numberOfAcquiredSamples
number of acquired samples, can be 6 or 3 (1 is not supported!)
std::string m_relShaperDigitTrueHitName
Name of the relation between SVDShaperDigits and SVDTrueHits.
std::string m_positionRecoWith3SamplesAlgorithm
string storing the cluster position reconstruction algorithm in 3-sample DAQ mode
std::string m_stripTimeRecoWith6SamplesAlgorithm
string storing the strip time reconstruction algorithm for cluster position reconstruction in 6-sampl...
void beginRun() override
configure clustering
SVDClusterPosition * m_position6SampleClass
cluster position class for the 6-sample acquisition mode
std::string m_stripChargeRecoWith6SamplesAlgorithm
string storing the strip charge reconstruction algorithm for cluster position reconstruction in 6-sam...
DBObjPtr< HardwareClockSettings > m_hwClock
systems clock
std::string m_svdEventInfoName
Name of the collection to use for the SVDEventInfo.
std::string m_storeClustersName
Name of the collection to use for the SVDClusters.
SVDMCClusterTimeFudgeFactor m_mcTimeFudgeFactor
SVDMCClusterTimeFudgeFactor db object.
double m_cutSeed
Seed cut in units of noise.
std::string m_relClusterShaperDigitName
Name of the relation between SVDClusters and SVDShaperDigits.
void shiftSVDClusterTime()
Apply cluster time shift depending on cluster size.
std::string m_relClusterMCParticleName
Name of the relation between SVDClusters and MCParticles.
void finalizeCluster(Belle2::SVD::RawCluster &rawCluster)
computes charge, position and time of the raw cluster and appends the new SVDCluster to the StoreArra...
std::string m_stripTimeRecoWith3SamplesAlgorithm
string storing the strip time reconstruction algorithm for cluster position reconstruction in 3-sampl...
std::string m_timeRecoWith6SamplesAlgorithm
string storing the cluster time reconstruction algorithm in 6-sample DAQ mode
DBObjPtr< SVDRecoConfiguration > m_recoConfig
SVD Reconstruction Configuration payload.
std::string m_positionRecoWith6SamplesAlgorithm
string storing the cluster position reconstruction algorithm in 6-sample DAQ mode
StoreArray< SVDCluster > m_storeClusters
Collection of SVDClusters.
std::string m_timeRecoWith3SamplesAlgorithm
string storing the cluster time reconstruction algorithm in 3-sample DAQ mode
bool m_useDB
if true takes the clusterizer cuts and reconstruction configuration from the DB objects
SVDClusterTime * m_time3SampleClass
cluster time class for the 3-sample acquisition mode
void alterClusterTime()
alter the cluster time (applied on MC to match resolution measured on data)
double m_cutAdjacent
Adjacent cut in units of noise.
std::string m_relClusterTrueHitName
Name of the relation between SVDClusters and SVDTrueHits.
bool m_returnRawClusterTime
if true cluster time is not calibrated, to be used for time calibration
static SVDClusterCharge * NewCharge(const std::string &description)
static function that returns the class to compute the cluster charge
static SVDClusterPosition * NewPosition(const std::string &description)
static function that returns the class to compute the cluster position
static SVDClusterTime * NewTime(const std::string &description, const bool &returnRawClusterTime)
static function that returns the class to compute the cluster time
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 ROOT::Math::XYZVector & getLorentzShift(double uCoord, double vCoord) const
Calculate Lorentz shift along a given coordinate in a magnetic field at a given position.
Definition: SensorInfo.cc:104
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
void clear() override
Delete all entries in this array.
Definition: StoreArray.h:207
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
bool isValid() const
Check whether the object was created.
Definition: StoreObjPtr.h:111
float getEntryU() const
Return local u coordinate of hit when entering silicon.
Definition: VXDTrueHit.h:80
float getExitW() const
Return local w coordinate of hit at the endpoint of the track.
Definition: VXDTrueHit.h:90
float getEntryW() const
Return local w coordinate of the start point of the track.
Definition: VXDTrueHit.h:84
float getExitU() const
Return local u coordinate of hit at the endpoint of the track.
Definition: VXDTrueHit.h:86
float getExitV() const
Return local v coordinate of hit at the endpoint of the track.
Definition: VXDTrueHit.h:88
float getEntryV() const
Return local v coordinate of the start point of the track.
Definition: VXDTrueHit.h:82
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
Definition: GeoCache.h:139
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
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
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