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

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