CMS 3D CMS Logo

List of all members | Public Types | Public Member Functions | Private Member Functions | Private Attributes | Friends
PFBlockAlgo Class Reference

Particle Flow Algorithm. More...

#include <PFBlockAlgo.h>

Public Types

typedef std::vector< std::unique_ptr< reco::PFBlockElement > > ElementList
 
typedef std::array< std::pair< unsigned int, unsigned int >, reco::PFBlockElement::kNBETypesElementRanges
 

Public Member Functions

void buildElements (const edm::Event &)
 
reco::PFBlockCollection findBlocks ()
 build blocks More...
 
 PFBlockAlgo ()
 
void setDebug (bool debug)
 sets debug printout flag More...
 
void setImporters (const std::vector< edm::ParameterSet > &, edm::ConsumesCollector &)
 
void setLinkers (const std::vector< edm::ParameterSet > &)
 
void updateEventSetup (const edm::EventSetup &)
 
 ~PFBlockAlgo ()
 

Private Member Functions

void link (const reco::PFBlockElement *el1, const reco::PFBlockElement *el2, double &dist) const
 check whether 2 elements are linked. Returns distance More...
 
void packLinks (reco::PFBlock &block, const std::unordered_map< std::pair< unsigned int, unsigned int >, double > &links) const
 

Private Attributes

bool debug_
 if true, debug printouts activated More...
 
ElementList elements_
 
const std::unordered_map< std::string, reco::PFBlockElement::TypeelementTypes_
 
std::vector< std::unique_ptr< BlockElementImporterBase > > importers_
 
std::vector< std::unique_ptr< KDTreeLinkerBase > > kdtrees_
 
std::vector< std::unique_ptr< BlockElementLinkerBase > > linkTests_
 
unsigned int linkTestSquare_ [reco::PFBlockElement::kNBETypes][reco::PFBlockElement::kNBETypes]
 
ElementRanges ranges_
 
bool useHO_
 

Friends

std::ostream & operator<< (std::ostream &, const PFBlockAlgo &)
 

Detailed Description

Particle Flow Algorithm.

Author
Colin Bernet (rewrite/refactor by L. Gray)
Date
January 2006 (April 2014)

Definition at line 36 of file PFBlockAlgo.h.

Member Typedef Documentation

typedef std::vector<std::unique_ptr<reco::PFBlockElement> > PFBlockAlgo::ElementList

Definition at line 40 of file PFBlockAlgo.h.

typedef std::array<std::pair<unsigned int,unsigned int>,reco::PFBlockElement::kNBETypes> PFBlockAlgo::ElementRanges

Definition at line 42 of file PFBlockAlgo.h.

Constructor & Destructor Documentation

PFBlockAlgo::PFBlockAlgo ( )

Definition at line 69 of file PFBlockAlgo.cc.

References ECAL, HCAL, hcaldqm::constants::HO, and INIT_ENTRY.

69  :
70  debug_(false),
71  elementTypes_( {
72  INIT_ENTRY(PFBlockElement::TRACK),
73  INIT_ENTRY(PFBlockElement::PS1),
74  INIT_ENTRY(PFBlockElement::PS2),
77  INIT_ENTRY(PFBlockElement::GSF),
78  INIT_ENTRY(PFBlockElement::BREM),
79  INIT_ENTRY(PFBlockElement::HFEM),
80  INIT_ENTRY(PFBlockElement::HFHAD),
81  INIT_ENTRY(PFBlockElement::SC),
83  INIT_ENTRY(PFBlockElement::HGCAL)
84  } ) {}
#define INIT_ENTRY(name)
Definition: PFBlockAlgo.cc:19
const std::unordered_map< std::string, reco::PFBlockElement::Type > elementTypes_
Definition: PFBlockAlgo.h:90
bool debug_
if true, debug printouts activated
Definition: PFBlockAlgo.h:82
PFBlockAlgo::~PFBlockAlgo ( )

Definition at line 142 of file PFBlockAlgo.cc.

