ATLAS Offline Software
Loading...
Searching...
No Matches
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
11namespace 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;
127 print_position(input, i, &log);
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
#define endmsg
static void print_position(const std::string &input, const unsigned int &position, MsgStream *msgStr)
static std::unique_ptr< RegionSelectorBase > GetRegion(const std::string &input)
create a region from a string
static std::unique_ptr< RegionSelectorBase > process_region(const std::string &input, unsigned int &i, bool is_in_braces)
singleton-like access to IMessageSvc via open function and helper
IMessageSvc * getMessageSvc(bool quiet=false)
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.