#include <TSystem.h>

#include <TFile.h>
#include <TTree.h>
#include <TKey.h>
#include <TList.h>

#include "MParList.h"
#include "MTaskList.h"
#include "MEvtLoop.h"

#include "MRawFileRead.h"
#include "MRawFileWrite.h"
#include "MSqlInsertRun.h"
#include "MRawFileWrite.h"
#include "MReportFileReadCC.h"
#include "MReportFileReadCosy.h"
#include "MReportFileReadTpoint.h"
#include "MRunbookFileRead.h"
#include "MMUXFileRead.h"
#include "MCCrunFileRead.h"
#include "MWriteRootFile.h"
#include "MString.h"

#include "MLog.h"
#include "MLogManip.h"

#include "MArgs.h"
#include "MTime.h"
#include "MArray.h"
#include "MRawEvtData.h"
#include "MRawRunHeader.h"
#include "MRawEvtHeader.h"
#include "MRawCrateArray.h"

#include "MFDataMember.h"

using namespace std;

//////////////////////////////////////////////////////////////////////////////
//                                                                          //
// This is an easy implementation of the Merging process                     //
// (as compilable prog)                                                     //
//                                                                          //
// at the moment it reads a binary file ("rawtest.bin") which was written   //
// in the DAQ raw format.                                                   //
//                                                                          //
// The data are stored in root container objects (classes derived from      //
// TObject like MRawRunHeader)                                              //
//                                                                          //
// This containers are written to a root file ("rawtest.root")              //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

static void StartUpMessage()
{
    gLog << all << endl;

    //                1         2         3         4         5
    //       12345678901234567890123456789012345678901234567890
    gLog << "==================================================" << endl;
    gLog << "                MERPP - MARS V" << MARSVER          << endl;
    gLog << "     MARS - Merging and Preprocessing Program"      << endl;
    gLog << "            Compiled on <" << __DATE__ << ">"       << endl;
    gLog << "               Using ROOT v" << ROOTVER             << endl;
    gLog << "==================================================" << endl;
    gLog << endl;
}

static void Usage()
{
    //                1         2         3         4         5         6         7         8
    //       12345678901234567890123456789012345678901234567890123456789012345678901234567890
    gLog << all << endl;
    gLog << "Sorry the usage is:" << endl;
    gLog << " merpp [options] inputfile[[.rep],[.raw],[.raw.gz],[.txt],[.rbk]] [outputfile[.root]]" << endl << endl;
    gLog << " Arguments:" << endl;
    gLog << "   inputfile.raw             Magic DAQ binary file." << endl;
    gLog << "   inputfile.rep             Magic Central Control report file." << endl;
    gLog << "   cosy_...rep                COSY Control report file." << endl;
    gLog << "   inputfile.txt             Magic DC currents file." << endl;
    gLog << "   inputfile.rbk             Magic runbook file(s) (wildcards must be escaped: '\\*')" << endl;
    gLog << "   MuxDataCheck...txt        MUX data check file " << endl;
    gLog << "   DominoDataCheck...txt     Domino data check file " << endl;
    gLog << "   CC_YYYY_MM_DD.run         Arehucas run summary file " << endl;
    gLog << "   ouputfile.root            Merpped root file." << endl << endl;
    gLog << " Options:" << endl;
    gLog.Usage();
    gLog << "   --debug[=1]               Enable root debugging" << endl;
    gLog << "   --version, -V             Show startup message with version number" << endl;
    gLog << "   -?, -h, --help            This help" << endl << endl;
    gLog << " File Options:" << endl;
    gLog << "   -c#                       Compression level #=1..9 [default=2]" << endl;
    gLog << "   -f                        Force overwrite of an existing file" << endl;
    gLog << "   -u, --update              Update an existing file."  << endl;
    gLog << "   --uu=, --updatetree=      Update a tree from an existing file." << endl << endl;
    gLog << " Raw Data Options:" << endl;
    gLog << "   -ff                       Force merpp to ignore broken events" << endl;
    gLog << "   --interleave=#            Process only each i-th event [default=1]" << endl;
    gLog << "   --maxevents=#             Process only the first # events [default=0 = all events]" << endl;
    gLog << "   --forcetriggerpattern     Force the setting of trigger patterns for P,C and D files" << endl;
//    gLog << "   --sql=mysql://user:password@url  Insert run into database" << endl << endl;
    gLog << "   --CalibrateDomino[=CalibrationCoeff_YYMMDD_HHMMSS.txt]" << endl;
    gLog << "                             Apply Domino calibration to raw data" << endl;
    gLog << "                             [if no file is specified, use the default one]" << endl;
    gLog << "   --LUT                     Aplay Domino Calibration with the use of LUT" << endl; 
    gLog << "   --spikefinder             Apply an additional, more complicated algorithm" << endl;
    gLog << "                             for finding spikes (useful for MAGIC II data)." << endl << endl;
    gLog << " Report File Options:" << endl;
    gLog << "   --auto-time               Take time automatically from MRawRunHeader" << endl;
    gLog << "                             (overwrites --start= and/or --stop=)" << endl;
    gLog << "   --start=date/time         Start event time" << endl;
    gLog << "   --stop=date/time          Stop  event time" << endl;
    gLog << "   --run=#                   Only data corresponding to this run number" << endl;
    gLog << "                             (from RUN-REPORT)" << endl;
    gLog << "   --runfile=#               Allow only run-control files" << endl;
    gLog << "                             (from .rep header)" << endl;
    gLog << "   --sumfile                 Check for an all night summary file" << endl;
    gLog << "                             (from .rep header)" << endl;
    gLog << "   --allfiles                Don't check file type <default>" << endl << endl;
    gLog << " REMARK: - At the moment you can process a .raw _or_ a .rep file, only!" << endl;
    gLog << "         - 'date/time' has the format 'yyyy-mm-dd/hh:mm:ss.mmm'" << endl << endl;
}

