Index: trunk/FACT++/src/feedback.cc
===================================================================
--- trunk/FACT++/src/feedback.cc	(revision 16387)
+++ trunk/FACT++/src/feedback.cc	(revision 16412)
@@ -37,5 +37,4 @@
         kFeedbackGlobal,
         kCurrents,
-        kCurrentsNew,
     };
 
@@ -95,5 +94,5 @@
     int HandleCameraTemp(const EventImp &evt)
     {
-        if (fControlType!=kTemp && fControlType!=kCurrents && fControlType!=kCurrentsNew)
+        if (fControlType!=kTemp && fControlType!=kCurrents)
             return GetCurrentState();
 
@@ -124,242 +123,5 @@
         fCursorTemp++;
 
-        return fControlType==kCurrentsNew ? HandleCurrentControlNew() : HandleCurrentControl();
-    }
-
-    int HandleCurrentControlNew()
-    {
-        if (GetCurrentState()==Feedback::State::kCalibrating && fBiasOffset>fTempOffset-1.2)
-        {
-            fCursorTemp = 0;
-
-            ostringstream msg;
-            msg << " (applied calibration offset " << fBiasOffset << "V exceeds temperature correction " << fTempOffset << "V - 1.2V.";
-            Warn("Trying to calibrate above G-APD breakdown volatge!");
-            Warn(msg);
-            return GetCurrentState();
-        }
-
-        double avg[2] = {   0,   0 };
-        double min[2] = {  90,  90 };
-        double max[2] = { -90, -90 };
-        int    num[2] = {   0,   0 };
-
-        vector<double> med[2];
-        med[0].resize(416);
-        med[1].resize(416);
-
-        const float *Ravg = fCalibration.data()+BIAS::kNumChannels*2; // Measured resistance
-
-        vector<float> vec(2*BIAS::kNumChannels+2);
-
-        vec[BIAS::kNumChannels*2]   = fTempOffset;
-        vec[BIAS::kNumChannels*2+1] = fBiasOffset;
-
-        float *Uoff = vec.data()+BIAS::kNumChannels;
-
-        if (GetCurrentState()==Feedback::State::kCalibrating)
-            for (int i=0; i<BIAS::kNumChannels; i++)
-                Uoff[i] = fBiasOffset;
-        else
-            for (int i=0; i<BIAS::kNumChannels; i++)
-                Uoff[i] = fTempOffset+fBiasOffset;
-
-        if (fControlType==kCurrentsNew)
-        {
-            // Would be a devision by zero. We need informations first.
-            if (fCursorCur==0)
-                return GetCurrentState();
-
-            for (int i=0; i<BIAS::kNumChannels; i++)
-            {
-                const PixelMapEntry &hv = fMap.hv(i);
-                if (!hv)
-                    continue;
-
-                // Nominal breakdown voltage (includes overvoltage already)
-                double Ubd = fVoltGapd[i];
-
-                // Nominal breakdown voltage excluding overvoltage of 1.1V
-                Ubd -= 1.1;
-
-                // Correct breakdown voltage for temperature dependence
-                Ubd += fTempOffset;
-
-                // Number of G-APDs in this patch
-                const int N = hv.group() ? 5 : 4;
-
-                // 100 Ohm measurement resistor for current measurement
-                const double R2 = 100;
-
-                // Serial resistors (one 1kOhm at the output of the bias crate, one 1kOhm in the camera)
-                const double R4 = 2000;
-
-                // Serial resistor of the individual G-APDs
-                double R5 = 3900/N;
-
-                // This is assuming that the broken pixels have a 390 Ohm instead of 3900 Ohm serial resistor
-                if (i==66)                 // Pixel 830(66)
-                    R5 = 300;              // 2400 = 1/(3/3900 + 1/390)
-                if (i==191 || i==193)      // Pixel 583(191) / Pixel 1401(193)
-                    R5 = 390/1.4;          // 379 = 1/(4/3900 + 1/390)
-
-                // Total resistance of branch with diode
-                const double R3 = R4+R5;
-
-                // Measured calibration resistor
-                const double R1 = Ravg[i] - R2;
-
-                // Voltage output of bias crate
-                const double Uout = fBiasVolt[i];
-
-                // Average current measured for this channel
-                const double Imes = double(fCurrentsAvg[i])/fCursorCur * (5000/4096.); // [uA]
-
-                // Voltage drop at measurement resistor R2 is define
-                // bythe measured current and the resistor
-                const double U2 = R2*Imes;
-
-                // The voltage seen by the calibration resistor R1 is defined by the
-                // bias crate output voltage minus the drop at the measurement resistor R2
-                const double U1 = Uout - U2;
-
-                // The current through the resistor R1 is defined
-                // by the applied voltage and the resistor
-                const double I1 = U1/R1;
-
-                // The current through the diode branch is the measured current
-                // minus the current through the calibration resistor R1
-                const double I3 = Imes - I1;
-
-                // The voltage drop in the diode branch (without the diode) is defined by the
-                // resistor and the current. It is 0 below the breakdown voltage of the G-APD
-                // is reached at the G-APD. This is the case when the output voltage minus
-                // the voltage drop at the calibration resistor reaches the breakdown voltage.
-                const double U3 = Uout-U2<Ubd ? 0 : R3*I3;
-
-                // Voltage drop at measurement resistor R2 and
-                // the total serial resistor R3 in the diode branch
-                const double Udrp = U2 + U3;
-
-                // Voltage finally at each G-APD (bias crate output voltage minus voltage drop)
-                const double Uapd = Uout - Udrp;
-
-                // The over-voltage seen by the G-APD (the voltage above the breakdown voltage) is
-                const double Uov = Uapd<Ubd ? 0 : Uapd - Ubd;
-
-                // The current through one G-APD is the sum divided by the number of G-APDs
-                // (assuming identical serial resistors)
-                double Iapd = I3/N;
-
-                // This is assuming that the broken pixels have a 390 Ohm instead of 3900 Ohm serial resistor
-                // In this and the previosu case we neglect the resistance of the G-APDs, but we can make an
-                // assumption: The differential resistance depends more on the NSB than on the PDE,
-                // thus it is at least comparable for all G-APDs in the patch. In addition, although the
-                // G-APD with the 390Ohm serial resistor has the wrong voltage applied, this does not
-                // significantly influences the ohmic resistor or the G-APD because the differential
-                // 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 the G-APD voltage is above the breakdown voltage we have the current through the
-                // G-APD and the over-voltage applied to the G-APD to calculate its differential resistor.
-                if (Uapd>Ubd)
-                {
-                    // The differential resistance of the G-APD, i.e. the dependence of the
-                    // current above the breakdown voltage, is given by
-                    const double Rapd = Uov/Iapd;
-
-                    // This allows us to estimate the current Iov at the overvoltage we want to apply
-                    const double Iov = (1.1+fBiasOffset)/Rapd;
-
-                    // This gives us an ohmic resistance Rov of the G-APD at the set-point
-                    const double Rest = (Ubd+1.1+fBiasOffset)/Iov;
-
-                    // This lets us estimate the total resistance Rtot of the circuit at the set-point
-                    const double R3b  = R4 + (R5+Rest)/N;
-                    const double Rtot = R2 + 1/(1/R1 + 1/R3b);
-
-                    // From this we can estimate the output voltage we need to get the
-                    // over-voltage at the G-APD as anticipated
-                    const double r    = 1 + R3/R1 - (R2 + R3 + R3*R2/R1)/Rtot;
-                    const double Uset = (Ubd+1.1+fBiasOffset)/r;
-
-                    Uoff[i] = Uset - fVoltGapd[i];
-                }
-
-                 // Calculate statistics only for channels with a valid calibration
-                 if (Uov>0)
-                 {
-                     const int g = hv.group();
-
-                     med[g][num[g]] = Uov;
-                     avg[g] += Uov;
-                     num[g]++;
-
-                     if (Uov<min[g])
-                         min[g] = Uov;
-                     if (Uov>max[g])
-                         max[g] = Uov;
-                 }
-            }
-
-            sort(med[0].begin(), med[0].begin()+num[0]);
-            sort(med[1].begin(), med[1].begin()+num[1]);
-
-            fCurrentsAvg.assign(BIAS::kNumChannels, 0);
-            fCursorCur = 0;
-        }
-
-        fDimDeviation.setQuality(fControlType);
-        fDimDeviation.Update(vec);
-
-        // Warning: Here it is assumed that the ramp up and down is done properly
-        // within the time between two new temperatures and that the calibration
-        // is finished within that time.
-        if (GetCurrentState()!=Feedback::State::kCalibrating ||
-            fDimBias.state()!=BIAS::State::kVoltageOff ||
-            fCursorTemp!=1 || !fOutputEnabled)
-        {
-            if (!fOutputEnabled || fDimBias.state()!=BIAS::State::kVoltageOn)
-                return GetCurrentState();
-
-            // Trigger calibration
-            if (GetCurrentState()==Feedback::State::kCalibrating && fCursorTemp==2)
-            {
-                DimClient::sendCommandNB("BIAS_CONTROL/REQUEST_STATUS", NULL, 0);
-                return GetCurrentState();
-            }
-        }
-
-        ostringstream msg;
-        msg << setprecision(4) << "Sending new absolute offset (" << fAppliedOffset << "V+" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0) << "V) to biasctrl.";
-        Info(msg);
-
-        if (fControlType==kCurrents && num[0]>0 && num[1]>0)
-        {
-            msg.str("");
-            msg << "   Avg0=" << setw(7) << avg[0]/num[0]    << "  |  Avg1=" << setw(7) << avg[1]/num[1];
-            Debug(msg);
-
-            msg.str("");
-            msg << "   Med0=" << setw(7) << med[0][num[0]/2] << "  |  Med1=" << setw(7) << med[1][num[1]/2];
-            Debug(msg);
-
-            msg.str("");
-            msg << "   Min0=" << setw(7) << min[0]           << "  |  Min1=" << setw(7) << min[1];
-            Debug(msg);
-
-            msg.str("");
-            msg << "   Max0=" << setw(7) << max[0]           << "  |  Max1=" << setw(7) << max[1];
-            Debug(msg);
-        }
-
-        DimClient::sendCommandNB("BIAS_CONTROL/SET_ALL_CHANNELS_OFFSET",
-                                 vec.data()+BIAS::kNumChannels, BIAS::kNumChannels*sizeof(float));
-
-        return GetCurrentState();
+        return HandleCurrentControl();
     }
 
