File indexing completed on 2025-12-17 09:21:22
0001 #include "QAG4SimulationDistortions.h"
0002
0003 #include <micromegas/MicromegasDefs.h>
0004
0005 #include <trackbase/ActsGeometry.h>
0006 #include <trackbase/TrkrCluster.h>
0007 #include <trackbase/TrkrClusterContainer.h>
0008 #include <trackbase/TrkrDefs.h>
0009 #include <trackbase_historic/SvtxTrack.h>
0010 #include <trackbase_historic/SvtxTrackMap.h>
0011 #include <trackbase_historic/SvtxTrackState.h>
0012 #include <trackbase_historic/TrackAnalysisUtils.h>
0013 #include <trackbase_historic/TrackSeed.h>
0014
0015 #include <g4detectors/PHG4TpcGeom.h>
0016 #include <g4detectors/PHG4TpcGeomContainer.h>
0017
0018 #include <qautils/QAHistManagerDef.h>
0019
0020 #include <fun4all/Fun4AllHistoManager.h>
0021 #include <fun4all/Fun4AllReturnCodes.h>
0022 #include <fun4all/SubsysReco.h>
0023
0024 #include <phool/PHCompositeNode.h>
0025 #include <phool/getClass.h>
0026 #include <phool/phool.h> // for PHWHERE
0027
0028 #include <Acts/Definitions/Algebra.hpp>
0029
0030 #include <TH1.h>
0031 #include <TH2.h>
0032 #include <TTree.h>
0033
0034 #include <algorithm>
0035 #include <cassert>
0036 #include <cmath>
0037 #include <iostream>
0038 #include <iterator>
0039 #include <limits>
0040 #include <string>
0041 #include <utility> // for pair
0042 #include <vector>
0043
0044 namespace
0045 {
0046
0047
0048 template <class T>
0049 constexpr T square(const T& x)
0050 {
0051 return x * x;
0052 }
0053
0054
0055 template <class T>
0056 T get_r(const T& x, const T& y)
0057 {
0058 return std::sqrt(square(x) + square(y));
0059 }
0060
0061 template <class T>
0062 constexpr T deltaPhi(const T& phi)
0063 {
0064 if (phi > M_PI)
0065 {
0066 return phi - 2. * M_PI;
0067 }
0068 if (phi <= -M_PI)
0069 {
0070 return phi + 2. * M_PI;
0071 }
0072
0073 return phi;
0074 }
0075
0076
0077 template <int type>
0078 int count_clusters(const std::vector<TrkrDefs::cluskey>& keys)
0079 {
0080 return std::count_if(keys.begin(), keys.end(),
0081 [](const TrkrDefs::cluskey& key)
0082 { return TrkrDefs::getTrkrId(key) == type; });
0083 }
0084 }
0085
0086
0087 QAG4SimulationDistortions::QAG4SimulationDistortions(const std::string& name)
0088 : SubsysReco(name)
0089 {
0090 }
0091
0092
0093 int QAG4SimulationDistortions::Init(PHCompositeNode* )
0094 {
0095
0096 m_total_tracks = 0;
0097 m_accepted_tracks = 0;
0098
0099 m_total_states = 0;
0100 m_accepted_states = 0;
0101
0102
0103 auto* hm = QAHistManagerDef::getHistoManager();
0104 assert(hm);
0105
0106 h_beta = new TH2F(std::string(get_histo_prefix() + "betadz").c_str(), ";tan#beta; #Deltaz [cm]", 100, -0.5, 0.5, 100, -0.5, 0.5);
0107 hm->registerHisto(h_beta);
0108
0109 h_alpha = new TH2F(std::string(get_histo_prefix() + "alphardphi").c_str(), ";tan#alpha; r#Delta#phi [cm]", 100, -0.5, 0.5, 100, -0.5, 0.5);
0110 hm->registerHisto(h_alpha);
0111
0112 h_rphiResid = new TH2F(std::string(get_histo_prefix() + "rphiResid").c_str(), ";r [cm]; #Deltar#phi [cm]", 60, 20, 80, 500, -2, 2);
0113 hm->registerHisto(h_rphiResid);
0114
0115 h_zResid = new TH2F(std::string(get_histo_prefix() + "zResid").c_str(), ";z [cm]; #Deltaz [cm]", 200, -100, 100, 1000, -2, 2);
0116 hm->registerHisto(h_zResid);
0117
0118 h_etaResid = new TH2F(std::string(get_histo_prefix() + "etaResid").c_str(), ";#eta;#Delta#eta", 20, -1, 1, 500, -0.2, 0.2);
0119 hm->registerHisto(h_etaResid);
0120
0121 h_etaResidLayer = new TH2F(std::string(get_histo_prefix() + "etaResidLayer").c_str(), ";r [cm]; #Delta#eta", 60, 20, 80, 500, -0.2, 0.2);
0122 hm->registerHisto(h_etaResidLayer);
0123
0124 h_zResidLayer = new TH2F(std::string(get_histo_prefix() + "zResidLayer").c_str(), ";r [cm]; #Deltaz [cm]", 60, 20, 80, 1000, -2, 2);
0125 hm->registerHisto(h_zResidLayer);
0126
0127 h_deltarphi_layer = new TH2F(std::string(get_histo_prefix() + "deltarphi_layer").c_str(), ";layer; r.#Delta#phi_{cluster-track} (cm)", 57, 0, 57, 500, -2, 2);
0128 hm->registerHisto(h_deltarphi_layer);
0129
0130 h_deltaz_layer = new TH2F(std::string(get_histo_prefix() + "deltaz_layer").c_str(), ";layer; #Deltaz_{cluster-track} (cm)", 57, 0, 57, 100, -2, 2);
0131 hm->registerHisto(h_deltaz_layer);
0132
0133 h_statez_pulls = new TH2F(std::string(get_histo_prefix() + "statez_pulls").c_str(), ";layer; #Deltaz_{cluster-track}/#sigma_{z}^{state}", 57, 0, 57, 100, -5, 5);
0134 hm->registerHisto(h_statez_pulls);
0135
0136 h_staterphi_pulls = new TH2F(std::string(get_histo_prefix() + "staterphi_pulls").c_str(), ";layer; #Deltar#phi_{cluster-track}/#sigma_{rphi}^{state}", 57, 0, 57, 100, -5, 5);
0137 hm->registerHisto(h_staterphi_pulls);
0138
0139 h_clusz_pulls = new TH2F(std::string(get_histo_prefix() + "clusz_pulls").c_str(), ";layer; #Deltaz_{cluster-track}/#sigma_{z}^{clus}", 57, 0, 57, 100, -5, 5);
0140 hm->registerHisto(h_clusz_pulls);
0141
0142 h_clusrphi_pulls = new TH2F(std::string(get_histo_prefix() + "clusrphi_pulls").c_str(), ";layer; #Deltar#phi_{cluster-track}/#sigma_{r#phi}^{clus}", 57, 0, 57, 100, -5, 5);
0143 hm->registerHisto(h_clusrphi_pulls);
0144
0145 h_nstates_vs_nclus = new TH2F(std::string(get_histo_prefix() + "nstates_vs_nclus").c_str(), ";Number of states on track; Number of clusters on track", 57, 0, 57, 57, 0, 57);
0146 hm->registerHisto(h_nstates_vs_nclus);
0147
0148 h_tpot_deltarphi = new TH1F(std::string(get_histo_prefix() + "tpot_deltarphi").c_str(), ";TPOT r.#Delta#phi_{cluster-track} (cm); Number of TPOT clusters", 100, -1, 1);
0149 hm->registerHisto(h_tpot_deltarphi);
0150
0151 h_tpot_deltaz = new TH1F(std::string(get_histo_prefix() + "tpot_deltaz").c_str(), ";TPOT #Deltaz_{cluster-track} (cm); Number of TPOT clusters", 100, -2, 2);
0152 hm->registerHisto(h_tpot_deltaz);
0153
0154 t_tree = new TTree(std::string(get_histo_prefix() + "residTree").c_str(), "tpc residual info");
0155 t_tree->Branch("tanAlpha", &m_tanAlpha, "tanAlpha/F");
0156 t_tree->Branch("tanBeta", &m_tanBeta, "tanBeta/F");
0157 t_tree->Branch("drphi", &m_drphi, "drphi/F");
0158 t_tree->Branch("dz", &m_dz, "dz/F");
0159 t_tree->Branch("clusR", &m_clusR, "clusR/F");
0160 t_tree->Branch("clusPhi", &m_clusPhi, "clusPhi/F");
0161 t_tree->Branch("clusZ", &m_clusZ, "clusZ/F");
0162 t_tree->Branch("clusEta", &m_clusEta, "clusEta/F");
0163 t_tree->Branch("stateR", &m_stateR, "stateR/F");
0164 t_tree->Branch("statePhi", &m_statePhi, "statePhi/F");
0165 t_tree->Branch("stateZ", &m_stateZ, "stateZ/F");
0166 t_tree->Branch("stateEta", &m_stateEta, "stateEta/F");
0167 t_tree->Branch("stateRPhiErr", &m_stateRPhiErr, "stateRPhiErr/F");
0168 t_tree->Branch("stateZErr", &m_stateZErr, "stateZErr/F");
0169 t_tree->Branch("clusRPhiErr", &m_clusRPhiErr, "clusRPhiErr/F");
0170 t_tree->Branch("clusZErr", &m_clusZErr, "clusZErr/F");
0171 t_tree->Branch("cluskey", &m_cluskey, "cluskey/l");
0172 t_tree->Branch("event", &m_event, "event/I");
0173
0174 t_tree->Branch("layer", &m_layer, "layer/I");
0175 t_tree->Branch("statePt", &m_statePt, "statePt/F");
0176 t_tree->Branch("statePz", &m_statePz, "statePz/F");
0177
0178 t_tree->Branch("trackPt", &m_trackPt, "trackPt/F");
0179 t_tree->Branch("charge", &m_charge, "charge/I");
0180 t_tree->Branch("crossing", &m_crossing, "crossing/I");
0181 t_tree->Branch("trackdEdx", &m_trackdEdx, "trackdEdx/F");
0182
0183 hm->registerHisto(t_tree);
0184
0185 return Fun4AllReturnCodes::EVENT_OK;
0186 }
0187
0188
0189 int QAG4SimulationDistortions::InitRun(PHCompositeNode* topNode)
0190 {
0191
0192 m_trackMap = findNode::getClass<SvtxTrackMap>(topNode, m_trackmapname);
0193
0194
0195 m_clusterContainer = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
0196
0197
0198 m_tpcGeom = findNode::getClass<PHG4TpcGeomContainer>(topNode, "TPCGEOMCONTAINER");
0199
0200
0201 m_tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
0202
0203
0204 m_globalPositionWrapper.loadNodes(topNode);
0205 if (m_disable_module_edge_corr)
0206 {
0207 m_globalPositionWrapper.set_enable_module_edge_corr(false);
0208 }
0209 if (m_disable_static_corr)
0210 {
0211 m_globalPositionWrapper.set_enable_static_corr(false);
0212 }
0213 if (m_disable_average_corr)
0214 {
0215 m_globalPositionWrapper.set_enable_average_corr(false);
0216 }
0217 if (m_disable_fluctuation_corr)
0218 {
0219 m_globalPositionWrapper.set_enable_fluctuation_corr(false);
0220 }
0221
0222 if (!m_trackMap || !m_clusterContainer || !m_tGeometry)
0223 {
0224 std::cout << PHWHERE << "Necessary distortion container not on node tree. Bailing."
0225 << std::endl;
0226
0227 return Fun4AllReturnCodes::ABORTRUN;
0228 }
0229
0230 return Fun4AllReturnCodes::EVENT_OK;
0231 }
0232
0233
0234 int QAG4SimulationDistortions::process_event(PHCompositeNode* )
0235 {
0236 Fun4AllHistoManager* hm = QAHistManagerDef::getHistoManager();
0237 assert(hm);
0238
0239 std::cout << "QAG4SimulationDistortions::process_event - tracks: " << m_trackMap->size() << std::endl;
0240 for (const auto& [key, track] : *m_trackMap)
0241 {
0242
0243 ++m_total_tracks;
0244
0245
0246 const auto crossing = track->get_crossing();
0247 if (crossing == std::numeric_limits<short>::max())
0248 {
0249 std::cout << "QAG4SimulationDistortions::process_event - invalid crossing. Track skipped." << std::endl;
0250 continue;
0251 }
0252
0253
0254 if (!checkTrack(track))
0255 {
0256 if (Verbosity() > 1)
0257 {
0258 std::cout << "failed track selection" << std::endl;
0259 }
0260 continue;
0261 }
0262 if (Verbosity() > 1)
0263 {
0264 std::cout << "pass track selection" << std::endl;
0265 }
0266
0267
0268 auto* tpcSeed = track->get_tpc_seed();
0269 auto* siliconSeed = track->get_silicon_seed();
0270
0271
0272 if (!tpcSeed || !siliconSeed)
0273 {
0274 continue;
0275 }
0276
0277 if (Verbosity() > 0)
0278 {
0279 std::cout << " tpc seed " << tpcSeed->get_tpc_seed_index()
0280 << " with si seed " << siliconSeed->get_silicon_seed_index()
0281 << " crossing " << siliconSeed->get_crossing()
0282 << std::endl;
0283 }
0284
0285
0286 ++m_accepted_tracks;
0287
0288 for (auto iter = track->begin_states(); iter != track->end_states(); ++iter)
0289 {
0290 ++m_total_states;
0291
0292 auto& state = iter->second;
0293 const auto ckey = state->get_cluskey();
0294 const auto trkrId = TrkrDefs::getTrkrId(ckey);
0295
0296 if (trkrId != TrkrDefs::tpcId)
0297 {
0298 continue;
0299 }
0300
0301 ++m_accepted_states;
0302
0303 auto* cluster = m_clusterContainer->findCluster(ckey);
0304
0305 const auto clusGlobPosition = m_globalPositionWrapper.getGlobalPositionDistortionCorrected(ckey, cluster, crossing);
0306
0307 const float clusR = get_r(clusGlobPosition(0), clusGlobPosition(1));
0308 const float clusPhi = std::atan2(clusGlobPosition(1), clusGlobPosition(0));
0309 const float clusZ = clusGlobPosition(2);
0310
0311
0312 const float clusRPhiErr = cluster->getRPhiError();
0313 const float clusZErr = cluster->getZError();
0314
0315 const Acts::Vector3 stateGlobPosition = Acts::Vector3(state->get_x(),
0316 state->get_y(),
0317 state->get_z());
0318 const Acts::Vector3 stateGlobMom = Acts::Vector3(state->get_px(),
0319 state->get_py(),
0320 state->get_pz());
0321
0322 const float stateRPhiErr = state->get_rphi_error();
0323 const float stateZErr = state->get_z_error();
0324
0325 const float stateR = get_r(stateGlobPosition(0), stateGlobPosition(1));
0326
0327 const auto dr = clusR - stateR;
0328 const auto trackDrDt = (stateGlobPosition(0) * stateGlobMom(0) + stateGlobPosition(1) * stateGlobMom(1)) / stateR;
0329 const auto trackDxDr = stateGlobMom(0) / trackDrDt;
0330 const auto trackDyDr = stateGlobMom(1) / trackDrDt;
0331 const auto trackDzDr = stateGlobMom(2) / trackDrDt;
0332
0333 const auto trackX = stateGlobPosition(0) + dr * trackDxDr;
0334 const auto trackY = stateGlobPosition(1) + dr * trackDyDr;
0335 const auto trackZ = stateGlobPosition(2) + dr * trackDzDr;
0336 const float statePhi = std::atan2(trackY, trackX);
0337 const float stateZ = trackZ;
0338
0339
0340 const float drphi = clusR * deltaPhi(clusPhi - statePhi);
0341 const float dz = clusZ - stateZ;
0342
0343 const auto trackPPhi = -stateGlobMom(0) * std::sin(statePhi) + stateGlobMom(1) * std::cos(statePhi);
0344 const auto trackPR = stateGlobMom(0) * std::cos(statePhi) + stateGlobMom(1) * std::sin(statePhi);
0345 const auto trackPZ = stateGlobMom(2);
0346
0347 const auto trackAlpha = -trackPPhi / trackPR;
0348 const auto trackBeta = -trackPZ / trackPR;
0349 const auto trackEta = std::atanh(stateGlobMom(2) / stateGlobMom.norm());
0350 const auto clusEta = std::atanh(clusZ / clusGlobPosition.norm());
0351
0352 h_alpha->Fill(trackAlpha, drphi);
0353 h_beta->Fill(trackBeta, dz);
0354 h_rphiResid->Fill(clusR, drphi);
0355 h_zResid->Fill(stateZ, dz);
0356 h_etaResid->Fill(trackEta, clusEta - trackEta);
0357 h_zResidLayer->Fill(clusR, dz);
0358 h_etaResidLayer->Fill(clusR, clusEta - trackEta);
0359
0360 const auto layer = TrkrDefs::getLayer(ckey);
0361 h_deltarphi_layer->Fill(layer, drphi);
0362 h_deltaz_layer->Fill(layer, dz);
0363
0364 h_statez_pulls->Fill(layer, dz / stateZErr);
0365 h_staterphi_pulls->Fill(layer, drphi / stateRPhiErr);
0366 h_clusz_pulls->Fill(layer, dz / clusZErr);
0367 h_clusrphi_pulls->Fill(layer, drphi / clusRPhiErr);
0368
0369 m_tanAlpha = trackAlpha;
0370 m_tanBeta = trackBeta;
0371 m_drphi = drphi;
0372 m_dz = dz;
0373 m_clusR = clusR;
0374 m_clusPhi = clusPhi;
0375 m_clusZ = clusZ;
0376 m_statePhi = statePhi;
0377 m_stateZ = stateZ;
0378 m_stateR = stateR;
0379 m_stateRPhiErr = stateRPhiErr;
0380 m_stateZErr = stateZErr;
0381 m_clusRPhiErr = clusRPhiErr;
0382 m_clusZErr = clusZErr;
0383 m_cluskey = ckey;
0384
0385 m_clusEta = clusEta;
0386 m_stateEta = trackEta;
0387 m_layer = layer;
0388 m_statePt = sqrt(stateGlobMom(0) * stateGlobMom(0) + stateGlobMom(1) * stateGlobMom(1));
0389 m_statePz = stateGlobMom(2);
0390 m_trackPt = track->get_pt();
0391 m_charge = track->get_charge();
0392 m_crossing = track->get_crossing();
0393
0394 float layerThicknesses[4] = {0.0, 0.0, 0.0, 0.0};
0395
0396
0397 layerThicknesses[0] = m_tpcGeom->GetLayerCellGeom(7)->get_thickness();
0398 layerThicknesses[1] = m_tpcGeom->GetLayerCellGeom(8)->get_thickness();
0399 layerThicknesses[2] = m_tpcGeom->GetLayerCellGeom(27)->get_thickness();
0400 layerThicknesses[3] = m_tpcGeom->GetLayerCellGeom(50)->get_thickness();
0401
0402 m_trackdEdx = TrackAnalysisUtils::calc_dedx(tpcSeed, m_clusterContainer, m_tGeometry, layerThicknesses);
0403
0404 t_tree->Fill();
0405 }
0406 int nstates = track->size_states();
0407 int nclus = (track->get_silicon_seed()->size_cluster_keys()) + (track->get_tpc_seed()->size_cluster_keys());
0408 h_nstates_vs_nclus->Fill(nstates, nclus);
0409 }
0410
0411 m_event++;
0412
0413 return Fun4AllReturnCodes::EVENT_OK;
0414 }
0415
0416
0417 int QAG4SimulationDistortions::End(PHCompositeNode* )
0418 {
0419
0420 std::cout
0421 << "QAG4SimulationDistortions::End -"
0422 << " track statistics total: " << m_total_tracks
0423 << " accepted: " << m_accepted_tracks
0424 << " fraction: " << 100. * m_accepted_tracks / m_total_tracks << "%"
0425 << std::endl;
0426
0427 std::cout
0428 << "QAG4SimulationDistortions::End -"
0429 << " state statistics total: " << m_total_states
0430 << " accepted: " << m_accepted_states << " fraction: "
0431 << 100. * m_accepted_states / m_total_states << "%"
0432 << std::endl;
0433
0434 return Fun4AllReturnCodes::EVENT_OK;
0435 }
0436
0437
0438 bool QAG4SimulationDistortions::checkTrack(SvtxTrack* track)
0439 {
0440 if (track->get_pt() < m_minPT)
0441 {
0442 return false;
0443 }
0444
0445
0446 const auto cluster_keys(get_cluster_keys(track));
0447 if (count_clusters<TrkrDefs::mvtxId>(cluster_keys) < 3)
0448 {
0449 return false;
0450 }
0451 if (count_clusters<TrkrDefs::inttId>(cluster_keys) < 2)
0452 {
0453 return false;
0454 }
0455 if (count_clusters<TrkrDefs::tpcId>(cluster_keys) < 35)
0456 {
0457 return false;
0458 }
0459
0460 const auto state_keys(get_state_keys(track));
0461 if (count_clusters<TrkrDefs::mvtxId>(state_keys) < 3)
0462 {
0463 return false;
0464 }
0465 if (count_clusters<TrkrDefs::inttId>(state_keys) < 2)
0466 {
0467 return false;
0468 }
0469
0470 if (m_useMicromegas && checkTPOTResidual(track) == false)
0471 {
0472 return false;
0473 }
0474
0475 return true;
0476 }
0477
0478 bool QAG4SimulationDistortions::checkTPOTResidual(SvtxTrack* track)
0479 {
0480 Fun4AllHistoManager* hm = QAHistManagerDef::getHistoManager();
0481 assert(hm);
0482
0483 bool flag = true;
0484
0485 int nTPOTcluster = 0;
0486 int nTPOTstate = 0;
0487 int TPOTtileID = -1;
0488 for (const auto& cluskey : get_cluster_keys(track))
0489 {
0490
0491 const auto detId = TrkrDefs::getTrkrId(cluskey);
0492 if (detId != TrkrDefs::micromegasId)
0493 {
0494 continue;
0495 }
0496 TPOTtileID = MicromegasDefs::getTileId(cluskey);
0497 nTPOTcluster++;
0498
0499 auto* cluster = m_clusterContainer->findCluster(cluskey);
0500
0501 SvtxTrackState* state = nullptr;
0502
0503
0504 for (auto state_iter = track->begin_states();
0505 state_iter != track->end_states();
0506 ++state_iter)
0507 {
0508 SvtxTrackState* tstate = state_iter->second;
0509 auto stateckey = tstate->get_cluskey();
0510 if (stateckey == cluskey)
0511 {
0512 state = tstate;
0513 break;
0514 }
0515 }
0516
0517 const auto layer = TrkrDefs::getLayer(cluskey);
0518
0519 if (!state)
0520 {
0521 if (Verbosity() > 1)
0522 {
0523 std::cout << " no state for cluster " << cluskey << " in layer " << layer << std::endl;
0524 }
0525 continue;
0526 }
0527 nTPOTstate++;
0528
0529 const auto crossing = track->get_crossing();
0530 assert(crossing != std::numeric_limits<short>::max());
0531
0532
0533
0534 const auto globClusPos = m_globalPositionWrapper.getGlobalPositionDistortionCorrected(cluskey, cluster, crossing);
0535 const double clusR = get_r(globClusPos(0), globClusPos(1));
0536 const double clusPhi = std::atan2(globClusPos(1), globClusPos(0));
0537 const double clusZ = globClusPos(2);
0538
0539 const double globStateX = state->get_x();
0540 const double globStateY = state->get_y();
0541 const double globStateZ = state->get_z();
0542 const double globStatePx = state->get_px();
0543 const double globStatePy = state->get_py();
0544 const double globStatePz = state->get_pz();
0545
0546 const double trackR = std::sqrt(square(globStateX) + square(globStateY));
0547
0548 const double dr = clusR - trackR;
0549 const double trackDrDt = (globStateX * globStatePx + globStateY * globStatePy) / trackR;
0550 const double trackDxDr = globStatePx / trackDrDt;
0551 const double trackDyDr = globStatePy / trackDrDt;
0552 const double trackDzDr = globStatePz / trackDrDt;
0553
0554 const double trackX = globStateX + dr * trackDxDr;
0555 const double trackY = globStateY + dr * trackDyDr;
0556 const double trackZ = globStateZ + dr * trackDzDr;
0557 const double trackPhi = std::atan2(trackY, trackX);
0558
0559
0560
0561 const double drphi = clusR * deltaPhi(clusPhi - trackPhi);
0562 if (std::isnan(drphi))
0563 {
0564 continue;
0565 }
0566
0567 const double dz = clusZ - trackZ;
0568 if (std::isnan(dz))
0569 {
0570 continue;
0571 }
0572
0573 h_tpot_deltarphi->Fill(drphi);
0574 h_tpot_deltaz->Fill(dz);
0575
0576 if (Verbosity() > 3)
0577 {
0578 std::cout << "QAG4SimulationDistortions::checkTPOTResidual -"
0579 << " drphi: " << drphi
0580 << " dz: " << dz
0581 << std::endl;
0582 }
0583
0584
0585 if (layer == 55 && std::fabs(drphi) > 0.1)
0586 {
0587 flag = false;
0588 break;
0589 }
0590
0591
0592 if (layer == 56 && std::fabs(dz) > 1)
0593 {
0594 flag = false;
0595 break;
0596 }
0597 }
0598
0599 if (flag)
0600 {
0601
0602
0603 if (TPOTtileID == 0)
0604 {
0605 if (nTPOTcluster < 1 || nTPOTstate < 1)
0606 {
0607 flag = false;
0608 }
0609 }
0610 else if (TPOTtileID > 0)
0611 {
0612 if (nTPOTcluster < 2 || nTPOTstate < 2)
0613 {
0614 flag = false;
0615 }
0616 }
0617 else if (TPOTtileID < 0)
0618 {
0619 flag = false;
0620 }
0621 }
0622
0623 return flag;
0624 }
0625
0626 std::vector<TrkrDefs::cluskey> QAG4SimulationDistortions::get_cluster_keys(SvtxTrack* track)
0627 {
0628 std::vector<TrkrDefs::cluskey> out;
0629 for (const auto& seed : {track->get_silicon_seed(), track->get_tpc_seed()})
0630 {
0631 if (seed)
0632 {
0633 std::copy(seed->begin_cluster_keys(), seed->end_cluster_keys(), std::back_inserter(out));
0634 }
0635 }
0636 return out;
0637 }
0638
0639 std::vector<TrkrDefs::cluskey> QAG4SimulationDistortions::get_state_keys(SvtxTrack* track)
0640 {
0641 std::vector<TrkrDefs::cluskey> out;
0642 for (auto state_iter = track->begin_states();
0643 state_iter != track->end_states();
0644 ++state_iter)
0645 {
0646 SvtxTrackState* tstate = state_iter->second;
0647 auto stateckey = tstate->get_cluskey();
0648 out.push_back(stateckey);
0649 }
0650 return out;
0651 }