/* ======================================================================== *\
   !
   ! *
   ! * 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):
   !
   !   Copyright: MAGIC Software Development, 2000-2004
   !
   !
   \* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//
//  mmcCleaning - study different cleaning levels with mc
//
//
/////////////////////////////////////////////////////////////////////////////


void mmcCleaning()
{
  //
  // This is a demonstration program which reads in MC camera files
  // and produces and output with calibrated events (signal in photons
  // for all pixels, in MCerPhotEvt containers).
  //

  // ------------- user change -----------------
  Char_t*  NonoiseFilename = "/local_disk/jrico/mc/Gamma_zbin12_0_7_1250to1259_w0_nonoise.root";  // File to be used for the calibration (must be a camera file without added noise)
  Char_t*  NoiseFilename   = "/local_disk/jrico/mc/Gamma_zbin12_0_7_1250to1259_w0.root";  // File to be analyzed

  Char_t* NonoiseOutFilename = "/local_disk/jrico/mc/Gamma_zbin12_0_7_1250to1259_w0_cleaned_nonoise.root";  // Output file name
  Char_t* NoiseOutFilename   = "/local_disk/jrico/mc/Gamma_zbin12_0_7_1250to1259_w0_cleaned_6045.root";     // Output file name


  MExtractSignal    sigextract;  
  // (other extraction methods can be used)

  sigextract.SetSaturationLimit(240);
  // Defines when to switch to low gain

  // Define FADC slices to be integrated in high and low gain:
  sigextract.SetRange(1, 14, 3, 14);

  // ---------------------------------------------------------------------
  //
  // Create a empty Parameter List and an empty Task List
  // The tasklist is identified in the eventloop by its name
  //
  MParList  plist;
  MTaskList tlist;
  plist.AddToList(&tlist);

  MPedestalCam  pedcam;
  MGeomCamMagic geomcam;
  MCerPhotEvt   nphot;

  plist.AddToList(&pedcam);
  plist.AddToList(&geomcam);
  plist.AddToList(&nphot);

  //
  // Now setup the tasks and tasklist:
  // ---------------------------------
  //
  MReadMarsFile read("Events");
  read.AddFile(NonoiseFilename);
  read.DisableAutoScheme();

  MGeomApply geom; 
  // Reads in geometry from MC file and sets the right sizes for
  // several parameter containers.

  MMcPedestalCopy   pcopy; 
  // Copies pedestal data from the MC file run fadc header to the 
  // MPedestalCam container.

  MDisplay       display(&nphot,&geomcam);
  MHillasDisplay display2(&nphot,&geomcam);

  MPointingPosCalc pointcalc;
  // Creates MPointingPos object and fill it with the telescope orientation
  // information taken from MMcEvt.

  MMcCalibrationUpdate  mccalibupdate;

  MCalibrate calib; 
  // MCalibrate transforms signals from ADC counts into photons. In the first
  // loop it applies a "dummy" calibration supplied by MMcCalibrationUpdate, just 
  // to equalize inner and outer pixels. At the end of the first loop, in the
  // PostProcess of MMcCalibrationCalc (see below) the true calibration constants
  // are calculated.

  calib.SetCalibrationMode(MCalibrate::kFfactor);

  MImgCleanStd clean(6.0,4.5);
  clean.SetRemoveSingle(kFALSE);
  //
  // Applies tail cuts to image. Since the calibration is performed on 
  // noiseless camera files, the precise values of the cleaning levels 
  // are unimportant (in any case, only pixels without any C-photon will
  // be rejected).
  //

  MHillasCalc hcalc; // Calculates Hillas parameters not dependent on source position.
  MHillasSrcCalc hsrccalc;

  MMcCalibrationCalc mccalibcalc; 
  // Calculates calibration constants to convert from ADC counts to photons.
  
  MWriteRootFile write(NonoiseOutFilename); // Writes output
  write.AddContainer("MRawRunHeader", "Events");
  write.AddContainer("MMcEvt",        "Events");
  write.AddContainer("MRawEvtHeader", "Events");
  write.AddContainer("MCerPhotEvt",   "Events");
  write.AddContainer("MHillas",       "Events");
  write.AddContainer("MHillasSrc",    "Events");

  tlist.AddToList(&read);
  tlist.AddToList(&geom);
  tlist.AddToList(&pcopy);
  tlist.AddToList(&pointcalc);
  tlist.AddToList(&sigextract);
  tlist.AddToList(&mccalibupdate);
  tlist.AddToList(&calib);
  tlist.AddToList(&clean);
  tlist.AddToList(&hcalc);
  tlist.AddToList(&hsrccalc);
  //  tlist.AddToList(&display2);
  tlist.AddToList(&mccalibcalc);
  tlist.AddToList(&write);

  //
  // First loop: No noise
  //

  MProgressBar bar;
  bar.SetWindowName("No noise...");

  MEvtLoop evtloop;
  evtloop.SetProgressBar(&bar);
  evtloop.SetParList(&plist);

  if (!evtloop.Eventloop())
    return;
  mccalibcalc.GetHistADC2PhotEl()->Write();
  mccalibcalc.GetHistPhot2PhotEl()->Write();
  // Writes out the histograms used for calibration.


  //
  // Second loop: process file with noise
  //
  MReadMarsFile read2("Events");
  read2.AddFile(NoiseFilename);
  read2.DisableAutoScheme();
  tlist.AddToListBefore(&read2, &read, "All");
  tlist.RemoveFromList(&read);

  MWriteRootFile write2(NoiseOutFilename); // Writes output
  write2.AddContainer("MRawRunHeader", "Events");
  write2.AddContainer("MMcEvt",        "Events");
  write2.AddContainer("MRawEvtHeader", "Events");
  write2.AddContainer("MCerPhotEvt",   "Events");
  write2.AddContainer("MHillas",       "Events");
  write2.AddContainer("MHillasSrc",    "Events");

  //  tlist.AddToListBefore(&display2,&clean, "All");
  tlist.AddToListBefore(&write2, &write, "All");
  tlist.RemoveFromList(&write);



  bar.SetWindowName("Cleaning 3015...");
  clean.SetRemoveSingle();

  //  tlist.RemoveFromList(&clean);
  //  tlist.RemoveFromList(&hcalc);
  tlist.RemoveFromList(&mccalibcalc);

  if (!evtloop.Eventloop())
    return;

  tlist.PrintStatistics();
}
