Index: /trunk/MagicSoft/Cosy/Changelog
===================================================================
--- /trunk/MagicSoft/Cosy/Changelog	(revision 1801)
+++ /trunk/MagicSoft/Cosy/Changelog	(revision 1802)
@@ -1,3 +1,53 @@
                                                                   -*-*- END -*-*-
+
+ 2003/03/02 - Daniela Dorner, Thomas Bretz (LaPalma):
+
+  * Makefile: 
+     - removed dummy
+     - exchnged caos, candrv
+     - removed MCint.o
+     - added cosy.so
+ 
+   * starg.cc:
+     - echanged to use png reading mode
+   
+   * caos/Led.[h,cc], caos/Leds.[h,cc], caos/Ring.[h,cc], 
+     caos/Ring.[h,cc]:
+     - added Print
+
+   * caos/Led.h:
+     - added compare
+     - added issortable
+
+   * caos/Ring.cc:
+     - changed output
+
+   * caos/Rings.cc:
+     - fixed some minor bugs
+
+   * gui/GuiLinkDef.h, gui/Makefile;
+     - added MGPngReader.[h,cc]
+
+   * gui/MGPngReader.[h,cc]:
+     - added
+     
+   * gui/MGStarguider.cc:
+     - release grabbed mouse
+     - removed ExitLoop
+     
+   * gui/MGStarguider.h:
+     - changed derivement from Camera to PixClient
+
+   * videodev/Camera.[h,cc]:
+     - changed to use PixClient
+   
+   * videodev/Makefile, videodev/VideodevLinkDef.h:
+     - added PixClient
+
+   * videodev/PixClient.[h,cc]
+     - added 
+
+
+
  2003/02/27 - Thomas Bretz (LaPalma):
 
Index: /trunk/MagicSoft/Cosy/Makefile
===================================================================
--- /trunk/MagicSoft/Cosy/Makefile	(revision 1801)
+++ /trunk/MagicSoft/Cosy/Makefile	(revision 1802)
@@ -20,6 +20,6 @@
 #
 
-PROGRAMS = testse starg cosy dummy
-SOLIB    = 
+PROGRAMS = testse cosy starg
+SOLIB    = cosy.so
 CINT     = M
 INCLUDES = -I. -Imain  -Ibase -Icandrv -Iincl -Igui -Ivideodev -Icatalog -Idevdrv
@@ -40,9 +40,9 @@
         main     \
         gui      \
-        caos     \
-        candrv   \
         catalog  \
         videodev \
 	devdrv   \
+        candrv   \
+        caos     \
 	base     \
         slalib
@@ -75,5 +75,5 @@
 	$(CXX) $(CXXFLAGS) $(LIBS) $(OBJS) $@.o  $(MARS_LIB) $(ROOTGLIBS) -o $@
 
