Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:17:49

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