Index: trunk/MagicSoft/Mars/Changelog
===================================================================
--- trunk/MagicSoft/Mars/Changelog	(revision 1628)
+++ trunk/MagicSoft/Mars/Changelog	(revision 1629)
@@ -1,7 +1,44 @@
                                                                   -*-*- END -*-*-
+
+ 2002/11/18: Thomas Bretz
+
+   * macros/multidimdist2.C:
+     - fixed a typo
+     - added Alpha and Theta
+
+   * mbase/MTime.h:
+     - added minus-operator
+
+   * mdata/MDataChain.[h,cc]:
+     - added floor
+
+   * mhist/MFillH.[h,cc]:
+     - moved MMap and MMap support MHArray
+
+   * mhist/MHArray.[h,cc]:
+     - added MMap
+     - added MMap-support
+     - added legend
+     - added more draw options
+
+   * mhist/MHFadcCam.[h,cc]:
+     - added Fill(const MRawEvtData*)
+     - added const getter functions
+
+   * mhist/MHFadcPix.h:
+     - added const getter functions
+
+   * mmc/MMcCorsikaRunHeader.[h,cc]:
+     - removed underscores from names
+     - removed empty destructor
+
+
+
  2002/11/16: Abelardo Moralejo
 
    * mmc/MMcCorsikaRunHeader.cc:
      - added default destructor
+
+
 
  2002/11/15: Thomas Bretz
Index: trunk/MagicSoft/Mars/macros/multidimdist2.C
===================================================================
--- trunk/MagicSoft/Mars/macros/multidimdist2.C	(revision 1628)
+++ trunk/MagicSoft/Mars/macros/multidimdist2.C	(revision 1629)
@@ -65,5 +65,5 @@
     //  Give the names of the star-files to be read
     //   Here you give the trainings sample(s) for
-    //                 the hadrons
+    //                 the gammas
     // ---------------------------------------------
     MReadMarsFile readg("Events", "star_gammas.root");
@@ -83,4 +83,6 @@
     matrix.AddColumn("MHillasSrc.fDist");
     matrix.AddColumn("log10(MHillas.fSize)");
+    matrix.AddColumn("MHillasSrc.fAlpha");
+    matrix.AddColumn("MMcEvt.fTheta");
     plist.AddToList(&matrix);
 
