Index: trunk/MagicSoft/Mars/mastro/MAstro.cc
===================================================================
--- trunk/MagicSoft/Mars/mastro/MAstro.cc	(revision 3537)
+++ trunk/MagicSoft/Mars/mastro/MAstro.cc	(revision 3568)
@@ -310,2 +310,97 @@
     return MTime(ut1).GetGmst();
 }
+
+// --------------------------------------------------------------------------
+//
+// RotationAngle 
+// 
+// calculates the angle for the rotation of the sky coordinate system
+// with respect to the local coordinate system. This is identical
+// to the rotation angle of the sky image in the camera.
+//
+//  sinl  [rad]: sine of observers latitude
+//  cosl  [rad]: cosine of observers latitude
+//  theta [rad]: polar angle/zenith distance
+//  phi   [rad]: rotation angle/azimuth
+//
+// Return sin/cos component of angle
+//
+// The convention is such, that the rotation angle is -pi/pi if
+// right ascension and local rotation angle are counted in the
+// same direction, 0 if counted in the opposite direction.
+//
+// (In other words: The rotation angle is 0 when the source culminates)
+//
+// Using vectors it can be done like:
+//    TVector3 v, p;
+//    v.SetMagThetaPhi(1, theta, phi);
+//    p.SetMagThetaPhi(1, TMath::Pi()/2-latitude, 0);
+//    v = v.Cross(l)); 
+//    v.RotateZ(-phi);
+//    v.Rotate(-theta)
+//    rho = TMath::ATan2(v(2), v(1));
+//
+// For more information see TDAS 00-11, eqs. (18) and (20)
+//
+void MAstro::RotationAngle(Double_t sinl, Double_t cosl, Double_t theta, Double_t phi, Double_t &sin, Double_t &cos)
+{
+    const Double_t sint = TMath::Sin(theta);
+    const Double_t cost = TMath::Cos(theta);
+
+    const Double_t snlt = sinl*sint;
+    const Double_t cslt = cosl*cost;
+
+    const Double_t sinp = TMath::Sin(phi);
+    const Double_t cosp = TMath::Cos(phi);
+
+    const Double_t v1 = sint*sinp;
+    const Double_t v2 = cosl - snlt*cosp;
+
+    const Double_t denom = TMath::Sqrt(v1*v1 + v2*v2);
+
+    cos =  -cosl*sinp      / denom;
+    sin = (snlt-cslt*cosp) / denom;
+}
+
+// --------------------------------------------------------------------------
+//
+// RotationAngle 
+// 
+// calculates the angle for the rotation of the sky coordinate system
+// with respect to the local coordinate system. This is identical
+// to the rotation angle of the sky image in the camera.
+//
+//  sinl  [rad]: sine of observers latitude
+//  cosl  [rad]: cosine of observers latitude
+//  theta [rad]: polar angle/zenith distance
+//  phi   [rad]: rotation angle/azimuth
+//
+// Return angle [rad] in the range -pi, pi
+//
+// The convention is such, that the rotation angle is -pi/pi if
+// right ascension and local rotation angle are counted in the
+// same direction, 0 if counted in the opposite direction.
+//
+// (In other words: The rotation angle is 0 when the source culminates)
+//
+// Using vectors it can be done like:
+//    TVector3 v, p;
+//    v.SetMagThetaPhi(1, theta, phi);
+//    p.SetMagThetaPhi(1, TMath::Pi()/2-latitude, 0);
+//    v = v.Cross(l)); 
+//    v.RotateZ(-phi);
+//    v.Rotate(-theta)
+//    rho = TMath::ATan2(v(2), v(1));
+//
+// For more information see TDAS 00-11, eqs. (18) and (20)
+//
+Double_t MAstro::RotationAngle(Double_t sinl, Double_t cosl, Double_t theta, Double_t phi)
+{
+    const Double_t snlt = sinl*TMath::Sin(theta);
+    const Double_t cslt = cosl*TMath::Cos(theta);
+
+    const Double_t sinp = TMath::Sin(phi);
+    const Double_t cosp = TMath::Cos(phi);
+
+    return TMath::ATan2(-cosl*sinp, snlt-cslt*cosp);
+}
Index: trunk/MagicSoft/Mars/mastro/MAstro.h
===================================================================
--- trunk/MagicSoft/Mars/mastro/MAstro.h	(revision 3537)
+++ trunk/MagicSoft/Mars/mastro/MAstro.h	(revision 3568)
@@ -50,4 +50,8 @@
     static Double_t UT2GMST(Double_t ut1);
 
+    // Rotation angle between local and sky coordinate system
+    static void     RotationAngle(Double_t sinl, Double_t cosl, Double_t theta, Double_t phi, Double_t &sin, Double_t &cos);
+    static Double_t RotationAngle(Double_t sinl, Double_t cosl, Double_t theta, Double_t phi);
+
     ClassDef(MAstro, 0)
 };
Index: trunk/MagicSoft/Mars/mastro/MAstroCamera.cc
===================================================================
--- trunk/MagicSoft/Mars/mastro/MAstroCamera.cc	(revision 3537)
+++ trunk/MagicSoft/Mars/mastro/MAstroCamera.cc	(revision 3568)
@@ -57,4 +57,5 @@
 using namespace std;
 
+// --------------------------------------------------------------------------
 MAstroCamera::MAstroCamera() : fGeom(0), fMirrors(0)
 {
@@ -63,4 +64,5 @@
 }
 