// FIXME: Move to MTime (maybe 'InterpreteCmdline')
MTime AnalyseTime(TString str)
{
    Int_t y=0, ms=0, mon=0, d=0, h=0, m=0, s=0;

    const Int_t n = sscanf(str.Data(), "%d-%d-%d/%d:%d:%d.%d", &y, &mon, &d, &h, &m, &s, &ms);

    if (n<6 || n>7)
    {
        gLog << warn << "'" << str << "' no valid Time... ignored." << endl;
        return MTime();
    }

    MTime t;
    t.Set(y, mon, d, h, m, s, ms);
    return t;
}

void GetTimeFromFile(const char *fname, MTime &start, MTime &stop)
{

    TFile f(fname, "READ");

    TTree *t = (TTree*)f.Get("RunHeaders");
    if (t->GetEntries()!=1)
    {
        gLog << warn << "WARNING - File " << fname << " contains no or more than one entry in RunHeaders... Times unchanged." << endl;
        return;
    }

    MRawRunHeader *h = 0;
    t->SetBranchAddress("MRawRunHeader.", &h);
    t->GetEntry(0);
    if (!h)
    {
        gLog << warn << "WARNING - File " << fname << " did not contain RunHeaders.MRawRunHeader... Times unchanged." << endl;
        return;
    }

    if (!start)
        start = h->GetRunStart();
    if (!stop)
        stop = h->GetRunEnd();
}

void RemoveExistingTree(const char *fname, const char* tname)
{

    gLog << inf << "Will remove tree " << tname << " from file " << fname << endl;

    TFile f(fname, "UPDATE");

    TTree *t = (TTree*)f.Get(tname);
    if (!t)
    {
      gLog << warn << "WARNING - File " << fname << " contains no tree " << tname << " to update " << endl;
      return;
    }
    
    TList *list = f.GetListOfKeys();
    TIter iter(list);
    
    Int_t cnt = 0;
    TKey *o = NULL;
    
    while ((o=((TKey*)iter.Next())))
      {
	if (o->GetName() == (TString)tname)
	  {
	    cnt++;
	    TString kname = MString::Format("%s;%d",tname,o->GetCycle());
	    f.Delete(kname);
	  }
      } 

    gDirectory->GetList()->Remove(t);
    gLog << all << "Found and removed " << cnt << " trees with name " << tname << endl;
}

