File indexing completed on 2025-12-17 09:21:07
0001
0002 #include "PHTrackClusterAssociator.h"
0003
0004 #include <fun4all/Fun4AllReturnCodes.h>
0005
0006 #include <phool/PHCompositeNode.h>
0007 #include <phool/PHIODataNode.h>
0008 #include <phool/PHNode.h>
0009 #include <phool/PHNodeIterator.h>
0010 #include <phool/PHObject.h>
0011 #include <phool/getClass.h>
0012 #include <phool/phool.h>
0013
0014 #include <trackbase_historic/SvtxTrack.h>
0015 #include <trackbase_historic/SvtxTrackCaloClusterMap_v1.h>
0016 #include <trackbase_historic/SvtxTrackMap.h>
0017
0018 #include <globalvertex/SvtxVertex.h>
0019 #include <globalvertex/SvtxVertexMap.h>
0020
0021 #include <calobase/RawCluster.h>
0022 #include <calobase/RawClusterContainer.h>
0023 #include <calobase/RawClusterUtility.h>
0024 #include <calobase/TowerInfo.h>
0025 #include <calobase/TowerInfoContainerv1.h>
0026 #include <calobase/RawTowerGeomContainer.h>
0027 #include <phgeom/PHGeomUtility.h>
0028
0029 #include <Acts/Definitions/Algebra.hpp>
0030 #include <cmath>
0031
0032 namespace
0033 {
0034 template <class T>
0035 inline constexpr T deltaPhi(const T& dphi)
0036 {
0037 if (dphi > M_PI)
0038 return dphi - 2. * M_PI;
0039 else if (dphi <= -M_PI)
0040 return dphi + 2. * M_PI;
0041 else
0042 return dphi;
0043 }
0044 }
0045
0046
0047 PHTrackClusterAssociator::PHTrackClusterAssociator(const std::string& name)
0048 : SubsysReco(name)
0049 {}
0050
0051
0052 int PHTrackClusterAssociator::InitRun(PHCompositeNode* topNode)
0053 {
0054 int ret = getNodes(topNode);
0055 if (ret != Fun4AllReturnCodes::EVENT_OK)
0056 {
0057 return ret;
0058 }
0059
0060 ret = createNodes(topNode);
0061 if (ret != Fun4AllReturnCodes::EVENT_OK)
0062 {
0063 return ret;
0064 }
0065
0066 return ret;
0067 }
0068
0069
0070 int PHTrackClusterAssociator::process_event(PHCompositeNode* topNode)
0071 {
0072 if (!m_calosAvailable)
0073 {
0074 return Fun4AllReturnCodes::EVENT_OK;
0075 }
0076
0077 for (int layer = 0; layer < m_nCaloLayers; layer++)
0078 {
0079 if (Verbosity() > 1)
0080 {
0081 std::cout << "Processing calo layer "
0082 << m_caloNames.at(layer) << std::endl;
0083 }
0084
0085 int ret = matchTracks(topNode, layer);
0086 if (ret != Fun4AllReturnCodes::EVENT_OK)
0087 {
0088 return Fun4AllReturnCodes::ABORTEVENT;
0089 }
0090 }
0091
0092 if (Verbosity() > 3)
0093 {
0094 for (const auto& [track, clustervec] : *m_trackClusterMap)
0095 {
0096 track->identify();
0097 std::cout << " has clusters associated to it : " << std::endl;
0098 for (auto cluster : clustervec)
0099 {
0100 cluster->identify();
0101 }
0102 }
0103 }
0104
0105 return Fun4AllReturnCodes::EVENT_OK;
0106 }
0107
0108 int PHTrackClusterAssociator::matchTracks(PHCompositeNode* topNode,
0109 const int caloLayer)
0110 {
0111 if (getCaloNodes(topNode, caloLayer) != Fun4AllReturnCodes::EVENT_OK)
0112 {
0113 return Fun4AllReturnCodes::ABORTEVENT;
0114 }
0115
0116
0117 double caloRadius = m_towerGeomContainer->get_radius();
0118 if (m_caloRadii.find(m_caloNames.at(caloLayer)) != m_caloRadii.end())
0119 {
0120 caloRadius = m_caloRadii.find(m_caloNames.at(caloLayer))->second;
0121 }
0122
0123 for (const auto& [key, track] : *m_trackMap)
0124 {
0125 const SvtxTrackState* state = track->get_state(caloRadius);
0126 const float statex = state->get_x();
0127 const float statey = state->get_y();
0128 const float statez = state->get_z();
0129 const float statephi = std::atan2(statey, statex);
0130 const float stateeta = std::asinh(statez /
0131 std::sqrt(statex * statex + statey * statey));
0132
0133 const int vertexid = track->get_vertex_id();
0134 const auto vertex = m_vertexMap->get(vertexid);
0135 const auto cluster = getCluster(statephi, stateeta, vertex);
0136 if (Verbosity() > 1)
0137 {
0138 if (!cluster)
0139 {
0140 std::cout << "no cluster found, continuing to next track"
0141 << std::endl;
0142 continue;
0143 }
0144 else
0145 {
0146 std::cout << "matching cluster " << cluster->get_id() << " to track " << track->get_id() << std::endl;
0147 }
0148 }
0149
0150 m_trackClusterMap->insert(track, cluster);
0151 }
0152
0153 return Fun4AllReturnCodes::EVENT_OK;
0154 }
0155
0156 RawCluster* PHTrackClusterAssociator::getCluster(double phi,
0157 double eta,
0158 SvtxVertex* vertex)
0159 {
0160 double minR = std::numeric_limits<double>::max();
0161 auto clusterMap = m_clusterContainer->getClustersMap();
0162 RawCluster* returncluster = nullptr;
0163 Acts::Vector3 vert = Acts::Vector3::Zero();
0164 if (vertex)
0165 {
0166 vert(0) = vertex->get_x();
0167 vert(1) = vertex->get_y();
0168 vert(2) = vertex->get_z();
0169 }
0170
0171 for (const auto& [key, cluster] : clusterMap)
0172 {
0173 const auto clusterEta =
0174 RawClusterUtility::GetPseudorapidity(*cluster,
0175 CLHEP::Hep3Vector(vert(0), vert(1), vert(2)));
0176 const auto dphi = deltaPhi(phi - cluster->get_phi());
0177 const auto deta = eta - clusterEta;
0178 const auto r = sqrt(pow(dphi, 2) + pow(deta, 2));
0179
0180 if (r < minR)
0181 {
0182 minR = r;
0183 returncluster = cluster;
0184 }
0185 }
0186
0187 return returncluster;
0188 }
0189
0190 int PHTrackClusterAssociator::getNodes(PHCompositeNode* topNode)
0191 {
0192 m_trackMap = findNode::getClass<SvtxTrackMap>(topNode, "SvtxTrackMap");
0193 if (!m_trackMap)
0194 {
0195 std::cout << PHWHERE << "No track map, can't continue" << std::endl;
0196 return Fun4AllReturnCodes::ABORTEVENT;
0197 }
0198
0199 m_vertexMap = findNode::getClass<SvtxVertexMap>(topNode, "SvtxVertexMap");
0200 if (!m_vertexMap)
0201 {
0202 std::cout << PHWHERE << "No vertex map, can't continue" << std::endl;
0203 return Fun4AllReturnCodes::ABORTEVENT;
0204 }
0205
0206 return Fun4AllReturnCodes::EVENT_OK;
0207 }
0208
0209 int PHTrackClusterAssociator::getCaloNodes(PHCompositeNode* topNode,
0210 const int caloLayer)
0211 {
0212 std::string towerGeoNodeName = "TOWERGEOM_" + m_caloNames.at(caloLayer);
0213 std::string towerNodeName = "TOWERINFO_CALIB_" + m_caloNames.at(caloLayer);
0214 std::string clusterNodeName = "CLUSTER_" + m_caloNames.at(caloLayer);
0215
0216 m_towerGeomContainer = findNode::getClass<RawTowerGeomContainer>(topNode, towerGeoNodeName.c_str());
0217
0218 m_towerContainer = findNode::getClass<TowerInfoContainerv1>(topNode, towerNodeName.c_str());
0219
0220 m_clusterContainer = findNode::getClass<RawClusterContainer>(topNode, clusterNodeName.c_str());
0221
0222 if (m_useCemcPosRecalib &&
0223 m_caloNames.at(caloLayer).compare("CEMC") == 0)
0224 {
0225 std::string nodeName = "CLUSTER_POS_COR_" + m_caloNames.at(caloLayer);
0226 m_clusterContainer = findNode::getClass<RawClusterContainer>(topNode, nodeName.c_str());
0227 }
0228
0229 if (!m_towerGeomContainer || !m_towerContainer || !m_clusterContainer)
0230 {
0231 std::cout << PHWHERE
0232 << "Calo geometry and/or cluster container not found on node tree. Track-Calo cluster map won't be filled."
0233 << std::endl;
0234 m_calosAvailable = false;
0235 return Fun4AllReturnCodes::ABORTEVENT;
0236 }
0237
0238 return Fun4AllReturnCodes::EVENT_OK;
0239 }
0240
0241 int PHTrackClusterAssociator::createNodes(PHCompositeNode* topNode)
0242 {
0243 PHNodeIterator iter(topNode);
0244
0245 PHCompositeNode* dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
0246
0247 if (!dstNode)
0248 {
0249 std::cerr << "DST node is missing, quitting" << std::endl;
0250 throw std::runtime_error("Failed to find DST node in PHActsSiliconSeeding::createNodes");
0251 }
0252
0253 PHNodeIterator dstIter(dstNode);
0254 PHCompositeNode* svtxNode = dynamic_cast<PHCompositeNode*>(dstIter.findFirst("PHCompositeNode", "SVTX"));
0255
0256 if (!svtxNode)
0257 {
0258 svtxNode = new PHCompositeNode("SVTX");
0259 dstNode->addNode(svtxNode);
0260 }
0261
0262 m_trackClusterMap = findNode::getClass<SvtxTrackCaloClusterMap>(topNode, "TrackCaloClusterMap");
0263 if (!m_trackClusterMap)
0264 {
0265 m_trackClusterMap = new SvtxTrackCaloClusterMap_v1;
0266 PHIODataNode<PHObject>* node = new PHIODataNode<PHObject>(
0267 m_trackClusterMap, "TrackCaloClusterMap", "PHObject");
0268 svtxNode->addNode(node);
0269 }
0270
0271 return Fun4AllReturnCodes::EVENT_OK;
0272 }
0273
0274
0275 int PHTrackClusterAssociator::ResetEvent(PHCompositeNode*)
0276 {
0277 return Fun4AllReturnCodes::EVENT_OK;
0278 }
0279
0280
0281 int PHTrackClusterAssociator::End(PHCompositeNode*)
0282 {
0283 return Fun4AllReturnCodes::EVENT_OK;
0284 }