+// --------------------------------------------------------------------------
 MAstroCamera::~MAstroCamera()
 {
@@ -73,10 +75,11 @@
 }
 
-void MAstroCamera::SetMirrors(TClonesArray *arr)
-{
-    if (!arr || arr->GetClass()!=MGeomMirror::Class())
+// --------------------------------------------------------------------------
+void MAstroCamera::SetMirrors(TClonesArray &arr)
+{
+    if (arr.GetClass()!=MGeomMirror::Class())
         return;
 
-    const Int_t n = arr->GetSize();
+    const Int_t n = arr.GetSize();
 
     if (!fMirrors)
@@ -86,8 +89,9 @@
 
     for (int i=0; i<n; i++)
-        memcpy((*fMirrors)[i], (*arr)[i], sizeof(MGeomMirror));
-
-}
-
+        memcpy((*fMirrors)[i], arr[i], sizeof(MGeomMirror));
+
+}
+
+// --------------------------------------------------------------------------
 void MAstroCamera::SetGeom(const MGeomCam &cam)
 {
@@ -98,8 +102,7 @@
 }
 
-Int_t MAstroCamera::ConvertToPad(const TVector3 &w, TVector2 &v)
-{
-    const TVector3 spot = fMirror0->GetReflection(w, fGeom->GetCameraDist())*1000;
-
+// --------------------------------------------------------------------------
+Int_t MAstroCamera::ConvertToPad(const TVector3 &w, TVector2 &v) const
+{
     /*
      --- Use this to plot the 'mean grid' instead of the grid of a
@@ -113,5 +116,5 @@
         */
 
-
+    const TVector3 spot = fMirror0->GetReflection(w, fGeom->GetCameraDist())*1000;
     v.Set(spot(0), spot(1));
 
@@ -120,16 +123,5 @@
 }
 
-void MAstroCamera::DrawNet(const TRotation &trans)
-{
-    const TRotation rot(MAstroSky2Local(*fTime, *fObservatory));
-
-    TVector2 radec(fRaDec.Phi(), fRaDec.Theta());
-    MAstroCatalog::DrawNet(radec, trans*rot, 2);
-
-    const TVector3 zdaz0 = MAstroSky2Local(*fTime, *fObservatory)*fRaDec;
-    TVector2 zdaz(zdaz0.Phi(), zdaz0.Theta());
-    MAstroCatalog::DrawNet(zdaz, trans, 1);
-}
-
+// --------------------------------------------------------------------------
 TObject *FindObjectInPad(const char *name, TVirtualPad *pad)
 {
@@ -155,4 +147,5 @@
 }
 
+// --------------------------------------------------------------------------
 void MAstroCamera::AddPrimitives(Option_t *o)
 {
@@ -171,13 +164,4 @@
     const Bool_t hasdot  = opt.Contains(".", TString::kIgnoreCase);
     const Bool_t usecam  = opt.Contains("c", TString::kIgnoreCase);
-
-    MAstroSky2Local rot(*fTime, *fObservatory);
-
-    const Float_t rho = rot.RotationAngle(fRaDec.Phi(), TMath::Pi()/2-fRaDec.Theta());
-
-    TString str = fTime->GetSqlDateTime();
-    str += Form("  (\\alpha=%.1fh \\delta=%.1f\\circ)  \\rho=%.1f\\circ",
-                fRaDec.Phi()/TMath::Pi()*12, 90-fRaDec.Theta()*TMath::RadToDeg(),
-                rho *TMath::RadToDeg());
 
     // Get camera
@@ -198,5 +182,5 @@
     }
 
-    camera->SetTitle(str);
+    camera->SetTitle(GetPadTitle());
 
     gPad->cd(1);
@@ -221,20 +205,5 @@
     }
 
-    TVector3 zdaz0 = fRaDec;
-    zdaz0 *= rot;
-
-    cout << zdaz0.Phi()*TMath::RadToDeg() << " " << zdaz0.Theta()*TMath::RadToDeg() << endl;
-
-    TVector3 test = zdaz0;
-    test *= rot.Inverse();
-
-    cout << test.Phi()*TMath::RadToDeg()/15 << " " << test.Theta()*TMath::RadToDeg() << endl;
-
-    TRotation rot2;
-    rot2.RotateZ(-zdaz0.Phi());
-    rot2.RotateY(-zdaz0.Theta());
-    rot2.RotateZ(-TMath::Pi()/2); // align coordinate system
-
-    DrawNet(rot2);
+    const TRotation rot(GetGrid(kTRUE));
 
     MVector3 *radec;
@@ -247,8 +216,6 @@
         TVector3 star(*radec);
 
-        // Calculate local coordinates
+        // Rotate Star into telescope system
         star *= rot;
-        // Rotate Star into telescope system
-        star *= rot2;
 
         TVector3 mean;
@@ -270,6 +237,4 @@
             {
                 TMarker *m=new TMarker(spot(0), spot(1), 1);
-                m->SetBit(kCannotPick);
-                m->SetBit(kCanDelete);
                 m->SetMarkerColor(kMagenta);
                 m->SetMarkerStyle(kDot);
@@ -303,14 +268,10 @@
         case kKey_Plus:
             fTime->SetMjd(fTime->GetMjd()+0.25/24);
-            SetBit(kHasChanged);
-            gPad->Modified();
-            gPad->Update();
+            Update(kTRUE);
             return;
 
         case kKey_Minus:
             fTime->SetMjd(fTime->GetMjd()-0.25/24);
-            SetBit(kHasChanged);
-            gPad->Modified();
-            gPad->Update();
+            Update(kTRUE);
             return;
         }
