ATLAS Offline Software
Loading...
Searching...
No Matches
ActsTrk::StripSpacePointFormationTool Class Reference

#include <StripSpacePointFormationTool.h>

Inheritance diagram for ActsTrk::StripSpacePointFormationTool:
Collaboration diagram for ActsTrk::StripSpacePointFormationTool:

Public Member Functions

AthAlgTool methods
 StripSpacePointFormationTool (const std::string &type, const std::string &name, const IInterface *parent)
virtual ~StripSpacePointFormationTool ()=default
virtual StatusCode initialize () override

Private Attributes

Id helpers
const SCT_IDm_stripId {}
tool handles
ToolHandle< ISiLorentzAngleToolm_lorentzAngleTool
 Using Lorentz angle tool.
Configuration flags
Gaudi::Property< bool > m_allClusters {this, "AllClusters", false, "Process all clusters without limits."}
Gaudi::Property< bool > m_useTopSp {this, "useTopSp", false, "SP global position is for second strip module."}
Gaudi::Property< bool > m_isITk {this, "isITk", true, "True if running in ITk"}
Cut parameters

The following are ranges within which clusters must lie to make a spacepoint.

Opposite and eta neighbours clusters must lie within range of each other. Phi clusters must lie in region of each wafer separately.

Gaudi::Property< float > m_overlapLimitOpposite {this, "OverlapLimitOpposite", 2.8, "Overlap limit for opposite-neighbour."}
Gaudi::Property< float > m_overlapLimitPhi {this, "OverlapLimitPhi", 5.64, "Overlap limit for phi-neighbours."}
Gaudi::Property< float > m_overlapLimitEtaMin {this, "OverlapLimitEtaMin", 1.68, "Low overlap limit for eta-neighbours."}
Gaudi::Property< float > m_overlapLimitEtaMax {this, "OverlapLimitEtaMax", 3.0, "High overlap limit for eta-neighbours."}
Gaudi::Property< float > m_stripLengthTolerance {this, "StripLengthTolerance", 0.01}
 The following are parameters to build the space points.
Gaudi::Property< float > m_stripGapParameter {this, "StripGapParameter", 0.0015, "Recommend 0.001 - 0.0015 for ITK geometry"}
Gaudi::Property< bool > m_useSCTLayerDep_OverlapCuts {this,"useSCTLayerDep_OverlapCuts", true}
Gaudi::Property< bool > m_useBeamSpotConstraint {this, "useBeamSpotConstraint", true, "Reject space points which are not compatible with a particle originating from the beamspot"}
 For applying geometric cuts on SPs using beamspot constraint.

Production of space points

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
StatusCode fillStripSpacePoints (const std::array< const InDetDD::SiDetectorElement *, nNeighbours > &neighbourElements, const std::array< std::vector< std::pair< const xAOD::StripCluster *, size_t > >, nNeighbours > &neighbourClusters, const std::array< double, 14 > &overlapExtents, const Amg::Vector3D &beamSpotVertex, std::vector< StripSP > &spacePoints, std::vector< StripSP > &overlapSpacePoints) const
StatusCode makeStripSpacePoint (std::vector< StripSP > &, const StripInformationHelper &firstInfo, const StripInformationHelper &secondInfo, bool isEndcap, double limit, double slimit) const
void updateRange (const InDetDD::SiDetectorElement *element1, const InDetDD::SiDetectorElement *element2, double &stripLengthGapTolerance, double &min, double &max) const
double offset (const InDetDD::SiDetectorElement *element1, const InDetDD::SiDetectorElement *element2, double &stripLengthGapTolerance) const
void correctPolarRange (const InDetDD::SiDetectorElement *element, double &min, double &max, size_t &minStrip, size_t &maxStrip) const
std::pair< Amg::Vector3D, Amg::Vector3DgetStripEnds (const xAOD::StripCluster *cluster, const InDetDD::SiDetectorElement *element, size_t &stripIndex) const

Detailed Description

Definition at line 34 of file StripSpacePointFormationTool.h.

Constructor & Destructor Documentation

◆ StripSpacePointFormationTool()

ActsTrk::StripSpacePointFormationTool::StripSpacePointFormationTool ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 16 of file StripSpacePointFormationTool.cxx.

19 : base_class(type, name, parent)
20 {}

◆ ~StripSpacePointFormationTool()

virtual ActsTrk::StripSpacePointFormationTool::~StripSpacePointFormationTool ( )
virtualdefault

Member Function Documentation

◆ correctPolarRange()

void ActsTrk::StripSpacePointFormationTool::correctPolarRange ( const InDetDD::SiDetectorElement * element,
double & min,
double & max,
size_t & minStrip,
size_t & maxStrip ) const
private

Definition at line 572 of file StripSpacePointFormationTool.cxx.

