Belle II Software prerelease-11-00-00a
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("absoluteShiftSVDClusterTime", m_absoluteShiftSVDClusterTime,
73 "if True, applies an absolute SVDCluster time shift, based on the layer/side", m_absoluteShiftSVDClusterTime);
74 addParam("SeedSN", m_cutSeed,
75 "minimum SNR for strips to be considered as cluster seed. Overwritten by the dbobject, unless you set useDB = False.", m_cutSeed);
76 addParam("ClusterSN", m_cutCluster,
77 "minimum value of the SNR of the cluster. Overwritten by the dbobject, unless you set useDB = False.", m_cutCluster);
78 addParam("timeAlgorithm6Samples", m_timeRecoWith6SamplesAlgorithm,
79 "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.",
81 addParam("timeAlgorithm3Samples", m_timeRecoWith3SamplesAlgorithm,
82 "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.",
84 addParam("chargeAlgorithm6Samples", m_chargeRecoWith6SamplesAlgorithm,
85 "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.",
87 addParam("chargeAlgorithm3Samples", m_chargeRecoWith3SamplesAlgorithm,
88 "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.",
90 addParam("positionAlgorithm6Samples", m_positionRecoWith6SamplesAlgorithm,
91 "cluster-position reconstruction algorithm for 6-sample DAQ mode: old (default), CoGOnly. Overwritten by the dbobject, unless you set useDB = False.",
93 addParam("positionAlgorithm3Samples", m_positionRecoWith3SamplesAlgorithm,
94 "cluster-position reconstruction algorithm for 3-sample DAQ mode: old (default), CoGOnly. Overwritten by the dbobject, unless you set useDB = False.",
96
97 addParam("stripTimeAlgorithm6Samples", m_stripTimeRecoWith6SamplesAlgorithm,
98 "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.",
100 addParam("stripTimeAlgorithm3Samples", m_stripTimeRecoWith3SamplesAlgorithm,
101 "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.",
103 addParam("stripChargeAlgorithm6Samples", m_stripChargeRecoWith6SamplesAlgorithm,
104 "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.",
106 addParam("stripChargeAlgorithm3Samples", m_stripChargeRecoWith3SamplesAlgorithm,
107 "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.",
109
110 addParam("useDB", m_useDB,
111 "if False, use clustering and reconstruction configuration module parameters", m_useDB);
112
113}
114
116{
117 // False by default, reset in endRun()
119
120 if (m_useDB) {
121 if (!m_recoConfig.isValid())
122 B2FATAL("no valid configuration found for SVD reconstruction");
123 else
124 B2DEBUG(20, "SVDRecoConfiguration: from now on we are using " << m_recoConfig->get_uniqueID());
125
126 m_timeRecoWith6SamplesAlgorithm = m_recoConfig->getTimeRecoWith6Samples();
127 //m_timeRecoWith6SamplesAlgorithm = "ELS3";
128 //m_timeRecoWith3SamplesAlgorithm = "ELS3";
129 m_timeRecoWith3SamplesAlgorithm = m_recoConfig->getTimeRecoWith3Samples();
130 m_chargeRecoWith6SamplesAlgorithm = m_recoConfig->getChargeRecoWith6Samples();
131 m_chargeRecoWith3SamplesAlgorithm = m_recoConfig->getChargeRecoWith3Samples();
132 m_positionRecoWith6SamplesAlgorithm = m_recoConfig->getPositionRecoWith6Samples();
133 m_positionRecoWith3SamplesAlgorithm = m_recoConfig->getPositionRecoWith3Samples();
134
135 //strip algorithms
136 m_stripTimeRecoWith6SamplesAlgorithm = m_recoConfig->getStripTimeRecoWith6Samples();
137 m_stripTimeRecoWith3SamplesAlgorithm = m_recoConfig->getStripTimeRecoWith3Samples();
138 m_stripChargeRecoWith6SamplesAlgorithm = m_recoConfig->getStripChargeRecoWith6Samples();
139 m_stripChargeRecoWith3SamplesAlgorithm = m_recoConfig->getStripChargeRecoWith3Samples();
140
141 }
142 //check that all algorithms are available, otherwise use the default one
143 SVDReconstructionBase recoBase;
144
146 B2WARNING("cluster time algorithm " << m_timeRecoWith6SamplesAlgorithm << " is NOT available, using CoG3");
148 };
149
151 B2WARNING("cluster time algorithm " << m_timeRecoWith3SamplesAlgorithm << " is NOT available, using CoG3");
153 };
155 B2WARNING("cluster charge algorithm " << m_chargeRecoWith6SamplesAlgorithm << " is NOT available, using MaxSample");
157 };
159 B2WARNING("cluster charge algorithm " << m_chargeRecoWith3SamplesAlgorithm << " is NOT available, using MaxSample");
161 };
163 B2WARNING("cluster position algorithm " << m_positionRecoWith6SamplesAlgorithm << " is NOT available, using OldDefault");
165 };
167 B2WARNING("cluster position algorithm " << m_positionRecoWith3SamplesAlgorithm << " is NOT available, using OldDefault");
169 };
170
171
182
183 string israwtime = "";
184 if (m_returnRawClusterTime) israwtime = " (raw)";
185 B2INFO("SVD 6-sample DAQ, cluster time algorithm: " << m_timeRecoWith6SamplesAlgorithm << israwtime <<
186 ", cluster charge algorithm: " <<
187 m_chargeRecoWith6SamplesAlgorithm << ", cluster position algorithm: " << m_positionRecoWith6SamplesAlgorithm);
188 B2INFO(" with strip charge reconstructed with " << m_stripChargeRecoWith6SamplesAlgorithm << " and strip time reconstructed with "
189 <<
191
192 B2INFO("SVD 3-sample DAQ, cluster time algorithm: " << m_timeRecoWith3SamplesAlgorithm << israwtime <<
193 ", cluster charge algorithm: " <<
194 m_chargeRecoWith3SamplesAlgorithm << ", cluster position algorithm: " << m_positionRecoWith3SamplesAlgorithm);
195 B2INFO(" with strip charge reconstructed with " << m_stripChargeRecoWith3SamplesAlgorithm << " and strip time reconstructed with "
196 <<
198}
199
201{
202 //Register collections
207
209 RelationArray relClusterTrueHits(m_storeClusters, m_storeTrueHits);
210 RelationArray relClusterMCParticles(m_storeClusters, m_storeMCParticles);
212 RelationArray relDigitMCParticles(m_storeDigits, m_storeMCParticles);
213
214 relClusterDigits.registerInDataStore();
215
216 //Relations to simulation objects only if the ancestor relations exist
217 if (relDigitTrueHits.isOptional())
218 relClusterTrueHits.registerInDataStore();
219
220 if (relDigitMCParticles.isOptional())
221 relClusterMCParticles.registerInDataStore();
222
223 //Store names to speed up creation later
228
229 m_relClusterShaperDigitName = relClusterDigits.getName();
230 m_relClusterTrueHitName = relClusterTrueHits.getName();
231 m_relClusterMCParticleName = relClusterMCParticles.getName();
232 m_relShaperDigitTrueHitName = relDigitTrueHits.getName();
233 m_relShaperDigitMCParticleName = relDigitMCParticles.getName();
234
235 // Report:
236 B2DEBUG(20, "SVDClusterizer Parameters (in default system unit, *=cannot be set directly):");
237
238 B2DEBUG(20, " 1. COLLECTIONS:");
239 B2DEBUG(20, " --> MCParticles: " << m_storeMCParticlesName);
240 B2DEBUG(20, " --> SVDShaperDigits: " << m_storeShaperDigitsName);
241 B2DEBUG(20, " --> SVDClusters: " << m_storeClustersName);
242 B2DEBUG(20, " --> SVDTrueHits: " << m_storeTrueHitsName);
243 B2DEBUG(20, " 2. RELATIONS:");
244 B2DEBUG(20, " --> DigitMCRel: " << m_relShaperDigitMCParticleName);
245 B2DEBUG(20, " --> ClusterMCRel: " << m_relClusterMCParticleName);
246 B2DEBUG(20, " --> ClusterDigitRel: " << m_relClusterShaperDigitName);
247 B2DEBUG(20, " --> DigitTrueRel: " << m_relShaperDigitTrueHitName);
248 B2DEBUG(20, " --> ClusterTrueRel: " << m_relClusterTrueHitName);
249 B2DEBUG(20, " 3. CLUSTERING:");
250 B2DEBUG(20, " --> Neighbour cut: " << m_cutAdjacent);
251 B2DEBUG(20, " --> Seed cut: " << m_cutSeed);
252}
253
254
255
257{
258 int nDigits = m_storeDigits.getEntries();
259 if (nDigits == 0)
260 return;
261
262 m_storeClusters.clear();
263
264
267 if (relClusterMCParticle) relClusterMCParticle.clear();
268
271 if (relClusterDigit) relClusterDigit.clear();
272
275 if (relClusterTrueHit) relClusterTrueHit.clear();
276
277 if (m_useDB) {
278 m_cutSeed = m_ClusterCal.getMinSeedSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
279 m_cutAdjacent = m_ClusterCal.getMinAdjSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
280 m_cutCluster = m_ClusterCal.getMinClusterSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
281 }
282
283 //create a dummy cluster just to start
284 RawCluster rawCluster(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip(), m_cutSeed, m_cutAdjacent,
286
287 //loop over the SVDShaperDigits
288 for (const SVDShaperDigit& currentDigit : m_storeDigits) {
289
290 //retrieve the VxdID, sensor and cellID of the current ShaperDigit
291 VxdID thisSensorID = currentDigit.getSensorID();
292 bool thisSide = currentDigit.isUStrip();
293 int thisCellID = currentDigit.getCellID();
294
295 if (m_useDB) {
296 m_cutSeed = m_ClusterCal.getMinSeedSNR(thisSensorID, thisSide);
297 m_cutAdjacent = m_ClusterCal.getMinAdjSNR(thisSensorID, thisSide);
298 m_cutCluster = m_ClusterCal.getMinClusterSNR(thisSensorID, thisSide);
299 }
300
301 //Ignore digits with insufficient signal
302 float thisNoise = m_NoiseCal.getNoise(thisSensorID, thisSide, thisCellID);
303 int thisCharge = currentDigit.getMaxADCCounts();
304 B2DEBUG(20, "Noise = " << thisNoise << " ADC, MaxSample = " << thisCharge << " ADC");
305
306 if ((float)thisCharge / thisNoise < m_cutAdjacent)
307 continue;
308
309 //this strip has a sufficient S/N
310 StripInRawCluster aStrip;
311 aStrip.shaperDigitIndex = currentDigit.getArrayIndex();
312 aStrip.maxSample = thisCharge;
313 aStrip.cellID = thisCellID;
314 aStrip.noise = thisNoise;
315 aStrip.samples = currentDigit.getSamples();
316
317 //try to add the strip to the existing cluster
318 if (! rawCluster.add(thisSensorID, thisSide, aStrip)) {
319
320 //if the strip is not added, write the cluster, if present and good:
321 if ((rawCluster.getSize() > 0) && (rawCluster.isGoodRawCluster()))
322 finalizeCluster(rawCluster);
323
324 //prepare for the next cluster:
325 rawCluster = RawCluster(thisSensorID, thisSide, m_cutSeed, m_cutAdjacent, m_storeShaperDigitsName);
326
327 //start another cluster:
328 if (! rawCluster.add(thisSensorID, thisSide, aStrip))
329 B2WARNING("this state is forbidden!!");
330
331 }
332 } //exit loop on ShaperDigits
333
334 //write the last cluster, if good
335 if ((rawCluster.getSize() > 0) && (rawCluster.isGoodRawCluster()))
336 finalizeCluster(rawCluster);
337
338 B2DEBUG(20, "Number of clusters: " << m_storeClusters.getEntries());
339}
340
341
343{
344
345 VxdID sensorID = rawCluster.getSensorID();
346 bool isU = rawCluster.isUSide();
347 int size = rawCluster.getSize();
348
349 //first take Event Information:
351 if (!temp_eventinfo.isValid())
352 m_svdEventInfoName = "SVDEventInfoSim";
354 if (!eventinfo) B2ERROR("No SVDEventInfo!");
355 eventinfo->setAPVClock(m_hwClock);
356
357
358 m_numberOfAcquiredSamples = eventinfo->getNSamples();
359
360 //--------------
361 // CLUSTER RECO
362 //--------------
363 double time = std::numeric_limits<double>::quiet_NaN();
364 double timeError = std::numeric_limits<double>::quiet_NaN();
365 int firstFrame = 0;
366
367 double charge = std::numeric_limits<double>::quiet_NaN();
368 double seedCharge = std::numeric_limits<float>::quiet_NaN();
369 double SNR = std::numeric_limits<double>::quiet_NaN();
370
371 double position = std::numeric_limits<float>::quiet_NaN();
372 double positionError = std::numeric_limits<float>::quiet_NaN();
373
374
375 if (m_numberOfAcquiredSamples == 6) {
376
377 //time
378 m_time6SampleClass->computeClusterTime(rawCluster, time, timeError, firstFrame);
379 //charge
380 m_charge6SampleClass->computeClusterCharge(rawCluster, charge, SNR, seedCharge);
381
382 //position
383 m_position6SampleClass->computeClusterPosition(rawCluster, position, positionError);
384 } else if (m_numberOfAcquiredSamples == 3) {
385 //time
386 m_time3SampleClass->computeClusterTime(rawCluster, time, timeError, firstFrame);
387
388 //charge
389 m_charge3SampleClass->computeClusterCharge(rawCluster, charge, SNR, seedCharge);
390
391 //position
392 m_position3SampleClass->computeClusterPosition(rawCluster, position, positionError);
393
394 } else //we should never get here!
395 B2FATAL("SVD Reconstruction not available for this cluster (unrecognized or not supported number of acquired APV samples!!");
396
397 // now go into FTSW time reference frame
398 time = eventinfo->getTimeInFTSWReference(time, firstFrame);
399
400 //apply the Lorentz Shift Correction
401 position = applyLorentzShiftCorrection(position, sensorID, isU);
402
403 //append the new cluster to the StoreArray...
404 if (SNR > m_cutCluster) {
405 m_storeClusters.appendNew(sensorID, isU, position, positionError, time, timeError, charge, seedCharge, size, SNR, -1,
406 firstFrame);
407
408 B2DEBUG(20, "CLUSTER SIZE = " << size);
409 B2DEBUG(20, " time = " << time << ", timeError = " << timeError << ", firstframe = " << firstFrame);
410 B2DEBUG(20, " charge = " << charge << ", SNR = " << SNR << ", seedCharge = " << seedCharge);
411 B2DEBUG(20, " position = " << position << ", positionError = " << positionError);
412
413 //..and write relations
414 writeClusterRelations(rawCluster);
415
416 //alter cluster position and time on MC to match resolution measured on data
417 if (m_isMC) {
418 // if no truehit associated to the cluster there is nothing to fudge
419 int clsIndex = m_storeClusters.getEntries() - 1;
420 SVDTrueHit* trueHit = m_storeClusters[clsIndex]->getRelatedTo<SVDTrueHit>(m_storeTrueHitsName);
421 if (trueHit) {
422 alterClusterPosition(trueHit);
424 }
425 }
426 //shift cluster time:
427 //1. by cluster size
428 //2. by absolute value
430 if (m_svdClusterTimeShifter.isValid() && m_svdAbsTimeShift.isValid()) {
432 }
433 }
434}
435
437{
439
442
445
446
447 //register relation between ShaperDigit and Cluster
448 int clsIndex = m_storeClusters.getEntries() - 1;
449
450 map<int, float> mc_relations;
451 map<int, float> truehit_relations;
452
453 vector<pair<int, float> > digit_weights;
454 digit_weights.reserve(m_storeClusters[clsIndex]->getSize());
455
456 std::vector<StripInRawCluster> strips = rawCluster.getStripsInRawCluster();
457
458 for (const auto& strip : strips) {
459
460 //Fill map with MCParticle relations
461 if (relDigitMCParticle) {
463 for (relMC_type& mcRel : relDigitMCParticle.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 (mcRel.weight < 0) continue;
467 mc_relations[mcRel.indexTo] += mcRel.weight;
468 };
469 };
470 //Fill map with SVDTrueHit relations
471 if (relDigitTrueHit) {
472 typedef const RelationIndex<SVDShaperDigit, SVDTrueHit>::Element relTrueHit_type;
473 for (relTrueHit_type& trueRel : relDigitTrueHit.getElementsFrom(m_storeDigits[strip.shaperDigitIndex])) {
474 //negative weights are from ignored particles, we don't like them and
475 //thus ignore them :D
476 if (trueRel.weight < 0) continue;
477 truehit_relations[trueRel.indexTo] += trueRel.weight;
478 };
479 };
480
481 digit_weights.push_back(make_pair(strip.shaperDigitIndex, strip.maxSample));
482 }
483
484 //Create Relations to this Digit
485 if (!mc_relations.empty()) {
486 relClusterMCParticle.add(clsIndex, mc_relations.begin(), mc_relations.end());
487 }
488 if (!truehit_relations.empty()) {
489 relClusterTrueHit.add(clsIndex, truehit_relations.begin(), truehit_relations.end());
490 }
491
492 relClusterDigit.add(clsIndex, digit_weights.begin(), digit_weights.end());
493
494}
495
496double SVDClusterizerModule::applyLorentzShiftCorrection(double position, VxdID vxdID, bool isU)
497{
498
499 //Lorentz shift correction - PATCHED
500 //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.
501
502 const SensorInfo& sensorInfo = dynamic_cast<const SensorInfo&>(VXD::GeoCache::getInstance().getSensorInfo(vxdID));
503
504 if ((vxdID.getLayerNumber() == 3) && ! m_isMC)
505 position += sensorInfo.getLorentzShift(isU, position);
506 else
507 position -= sensorInfo.getLorentzShift(isU, position);
508
509 return position;
510}
511
513{
514 // alter the position of the last cluster in the array
515 int clsIndex = m_storeClusters.getEntries() - 1;
516
517 // get the necessary information on the cluster
518 float clsPosition = m_storeClusters[clsIndex]->getPosition();
519 VxdID sensorID = m_storeClusters[clsIndex]->getSensorID();
520 bool isU = m_storeClusters[clsIndex]->isUCluster();
521 int layerNum = sensorID.getLayerNumber();
522
523 // get the track's incident angle
524 double trkAngle = 0.;
525
526 double trkLength = isU ? trueHit->getExitU() - trueHit->getEntryU() : trueHit->getExitV() - trueHit->getEntryV();
527 double trkHeight = std::abs(trueHit->getExitW() - trueHit->getEntryW());
528 trkAngle = atan2(trkLength, trkHeight);
529
530 // get the appropriate sigma to alter the position
531 double sigma = m_mcPositionFudgeFactor.getFudgeFactor(sensorID, isU, trkAngle);
532
533 // do the job
534 float fudgeFactor = (float) gRandom->Gaus(0., sigma);
535 m_storeClusters[clsIndex]->setPosition(clsPosition + fudgeFactor);
536
537 B2DEBUG(20, "Layer number: " << layerNum << ", is U side: " << isU << ", track angle: " << trkAngle << ", sigma: " << sigma <<
538 ", cluster position: " << clsPosition << ", fudge factor: " << fudgeFactor);
539}
540
542{
543 // alter the time of the last cluster in the array
544 int clsIndex = m_storeClusters.getEntries() - 1;
545
546 // get the necessary information on the cluster
547 float clsTime = m_storeClusters[clsIndex]->getClsTime();
548 VxdID sensorID = m_storeClusters[clsIndex]->getSensorID();
549 bool isU = m_storeClusters[clsIndex]->isUCluster();
550
551 // get the appropriate sigma to alter the time
552 double sigma = m_mcTimeFudgeFactor.getFudgeFactor(sensorID, isU);
553
554 // do the job
555 float fudgeFactor = (float) gRandom->Gaus(0., sigma);
556 m_storeClusters[clsIndex]->setClsTime(clsTime + fudgeFactor);
557
558 B2DEBUG(20, "Layer number: " << sensorID.getLayerNumber() << ", is U side: " << isU << ", sigma: " << sigma <<
559 ", cluster time: " << clsTime << ", fudge factor: " << fudgeFactor);
560}
561
563{
564 // alter the time of the last cluster in the array
565 int clsIndex = m_storeClusters.getEntries() - 1;
566
567 // get the necessary information on the cluster
568 float clsTime = m_storeClusters[clsIndex]->getClsTime();
569
570 TString algo = m_timeRecoWith6SamplesAlgorithm;
572
573 //cluster-size dependent shift
574 clsTime -= m_svdClusterTimeShifter->getClusterTimeShift(algo,
575 m_storeClusters[clsIndex]->getSensorID().getLayerNumber(),
576 m_storeClusters[clsIndex]->getSensorID().getSensorNumber(),
577 m_storeClusters[clsIndex]->isUCluster(),
578 m_storeClusters[clsIndex]->getSize());
579 //absolute shift
581 clsTime -= m_svdAbsTimeShift->getAbsTimeShift(algo,
582 m_storeClusters[clsIndex]->getSensorID().getLayerNumber(),
583 m_storeClusters[clsIndex]->isUCluster());
584
585 m_storeClusters[clsIndex]->setClsTime(clsTime);
586
587}
588
590{
591
592 delete m_time6SampleClass;
593 delete m_time3SampleClass;
598
599 //reset m_isMC, re-check at the next beginRun
600 m_isMC = false;
601}
@ 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.
bool m_absoluteShiftSVDClusterTime
if true applies an absolute SVDCluster time shift, based on the layer/side
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