Index: trunk/MagicSoft/Mars/manalysis/MPedestalCalc.cc
===================================================================
--- trunk/MagicSoft/Mars/manalysis/MPedestalCalc.cc	(revision 1629)
+++ trunk/MagicSoft/Mars/manalysis/MPedestalCalc.cc	(revision 1629)
@@ -0,0 +1,229 @@
+/* ======================================================================== *\
+!
+! *
+! * 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): Josep Flix 11/2002 <mailto:jflix@ifae.es>
+!   Author(s): Thomas Bretz 11/2002 <mailto:tbretz@astro.uni-wuerburg.de>
+!
+!   Copyright: MAGIC Software Development, 2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//  MPedestalCalc
+//
+//  Task to calculate the pedestals from the event stream.
+//
+//  From the events two streams of pedestals are created like in the
+//  following table
+//  MRawEvtData:    1   2   3   4   5   6   7   8   9  10  11  12
+//  MPedestalCam;1: ------1------   ------2------   ------3------...
+//  MPedestalCam;2:         ------1------   ------2------  ------...
+//
+//  Input Containers:
+//   MRawEvtData
+//
+//  Output Containers:
+//   MPedestalCam;1
+//   MPedestalCam;2
+//
+/////////////////////////////////////////////////////////////////////////////
+#include "MPedestalCalc.h"
+
+#include "MParList.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MTime.h"
+#include "MHFadcCam.h"
+#include "MRawEvtPixelIter.h"
+
+#include "MPedestalCam.h"
+#include "MPedestalPix.h"
+
+ClassImp(MPedestalCalc);
+
+MPedestalCalc::MPedestalCalc(const char *name, const char *title)
+    : fNumBranches(2), fTimeSlot(6), fHists(NULL)
+{
+    fName  = name  ? name  : "MPedestalCalc";
+    fTitle = title ? title : "Task to calculate pedestals from pedestal runs raw data";
+
+    AddToBranchList("fHiGainPixId");
+    AddToBranchList("fLoGainPixId");
+    AddToBranchList("fHiGainFadcSamples");
+    AddToBranchList("fLoGainFadcSamples");
+}
+
+Bool_t MPedestalCalc::PreProcess(MParList *pList)
+{
+    if (fHists)
+    {
+        *fLog << err << "ERROR - Previous PostProcess not called." << endl;
+        return kFALSE;
+    }
+
+    fHists = new MHFadcCam[fNumBranches];
+    fStart = new MTime    [fNumBranches];
+
+    fRawEvt = (MRawEvtData*)pList->FindObject("MRawEvtData");
+    if (!fRawEvt)
+    {
+        *fLog << dbginf << "MRawEvtData not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    fPedestals = (MPedestalCam*)pList->FindCreateObj("MPedestalCam");
+    if (!fPedestals)
+        return kFALSE;
+
+    fPedTime = (MTime*)pList->FindCreateObj("MTime", "MPedestalTime");
+    if (!fPedTime)
+        return kFALSE;
+
+    //
+    // Fixme: FindCreateObj --> FindObject
+    //
+    fEvtTime = (MTime*)pList->FindCreateObj("MTime", "MRawEvtTime");
+    if (!fEvtTime)
+        return kFALSE;
+
+    for (int i=0; i<fNumBranches; i++)
+        fStart[i].SetTime(fTimeSlot*10/fNumBranches*i, 0);
+
+    fPedTime->SetDuration(fTimeSlot);
+    fEvtTime->SetTime(0, 0);
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+//  Checks whether the current event exceed the validity range of a pedestal
+//  in one of the streams. If this is the case the data from the histogram
+//  is dumped as pedestals into the corresponding containers and the
+//  histograms are reset.
+//
+//  Then the current event is filled into the histograms.
+//
+Bool_t MPedestalCalc::Process()
+{
+    //
+    // Time when filling of stream a/b must be restarted
+    //
+    for (int i=0; i<fNumBranches; i++)
+    {
+        Check(i);
+        Fill(i);
+    }
+
+    fEvtTime->SetTime(fEvtTime->GetTimeLo()+10, 0);
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+//  Fill the event in the histogram if the current time of the
+//  event is _after_ the start time for filling
+//
+void MPedestalCalc::Fill(Int_t i)
+{
+    if (*fEvtTime < fStart[i])
+        return;
+
+    fHists[i].Fill(fRawEvt);
+}
+
+// --------------------------------------------------------------------------
+//
+//  If the current time of the event is equal or after the time
+//  which is given by the start time plus the validity range
+//  calculate the corresponding set of pedestals and reset the
+//  histograms
+//
+void MPedestalCalc::Check(Int_t i)
+{
+    if (*fEvtTime-fStart[i] < fTimeSlot*10)
+        return;
+
+    Calc(i);
+
+    fStart[i] = *fEvtTime;
+    fHists[i].ResetHistograms();
+}
+
+// --------------------------------------------------------------------------
+//
+//  Deletes all dynamicly allocated arrays
+//
+Bool_t MPedestalCalc::PostProcess()
+{
+    delete fHists;
+    delete fStart;
+
+    fHists=NULL;
+
+    return kTRUE;
+}
+
+/*
+ #include "MRawEvtData.h"
+ */
+// --------------------------------------------------------------------------
+//
+//  Dumps the mean, rms and their errors from the filled histograms into
+//  the Pedestal container. Sets the ReadyToSaveFlag of the MPedestalCam
+//  container.
+//
+void MPedestalCalc::Calc(Int_t i) const
+{
+    // FIXME! Fit +- 3 sigma to avoid outliers...
+
+    MRawEvtPixelIter pixel(fRawEvt);
+    while (pixel.Next())
+    {
+        const UInt_t pixid = pixel.GetPixelId();
+
+        const TH1 &h = *fHists[i].GetHistHi(pixid);
+
+        const Int_t   entries = (Int_t)h.GetEntries();
+        const Float_t meanhi  = h.GetMean();
+        const Float_t rmshi   = h.GetRMS();
+
+        const Float_t meanhierr = rmshi/sqrt(entries);
+        const Float_t rmshierr  = rmshi/sqrt(entries*2);
+
+        MPedestalPix &pix = (*fPedestals)[pixid];
+        pix.SetPedestal(meanhi, rmshi);
+        pix.SetPedestalRms(meanhierr, rmshierr);
+    }
+
+    *fPedTime = fStart[i];
+
+    fPedTime->SetReadyToSave();
+    fPedestals->SetReadyToSave();
+
+    /*
+     *fLog << i << "[" << fHists[i].GetHistHi(0)->GetEntries()/fRawEvt->GetNumHiGainSamples() << "]:  ";
+     *fLog << fEvtTime->GetTimeLo() << ": Calc [";
+     *fLog << fStart[i].GetTimeLo() << " < ";
+     *fLog << fStart[i].GetTimeLo()+fTimeSlot*10 << "]" << endl;
+     */
+}
Index: trunk/MagicSoft/Mars/mbase/MTime.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MTime.h	(revision 1628)
+++ trunk/MagicSoft/Mars/mbase/MTime.h	(revision 1629)
@@ -86,4 +86,9 @@
 };
 
