Index: trunk/MagicSoft/Mars/Changelog
===================================================================
--- trunk/MagicSoft/Mars/Changelog	(revision 4693)
+++ trunk/MagicSoft/Mars/Changelog	(revision 4694)
@@ -20,4 +20,51 @@
                                                  -*-*- END OF LINE -*-*-
 
+ 2004/08/20: Thomas Bretz
+
+   * macros/sql/filldotrbk.C:
+     - removed obsolete output
+
+   * macros/sql/filldotrun.C:
+     - removed obsolete output
+     - updated to support ExcludedFDA-table
+
+   * mbase/MParList.[h,cc]:
+     - added FindTask-member function
+
+   * mcalib/MHCalibrationChargeBlindCam.cc:
+     - fixed a 'comparison between signed and unsigned'
+
+   * mfileio/MRead.h:
+     - added GetFileName()
+     - removed const-qualifier from CheckAndWrite
+
+   * mfileio/MReadMarsFile.cc:
+     - changed some logiing output
+
+   * mfileio/MWriteAsciiFile.[h,cc], mfileio/MWriteFile.[h,cc]:
+     - removed const-qualifier from CheckAndWrite
+     
+   * mfileio/MWriteRootFile.[h,cc]:
+     - simplified the constructor by adding Init() function
+     - added ReInit function to support file splitting
+     - added file splitting support (GetNewFileName, ChangeFile)
+     - added new constructor for file splitting
+     - made gsDef* a static member
+     - slight changed to PreProcess to support file-splitting
+     - if file-spliiting is enabled return always kTRUE in IsFileOpen
+     - added many new outputs in case of possible problems
+
+   * mraw/MRawFileRead.[h,cc]:
+     - changed return type of GetFileName()
+
+   * mraw/MRawFileWrite.[h,cc]:
+     - removed obsolete pParList data member
+     - by default write all events to the 'Events' tree
+
+   * msql/MSQLServer.[h,cc]:
+     - enhanced Query function
+
+
+
  2004/08/19: Marcos Lopez
 
@@ -26,4 +73,5 @@
        the calibration file name, ignore the case, to deal with colors
        written in capital letters.
+
 
 
Index: trunk/MagicSoft/Mars/NEWS
===================================================================
--- trunk/MagicSoft/Mars/NEWS	(revision 4693)
+++ trunk/MagicSoft/Mars/NEWS	(revision 4694)
@@ -14,4 +14,6 @@
    - Added a new task (MTaskEnv) which can be used in setup files to switch
      between different tasks (for example to choose a signal extractor)
+
+   - Implemented automatic file splitting in MWriteRootFile
 
 
Index: trunk/MagicSoft/Mars/macros/sql/filldotrbk.C
===================================================================
--- trunk/MagicSoft/Mars/macros/sql/filldotrbk.C	(revision 4693)
+++ trunk/MagicSoft/Mars/macros/sql/filldotrbk.C	(revision 4694)
@@ -193,8 +193,5 @@
         TSQLResult *res = serv.Query(query);
         if (!res)
-        {
-            cout << "ERROR: " << query << endl << endl;
             return 0;
-        }
 
         delete res;
Index: trunk/MagicSoft/Mars/macros/sql/filldotrun.C
===================================================================
--- trunk/MagicSoft/Mars/macros/sql/filldotrun.C	(revision 4693)
+++ trunk/MagicSoft/Mars/macros/sql/filldotrun.C	(revision 4694)
@@ -107,8 +107,5 @@
     TSQLResult *res = serv.Query(query);
     if (!res)
-    {
-        cout << "ERROR - Query: " << query << endl;
-        return -1;
-    }
+        return -1;
 
     TSQLRow *row=res->Next();
@@ -134,8 +131,6 @@
     res=serv.Query(query);
     if (!res)
-    {
-        cout << "ERROR - Query: " << query << endl;
-        return -1;
-    }
+        return -1;
+
     delete res;
 
@@ -157,5 +152,5 @@
     if (!fin)
     {
-        cout << "Could not open file " << fname << endl;
+        cout << "Could not open file " << filename << endl;
         return -1;
     }
@@ -379,5 +374,5 @@
         if (!TMath::IsNaN(l2uprate) && TMath::Finite(l2uprate))
             query += Form("fL2RateUnpresc=%d, ", TMath::Nint(l2uprate));
-        query += "fMagicNumberKEY=1";
+        query += "fMagicNumberKEY=1, fExcludedFDAKEY=1";
 
         //cout << query << endl;
@@ -393,8 +388,5 @@
         TSQLResult *res = serv.Query(query);
         if (!res)
-        {
-            cout << query << " - FAILED!" << endl;
             return -1;
-        }
 
         delete res;
