Index: /trunk/FACT++/src/feedback.cc
===================================================================
--- /trunk/FACT++/src/feedback.cc	(revision 17029)
+++ /trunk/FACT++/src/feedback.cc	(revision 17030)
@@ -194,4 +194,7 @@
     int HandleCalibration(const EventImp &evt)
     {
+        if (fDimBias.state()!=BIAS::State::kVoltageOn)
+            return GetCurrentState();
+
         const uint16_t dac = 256+512*fCalibStep; // Command value
 
@@ -312,5 +315,6 @@
         }
 
-        vector<float> v(BIAS::kNumChannels*2);
+        vector<float> v;
+        v.reserve(BIAS::kNumChannels*2);
         v.insert(v.end(), fCalibDeltaI.begin(), fCalibDeltaI.end());
         v.insert(v.end(), fCalibR8.begin(),     fCalibR8.end());
@@ -333,9 +337,4 @@
 
         if (GetCurrentState()<Feedback::State::kCalibrating)
-            return GetCurrentState();
-
-        // FIXME? Allow for calibrated currents also during ramping?
-        if ((GetCurrentState()!=Feedback::State::kWaitingForData || fDimBias.state()!=BIAS::State::kVoltageOff) &&
-            fDimBias.state()!=BIAS::State::kVoltageOn)
             return GetCurrentState();
 
@@ -362,5 +361,7 @@
         // ---------------------- Calibrated, WaitingForData, InProgress -----------------------
 
-        const vector<float> &Imes = AverageCurrents(evt.Ptr<int16_t>(), 3).first;
+        const int Navg = fDimBias.state()!=BIAS::State::kVoltageOn ? 1 : 3;
+
+        const vector<float> &Imes = AverageCurrents(evt.Ptr<int16_t>(), Navg).first;
         if (Imes.size()==0)
             return GetCurrentState();
@@ -408,6 +409,4 @@
         vector<float> vec(416);
 
-        cout << setprecision(4) << endl;
-
         if (fEnableOldAlgorithm)
         {
@@ -458,5 +457,5 @@
 
                 if (i==2)
-                    cout << dU << endl;;
+                    cout << setprecision(4)<< dU << endl;;
 
                 vec[i] = Ubd + overvoltage + dU;
@@ -523,5 +522,5 @@
 
                 // Serial resistor of the individual G-APDs
-                double R5 = 3900/N;
+                double R5 = 3900./N;
 
                 // This is assuming that the broken pixels have a 390 Ohm instead of 3900 Ohm serial resistor
@@ -581,8 +580,6 @@
                 // resistor is large enough that the increase of the overvoltage does not dramatically
                 // increase the current flow as compared to the total current flow.
-                if (i==66)
-                    Iapd /= 1.3;
-                if (i==191 || i==193)
-                    Iapd /= 1.4;
+                if (i==66 || i==191 || i==193)
+                    Iapd = Iout/(N+9); // Iapd = R5*Iout/3900;
 
                 // The differential resistance of the G-APD, i.e. the dependence of the
@@ -590,12 +587,17 @@
                 //const double Rapd = Uov/Iapd;
                 // This allows us to estimate the current Iov at the overvoltage we want to apply
-                //const double Iov = pow(overvoltage, 1)/Rapd;
+                //const double Iov = overvoltage/Rapd;
 
                 // Estimate set point for over-voltage (voltage drop at the target point)
                 //const double Uset = Ubd + overvoltage + R*Iov*N;
-                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);
 
                 // Voltage set point
                 vec[i] = Uset;
+
+                if (fDimBias.state()==BIAS::State::kVoltageOn && GetCurrentState()==Feedback::State::kInProgress &&
+                    fabs(Uov-overvoltage)>0.033)
+                    cout << setprecision(4) << setw(3) << i << ": Uov=" << Uov << " Udrp=" << Udrp << " Iapd=" << Iapd*1e6 << endl;
+
 
                 // Calculate statistics only for channels with a valid calibration
@@ -628,24 +630,34 @@
         // ------------------------------- Update voltages ------------------------------------
 
-        if (GetCurrentState()!=Feedback::State::kCalibrated)
-        {
-            DimClient::sendCommandNB("BIAS_CONTROL/SET_ALL_CHANNELS_VOLTAGE",
-                                     vec.data(), BIAS::kNumChannels*sizeof(float));
-
-            ostringstream msg;
-            msg << setprecision(4) << "Sending new absolute offset: dU(" << fTemp << "degC)=" << fTempOffset << "V, Unom=" << overvoltage << "V, Uov=" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0);
-            Info(msg);
+        if (GetCurrentState()!=Feedback::State::kCalibrated) // WaitingForData, InProgress
+        {
+            if (fDimBias.state()!=BIAS::State::kRamping)
+            {
+                DimClient::sendCommandNB("BIAS_CONTROL/SET_ALL_CHANNELS_VOLTAGE",
+                                         vec.data(), BIAS::kNumChannels*sizeof(float));
+
+                ostringstream msg;
+                msg << setprecision(4) << "Sending new absolute offset: dU(" << fTemp << "degC)=" << fTempOffset << "V, Unom=" << overvoltage << "V, Uov=" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0);
+                Info(msg);
+            }
         }
         else
         {
-            ostringstream msg;
-            msg << setprecision(4) << "Current status: dU(" << fTemp << "degC)=" << fTempOffset << "V, Unom=" << overvoltage << "V, Uov=" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0);
-            Info(msg);
-
-        }
+            if (fDimBias.state()==BIAS::State::kVoltageOn)
+            {
+                ostringstream msg;
+                msg << setprecision(4) << "Current status: dU(" << fTemp << "degC)=" << fTempOffset << "V, Unom=" << overvoltage << "V, Uov=" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0);
+                Info(msg);
+            }
+
+        }
+
+        if (GetCurrentState()==Feedback::State::kInProgress &&
+            fDimBias.state()==BIAS::State::kRamping)
+            return GetCurrentState();
 
         // --------------------------------- Console out --------------------------------------
 
-        if (num[0]>0 && num[1]>0 && fIsVerbose)
+        if (num[0]>0 && num[1]>0 && fIsVerbose && !fDimBias.state()==BIAS::State::kRamping)
         {
             sort(med[0].begin(), med[0].begin()+num[0]);
@@ -816,4 +828,10 @@
         if (!CheckEventSize(evt.GetSize(), "Start", 4))
             return kSM_FatalError;
+
+        if (fDimBias.state()==BIAS::State::kRamping)
+        {
+            Warn("Feedback can not be started when biasctrl is in state Ramping.");
+            return GetCurrentState();
+        }
 
         fUserOffset = evt.GetFloat();
