Index: trunk/MagicSoft/Cosy/main/MCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 1760)
+++ trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 1793)
@@ -167,6 +167,6 @@
     // Get the values
     //
-    const int p1 =  fZd1->GetPos();
-    const int p2 = -fZd2->GetPos();
+    int p1 =  (fZd1->GetPos()+8192)%16384;
+    int p2 = -(fZd2->GetPos()+8192)%16384;
 
     if (fZd1->IsZombieNode())
@@ -180,7 +180,4 @@
     float p = (float)(p1+p2)/2;
 
-    //
-    // calculate 'regelabweichung'
-    //
     return ZdAz(p, pa);
 }
@@ -506,7 +503,8 @@
         lout << "SetVelocity" << endl;
         if (i)
-            SetPosVelocity(1.0, 0.1, 0.1);
-        else
-            SetPosVelocity(fabs(rd.Ratio()), 0.1, 0.3);
+            SetPosVelocity(1.0, 0.05, 0.1);
+        else                              // vel(0.6)  acc(0.5)
+            SetPosVelocity(fabs(rd.Ratio()), 0.15, 0.4);
+//            SetPosVelocity(fabs(rd.Ratio()), 0.1, 0.3);
 
         rd.Round();
@@ -859,6 +857,6 @@
         // (This is important on fast machines >500MHz)
         //
-        usleep(50000); // 0.05s
-        //usleep(500000); // 0.5s
+        usleep(50000); // 0.25s
+        //usleep(50000); // 0.05s
     }
 
@@ -907,5 +905,5 @@
 bool MCosy::CheckNetwork()
 {
-    return kTRUE;
+    //return kTRUE;
     //CheckConnections();
 
@@ -1030,4 +1028,16 @@
         cout << "WM_TestSe: done. (return 0x1e51)" << endl;
         return (void*)0x1e51;
+
+    case WM_GEAR:
+        cout << "WM_Gear: start." << endl;
+        fBackground = mp ? kBgdGear : kBgdNone;
+        cout << "WM_Gear: done. (return 0xfeaf)" << endl;
+        return (void*)0xfeaf;
+
+    case WM_DISPLAY:
+        cout << "WM_Display: start." << endl;
+        fTriggerDisplay = kTRUE;
+        cout << "WM_Disply: done. (return 0xd1e1)" << endl;
+        return (void*)0xd1e1;
 
     case WM_TRACK:
@@ -1265,5 +1275,5 @@
         {
             phca1 = fZd1->PosHasChanged();
-//            phca2 = fZd2->PosHasChanged();
+            phca2 = fZd2->PosHasChanged();
             phcaz = fAz->PosHasChanged();
             usleep(1);
@@ -1293,11 +1303,11 @@
         //
         // FIXME
-        time.Zd(fZd1->GetMjd());
-        /* OLD*
+        //time.Zd(fZd1->GetMjd());
+        /* OLD* */
         if (fZd1->GetMjd()>fZd2->GetMjd())
             time.Zd(fZd1->GetMjd());
         else
             time.Zd(fZd2->GetMjd());
-        */
+
         //time.Zd((fZd1->GetMjd()+fZd2->GetMjd())/2.0);
         time.Az(fAz->GetMjd());
@@ -1338,4 +1348,7 @@
         //---            fout << setprecision(5)  << setw(7)  << fTrackingError.Az() << endl;
     }
+
+    lout << "Tracking Thread done." << endl;
+
     //---        fout << endl << endl;
 }
@@ -1346,5 +1359,5 @@
     //        return;
 
-    if (fHistTestSe)
+    if (fHist)
     {
         lout << "You are much too fast... try again." << endl;
@@ -1352,8 +1365,8 @@
     }
 
-    fHistTestSe = new TH2F("Diff", "Difference of SE values",
-                           201, fMin.Zd(), fMax.Zd(), 101, -50, 50);
-    fHistTestSe->SetXTitle("ZA [\\circ]");
-    fHistTestSe->SetYTitle("\\Delta SE");
+    fHist = new TH2F("Diff", "Difference of SE values",
+                           201, fMin.Zd(), fMax.Zd(), 41, -10.5, 10.5);
+    fHist->SetXTitle("ZA [\\circ]");
+    fHist->SetYTitle("\\Delta SE");
 
     Double_t offset = 0;
@@ -1372,5 +1385,8 @@
             usleep(1);
 
-        const Double_t pos[3] = { fZd1->GetPos(), fZd2->GetPos(), fAz->GetPos() };
+        const Double_t pos[3] = {
+            (fZd1->GetPos()+8192)%16384,
+            (fZd2->GetPos()+8192)%16384,
+            fAz->GetPos() };
 
         //
