source: trunk/MagicSoft/Mars/mreport/MReportFileRead.cc@ 2712

Last change on this file since 2712 was 2711, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 9.7 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 11/2003 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2003
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MReportFileRead
28//
29// Task to read the central control report file. For more information see
30// the base class of all reports MReport.
31//
32// To add a report which should be read use AddToList.
33//
34// eg. AddToList("Drive") will assume the existance of a class called
35// MReportDrive. It will create such an object automatically. It will
36// send all lines starting with 'MReportDrive::fIndetifier-REPORT'
37// to this class.
38//
39//////////////////////////////////////////////////////////////////////////////
40#include "MReportFileRead.h"
41
42#include <fstream>
43
44#include <TClass.h>
45#include <TRegexp.h>
46#include <THashTable.h>
47
48#include "MLog.h"
49#include "MLogManip.h"
50
51#include "MReport.h"
52#include "MParList.h"
53
54ClassImp(MReportFileRead);
55
56using namespace std;
57
58const TString MReportFileRead::gsReportHeader ="[CC Report File]";
59const TString MReportFileRead::gsVersionPrefix="Arehucas Version Number";
60
61class MReportHelp : public TObject
62{
63private:
64 MReport *fReport;
65 ULong_t fNumReports;
66
67public:
68 MReportHelp(const char *name, MLog *fLog) : fReport(NULL), fNumReports(0)
69 {
70 TClass *cls = gROOT->GetClass(name);
71 Int_t rc = 0;
72 if (!cls)
73 rc =1;
74 else
75 {
76 if (!cls->Property())
77 rc = 5;
78 if (!cls->Size())
79 rc = 4;
80 if (!cls->IsLoaded())
81 rc = 3;
82 if (!cls->HasDefaultConstructor())
83 rc = 2;
84 }
85
86 if (rc)
87 {
88 *fLog << err << dbginf << "Cannot create new instance of class '" << name << "': ";
89 switch (rc)
90 {
91 case 1:
92 *fLog << "gROOT->GetClass() returned NULL." << endl;
93 return;
94 case 2:
95 *fLog << "no default constructor." << endl;
96 return;
97 case 3:
98 *fLog << "not loaded." << endl;
99 return;
100 case 4:
101 *fLog << "zero size." << endl;
102 return;
103 case 5:
104 *fLog << "no property." << endl;
105 return;
106 }
107 }
108
109 //
110 // create the parameter container of the the given class type
111 //
112 fReport = (MReport*)cls->New();
113 }
114 ~MReportHelp() { if (fReport) delete fReport; }
115
116 const char *GetName() const { return fReport->GetIdentifier(); }
117 ULong_t GetNumReports() const { return fNumReports; }
118 ULong_t Hash() const { return fReport->GetIdentifier().Hash(); }
119 MReport *GetReport() { return fReport; }
120 //void SetTime(MTime *t) { fReport->SetTime(t); }
121 Int_t Interprete(TString &str, const MTime &start, const MTime &stop)
122 {
123 const Int_t rc = fReport->Interprete(str, start, stop);
124
125 if (rc==kFALSE)
126 return kFALSE;
127
128 fNumReports++;
129 return rc;
130 }
131 Bool_t SetupReading(MParList &plist) { return fReport->SetupReading(plist); }
132 void AddToList(MParList &plist) { plist.AddToList(fReport); }
133};
134
135// --------------------------------------------------------------------------
136//
137// Default constructor. It tries to open the given file and creates a
138// THashTable which allows faster access to the MReport* objects.
139//
140MReportFileRead::MReportFileRead(const char *fname, const char *name, const char *title)
141 : fFileName(fname), fIn(NULL)
142{
143 fName = name ? name : "MReportFileRead";
144 fTitle = title ? title : "Read task to read Central Control report files";
145
146 fIn = new ifstream;
147 fList = new THashTable(1,1);
148 fList->SetOwner();
149}
150
151// --------------------------------------------------------------------------
152//
153// Destructor. Delete input stream and hash table.
154//
155MReportFileRead::~MReportFileRead()
156{
157 delete fIn;
158 delete fList;
159}
160
161MReportHelp *MReportFileRead::GetReportHelp(const TString &str) const
162{
163 return (MReportHelp*)fList->FindObject(str);
164}
165
166MReport *MReportFileRead::GetReport(MReportHelp *help) const
167{
168 return help ? help->GetReport() : 0;
169}
170
171MReport *MReportFileRead::GetReport(const TString &str) const
172{
173 return GetReport(GetReportHelp(str));
174}
175
176// --------------------------------------------------------------------------
177//
178// Add a new MReport* to the list (eg 'Drive' will add MReportDrive)
179// For convinience the object is created as a MReportHelp object.
180//
181Bool_t MReportFileRead::AddToList(const char *name) const
182{
183 MReportHelp *help = new MReportHelp(name, fLog);
184
185 MReport *rep = NULL;
186 if (!(rep=help->GetReport()))
187 return kFALSE;
188
189 if (GetReport(rep->GetIdentifier()))
190 {
191 *fLog << warn << "WARNING - Report with Identifier '";
192 *fLog << rep->GetIdentifier() << "' already added to the list... ";
193 *fLog << "ignored." << endl;
194 delete help;
195 return kFALSE;
196 }
197
198 fList->Add(help);
199 return kTRUE;
200}
201
202// --------------------------------------------------------------------------
203//
204// Check whether the file header corresponds to a central control file
205// header and check for the existance of a correct version number.
206// The version number may later be used to be able to read different
207// file versions
208//
209Int_t MReportFileRead::CheckFileHeader() const
210{
211 Int_t line = 0;
212
213 TString str;
214 str.ReadLine(*fIn); // Read to EOF or newline
215 if (str != gsReportHeader)
216 {
217 *fLog << err << "ERROR - First line doesn't match '" << gsReportHeader <<"' ";
218 *fLog << "in file '" << fFileName << "'"<<endl;
219 return line;
220 }
221 line++;
222
223 str.ReadLine(*fIn); // Read to EOF or newline
224 if (!str.BeginsWith(gsVersionPrefix))
225 {
226 *fLog << err << "ERROR - Version prefix '" << gsVersionPrefix <<"' ";
227 *fLog << "not found in second line of file '" << fFileName << "'"<<endl;
228 return line;
229 }
230 line++;
231
232 str.Remove(0, gsVersionPrefix.Length());
233 str = str.Strip(TString::kBoth);
234
235 TString ver = str(TRegexp("^[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9]$"));
236 if (ver.IsNull())
237 {
238 *fLog << err << "ERROR - Version string '" << str <<"' doesn't ";
239 *fLog << "match regular expression." << endl;
240 return line;
241 }
242
243 *fLog << dbg << "Report File version: <" << ver << ">" << endl;
244
245 return line;
246}
247
248// --------------------------------------------------------------------------
249//
250// Call SetupReading for all MReportHelp objects scheduled.
251// Try to open the file and check the file header.
252//
253Int_t MReportFileRead::PreProcess(MParList *pList)
254{
255 //MTime *time = (MTime*)pList->FindCreateObj("MTime");
256 //if (!time)
257 // return kFALSE;
258 fNumLine = 0;
259
260 TIter Next(fList);
261 MReportHelp *help=0;
262 while ((help=(MReportHelp*)Next()))
263 if (!help->SetupReading(*pList))
264 return kFALSE;
265
266 fList->ForEach(MReportHelp, AddToList)(*pList);
267
268 //
269 // open the input stream
270 // first of all check if opening the file in the constructor was
271 // successfull
272 //
273 fIn->open(fFileName);
274 if (!(*fIn))
275 {
276 *fLog << err << "Error: Cannot open file '" << fFileName << "'" << endl;
277 return kFALSE;
278 }
279 if (TestBit(kHasNoHeader))
280 return kTRUE;
281
282 const Int_t n = CheckFileHeader();
283 fNumLine += n;
284 return n==2;
285}
286
287// --------------------------------------------------------------------------
288//
289// Read the file line by line as long as a matching MReport* class is found.
290// In this case call its interpreter (Interprete()) and remove the identifier
291// first (XYZ-REPORT)
292//
293Int_t MReportFileRead::Process()
294{
295 TString str;
296
297 MReportHelp *rep=NULL;
298 while (!GetReport(rep))
299 {
300 str.ReadLine(*fIn);
301 if (!*fIn)
302 {
303 *fLog << dbg << "EOF detected." << endl;
304 return kFALSE;
305 }
306
307 fNumLine++;
308
309 const Int_t pos = str.First(' ');
310 if (pos<=0)
311 continue;
312
313 rep = GetReportHelp(str(0,pos));
314 if (GetReport(rep))
315 str.Remove(0, pos);
316 }
317
318 const Int_t rc = rep->Interprete(str, fStart, fStop);
319 if (rc==kFALSE)
320 {
321 *fLog << err << "ERROR - Interpretation of '" << rep->GetName() << "' failed (Line #" << fNumLine << ")" << endl;
322 return kFALSE;
323 }
324
325 return rc;
326}
327
328// --------------------------------------------------------------------------
329//
330// Close the file and print some execution statistics
331//
332Int_t MReportFileRead::PostProcess()
333{
334 fIn->close();
335
336 if (!GetNumExecutions())
337 return kTRUE;
338
339 *fLog << inf << endl;
340 *fLog << GetDescriptor() << " statistics:" << endl;
341 *fLog << dec << setfill(' ');
342
343 TIter Next(fList);
344 MReportHelp *rep=0;
345
346 while ((rep=(MReportHelp*)Next()))
347 {
348 *fLog << " " << setw(7) << rep->GetNumReports() << " (";
349 *fLog << setw(3) << (int)(100.*rep->GetNumReports()/GetNumExecutions());
350 *fLog << "%): " << rep->GetName() << endl;
351 }
352
353 return kTRUE;
354}
Note: See TracBrowser for help on using the repository browser.