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 !=
"") {
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)
virtual void produce(Event &, EventSetup const &)=0
TrackQuality
track quality
#define DEFINE_FWK_MODULE(type)
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
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
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
int subdetId() const
get the contents of the subdetector field (not cast into any detector's numbering enum) ...
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.