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

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