File indexing completed on 2025-08-05 08:18:04
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 else
0340 {
0341 if (aTrack->GetTrackID() == m_SaveTrackId)
0342 {
0343 std::cout << GetName() << ": Bad step status combination for the same track " << std::endl;
0344 std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0345 << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0346 << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0347 << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0348 std::cout << "last track: " << m_SaveTrackId
0349 << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0350 std::cout << "phys pre vol: " << volume->GetName()
0351 << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0352 std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0353 << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0354 gSystem->Exit(1);
0355 }
0356 }
0357 }
0358 else
0359 {
0360 std::cout << GetName() << ": New Hit for " << std::endl;
0361 std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0362 << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0363 << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0364 << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0365 std::cout << "last track: " << m_SaveTrackId
0366 << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0367 std::cout << "phys pre vol: " << volume->GetName()
0368 << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0369 std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0370 << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0371 }
0372 [[fallthrough]];
0373 case fGeomBoundary:
0374 case fUndefined:
0375
0376
0377 if (!m_Hit)
0378 {
0379 m_Hit = new PHG4Hitv1();
0380 }
0381
0382 m_Hit->set_x(0, prePoint->GetPosition().x() / cm);
0383 m_Hit->set_y(0, prePoint->GetPosition().y() / cm);
0384 m_Hit->set_z(0, prePoint->GetPosition().z() / cm);
0385
0386 m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
0387
0388 m_Hit->set_trkid(aTrack->GetTrackID());
0389 m_SaveTrackId = aTrack->GetTrackID();
0390
0391 m_Hit->set_edep(0);
0392 if (whichactive > 0)
0393 {
0394 m_Hit->set_sector(sector_id);
0395 m_Hit->set_scint_id(tower_id);
0396 m_Hit->set_eion(0);
0397 m_Hit->set_raw_light_yield(0);
0398 m_Hit->set_light_yield(0);
0399
0400 m_SaveHitContainer = m_HitContainer;
0401 }
0402 else
0403 {
0404 m_SaveHitContainer = m_AbsorberHitContainer;
0405 }
0406 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0407 {
0408 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0409 {
0410 m_Hit->set_trkid(pp->GetUserTrackId());
0411 m_Hit->set_shower_id(pp->GetShower()->get_id());
0412 m_SaveShower = pp->GetShower();
0413 }
0414 }
0415 break;
0416 default:
0417 break;
0418 }
0419
0420
0421 if (!m_Hit || !std::isfinite(m_Hit->get_x(0)))
0422 {
0423 std::cout << GetName() << ": hit was not created" << std::endl;
0424 std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0425 << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0426 << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0427 << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0428 std::cout << "last track: " << m_SaveTrackId
0429 << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0430 std::cout << "phys pre vol: " << volume->GetName()
0431 << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0432 std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0433 << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0434 gSystem->Exit(1);
0435 }
0436
0437 if (aTrack->GetTrackID() != m_SaveTrackId)
0438 {
0439 std::cout << GetName() << ": hits do not belong to the same track" << std::endl;
0440 std::cout << "saved track: " << m_SaveTrackId
0441 << ", current trackid: " << aTrack->GetTrackID()
0442 << ", prestep status: " << prePoint->GetStepStatus()
0443 << ", previous post step status: " << m_SavePostStepStatus
0444 << std::endl;
0445
0446 gSystem->Exit(1);
0447 }
0448 m_SavePreStepStatus = prePoint->GetStepStatus();
0449 m_SavePostStepStatus = postPoint->GetStepStatus();
0450 m_SaveVolPre = volume;
0451 m_SaveVolPost = touchpost->GetVolume();
0452
0453
0454
0455 m_Hit->set_x(1, postPoint->GetPosition().x() / cm);
0456 m_Hit->set_y(1, postPoint->GetPosition().y() / cm);
0457 m_Hit->set_z(1, postPoint->GetPosition().z() / cm);
0458
0459 m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);
0460
0461
0462 m_Hit->set_edep(m_Hit->get_edep() + edep);
0463 if (whichactive > 0)
0464 {
0465 m_Hit->set_eion(m_Hit->get_eion() + eion);
0466 light_yield = eion;
0467 if (m_LightScintModelFlag)
0468 {
0469 light_yield = GetVisibleEnergyDeposition(aStep);
0470 m_Hit->set_raw_light_yield(m_Hit->get_raw_light_yield() + light_yield);
0471 if (m_MapCorrHist)
0472 {
0473 const G4TouchableHandle& theTouchable = prePoint->GetTouchableHandle();
0474 const G4ThreeVector& worldPosition = postPoint->GetPosition();
0475 G4ThreeVector localPosition = theTouchable->GetHistory()->GetTopTransform().TransformPoint(worldPosition);
0476 float lx = localPosition.x() / cm;
0477 float ly = localPosition.y() / cm;
0478
0479
0480 int lcx = (int) (5.0 * lx) + 1;
0481 int lcy = (int) (5.0 * (ly + 2.0)) + 1;
0482
0483 if ((lcy >= 1) && (lcy <= m_MapCorrHist->GetNbinsY()) &&
0484 (lcx >= 1) && (lcx <= m_MapCorrHist->GetNbinsX()))
0485 {
0486 light_yield *= m_MapCorrHist->GetBinContent(lcx, lcy);
0487 }
0488 else
0489 {
0490 light_yield = 0.0;
0491 }
0492 }
0493 else
0494 {
0495 light_yield = light_yield * GetLightCorrection(postPoint->GetPosition().x(), postPoint->GetPosition().y());
0496 }
0497 }
0498 m_Hit->set_light_yield(m_Hit->get_light_yield() + light_yield);
0499 }
0500 if (geantino)
0501 {
0502 m_Hit->set_edep(-1);
0503 m_Hit->set_eion(-1);
0504 }
0505 if (edep > 0)
0506 {
0507 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0508 {
0509 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0510 {
0511 pp->SetKeep(1);
0512 }
0513 }
0514 }
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524 if (postPoint->GetStepStatus() == fGeomBoundary ||
0525 postPoint->GetStepStatus() == fWorldBoundary ||
0526 postPoint->GetStepStatus() == fAtRestDoItProc ||
0527 aTrack->GetTrackStatus() == fStopAndKill)
0528 {
0529
0530 if (m_Hit->get_edep() != 0)
0531 {
0532 m_SaveHitContainer->AddHit(layer_id, m_Hit);
0533
0534 if (m_SaveShower)
0535 {
0536 m_SaveShower->add_g4hit_id(m_SaveHitContainer->GetID(), m_Hit->get_hit_id());
0537 }
0538
0539
0540 m_Hit = nullptr;
0541 }
0542 else
0543 {
0544
0545
0546
0547 m_Hit->Reset();
0548 }
0549 }
0550
0551 return true;
0552 }
0553 else
0554 {
0555 return false;
0556 }
0557 }
0558
0559
0560 void PHG4IHCalSteppingAction::SetInterfacePointers(PHCompositeNode* topNode)
0561 {
0562 m_HitContainer = findNode::getClass<PHG4HitContainer>(topNode, m_HitNodeName);
0563 m_AbsorberHitContainer = findNode::getClass<PHG4HitContainer>(topNode, m_AbsorberNodeName);
0564
0565
0566 if (!m_HitContainer)
0567 {
0568 std::cout << "PHG4IHCalSteppingAction::SetTopNode - unable to find " << m_HitNodeName << std::endl;
0569 }
0570 if (!m_AbsorberHitContainer)
0571 {
0572 if (Verbosity() > 1)
0573 {
0574 std::cout << "PHG4IHcalSteppingAction::SetTopNode - unable to find " << m_AbsorberNodeName << std::endl;
0575 }
0576 }
0577 }
0578
0579 void PHG4IHCalSteppingAction::SetHitNodeName(const std::string& type, const std::string& name)
0580 {
0581 if (type == "G4HIT")
0582 {
0583 m_HitNodeName = name;
0584 return;
0585 }
0586 else if (type == "G4HIT_ABSORBER")
0587 {
0588 m_AbsorberNodeName = name;
0589 return;
0590 }
0591 std::cout << "Invalid output hit node type " << type << std::endl;
0592 gSystem->Exit(1);
0593 return;
0594 }
0595
0596 void PHG4IHCalSteppingAction::CreateNodeTree(PHCompositeNode* topNode)
0597 {
0598 PHNodeIterator nodeItr(topNode);
0599 PHCompositeNode* dst_node = dynamic_cast<PHCompositeNode*>(
0600 nodeItr.findFirst("PHCompositeNode", "DST"));
0601 if (!dst_node)
0602 {
0603 std::cout << "PHComposite node created: DST" << std::endl;
0604 dst_node = new PHCompositeNode("DST");
0605 topNode->addNode(dst_node);
0606 }
0607 PHNodeIterator dstiter(dst_node);
0608 PHCompositeNode* DetNode = dynamic_cast<PHCompositeNode*>(dstiter.findFirst("PHCompositeNode", m_Detector->SuperDetector()));
0609 if (!DetNode)
0610 {
0611 DetNode = new PHCompositeNode(m_Detector->SuperDetector());
0612 dst_node->addNode(DetNode);
0613 }
0614 m_CaloInfoContainer = new TowerInfoContainerv1(TowerInfoContainer::DETECTOR::HCAL);
0615 PHIODataNode<PHObject>* towerNode = new PHIODataNode<PHObject>(m_CaloInfoContainer, "TOWERINFO_SIM_" + m_Detector->SuperDetector(), "PHObject");
0616 DetNode->addNode(towerNode);
0617 }