File indexing completed on 2024-04-06 12:28:49
0001 #ifndef TkDetLayers_TkDetUtil_h
0002 #define TkDetLayers_TkDetUtil_h
0003
0004 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
0005 #include "TrackingTools/DetLayers/interface/MeasurementEstimator.h"
0006 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0007 #include "TrackingTools/DetLayers/interface/rangesIntersect.h"
0008 #include "DataFormats/GeometryVector/interface/VectorUtil.h"
0009 #include "DataFormats/GeometrySurface/interface/BoundDisk.h"
0010 #include "TrackingTools/DetLayers/interface/RingedForwardLayer.h"
0011 #include "DataFormats/GeometrySurface/interface/SimpleDiskBounds.h"
0012 #include "TrackingTools/DetLayers/interface/DetLayerException.h"
0013
0014 #include "TrackingTools/GeomPropagators/interface/HelixForwardPlaneCrossing.h"
0015
0016 #include "DataFormats/GeometrySurface/interface/SimpleDiskBounds.h"
0017
0018 #include "DetGroupMerger.h"
0019
0020 class GeomDet;
0021 class Plane;
0022 class TrajectoryStateOnSurface;
0023
0024 #pragma GCC visibility push(hidden)
0025
0026 namespace tkDetUtil {
0027
0028 struct RingPar {
0029 float theRingR, thetaRingMin, thetaRingMax;
0030 };
0031
0032 inline bool overlapInPhi(float phi, const GeomDet& det, float phiWindow) {
0033 std::pair<float, float> phiRange(phi - phiWindow, phi + phiWindow);
0034 return rangesIntersect(phiRange, det.surface().phiSpan(), [](auto x, auto y) { return Geom::phiLess(x, y); });
0035 }
0036
0037 inline bool overlapInPhi(GlobalPoint crossPoint, const GeomDet& det, float phiWindow) {
0038 return overlapInPhi(crossPoint.barePhi(), det, phiWindow);
0039 }
0040
0041 float computeWindowSize(const GeomDet* det, const TrajectoryStateOnSurface& tsos, const MeasurementEstimator& est);
0042
0043 float calculatePhiWindow(const MeasurementEstimator::Local2DVector& maxDistance,
0044 const TrajectoryStateOnSurface& ts,
0045 const Plane& plane);
0046
0047 float computeYdirWindowSize(const GeomDet* det,
0048 const TrajectoryStateOnSurface& tsos,
0049 const MeasurementEstimator& est);
0050
0051 std::array<int, 3> findThreeClosest(const std::vector<RingPar>& ringParams,
0052 const std::vector<GlobalPoint>& ringCrossing,
0053 const int ringSize);
0054
0055 bool overlapInR(const TrajectoryStateOnSurface& tsos, int index, double ymax, const std::vector<RingPar>& ringParams);
0056
0057 RingPar fillRingParametersFromDisk(const BoundDisk& ringDisk);
0058
0059 template <class T>
0060 std::array<int, 3> ringIndicesByCrossingProximity(const TrajectoryStateOnSurface& startingState,
0061 const Propagator& prop,
0062 const int ringSize,
0063 const T& diskComponents,
0064 const std::vector<RingPar>& ringParams) {
0065 typedef HelixForwardPlaneCrossing Crossing;
0066 typedef MeasurementEstimator::Local2DVector Local2DVector;
0067
0068 HelixPlaneCrossing::PositionType startPos(startingState.globalPosition());
0069 HelixPlaneCrossing::DirectionType startDir(startingState.globalMomentum());
0070 PropagationDirection propDir(prop.propagationDirection());
0071 float rho(startingState.transverseCurvature());
0072
0073
0074
0075
0076 Crossing myXing(startPos, startDir, rho, propDir);
0077
0078 std::vector<GlobalPoint> ringCrossings;
0079 ringCrossings.reserve(ringSize);
0080
0081 for (int i = 0; i < ringSize; i++) {
0082 const BoundDisk& theRing = static_cast<const BoundDisk&>(diskComponents[i]->surface());
0083 std::pair<bool, double> pathlen = myXing.pathLength(theRing);
0084 if (pathlen.first) {
0085 ringCrossings.push_back(GlobalPoint(myXing.position(pathlen.second)));
0086 } else {
0087
0088 ringCrossings.push_back(GlobalPoint(0., 0., 0.));
0089 }
0090 }
0091
0092
0093
0094 std::array<int, 3> closests = findThreeClosest(ringParams, ringCrossings, ringSize);
0095
0096 return closests;
0097 }
0098
0099 template <class T>
0100 void groupedCompatibleDetsV(const TrajectoryStateOnSurface& startingState,
0101 const Propagator& prop,
0102 const MeasurementEstimator& est,
0103 std::vector<DetGroup>& result,
0104 const int ringSize,
0105 const std::vector<const T*>& diskComponents,
0106 const std::vector<RingPar>& ringParams) {
0107 std::array<int, 3> const& ringIndices =
0108 ringIndicesByCrossingProximity(startingState, prop, ringSize, diskComponents, ringParams);
0109 if (ringIndices[0] == -1 || ringIndices[1] == -1 || ringIndices[2] == -1) {
0110 edm::LogError("TkDetLayers") << "TkRingedForwardLayer::groupedCompatibleDets : error in CrossingProximity";
0111 return;
0112 }
0113
0114
0115
0116
0117
0118 std::vector<int> ringOrder(ringSize);
0119 std::fill(ringOrder.begin(), ringOrder.end(), 1);
0120 if (ringSize > 1) {
0121 if (std::abs(diskComponents[0]->position().z()) < std::abs(diskComponents[1]->position().z())) {
0122 for (int i = 0; i < ringSize; i++) {
0123 if (i % 2 == 0)
0124 ringOrder[i] = 0;
0125 }
0126 } else if (std::abs(diskComponents[0]->position().z()) > std::abs(diskComponents[1]->position().z())) {
0127 std::fill(ringOrder.begin(), ringOrder.end(), 0);
0128 for (int i = 0; i < ringSize; i++) {
0129 if (i % 2 == 0)
0130 ringOrder[i] = 1;
0131 }
0132 } else {
0133 throw DetLayerException("Rings in Endcap Layer have same z position, no idea how to order them!");
0134 }
0135 }
0136
0137 auto index = [&ringIndices, &ringOrder](int i) { return ringOrder[ringIndices[i]]; };
0138
0139 std::vector<DetGroup> closestResult;
0140 diskComponents[ringIndices[0]]->groupedCompatibleDetsV(startingState, prop, est, closestResult);
0141
0142 if (closestResult.empty()) {
0143 diskComponents[ringIndices[1]]->groupedCompatibleDetsV(startingState, prop, est, result);
0144 return;
0145 }
0146
0147 DetGroupElement closestGel(closestResult.front().front());
0148 float rWindow = computeYdirWindowSize(closestGel.det(), closestGel.trajectoryState(), est);
0149
0150
0151
0152 bool ring1ok =
0153 ringIndices[1] != -1 && overlapInR(closestGel.trajectoryState(), ringIndices[1], rWindow, ringParams);
0154 bool ring2ok =
0155 ringIndices[2] != -1 && overlapInR(closestGel.trajectoryState(), ringIndices[2], rWindow, ringParams);
0156
0157
0158
0159
0160
0161 int direction = 0;
0162 if (startingState.globalPosition().z() * startingState.globalMomentum().z() > 0) {
0163 if (prop.propagationDirection() == alongMomentum)
0164 direction = 0;
0165 else
0166 direction = 1;
0167 } else {
0168 if (prop.propagationDirection() == alongMomentum)
0169 direction = 1;
0170 else
0171 direction = 0;
0172 }
0173
0174 if ((index(0) == index(1)) && (index(0) == index(2))) {
0175 edm::LogInfo("AllRingsInOnePlane") << " All rings: " << ringIndices[0] << " " << ringIndices[1] << " "
0176 << ringIndices[2] << " in one plane. Only the first two will be considered";
0177 ring2ok = false;
0178 }
0179
0180 if (index(0) == index(1)) {
0181 if (ring1ok) {
0182 std::vector<DetGroup> ring1res;
0183 diskComponents[ringIndices[1]]->groupedCompatibleDetsV(startingState, prop, est, ring1res);
0184 DetGroupMerger::addSameLevel(std::move(ring1res), closestResult);
0185 }
0186 if (ring2ok) {
0187 std::vector<DetGroup> ring2res;
0188 diskComponents[ringIndices[2]]->groupedCompatibleDetsV(startingState, prop, est, ring2res);
0189 DetGroupMerger::orderAndMergeTwoLevels(
0190 std::move(closestResult), std::move(ring2res), result, index(0), direction);
0191 return;
0192 } else {
0193 result.swap(closestResult);
0194 return;
0195 }
0196 } else if (index(0) == index(2)) {
0197 if (ring2ok) {
0198 std::vector<DetGroup> ring2res;
0199 diskComponents[ringIndices[2]]->groupedCompatibleDetsV(startingState, prop, est, ring2res);
0200 DetGroupMerger::addSameLevel(std::move(ring2res), closestResult);
0201 }
0202 if (ring1ok) {
0203 std::vector<DetGroup> ring1res;
0204 diskComponents[ringIndices[1]]->groupedCompatibleDetsV(startingState, prop, est, ring1res);
0205 DetGroupMerger::orderAndMergeTwoLevels(
0206 std::move(closestResult), std::move(ring1res), result, index(0), direction);
0207 return;
0208 } else {
0209 result.swap(closestResult);
0210 return;
0211 }
0212 } else {
0213 std::vector<DetGroup> ring12res;
0214 if (ring1ok) {
0215 std::vector<DetGroup> ring1res;
0216 diskComponents[ringIndices[1]]->groupedCompatibleDetsV(startingState, prop, est, ring1res);
0217 ring12res.swap(ring1res);
0218 }
0219 if (ring2ok) {
0220 std::vector<DetGroup> ring2res;
0221 diskComponents[ringIndices[2]]->groupedCompatibleDetsV(startingState, prop, est, ring2res);
0222 DetGroupMerger::addSameLevel(std::move(ring2res), ring12res);
0223 }
0224 if (!ring12res.empty()) {
0225 DetGroupMerger::orderAndMergeTwoLevels(
0226 std::move(closestResult), std::move(ring12res), result, index(0), direction);
0227 return;
0228 } else {
0229 result.swap(closestResult);
0230 return;
0231 }
0232 }
0233 }
0234
0235 template <class T>
0236 BoundDisk* computeDisk(const std::vector<const T*>& structures) {
0237 float theRmin = structures.front()->specificSurface().innerRadius();
0238 float theRmax = structures.front()->specificSurface().outerRadius();
0239 float theZmin = structures.front()->position().z() - structures.front()->surface().bounds().thickness() / 2;
0240 float theZmax = structures.front()->position().z() + structures.front()->surface().bounds().thickness() / 2;
0241
0242 for (typename std::vector<const T*>::const_iterator i = structures.begin(); i != structures.end(); i++) {
0243 float rmin = (**i).specificSurface().innerRadius();
0244 float rmax = (**i).specificSurface().outerRadius();
0245 float zmin = (**i).position().z() - (**i).surface().bounds().thickness() / 2.;
0246 float zmax = (**i).position().z() + (**i).surface().bounds().thickness() / 2.;
0247 theRmin = std::min(theRmin, rmin);
0248 theRmax = std::max(theRmax, rmax);
0249 theZmin = std::min(theZmin, zmin);
0250 theZmax = std::max(theZmax, zmax);
0251 }
0252
0253 float zPos = (theZmax + theZmin) / 2.;
0254 Plane::PositionType pos(0., 0., zPos);
0255 Plane::RotationType rot;
0256
0257 return new BoundDisk(pos, rot, new SimpleDiskBounds(theRmin, theRmax, theZmin - zPos, theZmax - zPos));
0258 }
0259
0260 }
0261
0262 #pragma GCC visibility pop
0263 #endif