CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/IOMC/RandomEngine/src/TRandomAdaptor.cc

Go to the documentation of this file.
00001 #include "IOMC/RandomEngine/src/TRandomAdaptor.h"
00002 #include "FWCore/Utilities/interface/EDMException.h"
00003 
00004 #include "CLHEP/Random/engineIDulong.h"
00005 
00006 #include "TBufferFile.h"
00007 
00008 #include <cstddef>
00009 #include <iomanip>
00010 #include <iostream>
00011 #include <sstream>
00012 #include <stdint.h>
00013 #include <string>
00014 
00015 namespace edm {
00016 
00017 TRandomAdaptor::TRandomAdaptor() : trand_(new TRandom3()) {
00018    theSeed = trand_->GetSeed();
00019 }
00020 TRandomAdaptor::TRandomAdaptor( long seed ) : trand_(new TRandom3(seed)) {
00021    theSeed = trand_->GetSeed();
00022 }
00023 TRandomAdaptor::TRandomAdaptor( int rowIndex, int colIndex ) : trand_(new TRandom3(rowIndex*colIndex-1)) {
00024    theSeed = trand_->GetSeed();
00025 }
00026 
00027 TRandomAdaptor::TRandomAdaptor(std::istream&) {
00028   Grumble(std::string("Cannot instantiate a TRandom engine from an istream"));
00029 }
00030 
00031 TRandomAdaptor::~TRandomAdaptor() {
00032 }
00033 
00034 std::ostream& TRandomAdaptor::put(std::ostream& os) const {
00035   Grumble(std::string("put(std::ostream) not available for TRandom engines"));
00036   return os;
00037 }
00038 
00039 std::vector<unsigned long> TRandomAdaptor::put() const {
00040   std::vector<unsigned long> v;
00041 
00042   int32_t itemSize = sizeof(uint32_t);
00043   TBufferFile buffer(TBuffer::kWrite, 2048 * itemSize);
00044   trand_->Streamer(buffer);
00045   buffer.SetReadMode();
00046   char* bufferPtr = buffer.Buffer();
00047   int32_t numItems = (buffer.Length() + itemSize - 1) / itemSize;
00048   v.reserve(numItems + 1);
00049   v.push_back(CLHEP::engineIDulong<TRandomAdaptor>());
00050   for(int i = 0; i < numItems; ++i) {
00051 
00052     // Here we do some ugly manipulations to the data to match the format
00053     // of the output of the CLHEP put function (the whole point of this adaptor
00054     // is to make TRandom3 work through the CLHEP interface as if it were a
00055     // a CLHEP engine ...).  In CLHEP, the vector returned by put contains
00056     // unsigned long's, but these always contain only 32 bits of information.
00057     // In the case of a 64 bit build the top 32 bits is only padding (all 0's).
00058 
00059     // Get the next 32 bits of data from the buffer
00060     uint32_t value32 = *reinterpret_cast<uint32_t*>(bufferPtr + i * itemSize);
00061 
00062     if(i == numItems - 1) {
00063       int nBytes = buffer.Length() % itemSize;
00064       if(nBytes == 1) value32 &= 0xffu;
00065       else if(nBytes == 2) value32 &= 0xffffu;
00066       else if(nBytes == 3) value32 &= 0xffffffu;
00067     }
00068 
00069     // Push it into the vector in an unsigned long which may be 32 or 64 bits
00070     v.push_back(static_cast<unsigned long>(value32));
00071   }
00072   return v;
00073 }
00074 
00075 void TRandomAdaptor::setSeed(long seed, int) { 
00076    trand_->SetSeed(seed);
00077    theSeed = trand_->GetSeed();
00078 }
00079 
00080 // Sets the state of the algorithm according to the zero terminated
00081 // array of seeds. It is allowed to ignore one or many seeds in this array.
00082 void TRandomAdaptor::setSeeds(long const* seeds, int) { 
00083    trand_->SetSeed(seeds[0]); 
00084    theSeed = trand_->GetSeed();
00085 }
00086 
00087 
00088 std::istream& TRandomAdaptor::get(std::istream& is) {
00089   Grumble(std::string("get(std::istream) not available for TRandom engines"));
00090   return getState(is);
00091 }
00092 
00093 std::istream& TRandomAdaptor::getState(std::istream& is) {
00094   Grumble(std::string("getState(std::istream) not available for TRandom engines"));
00095   return is;
00096 }
00097 
00098 bool TRandomAdaptor::get(std::vector<unsigned long> const& v) {
00099   if(v.empty())  return false;
00100   if(v[0] != CLHEP::engineIDulong<TRandomAdaptor>()) return false;
00101   int32_t numItems = v.size()-1;
00102 
00103   int32_t itemSize = sizeof(uint32_t);
00104   TBufferFile buffer(TBuffer::kRead, numItems * itemSize + 1024);
00105   char* bufferPtr = buffer.Buffer();
00106   for(int32_t i = 0; i < numItems; ++i) {
00107 
00108     *reinterpret_cast<uint32_t*>(bufferPtr + i * itemSize) = static_cast<uint32_t>(v[i+1] & 0xffffffff);
00109   }
00110 
00111   // Note that this will fail if the TRandom3 version (specifically the TStreamerInfo)
00112   // has changed between the time the state was saved and the time the following call
00113   // is made.  Because we are manually calling the Streamer function, the original
00114   // TStreamerInfo is not saved anywhere. Normally ROOT saves the TStreamerInfo
00115   // automatically.
00116   trand_->Streamer(buffer);
00117 
00118   return true;
00119 }
00120 
00121 void TRandomAdaptor::Grumble(std::string const& errortext) const {
00122 
00123 // Throw an edm::Exception for unimplemented functions
00124    std::ostringstream sstr;
00125    sstr << "Unimplemented Feature: " << errortext << '\n';
00126    edm::Exception except(edm::errors::UnimplementedFeature, sstr.str());
00127    throw except;
00128 }
00129 
00130 }  // namespace edm