Belle II Software  release-08-01-10
CutNodes.h
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #pragma once
10 #include <memory>
11 #include <iostream>
12 #include <functional>
13 
14 #include <framework/utilities/AbstractNodes.h>
15 #include <framework/utilities/NodeFactory.h>
16 #include <framework/logging/Logger.h>
17 
18 #include <boost/algorithm/string.hpp>
19 #include <boost/python/tuple.hpp>
20 
21 namespace py = boost::python;
22 typedef const py::tuple& Nodetuple;
23 
24 namespace Belle2 {
32  bool almostEqualDouble(const double& a, const double& b);
33 
54  template <template <typename type> class operation>
55  struct Visitor {
59  bool operator()(const double& val0, const double& val1)
60  {
61  return operation<double> {}(val0, val1);
62  }
66  bool operator()(const double& val0, const int& val1)
67  {
68  return operation<double> {}(val0, val1);
69  }
73  bool operator()(const double& val0, const bool& val1)
74  {
75  return operation<double> {}(val0, val1);
76  }
80  bool operator()(const int& val0, const int& val1)
81  {
82  return operation<int> {}(val0, val1);
83  }
87  bool operator()(const int& val0, const bool& val1)
88  {
89  return operation<int> {}(val0, val1);
90  }
94  bool operator()(const int& val0, const double& val1)
95  {
96  return operation<double> {}(val0, val1);
97  }
101  bool operator()(const bool& val0, const bool& val1)
102  {
103  return operation<bool> {}(val0, val1);
104  }
108  bool operator()(const bool& val0, const double& val1)
109  {
110  return operation<double> {}(val0, val1);
111  }
115  bool operator()(const bool& val0, const int& val1)
116  {
117  return operation<int> {}(val0, val1);
118  }
119  };
120 
125  struct EqualVisitor {
129  bool operator()(const double& val0, const double& val1)
130  {
131  return almostEqualDouble(val0, val1);
132  }
136  bool operator()(const double& val0, const int& val1)
137  {
138  return almostEqualDouble(val0, val1);
139  }
143  bool operator()(const double& val0, const bool& val1)
144  {
145  return almostEqualDouble(val0, val1);
146  }
150  bool operator()(const int& val0, const int& val1)
151  {
152  return std::equal_to<int> {}(val0, val1);
153  }
157  bool operator()(const int& val0, const bool& val1)
158  {
159  return std::equal_to<int> {}(val0, val1);
160  }
164  bool operator()(const int& val0, const double& val1)
165  {
166  return almostEqualDouble(val0, val1);
167  }
171  bool operator()(const bool& val0, const bool& val1)
172  {
173  return std::equal_to<bool> {}(val0, val1);
174  }
178  bool operator()(const bool& val0, const double& val1)
179  {
180  return almostEqualDouble(val0, val1);
181  }
185  bool operator()(const bool& val0, const int& val1)
186  {
187  return std::equal_to<int> {}(val0, val1);
188  }
189 
190  };
191 
192 
197  template<class AVariableManager>
198  class UnaryBooleanNode : public AbstractBooleanNode<AVariableManager> {
202  typedef typename AVariableManager::Object Object;
203  public:
208  bool check(const Object* p) const override
209  {
210  // Return negated result of child node evaluation if m_negation is true.
211  if (m_negation) return !m_bnode->check(p);
212 
213  return m_bnode->check(p);
214  }
215 
220  void print() const override
221  {
222  if (m_negation) std::cout << "not ";
223  if (m_bracketized) std::cout << "[";
224  m_bnode->print();
225  if (m_bracketized) std::cout << "]";
226  }
227 
232  std::string decompile() const override
233  {
234  std::stringstream stringstream;
235  if (m_negation) stringstream << "not "; // Add negation keyword
236 
237  if (m_bracketized) stringstream << "["; // Add opening bracket
238  stringstream << m_bnode->decompile();
239  if (m_bracketized) stringstream << "]"; // Add closing bracket
240 
241  return stringstream.str();
242  }
247 
248  private:
249  friend class NodeFactory; // friend declaration so that NodeFactory can call the private constructor
255  explicit UnaryBooleanNode(Nodetuple node, bool negation, bool bracketized)
256  : m_bnode{NodeFactory::compile_boolean_node<AVariableManager>(node)}, m_negation{negation}, m_bracketized{bracketized}
257  {
258  }
259 
260  std::unique_ptr<const AbstractBooleanNode<AVariableManager>> m_bnode;
261  const bool m_negation;
262  const bool
264  };
265 
266 
273  template<class AVariableManager>
274  class BinaryBooleanNode : public AbstractBooleanNode<AVariableManager> {
278  typedef typename AVariableManager::Object Object;
279  public:
285  bool check(const Object* p) const override
286  {
287 
288  switch (m_boperator) {
289  case BooleanOperator::AND:
290  return m_left_bnode->check(p) && m_right_bnode->check(p);
291  break;
292  case BooleanOperator::OR:
293  return m_left_bnode->check(p) || m_right_bnode->check(p);
294  break;
295  default:
296  throw std::runtime_error("BinaryBooleanNode has an invalid BooleanOperator");
297  }
298  return false;
299  }
300 
304  void print() const override
305  {
306  m_left_bnode->print();
308  m_right_bnode->print();
309  }
310 
315  std::string decompile() const override
316  {
317  std::stringstream stringstream;
318  stringstream << m_left_bnode->decompile(); // decompile left AbstractBooleanNode
320  stringstream << m_right_bnode->decompile(); // decompile right AbstractBooleanNode
321 
322  return stringstream.str();
323  }
328 
329  private:
330  friend class NodeFactory; // friend declaration so that NodeFactory can call the private constructor
336  explicit BinaryBooleanNode(Nodetuple left_node, Nodetuple right_node, BooleanOperator boperator)
337  : m_left_bnode{NodeFactory::compile_boolean_node<AVariableManager>(left_node)}, m_right_bnode{NodeFactory::compile_boolean_node<AVariableManager>(right_node)},
338  m_boperator{boperator}
339  {
340  }
341  std::unique_ptr<const AbstractBooleanNode<AVariableManager>> m_left_bnode;
342  std::unique_ptr<const AbstractBooleanNode<AVariableManager>> m_right_bnode;
344  };
345 
350  template<class AVariableManager>
351  class UnaryRelationalNode : public AbstractBooleanNode<AVariableManager> {
355  typedef typename AVariableManager::Object Object;
356  public:
361  bool check(const Object* p) const override
362  {
363  typename AVariableManager::VarVariant ret = m_enode->evaluate(p);
364  if (std::holds_alternative<bool>(ret)) {
365  return std::get<bool>(ret);
366  } else if (std::holds_alternative<int>(ret)) {
367  return static_cast<bool>(std::get<int>(ret));
368  } else if (std::holds_alternative<double>(ret)) {
369  if (static_cast<bool>(std::get<double>(ret))) {
370  // nan is considered false.
371  if (std::isnan(std::get<double>(ret))) {
372  return false;
373  }
374  if (std::get<double>(ret) != 1.0)
375  B2WARNING("Static casting of double value to bool in cutstring evaluation." << LogVar("Cut substring",
376  m_enode->decompile()) << LogVar(" Casted value", std::get<double>(ret)) << LogVar("Casted to", "true"));
377  } else {
378  if (std::get<double>(ret) != 0.0)
379  B2WARNING("Static casting of double value to bool in cutstring evaluation." << LogVar("Cut substring",
380  m_enode->decompile()) << LogVar(" Casted value", std::get<double>(ret)) << LogVar("Casted to", "false"));
381  }
382 
383  return static_cast<bool>(std::get<double>(ret));
384  } else {
385  throw std::runtime_error("UnaryRelationalNode should evaluate to bool.");
386  }
387  }
388 
392  void print() const override
393  {
394  m_enode->print();
395  }
396 
401  std::string decompile() const override
402  {
403  return m_enode->decompile();
404  }
409 
410  private:
411  friend class NodeFactory; // friend declaration so that NodeFactory can call the private constructor
416  explicit UnaryRelationalNode(Nodetuple node) : m_enode{NodeFactory::compile_expression_node<AVariableManager>(node)}
417  {}
418  std::unique_ptr<const AbstractExpressionNode<AVariableManager>> m_enode;
419  };
420 
426  template<class AVariableManager>
427  class BinaryRelationalNode : public AbstractBooleanNode<AVariableManager> {
431  typedef typename AVariableManager::Object Object;
432  public:
439  bool check(const Object* p) const override
440  {
441  // Get std::variant values of children node
442  typename AVariableManager::VarVariant left_eval = m_left_enode->evaluate(p);
443  typename AVariableManager::VarVariant right_eval = m_right_enode->evaluate(p);
444  switch (m_coperator) {
445  case ComparisonOperator::EQUALEQUAL:
446  return std::visit(EqualVisitor{}, left_eval, right_eval);
447  break;
448  case ComparisonOperator::GREATEREQUAL:
449  return std::visit(Visitor<std::greater_equal> {}, left_eval, right_eval);
450  break;
451  case ComparisonOperator::LESSEQUAL:
452  return std::visit(Visitor<std::less_equal> {}, left_eval, right_eval);
453  break;
454  case ComparisonOperator::GREATER:
455  return std::visit(Visitor<std::greater> {}, left_eval, right_eval);
456  break;
457  case ComparisonOperator::LESS:
458  return std::visit(Visitor<std::less> {}, left_eval, right_eval);
459  break;
460 
461  case ComparisonOperator::NOTEQUAL:
462  return !std::visit(EqualVisitor{}, left_eval, right_eval);
463  break;
464  default:
465  throw std::runtime_error("BinaryRelationalNode has an invalid ComparisonOperator.");
466  }
467  return false;
468  }
469 
473  void print() const override
474  {
475  m_left_enode->print();
477  m_right_enode->print();
478  }
483  std::string decompile() const override
484  {
485  std::stringstream stringstream;
486 
487  stringstream << m_left_enode->decompile();
489  stringstream << m_right_enode->decompile();
490 
491  return stringstream.str();
492  }
497 
498  private:
499  friend class NodeFactory; // friend declaration so that NodeFactory can call the private constructor
506  explicit BinaryRelationalNode(Nodetuple left_node, Nodetuple right_node, ComparisonOperator coperator)
507  : m_left_enode{NodeFactory::compile_expression_node<AVariableManager>(left_node)}, m_right_enode{NodeFactory::compile_expression_node<AVariableManager>(right_node)},
508  m_coperator{coperator}
509  {
510  }
511  std::unique_ptr<const AbstractExpressionNode<AVariableManager>> m_left_enode;
512  std::unique_ptr<const AbstractExpressionNode<AVariableManager>> m_right_enode;
514  };
515 
522  template<class AVariableManager>
523  class TernaryRelationalNode : public AbstractBooleanNode<AVariableManager> {
528  public:
535  bool check(const Object* p) const override
536  {
537  typename AVariableManager::VarVariant left_eval = m_left_enode->evaluate(p);
538  typename AVariableManager::VarVariant center_eval = m_center_enode->evaluate(p);
539  typename AVariableManager::VarVariant right_eval = m_right_enode->evaluate(p);
540 
541  switch (m_lc_coperator) {
542  case ComparisonOperator::EQUALEQUAL:
543  if (not std::visit(EqualVisitor {}, left_eval, center_eval)) return false;
544  break;
545  case ComparisonOperator::GREATEREQUAL:
546  if (not std::visit(Visitor<std::greater_equal> {}, left_eval, center_eval)) return false;
547  break;
548  case ComparisonOperator::LESSEQUAL:
549  if (not std::visit(Visitor<std::less_equal> {}, left_eval, center_eval)) return false;
550  break;
551  case ComparisonOperator::GREATER:
552  if (not std::visit(Visitor<std::greater> {}, left_eval, center_eval)) return false;
553  break;
554  case ComparisonOperator::LESS:
555  if (not std::visit(Visitor<std::less> {}, left_eval, center_eval)) return false;
556  break;
557  case ComparisonOperator::NOTEQUAL:
558  if (std::visit(EqualVisitor {}, left_eval, center_eval)) return false;
559  break;
560  default:
561  throw std::runtime_error("TernaryRelational has an invalid m_lc_operator");
562  }
563  switch (m_cr_coperator) {
564  case ComparisonOperator::EQUALEQUAL:
565  if (not std::visit(EqualVisitor {}, center_eval, right_eval)) return false;
566  break;
567  case ComparisonOperator::GREATEREQUAL:
568  if (not std::visit(Visitor<std::greater_equal> {}, center_eval, right_eval)) return false;
569  break;
570  case ComparisonOperator::LESSEQUAL:
571  if (not std::visit(Visitor<std::less_equal> {}, center_eval, right_eval)) return false;
572  break;
573  case ComparisonOperator::GREATER:
574  if (not std::visit(Visitor<std::greater> {}, center_eval, right_eval)) return false;
575  break;
576  case ComparisonOperator::LESS:
577  if (not std::visit(Visitor<std::less> {}, center_eval, right_eval)) return false;
578  break;
579  case ComparisonOperator::NOTEQUAL:
580  if (std::visit(EqualVisitor {}, center_eval, right_eval)) return false;
581  break;
582  default:
583  throw std::runtime_error("TernaryRelational has an invalid m_cr_operator");
584  }
585  return true;
586  }
590  void print() const override
591  {
592  m_left_enode->print();
594  m_center_enode->print();
596  m_right_enode->print();
597  }
598 
603  std::string decompile() const override
604  {
605  std::stringstream stringstream;
606  stringstream << m_left_enode->decompile();
608  stringstream << m_center_enode->decompile();
610  stringstream << m_right_enode->decompile();
611  return stringstream.str();
612  }
617 
618  private:
619  friend class NodeFactory;
628  explicit TernaryRelationalNode(Nodetuple left_node, Nodetuple center_node, Nodetuple right_node, ComparisonOperator lc_coperator,
629  ComparisonOperator cr_coperator)
630  : m_left_enode{NodeFactory::compile_expression_node<AVariableManager>(left_node)}, m_center_enode{NodeFactory::compile_expression_node<AVariableManager>(center_node)},
631  m_right_enode{NodeFactory::compile_expression_node<AVariableManager>(right_node)}, m_lc_coperator{lc_coperator},
632  m_cr_coperator{cr_coperator}
633  {
634  }
635  std::unique_ptr<const AbstractExpressionNode<AVariableManager>>
637  std::unique_ptr<const AbstractExpressionNode<AVariableManager>>
639  std::unique_ptr<const AbstractExpressionNode<AVariableManager>>
641  const ComparisonOperator
643  const ComparisonOperator
645  };
646 
652  template<class AVariableManager>
653  class UnaryExpressionNode : public AbstractExpressionNode<AVariableManager> {
658  public:
664  typename AVariableManager::VarVariant evaluate(const Object* p) const override
665  {
666  typename AVariableManager::VarVariant ret = m_enode->evaluate(p);
667  if (m_unary_minus) {
668  if (std::holds_alternative<int>(ret)) return -1 * std::get<int>(ret);
669  if (std::holds_alternative<double>(ret)) return -1.0 * std::get<double>(ret);
670  throw std::runtime_error("Attempted unary sign with boolean type value.");
671  }
672  return ret;
673  }
677  void print() const override
678  {
679  if (m_unary_minus) std::cout << "-";
680  if (m_parenthesized) std::cout << "( ";
681  m_enode->print();
682  if (m_parenthesized) std::cout << " )";
683  }
684 
689  std::string decompile() const override
690  {
691  std::stringstream stringstream;
692  if (m_unary_minus) stringstream << "-";
693  if (m_parenthesized) stringstream << "( ";
694  stringstream << m_enode->decompile();
695  if (m_parenthesized) stringstream << " )";
696  return stringstream.str();
697  }
702 
703  private:
704  friend class NodeFactory;
711  explicit UnaryExpressionNode(Nodetuple node, bool unary_minus, bool parenthesized) : m_enode{NodeFactory::compile_expression_node<AVariableManager>(node)},
712  m_unary_minus{unary_minus}, m_parenthesized{parenthesized}
713  {
714  }
715  std::unique_ptr<const AbstractExpressionNode<AVariableManager>> m_enode;
716  const bool m_unary_minus;
717  const bool m_parenthesized;
719  };
720 
725  template<class AVariableManager>
726  class BinaryExpressionNode : public AbstractExpressionNode<AVariableManager> {
730  typedef typename AVariableManager::Object Object;
731  public:
737  typename AVariableManager::VarVariant evaluate(const Object* p) const override
738  {
739  typename AVariableManager::VarVariant l_val, r_val, ret;
740  l_val = m_left_enode->evaluate(p);
741  r_val = m_right_enode->evaluate(p);
742  switch (m_aoperation) {
743  case ArithmeticOperation::PLUS:
744  if (std::holds_alternative<int>(l_val) && std::holds_alternative<int>(r_val)) {
745  ret = std::get<int>(l_val) + std::get<int>(r_val);
746  return ret;
747  } else if (std::holds_alternative<double>(l_val) && std::holds_alternative<double>(r_val)) {
748  ret = std::get<double>(l_val) + std::get<double>(r_val);
749  return ret;
750  } else if (std::holds_alternative<double>(l_val) && std::holds_alternative<int>(r_val)) {
751  ret = std::get<double>(l_val) + std::get<int>(r_val);
752  return ret;
753  } else if (std::holds_alternative<int>(l_val) && std::holds_alternative<double>(r_val)) {
754  ret = std::get<int>(l_val) + std::get<double>(r_val);
755  return ret;
756  } else {
757  throw std::runtime_error("Invalid datatypes in plus operation.");
758  }
759  break;
760  case ArithmeticOperation::MINUS:
761  if (std::holds_alternative<int>(l_val) && std::holds_alternative<int>(r_val)) {
762  ret = std::get<int>(l_val) - std::get<int>(r_val);
763  return ret;
764  } else if (std::holds_alternative<double>(l_val) && std::holds_alternative<double>(r_val)) {
765  ret = std::get<double>(l_val) - std::get<double>(r_val);
766  return ret;
767  } else if (std::holds_alternative<double>(l_val) && std::holds_alternative<int>(r_val)) {
768  ret = std::get<double>(l_val) - std::get<int>(r_val);
769  return ret;
770  } else if (std::holds_alternative<int>(l_val) && std::holds_alternative<double>(r_val)) {
771  ret = std::get<int>(l_val) - std::get<double>(r_val);
772  return ret;
773  } else {
774  throw std::runtime_error("Invalid datatypes in minus operation.");
775  }
776  break;
777  case ArithmeticOperation::PRODUCT:
778  if (std::holds_alternative<int>(l_val) && std::holds_alternative<int>(r_val)) {
779  ret = std::get<int>(l_val) * std::get<int>(r_val);
780  return ret;
781  } else if (std::holds_alternative<double>(l_val) && std::holds_alternative<double>(r_val)) {
782  ret = std::get<double>(l_val) * std::get<double>(r_val);
783  return ret;
784  } else if (std::holds_alternative<double>(l_val) && std::holds_alternative<int>(r_val)) {
785  ret = std::get<double>(l_val) * std::get<int>(r_val);
786  return ret;
787  } else if (std::holds_alternative<int>(l_val) && std::holds_alternative<double>(r_val)) {
788  ret = std::get<int>(l_val) * std::get<double>(r_val);
789  return ret;
790  } else {
791  throw std::runtime_error("Invalid datatypes in product operation.");
792  }
793  break;
794  case ArithmeticOperation::DIVISION:
795  if (std::holds_alternative<int>(l_val) && std::holds_alternative<int>(r_val)) {
796  // Always do double division
797  double d = std::get<int>(r_val);
798  ret = std::get<int>(l_val) / d;
799  return ret;
800  } else if (std::holds_alternative<double>(l_val) && std::holds_alternative<double>(r_val)) {
801  ret = std::get<double>(l_val) / std::get<double>(r_val);
802  return ret;
803  } else if (std::holds_alternative<double>(l_val) && std::holds_alternative<int>(r_val)) {
804  ret = std::get<double>(l_val) / std::get<int>(r_val);
805  return ret;
806  } else if (std::holds_alternative<int>(l_val) && std::holds_alternative<double>(r_val)) {
807  ret = std::get<int>(l_val) / std::get<double>(r_val);
808  return ret;
809  } else {
810  throw std::runtime_error("Invalid datatypes in division operation.");
811  }
812  break;
813  case ArithmeticOperation::POWER:
814  if (std::holds_alternative<int>(l_val) && std::holds_alternative<int>(r_val)) {
815  ret = std::pow(std::get<int>(l_val), std::get<int>(r_val));
816  return ret;
817  } else if (std::holds_alternative<double>(l_val) && std::holds_alternative<double>(r_val)) {
818  ret = std::pow(std::get<double>(l_val), std::get<double>(r_val));
819  return ret;
820  } else if (std::holds_alternative<double>(l_val) && std::holds_alternative<int>(r_val)) {
821  ret = std::pow(std::get<double>(l_val), std::get<int>(r_val));
822  return ret;
823  } else if (std::holds_alternative<int>(l_val) && std::holds_alternative<double>(r_val)) {
824  ret = std::pow(std::get<int>(l_val), std::get<double>(r_val));
825  return ret;
826  } else {
827  throw std::runtime_error("Invalid datatypes in power operation.");
828  }
829  break;
830  default:
831  throw std::runtime_error("Operation not valid");
832  }
833  ret = false;
834  return ret;
835  }
839  void print() const override
840  {
841  m_left_enode->print();
843  m_right_enode->print();
844  }
845 
850  std::string decompile() const override
851  {
852  std::stringstream stringstream;
853  stringstream << m_left_enode->decompile();
855  stringstream << m_right_enode->decompile();
856 
857  return stringstream.str();
858  }
863 
864  private:
865  friend class NodeFactory;
872  explicit BinaryExpressionNode(Nodetuple left_node, Nodetuple right_node, ArithmeticOperation aoperation) : m_left_enode{NodeFactory::compile_expression_node<AVariableManager>(left_node)},
873  m_right_enode{NodeFactory::compile_expression_node<AVariableManager>(right_node)}, m_aoperation{aoperation}
874  {
875  }
876  std::unique_ptr<const AbstractExpressionNode<AVariableManager>> m_left_enode;
877  std::unique_ptr<const AbstractExpressionNode<AVariableManager>> m_right_enode;
879  };
880 
885  template<class AVariableManager, typename T>
886  class DataNode : public AbstractExpressionNode<AVariableManager> {
887  private:
888  friend class NodeFactory;
897  explicit DataNode(T value) : m_value{value} {};
898  const T m_value;
899  public:
904  typename AVariableManager::VarVariant evaluate(const Object* p) const override
905  {
906  (void)p;
907  typename AVariableManager::VarVariant ret{m_value};
908  return ret;
909  }
913  void print() const override
914  {
915  std::cout << std::boolalpha;
916  std::cout << m_value;
917  }
918 
923  std::string decompile() const override
924  {
925  std::stringstream stringstream;
926  stringstream << std::boolalpha;
927  stringstream << m_value;
928  return stringstream.str();
929  }
934 
935  };
936 
940  template<class AVariableManager>
941  class IdentifierNode : public AbstractExpressionNode<AVariableManager> {
945  typedef typename AVariableManager::Object Object;
949  typedef typename AVariableManager::Var Var;
950  public:
955  typename AVariableManager::VarVariant evaluate(const Object* p) const override
956  {
957  if (m_var != nullptr) {
958  return m_var->function(p);
959  } else {
960  throw std::runtime_error("Cut string has an invalid format: Neither number nor variable name");
961  }
962  }
966  void print() const override
967  {
968  std::cout << m_name;
969  }
970 
975  std::string decompile() const override
976  {
977  return m_name;
978  }
979 
984  {
985  AVariableManager& manager = AVariableManager::Instance();
986  m_var = manager.getVariable(m_name);
987  if (m_var == nullptr) {
988  throw std::runtime_error(
989  "Cut string has an invalid format: Variable not found: " + m_name);
990  }
991  }
996 
997  private:
998  friend class NodeFactory;
1003  explicit IdentifierNode(const std::string& name) : m_name{name}, m_var{nullptr} {processVariable();}
1004  const std::string m_name;
1005  const Var* m_var;
1006  };
1007 
1012  template<class AVariableManager>
1013  class FunctionNode: public AbstractExpressionNode<AVariableManager> {
1017  typedef typename AVariableManager::Object Object;
1021  typedef typename AVariableManager::Var Var;
1022  public:
1027  typename AVariableManager::VarVariant evaluate(const Object* p) const override
1028  {
1029  return m_var->function(p);
1030  }
1034  void print() const override
1035  {
1036  std::string fullname = m_name + "(" + boost::algorithm::join(m_arguments, ", ") + ")";
1037  std::cout << fullname;
1038  }
1039 
1044  std::string decompile() const override
1045  {
1046  std::string fullname = m_name + "(" + boost::algorithm::join(m_arguments, ", ") + ")";
1047  return fullname;
1048  }
1049 
1054  {
1055  // Initialize Variable
1056  AVariableManager& manager = AVariableManager::Instance();
1057  m_var = manager.getVariable(m_name, m_arguments);
1058  if (m_var == nullptr) {
1059  auto fullname = m_name + "(" + boost::algorithm::join(m_arguments, ", ") + ")";
1060 
1061  throw std::runtime_error(
1062  "Cut string has an invalid format: Metavariable not found: " + fullname);
1063  }
1064  }
1069 
1070  private:
1071  friend class NodeFactory;
1077  explicit FunctionNode(const std::string& functionName, const std::vector<std::string>& functionArguments): m_name{functionName},
1078  m_arguments{functionArguments}
1079  {processMetaVariable();}
1080  const std::string m_name;
1081  const std::vector<std::string> m_arguments;
1082  const Var* m_var;
1083  };
1084 
1085 
1087 }
A parsed cut-string naturally has a tree shape which incorporates the infomation of operator preceden...
Definition: AbstractNodes.h:30
AVariableManager::Object Object
Template argument dependent Particle type definition.
Definition: AbstractNodes.h:35
AbstractExpressionNode Superclass for all nodes which host expressions.
Definition: AbstractNodes.h:66
AVariableManager::Var Var
Template argument dependent Variable type definition.
Definition: AbstractNodes.h:75
AVariableManager::Object Object
Template argument dependent Particle type definition.
Definition: AbstractNodes.h:71
Nodeclass with two AbstractBooleanNode as children and a Boolean Operator (AND, OR) Check() method ev...
Definition: CutNodes.h:274
BinaryBooleanNode(Nodetuple left_node, Nodetuple right_node, BooleanOperator boperator)
Definition: CutNodes.h:336
bool check(const Object *p) const override
Check if object passes this subexpression of the cut by calling check on the children nodes.
Definition: CutNodes.h:285
~BinaryBooleanNode()
Destructor.
Definition: CutNodes.h:327
std::string decompile() const override
Decompile Node back to a string.
Definition: CutNodes.h:315
std::unique_ptr< const AbstractBooleanNode< AVariableManager > > m_left_bnode
boolean subexpression of a cut
Definition: CutNodes.h:341
std::unique_ptr< const AbstractBooleanNode< AVariableManager > > m_right_bnode
boolean subexpression of a cut
Definition: CutNodes.h:342
AVariableManager::Object Object
Template argument dependent Particle type definition.
Definition: CutNodes.h:278
const BooleanOperator m_boperator
Boolean operation to be applied to the check() results of the child nodes.
Definition: CutNodes.h:343
void print() const override
Print node.
Definition: CutNodes.h:304
BinaryExpressionNode Node which connects two expression nodes with an arithemtic operation.
Definition: CutNodes.h:726
BinaryExpressionNode(Nodetuple left_node, Nodetuple right_node, ArithmeticOperation aoperation)
Constructor.
Definition: CutNodes.h:872
AVariableManager::VarVariant evaluate(const Object *p) const override
Evaluation of the child nodes and return result as a variant<double, int, bool> apply arithmetic oper...
Definition: CutNodes.h:737
~BinaryExpressionNode()
Destructor.
Definition: CutNodes.h:862
std::string decompile() const override
Decompile Node back to a string.
Definition: CutNodes.h:850
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_left_enode
left expression node
Definition: CutNodes.h:876
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_right_enode
right expression node
Definition: CutNodes.h:877
AVariableManager::Object Object
Template argument dependent Particle type definition.
Definition: CutNodes.h:730
ArithmeticOperation m_aoperation
arithmetic operation to be applied to the evaluations of left and right expressions
Definition: CutNodes.h:878
void print() const override
Print node.
Definition: CutNodes.h:839
BooleanNode which has two AbstractExpressionNodes nodes and a ComparisonOperator.
Definition: CutNodes.h:427
const ComparisonOperator m_coperator
comparison operator to be applied to the expression evaluations
Definition: CutNodes.h:513
bool check(const Object *p) const override
Evaluate the Expression children nodes which yield std::variant values.
Definition: CutNodes.h:439
~BinaryRelationalNode()
Destructor.
Definition: CutNodes.h:496
std::string decompile() const override
Decompile Node back to a string.
Definition: CutNodes.h:483
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_left_enode
subexpression of a cut
Definition: CutNodes.h:511
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_right_enode
subexpression of a cut
Definition: CutNodes.h:512
BinaryRelationalNode(Nodetuple left_node, Nodetuple right_node, ComparisonOperator coperator)
Constructor.
Definition: CutNodes.h:506
AVariableManager::Object Object
Template argument dependent Particle type definition.
Definition: CutNodes.h:431
void print() const override
Print node.
Definition: CutNodes.h:473
Template class for storing the Constants (int, double, bool) of the Cutstring.
Definition: CutNodes.h:886
const T m_value
constant of type T which is always returned by evaluate(const Object* p)
Definition: CutNodes.h:897
AVariableManager::VarVariant evaluate(const Object *p) const override
return m_value as a variant<double, int, bool>
Definition: CutNodes.h:904
DataNode(T value)
Constructor.
Definition: CutNodes.h:897
std::string decompile() const override
Decompile Node back to a string.
Definition: CutNodes.h:923
~DataNode()
Destructor.
Definition: CutNodes.h:933
AbstractExpressionNode< AVariableManager >::Object Object
Template argument dependent Particle type definition.
Definition: CutNodes.h:892
void print() const override
Print node.
Definition: CutNodes.h:913
FunctionNode Node class for handling MetaVariables in cuts.
Definition: CutNodes.h:1013
const std::vector< std::string > m_arguments
vector of string arguments of the MetaVariable
Definition: CutNodes.h:1081
AVariableManager::Var Var
Template argument dependent Variable type definition.
Definition: CutNodes.h:1021
const std::string m_name
Function name of the MetaVariable.
Definition: CutNodes.h:1080
AVariableManager::VarVariant evaluate(const Object *p) const override
evaluate m_var with p and return the result
Definition: CutNodes.h:1027
FunctionNode(const std::string &functionName, const std::vector< std::string > &functionArguments)
Constructor.
Definition: CutNodes.h:1077
void processMetaVariable()
Get MetaVariable from AVariableManager.
Definition: CutNodes.h:1053
std::string decompile() const override
Decompile Node back to a string.
Definition: CutNodes.h:1044
~FunctionNode()
Destructor.
Definition: CutNodes.h:1068
const Var * m_var
set if there was a valid variable in this cut
Definition: CutNodes.h:1082
AVariableManager::Object Object
Template argument dependent Particle type definition.
Definition: CutNodes.h:1017
void print() const override
Print node.
Definition: CutNodes.h:1034
Class which stores the name of a variable.
Definition: CutNodes.h:941
void processVariable()
Get variable from AVariableManger.
Definition: CutNodes.h:983
AVariableManager::Var Var
Template argument dependent Variable type definition.
Definition: CutNodes.h:949
~IdentifierNode()
Destructor.
Definition: CutNodes.h:995
IdentifierNode(const std::string &name)
Constructor.
Definition: CutNodes.h:1003
const std::string m_name
name of the variable
Definition: CutNodes.h:1004
AVariableManager::VarVariant evaluate(const Object *p) const override
evaluate m_var with p and return the result
Definition: CutNodes.h:955
std::string decompile() const override
Decompile Node back to a string.
Definition: CutNodes.h:975
const Var * m_var
set if there was a valid variable in this cut
Definition: CutNodes.h:1005
AVariableManager::Object Object
Template argument dependent Particle type definition.
Definition: CutNodes.h:945
void print() const override
Print node.
Definition: CutNodes.h:966
Wrapper class for static node compile functions.
Definition: NodeFactory.h:64
BooleanNode which has three AbstractExpressionNodes nodes and two ComparisonOperator.
Definition: CutNodes.h:523
const ComparisonOperator m_cr_coperator
comparison operator to be applied to the evaluations of the center and right expressions
Definition: CutNodes.h:644
bool check(const Object *p) const override
Definition: CutNodes.h:535
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_center_enode
center expression of the ternary relational expression
Definition: CutNodes.h:638
std::string decompile() const override
Decompile Node back to a string.
Definition: CutNodes.h:603
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_left_enode
left expression of the ternary relational expression
Definition: CutNodes.h:636
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_right_enode
right expression of the ternary relational expression
Definition: CutNodes.h:640
AbstractBooleanNode< AVariableManager >::Object Object
Template argument dependent Particle type definition.
Definition: CutNodes.h:527
const ComparisonOperator m_lc_coperator
comparison operator to be applied to the evaluations of the left and center expression
Definition: CutNodes.h:642
void print() const override
Print node.
Definition: CutNodes.h:590
~TernaryRelationalNode()
Destructor.
Definition: CutNodes.h:616
TernaryRelationalNode(Nodetuple left_node, Nodetuple center_node, Nodetuple right_node, ComparisonOperator lc_coperator, ComparisonOperator cr_coperator)
Constructor.
Definition: CutNodes.h:628
Nodeclass with a single AbstractBooleanNode as child.
Definition: CutNodes.h:198
const bool m_bracketized
if the boolean expression from which this node is compiled was in brackets, relevant in decompile to ...
Definition: CutNodes.h:263
bool check(const Object *p) const override
Check if Object passes this subexpression of the cut by calling check on the child node.
Definition: CutNodes.h:208
~UnaryBooleanNode()
Destructor.
Definition: CutNodes.h:246
const bool m_negation
if the evaluation of m_bnode->check(p) should be negated in check()
Definition: CutNodes.h:261
UnaryBooleanNode(Nodetuple node, bool negation, bool bracketized)
Definition: CutNodes.h:255
std::string decompile() const override
Decompile Node back to a string.
Definition: CutNodes.h:232
AVariableManager::Object Object
Template argument dependent Particle type definition.
Definition: CutNodes.h:202
std::unique_ptr< const AbstractBooleanNode< AVariableManager > > m_bnode
boolean subexpression of a cut
Definition: CutNodes.h:260
void print() const override
Print node brackets and negation keywords are added if m_bracketized, m_negation are set to true.
Definition: CutNodes.h:220
UnaryExpressionNode Node class with a single expression node as child.
Definition: CutNodes.h:653
const bool m_parenthesized
flag if expression in cut was in parenthesis
Definition: CutNodes.h:717
AVariableManager::VarVariant evaluate(const Object *p) const override
Evaluation of the child nodes and return result as a variant<double, int, bool> return negative resul...
Definition: CutNodes.h:664
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_enode
pointer to single expression node
Definition: CutNodes.h:715
const bool m_unary_minus
flag if expression evaluation should be returned times -1
Definition: CutNodes.h:716
UnaryExpressionNode(Nodetuple node, bool unary_minus, bool parenthesized)
Constructor.
Definition: CutNodes.h:711
std::string decompile() const override
Decompile Node back to a string.
Definition: CutNodes.h:689
~UnaryExpressionNode()
Destructor.
Definition: CutNodes.h:701
AbstractExpressionNode< AVariableManager >::Object Object
Template argument dependent Particle type definition.
Definition: CutNodes.h:657
void print() const override
Print node.
Definition: CutNodes.h:677
Nodeclass with a single AbstractExpressioNode as child.
Definition: CutNodes.h:351
UnaryRelationalNode(Nodetuple node)
Constructor.
Definition: CutNodes.h:416
bool check(const Object *p) const override
Evaluate the Expression Node child and assert that it is boolean.
Definition: CutNodes.h:361
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_enode
subexpression of a cut
Definition: CutNodes.h:418
std::string decompile() const override
Decompile Node back to a string.
Definition: CutNodes.h:401
AVariableManager::Object Object
Template argument dependent Particle type definition.
Definition: CutNodes.h:355
~UnaryRelationalNode()
Destructor.
Definition: CutNodes.h:408
void print() const override
Print node.
Definition: CutNodes.h:392
Class to store variables with their name which were sent to the logging service.
void injectArithmeticOperatorToStream(std::ostream &stream, const ArithmeticOperation &aoperation)
Helper functions for AbstractBooleanNode and AbstractExpressionNode print() and decompile() members S...
void injectComparisonOperatorToStream(std::ostream &stream, const ComparisonOperator &coperator)
Helper functions for AbstractBooleanNode and AbstractExpressionNode print() and decompile() members S...
void injectBooleanOperatorToStream(std::ostream &stream, const BooleanOperator &boperator)
Helper functions for AbstractBooleanNode and AbstractExpressionNode print() and decompile() members S...
ComparisonOperator
Enum for decoding the comparison operator type.
BooleanOperator
Enum for decoding the boolean operator type.
bool almostEqualDouble(const double &a, const double &b)
Helper function to test if two doubles are almost equal.
Definition: CutHelpers.cc:26
ArithmeticOperation
Enum for decoding the comparison operator type.
Abstract base class for different kinds of events.
Seperate Visitor struct for equal_to comparison of variant<double, int bool>.
Definition: CutNodes.h:125
bool operator()(const double &val0, const int &val1)
double int overload with double comparison.
Definition: CutNodes.h:136
bool operator()(const double &val0, const bool &val1)
double bool overload with double comparison.
Definition: CutNodes.h:143
bool operator()(const double &val0, const double &val1)
double double overload with double comparison.
Definition: CutNodes.h:129
bool operator()(const bool &val0, const double &val1)
bool double overload with double comparison.
Definition: CutNodes.h:178
bool operator()(const int &val0, const int &val1)
int int overload with int comparison.
Definition: CutNodes.h:150
bool operator()(const bool &val0, const int &val1)
bool int overload with int comparison.
Definition: CutNodes.h:185
bool operator()(const int &val0, const bool &val1)
int bool overload with int comparison.
Definition: CutNodes.h:157
bool operator()(const int &val0, const double &val1)
int double overload with double comparison.
Definition: CutNodes.h:164
bool operator()(const bool &val0, const bool &val1)
bool bool overload with bool comparison.
Definition: CutNodes.h:171
This is a class template which takes a template class operation as template argument.
Definition: CutNodes.h:55
bool operator()(const double &val0, const int &val1)
double int overload with double comparison.
Definition: CutNodes.h:66
bool operator()(const double &val0, const bool &val1)
double bool overload with double comparison.
Definition: CutNodes.h:73
bool operator()(const double &val0, const double &val1)
double double overload with double comparison.
Definition: CutNodes.h:59
bool operator()(const bool &val0, const double &val1)
bool double overload with double comparison.
Definition: CutNodes.h:108
bool operator()(const int &val0, const int &val1)
int int overload with int comparison.
Definition: CutNodes.h:80
bool operator()(const bool &val0, const int &val1)
bool int overload with int comparison.
Definition: CutNodes.h:115
bool operator()(const int &val0, const bool &val1)
int bool overload with int comparison.
Definition: CutNodes.h:87
bool operator()(const int &val0, const double &val1)
int double overload with double comparison.
Definition: CutNodes.h:94
bool operator()(const bool &val0, const bool &val1)
bool bool overload with bool comparison.
Definition: CutNodes.h:101