@@ -1378,18 +1394,113 @@
         //
         if (cnt++<10)
+        {
             offset += pos[0]+pos[1];
-        if (cnt++==10)
+            continue;
+        }
+        if (cnt==11)
+        {
             offset /= 10;
-        if (cnt<11)
+            cnt++;
+        }
+
+        Double_t apos = (pos[0]-pos[1])/2 * TMath::Pi()*2 / 16384;
+
+        ZdAz bend = fBending.CorrectBack(ZdAz(apos, pos[2]))*kRad2Deg;
+        fHist->Fill(bend.Zd(), pos[0]+pos[1]-offset);
+    }
+
+    lout << "Shaftencoder Test Stopped... displaying Histogram." << endl;
+
+    fBackground=kBgdSeTestDispl;
+}
+
+void MCosy::TalkThreadGear()
+{
+//    if (fZd1->IsZombieNode() || fZd2->IsZombieNode())
+    //        return;
+
+    if (fHist)
+    {
+        lout << "You are much too fast... try again." << endl;
+        return;
+    }
+
+    //    fHist = new TH2F("Gear", "Gear Ratio Re/Se",
+    //                     201, fMin.Zd(), fMax.Zd(), 61, 349.5, 500.5);
+    fHist = new TH2F("Gear", "Gear Ratio Re/Se",
+                     201, fMin.Az(), fMax.Az(), 61, 419.5, 570.5);
+    fHist->SetXTitle("ZA [\\circ]");
+    fHist->SetYTitle("Re/Se");
+
+    lout << "Starting Gear determination..." << endl;
+
+    ZdAz se0 = GetSePos();
+    ZdAz re0 = GetRePosPdo();
+
+    while (fBackground==kBgdGear)
+    {
+        fZd1->ResetPosHasChanged();
+        fZd2->ResetPosHasChanged();
+        fAz->ResetPosHasChanged();
+
+        while (!fZd1->PosHasChanged() && !fZd2->PosHasChanged() &&
+               !fAz->PosHasChanged() && fBackground==kBgdGear)
+            usleep(1);
+
+        ZdAz se = GetSePos();
+        ZdAz re = GetRePosPdo();
+
+        ZdAz dse = se-se0;
+        ZdAz dre = re-re0;
+
+        if (fabs(dse.Zd())*144>16384) // Each 2.5deg
+        {
+            se0.Zd(se.Zd());
+            re0.Zd(re.Zd());
+
+            ZdAz bend = fBending.CorrectBack(se*2*TMath::Pi()/16384)*kRad2Deg;
+            fHist->Fill(bend.Zd(), dre.Zd()/dse.Zd());
+        }
+
+        if (fabs(dse.Az())*144>16384) // Each 2.5deg
+        {
+            se0.Az(se.Az());
+            re0.Az(re.Az());
+
+            ZdAz bend = fBending.CorrectBack(se*2*TMath::Pi()/16384)*kRad2Deg;
+            fHist->Fill(bend.Az(), dre.Az()/dse.Az());
+
+            cout << bend.Az() << ": " << dre.Az()/dse.Az() << endl;
+        }
+
+        /*
+        const Double_t pos[3] = {
+            (fZd1->GetPos()+8192)%16384,
+            (fZd2->GetPos()+8192)%16384,
+            fAz->GetPos() };
+
+        //
+        //  Estimate Offset from the first ten positions
+        //
+        if (cnt++<10)
+        {
+            offset += pos[0]+pos[1];
             continue;
+        }
+        if (cnt==11)
+        {
+            offset /= 10;
+            cnt++;
+        }
 
         Double_t apos = (pos[0]-pos[1])/2 * TMath::Pi()*2 / 16384;
 
-        ZdAz bend = fBending(ZdAz(apos, pos[2]))*kRad2Deg;
-
+        ZdAz bend = fBending.CorrectBack(ZdAz(apos, pos[2]))*kRad2Deg;
         fHistTestSe->Fill(bend.Zd(), pos[0]+pos[1]-offset);
-    }
-
-    lout << "Shaftencoder Test Stopped... displaying Histogram." << endl;
+*/
+    }
+    lout << "Gear Test Stopped... displaying Histogram." << endl;
+
+    fBackground=kBgdGearDispl;
 }
 
@@ -1436,4 +1547,11 @@
         case kBgdSeTest:
             TalkThreadSeTest();
+            continue;
+
+        case kBgdGear:
+            TalkThreadGear();
+            continue;
+
+        default:
             continue;
         }
@@ -1479,16 +1597,27 @@
      */
 
