Index: trunk/MagicSoft/Mars/mtools/MTFillMatrix.cc
===================================================================
--- trunk/MagicSoft/Mars/mtools/MTFillMatrix.cc	(revision 2690)
+++ trunk/MagicSoft/Mars/mtools/MTFillMatrix.cc	(revision 2690)
@@ -0,0 +1,207 @@
+/* ======================================================================== *\
+!
+! *
+! * 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/2003 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2003
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//   MTFillMatrix
+//
+/////////////////////////////////////////////////////////////////////////////
+#include "MTFillMatrix.h"
+
+#include <TFile.h>
+
+#include "MHMatrix.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+#include "MTaskList.h"
+#include "MEvtLoop.h"
+
+#include "MRead.h"
+#include "MFillH.h"
+#include "MContinue.h"
+#include "MFilterList.h"
+#include "MFRandomSplit.h"
+#include "MFEventSelector2.h"
+
+ClassImp(MTFillMatrix);
+
+using namespace std;
+
+Bool_t MTFillMatrix::CheckResult(MHMatrix *m, Int_t num) const
+{
+    if (!m)
+        return kTRUE;
+
+    m->Print("SizeCols");
+
+    const Int_t generated = m->GetM().GetNrows();
+    if (TMath::Abs(generated-num) <= TMath::Sqrt(9.0*num))
+        return kTRUE;
+
+    *fLog << warn << "WARNING - No. of generated events (";
+    *fLog << generated << ") incompatible with requested events (";
+    *fLog << num << ") for " << m->GetDescriptor() << endl;
+
+    return kFALSE;
+}
+
+Bool_t MTFillMatrix::WriteMatrix(MHMatrix *m, const TString &fname, Int_t i) const
+{
+    if (!m)
+    {
+        *fLog << "ERROR - Unable to write matrix #" << i << " (=NULL)... ignored." << endl;
+        return kFALSE;
+    }
+
+    TFile file(fname, "RECREATE", m->GetTitle());
+    m->Write();
+    return kTRUE;
+}
+
+MTFillMatrix::MTFillMatrix(const MH3 &ref)
+: fReference(ref), fReader(0), fDestMatrix1(0),
+fDestMatrix2(0), fNumDestEvents1(0), fNumDestEvents2(0),
+fWriteFile1(0), fWriteFile2(0)
+{
+    fName  = "MFillMatrix";
+    fTitle = "Tool to fill MHMatrix from file";
+}
+
+Bool_t MTFillMatrix::Process()
+{
+    if (!fReader)
+    {
+        *fLog << err << "ERROR - No task to read data was given... abort." << endl;
+        return kFALSE;
+    }
+
+    const Bool_t useorigdistrib = fReference.GetHist().GetEntries()==0;
+
+    *fLog << inf;
+    fLog->Separator(GetDescriptor());
+    *fLog << "Fill " << fDestMatrix1->GetDescriptor() << " with " << fNumDestEvents1 << endl;
+    *fLog << "Fill " << fDestMatrix2->GetDescriptor() << " with " << fNumDestEvents2 << endl;
+        *fLog << "Distribution choosen ";
+    if (!useorigdistrib)
+        *fLog << "from " << fReference.GetDescriptor();
+    else
+        *fLog << "randomly";
+    *fLog << endl;
+
+    //
+    // Create parameter list and task list, add tasklist to parlist
+    //
+    MParList  plist;
+    MTaskList tlist;
+    plist.AddToList(&tlist);
+
+    //
+    // A selector to select a given number of events from a sample
+    //
+    MFEventSelector2 selector(fReference);
+    selector.SetNumMax(fNumDestEvents1+fNumDestEvents2);
+    selector.SetInverted();
+    if (useorigdistrib)
+        selector.SetUseOrigDistribution(kTRUE);
+
+    //
+    // Continue for all events which are not (SetInverted())
+    // selected by the 'selector'
+    //
+    MContinue cont(&selector);
+
+    //
+    // Create a filter doing a random split
+    //
+    const Double_t prob = (Double_t)fNumDestEvents1/(fNumDestEvents1+fNumDestEvents2);
+    MFRandomSplit split(prob);
+
+    //
+    // Create the logical inverted filter for 'split'
+    //
+    MFilterList invsplit;
+    invsplit.AddToList(&split);
+    invsplit.SetInverted();
+
+    //
+    // The two tasks filling the two matrices
+    //
+    MFillH fill1(fDestMatrix1);
+    MFillH fill2(fDestMatrix2);
+    fill1.SetFilter(&split);
+    fill2.SetFilter(&invsplit);
+
+    // entries in MTaskList
+    tlist.AddToList(fReader);    // Read events
+    tlist.AddToList(&cont);      // select a sample of events
+    tlist.AddToList(&invsplit);  // process invsplit (which implicitly processes split)
+    if (fDestMatrix1 && fNumDestEvents1>0)
+        tlist.AddToList(&fill1); // fill matrix 1
+    if (fDestMatrix2 && fNumDestEvents2>0)
+        tlist.AddToList(&fill2); // fill matrix 2
+    if (fWriteFile1)
+    {
+        fWriteFile1->SetFilter(&split);
+        tlist.AddToList(fWriteFile1);
+    }
+    if (fWriteFile2)
+    {
+        fWriteFile2->SetFilter(&invsplit);
+        tlist.AddToList(fWriteFile2);
+    }
+
+    //
+    // Execute the eventloop
+    //
+    MEvtLoop evtloop(fName);
+    evtloop.SetParList(&plist);
+    if (!evtloop.Eventloop())
+    {
+        *fLog << err << GetDescriptor() << ": Failed." << endl;
+        return kFALSE;
+    }
+
+    tlist.PrintStatistics();
+
+    CheckResult(fDestMatrix1, fNumDestEvents1);
+    CheckResult(fDestMatrix2, fNumDestEvents2);
+
+    *fLog << inf << GetDescriptor() << ": Done." << endl;
+    return kTRUE;
+}
+
+Bool_t MTFillMatrix::WriteMatrices(const TString &fname) const
+{
+    if (fDestMatrix1 && fDestMatrix2 &&
+        (TString)fDestMatrix1->GetName()==(TString)fDestMatrix2->GetName())
+    {
+        *fLog << "ERROR - Cannot write matrices (both have the same name)... ignored." << endl;
+        return kFALSE;
+    }
+
+    return WriteMatrix1(fname) && WriteMatrix2(fname);
+}
Index: trunk/MagicSoft/Mars/mtools/MTFillMatrix.h
===================================================================
--- trunk/MagicSoft/Mars/mtools/MTFillMatrix.h	(revision 2690)
+++ trunk/MagicSoft/Mars/mtools/MTFillMatrix.h	(revision 2690)
@@ -0,0 +1,73 @@
+#ifndef MARS_MTFillMatrix
+#define MARS_MTFillMatrix
+
+#ifndef MARS_MH3
+#include "MH3.h"
+#endif
+
+class MRead;
+class MTask;
+class MHMatrix;
+
+class MTFillMatrix : public MParContainer
+{
+private:
+    MH3       fReference;
+    MRead    *fReader;
+    MHMatrix *fDestMatrix1;
+    MHMatrix *fDestMatrix2;
+    Int_t     fNumDestEvents1;
+    Int_t     fNumDestEvents2;
+    MTask    *fWriteFile1;
+    MTask    *fWriteFile2;
+
+    Bool_t CheckResult(MHMatrix *m, Int_t num) const;
+    Bool_t WriteMatrix(MHMatrix *m, const TString &fname, Int_t i) const;
+
+public:
+    MTFillMatrix(const MH3 &ref);
+
+    void SetDestMatrix1(MHMatrix *matrix, UInt_t num=0)
+    {
+        fDestMatrix1 = matrix;
+        if (num>0)
+            fNumDestEvents1 = num;
+    }
+    void SetWriteFile1(MTask *write, UInt_t num=0)
+    {
+        fWriteFile1 = write;
+        if (num>0)
+            fNumDestEvents1 = num;
+    }
+    void SetNumDestEvents1(UInt_t num)
+    {
+        fNumDestEvents1 = num;
+    }
+    void SetDestMatrix2(MHMatrix *matrix, UInt_t num=0)
+    {
+        fDestMatrix2 = matrix;
+        if (num>0)
+            fNumDestEvents2 = num;
+    }
+    void SetWriteFile2(MTask *write, UInt_t num=0)
+    {
+        fWriteFile2 = write;
+        if (num>0)
+            fNumDestEvents2 = num;
+    }
+    void SetNumDestEvents2(UInt_t num)
+    {
+        fNumDestEvents2 = num;
+    }
+
+    void SetReader(MRead *task) { fReader = task; }
+
+    Bool_t Process();
+    Bool_t WriteMatrix1(const TString &fname) const { return WriteMatrix(fDestMatrix1, fname, 1); }
+    Bool_t WriteMatrix2(const TString &fname) const { return WriteMatrix(fDestMatrix2, fname, 2); }
+    Bool_t WriteMatrices(const TString &fname) const;
+
+    ClassDef(MTFillMatrix, 0)
+};
+
+#endif
Index: trunk/MagicSoft/Mars/mtools/Makefile
===================================================================
--- trunk/MagicSoft/Mars/mtools/Makefile	(revision 2604)
+++ trunk/MagicSoft/Mars/mtools/Makefile	(revision 2690)
@@ -22,5 +22,6 @@
 #  connect the include files defined in the config.mk file
 #
-INCLUDES = -I. -I../mbase -I../mgui -I../mgeom -I../mdata
+INCLUDES = -I. -I../mbase -I../mgui -I../mgeom -I../mdata -I../mhist \
+	   -I../mfileio -I../mfilter
 
 #------------------------------------------------------------------------------
@@ -29,4 +30,5 @@
 
 SRCFILES = MChisqEval.cc \
+	   MTFillMatrix.cc \
 	   MagicReversi.cc \
 	   MagicSnake.cc \
Index: trunk/MagicSoft/Mars/mtools/ToolsLinkDef.h
===================================================================
--- trunk/MagicSoft/Mars/mtools/ToolsLinkDef.h	(revision 2604)
+++ trunk/MagicSoft/Mars/mtools/ToolsLinkDef.h	(revision 2690)
@@ -6,4 +6,7 @@
 
 #pragma link C++ class MChisqEval+;
+
+#pragma link C++ class MTFillMatrix+;
+
 #pragma link C++ class MineSweeper+;
 #pragma link C++ class MagicReversi+;
