Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:17:38

0001 #include "GlobalVertexReco.h"
0002 
0003 #include "GlobalVertex.h"     // for GlobalVertex, GlobalVe...
0004 #include "GlobalVertexMap.h"  // for GlobalVertexMap
0005 #include "GlobalVertexMapv1.h"
0006 #include "GlobalVertexv2.h"
0007 #include "MbdVertex.h"
0008 #include "MbdVertexMap.h"
0009 #include "SvtxVertex.h"
0010 #include "SvtxVertexMap.h"
0011 
0012 #include <trackbase_historic/SvtxTrack.h>
0013 #include <trackbase_historic/SvtxTrackMap.h>
0014 
0015 #include <fun4all/Fun4AllReturnCodes.h>
0016 #include <fun4all/SubsysReco.h>  // for SubsysReco
0017 
0018 #include <phool/PHCompositeNode.h>
0019 #include <phool/PHIODataNode.h>
0020 #include <phool/PHNode.h>  // for PHNode
0021 #include <phool/PHNodeIterator.h>
0022 #include <phool/PHObject.h>  // for PHObject
0023 #include <phool/getClass.h>
0024 #include <phool/phool.h>  // for PHWHERE
0025 
0026 #include <cmath>
0027 #include <cstdlib>  // for exit
0028 #include <iostream>
0029 #include <limits>
0030 #include <set>      // for _Rb_tree_const_iterator
0031 #include <utility>  // for pair
0032 
0033 GlobalVertexReco::GlobalVertexReco(const std::string &name)
0034   : SubsysReco(name)
0035 {
0036 }
0037 
0038 int GlobalVertexReco::InitRun(PHCompositeNode *topNode)
0039 {
0040   if (Verbosity() > 0)
0041   {
0042     std::cout << "======================= GlobalVertexReco::InitRun() =======================" << std::endl;
0043     std::cout << "===========================================================================" << std::endl;
0044   }
0045 
0046   return CreateNodes(topNode);
0047 }
0048 
0049 int GlobalVertexReco::process_event(PHCompositeNode *topNode)
0050 {
0051   if (Verbosity() > 1)
0052   {
0053     std::cout << "GlobalVertexReco::process_event -- entered" << std::endl;
0054   }
0055 
0056   //---------------------------------
0057   // Get Objects off of the Node Tree
0058   //---------------------------------
0059   GlobalVertexMap *globalmap = findNode::getClass<GlobalVertexMap>(topNode, "GlobalVertexMap");
0060   if (!globalmap)
0061   {
0062     std::cout << PHWHERE << "::ERROR - cannot find GlobalVertexMap" << std::endl;
0063     exit(-1);
0064   }
0065 
0066   SvtxVertexMap *svtxmap = findNode::getClass<SvtxVertexMap>(topNode, "SvtxVertexMap");
0067   MbdVertexMap *mbdmap = findNode::getClass<MbdVertexMap>(topNode, "MbdVertexMap");
0068   SvtxTrackMap *trackmap = findNode::getClass<SvtxTrackMap>(topNode, "SvtxTrackMap");
0069 
0070   // we will make 3 different kinds of global vertexes
0071   //  (1) SVTX+MBD vertexes - we match SVTX vertex to the nearest MBD vertex within 3 sigma in zvertex
0072   //      the spatial point comes from the SVTX, the timing from the MBD
0073   //      number of SVTX+MBD vertexes <= number of SVTX vertexes
0074 
0075   //  (2) SVTX only vertexes - for those cases where the MBD wasn't simulated,
0076   //      or all the MBD vertexes are outside the 3 sigma matching requirement
0077   //      we pass forward the 3d point from the SVTX with the default timing info
0078 
0079   //  (3) MBD only vertexes - use the default x,y positions on this module and
0080   //      pull in the mbd z and mbd t
0081 
0082   // there may be some quirks as we get to large luminosity and the MBD becomes
0083   // untrust worthy, I'm guessing analyzers would resort exclusively to (1) or (2)
0084   // in those cases
0085 
0086   std::set<unsigned int> used_svtx_vtxids;
0087   std::set<unsigned int> used_mbd_vtxids;
0088 
0089   if (svtxmap && mbdmap)
0090   {
0091     if (Verbosity())
0092     {
0093       std::cout << "GlobalVertexReco::process_event - svtxmap && mbdmap" << std::endl;
0094     }
0095 
0096     for (SvtxVertexMap::ConstIter svtxiter = svtxmap->begin();
0097          svtxiter != svtxmap->end();
0098          ++svtxiter)
0099     {
0100       const SvtxVertex *svtx = svtxiter->second;
0101 
0102       const MbdVertex *mbd_best = nullptr;
0103       float min_sigma = std::numeric_limits<float>::max();
0104       for (MbdVertexMap::ConstIter mbditer = mbdmap->begin();
0105            mbditer != mbdmap->end();
0106            ++mbditer)
0107       {
0108         const MbdVertex *mbd = mbditer->second;
0109 
0110         float combined_error = sqrt(svtx->get_error(2, 2) + pow(mbd->get_z_err(), 2));
0111         float sigma = std::fabs(svtx->get_z() - mbd->get_z()) / combined_error;
0112         if (sigma < min_sigma)
0113         {
0114           min_sigma = sigma;
0115           mbd_best = mbd;
0116         }
0117       }
0118 
0119       if (min_sigma > 3.0 || !mbd_best)
0120       {
0121         continue;
0122       }
0123 
0124       // we have a matching pair
0125       GlobalVertex *vertex = new GlobalVertexv2();
0126       vertex->set_id(globalmap->size());
0127 
0128       vertex->clone_insert_vtx(GlobalVertex::SVTX, svtx);
0129       vertex->clone_insert_vtx(GlobalVertex::MBD, mbd_best);
0130       used_svtx_vtxids.insert(svtx->get_id());
0131       used_mbd_vtxids.insert(mbd_best->get_id());
0132       vertex->set_id(globalmap->size());
0133 
0134       globalmap->insert(vertex);
0135 
0136       //! Reset track ids to the new vertex object
0137       if (trackmap)
0138       {
0139         for (auto iter = svtx->begin_tracks(); iter != svtx->end_tracks();
0140              ++iter)
0141         {
0142           auto track = trackmap->find(*iter)->second;
0143           track->set_vertex_id(vertex->get_id());
0144         }
0145       }
0146 
0147       if (Verbosity() > 1)
0148       {
0149         vertex->identify();
0150       }
0151     }
0152   }
0153 
0154   // okay now loop over all unused SVTX vertexes (2nd class)...
0155   if (svtxmap)
0156   {
0157     if (Verbosity())
0158     {
0159       std::cout << "GlobalVertexReco::process_event - svtxmap " << std::endl;
0160     }
0161 
0162     for (SvtxVertexMap::ConstIter svtxiter = svtxmap->begin();
0163          svtxiter != svtxmap->end();
0164          ++svtxiter)
0165     {
0166       const SvtxVertex *svtx = svtxiter->second;
0167 
0168       if (used_svtx_vtxids.find(svtx->get_id()) != used_svtx_vtxids.end())
0169       {
0170         continue;
0171       }
0172       if (std::isnan(svtx->get_z()))
0173       {
0174         continue;
0175       }
0176 
0177       // we have a standalone SVTX vertex
0178       GlobalVertex *vertex = new GlobalVertexv2();
0179 
0180       vertex->set_id(globalmap->size());
0181 
0182       vertex->clone_insert_vtx(GlobalVertex::SVTX, svtx);
0183       used_svtx_vtxids.insert(svtx->get_id());
0184 
0185       //! Reset track ids to the new vertex object
0186       if (trackmap)
0187       {
0188         for (auto iter = svtx->begin_tracks(); iter != svtx->end_tracks();
0189              ++iter)
0190         {
0191           auto track = trackmap->find(*iter)->second;
0192           track->set_vertex_id(vertex->get_id());
0193         }
0194       }
0195       globalmap->insert(vertex);
0196 
0197       if (Verbosity() > 1)
0198       {
0199         vertex->identify();
0200       }
0201     }
0202   }
0203 
0204   // okay now loop over all unused MBD vertexes (3rd class)...
0205   if (mbdmap)
0206   {
0207     if (Verbosity())
0208     {
0209       std::cout << "GlobalVertexReco::process_event -  mbdmap" << std::endl;
0210     }
0211 
0212     for (MbdVertexMap::ConstIter mbditer = mbdmap->begin();
0213          mbditer != mbdmap->end();
0214          ++mbditer)
0215     {
0216       const MbdVertex *mbd = mbditer->second;
0217 
0218       if (used_mbd_vtxids.find(mbd->get_id()) != used_mbd_vtxids.end())
0219       {
0220         continue;
0221       }
0222       if (std::isnan(mbd->get_z()))
0223       {
0224         continue;
0225       }
0226 
0227       GlobalVertex *vertex = new GlobalVertexv2();
0228       vertex->set_id(globalmap->size());
0229 
0230       vertex->clone_insert_vtx(GlobalVertex::MBD, mbd);
0231       used_mbd_vtxids.insert(mbd->get_id());
0232 
0233       globalmap->insert(vertex);
0234 
0235       if (Verbosity() > 1)
0236       {
0237         vertex->identify();
0238       }
0239     }
0240   }
0241 
0242   /// Associate any tracks that were not assigned a track-vertex
0243   if (trackmap)
0244   {
0245     for (const auto &[tkey, track] : *trackmap)
0246     {
0247       //! Check that the vertex hasn't already been assigned
0248       auto trackvtxid = track->get_vertex_id();
0249       if (globalmap->find(trackvtxid) != globalmap->end())
0250       {
0251         continue;
0252       }
0253 
0254       float maxdz = std::numeric_limits<float>::max();
0255       unsigned int vtxid = std::numeric_limits<unsigned int>::max();
0256 
0257       for (const auto &[vkey, vertex] : *globalmap)
0258       {
0259         float dz = track->get_z() - vertex->get_z();
0260         if (std::fabs(dz) < maxdz)
0261         {
0262           maxdz = dz;
0263           vtxid = vkey;
0264         }
0265       }
0266 
0267       track->set_vertex_id(vtxid);
0268       if (Verbosity())
0269       {
0270         std::cout << "Associated track with z " << track->get_z() << " to GlobalVertex id " << track->get_vertex_id() << std::endl;
0271       }
0272     }
0273   }
0274 
0275   if (Verbosity())
0276   {
0277     globalmap->identify();
0278   }
0279   return Fun4AllReturnCodes::EVENT_OK;
0280 }
0281 
0282 int GlobalVertexReco::CreateNodes(PHCompositeNode *topNode)
0283 {
0284   PHNodeIterator iter(topNode);
0285 
0286   // Looking for the DST node
0287   PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0288   if (!dstNode)
0289   {
0290     std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
0291     return Fun4AllReturnCodes::ABORTRUN;
0292   }
0293 
0294   // store the GLOBAL stuff under a sub-node directory
0295   PHCompositeNode *globalNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "GLOBAL"));
0296   if (!globalNode)
0297   {
0298     globalNode = new PHCompositeNode("GLOBAL");
0299     dstNode->addNode(globalNode);
0300   }
0301 
0302   // create the GlobalVertexMap
0303   GlobalVertexMap *vertexes = findNode::getClass<GlobalVertexMap>(topNode, "GlobalVertexMap");
0304   if (!vertexes)
0305   {
0306     vertexes = new GlobalVertexMapv1();
0307     PHIODataNode<PHObject> *VertexMapNode = new PHIODataNode<PHObject>(vertexes, "GlobalVertexMap", "PHObject");
0308     globalNode->addNode(VertexMapNode);
0309   }
0310   return Fun4AllReturnCodes::EVENT_OK;
0311 }