CLHEP VERSION Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 // $Id: RanluxEngine.cc,v 1.6 2010/06/16 17:24:53 garren Exp $ 00002 // -*- C++ -*- 00003 // 00004 // ----------------------------------------------------------------------- 00005 // HEP Random 00006 // --- RanluxEngine --- 00007 // class implementation file 00008 // ----------------------------------------------------------------------- 00009 // This file is part of Geant4 (simulation toolkit for HEP). 00010 // 00011 // Ranlux random number generator originally implemented in FORTRAN77 00012 // by Fred James as part of the MATHLIB HEP library. 00013 // 'RanluxEngine' is designed to fit into the CLHEP random number 00014 // class structure. 00015 00016 // =============================================================== 00017 // Adeyemi Adesanya - Created: 6th November 1995 00018 // Gabriele Cosmo - Adapted & Revised: 22nd November 1995 00019 // Adeyemi Adesanya - Added setSeeds() method: 2nd February 1996 00020 // Gabriele Cosmo - Added flatArray() method: 8th February 1996 00021 // - Minor corrections: 31st October 1996 00022 // - Added methods for engine status: 19th November 1996 00023 // - Fixed bug in setSeeds(): 15th September 1997 00024 // J.Marraffino - Added stream operators and related constructor. 00025 // Added automatic seed selection from seed table and 00026 // engine counter: 14th Feb 1998 00027 // - Fixed bug: setSeeds() requires a zero terminated 00028 // array of seeds: 19th Feb 1998 00029 // Ken Smith - Added conversion operators: 6th Aug 1998 00030 // J. Marraffino - Remove dependence on hepString class 13 May 1999 00031 // M. Fischler - In restore, checkFile for file not found 03 Dec 2004 00032 // M. Fischler - Methods put, getfor instance save/restore 12/8/04 00033 // M. Fischler - split get() into tag validation and 00034 // getState() for anonymous restores 12/27/04 00035 // M. Fischler - put/get for vectors of ulongs 3/14/05 00036 // M. Fischler - State-saving using only ints, for portability 4/12/05 00037 // 00038 // =============================================================== 00039 00040 #include "CLHEP/Random/defs.h" 00041 #include "CLHEP/Random/Random.h" 00042 #include "CLHEP/Random/RanluxEngine.h" 00043 #include "CLHEP/Random/engineIDulong.h" 00044 #include <string.h> // for strcmp 00045 #include <cstdlib> // for std::abs(int) 00046 00047 #ifdef TRACE_IO 00048 #include "CLHEP/Random/DoubConv.hh" 00049 bool flat_trace = false; 00050 #endif 00051 00052 namespace CLHEP { 00053 00054 00055 static const int MarkerLen = 64; // Enough room to hold a begin or end marker. 00056 00057 std::string RanluxEngine::name() const {return "RanluxEngine";} 00058 00059 // Number of instances with automatic seed selection 00060 int RanluxEngine::numEngines = 0; 00061 00062 // Maximum index into the seed table 00063 int RanluxEngine::maxIndex = 215; 00064 00065 RanluxEngine::RanluxEngine(long seed, int lux) 00066 : HepRandomEngine() 00067 { 00068 long seedlist[2]={0,0}; 00069 00070 luxury = lux; 00071 setSeed(seed, luxury); 00072 00073 // setSeeds() wants a zero terminated array! 00074 seedlist[0]=theSeed; 00075 seedlist[1]=0; 00076 setSeeds(seedlist, luxury); 00077 } 00078 00079 RanluxEngine::RanluxEngine() 00080 : HepRandomEngine() 00081 { 00082 long seed; 00083 long seedlist[2]={0,0}; 00084 00085 luxury = 3; 00086 int cycle = std::abs(int(numEngines/maxIndex)); 00087 int curIndex = std::abs(int(numEngines%maxIndex)); 00088 numEngines +=1; 00089 long mask = ((cycle & 0x007fffff) << 8); 00090 HepRandom::getTheTableSeeds( seedlist, curIndex ); 00091 seed = seedlist[0]^mask; 00092 setSeed(seed, luxury); 00093 00094 // setSeeds() wants a zero terminated array! 00095 seedlist[0]=theSeed; 00096 seedlist[1]=0; 00097 setSeeds(seedlist, luxury); 00098 } 00099 00100 RanluxEngine::RanluxEngine(int rowIndex, int colIndex, int lux) 00101 : HepRandomEngine() 00102 { 00103 long seed; 00104 long seedlist[2]={0,0}; 00105 00106 luxury = lux; 00107 int cycle = std::abs(int(rowIndex/maxIndex)); 00108 int row = std::abs(int(rowIndex%maxIndex)); 00109 int col = std::abs(int(colIndex%2)); 00110 long mask = (( cycle & 0x000007ff ) << 20 ); 00111 HepRandom::getTheTableSeeds( seedlist, row ); 00112 seed = ( seedlist[col] )^mask; 00113 setSeed(seed, luxury); 00114 00115 // setSeeds() wants a zero terminated array! 00116 seedlist[0]=theSeed; 00117 seedlist[1]=0; 00118 setSeeds(seedlist, luxury); 00119 } 00120 00121 RanluxEngine::RanluxEngine( std::istream& is ) 00122 : HepRandomEngine() 00123 { 00124 is >> *this; 00125 } 00126 00127 RanluxEngine::~RanluxEngine() {} 00128 00129 void RanluxEngine::setSeed(long seed, int lux) { 00130 00131 // The initialisation is carried out using a Multiplicative 00132 // Congruential generator using formula constants of L'Ecuyer 00133 // as described in "A review of pseudorandom number generators" 00134 // (Fred James) published in Computer Physics Communications 60 (1990) 00135 // pages 329-344 00136 00137 const int ecuyer_a = 53668; 00138 const int ecuyer_b = 40014; 00139 const int ecuyer_c = 12211; 00140 const int ecuyer_d = 2147483563; 00141 00142 const int lux_levels[5] = {0,24,73,199,365}; 00143 00144 long int_seed_table[24]; 00145 long next_seed = seed; 00146 long k_multiple; 00147 int i; 00148 00149 // number of additional random numbers that need to be 'thrown away' 00150 // every 24 numbers is set using luxury level variable. 00151 00152 theSeed = seed; 00153 if( (lux > 4)||(lux < 0) ){ 00154 if(lux >= 24){ 00155 nskip = lux - 24; 00156 }else{ 00157 nskip = lux_levels[3]; // corresponds to default luxury level 00158 } 00159 }else{ 00160 luxury = lux; 00161 nskip = lux_levels[luxury]; 00162 } 00163 00164 00165 for(i = 0;i != 24;i++){ 00166 k_multiple = next_seed / ecuyer_a; 00167 next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a) 00168 - k_multiple * ecuyer_c ; 00169 if(next_seed < 0)next_seed += ecuyer_d; 00170 int_seed_table[i] = next_seed % int_modulus; 00171 } 00172 00173 for(i = 0;i != 24;i++) 00174 float_seed_table[i] = int_seed_table[i] * mantissa_bit_24(); 00175 00176 i_lag = 23; 00177 j_lag = 9; 00178 carry = 0. ; 00179 00180 if( float_seed_table[23] == 0. ) carry = mantissa_bit_24(); 00181 00182 count24 = 0; 00183 } 00184 00185 void RanluxEngine::setSeeds(const long *seeds, int lux) { 00186 00187 const int ecuyer_a = 53668; 00188 const int ecuyer_b = 40014; 00189 const int ecuyer_c = 12211; 00190 const int ecuyer_d = 2147483563; 00191 00192 const int lux_levels[5] = {0,24,73,199,365}; 00193 int i; 00194 long int_seed_table[24]; 00195 long k_multiple,next_seed; 00196 const long *seedptr; 00197 00198 theSeeds = seeds; 00199 seedptr = seeds; 00200 00201 if(seeds == 0){ 00202 setSeed(theSeed,lux); 00203 theSeeds = &theSeed; 00204 return; 00205 } 00206 00207 theSeed = *seeds; 00208 00209 // number of additional random numbers that need to be 'thrown away' 00210 // every 24 numbers is set using luxury level variable. 00211 00212 if( (lux > 4)||(lux < 0) ){ 00213 if(lux >= 24){ 00214 nskip = lux - 24; 00215 }else{ 00216 nskip = lux_levels[3]; // corresponds to default luxury level 00217 } 00218 }else{ 00219 luxury = lux; 00220 nskip = lux_levels[luxury]; 00221 } 00222 00223 for( i = 0;(i != 24)&&(*seedptr != 0);i++){ 00224 int_seed_table[i] = *seedptr % int_modulus; 00225 seedptr++; 00226 } 00227 00228 if(i != 24){ 00229 next_seed = int_seed_table[i-1]; 00230 for(;i != 24;i++){ 00231 k_multiple = next_seed / ecuyer_a; 00232 next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a) 00233 - k_multiple * ecuyer_c ; 00234 if(next_seed < 0)next_seed += ecuyer_d; 00235 int_seed_table[i] = next_seed % int_modulus; 00236 } 00237 } 00238 00239 for(i = 0;i != 24;i++) 00240 float_seed_table[i] = int_seed_table[i] * mantissa_bit_24(); 00241 00242 i_lag = 23; 00243 j_lag = 9; 00244 carry = 0. ; 00245 00246 if( float_seed_table[23] == 0. ) carry = mantissa_bit_24(); 00247 00248 count24 = 0; 00249 } 00250 00251 void RanluxEngine::saveStatus( const char filename[] ) const 00252 { 00253 std::ofstream outFile( filename, std::ios::out ) ; 00254 if (!outFile.bad()) { 00255 outFile << "Uvec\n"; 00256 std::vector<unsigned long> v = put(); 00257 #ifdef TRACE_IO 00258 std::cout << "Result of v = put() is:\n"; 00259 #endif 00260 for (unsigned int i=0; i<v.size(); ++i) { 00261 outFile << v[i] << "\n"; 00262 #ifdef TRACE_IO 00263 std::cout << v[i] << " "; 00264 if (i%6==0) std::cout << "\n"; 00265 #endif 00266 } 00267 #ifdef TRACE_IO 00268 std::cout << "\n"; 00269 #endif 00270 } 00271 #ifdef REMOVED 00272 if (!outFile.bad()) { 00273 outFile << theSeed << std::endl; 00274 for (int i=0; i<24; ++i) 00275 outFile <<std::setprecision(20) << float_seed_table[i] << " "; 00276 outFile << std::endl; 00277 outFile << i_lag << " " << j_lag << std::endl; 00278 outFile << std::setprecision(20) << carry << " " << count24 << std::endl; 00279 outFile << luxury << " " << nskip << std::endl; 00280 } 00281 #endif 00282 } 00283 00284 void RanluxEngine::restoreStatus( const char filename[] ) 00285 { 00286 std::ifstream inFile( filename, std::ios::in); 00287 if (!checkFile ( inFile, filename, engineName(), "restoreStatus" )) { 00288 std::cerr << " -- Engine state remains unchanged\n"; 00289 return; 00290 } 00291 if ( possibleKeywordInput ( inFile, "Uvec", theSeed ) ) { 00292 std::vector<unsigned long> v; 00293 unsigned long xin; 00294 for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) { 00295 inFile >> xin; 00296 #ifdef TRACE_IO 00297 std::cout << "ivec = " << ivec << " xin = " << xin << " "; 00298 if (ivec%3 == 0) std::cout << "\n"; 00299 #endif 00300 if (!inFile) { 00301 inFile.clear(std::ios::badbit | inFile.rdstate()); 00302 std::cerr << "\nRanluxEngine state (vector) description improper." 00303 << "\nrestoreStatus has failed." 00304 << "\nInput stream is probably mispositioned now." << std::endl; 00305 return; 00306 } 00307 v.push_back(xin); 00308 } 00309 getState(v); 00310 return; 00311 } 00312 00313 if (!inFile.bad() && !inFile.eof()) { 00314 // inFile >> theSeed; removed -- encompased by possibleKeywordInput 00315 for (int i=0; i<24; ++i) 00316 inFile >> float_seed_table[i]; 00317 inFile >> i_lag; inFile >> j_lag; 00318 inFile >> carry; inFile >> count24; 00319 inFile >> luxury; inFile >> nskip; 00320 } 00321 } 00322 00323 void RanluxEngine::showStatus() const 00324 { 00325 std::cout << std::endl; 00326 std::cout << "--------- Ranlux engine status ---------" << std::endl; 00327 std::cout << " Initial seed = " << theSeed << std::endl; 00328 std::cout << " float_seed_table[] = "; 00329 for (int i=0; i<24; ++i) 00330 std::cout << float_seed_table[i] << " "; 00331 std::cout << std::endl; 00332 std::cout << " i_lag = " << i_lag << ", j_lag = " << j_lag << std::endl; 00333 std::cout << " carry = " << carry << ", count24 = " << count24 << std::endl; 00334 std::cout << " luxury = " << luxury << " nskip = " << nskip << std::endl; 00335 std::cout << "----------------------------------------" << std::endl; 00336 } 00337 00338 double RanluxEngine::flat() { 00339 00340 float next_random; 00341 float uni; 00342 int i; 00343 00344 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry; 00345 #ifdef TRACE_IO 00346 if (flat_trace) { 00347 std::cout << "float_seed_table[" << j_lag << "] = " 00348 << float_seed_table[j_lag] 00349 << " float_seed_table[" << i_lag << "] = " << float_seed_table[i_lag] 00350 << " uni = " << uni << "\n"; 00351 std::cout << float_seed_table[j_lag] 00352 << " - " << float_seed_table[i_lag] 00353 << " - " << carry << " = " 00354 << (double)float_seed_table[j_lag] 00355 - (double) float_seed_table[i_lag] - (double)carry 00356 << "\n"; 00357 } 00358 #endif 00359 if(uni < 0. ){ 00360 uni += 1.0; 00361 carry = mantissa_bit_24(); 00362 }else{ 00363 carry = 0.; 00364 } 00365 00366 float_seed_table[i_lag] = uni; 00367 i_lag --; 00368 j_lag --; 00369 if(i_lag < 0) i_lag = 23; 00370 if(j_lag < 0) j_lag = 23; 00371 00372 if( uni < mantissa_bit_12() ){ 00373 uni += mantissa_bit_24() * float_seed_table[j_lag]; 00374 if( uni == 0) uni = mantissa_bit_24() * mantissa_bit_24(); 00375 } 00376 next_random = uni; 00377 count24 ++; 00378 00379 // every 24th number generation, several random numbers are generated 00380 // and wasted depending upon the luxury level. 00381 00382 if(count24 == 24 ){ 00383 count24 = 0; 00384 #ifdef TRACE_IO 00385 if (flat_trace) { 00386 std::cout << "carry = " << carry << "\n"; 00387 } 00388 #endif 00389 for( i = 0; i != nskip ; i++){ 00390 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry; 00391 if(uni < 0. ){ 00392 uni += 1.0; 00393 carry = mantissa_bit_24(); 00394 }else{ 00395 carry = 0.; 00396 } 00397 float_seed_table[i_lag] = uni; 00398 #ifdef TRACE_IO 00399 if (flat_trace) { 00400 double xfst = float_seed_table[i_lag]; 00401 std::cout << "fst[" << i_lag << "] = " 00402 << DoubConv::d2x(xfst) << "\n"; 00403 } 00404 #endif 00405 i_lag --; 00406 j_lag --; 00407 if(i_lag < 0)i_lag = 23; 00408 if(j_lag < 0) j_lag = 23; 00409 } 00410 } 00411 #ifdef TRACE_IO 00412 if (flat_trace) { 00413 std::cout << "next_random = " << next_random << "\n"; 00414 // flat_trace = false; 00415 } 00416 #endif 00417 return (double) next_random; 00418 } 00419 00420 void RanluxEngine::flatArray(const int size, double* vect) 00421 { 00422 float next_random; 00423 float uni; 00424 int i; 00425 int index; 00426 00427 for (index=0; index<size; ++index) { 00428 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry; 00429 if(uni < 0. ){ 00430 uni += 1.0; 00431 carry = mantissa_bit_24(); 00432 }else{ 00433 carry = 0.; 00434 } 00435 00436 float_seed_table[i_lag] = uni; 00437 i_lag --; 00438 j_lag --; 00439 if(i_lag < 0) i_lag = 23; 00440 if(j_lag < 0) j_lag = 23; 00441 00442 if( uni < mantissa_bit_12() ){ 00443 uni += mantissa_bit_24() * float_seed_table[j_lag]; 00444 if( uni == 0) uni = mantissa_bit_24() * mantissa_bit_24(); 00445 } 00446 next_random = uni; 00447 vect[index] = (double)next_random; 00448 count24 ++; 00449 00450 // every 24th number generation, several random numbers are generated 00451 // and wasted depending upon the luxury level. 00452 00453 if(count24 == 24 ){ 00454 count24 = 0; 00455 for( i = 0; i != nskip ; i++){ 00456 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry; 00457 if(uni < 0. ){ 00458 uni += 1.0; 00459 carry = mantissa_bit_24(); 00460 }else{ 00461 carry = 0.; 00462 } 00463 float_seed_table[i_lag] = uni; 00464 i_lag --; 00465 j_lag --; 00466 if(i_lag < 0)i_lag = 23; 00467 if(j_lag < 0) j_lag = 23; 00468 } 00469 } 00470 } 00471 } 00472 00473 RanluxEngine::operator unsigned int() { 00474 return ((unsigned int)(flat() * exponent_bit_32()) & 0xffffffff) | 00475 (((unsigned int)(float_seed_table[i_lag]*exponent_bit_32())>>16) & 0xff); 00476 // needed because Ranlux doesn't fill all bits of the double 00477 // which therefore doesn't fill all bits of the integer. 00478 } 00479 00480 std::ostream & RanluxEngine::put ( std::ostream& os ) const 00481 { 00482 char beginMarker[] = "RanluxEngine-begin"; 00483 os << beginMarker << "\nUvec\n"; 00484 std::vector<unsigned long> v = put(); 00485 for (unsigned int i=0; i<v.size(); ++i) { 00486 os << v[i] << "\n"; 00487 } 00488 return os; 00489 #ifdef REMOVED 00490 char endMarker[] = "RanluxEngine-end"; 00491 int pr = os.precision(20); 00492 os << " " << beginMarker << " "; 00493 os << theSeed << "\n"; 00494 for (int i=0; i<24; ++i) { 00495 os << float_seed_table[i] << "\n"; 00496 } 00497 os << i_lag << " " << j_lag << "\n"; 00498 os << carry << " " << count24 << " "; 00499 os << luxury << " " << nskip << "\n"; 00500 os << endMarker << "\n"; 00501 os.precision(pr); 00502 return os; 00503 #endif 00504 } 00505 00506 std::vector<unsigned long> RanluxEngine::put () const { 00507 std::vector<unsigned long> v; 00508 v.push_back (engineIDulong<RanluxEngine>()); 00509 #ifdef TRACE_IO 00510 std::cout << "RanluxEngine put: ID is " << v[0] << "\n"; 00511 #endif 00512 for (int i=0; i<24; ++i) { 00513 v.push_back 00514 (static_cast<unsigned long>(float_seed_table[i]/mantissa_bit_24())); 00515 #ifdef TRACE_IO 00516 std::cout << "v[" << i+1 << "] = " << v[i+1] << 00517 " float_seed_table[" << i << "] = " << float_seed_table[i] << "\n"; 00518 #endif 00519 } 00520 v.push_back(static_cast<unsigned long>(i_lag)); 00521 v.push_back(static_cast<unsigned long>(j_lag)); 00522 v.push_back(static_cast<unsigned long>(carry/mantissa_bit_24())); 00523 v.push_back(static_cast<unsigned long>(count24)); 00524 v.push_back(static_cast<unsigned long>(luxury)); 00525 v.push_back(static_cast<unsigned long>(nskip)); 00526 #ifdef TRACE_IO 00527 std::cout << "i_lag: " << v[25] << " j_lag: " << v[26] 00528 << " carry: " << v[27] << "\n"; 00529 std::cout << "count24: " << v[28] << " luxury: " << v[29] 00530 << " nskip: " << v[30] << "\n"; 00531 #endif 00532 #ifdef TRACE_IO 00533 flat_trace = true; 00534 #endif 00535 return v; 00536 } 00537 00538 std::istream & RanluxEngine::get ( std::istream& is ) 00539 { 00540 char beginMarker [MarkerLen]; 00541 is >> std::ws; 00542 is.width(MarkerLen); // causes the next read to the char* to be <= 00543 // that many bytes, INCLUDING A TERMINATION \0 00544 // (Stroustrup, section 21.3.2) 00545 is >> beginMarker; 00546 if (strcmp(beginMarker,"RanluxEngine-begin")) { 00547 is.clear(std::ios::badbit | is.rdstate()); 00548 std::cerr << "\nInput stream mispositioned or" 00549 << "\nRanluxEngine state description missing or" 00550 << "\nwrong engine type found." << std::endl; 00551 return is; 00552 } 00553 return getState(is); 00554 } 00555 00556 std::string RanluxEngine::beginTag ( ) { 00557 return "RanluxEngine-begin"; 00558 } 00559 00560 std::istream & RanluxEngine::getState ( std::istream& is ) 00561 { 00562 if ( possibleKeywordInput ( is, "Uvec", theSeed ) ) { 00563 std::vector<unsigned long> v; 00564 unsigned long uu; 00565 for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) { 00566 is >> uu; 00567 if (!is) { 00568 is.clear(std::ios::badbit | is.rdstate()); 00569 std::cerr << "\nRanluxEngine state (vector) description improper." 00570 << "\ngetState() has failed." 00571 << "\nInput stream is probably mispositioned now." << std::endl; 00572 return is; 00573 } 00574 v.push_back(uu); 00575 #ifdef TRACE_IO 00576 std::cout << "RanluxEngine::getState -- v[" << v.size()-1 00577 << "] = " << v[v.size()-1] << "\n"; 00578 #endif 00579 } 00580 getState(v); 00581 return (is); 00582 } 00583 00584 // is >> theSeed; Removed, encompassed by possibleKeywordInput() 00585 00586 char endMarker [MarkerLen]; 00587 for (int i=0; i<24; ++i) { 00588 is >> float_seed_table[i]; 00589 } 00590 is >> i_lag; is >> j_lag; 00591 is >> carry; is >> count24; 00592 is >> luxury; is >> nskip; 00593 is >> std::ws; 00594 is.width(MarkerLen); 00595 is >> endMarker; 00596 if (strcmp(endMarker,"RanluxEngine-end")) { 00597 is.clear(std::ios::badbit | is.rdstate()); 00598 std::cerr << "\nRanluxEngine state description incomplete." 00599 << "\nInput stream is probably mispositioned now." << std::endl; 00600 return is; 00601 } 00602 return is; 00603 } 00604 00605 bool RanluxEngine::get (const std::vector<unsigned long> & v) { 00606 if ((v[0] & 0xffffffffUL) != engineIDulong<RanluxEngine>()) { 00607 std::cerr << 00608 "\nRanluxEngine get:state vector has wrong ID word - state unchanged\n"; 00609 return false; 00610 } 00611 return getState(v); 00612 } 00613 00614 bool RanluxEngine::getState (const std::vector<unsigned long> & v) { 00615 if (v.size() != VECTOR_STATE_SIZE ) { 00616 std::cerr << 00617 "\nRanluxEngine get:state vector has wrong length - state unchanged\n"; 00618 return false; 00619 } 00620 for (int i=0; i<24; ++i) { 00621 float_seed_table[i] = v[i+1]*mantissa_bit_24(); 00622 #ifdef TRACE_IO 00623 std::cout << 00624 "float_seed_table[" << i << "] = " << float_seed_table[i] << "\n"; 00625 #endif 00626 } 00627 i_lag = v[25]; 00628 j_lag = v[26]; 00629 carry = v[27]*mantissa_bit_24(); 00630 count24 = v[28]; 00631 luxury = v[29]; 00632 nskip = v[30]; 00633 #ifdef TRACE_IO 00634 std::cout << "i_lag: " << i_lag << " j_lag: " << j_lag 00635 << " carry: " << carry << "\n"; 00636 std::cout << "count24: " << count24 << " luxury: " << luxury 00637 << " nskip: " << nskip << "\n"; 00638 00639 #endif 00640 #ifdef TRACE_IO 00641 flat_trace = true; 00642 #endif 00643 return true; 00644 } 00645 00646 } // namespace CLHEP