577 {
578 // for Inner Detector SCT, gap = 0 in config.
579 if (element->isBarrel() or (not m_isITk))
580 return;
581
582 // design for endcap modules
583 const InDetDD::StripStereoAnnulusDesign *design
584 = dynamic_cast<const InDetDD::StripStereoAnnulusDesign *> (&element->design());
585 if ( design==nullptr ) {
586 ATH_MSG_FATAL( "Invalid strip annulus design for module with identifier/identifierHash " << element->identify() << "/" << element->identifyHash());
587 return;
588 }
589
590 // converting min and max from cartesian reference frame to polar frame
591 auto firstPosition = (design->localPositionOfCell(design->strip1Dim(0, 0))+
592 design->localPositionOfCell(design->strip1Dim(design->diodesInRow(0)-1, 0)))*0.5;
593
594 double radius = firstPosition.xEta();
595
596 InDetDD::SiCellId minCellId = element->cellIdOfPosition(InDetDD::SiLocalPosition(radius, min, 0.));
597 InDetDD::SiCellId maxCellId = element->cellIdOfPosition(InDetDD::SiLocalPosition(radius, max, 0.));
598
599 if (not minCellId.isValid()) {
600 minCellId = InDetDD::SiCellId(0);
601 }
602
603 if (not maxCellId.isValid()) {
604 maxCellId = InDetDD::SiCellId(design->diodesInRow(0)-1);
605 }
606
607 minStrip = minCellId.strip();
608 maxStrip = maxCellId.strip();
609
610 // re-evaluate min and max in polar coordinate
611 min = std::atan2(min, radius);
612 max = std::atan2(max, radius);
613 }
#define ATH_MSG_FATAL(x)
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
int strip() const
Get strip number. Equivalent to phiIndex().
Definition SiCellId.h:131
bool isValid() const
Test if its in a valid state.
Definition SiCellId.h:136
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
SiCellId cellIdOfPosition(const Amg::Vector2D &localPos) const
As in previous method but returns SiCellId.
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
virtual Identifier identify() const override final
identifier of this detector element (inline)
virtual int strip1Dim(int strip, int row) const override
only relevant for SCT.
virtual SiLocalPosition localPositionOfCell(const SiCellId &cellId) const override
id -> position
virtual int diodesInRow(const int row) const override

◆ fillStripSpacePoints()

StatusCode ActsTrk::StripSpacePointFormationTool::fillStripSpacePoints ( const std::array< const InDetDD::SiDetectorElement *, nNeighbours > & neighbourElements,
const std::array< std::vector< std::pair< const xAOD::StripCluster *, size_t > >, nNeighbours > & neighbourClusters,
const std::array< double, 14 > & overlapExtents,
const Amg::Vector3D & beamSpotVertex,
std::vector< StripSP > & spacePoints,
std::vector< StripSP > & overlapSpacePoints ) const
private

Definition at line 221 of file StripSpacePointFormationTool.cxx.

