32 collectionCloner(*this, conf,
true),
33 priorityName_(conf.getParameter<
std::
string>(
"trackAlgoPriorityOrder")),
34 m_foundHitBonus(conf.getParameter<double>(
"foundHitBonus")),
35 m_lostHitPenalty(conf.getParameter<double>(
"lostHitPenalty")),
36 m_shareFrac(conf.getParameter<double>(
"shareFrac")),
37 m_minShareHits(conf.getParameter<unsigned
int>(
"minShareHits")),
38 m_minQuality(
reco::TrackBase::qualityByName(conf.getParameter<
std::
string>(
"minQuality"))),
39 m_allowFirstHitShare(conf.getParameter<bool>(
"allowFirstHitShare"))
41 for (
auto const & it : conf.
getParameter<std::vector<edm::InputTag> >(
"trackProducers") )
43 for (
auto const & it : conf.
getParameter<std::vector<std::string> >(
"inputClassifiers")) {
44 srcMVAs.push_back(consumes<MVACollection>(
edm::InputTag(it,
"MVAValues")));
45 srcQuals.push_back(consumes<QualityMaskCollection>(
edm::InputTag(it,
"QualityMasks")));
48 assert(srcColls.size()==srcQuals.size());
51 produces<MVACollection>(
"MVAValues");
52 produces<QualityMaskCollection>(
"QualityMasks");
58 desc.
add<std::vector<edm::InputTag> >(
"trackProducers",std::vector<edm::InputTag>());
59 desc.add<std::vector<std::string> >(
"inputClassifiers",std::vector<std::string>());
60 desc.add<
std::string>(
"trackAlgoPriorityOrder",
"trackAlgoPriorityOrder");
61 desc.add<
double>(
"shareFrac",.19);
62 desc.add<
double>(
"foundHitBonus",10.);
63 desc.add<
double>(
"lostHitPenalty",5.);
64 desc.add<
unsigned int>(
"minShareHits",2);
65 desc.add<
bool>(
"allowFirstHitShare",
true);
68 descriptions.add(
"TrackCollectionMerger", desc);
75 std::vector<TrackCollectionCloner::Tokens> srcColls;
77 using MVACollection = std::vector<float>;
78 using QualityMaskCollection = std::vector<unsigned char>;
80 using IHit = std::pair<unsigned int, TrackingRecHit const *>;
81 using IHitV = std::vector<IHit>;
83 std::vector<edm::EDGetTokenT<MVACollection>> srcMVAs;
84 std::vector<edm::EDGetTokenT<QualityMaskCollection>> srcQuals;
88 float m_foundHitBonus;
89 float m_lostHitPenalty;
91 unsigned int m_minShareHits;
93 bool m_allowFirstHitShare;
98 bool areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const;
119 auto collsSize = srcColls.size();
122 for (
auto i=0
U;
i< collsSize; ++
i) {
123 trackColls[
i] = &srcColls[
i].tracks(evt);
124 rSize += (*trackColls[
i]).
size();
128 unsigned char qualMask = ~0;
138 for (
auto i=0
U;
i< collsSize; ++
i) {
139 auto const & tkColl = *trackColls[
i];
140 auto size = tkColl.size();
143 assert((*hmva).size()==
size);
146 for (
auto j=0
U; j<
size; ++j) {
147 if (! (qualMask&(* hqual)[j]) )
continue;
149 quals[
k] = (*hqual)[j];
157 std::vector<bool> selected(ntotTk,
true);
166 auto merger = [&]()->
void {
173 for (
auto i=0
U; i< collsSize; ++
i) {
174 auto const & tkColl = *trackColls[
i];
175 for (
auto j=0
U; j< nGoods[
i]; ++j) {
176 auto const &
track = tkColl[tkInds[
k]];
178 oriAlgo[
k] =
track.originalAlgo();
179 algoMask[
k] =
track.algoMask();
181 auto validHits=
track.numberOfValidHits();
182 auto validPixelHits=
track.hitPattern().numberOfValidPixelHits();
184 score[
k] = m_foundHitBonus*validPixelHits+m_foundHitBonus*validHits - m_lostHitPenalty*
lostHits -
track.chi2();
187 rhv.reserve(validHits) ;
188 auto compById = [](IHit
const & h1, IHit
const & h2) {
return h1.first < h2.first;};
189 for (
auto it =
track.recHitsBegin(); it !=
track.recHitsEnd(); ++it) {
190 auto const &
hit = *(*it);
191 auto id =
hit.rawId() ;
192 if(
hit.geographicalId().subdetId()>2)
id &= (~3);
193 if likely(
hit.isValid()) { rhv.emplace_back(
id,&
hit); std::push_heap(rhv.begin(),rhv.end(),compById); }
195 std::sort_heap(rhv.begin(),rhv.end(),compById);
203 auto seti = [&](
unsigned int ii,
unsigned int jj) {
207 algoMask[
ii] |= algoMask[
jj];
209 algoMask[
jj] = algoMask[
ii];
216 for (
auto i=0
U; i<collsSize-1; ++
i) {
217 auto iStart1=iStart2;
218 iStart2=iStart1+nGoods[
i];
219 for (
auto t1=iStart1; t1<iStart2; ++t1) {
220 if (!selected[t1])
continue;
221 auto score1 =
score[t1];
222 for (
auto t2=iStart2;
t2 <ntotTk; ++
t2) {
223 if (!selected[t1])
break;
224 if (!selected[
t2])
continue;
225 if (!areDuplicate(rh1[t1],rh1[t2]))
continue;
229 if ( score1 - score2 > almostSame ) {
231 }
else if ( score2 - score1 > almostSame ) {
235 if ( (quals[t1]&qmask) == (quals[
t2]&qmask) ) {
242 }
else if ( (quals[t1]&qmask) > (quals[t2]&qmask) )
254 if (collsSize>1) merger();
257 auto pmvas = std::make_unique<MVACollection>();
258 auto pquals = std::make_unique<QualityMaskCollection>();
264 for (
auto i=0
U; i<collsSize; ++
i) {
265 std::vector<unsigned int> selId;
266 std::vector<unsigned int> tid;
267 auto iStart1=iStart2;
268 iStart2=iStart1+nGoods[
i];
269 assert(
producer.selTracks_->size()==isel);
270 for (
auto t1=iStart1; t1<iStart2; ++t1) {
271 if (!selected[t1])
continue;
274 selId.push_back(tkInds[t1]);
275 pmvas->push_back(
mvas[t1]);
276 pquals->push_back(quals[t1]);
279 assert(
producer.selTracks_->size()==nsel);
280 assert(tid.size()==nsel-isel);
282 for (;isel<nsel;++isel) {
283 auto & otk = (*
producer.selTracks_)[isel];
284 otk.setQualityMask((*pquals)[isel]);
285 otk.setOriginalAlgorithm(oriAlgo[tid[k]]);
286 otk.setAlgoMask(algoMask[tid[k++]]);
288 assert(tid.size()==
k);
291 assert(
producer.selTracks_->size()==pmvas->size());
301 bool TrackCollectionMerger::areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const {
320 if (share( rh1[0].
second, rh2[0].second)) firstoverlap=1;
326 while (ih!=nh1 && jh!=nh2) {
330 auto const id1 = rh1[ih].first;
331 auto const id2 = rh2[jh].first;
333 else if (id2<id1) ++jh;
336 auto li=ih;
while( (++li)!=nh1 && id1 == rh1[li].first);
337 auto lj=jh;
while( (++lj)!=nh2 && id2 == rh2[lj].first);
338 for (
auto ii=ih; ii!=li; ++
ii)
339 for (
auto jj=jh; jj!=lj; ++
jj) {
340 if (share( rh1[ii].
second, rh2[jj].second)) noverlap++;
347 return noverlap >=
int(m_minShareHits) &&
348 (noverlap-firstoverlap) > (
std::min(nh1,nh2)-firstoverlap)*m_shareFrac;
T getParameter(std::string const &) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
#define initDynArray(T, n, x, i)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
TrackQuality
track quality
#define DEFINE_FWK_MODULE(type)
std::vector< Track > TrackCollection
collection of Tracks
virtual bool sharesInput(const TrackingRecHit *other, SharedInputType what) const
static void fill(edm::ParameterSetDescription &desc)
TrackAlgorithm
track algorithm
virtual void produce(StreamID, Event &, EventSetup const &) const =0
U second(std::pair< T, U > const &p)
auto const T2 &decltype(t1.eta()) t2
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
#define declareDynArray(T, n, x)