Index: trunk/MagicSoft/Mars/Changelog
===================================================================
--- trunk/MagicSoft/Mars/Changelog	(revision 2563)
+++ trunk/MagicSoft/Mars/Changelog	(revision 2564)
@@ -46,4 +46,14 @@
      - changed 'MRawEvtTime' to 'MTime'
      - added some debugging output in case of kContinue
+
+   * mmain/MOnlineDump.[h,cc], mmain/MOnlineDisplay.[h,cc]:
+     - added
+
+   * mmain/MainLinkDef.h, mmain/Makefile:
+     - added MOnlineDump
+     - added MOnlineDisplay
+
+   * mona.cc:
+     - updated
 
 
Index: trunk/MagicSoft/Mars/mmain/MOnlineDisplay.cc
===================================================================
--- trunk/MagicSoft/Mars/mmain/MOnlineDisplay.cc	(revision 2564)
+++ trunk/MagicSoft/Mars/mmain/MOnlineDisplay.cc	(revision 2564)
@@ -0,0 +1,536 @@
+/* ======================================================================== *\
+!
+! *
+! * 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, 11/2003 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2003
+!
+!
+\* ======================================================================== */
+#include "MOnlineDisplay.h"
+
+//
+// C-lib
+//
+#include <stdlib.h>              // atoi
+
+//
+// root
+//
+#include <TList.h>               // TList::Add
+#include <TStyle.h>              // gStyle->SetOptStat
+#include <TCanvas.h>             // TCanvas::cd
+
+//
+// root GUI
+//
+#include <TGLabel.h>             // TGLabel
+#include <TGButton.h>            // TGPictureButton
+#include <TGSlider.h>            // TGSlider
+#include <TG3DLine.h>            // TGHorizontal3DLine
+#include <TGTextEntry.h>         // TGTextEntry
+#include <TGButtonGroup.h>       // TGVButtonGroup
+#include <TRootEmbeddedCanvas.h> // TRootEmbeddedCanvas
+
+//
+// General
+//
+#include "MGList.h"              // MGList
+
+#include "MParList.h"            // MParList::AddToList
+#include "MEvtLoop.h"            // MEvtLoop::GetParList
+#include "MTaskList.h"           // MTaskList::AddToList
+
+//
+// Tasks
+//
+#include "MReadMarsFile.h"       // MReadMarsFile
+#include "MGeomApply.h"          // MGeomApply
+#include "MFDataMember.h"        // MFDataMember
+#include "MMcPedestalCopy.h"     // MMcPedestalCopy
+#include "MMcPedestalNSBAdd.h"   // MMcPedestalNSBAdd
+#include "MCerPhotCalc.h"        // MCerPhotCalc
+#include "MCerPhotAnal2.h"       // MCerPhotAnal2
+#include "MImgCleanStd.h"        // MImgCleanStd
+#include "MHillasCalc.h"         // MHillasCalc
+#include "MHillasSrcCalc.h"      // MHillasSrcCalc
+#include "MBlindPixelCalc.h"     // MBlindPixelCalc
+#include "MFillH.h"              // MFillH
+#include "MGTask.h"              // MGTask
+
+//
+// Container
+//
+#include "MHEvent.h"             // MHEvent
+#include "MHCamera.h"            // MHCamera
+#include "MRawEvtData.h"         // MRawEvtData
+
+ClassImp(MOnlineDisplay);
+
+// --------------------------------------------------------------------------
+//
+//  Constructor.
+//
+MOnlineDisplay::MOnlineDisplay() : MStatusDisplay(), fTask(0)
+{
+    //
+    // Setup Task list for hillas calculation
+    //
+    //SetupTaskList("Events", filename);
+
+    //
+    // Add MOnlineDisplay GUI elements to the display
+    //
+    AddUserFrame("");
+
+    //
+    // Show new part of the window, resize to correct aspect ratio
+    //
+    // FIXME: This should be done by MStatusDisplay automatically
+    Resize(GetWidth(), GetHeight() + fUserFrame->GetDefaultHeight());
+    //SetWindowName("Online Display");
+    MapSubwindows();
+    //MapWindow();
+
+    //
+    // Readin foirst event and display it
+    //
+    //ReadFirstEvent();
+}
+
+// --------------------------------------------------------------------------
+//
+//  Destructor: PostProcess eventloop, delete eventloop with all containers
+//
+MOnlineDisplay::~MOnlineDisplay()
+{
+    //fEvtLoop->PostProcess();
+    //delete fEvtLoop;
+}
+
+// --------------------------------------------------------------------------
+//
+//  Return reading task
+//
+/*
+MReadTree *MOnlineDisplay::GetReader() const
+{
+    MParList  *plist  = (MParList*)fEvtLoop->GetParList();
+    MTaskList *tlist  = (MTaskList*)plist->FindObject("MTaskList");
+    MReadTree *reader = (MReadTree*)tlist->FindObject("MRead");
+    return reader;
+}
+
+// --------------------------------------------------------------------------
+//
+//  Setup Task and parameter list for hillas calculation,
+//  preprocess tasks and read in first event (process)
+//
+void MOnlineDisplay::SetupTaskList(const char *tname, const char *fname)
+{
+    //
+    // Setup an empty job, with a reader task only.
+    // All tasks and parameter containers are deleted automatically
+    // (via SetOwner())
+    //
+    MTaskList *tlist = new MTaskList;
+    tlist->SetOwner();
+
+    MReadMarsFile *read = new MReadMarsFile(tname, fname);
+    read->DisableAutoScheme();
+    tlist->AddToList(read);
+
+    MGeomApply *apl = new MGeomApply;
+    tlist->AddToList(apl);
+
+    MParList *plist = new MParList;
+    plist->SetOwner();
+    plist->AddToList(tlist);
+
+    fEvtLoop = new MEvtLoop;
+    fEvtLoop->SetOwner();
+    fEvtLoop->SetParList(plist);
+
+    MHEvent *evt1 = new MHEvent(MHEvent::kEvtSignal);
+    MHEvent *evt2 = new MHEvent(MHEvent::kEvtSignal);
+    MHEvent *evt3 = new MHEvent(MHEvent::kEvtPedestal);
+    MHEvent *evt4 = new MHEvent(MHEvent::kEvtPedestalRMS);
+    MHEvent *evt5 = new MHEvent(MHEvent::kEvtRelativeSignal);
+    MHEvent *evt6 = new MHEvent(MHEvent::kEvtCleaningLevels);
+    evt1->SetName("Signal");
+    evt2->SetName("Cleaned");
+    evt3->SetName("Pedestal");
+    evt4->SetName("PedRMS");
+    evt5->SetName("Signal/PedRMS");
+    evt6->SetName("CleanLevels");
+    plist->AddToList(evt1);
+    plist->AddToList(evt2);
+    plist->AddToList(evt3);
+    plist->AddToList(evt4);
+    plist->AddToList(evt5);
+    plist->AddToList(evt6);
+
+    MMcPedestalCopy   *pcopy = new MMcPedestalCopy;
+    MMcPedestalNSBAdd *pdnsb = new MMcPedestalNSBAdd;
+    MCerPhotCalc      *ncalc = new MCerPhotCalc;
+    MCerPhotAnal2     *nanal = new MCerPhotAnal2;
+    MFillH            *fill1 = new MFillH(evt1, "MCerPhotEvt",  "MFillH1");
+    MImgCleanStd      *clean = new MImgCleanStd;
+    MFillH            *fill2 = new MFillH(evt2, "MCerPhotEvt",  "MFillH2");
+    MFillH            *fill3 = new MFillH(evt3, "MPedestalCam", "MFillH3");
+    MFillH            *fill4 = new MFillH(evt4, "MPedestalCam", "MFillH4");
+    MFillH            *fill5 = new MFillH(evt5, "MCameraData",  "MFillH5");
+    MFillH            *fill6 = new MFillH(evt6, "MCameraData",  "MFillH6");
+    MBlindPixelCalc   *blind = new MBlindPixelCalc;
+    MHillasCalc       *hcalc = new MHillasCalc;
+    MHillasSrcCalc    *scalc = new MHillasSrcCalc;
+
+    MFilter *f1=new MFDataMember("MRawRunHeader.fRunType", '>', 255.5);
+    MFilter *f2=new MFDataMember("MRawRunHeader.fRunType", '<', 255.5);
+
+    ncalc->SetFilter(f1);
+    nanal->SetFilter(f2);
+
+    tlist->AddToList(f1);
+    tlist->AddToList(f2);
+    tlist->AddToList(pcopy);
+    tlist->AddToList(pdnsb);
+    tlist->AddToList(ncalc);
+    tlist->AddToList(nanal);
+    tlist->AddToList(fill1);
+    tlist->AddToList(clean);
+    tlist->AddToList(fill2);
+    tlist->AddToList(fill3);
+    tlist->AddToList(fill4);
+    tlist->AddToList(fill5);
+    tlist->AddToList(fill6);
+    tlist->AddToList(blind);
+    tlist->AddToList(hcalc);
+    tlist->AddToList(scalc);
+
+    //
+    // Now distribute Display to all tasks
+    //
+    tlist->SetDisplay(this);
+}
+*/
+// --------------------------------------------------------------------------
+//
+//  Add the top part of the frame: This is filename and treename display
+//
+void MOnlineDisplay::AddTopFramePart1(TGCompositeFrame *vf1)
+{/*
+    //
+    //  --- the top1 part of the window ---
+    //
+    TGHorizontalFrame *top1 = new TGHorizontalFrame(frame, 1, 1);
+    fList->Add(top1);
+
+    //
+    // create gui elements
+    //
+    TGLabel *file = new TGLabel(top1, new TGString(Form("%s#%s", filename, treename)));
+    fList->Add(file);
+
+    //
+    // layout and add gui elements in/to frame
+    //
+    TGLayoutHints *laystd = new TGLayoutHints(kLHintsCenterX, 5, 5);
+    fList->Add(laystd);
+
+    top1->AddFrame(file,  laystd);
+
+    //
+    //  --- the top1 part of the window ---
+    //
+    TGHorizontalFrame *top2 = new TGHorizontalFrame(frame, 1, 1);
+    fList->Add(top2);
+
+    //
+    // layout and add frames
+    //
+    TGLayoutHints *laytop1 = new TGLayoutHints(kLHintsCenterX, 5, 5, 5);
+    fList->Add(laytop1);
+    frame->AddFrame(top1, laytop1);
+    frame->AddFrame(top2, laytop1);*/
+    TGLabel *file = new TGLabel(vf1, new TGString("Magic Online Display -- MONA"));
+    TGLayoutHints *laystd = new TGLayoutHints(kLHintsCenterX, 5, 5);
+    fList->Add(file);
+    fList->Add(laystd);
+    vf1->AddFrame(file,  laystd);
+}
+
+// --------------------------------------------------------------------------
+//
+//  Add the second part of the top frame: This are the event number controls
+//
+void MOnlineDisplay::AddTopFramePart2(TGCompositeFrame *vf1)
+{
+    //
+    // --- the top2 part of the window ---
+    //
+    TGHorizontalFrame *top2 = new TGHorizontalFrame(vf1, 1, 1);
+    fList->Add(top2);
+
+    //
+    // Create the gui elements
+    //
+    TGTextButton *freeze = new TGTextButton(top2, " Freeze ", kFreeze);
+    freeze->SetUserData(freeze);
+    freeze->Associate(this);
+    freeze->SetToolTipText("Freeze the current Event");
+
+    fList->Add(freeze);
+
+    //
+    // add the gui elements to the frame
+    //
+    TGLayoutHints *laystd = new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 5, 5);
+    fList->Add(laystd);
+
+    top2->AddFrame(freeze, laystd);
+
+    TGLayoutHints *laystd2 = new TGLayoutHints(kLHintsCenterX, 5, 5, 5, 5);
+    fList->Add(laystd2);
+    vf1->AddFrame(top2, laystd2);
+
+    //
+    // Add trailing line...
+    //
+    TGHorizontal3DLine *line = new TGHorizontal3DLine(vf1);
+    TGLayoutHints *layline = new TGLayoutHints(kLHintsExpandX);
+    fList->Add(line);
+    fList->Add(layline);
+    vf1->AddFrame(line, layline);
+}
+
+// --------------------------------------------------------------------------
+//
+//  Add the user frame part of the display
+//
+void MOnlineDisplay::AddUserFrame(const char* filename)
+{
+    fUserFrame->ChangeOptions(kHorizontalFrame);
+
+    // Slider
+    TGVSlider *slider = new TGVSlider(fUserFrame, 1, kSlider1, kSlider);
+    slider->SetRange(10, 300);
+    slider->SetScale(15);
+    slider->SetPosition(10);
+    slider->Associate(this);
+    //slider->SetToolTipText("Change the update frequency of the event display (1-30s)");
+
+    // frame1/2
+    TGCompositeFrame *vf1 = new TGVerticalFrame(fUserFrame, 1, 1);
+    TGCompositeFrame *vf2 = new TGVerticalFrame(fUserFrame, 1, 1);
+
+    AddTopFramePart1(vf1);
+    AddTopFramePart2(vf1);
+
+    // create root embedded canvas and add it to the tab
+    TRootEmbeddedCanvas *ec = new TRootEmbeddedCanvas("Slices", vf2, vf1->GetDefaultHeight()*3/2, vf1->GetDefaultHeight(), 0);
+    vf2->AddFrame(ec);
+    fList->Add(ec);
+
+    // set background and border mode of the canvas
+    fCanvas = ec->GetCanvas();
+    fCanvas->SetBorderMode(0);
+    gROOT->GetListOfCanvases()->Add(fCanvas);
+    //fCanvas->SetBorderSize(1);
+    //fCanvas->SetBit(kNoContextMenu);
+    //fCanvas->SetFillColor(16);
+
+    // layout
+    TGLayoutHints *lays = new TGLayoutHints(kLHintsExpandY);
+    TGLayoutHints *lay = new TGLayoutHints(kLHintsExpandX);
+    fUserFrame->AddFrame(slider, lays);
+    fUserFrame->AddFrame(vf1, lay);
+    fUserFrame->AddFrame(vf2);
+
+    fList->Add(lay);
+    fList->Add(lays);
+    fList->Add(vf1);
+    fList->Add(vf2);
+    fList->Add(slider);
+}
+
+/*
+// --------------------------------------------------------------------------
+//
+//  Checks if the event number is valid, and if so reads the new event
+//  and updates the display
+//
+void MOnlineDisplay::ReadinEvent(Int_t dir)
+{
+    MParList    *plist = (MParList*)fEvtLoop->GetParList();
+    MTaskList   *tlist = (MTaskList*)plist->FindObject("MTaskList");
+    MRawEvtData *raw = (MRawEvtData*)plist->FindObject("MRawEvtData");
+    if (!raw)
+        return;
+
+    //
+    // Read first event.
+    //
+    MReadTree *reader = GetReader();
+
+    const Int_t num = reader->GetNumEntry();
+
+    do
+    {
+        if (dir<0 && !reader->DecEventNum())
+        {
+            reader->SetEventNum(num);
+            return;
+        }
+        if (dir>0 && !reader->IncEventNum())
+        {
+            reader->SetEventNum(num);
+            return;
+        }
+
+        if (!tlist->Process())
+            return;
+
+        reader->DecEventNum();
+
+    } while (raw->GetNumPixels()<1 && dir!=0);
+
+    //
+    // Cleare the 'FADC canvas'
+    //
+    fCanvas->Clear();
+    fCanvas->Modified();
+    fCanvas->Update();
+
+    //
+    // Print parameters
+    //
+    plist->FindObject("MHillas")->Print();
+    plist->FindObject("MHillasExt")->Print();
+    plist->FindObject("MHillasSrc")->Print();
+    plist->FindObject("MNewImagePar")->Print();
+
+    //
+    // UpdateDisplay
+    //
+    gStyle->SetOptStat(1101);
+    Update();
+
+    TGTextEntry *entry = (TGTextEntry*)fList->FindWidget(kEvtNumber);
+    entry->SetText(Form("%d", reader->GetNumEntry()+1));
+}
+
+// --------------------------------------------------------------------------
+//
+//  Read first event to get display booted
+//
+void MOnlineDisplay::ReadFirstEvent()
+{
+    if (!fEvtLoop->PreProcess())
+        return;
+
+    //
+    // Get parlist
+    //
+    MParList *plist = (MParList*)fEvtLoop->GetParList();
+
+    //
+    // Add Geometry tab
+    //
+    MGeomCam *geom = (MGeomCam*)plist->FindObject("MGeomCam");
+
+    TCanvas &c=AddTab("Geometry");
+
+    c.SetFillColor(16);
+
+    MHCamera *cam = new MHCamera(*geom);
+    cam->SetBit(TH1::kNoStats|MHCamera::kNoLegend);
+    cam->Draw();
+    cam->DrawPixelIndices();
+    fList->Add(cam);
+
+    c.Modified();
+    c.Update();
+
+    //
+    // Now read event...
+    //
+    ReadinEvent();
+
+    TGString *txt = new TGString(Form("of %d", GetReader()->GetEntries()));
+    fNumOfEvts->SetText(txt);
+
+    //
+    // Set name for 'FADC canvas'. The name is the anchor for MHCamera.
+    // and clear the canvas
+    //
+    MHEvent *o = (MHEvent*)plist->FindObject("Signal");
+    fCanvas->SetName(Form("%p;%p;PixelContent", o->GetHist(),
+                          GetCanvas(1)->GetPad(1)));
+
+    //
+    // Draw ellipse on top of all pads
+    //
+    TObject *hillas = plist->FindObject("MHillas");
+    for (int i=1; i<7;i++)
+    {
+        TCanvas *c = GetCanvas(i);
+        c->GetPad(1)->cd(1);
+        hillas->Draw();
+    }
+}
+*/
+// --------------------------------------------------------------------------
+//
+//  Adds the geometry tab 
+//
+void MOnlineDisplay::AddGeometryTab()
+{
+    /*
+    MGeomCam *geom = (MGeomCam*)fEvtLoop->GetParList()->FindObject("MGeomCam");
+    if (!geom)
+        return;
+
+    TCanvas &c=AddTab("Geometry");
+
+    MHCamera *cam = new MHCamera(*geom);
+    cam->SetBit(TH1::kNoStats);
+    cam->Draw();
+    cam->DrawPixelIndices();
+    fList->Add(cam);
+
+    c.Modified();
+    c.Update();
+    */
+}
+
+// --------------------------------------------------------------------------
+//
+//  ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
+//
+// Processes information from all GUI items.
+// Selecting an item usually generates an event with 4 parameters.
+// The first two are packed into msg (first and second bytes).
+// The other two are parm1 and parm2.
+//
+Bool_t MOnlineDisplay::ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2)
+{
+    if (fTask && fTask->ProcessMessage(GET_MSG(msg), GET_SUBMSG(msg), mp1, mp2))
+        return kTRUE;
+
+    return MStatusDisplay::ProcessMessage(msg, mp1, mp2);
+}
Index: trunk/MagicSoft/Mars/mmain/MOnlineDisplay.h
===================================================================
--- trunk/MagicSoft/Mars/mmain/MOnlineDisplay.h	(revision 2564)
+++ trunk/MagicSoft/Mars/mmain/MOnlineDisplay.h	(revision 2564)
@@ -0,0 +1,63 @@
+#ifndef MARS_MOnlineDisplay
+#define MARS_MOnlineDisplay
+
+#ifndef MARS_MStatusDisplay
+#include "MStatusDisplay.h"
+#endif
+
+class TGLabel;
+class TGTextEntry;
+class MEvtLoop;
+
+class MParList;
+class MTaskList;
+class MReadTree;
+class MGTask;
+
+class MOnlineDisplay : public MStatusDisplay
+{
+    friend class MOnlineDump;
+public:
+    enum
+    {
+        kSlider = MStatusDisplay::kSearch + 1,
+        kFreeze
+    };
+
+private:
+    TGCompositeFrame *fTab1;
+    TGCompositeFrame *fTab2;
+
+    //TGLabel  *fNumOfEvts;
+    TCanvas  *fCanvas;
+    //MEvtLoop *fEvtLoop;
+
+    MGTask *fTask;
+
+    void AddTopFramePart1(TGCompositeFrame *frame);
+    void AddTopFramePart2(TGCompositeFrame *frame);
+    void AddGeometryTab();
+    void AddUserFrame(const char *filename);
+
+    void UpdateDisplay();
+    //void SetupTaskList(const char *tname, const char *fname);
+
+    //void ReadFirstEvent();
+    //void ReadinEvent(Int_t dir=0);
+
+    //MReadTree *GetReader() const;
+
+    Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2);
+
+public:
+    MOnlineDisplay();
+    ~MOnlineDisplay();
+
+    void SetTask(MGTask *t) { fTask=t; }
+
+    ClassDef(MOnlineDisplay, 0) // Display for camera images (cerenkov events)
+};
+
+#endif
+
+
Index: trunk/MagicSoft/Mars/mmain/MOnlineDump.cc
===================================================================
--- trunk/MagicSoft/Mars/mmain/MOnlineDump.cc	(revision 2564)
+++ trunk/MagicSoft/Mars/mmain/MOnlineDump.cc	(revision 2564)
@@ -0,0 +1,228 @@
+#include "MOnlineDump.h"
+
+#include <TCanvas.h>
+#include <TSystem.h>
+
+#include <TGButton.h>
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MTime.h"
+#include "MRawRunHeader.h"
+#include "MRawEvtHeader.h"
+
+#include "MOnlineDisplay.h"
+
+#include "MFRealTimePeriod.h"
+#include "MHEvent.h"
+#include "MHCamera.h"
+#include "MParList.h"
+#include "MTaskList.h"
+#include "MFillH.h"
+#include "MEventRate.h"
+
+ClassImp(MOnlineDump);
+
+using namespace std;
+
+void MOnlineDump::SetNoContextMenu(TObject *c)
+{
+    if (fDisplay->HasCanvas((TCanvas*)c))
+        c->ResetBit(kNoContextMenu);
+}
+
+void MOnlineDump::DisplayTriggerRate()
+{
+    Bool_t set = kFALSE;
+
+    if (*fEvtTime==0)
+    {
+        fEvtTime->SetTime(gSystem->Now());
+        set = kTRUE;
+    }
+
+    const UInt_t  evts = fRawEvtHeader->GetDAQEvtNumber() - fEvtNumber;
+    const Double_t sec = *fEvtTime-fTime;
+
+    fEvtNumber = fRawEvtHeader->GetDAQEvtNumber();
+    fTime      = *fEvtTime;
+
+    if (evts>0 && sec>0 && fDisplay)
+        fDisplay->SetStatusLine2(Form("Trigger Rate: %.1fHz /  Event Rate: %.1fHz", evts/sec, fRate->GetRate()));
+
+    if (set)
+        fEvtTime->SetTime((ULong_t)0);
+}
+
+Bool_t MOnlineDump::ProcessMessage(Int_t msg, Int_t submsg, Long_t mp1, Long_t mp2)
+{
+    switch (msg)
+    {
+    case kC_VSLIDER:
+        switch (submsg)
+        {
+        case kSL_POS:
+            if (mp1==MOnlineDisplay::kSlider && GetFilter())
+            {
+                ((MFRealTimePeriod*)GetFilter())->SetTime(mp2*100.);
+                *fLog << dbg << "Update Time: " << Form("%.1fs", mp2/10.) << endl;
+            }
+            return kTRUE;
+        }
+        return kFALSE;
+    case kC_COMMAND:
+        switch(submsg)
+        {
+        case kCM_TAB:
+            {
+                //
+                // Set name for 'FADC canvas'. The name is the anchor for MHCamera.
+                // and clear the canvas
+                //
+                if (!fPlist || !fDisplay)
+                    return kTRUE;
+
+                TCanvas *c = fDisplay->GetCanvas(mp1);
+                if (!c)
+                    return kTRUE;
+
+                MHEvent *o = (MHEvent*)fPlist->FindObject(c->GetName());
+                if (o)
+                    ((MOnlineDisplay*)fDisplay)->fCanvas->SetName(Form("%p;%p;PixelContent", o->GetHist(),
+                                                                       c->GetPad(1)));
+            }
+            break;
+
+        case kCM_BUTTON:
+            if (mp1==MOnlineDisplay::kFreeze)
+            {
+                TGButton *but = (TGButton*)mp2;
+                if (!but->IsDown())
+                {
+                    but->AllowStayDown(kTRUE);
+                    fCamEvent->SetFreezed();
+                }
+                else
+                {
+                    but->AllowStayDown(kFALSE);
+                    fCamEvent->SetFreezed(kFALSE);
+                }
+                but->Toggle();
+            }
+            return kTRUE;
+        }
+        return kFALSE;
+    }
+    return kFALSE;
+}
+
+MOnlineDump::~MOnlineDump()
+{
+    if (fDisplay)
+        ((MOnlineDisplay*)fDisplay)->SetTask(0);
+}
+
+Int_t MOnlineDump::PreProcess(MParList *pList)
+{
+    fPlist = pList;
+
+    if (gROOT->IsBatch())
+    {
+        *fLog << err << "We are in batch mode!" << endl;
+        return kFALSE;
+    }
+    if (!fDisplay)
+    {
+        *fLog << err << "fDisplay not set." << endl;
+        return kFALSE;
+    }
+
+    MTaskList *tasks = (MTaskList*)pList->FindObject("MTaskList");
+    if (!tasks)
+    {
+        *fLog << err << "MTaskList not found... abort." << endl;
+        return kFALSE;
+    }
+
+    fFill1 = (MFillH*)tasks->FindObject("MFillCamEvent");
+    if (!fFill1)
+    {
+        *fLog << err << "MFillCamEvent not found... abort." << endl;
+        return kFALSE;
+    }
+    fFill2 = (MFillH*)tasks->FindObject("MFillEvent");
+    if (!fFill2)
+    {
+        *fLog << err << "MFillEvent not found... abort." << endl;
+        return kFALSE;
+    }
+    fFill3 = (MFillH*)tasks->FindObject("MFillTriggerLvl0");
+    if (!fFill3)
+    {
+        *fLog << err << "MFillTriggerLvl0 not found... abort." << endl;
+        return kFALSE;
+    }
+    fRawEvtHeader = (MRawEvtHeader*)pList->FindObject("MRawEvtHeader");
+    if (!fRawEvtHeader)
+    {
+        *fLog << err << "MRawEvtHeader not found... abort." << endl;
+        return kFALSE;
+    }
+
+    fRawRunHeader = (MRawRunHeader*)pList->FindObject("MRawRunHeader");
+    if (!fRawRunHeader)
+    {
+        *fLog << err << "MRawRunHeader not found... abort." << endl;
+        return kFALSE;;
+    }
+
+    fEvtTime = (MTime*)pList->FindObject("MTime");
+    if (!fEvtTime)
+    {
+        *fLog << err << "MTime not found... abort." << endl;
+        return kFALSE;
+    }
+
+    fRate = (MEventRate*)pList->FindObject("MEventRate");
+    if (!fRate)
+    {
+        *fLog << err << "MEventRate not found... abort." << endl;
+        return kFALSE;
+    }
+
+    MHEvent *hevent = (MHEvent*)pList->FindObject("MHEvent");
+    if (!hevent)
+    {
+        *fLog << err << "MHEvent not found... abort." << endl;
+        return kFALSE;
+    }
+    fCamEvent = hevent->GetHist();
+
+    fRunNumber = 0xffffffff;
+    fEvtNumber = 0;
+
+    SetNoContextMenu((TObject*)fFill1->GetCanvas());
+    SetNoContextMenu((TObject*)fFill2->GetCanvas());
+    SetNoContextMenu((TObject*)fFill3->GetCanvas());
+
+    return kTRUE;
+}
+
+Int_t MOnlineDump::Process()
+{
+    DisplayTriggerRate();
+
+    if (fDisplay && fRawRunHeader->GetNumEvents())
+        fDisplay->SetProgressBarPosition((Float_t)fEvtNumber/fRawRunHeader->GetNumEvents());
+
+    return kTRUE;
+}
+
+Int_t MOnlineDump::PostProcess()
+{
+    if (fDisplay)
+        fDisplay->SetProgressBarPosition(1);
+
+    return kTRUE;
+}
Index: trunk/MagicSoft/Mars/mmain/MOnlineDump.h
===================================================================
--- trunk/MagicSoft/Mars/mmain/MOnlineDump.h	(revision 2564)
+++ trunk/MagicSoft/Mars/mmain/MOnlineDump.h	(revision 2564)
@@ -0,0 +1,53 @@
+#ifndef MARS_MOnlineDump
+#define MARS_MOnlineDump
+
+#ifndef MARS_MGTask
+#include "MGTask.h"
+#endif
+
+class MFillH;
+class MHCamera;
+class MRawEvtHeader;
+class MRawRunHeader;
+class MTime;
+class MParList;
+class MEventRate;
+
+class MOnlineDump : public MGTask
+{
+private:
+    MFillH *fFill1;
+    MFillH *fFill2;
+    MFillH *fFill3;
+
+    MHCamera *fCamEvent;
+
+    UInt_t fRunNumber;
+    UInt_t fEvtNumber;
+
+    MRawEvtHeader *fRawEvtHeader;
+    MRawRunHeader *fRawRunHeader;
+    MEventRate    *fRate;
+
+    MTime *fEvtTime;
+    Double_t fTime;
+
+    MParList *fPlist;
+
+    void SetNoContextMenu(TObject *c);
+    void DisplayTriggerRate();
+
+    Bool_t ProcessMessage(Int_t msg, Int_t submsg, Long_t mp1, Long_t mp2);
+
+    Int_t PreProcess(MParList *pList);
+    Int_t Process();
+    Int_t PostProcess();
+
+public:
+    MOnlineDump() : fPlist(NULL) { fName = "MOnlineDump"; }
+    ~MOnlineDump();
+
+    ClassDef(MOnlineDump, 0) // Task to fill a histogram with data from a parameter container
+};
+
+#endif
Index: trunk/MagicSoft/Mars/mmain/MainLinkDef.h
===================================================================
--- trunk/MagicSoft/Mars/mmain/MainLinkDef.h	(revision 2563)
+++ trunk/MagicSoft/Mars/mmain/MainLinkDef.h	(revision 2564)
@@ -14,4 +14,6 @@
 #pragma link C++ class MCameraDisplay+;
 #pragma link C++ class MEventDisplay+;
