21 #include "DD4hep/Filter.h"
23 #include "G4LogicalVolumeStore.hh"
24 #include "G4LogicalVolume.hh"
27 #include "G4VProcess.hh"
28 #include "G4SystemOfUnits.hh"
34 using namespace geant_units::operators;
37 bool any(
const std::vector<T>&
v,
const T& what) {
38 return std::find(v.begin(), v.end(), what) != v.end();
50 (float)(p.getParameter<edm::
ParameterSet>(
"ECalSD").getParameter<double>(
"TimeSliceUnit")),
51 p.getParameter<edm::
ParameterSet>(
"ECalSD").getParameter<bool>(
"IgnoreTrackID")),
52 ecalSimParameters_(ecpar) {
65 double bunit = (
CLHEP::g / (CLHEP::MeV * CLHEP::cm2));
84 if (ageingWithSlopeLY)
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();
136 edm::LogVerbatim(
"EcalSim") <<
"ECalSD:: Use of Birks law is set to " << useBirk
137 <<
" with three constants kB = " <<
birk1 / bunit <<
", C1 = " << birk2
138 <<
", C2 = " << birk3 <<
"\n Use of L3 parametrization " << useBirkL3
139 <<
" with slope " << birkSlope <<
" and cut off " << birkCut <<
"\n"
140 <<
" Slope for Light yield is set to " <<
slopeLY;
143 <<
" by Birk or light yield curve";
148 <<
" MeV,\tions below " <<
kmaxIon / CLHEP::MeV <<
" MeV \n\tDepth1 Name = " <<
depth1Name
149 <<
"\tDepth2 Name = " <<
depth2Name <<
"\n\tstoreRL " << storeRL <<
":" << scaleRL
150 <<
"\tstoreLayerTimeSim " << storeLayerTimeSim <<
"\n\ttime Granularity "
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;
164 g2L_[
k] = ecDir.
make<TH2F>(name.c_str(), title.c_str(), 100,
xmin, xmin + 1000., 100, 0.0, 3000.);
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();
214 edep *= weight * wt1;
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;
328 if (scheme !=
nullptr) {
329 edm::LogVerbatim(
"EcalSim") <<
"EcalSD: updates numbering scheme for " << GetName();
335 std::vector<const G4LogicalVolume*> lvused;
336 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
337 std::map<const std::string, const G4LogicalVolume*> nameMap;
338 for (
auto lvi = lvs->begin(), lve = lvs->end(); lvi != lve; ++lvi)
339 nameMap.emplace(dd4hep::dd::noNamespace((*lvi)->GetName()), *lvi);
344 const G4LogicalVolume* lv = nameMap[lvname];
345 int ibec = (lvname.find(
"EFRY") == std::string::npos) ? 0 : 1;
346 int iref = (lvname.find(
"refl") == std::string::npos) ? 0 : 1;
347 int type = (ibec + iref == 1) ? 1 : -1;
349 if (strncmp(lvname.c_str(),
depth1Name.c_str(), 4) == 0) {
353 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" in Depth 1 volume list";
356 const G4LogicalVolume* lvr = nameMap[lvname +
"_refl"];
360 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
"_refl"
361 <<
" in Depth 1 volume list";
367 if (strncmp(lvname.c_str(),
depth2Name.c_str(), 4) == 0) {
371 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" in Depth 2 volume list";
374 const G4LogicalVolume* lvr = nameMap[lvname +
"_refl"];
378 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
"_refl"
379 <<
" in Depth 2 volume list";
386 if (!
any(lvused, lv)) {
387 lvused.push_back(lv);
389 xtalLMap.insert(std::pair<const G4LogicalVolume*, double>(lv, dz * type));
390 lv = nameMap[lvname +
"_refl"];
392 xtalLMap.insert(std::pair<const G4LogicalVolume*, double>(lv, -dz * type));
399 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" Material " << matname
400 <<
" in noWeight list";
403 lv = nameMap[lvname];
407 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
" Material " << matname
408 <<
" in noWeight list";
419 if (ite.first !=
nullptr)
420 name = dd4hep::dd::noNamespace((ite.first)->GetName());
421 edm::LogVerbatim(
"EcalSim") <<
" " << i <<
" " << ite.first <<
" " << name <<
" L = " << ite.second;
439 edm::LogWarning(
"EcalSim") <<
"ECalSD: light coll curve : wrong distance "
440 <<
"to APD " << dapd <<
" crlength = " <<
crystalLength <<
":" << crystalDepth
441 <<
" crystal name = " << lv->GetName() <<
" " << dd4hep::dd::noNamespace(lv->GetName())
447 <<
" crystal name = " << lv->GetName() <<
" " << dd4hep::dd::noNamespace(lv->GetName())
455 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
456 int theSize = touch->GetHistoryDepth() + 1;
461 for (
int ii = 0;
ii < theSize;
ii++) {
462 std::string_view
name = dd4hep::dd::noNamespace(touch->GetVolume(
ii)->GetName());
465 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::getBaseNumber(): Adding level " <<
ii <<
": " << name <<
"["
466 << touch->GetReplicaNumber(
ii) <<
"]";
474 const G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
475 double charge = preStepPoint->GetCharge();
477 if (charge != 0. && aStep->GetStepLength() > 0.) {
478 const G4Material* mat = preStepPoint->GetMaterial();
479 double density = mat->GetDensity();
480 double dedx = aStep->GetTotalEnergyDeposit() / aStep->GetStepLength();
481 double rkb =
birk1 / density;
486 else if (weight > 1.)
490 edm::LogVerbatim(
"EcalSim") <<
"ECalSD::getBirkL3 in " << dd4hep::dd::noNamespace(mat->GetName()) <<
" Charge "
491 << charge <<
" dE/dx " << dedx <<
" Birk Const " << rkb <<
" Weight = " << weight
492 <<
" dE " << aStep->GetTotalEnergyDeposit();
Log< level::Info, true > LogVerbatim
T getUntrackedParameter(std::string const &, T const &) const
bool isXtal(const G4LogicalVolume *)
static std::vector< std::string > checklist log
std::vector< std::string > lvNames_
void setLumies(double x, double y)
std::vector< const G4LogicalVolume * > useDepth2
void getBaseNumber(const G4Step *)
static const int kEcalDepthRefz
std::vector< const G4LogicalVolume * > noWeight
bool any(const std::vector< T > &v, const T &what)
double getEnergyDeposit(const G4Step *) override
std::unique_ptr< EcalNumberingScheme > numberingScheme_
virtual int getTrackID(const G4Track *)
std::vector< double > dzs_
Log< level::Error, false > LogError
const std::vector< std::string_view > logicalNames(const std::string &readoutName) const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
double getBirkL3(const G4Step *)
int getTrackID(const G4Track *) override
std::vector< std::string > matNames_
void addLevel(const std::string &name, const int ©Number)
std::map< const G4LogicalVolume *, double > xtalLMap
EcalBaseNumber theBaseNumber
static const int kEcalDepthMask
Abs< T >::type abs(const T &t)
uint16_t getLayerIDForTimeSim()
static const int kEcalDepthOffset
T * make(const Args &...args) const
make new ROOT object
const EcalSimulationParameters * ecalSimParameters_
G4ThreeVector setToLocal(const G4ThreeVector &, const G4VTouchable *) const
G4ThreeVector currentLocalPoint
uint16_t getRadiationLength(const G4StepPoint *hitPoint, const G4LogicalVolume *lv)
std::vector< const G4LogicalVolume * > useDepth1
TFileDirectory mkdir(const std::string &dir, const std::string &descr="")
create a new subdirectory
T getParameter(std::string const &) const
double calcLightCollectionEfficiencyWeighted(DetId id, double z)
double getAttenuation(const G4Step *aStep, double birk1, double birk2, double birk3) const
ECalSD(const std::string &, const EcalSimulationParameters *, const SensitiveDetectorCatalog &, edm::ParameterSet const &p, const SimTrackManager *)
double curve_LY(const G4LogicalVolume *)
EnergyResolutionVsLumi ageing
Log< level::Warning, false > LogWarning
void setNumberingScheme(EcalNumberingScheme *)
uint32_t setDetUnitId(const G4Step *) override
double getResponseWt(const G4Track *)
void setSize(const int &size)
double EnergyCorrected(const G4Step &, const G4Track *) override
tuple dump
OutputFilePath = cms.string('/tmp/zhokin/'), OutputFileExt = cms.string(''),.
uint16_t getDepth(const G4Step *) override