/*********************************/
/* Compute the hillas parameters */
/*********************************/

#include "TString.h"
#include "TArrayS.h"

#include "MParList.h"
#include "MTaskList.h"
#include "MPedestalCam.h"
#include "MBadPixelsCam.h"
#include "MBadPixelsTreat.h"
#include "MReadMarsFile.h"
#include "MReadReports.h"
#include "MGeomApply.h"
#include "MPedCalcPedRun.h"
#include "MEvtLoop.h"
#include "MGeomCamMagic.h"
#include "MExtractedSignalCam.h"
#include "MCalibrationChargeCam.h"
#include "MHCalibrationChargeCam.h"
#include "MHCalibrationRelTimeCam.h"
#include "MExtractor.h"
#include "MExtractFixedWindow.h"
#include "MExtractFixedWindowPeakSearch.h"
#include "MExtractSlidingWindow.h"
#include "MPedCalcFromLoGain.h"
#include "MExtractSignal.h"
#include "MCalibrationChargeCalc.h"
#include "MFCosmics.h"
#include "MContinue.h"
#include "MLog.h"
#include "MCerPhotEvt.h"
#include "MPedPhotCam.h"
#include "MCalibrateData.h"
#include "MPedPhotCalc.h"
#include "MHillas.h"
#include "MNewImagePar.h"
#include "MRawRunHeader.h"
#include "MSrcPosCam.h"
#include "MImgCleanStd.h"
#include "MHillasSrcCalc.h"
#include "MHillasCalc.h"
#include "MArrivalTimeCam.h"
#include "MArrivalTimeCalc2.h"
#include "MIslands.h"
#include "MImgIsland.h"
#include "MIslandsCalc.h"
#include "MIslandsClean.h"
#include "MWriteRootFile.h"
#include "MArgs.h"
#include "MRunIter.h"
#include "MJPedestal.h"
#include "MJCalibration.h"
#include "MHillasDisplay.h"
#include "MF.h"
#include "MContinue.h"
#include "MReportDrive.h"

#include "TApplication.h"

#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

Bool_t readDatacards(TString& filename);
void makeHillas();


// declaration of variables read from datacards
TString  outname;
const TString outpath = "./";
TString  idirname;
TString  filter;
TString  psfilename("makehillas.ps");
MRunIter pedcaliter;
MRunIter caliter;
MRunIter pediter;
MRunIter datiter;
UInt_t   display   = 0;
ULong_t  nmaxevents= 999999999;
Short_t  calflag   = 1;
Bool_t   caltimeflag   = kFALSE;
Short_t  cleanflag   = 1;
UShort_t lrings     = 1;
Float_t  lcore     = 3.0;
Float_t  ltail     = 1.5;
Int_t    islflag   = 0;
Float_t  lnew      = 40;
Int_t    kmethod   = 1;
Int_t    kalgorithm = 1;
Int_t    nfiles    = 0;
Int_t    hifirst = 0;
Int_t    hilast  = 14;
Int_t    lofirst = 2;
Int_t    lolast  = 14;
Int_t    wsize   = 6;
Int_t    sext    = 0;

const TString defaultcard="makehillas.datacard";
char* chext[3]={"Fixed window","Sliding window","Peak Search"};
/*************************************************************/
static void Usage()
{
  gLog <<endl;
  gLog << "Usage is:" << endl;
  gLog << "   makeHillas [-h] [-?] <datacards>" << endl << endl;
  gLog << "     <datacards>: datacards file name (dafault makehillas.datacards)" << endl;
  gLog << "     -?/-h: This help" << endl << endl;
}
/*************************************************************/
int main(int argc, char **argv)
{
  // create a TApplication to be able to 
  TApplication app("Application",0,0);

  // evaluate arguments
  MArgs arg(argc, argv);
  if (arg.HasOnly("-?") || arg.HasOnly("-h") || arg.HasOnly("--help"))
    {
      Usage();
      return -1;
    }

  TString datacard  = arg.GetArgumentStr(0);
  if(!datacard.Length())
    datacard = defaultcard;

  if(!readDatacards(datacard))
    {
      cout << "Error reading datacards. Stoping" << endl;
      return -1;
    }

  makeHillas();
}