+#pragma link C++ class MOnlineDisplay+;
+#pragma link C++ class MOnlineDump+;
 
 #pragma link C++ class MGDisplayAdc+;
Index: trunk/MagicSoft/Mars/mmain/Makefile
===================================================================
--- trunk/MagicSoft/Mars/mmain/Makefile	(revision 2563)
+++ trunk/MagicSoft/Mars/mmain/Makefile	(revision 2564)
@@ -37,4 +37,6 @@
            MGDisplayAdc.cc \
 	   MEventDisplay.cc \
+	   MOnlineDisplay.cc \
+	   MOnlineDump.cc \
            MCameraDisplay.cc
 
Index: trunk/MagicSoft/Mars/mona.cc
===================================================================
--- trunk/MagicSoft/Mars/mona.cc	(revision 2563)
+++ trunk/MagicSoft/Mars/mona.cc	(revision 2564)
@@ -2,5 +2,8 @@
 
 #include <TThread.h>
+#include <TCanvas.h>
 #include <TMethod.h>          // GetMenuItems
+
+#include <TGButton.h>
 
 #include "MParList.h"
@@ -16,11 +19,15 @@
 #include "MFRealTimePeriod.h"
 #include "MHTriggerLvl0.h"
-#include "MHCamera.h"         // ::Class()
-
-#include "MStatusDisplay.h"
+#include "MHCamera.h"         // ::Class(), SetFreezed
+#include "MHCamEvent.h"       // MHCamEvent
+#include "MHEvent.h"          // MHEvent::GetHist()
+
+#include "MOnlineDump.h"
+#include "MOnlineDisplay.h"
 
 #include "MImgCleanStd.h"
 #include "MHillasCalc.h"
 #include "MHillasSrcCalc.h"
