CMS 3D CMS Logo

HFShowerLibrary.cc
Go to the documentation of this file.
1 // File: HFShowerLibrary.cc
3 // Description: Shower library for Very forward hadron calorimeter
5 
9 
11 
12 #include "G4VPhysicalVolume.hh"
13 #include "G4NavigationHistory.hh"
14 #include "G4Step.hh"
15 #include "G4Track.hh"
16 #include "G4ParticleTable.hh"
17 #include "Randomize.hh"
18 #include <CLHEP/Units/SystemOfUnits.h>
19 #include <CLHEP/Units/PhysicalConstants.h>
20 
21 //#define EDM_ML_DEBUG
22 namespace {
23  HFShowerLibrary::Params paramsFrom(edm::ParameterSet const& hfShower,
24  edm::ParameterSet const& hfShowerLibrary,
25  double iDeltaPhi) {
27 
28  params.dphi_ = iDeltaPhi;
29 
30  params.probMax_ = hfShower.getParameter<double>("ProbMax");
31  params.equalizeTimeShift_ = hfShower.getParameter<bool>("EqualizeTimeShift");
32 
33  params.backProb_ = hfShowerLibrary.getParameter<double>("BackProbability");
34  params.verbose_ = hfShowerLibrary.getUntrackedParameter<bool>("Verbosity", false);
35  params.applyFidCut_ = hfShowerLibrary.getParameter<bool>("ApplyFiducialCut");
36 
37  return params;
38  }
39 
40  HFShowerLibrary::FileParams fileParamsFrom(edm::ParameterSet const& hfShowerLibrary) {
42 
43  edm::FileInPath fp = hfShowerLibrary.getParameter<edm::FileInPath>("FileName");
44  params.fileName_ = fp.fullPath();
45  if (params.fileName_.find('.') == 0)
46  params.fileName_.erase(0, 2);
47 
48  std::string emName = hfShowerLibrary.getParameter<std::string>("TreeEMID");
49  std::string hadName = hfShowerLibrary.getParameter<std::string>("TreeHadID");
50  std::string branchEvInfo = hfShowerLibrary.getUntrackedParameter<std::string>(
51  "BranchEvt", "HFShowerLibraryEventInfos_hfshowerlib_HFShowerLibraryEventInfo");
52  std::string branchPre =
53  hfShowerLibrary.getUntrackedParameter<std::string>("BranchPre", "HFShowerPhotons_hfshowerlib_");
54  std::string branchPost = hfShowerLibrary.getUntrackedParameter<std::string>("BranchPost", "_R.obj");
55  params.fileVersion_ = hfShowerLibrary.getParameter<int>("FileVersion");
56 
57  params.emBranchName_ = branchPre + emName + branchPost;
58  params.hadBranchName_ = branchPre + hadName + branchPost;
59 
60  if (not branchEvInfo.empty()) {
61  params.branchEvInfo_ = branchEvInfo + branchPost;
62  }
63 
64  params.cacheBranches_ = hfShowerLibrary.getUntrackedParameter<bool>("cacheBranches", false);
65  return params;
66  }
67 } // namespace
68 
70  const HcalSimulationParameters* hps,
71  edm::ParameterSet const& hfShower,
72  edm::ParameterSet const& hfShowerLibrary)
73  : HFShowerLibrary(paramsFrom(hfShower, hfShowerLibrary, hcons->getPhiTableHF().front()),
74  fileParamsFrom(hfShowerLibrary),
75  HFFibre::Params(hfShower.getParameter<double>("CFibre"), hcons, hps)) {}
76 
78  const HcalDDDSimConstants* hcons,
79  const HcalSimulationParameters* hps,
80  edm::ParameterSet const& p)
82  hcons,
83  hps,
84  p.getParameter<edm::ParameterSet>("HFShower").getParameter<edm::ParameterSet>("HFShowerBlock"),
85  p.getParameter<edm::ParameterSet>("HFShowerLibrary").getParameter<edm::ParameterSet>("HFLibraryFileBlock")) {}
86 
87 HFShowerLibrary::HFShowerLibrary(const Params& iParams, const FileParams& iFileParams, HFFibre::Params iFibreParams)
88  : fibre_(iFibreParams),
89  hf_(),
90  emBranch_(),
91  hadBranch_(),
92  verbose_(iParams.verbose_),
93  applyFidCut_(iParams.applyFidCut_),
94  equalizeTimeShift_(iParams.equalizeTimeShift_),
95  probMax_(iParams.probMax_),
96  backProb_(iParams.backProb_),
97  dphi_(iParams.dphi_),
98  rMin_(iFibreParams.rTableHF_.front()),
99  rMax_(iFibreParams.rTableHF_.back()),
100  gpar_(iFibreParams.gParHF_) {
101  std::string pTreeName = iFileParams.fileName_;
102 
103  const char* nTree = pTreeName.c_str();
104  {
105  //It is not safe to open a Tfile in one thread and close in another without adding the following:
106  TDirectory::TContext context;
107  hf_ = std::unique_ptr<TFile>(TFile::Open(nTree));
108  }
109  if (!hf_->IsOpen()) {
110  edm::LogError("HFShower") << "HFShowerLibrary: opening " << nTree << " failed";
111  throw cms::Exception("Unknown", "HFShowerLibrary") << "Opening of " << pTreeName << " fails\n";
112  } else {
113  edm::LogVerbatim("HFShower") << "HFShowerLibrary: opening " << nTree << " successfully";
114  }
115 
117  const int fileVersion = iFileParams.fileVersion_;
118 
119  auto newForm = iFileParams.branchEvInfo_.empty();
120  TTree* event(nullptr);
121  if (newForm) {
123  event = (TTree*)hf_->Get("HFSimHits");
124  } else {
125  event = (TTree*)hf_->Get("Events");
126  }
127  VersionInfo versionInfo;
128  if (event) {
129  TBranch* evtInfo(nullptr);
130  if (!newForm) {
131  std::string info = iFileParams.branchEvInfo_;
132  evtInfo = event->GetBranch(info.c_str());
133  }
134  if (evtInfo || newForm) {
135  versionInfo = loadEventInfo(evtInfo, fileVersion);
136  } else {
137  edm::LogError("HFShower") << "HFShowerLibrary: HFShowerLibrayEventInfo"
138  << " Branch does not exist in Event";
139  throw cms::Exception("Unknown", "HFShowerLibrary") << "Event information absent\n";
140  }
141  } else {
142  edm::LogError("HFShower") << "HFShowerLibrary: Events Tree does not "
143  << "exist";
144  throw cms::Exception("Unknown", "HFShowerLibrary") << "Events tree absent\n";
145  }
146 
147  edm::LogVerbatim("HFShower").log([&](auto& logger) {
148  logger << "HFShowerLibrary: Library " << versionInfo.libVers_ << " ListVersion " << versionInfo.listVersion_
149  << " File version " << fileVersion << " Events Total " << totEvents_ << " and " << evtPerBin_
150  << " per bin\n";
151  logger << "HFShowerLibrary: Energies (GeV) with " << nMomBin_ << " bins\n";
152  for (int i = 0; i < nMomBin_; ++i) {
153  if (i / 10 * 10 == i && i > 0) {
154  logger << "\n";
155  }
156  logger << " " << pmom_[i] / CLHEP::GeV;
157  }
158  });
159 
160  std::string nameBr = iFileParams.emBranchName_;
161  auto emBranch = event->GetBranch(nameBr.c_str());
162  if (verbose_)
163  emBranch->Print();
164  nameBr = iFileParams.hadBranchName_;
165  auto hadBranch = event->GetBranch(nameBr.c_str());
166  if (verbose_)
167  hadBranch->Print();
168 
169  if (emBranch->GetClassName() == std::string("vector<float>")) {
172  }
173  emBranch_ = BranchReader(emBranch, fileFormat, 0, iFileParams.cacheBranches_ ? totEvents_ : 0);
174  size_t offset = 0;
175  if ((fileFormat == FileFormat::kNewV3 && fileVersion < 3) || (fileFormat == FileFormat::kNew && fileVersion < 2)) {
176  //NOTE: for this format, the hadBranch is all empty up to
177  // totEvents_ (which is more like 1/2*GenEntries())
178  offset = totEvents_;
179  }
180  hadBranch_ = BranchReader(hadBranch, fileFormat, offset, iFileParams.cacheBranches_ ? totEvents_ : 0);
181 
182  edm::LogVerbatim("HFShower") << " HFShowerLibrary:Branch " << iFileParams.emBranchName_ << " has "
183  << emBranch->GetEntries() << " entries and Branch " << iFileParams.hadBranchName_
184  << " has " << hadBranch->GetEntries()
185  << " entries\n HFShowerLibrary::No packing information - Assume x, y, z are not in "
186  "packed form\n Maximum probability cut off "
187  << probMax_ << " Back propagation of light probability " << backProb_
188  << " Flag for equalizing Time Shift for different eta " << equalizeTimeShift_;
189 
190  edm::LogVerbatim("HFShower") << "HFShowerLibrary: rMIN " << rMin_ / CLHEP::cm << " cm and rMax " << rMax_ / CLHEP::cm
191  << " (Half) Phi Width of wedge " << dphi_ / CLHEP::deg;
192  if (iFileParams.cacheBranches_) {
193  hf_.reset();
194  }
195 }
196 
198  if (hf_)
199  hf_->Close();
200 }
201 
202 std::vector<HFShowerLibrary::Hit> HFShowerLibrary::getHits(const G4Step* aStep,
203  bool& isKilled,
204  double weight,
205  bool onlyLong) {
206  auto const preStepPoint = aStep->GetPreStepPoint();
207  auto const postStepPoint = aStep->GetPostStepPoint();
208  auto const track = aStep->GetTrack();
209  // Get Z-direction
210  auto const aParticle = track->GetDynamicParticle();
211  const G4ThreeVector& momDir = aParticle->GetMomentumDirection();
212  const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
213  int parCode = track->GetDefinition()->GetPDGEncoding();
214 
215  // VI: for ions use internally pdg code of alpha in order to keep
216  // consistency with previous simulation
217  if (track->GetDefinition()->IsGeneralIon()) {
218  parCode = 1000020040;
219  }
220 
221 #ifdef EDM_ML_DEBUG
222  G4String partType = track->GetDefinition()->GetParticleName();
223  const G4ThreeVector localPos = preStepPoint->GetTouchable()->GetHistory()->GetTopTransform().TransformPoint(hitPoint);
224  double zoff = localPos.z() + 0.5 * gpar_[1];
225 
226  edm::LogVerbatim("HFShower") << "HFShowerLibrary::getHits " << partType << " of energy "
227  << track->GetKineticEnergy() / CLHEP::GeV << " GeV weight= " << weight
228  << " onlyLong: " << onlyLong << " dir.orts " << momDir.x() << ", " << momDir.y() << ", "
229  << momDir.z() << " Pos x,y,z = " << hitPoint.x() << "," << hitPoint.y() << ","
230  << hitPoint.z() << " (" << zoff << ") sphi,cphi,stheta,ctheta = " << sin(momDir.phi())
231  << "," << cos(momDir.phi()) << ", " << sin(momDir.theta()) << "," << cos(momDir.theta());
232 #endif
233 
234  double tSlice = (postStepPoint->GetGlobalTime()) / CLHEP::nanosecond;
235 
236  // use kinetic energy for protons and ions
237  double pin = (track->GetDefinition()->GetBaryonNumber() > 0) ? preStepPoint->GetKineticEnergy()
238  : preStepPoint->GetTotalEnergy();
239 
240  return fillHits(hitPoint, momDir, parCode, pin, isKilled, weight, tSlice, onlyLong);
241 }
242 
243 std::vector<HFShowerLibrary::Hit> HFShowerLibrary::fillHits(const G4ThreeVector& hitPoint,
244  const G4ThreeVector& momDir,
245  int parCode,
246  double pin,
247  bool& ok,
248  double weight,
249  double tSlice,
250  bool onlyLong) {
251  std::vector<HFShowerLibrary::Hit> hit;
252  ok = false;
254  // shower is built only for gamma, e+- and stable hadrons
255  if (!isEM && !G4TrackToParticleID::isStableHadron(parCode)) {
256  return hit;
257  }
258  ok = true;
259 
260  // remove low-energy component
261  const double threshold = 50 * CLHEP::MeV;
262  if (pin < threshold) {
263  return hit;
264  }
265 
266  double pz = momDir.z();
267  double zint = hitPoint.z();
268 
269  // if particle moves from interaction point or "backwards (halo)
270  bool backward = (pz * zint < 0.) ? true : false;
271 
272  double sphi = sin(momDir.phi());
273  double cphi = cos(momDir.phi());
274  double ctheta = cos(momDir.theta());
275  double stheta = sin(momDir.theta());
276 
278  if (isEM) {
279  if (pin < pmom_[nMomBin_ - 1]) {
280  pe = interpolate(0, pin);
281  } else {
282  pe = extrapolate(0, pin);
283  }
284  } else {
285  if (pin < pmom_[nMomBin_ - 1]) {
286  pe = interpolate(1, pin);
287  } else {
288  pe = extrapolate(1, pin);
289  }
290  }
291 
292  std::size_t nHit = 0;
293  HFShowerLibrary::Hit oneHit;
294 #ifdef EDM_ML_DEBUG
295  int i = 0;
296 #endif
297  for (auto const& photon : pe) {
298  double zv = std::abs(photon.z()); // abs local z
299 #ifdef EDM_ML_DEBUG
300  edm::LogVerbatim("HFShower") << "HFShowerLibrary: Hit " << i++ << " " << photon << " zv " << zv;
301 #endif
302  if (zv <= gpar_[1] && photon.lambda() > 0 && (photon.z() >= 0 || (zv > gpar_[0] && (!onlyLong)))) {
303  int depth = 1;
304  if (onlyLong) {
305  } else if (!backward) { // fully valid only for "front" particles
306  if (photon.z() < 0)
307  depth = 2; // with "front"-simulated shower lib.
308  } else { // for "backward" particles - almost equal
309  double r = G4UniformRand(); // share between L and S fibers
310  if (r > 0.5)
311  depth = 2;
312  }
313 
314  // Updated coordinate transformation from local
315  // back to global using two Euler angles: phi and theta
316  double pex = photon.x();
317  double pey = photon.y();
318 
319  double xx = pex * ctheta * cphi - pey * sphi + zv * stheta * cphi;
320  double yy = pex * ctheta * sphi + pey * cphi + zv * stheta * sphi;
321  double zz = -pex * stheta + zv * ctheta;
322 
323  G4ThreeVector pos = hitPoint + G4ThreeVector(xx, yy, zz);
324  zv = std::abs(pos.z()) - gpar_[4] - 0.5 * gpar_[1];
325  G4ThreeVector lpos = G4ThreeVector(pos.x(), pos.y(), zv);
326 
327  zv = fibre_.zShift(lpos, depth, 0); // distance to PMT !
328 
329  double r = pos.perp();
330  double p = fibre_.attLength(photon.lambda());
331  double fi = pos.phi();
332  if (fi < 0)
333  fi += CLHEP::twopi;
334  int isect = int(fi / dphi_) + 1;
335  isect = (isect + 1) / 2;
336  double dfi = ((isect * 2 - 1) * dphi_ - fi);
337  if (dfi < 0)
338  dfi = -dfi;
339  double dfir = r * sin(dfi);
340 #ifdef EDM_ML_DEBUG
341  edm::LogVerbatim("HFShower") << "HFShowerLibrary: Position shift " << xx << ", " << yy << ", " << zz << ": "
342  << pos << " R " << r << " Phi " << fi << " Section " << isect << " R*Dfi " << dfir
343  << " Dist " << zv;
344 #endif
345  zz = std::abs(pos.z());
346  double r1 = G4UniformRand();
347  double r2 = G4UniformRand();
348  double r3 = backward ? G4UniformRand() : -9999.;
349  if (!applyFidCut_)
350  dfir += gpar_[5];
351 
352 #ifdef EDM_ML_DEBUG
353  edm::LogVerbatim("HFShower") << "HFShowerLibrary: rLimits " << rInside(r) << " attenuation " << r1 << ":"
354  << exp(-p * zv) << " r2 " << r2 << " r3 " << r3 << " rDfi " << gpar_[5] << " zz "
355  << zz << " zLim " << gpar_[4] << ":" << gpar_[4] + gpar_[1] << "\n"
356  << " rInside(r) :" << rInside(r) << " r1 <= exp(-p*zv) :" << (r1 <= exp(-p * zv))
357  << " r2 <= probMax :" << (r2 <= probMax_ * weight)
358  << " r3 <= backProb :" << (r3 <= backProb_)
359  << " dfir > gpar[5] :" << (dfir > gpar_[5])
360  << " zz >= gpar[4] :" << (zz >= gpar_[4])
361  << " zz <= gpar[4]+gpar[1] :" << (zz <= gpar_[4] + gpar_[1]);
362 #endif
363  if (rInside(r) && r1 <= exp(-p * zv) && r2 <= probMax_ * weight && dfir > gpar_[5] && zz >= gpar_[4] &&
364  zz <= gpar_[4] + gpar_[1] && r3 <= backProb_ && (depth != 2 || zz >= gpar_[4] + gpar_[0])) {
365  double tdiff = (equalizeTimeShift_) ? (fibre_.tShift(lpos, depth, -1)) : (fibre_.tShift(lpos, depth, 1));
366  oneHit.position = pos;
367  oneHit.depth = depth;
368  oneHit.time = (tSlice + (photon.t()) + tdiff);
369  hit.push_back(oneHit);
370 
371 #ifdef EDM_ML_DEBUG
372  edm::LogVerbatim("HFShower") << "HFShowerLibrary: Final Hit " << nHit << " position " << (hit[nHit].position)
373  << " Depth " << (hit[nHit].depth) << " Time " << tSlice << ":" << photon.t() << ":"
374  << tdiff << ":" << (hit[nHit].time);
375 #endif
376  ++nHit;
377  }
378 #ifdef EDM_ML_DEBUG
379  else
380  edm::LogVerbatim("HFShower") << "HFShowerLibrary: REJECTED !!!";
381 #endif
382  if (onlyLong && zz >= gpar_[4] + gpar_[0] && zz <= gpar_[4] + gpar_[1]) {
383  r1 = G4UniformRand();
384  r2 = G4UniformRand();
385  if (rInside(r) && r1 <= exp(-p * zv) && r2 <= probMax_ && dfir > gpar_[5]) {
386  double tdiff = (equalizeTimeShift_) ? (fibre_.tShift(lpos, 2, -1)) : (fibre_.tShift(lpos, 2, 1));
387  oneHit.position = pos;
388  oneHit.depth = 2;
389  oneHit.time = (tSlice + (photon.t()) + tdiff);
390  hit.push_back(oneHit);
391 #ifdef EDM_ML_DEBUG
392  edm::LogVerbatim("HFShower") << "HFShowerLibrary: Final Hit " << nHit << " position " << (hit[nHit].position)
393  << " Depth " << (hit[nHit].depth) << " Time " << tSlice << ":" << photon.t()
394  << ":" << tdiff << ":" << (hit[nHit].time);
395 #endif
396  ++nHit;
397  }
398  }
399  }
400  }
401 
402 #ifdef EDM_ML_DEBUG
403  edm::LogVerbatim("HFShower") << "HFShowerLibrary: Total Hits " << nHit << " out of " << pe.size() << " PE";
404 #endif
405  if (nHit > pe.size() && !onlyLong) {
406  edm::LogWarning("HFShower") << "HFShowerLibrary: Hit buffer " << pe.size() << " smaller than " << nHit << " Hits";
407  }
408  return hit;
409 }
410 
411 bool HFShowerLibrary::rInside(double r) const { return (r >= rMin_ && r <= rMax_); }
412 
414  auto nRecords = iReader.numberOfRecords();
415  if (nRecords > maxRecordsToCache) {
416  nRecords = maxRecordsToCache;
417  }
418  offsets_.reserve(nRecords + 1);
419 
420  //first pass is to figure out how much space will be needed
421  size_t nPhotons = 0;
422  for (size_t r = 0; r < nRecords; ++r) {
423  auto shower = iReader.getRecord(r + 1);
424  nPhotons += shower.size();
425  }
426 
427  photons_.reserve(nPhotons);
428 
429  size_t offset = 0;
430  for (size_t r = 0; r < nRecords; ++r) {
431  offsets_.emplace_back(offset);
432  auto shower = iReader.getRecord(r + 1);
433  offset += shower.size();
434  std::copy(shower.begin(), shower.end(), std::back_inserter(photons_));
435  }
436  offsets_.emplace_back(offset);
437  photons_.shrink_to_fit();
438 }
439 
440 void HFShowerLibrary::BranchReader::doCaching(size_t maxRecordsToCache) {
441  cache_ = makeCache(*this, maxRecordsToCache, branch_->GetDirectory()->GetFile()->GetName(), branch_->GetName());
442 }
443 
444 std::shared_ptr<HFShowerLibrary::BranchCache const> HFShowerLibrary::BranchReader::makeCache(
445  BranchReader& iReader, size_t maxRecordsToCache, std::string const& iFileName, std::string const& iBranchName) {
446  //This allows sharing of the same cached data across the different modules (e.g. the per stream instances of OscarMTProducer
448  std::lock_guard<std::mutex> guard(s_mutex);
449  CMS_SA_ALLOW static std::map<std::pair<std::string, std::string>, std::weak_ptr<BranchCache>> s_map;
450  auto v = s_map[{iFileName, iBranchName}].lock();
451  if (v) {
452  return v;
453  }
454  v = std::make_shared<BranchCache>(iReader, maxRecordsToCache);
455  s_map[{iFileName, iBranchName}] = v;
456  return v;
457 }
458 
460  assert(iRecord > 0);
461  assert(static_cast<size_t>(iRecord + 1) < offsets_.size());
462 
463  auto start = offsets_[iRecord - 1];
464  auto end = offsets_[iRecord];
465 
466  return HFShowerPhotonCollection(photons_.begin() + start, photons_.begin() + end);
467 }
468 
471  iBranch->SetAddress(&photo);
472  iBranch->GetEntry(iEntry);
473  return photo;
474 }
477 
478  auto temp = std::make_unique<HFShowerPhotonCollection>();
479  iBranch->SetAddress(&temp);
480  iBranch->GetEntry(iEntry);
481  photo = std::move(*temp);
482 
483  return photo;
484 }
487 
488  std::vector<float> t;
489  std::vector<float>* tp = &t;
490  iBranch->SetAddress(&tp);
491  iBranch->GetEntry(iEntry);
492  unsigned int tSize = t.size() / 5;
493  photo.reserve(tSize);
494  for (unsigned int i = 0; i < tSize; i++) {
495  photo.emplace_back(t[i], t[1 * tSize + i], t[2 * tSize + i], t[3 * tSize + i], t[4 * tSize + i]);
496  }
497 
498  return photo;
499 }
500 
502  if (cache_) {
503  return cache_->getRecord(record);
504  }
505  int nrc = record - 1;
507 
508  switch (format_) {
509  case FileFormat::kNew: {
510  photo = getRecordNewForm(branch_, nrc + offset_);
511  break;
512  }
513  case FileFormat::kNewV3: {
514  photo = getRecordNewFormV3(branch_, nrc + offset_);
515  break;
516  }
517  case FileFormat::kOld: {
518  photo = getRecordOldForm(branch_, nrc);
519  break;
520  }
521  }
522  return photo;
523 }
524 
525 size_t HFShowerLibrary::BranchReader::numberOfRecords() const { return branch_->GetEntries() - offset_; }
526 
529  if (type > 0) {
530  photo = hadBranch_.getRecord(record);
531  } else {
532  photo = emBranch_.getRecord(record);
533  }
534 #ifdef EDM_ML_DEBUG
535  int nPhoton = photo.size();
536  edm::LogVerbatim("HFShower") << "HFShowerLibrary::getRecord: Record " << record << " of type " << type << " with "
537  << nPhoton << " photons";
538  for (int j = 0; j < nPhoton; j++)
539  edm::LogVerbatim("HFShower") << "Photon " << j << " " << photo[j];
540 #endif
541  return photo;
542 }
543 
545  VersionInfo versionInfo;
546  if (branch) {
547  std::vector<HFShowerLibraryEventInfo> eventInfoCollection;
548  branch->SetAddress(&eventInfoCollection);
549  branch->GetEntry(0);
550  edm::LogVerbatim("HFShower") << "HFShowerLibrary::loadEventInfo loads EventInfo Collection of size "
551  << eventInfoCollection.size() << " records";
552 
553  totEvents_ = eventInfoCollection[0].totalEvents();
554  nMomBin_ = eventInfoCollection[0].numberOfBins();
555  evtPerBin_ = eventInfoCollection[0].eventsPerBin();
556  versionInfo.libVers_ = eventInfoCollection[0].showerLibraryVersion();
557  versionInfo.listVersion_ = eventInfoCollection[0].physListVersion();
558  pmom_ = eventInfoCollection[0].energyBins();
559  } else {
560  edm::LogVerbatim("HFShower") << "HFShowerLibrary::loadEventInfo loads EventInfo from hardwired"
561  << " numbers";
562 
563  nMomBin_ = 16;
564  evtPerBin_ = (fileVersion == 0) ? 5000 : 10000;
566  versionInfo.libVers_ = (fileVersion == 0) ? 1.1 : 1.2;
567  versionInfo.listVersion_ = 3.6;
568  pmom_ = {2, 3, 5, 7, 10, 15, 20, 30, 50, 75, 100, 150, 250, 350, 500, 1000};
569  }
570  for (int i = 0; i < nMomBin_; i++)
571  pmom_[i] *= CLHEP::GeV;
572  return versionInfo;
573 }
574 
576 #ifdef EDM_ML_DEBUG
577  edm::LogVerbatim("HFShower") << "HFShowerLibrary:: Interpolate for Energy " << pin / CLHEP::GeV << " GeV with "
578  << nMomBin_ << " momentum bins and " << evtPerBin_ << " entries/bin -- total "
579  << totEvents_;
580 #endif
581  int irc[2] = {0, 0};
582  double w = 0.;
583  double r = G4UniformRand();
584 
585  if (pin < pmom_[0]) {
586  w = pin / pmom_[0];
587  irc[1] = int(evtPerBin_ * r) + 1;
588  irc[0] = 0;
589  } else {
590  for (int j = 0; j < nMomBin_ - 1; j++) {
591  if (pin >= pmom_[j] && pin < pmom_[j + 1]) {
592  w = (pin - pmom_[j]) / (pmom_[j + 1] - pmom_[j]);
593  if (j == nMomBin_ - 2) {
594  irc[1] = int(evtPerBin_ * 0.5 * r);
595  } else {
596  irc[1] = int(evtPerBin_ * r);
597  }
598  irc[1] += (j + 1) * evtPerBin_ + 1;
599  r = G4UniformRand();
600  irc[0] = int(evtPerBin_ * r) + 1 + j * evtPerBin_;
601  if (irc[0] < 0) {
602  edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[0] = " << irc[0] << " now set to 0";
603  irc[0] = 0;
604  } else if (irc[0] > totEvents_) {
605  edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[0] = " << irc[0] << " now set to "
606  << totEvents_;
607  irc[0] = totEvents_;
608  }
609  }
610  }
611  }
612  if (irc[1] < 1) {
613  edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[1] = " << irc[1] << " now set to 1";
614  irc[1] = 1;
615  } else if (irc[1] > totEvents_) {
616  edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[1] = " << irc[1] << " now set to " << totEvents_;
617  irc[1] = totEvents_;
618  }
619 
620 #ifdef EDM_ML_DEBUG
621  edm::LogVerbatim("HFShower") << "HFShowerLibrary:: Select records " << irc[0] << " and " << irc[1] << " with weights "
622  << 1 - w << " and " << w;
623 #endif
625 
626  std::size_t npold = 0;
627  for (int ir = 0; ir < 2; ir++) {
628  if (irc[ir] > 0) {
629  auto photons = getRecord(type, irc[ir]);
630  int nPhoton = photons.size();
631  npold += nPhoton;
632  pe.reserve(pe.size() + nPhoton);
633  for (auto const& photon : photons) {
634  r = G4UniformRand();
635  if ((ir == 0 && r > w) || (ir > 0 && r < w)) {
636  storePhoton(photon, pe);
637  }
638  }
639  }
640  }
641 
642  if ((pe.size() > npold || (npold == 0 && irc[0] > 0)) && !(pe.empty() && npold == 0))
643  edm::LogWarning("HFShower") << "HFShowerLibrary: Interpolation Warning =="
644  << " records " << irc[0] << " and " << irc[1] << " gives a buffer of " << npold
645  << " photons and fills " << pe.size() << " *****";
646 #ifdef EDM_ML_DEBUG
647  else
648  edm::LogVerbatim("HFShower") << "HFShowerLibrary: Interpolation == records " << irc[0] << " and " << irc[1]
649  << " gives a buffer of " << npold << " photons and fills " << pe.size() << " PE";
650  for (std::size_t j = 0; j < pe.size(); j++)
651  edm::LogVerbatim("HFShower") << "Photon " << j << " " << pe[j];
652 #endif
653  return pe;
654 }
655 
657  int nrec = int(pin / pmom_[nMomBin_ - 1]);
658  double w = (pin - pmom_[nMomBin_ - 1] * nrec) / pmom_[nMomBin_ - 1];
659  nrec++;
660 #ifdef EDM_ML_DEBUG
661  edm::LogVerbatim("HFShower") << "HFShowerLibrary:: Extrapolate for Energy " << pin / CLHEP::GeV << " GeV with "
662  << nMomBin_ << " momentum bins and " << evtPerBin_ << " entries/bin -- "
663  << "total " << totEvents_ << " using " << nrec << " records";
664 #endif
665  std::vector<int> irc(nrec);
666 
667  for (int ir = 0; ir < nrec; ir++) {
668  double r = G4UniformRand();
669  irc[ir] = int(evtPerBin_ * 0.5 * r) + (nMomBin_ - 1) * evtPerBin_ + 1;
670  if (irc[ir] < 1) {
671  edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[" << ir << "] = " << irc[ir] << " now set to 1";
672  irc[ir] = 1;
673  } else if (irc[ir] > totEvents_) {
674  edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[" << ir << "] = " << irc[ir] << " now set to "
675  << totEvents_;
676  irc[ir] = totEvents_;
677 #ifdef EDM_ML_DEBUG
678  } else {
679  edm::LogVerbatim("HFShower") << "HFShowerLibrary::Extrapolation use irc[" << ir << "] = " << irc[ir];
680 #endif
681  }
682  }
683 
685  std::size_t npold = 0;
686  for (int ir = 0; ir < nrec; ir++) {
687  if (irc[ir] > 0) {
688  auto const photons = getRecord(type, irc[ir]);
689  int nPhoton = photons.size();
690  npold += nPhoton;
691  pe.reserve(pe.size() + nPhoton);
692  for (auto const& photon : photons) {
693  double r = G4UniformRand();
694  if (ir != nrec - 1 || r < w) {
695  storePhoton(photon, pe);
696  }
697  }
698 #ifdef EDM_ML_DEBUG
699  edm::LogVerbatim("HFShower") << "HFShowerLibrary: Record [" << ir << "] = " << irc[ir] << " npold = " << npold;
700 #endif
701  }
702  }
703 #ifdef EDM_ML_DEBUG
704  edm::LogVerbatim("HFShower") << "HFShowerLibrary:: uses " << npold << " photons";
705 #endif
706 
707  if (pe.size() > npold || npold == 0)
708  edm::LogWarning("HFShower") << "HFShowerLibrary: Extrapolation Warning == " << nrec << " records " << irc[0] << ", "
709  << irc[1] << ", ... gives a buffer of " << npold << " photons and fills " << pe.size()
710  << " *****";
711 #ifdef EDM_ML_DEBUG
712  else
713  edm::LogVerbatim("HFShower") << "HFShowerLibrary: Extrapolation == " << nrec << " records " << irc[0] << ", "
714  << irc[1] << ", ... gives a buffer of " << npold << " photons and fills " << pe.size()
715  << " PE";
716  for (std::size_t j = 0; j < pe.size(); j++)
717  edm::LogVerbatim("HFShower") << "Photon " << j << " " << pe[j];
718 #endif
719  return pe;
720 }
721 
723  iPhotons.push_back(iPhoton);
724 #ifdef EDM_ML_DEBUG
725  edm::LogVerbatim("HFShower") << "HFShowerLibrary: storePhoton " << iPhoton << " npe " << iPhotons.size() << " "
726  << iPhotons.back();
727 #endif
728 }
Definition: start.py:1
Log< level::Info, true > LogVerbatim
static HFShowerPhotonCollection getRecordOldForm(TBranch *, int iEntry)
BranchCache(BranchReader &, size_t maxRecordsToCache)
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
std::vector< Hit > getHits(const G4Step *aStep, bool &ok, double weight, bool onlyLong=false)
static const TGPicture * info(bool iBackgroundIsBlack)
#define CMS_SA_ALLOW
static std::recursive_mutex s_mutex
Definition: DQMService.cc:14
double zShift(const G4ThreeVector &point, int depth, int fromEndAbs=0) const
Definition: HFFibre.cc:125
T w() const
void storePhoton(HFShowerPhoton const &iPhoton, HFShowerPhotonCollection &iPhotons) const
HFShowerPhotonCollection getRecord(int, int) const
std::size_t numberOfRecords() const
static std::mutex mutex
Definition: Proxy.cc:8
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Definition: weight.py:1
HFShowerPhotonCollection extrapolate(int, double)
Log< level::Error, false > LogError
std::vector< double > gpar_
void doCaching(size_t maxRecords)
assert(be >=bs)
static bool isStableHadron(int pdgCode)
BranchReader hadBranch_
T getUntrackedParameter(std::string const &, T const &) const
std::unique_ptr< TFile > hf_
VersionInfo loadEventInfo(TBranch *, int fileVersion)
std::vector< HFShowerPhoton > HFShowerPhotonCollection
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
HFShowerPhotonCollection interpolate(int, double)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double tShift(const G4ThreeVector &point, int depth, int fromEndAbs=0) const
Definition: HFFibre.cc:114
Definition: logger.py:1
static std::shared_ptr< BranchCache const > makeCache(BranchReader &, size_t maxRecordsToCache, std::string const &iFileName, std::string const &iBranchName)
std::vector< double > pmom_
G4ThreeVector position
HFShowerPhotonCollection getRecord(int) const
HFShowerLibrary(const std::string &name, const HcalDDDSimConstants *hcons, const HcalSimulationParameters *hps, edm::ParameterSet const &p)
BranchReader emBranch_
static HFShowerPhotonCollection getRecordNewForm(TBranch *, int iEntry)
std::vector< std::size_t > offsets_
static HFShowerPhotonCollection getRecordNewFormV3(TBranch *, int iEntry)
HLT enums.
HFShowerPhotonCollection photons_
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
bool rInside(double r) const
def move(src, dest)
Definition: eostools.py:511
HFShowerPhotonCollection getRecord(int) const
Definition: event.py:1
double attLength(double lambda) const
Definition: HFFibre.cc:98