/* ======================================================================== *\
!
! *
! * 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/2000 <mailto:tbretz@uni-sw.gwdg.de>
!
!   Copyright: MAGIC Software Development, 2000-2001
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// MPedestalPix                                                            //
//                                                                         //
// This is the storage container to hold informations about the pedestal   //
// (offset) value of one Pixel (PMT).                                      //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
#include "MPedestalPix.h"

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

ClassImp(MPedestalPix);

using namespace std;

MPedestalPix::MPedestalPix() : fHist(NULL), fFlags(0)
{
  Clear();
}

MPedestalPix::~MPedestalPix()
{
  if (fHist)
    delete fHist;
}
  

// ------------------------------------------------------------------------
//
// Invalidate values
//
void MPedestalPix::Clear(Option_t *o)
{
  fPedestal = -1.;
  fPedestalRms = -1.;

  fMean       = -1.;
  fMeanErr    = -1.;
  fSigma      = -1.;
  fProb       = -1.;

  CLRBIT(fFlags,kFitted);
  CLRBIT(fFlags,kFitValid);  

}

void MPedestalPix::InitUseHists()
{
  fPedestal = 0.;
  fPedestalRms = 0.;

  fHist = new MHPedestalPixel("MHPedestalPixel","Pedestal Histograms Pixel ");

  if (!fHist)
    *fLog << warn << dbginf << " Could not create MHCalibrationPixel " << endl;

}

void MPedestalPix::FillHists(const Float_t f)
{

  if (!fHist)
    return;
  
  fHist->FillCharge(f);
  fHist->FillChargevsN(f);
}


void MPedestalPix::Set(Float_t m, Float_t r)
{
  fPedestal = m; 
  fPedestalRms = r; 
}

Bool_t MPedestalPix::IsValid() const 
{
 return fPedestal>=0||fPedestalRms>=0;
}

Bool_t MPedestalPix::IsFitted() const 
{
  return TESTBIT(fFlags,kFitted);
}

Bool_t MPedestalPix::IsFitValid() const 
{
  return TESTBIT(fFlags,kFitValid);
}

// --------------------------------------------------------------------------
//
// 1) Return if the charge distribution is already succesfully fitted  
//    or if the histogram is empty
// 2) Cut the histograms empty edges
// 3) Fit the histograms with a Gaussian
// 4) In case of failure print out the fit results
// 5) Retrieve the results and store them in this class
//
void MPedestalPix::FitCharge()
{
  
  //
  // 1) Return if the charge distribution is already succesfully fitted  
  //    or if the histogram is empty
  //
  if (fHist->IsFitOK() || fHist->IsEmpty())
    return;


  fHist->CutAllEdges();
      
  //
  // 2) Fit the Lo Gain histograms with a Gaussian
  //
  if(fHist->FitCharge())
    SETBIT(fFlags,kFitted);
  else
    CLRBIT(fFlags,kFitted);

  //
  // 6) Retrieve the results and store them in this class
  //
  fMean         = fHist->GetChargeMean();
  fMeanErr      = fHist->GetChargeMeanErr(); 
  fSigma        = fHist->GetChargeSigma();
  fSigmaErr     = fHist->GetChargeSigmaErr();
  fProb         = fHist->GetChargeProb();

  if (CheckFitValidity())
    SETBIT(fFlags,kFitValid);
  else
    CLRBIT(fFlags,kFitValid);

  return;
}

Bool_t MPedestalPix::CheckFitValidity()
{
  
  if (fProb < 0.001)
    return kFALSE;
  
  return kTRUE;
  
}
