Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:24:26

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 #pragma once
0010 
0011 // Project include(s)
0012 #include "detray/core/detail/multi_store.hpp"
0013 #include "detray/core/detail/single_store.hpp"
0014 #include "detray/definitions/containers.hpp"
0015 #include "detray/definitions/indexing.hpp"
0016 #include "detray/geometry/mask.hpp"
0017 #include "detray/geometry/shapes/rectangle2D.hpp"
0018 #include "detray/geometry/shapes/trapezoid2D.hpp"
0019 #include "detray/geometry/surface_descriptor.hpp"
0020 #include "detray/io/backend/detail/type_info.hpp"  // mask_info
0021 #include "detray/material/material_slab.hpp"
0022 #include "detray/navigation/accelerators/brute_force.hpp"
0023 
0024 // Linear algebra types
0025 #include "detray/tutorial/types.hpp"
0026 
0027 // New geometric shape type
0028 #include "my_square2D.hpp"
0029 
0030 /// This example defines a detray geometry type for a detector with cuboid
0031 /// volumes that contain a new surface shape (squares), trapezoids and
0032 /// rectangles for the volume boundary surfaces (portals).
0033 /// For now, all surfaces in the volume(s) are stored in a 'brute force'
0034 /// acceleration data structure which tests all surfaces it contains during
0035 /// navigation.
0036 /// In this example detector design, volumes do not contain other volumes, so
0037 /// the volume lookup is done using a uniform grid.
0038 /// Furthermore, the detector will contain homogeneous material on its surfaces.
0039 ///
0040 /// If the new square shape should participate in the file IO, then the type and
0041 /// a corresponding enum entry have to be added to the
0042 /// detray/io/frontend/definitions.hpp header. Preferably appended to the end
0043 /// of the existing structures, so that the written ids in existing files stay
0044 /// valid
0045 namespace detray::tutorial {
0046 
0047 /// Defines a detector that contains squares, trapezoids and a bounding portal
0048 /// box.
0049 struct my_metadata {
0050   /// Define the algebra type for the geometry and navigation
0051   using algebra_type = detray::tutorial::algebra_t;
0052 
0053   /// Portal link type between volumes
0054   using nav_link = std::uint_least16_t;
0055 
0056   /// How to store and link transforms. The geometry context allows to resolve
0057   /// the conditions data for e.g. module alignment
0058   template <template <typename...> class vector_t = dvector>
0059   using transform_store = single_store<transform3, vector_t, geometry_context>;
0060 
0061   //
0062   // Surface Primitives
0063   //
0064 
0065   /// The mask types for the detector sensitive/passive surfaces
0066   using square = mask<square2D, algebra_type, nav_link>;
0067   using trapezoid = mask<trapezoid2D, algebra_type, nav_link>;
0068   // Types for portals
0069   using rectangle = mask<rectangle2D, algebra_type, nav_link>;
0070 
0071   /// Assign the mask types to the mask tuple container entries. It may be a
0072   /// good idea to have the most common types in the first tuple entries, in
0073   /// order to minimize the depth of the 'unrolling' before a mask is found
0074   /// in the tuple
0075   enum class mask_id : std::uint_least8_t {
0076     e_square2D = 0u,
0077     e_trapezoid2D = 1u,
0078     e_rectangle2D = 2u
0079   };
0080 
0081   friend std::ostream& operator<<(std::ostream& os, const mask_id& id) {
0082     switch (id) {
0083       case mask_id::e_square2D:
0084         os << "e_square2D";
0085         break;
0086       case mask_id::e_trapezoid2D:
0087         os << "e_trapezoid2D";
0088         break;
0089       case mask_id::e_rectangle2D:
0090         os << "e_rectangle2D";
0091         break;
0092       default:
0093         os << "Unknown mask_id";
0094         break;
0095     }
0096     return os;
0097   }
0098 
0099   /// This is the mask collections tuple (in the detector called 'mask store')
0100   /// the @c regular_multi_store is a vecemem-ready tuple of vectors of
0101   /// the detector masks.
0102   template <template <typename...> class vector_t = dvector>
0103   using mask_store =
0104       regular_multi_store<mask_id, empty_context, dtuple, vector_t, square,
0105                           trapezoid, rectangle>;
0106 
0107   //
0108   // Material Description
0109   //
0110 
0111   /// The material types to be mapped onto the surfaces: Here homogeneous
0112   /// material
0113   using slab = material_slab<scalar>;
0114 
0115   /// Similar to the mask store, there is a material store, which
0116   enum class material_id : std::uint_least8_t {
0117     e_material_slab = 0u,
0118     e_none = 1u,
0119   };
0120 
0121   friend std::ostream& operator<<(std::ostream& os, const material_id& id) {
0122     switch (id) {
0123       case material_id::e_material_slab:
0124         os << "e_material_slab";
0125         break;
0126       case material_id::e_none:
0127         os << "e_none";
0128         break;
0129       default:
0130         os << "Unknown material_id";
0131         break;
0132     }
0133     return os;
0134   }
0135 
0136   /// How to store and link materials. The material does not make use of
0137   /// conditions data ( @c empty_context )
0138   template <typename container_t = host_container_types>
0139   using material_store =
0140       multi_store<material_id, empty_context, dtuple,
0141                   typename container_t::template vector_type<slab>>;
0142 
0143   //
0144   // Acceleration structures
0145   //
0146 
0147   /// Portals and passives in the brute force search, sensitives in the grids
0148   enum geo_objects : std::uint_least8_t {
0149     e_portal = 0u,
0150     e_passive = 0u,
0151     e_sensitive = 1u,
0152     e_volume = 2u,
0153     e_size = 3u,
0154     e_all = e_size,
0155   };
0156 
0157   DETRAY_HOST inline friend std::ostream& operator<<(std::ostream& os,
0158                                                      geo_objects gobj) {
0159     switch (gobj) {
0160       case geo_objects::e_portal:
0161         // e_passive has same value (0u)
0162         os << "e_portal/e_passive";
0163         break;
0164       case geo_objects::e_sensitive:
0165         os << "e_sensitive";
0166         break;
0167       case geo_objects::e_volume:
0168         os << "e_volume";
0169         break;
0170       case geo_objects::e_size:
0171         // e_all has same value (2u)
0172         os << "e_size/e_all";
0173         break;
0174     }
0175     return os;
0176   }
0177 
0178   /// Surface descriptor type used for sensitives, passives and portals
0179   /// It holds the indices to the surface data in the detector data stores
0180   /// that were defined above
0181   using transform_link = typename transform_store<>::single_link;
0182   using mask_link = typename mask_store<>::single_link;
0183   using material_link = typename material_store<>::single_link;
0184   using surface_type =
0185       surface_descriptor<mask_link, material_link, transform_link, nav_link>;
0186 
0187   /// The acceleration data structures live in another tuple that needs to
0188   /// indexed correctly
0189   enum class accel_id : std::uint_least8_t {
0190     e_surface_brute_force = 0u,  //< test all surfaces in a volume (brute force)
0191     e_volume_cylinder3D_grid = 1u,
0192     e_surface_default = e_surface_brute_force,
0193     e_volume_default = e_volume_cylinder3D_grid,
0194   };
0195 
0196   friend std::ostream& operator<<(std::ostream& os, const accel_id& id) {
0197     switch (id) {
0198       case accel_id::e_surface_brute_force:
0199         os << "e_surface_brute_force/e_surface_default";
0200         break;
0201       default:
0202         os << "Unknown accel_id";
0203         break;
0204     }
0205     return os;
0206   }
0207 
0208   /// One link for portals/passives and one sensitive surfaces
0209   using object_link_type =
0210       dmulti_index<dtyped_index<accel_id, dindex>, geo_objects::e_size>;
0211 
0212   /// Data structure that allows to find the current detector volume from a
0213   /// given position. Here: Uniform grid with a 3D cylindrical shape
0214   template <typename container_t = host_container_types>
0215   using volume_accelerator =
0216       spatial_grid<algebra_type,
0217                    axes<cylinder3D, axis::bounds::e_open, axis::irregular,
0218                         axis::regular, axis::irregular>,
0219                    bins::single<dindex>, simple_serializer, container_t, false>;
0220 
0221   /// The tuple store that hold the acceleration data structures for all
0222   /// volumes. Every collection of accelerationdata structures defines its
0223   /// own container and view type. Does not make use of conditions data
0224   /// ( @c empty_context )
0225   /// How to store the acceleration data structures
0226   template <typename container_t = host_container_types>
0227   using accelerator_store =
0228       multi_store<accel_id, empty_context, dtuple,
0229                   brute_force_collection<surface_type, container_t>,
0230                   grid_collection<volume_accelerator<container_t>>>;
0231 };
0232 
0233 }  // namespace detray::tutorial