Index: trunk/FACT++/src/EventBuilderWrapper.h
===================================================================
--- trunk/FACT++/src/EventBuilderWrapper.h	(revision 16528)
+++ trunk/FACT++/src/EventBuilderWrapper.h	(revision 16530)
@@ -93,8 +93,10 @@
     DimDescribedService fDimIncomplete;
 
-    Queue<pair<Time,GUI_STAT>> fDimQueue1;
-    Queue<tuple<Time,bool,FAD::EventHeader>> fDimQueue2;
-    Queue<pair<Time,array<uint32_t,4>>> fDimQueue3;
-    Queue<pair<Time,array<uint16_t,2>>> fDimQueue4;
+    Queue<pair<Time,GUI_STAT>>                      fQueueStatistics1;
+    Queue<tuple<Time,bool,FAD::EventHeader>>        fQueueProcHeader;
+    Queue<pair<Time,array<uint32_t,4>>>             fQueueEvents;
+    Queue<pair<Time,array<uint16_t,2>>>             fQueueRoi;
+    Queue<vector<char>>                             fQueueRawData;
+    Queue<tuple<Time,uint32_t,array<float,1440*4>>> fQueueEventData;
 
     string   fPath;
@@ -104,4 +106,5 @@
 
     array<uint16_t,2> fVecRoi;
+    pair<float,array<float, 1440*4>> fMaxEvent; // Maximum event from applyCalib
 
 protected:
@@ -224,12 +227,8 @@
                                                            "|roi:Region of interest of secondary baseline"
                                                            "|run:Run numbers of DRS runs (0=none)"),
