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