9 #include <svd/modules/svdReconstruction/SVDSimpleClusterizerModule.h>
11 #include <framework/datastore/DataStore.h>
12 #include <framework/datastore/RelationArray.h>
13 #include <framework/datastore/RelationIndex.h>
14 #include <framework/logging/Logger.h>
16 #include <svd/geometry/SensorInfo.h>
17 #include <svd/dataobjects/SVDEventInfo.h>
34 m_cutSeed(5.0), m_cutAdjacent(3.0), m_sizeHeadTail(3), m_cutCluster(0), m_useDB(true)
37 setDescription(
"Clusterize SVDRecoDigits fitted by the Center of Gravity estimator");
38 setPropertyFlags(c_ParallelProcessingCertified);
41 addParam(
"RecoDigits", m_storeRecoDigitsName,
42 "SVDRecoDigits collection name",
string(
""));
43 addParam(
"Clusters", m_storeClustersName,
44 "SVDCluster collection name",
string(
""));
45 addParam(
"SVDTrueHits", m_storeTrueHitsName,
46 "TrueHit collection name",
string(
""));
47 addParam(
"MCParticles", m_storeMCParticlesName,
48 "MCParticles collection name",
string(
""));
49 addParam(
"ShaperDigits", m_storeShaperDigitsName,
50 "SVDShaperDigits collection name",
54 addParam(
"AdjacentSN", m_cutAdjacent,
55 "SN for digits to be considered for clustering", m_cutAdjacent);
56 addParam(
"SeedSN", m_cutSeed,
57 "SN for digits to be considered as seed", m_cutSeed);
58 addParam(
"HeadTailSize", m_sizeHeadTail,
59 "Cluster size at which to switch to Analog head tail algorithm", m_sizeHeadTail);
60 addParam(
"ClusterSN", m_cutCluster,
61 "minimum value of the SNR of the cluster", m_cutCluster);
62 addParam(
"timeAlgorithm", m_timeAlgorithm,
63 " int to choose time algorithm: 0 = 6-sample CoG (default for 6-sample acquisition mode), 1 = 3-sample CoG (default for 3-sample acquisition mode), 2 = 3-sample ELS",
65 addParam(
"Calibrate3SampleWithEventT0", m_calibrate3SampleWithEventT0,
66 " if true returns the calibrated time instead of the raw time for 3-sample time algorithms",
67 m_calibrate3SampleWithEventT0);
68 addParam(
"useDB", m_useDB,
69 "if false use clustering module parameters", m_useDB);
70 addParam(
"SVDEventInfoName", m_svdEventInfoSet,
71 "Set the SVDEventInfo to use",
string(
"SVDEventInfoSim"));
75 void SVDSimpleClusterizerModule::initialize()
78 m_storeClusters.registerInDataStore(m_storeClustersName, DataStore::c_ErrorIfAlreadyRegistered);
79 m_storeDigits.isRequired(m_storeRecoDigitsName);
80 m_storeTrueHits.isOptional(m_storeTrueHitsName);
81 m_storeMCParticles.isOptional(m_storeMCParticlesName);
83 RelationArray relClusterDigits(m_storeClusters, m_storeDigits);
84 RelationArray relClusterTrueHits(m_storeClusters, m_storeTrueHits);
85 RelationArray relClusterMCParticles(m_storeClusters, m_storeMCParticles);
86 RelationArray relDigitTrueHits(m_storeDigits, m_storeTrueHits);
87 RelationArray relDigitMCParticles(m_storeDigits, m_storeMCParticles);
97 m_storeClustersName = m_storeClusters.getName();
98 m_storeRecoDigitsName = m_storeDigits.getName();
99 m_storeTrueHitsName = m_storeTrueHits.getName();
100 m_storeMCParticlesName = m_storeMCParticles.getName();
102 m_relClusterRecoDigitName = relClusterDigits.
getName();
103 m_relClusterTrueHitName = relClusterTrueHits.
getName();
104 m_relClusterMCParticleName = relClusterMCParticles.
getName();
105 m_relRecoDigitTrueHitName = relDigitTrueHits.
getName();
106 m_relRecoDigitMCParticleName = relDigitMCParticles.
getName();
109 B2DEBUG(1,
"SVDSimpleClusterizer Parameters (in default system unit, *=cannot be set directly):");
111 B2DEBUG(1,
" 1. COLLECTIONS:");
112 B2DEBUG(1,
" --> MCParticles: " << DataStore::arrayName<MCParticle>(m_storeMCParticlesName));
113 B2DEBUG(1,
" --> SVDRecoDigits: " << DataStore::arrayName<SVDRecoDigit>(m_storeRecoDigitsName));
114 B2DEBUG(1,
" --> SVDClusters: " << DataStore::arrayName<SVDCluster>(m_storeClustersName));
115 B2DEBUG(1,
" --> SVDTrueHits: " << DataStore::arrayName<SVDTrueHit>(m_storeTrueHitsName));
116 B2DEBUG(1,
" --> DigitMCRel: " << m_relRecoDigitMCParticleName);
117 B2DEBUG(1,
" --> ClusterMCRel: " << m_relClusterMCParticleName);
118 B2DEBUG(1,
" --> ClusterDigitRel: " << m_relClusterRecoDigitName);
119 B2DEBUG(1,
" --> DigitTrueRel: " << m_relRecoDigitTrueHitName);
120 B2DEBUG(1,
" --> ClusterTrueRel: " << m_relClusterTrueHitName);
121 B2DEBUG(1,
" 2. CLUSTERING:");
122 B2DEBUG(1,
" --> Neighbour cut: " << m_cutAdjacent);
123 B2DEBUG(1,
" --> Seed cut: " << m_cutSeed);
124 B2DEBUG(1,
" --> Size HeadTail: " << m_sizeHeadTail);
125 B2DEBUG(1,
" --> SVDEventInfoName: " << m_svdEventInfoSet);
130 void SVDSimpleClusterizerModule::event()
132 int nDigits = m_storeDigits.getEntries();
136 m_storeClusters.clear();
138 RelationArray relClusterMCParticle(m_storeClusters, m_storeMCParticles,
139 m_relClusterMCParticleName);
140 if (relClusterMCParticle) relClusterMCParticle.
clear();
142 RelationArray relClusterDigit(m_storeClusters, m_storeDigits,
143 m_relClusterRecoDigitName);
144 if (relClusterDigit) relClusterDigit.
clear();
146 RelationArray relClusterTrueHit(m_storeClusters, m_storeTrueHits,
147 m_relClusterTrueHitName);
148 if (relClusterTrueHit) relClusterTrueHit.
clear();
152 m_cutSeed = m_ClusterCal.getMinSeedSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
153 m_cutAdjacent = m_ClusterCal.getMinAdjSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
154 m_cutCluster = m_ClusterCal.getMinClusterSNR(m_storeDigits[0]->getSensorID(), m_storeDigits[0]->isUStrip());
158 m_sizeHeadTail, m_cutSeed, m_cutAdjacent, m_cutCluster, m_timeAlgorithm, m_storeShaperDigitsName, m_storeRecoDigitsName);
162 while (i < nDigits) {
165 VxdID thisSensorID = m_storeDigits[i]->getSensorID();
166 bool thisSide = m_storeDigits[i]->isUStrip();
167 int thisCellID = m_storeDigits[i]->getCellID();
170 m_cutSeed = m_ClusterCal.getMinSeedSNR(thisSensorID, thisSide);
171 m_cutAdjacent = m_ClusterCal.getMinAdjSNR(thisSensorID, thisSide);
172 m_cutCluster = m_ClusterCal.getMinClusterSNR(thisSensorID, thisSide);
176 float thisNoise = m_NoiseCal.getNoiseInElectrons(thisSensorID, thisSide, thisCellID);
177 float thisCharge = m_storeDigits[i]->getCharge();
178 B2DEBUG(10,
"Noise = " << thisNoise <<
" e-, Charge = " << thisCharge);
180 if ((
float)thisCharge / thisNoise < m_cutAdjacent) {
188 aStrip.
charge = thisCharge;
189 aStrip.
cellID = thisCellID;
190 aStrip.
noise = thisNoise;
192 aStrip.
time = m_storeDigits[i]->getTime();
193 aStrip.
timeError = m_storeDigits[i]->getTimeError();
196 if (! clusterCandidate.
add(thisSensorID, thisSide, aStrip)) {
199 if (clusterCandidate.
size() > 0) {
202 writeClusters(clusterCandidate);
207 clusterCandidate =
SimpleClusterCandidate(thisSensorID, thisSide, m_sizeHeadTail, m_cutSeed, m_cutAdjacent, m_cutCluster,
209 m_storeShaperDigitsName, m_storeRecoDigitsName);
212 if (! clusterCandidate.
add(thisSensorID, thisSide, aStrip))
213 B2WARNING(
"this state is forbidden!!");
220 if (clusterCandidate.
size() > 0) {
223 writeClusters(clusterCandidate);
226 B2DEBUG(1,
"Number of clusters: " << m_storeClusters.getEntries());
233 RelationArray relClusterDigit(m_storeClusters, m_storeDigits, m_relClusterRecoDigitName);
235 RelationArray relClusterMCParticle(m_storeClusters, m_storeMCParticles, m_relClusterMCParticleName);
236 RelationArray relClusterTrueHit(m_storeClusters, m_storeTrueHits, m_relClusterTrueHitName);
242 VxdID sensorID = cluster.getSensorID();
243 bool isU = cluster.isUSide();
244 float seedCharge = cluster.getSeedCharge();
245 float charge = cluster.getCharge();
246 float size = cluster.size();
247 float SNR = cluster.getSNR();
248 float position = cluster.getPosition();
249 float positionError = m_OldDefaultSF.getCorrectedClusterPositionError(sensorID, isU, size, cluster.getPositionError());
251 float time = cluster.getTime();
252 float timeError = cluster.getTimeError();
253 int firstFrame = cluster.getFirstFrame();
256 std::string m_svdEventInfoName = m_svdEventInfoSet;
257 if (m_svdEventInfoSet ==
"SVDEventInfoSim") {
259 m_svdEventInfoName =
"SVDEventInfo";
261 m_svdEventInfoName = m_svdEventInfoSet;
265 if (!eventinfo) B2ERROR(
"No SVDEventInfo!");
272 float caltime = time;
273 if (m_timeAlgorithm == 1 and m_calibrate3SampleWithEventT0)
274 caltime = m_3CoGTimeCal.getCorrectedTime(sensorID, isU, -1, time, -1);
275 else if (m_timeAlgorithm == 2 and m_calibrate3SampleWithEventT0)
276 caltime = m_3ELSTimeCal.getCorrectedTime(sensorID, isU, -1, time, -1);
282 time = eventinfo->getTimeInFTSWReference(caltime, firstFrame);
285 m_storeClusters.appendNew(sensorID, isU, position, positionError, time, timeError, charge, seedCharge, size, SNR, -1, firstFrame);
288 int clsIndex = m_storeClusters.getEntries() - 1;
290 map<int, float> mc_relations;
291 map<int, float> truehit_relations;
293 vector<pair<int, float> > digit_weights;
294 digit_weights.reserve(size);
296 std::vector<stripInCluster> strips = cluster.getStripsInCluster();
298 for (
auto strip : strips) {
301 if (relDigitMCParticle) {
303 for (relMC_type& mcRel : relDigitMCParticle.
getElementsFrom(m_storeDigits[strip.recoDigitIndex])) {
306 if (mcRel.weight < 0)
continue;
307 mc_relations[mcRel.indexTo] += mcRel.
weight;
311 if (relDigitTrueHit) {
313 for (relTrueHit_type& trueRel : relDigitTrueHit.
getElementsFrom(m_storeDigits[strip.recoDigitIndex])) {
316 if (trueRel.weight < 0)
continue;
317 truehit_relations[trueRel.indexTo] += trueRel.
weight;
321 digit_weights.push_back(make_pair(strip.recoDigitIndex, strip.charge));
326 if (!mc_relations.empty()) {
327 relClusterMCParticle.
add(clsIndex, mc_relations.begin(), mc_relations.end());
329 if (!truehit_relations.empty()) {
330 relClusterTrueHit.
add(clsIndex, truehit_relations.begin(), truehit_relations.end());
333 relClusterDigit.
add(clsIndex, digit_weights.begin(), digit_weights.end());
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.
SVDSimpleClusterizerModule: The SVD SimpleClusterizer.
Class representing a cluster candidate during simple clustering of the SVD.
bool add(VxdID vxdID, bool isUside, struct stripInCluster &aStrip)
Add a Strip to the current cluster.
void finalizeCluster()
compute the position, time and their error of the cluster
bool isGoodCluster()
return true if the cluster candidate can be promoted to cluster
int size() const
return the cluster size (number of strips of the cluster
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
const std::string & getName() const
Return name under which the object is saved in the DataStore.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Type-safe access to single objects in the data store.
bool isValid() const
Check whether the object was created.
Class to uniquely identify a any structure of the PXD and SVD.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Namespace to encapsulate code needed for simulation and reconstrucion of the SVD.
Abstract base class for different kinds of events.
Element type for the index.
RelationElement::weight_type weight
weight of the relation.
structure containing the relevant informations of eachstrip of the cluster
float timeError
6-sample CoG strip time error
int recoDigitIndex
index of the reco digit
float time
6-sample CoG strip time