Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-13 09:22:35

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include "ActsPlugins/Root/TGeoParser.hpp"
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Utilities/VectorHelpers.hpp"
0013 #include "ActsPlugins/Root/TGeoPrimitivesHelper.hpp"
0014 
0015 #include "RtypesCore.h"
0016 #include "TCollection.h"
0017 #include "TGeoBBox.h"
0018 #include "TGeoNode.h"
0019 #include "TGeoVolume.h"
0020 #include "TObjArray.h"
0021 #include "TObject.h"
0022 
0023 using namespace Acts;
0024 
0025 void ActsPlugins::TGeoParser::select(
0026     ActsPlugins::TGeoParser::State& state,
0027     const ActsPlugins::TGeoParser::Options& options,
0028     const TGeoMatrix& gmatrix) {
0029   // Volume is present
0030   if (state.volume != nullptr) {
0031     std::string volumeName = state.volume->GetName();
0032     // If you are on branch, you stay on branch
0033     state.onBranch =
0034         state.onBranch ||
0035         TGeoPrimitivesHelper::match(options.volumeNames, volumeName.c_str());
0036     // Loop over the daughters and collect them
0037     auto daughters = state.volume->GetNodes();
0038     // Daughter node iteration
0039     TIter iObj(daughters);
0040     while (TObject* obj = iObj()) {
0041       auto node = dynamic_cast<TGeoNode*>(obj);
0042       if (node != nullptr) {
0043         state.volume = nullptr;
0044         state.node = node;
0045         select(state, options, gmatrix);
0046       }
0047     }
0048   } else if (state.node != nullptr) {
0049     // The node name for checking
0050     std::string nodeName = state.node->GetName();
0051     std::string nodeVolName = state.node->GetVolume()->GetName();
0052     // Get the matrix of the current node for positioning
0053     const TGeoMatrix* nmatrix = state.node->GetMatrix();
0054     TGeoHMatrix transform = TGeoCombiTrans(gmatrix) * TGeoCombiTrans(*nmatrix);
0055     std::string suffix = "_transform";
0056     transform.SetName((nodeName + suffix).c_str());
0057     // Check if you had found the target node
0058     if (state.onBranch &&
0059         TGeoPrimitivesHelper::match(options.targetNames, nodeVolName.c_str())) {
0060       // Get the placement and orientation in respect to its mother
0061       const Double_t* rotation = transform.GetRotationMatrix();
0062       const Double_t* translation = transform.GetTranslation();
0063 
0064       // Create a eigen transform
0065       Vector3 t(options.unit * translation[0], options.unit * translation[1],
0066                 options.unit * translation[2]);
0067       Vector3 cx(rotation[0], rotation[3], rotation[6]);
0068       Vector3 cy(rotation[1], rotation[4], rotation[7]);
0069       Vector3 cz(rotation[2], rotation[5], rotation[8]);
0070       auto etrf = TGeoPrimitivesHelper::makeTransform(cx, cy, cz, t);
0071 
0072       bool accept = true;
0073       if (!options.parseRanges.empty()) {
0074         // It uses the bounding box of TGeoBBox
0075         if (auto* shape =
0076                 dynamic_cast<TGeoBBox*>(state.node->GetVolume()->GetShape());
0077             shape != nullptr) {
0078           // @TODO this should be replaced by a proper TGeo to VolumeBounds
0079           // and vertices conversion which would make a more appropriate
0080           // parsing
0081           double dx = options.unit * shape->GetDX();
0082           double dy = options.unit * shape->GetDY();
0083           double dz = options.unit * shape->GetDZ();
0084           for (auto x : std::vector<double>{-dx, dx}) {
0085             for (auto y : std::vector<double>{-dy, dy}) {
0086               for (auto z : std::vector<double>{-dz, dz}) {
0087                 Vector3 edge = etrf * Vector3(x, y, z);
0088                 for (auto& [axisDir, checkRange] : options.parseRanges) {
0089                   double val = VectorHelpers::cast(edge, axisDir);
0090                   if (val < checkRange.first || val > checkRange.second) {
0091                     accept = false;
0092                     break;
0093                   }
0094                 }
0095               }
0096             }
0097           }
0098         }
0099       }
0100       if (accept) {
0101         state.selectedNodes.push_back(
0102             {state.node, std::make_unique<TGeoHMatrix>(transform)});
0103       }
0104       state.node = nullptr;
0105     } else {
0106       // If it's not accepted, get the associated volume
0107       state.volume = state.node->GetVolume();
0108       state.node = nullptr;
0109       // Set one further down
0110       select(state, options, transform);
0111     }
0112   }
0113   return;
0114 }
0115 
0116 // Function to recursively find the node by volume name
0117 TGeoNode* ActsPlugins::TGeoParser::findNodeRecursive(TGeoNode* currentNode,
0118                                                      const char* volumeName) {
0119   // Check if the current node's volume matches the name
0120   if (std::strcmp(currentNode->GetVolume()->GetName(), volumeName) == 0) {
0121     return currentNode;
0122   }
0123   // Recursively search in the daughter nodes
0124   int nDaughters = currentNode->GetNdaughters();
0125   for (int i = 0; i < nDaughters; ++i) {
0126     TGeoNode* daughterNode = currentNode->GetDaughter(i);
0127     TGeoNode* foundNode = findNodeRecursive(daughterNode, volumeName);
0128     if (foundNode != nullptr) {
0129       return foundNode;
0130     }
0131   }
0132   return nullptr;  // Not found in this branch
0133 }