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();
135 assert((*hmva).size() ==
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]))
230 if (score1 - score2 > almostSame) {
232 }
else if (score2 - score1 > almostSame) {
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];
272 assert(
producer.selTracks_->size() == isel);
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]);
283 assert(
producer.selTracks_->size() == nsel);
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++]]);
295 assert(tid.size() ==
k);
298 assert(
producer.selTracks_->size() == pmvas->size());
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) {
319 if (share(rh1[0].
second, rh2[0].second))
326 while (ih != nh1 && jh != nh2) {
327 auto const id1 = rh1[ih].first;
328 auto const id2 = rh2[jh].first;
334 if (share(rh1[ih].
second, rh2[jh].second))
341 return noverlap >=
int(m_minShareHits) &&
342 (noverlap - firstoverlap) > (
std::min(nh1, nh2) - firstoverlap) * m_shareFrac;
#define declareDynArray(T, n, x)
T getParameter(std::string const &) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
bool getByToken(EDGetToken token, Handle< PROD > &result) const
TrackQuality
track quality
std::vector< Track > TrackCollection
collection of Tracks
virtual bool sharesInput(const TrackingRecHit *other, SharedInputType what) const
static void fill(edm::ParameterSetDescription &desc)
#define initDynArray(T, n, x, i)
TrackAlgorithm
track algorithm
virtual void produce(StreamID, Event &, EventSetup const &) const =0
U second(std::pair< T, U > const &p)
#define DEFINE_FWK_MODULE(type)
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
ParameterDescriptionBase * add(U const &iLabel, T const &value)
static void fillDescriptions(ConfigurationDescriptions &descriptions)
std::bitset< algoSize > AlgoMask
algo mask
std::array< unsigned int, reco::TrackBase::algoSize > trackAlgoPriorityOrder
math::XYZVector Vector
spatial vector