28 _reset_cache( c.second );
38 static std::regex_constants::syntax_option_type regex_flags() {
39 return std::regex_constants::icase | std::regex_constants::ECMAScript;
47 std::pair<std::string, PlacedVolume>
49 std::string path = std::move(p) +
"/" + node.
name();
50 if( path == this->_place )
return { path, node };
51 for( Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau ) {
52 auto ret = this->
scan( path, node->GetDaughter(idau) );
53 if( ret.second.isValid() )
return ret;
63 std::pair<std::string, PlacedVolume>
65 std::string path = std::move(p) +
"/" + node.
name();
68 bool stat = std::regex_match( voln, sm, this->_regex );
70 return { path, node };
72 for( Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau ) {
73 auto ret = this->
scan( path, node->GetDaughter(idau) );
74 if( ret.second.isValid() )
return ret;
87 std::string path = std::move(p) +
"/" + node.
name();
90 bool stat = std::regex_match( voln, sm, this->_regex );
92 this->placements.insert( { path, node } );
94 for( Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau )
95 this->
collect( path, { node->GetDaughter(idau) } );
103 : description(dsc), sensitive(sd), xd(e) {
106 this->
print = PrintLevel(value);
112 const auto& vids = pv.
volIDs();
113 for(
const auto& vid : vids ) {
114 if( vid.first == volid ) {
115 if( value == vid.second ) {
118 printout(ERROR, this->name,
119 "+++ Invalid VOLID: %s: %s %d <> %d",
120 name.c_str(), volid.c_str(), vid.second, value);
128 if( e.hasAttr(
_U(vis)) ) {
129 auto vis = e.attr<std::string>(
_U(vis));
132 if( e.hasAttr(
_U(limits)) ) {
133 auto lim = e.attr<std::string>(
_U(limits));
136 if( e.hasAttr(
_U(region)) ) {
137 auto reg = e.attr<std::string>(
_U(region));
138 volume.
setRegion( this->description, reg );
140 if( this->sensitive.isValid() && xd.ptr() != e.ptr() && e.hasAttr(
_U(sensitive)) ) {
147 std::pair<std::string, PlacedVolume> ret;
149 this->
id = this->xd.
id();
150 this->name = this->xd.nameStr();
152 if( this->xd.hasAttr(
_U(placement)) ) {
153 auto place = this->xd.attr<std::string>(
_U(placement));
155 if( !ret.second.isValid() ) {
156 except( this->name,
"+++ [id:%d] %s: Failed to find top level placement: '%s'",
157 this->
id, this->name.c_str(), place.c_str() );
160 else if( this->xd.hasAttr(
_U(volume)) ) {
161 auto vol = this->xd.attr<std::string>(
_U(volume));
163 if( !ret.second.isValid() ) {
164 except( this->name,
"+++ [id:%d] %s: Failed to find top level volume: '%s'",
165 this->
id, this->name.c_str(), vol.c_str() );
169 except( this->name,
"+++ [id:%d] %s Unknown DetElement selector.",
170 this->
id, this->name.c_str() );
173 if( xd.hasAttr(
_U(sensitive)) ) {
174 auto sens = xd.attr<std::string>(
_U(sensitive));
175 if( !this->sensitive.isValid() ) {
176 this->sensitive = this->description.sensitiveDetector( this->name );
178 if( !this->sensitive.isValid() ) {
179 except( this->name,
"+++ [id:%d] %s No suitable sensitive detector available",
180 this->
id, this->name.c_str() );
182 this->sensitive.setType( sens );
186 auto pv = ret.second;
187 auto vol = pv.volume();
190 _set_attr( vol, xd );
192 printout( this->print, this->name,
193 "+++ [id:%d] %-40s Creating detector element path:%s",
195 if( xd.hasAttr(
_U(sensitive)) ) {
196 std::string readout_name =
"----";
198 pv.addPhysVolID(
"system", this->
id );
199 if( xd.hasAttr(
_U(readout)) ) {
200 readout_name = xd.readoutStr();
201 Readout rdout = this->description.readout( readout_name );
203 except(this->name,
"+++ [id:%d] %s Invalid readout object: %s.",
204 this->
id, this->name.c_str(), readout_name.c_str() );
206 this->sensitive.setReadout( rdout );
208 printout( this->print, this->name,
209 "+++ [id:%d] %-40s Assign readout '%s' to sensitive detector: '%s' [%s]",
210 this->
id, this->name.c_str(), readout_name.c_str(),
211 this->sensitive.name(), this->sensitive.type().c_str() );
213 if( pv.num_daughters() > 0 ) {
214 for(
xml_coll_t coll(this->xd,
_U(daughter)); coll; ++coll ) {
215 this->add_children( detector, coll );
219 _reset_cache( detector );
226 auto vol = e.attr<std::string>(
_U(volume));
229 helper.collect( {}, pv );
230 if( helper.placements.empty() ) {
233 for(
auto& place : helper.placements ) {
235 int vid = e.hasAttr(
_U(
id)) ? e.id() : parent.
children().size();
237 std::string nam = e.nameStr() +
_toString(vid,
"_%d");
241 _set_attr( volume, e );
242 if( !this->sensitive.isValid() ) {
243 if( e.hasAttr(
_U(sensitive)) ) {
247 if( e.hasAttr(
_U(physvolid)) ) {
248 auto volid = e.attr<std::string>(
_U(physvolid) );
249 this->_set_volid( dpv, volid, vid );
254 printout( this->print, this->name,
255 "+++ [id:%d] %-40s sub-element %-8s [id:%d] vis:%-10s %3d --> place %s",
260 this->add_children( de, coll );