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);
62 descriptions.add(
"TrackCollectionMerger", desc);
69 std::vector<TrackCollectionCloner::Tokens> srcColls;
71 using MVACollection = std::vector<float>;
72 using QualityMaskCollection = std::vector<unsigned char>;
74 using IHit = std::pair<unsigned int, TrackingRecHit const *>;
75 using IHitV = std::vector<IHit>;
77 std::vector<edm::EDGetTokenT<MVACollection>> srcMVAs;
78 std::vector<edm::EDGetTokenT<QualityMaskCollection>> srcQuals;
81 float m_foundHitBonus;
82 float m_lostHitPenalty;
84 unsigned int m_minShareHits;
86 bool m_allowFirstHitShare;
91 bool areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const;
108 auto collsSize = srcColls.size();
111 for (
auto i=0U;
i< collsSize; ++
i) {
112 trackColls[
i] = &srcColls[
i].tracks(evt);
113 rSize += (*trackColls[
i]).
size();
117 unsigned char qualMask = ~0;
127 for (
auto i=0U;
i< collsSize; ++
i) {
128 auto const & tkColl = *trackColls[
i];
129 auto size = tkColl.size();
136 if (! (qualMask&(* hqual)[
j]) )
continue;
138 quals[
k] = (*hqual)[
j];
146 std::vector<bool> selected(ntotTk,
true);
155 auto merger = [&]()->
void {
162 for (
auto i=0U; i< collsSize; ++
i) {
163 auto const & tkColl = *trackColls[
i];
164 for (
auto j=0U;
j< nGoods[
i]; ++
j) {
165 auto const & track = tkColl[tkInds[
k]];
166 algo[
k] = track.algo();
167 oriAlgo[
k] = track.originalAlgo();
168 algoMask[
k] = track.algoMask();
170 auto validHits=track.numberOfValidHits();
171 auto validPixelHits=track.hitPattern().numberOfValidPixelHits();
172 auto lostHits=track.numberOfLostHits();
173 score[
k] = m_foundHitBonus*validPixelHits+m_foundHitBonus*validHits - m_lostHitPenalty*lostHits - track.chi2();
176 rhv.reserve(validHits) ;
177 auto compById = [](IHit
const & h1, IHit
const & h2) {
return h1.first < h2.first;};
178 for (
auto it = track.recHitsBegin(); it != track.recHitsEnd(); ++it) {
179 auto const &
hit = *(*it);
180 auto id =
hit.rawId() ;
181 if(
hit.geographicalId().subdetId()>2)
id &= (~3);
182 if likely(
hit.isValid()) { rhv.emplace_back(
id,&
hit); std::push_heap(rhv.begin(),rhv.end(),compById); }
184 std::sort_heap(rhv.begin(),rhv.end(),compById);
192 auto seti = [&](
unsigned int ii,
unsigned int jj) {
196 algoMask[
ii] |= algoMask[
jj];
198 algoMask[
jj] = algoMask[
ii];
205 for (
auto i=0U; i<collsSize-1; ++
i) {
206 auto iStart1=iStart2;
207 iStart2=iStart1+nGoods[
i];
208 for (
auto t1=iStart1; t1<iStart2; ++t1) {
209 if (!selected[t1])
continue;
210 auto score1 = score[t1];
211 for (
auto t2=iStart2;
t2 <ntotTk; ++
t2) {
212 if (!selected[t1])
break;
213 if (!selected[
t2])
continue;
214 if (!areDuplicate(rh1[t1],rh1[t2]))
continue;
215 auto score2 = score[
t2];
218 if ( score1 - score2 > almostSame ) {
220 }
else if ( score2 - score1 > almostSame ) {
224 if ( (quals[t1]&qmask) == (quals[
t2]&qmask) ) {
231 }
else if ( (quals[t1]&qmask) > (quals[t2]&qmask) )
243 if (collsSize>1) merger();
246 auto pmvas = std::make_unique<MVACollection>();
247 auto pquals = std::make_unique<QualityMaskCollection>();
253 for (
auto i=0U; i<collsSize; ++
i) {
254 std::vector<unsigned int> selId;
255 std::vector<unsigned int> tid;
256 auto iStart1=iStart2;
257 iStart2=iStart1+nGoods[
i];
259 for (
auto t1=iStart1; t1<iStart2; ++t1) {
260 if (!selected[t1])
continue;
263 selId.push_back(tkInds[t1]);
264 pmvas->push_back(mvas[t1]);
265 pquals->push_back(quals[t1]);
269 assert(tid.size()==nsel-isel);
271 for (;isel<nsel;++isel) {
272 auto & otk = (*
producer.selTracks_)[isel];
273 otk.setQualityMask((*pquals)[isel]);
274 otk.setOriginalAlgorithm(oriAlgo[tid[k]]);
275 otk.setAlgoMask(algoMask[tid[k++]]);
290 bool TrackCollectionMerger::areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const {
309 if (share( rh1[0].
second, rh2[0].second)) firstoverlap=1;
315 while (ih!=nh1 && jh!=nh2) {
319 auto const id1 = rh1[ih].first;
320 auto const id2 = rh2[jh].first;
322 else if (id2<id1) ++jh;
325 auto li=ih;
while( (++li)!=nh1 && id1 == rh1[li].first);
326 auto lj=jh;
while( (++lj)!=nh2 && id2 == rh2[lj].first);
327 for (
auto ii=ih; ii!=li; ++
ii)
328 for (
auto jj=jh;
jj!=lj; ++
jj) {
329 if (share( rh1[ii].
second, rh2[
jj].second)) noverlap++;
336 return noverlap >= int(m_minShareHits) &&
337 (noverlap-firstoverlap) > (
std::min(nh1,nh2)-firstoverlap)*m_shareFrac;
T getParameter(std::string const &) const
#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
TrackAlgorithm
track algorithm
U second(std::pair< T, U > const &p)
auto const T2 &decltype(t1.eta()) t2
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
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
virtual void produce(StreamID, Event &, EventSetup const &) const =0
#define declareDynArray(T, n, x)
tuple size
Write out results.