228 {
229
230 // This function is called once all the needed quantities are collected.
231 // It is used to build space points checking the compatibility of clusters on pairs of detector elements.
232 // Detector elements and cluster collections are elements and clusters, respectively.
233 // [0] is the trigger element
234 // [1] is the opposite element
235 // [2]-[3] are the elements tested for eta overlaps
236 // [4]-[5] are the elements tested for phi overlaps
237 //
238 // To build space points:
239 // - For the opposite element and the ones tested for eta overlaps, you have to check
240 // if clusters are compatible with the local position of the trigger cluster
241 // requiring that the distance between the two clusters in phi is withing a specified range.
242 // - overlapExtents[0], overlapExtents[1] are filled for the opposite element
243 // - overlapExtents[2], overlapExtents[3], overlapExtents[4], overlapExtents[5] are filled for the eta overlapping elements
244 // - For the elements tested for phi overlaps, you have to check
245 // if clusters are compatible with the local position of the trigger cluster.
246 // This needs that the trigger cluster is at the edge of the trigger module
247 // and that the other cluster is on the compatible edge of its module
248 // - overlapExtents[6], overlapExtents[7], overlapExtents[10], overlapExtents[11]
249 // overlapExtents[8], overlapExtents[9], overlapExtents[12], overlapExtents[13] are filled for the phi overlapping elements
250
251 constexpr int otherSideIndex{1};
252 constexpr int maxEtaIndex{3};
253 std::array<int, nNeighbours-1> elementIndex{};
254 int nElements = 0;
255
256 // For the nNeighbours sides, fill elementIndex with the indices of the existing elements.
257 // Same the number of elements in nElements to loop on the later on
258 for(int n=1; n!=nNeighbours; ++n) {
259 if(elements[n]) {
260 elementIndex[nElements++] = n;
261 }
262 }
263 // return if all detector elements are nullptr
264 if(!nElements) return StatusCode::SUCCESS;
265
266 // trigger element and clusters
267 const InDetDD::SiDetectorElement* element = elements[0];
268 bool isEndcap = element->isEndcap();
269
270 std::vector<StripInformationHelper> stripInfos;
271 stripInfos.reserve(clusters[0].size());
272
273 // loop on all clusters on the trigger detector element and save the related information
274 for (auto& cluster_index : clusters[0]) {
275 size_t stripIndex = -1;
276 auto ends = getStripEnds(cluster_index.first, element, stripIndex);
277 const auto& localPos = cluster_index.first->localPosition<1>();
278 StripInformationHelper stripInfo(cluster_index.first->identifierHash(), ends.first, ends.second, beamSpotVertex, localPos(0, 0), cluster_index.second, stripIndex);
279 stripInfos.push_back( std::move(stripInfo) );
280 }
281
282 double limit = 1. + m_stripLengthTolerance;
283 double slimit = 0.;
284
285 if(not m_allClusters) {
286 // Start processing the opposite side and the eta overlapping elements
287 int n = 0;
288 for(; n < nElements; ++n) {
289 int currentIndex = elementIndex[n];
290 if(currentIndex > maxEtaIndex) break;
291
292 // get the detector element and the IdentifierHash
293 const InDetDD::SiDetectorElement* currentElement = elements[currentIndex];
294
295 // retrieve the range
296 double min = overlapExtents[currentIndex*2-2];
297 double max = overlapExtents[currentIndex*2-1];
298
299 size_t minStrip, maxStrip = 0;
300
301 if (m_stripGapParameter != 0.) {
302 updateRange(element, currentElement, slimit, min, max);
303 correctPolarRange(element, min, max, minStrip, maxStrip);
304 }
305
306 StripInformationHelper currentStripInfo;
307 for (auto& cluster_index : clusters[currentIndex]) {
308 bool processed = false;
309 const auto& currentLocalPos = cluster_index.first->localPosition<1>();
310
311 for(auto& stripInfo : stripInfos) {
312 double diff = currentLocalPos(0, 0)-stripInfo.locX();
313 // In negative endcap, local z is opposite of positive endcap
314 // need to invert the difference for proper comparison
315 if( m_stripId->barrel_ec(currentElement->identify())<0 ) diff = -diff;
316
317 if(diff < min || diff > max) continue;
318
319 if (not processed) {
320 processed = true;
321 size_t currentStripIndex = 0;
322 auto ends = getStripEnds(cluster_index.first, currentElement, currentStripIndex);
323 currentStripInfo.set(cluster_index.first->identifierHash(), ends.first, ends.second, beamSpotVertex, currentLocalPos(0, 0), cluster_index.second, currentStripIndex);
324 }
325
326 // depending on the index you are processing, you save the space point in the correct container
327 if (currentIndex==otherSideIndex) {
328 ATH_CHECK( makeStripSpacePoint(spacePoints, stripInfo, currentStripInfo, isEndcap, limit, slimit) );
329 } else {
330 ATH_CHECK( makeStripSpacePoint(overlapSpacePoints, stripInfo, currentStripInfo, isEndcap, limit, slimit) );
331 }
332 }
333 }
334 }
335 // process the phi overlapping elements
336 // if possible n starts from 4
337 for(; n < nElements; ++n) {
338 int currentIndex = elementIndex[n];
339 const InDetDD::SiDetectorElement* currentElement = elements[currentIndex];
340
341 double min = overlapExtents[4*currentIndex-10];
342 double max = overlapExtents[4*currentIndex- 9];
343
344 std::size_t minStrip = 0;
345 std::size_t maxStrip = 0;
346
347 if (m_stripGapParameter != 0.) {
348 updateRange(element, currentElement, slimit, min, max);
349 correctPolarRange(element, min, max, minStrip, maxStrip);
350 }
351
352 std::vector<StripInformationHelper*> stripPhiInfos;
353 stripPhiInfos.reserve(stripInfos.size());
354
355 for(auto& stripInfo : stripInfos) {
356 auto stripIndex = stripInfo.stripIndex();
357 auto localPosition = stripInfo.locX();
358 auto centralValue = localPosition;
359 auto minValue = min;
360 auto maxValue = max;
361 if (isEndcap and m_isITk) { // for Inner Detector SCT, use the same cut as barrel
362 centralValue = stripIndex;
365 }
366
367 if (minValue <= centralValue and centralValue <= maxValue) {
368 stripPhiInfos.push_back(&stripInfo);
369 }
370 }
371 // continue if you have no cluster from the phi overlapping region of the trigger element
372 if(stripPhiInfos.empty()) continue;
373
374 min = overlapExtents[4*currentIndex-8];
375 max = overlapExtents[4*currentIndex-7];
376
377 if (m_stripGapParameter != 0.) {
378 updateRange(element, currentElement, slimit, min, max);
379 correctPolarRange(currentElement, min, max, minStrip, maxStrip);
380 }
381
382 for (auto& cluster_index : clusters[currentIndex]) {
383 const auto& currentLocalPos = cluster_index.first->localPosition<1>();
384
385 size_t currentStripIndex = 0;
386 auto ends = getStripEnds(cluster_index.first, currentElement, currentStripIndex);
387 StripInformationHelper currentStripInfo(cluster_index.first->identifierHash(), ends.first, ends.second, beamSpotVertex, currentLocalPos(0, 0), cluster_index.second, currentStripIndex);
388 auto centralValue = currentLocalPos(0, 0);
389 auto minValue = min;
390 auto maxValue = max;
391 if (isEndcap and m_isITk) { // for Inner Detector SCT, use the same cut as barrel
392 centralValue = currentStripIndex;
395 }
396
397 if (centralValue < minValue or centralValue > maxValue)
398 continue;
399
400 for(auto& stripInfo : stripPhiInfos) {
401 ATH_CHECK( makeStripSpacePoint(overlapSpacePoints, *stripInfo, currentStripInfo, isEndcap, limit, slimit) );
402 }
403 }
404 }
405 return StatusCode::SUCCESS;
406 }
407
408 for(int n=0; n!=nElements; ++n) {
409
410 int currentIndex = elementIndex[n];
411 const InDetDD::SiDetectorElement* currentElement = elements[currentIndex];
412
413 if (m_stripGapParameter != 0.) {
414 offset(element, currentElement, slimit);
415 }
416
417 for (auto& cluster_index : clusters[currentIndex]) {
418 size_t currentStripIndex = 0;
419 auto ends = getStripEnds(cluster_index.first, element, currentStripIndex);
420 const auto& currentLocalPos = cluster_index.first->localPosition<1>();
421 StripInformationHelper currentStripInfo(cluster_index.first->identifierHash(), ends.first, ends.second, beamSpotVertex, currentLocalPos(0, 0), cluster_index.second, currentStripIndex);
422
423 for(auto& stripInfo : stripInfos) {
424 // depending on the index you are processing, you save the space point in the correct container
425 if (currentIndex==otherSideIndex) {
426 ATH_CHECK( makeStripSpacePoint(spacePoints, stripInfo, currentStripInfo, isEndcap, limit, slimit) );
427 } else {
428 ATH_CHECK( makeStripSpacePoint(overlapSpacePoints, stripInfo, currentStripInfo, isEndcap, limit, slimit) );
429 }
430 }
431 }
432 }
433 return StatusCode::SUCCESS;
434 }
#define ATH_CHECK
Evaluate an expression and check for errors.
#define maxValue(current, test)
#define minValue(current, test)
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
void correctPolarRange(const InDetDD::SiDetectorElement *element, double &min, double &max, size_t &minStrip, size_t &maxStrip) const
StatusCode makeStripSpacePoint(std::vector< StripSP > &, const StripInformationHelper &firstInfo, const StripInformationHelper &secondInfo, bool isEndcap, double limit, double slimit) const
Gaudi::Property< float > m_stripLengthTolerance
The following are parameters to build the space points.
std::pair< Amg::Vector3D, Amg::Vector3D > getStripEnds(const xAOD::StripCluster *cluster, const InDetDD::SiDetectorElement *element, size_t &stripIndex) const
double offset(const InDetDD::SiDetectorElement *element1, const InDetDD::SiDetectorElement *element2, double &stripLengthGapTolerance) const
void updateRange(const InDetDD::SiDetectorElement *element1, const InDetDD::SiDetectorElement *element2, double &stripLengthGapTolerance, double &min, double &max) const

