Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:45

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 "ActsExamples/GenericDetector/BuildGenericDetector.hpp"
0010 
0011 #include <cmath>
0012 #include <numbers>
0013 
0014 /// helper method for cylinder
0015 std::vector<Acts::Vector3> ActsExamples::Generic::modulePositionsCylinder(
0016     double radius, double zStagger, double moduleHalfLength, double lOverlap,
0017     const std::pair<int, int>& binningSchema) {
0018   int nPhiBins = binningSchema.first;
0019   int nZbins = binningSchema.second;
0020   // prepare the return value
0021   std::vector<Acts::Vector3> mPositions;
0022   mPositions.reserve(nPhiBins * nZbins);
0023   // prep work
0024   double phiStep = 2 * std::numbers::pi / nPhiBins;
0025   double minPhi = -std::numbers::pi + 0.5 * phiStep;
0026   double zStart = -0.5 * (nZbins - 1) * (2 * moduleHalfLength - lOverlap);
0027   double zStep = 2 * std::abs(zStart) / (nZbins - 1);
0028   // loop over the bins
0029   for (std::size_t zBin = 0; zBin < static_cast<std::size_t>(nZbins); ++zBin) {
0030     // prepare z and r
0031     double moduleZ = zStart + zBin * zStep;
0032     double moduleR =
0033         (zBin % 2) != 0u ? radius - 0.5 * zStagger : radius + 0.5 * zStagger;
0034     for (std::size_t phiBin = 0; phiBin < static_cast<std::size_t>(nPhiBins);
0035          ++phiBin) {
0036       // calculate the current phi value
0037       double modulePhi = minPhi + phiBin * phiStep;
0038       mPositions.push_back(Acts::Vector3(moduleR * cos(modulePhi),
0039                                          moduleR * sin(modulePhi), moduleZ));
0040     }
0041   }
0042   return mPositions;
0043 }
0044 
0045 /// helper method for disc
0046 std::vector<std::vector<Acts::Vector3>>
0047 ActsExamples::Generic::modulePositionsDisc(
0048     double z, double ringStagger, std::vector<double> phiStagger,
0049     std::vector<double> phiSubStagger, double innerRadius, double outerRadius,
0050     const std::vector<std::size_t>& discBinning,
0051     const std::vector<double>& moduleHalfLength) {
0052   // calculate the radii
0053   std::vector<double> radii;
0054   // the radial span of the disc
0055   double deltaR = outerRadius - innerRadius;
0056   // quick exits
0057   if (discBinning.size() == 1) {
0058     radii.push_back(0.5 * (innerRadius + outerRadius));
0059   } else {
0060     double totalLength = 0;
0061     // sum up the total length
0062     for (auto& mhlength : moduleHalfLength) {
0063       totalLength += 2 * mhlength;
0064     }
0065     // now calculate the overlap (equal pay)
0066     double rOverlap = (totalLength - deltaR) / (moduleHalfLength.size() - 1);
0067     // and now fill the radii and gaps
0068     double lastR = innerRadius;
0069     double lastHl = 0.;
0070     double lastOl = 0.;
0071     // now calculate
0072     for (auto& mhlength : moduleHalfLength) {
0073       // calculate the radius
0074       radii.push_back(lastR + lastHl - lastOl + mhlength);
0075       lastR = radii[radii.size() - 1];
0076       lastOl = rOverlap;
0077       lastHl = mhlength;
0078     }
0079   }
0080   // now prepare the return method
0081   std::vector<std::vector<Acts::Vector3>> mPositions;
0082   for (std::size_t ir = 0; ir < radii.size(); ++ir) {
0083     // generate the z value
0084     // convention inner ring is closer to origin : makes sense
0085     double rz = radii.size() == 1 ? z
0086                                   : ((ir % 2) != 0u ? z + 0.5 * ringStagger
0087                                                     : z - 0.5 * ringStagger);
0088     // fill the ring positions
0089     double psStagger = phiSubStagger.empty() ? 0. : phiSubStagger[ir];
0090     mPositions.push_back(modulePositionsRing(rz, radii[ir], phiStagger[ir],
0091                                              psStagger, discBinning[ir]));
0092   }
0093   return mPositions;
0094 }
0095 
0096 /// Helper method for positioning
0097 std::vector<Acts::Vector3> ActsExamples::Generic::modulePositionsRing(
0098     double z, double radius, double phiStagger, double phiSubStagger,
0099     int nPhiBins) {
0100   // create and fill the positions
0101   std::vector<Acts::Vector3> rPositions;
0102   rPositions.reserve(nPhiBins);
0103   // prep work
0104   double phiStep = 2 * std::numbers::pi / nPhiBins;
0105   double minPhi = -std::numbers::pi + 0.5 * phiStep;
0106   // phi loop
0107   for (std::size_t iphi = 0; iphi < static_cast<std::size_t>(nPhiBins);
0108        ++iphi) {
0109     // if we have a phi sub stagger presents
0110     double rzs = 0.;
0111     // phi stagger affects 0 vs 1, 2 vs 3 ... etc
0112     // -> only works if it is a %4
0113     // phi sub stagger affects 2 vs 4, 1 vs 3 etc.
0114     if (phiSubStagger != 0. && ((nPhiBins % 4) == 0)) {
0115       // switch sides
0116       if ((iphi % 4) == 0u) {
0117         rzs = phiSubStagger;
0118       } else if (((iphi + 1) % 4) == 0u) {
0119         rzs = -phiSubStagger;
0120       }
0121     }
0122     // the module phi
0123     double phi = minPhi + iphi * phiStep;
0124     // main z position depending on phi bin
0125     double rz = (iphi % 2) != 0u ? z - 0.5 * phiStagger : z + 0.5 * phiStagger;
0126     rPositions.push_back(
0127         Acts::Vector3(radius * cos(phi), radius * sin(phi), rz + rzs));
0128   }
0129   return rPositions;
0130 }