CMS 3D CMS Logo

DDLogicalPart.cc
Go to the documentation of this file.
2 
3 #include <ostream>
4 
9 
10 class DDValue;
11 
12 void DD_NC(const DDName& n) {
13  auto& ns = LPNAMES::instance()[n.name()];
14 
15  bool alreadyIn(false);
16  for (const auto& p : ns) {
17  if (p.ns() == n.ns()) {
18  alreadyIn = true;
19  break;
20  }
21  }
22  if (!alreadyIn) {
23  ns.emplace_back(n);
24  }
25 }
26 
27 std::ostream& operator<<(std::ostream& os, const DDLogicalPart& part) {
29  if (defined.first) {
30  os << *(defined.first) << " ";
31  if (defined.second) {
32  part.rep().stream(os);
33  } else {
34  os << "* logicalpart not defined * ";
35  }
36  } else {
37  os << "* logicalpart not declared * ";
38  }
39  return os;
40 }
41 
42 // =================================================================================
43 
56 // now inlined...
57 
91  create(name);
92  DD_NC(name);
93 }
94 
108  const DDMaterial& material,
109  const DDSolid& solid,
111  : DDBase<DDName, std::unique_ptr<DDI::LogicalPart> >() {
112  create(ddname, std::make_unique<DDI::LogicalPart>(material, solid, cat));
113  DD_NC(ddname);
114 }
115 
116 DDEnums::Category DDLogicalPart::category() const { return rep().category(); }
117 
118 const DDMaterial& DDLogicalPart::material() const { return rep().material(); }
119 
120 const DDSolid& DDLogicalPart::solid() const { return rep().solid(); }
121 
175 std::vector<const DDsvalues_type*> DDLogicalPart::specifics() const {
176  std::vector<const DDsvalues_type*> result;
177  rep().specificsV(result);
178  return result;
179 }
180 
183  rep().mergedSpecificsV(result);
184  return result;
185 }
186 
187 // for internal use only
188 void DDLogicalPart::addSpecifics(const std::pair<const DDPartSelection*, const DDsvalues_type*>& s) {
189  rep().addSpecifics(s);
190 }
191 
192 void DDLogicalPart::removeSpecifics(const std::pair<DDPartSelection*, DDsvalues_type*>& s) { rep().removeSpecifics(s); }
193 
194 bool DDLogicalPart::hasDDValue(const DDValue& v) const { return rep().hasDDValue(v); }
195 
196 // finds out whether a DDLogicalPart is registered & already valid (initialized)
197 // - returns (true,""), if so; result holds the corresponding DDLogicalPart
198 // - returns (false,"some status message") otherwise
199 // - nm corresponds to a regular expression, but will be anchored ( ^regexp$ )
200 // - ns corresponds to a regular expression, but will be anchored ( ^regexp$ )
201 #include <regex.h>
202 #include <cstddef>
203 
204 namespace {
205  struct Regex {
206  explicit Regex(const std::string& s) : m_ok(false), me(s) {
207  size_t p = me.find('.');
208  m_ok = p != std::string::npos;
209  if (m_ok) {
210  if (p > 0) {
211  m_range.first = me.substr(0, p);
212  m_range.second = m_range.first + "{"; // '{' is 'z'+1
213  }
214  me = "^" + me + "$";
215  regcomp(&m_regex, me.c_str(), 0);
216  }
217  }
218 
219  ~Regex(void) {
220  if (m_ok)
221  regfree(&m_regex);
222  }
223 
224  bool empty(void) const { return me.empty(); }
225 
226  bool notRegex(void) const { return !m_ok; }
227 
228  const std::string& value(void) const { return me; }
229 
230  bool match(const std::string& s) const {
231  if (m_ok)
232  return !regexec(&m_regex, s.c_str(), 0, nullptr, 0);
233  else
234  return me == s;
235  }
236 
237  const std::pair<std::string, std::string>& range(void) const { return m_range; }
238 
239  private:
240  bool m_ok;
241  regex_t m_regex;
242  std::string me;
243  // range of me in a collating sequence
244  std::pair<std::string, std::string> m_range;
245  };
246 } // namespace
247 
248 std::pair<bool, std::string> DDIsValid(const std::string& ns,
249  const std::string& nm,
250  std::vector<DDLogicalPart>& result,
251  bool doRegex) {
252  if (!doRegex) {
253  DDName ddnm(nm, ns);
254  result.emplace_back(DDLogicalPart(ddnm));
255  return std::make_pair(true, "");
256  }
258  Regex aRegex(nm);
259  Regex aNsRegex(ns);
260  bool emptyNs = aNsRegex.empty();
261 
262  // THIS IS THE SLOW PART: I have to compare every namespace & name of every
263  // logical part with a regex-comparison .... a linear search always through the
264  // full range of logical parts!!!!
265  /*
266  Algorithm description:
267  x. empty nm and ns argument of method means: use all matching regex ^.*$
268  a. iterate over all logical part names, match against regex for names
269  b. iterate over all namespaces of names found in a & match against regex for namespaces
270  */
271  LPNAMES::value_type::const_iterator bn(LPNAMES::instance().begin()), ed(LPNAMES::instance().end());
272  typedef std::vector<LPNAMES::value_type::const_iterator> Candidates;
273  Candidates candidates;
274  if (aRegex.notRegex()) {
275  LPNAMES::value_type::const_iterator it = LPNAMES::instance().find(aRegex.value());
276  if (it != ed)
277  candidates.emplace_back(it);
278  } else {
279  if (!aRegex.range().first.empty()) {
280  bn = LPNAMES::instance().lower_bound(aRegex.range().first);
281  ed = LPNAMES::instance().upper_bound(aRegex.range().second);
282  }
283  for (LPNAMES::value_type::const_iterator it = bn; it != ed; ++it)
284  if (aRegex.match(it->first))
285  candidates.emplace_back(it);
286  }
287  for (const auto& it : candidates) {
288  //if (doit) edm::LogInfo("DDLogicalPart") << "rgx: " << aName << ' ' << it->first << ' ' << doit << std::endl;
289  std::vector<DDName>::size_type sz = it->second.size(); // no of 'compatible' namespaces
290  if (emptyNs && (sz == 1)) { // accept all logical parts in all the namespaces
291  result.emplace_back(it->second[0]);
292  //std::vector<DDName>::const_iterator nsIt(it->second.begin()), nsEd(it->second.end());
293  //for(; nsIt != nsEd; ++nsIt) {
294  // result.emplace_back(DDLogicalPart(*nsIt));
295  // edm::LogInfo("DDLogicalPart") << "DDD-WARNING: multiple namespaces match (in SpecPars PartSelector): " << *nsIt << std::endl;
296  //}
297  } else if (!emptyNs) { // only accept matching namespaces
298  std::vector<DDName>::const_iterator nsit(it->second.begin()), nsed(it->second.end());
299  for (; nsit != nsed; ++nsit) {
300  //edm::LogInfo("DDLogicalPart") << "comparing " << aNs << " with " << *nsit << std::endl;
301  bool another_doit = aNsRegex.match(nsit->ns());
302  if (another_doit) {
303  //temp.emplace_back(std::make_pair(it->first,*nsit));
304  result.emplace_back(DDLogicalPart(*nsit));
305  }
306  }
307  } else { // emtpyNs and sz>1 -> error, too ambigous
308  std::string message = "DDLogicalPart-name \"" + it->first + "\" matching regex \"" + nm +
309  "\" has been found at least in following namespaces:\n";
310  std::vector<DDName>::const_iterator vit = it->second.begin();
311  for (; vit != it->second.end(); ++vit) {
312  message += vit->ns();
313  message += " ";
314  }
315  message += "\nQualify the name with a regexp for the namespace, i.e \".*:name-regexp\" !";
316  return std::make_pair(false, message);
317  }
318  }
319  bool flag = true;
320  std::string message;
321 
322  // check whether the found logical-parts are also defined (i.e. have material, solid ...)
323  if (!result.empty()) {
324  std::vector<DDLogicalPart>::const_iterator lpit(result.begin()), lped(result.end());
325  for (; lpit != lped; ++lpit) {
326  // std::cout << "VI- " << std::string(lpit->name()) << std::endl;
327  if (!lpit->isDefined().second) {
328  message = message + "LogicalPart " + lpit->name().fullname() + " not (yet) defined!\n";
329  flag = false;
330  }
331  }
332  } else {
333  flag = false;
334  message = "No regex-match for namespace=" + ns + " name=" + nm + "\n";
335  }
336 
337  return std::make_pair(flag, message);
338 }
339 
340 const std::vector<std::pair<const DDPartSelection*, const DDsvalues_type*> >& DDLogicalPart::attachedSpecifics(
341  void) const {
342  return rep().attachedSpecifics();
343 }
void removeSpecifics(const std::pair< DDPartSelection *, DDsvalues_type *> &)
Definition: DDBase.h:10
DDsvalues_type mergedSpecifics(void) const
returns the merged-specifics, i.e. the last specified specifics of this logical-part ...
void addSpecifics(const std::pair< const DDPartSelection *, const DDsvalues_type *> &)
don&#39;t use, internal only /todo make it private
bool hasDDValue(const DDValue &) const
DDMaterial is used to define and access material information.
Definition: DDMaterial.h:45
std::ostream & operator<<(std::ostream &os, const DDLogicalPart &part)
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:17
const DDI::rep_traits< DDName, std::unique_ptr< DDI::LogicalPart > >::reference rep() const
Definition: DDBase.h:64
std::unique_ptr< T, impl::DeviceDeleter > unique_ptr
uint16_t size_type
A DDSolid represents the shape of a part.
Definition: DDSolid.h:39
static value_type & instance()
def cat(path)
Definition: eostools.py:401
std::vector< std::pair< unsigned int, DDValue > > DDsvalues_type
Definition: DDsvalues.h:12
std::pair< bool, std::string > DDIsValid(const std::string &ns, const std::string &nm, std::vector< DDLogicalPart > &result, bool doRegex)
Category
Definition: DDEnums.h:7
A DDLogicalPart aggregates information concerning material, solid and sensitveness ...
Definition: DDLogicalPart.h:93
DDEnums::Category category(void) const
Returns the categorization of the DDLogicalPart (sensitive detector element, cable, ...)
void DD_NC(const DDName &n)
std::vector< const DDsvalues_type * > specifics(void) const
returns the specific-data attached to the LogicalPart only (not to a DDExpandedNode) ...
const DDMaterial & material(void) const
Returns a reference object of the material this LogicalPart is made of.
part
Definition: HCALResponse.h:20
Definition: Assembly.h:7
const DDSolid & solid(void) const
Returns a reference object of the solid being the shape of this LogicalPart.
DDLogicalPart(void)
The default constructor provides an uninitialzed reference object.
Definition: DDLogicalPart.h:96
std::pair< const N *, bool > def_type
Definition: DDBase.h:51
const std::vector< std::pair< const DDPartSelection *, const DDsvalues_type * > > & attachedSpecifics(void) const
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
void create(const DDName &name, std::unique_ptr< DDI::LogicalPart > vals)
Definition: DDBase.h:95