Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:09:52

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