int main(const int argc, char **argv)
{
    //
    // Evaluate arguments
    //
    MArgs arg(argc, argv);

    if (arg.HasOnly("-V") || arg.HasOnly("--version"))
      {
        StartUpMessage();
        return 0;
      }

    if (arg.HasOnly("-?") || arg.HasOnly("-h") || arg.HasOnly("--help"))
    {
        StartUpMessage();
        Usage();
        return -1;
    }

    gLog.Setup(arg);
    // Setup the global root debugging 
    gDebug = arg.HasOption("--debug=") ? arg.GetIntAndRemove("--debug=") : 0;
    if (gDebug==0 && arg.HasOnlyAndRemove("--debug"))
        gDebug=1;

    StartUpMessage();

    const Int_t  kComprlvl   = arg.GetIntAndRemove("-c", 2);
    const Bool_t kInterleave = arg.GetIntAndRemove("--interleave=", 1);
    const Bool_t kForce      = arg.HasOnlyAndRemove("-f");
    const Bool_t kForceProc  = arg.HasOnlyAndRemove("-ff");
    const Int_t  kRunNumber  = arg.GetIntAndRemove("--run=", -1);
    const Bool_t kAutoTime   = arg.HasOnlyAndRemove("--auto-time");
          Int_t  kRunFile    = arg.GetIntAndRemove("--runfile=", -1);
          Bool_t kUpdate     = arg.HasOnlyAndRemove("--update") || arg.HasOnlyAndRemove("-u");
	  Int_t  kMaxEvents  = arg.GetIntAndRemove("--maxevents=", 0);
    const Bool_t kForceTrig  = arg.HasOnlyAndRemove("--forcetriggerpattern");
    const Bool_t kSpikeFinder= arg.HasOnlyAndRemove("--spikefinder");
    const Bool_t kLUT        = arg.HasOnlyAndRemove("--LUT");

    TString CalibCoeffFileName = "NONE";

    if ( arg.Has("--CalibrateDomino") )
      {
	if (arg.HasOnlyAndRemove("--CalibrateDomino"))
	  CalibCoeffFileName = ""; // The default calibration file as read from the run header will be used in this case!
	else
	  CalibCoeffFileName = arg.GetStringAndRemove("--CalibrateDomino=");
      }

    TString fUpdateTree;
    if (arg.Has("--uu="))
      fUpdateTree = arg.GetStringAndRemove("--uu=");
    if (arg.Has("--updatetree="))
      fUpdateTree = arg.GetStringAndRemove("--updatetree=");
    
    if (!fUpdateTree.IsNull() && kUpdate)
      {
	gLog << err << "Cannot use -u or -update together with option --uu or --updatetree " << endl;
	return -1;
      }

    if (CalibCoeffFileName == "NONE" & kSpikeFinder)
      {
	gLog << err << "Spike finder works only together with Domino Calibration" << endl;
	return -1;
      }

    if (CalibCoeffFileName == "NONE" & kLUT)
      {
	gLog << err << "LUT can be used only with the Domino Calibration" << endl;
	return -1;
      }


    MTime kTimeStart;
    MTime kTimeStop;
    if (arg.HasOption("--star="))
        kTimeStart = AnalyseTime(arg.GetStringAndRemove("--start="));
    if (arg.HasOption("--stop="))
        kTimeStop = AnalyseTime(arg.GetStringAndRemove("--stop="));

//    const TString kSqlDataBase(arg.GetStringAndRemove("--sql="));

    if (arg.HasOnlyAndRemove("--sumfile"))
        kRunFile = 0;

    if (arg.GetNumOptions()>0)
    {
        gLog << warn << "WARNING - Unknown commandline options..." << endl;
        arg.Print("options");
        gLog << endl;
    }

    //
    // check for the right usage of the program
    //
    if (arg.GetNumArguments()<1 || arg.GetNumArguments()>2)
    {
        Usage();
        return -1;
    }

    //
    // This is to make argv[i] more readable inside the code
    //
    TString kNamein  = arg.GetArgumentStr(0);
    TString kNameout = arg.GetArgumentStr(1);

    const Bool_t iscosy   = kNamein.Contains("cosy_") && kNamein.EndsWith(".rep");
    const Bool_t isunformattedtpoint = (kNamein.Contains("starg_") || kNamein.Contains("tpoint_")) && kNamein.EndsWith(".txt");
    const Bool_t istpoint = (isunformattedtpoint || (kNamein.Contains("tpoint_") || (kNamein.Contains("starg_"))) && kNamein.EndsWith(".rep"));
    const Bool_t isreport = !iscosy && !istpoint && kNamein.EndsWith(".rep");
    const Bool_t ismux    = kNamein.Contains("MuxDataCheck_") && kNamein.EndsWith(".txt");
    const Bool_t isdomino = kNamein.Contains("DominoDataCheck_") && kNamein.EndsWith(".txt");
    const Bool_t isdc     = !ismux  && !isunformattedtpoint && kNamein.EndsWith(".txt");
    const Bool_t isrbk    = kNamein.EndsWith(".rbk");
    const Bool_t isrun    = kNamein.EndsWith(".run");
    const Bool_t israwzip = kNamein.EndsWith(".raw.gz");
    const Bool_t israw    = !isreport && !isdc && !israwzip && !isrbk && !iscosy && !ismux && !isdomino && !isrun && !istpoint;

    if (!kNamein.EndsWith(".raw") && israw)
        kNamein += ".raw";

    if (kNameout.IsNull() && israwzip)
      {
        kNameout = kNamein(0, kNamein.Last('.'));
        kNameout = kNameout(0, kNameout.Last('.'));
      }

    if (kNameout.IsNull())
        kNameout = kNamein(0, kNamein.Last('.'));

    if (!kNameout.EndsWith(".root"))
        kNameout += ".root";

    //    gLog << all << "Output file: " << kNameout << endl;

    //
    // Initialize Non-GUI (batch) mode
    //
    gROOT->SetBatch();

    //
    // check whether the given files are OK.
    //
    if (!isrbk && gSystem->AccessPathName(kNamein, kFileExists))
    {
        gLog << err << "Sorry, the input file '" << kNamein << "' doesn't exist." << endl;
        return -1;
    }

    const Bool_t fileexist = !gSystem->AccessPathName(kNameout, kFileExists);
    const Bool_t writeperm = !gSystem->AccessPathName(kNameout, kWritePermission);

    if (fileexist && !writeperm)
    {
        gLog << err << "Sorry, you don't have write permission for '" << kNameout << "'." << endl;
        return -1;
    }

    if (fileexist && !kUpdate && fUpdateTree.IsNull() && !kForce)
    {
        gLog << err << "Sorry, file '" << kNameout << "' already existing." << endl;
        return -1;
    }

    if (!fileexist && (kUpdate || fUpdateTree.IsNull()))
    {
        gLog << warn << "File '" << kNameout << "' doesn't yet exist." << endl;
        kUpdate=kFALSE;
    }

    //
    // Evaluate possible start-/stop-time
    //
    if (kAutoTime && (kUpdate || !fUpdateTree.IsNull()) && (isreport || isdc))
      GetTimeFromFile(kNameout, kTimeStart, kTimeStop);

    if (kTimeStart)
      gLog << inf << "Start Time: " << kTimeStart << endl;
    if (kTimeStop)
      gLog << inf << "Stop  Time: " << kTimeStop << endl;

    //
    // Ignore TObject Streamer (bits, uniqueid) for MArray and MParContainer
    //
    MArray::Class()->IgnoreTObjectStreamer();
    MParContainer::Class()->IgnoreTObjectStreamer();

    if (!fUpdateTree.IsNull())
      RemoveExistingTree(kNameout, fUpdateTree);
	
    //
    // create a (empty) list of parameters which can be used by the tasks
    // and an (empty) list of tasks which should be executed
    //
    MParList plist;

    MTaskList tasks;
    tasks.SetOwner();
    plist.AddToList(&tasks);

    //
    // ---- The following is only necessary to supress some output ----
    /*
    MRawRunHeader runheader;
    plist.AddToList(&runheader);

    MRawEvtHeader evtheader;
    plist.AddToList(&evtheader);

    MRawEvtData evtdata;
    plist.AddToList(&evtdata);

    MRawCrateArray cratearray;
    plist.AddToList(&cratearray);

    MTime evttime;
    plist.AddToList(&evttime);
    */

    //
    // create the tasks which should be executed and add them to the list
    // in the case you don't need parameter containers, all of them can
    // be created by MRawFileRead::PreProcess
    //
    MTask   *read   = 0;
    MFilter *filter = 0;
    MTask   *write  = 0;

    const TString option((kUpdate || !fUpdateTree.IsNull()) ? "UPDATE" : "RECREATE");
    if (isrbk)
      {
	MRunbookFileRead *r = new MRunbookFileRead(kNamein);
        MWriteRootFile   *w = new MWriteRootFile  (kNameout, option, "Magic root-file", kComprlvl);
	w->AddContainer("MRunbook","Runbook");
	read  = r;
	write = w;
      }
    else if (ismux)
      {
	MMUXFileRead     *r = new MMUXFileRead  (kNamein);
        MWriteRootFile   *w = new MWriteRootFile(kNameout, option, "Magic root-file", kComprlvl);
	w->AddContainer("MTimeMUX",  "MUX");
	w->AddContainer("MReportMUX","MUX");
	read  = r;
	write = w;
      }
    else if (isdomino)
      {
	MMUXFileRead     *r = new MMUXFileRead  (kNamein);
        MWriteRootFile   *w = new MWriteRootFile(kNameout, option, "Magic root-file", kComprlvl);
	w->AddContainer("MTimeDomino",  "MUX");
	w->AddContainer("MReportDomino","MUX");
	read  = r;
	write = w;
      }
    else if (isrun)
      {
	MCCrunFileRead   *r = new MCCrunFileRead(kNamein);
        MWriteRootFile   *w = new MWriteRootFile(kNameout, option, "Magic root-file", kComprlvl);
	w->AddContainer("MTimeCCrun",  "RUN");
	w->AddContainer("MReportCCrun","RUN");
	read  = r;
	write = w;
      }
    else if (isreport || isdc || iscosy || istpoint)
      {
        MWriteRootFile *w = new MWriteRootFile(kNameout, option, "Magic root-file", kComprlvl);
        if (isdc)
	  {
            w->AddContainer("MTimeCurrents",      "Currents");
            w->AddContainer("MCameraDC",          "Currents");
            w->AddContainer("MReportCurrents",    "Currents");
	  }
        else if (iscosy)
	  {
            w->AddContainer("MTimeSE",            "SE");
            w->AddContainer("MReportSE",          "SE");
            w->AddContainer("MTimeRE",            "RE");
            w->AddContainer("MReportRE",          "RE");
	  }
	else if (istpoint)
	  {
	    w->AddContainer("MTimeTP",            "TP");
	    w->AddContainer("MReportTP",          "TP");
	  }
	else if (!fUpdateTree.IsNull())
	  {
	    w->AddContainer(MString::Format("MReport%s",fUpdateTree.Data()),fUpdateTree);
            w->AddContainer(MString::Format("MTime%s",  fUpdateTree.Data()),fUpdateTree);
	    if (fUpdateTree.Contains("Camera"))
	      {
		w->AddContainer("MCameraAUX",         "Camera");
		w->AddContainer("MCameraCalibration", "Camera");
		w->AddContainer("MCameraCooling",     "Camera");
		w->AddContainer("MCameraHV",          "Camera");
		w->AddContainer("MCameraDC",          "Camera");
		w->AddContainer("MCameraLV",          "Camera");
		w->AddContainer("MCameraLids",        "Camera");
		w->AddContainer("MCameraActiveLoad",  "Camera");
		
	if  (kNamein.Contains("M2")) //update camere za M2
		{
			 w->AddContainer("MCameraBias",         "Camera");
			// w->AddContainer("MCameraAtt",          "Camera");
		        w->AddContainer("MCameraPixTemp",      "Camera");
		        w->AddContainer("MCameraClusterTemp",  "Camera");
			 w->AddContainer("MCameraPD",           "Camera");
			
		}		
		
 		w->AddContainer("MCameraCentralPix",  "Camera", kFALSE);
	      }
	    if (fUpdateTree.Contains("Trigger"))
	      {
		w->AddContainer("MTriggerBit",        "Trigger"); 	
		w->AddContainer("MTriggerIPR",        "Trigger");		
		w->AddContainer("MTriggerCell",       "Trigger");
		w->AddContainer("MTriggerPrescFact",  "Trigger");
		w->AddContainer("MTriggerLiveTime",   "Trigger");
		
		  }
	    if (fUpdateTree.Contains("DT"))
	      {


              if  (kNamein.Contains("M2")) { w->AddContainer("MTriggerIPR2",           "Trigger"); }  // ipr se kod M2 nalazi u DT reportu, a spremamo ga u Trigger ROOT granu MTriggerIPR2
		w->AddContainer("MCameraTH",          "DT", kFALSE);
		w->AddContainer("MCameraTD",          "DT", kFALSE);
		w->AddContainer("MCameraRecTemp",     "DT", kFALSE);
	      
		
		  
		  }
	  }
	else
	  {
 	    w->AddContainer("MReportCamera",      "Camera");
             w->AddContainer("MTimeCamera",        "Camera");
            w->AddContainer("MCameraAUX",         "Camera");
             w->AddContainer("MCameraCalibration", "Camera");
             w->AddContainer("MCameraCooling",     "Camera");
             w->AddContainer("MCameraHV",          "Camera");
             w->AddContainer("MCameraDC",          "Camera");

		if  (kNamein.Contains("M2"))
		{
	            w->AddContainer("MCameraBias",         "Camera");
		  // w->AddContainer("MCameraAtt",          "Camera");
		     w->AddContainer("MCameraPixTemp",      "Camera");
		     w->AddContainer("MCameraClusterTemp",  "Camera");
		     w->AddContainer("MCameraPD",           "Camera");
		     w->AddContainer("MTriggerIPR2",        "Trigger");
		}		
             w->AddContainer("MCameraLV",          "Camera");
             w->AddContainer("MCameraLids",        "Camera");
 	    w->AddContainer("MCameraActiveLoad",  "Camera");
 	    w->AddContainer("MCameraCentralPix",  "Camera", kFALSE);
             w->AddContainer("MReportTrigger",     "Trigger");
             w->AddContainer("MTimeTrigger",       "Trigger");
             w->AddContainer("MTriggerBit",        "Trigger");
             w->AddContainer("MTriggerIPR",        "Trigger");
             w->AddContainer("MTriggerCell",       "Trigger");
            w->AddContainer("MTriggerPrescFact",  "Trigger");
            w->AddContainer("MTriggerLiveTime",   "Trigger");
             w->AddContainer("MReportDrive",       "Drive");
             w->AddContainer("MTimeDrive",         "Drive");
            w->AddContainer("MReportCC",          "CC");
 	    w->AddContainer("MTimeCC",            "CC");
             w->AddContainer("MReportStarguider",  "Starguider");
             w->AddContainer("MTimeStarguider",    "Starguider");
             w->AddContainer("MReportDT",          "DT", kFALSE);
             w->AddContainer("MTimeDT",            "DT", kFALSE);
	    w->AddContainer("MCameraTH",          "DT", kFALSE);
 	    w->AddContainer("MCameraTD",          "DT", kFALSE);
 	    w->AddContainer("MCameraRecTemp",     "DT", kFALSE);
             w->AddContainer("MReportPyrometer",   "Pyrometer");
             w->AddContainer("MTimePyrometer",     "Pyrometer");
	    w->AddContainer("MReportDAQ",         "DAQ");
 	    w->AddContainer("MTimeDAQ",           "DAQ");
 	    w->AddContainer("MReportAMC",         "AMC");
	    w->AddContainer("MTimeAMC",           "AMC");
 	    w->AddContainer("MReportSUMO",        "SUMO"  , kFALSE);
 	    w->AddContainer("MTimeSUMO",          "SUMO"  , kFALSE);
//	    w->AddContainer("MReportPulsar",      "Pulsar", kFALSE);
// 	    w->AddContainer("MTimePulsar",        "Pulsar", kFALSE);
	  }
        write = w;

	MReportFileRead *r = NULL;

        if (isdc)
	  {
	    r = new MReportFileReadCC(kNamein);
	    r->SetTimeStart(kTimeStart);
	    r->SetTimeStop (kTimeStop);
            r->SetHasNoHeader();
            r->AddToList("MReportCurrents");
	  }
        else if (iscosy)
	  {
	    r = new MReportFileReadCosy(kNamein);
	    r->SetTimeStart(kTimeStart);
	    r->SetTimeStop (kTimeStop);
	    r->AddToList("MReportSE");
	    r->AddToList("MReportRE");
	  }
	else if (istpoint)
	  {
	    if (isunformattedtpoint)
	      {
		TString formattedTpointFile(kNamein);
		formattedTpointFile.ReplaceAll(".txt",".rep");
		// execute a shell script that formats
		// the raw tpoint file into a report file
		gSystem->Exec(Form("$MARSSYS/mreport/scripts/formatTpointFile.sh %s %s",
				   kNamein.Data(), formattedTpointFile.Data()));
		r = new MReportFileReadTpoint(formattedTpointFile);
	      }
            else
	      {
		r = new MReportFileReadTpoint(kNamein);
	      }
	    r->SetTimeStart(kTimeStart);
	    r->SetTimeStop (kTimeStop);
	    r->AddToList("MReportTP");
	  }
	else if (!fUpdateTree.IsNull())
	  {
            r = new MReportFileReadCC(kNamein);
            ((MReportFileReadCC*)r)->SetRunNumber(kRunFile);
            r->AddToList(MString::Format("MReport%s",fUpdateTree.Data()));
	  }
	else
	  {
            r = new MReportFileReadCC(kNamein);
            ((MReportFileReadCC*)r)->SetRunNumber(kRunFile);
             r->AddToList("MReportCC");
             r->AddToList("MReportDAQ");
             r->AddToList("MReportDrive");
             r->AddToList("MReportCamera");
             r->AddToList("MReportTrigger");
             r->AddToList("MReportStarguider"); 
             r->AddToList("MReportPyrometer");
             r->AddToList("MReportAMC");
             r->AddToList("MReportSUMO");
             r->AddToList("MReportDT");
 //             r->AddToList("MReportPulsar");
            if (kRunNumber>0)
            {
                r->AddToList("MReportRun");
                filter = new MFDataMember("MReportRun.fRunNumber", '=', kRunNumber);
                w->SetFilter(filter);
            }
	  }
        read = r;
      }
    else
      {
        read  = new MRawFileRead(kNamein);
	if (israwzip)
	  ((MRawFileRead*)read)->SetZipped();

	// Set coefficients file for merpping the data:
	((MRawFileRead*)read)->SetCalibCoeffFileName(CalibCoeffFileName.Data());

	((MRawFileRead*)read)->SetSpikeFinder(kSpikeFinder);

	((MRawFileRead*)read)->SetLUT(kLUT);
  gLog << warn << "Setting by force trigger pattern to " << kLUT << endl;


        static_cast<MRawFileRead*>(read)->SetInterleave(kInterleave);
        static_cast<MRawFileRead*>(read)->SetForceMode(kForceProc);
        write = new MRawFileWrite(kNameout, option, "Magic root-file", kComprlvl);
	if (kForceTrig)
	  {
	    UInt_t trigpat;
	    if (kNamein.Contains("_P_"))
	      trigpat = 0xf7f7;
	    else if (kNamein.Contains("_C_"))
	      trigpat = 0xfdfd;
	    else
	      trigpat = 0xfefe;
	    gLog << warn << "Setting by force trigger pattern to " << hex << trigpat << endl;
	    static_cast<MRawFileWrite*>(write)->ForceTriggerPattern(trigpat);
	  }


      }

    tasks.AddToList(read);
    if (filter)
      tasks.AddToList(filter);

    tasks.AddToList(write);

    //
    // create the looping object and tell it about the parameters to use
    // and the tasks to execute
    //
    MEvtLoop magic;
    magic.SetParList(&plist);

    //
    // Start the eventloop which reads the raw file (MRawFileRead) and
    // write all the information into a root file (MRawFileWrite)
    //
    // between reading and writing we can do, transformations, checks, etc.
    // (I'm think of a task like MRawDataCheck)
    //
    if (!magic.Eventloop(kMaxEvents))
    {
        gLog << err << "ERROR: Merging and preprocessing failed!" << endl;
        return -1;
    }

    tasks.PrintStatistics();

    gLog << all << "Merpp finished successfull!" << endl;
    return 0;
}

-----------------------------13298103518283369281355689878
Content-Disposition: form-data; name="Submit"

UPLOAD file
-----------------------------13298103518283369281355689878
Content-Disposition: form-data; name="user_search"


-----------------------------13298103518283369281355689878
Content-Disposition: form-data; name="user_add"


-----------------------------13298103518283369281355689878
Content-Disposition: form-data; name="user_modify"


-----------------------------13298103518283369281355689878
Content-Disposition: form-data; name="user_delete"


-----------------------------13298103518283369281355689878
Content-Disposition: form-data; name="user"


-----------------------------13298103518283369281355689878
Content-Disposition: form-data; name="user_trans"


-----------------------------13298103518283369281355689878
Content-Disposition: form-data; name="authenticate"

yes
-----------------------------13298103518283369281355689878
Content-Disposition: form-data; name="message"


-----------------------------13298103518283369281355689878
Content-Disposition: form-data; name="file_name_convention"

Zy009876.jpg