Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MaterialGridHelper.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MaterialGridHelper.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
12 
13 #include <algorithm>
14 #include <cmath>
15 #include <memory>
16 #include <stdexcept>
17 #include <tuple>
18 #include <utility>
19 #include <vector>
20 
22  Acts::MaterialGridAxisData gridAxis2) {
23  // get the number of bins
24  size_t nBinsAxis1 = std::get<2>(gridAxis1);
25  size_t nBinsAxis2 = std::get<2>(gridAxis2);
26 
27  // get the minimum and maximum
28  double minAxis1 = std::get<0>(gridAxis1);
29  double minAxis2 = std::get<0>(gridAxis2);
30  double maxAxis1 = std::get<1>(gridAxis1);
31  double maxAxis2 = std::get<1>(gridAxis2);
32  // calculate maxima (add one last bin, because bin value always corresponds
33  // to
34  // left boundary)
35  double stepAxis1 = std::fabs(maxAxis1 - minAxis1) / (nBinsAxis1 - 1);
36  double stepAxis2 = std::fabs(maxAxis2 - minAxis2) / (nBinsAxis2 - 1);
37  maxAxis1 += stepAxis1;
38  maxAxis2 += stepAxis2;
39 
40  // Create the axis for the grid
41  Acts::EAxis axis1(minAxis1, maxAxis1, nBinsAxis1);
42  Acts::EAxis axis2(minAxis2, maxAxis2, nBinsAxis2);
43 
44  // The material mapping grid
45  return Acts::Grid2D(std::make_tuple(std::move(axis1), std::move(axis2)));
46 }
47 
50  Acts::MaterialGridAxisData gridAxis3) {
51  // get the number of bins
52  size_t nBinsAxis1 = std::get<2>(gridAxis1);
53  size_t nBinsAxis2 = std::get<2>(gridAxis2);
54  size_t nBinsAxis3 = std::get<2>(gridAxis3);
55 
56  // get the minimum and maximum
57  double minAxis1 = std::get<0>(gridAxis1);
58  double minAxis2 = std::get<0>(gridAxis2);
59  double minAxis3 = std::get<0>(gridAxis3);
60  double maxAxis1 = std::get<1>(gridAxis1);
61  double maxAxis2 = std::get<1>(gridAxis2);
62  double maxAxis3 = std::get<1>(gridAxis3);
63  // calculate maxima (add one last bin, because bin value always corresponds
64  // to
65  // left boundary)
66  double stepAxis1 =
67  std::fabs(maxAxis1 - minAxis1) / std::max(nBinsAxis1 - 1, size_t(1));
68  double stepAxis2 =
69  std::fabs(maxAxis2 - minAxis2) / std::max(nBinsAxis2 - 1, size_t(1));
70  double stepAxis3 =
71  std::fabs(maxAxis3 - minAxis3) / std::max(nBinsAxis3 - 1, size_t(1));
72  maxAxis1 += stepAxis1;
73  maxAxis2 += stepAxis2;
74  maxAxis3 += stepAxis3;
75 
76  // Create the axis for the grid
77  Acts::EAxis axis1(minAxis1, maxAxis1, nBinsAxis1);
78  Acts::EAxis axis2(minAxis2, maxAxis2, nBinsAxis2);
79  Acts::EAxis axis3(minAxis3, maxAxis3, nBinsAxis3);
80 
81  // The material mapping grid
82  return Acts::Grid3D(
83  std::make_tuple(std::move(axis1), std::move(axis2), std::move(axis3)));
84 }
85 
86 std::function<double(Acts::Vector3)> Acts::globalToLocalFromBin(
88  std::function<double(Acts::Vector3)> transfoGlobalToLocal;
89 
90  switch (type) {
91  case Acts::binX:
92  transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
93  return (pos.x());
94  };
95  break;
96 
97  case Acts::binY:
98  transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
99  return (pos.y());
100  };
101  break;
102 
103  case Acts::binR:
104  transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
105  return (Acts::VectorHelpers::perp(pos));
106  };
107  break;
108 
109  case Acts::binPhi:
110  transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
111  return (Acts::VectorHelpers::phi(pos));
112  };
113  break;
114 
115  case Acts::binZ:
116  transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double {
117  return (pos.z());
118  };
119  break;
120 
121  case Acts::binRPhi:
122  case Acts::binEta:
123  case Acts::binH:
124  case Acts::binMag:
125  case Acts::binValues:
126  throw std::invalid_argument("Incorrect bin, should be x,y,z,r,phi,z");
127  break;
128  }
129  return transfoGlobalToLocal;
130 }
131 
133  const Acts::BinUtility& bins,
134  std::function<Acts::Vector2(Acts::Vector3)>& transfoGlobalToLocal) {
135  auto bu = bins.binningData();
136 
137  bool isCartesian = false;
138  bool isCylindrical = false;
139 
140  for (size_t b = 0; b < bu.size(); b++) {
141  if (bu[b].binvalue == Acts::binX || bu[b].binvalue == Acts::binY) {
142  isCartesian = true;
143  }
144  if (bu[b].binvalue == Acts::binR || bu[b].binvalue == Acts::binPhi) {
145  isCylindrical = true;
146  }
147  }
148  if (!(isCartesian || isCylindrical) || (isCylindrical && isCartesian)) {
149  throw std::invalid_argument("Incorrect bin, should be x,y,z or r,phi,z");
150  }
151 
152  // First we need to create the 2 axis
153  MaterialGridAxisData gridAxis1{bu[0].min, bu[0].max, bu[0].bins()};
154  MaterialGridAxisData gridAxis2{bu[1].min, bu[1].max, bu[1].bins()};
155 
156  std::function<double(Acts::Vector3)> coord1 =
157  globalToLocalFromBin(bu[0].binvalue);
158  std::function<double(Acts::Vector3)> coord2 =
159  globalToLocalFromBin(bu[1].binvalue);
160  Transform3 transfo = bins.transform().inverse();
161  transfoGlobalToLocal = [coord1, coord2,
162  transfo](Acts::Vector3 pos) -> Acts::Vector2 {
163  pos = transfo * pos;
164  return {coord1(pos), coord2(pos)};
165  };
166  return Acts::createGrid(gridAxis1, gridAxis2);
167 }
168 
170  const Acts::BinUtility& bins,
171  std::function<Acts::Vector3(Acts::Vector3)>& transfoGlobalToLocal) {
172  auto bu = bins.binningData();
173  // First we need to create the 3 axis
174 
175  bool isCartesian = false;
176  bool isCylindrical = false;
177 
178  for (size_t b = 0; b < bu.size(); b++) {
179  if (bu[b].binvalue == Acts::binX || bu[b].binvalue == Acts::binY) {
180  isCartesian = true;
181  }
182  if (bu[b].binvalue == Acts::binR || bu[b].binvalue == Acts::binPhi) {
183  isCylindrical = true;
184  }
185  }
186  if (!(isCartesian || isCylindrical) || (isCylindrical && isCartesian)) {
187  throw std::invalid_argument("Incorrect bin, should be x,y,z or r,phi,z");
188  }
189 
190  MaterialGridAxisData gridAxis1{bu[0].min, bu[0].max, bu[0].bins()};
191 
192  MaterialGridAxisData gridAxis2{bu[1].min, bu[1].max, bu[1].bins()};
193 
194  MaterialGridAxisData gridAxis3{bu[2].min, bu[2].max, bu[2].bins()};
195 
196  std::function<double(Acts::Vector3)> coord1 =
197  globalToLocalFromBin(bu[0].binvalue);
198  std::function<double(Acts::Vector3)> coord2 =
199  globalToLocalFromBin(bu[1].binvalue);
200  std::function<double(Acts::Vector3)> coord3 =
201  globalToLocalFromBin(bu[2].binvalue);
202  Transform3 transfo = bins.transform().inverse();
203 
204  transfoGlobalToLocal = [coord1, coord2, coord3,
205  transfo](Acts::Vector3 pos) -> Acts::Vector3 {
206  pos = transfo * pos;
207  return {coord1(pos), coord2(pos), coord3(pos)};
208  };
209  return Acts::createGrid(gridAxis1, gridAxis2, gridAxis3);
210 }
211 
213  // Build material grid
214  // Re-build the axes
216  Acts::Grid2D::point_t max = grid.maxPosition();
217  Acts::Grid2D::index_t nBins = grid.numLocalBins();
218 
219  Acts::EAxis axis1(min[0], max[0], nBins[0]);
220  Acts::EAxis axis2(min[1], max[1], nBins[1]);
221 
222  // Fill the material Grid by averaging the material in the 2D grid
223  Acts::MaterialGrid2D mGrid(std::make_tuple(axis1, axis2));
224  for (size_t index = 0; index < grid.size(); index++) {
225  mGrid.at(index) = grid.at(index).average().parameters();
226  }
227 
228  return mGrid;
229 }
230 
232  // Build material grid
233  // Re-build the axes
235  Acts::Grid3D::point_t max = grid.maxPosition();
236  Acts::Grid3D::index_t nBins = grid.numLocalBins();
237 
238  Acts::EAxis axis1(min[0], max[0], nBins[0]);
239  Acts::EAxis axis2(min[1], max[1], nBins[1]);
240  Acts::EAxis axis3(min[2], max[2], nBins[2]);
241 
242  // Fill the material Grid by averaging the material in the 3D grid
243  Acts::MaterialGrid3D mGrid(std::make_tuple(axis1, axis2, axis3));
244  for (size_t index = 0; index < grid.size(); index++) {
245  mGrid.at(index) = grid.at(index).average().parameters();
246  }
247  return mGrid;
248 }