diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReducer.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReducer.cxx index 806abfd022d81c18e47559026d19ad243b1b27a3..49c56a2e137775e9ec9a616e302272f501fa7342 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReducer.cxx +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReducer.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #include "./FastReducer.h" @@ -141,22 +141,23 @@ bool FastReducer::findInitialJetGroups(const std::vector<int>& leaves, /* Will now test the incoming jet groups against the leaf conditions. */ - + std::size_t ijg{0}; for(auto iter = groups_b; iter != groups_e; ++iter){ auto jg = *iter; if(jg.size() != 1){ - collector->collect("FastReducer", "No jet groups"); + collector->collect("FastReducer", "Initial jet group size != 1"); return false; } - - // if a jet group satisfies a condition, note the fact, and store it by index + + // if a jet group satisfies a condition, note the fact, + // and store it by index bool jg_used{false}; auto cur_jg = m_jgIndAllocator(std::vector<std::size_t>{ijg}); for(const auto& leaf: leaves){ - + m_testedBy[leaf].insert(cur_jg); if (m_conditions[leaf]->isSatisfied(jg, collector)){ jg_used= true; @@ -177,16 +178,56 @@ bool FastReducer::findInitialJetGroups(const std::vector<int>& leaves, recordJetGroup(p.first, p.second, collector); } } - + // check all leaf conditions are satisfied for (const auto& i : leaves) { - if ((m_satisfiedBy.at(i)).empty()) { return false; } + auto& satisfiedBy = m_satisfiedBy.at(i); + if (satisfiedBy.empty()) { + return false; + } } - - return true; -} + /* + For the special but important case where all leaf nodes have + the root node as a parent, check that there are enough jets + to pass the hypo. This prevents doing a long calculation + to discover that the hypo will fail. For example, if the chain + requires 10j40, and there are 5 jets that pass the condition, + each condition will be satisfied by th 5 jets, and 5^10 combinations + will be attempted in th seach for a successful combination. As there + are only 5 jets involved, such a combination does not exist. + + Such trees have a tree vector with all entries == 0. + + This check cannot be applied in the general case. For example, + if the root condition requires 4 jets, and has three children, + two of which are leaf nodes, while the other is not, then the + check will fail the event as no jets have yet ben assigned to the + second child, while the full popagation through the tree may pass the + event. + + A possible way to tighten the chck would be to forbid children to be + separated from thir parent by more than 1 generation. + */ + if (std::all_of(m_tree.cbegin(), + m_tree.cend(), + [](std::size_t i){return i == 0;})) { + + if (m_conditions[0]->capacity() > ijg) { + + if (collector){ + collector->collect("FastReducer", "too few children. root capacity " + + std::to_string(m_conditions[0]->capacity()) + + " no of children: " + std::to_string(ijg)); + } + + return false; + } + } + + return true; +} bool FastReducer::propagateJetGroups(const Collector& collector){ @@ -218,6 +259,7 @@ bool FastReducer::propagateJetGroups(const Collector& collector){ } while(!to_process.empty()){ + auto k = to_process.top(); to_process.pop(); @@ -269,7 +311,7 @@ bool FastReducer::propagate_(std::size_t child, // Edges are contructed between satisfying jet groups and the parent. // if any such edge is constructed, the calling rroutine is notified so it // can scheduling processing the parent as a child. - + std::size_t par = m_tree.parent(child); // child == 0 do not attempt to process parent of node. @@ -282,11 +324,12 @@ bool FastReducer::propagate_(std::size_t child, // eg if condition c1 is satisfied by jg11 and jg12, while its only // sibling c2 is satisfied by jg21, the external jet groups are // jg11jg21, jg12jg21. Each of these are flattened. - + + auto jg_product = JetGroupProduct(siblings, m_satisfiedBy); - + // obtain the next product of hob groups passing siblings - auto next = jg_product.next(); + auto next = jg_product.next(collector); // step through the jet groups found by combining ghe child groups // check ecach combination to see if it satisfies the parent. If so @@ -316,7 +359,7 @@ bool FastReducer::propagate_(std::size_t child, std::set<std::size_t> unique_indices(elem_jgs.begin(), elem_jgs.end()); if(unique_indices.size() != elem_jgs.size()){ - next = jg_product.next(); + next = jg_product.next(collector); continue; } @@ -325,7 +368,7 @@ bool FastReducer::propagate_(std::size_t child, // obtain an index for the new jet group. auto cur_jg = m_jgIndAllocator(elem_jgs); if(m_testedBy[par].find(cur_jg) != m_testedBy[par].end()){ - next = jg_product.next(); + next = jg_product.next(collector); continue; } m_testedBy[par].insert(cur_jg); @@ -344,7 +387,7 @@ bool FastReducer::propagate_(std::size_t child, if(collector){recordJetGroup(cur_jg, jg, collector);} } - next = jg_product.next(); + next = jg_product.next(collector); } if(collector and !par_satisfied){ diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReductionMatcher.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReductionMatcher.cxx index f5ca74952ced2bd30086d14c243512d770086c80..7f78b0ca100e5cb2af754bdabb1184881526a309 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReductionMatcher.cxx +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReductionMatcher.cxx @@ -47,7 +47,7 @@ FastReductionMatcher::match(const HypoJetGroupCIter& groups_b, m_conditions, m_tree, m_sharedNodes, - jetCollector, + jetCollector, collector); return std::make_optional<bool>(reducer.pass()); diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/JetGroupProduct.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/JetGroupProduct.cxx index e660ab55479b6367edce21a64097b7e6b646c608..21ce1a5e774698b2e0e4b09ee5ba7cde03866954 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/JetGroupProduct.cxx +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/JetGroupProduct.cxx @@ -4,6 +4,7 @@ #include "./JetGroupProduct.h" #include <set> +#include <string> JetGroupProduct::JetGroupProduct(const std::vector<std::size_t>& siblings, @@ -22,9 +23,18 @@ JetGroupProduct::JetGroupProduct(const std::vector<std::size_t>& siblings, m_productGen = ProductGen(ends); } -std::optional<std::vector<std::size_t>> JetGroupProduct::next(){ +std::optional<std::vector<std::size_t>> +JetGroupProduct::next(const Collector& collector){ + unsigned int ipass{0}; + while(true){ + + if(collector){ + collector->collect("JobGroupProduct::next()", + "loop start pass" + std::to_string(ipass++)); + } + auto opt_indices = m_productGen.next(); if(!opt_indices.has_value()){ return std::optional<std::vector<std::size_t>>(); @@ -33,8 +43,8 @@ std::optional<std::vector<std::size_t>> JetGroupProduct::next(){ // indices index job groups in the indJetGroups table auto indices = *opt_indices; - // select inicies from the child jet group inicies. Form a vector - // of inidices. + // select indicies from the child jet group indicies. Form a vector + // of indices. std::vector<std::size_t> jg_indices; for(std::size_t i = 0; i < indices.size(); ++i){ auto s = m_siblings[i]; @@ -44,7 +54,7 @@ std::optional<std::vector<std::size_t>> JetGroupProduct::next(){ } - // require there are no duplicate inidices - this would be + // require there are no duplicate indices - this would be // rejected by a non-sharing flow network. but remove the // case early. Sharing is handled otherwise... std::set<std::size_t> unique_indices(jg_indices.begin(), diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/JetGroupProduct.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/JetGroupProduct.h index dc31dc0772dcdfa331fe775feb5f9e64fa369eb6..0e51a85da75d0d2ba2807a1d8586062b4cfbc797 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/JetGroupProduct.h +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/JetGroupProduct.h @@ -6,12 +6,15 @@ #define TRIGHLTJETHYPO_JETGROUPPRODUCT_H #include "./ProductGen.h" +#include "./DebugInfoCollector.h" #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/HypoJetDefs.h" #include <vector> #include <optional> using CondInd2JetGroupsInds = std::map<int, std::vector<std::size_t>>; +typedef std::unique_ptr<ITrigJetHypoInfoCollector> Collector; + class JetGroupProduct{ /* * Iterate through the combinations of jet groups. @@ -29,7 +32,7 @@ class JetGroupProduct{ public: JetGroupProduct(const std::vector<std::size_t>& siblings, const CondInd2JetGroupsInds& satisfiedBy); - std::optional<std::vector<std::size_t>> next(); + std::optional<std::vector<std::size_t>> next(const Collector&); private: const std::vector<std::size_t> m_siblings; diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/Tracer.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/Tracer.h new file mode 100644 index 0000000000000000000000000000000000000000..796815b49b31aaf399da95718a3a8e695f057b93 --- /dev/null +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/Tracer.h @@ -0,0 +1,20 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TRIGJETHYPO_TRACER_H +#define TRIGJETHYPO_TRACER_H + +#include <iostream> +class Tracer { +public: + Tracer(const std::string& msg): m_msg(msg){ + std::cerr<< "+ " << m_msg << '\n';} + ~Tracer() { + std::cerr << "- " <<m_msg << '\n'; + } +private: + std::string m_msg; +}; + +#endif diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/Tree.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/Tree.h index 06df1b161800954cb23bffd5ec95d944e0439a30..9cc78bfc9bf007ed067240841c6c1768a30fcdee 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/Tree.h +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/Tree.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #ifndef TRIGHLTJETHYPO_TREE_H @@ -25,6 +25,17 @@ class Tree{ const std::vector<std::size_t>& leaves() const; const std::vector<std::size_t>& firstGeneration() const; + std::vector<std::size_t>::const_iterator cbegin() const { + return m_parents.cbegin(); + } + + + std::vector<std::size_t>::const_iterator cend() const { + return m_parents.cend(); + } + + + std::size_t depth(std::size_t) const; private: