Index: trunk/MagicSoft/Mars/mranforest/MHRanForestGini.cc
===================================================================
--- trunk/MagicSoft/Mars/mranforest/MHRanForestGini.cc	(revision 7411)
+++ trunk/MagicSoft/Mars/mranforest/MHRanForestGini.cc	(revision 7413)
@@ -43,4 +43,5 @@
 #include "MRanTree.h"
 #include "MRanForest.h"
+#include "MDataArray.h"
 
 #include "MLog.h"
@@ -57,4 +58,5 @@
 //
 MHRanForestGini::MHRanForestGini(Int_t nbins, const char *name, const char *title)
+    : fRules(0.01, 0.01, 0.99, 0.99)
 {
     //
@@ -64,16 +66,15 @@
     fTitle = title ? title : "Measure of importance of Random Forest-input parameters";
 
-    fGraphGini = new TGraph;
-    fGraphGini->SetTitle("Importance of RF-input parameters measured by mean Gini decrease");
-    fGraphGini->SetMarkerStyle(kFullDotSmall);
-}
-
-// --------------------------------------------------------------------------
-//
-// Delete the histograms.
-//
-MHRanForestGini::~MHRanForestGini()
-{
-    delete fGraphGini;
+    fGraphGini.SetNameTitle("Gini", "Importance of RF-input parameters measured by mean Gini decrease");
+    fGraphGini.SetMarkerStyle(kFullDotMedium);
+
+    fGraphError.SetNameTitle("ResErr", "Resolution/Error versus train step");
+    fGraphError.SetMarkerStyle(kFullDotMedium);
+
+    fGraphNodes.SetNameTitle("Nodes", "Number of nodes versus train step");
+    fGraphNodes.SetMarkerStyle(kFullDotMedium);
+
+    fRules.SetTextAlign(13);
+    fRules.SetTextSize(0.05);
 }
 
@@ -104,6 +105,11 @@
 Bool_t MHRanForestGini::Fill(const MParContainer *par, const Stat_t w)
 {
+    MRanTree *t = fRanForest->GetCurTree();
+
     for (Int_t i=0;i<fRanForest->GetNumDim();i++)
-        fGini[i]+=fRanForest->GetCurTree()->GetGiniDec(i);
+        fGini[i] += t->GetGiniDec(i);
+
+    fGraphError.SetPoint(fGraphError.GetN(), GetNumExecutions(), t->GetError());
+    fGraphNodes.SetPoint(fGraphError.GetN(), GetNumExecutions(), t->GetNumEndNodes());
 
     return kTRUE;
@@ -117,27 +123,25 @@
     const Int_t n = fGini.GetSize();
 
-    fGraphGini->Set(n);
-
-    Stat_t max=0;
-    Stat_t min=0;
+    fGraphGini.Set(n);
+
     for (Int_t i=0; i<n; i++)
     {
-        fGini[i] /= fRanForest->GetNumTrees();
-        fGini[i] /= fRanForest->GetNumData();
-
-        const Stat_t ip = i+1;
-        const Stat_t ig = fGini[i];
-
-        if (ig>max) max=ig;
-        if (ig<min) min=ig;
-
-        fGraphGini->SetPoint(i,ip,ig);
-    }
-
-    // This is used in root>3.04/? so that SetMaximum/Minimum can succeed
-    fGraphGini->GetHistogram();
-
-    fGraphGini->SetMaximum(1.05*max);
-    fGraphGini->SetMinimum(0.95*min);
+        fGini[i] /= fRanForest->GetNumTrees()*fRanForest->GetNumData();
+        fGraphGini.SetPoint(i, i+1, fGini[i]);
+    }
+
+    fRules.AddText("");
+    const MDataArray &arr = *fRanForest->GetRules();
+    int i;
+    for (i=0; i<arr.GetNumEntries(); i++)
+    {
+        TString s;
+        s += i+1;
+        s += ") ";
+        s += arr.GetRule(i);
+        fRules.AddText(s);
+    }
+    for (; i<20; i++)
+        fRules.AddText("");
 
     return kTRUE;
@@ -150,5 +154,5 @@
 void MHRanForestGini::Draw(Option_t *)
 {
-    if (fGraphGini->GetN()==0)
+    if (fGraphGini.GetN()==0)
         return;
 
@@ -158,17 +162,42 @@
     AppendPad("");
 
-    fGraphGini->Draw("ALP");
-    pad->Modified();
-    pad->Update();
-
-    TH1 *h = fGraphGini->GetHistogram();
-    if (!h)
-        return;
-
-    //h->GetXaxis()->SetRangeUser(0, fGini.GetSize()+1);
-    h->SetXTitle("No.of RF-input parameter");
-    h->SetYTitle("Mean decrease in Gini-index [a.u.]");
-
-    pad->Modified();
-    pad->Update();
-}
+    pad->Divide(2,2);
+
+    pad->cd(1);
+    gPad->SetBorderMode(0);
+    gPad->SetGridx();
+    gPad->SetGridy();
+    fGraphGini.Draw("ALP");
+
+    TH1 *h = fGraphGini.GetHistogram();
+    if (h)
+    {
+        h->SetXTitle("No.of RF-input parameter");
+        h->SetYTitle("Mean decrease in Gini-index [au]");
+        h->GetXaxis()->SetNdivisions(10);
+    }
+
+    pad->cd(2);
+    gPad->SetBorderMode(0);
+    fGraphError.Draw("ALP");
+    h = fGraphError.GetHistogram();
+    if (h)
+    {
+        h->SetXTitle("Train step/Tree number");
+        h->SetYTitle("Error/Resolution");
+    }
+
+    pad->cd(3);
+    gPad->SetBorderMode(0);
+    fGraphNodes.Draw("ALP");
+    h = fGraphNodes.GetHistogram();
+    if (h)
+    {
+        h->SetXTitle("Train step/Tree number");
+        h->SetYTitle("Number of end nodes");
+    }
+
+    pad->cd(4);
+    gPad->SetBorderMode(0);
+    fRules.Draw();
+}
Index: trunk/MagicSoft/Mars/mranforest/MHRanForestGini.h
===================================================================
--- trunk/MagicSoft/Mars/mranforest/MHRanForestGini.h	(revision 7411)
+++ trunk/MagicSoft/Mars/mranforest/MHRanForestGini.h	(revision 7413)
@@ -9,7 +9,11 @@
 #include <TArrayF.h>
 #endif
+#ifndef ROOT_TGraph
+#include <TGraph.h>
+#endif
+#ifndef ROOT_TPaveText
+#include <TPaveText.h>
+#endif
 
-class TH1D;
-class TGraph;
 class MParList;
 class MRanForest;
@@ -22,11 +26,13 @@
 
     TArrayF fGini;           //!
-    TGraph *fGraphGini;      //->
+
+    TGraph  fGraphGini;
+    TGraph  fGraphError;
+    TGraph  fGraphNodes;
+
+    TPaveText fRules;
 
 public:
     MHRanForestGini(Int_t nbins=100, const char *name=NULL, const char *title=NULL);
-    ~MHRanForestGini();
-
-    TGraph *GetGraphGini() const  { return fGraphGini; }
 
     Bool_t SetupFill(const MParList *plist);
Index: trunk/MagicSoft/Mars/mranforest/MRanForest.cc
===================================================================
--- trunk/MagicSoft/Mars/mranforest/MRanForest.cc	(revision 7411)
+++ trunk/MagicSoft/Mars/mranforest/MRanForest.cc	(revision 7413)
@@ -166,5 +166,5 @@
         if(grid[i]>=grid[i+1])
         {
-            *fLog<<inf<<"Grid points must be in increasing order! Ignoring grid."<<endl;
+            *fLog<<warn<<"Grid points must be in increasing order! Ignoring grid."<<endl;
             return;
         }
@@ -225,6 +225,4 @@
             fClass[j] = int(fHadTrue[j]+0.5);
     }
-
-    return;
 }
 
@@ -272,5 +270,5 @@
 Bool_t MRanForest::AddTree(MRanTree *rantree=NULL)
 {
-    fRanTree = rantree ? rantree:fRanTree;
+    fRanTree = rantree ? rantree : fRanTree;
 
     if (!fRanTree) return kFALSE;
@@ -287,9 +285,8 @@
     // access matrix, copy last column (target) preliminarily
     // into fHadTrue
-    TMatrix mat_tmp = mat->GetM();
-    int dim         = mat_tmp.GetNcols();
-    int numdata     = mat_tmp.GetNrows();
-
-    fMatrix=new TMatrix(mat_tmp);
+    fMatrix = new TMatrix(mat->GetM());
+
+    int dim     = fMatrix->GetNcols()-1;
+    int numdata = fMatrix->GetNrows();
 
     fHadTrue.Set(numdata);
@@ -297,9 +294,8 @@
 
     for (Int_t j=0;j<numdata;j++)
-        fHadTrue[j] = (*fMatrix)(j,dim-1);
+        fHadTrue[j] = (*fMatrix)(j,dim);
 
     // remove last col
-    fMatrix->ResizeTo(numdata,dim-1);
-    dim=fMatrix->GetNcols();
+    fMatrix->ResizeTo(numdata,dim);
 
     //-------------------------------------------------------------------
@@ -308,12 +304,20 @@
     fClass.Reset(0);
 
-    if(fClassify) PrepareClasses();
+    if (fClassify)
+        PrepareClasses();
 
     //-------------------------------------------------------------------
     // allocating and initializing arrays
-    fHadEst.Set(numdata);       fHadEst.Reset(0);
-    fNTimesOutBag.Set(numdata); fNTimesOutBag.Reset(0);
-    fDataSort.Set(dim*numdata); fDataSort.Reset(0);
-    fDataRang.Set(dim*numdata); fDataRang.Reset(0);
+    fHadEst.Set(numdata);
+    fHadEst.Reset(0);
+
+    fNTimesOutBag.Set(numdata);
+    fNTimesOutBag.Reset(0);
+
+    fDataSort.Set(dim*numdata);
+    fDataSort.Reset(0);
+
+    fDataRang.Set(dim*numdata);
+    fDataRang.Reset(0);
 
     if(fWeight.GetSize()!=numdata)
@@ -326,5 +330,5 @@
     //-------------------------------------------------------------------
     // setup rules to be used for classification/regression
-    MDataArray *allrules=(MDataArray*)mat->GetColumns();
+    const MDataArray *allrules=(MDataArray*)mat->GetColumns();
     if(allrules==NULL)
     {
@@ -333,36 +337,28 @@
     }
 
-    fRules=new MDataArray(); fRules->Reset();
-    TString target_rule;
-
-    for(Int_t i=0;i<dim+1;i++)
-    {
-        MData &data=(*allrules)[i];
-        if(i<dim)
-            fRules->AddEntry(data.GetRule());
-        else
-            target_rule=data.GetRule();
-    }
-
-    *fLog << inf <<endl;
-    *fLog << inf <<"Setting up RF for training on target:"<<endl<<" "<<target_rule.Data()<<endl;
-    *fLog << inf <<"Following rules are used as input to RF:"<<endl;
-
-    for(Int_t i=0;i<dim;i++)
-    {
-        MData &data=(*fRules)[i];
-        *fLog<<inf<<" "<<i<<") "<<data.GetRule()<<endl<<flush;
-    }
-
-    *fLog << inf <<endl;
+    fRules = new MDataArray();
+    fRules->Reset();
+
+    const TString target_rule = (*allrules)[dim];
+    for (Int_t i=0;i<dim;i++)
+        fRules->AddEntry((*allrules)[i].GetRule());
+
+    *fLog << inf << endl;
+    *fLog << "Setting up RF for training on target:" << endl;
+    *fLog << " " << target_rule.Data() << endl;
+    *fLog << "Following rules are used as input to RF:" << endl;
+    for (Int_t i=0;i<dim;i++)
+        *fLog << " " << i << ") " << (*fRules)[i].GetRule() << endl;
+
+    *fLog << endl;
 
     //-------------------------------------------------------------------
     // prepare (sort) data for fast optimization algorithm
-    if(!CreateDataSort()) return kFALSE;
+    if (!CreateDataSort())
+        return kFALSE;
 
     //-------------------------------------------------------------------
     // access and init tree container
     fRanTree = (MRanTree*)plist->FindCreateObj("MRanTree");
-
     if(!fRanTree)
     {
@@ -371,25 +367,28 @@
     }
 
+    const Int_t tryest = TMath::Nint(TMath::Sqrt(dim)+0.5);
+
+    *fLog << inf << endl;
+    *fLog << "Following input for the tree growing are used:"<<endl;
+    *fLog << " Number of Trees : "<<fNumTrees<<endl;
+    *fLog << " Number of Trials: "<<(fNumTry==0?tryest:fNumTry)<<(fNumTry==0?" (auto)":"")<<endl;
+    *fLog << " Final Node size : "<<fNdSize<<endl;
+    *fLog << " Using Grid:       "<<(fGrid.GetSize()>0?"Yes":"No")<<endl;
+    *fLog << " Number of Events: "<<numdata<<endl;
+    *fLog << " Number of Params: "<<dim<<endl;
+
+    if(fNumTry==0)
+    {
+        fNumTry=tryest;
+        *fLog << inf << endl;
+        *fLog << "Set no. of trials to the recommended value of round("<< TMath::Sqrt(dim) <<") = ";
+        *fLog << fNumTry << endl;
+
+
+    }
+    fRanTree->SetNumTry(fNumTry);
     fRanTree->SetClassify(fClassify);
     fRanTree->SetNdSize(fNdSize);
 
-    if(fNumTry==0)
-    {
-        double ddim = double(dim);
-
-        fNumTry=int(sqrt(ddim)+0.5);
-        *fLog<<inf<<endl;
-        *fLog<<inf<<"Set no. of trials to the recommended value of round("<<sqrt(ddim)<<") = ";
-        *fLog<<inf<<fNumTry<<endl;
-
-    }
-    fRanTree->SetNumTry(fNumTry);
-
-    *fLog<<inf<<endl;
-    *fLog<<inf<<"Following settings for the tree growing are used:"<<endl;
-    *fLog<<inf<<" Number of Trees : "<<fNumTrees<<endl;
-    *fLog<<inf<<" Number of Trials: "<<fNumTry<<endl;
-    *fLog<<inf<<" Final Node size : "<<fNdSize<<endl;
-
     fTreeNo=0;
 
@@ -415,6 +414,5 @@
     if (fTreeNo==1)
     {
-        *fLog << inf << endl;
-        *fLog << underline;
+        *fLog << inf << endl << underline;
 
         if(calcResolution)
@@ -435,5 +433,6 @@
     TArrayF winbag(numdata); // Initialization includes filling with 0
 
-    float square=0; float mean=0;
+    float square=0;
+    float mean=0;
 
     for (Int_t n=0; n<numdata; n++)
@@ -483,5 +482,6 @@
     for (Int_t ievt=0;ievt<numdata;ievt++)
     {
-        if (jinbag[ievt]>0) continue;
+        if (jinbag[ievt]>0)
+            continue;
 
         fHadEst[ievt] +=fRanTree->TreeHad((*fMatrix), ievt);
@@ -491,5 +491,5 @@
 
     Int_t n=0;
-    double ferr=0;
+    Float_t ferr=0;
 
     for (Int_t ievt=0;ievt<numdata;ievt++)
@@ -508,8 +508,10 @@
     //-------------------------------------------------------------------
     // give running output
-    *fLog << inf << setw(5)  << fTreeNo;
-    *fLog << inf << setw(18) << fRanTree->GetNumEndNodes();
-    *fLog << inf << Form("%18.2f", ferr*100.);
-    *fLog << inf << endl;
+    *fLog << setw(5)  << fTreeNo;
+    *fLog << setw(18) << fRanTree->GetNumEndNodes();
+    *fLog << Form("%18.2f", ferr*100.);
+    *fLog << endl;
+
+    fRanTree->SetError(ferr);
 
     // adding tree to forest
Index: trunk/MagicSoft/Mars/mranforest/MRanForestCalc.cc
===================================================================
--- trunk/MagicSoft/Mars/mranforest/MRanForestCalc.cc	(revision 7411)
+++ trunk/MagicSoft/Mars/mranforest/MRanForestCalc.cc	(revision 7413)
@@ -16,7 +16,8 @@
 !
 !
-!   Author(s): Thomas Hengstebeck 3/2003 <mailto:hengsteb@alwa02.physik.uni-siegen.de>
-!
-!   Copyright: MAGIC Software Development, 2000-2003
+!   Author(s): Thomas Hengstebeck 2/2005 <mailto:hengsteb@physik.hu-berlin.de>
+!   Author(s): Thomas Bretz 8/2005 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2005
 !
 !
@@ -27,9 +28,4 @@
 //  MRanForestCalc
 //
-//  Calculates the hadroness of an event. It calculates a mean value of all
-//  classifications by the trees in a previously grown random forest.
-//
-//  To use only n trees for your calculation use:
-//  MRanForestCalc::SetUseNumTrees(n);
 //
 ////////////////////////////////////////////////////////////////////////////
@@ -38,26 +34,20 @@
 #include <TVector.h>
 
-#include "MHMatrix.h" // must be before MLogManip.h
-#include "MDataArray.h"
+#include "MHMatrix.h"
 
 #include "MLog.h"
 #include "MLogManip.h"
 
+#include "MData.h"
+#include "MDataArray.h"
+
+#include "MRanForest.h"
+#include "MParameters.h"
+
 #include "MParList.h"
-
-#include "MRanTree.h"
-#include "MRanForest.h"
-
-#include "MParameters.h"
-
+#include "MTaskList.h"
 #include "MEvtLoop.h"
-#include "MTaskList.h"
+#include "MRanForestGrow.h"
 #include "MFillH.h"
-#include "MStatusDisplay.h"
-#include "MRanForestGrow.h"
-#include "MRanForestFill.h"
-
-#include "MWriteRootFile.h"
-#include "MReadTree.h"
 
 ClassImp(MRanForestCalc);
@@ -65,85 +55,309 @@
 using namespace std;
 
-static const TString gsDefName  = "MRanForestCalc";
-static const TString gsDefTitle = "Tree Classification Loop 1/2";
-
-// --------------------------------------------------------------------------
-//
-// Setup histograms and the number of distances which are used for
-// avaraging in CalcDist
-//
+const TString MRanForestCalc::gsDefName    = "MRanForestCalc";
+const TString MRanForestCalc::gsDefTitle   = "RF for energy estimation";
+
+const TString MRanForestCalc::gsNameOutput = "RanForestOut";
+
 MRanForestCalc::MRanForestCalc(const char *name, const char *title)
-    : fNum(100), fHadronnessName("MHadronness"), fData(NULL), fRanForest(0), fRanTree(0)
-{
-    //
-    //   set the name and title of this object
-    //
+    : fDebug(kFALSE), fData(0), fRFOut(0),
+    fNumTrees(-1), fNumTry(-1), fNdSize(-1), fNumObsoleteVariables(1),
+    fTestMatrix(0), fEstimationMode(kMean)
+{
     fName  = name  ? name  : gsDefName.Data();
     fTitle = title ? title : gsDefTitle.Data();
-}
-
-// --------------------------------------------------------------------------
-//
-// Delete the data chains
-//
+
+    // FIXME:
+    fNumTrees = 100; //100
+    fNumTry   = 0;   //3   0 means: in MRanForest estimated best value will be calculated
+    fNdSize   = 1;   //1   
+}
+
 MRanForestCalc::~MRanForestCalc()
 {
-    if (!IsOwner())
-        return;
-
-    delete fRanForest;
-    delete fRanTree;
-}
-
-// --------------------------------------------------------------------------
-//
-// Needs:
-//  - MatrixGammas  [MHMatrix]
-//  - MatrixHadrons [MHMatrix]
-//  - MHadronness
-//  - all data containers used to build the matrixes
-//
-// The matrix object can be filles using MFillH. And must be of the same
-// number of columns (with the same meaning).
-//
+    fEForests.Delete();
+}
+
+Int_t MRanForestCalc::Train(const MHMatrix &matrixtrain, const TArrayD &grid, Int_t ver)
+{
+    gLog.Separator("MRanForestCalc - Train");
+
+    if (!matrixtrain.GetColumns())
+    {
+        *fLog << err << "ERROR - MHMatrix does not contain rules... abort." << endl;
+        return kFALSE;
+    }
+
+    const Int_t ncols = matrixtrain.GetM().GetNcols();
+    const Int_t nrows = matrixtrain.GetM().GetNrows();
+    if (ncols<=0 || nrows <=0)
+    {
+        *fLog << err << "ERROR - No. of columns or no. of rows of matrixtrain equal 0 ... abort." << endl;
+        return kFALSE;
+    }
+
+    // rules (= combination of image par) to be used for energy estimation
+    TFile fileRF(fFileName, "recreate");
+    if (!fileRF.IsOpen())
+    {
+        *fLog << err << "ERROR - File to store RFs could not be opened... abort." << endl;
+        return kFALSE;
+    }
+
+    const Int_t nobs = fNumObsoleteVariables; // Number of obsolete columns
+
+    const MDataArray &dcol = *matrixtrain.GetColumns();
+
+    MDataArray usedrules;
+    for (Int_t i=0; i<ncols; i++)
+        if (i<ncols-nobs)  // -3 is important!!!
+            usedrules.AddEntry(dcol[i].GetRule());
+        else
+            *fLog << inf << "Skipping " << dcol[i].GetRule() << " for training" << endl;
+
+    MDataArray rules(usedrules);
+    rules.AddEntry(ver<2?"Classification":dcol[ncols-1].GetRule());
+
+    // prepare matrix for current energy bin
+    TMatrix mat(matrixtrain.GetM());
+
+    // last column must be removed (true energy col.)
+    mat.ResizeTo(nrows, ncols-nobs+1);
+
+    if (fDebug)
+        gLog.SetNullOutput(kTRUE);
+
+    const Int_t nbins = ver>0 ? 1 : grid.GetSize()-1;
+    for (Int_t ie=0; ie<nbins; ie++)
+    {
+        switch (ver)
+        {
+        case 0: // Replace Energy Grid by classification
+            {
+                Int_t irows=0;
+                for (Int_t j=0; j<nrows; j++)
+                {
+                    const Double_t energy = matrixtrain.GetM()(j,ncols-1);
+                    const Bool_t   inside = energy>grid[ie] && energy<=grid[ie+1];
+
+                    mat(j, ncols-nobs) = inside ? 1 : 0;
+
+                    if (inside)
+                        irows++;
+                }
+                if (irows==0)
+                    *fLog << warn << "WARNING - Skipping";
+                else
+                    *fLog << inf << "Training RF for";
+
+                *fLog << " energy bin " << ie << " (" << grid[ie] << ", " << grid[ie+1] << ") " << irows << "/" << nrows << endl;
+
+                if (irows==0)
+                    continue;
+            }
+            break;
+
+        case 1: // Use Energy as classifier
+        case 2:
+            for (Int_t j=0; j<nrows; j++)
+                mat(j, ncols-nobs) = matrixtrain.GetM()(j,ncols-1);
+            break;
+        }
+
+        MHMatrix matrix(mat, &rules, "MatrixTrain");
+
+        MParList plist;
+        MTaskList tlist;
+        plist.AddToList(&tlist);
+        plist.AddToList(&matrix);
+
+        MRanForest rf;
+        rf.SetNumTrees(fNumTrees);
+        rf.SetNumTry(fNumTry);
+        rf.SetNdSize(fNdSize);
+        rf.SetClassify(ver<2 ? 1 : 0);
+        if (ver==1)
+            rf.SetGrid(grid);
+
+        plist.AddToList(&rf);
+
+        MRanForestGrow rfgrow;
+        tlist.AddToList(&rfgrow);
+
+        MFillH fillh("MHRanForestGini");
+        tlist.AddToList(&fillh);
+
+        MEvtLoop evtloop;
+        evtloop.SetParList(&plist);
+        evtloop.SetDisplay(fDisplay);
+        evtloop.SetLogStream(fLog);
+
+        if (!evtloop.Eventloop())
+            return kFALSE;
+
+        if (fDebug)
+            gLog.SetNullOutput(kFALSE);
+
+        if (ver==0)
+        {
+            // Calculate bin center
+            const Double_t E = (TMath::Log10(grid[ie])+TMath::Log10(grid[ie+1]))/2;
+
+            // save whole forest
+            rf.SetUserVal(E);
+            rf.SetName(Form("%.10f", E));
+        }
+
+        rf.Write();
+    }
+
+    // save rules
+    usedrules.Write("rules");
+
+    return kTRUE;
+}
+
+Int_t MRanForestCalc::ReadForests(MParList &plist)
+{
+    TFile fileRF(fFileName, "read");
+    if (!fileRF.IsOpen())
+    {
+        *fLog << err << dbginf << "File containing RFs could not be opened... aborting." << endl;
+        return kFALSE;
+    }
+
+    fEForests.Delete();
+
+    TIter Next(fileRF.GetListOfKeys());
+    TObject *o=0;
+    while ((o=Next()))
+    {
+        MRanForest *forest=0;
+        fileRF.GetObject(o->GetName(), forest);
+        if (!forest)
+            continue;
+
+        forest->SetUserVal(atof(o->GetName()));
+
+        fEForests.Add(forest);
+    }
+
+    // Maybe fEForests[0].fRules yould be used instead?
+
+    if (fData->Read("rules")<=0)
+    {
+        *fLog << err << "ERROR - Reading 'rules' from file " << fFileName << endl;
+        return kFALSE;
+    }
+
+    return kTRUE;
+}
+
 Int_t MRanForestCalc::PreProcess(MParList *plist)
 {
-    if (!fRanForest)
-    {
-        fRanForest = (MRanForest*)plist->FindObject("MRanForest");
-        if (!fRanForest)
+    fRFOut = (MParameterD*)plist->FindCreateObj("MParameterD", fNameOutput);
+    if (!fRFOut)
+        return kFALSE;
+
+    fData = (MDataArray*)plist->FindCreateObj("MDataArray");
+    if (!fData)
+        return kFALSE;
+
+    if (!ReadForests(*plist))
+    {
+        *fLog << err << "Reading RFs failed... aborting." << endl;
+        return kFALSE;
+    }
+
+    *fLog << inf << "RF read from " << fFileName << endl;
+
+    if (fTestMatrix)
+        return kTRUE;
+
+    fData->Print();
+
+    if (!fData->PreProcess(plist))
+    {
+        *fLog << err << "PreProcessing of the MDataArray failed... aborting." << endl;
+        return kFALSE;
+    }
+
+    return kTRUE;
+}
+
+#include <TGraph.h>
+#include <TF1.h>
+Int_t MRanForestCalc::Process()
+{
+    TVector event;
+    if (fTestMatrix)
+        *fTestMatrix >> event;
+    else
+        *fData >> event;
+
+    // --------------- Single Tree RF -------------------
+    if (fEForests.GetEntries()==1)
+    {
+        MRanForest *rf = (MRanForest*)fEForests[0];
+        fRFOut->SetVal(rf->CalcHadroness(event));
+        fRFOut->SetReadyToSave();
+
+        return kTRUE;
+    }
+
+    // --------------- Multi Tree RF -------------------
+    static TF1 f1("f1", "gaus");
+
+    Double_t sume = 0;
+    Double_t sumh = 0;
+    Double_t maxh = 0;
+    Double_t maxe = 0;
+
+    Double_t max  = -1e10;
+    Double_t min  =  1e10;
+
+    TIter Next(&fEForests);
+    MRanForest *rf = 0;
+
+    TGraph g;
+    while ((rf=(MRanForest*)Next()))
+    {
+        const Double_t h = rf->CalcHadroness(event);
+        const Double_t e = rf->GetUserVal();
+
+        g.SetPoint(g.GetN(), e, h);
+
+        sume += e*h;
+        sumh += h;
+
+        if (h>maxh)
         {
-            *fLog << err << dbginf << "MRanForest not found... aborting." << endl;
-            return kFALSE;
+            maxh = h;
+            maxe = e;
         }
-    }
-
-    if (!fRanTree)
-    {
-        fRanTree = (MRanTree*)plist->FindObject("MRanTree");
-        if (!fRanTree)
-        {
-            *fLog << err << dbginf << "MRanTree not found... aborting." << endl;
-            return kFALSE;
-        }
-    }
-
-    fData = fRanTree->GetRules();
-
-    if (!fData)
-    {
-        *fLog << err << dbginf << "Error matrix doesn't contain columns... aborting." << endl;
-        return kFALSE;
-    }
-
-    if (!fData->PreProcess(plist))
-    {
-        *fLog << err << dbginf << "PreProcessing of the MDataArray failed for the columns failed... aborting." << endl;
-        return kFALSE;
-    }
-
-    fHadroness = (MParameterD*)plist->FindCreateObj("MParameterD", fHadronnessName);
-    if (!fHadroness)
-        return kFALSE;
+        if (e>max)
+            max = e;
+        if (e<min)
+            min = e;
+    }
+
+    switch (fEstimationMode)
+    {
+    case kMean:
+        fRFOut->SetVal(pow(10, sume/sumh));
+        break;
+    case kMaximum:
+        fRFOut->SetVal(pow(10, maxe));
+        break;
+    case kFit:
+        f1.SetParameter(0, maxh);
+        f1.SetParameter(1, maxe);
+        f1.SetParameter(2, 0.125);
+        g.Fit(&f1, "Q0N");
+        fRFOut->SetVal(pow(10, f1.GetParameter(1)));
+        break;
+    }
+
+    fRFOut->SetReadyToSave();
 
     return kTRUE;
@@ -153,165 +367,35 @@
 //
 //
-Int_t MRanForestCalc::Process()
-{
-    // first copy the data from the data array to a vector event
-    TVector event;
-    *fData >> event;
-
-    Double_t hadroness=fRanForest->CalcHadroness(event);
-    fHadroness->SetVal(hadroness);
-
-    return kTRUE;
-}
-
-Bool_t MRanForestCalc::Grow(MHMatrix *matrixg,MHMatrix *matrixh,Int_t ntree,
-                            Int_t numtry,Int_t ndsize,const char* treefile,
-                            const char* treename,const char* contname,
-                            const char* hgininame)
-{
-
-    treename  = treename  ? treename  : "Tree";
-    contname  = contname  ? contname  : "MRanTree";
-    hgininame  = hgininame  ? hgininame  : "MHRanForestGini";
-
-    if (!matrixg->IsValid())
-    {
-        *fLog << err << dbginf << " MRanForestCalc::Grow - ERROR: matrixg not valid." << endl;
-        return kFALSE;
-    }
-    if(!matrixh->IsValid())
-    {
-        *fLog << err << dbginf << " MRanForestCalc::Grow - ERROR: matrixh not valid." << endl;
-        return kFALSE;
-    }
-
-    MEvtLoop run(GetName());
-    MTaskList tlist;
-    MParList plist;
-    plist.AddToList(&tlist);
-    plist.AddToList(matrixg);
-    plist.AddToList(matrixh);
-
-    // creating training task and setting parameters
-    MRanForestGrow rfgrow;
-    rfgrow.SetNumTrees(ntree); // number of trees
-    rfgrow.SetNumTry(numtry);  // number of trials in random split selection
-    rfgrow.SetNdSize(ndsize);  // limit for nodesize
-    tlist.AddToList(&rfgrow);
-
-    if(treefile){
-        MWriteRootFile rfwrite(treefile);
-        rfwrite.AddContainer(contname,treename);
-        tlist.AddToList(&rfwrite);
-    }
-
-    MFillH fillh(hgininame);
-    tlist.AddToList(&fillh);
-
-    run.SetParList(&plist);
-    
-    // Execute tree growing
-    if (!run.Eventloop())
-    {
-        *fLog << err << dbginf << "Evtloop in MRanForestCalc::Grow failed." << endl;
-        return kFALSE;
-    }
-    tlist.PrintStatistics(0, kTRUE);
-
-    if (TestBit(kEnableGraphicalOutput))
-        plist.FindObject(hgininame)->DrawClone();
-
-    return kTRUE;
-}
-
-Bool_t MRanForestCalc::Fill(Int_t ntree,const char* treefile,const char* treename)
-{
-    treefile  = treefile  ? treefile  : "RF.root";
-    treename  = treename  ? treename  : "Tree";
-
-    MParList  plist;
-
-    MTaskList tlist;
-    plist.AddToList(&tlist);
-
-    MReadTree read(treename,treefile);
-    read.DisableAutoScheme();
-
-    MRanForestFill rffill;
-    rffill.SetNumTrees(ntree);
-
-    tlist.AddToList(&read);
-    tlist.AddToList(&rffill);
-
-    MEvtLoop run(GetName());
-    run.SetParList(&plist);
-
-    //
-    // Execute tree reading
-    //
-    if (!run.Eventloop())
-    {
-        *fLog << err << dbginf << "Evtloop in MRanForestCalc::Fill failed." << endl;
-        return kFALSE;
-    }
-    tlist.PrintStatistics(0, kTRUE);
-
-    return kTRUE;
-}
-
 Int_t MRanForestCalc::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
 {
-    if (!IsEnvDefined(env, prefix, "File",     print))
-        return kFALSE;
-
-    TString fname = GetEnvValue(env, prefix, "File", "RF.root");
-    TString tname = GetEnvValue(env, prefix, "Tree", "Tree");
-    const Int_t   num   = GetEnvValue(env, prefix, "NumTrees", 100);
-    const Bool_t  debug = GetEnvValue(env, prefix, "Debug", kFALSE);
-
-    fname.ReplaceAll("\015", "");
-    tname.ReplaceAll("\015", "");
-
-    *fLog << inf << dbginf << "Reading " << num << " trees " << tname << " from file " << fname << endl;
-
-    gLog.SetNullOutput(!debug);
-    MEvtLoop evtloop;
-    MParList  plist;
-    evtloop.SetParList(&plist);
-    MLog l;
-    l.SetNullOutput(!debug);
-    evtloop.SetLogStream(&l);
-    gLog.SetNullOutput(debug);
-
-    if (IsOwner())
-    {
-        delete fRanForest;
-        delete fRanTree;
-    }
-    fRanForest = new MRanForest;
-    fRanTree   = new MRanTree;
-    SetOwner();
-
-    plist.AddToList(fRanForest);
-    plist.AddToList(fRanTree);
-
-    MTaskList tlist;
-    plist.AddToList(&tlist);
-
-    MReadTree read(tname, fname);
-    read.DisableAutoScheme();
-
-    MRanForestFill rffill;
-    rffill.SetNumTrees(num);
-
-    tlist.AddToList(&read);
-    tlist.AddToList(&rffill);
-
-    if (!evtloop.Eventloop())
-    {
-        *fLog << err << "ERROR - Reading " << tname << " from file " << fname << endl;
-        return kERROR;
-    }
-
-    return kTRUE;
-}
+    Bool_t rc = kFALSE;
+    if (IsEnvDefined(env, prefix, "FileName", print))
+    {
+        rc = kTRUE;
+        SetFileName(GetEnvValue(env, prefix, "FileName", fFileName));
+    }
+    if (IsEnvDefined(env, prefix, "Debug", print))
+    {
+        rc = kTRUE;
+        SetDebug(GetEnvValue(env, prefix, "Debug", fDebug));
+    }
+    if (IsEnvDefined(env, prefix, "NameOutput", print))
+    {
+        rc = kTRUE;
+        SetNameOutput(GetEnvValue(env, prefix, "NameOutput", fNameOutput));
+    }
+    if (IsEnvDefined(env, prefix, "EstimationMode", print))
+    {
+        TString txt = GetEnvValue(env, prefix, "EstimationMode", "");
+        txt = txt.Strip(TString::kBoth);
+        txt.ToLower();
+        if (txt==(TString)"mean")
+            fEstimationMode = kMean;
+        if (txt==(TString)"maximum")
+            fEstimationMode = kMaximum;
+        if (txt==(TString)"fit")
+            fEstimationMode = kFit;
+        rc = kTRUE;
+    }
+    return rc;
+}
Index: trunk/MagicSoft/Mars/mranforest/MRanForestCalc.h
===================================================================
--- trunk/MagicSoft/Mars/mranforest/MRanForestCalc.h	(revision 7411)
+++ trunk/MagicSoft/Mars/mranforest/MRanForestCalc.h	(revision 7413)
@@ -6,33 +6,64 @@
 #endif
 
-#ifndef MARS_MHMatrix
-#include "MHMatrix.h"
+#ifndef ROOT_TObjArray
+#include <TObjArray.h>
 #endif
 
-class MParList;
+#ifndef ROOT_TArrayD
+#include <TArrayD.h>
+#endif
+
+class MDataArray;
 class MParameterD;
-class MDataArray;
-class MRanTree;
-class MRanForest;
+class MHMatrix;
 
 class MRanForestCalc : public MTask
 {
+public:
+    enum EstimationMode_t
+    {
+        kMean,
+        kMaximum,
+        kFit
+    };
+
 private:
-    Int_t  fNum;              // number of trees used to compute hadronness
+    static const TString gsDefName;     //! Default Name
+    static const TString gsDefTitle;    //! Default Title
+    static const TString gsNameOutput;  //! Default Output name
 
-    TString fHadronnessName;  // Name of container storing hadronness
+    Bool_t       fDebug;      // Debugging of eventloop while training on/off
 
-    MParameterD *fHadroness;  //! Output container for calculated hadroness
+    TString      fFileName;   // File name to forest
+    TObjArray    fEForests;   // List of forests
+
+    TString      fNameOutput; // Name of output container
+
     MDataArray  *fData;       //! Used to store the MDataChains to get the event values
-    MRanForest  *fRanForest;
-    MRanTree    *fRanTree;
+    MParameterD *fRFOut;      //! Used to store result
 
+    Int_t        fNumTrees;   //! Training parameters
+    Int_t        fNumTry;     //! Training parameters
+    Int_t        fNdSize;     //! Training parameters
+
+    Int_t        fNumObsoleteVariables;
+
+    MHMatrix    *fTestMatrix; //! Test Matrix used in Process (together with MMatrixLoop)
+
+    EstimationMode_t fEstimationMode;
+
+private:
+    // MTask
     Int_t PreProcess(MParList *plist);
     Int_t Process();
 
-    enum { kIsOwner = BIT(14) };
+    // MRanForestCalc
+    Int_t ReadForests(MParList &plist);
 
-    Bool_t IsOwner() const { return TestBit(kIsOwner); }
-    void SetOwner() { SetBit(kIsOwner); }
+    // MParContainer
+    Int_t ReadEnv(const TEnv &env, TString prefix, Bool_t print);
+
+    // Train Interface
+    Int_t Train(const MHMatrix &n, const TArrayD &grid, Int_t ver=2);
 
 public:
@@ -40,20 +71,32 @@
     ~MRanForestCalc();
 
-    Int_t ReadEnv(const TEnv &env, TString prefix, Bool_t print);
+    // Setter for estimation
+    void SetFileName(TString filename)            { fFileName = filename; }
+    void SetEstimationMode(EstimationMode_t op)   { fEstimationMode = op; }
+    void SetNameOutput(TString name=gsNameOutput) { fNameOutput = name; }
 
-    void SetHadronnessName(const TString name) { fHadronnessName = name; }
-    TString GetHadronnessName() const { return fHadronnessName; }
+    // Setter for training
+    void SetNumTrees(UShort_t n=100) { fNumTrees = n; }
+    void SetNdSize(UShort_t n=5)     { fNdSize   = n; }
+    void SetNumTry(UShort_t n=0)     { fNumTry   = n; }
+    void SetDebug(Bool_t b=kTRUE)    { fDebug    = b; }
 
-    void SetUseNumTrees(UShort_t n=100) { fNum = n; }
+    void SetNumObsoleteVariables(Int_t n=1) { fNumObsoleteVariables = n; }
 
-    Bool_t Grow(MHMatrix *matrixg,MHMatrix *matrixh,Int_t ntree,
-                Int_t numtry,Int_t ndsize,const char* treefile=0,
-                const char* treename=0,const char* contname=0,
-                const char* hgininame=0);
+    // Train Interface
+    Int_t TrainMultiRF(const MHMatrix &n, const TArrayD &grid)
+    {
+        return Train(n, grid, 0);
+    }
+    Int_t TrainSingleRF(const MHMatrix &n, const TArrayD &grid=TArrayD())
+    {
+        return Train(n, grid, grid.GetSize()==0 ? 2 : 1);
+    }
 
-    Bool_t Fill(Int_t ntree,const char* treefile=0,const char* treename=0);
+    // Test Interface
+    void  SetTestMatrix(MHMatrix *m=0) { fTestMatrix=m; }
+    void  InitMapping(MHMatrix *m=0)   { fTestMatrix=m; }
 
-
-    ClassDef(MRanForestCalc, 0) // Task
+    ClassDef(MRanForestCalc, 0) // Task to calculate RF output and for RF training
 };
 
Index: trunk/MagicSoft/Mars/mranforest/MRanTree.h
===================================================================
--- trunk/MagicSoft/Mars/mranforest/MRanTree.h	(revision 7411)
+++ trunk/MagicSoft/Mars/mranforest/MRanTree.h	(revision 7413)
@@ -28,4 +28,5 @@
     Int_t fNumNodes;
     Int_t fNumEndNodes;
+    Float_t fError;
 
     TArrayI fBestVar;
@@ -70,4 +71,5 @@
     void SetNdSize(Int_t n);
     void SetNumTry(Int_t n);
+    void SetError(Float_t f) { fError = f; }
 
     Int_t GetNdSize() const { return fNdSize; }
@@ -75,4 +77,5 @@
     Int_t GetNumNodes()          const { return fNumNodes; }
     Int_t GetNumEndNodes()       const { return fNumEndNodes; }
+    Float_t GetError() const { return fError; }
 
     Int_t GetBestVar(Int_t i)    const { return fBestVar.At(i); }
Index: trunk/MagicSoft/Mars/mranforest/Makefile
===================================================================
--- trunk/MagicSoft/Mars/mranforest/Makefile	(revision 7411)
+++ trunk/MagicSoft/Mars/mranforest/Makefile	(revision 7413)
@@ -25,7 +25,7 @@
            MRanForest.cc \
            MRanForestGrow.cc \
+           MRanForestCalc.cc \
 	   MHRanForest.cc \
-	   MHRanForestGini.cc \
-	   MRFEnergyEst.cc
+	   MHRanForestGini.cc
 
 ############################################################
Index: trunk/MagicSoft/Mars/mranforest/RanForestLinkDef.h
===================================================================
--- trunk/MagicSoft/Mars/mranforest/RanForestLinkDef.h	(revision 7411)
+++ trunk/MagicSoft/Mars/mranforest/RanForestLinkDef.h	(revision 7413)
@@ -8,9 +8,8 @@
 #pragma link C++ class MRanForest+;
 #pragma link C++ class MRanForestGrow+;
+#pragma link C++ class MRanForestCalc+;
 
 #pragma link C++ class MHRanForest+;
 #pragma link C++ class MHRanForestGini+;
 
-#pragma link C++ class MRFEnergyEst+;
-
 #endif
