Index: trunk/MagicSoft/Mars/Changelog
===================================================================
--- trunk/MagicSoft/Mars/Changelog	(revision 9028)
+++ trunk/MagicSoft/Mars/Changelog	(revision 9029)
@@ -36,4 +36,11 @@
      - the file number is three digits
      - the Tag for data runs is DatRuns not DataRuns
+
+   * mfileio/Makefile, mfileio/FileIOLinkDef.h:
+     - added MReadFiles
+     - added MReadScanFile
+
+   * mfileio/MReadFiles.[h,cc], mfileio/MReadScanFile.[h,cc]:
+     - added
 
 
Index: trunk/MagicSoft/Mars/datacenter/macros/checkfileavail.C
===================================================================
--- trunk/MagicSoft/Mars/datacenter/macros/checkfileavail.C	(revision 9028)
+++ trunk/MagicSoft/Mars/datacenter/macros/checkfileavail.C	(revision 9029)
@@ -98,5 +98,5 @@
     }
 
-    TSQlRow *row = res->Next();
+    TSQLRow *row = res->Next();
 
     if (!row || !(*row)[0])
Index: trunk/MagicSoft/Mars/mfileio/FileIOLinkDef.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/FileIOLinkDef.h	(revision 9028)
+++ trunk/MagicSoft/Mars/mfileio/FileIOLinkDef.h	(revision 9029)
@@ -11,4 +11,6 @@
 #pragma link C++ class MReadMarsFile+;
 #pragma link C++ class MReadRflFile+;
+#pragma link C++ class MReadFiles+;
+#pragma link C++ class MReadScanFile+;
 
 #pragma link C++ class MRootFileBranch+;
