AEMDBInterface.cxx

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////
00002 /// $Id: AEMDBInterface.cxx,v 1.6 2005/08/15 17:31:32 hmeyer Exp $
00003 ///
00004 /// Class which defines inteface to database, taken from RunControl
00005 ///
00006 /// hmeyer@fnal.gov
00007 ////////////////////////////////////////////////////////////////////////
00008 
00009 #include "AEMDBInterface.h"
00010 
00011 #include <vector>
00012 #include <sstream>
00013 #include <iostream>
00014 #include <cstring>
00015 #include <cstdlib>
00016 #include <ctime>
00017 #include <string>
00018 
00019 extern "C" {
00020 #include <sys/types.h>
00021 #include <sys/stat.h>
00022 #include <unistd.h>
00023 }
00024 
00025 //----------------------------------------------------------------------
00026 
00027 DBRunEntry::DBRunEntry()
00028 {
00029   run = 0; nsubrun = 0; nevent = 0; momentum = 0;
00030   epochstart = 0; epochend = 0;
00031   nspill = 0; nemptyspill = 0; nbeamspill = 0;
00032   for (int i=0; i!=20; ++i) {
00033     trigcount[i]=0;
00034   }
00035   goodrun = 0;
00036 
00037   fRunTime = 0;
00038   fSpillLength = 0.;
00039   fSpills = 0;
00040   fSpillTime = 0.;
00041   fSpillEvents = 0;
00042   fDAQRate = 0.;
00043 }
00044 
00045 //----------------------------------------------------------------------
00046 
00047 void DBRunEntry::dump()
00048 {
00049   std::cout << "Run number "<< run << " has these entries:\n nsubrun : "
00050             << nsubrun << "\n nevent : " << nevent
00051             << "\n target :" << target
00052             << "\n momentum : " << momentum
00053             << "\n" << datestart << " to " << dateend
00054             << "\n nspill : " << nspill
00055             << "\n nemptyspill : " << nemptyspill
00056             << "\n goodrun : " << goodrun 
00057             << std::endl;
00058   for (int i=0; i!=16; ++i) {
00059     std::cout << trigcount[i] << ":";
00060   }
00061   std::cout << "\n DAQ Rate : " << fDAQRate << std::endl;
00062 }
00063 
00064 //----------------------------------------------------------------------
00065 
00066 #define CheckDBConn() \
00067    if (!fDBConn || (PQstatus(fDBConn) != CONNECTION_OK)){ \
00068       std::ostringstream __str; \
00069       __str << __FILE__ << ":" << __LINE__ \
00070             << " -- No DB connection: " \
00071             << PQerrorMessage(fDBConn); \
00072       throw(__str.str().c_str()); \
00073    }
00074 
00075 
00076 //----------------------------------------------------------------------
00077 
00078 AEMDBInterface::AEMDBInterface(std::string const Host) : fDBHost(Host) 
00079 {
00080   Open();
00081 }
00082 
00083 //----------------------------------------------------------------------
00084 
00085 AEMDBInterface::~AEMDBInterface()
00086 {
00087   PQfinish(fDBConn);
00088 }
00089 
00090 //----------------------------------------------------------------------
00091 /// Opens connection to database, throws an exception if errors 
00092 /// occurred when doing so
00093 ///
00094 void AEMDBInterface::Open()
00095 {
00096   std::ostringstream str;
00097 
00098   str << "dbname=runs host=" << fDBHost << " user=mippdbread";
00099 
00100   fDBConn = PQconnectdb(str.str().c_str());
00101 
00102   CheckDBConn();
00103 }
00104 
00105 //----------------------------------------------------------------------
00106 ///
00107 /// Returns the run number of the run in progress or if no run is
00108 /// currently running, returns the number of the run that has finished.
00109 ///
00110 int AEMDBInterface::GetRunNumber()
00111 {
00112   CheckDBConn();
00113 
00114   PGresult* res = 
00115     ExecQuery("SELECT run,status FROM runs ORDER BY run DESC LIMIT 1");
00116 
00117   if (PQntuples(res) != 1) {
00118     throw("Invalid number of rows in Runs table");
00119   }
00120   int run = atoi(PQgetvalue(res, 0, 0));
00121 
00122   PQclear(res);
00123 
00124   return run;
00125 }
00126 
00127 //----------------------------------------------------------------------
00128 ///
00129 /// Returns the number of subruns for run fRun
00130 ///
00131 int AEMDBInterface::GetnSubrun(int const fRun)
00132 {
00133   CheckDBConn();
00134 
00135   std::ostringstream str;
00136 
00137   str << "SELECT nsubrun FROM runs WHERE run=" << fRun;
00138 
00139   PGresult* res = 
00140     ExecQuery(str.str().c_str());
00141 
00142   if (PQntuples(res) != 1) {
00143     throw("Invalid number of rows in Runs table");
00144   }
00145   int nsubrun = atoi(PQgetvalue(res, 0, 0));
00146 
00147   PQclear(res);
00148 
00149   return nsubrun;
00150 }
00151 
00152 //----------------------------------------------------------------------
00153 ///
00154 /// Returns the number of spills with beam for run fRun
00155 ///
00156 int AEMDBInterface::GetnSpill(int const fRun)
00157 {
00158   CheckDBConn();
00159 
00160   std::ostringstream str;
00161 
00162   str << "SELECT nspill-nemptyspill FROM trigstat WHERE run=" << fRun;
00163 
00164   PGresult* res = 
00165     ExecQuery(str.str().c_str());
00166 
00167   int nspill;
00168   if (PQntuples(res) == 0) {
00169     nspill = 0;
00170   }
00171   else if (PQntuples(res) == 1) {
00172     nspill  = atoi(PQgetvalue(res, 0, 0));
00173   }
00174   else {
00175     throw("Invalid number of rows in Runs table");
00176   }
00177 
00178   PQclear(res);
00179 
00180   return nspill;
00181 }
00182 
00183 //----------------------------------------------------------------------
00184 ///
00185 /// Returns the number of events with beam for run fRun
00186 ///
00187 int AEMDBInterface::GetnEvent(int const fRun)
00188 {
00189   CheckDBConn();
00190 
00191   std::ostringstream str;
00192 
00193   str << "SELECT trigcount[1]+trigcount[5]+trigcount[6]+trigcount[7]+trigcount[8]+trigcount[9]+trigcount[10]+trigcount[11]+trigcount[12] FROM trigstat WHERE run=" << fRun;
00194 
00195   PGresult* res = 
00196     ExecQuery(str.str().c_str());
00197 
00198   int nevt;
00199   if (PQntuples(res) == 0) {
00200     nevt = 0;
00201   }
00202   else if (PQntuples(res) == 1) {
00203     nevt  = atoi(PQgetvalue(res, 0, 0));
00204   }
00205   else {
00206     throw("Invalid number of rows in Runs table");
00207   }
00208 
00209   PQclear(res);
00210 
00211   return nevt;
00212 }
00213 
00214 //----------------------------------------------------------------------
00215 ///
00216 /// Returns run information for run fRun
00217 ///
00218 DBRunEntry AEMDBInterface::GetRunEntry(int const fRun)
00219 {
00220   DBRunEntries fDBREs = GetRunEntry(fRun, fRun);
00221   DBRunEntry fDBRE;
00222 
00223   if (fDBREs.size() != 0) {
00224     fDBRE = fDBREs[0];
00225   }
00226   return fDBRE;
00227 }
00228 
00229 //----------------------------------------------------------------------
00230 ///
00231 /// Returns run information for a range of runs
00232 ///
00233 DBRunEntries AEMDBInterface::GetRunEntry(int const fRunMin, int const fRunMax)
00234 {
00235   CheckDBConn();
00236 
00237   std::ostringstream str;
00238 
00239   str << "SELECT nsubrun,nevent,target,momentum,datestart,dateend,DATE_PART('epoch',datestart),DATE_PART('epoch',dateend),nspill,nemptyspill,goodrun,trigcount,runs.run FROM runs,trigstat WHERE trigstat.run=runs.run and runs.run>=" << fRunMin << " and runs.run<=" << fRunMax << "ORDER BY runs.run";
00240 
00241   PGresult* res = ExecQuery(str.str().c_str());
00242 
00243   std::vector<DBRunEntry> fDBRuns;
00244 
00245   if (fRunMax-fRunMin != PQntuples(res)+1) {
00246     std::cout << "Warning: "<<fRunMax-fRunMin-PQntuples(res)+1<<
00247       "  runs in this range have no DB entry!!!"<<std::endl;
00248   }
00249 
00250   PutQueryToVector(res,fDBRuns);
00251 
00252   PQclear(res);
00253 
00254   return fDBRuns;
00255 }
00256 
00257 //----------------------------------------------------------------------
00258 ///
00259 /// Returns run information for one week of runs starting at fDateString
00260 ///
00261 long AEMDBInterface::GetRunEntry(std::string const fDateStart, DBRunEntries& fDBRuns)
00262 {
00263   CheckDBConn();
00264 
00265   std::ostringstream st;
00266 
00267   st << "SELECT DATE_PART('epoch','"<<fDateStart<<"'::date)";
00268 
00269   PGresult* r = ExecQuery(st.str().c_str());
00270   
00271   long epoch_start = atoi(PQgetvalue(r, 0, 0));
00272   long epoch_end = epoch_start+(7*24*60*60);
00273 
00274   PQclear(r);
00275 
00276   std::ostringstream str;
00277 
00278   str << "SELECT nsubrun,nevent,target,momentum,datestart,dateend,DATE_PART('epoch',datestart),DATE_PART('epoch',dateend),nspill,nemptyspill,goodrun,trigcount,runs.run FROM runs,trigstat WHERE trigstat.run=runs.run and DATE_PART('epoch',runs.dateend)>=" << epoch_start << " and DATE_PART('epoch',runs.datestart)<=" << epoch_end << "ORDER BY runs.run";
00279 
00280   PGresult* res = ExecQuery(str.str().c_str());
00281 
00282   PutQueryToVector(res,fDBRuns);
00283 
00284   PQclear(res);
00285   
00286   return epoch_start;
00287 }
00288 //----------------------------------------------------------------------
00289 ///
00290 /// Returns run information for total run
00291 ///
00292 void AEMDBInterface::GetRunEntry(DBRunEntries& fDBRuns)
00293 {
00294   CheckDBConn();
00295 
00296   std::ostringstream str;
00297 
00298   str << "SELECT nsubrun,nevent,target,momentum,datestart,dateend,DATE_PART('epoch',datestart),DATE_PART('epoch',dateend),nspill,nemptyspill,goodrun,trigcount,runs.run FROM runs,trigstat WHERE trigstat.run=runs.run ORDER BY runs.run";
00299 
00300   PGresult* res = ExecQuery(str.str().c_str());
00301 
00302   PutQueryToVector(res,fDBRuns);
00303 
00304   PQclear(res);
00305   
00306   return;
00307 }
00308 
00309 //----------------------------------------------------------------------
00310 ///
00311 /// copy run information from query result
00312 ///
00313 void AEMDBInterface::PutQueryToVector(PGresult* res, DBRunEntries& vec)
00314 {
00315   for (int i=0; i!=PQntuples(res); ++i) {
00316     DBRunEntry fDBRE;
00317     fDBRE.run        = atoi(PQgetvalue(res, i, 12));
00318     fDBRE.nsubrun    = atoi(PQgetvalue(res, i, 0));
00319     fDBRE.nevent     = atoi(PQgetvalue(res, i, 1));
00320     fDBRE.target     = std::string(PQgetvalue(res, i, 2));
00321     fDBRE.momentum   = atoi(PQgetvalue(res, i, 3));
00322     fDBRE.datestart  = std::string(PQgetvalue(res, i, 4));
00323     fDBRE.dateend    = std::string(PQgetvalue(res, i, 5));
00324     fDBRE.epochstart = atoi(PQgetvalue(res, i, 6));
00325     fDBRE.epochend   = atoi(PQgetvalue(res, i, 7));
00326     fDBRE.nspill     = atoi(PQgetvalue(res, i, 8));
00327     fDBRE.nemptyspill= atoi(PQgetvalue(res, i, 9));
00328     fDBRE.goodrun    = atoi(PQgetvalue(res, i, 10));
00329     std::string trigstr(PQgetvalue(res, i, 11));
00330     int elem = 0; // Element number
00331     std::string::size_type pos = trigstr.find("{");
00332     // If we couldn't find the bracket, then it's not a "correct"
00333     // representation of array
00334     ++pos;
00335     while (pos != std::string::npos) {
00336       std::string::size_type endPos = trigstr.find_first_of(",}", pos);
00337       if (endPos == std::string::npos) break;
00338       fDBRE.trigcount[elem++] = atoi(trigstr.substr(pos, endPos - pos).c_str());
00339       pos = endPos + 1;
00340     }
00341 
00342     fDBRE.fRunTime = fDBRE.epochend-fDBRE.epochstart;
00343     if (fDBRE.run <=14141) {
00344       fDBRE.fSpillLength = .6;
00345     }
00346     else {
00347       fDBRE.fSpillLength = 4.;
00348     }
00349     fDBRE.fSpills = fDBRE.nspill-fDBRE.nemptyspill;
00350     fDBRE.fSpillTime = fDBRE.fSpillLength * fDBRE.fSpills;
00351     fDBRE.fSpillEvents = fDBRE.trigcount[0]+fDBRE.trigcount[4]+fDBRE.trigcount[5]+fDBRE.trigcount[6]+fDBRE.trigcount[7]+fDBRE.trigcount[8]+fDBRE.trigcount[9]+fDBRE.trigcount[10]+fDBRE.trigcount[11];
00352     if (fDBRE.fSpillTime != 0.) {
00353       fDBRE.fDAQRate = fDBRE.fSpillEvents/fDBRE.fSpillTime;
00354     }
00355     else {
00356       fDBRE.fDAQRate = 0.;
00357     }
00358 
00359     vec.push_back(fDBRE);
00360   }
00361   return;
00362 }
00363 
00364 //----------------------------------------------------------------------
00365 /// 
00366 /// Wrap doing queries so as to clean up code a little
00367 /// Throws a const char* exception if query didn't succeed.
00368 /// User has to clean up the returned query by calling PQclear(res);
00369 ///
00370 PGresult* AEMDBInterface::ExecQuery(const char* query)
00371 {
00372   PGresult* res = PQexec(fDBConn, query);
00373   if (PQresultStatus(res) != PGRES_TUPLES_OK) {
00374     std::ostringstream str;
00375     str << "AEMDBInterface: couldn't execute query [" 
00376     << query << "]: " << PQresultErrorMessage(res);
00377     PQclear(res);
00378     throw(str.str().c_str());
00379   }
00380   return res;
00381 }
00382 
00383 //----------------------------------------------------------------------
00384 /// 
00385 /// Wrap execution of SQL commands (not queries!)
00386 /// so as to clean up code a little, throws a const char* exception
00387 /// if command didn't succeed
00388 ///
00389 void AEMDBInterface::ExecCommand(const char* command)
00390 {
00391   PGresult* res = PQexec(fDBConn, command);
00392   if (PQresultStatus(res) != PGRES_COMMAND_OK) {
00393     std::ostringstream str;
00394     str << "AEMDBInterface: couldn't execute command [" 
00395     << command << "]: " << PQresultErrorMessage(res);
00396     PQclear(res);
00397     throw(str.str().c_str());
00398   }
00399   PQclear(res);
00400 }

Generated on Mon Nov 23 08:01:43 2009 for MIPP(E907) by  doxygen 1.4.7