+inline Double_t operator-(MTime &t1, MTime &t2)
+{
+    return (Double_t)t1.GetTimeLo()-(Double_t)t2.GetTimeLo();
+}
+
 inline Bool_t operator<(MTime &t1, MTime &t2)
 {
Index: trunk/MagicSoft/Mars/mdata/MDataChain.cc
===================================================================
--- trunk/MagicSoft/Mars/mdata/MDataChain.cc	(revision 1628)
+++ trunk/MagicSoft/Mars/mdata/MDataChain.cc	(revision 1629)
@@ -70,4 +70,5 @@
 //   sqrt(x)   square root of x
 //   abs(x)    absolute value of x, |x|
+//   floor(x)  round down to the nearest integer (floor(9.9)=9)
 //
 //
@@ -227,4 +228,5 @@
     if (txt=="pow10") return kEPow10;
     if (txt=="sgn")   return kESgn;
+    if (txt=="floor") return kEFloor;
     if (txt[0]=='-')  return kENegative;
     if (txt[0]=='+')  return kEPositive;
@@ -471,4 +473,5 @@
     case kENegative: return -val;
     case kEPositive: return val;
+    case kEFloor:    return floor(val);
     case kENoop:     return val;
     }
@@ -553,4 +556,5 @@
     case kENegative: str += "-"    ; break;
     case kEPositive: str += "+"    ; break;
+    case kEFloor:    str += "floor"; break;
     case kENoop:
         break;
Index: trunk/MagicSoft/Mars/mdata/MDataChain.h
===================================================================
--- trunk/MagicSoft/Mars/mdata/MDataChain.h	(revision 1628)
+++ trunk/MagicSoft/Mars/mdata/MDataChain.h	(revision 1629)
@@ -38,5 +38,6 @@
         kESgn,
         kEPositive,
-        kENegative
+        kENegative,
+        kEFloor
     } OperatorType_t;
 
Index: trunk/MagicSoft/Mars/mhist/MFillH.cc
===================================================================
--- trunk/MagicSoft/Mars/mhist/MFillH.cc	(revision 1628)
+++ trunk/MagicSoft/Mars/mhist/MFillH.cc	(revision 1629)
@@ -85,82 +85,4 @@
 ClassImp(MFillH);
 
-//////////////////////////////////////////////////////////////////////////////
-//
-// MMap
-//
-// This class maps a key-value to a given value. In its simple versions it
-// maps a key to an index.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <TArrayI.h>
-
-class MMap
-{
-private:
-    TArrayI fKeys;
-    TArrayI fValues;
-
-    Int_t K(Int_t i) const { return ((TArrayI)fKeys)[i]; }
-    Int_t V(Int_t i) const { return ((TArrayI)fValues)[i]; }
-
-public:
-    // --------------------------------------------------------------------------
-    //
-    // Get the value which corresponds to the given key-value
-    //
-    Int_t GetValue(Int_t key) const
-    {
-        const Int_t n = fKeys.GetSize();
-        for (int i=0; i<n; i++)
-        {
-            if (K(i)==key)
-                return V(i);
-        }
-        return -1;
-    }
-
-    // --------------------------------------------------------------------------
-    //
-    // Adds a new pair key-value. While the key is the key to the value.
-    // if the key already exists the pair is ignored.
-    //
-    void Add(Int_t key, Int_t value)
-    {
-        if (GetValue(key)>=0)
-            return;
-
-        const Int_t n = fKeys.GetSize();
-
-        fKeys.Set(n+1);
-        fValues.Set(n+1);
-
-        fKeys[n] = key;
-        fValues[n] = value;
-    }
-
-    // --------------------------------------------------------------------------
-    //
-    // Adds a new pair key-value. While the key is the key to the value.
-    // In this case the value is an automatically sequential created index.
-    // if the key already exists the pair is ignored.
-    //
-    Int_t Add(Int_t key)
-    {
-        const Int_t k = GetValue(key);
-        if (k>=0)
-            return k;
-
-        const Int_t n = fKeys.GetSize();
-
-        fKeys.Set(n+1);
-        fValues.Set(n+1);
-
-        fKeys[n] = key;
-        fValues[n] = n;
-
-        return n;
-    }
-};
-
 // --------------------------------------------------------------------------
 //
@@ -177,5 +99,4 @@
 
     fIndex  = NULL;
-    fMapIdx = new MMap;
 }
 
@@ -326,6 +247,4 @@
         if (fIndex->TestBit(kCanDelete))
             delete fIndex;
-
-    delete fMapIdx;
 }
 
