Index: trunk/MagicSoft/Mars/Changelog
===================================================================
--- trunk/MagicSoft/Mars/Changelog	(revision 9576)
+++ trunk/MagicSoft/Mars/Changelog	(revision 9578)
@@ -18,4 +18,25 @@
 
                                                  -*-*- END OF LINE -*-*-
+
+ 2010/05/05 Thomas Bretz
+
+   * mastro/MAstro.cc:
+     - fixed AngularDistance (called a non existing function and
+       the compiler didn't complain)
+
+   * mbase/MParContainer.[h,cc]:
+     - added static function Overwrites (previously in MTask)
+
+   * mbase/MStatusDisplay.[h,cc]:
+     - allow writing a MStatusDisplay without writing a MStatusArray
+       (therefore added SeveAsPlainRoot)
+     - improved reading of files just containing canvases and objects
+
+   * mbase/MTask.[h,cc]:
+     - moved code from Overwrites to a static function in MParContainer
+
+   * msimcamera/MSimCalibrationSignal.cc:
+     - changed distribution of signal from Gauss to Poissonian
+
 
  2010/04/22 Thomas Bretz
Index: trunk/MagicSoft/Mars/mastro/MAstro.cc
===================================================================
--- trunk/MagicSoft/Mars/mastro/MAstro.cc	(revision 9576)
+++ trunk/MagicSoft/Mars/mastro/MAstro.cc	(revision 9578)
@@ -376,11 +376,20 @@
 Double_t MAstro::AngularDistance(Double_t theta0, Double_t phi0, Double_t theta1, Double_t phi1)
 {
-    TVector3 v0(1);
-    v0.Rotate(phi0, theta0);
-
-    TVector3 v1(1);
-    v1.Rotate(phi1, theta1);
-
-    return v0.Angle(v1);
+    // v1 = theta0/phi0 --> theta0 / 0
+    // v2 = theta1/phi1 --> theta1 / phi1-phi0
+    // acos(alpha) = v1*v2/|v1||v2|    |v1|*|v2|=1
+    const Double_t sin2 = TMath::Sin(theta0)*TMath::Sin(theta1);
+    const Double_t cos2 = TMath::Cos(theta0)*TMath::Cos(theta1);
+
+    return TMath::ACos(sin2*TMath::Cos(phi1-phi0) + cos2);
+    /*
+     TVector3 v0;
+     v0.SetMagThetaPhi(1, theta0, phi0);
+
+     TVector3 v1;
+     v1.SetMagThetaPhi(1, theta0, phi0);
+
+     return v0.Angle(v1);
+     */
 }
 
Index: trunk/MagicSoft/Mars/mbase/MParContainer.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MParContainer.cc	(revision 9576)
+++ trunk/MagicSoft/Mars/mbase/MParContainer.cc	(revision 9578)
@@ -237,4 +237,44 @@
 // --------------------------------------------------------------------------
 //
+// Check down to base whether the class given in the argument
+// overwrites the function given by name.
+//
+// This function calls itself recursively. If you want to call it,
+// leave out the argument.
+//
+Bool_t MParContainer::Overwrites(const TClass *base, const TObject &obj, const char *name, TClass *cls)
+{
+    if (!cls)
+        cls = obj.IsA();
+
+    //
+    // Check whether we reached the base class MTask
+    //
+    if (cls==base)
+        return kFALSE;
+
+    //
+    // Check whether the class cls overwrites Process
+    //
+    if (cls->GetMethodAny(name))
+        return kTRUE;
+
+    //
+    // If the class itself doesn't overload it check all it's base classes
+    //
+    TBaseClass *basecls=NULL;
+    TIter NextBase(cls->GetListOfBases());
+    while ((basecls=(TBaseClass*)NextBase()))
+    {
+        if (Overwrites(base, obj, name, basecls->GetClassPointer()))
+            return kTRUE;
+    }
+
+    return kFALSE;
+}
+
+
+// --------------------------------------------------------------------------
+//
 //  Return a unique name for this container. It is created from
 //  the container name and the unique Id. (This is mostly used
Index: trunk/MagicSoft/Mars/mbase/MParContainer.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MParContainer.h	(revision 9576)
+++ trunk/MagicSoft/Mars/mbase/MParContainer.h	(revision 9578)
@@ -82,4 +82,6 @@
     static const TString GetDescriptor(const TObject &o);
 
+    static Bool_t Overwrites(const TClass *base, const TObject &obj, const char *name, TClass *cls=NULL);
+
     virtual const TString GetDescriptor() const;
     virtual const TString GetUniqueName() const;
Index: trunk/MagicSoft/Mars/mbase/MStatusDisplay.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MStatusDisplay.cc	(revision 9576)
+++ trunk/MagicSoft/Mars/mbase/MStatusDisplay.cc	(revision 9578)
@@ -278,4 +278,5 @@
     savemenu->AddEntry(MString::Format("%s&C",    fname.Data()), kFileSaveAsC);
     savemenu->AddEntry(MString::Format("%s&root", fname.Data()), kFileSaveAsRoot);
+    savemenu->AddEntry(MString::Format("%s&root (plain)", fname.Data()), kFileSaveAsPlainRoot);
     savemenu->Associate(this);
 
@@ -1723,4 +1724,8 @@
         return kTRUE;
 
+    case kFileSaveAsPlainRoot:
+        SaveAsPlainRoot(kTRUE);
+        return kTRUE;
+
     case kFilePrint:
         PrintPS();
@@ -1777,4 +1782,8 @@
     case kTabSaveAsC:
         SaveAsC(fTab->GetCurrent());
+        return kTRUE;
+
+    case kTabSaveAsPlainRoot:
+        SaveAsPlainRoot(fTab->GetCurrent());
         return kTRUE;
 
@@ -2276,4 +2285,6 @@
     }
 
