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