/*************************************************************/
void makeHillas()
{
  // Set the signal extractor
  MExtractor* extractor;
  switch(sext)
    {
    case 0:
      extractor = new MExtractFixedWindow();
      break;
    case 1:
      extractor = new MExtractSlidingWindow();
      ((MExtractSlidingWindow*)extractor)->SetWindowSize(wsize,wsize);
      break;
    case 2:
      extractor = new MExtractFixedWindowPeakSearch();
      ((MExtractFixedWindowPeakSearch*)extractor)->SetWindows(wsize,wsize,4);
      break;
    default:
      extractor = new MExtractFixedWindow();
      break;
    }

  extractor->SetRange(hifirst,hilast,lofirst,lolast);
 

  /****************************************************/
  /* FIRST LOOP: PEDESTAL COMPUTATION FOR CALIBRATION */
  /****************************************************/

  // 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 pedcalloop;
  pedcalloop.SetInput(&pedcaliter);
  pedcalloop.SetExtractor(extractor);
  //  pedloop.SetBadPixels(badcam);
  //pedcalloop.SetOutputPath(outpath.Data());


  if (!pedcalloop.Process())
    return;

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

  MJCalibration calloop;

  calloop.SetRelTimeCalibration(caltimeflag);
  calloop.SetExtractor(extractor);
  calloop.SetInput(&caliter);
  calloop.SetBadPixels(pedcalloop.GetBadPixels());
  if(calflag==2)
    calloop.SetUseBlindPixel();
  if(calflag>0)
    if (!calloop.Process(pedcalloop.GetPedestalCam()))
      return;

  // Next loops are different if we take pedestals from data or from pedestal files
  if(pediter.GetNumRuns()==0)
    {
      /************************************************************************/
      /*                 THIRD (SMALL) LOOP TO GET INITIAl PEDESTALS          */
      /************************************************************************/      
      MParList  plist3;
      MTaskList tlist3;
      
      // containers
      MPedestalCam  pedcamdata;      
      MGeomCamMagic geomcam;
      
      plist3.AddToList(&tlist3);
      plist3.AddToList(&geomcam);
      plist3.AddToList(&pedcamdata);
            
      //tasks
      MReadMarsFile read3("Events");
      static_cast<MRead&>(read3).AddFiles(datiter); 
      read3.DisableAutoScheme();

      MGeomApply      geomapl;

      MPedCalcFromLoGain peddatacalc;
      peddatacalc.SetPedestalUpdate(kFALSE);
      peddatacalc.SetRange(hifirst,hilast,lofirst,lolast);
      peddatacalc.SetWindowSize(wsize,wsize);
      peddatacalc.SetNumEventsDump(500);
      peddatacalc.SetMaxHiGainVar(40);
      
      tlist3.AddToList(&read3);
      tlist3.AddToList(&geomapl);
      tlist3.AddToList(&peddatacalc);
      
      // Create and setup the eventloop
      MEvtLoop evtloop3;
      evtloop3.SetParList(&plist3);
      if (!evtloop3.Eventloop(500))
	return;
      
      tlist3.PrintStatistics();
      
      /************************************************************************/
      /*       FOURTH LOOP: PEDESTAL+DATA CALIBRATION INTO PHOTONS            */
      /************************************************************************/
      
      MParList  plist4;
      MTaskList tlist4;
      plist4.AddToList(&tlist4);
      
      // containers 
      MCerPhotEvt     nphot;
      MPedPhotCam     nphotrms;
      MHillas         hillas;
      MNewImagePar    newimagepar;
      MSrcPosCam      source;
      MRawRunHeader   runhead;      
      MArrivalTimeCam timecam;      
      MReportDrive    reportdrive;
      // islands
      MIslands      isl;
      MIslands      isl2;
      MIslands      isl3;
      
      isl.SetName("MIslands");  
      isl2.SetName("MIslands2");
      isl3.SetName("MIslands3");
      
      plist4.AddToList(&timecam);
      plist4.AddToList(&isl);
      
      if (islflag == 2)
	plist4.AddToList(&isl2);
      if (islflag == 3)
	plist4.AddToList(&isl3);
      
      plist4.AddToList(&geomcam);
      plist4.AddToList(&pedcamdata);
      plist4.AddToList(&calloop.GetCalibrationCam());
      plist4.AddToList(&calloop.GetQECam());
      plist4.AddToList(&calloop.GetRelTimeCam());
      plist4.AddToList(&calloop.GetBadPixels());
      plist4.AddToList(&nphot);
      plist4.AddToList(&nphotrms);
      plist4.AddToList(&source);
      plist4.AddToList(&hillas);
      plist4.AddToList(&newimagepar);
      plist4.AddToList(&runhead);
      plist4.AddToList(&reportdrive);
      
      // cuts
      MF cut(filter);
      
      //tasks
      //      MReadMarsFile read4("Events");
      MReadReports read4;
      read4.AddTree("Events","MTime.",kTRUE);
      read4.AddTree("Drive");
		    //      read4.DisableAutoScheme();
      static_cast<MRead&>(read4).AddFiles(datiter); 
            
      peddatacalc.SetPedestalUpdate(kTRUE);

      MCalibrateData::CalibrationMode_t calMode=MCalibrateData::kDefault;  
      if(calflag==0)
	calMode=MCalibrateData::kNone;
      if(calflag==-1)
	calMode=MCalibrateData::kDummy;
      MCalibrateData  photcalc;
      photcalc.SetCalibrationMode(calMode);
      photcalc.EnablePedestalType(MCalibrateData::kRun);
      photcalc.EnablePedestalType(MCalibrateData::kEvent);

      MImgCleanStd      clean(lcore,ltail);
      clean.SetCleanRings(lrings);
      MImgCleanStd::CleaningMethod_t cleanMeth= MImgCleanStd::kStandard;  
      if(cleanflag==2)
	cleanMeth=MImgCleanStd::kDemocratic;
      clean.SetMethod(cleanMeth);
      
      MArrivalTimeCalc2 timecalc;
      MIslandsCalc       island;
      island.SetOutputName("MIslands");
      island.SetAlgorithm(kalgorithm);
      
      MBadPixelsTreat   interpolatebadpixels;
      interpolatebadpixels.SetUseInterpolation();
      interpolatebadpixels.SetProcessPedestal();
      
      MIslandsClean      islclean(lnew);
      islclean.SetInputName("MIslands");
      islclean.SetMethod(kmethod);
      
      MIslandsCalc       island2;
      island2.SetOutputName("MIslands2");  
      island2.SetAlgorithm(kalgorithm);
      
      MIslandsCalc       island3;
      island3.SetOutputName("MIslands3");  
      
      
      MHillasCalc       hcalc;
      MHillasSrcCalc    csrc1;
      
      MContinue applycut(&cut);
      applycut.SetInverted(kTRUE);
      MWriteRootFile write(outname,"RECREATE");
      
      MHillasDisplay*  disphillas=NULL;
      
      write.AddContainer("MHillas"        , "Parameters");
      write.AddContainer("MHillasSrc"     , "Parameters");
      write.AddContainer("MHillasExt"     , "Parameters");
      write.AddContainer("MNewImagePar"   , "Parameters");
      write.AddContainer("MRawEvtHeader"  , "Parameters");
      write.AddContainer("MRawRunHeader"  , "Parameters");
      write.AddContainer("MTime"          , "Parameters");
      write.AddContainer("MConcentration" , "Parameters");
      write.AddContainer("MSrcPosCam"     , "Parameters");
      write.AddContainer("MIslands"       , "Parameters");
      write.AddContainer("MReportDrive"   , "Parameters");

      if (islflag == 2) 
	write.AddContainer("MIslands2" , "Parameters");
      if (islflag == 3) 
	write.AddContainer("MIslands3" , "Parameters");
      
      
      if(display)
	{
	  disphillas = new MHillasDisplay(&nphot,&geomcam);
	  disphillas->SetIslandsName("MIslands");
	  if (islflag == 2)
	    disphillas->SetIslandsName("MIslands2");
	  if (islflag == 3)
	    disphillas->SetIslandsName("MIslands3");
	}      
      
      tlist4.AddToList(&read4);
      tlist4.AddToList(&geomapl);
      tlist4.AddToList(&peddatacalc);
      tlist4.AddToList(extractor);
      tlist4.AddToList(&timecalc);
      tlist4.AddToList(&photcalc);
      if(calflag==11 || calflag==21)
      	tlist4.AddToList(&interpolatebadpixels);
      tlist4.AddToList(&clean);
      tlist4.AddToList(&island);
      
      if (islflag == 2)
	{
	  tlist4.AddToList(&islclean);
	  tlist4.AddToList(&island2);
	}
      
      if (islflag == 3)
	{
	  tlist4.AddToList(&islclean);
	  tlist4.AddToList(&island3);
	}
      
      tlist4.AddToList(&hcalc);
      tlist4.AddToList(&csrc1);
      if(filter.Length())
	tlist4.AddToList(&applycut);
      tlist4.AddToList(&write);
      if(display)
	{
	  disphillas->SetPSFile();
	  disphillas->SetPSFileName(psfilename);
	  if(display==2) 
	    disphillas->SetPause(kFALSE);	
	  tlist4.AddToList(disphillas);
	}
      
      // Create and setup the eventloop
      MEvtLoop datloop;
      datloop.SetParList(&plist4);
      
      cout << "*************************************************************" << endl;
      cout << "***   COMPUTING DATA USING EXTRACTED SIGNAL (IN PHOTONS)  ***" << endl;
      cout << "*************************************************************" << endl;
      
      if (!datloop.Eventloop(nmaxevents))
	return;
      
      tlist4.PrintStatistics();    
      delete extractor;
    }
  else
    {      
      /************************************************************************/
      /*                THIRD LOOP: PEDESTAL CALIBRATION INTO PHOTONS         */
      /************************************************************************/
      
      // First Compute the pedestals
      MJPedestal pedloop;
      pedloop.SetInput(&pediter);
      
      if (!pedloop.Process())
	return;
      
      MParList  plist3;
      MTaskList tlist3;
      plist3.AddToList(&tlist3);
      
      // containers
      MGeomCamMagic       geomcam;
      MCerPhotEvt         nphot;
      MPedPhotCam         nphotrms;
      MExtractedSignalCam sigcam;
      
      plist3.AddToList(&geomcam);
      plist3.AddToList(&pedloop.GetPedestalCam());
      plist3.AddToList(&calloop.GetCalibrationCam());
      plist3.AddToList(&calloop.GetQECam());
      plist3.AddToList(&calloop.GetRelTimeCam());
      plist3.AddToList(&calloop.GetBadPixels());
      plist3.AddToList(&sigcam);
      plist3.AddToList(&nphot);
      plist3.AddToList(&nphotrms);
      
      
      MCalibrateData::CalibrationMode_t calMode=MCalibrateData::kDefault;  
      if(calflag==0)
	calMode=MCalibrateData::kNone;
      if(calflag==-1)
	calMode=MCalibrateData::kDummy;
      
      //tasks
      MReadMarsFile read3("Events");
      static_cast<MRead&>(read3).AddFiles(pediter); 
      read3.DisableAutoScheme();
      
      MGeomApply      geomapl;
      MPedPhotCalc    photrmscalc; 
      MCalibrateData  photcalc;
      photcalc.SetCalibrationMode(calMode);
      
      tlist3.AddToList(&read3);
      tlist3.AddToList(&geomapl);
      tlist3.AddToList(extractor);
      tlist3.AddToList(&photcalc);
      tlist3.AddToList(&photrmscalc);
      
      // Create and setup the eventloop
      MEvtLoop evtloop3;
      evtloop3.SetParList(&plist3);
      if (!evtloop3.Eventloop())
	return;
      
      tlist3.PrintStatistics();
      
      /************************************************************************/
      /*                FOURTH LOOP: DATA CALIBRATION INTO PHOTONS            */
      /************************************************************************/
      
      MParList  plist4;
      MTaskList tlist4;
      plist4.AddToList(&tlist4);
      
      // containers 
      MHillas       hillas;
      MNewImagePar  newimagepar;
      MSrcPosCam    source;
      MRawRunHeader runhead;
      
      MArrivalTimeCam   timecam;
      
      
      // islands
      MIslands      isl;
      MIslands      isl2;
      MIslands      isl3;
      
      isl.SetName("MIslands");  
      isl2.SetName("MIslands2");
      isl3.SetName("MIslands3");
      
      plist4.AddToList(&timecam);
      plist4.AddToList(&isl);
      
      if (islflag == 2)
	plist4.AddToList(&isl2);
      if (islflag == 3)
	plist4.AddToList(&isl3);
      
      plist4.AddToList(&geomcam);
      plist4.AddToList(&pedloop.GetPedestalCam());
      plist4.AddToList(&calloop.GetCalibrationCam());
      plist4.AddToList(&calloop.GetQECam());
      plist4.AddToList(&calloop.GetRelTimeCam());
      plist4.AddToList(&calloop.GetBadPixels());
      plist4.AddToList(&nphot);
      plist4.AddToList(&nphotrms);
      plist4.AddToList(&source);
      plist4.AddToList(&hillas);
      plist4.AddToList(&newimagepar);
      plist4.AddToList(&runhead);
      
      // cuts
      MF cut(filter);
      
      //tasks
      //      MReadMarsFile read4("Events");
      MReadReports read4;
      read4.AddTree("Events","MTime.",kTRUE);
      read4.AddTree("Drive");
		    //      read4.DisableAutoScheme();
      static_cast<MRead&>(read4).AddFiles(datiter); 
            
      

      MImgCleanStd      clean(lcore,ltail);
      clean.SetCleanRings(lrings);
      MImgCleanStd::CleaningMethod_t cleanMeth= MImgCleanStd::kStandard;  
      if(cleanflag==2)
	cleanMeth=MImgCleanStd::kDemocratic;
      clean.SetMethod(cleanMeth);
      
      MArrivalTimeCalc2 timecalc;
      MIslandsCalc       island;
      island.SetOutputName("MIslands");
      island.SetAlgorithm(kalgorithm);
      
      MBadPixelsTreat   interpolatebadpixels;
      interpolatebadpixels.SetUseInterpolation();
      interpolatebadpixels.SetProcessPedestal();
      //  interpolatebadpixels.SetSloppyTreatment();
      
      MIslandsClean      islclean(lnew);
      islclean.SetInputName("MIslands");
      islclean.SetMethod(kmethod);
      
      MIslandsCalc       island2;
      island2.SetOutputName("MIslands2");  
      island2.SetAlgorithm(kalgorithm);
      
      MIslandsCalc       island3;
      island3.SetOutputName("MIslands3");  
      
      
      MHillasCalc       hcalc;
      MHillasSrcCalc    csrc1;
      
      MContinue applycut(&cut);
      applycut.SetInverted(kTRUE);
      MWriteRootFile write(outname,"RECREATE");
      
      MHillasDisplay*  disphillas=NULL;
      
      write.AddContainer("MHillas"        , "Parameters");
      write.AddContainer("MHillasSrc"     , "Parameters");
      write.AddContainer("MHillasExt"     , "Parameters");
      write.AddContainer("MNewImagePar"   , "Parameters");
      write.AddContainer("MRawEvtHeader"  , "Parameters");
      write.AddContainer("MRawRunHeader"  , "Parameters");
      write.AddContainer("MTime"          , "Parameters");
      write.AddContainer("MConcentration" , "Parameters");
      write.AddContainer("MSrcPosCam"     , "Parameters");
      write.AddContainer("MIslands"       , "Parameters");
      
      if (islflag == 2) 
	write.AddContainer("MIslands2" , "Parameters");
      if (islflag == 3) 
	write.AddContainer("MIslands3" , "Parameters");
      
      
      if(display)
	{
	  disphillas = new MHillasDisplay(&nphot,&geomcam);
	  disphillas->SetIslandsName("MIslands");
	  if (islflag == 2)
	    disphillas->SetIslandsName("MIslands2");
	  if (islflag == 3)
	    disphillas->SetIslandsName("MIslands3");
	}      
      
      tlist4.AddToList(&read4);
      tlist4.AddToList(&geomapl);
      tlist4.AddToList(extractor);
      tlist4.AddToList(&photcalc);
      if(calflag==11 || calflag==21)
	tlist4.AddToList(&interpolatebadpixels);
      tlist4.AddToList(&clean);
      tlist4.AddToList(&timecalc);
      tlist4.AddToList(&island);
      
      if (islflag == 2)
	{
	  tlist4.AddToList(&islclean);
	  tlist4.AddToList(&island2);
	}
      
      if (islflag == 3)
	{
	  tlist4.AddToList(&islclean);
	  tlist4.AddToList(&island3);
	}
      
      tlist4.AddToList(&hcalc);
      tlist4.AddToList(&csrc1);
      if(filter.Length())
	tlist4.AddToList(&applycut);
      tlist4.AddToList(&write);
      if(display)
	{
	  disphillas->SetPSFile();
	  disphillas->SetPSFileName(psfilename);
	  if(display==2) 
	    disphillas->SetPause(kFALSE);	
	  tlist4.AddToList(disphillas);
	}
      
      // Create and setup the eventloop
      MEvtLoop datloop;
      datloop.SetParList(&plist4);
      
      cout << "*************************************************************" << endl;
      cout << "***   COMPUTING DATA USING EXTRACTED SIGNAL (IN PHOTONS)  ***" << endl;
      cout << "*************************************************************" << endl;
      
      if (!datloop.Eventloop(nmaxevents))
	return;
      
      tlist4.PrintStatistics();    
      delete extractor;
    }
}
  //-------------------------------------------------------------------------------