Index: trunk/MagicSoft/Mars/mastro/MAstroCamera.h
===================================================================
--- trunk/MagicSoft/Mars/mastro/MAstroCamera.h	(revision 3537)
+++ trunk/MagicSoft/Mars/mastro/MAstroCamera.h	(revision 3568)
@@ -21,8 +21,7 @@
     MGeomMirror  *fMirror0;     //!
 
-    Int_t  ConvertToPad(const TVector3 &w, TVector2 &v);
+    Int_t  ConvertToPad(const TVector3 &w, TVector2 &v) const;
     void   AddPrimitives(Option_t *o);
     void   SetRangePad() { }
-    void   DrawNet(const TRotation &rot);
     void   ExecuteEvent(Int_t event, Int_t mp1, Int_t mp2);
 
@@ -31,5 +30,5 @@
     ~MAstroCamera();
 
-    void SetMirrors(TClonesArray *arr);
+    void SetMirrors(TClonesArray &arr);
     void SetGeom(const MGeomCam &cam);
 
Index: trunk/MagicSoft/Mars/mastro/MAstroCatalog.cc
===================================================================
--- trunk/MagicSoft/Mars/mastro/MAstroCatalog.cc	(revision 3537)
+++ trunk/MagicSoft/Mars/mastro/MAstroCatalog.cc	(revision 3568)
@@ -33,6 +33,8 @@
 #include "MAstroCatalog.h"
 
+#include <errno.h>
 #include <fstream>
 #include <stdlib.h>
+#include <limits.h> // INT_MAX (Suse 7.3/gcc 2.95)
 
 #include <KeySymbols.h>
@@ -45,4 +47,5 @@
 #include <TGToolTip.h>
 #include <TRotation.h>
+#include <TPaveText.h>
 #include <TStopwatch.h>
 
@@ -59,5 +62,5 @@
 
 using namespace std;
-
+/*
 class MRotation : public TRotation
 {
@@ -76,5 +79,5 @@
     }
 };
-
+*/
 /*
 MVector3 MVector3::GetZdAz(const MObservatory &obs, Double_t gmst) const
@@ -134,5 +137,6 @@
 }
 */
-MAstroCatalog::MAstroCatalog() : fLimMag(99), fRadiusFOV(99), fToolTip(0), fObservatory(0), fTime(0)
+// --------------------------------------------------------------------------
+MAstroCatalog::MAstroCatalog() : fLimMag(99), fRadiusFOV(90), fToolTip(0), fObservatory(0), fTime(0)
 {
     fList.SetOwner();
@@ -140,4 +144,5 @@
 }
 
+// --------------------------------------------------------------------------
 MAstroCatalog::~MAstroCatalog()
 {
@@ -161,4 +166,5 @@
 }
 
+// --------------------------------------------------------------------------
 TString MAstroCatalog::FindToken(TString &line, Char_t tok)
 {
@@ -176,4 +182,5 @@
 }
 
+// --------------------------------------------------------------------------
 Int_t MAstroCatalog::atoi(const TSubString &sub)
 {
@@ -181,4 +188,5 @@
 }
 
+// --------------------------------------------------------------------------
 Float_t MAstroCatalog::atof(const TSubString &sub)
 {
@@ -186,4 +194,5 @@
 }
 
+// --------------------------------------------------------------------------
 Int_t MAstroCatalog::atoi(const TString &s)
 {
@@ -191,4 +200,5 @@
 }
 
+// --------------------------------------------------------------------------
 Float_t MAstroCatalog::atof(const TString &s)
 {
@@ -196,4 +206,5 @@
 }
 
+// --------------------------------------------------------------------------
 Int_t MAstroCatalog::ReadXephem(TString catalog)
 {
@@ -203,4 +214,10 @@
 
     ifstream fin(catalog);
+    if (!fin)
+    {
+        gLog << err << "Cannot open file " << catalog << ": ";
+        gLog << strerror(errno) << endl;
+        return 0;
+    }
 
     Int_t add =0;
@@ -276,4 +293,5 @@
 }
 
+// --------------------------------------------------------------------------
 Int_t MAstroCatalog::ReadNGC2000(TString catalog)
 {
@@ -283,4 +301,10 @@
 
     ifstream fin(catalog);
+    if (!fin)
+    {
+        gLog << err << "Cannot open file " << catalog << ": ";
+        gLog << strerror(errno) << endl;
+        return 0;
+    }
 
     Int_t add=0;
@@ -339,4 +363,5 @@
 }
 
+// --------------------------------------------------------------------------
 Int_t MAstroCatalog::ReadBSC(TString catalog)
 {
@@ -346,4 +371,10 @@
 
     ifstream fin(catalog);
+    if (!fin)
+    {
+        gLog << err << "Cannot open file " << catalog << ": ";
+        gLog << strerror(errno) << endl;
+        return 0;
+    }
 
     Int_t add=0;
@@ -404,8 +435,8 @@
 }
 
+// --------------------------------------------------------------------------
 void MAstroCatalog::Paint(Option_t *o)
 {
-//    if (!gPad->IsBatch())
-//        gVirtualX->ClearWindow();
+    SetRangePad();
 
     if (TestBit(kHasChanged))
@@ -413,4 +444,5 @@
 }
 
