ATLAS Offline Software
SCTLorentzMonAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "SCTLorentzMonAlg.h"
6 
14 
15 #include <cmath>
16 #include <memory>
17 #include <vector>
18 
19 SCTLorentzMonAlg::SCTLorentzMonAlg(const std::string& name, ISvcLocator* pSvcLocator)
20  :AthMonitorAlgorithm(name,pSvcLocator) {
21 }
22 
24  ATH_CHECK(detStore()->retrieve(m_pSCTHelper, "SCT_ID"));
25  ATH_CHECK(m_trackSummaryTool.retrieve());
26  ATH_CHECK(m_tracksName.initialize());
28  ATH_CHECK(m_assoTool.retrieve(DisableTool{!m_rejectSharedHits} ));
29 
31 }
32 
33 StatusCode SCTLorentzMonAlg::fillHistograms(const EventContext& ctx) const {
34  static const int layer100[] = {
35  2, 2, 3, 2, 2, 2, 0, 2, 3, 2, 0, 2, 3, 2, 3, 2, 0, 2, 3, 0, 2, 0, 2, 3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 3, 0, 3, 2, 0, 2,
36  2, 0, 3, 3, 3, 0, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 3, 3, 2, 2, 2, 2, 2, 3, 3, 2, 3, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 3, 3,
37  2, 3, 2, 3, 3, 2, 3, 2, 2, 2, 2, 2, 2, 2
38  };
39  static const int phi100[] = {
40  29, 29, 6, 13, 23, 13, 14, 29, 9, 29, 14, 29, 9, 29, 39, 32, 21, 32, 13, 22, 32, 22, 32, 13, 32, 32, 32, 20, 20, 20,
41  20, 20, 20, 13, 21, 17, 33, 5, 33, 33, 31, 6, 19, 47, 21, 37, 37, 37, 37, 33, 37, 37, 24, 33, 33, 47, 19, 33, 33,
42  37, 37, 37, 55, 9, 38, 24, 37, 38, 8, 9, 9, 26, 38, 38, 38, 38, 39, 39, 38, 11, 45, 54, 54, 24, 31, 14, 47, 45, 47,
43  47, 47, 47
44  };
45  static const int eta100[] = {
46  3, -4, -6, 2, 6, 3, -5, -1, 6, -2, -6, -5, 5, -3, 2, 6, -3, 5, 5, 3, 4, 2, 2, 2, -1, -3, -4, 1, -1, -2, -3, -4, 4,
47  -1, -5, 6, 2, 4, 3, 1, 6, -2, 6, 3, -6, -1, 2, 1, 3, -5, 4, 5, -3, -4, -3, -5, -2, -1, -2, -3, -2, -4, -3, 2, 3, -6,
48  -5, 4, 6, 1, -6, 1, 1, -5, -4, -3, -3, -5, -2, 1, 5, 5, 4, 4, 5, 4, -1, -5, 3, 4, 1, -5
49  };
50  constexpr unsigned int layer100_n{sizeof(layer100) / sizeof(*layer100)};
51  constexpr unsigned int phi100_n{sizeof(phi100) / sizeof(*phi100)};
52  constexpr unsigned int eta100_n{sizeof(eta100) / sizeof(*eta100)};
53  constexpr bool theseArraysAreEqualInLength{(layer100_n == phi100_n) and (phi100_n == eta100_n)};
54  static_assert(theseArraysAreEqualInLength, "Coordinate arrays for <100> wafers are not of equal length");
55 
56  ATH_MSG_DEBUG("enters fillHistograms");
57 
59  const InDetDD::SiDetectorElementCollection* elements{sctDetEle.retrieve()};
60  if (elements==nullptr) {
61  ATH_MSG_WARNING(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
62  return StatusCode::SUCCESS;
63  }
65  if (not tracks.isValid()) {
66  ATH_MSG_WARNING(" TrackCollection not found: Exit SCTLorentzTool" << m_tracksName.key());
67  return StatusCode::SUCCESS;
68  }
69 
70  // Prepare AssociationTool
71  std::unique_ptr<Trk::PRDtoTrackMap> prd_to_track_map;
72  if (m_rejectSharedHits) {
73  prd_to_track_map = m_assoTool->createPRDtoTrackMap();
74  for (const Trk::Track* track : *tracks) {
75  ATH_CHECK( m_assoTool->addPRDs(*prd_to_track_map,*track) );
76  }
77  }
78 
79  for (const Trk::Track* track: *tracks) {
80  if (track==nullptr) {
81  ATH_MSG_ERROR("no pointer to track!!!");
82  continue;
83  }
84 
85  // Get pointer to track state on surfaces
86  const Trk::TrackStates* trackStates{track->trackStateOnSurfaces()};
87  if (trackStates==nullptr) {
88  ATH_MSG_WARNING("for current track, TrackStateOnSurfaces == Null, no data will be written for this track");
89  continue;
90  }
91 
92  const Trk::TrackSummary* summary{track->trackSummary()};
93  std::unique_ptr<Trk::TrackSummary> mySummary;
94  if (summary==nullptr) {
95  mySummary = m_trackSummaryTool->summary(*track);
96  summary = mySummary.get();
97  if (summary==nullptr) {
98  ATH_MSG_WARNING("Trk::TrackSummary is null and cannot be created by " << m_trackSummaryTool.name());
99  continue;
100  }
101  }
102 
103  for (const Trk::TrackStateOnSurface* tsos: *trackStates) {
104  if (tsos->type(Trk::TrackStateOnSurface::Measurement)) {
105  const InDet::SiClusterOnTrack* clus{dynamic_cast<const InDet::SiClusterOnTrack*>(tsos->measurementOnTrack())};
106  if (clus) { // Is it a SiCluster? If yes...
107  // Reject shared hits if you want
108  if (prd_to_track_map and prd_to_track_map->isShared(*(clus->prepRawData())) ) {
109  continue;
110  }
111 
112  const InDet::SiCluster* RawDataClus{dynamic_cast<const InDet::SiCluster*>(clus->prepRawData())};
113  if (RawDataClus==nullptr) {
114  continue; // Continue if dynamic_cast returns null
115  }
116  if (RawDataClus->detectorElement()->isSCT()) {
117  const Identifier sct_id{clus->identify()};
118  const int bec{m_pSCTHelper->barrel_ec(sct_id)};
119  const int layer{m_pSCTHelper->layer_disk(sct_id)};
120  const int side{m_pSCTHelper->side(sct_id)};
121  const int eta{m_pSCTHelper->eta_module(sct_id)};
122  const int phi{m_pSCTHelper->phi_module(sct_id)};
123 
124  // Check if the silicon surface is 100.
125  SiliconSurface surface{surface111};
126  for (unsigned int i{0}; i < layer100_n; i++) {
127  if ((layer100[i] == layer) and (eta100[i] == eta) and (phi100[i] == phi)) {
128  surface = surface100;
129  break;
130  }
131  }
132  // find cluster size
133  const std::vector<Identifier>& rdoList{RawDataClus->rdoList()};
134  int nStrip{static_cast<int>(rdoList.size())};
135  const Trk::TrackParameters* trkp{dynamic_cast<const Trk::TrackParameters*>(tsos->trackParameters())};
136  if (trkp==nullptr) {
137  ATH_MSG_WARNING(" Null pointer to MeasuredTrackParameters");
138  continue;
139  }
140  const Trk::Perigee* perigee{track->perigeeParameters()};
141 
142  if (perigee) {
143  // Get angle to wafer surface
144  float phiToWafer{90.f};
145  float thetaToWafer(90.f);
146  float sinAlpha{0.f}; // for barrel, which is the only thing considered here
147  float pTrack[3]; // 3 is for x, y, z.
148  pTrack[0] = trkp->momentum().x();
149  pTrack[1] = trkp->momentum().y();
150  pTrack[2] = trkp->momentum().z();
151  float etaTrack = trkp->eta();
152  int iflag{findAnglesToWaferSurface(pTrack, sinAlpha, clus->identify(), elements, thetaToWafer, phiToWafer)};
153  if (iflag < 0) {
154  ATH_MSG_WARNING("Error in finding track angles to wafer surface");
155  continue; // Let's think about this (later)... continue, break or return?
156  }
157 
158  bool passesCuts{true};
159  // The cuts for the physics runs follow ATL-COM-INDET-2021-011.
161  (trkp->momentum().perp() > 500.) and // Pt > 500MeV
162  (summary->get(Trk::numberOfSCTHits) > 6) // #SCTHits >6
163  ) {
164  passesCuts = true;
165  } else if ((track->perigeeParameters()->parameters()[Trk::qOverP] < 0.) and // use negative track only
166  (std::abs(perigee->parameters()[Trk::d0]) < 1.) and // d0 < 1mm
167  (trkp->momentum().perp() > 500.) and // Pt > 500MeV
168  (summary->get(Trk::numberOfSCTHits) > 6)// and // #SCTHits >6
169  ) {
170  passesCuts = true;
171  } else {
172  passesCuts = false;
173  }
174 
175  if (passesCuts) {
176  // Fill profile
177  std::string xVar{"phiToWafer"};
178  std::string yVar{"nStrip"};
179  if(bec == 0){ // Barrel
180  xVar += "_" + std::to_string(layer);
181  yVar += "_" + std::to_string(layer);
182  if(surface == surface100){
183  xVar += "_100";
184  yVar += "_100";
185  }
186  if(surface == surface111){
187  xVar += "_111";
188  yVar += "_111";
189  }
190  } else { // Endcaps
191  if (bec == -2) {
192  xVar += "_ECC";
193  yVar += "_ECC";
194  } else {
195  xVar += "_ECA";
196  yVar += "_ECA";
197  }
198  xVar += std::to_string(layer);
199  yVar += std::to_string(layer);
200  if (eta == 0) {
201  xVar += "_outer";
202  yVar += "_outer";
203  } else if (eta == 1) {
204  xVar += "_middle";
205  yVar += "_middle";
206  } else {
207  xVar += "_inner";
208  yVar += "_inner";
209  }
210  } // Common for barrel and endcaps
211  if(side == side0){
212  xVar += "_0";
213  yVar += "_0";
214  }
215  if(side == side1){
216  xVar += "_1";
217  yVar += "_1";
218  }
219 
220  auto phiToWaferAcc{Monitored::Scalar<float>(xVar, phiToWafer)};
221  auto nStripAcc{Monitored::Scalar<int>(yVar, nStrip)};
222  auto isCentralAcc{Monitored::Scalar<bool>("isCentral", (etaTrack < 0.5))};
223  fill("SCTLorentzMonitor", phiToWaferAcc, nStripAcc, isCentralAcc);
224  }// end if passesCuts
225  }// end if mtrkp
226  } // end if SCT..
227  } // end if (clus)
228  } // if (tsos->type(Trk::TrackStateOnSurface::Measurement)) {
229  }// end of loop on TrackStatesonSurface (they can be SiClusters, TRTHits,..)
230  } // end of loop on tracks
231 
232 
233  return StatusCode::SUCCESS;
234 }
235 
236 int
237 SCTLorentzMonAlg::findAnglesToWaferSurface(const float (&vec)[3], // 3 is for x, y, z.
238  const float& sinAlpha, const Identifier& id,
239  const InDetDD::SiDetectorElementCollection* elements,
240  float& theta, float& phi) const {
241  int iflag{-1};
242 
243  phi = 90.;
244  theta = 90.;
245 
246  const Identifier waferId{m_pSCTHelper->wafer_id(id)};
247  const IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
248  const InDetDD::SiDetectorElement* element{elements->getDetectorElement(waferHash)};
249  if (element==nullptr) {
250  ATH_MSG_ERROR("findAnglesToWaferSurface: failed to find detector element for id=" <<
252  return iflag;
253  }
254 
255  float cosAlpha{sqrt(1.0f - sinAlpha * sinAlpha)};
256  double phix{ cosAlpha * element->phiAxis().x() + sinAlpha * element->phiAxis().y()};
257  double phiy{-sinAlpha * element->phiAxis().x() + cosAlpha * element->phiAxis().y()};
258 
259  double pNormal{vec[0] * element->normal().x() + vec[1] * element->normal().y() + vec[2] * element->normal().z()};
260  double pEta{ vec[0] * element->etaAxis().x() + vec[1] * element->etaAxis().y() + vec[2] * element->etaAxis().z()};
261  double pPhi{ vec[0] * phix + vec[1] * phiy + vec[2] * element->phiAxis().z()};
262 
263  if (pPhi < 0.) {
264  phi = -90.;
265  }
266  if (pEta < 0.) {
267  theta = -90.;
268  }
269  if (pNormal != 0.) {
270  phi = atan(pPhi / pNormal) / CLHEP::deg;
271  theta = atan(pEta / pNormal) / CLHEP::deg;
272  }
273  iflag = 1;
274  return iflag;
275 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
PRDtoTrackMap.h
SCTLorentzMonAlg::m_SCTDetEleCollKey
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCTDetEleCollKey
Definition: SCTLorentzMonAlg.h:40
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
AthMonitorAlgorithm::dataType
DataType_t dataType() const
Accessor functions for the data type.
Definition: AthMonitorAlgorithm.h:221
SCT_ID.h
This is an Identifier helper class for the SCT subdetector. This class is a factory for creating comp...
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
InDetDD::SiDetectorElementCollection
Definition: SiDetectorElementCollection.h:30
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
ParticleGun_SamplingFraction.bec
int bec
Definition: ParticleGun_SamplingFraction.py:89
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:71
deg
#define deg
Definition: SbPolyhedron.cxx:17
SiClusterOnTrack.h
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
SCT_ID::barrel_ec
int barrel_ec(const Identifier &id) const
Values of different levels (failure returns 0)
Definition: SCT_ID.h:728
SCT_ID::phi_module
int phi_module(const Identifier &id) const
Definition: SCT_ID.h:740
SCTLorentzMonAlg::findAnglesToWaferSurface
int findAnglesToWaferSurface(const float(&vec)[3], const float &sinAlpha, const Identifier &id, const InDetDD::SiDetectorElementCollection *elements, float &theta, float &phi) const
Definition: SCTLorentzMonAlg.cxx:237
SCTLorentzMonAlg::SCTLorentzMonAlg
SCTLorentzMonAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: SCTLorentzMonAlg.cxx:19
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
TRT::Hit::side
@ side
Definition: HitInfo.h:83
AthMonitorAlgorithm
Base class for Athena Monitoring Algorithms.
Definition: AthMonitorAlgorithm.h:36
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SCTLorentzMonAlg::m_tracksName
SG::ReadHandleKey< TrackCollection > m_tracksName
Name of the Track collection to use.
Definition: SCTLorentzMonAlg.h:39
SCTLorentzMonAlg::side1
@ side1
Definition: SCTLorentzMonAlg.h:31
lumiFormat.i
int i
Definition: lumiFormat.py:92
SCTLorentzMonAlg::surface111
@ surface111
Definition: SCTLorentzMonAlg.h:30
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
Trk::numberOfSCTHits
@ numberOfSCTHits
number of SCT holes
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:71
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
SCTLorentzMonAlg::side0
@ side0
Definition: SCTLorentzMonAlg.h:31
SCTLorentzMonAlg.h
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
SCTLorentzMonAlg::initialize
virtual StatusCode initialize() override final
initialize
Definition: SCTLorentzMonAlg.cxx:23
SCT_ID::wafer_hash
IdentifierHash wafer_hash(const Identifier &wafer_id) const
wafer hash from id - optimized
Definition: SCT_ID.h:492
TrackSummary.h
Trk::ParametersBase
Definition: ParametersBase.h:55
AthMonitorAlgorithm::fill
void fill(const ToolHandle< GenericMonitoringTool > &groupHandle, std::vector< std::reference_wrapper< Monitored::IMonitoredVariable >> &&variables) const
Fills a vector of variables to a group by reference.
SCTLorentzMonAlg::m_pSCTHelper
const SCT_ID * m_pSCTHelper
Definition: SCTLorentzMonAlg.h:33
SCTLorentzMonAlg::surface100
@ surface100
Definition: SCTLorentzMonAlg.h:30
DataVector< const Trk::TrackStateOnSurface >
SCTLorentzMonAlg::fillHistograms
virtual StatusCode fillHistograms(const EventContext &ctx) const override final
adds event to the monitoring histograms
Definition: SCTLorentzMonAlg.cxx:33
Monitored.h
Header file to be included by clients of the Monitored infrastructure.
AthMonitorAlgorithm::DataType_t::cosmics
@ cosmics
Trk::TrackStateOnSurface
represents the track state (measurement, material, fit parameters and quality) at a surface.
Definition: TrackStateOnSurface.h:71
Trk::TrackSummary
A summary of the information contained by a track.
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:287
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
Trk::d0
@ d0
Definition: ParamDefs.h:69
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
SCT_ID::layer_disk
int layer_disk(const Identifier &id) const
Definition: SCT_ID.h:734
SiCluster.h
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
xAOD::TauJetParameters::nStrip
@ nStrip
Get number of strips.
Definition: TauDefs.h:204
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
SiDetectorElement.h
AthMonitorAlgorithm::initialize
virtual StatusCode initialize() override
initialize
Definition: AthMonitorAlgorithm.cxx:18
SCTLorentzMonAlg::m_trackSummaryTool
ToolHandle< Trk::ITrackSummaryTool > m_trackSummaryTool
Definition: SCTLorentzMonAlg.h:35
AtlasDetectorID::show_to_string
std::string show_to_string(Identifier id, const IdContext *context=0, char sep='.') const
or provide the printout in string form
Definition: AtlasDetectorID.cxx:574
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
SCTLorentzMonAlg::SiliconSurface
SiliconSurface
Definition: SCTLorentzMonAlg.h:30
SCT_ID::eta_module
int eta_module(const Identifier &id) const
Definition: SCT_ID.h:746
Trk::qOverP
@ qOverP
perigee
Definition: ParamDefs.h:73
SCT_ID::side
int side(const Identifier &id) const
Definition: SCT_ID.h:752
SCTLorentzMonAlg::m_assoTool
ToolHandle< Trk::IPRDtoTrackMapTool > m_assoTool
Definition: SCTLorentzMonAlg.h:36
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
SCTLorentzMonAlg::m_rejectSharedHits
BooleanProperty m_rejectSharedHits
Definition: SCTLorentzMonAlg.h:42
SCT_ID::wafer_id
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module, int side) const
For a single side of module.
Definition: SCT_ID.h:464
IdentifierHash
Definition: IdentifierHash.h:38
InDetDD::SiDetectorElementCollection::getDetectorElement
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Definition: SiDetectorElementCollection.cxx:15
Trk::PRDtoTrackMap::isShared
bool isShared(const PrepRawData &prd) const
does this PRD belong to more than one track?
InDet::SiCluster
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/SiCluster.h:40
Trk::TrackStateOnSurface::Measurement
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
Definition: TrackStateOnSurface.h:101
InDet::SiClusterOnTrack
Definition: SiClusterOnTrack.h:39
SCT_Monitoring::summary
@ summary
Definition: SCT_MonitoringNumbers.h:65