+#include "MEventRateCalc.h"
 
 #include "MArgs.h"
@@ -32,136 +39,5 @@
 #include "MRawRunHeader.h"       // MRawRunHeader
 
-class MOnlineDump : public MTask
-{
-private:
-    MFillH *fFill1;
-    MFillH *fFill2;
-    MFillH *fFill3;
-    MFRealTimePeriod *fFilter;
-
-    UInt_t fRunNumber;
-    UInt_t fEvtNumber;
-
-    MRawEvtHeader *fRawEvtHeader;
-    MRawRunHeader *fRawRunHeader;
-
-    MTime *fEvtTime;
-    Double_t fTime;
-
-    void SetNoContextMenu(TObject *c)
-    {
-        if (fDisplay->HasCanvas((TCanvas*)c))
-            c->ResetBit(kNoContextMenu);
-    }
-    void DisplayTriggerRate()
-    {
-        if (*fEvtTime==0)
-            fEvtTime->SetTime(gSystem->Now());
-    
-        if (fEvtNumber==0 || fRawRunHeader->GetRunNumber()!=fRunNumber)
-        {
-            fEvtNumber = fRawEvtHeader->GetDAQEvtNumber();
-            fRunNumber = fRawRunHeader->GetRunNumber();
-            fTime      = *fEvtTime;
-            return;
-        }
-    
-        const UInt_t  evts = fRawEvtHeader->GetDAQEvtNumber() - fEvtNumber;
-        const Double_t sec = *fEvtTime-fTime;
-    
-        if (evts>0 && sec>0 && fDisplay)
-            fDisplay->SetStatusLine2(Form("Trigger Rate: %.1fHz", evts/sec));
-    }
-
-public:
-    MOnlineDump() { fName = "MOnlineDump"; }
-    Int_t PreProcess(MParList *pList)
-    {
-        if (gROOT->IsBatch())
-        {
-            *fLog << err << "We are in batch mode!" << endl;
-            return kFALSE;
-        }
-        if (!fDisplay)
-        {
-            *fLog << err << "fDisplay not set." << endl;
-            return kFALSE;
-        }
-    
-        MTaskList *tasks = (MTaskList*)pList->FindObject("MTaskList");
-        if (!tasks)
-        {
-            *fLog << err << "MTaskList not found... abort." << endl;
-            return kFALSE;
-        }
-    
-        fFill1 = (MFillH*)tasks->FindObject("MFillCamEvent");
-        if (!fFill1)
-        {
-            *fLog << err << "MFillCamEvent not found... abort." << endl;
-            return kFALSE;
-        }
-        fFill2 = (MFillH*)tasks->FindObject("MFillEvent");
-        if (!fFill2)
-        {
-            *fLog << err << "MFillEvent not found... abort." << endl;
-            return kFALSE;
-        }
-        fFill3 = (MFillH*)tasks->FindObject("MFillTriggerLvl0");
-        if (!fFill3)
-        {
-            *fLog << err << "MFillTriggerLvl0 not found... abort." << endl;
-            return kFALSE;
-        }
-        fRawEvtHeader = (MRawEvtHeader*)pList->FindObject("MRawEvtHeader");
-        if (!fRawEvtHeader)
-        {
-            *fLog << err << "MRawEvtHeader not found... abort." << endl;
-            return kFALSE;
-        }
-    
-        fRawRunHeader = (MRawRunHeader*)pList->FindObject("MRawRunHeader");
-        if (!fRawRunHeader)
-        {
-            *fLog << err << "MRawRunHeader not found... abort." << endl;
-            return kFALSE;;
-        }
-    
-        fEvtTime = (MTime*)pList->FindObject("MRawEvtTime");
-        if (!fEvtTime)
-        {
-            *fLog << err << "MRawEvtTime not found... abort." << endl;
-            return kFALSE;
-        }
-    
-        fRunNumber = 0xffffffff;
-        fEvtNumber = 0;
-    
-        SetNoContextMenu((TObject*)fFill1->GetCanvas());
-        SetNoContextMenu((TObject*)fFill2->GetCanvas());
-        SetNoContextMenu((TObject*)fFill3->GetCanvas());
-    
-        return kTRUE;
-    }
-    Int_t Process()
-    {
-        DisplayTriggerRate();
-    
-        if (fDisplay)
-            fDisplay->SetProgressBarPosition((Float_t)fEvtNumber/fRawRunHeader->GetNumEvents());
-    
-        return kTRUE;
-    } 
-    Int_t PostProcess()
-    {
-        if (fDisplay)
-            fDisplay->SetProgressBarPosition(1);
-    
-        return kTRUE;
-    }
-//    ClassDef(MOnlineDump, 0) // Task to fill a histogram with data from a parameter container
-};
-//ClassImp(MOnlineDump);
-// --------------------------------------------------------------------
+using namespace std;
 
 void StartUpMessage()
