Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:05:27

0001 #ifndef DetectorDescription_DDCMS_DDFilteredView_h
0002 #define DetectorDescription_DDCMS_DDFilteredView_h
0003 
0004 // -*- C++ -*-
0005 //
0006 // Package:    DetectorDescription/Core
0007 // Class:      DDFilteredView
0008 //
0009 /**\class DDFilteredView
0010 
0011  Description: Filtered View of a Tree
0012 
0013  Implementation:
0014      Filter criteria is defined in XML
0015 */
0016 //
0017 // Original Author:  Ianna Osborne
0018 //         Created:  Wed, 30 Jan 2019 09:24:30 GMT
0019 //
0020 //
0021 #include "DetectorDescription/DDCMS/interface/DDSolidShapes.h"
0022 #include "DetectorDescription/DDCMS/interface/ExpandedNodes.h"
0023 #include "DetectorDescription/DDCMS/interface/DDVectorRegistry.h"
0024 #include <DD4hep/Filter.h>
0025 #include <DD4hep/SpecParRegistry.h>
0026 #include <DD4hep/Volumes.h>
0027 #include <memory>
0028 #include <tuple>
0029 #include <vector>
0030 
0031 namespace cms {
0032 
0033   struct DDSolid {
0034     explicit DDSolid(dd4hep::Solid s) : solid_(s) {}
0035     dd4hep::Solid solid() const { return solid_; }
0036     dd4hep::Solid solidA() const;
0037     dd4hep::Solid solidB() const;
0038     const std::vector<double> parameters() const;
0039 
0040   private:
0041     dd4hep::Solid solid_;
0042   };
0043 
0044   class DDDetector;
0045   class DDCompactView;
0046 
0047   using Volume = dd4hep::Volume;
0048   using PlacedVolume = dd4hep::PlacedVolume;
0049   using ExpandedNodes = cms::ExpandedNodes;
0050   using Filter = dd4hep::Filter;
0051   using DDSpecPar = dd4hep::SpecPar;
0052   using DDSpecParRefs = dd4hep::SpecParRefs;
0053   using DDSpecParRegistry = dd4hep::SpecParRegistry;
0054   using Iterator = TGeoIterator;
0055   using Node = TGeoNode;
0056   using Translation = ROOT::Math::DisplacementVector3D<ROOT::Math::Cartesian3D<double>>;
0057   using RotationMatrix = ROOT::Math::Rotation3D;
0058 
0059   struct DDFilter {
0060     DDFilter(const std::string& attribute = "", const std::string& value = "")
0061         : m_attribute(attribute), m_value(value) {}
0062     const std::string& attribute() const { return m_attribute; }
0063     const std::string& value() const { return m_value; }
0064 
0065   private:
0066     const std::string m_attribute;
0067     const std::string m_value;
0068   };
0069 
0070   class DDFilteredView {
0071   public:
0072     using nav_type = std::vector<int>;
0073 
0074     DDFilteredView(const DDDetector*, const Volume);
0075     DDFilteredView(const DDCompactView&, const cms::DDFilter&);
0076     DDFilteredView() = delete;
0077 
0078     //! The numbering history of the current node
0079     const ExpandedNodes& history();
0080 
0081     //! The physical volume of the current node
0082     const PlacedVolume volume() const;
0083 
0084     //! The full path to the current node
0085     const std::string path() const;
0086 
0087     const std::vector<const Node*> geoHistory() const;
0088 
0089     //! The list of the volume copy numbers
0090     //  along the full path to the current node
0091     const std::vector<int> copyNos() const;
0092 
0093     template <typename... Ts>
0094     auto copyNumbers(Ts&&... ts) const -> decltype(copyNos(std::forward<Ts>(ts)...)) {
0095       return copyNos(std::forward<Ts>(ts)...);
0096     }
0097 
0098     //! The absolute translation of the current node
0099     // Return value is Double_t translation[3] with x, y, z elements.
0100     const Double_t* trans() const;
0101     const Translation translation() const;
0102     const Translation translation(const std::vector<Node*>&) const;
0103 
0104     //! The absolute rotation of the current node
0105     const Double_t* rot() const;
0106     const RotationMatrix rotation() const;
0107     void rot(dd4hep::Rotation3D& matrixOut) const;
0108 
0109     //! User specific data
0110     void mergedSpecifics(DDSpecParRefs const&);
0111     const cms::DDSpecParRefs specpars() const { return refs_; }
0112 
0113     //! set the current node to the first child
0114     bool firstChild();
0115     bool nextChild();
0116 
0117     //! set the current node to the child in path
0118     std::vector<std::vector<Node*>> children(const std::string& path);
0119 
0120     //! set the current node to the next sibling
0121     bool nextSibling();
0122 
0123     //! set the current node to the next sub sibling
0124     bool sibling();
0125 
0126     //! count the number of children matching selection
0127     bool checkChild();
0128 
0129     //! set the current node to the parent node ...
0130     bool parent();
0131 
0132     //! set current node to the next node in the filtered tree
0133     bool next(int);
0134 
0135     //! set current node to the child node in the filtered tree
0136     void down();
0137 
0138     //! set current node to the parent node in the filtered tree
0139     void up();
0140 
0141     // Shape of current node
0142     dd4hep::Solid solid() const;
0143 
0144     // Name of current node
0145     std::string_view name() const;
0146 
0147     // Name of current node with namespace
0148     std::string_view fullName() const;
0149 
0150     // Copy number of current node
0151     unsigned short copyNum() const;
0152 
0153     // Material name of current node
0154     std::string_view materialName() const;
0155 
0156     //! extract shape parameters
0157     const std::vector<double> parameters() const;
0158 
0159     const cms::DDSolidShape shape() const;
0160 
0161     // Convert new DD4hep shape id to an old DD one
0162     LegacySolidShape legacyShape(const cms::DDSolidShape shape) const;
0163 
0164     //! extract attribute value
0165     template <typename T>
0166     T get(const std::string&);
0167 
0168     //! extract attribute value for current Node
0169     //  keep the namespace for comparison
0170     //  assume there are no regular expressions
0171     template <typename T>
0172     std::vector<T> getValuesNS(const std::string& key) {
0173       DDSpecParRefs refs;
0174       registry_->filter(refs, key);
0175 
0176       std::string path = this->path();
0177       for (const auto& specPar : refs) {
0178         for (const auto& part : specPar.second->paths) {
0179           bool flag(true);
0180           std::size_t from = 0;
0181           for (auto name : dd4hep::dd::split(part, "/")) {
0182             auto const& to = path.find(name, from);
0183             if (to == std::string::npos) {
0184               flag = false;
0185               break;
0186             } else {
0187               from = to;
0188             }
0189           }
0190           if (flag) {
0191             return specPar.second->value<std::vector<T>>(key);
0192           }
0193         }
0194       }
0195       return std::vector<T>();
0196     }
0197 
0198     //! extract another value from the same SpecPar
0199     //  call get<double> first to find a relevant one
0200     double getNextValue(const std::string&) const;
0201 
0202     //! extract attribute value in SpecPar
0203     template <typename T>
0204     T get(const std::string&, const std::string&) const;
0205 
0206     //! convert an attribute value from SpecPar
0207     //  without passing it through an evaluator,
0208     //  e.g. the original values have no units
0209     std::vector<double> get(const std::string&, const std::string&) const;
0210 
0211     std::string_view getString(const std::string&) const;
0212 
0213     //! return the stack of sibling numbers which indicates
0214     //  the current position in the DDFilteredView
0215     nav_type navPos() const;
0216 
0217     //! get Iterator level
0218     const int level() const;
0219 
0220     //! transversed the DDFilteredView according
0221     //  to the given stack of sibling numbers
0222     bool goTo(const nav_type&);
0223 
0224     //! print Filter paths and selections
0225     void printFilter() const;
0226 
0227     //! find a current Node SpecPar that has at least
0228     //  one of the attributes
0229     template <class T, class... Ts>
0230     void findSpecPar(T const& first, Ts const&... rest) {
0231       currentSpecPar_ = find(first);
0232       if constexpr (sizeof...(rest) > 0) {
0233         // this line will only be instantiated if there are further
0234         // arguments. if rest... is empty, there will be no call to
0235         // findSpecPar(next).
0236         if (currentSpecPar_ == nullptr)
0237           findSpecPar(rest...);
0238       }
0239     }
0240 
0241   private:
0242     bool accept(std::string_view);
0243     int nodeCopyNo(const std::string_view) const;
0244     std::vector<std::pair<std::string, int>> toNodeNames(const std::string&);
0245     bool match(const std::string&, const std::vector<std::pair<std::string, int>>&) const;
0246 
0247     //! set the current node to the first sibling
0248     bool firstSibling();
0249 
0250     //! find a SpecPar in the registry by key
0251     //  doesn't really belong here, but allows
0252     //  speeding up avoiding the same search over
0253     //  the registry
0254     const DDSpecPar* find(const std::string&) const;
0255     void filter(DDSpecParRefs&, const std::string&) const;
0256     std::string_view front(const std::string_view) const;
0257     std::string_view back(const std::string_view) const;
0258 
0259     //! helper functions
0260     std::string_view nodeNameAt(int) const;
0261     const int nodeCopyNoAt(int) const;
0262     bool compareEqualName(const std::string_view, const std::string_view) const;
0263     std::tuple<std::string_view, std::string_view> alignNamespaces(std::string_view, std::string_view) const;
0264     bool compareEqualCopyNumber(const std::string_view, int) const;
0265     bool matchPath(const std::string_view) const;
0266 
0267     ExpandedNodes nodes_;
0268     std::vector<Iterator> it_;
0269     std::vector<std::unique_ptr<Filter>> filters_;
0270     Filter* currentFilter_ = nullptr;
0271     Node* node_ = nullptr;
0272     const DDSpecParRegistry* registry_;
0273     DDSpecParRefs refs_;
0274     const DDSpecPar* currentSpecPar_ = nullptr;
0275     int startLevel_;
0276   };
0277 }  // namespace cms
0278 
0279 //stream geoHistory
0280 std::ostream& operator<<(std::ostream& os, const std::vector<const cms::Node*>& hst);
0281 
0282 #endif