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 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");
152 };
154 B2WARNING("cluster charge algorithm " << m_chargeRecoWith3SamplesAlgorithm << " is NOT available, using 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
204 RelationArray relClusterTrueHits(m_storeClusters, m_storeTrueHits);
205 RelationArray relClusterMCParticles(m_storeClusters, m_storeMCParticles);
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
262 if (relClusterMCParticle) relClusterMCParticle.clear();
263
266 if (relClusterDigit) relClusterDigit.clear();
267
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
486double 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::getInstance().getSensorInfo(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;
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:54
double getMinAdjSNR(const Belle2::VxdID &sensorID, const bool &isU) const
Return the minimum SNR for the adjacent.
Definition: SVDClustering.h:75
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
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
bool isUSide() const
Definition: RawCluster.h:85
VxdID getSensorID() const
Definition: RawCluster.h:80
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...
SVDClusterizerModule()
Constructor defining the parameters.
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
const std::string & getName() const
Return name under which the object is saved in the DataStore.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
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
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne to the SensorInfo of a given SensorID.
Definition: GeoCache.cc:67
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:214
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.
STL namespace.
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