12 #include "G4VPhysicalVolume.hh"
13 #include "G4NavigationHistory.hh"
16 #include "G4ParticleTable.hh"
17 #include "Randomize.hh"
18 #include "CLHEP/Units/SystemOfUnits.h"
19 #include "CLHEP/Units/PhysicalConstants.h"
27 : hcalConstant_(hcons), hf(nullptr), emBranch(nullptr), hadBranch(nullptr), npe(0) {
37 backProb = m_HS.getParameter<
double>(
"BackProbability");
41 "BranchEvt",
"HFShowerLibraryEventInfos_hfshowerlib_HFShowerLibraryEventInfo");
42 std::string branchPre = m_HS.getUntrackedParameter<
std::string>(
"BranchPre",
"HFShowerPhotons_hfshowerlib_");
44 verbose = m_HS.getUntrackedParameter<
bool>(
"Verbosity",
false);
45 applyFidCut = m_HS.getParameter<
bool>(
"ApplyFiducialCut");
48 if (pTreeName.find(
'.') == 0)
49 pTreeName.erase(0, 2);
50 const char* nTree = pTreeName.c_str();
51 hf = TFile::Open(nTree);
54 edm::LogError(
"HFShower") <<
"HFShowerLibrary: opening " << nTree <<
" failed";
55 throw cms::Exception(
"Unknown",
"HFShowerLibrary") <<
"Opening of " << pTreeName <<
" fails\n";
57 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary: opening " << nTree <<
" successfully";
60 newForm = (branchEvInfo.empty());
61 TTree*
event(
nullptr);
63 event = (TTree*)
hf->Get(
"HFSimHits");
65 event = (TTree*)
hf->Get(
"Events");
67 TBranch* evtInfo(
nullptr);
70 evtInfo =
event->GetBranch(info.c_str());
75 edm::LogError(
"HFShower") <<
"HFShowerLibrary: HFShowerLibrayEventInfo"
76 <<
" Branch does not exist in Event";
77 throw cms::Exception(
"Unknown",
"HFShowerLibrary") <<
"Event information absent\n";
80 edm::LogError(
"HFShower") <<
"HFShowerLibrary: Events Tree does not "
82 throw cms::Exception(
"Unknown",
"HFShowerLibrary") <<
"Events tree absent\n";
86 ss <<
"HFShowerLibrary: Library " <<
libVers <<
" ListVersion " <<
listVersion <<
" File version " << fileVersion_
88 ss <<
"HFShowerLibrary: Energies (GeV) with " <<
nMomBin <<
" bins\n";
90 if (
i / 10 * 10 ==
i &&
i > 0) {
93 ss <<
" " <<
pmom[
i] / CLHEP::GeV;
97 std::string nameBr = branchPre + emName + branchPost;
98 emBranch =
event->GetBranch(nameBr.c_str());
101 nameBr = branchPre + hadName + branchPost;
102 hadBranch =
event->GetBranch(nameBr.c_str());
112 <<
" entries and Branch " << hadName <<
" has " <<
hadBranch->GetEntries()
113 <<
" entries\n HFShowerLibrary::No packing information - Assume x, y, z are not in "
114 "packed form\n Maximum probability cut off "
115 << probMax <<
" Back propagation of light probability " <<
backProb
119 photo = std::make_unique<HFShowerPhotonCollection>();
122 std::vector<double> rTable = hcalConstant_->getRTableHF();
124 rMax = rTable[rTable.size() - 1];
127 std::vector<double> phibin = hcalConstant_->getPhiTableHF();
131 <<
" (Half) Phi Width of wedge " <<
dphi / CLHEP::deg;
134 gpar = hcalConstant_->getGparHF();
146 auto const preStepPoint = aStep->GetPreStepPoint();
147 auto const postStepPoint = aStep->GetPostStepPoint();
148 auto const track = aStep->GetTrack();
150 auto const aParticle =
track->GetDynamicParticle();
151 const G4ThreeVector& momDir = aParticle->GetMomentumDirection();
152 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
153 int parCode =
track->GetDefinition()->GetPDGEncoding();
157 if (
track->GetDefinition()->IsGeneralIon()) {
158 parCode = 1000020040;
162 G4String partType =
track->GetDefinition()->GetParticleName();
163 const G4ThreeVector localPos = preStepPoint->GetTouchable()->GetHistory()->GetTopTransform().TransformPoint(hitPoint);
164 double zoff = localPos.z() + 0.5 *
gpar[1];
166 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary::getHits " << partType <<
" of energy "
167 <<
track->GetKineticEnergy() / CLHEP::GeV <<
" GeV weight= " << weight
168 <<
" onlyLong: " << onlyLong <<
" dir.orts " << momDir.x() <<
", " << momDir.y() <<
", "
169 << momDir.z() <<
" Pos x,y,z = " << hitPoint.x() <<
"," << hitPoint.y() <<
","
170 << hitPoint.z() <<
" (" << zoff <<
") sphi,cphi,stheta,ctheta = " <<
sin(momDir.phi())
171 <<
"," <<
cos(momDir.phi()) <<
", " <<
sin(momDir.theta()) <<
"," <<
cos(momDir.theta());
174 double tSlice = (postStepPoint->GetGlobalTime()) / CLHEP::nanosecond;
177 double pin = (
track->GetDefinition()->GetBaryonNumber() > 0) ? preStepPoint->GetKineticEnergy()
178 : preStepPoint->GetTotalEnergy();
180 return fillHits(hitPoint, momDir, parCode, pin, isKilled, weight, tSlice, onlyLong);
184 const G4ThreeVector& momDir,
191 std::vector<HFShowerLibrary::Hit>
hit;
202 if (pin < threshold) {
206 double pz = momDir.z();
207 double zint = hitPoint.z();
210 bool backward = (pz * zint < 0.) ?
true :
false;
212 double sphi =
sin(momDir.phi());
213 double cphi =
cos(momDir.phi());
214 double ctheta =
cos(momDir.theta());
215 double stheta =
sin(momDir.theta());
233 for (
int i = 0;
i <
npe; ++
i) {
238 if (zv <=
gpar[1] &&
pe[
i].lambda() > 0 && (
pe[
i].
z() >= 0 || (zv >
gpar[0] && (!onlyLong)))) {
241 }
else if (!backward) {
245 double r = G4UniformRand();
252 double pex =
pe[
i].x();
253 double pey =
pe[
i].y();
255 double xx = pex * ctheta * cphi - pey * sphi + zv * stheta * cphi;
256 double yy = pex * ctheta * sphi + pey * cphi + zv * stheta * sphi;
257 double zz = -pex * stheta + zv * ctheta;
259 G4ThreeVector pos = hitPoint + G4ThreeVector(xx, yy, zz);
261 G4ThreeVector lpos = G4ThreeVector(pos.x(), pos.y(),
zv);
263 zv =
fibre_->zShift(lpos, depth, 0);
265 double r = pos.perp();
267 double fi = pos.phi();
270 int isect = int(fi /
dphi) + 1;
271 isect = (isect + 1) / 2;
272 double dfi = ((isect * 2 - 1) *
dphi - fi);
275 double dfir = r *
sin(dfi);
277 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary: Position shift " << xx <<
", " << yy <<
", " << zz <<
": "
278 << pos <<
" R " << r <<
" Phi " << fi <<
" Section " << isect <<
" R*Dfi " << dfir
282 double r1 = G4UniformRand();
283 double r2 = G4UniformRand();
284 double r3 = backward ? G4UniformRand() : -9999.;
290 <<
exp(-p * zv) <<
" r2 " << r2 <<
" r3 " << r3 <<
" rDfi " <<
gpar[5] <<
" zz "
291 << zz <<
" zLim " <<
gpar[4] <<
":" <<
gpar[4] +
gpar[1] <<
"\n"
292 <<
" rInside(r) :" <<
rInside(r) <<
" r1 <= exp(-p*zv) :" << (r1 <=
exp(-p * zv))
293 <<
" r2 <= probMax :" << (r2 <=
probMax * weight)
294 <<
" r3 <= backProb :" << (r3 <=
backProb)
295 <<
" dfir > gpar[5] :" << (dfir >
gpar[5]) <<
" zz >= gpar[4] :" << (zz >=
gpar[4])
296 <<
" zz <= gpar[4]+gpar[1] :" << (zz <=
gpar[4] +
gpar[1]);
298 if (
rInside(r) && r1 <=
exp(-p * zv) && r2 <= probMax * weight && dfir >
gpar[5] && zz >=
gpar[4] &&
299 zz <= gpar[4] + gpar[1] && r3 <= backProb && (depth != 2 || zz >=
gpar[4] +
gpar[0])) {
303 oneHit.
time = (tSlice + (
pe[
i].t()) + tdiff);
304 hit.push_back(oneHit);
307 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary: Final Hit " << nHit <<
" position " << (hit[nHit].position)
308 <<
" Depth " << (hit[nHit].depth) <<
" Time " << tSlice <<
":" <<
pe[
i].t() <<
":"
309 << tdiff <<
":" << (hit[nHit].time);
318 r1 = G4UniformRand();
319 r2 = G4UniformRand();
320 if (
rInside(r) && r1 <=
exp(-p * zv) && r2 <= probMax && dfir >
gpar[5]) {
324 oneHit.
time = (tSlice + (
pe[
i].t()) + tdiff);
325 hit.push_back(oneHit);
327 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary: Final Hit " << nHit <<
" position " << (hit[nHit].position)
328 <<
" Depth " << (hit[nHit].depth) <<
" Time " << tSlice <<
":" <<
pe[
i].t()
329 <<
":" << tdiff <<
":" << (hit[nHit].time);
338 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary: Total Hits " << nHit <<
" out of " << npe <<
" PE";
340 if (nHit > npe && !onlyLong) {
341 edm::LogWarning(
"HFShower") <<
"HFShowerLibrary: Hit buffer " << npe <<
" smaller than " << nHit <<
" Hits";
349 int nrc = record - 1;
359 std::vector<float>
t;
360 std::vector<float>*
tp = &
t;
363 unsigned int tSize = t.size() / 5;
364 photo->reserve(tSize);
365 for (
unsigned int i = 0;
i < tSize;
i++) {
367 HFShowerPhoton(t[
i], t[1 * tSize + i], t[2 * tSize + i], t[3 * tSize + i], t[4 * tSize + i]));
380 std::vector<float>
t;
381 std::vector<float>*
tp = &
t;
384 unsigned int tSize = t.size() / 5;
385 photo->reserve(tSize);
386 for (
unsigned int i = 0;
i < tSize;
i++) {
388 HFShowerPhoton(t[
i], t[1 * tSize + i], t[2 * tSize + i], t[3 * tSize + i], t[4 * tSize + i]));
398 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary::getRecord: Record " << record <<
" of type " << type <<
" with "
399 << nPhoton <<
" photons";
400 for (
int j = 0;
j < nPhoton;
j++)
410 std::vector<HFShowerLibraryEventInfo> eventInfoCollection;
411 branch->SetAddress(&eventInfoCollection);
413 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary::loadEventInfo loads EventInfo Collection of size "
414 << eventInfoCollection.size() <<
" records";
416 totEvents = eventInfoCollection[0].totalEvents();
417 nMomBin = eventInfoCollection[0].numberOfBins();
418 evtPerBin = eventInfoCollection[0].eventsPerBin();
419 libVers = eventInfoCollection[0].showerLibraryVersion();
420 listVersion = eventInfoCollection[0].physListVersion();
421 pmom = eventInfoCollection[0].energyBins();
423 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary::loadEventInfo loads EventInfo from hardwired"
431 pmom = {2, 3, 5, 7, 10, 15, 20, 30, 50, 75, 100, 150, 250, 350, 500, 1000};
434 pmom[
i] *= CLHEP::GeV;
439 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary:: Interpolate for Energy " << pin / CLHEP::GeV <<
" GeV with "
440 <<
nMomBin <<
" momentum bins and " <<
evtPerBin <<
" entries/bin -- total "
445 double r = G4UniformRand();
455 if (j == nMomBin - 2) {
464 edm::LogWarning(
"HFShower") <<
"HFShowerLibrary:: Illegal irc[0] = " << irc[0] <<
" now set to 0";
466 }
else if (irc[0] > totEvents) {
474 edm::LogWarning(
"HFShower") <<
"HFShowerLibrary:: Illegal irc[1] = " << irc[1] <<
" now set to 1";
476 }
else if (irc[1] > totEvents) {
482 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary:: Select records " << irc[0] <<
" and " << irc[1] <<
" with weights "
483 << 1 - w <<
" and " <<
w;
488 for (
int ir = 0; ir < 2; ir++) {
493 for (
int j = 0;
j < nPhoton;
j++) {
495 if ((ir == 0 && r > w) || (ir > 0 && r < w)) {
502 if ((
npe > npold || (npold == 0 && irc[0] > 0)) && !(
npe == 0 && npold == 0))
503 edm::LogWarning(
"HFShower") <<
"HFShowerLibrary: Interpolation Warning =="
504 <<
" records " << irc[0] <<
" and " << irc[1] <<
" gives a buffer of " << npold
505 <<
" photons and fills " <<
npe <<
" *****";
508 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary: Interpolation == records " << irc[0] <<
" and " << irc[1]
509 <<
" gives a buffer of " << npold <<
" photons and fills " << npe <<
" PE";
510 for (
int j = 0;
j <
npe;
j++)
520 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary:: Extrapolate for Energy " << pin / CLHEP::GeV <<
" GeV with "
522 <<
"total " <<
totEvents <<
" using " << nrec <<
" records";
524 std::vector<int> irc(nrec);
526 for (
int ir = 0; ir < nrec; ir++) {
527 double r = G4UniformRand();
530 edm::LogWarning(
"HFShower") <<
"HFShowerLibrary:: Illegal irc[" << ir <<
"] = " << irc[ir] <<
" now set to 1";
533 edm::LogWarning(
"HFShower") <<
"HFShowerLibrary:: Illegal irc[" << ir <<
"] = " << irc[ir] <<
" now set to "
538 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary::Extrapolation use irc[" << ir <<
"] = " << irc[ir];
546 for (
int ir = 0; ir < nrec; ir++) {
551 for (
int j = 0;
j < nPhoton;
j++) {
552 double r = G4UniformRand();
553 if (ir != nrec - 1 || r < w) {
558 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary: Record [" << ir <<
"] = " << irc[ir] <<
" npold = " << npold;
563 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary:: uses " << npold <<
" photons";
566 if (
npe > npold || npold == 0)
567 edm::LogWarning(
"HFShower") <<
"HFShowerLibrary: Extrapolation Warning == " << nrec <<
" records " << irc[0] <<
", "
568 << irc[1] <<
", ... gives a buffer of " << npold <<
" photons and fills " <<
npe
572 edm::LogVerbatim(
"HFShower") <<
"HFShowerLibrary: Extrapolation == " << nrec <<
" records " << irc[0] <<
", "
573 << irc[1] <<
", ... gives a buffer of " << npold <<
" photons and fills " << npe
575 for (
int j = 0;
j <
npe;
j++)
Log< level::Info, true > LogVerbatim
std::vector< Hit > getHits(const G4Step *aStep, bool &ok, double weight, bool onlyLong=false)
const HcalDDDSimConstants * hcalConstant_
std::unique_ptr< HFFibre > fibre_
Sin< T >::type sin(const T &t)
HFShowerPhotonCollection pe
Exp< T >::type exp(const T &t)
Log< level::Error, false > LogError
static bool isStableHadron(int pdgCode)
Cos< T >::type cos(const T &t)
void loadEventInfo(TBranch *)
Abs< T >::type abs(const T &t)
std::vector< double > gpar
std::vector< double > pmom
HFShowerLibrary(const std::string &name, const HcalDDDSimConstants *hcons, const HcalSimulationParameters *hps, edm::ParameterSet const &p)
T getParameter(std::string const &) const
void extrapolate(int, double)
std::unique_ptr< HFShowerPhotonCollection > photo
static int position[264][3]
static bool isGammaElectronPositron(int pdgCode)
std::vector< Hit > fillHits(const G4ThreeVector &p, const G4ThreeVector &v, int parCode, double parEnergy, bool &ok, double weight, double time, bool onlyLong=false)
Log< level::Warning, false > LogWarning
HFShowerPhotonCollection photon
void interpolate(int, double)