File indexing completed on 2025-08-05 08:11:20
0001 #include "TF1.h"
0002 #include "TF2.h"
0003 #include "TFile.h"
0004 #include "TGraphErrors.h"
0005 #include "TH1F.h"
0006 #include "TProfile.h"
0007 #include "TTree.h"
0008
0009 #include <Eigen/Dense>
0010
0011 #include "Beamspot.h"
0012 #include "Hit.h"
0013 #include "Utilities.h"
0014
0015 Beamspot fit_PCAD0Phi0(std::vector<std::pair<std::shared_ptr<Hit>, std::shared_ptr<Hit>>> tracklets, Beamspot BS_init, double d0_cut)
0016 {
0017 Beamspot reco_BS;
0018
0019 int Ntracklets = 0;
0020
0021 std::cout << "processing " << tracklets.size() << " tracklets..." << std::endl;
0022
0023 for (auto &tracklet : tracklets)
0024 {
0025 double x1 = tracklet.first->posX();
0026 double y1 = tracklet.first->posY();
0027 double z1 = tracklet.first->posZ();
0028 double x2 = tracklet.second->posX();
0029 double y2 = tracklet.second->posY();
0030 double z2 = tracklet.second->posZ();
0031
0032 int size1 = tracklet.first->PhiSize();
0033 int size2 = tracklet.second->PhiSize();
0034
0035
0036
0037
0038 double stripwidth = 0.0078;
0039 double rphierr1 = stripwidth * size1;
0040 double rphierr2 = stripwidth * size2;
0041 double r1 = sqrt(x1 * x1 + y1 * y1);
0042 double r2 = sqrt(x2 * x2 + y2 * y2);
0043 double phi1 = atan2(y1, x1);
0044 double phi2 = atan2(y2, x2);
0045 double sigma2_x1 = pow(rphierr1 * cos(phi1), 2.);
0046 double sigma2_y1 = pow(rphierr1 * sin(phi1), 2.);
0047 double sigma2_x2 = pow(rphierr2 * cos(phi2), 2.);
0048 double sigma2_y2 = pow(rphierr2 * sin(phi2), 2.);
0049
0050
0051 double px = x2 - x1;
0052 double py = y2 - y1;
0053 double sigma2_px = sigma2_x2 + sigma2_x1;
0054 double sigma2_py = sigma2_y2 + sigma2_y1;
0055 double phi0 = atan2(py, px);
0056 double sigma2_phi0 = (sigma2_px * py * py + sigma2_py * px * px) / pow(px * px + py * py, 2.);
0057
0058
0059
0060 double pca_x = x1 + ((BS_init.x - x1) * cos(phi0) + (BS_init.y - y1) * sin(phi0)) * cos(phi0);
0061 double pca_y = y1 + ((BS_init.x - x1) * cos(phi0) + (BS_init.y - y1) * sin(phi0)) * sin(phi0);
0062
0063
0064 double dca_origin = sqrt(pca_x * pca_x + pca_y * pca_y);
0065 double dzdr = (z2 - z1) / (r2 - r1);
0066 double z0 = z1 - dzdr * (r1 - dca_origin);
0067
0068 double d0 = sqrt(pow(pca_x - BS_init.x, 2.) + pow(pca_y - BS_init.y, 2.));
0069 if (d0 > d0_cut)
0070 continue;
0071 double phi_pca = atan2(pca_y - BS_init.y, pca_x - BS_init.x);
0072 double oppositephi_pca = phi_pca + M_PI;
0073 if (oppositephi_pca > M_PI)
0074 oppositephi_pca -= 2 * M_PI;
0075
0076 reco_BS.d0phi0dist->Fill(phi_pca, d0);
0077 reco_BS.d0phi0dist->Fill(oppositephi_pca, -d0);
0078
0079 reco_BS.pcadist->Fill(pca_x, pca_y);
0080 reco_BS.z0dist->Fill(z0);
0081
0082 Ntracklets++;
0083 }
0084
0085 TF1 z_f("gaus", "gaus", -60., 60.);
0086
0087
0088 reco_BS.d0phi0dist_bkgrm = (TH2F *)reco_BS.d0phi0dist->Clone("d0phi0dist_bkgrm");
0089 for (int i = 0; i < reco_BS.d0phi0dist->GetNbinsX(); i++)
0090 {
0091 TH1D *slice = reco_BS.d0phi0dist->ProjectionY("slice", i, i + 1);
0092 int maxbin = slice->GetMaximumBin();
0093 float max = slice->GetBinContent(maxbin);
0094 for (int j = 0; j < slice->GetNbinsX(); j++)
0095 {
0096 float content = slice->GetBinContent(j + 1);
0097 if (slice->GetBinContent(j + 1) < 0.995 * max)
0098 reco_BS.d0phi0dist_bkgrm->SetBinContent(i + 1, j + 1, 0.);
0099 }
0100 }
0101
0102 reco_BS.d0phi0dist_bkgrm_prof = reco_BS.d0phi0dist_bkgrm->ProfileX("d0phi0dist_bkgrm_prof");
0103
0104 TGraphErrors *g = new TGraphErrors();
0105 for (int i = 0; i < reco_BS.d0phi0dist_bkgrm_prof->GetNbinsX(); i++)
0106 {
0107 double d0 = reco_BS.d0phi0dist_bkgrm_prof->GetBinContent(i + 1);
0108 double phi = -M_PI + i * (2. * M_PI) / 200.;
0109 g->SetPoint(i, phi, d0);
0110 }
0111
0112 TF1 d0cos("d0cos", "[0]*TMath::Cos(x-[1])", -M_PI, M_PI);
0113 g->Fit(&d0cos);
0114 g->Write("maxgraph_prermoutl");
0115
0116 vector<float> phi_2;
0117 vector<float> d0_2;
0118 TF1 d0cos_rmoutl("d0cos_rmoutl", "[0]*TMath::Cos(x-[1])", -M_PI, M_PI);
0119 for (int i = 0; i < g->GetN(); i++)
0120 {
0121 double x, y;
0122 g->GetPoint(i, x, y);
0123 double y_fit = d0cos.Eval(x);
0124
0125 if (fabs(y - y_fit) < 0.2)
0126 {
0127 phi_2.push_back(x);
0128 d0_2.push_back(y);
0129 }
0130 }
0131
0132 TGraphErrors *g2 = new TGraphErrors(phi_2.size(), &phi_2[0], &d0_2[0]);
0133
0134 g2->Fit(&d0cos_rmoutl);
0135 g2->Write("maxgraph_rmoutl");
0136
0137 reco_BS.z0dist->Fit(&z_f);
0138
0139
0140 double BS_d0 = d0cos_rmoutl.GetParameter(0);
0141 double BS_phi0 = d0cos_rmoutl.GetParameter(1);
0142 double BS_sigmad0 = d0cos_rmoutl.GetParError(0);
0143 double BS_sigmaphi0 = d0cos_rmoutl.GetParError(1);
0144
0145 reco_BS.x = BS_d0 * cos(BS_phi0) + BS_init.x;
0146 reco_BS.y = BS_d0 * sin(BS_phi0) + BS_init.y;
0147 reco_BS.sigma_x = sqrt(pow(cos(BS_phi0), 2.) * pow(BS_sigmad0, 2.) + pow(BS_d0 * sin(BS_phi0), 2.) * pow(BS_sigmaphi0, 2.));
0148 reco_BS.sigma_y = sqrt(pow(sin(BS_phi0), 2.) * pow(BS_sigmad0, 2.) + pow(BS_d0 * cos(BS_phi0), 2.) * pow(BS_sigmaphi0, 2.));
0149
0150 reco_BS.Ntracklets = Ntracklets;
0151
0152 reco_BS.z = z_f.GetParameter("Mean");
0153 reco_BS.sigma_z = z_f.GetParameter("Sigma");
0154
0155 return reco_BS;
0156 }
0157
0158 int main(int argc, char **argv)
0159 {
0160 if (argc != 4)
0161 {
0162 std::cout << "Usage: ./BeamspotReco [infile] [outfile] [dphi_cut]" << std::endl;
0163 return 0;
0164 }
0165
0166 std::string infile = argv[1];
0167 std::string outfile = argv[2];
0168 double dphi_cut = atof(argv[3]);
0169
0170 TFile *inf = TFile::Open(infile.c_str());
0171 TTree *events = (TTree *)inf->Get("EventTree");
0172
0173 TFile *outf = new TFile(outfile.c_str(), "RECREATE");
0174 TTree *t = new TTree("reco_beamspot", "reco_beamspot");
0175
0176 uint64_t intt_bco;
0177 int Nclusters;
0178 std::vector<double> *clusters_x = 0;
0179 std::vector<double> *clusters_y = 0;
0180 std::vector<double> *clusters_z = 0;
0181 std::vector<int> *clusters_layer = 0;
0182 std::vector<int> *clusters_phisize = 0;
0183 std::vector<unsigned int> *clusters_adc = 0;
0184 bool InttBco_IsToBeRemoved;
0185
0186 events->SetBranchAddress("INTT_BCO", &intt_bco);
0187 if (events->GetListOfBranches()->FindObject("InttBco_IsToBeRemoved"))
0188 {
0189 events->SetBranchAddress("InttBco_IsToBeRemoved", &InttBco_IsToBeRemoved);
0190 }
0191 else
0192 {
0193 InttBco_IsToBeRemoved = false;
0194 }
0195 events->SetBranchAddress("NClus", &Nclusters);
0196 events->SetBranchAddress("ClusX", &clusters_x);
0197 events->SetBranchAddress("ClusY", &clusters_y);
0198 events->SetBranchAddress("ClusZ", &clusters_z);
0199 events->SetBranchAddress("ClusLayer", &clusters_layer);
0200 events->SetBranchAddress("ClusPhiSize", &clusters_phisize);
0201 events->SetBranchAddress("ClusAdc", &clusters_adc);
0202
0203 std::vector<std::pair<std::shared_ptr<Hit>, std::shared_ptr<Hit>>> tracklets;
0204 std::vector<uint64_t> bcos;
0205
0206
0207 for (int i = 0; i < events->GetEntries(); i++)
0208 {
0209 std::vector<std::shared_ptr<Hit>> layer1_clusters;
0210 std::vector<std::shared_ptr<Hit>> layer2_clusters;
0211
0212 events->GetEntry(i);
0213
0214 bcos.push_back(intt_bco);
0215
0216 std::cout << "event " << i << " INTT_BCO " << intt_bco << std::endl;
0217
0218 if (InttBco_IsToBeRemoved == true)
0219 continue;
0220
0221
0222 if (Nclusters < 20 || Nclusters > 350)
0223 continue;
0224
0225 for (int j = 0; j < Nclusters; j++)
0226 {
0227 if (clusters_adc->at(j) <= 35)
0228 continue;
0229
0230 if (clusters_layer->at(j) == 3 || clusters_layer->at(j) == 4)
0231 {
0232 layer1_clusters.push_back(std::make_shared<Hit>(clusters_x->at(j), clusters_y->at(j), clusters_z->at(j), 0., 0., 0., 0, clusters_phisize->at(j)));
0233 }
0234 if (clusters_layer->at(j) == 5 || clusters_layer->at(j) == 6)
0235 {
0236 layer2_clusters.push_back(std::make_shared<Hit>(clusters_x->at(j), clusters_y->at(j), clusters_z->at(j), 0., 0., 0., 0, clusters_phisize->at(j)));
0237 }
0238 }
0239
0240 if (layer1_clusters.size() < 10 || layer2_clusters.size() < 10)
0241 continue;
0242
0243 for (auto &cluster1 : layer1_clusters)
0244 {
0245 for (auto &cluster2 : layer2_clusters)
0246 {
0247
0248 if (deltaPhi(cluster1->Phi(), cluster2->Phi()) < dphi_cut)
0249 {
0250 tracklets.push_back(std::make_pair(cluster1, cluster2));
0251 }
0252 }
0253 }
0254 }
0255
0256 Beamspot origin;
0257
0258
0259 Beamspot BS = fit_PCAD0Phi0(tracklets, origin, 1.);
0260
0261
0262
0263
0264
0265 std::sort(bcos.begin(), bcos.end());
0266 uint64_t min_bco = bcos.front();
0267 uint64_t median_bco = (bcos.size() % 2 == 0) ? (bcos[bcos.size() / 2] + bcos[bcos.size() / 2 - 1]) / 2 : bcos[bcos.size() / 2];
0268 uint64_t max_bco = bcos.back();
0269
0270 t->Branch("x", &BS.x);
0271 t->Branch("y", &BS.y);
0272 t->Branch("z", &BS.z);
0273 t->Branch("sigma_x", &BS.sigma_x);
0274 t->Branch("sigma_y", &BS.sigma_y);
0275 t->Branch("sigma_z", &BS.sigma_z);
0276 t->Branch("xy_correlation", &BS.xy_correlation);
0277 t->Branch("Ntracklets", &BS.Ntracklets);
0278 t->Branch("intt_bco_min", &min_bco);
0279 t->Branch("intt_bco_median", &median_bco);
0280 t->Branch("intt_bco_max", &max_bco);
0281
0282 t->Fill();
0283 t->Write();
0284
0285 BS.d0phi0dist->Write("d0phi0dist", TObject::kOverwrite);
0286 BS.d0phi0dist_bkgrm->Write("d0phi0dist_bkgrm", TObject::kOverwrite);
0287 BS.d0phi0dist_bkgrm_prof->Write("d0phi0dist_bkgrm_prof", TObject::kOverwrite);
0288 BS.z0dist->Write("z0dist", TObject::kOverwrite);
0289 BS.pcadist->Write("pcadist", TObject::kOverwrite);
0290
0291 BS.identify();
0292
0293 outf->Close();
0294
0295 return 0;
0296 }