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 {
174 for (
auto i=0
U; i< collsSize; ++
i) {
175 auto const & tkColl = *trackColls[
i];
176 for (
auto j=0
U; j< nGoods[
i]; ++j) {
177 auto const &
track = tkColl[tkInds[
k]];
179 oriAlgo[
k] =
track.originalAlgo();
180 algoMask[
k] =
track.algoMask();
182 auto validHits=
track.numberOfValidHits();
183 auto validPixelHits=
track.hitPattern().numberOfValidPixelHits();
185 score[
k] = m_foundHitBonus*validPixelHits+m_foundHitBonus*validHits - m_lostHitPenalty*
lostHits -
track.chi2();
188 rhv.reserve(validHits) ;
189 auto compById = [](IHit
const & h1, IHit
const & h2) {
return h1.first < h2.first;};
190 for (
auto it =
track.recHitsBegin(); it !=
track.recHitsEnd(); ++it) {
191 auto const &
hit = *(*it);
192 auto id =
hit.rawId() ;
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 (mom[t1].Dot(mom[t2])<0)
continue;
226 if (!areDuplicate(rh1[t1],rh1[t2]))
continue;
230 if ( score1 - score2 > almostSame ) {
232 }
else if ( score2 - score1 > almostSame ) {
236 if ( (quals[t1]&qmask) == (quals[
t2]&qmask) ) {
243 }
else if ( (quals[t1]&qmask) > (quals[t2]&qmask) )
255 if (collsSize>1) merger();
258 auto pmvas = std::make_unique<MVACollection>();
259 auto pquals = std::make_unique<QualityMaskCollection>();
265 for (
auto i=0
U; i<collsSize; ++
i) {
266 std::vector<unsigned int> selId;
267 std::vector<unsigned int> tid;
268 auto iStart1=iStart2;
269 iStart2=iStart1+nGoods[
i];
270 assert(
producer.selTracks_->size()==isel);
271 for (
auto t1=iStart1; t1<iStart2; ++t1) {
272 if (!selected[t1])
continue;
275 selId.push_back(tkInds[t1]);
276 pmvas->push_back(
mvas[t1]);
277 pquals->push_back(quals[t1]);
280 assert(
producer.selTracks_->size()==nsel);
281 assert(tid.size()==nsel-isel);
283 for (;isel<nsel;++isel) {
284 auto & otk = (*
producer.selTracks_)[isel];
285 otk.setQualityMask((*pquals)[isel]);
286 otk.setOriginalAlgorithm(oriAlgo[tid[k]]);
287 otk.setAlgoMask(algoMask[tid[k++]]);
289 assert(tid.size()==
k);
292 assert(
producer.selTracks_->size()==pmvas->size());
304 bool TrackCollectionMerger::areDuplicate(IHitV
const& rh1, IHitV
const& rh2)
const {
315 if (m_allowFirstHitShare && rh1[0].
first==rh2[0].
first ) {
316 if (share( rh1[0].
second, rh2[0].second)) firstoverlap=1;
322 while (ih!=nh1 && jh!=nh2) {
323 auto const id1 = rh1[ih].first;
324 auto const id2 = rh2[jh].first;
326 else if (id2<id1) ++jh;
328 if (share( rh1[ih].
second, rh2[jh].second)) noverlap++;
333 return noverlap >=
int(m_minShareHits) &&
334 (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