00001 #include "RecoTracker/FinalTrackSelectors/interface/DuplicateListMerger.h"
00002 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00003 #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h"
00004 #include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h"
00005 #include "RecoTracker/TrackProducer/interface/ClusterRemovalRefSetter.h"
00006 #include "DataFormats/Common/interface/ValueMap.h"
00007
00008 #include "FWCore/Framework/interface/Event.h"
00009 #include "CommonTools/Statistics/interface/ChiSquaredProbability.h"
00010
00011 using reco::modules::DuplicateListMerger;
00012
00013 DuplicateListMerger::DuplicateListMerger(const edm::ParameterSet& iPara)
00014 {
00015 diffHitsCut_ = 9999;
00016 minTrkProbCut_ = 0.0;
00017 if(iPara.exists("diffHitsCut"))diffHitsCut_ = iPara.getParameter<int>("diffHitsCut");
00018 if(iPara.exists("minTrkProbCut"))minTrkProbCut_ = iPara.getParameter<double>("minTrkProbCut");
00019 if(iPara.exists("mergedSource"))mergedTrackSource_ = iPara.getParameter<edm::InputTag>("mergedSource");
00020 if(iPara.exists("originalSource"))originalTrackSource_ = iPara.getParameter<edm::InputTag>("originalSource");
00021 if(iPara.exists("candidateSource"))candidateSource_ = iPara.getParameter<edm::InputTag>("candidateSource");
00022
00023
00024 if(iPara.exists("mergedMVAVals")){
00025 mergedMVAVals_ = iPara.getParameter<edm::InputTag>("mergedMVAVals");
00026 }else{
00027 mergedMVAVals_ = edm::InputTag(mergedTrackSource_.label(),"MVAVals");
00028 }
00029 if(iPara.exists("originalMVAVals")){
00030 originalMVAVals_ = iPara.getParameter<edm::InputTag>("originalMVAVals");
00031 }else{
00032 originalMVAVals_ = edm::InputTag(originalTrackSource_.label(),"MVAVals");
00033 }
00034
00035 copyExtras_ = iPara.getUntrackedParameter<bool>("copyExtras",true);
00036 qualityToSet_ = reco::TrackBase::undefQuality;
00037 if (iPara.exists("newQuality")) {
00038 std::string qualityStr = iPara.getParameter<std::string>("newQuality");
00039 if (qualityStr != "") {
00040 qualityToSet_ = reco::TrackBase::qualityByName(qualityStr);
00041 }
00042 }
00043
00044 produces<std::vector<reco::Track> >();
00045 produces< std::vector<Trajectory> >();
00046 produces< TrajTrackAssociationCollection >();
00047
00048 produces<edm::ValueMap<float> >("MVAVals");
00049
00050 makeReKeyedSeeds_ = iPara.getUntrackedParameter<bool>("makeReKeyedSeeds",false);
00051 if (makeReKeyedSeeds_){
00052 copyExtras_=true;
00053 produces<TrajectorySeedCollection>();
00054 }
00055 if(copyExtras_){
00056 produces<reco::TrackExtraCollection>();
00057 produces<TrackingRecHitCollection>();
00058 }
00059
00060 }
00061
00062 DuplicateListMerger::~DuplicateListMerger()
00063 {
00064
00065
00066
00067 }
00068
00069 void DuplicateListMerger::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00070 {
00071 edm::Handle<reco::TrackCollection > originalHandle;
00072 iEvent.getByLabel(originalTrackSource_,originalHandle);
00073 edm::Handle<reco::TrackCollection > mergedHandle;
00074 iEvent.getByLabel(mergedTrackSource_,mergedHandle);
00075
00076 const reco::TrackCollection& mergedTracks(*mergedHandle);
00077 reco::TrackRefProd originalTrackRefs(originalHandle);
00078 reco::TrackRefProd mergedTrackRefs(mergedHandle);
00079
00080 edm::Handle< std::vector<Trajectory> > mergedTrajHandle;
00081 iEvent.getByLabel(mergedTrackSource_,mergedTrajHandle);
00082 edm::Handle< TrajTrackAssociationCollection > mergedTrajTrackHandle;
00083 iEvent.getByLabel(mergedTrackSource_,mergedTrajTrackHandle);
00084
00085 edm::Handle< std::vector<Trajectory> > originalTrajHandle;
00086 iEvent.getByLabel(originalTrackSource_,originalTrajHandle);
00087 edm::Handle< TrajTrackAssociationCollection > originalTrajTrackHandle;
00088 iEvent.getByLabel(originalTrackSource_,originalTrajTrackHandle);
00089
00090 edm::Handle<edm::View<DuplicateRecord> > candidateHandle;
00091 iEvent.getByLabel(candidateSource_,candidateHandle);
00092
00093 std::auto_ptr<std::vector<reco::Track> > out_generalTracks(new std::vector<reco::Track>());
00094 out_generalTracks->reserve(originalHandle->size());
00095 reco::TrackRefProd refTrks = iEvent.getRefBeforePut<reco::TrackCollection>();
00096 std::auto_ptr< std::vector<Trajectory> > outputTrajs = std::auto_ptr< std::vector<Trajectory> >(new std::vector<Trajectory>());
00097 outputTrajs->reserve(originalTrajHandle->size()+mergedTrajHandle->size());
00098 edm::RefProd< std::vector<Trajectory> > refTrajs;
00099 std::auto_ptr< TrajTrackAssociationCollection > outputTTAss = std::auto_ptr< TrajTrackAssociationCollection >(new TrajTrackAssociationCollection());
00100
00101
00102 std::auto_ptr<reco::TrackExtraCollection> outputTrkExtras;
00103 reco::TrackExtraRefProd refTrkExtras;
00104 std::auto_ptr<TrackingRecHitCollection> outputTrkHits;
00105 TrackingRecHitRefProd refTrkHits;
00106 std::auto_ptr<TrajectorySeedCollection> outputSeeds;
00107 edm::RefProd< TrajectorySeedCollection > refTrajSeeds;
00108
00109 const int rSize = (int)originalHandle->size();
00110 edm::RefToBase<TrajectorySeed> seedsRefs[rSize];
00111
00112 edm::Handle<edm::ValueMap<float> > originalMVAStore;
00113 edm::Handle<edm::ValueMap<float> > mergedMVAStore;
00114
00115 iEvent.getByLabel(originalMVAVals_,originalMVAStore);
00116 iEvent.getByLabel(mergedMVAVals_,mergedMVAStore);
00117
00118 std::auto_ptr<edm::ValueMap<float> > vmMVA = std::auto_ptr<edm::ValueMap<float> >(new edm::ValueMap<float>);
00119 edm::ValueMap<float>::Filler fillerMVA(*vmMVA);
00120 std::vector<float> mvaVec;
00121
00122
00123 if(copyExtras_){
00124 outputTrkExtras = std::auto_ptr<reco::TrackExtraCollection>(new reco::TrackExtraCollection);
00125 outputTrkExtras->reserve(originalHandle->size());
00126 refTrkExtras = iEvent.getRefBeforePut<reco::TrackExtraCollection>();
00127 outputTrkHits = std::auto_ptr<TrackingRecHitCollection>(new TrackingRecHitCollection);
00128 outputTrkHits->reserve(originalHandle->size()*25);
00129 refTrkHits = iEvent.getRefBeforePut<TrackingRecHitCollection>();
00130 if (makeReKeyedSeeds_){
00131 outputSeeds = std::auto_ptr<TrajectorySeedCollection>(new TrajectorySeedCollection);
00132 outputSeeds->reserve(originalHandle->size());
00133 refTrajSeeds = iEvent.getRefBeforePut<TrajectorySeedCollection>();
00134 }
00135 }
00136
00137
00138 std::vector<std::pair<int,const DuplicateRecord*> > matches;
00139 for(int i = 0; i < (int)candidateHandle->size(); i++){
00140 const DuplicateRecord& duplicateRecord = candidateHandle->at(i);
00141 int matchTrack = matchCandidateToTrack(duplicateRecord.first,mergedHandle);
00142 if(matchTrack < 0)continue;
00143 const reco::Track& matchedTrack(mergedTracks[matchTrack]);
00144 if( ChiSquaredProbability(matchedTrack.chi2(),matchedTrack.ndof()) < minTrkProbCut_)continue;
00145 unsigned int dHits = (duplicateRecord.first.recHits().second - duplicateRecord.first.recHits().first) - matchedTrack.recHitsSize();
00146 if(dHits > diffHitsCut_)continue;
00147 matches.push_back(std::pair<int,const DuplicateRecord*>(matchTrack,&duplicateRecord));
00148 }
00149
00150
00151 std::vector<std::pair<int,const DuplicateRecord*> >::iterator matchIter0 = matches.begin();
00152 std::vector<std::pair<int,const DuplicateRecord*> >::iterator matchIter1;
00153 while(matchIter0 != matches.end()){
00154 double nchi2 = mergedTracks[matchIter0->first].normalizedChi2();
00155 bool advance = true;
00156 for(matchIter1 = matchIter0+1; matchIter1 != matches.end(); matchIter1++){
00157 const reco::Track& match0first = *(matchIter0->second->second.first.get());
00158 const reco::Track& match0second = *(matchIter0->second->second.second.get());
00159 const reco::Track& match1first = *(matchIter1->second->second.first.get());
00160 const reco::Track& match1second = *(matchIter1->second->second.second.get());
00161 if(match1first.seedRef() == match0first.seedRef() ||
00162 match1first.seedRef() == match0second.seedRef() ||
00163 match1second.seedRef() == match0first.seedRef() ||
00164 match1second.seedRef() == match0second.seedRef()){
00165 double nchi2_1 = mergedTracks[matchIter1->first].normalizedChi2();
00166 advance = false;
00167 if(nchi2_1 < nchi2){
00168 matches.erase(matchIter0);
00169 }else{
00170 matches.erase(matchIter1);
00171 }
00172 break;
00173 }
00174 }
00175 if(advance)matchIter0++;
00176 }
00177
00178
00179 std::vector<reco::Track> inputTracks;
00180
00181 refTrajs = iEvent.getRefBeforePut< std::vector<Trajectory> >();
00182
00183 for(matchIter0 = matches.begin(); matchIter0 != matches.end(); matchIter0++){
00184 reco::TrackRef inTrkRef1 = matchIter0->second->second.first;
00185 reco::TrackRef inTrkRef2 = matchIter0->second->second.second;
00186 const reco::Track& inTrk1 = *(inTrkRef1.get());
00187 const reco::Track& inTrk2 = *(inTrkRef2.get());
00188 reco::TrackBase::TrackAlgorithm newTrkAlgo = std::min(inTrk1.algo(),inTrk2.algo());
00189 int combinedQualityMask = (inTrk1.qualityMask() | inTrk2.qualityMask());
00190 inputTracks.push_back(inTrk1);
00191 inputTracks.push_back(inTrk2);
00192 out_generalTracks->push_back(mergedTracks[matchIter0->first]);
00193 reco::TrackRef curTrackRef = reco::TrackRef(refTrks, out_generalTracks->size() - 1);
00194 float mergedMVA = (*mergedMVAStore)[reco::TrackRef(mergedTrackRefs,matchIter0->first)];
00195 mvaVec.push_back(mergedMVA);
00196 out_generalTracks->back().setAlgorithm(newTrkAlgo);
00197 out_generalTracks->back().setQualityMask(combinedQualityMask);
00198 out_generalTracks->back().setQuality(qualityToSet_);
00199 edm::RefToBase<TrajectorySeed> origSeedRef;
00200 if(copyExtras_){
00201 const reco::Track& track = mergedTracks[matchIter0->first];
00202 origSeedRef = track.seedRef();
00203
00204 if (makeReKeyedSeeds_){
00205 bool doRekeyOnThisSeed=false;
00206
00207 edm::InputTag clusterRemovalInfos("");
00208
00209 if (origSeedRef->nHits()!=0){
00210 TrajectorySeed::const_iterator firstHit=origSeedRef->recHits().first;
00211 const TrackingRecHit *hit = &*firstHit;
00212 if (firstHit->isValid()){
00213 edm::ProductID pID=clusterProductB(hit);
00214
00215
00216 edm::Handle<reco::ClusterRemovalInfo> CRIh;
00217 edm::Provenance prov=iEvent.getProvenance(pID);
00218 clusterRemovalInfos=edm::InputTag(prov.moduleLabel(),
00219 prov.productInstanceName(),
00220 prov.processName());
00221 doRekeyOnThisSeed=iEvent.getByLabel(clusterRemovalInfos,CRIh);
00222 }
00223 }
00224
00225 if (doRekeyOnThisSeed && !(clusterRemovalInfos==edm::InputTag(""))) {
00226 ClusterRemovalRefSetter refSetter(iEvent,clusterRemovalInfos);
00227 TrajectorySeed::recHitContainer newRecHitContainer;
00228 newRecHitContainer.reserve(origSeedRef->nHits());
00229 TrajectorySeed::const_iterator iH=origSeedRef->recHits().first;
00230 TrajectorySeed::const_iterator iH_end=origSeedRef->recHits().second;
00231 for (;iH!=iH_end;++iH){
00232 newRecHitContainer.push_back(*iH);
00233 refSetter.reKey(&newRecHitContainer.back());
00234 }
00235 outputSeeds->push_back( TrajectorySeed( origSeedRef->startingState(),
00236 newRecHitContainer,
00237 origSeedRef->direction()));
00238 }
00239
00240 else{
00241
00242 outputSeeds->push_back( TrajectorySeed(*origSeedRef));
00243 }
00244 edm::Ref<TrajectorySeedCollection> pureRef(refTrajSeeds, outputSeeds->size()-1);
00245 origSeedRef=edm::RefToBase<TrajectorySeed>( pureRef);
00246 }
00247
00248 outputTrkExtras->push_back( reco::TrackExtra(
00249 track.outerPosition(), track.outerMomentum(), track.outerOk(),
00250 track.innerPosition(), track.innerMomentum(), track.innerOk(),
00251 track.outerStateCovariance(), track.outerDetId(),
00252 track.innerStateCovariance(), track.innerDetId(),
00253 track.seedDirection(), origSeedRef ) );
00254 seedsRefs[(*matchIter0).first]=origSeedRef;
00255 out_generalTracks->back().setExtra( reco::TrackExtraRef( refTrkExtras, outputTrkExtras->size() - 1) );
00256 reco::TrackExtra & tx = outputTrkExtras->back();
00257 tx.setResiduals(track.residuals());
00258
00259 unsigned nh1=track.recHitsSize();
00260 for ( unsigned ih=0; ih<nh1; ++ih ) {
00261
00262 outputTrkHits->push_back( track.recHit(ih)->clone() );
00263 tx.add( TrackingRecHitRef( refTrkHits, outputTrkHits->size() - 1) );
00264 }
00265 }
00266 edm::Ref< std::vector<Trajectory> > trajRef(mergedTrajHandle, (*matchIter0).first);
00267 TrajTrackAssociationCollection::const_iterator match = mergedTrajTrackHandle->find(trajRef);
00268 if (match != mergedTrajTrackHandle->end()) {
00269 if(curTrackRef.isNonnull()){
00270 outputTrajs->push_back( *trajRef );
00271 if (copyExtras_ && makeReKeyedSeeds_)
00272 outputTrajs->back().setSeedRef( origSeedRef );
00273 outputTTAss->insert(edm::Ref< std::vector<Trajectory> >(refTrajs, outputTrajs->size() - 1),curTrackRef );
00274 }
00275 }
00276 }
00277
00278 for(int i = 0; i < (int)originalHandle->size(); i++){
00279 bool good = true;
00280 const reco::Track& origTrack = originalHandle->at(i);
00281 for(int j = 0; j < (int)inputTracks.size() && good; j++){
00282 const reco::Track& inputTrack = inputTracks[j];
00283 if(origTrack.seedRef() != inputTrack.seedRef())continue;
00284 if(origTrack.charge() != inputTrack.charge())continue;
00285 if(origTrack.momentum() != inputTrack.momentum())continue;
00286 if(origTrack.referencePoint() != inputTrack.referencePoint())continue;
00287 good = false;
00288 }
00289
00290 if(good){
00291 out_generalTracks->push_back(origTrack);
00292 reco::TrackRef curTrackRef = reco::TrackRef(refTrks, out_generalTracks->size() - 1);
00293 edm::RefToBase<TrajectorySeed> origSeedRef;
00294 reco::TrackRef origTrackRef = reco::TrackRef(originalHandle,i);
00295 mvaVec.push_back((*originalMVAStore)[origTrackRef]);
00296
00297 if(copyExtras_){
00298 const reco::Track& track = origTrack;
00299 origSeedRef = track.seedRef();
00300
00301 if (makeReKeyedSeeds_){
00302 bool doRekeyOnThisSeed=false;
00303
00304 edm::InputTag clusterRemovalInfos("");
00305
00306 if (origSeedRef->nHits()!=0){
00307 TrajectorySeed::const_iterator firstHit=origSeedRef->recHits().first;
00308 const TrackingRecHit *hit = &*firstHit;
00309 if (firstHit->isValid()){
00310 edm::ProductID pID=clusterProductB(hit);
00311
00312
00313 edm::Handle<reco::ClusterRemovalInfo> CRIh;
00314 edm::Provenance prov=iEvent.getProvenance(pID);
00315 clusterRemovalInfos=edm::InputTag(prov.moduleLabel(),
00316 prov.productInstanceName(),
00317 prov.processName());
00318 doRekeyOnThisSeed=iEvent.getByLabel(clusterRemovalInfos,CRIh);
00319 }
00320 }
00321
00322 if (doRekeyOnThisSeed && !(clusterRemovalInfos==edm::InputTag(""))) {
00323 ClusterRemovalRefSetter refSetter(iEvent,clusterRemovalInfos);
00324 TrajectorySeed::recHitContainer newRecHitContainer;
00325 newRecHitContainer.reserve(origSeedRef->nHits());
00326 TrajectorySeed::const_iterator iH=origSeedRef->recHits().first;
00327 TrajectorySeed::const_iterator iH_end=origSeedRef->recHits().second;
00328 for (;iH!=iH_end;++iH){
00329 newRecHitContainer.push_back(*iH);
00330 refSetter.reKey(&newRecHitContainer.back());
00331 }
00332 outputSeeds->push_back( TrajectorySeed( origSeedRef->startingState(),
00333 newRecHitContainer,
00334 origSeedRef->direction()));
00335 }
00336
00337 else{
00338
00339 outputSeeds->push_back( TrajectorySeed(*origSeedRef));
00340 }
00341 edm::Ref<TrajectorySeedCollection> pureRef(refTrajSeeds, outputSeeds->size()-1);
00342 origSeedRef=edm::RefToBase<TrajectorySeed>( pureRef);
00343 }
00344
00345
00346 outputTrkExtras->push_back( reco::TrackExtra(
00347 track.outerPosition(), track.outerMomentum(), track.outerOk(),
00348 track.innerPosition(), track.innerMomentum(), track.innerOk(),
00349 track.outerStateCovariance(), track.outerDetId(),
00350 track.innerStateCovariance(), track.innerDetId(),
00351 track.seedDirection(), origSeedRef ) );
00352 seedsRefs[i]=origSeedRef;
00353 out_generalTracks->back().setExtra( reco::TrackExtraRef( refTrkExtras, outputTrkExtras->size() - 1) );
00354 reco::TrackExtra & tx = outputTrkExtras->back();
00355 tx.setResiduals(track.residuals());
00356
00357
00358 unsigned nh1=track.recHitsSize();
00359 for ( unsigned ih=0; ih<nh1; ++ih ) {
00360
00361 outputTrkHits->push_back( track.recHit(ih)->clone() );
00362 tx.add( TrackingRecHitRef( refTrkHits, outputTrkHits->size() - 1) );
00363 }
00364
00365 }
00366
00367 edm::Ref< std::vector<Trajectory> > trajRef(originalTrajHandle, i);
00368 TrajTrackAssociationCollection::const_iterator match = originalTrajTrackHandle->find(trajRef);
00369 if (match != originalTrajTrackHandle->end()) {
00370 if(curTrackRef.isNonnull()){
00371 outputTrajs->push_back( *trajRef );
00372 if (copyExtras_ && makeReKeyedSeeds_)
00373 outputTrajs->back().setSeedRef( origSeedRef );
00374 outputTTAss->insert(edm::Ref< std::vector<Trajectory> >(refTrajs, outputTrajs->size() - 1),curTrackRef );
00375 }
00376 }
00377 }
00378 }
00379
00380 edm::ProductID nPID = refTrks.id();
00381 edm::TestHandle<TrackCollection> out_gtHandle(out_generalTracks.get(),nPID);
00382
00383 fillerMVA.insert(out_gtHandle,mvaVec.begin(),mvaVec.end());
00384 fillerMVA.fill();
00385
00386 iEvent.put(vmMVA,"MVAVals");
00387 iEvent.put(out_generalTracks);
00388 if (copyExtras_) {
00389 iEvent.put(outputTrkExtras);
00390 iEvent.put(outputTrkHits);
00391 if (makeReKeyedSeeds_)
00392 iEvent.put(outputSeeds);
00393 }
00394 iEvent.put(outputTrajs);
00395 iEvent.put(outputTTAss);
00396 }
00397
00398
00399
00400
00401
00402 int DuplicateListMerger::matchCandidateToTrack(TrackCandidate candidate, edm::Handle<reco::TrackCollection > tracks){
00403 int track = -1;
00404 std::vector<int> rawIds;
00405 RecHitContainer::const_iterator candBegin = candidate.recHits().first;
00406 RecHitContainer::const_iterator candEnd = candidate.recHits().second;
00407 for(; candBegin != candEnd; candBegin++){
00408 rawIds.push_back((*(candBegin)).rawId());
00409 }
00410
00411
00412 for(int i = 0; i < (int)tracks->size() && track < 0;i++){
00413 if((tracks->at(i)).seedRef() != candidate.seedRef())continue;
00414 int match = 0;
00415 trackingRecHit_iterator trackRecBegin = tracks->at(i).recHitsBegin();
00416 trackingRecHit_iterator trackRecEnd = tracks->at(i).recHitsEnd();
00417 for(;trackRecBegin != trackRecEnd; trackRecBegin++){
00418 if(std::find(rawIds.begin(),rawIds.end(),(*(trackRecBegin)).get()->rawId()) != rawIds.end())match++;
00419 }
00420 if(match != (int)tracks->at(i).recHitsSize())continue;
00421 track = i;
00422 }
00423
00424 return track;
00425 }
00426
00427
00428
00429