source: trunk/MagicSoft/Mars/mfilter/MFilterList.cc@ 2984

Last change on this file since 2984 was 2984, checked in by tbretz, 23 years ago
*** empty log message ***
File size: 9.4 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, 07/2001 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2003
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MFilterList
28//
29// A filter list can be used to concatenate filter (derived from MFilter)
30// by a logical or bitwise operator. For more details see the constructor.
31//
32// The list is setup by adding filters to the list calling AddToList().
33// For example in the case of the default constructor ("&&") all results
34// are logically and'd together and the result of this and is returned.
35//
36// Because the meaning of all filters can be inverted calling SetInverted()
37// which is defined in the base class MFilter you can use this list to
38// invert the meaning of a filter, by eg:
39//
40// MF anyfilter("MHillas.fAlpha");
41//
42// MFilterList alist;
43// alist.AddToList(&anyfilter);
44//
45// alist.SetInverted();
46//
47// Adding the filterlist to the eventloop will process all contained filters.
48// Doing this as early as possible is a simple way of processing all filters.
49//
50// If you want to make the list delete all contained filters you may make
51// the list owner of the filters by calling SetOwner()
52//
53/////////////////////////////////////////////////////////////////////////////
54#include "MFilterList.h"
55
56#include <fstream>
57
58#include <TString.h>
59
60#include "MLog.h"
61#include "MLogManip.h"
62
63#include "MIter.h"
64
65ClassImp(MFilterList);
66
67using namespace std;
68
69static const TString gsDefName = "MFilterList";
70static const TString gsDefTitle = "List combining filters logically.";
71
72// --------------------------------------------------------------------------
73//
74// Constructor.
75//
76// Specify the boolean operation which is used to evaluate the
77// result of this list. If no operation is specified "land" is
78// used.
79//
80// Options:
81// and, & : is a bitwise and
82// or, | : is a bitwise or
83// xor, ^ : is a bitwise exclusive or
84// land, && : is a logical and
85// lor, || : is a logical or
86//
87MFilterList::MFilterList(const char *type, const char *name, const char *title)
88{
89 fName = name ? name : gsDefName.Data();
90 fTitle = title ? title : gsDefTitle.Data();
91
92 gROOT->GetListOfCleanups()->Add(&fFilters);
93 fFilters.SetBit(kMustCleanup);
94
95 fFilterType = kEAnd;
96
97 TString str(type);
98
99 if (!str.CompareTo("OR", TString::kIgnoreCase) || !str.CompareTo("|"))
100 fFilterType = kEOr;
101 if (!str.CompareTo("XOR", TString::kIgnoreCase) || !str.CompareTo("^"))
102 fFilterType = kEXor;
103 if (!str.CompareTo("LAND", TString::kIgnoreCase) || !str.CompareTo("&&"))
104 fFilterType = kELAnd;
105 if (!str.CompareTo("LOR", TString::kIgnoreCase) || !str.CompareTo("||"))
106 fFilterType = kELOr;
107}
108
109// --------------------------------------------------------------------------
110//
111// CopyConstructor
112//
113MFilterList::MFilterList(MFilterList &ts)
114{
115 fFilters.AddAll(&ts.fFilters);
116 fFilterType = ts.fFilterType;
117}
118
119// --------------------------------------------------------------------------
120//
121// Evaluates and returns the result of the filter list.
122// The expression is evaluated step by step, eg:
123// ((filter[0] # filter[1]) # filter[3]) # filter[4])
124// The '#' stands for the boolean operation which is specified in
125// the constructor.
126//
127Bool_t MFilterList::IsExpressionTrue() const
128{
129 TIter Next(&fFilters);
130
131 MFilter *filter=(MFilter*)Next();
132
133 if (!filter)
134 return kTRUE;
135
136 Bool_t rc = filter->IsConditionTrue();
137
138 //
139 // loop over all filters
140 //
141 switch (fFilterType)
142 {
143 case kEAnd:
144 while ((filter=(MFilter*)Next()))
145 rc &= filter->IsConditionTrue();
146 break;
147
148 case kEOr:
149 while ((filter=(MFilter*)Next()))
150 rc |= filter->IsConditionTrue();
151 break;
152
153 case kEXor:
154 while ((filter=(MFilter*)Next()))
155 rc ^= filter->IsConditionTrue();
156 break;
157
158 case kELAnd:
159 while ((filter=(MFilter*)Next()))
160 rc = (rc && filter->IsConditionTrue());
161 break;
162
163 case kELOr:
164 while ((filter=(MFilter*)Next()))
165 rc = (rc || filter->IsConditionTrue());
166 break;
167 }
168 return rc;
169}
170
171// --------------------------------------------------------------------------
172//
173// If you want to add a new filter to the list call this function with the
174// pointer to the filter to be added.
175//
176Bool_t MFilterList::AddToList(MFilter *filter)
177{
178 if (!filter)
179 return kTRUE;
180
181 const char *name = filter->GetName();
182
183 if (fFilters.FindObject(filter))
184 {
185 *fLog << warn << dbginf << "Filter already existing... skipped." << endl;
186 return kTRUE;
187 }
188
189 if (fFilters.FindObject(name))
190 *fLog << warn << dbginf << "'" << name << "' exists in List already... skipped." << endl;
191
192 *fLog << inf << "Adding " << name << " to " << GetName() << "... " << flush;
193
194 filter->SetBit(kMustCleanup);
195 fFilters.Add(filter);
196
197 *fLog << "Done." << endl;
198
199 return kTRUE;
200}
201
202
203// --------------------------------------------------------------------------
204//
205// PreProcesses all filters in the list
206//
207Int_t MFilterList::PreProcess(MParList *pList)
208{
209 TIter Next(&fFilters);
210
211 MFilter *filter=NULL;
212
213 //
214 // loop over all filters
215 //
216 while ((filter=(MFilter*)Next()))
217 if (!filter->CallPreProcess(pList))
218 {
219 *fLog << err << "Error - Preprocessing Filter ";
220 *fLog << filter->GetName() << " in " << fName << endl;
221 return kFALSE;
222 }
223
224 return kTRUE;
225}
226
227// --------------------------------------------------------------------------
228//
229// Processes (updates) all filters in the list.
230//
231Int_t MFilterList::Process()
232{
233 TIter Next(&fFilters);
234
235 MFilter *filter=NULL;
236
237 //
238 // loop over all filters
239 //
240 while ((filter=(MFilter*)Next()))
241 if (!filter->CallProcess())
242 return kFALSE;
243
244 return kTRUE;
245}
246
247// --------------------------------------------------------------------------
248//
249// PostProcesses all filters in the list.
250//
251Int_t MFilterList::PostProcess()
252{
253 TIter Next(&fFilters);
254
255 MFilter *filter=NULL;
256
257 //
258 // loop over all filters
259 //
260 while ((filter=(MFilter*)Next()))
261 if (!filter->CallPostProcess())
262 return kFALSE;
263
264 return kTRUE;
265}
266
267// --------------------------------------------------------------------------
268//
269// If you want to use a verbose output ("and") instead of a symbolic ("&")
270// one the option string must conatin a "v"
271//
272void MFilterList::Print(Option_t *opt) const
273{
274 *fLog << all << GetRule(opt) << flush;
275}
276
277// --------------------------------------------------------------------------
278//
279// Implementation of SavePrimitive. Used to write the call to a constructor
280// to a macro. In the original root implementation it is used to write
281// gui elements to a macro-file.
282//
283void MFilterList::StreamPrimitive(ofstream &out) const
284{
285 out << " MFilterList " << ToLower(fName) << "(\"";
286
287 switch (fFilterType)
288 {
289 case kEAnd:
290 out << "&";
291 break;
292
293 case kEOr:
294 out << "|";
295 break;
296
297 case kEXor:
298 out << "^";
299 break;
300
301 case kELAnd:
302 out << "&&";
303 break;
304
305 case kELOr:
306 out << "||";
307 break;
308 }
309
310 out << "\"";
311
312 if (fName!=gsDefName || fTitle!=gsDefTitle)
313 {
314 out << ", \"" << fName << "\"";
315 if (fTitle!=gsDefTitle)
316 out << ", \"" << fTitle << "\"";
317 }
318 out << ");" << endl << endl;
319
320 MIter Next(&fFilters);
321
322 MParContainer *cont = NULL;
323 while ((cont=Next()))
324 {
325 cont->SavePrimitive(out, "");
326
327 out << " " << ToLower(fName) << ".AddToList(&";
328 out << cont->GetUniqueName() << ");" << endl << endl;
329 }
330}
331
332TString MFilterList::GetRule(Option_t *opt) const
333{
334 TString str(opt);
335 const Bool_t verbose = str.Contains("V", TString::kIgnoreCase);
336
337 TString ret = "(";
338
339 TIter Next(&fFilters);
340
341 MFilter *filter=(MFilter*)Next();
342
343 //
344 // loop over all filters
345 //
346 if (!filter)
347 return "<empty>";
348
349 ret += filter->GetRule();
350
351 while ((filter=(MFilter*)Next()))
352 {
353 switch (fFilterType)
354 {
355 case kEAnd:
356 ret += (verbose?" and ":" & ");
357 break;
358
359 case kEOr:
360 ret += (verbose?" or ":" | ");
361 break;
362
363 case kEXor:
364 ret += (verbose?" xor ":" ^ ");
365 break;
366
367 case kELAnd:
368 ret += (verbose?" land ":" && ");
369 break;
370
371 case kELOr:
372 ret += (verbose?" lor ":" || ");
373 break;
374 }
375
376 ret += filter->GetRule();
377 }
378
379 return ret+")";
380}
Note: See TracBrowser for help on using the repository browser.