17 #define INIT_ENTRY(name) {#name,name} 21 std::vector<unsigned> id_;
22 std::vector<unsigned> size_;
26 QuickUnion(
const unsigned NBranches) {
28 id_.resize(NBranches);
29 size_.resize(NBranches);
30 for(
unsigned i = 0;
i < NBranches; ++
i ) {
36 int count()
const {
return count_; }
38 unsigned find(
unsigned p) {
39 while( p != id_[p] ) {
46 bool connected(
unsigned p,
unsigned q) {
return find(p) ==
find(q); }
48 void unite(
unsigned p,
unsigned q) {
49 unsigned rootP =
find(p);
50 unsigned rootQ =
find(q);
53 if(size_[rootP] < size_[rootQ] ) {
54 id_[rootP] = rootQ; size_[rootQ] += size_[rootP];
56 id_[rootQ] = rootP; size_[rootP] += size_[rootQ];
87 for(
unsigned i = 0;
i < rowsize; ++
i ) {
88 for(
unsigned j = 0; j < rowsize; ++j ) {
96 for(
const auto& conf : confs ) {
101 size_t split = linkTypeStr.find(
':');
102 if( split == std::string::npos ) {
104 <<
"\"" << linkTypeStr <<
"\" is not a valid link type definition." 105 <<
" This string should have the form \"linkFrom:linkTo\"";
107 std::string link1(prefix+linkTypeStr.substr(0,split));
108 std::string link2(prefix+linkTypeStr.substr(split+1,std::string::npos));
111 <<
"One of \"" << link1 <<
"\" or \"" << link2
112 <<
"\" are invalid block element types!";
123 const bool useKDTree = conf.getParameter<
bool>(
"useKDTree");
127 kdtrees_.back()->setTargetType(std::min(type1,type2));
136 for(
const auto& conf : confs ) {
149 cout<<
"~PFBlockAlgo - number of remaining elements: " 156 for(
const auto& kdtree :
kdtrees_ ) {
167 for(
unsigned i = 0;
i < elem_size; ++
i ) {
168 for(
unsigned j = 0; j < elem_size; ++j ) {
169 if( qu.connected(
i,j) || j ==
i )
continue;
188 std::unordered_multimap<unsigned,unsigned> blocksmap(
elements_.size());
189 std::vector<unsigned>
keys;
193 while( key != qu.find(key) ) key = qu.find(key);
194 auto pos = std::lower_bound(keys.begin(),keys.end(),
key);
196 keys.insert(
pos,key);
198 blocksmap.emplace(key,
i);
203 for(
auto key : keys ) {
205 auto range = blocksmap.equal_range(
key);
206 auto& the_block =
blocks_->back();
208 the_block.addElement(p1);
209 const unsigned block_size = blocksmap.count(
key) + 1;
211 std::unordered_map<std::pair<unsigned int,unsigned int>,
PFBlockLink > links(
min(1000000u,block_size*block_size));
212 auto itr = range.first;
214 for( ; itr != range.second; ++itr ) {
218 the_block.addElement(p2);
219 linktest = PFBlock::LINKTEST_RECHIT;
224 links.emplace( std::make_pair(p1->index(), p2->index()) ,
226 p1->index(), p2->index() ) );
238 const std::unordered_map<std::pair<unsigned int,unsigned int>,
PFBlockLink>& links )
const {
244 unsigned elsize = els.
size();
246 for(
unsigned i1=0; i1<elsize; ++i1 ) {
247 for(
unsigned i2=0; i2<i1; ++i2 ) {
256 = PFBlock::LINKTEST_RECHIT;
260 const auto link_itr = links.find(std::make_pair(i2,i1));
261 if( link_itr != links.end() ) {
262 dist = link_itr->second.dist();
263 linktest = link_itr->second.test();
270 const auto minmax = std::minmax(type1,type2);
271 const unsigned index = rowsize*minmax.second + minmax.first;
274 if (bTestLink)
link( & els[i1], & els[i2], linktype, linktest, dist);
281 cout <<
"Setting link between elements " << i1 <<
" and " << i2
282 <<
" of dist =" << dist <<
" computed from link test " 309 double& dist)
const {
312 linktest = PFBlock::LINKTEST_RECHIT;
318 std::cout <<
" PFBlockAlgo links type1 " << type1
319 <<
" type2 " << type2 << std::endl;
328 importer->updateEventSetup(es);
337 ranges_.fill(std::make_pair(0,0));
344 [](
const auto&
a,
const auto&
b) {
return a->type() <
b->type(); } );
354 ranges_[current_type].first = 0;
358 if( the_type != current_type ) {
361 current_type = the_type;
369 for (ElementList::iterator it =
elements_.begin();
371 for(
const auto& kdtree :
kdtrees_ ) {
372 if( (*it)->type() == kdtree->targetType() ) {
373 kdtree->insertTargetElt(it->get());
375 if( (*it)->type() == kdtree->fieldType() ) {
376 kdtree->insertFieldClusterElt(it->get());
384 if(! out)
return out;
386 out<<
"====== Particle Flow Block Algorithm ======= ";
388 out<<
"number of unassociated elements : "<<a.
elements_.size()<<endl;
393 out<<
"\t"<<**ie <<endl;
399 const std::unique_ptr< reco::PFBlockCollection >&
blocks 403 out<<
"blocks already transfered"<<endl;
406 out<<
"number of blocks : "<<blocks->size()<<endl;
410 ib != blocks->end(); ++
ib) {
std::unique_ptr< reco::PFBlockCollection > blocks_
Abstract base class for a PFBlock element (track, cluster...)
def create(alignables, pedeDump, additionalData, outputFile, config)
ElementList::const_iterator IEC
const std::unique_ptr< reco::PFBlockCollection > & blocks() const
friend std::ostream & operator<<(std::ostream &, const PFBlockAlgo &)
const edm::OwnVector< reco::PFBlockElement > & elements() const
const LinkData & linkData() const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
void setLink(unsigned i1, unsigned i2, double dist, LinkData &linkData, LinkTest test=LINKTEST_RECHIT) const
std::vector< KDTreePtr > kdtrees_
const std::unordered_map< std::string, reco::PFBlockElement::Type > elementTypes_
void link(const reco::PFBlockElement *el1, const reco::PFBlockElement *el2, PFBlockLink::Type &linktype, reco::PFBlock::LinkTest &linktest, double &dist) const
check whether 2 elements are linked. Returns distance and linktype
void updateEventSetup(const edm::EventSetup &)
void setImporters(const std::vector< edm::ParameterSet > &, edm::ConsumesCollector &)
std::vector< PFBlock > PFBlockCollection
collection of PFBlock objects
void packLinks(reco::PFBlock &block, const std::unordered_map< std::pair< unsigned int, unsigned int >, PFBlockLink > &links) const
unsigned int linkTestSquare_[reco::PFBlockElement::kNBETypes][reco::PFBlockElement::kNBETypes]
reco::PFBlockCollection::const_iterator IBC
bool linkPrefilter(const reco::PFBlockElement *last, const reco::PFBlockElement *next) const
Avoid to check links when not useful.
void findBlocks()
build blocks
Type
possible types. WARNING: have a look at PFBlockElement
std::vector< ElementList::value_type::pointer > bare_elements_
void buildElements(const edm::Event &)
bool debug_
if true, debug printouts activated
void setLinkers(const std::vector< edm::ParameterSet > &)
std::vector< LinkTestPtr > linkTests_
T get(const Candidate &c)
std::vector< ImporterPtr > importers_