-$(SOLIB): $(LIBRARIES) $(OBJS) $(HEADERS) MCint.o
+$(SOLIB): $(LIBRARIES) $(OBJS) $(HEADERS) 
 	@echo " Linking $(SOLIB) ..."
 	$(CXX) -shared $(CXXFLAGS) $(SUBDIRS:=/*.o) $(ROOTGLIBS) -o $@
Index: /trunk/MagicSoft/Cosy/caos/Led.cc
===================================================================
--- /trunk/MagicSoft/Cosy/caos/Led.cc	(revision 1801)
+++ /trunk/MagicSoft/Cosy/caos/Led.cc	(revision 1802)
@@ -1,4 +1,5 @@
 #include "Led.h"
 
+#include <iostream.h>
 #include <TMath.h>
 
@@ -11,2 +12,11 @@
     fPhi = TMath::ATan2(fY-ring.GetY(), fX-ring.GetX())*180/TMath::Pi();
 }
+
+void Led::Print(Option_t *o=NULL) const
+{
+    cout << "Led: ";
+    cout << "x="   << fX   << "+-" << fDx   << ", ";
+    cout << "y="   << fY   << "+-" << fDy   << ", ";
+    cout << "phi=" << fPhi << "+-" << fDphi << ", ";
+    cout << "mag=" << fMag << endl;
+}
Index: /trunk/MagicSoft/Cosy/caos/Led.h
===================================================================
--- /trunk/MagicSoft/Cosy/caos/Led.h	(revision 1801)
+++ /trunk/MagicSoft/Cosy/caos/Led.h	(revision 1802)
@@ -27,11 +27,30 @@
     }
 
-    Double_t GetX() const   { return fX; }
-    Double_t GetY() const   { return fY; }
-    Double_t GetDx() const  { return fDx; }
-    Double_t GetDy() const  { return fDy; }
-    Double_t GetMag() const { return fMag; }
+    Int_t Compare(const TObject *obj) const
+    {
+        const Led *const l = (Led*)obj;
+
+        if (fPhi<l->fPhi)
+            return -1;
+
+        if (fPhi>l->fPhi)
+            return 1;
+
+        return 0;
+    }
+
+    Double_t GetX() const    { return fX; }
+    Double_t GetY() const    { return fY; }
+    Double_t GetDx() const   { return fDx; }
+    Double_t GetDy() const   { return fDy; }
+    Double_t GetPhi() const  { return fPhi; }
+    Double_t GetDphi() const { return fDphi; }
+    Double_t GetMag() const  { return fMag; }
+
+        Bool_t IsSortable() const { return kTRUE; }
 
     void CalcPhi(const Ring &ring);
+
+    void Print(Option_t *o=NULL) const;
 
     ClassDef(Led, 1)
Index: /trunk/MagicSoft/Cosy/caos/Leds.cc
===================================================================
--- /trunk/MagicSoft/Cosy/caos/Leds.cc	(revision 1801)
+++ /trunk/MagicSoft/Cosy/caos/Leds.cc	(revision 1802)
@@ -1,3 +1,5 @@
 #include "Leds.h"
+
+#include <iostream.h>
 
 #include "Led.h"
@@ -9,2 +11,8 @@
     new ((*this)[i]) Led(x, y, dx, dy, mag);
 }
+
+void Leds::Print(Option_t *o=NULL) const
+{
+    cout << "Number of Leds: " << GetEntries() << endl;
+    TClonesArray::Print();
+}
Index: /trunk/MagicSoft/Cosy/caos/Leds.h
===================================================================
--- /trunk/MagicSoft/Cosy/caos/Leds.h	(revision 1801)
+++ /trunk/MagicSoft/Cosy/caos/Leds.h	(revision 1802)
@@ -10,5 +10,4 @@
 class Leds : public TClonesArray
 {
-private:
 public:
     Leds() : TClonesArray("Led", 1) {}
@@ -27,4 +26,6 @@
     Led &operator()(int i) { return *(Led*)((*(Leds*)this)[i]); }
 
+    void Print(Option_t *o=NULL) const;
+
     ClassDef(Leds, 1)
 };
Index: /trunk/MagicSoft/Cosy/caos/Ring.cc
===================================================================
--- /trunk/MagicSoft/Cosy/caos/Ring.cc	(revision 1801)
+++ /trunk/MagicSoft/Cosy/caos/Ring.cc	(revision 1802)
@@ -20,6 +20,6 @@
         if (h1==0)
         {
-                cout << "h1==0" <<endl;
-                return kFALSE;
+            cout << "h1==0" <<endl;
+            return kFALSE;
         }
     }
@@ -38,13 +38,13 @@
     }
 
-    Float_t w1 = leds(i).GetX() - leds(j).GetX();
-    Float_t w2 = leds(j).GetX() - leds(k).GetX();
+    const Float_t w1 = leds(i).GetX() - leds(j).GetX();
+    const Float_t w2 = leds(j).GetX() - leds(k).GetX();
 
-    Float_t m1 = -w1/h1;
-    Float_t m2 = -w2/h2;
+    const Float_t m1 = -w1/h1;
+    const Float_t m2 = -w2/h2;
 
     if (m2-m1==0)
     {
-        cout << "m2-m1==0" << endl;
+        cout << "All three points in a row! (m2-m1==0)" << endl;
         return kFALSE;
     }
@@ -66,7 +66,14 @@
     fR = 0;
 
+    fDx=0;
+    fDy=0;
+    fDr=0;
+
+    if (n<1)
+        return;
+
     for (int i=0; i<n; i++)
     {
-        const Ring &ring = *(Ring*)((Rings&)rings)[i];
+        const Ring &ring = rings(i);
 
         fX += ring.GetX();
@@ -79,24 +86,31 @@
     fR /= n;
 
+    if (n<2)
+        return;
+
     //
     // deviation of x- and y coordinate and radius
     //
-    Float_t sumx=0;
-    Float_t sumy=0;
-    Float_t sumr=0;
-
     for (int i=0; i<n; i++)
     {
-        const Ring &ring = *(Ring*)((Rings&)rings)[i];
+        const Ring &ring = rings(i);
 
-        sumx += sqr(ring.GetX()-fX);
-        sumy += sqr(ring.GetY()-fY);
-        sumr += sqr(ring.GetR()-fR);
+        fDx += sqr(ring.GetX()-fX);
+        fDy += sqr(ring.GetY()-fY);
+        fDr += sqr(ring.GetR()-fR);
     }
 
-        fDx=sqrt(sumx)/(n-1);
-        fDy=sqrt(sumy)/(n-1);
-        fDr=sqrt(sumr)/(n-1);
-
+    fDx=sqrt(fDx)/(n-1);
+    fDy=sqrt(fDy)/(n-1);
+    fDr=sqrt(fDr)/(n-1);
 }
 
+void Ring::Print(Option_t *o=NULL) const
+{
+    cout << "Ring: ";
+    cout << "x="   << fX   << "+-" << fDx   << ", ";
+    cout << "y="   << fY   << "+-" << fDy   << ", ";
+    cout << "r="   << fR   << "+-" << fDr   << ", ";
+    cout << "phi=" << fPhi << "+-" << fDphi << endl;
+}
+
Index: /trunk/MagicSoft/Cosy/caos/Ring.h
===================================================================
--- /trunk/MagicSoft/Cosy/caos/Ring.h	(revision 1801)
+++ /trunk/MagicSoft/Cosy/caos/Ring.h	(revision 1802)
@@ -41,4 +41,6 @@
     void InterpolCenters(const Rings &rings);
 
+    void Print(Option_t *o=NULL) const;
+
     ClassDef(Ring, 1)
 };
Index: /trunk/MagicSoft/Cosy/caos/Rings.cc
===================================================================
--- /trunk/MagicSoft/Cosy/caos/Rings.cc	(revision 1801)
+++ /trunk/MagicSoft/Cosy/caos/Rings.cc	(revision 1802)
@@ -1,3 +1,5 @@
 #include "Rings.h"
+
+#include <iostream.h>
 
 #include "Led.h"
@@ -6,5 +8,5 @@
 ClassImp(Rings);
 
-Int_t Rings::CalcCenters(const Leds &leds)
+void Rings::CalcCenters(const Leds &leds)
 {
     int nPoints = leds.GetEntries();
@@ -15,11 +17,16 @@
             for (int k=j+1; k<nPoints; k++)
             {
-                Ring &ring = *(Ring*)(*this)[n];
+                Ring &ring = *new ((*this)[n]) Ring;
 
-                ring.CalcCenter(leds, i, j, k);
+                if (!ring.CalcCenter(leds, i, j, k))
+                {
+                    RemoveAt(n);
+                    continue;
+                }
 
                 n++;
             }
-    return n;
+
+    Expand(n);
 }
 
@@ -31,7 +38,17 @@
 
     //
-    // angles v and relative angle w
+    // angles v
     //
-    for (int j=0; j<leds.GetEntries(); j++)
+    const int n=leds.GetEntries();
+
+    for (int j=0; j<n; j++)
         leds(j).CalcPhi(fCenter);
 }
+
+void Rings::Print(Option_t *o=NULL) const
+{
+    cout << "Number of Rings: " << GetEntries() << endl;
+    TClonesArray::Print();
+    cout << "Center: " << endl;
+    fCenter.Print();
+}
Index: /trunk/MagicSoft/Cosy/caos/Rings.h
===================================================================
--- /trunk/MagicSoft/Cosy/caos/Rings.h	(revision 1801)
+++ /trunk/MagicSoft/Cosy/caos/Rings.h	(revision 1802)
@@ -17,13 +17,17 @@
     Ring fCenter;
 
-    Int_t CalcCenters(const Leds &leds);
+    void CalcCenters(const Leds &leds);
 
 public:
     Rings() : TClonesArray("Ring", 1) {}
 
-    //
-    //  rings.CalcRings(leds);
-    //
     void CalcRings(Leds &leds);
+
+    void Print(Option_t *o=NULL) const;
+
+    const Ring &operator()(int i) const { return *(Ring*)((*(Rings*)this)[i]); }
+    Ring &operator()(int i) { return *(Ring*)((*(Rings*)this)[i]); }
+
+    const Ring &GetCenter() const { return fCenter; }
 
     ClassDef(Rings, 1)
Index: /trunk/MagicSoft/Cosy/gui/GuiLinkDef.h
===================================================================
--- /trunk/MagicSoft/Cosy/gui/GuiLinkDef.h	(revision 1801)
+++ /trunk/MagicSoft/Cosy/gui/GuiLinkDef.h	(revision 1802)
@@ -19,4 +19,5 @@
 #pragma link C++ class MGCosy+;
 #pragma link C++ class MGStarguider+;
+#pragma link C++ class MGPngReader+;
 
 #endif
Index: /trunk/MagicSoft/Cosy/gui/MGPngReader.cc
===================================================================
--- /trunk/MagicSoft/Cosy/gui/MGPngReader.cc	(revision 1802)
+++ /trunk/MagicSoft/Cosy/gui/MGPngReader.cc	(revision 1802)
@@ -0,0 +1,1100 @@
+#include "MGPngReader.h"
+
+#include <fstream.h>    // ifstream
+#include <iostream.h>   // cout
+
+#include <TTimer.h>
+
+#include <TGMenu.h>
+#include <TSystem.h>
+#include <TGSplitter.h>    // TGHorizontal3DLine
+#include <TGTextEntry.h>
+
+#include "MGImage.h"
+#include "MGCoordinates.h"
+
+#include "coord.h"
+
+#include "StarCatalog.h"
+
+#include "Filter.h"
+#include "Filter2.h"
+#include "CaosFilter.h"
+#include "Writer.h"
+#include "base/timer.h"
+
+#include "MStarList.h"
+
+#include <TH1.h>
+#include <TH2.h>
+#include <TGraph.h>
+#include <TCanvas.h>
+
+#include <TFile.h>
+#include <TTree.h>
+#include <TBranch.h>
+
+#include "Led.h"
+#include "Leds.h"
+#include "Rings.h"
+
+#include "MGMenu.h"
+
+ClassImp(MGPngReader);
+
+enum {
+    IDM_kFilter,
+    IDM_kCaosFilter,
+    IDM_kCatalog,
+    IDM_kStarguider,
+    IDM_kStart,
+    IDM_kStop,
+    IDM_kFileType,
+    IDM_kPPM,
+    IDM_kPNG,
+    IDM_kOnce,
+    IDM_kUseFileRaDec,
+    IDM_kContinous,
+    IDM_kRate25ps,
+    IDM_kRate5ps,
+    IDM_kRate1s,
+    IDM_kRate5s,
+    IDM_kRate30s,
+    IDM_kRate1m,
+    IDM_kRate5m,
+    IDM_kSetup,
+    IDM_kLimMag3,
+    IDM_kLimMag4,
+    IDM_kLimMag5,
+    IDM_kLimMag6,
+    IDM_kLimMag7,
+    IDM_kLimMag8,
+    IDM_kLimMag9,
+    IDM_kPixSize,
+    IDM_kInterpol125,
+    IDM_kInterpol25,
+    IDM_kInterpol10,
+    IDM_kInterpol5,
+    IDM_kInterpol2,
+    IDM_kInterpol1,
+    IDM_kPositions,
+    IDM_kRings,
+    IDM_kLeds,
+    IDM_kStartAnalyse,
+    IDM_kStopAnalyse,
+    IDM_kResetHistograms
+};
+
+Bool_t MGPngReader::HandleTimer(TTimer *t)
+{
+    fImage->DoRedraw();
+    fZoomImage->DoRedraw();
+    return kTRUE;
+}
+
+#define kZOOM 96
+
+void MGPngReader::InitHists()
+{
+    Double_t xmin = 480.1-1.0;
+    Double_t xmax = 480.1+1.0;
+
+    Double_t ymin = 217.5-1.0;
+    Double_t ymax = 217.5+1.0;
+
+    Double_t rmin = 117.4-1.0;
+    Double_t rmax = 117.4+1.0;
+
+    Int_t xbin = 60;
+    Int_t ybin = 60;
+    Int_t rbin = 60;
+
+    fHistpr = new TH1F;
+    fHistpr->SetNameTitle("pr","Radius of the ring");
+    fHistpr->SetBins(rbin, rmin, rmax);
+    fHistpr->SetXTitle("r [mm]");
+    fHistpr->SetYTitle("counts");
+
+    fHistprx = new TH1F;
+    fHistprx->SetNameTitle("prx","x-coordinate of the ring-center");
+    fHistprx->SetBins(xbin, xmin, xmax);
+    fHistprx->SetXTitle("x [mm]");
+    fHistprx->SetYTitle("counts");
+
+    fHistpry = new TH1F;
+    fHistpry->SetNameTitle("pry","y-coordniate of the ring-center");
+    fHistpry->SetBins(ybin, ymin, ymax);
+    fHistpry->SetXTitle("y [mm]");
+    fHistpry->SetYTitle("counts");
+
+    for (int i=0; i<6; i++)
+    {
+        TString name  = "Angle";
+        TString title = "Angle of Led ";
+
+        name += i;
+        title += i;
+
+        fHistw[i] = new TH1F;
+        fHistw[i]->SetNameTitle(name, title);
+        fHistw[i]->SetBins(26, -25, 25);
+        fHistw[i]->SetXTitle("\\Phi [arcmin]");
+        fHistw[i]->SetYTitle("counts");
+
+        name = "Angles";
+        title = "Angles of the Leds ";
+
+        name += i;
+        title += i;
+
+        fHistv[i] = new TH1F;
+        fHistv[i]->SetNameTitle(name, title);
+        fHistv[i]->SetBins(721, -180.5, 180.5);
+        fHistv[i]->SetXTitle("\\Phi [deg]");
+        fHistv[i]->SetYTitle("counts");
+    }
+
+    fHistallw = new TH1F;
+    fHistallw->SetNameTitle("allw","Rotation angel");
+    fHistallw->SetBins(26, -25, 25);
+    fHistallw->SetXTitle("\\Phi [arcmin]");
+    fHistallw->SetYTitle("counts");
+
+    fHistprxpry = new TH2F;
+    fHistprxpry->SetNameTitle("prx und pry","x- and y-coordniate of the ring-center");
+    fHistprxpry->SetBins(xbin, xmin, xmax, ybin, ymin, ymax);
+    fHistprxpry->SetXTitle("x [mm]");
+    fHistprxpry->SetYTitle("y [mm]");
+    fHistprxpry->SetZTitle("counts");
+}
+
+void MGPngReader::InitGraphs()
+{
+    fGraphprx = new TGraph;
+    fGraphprx->SetTitle("time-developement of the x-coordinate of the ring-center");
+
+    fGraphpry = new TGraph;
+    fGraphpry->SetTitle("time-developement of the y-coordinate of the ring-center");
+
+    for (int i=0; i<6; i++)
+    {
+        TString title = "Time-developement of the angle ";
+        title += i;
+
+        fGraphw[i] = new TGraph;
+        fGraphw[i]->SetTitle(title);
+    }
+}
+
+void MGPngReader::InitGui()
+{
+    fList = new MGList;
+
+    const TGWindow *p=gClient->GetRoot();
+
+    //
+    // Create Menu for MGPngReader Display
+    //
+    fDisplay = new MGPopupMenu(p);
+    fDisplay->AddEntry("&Filter",      IDM_kFilter);
+    fDisplay->AddEntry("C&aosFilter",  IDM_kCaosFilter);
+    fDisplay->AddEntry("Sao &Catalog", IDM_kCatalog);
+    fDisplay->AddEntry("Starguider",   IDM_kStarguider);
+    fDisplay->DisableEntry(IDM_kStarguider);
+    fDisplay->Associate(this);
+    fList->Add(fDisplay);
+
+    fFileType = new MGPopupMenu(p);
+    fFileType->AddEntry("PP&M", IDM_kPPM);
+    fFileType->AddEntry("&PNG", IDM_kPNG);
+    fFileType->CheckEntry(IDM_kPNG);
+    fFileType->Associate(this);
+    fList->Add(fFileType);
+
+    fWriteType = new MGPopupMenu(p);
+    fWriteType->AddEntry("&Once",      IDM_kOnce);
+    fWriteType->AddEntry("&Continous", IDM_kContinous);
+    fWriteType->Associate(this);
+    fList->Add(fWriteType);
+
+    fWriteRate = new MGPopupMenu(p);
+    fWriteRate->AddEntry("25/s", IDM_kRate25ps);
+    fWriteRate->AddEntry("5/s",  IDM_kRate5ps);
+    fWriteRate->AddEntry("1s",   IDM_kRate1s);
+    fWriteRate->AddEntry("5s",   IDM_kRate5s);
+    fWriteRate->AddEntry("30s",  IDM_kRate30s);
+    fWriteRate->AddEntry("1min", IDM_kRate1m);
+    fWriteRate->AddEntry("5min", IDM_kRate5m);
+    fWriteRate->CheckEntry(IDM_kRate1m);
+    fWriteRate->Associate(this);
+    fList->Add(fWriteRate);
+
+    fWrtRate = 25*60;
+
+    fWritePictures = new MGPopupMenu(p);
+    fWritePictures->AddEntry("&Start",      IDM_kStart);
+    fWritePictures->AddEntry("Sto&p",       IDM_kStop);
+    fWritePictures->AddSeparator();
+    fWritePictures->AddPopup("File &Type",  fFileType);
+    fWritePictures->AddPopup("&Write Type", fWriteType);
+    fWritePictures->AddPopup("Write &Rate", fWriteRate);
+    fWritePictures->DisableEntry(IDM_kStop);
+    fWritePictures->Associate(this);
+    fList->Add(fWritePictures);
+
+    fLimMag = new MGPopupMenu(p);
+    fLimMag->AddEntry("3", IDM_kLimMag3);
+    fLimMag->AddEntry("4", IDM_kLimMag4);
+    fLimMag->AddEntry("5", IDM_kLimMag5);
+    fLimMag->AddEntry("6", IDM_kLimMag6);
+    fLimMag->AddEntry("7", IDM_kLimMag7);
+    fLimMag->AddEntry("8", IDM_kLimMag8);
+    fLimMag->AddEntry("9", IDM_kLimMag9);
+    fLimMag->CheckEntry(IDM_kLimMag8);
+    fLimMag->Associate(this);
+    fList->Add(fLimMag);
+
+    fSao->SetLimitMag(8.0);
+
+    fInterpol = new MGPopupMenu(p);
+    fInterpol->AddEntry("125", IDM_kInterpol125);
+    fInterpol->AddEntry("25",  IDM_kInterpol25);
+    fInterpol->AddEntry("10",  IDM_kInterpol10);
+    fInterpol->AddEntry("5",   IDM_kInterpol5);
+    fInterpol->AddEntry("2",   IDM_kInterpol2);
+    fInterpol->AddEntry("Off", IDM_kInterpol1);
+    fInterpol->CheckEntry(IDM_kInterpol1);
+    fInterpol->Associate(this);
+    fList->Add(fInterpol);
+
+    fIntRate = 1;
+
+    fSetup = new MGPopupMenu(p);
+    fSetup->AddPopup("Lim. &Magnitude",      fLimMag);
+    fSetup->AddPopup("Disp. &Interpolation", fInterpol);
+    fSetup->AddEntry("Use Ra/Dec from file", IDM_kUseFileRaDec);
+    fSetup->Associate(this);
+    fList->Add(fSetup);
+
+    fWrite = new MGPopupMenu(p);
+    fWrite->AddEntry("&Positions",  IDM_kPositions);
+    fWrite->AddEntry("&Leds", IDM_kLeds);
+    fWrite->AddEntry("&Rings", IDM_kRings);
+    fWrite->Associate(this);
+    fList->Add(fWrite);
+
+    fAnalyse = new MGPopupMenu(p);
+    fAnalyse->AddEntry("S&tart Analyse", IDM_kStartAnalyse);
+    fAnalyse->AddEntry("St&opp Analyse", IDM_kStopAnalyse);
+    fAnalyse->DisableEntry(IDM_kStopAnalyse);
+    fAnalyse->AddEntry("&Reset Histograms", IDM_kResetHistograms);
+//    fAnalyse->AddEntry("Reset &Graph", IDM_kResetGraph);
+    fAnalyse->Associate(this);
+    fList->Add(fAnalyse);
+
+    fMenu = new MGMenuBar(this, 0, 0, kHorizontalFrame);
+    fMenu->AddPopup("&Display", fDisplay, NULL);
+    fMenu->AddPopup("&WritePics",   fWritePictures,   NULL);
+    fMenu->AddPopup("&Setup",   fSetup,   NULL);
+    fMenu->Resize(fMenu->GetDefaultSize());
+    fMenu->BindKeys(this);
+    AddFrame(fMenu); //, new TGLayoutHints (kLHintsNormal, 0, 4, 0, 0));
+    fList->Add(fMenu);
+
+    fCaOs = new MGPopupMenu(p);
+    fCaOs->AddPopup("&Write", fWrite);
+    fCaOs->AddPopup("&Analyse", fAnalyse);
+    fCaOs->Associate(this);
+    fCaOs->BindKeys(fMenu, this);
+    fList->Add(fCaOs);
+
+    fCRaDec = new MGCoordinates(this, kETypeRaDec);
+    fCRaDec->Move(1, fMenu->GetDefaultHeight()+584);
+    AddFrame(fCRaDec);
+    fList->Add(fCRaDec);
+
+    fCZdAz = new MGCoordinates(this, kETypeZdAz);
+    fCZdAz->Move(240+12+10, fMenu->GetDefaultHeight()+584);
+    AddFrame(fCZdAz);
+    fList->Add(fCZdAz);
+
+    const Double_t pixsize = 23.4;
+
+    fSao->SetPixSize(pixsize/3600);
+
+    TString txt;
+    txt += pixsize;
+
+    fPixSize = new TGTextEntry(this, txt, IDM_kPixSize);
+    fPixSize->SetAlignment(kTextCenterX);
+    fPixSize->Move(600, fMenu->GetDefaultHeight()+584);
+    AddFrame(fPixSize);
+    fList->Add(fPixSize);
+
+    // TGHorizontal3DLine *fLineSep = new TGHorizontal3DLine(this);
+    // AddFrame(fLineSep, new TGLayoutHints (kLHintsNormal | kLHintsExpandX));
+    // fList->Add(fLineSep);
+
+    //
+    // Create Image Display
+    //
+    fZoomImage = new MGImage(this, kZOOM, kZOOM);
+    fZoomImage->Move(768-kZOOM-2, 700-kZOOM-2);
+    AddFrame(fZoomImage);
+    fList->Add(fZoomImage);
+
+    fImage = new MGImage(this, 768, 576);
+    fImage->Move(0, fMenu->GetDefaultHeight());
+    AddFrame(fImage);
+    fList->Add(fImage);
+
+    //
+    // Make everything visible
+    //
+    SetWindowName("MGPngReader Main Window");
+    SetIconName("MGPngReader");
+
+    MapSubwindows();
+    MapWindow();
+}
+
+MGPngReader::MGPngReader(MObservatory::LocationName_t obs)
+: TGMainFrame(gClient->GetRoot(), 768, 700), fFile(NULL), fDx((768-kZOOM)/2), fDy((512-kZOOM)/2)
+{
+    fSao = new StarCatalog(obs);
+    fRaDec = new RaDec(180, 40);
+
+    InitHists();
+    InitGraphs();
+
+    InitGui();
+
+    gVirtualX->GrabButton(fId, kButton2, 0, 0, 0, 0, kTRUE);
+
+    fTimer=new TTimer(this, 100); // 100ms
+    fTimer->TurnOn();
+}
+
+MGPngReader::~MGPngReader()
+{
+    gVirtualX->GrabButton(fId, kButton2, 0, 0, 0, 0, kFALSE);
+
+    fTimer->TurnOff();
+    delete fTimer;
+
+    delete fList;
+
+    delete fSao;
+    delete fRaDec;
+
+    delete fHistpr;
+    delete fHistprx;
+    delete fHistpry;
+    delete fHistprxpry;
+    delete fHistallw;
+    delete fGraphprx;
+    delete fGraphpry;
+
+    for (int i=0; i<6; i++)
+    {
+        delete fHistw[i];
+        delete fHistv[i];
+        delete fGraphw[i];
+    }
+
+    cout << "Camera Display destroyed." << endl;
+}
+
+void MGPngReader::Layout()
+{
+    // Resize(GetDefaultSize());
+}
+
+void MGPngReader::CloseWindow()
+{
+    cout << "EventDisplay::CloseWindow: Exit Application Loop." << endl;
+
+    //fClient.ExitLoop();
+    //    cout << "FIXME: ExitLoop not called!!!!!!" << endl;
+    gSystem->ExitLoop();
+}
+
+void MGPngReader::Toggle(MGPopupMenu *p, UInt_t id)
+{
+    if (p->IsEntryChecked(id))
+        p->UnCheckEntry(id);
+    else
+        p->CheckEntry(id);
+}
+
+void MGPngReader::ResetHists()
+{
+    fHistprx->Reset();
+    fHistpry->Reset();
+    fHistpr->Reset();
+    fHistprxpry->Reset();
+    fHistallw->Reset();
+    for (int i=0; i<6; i++)
+    {
+        fHistw[i]->Reset();
+        fHistv[i]->Reset();
+    }
+}
+
+void MGPngReader::DisplayAnalysis()
+{
+    TCanvas *c = new TCanvas("cring", "Center of the ring", 800, 800);
+    c->Divide(2,2);
+    c->cd(1);
+    fHistprx->Fit("gaus");
+    fHistprx->DrawCopy();
+    c->cd(2);
+    fHistpry->Fit("gaus");
+    fHistpry->DrawCopy();
+    c->cd(3);
+    fHistpr->Fit("gaus");
+    fHistpr->DrawCopy();
+    c->cd(4);
+    fHistprxpry->DrawCopy(/*"surf2"*/);
+    c->Update();
+
+    c = new TCanvas("c3", "Absolute angles of the leds", 800, 800);
+    c->Divide(2,3);
+    for (int i=0; i<6; i++)
+    {
+        c->cd(i+1);
+        TH1 *h = fHistv[i]->DrawCopy();
+        h->SetLineColor(i+1);
+        cout << "Led #" << i << ": MeanPhi=" << h->GetMean() << endl;
+    }
+    c->Update();
+
+    c = new TCanvas("c5", "timedevelopement of prx", 800, 800);
+    fGraphprx->Draw("ALP*");
+    fGraphprx->GetHistogram()->SetXTitle("time [1/25 s]");
+    fGraphprx->GetHistogram()->SetYTitle("x-coordinate");
+    c->Modified();
+    c->Update();
+
+    c = new TCanvas("c6", "timedevelopement of pry", 800, 800);
+    fGraphpry->Draw("ALP*");
+    fGraphpry->GetHistogram()->SetXTitle("time [1/25 s]");
+    fGraphpry->GetHistogram()->SetYTitle("y-coordinate");
+    c->Modified();
+    c->Update();
+
+    c = new TCanvas("c2", "Relative angles of the Leds", 800, 800);
+    c->Divide(2,3);
+    for (int i=0; i<6; i++)
+    {
+        c->cd(i+1);
+        fHistw[i]->DrawCopy();
+    }
+    c->Update();
+
+    c = new TCanvas("c7", "timedevelopement of the relative angles of the Leds", 800, 800);
+    c->Divide(2,3);
+    for (int i=0; i<6; i++)
+    {
+        c->cd(i+1);
+        fGraphw[i]->Draw("ALP*");
+        fGraphw[i]->GetHistogram()->SetXTitle("t [1/25s]");
+        fGraphw[i]->GetHistogram()->SetYTitle("[deg]");
+    }
+    c->Modified();
+    c->Update();
+
+    c = new TCanvas("c4", "rotation angle ", 800, 800);
+    fHistallw->Fit("gaus");
+    fHistallw->DrawCopy();
+}
+
+void MGPngReader::OpenFile()
+{
+    int i=0;
+    char name[100];
+    while (1)
+    {
+        sprintf(name, "data/data%03d.root", i++);
+        if (gSystem->AccessPathName(name, kFileExists))
+            break;
+    }
+
+    fFile = new TFile("leds.root", "RECREATE");
+
+    if (!fFile->IsOpen())
+    {
+        delete fFile;
+        fFile = NULL;
+
+        cout << "Error: Cannot open file '" << name << "'" << endl;
+
+    }
+
+    fTree = new TTree("Data", "Real CaOs Data");
+
+    fLeds = NULL;
+    fRings = NULL;
+    fTime = 0;
+
+    fBranchL = fTree->Branch("Leds.",  "Leds",  &fLeds);
+    fBranchR = fTree->Branch("Rings.", "Rings", &fRings);
+    fBranchT = fTree->Branch("Time.", &fTime, "fTime/D");//, &fTime);
+
+    cout << "Root file '" << name << "' open." << endl;
+}
+
+Bool_t MGPngReader::ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2)
+{
+    switch (GET_MSG(msg))
+    {
+    case kC_TEXTENTRY:
+        if (GET_SUBMSG(msg)==kTE_ENTER)
+        {
+            const Float_t pixsize = atof(fPixSize->GetText());
+            cout << "Pixel Size changed to " << pixsize << "\"/pix" << endl;
+            fSao->SetPixSize(pixsize/3600);
+        }
+        return kTRUE;
+
+    case kC_COMMAND:
+        //cout << "kC_COMMAND" << endl;
+        switch (GET_SUBMSG(msg))
+        {
+        case kCM_MENU:
+            //cout << "kCM_MENU #" << mp1 << endl;
+            switch (mp1)
+            {
+            case IDM_kCatalog:
+                Toggle(fDisplay, IDM_kCatalog);
+                if (fDisplay->IsEntryChecked(IDM_kCatalog))
+                    fDisplay->EnableEntry(IDM_kStarguider);
+                else
+                {
+                    fDisplay->UnCheckEntry(IDM_kStarguider);
+                    fDisplay->DisableEntry(IDM_kStarguider);
+                }
+                return kTRUE;
+
+            case IDM_kStarguider:
+                Toggle(fDisplay, IDM_kStarguider);
+                return kTRUE;
+
+            case IDM_kFilter:
+                Toggle(fDisplay, IDM_kFilter);
+                if (fDisplay->IsEntryChecked(IDM_kFilter))
+                    fDisplay->EnableEntry(IDM_kStarguider);
+                else
+                {
+                    fDisplay->UnCheckEntry(IDM_kStarguider);
+                    fDisplay->DisableEntry(IDM_kStarguider);
+                }
+                return kTRUE;
+
+            case IDM_kCaosFilter:
+                if (!fDisplay->IsEntryChecked(IDM_kCaosFilter))
+                    OpenFile();
+                Toggle(fDisplay, IDM_kCaosFilter);
+                if (fDisplay->IsEntryChecked(IDM_kCaosFilter))
+                    fMenu->AddPopup("&CaOs", fCaOs, NULL);
+                else
+                {
+                    fFile->Write();
+                    delete fFile;
+                    fFile = NULL;
+
+                    cout << "Root file closed." << endl;
+
+                    if(fWrite->IsEntryChecked(IDM_kPositions))
+                       fWrite->UnCheckEntry(IDM_kPositions);
+                    if(fWrite->IsEntryChecked(IDM_kLeds))
+                       fWrite->UnCheckEntry(IDM_kLeds);
+                    if(fWrite->IsEntryChecked(IDM_kRings))
+                        fWrite->UnCheckEntry(IDM_kRings);
+                    if(fAnalyse->IsEntryEnabled(IDM_kStopAnalyse))
+                    {
+                        fAnalyse->DisableEntry(IDM_kStopAnalyse);
+                        fAnalyse->EnableEntry(IDM_kStartAnalyse);
+                        ResetHists();
+                        // Graphs are not reset !!!
+                    }
+                    fMenu->RemovePopup("CaOs");
+                }
+                fMenu->Resize(fMenu->GetDefaultSize());
+                MapSubwindows();
+                MapWindow();
+                return kTRUE;
+
+            case IDM_kPositions:
+                Toggle(fWrite, IDM_kPositions);
+                return kTRUE;
+
+            case IDM_kLeds:
+                Toggle(fWrite, IDM_kLeds);
+                return kTRUE;
+
+            case IDM_kRings:
+                Toggle(fWrite, IDM_kRings);
+                return kTRUE;
+
+            case IDM_kStartAnalyse:
+                fAnalyse->DisableEntry(IDM_kStartAnalyse);
+                fAnalyse->EnableEntry(IDM_kStopAnalyse);
+                return kTRUE;
+
+            case IDM_kStopAnalyse:
+                {
+                    fAnalyse->DisableEntry(IDM_kStopAnalyse);
+                    fAnalyse->EnableEntry(IDM_kStartAnalyse);
+
+                    DisplayAnalysis();
+
+                    return kTRUE;
+                }
+
+            case IDM_kResetHistograms:
+                ResetHists();
+                return kTRUE;
+
+/*            case IDM_kResetGraph:
+                {
+                    fGraphx->GetHistogram()->Reset();
+
+                }
+*/
+
+            case IDM_kUseFileRaDec:
+                Toggle(fSetup, IDM_kUseFileRaDec);
+                return kTRUE;
+
+            case IDM_kStart:
+                fWritePictures->DisableEntry(IDM_kStart);
+                fWritePictures->EnableEntry(IDM_kStop);
+                return kTRUE;
+
+            case IDM_kStop:
+                fWritePictures->DisableEntry(IDM_kStop);
+                fWritePictures->EnableEntry(IDM_kStart);
+                return kTRUE;
+
+            case IDM_kPNG:
+                fFileType->CheckEntry(IDM_kPNG);
+                fFileType->UnCheckEntry(IDM_kPPM);
+                return kTRUE;
+
+            case IDM_kPPM:
+                fFileType->CheckEntry(IDM_kPPM);
+                fFileType->UnCheckEntry(IDM_kPNG);
+                return kTRUE;
+
+            case IDM_kOnce:
+                fWriteType->CheckEntry(IDM_kOnce);
+                fWriteType->UnCheckEntry(IDM_kContinous);
+                return kTRUE;
+
+            case IDM_kContinous:
+                fWriteType->CheckEntry(IDM_kContinous);
+                fWriteType->UnCheckEntry(IDM_kOnce);
+                return kTRUE;
+
+            case IDM_kRate25ps:
+            case IDM_kRate5ps:
+            case IDM_kRate1s:
+            case IDM_kRate5s:
+            case IDM_kRate30s:
+            case IDM_kRate1m:
+            case IDM_kRate5m:
+                for (int i=IDM_kRate25ps; i<=IDM_kRate5m; i++)
+                    if (mp1==i)
+                        fWriteRate->CheckEntry(i);
+                    else
+                        fWriteRate->UnCheckEntry(i);
+                switch (mp1)
+                {
+                case IDM_kRate25ps:
+                    fWrtRate = 1;
+                    return kTRUE;
+                case IDM_kRate5ps:
+                    fWrtRate = 5;
+                    return kTRUE;
+                case IDM_kRate1s:
+                    fWrtRate = 25;
+                    return kTRUE;
+                case IDM_kRate5s:
+                    fWrtRate = 5*25;
+                    return kTRUE;
+                case IDM_kRate30s:
+                    fWrtRate = 30*25;
+                    return kTRUE;
+                case IDM_kRate1m:
+                    fWrtRate = 60*25;
+                    return kTRUE;
+                case IDM_kRate5m:
+                    fWrtRate = 5*60*25;
+                    return kTRUE;
+                }
+                return kTRUE;
+
+            case IDM_kInterpol125:
+            case IDM_kInterpol25:
+            case IDM_kInterpol10:
+            case IDM_kInterpol5:
+            case IDM_kInterpol2:
+            case IDM_kInterpol1:
+                for (int i=IDM_kInterpol125; i<=IDM_kInterpol1; i++)
+                    if (mp1==i)
+                        fInterpol->CheckEntry(i);
+                    else
+                        fInterpol->UnCheckEntry(i);
+                switch (mp1)
+                {
+                case IDM_kInterpol1:
+                    fIntRate = 1;
+                    return kTRUE;
+                case IDM_kInterpol2:
+                    fIntRate = 2;
+                    return kTRUE;
+                case IDM_kInterpol5:
+                    fIntRate = 5;
+                    return kTRUE;
+                case IDM_kInterpol10:
+                    fIntRate = 10;
+                    return kTRUE;
+                case IDM_kInterpol25:
+                    fIntRate = 25;
+                    return kTRUE;
+                case IDM_kInterpol125:
+                    fIntRate = 125;
+                    return kTRUE;
+                }
+                return kTRUE;
+
+            case IDM_kLimMag3:
+            case IDM_kLimMag4:
+            case IDM_kLimMag5:
+            case IDM_kLimMag6:
+            case IDM_kLimMag7:
+            case IDM_kLimMag8:
+            case IDM_kLimMag9:
+                for (int i=IDM_kLimMag3; i<=IDM_kLimMag9; i++)
+                    if (mp1==i)
+                        fLimMag->CheckEntry(i);
+                    else
+                        fLimMag->UnCheckEntry(i);
+
+                fSao->SetLimitMag(mp1-IDM_kLimMag3+3);
+                return kTRUE;
+            }
+            break;
+        }
+        break;
+    }
+
+    return kTRUE;
+}
+
+void MGPngReader::GetCoordinates()
+{
+    XY xy = fCRaDec->GetCoordinates();
+
+    if (fSetup->IsEntryChecked(IDM_kUseFileRaDec))
+    {
+        ifstream fin("coordinates.txt");
+        if (!fin)
+            cout << "Error: Cannot open 'coordinates.txt' using fall back solution." << endl;
+        else
+            fin >> xy;
+    }
+
+    fCRaDec->SetCoordinates(xy);
+    fRaDec->Set(xy.X()*360/24, xy.Y());
+}
+
+void MGPngReader::CalcTrackingError(MStarList &spots, MStarList &stars)
+{
+    if (stars.GetRealEntries() < 3)
+    {
+        cout << "Sorry, less than 3 stars in FOV!" << endl;
+        return;
+    }
+
+    if (spots.GetRealEntries() < 1)
+    {
+        cout << "Sorry, less than 1 detected spot in FOV!" << endl;
+        return;
+    }
+
+    Int_t idx = 0;
+
+    MStarList sortedspots;
+
+    MStar *star;
+    MStar *spot;
+    MStarListIter NextStar(&stars);
+    MStarListIter NextSpot(&spots);
+
+    while ((spot=NextSpot()))
+    {
+        AltAz aa = fSao->CalcAltAzFromPix(spot->GetX(), spot->GetY());
+        spot->Set(aa.Az(), aa.Alt());
+    }
+
+    while ((star=NextStar()))
+    {
+        AltAz aa = fSao->CalcAltAzFromPix(star->GetX(), star->GetY());
+        star->Set(aa.Az(), aa.Alt());
+
+        const double aaz   = star->GetX();
+        const double dphi2 = aaz/2.;
+        const double cos2  = cos(dphi2)*cos(dphi2);
+        const double sin2  = sin(dphi2)*sin(dphi2);
+
+        Double_t min = 800;
+
+        NextSpot.Reset();
+        while ((spot=NextSpot()))
+        {
+            const double pzd = TMath::Pi()/2-spot->GetY();
+            const double azd = TMath::Pi()/2-star->GetY();
+
+            const double d = cos(azd)*cos2 - cos(2*pzd+azd)*sin2;
+
+            const Double_t dist = acos(d);
+
+            if (dist>=min)
+                continue;
+
+            min = dist;
+            sortedspots.AddAt(idx, spot->GetX(), spot->GetY(), spot->GetMag());
+        }
+        if (min>768)
+        {
+            cout << "ERROR!!!!!!!!" << endl;
+            return;
+        }
+        idx++;
+    }
+
+    //
+    // Now we have in sortedspots the entries with the shortest distances
+    // to the corresponding ones in stars.
+    // Now calculate the tracking error.
+    //
+    NextStar.Reset();
+    MStarListIter NextSpot2(&sortedspots);
+
+    Double_t meanx=0;
+    Double_t meany=0;
+
+    while ((star=NextStar()))
+    {
+        spot = NextSpot2();
+
+        meanx += star->GetX() - spot->GetX();
+        meany += star->GetY() - spot->GetY();
+    }
+
+    meanx /= idx;
+    meany /= idx;
+
+    cout << "Tracking Error:  dAlt=" << meany*180/TMath::Pi();
+    cout << "°  dAz=" << meanx*180/TMath::Pi() << "°    (calculated";
+    cout << " with " << idx << " stars/spots)" << endl;
+}
+
+
+
+void MGPngReader::ProcessFrame(const unsigned long n, byte *img, struct timeval *tm)
+{
+    static float myimg[768*576];
+
+    for (int i=0; i<768*576; i++)
+        myimg[i] += img[i];
+
+    if (n%fIntRate)
+        return;
+
+    cout << "Img: " << n << endl;
+
+    byte c[768*576];
+    for (int i=0; i<768*576; i++)
+        c[i] = (byte)(myimg[i]/fIntRate+.5);
+
+    if (!fWritePictures->IsEntryEnabled(IDM_kStart) &&
+        (!(n%fWrtRate) || fWriteType->IsEntryChecked(IDM_kOnce)))
+    {
+        if (fFileType->IsEntryChecked(IDM_kPNG))
+        {
+            static int num = 0;
+            char name[80];
+            sprintf(name, "pix/file%04d.png", num++);
+            Writer::Png(name, c, tm);
+        }
+
+        if (fFileType->IsEntryChecked(IDM_kPPM))
+        {
+            static int num = 0;
+            char name[80];
+            sprintf(name, "pix/file%04d.ppm", num++);
+            Writer::Ppm(name, c);
+        }
+
+        if (fWriteType->IsEntryChecked(IDM_kOnce))
+            ProcessMessage(MK_MSG(kC_COMMAND, kCM_MENU), IDM_kStop, 0);
+    }
+
+    MStarList spots;
+    if (fDisplay->IsEntryChecked(IDM_kStarguider))
+        Filter2::Execute(spots, c);
+    else
+        if (fDisplay->IsEntryChecked(IDM_kFilter))
+            Filter::Execute(c);
+
+    if (fDisplay->IsEntryChecked(IDM_kCaosFilter))
+    {
+        // Double_t kConv = 0.502; // [pix/mm]
+
+        static Timer t0(tm);
+        Timer t(tm);
+
+        fTime = (t.GetMjd()-t0.GetMjd())*24*60*60;
+
+        Leds leds;
+        CaosFilter::Execute(c, leds, 1);
+
+        if (fWrite->IsEntryChecked(IDM_kPositions))
+            leds.Print();
+
+        CaosFilter::FilterLeds(leds);
+        leds.Compress();
+
+        if (fWrite->IsEntryChecked(IDM_kLeds))
+            leds.Print();
+
+        Rings rings;
+        rings.CalcRings(leds);
+
+        leds.Sort();
+
+        fLeds  = &leds;
+        fRings = &rings;
+
+        if (fFile)
+            fTree->Fill();
+
+        if (fWrite->IsEntryChecked(IDM_kRings))
+            rings.Print();
+
+        if (fAnalyse->IsEntryEnabled(IDM_kStopAnalyse))
+        {
+            const Ring &center = rings.GetCenter();
+
+            Double_t phi[6] =
+            {
+                -124.727,
+                 -61.0495,
+                 -16.7907,
+                  49.3119,
+                 139.086
+            };
+
+            fHistpr->Fill(center.GetR());
+            fHistprx->Fill(center.GetX());
+            fHistpry->Fill(center.GetY());
+            fHistprxpry->Fill(center.GetX(), center.GetY());
+
+            Double_t sum = 0;
+            for (int i=0; i<6 && leds.At(i); i++)
+            {
+                const Double_t w = (leds(i).GetPhi()-phi[i])*60;
+
+                sum += w;
+
+                fHistw[i]->Fill(w);
+                fHistv[i]->Fill(leds(i).GetPhi());
+                fGraphw[i]->SetPoint(fGraphw[i]->GetN(), fTime, w);
+            }
+            fHistallw->Fill(sum/5);
+
+            fGraphprx->SetPoint(fGraphprx->GetN(), fTime, center.GetX());
+            fGraphpry->SetPoint(fGraphpry->GetN(), fTime, center.GetY());
+        }
+    }
+
+    byte zimg[kZOOM*kZOOM];
+    for (int y=0; y<kZOOM; y++)
+        for (int x=0; x<kZOOM; x++)
+            zimg[x+y*kZOOM] = c[(fDx+(x-kZOOM/2)/2)+(fDy+(y-kZOOM/2)/2)*768];
+
+    fZoomImage->DrawImg(zimg);
+
+    if (fDisplay->IsEntryChecked(IDM_kCatalog))
+    {
+        DrawCircle(c, 0.5);
+        DrawCircle(c, 1.0);
+        DrawCircle(c, 1.5);
+
+        byte cimg[768*576];
+
+        GetCoordinates();
+
+        Timer time(tm);
+
+        MStarList stars;
+        fSao->GetStars(stars, time.GetMjd(), *fRaDec);
+        fSao->GetImg(c, cimg, stars);
+        //fSao->GetImg(c, cimg, time.CalcMjd(), *fRaDec);
+
+        fImage->DrawColImg(c, cimg);
+
+        fCZdAz->SetCoordinates(fSao->GetZdAz());
+
+        if (fDisplay->IsEntryChecked(IDM_kStarguider))
+            CalcTrackingError(spots, stars);
+    }
+    else
+        fImage->DrawImg(c);
+
+    memset(myimg, 0, 768*576*sizeof(float));
+}
+
+void MGPngReader::DrawCircle(byte *img, double r)
+{
+    const double rpix = (int)(r*60*60/fSao->GetPixSize()+1);
+    const int cx = 768/2;
+    const int cy = 576/2;
+    for (int dx=-rpix*0.7; dx<rpix*0.7; dx++)
+    {
+        const int dy = (int)sqrt(rpix*rpix-dx*dx);
+        img[cx+dx + (cy-dy)*768] = 0xd0;
+        img[cx+dx + (cy+dy)*768] = 0xd0;
+        img[cx-dy + (cy+dx)*768] = 0xd0;
+        img[cx+dy + (cy+dx)*768] = 0xd0;
+    }
+}
+
+Bool_t MGPngReader::HandleDoubleClick(Event_t *event)
+{
+    const Int_t w = fImage->GetWidth();
+    const Int_t h = fImage->GetHeight();
+    const Int_t x = fImage->GetX();
+    const Int_t y = fImage->GetY();
+
+    if (!(event->fX>x && event->fX<x+w && event->fY>y && event->fY<y+h))
+        return kTRUE;
+
+    Int_t dx = event->fX-x;
+    Int_t dy = event->fY-y;
+
+    if (dx<kZOOM/4) dx=kZOOM/4;
+    if (dy<kZOOM/4) dy=kZOOM/4;
+    if (dx>766-kZOOM/2) dx=766-kZOOM/4;
+    if (dy>510-kZOOM/2) dy=510-kZOOM/4;
+
+    fDx = dx;
+    fDy = dy;
+
+    cout << "New coordinates for zoom: " << fDx << " " << fDy << endl;
+
+    return kTRUE;
+}
Index: /trunk/MagicSoft/Cosy/gui/MGPngReader.h
===================================================================
--- /trunk/MagicSoft/Cosy/gui/MGPngReader.h	(revision 1802)
+++ /trunk/MagicSoft/Cosy/gui/MGPngReader.h	(revision 1802)
@@ -0,0 +1,142 @@
+#ifndef COSY_MGPngReader
+#define COSY_MGPngReader
+
+#ifndef ROOT_TGFrame
+#include <TGFrame.h>
+#endif
+#include "PixClient.h"
+#ifndef MARS_MObservatory
+#include "MObservatory.h"
+#endif
+
+#include "MGList.h"
+#include "MGImage.h"
+
+#include <TH1.h>
+#include <TH2.h>
+#include <TGraph.h>
+#include <TCanvas.h>
+
+class AltAz;
+class RaDec;
+
+class TTimer;
+
+class MGMenuBar;
+class MGPopupMenu;
+class TGTextEntry;
+
+class MGImage;
+class MGCoordinates;
+
+class StarCatalog;
+class MStarList;
+
+class TFile;
+class TTree;
+class TBranch;
+
+class Leds;
+class Rings;
+
+class MGPngReader : public PixClient, public TGMainFrame
+{
+private:
+    MGList        *fList;
+
+    MGMenuBar     *fMenu;
+    MGImage       *fImage;
+    MGImage       *fZoomImage;
+
+    MGPopupMenu   *fDisplay;
+    MGPopupMenu   *fWrite;
+    MGPopupMenu   *fWritePictures;
+    MGPopupMenu   *fFileType;
+    MGPopupMenu   *fWriteType;
+    MGPopupMenu   *fAnalyse;
+    MGPopupMenu   *fCaOs;
+    MGPopupMenu   *fWriteRate;
+    MGPopupMenu   *fInterpol;
+    MGPopupMenu   *fSetup;
+    MGPopupMenu   *fLimMag;
+
+    TFile         *fFile;
+    TTree         *fTree;
+    TBranch       *fBranchL;
+    TBranch       *fBranchT;
+    TBranch       *fBranchR;
+
+    Leds *fLeds;
+    Rings *fRings;
+    Double_t fTime;
+
+    TH1F          *fHistpr;
+    TH1F          *fHistprx;
+    TH1F          *fHistpry;
+    TH1F          *fHistw[6];
+    TH1F          *fHistallw;
+    TH1F          *fHistv[6];
+
+    TH2F          *fHistprxpry;
+
+    TGraph        *fGraphprx;
+    TGraph        *fGraphpry;
+    TGraph        *fGraphw[6];
+
+    MGCoordinates *fCRaDec;
+    MGCoordinates *fCZdAz;
+
+    TGTextEntry   *fPixSize;
+
+    StarCatalog   *fSao;
+
+    RaDec *fRaDec;
+
+    TTimer *fTimer;
+
+    Int_t fDx;
+    Int_t fDy;
+
+    int fIntRate;
+    int fWrtRate;
+
+    void SetPixSize(const double pixsize);
+    void Toggle(MGPopupMenu *p, UInt_t id);
+    void GetCoordinates();
+    void CalcTrackingError(MStarList &, MStarList &);
+
+    void InitHists();
+    void InitGraphs();
+    void InitGui();
+
+    void OpenFile();
+
+    void ResetHists();
+    void DisplayAnalysis();
+
+    Bool_t HandleTimer(TTimer *t);
+    //Bool_t HandleKey(Event_t* event);
+
+    void DrawCircle(byte *img, double r);
+
+public:
+    MGPngReader(MObservatory::LocationName_t obs);
+    virtual ~MGPngReader();
+
+    //void Update();
+
+    void Layout();
+    void CloseWindow();
+
+    Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2);
+    Bool_t HandleDoubleClick(Event_t *event);
+
+    //
+    // Execution of one frame - this function may be overloaded!
+    //
+    void ProcessFrame(const unsigned long n, byte *img, struct timeval *tm);
+
+    ClassDef(MGPngReader, 0)
+};
+
+#endif
Index: /trunk/MagicSoft/Cosy/gui/MGStarguider.cc
===================================================================
--- /trunk/MagicSoft/Cosy/gui/MGStarguider.cc	(revision 1801)
+++ /trunk/MagicSoft/Cosy/gui/MGStarguider.cc	(revision 1802)
@@ -73,7 +73,7 @@
 
 MGStarguider::MGStarguider(MObservatory::LocationName_t key)
