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 printout(INFO,pref,
"DetElementCreator: ++ Summary: %-24s %d.",
"Total DetElements:",total_cnt);
170 printout(INFO,pref,
"DetElementCreator: +++++++++++++++ Readout structure generation ++++++++++++++++++++++++");
172 for(
const auto& f : fields ) {
173 string ro_name = f.first.name() + string(
"Hits");
176 id_str <<
"system:" << num_bits;
177 for(
const auto& q : f.second ) {
179 if ( q.second < 1<<0 ) bits = 1;
180 else if ( q.second < 1<<1 ) bits = 1;
181 else if ( q.second < 1<<2 ) bits = 2;
182 else if ( q.second < 1<<3 ) bits = 3;
183 else if ( q.second < 1<<4 ) bits = 4;
184 else if ( q.second < 1<<5 ) bits = 5;
185 else if ( q.second < 1<<6 ) bits = 6;
186 else if ( q.second < 1<<7 ) bits = 7;
187 else if ( q.second < 1<<8 ) bits = 8;
188 else if ( q.second < 1<<9 ) bits = 9;
189 else if ( q.second < 1<<10 ) bits = 10;
190 else if ( q.second < 1<<11 ) bits = 11;
191 else if ( q.second < 1<<12 ) bits = 12;
192 else if ( q.second < 1<<13 ) bits = 13;
193 else if ( q.second < 1<<14 ) bits = 14;
194 else if ( q.second < 1<<15 ) bits = 15;
196 id_str <<
",Lv" << q.first <<
":" << bits;
199 string idspec = id_str.str();
200 str <<
"<readout name=\"" << ro_name <<
"\">" << endl
203 <<
"</id> <!-- Number of bits: " << num_bits <<
" -->" << endl
204 <<
"</readout>" << endl;
216 printout(INFO,pref,
"DetElementCreator: ++ Setting up readout for subdetector:%-24s id:%04X",
217 f.first.name(), f.first.id());
220 printout(ERROR,pref,
"DetElementCreator: ++ FAILED to setup readout for subdetector:%-24s id:%04X [%s]",
221 f.first.name(), f.first.id(), e.what());
224 printout(INFO,pref,
"DetElementCreator: "
225 "+++++++++++++++ ID Descriptor generation ++++++++++++++++++++++++++++");
226 printout(INFO,
"",str.str().c_str());
232 ::snprintf(volid,
sizeof(volid),
"Lv%d", p.second.first);
233 printout(DEBUG,pref,
"DetElementCreator: ++ Set volid (%-24s): %-6s = %3d -> %s (%p)",
235 volid, p.second.second, place.
name(), place.
ptr());
239 except(pref,
"DetElementCreator: Exception on destruction: %s", e.what());
242 except(pref,
"DetElementCreator: UNKNOWN Exception on destruction.");
245 printout(ALWAYS, pref,
"DetElementCreator: ++ Instrumented %ld subdetectors with %d "
246 "DetElements %d sensitives out of %d volumes and %ld sensitive placements.",
253 string nam = pv.
name();
254 size_t idx = string::npos;
255 string nnam = nam.substr(0, idx);
258 except(
"DetElementCreator",
"++ Cannot deduce name from invalid PlacedVolume handle!");
266 det.setPlacement(pv);
276 auto& data =
stack.back();
285 det.setPlacement(pv);
287 det.placement().addPhysVolID(
"system",
det.id());
291 printout(
printLevel,
"DetElementCreator",
"++ Added sub-detector element: %s",
det.path().c_str());
305 int idx = pv->GetMotherVolume()->GetIndex(pv.
ptr())+1;
307 cnt.first = std::max(cnt.first,idx);
319 string pv_nam = pv.
name();
336 auto& data =
stack.back();
339 if ( data.sensitive ) {
356 if ( data.vol_count > 0 ) {
357 parent.daughter_count += data.vol_count;
358 parent.daughter_count += data.daughter_count;
359 data.has_sensitive =
true;
362 parent.daughter_count += data.daughter_count;
363 data.has_sensitive = (data.daughter_count>0);
366 if ( data.has_sensitive ) {
369 if ( data.pv.volIDs().empty() ) {
371 ::snprintf(text,
sizeof(text),
"Lv%d", lvl);
372 data.pv.addPhysVolID(text, data.pv->GetMotherVolume()->GetIndex(data.pv.ptr())+1);
377 printout(ERROR,
"DetElementCreator",
"PLacement VOLID error: %d <> %d",lvl,(*e).second.first);
381 for(
size_t i=1; i<
stack.size(); ++i) {
383 auto& p =
stack[i-1];
384 if ( !d.element.isValid() ) {
389 p.has_sensitive =
true;
392 "++ Assign detector element: %s (%p, %ld children) to %s (%p) with %ld vols",
393 data.element.name(), data.element.ptr(), data.element.children().size(),
394 parent.element.name(), parent.element.ptr(), data.vol_count);
399 int idx = data.pv->GetMotherVolume()->GetIndex(data.pv.ptr())+1;
403 cnt_det.first = std::max(cnt_det.first,idx);
405 printout(
printLevel,
"DetElementCreator",
"++ [%ld] Added element: %s",
406 stack.size(), data.element.path().c_str());
408 if ( !added && data.element.isValid() ) {
409 printout(WARNING,
"MEMORY-LEAK",
"Level:%3d Orpahaned DetElement:%s Daugthers:%d Parent:%s",
410 int(
stack.size()), data.element.name(), data.vol_count, parent.pv.name());
429 static void* create_object(
Detector& description,
int argc,
char** argv) {
430 PrintLevel prt = DEBUG;
431 size_t sd_level = 99999;
432 string sd_mat, sd_match, sd_veto, sd_type, detector;
433 for(
int i = 0; i < argc && argv[i]; ++i) {
434 if ( 0 == ::strncmp(
"-material",argv[i],5) )
436 else if ( 0 == ::strncmp(
"-match",argv[i],5) )
437 sd_match = argv[++i];
438 else if ( 0 == ::strncmp(
"-detector",argv[i],5) )
439 detector = argv[++i];
440 else if ( 0 == ::strncmp(
"-veto",argv[i],5) )
442 else if ( 0 == ::strncmp(
"-type",argv[i],5) )
444 else if ( 0 == ::strncmp(
"-level",argv[i],5) )
445 sd_level = ::atol(argv[++i]);
446 else if ( 0 == ::strncmp(
"-print",argv[i],5) )
447 prt = decodePrintLevel(argv[++i]);
451 if ( sd_mat.empty() || sd_match.empty() || sd_type.empty() ) {
453 "Usage: -plugin <name> -arg [-arg] \n"
454 " name: factory name DD4hep_ROOTGDMLParse \n"
455 " -material <string> Sensitive material name (identifier) \n"
456 " -match <string> Matching string for subdetector identification \n"
457 "\tArguments given: " << arguments(argc,argv) << endl << flush;