21 const std::shared_ptr<const PlanarBounds>& mBounds,
size_t numCellsX,
23 : m_activeBounds(mBounds), m_binUtility(nullptr) {
24 auto mutableBinUtility = std::make_shared<BinUtility>(
25 numCellsX, -mBounds->boundingBox().halfLengthX(),
27 (*mutableBinUtility) +=
28 BinUtility(numCellsY, -mBounds->boundingBox().halfLengthY(),
34 std::shared_ptr<const BinUtility> bUtility,
35 std::shared_ptr<const PlanarBounds> mBounds)
36 : m_activeBounds(std::move(mBounds)), m_binUtility(std::move(bUtility)) {
48 int readoutDirection,
double lorentzAngle)
const {
50 double lorentzAngleTan = tan(lorentzAngle);
51 double lorentzPlaneShiftX = halfThickness * lorentzAngleTan;
63 auto mutableReadoutPlaneTransform =
64 std::make_shared<Transform3D>(Transform3D::Identity());
65 auto mutableCounterPlaneTransform =
66 std::make_shared<Transform3D>(Transform3D::Identity());
69 std::shared_ptr<const PlanarBounds> readoutPlaneBounds =
moduleBounds;
70 std::shared_ptr<const PlanarBounds> counterPlaneBounds(
nullptr);
72 (*mutableReadoutPlaneTransform).translation() =
73 Vector3D(0., 0., readoutDirection * halfThickness);
75 if (lorentzAngle == 0.) {
77 (*mutableCounterPlaneTransform).translation() =
78 Vector3D(0., 0., -readoutDirection * halfThickness);
81 double lorentzReducedHalfX =
82 m_activeBounds->boundingBox().halfLengthX() - fabs(lorentzPlaneShiftX);
83 std::shared_ptr<const PlanarBounds> lorentzReducedBounds(
85 m_activeBounds->boundingBox().halfLengthY()));
86 counterPlaneBounds = lorentzReducedBounds;
89 double counterPlaneShift = -readoutDirection * lorentzPlaneShiftX;
90 (*mutableCounterPlaneTransform).translation() =
91 Vector3D(counterPlaneShift, 0., -readoutDirection * halfThickness);
94 auto readoutPlaneTransform =
96 auto counterPlaneTransform =
99 boundarySurfaces.push_back(Surface::makeShared<PlaneSurface>(
100 readoutPlaneTransform, readoutPlaneBounds));
101 boundarySurfaces.push_back(Surface::makeShared<PlaneSurface>(
102 counterPlaneTransform, counterPlaneBounds));
108 2. * m_activeBounds->boundingBox().halfLengthX() / m_binUtility->bins(0);
113 m_activeBounds->boundingBox().halfLengthY(), halfThickness));
115 double lorentzPlaneHalfX =
std::abs(halfThickness / cos(lorentzAngle));
117 std::shared_ptr<const PlanarBounds> lorentzPlaneBounds =
120 : std::shared_ptr<const PlanarBounds>(
126 xBinRotationMatrix.col(0) = Vector3D::UnitY();
127 xBinRotationMatrix.col(1) = Vector3D::UnitZ();
128 xBinRotationMatrix.col(2) = Vector3D::UnitX();
133 ? xBinRotationMatrix *
AngleAxis3D(lorentzAngle, Vector3D::UnitX())
134 : xBinRotationMatrix;
138 segmentationSurfacesX.reserve(m_binUtility->bins(0));
140 for (
size_t ibinx = 0; ibinx <= m_binUtility->bins(0); ++ibinx) {
143 -m_activeBounds->boundingBox().halfLengthX() + ibinx * pitchX;
145 if ((ibinx == 0
u) || ibinx == m_binUtility->bins(0)) {
150 bool boundaryStraight =
151 (lorentzAngle == 0. ||
152 ((ibinx == 0
u) && readoutDirection * lorentzAngle > 0.) ||
153 (ibinx == m_binUtility->bins(0) &&
154 readoutDirection * lorentzAngle < 0));
159 :
Vector3D(cPosX - readoutDirection * lorentzPlaneShiftX, 0., 0.);
162 boundaryStraight ? xBinRotationMatrix : lorentzPlaneRotationMatrix;
164 auto boundaryXTransform = std::make_shared<const Transform3D>(
167 std::shared_ptr<const PlanarBounds> boundaryXBounds =
168 boundaryStraight ? xBinBounds : lorentzPlaneBounds;
170 boundarySurfaces.push_back(Surface::makeShared<PlaneSurface>(
171 boundaryXTransform, boundaryXBounds));
176 cPosX - readoutDirection * lorentzPlaneShiftX, 0., 0.);
177 auto lorentzPlaneTransform = std::make_shared<const Transform3D>(
178 Translation3D(lorentzPlanePosition) * lorentzPlaneRotationMatrix);
180 segmentationSurfacesX.push_back(Surface::makeShared<PlaneSurface>(
181 lorentzPlaneTransform, lorentzPlaneBounds));
189 yBinRotationMatrix.col(0) = Vector3D::UnitX();
190 yBinRotationMatrix.col(1) = Vector3D::UnitZ();
191 yBinRotationMatrix.col(2) =
Vector3D(0., -1., 0.);
194 2. * m_activeBounds->boundingBox().halfLengthY() / m_binUtility->bins(1);
197 m_activeBounds->boundingBox().halfLengthX(), halfThickness));
200 segmentationSurfacesY.reserve(m_binUtility->bins(1));
201 for (
size_t ibiny = 0; ibiny <= m_binUtility->bins(1); ++ibiny) {
204 -m_activeBounds->boundingBox().halfLengthY() + ibiny * pitchY;
205 Vector3D binSurfaceCenter(0., binPosY, 0.);
207 auto binTransform = std::make_shared<const Transform3D>(
210 if (ibiny == 0 || ibiny == m_binUtility->bins(1)) {
211 boundarySurfaces.push_back(
212 Surface::makeShared<PlaneSurface>(binTransform, yBinBounds));
214 segmentationSurfacesY.push_back(
215 Surface::makeShared<PlaneSurface>(binTransform, yBinBounds));
222 double bX = m_binUtility->bins(0) > 1
223 ? m_binUtility->binningData()[0].center(dCell.
channel0)
225 double bY = m_binUtility->bins(1) > 1
226 ? m_binUtility->binningData()[1].center(dCell.
channel1)
235 int readoutDirection,
double lorentzAngle)
const {
236 Vector3D stepCenter = 0.5 * (startStep + endStep);
239 double driftInZ = halfThickness - readoutDirection * stepCenter.z();
241 double driftLength = driftInZ / cos(lorentzAngle);
243 double lorentzDeltaX = readoutDirection * driftInZ * tan(lorentzAngle);
245 Vector2D stepCenterProjected(stepCenter.x() + lorentzDeltaX, stepCenter.y());
248 Vector2D cellCenter = cellPosition(dCell);
251 startStep, endStep, stepCenterProjected, cellCenter);