-        fDimStatistics1 ("FAD_CONTROL/STATISTICS1",        "I:3;I:5;X:4;I:3;I:3;I:40;I:1;I:2;C:40;I:40;X:40",
+        fDimStatistics1 ("FAD_CONTROL/STATISTICS1",        "I:5;X:3;I:1;I:2;C:40;I:40;X:40",
                                                            "Event Builder status for GUI display"
-                                                           "|threadInfo[int]:Number of read, proc and writes"
-                                                           "|bufferInfo[int]:Events in buffer, incomp., comp., tot., max past cycle, total"
-                                                           "|memInfo[int]:total buf. mem, used mem, max used, max past cycle"
-                                                           "|EvtCnt[int]:Number of events skipped, written, with errors"
-                                                           "|badRoi[int]:Num boards with wrong ROI in event, run or board"
-                                                           "|badRoiBoard[int]:Num boards with wrong ROI"
+                                                           "|bufferInfo[int]:Events in buffer, incomp., comp., write, proc., tot."
+                                                           "|memInfo[int]:total mem allocated, used mem, max memory"
                                                            "|deltaT[ms]:Time in ms for rates"
                                                            "|rateNew[int]:Number of new start events received"
@@ -240,9 +239,12 @@
         fDimIncomplete("FAD_CONTROL/INCOMPLETE",           "X:1", "|incomplete[bits]:One bit per board"),
         // It is important to instantiate them after the DimServices
-        fDimQueue1(std::bind(&EventBuilderWrapper::factStatSend, this, placeholders::_1)),
-        fDimQueue2(std::bind(&EventBuilderWrapper::procHeader, this, placeholders::_1)),
-        fDimQueue3(std::bind(&EventBuilderWrapper::updateEvents, this, placeholders::_1)),
-        fDimQueue4(std::bind(&EventBuilderWrapper::updateRoi, this, placeholders::_1)),
-        fNightAsInt(0), fRunInProgress(-1)
+        fQueueStatistics1(std::bind(&EventBuilderWrapper::UpdateDimStatistics1, this, placeholders::_1)),
+        fQueueProcHeader( std::bind(&EventBuilderWrapper::procHeader,           this, placeholders::_1)),
+        fQueueEvents(     std::bind(&EventBuilderWrapper::UpdateDimEvents,      this, placeholders::_1)),
+        fQueueRoi(        std::bind(&EventBuilderWrapper::UpdateDimRoi,         this, placeholders::_1)),
+        fQueueRawData(    std::bind(&EventBuilderWrapper::UpdateDimRawData,     this, placeholders::_1)),
+        fQueueEventData(  std::bind(&EventBuilderWrapper::UpdateDimEventData,   this, placeholders::_1)),
+        fNightAsInt(0), fRunInProgress(-1),
+        fMaxEvent(make_pair(-FLT_MAX, array<float,1440*4>()))
     {
         if (This)
@@ -467,5 +469,5 @@
     shared_ptr<DataProcessorImp> fFile;
 
-    void updateEvents(const pair<Time,array<uint32_t,4>> &stat)
+    void UpdateDimEvents(const pair<Time,array<uint32_t,4>> &stat)
     {
         fDimEvents.setData(stat.second.data(), sizeof(uint32_t)*4);
@@ -485,4 +487,15 @@
         // and associate it to the run control structure
         evt.runCtrl->calib = shared_ptr<DrsCalibration>(new DrsCalibration(DataCalib::GetCalibration()));
+
+        /*
+         evt.runCtrl->calibInt.resize(1024*1440);
+
+         const int16_t *off = evt.runCtrl->zcalib.data();
+         int32_t *ptr = evt.runCtrl->calib.data();
+
+         const uint64_t num = evt.runCtrl->calib.fNumOffset;
+         for (int i=0; i<1024*1440)
+             ptr[i] = off[i]/num;
+         */
 
         // FIMXE: Check if file already exists...
@@ -527,5 +540,5 @@
         fNumEvts[kTriggerId] = 0;
         fNumEvts[kCurrent]   = 0;
-        fDimQueue3.emplace(Time(), fNumEvts);
+        fQueueEvents.emplace(Time(), fNumEvts);
 
         fDimWriteStats.FileOpened(file->GetFileName());
@@ -540,4 +553,21 @@
     bool runWrite(const EVT_CTRL2 &e)
     {
+        /*
+        const size_t size = sizeof(EVENT)+1440*(evt.Roi+evt.RoiTM)*2;
+        vector evt(e.fEvent, e.fEvent+size);
+
+        const EVENT &evt = *reinterpret_cast<EVENT*>(evt.data());
+
+        int16_t *val = evt.Adc_Data;
+        const int16_t *off = e.runCtrl->zcalib.data();
+        for (const int16_t *start=evt.StartPix; start<evt.StartPix+1440; val+=1024, off+=1024, start++)
+        {
+            if (*start<0)
+                continue;
+
+            for (size_t i=0; i<roi; i++)
+                val[i] -= offset[(*start+i)%1024];
+        }*/
+
         const EVENT &evt = *e.fEvent;
         if (!fFile->WriteEvt(evt))
@@ -553,5 +583,5 @@
         if (newt>oldt+boost::posix_time::seconds(1))
         {
-            fDimQueue3.emplace(Time(), fNumEvts);
+            fQueueEvents.emplace(Time(), fNumEvts);
             oldt = newt;
         }
@@ -589,5 +619,5 @@
 
         // Time for update events before time for update runs
-        fDimQueue3.emplace(Time(), fNumEvts);
+        fQueueEvents.emplace(Time(), fNumEvts);
         UpdateRuns();
 
@@ -598,5 +628,5 @@
     virtual void CloseRun(uint32_t /*runid*/) { }
 
-    void updateRoi(const pair<Time, array<uint16_t,2>> &roi)
+    void UpdateDimRoi(const pair<Time, array<uint16_t,2>> &roi)
     {
         fDimRoi.setData(roi.second.data(), sizeof(uint16_t)*2);
@@ -612,5 +642,5 @@
 	if (roi!=fVecRoi)
         {
-            fDimQueue4.emplace(Time(), roi);
+            fQueueRoi.emplace(Time(), roi);
 	    fVecRoi = roi;
 	}
@@ -690,26 +720,33 @@
     }
 
-    map<float,array<float, 1440*4>> evtList;
-
-    void applyCalib(const shared_ptr<EVT_CTRL2> &evt)
-    {
-        const EVENT   *event = evt->fEvent;
+    Time fLastDimRawData;
+    Time fLastDimEventData;
+
+    void UpdateDimRawData(const vector<char> &v)
+    {
+        const EVENT *evt = reinterpret_cast<const EVENT*>(v.data());
+
+        fDimRawData.setData(v.data());
+        fDimRawData.setQuality(evt->TriggerType);
+        fDimRawData.Update(Time(evt->PCTime, evt->PCUsec));
+    }
+    void UpdateDimEventData(const tuple<Time,uint32_t,array<float, 1440*4>> &tup)
+    {
+        fDimEventData.setQuality(get<1>(tup));
+        fDimEventData.setData(get<2>(tup));
+        fDimEventData.Update(get<0>(tup));
+    }
+
+    void applyCalib(const EVT_CTRL2 &evt, const size_t &size)
+    {
+        const EVENT   *event = evt.fEvent;
         const int16_t *start = event->StartPix;
 
         // Get the reference to the run associated information
-        RUN_CTRL2 &run = *evt->runCtrl;
-
-        // Currently we send any event no matter what its trigger id is...
-        // To be changed.
-        static Time oldt(boost::date_time::neg_infin);
-
-        static uint64_t cnt = 0;
-
-        // In case of a need of more performance this cold be split to several threads
-        Time newt;
-        if (newt>=oldt+boost::posix_time::milliseconds(100))
-        {
-            // Keep the last update time
-            oldt = newt;
+        RUN_CTRL2 &run = *evt.runCtrl;
+
+        if (size==1) // If there is more than one event waiting (including this one), throw them away
+        {
+            Time now;
 
             // ------------------- Copy event data to new memory --------------------
@@ -736,17 +773,12 @@
 
             // -------------- Update raw data dim sevice (VERY SLOW) -----------------
-            const Time tm = evt->time;
-            if (++cnt%50==0)              // Once every 5s
-            {
-                //array<char,sizeof(EVENT)+(1440+160)*1024*sizeof(float)> data1;
+            if (fQueueRawData.empty() && now>fLastDimRawData+boost::posix_time::seconds(5))
+            {
                 vector<char> data1(sizeof(EVENT)+vec.size()*sizeof(float));
                 memcpy(data1.data(), event, sizeof(EVENT));
                 memcpy(data1.data()+sizeof(EVENT), vec.data(), vec.size()*sizeof(float));
-
-                // This needs to be decoupled for optimum performance!
-                // Make a queue which does not overfill by maintaining queue size!
-                fDimRawData.setQuality(evt->trgTyp);
-                fDimRawData.setData(data1.data(), sizeof(EVENT)+vec.size()*sizeof(float));
-                fDimRawData.Update(tm);
+                fQueueRawData.emplace(data1);
+
+                fLastDimRawData = now;
             }
 
@@ -754,23 +786,19 @@
             DrsCalibrate::SlidingAverage(vec.data(), roi, 10);
 
+            // If this is a cosmic event
             array<float, 1440*4> stats; // Mean, RMS, Max, Pos
-            const double max = DrsCalibrate::GetPixelStats(stats.data(), vec.data(), roi);
+            const float max = DrsCalibrate::GetPixelStats(stats.data(), vec.data(), roi);
+            if (evt.trgTyp==0 && max>fMaxEvent.first)
+                fMaxEvent = make_pair(max, stats);
 
             // ------------------ Update dim service (statistics) ---------------------
-            if (evt->trgTyp==0)
-                evtList[max] = stats;
-
-            if (cnt%50==0)
-            {
-                if (!evtList.empty())
-                    stats = evtList.rbegin()->second;
-
-                // This needs to be decoupled for optimum performance!
-                // Make a queue which does not overfill by maintaining queue size!
-                fDimEventData.setQuality(evtList.empty() ? evt->trgTyp : 0);
-                fDimEventData.setData(stats.data(), 1440*4*sizeof(float));
-                fDimEventData.Update(tm);
-
-                evtList.clear();
+
+            if (fQueueEventData.empty() && now>fLastDimEventData+boost::posix_time::seconds(3))
+            {
+                fQueueEventData.emplace(evt.time, evt.trgTyp, evt.trgTyp==0 ? fMaxEvent.second : stats);
+                if (evt.trgTyp==0)
+                    fMaxEvent.first = -FLT_MAX;
+
+                fLastDimEventData = now;
             }
 
@@ -790,8 +818,15 @@
         // pointers to the last five events...
         // What if a new run is started? Do we mind?
-        run.prevStart.emplace_front();
-        memcpy(run.prevStart.front().data(), start, 1440*sizeof(int16_t));
-        if (run.prevStart.size()>5)
-            run.prevStart.pop_back();
+        auto &l = run.prevStart; // History for start cells of previous events (for step calibration)
+
+        if (l.size()<5)
+            l.emplace_front();
+        else
+        {
+            auto it = l.end();
+            l.splice(l.begin(), l, --it);
+        }
+
+        memcpy(l.front().data(), start, 1440*sizeof(int16_t));
     }
 
@@ -942,5 +977,5 @@
     */
 
-    void factStatSend(const pair<Time,GUI_STAT> &stat)
+    void UpdateDimStatistics1(const pair<Time,GUI_STAT> &stat)
     {
         fDimStatistics1.setData(&stat.second, sizeof(GUI_STAT));
@@ -950,5 +985,5 @@
     void factStat(const GUI_STAT &stat)
     {
-        fDimQueue1.emplace(Time(), stat);
+        fQueueStatistics1.emplace(Time(), stat);
     }
 
@@ -1209,5 +1244,5 @@
         fNumConnected = con;
 
-        fDimQueue2.emplace(Time(), changed, h);
+        fQueueProcHeader.emplace(Time(), changed, h);
     }
 };
@@ -1246,7 +1281,7 @@
 }
 
-void applyCalib(const shared_ptr<EVT_CTRL2> &evt)
+void applyCalib(const EVT_CTRL2 &evt, const size_t &size)
 {
-    EventBuilderWrapper::This->applyCalib(evt);
+    EventBuilderWrapper::This->applyCalib(evt, size);
 }
 
@@ -1256,5 +1291,5 @@
 }
 
-void factStat(GUI_STAT stat)
+void factStat(const GUI_STAT &stat)
 {
     EventBuilderWrapper::This->factStat(stat);