References gather_cfg::cout, debug_, and elements_.

142  {
143 
144 #ifdef PFLOW_DEBUG
145  if(debug_)
146  cout<<"~PFBlockAlgo - number of remaining elements: "
147  <<elements_.size()<<endl;
148 #endif
149 }
ElementList elements_
Definition: PFBlockAlgo.h:78
bool debug_
if true, debug printouts activated
Definition: PFBlockAlgo.h:82

Member Function Documentation

void PFBlockAlgo::buildElements ( const edm::Event evt)

Definition at line 299 of file PFBlockAlgo.cc.

References a, b, elements_, mps_fire::i, importers_, kdtrees_, and ranges_.

Referenced by PFBlockProducer::produce().

299  {
300  // import block elements as defined in python configuration
301  ranges_.fill(std::make_pair(0,0));
302  elements_.clear();
303  for( const auto& importer : importers_ ) {
304  importer->importToBlock(evt,elements_);
305  }
306 
307  std::sort(elements_.begin(),elements_.end(),
308  [](const auto& a, const auto& b) { return a->type() < b->type(); } );
309 
310  // list is now partitioned, so mark the boundaries so we can efficiently skip chunks
311  unsigned current_type = ( !elements_.empty() ? elements_[0]->type() : 0 );
312  unsigned last_type = ( !elements_.empty() ? elements_.back()->type() : 0 );
313  ranges_[current_type].first = 0;
314  ranges_[last_type].second = elements_.size()-1;
315  for( size_t i = 0; i < elements_.size(); ++i ) {
316  const auto the_type = elements_[i]->type();
317  if( the_type != current_type ) {
318  ranges_[the_type].first = i;
319  ranges_[current_type].second = i-1;
320  current_type = the_type;
321  }
322  }
323  // -------------- Loop over block elements ---------------------
324 
325  // Here we provide to all KDTree linkers the collections to link.
326  // Glowinski & Gouzevitch
327 
328  for (ElementList::iterator it = elements_.begin();
329  it != elements_.end(); ++it) {
330  for( const auto& kdtree : kdtrees_ ) {
331  if( (*it)->type() == kdtree->targetType() ) {
332  kdtree->insertTargetElt(it->get());
333  }
334  if( (*it)->type() == kdtree->fieldType() ) {
335  kdtree->insertFieldClusterElt(it->get());
336  }
337  }
338  }
339  //std::cout << "(new) imported: " << elements_.size() << " elements!" << std::endl;
340 }
ElementList elements_
Definition: PFBlockAlgo.h:78
std::vector< std::unique_ptr< KDTreeLinkerBase > > kdtrees_
Definition: PFBlockAlgo.h:94
ElementRanges ranges_
Definition: PFBlockAlgo.h:79
std::vector< std::unique_ptr< BlockElementImporterBase > > importers_
Definition: PFBlockAlgo.h:87
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121
reco::PFBlockCollection PFBlockAlgo::findBlocks ( )

build blocks

Definition at line 151 of file PFBlockAlgo.cc.

References gather_cfg::blocks, elements_, mps_fire::i, kdtrees_, crabWrapper::key, relativeConstraints::keys, linkTests_, linkTestSquare_, min(), p1, p2, packLinks(), and ranges_.

Referenced by PFBlockProducer::produce().

