24 #include "G4LogicalVolumeStore.hh"
25 #include "G4LogicalVolume.hh"
29 #include "G4SystemOfUnits.hh"
30 #include "G4PhysicalConstants.hh"
31 #include "Randomize.hh"
33 #include "DD4hep/Filter.h"
59 hcalConstants_(nullptr),
60 hcalSimConstants_(nullptr),
61 m_HBDarkening(nullptr),
62 m_HEDarkening(nullptr),
101 bool agingFlagHF = m_HC.
getParameter<
bool>(
"HFDarkening");
109 applyFidCut = m_HF.getParameter<
bool>(
"ApplyFiducialCut");
113 edm::LogVerbatim(
"HcalSim") <<
"***************************************************"
115 <<
"* Constructing a HCalSD with name " <<
name <<
"\n"
117 <<
"***************************************************";
120 <<
"\n Use of shower parametrization set to " <<
useParam
122 <<
"\n Use PMT Hit is set to " <<
usePMTHit <<
" with beta Threshold " <<
betaThr
124 <<
"\n Use of Birks law is set to " <<
useBirk
125 <<
" with three constants kB = " <<
birk1 / bunit <<
", C1 = " <<
birk2
126 <<
", C2 = " <<
birk3;
130 <<
" ions below " <<
kmaxIon <<
" MeV\n"
134 <<
" Flag (HB) " <<
agingFlagHB <<
" Flag (HF) " << agingFlagHF <<
"\n"
144 edm::LogError(
"HcalSim") <<
"HCalSD : Cannot find HcalDDDSimConstant";
145 throw cms::Exception(
"Unknown",
"HCalSD") <<
"Cannot find HcalDDDSimConstant\n";
149 matNames.emplace_back(
"Scintillator");
157 edm::LogError(
"HcalSim") <<
"HCalSD : Cannot find HcalDDDSimulationConstant";
158 throw cms::Exception(
"Unknown",
"HCalSD") <<
"Cannot find HcalDDDSimulationConstant\n";
173 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
175 const G4LogicalVolume* lv;
192 std::stringstream ss0;
193 ss0 <<
"HCalSD: Names to be tested for Volume = HF has " <<
hfNames.size() <<
" elements";
195 for (
unsigned int i = 0;
i <
hfNames.size(); ++
i) {
196 G4String namv(static_cast<std::string>(dd4hep::dd::noNamespace(
hfNames[
i])));
198 for (
auto lvol : *lvs) {
199 if (dd4hep::dd::noNamespace(lvol->GetName()) == namv) {
204 hfLV.emplace_back(lv);
207 ss0 <<
"\n HF[" <<
i <<
"] = " << namv <<
" LV " << lv <<
" at level " <<
temp[
i];
225 const G4MaterialTable* matTab = G4Material::GetMaterialTable();
226 std::vector<G4Material*>::const_iterator matite;
228 const G4Material* mat =
nullptr;
229 for (matite = matTab->begin(); matite != matTab->end(); ++matite) {
230 if (static_cast<std::string>(dd4hep::dd::noNamespace((*matite)->GetName())) == namx) {
238 std::stringstream ss1;
239 for (
unsigned int i = 0;
i <
matNames.size(); ++
i) {
240 if (
i / 10 * 10 ==
i) {
245 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: Material names for HCAL: " << ss1.str();
255 std::stringstream ss2;
256 for (
unsigned int ig = 0; ig <
gpar.size(); ig++) {
257 ss2 <<
"\n gpar[" << ig <<
"] = " <<
gpar[ig] / cm <<
" cm";
260 <<
" gpar (cm)" << ss2.str();
278 for (
int i = 0;
i < 9; ++
i) {
289 if (
tfile.isAvailable()) {
290 static const char*
const labels[] = {
"HB",
301 for (
int i = 0;
i < 9; ++
i) {
303 sprintf(
name,
"HCalSDHit%d",
i);
305 sprintf(
title,
"Energy (MeV)");
307 hit_[
i]->GetYaxis()->SetTitle(
"Hits");
309 sprintf(
name,
"HCalSDTime%d",
i);
311 sprintf(
title,
"Time (ns)");
313 time_[
i]->GetYaxis()->SetTitle(
"Hits");
314 sprintf(
title,
"Longitudinal profile in %s",
labels[
i]);
315 sprintf(
name,
"HCalSDDist%d",
i);
317 sprintf(
title,
"Distance (mm)");
319 dist_[
i]->GetYaxis()->SetTitle(
"Hits");
322 hzvem = hcDir.
make<TH1F>(
"hzvem",
"Longitudinal Profile (EM Part)", 330, 0.0, 1650.0);
323 hzvem->GetXaxis()->SetTitle(
"Longitudinal Profile (EM Part)");
324 hzvhad = hcDir.
make<TH1F>(
"hzvhad",
"Longitudinal Profile (Had Part)", 330, 0.0, 1650.0);
325 hzvhad->GetXaxis()->SetTitle(
"Longitudinal Profile (Hadronic Part)");
339 const std::vector<std::string>& lvnames,
340 std::vector<const G4LogicalVolume*>& lvvec) {
341 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
342 const G4LogicalVolume* lv;
343 std::stringstream ss3;
344 ss3 <<
"HCalSD: " << lvnames.size() <<
" names to be tested for Volume <" <<
value <<
">:";
345 for (
unsigned int i = 0;
i < lvnames.size(); ++
i) {
346 G4String namv(static_cast<std::string>(dd4hep::dd::noNamespace(lvnames[
i])));
348 for (
auto lvol : *lvs) {
349 if (dd4hep::dd::noNamespace(lvol->GetName()) == namv) {
354 lvvec.emplace_back(lv);
355 if (
i / 10 * 10 ==
i) {
364 auto const track = aStep->GetTrack();
365 depth_ = (aStep->GetPreStepPoint()->GetTouchable()->GetReplicaNumber(0)) % 10;
371 G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
372 const double invcm = 1. / CLHEP::cm;
373 double r = hitPoint.perp() * invcm;
374 double z =
std::abs(hitPoint.z()) * invcm;
375 double dose_acquired = 0.;
387 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::getFromLibrary: HFLumiDarkening at "
388 <<
"r= " <<
r <<
", z= " <<
z <<
" Dose= " << dose_acquired <<
" weight= " <<
weight_;
395 G4String nameVolume = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetName();
397 <<
" for Track " <<
track->GetTrackID() <<
" ("
398 <<
track->GetDefinition()->GetParticleName() <<
")";
403 auto nameVolume = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetName();
404 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: Starts shower library from " << nameVolume <<
" for Track "
405 <<
track->GetTrackID() <<
" (" <<
track->GetDefinition()->GetParticleName() <<
")";
414 <<
track->GetDefinition()->GetParticleName() <<
") kill= " << kill
422 auto const lv = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
423 auto const theTrack = aStep->GetTrack();
428 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: Hit at Fibre in LV " << lv->GetName() <<
" for track "
429 << aStep->GetTrack()->GetTrackID() <<
" ("
430 << aStep->GetTrack()->GetDefinition()->GetParticleName() <<
")";
442 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: Hit from PMT parametrization in LV " << lv->GetName() <<
" for Track "
443 << aStep->GetTrack()->GetTrackID() <<
" ("
444 << aStep->GetTrack()->GetDefinition()->GetParticleName() <<
")";
453 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: Hit from straight FibreBundle in LV: " << lv->GetName() <<
" for track "
454 << aStep->GetTrack()->GetTrackID() <<
" ("
455 << aStep->GetTrack()->GetDefinition()->GetParticleName() <<
")";
464 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: Hit from conical FibreBundle PV: " << lv->GetName() <<
" for track "
465 << aStep->GetTrack()->GetTrackID() <<
" ("
466 << aStep->GetTrack()->GetDefinition()->GetParticleName() <<
")";
472 destep = aStep->GetTotalEnergyDeposit();
474 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
489 lay = (touch->GetReplicaNumber(0) / 10) % 100 + 1;
492 <<
" lay: " << lay - 2;
497 G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
522 int pdg = theTrack->GetDefinition()->GetPDGEncoding();
524 double ke = theTrack->GetKineticEnergy();
525 if (
pdg / 1000000000 == 1 && (
pdg / 10000) % 100 > 0 && (
pdg / 10) % 100 > 0 &&
ke <
kmaxIon)
535 const G4Material* mat = aStep->GetPreStepPoint()->GetMaterial();
540 double wt2 = theTrack->GetWeight();
541 double edep =
weight_ * wt1 * destep;
547 <<
" weight= " <<
weight_ <<
" wt1= " << wt1 <<
" wt2= " << wt2;
553 auto const prePoint = aStep->GetPreStepPoint();
554 auto const touch = prePoint->GetTouchable();
555 const G4ThreeVector& hitPoint = prePoint->GetPosition();
557 int depth = (touch->GetReplicaNumber(0)) % 10 + 1;
558 int lay = (touch->GetReplicaNumber(0) / 10) % 100 + 1;
559 int det = (touch->GetReplicaNumber(1)) / 1000;
566 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: updates numbering scheme for " << GetName();
578 switch (theId.subdetId()) {
615 <<
" does not match one from relabller for " <<
tmp.subdet <<
":" <<
tmp.etaR <<
":"
616 <<
tmp.phi <<
":" <<
tmp.phis <<
":" <<
tmp.depth <<
":" <<
tmp.lay << std::endl;
622 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
623 int levels = (touch->GetHistoryDepth()) + 1;
624 for (
unsigned int it = 0; it <
hfNames.size(); ++it) {
626 const G4LogicalVolume* lv = touch->GetVolume(
levels -
hfLevels[it])->GetLogicalVolume();
635 for (
const auto& nam :
hfNames)
636 if (
name == static_cast<G4String>(nam)) {
652 if (
name == static_cast<G4String>(nam)) {
659 for (
auto lvol :
pmtLV)
695 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::isItinFidVolume:#PMT= " << npmt <<
" for hit point " << hitPoint;
701 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::isItinFidVolume: point " << hitPoint <<
" return flag " <<
flag;
708 if (!isKilled ||
hits.empty()) {
717 auto const theTrack = aStep->GetTrack();
728 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::getFromLibrary " <<
hits.size() <<
" hits for " << GetName() <<
" of "
729 << primaryID <<
" with " << theTrack->GetDefinition()->GetParticleName() <<
" of "
730 << aStep->GetPreStepPoint()->GetKineticEnergy() /
GeV <<
" GeV";
732 for (
unsigned int i = 0;
i <
hits.size(); ++
i) {
733 G4ThreeVector hitPoint =
hits[
i].position;
756 auto const theTrack = aStep->GetTrack();
769 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::hitForFibre " <<
hits.size() <<
" hits for " << GetName() <<
" of "
770 << primaryID <<
" with " << theTrack->GetDefinition()->GetParticleName() <<
" of "
771 << aStep->GetPreStepPoint()->GetKineticEnergy() /
GeV <<
" GeV in detector type " << det;
774 for (
unsigned int i = 0;
i <
hits.size(); ++
i) {
775 G4ThreeVector hitPoint =
hits[
i].position;
793 if (!isKilled ||
hits.empty()) {
801 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::getFromParam " <<
hits.size() <<
" hits for " << GetName() <<
" of "
802 << primaryID <<
" with " << aStep->GetTrack()->GetDefinition()->GetParticleName()
803 <<
" of " << aStep->GetPreStepPoint()->GetKineticEnergy() /
GeV
804 <<
" GeV in detector type " << det;
806 for (
unsigned int i = 0;
i <
hits.size(); ++
i) {
807 G4ThreeVector hitPoint =
hits[
i].position;
822 auto const preStepPoint = aStep->GetPreStepPoint();
823 auto const theTrack = aStep->GetTrack();
828 double etrack = preStepPoint->GetKineticEnergy();
831 primaryID = theTrack->GetTrackID();
833 primaryID = theTrack->GetParentID();
835 primaryID = theTrack->GetTrackID();
841 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
842 double rr = (hitPoint.x() * hitPoint.x() + hitPoint.y() * hitPoint.y());
843 double phi = (
rr == 0. ? 0. : atan2(hitPoint.y(), hitPoint.x()));
850 if (hitPoint.z() < 0)
853 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::Hit for Detector " << det <<
" etaR " << etaR <<
" phi " <<
phi / deg
854 <<
" depth " <<
depth;
856 double time = (aStep->GetPostStepPoint()->GetGlobalTime());
870 double beta = preStepPoint->GetBeta();
871 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::getHitPMT 1 hit for " << GetName() <<
" of " << primaryID <<
" with "
872 << theTrack->GetDefinition()->GetParticleName() <<
" of "
873 << preStepPoint->GetKineticEnergy() /
GeV <<
" GeV with velocity " <<
beta <<
" UnitID "
881 auto const preStepPoint = aStep->GetPreStepPoint();
882 auto const theTrack = aStep->GetTrack();
887 double etrack = preStepPoint->GetKineticEnergy();
890 primaryID = theTrack->GetTrackID();
892 primaryID = theTrack->GetParentID();
894 primaryID = theTrack->GetTrackID();
900 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
901 double rr = hitPoint.x() * hitPoint.x() + hitPoint.y() * hitPoint.y();
902 double phi =
rr == 0. ? 0. : atan2(hitPoint.y(), hitPoint.x());
909 if (hitPoint.z() < 0.)
912 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::Hit for Detector " << det <<
" etaR " << etaR <<
" phi " <<
phi / deg
913 <<
" depth " <<
depth;
915 double time = (aStep->GetPostStepPoint()->GetGlobalTime());
932 double beta = preStepPoint->GetBeta();
933 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::getHitFibreBundle 1 hit for " << GetName() <<
" of " << primaryID
934 <<
" with " << theTrack->GetDefinition()->GetParticleName() <<
" of "
935 << preStepPoint->GetKineticEnergy() /
GeV <<
" GeV with velocity " <<
beta <<
" UnitID "
951 layerWeights.insert(std::pair<uint32_t, double>(
id, wt));
954 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::readWeightFromFile:Entry " <<
entry <<
" ID " << std::hex <<
id
955 <<
std::dec <<
" (" << det <<
"/" <<
zside <<
"/1/" << etaR <<
"/" <<
phi <<
"/"
956 << lay <<
") Weight " << wt;
974 std::map<uint32_t, double>::const_iterator ite =
layerWeights.find(
id);
979 <<
tmp.zside <<
"/1/" <<
tmp.etaR <<
"/" <<
tmp.phis <<
"/" <<
tmp.lay <<
") Weight "
987 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
988 static const G4String modName[8] = {
"HEModule",
"HVQF",
"HBModule",
"MBAT",
"MBBT",
"MBBTC",
"MBBT_R1P",
"MBBT_R1M"};
991 double depth = -2000;
993 for (
int n = 0;
n < touch->GetHistoryDepth(); ++
n) {
994 G4String
name(static_cast<std::string>(dd4hep::dd::noNamespace(touch->GetVolume(
n)->GetName())));
998 for (
unsigned int ii = 0;
ii < 8; ++
ii) {
999 if (
name == modName[
ii]) {
1001 int dn = touch->GetHistoryDepth() -
n;
1002 local = touch->GetHistory()->GetTransform(dn).TransformPoint(global);
1006 }
else if (
ii == 1) {
1009 }
else if (
ii == 2) {
1026 <<
" depth " <<
depth <<
" ID " <<
id <<
" EDEP " << edep <<
" Time " <<
time;
1034 int jd = 2 *
idx +
id - 7;
1035 if (jd >= 0 && jd < 4) {
1037 if (
hit_[jd] !=
nullptr)
1038 hit_[jd]->Fill(edep);
1039 if (
time_[jd] !=
nullptr)
1041 if (
dist_[jd] !=
nullptr)
1049 if (
hzvem !=
nullptr)
1058 if (
id.subdet == 4) {
1059 int ieta = (
id.zside == 0) ? -
id.etaR :
id.etaR;
1061 if (
id.
depth <= 2) {
1062 if (G4UniformRand() > 0.5)
1066 }
else if ((
id.subdet == 1 ||
id.subdet == 2) &&
testNumber) {
1067 id.depth = (
depth_ == 0) ? 1 : 2;