@@ -500,9 +419,10 @@
 {
     if (fIndex)
-    {
-        const Int_t key = (Int_t)fIndex->GetValue();
-        const Int_t idx = fMapIdx->Add(key);
-        ((MHArray*)fH)->SetIndex(idx);
-    }
+        ((MHArray*)fH)->SetIndexByKey(fIndex->GetValue());
+    /*
+     const Int_t key = (Int_t)fIndex->GetValue();
+     const Int_t idx = fMapIdx->Add(key);
+     ((MHArray*)fH)->SetIndex(idx);
+     */
 
     return fH->Fill(fParContainer);
Index: trunk/MagicSoft/Mars/mhist/MHArray.cc
===================================================================
--- trunk/MagicSoft/Mars/mhist/MHArray.cc	(revision 1628)
+++ trunk/MagicSoft/Mars/mhist/MHArray.cc	(revision 1629)
@@ -37,6 +37,13 @@
 //  by its index.
 //
-//  To map a key to the index use/see MFillH, which automatically maps a
-//  key-value to the array index.
+//  To access the histograms by a key instead of an index use SetIndexByKey
+//  instead of Set/Inc/DecIndex. It will take the integerpart of the
+//  floating point value (2 in case of 2.9). For each new key a new
+//  index in the Mapping Table is created. So that you can access your
+//  histograms by the key (eg in case of the Angle Theta=23.2deg use
+//  SetIndexByKey(23.2)
+//
+//  If the index is equal to the number of histograms in the array a call
+//  to the Fill-member-function will create a new histogram.
 //
 //  In the constructor istempl leads to two different behaviours of the
@@ -73,8 +80,109 @@
 ClassImp(MHArray);
 
-// --------------------------------------------------------------------------
-//
-// Default Constructor. hname is the name of the histogram class which
-// is in the array.
+//////////////////////////////////////////////////////////////////////////////
+//
+// MMap
+//
+// This class maps a key-value to a given value. In its simple versions it
+// maps a key to an index.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <TArrayI.h>
+
+class MMap
+{
+private:
+    TArrayI fKeys;
+    TArrayI fValues;
+
+    Int_t K(Int_t i) const { return ((TArrayI)fKeys)[i]; }
+    Int_t V(Int_t i) const { return ((TArrayI)fValues)[i]; }
+
+public:
+    // --------------------------------------------------------------------------
+    //
+    // Return the size of the table
+    //
+    Int_t GetSize() const
+    {
+        return fKeys.GetSize();
+    }
+
+    // --------------------------------------------------------------------------
+    //
+    // Get the value which corresponds to the given key-value
+    //
+    Int_t GetValue(Int_t key) const
+    {
+        const Int_t n = fKeys.GetSize();
+        for (int i=0; i<n; i++)
+        {
+            if (K(i)==key)
+                return V(i);
+        }
+        return -1;
+    }
+
+    // --------------------------------------------------------------------------
+    //
+    // Get the key which corresponds to the given index
+    //
+    Int_t GetKey(Int_t value) const
+    {
+        const Int_t n = fKeys.GetSize();
+        for (int i=0; i<n; i++)
+        {
+            if (V(i)==value)
+                return K(i);
+        }
+        return -1;
+    }
+
+    // --------------------------------------------------------------------------
+    //
+    // Adds a new pair key-value. While the key is the key to the value.
+    // if the key already exists the pair is ignored.
+    //
+    void Add(Int_t key, Int_t value)
+    {
+        if (GetValue(key)>=0)
+            return;
+
+        const Int_t n = fKeys.GetSize();
+
+        fKeys.Set(n+1);
+        fValues.Set(n+1);
+
+        fKeys[n] = key;
+        fValues[n] = value;
+    }
+
+    // --------------------------------------------------------------------------
+    //
+    // Adds a new pair key-value. While the key is the key to the value.
+    // In this case the value is an automatically sequential created index.
+    // if the key already exists the pair is ignored.
+    //
+    Int_t Add(Int_t key)
+    {
+        const Int_t k = GetValue(key);
+        if (k>=0)
+            return k;
+
+        const Int_t n = fKeys.GetSize();
+
+        fKeys.Set(n+1);
+        fValues.Set(n+1);
+
+        fKeys[n] = key;
+        fValues[n] = n;
+
+        return n;
+    }
+};
+
+// --------------------------------------------------------------------------
+//
+// hname is the name of the histogram class which is in the array.
 //
 // istempl=kTRUE tells MHArray to use the first histogram retrieved from the
@@ -95,4 +203,6 @@
     fTitle = title ? TString(title) : (TString("Base class for Mars histogram arrays:") + hname);
 
+    fMapIdx = new MMap;
+
     fArray = new TList;
     fArray->SetOwner();
@@ -131,4 +241,32 @@
 // --------------------------------------------------------------------------
 //
+// Default Constructor. hname is the name of the histogram class which
+// is in the array.
+//
+// istempl=kTRUE tells MHArray to use the first histogram retrieved from the
+// ParameterList by hname to be used as a template. New histograms are not
+// created using the root dictionary, but the New-member function (see
+// MParConatiner)
+// In the case istempl=kFALSE new histograms are created using the root
+// dictionary while hname is the class name. For the creation their
+// default constructor is used.
+//
+MHArray::MHArray(const MH *hist, const char *name, const char *title)
+    : fIdx(0), fClass(NULL), fTemplate(hist), fTemplateName("<dummy>")
+{
+    //
+    //   set the name and title of this object
+    //
+    fName  = name  ? name  : "MHArray";
+    fTitle = title ? TString(title) : (TString("Base class for Mars histogram arrays:") + hist->GetName());
+
+    fMapIdx = new MMap;
+
+    fArray = new TList;
+    fArray->SetOwner();
+}
+
+// --------------------------------------------------------------------------
+//
 // Destructor: Deleteing the array and all histograms which are part of the
 // array.
@@ -138,7 +276,29 @@
     fArray->Delete();
     delete fArray;
-}
-
-
+    delete fMapIdx;
+}
+
+// --------------------------------------------------------------------------
+//
+//  Use this to access the histograms by a key. If you use values like
+//   (in this order) 2.5, 7.2, 2.5, 9.3, 9.3, 3.3, 2.2, 1.1
+//  it will be mapped to the following indices internally:
+//                    0    1    0    2    2    3    4    5
+//
+//  WARNING: Make sure that you don't create new histograms by setting
+//           a new index (SetIndex or IncIndex) which is equal the size
+//           of the array and create new histogram by CreateH. In this
+//           case you will confuse the mapping completely.
+//
+void MHArray::SetIndexByKey(Double_t key)
+{
+    fIdx = fMapIdx->Add((Int_t)key);
+}
+
+// --------------------------------------------------------------------------
+//
+//  Use this function to access a histogram by its index in the array.
+//  Becarefull the index isn't checked!
+//
 MH &MHArray::operator[](Int_t i)
 {
@@ -146,4 +306,9 @@
 }
 
