25 const std::shared_ptr<const PlanarBounds>& mBounds,
size_t numCellsX,
27 : m_activeBounds(mBounds), m_binUtility(nullptr) {
28 auto mutableBinUtility = std::make_shared<BinUtility>(
29 numCellsX, -mBounds->boundingBox().halfLengthX(),
31 (*mutableBinUtility) +=
32 BinUtility(numCellsY, -mBounds->boundingBox().halfLengthY(),
38 std::shared_ptr<const BinUtility> bUtility,
39 std::shared_ptr<const PlanarBounds> mBounds)
40 : m_activeBounds(std::
move(mBounds)), m_binUtility(std::
move(bUtility)) {
52 int readoutDirection,
double lorentzAngle)
const {
54 double lorentzAngleTan = tan(lorentzAngle);
55 double lorentzPlaneShiftX = halfThickness * lorentzAngleTan;
67 auto readoutPlaneTransform = Transform3::Identity();
68 auto counterPlaneTransform = Transform3::Identity();
71 std::shared_ptr<const PlanarBounds> readoutPlaneBounds =
moduleBounds;
72 std::shared_ptr<const PlanarBounds> counterPlaneBounds(
nullptr);
74 readoutPlaneTransform.translation() =
75 Vector3(0., 0., readoutDirection * halfThickness);
77 if (lorentzAngle == 0.) {
79 counterPlaneTransform.translation() =
80 Vector3(0., 0., -readoutDirection * halfThickness);
83 double lorentzReducedHalfX =
84 m_activeBounds->boundingBox().halfLengthX() - fabs(lorentzPlaneShiftX);
85 std::shared_ptr<const PlanarBounds> lorentzReducedBounds(
87 m_activeBounds->boundingBox().halfLengthY()));
88 counterPlaneBounds = lorentzReducedBounds;
91 double counterPlaneShift = -readoutDirection * lorentzPlaneShiftX;
92 counterPlaneTransform.translation() =
93 Vector3(counterPlaneShift, 0., -readoutDirection * halfThickness);
96 boundarySurfaces.push_back(Surface::makeShared<PlaneSurface>(
97 readoutPlaneTransform, readoutPlaneBounds));
98 boundarySurfaces.push_back(Surface::makeShared<PlaneSurface>(
99 counterPlaneTransform, counterPlaneBounds));
105 2. * m_activeBounds->boundingBox().halfLengthX() / m_binUtility->bins(0);
110 m_activeBounds->boundingBox().halfLengthY(), halfThickness));
112 double lorentzPlaneHalfX = std::abs(halfThickness / cos(lorentzAngle));
114 std::shared_ptr<const PlanarBounds> lorentzPlaneBounds =
117 : std::shared_ptr<const PlanarBounds>(
123 xBinRotationMatrix.col(0) = Vector3::UnitY();
124 xBinRotationMatrix.col(1) = Vector3::UnitZ();
125 xBinRotationMatrix.col(2) = Vector3::UnitX();
130 ? xBinRotationMatrix *
AngleAxis3(lorentzAngle, Vector3::UnitX())
131 : xBinRotationMatrix;
135 segmentationSurfacesX.reserve(m_binUtility->bins(0));
137 for (
size_t ibinx = 0; ibinx <= m_binUtility->bins(0); ++ibinx) {
140 -m_activeBounds->boundingBox().halfLengthX() + ibinx * pitchX;
142 if ((ibinx == 0
u) || ibinx == m_binUtility->bins(0)) {
146 bool boundaryStraight =
147 (lorentzAngle == 0. ||
148 ((ibinx == 0
u) && readoutDirection * lorentzAngle > 0.) ||
149 (ibinx == m_binUtility->bins(0) &&
150 readoutDirection * lorentzAngle < 0));
155 :
Vector3(cPosX - readoutDirection * lorentzPlaneShiftX, 0., 0.);
158 boundaryStraight ? xBinRotationMatrix : lorentzPlaneRotationMatrix;
160 auto boundaryXTransform =
163 std::shared_ptr<const PlanarBounds> boundaryXBounds =
164 boundaryStraight ? xBinBounds : lorentzPlaneBounds;
166 boundarySurfaces.push_back(Surface::makeShared<PlaneSurface>(
167 boundaryXTransform, boundaryXBounds));
172 cPosX - readoutDirection * lorentzPlaneShiftX, 0., 0.);
174 Translation3(lorentzPlanePosition) * lorentzPlaneRotationMatrix);
176 segmentationSurfacesX.push_back(Surface::makeShared<PlaneSurface>(
177 lorentzPlaneTransform, lorentzPlaneBounds));
185 yBinRotationMatrix.col(0) = Vector3::UnitX();
186 yBinRotationMatrix.col(1) = Vector3::UnitZ();
187 yBinRotationMatrix.col(2) =
Vector3(0., -1., 0.);
190 2. * m_activeBounds->boundingBox().halfLengthY() / m_binUtility->bins(1);
193 m_activeBounds->boundingBox().halfLengthX(), halfThickness));
196 segmentationSurfacesY.reserve(m_binUtility->bins(1));
197 for (
size_t ibiny = 0; ibiny <= m_binUtility->bins(1); ++ibiny) {
200 -m_activeBounds->boundingBox().halfLengthY() + ibiny * pitchY;
201 Vector3 binSurfaceCenter(0., binPosY, 0.);
206 if (ibiny == 0 || ibiny == m_binUtility->bins(1)) {
207 boundarySurfaces.push_back(
208 Surface::makeShared<PlaneSurface>(binTransform, yBinBounds));
210 segmentationSurfacesY.push_back(
211 Surface::makeShared<PlaneSurface>(binTransform, yBinBounds));
218 double bX = m_binUtility->bins(0) > 1
219 ? m_binUtility->binningData()[0].center(dCell.
channel0)
221 double bY = m_binUtility->bins(1) > 1
222 ? m_binUtility->binningData()[1].center(dCell.
channel1)
230 const Vector3& startStep,
const Vector3& endStep,
double halfThickness,
231 int readoutDirection,
double lorentzAngle)
const {
232 Vector3 stepCenter = 0.5 * (startStep + endStep);
235 double driftInZ = halfThickness - readoutDirection * stepCenter.z();
237 double driftLength = driftInZ / cos(lorentzAngle);
239 double lorentzDeltaX = readoutDirection * driftInZ * tan(lorentzAngle);
241 Vector2 stepCenterProjected(stepCenter.x() + lorentzDeltaX, stepCenter.y());
244 Vector2 cellCenter = cellPosition(dCell);
247 startStep, endStep, stepCenterProjected, cellCenter);