File indexing completed on 2025-12-17 09:20:33
0001 #include "PHTpcResiduals.h"
0002 #include "TpcSpaceChargeMatrixContainerv2.h"
0003
0004 #include <trackbase/ActsGeometry.h>
0005 #include <trackbase/ActsSurfaceMaps.h>
0006 #include <trackbase/ActsTrackingGeometry.h>
0007 #include <trackbase/TrkrCluster.h>
0008 #include <trackbase/TrkrClusterContainer.h>
0009
0010 #include <trackbase_historic/SvtxTrack.h>
0011 #include <trackbase_historic/SvtxTrackMap.h>
0012 #include <trackbase_historic/SvtxTrackState.h>
0013 #include <trackbase_historic/TrackSeed.h>
0014
0015 #include <micromegas/MicromegasDefs.h>
0016
0017 #include <fun4all/Fun4AllReturnCodes.h>
0018
0019 #include <phool/PHCompositeNode.h>
0020 #include <phool/getClass.h>
0021 #include <phool/phool.h>
0022
0023 #include <Acts/Definitions/TrackParametrization.hpp>
0024 #include <Acts/Definitions/Units.hpp>
0025 #include <Acts/EventData/GenericBoundTrackParameters.hpp>
0026 #include <Acts/EventData/ParticleHypothesis.hpp>
0027 #include <Acts/Surfaces/PerigeeSurface.hpp>
0028 #include <Acts/Surfaces/Surface.hpp>
0029 #include <Acts/Utilities/Result.hpp>
0030
0031 #include <TFile.h>
0032 #include <TH1.h>
0033
0034 #include <cassert>
0035 #include <iostream>
0036 #include <limits>
0037
0038 namespace
0039 {
0040
0041
0042 template <class T>
0043 constexpr T square(const T& x)
0044 {
0045 return x * x;
0046 }
0047
0048
0049 template <class T>
0050 T get_r(const T& x, const T& y)
0051 {
0052 return std::sqrt(square(x) + square(y));
0053 }
0054
0055 template <class T>
0056 constexpr T deltaPhi(const T& phi)
0057 {
0058 if (phi > M_PI)
0059 {
0060 return phi - 2. * M_PI;
0061 }
0062 if (phi <= -M_PI)
0063 {
0064 return phi + 2. * M_PI;
0065 }
0066
0067 return phi;
0068 }
0069
0070
0071
0072 constexpr double get_sector_phi(int isec)
0073 {
0074 return isec * M_PI / 6;
0075 }
0076
0077
0078 const std::vector<float> phi_rec = {get_sector_phi(9)};
0079 const std::vector<float> z_rec = {5.};
0080
0081
0082 std::vector<TrkrDefs::cluskey> get_cluster_keys(SvtxTrack* track)
0083 {
0084 std::vector<TrkrDefs::cluskey> out;
0085 for (const auto& seed : {track->get_silicon_seed(), track->get_tpc_seed()})
0086 {
0087 if (seed)
0088 {
0089 std::copy(seed->begin_cluster_keys(), seed->end_cluster_keys(), std::back_inserter(out));
0090 }
0091 }
0092 return out;
0093 }
0094
0095 std::vector<TrkrDefs::cluskey> get_state_keys(SvtxTrack* track)
0096 {
0097 std::vector<TrkrDefs::cluskey> out;
0098 for (auto state_iter = track->begin_states();
0099 state_iter != track->end_states();
0100 ++state_iter)
0101 {
0102 SvtxTrackState* tstate = state_iter->second;
0103 auto stateckey = tstate->get_cluskey();
0104 out.push_back(stateckey);
0105 }
0106 return out;
0107 }
0108
0109
0110 template <int type>
0111 int count_clusters(const std::vector<TrkrDefs::cluskey>& keys)
0112 {
0113 return std::count_if(keys.begin(), keys.end(),
0114 [](const TrkrDefs::cluskey& key)
0115 { return TrkrDefs::getTrkrId(key) == type; });
0116 }
0117
0118
0119 std::ostream& operator<<(std::ostream& out, const Acts::Vector3& v)
0120 {
0121 out << "(" << v.x() << "," << v.y() << "," << v.z() << ")";
0122 return out;
0123 }
0124
0125 }
0126
0127
0128 PHTpcResiduals::PHTpcResiduals(const std::string& name)
0129 : SubsysReco(name)
0130 , m_matrix_container(new TpcSpaceChargeMatrixContainerv2)
0131 {
0132 }
0133
0134
0135 int PHTpcResiduals::Init(PHCompositeNode* )
0136 {
0137
0138 std::cout << "PHTpcResiduals::Init - m_maxTAlpha: " << m_maxTAlpha << std::endl;
0139 std::cout << "PHTpcResiduals::Init - m_maxTBeta: " << m_maxTBeta << std::endl;
0140 std::cout << "PHTpcResiduals::Init - m_maxResidualDrphi: " << m_maxResidualDrphi << " cm" << std::endl;
0141 std::cout << "PHTpcResiduals::Init - m_maxResidualDz: " << m_maxResidualDz << " cm" << std::endl;
0142 std::cout << "PHTpcResiduals::Init - m_minRPhiErr: " << m_minRPhiErr << " cm" << std::endl;
0143 std::cout << "PHTpcResiduals::Init - m_minZErr: " << m_minZErr << " cm" << std::endl;
0144 std::cout << "PHTpcResiduals::Init - m_minPt: " << m_minPt << " GeV/c" << std::endl;
0145 std::cout << "PHTpcResiduals::Init - m_requireCrossing: " << m_requireCrossing << std::endl;
0146
0147
0148 m_total_tracks = 0;
0149 m_accepted_tracks = 0;
0150
0151 m_total_clusters = 0;
0152 m_accepted_clusters = 0;
0153
0154 return Fun4AllReturnCodes::EVENT_OK;
0155 }
0156
0157
0158 int PHTpcResiduals::InitRun(PHCompositeNode* topNode)
0159 {
0160 if (getNodes(topNode) != Fun4AllReturnCodes::EVENT_OK)
0161 {
0162 return Fun4AllReturnCodes::ABORTEVENT;
0163 }
0164
0165 if (createNodes(topNode) != Fun4AllReturnCodes::EVENT_OK)
0166 {
0167 return Fun4AllReturnCodes::ABORTEVENT;
0168 }
0169 m_zMax = m_tGeometry->get_max_driftlength() + m_tGeometry->get_CM_halfwidth();
0170 m_zMin = -m_zMax;
0171 return Fun4AllReturnCodes::EVENT_OK;
0172 }
0173
0174
0175 int PHTpcResiduals::process_event(PHCompositeNode* topNode)
0176 {
0177 const auto returnVal = processTracks(topNode);
0178 ++m_event;
0179
0180 return returnVal;
0181 }
0182
0183
0184 int PHTpcResiduals::End(PHCompositeNode* )
0185 {
0186 std::cout << "PHTpcResiduals::End - writing matrices to " << m_outputfile << std::endl;
0187
0188
0189 if (m_matrix_container)
0190 {
0191 std::unique_ptr<TFile> outputfile(TFile::Open(m_outputfile.c_str(), "RECREATE"));
0192 outputfile->cd();
0193 m_matrix_container->Write("TpcSpaceChargeMatrixContainer");
0194 }
0195
0196
0197 std::cout
0198 << "PHTpcResiduals::End -"
0199 << " track statistics total: " << m_total_tracks
0200 << " accepted: " << m_accepted_tracks
0201 << " fraction: " << 100. * m_accepted_tracks / m_total_tracks << "%"
0202 << std::endl;
0203
0204 std::cout
0205 << "PHTpcResiduals::End -"
0206 << " cluster statistics total: " << m_total_clusters
0207 << " accepted: " << m_accepted_clusters << " fraction: "
0208 << 100. * m_accepted_clusters / m_total_clusters << "%"
0209 << std::endl;
0210
0211 return Fun4AllReturnCodes::EVENT_OK;
0212 }
0213
0214
0215 int PHTpcResiduals::processTracks(PHCompositeNode* )
0216 {
0217 if (Verbosity())
0218 {
0219 std::cout << "PHTpcResiduals::processTracks - proto track size " << m_trackMap->size() << std::endl;
0220 }
0221
0222 for (const auto& [trackKey, track] : *m_trackMap)
0223 {
0224 if (Verbosity() > 1)
0225 {
0226 std::cout << "PHTpcResiduals::processTracks - Processing track key " << trackKey << std::endl;
0227 }
0228
0229 ++m_total_tracks;
0230 if (checkTrack(track))
0231 {
0232 ++m_accepted_tracks;
0233 processTrack(track);
0234 }
0235 }
0236
0237 return Fun4AllReturnCodes::EVENT_OK;
0238 }
0239
0240
0241 bool PHTpcResiduals::checkTrack(SvtxTrack* track) const
0242 {
0243 if (Verbosity() > 2)
0244 {
0245 std::cout << "PHTpcResiduals::checkTrack - pt: " << track->get_pt() << std::endl;
0246 }
0247
0248 if (m_requireCrossing && track->get_crossing() != 0)
0249 {
0250 return false;
0251 }
0252
0253 if (track->get_pt() < m_minPt)
0254 {
0255 return false;
0256 }
0257
0258
0259 const auto cluster_keys(get_cluster_keys(track));
0260 if (count_clusters<TrkrDefs::mvtxId>(cluster_keys) < 3)
0261 {
0262 return false;
0263 }
0264 if (count_clusters<TrkrDefs::inttId>(cluster_keys) < 2)
0265 {
0266 return false;
0267 }
0268 if (count_clusters<TrkrDefs::tpcId>(cluster_keys) < 35)
0269 {
0270 return false;
0271 }
0272
0273
0274
0275
0276
0277 const auto state_keys(get_state_keys(track));
0278 if (count_clusters<TrkrDefs::mvtxId>(state_keys) < 3)
0279 {
0280 return false;
0281 }
0282 if (count_clusters<TrkrDefs::inttId>(state_keys) < 2)
0283 {
0284 return false;
0285 }
0286
0287
0288
0289
0290
0291 if (m_useMicromegas && checkTPOTResidual(track) == false)
0292 {
0293 return false;
0294 }
0295
0296 return true;
0297 }
0298
0299
0300 bool PHTpcResiduals::checkTPOTResidual(SvtxTrack* track) const
0301 {
0302 bool flag = true;
0303
0304 int nTPOTcluster = 0;
0305 int nTPOTstate = 0;
0306 int TPOTtileID = -1;
0307 for (const auto& cluskey : get_cluster_keys(track))
0308 {
0309
0310 const auto detId = TrkrDefs::getTrkrId(cluskey);
0311 if (detId != TrkrDefs::micromegasId)
0312 {
0313 continue;
0314 }
0315 TPOTtileID = MicromegasDefs::getTileId(cluskey);
0316 nTPOTcluster++;
0317
0318 auto* const cluster = m_clusterContainer->findCluster(cluskey);
0319
0320 SvtxTrackState* state = nullptr;
0321
0322
0323 for (auto state_iter = track->begin_states();
0324 state_iter != track->end_states();
0325 ++state_iter)
0326 {
0327 SvtxTrackState* tstate = state_iter->second;
0328 auto stateckey = tstate->get_cluskey();
0329 if (stateckey == cluskey)
0330 {
0331 state = tstate;
0332 break;
0333 }
0334 }
0335
0336 const auto layer = TrkrDefs::getLayer(cluskey);
0337
0338 if (!state)
0339 {
0340 if (Verbosity() > 1)
0341 {
0342 std::cout << " no state for cluster " << cluskey << " in layer " << layer << std::endl;
0343 }
0344 continue;
0345 }
0346 nTPOTstate++;
0347
0348 const auto crossing = track->get_crossing();
0349 assert(crossing != std::numeric_limits<short>::max());
0350
0351
0352
0353 const auto globClusPos = m_globalPositionWrapper.getGlobalPositionDistortionCorrected(cluskey, cluster, crossing);
0354 const double clusR = get_r(globClusPos(0), globClusPos(1));
0355 const double clusPhi = std::atan2(globClusPos(1), globClusPos(0));
0356 const double clusZ = globClusPos(2);
0357
0358 const double globStateX = state->get_x();
0359 const double globStateY = state->get_y();
0360 const double globStateZ = state->get_z();
0361 const double globStatePx = state->get_px();
0362 const double globStatePy = state->get_py();
0363 const double globStatePz = state->get_pz();
0364
0365 const double trackR = std::sqrt(square(globStateX) + square(globStateY));
0366
0367 const double dr = clusR - trackR;
0368 const double trackDrDt = (globStateX * globStatePx + globStateY * globStatePy) / trackR;
0369 const double trackDxDr = globStatePx / trackDrDt;
0370 const double trackDyDr = globStatePy / trackDrDt;
0371 const double trackDzDr = globStatePz / trackDrDt;
0372
0373 const double trackX = globStateX + dr * trackDxDr;
0374 const double trackY = globStateY + dr * trackDyDr;
0375 const double trackZ = globStateZ + dr * trackDzDr;
0376 const double trackPhi = std::atan2(trackY, trackX);
0377
0378
0379
0380 const double drphi = clusR * deltaPhi(clusPhi - trackPhi);
0381 if (std::isnan(drphi))
0382 {
0383 continue;
0384 }
0385
0386 const double dz = clusZ - trackZ;
0387 if (std::isnan(dz))
0388 {
0389 continue;
0390 }
0391
0392 if (Verbosity() > 3)
0393 {
0394 std::cout << "PHTpcResiduals::checkTPOTResidual -"
0395 << " drphi: " << drphi
0396 << " dz: " << dz
0397 << std::endl;
0398 }
0399
0400
0401 if (layer == 55 && std::fabs(drphi) > 0.1)
0402 {
0403 flag = false;
0404 break;
0405 }
0406
0407
0408 if (layer == 56 && std::fabs(dz) > 1)
0409 {
0410 flag = false;
0411 break;
0412 }
0413 }
0414
0415 if (flag)
0416 {
0417
0418
0419 if (TPOTtileID == 0)
0420 {
0421 if (nTPOTcluster < 1 || nTPOTstate < 1)
0422 {
0423 flag = false;
0424 }
0425 }
0426 else if (TPOTtileID > 0)
0427 {
0428 if (nTPOTcluster < 2 || nTPOTstate < 2)
0429 {
0430 flag = false;
0431 }
0432 }
0433 else if (TPOTtileID < 0)
0434 {
0435 flag = false;
0436 }
0437 }
0438
0439 return flag;
0440 }
0441
0442
0443 void PHTpcResiduals::processTrack(SvtxTrack* track)
0444 {
0445 if (Verbosity() > 1)
0446 {
0447 std::cout << "PHTpcResiduals::processTrack -"
0448 << " track momentum: " << track->get_p()
0449 << " position: " << Acts::Vector3(track->get_x(), track->get_y(), track->get_z())
0450 << std::endl;
0451 }
0452
0453
0454 const auto crossing = track->get_crossing();
0455 assert(crossing != std::numeric_limits<short>::max());
0456
0457 for (const auto& cluskey : get_cluster_keys(track))
0458 {
0459
0460 ++m_total_clusters;
0461
0462
0463 const auto detId = TrkrDefs::getTrkrId(cluskey);
0464 if (detId != TrkrDefs::tpcId)
0465 {
0466 continue;
0467 }
0468
0469
0470 const auto stateiter = std::find_if( track->begin_states(), track->end_states(), [&cluskey]( const auto& state_pair )
0471 { return state_pair.second->get_cluskey() == cluskey; } );
0472
0473
0474 if( stateiter == track->end_states() ) { continue; }
0475
0476
0477 const auto& [pathLength, state] = *stateiter;
0478
0479
0480 auto* const cluster = m_clusterContainer->findCluster(cluskey);
0481 const auto globClusPos = m_globalPositionWrapper.getGlobalPositionDistortionCorrected(cluskey, cluster, crossing);
0482 const double clusR = get_r(globClusPos(0), globClusPos(1));
0483 const double clusPhi = std::atan2(globClusPos(1), globClusPos(0));
0484 const double clusZ = globClusPos(2);
0485
0486
0487 const double clusRPhiErr = cluster->getRPhiError();
0488 const double clusZErr = cluster->getZError();
0489 if (Verbosity() > 3)
0490 {
0491 std::cout << "PHTpcResiduals::processTrack -"
0492 << " cluskey: " << cluskey
0493 << " clusR: " << clusR
0494 << " clusPhi: " << clusPhi << "+/-" << clusRPhiErr
0495 << " clusZ: " << clusZ << "+/-" << clusZErr
0496 << std::endl;
0497 }
0498
0499
0500 const double globStateX = state->get_x();
0501 const double globStateY = state->get_y();
0502 const double globStateZ = state->get_z();
0503 const auto trackR = std::sqrt(square(globStateX) + square(globStateY));
0504
0505
0506 const double globalStateMomX = state->get_px();
0507 const double globalStateMomY = state->get_py();
0508 const double globalStateMomZ = state->get_pz();
0509
0510
0511 const double trackRPhiErr = state->get_rphi_error();
0512 const double trackZErr = state->get_z_error();
0513
0514 const double dr = clusR - trackR;
0515 const double trackDrDt = (globStateX * globalStateMomX + globStateY * globalStateMomY) / trackR;
0516 const double trackDxDr = globalStateMomX / trackDrDt;
0517 const double trackDyDr = globalStateMomY / trackDrDt;
0518 const double trackDzDr = globalStateMomZ / trackDrDt;
0519
0520 const double trackX = globStateX + dr * trackDxDr;
0521 const double trackY = globStateY + dr * trackDyDr;
0522 const double trackZ = globStateZ + dr * trackDzDr;
0523 const double trackPhi = std::atan2(trackY, trackX);
0524
0525 if (Verbosity() > 2)
0526 {
0527 std::cout << "PHTpcResiduals::processTrack -"
0528 << " trackR: " << trackR
0529 << " dr: " << dr
0530 << " trackDrDt: " << trackDrDt
0531 << " trackDxDr: " << trackDxDr
0532 << " trackDyDr: " << trackDyDr
0533 << " trackDzDr: " << trackDzDr
0534 << " trackPhi: " << trackPhi << "+/-" << trackRPhiErr
0535 << " track position: (" << trackX << ", " << trackY << ", " << trackZ << ")"
0536 << std::endl;
0537 }
0538
0539 const double erp = square(clusRPhiErr) + square(trackRPhiErr);
0540 if (std::isnan(erp))
0541 {
0542 continue;
0543 }
0544
0545 const double ez = square(clusZErr) + square(trackZErr);
0546 if (std::isnan(ez))
0547 {
0548 continue;
0549 }
0550
0551
0552 const double drphi = clusR * deltaPhi(clusPhi - trackPhi);
0553 if (std::isnan(drphi))
0554 {
0555 continue;
0556 }
0557
0558 const double dz = clusZ - trackZ;
0559 if (std::isnan(dz))
0560 {
0561 continue;
0562 }
0563
0564 if (Verbosity() > 3)
0565 {
0566 std::cout << "PHTpcResiduals::processTrack -"
0567 << " drphi: " << drphi
0568 << " dz: " << dz
0569 << " erp: " << erp
0570 << " ez: " << ez
0571 << std::endl;
0572 }
0573
0574
0575 if (std::sqrt(erp) < m_minRPhiErr)
0576 {
0577 continue;
0578 }
0579
0580 if (std::sqrt(ez) < m_minZErr)
0581 {
0582 continue;
0583 }
0584
0585 const double trackPPhi = -globalStateMomX*std::sin(trackPhi) + globalStateMomY*std::cos(trackPhi);
0586 const double trackPR = globalStateMomX*std::cos(trackPhi) + globalStateMomY*std::sin(trackPhi);
0587 const double trackPZ = globalStateMomZ;
0588
0589 const double trackAlpha = -trackPPhi / trackPR;
0590 if (std::isnan(trackAlpha))
0591 {
0592 continue;
0593 }
0594
0595 const double trackBeta = -trackPZ / trackPR;
0596 if (std::isnan(trackBeta))
0597 {
0598 continue;
0599 }
0600
0601 if (Verbosity() > 3)
0602 {
0603 std::cout
0604 << "PHTpcResiduals::processTrack -"
0605 << " trackPPhi: " << trackPPhi
0606 << " trackPR: " << trackPR
0607 << " trackPZ: " << trackPZ
0608 << " trackAlpha: " << trackAlpha
0609 << " trackBeta: " << trackBeta
0610 << std::endl;
0611 }
0612
0613
0614 const auto index = getCell(globClusPos);
0615
0616 if (Verbosity() > 3)
0617 {
0618 std::cout << "Bin index found is " << index << std::endl;
0619 }
0620
0621 if (index < 0)
0622 {
0623 continue;
0624 }
0625
0626 if (Verbosity() > 3)
0627 {
0628 std::cout << "PHTpcResiduals::processTrack - layer: " << (int) TrkrDefs::getLayer(cluskey) << std::endl;
0629 std::cout << "PHTpcResiduals::processTrack -"
0630 << " cluster: (" << clusR << ", " << clusR * clusPhi << ", " << clusZ << ")"
0631 << " (" << clusRPhiErr << ", " << clusZErr << ")"
0632 << std::endl;
0633
0634 std::cout << "PHTpcResiduals::processTrack -"
0635 << " track: (" << trackR << ", " << clusR * trackPhi << ", " << trackZ << ")"
0636 << " (" << trackAlpha << ", " << trackBeta << ")"
0637 << " (" << trackRPhiErr << ", " << trackZErr << ")"
0638 << std::endl;
0639 std::cout << std::endl;
0640 }
0641
0642
0643 if (std::abs(trackAlpha) > m_maxTAlpha || std::abs(drphi) > m_maxResidualDrphi)
0644 {
0645 continue;
0646 }
0647
0648 if (std::abs(trackBeta) > m_maxTBeta || std::abs(dz) > m_maxResidualDz)
0649 {
0650 continue;
0651 }
0652
0653
0654 m_matrix_container->add_to_lhs(index, 0, 0, square(clusR) / erp);
0655 m_matrix_container->add_to_lhs(index, 0, 1, 0);
0656 m_matrix_container->add_to_lhs(index, 0, 2, clusR * trackAlpha / erp);
0657
0658 m_matrix_container->add_to_lhs(index, 1, 0, 0);
0659 m_matrix_container->add_to_lhs(index, 1, 1, 1. / ez);
0660 m_matrix_container->add_to_lhs(index, 1, 2, trackBeta / ez);
0661
0662 m_matrix_container->add_to_lhs(index, 2, 0, clusR * trackAlpha / erp);
0663 m_matrix_container->add_to_lhs(index, 2, 1, trackBeta / ez);
0664 m_matrix_container->add_to_lhs(index, 2, 2, square(trackAlpha) / erp + square(trackBeta) / ez);
0665
0666 m_matrix_container->add_to_rhs(index, 0, clusR * drphi / erp);
0667 m_matrix_container->add_to_rhs(index, 1, dz / ez);
0668 m_matrix_container->add_to_rhs(index, 2, trackAlpha * drphi / erp + trackBeta * dz / ez);
0669
0670
0671 m_matrix_container->add_to_lhs_rphi(index, 0, 0, square(clusR) / erp);
0672 m_matrix_container->add_to_lhs_rphi(index, 0, 1, clusR * trackAlpha / erp);
0673 m_matrix_container->add_to_lhs_rphi(index, 1, 0, clusR * trackAlpha / erp);
0674 m_matrix_container->add_to_lhs_rphi(index, 1, 1, square(trackAlpha) / erp);
0675
0676 m_matrix_container->add_to_rhs_rphi(index, 0, clusR * drphi / erp);
0677 m_matrix_container->add_to_rhs_rphi(index, 1, trackAlpha * drphi / erp);
0678
0679
0680 m_matrix_container->add_to_lhs_z(index, 0, 0, 1. / ez);
0681 m_matrix_container->add_to_lhs_z(index, 0, 1, trackBeta / ez);
0682 m_matrix_container->add_to_lhs_z(index, 1, 0, trackBeta / ez);
0683 m_matrix_container->add_to_lhs_z(index, 1, 1, square(trackBeta) / ez);
0684
0685 m_matrix_container->add_to_rhs_z(index, 0, dz / ez);
0686 m_matrix_container->add_to_rhs_z(index, 1, trackBeta * dz / ez);
0687
0688
0689 m_matrix_container->add_to_entries(index);
0690
0691
0692 ++m_accepted_clusters;
0693 }
0694 }
0695
0696
0697 int PHTpcResiduals::getCell(const Acts::Vector3& loc)
0698 {
0699
0700 int phibins = 0;
0701 int rbins = 0;
0702 int zbins = 0;
0703 m_matrix_container->get_grid_dimensions(phibins, rbins, zbins);
0704
0705
0706 float phi = std::atan2(loc(1), loc(0));
0707 while (phi < m_phiMin)
0708 {
0709 phi += 2. * M_PI;
0710 }
0711 while (phi >= m_phiMax)
0712 {
0713 phi -= 2. * M_PI;
0714 }
0715 const int iphi = phibins * (phi - m_phiMin) / (m_phiMax - m_phiMin);
0716
0717
0718 const auto r = get_r(loc(0), loc(1));
0719 if (r < m_rMin || r >= m_rMax)
0720 {
0721 return -1;
0722 }
0723 const int ir = rbins * (r - m_rMin) / (m_rMax - m_rMin);
0724
0725
0726 const auto z = loc(2);
0727 if (z < m_zMin || z >= m_zMax)
0728 {
0729 return -1;
0730 }
0731 const int iz = zbins * (z - m_zMin) / (m_zMax - m_zMin);
0732
0733
0734 return m_matrix_container->get_cell_index(iphi, ir, iz);
0735 }
0736
0737
0738 int PHTpcResiduals::createNodes(PHCompositeNode* )
0739 {
0740 return Fun4AllReturnCodes::EVENT_OK;
0741 }
0742
0743
0744 int PHTpcResiduals::getNodes(PHCompositeNode* topNode)
0745 {
0746
0747 m_clusterContainer = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
0748 if (!m_clusterContainer)
0749 {
0750 std::cout << PHWHERE << "No TRKR_CLUSTER node on node tree. Exiting." << std::endl;
0751 return Fun4AllReturnCodes::ABORTEVENT;
0752 }
0753
0754
0755 m_tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
0756 if (!m_tGeometry)
0757 {
0758 std::cout << "ActsTrackingGeometry not on node tree. Exiting." << std::endl;
0759 return Fun4AllReturnCodes::ABORTEVENT;
0760 }
0761
0762
0763 m_trackMap = findNode::getClass<SvtxTrackMap>(topNode, m_trackmapname);
0764 if (!m_trackMap)
0765 {
0766 std::cout << PHWHERE << " " << m_trackmapname << " not on node tree. Exiting." << std::endl;
0767 return Fun4AllReturnCodes::ABORTEVENT;
0768 }
0769
0770
0771 m_globalPositionWrapper.loadNodes(topNode);
0772 if (m_disable_module_edge_corr)
0773 {
0774 m_globalPositionWrapper.set_enable_module_edge_corr(false);
0775 }
0776 if (m_disable_static_corr)
0777 {
0778 m_globalPositionWrapper.set_enable_static_corr(false);
0779 }
0780 if (m_disable_average_corr)
0781 {
0782 m_globalPositionWrapper.set_enable_average_corr(false);
0783 }
0784 if (m_disable_fluctuation_corr)
0785 {
0786 m_globalPositionWrapper.set_enable_fluctuation_corr(false);
0787 }
0788
0789 return Fun4AllReturnCodes::EVENT_OK;
0790 }
0791
0792
0793 void PHTpcResiduals::setGridDimensions(const int phiBins, const int rBins, const int zBins)
0794 {
0795 m_matrix_container->set_grid_dimensions(phiBins, rBins, zBins);
0796 }