Index: trunk/FACT++/src/EventBuilderWrapper.h
===================================================================
--- trunk/FACT++/src/EventBuilderWrapper.h	(revision 16380)
+++ trunk/FACT++/src/EventBuilderWrapper.h	(revision 16381)
@@ -332,7 +332,13 @@
             return;
 
+        fRunInProgress = -1;
+
         if (addr==tcp::endpoint())
         {
-            DisconnectSlot(i);
+            // In this order
+            g_port[i].sockDef = 0;
+
+            fDimIncomplete.setQuality(0);
+            fDimIncomplete.Update(uint64_t(0));
             return;
         }
@@ -351,15 +357,4 @@
     }
 
-    void DisconnectSlot(unsigned int i)
-    {
-        if (i>39)
-            return;
-
-        g_port[i].sockDef = 0;
-        // In this order
-
-        fDimIncomplete.setQuality(0);
-        fDimIncomplete.Update(uint64_t(0));
-    }
     void IgnoreSlot(unsigned int i)
     {
@@ -448,5 +443,5 @@
     }
 
-    virtual int CloseOpenFiles() { CloseRunFile(); return 0; }
+    virtual int CloseOpenFiles() { CloseRunFile(); fRunInProgress = -1; return 0; }
 
 
@@ -478,8 +473,8 @@
     }
 
-    bool runOpen(const shared_ptr<EVT_CTRL2> &evt)
-    {
-        const uint32_t night = evt->runCtrl->night;
-        const uint32_t runid = evt->runNum>0 ? evt->runNum : time(NULL);
+    bool runOpen(const EVT_CTRL2 &evt)
+    {
+        const uint32_t night = evt.runCtrl->night;
+        const uint32_t runid = evt.runNum>0 ? evt.runNum : time(NULL);
 
         // If there is still an open file: close it
@@ -489,5 +484,5 @@
         // Keep a copy of the currently valid drs calibration
         // and associate it to the run control structure
-        evt->runCtrl->calib = shared_ptr<DrsCalibration>(new DrsCalibration(DataCalib::GetCalibration()));
+        evt.runCtrl->calib = shared_ptr<DrsCalibration>(new DrsCalibration(DataCalib::GetCalibration()));
 
         // FIMXE: Check if file already exists...
@@ -509,7 +504,7 @@
             // Try to open the file
             FAD::RunDescription desc;
-            desc.name = evt->runCtrl->runType;
-
-            if (!file->Open(*evt, desc))
+            desc.name = evt.runCtrl->runType;
+
+            if (!file->Open(evt, desc))
                 return false;
         }
@@ -532,5 +527,5 @@
         fNumEvts[kTriggerId] = 0;
         fNumEvts[kCurrent]   = 0;
-        fDimQueue3.post(make_pair(Time(), fNumEvts));
+        fDimQueue3.emplace(Time(), fNumEvts);
 
         fDimWriteStats.FileOpened(file->GetFileName());
@@ -543,7 +538,7 @@
     }
 
