00001 #include "emcDB.h"
00002 
00003 #include "emcDataManager.h"
00004 #include "emcDefines.h"
00005 #include "emcGains.h"
00006 #include "emcHLRatios.h"
00007 #include "emcPedestals.h"
00008 #include "emcLCTofs.h"
00009 #include "emcWalkTofs.h"
00010 #include "emcTofT0s.h"
00011 #include "emcQAs.h"
00012 #include "emcRawDataAccessor.h"
00013 #include "emcCalFEM.h"
00014 #include "emcCalFEMFactory.h"
00015 #include "fileEventiterator.h"
00016 #include "EmcIndexer.h"
00017 #include "emcTracedFEM.h"
00018 #include "emcTracedValue.h"
00019 #include "emcGainFEM.h"
00020 #include "emcDefines.h"
00021 #include "RunTimesFactory.h"
00022 #include "TStopwatch.h"
00023 #include "emcCalibrationData.h"
00024 #include "emcRejectList.h"
00025 #include "emcConfigurationFile.h"
00026 #include "emcOMHelper.h"
00027 #include "emcOMCalFEMT.h"
00028 #include "PHTimeStamp.h"
00029 #include <typeinfo>
00030 #include <algorithm>
00031 #include <iomanip>
00032 #include <ctime>
00033 #include <cstdlib>
00034 #include <cstdio>
00035 #include <cassert>
00036 #include <stdexcept>
00037 #include <string>
00038 #include <list>
00039 #include <vector>
00040 #include <set>
00041 #include <fstream>
00042 #include <sstream>
00043 #include <memory>
00044 #include "TROOT.h"
00045 #include "TSystem.h"
00046 
00047 #include "PdbApplication.hh"
00048 #include "PdbBankManagerFactory.hh"
00049 #include "PdbBankID.hh"
00050 #include "PdbCalBank.hh"
00051 #include "PdbCalBankIterator.hh"
00052 #include "RunToTime.hh"
00053 
00054 using namespace std;
00055 
00056 
00057 int
00058 isRunNumber(const std::string str)
00059 {
00060   
00061   if (str.size()!=10) return -1;
00062 
00063   for ( size_t i = 0; i < 10; ++i )
00064     {
00065       if (!isdigit(str[i])) return -1;
00066     }
00067   return atoi(str.c_str());
00068 }
00069 
00070 
00071 std::string
00072 getTofT0Flavor(const std::string filename)
00073 {
00074   std::ifstream in(filename.c_str());
00075   assert(in.good());
00076   char str[1024];
00077 
00078   in.getline(str,1024,'\n');
00079 
00080   int channel=-1;
00081   float dummy;
00082 
00083   while ( in >> channel >> dummy >> dummy >>dummy )
00084     {
00085       std::cout << channel << std::endl;
00086     }
00087 
00088   assert(channel>=144);
00089 
00090   if (channel>=146)
00091     {
00092       return "TofT0Bs";
00093     }
00094   else
00095     {
00096       return "TofT0s";
00097     }
00098 }
00099 
00100 
00101 bool isInitialCalibrationDirectory(const char* dir)
00102 {
00103   char* cdir = gSystem->ExpandPathName(dir);
00104   void* dirp = gSystem->OpenDirectory(cdir);
00105 
00106   const char* entry;
00107 
00108   bool ok = false;
00109 
00110   while ( (entry = gSystem->GetDirEntry(dirp)) )
00111     {
00112       string str = entry;
00113 
00114       if ( str.find("INICAL") < str.size() )
00115         {
00116           ok = true;
00117         }
00118     }
00119 
00120   gSystem->FreeDirectory(dirp);
00121   delete[] cdir;
00122 
00123   return ok;
00124 }
00125 
00126 
00127 bool isRejectListDirectory(const char* dir)
00128 {
00129   char* cdir = gSystem->ExpandPathName(dir);
00130   void* dirp = gSystem->OpenDirectory(cdir);
00131 
00132   const char* entry;
00133 
00134   bool ok = false;
00135 
00136   while ( (entry = gSystem->GetDirEntry(dirp)) )
00137     {
00138       string str = entry;
00139 
00140       if ( str == "reject.list" )
00141         {
00142           ok = true;
00143         }
00144     }
00145 
00146   gSystem->FreeDirectory(dirp);
00147   delete[] cdir;
00148   return ok;
00149 }
00150 
00151 
00152 emcDB::emcDB(const char* dbms,
00153              const char* dbname,
00154              bool interactive, PHTimeStamp* ts, PHTimeStamp* tsend)
00155 {
00156   fDBMS = dbms;
00157   fDbname = dbname;
00158   initDBMS(fDBMS.c_str());
00159   fInteractive = interactive;
00160   fForceDate = ts;
00161   fForceEndDate = tsend;
00162   fInsertAfter.setTics(0);
00163   fInsertBefore.setToFarFuture();
00164   fStartAfter.setTics(0);
00165   fStartBefore.setToFarFuture();
00166   fEndAfter.setTics(0);
00167   fEndBefore.setToFarFuture();
00168   fDebug = false;
00169   fStartIntervalGiven = false;
00170   fEndIntervalGiven = false;
00171   fInsertIntervalGiven = false;
00172 }
00173 
00174 
00175 emcDB::~emcDB()
00176 {}
00177 
00178 
00179 void
00180 emcDB::Abort(const string& method, const string& message)
00181 {
00182   Error(method, message);
00183   BankManager()->getApplication()->abort();
00184   exit(1);
00185 }
00186 
00187 
00188 int
00189 emcDB::AbsolutePosition(const string& femName)
00190 {
00191   Int_t rv = -1;
00192 
00193   if (femName.substr(0, 8) == "FEM.EMC.")
00194     {
00195 
00196       string sector = femName.substr(8, 2);
00197       int sn = EmcIndexer::EmcSectorNumber(sector.c_str());
00198 
00199       int sm144;
00200 
00201       if ( sn >= 0 && femName.substr(11, 2) == "SM")
00202         {
00203 
00204           sm144 = atoi(femName.substr(13, 2).c_str());
00205           rv = EmcIndexer::iSiSM144_PXSM144(sn, sm144);
00206         }
00207     }
00208 
00209   return rv;
00210 }
00211 
00212 
00213 PdbBankManager*
00214 emcDB::BankManager()
00215 {
00216   static PdbBankManager* bankManager =
00217     PdbBankManagerFactory::instance().create(fDBMS.c_str());
00218   if (!bankManager)
00219     {
00220       std::cerr << "<FATAL> Do not know how to deal with this dbms = "
00221                 << fDBMS << std::endl;
00222       exit(1);
00223     }
00224   return bankManager;
00225 }
00226 
00227 
00228 int
00229 emcDB::Compare(PdbCalBank& bank, const string& dir,
00230                const string& flavour)
00231 {
00232   
00233   
00234   
00235 
00236   initDBMS("Ascii");
00237   const int kCannotReadFromFile = -1;
00238   const int kUnknownFlavour = -2;
00239   const int kPluginNotFound = -3;
00240 
00241   const int kSame = 1;
00242   const int kDifferent = 0;
00243 
00244   
00245 
00246   int femAbsolutePosition = bank.getBankID().getInternalValue();
00247 
00248   int femPinNumber = 0;
00249 
00250   if ( flavour == "Pedestals5" || flavour == "Pedestals" )
00251     {
00252       
00253       femPinNumber = GetPinNumber(femAbsolutePosition);
00254       cout << "FEM " << femAbsolutePosition << " has pinNumber="
00255            << femPinNumber << endl;
00256     }
00257 
00258   emcCalFEM* calfem1 = emcCalFEMFactory::Create(flavour.c_str(),
00259                                                 femAbsolutePosition);
00260 
00261   if (!calfem1)
00262     {
00263       return kUnknownFlavour;
00264     }
00265 
00266   
00267   calfem1->SetSource(destination());
00268   emcOMCalFEM* om = static_cast<emcOMCalFEM*>
00269     (emcOMHelper::findOM(*calfem1, 0));
00270   
00271   
00272   
00273   
00274   
00275   
00276   if (!om)
00277     {
00278       return kPluginNotFound;
00279     }
00280 
00281   om->FromPdbCalBank(*calfem1, bank);
00282 
00283   calfem1->SetValidityPeriod(bank.getStartValTime(), bank.getEndValTime());
00284 
00285   
00286 
00287   emcDataManager* dm = emcDataManager::GetInstance();
00288 
00289   string olddir = dm->GetSourceDir(); 
00290 
00291   dm->SetSourceDir(dir.c_str());
00292 
00293   emcCalFEM* calfem2 = emcCalFEMFactory::Create(flavour.c_str(),
00294                                                 femAbsolutePosition);
00295 
00296   calfem2->SetSource(emcManageable::kFile_ASCII);
00297 
00298   PHTimeStamp tdummy(0);
00299 
00300   int femCode = emcCalFEM::FEMCode(femAbsolutePosition, femPinNumber, 0, 0);
00301 
00302   bool ok = dm->Read(*calfem2, tdummy, femCode);
00303 
00304   dm->SetSourceDir(olddir.c_str()); 
00305 
00306   if (!ok)
00307     {
00308       return kCannotReadFromFile;
00309     }
00310 
00311   if ( *calfem1 != *calfem2 )
00312     {
00313 
00314       emcTracedFEM* tfem = dynamic_cast<emcTracedFEM*>(calfem2);
00315 
00316       if ( !tfem )
00317         {
00318           return kDifferent;
00319         }
00320 
00321       if ( EmcIndexer::isPbScFEM(femAbsolutePosition) )
00322         {
00323 
00324           
00325           if ( *calfem1 == *calfem2 )
00326             {
00327               return kSame;
00328             }
00329 
00330           std::auto_ptr<emcTracedFEM> test(tfem->clone());
00331 
00332           
00333 
00334           cout << "Performing Compact(0.02)" << endl;
00335 
00336           test->Compact(0.02);
00337 
00338           if ( *(test.get()) == *calfem1 )
00339             {
00340               return kSame;
00341             }
00342 
00343           
00344           
00345           
00346           
00347 
00348           cout << "Performing RemoveLastItems() and Compact(0.02)" << endl;
00349           tfem->RemoveLastItems();
00350           if ( tfem->GetNumberOfItems() < tfem->GetNumberOfChannels() )
00351             {
00352               return kDifferent;
00353             }
00354           else
00355             {
00356               tfem->Compact(0.02);
00357             }
00358         }
00359       else
00360         {
00361           UpdateXValue(*tfem, 0);
00362         }
00363 
00364       if ( *calfem1 != *calfem2)
00365         {
00366           return kDifferent;
00367         }
00368       else
00369         {
00370           return kSame;
00371         }
00372     }
00373 
00374   return kSame;
00375 }
00376 
00377 
00378 emcManageable::EStorage
00379 emcDB::destination() const
00380 {
00381   if ( fDBMS == "Objy" )
00382     {
00383       return emcManageable::kDB_Objy;
00384     }
00385   else if ( fDBMS == "Pg" )
00386     {
00387       return emcManageable::kDB_Pg;
00388     }
00389   else if ( fDBMS == "Ascii" )
00390     {
00391       return emcManageable::kFile_ASCII;
00392     }
00393   else
00394     {
00395       std::cerr << "emcDB::destination : unknown DBMS=" << fDBMS
00396                 << std::endl;
00397       exit(1);
00398     }
00399 }
00400 
00401 bool
00402 emcDB::Dump(const string fulldbname)
00403 {
00404   
00405   
00406   
00407   
00408   
00409   
00410 
00411   PdbCalBankIterator* it = BankManager()->getIterator();
00412 
00413   if (!it)
00414     {
00415       std::cerr << "emcDB::Dump : could not get a PdbCalBankIterator!"
00416                 << std::endl;
00417       ;
00418       return 0;
00419     }
00420 
00421   string bankName = fulldbname;
00422 
00423   cout << string(80, '-') << endl;
00424   cout << Version() << endl;
00425   cout << string(80, '-') << endl;
00426   cout << "Dumping " << bankName << " calibration database " << endl;
00427 
00428   PdbBankID bankID(fBankID);
00429 
00430   it->init(fulldbname.c_str(), bankID);
00431 
00432   if ( fInsertIntervalGiven )
00433     {
00434       it->setInsertTimeLimits(fInsertAfter, fInsertBefore);
00435     }
00436   if ( fStartIntervalGiven )
00437     {
00438       it->setStartValTimeLimits(fStartAfter, fStartBefore);
00439     }
00440   if ( fEndIntervalGiven )
00441     {
00442       it->setEndValTimeLimits(fEndAfter, fEndBefore);
00443     }
00444 
00445   it->print();
00446   cout << string(80, '-') << endl;
00447 
00448   string flavour;
00449 
00450   if ( bankName.find("calib.emc.") < bankName.size() )
00451     {
00452       flavour = bankName.substr(strlen("calib.emc."));
00453     }
00454 
00455   PdbCalBank* bank;
00456 
00457   while ( (bank = it->next()) )
00458     {
00459       bank->printHeader();
00460 
00461       if ( fInteractive == true )
00462         {
00463 
00464           cout << "[# of channels] Show channels [n] Next bank "
00465                << " [q] Quit, [c] Compare to file(s) " << endl;
00466           cout << "Please enter command >  ";
00467 
00468           string sanswer;
00469           cin >> sanswer;
00470 
00471           sanswer[0] = toupper(sanswer[0]);
00472 
00473           if ( sanswer == "C" )
00474             {
00475               CompareToDirectories(*bank, flavour);
00476             }
00477 
00478           if ( sanswer == "Q" )
00479             return Quit();
00480           if ( sanswer == "N" )
00481             continue;
00482 
00483           int nchannels = atoi(sanswer.c_str());
00484 
00485           DumpContent(*bank, nchannels);
00486         }
00487 
00488       delete bank;
00489     }
00490 
00491   return Quit();
00492 }
00493 
00494 
00495 
00496 void
00497 emcDB::CompareToDirectories(PdbCalBank& bank,
00498                             const string& flavour)
00499 {
00500   for (size_t j = 0; j < fDirectories.size(); j++ )
00501     {
00502       int compare = Compare(bank, fDirectories[j], flavour);
00503 
00504       if ( compare >= 0 )
00505         {
00506           string match = "MATCHES";
00507           if ( compare == 0 )
00508             {
00509               match = "DOES NOT match";
00510             }
00511           cout << match << " the one in "
00512                << fDirectories[j] << endl;
00513         }
00514       else
00515         {
00516           cout << "emcDB::CompareToDirectories  : "
00517                << "Cannot infer equality (return code "
00518                << compare << ")" << endl;
00519         }
00520     }
00521 }
00522 
00523 
00524 void
00525 emcDB::DumpContent(PdbCalBank& bank, int nchannels)
00526 {
00527   if (nchannels > 0)
00528     {
00529       for ( int i = 0;
00530             i < static_cast<int>(bank.getLength()) &&
00531               i < static_cast<int>(nchannels); i++)
00532         {
00533           bank.printEntry(i);
00534         }
00535     }
00536 }
00537 
00538 
00539 PHTimeStamp
00540 emcDB::EndOfValidity(void) const
00541 {
00542   if ( fForceEndDate )
00543     {
00544       return PHTimeStamp(*fForceEndDate);
00545     }
00546   else
00547     {
00548       PHTimeStamp end;
00549       end.setToFarFuture();
00550       return end;
00551     }
00552 }
00553 
00554 
00555 bool emcDB::Error(const string method, const string message)
00556 {
00557   cerr << "<E> emcDB::" << method << endl;
00558   cerr << "          :" << message << endl;
00559   return false;
00560 }
00561 
00562 
00563 int
00564 emcDB::GetPinNumber(int absPosition)
00565 {
00566   if (fPinNumbers.empty())
00567     {
00568       bool ok = ReadConfiguration(false);
00569       if (!ok)
00570         {
00571           cerr << EMC_ERROR_MSG
00572                << " Could not read configuration, thus pin numbers are not available"
00573                << "(i.e. you will not be able to properly compare pedestals)"
00574                << endl;
00575           fPinNumbers.resize(EmcIndexer::MaxNumberOfFEMs(), 0);
00576         }
00577     }
00578 
00579   return fPinNumbers[absPosition];
00580 }
00581 
00582 
00583 void
00584 emcDB::initDBMS(const char* dbms)
00585 {
00586   static std::set
00587     <std::string> alreadyLoaded;
00588 
00589   std::string DBMS = dbms;
00590 
00591   if ( alreadyLoaded.find(DBMS) != alreadyLoaded.end() )
00592     {
00593       return ;
00594     }
00595 
00596   
00597   if ( DBMS == "Objy" )
00598     {
00599       if ( !gSystem->Load("libemcOM.so") )
00600         {
00601           alreadyLoaded.insert("Objy");
00602         }
00603     }
00604   else if ( DBMS == "Pg" )
00605     {
00606       if ( !gSystem->Load("libemcOMpg.so") )
00607         {
00608           gSystem->Load("libPgCalInstance.so");
00609           PdbApplication* app = PdbApplication::instance();
00610           app->setDBName(fDbname.c_str());
00611           alreadyLoaded.insert("Pg");
00612         }
00613     }
00614   else if ( DBMS == "Ascii" )
00615     {
00616       if (!gSystem->Load("libemcOMascii.so"))
00617         {
00618           alreadyLoaded.insert("Ascii");
00619         }
00620     }
00621   else 
00622     {
00623       std::cerr << "emcDB::initDBMS : Do not know this DBMS : "
00624                 << DBMS << std::endl;
00625       exit(1);
00626     }
00627 }
00628 
00629 
00630 void emcDB::ParseFileName(const string filename, size_t& ifem, size_t& pin)
00631 {
00632   
00633   
00634   
00635   
00636 
00637   int iS; 
00638   int iSM144; 
00639 
00640   
00641   
00642 
00643   int offset = 0;
00644 
00645   if ( filename.substr(0, 4) == "NONE" )
00646     {
00647       iS = 8;
00648       offset = 2;
00649     }
00650   else
00651     {
00652       iS = EmcIndexer::EmcSectorNumber(const_cast<char*>(filename.substr(0, 2).c_str()));
00653     }
00654 
00655   iSM144 = atoi(filename.substr(4 + offset, 2).c_str());
00656 
00657   ifem = EmcIndexer::iSiSM144_PXSM144(iS, iSM144);
00658 
00659   size_t pos = filename.find("FEM");
00660 
00661   if (pos < filename.size())
00662     {
00663       pin = atoi(filename.substr(pos + 3, 4).c_str());
00664     }
00665   else
00666     {
00667       pin = 0;
00668     }
00669 }
00670 
00671 
00672 int emcDB::PedestalVersion(const string csdir)
00673 {
00674   string dir = csdir;
00675 
00676   char* cdir = gSystem->ExpandPathName(dir.c_str());
00677   void* dirp = gSystem->OpenDirectory(cdir);
00678   const char* entry;
00679   string str;
00680   int n = 0;
00681   int version = 0;
00682 
00683   assert(dirp != 0);
00684 
00685   while ( (version == 0) && (entry = gSystem->GetDirEntry(dirp)) )
00686     {
00687 
00688       str = entry;
00689 
00690       if (str.find("HG_Post") < str.size())
00691         n++;
00692       else
00693         if (str.find("LG_Post") < str.size())
00694           n++;
00695         else
00696           if (str.find("HG_Pre") < str.size())
00697             n++;
00698           else
00699             if (str.find("LG_Pre") < str.size())
00700               n++;
00701             else
00702               if (str.find("TAC") < str.size())
00703                 n++;
00704               else
00705                 if (str.find("LG_Pre-Post") < str.size())
00706                   n++;
00707                 else
00708                   if (str.find("HG_Pre-Post") < str.size())
00709                     n++;
00710     }
00711 
00712   if (n > 3)
00713     version = 1;
00714 
00715   gSystem->FreeDirectory(dirp);
00716   delete[] cdir;
00717 
00718   return version;
00719 }
00720 
00721 
00722 bool
00723 emcDB::Quit(void)
00724 {
00725   BankManager()->getApplication()->commit();
00726   return true;
00727 }
00728 
00729 
00730 void
00731 emcDB::SetEndInterval(const PHTimeStamp& endAfter,
00732                       const PHTimeStamp& endBefore)
00733 {
00734   fEndAfter = endAfter;
00735   fEndBefore = endBefore;
00736   fEndIntervalGiven = true;
00737 }
00738 
00739 
00740 void
00741 emcDB::SetInsertInterval(const PHTimeStamp& insertAfter,
00742                          const PHTimeStamp& insertBefore)
00743 {
00744   fInsertAfter = insertAfter;
00745   fInsertBefore = insertBefore;
00746   fInsertIntervalGiven = true;
00747 }
00748 
00749 
00750 void
00751 emcDB::SetStartInterval(const PHTimeStamp& startAfter,
00752                         const PHTimeStamp& startBefore)
00753 {
00754   fStartAfter = startAfter;
00755   fStartBefore = startBefore;
00756   fStartIntervalGiven = true;
00757 }
00758 
00759 
00760 bool emcDB::Update(const string ctedir)
00761 {
00762   
00763   
00764   
00765   
00766 
00767   string dir = ctedir;
00768 
00769   
00770   if ( !fInteractive )
00771     {
00772       return Error("Update", "Must be in interactive mode.");
00773     }
00774 
00775   initDBMS("Ascii");
00776 
00777   
00778 
00779   char* cdir = gSystem->ExpandPathName(dir.c_str());
00780   void* dirp = gSystem->OpenDirectory(cdir);
00781 
00782   if ( !dirp )
00783     {
00784       cerr << "Failed to open directory: " << dir << endl;
00785       return false;
00786     }
00787 
00788   
00789 
00790   while (dir[dir.size() - 1] == '/')
00791     {
00792       dir = dir.substr(0, dir.size() - 1);
00793     }
00794 
00795   size_t pos = dir.rfind('/');
00796 
00797   string topdir = dir.substr(0, pos + 1);
00798   string flavor = dir.substr(pos + 1, dir.size() - pos - 1);
00799 
00800   
00801 
00802   if (flavor.find("Gains") < flavor.size())
00803     {
00804       flavor = "Gains";
00805     }
00806   else if (flavor.find("PEDESTALS") < flavor.size())
00807     {
00808       int version = PedestalVersion(ctedir);
00809       if (version == 0)
00810         {
00811           flavor = "Pedestals";
00812         }
00813       else if (version == 1)
00814         {
00815           flavor = "Pedestals5";
00816         }
00817       else
00818         {
00819           assert(0 == 1);
00820         }
00821     }
00822   else if (flavor.find("ToF") < flavor.size())
00823     {
00824       flavor = "TOF";
00825     }
00826   else if (flavor.find("HLRatio") < flavor.size())
00827     {
00828       flavor = "HLRatios";
00829     }
00830   else if (flavor.find("QA") < flavor.size())
00831     {
00832       flavor = "QAs";
00833     }
00834   else
00835     {
00836       
00837       
00838 
00839       bool inical = isInitialCalibrationDirectory(cdir);
00840       bool rejectlist = isRejectListDirectory(cdir);
00841 
00842       if ( !inical && !rejectlist )
00843         {
00844           cerr << "<E> Cannot infer flavor type for this directory : "
00845                << dir << endl;
00846           return false;
00847         }
00848       else if ( inical )
00849         {
00850           if ( fForceDate )
00851             {
00852               return UpdateInitialCalibration(topdir);
00853             }
00854           else
00855             {
00856               cerr << "<E> Updating IniCal requires the forceDate option so far."
00857                    << endl;
00858               return false;
00859             }
00860         }
00861       else if ( rejectlist )
00862         {
00863           if ( fForceDate )
00864             {
00865               return UpdateRejectList(topdir);
00866             }
00867           else
00868             {
00869               cerr << "<E> Updating RejectList requires the forceDate "
00870                    << "option so far."
00871                    << endl;
00872               return false;
00873             }
00874         }
00875     }
00876 
00877   cout << string(50, '-') << endl;
00878   cout << "FLAVOUR = " << flavor << endl;
00879   cout << string(50, '-') << endl;
00880 
00881   if ( topdir.empty() )
00882     {
00883       topdir = "./";
00884     }
00885 
00886   emcDataManager* dm = emcDataManager::GetInstance();
00887   dm->SetSourceDir(topdir.c_str());
00888 
00889   
00890 
00891   const char* entry;
00892   string str;
00893   size_t ifem;
00894   size_t pin;
00895 
00896   emcCalFEM* read = 0;
00897 
00898   const size_t NMAX = 200;
00899   vector<bool> kAlreadyRead(NMAX);
00900   size_t i;
00901 
00902   for ( i = 0; i < kAlreadyRead.size(); i++ )
00903     {
00904       kAlreadyRead[i] = false;
00905     }
00906 
00907   PHTimeStamp tdummy;
00908   string theflavor;
00909 
00910   while ( (entry = gSystem->GetDirEntry(dirp)) )
00911     {
00912 
00913       str = entry;
00914 
00915       if (str == "." || str == "..")
00916         continue;
00917 
00918       theflavor = flavor;
00919 
00920       ParseFileName(str, ifem, pin);
00921 
00922       delete read;
00923 
00924       if (flavor == "TOF")
00925         {
00926           int runnumber = isRunNumber(str);
00927 
00928           if ( runnumber > 0 )
00929             {
00930               UpdateTofSectorOffset(cdir,runnumber);
00931               continue;
00932             }
00933 
00934           if (str.find(".TOF_LC") < str.size())
00935             {
00936               theflavor = "LCTofs";
00937               read = emcCalFEMFactory::Create("LCTofs", ifem);
00938             }
00939           else if (str.find(".TOF_WALK") < str.size())
00940             {
00941               theflavor = "WalkTofs";
00942               read = emcCalFEMFactory::Create("WalkTofs", ifem);
00943             }
00944           else if (str.find("PED-TOWERS-TAC-DRIFT.TofT0s") < str.size())
00945             {
00946               theflavor = "TacPeds";
00947               read = emcCalFEMFactory::Create("TacPeds", ifem);
00948             }
00949           else if (str.find(".TofT0s") < str.size())
00950             {
00951               std::string filename = cdir;
00952               filename += "/";
00953               filename += str;
00954               theflavor = getTofT0Flavor(filename);         
00955               read = emcCalFEMFactory::Create(theflavor.c_str(),ifem);
00956             }
00957           else
00958             {
00959               cerr << "<W> Unknown file type " << entry << endl;
00960               continue;
00961             }
00962         }
00963       else
00964         {
00965           read = emcCalFEMFactory::Create(flavor.c_str(), ifem);
00966         }
00967 
00968       assert(read != 0);
00969 
00970       read->SetSource(emcManageable::kFile_ASCII);
00971 
00972       read->SetDestination(destination());
00973 
00974       if ( ifem < kAlreadyRead.size() && !kAlreadyRead[ifem] )
00975         {
00976 
00977           int code = emcCalFEM::FEMCode(ifem, pin, 0, 0);
00978 
00979           assert(ifem < NMAX);
00980 
00981           cout << "Reading " << theflavor << "...";
00982 
00983           bool ok = dm->Read(*read, tdummy, code);
00984 
00985           cout << "done" << endl;
00986 
00987           if (ok)
00988             {
00989 
00990               
00991               
00992               
00993               
00994               
00995               
00996               
00997               
00998               
00999               
01000               
01001               
01002               
01003               
01004               
01005               
01006 
01007             }
01008 
01009           if (ok)
01010             {
01011               if (flavor != "TOF")
01012                 {
01013                   kAlreadyRead[ifem] = true;
01014                 }
01015 
01016               
01017               if (fForceDate)
01018                 {
01019                   if ( fForceEndDate )
01020                     {
01021                       read->SetValidityPeriod(*fForceDate, *fForceEndDate);
01022                     }
01023                   else
01024                     {
01025                       read->SetValidityPeriod(*fForceDate, read->GetEndValTime());
01026                     }
01027                 }
01028 
01029               read->Print();
01030 
01031               cout << "Writing...";
01032               ok = dm->Write(*read, tdummy);
01033               if (!ok)
01034                 {
01035                   cerr << "<E> Could not dump FEM " << ifem << " into DB" << endl;
01036                   cout << "Failed" << endl;
01037                 }
01038               else
01039                 {
01040                   cout << "done" << endl;
01041                 }
01042             } 
01043         } 
01044     } 
01045 
01046   return true;
01047 }
01048 
01049 
01050 
01051 void
01052 emcDB::UpdateXValue(emcTracedFEM& fem, int value)
01053 {
01054   
01055   
01056   
01057 
01058   emcTracedValue* tv;
01059 
01060   for ( size_t i = 0; i < fem.GetNumberOfChannels(); i++ )
01061     {
01062       int n = 0;
01063       fem.FirstItem(i);
01064       while ( (tv = fem.NextItem()) != 0 )
01065         {
01066           tv->Set(value, tv->GetConstant(), tv->GetSlope());
01067           n++;
01068         }
01069       assert(n == 1);
01070     }
01071 }
01072 
01073 
01074 bool
01075 emcDB::UpdateInitialCalibration(const string top_directory)
01076 {
01077   string browsedir = top_directory;
01078 
01079   browsedir += "IniCal/";
01080 
01081   char* cdir = gSystem->ExpandPathName(browsedir.c_str());
01082   void* dirp = gSystem->OpenDirectory(cdir);
01083 
01084   cout << "<I> emcDB::UpdateInitialCalibration : dir = "
01085        << cdir << endl;
01086 
01087   const char* entry;
01088 
01089   while ( (entry = gSystem->GetDirEntry(dirp)) )
01090     {
01091       string str = entry;
01092 
01093       cout << str << endl;
01094 
01095       if ( str.find("INICAL") < str.size() )
01096         {
01097           
01098           size_t pos = str.find('.');
01099           string sectorId = str.substr(0, pos);
01100           int iS = EmcIndexer::EmcSectorNumber(sectorId.c_str());
01101           if ( iS < 0 )
01102             {
01103               cerr << "<E> emcDB::UpdateInitialCalibration : file "
01104                    << str << " is not of InitialCalibration type, as "
01105                    << " its name suggest. I skip it."
01106                    << endl;
01107             }
01108           else
01109             {
01110               emcCalibrationData sector(emcCalibrationData::kIniCal, iS);
01111               sector.SetSource(emcManageable::kFile_ASCII);
01112               sector.SetDestination(destination());
01113               emcDataManager* dm = emcDataManager::GetInstance();
01114               dm->SetSourceDir(top_directory.c_str());
01115               PHTimeStamp dummy;
01116               bool ok = dm->Read(sector, dummy);
01117               if (ok)
01118                 {
01119                   assert(fForceDate != 0);
01120                   sector.SetValidityPeriod(*fForceDate, EndOfValidity());
01121                   sector.Print();
01122                   ok = dm->Write(sector);
01123                   if ( !ok )
01124                     {
01125                       cerr << "<E>  emcDB::UpdateInitialCalibration : "
01126                            << " Could not write sector " << iS
01127                            << " to Objy" << endl;
01128                     }
01129                 }
01130               else
01131                 {
01132                   cerr << "<E> emcDB::UpdateInitialCalibration : Could not "
01133                        << " read sector " << iS << " in "
01134                        << cdir << endl;
01135                 }
01136             }
01137         }
01138     }
01139 
01140   return true;
01141 }
01142 
01143 
01144 bool
01145 emcDB::UpdateRejectList(const string top_directory)
01146 {
01147   emcRejectList rl;
01148 
01149   emcDataManager* dm = emcDataManager::GetInstance();
01150 
01151   dm->SetSourceDir(top_directory.c_str());
01152 
01153   rl.SetSource(emcManageable::kFile_ASCII);
01154   rl.SetDestination(destination());
01155 
01156   PHTimeStamp dummy;
01157 
01158   bool ok = dm->Read(rl, dummy);
01159 
01160   if (ok)
01161     {
01162       assert(fForceDate != 0);
01163       rl.SetValidityPeriod(*fForceDate, EndOfValidity());
01164       ok = dm->Write(rl);
01165       if ( !ok )
01166         {
01167           cerr << "<E>  emcDB::UpdateRejectList : "
01168                << " Could not write rejectlist "
01169                << " to Objy" << endl;
01170         }
01171     }
01172   else
01173     {
01174       cerr << "<E> emcDB::UpdateRejectList : Could not "
01175            << " read rejectlist in "
01176            << top_directory << "/RejectList" << endl;
01177     }
01178   return true;
01179 }
01180 
01181 
01182 bool
01183 emcDB::UpdateTofSectorOffset(const std::string dir, int runnumber)
01184 {
01185   
01186   
01187 
01188   RunToTime* rt = RunToTime::instance();
01189   if (!rt)
01190     {
01191       std::cerr << "UpdateTofSectorOffset: could not get to RunToTime object"
01192                 << std::endl;
01193       return false;
01194     }
01195 
01196   std::auto_ptr<PHTimeStamp> start(rt->getBeginTime(runnumber));
01197   std::auto_ptr<PHTimeStamp> end(rt->getEndTime(runnumber));
01198 
01199   if ( !start.get() )
01200     {
01201       std::cerr << "UpdateTofSectorOffset: could not get start time of run="
01202                 << runnumber << std::endl;
01203       return false;
01204     }
01205 
01206   if ( *(end.get()) <= *(start.get()) )
01207     {
01208       std::cout << "End time = " << *end << " of run=" << runnumber 
01209                 << " is invalid. I will use start+1 second" << std::endl;
01210       *(end.get()) = *(start.get());
01211       *(end.get()) += 1;
01212     }
01213 
01214   
01215 
01216   std::ostringstream sdir;
01217   
01218   sdir << dir << "/" << std::setfill('0') << std::setw(10)
01219        << runnumber;
01220 
01221   char* cdir = gSystem->ExpandPathName(sdir.str().c_str());
01222   void* dirp = gSystem->OpenDirectory(cdir);
01223 
01224   if ( !dirp )
01225     {
01226       cerr << "Failed to open directory: " << dir << endl;
01227       return false;
01228     }
01229 
01230   const char* entry;
01231 
01232   
01233   std::map<const std::string, int> validentries;
01234   validentries["W0.TOF_OFFSET"]=1;
01235   validentries["W1.TOF_OFFSET"]=1;
01236   validentries["W2.TOF_OFFSET"]=1;
01237   validentries["W3.TOF_OFFSET"]=1;
01238   validentries["E2.TOF_OFFSET"]=1;
01239   validentries["E3.TOF_OFFSET"]=1;
01240   validentries["E0.TOF_OFFSET"]=1;
01241   validentries["E1.TOF_OFFSET"]=1;
01242                                
01243   while ( (entry = gSystem->GetDirEntry(dirp)) )
01244     {
01245       std::string sentry = entry;
01246       if ( validentries[sentry] == 1 )
01247         {
01248           int isector = 
01249             EmcIndexer::EmcSectorNumber(sentry.substr(0,2).c_str());
01250           assert(isector>=0 && isector<=7);
01251 
01252           emcDataManager* dm = emcDataManager::GetInstance();
01253           emcCalibrationData sec(emcCalibrationData::kTofSectorOffset,isector);
01254           sec.SetSource(emcManageable::kFile_ASCII);
01255           bool ok = dm->Read(sec,runnumber);
01256           if (!ok)
01257             {
01258               std::cerr << "UpdateTofSectorOffset: could not read run "
01259                         << runnumber << " sector " << isector
01260                         << " from dir " << cdir
01261                         << std::endl;         
01262             }
01263           else
01264             {
01265               sec.SetValidityPeriod(*(start.get()),*(end.get()));
01266               sec.SetDestination(emcManageable::kDB_Pg);
01267               ok = dm->Write(sec);
01268               if (!ok)
01269                 {
01270                   std::cerr << "updatePbGlGains: could not upload "
01271                             << "for run " << runnumber
01272                             << " sector " << isector
01273                             << std::endl;
01274                 }
01275             }
01276         }
01277     }
01278 
01279   gSystem->FreeDirectory(dirp);
01280 
01281   return true;
01282 }
01283 
01284 
01285 bool
01286 emcDB::UpdatePbGlGains(const string basedir)
01287 {
01288   
01289   
01290   
01291   
01292   
01293   
01294   
01295   
01296   
01297   
01298   
01299   
01300   
01301   
01302   
01303 
01304   bool kFaultTolerant = false; 
01305 
01306   PHTimeStamp tdummy(0);
01307 
01308   
01309   
01310   void* pdir = gSystem->OpenDirectory(basedir.c_str());
01311 
01312   if (!pdir)
01313     return false;
01314 
01315   const char* cfilename;
01316   std::vector<int> runs;
01317 
01318   while ( ( cfilename = gSystem->GetDirEntry(pdir) ) != 0 )
01319     {
01320       std::string filename = std::string(cfilename);
01321       if ( filename.find("Run") < filename.size() )
01322         {
01323           runs.push_back(atoi(filename.substr(3).c_str()));
01324         }
01325     }
01326 
01327   
01328   
01329   cout << EMC_INFO_MSG << "Number of runs in " << basedir
01330        << " = " << runs.size() << endl;
01331 
01332   if (runs.empty())
01333     {
01334       cerr << EMC_INFO_MSG << " huh ? no run found ? Is the top directory "
01335            << "correct ? " << endl;
01336       cerr << "I'm expecting something like " << endl;
01337       cerr << basedir << "/RunXXXX/Gains/..." << endl;
01338       cerr << basedir << "/RunXXXY/Gains/..." << endl;
01339       cerr << basedir << "/RunXXXZ/Gains/..." << endl;
01340       return false;
01341     }
01342 
01343   int maxrunnumber = 1500000;
01344 
01345   
01346   runs.push_back(maxrunnumber);
01347 
01348   
01349   sort(runs.begin(), runs.end());
01350 
01351   
01352   
01353   
01354   
01355   initDBMS("Ascii");
01356   RunTimes* rt = RunTimesFactory::instance().create("Ascii");
01357   assert(rt != 0);
01358   rt->RunStart(1);
01359 
01360   
01361   
01362   
01363   size_t irun;
01364   std::vector<int> pbruns;
01365   std::vector<int> pbruns_next;
01366 
01367   size_t nmax = runs.size();
01368 
01369   for ( irun = 0; irun < nmax - 1; irun++ )
01370     {
01371       PHTimeStamp start = rt->RunStart(runs[irun]);
01372       if (start.getTics() == 0)
01373         {
01374           pbruns.push_back(runs[irun]);
01375           pbruns_next.push_back(runs[irun + 1]);
01376         }
01377     }
01378 
01379   if (!pbruns.empty())
01380     {
01381       
01382       std::cerr << "<E> Runs for which I did not find start date : ";
01383       for (irun = 0;irun < pbruns.size();irun++)
01384         {
01385           std::cerr << pbruns[irun] << "[ -" << pbruns_next[irun] << "] , ";
01386         }
01387       std::cerr << std::endl;
01388       std::cerr << " (" << pbruns.size() << " runs over "
01389                 << runs.size() << std::endl;
01390       std::cerr << "Correct this error before continuing\n"
01391         "Use emcDB --runtimes (with OO_FD_BOOT = PHENIX_FD_BOOT)\n"
01392         "to get an ASCII file containing run to timestamp relationship\n"
01393         "and complete this file for the runs mentionned above\n"
01394         "Then restart emcDB --updatePbGlGains\n" << std::endl;
01395       std::cerr << "Aborting now." << std::endl;
01396       
01397       
01398       return false;
01399 
01400     }
01401 
01402   
01403   char des[80];
01404   char dirname[1024];
01405   bool ok;
01406 
01407   
01408   emcDataManager* dm = emcDataManager::GetInstance();
01409 
01410   if (fDebug)
01411     {
01412       dm->SetVerboseLevel(10);
01413     }
01414 
01415   
01416   for ( irun = 0; irun < nmax - 1; irun++ )
01417     {
01418 
01419       sprintf(dirname, "%s/Run%d/", basedir.c_str(), runs[irun]);
01420       dm->SetSourceDir(dirname);
01421       
01422       std::cout << dirname << std::endl;
01423 
01424       
01425       for ( int ifem = 108; ifem <= 171; ifem++)
01426         {
01427 
01428           
01429           
01430           emcGainFEM gains(ifem);
01431           gains.SetSource(emcManageable::kFile_ASCII);
01432           gains.SetDestination(destination());
01433 
01434           
01435           ok = dm->Read(gains, tdummy, ifem);
01436 
01437           if (ok)
01438             {
01439               
01440               
01441               
01442               
01443 
01444               PHTimeStamp start = rt->RunStart(runs[irun]);
01445               
01446               
01447               PHTimeStamp end = rt->RunStart(runs[irun + 1]);
01448 
01449               assert(start.getTics() != 0);
01450 
01451               if ( runs[irun + 1] != maxrunnumber )
01452                 {
01453                   gains.SetValidityPeriod(start, end);
01454                   sprintf(des, "RUNS[%06d-%06d[", runs[irun], runs[irun + 1]);
01455                 }
01456               else
01457                 {
01458                   end.setToFarFuture();
01459                   gains.SetValidityPeriod(start, end);
01460                   sprintf(des, "RUNS[%06d-[", runs[irun]);
01461                 }
01462 
01463               if (fDebug)
01464                 {
01465                   cout << des << " " << start << " " << end << endl;
01466                   cout << rt->RunStart(runs[irun]) << endl;
01467                 }
01468               
01469               
01470               
01471               gains.SetDescription(des);
01472 
01473               
01474               
01475               gains.SetXmin(runs[irun]);
01476               gains.SetXmax(runs[irun + 1]);
01477 
01478               
01479               UpdateXValue(static_cast<emcTracedFEM&>(gains), 0);
01480 
01481               
01482               ok = dm->Write(gains, tdummy);
01483               assert(ok == true);
01484             }
01485           else
01486             {
01487               std::cerr << "<E> Cannot read fem " << ifem << " for directory "
01488                         << dirname << std::endl;
01489               if (!kFaultTolerant)
01490                 return false;
01491             }
01492         }
01493 
01494       if (!ok)
01495         {
01496           std::cerr << "<E> Cannot write"
01497                     << " into DB " << std::endl;
01498           if (!kFaultTolerant)
01499             return false;
01500         }
01501     }
01502 
01503   return true;
01504 }
01505 
01506 
01507 void
01508 emcDB::MakeRunTimes(int minrunnumber)
01509 {
01510   initDBMS("Ascii");
01511   RunTimes* rt = RunTimesFactory::instance().create(fDBMS.c_str());
01512   if (!rt)
01513     {
01514       std::cerr << "emcDB::RunTimes: "
01515                 << "Could not get RunTimes object for DBMS="
01516                 << fDBMS
01517                 << std::endl;
01518       exit(1);
01519     }
01520   else
01521     {
01522       rt->MinRunNumber(minrunnumber);
01523       rt->Output();
01524     }
01525 }
01526 
01527 
01528 bool
01529 emcDB::ReadConfiguration(bool debug)
01530 {
01531   char str[200];
01532 
01533   emcConfigurationFile config(fConfigurationFile.c_str());
01534 
01535   if (!config.IsValid())
01536     return false;
01537 
01538   config.Rewind();
01539 
01540   fPinNumbers.resize(EmcIndexer::MaxNumberOfFEMs(), 0);
01541 
01542   string s;
01543   string fem;
01544   string pinNumber;
01545   vector<string> split;
01546   int absPosition;
01547 
01548   while ( config.GetLine(str, 200) )
01549     {
01550 
01551       s = str;
01552 
01553       
01554       if ( s.substr(0, 2) == "//" || s.substr(0, 1) == "#" )
01555         continue;
01556 
01557       if ( s.find("FEM.EMC") < s.size() )
01558         {
01559 
01560           Split(s, split);
01561 
01562           if (split.size() == 4)
01563             {
01564               fem = split[0];
01565               absPosition = AbsolutePosition(fem);
01566               pinNumber = split[3];
01567               if (absPosition >= 0)
01568                 {
01569                   fPinNumbers[absPosition] = atoi(pinNumber.c_str());
01570                 }
01571               if (debug)
01572                 {
01573                   cout << fem << ":absPosition=" << absPosition
01574                        << ":pinNumber=" << fPinNumbers[absPosition] << endl;
01575                 }
01576 
01577             }
01578         }
01579 
01580     }
01581   return true;
01582 }
01583 
01584 
01585 void
01586 emcDB::Split(const string& str, vector<string>& split)
01587 {
01588   split.clear();
01589   string s = str;
01590 
01591   size_t i = 0;
01592 
01593   
01594   do
01595     {
01596 
01597       if (s[i] == '\t' || s[i] == ',')
01598         {
01599           s.erase(i, 1);
01600         }
01601       else
01602         {
01603           i++;
01604         }
01605     }
01606   while (i < s.size());
01607 
01608   
01609   i = 0;
01610   if (s.size() > 2)
01611     {
01612       do
01613         {
01614           if (s[i] == ' ' && s[i + 1] == ' ')
01615             {
01616               s.erase(i, 1);
01617             }
01618           else
01619             {
01620               i++;
01621             }
01622         }
01623       while (i < s.size() - 1);
01624     }
01625 
01626   
01627 
01628   vector<int> pos;
01629 
01630   for (i = 0;i < s.size();i++)
01631     {
01632       if (s[i] == ' ')
01633         pos.push_back(i);
01634     }
01635 
01636   pos.push_back(s.size());
01637 
01638   size_t p = 0;
01639 
01640   for (i = 0;i < pos.size();i++)
01641     {
01642       split.push_back(s.substr(p, pos[i] - p));
01643       p = pos[i] + 1;
01644     }
01645 }
01646 
01647 
01648 string
01649 emcDB::Version(void)
01650 {
01651   
01652 
01653   
01654   
01655 
01656   
01657   
01658 
01659   
01660   
01661   
01662   
01663 
01664   
01665   
01666   
01667 
01668   
01669   
01670 
01671   
01672   
01673 
01674   
01675   
01676 
01677   
01678   
01679 
01680   
01681   
01682 
01683   
01684   
01685 
01686   return string("emcDB 2.1 (27 January 2005)");
01687   
01688 }