00001 #include "RecoVertex/NuclearInteractionProducer/interface/NuclearInteractionEDProducer.h"
00002 #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h"
00003 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005
00006 #include "DataFormats/VertexReco/interface/NuclearInteractionFwd.h"
00007
00008 #include "RecoVertex/NuclearInteractionProducer/interface/NuclearVertexBuilder.h"
00009 #include "RecoVertex/NuclearInteractionProducer/interface/NuclearLikelihood.h"
00010
00011 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00012
00013 #include "FWCore/Framework/interface/EventSetup.h"
00014
00015
00016 NuclearInteractionEDProducer::NuclearInteractionEDProducer(const edm::ParameterSet& iConfig) :
00017 conf_(iConfig),
00018 primaryProducer_(iConfig.getParameter<std::string>("primaryProducer")),
00019 seedsProducer_(iConfig.getParameter<std::string>("seedsProducer")),
00020 secondaryProducer_(iConfig.getParameter<std::string>("secondaryProducer")),
00021 additionalSecondaryProducer_(iConfig.getParameter<std::string>("additionalSecondaryProducer"))
00022 {
00023 produces<reco::NuclearInteractionCollection>();
00024 }
00025
00026 NuclearInteractionEDProducer::~NuclearInteractionEDProducer()
00027 {
00028 }
00029
00030
00031
00032
00033
00034
00035 void
00036 NuclearInteractionEDProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00037 {
00039 edm::Handle<reco::TrackCollection> primaryTrackCollection;
00040 iEvent.getByLabel( primaryProducer_, primaryTrackCollection );
00041
00043 edm::Handle< TrajectoryCollection > primaryTrajectoryCollection;
00044 iEvent.getByLabel( primaryProducer_, primaryTrajectoryCollection );
00045
00047 edm::Handle< TrajTrackAssociationCollection > refMapH;
00048 iEvent.getByLabel( primaryProducer_, refMapH );
00049 const TrajTrackAssociationCollection& refMap = *(refMapH.product());
00050
00052 edm::Handle<TrajectoryToSeedsMap> nuclMapH;
00053 iEvent.getByLabel(seedsProducer_, nuclMapH);
00054 const TrajectoryToSeedsMap& nuclMap = *(nuclMapH.product());
00055
00057 edm::Handle<reco::TrackCollection> secondaryTrackCollection;
00058 iEvent.getByLabel( secondaryProducer_, secondaryTrackCollection );
00059
00060
00061 edm::Handle<reco::TrackCollection> additionalSecTracks;
00062 iEvent.getByLabel( additionalSecondaryProducer_, additionalSecTracks);
00063
00065 std::auto_ptr<reco::NuclearInteractionCollection> theNuclearInteractions(new reco::NuclearInteractionCollection);
00066
00067 typedef edm::Ref<TrajectoryCollection> TrajectoryRef;
00068
00070 for(unsigned int i = 0; i < primaryTrajectoryCollection->size() ; i++) {
00071
00072 TrajectoryRef trajRef( primaryTrajectoryCollection, i );
00073
00075 TrajTrackAssociationCollection::const_iterator itPrimTrack = refMap.find( trajRef );
00076 if( itPrimTrack == refMap.end() || (itPrimTrack->val).isNull() ) continue;
00077 const reco::TrackRef& primary_track = itPrimTrack->val;
00078
00080 TrajectoryToSeedsMap::const_iterator itSeeds = nuclMap.find( trajRef );
00081 if( itSeeds == nuclMap.end() || (itSeeds->val).isNull()) continue;
00082 const TrajectorySeedRefVector& seeds = itSeeds->val;
00083
00085 std::vector<reco::TrackRef> secondary_tracks;
00086 for( unsigned int k=0; k < secondaryTrackCollection->size(); k++) {
00087 reco::TrackRef currentTrk(secondaryTrackCollection, k);
00088 if( isInside( currentTrk, seeds ) ) secondary_tracks.push_back(currentTrk);
00089 }
00090
00092 vertexBuilder->build(primary_track, secondary_tracks);
00093 likelihoodCalculator->calculate( vertexBuilder->getVertex() );
00094
00096 reco::NuclearInteraction nuclInter(seeds, vertexBuilder->getVertex(), likelihoodCalculator->result() );
00097
00100 if( additionalSecTracks.isValid() )
00101 findAdditionalSecondaryTracks(nuclInter, additionalSecTracks);
00102
00103 theNuclearInteractions->push_back( nuclInter );
00104
00105 std::ostringstream str;
00106 print(str, nuclInter, vertexBuilder);
00107 edm::LogInfo("NuclearInteractionMaker") << str.str();
00108
00109 }
00110
00111
00112 LogDebug("NuclearInteractionMaker") << "End of NuclearInteractionMaker - Number of nuclear interactions found :" << theNuclearInteractions->size();
00113 iEvent.put(theNuclearInteractions);
00114 }
00115
00116
00117 void
00118 NuclearInteractionEDProducer::beginJob(const edm::EventSetup& es)
00119 {
00121 edm::ESHandle<MagneticField> magField;
00122 es.get<IdealMagneticFieldRecord>().get(magField);
00123
00124 edm::ESHandle<TransientTrackBuilder> builder;
00125 es.get<TransientTrackRecord>().get("TransientTrackBuilder",builder);
00126
00127 vertexBuilder = std::auto_ptr< NuclearVertexBuilder >(new NuclearVertexBuilder( magField.product(), builder.product(), conf_) );
00128 likelihoodCalculator = std::auto_ptr< NuclearLikelihood >(new NuclearLikelihood);
00129
00130 }
00131
00132 void NuclearInteractionEDProducer::endJob() {}
00133
00134
00135 bool NuclearInteractionEDProducer::isInside( const reco::TrackRef& track, const TrajectorySeedRefVector& seeds) {
00136 unsigned int seedKey = track->seedRef().key();
00137 for (unsigned int i=0; i< seeds.size(); i++) { if( seeds[i].key() == seedKey ) return true; }
00138 return false;
00139 }
00140
00141 void NuclearInteractionEDProducer::findAdditionalSecondaryTracks( reco::NuclearInteraction& nucl,
00142 const edm::Handle<reco::TrackCollection>& additionalSecTracks) {
00143
00144 LogDebug("NuclearInteractionMaker") << "Check if one of the " << additionalSecTracks->size()
00145 << " additional secondary track is compatible";
00146 reco::TrackRefVector allSecondary;
00147 for(unsigned int i=0; i< additionalSecTracks->size(); i++) {
00148 reco::TrackRef sec(additionalSecTracks, i);
00149 if( vertexBuilder->isCompatible( sec ) ) {
00150
00151
00152 vertexBuilder->addSecondaryTrack( sec );
00153 }
00154 }
00155 likelihoodCalculator->calculate( vertexBuilder->getVertex() );
00156
00157 nucl = reco::NuclearInteraction(nucl.seeds(), vertexBuilder->getVertex(), likelihoodCalculator->result() );
00158 }
00159
00160
00161 void print(std::ostringstream& out, const reco::NuclearInteraction& nucl, const std::auto_ptr< NuclearVertexBuilder >& builder) {
00162 out<<"Nuclear Interaction with vertex position : (";
00163 out<< nucl.vertex().position().x() << " , "
00164 << nucl.vertex().position().y() << " , "
00165 << nucl.vertex().position().z() << ")";
00166 reco::TrackRef primTrack = (nucl.primaryTrack()).castTo<reco::TrackRef>();
00167 out<<"\tLikelihood : " << nucl.likelihood() << std::endl;
00168 out<<"\tPrimary Track : Pt = " << primTrack->pt() << " - Nhits = "
00169 << primTrack->numberOfValidHits() << std::endl;
00170 out << "\tNumber of seeds : " << nucl.seedsSize() << std::endl;
00171 out << "\tNumber of secondary Tracks : " << nucl.secondaryTracksSize() << std::endl;
00172 int it=0;
00173 for( reco::NuclearInteraction::trackRef_iterator itr_=nucl.secondaryTracks_begin(); itr_ != nucl.secondaryTracks_end(); itr_++, it++) {
00174 reco::TrackRef secTrack = (*itr_).castTo<reco::TrackRef>();
00175 ClosestApproachInRPhi* theApproach = builder->closestApproach(primTrack, secTrack);
00176 out << "\t\t Secondary track " << it << " : Pt = " << (*itr_)->pt()
00177 << " - Nhits = " << (*itr_)->numberOfValidHits()
00178 << " - Dist = " << theApproach->distance()
00179 << " - chi2 = " << (*itr_)->normalizedChi2() << std::endl;
00180 delete theApproach;
00181 }
00182 out << "----------------" << std::endl;
00183 }