source: trunk/MagicSoft/Mars/meventdisp/MGEvtDisplay.cc@ 2318

Last change on this file since 2318 was 2275, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 19.2 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, 10/2001 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2003
21!
22!
23\* ======================================================================== */
24
25#include "MGEvtDisplay.h"
26
27#include <stdlib.h> // atoi
28
29#include <TGTab.h> // TGTab
30#include <TGMenu.h> // TGPopupMenu
31#include <TCanvas.h> // TCanvas::Print
32#include <TGLabel.h> // TGLabel
33#include <TGButton.h> // TGPictureButton
34#include <TGMsgBox.h> // TGMsgBox
35#include <TGTextEntry.h> // TGTextEntry
36#include <TGFileDialog.h> // TGFileDialog
37#include <TRootEmbeddedCanvas.h> // TRootEmbeddedCanvas
38
39#include <TG3DLine.h> // TGHorizontal3DLine
40 // use TGSplitter instead for root<3.00
41
42#include "MLog.h"
43#include "MLogManip.h"
44
45#include "MParList.h"
46#include "MTaskList.h"
47#include "MEvtLoop.h"
48#include "MHCamera.h"
49#include "MReadMarsFile.h"
50#include "MGeomCamMagic.h"
51#include "MRawEvtData.h"
52#include "MRawEvtHeader.h"
53
54#include "MMcEvt.hxx"
55
56ClassImp(MGEvtDisplay);
57
58enum MGCamDisplayCommand
59{
60 kEvtPrev,
61 kEvtNext,
62 kEvtNumber,
63
64 kFileSaveAs,
65 kFileSaveAsRoot,
66 kFileSaveAsC,
67 kFileSaveAsPS,
68 kFileSaveAsEPS,
69 kFileSaveAsGIF,
70 kFilePrint,
71 kClose
72};
73
74// --------------------------------------------------------------------------
75//
76// Return a pointer to the parameter list.
77//
78MParList *MGEvtDisplay::GetParList() const
79{
80 return fEvtLoop->GetParList();
81}
82
83// --------------------------------------------------------------------------
84//
85// Return a pointer to the task list.
86//
87MTaskList *MGEvtDisplay::GetTaskList() const
88{
89 return (MTaskList*)GetParList()->FindObject("MTaskList");
90}
91
92// --------------------------------------------------------------------------
93//
94// Return a pointer to the reader task (MReadTree)
95//
96MReadTree *MGEvtDisplay::GetReader() const
97{
98 return (MReadTree*)GetTaskList()->FindObject("MRead");
99}
100
101// --------------------------------------------------------------------------
102//
103// Add the top part of the frame: This is filename and treename display
104//
105void MGEvtDisplay::AddTopFramePart1(TGVerticalFrame *frame,
106 const char *filename,
107 const char *treename)
108{
109 //
110 // --- the top1 part of the window ---
111 //
112 TGHorizontalFrame *top1 = new TGHorizontalFrame(frame, 300, 100);
113 fList->Add(top1);
114
115 //
116 // create gui elements
117 //
118 TGLabel *lfile = new TGLabel(top1, new TGString("File:"));
119 TGLabel *file = new TGLabel(top1, new TGString(filename));
120 TGLabel *ltree = new TGLabel(top1, new TGString("Tree:"));
121 TGLabel *tree = new TGLabel(top1, new TGString(treename));
122
123 fList->Add(lfile);
124 fList->Add(file);
125 fList->Add(ltree);
126 fList->Add(tree);
127
128 //
129 // layout and add gui elements in/to frame
130 //
131 TGLayoutHints *laystd = new TGLayoutHints(kLHintsLeft, 10, 10, 10, 10);
132 fList->Add(laystd);
133
134 top1->AddFrame(lfile, laystd);
135 top1->AddFrame(file, laystd);
136 top1->AddFrame(ltree, laystd);
137 top1->AddFrame(tree, laystd);
138
139 //
140 // --- the top1 part of the window ---
141 //
142 TGHorizontalFrame *top2 = new TGHorizontalFrame(frame, 300, 100);
143 fList->Add(top2);
144
145 fEvtInfo = new TGLabel(top2, new TGString(""));
146 fList->Add(fEvtInfo);
147 top2->AddFrame(fEvtInfo, laystd);
148
149 //
150 // layout and add frames
151 //
152 TGLayoutHints *laytop1 = new TGLayoutHints(kLHintsTop);
153 fList->Add(laytop1);
154 frame->AddFrame(top1, laytop1);
155 frame->AddFrame(top2, laytop1);
156}
157
158// --------------------------------------------------------------------------
159//
160// Add the second part of the top frame: This are the event number controls
161//
162void MGEvtDisplay::AddTopFramePart2(TGVerticalFrame *frame)
163{
164 //
165 // --- the top2 part of the window ---
166 //
167 TGHorizontalFrame *top2 = new TGHorizontalFrame(frame, 300, 100);
168 fList->Add(top2);
169
170 //
171 // Create the gui elements
172 //
173 TGTextButton *prevevt = new TGTextButton(top2, "<< Previous Event", kEvtPrev);
174 prevevt->Associate(this);
175
176 TGLabel *evtnr = new TGLabel(top2, new TGString("Event: "));
177
178 fTxtEvtNr = new TGTextEntry(top2, new TGTextBuffer(100), kEvtNumber);
179 fTxtEvtNr->Resize(60, fTxtEvtNr->GetDefaultHeight());
180 fTxtEvtNr->Associate(this);
181
182 fNumOfEvts = new TGLabel(top2, "out of Events.");
183
184 TGTextButton *nextevt = new TGTextButton (top2, "Next Event >>", kEvtNext);
185 nextevt->Associate(this);
186
187 //
188 // Add gui elements to 'atotodel'
189 //
190 fList->Add(prevevt);
191 fList->Add(evtnr);
192 fList->Add(fTxtEvtNr);
193 fList->Add(fNumOfEvts);
194 fList->Add(nextevt);
195
196 //
197 // add the gui elements to the frame
198 //
199 TGLayoutHints *laystd = new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 10, 10, 10);
200
201 fList->Add(laystd);
202
203 top2->AddFrame(prevevt, laystd);
204 top2->AddFrame(evtnr, laystd);
205 top2->AddFrame(fTxtEvtNr, laystd);
206 top2->AddFrame(fNumOfEvts, laystd);
207 top2->AddFrame(nextevt, laystd);
208
209 frame->AddFrame(top2, new TGLayoutHints(kLHintsCenterX));
210}
211
212// --------------------------------------------------------------------------
213//
214// Add a tab with an embedded canvas for an camera display and return the
215// pointer to the canvas
216//
217TCanvas *MGEvtDisplay::AddTab(TString name)
218{
219 TGLayoutHints *laycanvas = new TGLayoutHints(kLHintsCenterX|kLHintsCenterY|kLHintsExpandX|kLHintsExpandY);
220 fList->Add(laycanvas);
221
222 // Add new tab
223 TGCompositeFrame *f = fEvtDisplay->AddTab(name);
224
225 // create root embedded canvas and add it to the tab
226 TRootEmbeddedCanvas *ec = new TRootEmbeddedCanvas(name+"Display", f, f->GetWidth(), f->GetHeight());
227 f->AddFrame(ec, laycanvas);
228 fList->Add(ec);
229
230 // set background and border mode of the canvas
231 TCanvas &c = *ec->GetCanvas();
232 c.SetBorderMode(0);
233
234 // layout and map new tab
235#if ROOT_VERSION_CODE < ROOT_VERSION(3,03,00)
236 MapSubwindows();
237 Layout();
238#else
239 Layout();
240 MapSubwindows();
241#endif
242
243 // display new tab in the main frame
244 gClient->ProcessEventsFor(fEvtDisplay);
245
246 // return pointer to new canvas
247 return &c;
248}
249
250// --------------------------------------------------------------------------
251//
252// Add the mid frame: This are the two tabs with the canvas in the right one
253//
254void MGEvtDisplay::AddMidFrame(TGHorizontalFrame *frame)
255{
256 //
257 // create tab control
258 //
259 TGTab *tabs = new TGTab(frame, 300, 300);
260
261 //
262 // Create Tab1
263 //
264 fTab1 = tabs->AddTab("Setup");
265
266 //
267 // Crete second gui elemet for tab1 (TGVertical Frame)
268 //
269 TGLayoutHints *laytabs = new TGLayoutHints(kLHintsNormal|kLHintsExpandY, 10, 10, 10, 10);
270 frame->AddFrame(tabs, laytabs);
271
272 //
273 // Create second part of frame
274 //
275 fEvtDisplay = new TGTab(frame, 300, 300);
276
277 fCanvas=AddTab("Photons");
278
279 AddTab("Geometry");
280 MGeomCamMagic geom;
281 MHCamera *display = new MHCamera(geom);
282 display->SetBit(TH1::kNoStats);
283 display->Draw();
284 display->DrawPixelIndices();
285 fList->Add(display);
286
287 //
288 // Add second part to frame
289 //
290 TGLayoutHints *laydisp = new TGLayoutHints(kLHintsNormal|kLHintsExpandY|kLHintsExpandX, 10, 10, 10, 10);
291 frame->AddFrame(fEvtDisplay, laydisp);
292
293 //
294 // Now add all gui elements to 'autodel'-list
295 //
296 fList->Add(fEvtDisplay);
297 fList->Add(laydisp);
298 fList->Add(laytabs);
299}
300
301// --------------------------------------------------------------------------
302//
303// Add the low frame: These are the buttons Print and Close
304//
305void MGEvtDisplay::AddLowFrame(TGHorizontalFrame *frame)
306{
307 TGTextButton *but = new TGTextButton(frame, "Close", kClose);
308
309 but->Associate(this);
310
311 fList->Add(but);
312
313 TGLayoutHints *laybut = new TGLayoutHints(kLHintsLeft, 10, 10, 10, 10);
314 fList->Add(laybut);
315
316 frame->AddFrame(but, laybut);
317}
318
319// --------------------------------------------------------------------------
320//
321// Create and setup all the three frames and build the window interieur
322//
323void MGEvtDisplay::AddFrames(const char *filename, const char *treename)
324{
325 //
326 // Create the frame elements and add gui elements to it
327 //
328 TGVerticalFrame *frametop = new TGVerticalFrame(this, 300, 100);
329 fList->Add(frametop);
330
331 AddTopFramePart1(frametop, filename, treename);
332 AddTopFramePart2(frametop);
333
334 TGLayoutHints *laytop = new TGLayoutHints(kLHintsTop|kLHintsCenterX);
335 fList->Add(laytop);
336
337 // -----
338
339 TGHorizontalFrame *framemid = new TGHorizontalFrame(this, 300, 100);
340 fList->Add(framemid);
341
342 AddMidFrame(framemid);
343
344 TGLayoutHints *laymid = new TGLayoutHints(kLHintsExpandY|kLHintsExpandX);
345 fList->Add(laymid);
346
347 //
348 // add frame elements to 'autodel'
349 //
350 TGHorizontal3DLine *line1 = new TGHorizontal3DLine(this);
351 TGHorizontal3DLine *line2 = new TGHorizontal3DLine(this);
352 fList->Add(line1);
353 fList->Add(line2);
354
355 TGLayoutHints *layline = new TGLayoutHints(kLHintsTop|kLHintsExpandX);
356 fList->Add(layline);
357
358 // -----
359 TGHorizontalFrame *framelow = new TGHorizontalFrame(this, 300, 100);
360 fList->Add(framelow);
361
362 AddLowFrame(framelow);
363
364 TGLayoutHints *laylow = new TGLayoutHints(kLHintsTop);
365 fList->Add(laylow);
366
367 //
368 // Layout frame elements and add elements to frame
369 //
370 AddFrame(frametop, laytop);
371 AddFrame(line1, layline);
372 AddFrame(framemid, laymid);
373 AddFrame(line2, layline);
374 AddFrame(framelow, laylow);
375}
376
377// --------------------------------------------------------------------------
378//
379// Constructor
380//
381void MGEvtDisplay::AddMenuBar()
382{
383 //
384 // Add all GUI elements and update the event counter
385 //
386 TGLayoutHints *laymenubar = new TGLayoutHints(kLHintsTop|kLHintsLeft|kLHintsExpandX, 2, 2, 2, 2);
387 TGLayoutHints *laymenuitem = new TGLayoutHints(kLHintsTop|kLHintsLeft, 0, 4, 0, 0);
388 TGLayoutHints *laylinesep = new TGLayoutHints(kLHintsTop|kLHintsExpandX);
389
390 fList->Add(laymenubar);
391 fList->Add(laymenuitem);
392 fList->Add(laylinesep);
393
394 TGPopupMenu *filemenu = new TGPopupMenu(gClient->GetRoot());
395 filemenu->AddEntry("Save &As...", kFileSaveAs);
396 filemenu->AddEntry("Save As display.p&s", kFileSaveAsPS);
397 filemenu->AddEntry("Save As display.&eps", kFileSaveAsEPS);
398 filemenu->AddEntry("Save As display.&gif", kFileSaveAsGIF);
399 filemenu->AddEntry("Save As display.&C", kFileSaveAsC);
400 filemenu->AddEntry("Save As display.&root", kFileSaveAsRoot);
401 filemenu->AddSeparator();
402 filemenu->AddEntry("&Print...", kFilePrint);
403 filemenu->AddSeparator();
404 filemenu->AddEntry("E&xit", kClose);
405 filemenu->Associate(this);
406
407 TGMenuBar *menubar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
408 menubar->AddPopup("&File", filemenu, laymenuitem);
409 AddFrame(menubar, laymenubar);
410
411 TGHorizontal3DLine *linesep = new TGHorizontal3DLine(this);
412 AddFrame(linesep, laylinesep);
413
414 fList->Add(filemenu);
415 fList->Add(menubar);
416 fList->Add(linesep);
417}
418
419MGEvtDisplay::MGEvtDisplay(const char *fname, const char *tname,
420 const TGWindow *p, /*const TGWindow *main,*/
421 UInt_t w, UInt_t h)
422// : TGTransientFrame(p, main, w, h), fInitOk(kFALSE)
423: TGMainFrame(p, w, h), fInitOk(kFALSE)
424{
425 //
426 // create an autodelete-list for the gui elements
427 //
428 fList = new TList;
429 fList->SetOwner();
430
431 //
432 // Setup an empty job, with a reader task only.
433 // All tasks and parameter containers are deleted automatically
434 // (via SetOwner())
435 //
436 MTaskList *tlist = new MTaskList;
437 tlist->SetOwner();
438
439 MReadMarsFile *read = new MReadMarsFile(tname, fname);
440 read->DisableAutoScheme();
441 tlist->AddToList(read);
442
443 MParList *plist = new MParList;
444 plist->SetOwner();
445 plist->AddToList(tlist);
446
447 fEvtLoop = new MEvtLoop;
448 fEvtLoop->SetOwner();
449 fEvtLoop->SetParList(plist);
450
451 AddMenuBar();
452 AddFrames(fname, tname);
453
454 SetWMSizeHints(450, 400, 1000, 1000, 10, 10);
455 Move(rand()%100+50, rand()%100+50);
456}
457
458// --------------------------------------------------------------------------
459//
460// Destructs the graphical members and the eventloop members
461//
462MGEvtDisplay::~MGEvtDisplay()
463{
464 fEvtLoop->PostProcess();
465 delete fEvtLoop;
466
467 delete fList;
468}
469
470// --------------------------------------------------------------------------
471//
472// The close message is generated by the window manager when its close
473// window menu item is selected.
474//
475void MGEvtDisplay::CloseWindow()
476{
477 delete this;
478}
479
480void MGEvtDisplay::UpdateMcLabel()
481{
482 MMcEvt *evt=(MMcEvt*)GetParList()->FindObject("MMcEvt");
483 if (!evt)
484 return;
485
486 TString txt = " ";
487
488 switch (evt->GetPartId())
489 {
490 case kGAMMA:
491 txt += "Gamma";
492 break;
493 case kPROTON:
494 txt += "Proton";
495 break;
496 case kHELIUM:
497 txt += "Helium";
498 break;
499 default:
500 txt += "Unknown Particle Id#";
501 txt += evt->GetPartId();
502 }
503
504 txt += ": E=";
505 txt += (int)(evt->GetEnergy()+.5);
506 txt += "GeV r=";
507 txt += (int)(evt->GetImpact()/100+.5);
508 txt += "m ZA=";
509 txt += (int)(evt->GetTheta()*180/TMath::Pi()+.5);
510 txt += "° ";
511 txt += evt->GetPhotElfromShower();
512 txt += "PhEl";
513
514 const MRawEvtHeader *hed = (MRawEvtHeader*)GetParList()->FindObject("MRawEvtHeader");
515 if (hed)
516 {
517 txt += " DAQEvt #";
518 txt += hed->GetDAQEvtNumber();
519 }
520
521 fEvtInfo->SetText(txt);
522
523 gLog << all;
524 gLog.Separator(txt);
525
526 //
527 // Seems to be necessary to newly layout the upper part to display
528 // the whole line of text
529 //
530 TGFrame &f = *(TGFrame*)fEvtInfo->GetParent()->GetParent();
531 f.Layout();
532 f.MapSubwindows();
533}
534
535// --------------------------------------------------------------------------
536//
537// Checks if the event number is valid, and if so reads the new event
538// and updates the display
539//
540void MGEvtDisplay::ReadinEvent(Int_t dir)
541{
542 MRawEvtData *raw = (MRawEvtData*)GetParList()->FindObject("MRawEvtData");
543
544 if (!raw)
545 return;
546
547 const Int_t num = GetReader()->GetNumEntry();
548
549 do
550 {
551 if (dir<0 && !GetReader()->DecEventNum())
552 {
553 GetReader()->SetEventNum(num);
554 return;
555 }
556 if (dir>0 && !GetReader()->IncEventNum())
557 {
558 GetReader()->SetEventNum(num);
559 return;
560 }
561
562 if (!GetTaskList()->Process())
563 return;
564
565 GetReader()->DecEventNum();
566
567 } while (raw->GetNumPixels()<1 && dir!=0);
568
569 UpdateMcLabel();
570 UpdateDisplay();
571
572 fTxtEvtNr->SetText(Form("%d", GetReader()->GetNumEntry()+1));
573}
574
575void MGEvtDisplay::ReadFirstEvent()
576{
577 fInitOk = fEvtLoop->PreProcess();
578
579 if (fInitOk)
580 ReadinEvent();
581
582 TGString *txt = new TGString(Form("out of %d Events", GetReader()->GetEntries()));
583 fNumOfEvts->SetText(txt);
584}
585
586// --------------------------------------------------------------------------
587//
588// Opens a save as dialog, and tries to store the canvas
589// in the given output format
590//
591void MGEvtDisplay::SaveAsDialog() const
592{
593 static const char *gSaveAsTypes[] =
594 {
595 "PostScript", "*.ps",
596 "Encapsulated PostScript", "*.eps",
597 "Gif files", "*.gif",
598 "Macro files", "*.C",
599 "ROOT files", "*.root",
600 "All files", "*",
601 NULL, NULL
602 };
603
604 static TString dir(".");
605
606 TGFileInfo fi; // fFileName and fIniDir deleted in ~TGFileInfo
607
608 fi.fFileTypes = (const char**)gSaveAsTypes;
609 fi.fIniDir = StrDup(dir);
610
611 new TGFileDialog(fClient->GetRoot(), this, kFDSave, &fi);
612
613 if (!fi.fFilename)
614 return;
615
616 dir = fi.fIniDir;
617
618 if (strstr(fi.fFilename, ".root") ||
619 strstr(fi.fFilename, ".ps") ||
620 strstr(fi.fFilename, ".eps") ||
621 strstr(fi.fFilename, ".gif"))
622 {
623 fCanvas->SaveAs(fi.fFilename);
624 return;
625 }
626 if (strstr(fi.fFilename, ".C"))
627 {
628 fCanvas->SaveSource(fi.fFilename);
629 return;
630 }
631 Warning("SaveAsDialog", "Unknown Extension: %s", fi.fFilename);
632}
633
634// --------------------------------------------------------------------------
635//
636// ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
637//
638// Processes information from all GUI items.
639// Selecting an item usually generates an event with 4 parameters.
640// The first two are packed into msg (first and second bytes).
641// The other two are parm1 and parm2.
642//
643Bool_t MGEvtDisplay::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
644{
645 switch (GET_MSG(msg))
646 {
647 case kC_TEXTENTRY:
648 switch(GET_SUBMSG(msg))
649 {
650 case kTE_ENTER:
651 if (parm1==kClose)
652 {
653 CloseWindow();
654 return kTRUE;
655 }
656
657 if (!fInitOk)
658 return kTRUE;
659
660 switch(GET_SUBMSG(msg))
661 {
662 case kTE_ENTER:
663 if (GetReader()->SetEventNum(atoi(fTxtEvtNr->GetText())-1))
664 ReadinEvent();
665 return kTRUE;
666 }
667 return kTRUE;
668 }
669 return kTRUE;
670
671 case kC_COMMAND:
672 switch (GET_SUBMSG(msg))
673 {
674 case kCM_BUTTON:
675 if (parm1==kClose)
676 {
677 CloseWindow();
678 return kTRUE;
679 }
680
681 if (!fInitOk)
682 return kTRUE;
683
684 switch (parm1)
685 {
686 case kEvtPrev:
687 ReadinEvent(-1);
688 return kTRUE;
689
690 case kEvtNext:
691 ReadinEvent(+1);
692 return kTRUE;
693 }
694 return kTRUE;
695
696 case kCM_MENU:
697 switch (parm1)
698 {
699 case kFileSaveAs:
700 SaveAsDialog();
701 return kTRUE;
702 case kFileSaveAsRoot:
703 fCanvas->SaveAs("display.root");
704 return kTRUE;
705 case kFileSaveAsC:
706 // FIXME: The line opening the canvas is wrong.
707 fCanvas->SaveSource("display.C");
708 return kTRUE;
709 case kFileSaveAsPS:
710 fCanvas->SaveAs("display.ps");
711 return kTRUE;
712 case kFileSaveAsEPS:
713 fCanvas->SaveAs("display.eps");
714 return kTRUE;
715 case kFileSaveAsGIF:
716 fCanvas->SaveAs("display.gif");
717 return kTRUE;
718 case kFilePrint:
719 fCanvas->Print();
720 return kTRUE;
721 case kClose:
722 CloseWindow();
723 return kTRUE;
724 }
725 return kTRUE;
726 }
727 return kTRUE;
728 }
729 return kTRUE;
730}
731
Note: See TracBrowser for help on using the repository browser.