-    bool runWrite(const shared_ptr<EVT_CTRL2> &e)
-    {
-        const EVENT &evt = *e->fEvent;
+    bool runWrite(const EVT_CTRL2 &e)
+    {
+        const EVENT &evt = *e.fEvent;
         if (!fFile->WriteEvt(evt))
             return false;
@@ -558,5 +553,5 @@
         if (newt>oldt+boost::posix_time::seconds(1))
         {
-            fDimQueue3.post(make_pair(Time(), fNumEvts));
+            fDimQueue3.emplace(Time(), fNumEvts);
             oldt = newt;
         }
@@ -594,5 +589,5 @@
 
         // Time for update events before time for update runs
-        fDimQueue3.post(make_pair(Time(), fNumEvts));
+        fDimQueue3.emplace(Time(), fNumEvts);
         UpdateRuns();
 
@@ -609,8 +604,7 @@
     }
 
-    bool eventCheck(const shared_ptr<EVT_CTRL2> &evt)
-    {
-        const PEVNT_HEADER *fadhd = evt->FADhead.get();
-        const EVENT *event = evt->fEvent;
+    bool eventCheck(const EVT_CTRL2 &evt)
+    {
+        const EVENT *event = evt.fEvent;
 
 	const array<uint16_t,2> roi = {{ event->Roi, event->RoiTM }};
@@ -618,10 +612,10 @@
 	if (roi!=fVecRoi)
         {
-            fDimQueue4.post(make_pair(Time(), roi));
+            fDimQueue4.emplace(Time(), roi);
 	    fVecRoi = roi;
 	}
 
-        const FAD::EventHeader *beg = reinterpret_cast<const FAD::EventHeader*>(fadhd);
-        const FAD::EventHeader *end = reinterpret_cast<const FAD::EventHeader*>(fadhd)+40;
+        const FAD::EventHeader *beg = reinterpret_cast<const FAD::EventHeader*>(evt.FADhead);
+        const FAD::EventHeader *end = reinterpret_cast<const FAD::EventHeader*>(evt.FADhead)+40;
 
         // FIMXE: Compare with target configuration
@@ -696,102 +690,111 @@
     }
 
+    map<float,array<float, 1440*4>> evtList;
+
     void applyCalib(const shared_ptr<EVT_CTRL2> &evt)
     {
-        const PEVNT_HEADER *fadhd = evt->FADhead.get();
-        const EVENT *event = evt->fEvent;
+        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;
-
-        static int skip = 0;
-
-        // FIXME: Only send events if the have newer run-numbers
-        if (newt<oldt+boost::posix_time::milliseconds(skip>0 ? 100 : 1000))
-            return;
-        oldt = newt;
-
-        // Workaround to find a valid header.....
-        const FAD::EventHeader *beg = reinterpret_cast<const FAD::EventHeader*>(fadhd);
-        const FAD::EventHeader *end = reinterpret_cast<const FAD::EventHeader*>(fadhd)+40;
-
-        // FIMXE: Compare with target configuration
-        const FAD::EventHeader *ptr=beg;
-        for (; ptr!=end; ptr++)
-        {
-            if (ptr->fStartDelimiter!=0)
-                break;
-        }
-        if (ptr==end)
-            return;
-
-
-        vector<char> data(sizeof(EVENT)+event->Roi*sizeof(float)*(1440+160));
-        memcpy(data.data(), event, sizeof(EVENT));
-
-        float *vec = reinterpret_cast<float*>(data.data()+sizeof(EVENT));
-
-        evt->runCtrl->calib->Apply(vec, event->Adc_Data, event->StartPix, event->Roi);
-        DrsCalibrate::RemoveSpikes(vec, event->Roi);
-
-        vector<float> data2(1440*4); // Mean, RMS, Max, Pos
-        const double max = DrsCalibrate::GetPixelStats(data2.data(), vec, event->Roi);
-
-        // Maximum above roughly 5pe
-        if (ptr->IsTriggerPhys() && max<100 && skip<10)
-        {
-            skip++;
-            return;
-        }
-
-        skip = 0;
-
-        fDimRawData.setQuality(ptr->fTriggerType);
-        fDimRawData.Update(data);
-
-        fDimEventData.setQuality(ptr->fTriggerType);
-        fDimEventData.Update(data2);
-
-    }
-
-    /*
-    void SendFeedbackData(PEVNT_HEADER *fadhd, EVENT *event)
-    {
-        if (!DataCalib::IsValid())
-            return;
-
-        // Workaround to find a valid header.....
-        const FAD::EventHeader *beg = reinterpret_cast<FAD::EventHeader*>(fadhd);
-        const FAD::EventHeader *end = reinterpret_cast<FAD::EventHeader*>(fadhd)+40;
-
-        // FIMXE: Compare with target configuration
-
-        const FAD::EventHeader *ptr=beg;
-        for (; ptr<end; ptr++)
-        {
-            if (ptr->fStartDelimiter!=0)
-                break;
-        }
-
-        if (ptr==end)
-            return;
-
-        if (!ptr->HasTriggerLPext() && !ptr->HasTriggerLPint())
-            return;
-
-        vector<float> data(event->Roi*1440);
-        DataCalib::Apply(data.data(), event->Adc_Data, event->StartPix, event->Roi);
-
-        DrsCalibrate::RemoveSpikes(data.data(), event->Roi);
-
-        vector<float> data2(1440); // Mean, RMS, Max, Pos, first, last
-        DrsCalibrate::GetPixelMax(data2.data(), data.data(), event->Roi, 0, event->Roi-1);
-
-        fDimFeedbackData.Update(data2);
-    }
-    */
-
-    bool IsRunWaiting()// const
+        if (newt>=oldt+boost::posix_time::milliseconds(100))
+        {
+            // Keep the last update time
+            oldt = newt;
+
+            // ------------------- Copy event data to new memory --------------------
+            // (to make it thread safe; a static buffer might improve memory handling)
+            const uint16_t roi = event->Roi;
+
+            // ------------------- Apply full DRS calibration ------------------------
+            // (Is that necessray, or would a simple offset correct do well already?)
+
+            // There seems to be a problem using std::array... maybe the size is too big?
+            // array<float, (1440+160)*1024> vec2;
+            vector<float> vec((1440+160)*roi);
+            run.calib->Apply(vec.data(), event->Adc_Data, start, roi);
+
+            // ------------------- Appy DRS-step correction --------------------------
+            for (auto it=run.prevStart.begin(); it!=run.prevStart.end(); it++)
+            {
+                DrsCalibrate::CorrectStep(vec.data(), 1440, roi, it->data(), start, roi+10);
+                DrsCalibrate::CorrectStep(vec.data(), 1440, roi, it->data(), start, 3);
+            }
+
+            // ------------------------- Remove spikes --------------------------------
+            DrsCalibrate::RemoveSpikes3(vec.data(), roi);
+
+            // -------------- 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;
+                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);
+            }
+
+            // ------------------------- Basic statistics -----------------------------
+            DrsCalibrate::SlidingAverage(vec.data(), roi, 10);
+
+            array<float, 1440*4> stats; // Mean, RMS, Max, Pos
+            const double max = DrsCalibrate::GetPixelStats(stats.data(), vec.data(), roi);
+
+            // ------------------ 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();
+            }
+
+            // === SendFeedbackData(PEVNT_HEADER *fadhd, EVENT *event)
+            //
+            //    if (!ptr->HasTriggerLPext() && !ptr->HasTriggerLPint())
+            //        return;
+            //
+            //    vector<float> data2(1440); // Mean, RMS, Max, Pos, first, last
+            //    DrsCalibrate::GetPixelMax(data2.data(), data.data(), event->Roi, 0, event->Roi-1);
+            //
+            //    fDimFeedbackData.Update(data2);
+        }
+
+        // Keep the start cells of the last five events for further corrections
+        // As a performance improvement we could also just store the
+        // 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();
+    }
+
+    bool IsRunWaiting()
     {
         const lock_guard<mutex> lock(mtx_newrun);
@@ -803,10 +806,4 @@
         return fRunNumber;
     }