+// --------------------------------------------------------------------------
+//
+//  Use this function to access a histogram by its index in the array.
+//  Becarefull the index isn't checked!
+//
 MH *MHArray::At(Int_t i)
 {
@@ -151,4 +316,10 @@
 }
 
+// --------------------------------------------------------------------------
+//
+//  Use this function to access the histogram corresponding to the
+//  currently set index (by Set/Inc/DecIndex or SetIndexByKey)
+//  Becarefull the index set isn't checked!
+//
 MH *MHArray::GetH()
 {
@@ -170,4 +341,8 @@
     if (fTemplate)
     {
+        //
+        // create the parameter container as a clone of the existing
+        // template histogram.
+        //
         hist = (MH*)fTemplate->New();
     }
@@ -226,4 +401,7 @@
     fIdx = 0;
 
+    if (fTemplate)
+        return kTRUE;
+
     if (!fTemplateName.IsNull())
     {
@@ -246,5 +424,5 @@
     const Int_t n = fArray->GetSize();
 
-    if (fIdx <0 || fIdx>n)
+    if (fIdx<0 || fIdx>n)
     {
         *fLog << warn << "Histogram Index #" << fIdx << " out of bounds (>";
@@ -287,5 +465,29 @@
     *fLog << all << GetDescriptor() << " contains " << fArray->GetSize();
     *fLog << " histograms." << endl;
-}
+
+    if (fMapIdx->GetSize()<=0)
+        return;
+
+    *fLog << " idx\t     key" << endl;
+    for (int i=0; i<fMapIdx->GetSize(); i++)
+        *fLog << "  " << i << "\t<-->  " << fMapIdx->GetKey(i) << endl;
+    *fLog << endl;
+}
+
+// --------------------------------------------------------------------------
+//
+// Adds the given object to the given legend (if != NULL). The Legend
+// entry name is created from the key...
+//
+void MHArray::AddLegendEntry(TLegend *leg, TObject *obj, Int_t idx) const
+{
+    if (!leg)
+        return;
+
+    TString name = " ";
+    name += fMapIdx->GetKey(idx);
+    leg->AddEntry(obj, name, "lpf"); // l=line, p=polymarker, f=fill
+}
+
 
 // --------------------------------------------------------------------------
@@ -302,8 +504,18 @@
     gStyle->SetOptStat(0);
 
+    //
+    // if the keymapping is used create a legend to identify the histograms
+    //
+    TLegend *leg = NULL;
+    if (fMapIdx->GetSize()>0)
+    {
+        leg = new TLegend(0.85, 0.80, 0.99, 0.99);
+        leg->SetBit(kCanDelete);
+    }
+
     TIter Next(fArray);
     MH *hist = (MH*)Next();
 
-    Int_t col=2;
+    Int_t idx=0;
     Double_t max=0;
     Double_t min=0;
@@ -311,4 +523,9 @@
     TH1 *h1=NULL;
 
+    //
+    // If the array has at least one entry:
+    //  - find the starting boundaries
+    //  - draw it and set its line color
+    //
     if (hist)
     {
@@ -316,10 +533,17 @@
         {
             h1->Draw();
-            h1->SetLineColor(col++);
+            h1->SetLineColor(idx+2);
             max = h1->GetMaximum();
             min = h1->GetMinimum();
+
+            AddLegendEntry(leg, h1, idx);
         }
     }
 
+    //
+    // For all following histograms:
+    //  - update the boundaries
+    //  - draw it and set its line color
+    //
     while ((hist=(MH*)Next()))
     {
@@ -330,11 +554,16 @@
 
         h->Draw("same");
-        h->SetLineColor(col++);
+        h->SetLineColor(idx+2);
         if (max<h->GetMaximum())
             max = h->GetMaximum();
         if (min>h->GetMinimum())
             min = h->GetMinimum();
-    }
-
+
+        AddLegendEntry(leg, h, idx++);
+    }
+
+    //
+    // Now update the drawing region so that everything is displayed
+    //
     if (h1)
     {
@@ -342,4 +571,8 @@
         h1->SetMaximum(max>0 ? max*1.05 : max*0.95);
     }
