source: trunk/MagicSoft/Mars/msim/MSimAbsorption.cc@ 9368

Last change on this file since 9368 was 9348, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 9.0 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, 1/2009 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: CheObs Software Development, 2000-2009
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MSimAbsorption
28//
29// Task to calculate wavelength or incident angle dependent absorption
30//
31// Input Containers:
32// MPhotonEvent
33// MCorsikaEvtHeader
34// MCorsikaRunHeader
35//
36// Output Containers:
37// MPhotonEvent
38//
39//////////////////////////////////////////////////////////////////////////////
40#include "MSimAbsorption.h"
41
42#include <fstream>
43
44#include <TRandom.h>
45#include <TSpline.h>
46
47#include "MLog.h"
48#include "MLogManip.h"
49
50#include "MParList.h"
51
52#include "MBinning.h"
53#include "MArrayD.h"
54
55#include "MSpline3.h"
56
57#include "MCorsikaEvtHeader.h"
58#include "MCorsikaRunHeader.h"
59#include "MPhotonEvent.h"
60#include "MPhotonData.h"
61
62ClassImp(MSimAbsorption);
63
64using namespace std;
65
66// --------------------------------------------------------------------------
67//
68// Default Constructor.
69//
70MSimAbsorption::MSimAbsorption(const char* name, const char *title)
71 : fEvt(0), fHeader(0), fSpline(0), fUseTheta(kFALSE)
72{
73 fName = name ? name : "MSimAbsorption";
74 fTitle = title ? title : "Task to calculate wavelength dependent absorption";
75}
76
77// --------------------------------------------------------------------------
78//
79// Calls Clear()
80//
81MSimAbsorption::~MSimAbsorption()
82{
83 Clear();
84}
85
86// --------------------------------------------------------------------------
87//
88// Delete fSpline and set to 0.
89//
90void MSimAbsorption::Clear(Option_t *)
91{
92 if (fSpline)
93 delete fSpline;
94 fSpline=0;
95}
96
97// --------------------------------------------------------------------------
98//
99// Read a TGraph from a file and return a newly allocated MSpline3.
100//
101MSpline3 *MSimAbsorption::ReadSpline(const char *fname)
102{
103 *fLog << inf << "Reading spline from " << fname << endl;
104
105 TGraph g(fname);
106 if (g.GetN()==0)
107 {
108 *fLog << err << "ERROR - No data points from " << fname << "." << endl;
109 return 0;
110 }
111
112 // option: b1/e1 b2/e2 (first second derivative?)
113 // option: valbeg/valend (first second derivative?)
114
115 return new MSpline3(g);
116}
117
118// --------------------------------------------------------------------------
119//
120// Initializes a spline from min to max with n points with 1.
121//
122void MSimAbsorption::InitUnity(UInt_t n, Float_t min, Float_t max)
123{
124 // Delete the existing spline
125 Clear();
126
127 // We need at least two points (the edges)
128 if (n<2)
129 return;
130
131 // Initialize an array with the x-values
132 const MBinning bins(n-1, min, max);
133
134 // Initialize an array with all one
135 MArrayD y(n);
136 y.Reset(1);
137
138 // Set the spline
139 fSpline = new MSpline3(bins.GetEdges(), y.GetArray(), n);
140}
141
142// --------------------------------------------------------------------------
143//
144// Takes the existing fSpline and multiplies it with the given spline.
145// As x-points the values from fSpline are used.
146//
147void MSimAbsorption::Multiply(const TSpline3 &spline)
148{
149 if (!fSpline)
150 {
151 Clear();
152 // WARNING WARNING WARNING: This is a very dangerous cast!
153 fSpline = (MSpline3*)spline.Clone();
154 return;
155 }
156
157 // Initialize a TGraph with the number of knots from a TSpline
158 TGraph g(fSpline->GetNp());
159
160 // Loop over all knots
161 for (int i=0; i<fSpline->GetNp(); i++)
162 {
163 // Get th i-th knot
164 Double_t x, y;
165 fSpline->GetKnot(i, x, y);
166
167 // Multiply y by the value from the given spline
168 y *= spline.Eval(x);
169
170 // push the point "back"
171 g.SetPoint(i, x, y);
172 }
173
174 // Clear the spline and initialize a new one from the updated TGraph
175 Clear();
176 fSpline = new MSpline3(g);
177}
178
179// --------------------------------------------------------------------------
180//
181// Initializes a TSpline3 with n knots x and y. Call Multiply for it.
182//
183void MSimAbsorption::Multiply(UInt_t n, const Double_t *x, const Double_t *y)
184{
185 const TSpline3 spline("Spline", const_cast<Double_t*>(x), const_cast<Double_t*>(y), n);
186 Multiply(spline);
187}
188
189// --------------------------------------------------------------------------
190//
191// Read a Spline from a file using ReadSpline.
192// Call Multiply for it.
193//
194void MSimAbsorption::Multiply(const char *fname)
195{
196 const MSpline3 *spline = ReadSpline(fname);
197 if (!spline)
198 return;
199
200 fFileName = "";
201
202 Multiply(*spline);
203
204 delete spline;
205}
206
207// --------------------------------------------------------------------------
208//
209// Read a spline from a file and set fSpline accfordingly.
210//
211Bool_t MSimAbsorption::ReadFile(const char *fname)
212{
213 if (fname)
214 fFileName = fname;
215
216 MSpline3 *spline = ReadSpline(fFileName);
217 if (!spline)
218 return kFALSE;
219
220
221 // option: b1/e1 b2/e2 (first second derivative?)
222 // option: valbeg/valend (first second derivative?)
223
224 Clear();
225 fSpline = spline;
226
227 return kTRUE;
228}
229
230// --------------------------------------------------------------------------
231//
232// Search for the needed parameter containers. Read spline from file
233// calling ReadFile();
234//
235Int_t MSimAbsorption::PreProcess(MParList *pList)
236{
237 if (fFileName.IsNull())
238 {
239 *fLog << inf << "No file given... skipping." << endl;
240 return kSKIP;
241 }
242
243 fEvt = (MPhotonEvent*)pList->FindObject("MPhotonEvent");
244 if (!fEvt)
245 {
246 *fLog << err << "MPhotonEvent not found... aborting." << endl;
247 return kFALSE;
248 }
249
250 fHeader = (MCorsikaEvtHeader*)pList->FindObject("MCorsikaEvtHeader");
251 if (!fHeader)
252 {
253 *fLog << err << "MCorsikaEvtHeader not found... aborting." << endl;
254 return kFALSE;
255 }
256
257 *fLog << inf << "Using " << (fUseTheta?"Theta":"Wavelength") << " for absorption." << endl;
258
259 return ReadFile();
260}
261
262// --------------------------------------------------------------------------
263//
264Bool_t MSimAbsorption::ReInit(MParList *pList)
265{
266 if (fUseTheta)
267 return kTRUE;
268
269 MCorsikaRunHeader *h = (MCorsikaRunHeader*)pList->FindObject("MCorsikaRunHeader");
270 if (!h)
271 {
272 *fLog << err << "MCorsikaRunHeader not found... aborting." << endl;
273 return kFALSE;
274 }
275
276 if (h->GetWavelengthMin()<fSpline->GetXmin())
277 *fLog << warn << "WARNING - Lower bound of wavelength bandwidth exceeds lower bound of spline." << endl;
278
279 if (h->GetWavelengthMax()>fSpline->GetXmax())
280 *fLog << warn << "WARNING - Upper bound of wavelength bandwidth exceeds upper bound of spline." << endl;
281
282 return kTRUE;
283}
284
285// --------------------------------------------------------------------------
286//
287// Throw all events out of the MPhotonEvent which don't survive.
288// Depending on fUseTheta either the wavelength or the incident angle
289// is used.
290//
291Int_t MSimAbsorption::Process()
292{
293 // Get the number of photons in the list
294 const Int_t num = fEvt->GetNumPhotons();
295
296 // Counter for number of total and final events
297 Int_t cnt = 0;
298 for (Int_t i=0; i<num; i++)
299 {
300 // Get i-th photon from the list
301 const MPhotonData &ph = (*fEvt)[i];
302
303 // Depending on fUseTheta get the incident angle of the wavelength
304 const Double_t wl = fUseTheta ? ph.GetTheta()*TMath::RadToDeg() : ph.GetWavelength();
305
306 // Get the efficiency (the probability that this photon will survive)
307 // from the spline.
308 const Double_t eff = fSpline->Eval(wl);
309
310 // Get a random value between 0 and 1 to determine whether the photn will survive
311 // gRandom->Rndm() = [0;1[
312 if (gRandom->Rndm()>=eff)
313 continue;
314
315 // Copy the surviving events bakc in the list
316 (*fEvt)[cnt++] = ph;
317 }
318
319 // Now we shrink the array to the number of new entries.
320 fEvt->Shrink(cnt);
321
322 return kTRUE;
323}
324
325// --------------------------------------------------------------------------
326//
327// FileName: reflectivity.txt
328// UseTheta: No
329//
330Int_t MSimAbsorption::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
331{
332 Bool_t rc = kFALSE;
333 if (IsEnvDefined(env, prefix, "FileName", print))
334 {
335 rc = kTRUE;
336 SetFileName(GetEnvValue(env, prefix, "FileName", fFileName));
337 }
338
339 if (IsEnvDefined(env, prefix, "UseTheta", print))
340 {
341 rc = kTRUE;
342 SetUseTheta(GetEnvValue(env, prefix, "UseTheta", fUseTheta));
343 }
344
345 return rc;
346}
Note: See TracBrowser for help on using the repository browser.