-
-    /*
-    bool IsRunFileOpen()
-    {
-        return fLastOpened==fRunNumber-1;
-    }*/
 
     bool IncreaseRunNumber(uint32_t run)
@@ -953,5 +950,5 @@
     void factStat(const GUI_STAT &stat)
     {
-        fDimQueue1.post(make_pair(Time(), stat));
+        fDimQueue1.emplace(Time(), stat);
     }
 
@@ -1212,5 +1209,5 @@
         fNumConnected = con;
 
-        fDimQueue2.post(make_tuple(Time(), changed, h));
+        fDimQueue2.emplace(Time(), changed, h);
     }
 };
@@ -1219,10 +1216,10 @@
 
 // ----------- Event builder callbacks implementation ---------------
-bool runOpen(const shared_ptr<EVT_CTRL2> &evt)
+bool runOpen(const EVT_CTRL2 &evt)
 {
     return EventBuilderWrapper::This->runOpen(evt);
 }
 
-bool runWrite(const shared_ptr<EVT_CTRL2> &evt)
+bool runWrite(const EVT_CTRL2 &evt)
 {
     return EventBuilderWrapper::This->runWrite(evt);
@@ -1234,5 +1231,5 @@
 }
 
-bool eventCheck(const shared_ptr<EVT_CTRL2> &evt)
+bool eventCheck(const EVT_CTRL2 &evt)
 {
     return EventBuilderWrapper::This->eventCheck(evt);
