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