Go to the documentation of this file.00001 #include <iostream>
00002 #include <vector>
00003 #include <memory>
00004
00005
00006 #include "DataFormats/Common/interface/Handle.h"
00007 #include "FWCore/Framework/interface/ESHandle.h"
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 #include "FWCore/Utilities/interface/Exception.h"
00010
00011 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00012 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00013 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
00014 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
00015
00016 #include "DataFormats/TrackReco/interface/Track.h"
00017 #include "DataFormats/TrackReco/interface/TrackBase.h"
00018 #include "DataFormats/TrackReco/interface/TrackExtra.h"
00019 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00020 #include "TrackingTools/TransientTrack/interface/TrackTransientTrack.h"
00021 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00022 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00023 #include "TrackingTools/PatternTools/interface/TwoTrackMinimumDistance.h"
00024
00025 #include "DataFormats/EgammaCandidates/interface/Conversion.h"
00026 #include "DataFormats/EgammaCandidates/interface/ConversionFwd.h"
00027 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionTrackEcalImpactPoint.h"
00028 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionTrackPairFinder.h"
00029 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionVertexFinder.h"
00030
00031 #include "DataFormats/EgammaTrackReco/interface/TrackCaloClusterAssociation.h"
00032 #include "RecoEgamma/EgammaPhotonProducers/interface/SoftConversionProducer.h"
00033
00034 #include "Math/GenVector/VectorUtil.h"
00035
00036
00037 SoftConversionProducer::SoftConversionProducer(const edm::ParameterSet& config) : conf_(config) {
00038
00039 LogDebug("SoftConversionProducer") << " SoftConversionProducer CTOR " << "\n";
00040
00041 conversionOITrackProducer_ = conf_.getParameter<std::string>("conversionOITrackProducer");
00042 conversionIOTrackProducer_ = conf_.getParameter<std::string>("conversionIOTrackProducer");
00043 outInTrackClusterAssociationCollection_ = conf_.getParameter<std::string>("outInTrackClusterAssociationCollection");
00044 inOutTrackClusterAssociationCollection_ = conf_.getParameter<std::string>("inOutTrackClusterAssociationCollection");
00045 clusterType_ = conf_.getParameter<std::string>("clusterType");
00046 clusterBarrelCollection_ = conf_.getParameter<edm::InputTag>("clusterBarrelCollection");
00047 clusterEndcapCollection_ = conf_.getParameter<edm::InputTag>("clusterEndcapCollection");
00048 softConversionCollection_ = conf_.getParameter<std::string>("softConversionCollection");
00049 trackMaxChi2_ = conf_.getParameter<double>("trackMaxChi2");
00050 trackMinHits_ = conf_.getParameter<double>("trackMinHits");
00051 clustersMaxDeltaEta_ = conf_.getParameter<double>("clustersMaxDeltaEta");
00052 clustersMaxDeltaPhi_ = conf_.getParameter<double>("clustersMaxDeltaPhi");
00053
00054 theTrackPairFinder_ = 0;
00055 theVertexFinder_ = 0;
00056 theEcalImpactPositionFinder_ = 0;
00057
00058
00059 produces< reco::ConversionCollection >(softConversionCollection_);
00060
00061 }
00062
00063
00064 SoftConversionProducer::~SoftConversionProducer() {}
00065
00066
00067 void SoftConversionProducer::beginRun (edm::Run& r, edm::EventSetup const & theEventSetup) {
00068
00069
00070 theEventSetup.get<IdealMagneticFieldRecord>().get(theMF_);
00071
00072
00073 theTrackPairFinder_ = new ConversionTrackPairFinder ();
00074
00075
00076 theVertexFinder_ = new ConversionVertexFinder (conf_);
00077
00078
00079 theEcalImpactPositionFinder_ = new ConversionTrackEcalImpactPoint ( &(*theMF_) );
00080
00081 }
00082
00083
00084 void SoftConversionProducer::endRun (edm::Run& r, edm::EventSetup const & theEventSetup) {
00085
00086 if(theTrackPairFinder_) delete theTrackPairFinder_;
00087 if(theVertexFinder_) delete theVertexFinder_;
00088 if(theEcalImpactPositionFinder_) delete theEcalImpactPositionFinder_;
00089
00090 }
00091
00092
00093
00094 void SoftConversionProducer::produce(edm::Event& theEvent, const edm::EventSetup& theEventSetup) {
00095
00096 edm::Handle<reco::TrackCollection> outInTrkHandle;
00097 theEvent.getByLabel(conversionOITrackProducer_, outInTrkHandle);
00098
00099 edm::Handle<reco::TrackCaloClusterPtrAssociation> outInTrkClusterAssocHandle;
00100 theEvent.getByLabel( conversionOITrackProducer_, outInTrackClusterAssociationCollection_, outInTrkClusterAssocHandle);
00101
00102 edm::Handle<reco::TrackCollection> inOutTrkHandle;
00103 theEvent.getByLabel(conversionIOTrackProducer_, inOutTrkHandle);
00104
00105 edm::Handle<reco::TrackCaloClusterPtrAssociation> inOutTrkClusterAssocHandle;
00106 theEvent.getByLabel( conversionIOTrackProducer_, inOutTrackClusterAssociationCollection_, inOutTrkClusterAssocHandle);
00107
00108 edm::Handle<edm::View<reco::CaloCluster> > clusterBarrelHandle;
00109 theEvent.getByLabel(clusterBarrelCollection_, clusterBarrelHandle);
00110
00111 edm::Handle<edm::View<reco::CaloCluster> > clusterEndcapHandle;
00112 if(clusterType_ == "BasicCluster"){
00113
00114 theEvent.getByLabel(clusterEndcapCollection_, clusterEndcapHandle);
00115 }
00116
00117
00118 TrackClusterMap trackClusterMap;
00119
00120 int nTracksOI = (int) outInTrkHandle->size();
00121
00122 for(int itrk=0; itrk<nTracksOI; itrk++){
00123 reco::TrackRef tRef(outInTrkHandle,itrk);
00124 if(!trackQualityCut(tRef)) continue;
00125 reco::CaloClusterPtr cRef = (*outInTrkClusterAssocHandle)[tRef];
00126 trackClusterMap.push_back(make_pair(tRef,cRef));
00127 }
00128
00129 int nTracksIO = (int) inOutTrkHandle->size();
00130
00131 for(int itrk=0; itrk<nTracksIO; itrk++){
00132 reco::TrackRef tRef(inOutTrkHandle,itrk);
00133 if(!trackQualityCut(tRef)) continue;
00134 reco::CaloClusterPtr cRef = (*inOutTrkClusterAssocHandle)[tRef];
00135 trackClusterMap.push_back(make_pair(tRef,cRef));
00136 }
00137
00138
00139 edm::ESHandle<TransientTrackBuilder> theTransientTrackBuilder;
00140 theEventSetup.get<TransientTrackRecord>().get("TransientTrackBuilder",theTransientTrackBuilder);
00141
00142
00143 std::auto_ptr< reco::ConversionCollection > outputColl(new reco::ConversionCollection);
00144
00145
00146 TrackClusterMap::iterator iter1 = trackClusterMap.begin();
00147 TrackClusterMap::iterator iter2 = trackClusterMap.begin();
00148 TrackClusterMap::iterator iter_end = trackClusterMap.end();
00149
00150
00151
00152
00153 for( ; iter1 != iter_end; iter1++) {
00154
00155 const reco::TrackRef trk1 = iter1->first;
00156
00157 for(iter2 = iter1+1; iter2 != iter_end; iter2++) {
00158
00159 const reco::TrackRef trk2 = iter2->first;
00160 if(trk1 == trk2) continue;
00161
00162
00163 const reco::CaloClusterPtr cls1 = iter1->second;
00164 reco::TransientTrack tsk1 = theTransientTrackBuilder->build(*trk1);
00165
00166 const reco::CaloClusterPtr cls2 = iter2->second;
00167 reco::TransientTrack tsk2 = theTransientTrackBuilder->build(*trk2);
00168
00169
00170
00171
00172 if ( ( tsk1.innermostMeasurementState().globalParameters().position() - tsk2.innermostMeasurementState().globalParameters().position() ).mag() < 1e-7 &&
00173 ( tsk1.innermostMeasurementState().globalParameters().momentum() - tsk2.innermostMeasurementState().globalParameters().momentum() ).mag() < 1e-7 ) continue;
00174
00175
00176 double dEta = std::abs(cls1->position().Eta() - cls2->position().Eta());
00177 if(dEta > clustersMaxDeltaEta_) continue;
00178 double dPhi = std::abs(ROOT::Math::VectorUtil::DeltaPhi(cls1->position(),cls2->position()));
00179 if(dPhi > clustersMaxDeltaPhi_) continue;
00180
00181 std::vector<reco::TransientTrack> toBeFitted;
00182 toBeFitted.push_back(tsk1);
00183 toBeFitted.push_back(tsk2);
00184
00185
00186 TwoTrackMinimumDistance md;
00187 md.calculate ( tsk1.initialFreeState(), tsk2.initialFreeState() );
00188 float minAppDist = md.distance();
00189
00190
00191
00192
00193 reco::Vertex theConversionVertex = (reco::Vertex) theVertexFinder_->run(toBeFitted);
00194
00195
00196 if(theConversionVertex.isValid()){
00197
00198 reco::CaloClusterPtrVector scRefs;
00199 scRefs.push_back(cls1);
00200 scRefs.push_back(cls2);
00201
00202 std::vector<reco::CaloClusterPtr> clusterRefs;
00203 clusterRefs.push_back(cls1);
00204 clusterRefs.push_back(cls2);
00205
00206 std::vector<reco::TrackRef> trkRefs;
00207 trkRefs.push_back(trk1);
00208 trkRefs.push_back(trk2);
00209
00210 std::vector<math::XYZVector> trackPin;
00211 std::vector<math::XYZVector> trackPout;
00212 trackPin.push_back( trk1->innerMomentum());
00213 trackPin.push_back( trk2->innerMomentum());
00214 trackPout.push_back( trk1->outerMomentum());
00215 trackPout.push_back( trk2->outerMomentum());
00216
00217
00218 std::vector<math::XYZPoint> trkPositionAtEcal = theEcalImpactPositionFinder_->find(toBeFitted,clusterBarrelHandle);
00219
00220 if((clusterType_ == "BasicCluster") && (std::abs(cls2->position().Eta()) > 1.5)){
00221 trkPositionAtEcal.clear();
00222 trkPositionAtEcal = theEcalImpactPositionFinder_->find(toBeFitted,clusterEndcapHandle);
00223 }
00224
00225 double dummy = -9999.;
00226 std::vector<math::XYZPoint> dummyVec;
00227 reco::Conversion newCandidate(scRefs, trkRefs, trkPositionAtEcal, theConversionVertex, clusterRefs, minAppDist,dummyVec, trackPin, trackPout, dummy );
00228
00229
00230
00231
00232 if(NotAlreadyIn(newCandidate,outputColl)) outputColl->push_back(newCandidate);
00233
00234
00235
00236
00237
00238
00239 clusterRefs.clear();
00240 trkRefs.clear();
00241 trkPositionAtEcal.clear();
00242 }
00243
00244 toBeFitted.clear();
00245
00246 }
00247 }
00248
00249
00250
00251 theEvent.put( outputColl, softConversionCollection_);
00252
00253 }
00254
00255
00256 bool SoftConversionProducer::trackQualityCut(const reco::TrackRef& trk){
00257 return (trk->numberOfValidHits() >= trackMinHits_ && trk->normalizedChi2() < trackMaxChi2_);
00258 }
00259
00260
00261 bool SoftConversionProducer::NotAlreadyIn(const reco::Conversion& thisConv,
00262 const std::auto_ptr<reco::ConversionCollection>& outputColl) const {
00263
00264 if(outputColl->size() == 0) return true;
00265
00266 reco::ConversionCollection::const_iterator it = outputColl->begin();
00267 reco::ConversionCollection::const_iterator it_end = outputColl->end();
00268 for( ; it != it_end; it++){
00269 const reco::Conversion& conv = *it;
00270 if((thisConv.tracks()[0] == conv.tracks()[0] && thisConv.tracks()[1] == conv.tracks()[1]) ||
00271 (thisConv.tracks()[0] == conv.tracks()[1] && thisConv.tracks()[1] == conv.tracks()[0]))
00272 return false;
00273 }
00274
00275 return true;
00276 }