22 #include "DD4hep/Detector.h"
23 #include "DD4hep/Printout.h"
27 using namespace dd4hep;
28 using namespace dd4hep::rec;
31 MaterialScan::MaterialScan()
32 : m_detector(Detector::getInstance())
39 : m_detector(description)
64 void collect(TGeoNode* pv) {
66 for (Int_t idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau)
67 collect(pv->GetDaughter(idau));
69 void operator()(TGeoNode* pv) {
70 Volume v = pv->GetVolume();
71 Region r = v.region();
76 for (Int_t idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau)
77 (*
this)(pv->GetDaughter(idau));
81 if ( region.isValid() ) {
84 printout(ALWAYS,
"MaterialScan",
"+++ Set new scanning region to: %s [%ld placements]",
88 printout(ALWAYS,
"MaterialScan",
"+++ No region restrictions set. Back to full scanning mode.");
106 void operator()(TGeoNode* pv) {
108 for (Int_t idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau) {
109 TGeoNode* daughter = pv->GetDaughter(idau);
114 if ( detector.isValid() ) {
115 PlacedVolume pv = detector.placement();
117 if ( pv.isValid() ) {
121 printout(ALWAYS,
"MaterialScan",
"+++ Set new scanning volume to: %s [%ld placements]",
125 printout(ALWAYS,
"MaterialScan",
"+++ No subdetector restrictions set. Back to full scanning mode.");
145 void operator()(TGeoNode* pv) {
146 Volume vol = pv->GetVolume();
147 Material mat = vol.material();
148 if ( mat.ptr() == material.ptr() ) {
151 for (Int_t idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau)
152 (*
this)(pv->GetDaughter(idau));
156 if ( material.isValid() ) {
159 printout(ALWAYS,
"MaterialScan",
"+++ Set new scanning material to: %s [%ld placements]",
163 printout(ALWAYS,
"MaterialScan",
"+++ No material restrictions set. Back to full scanning mode.");
169 Vector3D p0(x0, y0, z0), p1(x1, y1, z1);
175 const auto& placements =
m_materialMgr->placementsBetween(p0, p1, epsilon);
179 double sum_lambda = 0;
180 double path_length = 0, total_length = 0;
181 const char* fmt1 =
" | %5d %-20s %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";
182 const char* fmt2 =
" | %5d %-20s %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";
183 const char* line =
" +--------------------------------------------------------------------------------------------------------------------------------------------------\n";
185 direction = (p1-p0).unit();
187 ::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",
188 line,p0[0],p0[1],p0[2],p1[0],p1[1],p1[2],line);
189 ::printf(
" | \\ %-11s Atomic Radiation Interaction Path Integrated Integrated Material\n",
"Material");
190 ::printf(
" | Num. \\ %-11s Number/Z Mass/A Density Length Length Thickness Length X0 Lambda Endpoint \n",
"Name");
191 ::printf(
" | Layer \\ %-11s [g/mole] [g/cm3] [cm] [cm] [cm] [cm] [cm] [cm] ( cm, cm, cm)\n",
"");
194 for(
unsigned i=0,n=placements.size(); i<n; ++i){
195 TGeoNode* pv = placements[i].first.ptr();
196 double length = placements[i].second;
197 total_length += length;
198 end = p0 + total_length * direction;
201 ::printf(
"%p %s %s %s\n",
202 placements[i].first.ptr(),
203 placements[i].first->GetName(),
204 placements[i].first->GetVolume()->GetName(),
205 placements[i].first->GetMedium()->GetName());
209 TGeoMaterial* mat = placements[i].first->GetMedium()->GetMaterial();
210 double nx0 = length / mat->GetRadLen();
211 double nLambda = length / mat->GetIntLen();
214 sum_lambda += nLambda;
215 path_length += length;
216 materials.
emplace_back(placements[i].first->GetMedium(),length);
217 const char* fmt = mat->GetRadLen() >= 1e5 ? fmt2 : fmt1;
218 ::printf(fmt, i+1, mat->GetName(), mat->GetZ(), mat->GetA(),
219 mat->GetDensity(), mat->GetRadLen(), mat->GetIntLen(),
220 length, path_length, sum_x0, sum_lambda, end[0], end[1], end[2]);
224 const MaterialData& avg = matMgr.createAveragedMaterial(materials);
226 ::printf(fmt,0,
"Average Material",avg.
Z(),avg.
A(),avg.
density(),
228 path_length, path_length,
231 end[0], end[1], end[2]);
236 void MaterialScan::print(
double x0,
double y0,
double z0,
double x1,
double y1,
double z1,
double epsilon)
const {
237 Vector3D p0(x0, y0, z0), p1(x1, y1, z1);
238 print(p0, p1, epsilon);
virtual double radiationLength() const
radiation length - tgeo units
virtual double interactionLength() const
interaction length - tgeo units
void setRegion(const char *region)
Set a specific region to limit the scan (resets other selection criteria)
virtual ~MaterialScan()
Default destructor.
Simple three dimensional vector providing the components for cartesian, cylindrical and spherical coo...
MaterialScan()
Default constructor.
void setMaterial(const char *material)
Set a specific volume material to limit the scan (resets other selection criteria) ...
std::unique_ptr< MaterialManager > m_materialMgr
Material manager.
std::set< const TGeoNode * > m_placements
Local cache: subdetector placements.
virtual double density() const
density
void print(const Vector3D &start, const Vector3D &end, double epsilon=1e-4) const
Scan along a line and print the materials traversed.
Detector & m_detector
Reference to detector setup.
virtual double A() const
averaged atomic number
Simple data class that implements the IMaterial interface and is used in the Surface implementation...
const MaterialVec & scan(double x0, double y0, double z0, double x1, double y1, double z1, double epsilon=1e-4) const
Scan along a line and store the matrials internally.
virtual double Z() const
averaged proton number
void setDetector(DetElement detector)
Set a specific detector volume to limit the scan (resets other selection criteria) ...
Material manager provides access to the material properties of the detector.