/* ======================================================================== *\
!
! *
! * 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    1/2002 <mailto:tbretz@uni-sw.gwdg.de>
!   Author(s): Wolfgang Wittek 1/2002 <mailto:wittek@mppmu.mpg.de>
!
!   Copyright: MAGIC Software Development, 2000-2002
!
!
\* ======================================================================== */

//////////////////////////////////////////////////////////////////////////////
//                                                                          //
//  MHEffOnTimeTime                                                         //
//                                                                          //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

#include "MHEffOnTimeTime.h"

#include <TF1.h>
#include <TH2.h>
#include <TCanvas.h>

#include "MTime.h"

#include "MBinning.h"
#include "MParList.h"

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

ClassImp(MHEffOnTimeTime);


// --------------------------------------------------------------------------
//
// Default Constructor. It sets name and title only. Typically you won't
// need to change this.
//
MHEffOnTimeTime::MHEffOnTimeTime(const char *name, const char *title)
    : fHist()
{
    //
    //   set the name and title of this object
    //
    fName  = name  ? name  : "MHEffOnTimeTime";
    fTitle = title ? title : "1-D histogram of Eff On Time";

    fHist.SetName("EffOn");
    fHist.SetTitle("Effective On Time Vs. Time");


    fHist.SetDirectory(NULL);

    fHist.GetXaxis()->SetTitle("t_{eff} [s]");
    fHist.GetYaxis()->SetTitle("t [s]");
}

TObject *MHEffOnTimeTime::DrawClone(Option_t *opt) const
{
    TCanvas *c = MakeDefCanvas("EffOnTimeTheta", "t_eff vs. t");

    gROOT->SetSelectedPad(NULL);

    ((TH2&)fHist).DrawCopy(opt);

    c->Modified();
    c->Update();

    return c;
}

void MHEffOnTimeTime::Draw(Option_t *opt)
{
    if (!gPad)
        MakeDefCanvas("EffOnTimeTheta", "t_eff vs. t");

    fHist.Draw(opt);

    gPad->Modified();
    gPad->Update();
}


void MHEffOnTimeTime::Calc(TH2D *hist)
{
    const Int_t nbins = hist->GetNbinsY();

    for (int i=1; i<nbins; i++)
    {
        //char txt[100];
        //sprintf(txt, "Name%d", 100*i);
        //new TCanvas(txt, "Title");

        TH1D &h = *hist->ProjectionX("dTime-Distribution for fixed Theta", i, i);

        //hist->Draw();
        //gPad->SetLogy();

        Double_t Nmdel = h.Integral("width");
        Double_t mean  = h.GetMean();

        TF1 func("Poisson", "[1] * [0] * exp(-[0] *x)",
                 mean, hist->GetXaxis()->GetXmax());

        func.SetParameter(0, 100); // [Hz]
        func.SetParameter(1, Nmdel);

        func.SetParLimits(0, 0, 1000);    // [Hz]
        func.SetParLimits(1, 0, 2*Nmdel);

        func.SetParName(0, "lambda");
        func.SetParName(1, "Nmdel");

        h.Fit("Poisson", "RN");

        //func.SetRange(0, 0.1); // Range of Drawing
        //func.DrawCopy("same");

        //cout << func.GetParameter(0) << " " << func.GetParameter(1) << endl;

        Double_t lambda = func.GetParameter(0);
        //Double_t a      = func.GetParameter(1);

        //cout << "t_eff = " << h->Integral()/lambda << "  T(last)=" << time.GetTimeLo()*0.0001 << endl;

        fHist.SetBinContent(i, h.Integral()/lambda);

        delete &h;
    }
}

Bool_t MHEffOnTimeTime::SetupFill(const MParList *plist)
{
    const MBinning* binstime = (MBinning*)plist->FindObject("BinningTime");
    if (!binstime)
    {
        *fLog << err << dbginf << "BinningTime [MBinning] not found... aborting." << endl;
        return kFALSE;
    }

    SetBinning(&fHist, binstime);

    return kTRUE;
}

Bool_t MHEffOnTimeTime::Fill(const MParContainer *par)
{
    return kTRUE;
}

