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

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// MCalibrationChargePix                                                         //
//                                                                         //
// Storage container of the calibrated Quantrum Efficiency of one pixel 
// For the moment, only a fixed average QE is stored:
//
// - Average QE: (email David Paneque, 14.2.04):
//
//  The conversion factor that comes purely from QE folded to a Cherenkov
//  spectrum has to be multiplied by:
//  * Plexiglass window -->> 0.96 X 0.96
//  * PMT photoelectron collection efficiency -->> 0.9
//  * Light guides efficiency -->> 0.94
//
//  Concerning the light guides effiency estimation... Daniel Ferenc 
//  is preparing some work (simulations) to estimate it. Yet so far, he has 
//  been busy with other stuff, and this work is still UNfinished.
//
//  The estimation I did comes from:
//  1) Reflectivity of light guide walls is 85 % (aluminum)
//  2) At ZERO degree light incidence, 37% of the light hits such walls 
//    (0.15X37%= 5.6% of light lost)
//  3) When increasing the light incidence angle, more and more light hits 
//     the walls.
//
//  However, the loses due to larger amount of photons hitting the walls is more 
//  or less counteracted by the fact that more and more photon trajectories cross 
//  the PMT photocathode twice, increasing the effective sensitivity of the PMT.
//
//  Jurgen Gebauer did some quick measurements about this issue. I attach a 
//  plot. You can see that the angular dependence is (more or less) in agreement 
//  with a CosTheta function (below 20-25 degrees),
//  which is the variation of teh entrance window cross section. So, in 
//  first approximation, no loses when increasing light incidence angle; 
//  and therefore, the factor 0.94.
//
//  So, summarizing... I would propose the following conversion factors 
//  (while working with CT1 cal box) in order to get the final number of photons 
//  from the detected measured size in ADC counts.
// 
//  Nph = ADC * FmethodConversionFactor / ConvPhe-PhFactor
// 
//  FmethodConversionFactor ; measured for individual pmts
// 
//  ConvPhe-PhFactor = 0.98 * 0.23 * 0.90 * 0.94 * 0.96 * 0.96 = 0.18
// 
//  I would not apply any smearing of this factor (which we have in nature), 
//  since we might be applying it to PMTs in the totally wrong direction.
// 
// 
/////////////////////////////////////////////////////////////////////////////
#include "MCalibrationQEPix.h"

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

ClassImp(MCalibrationQEPix);

using namespace std;

// --------------------------------------------------------------------------
//
// Default Constructor: 
//
MCalibrationQEPix::MCalibrationQEPix(const char *name, const char *title)
    : fPixId(-1)
{

  fName  = name  ? name  : "MCalibrationQEPix";
  fTitle = title ? title : "Container of the calibrated quantum efficiency ";

  Clear();

}

// ------------------------------------------------------------------------
//
// Invalidate values
//
void MCalibrationQEPix::Clear(Option_t *o)
{

  SetExcluded               ( kFALSE );
  SetQEValid                ( kFALSE );

  fQEGreen      =  -1.;
  fQEBlue       =  -1.;
  fQEUV         =  -1.;
  fQECT1        =  -1.;
  
  fQEGreenErr   =  -1.;
  fQEBlueErr    =  -1.;
  fQEUVErr      =  -1.;
  fQECT1Err     =  -1.;
 
}


void MCalibrationQEPix::SetQE( const Float_t qe, const PulserColor_t col )
{

  switch (col)
  {
      case kGREEN:
	  fQEGreen = qe;
	  break;
      case kBLUE:
	  fQEBlue = qe;
	  break;
      case kUV:
	  fQEUV = qe;
	  break;
      case kCT1:
	  fQECT1 = qe;
	  break;
      default:
	  fQECT1 = qe;
	  break;
  }
}

void MCalibrationQEPix::SetQEErr( const Float_t qeerr, const PulserColor_t col )
{

  switch (col)
  {
      case kGREEN:
	  fQEGreenErr = qeerr;
	  break;
      case kBLUE:
	  fQEBlueErr  = qeerr;
	  break;
      case kUV:
	  fQEUVErr    = qeerr;
	  break;
      case kCT1:
	  fQECT1Err   = qeerr;
	  break;
      default:
	  fQECT1Err  = qeerr;
	  break;
  }
}



// --------------------------------------------------------------------------
//
// Set the Excluded Bit from outside 
//
void MCalibrationQEPix::SetExcluded(Bool_t b )
{ 
    b ?  SETBIT(fFlags, kExcluded) : CLRBIT(fFlags, kExcluded); 
}

// --------------------------------------------------------------------------
//
// Set the Excluded Bit from outside 
//
void MCalibrationQEPix::SetQEValid(Bool_t b )    
{ 
  b ?  SETBIT(fFlags, kQEValid) : CLRBIT(fFlags, kQEValid); 
}


Int_t MCalibrationQEPix::GetPixId()  const
{
    return fPixId;
}

Float_t MCalibrationQEPix::GetQE(const PulserColor_t col )  const
{

  switch (col)
  {
      case kGREEN:
	  return fQEGreen;
	  break;
      case kBLUE:
	  return fQEBlue;
	  break;
      case kUV:
	  return fQEUV;
	  break;
      case kCT1:
	  return fQECT1;
	  break;
      default:
	  return fQECT1;
	  break;
  }
}

Float_t MCalibrationQEPix::GetQEErr(const PulserColor_t col )  const
{

  switch (col)
  {
      case kGREEN:
	  return fQEGreenErr;
	  break;
      case kBLUE:
	  return fQEBlueErr;
	  break;
      case kUV:
	  return fQEUVErr;
	  break;
      case kCT1:
	  return fQECT1Err;
	  break;
      default:
	  return fQECT1Err;
	  break;
  }
}


Bool_t MCalibrationQEPix::IsExcluded()            const
{ 
   return TESTBIT(fFlags,kExcluded);  
}


Bool_t MCalibrationQEPix::IsQEValid()         const 
{
  return TESTBIT(fFlags, kQEValid);  
}


//
// The check return kTRUE if:
//
// 1) Pixel has a fitted charge greater than fQELimit*PedRMS
// 2) Pixel has a fit error greater than fQEErrLimit
// 3) Pixel has a fitted charge greater its fQERelErrLimit times its charge error
// 4) Pixel has a charge sigma bigger than its Pedestal RMS
// 
Bool_t MCalibrationQEPix::CheckQEValidity()
{
 
  SetQEValid();
  return kTRUE;
}
