Index: /trunk/MagicSoft/Mars/mhbase/MHn.cc
===================================================================
--- /trunk/MagicSoft/Mars/mhbase/MHn.cc	(revision 8697)
+++ /trunk/MagicSoft/Mars/mhbase/MHn.cc	(revision 8697)
@@ -0,0 +1,375 @@
+/* ======================================================================== *\
+!
+! *
+! * 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-2007
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MHn
+//
+//   +-----------------+
+//   |1                |
+//   |                 |
+//   |                 |
+//   |                 |
+//   |                 |
+//   +-----------------+
+//
+//   +-----------------+      +--------+--------+
+//   |1                |      |1       |2       |
+//   |                 |      |        |        |
+//   +-----------------+      |        |        |
+//   |2                |      |        |        |
+//   |                 |      |        |        |
+//   +-----------------+      +--------+--------+
+//
+//   +--------+--------+      +-----+-----+-----+
+//   |1       |2       |      |1    |3          |
+//   |        |        |      |     |           |
+//   +--------+--------+      +-----+           +
+//   |3       |        |      |2    |           |
+//   |        |        |      |     |           |
+//   +--------+--------+      +-----+-----+-----+
+//
+//   +--------+--------+      +------+----------+
+//   |1       |2       |      |1     |4         |
+//   |        |        |      +------+          |
+//   +--------+--------+      |2     |          |
+//   |3       |4       |      +------+          |
+//   |        |        |      |3     |          |
+//   +--------+--------+      +------+----------+
+//
+//   +-----+-----+-----+      +--------+--------+
+//   |1    |2    |3    |      |1       |2       |
+//   |     |     |     |      +--------+--------|
+//   +-----+-----+-----+      |3       |4       |
+//   |4    |5    |     |      +--------+        |
+//   |     |     |     |      |5       |        |
+//   +-----+-----+-----+      +--------+--------+
+//
+//   +-----+-----+-----+      +--------+--------+
+//   |1    |2    |3    |      |1       |2       |
+//   |     |     |     |      +--------+--------+
+//   +-----+-----+-----+      |3       |4       |
+//   |4    |5    |6    |      +--------+--------+
+//   |     |     |     |      |5       |6       |
+//   +-----+-----+-----+      +--------+--------+
+//
+//
+// For example:
+//   MHn myhist
+//   ...
+//
+/////////////////////////////////////////////////////////////////////////////
+#include "MHn.h"
+
+#include <TCanvas.h>
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MH3.h"
+
+ClassImp(MHn);
+
+using namespace std;
+
+MHn::MHn(const char *name, const char *title) : fLayout(kSimple), fNum(0)
+{
+    fName  = name  ? name  : "MHn";
+    fTitle = title ? title : "Generalized histogram class for up to six histograms";
+
+    memset(fHist, 0, 6*sizeof(MH3*));
+}
+
+MHn::~MHn()
+{
+    for (int i=0; i<fNum; i++)
+        if (fHist[i])
+            delete fHist[i];
+}
+
+// --------------------------------------------------------------------------
+//
+// If a histogram with the same name is found, the pad-number with a
+// training underscore is added.
+//
+// FIXME: How do we handle identical names with different axes?
+//
+void MHn::InitHist()
+{
+    TString name = fName;
+
+    for (int i=0; i<fNum; i++)
+        if (name==fHist[i]->GetName())
+        {
+            name += Form("_%d", fNum);
+            break;
+        }
+
+    fHist[fNum]->SetName(fName);
+    fHist[fNum]->SetTitle(fTitle);
+
+    fHist[fNum]->SetAutoRangeX();
+
+    fNum++;
+}
+
+// --------------------------------------------------------------------------
+//
+// Add a new 1D-MH3 histogram. An internal pointer is set to it, so that
+// InitName and InitTitle can be used for this histogram until a new
+// histogram is added using AddHist
+//
+//  e.g. AddHist("MHillas.fSize")
+//
+Bool_t MHn::AddHist(const char *memberx)
+{
+    if (fNum==8)
+    {
+        *fLog << err << "ERROR - MHn doesn't support more than six histograms... AddHist ignored." << endl;
+        return kFALSE;
+    }
+
+    fHist[fNum] = new MH3(memberx);
+
+    InitHist();
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Add a new 2D-MH3 histogram. An internal pointer is set to it, so that
+// InitName and InitTitle can be used for this histogram until a new
+// histogram is added using AddHist
+//
+//  e.g. AddHist("MHillas.fLength", "MHillas.fSize")
+//
+Bool_t MHn::AddHist(const char *memberx, const char *membery)
+{
+    if (fNum==8)
+    {
+        *fLog << err << "ERROR - MHn doesn't support more than six histograms... AddHist ignored." << endl;
+        return kFALSE;
+    }
+
+    fHist[fNum] = new MH3(memberx, membery);
+
+    InitHist();
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Add a new 3D-MH3 histogram. An internal pointer is set to it, so that
+// InitName and InitTitle can be used for this histogram until a new
+// histogram is added using AddHist
+//
+//  e.g. AddHist("MHillas.fWidth", "MHillas.fLength", "MHillas.fSize")
+//
+Bool_t MHn::AddHist(const char *memberx, const char *membery, const char *memberz)
+{
+    if (fNum==8)
+    {
+        *fLog << err << "ERROR - MHn doesn't support more than six histograms... AddHist ignored." << endl;
+        return kFALSE;
+    }
+
+    fHist[fNum] = new MH3(memberx, membery, memberz);
+
+    InitHist();
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Set the draw option of the n-th MH3. See MH3 for more details of the
+// meaning of it.
+//
+Bool_t MHn::SetDrawOption(Int_t n, const char *opt)
+{
+    if (n<0 || n>=fNum)
+    {
+        *fLog << err << "ERROR - Histogram " << n << " not yet initialized... SetDrawOption ignored." << endl;
+        return kFALSE;
+    }
+
+    fDrawOption[n] = opt;
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Set the name of the n-th MH3. See MH3 for more details of the meaning
+// of the name. If the given name starts with a semicolon fName is prepend
+// to the string.
+//
+Bool_t MHn::InitName(Int_t n, const char *nam)
+{
+    if (n<0 || n>=fNum)
+    {
+        *fLog << err << "ERROR - Histogram " << n << " not yet initialized... InitName ignored." << endl;
+        return kFALSE;
+    }
+
+    TString name = TString(nam).Strip(TString::kBoth);
+
+    if (name[0]==';')
+        name.Prepend(fName);
+
+    fHist[n]->SetName(name);
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Set the title of the n-th MH3. See MH3 for more details of the meaning
+// of the title. If the given title starts with a semicolon fTitle is prepend
+// to the string.
+//
+Bool_t MHn::InitTitle(Int_t n, const char *tit)
+{
+    if (n<0 || n>=fNum)
+    {
+        *fLog << err << "ERROR - Histogram " << n << " not yet initialized... InitTitle ignored." << endl;
+        return kFALSE;
+    }
+
+    TString title = TString(tit).Strip(TString::kBoth);
+
+    if (title[0]==';')
+        title.Prepend(fTitle);
+
+    fHist[n]->SetTitle(title);
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Call SetupFill for all initialized histograms
+//
+Bool_t MHn::SetupFill(const MParList *plist)
+{
+    for (int i=0; i<fNum; i++)
+        if (!fHist[i]->SetupFill(plist))
+            return kFALSE;
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Call Fill for all initialized histograms
+//
+Bool_t MHn::Fill(const MParContainer *par, const Stat_t w)
+{
+    for (int i=0; i<fNum; i++)
+        if (!fHist[i]->Fill(par, w))
+            return kFALSE;
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Call Finalize for all initialized histograms
+//
+Bool_t MHn::Finalize()
+{
+    for (int i=0; i<fNum; i++)
+        if (!fHist[i]->Finalize())
+            return kFALSE;
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+void MHn::Draw(Option_t *opt)
+{
+    TVirtualPad *pad = gPad ? gPad : MakeDefCanvas(this);
+    pad->SetBorderMode(0);
+
+    const Bool_t same = TString(opt).Contains("same");
+
+    if (!same)
+    {
+        AppendPad();
+
+        const Int_t id = fNum + fLayout*10;
+
+        switch (id)
+        {
+        case 0:   // 0
+        case 10:  // 0
+            return;
+        case 1:   // 1
+        case 11:  // 1
+            break;
+
+        case 2:   // 2
+            pad->Divide(1,2);
+            break;
+        case 3:   // 3
+        case 4:   // 4
+            pad->Divide(2,2);
+            break;
+        case 5:   // 5
+        case 6:   // 6
+            pad->Divide(3,2);
+            break;
+
+        case 12:  // 2
+            pad->Divide(2,1);
+            break;
+        case 13:  // 3
+            break;
+        case 14:  // 4
+            pad->Divide(2,2);
+            break;
+        case 15:  // 5
+            pad->Divide(2,3);
+            pad->GetPad(4)->SetPad(0.51, 0.01, 0.99, 0.65);
+            delete pad->GetPad(6);
+            break;
+        case 16:  // 6
+            pad->Divide(2,3);
+            break;
+        }
+    }
+
+    for (int i=0; i<fNum; i++)
+    {
+        TString opt(fDrawOption[i]);
+        if (same)
+            opt += " same";
+
+        pad->cd(i+1);
+        fHist[i]->Draw(opt);
+    }
+}
Index: /trunk/MagicSoft/Mars/mhbase/MHn.h
===================================================================
--- /trunk/MagicSoft/Mars/mhbase/MHn.h	(revision 8697)
+++ /trunk/MagicSoft/Mars/mhbase/MHn.h	(revision 8697)
@@ -0,0 +1,80 @@
+#ifndef MARS_MHn
+#define MARS_MHn
+
+#ifndef ROOT_TH1
+#include <TH1.h>
+#endif
+#ifndef MARS_MH
+#include "MH.h"
+#endif
+
+class MH3;
+
+class MHn : public MH
+{
+public:
+    enum Layout_t { kSimple, kComplex };
+
+protected:
+    MH3    *fHist[6];        // Possible six histograms
+    TString fDrawOption[6];  // Possible corresponding draw options
+
+    Layout_t fLayout;        // Specifier for the layout in the canvas
+
+    Int_t fNum;              // Number of initialized histograms
+
+    void InitHist();
+
+    Bool_t InitName(Int_t n,  const char *n);
+    Bool_t InitTitle(Int_t n, const char *t);
+    Bool_t SetDrawOption(Int_t n, const char *opt);
+
+public:
+    MHn(const char *name=NULL, const char *title=NULL);
+    ~MHn();
+
+    // Setter
+    void SetLayout(Layout_t t) { fLayout = t; }
+
+    Bool_t AddHist(const char *memberx);
+    Bool_t AddHist(const char *memberx, const char *membery);
+    Bool_t AddHist(const char *memberx, const char *membery, const char *memberz);
+
+    void SetDrawOption(const char *opt) { SetDrawOption(fNum-1, opt); }
+
+    void InitName(const char *n)
+    {
+        InitName(fNum-1, n);
+    }
+
+    void InitTitle(const char *t)
+    {
+        InitTitle(fNum-1, t);
+    }
+
+    /*
+    void SetScaleX(Double_t scale) { fScale[0] = scale; }
+    void SetScaleY(Double_t scale) { fScale[1] = scale; }
+    void SetScaleZ(Double_t scale) { fScale[2] = scale; }
+
+    void SetLogx(Bool_t b=kTRUE) { b ? fHist->SetBit(kIsLogx) : fHist->ResetBit(kIsLogx); }
+    void SetLogy(Bool_t b=kTRUE) { b ? fHist->SetBit(kIsLogy) : fHist->ResetBit(kIsLogy); }
+    void SetLogz(Bool_t b=kTRUE) { b ? fHist->SetBit(kIsLogz) : fHist->ResetBit(kIsLogz); }
+
+    void Sumw2() const { if (fHist) fHist->Sumw2(); }
+    */
+
+    // MH
+    Bool_t SetupFill(const MParList *pList);
+    Bool_t Fill(const MParContainer *par, const Stat_t w=1);
+    Bool_t Finalize();
+
+    // TObject
+    //void SetColors() const;
+    void Draw(Option_t *opt=NULL);
+    //void Paint(Option_t *opt="");
+
+    ClassDef(MHn, 1) // Generalized histogram class for up to six histograms
+};
+
+#endif
