22 const std::shared_ptr<const PlanarBounds>& mBounds,
size_t numCellsX,
24 : m_activeBounds(mBounds), m_binUtility(nullptr) {
25 auto mutableBinUtility = std::make_shared<BinUtility>(
26 numCellsX, -mBounds->boundingBox().halfLengthX(),
28 (*mutableBinUtility) +=
29 BinUtility(numCellsY, -mBounds->boundingBox().halfLengthY(),
35 std::shared_ptr<const BinUtility> bUtility,
36 std::shared_ptr<const PlanarBounds> mBounds)
37 : m_activeBounds(std::move(mBounds)), m_binUtility(std::move(bUtility)) {
49 int readoutDirection,
double lorentzAngle)
const {
51 double lorentzAngleTan = tan(lorentzAngle);
52 double lorentzPlaneShiftX = halfThickness * lorentzAngleTan;
64 auto readoutPlaneTransform = Transform3D::Identity();
65 auto counterPlaneTransform = Transform3D::Identity();
68 std::shared_ptr<const PlanarBounds> readoutPlaneBounds =
moduleBounds;
69 std::shared_ptr<const PlanarBounds> counterPlaneBounds(
nullptr);
71 readoutPlaneTransform.translation() =
72 Vector3D(0., 0., readoutDirection * halfThickness);
74 if (lorentzAngle == 0.) {
76 counterPlaneTransform.translation() =
77 Vector3D(0., 0., -readoutDirection * halfThickness);
80 double lorentzReducedHalfX =
81 m_activeBounds->boundingBox().halfLengthX() - fabs(lorentzPlaneShiftX);
82 std::shared_ptr<const PlanarBounds> lorentzReducedBounds(
84 m_activeBounds->boundingBox().halfLengthY()));
85 counterPlaneBounds = lorentzReducedBounds;
88 double counterPlaneShift = -readoutDirection * lorentzPlaneShiftX;
89 counterPlaneTransform.translation() =
90 Vector3D(counterPlaneShift, 0., -readoutDirection * halfThickness);
93 boundarySurfaces.push_back(Surface::makeShared<PlaneSurface>(
94 readoutPlaneTransform, readoutPlaneBounds));
95 boundarySurfaces.push_back(Surface::makeShared<PlaneSurface>(
96 counterPlaneTransform, counterPlaneBounds));
102 2. * m_activeBounds->boundingBox().halfLengthX() / m_binUtility->bins(0);
107 m_activeBounds->boundingBox().halfLengthY(), halfThickness));
109 double lorentzPlaneHalfX =
std::abs(halfThickness /
cos(lorentzAngle));
111 std::shared_ptr<const PlanarBounds> lorentzPlaneBounds =
114 : std::shared_ptr<const PlanarBounds>(
120 xBinRotationMatrix.col(0) = Vector3D::UnitY();
121 xBinRotationMatrix.col(1) = Vector3D::UnitZ();
122 xBinRotationMatrix.col(2) = Vector3D::UnitX();
127 ? xBinRotationMatrix *
AngleAxis3D(lorentzAngle, Vector3D::UnitX())
128 : xBinRotationMatrix;
132 segmentationSurfacesX.reserve(m_binUtility->bins(0));
134 for (
size_t ibinx = 0; ibinx <= m_binUtility->bins(0); ++ibinx) {
137 -m_activeBounds->boundingBox().halfLengthX() + ibinx * pitchX;
139 if ((ibinx == 0
u) || ibinx == m_binUtility->bins(0)) {
144 bool boundaryStraight =
145 (lorentzAngle == 0. ||
146 ((ibinx == 0
u) && readoutDirection * lorentzAngle > 0.) ||
147 (ibinx == m_binUtility->bins(0) &&
148 readoutDirection * lorentzAngle < 0));
153 :
Vector3D(cPosX - readoutDirection * lorentzPlaneShiftX, 0., 0.);
156 boundaryStraight ? xBinRotationMatrix : lorentzPlaneRotationMatrix;
158 auto boundaryXTransform =
161 std::shared_ptr<const PlanarBounds> boundaryXBounds =
162 boundaryStraight ? xBinBounds : lorentzPlaneBounds;
164 boundarySurfaces.push_back(Surface::makeShared<PlaneSurface>(
165 boundaryXTransform, boundaryXBounds));
170 cPosX - readoutDirection * lorentzPlaneShiftX, 0., 0.);
172 Translation3D(lorentzPlanePosition) * lorentzPlaneRotationMatrix);
174 segmentationSurfacesX.push_back(Surface::makeShared<PlaneSurface>(
175 lorentzPlaneTransform, lorentzPlaneBounds));
183 yBinRotationMatrix.col(0) = Vector3D::UnitX();
184 yBinRotationMatrix.col(1) = Vector3D::UnitZ();
185 yBinRotationMatrix.col(2) =
Vector3D(0., -1., 0.);
188 2. * m_activeBounds->boundingBox().halfLengthY() / m_binUtility->bins(1);
191 m_activeBounds->boundingBox().halfLengthX(), halfThickness));
194 segmentationSurfacesY.reserve(m_binUtility->bins(1));
195 for (
size_t ibiny = 0; ibiny <= m_binUtility->bins(1); ++ibiny) {
198 -m_activeBounds->boundingBox().halfLengthY() + ibiny * pitchY;
199 Vector3D binSurfaceCenter(0., binPosY, 0.);
204 if (ibiny == 0 || ibiny == m_binUtility->bins(1)) {
205 boundarySurfaces.push_back(
206 Surface::makeShared<PlaneSurface>(binTransform, yBinBounds));
208 segmentationSurfacesY.push_back(
209 Surface::makeShared<PlaneSurface>(binTransform, yBinBounds));
216 double bX = m_binUtility->bins(0) > 1
217 ? m_binUtility->binningData()[0].center(dCell.
channel0)
219 double bY = m_binUtility->bins(1) > 1
220 ? m_binUtility->binningData()[1].center(dCell.
channel1)
229 int readoutDirection,
double lorentzAngle)
const {
230 Vector3D stepCenter = 0.5 * (startStep + endStep);
233 double driftInZ = halfThickness - readoutDirection * stepCenter.z();
235 double driftLength = driftInZ /
cos(lorentzAngle);
237 double lorentzDeltaX = readoutDirection * driftInZ * tan(lorentzAngle);
239 Vector2D stepCenterProjected(stepCenter.x() + lorentzDeltaX, stepCenter.y());
242 Vector2D cellCenter = cellPosition(dCell);
245 startStep, endStep, stepCenterProjected, cellCenter);