Selects and builds a cleaned vector of RIO fits the associatedHits and build new RIOs, if m_competingRios true then for ambiguous hits competing rios are built.
52{
53
54
55 int time_start = std::clock() / 1000;
56
57 std::vector<std::unique_ptr<const Trk::MeasurementBase>> selectedHits{}, selectedClusters{};
58
60
61 int nhits = associatedHits.size() + unassociatedHits.size();
62
63 ATH_MSG_DEBUG(
"Executing MuonPhiHitSelectorTool nhits select_rio " << nhits);
64
65 std::vector<double> phiHitx(nhits);
66 std::vector<double> phiHity(nhits);
67 std::vector<double> phiHitz(nhits);
68 std::vector<double> phiError(nhits);
69 std::vector<Identifier> phiId(nhits);
70 std::vector<double> phiPull(nhits);
71 std::vector<int> phiSelect(nhits);
72 std::vector<int> phiMult(nhits);
73 std::vector<int> quality(nhits);
74 std::vector<const Trk::PrepRawData*> phiPrep(nhits);
75
76 std::map<Identifier, int> phiMapId;
77 int nphi = 0;
78
79 for (const Trk::RIO_OnTrack* rot : associatedHits) {
80 Identifier id = rot->identify();
84 phiSelect[nphi] = 1;
86 phiSelect[nphi] = 2;
88 phiSelect[nphi] = 3;
89 }
90 phiHitx[nphi] = gHitPos.x();
91 phiHity[nphi] = gHitPos.y();
92 phiHitz[nphi] = gHitPos.z();
93
96
97
100 Er(0, 0) =
cov(0, 0);
101 Er(0, 1) =
cov(0, 1);
102 Er(1, 1) =
cov(1, 1);
103 Er(1, 0) = Er(0, 1);
104
105 double chi = Er(0, 0) != Er(1, 1) ? std::atan(-2 * Er(0, 1) / (Er(0, 0) - Er(1, 1))) / 2. : 0.;
106
107 CxxUtils::sincos scchi(chi);
108
110 Rot(0, 0) = scchi.cs;
111 Rot(1, 1) = Rot(0, 0);
112 Rot(0, 1) = scchi.sn;
113 Rot(1, 0) = -Rot(0, 1);
114 AmgMatrix(2, 2) D = Rot.transpose() * Er * Rot;
116 error = std::
min(D(0, 0),D(1, 1));
117 }
118 phiError[nphi] = std::sqrt(error);
119 quality[nphi] = 1000;
120 phiMapId[id] = 1;
121 phiPrep[nphi] = rot->prepRawData();
122 double phipos = std::atan2(phiHity[nphi], phiHitx[nphi]);
123 ATH_MSG_DEBUG(
"phi Segment Hit " << nphi <<
" det " << phiSelect[nphi] <<
" phi " << phipos);
124 nphi++;
125 }
126 int nphiseg = nphi;
127
128 for (const Trk::PrepRawData* prd : unassociatedHits) {
129 Identifier id = prd->identify();
131
132 if (phiMapId.count(id)) continue;
133 const Muon::MuonCluster* clus = dynamic_cast<const Muon::MuonCluster*>(prd);
136 phiSelect[nphi] = 1;
138 phiSelect[nphi] = 2;
140 phiSelect[nphi] = 3;
142 phiHitx[nphi] = gHitPos.x();
143 phiHity[nphi] = gHitPos.y();
144 phiHitz[nphi] = gHitPos.z();
145 phiError[nphi] = prd->localCovariance()(
Trk::locX);
146 quality[nphi] = 10;
147 phiPrep[nphi] = prd;
148 double phipos = std::atan2(phiHity[nphi], phiHitx[nphi]);
149 ATH_MSG_DEBUG(
"phi Pattern Hit " << nphi <<
" phi " << phipos);
150 nphi++;
151 }
152
155 int nfit;
156 std::vector<double> errorM(4);
158 fitRecPhi(pmom, phiId, phiHitx, phiHity, phiHitz, phiError, quality, nphi, phiPull, phiMult, phiSelect,
chi2, r0,
160
161
162
163 for (
int i = 0;
i < nphi; ++
i) {
164 if (phiSelect[i] > 0) {
165 if (phiSelect[i] == 1) {
166 const Muon::RpcPrepData* prd =
dynamic_cast<const Muon::RpcPrepData*
>(phiPrep[
i]);
167 const Amg::Vector3D globalpos(phiHitx[i], phiHity[i], phiHitz[i]);
168 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
169 if (rio) selectedHits.push_back(std::move(rio));
170 } else if (phiSelect[i] == 2) {
171 const Muon::TgcPrepData* prd =
dynamic_cast<const Muon::TgcPrepData*
>(phiPrep[
i]);
172 const Amg::Vector3D globalpos(phiHitx[i], phiHity[i], phiHitz[i]);
173 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
174 if (rio) selectedHits.push_back(std::move(rio));
175 } else if (phiSelect[i] == 3) {
176 const Muon::CscPrepData* prd =
dynamic_cast<const Muon::CscPrepData*
>(phiPrep[
i]);
177 const Amg::Vector3D globalpos(phiHitx[i], phiHity[i], phiHitz[i]);
178 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_cscRotCreator->createRIO_OnTrack(*prd, globalpos)};
179 if (rio) selectedHits.push_back(std::move(rio));
180 }
181
183 }
184 }
186 << " pattern hits " << nphi - nphiseg << " nfit " << nfit << " rio size "
187 << selectedHits.size());
188
189
190 std::vector<double> clusterX(nphi);
191 std::vector<double> clusterY(nphi);
192 std::vector<double> clusterZ(nphi);
193 std::vector<double> clusterError(nphi);
194 std::vector<Identifier> clusterId(nphi);
195 std::vector<int> clusterHits(nphi);
196 std::vector<double> clusterPull(nphi);
197 std::vector<int> clusterSelect(nphi);
198
199 std::vector<int> clusterInt(nphi);
200
202 double chi2cl, r0cl, phicl;
203 std::vector<double> errorMcl(4);
204 clusterPhi(phiId, phiHitx, phiHity, phiHitz, phiError, phiPull, phiSelect, nphi, clusterX, clusterY, clusterZ,
205 clusterError, clusterId, clusterHits, clusterSelect, clusterInt, ncl);
206
207
208 for (
int ic = 0;
ic < ncl; ++
ic) {
209 std::list<const Trk::PrepRawData*> prdList;
210 int iic = -1;
211 double avError = 0.;
214 for (
int i = 0;
i < nphi; ++
i) {
215 if (clusterInt[i] == ic) {
217 prdList.push_back(phiPrep[i]);
218 avError += 1. / (phiError[
i] * phiError[
i]);
219 if (clusterId[ic] == phiId[i]) iic =
i;
221 }
222 }
223 if (iic > -1) {
224 ATH_MSG_DEBUG(
"Phi cluster found np " << np <<
" ip " << ip);
225 if (np == 1) {
226
227 const Amg::Vector3D globalpos(clusterX[ic], clusterY[ic], clusterZ[ic]);
228 if (phiSelect[ip] == 1) {
230 const Muon::RpcPrepData* prd =
dynamic_cast<const Muon::RpcPrepData*
>(phiPrep[
ip]);
231 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
232 if (rio) selectedClusters.push_back(std::move(rio));
233 } else if (phiSelect[ip] == 2) {
235 const Muon::TgcPrepData* prd =
dynamic_cast<const Muon::TgcPrepData*
>(phiPrep[
ip]);
236 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
237 if (rio) selectedClusters.push_back(std::move(rio));
238 } else if (phiSelect[ip] == 3) {
240 const Muon::CscPrepData* prd =
dynamic_cast<const Muon::CscPrepData*
>(phiPrep[
ip]);
241 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_cscRotCreator->createRIO_OnTrack(*prd, globalpos)};
242 if (rio) selectedClusters.push_back(std::move(rio));
243 }
244 } else {
245
247
248 avError = std::sqrt(1. / avError);
249 double scaleFactor = clusterError[
ic] / avError;
250 std::unique_ptr<const Trk::CompetingRIOsOnTrack> rio =
252 selectedClusters.push_back(std::move(rio));
255 << " scale factor " << scaleFactor << " number of rios " << prdList.size());
256 } else {
257
259 const Amg::Vector3D globalpos(clusterX[ic], clusterY[ic], clusterZ[ic]);
260 if (phiSelect[ip] == 1) {
262 const Muon::RpcPrepData* prd =
dynamic_cast<const Muon::RpcPrepData*
>(phiPrep[
ip]);
263 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
264 if (rio) selectedClusters.push_back(std::move(rio));
265 } else if (phiSelect[ip] == 2) {
267 const Muon::TgcPrepData* prd =
dynamic_cast<const Muon::TgcPrepData*
>(phiPrep[
ip]);
268 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
269 if (rio) selectedClusters.push_back(std::move(rio));
270 } else if (phiSelect[ip] == 3) {
272 const Muon::CscPrepData* prd =
dynamic_cast<const Muon::CscPrepData*
>(phiPrep[
ip]);
273 std::unique_ptr<const Muon::MuonClusterOnTrack> rio{
m_clusterCreator->createRIO_OnTrack(*prd, globalpos)};
274 if (rio) selectedClusters.push_back(std::move(rio));
275 }
276 }
277 }
278 } else {
280 }
281 }
282
283 fitPhiSL(pmom, clusterId, clusterX, clusterY, clusterZ, clusterError, clusterSelect, ncl, clusterPull,
imax, chi2cl,
284 r0cl, phicl, errorMcl, false);
285
286
288 ATH_MSG_DEBUG(
"PhiHitSelector Time spent " << std::clock() / 1000 - time_start <<
" nhits " << nhits
289 << " segment hits " << associatedHits.size() << " nfit " << nfit
290 << " nclusters " << ncl);
291 ATH_MSG_DEBUG(
"Fit cluster results phi " << phicl <<
" chi2 " << chi2cl <<
" number of clusters " << ncl
292 << " size cluster Hits " << selectedClusters.size());
293 }
295 return selectedClusters;
296 }
297 return selectedHits;
298}
#define AmgSymMatrix(dim)
#define AmgMatrix(rows, cols)
Gaudi::Property< bool > m_makeClusters
flag that performs a clusterization and return clusters (default: false)
Gaudi::Property< bool > m_summary
flag to print out a summary of what comes in and what comes out
Gaudi::Property< bool > m_competingRios
flag that build competing rios on track for amibguous trigger hits (default: false)
void clusterPhi(const std::vector< Identifier > &id, const std::vector< double > &hitx, const std::vector< double > &hity, const std::vector< double > &hitz, const std::vector< double > &error, const std::vector< double > &pull, std::vector< int > &select, const int n, std::vector< double > &clusterX, std::vector< double > &clusterY, std::vector< double > &clusterZ, std::vector< double > &clusterError, std::vector< Identifier > &clusterId, std::vector< int > &clusterHits, std::vector< int > &clusterSelect, std::vector< int > &clusterInt, int &ncl) const
clusterization method
void fitRecPhi(const double pmom, const std::vector< Identifier > &phiId, const std::vector< double > &phiHitx, const std::vector< double > &phiHity, const std::vector< double > &phiHitz, const std::vector< double > &phiError, std::vector< int > &quality, const int nphi, std::vector< double > &phiPull, std::vector< int > &phiMult, std::vector< int > &phiSelect, double &chi2, double &r0, double &phi, std::vector< double > &errorM, int &nfit) const
fit method curved track model
Eigen::Matrix< double, 3, 1 > Vector3D