Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//==========================================================================
// AIDA Detector description implementation
//--------------------------------------------------------------------------
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
// All rights reserved.
//
// For the licensing terms see $DD4hepINSTALL/LICENSE.
// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
//
// Author : M.Frank
//
//==========================================================================
//
// Simple program to print all the materials in a detector on
// a straight line between two given points
//
// Author : M.Frank, CERN
//
//==========================================================================
// Framework include files
#include "DDRec/MaterialScan.h"
#include "DD4hep/Detector.h"
#include "DD4hep/Printout.h"
#include <cstdio>
using namespace dd4hep;
using namespace dd4hep::rec;
/// Default constructor
MaterialScan::MaterialScan()
: m_detector(Detector::getInstance())
{
m_materialMgr.reset(new MaterialManager(m_detector.world().volume()));
}
/// Default constructor
MaterialScan::MaterialScan(Detector& description)
: m_detector(description)
{
m_materialMgr.reset(new MaterialManager(m_detector.world().volume()));
}
/// Default destructor
MaterialScan::~MaterialScan() {
}
/// Set a specific detector volume to limit the scan
void MaterialScan::setDetector(DetElement detector) {
if ( detector.isValid() ) {
printout(ALWAYS,"MaterialScan","+++ Set new scanning volume to: %s",detector.path().c_str());
m_materialMgr.reset(new MaterialManager(detector.volume()));
}
}
/// Scan along a line and store the matrials internally
const MaterialVec& MaterialScan::scan(double x0, double y0, double z0, double x1, double y1, double z1, double epsilon) const {
Vector3D p0(x0, y0, z0), p1(x1, y1, z1);
return m_materialMgr->materialsBetween(p0, p1, epsilon);
}
/// Scan along a line and print the materials traversed
void MaterialScan::print(const Vector3D& p0, const Vector3D& p1, double epsilon) const {
const auto& materials = m_materialMgr->materialsBetween(p0, p1, epsilon);
auto& matMgr = *m_materialMgr;
Vector3D end, direction;
double sum_x0 = 0;
double sum_lambda = 0;
double path_length = 0;
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";
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";
const char* line = " +--------------------------------------------------------------------------------------------------------------------------------------------------\n";
direction = (p1-p0).unit();
::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",
line,p0[0],p0[1],p0[2],p1[0],p1[1],p1[2],line);
::printf(" | \\ %-11s Atomic Radiation Interaction Path Integrated Integrated Material\n","Material");
::printf(" | Num. \\ %-11s Number/Z Mass/A Density Length Length Thickness Length X0 Lambda Endpoint \n","Name");
::printf(" | Layer \\ %-11s [g/mole] [g/cm3] [cm] [cm] [cm] [cm] [cm] [cm] ( cm, cm, cm)\n","");
::printf("%s",line);
for( unsigned i=0,n=materials.size();i<n;++i){
TGeoMaterial* mat = materials[i].first->GetMaterial();
double length = materials[i].second;
double nx0 = length / mat->GetRadLen();
sum_x0 += nx0;
double nLambda = length / mat->GetIntLen();
sum_lambda += nLambda;
path_length += length;
end = p0 + path_length * direction;
const char* fmt = mat->GetRadLen() >= 1e5 ? fmt2 : fmt1;
::printf(fmt, i+1, mat->GetName(), mat->GetZ(), mat->GetA(),
mat->GetDensity(), mat->GetRadLen(), mat->GetIntLen(),
length, path_length, sum_x0, sum_lambda, end[0], end[1], end[2]);
//mat->Print();
}
printf("%s",line);
const MaterialData& avg = matMgr.createAveragedMaterial(materials);
const char* fmt = avg.radiationLength() >= 1e5 ? fmt2 : fmt1;
end = p0 + path_length * direction;
::printf(fmt,0,"Average Material",avg.Z(),avg.A(),avg.density(),
avg.radiationLength(), avg.interactionLength(),
path_length, path_length,
path_length/avg.radiationLength(),
path_length/avg.interactionLength(),
end[0], end[1], end[2]);
printf("%s",line);
}
/// Scan along a line and print the materials traversed
void MaterialScan::print(double x0, double y0, double z0, double x1, double y1, double z1, double epsilon) const {
Vector3D p0(x0, y0, z0), p1(x1, y1, z1);
print(p0, p1, epsilon);
}