151  {
152  // Glowinski & Gouzevitch
153  for( const auto& kdtree : kdtrees_ ) {
154  kdtree->process();
155  }
156  // !Glowinski & Gouzevitch
158  // the blocks have not been passed to the event, and need to be cleared
159  blocks.reserve(elements_.size());
160 
161  QuickUnion qu(elements_.size());
162  const auto elem_size = elements_.size();
163  for( unsigned i = 0; i < elem_size; ++i ) {
164  for( unsigned j = 0; j < elem_size; ++j ) {
165  if( qu.connected(i,j) || j == i ) continue;
166  if( !linkTests_[linkTestSquare_[elements_[i]->type()][elements_[j]->type()]] ) {
167  j = ranges_[elements_[j]->type()].second;
168  continue;
169  }
170  auto p1(elements_[i].get()), p2(elements_[j].get());
171  const PFBlockElement::Type type1 = p1->type();
172  const PFBlockElement::Type type2 = p2->type();
173  const unsigned index = linkTestSquare_[type1][type2];
174  if( linkTests_[index]->linkPrefilter(p1,p2) ) {
175  const double dist = linkTests_[index]->testLink(p1,p2);
176  // compute linking info if it is possible
177  if( dist > -0.5 ) {
178  qu.unite(i,j);
179  }
180  }
181  }
182  }
183 
184  std::unordered_multimap<unsigned,unsigned> blocksmap(elements_.size());
185  std::vector<unsigned> keys;
186  keys.reserve(elements_.size());
187  for( unsigned i = 0; i < elements_.size(); ++i ) {
188  unsigned key = i;
189  while( key != qu.find(key) ) key = qu.find(key); // make sure we always find the root node...
190  auto pos = std::lower_bound(keys.begin(),keys.end(),key);
191  if( pos == keys.end() || *pos != key ) {
192  keys.insert(pos,key);
193  }
194  blocksmap.emplace(key,i);
195  }
196 
197  for( auto key : keys ) {
198  blocks.push_back( reco::PFBlock() );
199  auto range = blocksmap.equal_range(key);
200  auto& the_block = blocks.back();
201  ElementList::value_type::pointer p1(elements_[range.first->second].get());
202  the_block.addElement(p1);
203  const unsigned block_size = blocksmap.count(key) + 1;
204  //reserve up to 1M or 8MB; pay rehash cost for more
205  std::unordered_map<std::pair<unsigned int,unsigned int>, double > links(min(1000000u,block_size*block_size));
206  auto itr = range.first;
207  ++itr;
208  for( ; itr != range.second; ++itr ) {
209  ElementList::value_type::pointer p2(elements_[itr->second].get());
210  const PFBlockElement::Type type1 = p1->type();
211  const PFBlockElement::Type type2 = p2->type();
212  the_block.addElement(p2);
213  const unsigned index = linkTestSquare_[type1][type2];
214  if( nullptr != linkTests_[index] ) {
215  const double dist = linkTests_[index]->testLink(p1,p2);
216  links.emplace( std::make_pair(p1->index(), p2->index()), dist );
217  }
218  }
219  packLinks( the_block, links );
220  }
221 
222  elements_.clear();
223 
224  return blocks;
225 }
type
Definition: HCALResponse.h:21
ElementList elements_
Definition: PFBlockAlgo.h:78
std::vector< std::unique_ptr< KDTreeLinkerBase > > kdtrees_
Definition: PFBlockAlgo.h:94
T min(T a, T b)
Definition: MathUtil.h:58
std::vector< PFBlock > PFBlockCollection
collection of PFBlock objects
Definition: PFBlockFwd.h:11
double p2[4]
Definition: TauolaWrapper.h:90
void packLinks(reco::PFBlock &block, const std::unordered_map< std::pair< unsigned int, unsigned int >, double > &links) const
Definition: PFBlockAlgo.cc:228
ElementRanges ranges_
Definition: PFBlockAlgo.h:79
std::vector< std::unique_ptr< BlockElementLinkerBase > > linkTests_
Definition: PFBlockAlgo.h:91
unsigned int linkTestSquare_[reco::PFBlockElement::kNBETypes][reco::PFBlockElement::kNBETypes]
Definition: PFBlockAlgo.h:92
double p1[4]
Definition: TauolaWrapper.h:89
Block of elements.
Definition: PFBlock.h:30
void PFBlockAlgo::link ( const reco::PFBlockElement el1,
const reco::PFBlockElement el2,
double &  dist 
) const
inlineprivate

check whether 2 elements are linked. Returns distance

Definition at line 273 of file PFBlockAlgo.cc.

