File indexing completed on 2024-04-06 12:19:04
0001 #include "IOMC/RandomEngine/interface/TRandomAdaptor.h"
0002 #include "FWCore/Utilities/interface/EDMException.h"
0003
0004 #include "CLHEP/Random/engineIDulong.h"
0005
0006 #include "TBufferFile.h"
0007
0008 #include <cstddef>
0009 #include <iomanip>
0010 #include <iostream>
0011 #include <sstream>
0012 #include <cstdint>
0013 #include <string>
0014
0015 namespace edm {
0016
0017 TRandomAdaptor::TRandomAdaptor() : trand_(new TRandom3()) { theSeed = trand_->GetSeed(); }
0018 TRandomAdaptor::TRandomAdaptor(long seed) : trand_(new TRandom3(seed)) { theSeed = trand_->GetSeed(); }
0019 TRandomAdaptor::TRandomAdaptor(int rowIndex, int colIndex) : trand_(new TRandom3(rowIndex * colIndex - 1)) {
0020 theSeed = trand_->GetSeed();
0021 }
0022
0023 TRandomAdaptor::TRandomAdaptor(std::istream&) {
0024 Grumble(std::string("Cannot instantiate a TRandom engine from an istream"));
0025 }
0026
0027 TRandomAdaptor::~TRandomAdaptor() {}
0028
0029 std::ostream& TRandomAdaptor::put(std::ostream& os) const {
0030 Grumble(std::string("put(std::ostream) not available for TRandom engines"));
0031 return os;
0032 }
0033
0034 std::vector<unsigned long> TRandomAdaptor::put() const {
0035 std::vector<unsigned long> v;
0036
0037 int32_t itemSize = sizeof(uint32_t);
0038 TBufferFile buffer(TBuffer::kWrite, 2048 * itemSize);
0039 trand_->Streamer(buffer);
0040 buffer.SetReadMode();
0041 char* bufferPtr = buffer.Buffer();
0042 int32_t numItems = (buffer.Length() + itemSize - 1) / itemSize;
0043 v.reserve(numItems + 1);
0044 v.push_back(CLHEP::engineIDulong<TRandomAdaptor>());
0045 for (int i = 0; i < numItems; ++i) {
0046
0047
0048
0049
0050
0051
0052
0053
0054 uint32_t value32 = *reinterpret_cast<uint32_t*>(bufferPtr + i * itemSize);
0055
0056 if (i == numItems - 1) {
0057 int nBytes = buffer.Length() % itemSize;
0058 if (nBytes == 1)
0059 value32 &= 0xffu;
0060 else if (nBytes == 2)
0061 value32 &= 0xffffu;
0062 else if (nBytes == 3)
0063 value32 &= 0xffffffu;
0064 }
0065
0066
0067 v.push_back(static_cast<unsigned long>(value32));
0068 }
0069 return v;
0070 }
0071
0072 void TRandomAdaptor::setSeed(long seed, int) {
0073 trand_->SetSeed(seed);
0074 theSeed = trand_->GetSeed();
0075 }
0076
0077
0078
0079 void TRandomAdaptor::setSeeds(long const* seeds, int) {
0080 trand_->SetSeed(seeds[0]);
0081 theSeed = trand_->GetSeed();
0082 }
0083
0084 std::istream& TRandomAdaptor::get(std::istream& is) {
0085 Grumble(std::string("get(std::istream) not available for TRandom engines"));
0086 return getState(is);
0087 }
0088
0089 std::istream& TRandomAdaptor::getState(std::istream& is) {
0090 Grumble(std::string("getState(std::istream) not available for TRandom engines"));
0091 return is;
0092 }
0093
0094 bool TRandomAdaptor::get(std::vector<unsigned long> const& v) {
0095 if (v.empty())
0096 return false;
0097 if (v[0] != CLHEP::engineIDulong<TRandomAdaptor>())
0098 return false;
0099 int32_t numItems = v.size() - 1;
0100
0101 int32_t itemSize = sizeof(uint32_t);
0102 TBufferFile buffer(TBuffer::kRead, numItems * itemSize + 1024);
0103 char* bufferPtr = buffer.Buffer();
0104 for (int32_t i = 0; i < numItems; ++i) {
0105 *reinterpret_cast<uint32_t*>(bufferPtr + i * itemSize) = static_cast<uint32_t>(v[i + 1] & 0xffffffff);
0106 }
0107
0108
0109
0110
0111
0112
0113 trand_->Streamer(buffer);
0114
0115 return true;
0116 }
0117
0118 void TRandomAdaptor::Grumble(std::string const& errortext) const {
0119
0120 std::ostringstream sstr;
0121 sstr << "Unimplemented Feature: " << errortext << '\n';
0122 edm::Exception except(edm::errors::UnimplementedFeature, sstr.str());
0123 throw except;
0124 }
0125
0126 }