Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-17 09:21:39

0001 #include "PHG4InnerHcalSteppingAction.h"
0002 
0003 #include "PHG4InnerHcalDetector.h"
0004 #include "PHG4StepStatusDecode.h"
0005 
0006 #include <phparameter/PHParameters.h>
0007 
0008 #include <g4main/PHG4Hit.h>
0009 #include <g4main/PHG4HitContainer.h>
0010 #include <g4main/PHG4Hitv1.h>
0011 #include <g4main/PHG4Shower.h>
0012 #include <g4main/PHG4SteppingAction.h>  // for PHG4SteppingAction
0013 #include <g4main/PHG4TrackUserInfoV1.h>
0014 
0015 #include <ffamodules/CDBInterface.h>
0016 
0017 #include <fun4all/Fun4AllReturnCodes.h>
0018 
0019 #include <calobase/TowerInfo.h>
0020 #include <calobase/TowerInfoContainer.h>
0021 #include <calobase/TowerInfoContainerv1.h>
0022 #include <calobase/TowerInfoDefs.h>
0023 
0024 #include <phool/PHCompositeNode.h>
0025 #include <phool/PHIODataNode.h>    // for PHIODataNode
0026 #include <phool/PHNode.h>          // for PHNode
0027 #include <phool/PHNodeIterator.h>  // for PHNodeIterator
0028 #include <phool/PHObject.h>        // for PHObject
0029 #include <phool/getClass.h>
0030 
0031 #include <TSystem.h>
0032 
0033 // Root headers
0034 #include <TFile.h>
0035 #include <TH2.h>
0036 
0037 #include <Geant4/G4ParticleDefinition.hh>      // for G4ParticleDefinition
0038 #include <Geant4/G4ReferenceCountedHandle.hh>  // for G4ReferenceCountedHandle
0039 #include <Geant4/G4Step.hh>
0040 #include <Geant4/G4StepPoint.hh>   // for G4StepPoint
0041 #include <Geant4/G4StepStatus.hh>  // for fGeomBoundary, fAtRest...
0042 #include <Geant4/G4String.hh>      // for G4String
0043 #include <Geant4/G4SystemOfUnits.hh>
0044 #include <Geant4/G4ThreeVector.hh>      // for G4ThreeVector
0045 #include <Geant4/G4TouchableHandle.hh>  // for G4TouchableHandle
0046 #include <Geant4/G4Track.hh>            // for G4Track
0047 #include <Geant4/G4TrackStatus.hh>      // for fStopAndKill
0048 #include <Geant4/G4TransportationManager.hh>
0049 #include <Geant4/G4Types.hh>                  // for G4double
0050 #include <Geant4/G4VPhysicalVolume.hh>        // for G4VPhysicalVolume
0051 #include <Geant4/G4VTouchable.hh>             // for G4VTouchable
0052 #include <Geant4/G4VUserTrackInformation.hh>  // for G4VUserTrackInformation
0053 
0054 #include <cmath>  // for isfinite
0055 #include <cstdlib>
0056 #include <filesystem>
0057 #include <iostream>
0058 #include <string>   // for operator<<, operator+
0059 #include <utility>  // for pair
0060 
0061 class PHCompositeNode;
0062 
0063 //____________________________________________________________________________..
0064 PHG4InnerHcalSteppingAction::PHG4InnerHcalSteppingAction(PHG4InnerHcalDetector* detector, const PHParameters* parameters)
0065   : PHG4SteppingAction(detector->GetName())
0066   , m_Detector(detector)
0067   , m_Params(parameters)
0068   , m_IsActive(m_Params->get_int_param("active"))
0069   , m_IsBlackHole(m_Params->get_int_param("blackhole"))
0070   , m_LightScintModelFlag(m_Params->get_int_param("light_scint_model"))
0071   , m_doG4Hit(m_Params->get_int_param("saveg4hit"))
0072   , m_tmin(m_Params->get_double_param("tmin"))
0073   , m_tmax(m_Params->get_double_param("tmax"))
0074   , m_dt(m_Params->get_double_param("dt"))
0075 {
0076   SetLightCorrection(m_Params->get_double_param("light_balance_inner_radius") * cm,
0077                      m_Params->get_double_param("light_balance_inner_corr"),
0078                      m_Params->get_double_param("light_balance_outer_radius") * cm,
0079                      m_Params->get_double_param("light_balance_outer_corr"));
0080 }
0081 
0082 PHG4InnerHcalSteppingAction::~PHG4InnerHcalSteppingAction()
0083 {
0084   // if the last hit was a zero energie deposit hit, it is just reset
0085   // and the memory is still allocated, so we need to delete it here
0086   // if the last hit was saved, hit is a nullptr pointer which are
0087   // legal to delete (it results in a no operation)
0088   delete m_Hit;
0089   // since we have a copy in memory of this one - we need to delete it
0090   delete m_MapCorrHist;
0091 }
0092 
0093 //____________________________________________________________________________..
0094 int PHG4InnerHcalSteppingAction::InitWithNode(PHCompositeNode* topNode)
0095 {
0096   if (m_LightScintModelFlag)
0097   {
0098     std::string ihcalmapname(m_Params->get_string_param("MapFileName"));
0099     if (ihcalmapname.empty())
0100     {
0101       return 0;
0102     }
0103     std::string url = CDBInterface::instance()->getUrl("OLD_INNER_HCAL_TILEMAP", ihcalmapname);
0104     if (!std::filesystem::exists(url))
0105     {
0106       std::cout << PHWHERE << " Could not locate " << url << std::endl;
0107       std::cout << "use empty filename to ignore mapfile" << std::endl;
0108       gSystem->Exit(1);
0109     }
0110     TFile* file = TFile::Open(url.c_str());
0111     file->GetObject(m_Params->get_string_param("MapHistoName").c_str(), m_MapCorrHist);
0112     if (!m_MapCorrHist)
0113     {
0114       std::cout << "ERROR: could not find Histogram " << m_Params->get_string_param("MapHistoName") << " in " << m_Params->get_string_param("MapFileName") << std::endl;
0115       gSystem->Exit(1);
0116       exit(1);  // make code checkers which do not know gSystem->Exit() happy
0117     }
0118     m_MapCorrHist->SetDirectory(nullptr);  // rootism: this needs to be set otherwise histo vanished when closing the file
0119     file->Close();
0120     delete file;
0121   }
0122   if (!m_doG4Hit)
0123   {
0124     try
0125     {
0126       CreateNodeTree(topNode);
0127     }
0128     catch (std::exception& e)
0129     {
0130       std::cout << e.what() << std::endl;
0131       return Fun4AllReturnCodes::ABORTRUN;
0132     }
0133     if (Verbosity() > 1)
0134     {
0135       topNode->print();
0136     }
0137   }
0138 
0139   return 0;
0140 }
0141 
0142 //____________________________________________________________________________..
0143 bool PHG4InnerHcalSteppingAction::NoHitSteppingAction(const G4Step* aStep)
0144 {
0145   G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();
0146   G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle();
0147   // get volume of the current step
0148   G4VPhysicalVolume* volume = touch->GetVolume();
0149 
0150   // m_Detector->IsInIHCal(volume)
0151   // returns
0152   //  0 is outside of IHCal
0153   //  1 is inside scintillator
0154   // -1 is steel absorber
0155 
0156   int whichactive = m_Detector->IsInInnerHcal(volume);
0157 
0158   if (!whichactive)
0159   {
0160     return false;
0161   }
0162   int layer_id = -1;
0163   int tower_id = -1;
0164   if (whichactive > 0)  // scintillator
0165   {
0166     std::pair<int, int> layer_tower = m_Detector->GetLayerTowerId(volume);
0167     layer_id = layer_tower.first;
0168     tower_id = layer_tower.second;
0169 
0170     //    std::cout<<"******** Inner HCal\t"<<volume->GetName()<<"\t"<<layer_id<<"\t"<<tower_id<<std::endl;
0171   }
0172   else
0173   {
0174     // absorber hit, do nothing
0175     return false;
0176   }
0177 
0178   if (!m_IsActive)
0179   {
0180     return false;
0181   }
0182 
0183   G4StepPoint* prePoint = aStep->GetPreStepPoint();
0184   G4StepPoint* postPoint = aStep->GetPostStepPoint();
0185   // time window cut
0186   double pretime = prePoint->GetGlobalTime() / nanosecond;
0187   double posttime = postPoint->GetGlobalTime() / nanosecond;
0188   if (posttime < m_tmin || pretime > m_tmax)
0189   {
0190     return false;
0191   }
0192   if ((posttime - pretime) > m_dt)
0193   {
0194     return false;
0195   }
0196   G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV;
0197   const G4Track* aTrack = aStep->GetTrack();
0198   // we only need visible energy here
0199   double light_yield = eion;
0200 
0201   // correct evis using light map
0202   if (m_LightScintModelFlag)
0203   {
0204     light_yield = GetVisibleEnergyDeposition(aStep);  // for scintillator only, calculate light yields
0205     if (m_MapCorrHist)
0206     {
0207       const G4TouchableHandle& theTouchable = prePoint->GetTouchableHandle();
0208       const G4ThreeVector& worldPosition = postPoint->GetPosition();
0209       G4ThreeVector localPosition = theTouchable->GetHistory()->GetTopTransform().TransformPoint(worldPosition);
0210       float lx = (localPosition.x() / cm);
0211       float lz = fabs(localPosition.z() / cm);
0212       // adjust to tilemap coordinates
0213       int lcz = (int) (5.0 * lz) + 1;
0214       int lcx = (int) (5.0 * (lx + 12.1)) + 1;
0215 
0216       if ((lcx >= 1) && (lcx <= m_MapCorrHist->GetNbinsY()) &&
0217           (lcz >= 1) && (lcz <= m_MapCorrHist->GetNbinsX()))
0218       {
0219         light_yield *= (double) (m_MapCorrHist->GetBinContent(lcz, lcx));
0220       }
0221       else
0222       {
0223         light_yield = 0.0;
0224       }
0225     }
0226     else
0227     {
0228       // old correction (linear ligh yield dependence along r), never tested
0229       light_yield = light_yield * GetLightCorrection(postPoint->GetPosition().x(), postPoint->GetPosition().y());
0230     }
0231   }
0232   // find the tower index for this step, tower_id is ieta, layer_id/4 is iphi
0233   unsigned int ieta = tower_id;
0234   unsigned int iphi = (unsigned int) layer_id / 4;
0235   unsigned int tower_key = TowerInfoDefs::encode_hcal(ieta, iphi);
0236   m_CaloInfoContainer->get_tower_at_key(tower_key)->set_energy(m_CaloInfoContainer->get_tower_at_key(tower_key)->get_energy() + light_yield);
0237   // set keep for the track
0238   if (light_yield > 0)
0239   {
0240     if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0241     {
0242       if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0243       {
0244         pp->SetKeep(1);  // we want to keep the track
0245       }
0246     }
0247   }
0248 
0249   return true;
0250 }
0251 
0252 //____________________________________________________________________________..
0253 bool PHG4InnerHcalSteppingAction::UserSteppingAction(const G4Step* aStep, bool /*was_used*/)
0254 {
0255   if ((!m_doG4Hit) && (!m_IsBlackHole))
0256   {
0257     return NoHitSteppingAction(aStep);
0258   }
0259   G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();
0260   G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle();
0261   // get volume of the current step
0262   G4VPhysicalVolume* volume = touch->GetVolume();
0263 
0264   // m_Detector->IsInInnerHcal(volume)
0265   // returns
0266   //  0 is outside of InnerHcal
0267   //  1 is inside scintillator
0268   // -1 is steel absorber
0269 
0270   int whichactive = m_Detector->IsInInnerHcal(volume);
0271 
0272   if (!whichactive)
0273   {
0274     return false;
0275   }
0276   int layer_id = -1;
0277   int tower_id = -1;
0278   if (whichactive > 0)  // scintillator
0279   {
0280     std::pair<int, int> layer_tower = m_Detector->GetLayerTowerId(volume);
0281     layer_id = layer_tower.first;
0282     tower_id = layer_tower.second;
0283     // std::cout << "name " << volume->GetName() << ", mid: " << layer_id
0284     //         << ", twr: " << tower_id << std::endl;
0285   }
0286   else
0287   {
0288     layer_id = touch->GetCopyNumber();  // steel plate id
0289   }
0290   // collect energy and track length step by step
0291   G4double edep = aStep->GetTotalEnergyDeposit() / GeV;
0292   G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV;
0293   G4double light_yield = 0;
0294   const G4Track* aTrack = aStep->GetTrack();
0295 
0296   // if this block stops everything, just put all kinetic energy into edep
0297   if (m_IsBlackHole)
0298   {
0299     edep = aTrack->GetKineticEnergy() / GeV;
0300     G4Track* killtrack = const_cast<G4Track*>(aTrack);
0301     killtrack->SetTrackStatus(fStopAndKill);
0302   }
0303 
0304   // make sure we are in a volume
0305   if (m_IsActive)
0306   {
0307     bool geantino = false;
0308 
0309     // the check for the pdg code speeds things up, I do not want to make
0310     // an expensive string compare for every track when we know
0311     // geantino or chargedgeantino has pid=0
0312     if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0 &&
0313         aTrack->GetParticleDefinition()->GetParticleName().find("geantino") != std::string::npos)
0314     {
0315       geantino = true;
0316     }
0317     G4StepPoint* prePoint = aStep->GetPreStepPoint();
0318     G4StepPoint* postPoint = aStep->GetPostStepPoint();
0319     //       std::cout << "track id " << aTrack->GetTrackID() << std::endl;
0320     //       std::cout << "time prepoint: " << prePoint->GetGlobalTime() << std::endl;
0321     //       std::cout << "time postpoint: " << postPoint->GetGlobalTime() << std::endl;
0322     switch (prePoint->GetStepStatus())
0323     {
0324     case fPostStepDoItProc:
0325       if (m_SavePostStepStatus != fGeomBoundary)
0326       {
0327         break;
0328       }
0329       else
0330       {
0331         std::cout << GetName() << ": New Hit for  " << std::endl;
0332         std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0333                   << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0334                   << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0335                   << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0336         std::cout << "last track: " << m_SaveTrackId
0337                   << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0338         std::cout << "phys pre vol: " << volume->GetName()
0339                   << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0340         std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0341                   << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0342       }
0343       [[fallthrough]];
0344     case fGeomBoundary:
0345     case fUndefined:
0346       // if previous hit was saved, hit pointer was set to nullptr
0347       // and we have to make a new one
0348       if (!m_Hit)
0349       {
0350         m_Hit = new PHG4Hitv1();
0351       }
0352       // here we set the entrance values in cm
0353       m_Hit->set_x(0, prePoint->GetPosition().x() / cm);
0354       m_Hit->set_y(0, prePoint->GetPosition().y() / cm);
0355       m_Hit->set_z(0, prePoint->GetPosition().z() / cm);
0356       // time in ns
0357       m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
0358       // set and save the track ID
0359       m_Hit->set_trkid(aTrack->GetTrackID());
0360       m_SaveTrackId = aTrack->GetTrackID();
0361       // set the initial energy deposit
0362       m_Hit->set_edep(0);
0363       if (whichactive > 0)  // return of IsInInnerHcalDetector, > 0 hit in scintillator, < 0 hit in absorber
0364       {
0365         m_Hit->set_scint_id(tower_id);  // the slat id
0366         m_Hit->set_eion(0);             // only implemented for v5 otherwise empty
0367         m_Hit->set_raw_light_yield(0);  //  for scintillator only, initialize light yields
0368         m_Hit->set_light_yield(0);      // for scintillator only, initialize light yields
0369         // Now save the container we want to add this hit to
0370         m_SaveHitContainer = m_Hits;
0371       }
0372       else
0373       {
0374         m_SaveHitContainer = m_AbsorberHits;
0375       }
0376       if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0377       {
0378         if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0379         {
0380           m_Hit->set_trkid(pp->GetUserTrackId());
0381           m_Hit->set_shower_id(pp->GetShower()->get_id());
0382           m_SaveShower = pp->GetShower();
0383         }
0384       }
0385       break;
0386     default:
0387       break;
0388     }
0389     // some sanity checks for inconsistencies
0390     // check if this hit was created, if not print out last post step status
0391     if (!m_Hit || !isfinite(m_Hit->get_x(0)))
0392     {
0393       std::cout << GetName() << ": hit was not created" << std::endl;
0394       std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0395                 << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0396                 << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0397                 << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0398       std::cout << "last track: " << m_SaveTrackId
0399                 << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0400       std::cout << "phys pre vol: " << volume->GetName()
0401                 << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0402       std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0403                 << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0404       gSystem->Exit(1);
0405     }
0406     // check if track id matches the initial one when the hit was created
0407     if (aTrack->GetTrackID() != m_SaveTrackId)
0408     {
0409       std::cout << GetName() << ": hits do not belong to the same track" << std::endl;
0410       std::cout << "saved track: " << m_SaveTrackId
0411                 << ", current trackid: " << aTrack->GetTrackID()
0412                 << ", prestep status: " << prePoint->GetStepStatus()
0413                 << ", previous post step status: " << m_SavePostStepStatus
0414                 << std::endl;
0415 
0416       gSystem->Exit(1);
0417     }
0418     m_SavePreStepStatus = prePoint->GetStepStatus();
0419     m_SavePostStepStatus = postPoint->GetStepStatus();
0420     m_SaveVolPre = volume;
0421     m_SaveVolPost = touchpost->GetVolume();
0422     // here we just update the exit values, it will be overwritten
0423     // for every step until we leave the volume or the particle
0424     // ceases to exist
0425     m_Hit->set_x(1, postPoint->GetPosition().x() / cm);
0426     m_Hit->set_y(1, postPoint->GetPosition().y() / cm);
0427     m_Hit->set_z(1, postPoint->GetPosition().z() / cm);
0428 
0429     m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);
0430 
0431     // sum up the energy to get total deposited
0432     m_Hit->set_edep(m_Hit->get_edep() + edep);
0433     if (whichactive > 0)  // return of IsInInnerHcalDetector, > 0 hit in scintillator, < 0 hit in absorber
0434     {
0435       m_Hit->set_eion(m_Hit->get_eion() + eion);
0436       light_yield = eion;
0437       if (m_LightScintModelFlag)
0438       {
0439         light_yield = GetVisibleEnergyDeposition(aStep);                         // for scintillator only, calculate light yields
0440         m_Hit->set_raw_light_yield(m_Hit->get_raw_light_yield() + light_yield);  // save raw Birks light yield
0441         if (m_MapCorrHist)
0442         {
0443           const G4TouchableHandle& theTouchable = prePoint->GetTouchableHandle();
0444           const G4ThreeVector& worldPosition = postPoint->GetPosition();
0445           G4ThreeVector localPosition = theTouchable->GetHistory()->GetTopTransform().TransformPoint(worldPosition);
0446           float lx = (localPosition.x() / cm);
0447           float lz = fabs(localPosition.z() / cm);
0448           // adjust to tilemap coordinates
0449           int lcz = (int) (5.0 * lz) + 1;
0450           int lcx = (int) (5.0 * (lx + 12.1)) + 1;
0451 
0452           if ((lcx >= 1) && (lcx <= m_MapCorrHist->GetNbinsY()) &&
0453               (lcz >= 1) && (lcz <= m_MapCorrHist->GetNbinsX()))
0454           {
0455             light_yield *= (double) (m_MapCorrHist->GetBinContent(lcz, lcx));
0456           }
0457           else
0458           {
0459             light_yield = 0.0;
0460           }
0461         }
0462         else
0463         {
0464           // old correction (linear ligh yield dependence along r), never tested
0465           light_yield = light_yield * GetLightCorrection(postPoint->GetPosition().x(), postPoint->GetPosition().y());
0466         }
0467       }
0468       m_Hit->set_light_yield(m_Hit->get_light_yield() + light_yield);
0469     }
0470     if (geantino)
0471     {
0472       m_Hit->set_edep(-1);  // only energy=0 g4hits get dropped, this way geantinos survive the g4hit compression
0473       m_Hit->set_eion(-1);
0474     }
0475     if (edep > 0)
0476     {
0477       if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0478       {
0479         if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0480         {
0481           pp->SetKeep(1);  // we want to keep the track
0482         }
0483       }
0484     }
0485 
0486     // if any of these conditions is true this is the last step in
0487     // this volume and we need to save the hit
0488     // postPoint->GetStepStatus() == fGeomBoundary: track leaves this volume
0489     // postPoint->GetStepStatus() == fWorldBoundary: track leaves this world
0490     // (happens when your detector goes outside world volume)
0491     // postPoint->GetStepStatus() == fAtRestDoItProc: track stops (typically
0492     // aTrack->GetTrackStatus() == fStopAndKill is also set)
0493     // aTrack->GetTrackStatus() == fStopAndKill: track ends
0494     if (postPoint->GetStepStatus() == fGeomBoundary ||
0495         postPoint->GetStepStatus() == fWorldBoundary ||
0496         postPoint->GetStepStatus() == fAtRestDoItProc ||
0497         aTrack->GetTrackStatus() == fStopAndKill)
0498     {
0499       // save only hits with energy deposit (or -1 for geantino)
0500       if (m_Hit->get_edep() != 0)
0501       {
0502         m_SaveHitContainer->AddHit(layer_id, m_Hit);
0503 
0504         if (m_SaveShower)
0505         {
0506           m_SaveShower->add_g4hit_id(m_SaveHitContainer->GetID(), m_Hit->get_hit_id());
0507         }
0508         // ownership has been transferred to container, set to null
0509         // so we will create a new hit for the next track
0510         m_Hit = nullptr;
0511       }
0512       else
0513       {
0514         // if this hit has no energy deposit, just reset it for reuse
0515         // this means we have to delete it in the dtor. If this was
0516         // the last hit we processed the memory is still allocated
0517         m_Hit->Reset();
0518       }
0519     }
0520     // return true to indicate the hit was used
0521     return true;
0522   }
0523   
0524       return false;
0525  
0526 }
0527 
0528 //____________________________________________________________________________..
0529 void PHG4InnerHcalSteppingAction::SetInterfacePointers(PHCompositeNode* topNode)
0530 {
0531   std::string hitnodename;
0532   std::string absorbernodename;
0533   if (m_Detector->SuperDetector() != "NONE")
0534   {
0535     hitnodename = "G4HIT_" + m_Detector->SuperDetector();
0536     absorbernodename = "G4HIT_ABSORBER_" + m_Detector->SuperDetector();
0537   }
0538   else
0539   {
0540     hitnodename = "G4HIT_" + m_Detector->GetName();
0541     absorbernodename = "G4HIT_ABSORBER_" + m_Detector->GetName();
0542   }
0543 
0544   // now look for the map and grab a pointer to it.
0545   m_Hits = findNode::getClass<PHG4HitContainer>(topNode, hitnodename);
0546   m_AbsorberHits = findNode::getClass<PHG4HitContainer>(topNode, absorbernodename);
0547 
0548   // if we do not find the node it's messed up.
0549   if (!m_Hits)
0550   {
0551     std::cout << "PHG4InnerHcalSteppingAction::SetTopNode - unable to find " << hitnodename << std::endl;
0552   }
0553   if (!m_AbsorberHits)
0554   {
0555     if (Verbosity() > 1)
0556     {
0557       std::cout << "PHG4HcalSteppingAction::SetTopNode - unable to find " << absorbernodename << std::endl;
0558     }
0559   }
0560 }
0561 
0562 void PHG4InnerHcalSteppingAction::CreateNodeTree(PHCompositeNode* topNode)
0563 {
0564   PHNodeIterator nodeItr(topNode);
0565   PHCompositeNode* dst_node = dynamic_cast<PHCompositeNode*>(
0566       nodeItr.findFirst("PHCompositeNode", "DST"));
0567   if (!dst_node)
0568   {
0569     std::cout << "PHComposite node created: DST" << std::endl;
0570     dst_node = new PHCompositeNode("DST");
0571     topNode->addNode(dst_node);
0572   }
0573   PHNodeIterator dstiter(dst_node);
0574   PHCompositeNode* DetNode = dynamic_cast<PHCompositeNode*>(dstiter.findFirst("PHCompositeNode", m_Detector->SuperDetector()));
0575   if (!DetNode)
0576   {
0577     DetNode = new PHCompositeNode(m_Detector->SuperDetector());
0578     dst_node->addNode(DetNode);
0579   }
0580   m_CaloInfoContainer = new TowerInfoContainerv1(TowerInfoContainer::DETECTOR::HCAL);
0581   PHIODataNode<PHObject>* towerNode = new PHIODataNode<PHObject>(m_CaloInfoContainer, "TOWERINFO_SIM_" + m_Detector->SuperDetector(), "PHObject");
0582   DetNode->addNode(towerNode);
0583 }