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")),
40 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());
52 produces<MVACollection>(
"MVAValues");
53 produces<QualityMaskCollection>(
"QualityMasks");
59 desc.
add<std::vector<edm::InputTag> >(
"trackProducers",std::vector<edm::InputTag>());
60 desc.add<std::vector<std::string> >(
"inputClassifiers",std::vector<std::string>());
61 desc.add<
std::string>(
"trackAlgoPriorityOrder",
"trackAlgoPriorityOrder");
62 desc.add<
double>(
"shareFrac",.19);
63 desc.add<
double>(
"foundHitBonus",10.);
64 desc.add<
double>(
"lostHitPenalty",5.);
65 desc.add<
unsigned int>(
"minShareHits",2);
66 desc.add<
bool>(
"allowFirstHitShare",
true);
67 desc.add<
bool>(
"enableMerging",
true);
70 descriptions.add(
"TrackCollectionMerger", desc);
77 std::vector<TrackCollectionCloner::Tokens> srcColls;
79 using MVACollection = std::vector<float>;
80 using QualityMaskCollection = std::vector<unsigned char>;
82 using IHit = std::pair<unsigned int, TrackingRecHit const *>;
83 using IHitV = std::vector<IHit>;
85 std::vector<edm::EDGetTokenT<MVACollection>> srcMVAs;
86 std::vector<edm::EDGetTokenT<QualityMaskCollection>> srcQuals;
90 float m_foundHitBonus;
91 float m_lostHitPenalty;
93 unsigned int m_minShareHits;
95 bool m_allowFirstHitShare;
101 bool areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const;
122 auto collsSize = srcColls.size();
125 for (
auto i=0
U;
i< collsSize; ++
i) {
126 trackColls[
i] = &srcColls[
i].tracks(evt);
127 rSize += (*trackColls[
i]).
size();
131 unsigned char qualMask = ~0;
133 if (!acceptAll) qualMask = 1<<m_minQuality;
142 for (
auto i=0
U;
i< collsSize; ++
i) {
143 auto const & tkColl = *trackColls[
i];
144 auto size = tkColl.size();
147 assert((*hmva).size()==
size);
150 for (
auto j=0
U; j<
size; ++j) {
151 if (! (acceptAll || (qualMask&(* hqual)[j]) ) )
continue;
153 quals[
k] = (*hqual)[j];
161 std::vector<bool> selected(ntotTk,
true);
170 auto merger = [&]()->
void {
178 for (
auto i=0
U; i< collsSize; ++
i) {
179 auto const & tkColl = *trackColls[
i];
180 for (
auto j=0
U; j< nGoods[
i]; ++j) {
181 auto const &
track = tkColl[tkInds[
k]];
183 oriAlgo[
k] =
track.originalAlgo();
184 algoMask[
k] =
track.algoMask();
186 auto validHits=
track.numberOfValidHits();
187 auto validPixelHits=
track.hitPattern().numberOfValidPixelHits();
189 score[
k] = m_foundHitBonus*validPixelHits+m_foundHitBonus*validHits - m_lostHitPenalty*
lostHits -
track.chi2();
192 rhv.reserve(validHits) ;
193 auto compById = [](IHit
const & h1, IHit
const & h2) {
return h1.first < h2.first;};
194 for (
auto it =
track.recHitsBegin(); it !=
track.recHitsEnd(); ++it) {
195 auto const &
hit = *(*it);
196 auto id =
hit.rawId() ;
197 if likely(
hit.isValid()) { rhv.emplace_back(
id,&
hit); std::push_heap(rhv.begin(),rhv.end(),compById); }
199 std::sort_heap(rhv.begin(),rhv.end(),compById);
207 auto seti = [&](
unsigned int ii,
unsigned int jj) {
211 algoMask[
ii] |= algoMask[
jj];
213 algoMask[
jj] = algoMask[
ii];
220 for (
auto i=0
U; i<collsSize-1; ++
i) {
221 auto iStart1=iStart2;
222 iStart2=iStart1+nGoods[
i];
223 for (
auto t1=iStart1; t1<iStart2; ++t1) {
224 if (!selected[t1])
continue;
225 auto score1 =
score[t1];
226 for (
auto t2=iStart2;
t2 <ntotTk; ++
t2) {
227 if (!selected[t1])
break;
228 if (!selected[
t2])
continue;
229 if (mom[t1].Dot(mom[t2])<0)
continue;
230 if (!areDuplicate(rh1[t1],rh1[t2]))
continue;
234 if ( score1 - score2 > almostSame ) {
236 }
else if ( score2 - score1 > almostSame ) {
240 if ( (quals[t1]&qmask) == (quals[
t2]&qmask) ) {
247 }
else if ( (quals[t1]&qmask) > (quals[t2]&qmask) )
259 const bool doMerging = m_enableMerging && collsSize>1;
260 if (doMerging) merger();
263 auto pmvas = std::make_unique<MVACollection>();
264 auto pquals = std::make_unique<QualityMaskCollection>();
270 for (
auto i=0
U; i<collsSize; ++
i) {
271 std::vector<unsigned int> selId;
272 std::vector<unsigned int> tid;
273 auto iStart1=iStart2;
274 iStart2=iStart1+nGoods[
i];
275 assert(
producer.selTracks_->size()==isel);
276 for (
auto t1=iStart1; t1<iStart2; ++t1) {
277 if (!selected[t1])
continue;
280 selId.push_back(tkInds[t1]);
281 pmvas->push_back(
mvas[t1]);
282 pquals->push_back(quals[t1]);
285 assert(
producer.selTracks_->size()==nsel);
286 assert(tid.size()==nsel-isel);
288 for (;isel<nsel;++isel) {
289 auto & otk = (*
producer.selTracks_)[isel];
290 otk.setQualityMask((*pquals)[isel]);
292 otk.setOriginalAlgorithm(oriAlgo[tid[k]]);
293 otk.setAlgoMask(algoMask[tid[k++]]);
296 if(doMerging) assert(tid.size()==
k);
299 assert(
producer.selTracks_->size()==pmvas->size());
311 bool TrackCollectionMerger::areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const {
322 if (m_allowFirstHitShare && rh1[0].
first==rh2[0].
first ) {
323 if (share( rh1[0].
second, rh2[0].second)) firstoverlap=1;
329 while (ih!=nh1 && jh!=nh2) {
330 auto const id1 = rh1[ih].first;
331 auto const id2 = rh2[jh].first;
335 if (share( rh1[ih].
second, rh2[jh].second)) noverlap++;
340 return noverlap >=
int(m_minShareHits) &&
341 (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)
math::XYZVector Vector
spatial vector