ATLAS Offline Software
Loading...
Searching...
No Matches
NswStationFitter.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 "NswStationFitter.h"
7
8#include "RecMuonRoIUtils.h"
9#include <cmath>
11
12#include <vector>
13#include <array>
14
15namespace{
16 constexpr double ZERO_LIMIT = 1.e-9;
17}
18
19static const double TanM1p5 = std::tan(-1.5/360.*2.*M_PI);
20static const double TanP1p5 = std::tan(1.5/360.*2.*M_PI);
21static const double CosM1p5 = std::cos(-1.5/360.*2.*M_PI);
22static const double CosP1p5 = std::cos(1.5/360.*2.*M_PI);
23static const double SinM1p5 = std::sin(-1.5/360.*2.*M_PI);
24static const double SinP1p5 = std::sin(1.5/360.*2.*M_PI);
25
27 const std::string& name,
28 const IInterface* parent):
29 AthAlgTool(type,name,parent)
30{
31}
32
34 TrigL2MuonSA::TrackPattern& trackPattern,
35 TrigL2MuonSA::StgcHits& stgcHits,
36 TrigL2MuonSA::MmHits& mmHits) const
37{
38
39 ATH_MSG_DEBUG("NswStationFitter::findSuperPoints() was called.");
40
41 // selection for sTGC hits, RoI matching based
42 ATH_CHECK( selectStgcHits(p_roids,trackPattern.stgcSegment) );
43 ATH_CHECK( selectMmHits(p_roids,trackPattern.mmSegment) );
44
47
48 bool isLargeStgc = false;
49 bool isSmallStgc = false;
50 if(stgcHits.size() != 0){
51 for(unsigned int iHit = 0; iHit < stgcHits.size(); iHit++){
52 if(stgcHits.at(iHit).isOutlier == 0){
53 if(stgcHits.at(iHit).stationName == 58) isLargeStgc = true;
54 else if(stgcHits.at(iHit).stationName == 57) isSmallStgc = true;
55 if(isLargeStgc && isSmallStgc) continue;
56 }
57 }
58 }
59 if(mmHits.size() != 0){
60 for(unsigned int iHit = 0; iHit < mmHits.size(); iHit++){
61 if(mmHits.at(iHit).isOutlier == 0){
62 if(isLargeStgc){
63 if(mmHits.at(iHit).stationName == 55) mmHits.at(iHit).isOutlier = 1;
64 } else if(isSmallStgc) {
65 if(mmHits.at(iHit).stationName == 56) mmHits.at(iHit).isOutlier = 1;
66 }
67 }
68 }
69 }
70 ATH_CHECK( MakeSegment(trackPattern,stgcHits) );
71 ATH_CHECK( MakeSegment(trackPattern,mmHits) );
72
73 ATH_MSG_DEBUG("Number of sTGC and MM hits for SPs " << trackPattern.stgcSegment.size() << " " << trackPattern.mmSegment.size());
74 if (trackPattern.stgcSegment.size() < 9 && trackPattern.mmSegment.size() < 6) {
75 ATH_MSG_DEBUG("Number of sTGC and MM hits for SPs is small " << trackPattern.stgcSegment.size() + trackPattern.mmSegment.size());
76 }
77 else {
78 ATH_CHECK( calcMergedHit(trackPattern) );
79 }
80
81
82 return StatusCode::SUCCESS;
83
84}
85
87 TrigL2MuonSA::StgcHits& stgcHits) const
88{
89
90 TrigL2MuonSA::StgcHits selectedStgcHits;
91 selectedStgcHits.clear();
92
93 // define region where RoI is near
94 double etaMin = p_roids->eta() - 1.;
95 double etaMax = p_roids->eta() + 1.;
96 double phiMin = p_roids->phi() - 1.;
97 double phiMax = p_roids->phi() + 1.;
98 if( phiMin > M_PI ) phiMin -= 2*M_PI;
99 if( phiMax > M_PI ) phiMax -= 2*M_PI;
100 if( phiMin < -1.*M_PI ) phiMin += 2*M_PI;
101 if( phiMax < -1.*M_PI ) phiMax += 2*M_PI;
102 // boolian to check if sTGC hits are near RoI
103 bool inRoiEta, inRoiPhi, inRoi;
104
105 // loop over sTGC digits.
106 unsigned int iHit;
107 if (stgcHits.size()>0) {
108 for (iHit = 0; iHit < stgcHits.size(); iHit++){
109 // Get the digit point.
110 TrigL2MuonSA::StgcHitData& hit = stgcHits[iHit];
111
112 // check if sTGC hits are near RoI
113 inRoiEta = false; inRoiPhi = false; inRoi = false;
114 if ( etaMin<=hit.eta && hit.eta<=etaMax ) inRoiEta = true;
115 if ( phiMin<=phiMax && phiMin<=hit.phi && hit.phi<=phiMax ) inRoiPhi= true;
116 if ( phiMin>phiMax && (phiMin<=hit.phi || hit.phi<=phiMax)) inRoiPhi= true;
117 if ( inRoiEta && inRoiPhi ) inRoi = true;
118 ATH_MSG_DEBUG("sTGC hits eta = "<<hit.eta<<", phi = "<<hit.phi<<", r = "<<hit.r<<", z = "<<hit.z<<", stationEta = "<<hit.stationEta<<", stationPhi = "<<hit.stationPhi<<", channelType = "<<hit.channelType<<", stationName = "<<hit.stationName<<",layerNumber ="<<hit.layerNumber<<", matched RoI? = "<<inRoi);
119 // pushback if the hit is near RoI
120 if (!inRoi){
121 continue;
122 }
123 selectedStgcHits.push_back(hit);
124 }
125 }
126
127 stgcHits.clear();
128 stgcHits = selectedStgcHits;
129
130 return StatusCode::SUCCESS;
131
132}
133
135 TrigL2MuonSA::MmHits& mmHits) const
136{
137
138 TrigL2MuonSA::MmHits selectedMmHits;
139 selectedMmHits.clear();
140
141 // define region where RoI is near
142 double etaMin = p_roids->eta() - 1.;
143 double etaMax = p_roids->eta() + 1.;
144 double phiMin = p_roids->phi() - 1.;
145 double phiMax = p_roids->phi() + 1.;
146 if( phiMin > M_PI ) phiMin -= 2*M_PI;
147 if( phiMax > M_PI ) phiMax -= 2*M_PI;
148 if( phiMin < -1.*M_PI ) phiMin += 2*M_PI;
149 if( phiMax < -1.*M_PI ) phiMax += 2*M_PI;
150 // boolian to check if sTGC hits are near RoI
151 bool inRoiEta, inRoiPhi, inRoi;
152
153 // loop over MM digits.
154 unsigned int iHit;
155 if (mmHits.size()>0) {
156 for (iHit = 0; iHit < mmHits.size(); iHit++){
157
158 // Get the digit point.
159 TrigL2MuonSA::MmHitData& hit = mmHits[iHit];
160
161 // check if MM hits are near RoI
162 inRoiEta = false; inRoiPhi = false; inRoi = false;
163 if ( etaMin<=hit.eta && hit.eta<=etaMax ) inRoiEta = true;
164 if ( phiMin<=phiMax && phiMin<=hit.phi && hit.phi<=phiMax ) inRoiPhi= true;
165 if ( phiMin>phiMax && (phiMin<=hit.phi || hit.phi<=phiMax)) inRoiPhi= true;
166 if ( inRoiEta && inRoiPhi ) inRoi = true;
167 ATH_MSG_DEBUG("MM hits eta = "<<hit.eta<<", phi = "<<hit.phi<<", r = "<<hit.r<<", z = "<<hit.z<<", stationEta = "<<hit.stationEta<<", stationPhi = "<<hit.stationPhi<<", stationName = "<<hit.stationName<<", matched RoI? = "<<inRoi);
168
169 // pushback if the hit is near RoI
170 if (!inRoi){
171 continue;
172 }
173 selectedMmHits.push_back(hit);
174 }
175 }
176
177 mmHits.clear();
178 mmHits = selectedMmHits;
179
180 return StatusCode::SUCCESS;
181
182}
183
185{
186
187 TrigL2MuonSA::StgcHits stgcHits = trackPattern.stgcSegment;
188 TrigL2MuonSA::MmHits mmHits = trackPattern.mmSegment;
189
190 if(stgcHits.size()==0 && mmHits.size()==0)
191 return StatusCode::SUCCESS;
192
193 //superpoint information
194 float rWeightedCenter=0.,zWeightedCenter=0.,phiWeightedCenter=0.;
195 int totNumRWeightedCenter=0.,totNumZWeightedCenter=0.,totNumPhiWeightedCenter=0.;
196 float localPhiCenter=0., localPhi;
197
198 // loop over sTGC digits.
199 unsigned int iHit;
200 if (stgcHits.size()>0) {
201 for (iHit = 0; iHit < stgcHits.size(); iHit++){
202
203 // Get the digit point.
204 TrigL2MuonSA::StgcHitData& hit = stgcHits[iHit];
205
206 if (iHit==0 && hit.stationPhi<=5) localPhiCenter = 0.25 * M_PI * ((float)hit.stationPhi-1.);
207 if (iHit==0 && hit.stationPhi> 5) localPhiCenter = 0.25 * M_PI * ((float)hit.stationPhi-9.);
208 if (hit.stationName == 57){
209 localPhiCenter += M_PI/8.; // small sTGC sectors
210 if (hit.stationPhi == 5) localPhiCenter -= 2 * M_PI;
211 }
212
213 localPhi = hit.phi - localPhiCenter;
214 if (localPhi > M_PI) localPhi -= 2.0*M_PI;
215 if (localPhi < -1.*M_PI) localPhi += 2.0*M_PI;
216 // calculate Weighted Center
217 if (hit.channelType == 1) { // strip
218 rWeightedCenter += hit.r;
219 totNumRWeightedCenter += 1;
220 }
221 if (hit.channelType == 2) { // wire
222 phiWeightedCenter += localPhi;
223 totNumPhiWeightedCenter += 1;
224 }
225 zWeightedCenter += hit.z;
226 totNumZWeightedCenter += 1;
227 }
228 }
229
230 // loop over MM digits.
231 if (mmHits.size()>0) {
232 for (iHit = 0; iHit < mmHits.size(); iHit++){
233
234 // Get the digit point.
235 TrigL2MuonSA::MmHitData& hit = mmHits[iHit];
236
237 if (hit.stationName == 55){
238 localPhiCenter += M_PI/8.; // small MM sectors
239 if (hit.stationPhi == 5) localPhiCenter -= 2 * M_PI;
240 }
241
242 localPhi = hit.phi - localPhiCenter;
243 if (localPhi > M_PI) localPhi -= 2.0*M_PI;
244 if (localPhi < -1.*M_PI) localPhi += 2.0*M_PI;
245 }
246 }
247
248 // calculate Weighted Center
249 if (totNumRWeightedCenter!=0) rWeightedCenter /= totNumRWeightedCenter;
250 if (totNumPhiWeightedCenter!=0) phiWeightedCenter /= totNumPhiWeightedCenter;
251 if (totNumZWeightedCenter!=0) zWeightedCenter /= totNumZWeightedCenter;
252
253 // store superpoint info in TrackData
255 TrigL2MuonSA::SuperPoint* superPoint = &(trackPattern.superPoints[inner]);
256 superPoint->R = rWeightedCenter;
257 superPoint->Phim = phiWeightedCenter+localPhiCenter;
258 superPoint->Z = zWeightedCenter;
259 superPoint->Npoint = totNumZWeightedCenter;
260 if (zWeightedCenter!=0) superPoint->Alin = rWeightedCenter/zWeightedCenter;
261 superPoint->Blin = 0.;
262
263 ATH_MSG_DEBUG("Nsw Super Point r/phi/z/slope = "<<superPoint->R<<"/"<<superPoint->Phim<<"/"<<superPoint->Z<<"/"<<superPoint->Alin);
264
265 return StatusCode::SUCCESS;
266
267}
268
270{
271 if(stgcHits.size() == 0) return StatusCode::SUCCESS;
272 int hitsInRoad = 0;
273 for(unsigned int iHit = 0; iHit < stgcHits.size(); iHit++){
274 if(stgcHits.at(iHit).isOutlier == 0){
275 hitsInRoad++;
276 stgcHits.at(iHit).isOutlier = 1;
277 }
278 }
279 if(hitsInRoad == 0) return StatusCode::SUCCESS;
280
281 if(hitsInRoad < 9) {
282 ATH_MSG_DEBUG("Number of STGC hits is too small, at least 9 hits required : "<<hitsInRoad<<" hits");
283 return StatusCode::SUCCESS;
284 } else if(hitsInRoad > 100) {
285 ATH_MSG_WARNING("Number of STGC hits is too large, at most 100 hits allowed : "<<hitsInRoad<<" hits");
286 return StatusCode::SUCCESS;
287 }
288
289 // cassifyDataEachLayer
290 std::array<std::vector<int>, 8> strHitIdByLayer;
291 std::array<std::vector<int>, 8> wireHitIdByLayer;
292 for(unsigned int iHit = 0; iHit < stgcHits.size(); ++iHit){
293 if(stgcHits.at(iHit).isOutlier != 1) continue;
294 int layerNumber = stgcHits.at(iHit).layerNumber;
295 if (layerNumber > 7) {
296 ATH_MSG_WARNING("STGC hit layer number > 7");
297 continue;
298 }
299 if(stgcHits.at(iHit).channelType == 1){
300 strHitIdByLayer[layerNumber].push_back(iHit);
301 }else if(stgcHits.at(iHit).channelType == 2){
302 wireHitIdByLayer[layerNumber].push_back(iHit);
303 }
304 }
305 ATH_MSG_DEBUG("@@STGC@@ strip Nhits " << strHitIdByLayer[0].size()
306 << " " << strHitIdByLayer[1].size()
307 << " " << strHitIdByLayer[2].size()
308 << " " << strHitIdByLayer[3].size()
309 << " " << strHitIdByLayer[4].size()
310 << " " << strHitIdByLayer[5].size()
311 << " " << strHitIdByLayer[6].size()
312 << " " << strHitIdByLayer[7].size());
313 ATH_MSG_DEBUG("@@STGC@@ wire Nhits " << wireHitIdByLayer[0].size()
314 << " " << wireHitIdByLayer[1].size()
315 << " " << wireHitIdByLayer[2].size()
316 << " " << wireHitIdByLayer[3].size()
317 << " " << wireHitIdByLayer[4].size()
318 << " " << wireHitIdByLayer[5].size()
319 << " " << wireHitIdByLayer[6].size()
320 << " " << wireHitIdByLayer[7].size());
321
322 std::vector< std::array<int, 8> > strHitIds; // Candidates' sets of strip hit ids in 8 layers
323 findSetOfStgcHitIds(stgcHits, strHitIdByLayer, strHitIds);
324 std::vector< std::array<int, 8> > wireHitIds; // Candidates' sets of wire hit ids in 8 layers
325 findSetOfStgcHitIds(stgcHits, wireHitIdByLayer, wireHitIds);
326 ATH_MSG_DEBUG("@@STGC@@ strip wire " << strHitIds.size() << " " << wireHitIds.size());
327
328 bool isLargeStrip = false;
329 bool isSmallStrip = false;
330 for (unsigned int iHit = 0; iHit < strHitIds.size(); ++iHit) {
331 std::array<int, 8> hitIds = strHitIds.at(iHit);
332 for (unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
333 if (hitIds[iLayer] != -1) {
334 if(stgcHits.at(hitIds[iLayer]).stationName == 58) isLargeStrip = true;
335 else if(stgcHits.at(hitIds[iLayer]).stationName == 57) isSmallStrip = true;
336 stgcHits.at(hitIds[iLayer]).isOutlier = 0;
337 }
338 }
339 }
340 for (unsigned int iHit = 0; iHit < wireHitIds.size(); ++iHit) {
341 std::array<int, 8> hitIds = wireHitIds.at(iHit);
342 for (unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
343 if (hitIds[iLayer] != -1) {
344 if(isLargeStrip){
345 if(stgcHits.at(hitIds[iLayer]).stationName == 58){
346 stgcHits.at(hitIds[iLayer]).isOutlier = 0;
347 }
348 }
349 else if(isSmallStrip){
350 if(stgcHits.at(hitIds[iLayer]).stationName == 57){
351 stgcHits.at(hitIds[iLayer]).isOutlier = 0;
352 }
353 }
354 }
355 }
356 }
357 return StatusCode::SUCCESS;
358
359}
360
362 std::array<std::vector<int>,8> hitIdByLayer,
363 std::vector<std::array<int, 8>>& hitIdsCandidate) const
364{
365 double NSWCenterZ = 7526.329;
366 int side = 0;
367
368 bool isStrip = 0;
369 for (unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
370 if ( hitIdByLayer[iLayer].size() > 0) {
371 side = std::abs(stgcHits.at(hitIdByLayer[iLayer].at(0)).z)/stgcHits.at(hitIdByLayer[iLayer].at(0)).z;
372 if ( stgcHits.at(hitIdByLayer[iLayer].at(0)).channelType == 1 ){
373 isStrip = 1;
374 break;
375 }
376 }
377 }
378 NSWCenterZ = NSWCenterZ * side;
379
380 std::array<std::vector<unsigned long int>,4> hitIdsInTwo;
381 std::array<std::vector<double>,4> slopeInTwo;
382 std::array<std::vector<double>,4> interceptInTwo;
383
384 // Loop over pairs of the i-th and the (i+4)-th layers
385 for(unsigned int iPair = 0; iPair < 4; ++iPair){
386 unsigned int nHitsInInner = hitIdByLayer[iPair].size();
387 unsigned int nHitsInOuter = hitIdByLayer[iPair+4].size();
388 if ( nHitsInInner > 0xffff-1 || nHitsInOuter > 0xffff-1) {
389 ATH_MSG_WARNING("Number of Stgc hits in layers exceeds the limit of (2^16 - 1) : Number of Stgc hits in "<<iPair<<"th layer = "<< nHitsInInner
390 <<", Number of Stgc hits in "<<iPair+4<<"th layer = "<<nHitsInOuter);
391 ATH_MSG_WARNING("Number of Stgc hits is limitted to (2^16 - 1) and hits with id more than (2^16 -1) will be trancated.");
392 if (nHitsInInner > 0xffff-1) {nHitsInInner = 0xffff-1;}
393 if (nHitsInOuter > 0xffff-1) {nHitsInOuter = 0xffff-1;}
394 }
395
396 bool foundCounterparts[256] = {};
397 // Loop over hits in the i-th layer
398 for(unsigned int iHit = 0; iHit < nHitsInInner; ++iHit){
399 bool foundCounterpart = 0;
400
401 double z[2] = {};
402 double r[2] = {};
403
404 int iHitId = hitIdByLayer[iPair].at(iHit);
405 if(isStrip){
406 r[0] = stgcHits.at(iHitId).r;
407 z[0] = stgcHits.at(iHitId).z;
408 } else {
409 double localPhiCenter;
410 if (stgcHits.at(iHitId).stationPhi<=5) {
411 localPhiCenter = 0.25 * M_PI * ((double)stgcHits.at(iHitId).stationPhi-1.);
412 } else {
413 localPhiCenter = 0.25 * M_PI * ((double)stgcHits.at(iHitId).stationPhi-9.);
414 }
415
416 if (stgcHits.at(iHitId).stationName == 57){
417 localPhiCenter += M_PI/8.; // small sTGC sectors
418 if (stgcHits.at(iHitId).stationPhi == 5) localPhiCenter -= 2. * M_PI;
419 }
420
421 double phiProj = stgcHits.at(iHitId).phi - localPhiCenter;
422 if (phiProj > M_PI) phiProj -= 2.0*M_PI;
423 if (phiProj < -1.*M_PI) phiProj += 2.0*M_PI;
424 r[0] = stgcHits.at(iHitId).r;
425 z[0] = phiProj;
426 }
427
428 // Loop over hits in the (i+4)-th layer
429 for(unsigned int jHit = 0; jHit < nHitsInOuter; ++jHit){
430 int jHitId = hitIdByLayer[iPair+4].at(jHit);
431 double slope, intercept;
432 if(isStrip) {
433 r[1] = stgcHits.at(jHitId).r;
434 z[1] = stgcHits.at(jHitId).z;
435 slope = (r[1] - r[0]) / (z[1] - z[0]);
436 intercept = slope*(0. - z[0]) + r[0];
437 // select pairs whose slops in limited regions
438 if(std::abs(slope) < 0.14 || std::abs(slope) > 0.6 || std::abs(intercept) > 300.) continue;
439 } else {
440 double localPhiCenter;
441 if (stgcHits.at(jHitId).stationPhi<=5) {
442 localPhiCenter = 0.25 * M_PI * ((double)stgcHits.at(jHitId).stationPhi-1.);
443 } else {
444 localPhiCenter = 0.25 * M_PI * ((double)stgcHits.at(jHitId).stationPhi-9.);
445 }
446
447 if (stgcHits.at(jHitId).stationName == 57){
448 localPhiCenter += M_PI/8.; // small sTGC sectors
449 if (stgcHits.at(jHitId).stationPhi == 5) localPhiCenter -= 2 * M_PI;
450 }
451
452 double phiProj = stgcHits.at(jHitId).phi - localPhiCenter;
453 if (phiProj > M_PI) phiProj -= 2.0*M_PI;
454 if (phiProj < -1.*M_PI) phiProj += 2.0*M_PI;
455 r[1] = stgcHits.at(jHitId).r;
456 z[1] = phiProj;
457 slope = (z[0]+z[1])/2.;
458 intercept = (r[0]+r[1])/2.;
459 if(std::abs(r[0]*std::sin(z[0]) - r[1]*std::sin(z[1])) > 300.) continue;
460 }
461
462 unsigned int encodedIds = (iHitId<<16) + jHitId;
463 hitIdsInTwo[iPair].push_back(encodedIds);
464 slopeInTwo[iPair].push_back(slope);
465 interceptInTwo[iPair].push_back(intercept);
466
467 foundCounterpart = 1;
468 foundCounterparts[jHit] = 1;
469 }//end of jHit in the (i+4)-th layer
470 if(!foundCounterpart){ // in case of no counterpart in the (i+4)-th layer
471 unsigned int encodedIds = (iHitId<<16) + 0xffff; // fill all bits with 1 for hit id for the layer with no hit
472 hitIdsInTwo[iPair].push_back(encodedIds);
473 if(isStrip) {
474 slopeInTwo[iPair].push_back(r[0]/z[0]);
475 interceptInTwo[iPair].push_back(0.);
476 } else {
477 slopeInTwo[iPair].push_back(z[0]);
478 interceptInTwo[iPair].push_back(r[0]);
479 }
480 }
481 }//end of iHit in the i-th layer
482 // Loop over hits in the (i+4)-th layer
483 for(unsigned int jHit = 0; jHit < nHitsInOuter; ++jHit){
484 if (!foundCounterparts[jHit]) {
485 int jHitId = hitIdByLayer[iPair+4].at(jHit);
486 unsigned int encodedIds = 0xffff0000 + jHitId; // fill all bits with 1 for hit id for the layer with no hit
487 hitIdsInTwo[iPair].push_back(encodedIds);
488 if(isStrip) {
489 slopeInTwo[iPair].push_back(stgcHits.at(jHitId).r/stgcHits.at(jHitId).z);
490 interceptInTwo[iPair].push_back(0.);
491 } else {
492 double localPhiCenter;
493 if (stgcHits.at(jHitId).stationPhi<=5) {
494 localPhiCenter = 0.25 * M_PI * ((double)stgcHits.at(jHitId).stationPhi-1.);
495 } else {
496 localPhiCenter = 0.25 * M_PI * ((double)stgcHits.at(jHitId).stationPhi-9.);
497 }
498 if (stgcHits.at(jHitId).stationName == 57){
499 localPhiCenter += M_PI/8.; // small sTGC sectors
500 if (stgcHits.at(jHitId).stationPhi == 5) localPhiCenter -= 2 * M_PI;
501 }
502
503 double phiProj = stgcHits.at(jHitId).phi - localPhiCenter;
504 if (phiProj > M_PI) phiProj -= 2.0*M_PI;
505 if (phiProj < -1.*M_PI) phiProj += 2.0*M_PI;
506 slopeInTwo[iPair].push_back(phiProj);
507 interceptInTwo[iPair].push_back(stgcHits.at(jHitId).r);
508 }
509 }
510 }
511 }//end of pair loop
512
513 ATH_MSG_DEBUG("@@STGC@@ isStrip= " << isStrip << " Npairs " << hitIdsInTwo[0].size() << " " << hitIdsInTwo[1].size() << " " << hitIdsInTwo[2].size() << " " << hitIdsInTwo[3].size());
514 for (unsigned int iLayer = 0; iLayer < 4; ++ iLayer) {
515 for (unsigned int iPair = 0; iPair < slopeInTwo[iLayer].size(); ++iPair) {
516 ATH_MSG_DEBUG("@@STGC@@ pair fit isStrip= " << isStrip << " slope= " << slopeInTwo[iLayer].at(iPair) << " intercept= " << interceptInTwo[iLayer].at(iPair));
517 }
518 }
519
520 std::array<std::vector<unsigned long int>,2> hitIdsInFour;
521 std::array<std::vector<double>,2> slopeInFour;
522 std::array<std::vector<double>,2> interceptInFour;
523 for(unsigned int iQuad = 0; iQuad < 2; ++iQuad){
524 unsigned int nPairsInInner = hitIdsInTwo[iQuad].size();
525 unsigned int nPairsInOuter = hitIdsInTwo[iQuad+2].size();
526
527 bool foundCounterparts[0xffff] = {};
528 for(unsigned int iPair = 0; iPair < nPairsInInner; ++iPair){
529 bool foundCounterpart = 0;
530 double slope[2];
531 double intercept[2];
532 slope[0] = slopeInTwo[iQuad].at(iPair);
533 intercept[0] = interceptInTwo[iQuad].at(iPair);
534
535 for(unsigned int jPair = 0; jPair < nPairsInOuter; ++jPair){
536 unsigned int ihitIds = hitIdsInTwo[iQuad].at(iPair);
537 unsigned int jhitIds = hitIdsInTwo[iQuad+2].at(jPair);
538 if ( !(((ihitIds>>16 & 0xffff) != 0xffff || (ihitIds & 0xffff) != 0xffff) &&
539 ((jhitIds>>16 & 0xffff) != 0xffff || (jhitIds & 0xffff) != 0xffff )) ) continue; // require at least 2 hits in 4 layers
540
541 slope[1] = slopeInTwo[iQuad+2].at(jPair);
542 intercept[1] = interceptInTwo[iQuad+2].at(jPair);
543
544 if (isStrip) {
545 double spR0 = slope[0] * NSWCenterZ + intercept[0];
546 double spR1 = slope[1] * NSWCenterZ + intercept[1];
547 if(std::abs(spR1 - spR0) > 50.) continue; //OPTIMIZE ME!!!
548 } else {
549 if(std::abs(intercept[0]*std::sin(slope[0]) - intercept[1]*std::sin(slope[1])) > 100.) continue;
550 }
551
552 foundCounterpart = 1;
553 foundCounterparts[jPair] = 1;
554
555 unsigned long int encodedIds = (hitIdsInTwo[iQuad].at(iPair) << 32 ) + hitIdsInTwo[iQuad+2].at(jPair);
556 hitIdsInFour[iQuad].push_back(encodedIds);
557 slopeInFour[iQuad].push_back((slope[1] + slope[0])/2.);
558 interceptInFour[iQuad].push_back((intercept[1] + intercept[0])/2.);
559 }// end of iPair of the i-th and (i+4)-th layers, i=0,2
560
561 if(foundCounterpart) continue; // in case of no counterpart of pairs in the inner layers
562 if((hitIdsInTwo[iQuad].at(iPair)>>16 & 0xffff) == 0xffff || (hitIdsInTwo[iQuad].at(iPair) & 0xffff) == 0xffff) continue;
563
564 unsigned long int encodedIds = (hitIdsInTwo[iQuad].at(iPair) << 32 ) + 0xffffffff;
565 hitIdsInFour[iQuad].push_back(encodedIds);
566 slopeInFour[iQuad].push_back(slope[0]);
567 interceptInFour[iQuad].push_back(intercept[0]);
568 }// end of jPair of the j-th and (j+4)-th layers, j=1,3
569 for (unsigned int jPair = 0; jPair < nPairsInOuter; ++jPair) {
570 if(foundCounterparts[jPair]) continue; // in case of no counterpart of pairs in the outner layers
571 if((hitIdsInTwo[iQuad+2].at(jPair)>>16 & 0xffff) == 0xffff || (hitIdsInTwo[iQuad+2].at(jPair) & 0xffff) == 0xffff) continue;
572// unsigned long int encodedIds = (0xffffffff << 32) + hitIdsInTwo[iQuad+2].at(jPair);
573 unsigned long int encodedIds = (0xffffffff00000000 ) + hitIdsInTwo[iQuad+2].at(jPair);
574 hitIdsInFour[iQuad].push_back(encodedIds);
575 slopeInFour[iQuad].push_back(slopeInTwo[iQuad+2].at(jPair));
576 interceptInFour[iQuad].push_back(interceptInTwo[iQuad+2].at(jPair));
577 }
578 }// end of quad loop
579
580 ATH_MSG_DEBUG("@@STGC@@ isStrip= " << isStrip << " Nquads " << hitIdsInFour[0].size() << " " << hitIdsInFour[1].size());
581 for (unsigned int iLayer = 0; iLayer < 2; ++ iLayer) {
582 for (unsigned int iQuad = 0; iQuad < slopeInFour[iLayer].size(); ++iQuad) {
583 ATH_MSG_DEBUG("@@STGC@@ quad fit isStrip= " << isStrip << " slope= " << slopeInFour[iLayer].at(iQuad) << " intercept= " << interceptInFour[iLayer].at(iQuad));
584 }
585 }
586
587 std::vector< std::array<int, 8> > hitIdsInEight;
588 std::vector<double> mseInEight;
589
590 unsigned int nQuadInInner = hitIdsInFour[0].size();
591 unsigned int nQuadInOuter = hitIdsInFour[1].size();
592
593 for(unsigned int iQuad = 0; iQuad < nQuadInInner; ++iQuad){
594 double slope[2];
595 double intercept[2];
596 slope[0] = slopeInFour[0].at(iQuad);
597 intercept[0] = interceptInFour[0].at(iQuad);
598
599 for(unsigned int jQuad = 0; jQuad < nQuadInOuter; ++jQuad){
600 unsigned long int ihitIds = hitIdsInFour[0].at(iQuad);
601 unsigned long int jhitIds = hitIdsInFour[1].at(jQuad);
602 int nOfLayersWithNoHit = 0;
603 for (unsigned int iLayer = 0; iLayer < 4; ++iLayer) {
604 if ( (ihitIds>>(3-iLayer)*16 & 0xffff) == 0xffff ) {++nOfLayersWithNoHit;}
605 if ( (jhitIds>>(3-iLayer)*16 & 0xffff) == 0xffff ) {++nOfLayersWithNoHit;}
606 }
607 if (nOfLayersWithNoHit > 4) continue; // require at least 4 hits in 8 layers
608
609 slope[1] = slopeInFour[1].at(jQuad);
610 intercept[1] = interceptInFour[1].at(jQuad);
611
612 if(isStrip) {
613 double spR0 = slope[0] * NSWCenterZ + intercept[0];
614 double spR1 = slope[1] * NSWCenterZ + intercept[1];
615 if(std::abs(spR1 - spR0) > 10. ||
616 std::abs(intercept[1] + intercept[0]) / 2 > 100.) continue; // OPTIMIZE ME!!!
617 } else {
618 if(std::abs(intercept[0]*std::sin(slope[0]) - intercept[1]*std::sin(slope[1])) > 100. ) continue;
619 }
620
621 std::array<int,8> setOfHitIds = {-1,-1,-1,-1,-1,-1,-1,-1};
622 std::vector<double> r, z;
623 for(unsigned int i = 0; i < 8; ++i) {
624 unsigned int iHitId, iLayer = 0;
625 if (i <= 3) {
626 iHitId = (unsigned int) ((ihitIds>>(3-i)*16) & 0xffff);
627 iLayer = i+3*(i%2);
628 } else {
629 iHitId = (unsigned int) ((jhitIds>>(3-i%4)*16) & 0xffff);
630 iLayer = (i-4)+3*(i%2)+1;
631 }
632 if ( iHitId != 0xffff ) {
633 if (isStrip) {
634 r.push_back(stgcHits.at(iHitId).r);
635 z.push_back(stgcHits.at(iHitId).z);
636 }
637 else {
638 double localPhiCenter;
639 if (stgcHits.at(iHitId).stationPhi<=5) {
640 localPhiCenter = 0.25 * M_PI * ((double)stgcHits.at(iHitId).stationPhi-1.);
641 } else {
642 localPhiCenter = 0.25 * M_PI * ((double)stgcHits.at(iHitId).stationPhi-9.);
643 }
644 if (stgcHits.at(iHitId).stationName == 57){
645 localPhiCenter += M_PI/8.; // small sTGC sectors
646 if (stgcHits.at(iHitId).stationPhi == 5) localPhiCenter -= 2 * M_PI;
647 }
648
649 double phiProj = stgcHits.at(iHitId).phi - localPhiCenter;
650 if (phiProj > M_PI) phiProj -= 2.0*M_PI;
651 if (phiProj < -1.*M_PI) phiProj += 2.0*M_PI;
652 r.push_back(phiProj);
653 z.push_back(stgcHits.at(iHitId).r);
654 }
655 setOfHitIds[iLayer] = iHitId;
656 ATH_MSG_DEBUG("@@STGC@@ strip_pos iHitId " << iLayer << " " << iHitId);
657 }
658 }
659 double slopefit=0., interceptfit=99999., mse =-1.;
660 if (isStrip) {
661 LinearFit(z,r,&slopefit,&interceptfit,&mse);
662 } else {
663 double phiavg = 0.;
664 for (unsigned int iHit = 0; iHit < r.size(); ++iHit){
665 phiavg += r.at(iHit);
666 }
667 phiavg /= r.size();
668 mse = 0.;
669 for (unsigned int iHit = 0; iHit < r.size(); ++iHit){
670 mse += std::pow(r.at(iHit) - phiavg,2);
671 }
672 }
673 hitIdsInEight.push_back(setOfHitIds);
674 mseInEight.push_back(mse);
675 } // end of quad loop in the outer layers
676 } // end of quad loop in the inner layers
677 if(!hitIdsInEight.size()){
678 ATH_MSG_DEBUG("No candidate segment found in STGC");
679 return;
680 }
681
682 ATH_MSG_DEBUG("@@STGC@@ isStrip= " << isStrip << " Noctets " << hitIdsInEight.size());
683 std::vector<int> nOctetSegments;
684 std::vector<int> patternStationName;
685
686 for (unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet) {
687
688 bool isFirstHit = true;
689 int hitStationName = 0;
690
691 int nOctetSegment = 0;
692 ATH_MSG_DEBUG("@@STGC@@ octet fit isStrip= " << isStrip << " mse " << mseInEight.at(iOctet));
693 std::array<int, 8> tmpOctet = hitIdsInEight.at(iOctet);
694 for (unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
695 if (tmpOctet[iLayer] != -1) {
696
697 if(isFirstHit){
698 hitStationName = stgcHits.at(tmpOctet[iLayer]).stationName;
699 isFirstHit = false;
700
701 ATH_MSG_DEBUG("@@STGC@@ octet pos isStrip= " << isStrip << " r= " << stgcHits.at(tmpOctet[iLayer]).r << " phi= " << stgcHits.at(tmpOctet[iLayer]).phi << " z= " << stgcHits.at(tmpOctet[iLayer]).z);
702 nOctetSegment++;
703 }
704 else if(stgcHits.at(tmpOctet[iLayer]).stationName == hitStationName){
705 ATH_MSG_DEBUG("@@STGC@@ octet pos isStrip= " << isStrip << " r= " << stgcHits.at(tmpOctet[iLayer]).r << " phi= " << stgcHits.at(tmpOctet[iLayer]).phi << " z= " << stgcHits.at(tmpOctet[iLayer]).z);
706 nOctetSegment++;
707 }
708 }
709 }
710 nOctetSegments.push_back(nOctetSegment);
711 patternStationName.push_back(hitStationName);
712 }
713 double nOcSegMax = 0;
714 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
715 if(nOctetSegments.at(iOctet) > nOcSegMax){
716 nOcSegMax = nOctetSegments.at(iOctet);
717 }
718 }
719
720 double msemin = 1000000.;
721 double mseminWireL = 1000000.; // Large sector
722 double mseminWireS = 1000000.; // Small sector
723
724 std::vector<int> octetIds(2,-1);
725
726 if(isStrip){
727 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
728 if(nOctetSegments.at(iOctet) != nOcSegMax){
729 continue;
730 }
731 if( mseInEight.at(iOctet) < msemin) {
732 msemin = mseInEight.at(iOctet);
733 }
734 }// end of Octet loop
735 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
736 if(nOctetSegments.at(iOctet) != nOcSegMax) continue;
737 if(mseInEight.at(iOctet) != msemin){
738 continue;
739 }
740 octetIds.push_back(iOctet);
741 }
742 } else {
743 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
744 if(patternStationName.at(iOctet) == 58){
745 if( mseInEight.at(iOctet) < mseminWireL) {
746 mseminWireL = mseInEight.at(iOctet);
747 }
748 }
749 else if(patternStationName.at(iOctet) == 57){
750 if( mseInEight.at(iOctet) < mseminWireS) {
751 mseminWireS = mseInEight.at(iOctet);
752 }
753 }
754 }// end of Octet loop
755 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
756 if(patternStationName.at(iOctet) == 58){
757 if(mseInEight.at(iOctet) != mseminWireL){
758 continue;
759 }
760 }
761 else if(patternStationName.at(iOctet) == 57){
762 if(mseInEight.at(iOctet) != mseminWireS){
763 continue;
764 }
765 }
766 octetIds.push_back(iOctet);
767 }
768 }
769 for(unsigned int ids = 0; ids < octetIds.size(); ids++){
770 if (octetIds.at(ids) != -1) {
771 hitIdsCandidate.push_back(hitIdsInEight.at(octetIds.at(ids)));
772 }
773 }
774}
775
777 TrigL2MuonSA::StgcHits& stgcHits) const
778{
779 TrigL2MuonSA::StgcHits selectedStgcHits;
780 selectedStgcHits.clear();
781 if(stgcHits.size() == 0) return StatusCode::SUCCESS;
782 for(unsigned int iHit = 0; iHit < stgcHits.size(); iHit++){
783 if(stgcHits.at(iHit).isOutlier != 0) continue;
784 selectedStgcHits.push_back(stgcHits.at(iHit));
785 }
786 trackPattern.stgcSegment.clear();
787 trackPattern.stgcSegment = selectedStgcHits;
788 return StatusCode::SUCCESS;
789}
791 TrigL2MuonSA::MmHits& mmHits) const
792{
793 TrigL2MuonSA::MmHits selectedMmHits;
794 selectedMmHits.clear();
795 if(mmHits.size() == 0) return StatusCode::SUCCESS;
796 for(unsigned int iHit = 0; iHit < mmHits.size(); iHit++){
797 if(mmHits.at(iHit).isOutlier != 0) continue;
798 selectedMmHits.push_back(mmHits.at(iHit));
799 }
800 trackPattern.mmSegment.clear();
801 trackPattern.mmSegment = selectedMmHits;
802 return StatusCode::SUCCESS;
803}
804
805
806void TrigL2MuonSA::NswStationFitter::LinearFit(std::vector<double>& x,std::vector<double>& y,
807 double* slope, double* intercept, double* mse) const
808{
809 double sumX=0, sumY=0, sumXY=0, sumX2=0;
810 int nHits = x.size();
811 *mse = 0.;
812 for (unsigned int iHit = 0; iHit < x.size(); ++iHit){
813 sumX += x.at(iHit);
814 sumY += y.at(iHit);
815 sumXY += x.at(iHit)*y.at(iHit);
816 sumX2 += x.at(iHit)*x.at(iHit);
817 }
818
819 if(nHits > 1) {
820 if(nHits * sumX2 - (sumX * sumX) > ZERO_LIMIT) {
821 *slope = (nHits * sumXY - sumX * sumY) / (nHits * sumX2 - (sumX * sumX));
822 *intercept = (sumX2 * sumY - sumXY * sumX) / (nHits * sumX2 - sumX * sumX);
823 } else {
824 *slope = 0.;
825 *intercept = sumY/nHits;
826 }
827 }
828 else if(nHits == 1) {
829 *slope = sumY/sumX;
830 *intercept = 0.;
831 }
832
833 if(nHits > 2) {
834 for(unsigned int iHit = 0; iHit< x.size(); ++iHit){
835 *mse += std::pow(y.at(iHit) - (*slope * x.at(iHit) + *intercept), 2.0);
836 }
837 *mse = *mse / (nHits - 2);
838 }
839 else {
840 *mse = 1000.;
841 }
842}
843
844void TrigL2MuonSA::NswStationFitter::LinearFitWeight(std::vector<double>& x,std::vector<double>& y,
845 std::vector<bool>& isStgc, double* slope, double* intercept, double* mse, double eta) const
846{
847 double RmsDeltarEtaStgc[12] = {};
848 double RmsDeltarEtaMm[12]= {};
849 getNswResolution(RmsDeltarEtaStgc, RmsDeltarEtaMm, 12);
850
851 double weightStgc[12] = {};
852 double weightMm[12] = {};
853 for(int i_weight=0; i_weight<12; i_weight++){
854 weightStgc[i_weight] = 1/std::pow(RmsDeltarEtaStgc[i_weight],2);
855 weightMm[i_weight] = 1/std::pow(RmsDeltarEtaMm[i_weight],2);
856 }
857 int weightBin = 0;
858 double minEta = 1.3;
859 double maxEta = 1.4;
860 for(int iBin=0; iBin<12; iBin++){
861 if(std::abs(eta) >= minEta && std::abs(eta) < maxEta){
862 weightBin = iBin;
863 break;
864 } else {
865 minEta += 0.1;
866 maxEta += 0.1;
867 }
868 }
869
870 double sumX=0, sumY=0, sumXY=0, sumX2=0, sumW=0;
871 int nHits = x.size();
872 *mse = 0.;
873 for (unsigned int iHit = 0; iHit < x.size(); ++iHit){
874 if(isStgc.at(iHit)){
875 sumX += weightStgc[weightBin] * x.at(iHit);
876 sumY += weightStgc[weightBin] * y.at(iHit);
877 sumXY += weightStgc[weightBin] * x.at(iHit) * y.at(iHit);
878 sumX2 += weightStgc[weightBin] * x.at(iHit) * x.at(iHit);
879 sumW += weightStgc[weightBin];
880 } else {
881 sumX += weightMm[weightBin] * x.at(iHit);
882 sumY += weightMm[weightBin] * y.at(iHit);
883 sumXY += weightMm[weightBin] * x.at(iHit) * y.at(iHit);
884 sumX2 += weightMm[weightBin] * x.at(iHit) * x.at(iHit);
885 sumW += weightMm[weightBin];
886 }
887 }
888
889 if(nHits > 1) {
890 if(nHits * sumX2 - (sumX * sumX) > ZERO_LIMIT) {
891 *slope = (sumW * sumXY - sumX * sumY) / (sumW * sumX2 - (sumX * sumX));
892 *intercept = (sumX2 * sumY - sumXY * sumX) / (sumW * sumX2 - sumX * sumX);
893 } else {
894 *slope = 0.;
895 *intercept = sumY/nHits;
896 }
897 }
898 else if(nHits == 1) {
899 *slope = sumY/sumX;
900 *intercept = 0.;
901 }
902
903 if(nHits > 2) {
904 for(unsigned int iHit = 0; iHit< x.size(); ++iHit){
905 *mse += std::pow((y.at(iHit) - (*slope * x.at(iHit) + *intercept)), 2.0);
906 }
907 *mse = *mse / (nHits - 2);
908 }
909 else {
910 *mse = 1000.;
911 }
912}
913
914void TrigL2MuonSA::NswStationFitter::getNswResolution(double *stgcDeltaR, double *mmDeltaR, unsigned int size) const
915{
916 double RmsDeltarEtaStgc[12] = {1.43,1.53,1.53,1.56,1.59,1.54,1.70,1.69,1.76,1.81,1.83,1.84};
917 double RmsDeltarEtaMm[12] = {0.49,0.46,0.48,0.40,0.39,0.39,0.38,0.35,0.36,0.33,0.33,0.40};
918 for(unsigned int bin=0; bin < size; bin++){
919 stgcDeltaR[bin] = RmsDeltarEtaStgc[bin];
920 mmDeltaR[bin] = RmsDeltarEtaMm[bin];
921 }
922}
923
925{
926 TrigL2MuonSA::StgcHits stgcHits = trackPattern.stgcSegment;
927 TrigL2MuonSA::MmHits mmHits = trackPattern.mmSegment;
928
929 double side_mm = 0;
930 std::vector<double> r, z;
931 std::vector<bool> isStgc;
932 for(unsigned int iHit = 0; iHit < stgcHits.size(); ++iHit) {
933 if (stgcHits.at(iHit).channelType == 1) {
934 r.push_back(stgcHits.at(iHit).r);
935 z.push_back(stgcHits.at(iHit).z);
936 isStgc.push_back(true);
937 }
938 }
939 for(unsigned int iHit = 0; iHit < mmHits.size(); ++iHit) {
940 if (mmHits.at(iHit).layerNumber < 2 || mmHits.at(iHit).layerNumber > 5) {
941 r.push_back(mmHits.at(iHit).r);
942 z.push_back(mmHits.at(iHit).z);
943 isStgc.push_back(false);
944 side_mm = std::abs(mmHits.at(iHit).z)/mmHits.at(iHit).z;
945 }
946 }
947 double slopefit=0., interceptfit=99999., mse=-1.;
948 LinearFit(z,r,&slopefit,&interceptfit,&mse);
949 ATH_MSG_DEBUG("@@Merge@@ stgc_mmX_fit slope= " << slopefit);
950 ATH_MSG_DEBUG("@@Merge@@ stgc_mmX_fit intercept= " << interceptfit);
951 ATH_MSG_DEBUG("@@Merge@@ stgc_mmX_fit mse= " << mse);
952
953 std::vector<double> phiLocal;
954 double localPhiCenter = 3.*M_PI;
955 for (unsigned int iHit = 0; iHit < stgcHits.size(); ++iHit) {
956 if (stgcHits.at(iHit).channelType != 2) {continue;}
957 if (stgcHits.at(iHit).stationPhi<=5) {
958 localPhiCenter = 0.25 * M_PI * ((double)stgcHits.at(iHit).stationPhi-1.);
959 } else {
960 localPhiCenter = 0.25 * M_PI * ((double)stgcHits.at(iHit).stationPhi-9.);
961 }
962
963 if (stgcHits.at(iHit).stationName == 57){
964 localPhiCenter += M_PI/8.; // small sTGC sectors
965 if (stgcHits.at(iHit).stationPhi == 5) localPhiCenter -= 2. * M_PI;
966 }
967
968 double phiProj = stgcHits.at(iHit).phi - localPhiCenter;
969 if (phiProj > M_PI) phiProj -= 2.0*M_PI;
970 if (phiProj < -1.*M_PI) phiProj += 2.0*M_PI;
971 double rInterpolate = slopefit * stgcHits.at(iHit).z + interceptfit;
972 double rProj = stgcHits.at(iHit).r;
973 phiLocal.push_back( std::atan(rProj/rInterpolate*std::tan(phiProj)) );
974 ATH_MSG_DEBUG("@@Merge@@ philocalwire " << stgcHits.at(iHit).stationPhi << " " << stgcHits.at(iHit).stationName << " "
975 << localPhiCenter << " " << stgcHits.at(iHit).phi << " " << stgcHits.at(iHit).r << " " << stgcHits.at(iHit).z);
976 ATH_MSG_DEBUG("@@Merge@@ philocalwire " << rProj << " " << rInterpolate << " " << std::tan(phiProj) );
977 ATH_MSG_DEBUG("@@Merge@@ philocalwire " << std::atan(rProj/rInterpolate*std::tan(phiProj)) );
978 }
979 double tanTiltAngleU = 0,
980 tanTiltAngleV = 0;
981 double cosTiltAngleU = 0,
982 cosTiltAngleV = 0;
983 double sinTiltAngleU = 0,
984 sinTiltAngleV = 0;
985 if(side_mm > ZERO_LIMIT){
986 tanTiltAngleU = TanM1p5,
987 tanTiltAngleV = TanP1p5;
988 cosTiltAngleU = CosM1p5,
989 cosTiltAngleV = CosP1p5;
990 sinTiltAngleU = SinM1p5,
991 sinTiltAngleV = SinP1p5;
992 } else if(side_mm < -1.*ZERO_LIMIT){
993 tanTiltAngleU = TanP1p5,
994 tanTiltAngleV = TanM1p5;
995 cosTiltAngleU = CosP1p5,
996 cosTiltAngleV = CosM1p5;
997 sinTiltAngleU = SinP1p5,
998 sinTiltAngleV = SinM1p5;
999 } else {
1000 ATH_MSG_DEBUG("@@Merge@@ no U, V layer hits -> not consider tilt of U/V layers");
1001 }
1002 for (unsigned int iHit = 0; iHit < mmHits.size(); ++iHit) {
1003 if (localPhiCenter > 2.*M_PI) {
1004 if (mmHits.at(iHit).stationPhi<=5) {
1005 localPhiCenter = 0.25 * M_PI * ((double)mmHits.at(iHit).stationPhi-1.);
1006 } else {
1007 localPhiCenter = 0.25 * M_PI * ((double)mmHits.at(iHit).stationPhi-9.);
1008 }
1009 if (mmHits.at(iHit).stationName == 55){
1010 localPhiCenter += M_PI/8.; // small MM sectors
1011 if (mmHits.at(iHit).stationPhi == 5) localPhiCenter -= 2 * M_PI;
1012 }
1013 }
1014 if (mmHits.at(iHit).layerNumber >1 && mmHits.at(iHit).layerNumber < 6){
1015 double rInterpolate = slopefit * mmHits.at(iHit).z + interceptfit;
1016 double rProj = mmHits.at(iHit).r;
1017 if(std::abs(side_mm) < ZERO_LIMIT) {
1018 phiLocal.push_back(0);
1019 ATH_MSG_DEBUG("@@Merge@@ philocalmm 0");
1020 }
1021 else if ((mmHits.at(iHit).layerNumber)%2 == 0) { // layer U
1022 phiLocal.push_back( std::atan((rProj-rInterpolate)/tanTiltAngleU/rInterpolate));
1023 ATH_MSG_DEBUG("@@Merge@@ philocalmmU " << std::atan((rProj-rInterpolate)/tanTiltAngleU/rInterpolate));
1024 } else { // layer V
1025 phiLocal.push_back( std::atan((rProj-rInterpolate)/tanTiltAngleV/rInterpolate));
1026 ATH_MSG_DEBUG("@@Merge@@ philocalmmV " << std::atan((rProj-rInterpolate)/tanTiltAngleV/rInterpolate));
1027 }
1028 }
1029 }
1030 double sumPhiLocal = 0;
1031 for (unsigned int iHit = 0; iHit < phiLocal.size(); ++iHit ) {
1032 sumPhiLocal += phiLocal.at(iHit);
1033 }
1034 double phiLocalAvg = sumPhiLocal/phiLocal.size();
1035 ATH_MSG_DEBUG("@@Merge@@ philocalAvg " << phiLocalAvg);
1036
1037 r.clear();
1038 z.clear();
1039 isStgc.clear();
1040 std::vector<double> r_stgc, z_stgc, r_mm, z_mm;
1041 std::vector<bool> isStgc_stgc, isStgc_mm;
1042 double side_stgc = 0;
1043 for(unsigned int iHit = 0; iHit < stgcHits.size(); ++iHit) {
1044 if (stgcHits.at(iHit).stationPhi<=5) localPhiCenter = 0.25 * M_PI * ((double)stgcHits.at(iHit).stationPhi-1.);
1045 if (stgcHits.at(iHit).stationPhi> 5) localPhiCenter = 0.25 * M_PI * ((double)stgcHits.at(iHit).stationPhi-9.);
1046 if (stgcHits.at(iHit).channelType == 1) {
1047 r_stgc.push_back(stgcHits.at(iHit).r/std::cos(phiLocalAvg));
1048 z_stgc.push_back(stgcHits.at(iHit).z);
1049 isStgc_stgc.push_back(true);
1050 side_stgc = std::abs(stgcHits.at(iHit).z)/stgcHits.at(iHit).z;
1051
1052 ATH_MSG_DEBUG("@@Merge@@ stgc strip_r " << phiLocalAvg << " " << stgcHits.at(iHit).z << " " << stgcHits.at(iHit).r/std::cos(phiLocalAvg));
1053 }
1054
1055 }
1056 double slopefit_stgc=0., interceptfit_stgc=99999., mse_stgc=1.e20;
1057 if(r_stgc.size() == 0) {
1058 ATH_MSG_DEBUG("No STGC hit to calculate superoint");
1059 } else {
1060 LinearFit(z_stgc,r_stgc,&slopefit_stgc,&interceptfit_stgc,&mse_stgc);
1061 }
1062
1063 for(unsigned int iHit = 0; iHit < mmHits.size(); ++iHit) {
1064 if (mmHits.at(iHit).layerNumber < 2 || mmHits.at(iHit).layerNumber > 5) {
1065 r_mm.push_back(mmHits.at(iHit).r/std::cos(phiLocalAvg));
1066 z_mm.push_back(mmHits.at(iHit).z);
1067 isStgc_mm.push_back(false);
1068 } else {
1069 z_mm.push_back(mmHits.at(iHit).z);
1070 isStgc_mm.push_back(false);
1071
1072 double rProj = mmHits.at(iHit).r;
1073 if(std::abs(side_mm) < ZERO_LIMIT) { // no layer U/V
1074 r_mm.push_back(rProj);
1075 }
1076 else if ((mmHits.at(iHit).layerNumber)%2 == 0) { // layer U
1077 double rPrime = (rProj * cosTiltAngleU)/(cos(phiLocalAvg)*cosTiltAngleU + sin(phiLocalAvg)*sinTiltAngleU);
1078 r_mm.push_back(rPrime);
1079 } else { //layer V
1080 double rPrime = (rProj * cosTiltAngleV)/(cos(phiLocalAvg)*cosTiltAngleV + sin(phiLocalAvg)*sinTiltAngleV);
1081 r_mm.push_back(rPrime);
1082 }
1083 }
1084 }
1085 double slopefit_mm=0., interceptfit_mm=99999., mse_mm=1.e20;
1086 if(r_mm.size() == 0) {
1087 ATH_MSG_WARNING("No MM hit to calculate superoint");
1088 } else {
1089 LinearFit(z_mm,r_mm,&slopefit_mm,&interceptfit_mm,&mse_mm);
1090 }
1091
1092 unsigned int fmerge = 0;
1093 slopefit=0., interceptfit=99999., mse=1.e20;
1094 double side = 0;
1095 double StgcSegZ = 7526.329;
1096 double StgcSegR = 0;
1097 double MmSegZ = 7526.329;
1098 double MmSegR = 0;
1099 if (mse_stgc < 1.e7 && mse_mm < 1.e7) {
1100 r = r_stgc;
1101 copy(r_mm.begin(), r_mm.end(), back_inserter(r));
1102 z = z_stgc;
1103 copy(z_mm.begin(), z_mm.end(), back_inserter(z));
1104 isStgc = isStgc_stgc;
1105 copy(isStgc_mm.begin(), isStgc_mm.end(), back_inserter(isStgc));
1106
1107 if(side_stgc < -1.*ZERO_LIMIT){
1108 StgcSegZ = -7526.329;
1109 }
1110 StgcSegR = slopefit_stgc * StgcSegZ + interceptfit_stgc;
1111 double StgcSegOriginTheta = std::atan(StgcSegR / StgcSegZ);
1112 double StgcSegEta = side_stgc * (- std::log(std::abs(std::tan(StgcSegOriginTheta / 2))));
1113 if(side_mm < -1.*ZERO_LIMIT){
1114 MmSegZ = -7526.329;
1115 }
1116 MmSegR = slopefit_mm * MmSegZ + interceptfit_mm;
1117 double MmSegOriginTheta = std::atan(MmSegR / MmSegZ);
1118 double MmSegEta = side_stgc * (- std::log(std::abs(std::tan(MmSegOriginTheta / 2))));
1119
1120 double SegEtaAve = 0;
1121 if(std::abs(side_stgc) > ZERO_LIMIT || std::abs(side_mm) > ZERO_LIMIT){
1122 if(side_stgc*side_mm > 0){
1123 side = side_stgc;
1124 SegEtaAve = (StgcSegEta + MmSegEta)/2;
1125 } else if(std::abs(side_stgc) < ZERO_LIMIT) {
1126 side = side_mm;
1127 SegEtaAve = MmSegEta;
1128 } else if(std::abs(side_mm) < ZERO_LIMIT) {
1129 side = side_stgc;
1130 SegEtaAve = StgcSegEta;
1131 }
1132 }
1133
1134 LinearFitWeight(z,r,isStgc,&slopefit,&interceptfit,&mse,SegEtaAve);
1135 fmerge = 1;
1136 }
1137 if (mse > 1.e7) {
1138 if (mse_stgc < mse_mm) {
1139 slopefit = slopefit_stgc;
1140 interceptfit = interceptfit_stgc;
1141 mse = mse_stgc;
1142 z = z_stgc;
1143 side = side_stgc;
1144 fmerge = 2;
1145 } else {
1146 slopefit = slopefit_mm;
1147 interceptfit = interceptfit_mm;
1148 mse = mse_mm;
1149 z = z_mm;
1150 side = side_mm;
1151 fmerge = 3;
1152 }
1153 }
1154 if (mse > 1.e19) {
1155 ATH_MSG_WARNING("No sTGC and MM hit to calculate superoint");
1156 return StatusCode::SUCCESS;
1157 }
1158
1159 // store superpoint info in TrackData
1161 TrigL2MuonSA::SuperPoint* superPoint = &(trackPattern.superPoints[inner]);
1162 double NSWCenterZ = 7526.329;
1163 if(side < -1.*ZERO_LIMIT){
1164 NSWCenterZ = -7526.329;
1165 }
1166 superPoint->R = slopefit * NSWCenterZ + interceptfit;
1167 superPoint->Phim = phiLocalAvg+localPhiCenter;
1168 superPoint->Z = NSWCenterZ;
1169 superPoint->Npoint = z.size();
1170
1171 if (NSWCenterZ != 0) superPoint->Alin = slopefit;
1172 superPoint->Blin = interceptfit;
1173
1174 ATH_MSG_DEBUG("Nsw Super Point r/phi/z/slope = "<<superPoint->R<<"/"<<superPoint->Phim<<"/"<<superPoint->Z<<"/"<<superPoint->Alin);
1175
1176 ATH_MSG_DEBUG("@@Merge@@ Nsw Super Point r/phi/z/slope = "<<superPoint->R<<"/"<<superPoint->Phim<<"/"<<superPoint->Z<<"/"<<superPoint->Alin);
1177 ATH_MSG_DEBUG("@@Merge@@ fit slope= " << slopefit << " " << slopefit_stgc << " " << slopefit_mm);
1178 ATH_MSG_DEBUG("@@Merge@@ fit intercept= " << interceptfit << " " << interceptfit_stgc << " " << interceptfit_mm);
1179 ATH_MSG_DEBUG("@@Merge@@ fit mse= " << mse << " " << mse_stgc << " " << mse_mm);
1180 ATH_MSG_DEBUG("@@Merge@@ fit tech= " << fmerge);
1181
1182
1183 return StatusCode::SUCCESS;
1184
1185}
1186
1188{
1189 if(mmHits.size() == 0) return StatusCode::SUCCESS;
1190 int hitsInRoad = 0;
1191 for(unsigned int iHit = 0; iHit < mmHits.size(); iHit++){
1192 if(mmHits.at(iHit).isOutlier == 0){
1193 hitsInRoad++;
1194 mmHits.at(iHit).isOutlier = 1;
1195 }
1196 }
1197 if(hitsInRoad == 0) return StatusCode::SUCCESS;
1198
1199 if(hitsInRoad < 6) {
1200 ATH_MSG_DEBUG("Number of MM hits is too small, at least 6 hits required : "<<hitsInRoad<<" hits");
1201 return StatusCode::SUCCESS;
1202 } else if(hitsInRoad > 100) {
1203 ATH_MSG_WARNING("Number of MM hits is too large, at most (2^16 - 1) hits allowed : "<<hitsInRoad<<" hits");
1204 return StatusCode::SUCCESS;
1205 }
1206
1207 std::array< std::vector<int>, 8 > hitIdByLayer;
1208 for(unsigned int iHit = 0; iHit < mmHits.size(); ++iHit){
1209 if(mmHits.at(iHit).isOutlier != 1) continue;
1210 int layerNumber = mmHits.at(iHit).layerNumber;
1211 if (layerNumber > 7) {
1212 ATH_MSG_WARNING("MM hit layer number > 7");
1213 continue;
1214 }
1215 hitIdByLayer[layerNumber].push_back(iHit);
1216 }
1217 ATH_MSG_DEBUG("@@MM@@ Nhits " << hitIdByLayer[0].size()
1218 << " " << hitIdByLayer[1].size()
1219 << " " << hitIdByLayer[2].size()
1220 << " " << hitIdByLayer[3].size()
1221 << " " << hitIdByLayer[4].size()
1222 << " " << hitIdByLayer[5].size()
1223 << " " << hitIdByLayer[6].size()
1224 << " " << hitIdByLayer[7].size());
1225
1226 std::vector< std::array<int, 8> > mmHitIds;
1227 findSetOfMmHitIds(mmHits, hitIdByLayer, mmHitIds);
1228 for (unsigned int iHit = 0; iHit < mmHitIds.size(); ++iHit) {
1229 std::array<int, 8> hitIds = mmHitIds.at(iHit);
1230 for (unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
1231 if (hitIds[iLayer] != -1) {
1232 mmHits.at(hitIds[iLayer]).isOutlier = 0;
1233 }
1234 }
1235 }
1236 return StatusCode::SUCCESS;
1237}
1238
1240 std::array<std::vector<int>,8> hitIdByLayer,
1241 std::vector<std::array<int, 8>>& hitIdsCandidate) const
1242{
1243
1244 double NSWCenterZ = 7526.329;
1245 int side = 0;
1246 for (unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
1247 if ( hitIdByLayer[iLayer].size() > 0) {
1248 side = std::abs(mmHits.at(hitIdByLayer[iLayer].at(0)).z)/mmHits.at(hitIdByLayer[iLayer].at(0)).z;
1249 break;
1250 }
1251 }
1252 NSWCenterZ = NSWCenterZ * side;
1253
1254 std::array<std::vector<unsigned long int>,4> hitIdsInTwo;
1255 std::array<std::vector<double>,4> slopeInTwo;
1256 std::array<std::vector<double>,4> interceptInTwo;
1257 // Loop over pairs of the i-th and the (i+6)-th layers
1258 for(unsigned int iPair = 0; iPair < 4; ++iPair){
1259
1260 unsigned int nHitsInInner = hitIdByLayer[iPair].size();
1261 unsigned int nHitsInOuter;
1262 if (iPair < 2) { // paris of X layers
1263 nHitsInOuter = hitIdByLayer[iPair+6].size();
1264 } else { // pairs of U or V layers
1265 nHitsInOuter = hitIdByLayer[iPair+2].size();
1266 }
1267
1268 if ( nHitsInInner > 0xffff-1 || nHitsInOuter > 0xffff-1) {
1269 ATH_MSG_WARNING("Number of Mm hits in layers exceeds the limit of (2^16 - 1) : Number of Mm hits in "<<iPair<<"th layer = "<< nHitsInInner
1270 <<", Number of Mm hits in "<<iPair+4<<"th layer = "<<nHitsInOuter);
1271 ATH_MSG_WARNING("Number of Mm hits is limitted to (2^16 - 1) and hits with id more than (2^16 -1) will be trancated.");
1272 if (nHitsInInner > 0xffff-1) {nHitsInInner = 0xffff-1;}
1273 if (nHitsInOuter > 0xffff-1) {nHitsInOuter = 0xffff-1;}
1274 }
1275
1276 bool foundCounterparts[0xffff] = {};
1277 // Loop over hits in the i-th layer
1278 for(unsigned int iHit = 0; iHit < nHitsInInner; ++iHit){
1279
1280 bool foundCounterpart = 0;
1281
1282 double z[2] = {};
1283 double r[2] = {};
1284
1285 int iHitId = hitIdByLayer[iPair].at(iHit);
1286 r[0] = mmHits.at(iHitId).r;
1287 z[0] = mmHits.at(iHitId).z;
1288
1289 // Loop over hits in the (i+6)-th layer
1290 for(unsigned int jHit = 0; jHit < nHitsInOuter; ++jHit){
1291
1292 int jHitId;
1293 if (iPair < 2) {
1294 jHitId = hitIdByLayer[iPair+6].at(jHit);
1295 } else {
1296 jHitId = hitIdByLayer[iPair+2].at(jHit);
1297 }
1298 r[1] = mmHits.at(jHitId).r;
1299 z[1] = mmHits.at(jHitId).z;
1300
1301 double slope = (r[1] - r[0]) / (z[1] - z[0]);
1302 double intercept = slope*(0. - z[0]) + r[0];
1303 // select pairs whose slops in limited regions
1304 if(std::abs(slope) < 0.1 || std::abs(slope) > 0.7 || std::abs(intercept) > 500.) continue;
1305
1306 int encodedIds = (iHitId<<16) + jHitId;
1307 hitIdsInTwo[iPair].push_back(encodedIds);
1308 slopeInTwo[iPair].push_back(slope);
1309 interceptInTwo[iPair].push_back(intercept);
1310
1311 foundCounterpart = 1;
1312 foundCounterparts[jHit] = 1;
1313 }//end of jHit in the (i+6)-th layer
1314 if(!foundCounterpart){ // in case of no counterpart in the (i+4)-th layer
1315 int encodedIds = (iHitId<<16) + 0xffff; // fill all bits with 1 for hit id for the layer with no hit
1316 hitIdsInTwo[iPair].push_back(encodedIds);
1317 slopeInTwo[iPair].push_back(r[0]/z[0]);
1318 interceptInTwo[iPair].push_back(0.);
1319 }
1320 }//end of iHit in the i-th layer
1321 // Loop over hits in the (i+4)-th layer
1322 for(unsigned int jHit = 0; jHit < nHitsInOuter; ++jHit){
1323 if (!foundCounterparts[jHit]) {
1324 int jHitId;
1325 if (iPair < 2) {
1326 jHitId = hitIdByLayer[iPair+6].at(jHit);
1327 } else {
1328 jHitId = hitIdByLayer[iPair+2].at(jHit);
1329 }
1330 int encodedIds = (0xFFFFu<<16) + jHitId; // fill all bits with 1 for hit id for the layer with no hit
1331 hitIdsInTwo[iPair].push_back(encodedIds);
1332 slopeInTwo[iPair].push_back(mmHits.at(jHitId).r/mmHits.at(jHitId).z);
1333 interceptInTwo[iPair].push_back(0.);
1334 }
1335 }
1336 }//end of pair loop
1337 ATH_MSG_DEBUG("@@MM@@ Npairs " << hitIdsInTwo[0].size() << " " << hitIdsInTwo[1].size() << " " << hitIdsInTwo[2].size() << " " << hitIdsInTwo[3].size());
1338 for (unsigned int iLayer = 0; iLayer < 4; ++ iLayer) {
1339 for (unsigned int iPair = 0; iPair < slopeInTwo[iLayer].size(); ++iPair) {
1340 ATH_MSG_DEBUG("@@MM@@ pair fit slope= " << slopeInTwo[iLayer].at(iPair) << " intercept= " << interceptInTwo[iLayer].at(iPair));
1341 }
1342 }
1343
1344 std::vector<std::array<int, 4>> hitIdsInFourX;
1345 std::vector<double> slopeInFourX;
1346 std::vector<double> interceptInFourX;
1347 std::vector<double> mseInFourX;
1348
1349 unsigned int nPairsInInnerX = hitIdsInTwo[0].size();
1350 unsigned int nPairsInOuterX = hitIdsInTwo[1].size();
1351
1352 for(unsigned int iPairX = 0; iPairX < nPairsInInnerX; ++iPairX){
1353
1354 double slope[2];
1355 double intercept[2];
1356 double spR[2];
1357
1358 slope[0] = slopeInTwo[0].at(iPairX);
1359 intercept[0] = interceptInTwo[0].at(iPairX);
1360 spR[0] = slope[0] * NSWCenterZ + intercept[0];
1361 for(unsigned int jPairX = 0; jPairX < nPairsInOuterX; ++jPairX){
1362 int ihitIds = hitIdsInTwo[0].at(iPairX);
1363 int jhitIds = hitIdsInTwo[1].at(jPairX);
1364 if ( ((ihitIds>>16 & 0xffff) == 0xffff || (ihitIds & 0xffff) == 0xffff) &&
1365 ((jhitIds>>16 & 0xffff) == 0xffff || (jhitIds & 0xffff) == 0xffff )) continue; // require at least 3 hits in 4 layers
1366
1367 slope[1] = slopeInTwo[1].at(jPairX);
1368 intercept[1] = interceptInTwo[1].at(jPairX);
1369 spR[1] = slope[1] * NSWCenterZ + intercept[1];
1370
1371 if(std::abs(spR[1] - spR[0]) > 50. ||
1372 std::abs((intercept[1] + intercept[0]) / 2) > 200.) continue;
1373
1374 std::array<int, 4> setOfHitIds{};
1375 setOfHitIds[0] = (ihitIds>>16 & 0xffff);
1376 setOfHitIds[1] = (ihitIds & 0xffff);
1377 setOfHitIds[2] = (jhitIds>>16 & 0xffff);
1378 setOfHitIds[3] = (jhitIds & 0xffff);
1379 std::vector<double> r;
1380 std::vector<double> z;
1381 for(unsigned int iLayer = 0; iLayer < 4; ++iLayer){
1382 if(setOfHitIds[iLayer] == 0xffff) {
1383 continue;
1384 }
1385 double rhit = mmHits.at(setOfHitIds[iLayer]).r;
1386 double zhit = mmHits.at(setOfHitIds[iLayer]).z;
1387 r.push_back(rhit);
1388 z.push_back(zhit);
1389 }
1390 double slopefit=0., interceptfit=99999., mse=-1.;
1391 LinearFit(z,r,&slopefit, &interceptfit, &mse);
1392
1393 hitIdsInFourX.push_back(setOfHitIds);
1394 slopeInFourX.push_back(slopefit);
1395 interceptInFourX.push_back(interceptfit);
1396 mseInFourX.push_back(mse);
1397
1398 }// end of iPair of the i-th and (i+4)-th layers, i=0,2
1399 }// end of jPair of the j-th and (j+4)-th layers, j=1,3
1400 ATH_MSG_DEBUG("@@MM@@ X Nquads " << hitIdsInFourX.size());
1401 for (unsigned int iQuad = 0; iQuad < slopeInFourX.size(); ++iQuad) {
1402 ATH_MSG_DEBUG("@@MM@@ X quad fit slope= " << slopeInFourX.at(iQuad) << " intercept= " << interceptInFourX.at(iQuad) << " mse= " << mseInFourX.at(iQuad));
1403 }
1404
1405 if(!hitIdsInFourX.size()){
1406 ATH_MSG_WARNING("No candidate segment found in MM X layers");
1407 return;
1408 }
1409
1410 double tanTiltAngleU = 0,
1411 tanTiltAngleV = 0;
1412 if(side > ZERO_LIMIT){
1413 tanTiltAngleU = tan( 1.5/360.*2.*M_PI),
1414 tanTiltAngleV = tan(-1.5/360.*2.*M_PI);
1415 } else if(side < -1.*ZERO_LIMIT){
1416 tanTiltAngleU = tan(-1.5/360.*2.*M_PI),
1417 tanTiltAngleV = tan(1.5/360.*2.*M_PI);
1418 }
1419
1420 std::vector< std::array<int, 8> > hitIdsInEight;
1421 std::vector<double> mseInEight;
1422
1423 for(unsigned int iQuadX = 0; iQuadX < hitIdsInFourX.size(); ++iQuadX){
1424 if(mseInFourX.at(iQuadX) > 10) continue;
1425
1426 double slopeX = slopeInFourX.at(iQuadX);
1427 double interceptX = interceptInFourX.at(iQuadX);
1428 std::array<int,4> hitIdsX{};
1429 hitIdsX = hitIdsInFourX.at(iQuadX);
1430
1431 for (unsigned int iPairU = 0; iPairU < hitIdsInTwo[2].size(); ++iPairU) {
1432
1433 int hitIdsU[2];
1434 hitIdsU[0] = hitIdsInTwo[2].at(iPairU)>>16 & 0xffff;
1435 hitIdsU[1] = hitIdsInTwo[2].at(iPairU) & 0xffff;
1436 double phiLocalU[2]={-99999,-99999};
1437 for(unsigned int iLayer = 0; iLayer < 2; ++iLayer) {
1438 if (hitIdsU[iLayer] == 0xffff) continue;
1439 if (hitIdsU[iLayer] < 0) {
1440 ATH_MSG_DEBUG("@@MM@@ hitIdsU[iLayer] iLayer= " << iLayer << " hitIdsU[iLayer]= " << hitIdsU[iLayer]);
1441 }
1442 double rInterpolate = slopeX * mmHits.at(hitIdsU[iLayer]).z + interceptX;
1443 double rProj = mmHits.at(hitIdsU[iLayer]).r;
1444 if(std::abs(tanTiltAngleU) < ZERO_LIMIT)
1445 phiLocalU[iLayer] = 0;
1446 else
1447 phiLocalU[iLayer] = std::atan((rProj-rInterpolate)/tanTiltAngleU/rInterpolate);
1448 }
1449
1450 for(unsigned int iPairV = 0; iPairV < hitIdsInTwo[3].size(); ++iPairV) {
1451
1452 int hitIdsV[2];
1453 hitIdsV[0] = hitIdsInTwo[3].at(iPairV)>>16 & 0xffff;
1454 hitIdsV[1] = hitIdsInTwo[3].at(iPairV) & 0xffff;
1455
1456 if( (hitIdsU[0] == 0xffff || hitIdsU[1] == 0xffff) &&
1457 (hitIdsV[0] == 0xffff || hitIdsV[1] == 0xffff) ) continue; // require at least 3 UV layers having hits
1458
1459 double phiLocalV[2]={-99999,-99999};
1460 for(unsigned int iLayer = 0; iLayer < 2; ++iLayer) {
1461 if (hitIdsV[iLayer] == 0xffff) continue;
1462 if (hitIdsV[iLayer] < 0) {
1463 ATH_MSG_DEBUG("@@MM@@ hitIdsV[iLayer] iLayer= " << iLayer << " hitIdsV[iLayer]= " << hitIdsV[iLayer]);
1464 }
1465 double rInterpolate = slopeX * mmHits.at(hitIdsV[iLayer]).z + interceptX;
1466 double rProj = mmHits.at(hitIdsV[iLayer]).r;
1467 if(std::abs(tanTiltAngleV) < ZERO_LIMIT)
1468 phiLocalV[iLayer] = 0;
1469 else
1470 phiLocalV[iLayer] = std::atan((rProj-rInterpolate)/tanTiltAngleV/rInterpolate);
1471 }
1472
1473 if ( std::abs(phiLocalU[0]-phiLocalV[0]) > 0.05 &&
1474 std::abs(phiLocalU[1]-phiLocalV[1]) > 0.05) continue;
1475
1476 // average of phis in 4 UV layers
1477 double phiLocalUV = 0;
1478 int nPhi = 0;
1479 for(unsigned int iLayer = 0; iLayer < 2; ++iLayer) {
1480 if(phiLocalU[iLayer] > -99999.) {
1481 phiLocalUV += phiLocalU[iLayer];
1482 ++nPhi;
1483 }
1484 if(phiLocalV[iLayer] > -99999.) {
1485 phiLocalUV += phiLocalV[iLayer];
1486 ++nPhi;
1487 }
1488 }
1489 phiLocalUV /= nPhi;
1490
1491 std::array<int, 8> setOfHitIds = {-1,-1,-1,-1,-1,-1,-1,-1};
1492 std::vector<double> r, z;
1493 for (unsigned int iLayer = 0; iLayer < 4; ++iLayer) {
1494 if ( hitIdsX[iLayer] != 0xffff) {
1495 if (hitIdsX[iLayer] < 0) {
1496 ATH_MSG_DEBUG("@@MM@@ hitIdsX[iLayer] iLayer= " << iLayer << " hitIdsX[iLayer]= " << hitIdsX[iLayer]);
1497 }
1498 z.push_back(mmHits.at(hitIdsX[iLayer]).z);
1499 r.push_back(mmHits.at(hitIdsX[iLayer]).r / std::cos(phiLocalUV));
1500 setOfHitIds[iLayer] = hitIdsX[iLayer];
1501 }
1502 }
1503 for (unsigned int iLayer = 0; iLayer < 2; ++iLayer) {
1504 if ( hitIdsU[iLayer] != 0xffff) {
1505 if (hitIdsU[iLayer] < 0) {
1506 ATH_MSG_DEBUG("@@MM@@ 2 hitIdsU[iLayer] iLayer= " << iLayer << " hitIdsU[iLayer]= " << hitIdsU[iLayer]);
1507 }
1508 z.push_back(mmHits.at(hitIdsU[iLayer]).z);
1509 r.push_back(mmHits.at(hitIdsU[iLayer]).r*(std::cos(phiLocalUV) + 1/std::cos(phiLocalUV))/2.);
1510 setOfHitIds[iLayer+4] = hitIdsU[iLayer];
1511 }
1512 if ( hitIdsV[iLayer] != 0xffff) {
1513 if (hitIdsV[iLayer] < 0) {
1514 ATH_MSG_DEBUG("@@MM@@ 2 hitIdsV[iLayer] iLayer= " << iLayer << " hitIdsV[iLayer]= " << hitIdsV[iLayer]);
1515 }
1516 z.push_back(mmHits.at(hitIdsV[iLayer]).z);
1517 r.push_back(mmHits.at(hitIdsV[iLayer]).r*(std::cos(phiLocalUV) + 1/std::cos(phiLocalUV))/2.);
1518 setOfHitIds[iLayer+6] = hitIdsV[iLayer];
1519 }
1520 }
1521 double slopefit=0., interceptfit=99999., mse=-1.;
1522 LinearFit(z,r,&slopefit,&interceptfit,&mse);
1523
1524 hitIdsInEight.push_back(setOfHitIds);
1525 mseInEight.push_back(mse);
1526 } // end of Pair loop of V layers
1527 } // end of Pair loop of U Layers
1528 }// end of Quad loop of X layers
1529 ATH_MSG_DEBUG("@@MM@@ Noctets " << hitIdsInEight.size());
1530
1531 std::vector<int> nOctetSegments;
1532 std::vector<int> patternStationName;
1533 for (unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet) {
1534 bool isFirstHit = true;
1535 int hitStationName = 0;
1536 int nOctetSegment = 0;
1537 ATH_MSG_DEBUG("@@MM@@ octet fit mse " << mseInEight.at(iOctet));
1538 std::array<int, 8> tmpOctet = hitIdsInEight.at(iOctet);
1539 for (unsigned int iLayer = 0; iLayer < 8; ++iLayer) {
1540 if (tmpOctet[iLayer] != -1) {
1541
1542 if(isFirstHit){
1543 hitStationName = mmHits.at(tmpOctet[iLayer]).stationName;
1544 isFirstHit = false;
1545
1546 ATH_MSG_DEBUG("@@MM@@ octet pos r= " << mmHits.at(tmpOctet[iLayer]).r << " phi= " << mmHits.at(tmpOctet[iLayer]).phi << " z= " << mmHits.at(tmpOctet[iLayer]).z);
1547 nOctetSegment++;
1548 }
1549 else if(mmHits.at(tmpOctet[iLayer]).stationName == hitStationName){
1550 ATH_MSG_DEBUG("@@MM@@ octet pos r= " << mmHits.at(tmpOctet[iLayer]).r << " phi= " << mmHits.at(tmpOctet[iLayer]).phi << " z= " << mmHits.at(tmpOctet[iLayer]).z);
1551 nOctetSegment++;
1552 }
1553
1554 }
1555 }
1556 nOctetSegments.push_back(nOctetSegment);
1557 patternStationName.push_back(hitStationName);
1558 }
1559
1560 double mseminL = 100000.;
1561 double mseminS = 100000.;
1562 std::vector<int> octetIds(2,-1);
1563 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
1564 if(patternStationName.at(iOctet) == 56){
1565 if( mseInEight.at(iOctet) < mseminL) {
1566 mseminL = mseInEight.at(iOctet);
1567 }
1568 }
1569 else if(patternStationName.at(iOctet) == 55){
1570 if( mseInEight.at(iOctet) < mseminS) {
1571 mseminS = mseInEight.at(iOctet);
1572 }
1573 }
1574 }// end of Octet loop
1575
1576 for(unsigned int iOctet = 0; iOctet < hitIdsInEight.size(); ++iOctet){
1577 if(patternStationName.at(iOctet) == 56){
1578 if( mseInEight.at(iOctet) != mseminL) {
1579 continue;
1580 }
1581 }
1582 else if(patternStationName.at(iOctet) == 55){
1583 if( mseInEight.at(iOctet) != mseminS) {
1584 continue;
1585 }
1586 }
1587 octetIds.push_back(iOctet);
1588 }
1589
1590 for(unsigned int ids = 0; ids < octetIds.size(); ids++){
1591 if (octetIds.at(ids) != -1) {
1592 hitIdsCandidate.push_back(hitIdsInEight.at(octetIds.at(ids)));
1593 }
1594 }
1595}
#define M_PI
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static const double SinM1p5
static const double CosP1p5
static const double SinP1p5
static const double TanP1p5
static const double CosM1p5
static const double TanM1p5
static const uint32_t nHits
#define y
#define x
#define z
const float ZERO_LIMIT
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
virtual double phi() const override final
Methods to retrieve data members.
virtual double eta() const override final
void findSetOfStgcHitIds(TrigL2MuonSA::StgcHits &stgcHits, std::array< std::vector< int >, 8 > hitIdByLayer, std::vector< std::array< int, 8 > > &hitIdsCandidate) const
StatusCode findMmHitsInSegment(TrigL2MuonSA::MmHits &mmHits) const
StatusCode calcMergedHit(TrigL2MuonSA::TrackPattern &trackPattern) const
StatusCode MakeSegment(TrigL2MuonSA::TrackPattern &trackPattern, TrigL2MuonSA::StgcHits &stgcHits) const
StatusCode superPointFitter(const TrigRoiDescriptor *p_roids, TrigL2MuonSA::TrackPattern &trackPattern, TrigL2MuonSA::StgcHits &stgcHits, TrigL2MuonSA::MmHits &mmHits) const
void getNswResolution(double *stgcDeltaR, double *mmDeltaR, unsigned int size) const
NswStationFitter(const std::string &type, const std::string &name, const IInterface *parent)
StatusCode findStgcHitsInSegment(TrigL2MuonSA::StgcHits &stgcHits) const
StatusCode selectMmHits(const TrigRoiDescriptor *p_roids, TrigL2MuonSA::MmHits &mmHits) const
StatusCode calcWeightedSumHit(TrigL2MuonSA::TrackPattern &trackPattern) const
void findSetOfMmHitIds(TrigL2MuonSA::MmHits &mmHits, std::array< std::vector< int >, 8 > hitIdByLayer, std::vector< std::array< int, 8 > > &hitIdsCandidate) const
void LinearFit(std::vector< double > &x, std::vector< double > &y, double *slope, double *intercept, double *mse) const
StatusCode selectStgcHits(const TrigRoiDescriptor *p_roids, TrigL2MuonSA::StgcHits &stgcHits) const
void LinearFitWeight(std::vector< double > &x, std::vector< double > &y, std::vector< bool > &isStgc, double *slope, double *intercept, double *mse, double eta) const
unsigned int layerNumber
Definition StgcData.h:42
TrigL2MuonSA::MmHits mmSegment
Definition TrackData.h:58
TrigL2MuonSA::SuperPoint superPoints[s_NCHAMBER]
Definition TrackData.h:60
TrigL2MuonSA::StgcHits stgcSegment
Definition TrackData.h:59
nope - should be used for standalone also, perhaps need to protect the class def bits ifndef XAOD_ANA...
int r
Definition globals.cxx:22
std::vector< StgcHitData > StgcHits
Definition StgcData.h:49
std::vector< MmHitData > MmHits
Definition MmData.h:47
Chamber
Define chamber types and locations.
@ EndcapInner
Inner station in the endcap spectrometer.