+
+    if (leg)
+        leg->Draw();
+
     gPad->Modified();
     gPad->Update();
@@ -353,4 +586,6 @@
 // the MH entries by calling their GetHistByName function.
 // If the option also contains 'nonew' no new canvas is created.
+// The option "Scale=1" scales the area of all histogram to 1
+// The option "Scale=max" scales the maximum of all histogram to 1
 //
 TObject *MHArray::DrawClone(Option_t *opt) const
@@ -360,5 +595,15 @@
     TCanvas *c = NULL;
 
-    Int_t nonew = o.Index("nonew", TString::kIgnoreCase);
+    Int_t scale1   = o.Index("scale=1",   TString::kIgnoreCase);
+    Int_t scalemax = o.Index("scale=max", TString::kIgnoreCase);
+    Int_t nonew    = o.Index("nonew",     TString::kIgnoreCase);
+
+    if (o.BeginsWith("scale=1", TString::kIgnoreCase))
+        scale1 = 0;
+    if (o.BeginsWith("scale=max", TString::kIgnoreCase))
+        scalemax = 0;
+    if (o.BeginsWith("nonew", TString::kIgnoreCase))
+        nonew = 0;
+
     if (nonew>=0)
     {
@@ -372,12 +617,26 @@
         o.Remove(nonew, 5);
     }
+    if (scale1>=0)
+        o.Remove(scale1, 7);
+    if (scalemax>=0)
+        o.Remove(scalemax, 9);
 
     const Stat_t sstyle = gStyle->GetOptStat();
     gStyle->SetOptStat(0);
 
+    //
+    // if the keymapping is used create a legend to identify the histograms
+    //
+    TLegend *leg = NULL;
+    if (fMapIdx->GetSize()>0)
+    {
+        leg = new TLegend(0.85, 0.80, 0.99, 0.99);
+        leg->SetBit(kCanDelete);
+    }
+
     TIter Next(fArray);
     MH *hist = (MH*)Next();
 
-    Int_t col=2;
+    Int_t idx=0;
     Double_t max=0;
     Double_t min=0;
@@ -385,4 +644,9 @@
     TH1 *h1=NULL;
 
+     //
+    // If the array has at least one entry:
+    //  - find the starting boundaries
+    //  - draw it and set its line color
+    //
     if (hist)
     {
@@ -390,12 +654,25 @@
         {
             h1 = (TH1*)h1->DrawCopy();
-            h1->SetMarkerColor(col);
-            h1->SetLineColor(col++);
+
+            if (scale1>=0)
+                h1->Scale(1./h1->Integral());
+            if (scalemax>=0)
+                h1->Scale(1./h1->GetMaximum());
+
+            h1->SetMarkerColor(idx);
+            h1->SetLineColor(idx+2);
             h1->SetFillStyle(4000);
             max = h1->GetMaximum();
             min = h1->GetMinimum();
+
+            AddLegendEntry(leg, h1, idx++);
         }
     }
 
+    //
+    // For all following histograms:
+    //  - update the boundaries
+    //  - draw it and set its line color
+    //
     while ((hist=(MH*)Next()))
     {
@@ -406,13 +683,24 @@
 
         h = (TH1*)h->DrawCopy("same");
-        h->SetMarkerColor(col);
-        h->SetLineColor(col++);
-        h->SetFillStyle(4000);
+
+        if (scale1>=0)
+            h->Scale(1./h->Integral());
+        if (scalemax>=0)
+            h->Scale(1./h->GetMaximum());
+
+        h->SetMarkerColor(idx);
+        h->SetLineColor(idx+2);
+        h->SetFillStyle(4000); // transperent (why is this necessary?)
         if (max<h->GetMaximum())
             max = h->GetMaximum();
         if (min>h->GetMinimum())
             min = h->GetMinimum();
-    }
-
+
+        AddLegendEntry(leg, h, idx++);
+    }
+
+    //
+    // Now update the drawing region so that everything is displayed
+    //
     if (h1)
     {
@@ -420,4 +708,8 @@
         h1->SetMaximum(max>0 ? max*1.05 : max*0.95);
     }
+
+    if (leg)
+        leg->Draw();
+
     gPad->Modified();
     gPad->Update();
Index: trunk/MagicSoft/Mars/mhist/MHArray.h
===================================================================
--- trunk/MagicSoft/Mars/mhist/MHArray.h	(revision 1628)
+++ trunk/MagicSoft/Mars/mhist/MHArray.h	(revision 1629)
@@ -7,4 +7,7 @@
 
 class TList;
