source: trunk/MagicSoft/Mars/mbase/MEvtLoop.cc@ 1474

Last change on this file since 1474 was 1474, checked in by tbretz, 22 years ago
*** empty log message ***
File size: 13.2 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 12/2000 <mailto:tbretz@uni-sw.gwdg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2001
21!
22!
23\* ======================================================================== */
24
25
26//////////////////////////////////////////////////////////////////////////////
27// //
28// MEvtLoop //
29// //
30// This class is the core of each event processing. //
31// First you must set the parameter list to use. The parameter list //
32// must contain the task list (MTaskList) to use. The name of the task //
33// list can be specified if you call Eventloop. The standard name is //
34// "MTaskList". The name you specify must match the name of the MTaskList //
35// object. //
36// //
37// If you call Eventloop first all PreProcess functions - with the //
38// parameter list as an argument - of the tasks in the task list are //
39// executed. If one of them returns kFALSE then the execution is stopped. //
40// If the preprocessing was ok. The Process funtion of the tasks are //
41// as long as one function returns kSTOP. Only the tasks which are marked //
42// marked as "All" or with a string which matches the MInputStreamID of //
43// MTaskList are executed. If one tasks returns kCONTINUE the pending //
44// tasks in the list are skipped and the execution in continued with //
45// the first one in the list. //
46// Afterwards the PostProcess functions are executed. //
47// //
48// //
49// Maybe we can add a TProgressMeter sometimes later to be able to show //
50// the progress graphically... //
51// //
52// //
53// You can create a macro from a completely setup eventloop by: //
54// evtloop.MakeMacro("mymacro.C"); //
55// //
56// You will always need to check the macro, it will not run, but it //
57// should have al important information. //
58// //
59// //
60// You can also write all this information to a root file: //
61// TFile file("myfile.root"); //
62// evtloop.Write("MyEvtloopKey"); //
63// //
64// You can afterwards read the information from an open file by: //
65// evtloop.Read("MyEvtloopKey"); //
66// //
67// To lookup the information write it to a file using MakeMacro //
68// //
69//////////////////////////////////////////////////////////////////////////////
70#include "MEvtLoop.h"
71
72#include <time.h>
73#include <fstream.h> // ofstream, SavePrimitive
74#include <iostream.h>
75
76#include <TSystem.h>
77#include <TStopwatch.h>
78#include <TGProgressBar.h>
79
80#include "MLog.h"
81#include "MLogManip.h"
82
83#include "MParList.h"
84#include "MTaskList.h"
85
86ClassImp(MEvtLoop);
87
88
89//!
90//! Maybe we can add a static parameter list to MEvtLoop
91//! Also we can derive MEvtLoop from MTaskList to have a static tasklist, too
92//!
93
94// --------------------------------------------------------------------------
95//
96// default constructor - emty
97//
98MEvtLoop::MEvtLoop() : fParList(NULL), fProgress(NULL)
99{
100}
101
102// --------------------------------------------------------------------------
103//
104// default destructor - emty
105//
106MEvtLoop::~MEvtLoop()
107{
108 if (TestBit(kIsOwner) && fParList)
109 delete fParList;
110}
111
112// --------------------------------------------------------------------------
113//
114// if you set the Eventloop as owner the destructor of the given parameter
115// list is calles by the destructor of MEvtLoop, otherwise not.
116//
117void MEvtLoop::SetOwner(Bool_t enable)
118{
119 enable ? SetBit(kIsOwner) : ResetBit(kIsOwner);
120}
121
122// --------------------------------------------------------------------------
123//
124// The proprocessing part of the eventloop. Be careful, this is
125// for developers or use in special jobs only!
126//
127Bool_t MEvtLoop::PreProcess(const char *tlist)
128{
129 //
130 // check if the needed parameter list is set.
131 //
132 if (!fParList)
133 {
134 *fLog << err << dbginf << "Parlist not initialized." << endl;
135 return kFALSE;
136 }
137
138 //
139 // check for the existance of the specified task list
140 // the default name is "MTaskList"
141 //
142 fTaskList = (MTaskList*)fParList->FindObject(tlist, "MTaskList");
143 if (!fTaskList)
144 {
145 *fLog << err << dbginf << "Cannot find tasklist '" << tlist << "' in parameter list." << endl;
146 return kFALSE;
147 }
148
149 if (fLog != &gLog)
150 fParList->SetLogStream(fLog);
151
152 //
153 // execute the preprocess of all tasks
154 // connect the different tasks with the right containers in
155 // the parameter list
156 //
157 if (!fTaskList->PreProcess(fParList))
158 {
159 *fLog << err << "Error detected while PreProcessing" << endl;
160 return kFALSE;
161 }
162
163 *fLog << endl;
164
165 return kTRUE;
166}
167
168// --------------------------------------------------------------------------
169//
170// The processing part of the eventloop. Be careful, this is
171// for developers or use in special jobs only!
172//
173void MEvtLoop::Process(Int_t maxcnt) const
174{
175 //
176 // loop over all events and process all tasks for
177 // each event
178 //
179 *fLog << all <<"Eventloop running (";
180
181 if (maxcnt<0)
182 *fLog << "all";
183 else
184 *fLog << dec << maxcnt;
185
186 *fLog << " events)..." << flush;
187
188 if (fProgress && maxcnt>0)
189 fProgress->SetRange(0, maxcnt);
190
191 Int_t dummy = maxcnt<0 ? 0 : maxcnt;
192
193 //
194 // start a stopwatch
195 //
196 TStopwatch clock;
197 clock.Start();
198
199 //
200 // This is the MAIN EVENTLOOP which processes the data
201 // if maxcnt<0 the number of processed events is counted
202 // else only maxcnt events are processed
203 //
204 if (maxcnt<0)
205 // process first and increment if sucessfull
206 if (fProgress)
207 while (fTaskList->Process())
208 {
209 fProgress->SetPosition(++dummy);
210#if ROOT_VERSION_CODE < ROOT_VERSION(3,02,06)
211 gSystem->ProcessEvents();
212#else
213 gClient->ProcessEventsFor(fProgress);
214#endif
215 }
216 else
217 while (fTaskList->Process()) dummy++;
218 else
219 // check for number and break if unsuccessfull
220 if (fProgress)
221 while (dummy-- && fTaskList->Process())
222 {
223 fProgress->SetPosition(maxcnt - dummy);
224#if ROOT_VERSION_CODE < ROOT_VERSION(3,02,06)
225 gSystem->ProcessEvents();
226#else
227 gClient->ProcessEventsFor(fProgress);
228#endif
229 }
230 else
231 while (dummy-- && fTaskList->Process());
232
233 //
234 // stop stop-watch, print results
235 //
236 clock.Stop();
237
238 *fLog << all << "Ready!" << endl << endl;
239
240 *fLog << dec << endl << "CPU - "
241 << "Time: " << clock.CpuTime() << "s"
242 << " for " << (maxcnt<0?dummy:maxcnt) << " Events"
243 << " --> " << (maxcnt<0?dummy:maxcnt)/clock.CpuTime() << " Events/s"
244 << endl;
245 *fLog << "Real - "
246 << "Time: " << clock.RealTime() << "s"
247 << " for " << (maxcnt<0?dummy:maxcnt) << " Events"
248 << " --> " << (maxcnt<0?dummy:maxcnt)/clock.RealTime() << " Events/s"
249 << endl << endl;
250}
251
252// --------------------------------------------------------------------------
253//
254// The postprocessing part of the eventloop. Be careful, this is
255// for developers or use in special jobs only!
256//
257Bool_t MEvtLoop::PostProcess() const
258{
259 //
260 // execute the post process of all tasks
261 //
262 return fTaskList->PostProcess();
263}
264
265// --------------------------------------------------------------------------
266//
267// See class description above.
268//
269Bool_t MEvtLoop::Eventloop(Int_t maxcnt, const char *tlist)
270{
271 Bool_t rc = PreProcess();
272
273 //
274 // If all Tasks were PreProcesses successfully start Processing.
275 //
276 if (rc)
277 Process(maxcnt);
278
279 //
280 // Now postprocess all tasks. Only successfully preprocessed tasks are
281 // postprocessed. If the Postprocessing of one task fail return an error.
282 //
283 if (!PostProcess())
284 return kFALSE;
285
286 //
287 // If postprocessing of all preprocessed tasks was sucefully return rc.
288 // This gives an error in case the preprocessing has failed already.
289 // Otherwise the eventloop is considered: successfully.
290 //
291 return rc;
292}
293
294void MEvtLoop::MakeMacro(const char *filename="evtloop.C")
295{
296 TString name(filename);
297
298 if (!name.EndsWith(".C"))
299 name += ".C";
300
301 time_t t = time(NULL);
302
303 ofstream fout(name);
304 fout <<
305 "/* ======================================================================== *\\" << endl <<
306 "!" << endl <<
307 "! *" << endl <<
308 "! * This file is part of MARS, the MAGIC Analysis and Reconstruction" << endl <<
309 "! * Software. It is distributed to you in the hope that it can be a useful" << endl <<
310 "! * and timesaving tool in analysing Data of imaging Cerenkov telescopes." << endl <<
311 "! * It is distributed WITHOUT ANY WARRANTY." << endl <<
312 "! *" << endl <<
313 "! * Permission to use, copy, modify and distribute this software and its" << endl <<
314 "! * documentation for any purpose is hereby granted without fee," << endl <<
315 "! * provided that the above copyright notice appear in all copies and" << endl <<
316 "! * that both that copyright notice and this permission notice appear" << endl <<
317 "! * in supporting documentation. It is provided \"as is\" without express" << endl <<
318 "! * or implied warranty." << endl <<
319 "! *" << endl <<
320 "!" << endl <<
321 "!" << endl <<
322 "! Author(s): Thomas Bretz et al. <mailto:tbretz@astro.uni-wuerzburg.de>" << endl <<
323 "!" << endl <<
324 "! Copyright: MAGIC Software Development, 2000-2002" << endl <<
325 "!" << endl <<
326 "!" << endl <<
327 "\\* ======================================================================== */" << endl << endl <<
328 "// ------------------------------------------------------------------------" << endl <<
329 "//" << endl <<
330 "// This macro was automatically created on" << endl<<
331 "// " << ctime(&t) <<
332 "// with the MEvtLoop::MakeMacro tool." << endl <<
333 "//" << endl <<
334 "// ------------------------------------------------------------------------" << endl << endl <<
335 "void " << name(0, name.Length()-2) << "()" << endl <<
336 "{" << endl;
337
338 SavePrimitive(fout);
339
340 fout << "}" << endl;
341}
342
343// --------------------------------------------------------------------------
344//
345// Implementation of SavePrimitive. Used to write the call to a constructor
346// to a macro. In the original root implementation it is used to write
347// gui elements to a macro-file.
348
349//
350void MEvtLoop::SavePrimitive(ofstream &out, Option_t *)
351{
352 fParList->SavePrimitive(out);
353
354 out << " MEvtLoop evtloop;" << endl;
355 out << " evtloop.SetParList(&" << ToLower(fParList->GetName()) << ");" << endl;
356 out << " if (!evtloop.Eventloop())" << endl;
357 out << " return;" << endl;
358}
359
360Int_t MEvtLoop::Read(const char *name)
361{
362 Int_t n = 0;
363 TObjArray list;
364
365 n += TObject::Read(name);
366 n += list.Read((TString)name+"_names");
367
368 fParList->SetNames(list);
369
370 return n;
371}
372
373Int_t MEvtLoop::Write(const char *name, Int_t option, Int_t bufsize)
374{
375 Int_t n = 0;
376
377 TObjArray list;
378 list.SetOwner();
379
380 fParList->GetNames(list);
381
382 n += list.Write((TString)name+"_names", kSingleKey);
383 n += TObject::Write(name, option, bufsize);
384
385 return n;
386}
Note: See TracBrowser for help on using the repository browser.