File indexing completed on 2025-08-05 08:18:07
0001
0002
0003
0004
0005
0006 #include "Fun4AllDstPileupMerger.h"
0007
0008 #include "PHG4Hit.h" // for PHG4Hit
0009 #include "PHG4HitContainer.h"
0010 #include "PHG4Hitv1.h"
0011 #include "PHG4Particle.h" // for PHG4Particle
0012 #include "PHG4Particlev3.h"
0013 #include "PHG4TruthInfoContainer.h"
0014 #include "PHG4VtxPoint.h" // for PHG4VtxPoint
0015 #include "PHG4VtxPointv1.h"
0016
0017 #include <phhepmc/PHHepMCGenEvent.h> // for PHHepMCGenEvent
0018 #include <phhepmc/PHHepMCGenEventMap.h>
0019
0020 #include <phool/PHCompositeNode.h>
0021 #include <phool/PHIODataNode.h> // for PHIODataNode
0022 #include <phool/PHNode.h> // for PHNode
0023 #include <phool/PHNodeIterator.h> // for PHNodeIterator
0024 #include <phool/PHNodeOperation.h>
0025 #include <phool/PHObject.h> // for PHObject
0026 #include <phool/getClass.h>
0027
0028 #include <TObject.h>
0029
0030 #pragma GCC diagnostic push
0031 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0032 #include <HepMC/GenEvent.h>
0033 #pragma GCC diagnostic pop
0034
0035 #include <iostream>
0036 #include <iterator>
0037 #include <limits>
0038 #include <utility>
0039
0040
0041 namespace
0042 {
0043 using PHG4Particle_t = PHG4Particlev3;
0044 using PHG4VtxPoint_t = PHG4VtxPointv1;
0045 using PHG4Hit_t = PHG4Hitv1;
0046
0047
0048 class FindG4HitContainer : public PHNodeOperation
0049 {
0050 public:
0051
0052 using ContainerMap = std::map<std::string, PHG4HitContainer *>;
0053
0054
0055 const ContainerMap &containers() const
0056 {
0057 return m_containers;
0058 }
0059
0060 protected:
0061
0062 void perform(PHNode *node) override
0063 {
0064
0065 if (node->getType() != "PHIODataNode")
0066 {
0067 return;
0068 }
0069
0070
0071 auto ionode = static_cast<PHIODataNode<TObject> *>(node);
0072 auto data = dynamic_cast<PHG4HitContainer *>(ionode->getData());
0073 if (data)
0074 {
0075 m_containers.insert(std::make_pair(node->getName(), data));
0076 }
0077 }
0078
0079 private:
0080
0081 ContainerMap m_containers;
0082 };
0083
0084 }
0085
0086
0087 void Fun4AllDstPileupMerger::load_nodes(PHCompositeNode *dstNode)
0088 {
0089
0090 m_geneventmap = findNode::getClass<PHHepMCGenEventMap>(dstNode, "PHHepMCGenEventMap");
0091 if (!m_geneventmap)
0092 {
0093 std::cout << "Fun4AllDstPileupMerger::load_nodes - creating PHHepMCGenEventMap" << std::endl;
0094 m_geneventmap = new PHHepMCGenEventMap();
0095 dstNode->addNode(new PHIODataNode<PHObject>(m_geneventmap, "PHHepMCGenEventMap", "PHObject"));
0096 }
0097
0098
0099 FindG4HitContainer nodeFinder;
0100 PHNodeIterator(dstNode).forEach(nodeFinder);
0101 m_g4hitscontainers = nodeFinder.containers();
0102
0103
0104 m_g4truthinfo = findNode::getClass<PHG4TruthInfoContainer>(dstNode, "G4TruthInfo");
0105 if (!m_g4truthinfo)
0106 {
0107 std::cout << "Fun4AllDstPileupMerger::load_nodes - creating node G4TruthInfo" << std::endl;
0108 m_g4truthinfo = new PHG4TruthInfoContainer();
0109 dstNode->addNode(new PHIODataNode<PHObject>(m_g4truthinfo, "G4TruthInfo", "PHObject"));
0110 }
0111 }
0112
0113
0114 void Fun4AllDstPileupMerger::copy_background_event(PHCompositeNode *dstNode, double delta_t) const
0115 {
0116
0117 const auto map = findNode::getClass<PHHepMCGenEventMap>(dstNode, "PHHepMCGenEventMap");
0118
0119
0120 int new_embed_id = -1;
0121
0122 if (map && m_geneventmap)
0123 {
0124 if (map->size() != 1)
0125 {
0126 std::cout << "Fun4AllDstPileupMerger::copy_background_event - cannot merge events that contain more than one PHHepMCGenEventMap" << std::endl;
0127 return;
0128 }
0129
0130
0131 auto genevent = map->get_map().begin()->second;
0132 auto newevent = m_geneventmap->insert_background_event(genevent);
0133
0134
0135
0136
0137
0138
0139 newevent->getEvent()->swap(*genevent->getEvent());
0140
0141
0142 newevent->moveVertex(0, 0, 0, delta_t);
0143 new_embed_id = newevent->get_embedding_id();
0144 }
0145
0146
0147
0148 using ConversionMap = std::map<int, int>;
0149 ConversionMap vtxid_map;
0150 ConversionMap trkid_map;
0151
0152 const auto container_truth = findNode::getClass<PHG4TruthInfoContainer>(dstNode, "G4TruthInfo");
0153 if (container_truth && m_g4truthinfo)
0154 {
0155 {
0156
0157 auto key = m_g4truthinfo->maxvtxindex();
0158 const auto range = container_truth->GetPrimaryVtxRange();
0159 for (auto iter = range.first; iter != range.second; ++iter)
0160 {
0161
0162 const auto &sourceVertex = iter->second;
0163 auto newVertex = new PHG4VtxPoint_t(sourceVertex);
0164 newVertex->set_t(sourceVertex->get_t() + delta_t);
0165 m_g4truthinfo->AddVertex(++key, newVertex);
0166 vtxid_map.insert(std::make_pair(sourceVertex->get_id(), key));
0167 }
0168 }
0169
0170 {
0171
0172 auto key = m_g4truthinfo->minvtxindex();
0173 const auto range = container_truth->GetSecondaryVtxRange();
0174
0175
0176 for (
0177 auto iter = std::reverse_iterator<PHG4TruthInfoContainer::ConstVtxIterator>(range.second);
0178 iter != std::reverse_iterator<PHG4TruthInfoContainer::ConstVtxIterator>(range.first);
0179 ++iter)
0180 {
0181
0182 const auto &sourceVertex = iter->second;
0183 auto newVertex = new PHG4VtxPoint_t(sourceVertex);
0184 newVertex->set_t(sourceVertex->get_t() + delta_t);
0185 m_g4truthinfo->AddVertex(--key, newVertex);
0186 vtxid_map.insert(std::make_pair(sourceVertex->get_id(), key));
0187 }
0188 }
0189
0190 {
0191
0192 auto key = m_g4truthinfo->maxtrkindex();
0193 const auto range = container_truth->GetPrimaryParticleRange();
0194 for (auto iter = range.first; iter != range.second; ++iter)
0195 {
0196 const auto &source = iter->second;
0197 auto dest = new PHG4Particle_t(source);
0198 m_g4truthinfo->AddParticle(++key, dest);
0199 dest->set_track_id(key);
0200
0201
0202 dest->set_parent_id(0);
0203
0204
0205 dest->set_primary_id(dest->get_track_id());
0206
0207
0208 const auto keyiter = vtxid_map.find(source->get_vtx_id());
0209 if (keyiter != vtxid_map.end())
0210 {
0211 dest->set_vtx_id(keyiter->second);
0212 }
0213 else
0214 {
0215 std::cout << "Fun4AllDstPileupMerger::copy_background_event - vertex id " << source->get_vtx_id() << " not found in map" << std::endl;
0216 }
0217
0218
0219 trkid_map.insert(std::make_pair(source->get_track_id(), dest->get_track_id()));
0220 }
0221 }
0222
0223 {
0224
0225 auto key = m_g4truthinfo->mintrkindex();
0226 const auto range = container_truth->GetSecondaryParticleRange();
0227
0228
0229
0230
0231
0232 for (
0233 auto iter = std::reverse_iterator<PHG4TruthInfoContainer::ConstIterator>(range.second);
0234 iter != std::reverse_iterator<PHG4TruthInfoContainer::ConstIterator>(range.first);
0235 ++iter)
0236 {
0237 const auto &source = iter->second;
0238 auto dest = new PHG4Particle_t(source);
0239 m_g4truthinfo->AddParticle(--key, dest);
0240 dest->set_track_id(key);
0241
0242
0243 auto keyiter = trkid_map.find(source->get_parent_id());
0244 if (keyiter != trkid_map.end())
0245 {
0246 dest->set_parent_id(keyiter->second);
0247 }
0248 else
0249 {
0250 std::cout << "Fun4AllDstPileupMerger::copy_background_event - track id " << source->get_parent_id() << " not found in map" << std::endl;
0251 }
0252
0253
0254 keyiter = trkid_map.find(source->get_primary_id());
0255 if (keyiter != trkid_map.end())
0256 {
0257 dest->set_primary_id(keyiter->second);
0258 }
0259 else
0260 {
0261 std::cout << "Fun4AllDstPileupMerger::copy_background_event - track id " << source->get_primary_id() << " not found in map" << std::endl;
0262 }
0263
0264
0265 keyiter = vtxid_map.find(source->get_vtx_id());
0266 if (keyiter != vtxid_map.end())
0267 {
0268 dest->set_vtx_id(keyiter->second);
0269 }
0270 else
0271 {
0272 std::cout << "Fun4AllDstPileupMerger::copy_background_event - vertex id " << source->get_vtx_id() << " not found in map" << std::endl;
0273 }
0274
0275
0276 trkid_map.insert(std::make_pair(source->get_track_id(), dest->get_track_id()));
0277 }
0278 }
0279
0280
0281
0282 for (const auto &pair : vtxid_map)
0283 {
0284 if (pair.first > 0)
0285 {
0286 m_g4truthinfo->AddEmbededVtxId(pair.second, new_embed_id);
0287 }
0288 }
0289
0290
0291
0292 for (const auto &pair : trkid_map)
0293 {
0294 if (pair.first > 0)
0295 {
0296 m_g4truthinfo->AddEmbededTrkId(pair.second, new_embed_id);
0297 }
0298 }
0299 }
0300
0301
0302
0303 for (const auto &pair : m_g4hitscontainers)
0304 {
0305
0306 if (!pair.second)
0307 {
0308 std::cout << "Fun4AllDstPileupMerger::copy_background_event - invalid destination container " << pair.first << std::endl;
0309 continue;
0310 }
0311
0312
0313 auto container_hit = findNode::getClass<PHG4HitContainer>(dstNode, pair.first);
0314 if (!container_hit)
0315 {
0316 std::cout << "Fun4AllDstPileupMerger::copy_background_event - invalid source container " << pair.first << std::endl;
0317 continue;
0318 }
0319 auto detiter = m_DetectorTiming.find(pair.first);
0320
0321 if (detiter != m_DetectorTiming.end())
0322 {
0323 if (delta_t < detiter->second.first || delta_t > detiter->second.second)
0324 {
0325 continue;
0326 }
0327 }
0328 {
0329
0330 const auto range = container_hit->getHits();
0331 for (auto iter = range.first; iter != range.second; ++iter)
0332 {
0333
0334 const auto &sourceHit = iter->second;
0335 auto newHit = new PHG4Hit_t(sourceHit);
0336
0337
0338 newHit->set_t(0, sourceHit->get_t(0) + delta_t);
0339 newHit->set_t(1, sourceHit->get_t(1) + delta_t);
0340
0341
0342 const auto keyiter = trkid_map.find(sourceHit->get_trkid());
0343 if (keyiter != trkid_map.end())
0344 {
0345 newHit->set_trkid(keyiter->second);
0346 }
0347 else
0348 {
0349 std::cout << "Fun4AllDstPileupMerger::copy_background_event - track id " << sourceHit->get_trkid() << " not found in map" << std::endl;
0350 }
0351
0352
0353
0354
0355
0356
0357 newHit->set_shower_id(std::numeric_limits<int>::min());
0358
0359
0360
0361
0362
0363 pair.second->AddHit(newHit->get_detid(), newHit);
0364 }
0365 }
0366
0367 {
0368
0369 const auto range = container_hit->getLayers();
0370 for (auto iter = range.first; iter != range.second; ++iter)
0371 {
0372 pair.second->AddLayer(*iter);
0373 }
0374 }
0375 }
0376 }