Garfield++ 3.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
GeometryRoot.cc
Go to the documentation of this file.
1#include <cmath>
2#include <iostream>
3
4#include <TGeoBBox.h>
5#include <TGeoNode.h>
6#include <TList.h>
7
9
10namespace Garfield {
11
13
14void GeometryRoot::SetGeometry(TGeoManager* geoman) {
15 if (!geoman) {
16 std::cerr << m_className << "::SetGeometry: Null pointer.\n";
17 return;
18 }
19
20 m_geoManager = geoman;
21 m_materials.clear();
22}
23
24Medium* GeometryRoot::GetMedium(const double x, const double y,
25 const double z) const {
26 if (!m_geoManager) return nullptr;
27 m_geoManager->SetCurrentPoint(x, y, z);
28 if (m_geoManager->IsOutside()) return nullptr;
29 TGeoNode* cnode = m_geoManager->GetCurrentNode();
30 std::string name(cnode->GetMedium()->GetMaterial()->GetName());
31
32 const unsigned int nMaterials = m_materials.size();
33 for (unsigned int i = 0; i < nMaterials; ++i) {
34 if (m_materials[i].name == name) {
35 return m_materials[i].medium;
36 }
37 }
38 return nullptr;
39}
40
42 if (!m_geoManager) {
43 PrintGeoNotDefined("GetNumberOfMaterials");
44 return 0;
45 }
46
47 return m_geoManager->GetListOfMaterials()->GetEntries();
48}
49
50TGeoMaterial* GeometryRoot::GetMaterial(const unsigned int i) {
51 if (!m_geoManager) {
52 PrintGeoNotDefined("GetMaterial");
53 return nullptr;
54 }
55
56 return m_geoManager->GetMaterial(i);
57}
58
59TGeoMaterial* GeometryRoot::GetMaterial(const char* name) {
60 if (!m_geoManager) {
61 PrintGeoNotDefined("GetMaterial");
62 return nullptr;
63 }
64
65 return m_geoManager->GetMaterial(name);
66}
67
68void GeometryRoot::SetMedium(const unsigned int imat, Medium* med) {
69 if (!m_geoManager) {
70 PrintGeoNotDefined("SetMedium");
71 return;
72 }
73
74 if (!med) {
75 std::cerr << m_className << "::SetMedium: Null pointer.\n";
76 return;
77 }
78
79 TGeoMaterial* mat = m_geoManager->GetMaterial(imat);
80 if (!mat) {
81 std::cerr << m_className << "::SetMedium:\n"
82 << " ROOT material " << imat << " does not exist.\n";
83 return;
84 }
85
86 std::string name(mat->GetName());
87 bool isNew = true;
88 // Check if this material has already been associated with a medium
89 const unsigned int nMaterials = m_materials.size();
90 for (unsigned int i = 0; i < nMaterials; ++i) {
91 if (name != m_materials[i].name) continue;
92 std::cout << m_className << "::SetMedium:\n"
93 << " Current association of material " << name
94 << " with medium " << med->GetName() << " is overwritten.\n";
95 m_materials[i].medium = med;
96 isNew = false;
97 break;
98 }
99
100 if (isNew) {
101 material newMaterial;
102 newMaterial.name = name;
103 newMaterial.medium = med;
104 m_materials.push_back(std::move(newMaterial));
105 }
106
107 // Check if material properties match
108 const double rho1 = mat->GetDensity();
109 const double rho2 = med->GetMassDensity();
110 std::cout << m_className << "::SetMedium:\n"
111 << " ROOT material: " << name << "\n"
112 << " Density: " << rho1 << " g / cm3\n"
113 << " Medium: " << med->GetName() << "\n"
114 << " Density: " << rho2 << " g / cm3\n";
115 if (rho1 > 0 && fabs(rho1 - rho2) / rho1 > 0.01) {
116 std::cout << " WARNING: Densities differ by > 1%.\n";
117 }
118}
119
120void GeometryRoot::SetMedium(const char* name, Medium* med) {
121 if (!m_geoManager) {
122 PrintGeoNotDefined("SetMedium");
123 return;
124 }
125
126 if (!med) {
127 std::cerr << m_className << "::SetMedium: Null pointer.\n";
128 return;
129 }
130
131 const int imat = m_geoManager->GetMaterialIndex(name);
132 if (imat < 0) {
133 std::cerr << m_className << "::SetMedium:\n"
134 << " ROOT material " << name << " does not exist.\n";
135 return;
136 }
137
138 SetMedium(imat, med);
139}
140
141bool GeometryRoot::GetBoundingBox(double& xmin, double& ymin, double& zmin,
142 double& xmax, double& ymax, double& zmax) {
143 if (!m_geoManager) return false;
144 auto top = m_geoManager->GetTopVolume();
145 if (!top) return false;
146 if (!top->GetShape()) return false;
147 TGeoBBox* box = (TGeoBBox*)m_geoManager->GetTopVolume()->GetShape();
148 if (!box) return false;
149 const double dx = box->GetDX();
150 const double dy = box->GetDY();
151 const double dz = box->GetDZ();
152 const double ox = box->GetOrigin()[0];
153 const double oy = box->GetOrigin()[1];
154 const double oz = box->GetOrigin()[2];
155 xmin = ox - dx;
156 xmax = ox + dx;
157 ymin = oy - dy;
158 ymax = oy + dy;
159 zmin = oz - dz;
160 zmax = oz + dz;
161 return true;
162}
163
164void GeometryRoot::PrintGeoNotDefined(const std::string& fcn) const {
165
166 std::cerr << m_className + "::" + fcn << ":\n"
167 << " ROOT geometry is not defined. Call SetGeometry first.\n";
168}
169
170}
Abstract base class for geometry classes.
Definition: GeometryBase.hh:13
TGeoManager * m_geoManager
Definition: GeometryRoot.hh:54
unsigned int GetNumberOfMaterials()
Get the number of materials defined in the ROOT geometry.
Definition: GeometryRoot.cc:41
std::vector< material > m_materials
Definition: GeometryRoot.hh:61
GeometryRoot()
Constructor.
Definition: GeometryRoot.cc:12
void SetMedium(const unsigned int imat, Medium *med)
Associate a ROOT material with Garfield medium.
Definition: GeometryRoot.cc:68
void PrintGeoNotDefined(const std::string &fcn) const
void SetGeometry(TGeoManager *geoman)
Set the geometry (pointer to ROOT TGeoManager).
Definition: GeometryRoot.cc:14
Medium * GetMedium(const double x, const double y, const double z) const override
Retrieve the medium at a given point.
Definition: GeometryRoot.cc:24
TGeoMaterial * GetMaterial(const unsigned int i)
Get pointer to ROOT material with given index.
Definition: GeometryRoot.cc:50
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
Get the bounding box (envelope of the geometry).
Abstract base class for media.
Definition: Medium.hh:13
virtual double GetMassDensity() const
Get the mass density [g/cm3].
Definition: Medium.cc:101
const std::string & GetName() const
Get the medium name/identifier.
Definition: Medium.hh:23