◆ getStripEnds()

std::pair< Amg::Vector3D, Amg::Vector3D > ActsTrk::StripSpacePointFormationTool::getStripEnds ( const xAOD::StripCluster * cluster,
const InDetDD::SiDetectorElement * element,
size_t & stripIndex ) const
private

Definition at line 616 of file StripSpacePointFormationTool.cxx.

619 {
620 const Eigen::Matrix<float,1,1>& localPos = cluster->localPosition<1>();
621
622 if (element->isEndcap() and m_isITk) {
623 // design for endcap modules
624 const InDetDD::StripStereoAnnulusDesign *design
625 = dynamic_cast<const InDetDD::StripStereoAnnulusDesign *> (&element->design());
626 if ( design==nullptr ) {
627 ATH_MSG_FATAL( "Invalid strip annulus design for module with identifier/identifierHash " << element->identify() << "/" << element->identifyHash());
628 return std::pair<Amg::Vector3D, Amg::Vector3D >();
629 }
630
631 // calculate phi pitch for evaluating the strip index
632 double phiPitchPhi = design->phiWidth()/design->diodesInRow(0);
633 stripIndex = -std::floor(localPos(0, 0) / phiPitchPhi) + design->diodesInRow(0) *0.5 - 0.5;
634
635 std::pair<Amg::Vector3D, Amg::Vector3D > ends = {
636 element->globalPosition(design->stripPosAtR(stripIndex, 0, design->minR())),
637 element->globalPosition(design->stripPosAtR(stripIndex, 0, design->maxR()))
638 };
639 return ends;
640
641 }
642
643 InDetDD::SiLocalPosition localPosition(0., localPos(0, 0), 0.);
644 std::pair<Amg::Vector3D, Amg::Vector3D > ends(element->endsOfStrip(localPosition));
645
646 return ends;
647 }
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...
HepGeom::Point3D< double > globalPosition(const HepGeom::Point3D< double > &localPos) const
transform a reconstruction local position into a global position (inline):
SiLocalPosition stripPosAtR(int strip, int row, double r) const
ConstVectorMap< N > localPosition() const
Returns the local position of the measurement.

◆ initialize()

StatusCode ActsTrk::StripSpacePointFormationTool::initialize ( )
overridevirtual

Definition at line 22 of file StripSpacePointFormationTool.cxx.

22 {
23
25
26 ATH_CHECK(m_lorentzAngleTool.retrieve());
27
29 ATH_MSG_INFO("Use SCT SP overlap cuts based on layer number parity");
30
31 return StatusCode::SUCCESS;
32 }
#define ATH_MSG_INFO(x)
ToolHandle< ISiLorentzAngleTool > m_lorentzAngleTool
Using Lorentz angle tool.
retrieve(aClass, aKey=None)
Definition PyKernel.py:110

◆ makeStripSpacePoint()

StatusCode ActsTrk::StripSpacePointFormationTool::makeStripSpacePoint ( std::vector< StripSP > & collection,
const StripInformationHelper & firstInfo,
const StripInformationHelper & secondInfo,
bool isEndcap,
double limit,
double slimit ) const
private

