#include #include #include "MParList.h" #include "MTaskList.h" #include "MEvtLoop.h" #include "MRawFileRead.h" #include "MReportFileReadCC.h" #include "MWriteRootFile.h" #include "MLog.h" #include "MLogManip.h" #include "MArgs.h" #include "MTime.h" #include "MArray.h" #include "MRawRunHeader.h" #include "MFDataPhrase.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 with ROOT v" << ROOT_RELEASE << " on <" << __DATE__ << ">" << 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.gz],[.txt]] [outputfile[.root]]" << endl << endl; gLog << " Arguments:" << endl; gLog << " inputfile.raw[.gz] Magic DAQ binary file." << endl; gLog << " inputfile.rep Magic Central Control report file." << endl; gLog << " inputfile.txt Magic DC currents file." << endl; gLog << " ouputfile.root Merpped root file." << endl << endl; gLog << " Options:" << endl; gLog.Usage(); 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 << " --only=Name Read only reports described by MReportName. See the" << endl; gLog << " mreport-directory for available classes." << endl << endl; gLog << " Raw Data Options:" << endl; gLog << " -ff Force merpp to ignore broken events and don't stop" << endl; gLog << " --interleave=# Process only each i-th event [default=1]" << endl << endl; // gLog << " --sql=mysql://user:password@url Insert run into database" << endl << endl; gLog << " Report File Options:" << endl; gLog << " --auto-time-start Take time automatically from MRawRunHeader" << endl; gLog << " (overwrites --start=)" << endl; gLog << " --auto-time-stop Take time automatically from MRawRunHeader" << endl; gLog << " (overwrites --stop=)" << endl; gLog << " --auto-time Abbrev. for --auto-time-start and auto-time-stop" << endl; gLog << " --start=date/time Start event time" << endl; gLog << " --stop=date/time Stop event time" << endl; gLog << " --rep-run=# Only data corresponding to this run number as" << endl; gLog << " taken from the RUN-REPORT is extracted" << endl; gLog << " --rep-file=# Only data corresponding to this file number as" << endl; gLog << " taken from the RUN-REPORT is extracted" << endl; gLog << " --header-run=# Allow only run-control .rep-files with this" << endl; gLog << " run number in there header" << endl; gLog << " --header-file=# Allow only run-control .rep-files with this" << endl; gLog << " file number in there header" << endl; gLog << " --telescope=# Allow only run-control .rep-files with this" << endl; gLog << " telescope number in there header" << endl; gLog << " --sumfile Check for an all night summary file" << endl; gLog << " (from .rep header)" << endl; gLog << " --allfiles Don't check file type " << endl << endl; gLog << " Compatibility (deprecated):" << endl; gLog << " --run=# See --rep-run (overwritten by --rep-run)" << endl; gLog << " --runfile=# See --header-run (overwritten by --header-run)" << 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) *start = h->GetRunStart(); if (stop && !*stop) *stop = h->GetRunEnd(); } void Add(MReportFileReadCC *r, const TString &rep, const TString &only) { if (!only.IsNull() && rep!=only) return; r->AddToList(Form("MReport%s", rep.Data())); } int main(const int argc, char **argv) { if (!MARS::CheckRootVer()) return 0xff; MLog::RedirectErrorHandler(MLog::kColor); // // Evaluate arguments // MArgs arg(argc, argv); gLog.Setup(arg); StartUpMessage(); if (arg.HasOnly("-V") || arg.HasOnly("--version")) return 0; if (arg.HasOnly("-?") || arg.HasOnly("-h") || arg.HasOnly("--help")) { Usage(); return 2; } 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 run = arg.GetIntAndRemove("--run=", -1); const Int_t kRunNumber = arg.GetIntAndRemove("--rep-run=", run); const Int_t kFileNumber = arg.GetIntAndRemove("--rep-file=", -1); const Bool_t kAutoTime = arg.HasOnlyAndRemove("--auto-time"); const Bool_t kAutoTimeStart = arg.HasOnlyAndRemove("--auto-time-start") || kAutoTime; const Bool_t kAutoTimeStop = arg.HasOnlyAndRemove("--auto-time-stop") || kAutoTime; const Int_t runfile = arg.GetIntAndRemove("--runfile=", -1); Int_t kHeaderRun = arg.GetIntAndRemove("--header-run=", runfile); const Int_t kHeaderFile = arg.GetIntAndRemove("--header-file=", -1); const Int_t kTelescope = arg.GetIntAndRemove("--telescope=", -1); Bool_t kUpdate = arg.HasOnlyAndRemove("--update") || arg.HasOnlyAndRemove("-u"); const TString kOnly = arg.GetStringAndRemove("--only=", ""); 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")) kHeaderRun = 0; if (arg.GetNumOptions()>0) { gLog << warn << "WARNING - Unknown commandline options..." << endl; arg.Print("options"); gLog << endl; return 2; } // // check for the right usage of the program // if (arg.GetNumArguments()<1 || arg.GetNumArguments()>2) { Usage(); return 2; } // // This is to make argv[i] more readable insidethe code // TString kNamein = arg.GetArgumentStr(0); TString kNameout = arg.GetArgumentStr(1); const Bool_t isreport = kNamein.EndsWith(".rep"); const Bool_t isdc = kNamein.EndsWith(".txt"); const Bool_t israw = !isreport && !isdc; if (!kNamein.EndsWith(".raw") && !kNamein.EndsWith(".raw.gz") && israw) kNamein += ".raw.gz"; if (kNameout.IsNull()) kNameout = kNamein(0, kNamein.Last('.')); if (!kNameout.EndsWith(".root")) kNameout += ".root"; // if (!kSqlDataBase.IsNull() && !israw) // gLog << warn << "WARNING - Option '--sql=' only valid for raw-files... ignored." << endl; // // Initialize Non-GUI (batch) mode // gROOT->SetBatch(); // // check whether the given files are OK. // if (gSystem->AccessPathName(kNamein, kFileExists)) { gLog << err << "Sorry, the input file '" << kNamein << "' doesn't exist." << endl; return 2; } 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 2; } if (fileexist && !kUpdate && !kForce) { gLog << err << "Sorry, file '" << kNameout << "' already existing." << endl; return 2; } if (!fileexist && kUpdate) { gLog << warn << "File '" << kNameout << "' doesn't yet exist." << endl; kUpdate=kFALSE; } // // Evaluate possible start-/stop-time // if ((kAutoTimeStart || kAutoTimeStop) && kUpdate && (isreport || isdc)) GetTimeFromFile(kNameout, kAutoTimeStart?&kTimeStart:0, kAutoTimeStop?&kTimeStop:0); 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(); // // 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 // const TString option(kUpdate ? "UPDATE" : "RECREATE"); MTask *read = 0; MFilter *filter = 0; MWriteRootFile *write = new MWriteRootFile(kNameout, option, "Magic root-file", kComprlvl); if (isreport || isdc) { if (isdc) { write->AddContainer("MTimeCurrents", "Currents"); write->AddContainer("MCameraDC", "Currents"); write->AddContainer("MReportCurrents", "Currents"); } else { const Bool_t required = kOnly.IsNull(); write->AddContainer("MReportCamera", "Camera", required); write->AddContainer("MTimeCamera", "Camera", required); write->AddContainer("MCameraAUX", "Camera", required); write->AddContainer("MCameraCalibration", "Camera", required); write->AddContainer("MCameraCooling", "Camera", required); write->AddContainer("MCameraActiveLoad", "Camera", required); write->AddContainer("MCameraHV", "Camera", required); write->AddContainer("MCameraLV", "Camera", required); write->AddContainer("MCameraLids", "Camera", required); write->AddContainer("MReportTrigger", "Trigger", required); write->AddContainer("MTimeTrigger", "Trigger", required); write->AddContainer("MTriggerBit", "Trigger", required); write->AddContainer("MTriggerIPR", "Trigger", required); write->AddContainer("MTriggerCell", "Trigger", required); write->AddContainer("MTriggerPrescFact", "Trigger", required); write->AddContainer("MTriggerLiveTime", "Trigger", required); write->AddContainer("MReportDrive", "Drive", required); write->AddContainer("MTimeDrive", "Drive", required); write->AddContainer("MCameraTH", "Rec", required); write->AddContainer("MCameraTD", "Rec", required); write->AddContainer("MCameraRecTemp", "Rec", required); write->AddContainer("MReportRec", "Rec", required); write->AddContainer("MTimeRec", "Rec", required); write->AddContainer("MReportCC", "CC", required); write->AddContainer("MTimeCC", "CC", required); write->AddContainer("MReportStarguider", "Starguider", required); write->AddContainer("MTimeStarguider", "Starguider", required); write->AddContainer("MReportPyrometer", "Pyrometer", required); write->AddContainer("MTimePyrometer", "Pyrometer", required); // write->AddContainer("MReportDAQ", "DAQ"); // write->AddContainer("MTimeDAQ", "DAQ"); } MReportFileReadCC *r = new MReportFileReadCC(kNamein); r->SetTimeStart(kTimeStart); r->SetTimeStop(kTimeStop); if (isdc) { r->SetHasNoHeader(); r->AddToList("MReportCurrents"); } else { r->SetTelescope(kTelescope); r->SetRunNumber(kHeaderRun); r->SetFileNumber(kHeaderFile); Add(r, "CC", kOnly); Add(r, "Rec", kOnly); Add(r, "Drive", kOnly); Add(r, "Camera", kOnly); Add(r, "Trigger", kOnly); Add(r, "Starguider", kOnly); Add(r, "Pyrometer", kOnly); // Add(r, "DAQ", kUpdateOnly); if (kRunNumber>0) { const TString f1 = kRunNumber>0 ? Form("MReportRun.fRunNumber==%d", kRunNumber) : ""; const TString f2 = kFileNumber>0 ? Form("MReportRun.fFileNumber==%d", kFileNumber) : ""; const TString f = Form(kRunNumber>0 && kFileNumber>0 ? "%s && %s" : "%s%s", f1.Data(), f2.Data()); r->AddToList("MReportRun"); filter = new MFDataPhrase(f.Data()); write->SetFilter(filter); } } read = r; } else { read = new MRawFileRead(kNamein); static_cast(read)->SetInterleave(kInterleave); static_cast(read)->SetForceMode(kForceProc); write->AddContainer("MRawRunHeader", "RunHeader"); write->AddContainer("MTime", "Events"); write->AddContainer("MRawEvtHeader", "Events"); write->AddContainer("MRawEvtData", "Events"); write->AddContainer("MRawEvtData2", "Events"); write->AddContainer("MRawCrateArray", "Events"); } tasks.AddToList(read); if (filter) tasks.AddToList(filter); /* if (israw && !kSqlDataBase.IsNull()) { MSqlInsertRun *ins = new MSqlInsertRun(kSqlDataBase); ins->SetUpdate(); tasks.AddToList(ins); }*/ 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()) { gLog << err << "ERROR: Merging and preprocessing failed!" << endl; return 2; } tasks.PrintStatistics(); gLog << all << "Merpp finished successfull!" << endl; return 0; }