Index: trunk/MagicSoft/Mars/macros/rootlogon.C
===================================================================
--- trunk/MagicSoft/Mars/macros/rootlogon.C	(revision 1380)
+++ trunk/MagicSoft/Mars/macros/rootlogon.C	(revision 1381)
@@ -80,4 +80,17 @@
     load();
 
+    gInterpreter->AddIncludePath("macros");
+    gInterpreter->AddIncludePath("manalysis");
+    gInterpreter->AddIncludePath("mbase");
+    gInterpreter->AddIncludePath("mdata");
+    gInterpreter->AddIncludePath("mfileio");
+    gInterpreter->AddIncludePath("mfilter");
+    gInterpreter->AddIncludePath("mgui");
+    gInterpreter->AddIncludePath("mhist");
+    gInterpreter->AddIncludePath("mmain");
+    gInterpreter->AddIncludePath("mmc");
+    gInterpreter->AddIncludePath("mmontecarlo");
+    gInterpreter->AddIncludePath("mraw");
+
     cout << "Welcome to the Mars Root environment." << endl;
 
Index: trunk/MagicSoft/Mars/mfileio/FileIOIncl.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/FileIOIncl.h	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/FileIOIncl.h	(revision 1381)
@@ -0,0 +1,3 @@
+#ifndef __CINT__
+
+#endif // __CINT__
Index: trunk/MagicSoft/Mars/mfileio/MCT1ReadAscii.cc
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MCT1ReadAscii.cc	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/MCT1ReadAscii.cc	(revision 1381)
@@ -0,0 +1,295 @@
+/* ======================================================================== *\
+!
+! *
+! * 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  12/2000 <mailto:tbretz@uni-sw.gwdg.de>
+!   Author(s): Harald Kornmayer 1/2001 (harald@mppmu.mpg.de)
+!
+!   Copyright: MAGIC Software Development, 2000-2001
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// MCT1ReadAscii                                                           //
+//                                                                         //
+// Reads a ascii file with CT1 data. The file description and some example //
+// files can be found on the Magic homepage.                               //
+//                                                                         //
+//  Input Containers:                                                      //
+//   -/-                                                                   //
+//                                                                         //
+//  Output Containers:                                                     //
+//   MCerPhotEvt                                                           //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+#include "MCT1ReadAscii.h"
+
+#include <fstream.h>
+
+#include <TList.h>
+#include <TSystem.h>
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+#include "MCerPhotEvt.h"
+#include "MPedestalCam.h"
+
+ClassImp(MCT1ReadAscii);
+
+// --------------------------------------------------------------------------
+//
+// Default constructor. Creates an array which stores the file names of
+// the files which should be read. If a filename is given it is added
+// to the list.
+//
+MCT1ReadAscii::MCT1ReadAscii(const char *fname,
+			     const char *name, 
+                             const char *title)
+    : fIn(NULL)
+{
+    fName  = name  ? name  : "MCT1ReadAscii";
+    fTitle = title ? title : "Task to loop over events in CT1 ascii file";
+
+    //
+    // remember file name for opening the file in the preprocessor
+    //
+    fFileNames = new TList;
+    fFileNames->SetOwner();
+
+    if (fname)
+        AddFile(fname);
+}
+
+// --------------------------------------------------------------------------
+//
+// Delete the filename list and the input stream if one exists.
+//
+MCT1ReadAscii::~MCT1ReadAscii()
+{
+    delete fFileNames;
+    if (fIn)
+        delete fIn;
+}
+
+// --------------------------------------------------------------------------
+//
+// Add this file as the last entry in the chain
+//
+void MCT1ReadAscii::AddFile(const char *txt)
+{
+    TNamed *name = new TNamed(txt, "");
+    fFileNames->AddLast(name);
+}
+
+// --------------------------------------------------------------------------
+//
+// This opens the next file in the list and deletes its name from the list.
+//
+Bool_t MCT1ReadAscii::OpenNextFile()
+{
+    //
+    // open the input stream and check if it is really open (file exists?)
+    //
+    if (fIn)
+        delete fIn;
+    fIn = NULL;
+
+    //
+    // Check for the existance of a next file to read
+    //
+    TNamed *file = (TNamed*)fFileNames->First();
+    if (!file)
+        return kFALSE;
+
+    //
+    // open the file which is the first one in the chain
+    //
+    const char *name = file->GetName();
+
+    fIn = new ifstream(gSystem->ExpandPathName(name));
+
+    const Bool_t noexist = !(*fIn);
+
+    if (noexist)
+        *fLog << dbginf << "Cannot open file '" << name << "'" << endl;
+    else
+        *fLog << "Open file: '" << name << "'" << endl;
+
+    //
+    // Remove this file from the list of pending files
+    //
+    fFileNames->Remove(file);
+
+    return !noexist;
+}
+
+// --------------------------------------------------------------------------
+//
+// Open the first file in the list. Check for the output containers or create
+// them if they don't exist.
+//
+// Initialize the size of the MPedestalCam container to 127 pixels (CT1 camera)
+//
+Bool_t MCT1ReadAscii::PreProcess(MParList *pList)
+{
+    //
+    // Preprocessing
+    //
+
+    //
+    // Try to open at least one (the first) file
+    //
+    if (!OpenNextFile())
+        return kFALSE;
+
+    //
+    //  look for the MCerPhotEvt class in the plist
+    //
+    fNphot = (MCerPhotEvt*)pList->FindCreateObj("MCerPhotEvt");
+    if (!fNphot)
+        return kFALSE;
+
+    //
+    //  look for the pedestal class in the plist
+    //
+    fPedest = (MPedestalCam*)pList->FindCreateObj("MPedestalCam");
+    if (!fPedest)
+        return kFALSE;
+
+    fPedest->InitSize(127);
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Read apedestal entry (line) from the file
+//
+void MCT1ReadAscii::ReadPedestals()
+{
+    //
+    // skip the next 4 values
+    //
+    Float_t val;
+
+    *fIn >> val;
+    *fIn >> val;
+    *fIn >> val;
+    *fIn >> val;
+
+    //
+    //    read in the next 127 numbers as the pedestals
+    //
+    for (Int_t i = 0; i<127; i++)
+    {
+        *fIn >> val;
+
+        if (val > 0.0)
+            (*fPedest)[i].SetMeanRms(val);
+    }
+}
+
+// --------------------------------------------------------------------------
+//
+// Read a data entry (line) from the file
+//
+void MCT1ReadAscii::ReadData()
+{
+    //
+    // clear the list of cerphot-events
+    //
+    fNphot->Clear();
+
+    //
+    // five unsused numbers
+    //
+    Int_t val;
+
+    *fIn >> val;   // ener
+    *fIn >> val;   // zenang
+    *fIn >> val;   // sec1
+    *fIn >> val;   // sec2
+
+    //
+    // read in the number of cerenkov photons and add the 'new' pixel
+    // too the list with it's id, number of photons and error
+    //
+    fNphot->InitSize(127);
+
+    for (Int_t i = 0; i<127; i++ )
+    {
+        Float_t nphot;
+
+        *fIn >> nphot;
+
+        if (nphot > 0.0)
+            fNphot->AddPixel(i, nphot, (*fPedest)[i].GetMeanRms());
+    }
+
+}
+
+// --------------------------------------------------------------------------
+//
+// Check for the event number and depending on this number decide if
+// pedestals or event data has to be read.
+//
+// If the end of the file is reached try to open the next in the list. If
+// there is now next file stop the eventloop.
+//
+Bool_t MCT1ReadAscii::Process()
+{
+    //
+    // FIXME. This function should switch between reading pedestals and
+    // reading event data by the 'switch entry'.
+    // After reading it should set the InputStreamID correctly.
+    // ( should use MPedestalCam )
+    //
+ 
+    //
+    // read in the event nr
+    //
+    Int_t evtnr;
+    *fIn >> evtnr;
+
+    //
+    // check if we are done. Try to open the next file in chain.
+    // If it was possible start reading. If not break the event loop
+    //
+    if (fIn->eof())
+        return OpenNextFile() ? kCONTINUE : kFALSE;
+
+    //
+    // if the first number is negativ this is a pedestal line:
+    // read in pedestals
+    //
+    // FIXME! Set InputStreamID
+
+    if (evtnr < 0)
+    {
+        ReadPedestals();
+        return kCONTINUE;
+    }
+
+    ReadData();
+
+    return kTRUE;
+}
+
Index: trunk/MagicSoft/Mars/mfileio/MCT1ReadAscii.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MCT1ReadAscii.h	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/MCT1ReadAscii.h	(revision 1381)
@@ -0,0 +1,41 @@
+#ifndef MARS_MCT1ReadAscii
+#define MARS_MCT1ReadAscii
+
+#ifndef MARS_MTask
+#include "MTask.h"
+#endif
+
+class TList;
+class MCerPhotEvt;
+class MPedestalCam;
+
+class MCT1ReadAscii : public MTask
+{
+private:
+    ifstream     *fIn;          // the inputfile
+    MCerPhotEvt  *fNphot;       // the data container for all data.
+    MPedestalCam *fPedest;      // ct1 pedestals
+    TList        *fFileNames;   // Array which stores the \0-terminated filenames
+
+    Bool_t OpenNextFile();
+
+    void ReadPedestals();
+    void ReadData();
+
+public:
+    MCT1ReadAscii(const char *filename=NULL,
+                  const char *name=NULL,
+                  const char *title=NULL);
+
+    ~MCT1ReadAscii();
+
+    void AddFile(const char *fname);
+
+    Bool_t PreProcess(MParList *pList);
+    Bool_t Process();
+
+    ClassDef(MCT1ReadAscii, 0)	// Reads the CT1 data file
+};
+
+#endif
+
Index: trunk/MagicSoft/Mars/mfileio/MReadMarsFile.cc
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MReadMarsFile.cc	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/MReadMarsFile.cc	(revision 1381)
@@ -0,0 +1,194 @@
+/* ======================================================================== *\
+!
+! *
+! * 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  12/2000 <mailto:tbretz@uni-sw.gwdg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// MReadMarsFile                                                           //
+//                                                                         //
+// This task works more or less like MReadTree, but in addition PreProcess //
+// reads all the information from the 'RunHeader' tree.                    //
+//                                                                         //
+// Warning: Until now this works only for 'one run header per file'        //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+#include "MReadMarsFile.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+#include "MTaskList.h"
+
+#include "MRawRunHeader.h"
+
+#include "MMcRunHeader.hxx"
+
+ClassImp(MReadMarsFile);
+
+// --------------------------------------------------------------------------
+//
+//  Default constructor. It creates a MReadTree object to read the
+//  RunHeaders and disables Auto Scheme for this tree.
+//
+MReadMarsFile::MReadMarsFile(const char *tname, const char *fname,
+                             const char *name, const char *title)
+    : MReadTree(tname, fname)
+{
+    fName  = name  ? name  : "MReadMarsFile";
+    fTitle = title ? title : "Task to loop over all events in a tree of a Mars file.";
+
+    //
+    // open the input stream
+    //
+    fRun = new MReadTree("RunHeaders", fname, "ReadRunHeaders");
+
+    //
+    // This disables the auto scheme. because reading new runheader is done
+    // at a low frequency we don't loose time if we always read all
+    // runheaders
+    //
+    fRun->DisableAutoScheme();
+}
+
+// --------------------------------------------------------------------------
+//
+// Destructor. Deleted the MReadTree object for the RunHeaders
+//
+MReadMarsFile::~MReadMarsFile()
+{
+    delete fRun;
+}
+
+// --------------------------------------------------------------------------
+//
+//  see MReadTree::AddFile, too. The file is also added to the chain for
+//  the run headers. If adding file gives a different result for both
+//  chains -1 is returned, otherwise the number of files which were added.
+//
+Int_t MReadMarsFile::AddFile(const char *fname)
+{
+    //
+    // FIXME! A check is missing whether the file already exists or not.
+    //
+    //
+    // returns the number of file which were added
+    //
+    Int_t n1 = fRun->AddFile(fname);
+    Int_t n2 = MReadTree::AddFile(fname);
+
+    return n1 != n2 ? -1 : n1;
+}
+
+// --------------------------------------------------------------------------
+//
+//  This overload MReadTree::Notify. Before the MReadTree Notify
+//  TObjects are called the RunHeaders of the next files are read.
+//  
+//  WARNING: This doesn't work correctly yet, if the files are not read in
+//           increasing order.
+//
+Bool_t MReadMarsFile::Notify()
+{
+    Int_t runtype = -1;
+
+    const MRawRunHeader *rawheader = (MRawRunHeader*)fParList->FindObject("MRawRunHeader");
+    if (rawheader)
+        runtype = rawheader->GetRunType();
+
+    //
+    // Try to read the new run headers. If reading the new run header
+    // was successfull call the ReInits
+    //
+    const Int_t idx = GetFileIndex();
+    fRun->SetEventNum(idx<0?0:idx); // Assumption: One Entry per File!
+    if (!fRun->Process())
+    {
+        *fLog << err << "ERROR - Cannot read new runheaders #" << idx;
+        *fLog << " after reading event #" << GetEventNum() << endl;
+        return kFALSE;
+    }
+
+    *fLog << inf << "MReadMarsFile: Switching to #" << GetFileIndex();
+    *fLog << " '" << GetFileName() << "' (before event #";
+    *fLog << GetEventNum()-1 << ")" << endl;
+
+    if (rawheader)
+    {
+        if (runtype != rawheader->GetRunType())
+            *fLog << warn << "Warning - You are mixing files with different run types!" << endl;
+    }
+
+    const MMcRunHeader *mcheader = (MMcRunHeader*)fParList->FindObject("MMcRunHeader");
+    if (mcheader)
+    {
+        if (mcheader->GetReflVersion()<=40 && mcheader->GetTelesTheta()>15)
+        {
+            *fLog << warn << "Warning - You may use Monte Carlo data produced with a version" << endl;
+            *fLog << "of the reflector program < 0.4 and a zenith angle > 15," << endl;
+            *fLog << "in this case you may get less photons than you would expect." << endl;
+        }
+    }
+
+    MTaskList *tlist = (MTaskList*)fParList->FindObject("MTaskList");
+    if (!tlist)
+    {
+        *fLog << err << dbginf << "ERROR - Task List not found in Parameter List." << endl;
+        return kFALSE;
+    }
+
+    if (tlist->ReInit())
+        return kTRUE;
+
+    //MReadTree::Notify();
+
+    *fLog << err << "ERROR - ReInit of '" << tlist->GetName() << "' failed." << endl;
+    return kFALSE;
+}
+
+// --------------------------------------------------------------------------
+//
+//  PreProcessed the MReadTree to read the run headers and its base class.
+//  see MReadTree::PreProcess for more information
+//
+Bool_t MReadMarsFile::PreProcess(MParList *pList)
+{
+    fParList  = pList;
+
+    if (!fRun->PreProcess(pList))
+    {
+        *fLog << err << "Error - PreProcessing MReadMarsFile::fRun... aborting." << endl;
+        return kFALSE;
+    }
+
+    const Int_t idx = GetFileIndex();
+    fRun->SetEventNum(idx<0?0:idx); // Assumption: One Entry per File!
+    if (!fRun->Process())
+    {
+        *fLog << err << "Error - Processing MReadMarsFile::fRun... aborting." << endl;
+        return kFALSE;
+    }
+
+    return MReadTree::PreProcess(pList);
+}
Index: trunk/MagicSoft/Mars/mfileio/MReadMarsFile.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MReadMarsFile.h	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/MReadMarsFile.h	(revision 1381)
@@ -0,0 +1,30 @@
+#ifndef MARS_MReadMarsFile
+#define MARS_MReadMarsFile
+
+#ifndef MARS_MReadTree
+#include "MReadTree.h"
+#endif
+
+class MParList;
+class MTaskList;
+
+class MReadMarsFile : public MReadTree
+{
+private:
+    MReadTree *fRun;
+    MParList  *fParList;  //! Parlist for reinitialization
+
+    Bool_t Notify();
+
+    Bool_t PreProcess(MParList *pList);
+  
+public:
+    MReadMarsFile(const char *treename, const char *filename=NULL, const char *name=NULL, const char *title=NULL);
+    ~MReadMarsFile();
+
+    Int_t AddFile(const char *fname);
+
+    ClassDef(MReadMarsFile, 0)	// Reads a tree from file(s)
+};
+
+#endif
Index: trunk/MagicSoft/Mars/mfileio/MReadTree.cc
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MReadTree.cc	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/MReadTree.cc	(revision 1381)
@@ -0,0 +1,801 @@
+/* ======================================================================== *\
+!
+! *
+! * 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  12/2000 <mailto:tbretz@uni-sw.gwdg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// MReadTree                                                               //
+//                                                                         //
+// This tasks opens all branches in a specified tree and creates the       //
+// corresponding parameter containers if not already existing in the       //
+// parameter list.                                                         //
+//                                                                         //
+// The Process function reads one events from the tree. To go through the  //
+// events of one tree make sure that the event number is increased from    //
+// outside. It makes also possible to go back by decreasing the number.    //
+//                                                                         //
+// If you don't want to start reading the first event you have to call     //
+// MReadTree::SetEventNum after instantiating your MReadTree-object.       //
+//                                                                         //
+// To make reading much faster (up to a factor of 10 to 20) you can        //
+// ensure that only the data you are really processing is enabled by       //
+// calling MReadTree::UseLeaf.                                             //
+//                                                                         //
+// If the chain switches from one file to another file all                 //
+// TObject::Notify() functions are called of TObject objects which were    //
+// added to the Notifier list view MReadTree::AddNotify. If MReadTree      //
+// is the owner (viw MReadTree::SetOwner) all this objects are deleted     //
+// by the destructor of MReadTree                                          //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+#include "MReadTree.h"
+
+#include <fstream.h>
+
+#include <TFile.h>           // TFile::GetName
+#include <TChain.h>
+#include <TSystem.h>         // gSystem->ExpandPath
+#include <TGProgressBar.h>
+#include <TChainElement.h>
+#include <TOrdCollection.h>
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MTime.h"
+#include "MFilter.h"
+#include "MParList.h"
+#include "MTaskList.h"
+
+ClassImp(MReadTree);
+
+class MChain : public TChain
+{
+private:
+    Bool_t fNotified;
+
+public:
+    MChain() : TChain(), fNotified(kFALSE) {}
+    MChain(const char *name, const char *title="") : TChain(name, title), fNotified(kFALSE) {}
+
+    void ResetTree() { fTree = 0; }
+
+    virtual Bool_t Notify() { fNotified = kTRUE; return kTRUE; }
+    virtual void   SetNotify(TObject *obj) { fNotify = obj; fNotified = kFALSE; }
+
+    Int_t LoadTree(Int_t entry)
+    {
+        //
+        // This is the code from TChain::LoadTree but skips the
+        // notification in LoadTree. If LoadTree raises the notification
+        // a flag is set and the notification is done by hand. If it
+        // has not been successfull -15 is returned.
+        // This is to support return values from Notify()/Reinit()
+        //
+        TObject *notify = GetNotify();
+
+        SetNotify(this);
+
+        Int_t rc = TChain::LoadTree(entry);
+
+        if (rc >= 0 && fNotified && notify)
+            if (!notify->Notify())
+                rc = -15;
+
+        SetNotify(notify);
+
+        return rc;
+    }
+};
+
+// --------------------------------------------------------------------------
+//
+//  Default constructor. It creates an TChain instance which represents the
+//  the Tree you want to read and adds the given file (if you gave one).
+//  More files can be added using MReadTree::AddFile.
+//  Also an empty veto list is created. This list is used if you want to
+//  veto (disable or "don't enable") a branch in the tree, it vetos also
+//  the creation of the corresponding object.
+//  An empty list of TObjects are also created. This objects are called
+//  at any time the TChain starts to read from another file.
+//
+MReadTree::MReadTree(const char *tname, const char *fname,
+                     const char *name, const char *title)
+    : fNumEntry(0), fBranchChoosing(kFALSE), fAutoEnable(kTRUE), fProgress(NULL)
+{
+    fName  = name  ? name  : "MReadTree";
+    fTitle = title ? title : "Task to loop over all events in one single tree";
+
+    fVetoList = new TList;
+    fVetoList->SetOwner();
+
+    fNotify = new TList;
+
+    //
+    // open the input stream
+    //
+    fChain = new MChain(tname);
+
+    // root 3.02:
+    // In TChain::Addfile remove the limitation that the file name must contain
+    // the string ".root". ".root" is necessary only in case one wants to specify
+    // a Tree in a subdirectory of a Root file with eg, the format:
+
+    if (fname)
+        fChain->Add(fname);
+}
+
+// --------------------------------------------------------------------------
+//
+// Destructor. It deletes the TChain and veto list object
+//
+MReadTree::~MReadTree()
+{
+    //
+    // Delete all the pointers to pointers to the objects where the
+    // branche data gets stored.
+    //
+    TIter Next(fChain->GetStatus());
+
+    TChainElement *element = NULL;
+    while ((element=(TChainElement*)Next()))
+        delete (MParContainer**)element->GetBaddress();
+
+    //
+    // Delete the chain and the veto list
+    //
+#if ROOT_VERSION_CODE < ROOT_VERSION(3,03,00)
+    if (fChain->GetFile())
+        delete fChain->GetFile();
+#endif
+    delete fChain;
+
+    delete fNotify;
+    delete fVetoList;
+}
+
+// --------------------------------------------------------------------------
+//
+//  If the owner flag is set all TObjects which are scheduled via
+//  AddNotify are deleted by the destructor of MReadTree
+//
+void MReadTree::SetOwner(Bool_t flag)
+{
+    flag ? fNotify->SetBit(kIsOwner) : fNotify->ResetBit(kIsOwner);
+}
+
+// --------------------------------------------------------------------------
+//
+//  This function is called each time MReadTree changes the file to read
+//  from. It calls all TObject::Notify() functions which are scheduled
+//  via AddNotify.
+//
+Bool_t MReadTree::Notify()
+{
+    *fLog << inf << GetDescriptor() << ": Notify '" << fChain->GetName();
+    *fLog << "' (before processing event #" << GetEventNum()-1 << ")" << endl;
+
+    //fNotify->Notify();
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+//  If you want to read the given tree over several files you must add
+//  the files here before PreProcess is called. Be careful: If the tree
+//  doesn't have the same contents (branches) it may confuse your
+//  program (trees which are are not existing in later files are not read
+//  anymore, tree wich are not existing in the first file are never read)
+//
+//  Name may use the wildcarding notation, eg "xxx*.root" means all files
+//  starting with xxx in the current file system directory.
+//
+//  AddFile returns the number of files added to the chain.
+//
+Int_t MReadTree::AddFile(const char *fname)
+{
+    //
+    // FIXME! A check is missing whether the file already exists or not.
+    //
+    //
+    // returns the number of file which were added
+    //
+    return fChain->Add(fname);
+}
+
+// --------------------------------------------------------------------------
+//
+//  This function is called if Branch choosing method should get enabled.
+//  Branch choosing means, that only the enabled branches are read into
+//  memory. To use an enableing scheme we have to disable all branches first.
+//  This is done, if this function is called the first time.
+//
+void MReadTree::EnableBranchChoosing()
+{
+    if (fBranchChoosing)
+        return;
+
+    *fLog << inf << GetDescriptor() << ": Branch choosing method enabled (only enabled branches are read)." << endl;
+    fChain->SetBranchStatus("*", kFALSE);
+    fBranchChoosing = kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// The first time this function is called all branches are disabled.
+// The given branch is enabled. By enabling only the branches you
+// are processing you can speed up your calculation many times (up to
+// a factor of 10 or 20)
+//
+void MReadTree::EnableBranch(const char *name)
+{
+    EnableBranchChoosing();
+
+    TNamed branch(name, "");
+    SetBranchStatus(&branch, kTRUE);
+}
+
+// --------------------------------------------------------------------------
+//
+// Set branch status of branch name
+//
+void MReadTree::SetBranchStatus(const char *name, Bool_t status)
+{
+    fChain->SetBranchStatus(name, status);
+
+    *fLog << inf << (status ? "Enabled" : "Disabled");
+    *fLog << " subbranch '" << name << "'." << endl;
+}
+
+// --------------------------------------------------------------------------
+//
+// Checks whether a branch with the given name exists in the chain
+// and sets the branch status of this branch corresponding to status.
+//
+void MReadTree::SetBranchStatus(TObject *branch, Bool_t status)
+{
+    //
+    // Get branch name
+    //
+    const char *name = branch->GetName();
+
+    //
+    // Check whether this branch really exists
+    //
+    if (fChain->GetBranch(name))
+        SetBranchStatus(name, status);
+
+    //
+    // Remove trailing '.' if one and try to enable the subbranch without
+    // the master branch name. This is to be compatible with older mars
+    // and camera files.
+    //
+    const char *dot = strrchr(name, '.');
+    if (!dot)
+        return;
+
+    if (fChain->GetBranch(dot+1))
+        SetBranchStatus(dot+1, status);
+}
+
+// --------------------------------------------------------------------------
+//
+// Set the status of all branches in the list to status.
+//
+void MReadTree::SetBranchStatus(const TList *list, Bool_t status)
+{
+    //
+    // Loop over all subbranches in this master branch
+    //
+    TIter Next(list);
+
+    TObject *obj;
+    while ((obj=Next()))
+        SetBranchStatus(obj, status);
+}
+
+// --------------------------------------------------------------------------
+//
+//  This is the implementation of the Auto Enabling Scheme.
+//  For more information see MTask::AddBranchToList.
+//  This function loops over all tasks and its filters in the tasklist
+//  and enables all branches which are requested by the tasks and its
+//  filters.
+//
+//  To enable 'unknown' branches which are not in the branchlist of
+//  the tasks you can call EnableBranch
+//
+void MReadTree::EnableBranches(MParList *plist)
+{
+    //
+    // check whether branch choosing must be switched on
+    //
+    EnableBranchChoosing();
+
+    //
+    // request the tasklist from the parameter list.
+    // FIXME: Tasklist can have a different name
+    //
+    const MTaskList *tlist = (MTaskList*)plist->FindObject("MTaskList");
+    if (!tlist)
+    {
+        *fLog << warn << GetDescriptor() << "Cannot use auto enabeling scheme for branches. 'MTaskList' not found." << endl;
+        return;
+    }
+
+    //
+    // This loop is not necessary. We could do it like in the commented
+    // loop below. But this loop makes sure, that we don't try to enable
+    // one branch several times. This would not harm, but we would get
+    // an output for each attempt. To have several outputs for one subbranch
+    // may confuse the user, this we don't want.
+    // This loop creates a new list of subbranches and for each branch
+    // which is added we check before whether it already exists or not.
+    //
+    TList list;
+
+    MTask *task;
+    TIter NextTask(tlist->GetList());
+    while ((task=(MTask*)NextTask()))
+    {
+        TObject *obj;
+
+        TIter NextTBranch(task->GetListOfBranches());
+        while ((obj=NextTBranch()))
+            if (!list.FindObject(obj->GetName()))
+                list.Add(obj);
+
+        const MFilter *filter = task->GetFilter();
+
+        if (!filter)
+            continue;
+
+        TIter NextFBranch(filter->GetListOfBranches());
+        while ((obj=NextFBranch()))
+            if (!list.FindObject(obj->GetName()))
+                list.Add(obj);
+    }
+
+    SetBranchStatus(&list, kTRUE);
+/*
+    //
+    // Loop over all tasks iand its filters n the task list.
+    //
+    MTask *task;
+    TIter NextTask(tlist->GetList());
+    while ((task=(MTask*)NextTask()))
+    {
+        SetBranchStatus(task->GetListOfBranches(), kTRUE);
+
+        const MFilter *filter = task->GetFilter();
+        if (!filter)
+           continue;
+
+        SetBranchStatus(filter->GetListOfBranches(), kTRUE);
+
+    }
+*/
+}
+
+// --------------------------------------------------------------------------
+//
+//  The disables all subbranches of the given master branch.
+//
+void MReadTree::DisableSubBranches(TBranch *branch)
+{
+    //
+    // This is not necessary, it would work without. But the output
+    // may confuse the user...
+    //
+    if (fAutoEnable || fBranchChoosing)
+        return;
+
+    SetBranchStatus(branch->GetListOfBranches(), kFALSE);
+}
+
+// --------------------------------------------------------------------------
+//
+//  The PreProcess loops (till now) over the branches in the given tree.
+//  It checks if the corresponding containers (containers with the same
+//  name than the branch name) are existing in the Parameter Container List.
+//  If not, a container of objec type 'branch-name' is created (everything
+//  after the last semicolon in the branch name is stripped). Only
+//  branches which don't have a veto (see VetoBranch) are enabled If the
+//  object isn't found in the root dictionary (a list of classes known by the
+//  root environment) the branch is skipped and an error message is printed
+//  out.
+//
+Bool_t MReadTree::PreProcess(MParList *pList)
+{
+    //
+    // Make sure, that all the following calls doesn't result in
+    // Notifications. This may be dangerous, because the notified
+    // tasks are not preprocessed.
+    //
+    fChain->SetNotify(NULL);
+
+    //
+    // get number of events in this tree
+    //
+    fNumEntries = (UInt_t)fChain->GetEntries();
+
+    if (!fNumEntries)
+    {
+        *fLog << warn << dbginf << "No entries found in file(s)" << endl;
+        return kFALSE;
+    }
+
+    //
+    // output logging information
+    //
+    *fLog << inf << fNumEntries << " entries found in file(s)." << endl;
+
+    //
+    // Get all branches of this tree and
+    // create the Iterator to loop over all branches
+    //
+    TIter Next(fChain->GetListOfBranches());
+    TBranch *branch=NULL;
+
+    Int_t num=0;
+    //
+    // loop over all tasks for processing
+    //
+    while ( (branch=(TBranch*)Next()) )
+    {
+        //
+        // Get Name of Branch and Object
+        //
+        const char *bname = branch->GetName();
+
+        TString oname(bname);
+        if (oname.EndsWith("."))
+            oname.Remove(oname.Length()-1);
+
+        //
+        // Check if enabeling the branch is allowed
+        //
+        if (fVetoList->FindObject(oname))
+        {
+            *fLog << inf << "Master branch " << bname << " has veto... skipped." << endl;
+            DisableSubBranches(branch);
+            continue;
+        }
+
+        //
+        // Create a pointer to the pointer to the object in which the
+        // branch data is stored. The pointers are stored in the TChain
+        // object and we get the pointers from there to delete it.
+        //
+        MParContainer **pcont= new MParContainer*;
+
+#if ROOT_VERSION_CODE < ROOT_VERSION(3,02,06)
+        const char *classname = oname;
+#else
+        const char *classname = branch->GetClassName();
+#endif
+
+        //
+        // check if object is existing in the list
+        //
+        *pcont=pList->FindCreateObj(classname, oname);
+
+        if (!*pcont)
+        {
+            //
+            // if class is not existing in the (root) environment
+            // we cannot proceed reading this branch
+            //
+            *fLog << warn << dbginf << "Warning: Class '" << classname;
+            *fLog << "' for " << oname << " not existing in dictionary. Branch skipped." << endl;
+            DisableSubBranches(branch);
+            continue;
+        }
+
+        //
+        // Check whether a Pointer to a pointer already exists, if
+        // we created one already delete it.
+        //
+        TChainElement *element = (TChainElement*)fChain->GetStatus()->FindObject(bname);
+        if (element)
+            delete (MParContainer**)element->GetBaddress();
+
+        //
+        // here pcont is a pointer the to container in which the data from
+        // the actual branch should be stored - enable branch.
+        //
+        fChain->SetBranchAddress(bname, pcont);
+
+        *fLog << inf << "Master branch address " << bname << " [";
+        *fLog << classname << "] setup for reading." << endl;
+
+        //*fLog << "Branch " << bname << " autodel: " << (int)branch->IsAutoDelete() << endl;
+        //branch->SetAutoDelete();
+
+        num++;
+    }
+
+    *fLog << inf << GetDescriptor() << " setup " << num << " master branches addresses." << endl;
+
+    //
+    // If auto enabling scheme isn't disabled, do auto enabling
+    //
+    if (fAutoEnable)
+        EnableBranches(pList);
+
+    //
+    // If a progress bar is given set its range.
+    //
+    if (fProgress)
+        fProgress->SetRange(0, fNumEntries);
+
+    //
+    // Now we can start notifying. Reset tree makes sure, that TChain thinks
+    // that the correct file is not yet initialized and reinitilizes it
+    // as soon as the first event is read. This is necessary to call
+    // the notifiers when the first event is read, but after the
+    // PreProcess-function.
+    //
+    fChain->ResetTree();
+    fChain->SetNotify(this);
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+//  Set the ready to save flag of all containers which branchaddresses are
+//  set for. This is necessary to copy data.
+//
+void MReadTree::SetReadyToSave(Bool_t flag)
+{
+    TIter Next(fChain->GetStatus());
+
+    TChainElement *element = NULL;
+    while ((element=(TChainElement*)Next()))
+    {
+        //
+        // Check whether the branch is enabled
+        //
+        if (!element->GetStatus())
+            continue;
+
+        //
+        // Get the pointer to the pointer of the corresponding container
+        //
+        MParContainer **pcont = (MParContainer**)element->GetBaddress();
+
+        //
+        // Check whether the pointer is not NULL
+        //
+        if (!pcont || !*pcont)
+            continue;
+
+        //
+        // Set the ready to save status of the container.
+        //
+        (*pcont)->SetReadyToSave(flag);
+    }
+
+    //
+    // Set the ready to save status of this task (used?), too
+    //
+    MTask::SetReadyToSave(flag);
+}
+
+// --------------------------------------------------------------------------
+//
+//  The Process-function reads one event from the tree (this contains all
+//  enabled branches) and increases the position in the file by one event.
+//  (Remark: The position can also be set by some member functions
+//  If the end of the file is reached the Eventloop is stopped.
+//
+#if ROOT_VERSION_CODE < ROOT_VERSION(3,02,06)
+#include "MRawEvtData.h"
+#endif
+Bool_t MReadTree::Process()
+{
+    //
+    // This is necessary due to a bug in TChain::LoadTree in root.
+    // will be fixed in 3.03
+    //
+#if ROOT_VERSION_CODE < ROOT_VERSION(3,03,01)
+    if (fNumEntry >= fNumEntries)
+        return kFALSE;
+#endif
+
+#if ROOT_VERSION_CODE < ROOT_VERSION(3,02,06)
+    //
+    // This fixes 99.9% of a memory leak using a root version prior
+    // to 3.02/??
+    //
+    TChainElement *element=NULL;
+    TIter Next(fChain->GetStatus());
+    while ((element=(TChainElement*)Next()))
+    {
+        MParContainer **c = (MParContainer**)element->GetBaddress();
+        if (!c) continue;
+        if ((*c)->InheritsFrom(MRawEvtData::Class()))
+            ((MRawEvtData*)(*c))->DeletePixels(kFALSE);
+
+    }
+#endif
+
+    Bool_t rc = fChain->GetEntry(fNumEntry++) != 0;
+
+    if (rc)
+        SetReadyToSave();
+
+    return rc;
+}
+
+// --------------------------------------------------------------------------
+//
+// Get the Event with the current EventNumber fNumEntry
+//
+Bool_t MReadTree::GetEvent()
+{
+    Bool_t rc = fChain->GetEntry(fNumEntry) != 0;
+
+    if (rc)
+        SetReadyToSave();
+
+    return rc;
+}
+
+// --------------------------------------------------------------------------
+//
+// Decrease the number of the event which is read by Process() next
+// by one or more
+//
+Bool_t MReadTree::DecEventNum(UInt_t dec)
+{
+    if (fNumEntry-dec >= fNumEntries)
+    {
+        *fLog << warn << GetDescriptor() << ": DecEventNum, WARNING - Event " << fNumEntry << "-";
+        *fLog << dec << "=" << (Int_t)fNumEntry-dec << " out of Range." << endl;
+        return kFALSE;
+    }
+
+    fNumEntry -= dec;
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Increase the number of the event which is read by Process() next
+// by one or more
+//
+Bool_t MReadTree::IncEventNum(UInt_t inc)
+{
+    if (fNumEntry+inc >= fNumEntries)
+    {
+        *fLog << warn << GetDescriptor() << ": IncEventNum, WARNING - Event " << fNumEntry << "+";
+        *fLog << inc << "=" << (Int_t)fNumEntry+inc << " out of Range." << endl;
+        return kFALSE;
+    }
+
+    fNumEntry += inc;
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// This function makes Process() read event number nr next
+//
+// Remark: You can use this function after instatiating you MReadTree-object
+//         to set the event number from which you want to start reading.
+//
+Bool_t MReadTree::SetEventNum(UInt_t nr)
+{
+    if (nr >= fNumEntries)
+    {
+        *fLog << warn << GetDescriptor() << ": SetEventNum, WARNING - " << nr << " out of Range." << endl;
+        return kFALSE;
+    }
+
+    fNumEntry = nr;
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+//  For the branch with the given name:
+//   1) no object is automatically created
+//   2) the branch address for this branch is not set
+//      (because we lack the object, see 1)
+//   3) The whole branch (exactly: all its subbranches) are disabled
+//      this means are not read in memory by TTree:GetEntry
+//
+void MReadTree::VetoBranch(const char *name)
+{
+    fVetoList->Add(new TNamed(name, ""));
+}
+
+// --------------------------------------------------------------------------
+//
+//  Return the name of the file we are actually reading from.
+//
+TString MReadTree::GetFileName() const
+{
+    const TFile *file = fChain->GetFile();
+
+    if (!file)
+        return TString("<unknown>");
+
+    TString name(file->GetName());
+    name.Remove(0, name.Last('/')+1);
+    return name;
+}
+
+// --------------------------------------------------------------------------
+//
+//  Return the number of the file in the chain, -1 in case of an error
+//
+Int_t MReadTree::GetFileIndex() const
+{
+    return fChain->GetTreeNumber();
+    /*
+    const TString filename = fChain->GetFile()->GetName();
+
+    int i=0;
+    TObject *file = NULL;
+
+    TIter Next(fChain->GetListOfFiles());
+    while ((file=Next()))
+    {
+        if (filename==gSystem->ExpandPathName(file->GetTitle()))
+            return i;
+        i++;
+    }
+    return -1;
+    */
+}
+
+// --------------------------------------------------------------------------
+//
+//  This schedules a TObject which Notify(9 function is called in case
+//  of MReadTree (TChain) switches from one file in the chain to another
+//  one.
+//
+void MReadTree::AddNotify(TObject *obj)
+{
+    fNotify->Add(obj);
+}
+
+void MReadTree::Print(Option_t *o) const
+{
+    *fLog << all << GetDescriptor() << dec << endl;
+    *fLog << setfill('-') << setw(strlen(GetDescriptor())) << "" << endl;
+    *fLog << " Files [Tree]:" << endl;
+
+    int i = 0;
+    TIter Next(fChain->GetListOfFiles());
+    TObject *obj = NULL;
+    while ((obj=Next()))
+        *fLog << " " << i++ << ") " << obj->GetTitle() << " [" << obj->GetName() << "]" << endl;
+
+    *fLog << " Total Number of Entries: " << fNumEntries << endl;
+    *fLog << " Next Entry to read: " << fNumEntry << endl;
+}
Index: trunk/MagicSoft/Mars/mfileio/MReadTree.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MReadTree.h	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/MReadTree.h	(revision 1381)
@@ -0,0 +1,77 @@
+#ifndef MARS_MReadTree
+#define MARS_MReadTree
+
+#ifndef MARS_MTask
+#include "MTask.h"
+#endif
+
+class MChain;
+class TBranch;
+class TGProgressBar;
+
+class MReadTree : public MTask
+{
+private:
+    MChain *fChain;            // Pointer to tree
+
+    UInt_t  fNumEntry;         // Number of actual entry in chain
+    UInt_t  fNumEntries;       // Number of Events in chain
+
+    Bool_t  fBranchChoosing;   // Flag for branch choosing method
+    Bool_t  fAutoEnable;       // Flag for auto enabeling scheme
+
+    TList  *fVetoList;         // List of Branches which are not allowed to get enabled
+    TList  *fNotify;           // List of TObjects to notify when switching files
+
+private:
+    TGProgressBar  *fProgress; //! Possible display of status
+
+    void SetBranchStatus(const TList *list, Bool_t status);
+    void SetBranchStatus(TObject *branch, Bool_t status);
+    void SetBranchStatus(const char *name, Bool_t status);
+
+    void DisableSubBranches(TBranch *b);
+    void EnableBranches(MParList *plist);
+    void EnableBranchChoosing();
+
+    virtual void SetReadyToSave(Bool_t flag=kTRUE);
+
+    enum { kIsOwner = BIT(14) };
+
+public:
+    MReadTree(const char *treename, const char *filename=NULL, const char *name=NULL, const char *title=NULL);
+    ~MReadTree();
+
+    void   DisableAutoScheme() { fAutoEnable = kFALSE; }
+    void   EnableBranch(const char *name);
+    void   VetoBranch(const char *name);
+
+    void   SetProgressBar(TGProgressBar *bar) { fProgress = bar; }
+
+    Bool_t GetEvent();
+
+    Bool_t DecEventNum(UInt_t dec=1); // decrease number of event (position in tree)
+    Bool_t IncEventNum(UInt_t inc=1); // increase number of event (position in tree)
+    Bool_t SetEventNum(UInt_t nr);    // set number of event (position in tree)
+
+    UInt_t GetEventNum() const { return fNumEntry;   }
+    UInt_t GetEntries() const  { return fNumEntries; }
+
+    TString GetFileName() const;
+    Int_t   GetFileIndex() const;
+
+    virtual void   AddNotify(TObject *obj);
+    virtual void   SetOwner(Bool_t flag=kTRUE);
+    virtual void   Print(Option_t *opt="") const;
+
+    virtual Int_t  AddFile(const char *fname);
+
+    virtual Bool_t PreProcess(MParList *pList);
+    virtual Bool_t Process();
+
+    virtual Bool_t Notify();
+
+    ClassDef(MReadTree, 0)	// Reads a tree from file(s)
+};
+
+#endif
Index: trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.cc
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.cc	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.cc	(revision 1381)
@@ -0,0 +1,310 @@
+/* ======================================================================== *\
+!
+! *
+! * 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  06/2001 <mailto:tbretz@uni-sw.gwdg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// MWriteAsciiFile                                                         //
+//                                                                         //
+// If you want to store a single container into an Ascii file you have     //
+// to use this class. You must know the name of the file you wanne write   //
+// (you should know it) and the name of the container you want to write.   //
+// This can be the name of the class or a given name, which identifies     //
+// the container in a parameter container list (MParList).                 //
+// The container is written to the ascii file if its ReadyToSave flag is   //
+// set (MParContainer)                                                     //
+//                                                                         //
+// You can write more than one container in one line of the file, see      //
+// AddContainer.                                                           //
+//                                                                         //
+// You can also write single data members of a container (like fWidth      //
+// of MHillas). For more details see AddContainer. Make sure, that a       //
+// getter method for the data member exist. The name of the method         //
+// must be the same than the data member itself, but the f must be         //
+// replaced by a Get.                                                      //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+#include "MWriteAsciiFile.h"
+
+#include <fstream.h>
+
+#include <TMethodCall.h> // TMethodCall, AsciiWrite
+
+#include "MDataList.h"   // MDataList
+#include "MDataChain.h"  // MDataChain
+#include "MDataValue.h"  // MDataValue
+#include "MDataMember.h" // MDataMember
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+
+ClassImp(MWriteAsciiFile);
+
+// --------------------------------------------------------------------------
+//
+// Init. Replaces the same code used in all constructors.
+//
+void MWriteAsciiFile::Init(const char *filename, const char *name, const char *title)
+{
+    fName  = name  ? name  : "MWriteAsciiFile";
+    fTitle = title ? title : "Task to write one container to an ascii file";
+
+    fNameFile = filename;
+
+    fOut = new ofstream(fNameFile);
+}
+
+// --------------------------------------------------------------------------
+//
+// Specify the name of the ascii output file 'filename' and the name
+// of the container you want to write. (Normally this is the name
+// of the class (eg. MHillas) but it can also be a different name which
+// identifies the container in the parameter list.
+// Because you cannot write more than one container there is no Add-function
+// like in MWriteRootFile.
+//
+//  For Example: MWriteAsciiFile("file.txt", "MHillas");
+//
+MWriteAsciiFile::MWriteAsciiFile(const char *filename, const char *contname,
+                                 const char *name, const char *title)
+{
+    Init(filename, name, title);
+
+    if (contname)
+       AddContainer(contname);
+}
+
+// --------------------------------------------------------------------------
+//
+// Specify a the name of the ascii output file 'filename' and a pointer to
+// the container you want to write. 
+// Because you cannot write more than one container there is no Add-function
+// like in MWriteRootFile.
+//
+//  For Example: MHillas hillas;
+//               MWriteAsciiFile("file.txt", &hillas);
+//
+//
+MWriteAsciiFile::MWriteAsciiFile(const char *filename, MParContainer *cont,
+                                 const char *name, const char *title)
+{
+    Init(filename, name, title);
+
+    if (cont)
+        AddContainer(cont);
+}
+
+// --------------------------------------------------------------------------
+//
+// Destructor. Delete the output file if necessary (it is closed
+// automatically by its destructor.
+//
+MWriteAsciiFile::~MWriteAsciiFile()
+{
+    fAutoDel.SetOwner();
+    delete fOut;
+}
+
+// --------------------------------------------------------------------------
+//
+// Return open state of the file
+//
+Bool_t MWriteAsciiFile::IsFileOpen() const
+{
+    return (bool)(*fOut);
+}
+
+// --------------------------------------------------------------------------
+//
+// Add a rule to be written as a column to the ascii file.
+// For more information about rules see MDataChain.
+//
+void MWriteAsciiFile::AddRule(const char *rule)
+{
+    MDataChain *chain = new MDataChain(rule);
+    fList.Add(chain);
+}
+
+// --------------------------------------------------------------------------
+//
+// Add another container (by pointer) to be written to the ascii file.
+// The container will be output one after each other in one line.
+// If you want to write only one data member of the container
+// specify the name of the data member (eg. fAlpha) Make sure,
+// that a "GetteMethod" for this data type exists (strip the f and
+// replace it by Get)
+// If you specify a single data member you can add a scale-factor which
+// is (in case of the data member being a floating point value) multiplied
+// with the data member value. This is usefull if you are want to
+// change the scale (unit) of a data member for writing (eg.
+// writing degrees for the hillas parameters instead of the internally
+// used millimeters)
+//
+void MWriteAsciiFile::AddContainer(MParContainer *cont, const TString member, Double_t scale)
+{
+    if (member.IsNull())
+    {
+        fList.Add(cont);
+        return;
+    }
+
+    MData *data = new MDataMember(cont, member);
+
+    if (scale!=1)
+    {
+        MDataList  *list = new MDataList('*');
+        MDataValue *val  = new MDataValue(scale);
+
+        list->SetOwner();
+        list->AddToList(data);
+        list->AddToList(val);
+
+        data = list;
+    }
+    fList.Add(data);
+    fAutoDel.Add(data);
+}
+
+// --------------------------------------------------------------------------
+//
+// Add another container (by name) to be written to the ascii file.
+// The container will be output one after each other in one line.
+// If you want to write only one data member of the container
+// specify the name of the data member (eg. fAlpha) Make sure,
+// that a "GetteMethod" for this data type exists (strip the f and
+// replace it by Get)
+// If you specify a single data member you can add a scale-factor which
+// is (in case of the data member being a floating point value) multiplied
+// with the data member value. This is usefull if you are want to
+// change the scale (unit) of a data member for writing (eg.
+// writing degrees for the hillas parameters instead of the internally
+// used millimeters)
+//
+void MWriteAsciiFile::AddContainer(const TString cont, const TString member, Double_t scale)
+{
+    if (member.IsNull())
+    {
+        TNamed *name = new TNamed(cont, cont);
+        fList.Add(name);
+        fAutoDel.Add(name);
+        return;
+    }
+
+    MData *data = new MDataMember(Form("%s.%s", (const char*)cont, (const char*)member));
+    if (scale!=1)
+    {
+        MDataList  *list = new MDataList('*');
+        MDataValue *val  = new MDataValue(scale);
+
+        list->SetOwner();
+        list->AddToList(data);
+        list->AddToList(val);
+
+        data = list;
+    }
+    fList.Add(data);
+    fAutoDel.Add(data);
+}
+
+// --------------------------------------------------------------------------
+//
+// Tries to get all containers from the ParList which were given by name
+// adds them to the list of pointers to the container which should be
+// written to the ascii file.
+//
+Bool_t MWriteAsciiFile::GetContainer(MParList *plist)
+{
+    TObject *obj=NULL;
+
+    TIter Next(&fList);
+    while ((obj=Next()))
+    {
+        //
+        // MData is the highest class in the inheritance tree
+        //
+        if (obj->InheritsFrom(MData::Class()))
+        {
+            if (!((MData*)obj)->PreProcess(plist))
+                return kFALSE;
+            continue;
+        }
+
+        //
+        // MParContainer is the next class in the inheritance tree
+        //
+        if (obj->InheritsFrom(MParContainer::Class()))
+            continue;
+
+        //
+        // It is neither a MData nor a MParContainer, it must be a TNamed
+        //
+        TObject *o = plist->FindObject(obj->GetName());
+        if (!o)
+            return kFALSE;
+
+        fList[fList.IndexOf(obj)] = o;
+    }
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Check if the containers are ready for writing. If so write them.
+// The containers are written in one line, one after each other.
+// If not all containers are written (because of the IsReadyToSave-flag)
+// a warning message is print.
+//
+void MWriteAsciiFile::CheckAndWrite() const
+{
+    Bool_t written = kFALSE;
+
+    MParContainer *obj = NULL;
+
+    Int_t num = fList.GetEntries();
+
+    TIter Next(&fList);
+    while ((obj=(MParContainer*)Next()))
+    {
+        if (!obj->IsReadyToSave())
+            continue;
+
+        if (!obj->AsciiWrite(*fOut))
+            continue;
+
+        written = kTRUE;
+
+        num--;
+    }
+
+    if (!written)
+        return;
+
+    *fOut << endl;
+
+    if (num!=0)
+        *fLog << warn << "Warning - given number of objects doesn't fit number of written objects." << endl;
+}
+
Index: trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.h	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.h	(revision 1381)
@@ -0,0 +1,45 @@
+#ifndef MARS_MWriteAsciiFile
+#define MARS_MWriteAsciiFile
+
+#ifndef MARS_MWriteFile
+#include "MWriteFile.h"
+#endif
+#ifndef ROOT_TObjArray
+#include <TObjArray.h>
+#endif
+
+class MData;
+
+class MWriteAsciiFile : public MWriteFile
+{
+private:
+    ofstream *fOut;     //! ascii file
+
+    TString fNameFile;  // name of the ascii file
+
+    TObjArray fList;    // list of rules and containers to be written
+    TObjArray fAutoDel; //! List of object to be deleted in the destructor
+
+    virtual void   CheckAndWrite() const;
+    virtual Bool_t IsFileOpen() const;
+    virtual Bool_t GetContainer(MParList *pList);
+    virtual const char *GetFileName() const { return fNameFile; }
+
+    void Init(const char *filename, const char *name, const char *title);
+
+public:
+    MWriteAsciiFile(const char *filename, const char *contname,
+                    const char *name=NULL, const char *title=NULL);
+    MWriteAsciiFile(const char *filename, MParContainer *cont=NULL,
+                    const char *name=NULL, const char *title=NULL);
+    ~MWriteAsciiFile();
+
+    void AddContainer(const TString cname, const TString member="", Double_t scale=1);
+    void AddContainer(MParContainer *cont, const TString member="", Double_t scale=1);
+
+    void AddRule(const char *rule);
+
+    ClassDef(MWriteAsciiFile, 0) // Class to write one container to an ascii file
+};
+
+#endif
Index: trunk/MagicSoft/Mars/mfileio/MWriteFile.cc
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MWriteFile.cc	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/MWriteFile.cc	(revision 1381)
@@ -0,0 +1,110 @@
+/* ======================================================================== *\
+!
+! *
+! * 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  06/2001 <mailto:tbretz@uni-sw.gwdg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2001
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// MWriteFile                                                              //
+//                                                                         //
+// This is a base class for writing tasks. If you want to implement        //
+// writing out parameter containers in a new file format, this is a good   //
+// starting point.                                                         //
+// The class defines a generalized interface between writing out data in   //
+// an eventloop and your file format.                                      //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+#include "MWriteFile.h"
+
+#include <fstream.h>
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+
+ClassImp(MWriteFile);
+
+// --------------------------------------------------------------------------
+//
+// Tries to open the given output file.
+// The derived class should retrieve needed containers from the parameter
+// list.
+// instance of the container which should be written.
+// If the container has already the HasChanged flag it is immediatly written
+// to the output file.
+//
+Bool_t MWriteFile::PreProcess(MParList *pList)
+{
+    //
+    // test whether file is now open or not
+    //
+    if (!IsFileOpen())
+    {
+        *fLog << err << dbginf << "Cannot open file '" << GetFileName() << "'" << endl;
+        return kFALSE;
+    }
+
+    *fLog << inf << "File '" << GetFileName() << "' open for writing." << endl;
+
+    //
+    // Get the containers (pointers) from the parameter list you want to write
+    //
+    if (!GetContainer(pList))
+        return kFALSE;
+
+    //
+    // write the container if it is already in changed state
+    //
+    CheckAndWrite();
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Checks if the HasChanged flag of the output container is set. If it is set
+// the container should be written to the output.
+//
+Bool_t MWriteFile::Process()
+{
+    CheckAndWrite();
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Checks if the HasChanged flag of the output container is set. If it is set
+// the container should be written to the output.
+//
+Bool_t MWriteFile::PostProcess()
+{
+    //
+    // check if the container changed state is set
+    //
+    CheckAndWrite();
+
+    return kTRUE;
+}
+
Index: trunk/MagicSoft/Mars/mfileio/MWriteFile.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MWriteFile.h	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/MWriteFile.h	(revision 1381)
@@ -0,0 +1,23 @@
+#ifndef MARS_MWriteFile
+#define MARS_MWriteFile
+
+#ifndef MARS_MTask
+#include "MTask.h"
+#endif
+
+class MWriteFile : public MTask
+{
+private:
+    Bool_t PreProcess(MParList *pList);
+    Bool_t Process();
+    Bool_t PostProcess();
+
+    virtual Bool_t      IsFileOpen() const = 0;
+    virtual void        CheckAndWrite() const = 0;
+    virtual Bool_t      GetContainer(MParList *pList) = 0;
+    virtual const char *GetFileName() const = 0;
+
+    ClassDef(MWriteFile, 0)	// Base class for tasks to write single containers to several output formats
+};
+
+#endif
Index: trunk/MagicSoft/Mars/mfileio/MWriteRootFile.cc
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MWriteRootFile.cc	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/MWriteRootFile.cc	(revision 1381)
@@ -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  06/2001 <mailto:tbretz@uni-sw.gwdg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2001
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// MWriteRootFile                                                          //
+//                                                                         //
+// This is a writer to store several containers to a root file.            //
+// The containers are added with AddContainer.                             //
+// To understand how it works, see base class MWriteFile                   //
+//                                                                         //
+// Warning: Checkout the Warning in MTaskList.                             //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+#include "MWriteRootFile.h"
+
+#include <TFile.h>
+#include <TTree.h>
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+
+ClassImp(MRootFileBranch);
+ClassImp(MWriteRootFile);
+
+// --------------------------------------------------------------------------
+//
+// Specify the name of the root file. You can also give an option ("UPDATE"
+// and "RECREATE" would make sense only) as well as the file title and
+// compression factor. To a more detaild description of the options see
+// TFile.
+//
+MWriteRootFile::MWriteRootFile(const char *fname,
+                               const Option_t *opt,
+                               const char *ftitle,
+                               const Int_t comp,
+                               const char *name,
+                               const char *title)
+{
+    fName  = name  ? name  : "MWriteRootFile";
+    fTitle = title ? title : "Task which writes a root-output file";
+
+    //
+    // Set the Arrays the owner of its entries. This means, that the
+    // destructor of the arrays will delete all its entries.
+    //
+    fBranches.SetOwner();
+
+    //
+    // Believing the root user guide, TTree instanced are owned by the
+    // directory (file) in which they are. This means we don't have to
+    // care about their destruction.
+    //
+    //fTrees.SetOwner();
+
+    //
+    // Open the rootfile
+    //
+    fOut = new TFile(fname, opt, ftitle, comp);
+}
+
+// --------------------------------------------------------------------------
+//
+// Prints some statistics about the file to the screen. And closes the file
+// properly.
+//
+MWriteRootFile::~MWriteRootFile()
+{
+    //
+    // Print some statistics to the looging out.
+    //
+    Print();
+
+    //
+    // If the file is still open (no error) write the keys. This is necessary
+    // for appearance of the all trees and branches.
+    //
+    if (IsFileOpen())
+        fOut->Write();
+
+    //
+    // Delete the file. This'll also close the file (if open)
+    //
+    delete fOut;
+
+    //
+    // Remark:
+    // - Trees are automatically deleted by the the file
+    //   (unless file.SetDirectory(0) was called)
+    // - Branches are automatically deleted by the tree destructor
+    //
+}
+
+// --------------------------------------------------------------------------
+//
+// Prints all trees with the actually number of written entries to log-out.
+//
+void MWriteRootFile::Print(Option_t *) const
+{
+    *fLog << all << " File: " << GetFileName() << endl;
+    *fLog << setfill('-') << setw(strlen(GetFileName())+8) << "" << endl;
+    *fLog << setfill(' '); // FIXME: not resetting setfill results in strange output???
+
+    TTree *t = NULL;
+    TIter Next(&fTrees);
+    while ((t=(TTree*)Next()))
+        *fLog << t->GetName() << ": \t" << t->GetEntries() << " entries." << endl;
+}
+
+// --------------------------------------------------------------------------
+//
+// Add a new Container to list of containers which should be written to the
+// file. Give the name of the container which will identify the container
+// in the parameterlist. tname is the name of the tree to which the
+// container should be written (Remark: one tree can hold more than one
+// container). The default is the same name as the container name.
+// You can slso specify a title for the tree. This is only
+// used the first time this tree in 'mentioned'. As default the title
+// is the name of the tree.
+//
+void MWriteRootFile::AddContainer(const char *cname, const char *tname, const char *ttitle)
+{
+    //
+    // create a new entry in the list of branches to write and
+    // add the entry to the list.
+    //
+    MRootFileBranch *entry = new MRootFileBranch(cname, tname, ttitle);
+    fBranches.AddLast(entry);
+
+    if (tname && tname[0])
+        AddToBranchList(Form("%s.%s", cname, tname));
+}
+
+// --------------------------------------------------------------------------
+//
+// Add a new Container to list of containers which should be written to the
+// file. Give the pointer to the container. tname is the name of the tree to
+// which the container should be written (Remark: one tree can hold more than
+// one container). The default is the same name as the container name.
+// You can slso specify a title for the tree. This is only
+// used the first time this tree in 'mentioned'. As default the title
+// is the name of the tree.
+//
+void MWriteRootFile::AddContainer(MParContainer *cont, const char *tname,
+                                  const char *ttitle)
+{
+    //
+    // create a new entry in the list of branches to write and
+    // add the entry to the list.
+    //
+    MRootFileBranch *entry = new MRootFileBranch(cont, tname, ttitle);
+    fBranches.AddLast(entry);
+}
+
+// --------------------------------------------------------------------------
+//
+// Add a new Container to list of containers which should be written to the
+// file. Give the pointer to the container. tname is the name of the tree to
+// which the container should be written (Remark: one tree can hold more than
+// one container). The default is the same name as the container name.
+// You can slso specify a title for the tree. This is only
+// used the first time this tree in 'mentioned'. As default the title
+// is the name of the tree.
+//
+Bool_t MWriteRootFile::GetContainer(MParList *pList)
+{
+    MRootFileBranch *entry;
+
+    //
+    // loop over all branches which are 'marked' as branches to get written.
+    //
+    TIter Next(&fBranches);
+    while ((entry=(MRootFileBranch*)Next()))
+    {
+        //
+        // Get the pointer to the container. If the pointer is NULL it seems,
+        // that the user identified the container by name.
+        //
+        MParContainer *cont = entry->GetContainer();
+        if (!cont)
+        {
+            //
+            // Get the name and try to find a container with this name
+            // in the parameter list.
+            //
+            const char *cname = entry->GetContName();
+            cont = (MParContainer*)pList->FindObject(cname);
+            if (!cont)
+            {
+                //
+                // No corresponding container is found
+                //
+                *fLog << dbginf << "Cannot find parameter container '" << cname << "'." << endl;
+                return kFALSE;
+            }
+            //
+            // The container is found. Put the pointer into the entry.
+            //
+            entry->SetContainer(cont);
+        }
+
+        //
+        // Get container name, tree name and tree title of this entry.
+        //
+        const char *cname  = cont->GetName();
+        const char *tname  = entry->GetName();
+        const char *ttitle = entry->GetTitle();
+
+        //
+        // if the tree name is NULL this idetifies it to use the default:
+        // the container name.
+        //
+        if (tname[0] == '\0')
+            tname = cname;
+
+        //
+        // Check if the tree is already existing (part of the file)
+        //
+        TTree *tree = (TTree*)fOut->Get(tname);
+        if (!tree)
+        {
+            //
+            // if the tree doesn't exist create a new tree. Use the tree
+            // name as title if title is NULL.
+            // And add the tree to the list of trees
+            //
+            tree = new TTree(tname, ttitle ? ttitle : tname);
+            fTrees.AddLast(tree);
+
+            *fLog << "Created Tree " << tname << "." << endl;
+        }
+
+        //
+        // Now we have a valid tree. Search the list of trees for this tree
+        // (either it is already there, or we created and add it previously)
+        // Add a pointer to the entry in the tree list to this branch-entry
+        //
+        TObject *obj;
+        TIter NextTree(&fTrees);
+        while ((obj=NextTree()))
+        {
+            if (obj == tree)
+                entry->SetTree((TTree*)obj);
+        }
+
+        //
+        // Try to get the branch from the file. 
+        // If the branch already exists the user specified one branch twice.
+        //
+        TBranch *branch = tree->GetBranch(cname);
+        if (branch)
+        {
+            *fLog << dbginf << "Branch '" << cname << "' is already existing." << endl;
+            return kFALSE;
+        }
+
+        //
+        // Create a new branch in the actual tree. The branch has the name
+        // container name. The type of the container is given by the
+        // ClassName entry in the container. The Address is the address of a
+        // pointer to the container (gotten from the branch entry). As
+        // Basket size we specify a (more or less) common default value.
+        // The containers should be written in Splitlevel=1
+        //
+        TString branchname(cname);
+        branchname.Append(".");
+        branch = tree->Branch(branchname, cont->ClassName(), entry->GetAddress());
+
+        *fLog << "Created Branch " << cname << " of " << cont->ClassName() << "." << endl;
+
+        //
+        // If the branch couldn't be created we have a problem.
+        //
+        if (!branch)
+        {
+            *fLog << dbginf << "Unable to create branch '" << cname << "'." << endl;
+            return kFALSE;
+        }
+    }
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Checks all given containers (branch entries) for the write flag.
+// If the write flag is set the corresponding Tree is marked to get filled.
+// All Trees which are marked to be filled are filled with the corresponding
+// branches.
+// Be carefull: If only one container (corresponding to a branch) of a tree
+// has the write flag, all containers in this tree are filled!
+//
+void MWriteRootFile::CheckAndWrite() const
+{
+    const Int_t kFillTree = BIT(14);
+
+    TObject *obj;
+
+    //
+    // Loop over all branch entries
+    //
+    TIter NextBranch(&fBranches);
+    while ((obj=NextBranch()))
+    {
+        MRootFileBranch *b = (MRootFileBranch*)obj;
+
+        //
+        // Check for the Write flag
+        //
+        if (!b->GetContainer()->IsReadyToSave())
+            continue;
+
+        //
+        // If the write flag of the branch entry is set, set the write flag of
+        // the corresponding tree entry.
+        //
+        b->GetTree()->SetBit(kFillTree);
+    }
+
+    //
+    // Loop over all tree entries
+    //
+    TIter NextTree(&fTrees);
+    while ((obj=NextTree()))
+    {
+        TTree *t = (TTree*)obj;
+
+        //
+        // Check the write flag of the tree
+        //
+        if (!t->TestBit(kFillTree))
+            continue;
+
+        //
+        // If the write flag is set, fill the tree (with the corresponding
+        // branches/containers), delete the write flag and increase the number
+        // of written/filled entries.
+        //
+        t->Fill();
+        t->ResetBit(kFillTree);
+    }
+}
+
+// --------------------------------------------------------------------------
+//
+// return open state of the root file.
+//
+Bool_t MWriteRootFile::IsFileOpen() const
+{
+    return fOut->IsOpen();
+}
+
+// --------------------------------------------------------------------------
+//
+// return name of the root-file
+//
+const char *MWriteRootFile::GetFileName() const
+{
+    return fOut->GetName();
+}
+
Index: trunk/MagicSoft/Mars/mfileio/MWriteRootFile.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MWriteRootFile.h	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/MWriteRootFile.h	(revision 1381)
@@ -0,0 +1,91 @@
+#ifndef MARS_MWriteRootFile
+#define MARS_MWriteRootFile
+
+#ifndef MARS_MWriteFile
+#include "MWriteFile.h"
+#endif
+#ifndef ROOT_TObjArray
+#include <TObjArray.h>
+#endif
+
+class TFile;
+class TTree;
+class TBranch;
+
+class MRootFileBranch : public TNamed
+{
+private:
+    TTree         *fTree;
+    TBranch       *fBranch;
+
+    MParContainer *fContainer;
+    TString        fContName;
+
+    void Init(const char *name, const char *title)
+    {
+        SetName(name?name:"");
+        SetTitle(title?title:"");
+    }
+
+public:
+    MRootFileBranch(const char *cname, const char *tname=NULL, const char *ttitle=NULL)
+        : fTree(NULL), fBranch(NULL), fContainer(NULL)
+    {
+        Init(tname, ttitle);
+        fContName = cname;
+    }
+
+    MRootFileBranch(MParContainer *cont, const char *tname=NULL, const char *ttitle=NULL)
+        : fTree(NULL), fBranch(NULL), fContName("")
+    {
+        Init(tname, ttitle);
+        fContainer = cont;
+    }
+
+    TTree         *GetTree() const      { return fTree; }
+    MParContainer *GetContainer() const { return fContainer; }
+    void          *GetAddress()         { return &fContainer; }
+    TBranch       *GetBranch() const    { return fBranch; }
+    const char    *GetContName() const  { return fContName; }
+
+    void SetContainer(MParContainer *cont) { fContainer = cont; }
+    void SetTree(TTree *tree)              { fTree = tree; }
+
+    ClassDef(MRootFileBranch, 0) // Storage container for MWriteRootFile to store TBranch informations
+};
+
+class MWriteRootFile : public MWriteFile
+{
+private:
+    TFile *fOut;
+
+    TObjArray fBranches;
+    TObjArray fTrees;
+
+    void        CheckAndWrite() const;
+    Bool_t      IsFileOpen() const;
+    Bool_t      GetContainer(MParList *pList);
+    const char *GetFileName() const;
+
+public:
+    MWriteRootFile(const char *fname,
+                   const Option_t *opt="RECREATE",
+                   const char *ftitle="Untitled",
+                   const Int_t comp=9,
+                   const char *name=NULL,
+                   const char *title=NULL);
+    ~MWriteRootFile();
+
+
+    void AddContainer(const char *cname,
+                      const char *tname=NULL, const char *ttitle=NULL);
+    void AddContainer(MParContainer *cont,
+                      const char *tname=NULL, const char *ttitle=NULL);
+
+
+    void Print(Option_t *t=NULL) const;
+
+    ClassDef(MWriteRootFile, 0)	// Class to write one container to a root file
+};
+
+#endif
Index: trunk/MagicSoft/Mars/mfileio/Makefile
===================================================================
--- trunk/MagicSoft/Mars/mfileio/Makefile	(revision 1381)
+++ trunk/MagicSoft/Mars/mfileio/Makefile	(revision 1381)
@@ -0,0 +1,55 @@
+##################################################################
+#
+#   makefile
+# 
+#   for the MARS software
+#
+##################################################################
+# @maintitle
+
+# @code
+
+#
+#  please change all system depend values in the 
+#  config.mk.${OSTYPE} file 
+#
+#
+include ../Makefile.conf.$(OSTYPE)
+include ../Makefile.conf.general
+
+# @endcode 
+
+INCLUDES = -I. -I../mbase
+
+# @code 
+
+CINT     = FileIO
+LIB      = mfileio.a
+
+#------------------------------------------------------------------------------
+
+.SUFFIXES: .c .cc .cxx .h .hxx .o 
+
+SRCFILES = MReadTree.cc \
+           MReadMarsFile.cc \
+           MWriteFile.cc \
+           MWriteAsciiFile.cc \
+           MWriteRootFile.cc \
+           MCTReadAscii.cc
+
+SRCS    = $(SRCFILES)
+HEADERS = $(SRCFILES:.cc=.h)
+OBJS    = $(SRCFILES:.cc=.o) 
+
+############################################################
+
+all: $(LIB)
+
+include ../Makefile.rules
+
+clean:	rmcint rmobjs rmcore rmlib
+
+mrproper:	clean rmbak
+
+# @endcode
+
