Index: trunk/MagicSoft/Cosy/catalog/SaoFile.cc
===================================================================
--- trunk/MagicSoft/Cosy/catalog/SaoFile.cc	(revision 740)
+++ trunk/MagicSoft/Cosy/catalog/SaoFile.cc	(revision 740)
@@ -0,0 +1,234 @@
+#include "SaoFile.h"
+
+#include <iostream.h>
+#include <string.h>
+
+#include "slamac.h"
+
+#include "File.h"
+
+#define FALSE 0
+#define TRUE  1
+
+static int lt(sort_t *t1, sort_t *t2)
+{
+    // t1->ra < t2->ra
+    if (t1->ra < t2->ra)
+        return 1;
+
+    // t1->ra > t2->ra
+    if (t1->ra > t2->ra)
+        return 0;
+
+    // t1->ra == t2->ra
+    if (t1->dec < t2->dec)
+        return 1;
+    else
+        return 0;
+}
+
+
+static void rekMergesort(sort_t **a, int length, int l, int r)
+{
+    // a recursive merge sort algorithm
+    if ( r <= l )
+        return;
+
+    sort_t **b = new sort_t*[length];
+
+    int m = (r+l)/2;
+
+    rekMergesort(a, length, l, m);
+
+    rekMergesort(a, length, m+1, r);
+
+    int i;
+    for (i=m+1; i>l; i--)
+        b[i-1]=a[i-1];
+
+    int j;
+    for (j=m; j<r; j++)
+        b[r+m-j]=a[j+1];
+
+    int k;
+    for (k=l; k<=r; k++)
+    {
+        if (lt( b[i],b[j]) )
+            a[k]=b[i++];
+        else
+            a[k]=b[j--];
+    }
+
+    delete b;
+}
+
+SaoFile::SaoFile(const char *name)
+{
+    file = new File(name, "r");
+
+    compressed = !strcasecmp(name+strlen(name)-4, ".cmp");
+
+    fEntries = file->Size()/(compressed?70-20:205);
+
+    cout << "Opening" << (compressed?" compressed":"") << " catalog '" << name << "'"
+        << " with " << fEntries << " entries" << endl;
+
+    delFlag = ' ';
+}
+
+SaoFile::~SaoFile()
+{
+    delete file;
+}
+
+int SaoFile::GetEntryNr() const
+{
+    return file->Tell()/(compressed?70-20:205);
+}
+
+int SaoFile::GetEntry(const int i)
+{
+    file->Seek(i*(compressed?70-20:205));
+    return GetNextEntry();
+}
+
+void SaoFile::Reset() const
+{
+    file->Seek(0);
+}
+
+int SaoFile::GetNextEntry()
+{
+    if (file->Eof())
+        return FALSE;
+
+    SAO = file->Geti(6);
+    if (!compressed)
+    {
+        delFlag = file->Getc();
+        file->Skip(77-8);
+    }
+    Pmag      = file->Getf(4);
+    Vmag      = file->Getf(4);
+    if (!compressed)
+        file->Skip(161/*151*/-85);
+    /*
+     RA2000h   = file->geti(2);
+     RA2000m   = file->geti(2);
+     RA2000s   = file->getf(6);
+     */
+    pmRA2000  = file->Getf(7);
+    if (!compressed)
+        file->Skip(178-168);
+    /*
+     DE2000sgn = file->getc();
+     DE2000d   = file->geti(2);
+     DE2000m   = file->geti(2);
+     DE2000s   = file->getf(5);
+     */
+    pmDE2000  = file->Getf(6);
+    RA2000rad = file->Getf(10);
+    DE2000rad = file->Getf(11);
+    file->Newline();
+
+    sprintf(data, "%6i%4.1f%4.1f"/*"%2i%2i%6.3f"*/"%7.4f"/*"%c%2i%2i%5.2f"*/"%6.3f%10.8f%11.8f\n",
+            Nr(), MagP(), MagV(), /*RaH(), RaM(), RaS(),*/ RaPm(),
+            /*DecSgn(), DecD(), DecM(), DecS(),*/ DecPm(), Ra(), Dec());
+
+    return !file->Eof();
+}
+
+void SaoFile::Print() const
+{
+    cout << SAO << " " << delFlag << " " << Pmag << " " << Vmag << " "
+        << /*RA2000h << "h" << RA2000m << "m" << RA2000s << "s " << */pmRA2000 << " "
+        << /*DE2000sgn << DE2000d << "d" << DE2000m << "m" << DE2000s << "s " << */pmDE2000 << " Ra:"
+        << RA2000rad << " Dec:" << DE2000rad << endl;
+}
+
+void SaoFile::Compress()
+{
+    FILE *f = fopen("sao.cmp", "w");
+
+    cout << endl << " Compressing catalog..." << flush;
+
+    const int entries = GetNrOfEntries();
+    const int step    = entries/360;
+
+    for (int i=0; i<entries; i++)
+    {
+        GetNextEntry();
+
+        if (!DelFlag())
+            fprintf(f, String());
+
+        if (i%step==0)
+            cout << "." << flush;
+    }
+    cout << "done." << endl;
+
+    fclose(f);
+}
+
+void SaoFile::Sort()
+{
+    cout << endl << "Reading coordinates..." << flush;
+
+    const int entries=GetNrOfEntries();
+
+    sort_t **srt = new sort_t*[entries];
+    for (int i=0; i<entries; i++)
+        srt[i] = new sort_t;
+
+    int counter=0;
+    const int step = entries/360;
+    while(GetNextEntry())
+    {
+        srt[counter]->ra  = (int)(360.0*(Ra()/D2PI));
+        srt[counter]->dec = (int)(360.0*(Dec()/D2PI));
+        srt[counter]->nr  = counter;
+
+        if (counter%step==0)
+            cout << "." << flush;
+
+        counter++;
+    }
+    cout << "done." << endl << endl;
+
+    /* sort entries */
+    cout << "Sorting coordinates..." << flush;
+    rekMergesort(srt, entries, 0, entries-1);
+    cout << "done." << endl << endl;
+
+    cout << "Writing sorted catalogue..." << flush;
+    FILE *f   = fopen("sao-sort.cmp", "w");
+    FILE *idx = fopen("sao-sort.idx", "w");
+
+    int ra=0, ral=0;
+    int dec=0, decl=0;
+    for (int i=0; i<entries; i++)
+    {
+        GetEntry(srt[i]->nr);
+
+        ra  = (int)(360.0*Ra()/D2PI);
+        dec = (int)(360.0*Dec()/D2PI);
+
+        if (ra!=ral || dec!=decl)
+        {
+            if (ra!=ral)
+                cout << "." << flush;
+            fprintf(idx, "%3d %3d %10d\n", ra, dec, i);
+        }
+
+        ral = ra;
+        decl = dec;
+
+        fprintf(f, String());
+        if (i%5000==0)
+            cout << "." << flush;
+    }
+    fclose(idx);
+    fclose(f);
+    cout << "done." << endl;
+}
+
Index: trunk/MagicSoft/Cosy/catalog/SaoFile.h
===================================================================
--- trunk/MagicSoft/Cosy/catalog/SaoFile.h	(revision 740)
+++ trunk/MagicSoft/Cosy/catalog/SaoFile.h	(revision 740)
@@ -0,0 +1,82 @@
+#ifndef SAOFILE_H
+#define SAOFILE_H
+
+#include "coord.h"
+
+struct _sort
+{
+   int ra;
+   int dec;
+   int nr;
+};
+
+typedef struct _sort sort_t;
+
+class File;
+
+class SaoFile
+{
+private:
+    File *file;
+    int compressed;
+
+    char data[205];
+
+    int   SAO;
+    char  delFlag;
+    float Pmag;
+    float Vmag;
+    // int   RA2000h;
+    // int   RA2000m;
+    // float RA2000s;
+    float pmRA2000;
+    // char  DE2000sgn;
+    // int   DE2000d;
+    // int   DE2000m;
+    float DE2000s;
+    float pmDE2000;
+    float RA2000rad;
+    float DE2000rad;
+
+    int fEntries;
+
+public:
+    SaoFile(const char *name);
+    ~SaoFile();
+
+    void  Compress();
+    void  Sort();
+
+    int   GetEntryNr() const;
+    int   GetEntry(const int i);
+    void  Reset() const;
+    int   GetNextEntry();
+    void  Print() const;
+
+    int   GetNrOfEntries() const { return fEntries; }
+
+    int   Nr() const          { return SAO; }
+    int   DelFlag() const     { return delFlag=='D'; }
+    float MagP() const        { return Pmag; }
+    float MagV() const        { return Vmag; }
+    float Ra() const          { return RA2000rad; }
+    float Dec() const         { return DE2000rad; }
+    RaDec GetRaDec() const    { return RaDec(RA2000rad, DE2000rad); }
+
+    float RaPm() const        { return pmRA2000; }
+    float DecPm() const       { return pmDE2000; }
+    RaDec GetRaDecPm() const  { return RaDec(pmRA2000, pmDE2000); }
+
+
+    // char DecSgn()   { return DE2000sgn; }
+    // int   RaH()     { return RA2000h; }
+    // int   DecD()    { return DE2000d; }
+    // int   RaM()     { return RA2000m; }
+    // int   DecM()    { return DE2000m; }
+    // float RaS()     { return RA2000s; }
+    // float DecS()    { return DE2000s; }
+
+    const char *String() const { return data; }
+};
+
+#endif
Index: trunk/MagicSoft/Cosy/catalog/StarCatalog.cc
===================================================================
--- trunk/MagicSoft/Cosy/catalog/StarCatalog.cc	(revision 740)
+++ trunk/MagicSoft/Cosy/catalog/StarCatalog.cc	(revision 740)
@@ -0,0 +1,668 @@
+#include "StarCatalog.h"
+
+#include <iomanip.h>   // cout
+#include <iostream.h>  // cout
+
+#include <TSystem.h>
+
+#include "slalib.h"
+#include "slamac.h"
+#include "File.h"
+#include "timer.h"
+
+StarCatalog::StarCatalog() : fEntries(0)
+{
+    // p = pointer to MainFrame (not owner)
+
+    //
+    // calculate observers location (goe)
+    //
+    int status;
+    slaDaf2r(51, 38, 48.0, &fPhi,   &status);
+    slaDaf2r( 9, 56, 36.0, &fElong, &status);
+
+    cout << "fPhi:   51ø38'48.0\" = " <<  360.0/D2PI*fPhi << endl;
+    cout << "fElong:  9ø56'36.0\" = " <<  360.0/D2PI*fElong << endl;
+
+    //
+    // read index file
+    //
+    File idx("sao-sort.idx", "r");
+    while (!idx.Eof())
+    {
+        idx.Newline();
+        fEntries++;
+    }
+
+    idx.Reset();
+
+    fSrt = new sort_t[fEntries];
+
+    for (int i=0; i<fEntries; i++)
+    {
+        fSrt[i].ra  = idx.Geti(4);
+        fSrt[i].dec = idx.Geti(4);
+        fSrt[i].nr  = idx.Geti(10);
+        idx.Newline();
+    }
+
+    //
+    // open catalog
+    //
+    fSao = new SaoFile("sao-sort.cmp");
+}
+
+StarCatalog::~StarCatalog()
+{
+    delete fSrt;
+    delete fSao;
+}
+
+void StarCatalog::SetPixSize(const double pixsize)
+{
+    fPixSize = D2PI/360.0 * pixsize;
+
+    fWidth  = fPixSize * 768/2;
+    fHeight = fPixSize * 576/2;
+}
+
+void StarCatalog::SetAltAz(const AltAz &altaz)
+{
+    fAltAz = altaz * D2PI/360.0;
+
+    cout << "Set --> Alt: " << 360.0/D2PI*fAltAz.Alt();
+    cout << "  Az: " << fAltAz.Az() << endl;
+
+    fRaDec = AltAz2RaDec(fAltAz);
+
+    cout << "Ra: " << 360.0/D2PI*fRaDec.Ra();
+    cout << "  Dec: " << 360.0/D2PI*fRaDec.Dec() << endl;
+
+    CalcAltAzRange();
+    CalcRaDecRange();
+}
+
+RaDec StarCatalog::AltAz2RaDec(const AltAz &altaz) const
+{
+    //
+    // -- observed to apparent --
+    //  Workaraound for slalib: discard const
+    //
+    double r=0, d=0;
+    slaOapqk ("A", altaz.Az(), DPI/2-altaz.Alt(), (double*)fAoprms, &r, &d);
+
+    //
+    // -- apparent to mean --
+    //  Workaraound for slalib: discard const
+    //
+    double ra, dec;
+    slaAmpqk(r, d, (double*)fAmprms, &ra, &dec);
+
+    return RaDec(ra, dec);
+}
+
+AltAz StarCatalog::RaDec2AltAz(const RaDec &radec, const RaDec &rdpm) const
+{
+    //
+    // ---- Mean to apparent ----
+    //
+
+    double r=0, d=0;
+    slaMapqkz(radec.Ra(), radec.Dec(), (double*)fAmprms, &r, &d);
+    //
+    // Doesn't work - don't know why
+    //
+    //    slaMapqk (radec.Ra(), radec.Dec(), rdpm.Ra(), rdpm.Dec(),
+    //              0, 0, (double*)fAmprms, &r, &d);
+    //
+
+    //
+    // -- apparent to observed --
+    //
+    double r1=0;  // ra
+    double d1=0;  // dec
+    double h0=0;  // ha
+
+    double zd;
+    double az;
+    slaAopqk (r, d, (double*)fAoprms,
+              &az,    // observed azimuth (radians: N=0,E=90)
+              &zd,    // observed zenith distance (radians) [-pi/2, pi/2]
+              &h0,    // observed hour angle (radians)
+              &d1,    // observed declination (radians)
+              &r1);   // observed right ascension (radians)
+
+    return AltAz(DPI/2-zd, az);
+}
+
+void StarCatalog::SetRaDec(const RaDec &radec, const RaDec &rdpm)
+{
+    fRaDec = radec;
+    fRaDec *= D2PI/360.0;
+
+    RaDec pm = rdpm * D2PI/360.0;
+
+    fAltAz = RaDec2AltAz(fRaDec, pm);
+
+    cout << "Alt: " << 360.0/D2PI*fAltAz.Alt() << "  ";
+    cout << "Az: "  << 360.0/D2PI*fAltAz.Az()  << endl;
+
+    CalcRaDecRange();
+    CalcAltAzRange();
+}
+
+void StarCatalog::CalcAltAzRange()
+{
+    char fAlt0[180];
+
+    for (int h=0; h<180; h++)
+        fAlt0[h] = kFALSE;
+
+    for (int h=0; h<360; h++)
+        fAz0[h] = kFALSE;
+
+    double az0, alt0;
+    double az1, alt1;
+    //
+    // scan horizontal border
+    //
+    for (int x=-768/2; x<768/2+1; x++)
+    {
+        slaDh2e(DPI+x*fPixSize, -fHeight, DPI/2-fAltAz.Alt(), &az0, &alt0);
+        slaDh2e(DPI+x*fPixSize, +fHeight, DPI/2-fAltAz.Alt(), &az1, &alt1);
+
+        const int z0 = ((int)(360.0/D2PI*(az0+fAltAz.Az()))+360)%360;
+        const int t0 = (int)(360.0/D2PI*alt0);
+
+        fAz0[z0] = kTRUE;
+
+        if (-89<=t0 && t0<=90)
+            fAlt0[90-t0] = kTRUE;
+
+        const int z1 = ((int)(360.0/D2PI*(az1+fAltAz.Az()))+360)%360;
+        const int t1 = (int)(360.0/D2PI*alt1);
+
+        fAz0[z1] = kTRUE;
+
+        if (-89<=t1 && t1<=90)
+            fAlt0[90-t1] = kTRUE;
+    }
+
+    //
+    // scan vertical border
+    //
+    for (int y=-576/2; y<576/2+1; y++)
+    {
+        slaDh2e(DPI-fWidth, y*fPixSize, DPI/2-fAltAz.Alt(), &az0, &alt0);
+        slaDh2e(DPI+fWidth, y*fPixSize, DPI/2-fAltAz.Alt(), &az1, &alt1);
+
+        const int z0 = ((int)(360.0/D2PI*(az0+fAltAz.Az()))+360)%360;
+        const int t0 = (int)(360.0/D2PI*alt0);
+
+        fAz0[z0] = kTRUE;
+
+        if (-89<=t0 && t0<=90)
+            fAlt0[90-t0] = kTRUE;
+
+        const int z1 = ((int)(360.0/D2PI*(az1+fAltAz.Az()))+360)%360;
+        const int t1 = (int)(360.0/D2PI*alt1);
+
+        fAz0[z1] = kTRUE;
+
+        if (-89<=t1 && t1<=90)
+            fAlt0[90-t1] = kTRUE;
+    }
+
+    //
+    // count degrees of azimut
+    //
+    fAzCnt=0;
+    for (int x=0; x<360; x++)
+        if (fAz0[x])
+            fAzCnt++;
+
+    cout << "fAzCnt: " << setw(3) << fAzCnt << "  " << flush;
+
+    //
+    // calculate min and max of altitude
+    //
+    fAltMin=0;
+    fAltMax=0;
+    for (int y=0; y<180; y++)
+    {
+        if (fAlt0[y])
+            fAltMax = y;
+
+        if (fAlt0[179-y])
+            fAltMin = 179-y;
+    }
+
+    fAltMin -= 90;
+    fAltMax -= 90;
+
+    //
+    // check whether altaz north- or south-pole is in the visible region
+    //
+    char img[768*576];
+    if (DrawAltAz(0, img, 90, 0))
+    {
+        fAltMax=89;
+        cout << "Alt Az Pole1 Inside!" << endl;
+    }
+    if (DrawAltAz(0, img, -90, 0))
+    {
+        fAltMin=-90;
+        cout << "Alt Az Pole2 Inside!" << endl;
+    }
+
+    cout << "fAltMin: " << setw(3) << fAltMin << "  ";
+    cout << "fAltMax: " << setw(3) << fAltMax << endl;
+}
+void StarCatalog::CalcRaDecRange()
+{
+    //
+    // calculate range to search in
+    //
+    char fDec[180];
+
+    for (int h=0; h<180; h++)
+        fDec[h] = kFALSE;
+
+    for (int h=0; h<360; h++)
+        fRa0[h] = kFALSE;
+
+    double ha0, ha1;
+    double de0, de1;
+
+    //
+    // scan horizontal border
+    //
+    for (int x=-768/2; x<768/2+1; x++)
+    {
+        double dx, dy;
+        slaDh2e(DPI-x*fPixSize, -fHeight, DPI/2-fAltAz.Alt(), &dx, &dy);
+        slaDh2e(fAltAz.Az()+dx, -dy, fPhi, &ha0, &de0);
+
+        slaDh2e(DPI-x*fPixSize, +fHeight, DPI/2-fAltAz.Alt(), &dx, &dy);
+        slaDh2e(fAltAz.Az()+dx, -dy, fPhi, &ha1, &de1);
+
+        const int h0 = ((int)(360.0/D2PI*(fAlpha-ha0))+360)%360;
+        const int d0 = (int)(360.0/D2PI*de0);
+
+        fRa0[h0] = kTRUE;
+
+        if (-90<=d0 && d0<=89)
+            fDec[d0+90] = kTRUE;
+
+        const int h1 = ((int)(360.0/D2PI*(fAlpha-ha1))+360)%360;
+        const int d1 = (int)(360.0/D2PI*de1);
+
+        fRa0[h1] = kTRUE;
+
+        if (-90<=d1 && d1<=89)
+            fDec[d1+90] = kTRUE;
+    }
+
+    //
+    // scan vertical border
+    //
+    for (int y=-576/2; y<576/2+1; y++)
+    {
+        double dx, dy;
+        slaDh2e(DPI-fWidth, -y*fPixSize, DPI/2-fAltAz.Alt(), &dx, &dy);
+        slaDh2e(fAltAz.Az()+dx, -dy, fPhi, &ha0, &de0);
+
+        slaDh2e(DPI+fWidth, -y*fPixSize, DPI/2-fAltAz.Alt(), &dx, &dy);
+        slaDh2e(fAltAz.Az()+dx, -dy, fPhi, &ha1, &de1);
+
+        const int h0 = ((int)(360.0/D2PI*(fAlpha-ha0))+360)%360;
+        const int d0 = (int)(360.0/D2PI*de0);
+
+        fRa0[h0] = kTRUE;
+
+        if (-90<=d0 && d0<=89)
+            fDec[d0+90] = kTRUE;
+
+        const int h1 = ((int)(360.0/D2PI*(fAlpha-ha1))+360)%360;
+        const int d1 = (int)(360.0/D2PI*de1);
+
+        fRa0[h1] = kTRUE;
+
+        if (-90<=d1 && d1<=89)
+            fDec[d1+90] = kTRUE;
+    }
+
+    //
+    // count degrees of right ascension
+    //
+    fRaCnt=0;
+    for (int x=0; x<360; x++)
+        if (fRa0[x])
+            fRaCnt++;
+    cout << "fRaCnt: " << setw(3) << fRaCnt << "  " << flush;
+
+    //
+    // calculate min and max of declination
+    //
+    for (int y=0; y<180; y++)
+    {
+        if (fDec[y])
+            fDecMax = y;
+
+        if (fDec[179-y])
+            fDecMin = 179-y;
+    }
+
+    fDecMin -= 90;
+    fDecMax -= 90;
+
+    //
+    // check whether radec north- or south-pole is in the visible region
+    //
+    char img[768*576];
+    if (DrawRaDec(0, img, 0, 90))
+    {
+        fDecMax=89;
+        cout << "Ra Dec Pole1 Inside!" << endl;
+    }
+    if (DrawRaDec(0, img, 0, -90))
+    {
+        fDecMin=-90;
+        cout << "Ra Dec Pole1 Inside!" << endl;
+    }
+
+    cout << "fDecMin: " << setw(3) << fDecMin << "  ";
+    cout << "fDecMax: " << setw(3) << fDecMax << endl;
+}
+
+void StarCatalog::DrawSCAltAz(char *img, const int color)
+{
+    //
+    // ------------ draw az lines ---------------
+    //
+    for (int az=0; az<360; az++)
+    {
+        if (!fAz0[az])
+            continue;
+
+        for (double alt=fAltMin-1; alt<fAltMax+1; alt+=0.006*(fAltMax-fAltMin))
+        {
+            if ((alt>88 && az%5) || alt>89.5)
+                continue;
+
+            DrawAltAz(color, img, alt, az);
+        }
+    }
+
+    //
+    // ------------ draw alt lines ---------------
+    //
+    for (int alt=fAltMin; alt<fAltMax+1; alt++)
+    {
+        for (double az=0; az<360; az+=0.004*fAzCnt)
+        {
+            if (!fAz0[(int)az] && !fAz0[(int)(az+359)%360] && !fAz0[(int)(az+1)%360])
+                continue;
+
+            DrawAltAz(color, img, alt, az);
+        }
+    }
+}
+
+void StarCatalog::DrawSCRaDec(char *img, const int color)
+{
+    //
+    // ------------ draw ra lines ---------------
+    //
+    for (int ra=0; ra<360; ra++)
+    {
+        if (!fRa0[ra])
+            continue;
+
+        for (double dec=fDecMin-1; dec<fDecMax+1; dec+=0.005*(fDecMax-fDecMin))
+        {
+            if ((dec>88 && ra%5) || dec>89.5)
+                continue;
+
+            DrawRaDec(color, img, ra, dec, ra==0||ra==90);
+        }
+    }
+
+    //
+    // ------------ draw dec lines ---------------
+    //
+    for (int dec=fDecMin; dec<fDecMax+1; dec++)
+    {
+        for (double ra=0; ra<360; ra+=0.003*fRaCnt)
+        {
+            if (!fRa0[(int)ra])
+                continue;
+
+            DrawRaDec(color, img, ra, dec, dec==89);
+        }
+    }
+
+//    DrawRaDec(color, img, 37.953, 89.2641, 10);
+}
+
+
+void StarCatalog::SetMjd(const double mjd)
+{
+    fMjd   = mjd;
+    fAlpha = slaGmst(mjd) + fElong;
+
+    cout << "UTC: " << mjd << endl;
+
+    //
+    // ----- calculate star independent parameters ----------
+    //
+    slaMappa(2000.0, fMjd, fAmprms);
+    slaAoppa(fMjd, 0,                // mjd, UT1-UTC
+             fElong, fPhi, 148,      // gttingen long, lat, height
+             0, 0,                   // polar motion x, y-coordinate (radians)
+             273.155, 1013.25, 0.5,  // temp, pressure, humidity
+             0.2, 0.0065,            // wavelength, tropo lapse rate
+             fAoprms);
+
+}
+
+void StarCatalog::DrawCross(char *img, const int x, const int y)
+{
+    for (int dx=-4; dx<5; dx++)
+        if (dx) img[y*768+x+dx] = 0xff;
+
+    for (int dy=-4; dy<5; dy++)
+        if (dy) img[(y+dy)*768+x] = 0xff;
+}
+
+void StarCatalog::GetImg(char *img, char *cimg, const double utc,
+                         const RaDec &radec)
+{
+    // memset(img,  0, 768*576);
+    memset(cimg, 0, 768*576);
+
+    SetMjd(utc);
+
+    SetRaDec(radec, RaDec());
+
+    DrawSCAltAz(cimg, 2<<4);
+    DrawSCRaDec(cimg, 2);
+
+    CalcImg(img);
+
+    DrawCross(img, 768/2, 576/2);
+}
+
+void StarCatalog::GetImg(char *img, char *cimg, const double utc,
+                         const AltAz &altaz)
+{
+    // memset(img,  0, 768*576);
+    memset(cimg, 0, 768*576);
+
+    SetMjd(utc);
+
+    SetAltAz(altaz);
+
+    CalcRaDecRange();
+    DrawSCRaDec(cimg, 2);
+    DrawSCAltAz(cimg, 2<<4);
+    CalcImg(img);
+
+    DrawCross(img, 768/2, 576/2);
+}
+
+void StarCatalog::DrawCircle(int color, char *img, int xx, int yy, int size)
+{
+    for (int x=xx-size; x<xx+size+1; x++)
+    {
+        if (x<0 || x>767)
+            continue;
+
+        const float p = xx+size-x;
+        const float q = 2*size - p;
+        const int h = (int)sqrt(p*q);
+
+        const int y1 = yy-h;
+        if (y1>=0 && y1<576)
+            img[y1*768+x] = color;
+
+        const int y2 = yy+h;
+        if (y2>=0 && y2<576)
+            img[y2*768+x] = color;
+    }
+}
+
+Bool_t StarCatalog::DrawAltAz(const int color, char *img, double alt, double az, int size)
+{
+    //
+    // alt/az[deg] -> alt/az[rad]
+    //
+    alt *= D2PI/360.0;
+    az  *= D2PI/360.0;
+
+    //
+    // alt/az[rad] -> alt/az[pix]
+    //
+    double dx, dy;
+    slaDe2h(az-fAltAz.Az(), -alt, DPI/2-fAltAz.Alt(), &dx, &dy);
+
+    //
+    // Align alt/az[pix]
+    //
+    const int xx = 767-(int)((fWidth-dx+DPI)/fPixSize);
+    const int yy =     (int)((fHeight+dy)/fPixSize);
+
+    //
+    // Range Check
+    //
+    if (!(0<=xx && xx<768 && 0<=yy && yy<576))
+        return kFALSE;
+
+    //
+    // Draw
+    //
+    DrawCircle(color, img, xx, yy, size);
+
+    return kTRUE;
+}
+
+Bool_t StarCatalog::Draw(const int color, char *img, const AltAz &altaz)
+{
+    return DrawAltAz(color, img, altaz.Alt(), altaz.Az());
+}
+
+Bool_t StarCatalog::Draw(const int color, char *img, const SaoFile *sao)
+{
+    //
+    // ---- mean to observed ---
+    //
+    AltAz altaz=RaDec2AltAz(sao->GetRaDec(), sao->GetRaDecPm()) * 360.0/D2PI;
+
+    if (sao->MagV() > fLimitMag)
+        return kFALSE;
+
+    const int mag = (10 - (sao->MagV()>1 ? (int)sao->MagV() : 1))/2;
+
+    //
+    // ---- imaging -----
+    //
+    return DrawAltAz(color, img, altaz.Alt(), altaz.Az(), mag);
+}
+
+Bool_t StarCatalog::DrawRaDec(const int color, char *img, double ra, double dec, int size)
+{
+    //
+    // radec[deg] -> radec[rad]
+    //
+    ra  *= D2PI/360.0;
+    dec *= D2PI/360.0;
+
+    //
+    // radec[rad] -> hadec[rad]
+    //
+    const double ha = fAlpha-ra;
+
+    //
+    // hadec[rad] -> altaz[rad]
+    //
+    double alt, az;
+    slaDe2h(ha, dec, fPhi, &az, &alt);
+
+    //
+    // altaz[rad] -> altaz[deg]
+    //
+    alt *= 360.0/D2PI;
+    az  *= 360.0/D2PI;
+
+    return DrawAltAz(color, img, alt, az, size);
+}
+
+Bool_t StarCatalog::Draw(const int color, char *img, const RaDec &radec)
+{
+    return DrawRaDec(color, img, radec.Ra(), radec.Dec());
+}
+
+void StarCatalog::CalcImg(char *img)
+{
+
+    //
+    // --------- search for stars in catalog ----------
+    //
+    int count   = 0;
+    int deleted = 0;
+
+    int idx     = 0;
+
+    while (fSrt[idx].dec<fDecMin)
+        idx++;
+
+    idx--;
+    while (++idx<fEntries && fSrt[idx].dec<fDecMax+1)
+    {
+        const int ra = fSrt[idx].ra;
+
+        if (!fRa0[ra])
+            continue;
+
+        int nr = fSrt[idx].nr;
+        do
+        {
+            //
+            // Get entry from catalog
+            //
+            fSao->GetEntry(nr++);
+
+            //
+            // Try to draw star into the image (white)
+            //
+            if (!Draw(0xff, img, fSao))
+                deleted++;
+
+            count++;
+        }
+        while ((int)(360.0/D2PI*fSao->Ra())==ra);
+    }
+
+    cout << " " << count << "-" << deleted << "=" << count-deleted << " " << flush;
+}
+
Index: trunk/MagicSoft/Cosy/catalog/StarCatalog.h
===================================================================
--- trunk/MagicSoft/Cosy/catalog/StarCatalog.h	(revision 740)
+++ trunk/MagicSoft/Cosy/catalog/StarCatalog.h	(revision 740)
@@ -0,0 +1,87 @@
+#ifndef STARCATALOG_H
+#define STARCATALOG_H
+
+#ifndef ROOT_TROOT
+#include <TROOT.h>
+#endif
+#ifndef SAOFILE_H
+#include "SaoFile.h"
+#endif
+
+#include "coord.h"
+
+class StarCatalog
+{
+private:
+    SaoFile *fSao;
+    sort_t  *fSrt;
+    int      fEntries;
+
+    double   fPhi;      // location of observatory
+    double   fElong;
+
+    double   fPixSize;  // [rad/pix] size of one pixel
+    double   fWidth;    // size of display
+    double   fHeight;   //
+
+    float    fLimitMag; // [M] limiting magnitude for display
+
+    AltAz    fAltAz;    // [rad]
+    char     fAz0[360];
+    int      fAltMin;
+    int      fAltMax;
+    int      fAzCnt;
+
+    RaDec    fRaDec;    // [rad]
+    char     fRa0[360];
+    int      fRaCnt;
+    int      fDecMin;
+    int      fDecMax;
+
+    double   fAlpha;
+    double   fMjd;
+    double   fAmprms[21];
+    double   fAoprms[14];
+
+    void DrawCross(char *img, const int x, const int y);
+    void DrawCircle(int color, char *img, int xx, int yy, int size);
+
+    Bool_t DrawAltAz(const int color, char *img, double alt, double az, int size=0);
+    Bool_t DrawRaDec(const int color, char *img, double ra,  double dec, int size=0);
+
+    Bool_t Draw(const int color, char *img, const AltAz &altaz);
+    Bool_t Draw(const int color, char *img, const RaDec &radec);
+    Bool_t Draw(const int color, char *img, const SaoFile *sao);
+
+    void   CalcImg(char *);
+
+    void   SetAltAz(const AltAz &altaz);
+    void   SetMjd(const double mjd);
+    void   DrawSCAltAz(char *img, const int color);
+    void   DrawSCRaDec(char *img, const int color);
+    void   SetRaDec(const RaDec &radec, const RaDec &rdpm);
+
+    void   CalcRaDecRange();
+    void   CalcAltAzRange();
+
+    RaDec  AltAz2RaDec(const AltAz &altaz) const;
+    AltAz  RaDec2AltAz(const RaDec &radec, const RaDec &rdpm) const;
+
+public:
+    StarCatalog();
+    virtual ~StarCatalog();
+
+    void   GetImg(char *img, char *cimg, const double utc,
+                  const RaDec &radec);
+    void   GetImg(char *img, char *cimg, const double utc,
+                  const AltAz &altaz);
+
+    const AltAz GetAltAz() const { return fAltAz*360/D2PI; }
+    const ZdAz  GetZdAz() const  { return ZdAz(DPI/2-fAltAz.Alt(), fAltAz.Az())*360/D2PI; }
+    const RaDec GetRaDec() const { return fRaDec*360/D2PI; }
+
+    void  SetPixSize(const double pixsize);
+    void  SetLimitMag(const float mag) { fLimitMag = mag; };
+};
+
+#endif
Index: trunk/MagicSoft/Cosy/gui/MGCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 740)
+++ trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 740)
@@ -0,0 +1,289 @@
+#include "MGCosy.h"
+
+#include "msgqueue.h"
+
+#include <TROOT.h>
+
+#include <TGMenu.h>        // TGPopupMenu
+#include <TGButton.h>      // TGButton
+#include <TSystem.h>       // gSystem
+#include <TGLabel.h>       // TGLabel
+#include <TGSplitter.h>    // TGHorizontal3DLine
+
+#include "timer.h"         // Timer
+
+#include "MCosy.h"
+#include "MGList.h"
+#include "MGCoordinates.h"
+
+#define IDM_EXIT 1
+#define IDM_TEXT 2
+
+#define kPB_POSITION  0x1001
+#define kPB_TRACK     0x1002
+#define kPB_STOP      0x1003
+#define kPB_CALCALTAZ 0x1004
+#define kPB_POLARIS   0x1005
+
+#define kEF_A         0x1010
+#define kEF_B         0x1011
+
+void MGCosy::CreateMenu()
+{
+    fLayMenuBar  = new TGLayoutHints (kLHintsNormal | kLHintsExpandX);
+    fLayMenuItem = new TGLayoutHints (kLHintsNormal, 0, 4, 0, 0);
+
+    //
+    //  crate the menu bar
+    //
+    TGPopupMenu *fFileMenu = new TGPopupMenu(fClient->GetRoot());
+    fFileMenu->AddEntry ("Exit", IDM_EXIT) ;
+    fFileMenu->Associate(this);
+    fList->Add(fFileMenu);
+
+    //
+    //  the button messages are handled by main frame (this)
+    //
+    TGMenuBar *fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
+    fMenuBar->AddPopup("File", fFileMenu, fLayMenuItem);
+    AddFrame(fMenuBar);
+    fList->Add(fMenuBar);
+
+    //
+    //  Seperator beyonf menubar
+    //
+    TGHorizontal3DLine *fLineSep = new TGHorizontal3DLine(this);
+    AddFrame(fLineSep, fLayMenuBar);
+    fList->Add(fLineSep);
+
+}
+
+void MGCosy::CreateLabel()
+{
+    fLabel1 = new TGLabel*[3];
+    fLabel1[0] = new TGLabel(this, "00000"); // Max: 16384
+    fLabel1[0]->SetTextJustify(kTextRight);
+    fLabel1[0]->Move(5, 40);
+    fList->Add(fLabel1[0]);
+    //    AddFrame(fLabel1[0], new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
+    fLabel1[1] = new TGLabel(this, "000");   // Max: 256
+    fLabel1[1]->SetTextJustify(kTextRight);
+    fLabel1[1]->Move(48, 40);
+    fList->Add(fLabel1[1]);
+    //    AddFrame(fLabel1[1], new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
+    fLabel1[2] = new TGLabel(this, "000");   // Max: 256
+    fLabel1[2]->SetTextJustify(kTextRight);
+    fLabel1[2]->Move(75, 40);
+    fList->Add(fLabel1[2]);
+    //    AddFrame(fLabel1[2], new TGLayoutHints(kLHintsNormal, 9, 9, 9, 9));
+
+    fLabel2 = new TGLabel*[3];
+    fLabel2[0] = new TGLabel(this, "00000");
+    fLabel2[0]->SetTextJustify(kTextRight);
+    fLabel2[0]->Move(5, 60);
+    fList->Add(fLabel2[0]);
+    //    AddFrame(fLabel2[0], new TGLayoutHints); //(kLHintsNormal, 0, 0, 0, 0));
+    fLabel2[1] = new TGLabel(this, "000");
+    fLabel2[1]->SetTextJustify(kTextRight);
+    fLabel2[1]->Move(48, 60);
+    fList->Add(fLabel2[1]);
+    //    AddFrame(fLabel2[1], new TGLayoutHints); //(kLHintsNormal, 1, 0, 0, 0));
+    fLabel2[2] = new TGLabel(this, "000");
+    fLabel2[2]->SetTextJustify(kTextRight);
+    fLabel2[2]->Move(75, 60);
+    fList->Add(fLabel2[2]);
+    //    AddFrame(fLabel2[2], new TGLayoutHints); //(kLHintsNormal, 2, 0, 0, 0));
+
+    fLabel3 = new TGLabel*[3];
+    fLabel3[0] = new TGLabel(this, "00000");
+    fLabel3[0]->SetTextJustify(kTextRight);
+    fLabel3[0]->Move(5, 80);
+    fList->Add(fLabel3[0]);
+    //    AddFrame(fLabel3[0]); //, new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
+    fLabel3[1] = new TGLabel(this, "000");
+    fLabel3[1]->SetTextJustify(kTextRight);
+    fLabel3[1]->Move(48, 80);
+    fList->Add(fLabel3[1]);
+    //    AddFrame(fLabel3[1]); //, new TGLayoutHints(kLHintsNormal, 1, 0, 0, 0));
+    fLabel3[2] = new TGLabel(this, "000");
+    fLabel3[2]->SetTextJustify(kTextRight);
+    fLabel3[2]->Move(75, 80);
+    fList->Add(fLabel3[2]);
+    //    AddFrame(fLabel3[2]); //, new TGLayoutHints(kLHintsNormal, 2, 0, 0, 0));
+}
+
+void MGCosy::CreateButton()
+{
+    TGTextButton *fButton1 = new TGTextButton(this, "Position Zd/Az", kPB_POSITION);
+    TGTextButton *fButton2 = new TGTextButton(this, "Track   Ra/Dec", kPB_TRACK);
+    TGTextButton *fButton3 = new TGTextButton(this, "Stop",           kPB_STOP);
+    TGTextButton *fButton4 = new TGTextButton(this, "Calc     Zd/Az", kPB_CALCALTAZ);
+    TGTextButton *fButton5 = new TGTextButton(this, "Set Polaris",    kPB_POLARIS);
+    fButton1->Move(110,  40);
+    fButton2->Move(110,  65);
+    fButton3->Move(260,  90);
+    fButton4->Move(110,  90);
+    fButton5->Move(110, 115);
+    fButton1->SetToolTipText("Move Telescope to Zd/Az position.");
+    fButton2->SetToolTipText("Track the coordinates given in Ra/Dec.");
+    fButton3->SetToolTipText("Stop movement of telescope.");
+    fButton4->SetToolTipText("Calculate Zd/Az corresponding to Ra/Dec.");
+    fButton5->SetToolTipText("Set the actual position as the position of Polaris.");
+    fList->Add(fButton1);
+    fList->Add(fButton2);
+    fList->Add(fButton3);
+    fList->Add(fButton4);
+    fList->Add(fButton5);
+}
+
+MGCosy::MGCosy(MsgQueue *q, const TGWindow *p, UInt_t w, UInt_t h)
+    : TGMainFrame(p, w, h), fQueue(q)
+{
+    fList = new MGList;
+
+    CreateMenu();
+    CreateLabel();
+    CreateButton();
+
+    fCoord = new MGCoordinates(this, kTRUE,
+                                "Coordinate 1 [\xb0]:", "Coordinate 2 [\xb0]:");
+    fCoord->Move(10, 160);
+    fList->Add(fCoord);
+
+    //
+    //   Map the window, set up the layout, etc.
+    //
+    SetWMSizeHints(350, 250, 350, 250, 10, 10 ) ;  // set the smallest and biggest size of the Main frame
+
+    MapSubwindows();
+    Layout();
+
+    SetWindowName("Cosy Main Window");
+    SetIconName("Cosy");
+
+    MapWindow();
+}
+
+
+
+// ======================================================================
+
+MGCosy::~MGCosy()
+{
+    delete fLayMenuBar;
+    delete fLayMenuItem;
+
+    fList->Delete();
+    delete fList;
+}
+// ======================================================================
+
+void MGCosy::CloseWindow()
+{
+    // Got close message for this MainFrame. Calls parent CloseWindow()
+    // (which destroys the window) and terminate the application.
+    // The close message is generated by the window manager when its close
+    // window menu item is selected.
+
+    gSystem->ExitLoop();
+    //  gSystem->DispatchOneEvent(kTRUE);
+
+    //    TGMainFrame::CloseWindow();
+    //  gROOT->GetApplication()->Terminate(0);
+}
+
+#include <iostream.h>
+
+Bool_t MGCosy::ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2)
+{
+    //
+    // This processing is serialized!
+    //
+    switch (GET_MSG(msg))
+    {
+    case kC_COMMAND:
+        switch (GET_SUBMSG(msg))
+        {
+        case kCM_BUTTON:
+
+            switch (mp1)
+            {
+            case kPB_POSITION:
+                cout << "Start positioning." << endl;
+                {
+                    XY xy = fCoord->GetCoordinates();
+                    ZdAz dest(xy.X(), xy.Y());
+                    cout << dest.Zd() << kDEG << " " << dest.Az() << kDEG << endl;
+                    fQueue->PostMsg(WM_POSITION, &dest, sizeof(dest));
+                }
+                cout << "PostMsg(WM_POSITION) returned." << endl;
+                return kTRUE;
+
+            case kPB_TRACK:
+                cout << "Start tracking." << endl;
+                {
+                    XY xy = fCoord->GetCoordinates();
+                    RaDec dest(xy.X(), xy.Y());
+                    cout << dest.Ra() << kDEG << " " << dest.Dec() << kDEG << endl;
+                    fQueue->PostMsg(WM_TRACK, &dest, sizeof(dest));
+                }
+                cout << "PostMsg(WM_TRACK) returned." << endl;
+                return kTRUE;
+
+            case kPB_STOP:
+                cout << "Sending stop movement msg." << endl;
+                fQueue->PostMsg(WM_STOP, 0, 0);
+                cout << "PostMsg(WM_STOP) returned." << endl;
+                return kTRUE;
+
+            case kPB_CALCALTAZ:
+                {
+                    Timer t;
+                    t.GetTime();
+
+                    XY xy = fCoord->GetCoordinates();
+                    RaDec rd(xy.X(), xy.Y());
+
+                    cout << "Ra/Dec: " << rd.Ra() << kDEG << " " << rd.Dec() << kDEG << endl;
+                    ZdAz aa=MCosy::RaDec2ZdAz(t.GetMjd(), rd*D2PI/360.0)*360.0/D2PI;
+                    cout << "Zd/Az: " << aa.Zd() << kDEG << " " << aa.Az() << kDEG << endl;
+                }
+                return kTRUE;
+
+            case kPB_POLARIS:
+                fQueue->PostMsg(WM_POLARIS, 0, 0);
+                return kTRUE;
+
+            default:
+                return kTRUE;
+            }
+            break;
+
+        case kCM_MENU:
+
+            switch (mp1)
+            {
+            case IDM_EXIT:
+                CloseWindow();
+                return kTRUE;
+
+            default:
+                return kTRUE;
+            }
+            return kTRUE;
+
+        default:
+            return kTRUE;
+        }
+
+    default:
+        return kTRUE;
+    }
+
+    //
+    // Start a thread to process the message.
+    //
+    // fQueue->PostMsg(msg, mp1, mp2);
+    return kTRUE;
+
+}
Index: trunk/MagicSoft/Cosy/gui/MGCosy.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCosy.h	(revision 740)
+++ trunk/MagicSoft/Cosy/gui/MGCosy.h	(revision 740)
@@ -0,0 +1,68 @@
+#ifndef MGCOSY_H
+#define MGCOSY_H
+
+#ifndef ROOT_TGFrame
+#include <TGFrame.h>
+#endif
+
+//#ifndef ROOT_TOrdCollection
+//#include <TOrdCollection.h>
+//#endif
+
+#ifndef ROOT_TGWidget
+#include <TGWidget.h>
+#endif
+
+#include <iostream.h>
+
+class TGLabel;
+class TGPopupMenu;
+class TGMenuBar;
+class TGHorizontal3DLine;
+class TGLayoutHints;
+class MsgQueue;
+class TIterator;
+class MGImage;
+class MGList;
+class MGCoordinates;
+
+class MGCosy : public TGMainFrame
+{
+private:
+
+    //
+    // Create a main frame with a number of different buttons.
+    //
+    TGLayoutHints *fLayMenuBar;
+    TGLayoutHints *fLayMenuItem;
+
+    MGList        *fList;
+
+    TGLabel      **fLabel1;
+    TGLabel      **fLabel2;
+    TGLabel      **fLabel3;
+
+    MGCoordinates *fCoord;
+
+    MsgQueue      *fQueue;
+
+    void CreateMenu();
+    void CreateLabel();
+    void CreateButton();
+
+public:
+    MGCosy(MsgQueue *q, const TGWindow *p, UInt_t w, UInt_t h);
+    ~MGCosy();
+
+    void CloseWindow();
+
+    TGLabel **GetLabel1() { return fLabel1; }
+    TGLabel **GetLabel2() { return fLabel2; }
+    TGLabel **GetLabel3() { return fLabel3; }
+
+    Bool_t ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2);
+};
+
+#endif
+
+
