21 #include "DD4hep/Filter.h"
23 #include "G4LogicalVolumeStore.hh"
24 #include "G4LogicalVolume.hh"
27 #include "G4VProcess.hh"
28 #include "G4SystemOfUnits.hh"
37 bool any(
const std::vector<T>&
v,
const T& what) {
52 ecalSimParameters_(ecpar),
53 numberingScheme_(nullptr) {
89 edm::LogError(
"EcalSim") <<
"ECalSD : Cannot find EcalSimulationParameters for " <<
name;
90 throw cms::Exception(
"Unknown",
"ECalSD") <<
"Cannot find EcalSimulationParameters for " <<
name <<
"\n";
108 }
else if (
name ==
"EcalHitsEB") {
111 dump = ((dumpGeom % 10) > 0);
112 }
else if (
name ==
"EcalHitsEE") {
115 dump = (((dumpGeom / 10) % 10) > 0);
116 }
else if (
name ==
"EcalHitsES") {
123 dump = (((dumpGeom / 100) % 10) > 0);
127 int type0 = dumpGeom / 1000;
128 type += (10 * type0);
133 edm::LogVerbatim(
"EcalSim") <<
"Constructing a ECalSD with name " << GetName();
137 <<
" with three constants kB = " <<
birk1 / bunit <<
", C1 = " <<
birk2
138 <<
", C2 = " <<
birk3 <<
"\n Use of L3 parametrization " <<
useBirkL3
140 <<
" Slope for Light yield is set to " <<
slopeLY;
143 <<
" by Birk or light yield curve";
157 if (
tfile.isAvailable()) {
159 static const std::string ctype[4] = {
"EB",
"EBref",
"EE",
"EERef"};
160 for (
int k = 0;
k < 4; ++
k) {
163 double xmin = (
k > 1) ? 3000.0 : 1000.0;
167 for (
int k = 0;
k < 4; ++
k)
181 const G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
182 const G4Track* theTrack = aStep->GetTrack();
183 double edep = aStep->GetTotalEnergyDeposit();
190 int pdg = theTrack->GetDefinition()->GetPDGEncoding();
192 double ke = theTrack->GetKineticEnergy();
193 if (((
pdg / 1000000000 == 1 && ((
pdg / 10000) % 100) > 0 && ((
pdg / 10) % 100) > 0)) && (
ke <
kmaxIon))
202 const G4LogicalVolume* lv = preStepPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
216 double wt2 = theTrack->GetWeight();
221 edm::LogVerbatim(
"EcalSim") << lv->GetName() <<
" " << dd4hep::dd::noNamespace(lv->GetName())
222 <<
" Light Collection Efficiency " <<
weight <<
":" << wt1 <<
" wt2= " << wt2
223 <<
" Weighted Energy Deposit " << edep /
CLHEP::MeV <<
" MeV at "
224 << preStepPoint->GetPosition();
230 double edep =
step.GetTotalEnergyDeposit();
231 const G4StepPoint* hitPoint =
step.GetPreStepPoint();
232 const G4LogicalVolume* lv = hitPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
248 primaryID = aTrack->GetTrackID();
257 const G4StepPoint* hitPoint = aStep->GetPreStepPoint();
259 const G4LogicalVolume* lv = hitPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
265 uint16_t depth1(0), depth2(0);
277 <<
std::dec <<
" Global " << (hitPoint->GetPosition()).
rho() <<
":"
281 <<
" L " << (ite ==
xtalLMap.end()) <<
":" << ite->second <<
" local "
290 double radl = hitPoint->GetMaterial()->GetRadlen();
293 const std::string& lvname = dd4hep::dd::noNamespace(lv->GetName());
294 int k1 = (lvname.find(
"EFRY") != std::string::npos) ? 2 : 0;
295 int k2 = (lvname.find(
"refl") != std::string::npos) ? 1 : 0;
297 double rz = (k1 == 0) ? (hitPoint->GetPosition()).
rho() :
std::abs((hitPoint->GetPosition()).
z());
298 edm::LogVerbatim(
"EcalSim") << lvname <<
" # " << k1 <<
":" << k2 <<
":" <<
kk <<
" rz " << rz <<
" D " << thisX0;
299 g2L_[
kk]->Fill(rz, thisX0);
302 G4ThreeVector localPoint =
setToLocal(hitPoint->GetPosition(), hitPoint->GetTouchable());
303 edm::LogVerbatim(
"EcalSim") << lv->GetName() <<
" " << dd4hep::dd::noNamespace(lv->GetName()) <<
" Global "
304 << hitPoint->GetPosition() <<
":" << (hitPoint->GetPosition()).
rho() <<
" Local "
305 << localPoint <<
" Crystal Length " <<
crystalLength <<
" Radl " << radl
306 <<
" crystalDepth " <<
crystalDepth <<
" Index " << thisX0 <<
" : "
314 const double invLayerSize = 0.1;
329 edm::LogVerbatim(
"EcalSim") <<
"EcalSD: updates numbering scheme for " << GetName();
337 std::vector<const G4LogicalVolume*> lvused;
338 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
339 std::map<const std::string, const G4LogicalVolume*> nameMap;
340 for (
auto lvi = lvs->begin(), lve = lvs->end(); lvi != lve; ++lvi)
341 nameMap.emplace(dd4hep::dd::noNamespace((*lvi)->GetName()), *lvi);
346 const G4LogicalVolume* lv = nameMap[lvname];
347 int ibec = (lvname.find(
"EFRY") == std::string::npos) ? 0 : 1;
348 int iref = (lvname.find(
"refl") == std::string::npos) ? 0 : 1;
349 int type = (ibec + iref == 1) ? 1 : -1;
351 if (strncmp(lvname.c_str(),
depth1Name.c_str(), 4) == 0) {
355 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" in Depth 1 volume list";
358 const G4LogicalVolume* lvr = nameMap[lvname +
"_refl"];
362 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
"_refl"
363 <<
" in Depth 1 volume list";
369 if (strncmp(lvname.c_str(),
depth2Name.c_str(), 4) == 0) {
373 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" in Depth 2 volume list";
376 const G4LogicalVolume* lvr = nameMap[lvname +
"_refl"];
380 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
"_refl"
381 <<
" in Depth 2 volume list";
388 if (!
any(lvused, lv)) {
389 lvused.push_back(lv);
391 xtalLMap.insert(std::pair<const G4LogicalVolume*, double>(lv,
dz *
type));
392 lv = nameMap[lvname +
"_refl"];
394 xtalLMap.insert(std::pair<const G4LogicalVolume*, double>(lv, -
dz *
type));
401 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" Material " << matname
402 <<
" in noWeight list";
405 lv = nameMap[lvname];
409 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" Material " << matname
410 <<
" in noWeight list";
421 if (ite.first !=
nullptr)
422 name = dd4hep::dd::noNamespace((ite.first)->GetName());
441 edm::LogWarning(
"EcalSim") <<
"ECalSD: light coll curve : wrong distance "
443 <<
" crystal name = " << lv->GetName() <<
" " << dd4hep::dd::noNamespace(lv->GetName())
449 <<
" crystal name = " << lv->GetName() <<
" " << dd4hep::dd::noNamespace(lv->GetName())
457 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
458 int theSize = touch->GetHistoryDepth() + 1;
463 for (
int ii = 0;
ii < theSize;
ii++) {
464 std::string_view
name = dd4hep::dd::noNamespace(touch->GetVolume(
ii)->GetName());
468 << touch->GetReplicaNumber(
ii) <<
"]";
476 const G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
477 double charge = preStepPoint->GetCharge();
479 if (
charge != 0. && aStep->GetStepLength() > 0.) {
480 const G4Material* mat = preStepPoint->GetMaterial();
481 double density = mat->GetDensity();
482 double dedx = aStep->GetTotalEnergyDeposit() / aStep->GetStepLength();
492 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::getBirkL3 in " << dd4hep::dd::noNamespace(mat->GetName()) <<
" Charge "
493 <<
charge <<
" dE/dx " << dedx <<
" Birk Const " << rkb <<
" Weight = " <<
weight
494 <<
" dE " << aStep->GetTotalEnergyDeposit();