CMS 3D CMS Logo

DDLogicalPart.cc
Go to the documentation of this file.
2 
3 #include <ostream>
4 
10 
11 class DDValue;
12 
13 void
14 DD_NC( const DDName & n )
15 {
16  auto & ns = LPNAMES::instance()[n.name()];
17 
18  bool alreadyIn( false );
19  for( const auto& p : ns )
20  {
21  if( p.ns() == n.ns())
22  {
23  alreadyIn = true;
24  break;
25  }
26  }
27  if( !alreadyIn )
28  {
29  ns.emplace_back( n );
30  }
31 }
32 
33 std::ostream &
34 operator<<( std::ostream & os, const DDLogicalPart & part )
35 {
37  if( defined.first )
38  {
39  os << *(defined.first) << " ";
40  if( defined.second )
41  {
42  part.rep().stream( os );
43  }
44  else
45  {
46  os << "* logicalpart not defined * ";
47  }
48  }
49  else
50  {
51  os << "* logicalpart not declared * ";
52  }
53  return os;
54 }
55 
56 // =================================================================================
57 
70 // now inlined...
71 
105  : DDBase<DDName, DDI::LogicalPart*>()
106 {
107  prep_ = StoreT::instance().create( name );
108  DD_NC( name );
109 }
110 
124  const DDMaterial & material,
125  const DDSolid & solid,
127  : DDBase<DDName,DDI::LogicalPart*>()
128 {
129  prep_ = StoreT::instance().create(ddname, new DDI::LogicalPart(material,solid,cat));
130  DD_NC(ddname);
131 }
132 
133 
134 // private!
135 /*
136 DDLogicalPart::DDLogicalPart(DDRedirect<DDLogicalPartImpl>* p, bool dummy)
137  : DDMultiRegistered<DDLogicalPartImpl>(p,true)
138 { }
139 */
140 
142 {
143  return rep().category();
144 }
145 
146 
148 {
149  return rep().material();
150 }
151 
152 
154 {
155  return rep().solid();
156 }
157 
211 std::vector<const DDsvalues_type *> DDLogicalPart::specifics() const
212 {
213  std::vector<const DDsvalues_type*> result;
214  rep().specificsV(result);
215  return result;
216 }
217 
218 
220 {
222  rep().mergedSpecificsV(result);
223  return result;
224 }
225 
226 // for internal use only
227 void DDLogicalPart::addSpecifics(const std::pair<const DDPartSelection*, const DDsvalues_type*> & s)
228 {
229  rep().addSpecifics(s);
230 }
231 void DDLogicalPart::removeSpecifics(const std::pair<DDPartSelection*,DDsvalues_type*> & s)
232 {
233  rep().removeSpecifics(s);
234 }
236 {
237  return rep().hasDDValue(v);
238 }
239 
240 // finds out whether a DDLogicalPart is registered & already valid (initialized)
241 // - returns (true,""), if so; result holds the corresponding DDLogicalPart
242 // - returns (false,"some status message") otherwise
243 // - nm corresponds to a regular expression, but will be anchored ( ^regexp$ )
244 // - ns corresponds to a regular expression, but will be anchored ( ^regexp$ )
245 #include <regex.h>
246 #include <cstddef>
247 
248 namespace
249 {
250  struct Regex
251  {
252  explicit Regex( const std::string & s )
253  : m_ok( false ),
254  me( s )
255  {
256  size_t p = me.find(".");
257  m_ok = p != std::string::npos;
258  if( m_ok )
259  {
260  if( p > 0 )
261  {
262  m_range.first = me.substr( 0, p );
263  m_range.second = m_range.first + "{"; // '{' is 'z'+1
264  }
265  me = "^" + me + "$";
266  regcomp( &m_regex, me.c_str(), 0 );
267  }
268  }
269 
270  ~Regex( void ) { if( m_ok ) regfree( &m_regex ); }
271 
272  bool empty( void ) const { return me.empty(); }
273 
274  bool notRegex( void ) const { return !m_ok; }
275 
276  const std::string & value( void ) const { return me;}
277 
278  bool match( const std::string & s ) const {
279  if( m_ok )
280  return !regexec( &m_regex, s.c_str(), 0, nullptr, 0 );
281  else
282  return me == s;
283  }
284 
285  const std::pair< std::string, std::string> & range( void ) const { return m_range; }
286  private:
287  bool m_ok;
288  regex_t m_regex;
289  std::string me;
290  // range of me in a collating sequence
291  std::pair<std::string, std::string> m_range;
292  };
293 }
294 
295 std::pair<bool, std::string>
296 DDIsValid( const std::string & ns, const std::string & nm, std::vector<DDLogicalPart> & result, bool doRegex )
297 {
298  if( !doRegex )
299  {
300  DDName ddnm( nm, ns );
301  result.emplace_back( DDLogicalPart( ddnm ));
302  return std::make_pair( true, "" );
303  }
305  Regex aRegex( nm );
306  Regex aNsRegex( ns );
307  bool emptyNs = aNsRegex.empty();
308 
309  // THIS IS THE SLOW PART: I have to compare every namespace & name of every
310  // logical part with a regex-comparison .... a linear search always through the
311  // full range of logical parts!!!!
312  /*
313  Algorithm description:
314  x. empty nm and ns argument of method means: use all matching regex ^.*$
315  a. iterate over all logical part names, match against regex for names
316  b. iterate over all namespaces of names found in a & match against regex for namespaces
317  */
318  LPNAMES::value_type::const_iterator bn(LPNAMES::instance().begin()),
319  ed(LPNAMES::instance().end());
320  typedef std::vector< LPNAMES::value_type::const_iterator> Candidates;
321  Candidates candidates;
322  if ( aRegex.notRegex() ) {
323  LPNAMES::value_type::const_iterator it = LPNAMES::instance().find(aRegex.value());
324  if (it!=ed) candidates.emplace_back(it);
325  }
326  else {
327  if ( !aRegex.range().first.empty()) {
328  bn = LPNAMES::instance().lower_bound(aRegex.range().first);
329  ed = LPNAMES::instance().upper_bound(aRegex.range().second);
330  }
331  for (LPNAMES::value_type::const_iterator it=bn; it != ed; ++it)
332  if(aRegex.match(it->first)) candidates.emplace_back(it);
333  }
334  for (const auto & it : candidates) {
335  //if (doit) edm::LogInfo("DDLogicalPart") << "rgx: " << aName << ' ' << it->first << ' ' << doit << std::endl;
336  std::vector<DDName>::size_type sz = it->second.size(); // no of 'compatible' namespaces
337  if ( emptyNs && (sz==1) ) { // accept all logical parts in all the namespaces
338  result.emplace_back(it->second[0]);
339  //std::vector<DDName>::const_iterator nsIt(it->second.begin()), nsEd(it->second.end());
340  //for(; nsIt != nsEd; ++nsIt) {
341  // result.emplace_back(DDLogicalPart(*nsIt));
342  // edm::LogInfo("DDLogicalPart") << "DDD-WARNING: multiple namespaces match (in SpecPars PartSelector): " << *nsIt << std::endl;
343  //}
344  }
345  else if ( !emptyNs ) { // only accept matching namespaces
346  std::vector<DDName>::const_iterator nsit(it->second.begin()), nsed(it->second.end());
347  for (; nsit !=nsed; ++nsit) {
348  //edm::LogInfo("DDLogicalPart") << "comparing " << aNs << " with " << *nsit << std::endl;
349  bool another_doit = aNsRegex.match(nsit->ns());
350  if ( another_doit ) {
351  //temp.emplace_back(std::make_pair(it->first,*nsit));
352  result.emplace_back(DDLogicalPart(*nsit));
353  }
354  }
355  }
356  else { // emtpyNs and sz>1 -> error, too ambigous
357  std::string message = "DDLogicalPart-name \"" + it->first +"\" matching regex \""
358  + nm + "\" has been found at least in following namespaces:\n";
359  std::vector<DDName>::const_iterator vit = it->second.begin();
360  for(; vit != it->second.end(); ++vit) {
361  message += vit->ns();
362  message += " ";
363  }
364  message += "\nQualify the name with a regexp for the namespace, i.e \".*:name-regexp\" !";
365  return std::make_pair(false,message);
366  }
367  }
368  bool flag=true;
369  std::string message;
370 
371  // check whether the found logical-parts are also defined (i.e. have material, solid ...)
372  if (!result.empty()) {
373  std::vector<DDLogicalPart>::const_iterator lpit(result.begin()), lped(result.end());
374  for (; lpit != lped; ++lpit) {
375  // std::cout << "VI- " << std::string(lpit->name()) << std::endl;
376  if (!lpit->isDefined().second) {
377  message = message + "LogicalPart " + lpit->name().fullname() + " not (yet) defined!\n";
378  flag = false;
379  }
380  }
381  }
382  else {
383  flag = false;
384  message = "No regex-match for namespace=" + ns + " name=" + nm + "\n";
385  }
386 
387  return std::make_pair(flag,message);
388 }
389 
390 const std::vector< std::pair<const DDPartSelection*, const DDsvalues_type*> > &
392 {
393  return rep().attachedSpecifics();
394 }
Definition: DDBase.h:10
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
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, ...)
std::ostream & operator<<(std::ostream &os, const DDLogicalPart &part)
const std::string & ns() const
Returns the namespace.
Definition: DDName.cc:102
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:15
const DDSolid & solid(void) const
Returns a reference object of the solid being the shape of this LogicalPart.
uint16_t size_type
A DDSolid represents the shape of a part.
Definition: DDSolid.h:38
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()
def cat(path)
Definition: eostools.py:400
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:20
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:92
void DD_NC(const DDName &n)
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
part
Definition: HCALResponse.h:20
void removeSpecifics(const std::pair< DDPartSelection *, DDsvalues_type * > &)
DDLogicalPart(void)
The default constructor provides an uninitialzed reference object.
Definition: DDLogicalPart.h:96
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
const std::vector< std::pair< const DDPartSelection *, const DDsvalues_type * > > & attachedSpecifics(void) const
const std::string & name() const
Returns the name.
Definition: DDName.cc:88
const DDMaterial & material(void) const
Returns a reference object of the material this LogicalPart is made of.
const DDName & ddname() const
Definition: DDBase.h:80