source: trunk/MagicSoft/Mars/msimreflector/MReflector.cc@ 9518

Last change on this file since 9518 was 9518, checked in by tbretz, 15 years ago
*** empty log message ***
File size: 10.8 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// MReflector
28//
29//////////////////////////////////////////////////////////////////////////////
30#include "MReflector.h"
31
32#include <fstream>
33#include <errno.h>
34
35#include <stdlib.h> // atof (Ubuntu 8.10)
36
37#include <TClass.h>
38#include <TSystem.h>
39#include <TEllipse.h>
40
41#include "MQuaternion.h"
42#include "MMirror.h"
43
44#include "MLog.h"
45#include "MLogManip.h"
46
47#include "MH.h"
48
49ClassImp(MReflector);
50
51using namespace std;
52
53// --------------------------------------------------------------------------
54//
55// Default constructor
56//
57MReflector::MReflector(const char *name, const char *title)
58{
59 fName = name ? name : "MReflector";
60 fTitle = title ? title : "Parameter container storing a collection of several mirrors (reflector)";
61
62 fMirrors.SetOwner();
63}
64
65// --------------------------------------------------------------------------
66//
67// Set the SigmaPSF of all mirrors currently stored.
68//
69void MReflector::SetSigmaPSF(Double_t psf)
70{
71 fMirrors.R__FOR_EACH(MMirror, SetSigmaPSF)(psf);
72}
73
74// --------------------------------------------------------------------------
75//
76// Calculate the maximum radius of th ereflector. This is not meant as
77// a precise number but as a rough estimate e.g. to bin a histogram.
78//
79void MReflector::InitMaxR()
80{
81 fMaxR = 0;
82
83 TIter Next(&fMirrors);
84 MMirror *m = 0;
85 while ((m=static_cast<MMirror*>(Next())))
86 {
87 // Take into account the maximum incident angle 8eg 10deg) and
88 // the theta-angle of the mirror and the z-distance.
89 const Double_t r = m->GetDist()+1.5*m->GetMaxR();
90 if (r > fMaxR)
91 fMaxR = r;
92 }
93}
94
95// --------------------------------------------------------------------------
96//
97// Return the total Area of all mirrors. Note, that it is recalculated
98// with any call.
99//
100Double_t MReflector::GetA() const
101{
102 Double_t A = 0;
103
104 TIter Next(&fMirrors);
105 MMirror *m = 0;
106 while ((m=static_cast<MMirror*>(Next())))
107 A += m->GetA();
108
109 return A;
110}
111
112// --------------------------------------------------------------------------
113//
114// Get the pointer to the first mirror. This is a very dangerous way of
115// access, but the fastest possible. because it is the most often called
116// function in ExecuteReflector we have to have a very fast access.
117//
118const MMirror **MReflector::GetFirstPtr() const
119{
120 return (const MMirror**)fMirrors.GetObjectRef(0);
121}
122
123// --------------------------------------------------------------------------
124//
125// Get number of mirrors. There should be no holes in the array!
126//
127const UInt_t MReflector::GetNumMirrors() const
128{
129 return fMirrors.GetEntriesFast();
130}
131
132// --------------------------------------------------------------------------
133//
134// Check with a rough estimate whether a photon can hit the reflector.
135//
136Bool_t MReflector::CanHit(const MQuaternion &p) const
137{
138 // p is given in the reflectory coordinate frame. This is meant as a
139 // fast check without lengthy calculations to omit all photons which
140 // cannot hit the reflector at all
141 return p.R2()<fMaxR*fMaxR;
142}
143
144// --------------------------------------------------------------------------
145//
146// I/O helper for ReadFile to avoid calling "delete arr" before every return
147//
148MMirror *MReflector::EvalTokens(TObjArray &arr, Double_t defpsf) const
149{
150 if (arr.GetEntries()<9)
151 {
152 *fLog << err << "ERROR - Not enough arguments..." << endl;
153 return 0;
154 }
155
156 const TVector3 pos(atof(arr[0]->GetName()),
157 atof(arr[1]->GetName()),
158 atof(arr[2]->GetName()));
159
160 const TVector3 norm(atof(arr[3]->GetName()),
161 atof(arr[4]->GetName()),
162 atof(arr[5]->GetName()));
163
164 const Double_t F = atof(arr[6]->GetName());
165
166 const TString val = arr[7]->GetName();
167
168 const Double_t psf = val.IsFloat() ? val.Atof() : -1;
169
170 const UInt_t n = val.IsFloat() ? 9 : 8;
171
172 TString type = arr[n-1]->GetName();
173 type.Prepend("MMirror");
174
175 for (UInt_t i=0; i<n; i++)
176 delete arr.RemoveAt(i);
177 arr.Compress();
178
179 TString msg;
180 TClass *cls = MParContainer::GetClass(type);
181 if (!cls)
182 {
183 *fLog << err << "ERROR - Class " << type << " not in dictionary." << endl;
184 return 0;
185 }
186
187 if (!cls->InheritsFrom(MMirror::Class()))
188 {
189 *fLog << err << "ERROR - Cannot create new instance of class " << type << ": " << endl;
190 *fLog << "Class doesn't inherit from MMirror." << endl;
191 return 0;
192 }
193
194 MMirror *m = static_cast<MMirror*>(cls->New());
195 if (!m)
196 {
197 *fLog << err << "ERROR - Cannot create new instance of class " << type << ": " << endl;
198 *fLog << " - Class has no default constructor." << endl;
199 *fLog << " - An abstract member functions of a base class is not overwritten." << endl;
200 return 0;
201 }
202
203 m->SetFocalLength(F);
204 m->SetPosition(pos);
205 m->SetNorm(norm);
206 m->SetSigmaPSF(psf>=0 ? psf : defpsf);
207
208 if (m->ReadM(arr)>=0)
209 return m;
210
211 *fLog << err << "ERROR - " << type << "::ReadM failed." << endl;
212
213 delete m;
214 return 0;
215}
216
217// --------------------------------------------------------------------------
218//
219// Read a reflector setup from a file. This needs improvemtn.
220//
221// The file structur is like:
222//
223// x y z nx ny nz F [psf] Type ...
224//
225// x: x-coordinate of the mirror's center
226// y: y-coordinate of the mirror's center
227// z: z-coordinate of the mirror's center
228// nx: x-component of the normal vecor in the mirror center
229// ny: y-component of the normal vecor in the mirror center
230// nz: z-component of the normal vecor in the mirror center
231// F: Focal distance of a spherical mirror
232// [psf]: This number is the psf given in the units of x,y,z and
233// defined at the focal distance F. It can be used to overwrite
234// the second argument given in ReadFile for individual mirrors.
235// Type: A instance of a mirrot of the class Type MMirrorType is created
236// (Type can be, for example, Hex for for MMirrorHex).
237// ...: Additional arguments as defined in MMirrorType::ReadM
238//
239//
240// Coordinate System:
241// The coordinate system is local in the reflectors frame.
242// It is defined viewing from the back side of the reflector
243// towards the camera. (x "right", y "up", z from reflector to camera)
244// Note, that it is left-handed!
245//
246Bool_t MReflector::ReadFile(TString fname, Double_t defpsf)
247{
248 SetTitle(fname);
249 fMirrors.Delete();
250
251 gSystem->ExpandPathName(fname);
252
253 ifstream fin(fname);
254 if (!fin)
255 {
256 *fLog << err << "Cannot open file " << fname << ": ";
257 *fLog << (errno!=0?strerror(errno):"Insufficient memory for decompression") << endl;
258 return kFALSE;
259 }
260
261/*
262 Int_t idx[964];
263 Int_t srt[964];
264 for (int i=0; i<964; i++)
265 srt[i] = gRandom->Integer(964);
266
267 TMath::Sort(964, srt, idx);
268 */
269
270 Int_t cnt = 0;
271
272 while (1)
273 {
274 TString line;
275 line.ReadLine(fin);
276 if (!fin)
277 break;
278
279 // Count lines
280 cnt++;
281
282 // Skip comments
283 if (line.BeginsWith("#"))
284 continue;
285
286 // Remove leading and trailing whitespaces
287 line=line.Strip(TString::kBoth);
288
289 // Skip empty lines
290 if (line.IsNull())
291 continue;
292
293 // Tokenize line
294 TObjArray *arr = line.Tokenize(' ');
295
296 // Evaluate tokens
297 MMirror *m = EvalTokens(*arr, defpsf);
298
299 // Delete now obsolete array
300 delete arr;
301
302 // Check if a new mirror could be created successfully
303 if (!m)
304 {
305 *fLog << err << "Error in line " << cnt << ": " << line << endl;
306 return kFALSE;
307 }
308
309 // Add new mirror to array
310 fMirrors.Add(m);
311 }
312
313 InitMaxR();
314
315 return kTRUE;
316
317// fMirrors.Sort();
318/*
319 for (int i=0; i<964; i++)
320 {
321 MMirror &ref = (MMirror&)*fMirrors[i];
322
323 TArrayD dist(964);
324 for (int j=0; j<964; j++)
325 {
326 const MMirror &mir = (MMirror&)*fMirrors[j];
327 dist[j] = (ref-mir).Mod();
328 }
329
330 TArrayI idx(964);
331 TMath::Sort(964, dist.GetArray(), idx.GetArray(), kFALSE);
332
333 for (int j=0; j<964; j++)
334 {
335 ref.fNeighbors.Add(fMirrors[idx[j]]);
336 }
337 }*/
338}
339
340// --------------------------------------------------------------------------
341//
342// Print the collection of mirrors
343//
344void MReflector::Print(Option_t *o) const
345{
346 *fLog << all << GetDescriptor() << " (" << GetNumMirrors() << "): " << endl;
347
348 fMirrors.Print(o);
349}
350
351// --------------------------------------------------------------------------
352//
353// Paint the collection of mirrors
354//
355void MReflector::Paint(Option_t *o)
356{
357 if (!TString(o).Contains("same", TString::kIgnoreCase))
358 MH::SetPadRange(-fMaxR*1.01, -fMaxR*1.01, fMaxR*1.01, fMaxR*1.01);
359
360 fMirrors.Paint(o);
361
362 TEllipse e;
363 e.SetFillStyle(0);
364 e.SetLineColor(17);
365 e.PaintEllipse(0, 0, fMaxR, fMaxR, 0, 360, 0);
366}
367
368// --------------------------------------------------------------------------
369//
370// SigmaPSF: -1
371// FileName: reflector.txt
372//
373// SigmaPSF can be used to set a default for the psf of the mirrors
374// read from the file. Note, that this can be overwritten for individual
375// mirrors in the file. The SigmaPSF is the sigma of a 1D-Gauss fitted
376// to the radial profile of the light distribution.
377//
378// For details on the file structure see MReflector::ReadFile
379//
380Int_t MReflector::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
381{
382 Bool_t rc = kFALSE;
383
384 Double_t psf = -1;
385 if (IsEnvDefined(env, prefix, "SetSigmaPSF", print))
386 {
387 rc = kTRUE;
388 psf = GetEnvValue(env, prefix, "SetSigmaPSF", -1);
389 }
390
391 if (IsEnvDefined(env, prefix, "FileName", print))
392 {
393 rc = kTRUE;
394 if (!ReadFile(GetEnvValue(env, prefix, "FileName", ""), psf))
395 return kERROR;
396 }
397
398 return rc;
399}
Note: See TracBrowser for help on using the repository browser.