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))
181 if (pos == keys.end() || *pos !=
key) {
182 keys.insert(pos, key);
184 blocksmap.emplace(key,
i);
187 for (
auto key : keys) {
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 {
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;
251 link(&els[i1], &els[i2], dist);
266 const unsigned index = rowsize *
std::max(type1, type2) +
std::min(type1, type2);
268 std::cout <<
" PFBlockAlgo links type1 " << type1 <<
" type2 " << type2 << std::endl;
277 importer->updateEventSetup(es);
286 ranges_.fill(std::make_pair(0, 0));
288 for (
const auto& importer : importers_) {
292 std::sort(
elements_.begin(),
elements_.end(), [](
const auto&
a,
const auto&
b) {
return a->type() <
b->type(); });
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;
Abstract base class for a PFBlock element (track, cluster...)
const LinkData & linkData() const
std::ostream & operator<<(std::ostream &out, const ALILine &li)
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
const uint16_t range(const Frame &aFrame)
tuple key
prepare the HTCondor submission files and eventually submit them
std::vector< std::unique_ptr< KDTreeLinkerBase > > kdtrees_
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 >, double > &links) const
std::vector< std::unique_ptr< BlockElementLinkerBase > > linkTests_
const std::unordered_map< std::string, reco::PFBlockElement::Type > elementTypes_
unsigned int linkTestSquare_[reco::PFBlockElement::kNBETypes][reco::PFBlockElement::kNBETypes]
void link(const reco::PFBlockElement *el1, const reco::PFBlockElement *el2, double &dist) const
check whether 2 elements are linked. Returns distance
std::vector< std::unique_ptr< BlockElementImporterBase > > importers_
reco::PFBlockCollection findBlocks()
build blocks
__host__ __device__ constexpr RandomIt lower_bound(RandomIt first, RandomIt last, const T &value, Compare comp={})
void buildElements(const edm::Event &)
bool debug_
if true, debug printouts activated
const edm::OwnVector< reco::PFBlockElement > & elements() const
void setLinkers(const std::vector< edm::ParameterSet > &)