Belle II Software development
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
18using namespace Belle2;
19
20REG_MODULE(TCConvertersTest);
21
23 Module()
24{
25 setDescription("Module for testing the functionality of the TrackCand converter modules and their underlying classes.");
26
27 addParam("PXDClusters", m_PXDClusterName, "PXDCluster collection name. WARNING: it is only checked if these exist, "\
28 "they are not actually used at the moment!", std::string(""));
29 addParam("SVDClusters", m_SVDClusterName, "SVDCluster collection name WARNING: it is only checked if these exist, "\
30 " they are not actually used at the moment!", std::string(""));
31 addParam("SpacePointTCName", m_SPTCName, "Name of the container under which SpacePoints are stored in the DataStore",
32 std::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
50 for (std::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
59}
60
61// ----------------------------------- EVENT -----------------------------------------
63{
64 StoreObjPtr<EventMetaData> eventMetaDataPtr("EventMetaData", DataStore::c_Event);
65 const int eventCounter = eventMetaDataPtr->getEvent();
66 B2DEBUG(20, "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
71
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(20, "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(25, "Found no original genfit::TrackCand related from SpacePointTrackCand " << trackCand->getArrayIndex() << \
107 " from Array " << trackCand->getArrayName());
109 continue;
110 }
111 if (convertedTC == nullptr) {
112 B2DEBUG(25, "Found no converted genfit::TrackCand related from SpacePointTrackCand " << trackCand->getArrayIndex() << \
113 " from Array " << trackCand->getArrayName());
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!)");
133 } else {
134 B2WARNING("Two genfit::TrackCands differ but there is no apparent reason why they should be allowed to do so!");
136 }
137 }
138 }
139}
140
141// -------------------------------- TERMINATE -----------------------------------------
143{
144 std::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 std::stringstream verbose;
155 verbose << m_lessHitsCtr << " times the original GFTC had less hits than the converted" << std::endl;
156 verbose << m_moreHitsCtr << " times the converted GFTC had less hits than the original" << std::endl;
157 verbose << m_failedWrongSortingParam << " times the sorting parameters did not match" << std::endl;
158 verbose << m_failedWrongOrder << " times the hits were contained in the wrong order " << std::endl;
159 verbose << m_failedNotSameHits << " times there were hits in the converted GFTC that were not in the original" << std::endl;
160 verbose << m_failedNoRelationConv << " times there was no related converted GFTC to a SPTC" << std::endl;
161 verbose << m_failedNoRelationConv << " times there was no related original GFTC to a SPTC" << std::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" << std::endl;
164 B2DEBUG(20, verbose.str());
165 }
166}
167
168// ================================================ ANALYZE MISMATCH ==============================================================
169bool TCConvertersTestModule::analyzeMisMatch(const genfit::TrackCand* origTC, const genfit::TrackCand* convTC,
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(29, "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 std::vector<trackCandHit> origHits = getTrackCandHits(origTC);
189 std::vector<trackCandHit> convHits = getTrackCandHits(convTC);
190
191 std::array<bool, 4> foundHits = checkHits(origHits, convHits);
192 B2DEBUG(29, "Contents of foundHits: " << std::get<0>(foundHits) << " " << std::get<1>(foundHits) << \
193 " " << std::get<2>(foundHits) << " " << std::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
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(20, "The hits appear in the wrong order in the converted GFTC compared to the original GFTC!");
203 }
204 if (!foundHits[3]) { // sorting params not matching
205 B2WARNING("The sorting parameters are not matching!");
207 }
208 }
209
210 return true;
211}
212
213// ====================================================== GET TRACKCANDHITS =======================================================
214std::vector<TCConvertersTestModule::trackCandHit> TCConvertersTestModule::getTrackCandHits(const genfit::TrackCand* trackCand)
215{
216 std::vector<trackCandHit> tcHits;
217 for (size_t iHit = 0; iHit < trackCand->getNHits(); ++iHit) {
218 genfit::TrackCandHit* hit = trackCand->getHit(iHit);
219 tcHits.push_back(std::make_tuple(hit->getDetId(), hit->getHitId(), hit->getPlaneId(), hit->getSortingParameter()));
220 }
221 return tcHits;
222}
223
224// ================================================== CHECK HITS ===================================================================
225std::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 std::vector<trackCandHit>::const_iterator vectorIt; // typedef for avoiding auto below
230
231 int priorPos = -1; // first hit is 0 at least
232 B2DEBUG(29, "Checking if all hits of converted TC can be found in the original TC!");
233 std::stringstream allHitsOut;
234 for (const trackCandHit& hit : origHits) {
235 allHitsOut << std::get<0>(hit) << "\t" << std::get<1>(hit) << "\t" << std::get<2>(hit) << "\t" << std::get<3>(hit) << std::endl;
236 }
237 B2DEBUG(29, "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 std::stringstream hitOut;
243 hitOut << "Checking hit " << std::get<0>(hit) << " " << std::get<1>(hit) << " " << std::get<2>(hit) << " " << std::get<3>
244 (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:" << std::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 " << std::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!" << std::endl;
257 checkResults[3] = false;
258 }
259 if (foundNoPlaneIdIt == origHits.end()) {
260 hitOut << " the planeIDs are not matching!" << std::endl;
261 checkResults[2] = false;
262 }
263 } else {
264 hitOut << " hit is not contained in origHits!" << std::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 << std::endl;
271 }
272 B2DEBUG(29, hitOut.str());
273 B2DEBUG(29, "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(29, "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;
292 m_failedNoGFTC = 0;
293 m_failedNoSPTC = 0;
294 m_failedOther = 0;
300
301 m_lessHitsCtr = 0;
302 m_moreHitsCtr = 0;
304}
@ 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
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
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.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
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:96
std::vector< trackCandHit > getTrackCandHits(const genfit::TrackCand *trackCand)
get all TrackCandHits from a genfit::TrackCand (no such method in genfit)
int m_convertedTCCtr
counter for genfit::TrackCands which where obtained by converting from a SpacePointTrackCand
int m_failedNotSameHits
Counter for failed conversions for which the genfit::TrackCandidates do not contain the same TrackCan...
std::vector< std::string > m_genfitTCNames
Names of genfit::TrackCand Store Arrays.
void initialize() override
initialize: check if all required StoreArrays are present, initialize counters, etc.
unsigned int m_lessHitsCtr
Counter for cases where the original GFTC has less hits than the converted.
void event() override
event: event-wise jobs
int m_failedWrongOrder
Counter for failed conversions due to wrong ordering of TrackCandHits.
std::string m_PXDClusterName
Container name of PXDCluster.
void terminate() override
terminate: print some summary information
int m_failedNoRelationConv
Counter for failed Relation to converted genfit::TrackCand.
std::tuple< int, int, int, double > trackCandHit
typedef to imitate a genfit::TrackCandHit
int m_failedWrongSortingParam
Counter for failed conversions due to one or more differing sorting parameters.
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...
int m_SpacePointTCCtr
counter for presented SpacePointTrackCands
unsigned int m_differButOKCtr
Counter for differing GFTCs, where the difference can be assigned to a refereeStatus.
std::string m_SPTCName
Container name of SpacePointTrackCands.
int m_failedOther
Counter for failed conversions for which none of the other stated could be assigned.
int m_failedNoSPTC
counter for conversions where no SpacePointTrackCand was created (i.e.
std::string m_SVDClusterName
Container name of SVDCluster.
int m_failedNoGFTC
counter for conversions where no genfit::TrackCand was created from a SpacePointTrackCand (i....
int m_failedNoRelationOrig
Counter for failed Relation to original genfit::TrackCand.
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
int m_genfitTCCtr
counter for presented genfit::TrackCands
void initializeCounters()
initialize all counter variables to zero, to avoid indeterministic behaviour
unsigned int m_moreHitsCtr
Counter for cases where the original GFTC has more hits than the converted.
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.