Definition at line 436 of file StripSpacePointFormationTool.cxx.

443 {
444 double a =-firstInfo.trajDirection().dot(secondInfo.normal());
445 double b = firstInfo.stripDirection().dot(secondInfo.normal());
446 double l0 = firstInfo.oneOverStrip()*slimit+limit ;
447
448 if(std::abs(a) > (std::abs(b)*l0)) {
449 ATH_MSG_DEBUG("SP fails geometric cuts (first)");
451 return StatusCode::SUCCESS;
452 }
453 }
454
455 double c =-secondInfo.trajDirection().dot(firstInfo.normal());
456 double d = secondInfo.stripDirection().dot(firstInfo.normal());
457 double l1 = secondInfo.oneOverStrip()*slimit+limit ;
458
459 if(std::abs(c) > (std::abs(d)*l1)) {
460 ATH_MSG_DEBUG("SP fails geometric cuts (second)");
462 return StatusCode::SUCCESS;
463 }
464 }
465
466 double m = a/b;
467
468 if(slimit!=0.) {
469 double n = c/d;
470 if (m > limit || n > limit) {
471 double cs = firstInfo.stripDirection().dot(secondInfo.stripDirection())*(firstInfo.oneOverStrip()*firstInfo.oneOverStrip());
472 double dm = (m-1);
473 double dmn = (n-1.)*cs;
474 if(dmn > dm) dm = dmn;
475 m-=dm; n-=(dm/cs);
476 if(std::abs(m) > limit || std::abs(n) > limit) {
477 ATH_MSG_DEBUG("SP falls outside of limit");
479 return StatusCode::SUCCESS;
480 }
481 }
482 } else if (m < -limit || n < -limit) {
483 double cs = firstInfo.stripDirection().dot(secondInfo.stripDirection())*(firstInfo.oneOverStrip()*firstInfo.oneOverStrip());
484 double dm = -(1.+m);
485 double dmn = -(1.+n)*cs;
486 if(dmn > dm) dm = dmn;
487 m+=dm; n+=(dm/cs);
488 if(std::abs(m) > limit || std::abs(n) > limit) {
489 ATH_MSG_DEBUG("SP falls outside of limit");
491 return StatusCode::SUCCESS;
492 }
493 }
494 }
495 }
496
497 Eigen::Matrix<double, 3, 1> globalPosition(m_useTopSp ? secondInfo.position(m) : firstInfo.position(m));
498
499 // evaluation of the local covariance
500 // Lines taken from SCT_SpacePoint::setupLocalCovarianceSCT()
501 constexpr float deltaY = 0.0004; // roughly pitch of SCT (80 mu) / sqrt(12)
502 constexpr float covTerm = 1600.*deltaY;
503
504 Eigen::Matrix<float, 2, 1> variance(0.1f, 8.f*covTerm);
505 // Swap r/z covariance terms for endcap clusters
506 if ( isEndcap )
507 std::swap( variance(0, 0), variance(1, 0) );
508
509 // evaluation of measurement details
510 double topHalfStripLength = 0.5*firstInfo.stripDirection().norm();
511 Eigen::Matrix<double, 3, 1> topStripDirection = -firstInfo.stripDirection()/(2.*topHalfStripLength);
512 Eigen::Matrix<double, 3, 1> topStripCenter = 0.5*firstInfo.trajDirection();
513
514 double bottomHalfStripLength = 0.5*secondInfo.stripDirection().norm();
515 Eigen::Matrix<double, 3, 1> bottomStripDirection = -secondInfo.stripDirection()/(2.*bottomHalfStripLength);
516
517 Eigen::Matrix<double, 3, 1> stripCenterDistance = firstInfo.stripCenter() - secondInfo.stripCenter();
518
519
520
521 StripSP toAdd;
522 toAdd.idHashes = {firstInfo.idHash(), secondInfo.idHash()};
523 toAdd.globPos = globalPosition.cast<float>();
524 toAdd.cov_r = variance(0,0);
525 toAdd.cov_z = variance(1,0);
526 toAdd.measurementIndexes = std::array<std::size_t,2> ({firstInfo.clusterIndex(), secondInfo.clusterIndex()});
527 toAdd.topHalfStripLength = static_cast<float>(topHalfStripLength);
528 toAdd.bottomHalfStripLength = static_cast<float>(bottomHalfStripLength);
529 toAdd.topStripDirection = topStripDirection.cast<float>();
530 toAdd.bottomStripDirection = bottomStripDirection.cast<float>();
531 toAdd.stripCenterDistance = stripCenterDistance.cast<float>();
532 toAdd.topStripCenter = topStripCenter.cast<float>();
533
534 collection.push_back(std::move(toAdd));
535
536 return StatusCode::SUCCESS;
537 }
#define ATH_MSG_DEBUG(x)
static Double_t a
Gaudi::Property< bool > m_useBeamSpotConstraint
For applying geometric cuts on SPs using beamspot constraint.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)

◆ offset()

double ActsTrk::StripSpacePointFormationTool::offset ( const InDetDD::SiDetectorElement * element1,
const InDetDD::SiDetectorElement * element2,
double & stripLengthGapTolerance ) const
private

