33 void Setup(
const int N, std::vector<double> eps, std::vector<double> d,
34 const double V, std::vector<int> sigmaIndex = {});
36 void ElectricField(
const double x,
const double y,
const double z,
double &ex,
37 double &ey,
double &ez, Medium *&m,
int &status)
override;
38 void ElectricField(
const double x,
const double y,
const double z,
double &ex,
39 double &ey,
double &ez,
double &v, Medium *&m,
40 int &status)
override;
43 const std::string &label)
override;
55 void AddPixel(
double x,
double z,
double lx,
double lz,
56 const std::string &label,
bool fromAnode =
true);
58 void AddStrip(
double z,
double lz,
const std::string &label,
59 bool fromAnode =
true);
63 void AddPlane(
const std::string &label,
bool fromAnode =
true);
76 const double xsteps,
const double ymin,
77 const double ymax,
const double ysteps,
78 const double zmin,
const double zmax,
79 const double zsteps,
const std::string &label);
84 const double xsteps,
const double ymin,
85 const double ymax,
const double ysteps,
86 const double zmin,
const double zmax,
92 for (
auto &electrode : m_readout_p) {
93 if (electrode.label == label) {
94 if (electrode.grid.LoadWeightingField(label +
"map",
"xyz",
true)) {
97 <<
"::LoadWeightingPotentialGrid: Weighting potential set for "
99 electrode.m_usegrid =
true;
105 <<
"::LoadWeightingPotentialGrid: Could not find file for "
109 Medium *
GetMedium(
const double x,
const double y,
const double z)
override;
111 bool GetBoundingBox(
double &xmin,
double &ymin,
double &zmin,
double &xmax,
112 double &ymax,
double &zmax)
override;
115 bool getLayer(
const double y,
int &m,
double &epsM) {
119 for (
int i = 1; i < m_N; i++) {
125 if (mholer == -1)
return false;
128 epsM = m_epsHolder[m - 1];
138 m_getPotentialInPlate =
false;
142 double m_precision = 1.e-12;
143 static constexpr double m_Vw = 1.;
144 double m_eps0 = 8.85418782e-3;
148 bool m_getPotentialInPlate =
true;
154 double m_upperBoundIntegration = 30;
156 std::vector<double> m_eps;
157 std::vector<double> m_epsHolder;
158 std::vector<double> m_d;
159 std::vector<double> m_dHolder;
160 std::vector<double> m_z;
162 std::vector<int> m_sigmaIndex;
166 TF1 m_wpStripIntegral;
167 TF2 m_wpPixelIntegral;
169 std::vector<std::vector<std::vector<int>>> m_sigmaMatrix;
172 std::vector<std::vector<std::vector<int>>> m_thetaMatrix;
176 std::vector<std::vector<double>> m_cMatrix;
177 std::vector<std::vector<double>> m_vMatrix;
178 std::vector<std::vector<double>> m_gMatrix;
179 std::vector<std::vector<double>> m_wMatrix;
181 int m_currentLayer = 0;
182 double m_currentPosition = -1;
184 Medium *m_medium =
nullptr;
189 int ind = structureelectrode::NotSet;
192 bool formAnode =
true;
194 bool m_usegrid =
false;
198 enum fieldcomponent {
205 enum structureelectrode {
213 std::vector<std::string> m_readout;
214 std::vector<Electrode> m_readout_p;
218 double IntegratePromptPotential(
const Electrode &el,
const double x,
219 const double y,
const double z);
221 void CalculateDynamicalWeightingPotential(
const Electrode &el);
223 double FindWeightingPotentialInGrid(Electrode &el,
const double x,
224 const double y,
const double z);
227 double kroneckerDelta(
const int index) {
228 if (std::find(m_sigmaIndex.begin(), m_sigmaIndex.end(), index) !=
237 bool Nsigma(
int N, std::vector<std::vector<int>> &sigmaMatrix);
241 bool Ntheta(
int N, std::vector<std::vector<int>> &thetaMatrix,
242 std::vector<std::vector<int>> &sigmaMatrix);
245 void constructGeometryMatrices(
const int N);
249 void constructGeometryFunction(
const int N);
253 void setHIntegrand();
256 void setwpPixelIntegrand();
259 void setwpStripIntegrand();
262 double constWEFieldLayer(
const int indexLayer) {
264 for (
int i = 1; i <= m_N - 1; i++) {
265 invEz += (m_z[i] - m_z[i - 1]) / m_epsHolder[i - 1];
267 return 1 / (m_epsHolder[indexLayer - 1] * invEz);
271 double wpPlane(
const double z) {
274 if (!
getLayer(z, im, epsM))
return 0.;
275 double v = 1 - (
z - m_z[im - 1]) * constWEFieldLayer(im);
276 for (
int i = 1; i <= im - 1; i++) {
277 v -= (m_z[i] - m_z[i - 1]) * constWEFieldLayer(i);
284 double constEFieldLayer(
const int indexLayer) {
285 if (kroneckerDelta(indexLayer) == 0)
return 0.;
287 for (
int i = 1; i <= m_N - 1; i++) {
288 invEz += -(m_z[i] - m_z[i - 1]) * kroneckerDelta(i) / m_epsHolder[i - 1];
290 return m_V / (m_epsHolder[indexLayer - 1] * invEz);
294 bool decToBinary(
int n, std::vector<int> &binaryNum);
297 void LayerUpdate(
double &z,
const int im,
const double epsM) {
299 if (z == m_currentPosition) {
304 m_currentPosition =
z;
307 if (im != m_currentLayer) {
309 for (
int i = 0; i < im - 1; i++) m_eps[i] = m_epsHolder[i];
310 m_eps[im - 1] = epsM;
312 for (
int i = im + 1; i < m_N; i++) m_eps[i] = m_epsHolder[i - 1];
315 double diff1 = m_z[im] -
z;
316 double diff2 =
z - m_z[im - 1];
318 for (
int i = 0; i < im - 1; i++) m_d[i] = m_dHolder[i];
321 for (
int i = im + 1; i < m_N; i++) m_d[i] = m_dHolder[i - 1];
323 constructGeometryFunction(m_N);
326 void UpdatePeriodicity()
override;
327 void Reset()
override;
void SetWeightingPotentialGrids(const double xmin, const double xmax, const double xsteps, const double ymin, const double ymax, const double ysteps, const double zmin, const double zmax, const double zsteps)
void SetWeightingPotentialGrid(const double xmin, const double xmax, const double xsteps, const double ymin, const double ymax, const double ysteps, const double zmin, const double zmax, const double zsteps, const std::string &label)
virtual void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status)=0