+// --------------------------------------------------------------------------
 void MAstroCatalog::DrawStar(Double_t x, Double_t y, const TVector3 &v, Bool_t transparent, const char *txt)
 {
@@ -428,10 +460,9 @@
     TMarker *tip=new TMarker(x, y, transparent ? kDot : kFullDotLarge);;
     tip->SetMarkerColor(kBlack);
-    tip->SetBit(kCanDelete);
-    tip->SetBit(kCannotPick);
     AddMap(tip, new TString(str));
 }
 
-void MAstroCatalog::Update()
+// --------------------------------------------------------------------------
+void MAstroCatalog::Update(Bool_t upd)
 {
     if (gPad && TestBit(kMustCleanup))
@@ -439,7 +470,14 @@
         SetBit(kHasChanged);
         gPad->Modified();
-    }
-}
-
+        if (upd)
+            gPad->Update();
+    }
+}
+
+// --------------------------------------------------------------------------
+//
+// Set the observation time. Necessary to use local coordinate
+// system.
+//
 void MAstroCatalog::SetTime(const MTime &time)
 {
@@ -449,4 +487,9 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// Set the observatory location. Necessary to use local coordinate
+// system.
+//
 void MAstroCatalog::SetObservatory(const MObservatory &obs)
 {
@@ -456,26 +499,34 @@
 }
 
-Int_t MAstroCatalog::ConvertToPad(const TVector3 &w0, TVector2 &v)
+// --------------------------------------------------------------------------
+//
+// Convert the vector to pad coordinates. After conversion
+// the x- coordinate of the vector must be the x coordinate
+// of the pad - the same for y. If the coordinate is inside
+// the current draw area return kTRUE, otherwise kFALSE.
+// If it is an invalid coordinate return kERROR
+//
+Int_t MAstroCatalog::ConvertToPad(const TVector3 &w0, TVector2 &v) const
 {
     TVector3 w(w0);
 
-    // Stretch such, that the X-component is alwas the same. Now
-    // Y and Z contains the crossing point between the star-light
-    // and the plain of a virtual screen (ccd...)
+    // Stretch such, that the Z-component is alwas the same. Now
+    // X and Y contains the intersection point between the star-light
+    // and the plain of a virtual plain screen (ccd...)
     if (TestBit(kPlainScreen))
-        w *= TMath::RadToDeg()/w.X();
-    else
-        w.SetMag(TMath::RadToDeg());
-
-    v.Set(w(1), w(2));
-
-    if (w(0)<0)
+        w *= 1./w(2);
+
+    w *= TMath::RadToDeg();
+    v.Set(w(0), w(1));
+
+    if (w(2)<0)
         return kERROR;
 
-    return w(1)>gPad->GetX1() && w(2)>gPad->GetY1() &&
-           w(1)<gPad->GetX2() && w(2)<gPad->GetY2();
-}
-
-Int_t MAstroCatalog::Convert(const TRotation &rot, TVector2 &v)
+    return w(0)>gPad->GetX1() && w(1)>gPad->GetY1() &&
+           w(0)<gPad->GetX2() && w(1)<gPad->GetY2();
+}
+
+// --------------------------------------------------------------------------
+Int_t MAstroCatalog::Convert(const TRotation &rot, TVector2 &v) const
 {
     MVector3 w;
@@ -486,4 +537,5 @@
 }
 
+// --------------------------------------------------------------------------
 Bool_t MAstroCatalog::DrawLine(const TVector2 &v, Double_t dx, Double_t dy, const TRotation &rot, Int_t type)
 {
@@ -501,18 +553,14 @@
 
     TLine *line = new TLine(v0.X(), v0.Y(), v1.X(), v1.Y());
-    line->SetBit(kCanDelete);
     line->SetLineStyle(kDashDotted); //kDashed, kDotted, kDashDotted
     line->SetLineColor(kWhite+type*2);
-    line->SetBit(kCannotPick);
     AddMap(line);
 
     const TVector2 deg = v*TMath::RadToDeg();
     TString txt = type==1 ?
-        Form("Ra=%.1fh  Dec=%.1fd", fmod(deg.X()/15+48, 24),  fmod(90-deg.Y()+270,180)-90) :
+        Form("Ra=%.2fh  Dec=%.1fd", fmod(deg.X()/15+48, 24),  fmod(90-deg.Y()+270,180)-90) :
         Form("Zd=%.1fd  Az=%.1fd",  fmod(deg.Y()+270,180)-90, fmod(deg.X()+720, 360));
 
     TMarker *tip=new TMarker(v0.X(), v0.Y(), kDot);
-    tip->SetBit(kCanDelete);
-    tip->SetBit(kCannotPick);
     tip->SetMarkerColor(kWhite+type*2);
     AddMap(tip, new TString(txt));
@@ -521,5 +569,9 @@
 }
 
-
+// --------------------------------------------------------------------------
+//
+// Use "local" draw option to align the display to the local
+// coordinate system instead of the sky coordinate system.
+//
 void MAstroCatalog::Draw(const TVector2 &v0, const TRotation &rot, TArrayI &dx, TArrayI &dy, Int_t stepx, Int_t stepy, Int_t type)
 {
@@ -570,5 +622,6 @@
 }
 
