File indexing completed on 2024-05-10 02:21:17
0001
0002
0003
0004
0005
0006 #include "SimG4CMS/Calo/interface/HFShowerLibrary.h"
0007 #include "SimDataFormats/CaloHit/interface/HFShowerLibraryEventInfo.h"
0008 #include "SimG4Core/Notification/interface/G4TrackToParticleID.h"
0009
0010 #include "FWCore/Utilities/interface/Exception.h"
0011
0012 #include "G4VPhysicalVolume.hh"
0013 #include "G4NavigationHistory.hh"
0014 #include "G4Step.hh"
0015 #include "G4Track.hh"
0016 #include "G4ParticleTable.hh"
0017 #include "Randomize.hh"
0018 #include <CLHEP/Units/SystemOfUnits.h>
0019 #include <CLHEP/Units/PhysicalConstants.h>
0020
0021
0022 namespace {
0023 HFShowerLibrary::Params paramsFrom(edm::ParameterSet const& hfShower,
0024 edm::ParameterSet const& hfShowerLibrary,
0025 double iDeltaPhi) {
0026 HFShowerLibrary::Params params;
0027
0028 params.dphi_ = iDeltaPhi;
0029
0030 params.probMax_ = hfShower.getParameter<double>("ProbMax");
0031 params.equalizeTimeShift_ = hfShower.getParameter<bool>("EqualizeTimeShift");
0032
0033 params.backProb_ = hfShowerLibrary.getParameter<double>("BackProbability");
0034 params.verbose_ = hfShowerLibrary.getUntrackedParameter<bool>("Verbosity", false);
0035 params.applyFidCut_ = hfShowerLibrary.getParameter<bool>("ApplyFiducialCut");
0036
0037 return params;
0038 }
0039
0040 HFShowerLibrary::FileParams fileParamsFrom(edm::ParameterSet const& hfShowerLibrary) {
0041 HFShowerLibrary::FileParams params;
0042
0043 edm::FileInPath fp = hfShowerLibrary.getParameter<edm::FileInPath>("FileName");
0044 params.fileName_ = fp.fullPath();
0045 if (params.fileName_.find('.') == 0)
0046 params.fileName_.erase(0, 2);
0047
0048 std::string emName = hfShowerLibrary.getParameter<std::string>("TreeEMID");
0049 std::string hadName = hfShowerLibrary.getParameter<std::string>("TreeHadID");
0050 std::string branchEvInfo = hfShowerLibrary.getUntrackedParameter<std::string>(
0051 "BranchEvt", "HFShowerLibraryEventInfos_hfshowerlib_HFShowerLibraryEventInfo");
0052 std::string branchPre =
0053 hfShowerLibrary.getUntrackedParameter<std::string>("BranchPre", "HFShowerPhotons_hfshowerlib_");
0054 std::string branchPost = hfShowerLibrary.getUntrackedParameter<std::string>("BranchPost", "_R.obj");
0055 params.fileVersion_ = hfShowerLibrary.getParameter<int>("FileVersion");
0056
0057 params.emBranchName_ = branchPre + emName + branchPost;
0058 params.hadBranchName_ = branchPre + hadName + branchPost;
0059
0060 if (not branchEvInfo.empty()) {
0061 params.branchEvInfo_ = branchEvInfo + branchPost;
0062 }
0063
0064 params.cacheBranches_ = hfShowerLibrary.getUntrackedParameter<bool>("cacheBranches", false);
0065 return params;
0066 }
0067 }
0068
0069 HFShowerLibrary::HFShowerLibrary(const HcalDDDSimConstants* hcons,
0070 const HcalSimulationParameters* hps,
0071 edm::ParameterSet const& hfShower,
0072 edm::ParameterSet const& hfShowerLibrary)
0073 : HFShowerLibrary(paramsFrom(hfShower, hfShowerLibrary, hcons->getPhiTableHF().front()),
0074 fileParamsFrom(hfShowerLibrary),
0075 HFFibre::Params(hfShower.getParameter<double>("CFibre"), hcons, hps)) {}
0076
0077 HFShowerLibrary::HFShowerLibrary(const std::string& name,
0078 const HcalDDDSimConstants* hcons,
0079 const HcalSimulationParameters* hps,
0080 edm::ParameterSet const& p)
0081 : HFShowerLibrary(
0082 hcons,
0083 hps,
0084 p.getParameter<edm::ParameterSet>("HFShower").getParameter<edm::ParameterSet>("HFShowerBlock"),
0085 p.getParameter<edm::ParameterSet>("HFShowerLibrary").getParameter<edm::ParameterSet>("HFLibraryFileBlock")) {}
0086
0087 HFShowerLibrary::HFShowerLibrary(const Params& iParams, const FileParams& iFileParams, HFFibre::Params iFibreParams)
0088 : fibre_(iFibreParams),
0089 hf_(),
0090 emBranch_(),
0091 hadBranch_(),
0092 verbose_(iParams.verbose_),
0093 applyFidCut_(iParams.applyFidCut_),
0094 equalizeTimeShift_(iParams.equalizeTimeShift_),
0095 probMax_(iParams.probMax_),
0096 backProb_(iParams.backProb_),
0097 dphi_(iParams.dphi_),
0098 rMin_(iFibreParams.rTableHF_.front()),
0099 rMax_(iFibreParams.rTableHF_.back()),
0100 gpar_(iFibreParams.gParHF_) {
0101 std::string pTreeName = iFileParams.fileName_;
0102
0103 const char* nTree = pTreeName.c_str();
0104 {
0105
0106 TDirectory::TContext context;
0107 hf_ = std::unique_ptr<TFile>(TFile::Open(nTree));
0108 }
0109 if (!hf_->IsOpen()) {
0110 edm::LogError("HFShower") << "HFShowerLibrary: opening " << nTree << " failed";
0111 throw cms::Exception("Unknown", "HFShowerLibrary") << "Opening of " << pTreeName << " fails\n";
0112 } else {
0113 edm::LogVerbatim("HFShower") << "HFShowerLibrary: opening " << nTree << " successfully";
0114 }
0115
0116 auto fileFormat = FileFormat::kOld;
0117 const int fileVersion = iFileParams.fileVersion_;
0118
0119 auto newForm = iFileParams.branchEvInfo_.empty();
0120 TTree* event(nullptr);
0121 if (newForm) {
0122 fileFormat = FileFormat::kNew;
0123 event = (TTree*)hf_->Get("HFSimHits");
0124 } else {
0125 event = (TTree*)hf_->Get("Events");
0126 }
0127 VersionInfo versionInfo;
0128 if (event) {
0129 TBranch* evtInfo(nullptr);
0130 if (!newForm) {
0131 std::string info = iFileParams.branchEvInfo_;
0132 evtInfo = event->GetBranch(info.c_str());
0133 }
0134 if (evtInfo || newForm) {
0135 versionInfo = loadEventInfo(evtInfo, fileVersion);
0136 } else {
0137 edm::LogError("HFShower") << "HFShowerLibrary: HFShowerLibrayEventInfo"
0138 << " Branch does not exist in Event";
0139 throw cms::Exception("Unknown", "HFShowerLibrary") << "Event information absent\n";
0140 }
0141 } else {
0142 edm::LogError("HFShower") << "HFShowerLibrary: Events Tree does not "
0143 << "exist";
0144 throw cms::Exception("Unknown", "HFShowerLibrary") << "Events tree absent\n";
0145 }
0146
0147 edm::LogVerbatim("HFShower").log([&](auto& logger) {
0148 logger << "HFShowerLibrary: Library " << versionInfo.libVers_ << " ListVersion " << versionInfo.listVersion_
0149 << " File version " << fileVersion << " Events Total " << totEvents_ << " and " << evtPerBin_
0150 << " per bin\n";
0151 logger << "HFShowerLibrary: Energies (GeV) with " << nMomBin_ << " bins\n";
0152 for (int i = 0; i < nMomBin_; ++i) {
0153 if (i / 10 * 10 == i && i > 0) {
0154 logger << "\n";
0155 }
0156 logger << " " << pmom_[i] / CLHEP::GeV;
0157 }
0158 });
0159
0160 std::string nameBr = iFileParams.emBranchName_;
0161 auto emBranch = event->GetBranch(nameBr.c_str());
0162 if (verbose_)
0163 emBranch->Print();
0164 nameBr = iFileParams.hadBranchName_;
0165 auto hadBranch = event->GetBranch(nameBr.c_str());
0166 if (verbose_)
0167 hadBranch->Print();
0168
0169 if (emBranch->GetClassName() == std::string("vector<float>")) {
0170 assert(fileFormat == FileFormat::kNew);
0171 fileFormat = FileFormat::kNewV3;
0172 }
0173 emBranch_ = BranchReader(emBranch, fileFormat, 0, iFileParams.cacheBranches_ ? totEvents_ : 0);
0174 size_t offset = 0;
0175 if ((fileFormat == FileFormat::kNewV3 && fileVersion < 3) || (fileFormat == FileFormat::kNew && fileVersion < 2)) {
0176
0177
0178 offset = totEvents_;
0179 }
0180 hadBranch_ = BranchReader(hadBranch, fileFormat, offset, iFileParams.cacheBranches_ ? totEvents_ : 0);
0181
0182 edm::LogVerbatim("HFShower") << " HFShowerLibrary:Branch " << iFileParams.emBranchName_ << " has "
0183 << emBranch->GetEntries() << " entries and Branch " << iFileParams.hadBranchName_
0184 << " has " << hadBranch->GetEntries()
0185 << " entries\n HFShowerLibrary::No packing information - Assume x, y, z are not in "
0186 "packed form\n Maximum probability cut off "
0187 << probMax_ << " Back propagation of light probability " << backProb_
0188 << " Flag for equalizing Time Shift for different eta " << equalizeTimeShift_;
0189
0190 edm::LogVerbatim("HFShower") << "HFShowerLibrary: rMIN " << rMin_ / CLHEP::cm << " cm and rMax " << rMax_ / CLHEP::cm
0191 << " (Half) Phi Width of wedge " << dphi_ / CLHEP::deg;
0192 if (iFileParams.cacheBranches_) {
0193 hf_.reset();
0194 }
0195 }
0196
0197 HFShowerLibrary::~HFShowerLibrary() {
0198 if (hf_)
0199 hf_->Close();
0200 }
0201
0202 std::vector<HFShowerLibrary::Hit> HFShowerLibrary::getHits(const G4Step* aStep,
0203 bool& isKilled,
0204 double weight,
0205 bool onlyLong) {
0206 auto const preStepPoint = aStep->GetPreStepPoint();
0207 auto const postStepPoint = aStep->GetPostStepPoint();
0208 auto const track = aStep->GetTrack();
0209
0210 auto const aParticle = track->GetDynamicParticle();
0211 const G4ThreeVector& momDir = aParticle->GetMomentumDirection();
0212 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
0213 int parCode = track->GetDefinition()->GetPDGEncoding();
0214
0215
0216
0217 if (track->GetDefinition()->IsGeneralIon()) {
0218 parCode = 1000020040;
0219 }
0220
0221 #ifdef EDM_ML_DEBUG
0222 G4String partType = track->GetDefinition()->GetParticleName();
0223 const G4ThreeVector localPos = preStepPoint->GetTouchable()->GetHistory()->GetTopTransform().TransformPoint(hitPoint);
0224 double zoff = localPos.z() + 0.5 * gpar_[1];
0225
0226 edm::LogVerbatim("HFShower") << "HFShowerLibrary::getHits " << partType << " of energy "
0227 << track->GetKineticEnergy() / CLHEP::GeV << " GeV weight= " << weight
0228 << " onlyLong: " << onlyLong << " dir.orts " << momDir.x() << ", " << momDir.y() << ", "
0229 << momDir.z() << " Pos x,y,z = " << hitPoint.x() << "," << hitPoint.y() << ","
0230 << hitPoint.z() << " (" << zoff << ") sphi,cphi,stheta,ctheta = " << sin(momDir.phi())
0231 << "," << cos(momDir.phi()) << ", " << sin(momDir.theta()) << "," << cos(momDir.theta());
0232 #endif
0233
0234 double tSlice = (postStepPoint->GetGlobalTime()) / CLHEP::nanosecond;
0235
0236
0237 double pin = (track->GetDefinition()->GetBaryonNumber() > 0) ? preStepPoint->GetKineticEnergy()
0238 : preStepPoint->GetTotalEnergy();
0239
0240 return fillHits(hitPoint, momDir, parCode, pin, isKilled, weight, tSlice, onlyLong);
0241 }
0242
0243 std::vector<HFShowerLibrary::Hit> HFShowerLibrary::fillHits(const G4ThreeVector& hitPoint,
0244 const G4ThreeVector& momDir,
0245 int parCode,
0246 double pin,
0247 bool& ok,
0248 double weight,
0249 double tSlice,
0250 bool onlyLong) {
0251 std::vector<HFShowerLibrary::Hit> hit;
0252 ok = false;
0253 bool isEM = G4TrackToParticleID::isGammaElectronPositron(parCode);
0254
0255 if (!isEM && !G4TrackToParticleID::isStableHadron(parCode)) {
0256 return hit;
0257 }
0258 ok = true;
0259
0260
0261 const double threshold = 50 * CLHEP::MeV;
0262 if (pin < threshold) {
0263 return hit;
0264 }
0265
0266 double pz = momDir.z();
0267 double zint = hitPoint.z();
0268
0269
0270 bool backward = (pz * zint < 0.) ? true : false;
0271
0272 double sphi = sin(momDir.phi());
0273 double cphi = cos(momDir.phi());
0274 double ctheta = cos(momDir.theta());
0275 double stheta = sin(momDir.theta());
0276
0277 HFShowerPhotonCollection pe;
0278 if (isEM) {
0279 if (pin < pmom_[nMomBin_ - 1]) {
0280 pe = interpolate(0, pin);
0281 } else {
0282 pe = extrapolate(0, pin);
0283 }
0284 } else {
0285 if (pin < pmom_[nMomBin_ - 1]) {
0286 pe = interpolate(1, pin);
0287 } else {
0288 pe = extrapolate(1, pin);
0289 }
0290 }
0291
0292 std::size_t nHit = 0;
0293 HFShowerLibrary::Hit oneHit;
0294 #ifdef EDM_ML_DEBUG
0295 int i = 0;
0296 #endif
0297 for (auto const& photon : pe) {
0298 double zv = std::abs(photon.z());
0299 #ifdef EDM_ML_DEBUG
0300 edm::LogVerbatim("HFShower") << "HFShowerLibrary: Hit " << i++ << " " << photon << " zv " << zv;
0301 #endif
0302 if (zv <= gpar_[1] && photon.lambda() > 0 && (photon.z() >= 0 || (zv > gpar_[0] && (!onlyLong)))) {
0303 int depth = 1;
0304 if (onlyLong) {
0305 } else if (!backward) {
0306 if (photon.z() < 0)
0307 depth = 2;
0308 } else {
0309 double r = G4UniformRand();
0310 if (r > 0.5)
0311 depth = 2;
0312 }
0313
0314
0315
0316 double pex = photon.x();
0317 double pey = photon.y();
0318
0319 double xx = pex * ctheta * cphi - pey * sphi + zv * stheta * cphi;
0320 double yy = pex * ctheta * sphi + pey * cphi + zv * stheta * sphi;
0321 double zz = -pex * stheta + zv * ctheta;
0322
0323 G4ThreeVector pos = hitPoint + G4ThreeVector(xx, yy, zz);
0324 zv = std::abs(pos.z()) - gpar_[4] - 0.5 * gpar_[1];
0325 G4ThreeVector lpos = G4ThreeVector(pos.x(), pos.y(), zv);
0326
0327 zv = fibre_.zShift(lpos, depth, 0);
0328
0329 double r = pos.perp();
0330 double p = fibre_.attLength(photon.lambda());
0331 double fi = pos.phi();
0332 if (fi < 0)
0333 fi += CLHEP::twopi;
0334 int isect = int(fi / dphi_) + 1;
0335 isect = (isect + 1) / 2;
0336 double dfi = ((isect * 2 - 1) * dphi_ - fi);
0337 if (dfi < 0)
0338 dfi = -dfi;
0339 double dfir = r * sin(dfi);
0340 #ifdef EDM_ML_DEBUG
0341 edm::LogVerbatim("HFShower") << "HFShowerLibrary: Position shift " << xx << ", " << yy << ", " << zz << ": "
0342 << pos << " R " << r << " Phi " << fi << " Section " << isect << " R*Dfi " << dfir
0343 << " Dist " << zv;
0344 #endif
0345 zz = std::abs(pos.z());
0346 double r1 = G4UniformRand();
0347 double r2 = G4UniformRand();
0348 double r3 = backward ? G4UniformRand() : -9999.;
0349 if (!applyFidCut_)
0350 dfir += gpar_[5];
0351
0352 #ifdef EDM_ML_DEBUG
0353 edm::LogVerbatim("HFShower") << "HFShowerLibrary: rLimits " << rInside(r) << " attenuation " << r1 << ":"
0354 << exp(-p * zv) << " r2 " << r2 << " r3 " << r3 << " rDfi " << gpar_[5] << " zz "
0355 << zz << " zLim " << gpar_[4] << ":" << gpar_[4] + gpar_[1] << "\n"
0356 << " rInside(r) :" << rInside(r) << " r1 <= exp(-p*zv) :" << (r1 <= exp(-p * zv))
0357 << " r2 <= probMax :" << (r2 <= probMax_ * weight)
0358 << " r3 <= backProb :" << (r3 <= backProb_)
0359 << " dfir > gpar[5] :" << (dfir > gpar_[5])
0360 << " zz >= gpar[4] :" << (zz >= gpar_[4])
0361 << " zz <= gpar[4]+gpar[1] :" << (zz <= gpar_[4] + gpar_[1]);
0362 #endif
0363 if (rInside(r) && r1 <= exp(-p * zv) && r2 <= probMax_ * weight && dfir > gpar_[5] && zz >= gpar_[4] &&
0364 zz <= gpar_[4] + gpar_[1] && r3 <= backProb_ && (depth != 2 || zz >= gpar_[4] + gpar_[0])) {
0365 double tdiff = (equalizeTimeShift_) ? (fibre_.tShift(lpos, depth, -1)) : (fibre_.tShift(lpos, depth, 1));
0366 oneHit.position = pos;
0367 oneHit.depth = depth;
0368 oneHit.time = (tSlice + (photon.t()) + tdiff);
0369 hit.push_back(oneHit);
0370
0371 #ifdef EDM_ML_DEBUG
0372 edm::LogVerbatim("HFShower") << "HFShowerLibrary: Final Hit " << nHit << " position " << (hit[nHit].position)
0373 << " Depth " << (hit[nHit].depth) << " Time " << tSlice << ":" << photon.t() << ":"
0374 << tdiff << ":" << (hit[nHit].time);
0375 #endif
0376 ++nHit;
0377 }
0378 #ifdef EDM_ML_DEBUG
0379 else
0380 edm::LogVerbatim("HFShower") << "HFShowerLibrary: REJECTED !!!";
0381 #endif
0382 if (onlyLong && zz >= gpar_[4] + gpar_[0] && zz <= gpar_[4] + gpar_[1]) {
0383 r1 = G4UniformRand();
0384 r2 = G4UniformRand();
0385 if (rInside(r) && r1 <= exp(-p * zv) && r2 <= probMax_ && dfir > gpar_[5]) {
0386 double tdiff = (equalizeTimeShift_) ? (fibre_.tShift(lpos, 2, -1)) : (fibre_.tShift(lpos, 2, 1));
0387 oneHit.position = pos;
0388 oneHit.depth = 2;
0389 oneHit.time = (tSlice + (photon.t()) + tdiff);
0390 hit.push_back(oneHit);
0391 #ifdef EDM_ML_DEBUG
0392 edm::LogVerbatim("HFShower") << "HFShowerLibrary: Final Hit " << nHit << " position " << (hit[nHit].position)
0393 << " Depth " << (hit[nHit].depth) << " Time " << tSlice << ":" << photon.t()
0394 << ":" << tdiff << ":" << (hit[nHit].time);
0395 #endif
0396 ++nHit;
0397 }
0398 }
0399 }
0400 }
0401
0402 #ifdef EDM_ML_DEBUG
0403 edm::LogVerbatim("HFShower") << "HFShowerLibrary: Total Hits " << nHit << " out of " << pe.size() << " PE";
0404 #endif
0405 if (nHit > pe.size() && !onlyLong) {
0406 edm::LogWarning("HFShower") << "HFShowerLibrary: Hit buffer " << pe.size() << " smaller than " << nHit << " Hits";
0407 }
0408 return hit;
0409 }
0410
0411 bool HFShowerLibrary::rInside(double r) const { return (r >= rMin_ && r <= rMax_); }
0412
0413 HFShowerLibrary::BranchCache::BranchCache(HFShowerLibrary::BranchReader& iReader, size_t maxRecordsToCache) {
0414 auto nRecords = iReader.numberOfRecords();
0415 if (nRecords > maxRecordsToCache) {
0416 nRecords = maxRecordsToCache;
0417 }
0418 offsets_.reserve(nRecords + 1);
0419
0420
0421 size_t nPhotons = 0;
0422 for (size_t r = 0; r < nRecords; ++r) {
0423 auto shower = iReader.getRecord(r + 1);
0424 nPhotons += shower.size();
0425 }
0426
0427 photons_.reserve(nPhotons);
0428
0429 size_t offset = 0;
0430 for (size_t r = 0; r < nRecords; ++r) {
0431 offsets_.emplace_back(offset);
0432 auto shower = iReader.getRecord(r + 1);
0433 offset += shower.size();
0434 std::copy(shower.begin(), shower.end(), std::back_inserter(photons_));
0435 }
0436 offsets_.emplace_back(offset);
0437 photons_.shrink_to_fit();
0438 }
0439
0440 void HFShowerLibrary::BranchReader::doCaching(size_t maxRecordsToCache) {
0441 cache_ = makeCache(*this, maxRecordsToCache, branch_->GetDirectory()->GetFile()->GetName(), branch_->GetName());
0442 }
0443
0444 std::shared_ptr<HFShowerLibrary::BranchCache const> HFShowerLibrary::BranchReader::makeCache(
0445 BranchReader& iReader, size_t maxRecordsToCache, std::string const& iFileName, std::string const& iBranchName) {
0446
0447 CMS_SA_ALLOW static std::mutex s_mutex;
0448 std::lock_guard<std::mutex> guard(s_mutex);
0449 CMS_SA_ALLOW static std::map<std::pair<std::string, std::string>, std::weak_ptr<BranchCache>> s_map;
0450 auto v = s_map[{iFileName, iBranchName}].lock();
0451 if (v) {
0452 return v;
0453 }
0454 v = std::make_shared<BranchCache>(iReader, maxRecordsToCache);
0455 s_map[{iFileName, iBranchName}] = v;
0456 return v;
0457 }
0458
0459 HFShowerPhotonCollection HFShowerLibrary::BranchCache::getRecord(int iRecord) const {
0460 assert(iRecord > 0);
0461 assert(static_cast<size_t>(iRecord + 1) < offsets_.size());
0462
0463 auto start = offsets_[iRecord - 1];
0464 auto end = offsets_[iRecord];
0465
0466 return HFShowerPhotonCollection(photons_.begin() + start, photons_.begin() + end);
0467 }
0468
0469 HFShowerPhotonCollection HFShowerLibrary::BranchReader::getRecordOldForm(TBranch* iBranch, int iEntry) {
0470 HFShowerPhotonCollection photo;
0471 iBranch->SetAddress(&photo);
0472 iBranch->GetEntry(iEntry);
0473 return photo;
0474 }
0475 HFShowerPhotonCollection HFShowerLibrary::BranchReader::getRecordNewForm(TBranch* iBranch, int iEntry) {
0476 HFShowerPhotonCollection photo;
0477
0478 auto temp = std::make_unique<HFShowerPhotonCollection>();
0479 iBranch->SetAddress(&temp);
0480 iBranch->GetEntry(iEntry);
0481 photo = std::move(*temp);
0482
0483 return photo;
0484 }
0485 HFShowerPhotonCollection HFShowerLibrary::BranchReader::getRecordNewFormV3(TBranch* iBranch, int iEntry) {
0486 HFShowerPhotonCollection photo;
0487
0488 std::vector<float> t;
0489 std::vector<float>* tp = &t;
0490 iBranch->SetAddress(&tp);
0491 iBranch->GetEntry(iEntry);
0492 unsigned int tSize = t.size() / 5;
0493 photo.reserve(tSize);
0494 for (unsigned int i = 0; i < tSize; i++) {
0495 photo.emplace_back(t[i], t[1 * tSize + i], t[2 * tSize + i], t[3 * tSize + i], t[4 * tSize + i]);
0496 }
0497
0498 return photo;
0499 }
0500
0501 HFShowerPhotonCollection HFShowerLibrary::BranchReader::getRecord(int record) const {
0502 if (cache_) {
0503 return cache_->getRecord(record);
0504 }
0505 int nrc = record - 1;
0506 HFShowerPhotonCollection photo;
0507
0508 switch (format_) {
0509 case FileFormat::kNew: {
0510 photo = getRecordNewForm(branch_, nrc + offset_);
0511 break;
0512 }
0513 case FileFormat::kNewV3: {
0514 photo = getRecordNewFormV3(branch_, nrc + offset_);
0515 break;
0516 }
0517 case FileFormat::kOld: {
0518 photo = getRecordOldForm(branch_, nrc);
0519 break;
0520 }
0521 }
0522 return photo;
0523 }
0524
0525 size_t HFShowerLibrary::BranchReader::numberOfRecords() const { return branch_->GetEntries() - offset_; }
0526
0527 HFShowerPhotonCollection HFShowerLibrary::getRecord(int type, int record) const {
0528 HFShowerPhotonCollection photo;
0529 if (type > 0) {
0530 photo = hadBranch_.getRecord(record);
0531 } else {
0532 photo = emBranch_.getRecord(record);
0533 }
0534 #ifdef EDM_ML_DEBUG
0535 int nPhoton = photo.size();
0536 edm::LogVerbatim("HFShower") << "HFShowerLibrary::getRecord: Record " << record << " of type " << type << " with "
0537 << nPhoton << " photons";
0538 for (int j = 0; j < nPhoton; j++)
0539 edm::LogVerbatim("HFShower") << "Photon " << j << " " << photo[j];
0540 #endif
0541 return photo;
0542 }
0543
0544 HFShowerLibrary::VersionInfo HFShowerLibrary::loadEventInfo(TBranch* branch, int fileVersion) {
0545 VersionInfo versionInfo;
0546 if (branch) {
0547 std::vector<HFShowerLibraryEventInfo> eventInfoCollection;
0548 branch->SetAddress(&eventInfoCollection);
0549 branch->GetEntry(0);
0550 edm::LogVerbatim("HFShower") << "HFShowerLibrary::loadEventInfo loads EventInfo Collection of size "
0551 << eventInfoCollection.size() << " records";
0552
0553 totEvents_ = eventInfoCollection[0].totalEvents();
0554 nMomBin_ = eventInfoCollection[0].numberOfBins();
0555 evtPerBin_ = eventInfoCollection[0].eventsPerBin();
0556 versionInfo.libVers_ = eventInfoCollection[0].showerLibraryVersion();
0557 versionInfo.listVersion_ = eventInfoCollection[0].physListVersion();
0558 pmom_ = eventInfoCollection[0].energyBins();
0559 } else {
0560 edm::LogVerbatim("HFShower") << "HFShowerLibrary::loadEventInfo loads EventInfo from hardwired"
0561 << " numbers";
0562
0563 nMomBin_ = 16;
0564 evtPerBin_ = (fileVersion == 0) ? 5000 : 10000;
0565 totEvents_ = nMomBin_ * evtPerBin_;
0566 versionInfo.libVers_ = (fileVersion == 0) ? 1.1 : 1.2;
0567 versionInfo.listVersion_ = 3.6;
0568 pmom_ = {2, 3, 5, 7, 10, 15, 20, 30, 50, 75, 100, 150, 250, 350, 500, 1000};
0569 }
0570 for (int i = 0; i < nMomBin_; i++)
0571 pmom_[i] *= CLHEP::GeV;
0572 return versionInfo;
0573 }
0574
0575 HFShowerPhotonCollection HFShowerLibrary::interpolate(int type, double pin) {
0576 #ifdef EDM_ML_DEBUG
0577 edm::LogVerbatim("HFShower") << "HFShowerLibrary:: Interpolate for Energy " << pin / CLHEP::GeV << " GeV with "
0578 << nMomBin_ << " momentum bins and " << evtPerBin_ << " entries/bin -- total "
0579 << totEvents_;
0580 #endif
0581 int irc[2] = {0, 0};
0582 double w = 0.;
0583 double r = G4UniformRand();
0584
0585 if (pin < pmom_[0]) {
0586 w = pin / pmom_[0];
0587 irc[1] = int(evtPerBin_ * r) + 1;
0588 irc[0] = 0;
0589 } else {
0590 for (int j = 0; j < nMomBin_ - 1; j++) {
0591 if (pin >= pmom_[j] && pin < pmom_[j + 1]) {
0592 w = (pin - pmom_[j]) / (pmom_[j + 1] - pmom_[j]);
0593 if (j == nMomBin_ - 2) {
0594 irc[1] = int(evtPerBin_ * 0.5 * r);
0595 } else {
0596 irc[1] = int(evtPerBin_ * r);
0597 }
0598 irc[1] += (j + 1) * evtPerBin_ + 1;
0599 r = G4UniformRand();
0600 irc[0] = int(evtPerBin_ * r) + 1 + j * evtPerBin_;
0601 if (irc[0] < 0) {
0602 edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[0] = " << irc[0] << " now set to 0";
0603 irc[0] = 0;
0604 } else if (irc[0] > totEvents_) {
0605 edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[0] = " << irc[0] << " now set to "
0606 << totEvents_;
0607 irc[0] = totEvents_;
0608 }
0609 }
0610 }
0611 }
0612 if (irc[1] < 1) {
0613 edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[1] = " << irc[1] << " now set to 1";
0614 irc[1] = 1;
0615 } else if (irc[1] > totEvents_) {
0616 edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[1] = " << irc[1] << " now set to " << totEvents_;
0617 irc[1] = totEvents_;
0618 }
0619
0620 #ifdef EDM_ML_DEBUG
0621 edm::LogVerbatim("HFShower") << "HFShowerLibrary:: Select records " << irc[0] << " and " << irc[1] << " with weights "
0622 << 1 - w << " and " << w;
0623 #endif
0624 HFShowerPhotonCollection pe;
0625
0626 std::size_t npold = 0;
0627 for (int ir = 0; ir < 2; ir++) {
0628 if (irc[ir] > 0) {
0629 auto photons = getRecord(type, irc[ir]);
0630 int nPhoton = photons.size();
0631 npold += nPhoton;
0632 pe.reserve(pe.size() + nPhoton);
0633 for (auto const& photon : photons) {
0634 r = G4UniformRand();
0635 if ((ir == 0 && r > w) || (ir > 0 && r < w)) {
0636 storePhoton(photon, pe);
0637 }
0638 }
0639 }
0640 }
0641
0642 if ((pe.size() > npold || (npold == 0 && irc[0] > 0)) && !(pe.empty() && npold == 0))
0643 edm::LogWarning("HFShower") << "HFShowerLibrary: Interpolation Warning =="
0644 << " records " << irc[0] << " and " << irc[1] << " gives a buffer of " << npold
0645 << " photons and fills " << pe.size() << " *****";
0646 #ifdef EDM_ML_DEBUG
0647 else
0648 edm::LogVerbatim("HFShower") << "HFShowerLibrary: Interpolation == records " << irc[0] << " and " << irc[1]
0649 << " gives a buffer of " << npold << " photons and fills " << pe.size() << " PE";
0650 for (std::size_t j = 0; j < pe.size(); j++)
0651 edm::LogVerbatim("HFShower") << "Photon " << j << " " << pe[j];
0652 #endif
0653 return pe;
0654 }
0655
0656 HFShowerPhotonCollection HFShowerLibrary::extrapolate(int type, double pin) {
0657 int nrec = int(pin / pmom_[nMomBin_ - 1]);
0658 double w = (pin - pmom_[nMomBin_ - 1] * nrec) / pmom_[nMomBin_ - 1];
0659 nrec++;
0660 #ifdef EDM_ML_DEBUG
0661 edm::LogVerbatim("HFShower") << "HFShowerLibrary:: Extrapolate for Energy " << pin / CLHEP::GeV << " GeV with "
0662 << nMomBin_ << " momentum bins and " << evtPerBin_ << " entries/bin -- "
0663 << "total " << totEvents_ << " using " << nrec << " records";
0664 #endif
0665 std::vector<int> irc(nrec);
0666
0667 for (int ir = 0; ir < nrec; ir++) {
0668 double r = G4UniformRand();
0669 irc[ir] = int(evtPerBin_ * 0.5 * r) + (nMomBin_ - 1) * evtPerBin_ + 1;
0670 if (irc[ir] < 1) {
0671 edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[" << ir << "] = " << irc[ir] << " now set to 1";
0672 irc[ir] = 1;
0673 } else if (irc[ir] > totEvents_) {
0674 edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[" << ir << "] = " << irc[ir] << " now set to "
0675 << totEvents_;
0676 irc[ir] = totEvents_;
0677 #ifdef EDM_ML_DEBUG
0678 } else {
0679 edm::LogVerbatim("HFShower") << "HFShowerLibrary::Extrapolation use irc[" << ir << "] = " << irc[ir];
0680 #endif
0681 }
0682 }
0683
0684 HFShowerPhotonCollection pe;
0685 std::size_t npold = 0;
0686 for (int ir = 0; ir < nrec; ir++) {
0687 if (irc[ir] > 0) {
0688 auto const photons = getRecord(type, irc[ir]);
0689 int nPhoton = photons.size();
0690 npold += nPhoton;
0691 pe.reserve(pe.size() + nPhoton);
0692 for (auto const& photon : photons) {
0693 double r = G4UniformRand();
0694 if (ir != nrec - 1 || r < w) {
0695 storePhoton(photon, pe);
0696 }
0697 }
0698 #ifdef EDM_ML_DEBUG
0699 edm::LogVerbatim("HFShower") << "HFShowerLibrary: Record [" << ir << "] = " << irc[ir] << " npold = " << npold;
0700 #endif
0701 }
0702 }
0703 #ifdef EDM_ML_DEBUG
0704 edm::LogVerbatim("HFShower") << "HFShowerLibrary:: uses " << npold << " photons";
0705 #endif
0706
0707 if (pe.size() > npold || npold == 0)
0708 edm::LogWarning("HFShower") << "HFShowerLibrary: Extrapolation Warning == " << nrec << " records " << irc[0] << ", "
0709 << irc[1] << ", ... gives a buffer of " << npold << " photons and fills " << pe.size()
0710 << " *****";
0711 #ifdef EDM_ML_DEBUG
0712 else
0713 edm::LogVerbatim("HFShower") << "HFShowerLibrary: Extrapolation == " << nrec << " records " << irc[0] << ", "
0714 << irc[1] << ", ... gives a buffer of " << npold << " photons and fills " << pe.size()
0715 << " PE";
0716 for (std::size_t j = 0; j < pe.size(); j++)
0717 edm::LogVerbatim("HFShower") << "Photon " << j << " " << pe[j];
0718 #endif
0719 return pe;
0720 }
0721
0722 void HFShowerLibrary::storePhoton(HFShowerPhoton const& iPhoton, HFShowerPhotonCollection& iPhotons) const {
0723 iPhotons.push_back(iPhoton);
0724 #ifdef EDM_ML_DEBUG
0725 edm::LogVerbatim("HFShower") << "HFShowerLibrary: storePhoton " << iPhoton << " npe " << iPhotons.size() << " "
0726 << iPhotons.back();
0727 #endif
0728 }