Definition at line 539 of file StripSpacePointFormationTool.cxx.

542 {
543 const Amg::Transform3D& T1 = element1->transform();
544 const Amg::Transform3D& T2 = element2->transform();
545 Amg::Vector3D C = element1->center() ;
546 bool isAnnulus = (element1->design().shape() == InDetDD::Annulus);
547
548 double x12 = T1(0,0)*T2(0,0)+T1(1,0)*T2(1,0)+T1(2,0)*T2(2,0);
549 double r = isAnnulus ? std::sqrt(C[0]*C[0]+C[1]*C[1]) : std::sqrt(T1(0,3)*T1(0,3)+T1(1,3)*T1(1,3));
550 double s = (T1(0,3)-T2(0,3))*T1(0,2)+(T1(1,3)-T2(1,3))*T1(1,2)+(T1(2,3)-T2(2,3))*T1(2,2);
551
552 double dm = (m_stripGapParameter*r)*std::abs(s*x12);
553 double d = isAnnulus ? dm/.04 : dm/std::sqrt((1.-x12)*(1.+x12));
554
555 if (std::abs(T1(2,2)) > 0.7) d*=(r/std::abs(T1(2,3)));
556
557 stripLengthGapTolerance = d;
558
559 return dm;
560 }
virtual const Amg::Transform3D & transform() const override final
Return local to global transform.
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
int r
Definition globals.cxx:22
struct color C
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D

◆ produceSpacePoints()

StatusCode ActsTrk::StripSpacePointFormationTool::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
overridevirtual

Production of StripSP from strip clusters Strip space points involves a more complex logic since they are made combining clusters from pairs of overlapping detectors.

For each trigger element, first evaluate and collect the quantities you need to build the space points. The detector element array has capacity 6: [0] is the trigger element [1] is the opposite element [2]-[3] are the elements tested for eta overlaps [4]-[5] are the elements tested for phi overlaps For each element you save the corresponding cluster collections and the space point compatibility range as described below.

For the opposite element and the ones tested for eta overlaps, you have to check if clusters are compatible with the local position of the trigger cluster requiring that the distance between the two clusters in phi is withing a specified range.

  • For the clusters on the opposite element: [-m_overlapLimitOpposite, m_overlapLimitOpposite]
  • For the eta overlapping clusters : you use m_overlapLimitEtaMin and m_overlapLimitEtaMax in different combination depending if you are checking a stereo module or not

For each element, the extremes of these ranges are saved in the overlapExtents array which is used later on

  • overlapExtents[0], overlapExtents[1] are filled for the opposite element
  • overlapExtents[2], overlapExtents[3], overlapExtents[4], overlapExtents[5] are filled for the eta overlapping elements

For the elements tested for phi overlaps, you have to check if clusters are compatible with the local position of the trigger cluster. This needs that the trigger cluster is at the edge of the trigger module: e.g. -hwidth < locX_trigger < -hwidth+m_overlapLimitPhi (or hwidth-m_overlapLimitPhi < locX_trigger < hwidth) and that the other cluster is on the compatible edge of its module: e.g. hwidth-m_overlapLimitPhi < locX_other < hwidth (or -hwidth < locX_other < -hwidth+m_overlapLimitPhi)

For each element, the extremes of these ranges are saved in the overlapExtents array which is used later on

  • overlapExtents[6], overlapExtents[7], overlapExtents[10], overlapExtents[11] overlapExtents[8], overlapExtents[9], overlapExtents[12], overlapExtents[13] are filled for the phi overlapping elements

Access to the cluster from a given detector element is possible via the ContainerAccessor.

Definition at line 34 of file StripSpacePointFormationTool.cxx.

