29 collectionCloner(*this, conf,
true),
30 m_foundHitBonus(conf.getParameter<double>(
"foundHitBonus")),
31 m_lostHitPenalty(conf.getParameter<double>(
"lostHitPenalty")),
32 m_shareFrac(conf.getParameter<double>(
"shareFrac")),
33 m_minShareHits(conf.getParameter<unsigned
int>(
"minShareHits")),
34 m_minQuality(
reco::TrackBase::qualityByName(conf.getParameter<
std::
string>(
"minQuality"))),
35 m_allowFirstHitShare(conf.getParameter<bool>(
"allowFirstHitShare"))
37 for (
auto const & it : conf.
getParameter<std::vector<edm::InputTag> >(
"trackProducers") )
39 for (
auto const & it : conf.
getParameter<std::vector<std::string> >(
"inputClassifiers")) {
40 srcMVAs.push_back(consumes<MVACollection>(
edm::InputTag(it,
"MVAValues")));
41 srcQuals.push_back(consumes<QualityMaskCollection>(
edm::InputTag(it,
"QualityMasks")));
44 assert(srcColls.size()==srcQuals.size());
47 produces<MVACollection>(
"MVAValues");
48 produces<QualityMaskCollection>(
"QualityMasks");
54 desc.
add<std::vector<edm::InputTag> >(
"trackProducers",std::vector<edm::InputTag>());
55 desc.add<std::vector<std::string> >(
"inputClassifiers",std::vector<std::string>());
56 desc.add<
double>(
"shareFrac",.19);
57 desc.add<
double>(
"foundHitBonus",10.);
58 desc.add<
double>(
"lostHitPenalty",5.);
59 desc.add<
unsigned int>(
"minShareHits",2);
60 desc.add<
bool>(
"allowFirstHitShare",
true);
63 descriptions.add(
"TrackCollectionMerger", desc);
70 std::vector<TrackCollectionCloner::Tokens> srcColls;
72 using MVACollection = std::vector<float>;
73 using QualityMaskCollection = std::vector<unsigned char>;
75 using IHit = std::pair<unsigned int, TrackingRecHit const *>;
76 using IHitV = std::vector<IHit>;
78 std::vector<edm::EDGetTokenT<MVACollection>> srcMVAs;
79 std::vector<edm::EDGetTokenT<QualityMaskCollection>> srcQuals;
82 float m_foundHitBonus;
83 float m_lostHitPenalty;
85 unsigned int m_minShareHits;
87 bool m_allowFirstHitShare;
92 bool areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const;
109 auto collsSize = srcColls.size();
112 for (
auto i=0
U;
i< collsSize; ++
i) {
113 trackColls[
i] = &srcColls[
i].tracks(evt);
114 rSize += (*trackColls[
i]).
size();
118 unsigned char qualMask = ~0;
128 for (
auto i=0
U;
i< collsSize; ++
i) {
129 auto const & tkColl = *trackColls[
i];
130 auto size = tkColl.size();
133 assert((*hmva).size()==
size);
137 if (! (qualMask&(* hqual)[
j]) )
continue;
139 quals[
k] = (*hqual)[
j];
147 std::vector<bool> selected(ntotTk,
true);
156 auto merger = [&]()->
void {
163 for (
auto i=0
U; i< collsSize; ++
i) {
164 auto const & tkColl = *trackColls[
i];
165 for (
auto j=0
U;
j< nGoods[
i]; ++
j) {
166 auto const &
track = tkColl[tkInds[
k]];
168 oriAlgo[
k] =
track.originalAlgo();
169 algoMask[
k] =
track.algoMask();
171 auto validHits=
track.numberOfValidHits();
172 auto validPixelHits=
track.hitPattern().numberOfValidPixelHits();
174 score[
k] = m_foundHitBonus*validPixelHits+m_foundHitBonus*validHits - m_lostHitPenalty*
lostHits -
track.chi2();
177 rhv.reserve(validHits) ;
178 auto compById = [](IHit
const & h1, IHit
const & h2) {
return h1.first < h2.first;};
179 for (
auto it =
track.recHitsBegin(); it !=
track.recHitsEnd(); ++it) {
180 auto const &
hit = *(*it);
181 auto id =
hit.rawId() ;
182 if(
hit.geographicalId().subdetId()>2)
id &= (~3);
183 if likely(
hit.isValid()) { rhv.emplace_back(
id,&
hit); std::push_heap(rhv.begin(),rhv.end(),compById); }
185 std::sort_heap(rhv.begin(),rhv.end(),compById);
193 auto seti = [&](
unsigned int ii,
unsigned int jj) {
197 algoMask[
ii] |= algoMask[
jj];
199 algoMask[
jj] = algoMask[
ii];
206 for (
auto i=0
U; i<collsSize-1; ++
i) {
207 auto iStart1=iStart2;
208 iStart2=iStart1+nGoods[
i];
209 for (
auto t1=iStart1; t1<iStart2; ++t1) {
210 if (!selected[t1])
continue;
211 auto score1 =
score[t1];
212 for (
auto t2=iStart2;
t2 <ntotTk; ++
t2) {
213 if (!selected[t1])
break;
214 if (!selected[
t2])
continue;
215 if (!areDuplicate(rh1[t1],rh1[t2]))
continue;
219 if ( score1 - score2 > almostSame ) {
221 }
else if ( score2 - score1 > almostSame ) {
225 if ( (quals[t1]&qmask) == (quals[
t2]&qmask) ) {
232 }
else if ( (quals[t1]&qmask) > (quals[t2]&qmask) )
244 if (collsSize>1) merger();
247 auto pmvas = std::make_unique<MVACollection>();
248 auto pquals = std::make_unique<QualityMaskCollection>();
254 for (
auto i=0
U; i<collsSize; ++
i) {
255 std::vector<unsigned int> selId;
256 std::vector<unsigned int> tid;
257 auto iStart1=iStart2;
258 iStart2=iStart1+nGoods[
i];
259 assert(
producer.selTracks_->size()==isel);
260 for (
auto t1=iStart1; t1<iStart2; ++t1) {
261 if (!selected[t1])
continue;
264 selId.push_back(tkInds[t1]);
265 pmvas->push_back(
mvas[t1]);
266 pquals->push_back(quals[t1]);
269 assert(
producer.selTracks_->size()==nsel);
270 assert(tid.size()==nsel-isel);
272 for (;isel<nsel;++isel) {
273 auto & otk = (*
producer.selTracks_)[isel];
274 otk.setQualityMask((*pquals)[isel]);
275 otk.setOriginalAlgorithm(oriAlgo[tid[k]]);
276 otk.setAlgoMask(algoMask[tid[k++]]);
278 assert(tid.size()==
k);
281 assert(
producer.selTracks_->size()==pmvas->size());
291 bool TrackCollectionMerger::areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const {
310 if (share( rh1[0].
second, rh2[0].second)) firstoverlap=1;
316 while (ih!=nh1 && jh!=nh2) {
320 auto const id1 = rh1[ih].first;
321 auto const id2 = rh2[jh].first;
323 else if (id2<id1) ++jh;
326 auto li=ih;
while( (++li)!=nh1 && id1 == rh1[li].first);
327 auto lj=jh;
while( (++lj)!=nh2 && id2 == rh2[lj].first);
328 for (
auto ii=ih; ii!=li; ++
ii)
329 for (
auto jj=jh;
jj!=lj; ++
jj) {
330 if (share( rh1[ii].
second, rh2[
jj].second)) noverlap++;
337 return noverlap >=
int(m_minShareHits) &&
338 (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
#define declareDynArray(T, n, x)