#include "MGStarguider.h" #include // ifstream #include // cout #include #include #include #include // TGHorizontal3DLine #include #include "MGImage.h" #include "MGCoordinates.h" #include "coord.h" #include "StarCatalog.h" #include "Filter.h" #include "Filter2.h" #include "Writer.h" #include "base/timer.h" #include "MStarList.h" ClassImp(MGStarguider); enum { IDM_kFilter, IDM_kCatalog, IDM_kStarguider, IDM_kStart, IDM_kStop, IDM_kFileType, IDM_kPPM, IDM_kPNG, IDM_kOnce, IDM_kUseFileRaDec, IDM_kContinous, IDM_kRate25ps, IDM_kRate5ps, IDM_kRate1s, IDM_kRate5s, IDM_kRate30s, IDM_kRate1m, IDM_kRate5m, IDM_kSetup, IDM_kLimMag3, IDM_kLimMag4, IDM_kLimMag5, IDM_kLimMag6, IDM_kLimMag7, IDM_kLimMag8, IDM_kLimMag9, IDM_kPixSize, IDM_kInterpol125, IDM_kInterpol25, IDM_kInterpol10, IDM_kInterpol5, IDM_kInterpol2, IDM_kInterpol1 }; Bool_t MGStarguider::HandleTimer(TTimer *t) { fImage->DoRedraw(); fZoomImage->DoRedraw(); return kTRUE; } #define kZOOM 96 MGStarguider::MGStarguider() : Camera(), TGMainFrame(gClient->GetRoot(), 768, 700), fDx((768-kZOOM)/2), fDy((512-kZOOM)/2) { gVirtualX->GrabButton(fId, kButton2, /*kButtonPressMask|kButtonReleaseMask|*/kNone, kNone, kNone, kNone); fList = new MGList; fSao = new StarCatalog; fRaDec = new RaDec(180, 40); // p = pointer to MainFrame (not owner) const TGWindow *p=gClient->GetRoot(); // // Create Menu for MGStarguider Display // fDisplay = new TGPopupMenu(p); fDisplay->AddEntry("&Filter", IDM_kFilter); fDisplay->AddEntry("Sao &Catalog", IDM_kCatalog); fDisplay->AddEntry("Starguider", IDM_kStarguider); fDisplay->Associate(this); fList->Add(fDisplay); fFileType = new TGPopupMenu(p); fFileType->AddEntry("PP&M", IDM_kPPM); fFileType->AddEntry("&PNG", IDM_kPNG); fFileType->CheckEntry(IDM_kPNG); fFileType->Associate(this); fList->Add(fFileType); fWriteType = new TGPopupMenu(p); fWriteType->AddEntry("Once", IDM_kOnce); fWriteType->AddEntry("Continous", IDM_kContinous); fWriteType->CheckEntry(IDM_kOnce); fWriteType->Associate(this); fList->Add(fWriteType); fWriteRate = new TGPopupMenu(p); fWriteRate->AddEntry("25/s", IDM_kRate25ps); fWriteRate->AddEntry("5/s", IDM_kRate5ps); fWriteRate->AddEntry("1s", IDM_kRate1s); fWriteRate->AddEntry("5s", IDM_kRate5s); fWriteRate->AddEntry("30s", IDM_kRate30s); fWriteRate->AddEntry("1min", IDM_kRate1m); fWriteRate->AddEntry("5min", IDM_kRate5m); fWriteRate->CheckEntry(IDM_kRate1m); fWriteRate->Associate(this); fList->Add(fWriteRate); fWrtRate = 25*60; fWrite = new TGPopupMenu(p); fWrite->AddEntry("&Start", IDM_kStart); fWrite->AddEntry("Sto&p", IDM_kStop); fWrite->AddSeparator(); fWrite->AddPopup("File &Type", fFileType); fWrite->AddPopup("&Write Type", fWriteType); fWrite->AddPopup("Write &Rate", fWriteRate); fWrite->DisableEntry(IDM_kStop); fWrite->Associate(this); fList->Add(fWrite); fLimMag = new TGPopupMenu(p); fLimMag->AddEntry("3", IDM_kLimMag3); fLimMag->AddEntry("4", IDM_kLimMag4); fLimMag->AddEntry("5", IDM_kLimMag5); fLimMag->AddEntry("6", IDM_kLimMag6); fLimMag->AddEntry("7", IDM_kLimMag7); fLimMag->AddEntry("8", IDM_kLimMag8); fLimMag->AddEntry("9", IDM_kLimMag9); fLimMag->CheckEntry(IDM_kLimMag8); fLimMag->Associate(this); fList->Add(fLimMag); fSao->SetLimitMag(8.0); fInterpol = new TGPopupMenu(p); fInterpol->AddEntry("125", IDM_kInterpol125); fInterpol->AddEntry("25", IDM_kInterpol25); fInterpol->AddEntry("10", IDM_kInterpol10); fInterpol->AddEntry("5", IDM_kInterpol5); fInterpol->AddEntry("2", IDM_kInterpol2); fInterpol->AddEntry("Off", IDM_kInterpol1); fInterpol->CheckEntry(IDM_kInterpol25); fInterpol->Associate(this); fList->Add(fInterpol); fIntRate = 25; fSetup = new TGPopupMenu(p); fSetup->AddPopup("Lim. &Magnitude", fLimMag); fSetup->AddPopup("Disp. &Interpolation", fInterpol); fSetup->AddEntry("Use Ra/Dec from file", IDM_kUseFileRaDec); fSetup->Associate(this); fList->Add(fSetup); fMenu = new TGMenuBar(this, 0, 0, kHorizontalFrame); fMenu->AddPopup("&Display", fDisplay, NULL); fMenu->AddPopup("&Write", fWrite, NULL); fMenu->AddPopup("&Setup", fSetup, NULL); fMenu->Resize(fMenu->GetDefaultSize()); AddFrame(fMenu); //, new TGLayoutHints (kLHintsNormal, 0, 4, 0, 0)); fList->Add(fMenu); fCRaDec = new MGCoordinates(this, kETypeRaDec); fCRaDec->Move(1, fMenu->GetDefaultHeight()+584); AddFrame(fCRaDec); fList->Add(fCRaDec); fCZdAz = new MGCoordinates(this, kETypeZdAz); fCZdAz->Move(240+12+10, fMenu->GetDefaultHeight()+584); AddFrame(fCZdAz); fList->Add(fCZdAz); const Double_t pixsize = 23.4; fSao->SetPixSize(pixsize/3600); TString txt; txt += pixsize; fPixSize = new TGTextEntry(this, txt, IDM_kPixSize); fPixSize->SetAlignment(kTextCenterX); fPixSize->Move(600, fMenu->GetDefaultHeight()+584); AddFrame(fPixSize); fList->Add(fPixSize); // TGHorizontal3DLine *fLineSep = new TGHorizontal3DLine(this); // AddFrame(fLineSep, new TGLayoutHints (kLHintsNormal | kLHintsExpandX)); // fList->Add(fLineSep); // // Create Image Display // fZoomImage = new MGImage(this, kZOOM, kZOOM); fZoomImage->Move(768-kZOOM-2, 700-kZOOM-2); AddFrame(fZoomImage); fList->Add(fZoomImage); fImage = new MGImage(this, 768, 576); fImage->Move(0, fMenu->GetDefaultHeight()); AddFrame(fImage); fList->Add(fImage); // // Make everything visible // SetWindowName("MGStarguider Main Window"); SetIconName("MGStarguider"); MapSubwindows(); MapWindow(); fTimer=new TTimer(this, 100); // 100ms fTimer->TurnOn(); } MGStarguider::~MGStarguider() { fTimer->TurnOff(); delete fTimer; delete fSao; delete fRaDec; delete fList; cout << "Camera Display destroyed." << endl; } void MGStarguider::Layout() { // Resize(GetDefaultSize()); } void MGStarguider::CloseWindow() { cout << "EventDisplay::CloseWindow: Exit Application Loop." << endl; ExitLoop(); gSystem->ExitLoop(); } void MGStarguider::Toggle(TGPopupMenu *p, UInt_t id) { if (p->IsEntryChecked(id)) p->UnCheckEntry(id); else p->CheckEntry(id); } Bool_t MGStarguider::ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2) { switch (GET_MSG(msg)) { case kC_TEXTENTRY: if (GET_SUBMSG(msg)==kTE_ENTER) { const Float_t pixsize = atof(fPixSize->GetText()); cout << "Pixel Size changed to " << pixsize << "\"/pix" << endl; fSao->SetPixSize(pixsize/3600); } return kTRUE; case kC_COMMAND: switch (GET_SUBMSG(msg)) { case kCM_MENU: switch (mp1) { case IDM_kCatalog: Toggle(fDisplay, IDM_kCatalog); if (fDisplay->IsEntryChecked(IDM_kCatalog)) fDisplay->EnableEntry(IDM_kStarguider); else { fDisplay->UnCheckEntry(IDM_kStarguider); fDisplay->DisableEntry(IDM_kStarguider); } return kTRUE; case IDM_kStarguider: Toggle(fDisplay, IDM_kStarguider); return kTRUE; case IDM_kFilter: Toggle(fDisplay, IDM_kFilter); if (fDisplay->IsEntryChecked(IDM_kFilter)) fDisplay->EnableEntry(IDM_kStarguider); else { fDisplay->UnCheckEntry(IDM_kStarguider); fDisplay->DisableEntry(IDM_kStarguider); } return kTRUE; case IDM_kUseFileRaDec: Toggle(fSetup, IDM_kUseFileRaDec); return kTRUE; case IDM_kStart: fWrite->DisableEntry(IDM_kStart); fWrite->EnableEntry(IDM_kStop); return kTRUE; case IDM_kStop: fWrite->DisableEntry(IDM_kStop); fWrite->EnableEntry(IDM_kStart); return kTRUE; case IDM_kPNG: fFileType->CheckEntry(IDM_kPNG); fFileType->UnCheckEntry(IDM_kPPM); return kTRUE; case IDM_kPPM: fFileType->CheckEntry(IDM_kPPM); fFileType->UnCheckEntry(IDM_kPNG); return kTRUE; case IDM_kOnce: fWriteType->CheckEntry(IDM_kOnce); fWriteType->UnCheckEntry(IDM_kContinous); return kTRUE; case IDM_kContinous: fWriteType->CheckEntry(IDM_kContinous); fWriteType->UnCheckEntry(IDM_kOnce); return kTRUE; case IDM_kRate25ps: case IDM_kRate5ps: case IDM_kRate1s: case IDM_kRate5s: case IDM_kRate30s: case IDM_kRate1m: case IDM_kRate5m: for (int i=IDM_kRate25ps; i<=IDM_kRate5m; i++) if (mp1==i) fWriteRate->CheckEntry(i); else fWriteRate->UnCheckEntry(i); switch (mp1) { case IDM_kRate25ps: fWrtRate = 1; return kTRUE; case IDM_kRate5ps: fWrtRate = 5; return kTRUE; case IDM_kRate1s: fWrtRate = 25; return kTRUE; case IDM_kRate5s: fWrtRate = 5*25; return kTRUE; case IDM_kRate30s: fWrtRate = 30*25; return kTRUE; case IDM_kRate1m: fWrtRate = 60*25; return kTRUE; case IDM_kRate5m: fWrtRate = 5*60*25; return kTRUE; } return kTRUE; case IDM_kInterpol125: case IDM_kInterpol25: case IDM_kInterpol10: case IDM_kInterpol5: case IDM_kInterpol2: case IDM_kInterpol1: for (int i=IDM_kInterpol125; i<=IDM_kInterpol1; i++) if (mp1==i) fInterpol->CheckEntry(i); else fInterpol->UnCheckEntry(i); switch (mp1) { case IDM_kInterpol1: fIntRate = 1; return kTRUE; case IDM_kInterpol2: fIntRate = 2; return kTRUE; case IDM_kInterpol5: fIntRate = 5; return kTRUE; case IDM_kInterpol10: fIntRate = 10; return kTRUE; case IDM_kInterpol25: fIntRate = 25; return kTRUE; case IDM_kInterpol125: fIntRate = 125; return kTRUE; } return kTRUE; case IDM_kLimMag3: case IDM_kLimMag4: case IDM_kLimMag5: case IDM_kLimMag6: case IDM_kLimMag7: case IDM_kLimMag8: case IDM_kLimMag9: for (int i=IDM_kLimMag3; i<=IDM_kLimMag9; i++) if (mp1==i) fLimMag->CheckEntry(i); else fLimMag->UnCheckEntry(i); fSao->SetLimitMag(mp1-IDM_kLimMag3+3); return kTRUE; } break; } break; } return kTRUE; } void MGStarguider::GetCoordinates() { XY xy = fCRaDec->GetCoordinates(); if (fSetup->IsEntryChecked(IDM_kUseFileRaDec)) { ifstream fin("coordinates.txt"); if (!fin) cout << "Error: Cannot open 'coordinates.txt' using fall back solution." << endl; else fin >> xy; } fCRaDec->SetCoordinates(xy); fRaDec->Set(xy.X()*360/24, xy.Y()); } void MGStarguider::CalcTrackingError(MStarList &spots, MStarList &stars) { if (stars.GetRealEntries() < 3) { cout << "Sorry, less than 3 stars in FOV!" << endl; return; } if (spots.GetRealEntries() < 1) { cout << "Sorry, less than 1 detected spot in FOV!" << endl; return; } Int_t idx = 0; MStarList sortedspots; MStar *star; MStar *spot; MStarListIter NextStar(&stars); MStarListIter NextSpot(&spots); while ((spot=NextSpot())) { AltAz aa = fSao->CalcAltAzFromPix(spot->GetX(), spot->GetY()); spot->Set(aa.Az(), aa.Alt()); } while ((star=NextStar())) { AltAz aa = fSao->CalcAltAzFromPix(star->GetX(), star->GetY()); star->Set(aa.Az(), aa.Alt()); const double aaz = star->GetX(); const double dphi2 = aaz/2.; const double cos2 = cos(dphi2)*cos(dphi2); const double sin2 = sin(dphi2)*sin(dphi2); Double_t min = 800; NextSpot.Reset(); while ((spot=NextSpot())) { const double pzd = TMath::Pi()/2-spot->GetY(); const double azd = TMath::Pi()/2-star->GetY(); const double d = cos(azd)*cos2 - cos(2*pzd+azd)*sin2; const Double_t dist = acos(d); if (dist>=min) continue; min = dist; sortedspots.AddAt(idx, spot->GetX(), spot->GetY(), spot->GetMag()); } if (min>768) { cout << "ERROR!!!!!!!!" << endl; return; } idx++; } // // Now we have in sortedspots the entries with the shortest distances // to the corresponding ones in stars. // Now calculate the tracking error. // NextStar.Reset(); MStarListIter NextSpot2(&sortedspots); Double_t meanx=0; Double_t meany=0; while ((star=NextStar())) { spot = NextSpot2(); meanx += star->GetX() - spot->GetX(); meany += star->GetY() - spot->GetY(); } meanx /= idx; meany /= idx; cout << "Tracking Error: dAlt=" << meany*180/TMath::Pi(); cout << "° dAz=" << meanx*180/TMath::Pi() << "° (calculated"; cout << " with " << idx << " stars/spots)" << endl; } void MGStarguider::ProcessFrame(const unsigned long n, byte *img, struct timeval *tm) { if (!fWrite->IsEntryEnabled(IDM_kStart) && (!(n%fWrtRate) || fWriteType->IsEntryChecked(IDM_kOnce))) { if (fFileType->IsEntryChecked(IDM_kPNG)) { static int num = 0; char name[80]; sprintf(name, "pix/file%04d.png", num++); Writer::Png(name, img, tm); } if (fFileType->IsEntryChecked(IDM_kPPM)) { static int num = 0; char name[80]; sprintf(name, "pix/file%04d.ppm", num++); Writer::Ppm(name, img); } if (fWriteType->IsEntryChecked(IDM_kOnce)) ProcessMessage(MK_MSG(kC_COMMAND, kCM_MENU), IDM_kStop, 0); } static float myimg[768*576]; for (int i=0; i<768*576; i++) myimg[i] += img[i]; if (n%fIntRate) return; cout << "Img: " << n << endl; byte c[768*576]; for (int i=0; i<768*576; i++) c[i] = (byte)(myimg[i]/fIntRate+.5); MStarList spots; if (fDisplay->IsEntryChecked(IDM_kStarguider)) Filter2::Execute(spots, c); else if (fDisplay->IsEntryChecked(IDM_kFilter)) Filter::Execute(c); byte zimg[kZOOM*kZOOM]; for (int y=0; yDrawImg(zimg); if (fDisplay->IsEntryChecked(IDM_kCatalog)) { byte cimg[768*576]; GetCoordinates(); Timer time(tm); MStarList stars; fSao->GetStars(stars, time.CalcMjd(), *fRaDec); fSao->GetImg(c, cimg, stars); //fSao->GetImg(c, cimg, time.CalcMjd(), *fRaDec); fImage->DrawColImg(c, cimg); fCZdAz->SetCoordinates(fSao->GetZdAz()); if (fDisplay->IsEntryChecked(IDM_kStarguider)) CalcTrackingError(spots, stars); } else fImage->DrawImg(c); memset(myimg, 0, 768*576*sizeof(float)); } Bool_t MGStarguider::HandleDoubleClick(Event_t *event) { const Int_t w = fImage->GetWidth(); const Int_t h = fImage->GetHeight(); const Int_t x = fImage->GetX(); const Int_t y = fImage->GetY(); if (!(event->fX>x && event->fXfY>y && event->fYfX-x; Int_t dy = event->fY-y; if (dx766-kZOOM/2) dx=766-kZOOM/4; if (dy>510-kZOOM/2) dy=510-kZOOM/4; fDx = dx; fDy = dy; cout << "New coordinates for zoom: " << fDx << " " << fDy << endl; return kTRUE; }