Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

SpillServerMonFinder.cxx

Go to the documentation of this file.
00001 
00002 #include "SpillServerMonFinder.h"
00003 #include "MessageService/MsgService.h"
00004 #include "DatabaseInterface/DbiSqlContext.h"
00005 #include <cmath>
00006 
00007 ClassImp(SpillServerMonFinder)
00008 
00009 CVSID("$Id: SpillServerMonFinder.cxx,v 1.5 2007/08/14 16:48:00 blake Exp $");
00010 
00011 static SpillServerMon kDefaultSpillFD_BeginningOfTime(0,0,-1,0,0,0,0,-999,0,0,0);
00012 
00013 static SpillServerMon kDefaultSpillFD_EndOfTime(1556150400,0,-1,1556150400,0,1556150400,0,-999,0,0,0);    
00014 
00015 SpillServerMonFinder* SpillServerMonFinder::fMyInstance = 0;
00016 
00017 SpillServerMonFinder& SpillServerMonFinder::Instance()
00018 {
00019   MSG("SpillServerMon", Msg::kDebug) << " *** SpillServerMonFinder::Instance() *** " << endl;
00020 
00021   // Cleaner destructor calls SpillServerMonFinder dtor
00022   static Cleaner cleaner;
00023 
00024   // create singleton instance of spillfinder
00025   if(!fMyInstance){
00026     MSG("SpillServerMon", Msg::kDebug) << "  Creating new instance of SpillServerMonFinder " << endl;
00027     cleaner.UseMe();
00028     fMyInstance = new SpillServerMonFinder();
00029   }
00030 
00031   // die if finder hasn't actually been created
00032   if(!fMyInstance){
00033     MSG("SpillServerMon", Msg::kFatal) << "  No SpillServerMonFinder Instance - aagghhh, I'm going to die!!!." << endl;
00034     assert(fMyInstance);
00035   }
00036 
00037   // can do re-setting here
00038   if(fMyInstance){
00039 
00040   }
00041   
00042   return *fMyInstance;
00043 }  
00044 
00045 SpillServerMonFinder::SpillServerMonFinder() :
00046   fPrevTable(0),
00047   fNextTable(0),
00048   fLastQueryPrev(kDefaultSpillFD_EndOfTime),
00049   fLastQueryNext(kDefaultSpillFD_BeginningOfTime),
00050   fTask(0)
00051 {
00052   MSG("SpillServerMon", Msg::kVerbose) << " *** SpillServerMonFinder::SpillServerMonFinder() *** " << endl;
00053 }
00054   
00055 SpillServerMonFinder::~SpillServerMonFinder()
00056 {
00057   MSG("SpillServerMon", Msg::kVerbose) << " *** SpillServerMonFinder::~SpillServerMonFinder() *** " << endl;
00058 
00059   if(fPrevTable) delete fPrevTable;
00060   if(fNextTable) delete fNextTable;
00061 }
00062 
00063 Bool_t SpillServerMonFinder::DataIsAvailable(const VldContext& context)
00064 {
00065   MSG("SpillServerMon", Msg::kDebug) << " *** SpillServerMonFinder::DataIsAvailable(...) *** " << endl;
00066 
00067   // check whether there is a database entry covering this vldcontext  
00068 
00069   fCurrentTable.NewQuery(context,fTask);
00070 
00071   const DbiValidityRec* vldRec = fCurrentTable.GetValidityRec();
00072   const VldRange& vldRange = vldRec->GetVldRange();
00073   VldTimeStamp start = vldRange.GetTimeStart();
00074   VldTimeStamp end = vldRange.GetTimeEnd();
00075 
00076   MSG("SpillServerMon", Msg::kVerbose) << "   timestamp = " << context.GetTimeStamp().GetSec() << endl;  
00077   MSG("SpillServerMon", Msg::kVerbose) << "   range = " << start.GetSec() << "->" << end.GetSec() << endl;
00078 
00079   if ( vldRec->IsGap () ){
00080     MSG("SpillServerMon", Msg::kDebug) << "   NO data is available " << endl;
00081     return false;
00082   }
00083   else{
00084     MSG("SpillServerMon", Msg::kDebug) << "   data is available " << endl;
00085     return true;
00086   }
00087 }
00088 
00089 const SpillServerMon& SpillServerMonFinder::GetPreviousSpill(const VldContext& context)
00090 {
00091   MSG("SpillServerMon", Msg::kDebug) << " *** SpillServerMonFinder::GetPreviousSpill(...) *** " << endl;
00092 
00093   const SpillServerMon* prev;
00094   const SpillServerMon* next;
00095   this->FindClosestEntries(context,prev,next);
00096   if(prev) return *prev;
00097 
00098   MSG("SpillServerMon", Msg::kWarning) << " can't find the previous spill, defaulting to the beginning of time! " << endl;
00099   return kDefaultSpillFD_BeginningOfTime;
00100 }
00101 
00102 const SpillServerMon& SpillServerMonFinder::GetNextSpill(const VldContext& context)
00103 {
00104   MSG("SpillServerMon", Msg::kDebug) << " *** SpillServerMonFinder::GetNextSpill(...) *** " << endl;
00105 
00106   const SpillServerMon* prev;
00107   const SpillServerMon* next;
00108   this->FindClosestEntries(context,prev,next);
00109   if(next) return *next;
00110 
00111   MSG("SpillServerMon", Msg::kWarning) << " can't find the next spill, defaulting to the end of time! " << endl;
00112   return kDefaultSpillFD_EndOfTime;
00113 }
00114 
00115 const SpillServerMon& SpillServerMonFinder::GetNearestSpill(const VldContext& context)
00116 {
00117   MSG("SpillServerMon", Msg::kDebug) << " *** SpillServerMonFinder::GetNearestSpill(...) *** " << endl;
00118 
00119   const SpillServerMon* prev;
00120   const SpillServerMon* next;
00121   this->FindClosestEntries(context,prev,next);
00122 
00123   if(prev && !next){
00124     MSG("SpillServerMon", Msg::kVerbose) << " no next entry, return previous entry " << endl;
00125     return *prev;
00126   }
00127 
00128   if(!prev && next){
00129     MSG("SpillServerMon", Msg::kVerbose) << " no previous entry, return next entry " << endl;
00130     return *next;
00131   }
00132 
00133   double dtNeg=-999.9;
00134   if(prev) dtNeg = this->GetTimeDifference( prev->GetSpillTime(),
00135                                             context.GetTimeStamp() );
00136  
00137   double dtPos=-999.9;
00138   if(next) dtPos = this->GetTimeDifference( context.GetTimeStamp(),
00139                                             next->GetSpillTime() );
00140 
00141   if( dtNeg>=0 && dtPos>=0 ){
00142     MSG("SpillServerMon", Msg::kVerbose) << " dtNeg=" << dtNeg << " dtPos=" << dtPos << endl;
00143     if( dtPos<=dtNeg ) return *next; else return *prev;
00144   }
00145 
00146   MSG("SpillServerMon", Msg::kWarning) << " can't find the nearest spill, moving back to the beginning of time! " << endl;
00147   return kDefaultSpillFD_BeginningOfTime;
00148 }
00149 
00150 Int_t SpillServerMonFinder::GetSpillTimeError(const VldContext& context, Bool_t usewindow, Double_t window)
00151 {
00152   MSG("SpillServerMon", Msg::kDebug) << " *** SpillServerMonFinder::GetSpillTimeError(...) *** " << endl;
00153 
00154   if( usewindow ){
00155     // return largest GPS error within a time window
00156     // only use the previous/next spill (for now)
00157     Int_t gpserror = -999;
00158     Double_t gpswindow = window;
00159     if( gpswindow<5.0 ) gpswindow=5.0;
00160 
00161     const SpillServerMon& prev = this->GetPreviousSpill(context);
00162     MSG("SpillServerMon", Msg::kVerbose) << "  prev: time=" << prev.GetTimeStamp().GetSec() << ", delta=" << this->GetTimeDifference(context.GetTimeStamp(),prev.GetTimeStamp()) << ", error=" << prev.GetSpillTimeError() << endl;
00163     if( fabs(this->GetTimeDifference(context.GetTimeStamp(),prev.GetTimeStamp()))<gpswindow ){   
00164       if( prev.GetSpillTimeError()>gpserror ) gpserror = prev.GetSpillTimeError();
00165     }
00166 
00167     const SpillServerMon& next = this->GetNextSpill(context);
00168     MSG("SpillServerMon", Msg::kVerbose) << "  next: time=" << next.GetTimeStamp().GetSec() << ", delta=" << this->GetTimeDifference(context.GetTimeStamp(),next.GetTimeStamp()) << ", error=" << next.GetSpillTimeError() << endl;
00169     if( fabs(this->GetTimeDifference(context.GetTimeStamp(),next.GetTimeStamp()))<gpswindow ){  
00170       if( next.GetSpillTimeError()>gpserror ) gpserror = next.GetSpillTimeError();
00171     }
00172 
00173     return gpserror;
00174   }
00175 
00176   else{
00177     // use the nearest spill
00178     const SpillServerMon& near = this->GetNearestSpill(context);
00179     return near.GetSpillTimeError();
00180   }
00181 
00182   return -999;
00183 }
00184 
00185 void SpillServerMonFinder::FindClosestEntries(const VldContext& context,const SpillServerMon* &prevEntry,const SpillServerMon* &nextEntry)
00186 {
00187   MSG("SpillServerMon", Msg::kDebug) << " *** SpillServerMonFinder::FindClosestEntries(...) *** " << endl;
00188 
00189   prevEntry = 0;
00190   nextEntry = 0;
00191 
00192   VldTimeStamp timestamp = context.GetTimeStamp();
00193 
00194   // can we return the results of the last query?
00195   if( timestamp >= fLastQueryPrev.GetSpillTime() 
00196    && timestamp <= fLastQueryNext.GetSpillTime() ){
00197     MSG("SpillServerMon", Msg::kDebug) << " Returning same results as before... " << endl;
00198     prevEntry = &fLastQueryPrev;
00199     nextEntry = &fLastQueryNext;
00200     return;
00201   }
00202   
00203   // carry out a new search on the current table
00204   MSG("SpillServerMon", Msg::kDebug) << " Searching the database... " << endl;
00205   fCurrentTable.NewQuery(context,fTask);
00206   this->FindClosestEntries(fCurrentTable,timestamp,prevEntry,nextEntry);
00207 
00208   // need to go in search of a previous entry
00209   if( prevEntry==0 ){   
00210     MSG("SpillServerMon", Msg::kDebug) << " Need to find a previous entry... " << endl;
00211     const DbiValidityRec* vldRec = fCurrentTable.GetValidityRec();
00212     const VldRange& vldRange = vldRec->GetVldRange();
00213     VldTimeStamp newstarttime(vldRange.GetTimeStart());
00214     VldTimeStamp starttime(1556150400,0);
00215 
00216     while( prevEntry==0 && newstarttime<starttime){
00217       MSG("SpillServerMon",Msg::kVerbose) << " No previous entry yet..." << endl;      
00218       MSG("SpillServerMon",Msg::kVerbose) << "  ... try start time: " << newstarttime.AsString("s") << endl;
00219 
00220       starttime=newstarttime;
00221       const char* sqltxt = Form("(TIMEEND<='%s') and (TASK=%d) and (DETECTORMASK & %d) and (SIMMASK & %d) order by TIMEEND desc limit 1",
00222                               starttime.AsString("s"),
00223                               fTask,
00224                               context.GetDetector(),
00225                               context.GetSimFlag() );
00226       
00227 
00228       DbiSqlContext prevcontext(sqltxt);
00229       if(fPrevTable) {
00230         fPrevTable->NewQuery(prevcontext,Dbi::kAnyTask);
00231       } else {
00232         fPrevTable = new DbiResultPtr<SpillServerMon>("SPILLSERVERMON",prevcontext);
00233       }
00234 
00235       const SpillServerMon* temp;
00236       this->FindClosestEntries(*fPrevTable,timestamp,prevEntry,temp);
00237 
00238       if( prevEntry ){
00239         MSG("SpillServerMon",Msg::kVerbose) << " Found a previous entry" << endl;
00240         if( temp ) MSG("SpillServerMon",Msg::kWarning) << " potential conflict... also found a next entry! " << endl;
00241       }
00242       else{
00243         newstarttime = fPrevTable->GetValidityRec()->GetVldRange().GetTimeStart();   
00244       }
00245     }
00246 
00247     if( prevEntry==0 ){
00248       MSG("SpillServerMon", Msg::kWarning) << " can't find the previous entry, defaulting to the beginning of time! " << endl;
00249       prevEntry = &kDefaultSpillFD_BeginningOfTime;
00250     }
00251   }
00252 
00253   // need to go in search of the next entry
00254   if( nextEntry==0 ){
00255     MSG("SpillServerMon",Msg::kVerbose) << " Need to find a next entry..." << endl;
00256 
00257     const DbiValidityRec* vldRec = fCurrentTable.GetValidityRec();
00258     const VldRange& vldRange = vldRec->GetVldRange();
00259     VldTimeStamp newendtime(vldRange.GetTimeEnd());
00260     VldTimeStamp endtime(0,0);
00261   
00262     while( nextEntry==0 && newendtime>endtime ){
00263       MSG("SpillServerMon",Msg::kVerbose) << " No next entry yet... " << endl;
00264       MSG("SpillServerMon",Msg::kVerbose) << "  ...Try end time:" << newendtime.AsString("s") << endl;
00265 
00266       endtime = newendtime;
00267       const char* sqltxt = Form("(TIMESTART>='%s') and (TASK=%d) and (DETECTORMASK & %d) and (SIMMASK & %d) order by TIMESTART asc limit 1",
00268                               endtime.AsString("s"),
00269                               fTask,
00270                               context.GetDetector(),
00271                               context.GetSimFlag() );
00272 
00273       DbiSqlContext nextcontext(sqltxt);
00274       if(fNextTable) {
00275         fNextTable->NewQuery(nextcontext,Dbi::kAnyTask);
00276       } else {
00277         fNextTable = new DbiResultPtr<SpillServerMon>("SPILLSERVERMON",nextcontext);
00278       }
00279 
00280       const SpillServerMon* temp;
00281       this->FindClosestEntries(*fNextTable,timestamp,temp,nextEntry);
00282 
00283       if( nextEntry ){
00284         MSG("SpillServerMon",Msg::kVerbose) << " Found a next entry" << endl;
00285         if( temp ) MSG("SpillServerMon",Msg::kWarning) << " potential conflict... also found a previous entry! " << endl;
00286       }
00287       else{ 
00288         newendtime = fNextTable->GetValidityRec()->GetVldRange().GetTimeEnd();
00289       }
00290     }
00291 
00292     if( nextEntry==0 ){
00293       MSG("SpillServerMon", Msg::kWarning) << " can't find the next entry, defaulting to the end of time! " << endl;
00294       nextEntry = &kDefaultSpillFD_EndOfTime;
00295     }
00296   }
00297 
00298   // Store the results
00299   MSG("SpillServerMon",Msg::kVerbose) << " storing the results... " << endl;
00300   fLastQueryPrev = *prevEntry;
00301   fLastQueryNext = *nextEntry;
00302 
00303   return;
00304 }
00305 
00306 void SpillServerMonFinder::FindClosestEntries(DbiResultPtr<SpillServerMon> &table,const VldTimeStamp& timestamp,const SpillServerMon* &prevEntry,const SpillServerMon* &nextEntry)
00307 {
00308   MSG("SpillServerMon", Msg::kDebug) << " *** SpillServerMonFinder::FindClosestEntriesInDb(...) *** " << endl;
00309 
00310   // Find the closest entries in the current table
00311   // or return null if there aren't any entries.
00312   
00313   prevEntry = 0;
00314   nextEntry = 0;
00315 
00316   const DbiValidityRec* vldRec = table.GetValidityRec();
00317 
00318   const VldRange&  vldRange = vldRec->GetVldRange();
00319   VldTimeStamp start = vldRange.GetTimeStart();
00320   VldTimeStamp end = vldRange.GetTimeEnd();
00321 
00322   if( table.GetNumRows() <=0 ){
00323     MSG("SpillServerMon",Msg::kWarning) << " This table has no rows " << endl;
00324   }
00325 
00326   double dt;
00327   double dtNeg=start.GetSec()-timestamp.GetSec()-1.0;
00328   double dtPos=end.GetSec()-timestamp.GetSec()+1.0;
00329 
00330   for(unsigned int i=0; i<table.GetNumRows(); i++){
00331     const SpillServerMon* entry = table.GetRow(i);
00332 
00333     dt = this->GetTimeDifference( timestamp, entry->GetSpillTime() );
00334 
00335     if( dt<=0.0 && dt>dtNeg ){
00336       dtNeg=dt; 
00337       prevEntry=entry;
00338     }
00339 
00340     if( dt>=0.0 && dt<dtPos ){
00341       dtPos=dt;
00342       nextEntry=entry;
00343     }
00344   }
00345 
00346   if( prevEntry ){
00347     MSG("SpillServerMon",Msg::kDebug) << " Db Search: Found previous entry at " << dtNeg << " seconds" << endl;
00348   }
00349   else{
00350     MSG("SpillServerMon",Msg::kVerbose) << " Db Search: No previous entry " << endl;
00351   }
00352 
00353   if( nextEntry ){
00354     MSG("SpillServerMon",Msg::kDebug) << " Db Search: Found next entry at +" << dtPos << " seconds" << endl;
00355   }
00356   else{
00357     MSG("SpillServerMon",Msg::kVerbose) << " Db Search: No next entry " << endl;
00358   }
00359 
00360   return;
00361 }
00362 
00363 Double_t SpillServerMonFinder::GetTimeDifference(VldTimeStamp first, VldTimeStamp second)
00364 {
00365   return  ( second.GetSec()-first.GetSec() )
00366     + 1.0e-9*( second.GetNanoSec()-first.GetNanoSec() );
00367 }

Generated on Fri Mar 28 15:40:04 2008 for loon by  doxygen 1.3.9.1