CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DDLogicalPart.cc
Go to the documentation of this file.
2 #include "LogicalPart.h"
4 #include <ostream>
5 
6 // Message logger.
8 
9 //DDBase<DDName,LogicalPart*>::StoreT::pointer_type
10 // DDBase<DDName,LogicalPart*>::StoreT::instance_ = 0;
11 
12 // cache to check for unique names (vs. unique namespace:name)
13 //LPNAMES::pointer_type LPNAMES::instance_ = 0;
14 
15 
16 void DD_NC(const DDName & n) {
17  std::vector<DDName> & ns = LPNAMES::instance()[n.name()];
18  typedef std::vector<DDName>::iterator IT;
19  bool alreadyIn(false);
20  for(IT p = ns.begin(); p != ns.end() ; ++p) {
21  if ( p->ns() == n.ns()) {
22  alreadyIn = true;
23  break;
24  }
25  }
26  if (!alreadyIn) {
27  ns.push_back(n);
28  }
29 }
30 
31 
32 std::ostream &
33 operator<<(std::ostream & os, const DDLogicalPart & part)
34 {
36  if (defined.first) {
37  os << *(defined.first) << " ";
38  if (defined.second) {
39  part.rep().stream(os);
40  }
41  else {
42  os << "* logicalpart not defined * ";
43  }
44  }
45  else {
46  os << "* logicalpart not declared * ";
47  }
48  return os;
49 }
50 
51 // =================================================================================
52 
65 // now inlined...
66 
99 DDLogicalPart::DDLogicalPart(const DDName & name) : DDBase<DDName,DDI::LogicalPart*>()
100 {
101  prep_ = StoreT::instance().create(name);
102  DD_NC(name);
103 }
104 
118  const DDMaterial & material,
119  const DDSolid & solid,
120  DDEnums::Category cat)
121  : DDBase<DDName,DDI::LogicalPart*>()
122 {
123  DCOUT('C', "create LogicalPart ddname=" << ddname << " mat=" << material.name() << " sol=" << solid.name());
124  prep_ = StoreT::instance().create(ddname, new DDI::LogicalPart(material,solid,cat));
125  DD_NC(ddname);
126 }
127 
128 
129 // private!
130 /*
131 DDLogicalPart::DDLogicalPart(DDRedirect<DDLogicalPartImpl>* p, bool dummy)
132  : DDMultiRegistered<DDLogicalPartImpl>(p,true)
133 { }
134 */
135 
137 {
138  return rep().category();
139 }
140 
141 
143 {
144  return rep().material();
145 }
146 
147 
149 {
150  return rep().solid();
151 }
152 
153 
154 /*
155  The weight must be calculated by using the method DDCompactView::weight().
156  For the weight calculation the full subtree of children is expanded. As a
157  usefull side-effect the weight of all LogicalParts of the children is calculated
158  as well.
159  This method will return 0, if the weight has not yet been calculated
160  using the DDCompactView, otherwise the weight of the component and all
161  its sub-components.
162  \todo In future DDLogicalPart::weight() will be sufficient for weight calculations
163  \todo make the method 'const'
164 */
166 {
167  return rep().weight();
168 }
169 
170 
224 std::vector<const DDsvalues_type *> DDLogicalPart::specifics() const
225 {
226  std::vector<const DDsvalues_type*> result;
227  rep().specificsV(result);
228  return result;
229 }
230 
231 
233 {
235  rep().mergedSpecificsV(result);
236  return result;
237 }
238 
239 // for internal use only
240 void DDLogicalPart::addSpecifics(const std::pair<DDPartSelection*,DDsvalues_type*> & s)
241 {
242  DCOUT('S', "lp=" << name());
243  rep().addSpecifics(s);
244 }
245 void DDLogicalPart::removeSpecifics(const std::pair<DDPartSelection*,DDsvalues_type*> & s)
246 {
247  rep().removeSpecifics(s);
248 }
250 {
251  return rep().hasDDValue(v);
252 }
253 // for internal use only
254 /*
255 const std::vector<DDSpecifics> & DDLogicalPart::specifics() const
256 {
257  return rep().specifics();
258 }
259 */
260 // void DDLogicalPart::clear()
261 // {
262 // StoreT::instance().clear();
263 // }
264 
265 
266 
267 // finds out whether a DDLogicalPart is registered & already valid (initialized)
268 // - returns (true,""), if so; result holds the corresponding DDLogicalPart
269 // - returns (false,"some status message") otherwise
270 // - nm corresponds to a regular expression, but will be anchored ( ^regexp$ )
271 // - ns corresponds to a regular expression, but will be anchored ( ^regexp$ )
272 #include <regex.h>
273 #include <set>
274 
275 namespace {
276 
277  struct Regex {
278 
279  explicit Regex(const std::string & s) : m_ok(false), me(s) {
280  size_t p = me.find(".");
281  m_ok = p!=std::string::npos;
282  if(m_ok) {
283  if (p>0) {
284  m_range.first = me.substr(0,p);
285  m_range.second = m_range.first+"{"; // '{' is 'z'+1
286  }
287  me = "^" + me + "$";
288  regcomp(&m_regex,me.c_str(),0);
289  }
290  }
291 
292  ~Regex() { if(m_ok) regfree(&m_regex); }
293 
294  bool empty() const { return me.empty();}
295 
296  bool notRegex() const { return !m_ok;}
297 
298  const std::string & value() const { return me;}
299 
300  bool match(const std::string & s) const {
301  if (m_ok)
302  return !regexec(&m_regex, s.c_str(), 0,0,0);
303  else
304  return me==s;
305  }
306 
307  const std::pair< std::string, std::string> & range() const { return m_range;}
308  private:
309  bool m_ok;
310  regex_t m_regex;
311  std::string me;
312  // range of me in a collating sequence
313  std::pair<std::string, std::string> m_range;
314  };
315 
316 }
317 
318 std::pair<bool,std::string> DDIsValid(const std::string & ns, const std::string & nm, std::vector<DDLogicalPart> & result, bool doRegex)
319 {
320  //return std::make_pair(true,"");
321  if (!doRegex) {
322  DDName ddnm(nm,ns);
323  result.push_back(DDLogicalPart(ddnm));
324  return std::make_pair(true,"");
325  }
326  std::string status;
327  Regex aRegex(nm);
328  Regex aNsRegex(ns);
329  bool emptyNs = aNsRegex.empty();
330  // std::cerr << "regex " << nm << " " << ns << std::endl;
331 
332  //edm::LogInfo("DDLogicalPart") << " . emptyNs=" << emptyNs << std::endl;
333  //edm::LogInfo("DDLogicalPart") << " . qname=[" << ns << ":" << nm << "]" << std::endl;
334 
335  // THIS IS THE SLOW PART: I have to compare every namespace & name of every
336  // logical part with a regex-comparison .... a linear search always through the
337  // full range of logical parts!!!!
338  /*
339  Algorithm description:
340  x. empty nm and ns argument of method means: use all matching regex ^.*$
341  a. iterate over all logical part names, match against regex for names
342  b. iterate over all namespaces of names found in a & match against regex for namespaces
343  */
344  LPNAMES::value_type::const_iterator bn(LPNAMES::instance().begin()),
345  ed(LPNAMES::instance().end());
346  typedef std::vector< LPNAMES::value_type::const_iterator> Candidates;
347  Candidates candidates;
348  if ( aRegex.notRegex() ) {
349  LPNAMES::value_type::const_iterator it = LPNAMES::instance().find(aRegex.value());
350  if (it!=ed) candidates.push_back(it);
351  }
352  else {
353  if ( !aRegex.range().first.empty()) {
354  bn = LPNAMES::instance().lower_bound(aRegex.range().first);
355  ed = LPNAMES::instance().upper_bound(aRegex.range().second);
356  }
357  for (LPNAMES::value_type::const_iterator it=bn; it != ed; ++it)
358  if(aRegex.match(it->first)) candidates.push_back(it);
359  }
360  for (int i=0; i<int(candidates.size()); ++i) {
361  LPNAMES::value_type::const_iterator it = candidates[i];
362  //if (doit) edm::LogInfo("DDLogicalPart") << "rgx: " << aName << ' ' << it->first << ' ' << doit << std::endl;
363  std::vector<DDName>::size_type sz = it->second.size(); // no of 'compatible' namespaces
364  if ( emptyNs && (sz==1) ) { // accept all logical parts in all the namespaces
365  result.push_back(it->second[0]);
366  //std::vector<DDName>::const_iterator nsIt(it->second.begin()), nsEd(it->second.end());
367  //for(; nsIt != nsEd; ++nsIt) {
368  // result.push_back(DDLogicalPart(*nsIt));
369  // edm::LogInfo("DDLogicalPart") << "DDD-WARNING: multiple namespaces match (in SpecPars PartSelector): " << *nsIt << std::endl;
370  //}
371  }
372  else if ( !emptyNs ) { // only accept matching namespaces
373  std::vector<DDName>::const_iterator nsit(it->second.begin()), nsed(it->second.end());
374  for (; nsit !=nsed; ++nsit) {
375  //edm::LogInfo("DDLogicalPart") << "comparing " << aNs << " with " << *nsit << std::endl;
376  bool another_doit = aNsRegex.match(nsit->ns());
377  if ( another_doit ) {
378  //temp.push_back(std::make_pair(it->first,*nsit));
379  result.push_back(DDLogicalPart(*nsit));
380  }
381  }
382  }
383  else { // emtpyNs and sz>1 -> error, too ambigous
384  std::string message = "DDLogicalPart-name \"" + it->first +"\" matching regex \""
385  + nm + "\" has been found at least in following namespaces:\n";
386  std::vector<DDName>::const_iterator vit = it->second.begin();
387  for(; vit != it->second.end(); ++vit) {
388  message += vit->ns();
389  message += " ";
390  }
391  message += "\nQualify the name with a regexp for the namespace, i.e \".*:name-regexp\" !";
392  return std::make_pair(false,message);
393  }
394  }
395  bool flag=true;
396  std::string message;
397 
398  // check whether the found logical-parts are also defined (i.e. have material, solid ...)
399  if (result.size()) {
400  std::vector<DDLogicalPart>::const_iterator lpit(result.begin()), lped(result.end());
401  for (; lpit != lped; ++lpit) {
402  // std::cout << "VI- " << std::string(lpit->name()) << std::endl;
403  if (!lpit->isDefined().second) {
404  message = message + "LogicalPart " + lpit->name().fullname() + " not (yet) defined!\n";
405  flag = false;
406  }
407  }
408  }
409  else {
410  flag = false;
411  message = "No regex-match for namespace=" + ns + " name=" + nm + "\n";
412  }
413 
414 
415  return std::make_pair(flag,message);
416 }
417 
418 
419 const std::vector< std::pair<DDPartSelection*,DDsvalues_type*> > &
421 {
422  return rep().attachedSpecifics();
423 }
424 
425 /*
426 const std::vector<DDPartSelection*> & DDLogicalPart::partSelections(const DDValue & v) const
427 {
428  return rep().partSelections(v);
429 }
430 */
Definition: DDBase.h:18
int i
Definition: DBlmapReader.cc:9
const DDI::rep_traits< N, C >::reference rep() const
Definition: DDBase.h:95
bool hasDDValue(const DDValue &) const
def_type isDefined() const
Definition: DDBase.h:121
long int flag
Definition: mlp_lapack.h:47
const N & name() const
Definition: DDBase.h:88
DDMaterial is used to define and access material information.
Definition: DDMaterial.h:45
std::vector< const DDsvalues_type * > specifics() const
returns the specific-data attached to the LogicalPart only (not to a DDExpandedNode) ...
const std::string & ns() const
Returns the namespace.
Definition: DDName.cc:101
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:18
std::ostream & operator<<(std::ostream &out, const ALILine &li)
Definition: ALILine.cc:187
uint16_t size_type
const DDMaterial & material() const
Returns a reference object of the material this LogicalPart is made of.
DDLogicalPart()
The default constructor provides an uninitialzed reference object.
A DDSolid represents the shape of a part.
Definition: DDSolid.h:42
const std::vector< std::pair< DDPartSelection *, DDsvalues_type * > > & attachedSpecifics() const
static value_type & instance()
void addSpecifics(const std::pair< DDPartSelection *, DDsvalues_type * > &)
don&#39;t use, internal only /todo make it private
tuple result
Definition: query.py:137
void DD_NC(const DDName &)
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
Category
Definition: DDEnums.h:7
A DDLogicalPart aggregates information concerning material, solid and sensitveness ...
Definition: DDLogicalPart.h:95
DDsvalues_type mergedSpecifics() const
returns the merged-specifics, i.e. the last specified specifics of this logical-part ...
#define end
Definition: vmac.h:38
std::vector< LinkConnSpec >::const_iterator IT
part
Definition: HCALResponse.h:21
string message
Definition: argparse.py:126
void removeSpecifics(const std::pair< DDPartSelection *, DDsvalues_type * > &)
#define begin
Definition: vmac.h:31
const DDSolid & solid() const
Returns a reference object of the solid being the shape of this LogicalPart.
std::pair< bool, std::string > DDIsValid(const std::string &ns, const std::string &name, std::vector< DDLogicalPart > &result, bool doRegex=true)
double & weight()
Weight of the LogicalPart viewed as a component, if cached, else -1.
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:6
string s
Definition: asciidump.py:422
tuple status
Definition: ntuplemaker.py:245
#define DCOUT(M_v_Y, M_v_S)
Definition: DDdebug.h:53
DDEnums::Category category() const
Returns the categorization of the DDLogicalPart (sensitive detector element, cable, ...)
const std::string & name() const
Returns the name.
Definition: DDName.cc:87
mathSSE::Vec4< T > v