Index: /trunk/MagicSoft/Mars/Changelog
===================================================================
--- /trunk/MagicSoft/Mars/Changelog	(revision 1282)
+++ /trunk/MagicSoft/Mars/Changelog	(revision 1283)
@@ -1,3 +1,69 @@
                                                                   -*-*- END -*-*-
+ 2002/04/22: Thomas Bretz
+
+   * Makefile:
+     - added a chapter how to compile mars using shared libraries
+
+   * NEWS:
+     - updated
+ 
+   * mfilter/MF.[h,cc]:
+     - added 
+
+   * mfilter/MFDataMember.[h,cc]:
+     - added 
+
+   * mhist/MH3.[h,cc]:
+     - added 
+
+   * mhist/MHHillasExt.[h,cc]:
+     - added 
+     
+   * macros/rootlogon.C:
+     - added make() function
+     - splitted rootlogon()
+     
+   * mbase/MFilterList.cc:
+     - fixed a bug in the constructor
+     - small changes to the print function
+     
+   * mbase/MParContainer.[h,cc]:
+     - Added GetterMethod-Function
+
+   * mbase/MParList.cc:
+     - Added a security check in case no def. constructor of the new class 
+       is available
+     - changed print function
+     
+   * mbase/MReadTree.cc:
+     - changed so that the class type of the branch is used for creation of 
+       a new object instead of its name
+
+   * mbase/MTaskList.[h,cc]:
+     - fixed the check for the Process function. Only base classes
+       of first order have been checked
+       
+   * mfilter/FilterLinkDef.h, mfilter/Makefile:
+     - added MF, MFDataMember
+
+   * mhist/HistLinkDef.h, mhist/MFillH.cc:
+     - added MH3, MHHillasExt
+
+   * mhist/MFillH.cc:
+     - small changes
+
+   * mhist/MH.[h,cc]:
+     - changed name handling in MakeDefCanvas to TString
+
+   * mhist/MHHillas.cc:
+     - exchanged Get*axis()->SetTitle with Set*Title()
+     
+   * mhist/MHHillas.h:
+     - made SetMm2Deg virtual (for MHHillasExt)
+
+   * mhist/MHStarMap.[h,cc]:
+     - changed layout from mm to deg
+
+
 
  2002/04/19: Thomas Bretz
@@ -52,5 +118,5 @@
    * mmain/MDataCheck.cc:
      - exchanged order in call to MFillH constructor
-     - made eventloop infinity (only 300 events have been processed)
+     - made eventloop infinite (only 300 events have been processed)
 
    * mbase/MEvtLoop.h:
@@ -117,5 +183,5 @@
        of the pixel is saved for all Camera pixels.
      - Old files can still be read but becareful when one looks at the
-       data member fPixelsFirst which is an array of diferent size for
+       data member fPixelsFirst which is an array of different size for
        the new and old files.
      - ClassDef version upgraded to 2.
@@ -179,5 +245,5 @@
      mhist/MHMcDifRate.[h,cc], mhist/MHMcIntRate.[h,cc]:
      - added
-     
+
    * mhist/Makefile, mhist/HistLinkDef.h:
      - added MHMcEfficiencyEnergy and MHMcEfficiencyImpact
Index: /trunk/MagicSoft/Mars/Makefile
===================================================================
--- /trunk/MagicSoft/Mars/Makefile	(revision 1282)
+++ /trunk/MagicSoft/Mars/Makefile	(revision 1283)
@@ -69,4 +69,16 @@
 # Use $(CXX) -v ... for a more verbose output
 #
+#
+#$(MARS_LIB)
+$(SOLIB): $(LIBRARIES) $(OBJS) $(HEADERS) MCint.o
+	@echo " Linking $(SOLIB) ..."
+	$(CXX) -shared $(CXXFLAGS) $(SUBDIRS:=/*.o) $(ROOTGLIBS) -o $@
+	mv mars.so lib
+
+$(PROGRAMS): $(LIBRARIES) $(OBJS) $(HEADERS) MCint.o $(PROGRAMS:=.o) 
+	@echo " Linking $@ ..." 
+	$(CXX) $(CXXFLAGS) $@.o $(OBJS) $(MARS_LIB) MCint.o $(ROOTGLIBS) -o $@
+
+#
 # We could link mars.so instead of all libraries. This would need
 # some MBs less space on the HD. But this means, that the Shared
@@ -74,12 +86,7 @@
 # 'mars'
 #
-$(PROGRAMS): $(LIBRARIES) $(OBJS) $(HEADERS) MCint.o $(PROGRAMS:=.o) 
-	@echo " Linking $@ ..." 
-	$(CXX) $(CXXFLAGS) $@.o $(OBJS) $(MARS_LIB) MCint.o $(ROOTGLIBS) -o $@
-
-$(SOLIB): $(LIBRARIES) $(OBJS) $(HEADERS) MCint.o
-	@echo " Linking $(SOLIB) ..."
-	$(CXX) -shared $(CXXFLAGS) $(SUBDIRS:=/*.o) $(ROOTGLIBS) -o $@
-	mv mars.so lib
+#$(PROGRAMS): $(LIBRARIES) $(OBJS) $(HEADERS) $(SOLIB) MCint.o $(PROGRAMS:=.o) 
+#	@echo " Linking $@ ..." 
+#	$(CXX) $(CXXFLAGS) $@.o $(OBJS) lib/$(SOLIB)  MCint.o $(ROOTGLIBS) -o $@
 
 $(LIBRARIES):
Index: /trunk/MagicSoft/Mars/NEWS
===================================================================
--- /trunk/MagicSoft/Mars/NEWS	(revision 1282)
+++ /trunk/MagicSoft/Mars/NEWS	(revision 1283)
@@ -17,8 +17,10 @@
      hillas parameters)
 
-   - replaced old MHillas by a new structure which allows you to extend
-     the parameters stored in MHillas very easily.
+   - Replaced old MHillas by a new structure which allows you to extend
+     the parameters stored in MHillas very easily:
+     see MHillas and MHillasExt
 
-   - Added classes to handle source dependancy of image parameters.
+   - Added classes to handle source dependancy of image parameters:
+     see MHillasSrc
 
    - Added container (MBinning) to have a standard input for the binning
@@ -30,8 +32,23 @@
    - Added the flexible binning to the hillas histograms
 
-   - Added a filter for the alpha parameter (MFilter)
+   - Added a filter for the alpha parameter (MFAlpha)
 
-   - it is now possible to write single data members of a class object to
+   - It is now possible to write single data members of a class object to
      an output stream instead of the whole container only
+
+   - Added a generalized filter for a data member:
+     MFDataMember filter("MHillas.fWidth", '<', 0.5);
+
+   - Added a generalized Filter parser for more difficult filter rules
+     MF filter("MHillas.fWidth<0.5 && MHillas.fLength>0.5");
+
+   - Added new Monte Carlo histograms:
+     MHMcEnergyImpact and MHMcEfficiency
+
+   - Added many new histograms needed for the flux calculation.
+
+   - Added a generalized histograms which can fill and show up to three
+     data members in either a one-, two- or three-dimensional histogram, eg:
+     MH3 mh3("MHillas.fWidth", "MHillas.fLength");
 
 
Index: /trunk/MagicSoft/Mars/macros/rootlogon.C
===================================================================
--- /trunk/MagicSoft/Mars/macros/rootlogon.C	(revision 1282)
+++ /trunk/MagicSoft/Mars/macros/rootlogon.C	(revision 1283)
@@ -23,8 +23,27 @@
 \* ======================================================================== */
 
+Bool_t isloaded()
+{
+    TString str = gSystem->GetLibraries("*/mars.so");
 
-void rootlogon()
+    return !str.IsNull();
+}
+
+void unload()
 {
-    cout << endl;
+    if (!isloaded())
+        return;
+
+    cout << "Unloading 'mars.so'... " << flush;
+    if (gSystem->Unload("mars.so"))
+        cout << "error." << endl;
+    else
+        cout << "done." << endl << endl;
+}
+
+void load()
+{
+    if (isloaded())
+        return;
 
     cout << "Loading 'mars.so'... " << flush;
@@ -40,4 +59,24 @@
 
     cout << endl;
+}
+
+void make()
+{
+    unload();
+
+    if (gSystem->Exec("make"))
+    {
+        cout << "Error calling make..." << endl;
+        return;
+    }
+
+    load();
+}
+
+void rootlogon()
+{
+    cout << endl;
+
+    load();
 
     cout << "Welcome to the Mars Root environment." << endl;
@@ -45,3 +84,2 @@
     cout << endl;
 }
-
Index: /trunk/MagicSoft/Mars/mbase/MFilterList.cc
===================================================================
--- /trunk/MagicSoft/Mars/mbase/MFilterList.cc	(revision 1282)
+++ /trunk/MagicSoft/Mars/mbase/MFilterList.cc	(revision 1283)
@@ -59,11 +59,11 @@
     TString str(type);
 
-    if (str.CompareTo("OR", TString::kIgnoreCase)  || str.CompareTo("|"))
+    if (!str.CompareTo("OR", TString::kIgnoreCase)  || !str.CompareTo("|"))
         fFilterType = kEOr;
-    if (str.CompareTo("XOR", TString::kIgnoreCase) || str.CompareTo("^"))
+    if (!str.CompareTo("XOR", TString::kIgnoreCase) || !str.CompareTo("^"))
         fFilterType = kEXor;
-    if (str.CompareTo("LAND", TString::kIgnoreCase) || str.CompareTo("&&"))
+    if (!str.CompareTo("LAND", TString::kIgnoreCase) || !str.CompareTo("&&"))
         fFilterType = kELAnd;
-    if (str.CompareTo("LOR", TString::kIgnoreCase) || str.CompareTo("||"))
+    if (!str.CompareTo("LOR", TString::kIgnoreCase) || !str.CompareTo("||"))
         fFilterType = kELOr;
 }
