File indexing completed on 2025-08-06 08:19:29
0001 #include "PHG4OHCalSteppingAction.h"
0002
0003 #include "PHG4OHCalDetector.h"
0004
0005
0006
0007 #include <g4detectors/PHG4HcalDefs.h>
0008 #include <g4detectors/PHG4StepStatusDecode.h>
0009
0010 #include <phparameter/PHParameters.h>
0011
0012 #include <calobase/TowerInfo.h>
0013 #include <calobase/TowerInfoContainer.h>
0014 #include <calobase/TowerInfoContainerv1.h>
0015 #include <calobase/TowerInfoDefs.h>
0016
0017 #include <g4main/PHG4Hit.h>
0018 #include <g4main/PHG4HitContainer.h>
0019 #include <g4main/PHG4Hitv1.h>
0020 #include <g4main/PHG4Shower.h>
0021 #include <g4main/PHG4SteppingAction.h> // for PHG4SteppingAction
0022 #include <g4main/PHG4TrackUserInfoV1.h>
0023
0024 #include <ffamodules/CDBInterface.h>
0025
0026 #include <fun4all/Fun4AllReturnCodes.h>
0027 #include <fun4all/Fun4AllServer.h>
0028
0029 #include <phool/PHCompositeNode.h>
0030 #include <phool/PHIODataNode.h> // for PHIODataNode
0031 #include <phool/PHNode.h> // for PHNode
0032 #include <phool/PHNodeIterator.h> // for PHNodeIterator
0033 #include <phool/PHObject.h> // for PHObject
0034 #include <phool/getClass.h>
0035 #include <phool/phool.h>
0036
0037
0038 #include <TAxis.h> // for TAxis
0039 #include <TFile.h>
0040 #include <TH2.h>
0041 #include <TNamed.h> // for TNamed
0042 #include <TSystem.h>
0043
0044
0045
0046 #include <Geant4/G4AffineTransform.hh> // for G4AffineTransform
0047 #include <Geant4/G4Field.hh>
0048 #include <Geant4/G4FieldManager.hh>
0049 #include <Geant4/G4LogicalVolume.hh> // for G4LogicalVolume
0050 #include <Geant4/G4NavigationHistory.hh> // for G4NavigationHistory
0051 #include <Geant4/G4ParticleDefinition.hh> // for G4ParticleDefinition
0052 #include <Geant4/G4PropagatorInField.hh>
0053 #include <Geant4/G4ReferenceCountedHandle.hh> // for G4ReferenceCountedHandle
0054 #include <Geant4/G4Step.hh>
0055 #include <Geant4/G4StepPoint.hh> // for G4StepPoint
0056 #include <Geant4/G4StepStatus.hh> // for fGeomBoundary, fAtRest...
0057 #include <Geant4/G4String.hh> // for G4String
0058 #include <Geant4/G4SystemOfUnits.hh>
0059 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
0060 #include <Geant4/G4TouchableHandle.hh> // for G4TouchableHandle
0061 #include <Geant4/G4Track.hh> // for G4Track
0062 #include <Geant4/G4TrackStatus.hh> // for fStopAndKill
0063 #include <Geant4/G4TransportationManager.hh>
0064 #include <Geant4/G4Types.hh> // for G4double
0065 #include <Geant4/G4VPhysicalVolume.hh> // for G4VPhysicalVolume
0066 #include <Geant4/G4VTouchable.hh> // for G4VTouchable
0067 #include <Geant4/G4VUserTrackInformation.hh> // for G4VUserTrackInformation
0068
0069
0070 #include <cassert>
0071 #include <cmath> // for isfinite, sqrt
0072 #include <exception>
0073 #include <filesystem>
0074 #include <iostream>
0075 #include <string> // for operator<<, string
0076 #include <tuple> // for get, tuple
0077
0078
0079 PHG4OHCalSteppingAction::PHG4OHCalSteppingAction(PHG4OHCalDetector* detector, PHParameters* parameters)
0080 : PHG4SteppingAction(detector->GetName())
0081 , m_Detector(detector)
0082 , m_Params(parameters)
0083 , m_EnableFieldCheckerFlag(m_Params->get_int_param("field_check"))
0084 , m_IsActiveFlag(m_Params->get_int_param("active"))
0085 , m_IsBlackHoleFlag(m_Params->get_int_param("blackhole"))
0086 , m_NScintiPlates(m_Params->get_int_param(PHG4HcalDefs::scipertwr) * m_Params->get_int_param("n_towers"))
0087 , m_LightScintModelFlag(m_Params->get_int_param("light_scint_model"))
0088 , m_doG4Hit(m_Params->get_int_param("saveg4hit"))
0089 , m_tmin(m_Params->get_double_param("tmin"))
0090 , m_tmax(m_Params->get_double_param("tmax"))
0091 , m_dt(m_Params->get_double_param("dt"))
0092 {
0093 SetLightCorrection(m_Params->get_double_param("light_balance_inner_radius") * cm,
0094 m_Params->get_double_param("light_balance_inner_corr"),
0095 m_Params->get_double_param("light_balance_outer_radius") * cm,
0096 m_Params->get_double_param("light_balance_outer_corr"));
0097
0098 std::string mapfile = m_Params->get_string_param("MapFileName");
0099 if (std::filesystem::path(mapfile).extension() != ".root")
0100 {
0101 mapfile = CDBInterface::instance()->getUrl(mapfile);
0102 m_Params->set_string_param("MapFileName", mapfile);
0103 }
0104 }
0105
0106 PHG4OHCalSteppingAction::~PHG4OHCalSteppingAction()
0107 {
0108
0109
0110
0111
0112 delete m_Hit;
0113
0114
0115 for (auto it : m_MapCorrHist)
0116 {
0117 delete it;
0118 }
0119 for (int j = 0; j < 4; j++)
0120 {
0121 delete m_MapCorrHistChim[j];
0122 }
0123 }
0124
0125 int PHG4OHCalSteppingAction::InitWithNode(PHCompositeNode* topNode)
0126 {
0127 m_EnableFieldCheckerFlag = m_Params->get_int_param("field_check");
0128
0129 if (m_LightScintModelFlag)
0130 {
0131 std::string mappingfilename(m_Params->get_string_param("MapFileName"));
0132 if (mappingfilename.empty())
0133 {
0134 return 0;
0135 }
0136 if (!std::filesystem::exists(m_Params->get_string_param("MapFileName")))
0137 {
0138 std::cout << PHWHERE << " Could not locate " << m_Params->get_string_param("MapFileName") << std::endl;
0139 std::cout << "use empty filename to ignore mapfile" << std::endl;
0140 gSystem->Exit(1);
0141 }
0142
0143 TFile* file = TFile::Open(mappingfilename.c_str());
0144 std::string Tilehist = m_Params->get_string_param("MapHistoName");
0145
0146 for (int i = 0; i < 24; i++)
0147 {
0148 std::string str2 = std::to_string(i);
0149 Tilehist += str2;
0150 file->GetObject(Tilehist.c_str(), m_MapCorrHist[i]);
0151 if (i < 4)
0152 {
0153 Tilehist += "_chimney";
0154 }
0155 file->GetObject(Tilehist.c_str(), m_MapCorrHistChim[i]);
0156 Tilehist = m_Params->get_string_param("MapHistoName");
0157
0158 if ((!m_MapCorrHist[i]) || (!m_MapCorrHistChim[i]))
0159 {
0160 std::cout << "ERROR: could not find Histogram " << Tilehist << i << " in " << m_Params->get_string_param("MapFileName") << std::endl;
0161 gSystem->Exit(1);
0162 }
0163
0164 m_MapCorrHist[i]->SetDirectory(nullptr);
0165 m_MapCorrHistChim[i]->SetDirectory(nullptr);
0166 }
0167
0168 file->Close();
0169 delete file;
0170 }
0171 if (!m_doG4Hit)
0172 {
0173 try
0174 {
0175 CreateNodeTree(topNode);
0176 }
0177 catch (std::exception& e)
0178 {
0179 std::cout << e.what() << std::endl;
0180 return Fun4AllReturnCodes::ABORTRUN;
0181 }
0182 if (Verbosity() > 1)
0183 {
0184 topNode->print();
0185 }
0186 }
0187 return 0;
0188 }
0189
0190
0191 bool PHG4OHCalSteppingAction::NoHitSteppingAction(const G4Step* aStep)
0192 {
0193 G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();
0194 G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle();
0195
0196 G4VPhysicalVolume* volume = touch->GetVolume();
0197
0198
0199
0200
0201
0202
0203
0204 int whichactive = m_Detector->IsInOHCal(volume);
0205
0206 if (!whichactive)
0207 {
0208 return false;
0209 }
0210 if (m_EnableFieldCheckerFlag)
0211 {
0212 FieldChecker(aStep);
0213 }
0214 int layer_id = -1;
0215 int tower_id = -1;
0216 int sector_id = -1;
0217 if (whichactive > 0)
0218 {
0219 std::tuple<int, int, int> layer_tower = m_Detector->GetRowColumnId(volume);
0220 sector_id = std::get<0>(layer_tower);
0221 layer_id = std::get<1>(layer_tower);
0222 tower_id = std::get<2>(layer_tower);
0223
0224
0225 }
0226 else
0227 {
0228
0229 return false;
0230 }
0231
0232 if (!m_IsActiveFlag)
0233 {
0234 return false;
0235 }
0236
0237 G4StepPoint* prePoint = aStep->GetPreStepPoint();
0238 G4StepPoint* postPoint = aStep->GetPostStepPoint();
0239
0240 double pretime = prePoint->GetGlobalTime() / nanosecond;
0241 double posttime = postPoint->GetGlobalTime() / nanosecond;
0242 if (posttime < m_tmin || pretime > m_tmax)
0243 {
0244 return false;
0245 }
0246 if ((posttime - pretime) > m_dt)
0247 {
0248 return false;
0249 }
0250 G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV;
0251 const G4Track* aTrack = aStep->GetTrack();
0252
0253 double light_yield = eion;
0254
0255
0256 if (m_LightScintModelFlag)
0257 {
0258 light_yield = GetVisibleEnergyDeposition(aStep);
0259 if ((m_MapCorrHistChim[tower_id]) || (m_MapCorrHist[tower_id]))
0260 {
0261 const G4TouchableHandle& theTouchable = prePoint->GetTouchableHandle();
0262 const G4ThreeVector& worldPosition = postPoint->GetPosition();
0263 G4ThreeVector localPosition = theTouchable->GetHistory()->GetTopTransform().TransformPoint(worldPosition);
0264 float lx = (localPosition.x() / cm);
0265 float ly = (localPosition.y() / cm);
0266
0267
0268 int lcx = (int) (2.0 * lx) + 1;
0269 int lcy = (int) (2.0 * (ly + 0.5)) + 1;
0270
0271 if ((sector_id == 29) || (sector_id == 30) || (sector_id == 31))
0272 {
0273 if ((lcy >= 1) && (lcy <= m_MapCorrHistChim[tower_id]->GetNbinsY()) &&
0274 (lcx >= 1) && (lcx <= m_MapCorrHistChim[tower_id]->GetNbinsX()))
0275 {
0276 light_yield *= (double) (m_MapCorrHistChim[tower_id]->GetBinContent(lcx, lcy));
0277 }
0278 else
0279 {
0280 light_yield = 0.0;
0281 }
0282 }
0283 else
0284 {
0285 if ((lcy >= 1) && (lcy <= m_MapCorrHist[tower_id]->GetNbinsY()) &&
0286 (lcx >= 1) && (lcx <= m_MapCorrHist[tower_id]->GetNbinsX()))
0287 {
0288 light_yield *= (double) (m_MapCorrHist[tower_id]->GetBinContent(lcx, lcy));
0289 }
0290 else
0291 {
0292 light_yield = 0.0;
0293 }
0294 }
0295 }
0296 else
0297 {
0298
0299 light_yield = light_yield * GetLightCorrection(postPoint->GetPosition().x(), postPoint->GetPosition().y());
0300 }
0301 }
0302
0303 unsigned int ieta = tower_id;
0304 unsigned int iphi = (unsigned int) layer_id / 5;
0305 unsigned int tower_key = TowerInfoDefs::encode_hcal(ieta, iphi);
0306 m_CaloInfoContainer->get_tower_at_key(tower_key)->set_energy(m_CaloInfoContainer->get_tower_at_key(tower_key)->get_energy() + light_yield);
0307
0308 if (light_yield > 0)
0309 {
0310 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0311 {
0312 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0313 {
0314 pp->SetKeep(1);
0315 }
0316 }
0317 }
0318
0319 return true;
0320 }
0321
0322
0323 bool PHG4OHCalSteppingAction::UserSteppingAction(const G4Step* aStep, bool )
0324 {
0325 if ((!m_doG4Hit) && (!m_IsBlackHoleFlag))
0326 {
0327 return NoHitSteppingAction(aStep);
0328 }
0329
0330 G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();
0331 G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle();
0332
0333 G4VPhysicalVolume* volume = touch->GetVolume();
0334
0335
0336
0337
0338
0339
0340
0341 int whichactive = m_Detector->IsInOHCal(volume);
0342
0343 if (!whichactive)
0344 {
0345 return false;
0346 }
0347
0348 if (m_EnableFieldCheckerFlag)
0349 {
0350 FieldChecker(aStep);
0351 }
0352
0353 int layer_id = -1;
0354 int tower_id = -1;
0355 int sector_id = -1;
0356 if (whichactive > 0)
0357 {
0358 std::tuple<int, int, int> layer_tower = m_Detector->GetRowColumnId(volume);
0359 sector_id = std::get<0>(layer_tower);
0360 layer_id = std::get<1>(layer_tower);
0361 tower_id = std::get<2>(layer_tower);
0362 }
0363 else
0364 {
0365 layer_id = touch->GetCopyNumber();
0366 }
0367
0368
0369 G4double edep = aStep->GetTotalEnergyDeposit() / GeV;
0370 G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV;
0371 G4double light_yield = 0;
0372
0373 const G4Track* aTrack = aStep->GetTrack();
0374
0375
0376 if (m_IsBlackHoleFlag)
0377 {
0378 edep = aTrack->GetKineticEnergy() / GeV;
0379 G4Track* killtrack = const_cast<G4Track*>(aTrack);
0380 killtrack->SetTrackStatus(fStopAndKill);
0381 }
0382
0383
0384 if (m_IsActiveFlag)
0385 {
0386 bool geantino = false;
0387
0388
0389
0390
0391 if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0 &&
0392 aTrack->GetParticleDefinition()->GetParticleName().find("geantino") != std::string::npos)
0393 {
0394 geantino = true;
0395 }
0396 G4StepPoint* prePoint = aStep->GetPreStepPoint();
0397 G4StepPoint* postPoint = aStep->GetPostStepPoint();
0398
0399
0400
0401
0402 switch (prePoint->GetStepStatus())
0403 {
0404 case fPostStepDoItProc:
0405 if (m_SavePostStepStatus != fGeomBoundary)
0406 {
0407 if (m_SavePostStepStatus != fAtRestDoItProc)
0408 {
0409 break;
0410 }
0411 else
0412 {
0413 if (aTrack->GetTrackID() == m_SaveTrackId)
0414 {
0415 std::cout << GetName() << ": Bad step status combination for the same track " << std::endl;
0416 std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0417 << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0418 << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0419 << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0420 std::cout << "last track: " << m_SaveTrackId
0421 << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0422 std::cout << "phys pre vol: " << volume->GetName()
0423 << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0424 std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0425 << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0426 gSystem->Exit(1);
0427 }
0428 }
0429 }
0430 else
0431 {
0432 std::cout << GetName() << ": New Hit for " << std::endl;
0433 std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0434 << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0435 << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0436 << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0437 std::cout << "last track: " << m_SaveTrackId
0438 << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0439 std::cout << "phys pre vol: " << volume->GetName()
0440 << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0441 std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0442 << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0443 }
0444 [[fallthrough]];
0445 case fGeomBoundary:
0446 case fUndefined:
0447 if (!m_Hit)
0448 {
0449 m_Hit = new PHG4Hitv1();
0450 }
0451
0452 m_Hit->set_x(0, prePoint->GetPosition().x() / cm);
0453 m_Hit->set_y(0, prePoint->GetPosition().y() / cm);
0454 m_Hit->set_z(0, prePoint->GetPosition().z() / cm);
0455
0456
0457 m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
0458
0459 m_Hit->set_trkid(aTrack->GetTrackID());
0460 m_SaveTrackId = aTrack->GetTrackID();
0461
0462 m_Hit->set_edep(0);
0463 if (whichactive > 0)
0464 {
0465 m_Hit->set_sector(sector_id);
0466 m_Hit->set_scint_id(tower_id);
0467 m_Hit->set_eion(0);
0468 m_Hit->set_raw_light_yield(0);
0469 m_Hit->set_light_yield(0);
0470
0471 m_SaveHitContainer = m_HitContainer;
0472 }
0473 else
0474 {
0475 m_SaveHitContainer = m_AbsorberHitContainer;
0476 }
0477 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0478 {
0479 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0480 {
0481 m_Hit->set_trkid(pp->GetUserTrackId());
0482 m_Hit->set_shower_id(pp->GetShower()->get_id());
0483 m_SaveShower = pp->GetShower();
0484 }
0485 }
0486 break;
0487 default:
0488 break;
0489 }
0490
0491
0492 if (!m_Hit || !std::isfinite(m_Hit->get_x(0)))
0493 {
0494 std::cout << GetName() << ": hit was not created" << std::endl;
0495 std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0496 << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0497 << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0498 << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0499 std::cout << "last track: " << m_SaveTrackId
0500 << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0501 std::cout << "phys pre vol: " << volume->GetName()
0502 << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0503 std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0504 << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0505 gSystem->Exit(1);
0506 }
0507 m_SavePostStepStatus = postPoint->GetStepStatus();
0508
0509 if (aTrack->GetTrackID() != m_SaveTrackId)
0510 {
0511 std::cout << GetName() << ": hits do not belong to the same track" << std::endl;
0512 std::cout << "saved track: " << m_SaveTrackId
0513 << ", current trackid: " << aTrack->GetTrackID()
0514 << std::endl;
0515 gSystem->Exit(1);
0516 }
0517 m_SavePreStepStatus = prePoint->GetStepStatus();
0518 m_SavePostStepStatus = postPoint->GetStepStatus();
0519 m_SaveVolPre = volume;
0520 m_SaveVolPost = touchpost->GetVolume();
0521
0522
0523
0524 m_Hit->set_x(1, postPoint->GetPosition().x() / cm);
0525 m_Hit->set_y(1, postPoint->GetPosition().y() / cm);
0526 m_Hit->set_z(1, postPoint->GetPosition().z() / cm);
0527
0528 m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);
0529
0530
0531 m_Hit->set_edep(m_Hit->get_edep() + edep);
0532
0533 if (whichactive > 0)
0534 {
0535 m_Hit->set_eion(m_Hit->get_eion() + eion);
0536 light_yield = eion;
0537 if (m_LightScintModelFlag)
0538 {
0539 light_yield = GetVisibleEnergyDeposition(aStep);
0540 m_Hit->set_raw_light_yield(m_Hit->get_raw_light_yield() + light_yield);
0541 if ((m_MapCorrHistChim[tower_id]) || (m_MapCorrHist[tower_id]))
0542 {
0543 const G4TouchableHandle& theTouchable = prePoint->GetTouchableHandle();
0544 const G4ThreeVector& worldPosition = postPoint->GetPosition();
0545 G4ThreeVector localPosition = theTouchable->GetHistory()->GetTopTransform().TransformPoint(worldPosition);
0546 float lx = (localPosition.x() / cm);
0547 float ly = (localPosition.y() / cm);
0548
0549
0550 int lcx = (int) (2.0 * lx) + 1;
0551 int lcy = (int) (2.0 * (ly + 0.5)) + 1;
0552
0553 if ((sector_id == 29) || (sector_id == 30) || (sector_id == 31))
0554 {
0555 if ((lcy >= 1) && (lcy <= m_MapCorrHistChim[tower_id]->GetNbinsY()) &&
0556 (lcx >= 1) && (lcx <= m_MapCorrHistChim[tower_id]->GetNbinsX()))
0557 {
0558 light_yield *= (double) (m_MapCorrHistChim[tower_id]->GetBinContent(lcx, lcy));
0559 }
0560 else
0561 {
0562 light_yield = 0.0;
0563 }
0564 }
0565 else
0566 {
0567 if ((lcy >= 1) && (lcy <= m_MapCorrHist[tower_id]->GetNbinsY()) &&
0568 (lcx >= 1) && (lcx <= m_MapCorrHist[tower_id]->GetNbinsX()))
0569 {
0570 light_yield *= (double) (m_MapCorrHist[tower_id]->GetBinContent(lcx, lcy));
0571 }
0572 else
0573 {
0574 light_yield = 0.0;
0575 }
0576 }
0577 }
0578 else
0579 {
0580
0581 light_yield = light_yield * GetLightCorrection(postPoint->GetPosition().x(), postPoint->GetPosition().y());
0582 }
0583 }
0584 m_Hit->set_light_yield(m_Hit->get_light_yield() + light_yield);
0585 }
0586
0587 if (geantino)
0588 {
0589 m_Hit->set_edep(-1);
0590 m_Hit->set_eion(-1);
0591 }
0592 if (edep > 0)
0593 {
0594 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0595 {
0596 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0597 {
0598 pp->SetKeep(1);
0599 }
0600 }
0601 }
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611 if (postPoint->GetStepStatus() == fGeomBoundary ||
0612 postPoint->GetStepStatus() == fWorldBoundary ||
0613 postPoint->GetStepStatus() == fAtRestDoItProc ||
0614 aTrack->GetTrackStatus() == fStopAndKill)
0615 {
0616
0617 if (m_Hit->get_edep() != 0)
0618 {
0619 m_SaveHitContainer->AddHit(layer_id, m_Hit);
0620 if (m_SaveShower)
0621 {
0622 m_SaveShower->add_g4hit_id(m_SaveHitContainer->GetID(), m_Hit->get_hit_id());
0623 }
0624
0625
0626 m_Hit = nullptr;
0627 }
0628 else
0629 {
0630
0631
0632
0633 m_Hit->Reset();
0634 }
0635 }
0636
0637 return true;
0638 }
0639 else
0640 {
0641 return false;
0642 }
0643 }
0644
0645
0646 void PHG4OHCalSteppingAction::SetInterfacePointers(PHCompositeNode* topNode)
0647 {
0648 m_HitContainer = findNode::getClass<PHG4HitContainer>(topNode, m_HitNodeName);
0649 m_AbsorberHitContainer = findNode::getClass<PHG4HitContainer>(topNode, m_AbsorberNodeName);
0650
0651
0652 if (!m_HitContainer)
0653 {
0654 std::cout << "PHG4OHCalSteppingAction::SetTopNode - unable to find " << m_HitNodeName << std::endl;
0655 }
0656 if (!m_AbsorberHitContainer)
0657 {
0658 if (Verbosity() > 1)
0659 {
0660 std::cout << "PHG4OHcalSteppingAction::SetTopNode - unable to find " << m_AbsorberNodeName << std::endl;
0661 }
0662 }
0663 }
0664
0665 void PHG4OHCalSteppingAction::FieldChecker(const G4Step* aStep)
0666 {
0667 Fun4AllServer* se = Fun4AllServer::instance();
0668 assert(se);
0669
0670 static const std::string h_field_name = "hOHCalField";
0671
0672 if (!se->isHistoRegistered(h_field_name))
0673 {
0674 TH2F* h = new TH2F(h_field_name.c_str(), "Magnetic field (Tesla) in HCal;X (cm);Y (cm)", 2400,
0675 -300, 300, 2400, -300, 300);
0676
0677 se->registerHisto(h, 1);
0678
0679 std::cout << "PHG4OHCalSteppingAction::FieldChecker - make a histograme to check outer Hcal field map."
0680 << " Saved to Fun4AllServer Histo with name " << h_field_name << std::endl;
0681 }
0682
0683 TH2F* h = dynamic_cast<TH2F*>(se->getHisto(h_field_name));
0684 assert(h);
0685
0686 assert(aStep);
0687 G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();
0688 assert(touch);
0689
0690 G4VPhysicalVolume* volume = touch->GetVolume();
0691 assert(volume);
0692
0693 G4ThreeVector globPosition = aStep->GetPreStepPoint()->GetPosition();
0694
0695 G4double globPosVec[4] = {0};
0696 G4double FieldValueVec[6] = {0};
0697
0698 globPosVec[0] = globPosition.x();
0699 globPosVec[1] = globPosition.y();
0700 globPosVec[2] = globPosition.z();
0701 globPosVec[3] = aStep->GetPreStepPoint()->GetGlobalTime();
0702
0703 const int binx = h->GetXaxis()->FindBin(globPosVec[0] / cm);
0704 const int biny = h->GetYaxis()->FindBin(globPosVec[1] / cm);
0705
0706 if (h->GetBinContent(binx, binx) == 0)
0707 {
0708
0709 G4TransportationManager* transportMgr = G4TransportationManager::GetTransportationManager();
0710 assert(transportMgr);
0711
0712 G4PropagatorInField* fFieldPropagator = transportMgr->GetPropagatorInField();
0713 assert(fFieldPropagator);
0714
0715 G4FieldManager* fieldMgr = fFieldPropagator->FindAndSetFieldManager(volume);
0716 assert(fieldMgr);
0717
0718 const G4Field* pField = fieldMgr->GetDetectorField();
0719 assert(pField);
0720
0721 pField->GetFieldValue(globPosVec, FieldValueVec);
0722
0723 G4ThreeVector FieldValue = G4ThreeVector(FieldValueVec[0],
0724 FieldValueVec[1], FieldValueVec[2]);
0725
0726 const double Bz = FieldValue.z() / tesla;
0727
0728 h->SetBinContent(binx, biny, Bz);
0729
0730 std::cout << "PHG4OHCalSteppingAction::FieldChecker - "
0731 << "volume " << volume->GetName() << " / " << volume->GetLogicalVolume()->GetName()
0732 << "\t bin " << binx
0733 << ", " << biny << " : Bz= " << Bz << " B = " << FieldValue.mag() / tesla
0734 << " Tesla @ x,y = " << globPosVec[0] / cm
0735 << "," << globPosVec[1] / cm << " cm" << std::endl;
0736 }
0737 }
0738
0739 void PHG4OHCalSteppingAction::SetHitNodeName(const std::string& type, const std::string& name)
0740 {
0741 if (type == "G4HIT")
0742 {
0743 m_HitNodeName = name;
0744 return;
0745 }
0746 else if (type == "G4HIT_ABSORBER")
0747 {
0748 m_AbsorberNodeName = name;
0749 return;
0750 }
0751 std::cout << "Invalid output hit node type " << type << std::endl;
0752 gSystem->Exit(1);
0753 return;
0754 }
0755
0756 void PHG4OHCalSteppingAction::CreateNodeTree(PHCompositeNode* topNode)
0757 {
0758 PHNodeIterator nodeItr(topNode);
0759 PHCompositeNode* dst_node = dynamic_cast<PHCompositeNode*>(
0760 nodeItr.findFirst("PHCompositeNode", "DST"));
0761 if (!dst_node)
0762 {
0763 std::cout << "PHComposite node created: DST" << std::endl;
0764 dst_node = new PHCompositeNode("DST");
0765 topNode->addNode(dst_node);
0766 }
0767 PHNodeIterator dstiter(dst_node);
0768 PHCompositeNode* DetNode = dynamic_cast<PHCompositeNode*>(dstiter.findFirst("PHCompositeNode", m_Detector->SuperDetector()));
0769 if (!DetNode)
0770 {
0771 DetNode = new PHCompositeNode(m_Detector->SuperDetector());
0772 dst_node->addNode(DetNode);
0773 }
0774 m_CaloInfoContainer = new TowerInfoContainerv1(TowerInfoContainer::DETECTOR::HCAL);
0775 PHIODataNode<PHObject>* towerNode = new PHIODataNode<PHObject>(m_CaloInfoContainer, "TOWERINFO_SIM_" + m_Detector->SuperDetector(), "PHObject");
0776 DetNode->addNode(towerNode);
0777 }