source: trunk/MagicSoft/Cosy/main/MStarguider.cc@ 7791

Last change on this file since 7791 was 7791, checked in by Daniela Dorner, 18 years ago
*** empty log message ***
File size: 64.1 KB
Line 
1#undef EXPERT
2#undef EXPERT
3
4#include "MStarguider.h"
5
6#include <fstream.h> // ifstream
7#include <iostream.h> // cout
8#include <iomanip.h> // cout
9
10#include <TH2F.h>
11#include <TGraph.h>
12#include <TTimer.h>
13#include <TSystem.h>
14#include <TFile.h> // temp writeout of histos
15#include <TSocket.h>
16
17#include "MAstro.h"
18#include "MString.h"
19
20#include <TGMenu.h>
21#include <TGLabel.h>
22#include <TGButton.h>
23#include <TGSplitter.h> // TGHorizontal3DLine
24#include <TGTextEntry.h>
25#include <TGLayout.h>
26#include "MString.h"
27
28#include "MCosy.h"
29#include "MCaos.h"
30// #include "MStargLeds.h"
31#include "MStargHistograms.h"
32#include "MDriveCom.h"
33
34#include "MGStarg.h"
35#include "MGNumStars.h"
36#include "TGFrame.h"
37
38#include "MGImage.h"
39#include "MGCoordinates.h"
40
41#include "coord.h"
42
43#include "Camera.h"
44#include "PngReader.h"
45
46#include "Led.h"
47#include "Writer.h"
48#include "FilterLed.h"
49#include "MStarList.h"
50#include "CaosFilter.h"
51#include "StarCatalog.h"
52#include "MGeomCamMagic.h"
53#include "MAstroCamera.h"
54
55#include "MGMenu.h"
56#include "MGCosy.h"
57
58ClassImp(MStarguider);
59
60enum {
61 IDM_kFilter,
62 IDM_kFindStar,
63 IDM_kCaosFilter,
64 IDM_kCatalog,
65 IDM_kStarguider,
66 IDM_kStart,
67 IDM_kStop,
68 IDM_kFileType,
69 IDM_kPPM,
70 IDM_kPNG,
71 IDM_kOnce,
72 IDM_kStretch,
73 IDM_kInput,
74 IDM_kChannel1,
75 IDM_kChannel2,
76 IDM_kChannel3,
77 IDM_kContinous,
78 IDM_kRate25ps,
79 IDM_kRate5ps,
80 IDM_kRate1s,
81 IDM_kRate5s,
82 IDM_kRate30s,
83 IDM_kRate1m,
84 IDM_kRate5m,
85 IDM_kSetup,
86 IDM_kLimMag3,
87 IDM_kLimMag4,
88 IDM_kLimMag5,
89 IDM_kLimMag6,
90 IDM_kLimMag7,
91 IDM_kLimMag8,
92 IDM_kLimMag9,
93 IDM_kPixSize,
94 IDM_kAngle,
95 IDM_kCut,
96 IDM_kInterpol250,
97 IDM_kInterpol125,
98 IDM_kInterpol50,
99 IDM_kInterpol25,
100 IDM_kInterpol10,
101 IDM_kInterpol5,
102 IDM_kInterpol2,
103 IDM_kInterpol1,
104 IDM_kCaosPrintRings,
105 IDM_kCaosPrintLeds,
106 IDM_kCaosAnalStart,
107 IDM_kCaosAnalStop,
108 IDM_kCaosWriteStart,
109 IDM_kCaosWriteStop,
110 IDM_kResetHistograms,
111 IDM_kStargAnalysis,
112 IDM_kStargCaosFilter,
113 IDM_kStargFindStar,
114 IDM_kRoqueLampAna,
115 IDM_kStarguiderMode,
116 IDM_kTpointMode
117
118};
119
120Bool_t MStarguider::HandleTimer(TTimer *t)
121{
122 if (IsMapped())
123 {
124 fImage->DoRedraw();
125 fZoomImage->DoRedraw();
126 }
127
128 if (fCosy && fCosy->GetWin()->IsMapped())
129 fCosy->GetWin()->GetImage()->DoRedraw();
130
131 fGStarg->Update(fPos, fD);
132 fGNumStars->Update(fNumStarsDetected, fNumStarsCorrelated);
133
134 return kTRUE;
135}
136
137#define kZOOM 96
138
139XY MStarguider::GetCoordinates() const
140{
141 return fPZdAz->GetCoordinates();
142}
143
144void MStarguider::InitGui(Int_t channel)
145{
146 fList = new MGList;
147
148 const TGWindow *p=gClient->GetRoot();
149
150 fChannel = new MGPopupMenu(p);
151 fChannel->AddEntry("Starfield Camera", IDM_kChannel1);
152 fChannel->AddEntry("TPoint Camera", IDM_kChannel2);
153 fChannel->AddEntry("Read from File", IDM_kChannel3);
154 if (channel<0)
155 fChannel->CheckEntry(IDM_kChannel3);
156 else
157 fChannel->CheckEntry(channel==0?IDM_kChannel1:IDM_kChannel2);
158 fChannel->Associate(this);
159 fList->Add(fChannel);
160
161 //
162 // Create Menu for MStarguider Display
163 //
164 fDisplay = new MGPopupMenu(p);
165 fDisplay->AddEntry("&Filter", IDM_kFilter);
166 fDisplay->AddEntry("Stretch", IDM_kStretch);
167 fDisplay->AddSeparator();
168 fDisplay->AddEntry("Find &Star", IDM_kFindStar);
169 fDisplay->AddEntry("C&aos Filter", IDM_kCaosFilter);
170 fDisplay->AddSeparator();
171 fDisplay->AddEntry("SAO &Catalog", IDM_kCatalog);
172 fDisplay->AddEntry("Starguider", IDM_kStarguider);
173 fDisplay->AddEntry("Starguider LED Filter", IDM_kStargCaosFilter);
174 fDisplay->AddEntry("Starguider Find Star", IDM_kStargFindStar);
175 fDisplay->AddSeparator();
176 if (channel>=0)
177 fDisplay->AddPopup("&Input", fChannel);
178 fDisplay->DisableEntry(IDM_kStargFindStar);
179 fDisplay->CheckEntry(IDM_kStretch);
180 fDisplay->Associate(this);
181 fList->Add(fDisplay);
182
183 fMode = new MGPopupMenu(p);
184 fMode->AddEntry("Starguider", IDM_kStarguiderMode);
185 fMode->AddEntry("Tpoint", IDM_kTpointMode);
186 fMode->Associate(this);
187 fList->Add(fMode);
188
189 fOperations = new MGPopupMenu(p);
190 fOperations->AddEntry("Roque Lamp Analysis", IDM_kRoqueLampAna);
191 fOperations->AddEntry("Starguider Analysis", IDM_kStargAnalysis);
192 fOperations->DisableEntry(IDM_kStargAnalysis);
193 fOperations->Associate(this);
194 fList->Add(fOperations);
195
196
197 fFileType = new MGPopupMenu(p);
198 fFileType->AddEntry("PP&M", IDM_kPPM);
199 fFileType->AddEntry("&PNG", IDM_kPNG);
200 fFileType->CheckEntry(IDM_kPNG);
201 fFileType->Associate(this);
202 fList->Add(fFileType);
203
204 fWriteType = new MGPopupMenu(p);
205 fWriteType->AddEntry("&Once", IDM_kOnce);
206 fWriteType->AddEntry("&Continous", IDM_kContinous);
207 fWriteType->CheckEntry(IDM_kOnce);
208 fWriteType->Associate(this);
209 fList->Add(fWriteType);
210
211 fWriteRate = new MGPopupMenu(p);
212 fWriteRate->AddEntry("25/s", IDM_kRate25ps);
213 fWriteRate->AddEntry("5/s", IDM_kRate5ps);
214 fWriteRate->AddEntry("1s", IDM_kRate1s);
215 fWriteRate->AddEntry("5s", IDM_kRate5s);
216 fWriteRate->AddEntry("30s", IDM_kRate30s);
217 fWriteRate->AddEntry("1min", IDM_kRate1m);
218 fWriteRate->AddEntry("5min", IDM_kRate5m);
219 fWriteRate->CheckEntry(IDM_kRate1m);
220 fWriteRate->Associate(this);
221 fList->Add(fWriteRate);
222
223 fWrtRate = 25*60;
224
225 fWritePictures = new MGPopupMenu(p);
226 fWritePictures->AddEntry("&Start", IDM_kStart);
227 fWritePictures->AddEntry("Sto&p", IDM_kStop);
228 fWritePictures->AddSeparator();
229 fWritePictures->AddPopup("File &Type", fFileType);
230 fWritePictures->AddPopup("&Write Type", fWriteType);
231 fWritePictures->AddPopup("Write &Rate", fWriteRate);
232 fWritePictures->DisableEntry(IDM_kStop);
233 fWritePictures->Associate(this);
234 fList->Add(fWritePictures);
235
236 fLimMag = new MGPopupMenu(p);
237 fLimMag->AddEntry("3", IDM_kLimMag3);
238 fLimMag->AddEntry("4", IDM_kLimMag4);
239 fLimMag->AddEntry("5", IDM_kLimMag5);
240 fLimMag->AddEntry("6", IDM_kLimMag6);
241 fLimMag->AddEntry("7", IDM_kLimMag7);
242 fLimMag->AddEntry("8", IDM_kLimMag8);
243 fLimMag->AddEntry("9", IDM_kLimMag9);
244 fLimMag->CheckEntry(IDM_kLimMag9);
245 fLimMag->Associate(this);
246 fList->Add(fLimMag);
247
248 fSao->SetLimitMag(9.0);
249
250 fInterpol = new MGPopupMenu(p);
251 fInterpol->AddEntry("250", IDM_kInterpol250);
252 fInterpol->AddEntry("125", IDM_kInterpol125);
253 fInterpol->AddEntry("50", IDM_kInterpol50);
254 fInterpol->AddEntry("25", IDM_kInterpol25);
255 fInterpol->AddEntry("10", IDM_kInterpol10);
256 fInterpol->AddEntry("5", IDM_kInterpol5);
257 fInterpol->AddEntry("2", IDM_kInterpol2);
258 fInterpol->AddEntry("Off", IDM_kInterpol1);
259 fInterpol->Associate(this);
260 fList->Add(fInterpol);
261
262 TString disp=gVirtualX->DisplayName();
263 cout << "Display: " << disp << endl;
264 if (disp.First(':')>=0)
265 disp=disp(0, disp.First(':'));
266
267 if (disp.IsNull() || disp==(TString)"localhost")
268 {
269 fInterpol->CheckEntry(IDM_kInterpol5);
270 fIntRate = 50;
271 }
272 else
273 {
274 fInterpol->CheckEntry(IDM_kInterpol125);
275 fIntRate = 125;
276 }
277
278 fSetup = new MGPopupMenu(p);
279 fSetup->AddPopup("Lim. &Magnitude", fLimMag);
280 fSetup->AddPopup("Disp. &Interpolation", fInterpol);
281 //fSetup->AddEntry("Use Ra/Dec from file", IDM_kUseFileRaDec);
282 fSetup->Associate(this);
283 fList->Add(fSetup);
284
285 fCaosPrint = new MGPopupMenu(p);
286 fCaosPrint->AddEntry("&Leds", IDM_kCaosPrintLeds);
287 fCaosPrint->AddEntry("&Rings", IDM_kCaosPrintRings);
288 fCaosPrint->Associate(this);
289 fList->Add(fCaosPrint);
290
291 fCaosWrite = new MGPopupMenu(p);
292 fCaosWrite->AddEntry("&Start", IDM_kCaosWriteStart);
293 fCaosWrite->AddEntry("Sto&p", IDM_kCaosWriteStop);
294 fCaosWrite->DisableEntry(IDM_kCaosWriteStop);
295 fCaosWrite->Associate(this);
296 fList->Add(fCaosWrite);
297
298 fCaosAnalyse = new MGPopupMenu(p);
299 fCaosAnalyse->AddEntry("S&tart Analysis", IDM_kCaosAnalStart);
300 fCaosAnalyse->AddEntry("St&op Analysis", IDM_kCaosAnalStop);
301 fCaosAnalyse->DisableEntry(IDM_kCaosAnalStop);
302 // fCaosAnalyse->AddEntry("&Reset Histograms", IDM_kResetHistograms);
303 // fCaosAnalyse->AddEntry("Reset &Graph", IDM_kResetGraph);
304 fCaosAnalyse->Associate(this);
305 fList->Add(fCaosAnalyse);
306
307 fMenu = new MGMenuBar(this, 0, 0, kHorizontalFrame);
308 fMenu->AddPopup("&Display", fDisplay, NULL);
309 fMenu->AddPopup("&Mode", fMode, NULL);
310 fMenu->AddPopup("&WritePics", fWritePictures, NULL);
311 fMenu->AddPopup("&Setup", fSetup, NULL);
312 fMenu->AddPopup("&Operations", fOperations, NULL);
313
314 fMenu->Resize(fMenu->GetDefaultSize());
315 fMenu->BindKeys(this);
316 AddFrame(fMenu);
317 fList->Add(fMenu);
318
319 fCaOs = new MGPopupMenu(p);
320 fCaOs->AddPopup("&Write", fCaosWrite);
321 fCaOs->AddPopup("&Print", fCaosPrint);
322 fCaOs->AddPopup("&Analyse", fCaosAnalyse);
323 fCaOs->Associate(this);
324 fCaOs->BindKeys(fMenu, this);
325 fList->Add(fCaOs);
326
327 TGLayoutHints *hints2a =
328 new TGLayoutHints(kLHintsCenterX|kLHintsCenterY|
329 kLHintsExpandX|kLHintsExpandY,1,1);
330 fList->Add(hints2a);
331
332 fGStarg = new MGStarg(this, 235);
333 fGStarg->DrawText("0.75'", "1.50'", "3.00'", "Misspointing [min]");
334 fGStarg->DrawHexagon();
335 fGStarg->Move(530,596+5);
336 fList->Add(fGStarg);
337
338 fCRaDec = new MGCoordinates(this, kETypeRaDec);
339 fCRaDec->Move(4, fMenu->GetDefaultHeight()+584);
340 AddFrame(fCRaDec);
341 fList->Add(fCRaDec);
342
343 fCZdAz = new MGCoordinates(this, kETypeZdAz, 2);
344 fCZdAz->Move(240+12+28, fMenu->GetDefaultHeight()+597);
345 AddFrame(fCZdAz);
346 fList->Add(fCZdAz);
347
348 fPZdAz = new MGCoordinates(this, kETypeZdAz, 2);
349 fPZdAz->Move(240+12+28, fMenu->GetDefaultHeight()+640);
350 AddFrame(fPZdAz);
351 fList->Add(fPZdAz);
352
353 fDZdAz = new MGCoordinates(this, kETypeZdAz, 2);
354 fDZdAz->Move(240+12+28, fMenu->GetDefaultHeight()+683);
355 AddFrame(fDZdAz);
356 fList->Add(fDZdAz);
357
358 fSZdAz = new MGCoordinates(this, kETypeZdAz, 2);
359 fSZdAz->Move(240+12+28, fMenu->GetDefaultHeight()+795);
360 AddFrame(fSZdAz);
361 fList->Add(fSZdAz);
362
363 fGNumStars = new MGNumStars(this, 235);
364 fGNumStars->DrawText("Number of stars");
365 fGNumStars->Move(278, fMenu->GetDefaultHeight()+713);
366 fList->Add(fGNumStars);
367
368 fTPoint = new TGTextButton(this, "TPoint");
369 fTPoint->Move(4, fMenu->GetDefaultHeight()+785);
370 fTPoint->AllowStayDown(kTRUE);
371 AddFrame(fTPoint);
372 fList->Add(fTPoint);
373
374 fStargTPoint = new TGTextButton(this, "StargTPoint");
375 fStargTPoint->Move(170, fMenu->GetDefaultHeight()+785);
376 fStargTPoint->AllowStayDown(kTRUE);
377 AddFrame(fStargTPoint);
378 fList->Add(fStargTPoint);
379
380 fFps = new TGLabel(this, "---fps");
381 fFps->SetTextJustify(kTextRight);
382 fFps->Move(650-495, fMenu->GetDefaultHeight()+714+23);
383 AddFrame(fFps);
384 fList->Add(fFps);
385
386 fPosZoom = new TGLabel(this, "(----, ----) ----.--d/----.--d");
387 fPosZoom->SetTextJustify(kTextLeft);
388 fPosZoom->Move(4, fMenu->GetDefaultHeight()+765);
389 AddFrame(fPosZoom);
390 fList->Add(fPosZoom);
391
392 fSkyBright = new TGLabel(this, "Sky Brightness: --- ");
393 fSkyBright->SetTextJustify(kTextLeft);
394 fSkyBright->Move(4, fMenu->GetDefaultHeight()+785);
395 AddFrame(fSkyBright);
396 fList->Add(fSkyBright);
397
398 TGLabel *l = new TGLabel(this, "deg");
399 l->SetTextJustify(kTextLeft);
400 l->Move(606-412, fMenu->GetDefaultHeight()+669);
401 AddFrame(l);
402 fList->Add(l);
403
404 l = new TGLabel(this, "arcsec/pix");
405 l->SetTextJustify(kTextLeft);
406 l->Move(606-412, fMenu->GetDefaultHeight()+692);
407 AddFrame(l);
408 fList->Add(l);
409
410 l = new TGLabel(this, "sigma");
411 l->SetTextJustify(kTextLeft);
412 l->Move(606-412, fMenu->GetDefaultHeight()+715);
413 AddFrame(l);
414 fList->Add(l);
415
416 l = new TGLabel(this, "Zd/Az telescope pointing at");
417 l->SetTextJustify(kTextLeft);
418 l->Move(240+12+20+7, fMenu->GetDefaultHeight()+584-5);
419 AddFrame(l);
420 fList->Add(l);
421
422 l = new TGLabel(this, "Zd/Az starguider pointing at");
423 l->SetTextJustify(kTextLeft);
424 l->Move(240+12+20+7, fMenu->GetDefaultHeight()+630+20-5-23);
425 AddFrame(l);
426 fList->Add(l);
427
428 l = new TGLabel(this, "Zd/Az misspointing");
429 l->SetTextJustify(kTextLeft);
430 l->Move(240+12+20+7, fMenu->GetDefaultHeight()+676+2*20-5-46);
431 AddFrame(l);
432 fList->Add(l);
433
434#ifdef EXPERT
435 l = new TGLabel(this, "Misspointing/FindStar (Experts Only!)");
436 l->SetTextJustify(kTextLeft);
437 l->Move(240+12+20, fMenu->GetDefaultHeight()+722+3*20-5);
438 AddFrame(l);
439 fList->Add(l);
440#endif
441
442 // Set input box for rotation angle
443 const Double_t angle = -0.4;
444 fSao->SetRotationAngle(angle);
445
446 TString txt;
447 txt += angle;
448
449 fAngle = new TGTextEntry(this, txt, IDM_kAngle);
450 fAngle->SetAlignment(kTextCenterX);
451 fAngle->Move(547-410, fMenu->GetDefaultHeight()+667);
452 AddFrame(fAngle);
453 fList->Add(fAngle);
454
455 // Set input box for pixel size
456 const Double_t pixsize = 48.8; // used to be 23.4
457
458 fSao->SetPixSize(pixsize);
459 fSao->SetRotationAngle(0);
460
461 txt = "";
462 txt += pixsize;
463
464 fPixSize = new TGTextEntry(this, txt, IDM_kPixSize);
465 fPixSize->SetAlignment(kTextCenterX);
466 fPixSize->Move(547-410, fMenu->GetDefaultHeight()+690);
467 AddFrame(fPixSize);
468 fList->Add(fPixSize);
469
470 // Set input box for cleaning cut
471 const Double_t cut = 3.0;
472
473 txt = "";
474 txt += cut;
475
476 fCut = new TGTextEntry(this, txt, IDM_kCut);
477 fCut->SetAlignment(kTextCenterX);
478 fCut->Move(547-410, fMenu->GetDefaultHeight()+713);
479 AddFrame(fCut);
480 fList->Add(fCut);
481
482 // TGHorizontal3DLine *fLineSep = new TGHorizontal3DLine(this);
483 // AddFrame(fLineSep, new TGLayoutHints (kLHintsNormal | kLHintsExpandX));
484 // fList->Add(fLineSep);
485
486 //
487 // Create Image Display
488 //
489 fZoomImage = new MGImage(this, kZOOM, kZOOM);
490 // fZoomImage->Move(768-kZOOM-2, 700-kZOOM-2);
491 fZoomImage->Move(4, 700-kZOOM-2+85);
492 AddFrame(fZoomImage);
493 fList->Add(fZoomImage);
494
495 fImage = new MGImage(this, 768, 576);
496 fImage->Move(0, fMenu->GetDefaultHeight());
497 AddFrame(fImage);
498 fList->Add(fImage);
499
500 const Int_t w = 768;
501 const Int_t h = 840;
502 SetWMSizeHints(w, h, w, h, 1, 1); // set the smallest and biggest size of the Main frame
503
504 //
505 // Make everything visible
506 //
507 SetWindowName("MStarguider Main Window");
508 SetIconName("MStarguider");
509
510 MapSubwindows();
511 fTPoint->UnmapWindow();
512 fStargTPoint->UnmapWindow();
513 fGStarg->UnmapWindow();
514 fGNumStars->UnmapWindow();
515 fPZdAz->UnmapWindow();
516 fDZdAz->UnmapWindow();
517 fSZdAz->UnmapWindow();
518 fSkyBright->UnmapWindow();
519 MapWindow();
520
521
522 //IconifyWindow();
523
524 //------------------------------------------------------------
525 // XY xy(3.819444, 24.05333);
526 // fCRaDec->SetCoordinates(xy);
527 // fRaDec->Set(xy.X()*360/24, xy.Y());
528 //------------------------------------------------------------
529}
530
531MStarguider::MStarguider(MObservatory::LocationName_t obs, Int_t channel)
532 : TGMainFrame(gClient->GetRoot(), 768, 840),
533 fCosy(NULL),
534 fOutTp(0),
535 fOutStargTp(0),
536 fOutRq(0),
537 fDx((768-kZOOM)/2),
538 fDy((512-kZOOM)/2),
539 fStatus(MDriveCom::kStandby)
540{
541 cout << " #### FIXME: Make MCaos Thread safe!" << endl;
542
543 fAmcSocket = new TSocket("amc", 7307);
544
545 fSao = new StarCatalog(obs);
546 fRaDec = new RaDec(180, 40);
547
548 // fStargLeds = new MStargLeds;
549 // fStargLeds->ReadResources();
550
551 fCaos = new MCaos;
552 fCaos->ReadResources();
553
554 fStargCaos = new MCaos;
555 fStargCaos->ReadResources("stargleds.txt");
556 fStargCaos->SetMinNumberRings(3);
557 fStargCaos->SetRadii(158,164);
558
559 fStargHistograms = new MStargHistograms();
560
561 InitGui(channel);
562
563 fTimer=new TTimer(this, 1000/25); // 40ms
564 fTimer->TurnOn();
565
566 fTime.Now();
567
568 fTimeFromTp.Set(1970,1,1);
569 fAltAzOffsetFromTp = AltAz(-1000,-1000);
570
571 gVirtualX->GrabButton(fId, kButton2, 0, 0, 0, 0, kTRUE);
572
573 if (channel<0)
574 fGetter=new PngReader(*this);
575 else
576 {
577 fGetter = new Camera(*this, channel);
578 ((Camera*)fGetter)->Loop(0);
579 }
580}
581
582MStarguider::~MStarguider()
583{
584 fGetter->ExitLoop();
585 delete fGetter;
586
587 gVirtualX->GrabButton(fId, kButton2, 0, 0, 0, 0, kFALSE);
588
589 fTimer->TurnOff();
590 delete fTimer;
591
592 delete fList;
593
594 delete fCaos;
595 delete fStargCaos;
596 // delete fStargLeds;
597 delete fStargHistograms;
598 delete fSao;
599 delete fRaDec;
600 delete fTPoint;//
601 delete fStargTPoint;//
602
603 if (fOutTp)
604 delete fOutTp;
605
606 if (fOutStargTp)
607 delete fOutStargTp;
608
609 if (fOutRq)
610 delete fOutRq;
611
612 delete fAmcSocket;
613
614 cout << "Camera Display destroyed." << endl;
615}
616
617bool MStarguider::SendAmcTrigger(const char *msg)
618{
619 if (!fAmcSocket->IsValid())
620 return false;
621
622 TString txt("TRIGGER ");
623 txt += msg;
624
625 const Int_t len = fAmcSocket->SendRaw(txt.Data(), txt.Length());
626 if (len<0)
627 {
628 cout << "ERROR - Sending Trigger to Amc" << endl;
629 return false;
630 }
631 if (len!=txt.Length())
632 {
633 cout << "Send wrong number (" << len << ") of Bytes to Amc." << endl;
634 return false;
635 }
636
637 return true;
638}
639
640void MStarguider::Layout()
641{
642 // Resize(GetDefaultSize());
643}
644
645void MStarguider::CloseWindow()
646{
647 cout << "EventDisplay::CloseWindow: Exit Application Loop." << endl;
648
649 //fClient.ExitLoop();
650 // cout << "FIXME: ExitLoop not called!!!!!!" << endl;
651 gSystem->ExitLoop();
652}
653
654void MStarguider::SwitchOff(MGPopupMenu *p, UInt_t id)
655{
656 p->UnCheckEntry(id);
657 p->DisableEntry(id);
658}
659
660void MStarguider::Toggle(MGPopupMenu *p, UInt_t id)
661{
662 if (p->IsEntryChecked(id))
663 p->UnCheckEntry(id);
664 else
665 p->CheckEntry(id);
666}
667
668void MStarguider::ToggleStargAnalysis()
669{
670 if (fOperations->IsEntryChecked(IDM_kStargAnalysis))
671 fStargHistograms->OpenFile();
672 else
673 fStargHistograms->CloseFile();
674}
675
676void MStarguider::ToggleFindStar()
677{
678 if (fDisplay->IsEntryChecked(IDM_kFindStar) && fCosy)
679 fTPoint->MapWindow();
680 else
681 {
682 fTPoint->UnmapWindow();
683 fTPoint->SetDown(kFALSE);
684 }
685}
686
687void MStarguider::ToggleStarguider()
688{
689 if (fDisplay->IsEntryChecked(IDM_kStarguider))
690 {
691 fLastBright = 0xff;
692
693 fChannel->EnableEntry(IDM_kChannel1);
694 fDisplay->DisableEntry(IDM_kFindStar);
695 fDisplay->DisableEntry(IDM_kCaosFilter);
696 fOperations->EnableEntry(IDM_kStargAnalysis);
697
698 fStargTPoint->MapWindow();
699
700 fPZdAz->MapWindow();
701 fDZdAz->MapWindow();
702 fSkyBright->MapWindow();
703
704 for (int i=IDM_kLimMag3; i<=IDM_kLimMag9; i++)
705 fLimMag->UnCheckEntry(i);
706 fLimMag->CheckEntry(IDM_kLimMag9);
707 fSao->SetLimitMag(9.0);
708
709 for (int i=IDM_kInterpol250; i<=IDM_kInterpol1; i++)
710 fInterpol->UnCheckEntry(i);
711 fInterpol->CheckEntry(IDM_kInterpol125);
712 fIntRate = 125;
713
714 fDisplay->CheckEntry(IDM_kCatalog);
715 fGStarg->MapWindow();
716 fGNumStars->MapWindow();
717
718 const Int_t ch0 =
719 fChannel->IsEntryChecked(IDM_kChannel1) ? 0 : 1;
720 const Int_t ch1 = 0;
721
722 if (ch0!=ch1)
723 {
724// fGetter->ExitLoop();
725 delete fGetter;
726 usleep(150000); // FIX: Device or resource busy.
727 if (fChannel->IsEntryChecked(IDM_kChannel3))
728 fGetter=new PngReader(*this);
729 else
730 {
731 fGetter = new Camera(*this, ch1);
732 ((Camera*)fGetter)->Loop(0);
733 }
734 }
735
736 SwitchOff(fChannel, IDM_kChannel2);
737 fChannel->CheckEntry(IDM_kChannel1);
738
739 }
740 else
741 {
742 fStatus = MDriveCom::kStandby;
743
744 fStargTPoint->UnmapWindow();
745 fStargTPoint->SetDown(kFALSE);
746
747 fPZdAz->UnmapWindow();
748 fDZdAz->UnmapWindow();
749 fSkyBright->UnmapWindow();
750 fGStarg->UnmapWindow();
751 fGNumStars->UnmapWindow();
752
753 fChannel->EnableEntry(IDM_kChannel2);
754 fDisplay->EnableEntry(IDM_kFindStar);
755 fDisplay->EnableEntry(IDM_kCaosFilter);
756 fOperations->DisableEntry(IDM_kStargAnalysis);
757 }
758 //gSystem->Unlink("tracking_error.txt");
759}
760
761void MStarguider::ToggleCaosFilter()
762{
763 if (fDisplay->IsEntryChecked(IDM_kCaosFilter))
764 {
765 if (!fMode->IsEntryChecked(IDM_kStarguiderMode)
766 && !fMode->IsEntryChecked(IDM_kTpointMode))
767 fMenu->AddPopup("&CaOs", fCaOs, NULL);
768
769 SwitchOff(fDisplay, IDM_kStarguider);
770 SwitchOff(fDisplay, IDM_kStargCaosFilter);
771 fDisplay->DisableEntry(IDM_kStargFindStar);
772 }
773 else
774 {
775 fCaosWrite->UnCheckEntry(IDM_kCaosPrintLeds);
776 fCaosWrite->UnCheckEntry(IDM_kCaosPrintRings);
777
778 if (fCaosAnalyse->IsEntryEnabled(IDM_kCaosAnalStop))
779 {
780 fCaosAnalyse->DisableEntry(IDM_kCaosAnalStop);
781 fCaosAnalyse->EnableEntry(IDM_kCaosAnalStart);
782 fCaos->DeleteHistograms();
783 }
784 if (fCaosWrite->IsEntryEnabled(IDM_kCaosWriteStop))
785 {
786 fCaosWrite->DisableEntry(IDM_kCaosWriteStop);
787 fCaosWrite->EnableEntry(IDM_kCaosWriteStart);
788 fCaos->CloseFile();
789 }
790 fMenu->RemovePopup("CaOs");
791
792 fDisplay->EnableEntry(IDM_kStargCaosFilter);
793 fDisplay->EnableEntry(IDM_kStarguider);
794 }
795 fMenu->Resize(fMenu->GetDefaultSize());
796 MapSubwindows(); // maps everything, but we don't want that
797 fTPoint->UnmapWindow();
798 fStargTPoint->UnmapWindow();
799 fGStarg->UnmapWindow();
800 fGNumStars->UnmapWindow();
801 fPZdAz->UnmapWindow();
802 fDZdAz->UnmapWindow();
803 fSZdAz->UnmapWindow();
804 fSkyBright->UnmapWindow();
805 MapWindow();
806}
807
808Bool_t MStarguider::ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2)
809{
810 switch (GET_MSG(msg))
811 {
812 case kC_TEXTENTRY:
813 if (GET_SUBMSG(msg)==kTE_ENTER)
814 switch (mp1)
815 {
816 case IDM_kPixSize:
817 {
818 const Float_t pixsize = atof(fPixSize->GetText());
819 cout << "Pixel Size changed to " << pixsize << "\"/pix" << endl;
820 fSao->SetPixSize(pixsize);
821 return kTRUE;
822 }
823 case IDM_kAngle:
824 {
825 const Float_t angle = atof(fAngle->GetText());
826 cout << "Rotation Angle changed to " << angle << "deg" << endl;
827 fSao->SetRotationAngle(angle);
828 return kTRUE;
829 }
830 case IDM_kCut:
831 {
832 const Float_t cut = atof(fCut->GetText());
833 cout << "Starguider cleaning level changed to " << cut << " sigma." << endl;
834 return kTRUE;
835 }
836 }
837 return kTRUE;
838
839 case kC_COMMAND:
840 switch (GET_SUBMSG(msg))
841 {
842 case kCM_MENU:
843 switch (mp1)
844 {
845 case IDM_kCatalog:
846 Toggle(fDisplay, IDM_kCatalog);
847 return kTRUE;
848
849 case IDM_kRoqueLampAna:
850 Toggle(fOperations, IDM_kRoqueLampAna);
851 if (fOperations->IsEntryChecked(IDM_kRoqueLampAna))
852 fDisplay->CheckEntry(IDM_kStargCaosFilter);
853 else
854 fDisplay->UnCheckEntry(IDM_kStargCaosFilter);
855
856 return kTRUE;
857
858 case IDM_kStargFindStar:
859 Toggle(fDisplay, IDM_kStargFindStar);
860 if (fDisplay->IsEntryChecked(IDM_kStargFindStar))
861 fSZdAz->MapWindow();
862 else
863 fSZdAz->UnmapWindow();
864 return kTRUE;
865
866 case IDM_kStarguider:
867 Toggle(fDisplay, IDM_kStarguider);
868 ToggleStarguider();
869 return kTRUE;
870
871 case IDM_kStargAnalysis:
872 Toggle(fOperations, IDM_kStargAnalysis);
873 ToggleStargAnalysis();
874 return kTRUE;
875
876 case IDM_kStarguiderMode:
877 Toggle(fMode, IDM_kStarguiderMode);
878
879 if (fMode->IsEntryChecked(IDM_kStarguiderMode))
880 {
881 //uncheck not needed items
882 //general
883 fDisplay->UnCheckEntry(IDM_kStargFindStar);
884 SwitchOff(fDisplay, IDM_kFilter);
885 SwitchOff(fChannel, IDM_kChannel3);
886 SwitchOff(fOperations, IDM_kRoqueLampAna);
887 SwitchOff(fOperations, IDM_kStargAnalysis);
888
889 //tpoint
890 SwitchOff(fDisplay, IDM_kFindStar);
891 ToggleFindStar();
892 SwitchOff(fDisplay, IDM_kCaosFilter);
893 ToggleCaosFilter();
894 fMode->UnCheckEntry(IDM_kTpointMode);
895
896 //enable starguider items
897 fDisplay->EnableEntry(IDM_kStargCaosFilter);
898 fDisplay->EnableEntry(IDM_kStarguider);
899 fDisplay->EnableEntry(IDM_kCatalog);
900
901 //check needed items
902 fDisplay->CheckEntry(IDM_kStretch);
903 fDisplay->CheckEntry(IDM_kStargCaosFilter);
904 fDisplay->CheckEntry(IDM_kStarguider);
905 ToggleStarguider();
906 }
907 else
908 {
909 //uncheck
910 //starguider items
911 fDisplay->UnCheckEntry(IDM_kStargCaosFilter);
912 fDisplay->UnCheckEntry(IDM_kStarguider);
913 ToggleStarguider();
914
915 //general
916 fDisplay->UnCheckEntry(IDM_kCatalog);
917 fDisplay->EnableEntry(IDM_kFilter);
918 fDisplay->EnableEntry(IDM_kCaosFilter);
919 fDisplay->EnableEntry(IDM_kFindStar);
920 fChannel->EnableEntry(IDM_kChannel3);
921 fOperations->EnableEntry(IDM_kRoqueLampAna);
922 }
923 return kTRUE;
924
925 case IDM_kTpointMode:
926 Toggle(fMode, IDM_kTpointMode);
927
928 if (fMode->IsEntryChecked(IDM_kTpointMode))
929 {
930 //unchecking not needed items
931 //general
932 fDisplay->UnCheckEntry(IDM_kStargFindStar);
933 SwitchOff(fDisplay, IDM_kFilter);
934 SwitchOff(fChannel, IDM_kChannel3);
935 SwitchOff(fOperations, IDM_kRoqueLampAna);
936
937 //from starguider
938 SwitchOff(fDisplay, IDM_kStargCaosFilter);
939 SwitchOff(fDisplay, IDM_kCatalog);
940 SwitchOff(fDisplay, IDM_kStarguider);
941 ToggleStarguider();
942 fMode->UnCheckEntry(IDM_kStarguiderMode);
943 SwitchOff(fOperations, IDM_kStargAnalysis);
944 ToggleStargAnalysis();
945
946 //switch camera
947 const Int_t ch0 =
948 fChannel->IsEntryChecked(IDM_kChannel1) ? 0 : 1;
949 const Int_t ch1 = 1;
950
951 if (ch0!=ch1)
952 {
953// fGetter->ExitLoop();
954 delete fGetter;
955 usleep(150000); // FIX: Device or resource busy.
956 fGetter = new Camera(*this, ch1);
957 ((Camera*)fGetter)->Loop(0);
958 }
959
960 SwitchOff(fChannel, IDM_kChannel1);
961 fChannel->CheckEntry(IDM_kChannel2);
962
963 //checking needed items
964 fDisplay->CheckEntry(IDM_kStretch);
965 fDisplay->CheckEntry(IDM_kCaosFilter);
966 ToggleCaosFilter();
967 fDisplay->CheckEntry(IDM_kFindStar);
968 ToggleFindStar();
969 }
970 else
971 {
972 //enable
973 //starguider items
974 fDisplay->EnableEntry(IDM_kStargCaosFilter);
975 fDisplay->EnableEntry(IDM_kCatalog);
976 fDisplay->EnableEntry(IDM_kStarguider);
977 fOperations->EnableEntry(IDM_kStargAnalysis);
978
979 //general
980 fDisplay->EnableEntry(IDM_kFilter);
981 fChannel->EnableEntry(IDM_kChannel1);
982 fChannel->EnableEntry(IDM_kChannel3);
983 fOperations->EnableEntry(IDM_kRoqueLampAna);
984
985 //tpoint
986 fDisplay->UnCheckEntry(IDM_kCaosFilter);
987 ToggleCaosFilter();
988 fDisplay->UnCheckEntry(IDM_kFindStar);
989 ToggleFindStar();
990 }
991 return kTRUE;
992
993 case IDM_kFilter:
994 Toggle(fDisplay, IDM_kFilter);
995 return kTRUE;
996
997 case IDM_kFindStar:
998 Toggle(fDisplay, IDM_kFindStar);
999 ToggleFindStar();
1000 return kTRUE;
1001
1002 case IDM_kStretch:
1003 Toggle(fDisplay, IDM_kStretch);
1004 return kTRUE;
1005
1006 case IDM_kCaosFilter:
1007 Toggle(fDisplay, IDM_kCaosFilter);
1008 ToggleCaosFilter();
1009 return kTRUE;
1010
1011 case IDM_kStargCaosFilter:
1012 Toggle(fDisplay, IDM_kStargCaosFilter);
1013 if (fDisplay->IsEntryChecked(IDM_kStargCaosFilter))
1014 {
1015 fDisplay->EnableEntry(IDM_kStargFindStar);
1016 SwitchOff(fDisplay, IDM_kCaosFilter);
1017 SwitchOff(fDisplay, IDM_kFindStar);
1018 SwitchOff(fDisplay, IDM_kFilter);
1019 }
1020 else
1021 {
1022 fDisplay->EnableEntry(IDM_kFilter);
1023 fDisplay->EnableEntry(IDM_kFindStar);
1024 fDisplay->EnableEntry(IDM_kCaosFilter);
1025 fDisplay->DisableEntry(IDM_kStargFindStar);
1026 }
1027 return kTRUE;
1028
1029 case IDM_kCaosPrintLeds:
1030 case IDM_kCaosPrintRings:
1031 Toggle(fCaosPrint, mp1);
1032 return kTRUE;
1033
1034 case IDM_kCaosAnalStart:
1035 fCaosAnalyse->DisableEntry(IDM_kCaosAnalStart);
1036 fCaosAnalyse->EnableEntry(IDM_kCaosAnalStop);
1037 fCaos->InitHistograms();
1038 return kTRUE;
1039
1040 case IDM_kCaosAnalStop:
1041 fCaosAnalyse->DisableEntry(IDM_kCaosAnalStop);
1042 fCaosAnalyse->EnableEntry(IDM_kCaosAnalStart);
1043 fCaos->ShowHistograms();
1044 fCaos->DeleteHistograms();
1045 return kTRUE;
1046
1047 case IDM_kCaosWriteStart:
1048 fCaosWrite->DisableEntry(IDM_kCaosWriteStart);
1049 fCaosWrite->EnableEntry(IDM_kCaosWriteStop);
1050 fCaos->OpenFile();
1051 return kTRUE;
1052
1053 case IDM_kCaosWriteStop:
1054 fCaosWrite->DisableEntry(IDM_kCaosWriteStop);
1055 fCaosWrite->EnableEntry(IDM_kCaosWriteStart);
1056 fCaos->CloseFile();
1057 return kTRUE;
1058
1059 case IDM_kStart:
1060 fWritePictures->DisableEntry(IDM_kStart);
1061 fWritePictures->EnableEntry(IDM_kStop);
1062 return kTRUE;
1063
1064 case IDM_kStop:
1065 fWritePictures->DisableEntry(IDM_kStop);
1066 fWritePictures->EnableEntry(IDM_kStart);
1067 return kTRUE;
1068
1069 case IDM_kPNG:
1070 fFileType->CheckEntry(IDM_kPNG);
1071 fFileType->UnCheckEntry(IDM_kPPM);
1072 return kTRUE;
1073
1074 case IDM_kPPM:
1075 fFileType->CheckEntry(IDM_kPPM);
1076 fFileType->UnCheckEntry(IDM_kPNG);
1077 return kTRUE;
1078
1079 case IDM_kOnce:
1080 fWriteType->CheckEntry(IDM_kOnce);
1081 fWriteType->UnCheckEntry(IDM_kContinous);
1082 return kTRUE;
1083
1084 case IDM_kContinous:
1085 fWriteType->CheckEntry(IDM_kContinous);
1086 fWriteType->UnCheckEntry(IDM_kOnce);
1087 return kTRUE;
1088
1089 case IDM_kRate25ps:
1090 case IDM_kRate5ps:
1091 case IDM_kRate1s:
1092 case IDM_kRate5s:
1093 case IDM_kRate30s:
1094 case IDM_kRate1m:
1095 case IDM_kRate5m:
1096 for (int i=IDM_kRate25ps; i<=IDM_kRate5m; i++)
1097 if (mp1==i)
1098 fWriteRate->CheckEntry(i);
1099 else
1100 fWriteRate->UnCheckEntry(i);
1101 switch (mp1)
1102 {
1103 case IDM_kRate25ps:
1104 fWrtRate = 1;
1105 return kTRUE;
1106 case IDM_kRate5ps:
1107 fWrtRate = 5;
1108 return kTRUE;
1109 case IDM_kRate1s:
1110 fWrtRate = 25;
1111 return kTRUE;
1112 case IDM_kRate5s:
1113 fWrtRate = 5*25;
1114 return kTRUE;
1115 case IDM_kRate30s:
1116 fWrtRate = 30*25;
1117 return kTRUE;
1118 case IDM_kRate1m:
1119 fWrtRate = 60*25;
1120 return kTRUE;
1121 case IDM_kRate5m:
1122 fWrtRate = 5*60*25;
1123 return kTRUE;
1124 }
1125 return kTRUE;
1126
1127 case IDM_kChannel1:
1128 case IDM_kChannel2:
1129 {
1130 const Int_t ch0 = fChannel->IsEntryChecked(IDM_kChannel1) ? 0 : 1;
1131 const Int_t ch1 = mp1==IDM_kChannel1 ? 0 : 1;
1132
1133 if (ch0==ch1)
1134 return kTRUE;
1135
1136 fChannel->CheckEntry (ch1==0?IDM_kChannel1:IDM_kChannel2);
1137 fChannel->UnCheckEntry(ch1==1?IDM_kChannel1:IDM_kChannel2);
1138// fGetter->ExitLoop();
1139 delete fGetter;
1140 usleep(150000); // FIX: Device or resource busy.
1141 if (fChannel->IsEntryChecked(IDM_kChannel3))
1142 fGetter=new PngReader(*this);
1143 else
1144 {
1145 fGetter = new Camera(*this, ch1);
1146 ((Camera*)fGetter)->Loop(0);
1147 }
1148 }
1149 return kTRUE;
1150
1151 case IDM_kInterpol250:
1152 case IDM_kInterpol125:
1153 case IDM_kInterpol50:
1154 case IDM_kInterpol25:
1155 case IDM_kInterpol10:
1156 case IDM_kInterpol5:
1157 case IDM_kInterpol2:
1158 case IDM_kInterpol1:
1159 for (int i=IDM_kInterpol250; i<=IDM_kInterpol1; i++)
1160 if (mp1==i)
1161 fInterpol->CheckEntry(i);
1162 else
1163 fInterpol->UnCheckEntry(i);
1164 switch (mp1)
1165 {
1166 case IDM_kInterpol1:
1167 fIntRate = 1;
1168 return kTRUE;
1169 case IDM_kInterpol2:
1170 fIntRate = 2;
1171 return kTRUE;
1172 case IDM_kInterpol5:
1173 fIntRate = 5;
1174 return kTRUE;
1175 case IDM_kInterpol10:
1176 fIntRate = 10;
1177 return kTRUE;
1178 case IDM_kInterpol25:
1179 fIntRate = 25;
1180 return kTRUE;
1181 case IDM_kInterpol50:
1182 fIntRate = 50;
1183 return kTRUE;
1184 case IDM_kInterpol125:
1185 fIntRate = 125;
1186 return kTRUE;
1187 case IDM_kInterpol250:
1188 fIntRate = 250;
1189 return kTRUE;
1190 }
1191 return kTRUE;
1192
1193 case IDM_kLimMag3:
1194 case IDM_kLimMag4:
1195 case IDM_kLimMag5:
1196 case IDM_kLimMag6:
1197 case IDM_kLimMag7:
1198 case IDM_kLimMag8:
1199 case IDM_kLimMag9:
1200 for (int i=IDM_kLimMag3; i<=IDM_kLimMag9; i++)
1201 if (mp1==i)
1202 fLimMag->CheckEntry(i);
1203 else
1204 fLimMag->UnCheckEntry(i);
1205
1206 fSao->SetLimitMag(mp1-IDM_kLimMag3+3);
1207 return kTRUE;
1208 }
1209 break;
1210 }
1211 break;
1212 }
1213
1214 return kTRUE;
1215}
1216
1217void MStarguider::SetPointingPosition(RaDec rd)
1218{
1219 rd.Ra(rd.Ra()*24/360);
1220 fCRaDec->SetCoordinates(rd);
1221}
1222
1223ZdAz MStarguider::TrackingError(TArrayF &x, TArrayF &y, TArrayF &mag,
1224 Int_t &num) const
1225{
1226 num = -1;
1227
1228 // Width of the final 2D gaussian
1229 const Double_t width = 0.8;
1230
1231 // The binning is made 1.7 sigma (which, in the 1D case, gives the
1232 // highest significance of a gaussian signal) (1bin equiv 3x3 sigma)
1233 const Double_t max = 50;
1234 const Int_t n = TMath::Nint(2*max/(1.77*1.7*width));
1235 //1.77=sqrt(pi) comes from pir=bin
1236
1237 // Fill a histogram with the dx/dy values from the file
1238 TH2F hist("Hist", "dX/dY", n, -max, max, n, -max, max);
1239// hist.SetDirectory(0);
1240
1241 //
1242 // Search for matching Magnitudes
1243 //
1244 //for (int i=0; i<mag.GetSize(); i++)
1245 //{
1246 // if (mag[i]>48-15 && mag[i]<48+15)
1247 // h.Fill(x[i], y[i]);
1248 //}
1249
1250 // fill dx and dy into histogram
1251 for (int i=0; i<mag.GetSize(); i++)
1252 hist.Fill(x[i], y[i]);
1253
1254 // Remove all bins which have content of only a single event
1255 // including under- and overflow bins
1256 for (int i=0; i<hist.GetSize(); i++)
1257 if (hist.GetBinContent(i)<1.5)
1258 hist.SetBinContent(i, 0);
1259
1260 // Find the bin containing the maximum
1261 Int_t bx, by, bz;
1262 hist.GetMaximumBin(bx, by, bz);
1263
1264 // In the worst case the events are spread through the
1265 // bins which are the neighbors of the maximum
1266 // Normally neighbors which do not belong to the signal are empty!
1267 hist.GetXaxis()->SetRange(bx-1, bx+1); // 3x3bins ~8x8pix ~9x9sigma
1268 hist.GetYaxis()->SetRange(by-1, by+1); // 3x3bins ~8x8pix ~9x9sigma
1269
1270 // Check whether this region contains events
1271 num = TMath::Nint(hist.Integral());
1272 if (num<1)
1273 return ZdAz();
1274
1275 // Get Mean for the given axis range
1276 Double_t mx = hist.GetMean(1);
1277 Double_t my = hist.GetMean(2);
1278
1279 const Int_t max1 = TMath::Nint(hist.GetBinContent(bx, by));
1280
1281 // Check if the maximum is unique
1282 Int_t bx2, by2, bz2;
1283 hist.GetXaxis()->SetRange(-1, 9999);
1284 hist.GetYaxis()->SetRange(-1, 9999);
1285 hist.SetBinContent(bx, by, 0);
1286 hist.GetMaximumBin(bx2, by2, bz2);
1287
1288 const Int_t max2 = TMath::Nint(hist.GetBinContent(bx2, by2));
1289 if (max1==max2 && TMath::Abs(bx2-bx)+TMath::Abs(by2-by)>1)
1290 return ZdAz();
1291
1292 // loop again over the file and fill the histogram again.
1293 // to get closer to the correct value
1294 Double_t sumx = 0;
1295 Double_t sumy = 0;
1296 num = 0;
1297 for (int i=0; i<mag.GetSize(); i++)
1298 {
1299 // only fill values into the histogram which
1300 // are inside 2*1.7=3.4 sigma (99.7%)
1301 if (TMath::Hypot(x[i]-mx, y[i]-my)>width*3.4)
1302 continue;
1303
1304 sumx += x[i];
1305 sumy += y[i];
1306 num++;
1307 }
1308
1309 if (num<1)
1310 return ZdAz();
1311
1312 // calc MeanX and MeanY
1313 mx = sumx/num;
1314 my = sumy/num;
1315
1316 // loop again to fill the mispointing corrected histograms
1317 // and fill another histogram to check the quality of the calculated
1318 // mispointing.
1319 sumx = 0;
1320 sumy = 0;
1321 num = 0;
1322 for (int i=0; i<mag.GetSize(); i++)
1323 {
1324 // only fill values into the histogram which
1325 // are inside 1.7=3.4 sigma (92%)
1326 // Cut at 1.7 sigma which gives the best background supression
1327 if (TMath::Hypot(x[i]-mx, y[i]-my)>width*1.7)
1328 continue;
1329
1330 sumx += x[i];
1331 sumy += y[i];
1332 num++;
1333 }
1334
1335 if (num<1)
1336 return ZdAz(); // FIXME!!!!!!!!!!!!
1337
1338 // Mispointing
1339 mx = sumx/num;
1340 my = sumy/num;
1341
1342#ifdef EXPERT
1343 cout << "Offset-XY: " << mx << " +- " << my << endl;
1344#endif
1345
1346 AltAz pos0 = fSao->CalcAltAzFromPix(768/2, 576/2)*kRad2Deg;
1347 AltAz pos1 = fSao->CalcAltAzFromPix(768/2+mx, 576/2+my)*kRad2Deg;
1348/*
1349 ofstream fout1("pointingpos.txt");
1350 fout1 << setprecision(10) << fSao->GetMjd()-52000 << " ";
1351 if (fCosy)
1352 fout1 << fCosy->GetPointingPos() << " ";
1353 fout1 << -pos1.Alt() << " " << pos1.Az() << endl;
1354 */
1355 pos1 -= pos0;
1356/*
1357 ofstream fout2("tracking_error.txt", ios::app);
1358 fout2 << setprecision(10) << fSao->GetMjd()-52000 << " ";
1359 if (fCosy)
1360 fout2 << fCosy->GetPointingPos() << " ";
1361 fout2 << -pos1.Alt() << " " << pos1.Az() << endl;
1362 */
1363 return ZdAz(-pos1.Alt(), pos1.Az());
1364}
1365
1366Int_t MStarguider::CalcTrackingError(Leds &leds, MStarList &stars,
1367 ZdAz &d, MTime &t, double &bright, Int_t &num)
1368{
1369 num = leds.GetEntries();
1370 if (num < 3) //was 1
1371 {
1372 cout << "Sorry, less than 3 detected spot in FOV!" << endl;
1373 if (fStargTPoint->IsDown())
1374 fStargTPoint->SetDown(kFALSE);
1375 return 0;
1376 }
1377
1378 if (stars.GetRealEntries() < 3)
1379 {
1380 cout << "Sorry, less than 3 stars in FOV!" << endl;
1381 if (fStargTPoint->IsDown())
1382 fStargTPoint->SetDown(kFALSE);
1383 return 0;
1384 }
1385
1386 stars.Sort(); // Sort by magnitude
1387
1388#ifdef EXPERT
1389 TString str = "data/tracking_";
1390 str += fSao->GetMjd();
1391 str += ".txt";
1392
1393 ofstream fout(str);
1394#endif
1395
1396 TArrayF x, y, mag;
1397
1398 // FIXME: Is predefined value 3 a good idea?
1399
1400 MStar *star;
1401 MStarListIter NextStar(&stars);
1402 while ((star=NextStar()))
1403 {
1404 TIter NextSp(&leds);
1405 Led *spot=NULL;
1406 while ((spot=(Led*)NextSp()))
1407 {
1408 const XY dpos(spot->GetX()-(768-star->GetX()),
1409 spot->GetY()-star->GetY());
1410
1411 const Int_t idx = x.GetSize();
1412
1413 x.Set(idx+1);
1414 y.Set(idx+1);
1415 mag.Set(idx+1);
1416
1417 x.AddAt(dpos.X(), idx);
1418 y.AddAt(dpos.Y(), idx);
1419 mag.AddAt(spot->GetMag()/star->GetMag(), idx);
1420#ifdef EXPERT
1421 if (fout)
1422 {
1423 fout << spot->GetX() << " "
1424 << spot->GetY() << " "
1425 << spot->GetMag() << " "
1426 << star->GetX() << " "
1427 << star->GetY() << " "
1428 << star->GetMag() << " ";
1429 fout << x[idx] << " " << y[idx] << " " << mag[idx] << endl;
1430 }
1431#endif
1432 }
1433 }
1434
1435 Int_t numcor = 0;
1436 d = TrackingError(x, y, mag, numcor);
1437 if (numcor<1)
1438 return 0;
1439
1440 fDZdAz->SetCoordinates(d);
1441
1442 //
1443 // Calculated offsets
1444 //
1445
1446#ifdef EXPERT
1447 // round= floor(x+.5)
1448 cout << "Offset-ZdAz: " << d.Zd()*60 << "' / " << d.Az()*60 << "'" << endl;
1449 cout << "Offset-ZdAz: " << d.Zd()/360*16384 << " / " << d.Az()/360*16384 << " (SE) " << endl;
1450#endif
1451
1452 //
1453 // Current Pointing position
1454 //
1455 ZdAz cpos = fSao->GetZdAz()-d;
1456 fPZdAz->SetCoordinates(cpos);
1457
1458
1459 // Check StargTPoint data set request
1460 if (!fStargTPoint->IsDown())
1461 return numcor;
1462 fStargTPoint->SetDown(kFALSE);
1463
1464 // If no file open: open new file
1465 if (!fOutStargTp)
1466 {
1467 // open tpoint file
1468 const TString name = MCosy::GetFileName("tpoint", "starg", "txt");
1469 cout << "TPoint-Starg File ********* " << name << " ********** " << endl;
1470
1471 fOutStargTp = new ofstream(name);
1472 *fOutStargTp << "Magic Model STARGTPOINT data file" << endl;
1473 *fOutStargTp << ": ALTAZ" << endl;
1474 *fOutStargTp << "49 48 0 ";
1475 *fOutStargTp << t << endl;
1476 }
1477
1478 // Get tracking coordinates
1479 const XY xy = fCRaDec->GetCoordinates();
1480 const RaDec rd(xy.X()*TMath::DegToRad()*15, xy.Y()*TMath::DegToRad());
1481
1482 // From the star position in the camera we calculate the Alt/Az
1483 // position we are currently tracking (real pointing position)
1484 fSao->SetMjd(t.GetMjd());
1485 AltAz za0 = fSao->CalcAltAz(rd)*kRad2Deg;
1486
1487 //correction with offset from last tpoint measurement
1488 za0 -= fAltAzOffsetFromTp;
1489 MTime t2 = fTimeFromTp;
1490
1491 //if the difference between the tpoint and the starguider tpoint
1492 //is too big, the starguider tpoint is not stored
1493 cout << " mjd difference: " << t.GetMjd()-t2.GetMjd() << endl;
1494// cout << "t: " << setprecision(11) << t.GetMjd() << endl;
1495// cout << "t2: " << setprecision(11) << t2.GetMjd() << endl;
1496 if ((t.GetMjd()-t2.GetMjd())>0.001) //1min20sec
1497 {
1498 cout << " time difference between tpoint and starguider-tpoint > 1 min *" <<
1499 t.GetMjd()-t2.GetMjd() << "s) " << endl;
1500 cout << " => starguider tpoint hasn't been stored. " << endl;
1501 cout << " Please repeat whole procedure. " << endl;
1502 return numcor;
1503 }
1504
1505
1506 // Write real pointing position
1507 cout << " Alt/Az: " << za0.Alt() << "° " << za0.Az() << "°" << endl;
1508 *fOutStargTp << setprecision(7) << za0.Az() << " " << za0.Alt() << " ";
1509
1510 // Write system pointing position
1511 cout << " SE-Pos: " << 90-cpos.Zd() << "° " << cpos.Az() << "°" << endl;
1512 *fOutStargTp << fmod(cpos.Az()+360, 360) << " " << 90-cpos.Zd();
1513
1514 *fOutStargTp << " " << xy.X() << " " << xy.Y();
1515 *fOutStargTp << " " << d.Zd() << " " << d.Az();
1516 *fOutStargTp << " " << setprecision(11) << t.GetMjd();
1517 *fOutStargTp << " " << num;
1518 *fOutStargTp << " " << bright;
1519 *fOutStargTp << endl;
1520
1521 fTimeFromTp.Set(1970,1,1);
1522
1523 return numcor;
1524}
1525
1526XY MStarguider::FindRoqueLamp(FilterLed &f, FilterLed &f2, Ring &CameraCenter, MTime &t, Double_t cut, Double_t box, XY SearchCenter)
1527{
1528 // Set search Paremeters (FIXME: Get them from user input!)
1529 f.SetCut(cut); // 3.5
1530 f.SetBox(box); // 70
1531
1532 // Try to find Led in this area
1533 Leds leds;
1534 f.FindStar(leds, (Int_t)SearchCenter.X(), (Int_t)SearchCenter.Y(), true);
1535
1536 // Check whether star found
1537 Led *star = (Led*)leds.At(0);
1538 if (!star || leds.GetEntries()<1)
1539 return XY(.0,.0);
1540
1541// cout << "Found Roque Lamp @ " << flush;
1542 star->Print();
1543 f.MarkPoint(star->GetX(), star->GetY(), 500);
1544
1545// cout << "RoquePos: " << star->GetX() << "," << star->GetY() << endl;
1546
1547 XY roquepos(star->GetX(), star->GetY());
1548 XY relroquepos(roquepos.X()-CameraCenter.GetX(), roquepos.Y()-CameraCenter.GetY());
1549
1550 // If no file open: open new Roque Lamp file
1551 if (!fOutRq)
1552 {
1553 const TString name = MCosy::GetFileName("tpoint", "roquelamp", "txt");
1554 cout << "Starg_RoqueLamp File ********* " << name << " ********** " << endl;
1555 fOutRq = new ofstream(name);
1556 *fOutRq << "# Magic Roque Lamp file " << t << endl;
1557 }
1558
1559 return relroquepos;
1560}
1561
1562ZdAz MStarguider::FindStar(FilterLed &f, FilterLed &f2, Ring &center, MTime &t, Double_t cut, Double_t box, Double_t scalefactor = 1.0)
1563{
1564 // Set search Paremeters (FIXME: Get them from user input!)
1565 f.SetCut(cut); // 3.5
1566 f.SetBox(box); // 70
1567
1568 // Try to find Led in this area
1569 Leds leds;
1570 f.FindStar(leds, (Int_t)center.GetX(), (Int_t)center.GetY(), true);
1571
1572 if (leds.GetEntries()<0)
1573 return ZdAz(0, 0);
1574
1575 // Check whether star found
1576 Led *star = (Led*)leds.At(0);
1577 if (!star)
1578 {
1579 if (fTPoint->IsDown())
1580 {
1581 fTPoint->SetDown(kFALSE);
1582 cout << "No star found. Couldn't take a tpoint." << endl;
1583 }
1584 return ZdAz(.0,.0);
1585 }
1586 cout << "Found star @ " << flush;
1587 star->Print();
1588 f2.MarkPoint(star->GetX(), star->GetY(), 2<<2);
1589
1590 // Initialize Star Catalog on th camera plane
1591 MGeomCamMagic geom;
1592 MAstroCamera ac;
1593 ac.SetGeom(geom);
1594 ac.SetRadiusFOV(3);
1595 ac.SetObservatory(*fSao);
1596 ac.SetTime(t);
1597
1598 // Get tracking coordinates
1599 const XY xy = fCRaDec->GetCoordinates();
1600 const RaDec rd(xy.X()*TMath::DegToRad()*15, xy.Y()*TMath::DegToRad());
1601
1602 ac.SetRaDec(rd.Ra(), rd.Dec());
1603
1604 // Adapt coordinate system (GUIs and humans are counting Y in different directions)
1605 Double_t x = star->GetX()-center.GetX();
1606 Double_t y = center.GetY()-star->GetY();
1607
1608#ifdef EXPERT
1609 cout << "STAR-Offset: " << MTime(-1) << " dx=" << x << "pix dy=" << y << "pix" << endl;
1610#endif
1611
1612 // MAKE SURE THAT THIS VALUE CAN BE SETUP
1613 // (Scalefactor describes the difference between the tpoint (=1)
1614 // and the starguider (!=1) camera
1615 // Convert from Pixel to millimeter (1pix=2.6mm)
1616 x *= (2.58427 * scalefactor);
1617 y *= (2.58427 * scalefactor);
1618
1619 // Correct for abberation.
1620 x /= 1.0713;
1621 y /= 1.0713;
1622
1623 // Convert offset from camera plane into local ccordinates
1624 Double_t dzd, daz;
1625 ac.GetDiffZdAz(x, y, dzd, daz);
1626
1627#ifdef EXPERT
1628 cout << "STAR-Offset: " << MTime(-1) << " dZd=" << dzd << "d dAz=" << daz << "d" << endl;
1629#endif
1630
1631 ZdAz zdaz(dzd,daz);
1632
1633 // Check TPoint data set request
1634 if (!fTPoint->IsDown())
1635 return zdaz;
1636 fTPoint->SetDown(kFALSE);
1637
1638 // If no file open: open new file
1639 if (!fOutTp)
1640 {
1641 //
1642 // open tpoint file
1643 //
1644 const TString name = MCosy::GetFileName("tpoint", "tpoint", "txt");
1645 cout << "TPoint-Starg File ********* " << name << " ********** " << endl;
1646
1647 fOutTp = new ofstream(name);
1648 *fOutTp << "Magic Model TPOINT data file" << endl;
1649 *fOutTp << ": ALTAZ" << endl;
1650 *fOutTp << "49 48 0 ";
1651 *fOutTp << t << endl;
1652 // temp(°C) pressure(mB) height(m) humidity(1) wavelength(microm) troplapserate(K/m)
1653 }
1654
1655 // Output Ra/Dec the drive system thinks that it is currently tracking
1656 cout << "TPoint Star: " << xy.X() << "h " << xy.Y() << "°" << endl;
1657
1658 // From the star position in the camera we calculate the Alt/Az
1659 // position we are currently tracking (real pointing position)
1660 fSao->SetMjd(t.GetMjd());
1661 AltAz za0 = fSao->CalcAltAz(rd)*kRad2Deg;
1662
1663 //ZdAz za0 = fSao->GetZdAz();
1664 za0 -= AltAz(-dzd, daz);
1665 fAltAzOffsetFromTp = AltAz(-dzd, daz);
1666 fTimeFromTp=t;
1667
1668
1669 // From the Shaftencoders we get the current 'pointing' position
1670 // as it is seen by the drive system (system pointing position)
1671 const ZdAz za1 = fCosy->GetTrackingPosRaw();
1672
1673 // Write real pointing position
1674 cout << " Alt/Az: " << za0.Alt() << "° " << za0.Az() << "°" << endl;
1675 *fOutTp << setprecision(7) << za0.Az() << " " << za0.Alt() << " ";
1676
1677 // Write system pointing position
1678 cout << " SE-Pos: " << 90-za1.Zd() << "° " << za1.Az() << "°" << endl;
1679 *fOutTp << fmod(za1.Az()+360, 360) << " " << 90-za1.Zd();
1680
1681 *fOutTp << " " << xy.X() << " " << xy.Y();
1682 *fOutTp << " " << -dzd << " " << -daz;
1683 *fOutTp << " " << setprecision(11) << t.GetMjd();
1684 *fOutTp << " " << setprecision(4) << center.GetMag();
1685 *fOutTp << " " << star->GetMag();
1686 *fOutTp << endl;
1687
1688 MLog &outrep = *fCosy->GetOutRep();
1689 if (outrep.Lock("MStarguider::FindStar"))
1690 {
1691 outrep << "FINDSTAR-REPORT 00 " << MTime(-1) << " " << setprecision(7);
1692 outrep << 90-za0.Alt() << " " << za0.Az() << " ";
1693 outrep << za1.Zd() << " " << za1.Az() << " ";
1694 outrep << xy.X() << " " << xy.Y() << " ";
1695 outrep << -dzd << " " << -daz << " ";
1696 outrep << star->GetX() << " " << star->GetY() << " ";
1697 outrep << center.GetX() << " " << center.GetY() << " ";
1698 outrep << x*1.0713/2.58427 << " " << y*1.0713/2.58427 << " " << star->GetMag();
1699 outrep << setprecision(11) << t.GetMjd() << endl;
1700 outrep.UnLock("MStarguider::FindStar");
1701 }
1702
1703 return zdaz;
1704}
1705
1706bool MStarguider::Interpolate(const unsigned long n, byte *img) const
1707{
1708 if (fIntRate<=1)
1709 return true;
1710
1711 static unsigned short myimg[768*576];
1712
1713 unsigned short *f = myimg;
1714 byte *i = img;
1715 byte *e = img+768*576;
1716
1717 while (i<e)
1718 *f++ += *i++;
1719
1720 if (n%fIntRate)
1721 return false;
1722
1723 f = myimg;
1724 i = img;
1725 e = img+768*576;
1726
1727 while (i<e)
1728 *i++ = (byte)(*f++/fIntRate);
1729
1730 memset(myimg, 0, sizeof(myimg));
1731
1732 return true;
1733}
1734
1735void MStarguider::ProcessFrame(const unsigned long n, byte *img,
1736 struct timeval *tm)
1737{
1738 static unsigned long n0 = n;
1739
1740 MTime t(*tm);
1741
1742 const Double_t d = t-fTime;
1743 if (d>1)
1744 {
1745 MString txt;
1746 txt.Print("%dfps", (int)((n-n0)/d+.5));
1747 fFps->SetText(txt);
1748 fTime = t;
1749 n0 = n;
1750 }
1751
1752 if (!Interpolate(n, img))
1753 return;
1754
1755 byte cimg[768*576];
1756 memset(cimg, 0, 768*576);
1757
1758 FilterLed f(img, 768, 576, 2.5); // 2.5
1759 FilterLed f2(cimg, 768, 576); // former color 0xb0
1760
1761 if (fDisplay->IsEntryChecked(IDM_kStretch))
1762 f.Stretch();
1763
1764 if (!fWritePictures->IsEntryEnabled(IDM_kStart) &&
1765 (!(n%fWrtRate) || fWriteType->IsEntryChecked(IDM_kOnce)))
1766 {
1767
1768 if (fFileType->IsEntryChecked(IDM_kPNG))
1769 Writer::Png("pix/file", img, tm, fCRaDec->GetCoordinates());
1770
1771 if (fFileType->IsEntryChecked(IDM_kPPM))
1772 Writer::Ppm("pix/file", img, tm, fCRaDec->GetCoordinates());
1773
1774 if (fWriteType->IsEntryChecked(IDM_kOnce))
1775 ProcessMessage(MK_MSG(kC_COMMAND, kCM_MENU), IDM_kStop, 0);
1776 }
1777
1778 // Visual Filter, whole FOV
1779 if (fDisplay->IsEntryChecked(IDM_kFilter))
1780 f.Execute();
1781
1782 // Find Center of Camera for Caos and Tpoints
1783 Ring center(768/2, 576/2);
1784 if (fDisplay->IsEntryChecked(IDM_kCaosFilter))
1785 {
1786 const bool printl = fCaosPrint->IsEntryChecked(IDM_kCaosPrintLeds);
1787 const bool printr = fCaosPrint->IsEntryChecked(IDM_kCaosPrintRings);
1788 ZdAz pos;
1789 if (fCosy)
1790 pos = fCosy->GetPointingPos();
1791 center = fCaos->Run(img, printl, printr, pos, t, 50, 3.0);
1792 cout << "Caos Filter Camera center position: " << center.GetX() << " " << center.GetY() << endl;
1793
1794 }
1795
1796 // Find Star at Center---for Tpoint Procedure
1797 if (fDisplay->IsEntryChecked(IDM_kFindStar))
1798 {
1799 // SCALE FACTOR ASSUMED TO BE 70
1800 FindStar(f, f2, center, t, 3.5, 70);
1801 SendAmcTrigger("TPoint");
1802 }
1803
1804 byte zimg[kZOOM*kZOOM];
1805 for (int y=0; y<kZOOM; y++)
1806 for (int x=0; x<kZOOM; x++)
1807 zimg[x+y*kZOOM] = img[(fDx+(x-kZOOM/2)/2)+(fDy+(y-kZOOM/2)/2)*768];
1808
1809 fZoomImage->DrawImg(zimg);
1810
1811 if (fCosy)
1812 {
1813 byte simg[(768/2-1)*(576/2-1)];
1814 for (int y=0; y<576/2-1; y++)
1815 for (int x=0; x<768/2-1; x++)
1816 simg[x+y*(768/2-1)] = ((unsigned int)img[2*x+2*y*768]+img[2*x+2*y*768+1]+img[2*x+2*(y+1)*768]+img[2*x+2*(y+1)*768+1])/4;
1817
1818 fCosy->GetWin()->GetImage()->DrawImg(simg);
1819 }
1820
1821 // Find Center of Camera in Starfield Camera picture
1822
1823 Ring sgcenter(53.2, 293.6); // Center of camera in SG picture [px]
1824 //ZdAz sgcenterzdaz(0, 0); // Center of camera in SG picture [deg]
1825 // // (0,0)_deg is at (53.2, 293.6)_px
1826 ZdAz star(0, 0); // Star on curtain in [deg]
1827
1828 if (fDisplay->IsEntryChecked(IDM_kStargCaosFilter))
1829 {
1830 ZdAz pos;
1831 if (fCosy)
1832 pos = fCosy->GetPointingPos();
1833
1834 sgcenter = fStargCaos->Run(img, kFALSE, kFALSE, pos, t, 19, 3.0); // [px]
1835
1836 //const Float_t pixsize = atof(fPixSize->GetText()); // [arcsec/px]
1837
1838 // BE CAREFULL: This transformation is WRONG. It is just
1839 // a transformation of units, but this implies, that the
1840 // coordiante axis in both units look the same. This is
1841 // wrong exspecially near the zenith were az-lines are highly
1842 // curved around the zenith!
1843 //sgcenterzdaz.Zd((sgcenter.GetY()-293.6) * pixsize /3600 );
1844 //sgcenterzdaz.Az((sgcenter.GetX()-53.2) * pixsize /3600 );
1845#ifdef EXPERT
1846 cout << "- LEDs imply offset of Zd="
1847 << sgcenter.GetX()-53.2 << "pix Az="
1848 << sgcenter.GetY()-293.6<< "pix" << endl;
1849#endif
1850 if (fDisplay->IsEntryChecked(IDM_kStargFindStar))
1851 {
1852 star = FindStar(f, f2, sgcenter, t, 4.5, 30, 267/161.9); // [deg]
1853#ifdef EXPERT
1854 cout << "- Star is found to be off Zd=" << star.Zd()*60 << "' Az="
1855 << star.Az()*60 << "'" << endl;
1856#endif
1857 fSZdAz->SetCoordinates(star); // Misspointing found from Camera
1858
1859 SendAmcTrigger("Starguider");
1860 }
1861 }
1862
1863// Find Roque Lamp
1864
1865 if (fOperations->IsEntryChecked(IDM_kRoqueLampAna))
1866 {
1867
1868 Double_t imageclean = 1.5;
1869 Double_t boxradius = 60;
1870 //Double_t scalefactor = 1;
1871 XY searchcenter(768/2-1,576/2+25);
1872
1873 XY roquelamp = FindRoqueLamp(f, f2, sgcenter, t, imageclean, boxradius, searchcenter);
1874
1875 if (fOutRq)
1876 {
1877 ZdAz pos = fCosy->GetPointingPos();
1878
1879 *fOutRq << "RoqueLampDirect: " << MTime(-1) << " "
1880 << pos.Zd() << " " << pos.Az() << " "
1881 << roquelamp.X() << " " << roquelamp.Y() << endl;
1882 }
1883
1884 cout << "Starguider Camera Center: " << sgcenter.GetX() << "," << sgcenter.GetY() << endl;
1885 cout << ">=>=>=> Roque Lamp found at: >=>=>=> (" << roquelamp.X() << ","
1886 << roquelamp.Y() << ") <=<=<=<" << endl;
1887
1888 }
1889
1890 // Find Spot on Camera Center in Starguider camera
1891 if (fOperations->IsEntryChecked(IDM_kRoqueLampAna))
1892 {
1893 XY cameraspot(0,0);
1894
1895 Double_t imageclean = 5;
1896 Double_t boxradius = 60;
1897 //Double_t scalefactor = 1;
1898 // XY searchcenter(sgcenter.GetX(),sgcenter.GetY());
1899 XY searchcenter(60.,290.);
1900
1901 cameraspot = FindRoqueLamp(f, f2, sgcenter, t, imageclean, boxradius, searchcenter);
1902
1903 if (fOutRq)
1904 {
1905 ZdAz pos = fCosy->GetPointingPos();
1906
1907 *fOutRq << "RoqueLampReflected: " << MTime(-1) << " "
1908 << pos.Zd() << " " << pos.Az() << " "
1909 << cameraspot.X() << " " << cameraspot.Y() << endl;
1910 }
1911
1912 cout << ">>>>> Spot on Magic camera found at: >>>>> (" << cameraspot.X() << ","
1913 << cameraspot.Y() << ") <<<<<" << endl;
1914
1915 f2.DrawCircle(sgcenter, 5.0, 0x0fa);
1916 f2.DrawCircle(sgcenter, 115.0, 0x0fa);
1917 }
1918 // we calculate the offset given by the three ETH Leds visible to
1919 // the guide camera
1920 // This is an (inferior, obsolete) alternative to the StarCaosFilter
1921 // Led offset;
1922 // if (fDisplay->IsEntryChecked(IDM_kStargLEDFilter))
1923 // fStargLeds->Run(img,offset);
1924
1925 // Position corresponding to the camera center (53.2, 293.6)
1926 //Ring skycenter(392, 318);
1927 // MStarList spots;
1928
1929 // we obtain a list of stars in the FOV from the SAO catalog
1930 if (fDisplay->IsEntryChecked(IDM_kCatalog))
1931 {
1932 MTime time(*tm);
1933
1934 XY xy = fCRaDec->GetCoordinates();
1935 fRaDec->Set(xy.X()*360/24, xy.Y());
1936
1937 UpdatePosZoom();
1938
1939 // Always call SetMjd first!
1940 fSao->SetPointing(time.GetMjd(), *fRaDec);
1941 fCZdAz->SetCoordinates(fSao->GetZdAz());
1942
1943 MStarList stars;
1944 fSao->SetBox(230); // Region of interest around center
1945
1946 // very careful: If center of camera cannot be determined
1947 // sgcenter jumps to (0,0)
1948
1949 //Please never change this offsets!!!
1950 // 53.2 and 293.6 are the "preliminary" camera center
1951 // -9 and 28.5 are the offsets of the pointing position in the sky
1952
1953 const Bool_t centerisvalid = sgcenter.GetX()>0 && sgcenter.GetY()>0;
1954// if (centerisvalid)
1955// skycenter.SetXY(sgcenter.GetX() - 53.2,
1956// sgcenter.GetY() - 293.6);
1957
1958 // we obtain stars in the effective star FOV and draw them.
1959 // coordinates are video frame coords.
1960 // We determine the ideal starfield using camera sagging info
1961 // from the LEDs
1962 const XY off(sgcenter.GetX()- 53.2-9,
1963 sgcenter.GetY()-293.6+28.5);
1964
1965 fSao->CalcStars(stars, 530, 292, off.X(), off.Y());
1966 fSao->DrawStars(stars, cimg);
1967
1968 // Position around which the circles are drawn.
1969 const Ring skycenter(768/2-off.X(), 576/2+off.Y());
1970
1971 // There are two corrections to the misspointing
1972 // - Sagging of the camera as measured with the LEDs
1973 // - Star not ideally centered on MAGIC Camera
1974
1975 // Next we evaluate the offset given by the LEDs. This we obtain
1976 // in Zd/Az and add it to the tracking error.
1977 if (fDisplay->IsEntryChecked(IDM_kStarguider))
1978 {
1979 const Float_t cut = atof(fCut->GetText());
1980
1981 Leds spots;
1982 f.SetBox(230);
1983 f.SetCut(cut);
1984
1985 double bright;
1986 f.ExecuteAndMark(spots, 530, 292, bright);
1987
1988 ULong_t color;
1989 gClient->GetColorByName("Green", color);
1990 if (bright> 60)
1991 gClient->GetColorByName("Yellow", color);
1992 if (bright> 85)
1993 gClient->GetColorByName("Orange", color);
1994 if (bright> 95)
1995 gClient->GetColorByName("Red", color);
1996 fSkyBright->SetBackgroundColor(color);
1997
1998 MString txt;
1999 txt.Print("Sky Brightness: %.1f", bright);
2000 fSkyBright->SetText(txt);
2001
2002 const Bool_t brightnessisvalid = bright<1.75*fLastBright &&
2003 bright>30 && bright<110;
2004
2005 fLastBright = bright;
2006
2007 Int_t numstars = 0;
2008 const Int_t rc = CalcTrackingError(spots, stars, fD, t, bright, numstars);
2009
2010 const Bool_t monitoring = brightnessisvalid && centerisvalid;
2011
2012 fStatus = monitoring ? MDriveCom::kMonitoring : MDriveCom::kError;
2013
2014 if (fCosy)
2015 fPos = fCosy->GetPointingPos();
2016
2017 if (fOperations->IsEntryChecked(IDM_kStargAnalysis))
2018 fStargHistograms->Fill(spots, stars, fD,
2019 fSao->GetZdAz(), sgcenter, /*sgcenterzdaz,*/
2020 star, bright, fPos, t);
2021
2022 fNumStarsDetected = numstars;
2023 fNumStarsCorrelated = rc;
2024
2025 if (fCosy)
2026 {
2027 MDriveCom &com = *fCosy->GetDriveCom();
2028 com.SendStargReport(fStatus, fD, fSao->GetZdAz(),
2029 sgcenter, numstars, rc, bright,
2030 time.GetMjd(), 0, 0); // Report
2031 }
2032
2033 } //kStarguider
2034
2035 if (centerisvalid && fNumStarsCorrelated>2)
2036 {
2037 f2.DrawCircle(skycenter, 2.0, 0x0a);
2038
2039 const Double_t ap = fSao->GetPixSize()/3600; //[deg/pix]
2040
2041 f2.DrawCircle(skycenter, 0.10/ap, 0x0a); //0.1deg
2042 f2.DrawHexagon(skycenter, 2.06/ap, 0x0a);
2043 f2.DrawHexagon(skycenter, 3.50/ap, 0x0a);
2044
2045 /*
2046 f2.DrawCircle(skycenter, 2.06*.5*74.0, 0x0a);
2047 f2.DrawCircle(skycenter, 2.32*.5*74.0, 0x0a);
2048 f2.DrawCircle(skycenter, 3.50*.5*74.0, 0x0a);
2049 f2.DrawCircle(skycenter, 3.84*.5*74.0, 0x0a);
2050 */
2051 }
2052
2053 } //CalcStars
2054
2055 // Draw Circles around center of Camera
2056 if (fDisplay->IsEntryChecked(IDM_kCaosFilter))
2057 {
2058 f2.DrawCircle(center, 0x0a);
2059 f2.DrawCircle(center, 7.0,
2060 fDisplay->IsEntryChecked(IDM_kFindStar)?3:0xb0);
2061 f2.DrawCircle(center, 115.0, 0x0a);
2062 f2.DrawCircle(center, 230.0, 0x0a);
2063 f2.DrawCircle(center, 245.0, 0x0a);
2064 }
2065
2066 if (fDisplay->IsEntryChecked(IDM_kStargCaosFilter))
2067 {
2068 f2.DrawCircle(sgcenter, 0x0a);
2069 f2.DrawCircle(sgcenter, 5.0,
2070 fDisplay->IsEntryChecked(IDM_kFindStar)?3:0xb0);
2071 }
2072
2073// if (fDisplay->IsEntryChecked(IDM_kCatalog))
2074// {
2075// fSao->PaintImg(cimg, 768, 576);
2076// const float r = 60*60/fSao->GetPixSize();
2077// f2.DrawCircle(0.5*r, 0x0a);
2078// f2.DrawCircle(1.0*r, 0x0a);
2079// f2.DrawCircle(1.5*r, 0x0a);
2080// }
2081
2082 if (fDisplay->IsEntryChecked(IDM_kCaosFilter) ||
2083 fDisplay->IsEntryChecked(IDM_kCatalog) ||
2084 fDisplay->IsEntryChecked(IDM_kFindStar) ||
2085 fOperations->IsEntryChecked(IDM_kRoqueLampAna))
2086 fImage->DrawColImg(img, cimg);
2087 else
2088 fImage->DrawImg(img);
2089}
2090
2091void MStarguider::UpdatePosZoom()
2092{
2093 MString txt;
2094 if (fDisplay->IsEntryChecked(IDM_kCatalog))
2095 {
2096 // FIXME: Necessary?
2097 fSao->Now();
2098 AltAz aa = fSao->CalcAltAzFromPix(fDx, fDy)*kRad2Deg;
2099 if (aa.Az()<0)
2100 aa.Az(aa.Az()+360);
2101 txt.Print("(%d, %d) %.1fd/%.1fd", fDx, fDy, -aa.Alt(), aa.Az()-180);
2102 }
2103 else
2104 txt.Print("(%d, %d)", fDx, fDy);
2105 fPosZoom->SetText(txt);
2106}
2107
2108Bool_t MStarguider::HandleDoubleClick(Event_t *event)
2109{
2110 const Int_t w = fImage->GetWidth();
2111 const Int_t h = fImage->GetHeight();
2112 const Int_t x = fImage->GetX();
2113 const Int_t y = fImage->GetY();
2114
2115 if (!(event->fX>x && event->fX<x+w && event->fY>y && event->fY<y+h))
2116 return kTRUE;
2117
2118 Int_t dx = event->fX-x;
2119 Int_t dy = event->fY-y;
2120
2121 if (dx<kZOOM/4) dx=kZOOM/4;
2122 if (dy<kZOOM/4) dy=kZOOM/4;
2123 if (dx>766-kZOOM/4) dx=766-kZOOM/4;
2124 if (dy>574-kZOOM/4) dy=574-kZOOM/4;
2125
2126 fDx = dx;
2127 fDy = dy;
2128
2129 UpdatePosZoom();
2130 return kTRUE;
2131}
2132
2133void MStarguider::Print(TString &str, Double_t deg) const
2134{
2135 Char_t sgn;
2136 UShort_t d, m, s;
2137
2138 MAstro::Deg2Dms(deg, sgn, d, m, s);
2139
2140 MString txt;
2141 str += txt.Print("%c %03d %02d %03d ", sgn, d, m, s);
2142}
Note: See TracBrowser for help on using the repository browser.