File indexing completed on 2025-08-06 08:18:28
0001
0002 #include "PHCosmicSeeder.h"
0003
0004 #include <fun4all/Fun4AllReturnCodes.h>
0005 #include <fun4all/SubsysReco.h>
0006 #include <phool/PHCompositeNode.h>
0007 #include <phool/PHIODataNode.h>
0008 #include <phool/PHNodeIterator.h>
0009 #include <phool/PHObject.h>
0010 #include <phool/getClass.h>
0011 #include <phool/phool.h>
0012
0013 #include <trackbase/TrkrClusterContainer.h>
0014 #include <trackbase/TrkrDefs.h>
0015 #include <trackbase_historic/TrackSeedContainer.h>
0016 #include <trackbase_historic/TrackSeedContainer_v1.h>
0017 #include <trackbase_historic/TrackSeed_v2.h>
0018 #include <trackbase/TrkrCluster.h>
0019
0020 #include <TFile.h>
0021 #include <TNtuple.h>
0022
0023 #include <algorithm>
0024 #include <cmath>
0025 #include <iostream>
0026 #include <iterator>
0027 #include <memory>
0028 #include <ostream>
0029 #include <set>
0030 #include <stdexcept>
0031 #include <string>
0032 #include <utility>
0033 #include <vector>
0034 namespace
0035 {
0036 template <class T>
0037 inline constexpr T square(const T& x)
0038 {
0039 return x * x;
0040 }
0041 template <class T>
0042 inline constexpr T r(const T& x, const T& y)
0043 {
0044 double sign = 1;
0045 if (y < 0)
0046 {
0047 sign = -1;
0048 }
0049 return std::sqrt(square(x) + square(y)) * sign;
0050 }
0051 }
0052
0053 PHCosmicSeeder::PHCosmicSeeder(const std::string& name)
0054 : SubsysReco(name)
0055 {
0056 }
0057
0058
0059 int PHCosmicSeeder::Init(PHCompositeNode* )
0060 {
0061 return Fun4AllReturnCodes::EVENT_OK;
0062 }
0063
0064
0065 int PHCosmicSeeder::InitRun(PHCompositeNode* topNode)
0066 {
0067 int ret = getNodes(topNode);
0068 if (ret != Fun4AllReturnCodes::EVENT_OK)
0069 {
0070 return ret;
0071 }
0072 ret = createNodes(topNode);
0073
0074 if (m_analysis)
0075 {
0076 m_outfile = new TFile("PHCosmicSeeder.root", "recreate");
0077 m_tup = new TNtuple("ntp_seed", "seed",
0078 "event:seed:nclus:xyint:xyslope:xzint:xzslope:"
0079 "longestxyint:longestxyslope:longestxzint:longestxzslope");
0080 }
0081
0082 return ret;
0083 }
0084
0085
0086 int PHCosmicSeeder::process_event(PHCompositeNode* )
0087 {
0088 PHCosmicSeeder::PositionMap clusterPositions;
0089 for (const auto& hitsetkey : m_clusterContainer->getHitSetKeys(m_trackerId))
0090 {
0091 auto range = m_clusterContainer->getClusters(hitsetkey);
0092 for (auto citer = range.first; citer != range.second; ++citer)
0093 {
0094 const auto ckey = citer->first;
0095 const auto cluster = citer->second;
0096 if(cluster->getMaxAdc() < m_adcCut){
0097 continue;
0098 }
0099 const auto global = m_tGeometry->getGlobalPosition(ckey, cluster);
0100 clusterPositions.insert(std::make_pair(ckey, global));
0101 }
0102 }
0103 if (Verbosity() > 2)
0104 {
0105 std::cout << "cluster map size is " << clusterPositions.size() << std::endl;
0106 }
0107 auto seeds = makeSeeds(clusterPositions);
0108
0109 if (Verbosity() > 1)
0110 {
0111 std::cout << "Initial seed candidate size is " << seeds.size() << std::endl;
0112 }
0113 std::sort(seeds.begin(), seeds.end(),
0114 [](const seed& a, const seed& b)
0115 { return a.ckeys.size() > b.ckeys.size(); });
0116
0117 auto prunedSeeds = combineSeeds(seeds, clusterPositions);
0118 if (Verbosity() > 1)
0119 {
0120 std::cout << "Pruned seed size is " << prunedSeeds.size() << std::endl;
0121 }
0122 std::sort(prunedSeeds.begin(), prunedSeeds.end(),
0123 [](const seed& a, const seed& b)
0124 { return a.ckeys.size() > b.ckeys.size(); });
0125
0126 auto finalSeeds = findIntersections(prunedSeeds);
0127 if (Verbosity() > 1)
0128 {
0129 std::cout << "final seeds are " << finalSeeds.size() << std::endl;
0130 }
0131 for (auto& seed1 : finalSeeds)
0132 {
0133 recalculateSeedLineParameters(seed1, clusterPositions, true);
0134
0135 recalculateSeedLineParameters(seed1, clusterPositions, false);
0136 }
0137 auto chainedSeeds = chainSeeds(finalSeeds, clusterPositions);
0138
0139 if (Verbosity() > 1)
0140 {
0141 std::cout << "Total seeds found is " << chainedSeeds.size() << std::endl;
0142 }
0143 int iseed = 0;
0144
0145 auto longestseedit = chainedSeeds.begin();
0146 seed longestseed;
0147 if (longestseedit != chainedSeeds.end())
0148 {
0149 longestseed = chainedSeeds.front();
0150 }
0151 for (auto& seed_A : chainedSeeds)
0152 {
0153
0154 if (m_trackerId == TrkrDefs::TrkrId::mvtxId && seed_A.ckeys.size() < 4)
0155 {
0156 continue;
0157 }
0158 if (m_analysis)
0159 {
0160 float seed_data[] = {
0161 (float) m_event,
0162 (float) iseed,
0163 (float) seed_A.ckeys.size(),
0164 seed_A.xyintercept,
0165 seed_A.xyslope,
0166 seed_A.xzintercept,
0167 seed_A.xzslope,
0168 longestseed.xyintercept,
0169 longestseed.xyslope,
0170 longestseed.xzintercept,
0171 longestseed.xzslope};
0172 m_tup->Fill(seed_data);
0173 }
0174 auto svtxseed = std::make_unique<TrackSeed_v2>();
0175 for (auto& key : seed_A.ckeys)
0176 {
0177 svtxseed->insert_cluster_key(key);
0178 }
0179
0180
0181
0182
0183 m_seedContainer->insert(svtxseed.get());
0184 ++iseed;
0185 }
0186 if (Verbosity() > 1)
0187 {
0188 std::cout << "Final n seeds: " << m_seedContainer->size() << std::endl;
0189 }
0190 ++m_event;
0191 return Fun4AllReturnCodes::EVENT_OK;
0192 }
0193 PHCosmicSeeder::SeedVector PHCosmicSeeder::findIntersections(PHCosmicSeeder::SeedVector& initialSeeds)
0194 {
0195 std::set<int> seedsToDelete;
0196
0197 for (unsigned int i = 0; i < initialSeeds.size(); ++i)
0198 {
0199 auto& seed1 = initialSeeds[i];
0200 for (unsigned int j = i; j < initialSeeds.size(); ++j)
0201 {
0202 if (i == j)
0203 {
0204 continue;
0205 }
0206 auto& seed2 = initialSeeds[j];
0207 std::vector<TrkrDefs::cluskey> intersection;
0208 unsigned int intersection_size_limit = 3;
0209 if (m_trackerId == TrkrDefs::TrkrId::mvtxId)
0210 {
0211 intersection_size_limit = 2;
0212 }
0213 std::set_intersection(seed1.ckeys.begin(), seed1.ckeys.end(),
0214 seed2.ckeys.begin(), seed2.ckeys.end(), std::back_inserter(intersection));
0215 if (intersection.size() > intersection_size_limit)
0216 {
0217
0218
0219 for (auto key : seed2.ckeys)
0220 {
0221 seed1.ckeys.insert(key);
0222 }
0223 seedsToDelete.insert(j);
0224 }
0225 }
0226 }
0227
0228 SeedVector finalSeeds;
0229 unsigned int clus_per_seed_size = 4;
0230 if (m_trackerId == TrkrDefs::TrkrId::mvtxId)
0231 {
0232 clus_per_seed_size = 3;
0233 }
0234 for (unsigned int i = 0; i < initialSeeds.size(); ++i)
0235 {
0236 if (seedsToDelete.find(i) != seedsToDelete.end())
0237 {
0238 continue;
0239 }
0240 if (initialSeeds[i].ckeys.size() < clus_per_seed_size)
0241 {
0242 continue;
0243 }
0244 finalSeeds.push_back(initialSeeds[i]);
0245 }
0246 return finalSeeds;
0247 }
0248 PHCosmicSeeder::SeedVector PHCosmicSeeder::chainSeeds(PHCosmicSeeder::SeedVector& initialSeeds,
0249 PositionMap& clusterPositions)
0250 {
0251 PHCosmicSeeder::SeedVector returnseeds;
0252 std::set<int> seedsToDelete;
0253 if (Verbosity() > 1)
0254 {
0255 std::cout << "Chaining seeds, n seeds = " << initialSeeds.size() << std::endl;
0256 }
0257 for (unsigned int i = 0; i < initialSeeds.size(); ++i)
0258 {
0259 auto& seed1 = initialSeeds[i];
0260 for (unsigned int j = i; j < initialSeeds.size(); ++j)
0261 {
0262 if (i == j)
0263 {
0264 continue;
0265 }
0266 auto& seed2 = initialSeeds[j];
0267 recalculateSeedLineParameters(seed1, clusterPositions, true);
0268 recalculateSeedLineParameters(seed2, clusterPositions, true);
0269 recalculateSeedLineParameters(seed1, clusterPositions, false);
0270 recalculateSeedLineParameters(seed2, clusterPositions, false);
0271
0272 float longestxyslope = seed1.xyslope;
0273 float longestxyint = seed1.xyintercept;
0274 float longestxzslope = seed1.xzslope;
0275 float longestxzint = seed1.xzintercept;
0276 if (seed1.ckeys.size() < seed2.ckeys.size())
0277 {
0278 longestxyint = seed2.xyintercept;
0279 longestxyslope = seed2.xyslope;
0280 longestxzint = seed2.xzintercept;
0281 longestxzslope = seed2.xzslope;
0282 }
0283
0284 float pdiff_tol = 1.0;
0285 if (m_trackerId == TrkrDefs::TrkrId::mvtxId)
0286 {
0287 pdiff_tol = 0.25;
0288 }
0289 float const pdiff = std::fabs((seed1.xyslope - seed2.xyslope) / longestxyslope);
0290 float const pdiff2 = std::fabs((seed1.xyintercept - seed2.xyintercept) / longestxyint);
0291 float const pdiff3 = std::fabs((seed1.xzintercept - seed2.xzintercept) / longestxzint);
0292 float const pdiff4 = std::fabs((seed1.xzslope - seed2.xzslope) / longestxzslope);
0293 if (Verbosity() > 1)
0294 {
0295 std::cout << "pdiff1,2,3,4 " << pdiff << ", " << pdiff2 << ", " << pdiff3 << ", " << pdiff4 << std::endl;
0296 }
0297 if (pdiff < pdiff_tol && pdiff2 < pdiff_tol && pdiff3 < pdiff_tol && pdiff4 < pdiff_tol)
0298 {
0299 seedsToDelete.insert(j);
0300 for (auto& key : seed2.ckeys)
0301 {
0302 seed1.ckeys.insert(key);
0303 }
0304 }
0305 }
0306 }
0307 for (unsigned int i = 0; i < initialSeeds.size(); ++i)
0308 {
0309 if (seedsToDelete.find(i) != seedsToDelete.end())
0310 {
0311 continue;
0312 }
0313
0314
0315 if (m_trackerId == TrkrDefs::TrkrId::mvtxId)
0316 {
0317 std::vector<bool> contains_layer = {false, false, false};
0318 for (auto& key : initialSeeds[i].ckeys)
0319 {
0320 contains_layer[TrkrDefs::getLayer(key)] = true;
0321 }
0322 if (std::find(contains_layer.begin(), contains_layer.end(), false) != contains_layer.end())
0323 {
0324 continue;
0325 }
0326 }
0327
0328 returnseeds.push_back(initialSeeds[i]);
0329 }
0330 if (returnseeds.size() > 1 && m_trackerId == TrkrDefs::TrkrId::mvtxId)
0331 {
0332 PHCosmicSeeder::SeedVector emptyseeds;
0333 return emptyseeds;
0334 }
0335
0336 return returnseeds;
0337 }
0338 PHCosmicSeeder::SeedVector PHCosmicSeeder::combineSeeds(PHCosmicSeeder::SeedVector& initialSeeds,
0339 PHCosmicSeeder::PositionMap& clusterPositions)
0340 {
0341 SeedVector prunedSeeds;
0342 std::set<int> seedsToDelete;
0343
0344 for (unsigned int i = 0; i < initialSeeds.size(); ++i)
0345 {
0346 for (unsigned int j = i; j < initialSeeds.size(); ++j)
0347 {
0348 if (i == j)
0349 {
0350 continue;
0351 }
0352 auto& seed1 = initialSeeds[i];
0353 auto& seed2 = initialSeeds[j];
0354
0355
0356 recalculateSeedLineParameters(seed1, clusterPositions, true);
0357 recalculateSeedLineParameters(seed2, clusterPositions, true);
0358 recalculateSeedLineParameters(seed1, clusterPositions, false);
0359 recalculateSeedLineParameters(seed2, clusterPositions, false);
0360
0361 float slope_tol = 0.1;
0362 float incept_tol = 3.0;
0363 if (m_trackerId == TrkrDefs::TrkrId::mvtxId)
0364 {
0365 slope_tol = 0.1;
0366 incept_tol = 0.5;
0367 }
0368 if (Verbosity() > 4)
0369 {
0370 std::cout << "xy slope diff: " << seed1.xyslope - seed2.xyslope << ", xy int diff " << seed1.xyintercept - seed2.xyintercept << ", xz slope diff " << seed1.xzslope - seed2.xzslope << ", xz int diff " << seed1.xzintercept - seed2.xzintercept << std::endl;
0371 }
0372
0373 if (std::fabs(seed1.xyslope - seed2.xyslope) < slope_tol &&
0374 std::fabs(seed1.xyintercept - seed2.xyintercept) < incept_tol &&
0375 std::fabs(seed1.xzslope - seed2.xzslope) < slope_tol &&
0376 std::fabs(seed1.xzintercept - seed2.xzintercept) < incept_tol)
0377 {
0378 for (auto& key : seed2.ckeys)
0379 {
0380 seed1.ckeys.insert(key);
0381 }
0382 seedsToDelete.insert(j);
0383 }
0384 }
0385 }
0386 if (Verbosity() > 4)
0387 {
0388 std::cout << "seeds to delete size is " << seedsToDelete.size() << std::endl;
0389 }
0390 for (unsigned int i = 0; i < initialSeeds.size(); ++i)
0391 {
0392 if (seedsToDelete.find(i) != seedsToDelete.end())
0393 {
0394 continue;
0395 }
0396 prunedSeeds.push_back(initialSeeds[i]);
0397 }
0398
0399 return prunedSeeds;
0400 }
0401 PHCosmicSeeder::SeedVector
0402 PHCosmicSeeder::makeSeeds(PHCosmicSeeder::PositionMap& clusterPositions)
0403 {
0404 PHCosmicSeeder::SeedVector seeds;
0405 std::set<TrkrDefs::cluskey> keys;
0406
0407 double dist_check = 2.0;
0408 if (m_trackerId == TrkrDefs::TrkrId::mvtxId)
0409 {
0410 dist_check = 2.5;
0411 }
0412 for (auto& [key1, pos1] : clusterPositions)
0413 {
0414 for (auto& [key2, pos2] : clusterPositions)
0415 {
0416 if (key1 == key2)
0417 {
0418 continue;
0419 }
0420
0421 float const dist = (pos2 - pos1).norm();
0422 if (m_trackerId == TrkrDefs::TrkrId::mvtxId && (TrkrDefs::getLayer(key1) == TrkrDefs::getLayer(key2)))
0423 {
0424 continue;
0425 }
0426 if (dist > dist_check)
0427 {
0428 continue;
0429 }
0430 if (Verbosity() > 5)
0431 {
0432 std::cout << "checking keys " << key1 << ", " << key2 << " with dist apart " << dist << std::endl;
0433 std::cout << "positions are " << pos1.transpose() << " , "
0434 << pos2.transpose() << std::endl;
0435 }
0436 PHCosmicSeeder::seed doub;
0437
0438 doub.xyslope = (pos2.y() - pos1.y()) / (pos2.x() - pos1.x());
0439 doub.xyintercept = pos1.y() - doub.xyslope * pos1.x();
0440 doub.xzslope = (pos2.z() - pos1.z()) / (pos2.x() - pos1.x());
0441 doub.xzintercept = pos1.z() - pos1.x() * doub.xzslope;
0442 doub.yzslope = (pos2.z() - pos1.z()) / (pos2.y() - pos1.y());
0443 doub.yzintercept = pos1.z() - pos1.y() * doub.yzslope;
0444
0445 keys.insert(key1);
0446 keys.insert(key2);
0447 doub.ckeys = keys;
0448 keys.clear();
0449 seeds.push_back(doub);
0450
0451 }
0452 }
0453 if (Verbosity() > 2)
0454 {
0455 std::cout << "doublet sizes " << seeds.size() << std::endl;
0456 }
0457 for (auto& dub : seeds)
0458 {
0459 if (Verbosity() > 2)
0460 {
0461 std::cout << "doublet has " << dub.ckeys.size() << " keys " << std::endl;
0462 for (auto key : dub.ckeys)
0463 {
0464 std::cout << "position is " << clusterPositions.find(key)->second.transpose() << std::endl;
0465 }
0466 }
0467 auto begin = dub.ckeys.begin();
0468 auto pos1 = clusterPositions.find(*(begin))->second;
0469 std::advance(begin, 1);
0470 auto pos2 = clusterPositions.find(*(begin))->second;
0471
0472 for (auto& [key, pos] : clusterPositions)
0473 {
0474
0475 if (std::find(dub.ckeys.begin(), dub.ckeys.end(), key) != dub.ckeys.end())
0476 {
0477 continue;
0478 }
0479
0480 float const dist1 = (pos1 - pos).norm();
0481 float const dist2 = (pos2 - pos).norm();
0482 float dist12_check = 2.;
0483 if (m_trackerId == TrkrDefs::TrkrId::mvtxId)
0484 {
0485 dist12_check = 3.5;
0486 }
0487 if (dist1 < dist2)
0488 {
0489 if (dist1 > dist12_check)
0490 {
0491 continue;
0492 }
0493 }
0494 else
0495 {
0496 if (dist2 > dist12_check)
0497 {
0498 continue;
0499 }
0500 }
0501
0502 float const predy = dub.xyslope * pos.x() + dub.xyintercept;
0503 float const predz = dub.xzslope * pos.x() + dub.xzintercept;
0504 float const predz2 = dub.yzslope * pos.y() + dub.yzintercept;
0505 if (Verbosity() > 2)
0506 {
0507 std::cout << "testing ckey " << key << " with box dca "
0508 << predy << ", " << pos.transpose() << " and " << predz << ", " << pos.z()
0509 << std::endl;
0510 }
0511 if (fabs(predy - pos.y()) < m_xyTolerance)
0512 {
0513 if (m_trackerId == TrkrDefs::TrkrId::mvtxId && (fabs(predz - pos.z()) > 0.3 || fabs(predz2 - pos.z()) > 0.3))
0514 {
0515 continue;
0516 }
0517 if (Verbosity() > 2)
0518 {
0519 std::cout << " adding ckey " << key << " with box dca "
0520 << predy << ", " << pos.y() << " and " << predz << ", " << pos.z()
0521 << std::endl;
0522 std::cout << " with pos " << pos.x() << ", " << pos.y() << ", " << pos.z()
0523 << std::endl;
0524 }
0525 dub.ckeys.insert(key);
0526 }
0527 }
0528 }
0529
0530
0531 std::set<int> seedsToDelete;
0532 for (unsigned int i = 0; i < seeds.size(); ++i)
0533 {
0534 auto seed_A = seeds[i];
0535 if (Verbosity() > 2 && seed_A.ckeys.size() > 2)
0536 {
0537 std::cout << "keys in seed " << std::endl;
0538 for (auto& key : seed_A.ckeys)
0539 {
0540 std::cout << key << ", ";
0541 }
0542 std::cout << "seed xy slope: " << seed_A.xyslope << std::endl;
0543 std::cout << std::endl
0544 << "seed pos " << std::endl;
0545 for (auto& key : seed_A.ckeys)
0546 {
0547 std::cout << clusterPositions.find(key)->second.transpose() << std::endl;
0548 }
0549 std::cout << "Done printing seed info" << std::endl;
0550 }
0551 if (seed_A.ckeys.size() < 3)
0552 {
0553 seedsToDelete.insert(i);
0554 }
0555 }
0556
0557 PHCosmicSeeder::SeedVector returnSeeds;
0558 for (unsigned int i = 0; i < seeds.size(); i++)
0559 {
0560 if (seedsToDelete.find(i) != seedsToDelete.end())
0561 {
0562 continue;
0563 }
0564 returnSeeds.push_back(seeds[i]);
0565 }
0566 return returnSeeds;
0567 }
0568 void PHCosmicSeeder::recalculateSeedLineParameters(seed& seed_A,
0569 PHCosmicSeeder::PositionMap& clusters, bool isXY)
0570 {
0571 float avgx = 0;
0572 float avgy = 0;
0573 PHCosmicSeeder::PositionMap seedClusters;
0574 for (auto& key : seed_A.ckeys)
0575 {
0576 auto glob = clusters.find(key)->second;
0577 if (isXY)
0578 {
0579 avgx += glob.x();
0580 avgy += glob.y();
0581 }
0582 else
0583 {
0584 avgx += glob.x();
0585 avgy += glob.z();
0586 }
0587 seedClusters.insert(std::make_pair(key, glob));
0588 }
0589
0590 avgx /= seed_A.ckeys.size();
0591 avgy /= seed_A.ckeys.size();
0592 float num = 0;
0593 float denom = 0;
0594 for (auto& [key, glob] : seedClusters)
0595 {
0596 if (isXY)
0597 {
0598 num += (glob.x() - avgx) * (glob.y() - avgy);
0599 denom += square(glob.x() - avgx);
0600 }
0601 else
0602 {
0603 num += (glob.x() - avgx) * (glob.z() - avgy);
0604 denom += square(glob.x() - avgx);
0605 }
0606 }
0607 if (isXY)
0608 {
0609 seed_A.xyslope = num / denom;
0610 seed_A.xyintercept = avgy - seed_A.xyslope * avgx;
0611 }
0612 else
0613 {
0614 seed_A.xzslope = num / denom;
0615 seed_A.xzintercept = avgy - seed_A.xzslope * avgx;
0616 }
0617 }
0618 int PHCosmicSeeder::getNodes(PHCompositeNode* topNode)
0619 {
0620 m_tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
0621 if (!m_tGeometry)
0622 {
0623 std::cout << PHWHERE << "No acts reco geometry, bailing."
0624 << std::endl;
0625 return Fun4AllReturnCodes::ABORTEVENT;
0626 }
0627 m_clusterContainer = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
0628 if (!m_clusterContainer)
0629 {
0630 std::cout << PHWHERE << "No cluster container on node tree, bailing."
0631 << std::endl;
0632 return Fun4AllReturnCodes::ABORTEVENT;
0633 }
0634 return Fun4AllReturnCodes::EVENT_OK;
0635 }
0636
0637 int PHCosmicSeeder::createNodes(PHCompositeNode* topNode)
0638 {
0639 PHNodeIterator iter(topNode);
0640
0641 PHCompositeNode* dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
0642
0643 if (!dstNode)
0644 {
0645 std::cerr << "DST node is missing, quitting" << std::endl;
0646 throw std::runtime_error("Failed to find DST node in PHCosmicSeeder::createNodes");
0647 }
0648
0649 PHNodeIterator dstIter(dstNode);
0650 PHCompositeNode* svtxNode = dynamic_cast<PHCompositeNode*>(dstIter.findFirst("PHCompositeNode", "SVTX"));
0651
0652 if (!svtxNode)
0653 {
0654 svtxNode = new PHCompositeNode("SVTX");
0655 dstNode->addNode(svtxNode);
0656 }
0657
0658 m_seedContainer = findNode::getClass<TrackSeedContainer>(topNode, m_trackMapName);
0659 if (!m_seedContainer)
0660 {
0661 m_seedContainer = new TrackSeedContainer_v1;
0662 PHIODataNode<PHObject>* trackNode =
0663 new PHIODataNode<PHObject>(m_seedContainer, m_trackMapName, "PHObject");
0664 svtxNode->addNode(trackNode);
0665 }
0666
0667 return Fun4AllReturnCodes::EVENT_OK;
0668 }
0669
0670 int PHCosmicSeeder::End(PHCompositeNode* )
0671 {
0672 if (m_outfile)
0673 {
0674 m_outfile->cd();
0675 m_tup->Write();
0676 m_outfile->Close();
0677 }
0678 return Fun4AllReturnCodes::EVENT_OK;
0679 }