ATLAS Offline Software
CoreStripSpacePointFormationTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include "Acts/Utilities/SpacePointUtility.hpp"
14 #include "Acts/SpacePointFormation/SpacePointBuilderConfig.hpp"
17 
18 namespace {
19  void gatherActsSurfaces(const ActsTrk::IActsToTrkConverterTool &converter_tool,
20  const InDetDD::SiDetectorElementCollection &detectorElements,
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 =
25  converter_tool.trkSurfaceToActsSurface(det_el->surface());
26  acts_surfaces.push_back( &surface );
27  }
28  }
29 }
30 
31 #include "StoreGate/WriteHandle.h"
32 namespace ActsTrk
33 {
34 
36  const std::string &name,
37  const IInterface *parent)
38  : base_class(type, name, parent)
39  {}
40 
42 
43  ATH_CHECK(detStore()->retrieve(m_stripId, "SCT_ID"));
44  ATH_CHECK(m_lorentzAngleTool.retrieve());
46  ATH_CHECK(m_ATLASConverterTool.retrieve());
47  return StatusCode::SUCCESS;
48  }
49 
51  const xAOD::StripClusterContainer &clusterContainer,
54  const Amg::Vector3D &beamSpotVertex,
55  std::vector<StripSP>& spacePoints,
56  std::vector<StripSP>& overlapSpacePoints,
57  bool processOverlaps,
58  const std::vector<IdentifierHash>& hashesToProcess,
60  {
65 
99 
102 
103  auto spBuilderConfig = std::make_shared<Acts::SpacePointBuilderConfig>();
104  TrackingSurfaceHelper tracking_surface_helper;
105  gatherActsSurfaces(*m_ATLASConverterTool, elements, tracking_surface_helper.actsSurfaces(xAOD::UncalibMeasType::StripClusterType));
106  tracking_surface_helper.setSiDetectorElements(xAOD::UncalibMeasType::StripClusterType, &elements);
107 
108  ATLASUncalibSourceLinkSurfaceAccessor surfaceAccessor{ &(*m_ATLASConverterTool), &tracking_surface_helper };
109 
110  spBuilderConfig->slSurfaceAccessor
111  .connect<&ATLASUncalibSourceLinkSurfaceAccessor::operator()>(&surfaceAccessor);
112 
113  const std::shared_ptr<const Acts::TrackingGeometry> trkGeometry = m_trackingGeometryTool->trackingGeometry();
114  spBuilderConfig->trackingGeometry = trkGeometry;
115 
116 
117  auto spConstructor = [this, &clusterContainer, &elements](const Acts::Vector3 &pos,
118  std::optional<double> /*t*/,
119  const Acts::Vector2 &cov,
120  std::optional<double> /*varT*/,
121  const boost::container::static_vector<Acts::SourceLink, 2> &slinks)
122  -> StripSP{
123  std::vector<std::size_t> measIndices;
124  std::array<StripInformationHelper, 2> stripInfos;
125  size_t idx = 0;
126  for (const auto& slink : slinks){
127  const auto& atlasSourceLink = slink.get<ATLASUncalibSourceLink>();
128  const xAOD::UncalibratedMeasurement *hit = &getUncalibratedMeasurement(atlasSourceLink);
129 
130  // Check if the cluster is in the cluster container
131  const auto it = std::find(clusterContainer.begin(), clusterContainer.end(), dynamic_cast<const xAOD::StripCluster*>(hit));
132  if (it != clusterContainer.end()){
133  const auto cluster_index = it - clusterContainer.begin();
134  const auto id = hit->identifierHash();
135  const auto &element = elements.getDetectorElement(id);
136  size_t stripIndex = 0;
137  auto ends = this->getStripEnds(atlasSourceLink, element, stripIndex);
138  auto vertex = Amg::Vector3D(0,0,0);
139  StripInformationHelper stripInfo(id,ends.first, ends.second, vertex, ActsTrk::localXFromSourceLink(atlasSourceLink), cluster_index, stripIndex);
140  measIndices.push_back(cluster_index);
141  stripInfos[idx++] = std::move(stripInfo);
142  }
143  }
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();
148 
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();
152 
153  StripSP sp;
154  sp.idHashes = {firstInfo.idHash(), secondInfo.idHash()};
155  sp.globPos = pos.cast<float>();
156  sp.cov_r = cov(0,0);
157  sp.cov_z = cov(1,0);
158  sp.measurementIndexes = measIndices;
159  sp.topHalfStripLength = topHalfStripLength;
160  sp.bottomHalfStripLength = bottomHalfStripLength;
161  sp.topStripDirection = topStripDirection.cast<float>();
162  sp.bottomStripDirection = bottomStripDirection.cast<float>();
163  sp.stripCenterDistance = stripCenterDistance.cast<float>();
164  sp.topStripCenter = topStripCenter.cast<float>();
165 
166  return sp;
167  };
168 
169  auto spBuilder = std::make_shared<Acts::SpacePointBuilder<StripSP>>(*spBuilderConfig, spConstructor);
170 
171  const auto hashesProc = (hashesToProcess.size() > 0 ? hashesToProcess : stripAccessor.allIdentifiers());
172  for (auto &idHash : hashesProc)
173  {
174  const InDetDD::SiDetectorElement *thisElement = elements.getDetectorElement(idHash);
175  if (thisElement->isStereo())
176  continue;
177 
178  // Retrieve the neighbours of the detector element
179  const std::vector<IdentifierHash>& others = *properties.neighbours(idHash);
180 
181  if ( others.empty()) continue;
182 
183  // This flag is use to trigger if the search should be performed.
184  // In case there are no clusters on the neighbours of the selected
185  // detector element, the flag stays false.
186  bool search = false;
187  size_t neighbour = 0;
188  while (not search and neighbour < others.size()){
189  search = stripAccessor.isIdentifierPresent( others.at(neighbour) );
190  neighbour++;
191  }
192  if (not search) continue;
193 
194  // prepare clusters, indices and modules for space point formation
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{};
198 
199  auto groupStart = clusterContainer.begin();
200  // Get the detector element and range for the idHash
201  neighbourElements[0] = thisElement;
202  for (auto &this_range : stripAccessor.rangesForIdentifierDirect(idHash)){
203  for (auto start = this_range.first; start != this_range.second; ++start){
204  size_t position = std::distance(groupStart, start);
205  neighbourClusters[0].push_back(std::make_pair(*start, position));
206  if ((*start)->identifierHash() != thisElement->identifyHash()) {
207  throw std::logic_error("Identifier mismatch.");
208  }
209  auto slink = makeATLASUncalibSourceLink(&clusterContainer, (*start)->index());
210  neighbourSourceLinks[0].emplace_back(std::make_pair(slink, position));
211  }
212  }
213 
214  Identifier thisId = thisElement->identify();
215 
216  // define overlap extends before building space points
217  std::array<double, 14> overlapExtents{};
218  // Default case: you test the opposite element and the overlapping in phi (total 3 elements)
219  int Nmax = 4;
220 
221  // In the barrel, test the eta overlaps as well (total 5 elements)
222  if (m_stripId->is_barrel(thisId))
223  Nmax = 6;
224 
225  // You can remove all the overlaps if requested.
226  // Here you test only the opposite element
227  if (not processOverlaps)
228  Nmax = 2;
229 
230  float hwidth(properties.halfWidth(idHash));
231  int n = 0;
232 
233  // The order of the elements in others is such that you first get the opposite element,
234  // the overlapping in phi and then the overlapping in eta
235  // For this reason you need to re-order the indices, since the SiSpacePointMakerTool will process
236  // first the eta overlaps and then the phi ones
237  const std::array<size_t, nNeighbours> neigbourIndices{ThisOne, Opposite, EtaMinus, EtaPlus, PhiMinus, PhiPlus};
238 
239  for (const auto &otherHash : others){
240  if (++n == Nmax) break;
241 
242  if (not stripAccessor.isIdentifierPresent(otherHash))
243  continue;
244 
245  const InDetDD::SiDetectorElement *otherElement = elements.getDetectorElement(otherHash);
246 
247  neighbourElements[neigbourIndices[n]] = otherElement;
248  for (auto &this_range : stripAccessor.rangesForIdentifierDirect(otherHash)){
249  for (auto start = this_range.first; start != this_range.second; ++start){
250  size_t position = std::distance(groupStart, 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.");
254  }
255  auto slink = makeATLASUncalibSourceLink(&clusterContainer, (*start)->index());
256  neighbourSourceLinks[neigbourIndices[n]].emplace_back(std::make_pair(slink, position));
257  }
258  }
259 
260  switch (n){
261  case Opposite:
262  {
263  overlapExtents[0] = -m_overlapLimitOpposite;
264  overlapExtents[1] = m_overlapLimitOpposite;
265  break;
266  }
267  case PhiMinus:
268  {
269  overlapExtents[6] = -hwidth;
270  overlapExtents[7] = -hwidth + m_overlapLimitPhi;
271  overlapExtents[8] = hwidth - m_overlapLimitPhi;
272  overlapExtents[9] = hwidth;
273  break;
274  }
275  case PhiPlus:
276  {
277  overlapExtents[10] = hwidth - m_overlapLimitPhi;
278  overlapExtents[11] = hwidth;
279  overlapExtents[12] = -hwidth;
280  overlapExtents[13] = -hwidth + m_overlapLimitPhi;
281  break;
282  }
283  case EtaMinus:
284  {
285  if ((m_stripId->layer_disk(thisId) & 1) == 0){
286  overlapExtents[2] = m_overlapLimitEtaMin;
287  overlapExtents[3] = m_overlapLimitEtaMax;
288  } else{
289  overlapExtents[2] = -m_overlapLimitEtaMax;
290  overlapExtents[3] = -m_overlapLimitEtaMin;
291  }
292  break;
293  }
294  default:
295  {
296  if ((m_stripId->layer_disk(thisId) & 1) == 0){
297  overlapExtents[4] = -m_overlapLimitEtaMax;
298  overlapExtents[5] = -m_overlapLimitEtaMin;
299  } else {
300  overlapExtents[4] = m_overlapLimitEtaMin;
301  overlapExtents[5] = m_overlapLimitEtaMax;
302  }
303  break;
304  }
305  }
306  }
307 
308  ATH_CHECK( fillSpacePoints(ctx, spBuilder, neighbourElements, neighbourSourceLinks, overlapExtents, beamSpotVertex,
309  spacePoints, overlapSpacePoints) );
310  }
311 
312  return StatusCode::SUCCESS;
313  }
314 
316  std::shared_ptr<Acts::SpacePointBuilder<StripSP>> spBuilder,
317  std::array<const InDetDD::SiDetectorElement *,nNeighbours> elements,
318  std::array<std::vector<std::pair<ATLASUncalibSourceLink, size_t>>,nNeighbours> sourceLinks,
319  std::array<double, 14> overlapExtents,
320  const Amg::Vector3D &beamSpotVertex,
321  std::vector<StripSP>& spacePoints,
322  std::vector<StripSP>& overlapSpacePoints ) const
323  {
324  // This function is called once all the needed quantities are collected.
325  // It is used to build space points checking the compatibility of clusters on pairs of detector elements.
326  // Detector elements and cluster collections are elements and clusters, respectively.
327  // [0] is the trigger element
328  // [1] is the opposite element
329  // [2]-[3] are the elements tested for eta overlaps
330  // [4]-[5] are the elements tested for phi overlaps
331  //
332  // To build space points:
333  // - For the opposite element and the ones tested for eta overlaps, you have to check
334  // if clusters are compatible with the local position of the trigger cluster
335  // requiring that the distance between the two clusters in phi is withing a specified range.
336  // - overlapExtents[0], overlapExtents[1] are filled for the opposite element
337  // - overlapExtents[2], overlapExtents[3], overlapExtents[4], overlapExtents[5] are filled for the eta overlapping elements
338  // - For the elements tested for phi overlaps, you have to check
339  // if clusters are compatible with the local position of the trigger cluster.
340  // This needs that the trigger cluster is at the edge of the trigger module
341  // and that the other cluster is on the compatible edge of its module
342  // - overlapExtents[6], overlapExtents[7], overlapExtents[10], overlapExtents[11]
343  // overlapExtents[8], overlapExtents[9], overlapExtents[12], overlapExtents[13] are filled for the phi overlapping elements
344 
345 
346 
347  Acts::Vector3 vertex(beamSpotVertex.x(), beamSpotVertex.y(), beamSpotVertex.z());
348  constexpr int otherSideIndex{1};
349  constexpr int maxEtaIndex{3};
350  std::array<int,nNeighbours - 1> elementIndex{};
351  int nElements = 0;
352 
353  // For the nNeighbours sides, fill elementIndex with the indices of the existing elements.
354  // Same the number of elements in nElements to loop on the later on
355  for (int n = 1; n != nNeighbours; ++n) {
356  if (elements[n]){
357  elementIndex[nElements++] = n;
358  }
359  }
360  // return if all detector elements are nullptr
361  if(!nElements) return StatusCode::SUCCESS;
362 
363  const InDetDD::SiDetectorElement *triggerElement = elements[0];
364 
365  bool isEndcap = triggerElement->isEndcap();
366  std::vector<StripInformationHelper> stripInfos;
367  stripInfos.reserve(sourceLinks[0].size());
368 
369  std::vector<ATLASUncalibSourceLink> triggerSlinks;
370  triggerSlinks.reserve(sourceLinks[0].size());
371 
372  // loop on all clusters on the trigger detector element and save the related information
373  for (auto &sourceLink_index : sourceLinks[0]){
374  triggerSlinks.emplace_back(sourceLink_index.first);
375  }
376 
377  double limit = 1. + m_stripLengthTolerance;
378  double slimit = 0.;
379 
380  if (not m_allClusters){
381  // Start processing the opposite side and the eta overlapping elements
382  int n = 0;
383  for (; n < nElements; ++n){
384  int currentIndex = elementIndex[n];
385  if (currentIndex > maxEtaIndex)
386  break;
387 
388  // get the detector element and the IdentifierHash
389  const InDetDD::SiDetectorElement *currentElement = elements[currentIndex];
390 
391  // retrieve the range
392  double min = overlapExtents[currentIndex * 2 - 2];
393  double max = overlapExtents[currentIndex * 2 - 1];
394 
395  size_t minStrip, maxStrip = 0;
396 
397  if (m_stripGapParameter != 0.){
398  updateRange(*triggerElement, *currentElement, slimit, min, max);
399  correctPolarRange(triggerElement, min, max, minStrip, maxStrip);
400  }
401 
402  StripInformationHelper currentStripInfo;
403  for (auto &sourceLink_index : sourceLinks[currentIndex]){
404  float source_local_x = ActsTrk::localXFromSourceLink( sourceLink_index.first );
405  const auto currentSlink = sourceLink_index.first;
406  for (auto triggerSlink : triggerSlinks){
407 
408  double diff = source_local_x - ActsTrk::localXFromSourceLink( triggerSlink );
409  if (diff < min || diff > max)
410  continue;
411  if (currentIndex == otherSideIndex){
412  ATH_CHECK( makeSpacePoint(ctx, spacePoints, spBuilder, triggerSlink, currentSlink, triggerElement,
413  currentElement, limit, slimit, vertex));
414 
415  } else {
416  ATH_CHECK(makeSpacePoint(ctx, overlapSpacePoints, spBuilder, triggerSlink, currentSlink, triggerElement,
417  currentElement, limit, slimit, vertex));
418  }
419  }
420  }
421  }
422  // process the phi overlapping elements
423  // if possible n starts from 4
424  for (; n < nElements; ++n){
425  int currentIndex = elementIndex[n];
426  const InDetDD::SiDetectorElement *currentElement = elements[currentIndex];
427  double min = overlapExtents[4 * currentIndex - 10];
428  double max = overlapExtents[4 * currentIndex - 9];
429 
430  size_t minStrip, maxStrip = 0;
431 
432  if (m_stripGapParameter != 0.){
433  updateRange(*triggerElement, *currentElement, slimit, min, max);
434  correctPolarRange(triggerElement, min, max, minStrip, maxStrip);
435  }
436 
437  std::vector<ATLASUncalibSourceLink> triggerPhiSlinks;
438  triggerSlinks.reserve(triggerSlinks.size());
439  for (auto triggerSlink : triggerSlinks){
440  auto centralValue = ActsTrk::localXFromSourceLink( triggerSlink );
441  auto minValue = min;
442  auto maxValue = max;
443  if (isEndcap){
444  size_t stripIndex = 0;
445  getStripEnds(triggerSlink, triggerElement, stripIndex);
446  centralValue = stripIndex;
447  minValue = minStrip;
448  maxValue = maxStrip;
449  }
450  if (minValue <= centralValue and centralValue <= maxValue){
451  triggerPhiSlinks.emplace_back(triggerSlink);
452  }
453  }
454  if (triggerPhiSlinks.empty())
455  continue;
456  min = overlapExtents[4 * currentIndex - 8];
457  max = overlapExtents[4 * currentIndex - 7];
458  if (m_stripGapParameter != 0.){
459  updateRange(*triggerElement, *currentElement, slimit, min, max);
460  correctPolarRange(currentElement, min, max, minStrip, maxStrip);
461  }
462 
463  for (auto &sourceLink_index : sourceLinks[currentIndex]){
464  const auto currentSlink = sourceLink_index.first;
465 
466  size_t currentStripIndex = 0;
467  getStripEnds(currentSlink, currentElement, currentStripIndex);
468  auto centralValue = ActsTrk::localXFromSourceLink( sourceLink_index.first );
469  auto minValue = min;
470  auto maxValue = max;
471  if (isEndcap) {
472  centralValue = currentStripIndex;
473  minValue = minStrip;
474  maxValue = maxStrip;
475  }
476  if (centralValue < minValue or centralValue > maxValue)
477  continue;
478  for (auto &triggerSlink : triggerPhiSlinks) {
479  ATH_CHECK(makeSpacePoint(ctx, overlapSpacePoints, spBuilder, triggerSlink, currentSlink, triggerElement,
480  currentElement, limit, slimit, vertex));
481  }
482  }
483  }
484  return StatusCode::SUCCESS;
485 
486  } // not m_allClusters
487 
488  for (int n = 0; n != nElements; ++n){
489 
490  int currentIndex = elementIndex[n];
491  const InDetDD::SiDetectorElement *currentElement = elements[currentIndex];
492 
493  if (m_stripGapParameter != 0.){
494  computeOffset(*triggerElement, *currentElement, slimit);
495  }
496 
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;
501 
502  for (auto triggerSlink : triggerSlinks){
503  if (currentIndex == otherSideIndex){
504  ATH_CHECK(makeSpacePoint(ctx, spacePoints, spBuilder, triggerSlink, currentSlink, triggerElement,
505  currentElement, limit, slimit, vertex));
506  }else{
507  ATH_CHECK(makeSpacePoint(ctx, overlapSpacePoints, spBuilder, triggerSlink, currentSlink, triggerElement,
508  currentElement, limit, slimit, vertex));
509  }
510  }
511  }
512  }
513  return StatusCode::SUCCESS;
514  }
515 
516 
518  std::vector<StripSP>& collection,
519  std::shared_ptr<Acts::SpacePointBuilder<StripSP>> spBuilder,
520  const ATLASUncalibSourceLink& currentSlink,
521  const ATLASUncalibSourceLink& anotherSlink,
522  const InDetDD::SiDetectorElement *currentElement,
523  const InDetDD::SiDetectorElement *anotherElement,
524  const double limit,
525  const double slimit,
526  const Acts::Vector3& vertex) const
527  {
528 
529  auto tgContext = m_trackingGeometryTool->getGeometryContext(ctx).context();
530 
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) {
541  const auto &atlasSLink = slink.get<ATLASUncalibSourceLink>();
542  const xAOD::UncalibratedMeasurement *measurement = &getUncalibratedMeasurement(atlasSLink);
543  Acts::BoundVector loc = Acts::BoundVector::Zero();
544  Acts::BoundSquareMatrix cov = Acts::BoundMatrix::Zero();
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>();
550  break;
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>();
556  break;
557  default:
558  throw std::domain_error(
559  "Can only handle measurement type pixel or strip");
560  }
561  return std::make_pair(loc, cov);
562  };
563  std::vector<Acts::SourceLink> slinks;
564 
565  slinks.emplace_back(Acts::SourceLink{currentSlink});
566  slinks.emplace_back(Acts::SourceLink{anotherSlink});
567 
568  Acts::SpacePointBuilderOptions spOpt{std::make_pair(ends1_acts, ends2_acts), paramCovAccessor};
569  spOpt.vertex = vertex;
570  spOpt.stripLengthTolerance = limit - 1;
571  spOpt.stripLengthGapTolerance = slimit;
572 
573 
574  spBuilder->buildSpacePoint(tgContext, slinks, spOpt,
575  std::back_inserter(collection));
576  return StatusCode::SUCCESS;
577  }
578 
580  const InDetDD::SiDetectorElement& element2,
581  double& stripLengthGapTolerance) const
582 {
583  // Get transformation matrices and center positions of detector elements
584  const Amg::Transform3D& t1 = element1.transform();
585  const Amg::Transform3D& t2 = element2.transform();
586  const Amg::Vector3D& c = element1.center();
587 
588  // Check if first element is an annulus
589  bool isAnnulus = (element1.design().shape() == InDetDD::Annulus);
590 
591  // Compute x12 and radius of detector element
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));
594 
595  // Compute distance between detector elements in the direction of strips
596  Amg::Vector3D dPos = t1.translation() - t2.translation();
597  double s = dPos.dot(t1.linear().col(2));
598 
599  // Compute offset distance
600  double dm = (m_stripGapParameter * r) * std::abs(s * x12);
601  double d = isAnnulus ? dm / 0.04 : dm / std::sqrt((1. - x12) * (1. + x12));
602 
603  // Adjust offset distance for z-component of transformation matrix
604  const double zComponentTolerance = 0.7;
605  if (std::abs(t1(2, 2)) > zComponentTolerance)
606  d *= (r / std::abs(t1(2, 3)));
607 
608  stripLengthGapTolerance = d;
609 
610  return dm;
611 }
612 
614  const InDetDD::SiDetectorElement &element2,
615  double &stripLengthGapTolerance,
616  double &min, double &max) const
617  {
618  double dm = computeOffset(element1, element2, stripLengthGapTolerance);
619  min -= dm;
620  max += dm;
621  }
622 
624  double &min,
625  double &max,
626  size_t &minStrip,
627  size_t &maxStrip) const
628  {
629  if (element->isBarrel())
630  return;
631 
632  // design for endcap modules
633  const InDetDD::StripStereoAnnulusDesign *design = dynamic_cast<const InDetDD::StripStereoAnnulusDesign *>(&element->design());
634  if (!design){
635  ATH_MSG_FATAL("Invalid strip annulus design for module with identifier/identifierHash " << element->identify() << "/" << element->identifyHash());
636  return;
637  }
638 
639  // converting min and max from cartesian reference frame to polar frame
640  auto firstPosition = (design->localPositionOfCell(design->strip1Dim(0, 0)) +
641  design->localPositionOfCell(design->strip1Dim(design->diodesInRow(0) - 1, 0))) *
642  0.5;
643 
644  double radius = firstPosition.xEta();
645 
648 
649  if (not minCellId.isValid())
650  minCellId = InDetDD::SiCellId(0);
651 
652  if (not maxCellId.isValid())
653  maxCellId = InDetDD::SiCellId(design->diodesInRow(0) - 1);
654 
655  minStrip = minCellId.strip();
656  maxStrip = maxCellId.strip();
657 
658  // re-evaluate min and max in polar coordinate
659  min = std::atan2(min, radius);
660  max = std::atan2(max, radius);
661  }
662 
663  std::pair<Amg::Vector3D, Amg::Vector3D>
665  const InDetDD::SiDetectorElement *element,
666  size_t &stripIndex) const
667  {
668  const xAOD::UncalibratedMeasurement &measurement = getUncalibratedMeasurement(sourceLink);
669  auto cluster = dynamic_cast<const xAOD::StripCluster *>(&measurement);
670  if(!cluster){
671  ATH_MSG_FATAL("Could not cast UncalibratedMeasurement as StripCluster");
672  return {};
673  }
674  float source_local_x = ActsTrk::localXFromSourceLink( sourceLink );
675  if (element->isEndcap()) {
676  // design for endcap modules
677  const InDetDD::StripStereoAnnulusDesign *design = dynamic_cast<const InDetDD::StripStereoAnnulusDesign *>(&element->design());
678  if (!design){
679  ATH_MSG_FATAL("Invalid strip annulus design for module with identifier/identifierHash " << element->identify() << "/" << element->identifyHash());
680  return {};
681  }
682 
683  // calculate phi pitch for evaluating the strip index
684  double phiPitchPhi = design->phiWidth()/design->diodesInRow(0);
685  stripIndex = -std::floor(source_local_x / phiPitchPhi) + design->diodesInRow(0) *0.5 - 0.5;
686 
687  std::pair<Amg::Vector3D, Amg::Vector3D > ends = {
688  element->globalPosition(design->stripPosAtR(stripIndex, 0, design->minR())),
689  element->globalPosition(design->stripPosAtR(stripIndex, 0, design->maxR()))
690  };
691  return ends;
692  }
693 
694  InDetDD::SiLocalPosition localPosition(0., source_local_x, 0.);
695  std::pair<Amg::Vector3D, Amg::Vector3D> ends(element->endsOfStrip(localPosition));
696  return ends;
697  }
698 
699 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
TrackingSurfaceHelper
Simple helper class which allows to access the tracking surface associated to a certain (Si-)measurem...
Definition: TrackingSurfaceHelper.h:17
beamspotman.r
def r
Definition: beamspotman.py:676
ActsTrk::EtaMinus
@ EtaMinus
Definition: StripInformationHelper.h:13
ActsTrk::StripSP::cov_z
float cov_z
Definition: IStripSpacePointFormationTool.h:24
InDetDD::SiDetectorElement::isEndcap
bool isEndcap() const
ActsTrk::CoreStripSpacePointFormationTool::m_stripLengthTolerance
Gaudi::Property< float > m_stripLengthTolerance
Definition: CoreStripSpacePointFormationTool.h:110
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
SCT_ID.h
This is an Identifier helper class for the SCT subdetector. This class is a factory for creating comp...
InDetDD::SolidStateDetectorElementBase::cellIdOfPosition
SiCellId cellIdOfPosition(const Amg::Vector2D &localPos) const
As in previous method but returns SiCellId.
Definition: SolidStateDetectorElementBase.cxx:224
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
ActsTrk::StripSP
Definition: IStripSpacePointFormationTool.h:18
maxValue
#define maxValue(current, test)
Definition: CompoundLayerMaterialCreator.h:22
max
#define max(a, b)
Definition: cfImp.cxx:41
ContainerAccessor
Definition: ContainerAccessor.h:25
InDetDD::SiDetectorElementCollection
Definition: SiDetectorElementCollection.h:30
InDetDD::StripStereoAnnulusDesign::strip1Dim
virtual int strip1Dim(int strip, int row) const override
only relevant for SCT.
Definition: StripStereoAnnulusDesign.cxx:294
ContainerAccessor::allIdentifiers
std::vector< identifier_t > allIdentifiers() const
Function to return all available identifier (i.e. keys in the map)
Definition: ContainerAccessor.h:84
Trk::locX
@ locX
Definition: ParamDefs.h:43
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:44
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
xAOD::UncalibMeasType::StripClusterType
@ StripClusterType
hist_file_dump.d
d
Definition: hist_file_dump.py:137
InDetDD::DetectorDesign::shape
virtual DetectorShape shape() const
Shape of element.
Definition: DetectorDesign.cxx:96
InDetDD::SolidStateDetectorElementBase::center
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
ActsTrk::ATLASUncalibSourceLinkSurfaceAccessor
Definition: ATLASSourceLinkSurfaceAccessor.h:24
InDetDD::SiCellId::isValid
bool isValid() const
Test if its in a valid state.
Definition: SiCellId.h:136
ALFA_EventTPCnv_Dict::t1
std::vector< ALFA_RawDataCollection_p1 > t1
Definition: ALFA_EventTPCnvDict.h:43
skel.it
it
Definition: skel.GENtoEVGEN.py:423
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
TrackingSurfaceHelper::setSiDetectorElements
void setSiDetectorElements(xAOD::UncalibMeasType type, const InDetDD::SiDetectorElementCollection *det_element_collection)
Definition: TrackingSurfaceHelper.h:29
mc.diff
diff
Definition: mc.SFGenPy8_MuMu_DD.py:14
ActsTrk::StripSP::measurementIndexes
std::vector< std::size_t > measurementIndexes
Definition: IStripSpacePointFormationTool.h:25
InDetDD::StripStereoAnnulusDesign::phiWidth
double phiWidth() const
Definition: StripStereoAnnulusDesign.h:331
ActsTrk::localXFromSourceLink
float localXFromSourceLink(const ATLASUncalibSourceLink &source_link)
Definition: ATLASSourceLink.h:54
ActsTrk::StripSP::topStripDirection
Eigen::Matrix< float, 3, 1 > topStripDirection
Definition: IStripSpacePointFormationTool.h:28
ISiLorentzAngleTool.h
InDetDD::SiCellId::strip
int strip() const
Get strip number. Equivalent to phiIndex().
Definition: SiCellId.h:131
ActsTrk::Opposite
@ Opposite
Definition: StripInformationHelper.h:13
TrackingSurfaceHelper::actsSurfaces
std::vector< const Acts::Surface * > & actsSurfaces(xAOD::UncalibMeasType type)
Definition: TrackingSurfaceHelper.h:25
ActsTrk::EtaPlus
@ EtaPlus
Definition: StripInformationHelper.h:13
ActsTrk::CoreStripSpacePointFormationTool::getStripEnds
std::pair< Amg::Vector3D, Amg::Vector3D > getStripEnds(const xAOD::StripCluster *cluster, const InDetDD::SiDetectorElement *element, size_t &stripIndex) const
search
void search(TDirectory *td, const std::string &s, std::string cwd, node *n)
recursive directory search for TH1 and TH2 and TProfiles
Definition: hcg.cxx:738
ActsTrk::StripSP::cov_r
float cov_r
Definition: IStripSpacePointFormationTool.h:23
InDetDD::SolidStateDetectorElementBase::identifyHash
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
ActsTrk::StripInformationHelper
Definition: StripInformationHelper.h:15
ActsTrk::StripSP::globPos
Eigen::Matrix< float, 3, 1 > globPos
Definition: IStripSpacePointFormationTool.h:22
InDetDD::SiLocalPosition
Definition: SiLocalPosition.h:31
InDetDD::StripStereoAnnulusDesign::diodesInRow
virtual int diodesInRow(const int row) const override
Definition: StripStereoAnnulusDesign.h:251
ActsTrk::IActsToTrkConverterTool::trkSurfaceToActsSurface
virtual const Acts::Surface & trkSurfaceToActsSurface(const Trk::Surface &atlasSurface) const =0
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
WriteHandle.h
Handle class for recording to StoreGate.
InDetDD::StripStereoAnnulusDesign::stripPosAtR
SiLocalPosition stripPosAtR(int strip, int row, double r) const
Definition: StripStereoAnnulusDesign.cxx:385
ContainerAccessor::rangesForIdentifierDirect
const boost::container::small_vector< Range, inline_size > rangesForIdentifierDirect(const identifier_t &identifier) const
Function to return the list of ranges corresponding to a given identifier.
Definition: ContainerAccessor.h:69
xAOD::UncalibratedMeasurement_v1
Definition: UncalibratedMeasurement_v1.h:13
ActsTrk::CoreStripSpacePointFormationTool::makeSpacePoint
StatusCode makeSpacePoint(const EventContext &ctx, std::vector< StripSP > &collection, std::shared_ptr< Acts::SpacePointBuilder< StripSP >> spBuilder, const ATLASUncalibSourceLink &currentSlink, const ATLASUncalibSourceLink &anotherSlink, const InDetDD::SiDetectorElement *currentElement, const InDetDD::SiDetectorElement *anotherElement, const double limit, const double slimit, const Acts::Vector3 &vertex) const
Definition: CoreStripSpacePointFormationTool.cxx:517
ActsTrk::makeATLASUncalibSourceLink
ATLASUncalibSourceLink makeATLASUncalibSourceLink(const xAOD::UncalibratedMeasurementContainer *container, std::size_t index, [[maybe_unused]] const EventContext &ctx)
Definition: ATLASSourceLink.h:31
InDetDD::StripStereoAnnulusDesign::minR
double minR() const
Definition: StripStereoAnnulusDesign.h:322
ActsTrk::StripSP::topHalfStripLength
float topHalfStripLength
Definition: IStripSpacePointFormationTool.h:26
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
InDetDD::Annulus
@ Annulus
Definition: DetectorDesign.h:42
InDetDD::StripStereoAnnulusDesign
Definition: StripStereoAnnulusDesign.h:50
ActsTrk::CoreStripSpacePointFormationTool::initialize
virtual StatusCode initialize() override
Definition: CoreStripSpacePointFormationTool.cxx:41
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
ActsTrk::IActsToTrkConverterTool
Definition: IActsToTrkConverterTool.h:43
ActsTrk::CoreStripSpacePointFormationTool::m_stripId
const SCT_ID * m_stripId
Definition: CoreStripSpacePointFormationTool.h:99
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ActsTrk::CoreStripSpacePointFormationTool::produceSpacePoints
virtual StatusCode produceSpacePoints(const EventContext &ctx, const xAOD::StripClusterContainer &clusterContainer, const InDet::SiElementPropertiesTable &properties, const InDetDD::SiDetectorElementCollection &elements, const Amg::Vector3D &beamSpotVertex, std::vector< StripSP > &spacePoints, std::vector< StripSP > &overlapSpacePoints, bool processOverlaps, const std::vector< IdentifierHash > &hashesToProcess, const ContainerAccessor< xAOD::StripCluster, IdentifierHash, 1 > &stripAccessor) const override
Definition: CoreStripSpacePointFormationTool.cxx:50
xAOD::StripCluster_v1
Definition: StripCluster_v1.h:17
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ActsTrk::PhiPlus
@ PhiPlus
Definition: StripInformationHelper.h:13
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
ReadCellNoiseFromCool.dm
dm
Definition: ReadCellNoiseFromCool.py:235
ActsTrk::StripSP::bottomHalfStripLength
float bottomHalfStripLength
Definition: IStripSpacePointFormationTool.h:27
python.JsonUtils.properties
properties
Definition: JsonUtils.py:96
min
#define min(a, b)
Definition: cfImp.cxx:40
ActsTrk::CoreStripSpacePointFormationTool::m_overlapLimitPhi
Gaudi::Property< float > m_overlapLimitPhi
Definition: CoreStripSpacePointFormationTool.h:107
lumiFormat.array
array
Definition: lumiFormat.py:98
ActsTrk::StripSP::bottomStripDirection
Eigen::Matrix< float, 3, 1 > bottomStripDirection
Definition: IStripSpacePointFormationTool.h:29
ActsTrk::CoreStripSpacePointFormationTool::m_overlapLimitOpposite
Gaudi::Property< float > m_overlapLimitOpposite
Definition: CoreStripSpacePointFormationTool.h:106
ActsTrk::CoreStripSpacePointFormationTool::m_overlapLimitEtaMin
Gaudi::Property< float > m_overlapLimitEtaMin
Definition: CoreStripSpacePointFormationTool.h:108
ActsTrk::CoreStripSpacePointFormationTool::m_overlapLimitEtaMax
Gaudi::Property< float > m_overlapLimitEtaMax
Definition: CoreStripSpacePointFormationTool.h:109
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
InDetDD::SiDetectorElement::endsOfStrip
std::pair< Amg::Vector3D, Amg::Vector3D > endsOfStrip(const Amg::Vector2D &position) const
Special method for SCT to retrieve the two ends of a "strip" Returned coordinates are in global frame...
Definition: SiDetectorElement.cxx:339
ActsTrk::CoreStripSpacePointFormationTool::m_allClusters
Gaudi::Property< bool > m_allClusters
Definition: CoreStripSpacePointFormationTool.h:105
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
ActsTrk::CoreStripSpacePointFormationTool::CoreStripSpacePointFormationTool
CoreStripSpacePointFormationTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: CoreStripSpacePointFormationTool.cxx:35
ActsTrk::CoreStripSpacePointFormationTool::m_stripGapParameter
Gaudi::Property< float > m_stripGapParameter
Definition: CoreStripSpacePointFormationTool.h:111
ActsTrk::getUncalibratedMeasurement
const xAOD::UncalibratedMeasurement & getUncalibratedMeasurement(const ATLASUncalibSourceLink &source_link)
Definition: ATLASSourceLink.h:27
SCT_ID::layer_disk
int layer_disk(const Identifier &id) const
Definition: SCT_ID.h:734
dumpNswErrorDb.maxStrip
tuple maxStrip
Definition: dumpNswErrorDb.py:27
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
InDet::SiElementPropertiesTable
Definition: SiElementPropertiesTable.h:30
InDetDD::SiDetectorElement::isBarrel
bool isBarrel() const
ActsTrk::CoreStripSpacePointFormationTool::m_ATLASConverterTool
ToolHandle< IActsToTrkConverterTool > m_ATLASConverterTool
Definition: CoreStripSpacePointFormationTool.h:102
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
ActsTrk::CoreStripSpacePointFormationTool::computeOffset
double computeOffset(const InDetDD::SiDetectorElement &element1, const InDetDD::SiDetectorElement &element2, double &stripLengthGapTolerance) const
Definition: CoreStripSpacePointFormationTool.cxx:579
ParticleGun_SamplingFraction.radius
radius
Definition: ParticleGun_SamplingFraction.py:96
ActsTrk::StripSP::stripCenterDistance
Eigen::Matrix< float, 3, 1 > stripCenterDistance
Definition: IStripSpacePointFormationTool.h:30
SiDetectorElement.h
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
InDetDD::SiCellId
Definition: SiCellId.h:29
StripClusterAuxContainer.h
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
StripStereoAnnulusDesign.h
ALFA_EventTPCnv_Dict::t2
std::vector< ALFA_RawDataContainer_p1 > t2
Definition: ALFA_EventTPCnvDict.h:44
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
ContainerAccessor.h
ActsTrk::CoreStripSpacePointFormationTool::m_lorentzAngleTool
ToolHandle< ISiLorentzAngleTool > m_lorentzAngleTool
Definition: CoreStripSpacePointFormationTool.h:101
ActsTrk::PhiMinus
@ PhiMinus
Definition: StripInformationHelper.h:13
ActsTrk::ThisOne
@ ThisOne
Definition: StripInformationHelper.h:13
InDetDD::SolidStateDetectorElementBase::globalPosition
HepGeom::Point3D< double > globalPosition(const HepGeom::Point3D< double > &localPos) const
transform a reconstruction local position into a global position (inline):
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
dumpNswErrorDb.minStrip
int minStrip
Definition: dumpNswErrorDb.py:26
ActsTrk::CoreStripSpacePointFormationTool::correctPolarRange
void correctPolarRange(const InDetDD::SiDetectorElement *element, double &min, double &max, size_t &minStrip, size_t &maxStrip) const
Definition: CoreStripSpacePointFormationTool.cxx:623
ATLASSourceLinkSurfaceAccessor.h
ActsTrk
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Definition: MuonDetectorBuilderTool.cxx:34
InDetDD::StripStereoAnnulusDesign::localPositionOfCell
virtual SiLocalPosition localPositionOfCell(const SiCellId &cellId) const override
id -> position
Definition: StripStereoAnnulusDesign.cxx:362
CoreStripSpacePointFormationTool.h
InDetDD::SiDetectorElement::isStereo
bool isStereo() const
Check if it is the stereo side (useful for SCT)
Definition: SiDetectorElement.cxx:300
SiCellId.h
InDetDD::SiDetectorElement::design
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
minValue
#define minValue(current, test)
Definition: CompoundLayerMaterialCreator.h:21
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
ContainerAccessor::isIdentifierPresent
bool isIdentifierPresent(const identifier_t &identifier) const
Function to verify if a given identifier is present in the map, i.e.
Definition: ContainerAccessor.h:77
python.compressB64.c
def c
Definition: compressB64.py:93
updateCoolNtuple.limit
int limit
Definition: updateCoolNtuple.py:45
InDetDD::SiDetectorElementCollection::getDetectorElement
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Definition: SiDetectorElementCollection.cxx:15
ActsTrk::nNeighbours
@ nNeighbours
Definition: StripInformationHelper.h:13
ActsTrk::StripSP::topStripCenter
Eigen::Matrix< float, 3, 1 > topStripCenter
Definition: IStripSpacePointFormationTool.h:31
InDetDD::SolidStateDetectorElementBase::identify
virtual Identifier identify() const override final
identifier of this detector element (inline)
ActsTrk::CoreStripSpacePointFormationTool::fillSpacePoints
StatusCode fillSpacePoints(const EventContext &ctx, std::shared_ptr< Acts::SpacePointBuilder< StripSP >> spBuilder, std::array< const InDetDD::SiDetectorElement *, nNeighbours > neighbourElements, std::array< std::vector< std::pair< ATLASUncalibSourceLink, size_t >>, nNeighbours > neighbourSourceLinks, std::array< double, 14 > overlapExtents, const Amg::Vector3D &beamSpotVertex, std::vector< StripSP > &spacePoints, std::vector< StripSP > &overlapSpacePoints) const
Definition: CoreStripSpacePointFormationTool.cxx:315
InDetDD::StripStereoAnnulusDesign::maxR
double maxR() const
Definition: StripStereoAnnulusDesign.h:326
ActsTrk::CoreStripSpacePointFormationTool::m_trackingGeometryTool
ToolHandle< IActsTrackingGeometryTool > m_trackingGeometryTool
Definition: CoreStripSpacePointFormationTool.h:103
InDetDD::SolidStateDetectorElementBase::transform
virtual const Amg::Transform3D & transform() const override final
Return local to global transform.
ActsTrk::StripSP::idHashes
std::vector< unsigned int > idHashes
Definition: IStripSpacePointFormationTool.h:21
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
xAOD::UncalibMeasType::PixelClusterType
@ PixelClusterType
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
SCT_ID::is_barrel
bool is_barrel(const Identifier &id) const
Test for barrel - WARNING: id MUST be sct id, otherwise answer is not accurate. Use SiliconID for gen...
Definition: SCT_ID.h:721
ActsTrk::CoreStripSpacePointFormationTool::updateRange
void updateRange(const InDetDD::SiDetectorElement &element1, const InDetDD::SiDetectorElement &element2, double &stripLengthGapTolerance, double &min, double &max) const
Definition: CoreStripSpacePointFormationTool.cxx:613