+class TLegend;
+
+class MMap;
 
 class MHArray : public MH
@@ -15,10 +18,13 @@
 
     const MParList *fParList; //! pointer to parameter list used for SetupFill when a new Hist is created
-    TClass *fClass;           //! pointer to class entry in root dictionary
+    TClass *fClass;           // pointer to class entry in root dictionary
 
-    MH *fTemplate;            //! pointer to a template histogram
-    TString fTemplateName;    //! name of the template class
+    const MH *fTemplate;      //-> pointer to a template histogram
+    TString fTemplateName;    // name of the template class
+
+    MMap *fMapIdx;            //! Table to map keys to array indices
 
     Bool_t CreateH();
+    void   AddLegendEntry(TLegend *leg, TObject *obj, Int_t idx) const;
 
     enum { kUseTemplate=BIT(14) };
@@ -26,4 +32,5 @@
 public:
     MHArray(const TString hname, Bool_t istempl=kFALSE, const char *name=NULL, const char *title=NULL);
+    MHArray(const MH *hist, const char *name=NULL, const char *title=NULL);
     ~MHArray();
 
@@ -36,4 +43,6 @@
 
     MH *GetH();
+
+    void SetIndexByKey(Double_t key);
 
     void SetIndex(Int_t i) { fIdx=i; }
Index: trunk/MagicSoft/Mars/mhist/MHFadcCam.cc
===================================================================
--- trunk/MagicSoft/Mars/mhist/MHFadcCam.cc	(revision 1628)
+++ trunk/MagicSoft/Mars/mhist/MHFadcCam.cc	(revision 1629)
@@ -100,5 +100,5 @@
         const UInt_t id = pixel.GetPixelId();
 
-        for (Int_t i=0;  i<nhisamples; i++)
+        for (Int_t i=0; i<nhisamples; i++)
             FillHi(id, pixel.GetHiGainSamples()[i]);
 
@@ -113,4 +113,9 @@
 }
 
