CMS 3D CMS Logo

TRandomAdaptor.cc
Go to the documentation of this file.
3 
4 #include "CLHEP/Random/engineIDulong.h"
5 
6 #include "TBufferFile.h"
7 
8 #include <cstddef>
9 #include <iomanip>
10 #include <iostream>
11 #include <sstream>
12 #include <cstdint>
13 #include <string>
14 
15 namespace edm {
16 
17 TRandomAdaptor::TRandomAdaptor() : trand_(new TRandom3()) {
18  theSeed = trand_->GetSeed();
19 }
20 TRandomAdaptor::TRandomAdaptor( long seed ) : trand_(new TRandom3(seed)) {
21  theSeed = trand_->GetSeed();
22 }
23 TRandomAdaptor::TRandomAdaptor( int rowIndex, int colIndex ) : trand_(new TRandom3(rowIndex*colIndex-1)) {
24  theSeed = trand_->GetSeed();
25 }
26 
28  Grumble(std::string("Cannot instantiate a TRandom engine from an istream"));
29 }
30 
32 }
33 
34 std::ostream& TRandomAdaptor::put(std::ostream& os) const {
35  Grumble(std::string("put(std::ostream) not available for TRandom engines"));
36  return os;
37 }
38 
39 std::vector<unsigned long> TRandomAdaptor::put() const {
40  std::vector<unsigned long> v;
41 
42  int32_t itemSize = sizeof(uint32_t);
43  TBufferFile buffer(TBuffer::kWrite, 2048 * itemSize);
44  trand_->Streamer(buffer);
45  buffer.SetReadMode();
46  char* bufferPtr = buffer.Buffer();
47  int32_t numItems = (buffer.Length() + itemSize - 1) / itemSize;
48  v.reserve(numItems + 1);
49  v.push_back(CLHEP::engineIDulong<TRandomAdaptor>());
50  for(int i = 0; i < numItems; ++i) {
51 
52  // Here we do some ugly manipulations to the data to match the format
53  // of the output of the CLHEP put function (the whole point of this adaptor
54  // is to make TRandom3 work through the CLHEP interface as if it were a
55  // a CLHEP engine ...). In CLHEP, the vector returned by put contains
56  // unsigned long's, but these always contain only 32 bits of information.
57  // In the case of a 64 bit build the top 32 bits is only padding (all 0's).
58 
59  // Get the next 32 bits of data from the buffer
60  uint32_t value32 = *reinterpret_cast<uint32_t*>(bufferPtr + i * itemSize);
61 
62  if(i == numItems - 1) {
63  int nBytes = buffer.Length() % itemSize;
64  if(nBytes == 1) value32 &= 0xffu;
65  else if(nBytes == 2) value32 &= 0xffffu;
66  else if(nBytes == 3) value32 &= 0xffffffu;
67  }
68 
69  // Push it into the vector in an unsigned long which may be 32 or 64 bits
70  v.push_back(static_cast<unsigned long>(value32));
71  }
72  return v;
73 }
74 
75 void TRandomAdaptor::setSeed(long seed, int) {
76  trand_->SetSeed(seed);
77  theSeed = trand_->GetSeed();
78 }
79 
80 // Sets the state of the algorithm according to the zero terminated
81 // array of seeds. It is allowed to ignore one or many seeds in this array.
82 void TRandomAdaptor::setSeeds(long const* seeds, int) {
83  trand_->SetSeed(seeds[0]);
84  theSeed = trand_->GetSeed();
85 }
86 
87 
88 std::istream& TRandomAdaptor::get(std::istream& is) {
89  Grumble(std::string("get(std::istream) not available for TRandom engines"));
90  return getState(is);
91 }
92 
93 std::istream& TRandomAdaptor::getState(std::istream& is) {
94  Grumble(std::string("getState(std::istream) not available for TRandom engines"));
95  return is;
96 }
97 
98 bool TRandomAdaptor::get(std::vector<unsigned long> const& v) {
99  if(v.empty()) return false;
100  if(v[0] != CLHEP::engineIDulong<TRandomAdaptor>()) return false;
101  int32_t numItems = v.size()-1;
102 
103  int32_t itemSize = sizeof(uint32_t);
104  TBufferFile buffer(TBuffer::kRead, numItems * itemSize + 1024);
105  char* bufferPtr = buffer.Buffer();
106  for(int32_t i = 0; i < numItems; ++i) {
107 
108  *reinterpret_cast<uint32_t*>(bufferPtr + i * itemSize) = static_cast<uint32_t>(v[i+1] & 0xffffffff);
109  }
110 
111  // Note that this will fail if the TRandom3 version (specifically the TStreamerInfo)
112  // has changed between the time the state was saved and the time the following call
113  // is made. Because we are manually calling the Streamer function, the original
114  // TStreamerInfo is not saved anywhere. Normally ROOT saves the TStreamerInfo
115  // automatically.
116  trand_->Streamer(buffer);
117 
118  return true;
119 }
120 
121 void TRandomAdaptor::Grumble(std::string const& errortext) const {
122 
123 // Throw an edm::Exception for unimplemented functions
124  std::ostringstream sstr;
125  sstr << "Unimplemented Feature: " << errortext << '\n';
127  throw except;
128 }
129 
130 } // namespace edm
void setSeed(long seed, int) override
void setSeeds(long const *seeds, int) override
std::vector< unsigned long > put() const override
~TRandomAdaptor() override
HLT enums.
std::istream & getState(std::istream &is) override
std::istream & get(std::istream &is) override
void Grumble(std::string const &errortext) const