22 #include "DD4hep/Filter.h"
24 #include "G4LogicalVolumeStore.hh"
25 #include "G4LogicalVolume.hh"
28 #include "G4VProcess.hh"
29 #include "G4SystemOfUnits.hh"
38 bool any(
const std::vector<T>&
v,
const T& what) {
54 ecalSimParameters_(nullptr),
55 numberingScheme_(nullptr) {
95 edm::LogError(
"EcalSim") <<
"ECalSD : Cannot find EcalSimulationParameters for " <<
name;
96 throw cms::Exception(
"Unknown",
"ECalSD") <<
"Cannot find EcalSimulationParameters for " <<
name <<
"\n";
114 }
else if (
name ==
"EcalHitsEB") {
117 dump = ((dumpGeom % 10) > 0);
118 }
else if (
name ==
"EcalHitsEE") {
121 dump = (((dumpGeom / 10) % 10) > 0);
122 }
else if (
name ==
"EcalHitsES") {
129 dump = (((dumpGeom / 100) % 10) > 0);
133 int type0 = dumpGeom / 1000;
134 type += (10 * type0);
139 edm::LogVerbatim(
"EcalSim") <<
"Constructing a ECalSD with name " << GetName();
143 <<
" with three constants kB = " <<
birk1 / bunit <<
", C1 = " <<
birk2
144 <<
", C2 = " <<
birk3 <<
"\n Use of L3 parametrization " <<
useBirkL3
146 <<
" Slope for Light yield is set to " <<
slopeLY;
149 <<
" by Birk or light yield curve";
163 if (
tfile.isAvailable()) {
165 static const std::string ctype[4] = {
"EB",
"EBref",
"EE",
"EERef"};
166 for (
int k = 0;
k < 4; ++
k) {
169 double xmin = (
k > 1) ? 3000.0 : 1000.0;
173 for (
int k = 0;
k < 4; ++
k)
187 const G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
188 const G4Track* theTrack = aStep->GetTrack();
189 double edep = aStep->GetTotalEnergyDeposit();
196 int pdg = theTrack->GetDefinition()->GetPDGEncoding();
198 double ke = theTrack->GetKineticEnergy();
199 if (((
pdg / 1000000000 == 1 && ((
pdg / 10000) % 100) > 0 && ((
pdg / 10) % 100) > 0)) && (
ke <
kmaxIon))
208 const G4LogicalVolume* lv = preStepPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
222 double wt2 = theTrack->GetWeight();
227 edm::LogVerbatim(
"EcalSim") << lv->GetName() <<
" " << dd4hep::dd::noNamespace(lv->GetName())
228 <<
" Light Collection Efficiency " <<
weight <<
":" << wt1 <<
" wt2= " << wt2
229 <<
" Weighted Energy Deposit " << edep /
CLHEP::MeV <<
" MeV at "
230 << preStepPoint->GetPosition();
236 double edep =
step.GetTotalEnergyDeposit();
237 const G4StepPoint* hitPoint =
step.GetPreStepPoint();
238 const G4LogicalVolume* lv = hitPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
254 primaryID = aTrack->GetTrackID();
263 const G4StepPoint* hitPoint = aStep->GetPreStepPoint();
265 const G4LogicalVolume* lv = hitPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
271 uint16_t depth1(0), depth2(0);
283 <<
std::dec <<
" Global " << (hitPoint->GetPosition()).
rho() <<
":"
287 <<
" L " << (ite ==
xtalLMap.end()) <<
":" << ite->second <<
" local "
296 double radl = hitPoint->GetMaterial()->GetRadlen();
299 const std::string& lvname = dd4hep::dd::noNamespace(lv->GetName());
300 int k1 = (lvname.find(
"EFRY") != std::string::npos) ? 2 : 0;
301 int k2 = (lvname.find(
"refl") != std::string::npos) ? 1 : 0;
303 double rz = (k1 == 0) ? (hitPoint->GetPosition()).
rho() :
std::abs((hitPoint->GetPosition()).
z());
304 edm::LogVerbatim(
"EcalSim") << lvname <<
" # " << k1 <<
":" << k2 <<
":" <<
kk <<
" rz " << rz <<
" D " << thisX0;
305 g2L_[
kk]->Fill(rz, thisX0);
308 G4ThreeVector localPoint =
setToLocal(hitPoint->GetPosition(), hitPoint->GetTouchable());
309 edm::LogVerbatim(
"EcalSim") << lv->GetName() <<
" " << dd4hep::dd::noNamespace(lv->GetName()) <<
" Global "
310 << hitPoint->GetPosition() <<
":" << (hitPoint->GetPosition()).
rho() <<
" Local "
311 << localPoint <<
" Crystal Length " <<
crystalLength <<
" Radl " << radl
312 <<
" crystalDepth " <<
crystalDepth <<
" Index " << thisX0 <<
" : "
320 const double invLayerSize = 0.1;
335 edm::LogVerbatim(
"EcalSim") <<
"EcalSD: updates numbering scheme for " << GetName();
343 std::vector<const G4LogicalVolume*> lvused;
344 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
345 std::map<const std::string, const G4LogicalVolume*> nameMap;
346 for (
auto lvi = lvs->begin(), lve = lvs->end(); lvi != lve; ++lvi)
347 nameMap.emplace(dd4hep::dd::noNamespace((*lvi)->GetName()), *lvi);
352 const G4LogicalVolume* lv = nameMap[lvname];
353 int ibec = (lvname.find(
"EFRY") == std::string::npos) ? 0 : 1;
354 int iref = (lvname.find(
"refl") == std::string::npos) ? 0 : 1;
355 int type = (ibec + iref == 1) ? 1 : -1;
357 if (strncmp(lvname.c_str(),
depth1Name.c_str(), 4) == 0) {
361 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" in Depth 1 volume list";
364 const G4LogicalVolume* lvr = nameMap[lvname +
"_refl"];
368 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
"_refl"
369 <<
" in Depth 1 volume list";
375 if (strncmp(lvname.c_str(),
depth2Name.c_str(), 4) == 0) {
379 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" in Depth 2 volume list";
382 const G4LogicalVolume* lvr = nameMap[lvname +
"_refl"];
386 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
"_refl"
387 <<
" in Depth 2 volume list";
394 if (!
any(lvused, lv)) {
395 lvused.push_back(lv);
397 xtalLMap.insert(std::pair<const G4LogicalVolume*, double>(lv,
dz *
type));
398 lv = nameMap[lvname +
"_refl"];
400 xtalLMap.insert(std::pair<const G4LogicalVolume*, double>(lv, -
dz *
type));
407 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" Material " << matname
408 <<
" in noWeight list";
411 lv = nameMap[lvname];
415 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" Material " << matname
416 <<
" in noWeight list";
427 if (ite.first !=
nullptr)
428 name = dd4hep::dd::noNamespace((ite.first)->GetName());
447 edm::LogWarning(
"EcalSim") <<
"ECalSD: light coll curve : wrong distance "
449 <<
" crystal name = " << lv->GetName() <<
" " << dd4hep::dd::noNamespace(lv->GetName())
455 <<
" crystal name = " << lv->GetName() <<
" " << dd4hep::dd::noNamespace(lv->GetName())
463 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
464 int theSize = touch->GetHistoryDepth() + 1;
469 for (
int ii = 0;
ii < theSize;
ii++) {
470 std::string_view
name = dd4hep::dd::noNamespace(touch->GetVolume(
ii)->GetName());
474 << touch->GetReplicaNumber(
ii) <<
"]";
482 const G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
483 double charge = preStepPoint->GetCharge();
485 if (
charge != 0. && aStep->GetStepLength() > 0.) {
486 const G4Material* mat = preStepPoint->GetMaterial();
487 double density = mat->GetDensity();
488 double dedx = aStep->GetTotalEnergyDeposit() / aStep->GetStepLength();
498 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::getBirkL3 in " << dd4hep::dd::noNamespace(mat->GetName()) <<
" Charge "
499 <<
charge <<
" dE/dx " << dedx <<
" Birk Const " << rkb <<
" Weight = " <<
weight
500 <<
" dE " << aStep->GetTotalEnergyDeposit();