8#include "trg/cdc/modules/mcmatcher/CDCTriggerRecoMatcherModule.h"
10#include <cdc/dataobjects/CDCHit.h>
18 struct iter_pair_range : std::pair<Iter, Iter> {
19 explicit iter_pair_range(std::pair<Iter, Iter>
const& x) :
std::pair<Iter, Iter>(x) {}
20 Iter begin()
const {
return this->first;}
21 Iter end()
const {
return this->second;}
25 inline iter_pair_range<Iter> as_range(std::pair<Iter, Iter>
const& x)
27 return iter_pair_range<Iter>(x);
33 typedef float Efficiency;
47 setDescription(
"A module to match CDCTriggerTracks to RecoTracks.\n"
48 "First makes relations from RecoTracks to CDCTriggerSegmentHits, "
49 "then makes relations from RecoTracks to CDCTriggerTracks "
54 "Name of the RecoTrack StoreArray to be matched.",
55 string(
"RecoTracks"));
57 "Name of the CDCTriggerTrack StoreArray to be matched.",
58 string(
"TRGCDC2DFinderTracks"));
60 "Name of the StoreArray of CDCTriggerSegmentHits used for the matching.",
63 "Switch to ignore stereo hits (= 2D matching).",
66 "Minimum purity for reconstructed tracks.",
69 "Minimum efficiency for MC tracks.",
72 "If true, create relations for clones and merged tracks "
73 "(will get negative weight).",
76 "If true, compare ID of CDCTriggerSegmentHits and CDCHits "
77 "to create relations, otherwise use only existing relations.",
107 for (
unsigned iHit = 0; iHit < cdcHits.size(); ++iHit) {
111 if (tsHit.getID() == cdcHits[iHit]->getID()) {
119 for (
unsigned iTS = 0; iTS < relHits.
size(); ++iTS) {
121 if (relHits.
weight(iTS) > 1)
131 B2DEBUG(100,
"########## start matching ############");
136 B2DEBUG(100,
"Number of trigger tracks is " << nTrgTracks);
137 B2DEBUG(100,
"Number of reco tracks is " << nRecoTracks);
139 if (not nRecoTracks or not nTrgTracks) {
147 std::multimap<HitId, TrackId> recoTrackId_by_hitId;
149 std::multimap<HitId, TrackId>::iterator itRecoInsertHit = recoTrackId_by_hitId.end();
150 TrackId recoTrackId = -1;
155 for (
unsigned iHit = 0; iHit < relHits.
size(); ++iHit) {
156 const HitId hitId = relHits[iHit]->getArrayIndex();
157 itRecoInsertHit = recoTrackId_by_hitId.insert(itRecoInsertHit,
158 make_pair(hitId, recoTrackId));
159 B2DEBUG(250,
"hitId " << hitId <<
" in SL " << relHits[iHit]->getISuperLayer()
160 <<
", recoTrackId " << recoTrackId);
166 std::multimap<HitId, TrackId> trgTrackId_by_hitId;
168 std::multimap<HitId, TrackId>::iterator itTrgInsertHit = trgTrackId_by_hitId.end();
169 TrackId trgTrackId = -1;
174 for (
unsigned int iHit = 0; iHit < relHits.
size(); ++iHit) {
175 const HitId hitId = relHits[iHit]->getArrayIndex();
176 itTrgInsertHit = trgTrackId_by_hitId.insert(itTrgInsertHit,
177 make_pair(hitId, trgTrackId));
178 B2DEBUG(250,
"hitId " << hitId <<
" in SL " << relHits[iHit]->getISuperLayer()
179 <<
", trgTrackId " << trgTrackId);
188 Eigen::MatrixXi confusionMatrix = Eigen::MatrixXi::Zero(nTrgTracks, nRecoTracks);
192 Eigen::RowVectorXi totalHits_by_recoTrackId = Eigen::RowVectorXi::Zero(nRecoTracks);
193 Eigen::VectorXi totalHits_by_trgTrackId = Eigen::VectorXi::Zero(nTrgTracks);
201 auto range_trgTrackIds = trgTrackId_by_hitId.equal_range(hitId);
202 auto range_recoTrackIds = recoTrackId_by_hitId.equal_range(hitId);
205 for (
const pair<HitId, TrackId> hitId_and_trgTrackId :
206 as_range(range_trgTrackIds)) {
207 TrackId trgTrackId = hitId_and_trgTrackId.second;
208 totalHits_by_trgTrackId(trgTrackId) += 1;
209 B2DEBUG(200,
" trgTrackId for total count: " << trgTrackId);
211 for (
const pair<HitId, TrackId> hitId_and_recoTrackId :
212 as_range(range_recoTrackIds)) {
213 TrackId recoTrackId = hitId_and_recoTrackId.second;
214 totalHits_by_recoTrackId(recoTrackId) += 1;
215 B2DEBUG(200,
" recoTrackId for total count: " << recoTrackId);
219 for (
const pair<HitId, TrackId> hitId_and_recoTrackId :
220 as_range(range_recoTrackIds)) {
221 for (
const pair<HitId, TrackId> hitId_and_trgTrackId :
222 as_range(range_trgTrackIds)) {
223 TrackId recoTrackId = hitId_and_recoTrackId.second;
224 TrackId trgTrackId = hitId_and_trgTrackId.second;
225 confusionMatrix(trgTrackId, recoTrackId) += 1;
226 B2DEBUG(200,
" trgTrackId : " << trgTrackId <<
"; recoTrackId : " << recoTrackId);
231 B2DEBUG(200,
"Confusion matrix of the event : " << endl << confusionMatrix);
233 B2DEBUG(200,
"totalHits_by_trgTrackId : " << endl << totalHits_by_trgTrackId);
234 B2DEBUG(200,
"totalHits_by_recoTrackId : " << endl << totalHits_by_recoTrackId);
237 vector<pair<TrackId, Purity>> purestRecoTrackId_by_trgTrackId(nTrgTracks);
239 for (TrackId trgTrackId = 0; trgTrackId < nTrgTracks; ++trgTrackId) {
240 Eigen::RowVectorXi trgTrackRow = confusionMatrix.row(trgTrackId);
241 Eigen::RowVectorXi::Index purestRecoTrackId;
244 int highestHits = trgTrackRow.maxCoeff(&purestRecoTrackId);
245 int totalHits = totalHits_by_trgTrackId(trgTrackId);
247 Purity highestPurity = Purity(highestHits) / totalHits;
249 purestRecoTrackId_by_trgTrackId[trgTrackId] =
250 pair<TrackId, Purity>(purestRecoTrackId, highestPurity);
256 TrackId trgTrackId = -1;
257 B2DEBUG(200,
"TrgTrack to highest purity RecoTrack relation");
258 for (
const pair< TrackId, Purity>& purestRecoTrackId :
259 purestRecoTrackId_by_trgTrackId) {
261 const Purity& purity = purestRecoTrackId.second;
262 const TrackId& recoTrackId = purestRecoTrackId.first;
263 B2DEBUG(200,
"trgTrackId : " << trgTrackId <<
" -> recoTrackId : " << recoTrackId
264 <<
" with purity " << purity);
269 vector<pair<TrackId, Efficiency>> mostEfficientTrgTrackId_by_recoTrackId(nRecoTracks);
271 for (TrackId recoTrackId = 0; recoTrackId < nRecoTracks; ++recoTrackId) {
272 Eigen::VectorXi recoTrackCol = confusionMatrix.col(recoTrackId);
273 Eigen::VectorXi::Index highestHitsTrgTrackId;
276 int highestHits = recoTrackCol.maxCoeff(&highestHitsTrgTrackId);
277 int totalHits = totalHits_by_recoTrackId(recoTrackId);
279 Efficiency highestEfficiency = Efficiency(highestHits) / totalHits;
281 mostEfficientTrgTrackId_by_recoTrackId[recoTrackId] =
282 pair<TrackId, Efficiency> (highestHitsTrgTrackId, highestEfficiency);
288 TrackId recoTrackId = -1;
289 B2DEBUG(200,
"RecoTrack to highest efficiency TrgTrack relation");
290 for (
const pair<TrackId, Efficiency>& mostEfficientTrgTrackId :
291 mostEfficientTrgTrackId_by_recoTrackId) {
293 const Efficiency& efficiency = mostEfficientTrgTrackId.second;
294 const TrackId& trgTrackId = mostEfficientTrgTrackId.first;
295 B2DEBUG(200,
"recoTrackId : " << recoTrackId <<
" -> trgTrackId : " << trgTrackId
296 <<
" with efficiency " << efficiency);
301 for (TrackId trgTrackId = 0; trgTrackId < nTrgTracks; ++trgTrackId) {
304 const pair<TrackId, Purity>& purestRecoTrackId = purestRecoTrackId_by_trgTrackId[trgTrackId];
305 const TrackId& recoTrackId = purestRecoTrackId.first;
306 const Purity& purity = purestRecoTrackId.second;
310 B2DEBUG(100,
"Classified TrgTrack " << trgTrackId <<
" as ghost because of too low purity.");
316 const pair<TrackId, Efficiency>& mostEfficientTrgTrackId =
317 mostEfficientTrgTrackId_by_recoTrackId[recoTrackId];
319 const TrackId& trgTrackIdCompare = mostEfficientTrgTrackId.first;
321 if (trgTrackId != trgTrackIdCompare) {
325 trgTrack->addRelationTo(recoTrack, -purity);
327 B2DEBUG(100,
"Classified TrgTrack " << trgTrackId <<
" as clone -> recoTrackId "
328 << recoTrackId <<
" : " << -purity);
332 trgTrack->addRelationTo(recoTrack, purity);
333 B2DEBUG(100,
"Classified TrgTrack " << trgTrackId <<
" as match -> recoTrackId "
334 << recoTrackId <<
" : " << purity);
340 for (TrackId recoTrackId = 0; recoTrackId < nRecoTracks; ++recoTrackId) {
343 const pair<TrackId, Efficiency>& mostEfficiencyTrgTrackId =
344 mostEfficientTrgTrackId_by_recoTrackId[recoTrackId];
345 const TrackId& trgTrackId = mostEfficiencyTrgTrackId.first;
346 const Efficiency& efficiency = mostEfficiencyTrgTrackId.second;
350 B2DEBUG(100,
"Classified RecoTrack " << recoTrackId <<
" as missing.");
356 const pair<TrackId, Purity>& purestRecoTrackId =
357 purestRecoTrackId_by_trgTrackId[trgTrackId];
358 const TrackId& recoTrackIdCompare = purestRecoTrackId.first;
360 if (recoTrackId != recoTrackIdCompare) {
366 B2DEBUG(100,
"Classifid RecoTrack " << recoTrackId <<
" as merge -> trgTrackId "
367 << trgTrackId <<
" : " << -efficiency);
373 B2DEBUG(100,
"Classified RecoTrack " << recoTrackId <<
" as match -> trgTrackId "
374 << trgTrackId <<
" : " << efficiency);
379 B2DEBUG(100,
"########## end matching ############");
bool m_relateHitsByID
switch for creating hit relations based on wire ID
virtual void initialize() override
Initialize the module.
std::string m_RecoTrackCollectionName
Name of the RecoTrack StoreArray to be matched.
virtual void event() override
Called once for each event.
StoreArray< CDCTriggerSegmentHit > m_segmentHits
list of hits that are used for the matching
double m_minPurity
minimum purity
bool m_axialOnly
switch for 2D matching
std::string m_TrgTrackCollectionName
Name of the CDCTriggerTrack Store Array to be matched.
StoreArray< CDCTriggerTrack > m_trgTracks
list of CDCTriggerTracks to be matched
double m_minEfficiency
minimum efficiency
CDCTriggerRecoMatcherModule()
Constructor, for setting module description and parameters.
StoreArray< RecoTrack > m_recoTracks
list of RecoTracks to be matched
std::string m_hitCollectionName
Name of the StoreArray containing the hits that are used for the matching.
bool m_relateClonesAndMerged
switch for creating relations for clones and merged tracks
Combination of several CDCHits to a track segment hit for the trigger.
Track created by the CDC trigger.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
This is the Reconstruction Event-Data Model Track.
std::vector< Belle2::RecoTrack::UsedCDCHit * > getCDCHitList() const
Return an unsorted list of cdc hits.
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
float weight(int index) const
Get weight with index.
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).
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool requireRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, const std::string &namedRelation="") const
Produce error if no relation from this array to 'toArray' has been registered.
int getEntries() const
Get the number of objects in the array.
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.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.