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