44 {
49
83
86
87 const auto hashesProc = (hashesToProcess.size() > 0 ? hashesToProcess : stripAccessor.allIdentifiers());
88
89 //factor out floating point conversions
90 double overlapLimitOpposite = m_overlapLimitOpposite;
91 double overlapLimitPhi = m_overlapLimitPhi;
92 double overlapLimitEtaMin = m_overlapLimitEtaMin;
93 double overlapLimitEtaMax = m_overlapLimitEtaMax;
94
95 for (auto& idHash : hashesProc) {
96 const InDetDD::SiDetectorElement* thisElement = elements.getDetectorElement(idHash);
97 if ( not thisElement->isStereo() ) {
98 // Retrieve the neighbours of the detector element
99 const std::vector<IdentifierHash>* others(properties.neighbours(idHash));
100 if (others==nullptr || others->empty() )
101 continue;
102
103 // This flag is use to trigger if the search should be performed.
104 // In case there are no clusters on the neighbours of the selected
105 // detector element, the flag stays false.
106 bool search=false;
107 size_t neighbour = 0;
108 while (not search and neighbour<others->size() ) {
109 search = stripAccessor.isIdentifierPresent(others->at(neighbour));
110 neighbour++;
111 }
112 if (not search)
113 continue;
114
115 // prepare clusters, indices and modules for space point formation
116 std::array<std::vector<std::pair<const xAOD::StripCluster*, size_t>>, nNeighbours> neighbourClusters{};
117 std::array<const InDetDD::SiDetectorElement*, nNeighbours> neighbourElements{};
118
119 auto groupStart = clusterContainer.begin();
120 // Get the detector element and range for the idHash
121 neighbourElements[0] = thisElement;
122 for (auto& this_range : stripAccessor.rangesForIdentifierDirect(idHash)) {
123 for (auto start=this_range.first; start!=this_range.second; start++) {
124 size_t position = std::distance(groupStart, start);
125 neighbourClusters[0].push_back(std::make_pair(*start, position));
126 }
127 }
128
129 Identifier thisId = thisElement->identify();
130
131 // define overlap extends before building space points
132 std::array<double, 14> overlapExtents{};
133 // Default case: you test the opposite element and the overlapping in phi (total 3 elements)
134 int Nmax = 4;
135
136 // In the barrel, test the eta overlaps as well (total 5 elements)
137 if (m_stripId->is_barrel(thisId))
138 Nmax = 6;
139
140 // You can remove all the overlaps if requested.
141 // Here you test only the opposite element
142 if(not processOverlaps) Nmax = 2;
143 //factor double conversion outside of loop
144 double hwidth(static_cast<double>(properties.halfWidth(idHash)));
145 int n = 0;
146
147
148 // The order of the elements in others is such that you first get the opposite element,
149 // the overlapping in phi and then the overlapping in eta
150 // For this reason you need to re-order the indices, since the SiSpacePointMakerTool will process
151 // first the eta overlaps and then the phi ones
152 const std::array<size_t, nNeighbours> neigbourIndices{ThisOne, Opposite, EtaMinus, EtaPlus, PhiMinus, PhiPlus};
153
154 for (const auto& otherHash : *others) {
155
156 if(++n==Nmax) break;
157
158 if(not stripAccessor.isIdentifierPresent(otherHash))
159 continue;
160
161 const InDetDD::SiDetectorElement* otherElement = elements.getDetectorElement(otherHash);
162
163 neighbourElements[neigbourIndices[n]] = otherElement;
164 for (auto& this_range : stripAccessor.rangesForIdentifierDirect(otherHash)) {
165 for (auto start=this_range.first; start!=this_range.second; start++) {
166 size_t position = std::distance(groupStart, start);
167 neighbourClusters[neigbourIndices[n]].push_back(std::make_pair(*start, position));
168 }
169 }
170
171 switch (n) {
172 case Opposite: {
173 overlapExtents[ 0] = -overlapLimitOpposite;
174 overlapExtents[ 1] = overlapLimitOpposite;
175 break;
176 }
177 case PhiMinus: {
178 overlapExtents[ 6] =-hwidth;
179 overlapExtents[ 7] =-hwidth+overlapLimitPhi;
180 overlapExtents[ 8] = hwidth-overlapLimitPhi;
181 overlapExtents[ 9] = hwidth;
182 break;
183 }
184 case PhiPlus: {
185 overlapExtents[10] = hwidth-overlapLimitPhi;
186 overlapExtents[11] = hwidth;
187 overlapExtents[12] =-hwidth;
188 overlapExtents[13] =-hwidth+overlapLimitPhi;
189 break;
190 }
191 case EtaMinus: {
192 overlapExtents[ 2] = overlapLimitEtaMin;
193 overlapExtents[ 3] = overlapLimitEtaMax;
194 if (m_useSCTLayerDep_OverlapCuts && (m_stripId->layer_disk(thisId) & 1) != 0) {
195 overlapExtents[ 2] =-overlapLimitEtaMax;
196 overlapExtents[ 3] =-overlapLimitEtaMin;
197 }
198 break;
199 }
200 default: {
201 overlapExtents[ 4] = overlapLimitEtaMin;
202 overlapExtents[ 5] = overlapLimitEtaMax;
203 if (m_useSCTLayerDep_OverlapCuts && (m_stripId->layer_disk(thisId) & 1) == 0) {
204 overlapExtents[ 4] = -overlapLimitEtaMax;
205 overlapExtents[ 5] = -overlapLimitEtaMin;
206 }
207 break;
208 }
209 }
210 }
211
212 // producing and filling space points
213 ATH_CHECK( fillStripSpacePoints(neighbourElements, neighbourClusters, overlapExtents, beamSpotVertex,
214 spacePoints, overlapSpacePoints) );
215 }
216 }
217 return StatusCode::SUCCESS;
218 }
StatusCode fillStripSpacePoints(const std::array< const InDetDD::SiDetectorElement *, nNeighbours > &neighbourElements, const std::array< std::vector< std::pair< const xAOD::StripCluster *, size_t > >, nNeighbours > &neighbourClusters, const std::array< double, 14 > &overlapExtents, const Amg::Vector3D &beamSpotVertex, std::vector< StripSP > &spacePoints, std::vector< StripSP > &overlapSpacePoints) const
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.
std::vector< identifier_t > allIdentifiers() const
Function to return all available identifier (i.e. keys in the map)
bool isIdentifierPresent(const identifier_t &identifier) const
Function to verify if a given identifier is present in the map, i.e.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
bool isStereo() const
Check if it is the stereo side (useful for SCT)
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:739

◆ updateRange()

void ActsTrk::StripSpacePointFormationTool::updateRange ( const InDetDD::SiDetectorElement * element1,
const InDetDD::SiDetectorElement * element2,
double & stripLengthGapTolerance,
double & min,
double & max ) const
private

