File indexing completed on 2025-08-05 08:18:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "PHG4TpcDistortion.h"
0012
0013 #include <TFile.h>
0014 #include <TH3.h>
0015 #include <TTree.h>
0016
0017 #include <cmath> // for sqrt, fabs, NAN
0018 #include <cstdlib> // for exit
0019 #include <iostream>
0020
0021 namespace
0022 {
0023 template <class T>
0024 inline constexpr T square(const T& x)
0025 {
0026 return x * x;
0027 }
0028
0029
0030
0031 inline bool check_boundaries(const TAxis* axis, double value)
0032 {
0033 const auto bin = axis->FindBin(value);
0034 return (bin >= 2 && bin < axis->GetNbins());
0035 }
0036
0037
0038
0039 inline bool check_boundaries(const TH3* h, double r, double phi, double z)
0040 {
0041 return check_boundaries(h->GetXaxis(), r) && check_boundaries(h->GetYaxis(), phi) && check_boundaries(h->GetZaxis(), z);
0042 }
0043
0044
0045 [[maybe_unused]] void print_histogram(TH3* h)
0046 {
0047 std::cout << "PHG4TpcDistortion::print_histogram - name: " << h->GetName() << std::endl;
0048 for (const auto& axis : {h->GetXaxis(), h->GetYaxis(), h->GetZaxis()})
0049 {
0050 std::cout
0051 << " " << axis->GetName()
0052 << " bins: " << axis->GetNbins()
0053 << " min: " << axis->GetXmin()
0054 << " max: " << axis->GetXmax()
0055 << std::endl;
0056 }
0057 std::cout << std::endl;
0058 }
0059
0060 }
0061
0062
0063 void PHG4TpcDistortion::Init()
0064 {
0065 std::cout << "PHG4TpcDistortion::Init - m_phi_hist_in_radians: " << m_phi_hist_in_radians << std::endl;
0066
0067 if (m_do_static_distortions)
0068 {
0069 std::cout << "PHG4TpcDistortion::Init - m_static_distortion_filename: " << m_static_distortion_filename << std::endl;
0070 m_static_tfile.reset(new TFile(m_static_distortion_filename.c_str()));
0071 if (!m_static_tfile->IsOpen())
0072 {
0073 std::cout << "PHG4TpcDistortion::Init - Static distortion file could not be opened!" << std::endl;
0074 exit(1);
0075 }
0076
0077
0078 hDRint[0] = dynamic_cast<TH3*>(m_static_tfile->Get("hIntDistortionR_negz"));
0079 hDRint[1] = dynamic_cast<TH3*>(m_static_tfile->Get("hIntDistortionR_posz"));
0080 hDPint[0] = dynamic_cast<TH3*>(m_static_tfile->Get("hIntDistortionP_negz"));
0081 hDPint[1] = dynamic_cast<TH3*>(m_static_tfile->Get("hIntDistortionP_posz"));
0082 hDZint[0] = dynamic_cast<TH3*>(m_static_tfile->Get("hIntDistortionZ_negz"));
0083 hDZint[1] = dynamic_cast<TH3*>(m_static_tfile->Get("hIntDistortionZ_posz"));
0084 if (m_do_ReachesReadout)
0085 {
0086 hReach[0] = dynamic_cast<TH3*>(m_static_tfile->Get("hReachesReadout_negz"));
0087 hReach[1] = dynamic_cast<TH3*>(m_static_tfile->Get("hReachesReadout_posz"));
0088 }
0089 }
0090
0091 if (m_do_time_ordered_distortions)
0092 {
0093 std::cout << "PHG4TpcDistortion::Init - m_time_ordered_distortion_filename: " << m_time_ordered_distortion_filename << std::endl;
0094 m_time_ordered_tfile.reset(new TFile(m_time_ordered_distortion_filename.c_str()));
0095 if (!m_time_ordered_tfile->IsOpen())
0096 {
0097 std::cout << "PHG4TpcDistortion::Init - TimeOrdered distortion file could not be opened!" << std::endl;
0098 exit(1);
0099 }
0100
0101 TimeTree = static_cast<TTree*>(m_time_ordered_tfile->Get("TimeDists"));
0102 if (!TimeTree)
0103 {
0104 std::cout << "PHG4TpcDistortion::Init - TimeOrdered distortion tree could not be found!" << std::endl;
0105 exit(1);
0106 }
0107
0108
0109 TimehDR[0] = new TH3F();
0110 TimehDR[1] = new TH3F();
0111 TimehDP[0] = new TH3F();
0112 TimehDP[1] = new TH3F();
0113 TimehDZ[0] = new TH3F();
0114 TimehDZ[1] = new TH3F();
0115 TimehRR[0] = new TH3F();
0116 TimehRR[1] = new TH3F();
0117
0118
0119 TimeTree->SetBranchAddress("hIntDistortionR_negz", &(TimehDR[0]));
0120 TimeTree->SetBranchAddress("hIntDistortionR_posz", &(TimehDR[1]));
0121 TimeTree->SetBranchAddress("hIntDistortionP_negz", &(TimehDP[0]));
0122 TimeTree->SetBranchAddress("hIntDistortionP_posz", &(TimehDP[1]));
0123 TimeTree->SetBranchAddress("hIntDistortionZ_negz", &(TimehDZ[0]));
0124 TimeTree->SetBranchAddress("hIntDistortionZ_posz", &(TimehDZ[1]));
0125 if (m_do_ReachesReadout)
0126 {
0127 TimeTree->SetBranchAddress("hReachesReadout_negz", &(TimehRR[0]));
0128 TimeTree->SetBranchAddress("hReachesReadout_posz", &(TimehRR[1]));
0129 }
0130 }
0131 }
0132
0133
0134 void PHG4TpcDistortion::load_event(int event_num)
0135 {
0136 if (TimeTree)
0137 {
0138 int nentries = TimeTree->GetEntries();
0139 if (event_num > nentries)
0140 {
0141 event_num = event_num % nentries;
0142 }
0143 if (event_num % nentries == 0 && event_num != 0)
0144 {
0145 std::cout << "Distortion map sequence repeating as of event number " << event_num << std::endl;
0146 }
0147 TimeTree->GetEntry(event_num);
0148 }
0149
0150 return;
0151 }
0152
0153
0154 double PHG4TpcDistortion::get_x_distortion_cartesian(double x, double y, double z) const
0155 {
0156 double r = sqrt(x * x + y * y);
0157 double phi = std::atan2(y, x);
0158
0159
0160 double dr = get_distortion('r', r, phi, z);
0161 double dphi = get_distortion('p', r, phi, z);
0162
0163
0164 double cosphi = cos(phi);
0165 double sinphi = sin(phi);
0166 double dx = dr * cosphi - dphi * sinphi;
0167 return dx;
0168 }
0169
0170
0171 double PHG4TpcDistortion::get_y_distortion_cartesian(double x, double y, double z) const
0172 {
0173 double r = sqrt(x * x + y * y);
0174 double phi = std::atan2(y, x);
0175
0176
0177 double dr = get_distortion('r', r, phi, z);
0178 double dphi = get_distortion('p', r, phi, z);
0179
0180
0181 double cosphi = cos(phi);
0182 double sinphi = sin(phi);
0183 double dy = dphi * cosphi + dr * sinphi;
0184 return dy;
0185 }
0186
0187
0188 double PHG4TpcDistortion::get_z_distortion_cartesian(double x, double y, double z) const
0189 {
0190 double r = sqrt(x * x + y * y);
0191 double phi = std::atan2(y, x);
0192
0193
0194 double dz = get_distortion('z', r, phi, z);
0195
0196 return dz;
0197 }
0198
0199
0200 double PHG4TpcDistortion::get_r_distortion(double r, double phi, double z) const
0201 {
0202 return get_distortion('r', r, phi, z);
0203 }
0204
0205
0206 double PHG4TpcDistortion::get_rphi_distortion(double r, double phi, double z) const
0207 {
0208 if (m_phi_hist_in_radians)
0209 {
0210 return r * get_distortion('p', r, phi, z);
0211 }
0212
0213 return get_distortion('p', r, phi, z);
0214 }
0215
0216
0217 double PHG4TpcDistortion::get_z_distortion(double r, double phi, double z) const
0218 {
0219 return get_distortion('z', r, phi, z);
0220 }
0221
0222 double PHG4TpcDistortion::get_reaches_readout(double r, double phi, double z) const
0223 {
0224 if (m_do_ReachesReadout)
0225 {
0226 return get_distortion('R', r, phi, z);
0227 }
0228 else
0229 {
0230 return 1;
0231 }
0232 }
0233
0234 double PHG4TpcDistortion::get_distortion(char axis, double r, double phi, double z) const
0235 {
0236 if (phi < 0)
0237 {
0238 phi += 2 * M_PI;
0239 }
0240 const int zpart = (z > 0 ? 1 : 0);
0241
0242 TH3* hdistortion = nullptr;
0243
0244 if (axis != 'r' && axis != 'p' && axis != 'z' && axis != 'R')
0245 {
0246 std::cout << "Distortion Requested along axis " << axis << " which is invalid. Exiting.\n"
0247 << std::endl;
0248 exit(1);
0249 }
0250
0251 double _distortion = 0.;
0252
0253
0254 if (m_do_static_distortions)
0255 {
0256 if (axis == 'r')
0257 {
0258 hdistortion = hDRint[zpart];
0259 }
0260 else if (axis == 'p')
0261 {
0262 hdistortion = hDPint[zpart];
0263 }
0264 else if (axis == 'z')
0265 {
0266 hdistortion = hDZint[zpart];
0267 }
0268 else if (axis == 'R')
0269 {
0270 hdistortion = hReach[zpart];
0271 }
0272 if (hdistortion)
0273 {
0274 if (check_boundaries(hdistortion, phi, r, z))
0275 {
0276 _distortion += hdistortion->Interpolate(phi, r, z);
0277 }
0278 }
0279 else
0280 {
0281 std::cout << "Static Distortion Requested along axis " << axis << ", but distortion map does not exist. Exiting.\n"
0282 << std::endl;
0283 exit(1);
0284 }
0285 }
0286
0287 if (m_do_time_ordered_distortions)
0288 {
0289 if (axis == 'r')
0290 {
0291 hdistortion = TimehDR[zpart];
0292 }
0293 else if (axis == 'p')
0294 {
0295 hdistortion = TimehDP[zpart];
0296 }
0297 else if (axis == 'z')
0298 {
0299 hdistortion = TimehDZ[zpart];
0300 }
0301 else if (axis == 'R')
0302 {
0303 hdistortion = TimehRR[zpart];
0304 }
0305 if (hdistortion)
0306 {
0307 if (check_boundaries(hdistortion, phi, r, z))
0308 {
0309 _distortion += hdistortion->Interpolate(phi, r, z);
0310 }
0311 }
0312 else
0313 {
0314 std::cout << "Time Series Distortion Requested along axis " << axis << ", but distortion map does not exist. Exiting.\n"
0315 << std::endl;
0316 exit(1);
0317 }
0318 }
0319
0320 return _distortion;
0321 }