21 #include "G4LogicalVolumeStore.hh"
22 #include "G4LogicalVolume.hh"
25 #include "G4VProcess.hh"
27 #include "G4SystemOfUnits.hh"
34 bool any(
const std::vector<T>&
v,
const T& what) {
50 ecalSimParameters_(nullptr),
51 numberingScheme_(nullptr) {
89 edm::LogError(
"EcalSim") <<
"ECalSD : Cannot find EcalSimulationParameters for " <<
name;
90 throw cms::Exception(
"Unknown",
"ECalSD") <<
"Cannot find EcalSimulationParameters for " <<
name <<
"\n";
106 }
else if (
name ==
"EcalHitsEB") {
108 }
else if (
name ==
"EcalHitsEE") {
110 }
else if (
name ==
"EcalHitsES") {
123 edm::LogVerbatim(
"EcalSim") <<
"Constructing a ECalSD with name " << GetName();
127 <<
" with three constants kB = " <<
birk1 <<
", C1 = " <<
birk2
128 <<
", C2 = " <<
birk3 <<
"\n Use of L3 parametrization " <<
useBirkL3
130 <<
" Slope for Light yield is set to " <<
slopeLY;
133 <<
" by Birk or light yield curve";
139 <<
"\tions below " <<
kmaxIon <<
" MeV"
142 <<
"\n\ttime Granularity "
149 if (
tfile.isAvailable()) {
151 static const std::string ctype[4] = {
"EB",
"EBref",
"EE",
"EERef"};
152 for (
int k = 0;
k < 4; ++
k) {
155 double xmin = (
k > 1) ? 3000.0 : 1000.0;
159 for (
int k = 0;
k < 4; ++
k)
168 const G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
169 const G4Track* theTrack = aStep->GetTrack();
170 double edep = aStep->GetTotalEnergyDeposit();
177 int pdg = theTrack->GetDefinition()->GetPDGEncoding();
179 double ke = theTrack->GetKineticEnergy();
180 if (((
pdg / 1000000000 == 1 && ((
pdg / 10000) % 100) > 0 && ((
pdg / 10) % 100) > 0)) && (
ke <
kmaxIon))
189 const G4LogicalVolume* lv = preStepPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
203 double wt2 = theTrack->GetWeight();
209 <<
" wt2= " << wt2 <<
" Weighted Energy Deposit " << edep /
MeV <<
" MeV";
218 primaryID = aTrack->GetTrackID();
227 const G4StepPoint* hitPoint = aStep->GetPreStepPoint();
229 const G4LogicalVolume* lv = hitPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
235 uint16_t depth1(0), depth2(0);
246 <<
" L " << (ite ==
xtalLMap.end()) <<
":" << ite->second;
254 double radl = hitPoint->GetMaterial()->GetRadlen();
258 int k1 = (lvname.find(
"EFRY") != std::string::npos) ? 2 : 0;
259 int k2 = (lvname.find(
"refl") != std::string::npos) ? 1 : 0;
261 double rz = (k1 == 0) ? (hitPoint->GetPosition()).
rho() :
std::abs((hitPoint->GetPosition()).
z());
262 edm::LogVerbatim(
"EcalSim") << lvname <<
" # " << k1 <<
":" << k2 <<
":" <<
kk <<
" rz " << rz <<
" D " << thisX0;
263 g2L_[
kk]->Fill(rz, thisX0);
266 G4ThreeVector localPoint =
setToLocal(hitPoint->GetPosition(), hitPoint->GetTouchable());
267 edm::LogVerbatim(
"EcalSim") << lv->GetName() <<
" Global " << hitPoint->GetPosition() <<
":"
268 << (hitPoint->GetPosition()).
rho() <<
" Local " << localPoint <<
" Crystal Length "
277 const double invLayerSize = 0.1;
292 edm::LogVerbatim(
"EcalSim") <<
"EcalSD: updates numbering scheme for " << GetName();
300 std::vector<const G4LogicalVolume*> lvused;
301 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
302 std::map<const std::string, const G4LogicalVolume*> nameMap;
303 for (
auto lvi = lvs->begin(), lve = lvs->end(); lvi != lve; ++lvi)
304 nameMap.emplace((*lvi)->GetName(), *lvi);
309 const G4LogicalVolume* lv = nameMap[lvname];
310 int ibec = (lvname.find(
"EFRY") == std::string::npos) ? 0 : 1;
311 int iref = (lvname.find(
"refl") == std::string::npos) ? 0 : 1;
312 int type = (ibec + iref == 1) ? 1 : -1;
314 if (strncmp(lvname.c_str(),
depth1Name.c_str(), 4) == 0) {
318 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" in Depth 1 volume list";
321 const G4LogicalVolume* lvr = nameMap[lvname +
"_refl"];
325 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
"_refl"
326 <<
" in Depth 1 volume list";
332 if (strncmp(lvname.c_str(),
depth2Name.c_str(), 4) == 0) {
336 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" in Depth 2 volume list";
339 const G4LogicalVolume* lvr = nameMap[lvname +
"_refl"];
343 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
"_refl"
344 <<
" in Depth 2 volume list";
351 if (!
any(lvused, lv)) {
352 lvused.push_back(lv);
354 xtalLMap.insert(std::pair<const G4LogicalVolume*, double>(lv,
dz *
type));
355 lv = nameMap[lvname +
"_refl"];
357 xtalLMap.insert(std::pair<const G4LogicalVolume*, double>(lv, -
dz *
type));
364 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" Material " << matname
365 <<
" in noWeight list";
368 lv = nameMap[lvname];
372 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" Material " << matname
373 <<
" in noWeight list";
383 G4String
name(
"Unknown");
385 name = (ite.first)->GetName();
404 edm::LogWarning(
"EcalSim") <<
"ECalSD: light coll curve : wrong distance "
406 <<
" crystal name = " << lv->GetName()
415 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
416 int theSize = touch->GetHistoryDepth() + 1;
421 for (
int ii = 0;
ii < theSize;
ii++) {
425 << touch->GetVolume(
ii)->GetName() <<
"[" << touch->GetReplicaNumber(
ii) <<
"]";
433 const G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
434 double charge = preStepPoint->GetCharge();
436 if (
charge != 0. && aStep->GetStepLength() > 0.) {
437 const G4Material* mat = preStepPoint->GetMaterial();
438 double density = mat->GetDensity();
439 double dedx = aStep->GetTotalEnergyDeposit() / aStep->GetStepLength();
449 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::getBirkL3 in " << mat->GetName() <<
" Charge " <<
charge <<
" dE/dx "
450 << dedx <<
" Birk Const " << rkb <<
" Weight = " <<
weight <<
" dE "
451 << aStep->GetTotalEnergyDeposit();