35 : m_detector(
Detector::getInstance())
42 : m_detector(description)
65 std::set<const TGeoNode*>& cont;
66 PvCollector(
Region r, std::set<const TGeoNode*>& c) : rg(r), cont(c) {}
67 void collect(TGeoNode* pv) {
69 for (Int_t idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau)
70 collect(pv->GetDaughter(idau));
72 void operator()(TGeoNode* pv) {
79 for (Int_t idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau)
80 (*this)(pv->GetDaughter(idau));
87 printout(ALWAYS,
"MaterialScan",
"+++ Set new scanning region to: %s [%ld placements]",
91 printout(ALWAYS,
"MaterialScan",
"+++ No region restrictions set. Back to full scanning mode.");
107 std::set<const TGeoNode*>& cont;
108 PvCollector(std::set<const TGeoNode*>& c) : cont(c) {}
109 void operator()(TGeoNode* pv) {
111 for (Int_t idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau) {
112 TGeoNode* daughter = pv->GetDaughter(idau);
124 printout(ALWAYS,
"MaterialScan",
"+++ Set new scanning volume to: %s [%ld placements]",
128 printout(ALWAYS,
"MaterialScan",
"+++ No subdetector restrictions set. Back to full scanning mode.");
146 std::set<const TGeoNode*>& cont;
147 PvCollector(
Material mat, std::set<const TGeoNode*>& c) : material(mat), cont(c) {}
148 void operator()(TGeoNode* pv) {
149 Volume vol = pv->GetVolume();
151 if ( mat.
ptr() == material.
ptr() ) {
154 for (Int_t idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau)
155 (*this)(pv->GetDaughter(idau));
162 printout(ALWAYS,
"MaterialScan",
"+++ Set new scanning material to: %s [%ld placements]",
166 printout(ALWAYS,
"MaterialScan",
"+++ No material restrictions set. Back to full scanning mode.");
172 Vector3D p0(x0, y0, z0), p1(x1, y1, z1);
182 double sum_lambda = 0;
183 double path_length = 0, total_length = 0;
184 const char* fmt1 =
" | %7s %-25s %3.0f %8.3f %8.4f %11.4f %11.4f %10.3f %8.2f %11.6f %11.6f (%7.2f,%7.2f,%7.2f)\n";
185 const char* fmt2 =
" | %7s %-25s %3.0f %8.3f %8.4f %11.6g %11.6g %10.3f %8.2f %11.6f %11.6f (%7.2f,%7.2f,%7.2f)\n";
186 const char* line =
" +--------------------------------------------------------------------------------------------------------------------------------------------------\n";
188 direction = (p1-p0).unit();
190 ::printf(
"%s + Material scan between: x_0 = (%7.2f,%7.2f,%7.2f) [cm] and x_1 = (%7.2f,%7.2f,%7.2f) [cm] : \n%s",
191 line,p0[0],p0[1],p0[2],p1[0],p1[1],p1[2],line);
192 ::printf(
" | \\ %-16s Atomic Radiation Interaction Path Integrated Integrated Material\n",
"Material");
193 ::printf(
" | Num. \\ %-16s Number/Z Mass/A Density Length Length Thickness Length X0 Lambda Endpoint/Startpoint\n",
"Name");
194 ::printf(
" | Layer \\ %-16s [g/mole] [g/cm3] [cm] [cm] [cm] [cm] [cm] [cm] ( cm, cm, cm)\n",
"");
197 std::set<Solid> tessellated_solids;
198 for(
unsigned i=0, n=placements.size(); i<n; ++i){
199 TGeoNode* pv = placements[i].first.ptr();
200 double length = placements[i].second;
201 total_length += length;
202 end = p0 + total_length * direction;
205 ::printf(
"%p %s %s %s\n",
206 placements[i].first.ptr(),
207 placements[i].first->GetName(),
208 placements[i].first->GetVolume()->GetName(),
209 placements[i].first->GetMedium()->GetName());
213 TGeoMaterial* curr_mat = placements[i].first->GetMedium()->GetMaterial();
214 TGeoMaterial* next_mat = (i+1)<n ? placements[i+1].first->GetMedium()->GetMaterial() :
nullptr;
215 double nx0 = length / curr_mat->GetRadLen();
216 double nLambda = length / curr_mat->GetIntLen();
219 sum_lambda += nLambda;
220 path_length += length;
221 materials.emplace_back(placements[i].first->GetMedium(),length);
222 const char* fmt = curr_mat->GetRadLen() >= 1e5 ? fmt2 : fmt1;
223 std::string mname = curr_mat->GetName();
224 if ( next_mat && (i+1)<n ) {
226 mname += next_mat->GetName();
228 Volume vol(placements[i].first->GetVolume());
230 if ( shape->IsA() == TGeoTessellated::Class() ) {
231 tessellated_solids.insert(shape);
234 ::printf(fmt,
"(start)" , curr_mat->GetName(), curr_mat->GetZ(), curr_mat->GetA(),
235 curr_mat->GetDensity(), curr_mat->GetRadLen()/dd4hep::cm, curr_mat->GetIntLen()/dd4hep::cm,
237 p0[0]/dd4hep::cm, p0[1]/dd4hep::cm, p0[2]/dd4hep::cm);
241 ::printf(fmt,
"(end)", curr_mat->GetName(), curr_mat->GetZ(), curr_mat->GetA(),
242 curr_mat->GetDensity(), curr_mat->GetRadLen()/dd4hep::cm, curr_mat->GetIntLen()/dd4hep::cm,
244 p0[0]/dd4hep::cm, p0[1]/dd4hep::cm, p0[2]/dd4hep::cm);
247 ::printf(fmt, std::to_string(i+1).c_str(), mname.c_str(), next_mat->GetZ(), next_mat->GetA(),
248 next_mat->GetDensity(), next_mat->GetRadLen()/dd4hep::cm, next_mat->GetIntLen()/dd4hep::cm,
249 length/dd4hep::cm, path_length/dd4hep::cm, sum_x0, sum_lambda,
250 end[0]/dd4hep::cm, end[1]/dd4hep::cm, end[2]/dd4hep::cm);
254 const MaterialData& avg = matMgr.createAveragedMaterial(materials);
256 ::printf(fmt,
"",
"Average Material",avg.
Z(),avg.
A(),avg.
density(),
258 path_length/dd4hep::cm, path_length/dd4hep::cm,
261 end[0]/dd4hep::cm, end[1]/dd4hep::cm, end[2]/dd4hep::cm);
264 if ( !tessellated_solids.empty() ) {
265 ::printf(
" | WARNING: %ld tessellated shape were encountered during the volume traversal:\n",
266 tessellated_solids.size());
267 for(
auto shape : tessellated_solids )
268 ::printf(
" | \t\t %s\n", shape.name());
269 ::printf(
" | WARNING: The results of this material scan are unreliable!\n");
276 Vector3D p0(x0, y0, z0), p1(x1, y1, z1);