00001
00002
00003 #include <stdexcept>
00004
00005 #include "cafe/Config.hpp"
00006 #include "cafe/RandomProcessor.hpp"
00007 #include "TFile.h"
00008
00009 #include <iomanip>
00010
00011 using std::endl;
00012
00013 namespace cafe {
00014
00015
00016 void patchedSetSeed (TRandom3& rnd, const UInt_t seed,
00017 const bool treatZeroAsSpecial, const int method, const int debug)
00018 {
00019
00020
00021 int anInt = 20060925;
00022 bool usedTimeStamp = false;
00023 if (seed == anInt) {
00024 rnd.SetSeed (seed);
00025 } else {
00026 if (treatZeroAsSpecial && seed == 0) {
00027 rnd.SetSeed (0);
00028 usedTimeStamp = true;
00029 } else {
00030 rnd.SetSeed (seed ^ anInt);
00031 }
00032 }
00033 if (debug) std::cout<<"DBG patchedSetSeed Input: "<<seed
00034 <<" --> timestamp? "<<usedTimeStamp<<", seed: "<<rnd.GetSeed()<<endl;
00035
00036 if (usedTimeStamp) {
00037
00038 if (method == 1) {
00039
00040 UInt_t myRandomSeed = rnd.Integer (0xFFffFFff);
00041 time_t now;
00042 time(&now);
00043 UInt_t myRandomSeedWithTime = myRandomSeed + (UInt_t) now;
00044 if (myRandomSeedWithTime < 10000) myRandomSeedWithTime ^= 20050823;
00045 if (debug) std::cout<<"DBG patchedSetSeed avoiding v4 bug. myRandomSeed: "<<myRandomSeed<<" ^ I(time): "<<UInt_t (now)
00046 <<" --> myRandomSeedWithTime: "<<myRandomSeedWithTime<<endl;
00047 rnd.SetSeed (myRandomSeedWithTime);
00048
00049 } else if (method == 2) {
00050 for (int it=0; it<700; ++it) rnd.Uniform();
00051 if (debug) std::cout<<"DBG patchedSetSeed, after discarding some numbers RandomSeed: "<<rnd.GetSeed()<<endl;
00052 }
00053 }
00054 }
00055
00056
00057
00058 RandomProcessor::RandomProcessor () :
00059 Processor()
00060 {
00061
00062 _eventKey = false;
00063 _rnd.SetSeed (0);
00064 }
00065
00066
00067 RandomProcessor::RandomProcessor(const char *name) :
00068 Processor(name)
00069 {
00070
00071
00072 Config config(name);
00073 _eventKey = config.get("EventKey", true);
00074 _seed = config.get("Seed", 0);
00075 _mTable = config.get("TableSize", 10000);
00076 _ROOT4patch = config.get("ROOT4patch", 1);
00077 int debug = config.get("DebugConstructor", 0);
00078 _ignoreDirectory = config.get("IgnoreDirectory", false);
00079 _nFirstCharsToIgnore = config.get("NFirstCharsToIgnore", 0);
00080 _nLastCharsToIgnore = config.get("NLastCharsToIgnore", 0);
00081 _addPrefix = config.get("AddPrefix", "");
00082
00083 if (_eventKey && _mTable <= 100) throw std::runtime_error("RandomProcessor: table size too small");
00084
00085
00086
00087 if (_seed == 0 && _eventKey) {
00088 patchedSetSeed (_rnd, hashString (name), false, 1, debug);
00089 out()<<" RandomProcessor["<<name<<"]: Seed==0, so took it from processor name ("
00090 <<name<<" --> "<<_rnd.GetSeed()<<")"<<endl;
00091 } else {
00092 patchedSetSeed (_rnd, _seed, true, 1, debug);
00093 }
00094
00095
00096 if (_eventKey) {
00097 out()<<" RandomProcessor["<<name<<"]: Will reseed random generator per event, based on filename and event #"<<endl;
00098 if (_ignoreDirectory || _nFirstCharsToIgnore || _nLastCharsToIgnore || _addPrefix.Length()) {
00099 out()<<" Each file's path will be processes as follows:"<<endl;
00100 if (_ignoreDirectory) out()<<" Ignoring directories"<<endl;
00101 if (_nFirstCharsToIgnore) out()<<" Ignoring the first "<<_nFirstCharsToIgnore<<" characters"<<endl;
00102 if (_nLastCharsToIgnore) out()<<" Ignoring the last "<<_nFirstCharsToIgnore<<" characters"<<endl;
00103 if (_addPrefix.Length()) out()<<" Adding the prefix: "<<_addPrefix<<endl;
00104 }
00105 } else {
00106 out()<<" RandomProcessor["<<name<<"]: Seed is "<<_rnd.GetSeed()<<" (from input "<<_seed<<"), it will not be reinitialized."<<endl;
00107 }
00108
00109
00110 if (_eventKey) {
00111 if (debug) out()<<"Debugging constructor. Pre-table we have seed: "<<_rnd.GetSeed()<<" (from input "<<_seed<<"), and"
00112 <<" _mTable: "<<_mTable<<endl;
00113 for (int i=0; i<_mTable; ++i) {
00114 _seeds.push_back (_rnd.Integer (0xffFFffFFu));
00115 if (debug > 9) out()<<"i: "<<i<<", l: "<<_seeds.size()<<", s: "<<_seeds[i]<<endl;
00116 }
00117 }
00118 }
00119
00120 void RandomProcessor::inputFileOpened(TFile* file)
00121 {
00122 if (_eventKey) {
00123 TString filename = file->GetName();
00124
00125 if (debug() > 40) out()<<"RandomProcessor::inputFileOpened name from ROOT: "<<filename<<endl;
00126
00127 if (_ignoreDirectory) {
00128 filename = gSystem->BaseName(filename);
00129 }
00130 if (_nFirstCharsToIgnore) {
00131 filename.Remove (0, _nFirstCharsToIgnore);
00132 }
00133 if (_nLastCharsToIgnore) {
00134 if (!filename.EndsWith (".root")) throw std::runtime_error ("RandomProcessor::inputFileOpened ["+name()
00135 +"] when using the NLastCharsToIgnore option, all "
00136 +"input file names must end with \".root\".");
00137 filename.Remove (TMath::Max(0, filename.Length() - 5 - _nLastCharsToIgnore), _nLastCharsToIgnore);
00138 }
00139 filename.Prepend (_addPrefix);
00140
00141 _fileHash = hashString (filename);
00142 if (debug() > 5) out()<<"_fileHash: "<<_fileHash<<" <--- "<<filename<<endl;
00143 }
00144 }
00145
00146 bool RandomProcessor::processEvent(cafe::Event& event)
00147 {
00148 if (_eventKey) {
00149
00150 TTree* ptree = event.getTree();
00151 if (ptree == 0) throw std::runtime_error ("event's tree pointer is NULL!");
00152 Long64_t iEvent = ptree->GetReadEntry();
00153
00154 UInt_t rawindex = (UInt_t (iEvent) ^ _fileHash);
00155 if (debug() > 99) out()<<"iEvent: "<<iEvent<<", rawindex: "<<rawindex<<" -> ["<<(rawindex % _mTable)<<"]"<<endl;
00156 UInt_t newseed = _seeds [rawindex % _mTable];
00157 patchedSetSeed (_rnd, newseed, false, 1, debug());
00158 if (debug() > 29) out()<<"iEvent: "<<iEvent<<", newseed: "<<newseed<<" -> "<<_rnd.GetSeed()<<endl;
00159 }
00160
00161 return true;
00162 }
00163 }
00164
00165 ClassImp(cafe::RandomProcessor)
00166
00167