Definition at line 562 of file StripSpacePointFormationTool.cxx.

566 {
567 double dm = offset(element1, element2, stripLengthGapTolerance);
568 min -= dm;
569 max += dm;
570 }

Member Data Documentation

◆ m_allClusters

Gaudi::Property< bool > ActsTrk::StripSpacePointFormationTool::m_allClusters {this, "AllClusters", false, "Process all clusters without limits."}
private

Definition at line 109 of file StripSpacePointFormationTool.h.

109{this, "AllClusters", false, "Process all clusters without limits."};

◆ m_isITk

Gaudi::Property<bool> ActsTrk::StripSpacePointFormationTool::m_isITk {this, "isITk", true, "True if running in ITk"}
private

Definition at line 111 of file StripSpacePointFormationTool.h.

111{this, "isITk", true, "True if running in ITk"};

◆ m_lorentzAngleTool

ToolHandle<ISiLorentzAngleTool> ActsTrk::StripSpacePointFormationTool::m_lorentzAngleTool
private
Initial value:
{this, "LorentzAngleTool", "",
"Tool to retreive Lorentz angle of SCT"}

Using Lorentz angle tool.

Definition at line 103 of file StripSpacePointFormationTool.h.

103 {this, "LorentzAngleTool", "",
104 "Tool to retreive Lorentz angle of SCT"};

◆ m_overlapLimitEtaMax

Gaudi::Property< float > ActsTrk::StripSpacePointFormationTool::m_overlapLimitEtaMax {this, "OverlapLimitEtaMax", 3.0, "High overlap limit for eta-neighbours."}
private

Definition at line 123 of file StripSpacePointFormationTool.h.

123{this, "OverlapLimitEtaMax", 3.0, "High overlap limit for eta-neighbours."};

◆ m_overlapLimitEtaMin

Gaudi::Property< float > ActsTrk::StripSpacePointFormationTool::m_overlapLimitEtaMin {this, "OverlapLimitEtaMin", 1.68, "Low overlap limit for eta-neighbours."}
private

Definition at line 122 of file StripSpacePointFormationTool.h.

122{this, "OverlapLimitEtaMin", 1.68, "Low overlap limit for eta-neighbours."};

◆ m_overlapLimitOpposite

Gaudi::Property< float > ActsTrk::StripSpacePointFormationTool::m_overlapLimitOpposite {this, "OverlapLimitOpposite", 2.8, "Overlap limit for opposite-neighbour."}
private

Definition at line 120 of file StripSpacePointFormationTool.h.

120{this, "OverlapLimitOpposite", 2.8, "Overlap limit for opposite-neighbour."};

◆ m_overlapLimitPhi

Gaudi::Property< float > ActsTrk::StripSpacePointFormationTool::m_overlapLimitPhi {this, "OverlapLimitPhi", 5.64, "Overlap limit for phi-neighbours."}
private

Definition at line 121 of file StripSpacePointFormationTool.h.

121{this, "OverlapLimitPhi", 5.64, "Overlap limit for phi-neighbours."};

◆ m_stripGapParameter

Gaudi::Property< float > ActsTrk::StripSpacePointFormationTool::m_stripGapParameter {this, "StripGapParameter", 0.0015, "Recommend 0.001 - 0.0015 for ITK geometry"}
private

Definition at line 126 of file StripSpacePointFormationTool.h.

126{this, "StripGapParameter", 0.0015, "Recommend 0.001 - 0.0015 for ITK geometry"};

◆ m_stripId

const SCT_ID* ActsTrk::StripSpacePointFormationTool::m_stripId {}
private

Definition at line 97 of file StripSpacePointFormationTool.h.

97{};

◆ m_stripLengthTolerance

Gaudi::Property< float > ActsTrk::StripSpacePointFormationTool::m_stripLengthTolerance {this, "StripLengthTolerance", 0.01}
private

The following are parameters to build the space points.

Definition at line 125 of file StripSpacePointFormationTool.h.

125{this, "StripLengthTolerance", 0.01};

◆ m_useBeamSpotConstraint

Gaudi::Property< bool > ActsTrk::StripSpacePointFormationTool::m_useBeamSpotConstraint {this, "useBeamSpotConstraint", true, "Reject space points which are not compatible with a particle originating from the beamspot"}
private

For applying geometric cuts on SPs using beamspot constraint.

Definition at line 129 of file StripSpacePointFormationTool.h.

129{this, "useBeamSpotConstraint", true, "Reject space points which are not compatible with a particle originating from the beamspot"};

◆ m_useSCTLayerDep_OverlapCuts

Gaudi::Property< bool > ActsTrk::StripSpacePointFormationTool::m_useSCTLayerDep_OverlapCuts {this,"useSCTLayerDep_OverlapCuts", true}
private

Definition at line 127 of file StripSpacePointFormationTool.h.

127{this,"useSCTLayerDep_OverlapCuts", true};

◆ m_useTopSp

Gaudi::Property< bool > ActsTrk::StripSpacePointFormationTool::m_useTopSp {this, "useTopSp", false, "SP global position is for second strip module."}
private

Definition at line 110 of file StripSpacePointFormationTool.h.

110{this, "useTopSp", false, "SP global position is for second strip module."};

The documentation for this class was generated from the following files: