CMS 3D CMS Logo

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