ATLAS Offline Software
Loading...
Searching...
No Matches
SCTLorentzMonAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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
19SCTLorentzMonAlg::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());
27 ATH_CHECK(m_SCTDetEleCollKey.initialize());
28 ATH_CHECK(m_assoTool.retrieve(DisableTool{!m_rejectSharedHits} ));
29
31}
32
33StatusCode 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;
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(ctx,*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) {
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
236int
237SCTLorentzMonAlg::findAnglesToWaferSurface(const float (&vec)[3], // 3 is for x, y, z.
238 const float& sinAlpha, const Identifier& id,
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=" <<
251 m_pSCTHelper->show_to_string(id));
252 return iflag;
253 }
254
255 float cosAlpha{std::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 = std::atan(pPhi / pNormal) / CLHEP::deg;
271 theta = std::atan(pEta / pNormal) / CLHEP::deg;
272 }
273 iflag = 1;
274 return iflag;
275}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::vector< size_t > vec
Header file to be included by clients of the Monitored infrastructure.
This is an Identifier helper class for the SCT subdetector.
const ServiceHandle< StoreGateSvc > & detStore() const
virtual StatusCode initialize() override
initialize
DataType_t dataType() const
Accessor functions for the data type.
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
This is a "hash" representation of an Identifier.
Class to hold the SiDetectorElement objects to be put in the detector store.
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Class to hold geometrical description of a silicon detector element.
virtual const Amg::Vector3D & normal() const override final
Get reconstruction local normal axes in global frame.
RIO_OnTrack base class for Silicon detector in the InnerDetector.
virtual const InDetDD::SiDetectorElement * detectorElement() const override final
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
Declare a monitored scalar variable.
ToolHandle< Trk::ITrackSummaryTool > m_trackSummaryTool
int findAnglesToWaferSurface(const float(&vec)[3], const float &sinAlpha, const Identifier &id, const InDetDD::SiDetectorElementCollection *elements, float &theta, float &phi) const
virtual StatusCode fillHistograms(const EventContext &ctx) const override final
adds event to the monitoring histograms
const SCT_ID * m_pSCTHelper
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCTDetEleCollKey
SCTLorentzMonAlg(const std::string &name, ISvcLocator *pSvcLocator)
BooleanProperty m_rejectSharedHits
SG::ReadHandleKey< TrackCollection > m_tracksName
Name of the Track collection to use.
ToolHandle< Trk::IPRDtoTrackMapTool > m_assoTool
virtual StatusCode initialize() override final
initialize
const_pointer_type retrieve()
virtual bool isValid() override final
Can the handle be successfully dereferenced?
double eta() const
Access method for pseudorapidity - from momentum.
const Amg::Vector3D & momentum() const
Access method for the momentum.
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
Identifier identify() const
return the identifier -extends MeasurementBase
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
A summary of the information contained by a track.
DataVector< const Trk::TrackStateOnSurface > TrackStates
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ qOverP
perigee
Definition ParamDefs.h:67
@ d0
Definition ParamDefs.h:63
ParametersBase< TrackParametersDim, Charged > TrackParameters
void fill(H5::Group &out_file, size_t iterations)