1 #include "trg/cdc/modules/mcmatcher/CDCTriggerRecoMatcherModule.h"
3 #include <cdc/dataobjects/CDCHit.h>
11 struct iter_pair_range : std::pair<Iter, Iter> {
12 iter_pair_range(std::pair<Iter, Iter>
const& x) : std::pair<Iter, Iter>(x) {}
13 Iter begin()
const {
return this->first;}
14 Iter end()
const {
return this->second;}
18 inline iter_pair_range<Iter> as_range(std::pair<Iter, Iter>
const& x)
20 return iter_pair_range<Iter>(x);
26 typedef float Efficiency;
40 setDescription(
"A module to match CDCTriggerTracks to RecoTracks.\n"
41 "First makes relations from RecoTracks to CDCTriggerSegmentHits, "
42 "then makes relations from RecoTracks to CDCTriggerTracks "
44 setPropertyFlags(c_ParallelProcessingCertified);
46 addParam(
"RecoTrackCollectionName", m_RecoTrackCollectionName,
47 "Name of the RecoTrack StoreArray to be matched.",
48 string(
"RecoTracks"));
49 addParam(
"TrgTrackCollectionName", m_TrgTrackCollectionName,
50 "Name of the CDCTriggerTrack StoreArray to be matched.",
51 string(
"TRGCDC2DFinderTracks"));
52 addParam(
"hitCollectionName", m_hitCollectionName,
53 "Name of the StoreArray of CDCTriggerSegmentHits used for the matching.",
55 addParam(
"axialOnly", m_axialOnly,
56 "Switch to ignore stereo hits (= 2D matching).",
58 addParam(
"minPurity", m_minPurity,
59 "Minimum purity for reconstructed tracks.",
61 addParam(
"minEfficiency", m_minEfficiency,
62 "Minimum efficiency for MC tracks.",
64 addParam(
"relateClonesAndMerged", m_relateClonesAndMerged,
65 "If true, create relations for clones and merged tracks "
66 "(will get negative weight).",
68 addParam(
"relateHitsByID", m_relateHitsByID,
69 "If true, compare ID of CDCTriggerSegmentHits and CDCHits "
70 "to create relations, otherwise use only existing relations.",
78 m_segmentHits.isRequired(m_hitCollectionName);
79 m_trgTracks.isRequired(m_TrgTrackCollectionName);
80 m_recoTracks.isRequired(m_RecoTrackCollectionName);
82 m_trgTracks.requireRelationTo(m_segmentHits);
83 m_recoTracks.registerRelationTo(m_segmentHits);
84 m_recoTracks.registerRelationTo(m_trgTracks);
85 m_trgTracks.registerRelationTo(m_recoTracks);
93 for (
int ireco = 0; ireco < m_recoTracks.getEntries(); ++ireco) {
94 RecoTrack* recoTrack = m_recoTracks[ireco];
100 for (
unsigned iHit = 0; iHit < cdcHits.size(); ++iHit) {
101 if (m_relateHitsByID) {
104 if (tsHit.getID() == cdcHits[iHit]->getID()) {
112 for (
unsigned iTS = 0; iTS < relHits.
size(); ++iTS) {
114 if (relHits.
weight(iTS) > 1)
124 B2DEBUG(100,
"########## start matching ############");
126 int nRecoTracks = m_recoTracks.getEntries();
127 int nTrgTracks = m_trgTracks.getEntries();
129 B2DEBUG(100,
"Number of trigger tracks is " << nTrgTracks);
130 B2DEBUG(100,
"Number of reco tracks is " << nRecoTracks);
132 if (not nRecoTracks or not nTrgTracks) {
140 std::multimap<HitId, TrackId> recoTrackId_by_hitId;
142 std::multimap<HitId, TrackId>::iterator itRecoInsertHit = recoTrackId_by_hitId.end();
143 TrackId recoTrackId = -1;
144 for (
const RecoTrack& recoTrack : m_recoTracks) {
148 for (
unsigned iHit = 0; iHit < relHits.
size(); ++iHit) {
149 const HitId hitId = relHits[iHit]->getArrayIndex();
150 itRecoInsertHit = recoTrackId_by_hitId.insert(itRecoInsertHit,
151 make_pair(hitId, recoTrackId));
152 B2DEBUG(250,
"hitId " << hitId <<
" in SL " << relHits[iHit]->getISuperLayer()
153 <<
", recoTrackId " << recoTrackId);
159 std::multimap<HitId, TrackId> trgTrackId_by_hitId;
161 std::multimap<HitId, TrackId>::iterator itTrgInsertHit = trgTrackId_by_hitId.end();
162 TrackId trgTrackId = -1;
167 for (
unsigned int iHit = 0; iHit < relHits.
size(); ++iHit) {
168 const HitId hitId = relHits[iHit]->getArrayIndex();
169 itTrgInsertHit = trgTrackId_by_hitId.insert(itTrgInsertHit,
170 make_pair(hitId, trgTrackId));
171 B2DEBUG(250,
"hitId " << hitId <<
" in SL " << relHits[iHit]->getISuperLayer()
172 <<
", trgTrackId " << trgTrackId);
181 Eigen::MatrixXi confusionMatrix = Eigen::MatrixXi::Zero(nTrgTracks, nRecoTracks);
185 Eigen::RowVectorXi totalHits_by_recoTrackId = Eigen::RowVectorXi::Zero(nRecoTracks);
186 Eigen::VectorXi totalHits_by_trgTrackId = Eigen::VectorXi::Zero(nTrgTracks);
189 for (HitId hitId = 0; hitId < m_segmentHits.getEntries(); ++hitId) {
191 if (m_axialOnly && m_segmentHits[hitId]->getISuperLayer() % 2)
continue;
194 auto range_trgTrackIds = trgTrackId_by_hitId.equal_range(hitId);
195 auto range_recoTrackIds = recoTrackId_by_hitId.equal_range(hitId);
198 for (
const pair<HitId, TrackId>& hitId_and_trgTrackId :
199 as_range(range_trgTrackIds)) {
200 TrackId trgTrackId = hitId_and_trgTrackId.second;
201 totalHits_by_trgTrackId(trgTrackId) += 1;
202 B2DEBUG(200,
" trgTrackId for total count: " << trgTrackId);
204 for (
const pair<HitId, TrackId>& hitId_and_recoTrackId :
205 as_range(range_recoTrackIds)) {
206 TrackId recoTrackId = hitId_and_recoTrackId.second;
207 totalHits_by_recoTrackId(recoTrackId) += 1;
208 B2DEBUG(200,
" recoTrackId for total count: " << recoTrackId);
212 for (
const pair<HitId, TrackId>& hitId_and_recoTrackId :
213 as_range(range_recoTrackIds)) {
214 for (
const pair<HitId, TrackId>& hitId_and_trgTrackId :
215 as_range(range_trgTrackIds)) {
216 TrackId recoTrackId = hitId_and_recoTrackId.second;
217 TrackId trgTrackId = hitId_and_trgTrackId.second;
218 confusionMatrix(trgTrackId, recoTrackId) += 1;
219 B2DEBUG(200,
" trgTrackId : " << trgTrackId <<
"; recoTrackId : " << recoTrackId);
224 B2DEBUG(200,
"Confusion matrix of the event : " << endl << confusionMatrix);
226 B2DEBUG(200,
"totalHits_by_trgTrackId : " << endl << totalHits_by_trgTrackId);
227 B2DEBUG(200,
"totalHits_by_recoTrackId : " << endl << totalHits_by_recoTrackId);
230 vector<pair<TrackId, Purity>> purestRecoTrackId_by_trgTrackId(nTrgTracks);
232 for (TrackId trgTrackId = 0; trgTrackId < nTrgTracks; ++trgTrackId) {
233 Eigen::RowVectorXi trgTrackRow = confusionMatrix.row(trgTrackId);
234 Eigen::RowVectorXi::Index purestRecoTrackId;
237 int highestHits = trgTrackRow.maxCoeff(&purestRecoTrackId);
238 int totalHits = totalHits_by_trgTrackId(trgTrackId);
240 Purity highestPurity = Purity(highestHits) / totalHits;
242 purestRecoTrackId_by_trgTrackId[trgTrackId] =
243 pair<TrackId, Purity>(purestRecoTrackId, highestPurity);
249 TrackId trgTrackId = -1;
250 B2DEBUG(200,
"TrgTrack to highest purity RecoTrack relation");
251 for (
const pair< TrackId, Purity>& purestRecoTrackId :
252 purestRecoTrackId_by_trgTrackId) {
254 const Purity& purity = purestRecoTrackId.second;
255 const TrackId& recoTrackId = purestRecoTrackId.first;
256 B2DEBUG(200,
"trgTrackId : " << trgTrackId <<
" -> recoTrackId : " << recoTrackId
257 <<
" with purity " << purity);
262 vector<pair<TrackId, Efficiency>> mostEfficientTrgTrackId_by_recoTrackId(nRecoTracks);
264 for (TrackId recoTrackId = 0; recoTrackId < nRecoTracks; ++recoTrackId) {
265 Eigen::VectorXi recoTrackCol = confusionMatrix.col(recoTrackId);
266 Eigen::VectorXi::Index highestHitsTrgTrackId;
269 int highestHits = recoTrackCol.maxCoeff(&highestHitsTrgTrackId);
270 int totalHits = totalHits_by_recoTrackId(recoTrackId);
272 Efficiency highestEfficiency = Efficiency(highestHits) / totalHits;
274 mostEfficientTrgTrackId_by_recoTrackId[recoTrackId] =
275 pair<TrackId, Efficiency> (highestHitsTrgTrackId, highestEfficiency);
281 TrackId recoTrackId = -1;
282 B2DEBUG(200,
"RecoTrack to highest efficiency TrgTrack relation");
283 for (
const pair<TrackId, Efficiency>& mostEfficientTrgTrackId :
284 mostEfficientTrgTrackId_by_recoTrackId) {
286 const Efficiency& efficiency = mostEfficientTrgTrackId.second;
287 const TrackId& trgTrackId = mostEfficientTrgTrackId.first;
288 B2DEBUG(200,
"recoTrackId : " << recoTrackId <<
" -> trgTrackId : " << trgTrackId
289 <<
" with efficiency " << efficiency);
294 for (TrackId trgTrackId = 0; trgTrackId < nTrgTracks; ++trgTrackId) {
297 const pair<TrackId, Purity>& purestRecoTrackId = purestRecoTrackId_by_trgTrackId[trgTrackId];
298 const TrackId& recoTrackId = purestRecoTrackId.first;
299 const Purity& purity = purestRecoTrackId.second;
301 if (!(purity >= m_minPurity)) {
303 B2DEBUG(100,
"Classified TrgTrack " << trgTrackId <<
" as ghost because of too low purity.");
307 RecoTrack* recoTrack = m_recoTracks[recoTrackId];
309 const pair<TrackId, Efficiency>& mostEfficientTrgTrackId =
310 mostEfficientTrgTrackId_by_recoTrackId[recoTrackId];
312 const TrackId& trgTrackIdCompare = mostEfficientTrgTrackId.first;
314 if (trgTrackId != trgTrackIdCompare) {
316 if (m_relateClonesAndMerged) {
318 trgTrack->addRelationTo(recoTrack, -purity);
320 B2DEBUG(100,
"Classified TrgTrack " << trgTrackId <<
" as clone -> recoTrackId "
321 << recoTrackId <<
" : " << -purity);
325 trgTrack->addRelationTo(recoTrack, purity);
326 B2DEBUG(100,
"Classified TrgTrack " << trgTrackId <<
" as match -> recoTrackId "
327 << recoTrackId <<
" : " << purity);
333 for (TrackId recoTrackId = 0; recoTrackId < nRecoTracks; ++recoTrackId) {
334 RecoTrack* recoTrack = m_recoTracks[recoTrackId];
336 const pair<TrackId, Efficiency>& mostEfficiencyTrgTrackId =
337 mostEfficientTrgTrackId_by_recoTrackId[recoTrackId];
338 const TrackId& trgTrackId = mostEfficiencyTrgTrackId.first;
339 const Efficiency& efficiency = mostEfficiencyTrgTrackId.second;
341 if (!(efficiency >= m_minEfficiency)) {
343 B2DEBUG(100,
"Classified RecoTrack " << recoTrackId <<
" as missing.");
349 const pair<TrackId, Purity>& purestRecoTrackId =
350 purestRecoTrackId_by_trgTrackId[trgTrackId];
351 const TrackId& recoTrackIdCompare = purestRecoTrackId.first;
353 if (recoTrackId != recoTrackIdCompare) {
355 if (m_relateClonesAndMerged) {
359 B2DEBUG(100,
"Classifid RecoTrack " << recoTrackId <<
" as merge -> trgTrackId "
360 << trgTrackId <<
" : " << -efficiency);
366 B2DEBUG(100,
"Classified RecoTrack " << recoTrackId <<
" as match -> trgTrackId "
367 << trgTrackId <<
" : " << efficiency);
372 B2DEBUG(100,
"########## end matching ############");