29 #include <CLHEP/Vector/LorentzVector.h>
31 #include "DD4hep/Filter.h"
41 using namespace geant_units::operators;
44 public Observer<const BeginOfEvent*>,
45 public Observer<const BeginOfTrack*>,
62 void update(
const G4Step*)
override;
65 bool stopAfter(
const G4Step*);
70 bool isItHF(
const G4VTouchable*);
73 static const int maxSet_ = 25, maxSet2_ = 9;
74 double rMax_,
zMax_, etaMinP_, etaMaxP_;
84 double stepLens_[maxSet_], radLens_[maxSet_], intLens_[maxSet_];
102 edm::LogVerbatim(
"MaterialBudget") <<
"MaterialBudgetHcalProducer initialized with rMax " << rMax_ <<
" mm and zMax "
103 << zMax_ <<
" mm printSummary is set to " << printSum_ <<
" and Fromdd4hep to "
106 produces<MaterialAccountingCaloCollection>(Form(
"%sMatBCalo", name_.c_str()));
114 edm::LogVerbatim(
"MaterialBudget") <<
"MaterialBudgetHcalProducer: Initialize the token for CompactView";
119 for (
auto const& mbc : matcoll_) {
120 hgc->emplace_back(mbc);
122 e.
put(
std::move(hgc), Form(
"%sMatBCalo", name_.c_str()));
130 constexpr int32_t addLevel = 1;
136 for (
auto&
name : names) {
138 if (
std::find(sensitives_.begin(), sensitives_.end(), namx) == sensitives_.end())
139 sensitives_.emplace_back(namx);
141 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Names to be tested for " << attribute
142 <<
" = " << value <<
" has " << sensitives_.size() <<
" elements";
143 for (
unsigned int i = 0;
i < sensitives_.size();
i++)
145 <<
"MaterialBudgetHcalProducer: sensitives[" <<
i <<
"] = " << sensitives_[
i];
146 attribute =
"Volume";
150 std::vector<int>
temp = fv2.
get<std::vector<int> >(
"hf",
"Levels");
152 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Names to be tested for " << attribute
153 <<
" = " << value <<
" has " << hfNames_.size() <<
" elements";
154 for (
unsigned int i = 0;
i < hfNames_.size();
i++) {
155 hfLevels_.push_back(temp[
i] + addLevel);
157 <<
"MaterialBudgetHcalProducer: HF[" <<
i <<
"] = " << hfNames_[
i] <<
" at level " << hfLevels_[
i];
160 const std::string ecalRO[2] = {
"EcalHitsEB",
"EcalHitsEE"};
161 attribute =
"ReadOutName";
162 for (
int k = 0;
k < 2;
k++) {
166 std::vector<std::string> senstmp =
getNames(fv);
167 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Names to be tested for " << attribute
168 <<
" = " << value <<
" has " << senstmp.size() <<
" elements";
169 for (
unsigned int i = 0;
i < senstmp.size();
i++) {
171 if (
std::find(sensitiveEC_.begin(), sensitiveEC_.end(),
name) == sensitiveEC_.end())
172 sensitiveEC_.push_back(name);
175 for (
unsigned int i = 0;
i < sensitiveEC_.size();
i++)
177 <<
"MaterialBudgetHcalProducer:sensitiveEC[" <<
i <<
"] = " << sensitiveEC_[
i];
180 constexpr int32_t addLevel = 0;
186 for (
auto&
name : names) {
188 if (
std::find(sensitives_.begin(), sensitives_.end(), namx) == sensitives_.end())
189 sensitives_.emplace_back(namx);
191 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Names to be tested for " << attribute
192 <<
" = " << value <<
" has " << sensitives_.size() <<
" elements";
193 for (
unsigned int i = 0;
i < sensitives_.size();
i++)
195 <<
"MaterialBudgetHcalProducer: sensitives[" <<
i <<
"] = " << sensitives_[
i];
196 attribute =
"Volume";
203 std::vector<double>
temp = getDDDArray(
"Levels", sv);
204 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Names to be tested for " << attribute
205 <<
" = " << value <<
" has " << hfNames_.size() <<
" elements";
206 for (
unsigned int i = 0;
i < hfNames_.size();
i++) {
207 int level =
static_cast<int>(temp[
i]);
208 hfLevels_.push_back(level + addLevel);
210 <<
"MaterialBudgetHcalProducer: HF[" <<
i <<
"] = " << hfNames_[
i] <<
" at level " << hfLevels_[
i];
213 const std::string ecalRO[2] = {
"EcalHitsEB",
"EcalHitsEE"};
214 attribute =
"ReadOutName";
215 for (
int k = 0;
k < 2;
k++) {
219 std::vector<std::string> senstmp =
getNames(fv3);
220 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Names to be tested for " << attribute
221 <<
" = " << value <<
" has " << senstmp.size() <<
" elements";
222 for (
unsigned int i = 0;
i < senstmp.size();
i++) {
224 if (
std::find(sensitiveEC_.begin(), sensitiveEC_.end(),
name) == sensitiveEC_.end())
225 sensitiveEC_.push_back(name);
228 for (
unsigned int i = 0;
i < sensitiveEC_.size();
i++)
230 <<
"MaterialBudgetHcalProducer:sensitiveEC[" <<
i <<
"] = " << sensitiveEC_[
i];
237 const G4Track* aTrack = (*trk)();
239 id_ =
layer_ = steps_ = 0;
240 radLen_ = intLen_ = stepLen_ = 0;
241 nlayHB_ = nlayHE_ = nlayHF_ = nlayHO_ = 0;
242 for (
int i = 0;
i < maxSet_; ++
i)
243 stepLens_[
i] = radLens_[
i] = intLens_[
i] = 0;
245 const G4ThreeVector&
dir = aTrack->GetMomentum();
246 if (dir.theta() != 0) {
252 edm::LogVerbatim(
"MaterialBudget") <<
"Start track with (eta, phi) = (" << eta_ <<
", " << phi_ <<
" Energy "
253 << aTrack->GetTotalEnergy() <<
" and ID "
254 << (aTrack->GetDefinition()->GetPDGEncoding());
266 G4Material* material = aStep->GetPreStepPoint()->GetMaterial();
267 double step = aStep->GetStepLength();
268 double radl = material->GetRadlen();
269 double intl = material->GetNuclearInterLength();
270 double density =
convertUnitsTo(1._g_per_cm3, material->GetDensity());
273 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
278 for (
unsigned int ii = 0;
ii < matList_.size();
ii++) {
279 if (matList_[
ii] == matName) {
281 radLength_[
ii] += (step / radl);
282 intLength_[
ii] += (step / intl);
288 matList_.push_back(matName);
289 stepLength_.push_back(step);
290 radLength_.push_back(step / radl);
291 intLength_.push_back(step / intl);
294 edm::LogVerbatim(
"MaterialBudget") <<
"Volume " << name <<
" id " << id_ <<
":" << idOld <<
" Step " << step
295 <<
" Material " << matName <<
" Old Length " << stepLen_ <<
" X0 "
296 << step / radl <<
":" << radLen_ <<
" Lambda " << step / intl <<
":"
300 edm::LogVerbatim(
"MaterialBudget") <<
"MaterialBudgetHcalProducer: Step at " << name <<
" id " << id_ <<
":"
301 << idOld <<
" Length " << step <<
" in " << matName <<
" of density "
302 << density <<
" g/cc; Radiation Length " << radl <<
" mm; Interaction Length "
303 << intl <<
" mm\n Position "
304 << aStep->GetPreStepPoint()->GetPosition() <<
" Cylindrical R "
305 << aStep->GetPreStepPoint()->GetPosition().perp() <<
" Length (so far) "
306 << stepLen_ <<
" L/X0 " << step / radl <<
"/" << radLen_ <<
" L/Lambda "
307 << step / intl <<
"/" << intLen_;
310 int det = 0, lay = 0;
312 edm::LogVerbatim(
"MaterialBudgetFull") <<
"Volume " << name <<
":" << matName <<
" EC:Sensitive:HF " << isItEC(name)
313 <<
":" << isSensitive(name) <<
":" << isItHF(touch) <<
" Eta " << abseta
314 <<
" HC " << ((touch->GetReplicaNumber(1)) / 1000) <<
":"
315 << ((touch->GetReplicaNumber(0) / 10) % 100 + 3) <<
" X0 "
316 << (radLen_ + (step / radl)) <<
" Lambda " << (intLen_ + (step / intl));
322 if (isSensitive(name)) {
329 det = (touch->GetReplicaNumber(1)) / 1000;
330 lay = (touch->GetReplicaNumber(0) / 10) % 100 + 3;
344 }
else if (lay !=
layer_) {
351 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer: Det " << det <<
" Layer " << lay <<
" Eta "
366 if ((abseta >= etaMinP_) && (abseta <= etaMaxP_))
367 edm::LogVerbatim(
"MaterialBudget") <<
"MaterialBudgetHcalProducer: Step at " << name <<
" calls filHisto with "
369 stepLens_[id_ - 1] = stepLen_;
370 radLens_[id_ - 1] = radLen_;
371 intLens_[id_ - 1] = intLen_;
375 radLen_ += (step / radl);
376 intLen_ += (step / intl);
378 if (!isItHF(aStep->GetPostStepPoint()->GetTouchable())) {
379 if ((abseta >= etaMinP_) && (abseta <= etaMaxP_))
380 edm::LogVerbatim(
"MaterialBudget") <<
"MaterialBudgetHcalProducer: After HF in " << name <<
":"
381 <<
static_cast<std::string>(dd4hep::dd::noNamespace(
382 aStep->GetPostStepPoint()->GetTouchable()->GetVolume(0)->GetName()))
383 <<
" calls fillHisto with " << id_;
384 stepLens_[idOld] = stepLen_;
385 radLens_[idOld] = radLen_;
386 intLens_[idOld] = intLen_;
393 if (stopAfter(aStep)) {
394 G4Track*
track = aStep->GetTrack();
395 track->SetTrackStatus(fStopAndKill);
401 matCalo.
m_eta = eta_;
402 matCalo.
m_phi = phi_;
403 for (
int k = 0;
k < maxSet_; ++
k) {
405 matCalo.
m_radLen.emplace_back(radLens_[k]);
406 matCalo.
m_intLen.emplace_back(intLens_[k]);
408 matCalo.
m_layers.emplace_back(nlayHB_);
409 matCalo.
m_layers.emplace_back(nlayHE_);
410 matCalo.
m_layers.emplace_back(nlayHO_);
411 matCalo.
m_layers.emplace_back(nlayHF_);
412 matcoll_.emplace_back(matCalo);
416 G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
417 double rr = hitPoint.perp();
420 if (rr > rMax_ || zz > zMax_) {
421 edm::LogVerbatim(
"MaterialBudget") <<
" MaterialBudgetHcalProducer::StopAfter R = " << rr <<
" and Z = " << zz;
429 std::vector<std::string>
tmp;
434 if (
std::find(tmp.begin(), tmp.end(), namx) == tmp.end())
442 std::vector<std::string>
tmp;
443 const std::vector<std::string> notIn = {
444 "CALO",
"HCal",
"MBBTL",
"MBBTR",
"MBBTC",
"MBAT",
"MBBT_R1M",
"MBBT_R1P",
"MBBT_R1MX",
"MBBT_R1PX",
"VCAL"};
447 if (
std::find(notIn.begin(), notIn.end(),
n) == notIn.end()) {
450 if (
std::find(tmp.begin(), tmp.end(), namx) == tmp.end())
458 edm::LogVerbatim(
"MaterialBudgetFull") <<
"MaterialBudgetHcalProducer:getDDDArray called for " <<
str;
462 const std::vector<double>& fvec = value.
doubles();
463 int nval = fvec.size();
465 throw cms::Exception(
"MaterialBudgetHcalProducer") <<
"nval = " << nval <<
" < 1 for array " << str <<
"\n";
470 throw cms::Exception(
"MaterialBudgetHcalProducer") <<
"cannot get array " << str <<
"\n";
475 std::vector<std::string>::const_iterator it = sensitives_.begin();
476 std::vector<std::string>::const_iterator itEnd = sensitives_.end();
477 std::string namx = (name.find(
'_') == std::string::npos) ? name : name.substr(0, name.find(
'_'));
478 for (; it != itEnd; ++it)
485 int levels = ((touch->GetHistoryDepth()) + 1);
486 for (
unsigned int it = 0; it < hfNames_.size(); it++) {
487 if (levels >= hfLevels_[it]) {
489 (
static_cast<std::string>(dd4hep::dd::noNamespace(touch->GetVolume(levels - hfLevels_[it])->GetName())))
491 if (name == hfNames_[it]) {
500 std::vector<std::string>::const_iterator it = sensitiveEC_.begin();
501 std::vector<std::string>::const_iterator itEnd = sensitiveEC_.end();
502 for (; it != itEnd; ++it)
503 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_
void registerConsumes(edm::ConsumesCollector) override
constexpr NumType convertRadToDeg(NumType radians)
std::vector< MaterialAccountingCalo > MaterialAccountingCaloCollection
edm::ESGetToken< DDCompactView, IdealGeometryRecord > cpvTokenDDD_
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 *.
edm::ESGetToken< cms::DDCompactView, IdealGeometryRecord > cpvTokenDD4hep_
const std::string names[nVars_]
constexpr NumType convertUnitsTo(double desiredUnits, NumType val)
MaterialBudgetHcalProducer(const edm::ParameterSet &)
bool getData(T &iHolder) const
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
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 ...
void beginRun(edm::EventSetup const &) override
void update(const BeginOfEvent *) override
This routine will be called when the appropriate signal arrives.
std::vector< double > m_stepLen
const std::string & name() const
Returns the name.
std::vector< std::string > getNames(DDFilteredView &fv)