@@ -180,5 +180,9 @@
     while ((filter=(MFilter*)Next()))
         if (!filter->PreProcess(pList))
+        {
+            *fLog << err << "Error - Preprocessing Filter ";
+            *fLog << filter->GetName() << " in " << fName << endl;
             return kFALSE;
+        }
 
     return kTRUE;
@@ -235,4 +239,6 @@
     const Bool_t verbose = str.Contains("V", TString::kIgnoreCase);
 
+    //*fLog << all << "(" << GetName() << "=" << (int)fFilterType << ")";
+
     *fLog << all << "(";
 
@@ -250,32 +256,35 @@
     }
 
-    do
+    filter->Print();
+
+    while ((filter=(MFilter*)Next()))
     {
         switch (fFilterType)
         {
         case kEAnd:
-            *fLog << (verbose?" and ":"&");
+            *fLog << (verbose?" and ":" & ");
             break;
 
         case kEOr:
-            *fLog << (verbose?" or ":"|");
+            *fLog << (verbose?" or ":" | ");
             break;
 
         case kEXor:
-            *fLog << (verbose?" xor ":"^");
+            *fLog << (verbose?" xor ":" ^ ");
             break;
 
         case kELAnd:
-            *fLog << (verbose?" land ":"&&");
+            *fLog << (verbose?" land ":" && ");
             break;
 
         case kELOr:
-            *fLog << (verbose?" lor ":"||");
+            *fLog << (verbose?" lor ":" || ");
             break;
         }
 
         filter->Print();
-    } while ((filter=(MFilter*)Next()));
+    }
 
     *fLog << ")" << flush;
 }
+
Index: /trunk/MagicSoft/Mars/mbase/MParContainer.cc
===================================================================
--- /trunk/MagicSoft/Mars/mbase/MParContainer.cc	(revision 1282)
+++ /trunk/MagicSoft/Mars/mbase/MParContainer.cc	(revision 1283)
@@ -319,2 +319,28 @@
     return rc;
 }
+
+TMethodCall *MParContainer::GetterMethod(const char *name) const
+{
+    TClass *cls = IsA()->GetBaseDataMember(name);
+    if (!cls)
+    {
+        *fLog << err << "No (base) class containing '" << name << "'." << endl;
+        return NULL;
+    }
+
+    TDataMember *member = cls->GetDataMember(name);
+    if (!member)
+    {
+        *fLog << err << "Datamember '" << name << "' not in " << GetDescriptor() << endl;
+        return NULL;
+    }
+
+    TMethodCall *call = member->GetterMethod();
+    if (!call)
+    {
+        *fLog << err << "Sorry, no getter method found for " << name << endl;
+        return NULL;
+    }
+
+    return call;
+}
Index: /trunk/MagicSoft/Mars/mbase/MParContainer.h
===================================================================
--- /trunk/MagicSoft/Mars/mbase/MParContainer.h	(revision 1282)
+++ /trunk/MagicSoft/Mars/mbase/MParContainer.h	(revision 1283)
@@ -24,4 +24,5 @@
 
 class TDataMember;
+class TMethodCall;
 
 class MParContainer : public TObject
@@ -66,4 +67,6 @@
     virtual void   SetReadyToSave(Bool_t flag=kTRUE) { fReadyToSave=flag; }
 
+    TMethodCall *GetterMethod(const char *name) const;
+
     Bool_t WriteDataMember(ostream &out, const char *member, Double_t scale=1) const;
     Bool_t WriteDataMember(ostream &out, const TDataMember *member, Double_t scale=1) const;
Index: /trunk/MagicSoft/Mars/mbase/MParList.cc
===================================================================
--- /trunk/MagicSoft/Mars/mbase/MParList.cc	(revision 1282)
+++ /trunk/MagicSoft/Mars/mbase/MParList.cc	(revision 1283)
@@ -380,5 +380,4 @@
     //
     TClass *cls = gROOT->GetClass(cname);