+Bool_t MHFadcCam::Fill(const MRawEvtData *par)
+{
+    return Fill((MParContainer*)par);
+}
+
 void MHFadcCam::ResetHistograms()
 {
Index: trunk/MagicSoft/Mars/mhist/MHFadcCam.h
===================================================================
--- trunk/MagicSoft/Mars/mhist/MHFadcCam.h	(revision 1628)
+++ trunk/MagicSoft/Mars/mhist/MHFadcCam.h	(revision 1629)
@@ -17,4 +17,6 @@
 #endif
 
+class MRawEvtData;
+
 class MHFadcCam : public MH
 {
@@ -30,9 +32,14 @@
 
     MHFadcPix *operator[](UInt_t i) { return (MHFadcPix*)(fArray->At(i)); }
+    const MHFadcPix *operator[](UInt_t i) const { return (MHFadcPix*)(fArray->At(i)); }
 
     TH1F *GetHistHi(UInt_t i)  { return (*this)[i]->GetHistHi(); }
     TH1F *GetHistLo(UInt_t i)  { return (*this)[i]->GetHistLo(); }
 
+    const TH1F *GetHistHi(UInt_t i) const { return (*this)[i]->GetHistHi(); }
+    const TH1F *GetHistLo(UInt_t i) const { return (*this)[i]->GetHistLo(); }
+
     Bool_t Fill(const MParContainer *par);
+    Bool_t Fill(const MRawEvtData *par);
 
     void ResetHistograms();
Index: trunk/MagicSoft/Mars/mhist/MHFadcPix.h
===================================================================
--- trunk/MagicSoft/Mars/mhist/MHFadcPix.h	(revision 1628)
+++ trunk/MagicSoft/Mars/mhist/MHFadcPix.h	(revision 1629)
@@ -23,4 +23,7 @@
     TH1F *GetHistLo() { return fHistLo; }
 
+    const TH1F *GetHistHi() const { return fHistHi; }
+    const TH1F *GetHistLo() const { return fHistLo; }
+
     void FillHi(Byte_t i);
     void FillLo(Byte_t i);
Index: trunk/MagicSoft/include-Classes/MMcFormat/MMcCorsikaRunHeader.cc
===================================================================
--- trunk/MagicSoft/include-Classes/MMcFormat/MMcCorsikaRunHeader.cc	(revision 1628)
+++ trunk/MagicSoft/include-Classes/MMcFormat/MMcCorsikaRunHeader.cc	(revision 1629)
@@ -47,30 +47,33 @@
     fTitle = title ? title : "Translation of the CORSIKA header";
 
-    fRunNumber = 0.0;
-    fDate = 0.0;
-    fCorsika_version = 0.0;
-    fNumObsLev = 0.0;
-    for(int i=0;i<10;i++)
-        fHeightLev[i]=0.0;
-    fSlopeSpec = 0.0;
-    fELowLim = 0.0;
-    fEUppLim = 0.0;
-    fEGS4_flag = 0.0;
-    fNKG_flag = 0.0;
-    fEcutoffh = 0.0;
-    fEcutoffm = 0.0;
-    fEcutoffe = 0.0;
-    fEcutoffg = 0.0;
+    fRunNumber = 0;
+    fDate = 0;
+    fCorsikaVersion = 0;
+    fNumObsLev = 0;
 
-    for(int i=0;i<50;i++)  fC[i] = 0.0;
-    for(int i=0;i<40;i++)  fCKA[i] = 0.0;
-    for(int i=0;i<5 ;i++)  fCETA[i] = 0.0;
-    for(int i=0;i<11;i++)  fCSTRBA[i] = 0.0;
-    for(int i=0;i<5;i++){
-        fAATM[i] = 0.0;
-        fBATM[i] = 0.0;
-        fCATM[i] = 0.0;
+    for (int i=0; i<10; i++)
+        fHeightLev[i]=0;
+
+    fSlopeSpec = 0;
+    fELowLim = 0;
+    fEUppLim = 0;
+    fEGS4flag = 0;
+    fNKGflag = 0;
+    fEcutoffh = 0;
+    fEcutoffm = 0;
+    fEcutoffe = 0;
+    fEcutoffg = 0;
+
+    for(int i=0; i<50; i++)  fC[i] = 0;
+    for(int i=0; i<40; i++)  fCKA[i] = 0;
+    for(int i=0; i<5; i++)  fCETA[i] = 0;
+    for(int i=0; i<11; i++)  fCSTRBA[i] = 0;
+    for(int i=0; i<5; i++)
+    {
+        fAATM[i] = 0;
+        fBATM[i] = 0;
+        fCATM[i] = 0;
     }
-    for(int i=0;i<4;i++)  fNFL[i] = 0.0;
+    for (int i=0;i<4; i++)  fNFL[i] = 0;
 
 }
@@ -105,13 +108,15 @@
     fRunNumber = runnumber;
     fDate = date;
-    fCorsika_version = vers;
+    fCorsikaVersion = vers;
     fNumObsLev = numobslev;
-    for(int i=0;i<10;i++)
+
+    for (int i=0; i<10; i++)
         fHeightLev[i]=height[i];
+
     fSlopeSpec = slope;
     fELowLim = elow;
     fEUppLim = eupp;
-    fEGS4_flag = egs4;
-    fNKG_flag = nkg;
+    fEGS4flag = egs4;
+    fNKGflag = nkg;
     fEcutoffh = eh;
     fEcutoffm = em;
@@ -119,14 +124,15 @@
     fEcutoffg = eg;
 
-    for(int i=0;i<50;i++)  fC[i] = c[i];
-    for(int i=0;i<40;i++)  fCKA[i] = cka[i];
-    for(int i=0;i<5 ;i++)  fCETA[i] = ceta[i];
-    for(int i=0;i<11;i++)  fCSTRBA[i] = cstrba[i];
-    for(int i=0;i<5;i++){
+    for (int i=0; i<50; i++)  fC[i] = c[i];
+    for (int i=0; i<40; i++)  fCKA[i] = cka[i];
+    for (int i=0; i<5 ; i++)  fCETA[i] = ceta[i];
+    for (int i=0; i<11; i++)  fCSTRBA[i] = cstrba[i];
+    for (int i=0; i<5; i++)
+    {
         fAATM[i] = aatm[i];
         fBATM[i] = batm[i];
         fCATM[i] = catm[i];
-       }
-    for(int i=0;i<4;i++)  fNFL[i] = nfl[i];
+    }
+    for (int i=0; i<4; i++)  fNFL[i] = nfl[i];
 }
 
Index: trunk/MagicSoft/include-Classes/MMcFormat/MMcCorsikaRunHeader.h
===================================================================
--- trunk/MagicSoft/include-Classes/MMcFormat/MMcCorsikaRunHeader.h	(revision 1628)
+++ trunk/MagicSoft/include-Classes/MMcFormat/MMcCorsikaRunHeader.h	(revision 1629)
@@ -20,5 +20,5 @@
     Float_t fRunNumber;
     Float_t fDate;
-    Float_t fCorsika_version;
+    Float_t fCorsikaVersion;
     Float_t fNumObsLev;
     Float_t fHeightLev[10];
@@ -26,6 +26,6 @@
     Float_t fELowLim;
     Float_t fEUppLim;    // Limits of energy range for generation
-    Float_t fEGS4_flag;
-    Float_t fNKG_flag;
+    Float_t fEGS4flag;
+    Float_t fNKGflag;
     Float_t fEcutoffh;
     Float_t fEcutoffm;
@@ -45,5 +45,4 @@
 public:
     MMcCorsikaRunHeader(const char *name=NULL, const char *title=NULL);
-    ~MMcCorsikaRunHeader();
 
     void Fill(const Float_t  runnumber,
