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.
4 #include <ostream>
5 
7 
8 void
9 DD_NC( const DDName & n )
10 {
11  auto & ns = LPNAMES::instance()[n.name()];
12  bool alreadyIn( false );
13  for( const auto& p : ns )
14  {
15  if( p.ns() == n.ns())
16  {
17  alreadyIn = true;
18  break;
19  }
20  }
21  if( !alreadyIn )
22  {
23  ns.push_back( n );
24  }
25 }
26 
27 std::ostream &
28 operator<<( std::ostream & os, const DDLogicalPart & part )
29 {
31  if( defined.first )
32  {
33  os << *(defined.first) << " ";
34  if( defined.second )
35  {
36  part.rep().stream( os );
37  }
38  else
39  {
40  os << "* logicalpart not defined * ";
41  }
42  }
43  else
44  {
45  os << "* logicalpart not declared * ";
46  }
47  return os;
48 }
49 
50 // =================================================================================
51 
64 // now inlined...
65 
99  : 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<const DDPartSelection*, const 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 
254 // finds out whether a DDLogicalPart is registered & already valid (initialized)
255 // - returns (true,""), if so; result holds the corresponding DDLogicalPart
256 // - returns (false,"some status message") otherwise
257 // - nm corresponds to a regular expression, but will be anchored ( ^regexp$ )
258 // - ns corresponds to a regular expression, but will be anchored ( ^regexp$ )
259 #include <regex.h>
260 #include <set>
261 
262 namespace
263 {
264  struct Regex
265  {
266  explicit Regex( const std::string & s )
267  : m_ok( false ),
268  me( s )
269  {
270  size_t p = me.find(".");
271  m_ok = p != std::string::npos;
272  if( m_ok )
273  {
274  if( p > 0 )
275  {
276  m_range.first = me.substr( 0, p );
277  m_range.second = m_range.first + "{"; // '{' is 'z'+1
278  }
279  me = "^" + me + "$";
280  regcomp( &m_regex, me.c_str(), 0 );
281  }
282  }
283 
284  ~Regex( void ) { if( m_ok ) regfree( &m_regex ); }
285 
286  bool empty( void ) const { return me.empty(); }
287 
288  bool notRegex( void ) const { return !m_ok; }
289 
290  const std::string & value( void ) const { return me;}
291 
292  bool match( const std::string & s ) const {
293  if( m_ok )
294  return !regexec( &m_regex, s.c_str(), 0, 0, 0 );
295  else
296  return me == s;
297  }
298 
299  const std::pair< std::string, std::string> & range( void ) const { return m_range; }
300  private:
301  bool m_ok;
302  regex_t m_regex;
303  std::string me;
304  // range of me in a collating sequence
305  std::pair<std::string, std::string> m_range;
306  };
307 }
308 
309 std::pair<bool, std::string>
310 DDIsValid( const std::string & ns, const std::string & nm, std::vector<DDLogicalPart> & result, bool doRegex )
311 {
312  if( !doRegex )
313  {
314  DDName ddnm( nm, ns );
315  result.push_back( DDLogicalPart( ddnm ));
316  return std::make_pair( true, "" );
317  }
319  Regex aRegex( nm );
320  Regex aNsRegex( ns );
321  bool emptyNs = aNsRegex.empty();
322 
323  // THIS IS THE SLOW PART: I have to compare every namespace & name of every
324  // logical part with a regex-comparison .... a linear search always through the
325  // full range of logical parts!!!!
326  /*
327  Algorithm description:
328  x. empty nm and ns argument of method means: use all matching regex ^.*$
329  a. iterate over all logical part names, match against regex for names
330  b. iterate over all namespaces of names found in a & match against regex for namespaces
331  */
332  LPNAMES::value_type::const_iterator bn(LPNAMES::instance().begin()),
333  ed(LPNAMES::instance().end());
334  typedef std::vector< LPNAMES::value_type::const_iterator> Candidates;
335  Candidates candidates;
336  if ( aRegex.notRegex() ) {
337  LPNAMES::value_type::const_iterator it = LPNAMES::instance().find(aRegex.value());
338  if (it!=ed) candidates.push_back(it);
339  }
340  else {
341  if ( !aRegex.range().first.empty()) {
342  bn = LPNAMES::instance().lower_bound(aRegex.range().first);
343  ed = LPNAMES::instance().upper_bound(aRegex.range().second);
344  }
345  for (LPNAMES::value_type::const_iterator it=bn; it != ed; ++it)
346  if(aRegex.match(it->first)) candidates.push_back(it);
347  }
348  for (int i=0; i<int(candidates.size()); ++i) {
349  LPNAMES::value_type::const_iterator it = candidates[i];
350  //if (doit) edm::LogInfo("DDLogicalPart") << "rgx: " << aName << ' ' << it->first << ' ' << doit << std::endl;
351  std::vector<DDName>::size_type sz = it->second.size(); // no of 'compatible' namespaces
352  if ( emptyNs && (sz==1) ) { // accept all logical parts in all the namespaces
353  result.push_back(it->second[0]);
354  //std::vector<DDName>::const_iterator nsIt(it->second.begin()), nsEd(it->second.end());
355  //for(; nsIt != nsEd; ++nsIt) {
356  // result.push_back(DDLogicalPart(*nsIt));
357  // edm::LogInfo("DDLogicalPart") << "DDD-WARNING: multiple namespaces match (in SpecPars PartSelector): " << *nsIt << std::endl;
358  //}
359  }
360  else if ( !emptyNs ) { // only accept matching namespaces
361  std::vector<DDName>::const_iterator nsit(it->second.begin()), nsed(it->second.end());
362  for (; nsit !=nsed; ++nsit) {
363  //edm::LogInfo("DDLogicalPart") << "comparing " << aNs << " with " << *nsit << std::endl;
364  bool another_doit = aNsRegex.match(nsit->ns());
365  if ( another_doit ) {
366  //temp.push_back(std::make_pair(it->first,*nsit));
367  result.push_back(DDLogicalPart(*nsit));
368  }
369  }
370  }
371  else { // emtpyNs and sz>1 -> error, too ambigous
372  std::string message = "DDLogicalPart-name \"" + it->first +"\" matching regex \""
373  + nm + "\" has been found at least in following namespaces:\n";
374  std::vector<DDName>::const_iterator vit = it->second.begin();
375  for(; vit != it->second.end(); ++vit) {
376  message += vit->ns();
377  message += " ";
378  }
379  message += "\nQualify the name with a regexp for the namespace, i.e \".*:name-regexp\" !";
380  return std::make_pair(false,message);
381  }
382  }
383  bool flag=true;
385 
386  // check whether the found logical-parts are also defined (i.e. have material, solid ...)
387  if (result.size()) {
388  std::vector<DDLogicalPart>::const_iterator lpit(result.begin()), lped(result.end());
389  for (; lpit != lped; ++lpit) {
390  // std::cout << "VI- " << std::string(lpit->name()) << std::endl;
391  if (!lpit->isDefined().second) {
392  message = message + "LogicalPart " + lpit->name().fullname() + " not (yet) defined!\n";
393  flag = false;
394  }
395  }
396  }
397  else {
398  flag = false;
399  message = "No regex-match for namespace=" + ns + " name=" + nm + "\n";
400  }
401 
402  return std::make_pair(flag,message);
403 }
404 
405 const std::vector< std::pair<const DDPartSelection*, const DDsvalues_type*> > &
407 {
408  return rep().attachedSpecifics();
409 }
Definition: DDBase.h:10
int i
Definition: DBlmapReader.cc:9
const DDI::rep_traits< N, C >::reference rep() const
Definition: DDBase.h:84
bool hasDDValue(const DDValue &) const
def_type isDefined() const
Definition: DDBase.h:110
const N & name() const
Definition: DDBase.h:78
DDMaterial is used to define and access material information.
Definition: DDMaterial.h:41
DDEnums::Category category(void) const
Returns the categorization of the DDLogicalPart (sensitive detector element, cable, ...)
const std::string & ns() const
Returns the namespace.
Definition: DDName.cc:101
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:18
const DDSolid & solid(void) const
Returns a reference object of the solid being the shape of this LogicalPart.
std::ostream & operator<<(std::ostream &out, const ALILine &li)
Definition: ALILine.cc:187
uint16_t size_type
double & weight(void)
Weight of the LogicalPart viewed as a component, if cached, else -1.
A DDSolid represents the shape of a part.
Definition: DDSolid.h:35
std::vector< const DDsvalues_type * > specifics(void) const
returns the specific-data attached to the LogicalPart only (not to a DDExpandedNode) ...
static value_type & instance()
tuple result
Definition: query.py:137
void DD_NC(const DDName &)
Definition: DDLogicalPart.cc:9
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:88
#define end
Definition: vmac.h:37
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
std::pair< bool, std::string > DDIsValid(const std::string &ns, const std::string &name, std::vector< DDLogicalPart > &result, bool doRegex=true)
part
Definition: HCALResponse.h:20
void removeSpecifics(const std::pair< DDPartSelection *, DDsvalues_type * > &)
#define begin
Definition: vmac.h:30
DDLogicalPart(void)
The default constructor provides an uninitialzed reference object.
Definition: DDLogicalPart.h:94
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
volatile std::atomic< bool > shutdown_flag false
tuple status
Definition: ntuplemaker.py:245
const std::vector< std::pair< const DDPartSelection *, const DDsvalues_type * > > & attachedSpecifics(void) const
#define DCOUT(M_v_Y, M_v_S)
Definition: DDdebug.h:53
const std::string & name() const
Returns the name.
Definition: DDName.cc:87
const DDMaterial & material(void) const
Returns a reference object of the material this LogicalPart is made of.