/* ======================================================================== *\
!
! *
! * 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): Markus Gaug   07/2004 <mailto:markus@ifae.es>
!
!   Copyright: MAGIC Software Development, 2000-2004
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//                                                               
// MCalibrationChargeBlindCam                                               
//                                                               
// Base class for Blind Pixels Calibration results. 
//
// Contains TClonesArrays for the following objects:
// - fBlindPixels:    Array of classes derived from MCalibrationChargeBlindPix, one entry 
//                    per blind pixel. 
//
// All TClonesArrays have to enlarged by the corresponding calls to (e.g. in MGeomApply): 
// - InitSize()
//
/////////////////////////////////////////////////////////////////////////////
#include "MCalibrationChargeBlindCam.h"
#include "MCalibrationChargeBlindPix.h"

#include "MCalibrationCam.h"
#include "MCalibrationPix.h"

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

#include <TClonesArray.h>

ClassImp(MCalibrationChargeBlindCam);

using namespace std;
// --------------------------------------------------------------------------
//
// Default constructor. 
//
// Set the following pointer to NULL:
// - fBlindPixels
//
// Initializes:
// - fPulserColor to kNONE 
//
// Creates a TClonesArray of MCalibrationChargeBlindPix containers for the TClonesArray's: 
// - fBlindPixels
// all initialized to 1 entry
//
// Later, a call to InitSize() 
// has to be performed in order to get the dimension correctly.
//
MCalibrationChargeBlindCam::MCalibrationChargeBlindCam(const char *name, const char *title)
    : fPulserColor(MCalibrationCam::kNONE), 
      fBlindPixels(NULL), 
      fValid(kFALSE)
{
  fName  = name  ? name  : "MCalibrationChargeBlindCam";
  fTitle = title ? title : "Container for the Calibration Information of the blind pixels in the camera";

  fBlindPixels = new TClonesArray("MCalibrationChargeBlindPix",1);
}

// --------------------------------------------------------------------------
//
// Deletes the following TClonesArray's of MCalibrationPix containers (if exist):
// - fBlindPixels
//
MCalibrationChargeBlindCam::~MCalibrationChargeBlindCam()
{

  //
  // delete fBlindPixels should delete all Objects stored inside
  // 
  delete fBlindPixels;

}

// --------------------------------------
//
// Calls the ForEach macro for the TClonesArray fBlindPixels with the argument Clear()
// 
void MCalibrationChargeBlindCam::Clear(Option_t *o)
{

  fBlindPixels->ForEach(TObject, Clear)();

  return;
}

// -----------------------------------------------------
//
// own copy function to do the initialization correctly
//
void MCalibrationChargeBlindCam::Copy(TObject& object) const
{
  
  MCalibrationChargeBlindCam &calib = (MCalibrationChargeBlindCam&)object;
  
  MParContainer::Copy(calib);
  
  calib.fPulserColor          = fPulserColor;
  
  const Int_t n3 = GetSize();
  if (n3 != 0)
    {
      calib.InitSize(n3);
      for (int i=0; i<n3; i++)
        (*this)[i].Copy(calib[i]);
    }
  
}

// -------------------------------------------------------------------
//
// Calls TClonesArray::ExpandCreate() for fBlindPixels
//
void MCalibrationChargeBlindCam::InitSize(const UInt_t i)
{
  fBlindPixels->ExpandCreate(i);
}


// --------------------------------------------------------------------------
//
// Get i-th blind pixel (pixel number)
//
MCalibrationChargeBlindPix &MCalibrationChargeBlindCam::operator[](UInt_t i)
{
  return *static_cast<MCalibrationChargeBlindPix*>(fBlindPixels->UncheckedAt(i));
}

// --------------------------------------------------------------------------
//
// Get i-th pixel (pixel number)
//
const MCalibrationChargeBlindPix &MCalibrationChargeBlindCam::operator[](UInt_t i) const
{
  return *static_cast<MCalibrationChargeBlindPix*>(fBlindPixels->UncheckedAt(i));
}

// --------------------------------------------------------------------------
//
// Returns the current size of the TClonesArray fBlindPixels 
// independently if the MCalibrationChargeBlindPix is filled with values or not.
//
const Int_t MCalibrationChargeBlindCam::GetSize() const
{
  return fBlindPixels->GetEntriesFast();
}

// --------------------------------------------------------------------------
//
// Print first the results of the pixels 
// and then the ones which are not FitValid
//
void MCalibrationChargeBlindCam::Print(Option_t *o) const
{

  *fLog << all << GetDescriptor() << ":" << endl;
  int id = 0;
  
  *fLog << all << "Calibrated Blind pixels:" << endl;
  *fLog << all << endl;

  TIter Next(fBlindPixels);
  MCalibrationChargeBlindPix *pix;
  while ((pix=(MCalibrationChargeBlindPix*)Next()))
    {
      
      if (pix->IsSinglePheFitOK()) 
	{                            

          *fLog << all 
                << Form("%s%3i","BlindPixel: ",pix->GetPixId())
                << Form("%s%4.2f%s%4.2f","  Lambda: ",pix->GetLambda(),"+-",pix->GetLambdaErr())
		<< Form("%s%4.2f%s%4.2f","  Mu0: ",pix->GetMu0(),"+-",pix->GetMu0Err())
		<< Form("%s%4.2f%s%4.2f","  Mu1: ",pix->GetMu1(),"+-",pix->GetMu1Err()) 
		<< Form("%s%4.2f%s%4.2f","  Sigma0: ",pix->GetSigma0(),"+-",pix->GetSigma0Err())
		<< Form("%s%4.2f%s%4.2f","  Sigma1: ",pix->GetSigma1(),"+-",pix->GetSigma1Err())
		<< endl;
	  *fLog << all
                << " Pedestal Fit OK? :" << pix->IsPedestalFitOK() 
		<< Form("%s%4.2f%s%4.2f","  Lambda (Check): " ,pix->GetLambdaCheck(),"+-",pix->GetLambdaCheckErr()) << endl;
	  *fLog << all
                << " Flux available? :" << pix->IsFluxInsidePlexiglassAvailable() 
		<< Form("%s%4.2f%s%4.2f","  Flux: " ,pix->GetFluxInsidePlexiglass(),"+-",pix->GetFluxInsidePlexiglassErr())
		<< endl;
          id++;
	}
    }
  *fLog << all << id << " blind pixels OK" << endl;
  id = 0;
  
  TIter Next2(fBlindPixels);
  while ((pix=(MCalibrationChargeBlindPix*)Next2()))
    {
      
      if (!pix->IsSinglePheFitOK()) 
	{                            

          *fLog << all 
                << Form("%s%3i","BlindPixel: ",pix->GetPixId())
                << Form("%s%4.2f%s%4.2f","  Lambda: ",pix->GetLambda(),"+-",pix->GetLambdaErr())
		<< Form("%s%4.2f%s%4.2f","  Mu0: ",pix->GetMu0(),"+-",pix->GetMu0Err())
		<< Form("%s%4.2f%s%4.2f","  Mu1: ",pix->GetMu1(),"+-",pix->GetMu1Err()) 
		<< Form("%s%4.2f%s%4.2f","  Sigma0: ",pix->GetSigma0(),"+-",pix->GetSigma0Err())
		<< Form("%s%4.2f%s%4.2f","  Sigma1: ",pix->GetSigma1(),"+-",pix->GetSigma1Err())
		<< endl;
	  *fLog << all
                << " Pedestal Fit OK? :" << pix->IsPedestalFitOK() 
		<< Form("%s%4.2f%s%4.2f","  Lambda (Check): " ,pix->GetLambdaCheck(),"+-",pix->GetLambdaCheckErr()) << endl;
	  *fLog << all
                << " Flux available? :" << pix->IsFluxInsidePlexiglassAvailable() 
		<< Form("%s%4.2f%s%4.2f","  Flux: " ,pix->GetFluxInsidePlexiglass(),"+-",pix->GetFluxInsidePlexiglassErr())
		<< endl;
          id++;
	}
    }
  *fLog << all << id << " blind pixels NOT OK" << endl;
  
}
