File indexing completed on 2025-01-18 09:11:26
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::abs(maxAxis1 - minAxis1) / (nBinsAxis1 - 1);
0036 double stepAxis2 = std::abs(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::abs(maxAxis1 - minAxis1) / std::max(nBinsAxis1 - 1, std::size_t{1});
0068 double stepAxis2 =
0069 std::abs(maxAxis2 - minAxis2) / std::max(nBinsAxis2 - 1, std::size_t{1});
0070 double stepAxis3 =
0071 std::abs(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::AxisDirection& type) {
0088 std::function<double(Acts::Vector3)> transfoGlobalToLocal;
0089
0090 switch (type) {
0091 case Acts::AxisDirection::AxisX:
0092 transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
0093 return (pos.x());
0094 };
0095 break;
0096
0097 case Acts::AxisDirection::AxisY:
0098 transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
0099 return (pos.y());
0100 };
0101 break;
0102
0103 case Acts::AxisDirection::AxisR:
0104 transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
0105 return (Acts::VectorHelpers::perp(pos));
0106 };
0107 break;
0108
0109 case Acts::AxisDirection::AxisPhi:
0110 transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
0111 return (Acts::VectorHelpers::phi(pos));
0112 };
0113 break;
0114
0115 case Acts::AxisDirection::AxisZ:
0116 transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
0117 return (pos.z());
0118 };
0119 break;
0120
0121
0122
0123
0124
0125 default:
0126 throw std::invalid_argument("Incorrect bin, should be x,y,z,r,phi");
0127 }
0128 return transfoGlobalToLocal;
0129 }
0130
0131 Acts::Grid2D Acts::createGrid2D(
0132 const Acts::BinUtility& bins,
0133 std::function<Acts::Vector2(Acts::Vector3)>& transfoGlobalToLocal) {
0134 auto bu = bins.binningData();
0135
0136 bool isCartesian = false;
0137 bool isCylindrical = false;
0138
0139 for (std::size_t b = 0; b < bu.size(); b++) {
0140 if (bu[b].binvalue == Acts::AxisDirection::AxisX ||
0141 bu[b].binvalue == Acts::AxisDirection::AxisY) {
0142 isCartesian = true;
0143 }
0144 if (bu[b].binvalue == Acts::AxisDirection::AxisR ||
0145 bu[b].binvalue == Acts::AxisDirection::AxisPhi) {
0146 isCylindrical = true;
0147 }
0148 }
0149 if (!(isCartesian || isCylindrical) || (isCylindrical && isCartesian)) {
0150 throw std::invalid_argument("Incorrect bin, should be x,y,z or r,phi,z");
0151 }
0152
0153
0154 MaterialGridAxisData gridAxis1{bu[0].min, bu[0].max, bu[0].bins()};
0155 MaterialGridAxisData gridAxis2{bu[1].min, bu[1].max, bu[1].bins()};
0156
0157 std::function<double(Acts::Vector3)> coord1 =
0158 globalToLocalFromBin(bu[0].binvalue);
0159 std::function<double(Acts::Vector3)> coord2 =
0160 globalToLocalFromBin(bu[1].binvalue);
0161 Transform3 transfo = bins.transform().inverse();
0162 transfoGlobalToLocal = [coord1, coord2,
0163 transfo](Acts::Vector3 pos) -> Acts::Vector2 {
0164 pos = transfo * pos;
0165 return {coord1(pos), coord2(pos)};
0166 };
0167 return Acts::createGrid(gridAxis1, gridAxis2);
0168 }
0169
0170 Acts::Grid3D Acts::createGrid3D(
0171 const Acts::BinUtility& bins,
0172 std::function<Acts::Vector3(Acts::Vector3)>& transfoGlobalToLocal) {
0173 auto bu = bins.binningData();
0174
0175
0176 bool isCartesian = false;
0177 bool isCylindrical = false;
0178
0179 for (std::size_t b = 0; b < bu.size(); b++) {
0180 if (bu[b].binvalue == Acts::AxisDirection::AxisX ||
0181 bu[b].binvalue == Acts::AxisDirection::AxisY) {
0182 isCartesian = true;
0183 }
0184 if (bu[b].binvalue == Acts::AxisDirection::AxisR ||
0185 bu[b].binvalue == Acts::AxisDirection::AxisPhi) {
0186 isCylindrical = true;
0187 }
0188 }
0189 if (!(isCartesian || isCylindrical) || (isCylindrical && isCartesian)) {
0190 throw std::invalid_argument("Incorrect bin, should be x,y,z or r,phi,z");
0191 }
0192
0193 MaterialGridAxisData gridAxis1{bu[0].min, bu[0].max, bu[0].bins()};
0194
0195 MaterialGridAxisData gridAxis2{bu[1].min, bu[1].max, bu[1].bins()};
0196
0197 MaterialGridAxisData gridAxis3{bu[2].min, bu[2].max, bu[2].bins()};
0198
0199 std::function<double(Acts::Vector3)> coord1 =
0200 globalToLocalFromBin(bu[0].binvalue);
0201 std::function<double(Acts::Vector3)> coord2 =
0202 globalToLocalFromBin(bu[1].binvalue);
0203 std::function<double(Acts::Vector3)> coord3 =
0204 globalToLocalFromBin(bu[2].binvalue);
0205 Transform3 transfo = bins.transform().inverse();
0206
0207 transfoGlobalToLocal = [coord1, coord2, coord3,
0208 transfo](Acts::Vector3 pos) -> Acts::Vector3 {
0209 pos = transfo * pos;
0210 return {coord1(pos), coord2(pos), coord3(pos)};
0211 };
0212 return Acts::createGrid(gridAxis1, gridAxis2, gridAxis3);
0213 }
0214
0215 Acts::MaterialGrid2D Acts::mapMaterialPoints(Acts::Grid2D& grid) {
0216
0217
0218 Acts::Grid2D::point_t min = grid.minPosition();
0219 Acts::Grid2D::point_t max = grid.maxPosition();
0220 Acts::Grid2D::index_t nBins = grid.numLocalBins();
0221
0222 Acts::EAxis axis1(min[0], max[0], nBins[0]);
0223 Acts::EAxis axis2(min[1], max[1], nBins[1]);
0224
0225
0226 Acts::MaterialGrid2D mGrid(std::make_tuple(axis1, axis2));
0227 for (std::size_t index = 0; index < grid.size(); index++) {
0228 mGrid.at(index) = grid.at(index).average().parameters();
0229 }
0230
0231 return mGrid;
0232 }
0233
0234 Acts::MaterialGrid3D Acts::mapMaterialPoints(Acts::Grid3D& grid) {
0235
0236
0237 Acts::Grid3D::point_t min = grid.minPosition();
0238 Acts::Grid3D::point_t max = grid.maxPosition();
0239 Acts::Grid3D::index_t nBins = grid.numLocalBins();
0240
0241 Acts::EAxis axis1(min[0], max[0], nBins[0]);
0242 Acts::EAxis axis2(min[1], max[1], nBins[1]);
0243 Acts::EAxis axis3(min[2], max[2], nBins[2]);
0244
0245
0246 Acts::MaterialGrid3D mGrid(std::make_tuple(axis1, axis2, axis3));
0247 for (std::size_t index = 0; index < grid.size(); index++) {
0248 mGrid.at(index) = grid.at(index).average().parameters();
0249 }
0250 return mGrid;
0251 }