File indexing completed on 2026-07-16 08:15:15
0001 #include "PHG4TpcGeomv2.h"
0002 #include "PHG4CylinderCellDefs.h"
0003
0004 #include <phool/phool.h>
0005
0006 #include <cstdlib>
0007
0008 namespace
0009 {
0010
0011 using array_t = std::array<std::vector<double>, PHG4TpcGeomv2::NSides>;
0012 std::ostream& operator<<(std::ostream& out, const array_t& array)
0013 {
0014 out << "{ ";
0015 for (const auto& iside : array)
0016 {
0017 out << "{";
0018 bool first = true;
0019 for (const auto& value : iside)
0020 {
0021 if (!first)
0022 {
0023 out << ", ";
0024 }
0025 first = false;
0026 out << value;
0027 }
0028 out << "} ";
0029 }
0030 out << " }";
0031 return out;
0032 }
0033 }
0034
0035 std::ostream& operator<<(std::ostream& out, const PHG4TpcGeomv2& geom)
0036 {
0037 out << "PHG4TpcGeomv2 - layer: " << geom.layer << std::endl;
0038 out
0039 << " binnig: " << geom.binning
0040 << ", radius: " << geom.radius
0041 << ", nzbins: " << geom.nzbins
0042 << ", zmin: " << geom.zmin
0043 << ", zstep: " << geom.zstep
0044 << ", nphibins: " << geom.nphibins
0045 << ", phimin: " << geom.phimin
0046 << ", phistep: " << geom.phistep
0047 << ", thickness: " << geom.thickness
0048 << std::endl;
0049
0050 out << " sector_R_bias: " << geom.sector_R_bias << std::endl;
0051 out << " sector_Phi_bias: " << geom.sector_Phi_bias << std::endl;
0052 out << " sector_min_Phi: " << geom.sector_min_Phi << std::endl;
0053 out << " sector_max_Phi: " << geom.sector_max_Phi << std::endl;
0054
0055 return out;
0056 }
0057
0058 void PHG4TpcGeomv2::set_zbins(const int i)
0059 {
0060 check_binning_method(PHG4CylinderCellDefs::sizebinning);
0061 nzbins = i;
0062 }
0063
0064 void PHG4TpcGeomv2::set_zmin(const double z)
0065 {
0066 check_binning_method(PHG4CylinderCellDefs::sizebinning);
0067 zmin = z;
0068 }
0069
0070 int PHG4TpcGeomv2::get_zbins() const
0071 {
0072 check_binning_method(PHG4CylinderCellDefs::sizebinning);
0073 return nzbins;
0074 }
0075
0076 double
0077 PHG4TpcGeomv2::get_zmin() const
0078 {
0079 check_binning_method(PHG4CylinderCellDefs::sizebinning);
0080 return zmin;
0081 }
0082
0083 double
0084 PHG4TpcGeomv2::get_zstep() const
0085 {
0086 check_binning_method(PHG4CylinderCellDefs::sizebinning);
0087 return zstep;
0088 }
0089
0090 void PHG4TpcGeomv2::set_zstep(const double z)
0091 {
0092 check_binning_method(PHG4CylinderCellDefs::sizebinning);
0093 zstep = z;
0094 }
0095
0096 int PHG4TpcGeomv2::get_phibins() const
0097 {
0098 check_binning_method_phi("PHG4TpcGeomv2::get_phibins");
0099 return nphibins;
0100 }
0101
0102 double
0103 PHG4TpcGeomv2::get_phistep() const
0104 {
0105 check_binning_method_phi("PHG4TpcGeomv2::get_phistep");
0106 return phistep;
0107 }
0108
0109 double
0110 PHG4TpcGeomv2::get_phimin() const
0111 {
0112 check_binning_method_phi("PHG4TpcGeomv2::get_phimin");
0113 return phimin;
0114 }
0115
0116 void PHG4TpcGeomv2::set_phibins(const int i)
0117 {
0118 check_binning_method_phi("PHG4TpcGeomv2::set_phibins");
0119 nphibins = i;
0120 }
0121
0122 void PHG4TpcGeomv2::set_phistep(const double phi)
0123 {
0124 check_binning_method_phi("PHG4TpcGeomv2::set_phistep");
0125 phistep = phi;
0126 }
0127
0128 void PHG4TpcGeomv2::set_phimin(const double phi)
0129 {
0130 check_binning_method_phi("PHG4TpcGeomv2::set_phimin");
0131 phimin = phi;
0132 }
0133
0134 int PHG4TpcGeomv2::get_etabins() const
0135 {
0136 check_binning_method_eta("PHG4TpcGeomv2::get_etabins");
0137 return nzbins;
0138 }
0139
0140 double
0141 PHG4TpcGeomv2::get_etastep() const
0142 {
0143 check_binning_method_eta("PHG4TpcGeomv2::get_etastep");
0144 return zstep;
0145 }
0146 double
0147 PHG4TpcGeomv2::get_etamin() const
0148 {
0149 check_binning_method_eta("PHG4TpcGeomv2::get_etamin");
0150 return zmin;
0151 }
0152
0153 void PHG4TpcGeomv2::set_etamin(const double z)
0154 {
0155 check_binning_method_eta("PHG4TpcGeomv2::set_etamin");
0156 zmin = z;
0157 }
0158
0159 void PHG4TpcGeomv2::set_etastep(const double z)
0160 {
0161 check_binning_method_eta("PHG4TpcGeomv2::set_etastep");
0162 zstep = z;
0163 }
0164
0165 void PHG4TpcGeomv2::set_etabins(const int i)
0166 {
0167 check_binning_method_eta("PHG4TpcGeomv2::set_etabins");
0168 nzbins = i;
0169 }
0170
0171 void PHG4TpcGeomv2::identify(std::ostream& os) const
0172 {
0173 os << "PHG4TpcGeomv2::identify - layer: " << layer << std::endl;
0174
0175 os
0176 << " binning: " << binning
0177 << ", radius: " << radius
0178 << ", nzbins: " << nzbins
0179 << ", zmin: " << zmin
0180 << ", zstep: " << zstep
0181 << ", nphibins: " << nphibins
0182 << ", phimin: " << phimin
0183 << ", phistep: " << phistep
0184 << ", thickness: " << thickness
0185 << std::endl;
0186
0187 os << " sector_R_bias: " << sector_R_bias << std::endl;
0188 os << " sector_Phi_bias: " << sector_Phi_bias << std::endl;
0189 os << " sector_min_Phi: " << sector_min_Phi << std::endl;
0190 os << " sector_max_Phi: " << sector_max_Phi << std::endl;
0191
0192 os << " rotation: rot_x " << rot_x << " rot_y " << rot_y << " rot_z " << rot_z << std::endl;
0193 os << " translation: place_x " << place_x << " place_y " << place_y << " place_z " << place_z << std::endl;
0194 }
0195
0196 std::pair<double, double>
0197 PHG4TpcGeomv2::get_zbounds(const int ibin) const
0198 {
0199 if (ibin < 0 || ibin >= nzbins)
0200 {
0201 std::cout << PHWHERE << " Asking for invalid bin in z: " << ibin << std::endl;
0202 exit(1);
0203 }
0204 check_binning_method(PHG4CylinderCellDefs::sizebinning);
0205 double zlow = zmin + ibin * zstep;
0206 double zhigh = zlow + zstep;
0207 return std::make_pair(zlow, zhigh);
0208 }
0209
0210 std::pair<double, double>
0211 PHG4TpcGeomv2::get_etabounds(const int ibin) const
0212 {
0213 if (ibin < 0 || ibin >= nzbins)
0214 {
0215 std::cout << PHWHERE << " Asking for invalid bin in z: " << ibin << std::endl;
0216 exit(1);
0217 }
0218 check_binning_method_eta("PHG4TpcGeomv2::get_etabounds");
0219
0220 double zlow = zmin + ibin * zstep;
0221 double zhigh = zlow + zstep;
0222 return std::make_pair(zlow, zhigh);
0223 }
0224
0225 std::pair<double, double>
0226 PHG4TpcGeomv2::get_phibounds(const int ibin) const
0227 {
0228 if (ibin < 0 || ibin >= nphibins)
0229 {
0230 std::cout << PHWHERE << "Asking for invalid bin in phi: " << ibin << std::endl;
0231 exit(1);
0232 }
0233
0234 double philow = phimin + ibin * phistep;
0235 double phihigh = philow + phistep;
0236 return std::make_pair(philow, phihigh);
0237 }
0238
0239 int PHG4TpcGeomv2::get_zbin(const double z) const
0240 {
0241 if (z < zmin || z >= (zmin + nzbins * zstep))
0242 {
0243
0244 return -1;
0245 }
0246
0247 check_binning_method(PHG4CylinderCellDefs::sizebinning);
0248 return floor((z - zmin) / zstep);
0249 }
0250
0251 int PHG4TpcGeomv2::get_etabin(const double eta) const
0252 {
0253 if (eta < zmin || eta >= (zmin + nzbins * zstep))
0254 {
0255
0256 return -1;
0257 }
0258 check_binning_method_eta();
0259 return floor((eta - zmin) / zstep);
0260 }
0261
0262 int PHG4TpcGeomv2::get_phibin_new(const double phi) const
0263 {
0264 double norm_phi = phi;
0265 if (phi < phimin || phi >= (phimin + nphibins * phistep))
0266 {
0267 int nwraparound = -floor((phi - phimin) * 0.5 / M_PI);
0268 norm_phi += 2 * M_PI * nwraparound;
0269 }
0270 check_binning_method_phi();
0271 return floor((norm_phi - phimin) / phistep);
0272 }
0273
0274 int PHG4TpcGeomv2::find_phibin(const double phi, int side) const
0275 {
0276 if(side < 0 || side > 1)
0277 {
0278 std::cout << PHWHERE << " side is not valid, have to quit!" << std::endl;
0279 exit(1);
0280 }
0281
0282 double norm_phi = phi;
0283 if (phi < phimin || phi >= (phimin + nphibins * phistep))
0284 {
0285 int nwraparound = -floor((phi - phimin) * 0.5 / M_PI);
0286 norm_phi += 2 * M_PI * nwraparound;
0287 }
0288
0289
0290
0291
0292
0293
0294
0295
0296 int phi_bin = -1;
0297
0298 for (std::size_t s = 0; s < sector_max_Phi[side].size(); s++)
0299 {
0300 if (norm_phi < sector_max_Phi[side][s] && norm_phi > sector_min_Phi[side][s])
0301 {
0302
0303 phi_bin = (floor(std::abs(sector_max_Phi[side][s] - norm_phi) / phistep) + nphibins / 12 * s);
0304 break;
0305 }
0306 if (s == 11)
0307 {
0308 if (norm_phi < sector_max_Phi[side][s] && norm_phi >= -M_PI)
0309 {
0310
0311 phi_bin = floor(std::abs(sector_max_Phi[side][s] - norm_phi) / phistep) + nphibins / 12 * s;
0312 break;
0313 }
0314 if (norm_phi > sector_min_Phi[side][s] + 2 * M_PI)
0315 {
0316
0317 phi_bin = floor(std::abs(sector_max_Phi[side][s] - (norm_phi - 2 * M_PI)) / phistep) + nphibins / 12 * s;
0318 break;
0319 }
0320 }
0321 }
0322 return phi_bin;
0323 }
0324
0325 float PHG4TpcGeomv2::get_pad_float(const double phi, int side) const
0326 {
0327 if(side < 0 || side > 1)
0328 {
0329 std::cout << PHWHERE << " side is not valid, have to quit!" << std::endl;
0330 exit(1);
0331 }
0332
0333 double norm_phi = phi;
0334 if (phi < phimin || phi >= (phimin + nphibins * phistep))
0335 {
0336 int nwraparound = -floor((phi - phimin) * 0.5 / M_PI);
0337 norm_phi += 2 * M_PI * nwraparound;
0338 }
0339
0340
0341
0342
0343
0344
0345
0346
0347 float phi_bin = -1;
0348
0349 for (std::size_t s = 0; s < sector_max_Phi[side].size(); s++)
0350 {
0351 if (norm_phi < sector_max_Phi[side][s] && norm_phi > sector_min_Phi[side][s])
0352 {
0353
0354 phi_bin = (std::abs(sector_max_Phi[side][s] - norm_phi) / phistep) + nphibins / 12 * s;
0355 break;
0356 }
0357 if (s == 11)
0358 {
0359 if (norm_phi < sector_max_Phi[side][s] && norm_phi >= -M_PI)
0360 {
0361
0362 phi_bin = (std::abs(sector_max_Phi[side][s] - norm_phi) / phistep) + nphibins / 12 * s;
0363 break;
0364 }
0365 if (norm_phi > sector_min_Phi[side][s] + 2 * M_PI)
0366 {
0367
0368 phi_bin = (std::abs(sector_max_Phi[side][s] - (norm_phi - 2 * M_PI)) / phistep) + nphibins / 12 * s;
0369 break;
0370 }
0371 }
0372 }
0373 return phi_bin - 0.5;
0374 }
0375
0376 float PHG4TpcGeomv2::get_tbin_float(const double z) const
0377 {
0378 if (z < zmin || z >= (zmin + nzbins * zstep))
0379 {
0380
0381 return -1;
0382 }
0383
0384 check_binning_method(PHG4CylinderCellDefs::sizebinning);
0385 return ((z - zmin) / zstep) - 0.5;
0386 }
0387
0388 int PHG4TpcGeomv2::get_phibin(const double phi, int side) const
0389 {
0390 if(side < 0 || side > 1)
0391 {
0392 std::cout << PHWHERE << " side is not valid, have to quit!" << std::endl;
0393 exit(1);
0394 }
0395
0396 double new_phi = phi;
0397 if (phi > M_PI)
0398 {
0399 new_phi = phi - 2 * M_PI;
0400 }
0401 if (phi < phimin)
0402 {
0403 new_phi = phi + 2 * M_PI;
0404 }
0405
0406 int phi_bin = find_phibin(new_phi, side);
0407
0408
0409
0410 if (phi_bin < 0)
0411 {
0412
0413 for (std::size_t s = 0; s < sector_max_Phi[side].size(); s++)
0414 {
0415 double daPhi = 0;
0416 if (s == 0)
0417 {
0418 daPhi = fabs(sector_min_Phi[side][11] + 2 * M_PI - sector_max_Phi[side][s]);
0419 }
0420 else
0421 {
0422 daPhi = fabs(sector_min_Phi[side][s - 1] - sector_max_Phi[side][s]);
0423 }
0424
0425 double min_phi = sector_max_Phi[side][s];
0426 double max_phi = sector_max_Phi[side][s] + daPhi;
0427 if (new_phi <= max_phi && new_phi >= min_phi)
0428 {
0429 if (fabs(max_phi - new_phi) > fabs(new_phi - min_phi))
0430 {
0431 new_phi = min_phi - phistep / 5;
0432 }
0433 else
0434 {
0435 new_phi = max_phi + phistep / 5;
0436 }
0437 }
0438 }
0439
0440
0441 phi_bin = find_phibin(new_phi, side);
0442 if (phi_bin < 0)
0443 {
0444 std::cout << PHWHERE << "Asking for bin for phi outside of phi range: " << phi << std::endl;
0445 exit(1);
0446
0447 }
0448 }
0449 return phi_bin;
0450 }
0451
0452 double
0453 PHG4TpcGeomv2::get_zcenter(const int ibin) const
0454 {
0455 if (ibin < 0 || ibin >= nzbins)
0456 {
0457 std::cout << PHWHERE << "Asking for invalid bin in z: " << ibin << std::endl;
0458 exit(1);
0459 }
0460 check_binning_method(PHG4CylinderCellDefs::sizebinning);
0461 return zmin + (ibin + 0.5) * zstep;
0462 }
0463
0464 double
0465 PHG4TpcGeomv2::get_etacenter(const int ibin) const
0466 {
0467 if (ibin < 0 || ibin >= nzbins)
0468 {
0469 std::cout << PHWHERE << "Asking for invalid bin in eta: " << ibin << std::endl;
0470 std::cout << "minbin: 0, maxbin " << nzbins << std::endl;
0471 exit(1);
0472 }
0473 check_binning_method_eta();
0474 return zmin + (ibin + 0.5) * zstep;
0475 }
0476
0477 double
0478 PHG4TpcGeomv2::get_phicenter_new(const int ibin) const
0479 {
0480 if (ibin < 0 || ibin >= nphibins)
0481 {
0482 std::cout << PHWHERE << "Asking for invalid bin in phi: " << ibin << std::endl;
0483 exit(1);
0484 }
0485
0486 check_binning_method_phi();
0487
0488 return (phimin + (ibin + 0.5) * phistep);
0489 }
0490
0491 double
0492 PHG4TpcGeomv2::get_phicenter(const int ibin, const int side) const
0493 {
0494 if(side < 0 || side > 1)
0495 {
0496 std::cout << PHWHERE << " side is not valid, have to quit!" << std::endl;
0497 exit(1);
0498 }
0499
0500
0501 if (ibin < 0 || ibin >= nphibins)
0502 {
0503 std::cout << PHWHERE << "Asking for invalid bin in phi: " << ibin << std::endl;
0504 exit(1);
0505 }
0506
0507 check_binning_method_phi();
0508
0509
0510 unsigned int pads_per_sector = nphibins / 12;
0511 unsigned int sector = ibin / pads_per_sector;
0512 double phi_center = (sector_max_Phi[side][sector] - (ibin + 0.5 - sector * pads_per_sector) * phistep);
0513 if (phi_center <= -M_PI)
0514 {
0515 phi_center += 2 * M_PI;
0516 }
0517 return phi_center;
0518 }
0519
0520 double
0521 PHG4TpcGeomv2::get_phi(const float ibin, const int side) const
0522 {
0523 if(side < 0 || side > 1)
0524 {
0525 std::cout << PHWHERE << " side is not valid, have to quit!" << std::endl;
0526 exit(1);
0527 }
0528
0529
0530 if (ibin < 0 || ibin >= nphibins)
0531 {
0532 std::cout << PHWHERE << "Asking for invalid bin in phi: " << ibin << std::endl;
0533 exit(1);
0534 }
0535
0536 check_binning_method_phi();
0537
0538
0539 unsigned int pads_per_sector = nphibins / 12;
0540 unsigned int sector = ibin / pads_per_sector;
0541 double phi = (sector_max_Phi[side][sector] - (ibin + 0.5 - sector * pads_per_sector) * phistep);
0542 if (phi <= -M_PI)
0543 {
0544 phi += 2 * M_PI;
0545 }
0546 return phi;
0547 }
0548
0549 std::string
0550 PHG4TpcGeomv2::methodname(const int i) const
0551 {
0552 switch (i)
0553 {
0554 case PHG4CylinderCellDefs::sizebinning:
0555 return "Bins in cm";
0556 break;
0557 case PHG4CylinderCellDefs::etaphibinning:
0558 return "Eta/Phi bins";
0559 break;
0560 case PHG4CylinderCellDefs::etaslatbinning:
0561 return "Eta/numslat bins";
0562 break;
0563 case PHG4CylinderCellDefs::spacalbinning:
0564 return "SPACAL Tower bins";
0565 break;
0566 default:
0567 break;
0568 }
0569 return "Unknown";
0570 }
0571
0572 void PHG4TpcGeomv2::check_binning_method(const int i) const
0573 {
0574 if (binning != i)
0575 {
0576 std::cout << "different binning method used " << methodname(binning)
0577 << ", not : " << methodname(i)
0578 << std::endl;
0579 exit(1);
0580 }
0581 return;
0582 }
0583
0584 void PHG4TpcGeomv2::check_binning_method_eta(const std::string& src) const
0585 {
0586 if (binning != PHG4CylinderCellDefs::etaphibinning &&
0587 binning != PHG4CylinderCellDefs::etaslatbinning &&
0588 binning != PHG4CylinderCellDefs::spacalbinning)
0589 {
0590 if (!src.empty())
0591 {
0592 std::cout << src << " : ";
0593 }
0594
0595 std::cout << "different binning method used " << methodname(binning)
0596 << ", not : " << methodname(PHG4CylinderCellDefs::etaphibinning)
0597 << " or " << methodname(PHG4CylinderCellDefs::etaslatbinning)
0598 << " or " << methodname(PHG4CylinderCellDefs::spacalbinning)
0599 << std::endl;
0600 exit(1);
0601 }
0602 return;
0603 }
0604
0605 void PHG4TpcGeomv2::check_binning_method_phi(const std::string& src) const
0606 {
0607 if (binning != PHG4CylinderCellDefs::etaphibinning &&
0608 binning != PHG4CylinderCellDefs::sizebinning &&
0609 binning != PHG4CylinderCellDefs::etaslatbinning &&
0610 binning != PHG4CylinderCellDefs::spacalbinning)
0611 {
0612 if (!src.empty())
0613 {
0614 std::cout << src << " : ";
0615 }
0616
0617 std::cout << "different binning method used " << methodname(binning)
0618 << ", not : " << methodname(PHG4CylinderCellDefs::etaphibinning)
0619 << " or " << methodname(PHG4CylinderCellDefs::sizebinning)
0620 << " or " << methodname(PHG4CylinderCellDefs::etaslatbinning)
0621 << " or " << methodname(PHG4CylinderCellDefs::spacalbinning)
0622 << std::endl;
0623 exit(1);
0624 }
0625 return;
0626 }