CLHEP VERSION Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

RanluxEngine.cc
Go to the documentation of this file.
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