2#include "Tracking/geo/TrackingGeometry.h"
4#include <Acts/Surfaces/SurfaceArray.hpp>
5#include <Acts/Visualization/ObjVisualization3D.hpp>
6#include <Acts/Visualization/ViewConfig.hpp>
7#include <G4GDMLParser.hh>
8#include <G4LogicalVolume.hh>
10#include <boost/filesystem/operations.hpp>
11#include <boost/filesystem/path.hpp>
13#include "Framework/Exception/Exception.h"
14#include "G4UIsession.hh"
15#include "G4strstreambuf.hh"
28 G4UIsession* SessionStart() {
return nullptr; }
29 G4int ReceiveG4cout(
const G4String&) {
return 0; }
30 G4int ReceiveG4cerr(
const G4String&) {
return 0; }
34 const Acts::GeometryContext& gctx,
35 const std::string& gdml)
36 :
framework::ConditionsObject(name), gctx_{gctx}, gdml_{gdml} {
39 double rotation_angle = M_PI * 0.5;
47 Acts::Vector3 x_pos1(cos(rotation_angle), 0., sin(rotation_angle));
48 Acts::Vector3 y_pos1(0., 1., 0.);
49 Acts::Vector3 z_pos1(-sin(rotation_angle), 0., cos(rotation_angle));
51 y_rot_.col(0) = x_pos1;
52 y_rot_.col(1) = y_pos1;
53 y_rot_.col(2) = z_pos1;
56 Acts::Vector3 x_pos2(1., 0., 0.);
57 Acts::Vector3 y_pos2(0., cos(rotation_angle), sin(rotation_angle));
58 Acts::Vector3 z_pos2(0., -sin(rotation_angle), cos(rotation_angle));
60 x_rot_.col(0) = x_pos2;
61 x_rot_.col(1) = y_pos2;
62 x_rot_.col(2) = z_pos2;
75 std::unique_ptr<SilentG4> silence;
76 if (G4RunManager::GetRunManager() ==
nullptr) {
78 silence = std::make_unique<SilentG4>();
81 G4coutbuf.SetDestination(silence.get());
82 G4cerrbuf.SetDestination(silence.get());
89 parser.Read(gdml_,
false);
94 const G4GDMLAuxListType* aux_list = parser.GetAuxList();
95 for (
const auto& aux : *aux_list) {
96 if (aux.type ==
"MagneticField") {
97 for (
const auto& sub : *aux.auxList) {
98 if (sub.type ==
"File") {
99 boost::filesystem::path fmap(std::string(sub.value));
100 if (fmap.is_absolute()) {
101 field_map_file_ = fmap.string();
103 boost::filesystem::path prefix = boost::filesystem::path(gdml_)
107 field_map_file_ = (prefix /
"fieldmap" / fmap).
string();
116 if (field_map_file_.empty()) {
117 ldmx_log(warn) <<
"TrackingGeometry: no MagneticField/File auxiliary "
119 << gdml_ <<
"' — tracking will use a zero B-field";
122 f_world_phys_vol_ = parser.GetWorldVolume();
128 G4coutbuf.SetDestination(
nullptr);
129 G4cerrbuf.SetDestination(
nullptr);
133G4VPhysicalVolume* TrackingGeometry::findDaughterByName(G4VPhysicalVolume* pvol,
135 G4LogicalVolume* lvol = pvol->GetLogicalVolume();
136 for (G4int i = 0; i < lvol->GetNoDaughters(); i++) {
137 G4VPhysicalVolume* f_daughter_phys_vol = lvol->GetDaughter(i);
138 std::string d_name = f_daughter_phys_vol->GetName();
139 if (d_name.find(name) != std::string::npos)
return f_daughter_phys_vol;
146void TrackingGeometry::getAllDaughters(G4VPhysicalVolume* pvol) {
147 G4LogicalVolume* lvol = pvol->GetLogicalVolume();
149 ldmx_log(trace) <<
"Checking daughters of ::" << pvol->GetName();
151 for (G4int i = 0; i < lvol->GetNoDaughters(); i++) {
152 G4VPhysicalVolume* f_daughter_phys_vol = lvol->GetDaughter(i);
154 ldmx_log(trace) <<
"name::" << f_daughter_phys_vol->GetName();
155 ldmx_log(trace) <<
"pos_::" << f_daughter_phys_vol->GetTranslation();
158 << f_daughter_phys_vol->GetLogicalVolume()->GetNoDaughters();
159 ldmx_log(trace) <<
"replica::" << f_daughter_phys_vol->IsReplicated();
160 ldmx_log(trace) <<
"copyNR::" << f_daughter_phys_vol->GetCopyNo();
162 getAllDaughters(f_daughter_phys_vol);
180void TrackingGeometry::dumpGeometry(
const std::string& outputDir,
181 const Acts::GeometryContext& gctx)
const {
182 if (!t_geometry_)
return;
185 ldmx_log(trace) << __PRETTY_FUNCTION__;
187 for (
auto const& surface_id : layer_surface_map_) {
188 ldmx_log(trace) <<
" " << surface_id.first;
189 ldmx_log(trace) <<
" Check the surface";
191 surface_id.second->toStream(gctx);
192 ldmx_log(trace) <<
" GeometryID: " << surface_id.second->geometryId();
193 ldmx_log(trace) <<
" GeometryID value: "
194 << surface_id.second->geometryId().value();
199 boost::filesystem::create_directory(outputDir);
201 double output_scalor = 1.0;
202 size_t output_precision = 6;
204 Acts::ObjVisualization3D obj_vis(output_precision, output_scalor);
205 Acts::ViewConfig container_view{.color = {220, 220, 220}};
206 Acts::ViewConfig volume_view{.color = {220, 220, 0}};
207 Acts::ViewConfig sensitive_view{.color = {0, 180, 240}};
208 Acts::ViewConfig passive_view{.color = {240, 280, 0}};
209 Acts::ViewConfig grid_view{.color = {220, 0, 0}};
211 Acts::GeometryView3D::drawTrackingVolume(
212 obj_vis, *(t_geometry_->highestTrackingVolume()), gctx, container_view,
213 volume_view, passive_view, sensitive_view, grid_view,
true,
"",
".");
217Acts::Transform3 TrackingGeometry::getTransform(
const G4VPhysicalVolume& phex,
218 bool toTrackingFrame)
const {
219 Acts::Vector3 pos(phex.GetTranslation().x(), phex.GetTranslation().y(),
220 phex.GetTranslation().z());
222 Acts::RotationMatrix3 rotation;
223 convertG4Rot(phex.GetRotation(), rotation);
226 if (toTrackingFrame) {
227 pos(0) = phex.GetTranslation().z();
228 pos(1) = phex.GetTranslation().x();
229 pos(2) = phex.GetTranslation().y();
230 rotation = x_rot_ * y_rot_ * rotation;
233 Acts::Translation3 translation(pos);
235 Acts::Transform3 transform(translation * rotation);
242Acts::Transform3 TrackingGeometry::toTracker(
243 const Acts::Transform3& trans)
const {
244 Acts::Vector3 pos{trans.translation()(2), trans.translation()(0),
245 trans.translation()(1)};
247 Acts::RotationMatrix3 rotation = trans.rotation();
248 rotation = x_rot_ * y_rot_ * rotation;
250 Acts::Translation3 translation(pos);
251 Acts::Transform3 transform(translation * rotation);
257void TrackingGeometry::convertG4Rot(
const G4RotationMatrix* g4rot,
258 Acts::RotationMatrix3& rot)
const {
262 rot = Acts::RotationMatrix3::Identity();
265 rot(0, 0) = g4rot->xx();
266 rot(0, 1) = g4rot->xy();
267 rot(0, 2) = g4rot->xz();
269 rot(1, 0) = g4rot->yx();
270 rot(1, 1) = g4rot->yy();
271 rot(1, 2) = g4rot->yz();
273 rot(2, 0) = g4rot->zx();
274 rot(2, 1) = g4rot->zy();
275 rot(2, 2) = g4rot->zz();
281Acts::Vector3 TrackingGeometry::convertG4Pos(
const G4ThreeVector& g4pos)
const {
282 Acts::Vector3 trans{g4pos.x(), g4pos.y(), g4pos.z()};
285 ldmx_log(trace) <<
"g4pos::" << g4pos;
286 ldmx_log(trace) <<
"trans" << trans;
292void TrackingGeometry::getSurfaces(
293 std::vector<const Acts::Surface*>& surfaces)
const {
295 EXCEPTION_RAISE(
"BadGeometry",
296 "TrackingGeometry::getSurfaces tGeometry is null");
298 const Acts::TrackingVolume* t_volume = t_geometry_->highestTrackingVolume();
299 if (t_volume->confinedVolumes()) {
300 for (
auto volume : t_volume->confinedVolumes()->arrayObjects()) {
301 if (volume->confinedLayers()) {
302 for (
const auto& layer : volume->confinedLayers()->arrayObjects()) {
303 if (layer->layerType() == Acts::navigation)
continue;
304 for (
auto surface : layer->surfaceArray()->surfaces()) {
306 surfaces.push_back(surface);
316void TrackingGeometry::makeLayerSurfacesMap() {
317 std::vector<const Acts::Surface*> surfaces;
318 getSurfaces(surfaces);
320 for (
auto& surface : surfaces) {
325 unsigned int volume_id = surface->geometryId().volume();
326 unsigned int layer_id = (surface->geometryId().layer() /
329 unsigned int sensor_id =
330 surface->geometryId().sensitive() -
334 ldmx_log(trace) <<
"VolumeID " << volume_id <<
" LayerId " << layer_id
335 <<
" sensorId " << sensor_id;
338 unsigned int surface_id = volume_id * 1000 + layer_id * 100 + sensor_id;
340 layer_surface_map_[surface_id] = surface;
This class throws away all of the messages from Geant4.
TrackingGeometry(const std::string &name, const Acts::GeometryContext &gctx, const std::string &gdml)
All classes in the ldmx-sw project use this namespace.