30 #include <TGeoBoolNode.h>
31 #include <TGeoSystemOfUnits.h>
46 bool is_volume(
const TGeoVolume* volume) {
50 inline double check_null(
double d) {
51 if ( fabs(d) < 1e-12 )
56 template <
typename O,
typename C,
typename F>
void handle(
const O* o,
const C& c, F pmf) {
57 for (
typename C::const_iterator i = c.begin(); i != c.end(); ++i) {
62 void _do_output(
const std::string& title,
bool reorder,
bool with_file,
bool have_hash,
const T& container) {
64 std::string tit = title +
":";
65 char delim = have_hash ?
'\'' :
' ';
66 std::string fname = title +
"s.txt";
69 out.open(fname, std::ios::out);
72 std::map<DetectorChecksum::hash_t, const DetectorChecksum::entry_t*> m;
73 for(
const auto& e : container)
74 m.emplace(e.second.hash, &e.second);
76 for(
const auto& e : m) {
77 auto data = format(
nullptr,
"+++ %-12s0x%016lx %c%s%c",
78 tit.c_str(), e.second->hash, delim, have_hash ? e.second->data.c_str() :
"", delim);
79 printout(ALWAYS,
"DetectorChecksum", data.c_str());
80 if ( with_file ) out << data << std::endl;
84 for(
const auto& e : container) {
85 auto data = format(
nullptr,
"+++ %-12s0x%016lx %c%s%c",
86 tit.c_str(), e.second.hash, delim, have_hash ? e.second.data.c_str() :
"", delim);
87 printout(ALWAYS,
"DetectorChecksum", data.c_str());
88 if ( with_file ) out << data << std::endl;
92 void _do_output_name(
const std::string& title,
bool reorder,
bool with_file,
bool have_hash,
const T& container) {
94 std::string tit = title +
":";
95 char delim = have_hash ?
'\'' :
' ';
96 std::string fname = title +
"s.txt";
99 out.open(fname, std::ios::out);
102 std::map<DetectorChecksum::hash_t, const DetectorChecksum::entry_t*> m;
103 std::map<DetectorChecksum::hash_t, typename T::key_type>
v;
104 for(
const auto& e : container) {
105 v.emplace(e.second.hash, e.first);
106 m.emplace(e.second.hash, &e.second);
108 for(
const auto& e : m) {
109 auto data = format(
nullptr,
"+++ %-12s0x%016lx %-32s %c%s%c",
110 tit.c_str(), e.second->hash,
v[e.first].
name(),
111 delim, have_hash ? e.second->data.c_str() :
"", delim);
112 printout(ALWAYS,
"DetectorChecksum", data.c_str());
113 if ( with_file ) out << data << std::endl;
117 for(
const auto& e : container) {
118 auto data = format(
nullptr,
"+++ %-12s0x%016lx %-32s %c%s%c",
119 tit.c_str(), e.second.hash, e.first.name(),
120 delim, have_hash ? e.second.data.c_str() :
"", delim);
121 printout(ALWAYS,
"DetectorChecksum", data.c_str());
122 if ( with_file ) out << data << std::endl;
129 : m_detDesc(description), m_dataPtr(0) {
139 std::string nam =
handle->GetName();
140 std::size_t idx = nam.find(
"_0x");
141 if ( idx == std::string::npos )
return nam;
142 return nam.substr(0, idx);
146 std::string nam =
handle->name();
147 std::size_t idx = nam.find(
"_0x");
148 if ( idx == std::string::npos )
return nam;
149 return nam.substr(0, idx);
158 std::stringstream log;
159 log.setf(std::ios::fixed, std::ios::floatfield);
165 std::string
data(log.str());
168 return { hash_value, std::move(
data) };
169 return { hash_value, std::string(
"") };
179 printout(INFO,
"DetectorChecksum",
"+++ Float precision: %d",
precision);
180 printout(INFO,
"DetectorChecksum",
"+++ Unit of length: %-12s -> conversion factor: %f",
m_len_unit_nam.c_str(),
m_len_unit);
181 printout(INFO,
"DetectorChecksum",
"+++ Unit of angle: %-12s -> conversion factor: %f",
m_ang_unit_nam.c_str(),
m_ang_unit);
182 printout(INFO,
"DetectorChecksum",
"+++ Unit of energy: %-12s -> conversion factor: %f",
m_ene_unit_nam.c_str(),
m_ene_unit);
183 printout(INFO,
"DetectorChecksum",
"+++ Unit of density: %-12s -> conversion factor: %f",
m_densunit_nam.c_str(),
m_densunit);
184 printout(INFO,
"DetectorChecksum",
"+++ Unit of density: %-12s -> conversion factor: %f",
m_atomunit_nam.c_str(),
m_atomunit);
191 auto iel = geo.find(element);
192 if ( iel == geo.end() ) {
193 if ( element->HasIsotopes() ) {
194 except(
"DetectorChecksum",
"%s: Atoms with isotopes not implemented", element.
name());
197 std::stringstream log =
logger();
199 <<
" Z=\"" << element->Z() <<
"\""
200 <<
" formula=\"" << element.
name() <<
"\""
203 <<
"\" value=\"" << std::scientific << element->A()/
m_atomunit <<
"\"/>" <<
newline
205 iel = geo.emplace(element,
make_entry(log) ).first;
214 auto ima = geo.find(medium);
215 if ( ima == geo.end() ) {
216 std::stringstream log =
logger();
217 auto* mat = medium->GetMaterial();
219 if ( mat->IsMixture() ) {
220 std::map<std::string, double> elts;
221 TGeoMixture*
mix = (TGeoMixture*)mat;
222 int count_elts =
mix->GetNelements();
223 for ( Int_t idx = 0; idx < count_elts; idx++ )
225 log <<
" <elements count=\""<< count_elts <<
"\">" <<
newline;
226 for(
const auto& w : elts )
227 log <<
" <fraction ref=\"" << w.first <<
"\" n=\"" << w.second <<
"\">" <<
newline;
228 log <<
" </elements>" <<
newline;
231 log <<
" A=\"" << mat->GetA() <<
"\""
232 <<
" Z=\"" << mat->GetZ() <<
"\">" <<
newline
233 <<
" <element=\"" <<
refName(mat->GetElement()) <<
"\"/>" <<
newline
237 log <<
"</material>";
238 ima = geo.emplace(medium,
make_entry(log)).first;
246 auto iso = geo.find(solid);
247 if ( iso == geo.end() ) {
248 const TGeoShape* shape = solid.
ptr();
252 log <<
"<shape type=\"INVALID\"></shape>)";
253 iso = geo.emplace(solid,
make_entry(log)).first;
260 TClass* cl = shape->IsA();
261 std::string nam =
"";
262 if ( cl == TGeoBBox::Class() ) {
263 TGeoBBox* sh = (TGeoBBox*) shape;
266 <<
" x=\"" << 2.0*sh->GetDX()/
m_len_unit <<
"\""
267 <<
" y=\"" << 2.0*sh->GetDY()/
m_len_unit <<
"\""
268 <<
" z=\"" << 2.0*sh->GetDZ()/
m_len_unit <<
"\""
271 else if ( cl == TGeoHalfSpace::Class() ) {
272 TGeoHalfSpace* sh = (TGeoHalfSpace*)(
const_cast<TGeoShape*
>(shape));
273 const auto& pnt = sh->GetPoint();
274 const auto& nrm = sh->GetNorm();
275 log <<
"<halfspace" << nam
277 <<
" <point x=\"" << pnt[0]/
m_len_unit <<
"\""
280 <<
" <normal x=\"" << nrm[0]/
m_len_unit <<
"\""
285 else if ( cl == TGeoTube::Class() || cl == TGeoTubeSeg::Class() ) {
286 const TGeoTube* sh = (
const TGeoTube*) shape;
287 log <<
"<tube" << nam
290 <<
" rmin=\"" << check_null(sh->GetRmin()/
m_len_unit) <<
"\""
291 <<
" rmax=\"" << check_null(sh->GetRmax()/
m_len_unit) <<
"\""
292 <<
" dz=\"" << check_null(2*sh->GetDz()/
m_len_unit) <<
"\""
293 <<
" startphi=\"" << 0.0 <<
"\""
297 else if ( cl == TGeoTubeSeg::Class() ) {
298 const TGeoTubeSeg* sh = (
const TGeoTubeSeg*) shape;
299 log <<
"<tube" << nam
302 <<
" rmin=\"" << check_null(sh->GetRmin()/
m_len_unit) <<
"\""
303 <<
" rmax=\"" << check_null(sh->GetRmax()/
m_len_unit) <<
"\""
304 <<
" dz=\"" << check_null(2*sh->GetDz()/
m_len_unit) <<
"\""
305 <<
" startphi=\"" << sh->GetPhi1()/
m_ang_unit <<
"\""
306 <<
" deltaphi=\"" << (sh->GetPhi2() - sh->GetPhi1())/
m_ang_unit <<
"\""
309 else if ( cl == TGeoCtub::Class() ) {
310 const TGeoCtub* sh = (
const TGeoCtub*) shape;
311 const Double_t* hi = sh->GetNhigh();
312 const Double_t* lo = sh->GetNlow();
313 log <<
"<cutTube" << nam
316 <<
" rmin=\"" << sh->GetRmin()/
m_len_unit <<
"\""
317 <<
" rmax=\"" << sh->GetRmax()/
m_len_unit <<
"\""
318 <<
" dz=\"" << 2*sh->GetDz()/
m_len_unit <<
"\""
319 <<
" startphi=\"" << sh->GetPhi1()/
m_ang_unit <<
"\""
320 <<
" deltaphi=\"" << (sh->GetPhi2() - sh->GetPhi1())/
m_ang_unit <<
"\""
329 else if ( cl == TGeoEltu::Class() ) {
330 const TGeoEltu* sh = (
const TGeoEltu*) shape;
331 log <<
"<eltube" << nam
338 else if ( cl == TGeoTrd1::Class() ) {
339 const TGeoTrd1* sh = (
const TGeoTrd1*) shape;
342 <<
" x1=\"" << 2*check_null(sh->GetDx1()/
m_len_unit) <<
"\""
343 <<
" x2=\"" << 2*check_null(sh->GetDx2()/
m_len_unit) <<
"\""
344 <<
" y1=\"" << 2*check_null(sh->GetDy()/
m_len_unit) <<
"\""
345 <<
" y2=\"" << 2*check_null(sh->GetDy()/
m_len_unit) <<
"\""
346 <<
" z=\"" << 2*check_null(sh->GetDz()/
m_len_unit) <<
"\""
349 else if ( cl == TGeoTrd2::Class() ) {
350 const TGeoTrd2* sh = (
const TGeoTrd2*) shape;
353 <<
" x1=\"" << 2*check_null(sh->GetDx1()/
m_len_unit) <<
"\""
354 <<
" x2=\"" << 2*check_null(sh->GetDx2()/
m_len_unit) <<
"\""
355 <<
" y1=\"" << 2*check_null(sh->GetDy1()/
m_len_unit) <<
"\""
356 <<
" y2=\"" << 2*check_null(sh->GetDy2()/
m_len_unit) <<
"\""
357 <<
" z=\"" << 2*check_null(sh->GetDz()/
m_len_unit) <<
"\""
360 else if ( cl == TGeoTrap::Class() ) {
361 const TGeoTrap* sh = (
const TGeoTrap*) shape;
362 log <<
"<trap" << nam
365 <<
" z=\"" << check_null(2*sh->GetDz()/
m_len_unit) <<
"\""
366 <<
" theta=\"" << check_null(sh->GetTheta()/
m_ang_unit) <<
"\""
367 <<
" phi=\"" << check_null(sh->GetPhi()/
m_ang_unit) <<
"\""
368 <<
" x1=\"" << check_null(2*sh->GetBl1()/
m_len_unit) <<
"\""
369 <<
" x2=\"" << check_null(2*sh->GetTl1()/
m_len_unit) <<
"\""
370 <<
" x3=\"" << check_null(2*sh->GetBl2()/
m_len_unit) <<
"\""
371 <<
" x4=\"" << check_null(2*sh->GetTl2()/
m_len_unit) <<
"\""
372 <<
" y1=\"" << check_null(2*sh->GetH1()/
m_len_unit) <<
"\""
373 <<
" y2=\"" << check_null(2*sh->GetH2()/
m_len_unit) <<
"\""
374 <<
" alpha1=\"" << check_null(sh->GetAlpha1()/
m_ang_unit) <<
"\""
375 <<
" alpha2=\"" << check_null(sh->GetAlpha2()/
m_ang_unit) <<
"\""
378 else if ( cl == TGeoHype::Class() ) {
379 const TGeoHype* sh = (
const TGeoHype*) shape;
380 log <<
"<hype" << nam
383 <<
" rmin=\"" << check_null(sh->GetRmin()/
m_len_unit) <<
"\""
384 <<
" rmax=\"" << check_null(sh->GetRmax()/
m_len_unit) <<
"\""
385 <<
" inst=\"" << check_null(sh->GetStIn()/
m_ang_unit) <<
"\""
386 <<
" outst=\"" << check_null(sh->GetStOut()/
m_ang_unit) <<
"\""
387 <<
" z=\"" << check_null(2*sh->GetDz()/
m_len_unit) <<
"\""
390 else if ( cl == TGeoPgon::Class() ) {
391 const TGeoPgon* sh = (
const TGeoPgon*) shape;
392 log <<
"<polyhedra" << nam
395 <<
" startphi=\"" << check_null(sh->GetPhi1()/
m_ang_unit) <<
"\""
396 <<
" deltaphi=\"" << check_null(sh->GetDphi()/
m_ang_unit) <<
"\""
397 <<
" numsides=\"" << sh->GetNedges() <<
"\">" <<
newline;
398 for(
int i=0, n=sh->GetNz(); i<n; ++i) {
399 log <<
" <zplane z=\"" << check_null(sh->GetZ(i)/
m_len_unit)
400 <<
"\" rmin=\"" << check_null(sh->GetRmin(i)/
m_len_unit) <<
"\""
403 log <<
"</polyhedra>";
405 else if ( cl == TGeoPcon::Class() ) {
406 const TGeoPcon* sh = (
const TGeoPcon*) shape;
407 log <<
"<polycone" << nam
410 <<
" startphi=\"" << check_null(sh->GetPhi1()/
m_ang_unit) <<
"\""
412 for(
int i=0, n=sh->GetNz(); i<n; ++i) {
413 log <<
" <zplane z=\"" << check_null(sh->GetZ(i)/
m_len_unit)
414 <<
"\" rmin=\"" << check_null(sh->GetRmin(i)/
m_len_unit) <<
"\""
417 log <<
"</polycone>";
419 else if ( cl == TGeoCone::Class() ) {
420 const TGeoCone* sh = (
const TGeoCone*) shape;
421 log <<
"<cone" << nam
424 <<
" rmin1=\"" << check_null(sh->GetRmin1()/
m_len_unit) <<
"\""
425 <<
" rmin2=\"" << check_null(sh->GetRmin2()/
m_len_unit) <<
"\""
426 <<
" rmax1=\"" << check_null(sh->GetRmax1()/
m_len_unit) <<
"\""
427 <<
" rmax2=\"" << check_null(sh->GetRmax2()/
m_len_unit) <<
"\""
428 <<
" z=\"" << check_null(sh->GetDz()/
m_len_unit) <<
"\""
433 else if ( cl == TGeoConeSeg::Class() ) {
435 log <<
"<cone" << nam
438 <<
" rmin1=\"" << check_null(sh->GetRmin1()/
m_len_unit) <<
"\""
439 <<
" rmin2=\"" << check_null(sh->GetRmin2()/
m_len_unit) <<
"\""
440 <<
" rmax1=\"" << check_null(sh->GetRmax1()/
m_len_unit) <<
"\""
441 <<
" rmax2=\"" << check_null(sh->GetRmax2()/
m_len_unit) <<
"\""
442 <<
" z=\"" << check_null(sh->GetDz()/
m_len_unit) <<
"\""
443 <<
" startphi=\"" << check_null(sh->GetPhi1()/
m_ang_unit) <<
"\""
444 <<
" deltaphi=\"" << check_null((sh->GetPhi1()-sh->GetPhi1())/
m_ang_unit) <<
"\""
447 else if ( cl == TGeoParaboloid::Class() ) {
448 const TGeoParaboloid* sh = (
const TGeoParaboloid*) shape;
449 log <<
"<paraboloid" << nam
451 <<
" rlo=\"" << sh->GetRlo()/
m_len_unit <<
"\""
452 <<
" rhi=\"" << sh->GetRhi()/
m_len_unit <<
"\""
456 else if ( cl == TGeoSphere::Class() ) {
457 const TGeoSphere* sh = (
const TGeoSphere*) shape;
458 log <<
"<sphere" << nam
461 <<
" rmin=\"" << sh->GetRmin()/
m_len_unit <<
"\""
462 <<
" rmax=\"" << sh->GetRmax()/
m_len_unit <<
"\""
463 <<
" startphi=\"" << sh->GetPhi1()/
m_ang_unit <<
"\""
464 <<
" deltaphi=\"" << (sh->GetPhi1()-sh->GetPhi1())/
m_ang_unit <<
"\""
465 <<
" starttheta=\"" << sh->GetTheta1()/
m_ang_unit <<
"\""
466 <<
" deltatheta=\"" << (sh->GetTheta1()-sh->GetTheta1())/
m_ang_unit <<
"\""
469 else if ( cl == TGeoTorus::Class() ) {
470 const TGeoTorus* sh = (
const TGeoTorus*) shape;
471 log <<
"<torus" << nam
474 <<
" rtor=\"" << sh->GetR()/
m_len_unit <<
"\""
475 <<
" rmin=\"" << sh->GetRmin()/
m_len_unit <<
"\""
476 <<
" rmax=\"" << sh->GetRmax()/
m_len_unit <<
"\""
477 <<
" startphi=\"" << sh->GetPhi1()/
m_ang_unit <<
"\""
478 <<
" deltaphi=\"" << sh->GetDphi()/
m_ang_unit <<
"\""
481 else if ( cl == TGeoArb8::Class() ) {
482 TGeoArb8* sh = (TGeoArb8*) shape;
483 const Double_t*
v = sh->GetVertices();
484 log <<
"<arb8" << nam
504 else if ( cl == TGeoXtru::Class() ) {
505 const TGeoXtru* sh = (
const TGeoXtru*) shape;
506 log <<
"<xtru" << nam <<
">" <<
newline;
507 for (
int i = 0; i < sh->GetNvert(); i++) {
508 log <<
" <twoDimVertex x=\"" << sh->GetX(i)/
m_len_unit <<
"\""
511 for (
int i = 0; i < sh->GetNz(); i++) {
512 log <<
" <section zOrder=\"" << i <<
"\""
513 <<
" scalingFactor=\"" << sh->GetScale(i) <<
"\""
514 <<
" zPosition=\"" << sh->GetZ(i)/
m_len_unit <<
"\""
515 <<
" xOffset=\"" << sh->GetXOffset(i)/
m_len_unit <<
"\""
520 else if (shape->IsA() == TGeoCompositeShape::Class() ) {
521 const TGeoCompositeShape* sh = (
const TGeoCompositeShape*)shape;
522 const TGeoBoolNode*
boolean = sh->GetBoolNode();
523 const TGeoShape* left =
boolean->GetLeftShape();
524 const TGeoShape* right =
boolean->GetRightShape();
525 const TGeoMatrix* mat_left =
boolean->GetLeftMatrix();
526 const TGeoMatrix* mat_right =
boolean->GetRightMatrix();
527 std::string str_oper;
529 TGeoBoolNode::EGeoBoolType oper =
boolean->GetBooleanOperator();
530 if (oper == TGeoBoolNode::kGeoSubtraction)
531 str_oper =
"subtraction";
532 else if (oper == TGeoBoolNode::kGeoUnion)
534 else if (oper == TGeoBoolNode::kGeoIntersection)
535 str_oper =
"intersection";
537 if ( left->IsA() == TGeoScaledShape::Class() && right->IsA() == TGeoBBox::Class() ) {
538 const auto* scaled = (TGeoScaledShape*)left;
539 const auto* sphere = (TGeoSphere*)scaled->GetShape();
540 const auto* box = (TGeoBBox*)right;
541 if ( scaled->IsA() == TGeoSphere::Class() && oper == TGeoBoolNode::kGeoIntersection ) {
542 Double_t sx = scaled->GetScale()->GetScale()[0];
543 Double_t sy = scaled->GetScale()->GetScale()[1];
544 Double_t ax = sx * sphere->GetRmax();
545 Double_t by = sy * sphere->GetRmax();
546 Double_t cz = sphere->GetRmax();
547 Double_t dz = box->GetDZ();
548 Double_t zorig = box->GetOrigin()[2];
549 Double_t zcut2 = dz + zorig;
550 Double_t zcut1 = 2 * zorig - zcut2;
551 log <<
"<ellipsoid" << nam
558 iso = geo.emplace(solid,
make_entry(log)).first;
570 log <<
"<" << str_oper << nam
573 <<
" <first ref=\"" << (
void*)ent_left.
hash <<
"\"" <<
">" <<
newline
577 <<
" <second ref=\"" << (
void*)ent_right.
hash <<
"\"" <<
">" <<
newline
581 <<
"</" << str_oper <<
">";
583 else if ( shape->IsA() == TGeoScaledShape::Class() ) {
584 const TGeoScaledShape* sh = (TGeoScaledShape*)shape;
585 const TGeoShape* org = sh->GetShape();
586 const double* scl = sh->GetScale()->GetScale();
587 log <<
"<scaled_shape" << nam
588 <<
" sx=\"" << scl[0] <<
"\""
589 <<
" sy=\"" << scl[1] <<
"\""
590 <<
" sz=\"" << scl[2] <<
"\">" <<
newline
592 <<
"</scaled_shape>";
594 else if ( shape->IsA() == TGeoShapeAssembly::Class() ) {
595 log <<
"<shape_assembly " << nam <<
"\"/>";
597 else if ( shape->IsA() == TGeoTessellated::Class() ) {
599 const TGeoTessellated* sh = (TGeoTessellated*)shape;
601 if ( sh->IsClosedBody() == false ) {
602 except(
"DetectorChecksum",
"+++ TGeoTessellated volume is not closed: %s", solid.
name());
604 for (
int ivertex = 0; ivertex < sh->GetNvertices(); ivertex++) {
606 const auto& vtx =
const_cast<TGeoTessellated*
>(sh)->GetVertex(ivertex);
607 log <<
"<position name\"" << nam <<
"_v" << ivertex
615 log <<
"<tessellated name=\"" << nam <<
"\">" <<
newline;
616 for (
int ifacet = 0; ifacet < sh->GetNfacets(); ifacet++) {
618 const auto& facet =
const_cast<TGeoTessellated*
>(sh)->GetFacet(ifacet);
619 if ( facet.GetNvert() == 3 ) {
620 log <<
"<triangular";
622 else if ( facet.GetNvert() == 4 ) {
623 log <<
"<quadrangular";
626 except(
"DetectorChecksum",
"+++ TGeoTessellated volume with unsupported number of vertices: %s", solid.
name());
628 for (
int ivertex = 0; ivertex < facet.GetNvert(); ivertex++) {
629 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1)
630 auto vertexIndex = facet[ivertex];
632 auto vertexIndex = facet.GetVertexIndex(ivertex);
634 log <<
" vertex" << ivertex + 1 <<
"=\"" << nam <<
"_v" << vertexIndex <<
"\"";
636 log <<
" type=\"ABSOLUTE\"/>" <<
newline;
638 log <<
"</tessellated>" <<
newline;
641 log <<
"<tessellated></tessellated>" <<
newline;
645 except(
"DetectorChecksum",
"+++ Unknown shape: %s", solid.
name());
647 auto ins = geo.emplace(solid,
make_entry(log));
649 except(
"DetectorChecksum",
"+++ FAILED to register shape: %s", solid.
name());
659 auto ipo = geo.find(trafo);
660 if ( ipo == geo.end() ) {
661 const double* tr = trafo->GetTranslation();
662 std::stringstream log =
logger();
665 <<
" x=\"" << check_null(tr[0]/
m_len_unit) <<
"\""
666 <<
" y=\"" << check_null(tr[1]/
m_len_unit) <<
"\""
667 <<
" z=\"" << check_null(tr[2]/
m_len_unit) <<
"\"";
669 ipo = geo.emplace(trafo,
make_entry(log)).first;
677 auto iro = geo.find(trafo);
678 if ( iro == geo.end() ) {
680 std::stringstream log =
logger();
683 <<
" x=\"" << check_null(rot.X()/
m_ang_unit) <<
"\""
684 <<
" y=\"" << check_null(rot.Y()/
m_ang_unit) <<
"\""
685 <<
" z=\"" << check_null(rot.Z()/
m_ang_unit) <<
"\""
687 iro = geo.emplace(trafo,
make_entry(log)).first;
695 auto ivi = geo.find(attr);
696 if ( ivi == geo.end() ) {
697 std::stringstream log =
logger();
698 float red = 0, green = 0, blue = 0;
701 attr.
rgb(red, green, blue);
704 <<
" name=\"" << attr.
name() <<
"\""
705 <<
" visible=\"" << attr.
visible() <<
"\""
708 log <<
" line_style=\"unbroken\"";
710 log <<
" line_style=\"broken\"";
712 log <<
" line_style=\"solid\"";
714 log <<
" line_style=\"wireframe\"";
716 <<
" alpha=\"" << attr.
alpha()
717 <<
" R=\"" << red <<
"\""
718 <<
" B=\"" << blue <<
"\""
719 <<
" G=\"" << green <<
"\"/>" <<
newline;
721 ivi = geo.emplace(attr,
make_entry(log)).first;
729 auto ire = geo.find(region);
730 if ( ire == geo.end() ) {
731 std::stringstream log =
logger();
732 log <<
"<region name=\"" << region.
name() <<
"\""
734 <<
" cut=\"" << region.
cut() <<
"\""
738 ire = geo.emplace(region,
make_entry(log)).first;
746 auto ili = geo.find(lim);
747 if ( ili == geo.end() ) {
748 std::stringstream log =
logger();
749 const std::set<Limit>& obj = lim.
limits();
750 log <<
"<limitset name=\"" << lim.
name() <<
"\">" <<
newline;
751 for (
const auto& limit : obj) {
752 log <<
"<limit name=\"" << limit.name <<
"\""
753 <<
" unit=\"" << limit.unit <<
"\""
754 <<
" value=\"" << limit.value <<
"\""
755 <<
" particles=\"" << limit.particles <<
"\""
758 log <<
"</limitSet>";
759 ili = geo.emplace(lim,
make_entry(log)).first;
766 auto ial = geo.find(alignment);
767 if ( ial == geo.end() ) {
768 std::stringstream log =
logger();
769 const auto&
data = alignment.
data();
771 data.delta.pivot.GetComponents(x, y, z);
773 log <<
"<translation"
789 ial = geo.emplace(alignment,
make_entry(log)).first;
797 if ( is_volume(volume) ) {
808 printout(WARNING,
"DetectorChecksum",
"++ CollectVolume: Skip volume: %s",volume.
name());
815 auto ivo = geo.find(volume);
816 if ( ivo == geo.end() ) {
817 const TGeoVolume*
v = volume;
821 std::stringstream log =
logger();
822 TGeoShape* sh =
v->GetShape();
824 throw std::runtime_error(
"DetectorChecksum: No solid present for volume:" + nam);
826 if (
v->IsAssembly()) {
829 log <<
"<" << tag << nam
830 <<
" solid=\"" <<
refName(sh) <<
"\""
831 <<
" solid_hash=\"" << (
void*)solid_ent.hash <<
"\"";
834 TGeoMedium* med =
v->GetMedium();
836 throw std::runtime_error(
"DetectorChecksum: No material present for volume:" + nam);
839 log <<
"<" << tag << nam
840 <<
" material=\"" <<
refName(med) <<
"\""
841 <<
" solid=\"" <<
refName(sh) <<
"\""
842 <<
" solid_hash=\"" << (
void*)solid_ent.hash <<
"\"";
845 auto reg = volume.
region();
850 log <<
" limits=\"" <<
refName(lim) <<
"\"";
852 log <<
" region=\"" <<
refName(reg) <<
"\"";
854 log <<
" vis=\"" <<
refName(vis) <<
"\"";
856 log <<
" sensitive=\"" <<
refName(
det) <<
"\"";
857 const TObjArray* dau =
const_cast<TGeoVolume*
>(
v)->GetNodes();
858 if (dau && dau->GetEntries() > 0) {
860 for (Int_t i = 0, n_dau = dau->GetEntries(); i < n_dau; ++i) {
861 TGeoNode* node =
reinterpret_cast<TGeoNode*
>(dau->At(i));
863 log <<
" <physvol name=\"" <<
refName(node) <<
" hash=\"" << (
void*)ent.hash <<
"\"/>" <<
newline;
865 log <<
"</" << tag <<
">";
870 auto ins = geo.emplace(volume,
make_entry(log));
872 except(
"DetectorChecksum",
"+++ FAILED to register volume: %s", volume.
name());
882 auto ipl = geo.find(node);
883 if ( ipl == geo.end() ) {
884 TGeoMatrix* matrix = node->GetMatrix();
885 TGeoVolume* volume = node->GetVolume();
887 std::stringstream log =
logger();
889 <<
" volume=\"" <<
refName(volume) <<
"\"";
890 log <<
" volume_hash=\"" << (
void*)vol_ent.hash <<
"\"";
895 if ( matrix->IsRotation() ) {
901 const auto& ids = node.
volIDs();
902 for (
const auto& vid : ids )
904 <<
" name=\"" << vid.first <<
"\""
905 <<
" value=\"" << vid.second <<
"\""
909 ipl = geo.emplace(node,
make_entry(log)).first;
916 auto dit = geo.find(
det);
917 if ( dit == geo.end() ) {
918 std::stringstream log =
logger();
922 <<
" name=\"" <<
det.name() <<
"\""
923 <<
" id=\"" <<
det.id() <<
"\""
924 <<
" type=\"" <<
det.type() <<
"\""
925 <<
" key=\"" <<
det.key() <<
"\""
926 <<
" parent=\"" << (
void*)par.hash <<
"\""
927 <<
" flag=\"" <<
det.typeFlag() <<
"\""
928 <<
" combineHits=\"" <<
det.combineHits() <<
"\""
929 <<
" placement=\"" << (
void*)place.hash <<
"\""
940 auto isi = geo.find(sd);
941 if ( isi == geo.end() ) {
942 std::stringstream log =
logger();
943 log <<
"<sensitive_detector"
944 <<
" name=\"" <<
refName(sd) <<
"\""
945 <<
" type=\"" << sd.
type() <<
"\""
953 log <<
" iddescriptor=\"" << (
void*)ro_ent.hash <<
"\"";
955 log <<
" segmentation=\"" << (
void*)seg_ent.
hash <<
"\"";
969 auto ise = geo.find(seg);
970 if ( ise == geo.end() ) {
972 std::stringstream log =
logger();
976 log <<
" <parameters>" <<
newline;
977 for (
const auto&
v : p ) {
978 log <<
" <parameter";
979 log <<
" name=\"" <<
v->
name() <<
"\""
980 <<
" type=\"" <<
v->type() <<
"\"";
981 if (
v->unitType() == param_t::LengthUnit )
984 else if (
v->unitType() == param_t::AngleUnit )
988 log <<
" value=\"" <<
v->value() <<
"\"";
991 log <<
" </parameters>" <<
newline;
992 log <<
"</segmentation>";
993 ise = geo.emplace(seg,
make_entry(log)).first;
1004 auto iid = geo.find(id_spec);
1005 if ( iid == geo.end() ) {
1007 std::stringstream log =
logger();
1009 for (
const auto& i : fm ) {
1011 log <<
" <idfield label=\"" << f->
name() <<
"\""
1012 <<
" signed=\"" << true_false(f->
isSigned()) <<
"\""
1013 <<
" length=\"" << f->
width() <<
"\""
1017 iid = geo.emplace(id_spec,
make_entry(log)).first;
1027 auto ifd = geo.find(f);
1028 if ( ifd == geo.end() ) {
1029 std::string type = f->GetTitle();
1030 std::stringstream log =
logger();
1031 log <<
"<field name=\"" << f->GetName() <<
"\" type=\"" << f->GetTitle() <<
"\">";
1034 field.setAttr(
_U(name), f->GetName());
1035 fld = PluginService::Create<NamedObject*>(type +
"_Convert2Detector", &
m_detDesc, &field, &fld);
1036 printout(ALWAYS,
"DetectorChecksum",
"++ %s electromagnetic field:%s of type %s",
1037 (fld.isValid() ?
"Converted" :
"FAILED to convert "), f->GetName(), type.c_str());
1038 if (!fld.isValid()) {
1040 PluginService::Create<NamedObject*>(type +
"_Convert2Detector", &
m_detDesc, &field, &fld);
1041 throw std::runtime_error(
"Failed to locate plugin to convert electromagnetic field:"
1042 + std::string(f->GetName()) +
" of type " + type +
". "
1057 std::stringstream log =
logger();
1058 log <<
"<header name=\"" << hdr.
name() <<
"\">"
1059 <<
"<autor name=\"" << hdr.
author() <<
"\"/>"
1060 <<
"<generator version=\"" << hdr.
version() <<
"\"" <<
" url=\"" << hdr.
url() <<
"\"/>"
1061 <<
"<comment>" << hdr.
comment() <<
"</comment>"
1066 printout(WARNING,
"DetectorChecksum",
"+++ No Detector header information availible from the geometry description.");
1072 auto it = geo.find(top);
1073 if ( it == geo.end() ) {
1076 for(
const auto& c : top.
children() ) {
1086 throw std::runtime_error(
"Attempt to call analyzeDetector with an invalid geometry!");
1092 for (
const auto& fld : description.
fields() )
1095 printout(ALWAYS,
"DetectorChecksum",
"++ ==> Computing checksum for tree: %s", top.
path().c_str());
1096 printout(ALWAYS,
"DetectorChecksum",
"++ Handled %ld materials.", geo.
mapOfMaterials.size());
1097 printout(ALWAYS,
"DetectorChecksum",
"++ Handled %ld solids.", geo.
mapOfSolids.size());
1098 printout(ALWAYS,
"DetectorChecksum",
"++ Handled %ld volumes.", geo.
mapOfVolumes.size());
1099 printout(ALWAYS,
"DetectorChecksum",
"++ Handled %ld vis.attributes.", geo.
mapOfVis.size());
1100 printout(ALWAYS,
"DetectorChecksum",
"++ Handled %ld fields.", geo.
mapOfFields.size());
1105 if ( match.end() == match.find(node) ) {
1106 const TObjArray* dau = node.
volume()->GetNodes();
1107 for (Int_t i = 0, n_dau = dau->GetEntries(); i < n_dau; ++i) {
1108 TGeoNode* n =
reinterpret_cast<TGeoNode*
>(dau->At(i));
1110 if ( !cont.empty() ) {
1111 cont.emplace_back(node);
1123 debug_hash << std::setw(16) << std::left << prefix <<
"." << ent.
data << std::endl;
1126 debug_hash << std::setw(16) << std::left << (prefix+
".hash64: ") << (
void*)ent.
hash << std::endl;
1128 debug_hash << std::setw(16) << std::left << prefix <<
": |" << ent.
data <<
"|" << std::endl;
1135 auto& geo = dat.mapOfDetElements;
1136 auto it = geo.find(
det);
1137 if ( it != geo.end() ) {
1138 std::set<PlacedVolume> child_places;
1139 std::set<PlacedVolume> hashed_places;
1140 auto det_pv =
det.placement();
1141 std::size_t hash_idx_de = hashes.size();
1144 hashes.push_back(it->second.hash);
1146 std::size_t hash_idx_ro = hashes.size();
1147 std::size_t hash_idx_id = 0;
1148 std::size_t hash_idx_seg = 0;
1154 hashes.push_back(sens_ent.hash);
1160 hash_idx_id = hashes.size();
1161 hashes.push_back(id_ent.hash);
1162 hash_idx_seg = hashes.size();
1163 hashes.push_back(seg_ent.hash);
1171 std::size_t hash_idx_pv = hashes.size();
1173 for (
const auto& c :
det.children() )
1174 child_places.emplace(c.second.placement());
1179 std::size_t hash_idx_daughters = hashes.size();
1180 for(
const auto& pv : child_places ) {
1181 auto chain =
_get_path(pv, child_places);
1182 for( std::size_t i=0; i < chain.size()-1; ++i ) {
1184 hashed_places.insert(chain[i]);
1186 if ( !chain.empty() ) hashed_places.insert(chain[chain.size()-1]);
1190 const TObjArray* dau = det_pv.volume()->GetNodes();
1191 if (dau && dau->GetEntries() > 0) {
1192 for (Int_t i = 0, n_dau = dau->GetEntries(); i < n_dau; ++i) {
1193 PlacedVolume pv =
reinterpret_cast<TGeoNode*
>(dau->At(i));
1194 if ( hashed_places.find(pv) == hashed_places.end() ) {
1201 std::size_t hash_idx_children = hashes.size();
1203 for (
const auto& c :
det.children() )
1209 std::stringstream str;
1210 hash_t code = detail::hash64(&hashes[hash_idx_de], (hash_idx_ro-hash_idx_de)*
sizeof(
hash_t));
1211 str <<
"+++ " << std::setw(4) << std::left << lvl
1212 <<
" " << std::setw(36) << std::left <<
det.name() <<
" de"
1213 <<
" " << std::setfill(
'0') << std::setw(16) << std::hex << code;
1214 code = detail::hash64(&hashes[hash_idx_pv],
sizeof(
hash_t));
1215 str <<
" " << std::setfill(
' ') << std::setw(9) << std::left <<
"+place"
1216 <<
" " << std::setfill(
'0') << std::setw(16) << std::hex << code;
1217 code = detail::hash64(&hashes[hash_idx_daughters], (hash_idx_children-hash_idx_daughters)*
sizeof(
hash_t));
1218 if ( !(child_places.empty() && hashed_places.empty()) )
1219 str <<
" " << std::setfill(
' ') << std::setw(10) << std::left <<
"+daughters"
1220 <<
" " << std::setfill(
'0') << std::setw(16) << std::hex << code;
1221 code = detail::hash64(&hashes[hash_idx_children], (hashes.size()-hash_idx_children)*
sizeof(
hash_t));
1222 if ( !
det.children().empty() )
1223 str <<
" " << std::setfill(
' ') << std::setw(9) << std::left <<
"+children"
1224 <<
" " << std::setfill(
'0') << std::setw(16) << std::hex << code;
1225 std::cout << str.str() << std::endl;
1226 if ( hash_idx_pv-hash_idx_ro > 0 ) {
1228 str << std::setfill(
' ') <<
"+++ " << std::setw(4) << std::left << lvl
1229 <<
" " << std::setw(56) << std::left <<
" ";
1230 code = detail::hash64(&hashes[hash_idx_ro], (hash_idx_pv-hash_idx_ro)*
sizeof(
hash_t));
1231 str <<
" " << std::setfill(
' ') << std::setw(9) << std::left <<
"+readout"
1232 <<
" " << std::setfill(
'0') << std::setw(16) << std::hex << code;
1233 if ( hash_idx_id > 0 ) {
1234 code = detail::hash64(&hashes[hash_idx_id],
sizeof(
hash_t));
1235 str <<
" " << std::setfill(
' ') << std::setw(10) << std::left <<
"+iddesc"
1236 <<
" " << std::setfill(
'0') << std::setw(16) << std::hex << code;
1238 if ( hash_idx_seg > 0 ) {
1239 code = detail::hash64(&hashes[hash_idx_seg],
sizeof(
hash_t));
1240 str <<
" " << std::setfill(
' ') << std::setw(9) << std::left <<
"+segment"
1241 <<
" " << std::setfill(
'0') << std::setw(16) << std::hex << code;
1243 std::cout << str.str() << std::endl;
1247 code = detail::hash64(&hashes[0], hashes.size()*
sizeof(
hash_t));
1248 str << std::setfill(
' ') <<
"+++ " << std::setw(4) << std::left << lvl
1249 <<
" " << std::setw(39) << std::left <<
"Combined hash code"
1250 <<
" " << std::setfill(
'0') << std::setw(16) << std::hex << code
1251 <<
" (" << std::dec << hashes.size() <<
" sub-codes)";
1252 std::cout << str.str() << std::endl;
1257 except(
"DetectorChecksum",
"ERROR: Cannot checksum invalid DetElement");
1263 auto it = geo.find(pv);
1264 if ( it != geo.end() ) {
1271 hashes.push_back(it->second.hash);
1272 hashes.push_back(vol.hash);
1274 if ( !
v.isAssembly() ) {
1276 hashes.push_back(mat.hash);
1280 const TObjArray* dau =
v->GetNodes();
1281 if (dau && dau->GetEntries() > 0) {
1282 for (Int_t i = 0, n_dau = dau->GetEntries(); i < n_dau; ++i) {
1283 PlacedVolume node =
reinterpret_cast<TGeoNode*
>(dau->At(i));
1290 except(
"DetectorChecksum",
"ERROR: Cannot checksum invalid PlacedVolume");
1346 for(
const auto& e : geo) {
1348 printout(ALWAYS,
"DetectorChecksum",
"+++ Detelement: 0x%016lx %-32s %s",
1349 e.second.hash, de.
name(),
debug > 2 ? (
"\n"+e.second.data).c_str() :
"");
1350 if ( de.
path() ==
"/world" ) {
1358 printout(ALWAYS,
"DetectorChecksum",
" Solid: 0x%016lx %-32s %s",
1359 es.hash, sol.
name(),
debug > 2 ? (
"\n"+es.data).c_str() :
"");
1360 printout(ALWAYS,
"DetectorChecksum",
" Volume: 0x%016lx %-32s %s",
1361 ev.hash, vol.
name(),
debug > 2 ? (
"\n"+ev.data).c_str() :
"");
1362 printout(ALWAYS,
"DetectorChecksum",
" Placement: 0x%016lx %-32s %s",
1363 ep.hash, pv.
name(),
debug > 2 ? (
"\n"+ep.data).c_str() :
"");
1368 static long create_checksum(
Detector& description,
int argc,
char** argv) {
1370 int precision = 6, newline = 1, level = 1, meshes = 0, readout = 0,
debug = 0;
1371 int dump_elements = 0, dump_materials = 0, dump_solids = 0, dump_volumes = 0;
1372 int dump_placements = 0, dump_detelements = 0, dump_sensitives = 0;
1373 int dump_iddesc = 0, dump_segmentations = 0, dump_pos = 0;
1375 int have_hash_strings = 0, reorder = 0, write_files = 0;
1376 std::string len_unit, ang_unit, ene_unit, dens_unit, atom_unit;
1378 for(
int i = 0; i < argc && argv[i]; ++i) {
1379 if ( 0 == ::strncmp(
"-detector",argv[i],4) && (i+1)<argc )
1381 else if ( 0 == ::strncmp(
"-precision",argv[i],4) && (i+1)<argc )
1382 precision = ::atol(argv[++i]);
1383 else if ( 0 == ::strncmp(
"-length_unit",argv[i],10) && (i+1)<argc )
1384 len_unit = argv[++i];
1385 else if ( 0 == ::strncmp(
"-angle_unit",argv[i],10) && (i+1)<argc )
1386 ang_unit = argv[++i];
1387 else if ( 0 == ::strncmp(
"-energy_unit",argv[i],10) && (i+1)<argc )
1388 ene_unit = argv[++i];
1389 else if ( 0 == ::strncmp(
"-density_unit",argv[i],10) && (i+1)<argc )
1390 dens_unit = argv[++i];
1391 else if ( 0 == ::strncmp(
"-atomic_unit",argv[i],10) && (i+1)<argc )
1392 atom_unit = argv[++i];
1393 else if ( 0 == ::strncmp(
"-level", argv[i],5) && (i+1)<argc )
1394 level = ::atol(argv[++i]);
1395 else if ( 0 == ::strncmp(
"-debug", argv[i],5) && (i+1)<argc )
1396 debug = ::atol(argv[++i]);
1397 else if ( 0 == ::strncmp(
"+newline",argv[i],5) )
1399 else if ( 0 == ::strncmp(
"-meshes",argv[i],5) )
1401 else if ( 0 == ::strncmp(
"-readout",argv[i],5) )
1403 else if ( 0 == ::strncmp(
"-dump_elements",argv[i],10) )
1405 else if ( 0 == ::strncmp(
"-dump_materials",argv[i],10) )
1407 else if ( 0 == ::strncmp(
"-dump_solids",argv[i],10) )
1409 else if ( 0 == ::strncmp(
"-dump_volumes",argv[i],10) )
1411 else if ( 0 == ::strncmp(
"-dump_positions",argv[i],12) )
1413 else if ( 0 == ::strncmp(
"-dump_rotations",argv[i],12) )
1415 else if ( 0 == ::strncmp(
"-dump_placements",argv[i],10) )
1416 dump_placements = 1;
1417 else if ( 0 == ::strncmp(
"-dump_detelements",argv[i],10) )
1418 dump_detelements = 1;
1419 else if ( 0 == ::strncmp(
"-dump_sensitives",argv[i],10) )
1420 dump_sensitives = 1;
1421 else if ( 0 == ::strncmp(
"-dump_segmentations",argv[i],10) )
1422 dump_segmentations = 1;
1423 else if ( 0 == ::strncmp(
"-dump_iddescriptors",argv[i],10) )
1425 else if ( 0 == ::strncmp(
"-write_files",argv[i],8) )
1427 else if ( 0 == ::strncmp(
"-reorder",argv[i],6) )
1429 else if ( 0 == ::strncmp(
"-keep_hashes",argv[i],8) )
1430 have_hash_strings = 1;
1433 "Usage: -plugin DD4hepDetectorChecksum -arg [-arg] \n\n"
1434 " -detector <string> Top level DetElement path. Default: '/world' \n"
1435 " -meshes also hash the detector's meshed solids \n"
1436 " (may be sensitive to changes due to rounding) \n"
1437 " default: false \n"
1438 " -readout also hash the detector's readout properties \n"
1439 " (sensitive det, id desc, segmentation) \n"
1440 " default: false \n"
1441 " -keep_hash keep the hash strings (not only hash codes. \n"
1442 " Useful for debugging and -dump_<x> options. \n"
1443 " -precsision <digits> Set floating point precision after comma \n"
1444 " for the checsum calculation. \n"
1446 " Debugging: Dump individual hash codes (debug>=1) \n"
1447 " Debugging: and the hashed string (debug>2) \n"
1448 " -dump_elements Dump hashes of used elements \n"
1449 " -dump_materials Dump hashes of used materials \n"
1450 " -dump_solids Dump hashes of used solids \n"
1451 " -dump_volumes Dump hashes of used volumes \n"
1452 " -dump_positions Dump hashes of used positions \n"
1453 " -dump_rotations Dump hashes of used rotations \n"
1454 " -dump_placements Dump hashes of used placements \n"
1455 " -dump_detelements Dump hashes of used detelements \n"
1456 " -dump_sensitive Dump hashes of sensitive detectors \n"
1457 " -dump_iddescriptors Dump hashes of ID descriptors \n"
1458 " -dump_segmentations Dump hashes of readout segmentations \n"
1459 " -write_files Write a file for each category dumped (debugging). \n"
1460 " File name is <item>.txt (aka. Positions.txt etc. \n"
1461 " -reorder Reorder dump containers according to hash. \n"
1463 " Modify units in the created hash strings (deprecated): \n"
1464 " -length_unit <value> Unit of length as literal. default: mm \n"
1465 " -angle_unit <value> Unit of angle as literal. default: deg \n"
1466 " -energy_unit <value> Unit of energy as literal. default: GeV \n"
1467 " -density_unit <value> Unit of density as literal. default: g/cm3 \n"
1468 " -atomic_unit <value> Unit of atomic weight as literal. default: g/mole \n"
1470 " -debug <number> Steer additional debug printouts (gets verbose) \n"
1471 " -help Print this help output \n\n"
1472 " Arguments given: " << arguments(argc, argv) << std::endl << std::flush;
1478 wr.precision = precision;
1479 if ( !len_unit.empty() ) wr.m_len_unit_nam = std::move(len_unit);
1480 if ( !ang_unit.empty() ) wr.m_ang_unit_nam = std::move(ang_unit);
1481 if ( !ene_unit.empty() ) wr.m_ene_unit_nam = std::move(ene_unit);
1482 if ( !dens_unit.empty() ) wr.m_densunit_nam = std::move(dens_unit);
1483 if ( !atom_unit.empty() ) wr.m_atomunit_nam = std::move(atom_unit);
1484 if ( newline ) wr.newline =
"\n";
1485 wr.have_hash_strings = have_hash_strings;
1486 wr.write_files = write_files;
1487 wr.reorder = reorder;
1488 wr.hash_meshes = meshes;
1489 wr.hash_readout = readout;
1490 wr.max_level = level;
1494 bool make_dump =
false;
1495 if ( dump_elements || dump_materials || dump_solids ||
1496 dump_volumes || dump_placements || dump_detelements ||
1497 dump_sensitives || dump_iddesc || dump_segmentations ||
1498 dump_pos || dump_rot )
1503 int round = std::fegetround();
1504 std::fesetround(FE_TONEAREST);
1505 printout(INFO,
"DetectorChecksum",
"+++ Rounding mode: %d new: %d", round, std::fegetround());
1512 wr.analyzeDetector(de);
1514 wr.checksumDetElement(0, de, hash_vec,
true);
1515 if ( wr.debug > 2 ) {
1516 std::cout << wr.debug_hash.str() << std::endl;
1517 wr.debug_hash.str(
"");
1520 printout(ALWAYS,
"DetectorChecksum",
"+++ Checksum for %s 0x%016lx",
1521 de.
path().c_str(), checksum);
1522 if ( make_dump )
goto MakeDump;
1528 wr.analyzeDetector(de);
1529 hash_vec.push_back(wr.handleHeader().hash);
1530 wr.checksumDetElement(0, description.
world(), hash_vec,
true);
1532 if ( wr.debug > 2 ) std::cout << wr.debug_hash.str() << std::endl;
1533 printout(ALWAYS,
"DetectorChecksum",
"+++ Checksum for %s 0x%016lx",
1534 de.
path().c_str(), checksum);
1539 if ( dump_elements ) wr.dump_elements();
1540 if ( dump_materials ) wr.dump_materials();
1541 if ( dump_pos ) wr.dump_positions();
1542 if ( dump_rot ) wr.dump_rotations();
1543 if ( dump_solids ) wr.dump_solids();
1544 if ( dump_volumes ) wr.dump_volumes();
1545 if ( dump_placements ) wr.dump_placements();
1546 if ( dump_sensitives ) wr.dump_sensitives();
1547 if ( dump_segmentations ) wr.dump_segmentations();
1548 if ( dump_iddesc ) wr.dump_iddescriptors();
1549 if ( dump_detelements ) wr.dump_detelements();