Index: trunk/FACT++/src/feedback.cc
===================================================================
--- trunk/FACT++/src/feedback.cc	(revision 17202)
+++ trunk/FACT++/src/feedback.cc	(revision 17203)
@@ -43,4 +43,5 @@
     DimDescribedService fDimCalibrationR8;
     DimDescribedService fDimCurrents;
+    DimDescribedService fDimOffsets;
 
     vector<float>    fCalibCurrentMes[6]; // Measured calibration current at six different levels
@@ -70,4 +71,6 @@
     double fTempCoefficient;
     double fTemp;
+
+    vector<double> fVoltOffset;
 
     uint16_t fCurrentRequestInterval;
@@ -399,4 +402,6 @@
         } __attribute__((__packed__));
 
+        int Ndev[3] = { 0, 0, 0 };
+
         dim_data data;
 
@@ -507,5 +512,5 @@
 
             // Current in R4/R5 branch
-            const double Iout = I8>I9 ? I8 - I9 : 0;
+            const double Iout = I8 - I9;//I8>I9 ? I8 - I9 : 0;
 
             // Applied voltage at calibration resistors, according to biasctrl
@@ -547,8 +552,9 @@
 
             // Nominal breakdown voltage with correction for temperature dependence
-            const double Ubd = fVoltGapd[i] + fTempOffset[i];
+            const double Ubd = fVoltGapd[i] + fVoltOffset[i] + fTempOffset[i];
 
             // Current overvoltage (at a G-APD with the correct 3900 Ohm resistor)
-            const double Uov = U9-Udrp-Ubd>0 ? U9-Udrp-Ubd : 0;
+            //const double Uov = U9-Udrp-Ubd>0 ? U9-Udrp-Ubd : 0;
+            const double Uov = U9-Udrp-Ubd>-0.34 ? U9-Udrp-Ubd : -0.34;
 
             // Iout linear with U9 above Ubd
@@ -591,5 +597,15 @@
             // Estimate set point for over-voltage (voltage drop at the target point)
             //const double Uset = Ubd + overvoltage + R*Iov*N;
-            const double Uset = Uov<0.3 ? Ubd + overvoltage + Udrp : Ubd + overvoltage + Udrp*pow(overvoltage/Uov, 1.66);
+            //const double Uset = Uov<0.3 ? Ubd + overvoltage + Udrp : Ubd + overvoltage + Udrp*pow(overvoltage/Uov, 1.66);
+            const double Uset = Uov<0 ?
+                Ubd + overvoltage + Udrp*pow(overvoltage/0.34+1, 1.66) :
+                Ubd + overvoltage + Udrp*pow((overvoltage+0.34)/(Uov+0.34), 1.66);
+
+            if (fabs(overvoltage-Uov)>0.033)
+                Ndev[0]++;
+            if (fabs(overvoltage-Uov)>0.022)
+                Ndev[1]++;
+            if (fabs(overvoltage-Uov)>0.011)
+                Ndev[2]++;
 
             // Voltage set point
@@ -638,5 +654,5 @@
 
                 ostringstream msg;
-                msg << setprecision(4) << "Sending new absolute offset: dU(" << fTemp << "degC)=" << fTempOffsetAvg << "V+-" << fTempOffsetRms << ", Unom=" << overvoltage << "V, Uov=" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0);
+                msg << setprecision(4) << "Sending new absolute offset: dU(" << fTemp << "degC)=" << fTempOffsetAvg << "V+-" << fTempOffsetRms << ", Unom=" << overvoltage << "V, Uov=" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0) << " [N=" << Ndev[0] << "/" << Ndev[1] << "/" << Ndev[2] << "]";
                 Info(msg);
             }
@@ -647,5 +663,5 @@
             {
                 ostringstream msg;
-                msg << setprecision(4) << "Current status: dU(" << fTemp << "degC)=" << fTempOffsetAvg << "V+-" << fTempOffsetRms << ", Unom=" << overvoltage << "V, Uov=" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0);
+                msg << setprecision(4) << "Current status: dU(" << fTemp << "degC)=" << fTempOffsetAvg << "V+-" << fTempOffsetRms << ", Unom=" << overvoltage << "V, Uov=" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0) << " [N=" << Ndev[0] << "/" << Ndev[1] << "/" << Ndev[2] << "]";
                 Info(msg);
             }
@@ -850,4 +866,46 @@
         return GetCurrentState();
     }
+
+    bool LoadOffsets(const string &file)
+    {
+        vector<double> data(416);
+
+        ifstream fin(file);
+
+        int cnt = 0;
+        while (fin && cnt<320)
+            fin >> data[cnt++];
+
+        if (cnt!=320)
+        {
+            Error("Reading offsets from "+file+" failed [N="+to_string(cnt-1)+"]");
+            return false;
+        }
+
+        fVoltOffset = data;
+
+        fDimOffsets.Update(fVoltOffset);
+
+        Info("New voltage offsets loaded from "+file);
+        return true;
+
+    }
+
+    int LoadOffset(const EventImp &evt)
+    {
+        LoadOffsets(evt.GetText());
+        return GetCurrentState();
+    }
+
+    int ResetOffset()
+    {
+        fVoltOffset.assign(416, 0);
+
+        fDimOffsets.Update(fVoltOffset);
+
+        Info("Voltage offsets resetted.");
+        return GetCurrentState();
+    }
+
 
     int Execute()
@@ -926,4 +984,8 @@
                      "|dU_temp[V]:Correction calculated from temperature"
                     ),
+        fDimOffsets("FEEDBACK/OFFSETS", "F:416",
+                    "Offsets operation voltages"
+                    "|U[V]:Offset per bias channels"),
+        fVoltOffset(416),
         fCurrentRequestInterval(0),
         fNumCalibIgnore(30),
@@ -988,4 +1050,11 @@
             ("Stop any control loop");
 
+        AddEvent("LOAD_OFFSETS", "C", Feedback::State::kConnected, Feedback::State::kCalibrated)
+            (bind(&StateMachineFeedback::LoadOffset, this, placeholders::_1))
+            ("");
+        AddEvent("RESET_OFFSETS", Feedback::State::kConnected, Feedback::State::kCalibrated)
+            (bind(&StateMachineFeedback::ResetOffset, this))
+            ("");
+
 
         AddEvent("PRINT")
@@ -1017,4 +1086,7 @@
         fNumCalibRequests       = conf.Get<uint16_t>("num-calib-average");
         fTempCoefficient        = conf.Get<double>("temp-coefficient");
+
+        if (conf.Has("offset-file"))
+            LoadOffsets(conf.Get<string>("offset-file"));
 
         return -1;
@@ -1042,4 +1114,5 @@
         ("num-calib-average",   var<uint16_t>(300), "Number of current requests to be averaged")
         ("temp-coefficient",    var<double>()->required(), "Temp. coefficient [V/K]")
+        ("offset-file",         var<string>(), "File with operation voltage offsets")
         ;
 
