6 #include "Acts/Utilities/SpacePointUtility.hpp"
14 #include "Acts/SpacePointFormation/SpacePointBuilderConfig.hpp"
31 ATH_MSG_INFO(
"Use SCT SP overlap cuts based on layer number parity");
33 return StatusCode::SUCCESS;
42 std::vector<StripSP>& overlapSpacePoints,
44 const std::vector<IdentifierHash>& hashesToProcess,
89 auto spBuilderConfig = std::make_shared<Acts::SpacePointBuilderConfig>();
92 spBuilderConfig->slSurfaceAccessor.connect<&detail::xAODUncalibMeasSurfAcc::operator()>(&surfaceAccessor);
96 auto spConstructor = [
this, &clusterContainer, &elements](
const Acts::Vector3 &
pos,
97 std::optional<double> ,
98 const Acts::Vector2 &
cov,
99 std::optional<double> ,
100 const boost::container::static_vector<Acts::SourceLink, 2> &slinks)
103 std::array<StripInformationHelper, 2> stripInfos;
105 for (
const auto& slink : slinks){
109 if (
it != clusterContainer.
end()){
113 size_t stripIndex = 0;
114 auto ends = this->
getStripEnds(hit, element, stripIndex);
117 assert(
idx < measIndices.size() &&
idx < stripInfos.size());
118 measIndices[
idx] = cluster_index;
119 stripInfos[
idx] = std::move(stripInfo);
123 const auto& [firstInfo, secondInfo] = stripInfos;
124 const auto topHalfStripLength = 0.5*firstInfo.stripDirection().norm();
125 Eigen::Matrix<double, 3, 1> topStripDirection = -firstInfo.stripDirection()/(2.*topHalfStripLength);
126 Eigen::Matrix<double, 3, 1> topStripCenter = 0.5*firstInfo.trajDirection();
128 const auto bottomHalfStripLength = 0.5*secondInfo.stripDirection().norm();
129 Eigen::Matrix<double, 3, 1> bottomStripDirection = -secondInfo.stripDirection()/(2.*bottomHalfStripLength);
130 Eigen::Matrix<double, 3, 1> stripCenterDistance = firstInfo.stripCenter() - secondInfo.stripCenter();
133 sp.
idHashes = {firstInfo.idHash(), secondInfo.idHash()};
148 auto spBuilder = std::make_shared<Acts::SpacePointBuilder<StripSP>>(*spBuilderConfig, spConstructor);
150 const auto hashesProc = (hashesToProcess.size() > 0 ? hashesToProcess : stripAccessor.
allIdentifiers());
151 for (
auto &idHash : hashesProc) {
157 const std::vector<IdentifierHash>& others = *
properties.neighbours(idHash);
159 if (others.empty()) {
166 size_t neighbour = 0;
167 while (not
search and neighbour < others.size()){
175 std::array<std::vector<std::pair<const xAOD::StripCluster *, size_t>>,
static_cast<size_t>(
nNeighbours)> neighbourClusters{};
176 std::array<std::vector<std::pair<ATLASUncalibSourceLink, size_t>>,
static_cast<size_t>(
nNeighbours)> neighbourSourceLinks{};
177 std::array<const InDetDD::SiDetectorElement *, static_cast<size_t>(
nNeighbours)> neighbourElements{};
179 auto groupStart = clusterContainer.
begin();
181 neighbourElements[0] = thisElement;
183 for (
auto start = this_range.first;
start != this_range.second; ++
start){
185 neighbourClusters[0].push_back(std::make_pair(*
start, position));
186 if ((*start)->identifierHash() != thisElement->
identifyHash()) {
187 throw std::logic_error(
"Identifier mismatch.");
190 neighbourSourceLinks[0].emplace_back(std::make_pair(slink, position));
197 std::array<double, 14> overlapExtents{};
207 if (not processOverlaps)
219 for (
const auto &otherHash : others){
220 if (++
n == Nmax)
break;
227 neighbourElements[neigbourIndices[
n]] = otherElement;
229 for (
auto start = this_range.first;
start != this_range.second; ++
start){
231 neighbourClusters[neigbourIndices[
n]].push_back(std::make_pair(*
start, position));
232 if ((*start)->identifierHash() != otherElement->
identifyHash()) {
233 throw std::logic_error(
"Identifier mismatch.");
236 neighbourSourceLinks[neigbourIndices[
n]].emplace_back(std::make_pair(slink, position));
249 overlapExtents[6] = -hwidth;
252 overlapExtents[9] = hwidth;
258 overlapExtents[11] = hwidth;
259 overlapExtents[12] = -hwidth;
290 return StatusCode::SUCCESS;
294 std::shared_ptr<Acts::SpacePointBuilder<StripSP>> spBuilder,
295 const std::array<const InDetDD::SiDetectorElement *,nNeighbours>& elements,
297 const std::array<double, 14>& overlapExtents,
300 std::vector<StripSP>& overlapSpacePoints )
const
325 Acts::Vector3
vertex(beamSpotVertex.x(), beamSpotVertex.y(), beamSpotVertex.z());
326 constexpr
int otherSideIndex{1};
327 constexpr
int maxEtaIndex{3};
335 elementIndex[nElements++] =
n;
339 if(!nElements)
return StatusCode::SUCCESS;
343 bool isEndcap = triggerElement->
isEndcap();
344 std::vector<StripInformationHelper> stripInfos;
345 stripInfos.reserve(sourceLinks[0].
size());
347 std::vector<ATLASUncalibSourceLink> triggerSlinks;
348 triggerSlinks.reserve(sourceLinks[0].
size());
351 for (
auto &sourceLink_index : sourceLinks[0]){
352 triggerSlinks.emplace_back(sourceLink_index.first);
361 for (;
n < nElements; ++
n){
362 int currentIndex = elementIndex[
n];
363 if (currentIndex > maxEtaIndex)
370 double min = overlapExtents[currentIndex * 2 - 2];
371 double max = overlapExtents[currentIndex * 2 - 1];
381 for (
auto &sourceLink_index : sourceLinks[currentIndex]){
383 const auto currentSlink = sourceLink_index.first;
384 for (
auto triggerSlink : triggerSlinks){
391 if (diff < min || diff >
max)
393 if (currentIndex == otherSideIndex){
406 for (;
n < nElements; ++
n){
407 int currentIndex = elementIndex[
n];
409 double min = overlapExtents[4 * currentIndex - 10];
410 double max = overlapExtents[4 * currentIndex - 9];
419 std::vector<ATLASUncalibSourceLink> triggerPhiSlinks;
420 triggerSlinks.reserve(triggerSlinks.size());
421 for (
auto triggerSlink : triggerSlinks){
426 size_t stripIndex = 0;
428 centralValue = stripIndex;
433 triggerPhiSlinks.emplace_back(triggerSlink);
436 if (triggerPhiSlinks.empty())
438 min = overlapExtents[4 * currentIndex - 8];
439 max = overlapExtents[4 * currentIndex - 7];
445 for (
auto &sourceLink_index : sourceLinks[currentIndex]){
446 const auto currentSlink = sourceLink_index.first;
448 size_t currentStripIndex = 0;
449 getStripEnds(currentSlink, currentElement, currentStripIndex);
454 centralValue = currentStripIndex;
458 if (centralValue < minValue or centralValue >
maxValue)
460 for (
auto &triggerSlink : triggerPhiSlinks) {
466 return StatusCode::SUCCESS;
470 for (
int n = 0;
n != nElements; ++
n){
472 int currentIndex = elementIndex[
n];
479 for (
auto &sourceLink_index : sourceLinks[currentIndex]){
480 size_t currentStripIndex = 0;
481 getStripEnds(sourceLink_index.first, triggerElement, currentStripIndex);
482 const auto currentSlink = sourceLink_index.first;
484 for (
auto triggerSlink : triggerSlinks){
485 if (currentIndex == otherSideIndex){
495 return StatusCode::SUCCESS;
500 std::vector<StripSP>& collection,
501 std::shared_ptr<Acts::SpacePointBuilder<StripSP>> spBuilder,
508 const Acts::Vector3&
vertex)
const
513 size_t stripIndex = 0;
514 auto ends1 =
getStripEnds(currentSlink, currentElement, stripIndex);
515 auto ends2 =
getStripEnds(anotherSlink, anotherElement, stripIndex);
516 std::pair<Acts::Vector3, Acts::Vector3> ends1_acts;
517 std::pair<Acts::Vector3, Acts::Vector3> ends2_acts;
518 ends1_acts.first = ends1.first;
519 ends1_acts.second = ends1.second;
520 ends2_acts.first = ends2.first;
521 ends2_acts.second = ends2.second;
522 auto paramCovAccessor = [&](
const Acts::SourceLink &slink) {
527 switch (measurement->type()) {
529 loc[Acts::eBoundLoc0] = measurement->localPosition<1>()[
Trk::locX];
530 cov.topLeftCorner<1, 1>() =
531 measurement->localCovariance<1>().cast<
double>();
534 loc[Acts::eBoundLoc0] = measurement->localPosition<2>()[
Trk::locX];
535 loc[Acts::eBoundLoc1] = measurement->localPosition<2>()[
Trk::locY];
536 cov.topLeftCorner<2, 2>() =
537 measurement->localCovariance<2>().cast<
double>();
540 throw std::domain_error(
541 "Can only handle measurement type pixel or strip");
543 return std::make_pair(loc,
cov);
545 std::vector<Acts::SourceLink> slinks;
547 slinks.emplace_back(Acts::SourceLink{currentSlink});
548 slinks.emplace_back(Acts::SourceLink{anotherSlink});
550 Acts::SpacePointBuilderOptions spOpt{std::make_pair(ends1_acts, ends2_acts), paramCovAccessor};
552 spOpt.stripLengthTolerance =
limit - 1;
553 spOpt.stripLengthGapTolerance = slimit;
556 spBuilder->buildSpacePoint(tgContext, slinks, spOpt,
557 std::back_inserter(collection));
558 return StatusCode::SUCCESS;
563 double& stripLengthGapTolerance)
const
574 double x12 =
t1.linear().col(0).dot(
t2.linear().col(0));
575 double r = isAnnulus ?
c.perp() : std::sqrt(
t1(0, 3) *
t1(0, 3) +
t1(1, 3) *
t1(1, 3));
579 double s = dPos.dot(
t1.linear().col(2));
583 double d = isAnnulus ?
dm / 0.04 :
dm / std::sqrt((1. - x12) * (1. + x12));
586 const double zComponentTolerance = 0.7;
587 if (std::abs(
t1(2, 2)) > zComponentTolerance)
588 d *= (
r / std::abs(
t1(2, 3)));
590 stripLengthGapTolerance =
d;
597 double &stripLengthGapTolerance,
598 double &
min,
double &
max)
const
600 double dm =
computeOffset(element1, element2, stripLengthGapTolerance);
626 double radius = firstPosition.xEta();
645 std::pair<Amg::Vector3D, Amg::Vector3D>
648 size_t &stripIndex)
const
653 ATH_MSG_FATAL(
"Could not cast UncalibratedMeasurement as StripCluster");
667 stripIndex = -std::floor(source_local_x / phiPitchPhi) + design->
diodesInRow(0) *0.5 - 0.5;
669 std::pair<Amg::Vector3D, Amg::Vector3D > ends = {
677 std::pair<Amg::Vector3D, Amg::Vector3D> ends(element->
endsOfStrip(localPosition));