00001 #ifndef PhysicsTools_PFCandProducer_TopProjectorAlgo_
00002 #define PhysicsTools_PFCandProducer_TopProjectorAlgo_
00003
00004
00005 #include <iostream>
00006 #include <memory>
00007 #include <string>
00008
00009
00010 #include "FWCore/Framework/interface/Frameworkfwd.h"
00011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00012
00013 #include "FWCore/Framework/interface/Event.h"
00014 #include "FWCore/Framework/interface/MakerMacros.h"
00015
00016 #include "DataFormats/Provenance/interface/ProductID.h"
00017
00018 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
00019
00020 #include "DataFormats/Candidate/interface/CandidateFwd.h"
00021
00022
00030 #include <iostream>
00031
00032
00033 namespace pf2pat {
00034
00035 template< class Top, class Bottom>
00036 class TopProjectorAlgo {
00037
00038 public:
00039
00040 typedef std::vector<Top> TopCollection;
00041 typedef edm::Handle< std::vector<Top> > TopHandle;
00042 typedef std::vector<Bottom> BottomCollection;
00043 typedef edm::Handle< std::vector<Bottom> > BottomHandle;
00044 typedef edm::Ptr<Bottom> BottomPtr;
00045
00046 TopProjectorAlgo(const edm::ParameterSet&);
00047
00048 ~TopProjectorAlgo() {};
00049
00050
00051 BottomCollection produce( const TopHandle& topHandle,
00052 const BottomHandle& bottomHandle,
00053 const edm::EventBase& iEvent );
00054
00055
00056 private:
00057
00061 void
00062 ptrToAncestor( reco::CandidatePtr candRef,
00063 reco::CandidatePtrVector& ancestors,
00064 const edm::ProductID& ancestorsID,
00065 const edm::EventBase& iEvent ) const;
00066
00070 void maskAncestors( const reco::CandidatePtrVector& ancestors,
00071 std::vector<bool>& masked ) const;
00072
00073
00074 void processCollection( const edm::Handle< std::vector<Top> >& handle,
00075 const edm::Handle< std::vector<Bottom> >& allPFCandidates ,
00076 std::vector<bool>& masked,
00077 const char* objectName,
00078 const edm::EventBase& iEvent ) const;
00079
00080 void printAncestors( const reco::CandidatePtrVector& ancestors,
00081 const edm::Handle< std::vector<Bottom> >& allPFCandidates ) const;
00082
00083
00085 bool verbose_;
00086
00087
00088 std::string name_;
00089
00090 };
00091
00092
00093
00094
00095 template< class Top, class Bottom>
00096 TopProjectorAlgo< Top, Bottom >::TopProjectorAlgo(const edm::ParameterSet& iConfig) {
00097
00098 verbose_ = iConfig.getUntrackedParameter<bool>("verbose",false);
00099 name_ = iConfig.getUntrackedParameter<std::string>("name","No Name");
00100 }
00101
00102
00103 template< class Top, class Bottom >
00104 std::vector<Bottom> TopProjectorAlgo< Top, Bottom >::produce( const edm::Handle< std::vector<Top> >& tops,
00105 const edm::Handle< std::vector<Bottom> >& bottoms,
00106 const edm::EventBase& iEvent ) {
00107
00108 edm::ProductID topsID = tops.id();
00109 edm::ProductID bottomsID = bottoms.id();
00110
00111 cout<<"produce "<<tops.id()<<" "<<bottoms.id()<<endl;
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 BottomCollection bottomOutput;
00135 bottomOutput.reserve( bottoms->size() );
00136
00137
00138 BottomCollection* pBottomOutput = &bottomOutput;
00139
00140
00141
00142 vector<bool> masked( bottoms->size(), false);
00143
00144 processCollection( tops, bottoms, masked, name_.c_str(), iEvent );
00145
00146 const BottomCollection& inCands = *bottoms;
00147
00148 if(verbose_)
00149 cout<<" Remaining candidates in the bottom collection ------ "<<endl;
00150
00151 for(unsigned i=0; i<inCands.size(); i++) {
00152
00153 if(masked[i]) {
00154 if(verbose_)
00155 cout<<"X "<<i<<" "<<inCands[i]<<endl;
00156 continue;
00157 }
00158 else {
00159 if(verbose_)
00160 cout<<"O "<<i<<" "<<inCands[i]<<endl;
00161
00162 pBottomOutput->push_back( inCands[i] );
00163 BottomPtr motherPtr( bottoms, i );
00164 pBottomOutput->back().setSourceCandidatePtr(motherPtr);
00165 }
00166 }
00167
00168 return bottomOutput;
00169 }
00170
00171
00172
00173 template< class Top, class Bottom >
00174 void TopProjectorAlgo< Top, Bottom >::processCollection( const edm::Handle< std::vector<Top> >& tops,
00175 const edm::Handle< std::vector<Bottom> >& bottoms ,
00176 std::vector<bool>& masked,
00177 const char* objectName,
00178 const edm::EventBase& iEvent) const {
00179
00180 if( tops.isValid() && bottoms.isValid() ) {
00181 const std::vector<Top>& topCollection = *tops;
00182
00183 if(verbose_)
00184 std::cout<<" processing: "<<objectName
00185 <<" size = "<<topCollection.size()<<std::endl;
00186
00187 for(unsigned i=0; i<topCollection.size(); i++) {
00188
00189
00190 edm::Ptr<Top> ptr( tops, i);
00191 reco::CandidatePtr basePtr( ptr );
00192
00193
00194 reco::CandidatePtrVector ancestors;
00195 ptrToAncestor( basePtr,
00196 ancestors,
00197 bottoms.id(),
00198 iEvent );
00199
00200 if(verbose_) {
00201
00202
00203
00204
00205
00206
00207 std::cout<<"\t"<<topCollection[i]<<std::endl;
00208 printAncestors( ancestors, bottoms );
00209 }
00210
00211 maskAncestors( ancestors, masked );
00212 }
00213 }
00214
00215 }
00216
00217
00218 template< class Top, class Bottom >
00219 void TopProjectorAlgo<Top,Bottom>::printAncestors( const reco::CandidatePtrVector& ancestors,
00220 const edm::Handle< std::vector<Bottom> >& allPFCandidates ) const {
00221
00222
00223 std::vector<Bottom> pfs = *allPFCandidates;
00224
00225 for(unsigned i=0; i<ancestors.size(); i++) {
00226
00227 edm::ProductID id = ancestors[i].id();
00228 assert( id == allPFCandidates.id() );
00229
00230 unsigned index = ancestors[i].key();
00231 assert( index < pfs.size() );
00232
00233 std::cout<<"\t\t"<<pfs[index]<<std::endl;
00234 }
00235 }
00236
00237
00238
00239 template< class Top, class Bottom >
00240 void
00241 TopProjectorAlgo<Top,Bottom>::ptrToAncestor( reco::CandidatePtr candPtr,
00242 reco::CandidatePtrVector& ancestors,
00243 const edm::ProductID& ancestorsID,
00244 const edm::EventBase& iEvent) const {
00245
00246
00247
00248 unsigned nSources = candPtr->numberOfSourceCandidatePtrs();
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 for(unsigned i=0; i<nSources; i++) {
00260
00261 CandidatePtr mother = candPtr->sourceCandidatePtr(i);
00262
00263
00264
00265
00266
00267 if( mother.id() != ancestorsID ) {
00268
00269 ptrToAncestor( mother, ancestors, ancestorsID, iEvent );
00270 }
00271 else {
00272
00273 ancestors.push_back( mother );
00274 }
00275 }
00276 }
00277
00278
00279
00280
00281 template< class Top, class Bottom >
00282 void TopProjectorAlgo<Top,Bottom>::maskAncestors( const reco::CandidatePtrVector& ancestors,
00283 std::vector<bool>& masked ) const {
00284
00285 for(unsigned i=0; i<ancestors.size(); i++) {
00286 unsigned index = ancestors[i].key();
00287 assert( index<masked.size() );
00288
00289
00290
00291
00292
00293 masked[index] = true;
00294 }
00295 }
00296
00297 }
00298 #endif