17 #ifndef DD4HEP_DETELEMENTCREATOR_H
18 #define DD4HEP_DETELEMENTCREATOR_H
60 typedef std::map<std::pair<DetElement,int>, std::pair<int,int> >
LeafCount;
92 const std::string& sd_type,
93 const std::string& sd_match,
94 const std::string& sd_veto,
95 const std::string& sd_mat,
122 const std::string&
det,
123 const string& sd_match,
124 const string& sd_veto,
125 const string& sd_type,
126 const string& sd_mat,
int sd_lvl,
135 except(
"DetElementCreator",
136 "++ Failed to extract MATERIAL from the element table.");
145 stringstream str, id_str;
147 printout(INFO,pref,
"DetElementCreator: +++++++++++++++ Summary of sensitve elements ++++++++++++++++++++++++");
149 printout(INFO,pref,
"DetElementCreator: ++ Summary: SD: %-24s %7d DetElements %7d sensitives out of %7d volumes",
150 (c.first.name()+
string(
":")).c_str(), c.second.elements, c.second.sensitives, c.second.volumes);
151 total.
elements += c.second.elements;
153 total.
volumes += c.second.volumes;
155 printout(INFO,pref,
"DetElementCreator: ++ Summary: %-24s %7d DetElements %7d sensitives out of %7d volumes",
157 printout(INFO,pref,
"DetElementCreator: +++++++++++++++ Summary of geometry depth analysis ++++++++++++++++++");
158 int total_cnt = 0, total_depth = 0;
159 map<DetElement, vector<pair<int,int> > > fields;
162 printout(INFO,pref,
"DetElementCreator: ++ Summary: SD: %-24s system:%04X Lvl:%3d Sensitives: %6d [Max: %6d].",
163 (de.
name()+
string(
":")).c_str(), de.
id(),
164 l.first.second, l.second.second, l.second.first);
165 fields[de].emplace_back(l.first.second,l.second.first);
166 total_depth += l.second.second;
169 if ( 0 == total_depth ) { }
170 printout(INFO, pref,
"DetElementCreator: ++ Summary: %-24s %d.",
"Total DetElements:", total_cnt);
171 printout(INFO, pref,
"DetElementCreator: +++++++++++++++ Readout structure generation ++++++++++++++++++++++++");
173 for(
const auto& f : fields ) {
174 string ro_name = f.first.name() + string(
"Hits");
177 id_str <<
"system:" << num_bits;
178 for(
const auto& q : f.second ) {
180 if ( q.second < 1<<0 ) bits = 1;
181 else if ( q.second < 1<<1 ) bits = 1;
182 else if ( q.second < 1<<2 ) bits = 2;
183 else if ( q.second < 1<<3 ) bits = 3;
184 else if ( q.second < 1<<4 ) bits = 4;
185 else if ( q.second < 1<<5 ) bits = 5;
186 else if ( q.second < 1<<6 ) bits = 6;
187 else if ( q.second < 1<<7 ) bits = 7;
188 else if ( q.second < 1<<8 ) bits = 8;
189 else if ( q.second < 1<<9 ) bits = 9;
190 else if ( q.second < 1<<10 ) bits = 10;
191 else if ( q.second < 1<<11 ) bits = 11;
192 else if ( q.second < 1<<12 ) bits = 12;
193 else if ( q.second < 1<<13 ) bits = 13;
194 else if ( q.second < 1<<14 ) bits = 14;
195 else if ( q.second < 1<<15 ) bits = 15;
197 id_str <<
",Lv" << q.first <<
":" << bits;
200 string idspec = id_str.str();
201 str <<
"<readout name=\"" << ro_name <<
"\">" << endl
204 <<
"</id> <!-- Number of bits: " << num_bits <<
" -->" << endl
205 <<
"</readout>" << endl;
217 printout(INFO,pref,
"DetElementCreator: ++ Setting up readout for subdetector:%-24s id:%04X",
218 f.first.name(), f.first.id());
221 printout(ERROR,pref,
"DetElementCreator: ++ FAILED to setup readout for subdetector:%-24s id:%04X [%s]",
222 f.first.name(), f.first.id(), e.what());
225 printout(INFO,pref,
"DetElementCreator: "
226 "+++++++++++++++ ID Descriptor generation ++++++++++++++++++++++++++++");
227 printout(INFO,
"",str.str().c_str());
233 ::snprintf(volid,
sizeof(volid),
"Lv%d", p.second.first);
234 printout(DEBUG,pref,
"DetElementCreator: ++ Set volid (%-24s): %-6s = %3d -> %s (%p)",
236 volid, p.second.second, place.
name(), place.
ptr());
240 except(pref,
"DetElementCreator: Exception on destruction: %s", e.what());
243 except(pref,
"DetElementCreator: UNKNOWN Exception on destruction.");
246 printout(ALWAYS, pref,
"DetElementCreator: ++ Instrumented %ld subdetectors with %d "
247 "DetElements %d sensitives out of %d volumes and %ld sensitive placements.",
254 string nam = pv.
name();
255 size_t idx = string::npos;
256 string nnam = nam.substr(0, idx);
259 except(
"DetElementCreator",
"++ Cannot deduce name from invalid PlacedVolume handle!");
267 det.setPlacement(pv);
277 auto& data =
stack.back();
286 det.setPlacement(pv);
288 det.placement().addPhysVolID(
"system",
det.id());
292 printout(
printLevel,
"DetElementCreator",
"++ Added sub-detector element: %s",
det.path().c_str());
306 int idx = pv->GetMotherVolume()->GetIndex(pv.
ptr())+1;
308 cnt.first = std::max(cnt.first,idx);
320 string pv_nam = pv.
name();
337 auto& data =
stack.back();
340 if ( data.sensitive ) {
357 if ( data.vol_count > 0 ) {
358 parent.daughter_count += data.vol_count;
359 parent.daughter_count += data.daughter_count;
360 data.has_sensitive =
true;
363 parent.daughter_count += data.daughter_count;
364 data.has_sensitive = (data.daughter_count>0);
367 if ( data.has_sensitive ) {
370 if ( data.pv.volIDs().empty() ) {
372 ::snprintf(text,
sizeof(text),
"Lv%d", lvl);
373 data.pv.addPhysVolID(text, data.pv->GetMotherVolume()->GetIndex(data.pv.ptr())+1);
378 printout(ERROR,
"DetElementCreator",
"PLacement VOLID error: %d <> %d",lvl,(*e).second.first);
382 for(
size_t i=1; i<
stack.size(); ++i ) {
384 auto& p =
stack[i-1];
385 if ( !d.element.isValid() ) {
390 p.has_sensitive =
true;
393 "++ Assign detector element: %s (%p, %ld children) to %s (%p) with %ld vols",
394 data.element.name(), data.element.ptr(), data.element.children().size(),
395 parent.element.name(), parent.element.ptr(), data.vol_count);
400 int idx = data.pv->GetMotherVolume()->GetIndex(data.pv.ptr())+1;
404 cnt_det.first = std::max(cnt_det.first,idx);
406 printout(
printLevel,
"DetElementCreator",
"++ [%ld] Added element: %s",
407 stack.size(), data.element.path().c_str());
409 if ( !added && data.element.isValid() ) {
410 printout(WARNING,
"MEMORY-LEAK",
"Level:%3d Orpahaned DetElement:%s Daugthers:%d Parent:%s",
411 int(
stack.size()), data.element.name(), data.vol_count, parent.pv.name());
430 static void* create_object(
Detector& description,
int argc,
char** argv) {
431 PrintLevel prt = DEBUG;
432 size_t sd_level = 99999;
433 string sd_mat, sd_match, sd_veto, sd_type, detector;
434 for(
int i = 0; i < argc && argv[i]; ++i) {
435 if ( 0 == ::strncmp(
"-material",argv[i],5) )
437 else if ( 0 == ::strncmp(
"-match",argv[i],5) )
438 sd_match = argv[++i];
439 else if ( 0 == ::strncmp(
"-detector",argv[i],5) )
440 detector = argv[++i];
441 else if ( 0 == ::strncmp(
"-veto",argv[i],5) )
443 else if ( 0 == ::strncmp(
"-type",argv[i],5) )
445 else if ( 0 == ::strncmp(
"-level",argv[i],5) )
446 sd_level = ::atol(argv[++i]);
447 else if ( 0 == ::strncmp(
"-print",argv[i],5) )
448 prt = decodePrintLevel(argv[++i]);
452 if ( sd_mat.empty() || sd_match.empty() || sd_type.empty() ) {
454 "Usage: -plugin <name> -arg [-arg] \n"
455 " name: factory name DD4hep_ROOTGDMLParse \n"
456 " -material <string> Sensitive material name (identifier) \n"
457 " -match <string> Matching string for subdetector identification \n"
458 "\tArguments given: " << arguments(argc,argv) << endl << flush;