6 #include "Acts/Utilities/SpacePointUtility.hpp"
14 #include "Acts/SpacePointFormation/SpacePointBuilderConfig.hpp"
23 const std::string &
name,
36 ATH_MSG_INFO(
"Use SCT SP overlap cuts based on layer number parity");
38 return StatusCode::SUCCESS;
47 std::vector<StripSP>& overlapSpacePoints,
49 const std::vector<IdentifierHash>& hashesToProcess,
94 auto spBuilderConfig = std::make_shared<Acts::SpacePointBuilderConfig>();
96 ATH_CHECK(acts_tracking_geometry !=
nullptr);
99 ATH_CHECK(detectorElementToGeometryIdMap.isValid());
103 spBuilderConfig->slSurfaceAccessor
104 .connect<&ATLASUncalibSourceLinkSurfaceAccessor::operator()>(&surfaceAccessor);
106 const std::shared_ptr<const Acts::TrackingGeometry> trkGeometry =
m_trackingGeometryTool->trackingGeometry();
107 spBuilderConfig->trackingGeometry = trkGeometry;
110 auto spConstructor = [
this, &clusterContainer, &elements](
const Acts::Vector3 &
pos,
111 std::optional<double> ,
112 const Acts::Vector2 &
cov,
113 std::optional<double> ,
114 const boost::container::static_vector<Acts::SourceLink, 2> &slinks)
116 std::vector<std::size_t> measIndices;
117 std::array<StripInformationHelper, 2> stripInfos;
119 for (
const auto& slink : slinks){
125 if (
it != clusterContainer.
end()){
126 const auto cluster_index =
it - clusterContainer.
begin();
127 const auto id = hit->identifierHash();
129 size_t stripIndex = 0;
130 auto ends = this->
getStripEnds(atlasSourceLink, element, stripIndex);
133 measIndices.push_back(cluster_index);
134 stripInfos[
idx++] = std::move(stripInfo);
137 const auto& [firstInfo, secondInfo] = stripInfos;
138 const auto topHalfStripLength = 0.5*firstInfo.stripDirection().norm();
139 Eigen::Matrix<double, 3, 1> topStripDirection = -firstInfo.stripDirection()/(2.*topHalfStripLength);
140 Eigen::Matrix<double, 3, 1> topStripCenter = 0.5*firstInfo.trajDirection();
142 const auto bottomHalfStripLength = 0.5*secondInfo.stripDirection().norm();
143 Eigen::Matrix<double, 3, 1> bottomStripDirection = -secondInfo.stripDirection()/(2.*bottomHalfStripLength);
144 Eigen::Matrix<double, 3, 1> stripCenterDistance = firstInfo.stripCenter() - secondInfo.stripCenter();
147 sp.
idHashes = {firstInfo.idHash(), secondInfo.idHash()};
162 auto spBuilder = std::make_shared<Acts::SpacePointBuilder<StripSP>>(*spBuilderConfig, spConstructor);
164 const auto hashesProc = (hashesToProcess.size() > 0 ? hashesToProcess : stripAccessor.
allIdentifiers());
165 for (
auto &idHash : hashesProc)
172 const std::vector<IdentifierHash>& others = *
properties.neighbours(idHash);
174 if ( others.empty())
continue;
180 size_t neighbour = 0;
181 while (not
search and neighbour < others.size()){
188 std::array<std::vector<std::pair<const xAOD::StripCluster *, size_t>>,
static_cast<size_t>(
nNeighbours)> neighbourClusters{};
189 std::array<std::vector<std::pair<ATLASUncalibSourceLink, size_t>>,
static_cast<size_t>(
nNeighbours)> neighbourSourceLinks{};
190 std::array<const InDetDD::SiDetectorElement *, static_cast<size_t>(
nNeighbours)> neighbourElements{};
192 auto groupStart = clusterContainer.
begin();
194 neighbourElements[0] = thisElement;
196 for (
auto start = this_range.first;
start != this_range.second; ++
start){
198 neighbourClusters[0].push_back(std::make_pair(*
start, position));
199 if ((*start)->identifierHash() != thisElement->
identifyHash()) {
200 throw std::logic_error(
"Identifier mismatch.");
203 neighbourSourceLinks[0].emplace_back(std::make_pair(slink, position));
210 std::array<double, 14> overlapExtents{};
220 if (not processOverlaps)
232 for (
const auto &otherHash : others){
233 if (++
n == Nmax)
break;
240 neighbourElements[neigbourIndices[
n]] = otherElement;
242 for (
auto start = this_range.first;
start != this_range.second; ++
start){
244 neighbourClusters[neigbourIndices[
n]].push_back(std::make_pair(*
start, position));
245 if ((*start)->identifierHash() != otherElement->
identifyHash()) {
246 throw std::logic_error(
"Identifier mismatch.");
249 neighbourSourceLinks[neigbourIndices[
n]].emplace_back(std::make_pair(slink, position));
262 overlapExtents[6] = -hwidth;
265 overlapExtents[9] = hwidth;
271 overlapExtents[11] = hwidth;
272 overlapExtents[12] = -hwidth;
303 return StatusCode::SUCCESS;
307 std::shared_ptr<Acts::SpacePointBuilder<StripSP>> spBuilder,
308 const std::array<const InDetDD::SiDetectorElement *,nNeighbours>& elements,
310 const std::array<double, 14>& overlapExtents,
313 std::vector<StripSP>& overlapSpacePoints )
const
338 Acts::Vector3 vertex(beamSpotVertex.x(), beamSpotVertex.y(), beamSpotVertex.z());
339 constexpr
int otherSideIndex{1};
340 constexpr
int maxEtaIndex{3};
348 elementIndex[nElements++] =
n;
352 if(!nElements)
return StatusCode::SUCCESS;
356 bool isEndcap = triggerElement->
isEndcap();
357 std::vector<StripInformationHelper> stripInfos;
358 stripInfos.reserve(sourceLinks[0].
size());
360 std::vector<ATLASUncalibSourceLink> triggerSlinks;
361 triggerSlinks.reserve(sourceLinks[0].
size());
364 for (
auto &sourceLink_index : sourceLinks[0]){
365 triggerSlinks.emplace_back(sourceLink_index.first);
374 for (;
n < nElements; ++
n){
375 int currentIndex = elementIndex[
n];
376 if (currentIndex > maxEtaIndex)
383 double min = overlapExtents[currentIndex * 2 - 2];
384 double max = overlapExtents[currentIndex * 2 - 1];
394 for (
auto &sourceLink_index : sourceLinks[currentIndex]){
396 const auto currentSlink = sourceLink_index.first;
397 for (
auto triggerSlink : triggerSlinks){
404 if (diff < min || diff >
max)
406 if (currentIndex == otherSideIndex){
408 currentElement,
limit, slimit, vertex));
412 currentElement,
limit, slimit, vertex));
419 for (;
n < nElements; ++
n){
420 int currentIndex = elementIndex[
n];
422 double min = overlapExtents[4 * currentIndex - 10];
423 double max = overlapExtents[4 * currentIndex - 9];
432 std::vector<ATLASUncalibSourceLink> triggerPhiSlinks;
433 triggerSlinks.reserve(triggerSlinks.size());
434 for (
auto triggerSlink : triggerSlinks){
439 size_t stripIndex = 0;
441 centralValue = stripIndex;
446 triggerPhiSlinks.emplace_back(triggerSlink);
449 if (triggerPhiSlinks.empty())
451 min = overlapExtents[4 * currentIndex - 8];
452 max = overlapExtents[4 * currentIndex - 7];
458 for (
auto &sourceLink_index : sourceLinks[currentIndex]){
459 const auto currentSlink = sourceLink_index.first;
461 size_t currentStripIndex = 0;
462 getStripEnds(currentSlink, currentElement, currentStripIndex);
467 centralValue = currentStripIndex;
471 if (centralValue < minValue or centralValue >
maxValue)
473 for (
auto &triggerSlink : triggerPhiSlinks) {
475 currentElement,
limit, slimit, vertex));
479 return StatusCode::SUCCESS;
483 for (
int n = 0;
n != nElements; ++
n){
485 int currentIndex = elementIndex[
n];
492 for (
auto &sourceLink_index : sourceLinks[currentIndex]){
493 size_t currentStripIndex = 0;
494 getStripEnds(sourceLink_index.first, triggerElement, currentStripIndex);
495 const auto currentSlink = sourceLink_index.first;
497 for (
auto triggerSlink : triggerSlinks){
498 if (currentIndex == otherSideIndex){
500 currentElement,
limit, slimit, vertex));
503 currentElement,
limit, slimit, vertex));
508 return StatusCode::SUCCESS;
513 std::vector<StripSP>& collection,
514 std::shared_ptr<Acts::SpacePointBuilder<StripSP>> spBuilder,
521 const Acts::Vector3& vertex)
const
526 size_t stripIndex = 0;
527 auto ends1 =
getStripEnds(currentSlink, currentElement, stripIndex);
528 auto ends2 =
getStripEnds(anotherSlink, anotherElement, stripIndex);
529 std::pair<Acts::Vector3, Acts::Vector3> ends1_acts;
530 std::pair<Acts::Vector3, Acts::Vector3> ends2_acts;
531 ends1_acts.first = ends1.first;
532 ends1_acts.second = ends1.second;
533 ends2_acts.first = ends2.first;
534 ends2_acts.second = ends2.second;
535 auto paramCovAccessor = [&](
const Acts::SourceLink &slink) {
540 switch (measurement->type()) {
542 loc[Acts::eBoundLoc0] = measurement->localPosition<1>()[
Trk::locX];
543 cov.topLeftCorner<1, 1>() =
544 measurement->localCovariance<1>().cast<
double>();
547 loc[Acts::eBoundLoc0] = measurement->localPosition<2>()[
Trk::locX];
548 loc[Acts::eBoundLoc1] = measurement->localPosition<2>()[
Trk::locY];
549 cov.topLeftCorner<2, 2>() =
550 measurement->localCovariance<2>().cast<
double>();
553 throw std::domain_error(
554 "Can only handle measurement type pixel or strip");
556 return std::make_pair(loc,
cov);
558 std::vector<Acts::SourceLink> slinks;
560 slinks.emplace_back(Acts::SourceLink{currentSlink});
561 slinks.emplace_back(Acts::SourceLink{anotherSlink});
563 Acts::SpacePointBuilderOptions spOpt{std::make_pair(ends1_acts, ends2_acts), paramCovAccessor};
564 spOpt.vertex = vertex;
565 spOpt.stripLengthTolerance =
limit - 1;
566 spOpt.stripLengthGapTolerance = slimit;
569 spBuilder->buildSpacePoint(tgContext, slinks, spOpt,
570 std::back_inserter(collection));
571 return StatusCode::SUCCESS;
576 double& stripLengthGapTolerance)
const
587 double x12 =
t1.linear().col(0).dot(
t2.linear().col(0));
588 double r = isAnnulus ?
c.perp() : std::sqrt(
t1(0, 3) *
t1(0, 3) +
t1(1, 3) *
t1(1, 3));
592 double s = dPos.dot(
t1.linear().col(2));
596 double d = isAnnulus ?
dm / 0.04 :
dm / std::sqrt((1. - x12) * (1. + x12));
599 const double zComponentTolerance = 0.7;
600 if (std::abs(
t1(2, 2)) > zComponentTolerance)
601 d *= (
r / std::abs(
t1(2, 3)));
603 stripLengthGapTolerance =
d;
610 double &stripLengthGapTolerance,
611 double &
min,
double &
max)
const
613 double dm =
computeOffset(element1, element2, stripLengthGapTolerance);
639 double radius = firstPosition.xEta();
658 std::pair<Amg::Vector3D, Amg::Vector3D>
661 size_t &stripIndex)
const
666 ATH_MSG_FATAL(
"Could not cast UncalibratedMeasurement as StripCluster");
680 stripIndex = -std::floor(source_local_x / phiPitchPhi) + design->
diodesInRow(0) *0.5 - 0.5;
682 std::pair<Amg::Vector3D, Amg::Vector3D > ends = {
690 std::pair<Amg::Vector3D, Amg::Vector3D> ends(element->
endsOfStrip(localPosition));