11 #include <type_traits>
17 #define INIT_ENTRY(name) \
22 std::vector<unsigned> id_;
23 std::vector<unsigned> size_;
27 QuickUnion(
const unsigned NBranches) {
29 id_.resize(NBranches);
30 size_.resize(NBranches);
31 for (
unsigned i = 0;
i < NBranches; ++
i) {
37 int count()
const {
return count_; }
39 unsigned find(
unsigned p) {
47 bool connected(
unsigned p,
unsigned q) {
return find(
p) ==
find(
q); }
49 void unite(
unsigned p,
unsigned q) {
50 unsigned rootP =
find(
p);
51 unsigned rootQ =
find(
q);
54 if (size_[rootP] < size_[rootQ]) {
56 size_[rootQ] += size_[rootP];
59 size_[rootP] += size_[rootQ];
71 elementTypes_({
INIT_ENTRY(PFBlockElement::TRACK),
86 for (
unsigned i = 0;
i < rowsize; ++
i) {
87 for (
unsigned j = 0;
j < rowsize; ++
j) {
94 for (
const auto& conf : confs) {
97 size_t split = linkTypeStr.find(
':');
98 if (
split == std::string::npos) {
99 throw cms::Exception(
"MalformedLinkType") <<
"\"" << linkTypeStr <<
"\" is not a valid link type definition."
100 <<
" This string should have the form \"linkFrom:linkTo\"";
106 <<
"One of \"" << link1 <<
"\" or \"" << link2 <<
"\" are invalid block element types!";
115 const bool useKDTree = conf.getParameter<
bool>(
"useKDTree");
126 for (
const auto& conf : confs) {
135 cout <<
"~PFBlockAlgo - number of remaining elements: " <<
elements_.size() << endl;
141 for (
const auto& kdtree :
kdtrees_) {
151 for (
unsigned i = 0;
i < elem_size; ++
i) {
152 for (
unsigned j =
i + 1;
j < elem_size; ++
j) {
153 if (qu.connected(
i,
j))
173 std::unordered_multimap<unsigned, unsigned> blocksmap(
elements_.size());
174 std::vector<unsigned>
keys;
178 while (
key != qu.find(
key))
184 blocksmap.emplace(
key,
i);
189 auto range = blocksmap.equal_range(
key);
190 auto& the_block =
blocks.back();
192 the_block.addElement(
p1);
193 const unsigned block_size = blocksmap.count(
key) + 1;
195 std::unordered_map<std::pair<unsigned int, unsigned int>,
double>
links(
min(1000000u, block_size * block_size));
196 auto itr =
range.first;
198 for (; itr !=
range.second; ++itr) {
199 ElementList::value_type::pointer
p2(
elements_[itr->second].get());
202 the_block.addElement(
p2);
206 links.emplace(std::make_pair(
p1->index(),
p2->index()), dist);
218 const std::unordered_map<std::pair<unsigned int, unsigned int>,
double>&
links)
const {
223 block.bookLinkData();
224 unsigned elsize = els.
size();
226 for (
unsigned i1 = 0;
i1 < elsize; ++
i1) {
227 for (
unsigned i2 = 0;
i2 <
i1; ++
i2) {
237 const auto link_itr =
links.find(std::make_pair(
i2,
i1));
238 if (link_itr !=
links.end()) {
239 dist = link_itr->second;
246 const auto minmax = std::minmax(type1, type2);
247 const unsigned index = rowsize * minmax.second + minmax.first;
268 std::cout <<
" PFBlockAlgo links type1 " << type1 <<
" type2 " << type2 << std::endl;
277 importer->updateEventSetup(es);
286 ranges_.fill(std::make_pair(0, 0));
297 ranges_[current_type].first = 0;
301 if (the_type != current_type) {
303 ranges_[current_type].second =
i - 1;
304 current_type = the_type;
313 for (
const auto& kdtree :
kdtrees_) {
314 if ((*it)->type() == kdtree->targetType()) {
315 kdtree->insertTargetElt(it->get());
317 if ((*it)->type() == kdtree->fieldType()) {
318 kdtree->insertFieldClusterElt(it->get());
329 out <<
"====== Particle Flow Block Algorithm ======= ";
331 out <<
"number of unassociated elements : " <<
a.elements_.size() << endl;
334 for (
auto const& element :
a.elements_) {
335 out <<
"\t" << *element << endl;