Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4TpcDistortion.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4TpcDistortion.cc
1 // $Id: $
2 
11 #include "PHG4TpcDistortion.h"
12 
13 #include <TFile.h>
14 #include <TH3.h>
15 #include <TTree.h>
16 
17 #include <cmath> // for sqrt, fabs, NAN
18 #include <cstdlib> // for exit
19 #include <iostream>
20 
21 namespace
22 {
23  template <class T>
24  inline constexpr T square(const T& x)
25  {
26  return x * x;
27  }
28 
29  // check boundaries in axis
30  /* for the interpolation to work, the value must be within the range of the provided axis, and not into the first and last bin */
31  inline bool check_boundaries( const TAxis* axis, double value )
32  {
33  const auto bin = axis->FindBin( value );
34  return( bin >= 2 && bin < axis->GetNbins() );
35  }
36 
37  // check boundaries in histogram, before interpolation
38  /* for the interpolation to work, the value must be within the range of the provided axis, and not into the first and last bin */
39  inline bool check_boundaries( const TH3* h, double r, double phi, double z )
40  {
41  return check_boundaries( h->GetXaxis(), r )
42  && check_boundaries( h->GetYaxis(), phi )
43  && check_boundaries( h->GetZaxis(), z );
44  }
45 
46 } // namespace
47 
48 //__________________________________________________________________________________________________________
50 {
52  {
53  std::cout << "PHG4TpcDistortion::Init - m_static_distortion_filename: " << m_static_distortion_filename << std::endl;
54  m_static_tfile.reset(new TFile(m_static_distortion_filename.c_str()));
55  if (!m_static_tfile->IsOpen())
56  {
57  std::cout << "Static distortion file could not be opened!" << std::endl;
58  exit(1);
59  }
60 
61  //Open Static Space Charge Maps
62  hDRint[0] = dynamic_cast<TH3*>(m_static_tfile->Get("hIntDistortionR_negz"));
63  hDRint[1] = dynamic_cast<TH3*>(m_static_tfile->Get("hIntDistortionR_posz"));
64  hDPint[0] = dynamic_cast<TH3*>(m_static_tfile->Get("hIntDistortionP_negz"));
65  hDPint[1] = dynamic_cast<TH3*>(m_static_tfile->Get("hIntDistortionP_posz"));
66  hDZint[0] = dynamic_cast<TH3*>(m_static_tfile->Get("hIntDistortionZ_negz"));
67  hDZint[1] = dynamic_cast<TH3*>(m_static_tfile->Get("hIntDistortionZ_posz"));
68  //not ready yet: hReach[0] = dynamic_cast<TH3*>(m_static_tfile->Get("hReachesReadout_negz"));
69  //not ready yet: hReach[1] = dynamic_cast<TH3*>(m_static_tfile->Get("hReachesReadout_posz"));
70  }
71 
73  {
74  std::cout << "PHG4TpcDistortion::Init - m_time_ordered_distortion_filename: " << m_time_ordered_distortion_filename << std::endl;
76  if (!m_time_ordered_tfile->IsOpen())
77  {
78  std::cout << "TimeOrdered distortion file could not be opened!" << std::endl;
79  exit(1);
80  }
81 
82  // create histograms
83  TimehDR[0] = new TH3F();
84  TimehDR[1] = new TH3F();
85  TimehDP[0] = new TH3F();
86  TimehDP[1] = new TH3F();
87  TimehDZ[0] = new TH3F();
88  TimehDZ[1] = new TH3F();
89  TimehRR[0] = new TH3F();//RR stands for ReachesReadout
90  TimehRR[1] = new TH3F();//RR stands for ReachesReadout
91 
92  TimeTree = static_cast<TTree*>(m_time_ordered_tfile->Get("TimeDists"));
93  TimeTree->SetBranchAddress("hIntDistortionR_negz", &(TimehDR[0]));
94  TimeTree->SetBranchAddress("hIntDistortionR_posz", &(TimehDR[1]));
95  TimeTree->SetBranchAddress("hIntDistortionP_negz", &(TimehDP[0]));
96  TimeTree->SetBranchAddress("hIntDistortionP_posz", &(TimehDP[1]));
97  TimeTree->SetBranchAddress("hIntDistortionZ_negz", &(TimehDZ[0]));
98  TimeTree->SetBranchAddress("hIntDistortionZ_posz", &(TimehDZ[1]));
99  //not ready yet: TimeTree->SetBranchAddress("hReachesReadout_negz", &(TimehRR[0]));
100  //not ready yet: TimeTree->SetBranchAddress("hReachesReadout_posz", &(TimehRR[1]));
101  }
102 }
103 
104 //__________________________________________________________________________________________________________
105 void PHG4TpcDistortion::load_event(int event_num)
106 {
107  if (TimeTree)
108  {
109  int nentries = TimeTree->GetEntries();
110  if (event_num > nentries) event_num = event_num % nentries;
111  if (event_num % nentries == 0 && event_num != 0)
112  {
113  std::cout << "Distortion map sequence repeating as of event number " << event_num << std::endl;
114  }
115  TimeTree->GetEntry(event_num);
116  }
117 
118  return;
119 }
120 
121 //__________________________________________________________________________________________________________
122 double PHG4TpcDistortion::get_x_distortion_cartesian(double x, double y, double z) const
123 {
124  double r = sqrt(x * x + y * y);
125  double phi = std::atan2(y, x);
126 
127  //get components
128  double dr = get_distortion('r', r, phi, z);
129  double dphi = get_distortion('p', r, phi, z);
130 
131  //rotate into cartesian based on local r phi:
132  double cosphi = cos(phi);
133  double sinphi = sin(phi);
134  double dx = dr * cosphi - dphi * sinphi;
135  return dx;
136 }
137 
138 //__________________________________________________________________________________________________________
139 double PHG4TpcDistortion::get_y_distortion_cartesian(double x, double y, double z) const
140 {
141  double r = sqrt(x * x + y * y);
142  double phi = std::atan2(y, x);
143 
144  //get components
145  double dr = get_distortion('r', r, phi, z);
146  double dphi = get_distortion('p', r, phi, z);
147 
148  //rotate into cartesian based on local r phi:
149  double cosphi = cos(phi);
150  double sinphi = sin(phi);
151  double dy = dphi * cosphi + dr * sinphi;
152  return dy;
153 }
154 
155 //__________________________________________________________________________________________________________
156 double PHG4TpcDistortion::get_z_distortion_cartesian(double x, double y, double z) const
157 {
158  double r = sqrt(x * x + y * y);
159  double phi = std::atan2(y, x);
160 
161  //get components
162  double dz = get_distortion('z', r, phi, z);
163 
164  return dz;
165 }
166 
167 //__________________________________________________________________________________________________________
168 double PHG4TpcDistortion::get_r_distortion(double r, double phi, double z) const
169 {
170  return get_distortion('r', r, phi, z);
171 }
172 
173 //__________________________________________________________________________________________________________
174 double PHG4TpcDistortion::get_rphi_distortion(double r, double phi, double z) const
175 {
176  if (m_phi_hist_in_radians) //if the hist is in radians, multiply by r to get the rphi distortion
177  return r*get_distortion('p', r, phi, z);
178 
179  return get_distortion('p', r, phi, z);
180 }
181 
182 //__________________________________________________________________________________________________________
183 double PHG4TpcDistortion::get_z_distortion(double r, double phi, double z) const
184 {
185  return get_distortion('z', r, phi, z);
186 }
187 //__________________________________________________________________________________________________________
188 double PHG4TpcDistortion::get_reaches_readout(double r, double phi, double z) const
189 {
190  if (r<1) printf("Unusual R: %f. This line is to keep the compiler from complaining about unused parameters like %f and %f.\n",r,phi,z);
191  return 1;
192  //not ready yet: return get_distortion('R', r, phi, z);
193 }
194 
195 double PHG4TpcDistortion::get_distortion(char axis, double r, double phi, double z) const
196 {
197  if (phi < 0) phi += 2 * M_PI;
198  const int zpart = (z > 0 ? 1 : 0); //z<0 corresponds to the negative side, which is element 0.
199 
200  TH3* hdistortion = nullptr;
201 
202  if (axis != 'r' && axis != 'p' && axis != 'z'&& axis != 'R')
203  {
204  std::cout << "Distortion Requested along axis " << axis << " which is invalid. Exiting.\n"
205  << std::endl;
206  exit(1);
207  }
208 
209  double _distortion = 0.;
210 
211  //select the appropriate histogram:
213  {
214  if (axis == 'r')
215  {
216  hdistortion = hDRint[zpart];
217  }
218  else if (axis == 'p')
219  {
220  hdistortion = hDPint[zpart];
221  }
222  else if (axis == 'z')
223  {
224  hdistortion = hDZint[zpart];
225  }
226  else if (axis == 'R')
227  {
228  hdistortion = hReach[zpart];
229  }
230  if (hdistortion)
231  {
232  if( check_boundaries( hdistortion, phi, r, z ) )
233  { _distortion += hdistortion->Interpolate(phi, r, z); }
234  }
235  else
236  {
237  std::cout << "Static Distortion Requested along axis " << axis << ", but distortion map does not exist. Exiting.\n"
238  << std::endl;
239  exit(1);
240  }
241  }
242 
244  {
245  if (axis == 'r')
246  {
247  hdistortion = TimehDR[zpart];
248  }
249  else if (axis == 'p')
250  {
251  hdistortion = TimehDP[zpart];
252  }
253  else if (axis == 'z')
254  {
255  hdistortion = TimehDZ[zpart];
256  }
257  else if (axis == 'R')
258  {
259  hdistortion = TimehRR[zpart];
260  }
261  if (hdistortion)
262  {
263  if( check_boundaries( hdistortion, phi, r, z ) )
264  { _distortion += hdistortion->Interpolate(phi, r, z); }
265  }
266  else
267  {
268  std::cout << "Time Series Distortion Requested along axis " << axis << ", but distortion map does not exist. Exiting.\n"
269  << std::endl;
270  exit(1);
271  }
272  }
273 
274  return _distortion;
275 }