-
     if (!cls)
     {
@@ -394,4 +393,9 @@
     //
     pcont = (MParContainer*)cls->New();
+    if (!pcont)
+    {
+        *fLog << err << dbginf << "Cannot create new instance of class '" << cname << "' (Maybe no def. constructor)" << endl;
+        return NULL;
+    }
 
     //
@@ -424,5 +428,5 @@
 void MParList::Print(Option_t *t) const
 {
-    *fLog << all << GetDescriptor() << endl;
+    *fLog << all << " " << GetDescriptor() << endl;
     *fLog << setfill('-') << setw(strlen(GetDescriptor())+2) << "" << endl;
     MParContainer *obj = NULL;
@@ -572,5 +576,4 @@
     //
     TClass *cls = gROOT->GetClass(cname);
-
     if (!cls)
     {
@@ -602,4 +605,9 @@
         //
         MParContainer *pcont = (MParContainer*)cls->New();
+        if (pcont)
+        {
+            gLog << err << dbginf << "Cannot create new instance of class '" << cname << "' (Maybe no def. constructor)" << endl;
+            return list;
+        }
 
         //
Index: /trunk/MagicSoft/Mars/mbase/MReadTree.cc
===================================================================
--- /trunk/MagicSoft/Mars/mbase/MReadTree.cc	(revision 1282)
+++ /trunk/MagicSoft/Mars/mbase/MReadTree.cc	(revision 1283)
@@ -458,5 +458,5 @@
         // check if object is existing in the list
         //
-        *pcont=pList->FindCreateObj(oname);
+        *pcont=pList->FindCreateObj(branch->GetClassName(), oname);
 
         if (!*pcont)
@@ -466,5 +466,6 @@
             // we cannot proceed reading this branch
             //
-            *fLog << warn << dbginf << "Warning: Class '" << oname << "' not existing in dictionary. Branch skipped." << endl;
+            *fLog << warn << dbginf << "Warning: Class '" << branch->GetClassName();
+            *fLog << "' for " << oname << " not existing in dictionary. Branch skipped." << endl;
             DisableSubBranches(branch);
             continue;
@@ -484,5 +485,7 @@
         //
         fChain->SetBranchAddress(bname, pcont);
-        *fLog << inf << "Master branch address " << bname << " setup for reading." << endl;
+
+        *fLog << inf << "Master branch address " << bname << " [";
+        *fLog << branch->GetClassName() << "] setup for reading." << endl;
 
         //*fLog << "Branch " << bname << " autodel: " << (int)branch->IsAutoDelete() << endl;
@@ -568,5 +571,4 @@
 //
 #if ROOT_VERSION_CODE < ROOT_VERSION(3,02,06)
-//#include "../mraw/MRawEvtData.h"
 #include "MRawEvtData.h"
 #endif
Index: /trunk/MagicSoft/Mars/mbase/MTaskList.cc
===================================================================
--- /trunk/MagicSoft/Mars/mbase/MTaskList.cc	(revision 1282)
+++ /trunk/MagicSoft/Mars/mbase/MTaskList.cc	(revision 1283)
@@ -58,4 +58,5 @@
 
 #include <TClass.h>
+#include <TBaseClass.h>
 #include <TOrdCollection.h>
 
@@ -259,8 +260,39 @@
 // --------------------------------------------------------------------------
 //
+// Check whether this task (or one of it's base classes) overloads
+// MTask::Process. Only if this function is overloaded this task is
+// added to the fTaskProcess-List. This makes the execution of the
+// tasklist a little bit (only a little bit) faster, bacause tasks
+// doing no Processing are not Processed.
+//
+Bool_t MTaskList::CheckClassForProcess(TClass *cls)
+{
+    //
+    // Check whether the class itself overloads the Process function
+    //
+    if (cls->GetName()=="MTask")
+        return kFALSE;
+
+    if (cls->GetMethodAny("Process"))
+        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 (CheckClassForProcess(base->GetClassPointer()))
+            return kTRUE;
+    }
+
+    return kFALSE;
+}
+
+// --------------------------------------------------------------------------
+//
 //  do pre processing (before eventloop) of all tasks in the task-list
 //
-#include <TMethod.h>
-#include <TBaseClass.h>
 Bool_t MTaskList::PreProcess(MParList *pList)
 { 
@@ -283,26 +315,6 @@
     while ((task=(MTask*)Next()))
     {
-        *fLog << all << task->GetName() << "... " << flush;
-
-        //
-        // Check whether this task (or one of it's base classes) overloads
-        // MTask::Process. Only if this function is overloaded this task is
-        // added to the fTaskProcess-List. This makes the execution of the
-        // tasklist a little bit (only a little bit) faster, bacause tasks
-        // doing no Processing are not Processed.
-        //
-        TBaseClass *cls=NULL;
-        TIter NextBase(task->IsA()->GetListOfBases());
-        while ((cls=(TBaseClass*)NextBase()))
-        {
-            if (cls->GetName()=="MTask")
-                break;
-
-            if (!cls->GetClassPointer()->GetMethodAny("Process"))
-                continue;
-
+        if (CheckClassForProcess(task->IsA()))
             fTasksProcess.Add(task);
-            break;
-        }
 
         //
Index: /trunk/MagicSoft/Mars/mbase/MTaskList.h
===================================================================
--- /trunk/MagicSoft/Mars/mbase/MTaskList.h	(revision 1282)
+++ /trunk/MagicSoft/Mars/mbase/MTaskList.h	(revision 1283)
@@ -30,5 +30,6 @@
     enum { kIsOwner = BIT(14) };
 
-    void Remove(MTask *task);
+    void   Remove(MTask *task);
+    Bool_t CheckClassForProcess(TClass *cls);
 
 public:
Index: /trunk/MagicSoft/Mars/mfilter/FilterLinkDef.h
===================================================================
--- /trunk/MagicSoft/Mars/mfilter/FilterLinkDef.h	(revision 1282)
+++ /trunk/MagicSoft/Mars/mfilter/FilterLinkDef.h	(revision 1283)
@@ -5,6 +5,8 @@
 #pragma link off all functions;
 
+#pragma link C++ class MF+;
 #pragma link C++ class MFAlpha+;
 #pragma link C++ class MFTriggerLvl1+;
+#pragma link C++ class MFDataMember+;
 
 #endif
Index: /trunk/MagicSoft/Mars/mfilter/MF.cc
===================================================================
--- /trunk/MagicSoft/Mars/mfilter/MF.cc	(revision 1283)
+++ /trunk/MagicSoft/Mars/mfilter/MF.cc	(revision 1283)
@@ -0,0 +1,369 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz  01/2002 <mailto:tbretz@uni-sw.gwdg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MF                                                              
+//
+// With this filter you can filter in all variables from Mars parameter
+// containers.
+//
+// In the constructor you can give the filter rule, like
+//   "MHillas.fLength < 15"
+// Where MHillas is the name of the parameter container in the parameter
+// list and fLength is the name of the data member which should be used
+// for the filter rule. If the name of the container is use specified
+// (MyHillas) the name to give would be:
+//   "MyHillas.fLength < 15"
+//
+// Also more difficult rules are allowed, like:
+//   "MHillas.fWidth<0.5 && MHillas.fLength<0.6"
+//
+// You can also use brackets:
+//   "MHillas.fSize>200 || (MHillas.fWidth<0.5 && MHillas.fLength<0.6)"
+//
+// The allowed logigal conditionals are:
+//   &&: logical and
+//   ||: logical or
+//   ^:  exclusive or
+//
+// As conditional signs, for now, only:
+//   <, >
+// are allowed.
+//
+// Warning: There is no priority rule build in. So better use brackets
+//   to get correct results. The rule is parsed/evaluated from the left
+//   to the right, which means:
+//
+//   "MHillas.fSize>200 || MHillas.fWidth<0.5 && MHillas.fLength<0.6"
+//
+//    is parses as
+//
+//   "(MHillas.fSize>200 || MHillas.fWidth<0.5) && MHillas.fLength<0.6"
+//
+//
+// FIXME: The possibility to use also complete filters is missing.
+//        Maybe we can use gInterpreter->Calc("") for this.
+//        gROOT->ProcessLineFast("line");
+//
+/////////////////////////////////////////////////////////////////////////////
+#include "MF.h"
+
+#include <stdlib.h>       // strtod, ...
+#include <ctype.h>        // isalnum, ...
+
+#include <TMethodCall.h>
+
+#include "MParList.h"
+
+#include "MFilterList.h"
+#include "MFDataMember.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+ClassImp(MF);
+
+// --------------------------------------------------------------------------
+//
+// Constructor. For the text describing the filter rule please see
+// the class description above.
+//
+MF::MF(const char *text, const char *name, const char *title)
+{
+    fName  = name  ? name  : "MF";
+    fTitle = title ? title : "Filter using a text";
+
+    *fLog << inf << "Trying to resolve filter rule..." << endl;
+    if (!(fFilter=ParseString(text, 1)))
+    {
+        *fLog << err << dbginf << "Parsing '" << text << "' failed." << endl;
+        return;
+    }
+
+    *fLog << inf << endl;
+    *fLog << "Using Filter rule " << fFilter->GetName();
+    *fLog << " for " << fName << ":" << endl;
+    fFilter->Print();
+    *fLog << endl << endl;
+}
+
+// --------------------------------------------------------------------------
+//
+// Destructor. Delete filters.
+//
+MF::~MF()
+{
+    if (fFilter)
+        delete fFilter;
+}
+
+// --------------------------------------------------------------------------
+//
+// Returns the number of alphanumeric characters (including '.')
+// in the given string
+//
+Int_t MF::IsAlNum(TString txt)
+{
+    int l = txt.Length();
+    for (int i = 0; i<l; i++)
+        if (!isalnum(txt[i]) && txt[i]!='.')
+            return i;
+
+    return l;
+}
+
+// --------------------------------------------------------------------------
+//
+// Parse a text string. Returns a corresponding filter of filter list.
+//
+MFilter *MF::ParseString(TString txt, Int_t level)
+{
+    MFilter *filter0=NULL;
+
+    TString type;
+    int nlist = 0;
+
+    while (!txt.IsNull())
+    {
+        MFilter *newfilter = NULL;
+
+        txt = txt.Strip(TString::kBoth);
+
+        //*fLog << all << setw(level) << " " << "Text: " << level << " '" << txt << "'" << endl;
+
+        switch (txt[0])
+        {
+        case '(':
+            {
+                //
+                // Search for the corresponding bracket
+                //
+                Int_t first=1;
+                for (int cnt=0; first<txt.Length(); first++)
+                {
+                    if (txt[first]=='(')
+                        cnt++;
+                    if (txt[first]==')')
+                        cnt--;
+
+                    if (cnt==-1)
+                        break;
+                }
+
+                if (first==txt.Length())
+                {
+                    *fLog << err << dbginf << "Syntax Error: ')' missing." << endl;
+                    if (filter0)
+                        delete filter0;
+                    return NULL;
+                }
+
+                //
+                // Make a copy of the 'interieur' and delete the substringä
+                // including the brackets
+                //
+                TString sub = txt(1, first-1);
+                txt.Remove(0, first+1);
+
+                //
+                // Parse the substring
+                //
+                newfilter = ParseString(sub, level+1);
+                if (!newfilter)
+                {
+                    *fLog << err << dbginf << "Parsing '" << sub << "' failed." << endl;
+                    if (filter0)
+                        delete filter0;
+                    return NULL;
+                }
+            }
+            break;
+
+        case ')':
+            *fLog << err << dbginf << "Syntax Error: Too many ')'" << endl;
+            if (filter0)
+                delete filter0;
+            return NULL;
+
+        case '&':
+        case '|':
+        case '^':
+            if (filter0)
+            {
+                //
+                // Check for the type of the conditional
+                //
+                TString is = txt[0];
+                txt.Remove(0, 1);
+
+                if (is==txt[0] && is!='^')
+                {
+                    is += txt[0];
+                    txt.Remove(0, 1);
+                }
+
+                //
+                // If no filter is available or the available filter
+                // is of a different conditional we have to create a new
+                // filter list with the new conditional
+                //
+                if (!filter0->InheritsFrom(MFilterList::Class()) || type!=is)
+                {
+                    MFilterList *list = new MFilterList(is);
+                    list->SetName(Form("List_%s_%d", (const char*)is, 10*level+nlist++));
+
+                    list->SetOwner();
+                    list->AddToList(filter0);
+                    filter0 = list;
+
+                    type = is;
+                }
+                continue;
+            }
+
+            *fLog << err << dbginf << "Syntax Error: First argument of condition missing." << endl;
+            if (filter0)
+                delete filter0;
+            return NULL;
+
+        default:
+            int i = IsAlNum(txt);
+
+            if (i==0)
+            {
+                *fLog << err << dbginf << "Syntax Error: Name of data member missing in '" << txt << "'" << endl;
+                if (filter0)
+                    delete filter0;
+                return NULL;
+            }
+
+            TString text = txt(0, i);
+
+            txt.Remove(0, i);
+            txt = txt.Strip(TString::kBoth);
+
+            if (txt.IsNull())
+            {
+                *fLog << err << dbginf << "Syntax Error: No conditional in '" << text << "'" << endl;
+                if (filter0)
+                    delete filter0;
+                return NULL;
+            }
+
+            char c;
+            switch (txt[0])
+            {
+            case '>':
+            case '<':
+                c = txt[0];
+                txt.Remove(0, 1);
+                break;
+
+            default:
+                *fLog << err << dbginf << "Syntax Error: Conditional '" << txt[0] << "' unknown." << endl;
+                if (filter0)
+                    delete filter0;
+                return NULL;
+            }
+
+            char *end;
+            Double_t num = strtod(txt.Data(), &end);
+            if (!end || txt.Data()==end)
+            {
+                *fLog << err << dbginf << "Error trying to convert '" << txt << "' to value." << endl;
+                if (filter0)
+                    delete filter0;
+                return NULL;
+            }
+
+            txt.Remove(0, end-txt.Data());
+
+            newfilter = new MFDataMember(text.Data(), c, num);
+            newfilter->SetName(Form("%s%c%f", text.Data(), c, num));
+        }
+
+        if (!filter0)
+        {
+            filter0 = newfilter;
+            continue;
+        }
+
+        if (!filter0->InheritsFrom(MFilterList::Class()))
+            continue;
+
+        ((MFilterList*)filter0)->AddToList(newfilter);
+    }
+
+    return filter0;
+}
+
+// --------------------------------------------------------------------------
+//
+// PreProcess all filters.
+//
+Bool_t MF::PreProcess(MParList *plist)
+{
+    if (!fFilter)
+    {
+        *fLog << err << dbginf << "No filter rule available." << endl;
+        return kFALSE;
+    }
+
+    if (!fFilter->PreProcess(plist))
+    {
+        *fLog << err << dbginf << "PreProcessing filters in ";
+        *fLog << fName << " failed." << endl;
+        return kFALSE;
+    }
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Process all filters.
+//
+Bool_t MF::Process()
+{
+    return fFilter->Process();
+}
+
+// --------------------------------------------------------------------------
+//
+//  Postprocess all filters.
+//
+Bool_t MF::PostProcess()
+{
+    return fFilter->PostProcess();
+}
+
+// --------------------------------------------------------------------------
+//
+// Return the result of the filter rule.
+//
+Bool_t MF::IsExpressionTrue() const
+{
+    return fFilter->IsExpressionTrue();
+}
Index: /trunk/MagicSoft/Mars/mfilter/MF.h
===================================================================
--- /trunk/MagicSoft/Mars/mfilter/MF.h	(revision 1283)
+++ /trunk/MagicSoft/Mars/mfilter/MF.h	(revision 1283)
@@ -0,0 +1,39 @@
+#ifndef MARS_MF
+#define MARS_MF
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// MF                                                                      //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef MARS_MFilter
+#include "MFilter.h"
+#endif
+
+class MParList;
+class TMethodCall;
+
+class MF : public MFilter
+{
+private:
+    MFilter *fFilter; // Filter
+
+    Int_t IsAlNum(TString txt);
+
+    MFilter *ParseString(TString txt, Int_t level);
+
+public:
+    MF(const char *text, const char *name=NULL, const char *title=NULL);
+    ~MF();
+
+    Bool_t IsExpressionTrue() const;
+
+    Bool_t PreProcess(MParList *pList);
+    Bool_t Process();
+    Bool_t PostProcess();
+
+    ClassDef(MF, 0) // A Filter for cuts in any data member
+};
+
+#endif
Index: /trunk/MagicSoft/Mars/mfilter/MFDataMember.cc
===================================================================
--- /trunk/MagicSoft/Mars/mfilter/MFDataMember.cc	(revision 1283)
+++ /trunk/MagicSoft/Mars/mfilter/MFDataMember.cc	(revision 1283)
@@ -0,0 +1,145 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz  01/2002 <mailto:tbretz@uni-sw.gwdg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MFDataMember                                                              
+//
+// With this filter you can filter in all variables from Mars parameter
+// containers.
+//
+// In the constructor you can give the filter variable, like
+//   "MHillas.fLength"
+// Where MHillas is the name of the parameter container in the parameter
+// list and fLength is the name of the data member which should be used
+// for the filter rule. If the name of the container is use specified
+// (MyHillas) the name to give would be:
+//   "MyHillas.fLength"
+//
+// For example:
+//   MFDataMember filter("MHillas.fLength", '<', 150);
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "MFDataMember.h"
+
+#include <TMethodCall.h>
+
+#include "MParList.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+ClassImp(MFDataMember);
+
+// --------------------------------------------------------------------------
+//
+MFDataMember::MFDataMember(const char *member, const char type, const Double_t val,
+                           const char *name, const char *title)
+{
+    fName  = name  ? name  : "MFDataMember";
+    fTitle = title ? title : "Filter using any data member of a class";
+
+    fFilterType = (type=='<' ? kELowerThan : kEGreaterThan);
+
+    if (type!='<' && type!='>')
+        *fLog << warn << dbginf << "Warning: Neither '<' nor '>' specified... using '>'." << endl;
+
+    fValue = val;
+
+    fDataMember = member;
+
+    AddToBranchList(fDataMember);
+}
+
+// --------------------------------------------------------------------------
+//
+Bool_t MFDataMember::PreProcess(MParList *plist)
+{
+    TString cname(fDataMember);
+    TString mname(fDataMember);
+
+    const char *dot = strrchr(cname, '.');
+
+    if (dot)
+    {
+        const int pos = dot-cname;
+
+        cname.Remove(pos);
+        mname.Remove(0, pos+1);
+    }
+
+    fObject = (MParContainer*)plist->FindObject(cname);
+    if (!fObject)
+    {
+        *fLog << err << "Object '" << cname << "' not in parameter list... aborting." << endl;
+        return kFALSE;
+    }
+
+    fMethodCall = fObject->GetterMethod(mname);
+
+    return fMethodCall ? kTRUE : kFALSE;
+}
+
+// --------------------------------------------------------------------------
+//
+Bool_t MFDataMember::Process()
+{
+    Double_t v;
+    switch (fMethodCall->ReturnType())
+    {
+    case TMethodCall::kLong:
+        Long_t l;
+        fMethodCall->Execute(fObject, l);
+        v = l;
+        return kTRUE;
+
+    case TMethodCall::kDouble:
+        fMethodCall->Execute(fObject, v);
+        return kTRUE;
+
+    default:
+        *fLog << err << "DataMember " << fDataMember << " of ";
+        *fLog << fObject->GetName() << " neither int nor float... abort." << endl;
+        return kFALSE;
+    }
+
+    switch (fFilterType)
+    {
+    case kELowerThan:
+        fResult = (v < fValue);
+        break;
+    case kEGreaterThan:
+        fResult = (v > fValue);
+        break;
+    }
+
+    return kTRUE;
+}
+
+void MFDataMember::Print(Option_t *) const
+{
+    *fLog << fDataMember << (fFilterType==kELowerThan?"<":">");
+    *fLog << fValue << flush;
+}
Index: /trunk/MagicSoft/Mars/mfilter/MFDataMember.h
===================================================================
--- /trunk/MagicSoft/Mars/mfilter/MFDataMember.h	(revision 1283)
+++ /trunk/MagicSoft/Mars/mfilter/MFDataMember.h	(revision 1283)
@@ -0,0 +1,47 @@
+#ifndef MARS_MFDataMember
+#define MARS_MFDataMember
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// MFDataMember                                                                 //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef MARS_MFilter
+#include "MFilter.h"
+#endif
+
+class MParList;
+class TMethodCall;
+
+class MFDataMember : public MFilter
+{
+private:
+    TString        fDataMember; // Data member which should be used for the filter
+
+    MParContainer *fObject;     // Object from which the value is retrieved
+    TMethodCall   *fMethodCall; // Method call to the getter method of the requested value
+
+    typedef enum { kELowerThan, kEGreaterThan } FilterType_t;
+    FilterType_t fFilterType;
+
+    Bool_t  fResult;
+    Double_t fValue;
+
+    void Init(const char type, const Int_t val,
+              const char *name, const char *title);
+
+public:
+    MFDataMember(const char *member, const char type, const Double_t deg,
+                 const char *name=NULL, const char *title=NULL);
+
+    Bool_t IsExpressionTrue() const { return fResult; }
+    Bool_t PreProcess(MParList *pList);
+    Bool_t Process();
+
+    void Print(Option_t *opt = "") const;
+
+    ClassDef(MFDataMember, 0) // A Filter for cuts in any data member
+};
+
+#endif
Index: /trunk/MagicSoft/Mars/mfilter/Makefile
===================================================================
--- /trunk/MagicSoft/Mars/mfilter/Makefile	(revision 1282)
+++ /trunk/MagicSoft/Mars/mfilter/Makefile	(revision 1283)
@@ -32,4 +32,6 @@
 
 SRCFILES = MFTriggerLvl1.cc \
+	   MF.cc \
+	   MFDataMember.cc \
 	   MFAlpha.cc
 
Index: /trunk/MagicSoft/Mars/mhist/HistLinkDef.h
===================================================================
--- /trunk/MagicSoft/Mars/mhist/HistLinkDef.h	(revision 1282)
+++ /trunk/MagicSoft/Mars/mhist/HistLinkDef.h	(revision 1283)
@@ -8,8 +8,10 @@
 
 #pragma link C++ class MH+;
+#pragma link C++ class MH3+;
 #pragma link C++ class MHFadcCam+;
 #pragma link C++ class MHFadcPix+;
 #pragma link C++ class MHHillas+;
 #pragma link C++ class MHHillasSrc+;
+#pragma link C++ class MHHillasExt+;
 #pragma link C++ class MHStarMap+;
 #pragma link C++ class MHEnergyTime+;
Index: /trunk/MagicSoft/Mars/mhist/MFillH.cc
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MFillH.cc	(revision 1282)
+++ /trunk/MagicSoft/Mars/mhist/MFillH.cc	(revision 1283)
@@ -238,5 +238,11 @@
         const TString name = ExtractName(fHName);
 
-        TObject *obj = pList->FindCreateObj(cls, name);
+        TObject *obj=NULL;
+        if (cls==name)
+            obj = pList->FindObject(fHName);
+
+        if (!obj)
+            obj = pList->FindCreateObj(cls, name);
+
         if (!obj)
             return kFALSE;
@@ -277,9 +283,15 @@
     // list. If it could not be found we cannot proceed.
     //
+    if (fParContainerName.IsNull())
+    {
+        fParContainer = pList;
+        return kTRUE;
+    }
+
     fParContainer = (MParContainer*)pList->FindObject(fParContainerName);
     if (fParContainer)
         return kTRUE;
 
-    *fLog << err << dbginf << fParContainerName << " [MParContainer] not found... aborting." << endl;
+    *fLog << err << dbginf << "'" << fParContainerName << "' [MParContainer] not found... aborting." << endl;
     return kFALSE;
 }
Index: /trunk/MagicSoft/Mars/mhist/MH.cc
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MH.cc	(revision 1282)
+++ /trunk/MagicSoft/Mars/mhist/MH.cc	(revision 1283)
@@ -66,6 +66,6 @@
     //   set the name and title of this object
     //
-    fName  = name  ? name  : "MH" ;
-    fTitle = title ? title : "Base class for Mars histograms" ;
+    fName  = name  ? name  : "MH";
+    fTitle = title ? title : "Base class for Mars histograms";
 }
 
@@ -83,22 +83,16 @@
 // number of all existing canvases plus one)
 //
-TCanvas *MH::MakeDefCanvas(const char *name, const char *title,
+TCanvas *MH::MakeDefCanvas(TString name, const char *title,
                            const UInt_t w, const UInt_t h)
 {
     const TList *list = (TList*)gROOT->GetListOfCanvases();
 
-    const char *def = name ? name : gROOT->GetDefCanvasName();
-
-    TCanvas *c;
-    if (list->FindObject(def))
-    {
-        const char *n = StrDup(Form("%s <%d>", def, list->GetSize()+1));
-        c = new TCanvas(n, title, w, h);
-        delete [] n;
-    }
-    else
-        c = new TCanvas(def, title, w, h);
-
-    return c;
+    if (name.IsNull())
+        name = gROOT->GetDefCanvasName();
+
+    if (list->FindObject(name))
+        name += Form(" <%d>", list->GetSize()+1);
+
+    return new TCanvas(name, title, w, h);
 }
 
Index: /trunk/MagicSoft/Mars/mhist/MH.h
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MH.h	(revision 1282)
+++ /trunk/MagicSoft/Mars/mhist/MH.h	(revision 1283)
@@ -22,5 +22,5 @@
     virtual Bool_t Fill(const MParContainer *par) = 0;
 
-    static TCanvas *MakeDefCanvas(const char *name=NULL, const char *title="",
+    static TCanvas *MakeDefCanvas(TString name="", const char *title="",
                                   const UInt_t w=700, const UInt_t h=500);
     static TCanvas *MakeDefCanvas(const TObject *obj,
Index: /trunk/MagicSoft/Mars/mhist/MH3.cc
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MH3.cc	(revision 1283)
+++ /trunk/MagicSoft/Mars/mhist/MH3.cc	(revision 1283)
@@ -0,0 +1,384 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz  2002 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MH3
+//
+// With this histogram you can fill a histogram with up to three
+// variables from Mars parameter containers in an eventloop.
+//
+// In the constructor you can give up to three variables which should be
+// filled in the histogram. Dependend on the number of given variables
+// (data members) a TH1F, TH2F or TH3F is created.
+// Specify the data mamber like the following:
+//   "MHillas.fLength"
+// Where MHillas is the name of the parameter container in the parameter
+// list and fLength is the name of the data member which should be filled
+// in the histogram. Assuming that your MHillas container has a different
+// name (MyHillas) the name to give would be:
+//   "MyHillas.fLength"
+//
+// The axis binning is retrieved from the parameter list, too. Create a
+// MBinning with the name "Binning" plus the name of your MH3 container
+// plus the axis name ("X", "Y" or "Z") and add it to the parameter list.
+//
+// If you want to use a different unit for histogramming use SetScaleX,
+// SetScaleY and SetScaleZ.
+//
+// For example:
+//   MH3 myhist("MHillas.fLength");
+//   myhist.SetName("MyHist");
+//   myhist.SetScaleX(geomcam.GetConvMm2Deg()); //convert length to degree
+//   MBinning bins("BinningMyHistX");
+//   bins.SetEdges(10, 0, 150);
+//   plist.AddToList(&myhist);
+//   plist.AddToList(&bins);
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "MH3.h"
+
+#include <TH2.h>
+#include <TH3.h>
+#include <TPad.h>
+#include <TCanvas.h>
+#include <TDataMember.h>
+#include <TMethodCall.h>
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+
+ClassImp(MH3);
+
+// --------------------------------------------------------------------------
+//
+// Creates an TH1F. memberx is filled into the X-bins. For a more detailed
+// description see the class description above.
+//
+MH3::MH3(const char *memberx) : fDimension(1)
+{
+    fHist = new TH1F;
+
+    fDataMember[0] = memberx;
+
+    fName  = "MH3";
+    fTitle = "Container for a 1D Mars Histogram";
+
+    fHist->SetDirectory(NULL);
+    fHist->SetYTitle("Counts");
+
+    fScale[0] = 1;
+    fScale[1] = 1;
+    fScale[2] = 1;
+}
+
+// --------------------------------------------------------------------------
+//
+// Creates an TH2F. memberx is filled into the X-bins. membery is filled
+// into the Y-bins. For a more detailed description see the class
+// description above.
+//
+MH3::MH3(const char *memberx, const char *membery) : fDimension(2)
+{
+    fHist = new TH2F;
+
+    fDataMember[0] = memberx;
+    fDataMember[1] = membery;
+
+    fName  = "MH3";
+    fTitle = "Container for a 2D Mars Histogram";
+
+    fHist->SetDirectory(NULL);
+    fHist->SetZTitle("Counts");
+
+    fScale[0] = 1;
+    fScale[1] = 1;
+    fScale[2] = 1;
+}
+
+// --------------------------------------------------------------------------
+//
+// Creates an TH3F. memberx is filled into the X-bins. membery is filled
+// into the Y-bins. membery is filled into the Z-bins. For a more detailed
+// description see the class description above.
+//
+MH3::MH3(const char *memberx, const char *membery, const char *memberz) : fDimension(3)
+{
+    fHist = new TH3F;
+
+    fDataMember[0] = memberx;
+    fDataMember[1] = membery;
+    fDataMember[2] = memberz;
+
+    fName  = "MH3";
+    fTitle = "Container for a 3D Mars Histogram";
+
+    fScale[0] = 1;
+    fScale[1] = 1;
+    fScale[2] = 1;
+}
+
+// --------------------------------------------------------------------------
+//
+// Deletes the histogram
+//
+MH3::~MH3()
+{
+    delete fHist;
+}
+
+// --------------------------------------------------------------------------
+//
+// Trys to determin the TMethodCall corresponding to the num-axis
+// corresponding data member.
+//
+Bool_t MH3::GetMethodCall(const MParList *plist, Int_t num)
+{
+    TString cname(fDataMember[num]);
+    TString mname(fDataMember[num]);
+
+    const char *dot = strrchr(cname, '.');
+
+    if (dot)
+    {
+        const int pos = dot-cname;
+
+        cname.Remove(pos);
+        mname.Remove(0, pos+1);
+    }
+
+    fObject[num] = (MParContainer*)plist->FindObject(cname);
+    if (!fObject[num])
+    {
+        *fLog << err << "Object '" << cname << "' not in parameter list... aborting." << endl;
+        return kFALSE;
+    }
+
+    fMethodCall[num] = fObject[num]->GetterMethod(mname);
+
+    return fMethodCall[num] ? kTRUE : kFALSE;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Setup the Binning for the histograms automatically if the correct
+// instances of MBinning are found in the parameter list
+// For a more detailed description see class description above.
+//
+Bool_t MH3::SetupFill(const MParList *plist)
+{
+    TString bname("Binning");
+    bname += fName;
+
+    MBinning *binsx = NULL;
+    MBinning *binsy = NULL;
+    MBinning *binsz = NULL;
+    switch (fDimension)
+    {
+    case 3:
+        binsz = (MBinning*)plist->FindObject(bname+"Z");
+        if (!binsz)
+        {
+            *fLog << err << dbginf << "MBinning '" << bname << "X' not found... aborting." << endl;
+            return kFALSE;
+        }
+        fHist->SetZTitle(fName+"Z");
+        if (!GetMethodCall(plist, 2))
+            return kFALSE;
+    case 2:
+        binsy = (MBinning*)plist->FindObject(bname+"Y");
+        if (!binsy)
+        {
+            *fLog << err << dbginf << "MBinning '" << bname << "Y' not found... aborting." << endl;
+            return kFALSE;
+        }
+        fHist->SetYTitle(fName+"Y");
+        if (!GetMethodCall(plist, 1))
+            return kFALSE;
+    case 1:
+        binsx = (MBinning*)plist->FindObject(bname+"X");
+        if (!binsx)
+        {
+            *fLog << err << dbginf << "MBinning '" << bname << "X' not found... aborting." << endl;
+            return kFALSE;
+        }
+        fHist->SetXTitle(fName+"X");
+        if (!GetMethodCall(plist, 0))
+            return kFALSE;
+    }
+
+    fHist->SetName(fName);
+
+    TString title("Histogram for ");
+    title += fName;
+
+    switch (fDimension)
+    {
+    case 1:
+        fHist->SetTitle(title+" (1D)");
+        SetBinning(fHist, binsx);
+        return kTRUE;
+    case 2:
+        fHist->SetTitle(title+" (2D)");
+        SetBinning(fHist, binsx, binsy);
+        return kTRUE;
+    case 3:
+        fHist->SetTitle(title+" (3D)");
+        SetBinning(fHist, binsx, binsy, binsz);
+        return kTRUE;
+    }
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Set the name of the histogram ant the MH3 container
+//
+void MH3::SetName(const char *name)
+{
+    fHist->SetName(name);
+    MParContainer::SetName(name);
+}
+
+// --------------------------------------------------------------------------
+//
+// Set the title of the histogram ant the MH3 container
+//
+void MH3::SetTitle(const char *title)
+{
+    fHist->SetTitle(title);
+    MParContainer::SetTitle(title);
+}
+
+// --------------------------------------------------------------------------
+//
+// Returns the value corresponding to the data member of the given object
+//
+Bool_t MH3::GetValue(Int_t num, Double_t &v)
+{
+    switch (fMethodCall[num]->ReturnType())
+    {
+    case TMethodCall::kLong:
+        Long_t l;
+        fMethodCall[num]->Execute(fObject[num], l); // FIXME: const, root
+        v = fScale[num]*l;
+        return kTRUE;
+
+    case TMethodCall::kDouble:
+        fMethodCall[num]->Execute(fObject[num], v); // FIXME: const, root
+        v *= fScale[num];
+        return kTRUE;
+
+    default:
+        *fLog << err << "DataMember "  << fDataMember[num] << " of ";
+        *fLog << fObject[num]->GetName() << " neither int nor float... abort." << endl;
+        return kFALSE;
+    }
+}
+
+// --------------------------------------------------------------------------
+//
+// Fills the one, two or three data members into our histogram
+//
+Bool_t MH3::Fill(const MParContainer *par)
+{
+    Double_t x, y, z;
+
+    switch (fDimension)
+    {
+    case 3:
+        if (!GetValue(2, z))
+            return kFALSE;
+    case 2:
+        if (!GetValue(1, y))
+            return kFALSE;
+    case 1:
+        if (!GetValue(0, x))
+            return kFALSE;
+    }
+
+    switch (fDimension)
+    {
+    case 3:
+        ((TH3*)fHist)->Fill(x, y, z);
+        return kTRUE;
+    case 2:
+        ((TH2*)fHist)->Fill(x, y);
+        return kTRUE;
+    case 1:
+        fHist->Fill(x);
+        return kTRUE;
+    }
+
+    return kFALSE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Draw clone of histogram. So that the object can be deleted
+// and the histogram is still visible in the canvas.
+// The cloned object are deleted together with the canvas if the canvas is
+// destroyed. If you want to handle destroying the canvas you can get a
+// pointer to it from this function
+//
+TObject *MH3::DrawClone(Option_t *opt) const
+{
+    TCanvas &c = *MH::MakeDefCanvas(fHist);
+
+    *fLog << all << "Created Canvas: '" << fHist->GetName() <<"' '" << fHist->GetTitle() << "'" << endl;
+
+    //
+    // This is necessary to get the expected bahviour of DrawClone
+    //
+    gROOT->SetSelectedPad(NULL);
+
+    fHist->DrawCopy(opt);
+
+    c.Modified();
+    c.Update();
+
+    return &c;
+}
+
+// --------------------------------------------------------------------------
+//
+// Creates a new canvas and draws the histogram into it.
+// Be careful: The histogram belongs to this object and won't get deleted
+// together with the canvas.
+//
+void MH3::Draw(Option_t *opt)
+{
+    if (!gPad)
+        MH::MakeDefCanvas(fHist);
+
+    fHist->Draw(opt);
+
+    gPad->Modified();
+    gPad->Update();
+}
Index: /trunk/MagicSoft/Mars/mhist/MH3.h
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MH3.h	(revision 1283)
+++ /trunk/MagicSoft/Mars/mhist/MH3.h	(revision 1283)
@@ -0,0 +1,58 @@
+#ifndef MARS_MH3
+#define MARS_MH3
+
+#ifndef ROOT_TH1
+#include <TH1.h>
+#endif
+#ifndef MARS_MH
+#include "MH.h"
+#endif
+
+class TH1;
+class TMethodCall;
+
+class MH3 : public MH
+{
+protected:
+    const Int_t fDimension;        // Number of dimensions of histogram
+
+    TH1 *fHist;                    // Histogram to fill
+
+    TString fDataMember[3];        // Data member which should be filled into the histogram x
+
+    MParContainer *fObject[3];     // Object from which the data is filled
+    TMethodCall   *fMethodCall[3]; // Method call to get the data from the object
+
+    Double_t fScale[3];
+
+    Bool_t GetValue(Int_t num, Double_t &v);
+    Bool_t GetMethodCall(const MParList *plist, Int_t num);
+
+public:
+    MH3(const char *memberx);
+    MH3(const char *memberx, const char *membery);
+    MH3(const char *memberx, const char *membery, const char *memberz);
+    ~MH3();
+
+    void SetScaleX(Double_t scale) { fScale[0] = scale; }
+    void SetScaleY(Double_t scale) { fScale[1] = scale; }
+    void SetScaleZ(Double_t scale) { fScale[2] = scale; }
+
+    Int_t GetDimension() const { return fDimension; }
+
+    void SetName(const char *name);
+    void SetTitle(const char *title);
+
+    Bool_t SetupFill(const MParList *pList);
+    Bool_t Fill(const MParContainer *par);
+
+    TH1 &GetHist() { return *fHist; }
+    const TH1 &GetHist() const { return *fHist; }
+
+    void Draw(Option_t *opt=NULL);
+    TObject *DrawClone(Option_t *opt=NULL) const;
+
+    ClassDef(MH3, 1) // Generalized 1/2/3D-histogram for Mars variables
+};
+
+#endif
Index: /trunk/MagicSoft/Mars/mhist/MHHillas.cc
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MHHillas.cc	(revision 1282)
+++ /trunk/MagicSoft/Mars/mhist/MHHillas.cc	(revision 1283)
@@ -53,5 +53,5 @@
 //
 MHHillas::MHHillas(const char *name, const char *title)
-    : fMm2Deg(-1), fUseMmScale(kFALSE)
+    : fMm2Deg(-1), fUseMmScale(kTRUE)
 {
     //
@@ -72,9 +72,9 @@
     fWidth->SetDirectory(NULL);
 
-    fLength->GetXaxis()->SetTitle("Length [mm]");
-    fWidth->GetXaxis()->SetTitle("Width [mm]");
-
-    fLength->GetYaxis()->SetTitle("Counts");
-    fWidth->GetYaxis()->SetTitle("Counts");
+    fLength->SetXTitle("Length [mm]");
+    fWidth->SetXTitle("Width [mm]");
+
+    fLength->SetYTitle("Counts");
+    fWidth->SetYTitle("Counts");
 }
 
@@ -119,8 +119,9 @@
     }
 
-    fLength->GetXaxis()->SetTitle("Length [\\circ]");
-    fWidth->GetXaxis()->SetTitle("Width [\\circ]");
-
-    fMm2Deg = geom->GetConvMm2Deg();
+    fLength->SetXTitle("Length [\\circ]");
+    fWidth->SetXTitle("Width [\\circ]");
+
+    fMm2Deg     = geom->GetConvMm2Deg();
+    fUseMmScale = kFALSE;
 
     return kTRUE;
@@ -189,6 +190,6 @@
     if (fUseMmScale)
     {
-        fLength->GetXaxis()->SetTitle("Length [mm]");
-        fWidth->GetXaxis()->SetTitle("Width [mm]");
+        fLength->SetXTitle("Length [mm]");
+        fWidth->SetXTitle("Width [mm]");
 
         fLength->Scale(1./fMm2Deg);
@@ -197,6 +198,6 @@
     else
     {
-        fLength->GetXaxis()->SetTitle("Length [\\circ]");
-        fWidth->GetXaxis()->SetTitle("Width [\\circ]");
+        fLength->SetXTitle("Length [\\circ]");
+        fWidth->SetXTitle("Width [\\circ]");
 
         fLength->Scale(fMm2Deg);
Index: /trunk/MagicSoft/Mars/mhist/MHHillas.h
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MHHillas.h	(revision 1282)
+++ /trunk/MagicSoft/Mars/mhist/MHHillas.h	(revision 1283)
@@ -7,5 +7,4 @@
 
 class TH1F;
-class MHillas;
 
 class MHHillas : public MH
@@ -15,4 +14,5 @@
     TH1F *fLength;
 
+protected:
     Float_t fMm2Deg;
 
@@ -24,5 +24,5 @@
 
     void SetMmScale(Bool_t mmscale=kTRUE);
-    void SetMm2Deg(Float_t mmdeg);
+    virtual void SetMm2Deg(Float_t mmdeg);
 
     Bool_t SetupFill(const MParList *pList);
Index: /trunk/MagicSoft/Mars/mhist/MHHillasExt.cc
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MHHillasExt.cc	(revision 1283)
+++ /trunk/MagicSoft/Mars/mhist/MHHillasExt.cc	(revision 1283)
@@ -0,0 +1,285 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz  2001 <mailto:tbretz@uni-sw.gwdg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MHHillasExt
+//
+// This class contains histograms for every Hillas parameter
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "MHHillasExt.h"
+
+#include <math.h>
+
+#include <TH1.h>
+#include <TPad.h>
+#include <TCanvas.h>
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MGeomCam.h"
+#include "MParList.h"
+#include "MHillasExt.h"
+
+ClassImp(MHHillasExt);
+
+// --------------------------------------------------------------------------
+//
+// Setup four histograms for Width, Length
+//
+MHHillasExt::MHHillasExt(const char *name, const char *title)
+{
+    //
+    //   set the name and title of this object
+    //
+    fName  = name  ? name  : "MHHillasExt";
+    fTitle = title ? title : "Container for Hillas (ext) histograms";
+
+    //
+    // loop over all Pixels and create two histograms
+    // one for the Low and one for the High gain
+    // connect all the histogram with the container fHist
+    //
+    fHConc.SetDirectory(NULL);
+    fHConc1.SetDirectory(NULL);
+    fHAsym.SetDirectory(NULL);
+    fHM3Long.SetDirectory(NULL);
+    fHM3Trans.SetDirectory(NULL);
+
+    fHConc.SetTitle("Ratio: Conc");
+    fHConc1.SetTitle("Ratio: Conc1");
+    fHAsym.SetTitle("Asymmetry");
+    fHM3Long.SetTitle("3^{rd} Moment Longitudinal");
+    fHM3Trans.SetTitle("3^{rd} Moment Transverse");
+
+    fHConc.SetXTitle("Ratio");
+    fHConc1.SetXTitle("Ratio");
+    fHAsym.SetXTitle("Asym [mm]");
+    fHM3Long.SetXTitle("3^{rd} M_{l} [mm]");
+    fHM3Trans.SetXTitle("3^{rd} M_{t} [mm]");
+
+    fHConc.SetYTitle("Counts");
+    fHConc1.SetYTitle("Counts");
+    fHAsym.SetYTitle("Counts");
+    fHM3Long.SetYTitle("Counts");
+    fHM3Trans.SetYTitle("Counts");
+}
+
+// --------------------------------------------------------------------------
+//
+// Delete the four histograms
+//
+MHHillasExt::~MHHillasExt()
+{
+}
+
+// --------------------------------------------------------------------------
+//
+// Setup the Binning for the histograms automatically if the correct
+// instances of MBinning (with the names 'BinningWidth' and 'BinningLength')
+// are found in the parameter list
+// Use this function if you want to set the conversion factor which
+// is used to convert the mm-scale in the camera plain into the deg-scale
+// used for histogram presentations. The conversion factor is part of
+// the camera geometry. Please create a corresponding MGeomCam container.
+//
+Bool_t MHHillasExt::SetupFill(const MParList *plist)
+{
+    const MBinning* binsc  = (MBinning*)plist->FindObject("BinningConc");
+    const MBinning* binsc1 = (MBinning*)plist->FindObject("BinningConc1");
+    const MBinning* binsa  = (MBinning*)plist->FindObject("BinningAsym");
+    const MBinning* binsl  = (MBinning*)plist->FindObject("BinningM3Long");
+    const MBinning* binst  = (MBinning*)plist->FindObject("BinningM3Trans");
+    if (!binsc || !binsc1 || !binsa || !binsl || !binst)
+    {
+        *fLog << err << dbginf << "At least one MBinning not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    SetBinning(&fHConc,    binsc);
+    SetBinning(&fHConc1,   binsc1);
+    SetBinning(&fHAsym,    binsa);
+    SetBinning(&fHM3Long,  binsl);
+    SetBinning(&fHM3Trans, binst);
+
+    const MGeomCam *geom = (MGeomCam*)plist->FindObject("MGeomCam");
+    if (!geom)
+    {
+        *fLog << warn << dbginf << "No Camera Geometry available. Using mm-scale for histograms." << endl;
+        return kTRUE;
+    }
+
+    fHAsym.SetXTitle("Asym [\\circ]");
+    fHM3Long.SetXTitle("3^{rd} M_{l} [\\circ]");
+    fHM3Trans.SetXTitle("3^{rd} M_{t} [\\circ]");
+
+    return MHHillas::SetupFill(plist);
+}
+
+// --------------------------------------------------------------------------
+//
+// Fill the four histograms with data from a MHillas-Container.
+// Be careful: Only call this with an object of type MHillas
+//
+Bool_t MHHillasExt::Fill(const MParContainer *par)
+{
+    const MHillasExt &h = *(MHillasExt*)par;
+
+    fHConc.Fill(h.GetConc());
+    fHConc1.Fill(h.GetConc1());
+
+    if (fUseMmScale)
+    {
+        fHAsym.Fill(h.GetAsym());
+        fHM3Long.Fill(h.GetM3Long());
+        fHM3Trans.Fill(h.GetM3Trans());
+    }
+    else
+    {
+        fHAsym.Fill(fMm2Deg*h.GetAsym());
+        fHM3Long.Fill(fMm2Deg*h.GetM3Long());
+        fHM3Trans.Fill(fMm2Deg*h.GetM3Trans());
+    }
+
+    return MHHillas::Fill(par);
+}
+
+// --------------------------------------------------------------------------
+//
+// With this function you can convert the histogram ('on the fly') between
+// degrees and millimeters.
+//
+void MHHillasExt::SetMmScale(Bool_t mmscale)
+{
+    if (fUseMmScale == mmscale)
+        return;
+
+    if (fMm2Deg<0)
+    {
+        *fLog << warn << dbginf << "Warning - Sorry, no conversion factor for conversion available." << endl;
+        return;
+    }
+
+    if (fUseMmScale)
+    {
+        fHAsym.SetXTitle("Asym [mm]");
+        fHM3Long.SetXTitle("3^{rd} M_{l}[mm]");
+        fHM3Trans.SetXTitle("3^{rd} M_{t} [mm]");
+
+        fHAsym.Scale(1./fMm2Deg);
+        fHM3Long.Scale(1./fMm2Deg);
+        fHM3Trans.Scale(1./fMm2Deg);
+    }
+    else
+    {
+        fHAsym.SetXTitle("Asym [\\circ]");
+        fHM3Long.SetXTitle("3^{rd} M_{l} [\\circ]");
+        fHM3Trans.SetXTitle("3^{rd} M_{t} [\\circ]");
+
+        fHAsym.Scale(fMm2Deg);
+        fHM3Long.Scale(fMm2Deg);
+        fHM3Trans.Scale(fMm2Deg);
+    }
+
+    MHHillas::SetMmScale(mmscale);
+}
+
+// --------------------------------------------------------------------------
+//
+// Draw clones of all four histograms. So that the object can be deleted
+// and the histograms are still visible in the canvas.
+// The cloned object are deleted together with the canvas if the canvas is
+// destroyed. If you want to handle dostroying the canvas you can get a
+// pointer to it from this function
+//
+TObject *MHHillasExt::DrawClone(Option_t *opt) const
+{
+    TCanvas &c = *MakeDefCanvas("Hillas", "Histograms of Hillas Parameters",
+                               3*350, 2*250);
+    c.Divide(3, 2);
+
+    gROOT->SetSelectedPad(NULL);
+
+    //
+    // This is necessary to get the expected bahviour of DrawClone
+    //
+    c.cd(1);
+    ((TH1F&)fHConc).DrawCopy();
+
+    c.cd(4);
+    ((TH1F&)fHConc1).DrawCopy();
+
+    c.cd(2);
+    ((TH1F&)fHAsym).DrawCopy();
+
+    c.cd(3);
+    ((TH1F&)fHM3Long).DrawCopy();
+
+    c.cd(6);
+    ((TH1F&)fHM3Trans).DrawCopy();
+
+    c.Modified();
+    c.Update();
+
+    MHHillas::DrawClone();
+
+    return &c;
+}
+
+// --------------------------------------------------------------------------
+//
+// Creates a new canvas and draws the four histograms into it.
+// Be careful: The histograms belongs to this object and won't get deleted
+// together with the canvas.
+//
+void MHHillasExt::Draw(Option_t *)
+{
+    if (!gPad)
+        MakeDefCanvas("Hillas", "Histograms of Hillas Parameters", 350, 3*250);
+
+    gPad->Divide(3, 2);
+
+    gPad->cd(1);
+    fHConc.DrawCopy();
+
+    gPad->cd(4);
+    fHConc1.DrawCopy();
+
+    gPad->cd(2);
+    fHAsym.DrawCopy();
+
+    gPad->cd(3);
+    fHM3Long.DrawCopy();
+
+    gPad->cd(6);
+    fHM3Trans.DrawCopy();
+
+    gPad->Modified();
+    gPad->Update();
+
+    MHHillas::DrawClone();
+}
Index: /trunk/MagicSoft/Mars/mhist/MHHillasExt.h
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MHHillasExt.h	(revision 1283)
+++ /trunk/MagicSoft/Mars/mhist/MHHillasExt.h	(revision 1283)
@@ -0,0 +1,35 @@
+#ifndef MARS_MHHillasExt
+#define MARS_MHHillasExt
+
+#ifndef ROOT_TH1
+#include <TH1.h>
+#endif
+#ifndef MARS_MHHillas
+#include "MHHillas.h"
+#endif
+
+class MHHillasExt : public MHHillas
+{
+private:
+    TH1F fHConc;    // [ratio] concentration ratio: sum of the two highest pixels / fSize
+    TH1F fHConc1;   // [ratio] concentration ratio: sum of the highest pixel / fSize
+    TH1F fHAsym;    // [mm]    fDist minus dist: center of ellipse, highest pixel
+    TH1F fHM3Long;  // [mm]    3rd moment (e-weighted) along major axis
+    TH1F fHM3Trans; // [mm]    3rd moment (e-weighted) along minor axis
+
+public:
+    MHHillasExt(const char *name=NULL, const char *title=NULL);
+    ~MHHillasExt();
+
+    void SetMmScale(Bool_t mmscale=kTRUE);
+
+    Bool_t SetupFill(const MParList *pList);
+    Bool_t Fill(const MParContainer *par);
+
+    void Draw(Option_t *opt=NULL);
+    TObject *DrawClone(Option_t *opt=NULL) const;
+
+    ClassDef(MHHillasExt, 1) // Container which holds histograms for length and width
+};
+
+#endif
Index: /trunk/MagicSoft/Mars/mhist/MHStarMap.cc
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MHStarMap.cc	(revision 1282)
+++ /trunk/MagicSoft/Mars/mhist/MHStarMap.cc	(revision 1283)
@@ -39,5 +39,12 @@
 #include <TCanvas.h>  // TCanvas
 
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+
+#include "MGeomCam.h"
 #include "MHillas.h"
+#include "MBinning.h"
 
 ClassImp(MHStarMap);
@@ -48,4 +55,5 @@
 //
 MHStarMap::MHStarMap(const char *name, const char *title)
+    : fMm2Deg(-1), fUseMmScale(kTRUE)
 {
     //
@@ -57,5 +65,4 @@
     //   set the name and title of this object
     //
-    
     fName  = name  ? name  : "MHStarMap" ;
     fTitle = title ? title : "Container for a Star Map" ;
@@ -88,4 +95,50 @@
 // --------------------------------------------------------------------------
 //
+// Setup the Binning for the histograms automatically if the correct
+// instances of MBinning (with the names 'BinningWidth' and 'BinningLength')
+// are found in the parameter list
+// Use this function if you want to set the conversion factor which
+// is used to convert the mm-scale in the camera plain into the deg-scale
+// used for histogram presentations. The conversion factor is part of
+// the camera geometry. Please create a corresponding MGeomCam container.
+//
+Bool_t MHStarMap::SetupFill(const MParList *plist)
+{
+    const MGeomCam *geom = (MGeomCam*)plist->FindObject("MGeomCam");
+    if (geom)
+    {
+        fMm2Deg = geom->GetConvMm2Deg();
+        fUseMmScale = kFALSE;
+
+        fStarMap->SetXTitle("x [\\circ]");
+        fStarMap->SetYTitle("y [\\circ]");
+    }
+
+    const MBinning *bins = (MBinning*)plist->FindObject("BinningStarMap");
+    if (!bins)
+    {
+        float r = geom ? geom->GetMaxRadius() : 600;
+        r *= 2./3;
+        if (!fUseMmScale)
+            r *= fMm2Deg;
+
+        MBinning b;
+        b.SetEdges(100, -r, r);
+        SetBinning(fStarMap, &b, &b);
+    }
+    else
+        SetBinning(fStarMap, bins, bins);
+
+    if (!geom)
+    {
+        *fLog << warn << dbginf << "No Camera Geometry available. Using mm-scale for histograms." << endl;
+        return kTRUE;
+    }
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
 // Fill the four histograms with data from a MHillas-Container.
 // Be careful: Only call this with an object of type MHillas
@@ -98,22 +151,93 @@
 
     const float m = tan(delta);
-    const float t = h.GetMeanY() - m*h.GetMeanX();
+
+    float t = h.GetMeanY() - m*h.GetMeanX();
+
+    if (!fUseMmScale)
+        t *= fMm2Deg;
 
     if (m>-1 && m<1)
-        for (int x=-298; x<298; x+=4)
+    {
+        TAxis &axe = *fStarMap->GetXaxis();
+
+        const int N = axe.GetXbins()->GetSize();
+        for (int i=0; i<N; i++)
         {
+            const float x = axe.GetBinCenter(i);
             const float y = m*x+t;
 
             fStarMap->Fill(x, y);
         }
+    }
     else
-        for (int y=-298; y<298; y+=4)
+    {
+        TAxis &axe = *fStarMap->GetYaxis();
+
+        const int N = axe.GetXbins()->GetSize();
+        for (int i=0; i<N; i++)
         {
+            const float y = axe.GetBinCenter(i);
             const float x = (y-t)/m;
 
             fStarMap->Fill(x, y);
         }
+    }
 
     return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Use this function to setup your own conversion factor between degrees
+// and millimeters. The conversion factor should be the one calculated in
+// MGeomCam. Use this function with Caution: You could create wrong values
+// by setting up your own scale factor.
+//
+void MHStarMap::SetMm2Deg(Float_t mmdeg)
+{
+    if (mmdeg<0)
+    {
+        *fLog << warn << dbginf << "Warning - Conversion factor < 0 - nonsense. Ignored." << endl;
+        return;
+    }
+
+    if (fMm2Deg>=0)
+        *fLog << warn << dbginf << "Warning - Conversion factor already set. Overwriting" << endl;
+
+    fMm2Deg = mmdeg;
+}
+
+// --------------------------------------------------------------------------
+//
+// With this function you can convert the histogram ('on the fly') between
+// degrees and millimeters.
+//
+void MHStarMap::SetMmScale(Bool_t mmscale)
+{
+    if (fUseMmScale == mmscale)
+        return;
+
+    if (fMm2Deg<0)
+    {
+        *fLog << warn << dbginf << "Warning - Sorry, no conversion factor for conversion available." << endl;
+        return;
+    }
+
+    if (fUseMmScale)
+    {
+        fStarMap->SetXTitle("x [mm]");
+        fStarMap->SetYTitle("y [mm]");
+
+        fStarMap->Scale(1./fMm2Deg);
+    }
+    else
+    {
+        fStarMap->SetXTitle("x [\\circ]");
+        fStarMap->SetYTitle("y [\\circ]");
+
+        fStarMap->Scale(1./fMm2Deg);
+    }
+
+    fUseMmScale = mmscale;
 }
 
Index: /trunk/MagicSoft/Mars/mhist/MHStarMap.h
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MHStarMap.h	(revision 1282)
+++ /trunk/MagicSoft/Mars/mhist/MHStarMap.h	(revision 1283)
@@ -17,4 +17,8 @@
     TH2F *fStarMap;
 
+    Float_t fMm2Deg;
+
+    Bool_t fUseMmScale;
+
     void PrepareDrawing() const;
 
@@ -23,4 +27,8 @@
     ~MHStarMap();
 
+    void SetMmScale(Bool_t mmscale=kTRUE);
+    void SetMm2Deg(Float_t mmdeg);
+
+    Bool_t SetupFill(const MParList *pList);
     Bool_t Fill(const MParContainer *par);
 
Index: /trunk/MagicSoft/Mars/mhist/Makefile
===================================================================
--- /trunk/MagicSoft/Mars/mhist/Makefile	(revision 1282)
+++ /trunk/MagicSoft/Mars/mhist/Makefile	(revision 1283)
@@ -31,8 +31,10 @@
            MBinning.cc \
            MH.cc \
+           MH3.cc \
            MHFadcPix.cc \
            MHFadcCam.cc \
            MHHillas.cc \
            MHHillasSrc.cc \
+           MHHillasExt.cc \
            MHStarMap.cc \
            MHEnergyTime.cc \
