Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BeamspotReco.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file BeamspotReco.cxx
1 #include "TFile.h"
2 #include "TTree.h"
3 #include "TH1F.h"
4 #include "TF1.h"
5 #include "TF2.h"
6 #include "TGraphErrors.h"
7 
8 #include <Eigen/Dense>
9 
10 #include "Hit.h"
11 #include "Beamspot.h"
12 
13 Beamspot fit_PCAD0Phi0(std::vector<std::pair<std::shared_ptr<Hit>,std::shared_ptr<Hit>>> tracklets, Beamspot BS_init, double d0_cut)
14 {
15  Beamspot reco_BS;
16 
17  int Ntracklets = 0;
18 
19  std::cout << "processing " << tracklets.size() << " tracklets..." << std::endl;
20 
21  for(auto& tracklet : tracklets)
22  {
23  double x1 = tracklet.first->posX();
24  double y1 = tracklet.first->posY();
25  double z1 = tracklet.first->posZ();
26  double x2 = tracklet.second->posX();
27  double y2 = tracklet.second->posY();
28  double z2 = tracklet.second->posZ();
29 
30  int size1 = tracklet.first->PhiSize();
31  int size2 = tracklet.second->PhiSize();
32 
33  //std::cout << "tracklet: (" << x1 << ", " << y1 << ", " << z1 <<") -> (" << x2 << ", " << y2 << ", " << z2 << ")" << std::endl;
34 
35  // cluster position uncertainties
36  double stripwidth = 0.0078; // cm
37  double rphierr1 = stripwidth*size1;
38  double rphierr2 = stripwidth*size2;
39  double r1 = sqrt(x1*x1+y1*y1);
40  double r2 = sqrt(x2*x2+y2*y2);
41  double phi1 = atan2(y1,x1);
42  double phi2 = atan2(y2,x2);
43  double sigma2_x1 = pow(rphierr1*cos(phi1),2.);
44  double sigma2_y1 = pow(rphierr1*sin(phi1),2.);
45  double sigma2_x2 = pow(rphierr2*cos(phi2),2.);
46  double sigma2_y2 = pow(rphierr2*sin(phi2),2.);
47 
48  // phi0 (angle of momentum vector at PCA) and uncertainty
49  double px = x2-x1;
50  double py = y2-y1;
51  double sigma2_px = sigma2_x2+sigma2_x1;
52  double sigma2_py = sigma2_y2+sigma2_y1;
53  double phi0 = atan2(py,px);
54  double sigma2_phi0 = (sigma2_px*py*py+sigma2_py*px*px)/pow(px*px+py*py,2.); // the aftermath of a bit of algebra
55  //std::cout << "phi0: " << phi0 << " +- " << sqrt(sigma2_phi0) << std::endl;
56 
57  // PCA and uncertainty
58  double pca_x = x1 + ((BS_init.x-x1)*cos(phi0)+(BS_init.y-y1)*sin(phi0))*cos(phi0);
59  double pca_y = y1 + ((BS_init.x-x1)*cos(phi0)+(BS_init.y-y1)*sin(phi0))*sin(phi0);
60  //std::cout << "PCA: (" << pca_x << " +- " << sqrt(sigma2_pca_x) << ", " << pca_y << " +- " << sqrt(sigma2_pca_y) << std::endl;
61 
62  double dca_origin = sqrt(pca_x*pca_x+pca_y*pca_y);
63  double dzdr = (z2-z1)/(r2-r1);
64  double z0 = z1-dzdr*(r1-dca_origin);
65 
66  double d0 = sqrt(pow(pca_x-BS_init.x,2.)+pow(pca_y-BS_init.y,2.));
67  if(d0>d0_cut) continue;
68  double phi_pca = atan2(pca_y-BS_init.y,pca_x-BS_init.x);
69  double oppositephi_pca = phi_pca+M_PI;
70  if(oppositephi_pca>M_PI) oppositephi_pca -= 2*M_PI;
71 
72  reco_BS.d0phi0dist->Fill(phi_pca,d0);
73  reco_BS.d0phi0dist->Fill(oppositephi_pca,-d0);
74 
75  reco_BS.pcadist->Fill(pca_x,pca_y);
76  reco_BS.z0dist->Fill(z0);
77 
78  Ntracklets++;
79  }
80 
81  TF1 z_f("gaus","gaus",-60.,60.);
82 
83  //TF2 d0phi0_f("d0phi0_f","[0]+[1]*TMath::Gaus(y,[2]*TMath::Cos(x-[3]),[4])",-M_PI,M_PI,-1.,1.);
84 
85  TGraphErrors* g = new TGraphErrors();
86 
87  for(int i=0;i<reco_BS.d0phi0dist->GetNbinsY();i++)
88  {
89  TH1D* slice = reco_BS.d0phi0dist->ProjectionY("slice",i,i+1);
90  int maxbin = slice->GetMaximumBin();
91  double best_d0 = slice->GetBinCenter(maxbin);
92  double low_d0 = slice->GetBinCenter(slice->FindFirstBinAbove(0.5*slice->GetMaximum(),1,maxbin-10,maxbin));
93  double high_d0 = slice->GetBinCenter(slice->FindLastBinAbove(0.5*slice->GetMaximum(),1,maxbin,maxbin+10));
94  double d0_error;
95  if(best_d0-low_d0>high_d0-best_d0) d0_error = best_d0-low_d0;
96  else d0_error = high_d0-best_d0;
97  std::cout << "d0 error: " << d0_error << std::endl;
98  double slice_phi = -M_PI+i*(2.*M_PI)/200.;
99  g->AddPoint(slice_phi,best_d0);
100  g->SetPointError(i,M_PI/100.,d0_error);
101  }
102 
103  TF1 d0cos("d0cos","[0]*TMath::Cos(x-[1])",-M_PI,M_PI);
104  g->Fit(&d0cos);
105  g->Write("maxgraph");
106 /*
107  d0phi0_f.SetParameter(0,(float)Ntracklets/(reco_BS.d0phi0dist->GetNbinsX()*reco_BS.d0phi0dist->GetNbinsY()));
108  d0phi0_f.SetParLimits(0,0.,1e9);
109  d0phi0_f.SetParameter(1,1.);
110  d0phi0_f.SetParameter(2,1.);
111  d0phi0_f.SetParameter(3,0.);
112  d0phi0_f.SetParLimits(3,-M_PI,M_PI);
113  d0phi0_f.SetParameter(4,.001);
114  d0phi0_f.SetParLimits(4,0.,1.);
115 */
116  reco_BS.z0dist->Fit(&z_f);
117  //reco_BS.d0phi0dist->Fit(&d0phi0_f,"LI");
118 
119  // build reconstructed beamspot: x and y first
120 
121  double BS_d0 = d0cos.GetParameter(0);
122  double BS_phi0 = d0cos.GetParameter(1);
123  double BS_sigmad0 = d0cos.GetParError(0);
124  double BS_sigmaphi0 = d0cos.GetParError(1);
125 
126  reco_BS.x = BS_d0*cos(BS_phi0)+BS_init.x;
127  reco_BS.y = BS_d0*sin(BS_phi0)+BS_init.y;
128  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.));
129  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.));
130 
131  reco_BS.Ntracklets = Ntracklets;
132 
133  reco_BS.z = z_f.GetParameter("Mean");
134  reco_BS.sigma_z = z_f.GetParameter("Sigma");
135 
136  return reco_BS;
137 }
138 
139 int main(int argc, char** argv)
140 {
141  if(argc!=4)
142  {
143  std::cout << "Usage: ./BeamspotReco [infile] [outfile] [dphi_cut]" << std::endl;
144  return 0;
145  }
146 
147  std::string infile = argv[1];
148  std::string outfile = argv[2];
149  double dphi_cut = atof(argv[3]);
150 
151  TFile* inf = TFile::Open(infile.c_str());
152  TTree* events = (TTree*)inf->Get("EventTree");
153 
154  TFile* outf = new TFile(outfile.c_str(),"RECREATE");
155  TTree* t = new TTree("reco_beamspot","reco_beamspot");
156 
157  int Nclusters;
158  std::vector<double>* clusters_x = 0;
159  std::vector<double>* clusters_y = 0;
160  std::vector<double>* clusters_z = 0;
161  std::vector<int>* clusters_layer = 0;
162  std::vector<int>* clusters_phisize = 0;
163 
164  events->SetBranchAddress("NClus",&Nclusters);
165  events->SetBranchAddress("ClusX",&clusters_x);
166  events->SetBranchAddress("ClusY",&clusters_y);
167  events->SetBranchAddress("ClusZ",&clusters_z);
168  events->SetBranchAddress("ClusLayer",&clusters_layer);
169  events->SetBranchAddress("ClusPhiSize",&clusters_phisize);
170 
171  std::vector<std::pair<std::shared_ptr<Hit>,std::shared_ptr<Hit>>> tracklets;
172 
173  // assemble tracklets that pass dphi cut
174  for(int i=0;i<events->GetEntries();i++)
175  {
176  std::vector<std::shared_ptr<Hit>> layer1_clusters;
177  std::vector<std::shared_ptr<Hit>> layer2_clusters;
178 
179  events->GetEntry(i);
180 
181  std::cout << "event " << i << std::endl;
182 
183  for(int j=0;j<Nclusters;j++)
184  {
185  if(clusters_layer->at(j)==3 || clusters_layer->at(j)==4)
186  {
187  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)));
188  }
189  if(clusters_layer->at(j)==5 || clusters_layer->at(j)==6)
190  {
191  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)));
192  }
193  }
194  for(auto& cluster1 : layer1_clusters)
195  {
196  for(auto& cluster2: layer2_clusters)
197  {
198  if(fabs(cluster1->Phi()-cluster2->Phi())<dphi_cut && fabs(cluster1->posZ()-cluster2->posZ())<5.)
199  {
200  tracklets.push_back(std::make_pair(cluster1,cluster2));
201  }
202  }
203  }
204  }
205 
207  Beamspot BS = fit_PCAD0Phi0(tracklets,origin,100.);
208  //BS = fit_PCAD0Phi0(tracklets,BS,0.5);
209  //BS = fit_PCAD0Phi0(tracklets,BS,0.2);
210  //BS = fit_PCAD0Phi0(tracklets,BS,0.1);
211 
212  t->Branch("x",&BS.x);
213  t->Branch("y",&BS.y);
214  t->Branch("z",&BS.z);
215  t->Branch("sigma_x",&BS.sigma_x);
216  t->Branch("sigma_y",&BS.sigma_y);
217  t->Branch("sigma_z",&BS.sigma_z);
218  t->Branch("xy_correlation",&BS.xy_correlation);
219  t->Branch("Ntracklets",&BS.Ntracklets);
220 
221  t->Fill();
222  t->Write();
223 
224  BS.d0phi0dist->Write("d0phi0dist",TObject::kOverwrite);
225  BS.z0dist->Write("z0dist",TObject::kOverwrite);
226  BS.pcadist->Write("pcadist",TObject::kOverwrite);
227 
228  BS.identify();
229 
230  outf->Close();
231 
232  return 0;
233 }