File indexing completed on 2025-08-05 08:09:39
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Material/MaterialGridHelper.hpp"
0010
0011 #include "Acts/Utilities/BinningData.hpp"
0012
0013 #include <algorithm>
0014 #include <cmath>
0015 #include <memory>
0016 #include <stdexcept>
0017 #include <tuple>
0018 #include <utility>
0019 #include <vector>
0020
0021 Acts::Grid2D Acts::createGrid(Acts::MaterialGridAxisData gridAxis1,
0022 Acts::MaterialGridAxisData gridAxis2) {
0023
0024 std::size_t nBinsAxis1 = std::get<2>(gridAxis1);
0025 std::size_t nBinsAxis2 = std::get<2>(gridAxis2);
0026
0027
0028 double minAxis1 = std::get<0>(gridAxis1);
0029 double minAxis2 = std::get<0>(gridAxis2);
0030 double maxAxis1 = std::get<1>(gridAxis1);
0031 double maxAxis2 = std::get<1>(gridAxis2);
0032
0033
0034
0035 double stepAxis1 = std::fabs(maxAxis1 - minAxis1) / (nBinsAxis1 - 1);
0036 double stepAxis2 = std::fabs(maxAxis2 - minAxis2) / (nBinsAxis2 - 1);
0037 maxAxis1 += stepAxis1;
0038 maxAxis2 += stepAxis2;
0039
0040
0041 Acts::EAxis axis1(minAxis1, maxAxis1, nBinsAxis1);
0042 Acts::EAxis axis2(minAxis2, maxAxis2, nBinsAxis2);
0043
0044
0045 return Acts::Grid2D(std::make_tuple(std::move(axis1), std::move(axis2)));
0046 }
0047
0048 Acts::Grid3D Acts::createGrid(Acts::MaterialGridAxisData gridAxis1,
0049 Acts::MaterialGridAxisData gridAxis2,
0050 Acts::MaterialGridAxisData gridAxis3) {
0051
0052 std::size_t nBinsAxis1 = std::get<2>(gridAxis1);
0053 std::size_t nBinsAxis2 = std::get<2>(gridAxis2);
0054 std::size_t nBinsAxis3 = std::get<2>(gridAxis3);
0055
0056
0057 double minAxis1 = std::get<0>(gridAxis1);
0058 double minAxis2 = std::get<0>(gridAxis2);
0059 double minAxis3 = std::get<0>(gridAxis3);
0060 double maxAxis1 = std::get<1>(gridAxis1);
0061 double maxAxis2 = std::get<1>(gridAxis2);
0062 double maxAxis3 = std::get<1>(gridAxis3);
0063
0064
0065
0066 double stepAxis1 =
0067 std::fabs(maxAxis1 - minAxis1) / std::max(nBinsAxis1 - 1, std::size_t(1));
0068 double stepAxis2 =
0069 std::fabs(maxAxis2 - minAxis2) / std::max(nBinsAxis2 - 1, std::size_t(1));
0070 double stepAxis3 =
0071 std::fabs(maxAxis3 - minAxis3) / std::max(nBinsAxis3 - 1, std::size_t(1));
0072 maxAxis1 += stepAxis1;
0073 maxAxis2 += stepAxis2;
0074 maxAxis3 += stepAxis3;
0075
0076
0077 Acts::EAxis axis1(minAxis1, maxAxis1, nBinsAxis1);
0078 Acts::EAxis axis2(minAxis2, maxAxis2, nBinsAxis2);
0079 Acts::EAxis axis3(minAxis3, maxAxis3, nBinsAxis3);
0080
0081
0082 return Acts::Grid3D(
0083 std::make_tuple(std::move(axis1), std::move(axis2), std::move(axis3)));
0084 }
0085
0086 std::function<double(Acts::Vector3)> Acts::globalToLocalFromBin(
0087 Acts::BinningValue& type) {
0088 std::function<double(Acts::Vector3)> transfoGlobalToLocal;
0089
0090 switch (type) {
0091 case Acts::binX:
0092 transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
0093 return (pos.x());
0094 };
0095 break;
0096
0097 case Acts::binY:
0098 transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
0099 return (pos.y());
0100 };
0101 break;
0102
0103 case Acts::binR:
0104 transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
0105 return (Acts::VectorHelpers::perp(pos));
0106 };
0107 break;
0108
0109 case Acts::binPhi:
0110 transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
0111 return (Acts::VectorHelpers::phi(pos));
0112 };
0113 break;
0114
0115 case Acts::binZ:
0116 transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
0117 return (pos.z());
0118 };
0119 break;
0120
0121
0122
0123
0124
0125
0126 default:
0127 throw std::invalid_argument("Incorrect bin, should be x,y,z,r,phi");
0128 }
0129 return transfoGlobalToLocal;
0130 }
0131
0132 Acts::Grid2D Acts::createGrid2D(
0133 const Acts::BinUtility& bins,
0134 std::function<Acts::Vector2(Acts::Vector3)>& transfoGlobalToLocal) {
0135 auto bu = bins.binningData();
0136
0137 bool isCartesian = false;
0138 bool isCylindrical = false;
0139
0140 for (std::size_t b = 0; b < bu.size(); b++) {
0141 if (bu[b].binvalue == Acts::binX || bu[b].binvalue == Acts::binY) {
0142 isCartesian = true;
0143 }
0144 if (bu[b].binvalue == Acts::binR || bu[b].binvalue == Acts::binPhi) {
0145 isCylindrical = true;
0146 }
0147 }
0148 if (!(isCartesian || isCylindrical) || (isCylindrical && isCartesian)) {
0149 throw std::invalid_argument("Incorrect bin, should be x,y,z or r,phi,z");
0150 }
0151
0152
0153 MaterialGridAxisData gridAxis1{bu[0].min, bu[0].max, bu[0].bins()};
0154 MaterialGridAxisData gridAxis2{bu[1].min, bu[1].max, bu[1].bins()};
0155
0156 std::function<double(Acts::Vector3)> coord1 =
0157 globalToLocalFromBin(bu[0].binvalue);
0158 std::function<double(Acts::Vector3)> coord2 =
0159 globalToLocalFromBin(bu[1].binvalue);
0160 Transform3 transfo = bins.transform().inverse();
0161 transfoGlobalToLocal = [coord1, coord2,
0162 transfo](Acts::Vector3 pos) -> Acts::Vector2 {
0163 pos = transfo * pos;
0164 return {coord1(pos), coord2(pos)};
0165 };
0166 return Acts::createGrid(gridAxis1, gridAxis2);
0167 }
0168
0169 Acts::Grid3D Acts::createGrid3D(
0170 const Acts::BinUtility& bins,
0171 std::function<Acts::Vector3(Acts::Vector3)>& transfoGlobalToLocal) {
0172 auto bu = bins.binningData();
0173
0174
0175 bool isCartesian = false;
0176 bool isCylindrical = false;
0177
0178 for (std::size_t b = 0; b < bu.size(); b++) {
0179 if (bu[b].binvalue == Acts::binX || bu[b].binvalue == Acts::binY) {
0180 isCartesian = true;
0181 }
0182 if (bu[b].binvalue == Acts::binR || bu[b].binvalue == Acts::binPhi) {
0183 isCylindrical = true;
0184 }
0185 }
0186 if (!(isCartesian || isCylindrical) || (isCylindrical && isCartesian)) {
0187 throw std::invalid_argument("Incorrect bin, should be x,y,z or r,phi,z");
0188 }
0189
0190 MaterialGridAxisData gridAxis1{bu[0].min, bu[0].max, bu[0].bins()};
0191
0192 MaterialGridAxisData gridAxis2{bu[1].min, bu[1].max, bu[1].bins()};
0193
0194 MaterialGridAxisData gridAxis3{bu[2].min, bu[2].max, bu[2].bins()};
0195
0196 std::function<double(Acts::Vector3)> coord1 =
0197 globalToLocalFromBin(bu[0].binvalue);
0198 std::function<double(Acts::Vector3)> coord2 =
0199 globalToLocalFromBin(bu[1].binvalue);
0200 std::function<double(Acts::Vector3)> coord3 =
0201 globalToLocalFromBin(bu[2].binvalue);
0202 Transform3 transfo = bins.transform().inverse();
0203
0204 transfoGlobalToLocal = [coord1, coord2, coord3,
0205 transfo](Acts::Vector3 pos) -> Acts::Vector3 {
0206 pos = transfo * pos;
0207 return {coord1(pos), coord2(pos), coord3(pos)};
0208 };
0209 return Acts::createGrid(gridAxis1, gridAxis2, gridAxis3);
0210 }
0211
0212 Acts::MaterialGrid2D Acts::mapMaterialPoints(Acts::Grid2D& grid) {
0213
0214
0215 Acts::Grid2D::point_t min = grid.minPosition();
0216 Acts::Grid2D::point_t max = grid.maxPosition();
0217 Acts::Grid2D::index_t nBins = grid.numLocalBins();
0218
0219 Acts::EAxis axis1(min[0], max[0], nBins[0]);
0220 Acts::EAxis axis2(min[1], max[1], nBins[1]);
0221
0222
0223 Acts::MaterialGrid2D mGrid(std::make_tuple(axis1, axis2));
0224 for (std::size_t index = 0; index < grid.size(); index++) {
0225 mGrid.at(index) = grid.at(index).average().parameters();
0226 }
0227
0228 return mGrid;
0229 }
0230
0231 Acts::MaterialGrid3D Acts::mapMaterialPoints(Acts::Grid3D& grid) {
0232
0233
0234 Acts::Grid3D::point_t min = grid.minPosition();
0235 Acts::Grid3D::point_t max = grid.maxPosition();
0236 Acts::Grid3D::index_t nBins = grid.numLocalBins();
0237
0238 Acts::EAxis axis1(min[0], max[0], nBins[0]);
0239 Acts::EAxis axis2(min[1], max[1], nBins[1]);
0240 Acts::EAxis axis3(min[2], max[2], nBins[2]);
0241
0242
0243 Acts::MaterialGrid3D mGrid(std::make_tuple(axis1, axis2, axis3));
0244 for (std::size_t index = 0; index < grid.size(); index++) {
0245 mGrid.at(index) = grid.at(index).average().parameters();
0246 }
0247 return mGrid;
0248 }