@@ -965,5 +727,5 @@
     void HandleCalibrateCurrents(const EventImp &evt)
     {
-        if (fBiasVolt.empty() || fCalibration.empty() || evt.GetSize()<416*sizeof(int16_t))
+        if (fBiasVolt.size()==0 || fCalibration.size()==0 || evt.GetSize()<416*sizeof(int16_t))
             return;
 
@@ -1044,5 +806,5 @@
             HandleCalibration(evt);
 
-        if (fControlType==kFeedbackGlobal || fControlType==kCurrents || fControlType==kCurrentsNew)
+        if (fControlType==kFeedbackGlobal || fControlType==kCurrents)
             AverageCurrents(evt);
 
@@ -1113,5 +875,5 @@
     int PrintCalibration()
     {
-        if (fCalibration.empty())
+        if (fCalibration.size()==0)
         {
             Out() << "No calibration performed so far." << endl;
@@ -1191,5 +953,5 @@
         fOutputEnabled = evt.GetBool();
 
-        if (fControlType==kCurrents || fControlType==kCurrentsNew)
+        if (fControlType==kCurrents)
             if (fCursorTemp>1)
                 fCursorTemp = 1;
@@ -1281,5 +1043,5 @@
             return kSM_FatalError;
 
-        if (fCalibration.empty())
+        if (fCalibration.size()==0)
         {
             Warn("Current control needs a bias crate calibration first... command ignored.");
@@ -1301,29 +1063,4 @@
     }
 
-    int StartNewCurrentCtrl(const EventImp &evt)
-    {
-        if (!CheckEventSize(evt.GetSize(), "StartNewCurrentCtrl", 4))
-            return kSM_FatalError;
-
-        if (fCalibration.empty())
-        {
-            Warn("Current control needs a bias crate calibration first... command ignored.");
-            return GetCurrentState();
-        }
-
-        WarnState(true, false);
-
-        fBiasOffset = evt.GetFloat();
-        fTempOffset = -3;
-        ResetData(0);
-        fControlType = kCurrentsNew;
-
-        ostringstream out;
-        out << "Starting new current/temp feedback with an offset of " << fBiasOffset << "V";
-        Message(out);
-
-        return GetCurrentState();
-    }
-
     int StopFeedback()
     {
@@ -1393,5 +1130,5 @@
         }
 
-        if (fVoltGapd.empty())
+        if (fVoltGapd.size()==0)
         {
             Error("No G-APD reference voltages received yet (BIAS_CONTROL/NOMINAL).");
@@ -1511,5 +1248,5 @@
                 return fOutputEnabled ? Feedback::State::kTempCtrlRunning : Feedback::State::kTempCtrlIdle;
             }
-            if (fControlType==kCurrents || fControlType==kCurrentsNew)
+            if (fControlType==kCurrents)
             {
                 static Time past;