References constexpr, gather_cfg::cout, debug_, reco::PFBlockElement::kNBETypes, linkTests_, SiStripPI::max, min(), and reco::PFBlockElement::type().

Referenced by packLinks().

275  {
276  constexpr unsigned rowsize = reco::PFBlockElement::kNBETypes;
277  dist=-1.0;
278  const PFBlockElement::Type type1 = el1->type();
279  const PFBlockElement::Type type2 = el2->type();
280  const unsigned index = rowsize*std::max(type1,type2) + std::min(type1,type2);
281  if(debug_ ) {
282  std::cout << " PFBlockAlgo links type1 " << type1
283  << " type2 " << type2 << std::endl;
284  }
285 
286  // index is always checked in the preFilter above, no need to check here
287  dist = linkTests_[index]->testLink(el1,el2);
288 }
Type type() const
T min(T a, T b)
Definition: MathUtil.h:58
std::vector< std::unique_ptr< BlockElementLinkerBase > > linkTests_
Definition: PFBlockAlgo.h:91
bool debug_
if true, debug printouts activated
Definition: PFBlockAlgo.h:82
#define constexpr
void PFBlockAlgo::packLinks ( reco::PFBlock block,
const std::unordered_map< std::pair< unsigned int, unsigned int >, double > &  links 
) const
private

compute missing links in the blocks (the recursive procedure does not build all links)

Definition at line 228 of file PFBlockAlgo.cc.

References reco::PFBlock::bookLinkData(), constexpr, reco::PFBlock::elements(), reco::PFBlockElement::kNBETypes, link(), reco::PFBlock::linkData(), linkTests_, reco::PFBlock::setLink(), and edm::OwnVector< T, P >::size().

Referenced by findBlocks().

229  {
230  constexpr unsigned rowsize = reco::PFBlockElement::kNBETypes;
231 
233 
234  block.bookLinkData();
235  unsigned elsize = els.size();
236  //First Loop: update all link data
237  for( unsigned i1=0; i1<elsize; ++i1 ) {
238  for( unsigned i2=0; i2<i1; ++i2 ) {
239 
240  // no reflexive link
241  //if( i1==i2 ) continue;
242 
243  double dist = -1;
244 
245  bool linked = false;
246 
247  // are these elements already linked ?
248  // this can be optimized
249  const auto link_itr = links.find(std::make_pair(i2,i1));
250  if( link_itr != links.end() ) {
251  dist = link_itr->second;
252  linked = true;
253  }
254 
255  if(!linked) {
256  const PFBlockElement::Type type1 = els[i1].type();
257  const PFBlockElement::Type type2 = els[i2].type();
258  const auto minmax = std::minmax(type1,type2);
259  const unsigned index = rowsize*minmax.second + minmax.first;
260  bool bTestLink = ( nullptr == linkTests_[index] ? false : linkTests_[index]->linkPrefilter(&(els[i1]),&(els[i2])) );
261  if (bTestLink) link( & els[i1], & els[i2], dist);
262  }
263 
264  //loading link data according to link test used: RECHIT
265  //block.setLink( i1, i2, chi2, block.linkData() );
266  block.setLink( i1, i2, dist, block.linkData() );
267  }
268  }
269 
270 }
size_type size() const
Definition: OwnVector.h:264
const edm::OwnVector< reco::PFBlockElement > & elements() const
Definition: PFBlock.h:107
const LinkData & linkData() const
Definition: PFBlock.h:112
void setLink(unsigned i1, unsigned i2, double dist, LinkData &linkData, LinkTest test=LINKTEST_RECHIT) const
Definition: PFBlock.cc:26
void bookLinkData()
Definition: PFBlock.cc:20
std::vector< std::unique_ptr< BlockElementLinkerBase > > linkTests_
Definition: PFBlockAlgo.h:91
void link(const reco::PFBlockElement *el1, const reco::PFBlockElement *el2, double &dist) const
check whether 2 elements are linked. Returns distance
Definition: PFBlockAlgo.cc:273
#define constexpr
void PFBlockAlgo::setDebug ( bool  debug)
inline

