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

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