Belle II Software  release-05-02-19
TCConvertersTestModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2014 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Thomas Madlener *
7  * *
8  **************************************************************************/
9 
10 #include <tracking/modules/spacePointCreator/TCConvertersTestModule.h>
11 
12 #include <framework/datastore/StoreArray.h>
13 #include <framework/datastore/StoreObjPtr.h>
14 #include <framework/dataobjects/EventMetaData.h>
15 
16 // #include <tracking/spacePointCreation/SpacePointTrackCand.h> // already in header
17 // #include <genfit/TrackCand.h> // already in header
18 
19 using namespace Belle2;
20 using namespace std;
21 
22 REG_MODULE(TCConvertersTest)
23 
25  Module()
26 {
27  setDescription("Module for testing the functionality of the TrackCand converter modules and their underlying classes.");
28 
29  addParam("PXDClusters", m_PXDClusterName, "PXDCluster collection name. WARNING: it is only checked if these exist, "\
30  "they are not actually used at the moment!", string(""));
31  addParam("SVDClusters", m_SVDClusterName, "SVDCluster collection name WARNING: it is only checked if these exist, "\
32  " they are not actually used at the moment!", string(""));
33  addParam("SpacePointTCName", m_SPTCName, "Name of the container under which SpacePoints are stored in the DataStore", string(""));
34 
35  std::vector<std::string> emptyDefaultStringVec = { std::string("") };
36  addParam("genfitTCNames", m_genfitTCNames, "Names of containers of genfit::TrackCands. "\
37  "WARNING: For this module provide two names! First is the name of the container with the genfit::TrackCands"\
38  " which were used to create SpacePointTrackCands (e.g. from MCTrackFinderTruth), second are the genfit::TrackCands"\
39  " obtaineed by the 'back conversion' from the SpacePointTrackCands!", emptyDefaultStringVec);
40 
41  initializeCounters(); // NOTE: they get initialized in initialize again!!
42 }
43 
44 // --------------------------------- INITIALIZE -------------------------------------
46 {
47  B2INFO("TCConvertersTest ---------------------------- initialize ------------------ ");
48 
49  // check if all StoreArrays are present
50  StoreArray<SpacePointTrackCand> SPTCs(m_SPTCName); SPTCs.isRequired(m_SPTCName);
51  for (string aName : m_genfitTCNames) {
53  TCs.isRequired(aName);
54  }
55 
56  StoreArray<PXDCluster> PXDClusters(m_PXDClusterName); PXDClusters.isRequired(m_PXDClusterName);
57  StoreArray<SVDCluster> SVDClusters(m_SVDClusterName); SVDClusters.isRequired(m_SVDClusterName);
58 
59  initializeCounters();
60 }
61 
62 // ----------------------------------- EVENT -----------------------------------------
64 {
65  StoreObjPtr<EventMetaData> eventMetaDataPtr("EventMetaData", DataStore::c_Event);
66  const int eventCounter = eventMetaDataPtr->getEvent();
67  B2DEBUG(10, "TCConvertersTest::event(). Processing event " << eventCounter << " --------");
68 
69  // this is very specific at the moment, but as it is only a testing module, I think it should work
70  StoreArray<genfit::TrackCand> genfitTCs(m_genfitTCNames[0]);
71  StoreArray<genfit::TrackCand> convertedGenfitTCs(m_genfitTCNames[1]);
72 
73  StoreArray<SpacePointTrackCand> SpacePointTCs(m_SPTCName);
74 
75  int nGenfitTCs = genfitTCs.getEntries();
76  int nConvertedTCs = convertedGenfitTCs.getEntries();
77  int nSpacePointTCs = SpacePointTCs.getEntries();
78 
79  m_genfitTCCtr += nGenfitTCs;
80  m_convertedTCCtr += nConvertedTCs;
81  m_SpacePointTCCtr += nSpacePointTCs;
82 
83  B2DEBUG(11, "Found " << nGenfitTCs << " genfit::TrackCands, " << nSpacePointTCs << " SpacePointTrackCands and " << \
84  nConvertedTCs << " genfit::TrackCands created by conversion from a SpacePointTrackCand");
85 
86  // count the 'simple' reasons for failure (if there are less SpacePointTCs than genfitTCs,
87  // there has to be a problem with the creation of SpacePointTCs which should result in a warning.
88  // The same applies for the back-conversion to genfitTCs)
89  m_failedNoSPTC += (nGenfitTCs - nSpacePointTCs);
90  m_failedNoGFTC += (nSpacePointTCs - nConvertedTCs);
91 
92  // have to loop over the SpacePointTrackCand as they inherit from RelationObject and therefore have the possibility
93  // to get Relations to or from them
94  for (int iTC = 0; iTC < nSpacePointTCs; ++iTC) {
95  const SpacePointTrackCand* trackCand = SpacePointTCs[iTC];
96 
97  B2DEBUG(20, "Now comparing genfit::TrackCands related from SpacePointTrackCand " << trackCand->getArrayIndex() << \
98  " from Array " << trackCand->getArrayName());
99 
100  // there SHOULD only exist one relation to each StoreArray of genfit::TrackCands for each SpacePointTrackCand (each converter
101  // module registers one, but since genfit::TrackCand is no RelationObject it is only possible to register RelationTo)
102  const genfit::TrackCand* genfitTC = trackCand->getRelatedTo<genfit::TrackCand>(m_genfitTCNames[0]);
103  const genfit::TrackCand* convertedTC = trackCand->getRelatedTo<genfit::TrackCand>(m_genfitTCNames[1]);
104 
105  // check if both trackCands are present (this should never happen, if the relations work correctly!)
106  if (genfitTC == NULL) {
107  B2DEBUG(50, "Found no original genfit::TrackCand related from SpacePointTrackCand " << trackCand->getArrayIndex() << \
108  " from Array " << trackCand->getArrayName());
109  ++m_failedNoRelationOrig;
110  continue;
111  }
112  if (convertedTC == NULL) {
113  B2DEBUG(50, "Found no converted genfit::TrackCand related from SpacePointTrackCand " << trackCand->getArrayIndex() << \
114  " from Array " << trackCand->getArrayName());
115  ++m_failedNoRelationConv;
116  continue;
117  }
118 
119  // only print in debug mode
120  if (LogSystem::Instance().isLevelEnabled(LogConfig::c_Debug, 100, PACKAGENAME())) {
121  genfitTC->Print();
122  convertedTC->Print();
123  }
124 
125  // compare the two genfit::TrackCands
126  if (*genfitTC == *convertedTC) {
127  B2DEBUG(20, "The two genfit::TrackCands are equal!");
128  continue;
129  } else {
130  B2DEBUG(20, "The two genfit::TrackCands differ!");
131  if (analyzeMisMatch(genfitTC, convertedTC, trackCand)) {
132  B2DEBUG(20, "It is OK for the two TrackCands to differ (i.e. the hits that miss are due to their absence in the SPTC!)");
133  m_differButOKCtr++;
134  } else {
135  B2WARNING("Two genfit::TrackCands differ but there is no appearant reason why they should be allowed to do so!");
136  m_failedOther++;
137  }
138  }
139  }
140 }
141 
142 // -------------------------------- TERMINATE -----------------------------------------
144 {
145  stringstream results; // put together BASIC results
146  results << "There were " << m_failedOther << " cases that one should look into and " << \
147  m_differButOKCtr << " cases where the failure of the comparison can be explained.";
148 
149  B2INFO("TCConverterTest::terminate(): Got " << m_genfitTCCtr << " 'original' genfit::TrackCands, " << \
150  m_convertedTCCtr << " genfit::TrackCands to compare and " << m_SpacePointTCCtr << " SpacePointTrackCands. " << results.str());
151 
152  if (m_failedOther) { B2WARNING("There were cases during comparison that need to be looked at!"); } // should not happen anymore
153 
154  if (LogSystem::Instance().isLevelEnabled(LogConfig::c_Debug, 1, PACKAGENAME())) {
155  stringstream verbose;
156  verbose << m_lessHitsCtr << " times the original GFTC had less hits than the converted" << endl;
157  verbose << m_moreHitsCtr << " times the converted GFTC had less hits than the original" << endl;
158  verbose << m_failedWrongSortingParam << " times the sorting parameters did not match" << endl;
159  verbose << m_failedWrongOrder << " times the hits were contained in the wrong order " << endl;
160  verbose << m_failedNotSameHits << " times there were hits in the converted GFTC that were not in the original" << endl;
161  verbose << m_failedNoRelationConv << " times there was no related converted GFTC to a SPTC" << endl;
162  verbose << m_failedNoRelationConv << " times there was no related original GFTC to a SPTC" << endl;
163  verbose << "In " << m_failedNoSPTC << " cases the conversion from GFTC -> SPTC went wrong and in ";
164  verbose << m_failedNoGFTC << " cases the conversion from SPTC -> GFTC went wrong" << endl;
165  B2DEBUG(1, verbose.str());
166  }
167 }
168 
169 // ================================================ ANALYZE MISMATCH ==============================================================
171  const Belle2::SpacePointTrackCand* spTC)
172 {
173  // compare number of hits
174  size_t nOrigHits = origTC->getNHits();
175  size_t nConvHits = convTC->getNHits();
176  bool diffNHits = nOrigHits != nConvHits;
177  if (diffNHits) {
178  B2DEBUG(100, "The number of hits do not match. original GFTC: " << nOrigHits << ", converted GFTC: " << nConvHits);
179  if (nOrigHits > nConvHits) m_moreHitsCtr++; // the converted GFTC has less hits than the original
180  else m_lessHitsCtr++;
182  // if there is a missing hit, but omitted hit is wrong, there is something wrong
183  B2WARNING("The number of hits does not match but the referee status omittedClusters is not set for the SPTC!");
184  return false;
185  }
186  }
187 
188  // get the hits to compare further on the hit level
189  vector<trackCandHit> origHits = getTrackCandHits(origTC);
190  vector<trackCandHit> convHits = getTrackCandHits(convTC);
191 
192  array<bool, 4> foundHits = checkHits(origHits, convHits);
193  B2DEBUG(1999, "Contents of foundHits: " << get<0>(foundHits) << " " << get<1>(foundHits) << \
194  " " << get<2>(foundHits) << " " << get<3>(foundHits));
195 
196  if (!foundHits[0]) { // if there are unfound hits: return false regardless of the refereeStatus of the SPTC
197  B2WARNING("Not all hits from the converted GFTC are in the original GFTC!"); // warning for the moment, should not happen often
198  m_failedNotSameHits++;
199  return false;
200  } else { // NOTE: for the moment only checking the order and the sorting params, but not the planeIDs!
201  if (!foundHits[1]) { // if all hits are present, but they are in the wrong order
202  B2DEBUG(1, "The hits appear in the wrong order in the converted GFTC compared to the original GFTC!");
203  m_failedWrongOrder++;
204  }
205  if (!foundHits[3]) { // sorting params not matching
206  B2WARNING("The sorting parameters are not matching!");
207  m_failedWrongSortingParam++;
208  }
209  }
210 
211  return true;
212 }
213 
214 // ====================================================== GET TRACKCANDHITS =======================================================
215 std::vector<TCConvertersTestModule::trackCandHit> TCConvertersTestModule::getTrackCandHits(const genfit::TrackCand* trackCand)
216 {
217  vector<trackCandHit> tcHits;
218  for (size_t iHit = 0; iHit < trackCand->getNHits(); ++iHit) {
219  genfit::TrackCandHit* hit = trackCand->getHit(iHit);
220  tcHits.push_back(make_tuple(hit->getDetId(), hit->getHitId(), hit->getPlaneId(), hit->getSortingParameter()));
221  }
222  return tcHits;
223 }
224 
225 // ================================================== CHECK HITS ===================================================================
226 std::array<bool, 4> TCConvertersTestModule::checkHits(const std::vector<trackCandHit>& origHits,
227  const std::vector<trackCandHit>& convHits)
228 {
229  std::array<bool, 4> checkResults = {{ true, true, true, true }};
230  typedef vector<trackCandHit>::const_iterator vectorIt; // typedef for avoiding auto below
231 
232  int priorPos = -1; // first hit is 0 at least
233  B2DEBUG(499, "Checking if all hits of converted TC can be found in the original TC!");
234  stringstream allHitsOut;
235  for (const trackCandHit& hit : origHits) {
236  allHitsOut << get<0>(hit) << "\t" << get<1>(hit) << "\t" << get<2>(hit) << "\t" << get<3>(hit) << endl;
237  }
238  B2DEBUG(499, "Hits of original TC:\ndetId\thitId\tplaneId\tsort.Param:\n" << allHitsOut.str());
239 
240  for (size_t iHit = 0; iHit < convHits.size(); ++iHit) { // loop over all hits in convHits
241  trackCandHit hit = convHits[iHit];
242  int pos;
243  stringstream hitOut;
244  hitOut << "Checking hit " << get<0>(hit) << " " << get<1>(hit) << " " << get<2>(hit) << " " << get<3>(hit) << " -> ";
245  vectorIt foundIt = find(origHits.begin(), origHits.end(), hit);
246 
247  if (foundIt == origHits.end()) { // check if a hit can be found without comparing the sorting parameters
248  hitOut << "not found, now checking if omitting planeID and sortingParams helps:" << endl;
249  vectorIt foundOnlyHitsIt = checkEntries<0, 1>(origHits, hit);
250  if (foundOnlyHitsIt != origHits.end()) {
251  pos = foundOnlyHitsIt - origHits.begin();
252  hitOut << " hit is contained in origHits at position " << pos << "! Now checking what is not matching " << endl;
253  vectorIt foundNoSortIt = checkEntries<0, 1, 2>(origHits, hit);
254  vectorIt foundNoPlaneIdIt = checkEntries<0, 1, 3>(origHits, hit);
255  if (foundNoSortIt == origHits.end()) {
256  hitOut << " sorting parameters are not matching!" << endl;
257  checkResults[3] = false;
258  }
259  if (foundNoPlaneIdIt == origHits.end()) {
260  hitOut << " the planeIDs are not matching!" << endl;
261  checkResults[2] = false;
262  }
263  } else {
264  hitOut << " hit is not contained in origHits!" << endl;
265  checkResults[0] = false;
266  continue; // start over with next hit
267  }
268  } else {
269  pos = foundIt - origHits.begin();
270  hitOut << " hit found at position " << pos << endl;
271  }
272  B2DEBUG(499, hitOut.str());
273  B2DEBUG(499, "This hit appears in position " << pos << " in the original TC " << " the last checked hit was on position " <<
274  priorPos);
275 
276  if (pos <= priorPos) {
277  B2DEBUG(499, "The ordering of hits is wrong!");
278  checkResults[1] = false;
279  }
280  priorPos = pos;
281  }
282  return checkResults;
283 }
284 
285 // ======================================================= INITIALIZE COUNTERS ====================================================
287 {
288  B2INFO("TCConvertersTestModule initializing Counter variables");
289  m_genfitTCCtr = 0;
290  m_SpacePointTCCtr = 0;
291  m_convertedTCCtr = 0;
292  m_failedNoGFTC = 0;
293  m_failedNoSPTC = 0;
294  m_failedOther = 0;
295  m_failedNotSameHits = 0;
296  m_failedWrongOrder = 0;
297  m_failedWrongSortingParam = 0;
298  m_failedNoRelationOrig = 0;
299  m_failedNoRelationConv = 0;
300 
301  m_lessHitsCtr = 0;
302  m_moreHitsCtr = 0;
303  m_differButOKCtr = 0;
304 }
Belle2::TCConvertersTestModule::initialize
void initialize() override
Initialize the Module.
Definition: TCConvertersTestModule.cc:45
Belle2::TCConvertersTestModule::event
void event() override
event: event-wise jobs
Definition: TCConvertersTestModule.cc:63
genfit::TrackCand
Track candidate – seed values and indices.
Definition: TrackCand.h:69
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::TCConvertersTestModule::analyzeMisMatch
bool analyzeMisMatch(const genfit::TrackCand *origTC, const genfit::TrackCand *convTC, const Belle2::SpacePointTrackCand *spTC)
analyze why the conversion failed, and check if it can be explained by the referee Status of the SPTC...
Definition: TCConvertersTestModule.cc:170
Belle2::RelationsInterface::getArrayName
std::string getArrayName() const
Get name of array this object is stored in, or "" if not found.
Definition: RelationsObject.h:379
genfit::TrackCandHit
Hit object for use in TrackCand.
Definition: TrackCandHit.h:34
Belle2::RelationsInterface::getRelatedTo
TO * getRelatedTo(const std::string &name="", const std::string &namedRelation="") const
Get the object to which this object has a relation.
Definition: RelationsObject.h:250
Belle2::TCConvertersTestModule::getTrackCandHits
std::vector< trackCandHit > getTrackCandHits(const genfit::TrackCand *trackCand)
get all TrackCandHits from a genfit::TrackCand (no such method in genfit)
Definition: TCConvertersTestModule.cc:215
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2::TCConvertersTestModule::trackCandHit
std::tuple< int, int, int, double > trackCandHit
terminate: print some summary information
Definition: TCConvertersTestModule.h:59
genfit::TrackCand::Print
void Print(const Option_t *="") const
Write the content of all private attributes to the terminal.
Definition: TrackCand.cc:202
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::StoreObjPtr
Type-safe access to single objects in the data store.
Definition: ParticleList.h:33
Belle2::TCConvertersTestModule::initializeCounters
void initializeCounters()
initialize all counter variables to zero, to avoid indeterministic behaviour
Definition: TCConvertersTestModule.cc:286
Belle2::TCConvertersTestModule
Module for testing if the converting Modules do their job as intened.
Definition: TCConvertersTestModule.h:46
Belle2::SpacePointTrackCand::hasRefereeStatus
bool hasRefereeStatus(unsigned int short bitmask) const
Check if the SpacePointTrackCand has the status characterized by the bitmask.
Definition: SpacePointTrackCand.h:217
Belle2::RelationsInterface::getArrayIndex
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
Definition: RelationsObject.h:387
Belle2::LogSystem::Instance
static LogSystem & Instance()
Static method to get a reference to the LogSystem instance.
Definition: LogSystem.cc:33
Belle2::SpacePointTrackCand::c_omittedClusters
@ c_omittedClusters
bit 9: Not all Clusters of the genfit::TrackCand have been used to create this SPTC.
Definition: SpacePointTrackCand.h:92
Belle2::TCConvertersTestModule::checkHits
std::array< bool, 4 > checkHits(const std::vector< trackCandHit > &origHits, const std::vector< trackCandHit > &convHits)
check if the same trackCandHits are contained in both vectors
Definition: TCConvertersTestModule.cc:226
Belle2::LogConfig::c_Debug
@ c_Debug
Debug: for code development.
Definition: LogConfig.h:36
Belle2::StoreArray< SpacePointTrackCand >
Belle2::DataStore::c_Event
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
Definition: DataStore.h:61
Belle2::StoreArray::getEntries
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:226
Belle2::SpacePointTrackCand
Storage for (VXD) SpacePoint-based track candidates.
Definition: SpacePointTrackCand.h:51
Belle2::TCConvertersTestModule::terminate
void terminate() override
This method is called at the end of the event processing.
Definition: TCConvertersTestModule.cc:143