Back to home page

EIC code displayed by LXR

 
 

    


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

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 "Acts/Detector/ProtoDetector.hpp"
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 
0013 #include <cstddef>
0014 #include <sstream>
0015 #include <stdexcept>
0016 
0017 void Acts::ProtoVolume::extendUp(Acts::ProtoVolume& ptVolume) {
0018   ptVolume.extent.extend(extent);
0019   if (container.has_value()) {
0020     for (auto& cv : container.value().constituentVolumes) {
0021       ptVolume.extent.extend(cv.extent);
0022       cv.extendUp(ptVolume);
0023     }
0024   }
0025 }
0026 
0027 void Acts::ProtoVolume::propagateMinDown(AxisDirection aDir) {
0028   if (container.has_value()) {
0029     for (auto& cv : container.value().constituentVolumes) {
0030       cv.extent.set(aDir, extent.min(aDir), cv.extent.max(aDir));
0031       cv.propagateMinDown(aDir);
0032     }
0033   }
0034 }
0035 
0036 void Acts::ProtoVolume::propagateMaxDown(AxisDirection aDir) {
0037   if (container.has_value()) {
0038     for (auto& cv : container.value().constituentVolumes) {
0039       cv.extent.set(aDir, cv.extent.min(aDir), extent.max(aDir));
0040       cv.propagateMaxDown(aDir);
0041     }
0042   }
0043 }
0044 
0045 void Acts::ProtoVolume::constrainDown(const Acts::ProtoVolume& ptVolume) {
0046   extent.addConstrain(ptVolume.extent);
0047   if (container.has_value()) {
0048     for (auto& cv : container.value().constituentVolumes) {
0049       cv.extent.addConstrain(extent);
0050     }
0051   }
0052 }
0053 
0054 void Acts::ProtoVolume::harmonize(bool legacy) {
0055   std::vector<AxisDirection> otherConstrains;
0056 
0057   // Deal with the constituents
0058   if (container.has_value() && !container.value().constituentVolumes.empty()) {
0059     auto& cts = container.value();
0060 
0061     if (cts.constituentBinning.empty()) {
0062       std::string errorMsg = std::string("ProtoVolume '") + name +
0063                              std::string("' with constituents, but no binning");
0064       throw std::runtime_error(errorMsg);
0065     }
0066 
0067     // Check if there are any layers present
0068     bool layersPresent = false;
0069     for (const auto& cv : cts.constituentVolumes) {
0070       if (cv.internal.has_value()) {
0071         layersPresent = true;
0072         break;
0073       }
0074     }
0075 
0076     // If layers are present, it can't be a container in the legacy style
0077     auto binValue = cts.constituentBinning[0].binvalue;
0078     // Set the first last
0079     auto& fVolume = cts.constituentVolumes.front();
0080     auto& lVolume = cts.constituentVolumes.back();
0081 
0082     std::vector<float> borders = {};
0083 
0084     // The volumes should be harmonized in all other constraining values
0085     for (auto oaDir : allAxisDirections()) {
0086       if (oaDir != binValue && extent.constrains(oaDir)) {
0087         otherConstrains.push_back(oaDir);
0088       }
0089     }
0090 
0091     // Legacy conversion - layers are kept untouched
0092     if (!layersPresent) {
0093       // Set the outer boundaries
0094       fVolume.extent.set(binValue, extent.min(binValue),
0095                          fVolume.extent.max(binValue));
0096       lVolume.extent.set(binValue, lVolume.extent.min(binValue),
0097                          extent.max(binValue));
0098       // Align the containers
0099       borders.push_back(static_cast<float>(fVolume.extent.min(binValue)));
0100       for (unsigned int iv = 1; iv < cts.constituentVolumes.size(); ++iv) {
0101         auto& lv = cts.constituentVolumes[iv - 1u];
0102         double zero = lv.extent.min(binValue);
0103         double low = lv.extent.max(binValue);
0104 
0105         auto& hv = cts.constituentVolumes[iv];
0106         double high = hv.extent.min(binValue);
0107         double mid = 0.5 * (low + high);
0108         double max = hv.extent.max(binValue);
0109         lv.extent.set(binValue, zero, mid);
0110         hv.extent.set(binValue, mid, max);
0111         borders.push_back(mid);
0112       }
0113       borders.push_back(cts.constituentVolumes.back().extent.max(binValue));
0114 
0115     } else if (layersPresent && !legacy) {
0116       // Count the gaps
0117       std::size_t gaps = 0;
0118       std::vector<float> boundaries = {};
0119       // New container vector
0120       std::vector<ProtoVolume> updatedConstituents;
0121       double containerMin = extent.min(binValue);
0122       if (fVolume.extent.min(binValue) > containerMin) {
0123         ProtoVolume gap;
0124         gap.name = name + "-gap-" + std::to_string(gaps++);
0125         gap.extent.set(binValue, containerMin, fVolume.extent.min(binValue));
0126         updatedConstituents.push_back(gap);
0127         borders.push_back(static_cast<float>(containerMin));
0128       }
0129       // Fill the gaps
0130       for (unsigned int iv = 1; iv < cts.constituentVolumes.size(); ++iv) {
0131         auto& lv = cts.constituentVolumes[iv - 1u];
0132         // This volume is one to save
0133         updatedConstituents.push_back(lv);
0134         borders.push_back(static_cast<float>(lv.extent.min(binValue)));
0135         // check if a gap to the next is needed
0136         double low = lv.extent.max(binValue);
0137         auto& hv = cts.constituentVolumes[iv];
0138         double high = hv.extent.min(binValue);
0139         if (high > low) {
0140           ProtoVolume gap;
0141           gap.name = name + "-gap-" + std::to_string(gaps++);
0142           gap.extent.set(binValue, low, high);
0143           updatedConstituents.push_back(gap);
0144           borders.push_back(static_cast<float>(low));
0145         }
0146       }
0147       double constituentsMax = lVolume.extent.max(binValue);
0148       updatedConstituents.push_back(lVolume);
0149       borders.push_back(static_cast<float>(constituentsMax));
0150       // Check the container min/max setting
0151       double containerMax = extent.max(binValue);
0152       if (constituentsMax < containerMax) {
0153         ProtoVolume gap;
0154         gap.name = name + "-gap-" + std::to_string(gaps++);
0155         gap.extent.set(binValue, constituentsMax, containerMax);
0156         updatedConstituents.push_back(gap);
0157         borders.push_back(static_cast<float>(containerMax));
0158       }
0159       cts.constituentVolumes = updatedConstituents;
0160     } else if (legacy && layersPresent) {
0161       borders = {0., 1.};
0162     }
0163     cts.constituentBinning = {
0164         BinningData(cts.constituentBinning[0].option, binValue, borders)};
0165 
0166     // Harmonize downwards
0167     for (auto& cv : cts.constituentVolumes) {
0168       cv.extent.extend(extent, otherConstrains);
0169       cv.harmonize(legacy);
0170     }
0171   }
0172 }
0173 
0174 std::string Acts::ProtoVolume::toString(const std::string& indent) const {
0175   std::string subIndent("  ");
0176   std::stringstream ss;
0177   ss << indent << "> volume: " << name << '\n';
0178   ss << indent << "  extent: ";
0179   ss << extent.toString(indent) << '\n';
0180   if (container.has_value()) {
0181     auto& cts = container.value();
0182     if (!cts.constituentVolumes.empty()) {
0183       ss << indent << "  container of " << cts.constituentVolumes.size()
0184          << " constituents. " << '\n';
0185       ss << indent << "  constituent binning:" << '\n';
0186       for (const auto& cb : cts.constituentBinning) {
0187         ss << cb.toString(indent) << '\n';
0188       }
0189       ss << indent << "  constituents are:" << '\n';
0190       for (const auto& cv : cts.constituentVolumes) {
0191         ss << cv.toString(indent + subIndent) << '\n';
0192       }
0193     }
0194   }
0195   return ss.str();
0196 }
0197 
0198 std::string Acts::ProtoDetector::toString(const std::string& indent) const {
0199   std::string subIndent("  ");
0200   std::stringstream ss;
0201   ss << indent << "> detector: " << name << '\n';
0202   ss << worldVolume.toString(indent + subIndent) << '\n';
0203   return ss.str();
0204 }