-void MAstroCatalog::DrawNet(const TVector2 &v0, const TRotation &rot, Int_t type)
+// --------------------------------------------------------------------------
+void MAstroCatalog::DrawGrid(const TVector3 &v0, const TRotation &rot, Int_t type)
 {
     TArrayI dx(1);
@@ -576,23 +629,26 @@
 
     // align to 1deg boundary
-    TVector2 v = v0*TMath::RadToDeg();
+    TVector2 v(v0.Phi()*TMath::RadToDeg(), v0.Theta()*TMath::RadToDeg());
     v.Set((Float_t)TMath::Nint(v.X()), (Float_t)TMath::Nint(v.Y()));
 
     // calculate stepsizes based on visible FOV
-    Int_t stepx=1;
-
-    if (fabs(90-v.Y())>90-fRadiusFOV || fabs(90-v.Y())<fRadiusFOV)
-        stepx = 180/10;
+    Int_t stepx = 1;
+
+    if (v.Y()<fRadiusFOV || v.Y()>180-fRadiusFOV)
+        stepx=36;
     else
     {
         // This is a rough estimate how many degrees are visible
-        const Float_t m = log(fRadiusFOV/180.)/log(90./fRadiusFOV-1);
+        const Float_t m = log(fRadiusFOV/180.)/log(90./(fRadiusFOV+1)+1);
         const Float_t t = log(180.)-m*log(fRadiusFOV);
-        const Int_t n = (Int_t)(exp(m*log(90-fabs(90-v.Y()))+t)+0.5);
-        stepx = n<6 ? 1 : n/6;
-    }
-
-    const Int_t n = (Int_t)(fRadiusFOV+1);
-    Int_t stepy = n<4 ? 1 : n/4;
+        const Float_t f = m*log(90-fabs(90-v.Y()))+t;
+        const Int_t nx = (Int_t)(exp(f)+0.5);
+        stepx = nx<4 ? 1 : nx/4;
+        if (stepx>36)
+            stepx=36;
+    }
+
+    const Int_t ny = (Int_t)(fRadiusFOV+1);
+    Int_t stepy = ny<4 ? 1 : ny/4;
 
     // align stepsizes to be devisor or 180 and 90
@@ -602,10 +658,18 @@
         stepy++;
 
-    // align to step-size boundary
+    // align to step-size boundary (search for the nearest one)
+    Int_t dv = 1;
     while ((int)(v.X())%stepx)
-        v.Set(v.X()+1, v.Y());
-
+    {
+        v.Set(v.X()+dv, v.Y());
+        dv = -TMath::Sign(TMath::Abs(dv)+1, dv);
+    }
+
+    dv = 1;
     while ((int)(v.Y())%stepy)
-        v.Set(v.X(), v.Y()+1);
+    {
+        v.Set(v.X(), v.Y()+dv);
+        dv = -TMath::Sign(TMath::Abs(dv)+1, dv);
+    }
 
     // draw...
@@ -615,21 +679,99 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// Get a rotation matrix which aligns the pointing position
+// to the center of the x,y plain
+//
+TRotation MAstroCatalog::AlignCoordinates(const TVector3 &v) const
+{
+    TRotation trans;
+    trans.RotateZ(-v.Phi());
+    trans.RotateY(-v.Theta());
+    trans.RotateZ(-TMath::Pi()/2);
+    return trans;
+}
+
+// --------------------------------------------------------------------------
+//
+// Return the rotation matrix which converts either sky or
+// local coordinates to coordinates which pole is the current
+// pointing direction.
+//
+TRotation MAstroCatalog::GetGrid(Bool_t local)
+{
+    const Bool_t enable = fTime && fObservatory;
+
+    if (!local)
+    {
+        const TRotation trans(AlignCoordinates(fRaDec));
+
+        DrawGrid(fRaDec, trans, 1);
+
+        if (enable)
+        {
+            const MAstroSky2Local rot(*fTime, *fObservatory);
+            DrawGrid(rot*fRaDec, trans*rot.Inverse(), 2);
+        }
+
+        return trans;
+    }
+
+    if (local && enable)
+    {
+        const MAstroSky2Local rot(*fTime, *fObservatory);
+
+        const TRotation trans(AlignCoordinates(rot*fRaDec));
+
+        DrawGrid(fRaDec,     trans*rot, 1);
+        DrawGrid(rot*fRaDec, trans,     2);
+
+        return trans*rot;
+    }
+
+    return TRotation();
+}
+
+// --------------------------------------------------------------------------
+TString MAstroCatalog::GetPadTitle() const
+{
+    const Double_t ra  = fRaDec.Phi()*TMath::RadToDeg();
+    const Double_t dec = (TMath::Pi()/2-fRaDec.Theta())*TMath::RadToDeg();
+
+    TString txt;
+    txt += Form("\\alpha=%.2fh ",      fmod(ra/15+48, 24));
+    txt += Form("\\delta=%.1f\\circ ", fmod(dec+270,180)-90);
+    txt += Form("/ FOV=%.1f\\circ",    fRadiusFOV);
+
+    if (!fTime || !fObservatory)
+        return txt;
+
+    const MAstroSky2Local rot(*fTime, *fObservatory);
+    const TVector3 loc = rot*fRaDec;
+
+    const Double_t rho = rot.RotationAngle(fRaDec.Phi(), TMath::Pi()/2-fRaDec.Theta());
+
+    const Double_t zd = TMath::RadToDeg()*loc.Theta();
+    const Double_t az = TMath::RadToDeg()*loc.Phi();
+
+    txt.Prepend("#splitline{");
+
+    txt += Form("  \\theta=%.1fh ",    fmod(zd+270,180)-90);
+    txt += Form("\\phi=%.1f\\circ ",   fmod(az+720, 360));
+    txt += Form(" / \\rho=%.1f\\circ", rho*TMath::RadToDeg());
+    txt += "}{<";
+    txt += fTime->GetSqlDateTime();
+    txt += ">}";
+    return txt;
+}
+
+// --------------------------------------------------------------------------
 void MAstroCatalog::AddPrimitives(Option_t *o)
 {
-    // Precalc Sin/Cos...
-    TRotation trans;
-    trans.RotateZ(-fRaDec.Phi());
-    trans.Rotate(TMath::Pi()/2-fRaDec.Theta(), TVector3(0, 1, 0));
-
-    if (fTime && fObservatory)
-    {
-        const TRotation rot(MAstroSky2Local(*fTime, *fObservatory));
-        const TVector3 zdaz0 = rot*fRaDec;
-        const TVector2 zdaz(zdaz0.Phi(), zdaz0.Theta());
-        DrawNet(zdaz, trans*rot.Inverse(), 2);
-    }
-
-    const TVector2 radec(fRaDec.Phi(), fRaDec.Theta());
-    DrawNet(radec, trans, 1);
+    const Bool_t local = TString(o).Contains("local", TString::kIgnoreCase);
+
+    cout << "Opt: " << o << endl;
+
+    const TRotation rot(GetGrid(local));
 
     TIter Next(&fList);
@@ -639,9 +781,19 @@
         // FIXME: Check Magnitude!
         TVector2 s(v->Phi(), v->Theta());
-        if (Convert(trans, s)==kTRUE)
+        if (Convert(rot, s)==kTRUE)
             DrawStar(s.X(), TMath::Pi()/2-s.Y(), *v, kFALSE);
     }
