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