Bool_t readDatacards(TString& filename)
{
  ifstream ifun(filename.Data());
  if(!ifun)
    {
      cout << "File " << filename << " not found" << endl;
      return kFALSE;
    }

  TString word;
  
  while(ifun >> word)
    {
      // skip comments
      if(word[0]=='/' && word[1]=='/')
	{
	  while(ifun.get()!='\n'); // skip line
	  continue;
	}

      // number of events
      if(strcmp(word.Data(),"NEVENTS")==0)
	ifun >> nmaxevents;


      // input file directory
      if(strcmp(word.Data(),"IDIR")==0)
	{
	  if(idirname.Length())
	    cout << "readDataCards Warning: overriding input directory file name" << endl;
	  ifun >> idirname;
	}

      // pedestal runs
      if(strcmp(word.Data(),"PRUNS")==0)
	{
	  if(pediter.GetNumRuns())
	    cout << "readDataCards Warning: adding pedestal runs to the existing list" << endl;
	  ifun >> word;
	  if(strcmp(word.Data(),"0")!=0)
	    pediter.AddRuns(word.Data(),idirname.Data());
	}

      // pedestal runs for calibration
      if(strcmp(word.Data(),"PCRUNS")==0)
	{
	  if(pedcaliter.GetNumRuns())
	    cout << "readDataCards Warning: adding pedestal runs for calibration to the existing list" << endl;
	  ifun >> word;
	  pedcaliter.AddRuns(word.Data(),idirname.Data());
	}

      // calibration runs
      if(strcmp(word.Data(),"CRUNS")==0)
	{
	  if(caliter.GetNumRuns())
	    cout << "readDataCards Warning: adding calibration runs to the existing list" << endl;
	  ifun >> word;
	  caliter.AddRuns(word.Data(),idirname.Data());
	}

      // data runs
      if(strcmp(word.Data(),"DRUNS")==0)
	{
	  if(datiter.GetNumRuns())
	    cout << "readDataCards Warning: adding data runs to the existing list" << endl;
	  ifun >> word;
	  datiter.AddRuns(word.Data(),idirname.Data());
	}
      
      // output file name
      if(strcmp(word.Data(),"OUTFILE")==0)
	{
	  if(outname.Length())
	    cout << "readDataCards Warning: overriding output file name" << endl;
	  ifun >> outname;
	}

      // exclusion cut
      if(strcmp(word.Data(),"FILTER")==0)
	{
	  if(filter.Length())
	    cout << "readDataCards Warning: overriding existing cut" << endl;
	  
	  char ch;
	  while((ch=ifun.get())!='\n')
	    filter.Append(ch);	  
	}

      // display flag
      if(strcmp(word.Data(),"DISPLAY")==0)
	ifun >> display;

      // ps file name
      if(strcmp(word.Data(),"PSFILENAME")==0)
	ifun >> psfilename;

      // calibration flag
      if(strcmp(word.Data(),"CALFLAG")==0)
	ifun >> calflag;

      // calibration flag
      if(strcmp(word.Data(),"CALTIME")==0)
	ifun >> caltimeflag;

      // cleaning level
      if(strcmp(word.Data(),"CLEANLEVEL")==0)
	{
	  ifun >> lcore;
	  ifun >> ltail;
	  if(ifun.get()!='\n'){
	    ifun.unget();
	    ifun >> lrings;
	    if(ifun.get()!='\n'){
	      ifun.unget();
	      ifun >> cleanflag;
	    }
	  }
	}
      
      // cleaning level
      if(strcmp(word.Data(),"EXTRACTOR")==0)
	ifun >> sext >> hifirst >> hilast >> lofirst >> lolast >> wsize;
      
      if(strcmp(word.Data(),"ISLFLAG")==0)
	{
	  ifun >> islflag;

	  // if (islflag == 1 || islflag == 2)
	    ifun >> kalgorithm;
	}

      // island cleaning 
      if (islflag == 2){
	if(strcmp(word.Data(),"ISLANDCLEAN")==0)
	  {
	    ifun >> kmethod;
	    ifun >> lnew;
	  }
      }
    }

  pediter.Reset();
  pedcaliter.Reset();
  caliter.Reset();
  datiter.Reset();
  TString pfile;

  // Dump read values
  cout << "************************************************" << endl;
  cout << "* Datacards read from file " << filename << endl;
  cout << "************************************************" << endl;
  cout << "Pedestal file (s) for calibration: "  << endl;
  while(!(pfile=pedcaliter.Next()).IsNull())
    cout << pfile << endl;
  cout << "Calibration file (s): "  << endl;
  while(!(pfile=caliter.Next()).IsNull())
    cout << pfile << endl;
  if(pediter.GetNumRuns()>0)
    {
      cout << "Pedestal file (s): "  << endl;
      while(!(pfile=pediter.Next()).IsNull())
	cout << pfile << endl;
    }
  else 
    cout << "Warning: Pedestals for data will be computed from data themselves" << endl;
  cout << "Data file (s): "  << endl;
  while(!(pfile=datiter.Next()).IsNull())
    cout << pfile << endl;
  cout << "Maximum number of events: " << nmaxevents << endl;
  if(filter.Length())
    cout << "Applying rejection cut: " << filter << endl;
  cout << "Output file name: " << outname << endl;
  if(display)
    cout << "Generating PS file: " << psfilename << endl;
  cout << "Signal Extractor: " << chext[sext] << " with bounds ("<<hifirst<<","<<hilast<<","<<lofirst<<","<<lolast<<"), window size " << wsize << endl;
  cout << "Calibration: ";
  if(calflag==0)    
    cout << "Pixel area proportional intercalibration (kNone)" << endl;
  else if(calflag==-1)    
    cout << "No calibration whatsoever" << endl;
  else if(calflag==1)
    cout << "Default calibration" << endl;
  else if(calflag==11)
    cout << "Default calibration + bad pixels interpolation" << endl;
  cout << "Cleaning level: ("<<lcore<<","<<ltail<<") - " << lrings << "ring" << endl;
  cout << "Cleaning method: "<< cleanflag << endl;
  if (islflag == 1 || islflag == 2)
    cout << "Island calcultation..." << "using algorithm #" << kalgorithm <<endl;
  if (islflag == 2)
    {
      cout << "Island Cleaning: "<< kmethod <<" method  "<< lnew << " new threshold" << endl;
    }
  cout << "***********" << endl << endl;
  
  if(!pedcaliter.GetNumEntries())
    {
      cout << "No pedestal file for calibration specified" << endl;
      return kFALSE;
    }
  if(!caliter.GetNumEntries() && calflag>0)
    {
      cout << "No calibration file name specified" << endl;
      return kFALSE;
    }
  if(!datiter.GetNumEntries())
    {
      cout << "No data file name specified" << endl;
      return kFALSE;
    }
  if(!outname.Length())
    {
      cout << "No output file name specified" << endl;
      return kFALSE;
    }


  return kTRUE;
}

