Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:27

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