source: trunk/MagicSoft/Mars/mdata/MDataFormula.cc@ 4740

Last change on this file since 4740 was 3666, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 7.6 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, 04/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MDataFormula
28//
29// A MDataFormula is a wrapper for TFormula. It should have access to all
30// multi-argument functions, to formulas and to single-argument functions
31// unknown by MDataChain intrinsically.
32//
33// eg.
34// MDataFormula("myfunc(MParams.fValue)");
35// MDataFormula("TMath::Hypot(MParams.fX, MParams.fY)");
36// MDataFormula("TMath::Pow(MParams.fX, 7.5)");
37// MDataFormula("TMath::Pow(MParams.fX, [6])");
38//
39// Using this should be rather slow. If you can create a 'plain' Data-Chain
40// this should be much faster.
41//
42// To do:
43// - implement SetVariables to be used in functions like "gaus(0)" or
44// "pol0(1)"
45//
46/////////////////////////////////////////////////////////////////////////////
47#include "MDataFormula.h"
48
49#include <TArrayD.h>
50#include <TFormula.h>
51
52#include "MLog.h"
53#include "MLogManip.h"
54
55#include "MDataChain.h"
56
57ClassImp(MDataFormula);
58
59using namespace std;
60
61TString MDataFormula::Parse(const char *rule)
62{
63 TString txt(rule);
64
65 Int_t pos1 = txt.First('(');
66 if (pos1<0)
67 {
68 *fLog << err << dbginf << "Syntax Error: '(' not found in " << txt << endl;
69 return "";
70 }
71
72 Int_t pos2 = txt.Last(')');
73 if (pos2<0)
74 {
75 *fLog << err << dbginf << "Syntax Error: ')' not found in " << txt << endl;
76 return "";
77 }
78
79 if (pos2<pos1+1)
80 {
81 *fLog << err << dbginf << "Syntax Error: '(' not behind ')' in " << txt << endl;
82 return "";
83 }
84
85 //TObject *func = gROOT->GetListOfFunctions()->FindObject(txt(0, pos1));
86
87 TString args = txt(pos1+1, pos2-pos1);
88 Int_t num = 0;
89
90 while (args.Length()>0 && num<5)
91 {
92 const Int_t last = args.First(',');
93 const Int_t len = last<0 ? args.Last(')') : last;
94 if (len<0)
95 {
96 *fLog << err << dbginf << "Syntax Error: ',' found after ')'" << endl;
97 return "";
98 }
99
100 const TString arg = args(0, len);
101
102 MDataChain *chain = new MDataChain(arg);
103 if (!chain->IsValid())
104 {
105 delete chain;
106 return "";
107 }
108 fMembers.AddLast(chain);
109
110 txt.ReplaceAll(arg, Form("[%d]", num++));
111 pos1 += len;
112
113 args.Remove(0, len+1);
114 }
115
116 return txt;
117}
118
119// --------------------------------------------------------------------------
120//
121// Default Constructor. Not for usage!
122//
123MDataFormula::MDataFormula(const char *rule, const char *name, const char *title) : fFormula(0)
124{
125 fName = name ? name : "MDataFormula";
126 fTitle = title ? title : rule;
127
128 fMembers.SetOwner();
129
130 if (!rule)
131 return;
132
133 const TString txt=Parse(rule);
134 if (txt.IsNull())
135 {
136 fMembers.Delete();
137 return;
138 }
139
140 fFormula = new TFormula;
141 if (fFormula->Compile(txt))
142 {
143 *fLog << err << dbginf << "Syntax Error: TFormula::Compile failed for " << txt << endl;
144 delete fFormula;
145 fFormula = 0;
146 return;
147 }
148
149 gROOT->GetListOfFunctions()->Remove(fFormula);
150}
151
152// --------------------------------------------------------------------------
153//
154// Destructor
155//
156MDataFormula::~MDataFormula()
157{
158 if (fFormula)
159 delete fFormula;
160}
161
162// --------------------------------------------------------------------------
163//
164// CopyConstructor
165//
166MDataFormula::MDataFormula(MDataFormula &ts)
167{
168 TFormula *f = ts.fFormula;
169
170 fName = "MDataFormula";
171 fTitle = f ? f->GetExpFormula() : (TString)"";
172
173 fFormula = f ? (TFormula*)f->Clone() : 0;
174 gROOT->GetListOfFunctions()->Add(fFormula);
175
176 fMembers.SetOwner();
177
178 TObject *o = NULL;
179 TIter Next(&ts.fMembers);
180 while ((o=Next()))
181 fMembers.AddLast(o->Clone());
182}
183
184// --------------------------------------------------------------------------
185//
186// Evaluates and returns the result of the member list.
187// The expression is evaluated step by step, eg:
188// ((member[0] # member[1]) # member[3]) # member[4])
189// The '#' stands for the boolean operation which is specified in
190// the constructor.
191//
192Double_t MDataFormula::GetValue() const
193{
194 TArrayD val(fMembers.GetSize());
195
196 MData *member = NULL;
197
198 Int_t i=0;
199 TIter Next(&fMembers);
200 while ((member=(MData*)Next()))
201 val[i++] = member->GetValue();
202
203 return fFormula->EvalPar(0, val.GetArray());
204}
205
206Bool_t MDataFormula::IsValid() const
207{
208 TIter Next(&fMembers);
209
210 MData *data = NULL;
211 while ((data=(MData*)Next()))
212 if (!data->IsValid())
213 return kFALSE;
214
215 return fFormula ? kTRUE : kFALSE;
216}
217
218// --------------------------------------------------------------------------
219//
220// Checks whether at least one member has the ready-to-save flag.
221//
222Bool_t MDataFormula::IsReadyToSave() const
223{
224 TIter Next(&fMembers);
225
226 MData *data = NULL;
227
228 while ((data=(MData*)Next()))
229 if (data->IsReadyToSave())
230 return kTRUE;
231
232 return kFALSE;
233}
234
235// --------------------------------------------------------------------------
236//
237// PreProcesses all members in the list
238//
239Bool_t MDataFormula::PreProcess(const MParList *plist)
240{
241 TIter Next(&fMembers);
242
243 MData *member=NULL;
244
245 //
246 // loop over all members
247 //
248 while ((member=(MData*)Next()))
249 if (!member->PreProcess(plist))
250 {
251 *fLog << err << "Error - Preprocessing Data Member ";
252 *fLog << member->GetName() << " in " << fName << endl;
253 return kFALSE;
254 }
255
256 return kTRUE;
257}
258
259// --------------------------------------------------------------------------
260//
261// Builds a rule from all the list members. This is a rule which could
262// be used to rebuild the list using the constructor of a MDataChain
263//
264TString MDataFormula::GetRule() const
265{
266 if (!fFormula)
267 return "<empty>";
268
269 TString rule = fFormula->GetExpFormula();
270
271 MData *member = NULL;
272
273 Int_t i=0;
274 TIter Next(&fMembers);
275 while ((member=(MData*)Next()))
276 {
277 TString r = member->GetRule();
278 r.ReplaceAll("]", "\\]");
279 rule.ReplaceAll(Form("[%d]", i++), r);
280 }
281 rule.ReplaceAll("\\]", "]");
282
283 return rule;
284}
285/*
286// --------------------------------------------------------------------------
287//
288// Return a comma seperated list of all data members used in the chain.
289// This is mainly used in MTask::AddToBranchList
290//
291TString MDataFormula::GetDataMember() const
292{
293 TString str;
294
295 TIter Next(&fMembers);
296
297 MData *member=(MData*)Next();
298
299 if (!member->GetDataMember().IsNull())
300 str += member->GetDataMember();
301
302 while ((member=(MData*)Next()))
303 {
304 if (!member->GetDataMember().IsNull())
305 {
306 str += ",";
307 str += member->GetDataMember();
308 }
309 }
310
311 return str;
312}
313
314void MDataFormula::SetVariables(const TArrayD &arr)
315{
316 fMembers.ForEach(MData, SetVariables)(arr);
317}
318*/
Note: See TracBrowser for help on using the repository browser.