Geant4 Cross Reference |
1 // -*- C++ -*- 2 // 3 // ----------------------------------------------------------------------- 4 // HEP Random 5 // --- RandFlat --- 6 // class implementation file 7 // ----------------------------------------------------------------------- 8 // This file is part of Geant4 (simulation toolkit for HEP). 9 10 // ======================================================================= 11 // Gabriele Cosmo - Created: 17th May 1995 12 // - Added methods to shoot arrays: 28th July 1997 13 // - Added operator(): 24th Jul 1997 14 // J.Marraffino - Added default arguments as attributes and 15 // operator() with arguments: 16th Feb 1998 16 // M Fischler - Copy constructor should supply right engine to HepRandom: 17 // 1/26/00. 18 // M Fischler - Semi-fix to the saveEngineStatus misbehavior causing 19 // non-reproducing shootBit() 3/1/00. 20 // M Fischler - Avoiding hang when file not found in restoreEngineStatus 21 // 12/3/04 22 // M Fischler - put and get to/from streams 12/10/04 23 // M Fischler - save and restore dist to streams 12/20/04 24 // M Fischler - put/get to/from streams uses pairs of ulongs when 25 // + storing doubles avoid problems with precision 26 // 4/14/05 27 // ======================================================================= 28 29 #include "CLHEP/Random/RandFlat.h" 30 #include "CLHEP/Random/DoubConv.h" 31 #include <iostream> 32 #include <string> 33 #include <string.h> // for strcmp 34 #include <vector> 35 36 namespace CLHEP { 37 38 const int RandFlat::MSBBits= 15; 39 const unsigned long RandFlat::MSB= 1ul<<RandFlat::MSBBits; 40 CLHEP_THREAD_LOCAL unsigned long RandFlat::staticRandomInt= 0; 41 CLHEP_THREAD_LOCAL unsigned long RandFlat::staticFirstUnusedBit= 0; 42 43 std::string RandFlat::name() const {return "RandFlat";} 44 HepRandomEngine & RandFlat::engine() {return *localEngine;} 45 46 RandFlat::~RandFlat() { 47 } 48 49 double RandFlat::operator()() { 50 return fire( defaultA, defaultB ); 51 } 52 53 double RandFlat::operator()( double w ) { 54 return fire( w ); 55 } 56 57 double RandFlat::operator()( double a, double b ) { 58 return fire( a, b ); 59 } 60 61 double RandFlat::shoot() { 62 return HepRandom::getTheEngine()->flat(); 63 } 64 65 void RandFlat::shootArray(const int size, double* vect) { 66 HepRandom::getTheEngine()->flatArray(size,vect); 67 } 68 69 void RandFlat::shootArray( const int size, double* vect, 70 double lx, double dx ) 71 { 72 int i; 73 74 for (i=0; i<size; ++i) 75 vect[i] = shoot(lx,dx); 76 } 77 78 void RandFlat::shootArray( HepRandomEngine* anEngine, 79 const int size, double* vect, 80 double lx, double dx ) 81 { 82 int i; 83 84 for (i=0; i<size; ++i) 85 vect[i] = shoot(anEngine,lx,dx); 86 } 87 88 void RandFlat::fireArray( const int size, double* vect) 89 { 90 int i; 91 92 for (i=0; i<size; ++i) 93 vect[i] = fire( defaultA, defaultB ); 94 } 95 96 void RandFlat::fireArray( const int size, double* vect, 97 double lx, double dx ) 98 { 99 int i; 100 101 for (i=0; i<size; ++i) 102 vect[i] = fire( lx, dx ); 103 } 104 105 void RandFlat::saveEngineStatus ( const char filename[] ) { 106 107 // First save the engine status just like the base class would do: 108 getTheEngine()->saveStatus( filename ); 109 110 // Now append the cached random Int, and first unused bit: 111 112 std::ofstream outfile ( filename, std::ios::app ); 113 114 outfile << "RANDFLAT staticRandomInt: " << staticRandomInt 115 << " staticFirstUnusedBit: " << staticFirstUnusedBit << "\n"; 116 117 } // saveEngineStatus 118 119 120 void RandFlat::restoreEngineStatus( const char filename[] ) { 121 122 // First restore the engine status just like the base class would do: 123 getTheEngine()->restoreStatus( filename ); 124 125 // Now find the line describing the cached data: 126 127 std::ifstream infile ( filename, std::ios::in ); 128 if (!infile) return; 129 char inputword[] = "NO_KEYWORD "; // leaves room for 14 characters plus \0 130 while (true) { 131 infile.width(13); 132 infile >> inputword; 133 if (strcmp(inputword,"RANDFLAT")==0) break; 134 if (infile.eof()) break; 135 // If the file ends without the RANDFLAT line, that means this 136 // was a file produced by an earlier version of RandFlat. We will 137 // replicate the old behavior in that case: staticFirstUnusedBit 138 // and staticRandomInt retain their existing values. 139 } 140 141 // Then read and use the caching info: 142 143 if (strcmp(inputword,"RANDFLAT")==0) { 144 char setword[40]; // the longest, staticFirstUnusedBit: has length 21 145 infile.width(39); 146 infile >> setword; 147 // setword should be staticRandomInt: 148 infile >> staticRandomInt; 149 infile.width(39); 150 infile >> setword; 151 // setword should be staticFirstUnusedBit: 152 infile >> staticFirstUnusedBit; 153 } 154 155 } // restoreEngineStatus 156 157 std::ostream & RandFlat::put ( std::ostream & os ) const { 158 long pr=os.precision(20); 159 std::vector<unsigned long> t(2); 160 os << " " << name() << "\n"; 161 os << "Uvec" << "\n"; 162 os << randomInt << " " << firstUnusedBit << "\n"; 163 t = DoubConv::dto2longs(defaultWidth); 164 os << defaultWidth << " " << t[0] << " " << t[1] << "\n"; 165 t = DoubConv::dto2longs(defaultA); 166 os << defaultA << " " << t[0] << " " << t[1] << "\n"; 167 t = DoubConv::dto2longs(defaultB); 168 os << defaultB << " " << t[0] << " " << t[1] << "\n"; 169 os.precision(pr); 170 return os; 171 } 172 173 std::istream & RandFlat::get ( std::istream & is ) { 174 std::string inName; 175 is >> inName; 176 if (inName != name()) { 177 is.clear(std::ios::badbit | is.rdstate()); 178 std::cerr << "Mismatch when expecting to read state of a " 179 << name() << " distribution\n" 180 << "Name found was " << inName 181 << "\nistream is left in the badbit state\n"; 182 return is; 183 } 184 if (possibleKeywordInput(is, "Uvec", randomInt)) { 185 std::vector<unsigned long> t(2); 186 is >> randomInt >> firstUnusedBit; 187 is >> defaultWidth >>t[0]>>t[1]; defaultWidth = DoubConv::longs2double(t); 188 is >> defaultA >> t[0] >> t[1]; defaultA = DoubConv::longs2double(t); 189 is >> defaultB >> t[0] >> t[1]; defaultB = DoubConv::longs2double(t); 190 if (!is) { 191 is.clear(std::ios::badbit | is.rdstate()); 192 std::cerr << "\nRandFlat input failed" 193 << "\nInput stream is probably mispositioned now." << std::endl; 194 return is; 195 } 196 return is; 197 } 198 // is >> randomInt encompassed by possibleKeywordInput 199 is >> firstUnusedBit; 200 is >> defaultWidth >> defaultA >> defaultB; 201 return is; 202 } 203 204 std::ostream & RandFlat::saveDistState ( std::ostream & os ) { 205 os << distributionName() << "\n"; 206 long prec = os.precision(20); 207 os << "RANDFLAT staticRandomInt: " << staticRandomInt 208 << " staticFirstUnusedBit: " << staticFirstUnusedBit << "\n"; 209 os.precision(prec); 210 return os; 211 } 212 213 std::istream & RandFlat::restoreDistState ( std::istream & is ) { 214 std::string inName; 215 is >> inName; 216 if (inName != distributionName()) { 217 is.clear(std::ios::badbit | is.rdstate()); 218 std::cerr << "Mismatch when expecting to read static state of a " 219 << distributionName() << " distribution\n" 220 << "Name found was " << inName 221 << "\nistream is left in the badbit state\n"; 222 return is; 223 } 224 std::string keyword; 225 std::string c1; 226 std::string c2; 227 is >> keyword; 228 if (keyword!="RANDFLAT") { 229 is.clear(std::ios::badbit | is.rdstate()); 230 std::cerr << "Mismatch when expecting to read RANDFLAT bit cache info: " 231 << keyword << "\n"; 232 return is; 233 } 234 is >> c1 >> staticRandomInt >> c2 >> staticFirstUnusedBit; 235 return is; 236 } 237 238 std::ostream & RandFlat::saveFullState ( std::ostream & os ) { 239 HepRandom::saveFullState(os); 240 saveDistState(os); 241 return os; 242 } 243 244 std::istream & RandFlat::restoreFullState ( std::istream & is ) { 245 HepRandom::restoreFullState(is); 246 restoreDistState(is); 247 return is; 248 } 249 250 251 } // namespace CLHEP 252 253