source: trunk/MagicSoft/Mars/mastro/MAstroCamera.cc@ 3780

Last change on this file since 3780 was 3710, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 9.8 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, 3/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MAstroCamera
28// ============
29//
30// A tools displaying stars from a catalog in the camera display.
31// PRELIMINARY!!
32//
33//
34// Usage:
35// ------
36// For a usage example see macros/starfield.C
37//
38// To be able to reflect the star-light you need the geometry of the
39// mirror and the distance of the plain screen.
40//
41// You can get the mirror geometry from a MC file and the distance of
42// the screen from MGeomCam.
43//
44//
45// Algorithm:
46// ----------
47// The caluclation of the position of the reflection in the camera is
48// done by:
49// - Rotation of the star-field such that the camera is looking into
50// the pointing direction
51// - Calculation of the reflected star-light vector by calling
52// MGeomMirror::GetReflection (which returns the point at which
53// the vector hits the camera plain)
54// - Depending on the draw-option you get each reflected point, the
55// reflection on a virtual ideal mirror or the reflection on each
56// individual mirror
57//
58//
59// GUI:
60// ----
61// * You can use the the cursor keys to change the pointing position
62// and plus/minus to change the time by a quarter of an hour.
63//
64// ToDo:
65// -----
66// * possibility to overwrite distance from mirror to screen
67// * read the mirror geometry directly from the MC input file
68//
69/////////////////////////////////////////////////////////////////////////////
70#include "MAstroCamera.h"
71
72#include <KeySymbols.h> // kKey_*
73
74#include <TH2.h> // TH2D
75#include <TMarker.h> // TMarker
76#include <TVirtualPad.h> // gPad
77
78#include "MLog.h"
79#include "MLogManip.h"
80
81#include "MGeomCam.h"
82#include "MGeomMirror.h"
83
84#include "MTime.h"
85#include "MAstroSky2Local.h"
86#include "MObservatory.h"
87
88#include "../mhist/MHCamera.h" // FIXME: This dependancy is very bad!
89 // HOW TO GET RID OF IT? Move MHCamera to mgeom?
90
91ClassImp(MAstroCamera);
92
93using namespace std;
94
95// --------------------------------------------------------------------------
96//
97// Create a virtual MGeomMirror which is in the center of the coordinate
98// system and has a normal vector in z-direction.
99//
100MAstroCamera::MAstroCamera() : fGeom(0), fMirrors(0)
101{
102 fMirror0 = new MGeomMirror;
103 fMirror0->SetMirrorContent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
104}
105
106// --------------------------------------------------------------------------
107//
108// Delete fGeom, fMirrors and the virtual 0-Mirror fMirror0
109//
110MAstroCamera::~MAstroCamera()
111{
112 if (fGeom)
113 delete fGeom;
114 if (fMirrors)
115 delete fMirrors;
116
117 delete fMirror0;
118}
119
120// --------------------------------------------------------------------------
121//
122// Set a list of mirrors. The Mirrors must be of type MGeomMirror and
123// stored in a TClonesArray
124//
125void MAstroCamera::SetMirrors(TClonesArray &arr)
126{
127 if (arr.GetClass()!=MGeomMirror::Class())
128 {
129 cout << "ERROR - TClonesArray doesn't contain objects of type MGeomMirror... ignored." << endl;
130 return;
131 }
132
133 const Int_t n = arr.GetSize();
134
135 if (!fMirrors)
136 fMirrors = new TClonesArray(MGeomMirror::Class(), n);
137
138 fMirrors->ExpandCreate(n);
139
140 for (int i=0; i<n; i++)
141 memcpy((*fMirrors)[i], arr[i], sizeof(MGeomMirror));
142
143}
144
145// --------------------------------------------------------------------------
146//
147// Set the camera geometry. The MGeomCam object is cloned.
148//
149void MAstroCamera::SetGeom(const MGeomCam &cam)
150{
151 if (fGeom)
152 delete fGeom;
153
154 fGeom = (MGeomCam*)cam.Clone();
155}
156
157// --------------------------------------------------------------------------
158//
159// Convert To Pad coordinates (see MAstroCatalog)
160//
161Int_t MAstroCamera::ConvertToPad(const TVector3 &w, TVector2 &v) const
162{
163 /*
164 --- Use this to plot the 'mean grid' instead of the grid of a
165 theoretical central mirror ---
166
167 TVector3 spot;
168 const Int_t num = fConfig->GetNumMirror();
169 for (int i=0; i<num; i++)
170 spot += fConfig->GetMirror(i).GetReflection(w, fGeom->GetCameraDist())*1000;
171 spot *= 1./num;
172 */
173
174 const TVector3 spot = fMirror0->GetReflection(w, fGeom->GetCameraDist())*1000;
175 v.Set(spot(0), spot(1));
176
177 const Float_t max = fGeom->GetMaxRadius()*0.70;
178 return v.X()>-max && v.Y()>-max && v.X()<max && v.Y()<max;
179}
180
181// --------------------------------------------------------------------------
182//
183// Find an object with a given name in the list of primitives of this pad.
184//
185TObject *FindObjectInPad(const char *name, TVirtualPad *pad)
186{
187 if (!pad)
188 pad = gPad;
189
190 if (!pad)
191 return NULL;
192
193 TObject *o;
194
195 TIter Next(pad->GetListOfPrimitives());
196 while ((o=Next()))
197 {
198 if (o->InheritsFrom(gROOT->GetClass(name)))
199 return o;
200
201 if (o->InheritsFrom("TPad"))
202 if ((o = FindObjectInPad(name, (TVirtualPad*)o)))
203 return o;
204 }
205 return NULL;
206}
207
208// --------------------------------------------------------------------------
209//
210// Options:
211//
212// '*' Draw the mean of the reflections on all mirrors
213// '.' Draw a dot for the reflection on each individual mirror
214// 'h' To create a TH2D of the star-light which is displayed
215// 'c' Use the underlaying MHCamera as histogram
216// '0' Draw the reflection on a virtual perfect mirror
217//
218// If the Pad contains an object MHCamera of type MHCamera it is used.
219// Otherwise a new object is created.
220//
221void MAstroCamera::AddPrimitives(TString o)
222{
223 if (!fTime || !fObservatory || !fMirrors)
224 {
225 cout << "Missing data..." << endl;
226 return;
227 }
228
229 if (o.IsNull())
230 o = "*.";
231
232 const Bool_t hasnull = o.Contains("0", TString::kIgnoreCase);
233 const Bool_t hashist = o.Contains("h", TString::kIgnoreCase);
234 const Bool_t hasmean = o.Contains("*", TString::kIgnoreCase);
235 const Bool_t hasdot = o.Contains(".", TString::kIgnoreCase);
236 const Bool_t usecam = o.Contains("c", TString::kIgnoreCase);
237
238 // Get camera
239 MHCamera *camera=(MHCamera*)FindObjectInPad("MHCamera", gPad);
240 if (camera)
241 {
242 if (!camera->GetGeometry() || camera->GetGeometry()->IsA()!=fGeom->IsA())
243 camera->SetGeometry(*fGeom);
244 }
245 else
246 {
247 camera = new MHCamera(*fGeom);
248 camera->SetName("MHCamera");
249 camera->SetStats(0);
250 camera->SetInvDeepBlueSeaPalette();
251 camera->SetBit(kCanDelete);
252 camera->Draw();
253 }
254
255 camera->SetTitle(GetPadTitle());
256
257 gPad->cd(1);
258
259 if (!usecam)
260 {
261 if (camera->GetEntries()==0)
262 camera->SetBit(MHCamera::kNoLegend);
263 }
264 else
265 {
266 camera->Reset();
267 camera->SetYTitle("arb.cur");
268 }
269
270 TH2 *h=0;
271 if (hashist)
272 {
273 TH2F hist("","", 90, -650, 650, 90, -650, 650);
274 hist.SetMinimum(0);
275 h = (TH2*)hist.DrawCopy("samecont1");
276 }
277
278 const TRotation rot(GetGrid(kTRUE));
279
280 MVector3 *radec;
281 TIter Next(&fList);
282
283 while ((radec=(MVector3*)Next()))
284 {
285 const Double_t mag = radec->Magnitude();
286
287 TVector3 star(*radec);
288
289 // Rotate Star into telescope system
290 star *= rot;
291
292 TVector3 mean;
293
294 Int_t num = 0;
295
296 MGeomMirror *mirror = 0;
297 TIter NextM(fMirrors);
298 while ((mirror=(MGeomMirror*)NextM()))
299 {
300 const TVector3 spot = mirror->GetReflection(star, fGeom->GetCameraDist())*1000;
301
302 // calculate mean of all 'stars' hitting the camera plane
303 // by taking the sum of the intersection points between
304 // the light vector and the camera plane
305 mean += spot;
306
307 if (hasdot)
308 {
309 TMarker *m=new TMarker(spot(0), spot(1), 1);
310 m->SetMarkerColor(kMagenta);
311 m->SetMarkerStyle(kDot);
312 AddMap(m);
313 }
314 if (h)
315 h->Fill(spot(0), spot(1), pow(10, -mag/2.5));
316
317 if (usecam)
318 camera->Fill(spot(0), spot(1), pow(10, -mag/2.5));
319
320 num++;
321 }
322
323 // transform meters into millimeters (camera display works with mm)
324 mean *= 1./num;
325 DrawStar(mean(0), mean(1), *radec, !hasmean, Form("x=%.1fmm y=%.1fmm", mean(0), mean(1)));
326
327 if (hasnull)
328 {
329 TVector3 star(*radec);
330 star *= rot;
331 const TVector3 spot = fMirror0->GetReflection(star, fGeom->GetCameraDist())*1000;
332 DrawStar(spot(0), spot(1), *radec, !hasmean, Form("x=%.1fmm y=%.1fmm", mean(0), mean(1)));
333 }
334 }
335}
336
337// ------------------------------------------------------------------------
338//
339// Execute a gui event on the camera
340//
341void MAstroCamera::ExecuteEvent(Int_t event, Int_t mp1, Int_t mp2)
342{
343 if (event==kKeyPress && fTime)
344 switch (mp2)
345 {
346 case kKey_Plus:
347 fTime->SetMjd(fTime->GetMjd()+0.25/24);
348 Update(kTRUE);
349 return;
350
351 case kKey_Minus:
352 fTime->SetMjd(fTime->GetMjd()-0.25/24);
353 Update(kTRUE);
354 return;
355 }
356
357 MAstroCatalog::ExecuteEvent(event, mp1, mp2);
358}
Note: See TracBrowser for help on using the repository browser.