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)
36 return std::find(v.begin(), v.end(), what) != v.end();
42 CaloSD(name, cpv, clg, p, manager,
43 p.getParameter<edm::
ParameterSet>(
"ECalSD").getParameter<int>(
"TimeSliceUnit"),
44 p.getParameter<edm::
ParameterSet>(
"ECalSD").getParameter<bool>(
"IgnoreTrackID")),
87 std::vector<double> tempD =
getDDDArray(
"EnergyWeight",sv);
88 if (tempD.size() > 0) {
if (tempD[0] < 0.1) useWeight =
false; }
97 if (nullNS) scheme = 0;
100 else if (name ==
"EcalHitsES") {
104 }
else {
edm::LogWarning(
"EcalSim") <<
"ECalSD: ReadoutName not supported\n";}
108 LogDebug(
"EcalSim") <<
"Constructing a ECalSD with name " << GetName();
111 edm::LogInfo(
"EcalSim") <<
"ECalSD:: Use of Birks law is set to "
112 << useBirk <<
" with three constants kB = "
113 << birk1 <<
", C1 = " << birk2 <<
", C2 = "
114 << birk3 <<
"\n Use of L3 parametrization "
115 << useBirkL3 <<
" with slope " << birkSlope
116 <<
" and cut off " << birkCut <<
"\n"
117 <<
" Slope for Light yield is set to "
120 edm::LogInfo(
"EcalSim") <<
"ECalSD:: energy deposit is not corrected "
121 <<
" by Birk or light yield curve";
127 <<
" ions below " <<
kmaxIon <<
" MeV\n"
131 if (useWeight)
initMap(name,cpv);
145 G4Track*
theTrack = aStep->GetTrack();
146 double wt2 = theTrack->GetWeight();
147 G4String nameVolume =
preStepPoint->GetPhysicalVolume()->GetName();
154 int pdg = theTrack->GetDefinition()->GetPDGEncoding();
156 double ke = theTrack->GetKineticEnergy()/
MeV;
157 if (((pdg/1000000000 == 1 && ((pdg/10000)%100) > 0 &&
158 ((pdg/10)%100) > 0)) && (ke<
kmaxIon)) weight = 0;
159 if ((pdg == 2212) && (ke <
kmaxProton)) weight = 0;
160 if ((pdg == 2112) && (ke <
kmaxNeutron)) weight = 0;
163 LogDebug(
"EcalSim") <<
"Ignore Track " << theTrack->GetTrackID()
164 <<
" Type " << theTrack->GetDefinition()->GetParticleName()
165 <<
" Kinetic Energy " << ke <<
" MeV";
170 G4LogicalVolume* lv = aStep->GetPreStepPoint()->GetTouchable()->GetVolume(0)->GetLogicalVolume();
179 double edep = aStep->GetTotalEnergyDeposit()*weight*wt1;
196 if(wt2 > 0.0) { edep *= wt2; }
198 LogDebug(
"EcalSim") <<
"ECalSD:: " << nameVolume
199 <<
" Light Collection Efficiency " <<weight <<
":" <<wt1
200 <<
" Weighted Energy Deposit " << edep/
MeV <<
" MeV";
211 G4LogicalVolume* lv =
preStepPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
220 primaryID = aTrack->GetTrackID();
228 G4LogicalVolume* lv = aStep->GetPreStepPoint()->GetTouchable()->GetVolume(0)->GetLogicalVolume();
232 uint16_t depth1 = (ite ==
xtalLMap.end()) ? 0 : (((ite->second) >= 0) ? 0 :
244 G4StepPoint* hitPoint = aStep->GetPreStepPoint();
245 G4LogicalVolume* lv = hitPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
248 G4ThreeVector localPoint =
setToLocal(hitPoint->GetPosition(),
249 hitPoint->GetTouchable());
250 double radl = hitPoint->GetMaterial()->GetRadlen();
252 thisX0 = (uint16_t)floor(depth/radl);
269 edm::LogInfo(
"EcalSim") <<
"EcalSD: updates numbering scheme for "
270 << GetName() <<
"\n";
279 G4String attribute =
"ReadOutName";
287 std::vector<G4LogicalVolume*> lvused;
288 const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
289 std::vector<G4LogicalVolume *>::const_iterator lvcite;
290 std::map<std::string, G4LogicalVolume *> nameMap;
291 for (
auto lvi = lvs->begin(), lve = lvs->end(); lvi != lve; ++lvi)
292 nameMap.insert(std::make_pair((*lvi)->GetName(), *lvi));
298 G4LogicalVolume* lv = nameMap[lvname];
299 int ibec = (lvname.find(
"EFRY") == std::string::npos) ? 0 : 1;
300 int iref = (lvname.find(
"refl") == std::string::npos) ? 0 : 1;
301 int type = (ibec+iref == 1) ? 1 : -1;
303 if (strncmp(lvname.c_str(),
depth1Name.c_str(), 4) == 0) {
307 LogDebug(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname
308 <<
" in Depth 1 volume list";
311 G4LogicalVolume* lvr = nameMap[lvname +
"_refl"];
315 LogDebug(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
"_refl"
316 <<
" in Depth 1 volume list";
322 if (strncmp(lvname.c_str(),
depth2Name.c_str(), 4) == 0) {
326 LogDebug(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname
327 <<
" in Depth 2 volume list";
330 G4LogicalVolume* lvr = nameMap[lvname +
"_refl"];
334 LogDebug(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname <<
"_refl"
335 <<
" in Depth 2 volume list";
342 if (!
any(lvused,lv)) {
343 lvused.push_back(lv);
345 const std::vector<double> & paras = sol.
parameters();
347 LogDebug(
"EcalSim") <<
"ECalSD::initMap (for " << sd <<
"): Solid "
348 << lvname <<
" Shape " << sol.
shape()
349 <<
" Parameter 0 = "<< paras[0]
350 <<
" Logical Volume " << lv;
353 double dz = 2*paras[0];
354 xtalLMap.insert(std::pair<G4LogicalVolume*,double>(lv,dz*type));
355 lv = nameMap[lvname +
"_refl"];
357 xtalLMap.insert(std::pair<G4LogicalVolume*,double>(lv,-dz*type));
364 LogDebug(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname
365 <<
" Material " << matname <<
" in noWeight list";
368 lv = nameMap[lvname];
372 LogDebug(
"EcalSim") <<
"ECalSD::initMap Logical Volume " << lvname
373 <<
" Material " << matname <<
" in noWeight list";
381 LogDebug(
"EcalSim") <<
"ECalSD: Length Table for " << attribute <<
" = "
383 std::map<G4LogicalVolume*,double>::const_iterator ite =
xtalLMap.begin();
385 for (; ite !=
xtalLMap.end(); ite++, i++) {
386 G4String
name =
"Unknown";
387 if (ite->first != 0) name = (ite->first)->GetName();
388 LogDebug(
"EcalSim") <<
" " << i <<
" " << ite->first <<
" " << name
389 <<
" L = " << ite->second;
396 G4StepPoint* stepPoint = aStep->GetPreStepPoint();
397 G4LogicalVolume* lv = stepPoint->GetTouchable()->GetVolume(0)->GetLogicalVolume();
400 G4ThreeVector localPoint =
setToLocal(stepPoint->GetPosition(),
401 stepPoint->GetTouchable());
408 if (depth >= -0.1 || depth <= crlength+0.1)
412 double dapd = crlength - depth;
413 if (dapd >= -0.1 || dapd <= crlength+0.1) {
417 edm::LogWarning(
"EcalSim") <<
"ECalSD: light coll curve : wrong distance "
418 <<
"to APD " << dapd <<
" crlength = "
419 << crlength <<
" crystal name = " <<lv->GetName()
420 <<
" z of localPoint = " << localPoint.z()
421 <<
" take weight = " <<
weight;
425 LogDebug(
"EcalSim") <<
"ECalSD, light coll curve : " << dapd
426 <<
" crlength = " << crlength
427 <<
" crystal name = " << lv->GetName()
428 <<
" z of localPoint = " << localPoint.z()
429 <<
" take weight = " <<
weight;
441 const G4ThreeVector& localPoint) {
447 else depth =
std::abs(0.5*(ite->second)+localPoint.z());
455 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
456 int theSize = touch->GetHistoryDepth()+1;
460 for (
int ii = 0;
ii < theSize ;
ii++) {
463 LogDebug(
"EcalSim") <<
"ECalSD::getBaseNumber(): Adding level " <<
ii
464 <<
": " << touch->GetVolume(
ii)->GetName() <<
"["
465 << touch->GetReplicaNumber(
ii) <<
"]";
475 double charge = aStep->GetPreStepPoint()->GetCharge();
477 if (charge != 0. && aStep->GetStepLength() > 0) {
478 G4Material* mat = aStep->GetPreStepPoint()->GetMaterial();
479 double density = mat->GetDensity();
480 double dedx = aStep->GetTotalEnergyDeposit()/aStep->GetStepLength();
481 double rkb =
birk1/density;
485 else if (weight > 1.) weight = 1.;
488 LogDebug(
"EcalSim") <<
"ECalSD::getBirkL3 in " << mat->GetName()
489 <<
" Charge " << charge <<
" dE/dx " << dedx
490 <<
" Birk Const " << rkb <<
" Weight = " << weight
491 <<
" dE " << aStep->GetTotalEnergyDeposit();
502 LogDebug(
"EcalSim") <<
"ECalSD:getDDDArray called for " << str;
509 const std::vector<double> & fvec = value.
doubles();
512 std::vector<double> fvec;
521 LogDebug(
"EcalSim") <<
"ECalSD:getStringArray called for " << str;
528 const std::vector<std::string> & fvec = value.
strings();
531 std::vector<std::string> fvec;
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
const std::vector< double > & parameters(void) const
Give the parameters of the solid.
const DDLogicalPart & logicalPart() const
The logical-part of the current node in the filtered-view.
const std::vector< double > & doubles() const
a reference to the double-valued values stored in the given instance of DDValue
static std::vector< std::string > checklist log
void addFilter(const DDFilter &, log_op op=AND)
std::vector< std::string > getStringArray(const std::string &, const DDsvalues_type &)
std::vector< G4LogicalVolume * > useDepth1
void setLumies(double x, double y)
void getBaseNumber(const G4Step *)
static const int kEcalDepthRefz
virtual double getEnergyDeposit(G4Step *)
bool any(const std::vector< T > &v, const T &what)
virtual int getTrackID(G4Track *)
const DDSolid & solid(void) const
Returns a reference object of the solid being the shape of this LogicalPart.
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
type of data representation of DDCompactView
bool DDfetch(const DDsvalues_type *, DDValue &)
helper for retrieving DDValues from DDsvalues_type *.
std::vector< G4LogicalVolume * > noWeight
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
std::vector< G4LogicalVolume * > useDepth2
A DDSolid represents the shape of a part.
static TrackerG4SimHitNumberingScheme & numberingScheme(const DDCompactView &cpv, const GeometricDet &det)
virtual uint16_t getDepth(G4Step *)
void addLevel(const std::string &name, const int ©Number)
EcalBaseNumber theBaseNumber
bool next()
set current node to the next node in the filtered tree
std::vector< std::pair< unsigned int, DDValue > > DDsvalues_type
std::maps an index to a DDValue. The index corresponds to the index assigned to the name of the std::...
static const int kEcalDepthMask
double crystalLength(G4LogicalVolume *)
Abs< T >::type abs(const T &t)
DDSolidShape shape(void) const
The type of the solid.
static const int kEcalDepthOffset
virtual int getTrackID(G4Track *)
double getAttenuation(G4Step *aStep, double birk1, double birk2, double birk3)
void initMap(G4String, const DDCompactView &)
const std::vector< std::string > & strings() const
a reference to the std::string-valued values stored in the given instance of DDValue ...
double curve_LY(G4Step *)
G4StepPoint * preStepPoint
double crystalDepth(G4LogicalVolume *, const G4ThreeVector &)
std::vector< double > getDDDArray(const std::string &, const DDsvalues_type &)
virtual uint16_t getRadiationLength(G4Step *)
double getBirkL3(G4Step *)
double calcLightCollectionEfficiencyWeighted(DetId id, double z)
DDsvalues_type mergedSpecifics() const
double getResponseWt(G4Track *)
ECalSD(G4String, const DDCompactView &, SensitiveDetectorCatalog &, edm::ParameterSet const &p, const SimTrackManager *)
bool firstChild()
set the current node to the first child ...
void setCriteria(const DDValue &nameVal, comp_op, log_op l=AND, bool asString=true, bool merged=true)
virtual uint32_t setDetUnitId(G4Step *)
EcalNumberingScheme * numberingScheme
EnergyResolutionVsLumi ageing
std::map< G4LogicalVolume *, double > xtalLMap
void setNumberingScheme(EcalNumberingScheme *)
void setSize(const int &size)
const std::string & name() const
Returns the name.
const DDMaterial & material(void) const
Returns a reference object of the material this LogicalPart is made of.
virtual uint32_t getUnitID(const EcalBaseNumber &baseNumber) const =0
The DDGenericFilter is a runtime-parametrized Filter looking on DDSpecifcs.
G4ThreeVector setToLocal(const G4ThreeVector &, const G4VTouchable *)