/* ======================================================================== *\ ! ! * ! * 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): Thomas Bretz, 11/2003 ! ! Copyright: MAGIC Software Development, 2000-2003 ! ! \* ======================================================================== */ ////////////////////////////////////////////////////////////////////////////// // // MReportFileRead // // Task to read the central control report file. For more information see // the base class of all reports MReport. // // To add a report which should be read use AddToList. // // eg. AddToList("Drive") will assume the existance of a class called // MReportDrive. It will create such an object automatically. It will // send all lines starting with 'MReportDrive::fIndetifier-REPORT' // to this class. // ////////////////////////////////////////////////////////////////////////////// #include "MReportFileRead.h" #include #include #include #include "MLog.h" #include "MLogManip.h" #include "MParList.h" #include "MReportHelp.h" ClassImp(MReportFileRead); using namespace std; const TString MReportFileRead::gsReportHeader ="[CC Report File]"; const TString MReportFileRead::gsVersionPrefix="Arehucas Version Number"; // -------------------------------------------------------------------------- // // Default constructor. It tries to open the given file and creates a // THashTable which allows faster access to the MReport* objects. // MReportFileRead::MReportFileRead(const char *fname, const char *name, const char *title) : fFileName(fname), fIn(NULL) { fName = name ? name : "MReportFileRead"; fTitle = title ? title : "Read task to read Central Control report files"; fIn = new ifstream; fList = new THashTable(1,1); fList->SetOwner(); } // -------------------------------------------------------------------------- // // Destructor. Delete input stream and hash table. // MReportFileRead::~MReportFileRead() { delete fIn; delete fList; } // -------------------------------------------------------------------------- // // Wrapper. Returns the MReportHelp with the given identifier from the // hash table. // MReportHelp *MReportFileRead::GetReportHelp(const TString &str) const { return (MReportHelp*)fList->FindObject(str); } // -------------------------------------------------------------------------- // // Wrapper. Returns the MReport stored in the given MReportHelp // MReport *MReportFileRead::GetReport(MReportHelp *help) const { return help ? help->GetReport() : 0; } // -------------------------------------------------------------------------- // // Wrapper. Returns the MReport stored in the MReportHelp given by its // identifier. // MReport *MReportFileRead::GetReport(const TString &str) const { return GetReport(GetReportHelp(str)); } // -------------------------------------------------------------------------- // // Add a new MReport* to the list (eg 'Drive' will add MReportDrive) // For convinience the object is created as a MReportHelp object. // Bool_t MReportFileRead::AddToList(const char *name) const { MReportHelp *help = new MReportHelp(name, fLog); if (!help->GetReport()) return kFALSE; if (GetReport(help->GetName())) { *fLog << warn << "WARNING - Report with Identifier '"; *fLog << help->GetName() << "' already added to the list... "; *fLog << "ignored." << endl; delete help; return kFALSE; } fList->Add(help); return kTRUE; } // -------------------------------------------------------------------------- // // Check whether the file header corresponds to a central control file // header and check for the existance of a correct version number. // The version number may later be used to be able to read different // file versions // Int_t MReportFileRead::CheckFileHeader() const { Int_t line = 0; TString str; str.ReadLine(*fIn); // Read to EOF or newline if (str != gsReportHeader) { *fLog << err << "ERROR - First line doesn't match '" << gsReportHeader <<"' "; *fLog << "in file '" << fFileName << "'"<" << endl; return line; } // -------------------------------------------------------------------------- // // Call SetupReading for all MReportHelp objects scheduled. // Try to open the file and check the file header. // Int_t MReportFileRead::PreProcess(MParList *pList) { //MTime *time = (MTime*)pList->FindCreateObj("MTime"); //if (!time) // return kFALSE; fNumLine = 0; TIter Next(fList); MReportHelp *help=0; while ((help=(MReportHelp*)Next())) if (!help->SetupReading(*pList)) return kFALSE; fList->ForEach(MReportHelp, AddToList)(*pList); // // open the input stream // first of all check if opening the file in the constructor was // successfull // fIn->open(fFileName); if (!(*fIn)) { *fLog << err << "Error: Cannot open file '" << fFileName << "'" << endl; return kFALSE; } if (TestBit(kHasNoHeader)) return kTRUE; const Int_t n = CheckFileHeader(); fNumLine += n; return n==2; } // -------------------------------------------------------------------------- // // Read the file line by line as long as a matching MReport* class is found. // In this case call its interpreter (Interprete()) and remove the identifier // first (XYZ-REPORT) // Int_t MReportFileRead::Process() { TString str; MReportHelp *rep=NULL; while (!GetReport(rep)) { str.ReadLine(*fIn); if (!*fIn) { *fLog << dbg << "EOF detected." << endl; return kFALSE; } fNumLine++; const Int_t pos = str.First(' '); if (pos<=0) continue; rep = GetReportHelp(str(0,pos)); if (GetReport(rep)) str.Remove(0, pos); } const Int_t rc = rep->Interprete(str, fStart, fStop); switch (rc) { case kFALSE: *fLog << err << "ERROR - Interpretation of '" << rep->GetName() << "' failed (Line #" << fNumLine << ")... abort." << endl; break; case kCONTINUE: *fLog << warn << "WARNING - Interpretation of '" << rep->GetName() << "' failed (Line #" << fNumLine << ")... skipped." << endl; break; case -1: // This is the special case: out of time limit return kCONTINUE; } return rc; } // -------------------------------------------------------------------------- // // Close the file and print some execution statistics // Int_t MReportFileRead::PostProcess() { fIn->close(); if (!GetNumExecutions()) return kTRUE; *fLog << inf << endl; *fLog << GetDescriptor() << " statistics:" << endl; *fLog << dec << setfill(' '); TIter Next(fList); MReportHelp *rep=0; while ((rep=(MReportHelp*)Next())) { *fLog << inf; *fLog << " " << setw(7) << rep->GetNumReports() << " ("; *fLog << setw(3) << (int)(100.*rep->GetNumReports()/GetNumExecutions()); *fLog << "%): " << rep->GetName() << endl; if (rep->GetNumSkipped()==0) continue; *fLog << warn; *fLog << " " << setw(7) << rep->GetNumSkipped() << " ("; *fLog << setw(3) << (int)(100.*rep->GetNumSkipped()/GetNumExecutions()); *fLog << "%): " << rep->GetName() << " skipped!" << endl; } return kTRUE; }