File indexing completed on 2025-12-17 09:20:34
0001
0002
0003
0004
0005
0006
0007
0008 #include "TpcCentralMembraneMatching.h"
0009
0010 #include <trackbase/CMFlashDifferenceContainerv1.h>
0011 #include <trackbase/CMFlashDifferencev1.h>
0012 #include <trackbase/LaserCluster.h>
0013 #include <trackbase/LaserClusterContainerv1.h>
0014 #include <trackbase/TpcDefs.h>
0015
0016 #include <tpc/LaserEventInfo.h>
0017
0018 #include <ffaobjects/EventHeader.h>
0019
0020 #include <fun4all/Fun4AllReturnCodes.h>
0021
0022 #include <phool/PHCompositeNode.h>
0023 #include <phool/getClass.h>
0024 #include <phool/phool.h>
0025
0026 #include <TF1.h>
0027 #include <TFile.h>
0028 #include <TGraph.h>
0029 #include <TH1.h>
0030 #include <TH2.h>
0031 #include <TStyle.h>
0032 #include <TTree.h>
0033 #include <TVector3.h>
0034
0035 #include <algorithm>
0036 #include <cmath>
0037 #include <format>
0038 #include <iomanip>
0039 #include <set>
0040 #include <string>
0041
0042 int layerMins[3] = {16, 23, 39};
0043 int layerMaxes[3] = {22, 38, 54};
0044
0045 namespace
0046 {
0047 template <class T>
0048 constexpr T delta_phi(const T& phi)
0049 {
0050 if (phi > M_PI)
0051 {
0052 return phi - 2. * M_PI;
0053 }
0054 if (phi <= -M_PI)
0055 {
0056 return phi + 2. * M_PI;
0057 }
0058
0059 return phi;
0060 }
0061
0062 template <class T>
0063 constexpr T square(const T& x)
0064 {
0065 return x * x;
0066 }
0067
0068 template <class T>
0069 inline T get_r(const T& x, const T& y)
0070 {
0071 return std::sqrt(square(x) + square(y));
0072 }
0073
0074
0075 [[maybe_unused]] std::ostream& operator<<(std::ostream& out, const Acts::Vector3& v)
0076 {
0077 out << "(" << v.x() << ", " << v.y() << ", " << v.z() << ")";
0078 return out;
0079 }
0080
0081
0082 [[maybe_unused]] void normalize_distortions(TpcDistortionCorrectionContainer* dcc)
0083 {
0084
0085 for (unsigned int i = 0; i < 2; ++i)
0086 {
0087
0088 for (int ip = 0; ip < dcc->m_hentries[i]->GetNbinsX(); ++ip)
0089 {
0090 for (int ir = 0; ir < dcc->m_hentries[i]->GetNbinsY(); ++ir)
0091 {
0092
0093 const auto entries = dcc->m_hentries[i]->GetBinContent(ip + 1, ir + 1);
0094 if (entries <= 1)
0095 {
0096 continue;
0097 }
0098
0099
0100 for (const auto& h : {dcc->m_hDRint[i], dcc->m_hDPint[i], dcc->m_hDZint[i]})
0101 {
0102 h->SetBinContent(ip + 1, ir + 1, h->GetBinContent(ip + 1, ir + 1) / entries);
0103 h->SetBinError(ip + 1, ir + 1, h->GetBinError(ip + 1, ir + 1) / entries);
0104 }
0105 }
0106 }
0107 }
0108 }
0109
0110
0111 [[maybe_unused]] void fill_guarding_bins(TpcDistortionCorrectionContainer* dcc)
0112 {
0113
0114 for (unsigned int i = 0; i < 2; ++i)
0115 {
0116 for (const auto& h : {dcc->m_hDRint[i], dcc->m_hDPint[i], dcc->m_hDZint[i], dcc->m_hentries[i]})
0117 {
0118
0119
0120
0121
0122
0123
0124 const auto phibins = h->GetNbinsX();
0125 const auto rbins = h->GetNbinsY();
0126 for (int ir = 0; ir < rbins; ++ir)
0127 {
0128
0129 h->SetBinContent(1, ir + 1, h->GetBinContent(phibins - 1, ir + 1));
0130 h->SetBinError(1, ir + 1, h->GetBinError(phibins - 1, ir + 1));
0131
0132
0133 h->SetBinContent(phibins, ir + 1, h->GetBinContent(2, ir + 1));
0134 h->SetBinError(phibins, ir + 1, h->GetBinError(2, ir + 1));
0135 }
0136
0137
0138 for (int iphi = 0; iphi < phibins; ++iphi)
0139 {
0140
0141 h->SetBinContent(iphi + 1, 1, h->GetBinContent(iphi + 1, 2));
0142 h->SetBinError(iphi + 1, 1, h->GetBinError(iphi + 1, 2));
0143
0144
0145 h->SetBinContent(iphi + 1, rbins, h->GetBinContent(iphi + 1, rbins - 1));
0146 h->SetBinError(iphi + 1, rbins, h->GetBinError(iphi + 1, rbins - 1));
0147 }
0148 }
0149 }
0150 }
0151
0152 }
0153
0154
0155 TpcCentralMembraneMatching::TpcCentralMembraneMatching(const std::string& name)
0156 : SubsysReco(name)
0157 {
0158
0159 CalculateCenters(nPads_R1, R1_e, nGoodStripes_R1_e, keepUntil_R1_e, nStripesIn_R1_e, nStripesBefore_R1_e, cx1_e, cy1_e);
0160 CalculateCenters(nPads_R1, R1, nGoodStripes_R1, keepUntil_R1, nStripesIn_R1, nStripesBefore_R1, cx1, cy1);
0161 CalculateCenters(nPads_R2, R2, nGoodStripes_R2, keepUntil_R2, nStripesIn_R2, nStripesBefore_R2, cx2, cy2);
0162 CalculateCenters(nPads_R3, R3, nGoodStripes_R3, keepUntil_R3, nStripesIn_R3, nStripesBefore_R3, cx3, cy3);
0163 }
0164
0165
0166 void TpcCentralMembraneMatching::set_grid_dimensions(int phibins, int rbins)
0167 {
0168 m_phibins = phibins;
0169 m_rbins = rbins;
0170 }
0171
0172
0173 double TpcCentralMembraneMatching::getPhiRotation_smoothed(TH1* hitHist, TH1* clustHist, bool side)
0174 {
0175
0176 hitHist->Smooth();
0177 clustHist->Smooth();
0178
0179
0180 TF1* f1 = new TF1("f1", [&](double* x, double* p)
0181 { return p[0] * hitHist->GetBinContent(hitHist->FindBin((x[0] - p[1]) > M_PI ? x[0] - p[1] - 2 * M_PI : x[0] - p[1])); }, -M_PI, M_PI, 2);
0182 f1->SetParNames("A", "shift");
0183 f1->SetParameters(1.0, 0.0);
0184 f1->SetParLimits(1, -M_PI / 18, M_PI / 18);
0185
0186 if (side && m_recoRotation[1][1] != -999)
0187 {
0188 f1->SetParameter(1, m_recoRotation[1][1]);
0189 }
0190 if (!side && m_recoRotation[0][1] != -999)
0191 {
0192 f1->SetParameter(1, m_recoRotation[0][1]);
0193 }
0194
0195 f1->SetNpx(500);
0196
0197 clustHist->Fit("f1", "IQ");
0198
0199
0200
0201
0202 return f1->GetParameter(1);
0203 }
0204
0205 void TpcCentralMembraneMatching::getRegionPhiRotation(bool side)
0206 {
0207 TH1* oddHist[3]{};
0208 TH1* evenHist[3]{};
0209
0210 TH1* oddTruthHist[3]{};
0211 TH1* evenTruthHist[3]{};
0212
0213 for (int i = 0; i < (int) m_reco_RPeaks[side].size(); i++)
0214 {
0215 int peak = reco_r_phi[side]->GetYaxis()->FindBin(m_reco_RPeaks[side][i]);
0216
0217 int region = 2;
0218 if (m_reco_RPeaks[side][i] < 41)
0219 {
0220 region = 0;
0221 }
0222 else if (m_reco_RPeaks[side][i] < 58)
0223 {
0224 region = 1;
0225 }
0226
0227 if (m_reco_RMatches[side][i] % 2)
0228 {
0229 if (!oddHist[region])
0230 {
0231 oddHist[region] = (TH1*) reco_r_phi[side]->ProjectionX(std::format("oddR{}_{}", region, side).c_str(), peak - 2, peak + 2);
0232 }
0233 else
0234 {
0235 oddHist[region]->Add(reco_r_phi[side]->ProjectionX(std::format("oddR{}_{}", region, side).c_str(), peak - 2, peak + 2));
0236 }
0237 }
0238 else
0239 {
0240 if (!evenHist[region])
0241 {
0242 evenHist[region] = (TH1*) reco_r_phi[side]->ProjectionX(std::format("evenR{}_{}", region, side).c_str(), peak - 2, peak + 2);
0243 }
0244 else
0245 {
0246 evenHist[region]->Add(reco_r_phi[side]->ProjectionX(std::format("evenR{}_{}", region, side).c_str(), peak - 2, peak + 2));
0247 }
0248 }
0249 }
0250
0251 for (unsigned int i = 0; i < m_truth_RPeaks.size(); i++)
0252 {
0253 int peak = truth_r_phi[side]->GetYaxis()->FindBin(m_truth_RPeaks[i]);
0254
0255 int region = 2;
0256 if (m_truth_RPeaks[i] < 41)
0257 {
0258 region = 0;
0259 }
0260 else if (m_truth_RPeaks[i] < 58)
0261 {
0262 region = 1;
0263 }
0264
0265 if (i % 2)
0266 {
0267 if (!oddTruthHist[region])
0268 {
0269 oddTruthHist[region] = (TH1*) truth_r_phi[side]->ProjectionX(std::format("oddTR{}_{}", region, side).c_str(), peak - 1, peak + 1);
0270 }
0271 else
0272 {
0273 oddTruthHist[region]->Add(truth_r_phi[side]->ProjectionX(std::format("oddTR{}_{}", region, side).c_str(), peak - 1, peak + 1));
0274 }
0275 }
0276 else
0277 {
0278 if (!evenTruthHist[region])
0279 {
0280 evenTruthHist[region] = (TH1*) truth_r_phi[side]->ProjectionX(std::format("evenTR{}_{}", region, side).c_str(), peak - 1, peak + 1);
0281 }
0282 else
0283 {
0284 evenTruthHist[region]->Add(truth_r_phi[side]->ProjectionX(std::format("evenTR{}_{}", region, side).c_str(), peak - 1, peak + 1));
0285 }
0286 }
0287 }
0288
0289 int regions[3]{1, 0, 2};
0290
0291 double rotationEven[3]{-999, -999, -999};
0292 double rotationOdd[3]{-999, -999, -999};
0293
0294 for (int region : regions)
0295 {
0296 TF1* fEven = new TF1(
0297 "fEven", [&](double* x, double* p)
0298 { return p[0] * evenTruthHist[region]->GetBinContent(evenTruthHist[region]->FindBin((x[0] - p[1]) > M_PI ? x[0] - p[1] - 2 * M_PI : x[0] - p[1])); },
0299 -M_PI, M_PI, 2);
0300 fEven->SetParNames("A", "shift");
0301 fEven->SetParameters(1.0, 0.0);
0302 fEven->SetParLimits(1, -M_PI / 18, M_PI / 18);
0303 fEven->SetNpx(1000);
0304
0305 TF1* fOdd = new TF1(
0306 "fOdd", [&](double* x, double* p)
0307 { return p[0] * oddTruthHist[region]->GetBinContent(oddTruthHist[region]->FindBin((x[0] - p[1]) > M_PI ? x[0] - p[1] - 2 * M_PI : x[0] - p[1])); },
0308 -M_PI, M_PI, 2);
0309 fOdd->SetParNames("A", "shift");
0310 fOdd->SetParameters(1.0, 0.0);
0311 fOdd->SetParLimits(1, -M_PI / 18, M_PI / 18);
0312 fOdd->SetNpx(1000);
0313
0314 if (region != 1)
0315 {
0316 if (rotationEven[1] != -999)
0317 {
0318 fEven->SetParameter(1, rotationEven[1]);
0319 }
0320
0321 if (rotationOdd[1] != -999)
0322 {
0323 fOdd->SetParameter(1, rotationOdd[1]);
0324 }
0325 }
0326
0327 evenHist[region]->Fit("fEven", "IQ");
0328 oddHist[region]->Fit("fOdd", "IQ");
0329
0330 rotationEven[region] = fEven->GetParameter(1);
0331 rotationOdd[region] = fOdd->GetParameter(1);
0332
0333 m_recoRotation[side][region] = (rotationOdd[region] + rotationEven[region]) / 2.0;
0334 }
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571 }
0572
0573 std::vector<int> TpcCentralMembraneMatching::doGlobalRMatching(TH2* r_phi, bool side)
0574 {
0575 TH1D* proj = r_phi->ProjectionY("R_proj");
0576
0577 if (side)
0578 {
0579 m_m[1] = 0.0;
0580 m_b[1] = 0.0;
0581 }
0582 else
0583 {
0584 m_m[0] = 0.0;
0585 m_b[0] = 0.0;
0586 }
0587
0588 std::vector<double> rPeaks;
0589 std::vector<double> rHeights;
0590 std::vector<double> finalRPeaks;
0591 std::vector<double> finalRHeights;
0592 std::vector<std::vector<int>> groupR;
0593
0594 proj->GetXaxis()->SetRangeUser(0, 41);
0595 double maxR1 = proj->GetMaximum();
0596
0597 proj->GetXaxis()->SetRangeUser(41, 58);
0598 double maxR2 = proj->GetMaximum();
0599
0600 proj->GetXaxis()->SetRangeUser(58, 100);
0601 double maxR3 = proj->GetMaximum();
0602
0603 proj->GetXaxis()->SetRange(0, 0);
0604
0605 std::vector<int> hitMatches;
0606
0607 for (int i = 2; i < proj->GetNbinsX(); i++)
0608 {
0609
0610 if ((proj->GetBinCenter(i) < 41.0 && proj->GetBinContent(i) > 0.15 * maxR1) || (proj->GetBinCenter(i) >= 41.0 && proj->GetBinCenter(i) < 58.0 && proj->GetBinContent(i) > 0.15 * maxR2) || (proj->GetBinCenter(i) >= 58.0 && proj->GetBinContent(i) > 0.15 * maxR3))
0611 {
0612 rPeaks.push_back(proj->GetBinCenter(i));
0613 rHeights.push_back(proj->GetBinContent(i));
0614 }
0615 }
0616
0617 if (rPeaks.size() < 5)
0618 {
0619 if (side)
0620 {
0621 m_reco_RPeaks[1].clear();
0622 }
0623 else
0624 {
0625 m_reco_RPeaks[0].clear();
0626 }
0627
0628 if (Verbosity())
0629 {
0630 std::cout << (side ? "side 1" : "side 0") << " has fewer than 5 radial peaks (only has " << rPeaks.size() << "). Returning empty vectors" << std::endl;
0631 }
0632 return hitMatches;
0633 }
0634
0635 double threshold = 0.75;
0636
0637 for (int i = 0; i < (int) rPeaks.size(); i++)
0638 {
0639 std::vector<int> tmpR;
0640 tmpR.push_back(i);
0641
0642 bool closePeak = false;
0643 int currentPeak = -1;
0644
0645 if (rPeaks[i] > 41.0)
0646 {
0647 threshold = 1.0;
0648 }
0649
0650 for (int j = 0; j < (int) finalRPeaks.size(); j++)
0651 {
0652 for (int k = 0; k < (int) groupR[j].size(); k++)
0653 {
0654 if (fabs(rPeaks[i] - rPeaks[groupR[j][k]]) <= threshold || fabs(rPeaks[i] - finalRPeaks[j]) <= threshold)
0655 {
0656 closePeak = true;
0657 currentPeak = j;
0658 break;
0659 }
0660 }
0661 if (closePeak)
0662 {
0663 break;
0664 }
0665 }
0666
0667 if (!closePeak)
0668 {
0669 finalRPeaks.push_back(rPeaks[i]);
0670 finalRHeights.push_back(rHeights[i]);
0671 groupR.push_back(tmpR);
0672 tmpR.clear();
0673 continue;
0674 }
0675
0676 groupR[currentPeak].push_back(i);
0677 double num = 0.0;
0678 double den = 0.0;
0679 for (int j : groupR[currentPeak])
0680 {
0681 double rHeight = proj->GetBinContent(proj->FindBin(rPeaks[j]));
0682 num += rPeaks[j] * rHeight;
0683 den += rHeight;
0684 }
0685
0686 finalRPeaks[currentPeak] = num / den;
0687 finalRHeights[currentPeak] = den;
0688 }
0689
0690 if (side)
0691 {
0692 m_reco_RPeaks[1].clear();
0693
0694 for (double& finalRPeak : finalRPeaks)
0695 {
0696 m_reco_RPeaks[1].push_back(finalRPeak);
0697 }
0698 }
0699 else
0700 {
0701 m_reco_RPeaks[0].clear();
0702
0703 for (double& finalRPeak : finalRPeaks)
0704 {
0705 m_reco_RPeaks[0].push_back(finalRPeak);
0706 }
0707 }
0708
0709 if (Verbosity())
0710 {
0711 std::cout << "finalRPeaks: {";
0712 for (int i = 0; i < (int) finalRPeaks.size() - 1; i++)
0713 {
0714 std::cout << finalRPeaks[i] << ", ";
0715 }
0716 std::cout << finalRPeaks[finalRPeaks.size() - 1] << "}" << std::endl;
0717
0718 if (side)
0719 {
0720 std::cout << "m_reco_RPeaks[1]: {";
0721 for (int i = 0; i < (int) m_reco_RPeaks[1].size() - 1; i++)
0722 {
0723 std::cout << m_reco_RPeaks[1][i] << ", ";
0724 }
0725 std::cout << m_reco_RPeaks[1][m_reco_RPeaks[1].size() - 1] << "}" << std::endl;
0726 }
0727 else
0728 {
0729 std::cout << "m_reco_RPeaks[0]: {";
0730 for (int i = 0; i < (int) m_reco_RPeaks[0].size() - 1; i++)
0731 {
0732 std::cout << m_reco_RPeaks[0][i] << ", ";
0733 }
0734 std::cout << m_reco_RPeaks[0][m_reco_RPeaks[0].size() - 1] << "}" << std::endl;
0735 }
0736
0737 std::cout << "rHeights: {";
0738 for (int i = 0; i < (int) finalRHeights.size() - 1; i++)
0739 {
0740 std::cout << finalRHeights[i] << ", ";
0741 }
0742 std::cout << finalRHeights[finalRHeights.size() - 1] << "}" << std::endl;
0743 }
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770 double first_NN = 100000000.0;
0771 int first_match = -1;
0772 for (int i = 0; i < (int) m_truth_RPeaks.size(); i++)
0773 {
0774 if (fabs(finalRPeaks[0] - m_truth_RPeaks[i]) < first_NN)
0775 {
0776 first_NN = fabs(finalRPeaks[0] - m_truth_RPeaks[i]);
0777 first_match = i;
0778 }
0779 }
0780
0781 double last_NN = 100000000.0;
0782 int last_match = -1;
0783 for (int i = 0; i < (int) m_truth_RPeaks.size(); i++)
0784 {
0785 if (fabs(finalRPeaks[finalRPeaks.size() - 1] - m_truth_RPeaks[i]) < last_NN)
0786 {
0787 last_NN = fabs(finalRPeaks[finalRPeaks.size() - 1] - m_truth_RPeaks[i]);
0788 last_match = i;
0789 }
0790 }
0791
0792 double bestSum = 100000000.0;
0793 int match_i = 0;
0794 int match_j = 0;
0795
0796 int minI = -3;
0797 if (first_match + minI < 0)
0798 {
0799 minI = -first_match;
0800 }
0801
0802 int maxJ = 3;
0803 if (last_match + maxJ >= (int) m_truth_RPeaks.size())
0804 {
0805 maxJ = ((int) m_truth_RPeaks.size()) - 1 - last_match;
0806 }
0807
0808 std::vector<std::vector<double>> matches(3 - minI + 1, std::vector<double>(maxJ + 3 + 1, -999.0));
0809 std::vector<std::vector<std::vector<int>>> NNMatches(3 - minI + 1, std::vector<std::vector<int>>(maxJ + 3 + 1, std::vector<int>(finalRPeaks.size(), -1)));
0810
0811 for (int i = minI; i <= 3; i++)
0812 {
0813 for (int j = -3; j <= maxJ; j++)
0814 {
0815 bool goodPair = true;
0816
0817 if (m_fixShifts)
0818 {
0819 if (m_fieldOn)
0820 {
0821 if (i != -1 || j != -1)
0822 {
0823 goodPair = false;
0824 }
0825 }
0826
0827 if (!m_fieldOn)
0828 {
0829 if (i != 0 || j != 0)
0830 {
0831 goodPair = false;
0832 }
0833 }
0834 }
0835
0836 if (!goodPair)
0837 {
0838 continue;
0839 }
0840
0841 double sum = 0.0;
0842 double m = (m_truth_RPeaks[last_match + j] - m_truth_RPeaks[first_match + i]) / (finalRPeaks[finalRPeaks.size() - 1] - finalRPeaks[0]);
0843 double b = ((m_truth_RPeaks[first_match + i] * finalRPeaks[finalRPeaks.size() - 1]) - (m_truth_RPeaks[last_match + j] * finalRPeaks[0])) / (finalRPeaks[finalRPeaks.size() - 1] - finalRPeaks[0]);
0844
0845 int recoIndex = 0;
0846 for (double finalRPeak : finalRPeaks)
0847 {
0848 int minMatch = 0;
0849 double minResidual = 1000000000.0;
0850 for (int k = 0; k < (int) m_truth_RPeaks.size(); k++)
0851 {
0852 double residual = fabs((m * finalRPeak + b) - m_truth_RPeaks[k]);
0853 if (residual < minResidual)
0854 {
0855 minResidual = residual;
0856 minMatch = k;
0857 if (minResidual < 0.5)
0858 {
0859 break;
0860 }
0861 }
0862 }
0863 sum += fabs((m * finalRPeak + b) - m_truth_RPeaks[minMatch]);
0864
0865 NNMatches[i - minI][j + 3][recoIndex] = minMatch;
0866 recoIndex++;
0867 }
0868
0869
0870 matches[i - minI][j + 3] = sum;
0871 if (m_savehistograms)
0872 {
0873 if (side)
0874 {
0875 m_matchResiduals[1]->Fill(i, j, sum);
0876 }
0877 else
0878 {
0879 m_matchResiduals[0]->Fill(i, j, sum);
0880 }
0881 }
0882 if (sum < bestSum)
0883 {
0884 bestSum = sum;
0885 match_i = i - minI;
0886 match_j = j + 3;
0887 }
0888 }
0889 }
0890
0891 if (Verbosity())
0892 {
0893 std::cout << "best total residual = " << bestSum << " at i " << match_i + minI << " j " << match_j - 3 << std::endl;
0894 for (int i = 0; i < (int) matches.size(); i++)
0895 {
0896 for (int j = 0; j < (int) matches[i].size(); j++)
0897 {
0898 if (matches[i][j] == -999.0)
0899 {
0900 continue;
0901 }
0902 std::cout << "total Residual match i=" << i + minI << " j=" << j - 3 << " : " << matches[i][j] << std::endl;
0903 }
0904 }
0905 }
0906
0907 for (int& i : NNMatches[match_i][match_j])
0908 {
0909 hitMatches.push_back(i);
0910 }
0911
0912 if (Verbosity())
0913 {
0914 for (int i = 0; i < (int) NNMatches.size(); i++)
0915 {
0916 for (int j = 0; j < (int) NNMatches[i].size(); j++)
0917 {
0918 if (matches[i][j] == -999.0)
0919 {
0920 continue;
0921 }
0922 double m = (m_truth_RPeaks[last_match + j - 3] - m_truth_RPeaks[first_match + i + minI]) / (finalRPeaks[finalRPeaks.size() - 1] - finalRPeaks[0]);
0923 double b = ((m_truth_RPeaks[first_match + i + minI] * finalRPeaks[finalRPeaks.size() - 1]) - (m_truth_RPeaks[last_match + j - 3] * finalRPeaks[0])) / (finalRPeaks[finalRPeaks.size() - 1] - finalRPeaks[0]);
0924 for (int k = 0; k < (int) NNMatches[i][j].size(); k++)
0925 {
0926 std::cout << "i " << i + minI << " j " << j - 3 << " Reco index " << k << " recoR=" << finalRPeaks[k] << " shifted R=" << (m * finalRPeaks[k] + b) << " matchIndex=" << NNMatches[i][j][k] << " truth R=" << m_truth_RPeaks[NNMatches[i][j][k]] << " residual=" << (m * finalRPeaks[k] + b) - m_truth_RPeaks[NNMatches[i][j][k]] << std::endl;
0927 }
0928 }
0929 }
0930 }
0931
0932 double final_m = (m_truth_RPeaks[last_match + match_j - 3] - m_truth_RPeaks[first_match + match_i + minI]) / (finalRPeaks[finalRPeaks.size() - 1] - finalRPeaks[0]);
0933 double final_b = ((m_truth_RPeaks[first_match + match_i + minI] * finalRPeaks[finalRPeaks.size() - 1]) - (m_truth_RPeaks[last_match + match_j - 3] * finalRPeaks[0])) / (finalRPeaks[finalRPeaks.size() - 1] - finalRPeaks[0]);
0934
0935 if (side)
0936 {
0937 m_m[1] = final_m;
0938 m_b[1] = final_b;
0939 m_matchLow[1] = match_i + minI;
0940 m_matchHigh[1] = match_j - 3;
0941 }
0942 else
0943 {
0944 m_m[0] = final_m;
0945 m_b[0] = final_b;
0946 m_matchLow[0] = match_i + minI;
0947 m_matchHigh[0] = match_j - 3;
0948 }
0949
0950 return hitMatches;
0951 }
0952
0953 int TpcCentralMembraneMatching::getClusterRMatch(double clusterR, int side)
0954 {
0955 double closestDist = 100.;
0956 int closestPeak = -1;
0957
0958
0959 for (int j = 0; j < (int) m_reco_RPeaks[side].size(); j++)
0960 {
0961 if (std::abs(clusterR - m_reco_RPeaks[side][j]) < closestDist)
0962 {
0963 closestDist = std::abs(clusterR - m_reco_RPeaks[side][j]);
0964 closestPeak = j;
0965 }
0966 }
0967
0968
0969 if (closestPeak != -1)
0970 {
0971 return m_reco_RMatches[side][closestPeak];
0972 }
0973
0974 return -1;
0975 }
0976
0977
0978 int TpcCentralMembraneMatching::InitRun(PHCompositeNode* topNode)
0979 {
0980 if (!m_fieldOn)
0981 {
0982 m_useHeader = false;
0983 }
0984
0985 if (m_savehistograms)
0986 {
0987 static constexpr float max_dr = 5.0;
0988 static constexpr float max_dphi = 0.05;
0989
0990 fout = new TFile(m_histogramfilename.c_str(), "RECREATE");
0991
0992 hxy_reco = new TH2F("hxy_reco", "reco cluster x:y", 800, -100, 100, 800, -80, 80);
0993 hxy_truth = new TH2F("hxy_truth", "truth cluster x:y", 800, -100, 100, 800, -80, 80);
0994
0995 hdrdphi = new TH2F("hdrdphi", "dr vs dphi", 800, -max_dr, max_dr, 800, -max_dphi, max_dphi);
0996 hdrdphi->GetXaxis()->SetTitle("dr");
0997 hdrdphi->GetYaxis()->SetTitle("dphi");
0998
0999 hrdr = new TH2F("hrdr", "dr vs r", 800, 0.0, 80.0, 800, -max_dr, max_dr);
1000 hrdr->GetXaxis()->SetTitle("r");
1001 hrdr->GetYaxis()->SetTitle("dr");
1002
1003 hrdphi = new TH2F("hrdphi", "dphi vs r", 800, 0.0, 80.0, 800, -max_dphi, max_dphi);
1004 hrdphi->GetXaxis()->SetTitle("r");
1005 hrdphi->GetYaxis()->SetTitle("dphi");
1006
1007 hdphi = new TH1F("hdphi", "dph", 800, -max_dphi, max_dphi);
1008 hdphi->GetXaxis()->SetTitle("dphi");
1009
1010 hdr1_single = new TH1F("hdr1_single", "innner dr single", 200, -max_dr, max_dr);
1011 hdr2_single = new TH1F("hdr2_single", "mid dr single", 200, -max_dr, max_dr);
1012 hdr3_single = new TH1F("hdr3_single", "outer dr single", 200, -max_dr, max_dr);
1013 hdr1_double = new TH1F("hdr1_double", "innner dr double", 200, -max_dr, max_dr);
1014 hdr2_double = new TH1F("hdr2_double", "mid dr double", 200, -max_dr, max_dr);
1015 hdr3_double = new TH1F("hdr3_double", "outer dr double", 200, -max_dr, max_dr);
1016 hdrphi = new TH1F("hdrphi", "r * dphi", 200, -0.05, 0.05);
1017 hnclus = new TH1F("hnclus", " nclusters ", 3, 0., 3.);
1018
1019 m_debugfile = new TFile(m_debugfilename.c_str(), "RECREATE");
1020
1021 match_tree = new TTree("match_tree", "Match TTree");
1022 event_tree = new TTree("event_tree", "Event Tree");
1023
1024 match_tree->Branch("event", &m_event_index);
1025 match_tree->Branch("matched", &m_matched);
1026 match_tree->Branch("truthIndex", &m_truthIndex);
1027 match_tree->Branch("truthR", &m_truthR);
1028 match_tree->Branch("truthPhi", &m_truthPhi);
1029 match_tree->Branch("recoR", &m_recoR);
1030 match_tree->Branch("recoPhi", &m_recoPhi);
1031 match_tree->Branch("recoZ", &m_recoZ);
1032 match_tree->Branch("rawR", &m_rawR);
1033 match_tree->Branch("rawPhi", &m_rawPhi);
1034 match_tree->Branch("staticR", &m_staticR);
1035 match_tree->Branch("staticPhi", &m_staticPhi);
1036 match_tree->Branch("fitMode", &m_fitMode);
1037 match_tree->Branch("isSaturated", &m_isSaturated);
1038 match_tree->Branch("side", &m_side);
1039 match_tree->Branch("adc", &m_adc);
1040 match_tree->Branch("nhits", &m_nhits);
1041 match_tree->Branch("nLayers", &m_nLayers);
1042 match_tree->Branch("nIPhi", &m_nIPhi);
1043 match_tree->Branch("nIT", &m_nIT);
1044 match_tree->Branch("layerSD", &m_layersSD);
1045 match_tree->Branch("IPhiSD", &m_IPhiSD);
1046 match_tree->Branch("ITSD", &m_ITSD);
1047 match_tree->Branch("layerWeightedSD", &m_layersWeightedSD);
1048 match_tree->Branch("IPhiWeightedSD", &m_IPhiWeightedSD);
1049 match_tree->Branch("ITWeightedSD", &m_ITWeightedSD);
1050 match_tree->Branch("lowShift", &m_lowShift);
1051 match_tree->Branch("highShift", &m_highShift);
1052 match_tree->Branch("phiRotation", &m_phiRotation);
1053 match_tree->Branch("distanceToTruth", &m_distanceToTruth);
1054 match_tree->Branch("NNDistance", &m_NNDistance);
1055 match_tree->Branch("NNR", &m_NNR);
1056 match_tree->Branch("NNPhi", &m_NNPhi);
1057 match_tree->Branch("NNIndex", &m_NNIndex);
1058
1059 event_tree->Branch("event", &m_event_index);
1060 event_tree->Branch("matched", &e_matched);
1061 event_tree->Branch("truthIndex", &e_truthIndex);
1062 event_tree->Branch("truthR", &e_truthR);
1063 event_tree->Branch("truthPhi", &e_truthPhi);
1064 event_tree->Branch("recoR", &e_recoR);
1065 event_tree->Branch("recoPhi", &e_recoPhi);
1066 event_tree->Branch("side", &e_side);
1067 event_tree->Branch("isSaturated", &e_isSaturated);
1068 event_tree->Branch("fitMode", &e_fitMode);
1069 event_tree->Branch("NNindex", &e_NNIndex);
1070 event_tree->Branch("NNR", &e_NNR);
1071 event_tree->Branch("NNPhi", &e_NNPhi);
1072 event_tree->Branch("NNDistance", &e_NNDistance);
1073 event_tree->Branch("adc", &e_adc);
1074
1075
1076 m_matchResiduals[0] = new TH2F("matchResiduals_0", "Matching Residuals TPC South;Shift of smallest R from NN match;Shift of largest R from NN match", 7, -3.5, 3.5, 7, -3.5, 3.5);
1077 m_matchResiduals[1] = new TH2F("matchResiduals_1", "Matching Residuals TPC North;Shift of smallest R from NN match;Shift of largest R from NN match", 7, -3.5, 3.5, 7, -3.5, 3.5);
1078 }
1079
1080 truth_r_phi[0] = new TH2F("truth_r_phi_0", "truth r vs #phi side 0;#phi (rad); r (cm)", 360, -M_PI, M_PI, 500, 0, 100);
1081 truth_r_phi[1] = new TH2F("truth_r_phi_1", "truth r vs #phi side 1;#phi (rad); r (cm)", 360, -M_PI, M_PI, 500, 0, 100);
1082
1083 reco_r_phi[0] = new TH2F("reco_r_phi_0", "reco R vs #phi side 0;#phi (rad); r (cm)", 360, -M_PI, M_PI, 350, 20, 90);
1084 reco_r_phi[1] = new TH2F("reco_r_phi_1", "reco R vs #phi side 1;#phi (rad); r (cm)", 360, -M_PI, M_PI, 350, 20, 90);
1085
1086
1087
1088
1089 const double phi_petal = M_PI / 9.0;
1090
1091
1092
1093
1094
1095
1096
1097 auto save_truth_position = [&](TVector3 source)
1098 {
1099 source.SetZ(-1);
1100 source.RotateZ(-M_PI / 18);
1101 m_truth_pos.push_back(source);
1102 truth_r_phi[0]->Fill(source.Phi(), source.Perp());
1103
1104 source.SetZ(+1);
1105 source.RotateZ(M_PI / 18);
1106 source.SetX(-1 * source.X());
1107 m_truth_pos.push_back(source);
1108 truth_r_phi[1]->Fill(source.Phi(), source.Perp());
1109 };
1110
1111
1112 for (int j = 0; j < nRadii; ++j)
1113 {
1114 for (int i = 0; i < nGoodStripes_R1_e[j]; ++i)
1115 {
1116 for (int k = 0; k < 18; ++k)
1117 {
1118 TVector3 dummyPos(cx1_e[i][j], cy1_e[i][j], 0.0);
1119 dummyPos.RotateZ(k * phi_petal);
1120 save_truth_position(dummyPos);
1121
1122
1123 int truth_index_1;
1124 int truth_index_0;
1125 if (k <= 8)
1126 {
1127 truth_index_0 = (26 - k) * 10000 + j * 100 + (nGoodStripes_R1_e[j] - i - 1);
1128 truth_index_1 = (8 - k) * 10000 + j * 100 + (nGoodStripes_R1_e[j] - i - 1);
1129 }
1130 else
1131 {
1132 truth_index_0 = (44 - k) * 10000 + j * 100 + (nGoodStripes_R1_e[j] - i - 1);
1133 truth_index_1 = (26 - k) * 10000 + j * 100 + (nGoodStripes_R1_e[j] - i - 1);
1134 }
1135 m_truth_index.push_back(truth_index_0);
1136 m_truth_index.push_back(truth_index_1);
1137
1138 if (Verbosity() > 2)
1139 {
1140 std::cout << " i " << i << " j " << j << " k " << k << " x1 " << dummyPos.X() << " y1 " << dummyPos.Y()
1141 << " theta " << std::atan2(dummyPos.Y(), dummyPos.X())
1142 << " radius " << get_r(dummyPos.X(), dummyPos.y()) << std::endl;
1143 }
1144 if (m_savehistograms)
1145 {
1146 hxy_truth->Fill(dummyPos.X(), dummyPos.Y());
1147 }
1148 }
1149 }
1150 }
1151
1152
1153 for (int j = 0; j < nRadii; ++j)
1154 {
1155 for (int i = 0; i < nGoodStripes_R1[j]; ++i)
1156 {
1157 for (int k = 0; k < 18; ++k)
1158 {
1159 TVector3 dummyPos(cx1[i][j], cy1[i][j], 0.0);
1160 dummyPos.RotateZ(k * phi_petal);
1161 save_truth_position(dummyPos);
1162
1163
1164 int truth_index_1;
1165 int truth_index_0;
1166 if (k <= 8)
1167 {
1168 truth_index_0 = (26 - k) * 10000 + (j + 8) * 100 + (nGoodStripes_R1[j] - i - 1);
1169 truth_index_1 = (8 - k) * 10000 + (j + 8) * 100 + (nGoodStripes_R1[j] - i - 1);
1170 }
1171 else
1172 {
1173 truth_index_0 = (44 - k) * 10000 + (j + 8) * 100 + (nGoodStripes_R1[j] - i - 1);
1174 truth_index_1 = (26 - k) * 10000 + (j + 8) * 100 + (nGoodStripes_R1[j] - i - 1);
1175 }
1176 m_truth_index.push_back(truth_index_0);
1177 m_truth_index.push_back(truth_index_1);
1178
1179 if (Verbosity() > 2)
1180 {
1181 std::cout << " i " << i << " j " << j << " k " << k << " x1 " << dummyPos.X() << " y1 " << dummyPos.Y()
1182 << " theta " << std::atan2(dummyPos.Y(), dummyPos.X())
1183 << " radius " << get_r(dummyPos.X(), dummyPos.y()) << std::endl;
1184 }
1185 if (m_savehistograms)
1186 {
1187 hxy_truth->Fill(dummyPos.X(), dummyPos.Y());
1188 }
1189 }
1190 }
1191 }
1192
1193 for (int j = 0; j < nRadii; ++j)
1194 {
1195 for (int i = 0; i < nGoodStripes_R2[j]; ++i)
1196 {
1197 for (int k = 0; k < 18; ++k)
1198 {
1199 TVector3 dummyPos(cx2[i][j], cy2[i][j], 0.0);
1200 dummyPos.RotateZ(k * phi_petal);
1201 save_truth_position(dummyPos);
1202
1203
1204 int truth_index_1;
1205 int truth_index_0;
1206 if (k <= 8)
1207 {
1208 truth_index_0 = (26 - k) * 10000 + (j + 16) * 100 + (nGoodStripes_R2[j] - i - 1);
1209 truth_index_1 = (8 - k) * 10000 + (j + 16) * 100 + (nGoodStripes_R2[j] - i - 1);
1210 }
1211 else
1212 {
1213 truth_index_0 = (44 - k) * 10000 + (j + 16) * 100 + (nGoodStripes_R2[j] - i - 1);
1214 truth_index_1 = (26 - k) * 10000 + (j + 16) * 100 + (nGoodStripes_R2[j] - i - 1);
1215 }
1216 m_truth_index.push_back(truth_index_0);
1217 m_truth_index.push_back(truth_index_1);
1218
1219 if (Verbosity() > 2)
1220 {
1221 std::cout << " i " << i << " j " << j << " k " << k << " x1 " << dummyPos.X() << " y1 " << dummyPos.Y()
1222 << " theta " << std::atan2(dummyPos.Y(), dummyPos.X())
1223 << " radius " << get_r(dummyPos.X(), dummyPos.y()) << std::endl;
1224 }
1225 if (m_savehistograms)
1226 {
1227 hxy_truth->Fill(dummyPos.X(), dummyPos.Y());
1228 }
1229 }
1230 }
1231 }
1232
1233 for (int j = 0; j < nRadii; ++j)
1234 {
1235 for (int i = 0; i < nGoodStripes_R3[j]; ++i)
1236 {
1237 for (int k = 0; k < 18; ++k)
1238 {
1239 TVector3 dummyPos(cx3[i][j], cy3[i][j], 0.0);
1240 dummyPos.RotateZ(k * phi_petal);
1241 save_truth_position(dummyPos);
1242
1243
1244 int truth_index_1;
1245 int truth_index_0;
1246 if (k <= 8)
1247 {
1248 truth_index_0 = (26 - k) * 10000 + (j + 24) * 100 + (nGoodStripes_R3[j] - i - 1);
1249 truth_index_1 = (8 - k) * 10000 + (j + 24) * 100 + (nGoodStripes_R3[j] - i - 1);
1250 }
1251 else
1252 {
1253 truth_index_0 = (44 - k) * 10000 + (j + 24) * 100 + (nGoodStripes_R3[j] - i - 1);
1254 truth_index_1 = (26 - k) * 10000 + (j + 24) * 100 + (nGoodStripes_R3[j] - i - 1);
1255 }
1256 m_truth_index.push_back(truth_index_0);
1257 m_truth_index.push_back(truth_index_1);
1258
1259 if (Verbosity() > 2)
1260 {
1261 std::cout << " i " << i << " j " << j << " k " << k << " x1 " << dummyPos.X() << " y1 " << dummyPos.Y()
1262 << " theta " << std::atan2(dummyPos.Y(), dummyPos.X())
1263 << " radius " << get_r(dummyPos.X(), dummyPos.y()) << std::endl;
1264 }
1265 if (m_savehistograms)
1266 {
1267 hxy_truth->Fill(dummyPos.X(), dummyPos.Y());
1268 }
1269 }
1270 }
1271 }
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330 for (int s = 0; s < 2; s++)
1331 {
1332 gr_dR[s] = new TGraph2D();
1333 gr_dPhi[s] = new TGraph2D();
1334
1335 gr_points[s] = new TGraph();
1336 gr_points[s]->SetMarkerStyle(20);
1337 gr_points[s]->SetMarkerSize(0.5);
1338 gr_points[s]->SetMarkerColor(kBlack);
1339 }
1340
1341 int ret = GetNodes(topNode);
1342 return ret;
1343 }
1344
1345
1346 int TpcCentralMembraneMatching::process_event(PHCompositeNode* topNode)
1347 {
1348 e_matched.clear();
1349 e_truthIndex.clear();
1350 e_truthR.clear();
1351 e_truthPhi.clear();
1352 e_recoR.clear();
1353 e_recoPhi.clear();
1354 e_side.clear();
1355 e_isSaturated.clear();
1356 e_fitMode.clear();
1357 e_NNR.clear();
1358 e_NNPhi.clear();
1359 e_NNIndex.clear();
1360 e_adc.clear();
1361
1362 for (int s = 0; s < 2; s++)
1363 {
1364 gr_dR[s]->Clear();
1365 gr_dPhi[s]->Clear();
1366 }
1367
1368 std::vector<TVector3> reco_pos;
1369 std::vector<TVector3> static_pos;
1370 std::vector<TVector3> raw_pos;
1371 std::vector<bool> reco_side;
1372 std::vector<bool> fitMode;
1373 std::vector<bool> isSaturated;
1374 std::vector<unsigned int> reco_nhits;
1375 std::vector<unsigned int> reco_adc;
1376 std::vector<unsigned int> reco_nLayers;
1377 std::vector<unsigned int> reco_nIPhi;
1378 std::vector<unsigned int> reco_nIT;
1379 std::vector<float> reco_SDLayer;
1380 std::vector<float> reco_SDIPhi;
1381 std::vector<float> reco_SDIT;
1382 std::vector<float> reco_SDWeightedLayer;
1383 std::vector<float> reco_SDWeightedIPhi;
1384 std::vector<float> reco_SDWeightedIT;
1385
1386
1387
1388 eventHeader = findNode::getClass<EventHeader>(topNode, "EventHeader");
1389 if (!eventHeader)
1390 {
1391 std::cout << PHWHERE << " EventHeader Node missing, abort" << std::endl;
1392 return Fun4AllReturnCodes::ABORTRUN;
1393 }
1394
1395 if (m_useHeader && eventHeader->get_EvtSequence() == 0)
1396 {
1397 m_useHeader = false;
1398 }
1399
1400 if (m_useHeader)
1401 {
1402 m_event_index = eventHeader->get_EvtSequence();
1403 }
1404
1405 LaserEventInfo* lasereventinfo = findNode::getClass<LaserEventInfo>(topNode, "LaserEventInfo");
1406 if (!lasereventinfo)
1407 {
1408 std::cout << PHWHERE << " LaserEvetnInfo Node missing, abort" << std::endl;
1409 return Fun4AllReturnCodes::ABORTRUN;
1410 }
1411
1412 if ((eventHeader->get_RunNumber() > 66153 && !lasereventinfo->isGl1LaserEvent()) || (eventHeader->get_RunNumber() <= 66153 && !lasereventinfo->isLaserEvent()) || !m_corrected_CMcluster_map)
1413
1414 {
1415 if (!m_useHeader)
1416 {
1417 m_event_index++;
1418 }
1419 return Fun4AllReturnCodes::EVENT_OK;
1420 }
1421
1422 if (Verbosity())
1423 {
1424 std::cout << PHWHERE << " working on event " << m_event_index << " which has " << m_corrected_CMcluster_map->size() << " clusters" << std::endl;
1425 }
1426
1427
1428 for (const auto& harray : {m_dcc_out->m_hDRint, m_dcc_out->m_hDPint, m_dcc_out->m_hDZint, m_dcc_out->m_hentries})
1429 {
1430 for (const auto& h : harray)
1431 {
1432 h->Reset();
1433 }
1434 }
1435
1436 reco_r_phi[0]->Reset();
1437 reco_r_phi[1]->Reset();
1438
1439 int nClus_gtMin = 0;
1440 int clusterIndex = 0;
1441
1442
1443 auto clusrange = m_corrected_CMcluster_map->getClusters();
1444 for (auto cmitr = clusrange.first;
1445 cmitr != clusrange.second;
1446 ++cmitr)
1447 {
1448 const auto& [cmkey, cmclus_orig] = *cmitr;
1449
1450 LaserCluster* cmclus = cmclus_orig;
1451 const unsigned int nhits = cmclus->getNhits();
1452
1453 const unsigned int adc = cmclus->getAdc();
1454 bool side = (bool) TpcDefs::getSide(cmkey);
1455
1456
1457
1458
1459 nClus_gtMin++;
1460
1461
1462
1463
1464 Acts::Vector3 pos(cmclus->getX(), cmclus->getY(), (side ? 1.0 : -1.0));
1465 TVector3 tmp_raw(pos[0], pos[1], pos[2]);
1466 if (m_dcc_in_module_edge)
1467 {
1468 pos = m_distortionCorrection.get_corrected_position(pos, m_dcc_in_module_edge);
1469 }
1470 if (m_dcc_in_static)
1471 {
1472 pos = m_distortionCorrection.get_corrected_position(pos, m_dcc_in_static);
1473 }
1474 TVector3 tmp_static(pos[0], pos[1], pos[2]);
1475
1476 if (m_dcc_in_average)
1477 {
1478 pos = m_distortionCorrection.get_corrected_position(pos, m_dcc_in_average);
1479 }
1480 TVector3 tmp_pos(pos[0], pos[1], pos[2]);
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510 bool tmpIsSaturated = false;
1511 for (int h = 0; h < (int) cmclus->getNhits(); h++)
1512 {
1513 if (cmclus->getHitAdc(h) > 900)
1514 {
1515 tmpIsSaturated = true;
1516 break;
1517 }
1518 }
1519
1520 reco_pos.push_back(tmp_pos);
1521 static_pos.push_back(tmp_static);
1522 raw_pos.push_back(tmp_raw);
1523 reco_side.push_back(side);
1524 fitMode.push_back(cmclus->getFitMode());
1525 isSaturated.push_back(tmpIsSaturated);
1526 reco_nhits.push_back(nhits);
1527 reco_adc.push_back(adc);
1528 reco_nLayers.push_back(cmclus->getNLayers());
1529 reco_nIPhi.push_back(cmclus->getNIPhi());
1530 reco_nIT.push_back(cmclus->getNIT());
1531 reco_SDLayer.push_back(cmclus->getSDLayer());
1532 reco_SDIPhi.push_back(cmclus->getSDIPhi());
1533 reco_SDIT.push_back(cmclus->getSDIT());
1534 reco_SDWeightedLayer.push_back(cmclus->getSDWeightedLayer());
1535 reco_SDWeightedIPhi.push_back(cmclus->getSDWeightedIPhi());
1536 reco_SDWeightedIT.push_back(cmclus->getSDWeightedIT());
1537
1538 if (side == 0)
1539 {
1540 reco_r_phi[0]->Fill(tmp_pos.Phi(), tmp_pos.Perp());
1541 }
1542 else
1543 {
1544 reco_r_phi[1]->Fill(tmp_pos.Phi(), tmp_pos.Perp());
1545 }
1546
1547 if (Verbosity() > 2)
1548 {
1549 double raw_rad = std::sqrt(cmclus->getX() * cmclus->getX() + cmclus->getY() * cmclus->getY());
1550 double static_rad = sqrt(tmp_static.X() * tmp_static.X() + tmp_static.Y() * tmp_static.Y());
1551 double corr_rad = sqrt(tmp_pos.X() * tmp_pos.X() + tmp_pos.Y() * tmp_pos.Y());
1552 std::cout << "cluster " << clusterIndex << std::endl;
1553 clusterIndex++;
1554 std::cout << "found raw cluster " << cmkey << " side " << side << " with x " << cmclus->getX() << " y " << cmclus->getY() << " z " << cmclus->getZ() << " radius " << raw_rad << std::endl;
1555 std::cout << " --- static corrected positions: " << tmp_static.X() << " " << tmp_static.Y() << " " << tmp_static.Z() << " radius " << static_rad << std::endl;
1556 std::cout << " --- corrected positions: " << tmp_pos.X() << " " << tmp_pos.Y() << " " << tmp_pos.Z() << " radius " << corr_rad << std::endl;
1557 }
1558
1559 if (m_savehistograms)
1560 {
1561 hxy_reco->Fill(tmp_pos.X(), tmp_pos.Y());
1562 }
1563 }
1564
1565 if (nClus_gtMin < 25)
1566 {
1567 if (!m_useHeader)
1568 {
1569 m_event_index++;
1570 }
1571 return Fun4AllReturnCodes::EVENT_OK;
1572 }
1573
1574 int truth_index = 0;
1575 int nMatched = 0;
1576 std::vector<bool> truth_matched(m_truth_pos.size(), false);
1577 std::vector<bool> reco_matched(reco_pos.size(), false);
1578 std::vector<int> truth_matchedRecoIndex(m_truth_pos.size(), -1);
1579 std::vector<int> reco_matchedTruthIndex(reco_pos.size(), -1);
1580
1581 std::vector<float> reco_distToNN(reco_pos.size(), 10000.0);
1582 std::vector<float> NNDist(reco_pos.size(), 100000.0);
1583 std::vector<float> NNR(reco_pos.size(), 100000.0);
1584 std::vector<float> NNPhi(reco_pos.size(), 100000.0);
1585 std::vector<int> NNIndex(reco_pos.size(), -1);
1586
1587 std::vector<std::vector<int>> truth_NNRecoIndex(m_truth_pos.size(), std::vector<int>(0));
1588
1589 if (m_doFancy)
1590 {
1591
1592 m_recoRotation[0][1] = getPhiRotation_smoothed(truth_r_phi[0]->ProjectionX("hR2", 206, 290), reco_r_phi[0]->ProjectionX("cR2_0", 206, 290), false);
1593 m_recoRotation[0][0] = getPhiRotation_smoothed(truth_r_phi[0]->ProjectionX("hR1", 151, 206), reco_r_phi[0]->ProjectionX("cR1_0", 151, 206), false);
1594 m_recoRotation[0][2] = getPhiRotation_smoothed(truth_r_phi[0]->ProjectionX("hR3", 290, 499), reco_r_phi[0]->ProjectionX("cR3_0", 290, 499), false);
1595
1596 m_recoRotation[1][1] = getPhiRotation_smoothed(truth_r_phi[1]->ProjectionX("hR2", 206, 290), reco_r_phi[1]->ProjectionX("cR2_1", 206, 290), true);
1597 m_recoRotation[1][0] = getPhiRotation_smoothed(truth_r_phi[1]->ProjectionX("hR1", 151, 206), reco_r_phi[1]->ProjectionX("cR1_1", 151, 206), true);
1598 m_recoRotation[1][2] = getPhiRotation_smoothed(truth_r_phi[1]->ProjectionX("hR3", 290, 499), reco_r_phi[1]->ProjectionX("cR3_1", 290, 499), true);
1599
1600 m_reco_RMatches[0] = doGlobalRMatching(reco_r_phi[0], false);
1601 m_reco_RMatches[1] = doGlobalRMatching(reco_r_phi[1], true);
1602
1603 if (Verbosity() > 2)
1604 {
1605 for (int i = 0; i < (int) m_reco_RMatches[0].size(); i++)
1606 {
1607 std::cout << "side 0 cluster index " << i << " hit match " << m_reco_RMatches[0][i] << " recoPeak=" << m_reco_RPeaks[0][i] << " shifted recoPeak=" << (m_m[0] * m_reco_RPeaks[0][i] + m_b[0]) << " truthPeak=" << m_truth_RPeaks[m_reco_RMatches[0][i]] << " residual=" << m_truth_RPeaks[m_reco_RMatches[0][i]] - (m_m[0] * m_reco_RPeaks[0][i] + m_b[0]) << std::endl;
1608 }
1609
1610 for (int i = 0; i < (int) m_reco_RMatches[1].size(); i++)
1611 {
1612 std::cout << "side 1 cluster index " << i << " hit match " << m_reco_RMatches[1][i] << " recoPeak=" << m_reco_RPeaks[1][i] << " shifted recoPeak=" << (m_m[1] * m_reco_RPeaks[1][i] + m_b[1]) << " truthPeak=" << m_truth_RPeaks[m_reco_RMatches[1][i]] << " residual=" << m_truth_RPeaks[m_reco_RMatches[1][i]] - (m_m[1] * m_reco_RPeaks[1][i] + m_b[1]) << std::endl;
1613 }
1614 }
1615
1616 for (const auto& truth : m_truth_pos)
1617 {
1618 double tR = get_r(truth.X(), truth.Y());
1619 double tPhi = truth.Phi();
1620 double tZ = truth.Z();
1621
1622 int truthRIndex = -1;
1623
1624
1625 for (int k = 0; k < (int) m_truth_RPeaks.size(); k++)
1626 {
1627 if (std::abs(tR - m_truth_RPeaks[k]) < 0.5)
1628 {
1629 truthRIndex = k;
1630 break;
1631 }
1632 }
1633
1634 if (truthRIndex == -1)
1635 {
1636 truth_index++;
1637 continue;
1638 }
1639
1640 double prev_dphi = 10000.0;
1641
1642 int recoMatchIndex = -1;
1643 unsigned int reco_index = 0;
1644 for (const auto& reco : reco_pos)
1645 {
1646 if (reco_matched[reco_index] || reco_nhits[reco_index] < m_nHitsInCuster_minimum)
1647 {
1648 reco_index++;
1649 continue;
1650 }
1651
1652 double rR = get_r(reco.X(), reco.Y());
1653 double rPhi = reco.Phi();
1654 bool side = reco_side[reco_index];
1655
1656 int region = -1;
1657
1658 if (rR < 41)
1659 {
1660 region = 0;
1661 }
1662 else if (rR >= 41 && rR < 58)
1663 {
1664 region = 1;
1665 }
1666 else if (rR >= 58)
1667 {
1668 region = 2;
1669 }
1670
1671 if (region != -1)
1672 {
1673 if (side)
1674 {
1675 rPhi -= m_recoRotation[1][region];
1676 }
1677 else
1678 {
1679 rPhi -= m_recoRotation[0][region];
1680 }
1681 }
1682
1683 int clustRMatchIndex = -1;
1684 clustRMatchIndex = getClusterRMatch(rR, (side ? 1 : 0));
1685
1686 if (clustRMatchIndex == -1 || truthRIndex != clustRMatchIndex)
1687 {
1688 reco_index++;
1689 continue;
1690 }
1691
1692 if ((!side && tZ > 0) || (side && tZ < 0))
1693 {
1694 reco_index++;
1695 continue;
1696 }
1697
1698 auto dphi = delta_phi(tPhi - rPhi);
1699 if (fabs(dphi) > m_phi_cut)
1700 {
1701 reco_index++;
1702 continue;
1703 }
1704
1705 if (fabs(dphi) < fabs(prev_dphi))
1706 {
1707 prev_dphi = dphi;
1708 recoMatchIndex = reco_index;
1709 truth_matched[truth_index] = true;
1710 }
1711
1712 reco_index++;
1713 }
1714
1715 if (recoMatchIndex != -1)
1716 {
1717 truth_matchedRecoIndex[truth_index] = recoMatchIndex;
1718 reco_matched[recoMatchIndex] = true;
1719 reco_matchedTruthIndex[recoMatchIndex] = truth_index;
1720 nMatched++;
1721
1722 if (Verbosity() > 2)
1723 {
1724 std::cout << "truth " << truth_index << " matched to reco " << recoMatchIndex << " and there are now " << nMatched << " matches" << std::endl;
1725 std::cout << "tR=" << std::setw(10) << tR << " tPhi=" << std::setw(10) << tPhi << " tZ=" << std::setw(10) << tZ << std::endl;
1726 std::cout << "rR=" << std::setw(10) << get_r(reco_pos[recoMatchIndex].X(), reco_pos[recoMatchIndex].Y()) << " rPhi=" << std::setw(10) << reco_pos[recoMatchIndex].Phi() << " rZ=" << std::setw(10) << reco_pos[recoMatchIndex].Z() << " rSide=" << reco_side[recoMatchIndex] << " dPhi=" << prev_dphi << std::endl;
1727 }
1728 }
1729
1730 truth_index++;
1731 }
1732
1733
1734
1735 int recoIndex = 0;
1736 for (const auto& reco : reco_pos)
1737 {
1738 double rR = get_r(reco.X(), reco.Y());
1739 double rPhi = reco.Phi();
1740 bool side = reco_side[recoIndex];
1741
1742 int region = -1;
1743
1744 if (rR < 41)
1745 {
1746 region = 0;
1747 }
1748 else if (rR >= 41 && rR < 58)
1749 {
1750 region = 1;
1751 }
1752 else if (rR >= 58)
1753 {
1754 region = 2;
1755 }
1756
1757 if (region != -1)
1758 {
1759 if (side)
1760 {
1761 rPhi -= m_recoRotation[1][region];
1762 }
1763 else
1764 {
1765 rPhi -= m_recoRotation[0][region];
1766 }
1767 }
1768
1769 int clustRMatchIndex = -1;
1770 clustRMatchIndex = getClusterRMatch(rR, (side ? 1 : 0));
1771
1772 int truthMatchIndex = -1;
1773 truth_index = 0;
1774 for (const auto& truth : m_truth_pos)
1775 {
1776 double tR = get_r(truth.X(), truth.Y());
1777 double tPhi = truth.Phi();
1778 double tZ = truth.Z();
1779
1780 if ((!side && tZ > 0) || (side && tZ < 0))
1781 {
1782 truth_index++;
1783 continue;
1784 }
1785
1786 if (sqrt(pow(truth.X() - reco.X(), 2) + pow(truth.Y() - reco.Y(), 2)) < NNDist[recoIndex])
1787 {
1788 NNDist[recoIndex] = sqrt(pow(truth.X() - reco.X(), 2) + pow(truth.Y() - reco.Y(), 2));
1789 NNR[recoIndex] = tR;
1790 NNPhi[recoIndex] = tPhi;
1791 NNIndex[recoIndex] = m_truth_index[truth_index];
1792 }
1793
1794 if (clustRMatchIndex == -1)
1795 {
1796 continue;
1797 }
1798
1799 if (reco_matched[recoIndex])
1800 {
1801 if (reco_matchedTruthIndex[recoIndex] == truth_index)
1802 {
1803 reco_distToNN[recoIndex] = sqrt(pow(truth.X() - reco.X(), 2) + pow(truth.Y() - reco.Y(), 2));
1804 break;
1805 }
1806
1807 truth_index++;
1808 continue;
1809 }
1810
1811 int truthRIndex = -1;
1812
1813
1814 for (int k = 0; k < (int) m_truth_RPeaks.size(); k++)
1815 {
1816 if (std::abs(tR - m_truth_RPeaks[k]) < 0.5)
1817 {
1818 truthRIndex = k;
1819 break;
1820 }
1821 }
1822
1823 if (truthRIndex == -1 || truthRIndex != clustRMatchIndex)
1824 {
1825 truth_index++;
1826 continue;
1827 }
1828
1829 if ((!side && tZ > 0) || (side && tZ < 0))
1830 {
1831 truth_index++;
1832 continue;
1833 }
1834
1835 auto dphi = delta_phi(tPhi - rPhi);
1836 if (fabs(dphi) > m_phi_cut)
1837 {
1838 truth_index++;
1839 continue;
1840 }
1841
1842 float dist = sqrt(pow(tR * sin(tPhi) - rR * sin(rPhi), 2) + pow(tR * cos(tPhi) - rR * cos(rPhi), 2));
1843
1844 if (dist < reco_distToNN[recoIndex])
1845 {
1846 reco_distToNN[recoIndex] = dist;
1847 truthMatchIndex = truth_index;
1848 }
1849
1850 truth_index++;
1851
1852 }
1853
1854 if (!reco_matched[recoIndex])
1855 {
1856 reco_matchedTruthIndex[recoIndex] = truthMatchIndex;
1857 }
1858 recoIndex++;
1859 }
1860 }
1861 else
1862 {
1863 int reco_index = 0;
1864 for (const auto& reco : reco_pos)
1865 {
1866 double rR = get_r(reco.X(), reco.Y());
1867 double rPhi = reco.Phi();
1868 bool side = reco_side[reco_index];
1869
1870 truth_index = 0;
1871 double minNNDist = 100000.0;
1872 int match_localTruth = -1;
1873 for (const auto& truth : m_truth_pos)
1874 {
1875
1876 double tR = get_r(truth.X(), truth.Y());
1877 double tPhi = truth.Phi();
1878 double tZ = truth.Z();
1879
1880 if ((!side && tZ > 0) || (side && tZ < 0))
1881 {
1882 truth_index++;
1883 continue;
1884 }
1885
1886 auto dR = fabs(tR - rR);
1887 if (dR > 5.0)
1888 {
1889 truth_index++;
1890 continue;
1891 }
1892
1893 auto dphi = delta_phi(tPhi - rPhi);
1894 if (fabs(dphi) > 0.05)
1895 {
1896 truth_index++;
1897 continue;
1898 }
1899
1900 double dist = sqrt(pow(truth.X() - reco.X(), 2) + pow(truth.Y() - reco.Y(), 2));
1901 if (dist < minNNDist)
1902 {
1903 minNNDist = dist;
1904 match_localTruth = truth_index;
1905 }
1906 truth_index++;
1907 }
1908
1909 if (match_localTruth == -1)
1910 {
1911 reco_index++;
1912 continue;
1913 }
1914
1915 truth_NNRecoIndex[match_localTruth].push_back(reco_index);
1916 NNDist[reco_index] = sqrt(pow(m_truth_pos[match_localTruth].X() - reco.X(), 2) + pow(m_truth_pos[match_localTruth].Y() - reco.Y(), 2));
1917 NNR[reco_index] = get_r(m_truth_pos[match_localTruth].X(), m_truth_pos[match_localTruth].Y());
1918 NNPhi[reco_index] = m_truth_pos[match_localTruth].Phi();
1919 NNIndex[reco_index] = m_truth_index[match_localTruth];
1920
1921 reco_index++;
1922 }
1923
1924 truth_index = 0;
1925 for (const auto& truthIndex : truth_NNRecoIndex)
1926 {
1927 double maxADC = 0.0;
1928 int recoMatchIndex = -1;
1929
1930 int currentTruthIndex = m_truth_index[truth_index];
1931 int currentRow = (currentTruthIndex / 100) % 100;
1932
1933 if (currentRow == 15 || currentRow == 23 || currentRow == 31)
1934 {
1935 truth_index++;
1936 continue;
1937 }
1938
1939 for (const auto& recoIndex : truthIndex)
1940 {
1941
1942 if (reco_nLayers[recoIndex] != 2)
1943 {
1944 continue;
1945 }
1946
1947 int lowRMatch = 0;
1948 int highRMatch = (int) m_truth_RPeaks.size() - 1;
1949 int upperBound = (int) m_truth_RPeaks.size();
1950 while (lowRMatch <= highRMatch)
1951 {
1952 int mid = lowRMatch + (highRMatch - lowRMatch) / 2;
1953 if (m_truth_RPeaks[mid] >= reco_pos[recoIndex].Perp())
1954 {
1955 upperBound = mid;
1956 highRMatch = mid - 1;
1957 }
1958 else
1959 {
1960 lowRMatch = mid + 1;
1961 }
1962 }
1963 upperBound = std::max(upperBound, 1);
1964
1965 double dR = m_truth_pos[truth_index].Perp() - reco_pos[recoIndex].Perp();
1966 if (fabs(dR) > 0.5 * (m_truth_RPeaks[upperBound] - m_truth_RPeaks[upperBound - 1]))
1967 {
1968 continue;
1969 }
1970
1971 double dphi = delta_phi(m_truth_pos[truth_index].Phi() - reco_pos[recoIndex].Phi());
1972 if (fabs(dphi) > 0.5 * phiSpacing[upperBound - 1])
1973 {
1974 continue;
1975 }
1976
1977 if (reco_adc[recoIndex] > maxADC)
1978 {
1979 maxADC = reco_adc[recoIndex];
1980 recoMatchIndex = recoIndex;
1981 }
1982 }
1983
1984 if (recoMatchIndex >= 0)
1985 {
1986 truth_matchedRecoIndex[truth_index] = recoMatchIndex;
1987 reco_matched[recoMatchIndex] = true;
1988 reco_matchedTruthIndex[recoMatchIndex] = truth_index;
1989 truth_matched[truth_index] = true;
1990 nMatched++;
1991 }
1992
1993 truth_index++;
1994 }
1995 }
1996
1997
1998 if (Verbosity() > 1)
1999 {
2000 const auto n_valid_truth = std::count_if(m_truth_pos.begin(), m_truth_pos.end(), [](const TVector3& pos)
2001 { return get_r(pos.x(), pos.y()) > 30; });
2002 std::cout << "TpcCentralMembraneMatching::process_event - m_truth_pos size: " << m_truth_pos.size() << std::endl;
2003 std::cout << "TpcCentralMembraneMatching::process_event - m_truth_pos size, r>30cm: " << n_valid_truth << std::endl;
2004 std::cout << "TpcCentralMembraneMatching::process_event - reco_pos size: " << reco_pos.size() << std::endl;
2005 std::cout << "TpcCentralMembraneMatching::process_event - matched_pair size: " << nMatched << std::endl;
2006 }
2007
2008 if (m_savehistograms)
2009 {
2010 for (int i = 0; i < (int) reco_pos.size(); i++)
2011 {
2012 m_matched = reco_matched[i];
2013 m_truthR = m_truth_pos[reco_matchedTruthIndex[i]].Perp();
2014 m_truthPhi = m_truth_pos[reco_matchedTruthIndex[i]].Phi();
2015 m_distanceToTruth = sqrt(pow(m_truth_pos[reco_matchedTruthIndex[i]].Y() - reco_pos[i].Y(), 2) + pow(m_truth_pos[reco_matchedTruthIndex[i]].X() - reco_pos[i].X(), 2));
2016 m_truthIndex = m_truth_index[reco_matchedTruthIndex[i]];
2017 m_recoR = reco_pos[i].Perp();
2018 m_recoPhi = reco_pos[i].Phi();
2019 m_recoZ = reco_pos[i].Z();
2020 m_rawR = raw_pos[i].Perp();
2021 m_rawPhi = raw_pos[i].Phi();
2022 m_staticR = static_pos[i].Perp();
2023 m_staticPhi = static_pos[i].Phi();
2024 m_side = reco_side[i];
2025 m_fitMode = fitMode[i];
2026 m_isSaturated = isSaturated[i];
2027 m_adc = reco_adc[i];
2028 m_nhits = reco_nhits[i];
2029 m_nLayers = reco_nLayers[i];
2030 m_nIPhi = reco_nIPhi[i];
2031 m_nIT = reco_nIT[i];
2032 m_layersSD = reco_SDLayer[i];
2033 m_IPhiSD = reco_SDIPhi[i];
2034 m_ITSD = reco_SDIT[i];
2035 m_layersWeightedSD = reco_SDWeightedLayer[i];
2036 m_IPhiWeightedSD = reco_SDWeightedIPhi[i];
2037 m_ITWeightedSD = reco_SDWeightedIT[i];
2038
2039 e_matched.push_back(reco_matched[i]);
2040 e_truthIndex.push_back(m_truth_index[reco_matchedTruthIndex[i]]);
2041 e_truthR.push_back(m_truth_pos[reco_matchedTruthIndex[i]].Perp());
2042 e_truthPhi.push_back(m_truth_pos[reco_matchedTruthIndex[i]].Phi());
2043 e_recoR.push_back(reco_pos[i].Perp());
2044 e_recoPhi.push_back(reco_pos[i].Phi());
2045 e_side.push_back(reco_side[i]);
2046 e_isSaturated.push_back(isSaturated[i]);
2047 e_fitMode.push_back(fitMode[i]);
2048 e_NNR.push_back(NNR[i]);
2049 e_NNPhi.push_back(NNPhi[i]);
2050 e_NNIndex.push_back(NNIndex[i]);
2051 e_NNDistance.push_back(NNDist[i]);
2052 e_adc.push_back(reco_adc[i]);
2053
2054 if (m_side)
2055 {
2056 m_lowShift = m_matchLow[1];
2057 m_highShift = m_matchHigh[1];
2058 }
2059 else
2060 {
2061 m_lowShift = m_matchLow[0];
2062 m_highShift = m_matchHigh[0];
2063 }
2064
2065 int region = -1;
2066
2067 if (m_recoR < 41)
2068 {
2069 region = 0;
2070 }
2071 else if (m_recoR >= 41 && m_recoR < 58)
2072 {
2073 region = 1;
2074 }
2075 else if (m_recoR >= 58)
2076 {
2077 region = 2;
2078 }
2079
2080 if (region == -1)
2081 {
2082 m_phiRotation = -999.0;
2083 }
2084 else
2085 {
2086 m_phiRotation = m_recoRotation[m_side][region];
2087 }
2088
2089 m_NNDistance = NNDist[i];
2090 m_NNR = NNR[i];
2091 m_NNPhi = NNPhi[i];
2092 m_NNIndex = NNIndex[i];
2093
2094 match_tree->Fill();
2095 }
2096
2097 event_tree->Fill();
2098 }
2099
2100 unsigned int ckey = 0;
2101 for (unsigned int i = 0; i < m_truth_pos.size(); i++)
2102 {
2103 if (!truth_matched[i])
2104 {
2105 continue;
2106 }
2107
2108
2109
2110 int reco_index = truth_matchedRecoIndex[i];
2111
2112 if (reco_index == -1)
2113 {
2114 continue;
2115 }
2116
2117
2118
2119 auto* cmdiff = new CMFlashDifferencev1();
2120 cmdiff->setTruthPhi(m_truth_pos[i].Phi());
2121 cmdiff->setTruthR(m_truth_pos[i].Perp());
2122 cmdiff->setTruthZ(m_truth_pos[i].Z());
2123
2124 if (m_averageMode)
2125 {
2126 cmdiff->setRecoPhi(static_pos[reco_index].Phi());
2127 cmdiff->setRecoR(static_pos[reco_index].Perp());
2128 cmdiff->setRecoZ(static_pos[reco_index].Z());
2129 cmdiff->setNclusters(reco_nhits[reco_index]);
2130 }
2131 else
2132 {
2133 cmdiff->setRecoPhi(reco_pos[reco_index].Phi());
2134 cmdiff->setRecoR(reco_pos[reco_index].Perp());
2135 cmdiff->setRecoZ(reco_pos[reco_index].Z());
2136 cmdiff->setNclusters(reco_nhits[reco_index]);
2137 }
2138
2139 if (Verbosity() > 1)
2140 {
2141 std::cout << "adding cmdiff to container with key " << ckey << " in event " << m_event_index << std::endl;
2142 }
2143
2144 m_cm_flash_diffs->addDifferenceSpecifyKey(ckey, cmdiff);
2145
2146
2147 double clus_r = reco_pos[reco_index].Perp();
2148 double clus_phi = reco_pos[reco_index].Phi();
2149 double dr = reco_pos[reco_index].Perp() - m_truth_pos[i].Perp();
2150 double dphi = delta_phi(reco_pos[reco_index].Phi() - m_truth_pos[i].Phi());
2151 if (m_averageMode)
2152 {
2153 clus_r = static_pos[reco_index].Perp();
2154 clus_phi = static_pos[reco_index].Phi();
2155
2156 dr = static_pos[reco_index].Perp() - m_truth_pos[i].Perp();
2157 dphi = delta_phi(static_pos[reco_index].Phi() - m_truth_pos[i].Phi());
2158 }
2159 if (clus_phi < 0)
2160 {
2161 clus_phi += 2 * M_PI;
2162 }
2163
2164
2165 const bool side = reco_side[reco_index];
2166
2167
2168
2169
2170
2171
2172
2173 gr_dR[side]->AddPoint(clus_phi, clus_r, dr);
2174 gr_dPhi[side]->AddPoint(clus_phi, clus_r, dphi);
2175
2176 if (clus_phi < M_PI / 12)
2177 {
2178 gr_dR[side]->AddPoint(clus_phi + 2 * M_PI, clus_r, dr);
2179 gr_dPhi[side]->AddPoint(clus_phi + 2 * M_PI, clus_r, dphi);
2180 }
2181 if (clus_phi > 23 * M_PI / 12)
2182 {
2183 gr_dR[side]->AddPoint(clus_phi - 2 * M_PI, clus_r, dr);
2184 gr_dPhi[side]->AddPoint(clus_phi - 2 * M_PI, clus_r, dphi);
2185 }
2186
2187
2188
2189
2190
2191 deltaRByIndex[m_truth_index[i]] += dr;
2192 deltaPhiByIndex[m_truth_index[i]] += dphi;
2193 meanRByIndex[m_truth_index[i]] += clus_r;
2194 meanPhiByIndex[m_truth_index[i]] += clus_phi;
2195 nByIndex[m_truth_index[i]]++;
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222 ckey++;
2223 }
2224
2225
2226
2227 for (int s = 0; s < 2; s++)
2228 {
2229 bool firstGoodR = false;
2230 for (int j = 1; j <= m_dcc_out->m_hDRint[s]->GetNbinsY(); j++)
2231 {
2232 double RVal = m_dcc_out->m_hDRint[s]->GetYaxis()->GetBinCenter(j);
2233 double Rlow = m_dcc_out->m_hDRint[s]->GetYaxis()->GetBinLowEdge(j);
2234 double Rhigh = m_dcc_out->m_hDRint[s]->GetYaxis()->GetBinLowEdge(j + 1);
2235
2236 if (!firstGoodR)
2237 {
2238 for (int p = 0; p < gr_dR[s]->GetN(); p++)
2239 {
2240 if (gr_dR[s]->GetY()[p] > Rlow && gr_dR[s]->GetY()[p] > Rhigh)
2241 {
2242 firstGoodR = true;
2243 break;
2244 }
2245 }
2246 continue;
2247 }
2248
2249 for (int i = 2; i <= m_dcc_out->m_hDRint[s]->GetNbinsX() - 1; i++)
2250 {
2251 double phiVal = m_dcc_out->m_hDRint[s]->GetXaxis()->GetBinCenter(i);
2252 m_dcc_out->m_hDRint[s]->SetBinContent(i, j, gr_dR[s]->Interpolate(phiVal, RVal));
2253 m_dcc_out->m_hDPint[s]->SetBinContent(i, j, RVal * gr_dPhi[s]->Interpolate(phiVal, RVal));
2254 }
2255 }
2256 }
2257
2258 if (Verbosity() > 1)
2259 {
2260 std::cout << "TpcCentralMembraneMatching::process_events - cmclusters: " << m_corrected_CMcluster_map->size() << std::endl;
2261 std::cout << "TpcCentralMembraneMatching::process_events - matched pairs: " << nMatched << std::endl;
2262 std::cout << "TpcCentralMembraneMatching::process_events - differences: " << m_cm_flash_diffs->size() << std::endl;
2263 std::cout << "TpcCentralMembraneMatching::process_events - entries: " << m_dcc_out->m_hentries[0]->GetEntries() << ", " << m_dcc_out->m_hentries[1]->GetEntries() << std::endl;
2264 }
2265
2266
2267
2268
2269
2270 if (Verbosity() > 2)
2271 {
2272
2273 auto diffrange = m_cm_flash_diffs->getDifferences();
2274 for (auto cmitr = diffrange.first;
2275 cmitr != diffrange.second;
2276 ++cmitr)
2277 {
2278 auto key = cmitr->first;
2279 auto* cmreco = cmitr->second;
2280
2281 std::cout << " key " << key
2282 << " nclus " << cmreco->getNclusters()
2283 << " truth Phi " << cmreco->getTruthPhi() << " reco Phi " << cmreco->getRecoPhi()
2284 << " truth R " << cmreco->getTruthR() << " reco R " << cmreco->getRecoR()
2285 << " truth Z " << cmreco->getTruthZ() << " reco Z " << cmreco->getRecoZ()
2286 << std::endl;
2287 }
2288 }
2289
2290 if (!m_useHeader)
2291 {
2292 m_event_index++;
2293 }
2294
2295 return Fun4AllReturnCodes::EVENT_OK;
2296 }
2297
2298
2299 int TpcCentralMembraneMatching::End(PHCompositeNode* )
2300 {
2301 std::cout << PHWHERE << "starting TpcCentralMembraneMatching::End()" << std::endl;
2302
2303
2304 if (m_dcc_out_aggregated)
2305 {
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315 for (int s = 0; s < 2; s++)
2316 {
2317 gr_dR[s]->Clear();
2318 gr_dPhi[s]->Clear();
2319 }
2320
2321 for (auto [idx, n] : nByIndex)
2322 {
2323 if (n < 50)
2324 {
2325 continue;
2326 }
2327 int side = (idx < 180000 ? 1 : 0);
2328
2329 gr_dR[side]->AddPoint(meanPhiByIndex[idx] / n, meanRByIndex[idx] / n, deltaRByIndex[idx] / n);
2330 gr_dPhi[side]->AddPoint(meanPhiByIndex[idx] / n, meanRByIndex[idx] / n, deltaPhiByIndex[idx] / n);
2331 gr_points[side]->AddPoint(meanPhiByIndex[idx] / n, meanRByIndex[idx] / n);
2332
2333 if (meanPhiByIndex[idx] / n < M_PI / 12)
2334 {
2335 gr_dR[side]->AddPoint(meanPhiByIndex[idx] / n + 2 * M_PI, meanRByIndex[idx] / n, deltaRByIndex[idx] / n);
2336 gr_dPhi[side]->AddPoint(meanPhiByIndex[idx] / n + 2 * M_PI, meanRByIndex[idx] / n, deltaPhiByIndex[idx] / n);
2337 }
2338 if (meanPhiByIndex[idx] / n > 23 * M_PI / 12)
2339 {
2340 gr_dR[side]->AddPoint(meanPhiByIndex[idx] / n - 2 * M_PI, meanRByIndex[idx] / n, deltaRByIndex[idx] / n);
2341 gr_dPhi[side]->AddPoint(meanPhiByIndex[idx] / n - 2 * M_PI, meanRByIndex[idx] / n, deltaPhiByIndex[idx] / n);
2342 }
2343 }
2344
2345 for (int s = 0; s < 2; s++)
2346 {
2347 bool firstGoodR = false;
2348 for (int j = 1; j <= m_dcc_out_aggregated->m_hDRint[s]->GetNbinsY(); j++)
2349 {
2350 double RVal = m_dcc_out_aggregated->m_hDRint[s]->GetYaxis()->GetBinCenter(j);
2351 double Rlow = m_dcc_out_aggregated->m_hDRint[s]->GetYaxis()->GetBinLowEdge(j);
2352 double Rhigh = m_dcc_out_aggregated->m_hDRint[s]->GetYaxis()->GetBinLowEdge(j + 1);
2353
2354 if (!firstGoodR)
2355 {
2356 for (int p = 0; p < gr_dR[s]->GetN(); p++)
2357 {
2358 if (gr_dR[s]->GetY()[p] > Rlow && gr_dR[s]->GetY()[p] > Rhigh)
2359 {
2360 firstGoodR = true;
2361 break;
2362 }
2363 }
2364 continue;
2365 }
2366
2367 for (int i = 2; i <= m_dcc_out_aggregated->m_hDRint[s]->GetNbinsX() - 1; i++)
2368 {
2369 double phiVal = m_dcc_out_aggregated->m_hDRint[s]->GetXaxis()->GetBinCenter(i);
2370
2371 m_dcc_out_aggregated->m_hDRint[s]->SetBinContent(i, j, gr_dR[s]->Interpolate(phiVal, RVal));
2372 m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, RVal * gr_dPhi[s]->Interpolate(phiVal, RVal));
2373 }
2374 }
2375 }
2376
2377
2378 std::unique_ptr<TFile> outputfile(TFile::Open(m_outputfile.c_str(), "RECREATE"));
2379 outputfile->cd();
2380
2381
2382 for (unsigned int i = 0; i < 2; ++i)
2383 {
2384 for (const auto& h : {m_dcc_out_aggregated->m_hDRint[i], m_dcc_out_aggregated->m_hDPint[i], m_dcc_out_aggregated->m_hDZint[i], m_dcc_out_aggregated->m_hentries[i]})
2385 {
2386 if (h)
2387 {
2388 std::cout << "writing in " << m_outputfile << " histogram " << h->GetName() << std::endl;
2389 h->Write();
2390 }
2391 }
2392
2393
2394
2395 gr_points[i]->Write(std::format("gr_points_{}z", (i == 1 ? "pos" : "neg")).c_str());
2396 gr_dR[i]->Write(std::format("gr_dr_{}z", (i == 1 ? "pos" : "neg")).c_str());
2397 gr_dPhi[i]->Write(std::format("gr_dPhi_{}z", (i == 1 ? "pos" : "neg")).c_str());
2398 }
2399 }
2400
2401
2402 if (m_savehistograms && fout)
2403 {
2404 fout->cd();
2405
2406 hxy_reco->Write();
2407 hxy_truth->Write();
2408 hdrdphi->Write();
2409 hrdr->Write();
2410 hrdphi->Write();
2411 hdphi->Write();
2412 hdrphi->Write();
2413 hdr1_single->Write();
2414 hdr2_single->Write();
2415 hdr3_single->Write();
2416 hdr1_double->Write();
2417 hdr2_double->Write();
2418 hdr3_double->Write();
2419 hnclus->Write();
2420
2421 fout->Close();
2422 }
2423
2424 if (m_savehistograms && m_debugfile)
2425 {
2426 m_debugfile->cd();
2427
2428 std::cout << "writing in " << m_debugfilename << " match tree " << std::endl;
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443 m_debugfile->Write();
2444 std::cout << "closing " << m_debugfilename << std::endl;
2445 m_debugfile->Close();
2446 std::cout << m_debugfilename << " has been closed" << std::endl;
2447 }
2448
2449 return Fun4AllReturnCodes::EVENT_OK;
2450 }
2451
2452
2453
2454 int TpcCentralMembraneMatching::GetNodes(PHCompositeNode* topNode)
2455 {
2456
2457
2458
2459
2460
2461 m_corrected_CMcluster_map = findNode::getClass<LaserClusterContainer>(topNode, "LASER_CLUSTER");
2462 if (!m_corrected_CMcluster_map)
2463 {
2464 std::cout << PHWHERE << "CORRECTED_CM_CLUSTER Node missing, abort." << std::endl;
2465 return Fun4AllReturnCodes::ABORTRUN;
2466 }
2467
2468
2469 m_dcc_in_module_edge = findNode::getClass<TpcDistortionCorrectionContainer>(topNode, "TpcDistortionCorrectionContainerModuleEdge");
2470 if (m_dcc_in_module_edge)
2471 {
2472 std::cout << "TpcCentralMembraneMatching::GetNodes - found TPC distortion correction container module edge" << std::endl;
2473 }
2474
2475
2476 m_dcc_in_static = findNode::getClass<TpcDistortionCorrectionContainer>(topNode, "TpcDistortionCorrectionContainerStatic");
2477 if (m_dcc_in_static)
2478 {
2479 std::cout << "TpcCentralMembraneMatching::GetNodes - found TPC distortion correction container static" << std::endl;
2480 }
2481
2482
2483 m_dcc_in_average = findNode::getClass<TpcDistortionCorrectionContainer>(topNode, "TpcDistortionCorrectionContainerAverage");
2484 if (m_dcc_in_average)
2485 {
2486 std::cout << "TpcCentralMembraneMatching::GetNodes - found TPC distortion correction container average" << std::endl;
2487 }
2488
2489 PHNodeIterator iter(topNode);
2490
2491
2492 PHCompositeNode* dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
2493 if (!dstNode)
2494 {
2495 std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
2496 return Fun4AllReturnCodes::ABORTRUN;
2497 }
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508 auto* flashDiffContainer = findNode::getClass<CMFlashDifferenceContainerv1>(topNode, "CM_FLASH_DIFFERENCES");
2509 if (!flashDiffContainer)
2510 {
2511 PHNodeIterator dstiter(dstNode);
2512 PHCompositeNode* DetNode =
2513 dynamic_cast<PHCompositeNode*>(dstiter.findFirst("PHCompositeNode", "TRKR"));
2514 if (!DetNode)
2515 {
2516 DetNode = new PHCompositeNode("TRKR");
2517 dstNode->addNode(DetNode);
2518 }
2519
2520 flashDiffContainer = new CMFlashDifferenceContainerv1;
2521 PHIODataNode<PHObject>* CMFlashDifferenceNode =
2522 new PHIODataNode<PHObject>(flashDiffContainer, "CM_FLASH_DIFFERENCES", "PHObject");
2523
2524 DetNode->addNode(CMFlashDifferenceNode);
2525 }
2526
2527
2528 m_cm_flash_diffs = findNode::getClass<CMFlashDifferenceContainerv1>(topNode, "CM_FLASH_DIFFERENCES");
2529 if (!m_cm_flash_diffs)
2530 {
2531 std::cout << PHWHERE << " ERROR: Can't find CM_FLASH_DIFFERENCES." << std::endl;
2532 return Fun4AllReturnCodes::ABORTRUN;
2533 }
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560 const std::string dcc_out_node_name = "TpcDistortionCorrectionContainerFluctuation";
2561 m_dcc_out = findNode::getClass<TpcDistortionCorrectionContainer>(topNode, dcc_out_node_name);
2562 if (!m_dcc_out)
2563 {
2564
2565 auto* runNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "RUN"));
2566 if (!runNode)
2567 {
2568 std::cout << "TpcCentralMembraneMatching::InitRun - RUN Node missing, quitting" << std::endl;
2569 return Fun4AllReturnCodes::ABORTRUN;
2570 }
2571
2572 std::cout << "TpcCentralMembraneMatching::GetNodes - creating TpcDistortionCorrectionContainer in node " << dcc_out_node_name << std::endl;
2573 m_dcc_out = new TpcDistortionCorrectionContainer;
2574 m_dcc_out->m_dimensions = 2;
2575 m_dcc_out->m_phi_hist_in_radians = false;
2576 m_dcc_out->m_interpolate_z = true;
2577 auto* node = new PHDataNode<TpcDistortionCorrectionContainer>(m_dcc_out, dcc_out_node_name);
2578 runNode->addNode(node);
2579 }
2580
2581
2582
2583
2584
2585 m_dcc_out_aggregated.reset(new TpcDistortionCorrectionContainer);
2586
2587
2588 const float phiMin = m_phiMin - (m_phiMax - m_phiMin) / m_phibins;
2589 const float phiMax = m_phiMax + (m_phiMax - m_phiMin) / m_phibins;
2590
2591 const float rMin = m_rMin - (m_rMax - m_rMin) / m_rbins;
2592 const float rMax = m_rMax + (m_rMax - m_rMin) / m_rbins;
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627 const std::array<const std::string, 2> extension = {{"_negz", "_posz"}};
2628 for (const auto& dcc : {m_dcc_out, m_dcc_out_aggregated.get()})
2629 {
2630
2631 dcc->m_dimensions = 2;
2632
2633
2634 for (int i = 0; i < 2; ++i)
2635 {
2636 delete dcc->m_hDPint[i];
2637 dcc->m_hDPint[i] = new TH2F(std::format("hIntDistortionP{}", extension[i]).c_str(), std::format("hIntDistortionP{}", extension[i]).c_str(), m_phibins + 2, phiMin, phiMax, m_rbins + 2, rMin, rMax);
2638 delete dcc->m_hDRint[i];
2639 dcc->m_hDRint[i] = new TH2F(std::format("hIntDistortionR{}", extension[i]).c_str(), std::format("hIntDistortionR{}", extension[i]).c_str(), m_phibins + 2, phiMin, phiMax, m_rbins + 2, rMin, rMax);
2640 delete dcc->m_hDZint[i];
2641 dcc->m_hDZint[i] = new TH2F(std::format("hIntDistortionZ{}", extension[i]).c_str(), std::format("hIntDistortionZ{}", extension[i]).c_str(), m_phibins + 2, phiMin, phiMax, m_rbins + 2, rMin, rMax);
2642 delete dcc->m_hentries[i];
2643 dcc->m_hentries[i] = new TH2I(std::format("hEntries{}", extension[i]).c_str(), std::format("hEntries{}", extension[i]).c_str(), m_phibins + 2, phiMin, phiMax, m_rbins + 2, rMin, rMax);
2644
2645
2646
2647
2648
2649 }
2650 }
2651
2652 return Fun4AllReturnCodes::EVENT_OK;
2653 }
2654
2655
2656 void TpcCentralMembraneMatching::CalculateCenters(
2657 int nPads,
2658 const std::array<double, nRadii>& R,
2659 std::array<int, nRadii>& nGoodStripes,
2660 const std::array<int, nRadii>& keepUntil,
2661 std::array<int, nRadii>& nStripesIn,
2662 std::array<int, nRadii>& nStripesBefore,
2663 double cx[][nRadii], double cy[][nRadii])
2664 {
2665 const double phi_module = M_PI / 6.0;
2666 const int pr_mult = 3;
2667 const int dw_mult = 8;
2668 const double diffwidth = 0.6 * mm;
2669 const double adjust = 0.015;
2670
2671 double theta = 0.0;
2672
2673
2674
2675
2676 std::array<double, nRadii> spacing{};
2677 for (int i = 0; i < nRadii; i++)
2678 {
2679 spacing[i] = 2.0 * ((dw_mult * diffwidth / R[i]) + (pr_mult * phi_module / nPads));
2680 }
2681
2682
2683 for (int j = 0; j < nRadii; j++)
2684 {
2685 int i_out = 0;
2686 for (int i = keepThisAndAfter[j]; i < keepUntil[j]; i++)
2687 {
2688 if (j % 2 == 0)
2689 {
2690 theta = i * spacing[j] + (spacing[j] / 2) - adjust;
2691 cx[i_out][j] = R[j] * cos(theta) / cm;
2692 cy[i_out][j] = R[j] * sin(theta) / cm;
2693 }
2694 else
2695 {
2696 theta = (i + 1) * spacing[j] - adjust;
2697 cx[i_out][j] = R[j] * cos(theta) / cm;
2698 cy[i_out][j] = R[j] * sin(theta) / cm;
2699 }
2700
2701 if (Verbosity() > 2)
2702 {
2703 std::cout << " j " << j << " i " << i << " i_out " << i_out << " theta " << theta << " cx " << cx[i_out][j] << " cy " << cy[i_out][j]
2704 << " radius " << sqrt(pow(cx[i_out][j], 2) + pow(cy[i_out][j], 2)) << std::endl;
2705 }
2706
2707 i_out++;
2708
2709 nStripesBefore_R1_e[0] = 0;
2710
2711 nStripesIn[j] = keepUntil[j] - keepThisAndAfter[j];
2712 if (j == 0)
2713 {
2714 nStripesBefore[j] = 0;
2715 }
2716 else
2717 {
2718 nStripesBefore[j] = nStripesIn[j - 1] + nStripesBefore[j - 1];
2719 }
2720 nStripesBefore_R1_e[0] = 0;
2721 }
2722 nGoodStripes[j] = i_out;
2723 }
2724 }