73 tag(tag_), tk(tk_), traj(traj_), tass(tass_), tsel(tsel_), tmva(tmva_) {}
77 consumes<std::vector<Trajectory> >(tag), consumes<TrajTrackAssociationCollection >(tag),
82 consumes<std::vector<Trajectory> >(tag), consumes<TrajTrackAssociationCollection >(tag),
138 #include <x86intrin.h> 143 inline volatile unsigned long long rdtsc() {
150 unsigned long long st;
151 long long totBegin=0;
154 unsigned long long timeNo;
155 unsigned long long timeOv;
159 void start() { st=rdtsc(); }
160 void noOverlap() { timeNo += (rdtsc()-st);}
161 void overlap() { timeOv += (rdtsc()-st);}
162 void pre(
int tt) { totPre+=
tt;}
163 void end(
int tt) { totEnd+=
tt;}
164 void de(
float d) {
if (d>maxDE) maxDE=
d;}
165 void dp(
float d) {
if (d>maxDP) maxDP=
d;}
169 std::cout <<
"TrackListMerger stat\nBegin/Pre/End/maxDPhi/maxDEta/Overlap/NoOverlap " 170 << totBegin <<
'/'<< totPre <<
'/'<< totEnd <<
'/'<< maxDP <<
'/'<< maxDE
171 <<
'/'<< timeOv/1000 <<
'/'<< timeNo/1000
175 ~StatCount() {
print();}
210 std::vector<edm::InputTag> trackProducerTags(conf.
getParameter<std::vector<edm::InputTag> >(
"TrackProducers"));
212 maxNormalizedChisq_ = conf.
getParameter<
double>(
"MaxNormalizedChisq");
217 allowFirstHitShare_ = conf.
getParameter<
bool>(
"allowFirstHitShare");
218 foundHitBonus_ = conf.
getParameter<
double>(
"FoundHitBonus");
219 lostHitPenalty_ = conf.
getParameter<
double>(
"LostHitPenalty");
220 indivShareFrac_=conf.
getParameter<std::vector<double> >(
"indivShareFrac");
223 if (!qualityStr.empty()) {
229 use_sharesInput_ =
true;
230 if ( epsilon_ > 0.0 )use_sharesInput_ =
false;
234 for (
unsigned int i=0;
i<setsToMerge.size();
i++) {
235 listsToMerge_.push_back(setsToMerge[
i].getParameter<std::vector< int> >(
"tLists"));
236 promoteQuality_.push_back(setsToMerge[
i].getParameter<bool>(
"pQual"));
238 hasSelector_ = conf.
getParameter<std::vector<int> > (
"hasSelector");
241 std::vector<edm::InputTag>
selectors(conf.
getParameter<std::vector<edm::InputTag> >(
"selectedTrackQuals"));
242 std::vector<edm::InputTag> mvaStores;
243 if(conf.
exists(
"mvaValueTags")){
244 mvaStores = conf.
getParameter<std::vector<edm::InputTag> >(
"mvaValueTags");
246 for (
int i = 0;
i < (
int)selectors.size();
i++){
248 mvaStores.push_back(ntag);
251 unsigned int numTrkColl = trackProducerTags.size();
252 if (numTrkColl != hasSelector_.size() || numTrkColl != selectors.size()) {
253 throw cms::Exception(
"Inconsistent size") <<
"need same number of track collections and selectors";
255 if (numTrkColl != hasSelector_.size() || numTrkColl != mvaStores.size()) {
256 throw cms::Exception(
"Inconsistent size") <<
"need same number of track collections and MVA stores";
258 for (
unsigned int i = indivShareFrac_.size();
i < numTrkColl;
i++) {
260 indivShareFrac_.push_back(1.0);
263 trkQualMod_=conf.
getParameter<
bool>(
"writeOnlyTrkQuals");
266 for (
unsigned int i=1;
i<numTrkColl;
i++) {
267 if (!(trackProducerTags[
i]==trackProducerTags[0])) ok=
false;
270 throw cms::Exception(
"Bad input") <<
"to use writeOnlyTrkQuals=True all input InputTags must be the same";
272 produces<edm::ValueMap<int> >();
273 produces<QualityMaskCollection>(
"QualityMasks");
276 produces<reco::TrackCollection>();
279 if (makeReKeyedSeeds_){
281 produces<TrajectorySeedCollection>();
285 produces<reco::TrackExtraCollection>();
286 produces<TrackingRecHitCollection>();
288 produces< std::vector<Trajectory> >();
289 produces< TrajTrackAssociationCollection >();
291 produces<edm::ValueMap<float> >(
"MVAVals");
292 produces<MVACollection>(
"MVAValues");
295 trackProducers_.resize(numTrkColl);
296 for (
unsigned int i = 0;
i < numTrkColl; ++
i) {
297 trackProducers_[
i] = hasSelector_[
i]>0 ? edTokens(trackProducerTags[
i], selectors[i], mvaStores[i]) : edTokens(trackProducerTags[i], mvaStores[i]);
328 std::vector<const reco::TrackCollection *> trackColls;
329 std::vector<edm::Handle<reco::TrackCollection> > trackHandles(trackProducers_.size());
330 for (
unsigned int i=0;
i<trackProducers_.size();
i++) {
331 trackColls.push_back(
nullptr);
334 if (trackHandles[i].isValid()) {
335 trackColls[
i]= trackHandles[
i].product();
337 edm::LogWarning(
"TrackListMerger") <<
"TrackCollection " << trackProducers_[
i].tag <<
" not found";
338 trackColls[
i]=&s_empty;
342 unsigned int collsSize =trackColls.size();
343 unsigned int rSize=0;
344 unsigned int trackCollSizes[collsSize];
345 unsigned int trackCollFirsts[collsSize];
346 for (
unsigned int i=0;
i!=collsSize;
i++) {
347 trackCollSizes[
i]=trackColls[
i]->size();
348 trackCollFirsts[
i]=rSize;
349 rSize+=trackCollSizes[
i];
352 statCount.begin(rSize);
361 bool trkUpdated[rSize];
362 int trackCollNum[rSize];
363 int trackQuals[rSize];
364 float trackMVAs[rSize];
366 std::vector<reco::TrackBase::AlgoMask> algoMask(rSize);
367 for (
unsigned int j=0; j<rSize;j++) {
372 for (
unsigned int j=0; j!= collsSize; j++) {
378 e.
getByToken(trackProducers_[j].tmva, trackMVAStore);
379 if ( hasSelector_[j]>0 ){
380 e.
getByToken(trackProducers_[j].tsel, trackSelColl);
383 if ( !tC1->empty() ){
385 for (reco::TrackCollection::const_iterator
track=tC1->begin();
track!=tC1->end();
track++){
388 trackQuals[
i]=
track->qualityMask();
389 oriAlgo[
i]=
track->originalAlgo();
390 algoMask[
i]=
track->algoMask();
394 if( (*trackMVAStore).contains(trkRef.
id()) ) trackMVAs[
i] = (*trackMVAStore)[trkRef];
395 if ( hasSelector_[j]>0 ) {
396 int qual=(*trackSelColl)[trkRef];
406 selected[
i]=trackQuals[
i]+10;
407 if ((
short unsigned)
track->ndof() < 1){
411 if (
track->normalizedChi2() > maxNormalizedChisq_){
415 if (
track->found() < minFound_){
419 if (
track->pt() < minPT_){
431 statCount.pre(ngood);
434 typedef std::pair<unsigned int, const TrackingRecHit*> IHit;
435 std::vector<std::vector<IHit>> rh1(ngood);
441 for (
unsigned int j=0; j<rSize; j++) {
442 if (selected[j]==0)
continue;
445 unsigned int collNum=trackCollNum[j];
446 unsigned int trackNum=j-trackCollFirsts[collNum];
449 algo[
i]=track->
algo();
453 score[
i] = foundHitBonus_*validPixelHits+foundHitBonus_*validHits - lostHitPenalty_*lostHits - track->
chi2();
456 rh1[
i].reserve(validHits) ;
457 auto compById = [](IHit
const & h1, IHit
const & h2) {
return h1.first < h2.first;};
460 unsigned int id = hit->
rawId() ;
462 if LIKELY(hit->
isValid()) { rh1[
i].emplace_back(
id,hit); std::push_heap(rh1[i].
begin(),rh1[i].
end(),compById); }
464 std::sort_heap(rh1[i].
begin(),rh1[i].
end(),compById);
468 if LIKELY(ngood>1 && collsSize>1)
469 for (
unsigned int ltm=0; ltm<listsToMerge_.size(); ltm++) {
470 int saveSelected[rSize];
471 bool notActive[collsSize];
472 for (
unsigned int cn=0;cn!=collsSize;++cn)
473 notActive[cn]=
find(listsToMerge_[ltm].
begin(),listsToMerge_[ltm].end(),cn)==listsToMerge_[ltm].
end();
475 for (
unsigned int i=0; i<rSize; i++) saveSelected[i]=selected[i];
478 for (
unsigned int i=0; i<rSize-1; i++) {
479 if (selected[i]==0)
continue;
480 unsigned int collNum=trackCollNum[
i];
483 if (notActive[collNum])
continue;
486 unsigned int nh1=rh1[k1].size();
487 int qualityMaskT1 = trackQuals[
i];
490 float score1 = score[k1];
493 for (
unsigned int j=i+1; j<rSize; j++) {
494 if (selected[j]==0)
continue;
495 unsigned int collNum2=trackCollNum[j];
496 if ( (collNum == collNum2) && indivShareFrac_[collNum] > 0.99)
continue;
498 if (notActive[collNum2])
continue;
502 int newQualityMask = -9;
503 if (promoteQuality_[ltm]) {
504 int maskT1= saveSelected[
i]>1? saveSelected[
i]-10 : qualityMaskT1;
505 int maskT2= saveSelected[j]>1? saveSelected[j]-10 : trackQuals[j];
506 newQualityMask =(maskT1 | maskT2);
508 unsigned int nh2=rh1[k2].size();
512 auto share = use_sharesInput_ ?
528 if (share(it,jt,epsilon_)) firstoverlap=1;
535 while (ih!=nh1 && jh!=nh2) {
539 auto const id1 = rh1[k1][ih].first;
540 auto const id2 = rh1[k2][jh].first;
545 auto li=ih;
while( (++li)!=nh1 &&
id1 == rh1[k1][li].first);
546 auto lj=jh;
while( (++lj)!=nh2 &&
id2 == rh1[k2][lj].first);
547 for (
auto ii=ih;
ii!=li; ++
ii)
548 for (
auto jj=jh;
jj!=lj; ++
jj) {
551 if (share(it,jt,epsilon_)) noverlap++;
558 bool dupfound = (collNum != collNum2) ? (noverlap-firstoverlap) > (
std::min(nhit1,nhit2)-firstoverlap)*shareFrac_ :
559 (noverlap-firstoverlap) > (
std::min(nhit1,nhit2)-firstoverlap)*indivShareFrac_[collNum];
561 auto seti = [&](
unsigned int ii,
unsigned int jj) {
563 selected[
ii]=10+newQualityMask;
566 algoMask[
ii] |= algoMask[
jj];
567 algoMask[
jj] = algoMask[
ii];
571 float score2 = score[k2];
573 if ( score1 - score2 > almostSame ) {
575 }
else if ( score2 - score1 > almostSame ) {
603 statCount.noOverlap();
606 if (selected[i]==0)
break;
613 auto vmMVA = std::make_unique<edm::ValueMap<float>>();
620 unsigned int tSize=trackColls[0]->size();
621 auto vm = std::make_unique<edm::ValueMap<int>>();
624 std::vector<int> finalQuals(tSize,-1);
625 for (
unsigned int i=0; i<rSize; i++) {
626 unsigned int tNum=i%tSize;
628 if (selected[i]>1 ) {
629 finalQuals[tNum]=selected[
i]-10;
631 finalQuals[tNum]=(finalQuals[tNum] | (1<<qualityToSet_));
633 if ( selected[i]==1 )
634 finalQuals[tNum]=trackQuals[
i];
637 filler.insert(trackHandles[0], finalQuals.begin(),finalQuals.end());
642 auto quals = std::make_unique<QualityMaskCollection>(finalQuals.begin(),finalQuals.end());
645 std::vector<float> mvaVec(tSize,-99);
647 for(
unsigned int i = 0; i < rSize; i++){
648 unsigned int tNum = i % tSize;
649 mvaVec[tNum] = trackMVAs[tNum];
652 fillerMVA.insert(trackHandles[0],mvaVec.begin(),mvaVec.end());
656 auto mvas = std::make_unique<MVACollection>(mvaVec.begin(),mvaVec.end());
667 std::vector<reco::TrackRef> trackRefs(rSize);
668 std::vector<edm::RefToBase<TrajectorySeed>> seedsRefs(rSize);
670 unsigned int nToWrite=0;
671 for (
unsigned int i=0; i<rSize; i++)
672 if (selected[i]!=0) nToWrite++;
674 std::vector<float> mvaVec;
676 outputTrks = std::make_unique<reco::TrackCollection>();
677 outputTrks->reserve(nToWrite);
681 outputTrkExtras = std::make_unique<reco::TrackExtraCollection>();
682 outputTrkExtras->reserve(nToWrite);
684 outputTrkHits = std::make_unique<TrackingRecHitCollection>();
685 outputTrkHits->reserve(nToWrite*25);
687 if (makeReKeyedSeeds_){
688 outputSeeds = std::make_unique<TrajectorySeedCollection>();
689 outputSeeds->
reserve(nToWrite);
695 outputTrajs = std::make_unique<std::vector<Trajectory>>();
696 outputTrajs->reserve(rSize);
698 for (
unsigned int i=0; i<rSize; i++) {
699 if (selected[i]==0) {
704 unsigned int collNum=trackCollNum[
i];
705 unsigned int trackNum=i-trackCollFirsts[collNum];
708 mvaVec.push_back(trackMVAs[i]);
709 if (selected[i]>1 ) {
710 outputTrks->back().setQualityMask(selected[i]-10);
712 outputTrks->back().setQuality(qualityToSet_);
715 if ( selected[i]==1 )
716 outputTrks->back().setQualityMask(trackQuals[i]);
717 outputTrks->back().setOriginalAlgorithm(oriAlgo[i]);
718 outputTrks->back().setAlgoMask(algoMask[i]);
726 if (makeReKeyedSeeds_){
727 bool doRekeyOnThisSeed=
false;
731 if (origSeedRef->
nHits()!=0){
734 if (firstHit->isValid()){
743 doRekeyOnThisSeed=e.
getByLabel(clusterRemovalInfos,CRIh);
747 if (doRekeyOnThisSeed && !(clusterRemovalInfos==
edm::InputTag(
""))) {
753 for (;iH!=iH_end;++iH){
755 refSetter.
reKey(&newRecHitContainer.
back());
777 seedsRefs[
i]=origSeedRef;
778 outputTrks->back().setExtra(
reco::TrackExtraRef( refTrkExtras, outputTrkExtras->size() - 1) );
784 tx.
setHits(refTrkHits,outputTrkHits->size(),nh1);
788 outputTrkHits->push_back( (*hh)->clone() );
799 outputTTAss = std::make_unique<TrajTrackAssociationCollection>(refTrajs, refTrks);
801 for (
unsigned int ti=0; ti<trackColls.size(); ti++) {
804 e.
getByToken(trackProducers_[ti].traj, hTraj1);
805 e.
getByToken(trackProducers_[ti].tass, hTTAss1);
809 for (
size_t i = 0,
n = hTraj1->size(); i <
n; ++
i) {
812 if (match != hTTAss1->
end()) {
814 uint32_t oldKey = trackCollFirsts[ti]+
static_cast<uint32_t
>(trkRef.
key());
815 if (trackRefs[oldKey].isNonnull()) {
816 outputTrajs->push_back( *trajRef );
818 if (copyExtras_ && makeReKeyedSeeds_)
819 outputTrajs->back().setSeedRef( seedsRefs[oldKey] );
820 outputTTAss->insert (
edm::Ref< std::vector<Trajectory> >(refTrajs, outputTrajs->size() - 1),
827 statCount.end(outputTrks->size());
831 fillerMVA.insert(outHandle,mvaVec.begin(),mvaVec.end());
837 auto mvas = std::make_unique<MVACollection>(mvaVec.begin(),mvaVec.end());
843 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
std::unique_ptr< TrajTrackAssociationCollection > outputTTAss
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
std::vector< bool > promoteQuality_
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
edm::EDGetTokenT< TrajTrackAssociationCollection > tass
edm::RefProd< std::vector< Trajectory > > refTrajs
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.
std::unique_ptr< TrajectorySeedCollection > outputSeeds
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
edm::RefProd< TrajectorySeedCollection > refTrajSeeds
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_
bool overlap(const reco::Muon &muon1, const reco::Muon &muon2, double pullX=1.0, double pullY=1.0, bool checkAdjacentChambers=false)
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::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
trackingRecHit_iterator recHitsBegin() const
Iterator to first hit on the track.
virtual LocalPoint localPosition() const =0
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.
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
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.
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_)
DetId geographicalId() const
std::string const & productInstanceName() const
std::string priorityName_
std::vector< std::vector< int > > listsToMerge_
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.