/* ======================================================================== *\
!
! *
! * 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. 
// 
//  Last, a third loop is performed over the calibration file again in order to 
//  "calibrate" it and test the resulting outcome.
//
/////////////////////////////////////////////////////////////////////////////
static const TString inpath = "/mnt/Data/rootdata/Miscellaneous/2004_03_03/";
static const Int_t pedrun  = 20123;
static const Int_t calrun1 = 20125;
static const Int_t calrun2 = 0;

void calibration(const Int_t prun=pedrun, const Int_t crun1=calrun1, const Int_t crun2=calrun2)
{


  //
  // Choose the signal Extractor:
  //
  MExtractFixedWindowPeakSearch extractor;
  //  MExtractSlidingWindow  extractor;   
  //  MExtractFixedWindow    extractor;   

  //
  // Set Ranges or Windows
  //
  //  extractor.SetRange(2,14,5,14);
  //  extractor.SetWindows(8,8);

  //
  // Choose the arrival time Extractor:
  //
  MExtractTimeHighestIntegral timeext;
  // MExtractTimeSpline timeext;
  //
  // Set Ranges or Windows
  //
  // timeext.SetRange(0,14,6,14);

  //
  // Tell if you want to calibrate times:
  //
  Bool_t useTimes = kTRUE;
  //  Bool_t calibrateTimes = kFALSE;  

  MRunIter pruns;
  MRunIter cruns;

  pruns.AddRun(prun,inpath);

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

  gStyle->SetOptStat(1);
  gStyle->SetOptFit();

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

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

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

  if (!pedloop.Process())
    return;

  /****************************************/
  /* SECOND LOOP: CALIBRATION COMPUTATION */
  /****************************************/

  MJCalibration calloop;

  //
  // If you want to run the data-check on RAW DATA!!!, choose:
  // calloop.SetDataCheck();
  // 
  // If you want to see the data-check plots only, choose:
  // calloop.SetDataCheckDisplay();
  // 
  // For everything, you have ever dreamed of, choose:
  //  calloop.SetFullDisplay();

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

  /*
  MCalibrationChargeCam &chargecam = calloop.GetCalibrationCam();
  MLog juanlog;
  juanlog.SetOutputFile("test.txt",1);
  chargecam.SetLogStream(&juanlog);
  chargecam.Print();
  chargecam.SetLogStream(&gLog);
  */

  /********************************************************************/
  /* THIRD LOOP: APPLY CALIBRATION TO THE CALIBRATION FILES FOR TESTS */
  /********************************************************************/

  MJExtractCalibTest testloop;

  testloop.SetExtractor(&extractor);
  testloop.SetInput(&cruns);
  testloop.SetDisplay(display);
  testloop.SetBadPixels(calloop.GetBadPixels());
  testloop.ProcessD(pedloop.GetPedestalCam(),calloop.GetCalibrationCam(),calloop.GetQECam());
  
}

