30 #include <CLHEP/Vector/LorentzVector.h>
32 #include "DD4hep/Filter.h"
42 using namespace geant_units::operators;
46 public Observer<const BeginOfEvent*>,
47 public Observer<const BeginOfTrack*>,
63 void update(
const G4Step*)
override;
66 bool stopAfter(
const G4Step*);
71 bool isItHF(
const G4VTouchable*);
74 static const int maxSet_ = 25, maxSet2_ = 9;
75 double rMax_,
zMax_, etaMinP_, etaMaxP_;
81 double stepLens_[maxSet_], radLens_[maxSet_], intLens_[maxSet_];
99 edm::LogVerbatim(
"MaterialBudget") <<
"MaterialBudgetHcalProducer initialized with rMax " << rMax_ <<
" mm and zMax "
100 << zMax_ <<
" mm printSummary is set to " << printSum_ <<
" and Fromdd4hep to "
103 produces<MaterialAccountingCaloCollection>(Form(
"%sMatBCalo", name_.c_str()));
108 for (
auto const& mbc : matcoll_) {
109 hgc->emplace_back(mbc);
111 e.
put(
std::move(hgc), Form(
"%sMatBCalo", name_.c_str()));
119 (*job)()->get<IdealGeometryRecord>().get(pDD);
121 constexpr int32_t addLevel = 1;
127 for (
auto&
name : names) {
129 if (
std::find(sensitives_.begin(), sensitives_.end(), namx) == sensitives_.end())
130 sensitives_.emplace_back(namx);
132 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Names to be tested for " << attribute
133 <<
" = " << value <<
" has " << sensitives_.size() <<
" elements";
134 for (
unsigned int i = 0;
i < sensitives_.size();
i++)
136 <<
"MaterialBudgetHcalProducer: sensitives[" <<
i <<
"] = " << sensitives_[
i];
137 attribute =
"Volume";
141 std::vector<int>
temp = fv2.
get<std::vector<int> >(
"hf",
"Levels");
143 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Names to be tested for " << attribute
144 <<
" = " << value <<
" has " << hfNames_.size() <<
" elements";
145 for (
unsigned int i = 0;
i < hfNames_.size();
i++) {
146 hfLevels_.push_back(temp[
i] + addLevel);
148 <<
"MaterialBudgetHcalProducer: HF[" <<
i <<
"] = " << hfNames_[
i] <<
" at level " << hfLevels_[
i];
151 const std::string ecalRO[2] = {
"EcalHitsEB",
"EcalHitsEE"};
152 attribute =
"ReadOutName";
153 for (
int k = 0;
k < 2;
k++) {
157 std::vector<std::string> senstmp =
getNames(fv);
158 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Names to be tested for " << attribute
159 <<
" = " << value <<
" has " << senstmp.size() <<
" elements";
160 for (
unsigned int i = 0;
i < senstmp.size();
i++) {
162 if (
std::find(sensitiveEC_.begin(), sensitiveEC_.end(),
name) == sensitiveEC_.end())
163 sensitiveEC_.push_back(name);
166 for (
unsigned int i = 0;
i < sensitiveEC_.size();
i++)
168 <<
"MaterialBudgetHcalProducer:sensitiveEC[" <<
i <<
"] = " << sensitiveEC_[
i];
171 (*job)()->get<IdealGeometryRecord>().get(pDD);
173 constexpr int32_t addLevel = 0;
179 for (
auto&
name : names) {
181 if (
std::find(sensitives_.begin(), sensitives_.end(), namx) == sensitives_.end())
182 sensitives_.emplace_back(namx);
184 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Names to be tested for " << attribute
185 <<
" = " << value <<
" has " << sensitives_.size() <<
" elements";
186 for (
unsigned int i = 0;
i < sensitives_.size();
i++)
188 <<
"MaterialBudgetHcalProducer: sensitives[" <<
i <<
"] = " << sensitives_[
i];
189 attribute =
"Volume";
196 std::vector<double>
temp = getDDDArray(
"Levels", sv);
197 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Names to be tested for " << attribute
198 <<
" = " << value <<
" has " << hfNames_.size() <<
" elements";
199 for (
unsigned int i = 0;
i < hfNames_.size();
i++) {
200 int level =
static_cast<int>(temp[
i]);
201 hfLevels_.push_back(level + addLevel);
203 <<
"MaterialBudgetHcalProducer: HF[" <<
i <<
"] = " << hfNames_[
i] <<
" at level " << hfLevels_[
i];
206 const std::string ecalRO[2] = {
"EcalHitsEB",
"EcalHitsEE"};
207 attribute =
"ReadOutName";
208 for (
int k = 0;
k < 2;
k++) {
212 std::vector<std::string> senstmp =
getNames(fv3);
213 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Names to be tested for " << attribute
214 <<
" = " << value <<
" has " << senstmp.size() <<
" elements";
215 for (
unsigned int i = 0;
i < senstmp.size();
i++) {
217 if (
std::find(sensitiveEC_.begin(), sensitiveEC_.end(),
name) == sensitiveEC_.end())
218 sensitiveEC_.push_back(name);
221 for (
unsigned int i = 0;
i < sensitiveEC_.size();
i++)
223 <<
"MaterialBudgetHcalProducer:sensitiveEC[" <<
i <<
"] = " << sensitiveEC_[
i];
230 const G4Track* aTrack = (*trk)();
232 id_ =
layer_ = steps_ = 0;
233 radLen_ = intLen_ = stepLen_ = 0;
234 nlayHB_ = nlayHE_ = nlayHF_ = nlayHO_ = 0;
235 for (
int i = 0;
i < maxSet_; ++
i)
236 stepLens_[
i] = radLens_[
i] = intLens_[
i] = 0;
238 const G4ThreeVector&
dir = aTrack->GetMomentum();
239 if (dir.theta() != 0) {
245 edm::LogVerbatim(
"MaterialBudget") <<
"Start track with (eta, phi) = (" << eta_ <<
", " << phi_ <<
" Energy "
246 << aTrack->GetTotalEnergy() <<
" and ID "
247 << (aTrack->GetDefinition()->GetPDGEncoding());
259 G4Material* material = aStep->GetPreStepPoint()->GetMaterial();
260 double step = aStep->GetStepLength();
261 double radl = material->GetRadlen();
262 double intl = material->GetNuclearInterLength();
263 double density =
convertUnitsTo(1._g_per_cm3, material->GetDensity());
266 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
271 for (
unsigned int ii = 0;
ii < matList_.size();
ii++) {
272 if (matList_[
ii] == matName) {
274 radLength_[
ii] += (step / radl);
275 intLength_[
ii] += (step / intl);
281 matList_.push_back(matName);
282 stepLength_.push_back(step);
283 radLength_.push_back(step / radl);
284 intLength_.push_back(step / intl);
287 edm::LogVerbatim(
"MaterialBudget") <<
"Volume " << name <<
" id " << id_ <<
":" << idOld <<
" Step " << step
288 <<
" Material " << matName <<
" Old Length " << stepLen_ <<
" X0 "
289 << step / radl <<
":" << radLen_ <<
" Lambda " << step / intl <<
":"
293 edm::LogVerbatim(
"MaterialBudget") <<
"MaterialBudgetHcalProducer: Step at " << name <<
" id " << id_ <<
":"
294 << idOld <<
" Length " << step <<
" in " << matName <<
" of density "
295 << density <<
" g/cc; Radiation Length " << radl <<
" mm; Interaction Length "
296 << intl <<
" mm\n Position "
297 << aStep->GetPreStepPoint()->GetPosition() <<
" Cylindrical R "
298 << aStep->GetPreStepPoint()->GetPosition().perp() <<
" Length (so far) "
299 << stepLen_ <<
" L/X0 " << step / radl <<
"/" << radLen_ <<
" L/Lambda "
300 << step / intl <<
"/" << intLen_;
303 int det = 0, lay = 0;
305 edm::LogVerbatim(
"MaterialBudgetFull") <<
"Volume " << name <<
":" << matName <<
" EC:Sensitive:HF " << isItEC(name)
306 <<
":" << isSensitive(name) <<
":" << isItHF(touch) <<
" Eta " << abseta
307 <<
" HC " << ((touch->GetReplicaNumber(1)) / 1000) <<
":"
308 << ((touch->GetReplicaNumber(0) / 10) % 100 + 3) <<
" X0 "
309 << (radLen_ + (step / radl)) <<
" Lambda " << (intLen_ + (step / intl));
315 if (isSensitive(name)) {
322 det = (touch->GetReplicaNumber(1)) / 1000;
323 lay = (touch->GetReplicaNumber(0) / 10) % 100 + 3;
337 }
else if (lay !=
layer_) {
344 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Det " << det <<
" Layer " << lay <<
" Eta "
359 if ((abseta >= etaMinP_) && (abseta <= etaMaxP_))
360 edm::LogVerbatim(
"MaterialBudget") <<
"MaterialBudgetHcalProducer: Step at " << name <<
" calls filHisto with "
362 stepLens_[id_ - 1] = stepLen_;
363 radLens_[id_ - 1] = radLen_;
364 intLens_[id_ - 1] = intLen_;
368 radLen_ += (step / radl);
369 intLen_ += (step / intl);
371 if (!isItHF(aStep->GetPostStepPoint()->GetTouchable())) {
372 if ((abseta >= etaMinP_) && (abseta <= etaMaxP_))
373 edm::LogVerbatim(
"MaterialBudget") <<
"MaterialBudgetHcalProducer: After HF in " << name <<
":"
374 <<
static_cast<std::string>(dd4hep::dd::noNamespace(
375 aStep->GetPostStepPoint()->GetTouchable()->GetVolume(0)->GetName()))
376 <<
" calls fillHisto with " << id_;
377 stepLens_[idOld] = stepLen_;
378 radLens_[idOld] = radLen_;
379 intLens_[idOld] = intLen_;
386 if (stopAfter(aStep)) {
387 G4Track*
track = aStep->GetTrack();
388 track->SetTrackStatus(fStopAndKill);
394 matCalo.
m_eta = eta_;
395 matCalo.
m_phi = phi_;
396 for (
int k = 0;
k < maxSet_; ++
k) {
398 matCalo.
m_radLen.emplace_back(radLens_[k]);
399 matCalo.
m_intLen.emplace_back(intLens_[k]);
401 matCalo.
m_layers.emplace_back(nlayHB_);
402 matCalo.
m_layers.emplace_back(nlayHE_);
403 matCalo.
m_layers.emplace_back(nlayHO_);
404 matCalo.
m_layers.emplace_back(nlayHF_);
405 matcoll_.emplace_back(matCalo);
409 G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
410 double rr = hitPoint.perp();
413 if (rr > rMax_ || zz > zMax_) {
414 edm::LogVerbatim(
"MaterialBudget") <<
" MaterialBudgetHcalProducer::StopAfter R = " << rr <<
" and Z = " << zz;
422 std::vector<std::string>
tmp;
427 if (
std::find(tmp.begin(), tmp.end(), namx) == tmp.end())
435 std::vector<std::string>
tmp;
436 const std::vector<std::string> notIn = {
437 "CALO",
"HCal",
"MBBTL",
"MBBTR",
"MBBTC",
"MBAT",
"MBBT_R1M",
"MBBT_R1P",
"MBBT_R1MX",
"MBBT_R1PX",
"VCAL"};
440 if (
std::find(notIn.begin(), notIn.end(),
n) == notIn.end()) {
443 if (
std::find(tmp.begin(), tmp.end(), namx) == tmp.end())
451 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer:getDDDArray called for " <<
str;
455 const std::vector<double>& fvec = value.
doubles();
456 int nval = fvec.size();
458 throw cms::Exception(
"MaterialBudgetHcalProducer") <<
"nval = " << nval <<
" < 1 for array " << str <<
"\n";
463 throw cms::Exception(
"MaterialBudgetHcalProducer") <<
"cannot get array " << str <<
"\n";
468 std::vector<std::string>::const_iterator it = sensitives_.begin();
469 std::vector<std::string>::const_iterator itEnd = sensitives_.end();
470 std::string namx = (name.find(
'_') == std::string::npos) ? name : name.substr(0, name.find(
'_'));
471 for (; it != itEnd; ++it)
478 int levels = ((touch->GetHistoryDepth()) + 1);
479 for (
unsigned int it = 0; it < hfNames_.size(); it++) {
480 if (levels >= hfLevels_[it]) {
482 (
static_cast<std::string>(dd4hep::dd::noNamespace(touch->GetVolume(levels - hfLevels_[it])->GetName())))
484 if (name == hfNames_[it]) {
493 std::vector<std::string>::const_iterator it = sensitiveEC_.begin();
494 std::vector<std::string>::const_iterator itEnd = sensitiveEC_.end();
495 for (; it != itEnd; ++it)
496 if (name.substr(0, 4) == *it)
Log< level::Info, true > LogVerbatim
T getUntrackedParameter(std::string const &, T const &) const
bool isItEC(const std::string &)
#define DEFINE_SIMWATCHER(type)
static const char layer_[]
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
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
static std::vector< std::string > checklist log
bool stopAfter(const G4Step *)
std::vector< double > stepLength_
constexpr NumType convertRadToDeg(NumType radians)
std::vector< MaterialAccountingCalo > MaterialAccountingCaloCollection
std::vector< double > m_radLen
std::vector< double > getDDDArray(const std::string &str, const DDsvalues_type &sv)
bool isSensitive(const std::string &)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Compact representation of the geometrical detector hierarchy.
bool DDfetch(const DDsvalues_type *, DDValue &)
helper for retrieving DDValues from DDsvalues_type *.
const std::string names[nVars_]
constexpr NumType convertUnitsTo(double desiredUnits, NumType val)
MaterialBudgetHcalProducer(const edm::ParameterSet &)
std::vector< std::pair< unsigned int, DDValue > > DDsvalues_type
bool next()
set current node to the next node in the filtered tree
bool isItHF(const G4VTouchable *)
Abs< T >::type abs(const T &t)
A DDLogicalPart aggregates information concerning material, solid and sensitveness ...
std::string_view name() const
bool firstChild()
set the current node to the first child
void update(const BeginOfJob *) override
This routine will be called when the appropriate signal arrives.
T get(const std::string &)
extract attribute value
MaterialAccountingCaloCollection matcoll_
std::vector< std::string > sensitives_
T getParameter(std::string const &) const
std::vector< int > m_layers
std::vector< double > m_intLen
DDsvalues_type mergedSpecifics() const
std::vector< std::string > matList_
std::vector< int > hfLevels_
void produce(edm::Event &, const edm::EventSetup &) override
bool firstChild()
set the current node to the first child ...
std::vector< double > m_stepLen
const std::string & name() const
Returns the name.
std::vector< std::string > getNames(DDFilteredView &fv)