31 : collectionCloner(producesCollector(), conf,
true),
32 priorityName_(conf.getParameter<
std::
string>(
"trackAlgoPriorityOrder")),
33 m_foundHitBonus(conf.getParameter<double>(
"foundHitBonus")),
34 m_lostHitPenalty(conf.getParameter<double>(
"lostHitPenalty")),
35 m_shareFrac(conf.getParameter<double>(
"shareFrac")),
36 m_minShareHits(conf.getParameter<unsigned
int>(
"minShareHits")),
37 m_minQuality(
reco::TrackBase::qualityByName(conf.getParameter<
std::
string>(
"minQuality"))),
38 m_allowFirstHitShare(conf.getParameter<
bool>(
"allowFirstHitShare")),
39 m_enableMerging(conf.getParameter<
bool>(
"enableMerging")) {
40 for (
auto const& it : conf.
getParameter<std::vector<edm::InputTag>>(
"trackProducers"))
42 for (
auto const& it : conf.
getParameter<std::vector<std::string>>(
"inputClassifiers")) {
43 srcMVAs.push_back(consumes<MVACollection>(
edm::InputTag(it,
"MVAValues")));
44 srcQuals.push_back(consumes<QualityMaskCollection>(
edm::InputTag(it,
"QualityMasks")));
47 assert(srcColls.size() == srcQuals.size());
49 produces<MVACollection>(
"MVAValues");
50 produces<QualityMaskCollection>(
"QualityMasks");
55 desc.
add<std::vector<edm::InputTag>>(
"trackProducers", std::vector<edm::InputTag>());
56 desc.
add<std::vector<std::string>>(
"inputClassifiers", std::vector<std::string>());
57 desc.
add<
std::string>(
"trackAlgoPriorityOrder",
"trackAlgoPriorityOrder");
58 desc.
add<
double>(
"shareFrac", .19);
59 desc.add<
double>(
"foundHitBonus", 10.);
60 desc.add<
double>(
"lostHitPenalty", 5.);
61 desc.add<
unsigned int>(
"minShareHits", 2);
62 desc.add<
bool>(
"allowFirstHitShare",
true);
63 desc.add<
bool>(
"enableMerging",
true);
66 descriptions.add(
"TrackCollectionMerger", desc);
71 std::vector<TrackCollectionCloner::Tokens> srcColls;
73 using MVACollection = std::vector<float>;
74 using QualityMaskCollection = std::vector<unsigned char>;
76 using IHit = std::pair<unsigned int, TrackingRecHit const*>;
77 using IHitV = std::vector<IHit>;
79 std::vector<edm::EDGetTokenT<MVACollection>> srcMVAs;
80 std::vector<edm::EDGetTokenT<QualityMaskCollection>> srcQuals;
84 float m_foundHitBonus;
85 float m_lostHitPenalty;
87 unsigned int m_minShareHits;
89 bool m_allowFirstHitShare;
94 bool areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const;
111 auto collsSize = srcColls.size();
114 for (
auto i = 0
U;
i < collsSize; ++
i) {
115 trackColls[
i] = &srcColls[
i].tracks(evt);
116 rSize += (*trackColls[
i]).
size();
119 unsigned char qualMask = ~0;
122 qualMask = 1 << m_minQuality;
130 for (
auto i = 0
U;
i < collsSize; ++
i) {
131 auto const& tkColl = *trackColls[
i];
132 auto size = tkColl.size();
139 if (!(acceptAll || (qualMask & (*hqual)[
j])))
141 mvas[
k] = (*hmva)[
j];
142 quals[
k] = (*hqual)[
j];
150 std::vector<bool> selected(ntotTk,
true);
158 auto merger = [&]() ->
void {
165 for (
auto i = 0
U;
i < collsSize; ++
i) {
166 auto const& tkColl = *trackColls[
i];
167 for (
auto j = 0
U;
j < nGoods[
i]; ++
j) {
168 auto const&
track = tkColl[tkInds[
k]];
170 oriAlgo[
k] =
track.originalAlgo();
171 algoMask[
k] =
track.algoMask();
173 auto validHits =
track.numberOfValidHits();
174 auto validPixelHits =
track.hitPattern().numberOfValidPixelHits();
176 score[
k] = m_foundHitBonus * validPixelHits + m_foundHitBonus * validHits - m_lostHitPenalty *
lostHits -
180 rhv.reserve(validHits);
181 auto compById = [](IHit
const& h1, IHit
const& h2) {
return h1.first < h2.first; };
182 for (
auto it =
track.recHitsBegin(); it !=
track.recHitsEnd(); ++it) {
183 auto const&
hit = *(*it);
184 auto id =
hit.rawId();
187 rhv.emplace_back(
id, &
hit);
188 std::push_heap(rhv.begin(), rhv.end(), compById);
191 std::sort_heap(rhv.begin(), rhv.end(), compById);
198 auto seti = [&](
unsigned int ii,
unsigned int jj) {
199 selected[
jj] =
false;
202 oriAlgo[
ii] = oriAlgo[
jj];
203 algoMask[
ii] |= algoMask[
jj];
205 algoMask[
jj] = algoMask[
ii];
210 for (
auto i = 0
U;
i < collsSize - 1; ++
i) {
211 auto iStart1 = iStart2;
212 iStart2 = iStart1 + nGoods[
i];
213 for (
auto t1 = iStart1;
t1 < iStart2; ++
t1) {
217 for (
auto t2 = iStart2;
t2 < ntotTk; ++
t2) {
222 if (mom[
t1].Dot(mom[
t2]) < 0)
224 if (!areDuplicate(rh1[
t1], rh1[
t2]))
229 constexpr
float almostSame = 0.01f;
230 if (score1 - score2 > almostSame) {
232 }
else if (score2 - score1 > almostSame) {
235 constexpr
unsigned int qmask =
237 if ((quals[
t1] & qmask) == (quals[
t2] & qmask)) {
244 }
else if ((quals[
t1] & qmask) > (quals[
t2] & qmask))
255 const bool doMerging = m_enableMerging && collsSize > 1;
260 auto pmvas = std::make_unique<MVACollection>();
261 auto pquals = std::make_unique<QualityMaskCollection>();
267 for (
auto i = 0
U;
i < collsSize; ++
i) {
268 std::vector<unsigned int> selId;
269 std::vector<unsigned int> tid;
270 auto iStart1 = iStart2;
271 iStart2 = iStart1 + nGoods[
i];
273 for (
auto t1 = iStart1;
t1 < iStart2; ++
t1) {
278 selId.push_back(tkInds[
t1]);
279 pmvas->push_back(mvas[
t1]);
280 pquals->push_back(quals[
t1]);
284 assert(tid.size() == nsel - isel);
286 for (; isel < nsel; ++isel) {
287 auto& otk = (*
producer.selTracks_)[isel];
288 otk.setQualityMask((*pquals)[isel]);
290 otk.setOriginalAlgorithm(oriAlgo[tid[
k]]);
291 otk.setAlgoMask(algoMask[tid[
k++]]);
306 bool TrackCollectionMerger::areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const {
307 auto nh1 = rh1.size();
308 auto nh2 = rh2.size();
316 int firstoverlap = 0;
318 if (m_allowFirstHitShare && rh1[0].
first == rh2[0].
first) {
326 while (ih != nh1 && jh != nh2) {
327 auto const id1 = rh1[ih].first;
328 auto const id2 = rh2[jh].first;
341 return noverlap >=
int(m_minShareHits) &&
342 (noverlap - firstoverlap) > (
std::min(nh1, nh2) - firstoverlap) * m_shareFrac;