+    // The first entry in the list is a TNamed which is expected to
+    // contain the status display title.
     fTitle = o->GetTitle();
 
@@ -2312,8 +2323,13 @@
     //
     // If no status display was found with this name try to find canvases
-    // in the file and s´display them instead.
+    // in the file and display them instead.
     //
     if (n==0)
     {
+        // Either read the title from the file or create our own
+        TNamed *n=0;
+        gFile->GetObject("Title", n); // FIXME: Is the list allowed to take ownership?
+        list.Add(n ? n : new TNamed(GetName(), GetTitle()));
+
         const Bool_t store = TH1::AddDirectoryStatus();
         TH1::AddDirectory(kFALSE);
@@ -2325,16 +2341,23 @@
             TCanvas *c=0;
             gFile->GetObject(key->GetName(), c);
+
+            // If key doesn't correspond to a TCanvas create a new canvas
+            // and draw the object itself instead.
             if (!c)
             {
-                AddTab(key->GetName(), key->GetTitle());
                 TObject *obj = gFile->Get(key->GetName());
-                obj->SetBit(kCanDelete);
-                obj->Draw();
+
+                if (MParContainer::Overwrites(TObject::Class(), *obj, "Draw") ||
+                    MParContainer::Overwrites(TObject::Class(), *obj, "Paint"))
+                {
+                    AddTab(key->GetName(), key->GetTitle());
+                    obj->SetBit(kCanDelete);
+                    obj->Draw();
+                }
+                // FIXME: Is the object deleted?
                 continue;
             }
 
-            if (list.GetEntries()==0)
-                list.Add(new TNamed(GetName(), GetTitle()));
-
+            // Add teh canvas to the list
             c->SetTitle(gFile->GetName());
             list.Add(c);
@@ -2343,11 +2366,11 @@
         TH1::AddDirectory(store);
 
-        if (list.GetEntries()==0)
+        if (list.GetEntries()<=1)
         {
-            *fLog << warn << "MStatusDisplay::Read: No objects read from " << gFile->GetName() << endl;
+            *fLog << warn << "MStatusDisplay::Read: No drawable objects read from " << gFile->GetName() << endl;
             return 0;
         }
 
-        *fLog << inf << "MStatusDisplay: " << list.GetEntries() << " canvases directly read from file." << endl;
+        *fLog << inf << "MStatusDisplay: " << list.GetEntries()-1 << " canvases directly read from file." << endl;
     }
 
