6 #include "Acts/Utilities/SpacePointUtility.hpp"
14 #include "Acts/SpacePointFormation/SpacePointBuilderConfig.hpp"
23 const std::string &
name,
34 return StatusCode::SUCCESS;
42 std::vector<StripSP>& spacePoints,
43 std::vector<StripSP>& overlapSpacePoints,
45 const std::vector<IdentifierHash>& hashesToProcess,
90 auto spBuilderConfig = std::make_shared<Acts::SpacePointBuilderConfig>();
92 ATH_CHECK(acts_tracking_geometry !=
nullptr);
95 ATH_CHECK(detectorElementToGeometryIdMap.isValid());
99 spBuilderConfig->slSurfaceAccessor
100 .connect<&ATLASUncalibSourceLinkSurfaceAccessor::operator()>(&surfaceAccessor);
102 const std::shared_ptr<const Acts::TrackingGeometry> trkGeometry =
m_trackingGeometryTool->trackingGeometry();
103 spBuilderConfig->trackingGeometry = trkGeometry;
106 auto spConstructor = [
this, &clusterContainer, &elements](
const Acts::Vector3 &
pos,
107 std::optional<double> ,
108 const Acts::Vector2 &
cov,
109 std::optional<double> ,
110 const boost::container::static_vector<Acts::SourceLink, 2> &slinks)
112 std::vector<std::size_t> measIndices;
113 std::array<StripInformationHelper, 2> stripInfos;
115 for (
const auto& slink : slinks){
121 if (
it != clusterContainer.
end()){
122 const auto cluster_index =
it - clusterContainer.
begin();
123 const auto id = hit->identifierHash();
125 size_t stripIndex = 0;
126 auto ends = this->
getStripEnds(atlasSourceLink, element, stripIndex);
129 measIndices.push_back(cluster_index);
130 stripInfos[
idx++] = std::move(stripInfo);
133 const auto& [firstInfo, secondInfo] = stripInfos;
134 const auto topHalfStripLength = 0.5*firstInfo.stripDirection().norm();
135 Eigen::Matrix<double, 3, 1> topStripDirection = -firstInfo.stripDirection()/(2.*topHalfStripLength);
136 Eigen::Matrix<double, 3, 1> topStripCenter = 0.5*firstInfo.trajDirection();
138 const auto bottomHalfStripLength = 0.5*secondInfo.stripDirection().norm();
139 Eigen::Matrix<double, 3, 1> bottomStripDirection = -secondInfo.stripDirection()/(2.*bottomHalfStripLength);
140 Eigen::Matrix<double, 3, 1> stripCenterDistance = firstInfo.stripCenter() - secondInfo.stripCenter();
143 sp.
idHashes = {firstInfo.idHash(), secondInfo.idHash()};
158 auto spBuilder = std::make_shared<Acts::SpacePointBuilder<StripSP>>(*spBuilderConfig, spConstructor);
160 const auto hashesProc = (hashesToProcess.size() > 0 ? hashesToProcess : stripAccessor.
allIdentifiers());
161 for (
auto &idHash : hashesProc)
168 const std::vector<IdentifierHash>& others = *
properties.neighbours(idHash);
170 if ( others.empty())
continue;
176 size_t neighbour = 0;
177 while (not
search and neighbour < others.size()){
184 std::array<std::vector<std::pair<const xAOD::StripCluster *, size_t>>,
static_cast<size_t>(
nNeighbours)> neighbourClusters{};
185 std::array<std::vector<std::pair<ATLASUncalibSourceLink, size_t>>,
static_cast<size_t>(
nNeighbours)> neighbourSourceLinks{};
186 std::array<const InDetDD::SiDetectorElement *, static_cast<size_t>(
nNeighbours)> neighbourElements{};
188 auto groupStart = clusterContainer.
begin();
190 neighbourElements[0] = thisElement;
192 for (
auto start = this_range.first;
start != this_range.second; ++
start){
194 neighbourClusters[0].push_back(std::make_pair(*
start, position));
195 if ((*start)->identifierHash() != thisElement->
identifyHash()) {
196 throw std::logic_error(
"Identifier mismatch.");
199 neighbourSourceLinks[0].emplace_back(std::make_pair(slink, position));
206 std::array<double, 14> overlapExtents{};
216 if (not processOverlaps)
228 for (
const auto &otherHash : others){
229 if (++
n == Nmax)
break;
236 neighbourElements[neigbourIndices[
n]] = otherElement;
238 for (
auto start = this_range.first;
start != this_range.second; ++
start){
240 neighbourClusters[neigbourIndices[
n]].push_back(std::make_pair(*
start, position));
241 if ((*start)->identifierHash() != otherElement->
identifyHash()) {
242 throw std::logic_error(
"Identifier mismatch.");
245 neighbourSourceLinks[neigbourIndices[
n]].emplace_back(std::make_pair(slink, position));
258 overlapExtents[6] = -hwidth;
261 overlapExtents[9] = hwidth;
267 overlapExtents[11] = hwidth;
268 overlapExtents[12] = -hwidth;
298 spacePoints, overlapSpacePoints) );
301 return StatusCode::SUCCESS;
305 std::shared_ptr<Acts::SpacePointBuilder<StripSP>> spBuilder,
306 const std::array<const InDetDD::SiDetectorElement *,nNeighbours>& elements,
308 const std::array<double, 14>& overlapExtents,
310 std::vector<StripSP>& spacePoints,
311 std::vector<StripSP>& overlapSpacePoints )
const
336 Acts::Vector3
vertex(beamSpotVertex.x(), beamSpotVertex.y(), beamSpotVertex.z());
337 constexpr
int otherSideIndex{1};
338 constexpr
int maxEtaIndex{3};
346 elementIndex[nElements++] =
n;
350 if(!nElements)
return StatusCode::SUCCESS;
354 bool isEndcap = triggerElement->
isEndcap();
355 std::vector<StripInformationHelper> stripInfos;
356 stripInfos.reserve(sourceLinks[0].
size());
358 std::vector<ATLASUncalibSourceLink> triggerSlinks;
359 triggerSlinks.reserve(sourceLinks[0].
size());
362 for (
auto &sourceLink_index : sourceLinks[0]){
363 triggerSlinks.emplace_back(sourceLink_index.first);
372 for (;
n < nElements; ++
n){
373 int currentIndex = elementIndex[
n];
374 if (currentIndex > maxEtaIndex)
381 double min = overlapExtents[currentIndex * 2 - 2];
382 double max = overlapExtents[currentIndex * 2 - 1];
392 for (
auto &sourceLink_index : sourceLinks[currentIndex]){
394 const auto currentSlink = sourceLink_index.first;
395 for (
auto triggerSlink : triggerSlinks){
398 if (diff < min || diff >
max)
400 if (currentIndex == otherSideIndex){
413 for (;
n < nElements; ++
n){
414 int currentIndex = elementIndex[
n];
416 double min = overlapExtents[4 * currentIndex - 10];
417 double max = overlapExtents[4 * currentIndex - 9];
426 std::vector<ATLASUncalibSourceLink> triggerPhiSlinks;
427 triggerSlinks.reserve(triggerSlinks.size());
428 for (
auto triggerSlink : triggerSlinks){
433 size_t stripIndex = 0;
435 centralValue = stripIndex;
440 triggerPhiSlinks.emplace_back(triggerSlink);
443 if (triggerPhiSlinks.empty())
445 min = overlapExtents[4 * currentIndex - 8];
446 max = overlapExtents[4 * currentIndex - 7];
452 for (
auto &sourceLink_index : sourceLinks[currentIndex]){
453 const auto currentSlink = sourceLink_index.first;
455 size_t currentStripIndex = 0;
456 getStripEnds(currentSlink, currentElement, currentStripIndex);
461 centralValue = currentStripIndex;
465 if (centralValue < minValue or centralValue >
maxValue)
467 for (
auto &triggerSlink : triggerPhiSlinks) {
473 return StatusCode::SUCCESS;
477 for (
int n = 0;
n != nElements; ++
n){
479 int currentIndex = elementIndex[
n];
486 for (
auto &sourceLink_index : sourceLinks[currentIndex]){
487 size_t currentStripIndex = 0;
488 getStripEnds(sourceLink_index.first, triggerElement, currentStripIndex);
489 const auto currentSlink = sourceLink_index.first;
491 for (
auto triggerSlink : triggerSlinks){
492 if (currentIndex == otherSideIndex){
502 return StatusCode::SUCCESS;
507 std::vector<StripSP>& collection,
508 std::shared_ptr<Acts::SpacePointBuilder<StripSP>> spBuilder,
515 const Acts::Vector3&
vertex)
const
520 size_t stripIndex = 0;
521 auto ends1 =
getStripEnds(currentSlink, currentElement, stripIndex);
522 auto ends2 =
getStripEnds(anotherSlink, anotherElement, stripIndex);
523 std::pair<Acts::Vector3, Acts::Vector3> ends1_acts;
524 std::pair<Acts::Vector3, Acts::Vector3> ends2_acts;
525 ends1_acts.first = ends1.first;
526 ends1_acts.second = ends1.second;
527 ends2_acts.first = ends2.first;
528 ends2_acts.second = ends2.second;
529 auto paramCovAccessor = [&](
const Acts::SourceLink &slink) {
534 switch (measurement->type()) {
536 loc[Acts::eBoundLoc0] = measurement->localPosition<1>()[
Trk::locX];
537 cov.topLeftCorner<1, 1>() =
538 measurement->localCovariance<1>().cast<
double>();
541 loc[Acts::eBoundLoc0] = measurement->localPosition<2>()[
Trk::locX];
542 loc[Acts::eBoundLoc1] = measurement->localPosition<2>()[
Trk::locY];
543 cov.topLeftCorner<2, 2>() =
544 measurement->localCovariance<2>().cast<
double>();
547 throw std::domain_error(
548 "Can only handle measurement type pixel or strip");
550 return std::make_pair(loc,
cov);
552 std::vector<Acts::SourceLink> slinks;
554 slinks.emplace_back(Acts::SourceLink{currentSlink});
555 slinks.emplace_back(Acts::SourceLink{anotherSlink});
557 Acts::SpacePointBuilderOptions spOpt{std::make_pair(ends1_acts, ends2_acts), paramCovAccessor};
559 spOpt.stripLengthTolerance =
limit - 1;
560 spOpt.stripLengthGapTolerance = slimit;
563 spBuilder->buildSpacePoint(tgContext, slinks, spOpt,
564 std::back_inserter(collection));
565 return StatusCode::SUCCESS;
570 double& stripLengthGapTolerance)
const
581 double x12 =
t1.linear().col(0).dot(
t2.linear().col(0));
582 double r = isAnnulus ?
c.perp() : std::sqrt(
t1(0, 3) *
t1(0, 3) +
t1(1, 3) *
t1(1, 3));
586 double s = dPos.dot(
t1.linear().col(2));
590 double d = isAnnulus ?
dm / 0.04 :
dm / std::sqrt((1. - x12) * (1. + x12));
593 const double zComponentTolerance = 0.7;
594 if (std::abs(
t1(2, 2)) > zComponentTolerance)
595 d *= (
r / std::abs(
t1(2, 3)));
597 stripLengthGapTolerance =
d;
604 double &stripLengthGapTolerance,
605 double &
min,
double &
max)
const
607 double dm =
computeOffset(element1, element2, stripLengthGapTolerance);
633 double radius = firstPosition.xEta();
652 std::pair<Amg::Vector3D, Amg::Vector3D>
655 size_t &stripIndex)
const
660 ATH_MSG_FATAL(
"Could not cast UncalibratedMeasurement as StripCluster");
674 stripIndex = -std::floor(source_local_x / phiPitchPhi) + design->
diodesInRow(0) *0.5 - 0.5;
676 std::pair<Amg::Vector3D, Amg::Vector3D > ends = {
684 std::pair<Amg::Vector3D, Amg::Vector3D> ends(element->
endsOfStrip(localPosition));