/* ======================================================================== *\
!
! *
! * 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 Hengstebeck 3/2003 <mailto:hengsteb@alwa02.physik.uni-siegen.de>
!
!   Copyright: MAGIC Software Development, 2000-2003
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//
// MHRanForest
//
// This histogram shows a measure of variable importance (mean decrease in
// Gini-index)
//
////////////////////////////////////////////////////////////////////////////
#include "MHRanForestGini.h"

#include <TPad.h>
#include <TGraph.h>
#include <TStyle.h>
#include <TCanvas.h>
#include <TMarker.h>

#include "MParList.h"
#include "MBinning.h"
#include "MRanTree.h"
#include "MRanForest.h"

#include "MLog.h"
#include "MLogManip.h"

ClassImp(MHRanForestGini);

// --------------------------------------------------------------------------
//
// Setup histograms, nbins is the number of bins used for the evaluation.
// The default is 100 bins.
//
MHRanForestGini::MHRanForestGini(Int_t nbins, const char *name, const char *title)
{
    //
    //   set the name and title of this object
    //
    fName  = name  ? name  : "MHRanForestGini";
    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->SetMaximum(1);
}

// --------------------------------------------------------------------------
//
// Delete the histograms.
//
MHRanForestGini::~MHRanForestGini()
{
    delete fGraphGini;
}

// --------------------------------------------------------------------------
//
// Setup Filling of the histograms. It needs:
//  MMcEvt and MRanForest
//
Bool_t MHRanForestGini::SetupFill(const MParList *plist)
{
    fRanForest = (MRanForest*)plist->FindObject("MRanForest");
    if (!fRanForest)
    {
        *fLog << err << dbginf << "MRanForest not found... aborting." << endl;
        return kFALSE;
    }

    fGini.Set(fRanForest->GetNumDim());
    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Fill the RanForest from a MRanForest container into the corresponding
// histogram dependant on the particle id.
//
//
Bool_t MHRanForestGini::Fill(const MParContainer *par)
{
    for (Int_t i=0;i<fRanForest->GetNumDim();i++)
        fGini[i]+=fRanForest->GetCurTree()->GetGiniDec(i);

    return kTRUE;
}

// --------------------------------------------------------------------------
//
//
Bool_t MHRanForestGini::Finalize()
{
    Int_t n = fGini.GetSize();

    fGraphGini->Set(n);

    Stat_t max=0.;
    Stat_t min=0.;
    for (Int_t i=0; i<n; i++)
    {
        fGini[i]/=fRanForest->GetNumTrees();
        fGini[i]/=fRanForest->GetNumData();

        Stat_t ip = i+1.;
        Stat_t ig = fGini[i];

        max=TMath::Max(max,ig);
        min=TMath::Min(min,ig);

        fGraphGini->SetPoint(i,ip,ig);
    }
    fGraphGini->SetMaximum(1.05*max);
    fGraphGini->SetMinimum(0.95*min);

    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Draw clone of histogram (For the Meaning see class description)
//
TObject *MHRanForestGini::DrawClone(Option_t *opt) const
{
    if (fGraphGini->GetN()==0)
        return NULL;

    TCanvas &c = *MakeDefCanvas("RanForestGini", fTitle);
    gROOT->SetSelectedPad(NULL);

    //gStyle->SetOptStat(10);
    TGraph &g = (TGraph&)*fGraphGini->DrawClone("AL");
    g.SetBit(kCanDelete);
    gPad->Modified();
    gPad->Update();
    if (g.GetHistogram())
    {
        g.GetXaxis()->SetRangeUser(0, fRanForest->GetNumTrees());
        g.GetXaxis()->SetTitle("No. of RF-input parameter");
        g.GetYaxis()->SetTitle("Mean decrease in Gini-index [a.u.]");
        g.SetMarkerStyle(kFullDotMedium);
        //g.Draw("P");
        gPad->Modified();
        gPad->Update();
    }
    gPad->SetGrid();

    return &c;
}

// --------------------------------------------------------------------------
//
// Draw histogram. (For the Meaning see class description)
//
void MHRanForestGini::Draw(Option_t *)
{
   if (fGraphGini->GetN()==0)
        return;

   if (!gPad)
        MakeDefCanvas("RanForest", fTitle);

    //gStyle->SetOptStat(10);
    fGraphGini->Draw("ALP");
    gPad->Modified();
    gPad->Update();
    if (fGraphGini->GetHistogram())
    {
        fGraphGini->GetXaxis()->SetRangeUser(0, 1);
        fGraphGini->GetXaxis()->SetTitle("No. of RF-input parameter");
        fGraphGini->GetYaxis()->SetTitle("Mean decrease in Gini-index [a.u.]");

        fGraphGini->SetMarkerStyle(kFullDotSmall);
        //fGraphGini->Draw("P");
        gPad->Modified();
        gPad->Update();
    }
}