@@ -2358,5 +2381,4 @@
         return 0;
     }
-
 
     if (n==0)
@@ -2423,16 +2445,34 @@
     }
 
-    MStatusArray list;
-
-    // Be careful: So far Display() assumes that it is the first entry in the list
-    TNamed named;
-    named.SetTitle(fTitle);
-    list.Add(&named);
-
-    FillArray(list, num);
-
-    const Int_t n = list.Write(name, kSingleKey);
-
-    //*fLog << inf << "MStatusDisplay: " << n << " keys written to file as key " << name << "." << endl;
+    Int_t n = 0; // Number of keys written
+
+    TNamed named("Title", fTitle.Data());
+
+    if (TString(option)=="plain")
+    {
+        // Get canvas range to store
+        Int_t from, to;
+        GetCanvasRange(from, to, num);
+
+        n += named.Write();
+
+        TCanvas *c;
+        for (int i=from; i<to; i++)
+            if ((c = GetCanvas(i)))
+                n += c->Write();
+    }
+    else
+    {
+        // Be careful: So far Display() assumes that the TNamed
+        // is the first entry in the list
+        MStatusArray list;
+        list.Add(&named);
+
+        FillArray(list, num);
+
+        n += list.Write(name, kSingleKey);
+    }
+
+    *fLog << inf << "MStatusDisplay: " << n << " keys written to file as key " << name << "." << endl;
 
     return n;
@@ -3029,5 +3069,6 @@
 // --------------------------------------------------------------------------
 //
-// In case of num<0 all tabs are written into the PS file. If num>0
+// In case of num<0 all tabs are written into a root file. As plain
+// TCanvas objects if plain==kTRUE otherwise in a MStatusArray. If num>0
 // the canvas in the corresponding tab is written to the file.
 // Name is the name of the file (with or without extension).
@@ -3035,7 +3076,7 @@
 // Returns the number of keys written.
 //
-// To write all tabs you can also use SaveAsPS(name)
-//
-Int_t MStatusDisplay::SaveAsRoot(Int_t num, TString name)
+// To write all tabs you can also use SaveAsRoot(name)
+//
+Int_t MStatusDisplay::SaveAsRoot(Int_t num, TString name, Bool_t plain)
 {
     num = InitWriteDisplay(num, name, "root");
@@ -3045,5 +3086,5 @@
     TFile *fsave = gFile;
     TFile file(name, "RECREATE", GetTitle(), 9);
-    const Int_t keys = Write(num);
+    const Int_t keys = Write(num, plain ? "plain" : "");
     gFile = fsave;
 
Index: trunk/MagicSoft/Mars/mbase/MStatusDisplay.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MStatusDisplay.h	(revision 9576)
+++ trunk/MagicSoft/Mars/mbase/MStatusDisplay.h	(revision 9578)
@@ -49,5 +49,5 @@
         kFileSaveAsPS, kFileSaveAsPDF, kFileSaveAsSVG, kFileSaveAsRoot,
         kFileSaveAsPNG, kFileSaveAsGIF, kFileSaveAsJPG, kFileSaveAsXPM,
-        kFileSaveAsBMP, kFileSaveAsCSV, kFileSaveAsTIFF,
+        kFileSaveAsBMP, kFileSaveAsCSV, kFileSaveAsTIFF, kFileSaveAsPlainRoot,
         kFileSaveAsXML, kFileSaveAsC, kFilePrint, kFilePrinterName,
         kFileClose, kFileExit, kFileReset,
@@ -58,5 +58,5 @@
         kTabSaveAsRoot, kTabSaveAsPNG, kTabSaveAsGIF, kTabSaveAsJPG,
         kTabSaveAsXPM, kTabSaveAsBMP, kTabSaveAsCSV, kTabSaveAsTIFF,
-        kTabSaveAsXML, kTabSaveAsC,
+        kTabSaveAsXML, kTabSaveAsC, kTabSaveAsPlainRoot,
         kTabPrint, kTabNext, kTabPrevious, kTabRemove,
         // kSize
@@ -253,4 +253,5 @@
      Bool_t SaveAsC(TString name="")    { return SaveAsC(-1, name); }
      Int_t  SaveAsRoot(TString name="") { return SaveAsRoot(-1, name); }
+     Int_t  SaveAsPlainRoot(TString name="") { return SaveAsRoot(-1, name, kTRUE); }
      Int_t  SaveAs(TString name)        { return SaveAs(-1, name); }
 
@@ -271,5 +272,6 @@
      Bool_t SaveAsXML(Int_t num, TString name="")  { return SaveAsImage(num, name, TImage::kXml); }
      Bool_t SaveAsC(Int_t num, TString name="");
-     Int_t  SaveAsRoot(Int_t num, TString name="");
+     Int_t  SaveAsRoot(Int_t num, TString name="", Bool_t plain=kFALSE);
+     Int_t  SaveAsPlainRoot(Int_t num, TString name="") { return SaveAsRoot(num, name, kTRUE); }
      Int_t  SaveAs(Int_t num, TString name);
 
Index: trunk/MagicSoft/Mars/mbase/MTask.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MTask.cc	(revision 9576)
+++ trunk/MagicSoft/Mars/mbase/MTask.cc	(revision 9578)
@@ -505,41 +505,4 @@
 }
 