sets debug printout flag

Definition at line 63 of file PFBlockAlgo.h.

References groupFilesInBlocks::block, and debug.

Referenced by PFBlockProducer::PFBlockProducer().

63 {debug_ = debug;}
#define debug
Definition: HDRShower.cc:19
bool debug_
if true, debug printouts activated
Definition: PFBlockAlgo.h:82
void PFBlockAlgo::setImporters ( const std::vector< edm::ParameterSet > &  confs,
edm::ConsumesCollector sumes 
)

Definition at line 132 of file PFBlockAlgo.cc.

References beamerCreator::create(), reco::get(), Reconstruction_hiPF_cff::importerName, importers_, and AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by PFBlockProducer::PFBlockProducer().

133  {
134  importers_.reserve(confs.size());
135  for( const auto& conf : confs ) {
136  const std::string& importerName =
137  conf.getParameter<std::string>("importerName");
138  importers_.emplace_back(BlockElementImporterFactory::get()->create(importerName,conf,sumes));
139  }
140 }
def create(alignables, pedeDump, additionalData, outputFile, config)
std::vector< std::unique_ptr< BlockElementImporterBase > > importers_
Definition: PFBlockAlgo.h:87
T get(const Candidate &c)
Definition: component.h:55
void PFBlockAlgo::setLinkers ( const std::vector< edm::ParameterSet > &  confs)

Definition at line 86 of file PFBlockAlgo.cc.

References constexpr, beamerCreator::create(), elementTypes_, Exception, reco::get(), mps_fire::i, kdtrees_, reco::PFBlockElement::kNBETypes, hltParticleFlowForJets_cfi::linkerName, linkTests_, linkTestSquare_, SiStripPI::max, min(), tablePrinter::prefix, split, AlCaHLTBitMon_QueryRunRegistry::string, and hltParticleFlowForJets_cfi::useKDTree.

Referenced by PFBlockProducer::PFBlockProducer().

86  {
87  constexpr unsigned rowsize = reco::PFBlockElement::kNBETypes;
88  for( unsigned i = 0; i < rowsize; ++i ) {
89  for( unsigned j = 0; j < rowsize; ++j ) {
90 
91  linkTestSquare_[i][j] = 0;
92  }
93  }
94  linkTests_.resize(rowsize*rowsize);
95  const std::string prefix("PFBlockElement::");
96  const std::string pfx_kdtree("KDTree");
97  for( const auto& conf : confs ) {
98  const std::string& linkerName =
99  conf.getParameter<std::string>("linkerName");
100  const std::string& linkTypeStr =
101  conf.getParameter<std::string>("linkType");
102  size_t split = linkTypeStr.find(':');
103  if( split == std::string::npos ) {
104  throw cms::Exception("MalformedLinkType")
105  << "\"" << linkTypeStr << "\" is not a valid link type definition."
106  << " This string should have the form \"linkFrom:linkTo\"";
107  }
108  std::string link1(prefix+linkTypeStr.substr(0,split));
109  std::string link2(prefix+linkTypeStr.substr(split+1,std::string::npos));
110  if( !(elementTypes_.count(link1) && elementTypes_.count(link2) ) ) {
111  throw cms::Exception("InvalidBlockElementType")
112  << "One of \"" << link1 << "\" or \"" << link2
113  << "\" are invalid block element types!";
114  }
115  const PFBlockElement::Type type1 = elementTypes_.at(link1);
116  const PFBlockElement::Type type2 = elementTypes_.at(link2);
117  const unsigned index = rowsize*std::max(type1,type2)+std::min(type1,type2);
118  linkTests_[index].reset(BlockElementLinkerFactory::get()->create(linkerName,conf));
119  linkTestSquare_[type1][type2] = index;
120  linkTestSquare_[type2][type1] = index;
121  // setup KDtree if requested
122  const bool useKDTree = conf.getParameter<bool>("useKDTree");
123  if( useKDTree ) {
124  kdtrees_.emplace_back( KDTreeLinkerFactory::get()->create(pfx_kdtree+
125  linkerName) );
126  kdtrees_.back()->setTargetType(std::min(type1,type2));
127  kdtrees_.back()->setFieldType(std::max(type1,type2));
128  }
129  }
130 }
def create(alignables, pedeDump, additionalData, outputFile, config)
const std::unordered_map< std::string, reco::PFBlockElement::Type > elementTypes_
Definition: PFBlockAlgo.h:90
std::vector< std::unique_ptr< KDTreeLinkerBase > > kdtrees_
Definition: PFBlockAlgo.h:94
T min(T a, T b)
Definition: MathUtil.h:58
std::vector< std::unique_ptr< BlockElementLinkerBase > > linkTests_
Definition: PFBlockAlgo.h:91
unsigned int linkTestSquare_[reco::PFBlockElement::kNBETypes][reco::PFBlockElement::kNBETypes]
Definition: PFBlockAlgo.h:92
double split
Definition: MVATrainer.cc:139
T get(const Candidate &c)
Definition: component.h:55
#define constexpr
void PFBlockAlgo::updateEventSetup ( const edm::EventSetup es)

