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

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