@@ -213,6 +89,8 @@
 }
 
-Bool_t Loop(MStatusDisplay *display, Int_t port)
-{
+Bool_t Loop(MOnlineDisplay *display, Int_t port)
+{
+    display->Reset();
+
     //
     // create the tasks which should be executed and add them to the list
@@ -238,4 +116,8 @@
     tasks.AddToList(&ncalc);
 
+    MEventRateCalc tcalc;
+    tcalc.SetNumEvents(100);
+    tasks.AddToList(&tcalc);
+
     MFillH fill1("MHEvent",    "MCerPhotEvt", "MFillEvent");
     MFillH fill2("MHCamEvent", "MCerPhotEvt", "MFillCamEvent");
@@ -248,4 +130,5 @@
 
     tasks.AddToList(&filter);
+
     tasks.AddToList(&fill1);
     tasks.AddToList(&fill2);
@@ -254,5 +137,30 @@
     MOnlineDump dump;
     dump.SetFilter(&filter);
+    display->SetTask(&dump);
     tasks.AddToList(&dump);
+
+    MHCamEvent hist("PedestalRms");
+    hist.SetType(1);
+    plist.AddToList(&hist);
+
+    // -------------------------------------------
+
+    MHCamEvent maxhi("MaxIdxHi", "Index of slice with maximum content (hi-gain)");
+    MHCamEvent maxlo("MaxIdxLo", "Index of slice with maximum content (lo-gain)");
+    maxhi.SetType(3);
+    maxlo.SetType(4);
+    plist.AddToList(&maxhi);
+    plist.AddToList(&maxlo);
+
+    // -------------------------------------------
+
+    MFillH hfilla("MaxIdxHi", "MRawEvtData");
+    MFillH hfillb("MaxIdxLo", "MRawEvtData");
+    MFillH hfillc("Pedestals [MHCamEvent]", "MPedestalCam");
+    MFillH hfilld("PedestalRms", "MPedestalCam");
+    tasks.AddToList(&hfilla);
+    tasks.AddToList(&hfillb);
+    tasks.AddToList(&hfillc);
+    tasks.AddToList(&hfilld);
 
     MImgCleanStd      clean;
@@ -291,8 +199,6 @@
 void *thread(void *ptr)
 {
-    const Int_t port = *(Int_t*)ptr;
-
-    MStatusDisplay d;
-    d.Resize(740, 600);
+    const Int_t port = *((Int_t**)ptr)[0];
+    MOnlineDisplay &d = *((MOnlineDisplay**)ptr)[1];
 
     //
@@ -303,9 +209,7 @@
         Loop(&d, port);
 
-    gLog << dbg << "Exit System Loop... " << flush;
-    gSystem->ExitLoop();
-    gLog << "done." << endl;
-
-    TThread::Self()->Exit();
+
+    gLog << dbg << "Loop stopped... exit thread()" << endl;
+
     return 0;
 }
@@ -403,7 +307,16 @@
     // if the thread is terminated (by return)
     //
-    gLog << dbg << "Starting Thread..." << endl;
-    TThread t(thread, (void*)&port);
+    gLog << dbg << "Starting Display..." << flush;
+    MOnlineDisplay d;
+    d.SetBit(MStatusDisplay::kExitLoopOnExit);
+    gLog << "done." << endl;
+
+    // gDebug=1;
+
+    gLog << dbg << "Starting Thread..." << flush;
+    const void *ptr[2] = { &port, &d };
+    TThread t(thread, ptr);
     t.Run();
+    gLog << "done." << endl;
 
     gLog << dbg << "Starting System loop... " << endl;
@@ -411,4 +324,16 @@
     gLog << dbg << "System loop stopped." << endl;
 
+    d.UnmapWindow();
+
+    gLog << dbg << "Waiting for termination of thread... (be patient)" << endl;
+    while (t.GetState()!=TThread::kCanceledState)
+        gSystem->ProcessEvents();
+
+    gLog << dbg << "Thread terminated... joining." << endl;
+
+    TThread::Join(t.GetId()); //- seems that it is implicitly done... why?
+
+    gLog << dbg << "Exit MONA." << endl;
+
     return 0;
 }