-: Camera(), TGMainFrame(gClient->GetRoot(), 768, 700), fObservatory(key), fDx((768-kZOOM)/2), fDy((512-kZOOM)/2)
-{
-    gVirtualX->GrabButton(fId, kButton2, /*kButtonPressMask|kButtonReleaseMask|*/kNone, kNone, kNone, kNone);
+: TGMainFrame(gClient->GetRoot(), 768, 700), fObservatory(key), fDx((768-kZOOM)/2), fDy((512-kZOOM)/2)
+{
+    gVirtualX->GrabButton(fId, kButton2, 0, 0, 0, 0, kTRUE);
 
 
@@ -233,4 +233,6 @@
 MGStarguider::~MGStarguider()
 {
+    gVirtualX->GrabButton(0, kButton2, 0, 0, 0, 0, kFALSE);
+
     fTimer->TurnOff();
     delete fTimer;
@@ -252,5 +254,6 @@
     cout << "EventDisplay::CloseWindow: Exit Application Loop." << endl;
 
-    ExitLoop();
+    /*ExitLoop();*/
+    //cout << "FIXME: ExitLoop not called!!!!!!" << endl;
 
     gSystem->ExitLoop();
Index: /trunk/MagicSoft/Cosy/gui/MGStarguider.h
===================================================================
--- /trunk/MagicSoft/Cosy/gui/MGStarguider.h	(revision 1801)
+++ /trunk/MagicSoft/Cosy/gui/MGStarguider.h	(revision 1802)
@@ -5,7 +5,5 @@
 #include <TGFrame.h>
 #endif
-#ifndef CAMERA_H
-#include "Camera.h"
-#endif
+#include "PixClient.h"
 
 #include "MGList.h"
@@ -31,5 +29,5 @@
 class MStarList;
 
-class MGStarguider : public Camera, public TGMainFrame
+class MGStarguider : public PixClient, public TGMainFrame
 {
 private:
Index: /trunk/MagicSoft/Cosy/gui/Makefile
===================================================================
--- /trunk/MagicSoft/Cosy/gui/Makefile	(revision 1801)
+++ /trunk/MagicSoft/Cosy/gui/Makefile	(revision 1802)
@@ -21,5 +21,5 @@
 
 INCLUDES = -I. -I.. -I../base -I../slalib -I../candrv -I../incl \
-	   -I../catalog -I../videodev -I../main
+	   -I../catalog -I../videodev -I../main -I../caos
 
 # @code 
@@ -40,5 +40,7 @@
 	   MGVelocity.cc \
            MGStarguider.cc \
-	   MGSkyPosition.cc
+           MGPngReader.cc \
+	   MGSkyPosition.cc \
+           MGMenu.cc
 
 SRCS        = $(SRCFILES)
Index: /trunk/MagicSoft/Cosy/starg.cc
===================================================================
--- /trunk/MagicSoft/Cosy/starg.cc	(revision 1801)
+++ /trunk/MagicSoft/Cosy/starg.cc	(revision 1802)
@@ -1,8 +1,12 @@
-#include <iostream.h>
-
 #include <TROOT.h>
 #include <TApplication.h>
 
+#include <iostream.h>
+
 #include "MGStarguider.h"
+#include "MGPngReader.h"
+#include "Camera.h"
+#include "PngReader.h"
+#include "PixClient.h"
 
 /* ---------------------------------------------------------------------- */
@@ -16,9 +20,40 @@
     TApplication *app=new TApplication("Starguider", &argc, argv);
 
-    MGStarguider starg(MObservatory::kMagic1);
+    Bool_t dummy = kFALSE;
 
-    starg.Loop(0);
+    for (int i=0; i<argc; i++)
+    {
+        TString arg(argv[i]);
+        if (arg=="-d")
+            dummy = kTRUE;
+    }
 
-    app->Run(kTRUE);
+    PixClient *client=new MGPngReader(MObservatory::kMagic1);
+
+    if (dummy)
+    {
+        cout << " --> Starting in dummy-mode. <--" << endl;
+        PngReader *read=new PngReader(*client);
+        app->Run(kTRUE);
+        read->ExitLoop();
+        delete read;
+        //        delete client;
+    }
+    else
+    {
+        cout << " --> Starting in real-mode. <--" << endl;
+        //PixClient *client=new MGStarguider(MObservatory::kMagic1);
+        Camera *cam = new Camera(*client);
+        cam->Loop(0);
+        app->Run(kTRUE);
+        cam->ExitLoop();
+        delete cam;
+        //        delete client;
+    }
+
+    delete client;
+
+
+    cout << "Application end...." << endl;
 
     cout << "Exit." << endl;
Index: /trunk/MagicSoft/Cosy/videodev/Camera.cc
===================================================================
--- /trunk/MagicSoft/Cosy/videodev/Camera.cc	(revision 1801)
+++ /trunk/MagicSoft/Cosy/videodev/Camera.cc	(revision 1802)
@@ -102,5 +102,5 @@
 }
 
-Camera::Camera() : fd(-1), iBufferSize(0)
+Camera::Camera(PixClient &client) : fd(-1), iBufferSize(0), fClient(client)
 {
     cout << "Starting thread..." << flush;
@@ -192,10 +192,4 @@
 
 
-void Camera::ProcessFrame(const unsigned long n, byte *img,
-                          struct timeval *tm)
-{
-    cout << "Img: " << n << "  " << (void*)img << endl;
-}
-
 void *Camera::MapThread(void *arg)
 {
@@ -251,5 +245,5 @@
                 break;
 
-            ProcessFrame(i, (byte*)fImg, &fTime);
+            fClient.ProcessFrame(i, (byte*)fImg, &fTime);
             i++;
         }
@@ -258,10 +252,10 @@
         {
             LoopStep(i);
-            ProcessFrame(i, (byte*)fImg, &fTime);
+            fClient.ProcessFrame(i, (byte*)fImg, &fTime);
             i++;
         }
 
         LoopStep(i);
-        ProcessFrame(i, (byte*)fImg, &fTime);
+        fClient.ProcessFrame(i, (byte*)fImg, &fTime);
         i++;
 
Index: /trunk/MagicSoft/Cosy/videodev/Camera.h
===================================================================
--- /trunk/MagicSoft/Cosy/videodev/Camera.h	(revision 1801)
+++ /trunk/MagicSoft/Cosy/videodev/Camera.h	(revision 1802)
@@ -14,6 +14,5 @@
 #endif
 
-
-typedef unsigned char byte;
+#include "PixClient.h"
 
 class Camera
@@ -51,4 +50,6 @@
     pthread_cond_t  fCond;
 
+    PixClient &fClient;
+
     //
     // Hardware dependant functions
@@ -74,5 +75,5 @@
 
 public:
-    Camera();
+    Camera(PixClient &client);
     virtual ~Camera();
 
@@ -96,6 +97,6 @@
     // Execution of one frame - this function may be overloaded!
     //
-    virtual void ProcessFrame(const unsigned long n,
-                              byte *img, struct timeval *tm);
+    //virtual void ProcessFrame(const unsigned long n,
+    //                          byte *img, struct timeval *tm);
 
     //
Index: /trunk/MagicSoft/Cosy/videodev/CaosFilter.cc
===================================================================
--- /trunk/MagicSoft/Cosy/videodev/CaosFilter.cc	(revision 1802)
+++ /trunk/MagicSoft/Cosy/videodev/CaosFilter.cc	(revision 1802)
@@ -0,0 +1,620 @@
+#include "CaosFilter.h"
+
+#include <memory.h>   // memset
+#include <iostream.h> // cout
+#include <fstream.h>
+
+#include "Led.h"
+#include "Leds.h"
+
+ClassImp(CaosFilter);
+
+void CaosFilter::DrawBox(const int x1, const int y1,
+                     const int x2, const int y2,
+                     byte *buffer, const int col)
+{
+    for (int x=x1; x<x2+1; x++)
+        for (int y=y1; y<y2+1; y++)
+            buffer[y*768+x] = col;
+}
+
+void CaosFilter::MarkPoint(const int x, const int y, byte *buffer, const int col)
+{
+    DrawBox(x-8, y, x-5, y, buffer, col);
+    DrawBox(x, y+5, x, y+8, buffer, col);
+    DrawBox(x+5, y, x+8, y, buffer, col);
+    DrawBox(x, y-8, x, y-5, buffer, col);
+    return;
+}
+
+float CaosFilter::Mean(const byte *buffer, const int offset, int *min, int *max)
+{
+    double mean = 0.0;
+
+    *min = 0xff;
+    *max = 0x00;
+
+    //
+    // calculate mean value
+    //
+    for (int x=offset; x<768-offset; x++)
+        for (int y=offset; y<576-offset; y++)
+        {
+            byte val = buffer[y*768+x];
+
+            mean += val;
+
+            if (val>*max)
+                *max = val;
+
+            if (val<*min)
+                *min = val;
+        }
+
+    mean /= (768-2*offset)*(576-2*offset);
+
+    return mean;
+}
+
+int CaosFilter::GetMeanPosition(const byte *bitmap, const int x, const int y,
+                                const int box, Float_t &mx, Float_t &my)
+{
+    unsigned int sumx=0;
+    unsigned int sumy=0;
+
+    unsigned int sum=0;
+
+    for (int dx=x-box; dx<x+box+1; dx++)
+        for (int dy=y-box; dy<y+box+1; dy++)
+        {
+            const byte m = bitmap[dy*768+dx]; // desc->buffer[3*(x+y*768)]; //
+
+            sumx += m*dx;
+            sumy += m*dy;
+            sum  += m;
+        }
+
+    mx = (Float_t)sumx/sum;
+    my = (Float_t)sumy/sum;
+
+    return (int)my*768 + (int)mx;
+}
+
+float CaosFilter::SDev(const byte *buffer, const int offset, const double mean)
+{
+    //
+    // calculate sigma
+    //
+    double sdev=0.0;
+
+    for (int x=offset; x<768-offset; x++)
+        for (int y=offset; y<576-offset; y++)
+        {
+            const float val = mean - buffer[y*768+x];
+
+            sdev += val*val;
+        }
+
+    sdev /= (768-2*offset)*(576-2*offset)-1;
+
+    return sqrt(sdev);
+}
+
+
+int CaosFilter::GetMeanPosition(const byte *bitmap, const int x, const int y,
+                            const int box)
+{
+    unsigned int sumx=0;
+    unsigned int sumy=0;
+
+    unsigned int sum=0;
+
+    for (int dx=x-box; dx<x+box+1; dx++)
+        for (int dy=y-box; dy<y+box+1; dy++)
+        {
+            const byte m = bitmap[dy*768+dx]; // desc->buffer[3*(x+y*768)]; //
+
+            sumx += m*dx;
+            sumy += m*dy;
+            sum  += m;
+        }
+
+    const float px = (float)sumx/sum;
+    const float py = (float)sumy/sum;
+
+    return (int)py*768 + (int)px;
+}
+
+
+//
+// Calculation of center of rings
+//
+Double_t sqr(Double_t x) { return x*x; }
+
+void swap(int *m, int *n)
+{
+    int dummy = *m;
+    *m = *n;
+    *n = dummy;
+}
+
+bool CaosFilter::CalcCenter(Float_t *px, Float_t *py, Float_t &cx,
+                            Float_t &cy, Float_t &R)
+{
+    int i=0;
+    int j=1;
+    int k=2;
+
+    Float_t h1 = py[i]-py[j];
+
+    if (h1==0)
+    {
+        swap(&j, &k);
+        h1 = py[i]-py[j];
+        if (h1==0)
+        {
+            cout << "h1==0" <<endl;
+            return kFALSE;
+        }
+    }
+
+    Float_t h2 = py[j]-py[k];
+
+    if (h2==0)
+    {
+        swap(&i, &j);
+        h2 = py[j]-py[k];
+        if (h2==0)
+        {
+            cout << "h2==0" << endl;
+            return kFALSE;
+        }
+    }
+
+    Float_t w1 = px[i]-px[j];
+    Float_t w2 = px[j]-px[k];
+
+    Float_t m1 = -w1/h1;
+    Float_t m2 = -w2/h2;
+
+    if (m2-m1==0)
+    {
+        cout << "m2-m1==0" << endl;
+        return kFALSE;
+    }
+
+    cx = ((m2*(px[j]+px[k]) +py[i]-py[k]        -m1*(px[i]+px[j]))/(m2-m1)/2);
+    cy = ((m2*(py[i]+py[j]) +m1*m2*(px[k]-px[i])-m1*(py[j]+py[k]))/(m2-m1)/2);
+
+    R = sqrt(sqr(cx-px[i])+sqr(cy-py[i]));
+
+    return kTRUE;
+}
+
+//
+// Interpolation of centers of rings
+//
+void CaosFilter::InterpolCenter(int &m, Float_t *x, Float_t *y, Float_t &px,
+                                Float_t &py, Float_t &pr, Float_t &sx,
+                                Float_t &sy, Float_t &sr)
+{
+    int nPoints = m;
+    int mn[10]={0,0,0,1,4,10,20,35,56,84};
+    int nRings = mn[m];
+    Float_t rx[10];
+    Float_t ry[10];
+    Float_t rr[10];
+    px = 0;
+    py = 0;
+    pr = 0;
+
+    int n=0;
+    for (int i=0; i<nPoints-2; i++)
+        for (int j=i+1; j<nPoints-1; j++)
+            for (int k=j+1; k<nPoints; k++)
+            {
+                rx[n]=0;
+                ry[n]=0;
+                rr[n]=0;
+
+                Float_t xx[3] = { x[i], x[j], x[k] };
+                Float_t yy[3] = { y[i], y[j], y[k] };
+                CalcCenter(xx, yy, rx[n], ry[n], rr[n]);
+
+                px += rx[n];
+                py += ry[n];
+                pr += rr[n];
+
+                n++;
+            }
+
+    px /= n;
+    py /= n;
+    pr /= n;
+
+    //
+    // deviation of x- and y coordinate and radius
+    //
+    Float_t sumx=0;
+    Float_t sumy=0;
+    Float_t sumr=0;
+
+    for (n=0; n<nRings; n++)
+    {
+        sumx += sqr(rx[n]-px);
+        sumy += sqr(ry[n]-py);
+        sumr += sqr(rr[n]-pr);
+
+    }
+    sx=sqrt(sumx)/(nRings-1);
+    sy=sqrt(sumy)/(nRings-1);
+    sr=sqrt(sumr)/(nRings-1);
+}
+
+
+
+//
+//Calculation of rings
+//
+
+Double_t kConv = 0.502; // [pix/mm]
+
+void CaosFilter::CalcRings(int &m, Float_t *x, Float_t *y, Float_t &px,
+                       Float_t &py, Float_t &pr, float *v, float *w)
+{
+
+//    Float_t v[5];
+//    Float_t w[5];
+    Float_t s[5];
+    Float_t sx;
+    Float_t sy;
+    Float_t sr;
+
+    for (int i=0; i<6; i++)
+    {
+        x[i] /= kConv;
+        y[i] /= kConv;
+    }
+
+    InterpolCenter(m, x, y, px, py, pr, sx, sy, sr);
+
+    //
+    // angles v and relative angle w
+    //
+    for (int j=0; j<6; j++)
+    {
+        v[j] = atan2(y[j]-py, x[j]-px)*180/TMath::Pi();
+    }
+
+    w[0]=v[0]+167.11;
+    w[1]=v[1]-94.31;
+    w[2]=v[2]+87;
+    w[3]=v[3]+56.58;
+    w[4]=v[4]-33.48;
+
+    //
+    // distances between the LEDs
+    //
+    s[0]=sqrt(sqr(x[1]-x[0]) + sqr(y[1]-y[0]));///41.6;
+    s[1]=sqrt(sqr(x[1]-x[4]) + sqr(y[1]-y[4]));///27.7;
+    s[2]=sqrt(sqr(x[3]-x[4]) + sqr(y[3]-y[4]));///39.1;
+    s[3]=sqrt(sqr(x[2]-x[3]) + sqr(y[2]-y[3]));///14.4;
+    s[4]=sqrt(sqr(x[2]-x[0]) + sqr(y[2]-y[0]));///35.2;
+
+}
+
+//
+// filter LEDs from spots
+//
+int CaosFilter::FilterLeds(float *xw, float *yw, float *xl, float *yl)
+{
+    int n=0;
+    int m=0;
+
+    for (n=0; n<10; n++)
+    {
+        if (!(xw[n]>250 && xw[n]<540 && yw[n]>140 && yw[n]<500))
+            continue;
+
+        if (n>0 && xw[n]>(xl[m-1]-3) && xw[n]<(xl[m-1]+3))
+            continue;
+
+        xl[m]=xw[n];
+        yl[m]=yw[n];
+        m++;
+    }
+    return m;
+}
+
+void CaosFilter::FilterLeds(Leds &leds)
+{
+    for (int n=0; n<leds.GetEntries(); n++)
+    {
+        const Led &led = leds(n);
+
+        const Double_t x = led.GetX()-480;
+        const Double_t y = led.GetY()-200;
+
+        const Double_t r2 = x*x+y*y;
+
+        if (r2<80*80 || r2>145*145)
+        {
+            leds.RemoveAt(n);
+            continue;
+        }
+    }
+
+    TIter Next1(&leds);
+
+    Led *led1 = NULL;
+
+    while ((led1=(Led*)Next1()))
+    {
+        Led *led2 = NULL;
+        TIter Next2(&leds);
+
+        const Double_t x1 = led1->GetX();
+        const Double_t y1 = led1->GetY();
+
+        while ((led2=(Led*)Next2()))
+        {
+            if (led1==led2)
+                continue;
+
+            const Double_t x2 = led2->GetX();
+            const Double_t y2 = led2->GetY();
+
+            const Double_t dx = x2-x1;
+            const Double_t dy = y2-y1;
+
+            if (dx*dx+dy*dy<5*5)
+            {
+                // FIXME: Interpolation
+                leds.Remove(led2);
+            }
+        }
+    }
+}
+
+
+
+void CaosFilter::Execute(byte *img, float *xw, float *yw, float *xl,
+                         float *yl, float &prx, float &pry, float &pr, float *v, float *w)
+{
+    const int offset = 10;
+
+    int max;
+    int min;
+
+    const float mean = Mean(img, offset, &min, &max);
+    const float sdev = SDev(img, offset, mean);
+
+    const float cut = mean + 2.5*sdev;
+
+    //
+    // clean image from noise
+    //
+    for (int x=0; x<768; x++)
+        for (int y=0; y<576; y++)
+        {
+            if (img[y*768+x]>cut)
+                continue;
+
+            //
+            // FIXME: Create LOOKUP Table!
+            //
+
+            img[y*768+x] = 0;
+        }
+
+    //
+    // find mean points
+    //
+    const int maxpnt = 0x1000;
+
+    int pos[maxpnt+1][2]; // FIXME
+    int cnt = 0;
+
+    for (int x=offset; x<768-offset; x++)
+    {
+        for (int y=offset; y<576-offset; y++)
+        {
+            if (img[x+768*y]==0)
+                continue;
+
+            const int ipos = GetMeanPosition(img, x, y, 5);
+
+            int j;
+            for (j=0; j<cnt; j++)
+            {
+                if (pos[j][0]==ipos)
+                {
+                    if (pos[j][1] < 0xf0)
+                        pos[j][1] += 0x10;
+                    break;
+                }
+            }
+            if (cnt && j<cnt)
+                continue;
+
+            pos[cnt][0] = ipos; // pixel number
+            pos[cnt][1] = 0x10; // magnitude
+
+            cnt++;
+
+            if (cnt==maxpnt)
+                break;
+        }
+        if (cnt==maxpnt)
+        {
+            cout << "Error! More than " << maxpnt << " stars found." << endl;
+            break;
+        }
+    }
+
+
+    //
+    // Draw marker for found stars into picture
+    //
+    int points=0;
+
+    byte marker[768*576];
+    memset(marker, 0, 768*576);
+
+    for (int i=0; i<cnt; i++)
+    {
+        if (pos[i][1]<=0xa0)
+            continue;
+
+        const int px = pos[i][0]%768;
+        const int py = pos[i][0]/768;
+
+        MarkPoint(px, py, marker, pos[i][1]);
+
+        Float_t mx, my;
+        GetMeanPosition(img, px, py, 5, mx, my);
+
+        //
+        // Write positions in array
+        //
+        //            cout << mx << "  " << my << "  " << cnt << endl;
+        //            cout << "points:" << points << endl;
+
+        xw[points]=mx;
+        yw[points]=my;
+
+        points++;
+    }
+
+    int m = FilterLeds(xw, yw, xl, yl);
+    CalcRings(m, xl, yl, prx, pry, pr, v, w);
+
+    //
+    // Copy markers into image
+    //
+    for (int x=0; x<768*576; x++)
+    {
+        if (!marker[x])
+            continue;
+
+        img[x]=marker[x];
+    }
+}
+
+void CaosFilter::Execute(byte *img, Leds &leds, Double_t conv)
+{
+    const int offset = 10;
+
+    int max;
+    int min;
+
+    const float mean = Mean(img, offset, &min, &max);
+    const float sdev = SDev(img, offset, mean);
+
+    const float cut = mean + 2.5*sdev;
+
+    //
+    // clean image from noise
+    //
+    for (int x=0; x<768; x++)
+        for (int y=0; y<576; y++)
+        {
+            if (img[y*768+x]>cut)
+                continue;
+
+            //
+            // FIXME: Create LOOKUP Table!
+            //
+
+            img[y*768+x] = 0;
+        }
+
+    //
+    // find mean points
+    //
+    const int maxpnt = 0x1000;
+
+    int pos[maxpnt+1][2]; // FIXME
+    int cnt = 0;
+
+    for (int x=offset; x<768-offset; x++)
+    {
+        for (int y=offset; y<576-offset; y++)
+        {
+            if (img[x+768*y]==0)
+                continue;
+
+            const int ipos = GetMeanPosition(img, x, y, 5);
+
+            int j;
+            for (j=0; j<cnt; j++)
+            {
+                if (pos[j][0]==ipos)
+                {
+                    if (pos[j][1] < 0xf0)
+                        pos[j][1] += 0x10;
+                    break;
+                }
+            }
+            if (cnt && j<cnt)
+                continue;
+
+            pos[cnt][0] = ipos; // pixel number
+            pos[cnt][1] = 0x10; // magnitude
+
+            cnt++;
+
+            if (cnt==maxpnt)
+                break;
+        }
+        if (cnt==maxpnt)
+        {
+            cout << "Error! More than " << maxpnt << " stars found." << endl;
+            break;
+        }
+    }
+
+
+    //
+    // Draw marker for found stars into picture
+    //
+    int points=0;
+
+    byte marker[768*576];
+    memset(marker, 0, 768*576);
+
+    for (int i=0; i<cnt; i++)
+    {
+        if (pos[i][1]<=0x80) // 0xa0
+            continue;
+
+        const int px = pos[i][0]%768;
+        const int py = pos[i][0]/768;
+
+        MarkPoint(px, py, marker, pos[i][1]);
+
+        Float_t mx, my;
+        GetMeanPosition(img, px, py, 5, mx, my);
+
+        //
+        // Write positions in array
+        //
+        //            cout << mx << "  " << my << "  " << cnt << endl;
+        //            cout << "points:" << points << endl;
+
+        leds.Set(points++, mx/conv, my/conv, 0, 0, pos[i][1]);
+    }
+
+    //
+    // Copy markers into image
+    //
+    for (int x=0; x<768*576; x++)
+    {
+        if (!marker[x])
+            continue;
+
+        img[x]=marker[x];
+    }
+}
+
+        
Index: /trunk/MagicSoft/Cosy/videodev/Makefile
===================================================================
--- /trunk/MagicSoft/Cosy/videodev/Makefile	(revision 1801)
+++ /trunk/MagicSoft/Cosy/videodev/Makefile	(revision 1802)
@@ -20,5 +20,5 @@
 # @endcode 
 
-INCLUDES = -I. -I.. -I../incl -I../base -I/usr/X11R6/include
+INCLUDES = -I. -I.. -I../incl -I../base -I../caos -I/usr/X11R6/include
 
 # @code 
@@ -32,6 +32,9 @@
 
 SRCFILES = Camera.cc \
+           PngReader.cc \
+           PixClient.cc \
 	   Filter.cc \
 	   Filter2.cc \
+           CaosFilter.cc \
            Writer.cc 
 
Index: /trunk/MagicSoft/Cosy/videodev/PixClient.cc
===================================================================
--- /trunk/MagicSoft/Cosy/videodev/PixClient.cc	(revision 1802)
+++ /trunk/MagicSoft/Cosy/videodev/PixClient.cc	(revision 1802)
@@ -0,0 +1,10 @@
+#include "PixClient.h"
+
+#include <iostream.h>
+
+void PixClient::ProcessFrame(const unsigned long n, byte *img,
+                             struct timeval *tm)
+{
+    cout << "PixClient - Img: " << n << "  " << (void*)img << endl;
+}
+
Index: /trunk/MagicSoft/Cosy/videodev/PixClient.h
===================================================================
--- /trunk/MagicSoft/Cosy/videodev/PixClient.h	(revision 1802)
+++ /trunk/MagicSoft/Cosy/videodev/PixClient.h	(revision 1802)
@@ -0,0 +1,21 @@
+#ifndef COSY_PixClient
+#define COSY_PixClient
+
+#ifdef __CINT__
+struct timeval;
+#else
+#include <unistd.h>
+#include <sys/time.h>
+#endif
+
+
+typedef unsigned char byte;
+
+class PixClient
+{
+public:
+    virtual void ProcessFrame(const unsigned long n,
+                              byte *img, struct timeval *tm);
+};
+
+#endif
Index: /trunk/MagicSoft/Cosy/videodev/VideodevLinkDef.h
===================================================================
--- /trunk/MagicSoft/Cosy/videodev/VideodevLinkDef.h	(revision 1801)
+++ /trunk/MagicSoft/Cosy/videodev/VideodevLinkDef.h	(revision 1802)
@@ -8,6 +8,8 @@
 #pragma link C++ class Filter+;
 #pragma link C++ class Filter2+;
+#pragma link C++ class CaosFilter+;
 
 #pragma link C++ class Camera+;
+#pragma link C++ class PngReader+;
 
 #endif
