32 : collectionCloner(producesCollector(), conf,
true),
33 priorityName_(conf.getParameter<
std::
string>(
"trackAlgoPriorityOrder")),
35 m_foundHitBonus(conf.getParameter<double>(
"foundHitBonus")),
36 m_lostHitPenalty(conf.getParameter<double>(
"lostHitPenalty")),
37 m_shareFrac(conf.getParameter<double>(
"shareFrac")),
38 m_minShareHits(conf.getParameter<unsigned
int>(
"minShareHits")),
39 m_minQuality(
reco::TrackBase::qualityByName(conf.getParameter<
std::
string>(
"minQuality"))),
40 m_allowFirstHitShare(conf.getParameter<
bool>(
"allowFirstHitShare")),
41 m_enableMerging(conf.getParameter<
bool>(
"enableMerging")) {
42 for (
auto const& it : conf.
getParameter<std::vector<edm::InputTag>>(
"trackProducers"))
44 for (
auto const& it : conf.
getParameter<std::vector<std::string>>(
"inputClassifiers")) {
45 srcMVAs.push_back(consumes<MVACollection>(
edm::InputTag(it,
"MVAValues")));
46 srcQuals.push_back(consumes<QualityMaskCollection>(
edm::InputTag(it,
"QualityMasks")));
49 assert(srcColls.size() == srcQuals.size());
51 produces<MVACollection>(
"MVAValues");
52 produces<QualityMaskCollection>(
"QualityMasks");
57 desc.add<std::vector<edm::InputTag>>(
"trackProducers", std::vector<edm::InputTag>());
58 desc.add<std::vector<std::string>>(
"inputClassifiers", std::vector<std::string>());
59 desc.add<
std::string>(
"trackAlgoPriorityOrder",
"trackAlgoPriorityOrder");
60 desc.add<
double>(
"shareFrac", .19);
61 desc.add<
double>(
"foundHitBonus", 10.);
62 desc.add<
double>(
"lostHitPenalty", 5.);
63 desc.add<
unsigned int>(
"minShareHits", 2);
64 desc.add<
bool>(
"allowFirstHitShare",
true);
65 desc.add<
bool>(
"enableMerging",
true);
68 descriptions.add(
"TrackCollectionMerger",
desc);
73 std::vector<TrackCollectionCloner::Tokens> srcColls;
75 using MVACollection = std::vector<float>;
76 using QualityMaskCollection = std::vector<unsigned char>;
78 using IHit = std::pair<unsigned int, TrackingRecHit const*>;
79 using IHitV = std::vector<IHit>;
81 std::vector<edm::EDGetTokenT<MVACollection>> srcMVAs;
82 std::vector<edm::EDGetTokenT<QualityMaskCollection>> srcQuals;
87 float m_foundHitBonus;
88 float m_lostHitPenalty;
90 unsigned int m_minShareHits;
92 bool m_allowFirstHitShare;
97 bool areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const;
113 auto collsSize = srcColls.size();
116 for (
auto i = 0
U;
i < collsSize; ++
i) {
117 trackColls[
i] = &srcColls[
i].tracks(evt);
118 rSize += (*trackColls[
i]).
size();
121 unsigned char qualMask = ~0;
124 qualMask = 1 << m_minQuality;
132 for (
auto i = 0
U;
i < collsSize; ++
i) {
133 auto const& tkColl = *trackColls[
i];
134 auto size = tkColl.size();
141 if (!(acceptAll || (qualMask & (*hqual)[
j])))
143 mvas[
k] = (*hmva)[
j];
144 quals[
k] = (*hqual)[
j];
152 std::vector<bool> selected(ntotTk,
true);
160 auto merger = [&]() ->
void {
167 for (
auto i = 0
U;
i < collsSize; ++
i) {
168 auto const& tkColl = *trackColls[
i];
169 for (
auto j = 0
U;
j < nGoods[
i]; ++
j) {
170 auto const&
track = tkColl[tkInds[
k]];
172 oriAlgo[
k] =
track.originalAlgo();
173 algoMask[
k] =
track.algoMask();
175 auto validHits =
track.numberOfValidHits();
176 auto validPixelHits =
track.hitPattern().numberOfValidPixelHits();
178 score[
k] = m_foundHitBonus * validPixelHits + m_foundHitBonus * validHits - m_lostHitPenalty *
lostHits -
182 rhv.reserve(validHits);
183 auto compById = [](IHit
const& h1, IHit
const& h2) {
return h1.first < h2.first; };
184 for (
auto it =
track.recHitsBegin(); it !=
track.recHitsEnd(); ++it) {
185 auto const&
hit = *(*it);
186 auto id =
hit.rawId();
188 rhv.emplace_back(
id, &
hit);
189 std::push_heap(rhv.begin(), rhv.end(), compById);
192 std::sort_heap(rhv.begin(), rhv.end(), compById);
199 auto seti = [&](
unsigned int ii,
unsigned int jj) {
200 selected[
jj] =
false;
203 oriAlgo[
ii] = oriAlgo[
jj];
204 algoMask[
ii] |= algoMask[
jj];
206 algoMask[
jj] = algoMask[
ii];
211 for (
auto i = 0
U;
i < collsSize - 1; ++
i) {
212 auto iStart1 = iStart2;
213 iStart2 = iStart1 + nGoods[
i];
214 for (
auto t1 = iStart1;
t1 < iStart2; ++
t1) {
218 for (
auto t2 = iStart2;
t2 < ntotTk; ++
t2) {
223 if (mom[
t1].Dot(mom[
t2]) < 0)
225 if (!areDuplicate(rh1[
t1], rh1[
t2]))
230 constexpr
float almostSame = 0.01f;
231 if (score1 - score2 > almostSame) {
233 }
else if (score2 - score1 > almostSame) {
236 constexpr
unsigned int qmask =
238 if ((quals[
t1] & qmask) == (quals[
t2] & qmask)) {
245 }
else if ((quals[
t1] & qmask) > (quals[
t2] & qmask))
256 const bool doMerging = m_enableMerging && collsSize > 1;
261 auto pmvas = std::make_unique<MVACollection>();
262 auto pquals = std::make_unique<QualityMaskCollection>();
268 for (
auto i = 0
U;
i < collsSize; ++
i) {
269 std::vector<unsigned int> selId;
270 std::vector<unsigned int> tid;
271 auto iStart1 = iStart2;
272 iStart2 = iStart1 + nGoods[
i];
274 for (
auto t1 = iStart1;
t1 < iStart2; ++
t1) {
279 selId.push_back(tkInds[
t1]);
280 pmvas->push_back(mvas[
t1]);
281 pquals->push_back(quals[
t1]);
285 assert(tid.size() == nsel - isel);
287 for (; isel < nsel; ++isel) {
288 auto& otk = (*
producer.selTracks_)[isel];
289 otk.setQualityMask((*pquals)[isel]);
291 otk.setOriginalAlgorithm(oriAlgo[tid[
k]]);
292 otk.setAlgoMask(algoMask[tid[
k++]]);
307 bool TrackCollectionMerger::areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const {
308 auto nh1 = rh1.size();
309 auto nh2 = rh2.size();
317 int firstoverlap = 0;
319 if (m_allowFirstHitShare && rh1[0].
first == rh2[0].
first) {
327 while (ih != nh1 && jh != nh2) {
328 auto const id1 = rh1[ih].first;
329 auto const id2 = rh2[jh].first;
342 return noverlap >=
int(m_minShareHits) &&
343 (noverlap - firstoverlap) > (
std::min(nh1, nh2) - firstoverlap) * m_shareFrac;