/* ======================================================================== *\
!
! *
! * 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 outpath = "./";
static const TString inpath = "./";
//static const TString inpath = "/home/rootdata/Calib/";
//
// Tell if you want to calibrate times:
//
static const  Bool_t useTimes = kTRUE;
//
// the default pedestal run for the calibration
//
static const Int_t   pedrun  = 26210;
//
// the default start calibration run 
//
static const Int_t   calrun1 = 26209;
//
// the default last calibration run (if 0, only one run is taken, otherwise consecutive runs 
// between calrun1 and calrun2)
//
static const Int_t calrun2 = 0;
//
// A switch to output debugging information about Objects use
//
static const Bool_t debug = kFALSE;
//
void calibration(const Int_t prun=pedrun, const Int_t crun1=calrun1, const Int_t crun2=calrun2)
{


  TObject::SetObjectStat(kTRUE);

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

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

  //
  // Choose the arrival time Extractor:
  //
  //  MExtractTimeHighestIntegral timeext;
  MExtractTimeFastSpline timeext;
  //
  // Set Ranges or Windows
  //
  timeext.SetRange(2,12,4,14);

  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.SetOutputPath(outpath.Data());
  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.SetOutputPath(outpath.Data());
  calloop.SetDisplay(display);
  calloop.SetQECam(qecam);
  calloop.SetBadPixels(pedloop.GetBadPixels());

  calloop.Process(pedloop.GetPedestalCam());

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

  MJExtractCalibTest testloop;

  testloop.SetExtractor(&extractor);
  testloop.SetTimeExtractor(&timeext);
  testloop.SetInput(&cruns);
  testloop.SetOutputPath(outpath);
  testloop.SetDisplay(display);
  testloop.SetBadPixels(calloop.GetBadPixels());
  testloop.ProcessD(pedloop.GetPedestalCam(),calloop.GetCalibrationCam(),calloop.GetQECam());
  if (useTimes)
      testloop.ProcessT(pedloop.GetPedestalCam(),calloop.GetRelTimeCam());

  TObject::SetObjectStat(kFALSE);
  //
  // List of useful containers:
  // 
  if (debug)
    gObjectTable->Print();

  //
  // List of useful containers:
  // 
/*
  MPedestalCam          &pedcam      = pedloop.GetPedestalCam();
  MCalibrationChargeCam &chargecam   = calloop.GetCalibrationCam();
  MCalibrationQECam     &qecam       = calloop.GetCalibrationCam();
  MBadPixelsCam         &badcam      = calloop.GetBadPixels();
  MHCalibrationTestCam  &testcam     = testloop.GetTestCam();
  MHCalibrationTestTimeCam &testtime = testloop.GetTestTimeCam();
*/
}


