/* ======================================================================== *\
!
! *
! * 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, 11/2003 <mailto:markus@ifae.es>
!
!   Copyright: MAGIC Software Development, 2000-2004
!
!
\* ======================================================================== */
/////////////////////////////////////////////////////////////////////////////
//
//  calibration.C
//
//  Needs as arguments the run number of a calibration file ("*_C_*.root") and 
//  the run number of the corresponding pedestal file ("*_P_*.root"). 
//
//  The TString inpath has to be set correctly.
//
//  The macro searches for the pulser colour which corresponds to the calibration
//  run number. If the run number is smaller than 20000, pulser colour "CT1" 
//  is assumed, otherwise, it searches for the strings "green", "blue", "uv" or 
//  "ct1" in the filenames. If no colour or multiple colours are found, the 
//  execution is aborted.  
//
//  The container MBadPixelsCam is created and followed during the execution of the 
//  rest of the macro.
// 
//  A first loop over the pedestal file is performed using the class MJPedestal
//
//  The container MCalibrationQECam is created and followed during the execution of the 
//  rest of the macro.
//
//  A loop over the calibration files is performed using the class MJCalibration. 
//  The results are displayed using the MJCalibration::SetNormalDisplay() facility, 
//  but other displays can easily be uncommented. 
//  The call to MJCalibration skips the relative time calibration, which can be 
//  uncommented as well. 
// 
/////////////////////////////////////////////////////////////////////////////
const TString inpath = "/home/rootdata/BlindPixel/";
const Int_t pedrun  = 20491;
const Int_t calrun1 = 20494;
const Int_t calrun2 = 20496;

void calibration(const Int_t prun=pedrun, const Int_t crun1=calrun1, const Int_t crun2=calrun2)
{
  
  MRunIter pruns;
  MRunIter cruns;

  pruns.AddRun(prun,inpath);

  if (crun2==0)
    cruns.AddRun(crun1,inpath);
  else
    cruns.AddRuns(crun1,crun2,inpath);

  MCalibrationCam::PulserColor_t color;

  if (crun1 < 20000)
    color = MCalibrationCam::kCT1;
  else
    color = FindColor((MDirIter*)&cruns);

  if (color == MCalibrationCam::kNONE)
    return;

  MCalibrationQECam qecam;
  MBadPixelsCam     badcam;

  //
  // If you want to exclude pixels from the beginning, read 
  // an ascii-file with the corr. pixel numbers (see MBadPixelsCam)
  //
  //  badcam.AsciiRead("badpixels.dat");

  for (Int_t i=0;i<badcam.GetSize();i++)
    if (badcam[i].IsBad())
      cout << "Bad Pixel: " << i << endl;

  MStatusDisplay *display = new MStatusDisplay;
  display->SetUpdateTime(3000);
  display->Resize(850,700);
  
  /************************************/
  /* FIRST LOOP: PEDESTAL COMPUTATION */
  /************************************/

  MJPedestal pedloop;
  pedloop.SetInput(&pruns);
  pedloop.SetDisplay(display);
  pedloop.SetBadPixels(badcam);

  if (!pedloop.Process())
    return;

  //
  // Now setup the tasks and for the calibration:
  // ---------------------------------------------------
  //
  MJCalibration calloop;
  calloop.SetColor(color);

  //
  // If you want only the most necessary plots, choose:
  // calloop.SetDataCheck();
  // 
  // For everything, you ever dreamed of, choose:
  // calloop.SetFullDisplay();

  //
  // If you want to calibrate the times as well, choose:
  //
  //  calloop.SetRelTimeCalibration();
  calloop.SetInput(&cruns);
  calloop.SetDisplay(display);
  calloop.SetQECam(qecam);
  calloop.SetBadPixels(pedloop.GetBadPixels());
  if (!calloop.Process(pedloop.GetPedestalCam()))
    return;
  
}

MCalibrationCam::PulserColor_t FindColor(MDirIter* run) 
{
  
  MCalibrationCam::PulserColor_t col = MCalibrationCam::kNONE;

  TString filenames;

  while (!(filenames=run->Next()).IsNull())
    {

      filenames.ToLower();

      if (filenames.Contains("green"))
        if (col == MCalibrationCam::kNONE)
          {
            cout << "Found colour: Green  in " << filenames << endl;
            col = MCalibrationCam::kGREEN;
          }
        else if (col != MCalibrationCam::kGREEN)
          {
            cout << "Different colour found in " << filenames << "... abort" << endl;
            return MCalibrationCam::kNONE;
          }

      if (filenames.Contains("blue"))
        if (col == MCalibrationCam::kNONE)
          {
            cout << "Found colour: Blue  in " << filenames << endl;
            col = MCalibrationCam::kBLUE;
          }
        else if (col != MCalibrationCam::kBLUE)
          {
            cout << "Different colour found in " << filenames << "... abort" << endl;
            return MCalibrationCam::kNONE;
          }

      if (filenames.Contains("uv"))
        if (col == MCalibrationCam::kNONE)
          {
            cout << "Found colour: Uv  in " << filenames << endl;
            col = MCalibrationCam::kUV;
          }
        else if (col != MCalibrationCam::kUV)
          {
            cout << "Different colour found in " << filenames << "... abort" << endl;
            return MCalibrationCam::kNONE;
          }

      if (filenames.Contains("ct1"))
        if (col == MCalibrationCam::kNONE)
          {
            cout << "Found colour: Ct1  in " << filenames << endl;
            col = MCalibrationCam::kCT1;
          }
        else if (col != MCalibrationCam::kCT1)
          {
            cout << "Different colour found in " << filenames << "... abort" << endl;
            return MCalibrationCam::kNONE;
          }
      
    }
  

      
  if (col == MCalibrationCam::kNONE)
    cout <<  "No colour found in filenames of runs: " << ((MRunIter*)run)->GetRunsAsString() 
         << "... abort" << endl;
  
  return col;      
}