-}
-
+
+    TPaveText *pv = new TPaveText(0.01, 0.90, 0.63, 0.99, "brNDC");
+    pv->AddText(GetPadTitle());
+    AddMap(pv);
+
+    TMarker *mk=new TMarker(0, 0, kMultiply);
+    mk->SetMarkerColor(kBlack);
+    mk->SetMarkerSize(1.5);
+    AddMap(mk);
+}
+
+// --------------------------------------------------------------------------
 void MAstroCatalog::SetRangePad()
 {
@@ -658,4 +810,5 @@
 }
 
+// --------------------------------------------------------------------------
 void MAstroCatalog::DrawPrimitives(Option_t *o)
 {
@@ -680,4 +833,5 @@
 }
 
+// --------------------------------------------------------------------------
 void MAstroCatalog::DrawMap()
 {
@@ -688,4 +842,5 @@
 }
 
+// --------------------------------------------------------------------------
 void MAstroCatalog::Draw(Option_t *o)
 {
@@ -770,4 +925,5 @@
 }
 
+// --------------------------------------------------------------------------
 void MAstroCatalog::ExecuteEventKbd(Int_t keycode, Int_t keysym)
 {
@@ -821,4 +977,5 @@
 }
 
+// --------------------------------------------------------------------------
 Int_t MAstroCatalog::DistancetoPrimitive(Int_t px, Int_t py)
 {
@@ -843,4 +1000,5 @@
 }
 
+// --------------------------------------------------------------------------
 void MAstroCatalog::ShowToolTip(Int_t px, Int_t py, const char *txt)
 {
@@ -858,3 +1016,2 @@
     fToolTip->Show(x+4, y+4);
 }
