ATLAS Offline Software
Loading...
Searching...
No Matches
Csc2dSegmentMaker.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "Csc2dSegmentMaker.h"
6
7#include <cmath>
8#include <sstream>
9
19#include "TrkRoad/TrackRoad.h"
20#include "TrkSegment/Segment.h"
21
26
31
34
35namespace {
36
37 std::string measphi_name(bool measphi) {
38 if (measphi) return "phi";
39 return "eta";
40 }
41
42 // Convert chamber identifier to string.
43 std::string chamber(int istation, int zsec, int phi) {
44 std::ostringstream ssout;
45 if (istation == 1)
46 ssout << "CSS";
47 else if (istation == 2)
48 ssout << "CSL";
49 else
50 ssout << "???";
51 if (zsec == -1)
52 ssout << "-";
53 else if (zsec == 1)
54 ssout << "+";
55 else
56 ssout << "?";
57 ssout << phi;
58 return ssout.str();
59 }
60
61} // namespace
62
63//******************************************************************************
64
65Csc2dSegmentMaker::Csc2dSegmentMaker(const std::string& type, const std::string& aname, const IInterface* parent) :
66 AthAlgTool(type, aname, parent) {
67 declareInterface<ICscSegmentFinder>(this);
68}
69
70//******************************************************************************
71
73 ATH_MSG_DEBUG("Initializing " << name());
74 // Show keys.
75 ATH_MSG_DEBUG(" SegmentTool: " << m_segmentTool.typeAndName());
76 ATH_MSG_DEBUG(" Input cscdig key: " << m_cscdig_sg_inkey);
77 ATH_CHECK(m_idHelperSvc.retrieve());
78 ATH_CHECK(m_segmentTool.retrieve());
80 ATH_CHECK(m_printer.retrieve());
81 return StatusCode::SUCCESS;
82}
83
84//******************************************************************************
85std::unique_ptr<MuonSegmentCombinationCollection> Csc2dSegmentMaker::find(const std::vector<const Muon::CscPrepDataCollection*>& pcols,
86 const EventContext& ctx) const {
87 // Construct output segment collection.
88 std::unique_ptr<MuonSegmentCombinationCollection> mpsegs(new MuonSegmentCombinationCollection);
89
90 for (unsigned int icol = 0; icol < pcols.size(); ++icol) {
91 const CscPrepDataCollection* clus = pcols[icol];
92 if (clus->empty()) continue; // skip zero cluster collection
93 break;
94 }
95
96 unsigned int col_count = 0;
97 // Loop over collections in the container.
98 for (unsigned int icol = 0; icol < pcols.size(); ++icol) {
99 const CscPrepDataCollection* clus = pcols[icol];
100 ++col_count;
101 ATH_MSG_VERBOSE("** Collection " << col_count << " has " << clus->size() << " clusters");
102
103 if (clus->empty()) continue; // skip zero cluster collection
105 if (pcol) {
106 mpsegs->push_back(pcol);
107 ATH_MSG_DEBUG("Found 2d CSC segment " << m_printer->print(*pcol));
108 }
109 }
110
111 if (!mpsegs->empty())
112 ATH_MSG_DEBUG("found " << mpsegs->size() << " 2d csc segments");
113 else
114 mpsegs.reset();
115
116 return mpsegs;
117}
118
119//******************************************************************************
120
122 // check whether input not empty
123 if (clus.empty()) return nullptr;
124
125 int col_station = 0;
126 int col_eta = 0;
127 int col_phisec = 0;
128 Identifier eta_id, phi_id;
129
130 ChamberTrkClusters eta_clus, phi_clus;
131
132 const MuonGM::CscReadoutElement* detEl = clus.front()->detectorElement();
133 if (!detEl) {
134 ATH_MSG_WARNING("Failed to obtain CscReadoutElement for cluster");
135 return nullptr;
136 }
137 Amg::Transform3D gToLocal = detEl->GlobalToAmdbLRSTransform();
138 Amg::Vector3D lpos000 = gToLocal * Amg::Vector3D(0.0, 0.0, 0.0);
139
140 int stationEta = detEl->getStationEta();
141 int stationPhi = detEl->getStationPhi();
142 int chamberLayer = detEl->ChamberLayer();
143 std::string stationName = detEl->getStationName();
144 std::string redName = stationName.substr(0, 3); // CSS or CSL, all that the CscIdHelper wants
145 std::string isPhi;
146 ATH_MSG_DEBUG("in station " << stationName << " eta " << stationEta << ", phi " << stationPhi << ", chamber layer " << chamberLayer);
147 // new method: we no longer assume automatically that eta and phi go together
148 // this is the usual reason for problems due to broken wires, but it need not always be the case
149 // instead, pass the status of every layer to the CscSegmentUtilTool
150 // if there are only 2 layers for eta or phi, do 2-layer segment finding for eta or phi
151 // if there are fewer than two good layers for eta or phi, so no eta or phi segment can be made, the final segment need not include
152 // information from the missing side
153
154 int layStatus[2] = {
155 0, 0}; // eta=0,phi=1; each decimal place will be 0 for good, 1 for bad, so 1001 means first and 4th layers are bad, etc.
156 for (int iLay = 0; iLay < 4; iLay++) { // loop over the layers in this chamber
157 for (int iPhi = 0; iPhi < 2; iPhi++) { // eta or phi
158 int nbad = 0;
159 if (iPhi)
160 isPhi = "phi";
161 else
162 isPhi = "eta";
163 // ATH_MSG_DEBUG("get hashes for "<<detEl->maxNumberOfStrips(iPhi)<<" strips ");
164 for (int iStrip = 0; iStrip < detEl->maxNumberOfStrips(iPhi); iStrip++) {
165 ATH_MSG_DEBUG("get strip quality for " << isPhi << " layer " << iLay << " strip " << iStrip);
166 Identifier stripId =
167 m_idHelperSvc->cscIdHelper().channelID(redName, stationEta, stationPhi, chamberLayer, iLay + 1, iPhi, iStrip + 1);
168 IdentifierHash hashID;
169 m_idHelperSvc->cscIdHelper().get_channel_hash(stripId, hashID);
170 if (!m_segmentTool->isGood(hashID, ctx)) {
171 ATH_MSG_DEBUG("bad strip");
172 nbad++;
173 }
174 }
175 ATH_MSG_DEBUG("found " << nbad << " bad strips out of " << detEl->maxNumberOfStrips(iPhi) << " in " << isPhi << " layer "
176 << iLay);
177 if (nbad == detEl->maxNumberOfStrips(iPhi)) { layStatus[iPhi] += pow(10, iLay); }
178 }
179 }
180 ATH_MSG_DEBUG("final status for eta is " << layStatus[0] << " and phi " << layStatus[1]);
181
182 for (CscPrepDataCollection::const_iterator iclu = clus.begin(); iclu != clus.end(); ++iclu) {
183 const CscPrepData* pclu = *iclu;
184 Identifier id = pclu->identify();
185 int station = m_idHelperSvc->cscIdHelper().stationName(id) - 49;
186 int eta = m_idHelperSvc->cscIdHelper().stationEta(id);
187 int phisec = m_idHelperSvc->cscIdHelper().stationPhi(id);
188 int iwlay = m_idHelperSvc->cscIdHelper().wireLayer(id);
189 bool measphi = m_idHelperSvc->cscIdHelper().measuresPhi(id);
190
191 if (iclu == clus.begin()) {
192 col_station = station;
193 col_eta = eta;
194 col_phisec = phisec;
195 }
196 ATH_MSG_DEBUG("****** " << chamber(station, eta, phisec) << measphi_name(measphi) << iwlay);
197
198 if (station != col_station || eta != col_eta || phisec != col_phisec) {
199 ATH_MSG_WARNING("Inconsistent collection contents");
200 return nullptr;
201 }
202
203 const Muon::MuonClusterOnTrack* clu = m_cscClusterOnTrackCreator->createRIO_OnTrack(*pclu, pclu->globalPosition());
204 const Muon::CscClusterOnTrack* ptclu = dynamic_cast<const Muon::CscClusterOnTrack*>(clu);
205 if (!ptclu) {
206 ATH_MSG_WARNING("Failed to create CscClusterOnTrack from PRD");
207 delete clu;
208 continue;
209 }
210 Amg::Vector3D lpos = gToLocal * ptclu->globalPosition();
211 if (measphi) {
212 phi_id = id;
213 phi_clus[iwlay - 1].emplace_back(lpos, ptclu, measphi);
214 } else {
215 eta_id = id;
216 eta_clus[iwlay - 1].emplace_back(lpos, ptclu, measphi);
217 }
218 }
219
220 // Insert r-phi-segments.
221
222 int nHitLayer_eta = 0;
223 int nHitLayer_phi = 0;
224 for (int i = 0; i < 4; ++i) {
225 if (!eta_clus[i].empty()) ++nHitLayer_eta;
226 if (!phi_clus[i].empty()) ++nHitLayer_phi;
227 }
228 ATH_MSG_DEBUG("there are " << nHitLayer_eta << " eta hit layers and " << nHitLayer_phi << " phi hit layers");
229
230 // MuonSegmentCombination* pcol;
231 MuonSegmentCombination* pcol = nullptr;
232 if (nHitLayer_eta >= 2 || nHitLayer_phi >= 2) {
233 ATH_MSG_DEBUG("Csc2dSegment calls get2dMuonSegmentCombination !!!");
234 pcol = m_segmentTool->get2dMuonSegmentCombination(eta_id, phi_id, eta_clus, phi_clus, lpos000, ctx, layStatus[0], layStatus[1]);
235 }
236
237 // to avoid memory leak
238 for (unsigned int i = 0; i < 4; ++i) {
239 for (TrkClusters::iterator itclus = eta_clus[i].begin(); itclus != eta_clus[i].end(); ++itclus) { delete itclus->cl; }
240 eta_clus[i].clear();
241 for (TrkClusters::iterator itclus = phi_clus[i].begin(); itclus != phi_clus[i].end(); ++itclus) { delete itclus->cl; }
242 phi_clus[i].clear();
243 }
244
245 return pcol;
246}
247
248//******************************************************************************
249std::unique_ptr<MuonSegmentCombinationCollection> Csc2dSegmentMaker::find(const MuonSegmentCombinationCollection&,
250 const EventContext&) const {
251 return {};
252}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
DataVector< Muon::MuonSegmentCombination > MuonSegmentCombinationCollection
This typedef represents a collection of MuonSegmentCombination objects.
static const Attributes_t empty
constexpr int pow(int base, int exp) noexcept
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
std::unique_ptr< MuonSegmentCombinationCollection > find(const std::vector< const Muon::CscPrepDataCollection * > &pcols, const EventContext &ctx) const
ToolHandle< ICscSegmentUtilTool > m_segmentTool
Csc2dSegmentMaker(const std::string &, const std::string &, const IInterface *)
PublicToolHandle< Muon::MuonEDMPrinterTool > m_printer
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
ToolHandle< Muon::IMuonClusterOnTrackCreator > m_cscClusterOnTrackCreator
Gaudi::Property< std::string > m_cscdig_sg_inkey
Muon::MuonSegmentCombination * findSegmentCombination(const Muon::CscPrepDataCollection &pcol, const EventContext &ctx) const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
const_iterator begin() const noexcept
const PrepDataT * front() const
size_type size() const noexcept
bool empty() const noexcept
std::vector< Cluster > ChamberTrkClusters[4]
This is a "hash" representation of an Identifier.
int maxNumberOfStrips(int measuresPhi) const
Class to represent the calibrated clusters created from CSC strips.
Class representing clusters from the CSC.
Definition CscPrepData.h:39
virtual const Amg::Vector3D & globalPosition() const override final
Returns the global position.
virtual const MuonGM::CscReadoutElement * detectorElement() const override final
Return the detector element corresponding to this PRD.
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
Base class for Muon cluster RIO_OnTracks.
virtual const Amg::Vector3D & globalPosition() const override
Returns global position.
Class to hold a set of MuonSegments belonging together.
This is the common class for 3D segments used in the muon spectrometer.
Identifier identify() const
return the identifier
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
MuonPrepDataCollection< CscPrepData > CscPrepDataCollection
MuonPrepDataContainerT< CscStripPrepData > CscStripPrepDataContainer
MuonPrepDataContainerT< CscPrepData > CscPrepDataContainer