Belle II Software development
GFTC2SPTCConverterModule.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 <tracking/modules/spacePointCreator/GFTC2SPTCConverterModule.h>
10#include <tracking/spacePointCreation/SpacePointTrackCand.h>
11
12#include <framework/dataobjects/EventMetaData.h>
13#include <framework/datastore/StoreObjPtr.h>
14#include <framework/gearbox/Const.h>
15
16#include <algorithm> // count, sort, etc...
17
18#include <boost/tuple/tuple_comparison.hpp>
19
20using namespace Belle2;
21
22REG_MODULE(GFTC2SPTCConverter);
23
25 Module()
26{
27 setDescription("Module for converting genfit::TrackCands (e.g. from TrackFinderMCTruth) to SpacePointTrackCands.");
29
30 addParam("PXDClusters", m_PXDClusterName, "PXDCluster collection name", std::string(""));
31 addParam("SVDClusters", m_SVDClusterName, "SVDCluster collection name", std::string(""));
32 addParam("genfitTCName", m_genfitTCName, "Name of container of genfit::TrackCands", std::string(""));
33 addParam("SpacePointTCName", m_SPTCName,
34 "Name of the container under which SpacePointTrackCands will be stored in the DataStore (NOTE: These SpaceTrackCands are not checked for curling behaviour, but are simply converted and stored!)",
35 std::string(""));
36
37 addParam("SingleClusterSVDSP", m_SingleClusterSVDSPName,
38 "Single Cluster SVD SpacePoints collection name. NOTE: This StoreArray will be searched for SpacePoints only if 'useSingleClusterSP' is set to true!",
39 std::string("SVDSpacePoints"));
40 addParam("NoSingleClusterSVDSP", m_NoSingleClusterSVDSPName,
41 "Non Single Cluster SVD SpacePoints collection name. This StoreArray will be searched for SpacePoints",
42 std::string("SVDSpacePoints"));
43 addParam("PXDClusterSP", m_PXDClusterSPName, "PXD Cluster SpacePoints collection name.", std::string("PXDSpacePoints"));
44
45 addParam("minNDF", m_PARAMminNDF,
46 "Minimum number of degrees of freedom a SpacePointTrackCand has to contain in order to get registered in the DataStore. If set to 0, any number is accepted",
47 0);
48
49 addParam("checkTrueHits", m_PARAMcheckTrueHits,
50 "Set to true if you want TrueHits of Clusters forming a SpacePoint (e.g. SVD) to be checked for equality", false);
51 addParam("useSingleClusterSP", m_PARAMuseSingleClusterSP,
52 "Set to true if you want to use singleCluster SVD SpacePoints if no doubleCluster SVD SpacePoint can be found. NOTE: this gets overridden if 'skipCluster' is set to true!",
53 true);
54 addParam("checkNoSingleSVDSP", m_PARAMcheckNoSingleSVDSP,
55 "Set to false if you want to disable the initial check for the StoreArray of Non Single Cluster SVD SpacePoints. NOTE: The module will still search for these SpacePoints first, so you have to make sure you are not registering SpacePoints under the StoreArray with the NoSingleClusterSVDSP name! (Disable the module that registers these SpacePoints)",
56 true);
57 addParam("skipCluster", m_PARAMskipCluster,
58 "Set to true if you only want to skip the Clusters for which no appropriate SpacePoints can be found, instead of aborting the conversion of the whole GFTC when such a case occurs. NOTE: setting this to true automatically sets 'useSingleClusterSP' to false!",
59 false);
60
61 initializeCounters(); // NOTE: they get initialized in initialize again!!
62}
63
64// ------------------------------ INITIALIZE ---------------------------------------
66{
67 B2INFO("GFTC2SPTCConverter -------------- initialize() ---------------------");
68 // initialize Counters
70
71 // check if all required StoreArrays are here
76 }
79 }
81
83
84 // registering StoreArray for SpacePointTrackCand
86
87 // m_SpacePointTrackCands Relation to genfit::TrackCand
89
90 // CAUTION: if the StoreArray of the TrueHits is named, this check fails!!!
92 m_PXDTrueHits.isRequired();
93 m_SVDTrueHits.isRequired();
94 }
95
96 if (m_PARAMminNDF < 0) {
97 B2WARNING("'minNDF' is set to a value below 0. Resetting to 0!");
98 m_PARAMminNDF = 0;
99 }
100
101}
102
103// ------------------------------------- EVENT -------------------------------------------------------
105{
106 StoreObjPtr<EventMetaData> eventMetaDataPtr("EventMetaData", DataStore::c_Event);
107 const int eventCounter = eventMetaDataPtr->getEvent();
108 B2DEBUG(21, "GFTC2SPTCConverter::event(). Processing event " << eventCounter << " --------");
109
110 int nTCs = m_GenfitTrackCands.getEntries();
111
112 B2DEBUG(21, "Found " << nTCs << " genfit::TrackCands in StoreArray " << m_GenfitTrackCands.getName());
113
114 for (int iTC = 0; iTC < nTCs; ++iTC) {
115 genfit::TrackCand* trackCand = m_GenfitTrackCands[iTC];
116 m_genfitTCCtr += 1;
117
118 B2DEBUG(21,
119 "================================================================================\nNow processing genfit::TrackCand "
120 << iTC << ".");
121 if (LogSystem::Instance().isLevelEnabled(LogConfig::c_Debug, 15, PACKAGENAME())) { trackCand->Print(); } // prints to stdout
122 try {
123 // get the converted SPTC
124 std::pair<const SpacePointTrackCand, conversionStatus> spacePointTC = createSpacePointTC(trackCand);
125 // check if the SPTC contains enough SpacePoints
126 if (spacePointTC.second == 0) {
127 if (LogSystem::Instance().isLevelEnabled(LogConfig::c_Debug, 50, PACKAGENAME())) spacePointTC.first.print(50);
128 SpacePointTrackCand* newSPTC = m_SpacePointTrackCands.appendNew(spacePointTC.first);
130 newSPTC->addRelationTo(trackCand);
131 B2DEBUG(21, "Added new SpacePointTrackCand to StoreArray " << m_SpacePointTrackCands.getName());
132 } else {
133 B2DEBUG(21, "The conversion failed due to: " << spacePointTC.second);
134 increaseFailCounter(spacePointTC.second);
135 }
136 } catch (std::runtime_error& anE) { // catch all Belle2 exceptions with this!
137 B2ERROR("Caught exception in creation of SpacePointTrackCand: " << anE.what());
138 } catch (...) { // catch the rest
139 B2ERROR("Caught undefined exception in creation of SpacePointTrackCand!"); // COULDDO: rethrow exception as something is fishy if this happens
140 }
141 }
142}
143
144// -------------------------------- TERMINATE --------------------------------------------------------
146{
147 std::stringstream generalOutput;
148 generalOutput << "GFTC2SPTCConverter::terminate(): got " << m_genfitTCCtr << " GFTCs and created " << m_SpacePointTCCtr <<
149 " SPTCs. ";
150 if (m_abortedLowNDFCtr) generalOutput << "For " << m_abortedLowNDFCtr << " SPTCs the NDF was below " << m_PARAMminNDF << "\n";
151 // NEW output
152 B2INFO(generalOutput.str());
153 if (LogSystem::Instance().isLevelEnabled(LogConfig::c_Debug, 1, PACKAGENAME())) {
154 std::stringstream verboseOutput;
155 verboseOutput << "counter variables: ";
156 verboseOutput << "abortedNoSP: " << m_abortedNoSPCtr << ", abortedUnsuitableGFTC: " << m_abortedUnsuitableTCCtr <<
157 ", abortedNoValidSP: " << m_abortedNoValidSPCtr;
158 if (m_PARAMcheckTrueHits) verboseOutput << ", abortedTrueHit: " << m_abortedTrueHitCtr;
159 if (m_PARAMskipCluster) {
160 verboseOutput << ", skippedCluster: " << m_skippedCluster << ", skippedPXDnoSP: " << m_skippedPXDnoSPCtr;
161 verboseOutput << ", skippedSVDnoSP: " << m_skippedSVDnoSPCtr << ", skippedPXDnoTH: " << m_skippedPXDnoTHCtr << ", skippedSVDnoTH: "
163 verboseOutput << ", skippedPXDunsuitable: " << m_skippedPXDunsuitableCtr << ", skippedSVDunsuitable: " << m_skippedSVDunsuitableCtr;
164 verboseOutput << ", skippedPXDnoValidSP " << m_skippedPXDnoValidSPCtr << ", skippedSVDnoValidSP " << m_skippedSVDnoValidSPCtr;
165 }
166 if (m_nonSingleSPCtr) verboseOutput << ", nonSingleSP " << m_nonSingleSPCtr;
167 verboseOutput << ", noTwoClusterSP: " << m_noTwoClusterSPCtr << ", singleClusterSVDSP: " << m_singleClusterSPCtr;
168 B2DEBUG(21, verboseOutput.str());
169 }
170 if (LogSystem::Instance().isLevelEnabled(LogConfig::c_Debug, 2, PACKAGENAME())) {
171 std::stringstream explanation;
172 explanation << "explanation of counter variables (key words only):\n";
173 explanation << "NoSP -> Found no related SpacePoint to a Cluster\n";
174 explanation << "Unsuitable -> Cluster combination of SpacePoint was not in consecutive order in GFTC\n";
175 explanation << "NoValidSP -> Cluster combination of SpacePoint was not contained in GFTC\n";
176 if (m_PARAMcheckTrueHits) explanation << "TrueHit/noTH -> found no related TrueHit to a SpacePoint\n";
177 if (m_nonSingleSPCtr) explanation << "nonSingleSP -> more than one singleCluster SpacePoint related to a Cluster\n";
178 explanation << "noTwoClusterSP -> found no two Cluster SpacePoint\n";
179 explanation << "singleClusterSVDSP -> number of tries to add a singleCluster SpacePoint for latter cases\n";
180 B2DEBUG(22, explanation.str());
181 }
182}
183
184// ================================================================= CREATE SPACEOINT TRACKCAND =========================================================================================
185std::pair<const Belle2::SpacePointTrackCand, GFTC2SPTCConverterModule::conversionStatus>
186GFTC2SPTCConverterModule::createSpacePointTC(const genfit::TrackCand* genfitTC)
187{
188 m_NDF = 0; // reset for every trackCand
189 std::vector<HitInfo<SpacePoint> > tcSpacePoints;
190 // cppcheck-suppress unreadVariable
191 conversionStatus convStatus = c_noFail; // part of return
192
193 int nHits = genfitTC->getNHits();
194 B2DEBUG(21, "genfit::TrackCand contains " << nHits << " hits");
195
196 // for easier handling fill a taggedPair (typedef) to distinguish whether a hit has already been used or if is still open for procession
197 std::vector<flaggedPair<int> > fHitIDs;
198 for (int i = 0; i < nHits; ++i) {
199 auto aHit = genfitTC->getHit(i);
200 flaggedPair<int> aPair(false, aHit->getDetId(), aHit->getHitId());
201 fHitIDs.push_back(aPair);
202 }
203
204 bool usedSingleCluster = false;
205 // now loop over all hits and add them appropriately
206 for (int iTCHit = 0; iTCHit < nHits; ++iTCHit) {
207 genfit::TrackCandHit* aTCHit = genfitTC->getHit(iTCHit);
208 double sortingParam = aTCHit->getSortingParameter();
209
210 B2DEBUG(20, "Processing TrackCandHit " << iTCHit << " of " << nHits);
211 if (fHitIDs[iTCHit].get<0>()) { // check if this hit has already been used, if not process
212 B2DEBUG(28, "This hit has already been added to the SpacePointTrackCand via a SpacePoint and will not be processed again");
213 } else {
214 std::pair<SpacePoint*, conversionStatus> aSpacePoint = processTrackCandHit(aTCHit, fHitIDs, iTCHit);
215
216 // if there is more than one single Cluster SpacePoint related to a Cluster, add one
217 if (aSpacePoint.first != nullptr && (aSpacePoint.second >= 0 || aSpacePoint.second == c_nonSingleSP)) {
218 if (aSpacePoint.second == c_singleClusterSP) usedSingleCluster = true;
219 tcSpacePoints.push_back({sortingParam, aSpacePoint.first});
220 B2DEBUG(28, "Added SpacePoint " << aSpacePoint.first->getArrayIndex() << " from Array " << aSpacePoint.first->getArrayName() <<
221 " to tcSpacePoints");
222 m_NDF += getNDF(aSpacePoint.first);
223 } else {
224 convStatus = aSpacePoint.second;
225 B2DEBUG(28, "There was an error during conversion: for Hit " << iTCHit << ": " << convStatus);
226 if (!m_PARAMskipCluster) {
227 B2DEBUG(21,
228 "There was an error during conversion for a GFTC. 'skipCluster' is set to false, hence this trackCand will not be converted!");
229
230 // return empty SPTC if there is a conversion error and splitCurlers is set to false
231 return std::make_pair(SpacePointTrackCand(), convStatus);
232 }
233 }
234 }
235 }
236
237 B2DEBUG(20, "NDF for this SpacePointTrackCand: " << m_NDF);
238 if (m_NDF < m_PARAMminNDF) {
239 B2DEBUG(21, "The created SpacePointTrackCand has not enough NDF: NDF is " << m_NDF << " but 'minNDF' is set to " << m_PARAMminNDF);
240 return std::make_pair(SpacePointTrackCand(), c_lowNDF);
241 }
242
243 // check if all hits have been used
244 bool usedAllHits = checkUsedAllHits(fHitIDs);
245 if (!usedAllHits && !m_PARAMskipCluster) {
246 B2WARNING("There is at least one TrackCandHit that has not been marked as used although 'skipCluster' is set to false"); // write warning here, because if this happens something has gone wrong
247 throw UnusedHits();
248 }
249
250 // create a vector of SpacePoint* and one with sorting Parameters to add to the SpacePointTrackCand
251 std::vector<const SpacePoint*> spacePoints;
252 std::vector<double> sortingParams;
253 for (const HitInfo<SpacePoint>& aSP : tcSpacePoints) {
254 spacePoints.push_back(aSP.second);
255 sortingParams.push_back(aSP.first);
256 }
257
258 SpacePointTrackCand spacePointTC = SpacePointTrackCand(spacePoints, genfitTC->getPdgCode(), genfitTC->getChargeSeed(),
259 genfitTC->getMcTrackId());
260 spacePointTC.set6DSeed(genfitTC->getStateSeed());
261 spacePointTC.setCovSeed(genfitTC->getCovSeed());
262 spacePointTC.setSortingParameters(sortingParams);
263
265 if (!usedAllHits) { spacePointTC.addRefereeStatus(SpacePointTrackCand::c_omittedClusters); }
266 if (usedSingleCluster) { spacePointTC.addRefereeStatus(SpacePointTrackCand::c_singleClustersSPs); }
267
268 return std::make_pair(spacePointTC, c_noFail);
269}
270
271// ============================================================================== PROCESS TRACKCANDHIT ===============================================================================================
272std::pair<Belle2::SpacePoint*, GFTC2SPTCConverterModule::conversionStatus>
273GFTC2SPTCConverterModule::processTrackCandHit(genfit::TrackCandHit* hit, std::vector<flaggedPair<int> >& flaggedHitIDs, int iHit)
274{
275 int detID = hit->getDetId();
276 int hitID = hit->getHitId();
277 int planeID = hit->getPlaneId(); // not used at the moment (except for debug output)
278 B2DEBUG(28, "Processing TrackCandHit " << iHit << " with detID: " << detID << ", hitID: " << hitID << ", planeID: " << planeID);
279
280 std::pair<SpacePoint*, conversionStatus> returnSP = { nullptr, c_noFail }; // default return, optimistically assuming no fail
281
282 if (detID == Const::PXD) {
283 const PXDCluster* aCluster = m_PXDClusters[hitID];
284 returnSP = getSpacePoint<PXDCluster, PXDTrueHit>(aCluster, flaggedHitIDs, iHit, true, m_PXDClusterSPName);
285 if (m_PARAMskipCluster) { increaseSkippedCounter(returnSP.second, aCluster); } // have to do this here at the moment -> COULDDO; change increaseSkippedCounter, such that it can be used without a Cluster
286 if (returnSP.second == c_singleClusterSP) returnSP.second = c_noFail; // getSpacePoint returns singleClusterSP for PXDs!
287 } else if (detID == Const::SVD) {
288 const SVDCluster* aCluster = m_SVDClusters[hitID];
289 returnSP = getSpacePoint<SVDCluster, SVDTrueHit>(aCluster, flaggedHitIDs, iHit, false, m_NoSingleClusterSVDSPName);
290 if (m_PARAMskipCluster) { increaseSkippedCounter(returnSP.second, aCluster); }
291 } else {
292 throw SpacePointTrackCand::UnsupportedDetType();
293 }
294 return returnSP;
295}
296
297// ============================================================================ GET SPACEPOINT =======================================================================================================
298template<typename ClusterType, typename TrueHitType>
299std::pair<Belle2::SpacePoint*, GFTC2SPTCConverterModule::conversionStatus>
300GFTC2SPTCConverterModule::getSpacePoint(const ClusterType* cluster, std::vector<flaggedPair<int> >& flaggedHitIDs, int iHit,
301 bool singleCluster, std::string arrayName)
302{
303 std::pair<SpacePoint*, conversionStatus> spacePoint = {nullptr, c_noFail}; // default return. be optimistic and assume that there are no problems!
304
305 B2DEBUG(28, "Trying to find a related SpacePoint in StoreArray " << arrayName << " for Cluster " << cluster->getArrayIndex() <<
306 " from Array " << cluster->getArrayName());
307 RelationVector<SpacePoint> spacePoints = cluster->template getRelationsFrom<SpacePoint>(arrayName);
308 B2DEBUG(28, "Found " << spacePoints.size() << " related SpacePoints for Cluster " << cluster->getArrayIndex() << " from Array " <<
309 cluster->getArrayName()); // NOTE: .size == 0 handled later!
310
311 if (singleCluster) { // if it is a singleCluster SpacePoint process different, then if it is a double Cluster SpacePoint
312 if (spacePoints.size() == 0) {
313 B2DEBUG(28, "Found no related (single Cluster) SpacePoint!");
314 spacePoint.second = c_foundNoSpacePoint;
315 return spacePoint;
316 }
317 if (spacePoints.size() > 1) {
318 B2ERROR("More than one single Cluster SpacePoint related to a Cluster! Returning only the first in RelationVector!");
319 spacePoint.second = c_nonSingleSP; // WARNING: returning first SpacePoint in RelationVector this way
321 }
322 spacePoint.first = spacePoints[0];
323 // cppcheck-suppress redundantAssignment
324 spacePoint.second = c_singleClusterSP;
325 markHitAsUsed(flaggedHitIDs, iHit); // mark hit as used
326 } else {
327 // try to get the appropriate double Cluster SVD SpacePoint
328 spacePoint = findAppropriateSpacePoint<ClusterType>(spacePoints, flaggedHitIDs);
329 if (spacePoint.first == nullptr) {
330 B2DEBUG(28, "Did not find an appropriate double Cluster SpacePoint for Cluster " << cluster->getArrayIndex() << " from Array " <<
331 cluster->getArrayName() << ". Reason for failure: " << spacePoint.second);
334 B2DEBUG(28, "Trying to get a single Cluster SpacePoint now!");
336 // get single Cluster SVD PacePoint if desired. WARNING: hardcoded to SVD here at the moment!
337 return getSpacePoint<ClusterType, TrueHitType>(cluster, flaggedHitIDs, iHit, true, m_SingleClusterSVDSPName);
338 }
339 }
340 }
341
342 if (m_PARAMcheckTrueHits && spacePoint.first != nullptr) { // only do the TrueHit check if there is actually something to check
343 if (!foundRelatedTrueHit<TrueHitType>(spacePoint.first)) { spacePoint.second = c_foundNoTrueHit; }
344 }
345
346 return spacePoint;
347}
348
349// ============================================================= FIND APPROPRIATE SPACEPOINT ===============================================================================
350template<typename ClusterType>
351std::pair<Belle2::SpacePoint*, GFTC2SPTCConverterModule::conversionStatus>
353 std::vector<flaggedPair<int> >& flaggedHitIDs)
354{
355 std::pair<SpacePoint*, conversionStatus> returnSP = { nullptr, c_noFail }; // default return, be optimistc and assume that there are no problems
356 B2DEBUG(22, "Trying to find an appropriate SpacePoint from RelationVector with " << spacePoints.size() << " entries!");
357 if (spacePoints.size() == 0) {
358 B2DEBUG(28, "There are no spacePoints to choose of!");
359 returnSP.second = c_foundNoSpacePoint;
360 return returnSP;
361 }
362
363 // WARNING: TEL cluster will do something wrong here!
364 int detID = spacePoints[0]->getType() == VXD::SensorInfoBase::SVD ? Const::SVD : Const::PXD;
365
366 // .first: Cluster Combination exists in the TrackCand, .second: Cluster Combination exists and has not yet been used
367 std::vector<std::pair<bool, bool> > existAndValidSP;
368 // .first: index of SpacePoint in RelationVector, .second: Index of Cluster in the genfit::TrackCand
369 std::vector<std::pair<int, int> > clusterPositions;
370
371 // loop over all SpacePoints to look if their Cluster combination is vali (or existing but used, etc...)
372 for (unsigned int iSP = 0; iSP < spacePoints.size(); ++iSP) {
373 const SpacePoint* aSP = spacePoints[iSP];
374 B2DEBUG(22, "Processing SpacePoint " << iSP + 1 << " of " << spacePoints.size() << " with Index " << aSP->getArrayIndex() <<
375 " in StoreArray " << aSP->getArrayName());
376
377 bool bothValid = true; // assume true, change to false if the second Cluster cannot be found in the genfit::TrackCand
378 bool foundBoth = true; // assume true, change to false if the second Cluster can be found, but is already used
379
380 std::vector<int> clusterInds = getClusterIndices<SVDCluster>(aSP, m_SVDClusterName);
381 for (int index : clusterInds) {
382 // get the valid and existing position for cluster. TODO: rename variable!
383 std::pair<int, int> existAndValidClPos = checkExistAndValid(index, detID, flaggedHitIDs);
384 if (existAndValidClPos.first < 0) { // check if cluster is valid and/or exists
385 bothValid = false;
386 if (existAndValidClPos.second < 0) foundBoth = false;
387 }
388
389 // push_back the index in the relationVector and the found valid position
390 clusterPositions.push_back({iSP, existAndValidClPos.first});
391 B2DEBUG(29, "clusterInd: " << index << " checkExistAndValid.first: " << existAndValidClPos.first << ", .second: " <<
392 existAndValidClPos.second << " bothValid/foundBoth: " << bothValid << "/" << foundBoth);
393 }
394 // push_back the determined values
395 existAndValidSP.push_back({foundBoth, bothValid});
396 B2DEBUG(22, "Cluster combination of SpacePoint " << aSP->getArrayIndex() << " is contained in genfit::TrackCand: " << foundBoth <<
397 ". SpacePoint is valid: " << bothValid);
398 }
399
400 int relVecPosition = getAppropriateSpacePointIndex(existAndValidSP, clusterPositions);
401 if (relVecPosition < 0) {
402 returnSP.second = getFailEnum(relVecPosition);
403 return returnSP;
404 }
405
406 B2DEBUG(22, "SpacePoint " << spacePoints[relVecPosition]->getArrayIndex() <<
407 " is the appropriate SpacePoint of all checked SpacePoints! The positions inside the GFTC are: " << clusterPositions.at(
408 relVecPosition * 2).second << " and " << clusterPositions.at(relVecPosition * 2 + 1).second);
409 markHitAsUsed(flaggedHitIDs, clusterPositions.at(relVecPosition * 2).second);
410 markHitAsUsed(flaggedHitIDs, clusterPositions.at(relVecPosition * 2 + 1).second);
411 returnSP.first = spacePoints[relVecPosition];
412
413 return returnSP;
414}
415
416// ========================================================================= GET CLUSTER INDICES ===========================================================================
417template<typename ClusterType>
418std::vector<int> GFTC2SPTCConverterModule::getClusterIndices(const Belle2::SpacePoint* spacePoint, std::string storeArrayName)
419{
420 std::vector<int> clusterInds;
421 RelationVector<ClusterType> relClusters = spacePoint->getRelationsTo<ClusterType>(storeArrayName);
422 B2ASSERT("Too many clusters. There are " << relClusters.size() << " clusters.", relClusters.size() < 3);
423
424 std::stringstream clusterStream;
425 for (const ClusterType& aCluster : relClusters) {
426 clusterInds.push_back(aCluster.getArrayIndex());
427 clusterStream << aCluster.getArrayIndex() << " ";
428 }
429
430 B2DEBUG(29, "getClusterIndices(SpacePoint " << spacePoint->getArrayIndex() << "," << spacePoint->getArrayName() <<
431 "): clusters are: " << clusterStream.str());
432
433 return clusterInds;
434}
435
436// ========================================================================== CHECK EXIST AND VALID =============================================================================
437std::pair<int, int> GFTC2SPTCConverterModule::checkExistAndValid(int clusterInd, int detID,
438 std::vector<flaggedPair<int> >& flaggedHitIDs)
439{
440 B2DEBUG(29, "Now checking if Cluster " << clusterInd << " is valid");
441 std::pair<int, int> positions = { -1, -1}; // return Vector
442
443 // flaggedPair for finding valid IDs: hit is in genfit::TrackCand and has not yet been used by another SpacePoint
444 flaggedPair<int> validID(false, detID, clusterInd);
445 flaggedPair<int> existingID(true, detID, clusterInd); // flaggedPair for finding existing but used fHitIDs
446
447 // find the positions of these two pairs in flaggedHitIDs
448 // position in "normal array indexing" (i.e. starting at 0, ending at vector.size() -1 )
449 unsigned int validPos = std::find(flaggedHitIDs.begin(), flaggedHitIDs.end(), validID) - flaggedHitIDs.begin();
450 unsigned int existingPos = std::find(flaggedHitIDs.begin(), flaggedHitIDs.end(), existingID) - flaggedHitIDs.begin();
451
452 B2DEBUG(22, "validID = (" << validID.get<1>() << "," << validID.get<2>() << "), found at position " << validPos <<
453 ", existingID found at position " << existingPos << " of " << flaggedHitIDs.size());
454
455 // check if these positions are still in the TrackCand
456 if (validPos < flaggedHitIDs.size()) { positions.first = validPos; }
457 if (existingPos < flaggedHitIDs.size()) { positions.second = existingPos; }
458
459 B2DEBUG(29, "Return values, .first: " << positions.first << ", .second: " << positions.second);
460 return positions;
461}
462
463// ============================================================================ GET NDF =============================================================================================
465{
466 if (spacePoint == nullptr) {
467 B2ERROR("Got nullptr pointer to determine the NDF of!");
468 return 0;
469 }
470 std::pair<bool, bool> assignedHits = spacePoint->getIfClustersAssigned();
471 // if both are assigned -> NDF of SpacePoint is 2
472 if (assignedHits.first && assignedHits.second) return 2;
473 // if ONLY one is assigned -> NDF of SpacePoint is 1 (note the use of the bitwise XOR operator)
474 if (assignedHits.first ^ assignedHits.second) return 1;
475 return 0;
476}
477
478// =========================================================================== GET APPROPRIATE SPACEPOINT INDEX =====================================================================
479int GFTC2SPTCConverterModule::getAppropriateSpacePointIndex(const std::vector<std::pair<bool, bool> >& existAndValidSPs,
480 const std::vector<std::pair<int, int> >& clusterPositions)
481{
482 // get the number of existing but used and the number of valid SpacePoints
483 int nExistingButUsedSP = std::count(existAndValidSPs.begin(), existAndValidSPs.end(), std::make_pair(true, false));
484 int nValidSP = std::count(existAndValidSPs.begin(), existAndValidSPs.end(), std::make_pair(true, true));
485
486 if (LogSystem::Instance().isLevelEnabled(LogConfig::c_Debug, 999, PACKAGENAME())) { // some very verbose output
487 std::stringstream output;
488 output << "content of passed vector of pairs (comma separated): ";
489 for (auto entry : existAndValidSPs) { output << entry.first << "/" << entry.second << ", "; }
490 B2DEBUG(29, output.str() << "nValidSP: " << nValidSP << " nExistingButUsedSP: " << nExistingButUsedSP);
491 }
492
493 // if there is no valid SpacePoint, but a SpacePoint with an existing but used cluster, throw, because conversion cannot be done properly then
494 if (nValidSP < 1 && nExistingButUsedSP > 0) {
495 B2DEBUG(28,
496 "There are only Cluster Combinations where one of the Clusters is already used by another SpacePoint! This genfit::TrackCand cannot be converted properly to a SpacePointTrackCand!");
497 return c_unsuitableGFTC;
498 } else if (nValidSP < 1 && nExistingButUsedSP < 1) {
499 B2DEBUG(28, "Found no valid SpacePoint and no SpacePoint with existing but used Clusters/Hits!");
500 return c_noValidSP;
501 } // if there is at least one valid SpacePoint, check the position difference and then decide if the SP can be used!
502 else if (nValidSP > 0) {
503 // 1) index of SpacePoint in RelationVector, 2) squared position difference, 3) & 4) are positions inside genfit::TrackCand (valid positions)
504 std::vector<std::pair<int, int> > positionInfos;
505
506 for (unsigned int iSP = 0; iSP < existAndValidSPs.size(); ++iSP) {
507 if (!existAndValidSPs.at(iSP).second) continue; // if not valid continue with next SpacePoint
508 // sign doesn't matter, comparing squared values later only!
509 int posDiff = clusterPositions.at(iSP * 2).second - clusterPositions.at(iSP * 2 + 1).second;
510
511 B2DEBUG(28, "Difference of positions of Clusters for entry " << iSP << " is " << posDiff);
512 positionInfos.push_back(std::make_pair(iSP, posDiff * posDiff));
513 }
514
515 // sort to find the smallest difference
516 sort(positionInfos.begin(), positionInfos.end(), [](const std::pair<int, int>& lTuple, const std::pair<int, int>& rTuple) { return lTuple.second < rTuple.second; });
517
518 if (positionInfos.at(0).second != 1) {
519 B2DEBUG(28, "The shortest squared distance between two Clusters is " << positionInfos.at(0).second <<
520 "! This would lead to wrong ordered TrackCandHits.");
521 return c_unsuitableGFTC;
522 }
523
524 B2DEBUG(22, "SpacePoint with index " << positionInfos.at(0).first <<
525 " is the valid SpacePoint with two Clusters in consecutive order from all valid SpacePoints.");
526 return positionInfos.at(0).first;
527 }
528
529 return c_noValidSP; // default return is negative
530}
531
532// =============================================================================== CHECK USED ALL HITS ==========================================================================
534{
535 bool usedAll = true; // defining variable here so that all hits are checked (debug output)
536 for (unsigned int i = 0; i < flaggedHitIDs.size(); ++i) {
537 flaggedPair<int> fPair = flaggedHitIDs[i];
538 B2DEBUG(28, "Hit " << i << " with (detID,hitID): (" << fPair.get<1>() << "," << fPair.get<2>() << ") has been used: " <<
539 fPair.get<0>());
540 if (!fPair.get<0>()) {
541// return false;
542 usedAll = false;
543 }
544 }
545// return true;
546 return usedAll;
547}
548
549// ================================================== FOUND RELATED TRUEHIT =================================================================
550template <typename TrueHitType>
551bool GFTC2SPTCConverterModule::foundRelatedTrueHit(const Belle2::SpacePoint* spacePoint, unsigned int allowedRelations)
552{
553 RelationVector<TrueHitType> relTrueHits = spacePoint->getRelationsTo<TrueHitType>("ALL"); // WARNING: searching in all relations
554 if (relTrueHits.size() == 0) {
555 B2DEBUG(22, "Found no TrueHit to SpacePoint " << spacePoint->getArrayIndex() << " from Array " << spacePoint->getArrayName());
556 return false;
557 }
558 B2DEBUG(22, "Found " << relTrueHits.size() << " related TrueHits for SpacePoint " << spacePoint->getArrayIndex() << " from Array "
559 << spacePoint->getArrayName());
560 return (relTrueHits.size() <= allowedRelations);
561}
562
563
564
565void GFTC2SPTCConverterModule::markHitAsUsed(std::vector<flaggedPair<int> >& flaggedHitIDs, int hitToMark)
566{
567 flaggedHitIDs[hitToMark].get<0>() = true;
568 flaggedPair<int> fPair = flaggedHitIDs[hitToMark];
569 B2DEBUG(22, "Marked Hit " << hitToMark << " as used. (detID,hitID) of this hit is (" << fPair.get<1>() << "," << fPair.get<2>() <<
570 ")");
571}
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition: DataStore.h:72
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
Definition: DataStore.h:59
unsigned int m_abortedNoSPCtr
Counter for aborted conversions because no SpacePoint has been found.
StoreArray< SpacePoint > m_SingleClusterSpacePoints
SVD SpacePoints StoreArray only consisting of one SVDCluster.
int getNDF(Belle2::SpacePoint *spacePoint)
get the NDF of a SpacePoint
int m_PARAMminNDF
parameter for specifying a minimal number of degrees of freedom a SpacePointTrackCand has to have in ...
unsigned int m_skippedPXDunsuitableCtr
Counter for skipped PXD Clusters due to unsuitable GFTC.
bool m_PARAMskipCluster
Switch for controlling the behavior of the converter, when for one or more Clusters no appropriate Sp...
conversionStatus
enum for differentiating different reasons why a conversion failed negative values mean fail!
@ c_nonSingleSP
conversion failed because there were more than one single Cluster SpacePoints related to a Cluster
@ c_foundNoSpacePoint
conversion failed because no related SpacePoint was found to a Cluster/Hit of the GFTC
@ c_singleClusterSP
had to use a singleCluster SpacePoint (also returned if PXD is passed!
@ c_lowNDF
conversion failed because the created SpacePointTrackCand had not enough degrees of freedom
@ c_noValidSP
conversion failed because there was no valid SpacePoint (only possible for double Cluster SpacePoints...
@ c_foundNoTrueHit
conversion failed because there was no related SpacePoint to a TrueHit
@ c_unsuitableGFTC
conversion failed because the GFTC is considered not suitable for conversion
@ c_noFail
conversion without any problems
unsigned int m_skippedSVDnoValidSPCtr
Counter for skipped SVD Clusters due to no found valid SpacePoint.
std::string m_SingleClusterSVDSPName
Single Cluster SVD SpacePoints collection name.
unsigned int m_abortedUnsuitableTCCtr
Counter for aborted conversions due to unsuitable genfit::TrackCand.
std::pair< double, const HitType * > HitInfo
container used for storing information, that is then put into the SpacePointTrackCand
StoreArray< SVDCluster > m_SVDClusters
SVDClusters StoreArray.
std::string m_NoSingleClusterSVDSPName
Non SingleCluster SVD SpacePoints collection name.
void initialize() override
initialize module (e.g.
StoreArray< SpacePointTrackCand > m_SpacePointTrackCands
SpacePointTrackCands StoreArray.
void event() override
event: convert genfit::TrackCands to SpacePointTrackCands
std::string m_PXDClusterName
PXDCluster collection name.
unsigned int m_skippedSVDunsuitableCtr
Counter for skipped SVD Clusters due to unsuitable GFTC.
StoreArray< PXDTrueHit > m_PXDTrueHits
PXDTrueHits StoreArray.
void terminate() override
terminate: print some summary information on the processed events
bool foundRelatedTrueHit(const Belle2::SpacePoint *spacePoint, unsigned int allowedRelations=1)
check if there is a related TrueHit for a given SpacePoint.
unsigned int m_skippedSVDnoSPCtr
Counter for skipped SVD Clusters, due to no found SpacePoint.
unsigned int m_genfitTCCtr
Counter for genfit::TrackCands which were presented to the module.
std::string m_genfitTCName
Name of collection of genfit::TrackCand StoreArray.
void increaseSkippedCounter(conversionStatus status, ClusterType *cluster)
increase the appropriate counter variable if a Cluster is skipped (i.e.
bool m_PARAMcheckTrueHits
Parameter Indicating if the TrueHits related from the Clusters forming a SpacePoint should be checked...
unsigned int m_skippedSVDnoTHCtr
Counter for skipped SVD Clusters, due to no related TrueHit to a SpacePoint.
StoreArray< genfit::TrackCand > m_GenfitTrackCands
Genfit::TrackCand StoreArray.
bool m_PARAMuseSingleClusterSP
Parameter Indicating if SingleCluster SVD SpacePoints should be used if no double Cluster SVD SpacePo...
std::pair< Belle2::SpacePoint *, conversionStatus > processTrackCandHit(genfit::TrackCandHit *hit, std::vector< flaggedPair< int > > &flaggedHitIDs, int iHit)
process a TrackCandHit (i.e.
unsigned int m_nonSingleSPCtr
Counter for cases where there is more than one single Cluster SpacePoint related to a Cluster.
unsigned int m_noTwoClusterSPCtr
Counter for cases where no related two Cluster could be found for a Cluster.
StoreArray< PXDCluster > m_PXDClusters
PXDClusters StoreArray.
unsigned int m_abortedNoValidSPCtr
Counter for aborted conversions due to no found valid SpacePoint to any Cluster of the GFTC.
boost::tuple< bool, T, T > flaggedPair
typedef, for avoiding having a vector<bool> and a vector<pair<T,T>>
std::string m_SPTCName
Name of collection under which SpacePointTrackCands will be stored in the StoreArray.
conversionStatus getFailEnum(int intToConvert)
get the enum representation of an integer
void increaseFailCounter(conversionStatus status)
increase the counter that 'belongs' to the conversionStatus
void markHitAsUsed(std::vector< flaggedPair< int > > &flaggedHitIDs, int hitToMark)
mark a hit as used, i.e.
unsigned int m_skippedPXDnoSPCtr
Counter for skipped PXD Clusters, due to no found SpacePoint.
std::pair< Belle2::SpacePoint *, conversionStatus > findAppropriateSpacePoint(const Belle2::RelationVector< Belle2::SpacePoint > &spacePoints, std::vector< flaggedPair< int > > &flaggedHitIDs)
given a RelationVector with SpacePoints in it, it tries to get the appropriate one (see main document...
unsigned int m_skippedPXDnoValidSPCtr
Counter for skipped PXD Clusters due to no found valid SpacePoint.
std::string m_SVDClusterName
SVDCluster collection name.
std::string m_PXDClusterSPName
PXDCluster SpacePoints collection name.
unsigned int m_skippedPXDnoTHCtr
Counter for skipped PXD Clusters, due to no related TrueHit to a SpacePoint.
std::pair< int, int > checkExistAndValid(int clusterInd, int detID, std::vector< flaggedPair< int > > &flaggedHitIDs)
check if the Cluster (of a SpacePoint) is valid and/or exists in a genfit::TrackCand
unsigned int m_skippedCluster
Counter for skipped Cluster.
std::pair< Belle2::SpacePoint *, conversionStatus > getSpacePoint(const ClusterType *cluster, std::vector< flaggedPair< int > > &flaggedHitIDs, int iHit, bool singleCluster, std::string arrayName="")
templated version to get a SpacePoint from a Cluster
bool m_PARAMcheckNoSingleSVDSP
Switch for checking the StoreArray of non-single cluster SVD SpacePoints in initialize.
unsigned int m_SpacePointTCCtr
Counter for SpacePointTrackCands which were converted (if a curling track is split up,...
unsigned int m_abortedLowNDFCtr
Counter for SpacePointTrackCands that were not stored due to a too small number of degrees of freedom...
bool checkUsedAllHits(std::vector< flaggedPair< int > > &flaggedHitIDs)
check if all hits have been used (i.e.
std::vector< int > getClusterIndices(const Belle2::SpacePoint *spacePoint, std::string storeArrayName)
get the indices of the Clusters related to the SpacePoint.
void initializeCounters()
reset counters to 0 to avoid indeterministic behaviour
int m_NDF
number of degrees of freedom.
unsigned int m_singleClusterSPCtr
Counter for single cluster SVD SpacePoints.
std::pair< const Belle2::SpacePointTrackCand, conversionStatus > createSpacePointTC(const genfit::TrackCand *genfitTC)
create a SpacePointTrackCand from the genfit::TrackCand
int getAppropriateSpacePointIndex(const std::vector< std::pair< bool, bool > > &existAndValidSPs, const std::vector< std::pair< int, int > > &clusterPositions)
get the position of the appropriate SpacePoint inside the RelationVector NOTE: returns negative index...
StoreArray< SpacePoint > m_PXDSpacePoints
PXDSpacePoints StoreArray.
StoreArray< SpacePoint > m_NoSingleClusterSpacePoints
SVD SpacePoints StoreArray consisting of two SVDClusters.
StoreArray< SVDTrueHit > m_SVDTrueHits
SVDTrueHits StoreArray.
unsigned int m_abortedTrueHitCtr
Counting discarded conversions due to check for TrueHits not good.
@ c_Debug
Debug: for code development.
Definition: LogConfig.h:26
static LogSystem & Instance()
Static method to get a reference to the LogSystem instance.
Definition: LogSystem.cc:31
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
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:30
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
std::string getArrayName() const
Get name of array this object is stored in, or "" if not found.
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:29
Storage for (VXD) SpacePoint-based track candidates.
void setSortingParameters(const std::vector< double > &sortParams)
set the sorting parameters
void set6DSeed(const TVectorD &state6D)
set the 6D state seed
void setCovSeed(const TMatrixDSym &cov)
set the covariance matrix seed
@ c_checkedTrueHits
bit 5: All SpacePoints of the SPTC have a relation to at least one TrueHit.
@ c_omittedClusters
bit 9: Not all Clusters of the genfit::TrackCand have been used to create this SPTC.
@ c_singleClustersSPs
bit 10: SPTC contains single Cluster SpacePoints.
void addRefereeStatus(unsigned short int bitmask)
add a referee status
SpacePoint typically is build from 1 PXDCluster or 1-2 SVDClusters.
Definition: SpacePoint.h:42
std::pair< bool, bool > getIfClustersAssigned() const
Returns, if u(v)-coordinate is based on cluster information.
Definition: SpacePoint.h:162
const std::string & getName() const
Return name under which the object is saved in the DataStore.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
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
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:140
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.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
Abstract base class for different kinds of events.