-
Index: trunk/MagicSoft/Mars/mastro/MAstroCatalog.h
===================================================================
--- trunk/MagicSoft/Mars/mastro/MAstroCatalog.h	(revision 3537)
+++ trunk/MagicSoft/Mars/mastro/MAstroCatalog.h	(revision 3568)
@@ -74,8 +74,9 @@
 {
 private:
-    Double_t fLimMag;    // [1]   Limiting Magnitude
-    Double_t fRadiusFOV; // [deg] Radius of Field of View
-
-    TGToolTip *fToolTip; //!
+    Double_t   fLimMag;    // [1]   Limiting Magnitude
+    Double_t   fRadiusFOV; // [deg] Radius of Field of View
+
+    TExMap     fMapG;      //! A map with all gui primitives and tooltips
+    TGToolTip *fToolTip;   //! The tooltip currently displayed
 
     void ShowToolTip(Int_t px, Int_t py, const char *txt);
@@ -92,37 +93,18 @@
 //#endif
 
-protected:
-    enum {
-        kHasChanged  = BIT(15),
-        kGuiActive   = BIT(16),
-        kPlainScreen = BIT(17)
-    };
-
-    TExMap   fMapG;
-    TList    fList;      // List of stars loaded
-    MVector3 fRaDec;     // pointing position
-
-    MObservatory *fObservatory; // Possible obervatora location
-    MTime        *fTime;        // Possible observation time
-
-    virtual Int_t  ConvertToPad(const TVector3 &w, TVector2 &v);
-    virtual Int_t  Convert(const TRotation &rot, TVector2 &v);
-    virtual Bool_t DrawLine(const TVector2 &v0, Double_t dx, Double_t dy, const TRotation &rot, Int_t type);
-    virtual void   AddPrimitives(Option_t *o);
-    virtual void   DrawPrimitives(Option_t *o);
-    virtual void   SetRangePad();
-    void  Draw(const TVector2 &v0, const TRotation &rot, TArrayI &dx, TArrayI &dy, Int_t stepx, Int_t stepy, Int_t type);
-    void  DrawNet(const TVector2 &v0, const TRotation &rot, Int_t type);
-    void  DrawStar(Double_t x, Double_t y, const TVector3 &v, Bool_t t, const char *txt=0);
-    void  Paint(Option_t *o="");
-    Int_t DistancetoPrimitive(Int_t px, Int_t py);
-    void  Update();
-
-    void ExecuteEventKbd(Int_t keycode, Int_t keysym);
-    void ExecuteEvent(Int_t event, Int_t mp1, Int_t mp2);
-
-    void DrawMap();
-    void AddMap(void *k, void *v=0) { fMapG.Add(fMapG.GetSize(), (Long_t)k, (Long_t)v); }
-    void DeleteMap()
+    virtual Int_t ConvertToPad(const TVector3 &w, TVector2 &v) const;
+    virtual void  AddPrimitives(Option_t *o);
+    virtual void  SetRangePad();
+
+    Int_t     Convert(const TRotation &rot, TVector2 &v) const;
+    void      Draw(const TVector2 &v0, const TRotation &rot, TArrayI &dx, TArrayI &dy, Int_t stepx, Int_t stepy, Int_t type);
+    void      DrawPrimitives(Option_t *o);
+    Bool_t    DrawLine(const TVector2 &v0, Double_t dx, Double_t dy, const TRotation &rot, Int_t type);
+    void      DrawGrid(const TVector3 &v0, const TRotation &rot, Int_t type);
+    TRotation AlignCoordinates(const TVector3 &v) const;
+    void      Paint(Option_t *o="");
+    Int_t     DistancetoPrimitive(Int_t px, Int_t py);
+    void      DrawMap();
+    void      DeleteMap()
     {
         Long_t key, val;
@@ -148,4 +130,32 @@
     }
 
+protected:
+    enum {
+        kHasChanged  = BIT(15),
+        kGuiActive   = BIT(16),
+        kPlainScreen = BIT(17)
+    };
+
+    TList    fList;      // List of stars loaded
+    MVector3 fRaDec;     // pointing position
+
+    MObservatory *fObservatory; // Possible obervatora location
+    MTime        *fTime;        // Possible observation time
+
+    virtual TString GetPadTitle() const;
+    TRotation GetGrid(Bool_t local);
+    void      DrawStar(Double_t x, Double_t y, const TVector3 &v, Bool_t t, const char *txt=0);
+    void      Update(Bool_t upd=kFALSE);
+
+    void ExecuteEventKbd(Int_t keycode, Int_t keysym);
+    void ExecuteEvent(Int_t event, Int_t mp1, Int_t mp2);
+
+    void AddMap(TObject *k, void *v=0)
+    {
+        k->SetBit(kCanDelete);
+        k->SetBit(kCannotPick);
+        fMapG.Add(fMapG.GetSize(), (Long_t)k, (Long_t)v);
+    }
+
 public:
     MAstroCatalog();
@@ -161,5 +171,5 @@
         if (deg>max)
             deg=max;
-        if (deg<=0)
+        if (deg<1)
             deg=1;
 
@@ -189,4 +199,9 @@
 
     void Draw(Option_t *o="");
+    void SetDrawOption(Option_t *option="")
+    {
+        TObject::SetDrawOption(option);
+        Update(kTRUE);
+    } //*MENU*
 
     virtual void EventInfo(Int_t event, Int_t px, Int_t py, TObject *selected=0);
Index: trunk/MagicSoft/Mars/mastro/MAstroSky2Local.cc
===================================================================
--- trunk/MagicSoft/Mars/mastro/MAstroSky2Local.cc	(revision 3537)
+++ trunk/MagicSoft/Mars/mastro/MAstroSky2Local.cc	(revision 3568)
@@ -62,4 +62,5 @@
 #include "MAstroSky2Local.h"
 
+#include "MAstro.h"
 #include "MTime.h"
 #include "MObservatory.h"
@@ -128,18 +129,12 @@
 // seen with an Alt/Az telescope.
 //
+// For more information see MAstro::RotationAngle
+//
 Double_t MAstroSky2Local::RotationAngle(Double_t ra, Double_t dec) const
 {
-    TVector3 loc;
-    loc.SetMagThetaPhi(1, TMath::Pi()/2-dec, ra);
-    loc *= *this;
+    TVector3 v;
+    v.SetMagThetaPhi(1, TMath::Pi()/2-dec, ra);
+    v *= *this;
 
-    TRotation rot;
-    rot.RotateZ(-loc.Phi());
-    rot.RotateY(-loc.Theta());
-
-    TVector3 v(1, 0, 0);
-    v *= *this;
-    v *= rot;
-
-    return TMath::ATan2(v(1), v(0));
+    return MAstro::RotationAngle(ZZ(), XZ(), v.Theta(), v.Phi());
 }
Index: trunk/MagicSoft/Mars/mastro/MObservatory.cc
===================================================================
--- trunk/MagicSoft/Mars/mastro/MObservatory.cc	(revision 3537)
+++ trunk/MagicSoft/Mars/mastro/MObservatory.cc	(revision 3568)
@@ -101,97 +101,31 @@
 {
     *fLog << all;
-    *fLog << fObservatoryName << endl;
-    *fLog << "Latitude " << (fLatitude > 0 ? (fLatitude*kRad2Deg) : -(fLatitude*kRad2Deg)) << " deg " << (fLatitude > 0 ? "W" : "E") << endl;
-    *fLog << "Longitude " << (fLongitude > 0 ? (fLongitude*kRad2Deg) : -(fLongitude*kRad2Deg)) <<" deg " << (fLongitude < 0 ? "N" : "S") << endl;
-    *fLog << "Height " << fHeight << "m" << endl;
+    *fLog << underline << fObservatoryName << ":" << endl;
+    *fLog << "Latitude:  " << TMath::Abs(fLatitude*kRad2Deg)  << " deg " << (fLatitude  > 0 ? "W" : "E") << endl;
+    *fLog << "Longitude: " << TMath::Abs(fLongitude*kRad2Deg) << " deg " << (fLongitude < 0 ? "N" : "S") << endl;
+    *fLog << "Height:    " << fHeight << "m" << endl;
 }
 
 // --------------------------------------------------------------------------
 //
-// RotationAngle 
-// 
-// calculates the angle for the rotation of the sky image in the camera;
-// this angle is a function of the local coordinates
+// Get the corresponding rotation angle of the sky coordinate system
+// seen with an Alt/Az telescope.
 //
-//  theta [rad]: polar angle/zenith distance
-//  phi   [rad]: rotation angle/azimuth
-//
-// Return sin/cos component of angle
-//
-// calculate rotation angle alpha of sky image in camera
-// (see TDAS 00-11, eqs. (18) and (20))
+// For more information see MAstro::RotationAngle
 //
 void MObservatory::RotationAngle(Double_t theta, Double_t phi, Double_t &sin, Double_t &cos) const
 {
-    const Double_t sint = TMath::Sin(theta);
-    const Double_t cost = TMath::Cos(theta);
-
-    const Double_t sinl = fSinLatitude*sint;
-    const Double_t cosl = fCosLatitude*cost;
-
-    const Double_t sinp = TMath::Sin(phi);
-    const Double_t cosp = TMath::Cos(phi);
-
-    const Double_t v1 = sint*sinp;
-    const Double_t v2 = cosl - sinl*cosp;
-
-    const Double_t denom = TMath::Sqrt(v1*v1 + v2*v2);
-
-    sin =  fCosLatitude*sinp / denom;
-    cos = (sinl - cosl*cosp) / denom;
+    MAstro::RotationAngle(fSinLatitude, fCosLatitude, theta, phi, sin, cos);
 }
 
 // --------------------------------------------------------------------------
 //
-// RotationAngle 
-// 
-// calculates the angle for the rotation of the sky image in the camera;
-// this angle is a function of the local coordinates
+// Get the corresponding rotation angle of the sky coordinate system
+// seen with an Alt/Az telescope.
 //
-//  theta [rad]: polar angle/zenith distance
-//  phi   [rad]: rotation angle/azimuth
-//
-// Return RotationAngle in rad
-//
-// calculate rotation angle alpha of sky image in camera
-// (see TDAS 00-11, eqs. (18) and (20))
+// For more information see MAstro::RotationAngle
 //
 Double_t MObservatory::RotationAngle(Double_t theta, Double_t phi) const
 {
-    const Double_t sint = TMath::Sin(theta);
-    const Double_t cost = TMath::Cos(theta);
-
-    const Double_t sinp = TMath::Sin(phi);
-    const Double_t cosp = TMath::Cos(phi);
-
-    const Double_t v1 = sint*sinp;
-    const Double_t v2 = fCosLatitude*cost - fSinLatitude*sint*cosp;
-
-    const Double_t denom = TMath::Sqrt(v1*v1 + v2*v2);
-
-    return TMath::ASin((fCosLatitude*sinp) / denom);
+    return MAstro::RotationAngle(fSinLatitude, fCosLatitude, theta, phi);
 }
-
-// --------------------------------------------------------------------------
-//
-// RotationAngle 
-// 
-// calculates the angle for the rotation of the sky image in the camera;
-// this angle is a function of the sky coordinates, the observatory
-// location and the time
-//
-//  ra  [rad]: Right ascension
-//  dec [rad]: Declination
-//
-// Return RotationAngle in rad
-//
-Double_t MObservatory::RotationAngle(Double_t ra, Double_t dec, const MTime &t) const
-{
-    const Double_t alpha = t.GetGmst() + GetElong();
-
-    TVector3 v;
-    v.SetMagThetaPhi(1, TMath::Pi()/2-dec, alpha-ra);
-    v.RotateY(GetPhi()-TMath::Pi()/2);
-
-    return RotationAngle(v.Theta(), v.Phi());
-}
Index: trunk/MagicSoft/Mars/mastro/MObservatory.h
===================================================================
--- trunk/MagicSoft/Mars/mastro/MObservatory.h	(revision 3537)
+++ trunk/MagicSoft/Mars/mastro/MObservatory.h	(revision 3568)
@@ -58,5 +58,4 @@
     void RotationAngle(Double_t theta, Double_t phi, Double_t &sin, Double_t &cos) const;
     Double_t RotationAngle(Double_t theta, Double_t phi) const;
-    Double_t RotationAngle(Double_t ra, Double_t dec, const MTime &t) const;
 
     LocationName_t GetObservatoryKey() const { return fObservatoryKey; }