-    if (fBackground==kBgdSeTest || fHistTestSe==NULL)
-        return kTRUE;
-
-    DisplayHistTestSe();
+    const Bool_t trigger = fTriggerDisplay;
+    fTriggerDisplay = kFALSE;
+
+    if (fBackground==kBgdSeTestDispl || (trigger&&fBackground==kBgdSeTest))
+        DisplayHistTestSe(!trigger);
+
+    if (fBackground==kBgdGearDispl || (trigger&&fBackground==kBgdGear))
+        DisplayHistGear(!trigger);
 
     return kTRUE;
 }
 
-void MCosy::DisplayHistTestSe()
-{
-    TH2F &hist = *fHistTestSe;
-    fHistTestSe = NULL;
+void MCosy::DisplayHistTestSe(Bool_t del)
+{
+    lout << "Displaying histogram..." << endl;
+
+    TH2F &hist = *fHist;
+
+    if (del)
+    {
+        fHist = NULL;
+        fBackground = kBgdNone;
+    }
 
     TCanvas *c=new TCanvas("c1", "", 1000, 1000);
@@ -1514,5 +1643,44 @@
     p2.DrawCopy();
 
-    delete &hist;
+    if (del)
+        delete &hist;
+}
+
+void MCosy::DisplayHistGear(Bool_t del)
+{
+    lout << "Displaying histogram..." << endl;
+
+    TH2F &hist = *fHist;
+
+    if (del)
+    {
+        fHist = NULL;
+        fBackground = kBgdNone;
+    }
+
+    TCanvas *c=new TCanvas("c1", "", 1000, 1000);
+    c->Divide(1,2);
+
+    c->cd(1);
+    TH2 *h=(TH2*)hist.DrawCopy();
+
+    TProfile *p = h->ProfileX("_pfx", -1, 9999, "s");
+    p->SetLineColor(kBlue);
+    p->Draw("same");
+    p->SetBit(kCanDelete);
+
+    c->cd(2);
+
+    TH1F p2("spread", "Spread of the gear [16384/1500/4*U/U]", hist.GetNbinsX(), hist.GetBinLowEdge(1),
+            hist.GetBinLowEdge(hist.GetNbinsX()+1));
+    p2.SetXTitle("ZA [\\circ]");
+    for (int i=0; i<hist.GetNbinsX(); i++)
+        p2.SetBinError(i, p->GetBinError(i));
+    p2.SetLineColor(kRed);
+    p2.SetStats(0);
+    p2.DrawCopy();
+
+    if (del)
+        delete &hist;
 }
 
@@ -1549,5 +1717,4 @@
 void MCosy::Stop()
 {
-
     lout << "- Stopping GUI update." << endl;
     fUpdateGui->TurnOff();
@@ -1653,5 +1820,5 @@
 bool MCosy::HasZombie() const
 {
-    bool ses = fZd1->IsZombieNode() & fZd2->IsZombieNode();
+    bool ses = fZd1->IsZombieNode() | fZd2->IsZombieNode();
 
     return fMac1->IsZombieNode() | fMac2->IsZombieNode() | fAz->IsZombieNode() | ses;
@@ -1729,5 +1896,6 @@
 
     lout.DisableOutputDevice(MLog::eGui);
-    lout.SetOutputGui(NULL, kFALSE);
+    // FIXME: WHY DOES THIS CRASH THE APPLICATIOn WHILE TRAKING?
+    // lout.SetOutputGui(NULL, kFALSE);
 
     gApplication->Terminate(0);
Index: trunk/MagicSoft/Cosy/main/MCosy.h
===================================================================
--- trunk/MagicSoft/Cosy/main/MCosy.h	(revision 1760)
+++ trunk/MagicSoft/Cosy/main/MCosy.h	(revision 1793)
@@ -27,4 +27,6 @@
 #define WM_HOME         0x100a
 #define WM_TESTSE       0x100b
+#define WM_GEAR         0x100c
+#define WM_DISPLAY      0x100d
 
 
@@ -87,5 +89,8 @@
         kBgdNone,
         kBgdTracking,
-        kBgdSeTest
+        kBgdSeTest,
+        kBgdSeTestDispl,
+        kBgdGear,
+        kBgdGearDispl
     };
 
@@ -101,5 +106,6 @@
     ZdAz  fMax;
 
-    TH2F *fHistTestSe;
+    TH2F  *fHist;
+    Bool_t fTriggerDisplay;
 
     XY kGearRatio;        // describing the gear of the system [re/se]
@@ -138,6 +144,8 @@
     void TalkThreadTracking();
     void TalkThreadSeTest();
+    void TalkThreadGear();
 
-    void DisplayHistTestSe();
+    void DisplayHistTestSe(Bool_t del=kTRUE);
+    void DisplayHistGear(Bool_t del=kTRUE);
 
     int  SetPosition(const ZdAz &dst);