-// --------------------------------------------------------------------------
-//
-// Check whether the class given in the argument overwrites MTask::Process.
-// This function calls itself recursively. If you want to call it,
-// leave out the argument.
-//
-Bool_t MTask::Overwrites(const char *name, TClass *cls) const
-{
-    if (!cls)
-        cls = IsA();
-
-    //
-    // Check whether we reached the base class MTask
-    //
-    if (cls==MTask::Class())
-        return kFALSE;
-
-    //
-    // Check whether the class cls overwrites Process
-    //
-    if (cls->GetMethodAny(name))
-        return kTRUE;
-
-    //
-    // If the class itself doesn't overload it check all it's base classes
-    //
-    TBaseClass *base=NULL;
-    TIter NextBase(cls->GetListOfBases());
-    while ((base=(TBaseClass*)NextBase()))
-    {
-        if (Overwrites(name, base->GetClassPointer()))
-            return kTRUE;
-    }
-
-    return kFALSE;
-}
-
 void MTask::SetDisplay(MStatusDisplay *d)
 {
Index: trunk/MagicSoft/Mars/mbase/MTask.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MTask.h	(revision 9576)
+++ trunk/MagicSoft/Mars/mbase/MTask.h	(revision 9578)
@@ -79,5 +79,5 @@
 
     const TList *GetListOfBranches() const { return fListOfBranches; }
-    Bool_t Overwrites(const char *name, TClass *cls=NULL) const;
+    Bool_t Overwrites(const char *name, TClass *cls=NULL) const { return MParContainer::Overwrites(MTask::Class(), *this, name, cls); }
 
     // Filter functions
Index: trunk/MagicSoft/Mars/msimcamera/MSimCalibrationSignal.cc
===================================================================
--- trunk/MagicSoft/Mars/msimcamera/MSimCalibrationSignal.cc	(revision 9576)
+++ trunk/MagicSoft/Mars/msimcamera/MSimCalibrationSignal.cc	(revision 9578)
@@ -61,5 +61,4 @@
 
 #include "MGeomCam.h"
-#include "MParSpline.h"
 #include "MTriggerPattern.h"
 
@@ -69,4 +68,6 @@
 #include "MPhotonEvent.h"
 #include "MPhotonData.h"
+
+#include "MParSpline.h"
 
 ClassImp(MSimCalibrationSignal);
@@ -197,5 +198,5 @@
         {
             // FIXME: Scale number of photons with the pixel size!
-            const Int_t num = TMath::Nint(gRandom->Gaus(fNumPhotons, fNumPhotons/10));
+            const Int_t num = gRandom->Poisson(fNumPhotons);
 
             // FIXME: How does the distribution look like? Poissonian?