Index: trunk/MagicSoft/Mars/mfileio/MReadFiles.cc
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MReadFiles.cc	(revision 9029)
+++ trunk/MagicSoft/Mars/mfileio/MReadFiles.cc	(revision 9029)
@@ -0,0 +1,252 @@
+/* ======================================================================== *\
+!
+! *
+! * 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, 7/2008 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2008
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MReadFiles
+//
+/////////////////////////////////////////////////////////////////////////////
+#include "MReadFiles.h"
+
+#include <TObjString.h>
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MZlib.h"
+#include "MDirIter.h"
+
+ClassImp(MReadFiles);
+
+using namespace std;
+
+// --------------------------------------------------------------------------
+//
+// 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.
+//
+MReadFiles::MReadFiles(const char *fname, const char *name, const char *title)
+    : fNumFile(0), fNumLine(0), fParList(0), fIn(0)
+{
+    fName  = name  ? name  : "MRead";
+    fTitle = title ? title : "Reads a Reflector output file";
+
+    //
+    // remember file name for opening the file in the preprocessor
+    //
+    fFileNames.SetOwner();
+
+    if (fname)
+        AddFile(fname);
+}
+
+// --------------------------------------------------------------------------
+//
+// Delete the filename list and the input stream if one exists.
+//
+MReadFiles::~MReadFiles()
+{
+    if (fIn)
+        delete fIn;
+}
+
+// --------------------------------------------------------------------------
+//
+// Call Close() and reset fNumLine and fNumFile
+//
+Bool_t MReadFiles::Rewind()
+{
+    Close();
+
+    fNumFile = 0;
+    fNumLine = 0;
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Read a line from the file, return kFALSE if stream is at the end,
+// kTRUE in case of success. Increase fNumLine in case of success.
+//
+Bool_t MReadFiles::ReadLine(TString &line)
+{
+    line.ReadLine(*fIn);
+    if (!*fIn)
+        return kFALSE;
+
+    fNumLine++;
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Close an open stream and set fIn to NULL
+//
+void MReadFiles::Close()
+{
+    if (fIn)
+        delete fIn;
+
+    fIn = NULL;
+    fFileName = "";
+}
+
+// --------------------------------------------------------------------------
+//
+// This opens the next file in the list and deletes its name from the list.
+//
+Bool_t MReadFiles::OpenNextFile()
+{
+    // First close an open file, if any
+    Close();
+
+    // Check for the existence of a next file to read
+    if (fNumFile >= (UInt_t)fFileNames.GetSize())
+    {
+        *fLog << inf << GetDescriptor() << ": No unread files anymore..." << endl;
+        return kFALSE;
+    }
+
+    // open the file which is the first one in the chain
+    fFileName = fFileNames.At(fNumFile)->GetName();
+
+    *fLog << inf << "Open file: " << fFileName << endl;
+
+    // open a stream to a zipped or unzipped file
+    fIn = new MZlib(fFileName);
+    if (!*fIn)
+    {
+        *fLog << err << "Cannot open file " << fFileName << ": ";
+        *fLog << strerror(errno) << endl;
+        return kFALSE;
+    }
+
+    //*fLog << inf;
+    //fLog->Separator(fFileName);
+
+    fNumFile++;
+    fNumLine=0;
+
+    // return stream status
+    return *fIn;
+}
+
+// --------------------------------------------------------------------------
+//
+// Open next file (the first one) and call AnalyzeHeader.
+// Rewind() afterwards.
+//
+Int_t MReadFiles::PreProcess(MParList *plist)
+{
+    fParList = plist;
+
+    Rewind();
+
+    if (!OpenNextFile())
+        return kFALSE;
+
+    if (!AnalyzeHeader(*plist))
+        return kFALSE;
+
+    Rewind();
+
+    return kTRUE;
+}
+
+Int_t MReadFiles::Process()
+{
+    // if no file open or there was a failure
+    if (!fIn || !*fIn)
+    {
+        // try to open the next file
+        if (!OpenNextFile())
+            return kFALSE;
+
+        // read the header from the file
+        if (!ReadHeader())
+            return kERROR;
+
+        // after reading the header ReInit tasklist
+        if (!ReInit(fParList))
+            return kERROR;
+    }
+
+    // Read one event
+    return ReadEvent();
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Check if the file is accessible
+//
+Bool_t MReadFiles::CheckFile(TString name) const
+{
+    gSystem->ExpandPathName(name);
+
+    if (IsFileValid(name))
+        return kTRUE;
+
+    *fLog << err;
+    *fLog << "ERROR - File " << name<< " not accessible!" << endl;
+    return kFALSE;;
+}
+
+// --------------------------------------------------------------------------
+//
+// Add this file as the last entry in the chain. Wildcards as accepted
+// by MDirIter are allowed.
+//
+Int_t MReadFiles::AddFile(const char *txt, int)
+{
+    const TString dir  = gSystem->DirName(txt);
+    const TString base = gSystem->BaseName(txt);
+
+    Int_t num = 0;
+
+    MDirIter Next(dir, base);
+    while (1)
+    {
+        const TString fname = Next();
+        if (fname.IsNull())
+            break;
+
+        if (!CheckFile(fname))
+            continue;
+
+        if (fFileNames.FindObject(fname))
+            *fLog << warn << "WARNING - " << fname << " already in list." << endl;
+
+        *fLog << inf2 << fname << " added to list." << endl;
+        fFileNames.AddLast(new TObjString(fname));
+        num++;
+    }
+
+    if (num>1)
+        *fLog << inf2 << num << " files added to list." << endl;
+
+    return num;
+}
Index: trunk/MagicSoft/Mars/mfileio/MReadFiles.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MReadFiles.h	(revision 9029)
+++ trunk/MagicSoft/Mars/mfileio/MReadFiles.h	(revision 9029)
@@ -0,0 +1,54 @@
+#ifndef MARS_MReadFiles
+#define MARS_MReadFiles
+
+#ifndef MARS_MRead
+#include "MRead.h"
+#endif
+
+class MZlib;
+
+class MReadFiles : public MRead
+{
+private:
+    TList     fFileNames;  // Array which stores the \0-terminated filenames
+
+    TString   fFileName;   // Currently open file
+
+    UInt_t    fNumFile;    // File number in sequence
+    UInt_t    fNumLine;    // Line number in file
+
+    MParList *fParList;    //! Parlist for reinitialization
+
+protected:
+    MZlib    *fIn;         // the inputfile
+
+    Bool_t ReadLine(TString &line);
+
+    UInt_t GetNumLine() const { return fNumLine; }
+
+    Int_t  PreProcess(MParList *pList);
+    Int_t  Process();
+
+private:
+    Bool_t OpenNextFile();
+    Bool_t CheckFile(TString name) const;
+
+    virtual Bool_t AnalyzeHeader(MParList &plist)=0;
+    virtual Bool_t ReadHeader()=0;
+    virtual Int_t  ReadEvent()=0;
+
+public:
+    MReadFiles(const char *filename=NULL, const char *name=NULL,
+               const char *title=NULL);
+    ~MReadFiles();
+
+    Int_t AddFile(const char *fname, int i=0);
+
+    Bool_t  Rewind();
+    void    Close();
+    TString GetFullFileName() const { return fFileName; }
+
+    ClassDef(MReadFiles, 0) // Base class to read a chain of files
+};
+
+#endif
Index: trunk/MagicSoft/Mars/mfileio/MReadScanFile.cc
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MReadScanFile.cc	(revision 9029)
+++ trunk/MagicSoft/Mars/mfileio/MReadScanFile.cc	(revision 9029)
@@ -0,0 +1,221 @@
+/* ======================================================================== *\
+!
+! *
+! * 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, 7/2008 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2008
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MReadFiles
+//
+/////////////////////////////////////////////////////////////////////////////
+#include "MReadScanFile.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParameters.h"
+#include "MParList.h"
+
+ClassImp(MReadScanFile);
+
+using namespace std;
+
+// --------------------------------------------------------------------------
+//
+// Check if str only contains '*'
+//
+Bool_t MReadScanFile::IsDelimiter(const TString &str) const
+{
+    const char *end = str.Data()+str.Length()+1;
+    char const *ptr = str.Data();
+
+    while (*ptr++=='*');
+
+    if (ptr==end)
+        return kTRUE;
+
+    *fLog << err << "ERROR - Synatx error in line " << GetNumLine() << "... delimiter expected." << endl;
+    *fLog << "'" << str << "'" << endl;
+
+    return kFALSE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Read a line, check if it is a delimiter line and check its length.
+//
+Bool_t MReadScanFile::ReadDelimiter()
+{
+    TString str;
+    if (!ReadLine(str))
+        return kFALSE;
+    if (!IsDelimiter(str))
+        return kFALSE;
+
+    return kTRUE;
+
+/*
+
+    if (fLength<0)
+        fLength = str.Length();
+
+    if (fLength==str.Length())
+        return kTRUE;
+
+    *fLog << err << "ERROR - Delimiter line " << GetNumLine() << " has wrong length." << endl;
+    return kFALSE;
+    */
+}
+
+// --------------------------------------------------------------------------
+//
+// Read the header. Do some action if necessary. Leave the stream pointer
+// behind the header.
+//
+Bool_t MReadScanFile::ReadHeader()
+{
+    if (!ReadDelimiter())
+        return kFALSE;
+
+    // FIXME: Check header here
+    TString str;
+    if (!ReadLine(str))
+        return kFALSE;
+    cout << str << endl;
+
+    if (!ReadDelimiter())
+        return kFALSE;
+
+    return kTRUE;
+}
+
+Int_t MReadScanFile::ReadEvent()
+{
+    // If end-of-file go on reading next event in next file
+    TString str;
+    if (!ReadLine(str))
+        return Process();
+/*
+    if (fLength!=str.Length())
+    {
+        *fLog << err << "ERROR - Line " << GetNumLine() << " has wrong length." << endl;
+        return kERROR;
+    }
+ */
+    // Line is not properly formatted by TTree::Scan
+    if (str[0]!='*')
+    {
+        *fLog << err << "Line " << GetNumLine() << " doens't start with a '*'" << endl;
+        return kERROR;
+    }
+
+    // Line is the delimiter at the end of the file
+    // FIXME: Could we concatenate files here into one file?!
+    if (str[1]=='*')
+        return IsDelimiter(str) ? Process() : kERROR;
+
+    // Read and interpete the data
+    const char *end = str.Data()+str.Length();
+    char const *ptr = str.Data()+1;
+
+    TIter Next (&fList);
+    MParameterD *d = 0;
+
+    while (ptr && ptr<end)
+    {
+        // We have more columns in the file than conatiners
+        d = static_cast<MParameterD*>(Next());
+        if (!d)
+        {
+            *fLog << err << "Line " << GetNumLine() << " has too many fields." << endl;
+            return kERROR;
+        }
+
+        // set interpreted value
+        d->SetVal(atof(ptr));
+
+        // go on with the next column
+        ptr = strchr(ptr, '*')+1;
+    }
+
+    // we didn't find enough columns
+    if (ptr<end)
+    {
+        *fLog << err << "Line " << GetNumLine() << " has too less fields." << endl;
+        return kERROR;
+    }
+
+    // everything's ok
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Analyzse the header. Starts reading at the beginning of the file.
+// Leaves the stream pointer at the end of the header.
+// Add needed MParContainers to parlist or check for them.
+//
+Bool_t MReadScanFile::AnalyzeHeader(MParList &plist)
+{
+    fLength = -1;
+    if (!ReadDelimiter())
+        return kFALSE;
+ 
+    TString line;
+    if (!ReadLine(line))
+        return kFALSE;
+/*
+    if (fLength!=str.Length())
+    {
+        *fLog << err << "ERROR - Line " << GetNumLine() << " has wrong length." << endl;
+        return kFALSE;
+    }
+ */
+    TObjArray *arr = line.Tokenize('*');
+
+    TIter Next(arr);
+    TObject *o = 0;
+    while ((o=Next()))
+    {
+        TString name = TString(o->GetName()).Strip(TString::kBoth);
+        name.ReplaceAll(".", "_");
+
+        MParContainer *p = plist.FindCreateObj("MParameterD", name);
+        if (!p)
+        {
+            delete arr;
+            return kFALSE;
+        }
+
+        fList.AddLast(p);
+    }
+
+    delete arr;
+
+    return ReadDelimiter();
+}
+
+UInt_t MReadScanFile::GetEntries()
+{
+    *fLog << err << "Unkown number of entries" << endl;
+    return 0;
+}
Index: trunk/MagicSoft/Mars/mfileio/MReadScanFile.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MReadScanFile.h	(revision 9029)
+++ trunk/MagicSoft/Mars/mfileio/MReadScanFile.h	(revision 9029)
@@ -0,0 +1,33 @@
+#ifndef MARS_MReadScanFile
+#define MARS_MReadScanFile
+
+#ifndef MARS_MReadFiles
+#include "MReadFiles.h"
+#endif
+
+class MParList;
+
+class MReadScanFile : public MReadFiles
+{
+private:
+    TList fList;
+
+    Int_t fLength;
+
+    Bool_t IsDelimiter(const TString &str) const;
+    Bool_t ReadDelimiter();
+
+    Bool_t AnalyzeHeader(MParList &plist);
+    Bool_t ReadHeader();
+    Int_t  ReadEvent();
+
+public:
+    MReadScanFile(const char *filename=NULL, const char *name=NULL,
+                  const char *title=NULL) : MReadFiles(filename, name, title), fLength(-1) { }
+
+    UInt_t GetEntries();
+
+    ClassDef(MReadScanFile, 0) // Reads files written with TTree::Scan
+};
+
+#endif
Index: trunk/MagicSoft/Mars/mfileio/Makefile
===================================================================
--- trunk/MagicSoft/Mars/mfileio/Makefile	(revision 9028)
+++ trunk/MagicSoft/Mars/mfileio/Makefile	(revision 9029)
@@ -24,7 +24,9 @@
            MChain.cc \
 	   MReadTree.cc \
+           MReadFiles.cc \
            MReadReports.cc \
            MReadMarsFile.cc \
            MReadRflFile.cc \
+           MReadScanFile.cc \
            MWriteFile.cc \
            MWriteAsciiFile.cc \
