]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/BASE/AliHLTTTreeProcessor.cxx
skipping publishing if there was no new event added during the last interval
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTTTreeProcessor.cxx
index 0a220778b937870cd8135e185e270f101868482d..acbf2b3845214262a74547192d156241deb2dee6 100644 (file)
@@ -31,6 +31,7 @@
 #include "TString.h"
 #include "TTree.h"
 #include "TH1.h"
+#include "TStopwatch.h"
 
 /** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTTTreeProcessor)
@@ -41,7 +42,14 @@ AliHLTTTreeProcessor::AliHLTTTreeProcessor()
                           fTree(0),
                           fMaxEntries(kMaxEntries),
                           fPublishInterval(kInterval),
-                          fLastTime(0)
+                          fLastTime(0),
+                          fpEventTimer(NULL),
+                          fpCycleTimer(NULL),
+                          fMaxEventTime(0),
+                          fNofEventsForce(0),
+                          fForcedEventsCount(0),
+                          fSkippedEventsCount(0),
+                          fNewEventsCount(0)
 {
   // see header file for class documentation
   // or
@@ -50,6 +58,8 @@ AliHLTTTreeProcessor::AliHLTTTreeProcessor()
   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
 }
 
+const AliHLTUInt32_t AliHLTTTreeProcessor::fgkTimeScale=1000000; // ticks per second
+
 AliHLTTTreeProcessor::~AliHLTTTreeProcessor()
 {
   // see header file for class documentation
@@ -115,6 +125,18 @@ int AliHLTTTreeProcessor::DoInit(int argc, const char** argv)
     return -EINVAL;
   }
 
+  if (iResult>=0 && fMaxEventTime>0) {
+    fpEventTimer=new TStopwatch;
+    if (fpEventTimer) {
+      fpEventTimer->Reset();
+    }
+    fpCycleTimer=new TStopwatch;
+    if (fpCycleTimer) {
+      fpCycleTimer->Reset();
+    }
+  }
+  fSkippedEventsCount=0;
+
   return iResult;
 }
 
@@ -124,6 +146,12 @@ int AliHLTTTreeProcessor::DoDeinit()
   delete fTree;
   fTree = 0;
   fDefinitions.clear();
+
+  if (fpEventTimer) delete fpEventTimer;
+  fpEventTimer=NULL;
+  if (fpCycleTimer) delete fpCycleTimer;
+  fpCycleTimer=NULL;
+
   return 0;
 }
 
@@ -141,10 +169,39 @@ int AliHLTTTreeProcessor::DoEvent(const AliHLTComponentEventData& evtData, AliHL
     return -EINVAL;//-ENULLTREE? :)
   }
 
+  AliHLTUInt32_t averageEventTime=0;
+  AliHLTUInt32_t averageCycleTime=0;
+
+  int fillingtime=0;
+  int publishtime=0;
+  bool bDoFilling=true;
+  bool bDoPublishing=false;
+  const int cycleResetInterval=1000;
+  if (fpEventTimer && fpCycleTimer) {
+    averageEventTime=(fpEventTimer->RealTime()*fgkTimeScale)/(GetEventCount()+1);
+    fillingtime=fpEventTimer->RealTime()*fgkTimeScale;
+    publishtime=fillingtime;
+    fpEventTimer->Start(kFALSE);
+    fpCycleTimer->Stop();
+    averageCycleTime=(fpCycleTimer->RealTime()*fgkTimeScale)/((GetEventCount()%cycleResetInterval)+1);
+    // adapt processing to 3/4 of the max time
+    bDoFilling=4*averageEventTime<3*fMaxEventTime || averageEventTime<averageCycleTime;
+    if (fNofEventsForce>0 && fForcedEventsCount<fNofEventsForce) {
+      fForcedEventsCount++;
+      bDoFilling=true;
+    }
+  }
+
   // process input data blocks and fill the tree
   int iResult = 0;
   if (eventType!=gkAliEventTypeEndOfRun) {
-    iResult=FillTree(fTree, evtData, trigData);
+    if (bDoFilling) {iResult=FillTree(fTree, evtData, trigData); fNewEventsCount++;}
+    else fSkippedEventsCount++;
+  }
+  if (fpEventTimer) {
+    fpEventTimer->Stop();
+    fillingtime=fpEventTimer->RealTime()*fgkTimeScale-fillingtime;
+    fpEventTimer->Start(kFALSE);
   }
 
   if (iResult < 0)
@@ -152,8 +209,9 @@ int AliHLTTTreeProcessor::DoEvent(const AliHLTComponentEventData& evtData, AliHL
 
   const TDatime time;
 
-  if (fLastTime - time.Get() > fPublishInterval ||
+  if (( time.Get() - fLastTime > fPublishInterval && fNewEventsCount>0) ||
       eventType==gkAliEventTypeEndOfRun) {
+    bDoPublishing=true;
     for (list_const_iterator i = fDefinitions.begin(); i != fDefinitions.end(); ++i) {
       if (TH1* h = CreateHistogram(*i)) {
         //I do not care about errors here - since I'm not able
@@ -163,10 +221,36 @@ int AliHLTTTreeProcessor::DoEvent(const AliHLTComponentEventData& evtData, AliHL
         PushBack(h, GetOriginDataType(), GetDataSpec());
       }
     }
+      unsigned eventcount=GetEventCount()+1;
+      HLTBenchmark("publishing %d histograms, %d entries in tree, %d new events since last publishing, accumulated %d of %d events (%.1f%%)", fDefinitions.size(), fTree->GetEntriesFast(), fNewEventsCount, eventcount-fSkippedEventsCount, eventcount, eventcount>0?(100*float(eventcount-fSkippedEventsCount)/eventcount):0);
+    fNewEventsCount=0;
 
     fLastTime = time.Get();
   }
 
+  if (fpEventTimer) {
+    fpEventTimer->Stop();
+    publishtime=fpEventTimer->RealTime()*fgkTimeScale-publishtime;
+    if (publishtime>fillingtime) publishtime-=fillingtime;
+    else publishtime=0;
+
+    averageEventTime=(fpEventTimer->RealTime()*fgkTimeScale)/(GetEventCount()+1);
+
+    // info output once every 5 seconds
+    static UInt_t lastTime=0;
+    if (time.Get()-lastTime>5 ||
+       eventType==gkAliEventTypeEndOfRun ||
+       bDoPublishing) {
+      lastTime=time.Get();
+      unsigned eventcount=GetEventCount()+1;
+      HLTBenchmark("filling time %d us, publishing time %d, average total processing time %d us, cycle time %d us, accumulated %d of %d events (%.1f%%)", fillingtime, publishtime, averageEventTime, averageCycleTime, eventcount-fSkippedEventsCount, eventcount, eventcount>0?(100*float(eventcount-fSkippedEventsCount)/eventcount):0);
+    }
+  }
+  if (fpCycleTimer) {
+    bool bReset=(GetEventCount()%cycleResetInterval)==0;
+    fpCycleTimer->Start(bReset);
+  }
+
   return iResult;
 }
 
@@ -220,6 +304,37 @@ int AliHLTTTreeProcessor::ScanConfigurationArgument(int argc, const char** argv)
 
       fPublishInterval = interval;
 
+      i += 2;
+    } else if (argument.CompareTo("-maxeventtime") == 0) { // max average processing time in us
+      if (i + 1 == argc) {
+        HLTError("Numeric value for '-maxeventtime' is expected");
+        return -EPROTO;
+      }
+
+      const Int_t time = TString(argv[i + 1]).Atoi();
+      if (time <= 0) {
+        HLTError("Bad value for '-maxeventtime' argument: %d", time);
+        return -EPROTO;
+      }
+
+      fMaxEventTime = time;
+
+      i += 2;
+    } else if (argument.CompareTo("-forced-events") == 0) { // number of forced events
+      if (i + 1 == argc) {
+        HLTError("Numeric value for '-forced-events' is expected");
+        return -EPROTO;
+      }
+
+      const Int_t count = TString(argv[i + 1]).Atoi();
+      if (count <= 0) {
+        HLTError("Bad value for '-forced-events' argument: %d", count);
+        return -EPROTO;
+      }
+
+      fNofEventsForce = count;
+      fForcedEventsCount=0;
+
       i += 2;
     } else if (argument.CompareTo("-histogram") == 0) { //3. Histogramm definition.
       const int nParsed = ParseHistogramDefinition(argc, argv, i, def);