41 std::vector<MMPrepData>&& MMprds,
42 std::vector<std::unique_ptr<MMPrepData>>& clustersVect)
const {
48 ATH_MSG_DEBUG(
"Sorting PRD into layer layer: " << layer <<
" gas_gap " <<
m_idHelperSvc->mmIdHelper().gasGap(
id) <<
"multilayer "
50 MMprdsPerLayer.at(layer).push_back(std::move(MMprd));
54 for (std::vector<MMPrepData>& prdInLay : MMprdsPerLayer) {
56 return m_idHelperSvc->mmIdHelper().channel(a.identify()) < m_idHelperSvc->mmIdHelper().channel(b.identify());
60 for (std::vector<MMPrepData>& MMprdsOfLayer : MMprdsPerLayer) {
61 std::vector<double> stripsLocalPosX;
62 stripsLocalPosX.reserve(MMprdsOfLayer.size());
67 stripsLocalPosX.push_back(
69 MMprd.localPosition().x());
72 double globalR = MMprd.globalPosition().perp();
73 double Tan = globalR / MMprd.globalPosition().z();
74 double angleToIp = std::atan(Tan) / Gaudi::Units::degree;
77 << MMprd.driftDist() <<
" localPosX " <<
Amg::toString(MMprd.localPosition())
78 <<
" angleToIp " << angleToIp);
80 if (MMprdsOfLayer.size() < 2)
continue;
83 double meanX = std::accumulate(stripsLocalPosX.begin(), stripsLocalPosX.end(), 0.0) / stripsLocalPosX.size();
85 std::for_each(stripsLocalPosX.begin(), stripsLocalPosX.end(), [meanX](
double& d) { d -= meanX; });
89 std::vector<int> flag = std::vector<int>(MMprdsOfLayer.size(), 0);
93 std::vector<int> idx_goodStrips;
94 StatusCode
sc =
runHoughTrafo(MMprdsOfLayer, stripsLocalPosX, flag, idx_goodStrips);
98 if (idx_goodStrips.size() < 3 ||
sc.isFailure()) {
100 idx_goodStrips.clear();
101 for (
size_t i_hit = 0; i_hit < MMprdsOfLayer.size(); i_hit++) {
102 if (flag.at(i_hit) == 0) idx_goodStrips.push_back(i_hit);
108 int nStripsCutByCrosstalk = 0;
109 while (!
applyCrossTalkCut(idx_goodStrips, MMprdsOfLayer, flag, nStripsCutByCrosstalk).isFailure()) {}
110 ATH_MSG_DEBUG(
"After cutting CT idx_goddStrips " << idx_goodStrips <<
" flag " << flag);
112 std::vector<Identifier> stripsOfCluster;
113 std::vector<uint16_t> stripsOfClusterChannels;
114 std::vector<short int> stripsOfClusterTimes;
115 std::vector<int> stripsOfClusterCharges;
116 std::vector<float> stripsOfClusterDriftDists;
117 std::vector<
AmgVector(2)> stripsOfClusterDriftDistErrors;
118 std::vector<float> stripsOfClusterLocalPos;
119 stripsOfCluster.reserve(idx_goodStrips.size());
121 stripsOfClusterTimes.reserve(idx_goodStrips.size());
122 stripsOfClusterCharges.reserve(idx_goodStrips.size());
123 stripsOfClusterDriftDists.reserve(idx_goodStrips.size());
124 stripsOfClusterDriftDistErrors.reserve(idx_goodStrips.size());
125 stripsOfClusterLocalPos.reserve(idx_goodStrips.size());
127 ATH_MSG_DEBUG(
"Found good Strips: " << idx_goodStrips.size());
129 for (
int idx : idx_goodStrips) {
130 ATH_MSG_DEBUG(
"Setting good strip: " << idx <<
" size of strips flag: " << flag.size());
133 stripsOfCluster.push_back(MMprdsOfLayer.at(idx).identify());
135 stripsOfClusterChannels.push_back(
m_idHelperSvc->mmIdHelper().channel(MMprdsOfLayer.at(idx).identify()));
136 stripsOfClusterTimes.push_back(MMprdsOfLayer.at(idx).time());
137 stripsOfClusterCharges.push_back(MMprdsOfLayer.at(idx).charge());
139 stripsOfClusterDriftDists.push_back(MMprdsOfLayer.at(idx).driftDist());
140 const Amg::MatrixX cov{MMprdsOfLayer.at(idx).localCovariance()};
141 stripsOfClusterDriftDistErrors.emplace_back(cov(0,0), cov(1,1));
142 stripsOfClusterLocalPos.push_back(MMprdsOfLayer.at(idx).localPosition().x());
145 double localClusterPosition = -9999;
146 double sigmaLocalClusterPosition = 0;
147 double finalFitAngle, finalFitChiSqProb;
149 sc =
finalFit(stripsOfCluster, stripsOfClusterLocalPos, stripsOfClusterDriftDists, stripsOfClusterDriftDistErrors,
150 localClusterPosition, sigmaLocalClusterPosition, finalFitAngle, finalFitChiSqProb);
154 if (
sc.isFailure())
break;
158 covN.coeffRef(0, 0) = sigmaLocalClusterPosition;
160 int idx = idx_goodStrips[0];
161 ATH_MSG_DEBUG(
"idx_goodStrips[0]: " << idx <<
" size: " << MMprdsOfLayer.size());
163 MMprdsOfLayer.at(idx).localPosition().y());
166 float driftDist = 0.0;
168 std::unique_ptr<MMPrepData> prdN = std::make_unique<MMPrepData>(MMprdsOfLayer.at(idx).identify(),
169 MMprdsOfLayer.at(idx).collectionHash(),
170 std::move(localClusterPositionV),
171 std::move(stripsOfCluster),
173 MMprdsOfLayer.at(idx).detectorElement(),
175 std::accumulate(stripsOfClusterCharges.begin(), stripsOfClusterCharges.end(), 0),
177 std::move(stripsOfClusterChannels),
178 std::move(stripsOfClusterTimes),
179 std::move(stripsOfClusterCharges));
183 ATH_MSG_DEBUG(
"Setting prd angle: " << finalFitAngle <<
" chi2 Prob: " << finalFitChiSqProb);
186 prdN->setDriftDist(std::move(stripsOfClusterDriftDists), std::move(stripsOfClusterDriftDistErrors));
188 prdN->setMicroTPC(finalFitAngle, finalFitChiSqProb);
189 ATH_MSG_DEBUG(
"Reading back prd angle: " << prdN->angle() <<
" chi2 Prob: " << prdN->chisqProb());
190 clustersVect.push_back(std::move(prdN));
192 int leftOverStrips = 0;
193 for (
auto f : flag) {
194 if (f == 0) leftOverStrips++;
196 if (leftOverStrips < 3)
break;
201 return StatusCode::SUCCESS;
278 std::vector<int>& flag, std::vector<std::tuple<double, double>>& tracks,
279 std::vector<int>& idxGoodStrips)
const {
280 std::vector<double>
chi2;
281 std::vector<std::vector<int>> allGoodStrips;
282 std::vector<int> ngoodStrips;
283 std::vector<std::tuple<int, double>> trackQuality;
284 for (
auto track : tracks) {
285 double houghAngle = std::get<0>(track);
286 double houghD = std::get<1>(track);
287 double slope, intercept;
291 if (
sc.isFailure()) {
return sc; }
292 std::vector<double> dist;
293 std::vector<int> indexUsedForDist, goodStrips;
294 for (
size_t i_hit = 0; i_hit < xpos.size(); i_hit++) {
295 if (flag.at(i_hit) != 1) {
296 dist.push_back(mmPrd.at(i_hit).driftDist() - slope * xpos.at(i_hit) - intercept);
297 indexUsedForDist.push_back(i_hit);
303 for (
size_t i_hit : indexUsedForDist) {
304 double d = mmPrd.at(i_hit).driftDist() - slope * xpos.at(i_hit) - intercept;
307 dist.push_back(d * d / mmPrd.at(i_hit).localCovariance()(1, 1));
308 goodStrips.push_back(i_hit);
312 ATH_MSG_DEBUG(
"Angle estimate =" << std::get<0>(track) <<
" " << std::get<0>(track) / Gaudi::Units::degree);
324 ATH_MSG_DEBUG(
"chi2 =" << std::accumulate(dist.begin(), dist.end(), 0.0) / (dist.size() - 2));
326 if (!goodStrips.empty()) {
327 allGoodStrips.push_back(goodStrips);
328 chi2.push_back(std::accumulate(dist.begin(), dist.end(), 0.0) / (dist.size() - 2));
329 trackQuality.emplace_back(goodStrips.size(), std::accumulate(dist.begin(), dist.end(), 0.0) / (dist.size() - 2));
332 if (
chi2.empty())
return StatusCode::FAILURE;
333 int trackIndex = std::min_element(trackQuality.begin(), trackQuality.end(), sortTracks) - trackQuality.begin();
334 idxGoodStrips = allGoodStrips.at(trackIndex);
335 return StatusCode::SUCCESS;
389 const std::vector<float>& driftDists,
const std::vector<
AmgVector(2)>& driftDistErrors,
390 double& x0,
double& sigmaX0,
double& fitAngle,
double& chiSqProb)
const {
391 std::unique_ptr<TGraphErrors> fitGraph = std::make_unique<TGraphErrors>();
392 std::unique_ptr<TF1> ffit = std::make_unique<TF1>(
"ffit",
"pol1");
396 double xmean = std::accumulate(stripsPos.begin(), stripsPos.end(), 0.0) / stripsPos.size();
398 std::unique_ptr<TLinearFitter> lf = std::make_unique<TLinearFitter>(1,
"1++x");
400 for (
size_t idx = 0; idx < stripsPos.size(); idx++) {
401 double xpos = stripsPos.at(idx) - xmean;
404 else if (
xmax < xpos)
406 lf->AddPoint(&xpos, driftDists.at(idx));
407 fitGraph->SetPoint(fitGraph->GetN(), xpos, driftDists.at(idx));
408 fitGraph->SetPointError(fitGraph->GetN() - 1, std::sqrt(driftDistErrors.at(idx)[0]), std::sqrt(driftDistErrors.at(idx)[1]));
413 ffit->SetParLimits(1, -11.5, -0.15);
415 ffit->SetParLimits(1, 0.15, 11.5);
417 ffit->SetParameters(lf->GetParameter(0), lf->GetParameter(1));
418 TFitResultPtr s = fitGraph->Fit(
"ffit",
"SMQ",
"",
xmin - .5,
xmax + .5);
420 double cov = (s->GetCovarianceMatrix())(0, 1);
422 double fitSlope = ffit->GetParameter(1);
423 double dHalfGap = 2.52;
424 double interceptCorr = dHalfGap - ffit->GetParameter(0);
425 x0 = interceptCorr / fitSlope;
427 (std::pow(ffit->GetParError(0) / interceptCorr, 2) + std::pow(ffit->GetParError(1) / fitSlope, 2) - 2. / (fitSlope * interceptCorr) * cov) *
430 fitAngle = std::tan(-1 / fitSlope);
431 chiSqProb = ffit->GetProb();
442 ATH_MSG_DEBUG(
"Cluster position " << x0 <<
" +- " << sigmaX0);
450 if (s != 0 && s != 4000) {
452 return StatusCode::FAILURE;
455 (ffit->GetParameter(1) <= -11.49 || ffit->GetParameter(1) >= -0.151))
456 return StatusCode::FAILURE;
458 (ffit->GetParameter(1) >= 11.49 || ffit->GetParameter(1) <= 0.151))
459 return StatusCode::FAILURE;
460 return StatusCode::SUCCESS;
464 const std::vector<NSWCalib::CalibratedStrip>& calibratedStrips,
469 std::vector<Identifier> ids;
470 std::vector<float> stripsPos;
471 std::vector<float> driftDists;
472 std::vector<
AmgVector(2)> driftDistErrors;
475 ids.push_back(
strip.identifier);
476 stripsPos.push_back(
strip.locPos.x());
477 driftDists.push_back(
strip.distDrift);
478 driftDistErrors.emplace_back(
strip.resTransDistDrift,
strip.resLongDistDrift);
481 double localClusterPosition = -9999;
482 double sigmaLocalClusterPosition = 0;
483 double finalFitAngle, finalFitChiSqProb;
485 StatusCode
sc =
finalFit(ids, stripsPos, driftDists, driftDistErrors, localClusterPosition, sigmaLocalClusterPosition, finalFitAngle,
487 if (
sc == StatusCode::FAILURE)
return RIO_Author::unKnownAuthor;
489 clusterLocalPosition[
Trk::locX] = localClusterPosition;
492 covN.coeffRef(0, 0) = sigmaLocalClusterPosition;
494 return RIO_Author::uTPCClusterBuilder;