source: trunk/Mars/mbase/MParSpline.cc@ 11952

Last change on this file since 11952 was 9576, checked in by tbretz, 15 years ago
*** empty log message ***
File size: 8.5 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of CheObs, the Modular 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 appears 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, 4/2009 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: CheObs Software Development, 2000-2009
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MParSpline
28//
29// Parameter container to store a MParSpline
30//
31//////////////////////////////////////////////////////////////////////////////
32#include "MParSpline.h"
33
34#include <TF1.h> // MParSpline
35
36#include "MLog.h"
37#include "MLogManip.h"
38
39#include "MSpline3.h"
40
41ClassImp(MParSpline);
42
43using namespace std;
44
45// --------------------------------------------------------------------------
46//
47// Default constructor
48//
49MParSpline::MParSpline(const char *name, const char *title) : fSpline(0)
50{
51 fName = name ? name : "MParSpline";
52 fTitle = title ? title : "Parameter container to store a MSpline3";
53}
54
55// --------------------------------------------------------------------------
56//
57// Return Xmin of the spline. 0 if fSpline==NULL
58//
59Double_t MParSpline::GetXmin() const
60{
61 return fSpline ? fSpline->GetXmin() : 0;
62}
63
64// --------------------------------------------------------------------------
65//
66// Return Xmax of the spline. 0 if fSpline==NULL
67//
68Double_t MParSpline::GetXmax() const
69{
70 return fSpline ? fSpline->GetXmax() : 0;
71}
72
73// --------------------------------------------------------------------------
74//
75// Return the width of the range in which the spline is defined.
76//
77Double_t MParSpline::GetWidth() const
78{
79 return fSpline ? fSpline->GetXmax()-fSpline->GetXmin() : 0;
80}
81
82// --------------------------------------------------------------------------
83//
84// Return the result of the spline at val.
85// The user is reposible to make sure that fSpline is valid (!=NULL)
86//
87Double_t MParSpline::Eval(Double_t val) const
88{
89 return fSpline->Eval(val);
90}
91
92// --------------------------------------------------------------------------
93//
94// Delete fSpline and set to 0.
95//
96void MParSpline::Clear(Option_t *)
97{
98 if (fSpline)
99 delete fSpline;
100 fSpline=0;
101}
102
103// --------------------------------------------------------------------------
104//
105// Read a TGraph from a file and return a newly allocated MSpline3.
106//
107MSpline3 *MParSpline::ReadSpline(const char *fname) const
108{
109 *fLog << inf << "Reading spline from " << fname << endl;
110
111 TGraph g(fname);
112 if (g.GetN()==0)
113 {
114 *fLog << err << "ERROR - No data points from " << fname << "." << endl;
115 return 0;
116 }
117
118 // option: b1/e1 b2/e2 (first second derivative?)
119 // option: valbeg/valend (first second derivative?)
120
121 MSpline3 *s = new MSpline3(g);
122 s->SetTitle(fname);
123
124 return s;
125}
126
127// --------------------------------------------------------------------------
128//
129// Initializes a spline from min to max with n points with 1.
130//
131/*
132void MParSpline::InitUnity(UInt_t n, Float_t min, Float_t max)
133{
134 // Delete the existing spline
135 Clear();
136
137 // We need at least two points (the edges)
138 if (n<2)
139 return;
140
141 // Initialize an array with the x-values
142 const MBinning bins(n-1, min, max);
143
144 // Initialize an array with all one
145 MArrayD y(n);
146 y.Reset(1);
147
148 // Set the spline
149 fSpline = new MSpline3(bins.GetEdges(), y.GetArray(), n);
150}
151*/
152
153// --------------------------------------------------------------------------
154//
155// Takes the existing fSpline and multiplies it with the given spline.
156// As x-points the values from fSpline are used.
157//
158void MParSpline::Multiply(const TSpline3 &spline)
159{
160 if (!fSpline)
161 {
162 Clear();
163 // WARNING WARNING WARNING: This is a very dangerous cast!
164 fSpline = (MSpline3*)spline.Clone();
165 return;
166 }
167
168 // Initialize a TGraph with the number of knots from a TSpline
169 TGraph g(fSpline->GetNp());
170
171 // Loop over all knots
172 for (int i=0; i<fSpline->GetNp(); i++)
173 {
174 // Get th i-th knot
175 Double_t x, y;
176 fSpline->GetKnot(i, x, y);
177
178 // Multiply y by the value from the given spline
179 y *= spline.Eval(x);
180
181 // push the point "back"
182 g.SetPoint(i, x, y);
183 }
184
185 // Clear the spline and initialize a new one from the updated TGraph
186 Clear();
187 fSpline = new MSpline3(g);
188}
189
190// --------------------------------------------------------------------------
191//
192// Initializes a TSpline3 with n knots x and y. Call Multiply for it.
193//
194void MParSpline::Multiply(UInt_t n, const Double_t *x, const Double_t *y)
195{
196 const TSpline3 spline("Spline", const_cast<Double_t*>(x), const_cast<Double_t*>(y), n);
197 Multiply(spline);
198}
199
200// --------------------------------------------------------------------------
201//
202// Read a Spline from a file using ReadSpline.
203// Call Multiply for it.
204//
205void MParSpline::Multiply(const char *fname)
206{
207 const MSpline3 *spline = ReadSpline(fname);
208 if (!spline)
209 return;
210
211 Multiply(*spline);
212
213 delete spline;
214}
215
216// --------------------------------------------------------------------------
217//
218// Read a spline from a file and set fSpline accfordingly.
219//
220Bool_t MParSpline::ReadFile(const char *fname)
221{
222 MSpline3 *spline = ReadSpline(fname);
223 if (!spline)
224 return kFALSE;
225
226
227 // option: b1/e1 b2/e2 (first second derivative?)
228 // option: valbeg/valend (first second derivative?)
229
230 Clear();
231 fSpline = spline;
232
233 return kTRUE;
234}
235
236// --------------------------------------------------------------------------
237//
238// Set the spline to a function. For details see MSpline3
239//
240void MParSpline::SetFunction(const TF1 &f)
241{
242 // FIXME: Use TF1 directly? (In most cases this seems to be slower)
243
244 // option: b1/e1 b2/e2 (first second derivative?)
245 // option: valbeg/valend (first second derivative?)
246
247 // if (f.GetNpar()==0)
248 // No SUPPORT
249
250 Clear();
251 fSpline = new MSpline3(f);//, fRunHeader->GetFreqSampling()/1000.);
252 fSpline->SetTitle(f.GetTitle());
253
254 // FIXME: Make a boundary condition e1b1,0,0 (First der, at Xmin and Xmax==0)
255 // FIXME: Force the spline to be 0 at Xmin and Xmax?
256}
257
258Bool_t MParSpline::SetFunction(const char *func, Int_t n, Double_t xmin, Double_t xmax)
259{
260 // FIXME: Use TF1 directly? (In most cases this seems to be slower)
261 TF1 f("f", func, xmin, xmax);
262 f.SetNpx(n);
263
264 SetFunction(f);
265
266 return kTRUE;
267}
268
269// --------------------------------------------------------------------------
270//
271// FileName: reflectivity.txt
272// Function.Name: exp(-(x/2)^2/2)
273// Function.Npx: 25
274// Function.Xmin: -8
275// Function.Xmax: 8
276//
277Int_t MParSpline::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
278{
279 Bool_t rc = kFALSE;
280 if (IsEnvDefined(env, prefix, "FileName", print))
281 {
282 rc = kTRUE;
283 if (!ReadFile(GetEnvValue(env, prefix, "FileName", "")))
284 return kERROR;
285 }
286
287 if (IsEnvDefined(env, prefix, "Function.Name", print))
288 {
289 rc = kTRUE;
290
291 Int_t npx = 25;
292 Float_t xmin = -8;
293 Float_t xmax = 8;
294 TString func = "exp(-(x/2)^2/2)";
295
296 if (IsEnvDefined(env, prefix, "Function.Npx", print))
297 npx = GetEnvValue(env, prefix, "Function.Npx", npx);
298 if (IsEnvDefined(env, prefix, "Function.Xmin", print))
299 xmin = GetEnvValue(env, prefix, "Function.Xmin", xmin);
300 if (IsEnvDefined(env, prefix, "Function.Xmax", print))
301 xmax = GetEnvValue(env, prefix, "Function.Xmax", xmax);
302
303 SetFunction(GetEnvValue(env, prefix, "Function.Name", func), npx, xmin, xmax);
304 }
305 return rc;
306}
307
308void MParSpline::Paint(Option_t *)
309{
310 fSpline->SetMarkerStyle(kFullDotMedium);
311
312 if (!fSpline->GetHistogram())
313 fSpline->Paint();
314
315 TH1 *h = fSpline->GetHistogram();
316 if (!h)
317 return;
318
319 //h->SetXTitle("t [ns]");
320 //h->SetYTitle("a.u.");
321
322 fSpline->Paint("PC");
323}
324
325void MParSpline::RecursiveRemove(TObject *obj)
326{
327 if (obj==fSpline)
328 fSpline=0;
329
330 MParContainer::RecursiveRemove(obj);
331}
Note: See TracBrowser for help on using the repository browser.