DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
DetectorChecksum.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
14 // Framework includes
15 #include <DD4hep/Plugins.h>
16 #include <DD4hep/Printout.h>
17 #include <DD4hep/FieldTypes.h>
18 #include <DD4hep/DetectorTools.h>
19 #include <DD4hep/MatrixHelpers.h>
20 #include <DD4hep/AlignmentData.h>
24 #include "DetectorChecksum.h"
25 
26 // ROOT includes
27 #include <TROOT.h>
28 #include <TClass.h>
29 #include <TColor.h>
30 #include <TGeoBoolNode.h>
31 #include <TGeoSystemOfUnits.h>
32 
33 // C/C++ include files
34 #include <iostream>
35 #include <sstream>
36 #include <fstream>
37 #include <iomanip>
38 #include <cfloat>
39 #include <cfenv>
40 
41 using namespace dd4hep;
43 
44 namespace {
45 
46  bool is_volume(const TGeoVolume* volume) {
47  Volume v(volume);
48  return v.data() != 0;
49  }
50  inline double check_null(double d) {
51  if ( fabs(d) < 1e-12 )
52  return 0e0;
53  else
54  return d;
55  }
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) {
58  (o->*pmf)(*i);
59  }
60  }
61  template <typename T>
62  void _do_output(const std::string& title, bool reorder, bool with_file, bool have_hash, const T& container) {
63  std::ofstream out;
64  std::string tit = title + ":";
65  char delim = have_hash ? '\'' : ' ';
66  std::string fname = title + "s.txt";
67 
68  if ( with_file ) {
69  out.open(fname, std::ios::out);
70  }
71  if ( reorder ) {
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);
75 
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;
81  }
82  return;
83  }
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;
89  }
90  }
91  template <typename T>
92  void _do_output_name(const std::string& title, bool reorder, bool with_file, bool have_hash, const T& container) {
93  std::ofstream out;
94  std::string tit = title + ":";
95  char delim = have_hash ? '\'' : ' ';
96  std::string fname = title + "s.txt";
97 
98  if ( with_file ) {
99  out.open(fname, std::ios::out);
100  }
101  if ( reorder ) {
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);
107  }
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;
114  }
115  return;
116  }
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;
123  }
124  }
125 }
126 
129  : m_detDesc(description), m_dataPtr(0) {
130 }
131 
133  if (m_dataPtr)
134  delete m_dataPtr;
135  m_dataPtr = 0;
136 }
137 
138 template <typename T> std::string DetectorChecksum::refName(T handle) const {
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);
143 }
144 
145 template <> std::string DetectorChecksum::refName(Segmentation handle) const {
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);
150 }
151 
152 template <typename T> std::string DetectorChecksum::attr_name(T handle) const {
153  std::string n = " name=\"" + refName(handle)+"\"";
154  return n;
155 }
156 
157 std::stringstream DetectorChecksum::logger() const {
158  std::stringstream log;
159  log.setf(std::ios::fixed, std::ios::floatfield);
160  log << std::setprecision(precision);
161  return log;
162 }
163 
165  std::string data(log.str());
166  hash_t hash_value = hash64(data.c_str(), data.length());
167  if ( have_hash_strings )
168  return { hash_value, std::move(data) };
169  return { hash_value, std::string("") };
170 }
171 
176  m_densunit = _toDouble(m_densunit_nam)/_toDouble("g/cm3"); // g/cm3 is always internal unit of TGeo
177  m_atomunit = _toDouble(m_atomunit_nam)/_toDouble("g/mole"); // g/mole is always internal unit of TGeo
178  if ( debug > 1 ) {
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);
185  }
186 }
187 
190  auto& geo = data().mapOfElements;
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());
195  }
196  else {
197  std::stringstream log = logger();
198  log << "<element" << attr_name(element)
199  << " Z=\"" << element->Z() << "\""
200  << " formula=\"" << element.name() << "\""
201  << ">" << newline
202  << " <atom unit=\"" << m_atomunit_nam
203  << "\" value=\"" << std::scientific << element->A()/m_atomunit << "\"/>" << newline
204  << "</element>";
205  iel = geo.emplace(element, make_entry(log) ).first;
206  }
207  }
208  return iel->second;
209 }
210 
213  auto& geo = data().mapOfMaterials;
214  auto ima = geo.find(medium);
215  if ( ima == geo.end() ) {
216  std::stringstream log = logger();
217  auto* mat = medium->GetMaterial();
218  log << "<material" << attr_name(medium) << "\"/>" << newline;
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++ )
224  elts[refName(mix->GetElement(idx))] = mix->GetWmixt()[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;
229  }
230  else {
231  log << " A=\"" << mat->GetA() << "\""
232  << " Z=\"" << mat->GetZ() << "\">" << newline
233  << " <element=\"" << refName(mat->GetElement()) << "\"/>" << newline
234  << " <atom unit=\"" << m_atomunit_nam << "\" value=\"" << mat->GetA()/m_atomunit << "\"/>" << newline;
235  }
236  log << " <D unit=\"" << m_densunit_nam << "\" value=\"" << mat->GetDensity()/m_densunit << "\"/>" << newline;
237  log << "</material>";
238  ima = geo.emplace(medium, make_entry(log)).first;
239  }
240  return ima->second;
241 }
242 
245  auto& geo = data().mapOfSolids;
246  auto iso = geo.find(solid);
247  if ( iso == geo.end() ) {
248  const TGeoShape* shape = solid.ptr();
249  auto log = logger();
250 
251  if ( !shape ) {
252  log << "<shape type=\"INVALID\"></shape>)";
253  iso = geo.emplace(solid, make_entry(log)).first;
254  return iso->second;
255  }
256 
257  // NOTE: We cannot use the name when creating the hash!
258  // The name is artificially assigned and contains the shape pointer.
259  // This causes havoc.
260  TClass* cl = shape->IsA();
261  std::string nam = "";//attr_name(solid);
262  if ( cl == TGeoBBox::Class() ) {
263  TGeoBBox* sh = (TGeoBBox*) shape;
264  log << "<box" << nam
265  << " lunit=\"" << m_len_unit_nam << "\""
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 << "\""
269  << "/>";
270  }
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
276  << " lunit=\"" << m_len_unit_nam << "\">" << newline
277  << " <point x=\"" << pnt[0]/m_len_unit << "\""
278  << " y=\"" << pnt[1]/m_len_unit << "\""
279  << " z=\"" << pnt[2]/m_len_unit << "\"/>" << newline
280  << " <normal x=\"" << nrm[0]/m_len_unit << "\""
281  << " y=\"" << nrm[1]/m_len_unit << "\""
282  << " z=\"" << nrm[2]/m_len_unit << "\"/>" << newline
283  << "</halfspace>";
284  }
285  else if ( cl == TGeoTube::Class() || cl == TGeoTubeSeg::Class() ) {
286  const TGeoTube* sh = (const TGeoTube*) shape;
287  log << "<tube" << nam
288  << " lunit=\"" << m_len_unit_nam << "\""
289  << " aunit=\"" << m_ang_unit_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 << "\""
294  << " deltaphi=\"" << 360.0/m_ang_unit << "\""
295  << "/>";
296  }
297  else if ( cl == TGeoTubeSeg::Class() ) {
298  const TGeoTubeSeg* sh = (const TGeoTubeSeg*) shape;
299  log << "<tube" << nam
300  << " lunit=\"" << m_len_unit_nam << "\""
301  << " aunit=\"" << m_ang_unit_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 << "\""
307  << "/>";
308  }
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
314  << " lunit=\"" << m_len_unit_nam << "\""
315  << " aunit=\"" << m_ang_unit_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 << "\""
321  << " lowX=\"" << lo[0]/m_len_unit << "\""
322  << " lowY=\"" << lo[1]/m_len_unit << "\""
323  << " lowZ=\"" << lo[2]/m_len_unit << "\""
324  << " highX=\"" << hi[0]/m_len_unit << "\""
325  << " highY=\"" << hi[1]/m_len_unit << "\""
326  << " highZ=\"" << hi[2]/m_len_unit << "\""
327  << "/>";
328  }
329  else if ( cl == TGeoEltu::Class() ) {
330  const TGeoEltu* sh = (const TGeoEltu*) shape;
331  log << "<eltube" << nam
332  << " lunit=\"" << m_len_unit_nam << "\""
333  << " dx=\"" << sh->GetA()/m_len_unit << "\""
334  << " dy=\"" << sh->GetB()/m_len_unit << "\""
335  << " dz=\"" << sh->GetDz()/m_len_unit << "\""
336  << "/>";
337  }
338  else if ( cl == TGeoTrd1::Class() ) {
339  const TGeoTrd1* sh = (const TGeoTrd1*) shape;
340  log << "<trd" << nam
341  << " lunit=\"" << m_len_unit_nam << "\""
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) << "\""
347  << "/>";
348  }
349  else if ( cl == TGeoTrd2::Class() ) {
350  const TGeoTrd2* sh = (const TGeoTrd2*) shape;
351  log << "<trd" << nam
352  << " lunit=\"" << m_len_unit_nam << "\""
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) << "\""
358  << "/>";
359  }
360  else if ( cl == TGeoTrap::Class() ) {
361  const TGeoTrap* sh = (const TGeoTrap*) shape;
362  log << "<trap" << nam
363  << " lunit=\"" << m_len_unit_nam << "\""
364  << " aunit=\"" << m_ang_unit_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) << "\""
376  << "/>";
377  }
378  else if ( cl == TGeoHype::Class() ) {
379  const TGeoHype* sh = (const TGeoHype*) shape;
380  log << "<hype" << nam
381  << " lunit=\"" << m_len_unit_nam << "\""
382  << " aunit=\"" << m_ang_unit_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) << "\""
388  << "/>";
389  }
390  else if ( cl == TGeoPgon::Class() ) {
391  const TGeoPgon* sh = (const TGeoPgon*) shape;
392  log << "<polyhedra" << nam
393  << " lunit=\"" << m_len_unit_nam << "\""
394  << " aunit=\"" << m_ang_unit_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) << "\""
401  << "\" rmax=\"" << check_null(sh->GetRmax(i)/m_len_unit) << "\"/>" << newline;
402  }
403  log << "</polyhedra>";
404  }
405  else if ( cl == TGeoPcon::Class() ) {
406  const TGeoPcon* sh = (const TGeoPcon*) shape;
407  log << "<polycone" << nam
408  << " lunit=\"" << m_len_unit_nam << "\""
409  << " aunit=\"" << m_ang_unit_nam << "\""
410  << " startphi=\"" << check_null(sh->GetPhi1()/m_ang_unit) << "\""
411  << " deltaphi=\"" << check_null(sh->GetDphi()/m_ang_unit) << "\">" << newline;
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) << "\""
415  << "\" rmax=\"" << check_null(sh->GetRmax(i)/m_len_unit) << "\"/>" << newline;
416  }
417  log << "</polycone>";
418  }
419  else if ( cl == TGeoCone::Class() ) {
420  const TGeoCone* sh = (const TGeoCone*) shape;
421  log << "<cone" << nam
422  << " lunit=\"" << m_len_unit_nam << "\""
423  << " aunit=\"" << m_ang_unit_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) << "\""
429  << " startphi=\"" << 0.0/m_ang_unit << "\""
430  << " deltaphi=\"" << 360.0/m_ang_unit << "\""
431  << "/>";
432  }
433  else if ( cl == TGeoConeSeg::Class() ) {
434  const TGeoConeSeg* sh = (const TGeoConeSeg*) shape;
435  log << "<cone" << nam
436  << " lunit=\"" << m_len_unit_nam << "\""
437  << " aunit=\"" << m_ang_unit_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) << "\""
445  << "/>";
446  }
447  else if ( cl == TGeoParaboloid::Class() ) {
448  const TGeoParaboloid* sh = (const TGeoParaboloid*) shape;
449  log << "<paraboloid" << nam
450  << " lunit=\"" << m_len_unit_nam << "\""
451  << " rlo=\"" << sh->GetRlo()/m_len_unit << "\""
452  << " rhi=\"" << sh->GetRhi()/m_len_unit << "\""
453  << " z=\"" << sh->GetDz()/m_len_unit << "\""
454  << "/>";
455  }
456  else if ( cl == TGeoSphere::Class() ) {
457  const TGeoSphere* sh = (const TGeoSphere*) shape;
458  log << "<sphere" << nam
459  << " lunit=\"" << m_len_unit_nam << "\""
460  << " aunit=\"" << m_ang_unit_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 << "\""
467  << "/>";
468  }
469  else if ( cl == TGeoTorus::Class() ) {
470  const TGeoTorus* sh = (const TGeoTorus*) shape;
471  log << "<torus" << nam
472  << " lunit=\"" << m_len_unit_nam << "\""
473  << " aunit=\"" << m_ang_unit_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 << "\""
479  << "/>";
480  }
481  else if ( cl == TGeoArb8::Class() ) {
482  TGeoArb8* sh = (TGeoArb8*) shape;
483  const Double_t* v = sh->GetVertices();
484  log << "<arb8" << nam
485  << " v1x=\"" << v[0]/m_len_unit << "\""
486  << " v1y=\"" << v[1]/m_len_unit << "\""
487  << " v2x=\"" << v[2]/m_len_unit << "\""
488  << " v2y=\"" << v[3]/m_len_unit << "\""
489  << " v3x=\"" << v[4]/m_len_unit << "\""
490  << " v3y=\"" << v[5]/m_len_unit << "\""
491  << " v4x=\"" << v[6]/m_len_unit << "\""
492  << " v4y=\"" << v[7]/m_len_unit << "\""
493  << " v5x=\"" << v[8]/m_len_unit << "\""
494  << " v5y=\"" << v[9]/m_len_unit << "\""
495  << " v6x=\"" << v[10]/m_len_unit << "\""
496  << " v6y=\"" << v[11]/m_len_unit << "\""
497  << " v7x=\"" << v[12]/m_len_unit << "\""
498  << " v7y=\"" << v[13]/m_len_unit << "\""
499  << " v8x=\"" << v[14]/m_len_unit << "\""
500  << " v8y=\"" << v[15]/m_len_unit << "\""
501  << " dz=\"" << sh->GetDz()/m_len_unit << "\""
502  << "/>";
503  }
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 << "\""
509  << "\" y=\"" << sh->GetY(i)/m_len_unit << "\"/>" << newline;
510  }
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 << "\""
516  << " yOffset=\"" << sh->GetYOffset(i)/m_len_unit << "\"/>" << newline;
517  }
518  log << "</xtru>";
519  }
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;
528 
529  TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
530  if (oper == TGeoBoolNode::kGeoSubtraction)
531  str_oper = "subtraction";
532  else if (oper == TGeoBoolNode::kGeoUnion)
533  str_oper = "union";
534  else if (oper == TGeoBoolNode::kGeoIntersection)
535  str_oper = "intersection";
536 
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
552  << " lunit=\"" << m_len_unit_nam << "\""
553  << " ax=\"" << ax/m_len_unit << "\""
554  << " by=\"" << by/m_len_unit << "\""
555  << " cz=\"" << cz/m_len_unit << "\""
556  << " zcut1=\"" << zcut1/m_len_unit << "\""
557  << " zcut2=\"" << zcut2/m_len_unit << "\"/>";
558  iso = geo.emplace(solid, make_entry(log)).first;
559  return iso->second;
560  }
561  }
562  // The name cannot be used. We hence use the full hash code
563  // for the left and right side shapes!
564  const entry_t& ent_left = handleSolid(Solid(left));
565  const entry_t& ent_right = handleSolid(Solid(right));
566  const entry_t& ent_pos_left = handlePosition(mat_left);
567  const entry_t& ent_rot_left = handleRotation(mat_left);
568  const entry_t& ent_pos_right = handlePosition(mat_right);
569  const entry_t& ent_rot_right = handleRotation(mat_right);
570  log << "<" << str_oper << nam
571  << " lunit=\"" << m_len_unit_nam << "\""
572  << " aunit=\"" << m_ang_unit_nam << "\">" << newline
573  << " <first ref=\"" << (void*)ent_left.hash << "\"" << ">" << newline
574  << " " << ent_pos_left.hash << newline
575  << " " << ent_rot_left.hash << newline
576  << " </first>" << newline
577  << " <second ref=\"" << (void*)ent_right.hash << "\"" << ">" << newline
578  << " " << ent_pos_right.hash << newline
579  << " " << ent_rot_right.hash << newline
580  << " </second>" << newline
581  << "</" << str_oper << ">";
582  }
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
591  << " " << handleSolid(Solid(org)).hash << newline
592  << "</scaled_shape>";
593  }
594  else if ( shape->IsA() == TGeoShapeAssembly::Class() ) {
595  log << "<shape_assembly " << nam << "\"/>";
596  }
597  else if ( shape->IsA() == TGeoTessellated::Class() ) {
598  if ( hash_meshes ) {
599  const TGeoTessellated* sh = (TGeoTessellated*)shape;
600  log << "<define>" << newline;
601  if ( sh->IsClosedBody() == false ) {
602  except("DetectorChecksum","+++ TGeoTessellated volume is not closed: %s", solid.name());
603  }
604  for (int ivertex = 0; ivertex < sh->GetNvertices(); ivertex++) {
605  // Note: const_cast since TGeoTessellated::GetVertex not marked const in ROOT <= 6.28
606  const auto& vtx = const_cast<TGeoTessellated*>(sh)->GetVertex(ivertex);
607  log << "<position name\"" << nam << "_v" << ivertex
608  << " lunit=\"" << m_len_unit_nam << "\""
609  << " x=\"" << vtx.x()/m_len_unit << "\""
610  << " y=\"" << vtx.y()/m_len_unit << "\""
611  << " z=\"" << vtx.z()/m_len_unit << "\""
612  << "/>" << newline;
613  }
614  log << "</define>" << newline;
615  log << "<tessellated name=\"" << nam << "\">" << newline;
616  for (int ifacet = 0; ifacet < sh->GetNfacets(); ifacet++) {
617  // Note: const_cast since TGeoTessellated::GetFacet not marked const in ROOT <= 6.28
618  const auto& facet = const_cast<TGeoTessellated*>(sh)->GetFacet(ifacet);
619  if ( facet.GetNvert() == 3 ) {
620  log << "<triangular";
621  }
622  else if ( facet.GetNvert() == 4 ) {
623  log << "<quadrangular";
624  }
625  else {
626  except("DetectorChecksum","+++ TGeoTessellated volume with unsupported number of vertices: %s", solid.name());
627  }
628  for (int ivertex = 0; ivertex < facet.GetNvert(); ivertex++) {
629 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1)
630  auto vertexIndex = facet[ivertex];
631 #else
632  auto vertexIndex = facet.GetVertexIndex(ivertex);
633 #endif
634  log << " vertex" << ivertex + 1 << "=\"" << nam << "_v" << vertexIndex << "\"";
635  }
636  log << " type=\"ABSOLUTE\"/>" << newline;
637  }
638  log << "</tessellated>" << newline;
639  }
640  else {
641  log << "<tessellated></tessellated>" << newline;
642  }
643  }
644  else {
645  except("DetectorChecksum","+++ Unknown shape: %s", solid.name());
646  }
647  auto ins = geo.emplace(solid, make_entry(log));
648  if ( !ins.second ) {
649  except("DetectorChecksum", "+++ FAILED to register shape: %s", solid.name());
650  }
651  iso = ins.first;
652  }
653  return iso->second;
654 }
655 
657 const DetectorChecksum::entry_t& DetectorChecksum::handlePosition(const TGeoMatrix* trafo) const {
658  auto& geo = data().mapOfPositions;
659  auto ipo = geo.find(trafo);
660  if ( ipo == geo.end() ) {
661  const double* tr = trafo->GetTranslation();
662  std::stringstream log = logger();
663  log << "<position"
664  << " unit=\"" << m_len_unit_nam << "\""
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) << "\"";
668  log << "/>";
669  ipo = geo.emplace(trafo, make_entry(log)).first;
670  }
671  return ipo->second;
672 }
673 
675 const DetectorChecksum::entry_t& DetectorChecksum::handleRotation(const TGeoMatrix* trafo) const {
676  auto& geo = data().mapOfRotations;
677  auto iro = geo.find(trafo);
678  if ( iro == geo.end() ) {
679  XYZAngles rot = detail::matrix::_xyzAngles(trafo->GetRotationMatrix());
680  std::stringstream log = logger();
681  log << "<rotation"
682  << " unit=\"" << m_ang_unit_nam << "\""
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) << "\""
686  << "/>";
687  iro = geo.emplace(trafo, make_entry(log)).first;
688  }
689  return iro->second;
690 }
691 
694  auto& geo = data().mapOfVis;
695  auto ivi = geo.find(attr);
696  if ( ivi == geo.end() ) {
697  std::stringstream log = logger();
698  float red = 0, green = 0, blue = 0;
699  int style = attr.lineStyle();
700  int draw = attr.drawingStyle();
701  attr.rgb(red, green, blue);
702 
703  log << "<vis"
704  << " name=\"" << attr.name() << "\""
705  << " visible=\"" << attr.visible() << "\""
706  << " show_daughters=\"" << attr.showDaughters() << "\"";
707  if (style == VisAttr::SOLID)
708  log << " line_style=\"unbroken\"";
709  else if (style == VisAttr::DASHED)
710  log << " line_style=\"broken\"";
711  if (draw == VisAttr::SOLID)
712  log << " line_style=\"solid\"";
713  else if (draw == VisAttr::WIREFRAME)
714  log << " line_style=\"wireframe\"";
715  log << "<color"
716  << " alpha=\"" << attr.alpha()
717  << " R=\"" << red << "\""
718  << " B=\"" << blue << "\""
719  << " G=\"" << green << "\"/>" << newline;
720  log << "</vis>";
721  ivi = geo.emplace(attr, make_entry(log)).first;
722  }
723  return ivi->second;
724 }
725 
728  auto& geo = data().mapOfRegions;
729  auto ire = geo.find(region);
730  if ( ire == geo.end() ) {
731  std::stringstream log = logger();
732  log << "<region name=\"" << region.name() << "\""
733  << " store_secondaries=\"" << (region.storeSecondaries() ? 1 : 0) << "\""
734  << " cut=\"" << region.cut() << "\""
735  << " eunit=\"" << m_ene_unit_nam << "\""
736  << " lunit=\"" << m_len_unit_nam << "\""
737  << "/>";
738  ire = geo.emplace(region, make_entry(log)).first;
739  }
740  return ire->second;
741 }
742 
745  auto& geo = data().mapOfLimits;
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 << "\""
756  << "/>" << newline;
757  }
758  log << "</limitSet>";
759  ili = geo.emplace(lim, make_entry(log)).first;
760  }
761  return ili->second;
762 }
763 
765  auto& geo = data().mapOfAlignments;
766  auto ial = geo.find(alignment);
767  if ( ial == geo.end() ) {
768  std::stringstream log = logger();
769  const auto& data = alignment.data();
770  double x, y, z;
771  data.delta.pivot.GetComponents(x, y, z);
772  log << "<nominal>" << newline;
773  log << "<translation"
774  << " unit=\"" << m_len_unit_nam << "\""
775  << " x=\"" << data.delta.translation.X()/m_len_unit << "\""
776  << " y=\"" << data.delta.translation.Y()/m_len_unit << "\""
777  << " z=\"" << data.delta.translation.Z()/m_len_unit << "\"/>" << newline;
778  log << "<pivot"
779  << " unit=\"" << m_len_unit_nam << "\""
780  << " x=\"" << x / m_len_unit << "\""
781  << " y=\"" << y / m_len_unit << "\""
782  << " z=\"" << z / m_len_unit << "\"/>" << newline;
783  log << "<rotation"
784  << " unit=\"" << m_len_unit_nam << "\""
785  << " theta=\"" << data.delta.rotation.Theta()/m_ang_unit << "\""
786  << " phi=\"" << data.delta.rotation.Phi()/m_len_unit << "\""
787  << " psi=\"" << data.delta.rotation.Psi()/m_len_unit << "\"/>" << newline;
788  log << "</nominal>";
789  ial = geo.emplace(alignment, make_entry(log)).first;
790  }
791  return ial->second;
792 }
793 
796  Volume v(volume);
797  if ( is_volume(volume) ) {
798  Region reg = v.region();
799  LimitSet lim = v.limitSet();
800  VisAttr vis = v.visAttributes();
801  SensitiveDetector det = v.sensitiveDetector();
802  if ( lim.isValid() ) handleLimitSet(lim);
803  if ( reg.isValid() ) handleRegion(reg);
804  if ( vis.isValid() ) handleVis(vis);
805  if ( det.isValid() ) handleSensitive(det);
806  }
807  else {
808  printout(WARNING,"DetectorChecksum","++ CollectVolume: Skip volume: %s",volume.name());
809  }
810 }
811 
814  auto& geo = data().mapOfVolumes;
815  auto ivo = geo.find(volume);
816  if ( ivo == geo.end() ) {
817  const TGeoVolume* v = volume;
818  std::string tag;
819  std::string sol;
820  std::string nam = attr_name(v);
821  std::stringstream log = logger();
822  TGeoShape* sh = v->GetShape();
823  if ( !sh )
824  throw std::runtime_error("DetectorChecksum: No solid present for volume:" + nam);
825 
826  if (v->IsAssembly()) {
827  const auto& solid_ent = handleSolid(sh);
828  tag = "assembly";
829  log << "<" << tag << nam
830  << " solid=\"" << refName(sh) << "\""
831  << " solid_hash=\"" << (void*)solid_ent.hash << "\"";
832  }
833  else {
834  TGeoMedium* med = v->GetMedium();
835  if ( !med )
836  throw std::runtime_error("DetectorChecksum: No material present for volume:" + nam);
837  const auto& solid_ent = handleSolid(sh);
838  tag = "volume";
839  log << "<" << tag << nam
840  << " material=\"" << refName(med) << "\""
841  << " solid=\"" << refName(sh) << "\""
842  << " solid_hash=\"" << (void*)solid_ent.hash << "\"";
843  }
844  collectVolume(volume);
845  auto reg = volume.region();
846  auto lim = volume.limitSet();
847  auto vis = volume.visAttributes();
848  auto det = volume.sensitiveDetector();
849  if ( lim.isValid() )
850  log << " limits=\"" << refName(lim) << "\"";
851  if ( reg.isValid() )
852  log << " region=\"" << refName(reg) << "\"";
853  if ( vis.isValid() )
854  log << " vis=\"" << refName(vis) << "\"";
855  if ( det.isValid() )
856  log << " sensitive=\"" << refName(det) << "\"";
857  const TObjArray* dau = const_cast<TGeoVolume*>(v)->GetNodes();
858  if (dau && dau->GetEntries() > 0) {
859  log << ">" << newline;
860  for (Int_t i = 0, n_dau = dau->GetEntries(); i < n_dau; ++i) {
861  TGeoNode* node = reinterpret_cast<TGeoNode*>(dau->At(i));
862  const auto& ent = handlePlacement(node);
863  log << " <physvol name=\"" << refName(node) << " hash=\"" << (void*)ent.hash << "\"/>" << newline;
864  }
865  log << "</" << tag << ">";
866  }
867  else {
868  log << "/>";
869  }
870  auto ins = geo.emplace(volume, make_entry(log));
871  if ( !ins.second ) {
872  except("DetectorChecksum", "+++ FAILED to register volume: %s", volume.name());
873  }
874  ivo = ins.first;
875  }
876  return ivo->second;
877 }
878 
881  auto& geo = data().mapOfPlacements;
882  auto ipl = geo.find(node);
883  if ( ipl == geo.end() ) {
884  TGeoMatrix* matrix = node->GetMatrix();
885  TGeoVolume* volume = node->GetVolume();
886  const auto& vol_ent = handleVolume(volume);
887  std::stringstream log = logger();
888  log << "<physvol" << attr_name(node)
889  << " volume=\"" << refName(volume) << "\"";
890  log << " volume_hash=\"" << (void*)vol_ent.hash << "\"";
891  log << ">" << newline;
892  if ( matrix ) {
893  log << " " << handlePosition(matrix).hash << newline;
894  //log << " " << _to_hex(handlePosition(matrix).hash) << newline;
895  if ( matrix->IsRotation() ) {
896  log << " " << handleRotation(matrix).hash << newline;
897  //log << " " << _to_hex(handleRotation(matrix).hash) << newline;
898  }
899  }
900  if ( node.data() ) {
901  const auto& ids = node.volIDs();
902  for (const auto& vid : ids )
903  log << " <physvolid"
904  << " name=\"" << vid.first << "\""
905  << " value=\"" << vid.second << "\""
906  << "/>" << newline;
907  }
908  log << "</physvol>";
909  ipl = geo.emplace(node, make_entry(log)).first;
910  }
911  return ipl->second;
912 }
913 
915  auto& geo = data().mapOfDetElements;
916  auto dit = geo.find(det);
917  if ( dit == geo.end() ) {
918  std::stringstream log = logger();
919  const auto& place = handlePlacement(det.placement());
920  const auto& par = det.parent().isValid() ? handleDetElement(det.parent()) : empty_entry;
921  log << "<detelement"
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 << "\""
930  << "/>";
931  dit = geo.emplace(det, make_entry(log)).first;
932  }
933  return dit->second;
934 }
935 
938  if ( sd.isValid() ) {
939  auto& geo = data().mapOfSensDets;
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() << "\""
946  << " ecut=\"" << sd.energyCutoff()/m_ene_unit << "\""
947  << " eunit=\"" << m_ene_unit_nam << "\""
948  << " hits_collection=\"" << sd.hitsCollection() << "\""
949  << " combine_hits=\"" << sd.combineHits() << "\"";
950  Readout ro = sd.readout();
951  if ( ro.isValid() ) {
952  const auto& ro_ent = handleIdSpec(ro.idSpec());
953  log << " iddescriptor=\"" << (void*)ro_ent.hash << "\"";
954  const auto& seg_ent = handleSegmentation(ro.segmentation());
955  log << " segmentation=\"" << (void*)seg_ent.hash << "\"";
956  }
957  log << "/>";
958  isi = geo.emplace(sd, make_entry(log)).first;
959  }
960  return isi->second;
961  }
962  return empty_entry;
963 }
964 
967  if (seg.isValid()) {
968  auto& geo = data().mapOfSegmentations;
969  auto ise = geo.find(seg);
970  if ( ise == geo.end() ) {
972  std::stringstream log = logger();
973  const auto& p = seg.parameters();
974  log << "<segmentation" << attr_name(seg)
975  << " type=\"" << seg.type() << "\">" << newline;
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 )
982  log << " value=\"" << _toDouble(v->value())/m_len_unit << "\""
983  << " unit=\"" << m_len_unit_nam << "\"";
984  else if ( v->unitType() == param_t::AngleUnit )
985  log << " value=\"" << _toDouble(v->value())/m_ang_unit << "\""
986  << " unit=\"" << m_ang_unit_nam << "\"";
987  else
988  log << " value=\"" << v->value() << "\"";
989  log << "/>" << newline;
990  }
991  log << " </parameters>" << newline;
992  log << "</segmentation>";
993  ise = geo.emplace(seg, make_entry(log)).first;
994  }
995  return ise->second;
996  }
997  return empty_entry;
998 }
999 
1002  if ( id_spec.isValid() ) {
1003  auto& geo = data().mapOfIdSpecs;
1004  auto iid = geo.find(id_spec);
1005  if ( iid == geo.end() ) {
1006  const IDDescriptor::FieldMap& fm = id_spec.fields();
1007  std::stringstream log = logger();
1008  log << "<id name=\"" << refName(id_spec) << "\">" << newline;
1009  for (const auto& i : fm ) {
1010  const BitFieldElement* f = i.second;
1011  log << " <idfield label=\"" << f->name() << "\""
1012  << " signed=\"" << true_false(f->isSigned()) << "\""
1013  << " length=\"" << f->width() << "\""
1014  << " start=\"" << f->offset() << "\"/>" << newline;
1015  }
1016  log << "</id>";
1017  iid = geo.emplace(id_spec, make_entry(log)).first;
1018  }
1019  return iid->second;
1020  }
1021  return empty_entry;
1022 }
1023 
1026  auto& geo = data().mapOfFields;
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() << "\">";
1032 #if 0
1033  field = xml_elt_t(geo.doc, Unicode(type));
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()) {
1039  PluginDebug dbg;
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 + ". "
1043  + dbg.missingFactory(type));
1044  }
1045 #endif
1046  log << "</field>";
1047  ifd = geo.emplace(f, make_entry(log)).first;
1048  }
1049  return ifd->second;
1050 }
1051 
1054  GeometryInfo& geo = data();
1055  Header hdr = m_detDesc.header();
1056  if ( hdr.isValid() && 0 == geo.header.hash ) {
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>"
1062  << "</header>";
1063  geo.header = make_entry(log);
1064  return geo.header;
1065  }
1066  printout(WARNING,"DetectorChecksum","+++ No Detector header information availible from the geometry description.");
1067  return empty_entry;
1068 }
1069 
1071  auto& geo = data().mapOfDetElements;
1072  auto it = geo.find(top);
1073  if ( it == geo.end() ) {
1074  handleDetElement(top);
1075  handlePlacement(top.placement());
1076  for( const auto& c : top.children() ) {
1077  collect_det_elements(c.second);
1078  }
1079  }
1080 }
1081 
1084  Detector& description = m_detDesc;
1085  if (!top.isValid()) {
1086  throw std::runtime_error("Attempt to call analyzeDetector with an invalid geometry!");
1087  }
1088  GeometryInfo& geo = *(m_dataPtr = new GeometryInfo);
1089  m_data->clear();
1090  handleHeader();
1091  collect_det_elements(top);
1092  for (const auto& fld : description.fields() )
1093  handleField(fld.second);
1094  if ( debug > 1 ) {
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());
1101  }
1102 }
1103 
1104 std::vector<PlacedVolume> _get_path(PlacedVolume node, const std::set<PlacedVolume>& match) {
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));
1109  auto cont = _get_path(n, match);
1110  if ( !cont.empty() ) {
1111  cont.emplace_back(node);
1112  return cont;
1113  }
1114  }
1115  return { };
1116  }
1117  return { node };
1118 }
1119 
1120 void DetectorChecksum::hash_debug(const std::string& prefix, const entry_t& ent, int flg) const {
1121  if ( debug > 2 ) {
1122  if ( flg == 1 ) {
1123  debug_hash << std::setw(16) << std::left << prefix << "." << ent.data << std::endl;
1124  return;
1125  }
1126  debug_hash << std::setw(16) << std::left << (prefix+".hash64: ") << (void*)ent.hash << std::endl;
1127  if ( debug > 3 ) {
1128  debug_hash << std::setw(16) << std::left << prefix << ": |" << ent.data << "|" << std::endl;
1129  }
1130  }
1131 }
1132 
1133 void DetectorChecksum::checksumDetElement(int lvl, DetElement det, hashes_t& hashes, bool recursive) const {
1134  auto& dat = data();
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();
1142 
1144  hashes.push_back(it->second.hash);
1145  hash_debug(det.name(), it->second);
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;
1149  if ( hash_readout ) {
1151  if ( sd.isValid() ) {
1152  Readout ro = sd.readout();
1153  const auto& sens_ent = handleSensitive(sd);
1154  hashes.push_back(sens_ent.hash);
1155  hash_debug(" .sensitive", sens_ent);
1156  if ( ro.isValid() ) {
1157  const auto& id_ent = handleIdSpec(ro.idSpec());
1158  const auto& seg_ent = handleSegmentation(ro.segmentation());
1159 
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);
1164 
1165  hash_debug(" .iddesc", id_ent);
1166  hash_debug(" .readout", seg_ent);
1167  }
1168  }
1169  }
1170 
1171  std::size_t hash_idx_pv = hashes.size();
1172  checksumPlacement(det_pv, hashes, false);
1173  for ( const auto& c : det.children() )
1174  child_places.emplace(c.second.placement());
1175 
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 ) {
1183  checksumPlacement(chain[i], hashes, false);
1184  hashed_places.insert(chain[i]);
1185  }
1186  if ( !chain.empty() ) hashed_places.insert(chain[chain.size()-1]);
1187  }
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() ) {
1195  checksumPlacement(det_pv, hashes, true);
1196  }
1197  }
1198  }
1199 
1201  std::size_t hash_idx_children = hashes.size();
1202  if ( recursive ) {
1203  for ( const auto& c : det.children() )
1204  checksumDetElement(lvl+1, c.second, hashes, recursive);
1205  }
1206 
1208  if ( debug > 0 || lvl <= max_level ) {
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 ) {
1227  str.str("");
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;
1237  }
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;
1242  }
1243  std::cout << str.str() << std::endl;
1244  }
1245  if ( lvl == 0 ) {
1246  str.str("");
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;
1253  }
1254  }
1255  return;
1256  }
1257  except("DetectorChecksum","ERROR: Cannot checksum invalid DetElement");
1258 }
1259 
1260 void DetectorChecksum::checksumPlacement(PlacedVolume pv, hashes_t& hashes, bool recursive) const {
1261  handlePlacement(pv);
1262  auto& geo = data().mapOfPlacements;
1263  auto it = geo.find(pv);
1264  if ( it != geo.end() ) {
1265  Volume v = pv.volume();
1266  const auto& vol = handleVolume(v);
1267  entry_t name_entry {0, pv.name()};
1268 
1269  hash_debug(" .place.name", name_entry, 1);
1270  hash_debug(" .place", it->second);
1271  hashes.push_back(it->second.hash);
1272  hashes.push_back(vol.hash);
1273  hash_debug(" .place.vol", vol);
1274  if ( !v.isAssembly() ) {
1275  const auto& mat = handleMaterial(v.material());
1276  hashes.push_back(mat.hash);
1277  hash_debug(" .place.mat", mat);
1278  }
1279  if ( recursive ) {
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));
1284  checksumPlacement(node, hashes, recursive);
1285  }
1286  }
1287  }
1288  return;
1289  }
1290  except("DetectorChecksum","ERROR: Cannot checksum invalid PlacedVolume");
1291 }
1292 
1295  _do_output_name("Element", reorder, write_files, debug>1 && have_hash_strings, data().mapOfElements);
1296 }
1297 
1300  _do_output_name("Material", reorder, write_files, debug>1 && have_hash_strings, data().mapOfMaterials);
1301 }
1302 
1305  _do_output_name("Solid", reorder, write_files, debug>1 && have_hash_strings, data().mapOfSolids);
1306 }
1307 
1310  _do_output("Position", reorder, write_files, have_hash_strings, data().mapOfPositions);
1311 }
1312 
1315  _do_output("Rotation", reorder, write_files, have_hash_strings, data().mapOfRotations);
1316 }
1317 
1320  _do_output_name("Volume", reorder, write_files, debug>1 && have_hash_strings, data().mapOfVolumes);
1321 }
1322 
1325  _do_output_name("Placement", reorder, write_files, debug>1 && have_hash_strings, data().mapOfPlacements);
1326 }
1327 
1330  _do_output_name("ID desc", reorder, write_files, debug>1 && have_hash_strings, data().mapOfIdSpecs);
1331 }
1332 
1335  _do_output_name("Segment", reorder, write_files, debug>1 && have_hash_strings, data().mapOfSegmentations);
1336 }
1337 
1340  _do_output_name("Sens.Det", reorder, write_files, debug>0 && have_hash_strings, data().mapOfSensDets);
1341 }
1342 
1345  const auto& geo = data().mapOfDetElements;
1346  for(const auto& e : geo) {
1347  DetElement de = e.first;
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" ) {
1351  PlacedVolume pv = de.placement();
1352  Volume vol = pv.volume();
1353  Solid sol = vol.solid();
1354  const auto& es = handleSolid(sol);
1355  const auto& ev = handleVolume(vol);
1356  const auto& ep = handlePlacement(pv);
1357 
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() : "");
1364  }
1365  }
1366 }
1367 
1368 static long create_checksum(Detector& description, int argc, char** argv) {
1369  std::vector<std::string> detectors;
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;
1374  int dump_rot = 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;
1377 
1378  for(int i = 0; i < argc && argv[i]; ++i) {
1379  if ( 0 == ::strncmp("-detector",argv[i],4) && (i+1)<argc )
1380  detectors.emplace_back(argv[++i]);
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) )
1398  newline = 0;
1399  else if ( 0 == ::strncmp("-meshes",argv[i],5) )
1400  meshes = 1;
1401  else if ( 0 == ::strncmp("-readout",argv[i],5) )
1402  readout = 1;
1403  else if ( 0 == ::strncmp("-dump_elements",argv[i],10) )
1404  dump_elements = 1;
1405  else if ( 0 == ::strncmp("-dump_materials",argv[i],10) )
1406  dump_materials = 1;
1407  else if ( 0 == ::strncmp("-dump_solids",argv[i],10) )
1408  dump_solids = 1;
1409  else if ( 0 == ::strncmp("-dump_volumes",argv[i],10) )
1410  dump_volumes = 1;
1411  else if ( 0 == ::strncmp("-dump_positions",argv[i],12) )
1412  dump_pos = 1;
1413  else if ( 0 == ::strncmp("-dump_rotations",argv[i],12) )
1414  dump_rot = 1;
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) )
1424  dump_iddesc = 1;
1425  else if ( 0 == ::strncmp("-write_files",argv[i],8) )
1426  write_files = 1;
1427  else if ( 0 == ::strncmp("-reorder",argv[i],6) )
1428  reorder = 1;
1429  else if ( 0 == ::strncmp("-keep_hashes",argv[i],8) )
1430  have_hash_strings = 1;
1431  else {
1432  std::cout <<
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"
1445  " \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"
1462  " \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"
1469  " \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;
1473  ::exit(EINVAL);
1474  }
1475  }
1476  DetectorChecksum wr(description);
1477  DetElement de = description.world();
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;
1491  wr.debug = debug;
1492  wr.configure();
1493 
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 )
1499  {
1500  make_dump = true;
1501  wr.debug = 1;
1502  }
1503  int round = std::fegetround();
1504  std::fesetround(FE_TONEAREST);
1505  printout(INFO,"DetectorChecksum","+++ Rounding mode: %d new: %d", round, std::fegetround());
1506 
1507  DetectorChecksum::hashes_t hash_vec;
1508  DetectorChecksum::hash_t checksum = 0;
1509  if ( !detectors.empty() ) {
1510  for (const auto& det : detectors ) {
1511  de = detail::tools::findElement(description,det);
1512  wr.analyzeDetector(de);
1513  hash_vec.clear();
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("");
1518  }
1519  checksum = detail::hash64(&hash_vec[0], hash_vec.size()*sizeof(DetectorChecksum::hash_t));
1520  printout(ALWAYS,"DetectorChecksum","+++ Checksum for %s 0x%016lx",
1521  de.path().c_str(), checksum);
1522  if ( make_dump ) goto MakeDump;
1523  }
1524  return 1;
1525  }
1526 
1527 
1528  wr.analyzeDetector(de);
1529  hash_vec.push_back(wr.handleHeader().hash);
1530  wr.checksumDetElement(0, description.world(), hash_vec, true);
1531  checksum = detail::hash64(&hash_vec[0], hash_vec.size()*sizeof(DetectorChecksum::hash_t));
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);
1535 
1536  MakeDump:
1537  if ( make_dump ) {
1538  wr.debug = debug;
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();
1550  }
1551  return 1;
1552 }
1553 
1554 DECLARE_APPLY(DD4hepDetectorChecksum, create_checksum)
dd4hep::detail::DetectorChecksum::reorder
int reorder
Definition: DetectorChecksum.h:127
dd4hep::DetElement::children
const Children & children() const
Access to the list of children.
Definition: DetElement.cpp:207
dd4hep::detail::DetectorChecksum::debug_hash
std::stringstream debug_hash
Definition: DetectorChecksum.h:93
dd4hep::detail::DetectorChecksum::handleHeader
virtual const entry_t & handleHeader() const
Add header information in Detector format.
Definition: DetectorChecksum.cpp:1053
dd4hep::DetElement::path
const std::string & path() const
Path of the detector element (not necessarily identical to placement path!)
Definition: DetElement.cpp:158
dd4hep::detail::DetectorChecksum::handleDetElement
virtual const entry_t & handleDetElement(DetElement det) const
Definition: DetectorChecksum.cpp:914
dd4hep::detail::DetectorChecksum::attr_name
std::string attr_name(T handle) const
Definition: DetectorChecksum.cpp:152
dd4hep::detail::DetectorChecksum::dump_materials
void dump_materials() const
Dump materials used in this apparatus.
Definition: DetectorChecksum.cpp:1299
dd4hep::DDSegmentation::BitFieldElement::offset
unsigned offset() const
Definition: BitFieldCoder.h:64
dd4hep::detail::DetectorChecksum::checksumPlacement
void checksumPlacement(PlacedVolume pv, hashes_t &hashes, bool recursive) const
Definition: DetectorChecksum.cpp:1260
dd4hep::Header::comment
const std::string & comment() const
Accessor to object comment.
Definition: Objects.cpp:128
dd4hep::Detector::world
virtual DetElement world() const =0
Return reference to the top-most (world) detector element.
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfIdSpecs
IdSpecMap mapOfIdSpecs
Definition: DetectorChecksum.h:77
dd4hep::Atom
Handle class describing an element in the periodic table.
Definition: Objects.h:242
dd4hep::detail::DetectorChecksum::dump_positions
void dump_positions() const
Dump positions used in this apparatus.
Definition: DetectorChecksum.cpp:1309
dd4hep::DDSegmentation::BitFieldElement
Helper class for BitFieldCoder that corresponds to one field value.
Definition: BitFieldCoder.h:32
dd4hep::detail::DetectorChecksum::newline
std::string newline
Definition: DetectorChecksum.h:113
dd4hep::detail::DetectorChecksum
Geometry converter from dd4hep to Geant 4 in Detector format.
Definition: DetectorChecksum.h:38
dd4hep::IDDescriptor::FieldMap
std::vector< std::pair< std::string, const Field * > > FieldMap
Definition: IDDescriptor.h:40
dd4hep::detail::DetectorChecksum::entry_t
Definition: DetectorChecksum.h:41
dd4hep::detail::DetectorChecksum::collect_det_elements
void collect_det_elements(DetElement top) const
Definition: DetectorChecksum.cpp:1070
dd4hep::detail::DetectorChecksum::m_len_unit
double m_len_unit
Definition: DetectorChecksum.h:100
v
View * v
Definition: MultiView.cpp:28
dd4hep::SensitiveDetector
Handle class to hold the information of a sensitive detector.
Definition: DetElement.h:44
dd4hep::detail::DetectorChecksum::handleSolid
virtual const entry_t & handleSolid(Solid solid) const
Convert the geometry type solid into the corresponding gdml string.
Definition: DetectorChecksum.cpp:244
MatrixHelpers.h
dd4hep::Alignment::data
AlignmentData & data()
Data accessor for the use of decorators.
Definition: Alignments.cpp:53
dd4hep::DDSegmentation::BitFieldElement::isSigned
bool isSigned() const
Definition: BitFieldCoder.h:70
dd4hep::XYZAngles
ROOT::Math::XYZVector XYZAngles
Definition: Objects.h:83
dd4hep::detail::DetectorChecksum::dump_placements
void dump_placements() const
Dump placements used in this apparatus.
Definition: DetectorChecksum.cpp:1324
dd4hep::detail::DetectorChecksum::dump_solids
void dump_solids() const
Dump solids used in this apparatus.
Definition: DetectorChecksum.cpp:1304
dd4hep::detail::DetectorChecksum::m_len_unit_nam
std::string m_len_unit_nam
Definition: DetectorChecksum.h:95
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfDetElements
MapOfDetElements mapOfDetElements
Definition: DetectorChecksum.h:84
dd4hep::PlacedVolume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:173
dd4hep::VisAttr
Handle class describing visualization attributes.
Definition: Objects.h:324
dd4hep::Region::storeSecondaries
bool storeSecondaries() const
Access secondaries flag.
Definition: Objects.cpp:525
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfPlacements
PlacementMap mapOfPlacements
Definition: DetectorChecksum.h:73
dd4hep::DetElement::placement
PlacedVolume placement() const
Access to the physical volume of this detector element.
Definition: DetElement.cpp:321
dd4hep::LimitSet::limits
const std::set< Limit > & limits() const
Accessor to limits container.
Definition: Objects.cpp:464
dd4hep::detail::DetectorChecksum::dump_detelements
void dump_detelements() const
Dump detelements used in this apparatus.
Definition: DetectorChecksum.cpp:1344
dd4hep::debug
std::size_t debug(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:64
dd4hep::detail::DetectorChecksum::dump_volumes
void dump_volumes() const
Dump volumes used in this apparatus.
Definition: DetectorChecksum.cpp:1319
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfVis
VisMap mapOfVis
Definition: DetectorChecksum.h:75
dd4hep::detail::DetectorChecksum::hash_readout
int hash_readout
Property: Include readout property in detector hash.
Definition: DetectorChecksum.h:120
dd4hep::detail::DetectorChecksum::handleSegmentation
virtual const entry_t & handleSegmentation(Segmentation seg) const
Convert the segmentation of a SensitiveDetector into the corresponding Detector object.
Definition: DetectorChecksum.cpp:966
dd4hep::detail::DetectorChecksum::have_hash_strings
int have_hash_strings
Property: Keep hash-strings, not only hash values (debugging)
Definition: DetectorChecksum.h:124
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfAlignments
AlignmentMap mapOfAlignments
Definition: DetectorChecksum.h:83
dd4hep::IDDescriptor
Class implementing the ID encoding of the detector response.
Definition: IDDescriptor.h:37
dd4hep::detail::DetectorChecksum::handleMaterial
virtual const entry_t & handleMaterial(Material medium) const
Convert the geometry type material into the corresponding gdml string.
Definition: DetectorChecksum.cpp:212
DECLARE_APPLY
#define DECLARE_APPLY(name, func)
Definition: Factories.h:281
dd4hep::detail::DetectorChecksum::hash_t
uint64_t hash_t
Definition: DetectorChecksum.h:40
dd4hep::detail::DetectorChecksum::data
GeometryInfo & data() const
Definition: DetectorChecksum.h:130
dd4hep::detail::DetectorChecksum::dump_elements
void dump_elements() const
Dump elements used in this apparatus.
Definition: DetectorChecksum.cpp:1294
dd4hep::detail::DetectorChecksum::dump_iddescriptors
void dump_iddescriptors() const
Dump iddescriptors used in this apparatus.
Definition: DetectorChecksum.cpp:1329
dd4hep::Volume::solid
Solid solid() const
Access to Solid (Shape)
Definition: Volumes.cpp:1223
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:128
DetectorInterna.h
dd4hep::detail::DetectorChecksum::~DetectorChecksum
virtual ~DetectorChecksum()
Standard destructor.
Definition: DetectorChecksum.cpp:132
dd4hep::detail::DetectorChecksum::handleIdSpec
virtual const entry_t & handleIdSpec(IDDescriptor idspec) const
Convert the geometry id dictionary entry to the corresponding gdml string.
Definition: DetectorChecksum.cpp:1001
dd4hep::Solid_type< TGeoShape >
dd4hep::Detector::fields
virtual const HandleMap & fields() const =0
Accessor to the map of field entries, which together form the global field.
dd4hep::Header::url
const std::string & url() const
Accessor to object url.
Definition: Objects.cpp:88
dd4hep::DDSegmentation::SegmentationParameter
Class to hold a segmentation parameter with its description.
Definition: SegmentationParameter.h:107
dd4hep::Handle::name
const char * name() const
Access the object name (or "" if not supported by the object)
dd4hep::detail::DetectorChecksum::logger
std::stringstream logger() const
Definition: DetectorChecksum.cpp:157
dd4hep::detail::DetectorChecksum::max_level
int max_level
Property: maximum depth level for printouts.
Definition: DetectorChecksum.h:122
dd4hep::detail::DetectorChecksum::hash_debug
void hash_debug(const std::string &prefix, const entry_t &str, int flag=0) const
Definition: DetectorChecksum.cpp:1120
dd4hep::detail::DetectorChecksum::dump_sensitives
void dump_sensitives() const
Dump sensitives used in this apparatus.
Definition: DetectorChecksum.cpp:1339
dd4hep::VisAttr::alpha
float alpha() const
Get alpha value.
Definition: Objects.cpp:371
dd4hep::detail::DetectorChecksum::handleField
virtual const entry_t & handleField(OverlayedField field) const
Convert the electric or magnetic fields into the corresponding gdml string.
Definition: DetectorChecksum.cpp:1025
dd4hep::OverlayedField
Class describing a field overlay with several sources.
Definition: Fields.h:138
dd4hep::detail::DetectorChecksum::GeometryInfo::header
entry_t header
Definition: DetectorChecksum.h:85
dd4hep::detail::DetectorChecksum::handleElement
virtual const entry_t & handleElement(Atom element) const
Convert the geometry type element into the corresponding gdml string.
Definition: DetectorChecksum.cpp:189
dd4hep::detail::tools::findElement
DetElement findElement(const Detector &description, const std::string &path)
Find DetElement as child of the top level volume by its absolute path.
Definition: DetectorTools.cpp:214
dd4hep::Header::name
const std::string name() const
Accessor to object name.
Definition: Objects.cpp:68
dd4hep::VisAttr::lineStyle
int lineStyle() const
Get line style.
Definition: Objects.cpp:351
dd4hep::Material
Handle class describing a material.
Definition: Objects.h:272
dd4hep::VisAttr::drawingStyle
int drawingStyle() const
Get drawing style.
Definition: Objects.cpp:361
dd4hep::detail::DetectorChecksum::handleRotation
virtual const entry_t & handleRotation(const TGeoMatrix *trafo) const
Convert the Rotation into the corresponding gdml string.
Definition: DetectorChecksum.cpp:675
dd4hep::detail::DetectorChecksum::debug
int debug
Property: debug level.
Definition: DetectorChecksum.h:126
dd4hep::detail::DetectorChecksum::dump_rotations
void dump_rotations() const
Dump rotations used in this apparatus.
Definition: DetectorChecksum.cpp:1314
dd4hep::VisAttr::showDaughters
bool showDaughters() const
Get Flag to show/hide daughter elements.
Definition: Objects.cpp:331
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfFields
FieldMap mapOfFields
Definition: DetectorChecksum.h:82
dd4hep::View::name
const std::string & name() const
Access to the view name/title.
Definition: View.h:81
dd4hep::detail::DetectorChecksum::m_ang_unit
double m_ang_unit
Definition: DetectorChecksum.h:101
dd4hep::detail::DetectorChecksum::m_atomunit
double m_atomunit
Definition: DetectorChecksum.h:104
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:188
dd4hep::detail::DetectorChecksum::write_files
int write_files
Definition: DetectorChecksum.h:128
dd4hep::Volume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:378
dd4hep::detail::DetectorChecksum::handleVolume
virtual const entry_t & handleVolume(Volume volume) const
Convert the geometry type logical volume into the corresponding gdml string.
Definition: DetectorChecksum.cpp:813
dd4hep::Solid_type::name
const char * name() const
Access to shape name.
Definition: Shapes.cpp:54
dd4hep::detail::DetectorChecksum::refName
std::string refName(T handle) const
Definition: DetectorChecksum.cpp:138
dd4hep::DDSegmentation::BitFieldElement::name
const std::string & name() const
Definition: BitFieldCoder.h:61
mix
#define mix(a, b, c)
Definition: Geant4EventSeed.h:113
dd4hep::detail::DetectorChecksum::hash_meshes
int hash_meshes
Property: Include meshed solids in detector hash.
Definition: DetectorChecksum.h:118
dd4hep::LimitSet
Handle class describing a set of limits as they are used for simulation.
Definition: Objects.h:425
dd4hep::SensitiveDetector::hitsCollection
const std::string & hitsCollection() const
Access the hits collection name.
Definition: DetElement.cpp:447
dd4hep::Volume::limitSet
LimitSet limitSet() const
Access to the limit set.
Definition: Volumes.cpp:1275
dd4hep::VisAttr::DASHED
@ DASHED
Definition: Objects.h:327
DetectorTools.h
dd4hep::Detector::sensitiveDetector
virtual SensitiveDetector sensitiveDetector(const std::string &name) const =0
Retrieve a sensitive detector by its name from the detector description.
DetectorChecksum
dd4hep::detail::DetectorChecksum DetectorChecksum
Definition: DetectorChecksum.cpp:42
dd4hep::detail::DetectorChecksum::entry_t::hash
hash_t hash
Definition: DetectorChecksum.h:42
dd4hep::Volume::region
Region region() const
Access to the handle to the region structure.
Definition: Volumes.cpp:1256
dd4hep::DDSegmentation::BitFieldElement::width
unsigned width() const
Definition: BitFieldCoder.h:67
dd4hep::detail::DetectorChecksum::handleAlignment
const entry_t & handleAlignment(Alignment alignment) const
Convert alignment entry into the corresponding gdml string.
Definition: DetectorChecksum.cpp:764
_U
#define _U(a)
Definition: Tags.h:23
dd4hep::SensitiveDetector::combineHits
bool combineHits() const
Access flag to combine hist.
Definition: DetElement.cpp:471
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfElements
ElementMap mapOfElements
Definition: DetectorChecksum.h:69
dd4hep::Header::author
const std::string & author() const
Accessor to object author.
Definition: Objects.cpp:98
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfRegions
RegionMap mapOfRegions
Definition: DetectorChecksum.h:74
Plugins.h
dd4hep::detail::DetectorChecksum::m_densunit
double m_densunit
Definition: DetectorChecksum.h:103
dd4hep::Region
Handle class describing a region as used in simulation.
Definition: Objects.h:462
dd4hep::Alignment
Main handle class to hold an alignment object.
Definition: Alignments.h:115
dd4hep::detail::DetectorChecksum::DetectorChecksum
DetectorChecksum(Detector &description)
Initializing Constructor.
Definition: DetectorChecksum.cpp:128
dd4hep::PluginDebug
Helper to debug plugin manager calls.
Definition: Plugins.h:74
dd4hep::VisAttr::rgb
bool rgb(float &red, float &green, float &blue) const
Get RGB values of the color (if valid)
Definition: Objects.cpp:396
dd4hep::detail::DetectorChecksum::dump_segmentations
void dump_segmentations() const
Dump segmentations used in this apparatus.
Definition: DetectorChecksum.cpp:1334
dd4hep::detail::GeoHandler::m_data
std::map< int, std::vector< const TGeoNode * > > * m_data
actual container with std::vector (preserves order)
Definition: GeoHandler.h:93
dd4hep::Header
Handle class describing the basic information about geometry objects as it is defined in Detector.
Definition: Objects.h:158
dd4hep::detail::DetectorChecksum::collectVolume
virtual void collectVolume(Volume volume) const
Dump logical volume in GDML format to output stream.
Definition: DetectorChecksum.cpp:795
dd4hep::Readout::segmentation
Segmentation segmentation() const
Access segmentation structure.
Definition: Readout.cpp:134
dd4hep::detail::DetectorChecksum::m_densunit_nam
std::string m_densunit_nam
Definition: DetectorChecksum.h:98
dd4hep::detail::DetectorChecksum::handlePosition
virtual const entry_t & handlePosition(const TGeoMatrix *trafo) const
Convert the Position into the corresponding gdml string.
Definition: DetectorChecksum.cpp:657
dd4hep::detail::DetectorChecksum::handlePlacement
virtual const entry_t & handlePlacement(PlacedVolume node) const
Convert the geometry type volume placement into the corresponding gdml string.
Definition: DetectorChecksum.cpp:880
dd4hep::xml::Strng_t
Helper class to encapsulate a unicode string.
Definition: XMLElements.h:170
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfVolumes
VolumeMap mapOfVolumes
Definition: DetectorChecksum.h:72
DetectorChecksum.h
dd4hep::PluginDebug::missingFactory
std::string missingFactory(const std::string &name) const
Helper to check factory existence.
Definition: Plugins.cpp:147
dd4hep::detail::matrix::_xyzAngles
XYZAngles _xyzAngles(const double *matrix)
Convert a 3x3 rotation matrix to XYZAngles.
Definition: MatrixHelpers.cpp:195
detectors
DetectorMap detectors
Definition: AlignmentsCalculator.cpp:79
dd4hep::Region::cut
double cut() const
Access cut value.
Definition: Objects.cpp:515
dd4hep::detail::DetectorChecksum::handleSensitive
virtual const entry_t & handleSensitive(SensitiveDetector sens_det) const
Convert the geometry type SensitiveDetector into the corresponding gdml string.
Definition: DetectorChecksum.cpp:937
dd4hep::SensitiveDetector::type
std::string type() const
Access the type of the sensitive detector.
Definition: DetElement.cpp:409
dd4hep::IDDescriptor::fields
const FieldMap & fields() const
Access the fieldmap container.
Definition: IDDescriptor.cpp:87
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfPositions
TrafoMap mapOfPositions
Definition: DetectorChecksum.h:80
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfSegmentations
SegmentationMap mapOfSegmentations
Definition: DetectorChecksum.h:78
dd4hep::detail::DetectorChecksum::checksumDetElement
void checksumDetElement(int level, DetElement det, hashes_t &hashes, bool recursive) const
Definition: DetectorChecksum.cpp:1133
dd4hep::Segmentation::type
std::string type() const
Accessor: Segmentation type.
Definition: Segmentations.cpp:50
dd4hep::detail::DetectorChecksum::empty_entry
entry_t empty_entry
Definition: DetectorChecksum.h:112
DetFactoryHelper.h
dd4hep::detail::DetectorChecksum::m_ene_unit
double m_ene_unit
Definition: DetectorChecksum.h:102
dd4hep::_toDouble
double _toDouble(const std::string &value)
String conversions: string to double value.
Definition: Handle.cpp:116
dd4hep::detail::DetectorChecksum::handleLimitSet
virtual const entry_t & handleLimitSet(LimitSet limitset) const
Convert the geometry type LimitSet into the corresponding gdml string.
Definition: DetectorChecksum.cpp:744
dd4hep::VisAttr::visible
bool visible() const
Get visibility flag.
Definition: Objects.cpp:341
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfSolids
SolidMap mapOfSolids
Definition: DetectorChecksum.h:71
dd4hep::VisAttr::SOLID
@ SOLID
Definition: Objects.h:327
dd4hep::Handle::ptr
T * ptr() const
Access to the held object.
Definition: Handle.h:153
ObjectsInterna.h
dd4hep::detail::DetectorChecksum::precision
int precision
Property: precision of hashed printouts.
Definition: DetectorChecksum.h:116
dd4hep::Segmentation::parameters
DDSegmentation::Parameters parameters() const
Access to the parameters.
Definition: Segmentations.cpp:59
dd4hep::detail::DetectorChecksum::GeometryInfo
Data structure of the geometry converter from dd4hep to Geant 4 in Detector format.
Definition: DetectorChecksum.h:67
dd4hep::SensitiveDetector::energyCutoff
double energyCutoff() const
Access energy cut off.
Definition: DetElement.cpp:436
dd4hep::detail::DetectorChecksum::make_entry
entry_t make_entry(std::stringstream &log) const
Definition: DetectorChecksum.cpp:164
dd4hep::detail::DetectorChecksum::m_detDesc
Detector & m_detDesc
Reference to detector description.
Definition: DetectorChecksum.h:91
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::Solid
Solid_type< TGeoShape > Solid
Definition: Shapes.h:197
dd4hep::VisAttr::WIREFRAME
@ WIREFRAME
Definition: Objects.h:327
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::detail::DetectorChecksum::m_dataPtr
GeometryInfo * m_dataPtr
Definition: DetectorChecksum.h:92
dd4hep::SensitiveDetector::readout
Readout readout() const
Access readout structure of the sensitive detector.
Definition: DetElement.cpp:420
dd4hep::PlacedVolume::volume
Volume volume() const
Logical volume of this placement.
Definition: Volumes.cpp:452
xml_elt_t
dd4hep::xml::Element xml_elt_t
Definition: ConditionsRepository.cpp:33
dd4hep::PlacedVolume::data
Object * data() const
Check if placement is properly instrumented.
Definition: Volumes.cpp:431
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfLimits
LimitMap mapOfLimits
Definition: DetectorChecksum.h:76
TGeoConeSeg
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
Definition: ROOTClasses.h:17
dd4hep::detail::DetectorChecksum::analyzeDetector
void analyzeDetector(DetElement top)
Create geometry conversion in Detector format.
Definition: DetectorChecksum.cpp:1083
dd4hep::Readout
Handle to the implementation of the readout structure of a subdetector.
Definition: Readout.h:38
dd4hep::Segmentation
Handle class supporting generic Segmentations of sensitive detectors.
Definition: Segmentations.h:41
dd4hep::detail::DetectorChecksum::configure
void configure()
Definition: DetectorChecksum.cpp:172
dd4hep::Readout::idSpec
IDDescriptor idSpec() const
Access IDDescription structure.
Definition: Readout.cpp:112
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfMaterials
MaterialMap mapOfMaterials
Definition: DetectorChecksum.h:70
dd4hep::detail::DetectorChecksum::hashes_t
std::vector< hash_t > hashes_t
Definition: DetectorChecksum.h:150
dd4hep::PlacedVolume::volIDs
const PlacedVolumeExtension::VolIDs & volIDs() const
Access to the volume IDs.
Definition: Volumes.cpp:480
dd4hep::Volume::visAttributes
VisAttr visAttributes() const
Access the visualisation attributes.
Definition: Volumes.cpp:1210
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfRotations
TrafoMap mapOfRotations
Definition: DetectorChecksum.h:81
dd4hep::detail::DetectorChecksum::handleVis
virtual const entry_t & handleVis(VisAttr vis) const
Convert the geometry visualisation attributes to the corresponding gdml string.
Definition: DetectorChecksum.cpp:693
_get_path
std::vector< PlacedVolume > _get_path(PlacedVolume node, const std::set< PlacedVolume > &match)
Definition: DetectorChecksum.cpp:1104
dd4hep::detail::DetectorChecksum::m_ang_unit_nam
std::string m_ang_unit_nam
Definition: DetectorChecksum.h:96
FieldTypes.h
Printout.h
dd4hep::detail::DetectorChecksum::handleRegion
virtual const entry_t & handleRegion(Region region) const
Convert the geometry type region into the corresponding gdml string.
Definition: DetectorChecksum.cpp:727
AlignmentData.h
dd4hep::Header::version
const std::string & version() const
Accessor to object version.
Definition: Objects.cpp:118
dd4hep::Detector::header
virtual Header header() const =0
Accessor to the map of header entries.
dd4hep::detail::DetectorChecksum::entry_t::data
std::string data
Definition: DetectorChecksum.h:43
handle
void handle(const O *o, const C &c, F pmf)
Definition: LCDDConverter.cpp:1105
dd4hep::detail::DetectorChecksum::m_atomunit_nam
std::string m_atomunit_nam
Definition: DetectorChecksum.h:99
dd4hep::detail::DetectorChecksum::m_ene_unit_nam
std::string m_ene_unit_nam
Definition: DetectorChecksum.h:97
dd4hep::detail::DetectorChecksum::GeometryInfo::mapOfSensDets
SensDetMap mapOfSensDets
Definition: DetectorChecksum.h:79
dd4hep::Volume::sensitiveDetector
Handle< NamedObject > sensitiveDetector() const
Access to the handle to the sensitive detector.
Definition: Volumes.cpp:1287