Belle II Software  release-08-01-10
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 
20 using namespace Belle2;
21 
22 REG_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 overriden 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 =========================================================================================
185 std::pair<const Belle2::SpacePointTrackCand, GFTC2SPTCConverterModule::conversionStatus>
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 ===============================================================================================
272 std::pair<Belle2::SpacePoint*, GFTC2SPTCConverterModule::conversionStatus>
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 =======================================================================================================
298 template<typename ClusterType, typename TrueHitType>
299 std::pair<Belle2::SpacePoint*, GFTC2SPTCConverterModule::conversionStatus>
300 GFTC2SPTCConverterModule::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 ===============================================================================
350 template<typename ClusterType>
351 std::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 ===========================================================================
417 template<typename ClusterType>
418 std::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 =============================================================================
437 std::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 =====================================================================
479 int 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 doesnot 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 =================================================================
550 template <typename TrueHitType>
551 bool 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 
565 void 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
typdef, 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
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
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.
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
Hit object for use in TrackCand.
Definition: TrackCandHit.h:34
Track candidate – seed values and indices.
Definition: TrackCand.h:69
int getMcTrackId() const
Get the MCT track id, for MC simulations - default value = -1.
Definition: TrackCand.h:119
int getPdgCode() const
Get the PDG code.
Definition: TrackCand.h:139
void Print(const Option_t *="") const
Write the content of all private attributes to the terminal.
Definition: TrackCand.cc:202
const TMatrixDSym & getCovSeed() const
get the covariance matrix seed (6D).
Definition: TrackCand.h:131
const TVectorD & getStateSeed() const
Returns the 6D seed state; should be in global coordinates.
Definition: TrackCand.h:134
REG_MODULE(arichBtest)
Register the Module.
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
Abstract base class for different kinds of events.