/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz 10/2001 ! ! Copyright: MAGIC Software Development, 2000-2002 ! ! \* ======================================================================== */ #include "MGEvtDisplay.h" #include // atoi #include // TGTab #include // TGPopupMenu #include // TCanvas::Print #include // TGLabel #include // TGPictureButton #include // TGMsgBox #include // TGTextEntry #include // TGFileDialog #include // TRootEmbeddedCanvas #include // TGHorizontal3DLine // use TGSplitter instead for root<3.00 #include "MParList.h" #include "MTaskList.h" #include "MEvtLoop.h" #include "MCamDisplay.h" #include "MReadMarsFile.h" #include "MGeomCamMagic.h" #include "MRawEvtHeader.h" #include "MMcEvt.hxx" ClassImp(MGEvtDisplay); enum MGCamDisplayCommand { kEvtPrev, kEvtNext, kEvtNumber, kFileSaveAs, kFileSaveAsRoot, kFileSaveAsC, kFileSaveAsPS, kFileSaveAsEPS, kFileSaveAsGIF, kFilePrint, kClose }; // -------------------------------------------------------------------------- // // Return a pointer to the parameter list. // MParList *MGEvtDisplay::GetParList() const { return fEvtLoop->GetParList(); } // -------------------------------------------------------------------------- // // Return a pointer to the task list. // MTaskList *MGEvtDisplay::GetTaskList() const { return (MTaskList*)GetParList()->FindObject("MTaskList"); } // -------------------------------------------------------------------------- // // Return a pointer to the reader task (MReadTree) // MReadTree *MGEvtDisplay::GetReader() const { return (MReadTree*)GetTaskList()->FindObject("MRead"); } // -------------------------------------------------------------------------- // // Add the top part of the frame: This is filename and treename display // void MGEvtDisplay::AddTopFramePart1(TGVerticalFrame *frame, const char *filename, const char *treename) { // // --- the top1 part of the window --- // TGHorizontalFrame *top1 = new TGHorizontalFrame(frame, 300, 100); fList->Add(top1); // // create gui elements // TGLabel *lfile = new TGLabel(top1, new TGString("File:")); TGLabel *file = new TGLabel(top1, new TGString(filename)); TGLabel *ltree = new TGLabel(top1, new TGString("Tree:")); TGLabel *tree = new TGLabel(top1, new TGString(treename)); fList->Add(lfile); fList->Add(file); fList->Add(ltree); fList->Add(tree); // // layout and add gui elements in/to frame // TGLayoutHints *laystd = new TGLayoutHints(kLHintsLeft, 10, 10, 10, 10); fList->Add(laystd); top1->AddFrame(lfile, laystd); top1->AddFrame(file, laystd); top1->AddFrame(ltree, laystd); top1->AddFrame(tree, laystd); // // --- the top1 part of the window --- // TGHorizontalFrame *top2 = new TGHorizontalFrame(frame, 300, 100); fList->Add(top2); fEvtInfo = new TGLabel(top2, new TGString("")); fList->Add(fEvtInfo); top2->AddFrame(fEvtInfo, laystd); // // layout and add frames // TGLayoutHints *laytop1 = new TGLayoutHints(kLHintsTop); fList->Add(laytop1); frame->AddFrame(top1, laytop1); frame->AddFrame(top2, laytop1); } // -------------------------------------------------------------------------- // // Add the second part of the top frame: This are the event number controls // void MGEvtDisplay::AddTopFramePart2(TGVerticalFrame *frame) { // // --- the top2 part of the window --- // TGHorizontalFrame *top2 = new TGHorizontalFrame(frame, 300, 100); fList->Add(top2); // // Create the gui elements // TGTextButton *prevevt = new TGTextButton(top2, "<< Previous Event", kEvtPrev); prevevt->Associate(this); TGLabel *evtnr = new TGLabel(top2, new TGString("Event: ")); fTxtEvtNr = new TGTextEntry(top2, new TGTextBuffer(100), kEvtNumber); fTxtEvtNr->Resize(60, fTxtEvtNr->GetDefaultHeight()); fTxtEvtNr->Associate(this); fNumOfEvts = new TGLabel(top2, "out of Events."); TGTextButton *nextevt = new TGTextButton (top2, "Next Event >>", kEvtNext); nextevt->Associate(this); // // Add gui elements to 'atotodel' // fList->Add(prevevt); fList->Add(evtnr); fList->Add(fTxtEvtNr); fList->Add(fNumOfEvts); fList->Add(nextevt); // // add the gui elements to the frame // TGLayoutHints *laystd = new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 10, 10, 10); fList->Add(laystd); top2->AddFrame(prevevt, laystd); top2->AddFrame(evtnr, laystd); top2->AddFrame(fTxtEvtNr, laystd); top2->AddFrame(fNumOfEvts, laystd); top2->AddFrame(nextevt, laystd); frame->AddFrame(top2, new TGLayoutHints(kLHintsCenterX)); } // -------------------------------------------------------------------------- // // Add a tab with an embedded canvas for an camera display and return the // pointer to the canvas // TCanvas *MGEvtDisplay::AddTab(TString name) { TGLayoutHints *laycanvas = new TGLayoutHints(kLHintsCenterX|kLHintsCenterY|kLHintsExpandX|kLHintsExpandY); fList->Add(laycanvas); TGCompositeFrame *frame = fEvtDisplay->AddTab(name); TRootEmbeddedCanvas *canvas = new TRootEmbeddedCanvas(name+"Display", frame, 400, 400); frame->AddFrame(canvas, laycanvas); fList->Add(canvas); return canvas->GetCanvas(); } // -------------------------------------------------------------------------- // // Add the mid frame: This are the two tabs with the canvas in the right one // void MGEvtDisplay::AddMidFrame(TGHorizontalFrame *frame) { // // create tab control // TGTab *tabs = new TGTab(frame, 300, 300); // // Create Tab1 // fTab1 = tabs->AddTab("Setup"); // // Crete second gui elemet for tab1 (TGVertical Frame) // TGLayoutHints *laytabs = new TGLayoutHints(kLHintsNormal|kLHintsExpandY, 10, 10, 10, 10); frame->AddFrame(tabs, laytabs); // // Create second part of frame // fEvtDisplay = new TGTab(frame, 300, 300); fCanvas=AddTab("Photons"); AddTab("Geometry"); MGeomCamMagic geom; MCamDisplay *display = new MCamDisplay(&geom); display->Draw(); display->DrawPixelNumbers(); fList->Add(display); // // Add second part to frame // TGLayoutHints *laydisp = new TGLayoutHints(kLHintsNormal|kLHintsExpandY|kLHintsExpandX, 10, 10, 10, 10); frame->AddFrame(fEvtDisplay, laydisp); // // Now add all gui elements to 'autodel'-list // fList->Add(fEvtDisplay); fList->Add(laydisp); fList->Add(laytabs); } // -------------------------------------------------------------------------- // // Add the low frame: These are the buttons Print and Close // void MGEvtDisplay::AddLowFrame(TGHorizontalFrame *frame) { TGTextButton *but = new TGTextButton(frame, "Close", kClose); but->Associate(this); fList->Add(but); TGLayoutHints *laybut = new TGLayoutHints(kLHintsLeft, 10, 10, 10, 10); fList->Add(laybut); frame->AddFrame(but, laybut); } // -------------------------------------------------------------------------- // // Create and setup all the three frames and build the window interieur // void MGEvtDisplay::AddFrames(const char *filename, const char *treename) { // // Create the frame elements and add gui elements to it // TGVerticalFrame *frametop = new TGVerticalFrame(this, 300, 100); fList->Add(frametop); AddTopFramePart1(frametop, filename, treename); AddTopFramePart2(frametop); TGLayoutHints *laytop = new TGLayoutHints(kLHintsTop|kLHintsCenterX); fList->Add(laytop); // ----- TGHorizontalFrame *framemid = new TGHorizontalFrame(this, 300, 100); fList->Add(framemid); AddMidFrame(framemid); TGLayoutHints *laymid = new TGLayoutHints(kLHintsExpandY|kLHintsExpandX); fList->Add(laymid); // // add frame elements to 'autodel' // TGHorizontal3DLine *line1 = new TGHorizontal3DLine(this); TGHorizontal3DLine *line2 = new TGHorizontal3DLine(this); fList->Add(line1); fList->Add(line2); TGLayoutHints *layline = new TGLayoutHints(kLHintsTop|kLHintsExpandX); fList->Add(layline); // ----- TGHorizontalFrame *framelow = new TGHorizontalFrame(this, 300, 100); fList->Add(framelow); AddLowFrame(framelow); TGLayoutHints *laylow = new TGLayoutHints(kLHintsTop); fList->Add(laylow); // // Layout frame elements and add elements to frame // AddFrame(frametop, laytop); AddFrame(line1, layline); AddFrame(framemid, laymid); AddFrame(line2, layline); AddFrame(framelow, laylow); } // -------------------------------------------------------------------------- // // Constructor // void MGEvtDisplay::AddMenuBar() { // // Add all GUI elements and update the event counter // TGLayoutHints *laymenubar = new TGLayoutHints(kLHintsTop|kLHintsLeft|kLHintsExpandX, 2, 2, 2, 2); TGLayoutHints *laymenuitem = new TGLayoutHints(kLHintsTop|kLHintsLeft, 0, 4, 0, 0); TGLayoutHints *laylinesep = new TGLayoutHints(kLHintsTop|kLHintsExpandX); fList->Add(laymenubar); fList->Add(laymenuitem); fList->Add(laylinesep); TGPopupMenu *filemenu = new TGPopupMenu(gClient->GetRoot()); filemenu->AddEntry("Save &As...", kFileSaveAs); filemenu->AddEntry("Save As display.p&s", kFileSaveAsPS); filemenu->AddEntry("Save As display.&eps", kFileSaveAsEPS); filemenu->AddEntry("Save As display.&gif", kFileSaveAsGIF); filemenu->AddEntry("Save As display.&C", kFileSaveAsC); filemenu->AddEntry("Save As display.&root", kFileSaveAsRoot); filemenu->AddSeparator(); filemenu->AddEntry("&Print...", kFilePrint); filemenu->AddSeparator(); filemenu->AddEntry("E&xit", kClose); filemenu->Associate(this); TGMenuBar *menubar = new TGMenuBar(this, 1, 1, kHorizontalFrame); menubar->AddPopup("&File", filemenu, laymenuitem); AddFrame(menubar, laymenubar); TGHorizontal3DLine *linesep = new TGHorizontal3DLine(this); AddFrame(linesep, laylinesep); fList->Add(filemenu); fList->Add(menubar); fList->Add(linesep); } MGEvtDisplay::MGEvtDisplay(const char *fname, const char *tname, const TGWindow *p, /*const TGWindow *main,*/ UInt_t w, UInt_t h) // : TGTransientFrame(p, main, w, h), fInitOk(kFALSE) : TGMainFrame(p, w, h), fInitOk(kFALSE) { // // create an autodelete-list for the gui elements // fList = new TList; fList->SetOwner(); // // Setup an empty job, with a reader task only. // All tasks and parameter containers are deleted automatically // (via SetOwner()) // MTaskList *tlist = new MTaskList; tlist->SetOwner(); MReadMarsFile *read = new MReadMarsFile(tname, fname); read->DisableAutoScheme(); tlist->AddToList(read); MParList *plist = new MParList; plist->SetOwner(); plist->AddToList(tlist); fEvtLoop = new MEvtLoop; fEvtLoop->SetOwner(); fEvtLoop->SetParList(plist); AddMenuBar(); AddFrames(fname, tname); SetWMSizeHints(450, 400, 1000, 1000, 10, 10); Move(rand()%100+50, rand()%100+50); } // -------------------------------------------------------------------------- // // Destructs the graphical members and the eventloop members // MGEvtDisplay::~MGEvtDisplay() { fEvtLoop->PostProcess(); delete fEvtLoop; delete fList; } // -------------------------------------------------------------------------- // // The close message is generated by the window manager when its close // window menu item is selected. // void MGEvtDisplay::CloseWindow() { delete this; } void MGEvtDisplay::UpdateMcLabel() { MMcEvt *evt=(MMcEvt*)GetParList()->FindObject("MMcEvt"); if (!evt) return; TString txt = " "; switch (evt->GetPartId()) { case kGAMMA: txt += "Gamma"; break; case kPROTON: txt += "Proton"; break; case kHELIUM: txt += "Helium"; break; default: txt += "Unknown Particle Id#"; txt += evt->GetPartId(); } txt += ": E="; txt += (int)(evt->GetEnergy()+.5); txt += "GeV r="; txt += (int)(evt->GetImpact()/100+.5); txt += "m ZA="; txt += (int)(evt->GetTheta()*180/TMath::Pi()+.5); txt += "° "; txt += evt->GetPhotElfromShower(); txt += "PhEl"; const MRawEvtHeader *hed = (MRawEvtHeader*)GetParList()->FindObject("MRawEvtHeader"); if (hed) { txt += " DAQEvt #"; txt += hed->GetDAQEvtNumber(); } fEvtInfo->SetText(txt); // // Seems to be necessary to newly layout the upper part to display // the whole line of text // TGFrame &f = *(TGFrame*)fEvtInfo->GetParent()->GetParent(); f.Layout(); f.MapSubwindows(); } // -------------------------------------------------------------------------- // // Checks if the event number is valid, and if so reads the new event // and updates the display // void MGEvtDisplay::ReadinEvent() { if (GetTaskList()->Process()) { GetReader()->DecEventNum(); UpdateDisplay(); UpdateMcLabel(); } fTxtEvtNr->SetText(Form("%d", GetReader()->GetNumEntry()+1)); } void MGEvtDisplay::ReadFirstEvent() { fInitOk = fEvtLoop->PreProcess(); if (fInitOk) ReadinEvent(); TGString *txt = new TGString(Form("out of %d Events", GetReader()->GetEntries())); fNumOfEvts->SetText(txt); } // -------------------------------------------------------------------------- // // Opens a save as dialog, and tries to store the canvas // in the given output format // void MGEvtDisplay::SaveAsDialog() const { static const char *gSaveAsTypes[] = { "PostScript", "*.ps", "Encapsulated PostScript", "*.eps", "Gif files", "*.gif", "Macro files", "*.C", "ROOT files", "*.root", "All files", "*", NULL, NULL }; static TString dir("."); TGFileInfo fi; // fFileName and fIniDir deleted in ~TGFileInfo fi.fFileTypes = (const char**)gSaveAsTypes; fi.fIniDir = StrDup(dir); new TGFileDialog(fClient->GetRoot(), this, kFDSave, &fi); if (!fi.fFilename) return; dir = fi.fIniDir; if (strstr(fi.fFilename, ".root") || strstr(fi.fFilename, ".ps") || strstr(fi.fFilename, ".eps") || strstr(fi.fFilename, ".gif")) { fCanvas->SaveAs(fi.fFilename); return; } if (strstr(fi.fFilename, ".C")) { fCanvas->SaveSource(fi.fFilename); return; } Warning("SaveAsDialog", "Unknown Extension: %s", fi.fFilename); } // -------------------------------------------------------------------------- // // ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2) // // Processes information from all GUI items. // Selecting an item usually generates an event with 4 parameters. // The first two are packed into msg (first and second bytes). // The other two are parm1 and parm2. // Bool_t MGEvtDisplay::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2) { if (GET_MSG(msg)!=kC_TEXTENTRY && GET_MSG(msg)!=kC_COMMAND) return kTRUE; switch(GET_SUBMSG(msg)) { case kTE_ENTER: case kCM_BUTTON: if (parm1==kClose) { CloseWindow(); return kTRUE; } if (!fInitOk) return kTRUE; switch(GET_SUBMSG(msg)) { case kTE_ENTER: if (GetReader()->SetEventNum(atoi(fTxtEvtNr->GetText())-1)) ReadinEvent(); return kTRUE; case kCM_BUTTON: switch (parm1) { case kEvtPrev: if (GetReader()->DecEventNum()) ReadinEvent(); return kTRUE; case kEvtNext: if (GetReader()->IncEventNum()) ReadinEvent(); return kTRUE; } return kTRUE; } return kTRUE; case kCM_MENU: switch (parm1) { case kFileSaveAs: SaveAsDialog(); return kTRUE; case kFileSaveAsRoot: fCanvas->SaveAs("display.root"); return kTRUE; case kFileSaveAsC: // FIXME: The line opening the canvas is wrong. fCanvas->SaveSource("display.C"); return kTRUE; case kFileSaveAsPS: fCanvas->SaveAs("display.ps"); return kTRUE; case kFileSaveAsEPS: fCanvas->SaveAs("display.eps"); return kTRUE; case kFileSaveAsGIF: fCanvas->SaveAs("display.gif"); return kTRUE; case kFilePrint: fCanvas->Print(); return kTRUE; case kClose: CloseWindow(); return kTRUE; } return kTRUE; } return kTRUE; }