Belle II Software development
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
30using namespace std;
31using namespace Belle2;
32using namespace Belle2::SVD;
33
34
35//-----------------------------------------------------------------
36// Register the Module
37//-----------------------------------------------------------------
38REG_MODULE(SVDClusterizer);
39
40//-----------------------------------------------------------------
41// Implementation
42//-----------------------------------------------------------------
43
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 // False by default, reset in endRun()
117
118 if (m_useDB) {
119 if (!m_recoConfig.isValid())
120 B2FATAL("no valid configuration found for SVD reconstruction");
121 else
122 B2DEBUG(20, "SVDRecoConfiguration: from now on we are using " << m_recoConfig->get_uniqueID());
123
124 m_timeRecoWith6SamplesAlgorithm = m_recoConfig->getTimeRecoWith6Samples();
125 //m_timeRecoWith6SamplesAlgorithm = "ELS3";
126 //m_timeRecoWith3SamplesAlgorithm = "ELS3";
127 m_timeRecoWith3SamplesAlgorithm = m_recoConfig->getTimeRecoWith3Samples();
128 m_chargeRecoWith6SamplesAlgorithm = m_recoConfig->getChargeRecoWith6Samples();
129 m_chargeRecoWith3SamplesAlgorithm = m_recoConfig->getChargeRecoWith3Samples();
130 m_positionRecoWith6SamplesAlgorithm = m_recoConfig->getPositionRecoWith6Samples();
131 m_positionRecoWith3SamplesAlgorithm = m_recoConfig->getPositionRecoWith3Samples();
132
133 //strip algorithms
134 m_stripTimeRecoWith6SamplesAlgorithm = m_recoConfig->getStripTimeRecoWith6Samples();
135 m_stripTimeRecoWith3SamplesAlgorithm = m_recoConfig->getStripTimeRecoWith3Samples();
136 m_stripChargeRecoWith6SamplesAlgorithm = m_recoConfig->getStripChargeRecoWith6Samples();
137 m_stripChargeRecoWith3SamplesAlgorithm = m_recoConfig->getStripChargeRecoWith3Samples();
138
139 }
140 //check that all algorithms are available, otherwise use the default one
141 SVDReconstructionBase recoBase;
142
144 B2WARNING("cluster time algorithm " << m_timeRecoWith6SamplesAlgorithm << " is NOT available, using CoG3");
146 };
147
149 B2WARNING("cluster time algorithm " << m_timeRecoWith3SamplesAlgorithm << " is NOT available, using CoG3");
151 };
153 B2WARNING("cluster charge algorithm " << m_chargeRecoWith6SamplesAlgorithm << " is NOT available, using MaxSample");
155 };
157 B2WARNING("cluster charge algorithm " << m_chargeRecoWith3SamplesAlgorithm << " is NOT available, using MaxSample");
159 };
161 B2WARNING("cluster position algorithm " << m_positionRecoWith6SamplesAlgorithm << " is NOT available, using OldDefault");
163 };
165 B2WARNING("cluster position algorithm " << m_positionRecoWith3SamplesAlgorithm << " is NOT available, using OldDefault");
167 };
168
169
180
181 string israwtime = "";
182 if (m_returnRawClusterTime) israwtime = " (raw)";
183 B2INFO("SVD 6-sample DAQ, cluster time algorithm: " << m_timeRecoWith6SamplesAlgorithm << israwtime <<
184 ", cluster charge algorithm: " <<
185 m_chargeRecoWith6SamplesAlgorithm << ", cluster position algorithm: " << m_positionRecoWith6SamplesAlgorithm);
186 B2INFO(" with strip charge reconstructed with " << m_stripChargeRecoWith6SamplesAlgorithm << " and strip time reconstructed with "
187 <<
189
190 B2INFO("SVD 3-sample DAQ, cluster time algorithm: " << m_timeRecoWith3SamplesAlgorithm << israwtime <<
191 ", cluster charge algorithm: " <<
192 m_chargeRecoWith3SamplesAlgorithm << ", cluster position algorithm: " << m_positionRecoWith3SamplesAlgorithm);
193 B2INFO(" with strip charge reconstructed with " << m_stripChargeRecoWith3SamplesAlgorithm << " and strip time reconstructed with "
194 <<
196}
197
199{
200 //Register collections
205
207 RelationArray relClusterTrueHits(m_storeClusters, m_storeTrueHits);
208 RelationArray relClusterMCParticles(m_storeClusters, m_storeMCParticles);
210 RelationArray relDigitMCParticles(m_storeDigits, m_storeMCParticles);
211
212 relClusterDigits.registerInDataStore();
213
214 //Relations to simulation objects only if the ancestor relations exist
215 if (relDigitTrueHits.isOptional())
216 relClusterTrueHits.registerInDataStore();
217
218 if (relDigitMCParticles.isOptional())
219 relClusterMCParticles.registerInDataStore();
220
221 //Store names to speed up creation later
226
227 m_relClusterShaperDigitName = relClusterDigits.getName();
228 m_relClusterTrueHitName = relClusterTrueHits.getName();
229 m_relClusterMCParticleName = relClusterMCParticles.getName();
230 m_relShaperDigitTrueHitName = relDigitTrueHits.getName();
231 m_relShaperDigitMCParticleName = relDigitMCParticles.getName();
232
233 // Report:
234 B2DEBUG(20, "SVDClusterizer Parameters (in default system unit, *=cannot be set directly):");
235
236 B2DEBUG(20, " 1. COLLECTIONS:");
237 B2DEBUG(20, " --> MCParticles: " << m_storeMCParticlesName);
238 B2DEBUG(20, " --> SVDShaperDigits: " << m_storeShaperDigitsName);
239 B2DEBUG(20, " --> SVDClusters: " << m_storeClustersName);
240 B2DEBUG(20, " --> SVDTrueHits: " << m_storeTrueHitsName);
241 B2DEBUG(20, " 2. RELATIONS:");
242 B2DEBUG(20, " --> DigitMCRel: " << m_relShaperDigitMCParticleName);
243 B2DEBUG(20, " --> ClusterMCRel: " << m_relClusterMCParticleName);
244 B2DEBUG(20, " --> ClusterDigitRel: " << m_relClusterShaperDigitName);
245 B2DEBUG(20, " --> DigitTrueRel: " << m_relShaperDigitTrueHitName);
246 B2DEBUG(20, " --> ClusterTrueRel: " << m_relClusterTrueHitName);
247 B2DEBUG(20, " 3. CLUSTERING:");
248 B2DEBUG(20, " --> Neighbour cut: " << m_cutAdjacent);
249 B2DEBUG(20, " --> Seed cut: " << m_cutSeed);
250}
251
252
253
255{
256 int nDigits = m_storeDigits.getEntries();
257 if (nDigits == 0)
258 return;
259
260 m_storeClusters.clear();
261
262
265 if (relClusterMCParticle) relClusterMCParticle.clear();
266
269 if (relClusterDigit) relClusterDigit.clear();
270
273 if (relClusterTrueHit) relClusterTrueHit.clear();
274
275 if (m_useDB) {
276 m_cutSeed = m_ClusterCal.getMinSeedSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
277 m_cutAdjacent = m_ClusterCal.getMinAdjSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
278 m_cutCluster = m_ClusterCal.getMinClusterSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
279 }
280
281 //create a dummy cluster just to start
282 RawCluster rawCluster(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip(), m_cutSeed, m_cutAdjacent,
284
285 //loop over the SVDShaperDigits
286 for (const SVDShaperDigit& currentDigit : m_storeDigits) {
287
288 //retrieve the VxdID, sensor and cellID of the current ShaperDigit
289 VxdID thisSensorID = currentDigit.getSensorID();
290 bool thisSide = currentDigit.isUStrip();
291 int thisCellID = currentDigit.getCellID();
292
293 if (m_useDB) {
294 m_cutSeed = m_ClusterCal.getMinSeedSNR(thisSensorID, thisSide);
295 m_cutAdjacent = m_ClusterCal.getMinAdjSNR(thisSensorID, thisSide);
296 m_cutCluster = m_ClusterCal.getMinClusterSNR(thisSensorID, thisSide);
297 }
298
299 //Ignore digits with insufficient signal
300 float thisNoise = m_NoiseCal.getNoise(thisSensorID, thisSide, thisCellID);
301 int thisCharge = currentDigit.getMaxADCCounts();
302 B2DEBUG(20, "Noise = " << thisNoise << " ADC, MaxSample = " << thisCharge << " ADC");
303
304 if ((float)thisCharge / thisNoise < m_cutAdjacent)
305 continue;
306
307 //this strip has a sufficient S/N
308 StripInRawCluster aStrip;
309 aStrip.shaperDigitIndex = currentDigit.getArrayIndex();
310 aStrip.maxSample = thisCharge;
311 aStrip.cellID = thisCellID;
312 aStrip.noise = thisNoise;
313 aStrip.samples = currentDigit.getSamples();
314
315 //try to add the strip to the existing cluster
316 if (! rawCluster.add(thisSensorID, thisSide, aStrip)) {
317
318 //if the strip is not added, write the cluster, if present and good:
319 if ((rawCluster.getSize() > 0) && (rawCluster.isGoodRawCluster()))
320 finalizeCluster(rawCluster);
321
322 //prepare for the next cluster:
323 rawCluster = RawCluster(thisSensorID, thisSide, m_cutSeed, m_cutAdjacent, m_storeShaperDigitsName);
324
325 //start another cluster:
326 if (! rawCluster.add(thisSensorID, thisSide, aStrip))
327 B2WARNING("this state is forbidden!!");
328
329 }
330 } //exit loop on ShaperDigits
331
332 //write the last cluster, if good
333 if ((rawCluster.getSize() > 0) && (rawCluster.isGoodRawCluster()))
334 finalizeCluster(rawCluster);
335
336 B2DEBUG(20, "Number of clusters: " << m_storeClusters.getEntries());
337}
338
339
341{
342
343 VxdID sensorID = rawCluster.getSensorID();
344 bool isU = rawCluster.isUSide();
345 int size = rawCluster.getSize();
346
347 //first take Event Information:
349 if (!temp_eventinfo.isValid())
350 m_svdEventInfoName = "SVDEventInfoSim";
352 if (!eventinfo) B2ERROR("No SVDEventInfo!");
353 eventinfo->setAPVClock(m_hwClock);
354
355
356 m_numberOfAcquiredSamples = eventinfo->getNSamples();
357
358 //--------------
359 // CLUSTER RECO
360 //--------------
361 double time = std::numeric_limits<double>::quiet_NaN();
362 double timeError = std::numeric_limits<double>::quiet_NaN();
363 int firstFrame = 0;
364
365 double charge = std::numeric_limits<double>::quiet_NaN();
366 double seedCharge = std::numeric_limits<float>::quiet_NaN();
367 double SNR = std::numeric_limits<double>::quiet_NaN();
368
369 double position = std::numeric_limits<float>::quiet_NaN();
370 double positionError = std::numeric_limits<float>::quiet_NaN();
371
372
373 if (m_numberOfAcquiredSamples == 6) {
374
375 //time
376 m_time6SampleClass->computeClusterTime(rawCluster, time, timeError, firstFrame);
377 //charge
378 m_charge6SampleClass->computeClusterCharge(rawCluster, charge, SNR, seedCharge);
379
380 //position
381 m_position6SampleClass->computeClusterPosition(rawCluster, position, positionError);
382 } else if (m_numberOfAcquiredSamples == 3) {
383 //time
384 m_time3SampleClass->computeClusterTime(rawCluster, time, timeError, firstFrame);
385
386 //charge
387 m_charge3SampleClass->computeClusterCharge(rawCluster, charge, SNR, seedCharge);
388
389 //position
390 m_position3SampleClass->computeClusterPosition(rawCluster, position, positionError);
391
392 } else //we should never get here!
393 B2FATAL("SVD Reconstruction not available for this cluster (unrecognized or not supported number of acquired APV samples!!");
394
395 // now go into FTSW time reference frame
396 time = eventinfo->getTimeInFTSWReference(time, firstFrame);
397
398 //apply the Lorentz Shift Correction
399 position = applyLorentzShiftCorrection(position, sensorID, isU);
400
401 //append the new cluster to the StoreArray...
402 if (SNR > m_cutCluster) {
403 m_storeClusters.appendNew(sensorID, isU, position, positionError, time, timeError, charge, seedCharge, size, SNR, -1,
404 firstFrame);
405
406 B2DEBUG(20, "CLUSTER SIZE = " << size);
407 B2DEBUG(20, " time = " << time << ", timeError = " << timeError << ", firstframe = " << firstFrame);
408 B2DEBUG(20, " charge = " << charge << ", SNR = " << SNR << ", seedCharge = " << seedCharge);
409 B2DEBUG(20, " position = " << position << ", positionError = " << positionError);
410
411 //..and write relations
412 writeClusterRelations(rawCluster);
413
414 //alter cluster position and time on MC to match resolution measured on data
415 if (m_isMC) {
416 // if no truehit associated to the cluster there is nothing to fudge
417 int clsIndex = m_storeClusters.getEntries() - 1;
418 SVDTrueHit* trueHit = m_storeClusters[clsIndex]->getRelatedTo<SVDTrueHit>(m_storeTrueHitsName);
419 if (trueHit) {
420 alterClusterPosition(trueHit);
422 }
423 }
424 //shift cluster time:
425 //1. by cluster size
426 //2. by absolute value
428 if (m_svdClusterTimeShifter.isValid() && m_svdAbsTimeShift.isValid()) {
430 }
431 }
432}
433
435{
437
440
443
444
445 //register relation between ShaperDigit and Cluster
446 int clsIndex = m_storeClusters.getEntries() - 1;
447
448 map<int, float> mc_relations;
449 map<int, float> truehit_relations;
450
451 vector<pair<int, float> > digit_weights;
452 digit_weights.reserve(m_storeClusters[clsIndex]->getSize());
453
454 std::vector<StripInRawCluster> strips = rawCluster.getStripsInRawCluster();
455
456 for (const auto& strip : strips) {
457
458 //Fill map with MCParticle relations
459 if (relDigitMCParticle) {
461 for (relMC_type& mcRel : relDigitMCParticle.getElementsFrom(m_storeDigits[strip.shaperDigitIndex])) {
462 //negative weights are from ignored particles, we don't like them and
463 //thus ignore them :D
464 if (mcRel.weight < 0) continue;
465 mc_relations[mcRel.indexTo] += mcRel.weight;
466 };
467 };
468 //Fill map with SVDTrueHit relations
469 if (relDigitTrueHit) {
470 typedef const RelationIndex<SVDShaperDigit, SVDTrueHit>::Element relTrueHit_type;
471 for (relTrueHit_type& trueRel : relDigitTrueHit.getElementsFrom(m_storeDigits[strip.shaperDigitIndex])) {
472 //negative weights are from ignored particles, we don't like them and
473 //thus ignore them :D
474 if (trueRel.weight < 0) continue;
475 truehit_relations[trueRel.indexTo] += trueRel.weight;
476 };
477 };
478
479 digit_weights.push_back(make_pair(strip.shaperDigitIndex, strip.maxSample));
480 }
481
482 //Create Relations to this Digit
483 if (!mc_relations.empty()) {
484 relClusterMCParticle.add(clsIndex, mc_relations.begin(), mc_relations.end());
485 }
486 if (!truehit_relations.empty()) {
487 relClusterTrueHit.add(clsIndex, truehit_relations.begin(), truehit_relations.end());
488 }
489
490 relClusterDigit.add(clsIndex, digit_weights.begin(), digit_weights.end());
491
492}
493
494double SVDClusterizerModule::applyLorentzShiftCorrection(double position, VxdID vxdID, bool isU)
495{
496
497 //Lorentz shift correction - PATCHED
498 //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.
499
500 const SensorInfo& sensorInfo = dynamic_cast<const SensorInfo&>(VXD::GeoCache::getInstance().getSensorInfo(vxdID));
501
502 if ((vxdID.getLayerNumber() == 3) && ! m_isMC)
503 position += sensorInfo.getLorentzShift(isU, position);
504 else
505 position -= sensorInfo.getLorentzShift(isU, position);
506
507 return position;
508}
509
511{
512 // alter the position of the last cluster in the array
513 int clsIndex = m_storeClusters.getEntries() - 1;
514
515 // get the necessary information on the cluster
516 float clsPosition = m_storeClusters[clsIndex]->getPosition();
517 VxdID sensorID = m_storeClusters[clsIndex]->getSensorID();
518 bool isU = m_storeClusters[clsIndex]->isUCluster();
519 int layerNum = sensorID.getLayerNumber();
520
521 // get the track's incident angle
522 double trkAngle = 0.;
523
524 double trkLength = isU ? trueHit->getExitU() - trueHit->getEntryU() : trueHit->getExitV() - trueHit->getEntryV();
525 double trkHeight = std::abs(trueHit->getExitW() - trueHit->getEntryW());
526 trkAngle = atan2(trkLength, trkHeight);
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 //cluster-size dependent shift
572 clsTime -= m_svdClusterTimeShifter->getClusterTimeShift(algo,
573 m_storeClusters[clsIndex]->getSensorID().getLayerNumber(),
574 m_storeClusters[clsIndex]->getSensorID().getSensorNumber(),
575 m_storeClusters[clsIndex]->isUCluster(),
576 m_storeClusters[clsIndex]->getSize());
577 //absolute shift
578 clsTime -= m_svdAbsTimeShift->getAbsTimeShift(algo,
579 m_storeClusters[clsIndex]->getSensorID().getLayerNumber(),
580 m_storeClusters[clsIndex]->isUCluster());
581
582 m_storeClusters[clsIndex]->setClsTime(clsTime);
583
584}
585
587{
588
589 delete m_time6SampleClass;
590 delete m_time3SampleClass;
595
596 //reset m_isMC, re-check at the next beginRun
597 m_isMC = false;
598}
@ 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?
static Environment & Instance()
Static method to get a reference to the Environment instance.
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
Module()
Constructor.
Definition Module.cc:30
@ 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.
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.
range_from getElementsFrom(const FROM *from) const
Return a range of all elements pointing from the given object.
RelationIndexContainer< FROM, TO >::Element Element
Struct representing a single element in the index.
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
const std::vector< StripInRawCluster > getStripsInRawCluster() const
Definition RawCluster.h:110
bool add(VxdID vxdID, bool isUside, struct StripInRawCluster &aStrip)
Add a Strip to the current cluster.
Definition RawCluster.cc:54
VxdID getSensorID() const
Definition RawCluster.h:80
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
void alterClusterPosition(Belle2::SVDTrueHit *trueHit)
alter the cluster position (applied on MC to match resolution measured on data)
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
bool m_isMC
true if we are reconstructing MC
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 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...
SVDClusterizerModule()
Constructor defining the parameters.
std::string m_timeRecoWith6SamplesAlgorithm
string storing the cluster time reconstruction algorithm in 6-sample DAQ mode
DBObjPtr< SVDAbsoluteClusterTimeShift > m_svdAbsTimeShift
SVDCluster absolute time shift.
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 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.
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.
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
bool isValid() const
Check whether the object was created.
float getEntryU() const
Return local u coordinate of hit when entering silicon.
Definition VXDTrueHit.h:78
float getExitW() const
Return local w coordinate of hit at the endpoint of the track.
Definition VXDTrueHit.h:88
float getEntryW() const
Return local w coordinate of the start point of the track.
Definition VXDTrueHit.h:82
float getExitU() const
Return local u coordinate of hit at the endpoint of the track.
Definition VXDTrueHit.h:84
float getExitV() const
Return local v coordinate of hit at the endpoint of the track.
Definition VXDTrueHit.h:86
float getEntryV() const
Return local v coordinate of the start point of the track.
Definition VXDTrueHit.h:80
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a reference 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
Class to uniquely identify a any structure of the PXD and SVD.
Definition VxdID.h:32
baseType getLayerNumber() const
Get the layer id.
Definition VxdID.h:95
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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Namespace to encapsulate code needed for simulation and reconstrucion of the SVD.
Abstract base class for different kinds of events.
STL namespace.
structure containing the relevant information 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