1#include "Tracking/geo/EcalTrackingGeometry.h"
5EcalTrackingGeometry::EcalTrackingGeometry(std::string gdmlfile,
6 Acts::GeometryContext* gctx,
13 double rotationAngle = M_PI * 0.5;
21 Acts::Vector3 xPos1(cos(rotationAngle), 0., sin(rotationAngle));
22 Acts::Vector3 yPos1(0., 1., 0.);
23 Acts::Vector3 zPos1(-sin(rotationAngle), 0., cos(rotationAngle));
25 y_rot_.col(0) = xPos1;
26 y_rot_.col(1) = yPos1;
27 y_rot_.col(2) = zPos1;
30 Acts::Vector3 xPos2(1., 0., 0.);
31 Acts::Vector3 yPos2(0., cos(rotationAngle), sin(rotationAngle));
32 Acts::Vector3 zPos2(0., -sin(rotationAngle), cos(rotationAngle));
34 x_rot_.col(0) = xPos2;
35 x_rot_.col(1) = yPos2;
36 x_rot_.col(2) = zPos2;
42 "/Users/pbutti/sw/ldmx-sw/Detectors/data/ldmx-det-v12/detector.gdml",
44 G4VPhysicalVolume* fWorldPhysVol = parser.GetWorldVolume();
46 std::cout <<
"World position" << std::endl;
47 std::cout << fWorldPhysVol->GetTranslation() << std::endl;
50 if (debug) std::cout <<
"Loop on world daughters" << std::endl;
52 _ECAL = findDaughterByName(fWorldPhysVol,
"em_calorimeters_PV");
55 std::cout << _ECAL->GetName() << std::endl;
56 std::cout << _ECAL->GetTranslation() << std::endl;
57 std::cout << _ECAL->GetLogicalVolume()->GetNoDaughters() << std::endl;
63 std::cout <<
"Looking for later components" << std::endl;
67 std::vector<Acts::CuboidVolumeBuilder::LayerConfig> layersCfg;
70 std::vector<std::reference_wrapper<G4VPhysicalVolume>> components;
71 std::vector<std::shared_ptr<const Acts::Surface>> sensor_surfaces;
74 getComponentRing(
"_a_",
"Si", components);
76 for (
auto& component : components) {
80 for (
int i = 0; i < sensor_surfaces.size(); i += 14) {
81 std::vector<std::shared_ptr<const Acts::Surface>> rings;
82 for (
int j = 0; j < 14; j++) {
83 rings.push_back(sensor_surfaces.at(i + j));
86 Acts::CuboidVolumeBuilder::LayerConfig lyCfg = buildLayerConfig(rings);
87 layersCfg.push_back(lyCfg);
91 sensor_surfaces.clear();
95 getComponentRing(
"_a_",
"Si", components);
97 for (
auto& component : components) {
101 for (
int i = 0; i < sensor_surfaces.size(); i += 14) {
102 std::vector<std::shared_ptr<const Acts::Surface>> rings;
103 for (
int j = 0; j < 14; j++) {
104 rings.push_back(sensor_surfaces.at(i + j));
107 Acts::CuboidVolumeBuilder::LayerConfig lyCfg = buildLayerConfig(rings);
108 layersCfg.push_back(lyCfg);
112 sensor_surfaces.clear();
192 Acts::CuboidVolumeBuilder::VolumeConfig ecal_vcfg;
195 ecal_vcfg.position = {0., 0., 0.};
196 G4Box* ecal_box = (G4Box*)_ECAL->GetLogicalVolume()->GetSolid();
200 ecal_vcfg.length = {ecal_box->GetZHalfLength() * 2.,
201 ecal_box->GetXHalfLength() * 2.,
202 ecal_box->GetYHalfLength() * 2.};
204 ecal_vcfg.name =
"Ecal_volume";
205 ecal_vcfg.layerCfg = layersCfg;
208 Acts::CuboidVolumeBuilder cvb;
209 Acts::CuboidVolumeBuilder::Config config;
210 config.position = {0., 0., 0.};
211 config.length = {2000, 2000, 2000};
212 config.volumeCfg = {ecal_vcfg};
214 cvb.setConfig(config);
216 Acts::TrackingGeometryBuilder::Config tgbCfg;
217 tgbCfg.trackingVolumeBuilders.push_back(
218 [=](
const auto& cxt,
const auto& inner,
const auto&) {
219 return cvb.trackingVolume(cxt, inner,
nullptr);
221 Acts::TrackingGeometryBuilder tgb(tgbCfg);
222 tGeometry_ = tgb.trackingGeometry(*gctx_);
224 dumpGeometry(
"./ecal_test/");
227G4VPhysicalVolume* EcalTrackingGeometry::findDaughterByName(
228 G4VPhysicalVolume* pvol, G4String name) {
229 G4LogicalVolume* lvol = pvol->GetLogicalVolume();
230 for (G4int i = 0; i < lvol->GetNoDaughters(); i++) {
231 G4VPhysicalVolume* fDaughterPhysVol = lvol->GetDaughter(i);
232 if (fDaughterPhysVol->GetName() == name)
return fDaughterPhysVol;
245void EcalTrackingGeometry::getComponentRing(
246 std::string super_layer_name, std::string component_type,
247 std::vector<std::reference_wrapper<G4VPhysicalVolume>>& components) {
248 G4LogicalVolume* l_ECAL = _ECAL->GetLogicalVolume();
249 for (G4int i = 0; i < l_ECAL->GetNoDaughters(); i++) {
252 std::string sln = l_ECAL->GetDaughter(i)->GetName();
257 if (sln.find(super_layer_name) != std::string::npos &&
258 sln.find(component_type) != std::string::npos) {
260 components.push_back(*(l_ECAL->GetDaughter(i)));
266 sort(components.begin(), components.end(), compareZlocation);
269void EcalTrackingGeometry::getAllDaughters(G4VPhysicalVolume* pvol) {
270 G4LogicalVolume* lvol = pvol->GetLogicalVolume();
272 for (G4int i = 0; i < lvol->GetNoDaughters(); i++) {
273 G4VPhysicalVolume* fDaughterPhysVol = lvol->GetDaughter(i);
275 std::cout <<
"name::" << fDaughterPhysVol->GetName() << std::endl;
276 std::cout <<
"pos::" << fDaughterPhysVol->GetTranslation() << std::endl;
277 std::cout <<
"n_dau::"
278 << fDaughterPhysVol->GetLogicalVolume()->GetNoDaughters()
280 std::cout <<
"replica::" << fDaughterPhysVol->IsReplicated() << std::endl;
281 std::cout <<
"copyNR::" << fDaughterPhysVol->GetCopyNo() << std::endl;
286void EcalTrackingGeometry::dumpGeometry(
const std::string& outputDir) {
288 boost::filesystem::create_directory(outputDir);
290 double outputScalor = 1.0;
291 size_t outputPrecision = 6;
293 Acts::ObjVisualization3D objVis(outputPrecision, outputScalor);
294 Acts::ViewConfig containerView = Acts::ViewConfig({220, 220, 220});
295 Acts::ViewConfig volumeView = Acts::ViewConfig({220, 220, 0});
296 Acts::ViewConfig sensitiveView = Acts::ViewConfig({0, 180, 240});
297 Acts::ViewConfig passiveView = Acts::ViewConfig({240, 280, 0});
298 Acts::ViewConfig gridView = Acts::ViewConfig({220, 0, 0});
300 Acts::GeometryView3D::drawTrackingVolume(
301 objVis, *(tGeometry_->highestTrackingVolume()), *gctx_, containerView,
302 volumeView, passiveView, sensitiveView, gridView,
true,
"",
".");
305std::shared_ptr<const Acts::Surface>
307 G4Polyhedra* hex = (G4Polyhedra*)phex.GetLogicalVolume()->GetSolid();
308 G4Material* hex_mat = phex.GetLogicalVolume()->GetMaterial();
310 double side = hex->GetCorner(3).r;
311 double height = (side / 2.) * sqrt(3);
312 double thickness = 0.5 * Acts::UnitConstants::mm;
314 std::shared_ptr<Acts::PlaneSurface> surface;
323 std::shared_ptr<const Acts::DiamondBounds> d_bounds =
324 std::make_shared<Acts::DiamondBounds>(
325 side / 2. * Acts::UnitConstants::mm, side * Acts::UnitConstants::mm,
326 side / 2. * Acts::UnitConstants::mm, height * Acts::UnitConstants::mm,
327 height * Acts::UnitConstants::mm);
333 Acts::Vector3 pos(phex.GetTranslation().z(), phex.GetTranslation().x(),
334 phex.GetTranslation().y());
336 Acts::RotationMatrix3 rotation;
339 ConvertG4Rot(phex.GetObjectRotationValue(), rotation);
342 rotation = x_rot_ * y_rot_ * rotation;
344 Acts::Translation3 translation(pos);
345 Acts::Transform3 transform(translation * rotation);
346 surface = Acts::Surface::makeShared<Acts::PlaneSurface>(transform, d_bounds);
348 Acts::Material silicon = Acts::Material::fromMassDensity(
349 hex_mat->GetRadlen(), hex_mat->GetNuclearInterLength(), hex_mat->GetA(),
350 hex_mat->GetZ(), hex_mat->GetDensity());
352 Acts::MaterialSlab silicon_slab(silicon, thickness);
353 surface->assignSurfaceMaterial(
354 std::make_shared<Acts::HomogeneousSurfaceMaterial>(silicon_slab));
357 surface->toStream(*gctx_);
364void EcalTrackingGeometry::ConvertG4Rot(
const G4RotationMatrix& g4rot,
365 Acts::RotationMatrix3& rot) {
366 rot(0, 0) = g4rot.xx();
367 rot(0, 1) = g4rot.xy();
368 rot(0, 2) = g4rot.xz();
370 rot(1, 0) = g4rot.yx();
371 rot(1, 1) = g4rot.yy();
372 rot(1, 2) = g4rot.yz();
374 rot(2, 0) = g4rot.zx();
375 rot(2, 1) = g4rot.zy();
376 rot(2, 2) = g4rot.zz();
381Acts::Vector3 EcalTrackingGeometry::ConvertG4Pos(
const G4ThreeVector& g4pos) {
382 std::cout << std::endl;
383 std::cout <<
"g4pos::" << g4pos << std::endl;
384 Acts::Vector3 trans{g4pos.x(), g4pos.y(), g4pos.z()};
385 std::cout << trans << std::endl;
391Acts::CuboidVolumeBuilder::LayerConfig EcalTrackingGeometry::buildLayerConfig(
392 const std::vector<std::shared_ptr<const Acts::Surface>>& rings,
393 double clearance,
bool active) {
394 Acts::CuboidVolumeBuilder::LayerConfig lcfg;
396 for (
auto& hex : rings) {
397 lcfg.surfaces.push_back(hex);
401 Acts::Vector2 ploc{0., 0.};
403 rings.front()->surfaceMaterial()->materialSlab(ploc).thickness();
405 lcfg.envelopeX = std::array<double, 2>{thickness / 2. + clearance,
406 thickness / 2. + clearance};
407 lcfg.active = active;
std::shared_ptr< const Acts::Surface > convertHexToActsSurface(const G4VPhysicalVolume &phex)