73 : tag(tag_), tk(tk_), traj(traj_), tass(tass_), tsel(tsel_), tmva(tmva_) {}
77 consumes<reco::TrackCollection>(tag),
78 consumes<std::vector<Trajectory>>(tag),
79 consumes<TrajTrackAssociationCollection>(tag),
85 consumes<reco::TrackCollection>(tag),
86 consumes<std::vector<Trajectory>>(tag),
87 consumes<TrajTrackAssociationCollection>(tag),
140 #include <x86intrin.h> 145 inline volatile unsigned long long rdtsc() {
return __rdtsc(); }
150 unsigned long long st;
151 long long totBegin = 0;
152 long long totPre = 0;
153 long long totEnd = 0;
154 unsigned long long timeNo;
155 unsigned long long timeOv;
157 void start() { st = rdtsc(); }
158 void noOverlap() { timeNo += (rdtsc() - st); }
159 void overlap() { timeOv += (rdtsc() - st); }
160 void pre(
int tt) { totPre +=
tt; }
161 void end(
int tt) { totEnd +=
tt; }
172 std::cout <<
"TrackListMerger stat\nBegin/Pre/End/maxDPhi/maxDEta/Overlap/NoOverlap " << totBegin <<
'/' << totPre
173 <<
'/' << totEnd <<
'/' << maxDP <<
'/' << maxDE <<
'/' << timeOv / 1000 <<
'/' << timeNo / 1000
177 ~StatCount() {
print(); }
206 std::vector<edm::InputTag> trackProducerTags(conf.
getParameter<std::vector<edm::InputTag>>(
"TrackProducers"));
208 maxNormalizedChisq_ = conf.
getParameter<
double>(
"MaxNormalizedChisq");
213 allowFirstHitShare_ = conf.
getParameter<
bool>(
"allowFirstHitShare");
214 foundHitBonus_ = conf.
getParameter<
double>(
"FoundHitBonus");
215 lostHitPenalty_ = conf.
getParameter<
double>(
"LostHitPenalty");
216 indivShareFrac_ = conf.
getParameter<std::vector<double>>(
"indivShareFrac");
219 if (!qualityStr.empty()) {
224 use_sharesInput_ =
true;
226 use_sharesInput_ =
false;
230 for (
unsigned int i = 0;
i < setsToMerge.size();
i++) {
231 listsToMerge_.push_back(setsToMerge[
i].getParameter<std::vector<int>>(
"tLists"));
232 promoteQuality_.push_back(setsToMerge[
i].getParameter<bool>(
"pQual"));
234 hasSelector_ = conf.
getParameter<std::vector<int>>(
"hasSelector");
237 std::vector<edm::InputTag>
selectors(conf.
getParameter<std::vector<edm::InputTag>>(
"selectedTrackQuals"));
238 std::vector<edm::InputTag> mvaStores;
239 if (conf.
exists(
"mvaValueTags")) {
240 mvaStores = conf.
getParameter<std::vector<edm::InputTag>>(
"mvaValueTags");
242 for (
int i = 0;
i < (
int)selectors.size();
i++) {
244 mvaStores.push_back(ntag);
247 unsigned int numTrkColl = trackProducerTags.size();
248 if (numTrkColl != hasSelector_.size() || numTrkColl != selectors.size()) {
249 throw cms::Exception(
"Inconsistent size") <<
"need same number of track collections and selectors";
251 if (numTrkColl != hasSelector_.size() || numTrkColl != mvaStores.size()) {
252 throw cms::Exception(
"Inconsistent size") <<
"need same number of track collections and MVA stores";
254 for (
unsigned int i = indivShareFrac_.size();
i < numTrkColl;
i++) {
256 indivShareFrac_.push_back(1.0);
259 trkQualMod_ = conf.
getParameter<
bool>(
"writeOnlyTrkQuals");
262 for (
unsigned int i = 1;
i < numTrkColl;
i++) {
263 if (!(trackProducerTags[
i] == trackProducerTags[0]))
267 throw cms::Exception(
"Bad input") <<
"to use writeOnlyTrkQuals=True all input InputTags must be the same";
269 produces<edm::ValueMap<int>>();
270 produces<QualityMaskCollection>(
"QualityMasks");
272 produces<reco::TrackCollection>();
275 if (makeReKeyedSeeds_) {
277 produces<TrajectorySeedCollection>();
281 produces<reco::TrackExtraCollection>();
282 produces<TrackingRecHitCollection>();
284 produces<std::vector<Trajectory>>();
285 produces<TrajTrackAssociationCollection>();
287 produces<edm::ValueMap<float>>(
"MVAVals");
288 produces<MVACollection>(
"MVAValues");
291 trackProducers_.resize(numTrkColl);
292 for (
unsigned int i = 0;
i < numTrkColl; ++
i) {
293 trackProducers_[
i] = hasSelector_[
i] > 0 ? edTokens(trackProducerTags[
i], selectors[i], mvaStores[i])
294 : edTokens(trackProducerTags[i], mvaStores[i]);
323 std::vector<const reco::TrackCollection*> trackColls;
324 std::vector<edm::Handle<reco::TrackCollection>> trackHandles(trackProducers_.size());
325 for (
unsigned int i = 0;
i < trackProducers_.size();
i++) {
326 trackColls.push_back(
nullptr);
329 if (trackHandles[i].isValid()) {
330 trackColls[
i] = trackHandles[
i].product();
332 edm::LogWarning(
"TrackListMerger") <<
"TrackCollection " << trackProducers_[
i].tag <<
" not found";
333 trackColls[
i] = &s_empty;
337 unsigned int collsSize = trackColls.size();
338 unsigned int rSize = 0;
339 unsigned int trackCollSizes[collsSize];
340 unsigned int trackCollFirsts[collsSize];
341 for (
unsigned int i = 0;
i != collsSize;
i++) {
342 trackCollSizes[
i] = trackColls[
i]->size();
343 trackCollFirsts[
i] = rSize;
344 rSize += trackCollSizes[
i];
347 statCount.begin(rSize);
356 bool trkUpdated[rSize];
357 int trackCollNum[rSize];
358 int trackQuals[rSize];
359 float trackMVAs[rSize];
361 std::vector<reco::TrackBase::AlgoMask> algoMask(rSize);
362 for (
unsigned int j = 0;
j < rSize;
j++) {
365 trkUpdated[
j] =
false;
368 trackMVAs[
j] = -998.0;
373 for (
unsigned int j = 0;
j != collsSize;
j++) {
379 e.
getByToken(trackProducers_[
j].tmva, trackMVAStore);
380 if (hasSelector_[
j] > 0) {
381 e.
getByToken(trackProducers_[
j].tsel, trackSelColl);
386 for (reco::TrackCollection::const_iterator
track = tC1->begin();
track != tC1->end();
track++) {
389 trackQuals[
i] =
track->qualityMask();
390 oriAlgo[
i] =
track->originalAlgo();
391 algoMask[
i] =
track->algoMask();
395 if ((*trackMVAStore).contains(trkRef.
id()))
396 trackMVAs[
i] = (*trackMVAStore)[trkRef];
397 if (hasSelector_[j] > 0) {
398 int qual = (*trackSelColl)[trkRef];
404 trackQuals[
i] = qual;
408 selected[
i] = trackQuals[
i] + 10;
409 if ((
short unsigned)
track->ndof() < 1) {
413 if (
track->normalizedChi2() > maxNormalizedChisq_) {
417 if (
track->found() < minFound_) {
421 if (
track->pt() < minPT_) {
432 statCount.pre(ngood);
435 typedef std::pair<unsigned int, const TrackingRecHit*> IHit;
436 std::vector<std::vector<IHit>> rh1(ngood);
441 for (
unsigned int j = 0;
j < rSize;
j++) {
442 if (selected[
j] == 0)
446 unsigned int collNum = trackCollNum[
j];
447 unsigned int trackNum =
j - trackCollFirsts[collNum];
450 algo[
i] = track->
algo();
455 foundHitBonus_ * validPixelHits + foundHitBonus_ * validHits - lostHitPenalty_ * lostHits - track->
chi2();
457 rh1[
i].reserve(validHits);
458 auto compById = [](IHit
const& h1, IHit
const& h2) {
return h1.first < h2.first; };
461 unsigned int id = hit->
rawId();
466 rh1[
i].emplace_back(
id, hit);
467 std::push_heap(rh1[i].
begin(), rh1[i].
end(), compById);
470 std::sort_heap(rh1[i].
begin(), rh1[i].
end(), compById);
475 LIKELY(ngood > 1 && collsSize > 1)
476 for (
unsigned int ltm = 0; ltm < listsToMerge_.size(); ltm++) {
477 int saveSelected[rSize];
478 bool notActive[collsSize];
479 for (
unsigned int cn = 0; cn != collsSize; ++cn)
480 notActive[cn] =
find(listsToMerge_[ltm].
begin(), listsToMerge_[ltm].end(), cn) == listsToMerge_[ltm].
end();
482 for (
unsigned int i = 0; i < rSize; i++)
483 saveSelected[i] = selected[i];
486 for (
unsigned int i = 0; i < rSize - 1; i++) {
487 if (selected[i] == 0)
489 unsigned int collNum = trackCollNum[
i];
492 if (notActive[collNum])
496 unsigned int nh1 = rh1[k1].size();
497 int qualityMaskT1 = trackQuals[
i];
500 float score1 = score[k1];
503 for (
unsigned int j = i + 1;
j < rSize;
j++) {
504 if (selected[
j] == 0)
506 unsigned int collNum2 = trackCollNum[
j];
507 if ((collNum == collNum2) && indivShareFrac_[collNum] > 0.99)
510 if (notActive[collNum2])
515 int newQualityMask = -9;
516 if (promoteQuality_[ltm]) {
517 int maskT1 = saveSelected[
i] > 1 ? saveSelected[
i] - 10 : qualityMaskT1;
518 int maskT2 = saveSelected[
j] > 1 ? saveSelected[
j] - 10 : trackQuals[
j];
519 newQualityMask = (maskT1 | maskT2);
521 unsigned int nh2 = rh1[k2].size();
529 return (it->
geographicalId() == jt->geographicalId()) && (delta < eps);
536 int firstoverlap = 0;
542 if (share(it, jt, epsilon_))
549 while (ih != nh1 && jh != nh2) {
553 auto const id1 = rh1[k1][ih].first;
554 auto const id2 = rh1[k2][jh].first;
562 while ((++li) != nh1 &&
id1 == rh1[k1][li].first) {
565 while ((++lj) != nh2 &&
id2 == rh1[k2][lj].first) {
567 for (
auto ii = ih;
ii != li; ++
ii)
568 for (
auto jj = jh;
jj != lj; ++
jj) {
571 if (share(it, jt, epsilon_))
581 (collNum != collNum2)
582 ? (noverlap - firstoverlap) > (
std::min(nhit1, nhit2) - firstoverlap) * shareFrac_
583 : (noverlap - firstoverlap) > (
std::min(nhit1, nhit2) - firstoverlap) * indivShareFrac_[collNum];
585 auto seti = [&](
unsigned int ii,
unsigned int jj) {
587 selected[
ii] = 10 + newQualityMask;
588 trkUpdated[
ii] =
true;
590 oriAlgo[ii] = oriAlgo[jj];
591 algoMask[
ii] |= algoMask[
jj];
592 algoMask[
jj] = algoMask[
ii];
596 float score2 = score[k2];
598 if (score1 - score2 > almostSame) {
600 }
else if (score2 - score1 > almostSame) {
632 statCount.noOverlap();
635 if (selected[i] == 0)
641 auto vmMVA = std::make_unique<edm::ValueMap<float>>();
646 unsigned int tSize = trackColls[0]->size();
647 auto vm = std::make_unique<edm::ValueMap<int>>();
650 std::vector<int> finalQuals(tSize, -1);
651 for (
unsigned int i = 0; i < rSize; i++) {
652 unsigned int tNum = i % tSize;
654 if (selected[i] > 1) {
655 finalQuals[tNum] = selected[
i] - 10;
657 finalQuals[tNum] = (finalQuals[tNum] | (1 << qualityToSet_));
659 if (selected[i] == 1)
660 finalQuals[tNum] = trackQuals[
i];
663 filler.insert(trackHandles[0], finalQuals.begin(), finalQuals.end());
667 for (
auto&
q : finalQuals)
669 auto quals = std::make_unique<QualityMaskCollection>(finalQuals.begin(), finalQuals.end());
672 std::vector<float> mvaVec(tSize, -99);
674 for (
unsigned int i = 0; i < rSize; i++) {
675 unsigned int tNum = i % tSize;
676 mvaVec[tNum] = trackMVAs[tNum];
679 fillerMVA.insert(trackHandles[0], mvaVec.begin(), mvaVec.end());
683 auto mvas = std::make_unique<MVACollection>(mvaVec.begin(), mvaVec.end());
693 std::vector<reco::TrackRef> trackRefs(rSize);
694 std::vector<edm::RefToBase<TrajectorySeed>> seedsRefs(rSize);
696 unsigned int nToWrite = 0;
697 for (
unsigned int i = 0; i < rSize; i++)
698 if (selected[i] != 0)
701 std::vector<float> mvaVec;
703 outputTrks = std::make_unique<reco::TrackCollection>();
704 outputTrks->reserve(nToWrite);
708 outputTrkExtras = std::make_unique<reco::TrackExtraCollection>();
709 outputTrkExtras->reserve(nToWrite);
711 outputTrkHits = std::make_unique<TrackingRecHitCollection>();
712 outputTrkHits->reserve(nToWrite * 25);
714 if (makeReKeyedSeeds_) {
715 outputSeeds = std::make_unique<TrajectorySeedCollection>();
716 outputSeeds->
reserve(nToWrite);
721 outputTrajs = std::make_unique<std::vector<Trajectory>>();
722 outputTrajs->reserve(rSize);
724 for (
unsigned int i = 0; i < rSize; i++) {
725 if (selected[i] == 0) {
730 unsigned int collNum = trackCollNum[
i];
731 unsigned int trackNum = i - trackCollFirsts[collNum];
734 mvaVec.push_back(trackMVAs[i]);
735 if (selected[i] > 1) {
736 outputTrks->back().setQualityMask(selected[i] - 10);
738 outputTrks->back().setQuality(qualityToSet_);
741 if (selected[i] == 1)
742 outputTrks->back().setQualityMask(trackQuals[i]);
743 outputTrks->back().setOriginalAlgorithm(oriAlgo[i]);
744 outputTrks->back().setAlgoMask(algoMask[i]);
752 if (makeReKeyedSeeds_) {
753 bool doRekeyOnThisSeed =
false;
757 if (origSeedRef->
nHits() != 0) {
760 if (firstHit->isValid()) {
767 doRekeyOnThisSeed = e.
getByLabel(clusterRemovalInfos, CRIh);
771 if (doRekeyOnThisSeed && !(clusterRemovalInfos ==
edm::InputTag(
""))) {
777 for (; iH != iH_end; ++iH) {
779 refSetter.
reKey(&newRecHitContainer.
back());
781 outputSeeds->push_back(
806 seedsRefs[
i] = origSeedRef;
807 outputTrks->back().setExtra(
reco::TrackExtraRef(refTrkExtras, outputTrkExtras->size() - 1));
813 tx.
setHits(refTrkHits, outputTrkHits->size(), nh1);
817 outputTrkHits->push_back((*hh)->clone());
827 outputTTAss = std::make_unique<TrajTrackAssociationCollection>(refTrajs, refTrks);
829 for (
unsigned int ti = 0; ti < trackColls.size(); ti++) {
832 e.
getByToken(trackProducers_[ti].traj, hTraj1);
833 e.
getByToken(trackProducers_[ti].tass, hTTAss1);
838 for (
size_t i = 0,
n = hTraj1->size(); i <
n; ++
i) {
841 if (match != hTTAss1->
end()) {
843 uint32_t oldKey = trackCollFirsts[ti] +
static_cast<uint32_t
>(trkRef.
key());
844 if (trackRefs[oldKey].isNonnull()) {
845 outputTrajs->push_back(*trajRef);
847 if (copyExtras_ && makeReKeyedSeeds_)
848 outputTrajs->back().setSeedRef(seedsRefs[oldKey]);
849 outputTTAss->insert(
edm::Ref<std::vector<Trajectory>>(refTrajs, outputTrajs->size() - 1), trackRefs[oldKey]);
855 statCount.end(outputTrks->size());
859 fillerMVA.insert(outHandle, mvaVec.begin(), mvaVec.end());
865 auto mvas = std::make_unique<MVACollection>(mvaVec.begin(), mvaVec.end());
871 if (makeReKeyedSeeds_)
PropagationDirection direction() const
const edm::RefToBase< TrajectorySeed > & seedRef() const
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
TrackListMerger(const edm::ParameterSet &conf)
std::vector< unsigned char > QualityMaskCollection
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
std::vector< bool > promoteQuality_
std::unique_ptr< TrajTrackAssociationCollection > outputTTAss
const TrackExtraRef & extra() const
reference to "extra" object
friend struct const_iterator
const_iterator end() const
last iterator over the map (read only)
reco::TrackRefProd refTrks
bool getByToken(EDGetToken token, Handle< PROD > &result) const
TkEDGetTokenss edTokens(const edm::InputTag &tag, const edm::InputTag &mvatag)
TrackQuality
track quality
size_t recHitsSize() const
Get number of RecHits. (Warning, this includes invalid hits, which are not physical hits)...
std::vector< ParameterSet > VParameterSet
void reKey(TrackingRecHit *hit) const
const_iterator find(const key_type &k) const
find element with specified reference key
reco::TrackBase::TrackQuality qualityToSet_
std::vector< Track > TrackCollection
collection of Tracks
bool exists(std::string const ¶meterName) const
checks if a parameter exists
bool innerOk() const
return true if the innermost hit is valid
unsigned short numberOfLostHits() const
number of cases where track crossed a layer without getting a hit.
key_type key() const
Accessor for product key.
~TrackListMerger() override
S & print(S &os, JobReport::InputFile const &f)
std::string const & processName() const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
const math::XYZPoint & outerPosition() const
position of the outermost hit
std::vector< float > MVACollection
std::unique_ptr< std::vector< Trajectory > > outputTrajs
ProductID id() const
Accessor for product ID.
TrackAlgorithm
track algorithm
TrackingRecHitRefProd refTrkHits
void produce(edm::Event &e, const edm::EventSetup &c) override
std::vector< double > indivShareFrac_
const math::XYZPoint & innerPosition() const
position of the innermost hit
TrackAlgorithm algo() const
std::unique_ptr< TrackingRecHitCollection > outputTrkHits
#define DEFINE_FWK_MODULE(type)
edm::EDGetTokenT< edm::ValueMap< int > > tsel
std::vector< TrajectorySeed > TrajectorySeedCollection
double chi2() const
chi-squared of the fit
recHitContainer::const_iterator const_iterator
CovarianceMatrix outerStateCovariance() const
outermost trajectory state curvilinear errors
edm::RefProd< TrajectorySeedCollection > refTrajSeeds
edm::EDGetTokenT< reco::TrackCollection > tk
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector's numbering enum) ...
unsigned int outerDetId() const
DetId of the detector on which surface the outermost state is located.
Abs< T >::type abs(const T &t)
TkEDGetTokenss edTokens(const edm::InputTag &tag, const edm::InputTag &seltag, const edm::InputTag &mvatag)
unsigned short numberOfValidHits() const
number of valid hits found
edm::EDGetTokenT< TrajTrackAssociationCollection > tass
trackingRecHit_iterator recHitsBegin() const
Iterator to first hit on the track.
virtual LocalPoint localPosition() const =0
edm::RefProd< std::vector< Trajectory > > refTrajs
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
RefProd< PROD > getRefBeforePut()
std::unique_ptr< reco::TrackExtraCollection > outputTrkExtras
std::vector< int > hasSelector_
std::vector< TrackExtra > TrackExtraCollection
collection of TrackExtra objects
double maxNormalizedChisq_
PTrajectoryStateOnDet const & startingState() const
static TrackQuality qualityByName(const std::string &name)
const math::XYZVector & outerMomentum() const
momentum vector at the outermost hit position
bool outerOk() const
return true if the outermost hit is valid
const PropagationDirection & seedDirection() const
direction of how the hits were sorted in the original seed
const HitPattern & hitPattern() const
Access the hit pattern, indicating in which Tracker layers the track has hits.
std::unique_ptr< TrajectorySeedCollection > outputSeeds
edm::EDGetTokenT< edm::ValueMap< float > > tmva
edm::Ref< TrackCollection > TrackRef
persistent reference to a Track
CovarianceMatrix innerStateCovariance() const
innermost trajectory state curvilinear errors
std::string const & moduleLabel() const
unsigned int nHits() const
std::vector< TkEDGetTokenss > trackProducers_
const math::XYZVector & innerMomentum() const
momentum vector at the innermost hit position
const TrackResiduals & residuals() const
get the residuals
int numberOfValidPixelHits() const
TkEDGetTokenss(const edm::InputTag &tag_, edm::EDGetTokenT< reco::TrackCollection > &&tk_, edm::EDGetTokenT< std::vector< Trajectory >> &&traj_, edm::EDGetTokenT< TrajTrackAssociationCollection > &&tass_, edm::EDGetTokenT< edm::ValueMap< int >> &&tsel_, edm::EDGetTokenT< edm::ValueMap< float >> &&tmva_)
std::vector< std::vector< int > > listsToMerge_
std::unique_ptr< reco::TrackCollection > outputTrks
edm::EDGetTokenT< std::vector< Trajectory > > traj
std::array< unsigned int, reco::TrackBase::algoSize > trackAlgoPriorityOrder
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
DetId geographicalId() const
std::string const & productInstanceName() const
std::string priorityName_
Provenance getProvenance(BranchID const &theID) const
unsigned int innerDetId() const
DetId of the detector on which surface the innermost state is located.
reco::TrackExtraRefProd refTrkExtras
trackingRecHit_iterator recHitsEnd() const
Iterator to last hit on the track.