@@ -406,5 +398,5 @@
 
 // This tool will work from Period017 (2004_05_17) on...
-void filldotrun(const char *path="/data/MAGIC/Period018/ccdata", Bool_t dummy=kTRUE)
+int filldotrun(const TString path="/data/MAGIC/Period018/ccdata", Bool_t dummy=kTRUE)
 {
     MSQLServer serv("mysql://hercules:d99swMT!@localhost");
@@ -423,22 +415,22 @@
     if (path.EndsWith(".run"))
     {
+        cout << path(TRegexp("CC_.*.run", kFALSE)) << flush;
+        Int_t n = insert(serv, dummy, path);
+        cout << " <" << n << "> " << (dummy?"DUMMY":"") << endl;
+
+        return n<0 ? 0 : 1;
+    }
+
+    MDirIter Next(path, "CC_*.run", -1);
+    while (1)
+    {
+        TString name = Next();
+        if (name.IsNull())
+            break;
+
         cout << name(TRegexp("CC_.*.run", kFALSE)) << flush;
         Int_t n = insert(serv, dummy, name);
         cout << " <" << n << "> " << (dummy?"DUMMY":"") << endl;
 
-        return n<0 ? 0 : 1;
-    }
-
-    MDirIter Next(path, "CC_*.run", -1);
-    while (1)
-    {
-        TString name = Next();
-        if (name.IsNull())
-            break;
-
-        cout << name(TRegexp("CC_.*.run", kFALSE)) << flush;
-        Int_t n = insert(serv, dummy, name);
-        cout << " <" << n << "> " << (dummy?"DUMMY":"") << endl;
-
         if (n<0)
             return 0;
Index: trunk/MagicSoft/Mars/mbase/MParList.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MParList.cc	(revision 4693)
+++ trunk/MagicSoft/Mars/mbase/MParList.cc	(revision 4694)
@@ -368,4 +368,16 @@
 // --------------------------------------------------------------------------
 //
+//  Searches for the tasklist tlist (default: MTaskList) and returns
+//  a task with the given name found in this list. If one of both isn't
+//  found NULL is returned
+//
+MTask *MParList::FindTask(const char *name, const char *tlist) const
+{
+    TObject *l = FindObject(tlist, "MTaskList");
+    return (MTask*)(l ? l->FindObject(name) : NULL);
+}
+
+// --------------------------------------------------------------------------
+//
 //  returns the ClassName without anything which is behind that last ';' in
 //  string.
Index: trunk/MagicSoft/Mars/mbase/MParList.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MParList.h	(revision 4693)
+++ trunk/MagicSoft/Mars/mbase/MParList.h	(revision 4694)
@@ -21,4 +21,5 @@
 
 class MLog;
+class MTask;
 
 class MParList : public MParContainer
@@ -57,4 +58,6 @@
     TObject *FindObject(const char *name, const char *classname) const;
     TObject *FindObject(const TObject *obj, const char *classname) const;
+
+    MTask   *FindTask(const char *name, const char *tlist="MTaskList") const;
 
     MParContainer *FindCreateObj(const char *classname, const char *objname=NULL);
Index: trunk/MagicSoft/Mars/mcalib/MHCalibrationChargeBlindCam.cc
===================================================================
--- trunk/MagicSoft/Mars/mcalib/MHCalibrationChargeBlindCam.cc	(revision 4693)
+++ trunk/MagicSoft/Mars/mcalib/MHCalibrationChargeBlindCam.cc	(revision 4694)
@@ -179,5 +179,5 @@
 {
 
-  const Int_t nblindpixels  = fSignal->GetNumBlindPixels();
+  const UInt_t nblindpixels  = fSignal->GetNumBlindPixels();
 
   Int_t runnr = 0;
@@ -195,7 +195,8 @@
   if (fCam->GetNumBlindPixels() != nblindpixels)
     {
-      *fLog << err << "Size mismatch in MCalibrationChargeBlindCam ... abort." << endl;      
-      *fLog << err << "Size of MCalibrationChargeBlindCam: " << fCam->GetNumBlindPixels() 
-            << "Size of MExtractedSignalBlindPixel: " << nblindpixels << endl;
+        *fLog << err;
+        *fLog << "Size mismatch in MCalibrationChargeBlindCam ... abort." << endl;
+        *fLog << "  Size of MCalibrationChargeBlindCam: " << fCam->GetNumBlindPixels() << endl;
+        *fLog << "  Size of MExtractedSignalBlindPixel: " << nblindpixels << endl;
       return kFALSE;
     }
@@ -210,5 +211,5 @@
       fBlindPixelsArray->Expand(nblindpixels);
 
-      for (Int_t i=0; i<nblindpixels; i++)
+      for (UInt_t i=0; i<nblindpixels; i++)
 	{
 	  (*fBlindPixelsArray)[i] = new MHCalibrationChargeBlindPix;
@@ -230,5 +231,5 @@
   }
 
-  for (Int_t i=0; i<nblindpixels; i++)
+  for (UInt_t i=0; i<nblindpixels; i++)
     {
       TH1F *h = (*this)[i].GetHGausHist();
Index: trunk/MagicSoft/Mars/mfileio/MRead.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MRead.h	(revision 4693)
+++ trunk/MagicSoft/Mars/mfileio/MRead.h	(revision 4694)
@@ -17,6 +17,7 @@
     MRead() : fSelector(NULL) {}
 
-    virtual UInt_t GetEntries() = 0;
-    virtual Bool_t Rewind();
+    virtual UInt_t  GetEntries() = 0;
+    virtual TString GetFileName() const = 0;
+    virtual Bool_t  Rewind();
 
     void SetSelector(MFilter *f) { fSelector = f; }
Index: trunk/MagicSoft/Mars/mfileio/MReadMarsFile.cc
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MReadMarsFile.cc	(revision 4693)
+++ trunk/MagicSoft/Mars/mfileio/MReadMarsFile.cc	(revision 4694)
@@ -191,5 +191,5 @@
     if (!tlist)
     {
-        *fLog << err << dbginf << "ERROR - Task List not found in Parameter List." << endl;
+        *fLog << err << dbginf << "ERROR - MTaskList not found in Parameter List." << endl;
         return kFALSE;
     }
Index: trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.cc
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.cc	(revision 4693)
+++ trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.cc	(revision 4694)
@@ -188,5 +188,5 @@
 // a warning message is print.
 //
-Bool_t MWriteAsciiFile::CheckAndWrite() const
+Bool_t MWriteAsciiFile::CheckAndWrite()
 {
     Bool_t written = kFALSE;
Index: trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.h	(revision 4693)
+++ trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.h	(revision 4694)
@@ -21,5 +21,5 @@
     TObjArray fAutoDel; //! List of object to be deleted in the destructor
 
-    virtual Bool_t CheckAndWrite() const;
+    virtual Bool_t CheckAndWrite();
     virtual Bool_t IsFileOpen() const;
     virtual Bool_t GetContainer(MParList *pList);
Index: trunk/MagicSoft/Mars/mfileio/MWriteFile.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MWriteFile.h	(revision 4693)
+++ trunk/MagicSoft/Mars/mfileio/MWriteFile.h	(revision 4694)
@@ -8,12 +8,14 @@
 class MWriteFile : public MTask
 {
+protected:
+    Bool_t ReInit(MParList *pList);
+
 private:
     Int_t PreProcess(MParList *pList);
     Int_t Process();
     Int_t PostProcess();
-    Bool_t ReInit(MParList *pList);
 
     virtual Bool_t      IsFileOpen() const = 0;
-    virtual Bool_t      CheckAndWrite() const = 0;
+    virtual Bool_t      CheckAndWrite() = 0;
     virtual Bool_t      GetContainer(MParList *pList) = 0;
     virtual const char *GetFileName() const = 0;
Index: trunk/MagicSoft/Mars/mfileio/MWriteRootFile.cc
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MWriteRootFile.cc	(revision 4693)
+++ trunk/MagicSoft/Mars/mfileio/MWriteRootFile.cc	(revision 4694)
@@ -18,5 +18,5 @@
 !   Author(s): Thomas Bretz, 6/2001 <mailto:tbretz@astro.uni-wuerzburg.de>
 !
-!   Copyright: MAGIC Software Development, 2000-2003
+!   Copyright: MAGIC Software Development, 2000-2004
 !
 !
@@ -24,13 +24,17 @@
 
 /////////////////////////////////////////////////////////////////////////////
-//                                                                         //
-// 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.                             //
-//                                                                         //
+//
+// 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: Look at the Warning in MTaskList.
+//
+// There is a special mode of operation which opens a new file for each new
+// file read by the reading task (opening the new file is initiated by
+// ReInit()) For more details se the corresponding constructor.
+//
 /////////////////////////////////////////////////////////////////////////////
 #include "MWriteRootFile.h"
@@ -40,8 +44,10 @@
 #include <TFile.h>
 #include <TTree.h>
+#include <TRegexp.h>
 
 #include "MLog.h"
 #include "MLogManip.h"
 
+#include "MRead.h"
 #include "MParList.h"
 
@@ -51,6 +57,25 @@
 using namespace std;
 
-static const TString gsDefName  = "MWriteRootFile";
-static const TString gsDefTitle = "Task which writes a root-output file";
+const TString MWriteRootFile::gsDefName  = "MWriteRootFile";
+const TString MWriteRootFile::gsDefTitle = "Task which writes a root-output file";
+
+void MWriteRootFile::Init(const char *name, const char *title)
+{
+    fName  = name  ? name  : gsDefName.Data();
+    fTitle = title ? title : gsDefTitle.Data();
+
+    //
+    // 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();
+}
 
 // --------------------------------------------------------------------------
@@ -61,8 +86,41 @@
 MWriteRootFile::MWriteRootFile() : fOut(NULL)
 {
-    fName  = gsDefName;
-    fTitle = gsDefTitle;
-
+    Init();
+
+    //
+    // Set the Arrays the owner of its entries. This means, that the
+    // destructor of the arrays will delete all its entries.
+    //
     fBranches.SetOwner();
+}
+
+// --------------------------------------------------------------------------
+//
+// Use this constructor to run in a special mode.
+//
+// In this mode for each input file a new output file is written. This
+// happens in ReInit.
+//
+// comp:        Compression Level (see TFile, TBranch)
+// rule:        Rule to create output file name (see GetNewFileName())
+// overwrite:   Allow newly created file to overwrite old files ("RECREATE")
+// ftitle:      File title stored in the file (see TFile)
+// name, title: Name and title of this object
+//
+MWriteRootFile::MWriteRootFile(const Int_t comp,
+                               const char *rule,
+                               const Bool_t overwrite,
+                               const char *ftitle,
+                               const char *name,
+                               const char *title) : fSplitRule(rule)
+{
+    Init(name, title);
+
+    //
+    // Open a TFile in dummy mode! This is necessary to be able to create
+    // the trees and branches, which are then (in ReInit) moved to
+    // a valid file. (Stupid workaround - but does a good job)
+    //
+    fOut = new TFile("/dev/null", overwrite?"RECREATE":"NEW", ftitle, comp);
 }
 
@@ -81,19 +139,14 @@
                                const char *title)
 {
-    fName  = name  ? name  : gsDefName.Data();
-    fTitle = title ? title : gsDefTitle.Data();
-
-    //
-    // 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();
+    Init(name, title);
+
+    //
+    // If no name is given we open the TFile in some kind of dummy mode...
+    //
+    if (!fname)
+    {
+        fOut = new TFile("/dev/null", "READ", ftitle, comp);
+        return;
+    }
 
     TString str(fname);
@@ -112,5 +165,5 @@
 // properly.
 //
-MWriteRootFile::~MWriteRootFile()
+void MWriteRootFile::Close()
 {
     //
@@ -130,4 +183,5 @@
     //
     delete fOut;
+    fOut = 0;
 
     //
@@ -139,4 +193,13 @@
 
     *fLog << inf << "Output File closed and object deleted." << endl;
+}
+
+// --------------------------------------------------------------------------
+//
+// call Close()
+//
+MWriteRootFile::~MWriteRootFile()
+{
+    Close();
 }
 
@@ -350,4 +413,13 @@
             *fLog << inf << "Branch '" << cname << "' already existing... updating." << endl;
             branch->SetAddress(entry->GetAddress());
+
+            if (!fSplitRule.IsNull())
+            {
+                *fLog << warn << endl;
+                *fLog << "WARNING:   You are updating an existing branch.  For this" << endl;
+                *fLog << "     case file-splitting mode is not allowed... disabled!" << endl;
+                *fLog << endl;
+                fSplitRule = "";
+            }
         }
         else
@@ -365,4 +437,5 @@
 
             branch = tree->Branch(branchname, cont->ClassName(), entry->GetAddress());
+
             //
             // If the branch couldn't be created we have a problem.
@@ -376,4 +449,13 @@
 
             *fLog << "done." << endl;
+
+            if (!tree->TestBit(kIsNewTree) && !fSplitRule.IsNull())
+            {
+                *fLog << warn << endl;
+                *fLog << "WARNING:   You  have  created  a new branch  in  an existing tree." << endl;
+                *fLog << "     For this case file-splitting mode is not allowed... disabled!" << endl;
+                *fLog << endl;
+                fSplitRule= "";
+            }
         }
 
@@ -384,4 +466,5 @@
         entry->SetBranch(branch);
     }
+
     return kTRUE;
 }
@@ -401,5 +484,5 @@
 // has the write flag, all containers in this tree are filled!
 //
-Bool_t MWriteRootFile::CheckAndWrite() const
+Bool_t MWriteRootFile::CheckAndWrite()
 {
     TObject *obj;
@@ -438,8 +521,9 @@
     // Loop over all tree entries
     //
-    TIter NextTree(&fTrees);
-    while ((obj=NextTree()))
-    {
-        TTree *t = (TTree*)obj;
+    const Int_t n = fTrees.GetEntriesFast();
+
+    for (int idx=0; idx<n; idx++)
+    {
+        TTree *t = (TTree*)fTrees[idx];
 
         //
@@ -455,4 +539,5 @@
         //
         t->ResetBit(kFillTree);
+
         if (!t->Fill())
         {
@@ -461,4 +546,20 @@
         }
     }
+
+    //
+    // For more information see TTree:ChangeFile()
+    //
+    TTree *t0 = (TTree*)fTrees[0];
+    if (!t0 || fOut==t0->GetCurrentFile())
+        return kTRUE;
+
+    *fLog << warn << endl;
+    *fLog << "WARNING - MWriteRootFile:   Root's  TTree/TFile   has  opened   a  new  file" << endl;
+    *fLog << "  automatically.  You can change this behaviour using TTree::SetMaxTreeSize." << endl;
+    *fLog << "  You won't be able to read splitted  files  correctly with MReadMarsFile if" << endl;
+    *fLog << "  they have more than one entry in 'RunHeaders' or you try to read more than" << endl;
+    *fLog << "  one of such sequences at once." << endl;
+    *fLog << endl;
+
     return kTRUE;
 }
@@ -466,9 +567,198 @@
 // --------------------------------------------------------------------------
 //
+// Open a new file with the ame fname. Move all trees and branches from the
+// old file to the new file.
+//
+Bool_t MWriteRootFile::ChangeFile(const char *fname)
+{
+    //
+    // The following code is more or less a copy of TTree::ChangeFile
+    //
+    const Int_t   compr = fOut->GetCompressionLevel();
+    const TString title = fOut->GetTitle();
+
+    *fLog << inf << "MWriteRootFile - Open new file " << fname << " (Title=" << title << ", Compression=" << compr << ")" << endl;
+
+    // Open new file with old setup
+    TFile *newfile = TFile::Open(fname, "RECREATE", title, compr);
+    if (!newfile)
+    {
+        *fLog << err << "ERROR - Cannot open new file " << fname << endl;
+        return kFALSE;
+    }
+
+    // Print statistics of old file
+    const TString n = GetFileName();
+    if (!n.IsNull() && n!=TString("/dev/null"))
+        Print();
+
+    if (fOut->IsOpen())
+        fOut->Write();
+
+    // Move all trees from the old file to the new file
+    TObject *obj=0;
+    while ((obj = fOut->GetList()->First()))
+    {
+        // Remove obj from old file (otherwise deleting
+        // the old file will delete the objs)
+        fOut->GetList()->Remove(obj);
+
+        // If this is not a tree do nothing.
+        if (!obj->InheritsFrom("TTree"))
+            continue;
+
+        // process all trees in the old file
+        TTree *t = (TTree*)obj;
+
+        // reset and move to new file (this is done implicitly for all branches)
+        t->Reset();
+        t->SetDirectory(newfile);
+    }
+
+    // Close/delete the old file (keys already written above)
+    delete fOut;
+
+    // Replace current with new file
+    fOut = newfile;
+
+    // Change current directory to new file
+    gFile = fOut;
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// A rule looks like:
+//   "outputpath{s/source/destination}"
+//
+// outpath:                the output path into which the files are written
+// {s/source/destination}  a substitution rule for the filename
+//   while source can be a regular expression everything which matches this
+//   regular expression (see TRegexp) will be replaced by destination.
+//   Warning: The algorithm is recursive you may create endless loops!
+//
+// Example:
+//   inputfile: /data/MAGIC/Period016/rootdata/20040621_23210_D_Mkn421_E.root
+//   rule:      /outpath/{s/_D_/_Y_}
+//   outfile:   /outpath/20040621_23210_Y_Mkn421_E.root
+//
+// If you need more difficult rules please send me an eMail...
+//
+TString MWriteRootFile::GetNewFileName(const char *inname) const
+{
+    // Remove the path from the filename
+    TString fname(inname);
+    if (fname.Last('/')>=0)
+        fname.Remove(0, fname.Last('/')+1);
+
+    // Make a copy of the rule
+    TString rule(fSplitRule);
+
+    // [characte class], ^ do not, [^{}] do not match { and }, [^{}]+ match at least not one { or }
+    const TRegexp subst0("{s/[^{}/]+/[^{}/]+}");
+
+    TString path;
+    Bool_t first = kTRUE;
+
+    Ssiz_t idx=0;
+    while (1)
+    {
+        // Find a substitution exprsssion
+        Ssiz_t len = 0;
+        idx = subst0.Index(rule, &len);
+        if (idx<0)
+            break;
+
+        // If the first substitution expression is found in the rule
+        // determin the path from everything before
+        if (first)
+        {
+            path=rule(0, idx);
+            first = kFALSE;
+        }
+
+        // Extract a substitution expression
+        TString expr = rule(idx, len);
+        rule.Remove(idx, len);
+
+        expr.Remove(0,3);
+        expr.Remove(expr.Length()-1);
+
+        // In all cases this is well defined (see Regexp)
+        const Ssiz_t pos = expr.First('/');
+
+        // Split substitution rule into source and destination
+        const TString src  = expr(0, pos);
+        const TString dest = expr(pos+1, expr.Length());
+
+        // Replace source by destination
+        const TRegexp regexp(src);
+        while (1)
+        {
+            TString sub = fname(idx+dest.Length());
+            idx = regexp.Index(fname, &len);
+            if (idx<0)
+                break;
+
+            fname.Replace(idx, len, dest);
+        }
+    }
+
+    // Check if we have a trailing '/'
+    if (!path.IsNull() && path[path.Length()-1]!='/')
+        path.Append("/");
+
+    // Create full qualified pathname
+    path += fname;
+    return path;
+}
+
+// --------------------------------------------------------------------------
+//
+// ReInit. If file splitting is not allowed call MWriteFile::ReInit.
+//
+// In other cases get MRead from the TaskList (splitting is switched of if
+// this is impossible).
+//
+// Convert the input- into a new output file-name.
+//
+// Open a new file, change all trees to the new file (calling ChangeFile()),
+// and close the old one.
+//
+// Call MWriteFile::ReInit()
+//
+Bool_t MWriteRootFile::ReInit(MParList *pList)
+{
+    if (fSplitRule.IsNull())
+        return MWriteFile::ReInit(pList);
+
+    MRead *read = (MRead*)pList->FindTask("MRead");
+    if (!read)
+    {
+        *fLog << warn;
+        *fLog << "WARNING: No Task 'MRead' found in the tasklist.  This task is" << endl;
+        *fLog << "  necessary  to  get  the filename.  Without  a filename file" << endl;
+        *fLog << "  file splitting is not allowed... disabled!" << endl;
+        *fLog << endl;
+        fSplitRule = "";
+        return kTRUE;
+    }
+
+    const TString fname = GetNewFileName(read->GetFileName());
+    if (!ChangeFile(fname))
+        return kFALSE;
+
+    return MWriteFile::ReInit(pList);
+}
+
+// --------------------------------------------------------------------------
+//
 // return open state of the root file.
 //
 Bool_t MWriteRootFile::IsFileOpen() const
 {
-    return fOut->IsOpen();
+    const char *n = fOut->GetName();
+    return n==0 || *n==0 ? kTRUE : fOut->IsOpen();
 }
 
@@ -479,5 +769,6 @@
 const char *MWriteRootFile::GetFileName() const
 {
-    return fOut->GetName();
+    const char *n = fOut->GetName();
+    return n==0 || *n==0 ? "<dummy>" : n;
 }
 
Index: trunk/MagicSoft/Mars/mfileio/MWriteRootFile.h
===================================================================
--- trunk/MagicSoft/Mars/mfileio/MWriteRootFile.h	(revision 4693)
+++ trunk/MagicSoft/Mars/mfileio/MWriteRootFile.h	(revision 4694)
@@ -7,4 +7,7 @@
 #ifndef ROOT_TObjArray
 #include <TObjArray.h>
+#endif
+#ifndef ROOT_TArrayL
+#include <TArrayL.h>
 #endif
 
@@ -68,21 +71,17 @@
 {
 private:
-    TFile *fOut;
+    static const TString gsDefName;
+    static const TString gsDefTitle;
 
-    TObjArray fBranches;
-    TObjArray fTrees;     //!
+    TFile *fOut;             // Current file
 
-    //UInt_t fNumEvents; //! Number of events written in a run
+    TObjArray fBranches;     // List of Branch setup (MRootFileBranch)
+    TObjArray fTrees;        //! List of trees
 
-    Bool_t      CheckAndWrite() const;
-    Bool_t      IsFileOpen() const;
-    Bool_t      GetContainer(MParList *pList);
-    const char *GetFileName() const;
-
-    void StreamPrimitive(ofstream &out) const;
-    //Bool_t ReInit(MParList *pList);
+    TString fSplitRule;      // file splitting allowed if rule existing (done in ReInit)
 
     enum {
         kFillTree  = BIT(14),
+        // Be carefull these bits are already in use!
         // TBranch::kAutoDelete = BIT(15)
         // TBranchElement::kDeleteObject = BIT(16)
@@ -90,18 +89,40 @@
     };
 
+    // File handling
+    void    Close();
+    TString GetNewFileName(const char *fname) const;
+    Bool_t  ChangeFile(const char *fname);
+
+    // MWrite
+    Bool_t      CheckAndWrite();
+    Bool_t      IsFileOpen() const;
+    Bool_t      GetContainer(MParList *pList);
+    const char *GetFileName() const;
+
+    // MTask
+    Bool_t ReInit(MParList *pList);
+    void   StreamPrimitive(ofstream &out) const;
+
+    // Constructor
+    void Init(const char *name=0, const char *title=0);
+
 public:
     MWriteRootFile();
+    MWriteRootFile(const Int_t comp,
+                   const char *rule,
+                   const Bool_t overwrite=kTRUE,
+                   const char *ftitle="Untitled",
+                   const char *name=NULL,
+                   const char *title=NULL);
     MWriteRootFile(const char *fname,
                    const Option_t *opt="RECREATE",
                    const char *ftitle="Untitled",
-                   const Int_t comp=9,
+                   const Int_t comp=2,
                    const char *name=NULL,
                    const char *title=NULL);
     ~MWriteRootFile();
 
-
     void AddContainer(const char *cname,   const char *tname=NULL, Bool_t must=kTRUE);
     void AddContainer(MParContainer *cont, const char *tname=NULL, Bool_t must=kTRUE);
-
 
     void Print(Option_t *t=NULL) const;
Index: trunk/MagicSoft/Mars/mraw/MRawFileRead.cc
===================================================================
--- trunk/MagicSoft/Mars/mraw/MRawFileRead.cc	(revision 4693)
+++ trunk/MagicSoft/Mars/mraw/MRawFileRead.cc	(revision 4694)
@@ -109,6 +109,6 @@
     fFileNames->SetOwner();
 
-    if(fname!=NULL)
-      AddFile(fname);
+    if (fname!=NULL)
+        AddFile(fname);
 }
 
@@ -230,5 +230,5 @@
 // Return file name of current file.
 //
-const TString MRawFileRead::GetFileName() const
+TString MRawFileRead::GetFileName() const
 {
     const TObject *file = fFileNames->At(fNumFile-1);
Index: trunk/MagicSoft/Mars/mraw/MRawFileRead.h
===================================================================
--- trunk/MagicSoft/Mars/mraw/MRawFileRead.h	(revision 4693)
+++ trunk/MagicSoft/Mars/mraw/MRawFileRead.h	(revision 4694)
@@ -34,5 +34,5 @@
     void SetInterleave(UInt_t i) { fInterleave = i; }
 
-    const TString GetFileName() const;
+    TString GetFileName() const;
 
     Int_t  AddFile(const char *fname, Int_t entries=-1);
Index: trunk/MagicSoft/Mars/mraw/MRawFileWrite.cc
===================================================================
--- trunk/MagicSoft/Mars/mraw/MRawFileWrite.cc	(revision 4693)
+++ trunk/MagicSoft/Mars/mraw/MRawFileWrite.cc	(revision 4694)
@@ -65,5 +65,5 @@
                              const char *ftitle,
                              const Int_t comp,
-                             const char *name, const char *title)
+                             const char *name, const char *title) : fSplit(kFALSE)
 {
     fName  = name  ? name  : "MRawFileWrite";
@@ -82,4 +82,20 @@
 MRawFileWrite::~MRawFileWrite()
 {
+    if (fOut != fTData->GetCurrentFile())
+    {
+        *fLog << warn << endl;
+        *fLog << "WARNING - MWriteRootFile:   Root's  TTree/TFile   has  opened   a  new  file" << endl;
+        *fLog << "  automatically.  You can change this behaviour using TTree::SetMaxTreeSize." << endl;
+        *fLog << "  You won't be able to read splitted  files  correctly with MReadMarsFile if" << endl;
+        *fLog << "  they have more than one entry in 'RunHeaders' or you try to read more than" << endl;
+        *fLog << "  one of such sequences at once." << endl;
+        *fLog << endl;
+    }
+
+    //
+    // For more information see TTree:ChangeFile()
+    //
+    fOut = fTData->GetCurrentFile();
+
     //
     // delete instance, this also does a fOut->Close()
@@ -125,9 +141,4 @@
 
     //
-    // remember the pointer to the parameter list fur further usage
-    //
-    pParList = pList;
-
-    //
     //  check if MEvtHeader exists in the Parameter list already.
     //  if not create one and add them to the list
@@ -180,7 +191,7 @@
     // create data trees for the three types of data
     //
-    fTData        = new TTree("Events",      "Normal Triggered Events");
-    fTPedestal    = new TTree("Pedestals",   "Pedestal Triggered Events");
-    fTCalibration = new TTree("Calibration", "Calibration Triggered Events");
+    fTData        =          new TTree("Events",      "Normal Triggered Events");
+    fTPedestal    = fSplit ? new TTree("Pedestals",   "Pedestal Triggered Events")    : fTData;
+    fTCalibration = fSplit ? new TTree("Calibration", "Calibration Triggered Events") : fTData;
 
     //
@@ -207,15 +218,17 @@
     // FIXME: Can we calculate a good buffer size out of the event size?
     //        using splitlevel=0 sppeds up writing by a factor of 5-10%
-    fTData       ->Branch("MTime.",          "MTime",          &fTime,          32000);
+    fTData->Branch("MTime.",          "MTime",          &fTime,          32000);
+    fTData->Branch("MRawEvtHeader.",  "MRawEvtHeader",  &fRawEvtHeader,  32000);
+    fTData->Branch("MRawEvtData.",    "MRawEvtData",    &fRawEvtData,    320000);
+    fTData->Branch("MRawCrateArray.", "MRawCrateArray", &fRawCrateArray, 32000);
+    if (!fSplit)
+        return kTRUE;
+
     fTPedestal   ->Branch("MTime.",          "MTime",          &fTime,          32000);
     fTCalibration->Branch("MTime.",          "MTime",          &fTime,          32000);
-    fTData       ->Branch("MRawEvtHeader.",  "MRawEvtHeader",  &fRawEvtHeader,  32000);
     fTPedestal   ->Branch("MRawEvtHeader.",  "MRawEvtHeader",  &fRawEvtHeader,  32000);
     fTCalibration->Branch("MRawEvtHeader.",  "MRawEvtHeader",  &fRawEvtHeader,  32000);
-    fTData       ->Branch("MRawEvtData.",    "MRawEvtData",    &fRawEvtData,    320000);
     fTPedestal   ->Branch("MRawEvtData.",    "MRawEvtData",    &fRawEvtData,    320000);
     fTCalibration->Branch("MRawEvtData.",    "MRawEvtData",    &fRawEvtData,    320000);
-    //fTree->Branch("MRawCrateArray",  fRawCrateArray->GetArray(),      32000, 1);
-    fTData       ->Branch("MRawCrateArray.", "MRawCrateArray", &fRawCrateArray, 32000);
     fTPedestal   ->Branch("MRawCrateArray.", "MRawCrateArray", &fRawCrateArray, 32000);
     fTCalibration->Branch("MRawCrateArray.", "MRawCrateArray", &fRawCrateArray, 32000);
Index: trunk/MagicSoft/Mars/mraw/MRawFileWrite.h
===================================================================
--- trunk/MagicSoft/Mars/mraw/MRawFileWrite.h	(revision 4693)
+++ trunk/MagicSoft/Mars/mraw/MRawFileWrite.h	(revision 4694)
@@ -19,6 +19,4 @@
 {
 private:
-    MParList *pParList;
-
     MTime          *fTime;
     MRawRunHeader  *fRawRunHeader;
@@ -35,4 +33,6 @@
     TFile *fOut;                    //!
 
+    Bool_t fSplit;
+
     Int_t  PreProcess(MParList *pList);
     Bool_t ReInit(MParList *pList);
@@ -47,4 +47,6 @@
     ~MRawFileWrite();
 
+    void EnableSplit(Bool_t b=kTRUE) { fSplit=b; }
+
     ClassDef(MRawFileWrite, 0)	// Task to write the raw data containers to a root file
 };
Index: trunk/MagicSoft/Mars/msql/MSQLServer.cc
===================================================================
--- trunk/MagicSoft/Mars/msql/MSQLServer.cc	(revision 4693)
+++ trunk/MagicSoft/Mars/msql/MSQLServer.cc	(revision 4694)
@@ -410,7 +410,33 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// Send a SQL query to the SQl server.
+//
+// If MSQLServer is no server (column, row, ...) NULL is returned and an
+//  error message is send to stdout.
+//
+// If the query failed for some reason an error message is send to stdout
+//  and NULL is returned.
+//
+// If everything works fine a TSQLResult is returned. Make sure that you
+// delete it!
+//
 TSQLResult *MSQLServer::Query(const char *sql) /*FOLD00*/
 {
-    return fType==kIsServer ? fServ->Query(sql) : NULL;
+    if (fType!=kIsServer)
+    {
+        cout << "ERROR: MSQLServer::Query - this is not a server!" << endl;
+        return NULL;
+    }
+
+    TSQLResult *res = fServ->Query(sql);
+    if (!res)
+    {
+        cout << "ERROR: MSQLServer::Query - Query failed: " << sql << endl;
+        return NULL;
+    }
+
+    return res;
 }
 
