Index: /trunk/FACT++/src/ratecontrol.cc
===================================================================
--- /trunk/FACT++/src/ratecontrol.cc	(revision 12434)
+++ /trunk/FACT++/src/ratecontrol.cc	(revision 12435)
@@ -40,5 +40,4 @@
         kStateConnected,
 
-        kStateWaitingForReference,
         kStateSettingGlobalThreshold,
         kStateGlobalThresholdSet,
@@ -64,4 +63,5 @@
 
     uint16_t fThresholdMin;
+    uint16_t fThresholdReference;
 
     bool fTriggerOn;
@@ -214,4 +214,8 @@
                 if (maxi==j)
                 {
+                    // This is the step which has to be performed to go from
+                    // a NSB rate of sdata.fPatchRate[i*4+j]
+
+
                     const float step = (log10(sdata.fPatchRate[i*4+j])-log10(mp+5*dp))/0.039;
                     //  * (dif-5)/dif
@@ -259,5 +263,5 @@
         for (int i=0; i<40; i++)
         {
-            if ( fabs(sdata.fBoardRate[i]-mb)<5*db)
+            if ( fabs(sdata.fBoardRate[i]-mb)<3*db)
             {
                 avg += sdata.fBoardRate[i];
@@ -272,16 +276,24 @@
             Out() << "Board:  Median=" << mb << " Dev=" << db << endl;
             Out() << "Camera: " << fTriggerRate << " (" << sdata.fTriggerRate << ", n=" << num << ")" << endl;
+            Out() << "Target: " << fTargetRate << endl;
         }
 
         // ----------------------
 
-
-        if (fTriggerRate<fTargetRate)
-            return;
-
-        // Is this a step to 70Hz?
-        const float step = (log10(fTriggerRate)-log10(fTargetRate))/0.039;
+        if (fTriggerRate>0 && fTriggerRate<fTargetRate)
+        {
+            // I am assuming here (and at other places) the the answer from the FTM when setting
+            // the new threshold always arrives faster than the next rate update.
+            fThresholdMin = fThresholds[0];
+            return;
+        }
+
+        // This is a step towards a threshold at which the NSB rate is equal the target rate
+        // +1 to avoid getting a step of 0
+        const float step = (log10(fTriggerRate)-log10(fTargetRate))/0.039 + 1;
 
         const uint16_t diff = fThresholds[0]+int16_t(truncf(step));
+
+        cout << diff << endl;
 
         if (diff==fThresholds[0])
@@ -327,11 +339,9 @@
 
             const FTM::DimStaticData &sdata = *static_cast<FTM::DimStaticData*>(curr->getData());
-
+            fTriggerOn = sdata.HasTrigger();
+ 
             PrintThresholds(sdata);
 
-            fTriggerOn = sdata.HasTrigger();
-
             fThresholds.assign(sdata.fThreshold, sdata.fThreshold+160);
-
             return;
         }
@@ -342,5 +352,5 @@
                 return;
 
-            if (!fTriggerOn)
+            if (!fTriggerOn && !fEnabled)
                 return;
 
@@ -358,15 +368,31 @@
     }
 
-    int StartDataTaking()
-    {
-        if (!fEnabled)
+    int Calibrate()
+    {
+        if (!fTriggerOn)
             return kStateGlobalThresholdSet;
 
-        fThresholds.resize(0);
-
-        const int32_t val[2] = { -1, fThresholdMin };
+        const int32_t val[2] = { -1, fThresholdReference };
         Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", val);
 
-        return kStateWaitingForReference;
+        fThresholds.assign(160, fThresholdReference);
+
+        fThresholdMin = fThresholdReference;
+        fTriggerRate  = -1;
+        fEnabled      = true;
+
+        return kStateSettingGlobalThreshold;
+    }
+
+    int StartRC()
+    {
+        fEnabled = true;
+        return GetCurrentState();
+    }
+
+    int StopRC()
+    {
+        fEnabled = false;
+        return GetCurrentState();
     }
 
@@ -388,5 +414,5 @@
         // FIXME: Check missing
 
-        fThresholdMin = evt.GetUShort();
+        fThresholdReference = evt.GetUShort();
 
         return GetCurrentState();
@@ -453,15 +479,7 @@
             return kStateDisconnected;
 
-        if (GetCurrentState()==kStateWaitingForReference)
-        {
-            if (fThresholds.size()==0)
-                return kStateWaitingForReference;
-
-            return kStateSettingGlobalThreshold;
-        }
-
         if (GetCurrentState()==kStateSettingGlobalThreshold)
         {
-            if (fTriggerRate>fTargetRate)
+            if (fTriggerRate<0 || fTriggerRate>fTargetRate)
                 return kStateSettingGlobalThreshold;
 
@@ -471,11 +489,12 @@
         if (GetCurrentState()==kStateGlobalThresholdSet)
         {
-            // FIXME: What if it changes?
-            return kStateGlobalThresholdSet;
+            if (!fTriggerOn)
+                return kStateGlobalThresholdSet;
+            //return kStateInProgress;
         }
 
         // At least one subsystem is not connected
         //        if (fStatusFTM.second>=FTM::kConnected)
-        return fTriggerOn ? kStateInProgress : kStateConnected;
+        return fTriggerOn && fEnabled ? kStateInProgress : kStateConnected;
     }
 
@@ -513,17 +532,20 @@
                      "All needed subsystems are connected to their hardware, no action is performed.");
 
+        AddStateName(kStateSettingGlobalThreshold, "Calibrating", "");
+        AddStateName(kStateGlobalThresholdSet, "GlobalThresholdSet", "");
+
         AddStateName(kStateInProgress, "InProgress",
                      "Rate scan in progress.");
 
-//        AddEvent("STOP", kStateInProgress)
-//            (bind(&StateMachineRateControl::StopRateControl, this))
-//            ("Stop a ratescan in progress");
-
-        AddEvent("START_DATA_TAKING")
-            (bind(&StateMachineRateControl::StartDataTaking, this))
+        AddEvent("CALIBRATE")
+            (bind(&StateMachineRateControl::Calibrate, this))
             ("");
 
-        AddEvent("ENABLE_RATE_CONTROL", "B:1")
-            (bind(&StateMachineRateControl::SetEnabled, this, placeholders::_1))
+        AddEvent("START", "")
+            (bind(&StateMachineRateControl::StartRC, this))
+            ("");
+
+        AddEvent("STOP", "")
+            (bind(&StateMachineRateControl::StopRC, this))
             ("");
 
@@ -550,4 +572,8 @@
     {
         fVerbose = !conf.Get<bool>("quiet");
+
+        fThresholdReference = 300;
+        fTargetRate         =  70;
+
         return -1;
     }
