Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-22 08:02:48

0001 /*
0002  * AIDA Detector description implementation 
0003  * 
0004  * Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005  * All rights reserved.
0006  *
0007  * For the licensing terms see $DD4hepINSTALL/LICENSE.
0008  * For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009  *
0010  * HexGrid.cpp  
0011  *
0012  * Created on: August 9, 2023
0013  *      Author: Sebouh J. Paul, UC Riverside
0014  */
0015 #include <DD4hep/Factories.h>
0016 #include <DDSegmentation/HexGrid.h>
0017 
0018 namespace dd4hep {
0019   namespace DDSegmentation {
0020 
0021     /// Default constructor used by derived classes passing the encoding string
0022     HexGrid::HexGrid(const std::string& cellEncoding) :
0023       Segmentation(cellEncoding) {
0024         _type = "HexGridXY";
0025         _description = "Hexagonal segmentation in the local XY-plane";
0026 
0027         // register all necessary parameters
0028         registerParameter("stagger", "stagger mode", _stagger, 1);
0029         registerParameter("side_length", "Cell size", _sideLength, 1., SegmentationParameter::LengthUnit);
0030         registerParameter("offset_x", "Cell offset in X", _offsetX, 0., SegmentationParameter::LengthUnit, true);
0031         registerParameter("offset_y", "Cell offset in Y", _offsetY, 0., SegmentationParameter::LengthUnit, true);
0032         registerIdentifier("identifier_x", "Cell ID identifier for X", _xId, "x");
0033         registerIdentifier("identifier_y", "Cell ID identifier for Y", _yId, "y");
0034         registerParameter("stagger_keyword", "Volume ID identifier used for determining which volumes to stagger", _staggerKeyword, (std::string)"layer", SegmentationParameter::NoUnit, true);
0035     }
0036 
0037     /// Default constructor used by derived classes passing an existing decoder
0038     HexGrid::HexGrid(const BitFieldCoder* decode) : Segmentation(decode) {
0039         // define type and description
0040         _type = "HexGridXY";
0041         _description = "Hexagonal segmentation in the local XY-plane";
0042 
0043         // register all necessary parameters                                                                        
0044         registerParameter("stagger", "stagger mode", _stagger, 1);
0045         registerParameter("side_length", "Cell size", _sideLength, 1., SegmentationParameter::LengthUnit);
0046         registerParameter("offset_x", "Cell offset in X", _offsetX, 0., SegmentationParameter::LengthUnit, true);
0047         registerParameter("offset_y", "Cell offset in Y", _offsetY, 0., SegmentationParameter::LengthUnit, true);
0048         registerIdentifier("identifier_x", "Cell ID identifier for X", _xId, "x");
0049         registerIdentifier("identifier_y", "Cell ID identifier for Y", _yId, "y");
0050         registerParameter("stagger_keyword", "Volume ID identifier used for determining which volumes to stagger", _staggerKeyword, (std::string)"layer", SegmentationParameter::NoUnit, true);
0051     
0052     }
0053 
0054     /// Destructor
0055     HexGrid::~HexGrid() {
0056     }
0057 
0058     /// determine the position based on the cell ID
0059     Vector3D HexGrid::position(const CellID& cID) const {
0060         int layer=0;
0061         if (_stagger) layer= _decoder->get(cID,_staggerKeyword);
0062                 
0063         Vector3D cellPosition;
0064         cellPosition.X = _decoder->get(cID,_xId )*1.5*_sideLength+_offsetX+_sideLength/2.;
0065         cellPosition.Y = _decoder->get(cID,_yId )*std::sqrt(3)/2.*_sideLength+ _offsetY+_sideLength*std::sqrt(3)/2.;
0066         if (_stagger==0)
0067           cellPosition.X+=_sideLength;
0068         else if (_stagger==1)
0069           cellPosition.X+=(layer%3)*_sideLength;
0070         else if (_stagger==2){
0071           switch (layer%4){
0072           case 0:
0073             cellPosition.X-=0.75*_sideLength;
0074             break;
0075           case 1:
0076             cellPosition.Y+=std::sqrt(3)/4*_sideLength;
0077             break;
0078           case 2:
0079             cellPosition.Y-=std::sqrt(3)/4*_sideLength;
0080             break;
0081           case 3:
0082             cellPosition.X+=0.75*_sideLength;
0083             break;
0084           }
0085         }
0086         return cellPosition;
0087     }
0088 
0089     inline double positive_modulo(double i, double n) {
0090       return std::fmod(std::fmod(i,n) + n,n);
0091     }
0092 
0093     
0094     /// determine the cell ID based on the position
0095     CellID HexGrid::cellID(const Vector3D& localPosition, const Vector3D& /* globalPosition */, const VolumeID& vID) const {
0096         CellID cID = vID ;
0097         int layer=0;
0098         if (_stagger) layer= _decoder->get(cID,_staggerKeyword);
0099 
0100         double x=localPosition.X-_offsetX;
0101         double y=localPosition.Y-_offsetY;
0102         if (_stagger==0)
0103           x-=_sideLength;
0104         else if (_stagger==1)
0105           x-=(layer%3)*_sideLength;
0106         else if (_stagger==2){
0107           switch (layer%4){
0108           case 0:
0109             x+=0.75*_sideLength;
0110             break;
0111           case 1:
0112             y-=std::sqrt(3)/4*_sideLength;
0113             break;
0114           case 2:
0115             y+=std::sqrt(3)/4*_sideLength;
0116             break;
0117           case 3:
0118             x-=0.75*_sideLength;
0119             break;
0120           }
0121         }
0122         
0123         double a=positive_modulo(y/(std::sqrt(3)*_sideLength),1);
0124         double b=positive_modulo(x/(3*_sideLength),1);
0125         int ix = std::floor(x/(3*_sideLength/2.))+                
0126           (b<0.5)*(-std::abs(a-.5)<(b-.5)*3)+(b>0.5)*(std::abs(a-.5)-.5<(b-1)*3);
0127         int iy=std::floor(y/(std::sqrt(3)*_sideLength/2.));
0128         iy-=(ix+iy)&1;
0129         
0130         _decoder->set( cID,_xId, ix );
0131         _decoder->set( cID,_yId, iy );
0132         return cID ;
0133     }
0134 
0135     std::vector<double> HexGrid::cellDimensions(const CellID&) const {
0136       return {2*_sideLength, std::sqrt(3)*_sideLength};
0137     }
0138 
0139   } /* namespace DDSegmentation */
0140 } /* namespace dd4hep */