ATLAS Offline Software
RegionSelectorBase.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
10 
11 namespace MuonCalib {
12 
13  std::unique_ptr<RegionSelectorBase> RegionSelectorBase::GetRegion(const std::string &input) {
14  unsigned int i(0);
15  return process_region(input, i, false);
16  }
17 
18  std::unique_ptr<RegionSelectorBase> RegionSelectorBase::process_region(const std::string &input, unsigned int &i, bool is_in_braces) {
19  unsigned int start_sub(i);
20  // create master region as logical operation
21  std::unique_ptr<RegionLogicalOperation> new_region = std::make_unique<RegionLogicalOperation>();
22  bool currect_inverse(false);
23  MsgStream log(Athena::getMessageSvc(), "RegionSelectorBase");
24  // loop over characters
25  for (; i < input.size(); i++) {
26  int start_element(i);
27  switch (input[i]) {
28  // read elementary region
29  case '[': {
30  std::string element;
31  int start_element(i);
32  for (; i < input.size(); i++) {
33  element.push_back(input[i]);
34  if (input[i] == ']') break;
35  }
36  if (i == input.size()) {
37  log << MSG::WARNING << "Missing ']' at end of input! Started here:" << endmsg;
38  print_position(input, start_element, &log);
39  return nullptr;
40  }
41  std::unique_ptr<RegionElement> reg_el = std::make_unique<RegionElement>();
42  // syntax error in region
43  if (!reg_el->Initialize(element)) {
44  print_position(input, start_element, &log);
45  return nullptr;
46  }
47  // add region to operation
48  if (!new_region->AddRegion(std::move(reg_el), currect_inverse)) {
49  log << MSG::WARNING << "Missing operator!" << endmsg;
50  print_position(input, start_element, &log);
51  return nullptr;
52  }
53  currect_inverse = false;
54  break;
55  }
56  // new substring - start recursive processing
57  case '(': {
58  i++;
59  if (i >= input.size()) {
60  log << MSG::WARNING << "'(' at end of input!" << endmsg;
61  print_position(input, start_element, &log);
62  return nullptr;
63  }
64  std::unique_ptr<RegionSelectorBase> second_region{process_region(input, i, true)};
65  if (!second_region) { return nullptr; }
66  if (!new_region->AddRegion(std::move(second_region), currect_inverse)) {
67  log << MSG::WARNING << "Missing operator!" << endmsg;
68  print_position(input, start_element, &log);
69  return nullptr;
70  }
71  currect_inverse = false;
72  break;
73  }
74  // invert the following region
75  case '!': {
76  if (currect_inverse) {
77  log << MSG::WARNING << "Surplus '!'" << endmsg;
78  print_position(input, start_element, &log);
79  return nullptr;
80  }
81  currect_inverse = true;
82  break;
83  }
84  // operator
85  case '&':
86  case '|': {
87  bool next_op(input[i] == '|');
88  if (!new_region->AddOperator(next_op)) {
89  log << MSG::WARNING << "Unexpected operator!" << endmsg;
90  print_position(input, start_element, &log);
91  return nullptr;
92  }
93  break;
94  }
95  // end of current subregion
96  case ')': {
97  if (new_region->SurplusOperator()) {
98  log << MSG::WARNING << "Surplus operator" << endmsg;
99  print_position(input, start_element, &log);
100  return nullptr;
101  }
102  if (is_in_braces) { return new_region; }
103  log << MSG::WARNING << "Unexpected ')'" << endmsg;
104  print_position(input, start_element, &log);
105  return nullptr;
106  }
107  // ignore whitespaces
108  case ' ':
109  case '\t':
110  case '\n':
111  break;
112  // any other characters are junk at this point
113  default:
114  log << MSG::WARNING << "Syntax Error" << endmsg;
115  print_position(input, start_element, &log);
116  return nullptr;
117  }
118  }
119  // if we ar ein a subregion and reached the end of input there is an error
120  if (is_in_braces) {
121  log << MSG::WARNING << "Missing ')'" << endmsg;
122  print_position(input, start_sub, &log);
123  return nullptr;
124  }
125  if (new_region->SurplusOperator()) {
126  log << MSG::WARNING << "Surplus operator" << endmsg;
128  return nullptr;
129  }
130  return new_region;
131  }
132 
133  void RegionSelectorBase::print_position(const std::string &input, const unsigned int &position, MsgStream *msgStr) {
134  unsigned int i(0);
135  std::string st1, st2;
136  for (; i < input.size() && i < position; i++) { st1 += input[i]; }
137  for (; i < input.size(); i++) { st2 += input[i]; }
138  *msgStr << MSG::WARNING << st1 << "*" << st2 << endmsg;
139  }
140 
141 } // namespace MuonCalib
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
MuonCalib::RegionSelectorBase::GetRegion
static std::unique_ptr< RegionSelectorBase > GetRegion(const std::string &input)
create a region from a string
Definition: RegionSelectorBase.cxx:13
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
RegionLogicalOperation.h
MuonCalib::RegionSelectorBase::print_position
static void print_position(const std::string &input, const unsigned int &position, MsgStream *msgStr)
Definition: RegionSelectorBase.cxx:133
MuonCalib::RegionSelectorBase::process_region
static std::unique_ptr< RegionSelectorBase > process_region(const std::string &input, unsigned int &i, bool is_in_braces)
Definition: RegionSelectorBase.cxx:18
lumiFormat.i
int i
Definition: lumiFormat.py:92
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
MuonCalib
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.
Definition: CscCalcPed.cxx:22
RegionSelectorBase.h
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
RegionElement.h