source: trunk/MagicSoft/Mars/mastro/MAstroCatalog.cc@ 3537

Last change on this file since 3537 was 3537, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 20.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, 03/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2002-2004
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MAstroCatalog
28//
29// THIS IMPLEMENTATION IS PRELIMINARY AND WILL BE MERGED WITH
30// SOME PARTS OF THE DRIVE SOFTWARE SOON!
31//
32//////////////////////////////////////////////////////////////////////////////
33#include "MAstroCatalog.h"
34
35#include <fstream>
36#include <stdlib.h>
37
38#include <KeySymbols.h>
39
40#include <TPad.h> // TPad::GetMaxPickDistance
41#include <TLine.h>
42#include <TMarker.h>
43#include <TCanvas.h>
44#include <TArrayI.h>
45#include <TGToolTip.h>
46#include <TRotation.h>
47#include <TStopwatch.h>
48
49#include "MLog.h"
50#include "MLogManip.h"
51
52#include "MTime.h"
53#include "MAstro.h"
54#include "MAstroSky2Local.h"
55#include "MObservatory.h"
56
57ClassImp(MVector3);
58ClassImp(MAstroCatalog);
59
60using namespace std;
61
62class MRotation : public TRotation
63{
64public:
65 MRotation(Double_t gmst, const MObservatory &obs) : TRotation(1, 0, 0, 0, -1, 0, 0, 0, 1)
66 {
67 RotateZ(gmst + obs.GetElong());
68 RotateY(obs.GetPhi()-TMath::Pi()/2);
69 RotateZ(TMath::Pi());
70 }
71 MRotation(const MTime &t, const MObservatory &obs) : TRotation(1, 0, 0, 0, -1, 0, 0, 0, 1)
72 {
73 RotateZ(t.GetGmst() + obs.GetElong());
74 RotateY(obs.GetPhi()-TMath::Pi()/2);
75 RotateZ(TMath::Pi());
76 }
77};
78
79/*
80MVector3 MVector3::GetZdAz(const MObservatory &obs, Double_t gmst) const
81{
82 if (!fType==kIsRaDec)
83 return MVector3();
84
85 MVector3 v(*this);
86 v *= MAstroSky2Local(gmst, obs);
87
88 return v;
89
90 // ------ Using vectors -------
91 // v(1) = -v(1); // phi --> -phi
92 // v.RotateZ(gmst + obs.GetElong()); // -phi --> alpha-phi
93 // v.RotateY(obs.GetPhi()-TMath::Pi()/2);
94 // v.RotateZ(TMath::Pi());
95
96 // ------ The same using slalib, tested in the drive system -------
97 // const Double_t alpha = slaGmst(mjd) + obs.GetElong();
98 // Double_t el;
99 // slaDe2h(fAlpha-ra, dec, obs.GetPhi(), &az, &el);
100 // zd = TMath::Pi()/2-el;
101}
102
103MVector3 MVector3::GetZdAz(const MTime &time, MObservatory &obs) const
104{
105 return GetZdAz(obs, time.GetGmst());
106}
107
108MVector3 MVector3::GetRaDec(const MObservatory &obs, Double_t gmst) const
109{
110 if (!fType==kIsZdAz)
111 return MVector3();
112
113 MVector3 v(*this);
114 v *= MAstroSky2Local(gmst, obs).Inverse();
115
116 return v;
117
118 // ------ Using vectors -------
119 // v.RotateZ(-TMath::Pi());
120 // v.RotateY(TMath::Pi()/2-obs.GetPhi());
121 // v.RotateZ(-gmst - obs.GetElong()); // alpha-phi --> -phi
122 // v(1) = -v(1); // -phi --> phi
123
124 // ------ The same using slalib, tested in the drive system -------
125 // const Double_t alpha = slaGmst(mjd) + obs.GetElong();
126 // Double_t el;
127 // slaDe2h(fAlpha-ra, dec, obs.GetPhi(), &az, &el);
128 // zd = TMath::Pi()/2-el;
129}
130
131MVector3 MVector3::GetRaDec(const MTime &time, MObservatory &obs) const
132{
133 return GetRaDec(obs, time.GetGmst());
134}
135*/
136MAstroCatalog::MAstroCatalog() : fLimMag(99), fRadiusFOV(99), fToolTip(0), fObservatory(0), fTime(0)
137{
138 fList.SetOwner();
139 fToolTip = new TGToolTip(0, "", 0);
140}
141
142MAstroCatalog::~MAstroCatalog()
143{
144 if (fTime)
145 delete fTime;
146 if (fObservatory)
147 delete fObservatory;
148
149 fToolTip->Hide();
150 delete fToolTip;
151
152 DeleteMap();
153
154 // FIXME: There must be an easier way!
155 TIter Next(gROOT->GetListOfCanvases());
156 TCanvas *c;
157 while ((c=(TCanvas*)Next()))
158 c->Disconnect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", this,
159 "EventInfo(Int_t,Int_t,Int_t,TObject*)");
160
161}
162
163TString MAstroCatalog::FindToken(TString &line, Char_t tok)
164{
165 Ssiz_t token = line.First(tok);
166 if (token<0)
167 {
168 const TString copy(line);
169 line = "";
170 return copy;
171 }
172
173 const TString res = line(0, token);
174 line.Remove(0, token+1);
175 return res;
176}
177
178Int_t MAstroCatalog::atoi(const TSubString &sub)
179{
180 return atoi(TString(sub));
181}
182
183Float_t MAstroCatalog::atof(const TSubString &sub)
184{
185 return atof(TString(sub));
186}
187
188Int_t MAstroCatalog::atoi(const TString &s)
189{
190 return std::atoi(s);
191}
192
193Float_t MAstroCatalog::atof(const TString &s)
194{
195 return std::atof(s);
196}
197
198Int_t MAstroCatalog::ReadXephem(TString catalog)
199{
200 SetBit(kHasChanged);
201
202 gLog << inf << "Reading Xephem catalog: " << catalog << endl;
203
204 ifstream fin(catalog);
205
206 Int_t add =0;
207 Int_t cnt =0;
208 Int_t line=0;
209
210 Double_t maxmag=0;
211
212 while (1)
213 {
214 TString row;
215 row.ReadLine(fin);
216 if (!fin)
217 break;
218
219 line++;
220
221 if (row[0]=='#')
222 continue;
223
224 TString line(row);
225
226 TString name = FindToken(line);
227 TString dummy = FindToken(line);
228 TString r = FindToken(line);
229 TString d = FindToken(line);
230 TString m = FindToken(line);
231 TString epoch = FindToken(line);
232
233 if (name.IsNull() || r.IsNull() || d.IsNull() || m.IsNull() || epoch.IsNull())
234 {
235 gLog << warn << "Invalid Entry Line #" << line << ": " << row << endl;
236 continue;
237 }
238
239 cnt++;
240
241 const Double_t mag = atof(m);
242
243 maxmag = TMath::Max(maxmag, mag);
244
245 if (mag>fLimMag)
246 continue;
247
248 if (epoch!="2000")
249 {
250 gLog << warn << "Epoch != 2000... skipped." << endl;
251 continue;
252 }
253
254 Double_t ra0, dec0;
255 MAstro::Coordinate2Angle(r, ra0);
256 MAstro::Coordinate2Angle(d, dec0);
257
258 ra0 *= TMath::Pi()/12;
259 dec0 *= TMath::Pi()/180;
260
261 MVector3 *star=new MVector3;
262 star->SetRaDec(ra0, dec0, mag);
263 star->SetName(name);
264 if (star->Angle(fRaDec)*TMath::RadToDeg()>fRadiusFOV)
265 {
266 delete star;
267 continue;
268 }
269
270 fList.Add(star);
271 add++;
272 }
273 gLog << inf << "Read " << add << " out of " << cnt << " (Total max mag=" << maxmag << ")" << endl;
274
275 return add;
276}
277
278Int_t MAstroCatalog::ReadNGC2000(TString catalog)
279{
280 SetBit(kHasChanged);
281
282 gLog << inf << "Reading NGC2000 catalog: " << catalog << endl;
283
284 ifstream fin(catalog);
285
286 Int_t add=0;
287 Int_t cnt=0;
288 Int_t n =0;
289
290 Double_t maxmag=0;
291
292 while (1)
293 {
294 TString row;
295 row.ReadLine(fin);
296 if (!fin)
297 break;
298
299 cnt++;
300
301 const Int_t rah = atoi(row(13, 2));
302 const Float_t ram = atof(row(16, 4));
303 const Char_t decs = row(22);
304 const Int_t decd = atoi(row(23, 2));
305 const Int_t decm = atoi(row(26, 2));
306 const TString m = row(43, 4);
307
308 if (m.Strip().IsNull())
309 continue;
310
311 n++;
312
313 const Double_t mag = atof(m);
314
315 maxmag = TMath::Max(maxmag, mag);
316
317 if (mag>fLimMag)
318 continue;
319
320 const Double_t ra = MAstro::Hms2Rad(rah, (int)ram, fmod(ram, 1)*60);
321 const Double_t dec = MAstro::Dms2Rad(decd, decm, 0, decs);
322
323 MVector3 *star=new MVector3;
324 star->SetRaDec(ra, dec, mag);
325 star->SetName(row(0, 8));
326 if (star->Angle(fRaDec)*TMath::RadToDeg()>fRadiusFOV)
327 {
328 delete star;
329 continue;
330 }
331
332 fList.Add(star);
333 add++;
334 }
335
336 gLog << inf << "Read " << add << " out of " << n << " (Total max mag=" << maxmag << ")" << endl;
337
338 return add;
339}
340
341Int_t MAstroCatalog::ReadBSC(TString catalog)
342{
343 SetBit(kHasChanged);
344
345 gLog << inf << "Reading Bright Star Catalog (BSC5) catalog: " << catalog << endl;
346
347 ifstream fin(catalog);
348
349 Int_t add=0;
350 Int_t cnt=0;
351 Int_t n =0;
352
353 Double_t maxmag=0;
354
355 while (1)
356 {
357 TString row;
358 row.ReadLine(fin);
359 if (!fin)
360 break;
361
362 cnt++;
363
364 const Int_t rah = atoi(row(75, 2));
365 const Int_t ram = atoi(row(77, 2));
366 const Float_t ras = atof(row(79, 4));
367 const Char_t decsgn = row(83);
368 const Int_t decd = atoi(row(84, 2));
369 const Int_t decm = atoi(row(86, 2));
370 const Int_t decs = atoi(row(88, 2));
371 const TString m = row(102, 5);
372
373 if (m.Strip().IsNull())
374 continue;
375
376 n++;
377
378 const Double_t mag = atof(m.Data());
379
380 maxmag = TMath::Max(maxmag, mag);
381
382 if (mag>fLimMag)
383 continue;
384
385 const Double_t ra = MAstro::Hms2Rad(rah, ram, ras);
386 const Double_t dec = MAstro::Dms2Rad(decd, decm, decs, decsgn);
387
388 MVector3 *star=new MVector3;
389 star->SetRaDec(ra, dec, mag);
390 star->SetName(row(4,9));
391 if (star->Angle(fRaDec)*TMath::RadToDeg()>fRadiusFOV)
392 {
393 delete star;
394 continue;
395 }
396
397 fList.Add(star);
398 add++;
399 }
400
401 gLog << inf << "Read " << add << " out of " << n << " (Total max mag=" << maxmag << ")" << endl;
402
403 return add;
404}
405
406void MAstroCatalog::Paint(Option_t *o)
407{
408// if (!gPad->IsBatch())
409// gVirtualX->ClearWindow();
410
411 if (TestBit(kHasChanged))
412 DrawPrimitives(o);
413}
414
415void MAstroCatalog::DrawStar(Double_t x, Double_t y, const TVector3 &v, Bool_t transparent, const char *txt)
416{
417 const Double_t ra = v.Phi()*TMath::RadToDeg()/15;
418 const Double_t dec = (TMath::Pi()/2-v.Theta())*TMath::RadToDeg();
419
420 TString str = v.GetName();
421 str += Form(": Ra=%.2fh", ra);
422 str += Form(" Dec=%.1fd", dec);
423 str += Form(" Mag=%.1f", -2.5*log10(v.Mag()));
424 if (txt)
425 str += Form(" (%s)", txt);
426
427 // draw star on the camera display
428 TMarker *tip=new TMarker(x, y, transparent ? kDot : kFullDotLarge);;
429 tip->SetMarkerColor(kBlack);
430 tip->SetBit(kCanDelete);
431 tip->SetBit(kCannotPick);
432 AddMap(tip, new TString(str));
433}
434
435void MAstroCatalog::Update()
436{
437 if (gPad && TestBit(kMustCleanup))
438 {
439 SetBit(kHasChanged);
440 gPad->Modified();
441 }
442}
443
444void MAstroCatalog::SetTime(const MTime &time)
445{
446 if (fTime)
447 delete fTime;
448 fTime=(MTime*)time.Clone();
449}
450
451void MAstroCatalog::SetObservatory(const MObservatory &obs)
452{
453 if (fObservatory)
454 delete fObservatory;
455 fObservatory=(MObservatory*)obs.Clone();
456}
457
458Int_t MAstroCatalog::ConvertToPad(const TVector3 &w0, TVector2 &v)
459{
460 TVector3 w(w0);
461
462 // Stretch such, that the X-component is alwas the same. Now
463 // Y and Z contains the crossing point between the star-light
464 // and the plain of a virtual screen (ccd...)
465 if (TestBit(kPlainScreen))
466 w *= TMath::RadToDeg()/w.X();
467 else
468 w.SetMag(TMath::RadToDeg());
469
470 v.Set(w(1), w(2));
471
472 if (w(0)<0)
473 return kERROR;
474
475 return w(1)>gPad->GetX1() && w(2)>gPad->GetY1() &&
476 w(1)<gPad->GetX2() && w(2)<gPad->GetY2();
477}
478
479Int_t MAstroCatalog::Convert(const TRotation &rot, TVector2 &v)
480{
481 MVector3 w;
482 w.SetMagThetaPhi(1, v.Y(), v.X());
483 w *= rot;
484
485 return ConvertToPad(w, v);
486}
487
488Bool_t MAstroCatalog::DrawLine(const TVector2 &v, Double_t dx, Double_t dy, const TRotation &rot, Int_t type)
489{
490 const TVector2 add(dx*TMath::DegToRad(), dy*TMath::DegToRad());
491
492 TVector2 v0 = v;
493 TVector2 v1 = v+add;
494
495 const Int_t rc0 = Convert(rot, v0);
496 const Int_t rc1 = Convert(rot, v1);
497
498 // Both are kFALSE or both are kERROR
499 if ((rc0|rc1)==kFALSE || (rc0&rc1)==kERROR)
500 return kFALSE;
501
502 TLine *line = new TLine(v0.X(), v0.Y(), v1.X(), v1.Y());
503 line->SetBit(kCanDelete);
504 line->SetLineStyle(kDashDotted); //kDashed, kDotted, kDashDotted
505 line->SetLineColor(kWhite+type*2);
506 line->SetBit(kCannotPick);
507 AddMap(line);
508
509 const TVector2 deg = v*TMath::RadToDeg();
510 TString txt = type==1 ?
511 Form("Ra=%.1fh Dec=%.1fd", fmod(deg.X()/15+48, 24), fmod(90-deg.Y()+270,180)-90) :
512 Form("Zd=%.1fd Az=%.1fd", fmod(deg.Y()+270,180)-90, fmod(deg.X()+720, 360));
513
514 TMarker *tip=new TMarker(v0.X(), v0.Y(), kDot);
515 tip->SetBit(kCanDelete);
516 tip->SetBit(kCannotPick);
517 tip->SetMarkerColor(kWhite+type*2);
518 AddMap(tip, new TString(txt));
519
520 return kTRUE;
521}
522
523
524void MAstroCatalog::Draw(const TVector2 &v0, const TRotation &rot, TArrayI &dx, TArrayI &dy, Int_t stepx, Int_t stepy, Int_t type)
525{
526 const TVector2 v1 = v0 + TVector2(dx[0]*TMath::DegToRad(), dy[0]*TMath::DegToRad());
527
528 Int_t idx[] = {1, 1, 1, 1};
529
530 Int_t dirs[4][2] = { {0, stepy}, {stepx, 0}, {0, -stepy}, {-stepx, 0} };
531
532 for (int i=0; i<dx.GetSize(); i++)
533 {
534 for (int j=0; j<4; j++)
535 {
536 const Bool_t rcx0 = (dx[i]+720)%360==(dx[0]+dirs[j][0]+720)%360;
537 const Bool_t rcy0 = (dy[i]+360)%180==(dy[0]+dirs[j][1]+360)%180;
538 if (rcx0&&rcy0)
539 idx[j] = 0;
540 }
541 }
542
543 // Enhance size of array by 1, copy current
544 // position as last entry
545 dx.Set(dx.GetSize()+1);
546 dy.Set(dy.GetSize()+1);
547
548 dx[dx.GetSize()-1] = dx[0];
549 dy[dy.GetSize()-1] = dy[0];
550
551 // Store current positon
552 const Int_t d[2] = { dx[0], dy[0] };
553
554 for (int i=0; i<4; i++)
555 if (idx[i])
556 {
557 // Calculate new position
558 dx[0] = d[0]+dirs[i][0];
559 dy[0] = d[1]+dirs[i][1];
560
561 //cout << dx[0] << " " << dy[0] << endl;
562
563 // Draw corresponding line and iterate through grid
564 if (DrawLine(v1, dirs[i][0], dirs[i][1], rot, type))
565 Draw(v0, rot, dx, dy, stepx, stepy, type);
566
567 dx[0]=d[0];
568 dy[0]=d[1];
569 }
570}
571
572void MAstroCatalog::DrawNet(const TVector2 &v0, const TRotation &rot, Int_t type)
573{
574 TArrayI dx(1);
575 TArrayI dy(1);
576
577 // align to 1deg boundary
578 TVector2 v = v0*TMath::RadToDeg();
579 v.Set((Float_t)TMath::Nint(v.X()), (Float_t)TMath::Nint(v.Y()));
580
581 // calculate stepsizes based on visible FOV
582 Int_t stepx=1;
583
584 if (fabs(90-v.Y())>90-fRadiusFOV || fabs(90-v.Y())<fRadiusFOV)
585 stepx = 180/10;
586 else
587 {
588 // This is a rough estimate how many degrees are visible
589 const Float_t m = log(fRadiusFOV/180.)/log(90./fRadiusFOV-1);
590 const Float_t t = log(180.)-m*log(fRadiusFOV);
591 const Int_t n = (Int_t)(exp(m*log(90-fabs(90-v.Y()))+t)+0.5);
592 stepx = n<6 ? 1 : n/6;
593 }
594
595 const Int_t n = (Int_t)(fRadiusFOV+1);
596 Int_t stepy = n<4 ? 1 : n/4;
597
598 // align stepsizes to be devisor or 180 and 90
599 while (180%stepx)
600 stepx++;
601 while (90%stepy)
602 stepy++;
603
604 // align to step-size boundary
605 while ((int)(v.X())%stepx)
606 v.Set(v.X()+1, v.Y());
607
608 while ((int)(v.Y())%stepy)
609 v.Set(v.X(), v.Y()+1);
610
611 // draw...
612 v *= TMath::DegToRad();
613
614 Draw(v, rot, dx, dy, stepx, stepy, type);
615}
616
617void MAstroCatalog::AddPrimitives(Option_t *o)
618{
619 // Precalc Sin/Cos...
620 TRotation trans;
621 trans.RotateZ(-fRaDec.Phi());
622 trans.Rotate(TMath::Pi()/2-fRaDec.Theta(), TVector3(0, 1, 0));
623
624 if (fTime && fObservatory)
625 {
626 const TRotation rot(MAstroSky2Local(*fTime, *fObservatory));
627 const TVector3 zdaz0 = rot*fRaDec;
628 const TVector2 zdaz(zdaz0.Phi(), zdaz0.Theta());
629 DrawNet(zdaz, trans*rot.Inverse(), 2);
630 }
631
632 const TVector2 radec(fRaDec.Phi(), fRaDec.Theta());
633 DrawNet(radec, trans, 1);
634
635 TIter Next(&fList);
636 TVector3 *v=0;
637 while ((v=(TVector3*)Next()))
638 {
639 // FIXME: Check Magnitude!
640 TVector2 s(v->Phi(), v->Theta());
641 if (Convert(trans, s)==kTRUE)
642 DrawStar(s.X(), TMath::Pi()/2-s.Y(), *v, kFALSE);
643 }
644}
645
646void MAstroCatalog::SetRangePad()
647{
648 const Double_t edge = fRadiusFOV/TMath::Sqrt(2.);
649 gPad->Range(-edge, -edge, edge, edge);
650
651 const Float_t w = gPad->GetWw();
652 const Float_t h = gPad->GetWh();
653
654 if (w<h)
655 gPad->Range(-edge, -edge*h/w, edge, edge*h/w);
656 else
657 gPad->Range(-edge*w/h, -edge, edge*w/h, edge);
658}
659
660void MAstroCatalog::DrawPrimitives(Option_t *o)
661{
662 DeleteMap();
663
664 SetRangePad();
665
666 TStopwatch clk;
667 clk.Start();
668 AddPrimitives(o);
669 clk.Stop();
670 clk.Print();
671
672 // Append to a possible second pad
673 if (!gPad->GetListOfPrimitives()->FindObject(this))
674 AppendPad(o);
675
676 // Append all objects to pad
677 DrawMap();
678
679 ResetBit(kHasChanged);
680}
681
682void MAstroCatalog::DrawMap()
683{
684 Long_t key, val;
685 TExMapIter map(&fMapG);
686 while (map.Next(key, val))
687 ((TObject*)key)->Draw();
688}
689
690void MAstroCatalog::Draw(Option_t *o)
691{
692 // Append to first pad
693 AppendPad(o);
694
695 // If contents have not previously changed make sure that
696 // all primitives are recreated.
697 if (!TestBit(kHasChanged))
698 DrawPrimitives(o);
699
700 // Connect all TCanvas::ProcessedEvent to this->EventInfo
701 // This means, that after TCanvas has processed an event
702 // EventInfo of this class is called, see TCanvas::HandleInput
703 gPad->GetCanvas()->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
704 "MAstroCatalog", this,
705 "EventInfo(Int_t,Int_t,Int_t,TObject*)");
706
707 // Do this instead of fListG.Draw, because
708 // TCollection overwrites Draw
709 // Would be nice, but doesn't work because the single
710 // graphical object are not handled by TPad anymore...
711 // fListG.AppendPad();
712}
713
714// --------------------------------------------------------------------------
715//
716// This function was connected to all created canvases. It is used
717// to redirect GetObjectInfo into our own status bar.
718//
719// The 'connection' is done in AddTab
720//
721void MAstroCatalog::EventInfo(Int_t event, Int_t px, Int_t py, TObject *selected)
722{
723 TCanvas *c = (TCanvas*)gTQSender;
724
725 gPad = c ? c->GetSelectedPad() : NULL;
726 if (!gPad)
727 return;
728
729 // Try to find a corresponding object with kCannotPick set and
730 // an available TString (for a tool tip)
731 TString *str=0;
732 if (!selected || selected==this)
733 {
734 Long_t key, val;
735 TExMapIter map(&fMapG);
736 while (map.Next(key, val))
737 {
738 if (!val)
739 continue;
740
741 TObject *o=(TObject*)key;
742 if (o->DistancetoPrimitive(px, py)>TPad::GetMaxPickDistance())
743 continue;
744
745 selected = o;
746 str = (TString*)val;
747 break;
748 }
749 }
750
751 if (!selected)
752 return;
753
754 switch (event)
755 {
756 case kMouseMotion:
757 if (!fToolTip->IsMapped() && str)
758 ShowToolTip(px, py, *str);
759 break;
760
761 case kMouseLeave:
762 if (fToolTip->IsMapped())
763 fToolTip->Hide();
764 break;
765
766 case kKeyPress:
767 ExecuteEvent(kKeyPress, px, py);
768 break;
769 }
770}
771
772void MAstroCatalog::ExecuteEventKbd(Int_t keycode, Int_t keysym)
773{
774 Double_t dra =0;
775 Double_t ddec=0;
776
777 switch (keysym)
778 {
779 case kKey_Left:
780 dra = -TMath::DegToRad();
781 break;
782 case kKey_Right:
783 dra = +TMath::DegToRad();
784 break;
785 case kKey_Up:
786 ddec = +TMath::DegToRad();
787 break;
788 case kKey_Down:
789 ddec = -TMath::DegToRad();
790 break;
791 case kKey_Plus:
792 SetRadiusFOV(fRadiusFOV+1);
793 break;
794 case kKey_Minus:
795 SetRadiusFOV(fRadiusFOV-1);
796 break;
797
798 default:
799 return;
800 }
801
802 const Double_t r = fRaDec.Phi();
803 const Double_t d = TMath::Pi()/2-fRaDec.Theta();
804
805 SetRaDec(r+dra, d+ddec);
806
807 gPad->Update();
808}
809
810// ------------------------------------------------------------------------
811//
812// Execute a gui event on the camera
813//
814void MAstroCatalog::ExecuteEvent(Int_t event, Int_t mp1, Int_t mp2)
815{
816 if (!TestBit(kGuiActive))
817 return;
818
819 if (event==kKeyPress)
820 ExecuteEventKbd(mp1, mp2);
821}
822
823Int_t MAstroCatalog::DistancetoPrimitive(Int_t px, Int_t py)
824{
825 Int_t min = INT_MAX;
826
827 Long_t key, val;
828 TExMapIter map(&fMapG);
829 while (map.Next(key, val))
830 {
831 TObject *o=(TObject*)key;
832
833 const Int_t d = o->DistancetoPrimitive(px, py);
834
835 if (d<TPad::GetMaxPickDistance())
836 return 0;
837
838 if (d<min)
839 min=d;
840 }
841
842 return min;
843}
844
845void MAstroCatalog::ShowToolTip(Int_t px, Int_t py, const char *txt)
846{
847 Int_t x=0;
848 Int_t y=0;
849
850 const Window_t id1 = gVirtualX->GetWindowID(gPad->GetCanvasID());
851 const Window_t id2 = fToolTip->GetParent()->GetId();
852
853 Window_t id3;
854 gVirtualX->TranslateCoordinates(id1, id2, px, py, x, y, id3);
855
856 // Show tool tip
857 fToolTip->SetText(txt);
858 fToolTip->Show(x+4, y+4);
859}
860
Note: See TracBrowser for help on using the repository browser.