CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/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(std::istream&) {
00018   Grumble(std::string("Cannot instantiate a TRandom engine from an istream"));
00019 }
00020 
00021 TRandomAdaptor::~TRandomAdaptor() {
00022 }
00023 
00024 std::ostream& TRandomAdaptor::put(std::ostream& os) const {
00025   Grumble(std::string("put(std::ostream) not available for TRandom engines"));
00026   return os;
00027 }
00028 
00029 std::vector<unsigned long> TRandomAdaptor::put() const {
00030   std::vector<unsigned long> v;
00031 
00032   int32_t itemSize = sizeof(uint32_t);
00033   TBufferFile buffer(TBuffer::kWrite, 2048 * itemSize);
00034   trand_->Streamer(buffer);
00035   buffer.SetReadMode();
00036   char* bufferPtr = buffer.Buffer();
00037   int32_t numItems = (buffer.Length() + itemSize - 1) / itemSize;
00038   v.reserve(numItems + 1);
00039   v.push_back(CLHEP::engineIDulong<TRandomAdaptor>());
00040   for(int i = 0; i < numItems; ++i) {
00041 
00042     // Here we do some ugly manipulations to the data to match the format
00043     // of the output of the CLHEP put function (the whole point of this adaptor
00044     // is to make TRandom3 work through the CLHEP interface as if it were a
00045     // a CLHEP engine ...).  In CLHEP, the vector returned by put contains
00046     // unsigned long's, but these always contain only 32 bits of information.
00047     // In the case of a 64 bit build the top 32 bits is only padding (all 0's).
00048 
00049     // Get the next 32 bits of data from the buffer
00050     uint32_t value32 = *reinterpret_cast<uint32_t*>(bufferPtr + i * itemSize);
00051 
00052     if(i == numItems - 1) {
00053       int nBytes = buffer.Length() % itemSize;
00054       if(nBytes == 1) value32 &= 0xffu;
00055       else if(nBytes == 2) value32 &= 0xffffu;
00056       else if(nBytes == 3) value32 &= 0xffffffu;
00057     }
00058 
00059     // Push it into the vector in an unsigned long which may be 32 or 64 bits
00060     v.push_back(static_cast<unsigned long>(value32));
00061   }
00062   return v;
00063 }
00064 
00065 std::istream& TRandomAdaptor::get(std::istream& is) {
00066   Grumble(std::string("get(std::istream) not available for TRandom engines"));
00067   return getState(is);
00068 }
00069 
00070 std::istream& TRandomAdaptor::getState(std::istream& is) {
00071   Grumble(std::string("getState(std::istream) not available for TRandom engines"));
00072   return is;
00073 }
00074 
00075 bool TRandomAdaptor::get(std::vector<unsigned long> const& v) {
00076   if(v.empty())  return false;
00077   if(v[0] != CLHEP::engineIDulong<TRandomAdaptor>()) return false;
00078   int32_t numItems = v.size()-1;
00079 
00080   int32_t itemSize = sizeof(uint32_t);
00081   TBufferFile buffer(TBuffer::kRead, numItems * itemSize + 1024);
00082   char* bufferPtr = buffer.Buffer();
00083   for(int32_t i = 0; i < numItems; ++i) {
00084 
00085     *reinterpret_cast<uint32_t*>(bufferPtr + i * itemSize) = static_cast<uint32_t>(v[i+1] & 0xffffffff);
00086   }
00087 
00088   // Note that this will fail if the TRandom3 version (specifically the TStreamerInfo)
00089   // has changed between the time the state was saved and the time the following call
00090   // is made.  Because we are manually calling the Streamer function, the original
00091   // TStreamerInfo is not saved anywhere. Normally ROOT saves the TStreamerInfo
00092   // automatically.
00093   trand_->Streamer(buffer);
00094 
00095   return true;
00096 }
00097 
00098 void TRandomAdaptor::Grumble(std::string const& errortext) const {
00099 
00100 // Throw an edm::Exception for unimplemented functions
00101    std::ostringstream sstr;
00102    sstr << "Unimplemented Feature: " << errortext << '\n';
00103    edm::Exception except(edm::errors::UnimplementedFeature, sstr.str());
00104    throw except;
00105 }
00106 
00107 }  // namespace edm