Definition at line 290 of file PFBlockAlgo.cc.

References importers_.

Referenced by PFBlockProducer::beginLuminosityBlock().

290  {
291  for( auto& importer : importers_ ) {
292  importer->updateEventSetup(es);
293  }
294 }
std::vector< std::unique_ptr< BlockElementImporterBase > > importers_
Definition: PFBlockAlgo.h:87

Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  out,
const PFBlockAlgo a 
)
friend

Definition at line 342 of file PFBlockAlgo.cc.

342  {
343  if(! out) return out;
344 
345  out<<"====== Particle Flow Block Algorithm ======= ";
346  out<<endl;
347  out<<"number of unassociated elements : "<<a.elements_.size()<<endl;
348  out<<endl;
349 
350  for(auto const& element : a.elements_) {
351  out<<"\t"<< *element <<endl;
352  }
353 
354  return out;
355 }
ElementList elements_
Definition: PFBlockAlgo.h:78

Member Data Documentation

bool PFBlockAlgo::debug_
private

if true, debug printouts activated

Definition at line 82 of file PFBlockAlgo.h.

Referenced by link(), and ~PFBlockAlgo().

ElementList PFBlockAlgo::elements_
private

Definition at line 78 of file PFBlockAlgo.h.

Referenced by buildElements(), findBlocks(), operator<<(), and ~PFBlockAlgo().

const std::unordered_map<std::string,reco::PFBlockElement::Type> PFBlockAlgo::elementTypes_
private

Definition at line 90 of file PFBlockAlgo.h.

Referenced by setLinkers().

std::vector<std::unique_ptr<BlockElementImporterBase> > PFBlockAlgo::importers_
private

Definition at line 87 of file PFBlockAlgo.h.

Referenced by buildElements(), setImporters(), and updateEventSetup().

std::vector<std::unique_ptr<KDTreeLinkerBase> > PFBlockAlgo::kdtrees_
private

Definition at line 94 of file PFBlockAlgo.h.

Referenced by buildElements(), findBlocks(), and setLinkers().

std::vector<std::unique_ptr<BlockElementLinkerBase> > PFBlockAlgo::linkTests_
private

Definition at line 91 of file PFBlockAlgo.h.

Referenced by findBlocks(), link(), packLinks(), and setLinkers().

unsigned int PFBlockAlgo::linkTestSquare_[reco::PFBlockElement::kNBETypes][reco::PFBlockElement::kNBETypes]
private

Definition at line 92 of file PFBlockAlgo.h.

Referenced by findBlocks(), and setLinkers().

ElementRanges PFBlockAlgo::ranges_
private

Definition at line 79 of file PFBlockAlgo.h.

Referenced by buildElements(), and findBlocks().

bool PFBlockAlgo::useHO_
private

Definition at line 85 of file PFBlockAlgo.h.