6 #include "Acts/Utilities/SpacePointUtility.hpp"
14 #include "Acts/SpacePointFormation/SpacePointBuilderConfig.hpp"
21 std::vector<const Acts::Surface *> &acts_surfaces) {
22 acts_surfaces.reserve(detectorElements.size());
23 for (
const auto *det_el : detectorElements) {
24 const Acts::Surface &surface =
26 acts_surfaces.push_back( &surface );
36 const std::string &
name,
47 return StatusCode::SUCCESS;
55 std::vector<StripSP>& spacePoints,
56 std::vector<StripSP>& overlapSpacePoints,
58 const std::vector<IdentifierHash>& hashesToProcess,
103 auto spBuilderConfig = std::make_shared<Acts::SpacePointBuilderConfig>();
110 spBuilderConfig->slSurfaceAccessor
111 .connect<&ATLASUncalibSourceLinkSurfaceAccessor::operator()>(&surfaceAccessor);
113 const std::shared_ptr<const Acts::TrackingGeometry> trkGeometry =
m_trackingGeometryTool->trackingGeometry();
114 spBuilderConfig->trackingGeometry = trkGeometry;
117 auto spConstructor = [
this, &clusterContainer, &elements](
const Acts::Vector3 &
pos,
118 std::optional<double> ,
119 const Acts::Vector2 &
cov,
120 std::optional<double> ,
121 const boost::container::static_vector<Acts::SourceLink, 2> &slinks)
123 std::vector<std::size_t> measIndices;
124 std::array<StripInformationHelper, 2> stripInfos;
126 for (
const auto& slink : slinks){
132 if (
it != clusterContainer.
end()){
133 const auto cluster_index =
it - clusterContainer.
begin();
134 const auto id = hit->identifierHash();
136 size_t stripIndex = 0;
137 auto ends = this->
getStripEnds(atlasSourceLink, element, stripIndex);
140 measIndices.push_back(cluster_index);
141 stripInfos[
idx++] = std::move(stripInfo);
144 const auto& [firstInfo, secondInfo] = stripInfos;
145 const auto topHalfStripLength = 0.5*firstInfo.stripDirection().norm();
146 Eigen::Matrix<double, 3, 1> topStripDirection = -firstInfo.stripDirection()/(2.*topHalfStripLength);
147 Eigen::Matrix<double, 3, 1> topStripCenter = 0.5*firstInfo.trajDirection();
149 const auto bottomHalfStripLength = 0.5*secondInfo.stripDirection().norm();
150 Eigen::Matrix<double, 3, 1> bottomStripDirection = -secondInfo.stripDirection()/(2.*bottomHalfStripLength);
151 Eigen::Matrix<double, 3, 1> stripCenterDistance = firstInfo.stripCenter() - secondInfo.stripCenter();
154 sp.
idHashes = {firstInfo.idHash(), secondInfo.idHash()};
169 auto spBuilder = std::make_shared<Acts::SpacePointBuilder<StripSP>>(*spBuilderConfig, spConstructor);
171 const auto hashesProc = (hashesToProcess.size() > 0 ? hashesToProcess : stripAccessor.
allIdentifiers());
172 for (
auto &idHash : hashesProc)
179 const std::vector<IdentifierHash>& others = *
properties.neighbours(idHash);
181 if ( others.empty())
continue;
187 size_t neighbour = 0;
188 while (not
search and neighbour < others.size()){
195 std::array<std::vector<std::pair<const xAOD::StripCluster *, size_t>>,
static_cast<size_t>(
nNeighbours)> neighbourClusters{};
196 std::array<std::vector<std::pair<ATLASUncalibSourceLink, size_t>>,
static_cast<size_t>(
nNeighbours)> neighbourSourceLinks{};
197 std::array<const InDetDD::SiDetectorElement *, static_cast<size_t>(
nNeighbours)> neighbourElements{};
199 auto groupStart = clusterContainer.
begin();
201 neighbourElements[0] = thisElement;
203 for (
auto start = this_range.first;
start != this_range.second; ++
start){
205 neighbourClusters[0].push_back(std::make_pair(*
start, position));
206 if ((*start)->identifierHash() != thisElement->
identifyHash()) {
207 throw std::logic_error(
"Identifier mismatch.");
210 neighbourSourceLinks[0].emplace_back(std::make_pair(slink, position));
217 std::array<double, 14> overlapExtents{};
227 if (not processOverlaps)
239 for (
const auto &otherHash : others){
240 if (++
n == Nmax)
break;
247 neighbourElements[neigbourIndices[
n]] = otherElement;
249 for (
auto start = this_range.first;
start != this_range.second; ++
start){
251 neighbourClusters[neigbourIndices[
n]].push_back(std::make_pair(*
start, position));
252 if ((*start)->identifierHash() != otherElement->
identifyHash()) {
253 throw std::logic_error(
"Identifier mismatch.");
256 neighbourSourceLinks[neigbourIndices[
n]].emplace_back(std::make_pair(slink, position));
269 overlapExtents[6] = -hwidth;
272 overlapExtents[9] = hwidth;
278 overlapExtents[11] = hwidth;
279 overlapExtents[12] = -hwidth;
309 spacePoints, overlapSpacePoints) );
312 return StatusCode::SUCCESS;
316 std::shared_ptr<Acts::SpacePointBuilder<StripSP>> spBuilder,
317 std::array<const InDetDD::SiDetectorElement *,nNeighbours> elements,
319 std::array<double, 14> overlapExtents,
321 std::vector<StripSP>& spacePoints,
322 std::vector<StripSP>& overlapSpacePoints )
const
347 Acts::Vector3
vertex(beamSpotVertex.x(), beamSpotVertex.y(), beamSpotVertex.z());
348 constexpr
int otherSideIndex{1};
349 constexpr
int maxEtaIndex{3};
357 elementIndex[nElements++] =
n;
361 if(!nElements)
return StatusCode::SUCCESS;
365 bool isEndcap = triggerElement->
isEndcap();
366 std::vector<StripInformationHelper> stripInfos;
367 stripInfos.reserve(sourceLinks[0].
size());
369 std::vector<ATLASUncalibSourceLink> triggerSlinks;
370 triggerSlinks.reserve(sourceLinks[0].
size());
373 for (
auto &sourceLink_index : sourceLinks[0]){
374 triggerSlinks.emplace_back(sourceLink_index.first);
383 for (;
n < nElements; ++
n){
384 int currentIndex = elementIndex[
n];
385 if (currentIndex > maxEtaIndex)
392 double min = overlapExtents[currentIndex * 2 - 2];
393 double max = overlapExtents[currentIndex * 2 - 1];
403 for (
auto &sourceLink_index : sourceLinks[currentIndex]){
405 const auto currentSlink = sourceLink_index.first;
406 for (
auto triggerSlink : triggerSlinks){
409 if (diff < min || diff >
max)
411 if (currentIndex == otherSideIndex){
424 for (;
n < nElements; ++
n){
425 int currentIndex = elementIndex[
n];
427 double min = overlapExtents[4 * currentIndex - 10];
428 double max = overlapExtents[4 * currentIndex - 9];
437 std::vector<ATLASUncalibSourceLink> triggerPhiSlinks;
438 triggerSlinks.reserve(triggerSlinks.size());
439 for (
auto triggerSlink : triggerSlinks){
444 size_t stripIndex = 0;
446 centralValue = stripIndex;
451 triggerPhiSlinks.emplace_back(triggerSlink);
454 if (triggerPhiSlinks.empty())
456 min = overlapExtents[4 * currentIndex - 8];
457 max = overlapExtents[4 * currentIndex - 7];
463 for (
auto &sourceLink_index : sourceLinks[currentIndex]){
464 const auto currentSlink = sourceLink_index.first;
466 size_t currentStripIndex = 0;
467 getStripEnds(currentSlink, currentElement, currentStripIndex);
472 centralValue = currentStripIndex;
476 if (centralValue < minValue or centralValue >
maxValue)
478 for (
auto &triggerSlink : triggerPhiSlinks) {
484 return StatusCode::SUCCESS;
488 for (
int n = 0;
n != nElements; ++
n){
490 int currentIndex = elementIndex[
n];
497 for (
auto &sourceLink_index : sourceLinks[currentIndex]){
498 size_t currentStripIndex = 0;
499 getStripEnds(sourceLink_index.first, triggerElement, currentStripIndex);
500 const auto currentSlink = sourceLink_index.first;
502 for (
auto triggerSlink : triggerSlinks){
503 if (currentIndex == otherSideIndex){
513 return StatusCode::SUCCESS;
518 std::vector<StripSP>& collection,
519 std::shared_ptr<Acts::SpacePointBuilder<StripSP>> spBuilder,
526 const Acts::Vector3&
vertex)
const
531 size_t stripIndex = 0;
532 auto ends1 =
getStripEnds(currentSlink, currentElement, stripIndex);
533 auto ends2 =
getStripEnds(anotherSlink, anotherElement, stripIndex);
534 std::pair<Acts::Vector3, Acts::Vector3> ends1_acts;
535 std::pair<Acts::Vector3, Acts::Vector3> ends2_acts;
536 ends1_acts.first = ends1.first;
537 ends1_acts.second = ends1.second;
538 ends2_acts.first = ends2.first;
539 ends2_acts.second = ends2.second;
540 auto paramCovAccessor = [&](
const Acts::SourceLink &slink) {
545 switch (measurement->type()) {
547 loc[Acts::eBoundLoc0] = measurement->localPosition<1>()[
Trk::locX];
548 cov.topLeftCorner<1, 1>() =
549 measurement->localCovariance<1>().cast<Acts::ActsScalar>();
552 loc[Acts::eBoundLoc0] = measurement->localPosition<2>()[
Trk::locX];
553 loc[Acts::eBoundLoc1] = measurement->localPosition<2>()[
Trk::locY];
554 cov.topLeftCorner<2, 2>() =
555 measurement->localCovariance<2>().cast<Acts::ActsScalar>();
558 throw std::domain_error(
559 "Can only handle measurement type pixel or strip");
561 return std::make_pair(loc,
cov);
563 std::vector<Acts::SourceLink> slinks;
565 slinks.emplace_back(Acts::SourceLink{currentSlink});
566 slinks.emplace_back(Acts::SourceLink{anotherSlink});
568 Acts::SpacePointBuilderOptions spOpt{std::make_pair(ends1_acts, ends2_acts), paramCovAccessor};
570 spOpt.stripLengthTolerance =
limit - 1;
571 spOpt.stripLengthGapTolerance = slimit;
574 spBuilder->buildSpacePoint(tgContext, slinks, spOpt,
575 std::back_inserter(collection));
576 return StatusCode::SUCCESS;
581 double& stripLengthGapTolerance)
const
592 double x12 =
t1.linear().col(0).dot(
t2.linear().col(0));
593 double r = isAnnulus ?
c.perp() : std::sqrt(
t1(0, 3) *
t1(0, 3) +
t1(1, 3) *
t1(1, 3));
597 double s = dPos.dot(
t1.linear().col(2));
601 double d = isAnnulus ?
dm / 0.04 :
dm / std::sqrt((1. - x12) * (1. + x12));
604 const double zComponentTolerance = 0.7;
605 if (std::abs(
t1(2, 2)) > zComponentTolerance)
606 d *= (
r / std::abs(
t1(2, 3)));
608 stripLengthGapTolerance =
d;
615 double &stripLengthGapTolerance,
616 double &
min,
double &
max)
const
618 double dm =
computeOffset(element1, element2, stripLengthGapTolerance);
644 double radius = firstPosition.xEta();
663 std::pair<Amg::Vector3D, Amg::Vector3D>
666 size_t &stripIndex)
const
671 ATH_MSG_FATAL(
"Could not cast UncalibratedMeasurement as StripCluster");
685 stripIndex = -std::floor(source_local_x / phiPitchPhi) + design->
diodesInRow(0) *0.5 - 0.5;
687 std::pair<Amg::Vector3D, Amg::Vector3D > ends = {
695 std::pair<Amg::Vector3D, Amg::Vector3D> ends(element->
endsOfStrip(localPosition));