13 #include <type_traits>
19 #define INIT_ENTRY(name) \
24 std::vector<unsigned> id_;
25 std::vector<unsigned> size_;
29 QuickUnion(
const unsigned NBranches) {
31 id_.resize(NBranches);
32 size_.resize(NBranches);
33 for (
unsigned i = 0;
i < NBranches; ++
i) {
39 int count()
const {
return count_; }
41 unsigned find(
unsigned p) {
49 bool connected(
unsigned p,
unsigned q) {
return find(
p) ==
find(
q); }
51 void unite(
unsigned p,
unsigned q) {
52 unsigned rootP =
find(
p);
53 unsigned rootQ =
find(
q);
56 if (size_[rootP] < size_[rootQ]) {
58 size_[rootQ] += size_[rootP];
61 size_[rootP] += size_[rootQ];
73 elementTypes_({
INIT_ENTRY(PFBlockElement::TRACK),
88 for (
unsigned i = 0;
i < rowsize; ++
i) {
89 for (
unsigned j = 0;
j < rowsize; ++
j) {
96 for (
const auto& conf : confs) {
99 size_t split = linkTypeStr.find(
':');
100 if (
split == std::string::npos) {
101 throw cms::Exception(
"MalformedLinkType") <<
"\"" << linkTypeStr <<
"\" is not a valid link type definition."
102 <<
" This string should have the form \"linkFrom:linkTo\"";
108 <<
"One of \"" << link1 <<
"\" or \"" << link2 <<
"\" are invalid block element types!";
117 const bool useKDTree = conf.getParameter<
bool>(
"useKDTree");
128 for (
const auto& conf : confs) {
137 cout <<
"~PFBlockAlgo - number of remaining elements: " <<
elements_.size() << endl;
143 for (
const auto& kdtree :
kdtrees_) {
153 for (
unsigned i = 0;
i < elem_size; ++
i) {
154 for (
unsigned j =
i + 1;
j < elem_size; ++
j) {
155 if (qu.connected(
i,
j))
175 std::unordered_multimap<unsigned, unsigned> blocksmap(
elements_.size());
176 std::vector<unsigned>
keys;
180 while (
key != qu.find(
key))
186 blocksmap.emplace(
key,
i);
191 auto range = blocksmap.equal_range(
key);
192 auto& the_block =
blocks.back();
194 the_block.addElement(
p1);
195 const unsigned block_size = blocksmap.count(
key) + 1;
197 std::unordered_map<std::pair<unsigned int, unsigned int>,
double>
links(
min(1000000u, block_size * block_size));
201 ElementList::value_type::pointer
p2(
elements_[
itr->second].get());
204 the_block.addElement(
p2);
208 links.emplace(std::make_pair(
p1->index(),
p2->index()), dist);
220 const std::unordered_map<std::pair<unsigned int, unsigned int>,
double>&
links)
const {
225 block.bookLinkData();
226 unsigned elsize = els.
size();
228 for (
unsigned i1 = 0;
i1 < elsize; ++
i1) {
229 for (
unsigned i2 = 0;
i2 <
i1; ++
i2) {
239 const auto link_itr =
links.find(std::make_pair(
i2,
i1));
240 if (link_itr !=
links.end()) {
241 dist = link_itr->second;
248 const auto minmax = std::minmax(type1, type2);
249 const unsigned index = rowsize * minmax.second + minmax.first;
270 std::cout <<
" PFBlockAlgo links type1 " << type1 <<
" type2 " << type2 << std::endl;
279 importer->updateEventSetup(es);
288 ranges_.fill(std::make_pair(0, 0));
294 std::sort(
elements_.begin(),
elements_.end(), [](
const auto&
a,
const auto&
b) {
return a->type() <
b->type(); });
299 ranges_[current_type].first = 0;
303 if (the_type != current_type) {
305 ranges_[current_type].second =
i - 1;
306 current_type = the_type;
315 for (
const auto& kdtree :
kdtrees_) {
316 if ((*it)->type() == kdtree->targetType()) {
317 kdtree->insertTargetElt(it->get());
319 if ((*it)->type() == kdtree->fieldType()) {
320 kdtree->insertFieldClusterElt(it->get());
331 out <<
"====== Particle Flow Block Algorithm ======= ";
333 out <<
"number of unassociated elements : " <<
a.elements_.size() << endl;
336 for (
auto const& element :
a.elements_) {
337 out <<
"\t" << *element << endl;