23 #include "G4LogicalVolumeStore.hh"
24 #include "G4LogicalVolume.hh"
28 #include "G4SystemOfUnits.hh"
29 #include "G4PhysicalConstants.hh"
30 #include "Randomize.hh"
56 hcalConstants_(nullptr),
57 hcalSimConstants_(nullptr),
58 m_HBDarkening(nullptr),
59 m_HEDarkening(nullptr),
97 bool agingFlagHF = m_HC.
getParameter<
bool>(
"HFDarkening");
105 applyFidCut = m_HF.getParameter<
bool>(
"ApplyFiducialCut");
108 edm::LogVerbatim(
"HcalSim") <<
"***************************************************"
110 <<
"* Constructing a HCalSD with name " <<
name <<
"\n"
112 <<
"***************************************************";
115 <<
"\nUse of shower parametrization set to " <<
useParam
116 <<
"\nUse of shower library is set to " <<
useShowerLibrary <<
"\nUse PMT Hit is set to "
117 <<
usePMTHit <<
" with beta Threshold " <<
betaThr <<
"\nUSe of FibreBundle Hit set to "
119 <<
" with three constants kB = " <<
birk1 <<
", C1 = " <<
birk2 <<
", C2 = " <<
birk3;
123 <<
" ions below " <<
kmaxIon <<
" MeV\n"
127 <<
" Flag (HB) " <<
agingFlagHB <<
" Flag (HF) " << agingFlagHF <<
"\n"
137 edm::LogError(
"HcalSim") <<
"HCalSD : Cannot find HcalDDDSimConstant";
138 throw cms::Exception(
"Unknown",
"HCalSD") <<
"Cannot find HcalDDDSimConstant\n";
142 matNames.emplace_back(
"Scintillator");
150 edm::LogError(
"HcalSim") <<
"HCalSD : Cannot find HcalDDDSimulationConstant";
151 throw cms::Exception(
"Unknown",
"HCalSD") <<
"Cannot find HcalDDDSimulationConstant\n";
166 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
168 const G4LogicalVolume* lv;
185 std::stringstream ss0;
186 ss0 <<
"HCalSD: Names to be tested for Volume = HF has " <<
hfNames.size() <<
" elements";
188 for (
unsigned int i = 0;
i <
hfNames.size(); ++
i) {
189 G4String namv = static_cast<G4String>(
hfNames[
i]);
191 for (
auto lvol : *lvs) {
192 if (lvol->GetName() == namv) {
197 hfLV.emplace_back(lv);
200 ss0 <<
"\n HF[" <<
i <<
"] = " << namv <<
" LV " << lv <<
" at level " <<
temp[
i];
218 const G4MaterialTable* matTab = G4Material::GetMaterialTable();
219 std::vector<G4Material*>::const_iterator matite;
221 const G4Material* mat =
nullptr;
222 for (matite = matTab->begin(); matite != matTab->end(); ++matite) {
223 if ((*matite)->GetName() == static_cast<G4String>(namx)) {
231 std::stringstream ss1;
232 for (
unsigned int i = 0;
i <
matNames.size(); ++
i) {
233 if (
i / 10 * 10 ==
i) {
238 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: Material names for HCAL: " << ss1.str();
248 std::stringstream ss2;
249 for (
unsigned int ig = 0; ig <
gpar.size(); ig++) {
250 ss2 <<
"\n gpar[" << ig <<
"] = " <<
gpar[ig] / cm <<
" cm";
253 <<
" gpar (cm)" << ss2.str();
271 for (
int i = 0;
i < 9; ++
i) {
282 if (
tfile.isAvailable()) {
283 static const char*
const labels[] = {
"HB",
294 for (
int i = 0;
i < 9; ++
i) {
296 sprintf(
name,
"HCalSDHit%d",
i);
298 sprintf(
title,
"Energy (MeV)");
300 hit_[
i]->GetYaxis()->SetTitle(
"Hits");
302 sprintf(
name,
"HCalSDTime%d",
i);
304 sprintf(
title,
"Time (ns)");
306 time_[
i]->GetYaxis()->SetTitle(
"Hits");
307 sprintf(
title,
"Longitudinal profile in %s",
labels[
i]);
308 sprintf(
name,
"HCalSDDist%d",
i);
310 sprintf(
title,
"Distance (mm)");
312 dist_[
i]->GetYaxis()->SetTitle(
"Hits");
315 hzvem = hcDir.
make<TH1F>(
"hzvem",
"Longitudinal Profile (EM Part)", 330, 0.0, 1650.0);
316 hzvem->GetXaxis()->SetTitle(
"Longitudinal Profile (EM Part)");
317 hzvhad = hcDir.
make<TH1F>(
"hzvhad",
"Longitudinal Profile (Had Part)", 330, 0.0, 1650.0);
318 hzvhad->GetXaxis()->SetTitle(
"Longitudinal Profile (Hadronic Part)");
325 const std::vector<std::string>& lvnames,
326 std::vector<const G4LogicalVolume*>& lvvec) {
327 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
328 const G4LogicalVolume* lv;
329 std::stringstream ss3;
330 ss3 <<
"HCalSD: " << lvnames.size() <<
" names to be tested for Volume <" <<
value <<
">:";
331 for (
unsigned int i = 0;
i < lvnames.size(); ++
i) {
332 G4String namv = static_cast<G4String>(lvnames[
i]);
334 for (
auto lvol : *lvs) {
335 if (lvol->GetName() == namv) {
340 lvvec.emplace_back(lv);
341 if (
i / 10 * 10 ==
i) {
350 auto const track = aStep->GetTrack();
351 depth_ = (aStep->GetPreStepPoint()->GetTouchable()->GetReplicaNumber(0)) % 10;
357 G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
358 const double invcm = 1. / CLHEP::cm;
359 double r = hitPoint.perp() * invcm;
360 double z =
std::abs(hitPoint.z()) * invcm;
361 double dose_acquired = 0.;
373 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::getFromLibrary: HFLumiDarkening at "
374 <<
"r= " <<
r <<
", z= " <<
z <<
" Dose= " << dose_acquired <<
" weight= " <<
weight_;
381 G4String nameVolume = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetName();
383 <<
" for Track " <<
track->GetTrackID() <<
" ("
384 <<
track->GetDefinition()->GetParticleName() <<
")";
389 auto nameVolume = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetName();
390 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: Starts shower library from " << nameVolume <<
" for Track "
391 <<
track->GetTrackID() <<
" (" <<
track->GetDefinition()->GetParticleName() <<
")";
400 <<
track->GetDefinition()->GetParticleName() <<
") kill= " << kill
408 auto const lv = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
409 auto const theTrack = aStep->GetTrack();
414 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: Hit at Fibre in LV " << lv->GetName() <<
" for track "
415 << aStep->GetTrack()->GetTrackID() <<
" ("
416 << aStep->GetTrack()->GetDefinition()->GetParticleName() <<
")";
428 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: Hit from PMT parametrization in LV " << lv->GetName() <<
" for Track "
429 << aStep->GetTrack()->GetTrackID() <<
" ("
430 << aStep->GetTrack()->GetDefinition()->GetParticleName() <<
")";
439 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: Hit from straight FibreBundle in LV: " << lv->GetName() <<
" for track "
440 << aStep->GetTrack()->GetTrackID() <<
" ("
441 << aStep->GetTrack()->GetDefinition()->GetParticleName() <<
")";
450 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: Hit from conical FibreBundle PV: " << lv->GetName() <<
" for track "
451 << aStep->GetTrack()->GetTrackID() <<
" ("
452 << aStep->GetTrack()->GetDefinition()->GetParticleName() <<
")";
458 destep = aStep->GetTotalEnergyDeposit();
460 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
475 lay = (touch->GetReplicaNumber(0) / 10) % 100 + 1;
478 <<
" lay: " << lay - 2;
483 G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
508 int pdg = theTrack->GetDefinition()->GetPDGEncoding();
510 double ke = theTrack->GetKineticEnergy();
511 if (
pdg / 1000000000 == 1 && (
pdg / 10000) % 100 > 0 && (
pdg / 10) % 100 > 0 &&
ke <
kmaxIon)
521 const G4Material* mat = aStep->GetPreStepPoint()->GetMaterial();
526 double wt2 = theTrack->GetWeight();
527 double edep =
weight_ * wt1 * destep;
533 <<
" weight= " <<
weight_ <<
" wt1= " << wt1 <<
" wt2= " << wt2;
539 auto const prePoint = aStep->GetPreStepPoint();
540 auto const touch = prePoint->GetTouchable();
541 const G4ThreeVector& hitPoint = prePoint->GetPosition();
543 int depth = (touch->GetReplicaNumber(0)) % 10 + 1;
544 int lay = (touch->GetReplicaNumber(0) / 10) % 100 + 1;
545 int det = (touch->GetReplicaNumber(1)) / 1000;
552 edm::LogVerbatim(
"HcalSim") <<
"HCalSD: updates numbering scheme for " << GetName();
564 switch (theId.subdetId()) {
601 <<
" does not match one from relabller for " <<
tmp.subdet <<
":" <<
tmp.etaR <<
":"
602 <<
tmp.phi <<
":" <<
tmp.phis <<
":" <<
tmp.depth <<
":" <<
tmp.lay << std::endl;
608 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
609 int levels = (touch->GetHistoryDepth()) + 1;
610 for (
unsigned int it = 0; it <
hfNames.size(); ++it) {
612 const G4LogicalVolume* lv = touch->GetVolume(
levels -
hfLevels[it])->GetLogicalVolume();
622 if (
name == static_cast<G4String>(nam)) {
638 if (
name == static_cast<G4String>(nam)) {
645 for (
auto lvol :
pmtLV)
681 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::isItinFidVolume:#PMT= " << npmt <<
" for hit point " << hitPoint;
687 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::isItinFidVolume: point " << hitPoint <<
" return flag " <<
flag;
694 if (!isKilled ||
hits.empty()) {
703 auto const theTrack = aStep->GetTrack();
714 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::getFromLibrary " <<
hits.size() <<
" hits for " << GetName() <<
" of "
715 << primaryID <<
" with " << theTrack->GetDefinition()->GetParticleName() <<
" of "
716 << aStep->GetPreStepPoint()->GetKineticEnergy() /
GeV <<
" GeV";
718 for (
unsigned int i = 0;
i <
hits.size(); ++
i) {
719 G4ThreeVector hitPoint =
hits[
i].position;
742 auto const theTrack = aStep->GetTrack();
755 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::hitForFibre " <<
hits.size() <<
" hits for " << GetName() <<
" of "
756 << primaryID <<
" with " << theTrack->GetDefinition()->GetParticleName() <<
" of "
757 << aStep->GetPreStepPoint()->GetKineticEnergy() /
GeV <<
" GeV in detector type " << det;
760 for (
unsigned int i = 0;
i <
hits.size(); ++
i) {
761 G4ThreeVector hitPoint =
hits[
i].position;
779 if (!isKilled ||
hits.empty()) {
787 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::getFromParam " <<
hits.size() <<
" hits for " << GetName() <<
" of "
788 << primaryID <<
" with " << aStep->GetTrack()->GetDefinition()->GetParticleName()
789 <<
" of " << aStep->GetPreStepPoint()->GetKineticEnergy() /
GeV
790 <<
" GeV in detector type " << det;
792 for (
unsigned int i = 0;
i <
hits.size(); ++
i) {
793 G4ThreeVector hitPoint =
hits[
i].position;
808 auto const preStepPoint = aStep->GetPreStepPoint();
809 auto const theTrack = aStep->GetTrack();
814 double etrack = preStepPoint->GetKineticEnergy();
817 primaryID = theTrack->GetTrackID();
819 primaryID = theTrack->GetParentID();
821 primaryID = theTrack->GetTrackID();
827 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
828 double rr = (hitPoint.x() * hitPoint.x() + hitPoint.y() * hitPoint.y());
829 double phi = (
rr == 0. ? 0. : atan2(hitPoint.y(), hitPoint.x()));
836 if (hitPoint.z() < 0)
839 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::Hit for Detector " << det <<
" etaR " << etaR <<
" phi " <<
phi / deg
840 <<
" depth " <<
depth;
842 double time = (aStep->GetPostStepPoint()->GetGlobalTime());
856 double beta = preStepPoint->GetBeta();
857 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::getHitPMT 1 hit for " << GetName() <<
" of " << primaryID <<
" with "
858 << theTrack->GetDefinition()->GetParticleName() <<
" of "
859 << preStepPoint->GetKineticEnergy() /
GeV <<
" GeV with velocity " <<
beta <<
" UnitID "
867 auto const preStepPoint = aStep->GetPreStepPoint();
868 auto const theTrack = aStep->GetTrack();
873 double etrack = preStepPoint->GetKineticEnergy();
876 primaryID = theTrack->GetTrackID();
878 primaryID = theTrack->GetParentID();
880 primaryID = theTrack->GetTrackID();
886 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
887 double rr = hitPoint.x() * hitPoint.x() + hitPoint.y() * hitPoint.y();
888 double phi =
rr == 0. ? 0. : atan2(hitPoint.y(), hitPoint.x());
895 if (hitPoint.z() < 0.)
898 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::Hit for Detector " << det <<
" etaR " << etaR <<
" phi " <<
phi / deg
899 <<
" depth " <<
depth;
901 double time = (aStep->GetPostStepPoint()->GetGlobalTime());
918 double beta = preStepPoint->GetBeta();
919 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::getHitFibreBundle 1 hit for " << GetName() <<
" of " << primaryID
920 <<
" with " << theTrack->GetDefinition()->GetParticleName() <<
" of "
921 << preStepPoint->GetKineticEnergy() /
GeV <<
" GeV with velocity " <<
beta <<
" UnitID "
937 layerWeights.insert(std::pair<uint32_t, double>(
id, wt));
940 edm::LogVerbatim(
"HcalSim") <<
"HCalSD::readWeightFromFile:Entry " <<
entry <<
" ID " << std::hex <<
id
941 <<
std::dec <<
" (" << det <<
"/" <<
zside <<
"/1/" << etaR <<
"/" <<
phi <<
"/"
942 << lay <<
") Weight " << wt;
960 std::map<uint32_t, double>::const_iterator ite =
layerWeights.find(
id);
965 <<
tmp.zside <<
"/1/" <<
tmp.etaR <<
"/" <<
tmp.phis <<
"/" <<
tmp.lay <<
") Weight "
973 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
974 static const G4String modName[8] = {
"HEModule",
"HVQF",
"HBModule",
"MBAT",
"MBBT",
"MBBTC",
"MBBT_R1P",
"MBBT_R1M"};
977 double depth = -2000;
979 for (
int n = 0;
n < touch->GetHistoryDepth(); ++
n) {
980 G4String
name = touch->GetVolume(
n)->GetName();
984 for (
unsigned int ii = 0;
ii < 8; ++
ii) {
985 if (
name == modName[
ii]) {
987 int dn = touch->GetHistoryDepth() -
n;
988 local = touch->GetHistory()->GetTransform(dn).TransformPoint(global);
992 }
else if (
ii == 1) {
995 }
else if (
ii == 2) {
1012 <<
" depth " <<
depth <<
" ID " <<
id <<
" EDEP " << edep <<
" Time " <<
time;
1020 int jd = 2 *
idx +
id - 7;
1021 if (jd >= 0 && jd < 4) {
1023 if (
hit_[jd] !=
nullptr)
1024 hit_[jd]->Fill(edep);
1025 if (
time_[jd] !=
nullptr)
1027 if (
dist_[jd] !=
nullptr)
1035 if (
hzvem !=
nullptr)
1044 if (
id.subdet == 4) {
1045 int ieta = (
id.zside == 0) ? -
id.etaR :
id.etaR;
1047 if (
id.
depth <= 2) {
1048 if (G4UniformRand() > 0.5)
1052 }
else if ((
id.subdet == 1 ||
id.subdet == 2) &&
testNumber) {
1053 id.depth = (
depth_ == 0) ? 1 : 2;