File indexing completed on 2025-12-18 09:20:29
0001 #include "PHG4IHCalSteppingAction.h"
0002
0003 #include "PHG4IHCalDetector.h"
0004
0005 #include <g4detectors/PHG4StepStatusDecode.h>
0006
0007 #include <phparameter/PHParameters.h>
0008
0009 #include <calobase/TowerInfo.h>
0010 #include <calobase/TowerInfoContainer.h>
0011 #include <calobase/TowerInfoContainerv1.h>
0012 #include <calobase/TowerInfoDefs.h>
0013
0014 #include <g4main/PHG4Hit.h>
0015 #include <g4main/PHG4HitContainer.h>
0016 #include <g4main/PHG4Hitv1.h>
0017 #include <g4main/PHG4Shower.h>
0018 #include <g4main/PHG4SteppingAction.h> // for PHG4SteppingAction
0019 #include <g4main/PHG4TrackUserInfoV1.h>
0020
0021 #include <ffamodules/CDBInterface.h>
0022
0023 #include <fun4all/Fun4AllReturnCodes.h>
0024
0025 #include <phool/PHCompositeNode.h>
0026 #include <phool/PHIODataNode.h> // for PHIODataNode
0027 #include <phool/PHNode.h> // for PHNode
0028 #include <phool/PHNodeIterator.h> // for PHNodeIterator
0029 #include <phool/PHObject.h> // for PHObject
0030 #include <phool/getClass.h>
0031 #include <phool/phool.h>
0032
0033
0034 #include <TFile.h>
0035 #include <TH2.h>
0036 #include <TSystem.h>
0037
0038 #include <Geant4/G4NavigationHistory.hh>
0039 #include <Geant4/G4ParticleDefinition.hh> // for G4ParticleDefinition
0040 #include <Geant4/G4ReferenceCountedHandle.hh> // for G4ReferenceCountedHandle
0041 #include <Geant4/G4Step.hh>
0042 #include <Geant4/G4StepPoint.hh> // for G4StepPoint
0043 #include <Geant4/G4StepStatus.hh> // for fGeomBoundary, fAtRest...
0044 #include <Geant4/G4String.hh> // for G4String
0045 #include <Geant4/G4SystemOfUnits.hh>
0046 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
0047 #include <Geant4/G4TouchableHandle.hh> // for G4TouchableHandle
0048 #include <Geant4/G4Track.hh> // for G4Track
0049 #include <Geant4/G4TrackStatus.hh> // for fStopAndKill
0050 #include <Geant4/G4Types.hh> // for G4double
0051 #include <Geant4/G4VPhysicalVolume.hh> // for G4VPhysicalVolume
0052 #include <Geant4/G4VTouchable.hh> // for G4VTouchable
0053 #include <Geant4/G4VUserTrackInformation.hh> // for G4VUserTrackInformation
0054
0055 #include <cmath> // for isfinite
0056 #include <exception>
0057 #include <filesystem>
0058 #include <iostream>
0059 #include <string> // for operator<<, operator+
0060 #include <tuple>
0061
0062
0063 PHG4IHCalSteppingAction::PHG4IHCalSteppingAction(PHG4IHCalDetector* detector, PHParameters* parameters)
0064 : PHG4SteppingAction(detector->GetName())
0065 , m_Detector(detector)
0066 , m_Params(parameters)
0067 , m_IsActive(m_Params->get_int_param("active"))
0068 , m_IsBlackHole(m_Params->get_int_param("blackhole"))
0069 , m_LightScintModelFlag(m_Params->get_int_param("light_scint_model"))
0070 , m_doG4Hit(m_Params->get_int_param("saveg4hit"))
0071 , m_tmin(m_Params->get_double_param("tmin"))
0072 , m_tmax(m_Params->get_double_param("tmax"))
0073 , m_dt(m_Params->get_double_param("dt"))
0074 {
0075 SetLightCorrection(m_Params->get_double_param("light_balance_inner_radius") * cm,
0076 m_Params->get_double_param("light_balance_inner_corr"),
0077 m_Params->get_double_param("light_balance_outer_radius") * cm,
0078 m_Params->get_double_param("light_balance_outer_corr"));
0079
0080 std::string mapfile = m_Params->get_string_param("MapFileName");
0081 if (std::filesystem::path(mapfile).extension() != ".root")
0082 {
0083 mapfile = CDBInterface::instance()->getUrl(mapfile);
0084 m_Params->set_string_param("MapFileName", mapfile);
0085 }
0086 }
0087
0088 PHG4IHCalSteppingAction::~PHG4IHCalSteppingAction()
0089 {
0090
0091
0092
0093
0094 delete m_Hit;
0095
0096 delete m_MapCorrHist;
0097 }
0098
0099
0100 int PHG4IHCalSteppingAction::InitWithNode(PHCompositeNode* topNode)
0101 {
0102 if (m_LightScintModelFlag)
0103 {
0104 std::string ihcalmapname(m_Params->get_string_param("MapFileName"));
0105 if (ihcalmapname.empty())
0106 {
0107 return 0;
0108 }
0109 if (!std::filesystem::exists(m_Params->get_string_param("MapFileName")))
0110 {
0111 std::cout << PHWHERE << " Could not locate " << m_Params->get_string_param("MapFileName") << std::endl;
0112 std::cout << "use empty filename to ignore mapfile" << std::endl;
0113 gSystem->Exit(1);
0114 }
0115 TFile* file = TFile::Open(ihcalmapname.c_str());
0116 file->GetObject(m_Params->get_string_param("MapHistoName").c_str(), m_MapCorrHist);
0117 if (!m_MapCorrHist)
0118 {
0119 std::cout << "ERROR: could not find Histogram " << m_Params->get_string_param("MapHistoName") << " in " << m_Params->get_string_param("MapFileName") << std::endl;
0120 gSystem->Exit(1);
0121 }
0122 m_MapCorrHist->SetDirectory(nullptr);
0123 file->Close();
0124 delete file;
0125 }
0126 if (!m_doG4Hit)
0127 {
0128 try
0129 {
0130 CreateNodeTree(topNode);
0131 }
0132 catch (std::exception& e)
0133 {
0134 std::cout << e.what() << std::endl;
0135 return Fun4AllReturnCodes::ABORTRUN;
0136 }
0137 if (Verbosity() > 1)
0138 {
0139 topNode->print();
0140 }
0141 }
0142
0143 return 0;
0144 }
0145
0146
0147 bool PHG4IHCalSteppingAction::NoHitSteppingAction(const G4Step* aStep)
0148 {
0149 G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();
0150 G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle();
0151
0152 G4VPhysicalVolume* volume = touch->GetVolume();
0153
0154
0155
0156
0157
0158
0159
0160 int whichactive = m_Detector->IsInIHCal(volume);
0161
0162 if (!whichactive)
0163 {
0164 return false;
0165 }
0166 int layer_id = -1;
0167 int tower_id = -1;
0168
0169 if (whichactive > 0)
0170 {
0171 std::tuple<int, int, int> layer_tower = m_Detector->GetLayerTowerId(volume);
0172
0173 layer_id = std::get<1>(layer_tower);
0174 tower_id = std::get<2>(layer_tower);
0175
0176
0177 }
0178 else
0179 {
0180
0181 return false;
0182 }
0183
0184 if (!m_IsActive)
0185 {
0186 return false;
0187 }
0188
0189 G4StepPoint* prePoint = aStep->GetPreStepPoint();
0190 G4StepPoint* postPoint = aStep->GetPostStepPoint();
0191
0192 double pretime = prePoint->GetGlobalTime() / nanosecond;
0193 double posttime = postPoint->GetGlobalTime() / nanosecond;
0194 if (posttime < m_tmin || pretime > m_tmax)
0195 {
0196 return false;
0197 }
0198 if ((posttime - pretime) > m_dt)
0199 {
0200 return false;
0201 }
0202 G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV;
0203 const G4Track* aTrack = aStep->GetTrack();
0204
0205 double light_yield = eion;
0206
0207
0208 if (m_LightScintModelFlag)
0209 {
0210 light_yield = GetVisibleEnergyDeposition(aStep);
0211 if (m_MapCorrHist)
0212 {
0213 const G4TouchableHandle& theTouchable = prePoint->GetTouchableHandle();
0214 const G4ThreeVector& worldPosition = postPoint->GetPosition();
0215 G4ThreeVector localPosition = theTouchable->GetHistory()->GetTopTransform().TransformPoint(worldPosition);
0216 float lx = localPosition.x() / cm;
0217 float ly = localPosition.y() / cm;
0218
0219
0220 int lcx = (int) (5.0 * lx) + 1;
0221 int lcy = (int) (5.0 * (ly + 2.0)) + 1;
0222
0223 if ((lcy >= 1) && (lcy <= m_MapCorrHist->GetNbinsY()) &&
0224 (lcx >= 1) && (lcx <= m_MapCorrHist->GetNbinsX()))
0225 {
0226 light_yield *= m_MapCorrHist->GetBinContent(lcx, lcy);
0227 }
0228 else
0229 {
0230 light_yield = 0.0;
0231 }
0232 }
0233 else
0234 {
0235 light_yield = light_yield * GetLightCorrection(postPoint->GetPosition().x(), postPoint->GetPosition().y());
0236 }
0237 }
0238
0239 unsigned int ieta = tower_id;
0240 unsigned int iphi = (unsigned int) layer_id / 4;
0241 unsigned int tower_key = TowerInfoDefs::encode_hcal(ieta, iphi);
0242 m_CaloInfoContainer->get_tower_at_key(tower_key)->set_energy(m_CaloInfoContainer->get_tower_at_key(tower_key)->get_energy() + light_yield);
0243
0244 if (light_yield > 0)
0245 {
0246 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0247 {
0248 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0249 {
0250 pp->SetKeep(1);
0251 }
0252 }
0253 }
0254
0255 return true;
0256 }
0257
0258 bool PHG4IHCalSteppingAction::UserSteppingAction(const G4Step* aStep, bool )
0259 {
0260 if ((!m_doG4Hit) && (!m_IsBlackHole))
0261 {
0262 return NoHitSteppingAction(aStep);
0263 }
0264
0265 G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();
0266 G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle();
0267
0268 G4VPhysicalVolume* volume = touch->GetVolume();
0269
0270
0271
0272
0273
0274
0275
0276 int whichactive = m_Detector->IsInIHCal(volume);
0277
0278 if (!whichactive)
0279 {
0280 return false;
0281 }
0282 int layer_id = -1;
0283 int tower_id = -1;
0284 int sector_id = -1;
0285 if (whichactive > 0)
0286 {
0287 std::tuple<int, int, int> layer_tower = m_Detector->GetLayerTowerId(volume);
0288 sector_id = std::get<0>(layer_tower);
0289 layer_id = std::get<1>(layer_tower);
0290 tower_id = std::get<2>(layer_tower);
0291
0292
0293 }
0294 else
0295 {
0296 layer_id = m_Detector->GetSectorId(volume);
0297 }
0298
0299 G4double edep = aStep->GetTotalEnergyDeposit() / GeV;
0300 G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV;
0301 double light_yield = 0;
0302 const G4Track* aTrack = aStep->GetTrack();
0303
0304
0305 if (m_IsBlackHole)
0306 {
0307 edep = aTrack->GetKineticEnergy() / GeV;
0308 G4Track* killtrack = const_cast<G4Track*>(aTrack);
0309 killtrack->SetTrackStatus(fStopAndKill);
0310 }
0311
0312
0313 if (m_IsActive)
0314 {
0315 bool geantino = false;
0316
0317
0318
0319
0320 if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0 &&
0321 aTrack->GetParticleDefinition()->GetParticleName().find("geantino") != std::string::npos)
0322 {
0323 geantino = true;
0324 }
0325 G4StepPoint* prePoint = aStep->GetPreStepPoint();
0326 G4StepPoint* postPoint = aStep->GetPostStepPoint();
0327
0328
0329
0330 switch (prePoint->GetStepStatus())
0331 {
0332 case fPostStepDoItProc:
0333 if (m_SavePostStepStatus != fGeomBoundary)
0334 {
0335 if (m_SavePostStepStatus != fAtRestDoItProc)
0336 {
0337 break;
0338 }
0339
0340 if (aTrack->GetTrackID() == m_SaveTrackId)
0341 {
0342 std::cout << GetName() << ": Bad step status combination for the same track " << std::endl;
0343 std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0344 << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0345 << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0346 << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0347 std::cout << "last track: " << m_SaveTrackId
0348 << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0349 std::cout << "phys pre vol: " << volume->GetName()
0350 << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0351 std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0352 << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0353 gSystem->Exit(1);
0354 }
0355 }
0356 else
0357 {
0358 std::cout << GetName() << ": New Hit for " << std::endl;
0359 std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0360 << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0361 << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0362 << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0363 std::cout << "last track: " << m_SaveTrackId
0364 << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0365 std::cout << "phys pre vol: " << volume->GetName()
0366 << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0367 std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0368 << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0369 }
0370 [[fallthrough]];
0371 case fGeomBoundary:
0372 case fUndefined:
0373
0374
0375 if (!m_Hit)
0376 {
0377 m_Hit = new PHG4Hitv1();
0378 }
0379
0380 m_Hit->set_x(0, prePoint->GetPosition().x() / cm);
0381 m_Hit->set_y(0, prePoint->GetPosition().y() / cm);
0382 m_Hit->set_z(0, prePoint->GetPosition().z() / cm);
0383
0384 m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
0385
0386 m_Hit->set_trkid(aTrack->GetTrackID());
0387 m_SaveTrackId = aTrack->GetTrackID();
0388
0389 m_Hit->set_edep(0);
0390 if (whichactive > 0)
0391 {
0392 m_Hit->set_sector(sector_id);
0393 m_Hit->set_scint_id(tower_id);
0394 m_Hit->set_eion(0);
0395 m_Hit->set_raw_light_yield(0);
0396 m_Hit->set_light_yield(0);
0397
0398 m_SaveHitContainer = m_HitContainer;
0399 }
0400 else
0401 {
0402 m_SaveHitContainer = m_AbsorberHitContainer;
0403 }
0404 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0405 {
0406 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0407 {
0408 m_Hit->set_trkid(pp->GetUserTrackId());
0409 m_Hit->set_shower_id(pp->GetShower()->get_id());
0410 m_SaveShower = pp->GetShower();
0411 }
0412 }
0413 break;
0414 default:
0415 break;
0416 }
0417
0418
0419 if (!m_Hit || !std::isfinite(m_Hit->get_x(0)))
0420 {
0421 std::cout << GetName() << ": hit was not created" << std::endl;
0422 std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0423 << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0424 << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0425 << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0426 std::cout << "last track: " << m_SaveTrackId
0427 << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0428 std::cout << "phys pre vol: " << volume->GetName()
0429 << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0430 std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0431 << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0432 gSystem->Exit(1);
0433 }
0434
0435 if (aTrack->GetTrackID() != m_SaveTrackId)
0436 {
0437 std::cout << GetName() << ": hits do not belong to the same track" << std::endl;
0438 std::cout << "saved track: " << m_SaveTrackId
0439 << ", current trackid: " << aTrack->GetTrackID()
0440 << ", prestep status: " << prePoint->GetStepStatus()
0441 << ", previous post step status: " << m_SavePostStepStatus
0442 << std::endl;
0443
0444 gSystem->Exit(1);
0445 }
0446 m_SavePreStepStatus = prePoint->GetStepStatus();
0447 m_SavePostStepStatus = postPoint->GetStepStatus();
0448 m_SaveVolPre = volume;
0449 m_SaveVolPost = touchpost->GetVolume();
0450
0451
0452
0453 m_Hit->set_x(1, postPoint->GetPosition().x() / cm);
0454 m_Hit->set_y(1, postPoint->GetPosition().y() / cm);
0455 m_Hit->set_z(1, postPoint->GetPosition().z() / cm);
0456
0457 m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);
0458
0459
0460 m_Hit->set_edep(m_Hit->get_edep() + edep);
0461 if (whichactive > 0)
0462 {
0463 m_Hit->set_eion(m_Hit->get_eion() + eion);
0464 light_yield = eion;
0465 if (m_LightScintModelFlag)
0466 {
0467 light_yield = GetVisibleEnergyDeposition(aStep);
0468 m_Hit->set_raw_light_yield(m_Hit->get_raw_light_yield() + light_yield);
0469 if (m_MapCorrHist)
0470 {
0471 const G4TouchableHandle& theTouchable = prePoint->GetTouchableHandle();
0472 const G4ThreeVector& worldPosition = postPoint->GetPosition();
0473 G4ThreeVector localPosition = theTouchable->GetHistory()->GetTopTransform().TransformPoint(worldPosition);
0474 float lx = localPosition.x() / cm;
0475 float ly = localPosition.y() / cm;
0476
0477
0478 int lcx = (int) (5.0 * lx) + 1;
0479 int lcy = (int) (5.0 * (ly + 2.0)) + 1;
0480
0481 if ((lcy >= 1) && (lcy <= m_MapCorrHist->GetNbinsY()) &&
0482 (lcx >= 1) && (lcx <= m_MapCorrHist->GetNbinsX()))
0483 {
0484 light_yield *= m_MapCorrHist->GetBinContent(lcx, lcy);
0485 }
0486 else
0487 {
0488 light_yield = 0.0;
0489 }
0490 }
0491 else
0492 {
0493 light_yield = light_yield * GetLightCorrection(postPoint->GetPosition().x(), postPoint->GetPosition().y());
0494 }
0495 }
0496 m_Hit->set_light_yield(m_Hit->get_light_yield() + light_yield);
0497 }
0498 if (geantino)
0499 {
0500 m_Hit->set_edep(-1);
0501 m_Hit->set_eion(-1);
0502 }
0503 if (edep > 0)
0504 {
0505 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0506 {
0507 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0508 {
0509 pp->SetKeep(1);
0510 }
0511 }
0512 }
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522 if (postPoint->GetStepStatus() == fGeomBoundary ||
0523 postPoint->GetStepStatus() == fWorldBoundary ||
0524 postPoint->GetStepStatus() == fAtRestDoItProc ||
0525 aTrack->GetTrackStatus() == fStopAndKill)
0526 {
0527
0528 if (m_Hit->get_edep() != 0)
0529 {
0530 m_SaveHitContainer->AddHit(layer_id, m_Hit);
0531
0532 if (m_SaveShower)
0533 {
0534 m_SaveShower->add_g4hit_id(m_SaveHitContainer->GetID(), m_Hit->get_hit_id());
0535 }
0536
0537
0538 m_Hit = nullptr;
0539 }
0540 else
0541 {
0542
0543
0544
0545 m_Hit->Reset();
0546 }
0547 }
0548
0549 return true;
0550 }
0551
0552 return false;
0553 }
0554
0555
0556 void PHG4IHCalSteppingAction::SetInterfacePointers(PHCompositeNode* topNode)
0557 {
0558 m_HitContainer = findNode::getClass<PHG4HitContainer>(topNode, m_HitNodeName);
0559 m_AbsorberHitContainer = findNode::getClass<PHG4HitContainer>(topNode, m_AbsorberNodeName);
0560
0561
0562 if (!m_HitContainer)
0563 {
0564 std::cout << "PHG4IHCalSteppingAction::SetTopNode - unable to find " << m_HitNodeName << std::endl;
0565 }
0566 if (!m_AbsorberHitContainer)
0567 {
0568 if (Verbosity() > 1)
0569 {
0570 std::cout << "PHG4IHcalSteppingAction::SetTopNode - unable to find " << m_AbsorberNodeName << std::endl;
0571 }
0572 }
0573 }
0574
0575 void PHG4IHCalSteppingAction::SetHitNodeName(const std::string& type, const std::string& name)
0576 {
0577 if (type == "G4HIT")
0578 {
0579 m_HitNodeName = name;
0580 return;
0581 }
0582 if (type == "G4HIT_ABSORBER")
0583 {
0584 m_AbsorberNodeName = name;
0585 return;
0586 }
0587 std::cout << "Invalid output hit node type " << type << std::endl;
0588 gSystem->Exit(1);
0589 return;
0590 }
0591
0592 void PHG4IHCalSteppingAction::CreateNodeTree(PHCompositeNode* topNode)
0593 {
0594 PHNodeIterator nodeItr(topNode);
0595 PHCompositeNode* dst_node = dynamic_cast<PHCompositeNode*>(
0596 nodeItr.findFirst("PHCompositeNode", "DST"));
0597 if (!dst_node)
0598 {
0599 std::cout << "PHComposite node created: DST" << std::endl;
0600 dst_node = new PHCompositeNode("DST");
0601 topNode->addNode(dst_node);
0602 }
0603 PHNodeIterator dstiter(dst_node);
0604 PHCompositeNode* DetNode = dynamic_cast<PHCompositeNode*>(dstiter.findFirst("PHCompositeNode", m_Detector->SuperDetector()));
0605 if (!DetNode)
0606 {
0607 DetNode = new PHCompositeNode(m_Detector->SuperDetector());
0608 dst_node->addNode(DetNode);
0609 }
0610 m_CaloInfoContainer = new TowerInfoContainerv1(TowerInfoContainer::DETECTOR::HCAL);
0611 PHIODataNode<PHObject>* towerNode = new PHIODataNode<PHObject>(m_CaloInfoContainer, "TOWERINFO_SIM_" + m_Detector->SuperDetector(), "PHObject");
0612 DetNode->addNode(towerNode);
0613 }