00001 #include <iostream>
00002
00003 #include "RecoParticleFlow/PFTracking/interface/PFConversionsProducer.h"
00004
00005 #include "FWCore/Framework/interface/Event.h"
00006 #include "FWCore/Framework/interface/EventSetup.h"
00007 #include "FWCore/Framework/interface/ESHandle.h"
00008 #include "FWCore/Framework/interface/MakerMacros.h"
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010 #include "FWCore/Utilities/interface/Exception.h"
00011
00012 #include "DataFormats/Common/interface/Handle.h"
00013 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
00014 #include "DataFormats/EgammaReco/interface/SuperClusterFwd.h"
00015 #include "DataFormats/ParticleFlowReco/interface/PFRecTrack.h"
00016 #include "DataFormats/ParticleFlowReco/interface/PFRecTrackFwd.h"
00017 #include "RecoEgamma/EgammaTools/interface/ConversionLikelihoodCalculator.h"
00018
00019 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00020
00021 #include "RecoParticleFlow/PFTracking/interface/PFTrackTransformer.h"
00022 #include "FWCore/Framework/interface/ESHandle.h"
00023 #include "MagneticField/Engine/interface/MagneticField.h"
00024 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00025 #include <vector>
00026
00027 using namespace std;
00028 PFConversionsProducer::PFConversionsProducer( const edm::ParameterSet& pset ) : pfTransformer_(0) {
00029
00030 conversionCollectionProducer_ = pset.getParameter<std::string>("conversionProducer");
00031 conversionCollection_ = pset.getParameter<std::string>("conversionCollection");
00032 debug_ = pset.getParameter<bool>("debug");
00033
00034 OtherConvLabels_ =pset.getParameter<std::vector< edm::InputTag > >("OtherConversionCollection");
00035 OtherOutInLabels_ =pset.getParameter<std::vector< edm::InputTag > >("OtherOutInCollection");
00036 OtherInOutLabels_ =pset.getParameter<std::vector< edm::InputTag > >("OtherInOutCollection");
00037
00038 PFConversionCollection_ = pset.getParameter<std::string>("PFConversionCollection");
00039 PFConversionRecTracks_ = pset.getParameter<std::string>("PFRecTracksFromConversions");
00040
00041
00042
00043 produces<reco::PFConversionCollection>(PFConversionCollection_);
00044 produces<reco::PFRecTrackCollection>(PFConversionRecTracks_);
00045
00046 }
00047
00048
00049
00050 PFConversionsProducer::~PFConversionsProducer() {
00051 delete pfTransformer_;
00052 }
00053
00054
00055 void PFConversionsProducer::beginJob( const edm::EventSetup& setup)
00056 {
00057
00058 nEvt_=0;
00059 edm::ESHandle<MagneticField> magneticField;
00060 setup.get<IdealMagneticFieldRecord>().get(magneticField);
00061 pfTransformer_= new PFTrackTransformer(math::XYZVector(magneticField->inTesla(GlobalPoint(0,0,0))));
00062
00063
00064 return ;
00065 }
00066
00067
00068
00069
00070
00071
00072 void PFConversionsProducer::produce( edm::Event& e, const edm::EventSetup& )
00073 {
00074
00075
00076 using namespace edm;
00077 if (debug_) std::cout <<" PFConversionsProducer Produce event: "<<e.id().event() <<" in run "<<e.id().run()<< std::endl;
00078
00079 nEvt_++;
00080
00082 Handle<reco::ConversionCollection> conversionHandle;
00083 e.getByLabel(conversionCollectionProducer_, conversionCollection_ , conversionHandle);
00084 if (! conversionHandle.isValid()) {
00085 edm::LogError("PFConversionsProducer") << "Error! Can't get the product "<<conversionCollection_.c_str();
00086 return;
00087 }
00088 const reco::ConversionCollection conversionCollection = *(conversionHandle.product());
00089
00090
00091
00092
00093 Handle<std::vector<Trajectory> > outInTrajectoryHandle;
00094 e.getByLabel("ckfOutInTracksFromConversions",outInTrajectoryHandle);
00095
00096
00097 Handle<std::vector<Trajectory> > inOutTrajectoryHandle;
00098 e.getByLabel("ckfInOutTracksFromConversions",inOutTrajectoryHandle);
00099
00100
00101
00102 Handle<reco::TrackCollection> outInTrkHandle;
00103 e.getByLabel("ckfOutInTracksFromConversions",outInTrkHandle);
00104
00105 Handle<reco::TrackCollection> inOutTrkHandle;
00106 e.getByLabel("ckfInOutTracksFromConversions",inOutTrkHandle);
00107
00108
00109
00110
00111
00112 reco::PFConversionCollection outputConversionCollection;
00113 std::auto_ptr<reco::PFConversionCollection> outputConversionCollection_p(new reco::PFConversionCollection);
00114
00115 reco::PFRecTrackCollection pfConversionRecTrackCollection;
00116 std::auto_ptr<reco::PFRecTrackCollection> pfConversionRecTrackCollection_p(new reco::PFRecTrackCollection);
00117
00118
00119 reco::PFRecTrackRefProd pfTrackRefProd = e.getRefBeforePut<reco::PFRecTrackCollection>(PFConversionRecTracks_);
00120
00121
00122 int iPfTk=0;
00123 std::vector<reco::ConversionRef> tmp;
00124 std::map<reco::CaloClusterPtr, std::vector<reco::ConversionRef> > aMap;
00125
00126
00127
00128 for( unsigned int icp = 0; icp < conversionHandle->size(); icp++) {
00129 reco::ConversionRef cpRef(reco::ConversionRef(conversionHandle,icp));
00130 std::vector<reco::TrackRef> tracks = cpRef->tracks();
00131
00132 if ( tracks.size() < 2 ) continue;
00133 reco::CaloClusterPtr aClu = cpRef->caloCluster()[0];
00134
00135 tmp.clear();
00136 for( unsigned int jcp = icp; jcp < conversionHandle->size(); jcp++) {
00137 reco::ConversionRef cp2Ref(reco::ConversionRef(conversionHandle,jcp));
00138 std::vector<reco::TrackRef> tracks2 = cp2Ref->tracks();
00139 if ( tracks.size() < 2 ) continue;
00140
00141
00142 if ( cpRef->caloCluster()[0] == cp2Ref ->caloCluster()[0] ) {
00143 if (debug_) std::cout << " PFConversionProducer Pushing back SC Energy " << aClu->energy() << " eta " << aClu->eta() << " phi " << aClu->phi() << " E/P " << cp2Ref->EoverP() << std::endl;
00144 tmp.push_back(cp2Ref);
00145 }
00146
00147
00148
00149 }
00150
00151 aMap.insert(make_pair( aClu, tmp ));
00152 }
00153
00154
00155
00156 for ( std::map<reco::CaloClusterPtr, std::vector<reco::ConversionRef> >::iterator iMap = aMap.begin(); iMap!= aMap.end(); ++iMap) {
00157 std::vector<reco::ConversionRef> conversions = iMap->second;
00158
00159
00160 float epMin=999;
00161 unsigned int iBestConv=0;
00162 for( unsigned int icp = 0; icp < conversions.size(); icp++) {
00163 reco::ConversionRef cpRef = conversions[icp];
00164 std::vector<reco::TrackRef> tracks = cpRef->tracks();
00165 if (debug_) std::cout << " PFConversionProducer This conversion candidate has track size " << tracks.size() << " E/P " << cpRef->EoverP() << std::endl;
00166 if (debug_) std::cout << " PFConversionProducer SC Energy " << cpRef->caloCluster()[0]->energy() << " eta " << cpRef->caloCluster()[0]->eta() << " phi " << cpRef->caloCluster()[0]->phi() << std::endl;
00167
00168 float px=0;
00169 float py=0;
00170 float pz=0;
00171 for (unsigned int i=0; i<tracks.size(); i++) {
00172 px+=tracks[i]->innerMomentum().x();
00173 py+=tracks[i]->innerMomentum().y();
00174 pz+=tracks[i]->innerMomentum().z();
00175 }
00176 float p=sqrt(px*px+py*py+pz*pz);
00177 float ep=fabs(1.-cpRef->caloCluster()[0]->energy()/p);
00178 if (debug_) std::cout << "icp " << icp << " 1-E/P = " << ep << " E/P " << cpRef->caloCluster()[0]->energy()/p << std::endl;
00179 if ( ep<epMin) {
00180 epMin=ep;
00181 iBestConv=icp;
00182 }
00183
00184 }
00185
00186
00187 if (debug_) std::cout<< " Best conv " << iBestConv << std::endl;
00188 reco::ConversionRef cpRef = conversions[iBestConv];
00189 std::vector<reco::TrackRef> tracks = conversions[iBestConv]->tracks();
00190
00191 fillPFConversions ( cpRef, outInTrkHandle, inOutTrkHandle, outInTrajectoryHandle, inOutTrajectoryHandle, iPfTk, pfTrackRefProd, outputConversionCollection, pfConversionRecTrackCollection);
00192
00193
00194 }
00195
00198
00199 if ((OtherConvLabels_.size()==OtherOutInLabels_.size()) &&(OtherConvLabels_.size()==OtherInOutLabels_.size())){
00200 for (uint icol=0; icol< OtherConvLabels_.size();icol++){
00201 Handle<reco::ConversionCollection> newColl;
00202 e.getByLabel(OtherConvLabels_[icol],newColl);
00203
00204
00205 Handle<std::vector<Trajectory> > outInTraj;
00206 e.getByLabel(OtherOutInLabels_[icol],outInTraj);
00207
00208
00209 Handle<std::vector<Trajectory> > inOutTraj;
00210 e.getByLabel(OtherInOutLabels_[icol],inOutTraj);
00211
00212
00213
00214 Handle<reco::TrackCollection> outInTrk;
00215 e.getByLabel(OtherOutInLabels_[icol],outInTrk);
00216
00217 Handle<reco::TrackCollection> inOutTrk;
00218 e.getByLabel(OtherInOutLabels_[icol],inOutTrk);
00219
00221
00222
00223 for( unsigned int icp = 0; icp < newColl->size(); icp++) {
00224 reco::ConversionRef cpRef(reco::ConversionRef(newColl,icp));
00225 std::vector<reco::TrackRef> tracks = cpRef->tracks();
00226
00227 if ( tracks.size() < 2 ) continue;
00228
00229 if (isNotUsed(cpRef,outputConversionCollection)){
00230
00231 fillPFConversions ( cpRef, outInTrk, inOutTrk, outInTraj, inOutTraj,
00232 iPfTk, pfTrackRefProd, outputConversionCollection,
00233 pfConversionRecTrackCollection);
00234 }
00235
00236
00237
00238 }
00239 }
00240 }
00241
00242
00243
00244 if (debug_) std::cout << " PFConversionProducer putting PFConversions in the event " << outputConversionCollection.size() << std::endl;
00245 outputConversionCollection_p->assign(outputConversionCollection.begin(),outputConversionCollection.end());
00246 e.put( outputConversionCollection_p, PFConversionCollection_ );
00247
00248 if (debug_) std::cout << " PFConversionProducer putting pfRecTracks in the event " << pfConversionRecTrackCollection.size() << std::endl;
00249 pfConversionRecTrackCollection_p->assign(pfConversionRecTrackCollection.begin(),pfConversionRecTrackCollection.end());
00250 e.put( pfConversionRecTrackCollection_p, PFConversionRecTracks_ );
00251
00252
00253
00254
00255 }
00256
00257
00258
00259 void PFConversionsProducer:: fillPFConversions ( reco::ConversionRef& cpRef,
00260 const edm::Handle<reco::TrackCollection> & outInTrkHandle,
00261 const edm::Handle<reco::TrackCollection> & inOutTrkHandle,
00262 const edm::Handle<std::vector<Trajectory> > & outInTrajectoryHandle,
00263 const edm::Handle<std::vector<Trajectory> > & inOutTrajectoryHandle,
00264 int iPfTk,
00265 reco::PFRecTrackRefProd& pfTrackRefProd,
00266 reco::PFConversionCollection& outputConversionCollection,
00267 reco::PFRecTrackCollection& pfConversionRecTrackCollection ) {
00268
00269
00270 std::vector<Trajectory> tjOIvec= *(outInTrajectoryHandle.product());
00271 std::vector<Trajectory> tjIOvec= *(inOutTrajectoryHandle.product());
00272
00273
00274 std::vector<reco::TrackRef> tracks = cpRef->tracks();
00275
00277 std::vector<reco::PFRecTrackRef> pfRecTracksRef;
00278 for (unsigned int i=0; i<tracks.size(); i++) {
00279
00280
00281
00282
00283 int nFound=0;
00284 int iOutInSize=0;
00285 for( reco::TrackCollection::const_iterator iTk = (*outInTrkHandle).begin(); iTk != (*outInTrkHandle).end(); iTk++) {
00286
00287 Trajectory traj=tjOIvec[iOutInSize];
00288 iOutInSize++;
00289
00290 if ( &(*iTk) != &(*tracks[i]) ) continue;
00291 nFound++;
00292 if (debug_) std::cout << " Found the corresponding trajectory " << std::endl;
00293
00294 reco::PFRecTrack pftrack( double(tracks[i]->charge()), reco::PFRecTrack::KF_ELCAND, i, tracks[i] );
00295
00296
00297 bool valid = pfTransformer_->addPoints( pftrack, *tracks[i], traj);
00298
00299 if(valid) {
00300 pfRecTracksRef.push_back(reco::PFRecTrackRef( pfTrackRefProd, iPfTk ));
00301 iPfTk++;
00302 pfConversionRecTrackCollection.push_back(pftrack);
00303 }
00304
00305 }
00306
00307 if (nFound==0) {
00308
00309
00310 int iInOutSize=0;
00311 for( reco::TrackCollection::const_iterator iTk = (*inOutTrkHandle).begin(); iTk != (*inOutTrkHandle).end(); iTk++) {
00312
00313 Trajectory traj=tjIOvec[iInOutSize];
00314 iInOutSize++;
00315
00316 if ( &(*iTk) != &(*tracks[i]) ) continue;
00317 if (debug_) std::cout << " Found the correspnding trajectory " << std::endl;
00318
00319 reco::PFRecTrack pftrack( double(tracks[i]->charge()), reco::PFRecTrack::KF_ELCAND, i, tracks[i] );
00320
00321
00322 bool valid = pfTransformer_->addPoints( pftrack, *tracks[i], traj);
00323
00324 if(valid) {
00325 pfRecTracksRef.push_back(reco::PFRecTrackRef( pfTrackRefProd, iPfTk ));
00326 iPfTk++;
00327 pfConversionRecTrackCollection.push_back(pftrack);
00328 }
00329
00330 }
00331 }
00332 }
00333
00334
00335 reco::PFConversion pfConversion(cpRef, pfRecTracksRef);
00336 outputConversionCollection.push_back(pfConversion);
00337
00338
00339
00340
00341 }
00342
00343
00344
00345 void PFConversionsProducer::endJob()
00346 {
00347
00348
00349
00350 edm::LogInfo("PFConversionProducer") << "Analyzed " << nEvt_ << "\n";
00351
00352 std::cout << "PFConversionProducer::endJob Analyzed " << nEvt_ << " events " << "\n";
00353
00354 return ;
00355 }
00356
00357 bool PFConversionsProducer::isNotUsed(reco::ConversionRef newPf,reco::PFConversionCollection PFC){
00358 std::vector<reco::TrackRef> tracks = newPf->tracks();
00359 if (tracks.size()!=2) return false;
00360 for (uint ip=0; ip<PFC.size();ip++){
00361 std::vector<reco::TrackRef> oldTracks = PFC[ip].originalConversion()->tracks();
00362 for (uint it=0; it<2; it++){
00363 for (uint it2=0; it2<oldTracks.size(); it2++){
00364 if (SameTrack(tracks[it],oldTracks[it2])) return false;
00365 }
00366 }
00367
00368 }
00369 return true;
00370 }
00371
00372 bool PFConversionsProducer::SameTrack(reco::TrackRef t1, reco::TrackRef t2){
00373 float irec=0;
00374 float isha=0;
00375 trackingRecHit_iterator i1b= t1->recHitsBegin();
00376 trackingRecHit_iterator i1e= t1->recHitsEnd();
00377 for(;i1b!=i1e;++i1b){
00378 if (!((*i1b)->isValid())) continue;
00379 irec++;
00380 trackingRecHit_iterator i2b= t2->recHitsBegin();
00381 trackingRecHit_iterator i2e= t2->recHitsEnd();
00382 for(;i2b!=i2e;++i2b){
00383 if (!((*i2b)->isValid())) continue;
00384 if ((*i1b)->sharesInput(&(**i2b), TrackingRecHit::all )) isha++;
00385 }
00386 }
00387 return ((isha/irec)>0.5);
00388 }