CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DDFilter.cc
Go to the documentation of this file.
4 
6 { }
7 
9 { }
10 
11 // =======================================================================
12 // =======================================================================
13 
25 namespace {
26 
27 // SpecificsFilterString-comparison (sfs)
28  inline bool sfs_compare(const DDSpecificsFilter::SpecificCriterion & crit,
29  const DDsvalues_type & sv) {
30  DDsvalues_type::const_iterator it = find(sv,crit.nameVal_.id());
31  if (it == sv.end()) return false;
32  switch (crit.comp_) {
34  return ( crit.nameVal_.strings() == it->second.strings() );
36  return ( crit.nameVal_.strings() != it->second.strings() );
38  return ( it->second.strings() <= crit.nameVal_.strings() );
39  case DDCompOp::smaller:
40  return ( it->second.strings() < crit.nameVal_.strings() );
42  return ( it->second.strings() >= crit.nameVal_.strings() );
43  case DDCompOp::bigger:
44  return ( it->second.strings() > crit.nameVal_.strings() );
45  default:
46  return false;
47  }
48  return false;
49  }
50 
51  inline bool sfd_compare(const DDSpecificsFilter::SpecificCriterion & crit,
52  const DDsvalues_type & sv)
53  {
54  DDsvalues_type::const_iterator it = find(sv,crit.nameVal_.id());
55  if (it == sv.end()) return false;
56  if (it->second.isEvaluated() ) {
57  switch (crit.comp_) {
59  return (crit.nameVal_.doubles() == it->second.doubles() );
61  return (crit.nameVal_.doubles() != it->second.doubles() );
63  return ( it->second.doubles() <= crit.nameVal_.doubles() );
64  case DDCompOp::smaller:
65  return ( it->second.doubles() < crit.nameVal_.doubles() );
67  return ( it->second.doubles() >= crit.nameVal_.doubles() );
68  case DDCompOp::bigger:
69  return ( it->second.doubles() > crit.nameVal_.doubles() );
70  default:
71  return false;
72  }
73  } else {
74  edm::LogWarning("DD:Filter") << "Attempt to access a DDValue as doubles but DDValue is NOT Evaluated!"
75  << crit.nameVal_.name();
76  }
77  return false;
78  }
79 
80  inline bool sfs_compare_nm (const DDSpecificsFilter::SpecificCriterion & crit,
81  const std::vector<const DDsvalues_type *> & specs)
82  {
83  // The meaning of this is defined for each operator below.
84  bool result = false;
85 
86  // go through all specifics
87  for( const auto& spit : specs ) {
88  // go through all DDValues of the current specific.
89  for( const auto& it : *spit ) {
90 
91  size_t ci = 0; // criteria values index
92  size_t si = 0; // specs values index
93  // compare all the crit values to all the specs values when the name matches.
94 
95  while ( !result && ci < crit.nameVal_.strings().size()) {
96  if (it.second.id() == crit.nameVal_.id()) {
97  while ( !result && si < it.second.strings().size()) {
98  switch (crit.comp_) {
99  // equals means at least one value in crit matches one value
100  // in specs.
101  //
102  // not equals means that no values in crit match no values in specs
103  // (see below the ! (not))
104  //
105  // Maybe we should have an 'in' or 'contains' operator and equals would meaning
106  // would be changed to mean ALL equal.
107  case DDCompOp::equals:
108  case DDCompOp::matches:
109  case DDCompOp::not_equals:
110  case DDCompOp::not_matches:
111  result = ( crit.nameVal_.strings()[ci] == it.second.strings()[si] );
112  break;
113 
114  // less than or equals means that ALL values in specs
115  // are less than or equals ALL values in crit. therefore
116  // if even ONE is bigger, then this is false.
118  result = ( it.second.strings()[si] > crit.nameVal_.strings()[ci] );
119  break;
120 
121  // less than means that all are strictly less than, therefore
122  // if one is greater than or equal, then this is false
123  case DDCompOp::smaller:
124  result = ( it.second.strings()[si] >= crit.nameVal_.strings()[ci] );
125  break;
126 
127  // greater or equal to means that all values in specs are
128  // greater than or equals to all values in crit. therefore
129  // if even ONE is less than, then this is false
131  result = ( it.second.strings()[si] < crit.nameVal_.strings()[ci] );
132  break;
133 
134  // greater means that all values in specs are greater than
135  // all values in crit. therefore if even one is less than or
136  // equal to crit, then this is false;
137  case DDCompOp::bigger:
138  result = ( it.second.strings() <= crit.nameVal_.strings() );
139  }
140  si ++;
141  }
142 
143  if ( crit.comp_ == DDCompOp::not_equals
144  || crit.comp_ == DDCompOp::not_matches
145  || crit.comp_ == DDCompOp::smaller_equals
146  || crit.comp_ == DDCompOp::smaller
147  || crit.comp_ == DDCompOp::bigger)
148  result = !result;
149  }
150  ++ci;
151  }
152  }
153  }
154 
155  return result;
156  }
157 
158  inline bool sfd_compare_nm(const DDSpecificsFilter::SpecificCriterion & crit,
159  const std::vector<const DDsvalues_type *> & specs)
160  {
161  // The meaning of this is defined for each operator below.
162  bool result = false;
163 
164  // go through all specifics
165  for( const auto& spit : specs ) {
166  // go through all DDValues of the current specific.
167  for( const auto& it : *spit ) {
168  if ( !it.second.isEvaluated() ) {
169  edm::LogWarning("DD:Filter") << "(nm) Attempt to access a DDValue as doubles but DDValue is NOT Evaluated!"
170  << crit.nameVal_.name();
171  continue; // go on to next one, do not attempt to acess doubles()
172  }
173  size_t ci = 0; // criteria values index
174  size_t si = 0; // specs values index
175  // compare all the crit values to all the specs values when the name matches.
176 
177  while ( !result && ci < crit.nameVal_.doubles().size()) {
178  if (it.second.id() == crit.nameVal_.id()) {
179  while ( !result && si < it.second.doubles().size()) {
180  switch (crit.comp_) {
181 
182  // equals means at least one value in crit matches one value
183  // in specs.
184  //
185  // not equals means that no values in crit match no values in specs
186  // (see below the ! (not))
187  case DDCompOp::equals:
188  case DDCompOp::matches:
189  case DDCompOp::not_equals:
190  case DDCompOp::not_matches:
191  result = ( crit.nameVal_.doubles()[ci] == it.second.doubles()[si] );
192  break;
193 
194  // less than or equals means that ALL values in specs
195  // are less than or equals ALL values in crit. therefore
196  // if even ONE is bigger, then this is false.
198  result = ( it.second.doubles()[si] > crit.nameVal_.doubles()[ci] );
199  break;
200 
201  // less than means that all are strictly less than, therefore
202  // if one is greater than or equal, then this is false
203  case DDCompOp::smaller:
204  result = ( it.second.doubles()[si] >= crit.nameVal_.doubles()[ci] );
205  break;
206 
207  // greater or equal to means that all values in specs are
208  // greater than or equals to all values in crit. therefore
209  // if even ONE is less than, then this is false
211  result = ( it.second.doubles()[si] < crit.nameVal_.doubles()[ci] );
212  break;
213 
214  // greater means that all values in specs are greater than
215  // all values in crit. therefore if even one is less than or
216  // equal to crit, then this is false;
217  case DDCompOp::bigger:
218  result = ( it.second.doubles() <= crit.nameVal_.doubles() );
219  }
220  si ++;
221  }
222  if ( crit.comp_ == DDCompOp::not_equals
223  || crit.comp_ == DDCompOp::not_matches
224  || crit.comp_ == DDCompOp::smaller_equals
225  || crit.comp_ == DDCompOp::smaller
226  || crit.comp_ == DDCompOp::bigger)
227  result = !result;
228  }
229  ++ci;
230  }
231  }
232  }
233  return result;
234  }
235 }
236 
237 // ================================================================================================
239  : DDFilter()
240 { }
241 
243 
244 
245 void DDSpecificsFilter::setCriteria(const DDValue & nameVal, // name & value of a variable
246  DDCompOp op,
247  DDLogOp l,
248  bool asStrin, // compare std::strings otherwise doubles
249  bool merged // use merged-specifics or simple-specifics
250  )
251 {
252  criteria_.push_back(SpecificCriterion(nameVal,op,asStrin,merged));
253  logOps_.push_back(l);
254  }
255 
257 {
258  return accept_impl(node);
259 }
260 
262 {
263  bool result = true;
264  auto logOpIt = logOps_.begin();
265  const DDLogicalPart & logp = node.logicalPart();
266  DDsvalues_type sv;
267  std::vector<const DDsvalues_type *> specs;
268  for( auto it = begin(criteria_); it != end(criteria_); ++it, ++logOpIt ) {
269  // avoid useless evaluations
270  if ( ( result &&(*logOpIt)==DDLogOp::OR ) ||
271  ( (!result)&&(*logOpIt)==DDLogOp::AND) ) continue;
272 
273  bool locres=false;
274  if (logp.hasDDValue(it->nameVal_)) {
275 
276  if (it->merged_) {
277 
278  if (sv.empty()) node.mergedSpecificsV(sv);
279 
280  if (it->asString_) { // merged specifics & compare std::strings
281  locres = sfs_compare(*it,sv);
282  }
283  else { // merged specifics & compare doubles
284  locres = sfd_compare(*it,sv);
285  }
286  }
287  else {
288 
289  if (specs.empty()) node.specificsV(specs);
290 
291  if (it->asString_) { // non-merged specifics & compare std::strings
292  locres = sfs_compare_nm(*it, specs);
293  }
294  else { // non-merged specifics & compare doubles
295  locres = sfd_compare_nm(*it, specs);
296  }
297  }
298  }
299  if (*logOpIt==DDLogOp::AND) {
300  result &= locres;
301  }
302  else {
303  result |= locres;
304  }
305  }
306  return result;
307 }
const std::string & name(void) const
the name of the DDValue
Definition: DDValue.h:55
virtual ~DDFilter()
Definition: DDFilter.cc:8
bool hasDDValue(const DDValue &) const
const std::vector< double > & doubles() const
a reference to the double-valued values stored in the given instance of DDValue
Definition: DDValue.cc:139
DDLogOp
logical operations to obtain one result from two filter comparisons
Definition: DDFilter.h:15
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
unsigned int id(void) const
returns the ID of the DDValue
Definition: DDValue.h:49
bool accept_impl(const DDExpandedView &) const
Definition: DDFilter.cc:261
tuple node
Definition: Node.py:50
std::vector< SpecificCriterion > criteria_
Definition: DDFilter.h:71
void specificsV(std::vector< const DDsvalues_type * > &vc) const
tuple result
Definition: query.py:137
std::vector< std::pair< unsigned int, DDValue > > DDsvalues_type
std::maps an index to a DDValue. The index corresponds to the index assigned to the name of the std::...
Definition: DDsvalues.h:19
A DDLogicalPart aggregates information concerning material, solid and sensitveness ...
Definition: DDLogicalPart.h:88
#define end
Definition: vmac.h:37
const std::vector< std::string > & strings() const
a reference to the std::string-valued values stored in the given instance of DDValue ...
Definition: DDValue.h:62
std::vector< DDLogOp > logOps_
Definition: DDFilter.h:72
DDCompOp
comparison operators to be used with this filter
Definition: DDFilter.h:12
DDFilter()
Definition: DDFilter.cc:5
#define begin
Definition: vmac.h:30
A Filter accepts or rejects a DDExpandedNode based on a user-coded decision rule. ...
Definition: DDFilter.h:18
bool accept(const DDExpandedView &) const
true, if the DDExpandedNode fulfills the filter criteria
Definition: DDFilter.cc:256
const DDLogicalPart & logicalPart() const
The logical-part of the current node in the expanded-view.
Provides an exploded view of the detector (tree-view)
void setCriteria(const DDValue &nameVal, DDCompOp, DDLogOp l=DDLogOp::AND, bool asString=true, bool merged=true)
Definition: DDFilter.cc:245
void mergedSpecificsV(DDsvalues_type &res) const