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  std::vector<DDName> & ns = LPNAMES::instance()[n.name()];
12  typedef std::vector<DDName>::iterator IT;
13  bool alreadyIn( false );
14  for( IT p = ns.begin(); p != ns.end(); ++p )
15  {
16  if( p->ns() == n.ns())
17  {
18  alreadyIn = true;
19  break;
20  }
21  }
22  if( !alreadyIn )
23  {
24  ns.push_back( n );
25  }
26 }
27 
28 std::ostream &
29 operator<<( std::ostream & os, const DDLogicalPart & part )
30 {
32  if( defined.first )
33  {
34  os << *(defined.first) << " ";
35  if( defined.second )
36  {
37  part.rep().stream( os );
38  }
39  else
40  {
41  os << "* logicalpart not defined * ";
42  }
43  }
44  else
45  {
46  os << "* logicalpart not declared * ";
47  }
48  return os;
49 }
50 
51 // =================================================================================
52 
65 // now inlined...
66 
100  : DDBase<DDName, DDI::LogicalPart*>()
101 {
102  prep_ = StoreT::instance().create( name );
103  DD_NC( name );
104 }
105 
119  const DDMaterial & material,
120  const DDSolid & solid,
121  DDEnums::Category cat)
122  : DDBase<DDName,DDI::LogicalPart*>()
123 {
124  DCOUT('C', "create LogicalPart ddname=" << ddname << " mat=" << material.name() << " sol=" << solid.name());
125  prep_ = StoreT::instance().create(ddname, new DDI::LogicalPart(material,solid,cat));
126  DD_NC(ddname);
127 }
128 
129 
130 // private!
131 /*
132 DDLogicalPart::DDLogicalPart(DDRedirect<DDLogicalPartImpl>* p, bool dummy)
133  : DDMultiRegistered<DDLogicalPartImpl>(p,true)
134 { }
135 */
136 
138 {
139  return rep().category();
140 }
141 
142 
144 {
145  return rep().material();
146 }
147 
148 
150 {
151  return rep().solid();
152 }
153 
154 
155 /*
156  The weight must be calculated by using the method DDCompactView::weight().
157  For the weight calculation the full subtree of children is expanded. As a
158  usefull side-effect the weight of all LogicalParts of the children is calculated
159  as well.
160  This method will return 0, if the weight has not yet been calculated
161  using the DDCompactView, otherwise the weight of the component and all
162  its sub-components.
163  \todo In future DDLogicalPart::weight() will be sufficient for weight calculations
164  \todo make the method 'const'
165 */
167 {
168  return rep().weight();
169 }
170 
171 
225 std::vector<const DDsvalues_type *> DDLogicalPart::specifics() const
226 {
227  std::vector<const DDsvalues_type*> result;
228  rep().specificsV(result);
229  return result;
230 }
231 
232 
234 {
236  rep().mergedSpecificsV(result);
237  return result;
238 }
239 
240 // for internal use only
241 void DDLogicalPart::addSpecifics(const std::pair<const DDPartSelection*, const DDsvalues_type*> & s)
242 {
243  DCOUT('S', "lp=" << name());
244  rep().addSpecifics(s);
245 }
246 void DDLogicalPart::removeSpecifics(const std::pair<DDPartSelection*,DDsvalues_type*> & s)
247 {
248  rep().removeSpecifics(s);
249 }
251 {
252  return rep().hasDDValue(v);
253 }
254 
255 // finds out whether a DDLogicalPart is registered & already valid (initialized)
256 // - returns (true,""), if so; result holds the corresponding DDLogicalPart
257 // - returns (false,"some status message") otherwise
258 // - nm corresponds to a regular expression, but will be anchored ( ^regexp$ )
259 // - ns corresponds to a regular expression, but will be anchored ( ^regexp$ )
260 #include <regex.h>
261 #include <set>
262 
263 namespace
264 {
265  struct Regex
266  {
267  explicit Regex( const std::string & s )
268  : m_ok( false ),
269  me( s )
270  {
271  size_t p = me.find(".");
272  m_ok = p != std::string::npos;
273  if( m_ok )
274  {
275  if( p > 0 )
276  {
277  m_range.first = me.substr( 0, p );
278  m_range.second = m_range.first + "{"; // '{' is 'z'+1
279  }
280  me = "^" + me + "$";
281  regcomp( &m_regex, me.c_str(), 0 );
282  }
283  }
284 
285  ~Regex( void ) { if( m_ok ) regfree( &m_regex ); }
286 
287  bool empty( void ) const { return me.empty(); }
288 
289  bool notRegex( void ) const { return !m_ok; }
290 
291  const std::string & value( void ) const { return me;}
292 
293  bool match( const std::string & s ) const {
294  if( m_ok )
295  return !regexec( &m_regex, s.c_str(), 0, 0, 0 );
296  else
297  return me == s;
298  }
299 
300  const std::pair< std::string, std::string> & range( void ) const { return m_range; }
301  private:
302  bool m_ok;
303  regex_t m_regex;
304  std::string me;
305  // range of me in a collating sequence
306  std::pair<std::string, std::string> m_range;
307  };
308 }
309 
310 std::pair<bool, std::string>
311 DDIsValid( const std::string & ns, const std::string & nm, std::vector<DDLogicalPart> & result, bool doRegex )
312 {
313  if( !doRegex )
314  {
315  DDName ddnm( nm, ns );
316  result.push_back( DDLogicalPart( ddnm ));
317  return std::make_pair( true, "" );
318  }
320  Regex aRegex( nm );
321  Regex aNsRegex( ns );
322  bool emptyNs = aNsRegex.empty();
323 
324  // THIS IS THE SLOW PART: I have to compare every namespace & name of every
325  // logical part with a regex-comparison .... a linear search always through the
326  // full range of logical parts!!!!
327  /*
328  Algorithm description:
329  x. empty nm and ns argument of method means: use all matching regex ^.*$
330  a. iterate over all logical part names, match against regex for names
331  b. iterate over all namespaces of names found in a & match against regex for namespaces
332  */
333  LPNAMES::value_type::const_iterator bn(LPNAMES::instance().begin()),
334  ed(LPNAMES::instance().end());
335  typedef std::vector< LPNAMES::value_type::const_iterator> Candidates;
336  Candidates candidates;
337  if ( aRegex.notRegex() ) {
338  LPNAMES::value_type::const_iterator it = LPNAMES::instance().find(aRegex.value());
339  if (it!=ed) candidates.push_back(it);
340  }
341  else {
342  if ( !aRegex.range().first.empty()) {
343  bn = LPNAMES::instance().lower_bound(aRegex.range().first);
344  ed = LPNAMES::instance().upper_bound(aRegex.range().second);
345  }
346  for (LPNAMES::value_type::const_iterator it=bn; it != ed; ++it)
347  if(aRegex.match(it->first)) candidates.push_back(it);
348  }
349  for (int i=0; i<int(candidates.size()); ++i) {
350  LPNAMES::value_type::const_iterator it = candidates[i];
351  //if (doit) edm::LogInfo("DDLogicalPart") << "rgx: " << aName << ' ' << it->first << ' ' << doit << std::endl;
352  std::vector<DDName>::size_type sz = it->second.size(); // no of 'compatible' namespaces
353  if ( emptyNs && (sz==1) ) { // accept all logical parts in all the namespaces
354  result.push_back(it->second[0]);
355  //std::vector<DDName>::const_iterator nsIt(it->second.begin()), nsEd(it->second.end());
356  //for(; nsIt != nsEd; ++nsIt) {
357  // result.push_back(DDLogicalPart(*nsIt));
358  // edm::LogInfo("DDLogicalPart") << "DDD-WARNING: multiple namespaces match (in SpecPars PartSelector): " << *nsIt << std::endl;
359  //}
360  }
361  else if ( !emptyNs ) { // only accept matching namespaces
362  std::vector<DDName>::const_iterator nsit(it->second.begin()), nsed(it->second.end());
363  for (; nsit !=nsed; ++nsit) {
364  //edm::LogInfo("DDLogicalPart") << "comparing " << aNs << " with " << *nsit << std::endl;
365  bool another_doit = aNsRegex.match(nsit->ns());
366  if ( another_doit ) {
367  //temp.push_back(std::make_pair(it->first,*nsit));
368  result.push_back(DDLogicalPart(*nsit));
369  }
370  }
371  }
372  else { // emtpyNs and sz>1 -> error, too ambigous
373  std::string message = "DDLogicalPart-name \"" + it->first +"\" matching regex \""
374  + nm + "\" has been found at least in following namespaces:\n";
375  std::vector<DDName>::const_iterator vit = it->second.begin();
376  for(; vit != it->second.end(); ++vit) {
377  message += vit->ns();
378  message += " ";
379  }
380  message += "\nQualify the name with a regexp for the namespace, i.e \".*:name-regexp\" !";
381  return std::make_pair(false,message);
382  }
383  }
384  bool flag=true;
386 
387  // check whether the found logical-parts are also defined (i.e. have material, solid ...)
388  if (result.size()) {
389  std::vector<DDLogicalPart>::const_iterator lpit(result.begin()), lped(result.end());
390  for (; lpit != lped; ++lpit) {
391  // std::cout << "VI- " << std::string(lpit->name()) << std::endl;
392  if (!lpit->isDefined().second) {
393  message = message + "LogicalPart " + lpit->name().fullname() + " not (yet) defined!\n";
394  flag = false;
395  }
396  }
397  }
398  else {
399  flag = false;
400  message = "No regex-match for namespace=" + ns + " name=" + nm + "\n";
401  }
402 
403  return std::make_pair(flag,message);
404 }
405 
406 const std::vector< std::pair<const DDPartSelection*, const DDsvalues_type*> > &
408 {
409  return rep().attachedSpecifics();
410 }
Definition: DDBase.h:14
int i
Definition: DBlmapReader.cc:9
const DDI::rep_traits< N, C >::reference rep() const
Definition: DDBase.h:89
bool hasDDValue(const DDValue &) const
def_type isDefined() const
Definition: DDBase.h:115
const N & name() const
Definition: DDBase.h:82
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
std::vector< LinkConnSpec >::const_iterator IT
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:6
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.