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 or (fileFormat == FileFormat::kNew and 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 * 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:15
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
float *__restrict__ zv
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
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< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
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