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

Last change on this file since 2227 was 2210, 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->Draw();
283 display->DrawPixelNumbers();
284 fList->Add(display);
285
286 //
287 // Add second part to frame
288 //
289 TGLayoutHints *laydisp = new TGLayoutHints(kLHintsNormal|kLHintsExpandY|kLHintsExpandX, 10, 10, 10, 10);
290 frame->AddFrame(fEvtDisplay, laydisp);
291
292 //
293 // Now add all gui elements to 'autodel'-list
294 //
295 fList->Add(fEvtDisplay);
296 fList->Add(laydisp);
297 fList->Add(laytabs);
298}
299
300// --------------------------------------------------------------------------
301//
302// Add the low frame: These are the buttons Print and Close
303//
304void MGEvtDisplay::AddLowFrame(TGHorizontalFrame *frame)
305{
306 TGTextButton *but = new TGTextButton(frame, "Close", kClose);
307
308 but->Associate(this);
309
310 fList->Add(but);
311
312 TGLayoutHints *laybut = new TGLayoutHints(kLHintsLeft, 10, 10, 10, 10);
313 fList->Add(laybut);
314
315 frame->AddFrame(but, laybut);
316}
317
318// --------------------------------------------------------------------------
319//
320// Create and setup all the three frames and build the window interieur
321//
322void MGEvtDisplay::AddFrames(const char *filename, const char *treename)
323{
324 //
325 // Create the frame elements and add gui elements to it
326 //
327 TGVerticalFrame *frametop = new TGVerticalFrame(this, 300, 100);
328 fList->Add(frametop);
329
330 AddTopFramePart1(frametop, filename, treename);
331 AddTopFramePart2(frametop);
332
333 TGLayoutHints *laytop = new TGLayoutHints(kLHintsTop|kLHintsCenterX);
334 fList->Add(laytop);
335
336 // -----
337
338 TGHorizontalFrame *framemid = new TGHorizontalFrame(this, 300, 100);
339 fList->Add(framemid);
340
341 AddMidFrame(framemid);
342
343 TGLayoutHints *laymid = new TGLayoutHints(kLHintsExpandY|kLHintsExpandX);
344 fList->Add(laymid);
345
346 //
347 // add frame elements to 'autodel'
348 //
349 TGHorizontal3DLine *line1 = new TGHorizontal3DLine(this);
350 TGHorizontal3DLine *line2 = new TGHorizontal3DLine(this);
351 fList->Add(line1);
352 fList->Add(line2);
353
354 TGLayoutHints *layline = new TGLayoutHints(kLHintsTop|kLHintsExpandX);
355 fList->Add(layline);
356
357 // -----
358 TGHorizontalFrame *framelow = new TGHorizontalFrame(this, 300, 100);
359 fList->Add(framelow);
360
361 AddLowFrame(framelow);
362
363 TGLayoutHints *laylow = new TGLayoutHints(kLHintsTop);
364 fList->Add(laylow);
365
366 //
367 // Layout frame elements and add elements to frame
368 //
369 AddFrame(frametop, laytop);
370 AddFrame(line1, layline);
371 AddFrame(framemid, laymid);
372 AddFrame(line2, layline);
373 AddFrame(framelow, laylow);
374}
375
376// --------------------------------------------------------------------------
377//
378// Constructor
379//
380void MGEvtDisplay::AddMenuBar()
381{
382 //
383 // Add all GUI elements and update the event counter
384 //
385 TGLayoutHints *laymenubar = new TGLayoutHints(kLHintsTop|kLHintsLeft|kLHintsExpandX, 2, 2, 2, 2);
386 TGLayoutHints *laymenuitem = new TGLayoutHints(kLHintsTop|kLHintsLeft, 0, 4, 0, 0);
387 TGLayoutHints *laylinesep = new TGLayoutHints(kLHintsTop|kLHintsExpandX);
388
389 fList->Add(laymenubar);
390 fList->Add(laymenuitem);
391 fList->Add(laylinesep);
392
393 TGPopupMenu *filemenu = new TGPopupMenu(gClient->GetRoot());
394 filemenu->AddEntry("Save &As...", kFileSaveAs);
395 filemenu->AddEntry("Save As display.p&s", kFileSaveAsPS);
396 filemenu->AddEntry("Save As display.&eps", kFileSaveAsEPS);
397 filemenu->AddEntry("Save As display.&gif", kFileSaveAsGIF);
398 filemenu->AddEntry("Save As display.&C", kFileSaveAsC);
399 filemenu->AddEntry("Save As display.&root", kFileSaveAsRoot);
400 filemenu->AddSeparator();
401 filemenu->AddEntry("&Print...", kFilePrint);
402 filemenu->AddSeparator();
403 filemenu->AddEntry("E&xit", kClose);
404 filemenu->Associate(this);
405
406 TGMenuBar *menubar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
407 menubar->AddPopup("&File", filemenu, laymenuitem);
408 AddFrame(menubar, laymenubar);
409
410 TGHorizontal3DLine *linesep = new TGHorizontal3DLine(this);
411 AddFrame(linesep, laylinesep);
412
413 fList->Add(filemenu);
414 fList->Add(menubar);
415 fList->Add(linesep);
416}
417
418MGEvtDisplay::MGEvtDisplay(const char *fname, const char *tname,
419 const TGWindow *p, /*const TGWindow *main,*/
420 UInt_t w, UInt_t h)
421// : TGTransientFrame(p, main, w, h), fInitOk(kFALSE)
422: TGMainFrame(p, w, h), fInitOk(kFALSE)
423{
424 //
425 // create an autodelete-list for the gui elements
426 //
427 fList = new TList;
428 fList->SetOwner();
429
430 //
431 // Setup an empty job, with a reader task only.
432 // All tasks and parameter containers are deleted automatically
433 // (via SetOwner())
434 //
435 MTaskList *tlist = new MTaskList;
436 tlist->SetOwner();
437
438 MReadMarsFile *read = new MReadMarsFile(tname, fname);
439 read->DisableAutoScheme();
440 tlist->AddToList(read);
441
442 MParList *plist = new MParList;
443 plist->SetOwner();
444 plist->AddToList(tlist);
445
446 fEvtLoop = new MEvtLoop;
447 fEvtLoop->SetOwner();
448 fEvtLoop->SetParList(plist);
449
450 AddMenuBar();
451 AddFrames(fname, tname);
452
453 SetWMSizeHints(450, 400, 1000, 1000, 10, 10);
454 Move(rand()%100+50, rand()%100+50);
455}
456
457// --------------------------------------------------------------------------
458//
459// Destructs the graphical members and the eventloop members
460//
461MGEvtDisplay::~MGEvtDisplay()
462{
463 fEvtLoop->PostProcess();
464 delete fEvtLoop;
465
466 delete fList;
467}
468
469// --------------------------------------------------------------------------
470//
471// The close message is generated by the window manager when its close
472// window menu item is selected.
473//
474void MGEvtDisplay::CloseWindow()
475{
476 delete this;
477}
478
479void MGEvtDisplay::UpdateMcLabel()
480{
481 MMcEvt *evt=(MMcEvt*)GetParList()->FindObject("MMcEvt");
482 if (!evt)
483 return;
484
485 TString txt = " ";
486
487 switch (evt->GetPartId())
488 {
489 case kGAMMA:
490 txt += "Gamma";
491 break;
492 case kPROTON:
493 txt += "Proton";
494 break;
495 case kHELIUM:
496 txt += "Helium";
497 break;
498 default:
499 txt += "Unknown Particle Id#";
500 txt += evt->GetPartId();
501 }
502
503 txt += ": E=";
504 txt += (int)(evt->GetEnergy()+.5);
505 txt += "GeV r=";
506 txt += (int)(evt->GetImpact()/100+.5);
507 txt += "m ZA=";
508 txt += (int)(evt->GetTheta()*180/TMath::Pi()+.5);
509 txt += "° ";
510 txt += evt->GetPhotElfromShower();
511 txt += "PhEl";
512
513 const MRawEvtHeader *hed = (MRawEvtHeader*)GetParList()->FindObject("MRawEvtHeader");
514 if (hed)
515 {
516 txt += " DAQEvt #";
517 txt += hed->GetDAQEvtNumber();
518 }
519
520 fEvtInfo->SetText(txt);
521
522 gLog << all;
523 gLog.Separator(txt);
524
525 //
526 // Seems to be necessary to newly layout the upper part to display
527 // the whole line of text
528 //
529 TGFrame &f = *(TGFrame*)fEvtInfo->GetParent()->GetParent();
530 f.Layout();
531 f.MapSubwindows();
532}
533
534// --------------------------------------------------------------------------
535//
536// Checks if the event number is valid, and if so reads the new event
537// and updates the display
538//
539void MGEvtDisplay::ReadinEvent(Int_t dir)
540{
541 MRawEvtData *raw = (MRawEvtData*)GetParList()->FindObject("MRawEvtData");
542
543 if (!raw)
544 return;
545
546 const Int_t num = GetReader()->GetNumEntry();
547
548 do
549 {
550 if (dir<0 && !GetReader()->DecEventNum())
551 {
552 GetReader()->SetEventNum(num);
553 return;
554 }
555 if (dir>0 && !GetReader()->IncEventNum())
556 {
557 GetReader()->SetEventNum(num);
558 return;
559 }
560
561 if (!GetTaskList()->Process())
562 return;
563
564 GetReader()->DecEventNum();
565
566 } while (raw->GetNumPixels()<1 && dir!=0);
567
568 UpdateMcLabel();
569 UpdateDisplay();
570
571 fTxtEvtNr->SetText(Form("%d", GetReader()->GetNumEntry()+1));
572}
573
574void MGEvtDisplay::ReadFirstEvent()
575{
576 fInitOk = fEvtLoop->PreProcess();
577
578 if (fInitOk)
579 ReadinEvent();
580
581 TGString *txt = new TGString(Form("out of %d Events", GetReader()->GetEntries()));
582 fNumOfEvts->SetText(txt);
583}
584
585// --------------------------------------------------------------------------
586//
587// Opens a save as dialog, and tries to store the canvas
588// in the given output format
589//
590void MGEvtDisplay::SaveAsDialog() const
591{
592 static const char *gSaveAsTypes[] =
593 {
594 "PostScript", "*.ps",
595 "Encapsulated PostScript", "*.eps",
596 "Gif files", "*.gif",
597 "Macro files", "*.C",
598 "ROOT files", "*.root",
599 "All files", "*",
600 NULL, NULL
601 };
602
603 static TString dir(".");
604
605 TGFileInfo fi; // fFileName and fIniDir deleted in ~TGFileInfo
606
607 fi.fFileTypes = (const char**)gSaveAsTypes;
608 fi.fIniDir = StrDup(dir);
609
610 new TGFileDialog(fClient->GetRoot(), this, kFDSave, &fi);
611
612 if (!fi.fFilename)
613 return;
614
615 dir = fi.fIniDir;
616
617 if (strstr(fi.fFilename, ".root") ||
618 strstr(fi.fFilename, ".ps") ||
619 strstr(fi.fFilename, ".eps") ||
620 strstr(fi.fFilename, ".gif"))
621 {
622 fCanvas->SaveAs(fi.fFilename);
623 return;
624 }
625 if (strstr(fi.fFilename, ".C"))
626 {
627 fCanvas->SaveSource(fi.fFilename);
628 return;
629 }
630 Warning("SaveAsDialog", "Unknown Extension: %s", fi.fFilename);
631}
632
633// --------------------------------------------------------------------------
634//
635// ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
636//
637// Processes information from all GUI items.
638// Selecting an item usually generates an event with 4 parameters.
639// The first two are packed into msg (first and second bytes).
640// The other two are parm1 and parm2.
641//
642Bool_t MGEvtDisplay::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
643{
644 switch (GET_MSG(msg))
645 {
646 case kC_TEXTENTRY:
647 switch(GET_SUBMSG(msg))
648 {
649 case kTE_ENTER:
650 if (parm1==kClose)
651 {
652 CloseWindow();
653 return kTRUE;
654 }
655
656 if (!fInitOk)
657 return kTRUE;
658
659 switch(GET_SUBMSG(msg))
660 {
661 case kTE_ENTER:
662 if (GetReader()->SetEventNum(atoi(fTxtEvtNr->GetText())-1))
663 ReadinEvent();
664 return kTRUE;
665 }
666 return kTRUE;
667 }
668 return kTRUE;
669
670 case kC_COMMAND:
671 switch (GET_SUBMSG(msg))
672 {
673 case kCM_BUTTON:
674 if (parm1==kClose)
675 {
676 CloseWindow();
677 return kTRUE;
678 }
679
680 if (!fInitOk)
681 return kTRUE;
682
683 switch (parm1)
684 {
685 case kEvtPrev:
686 ReadinEvent(-1);
687 return kTRUE;
688
689 case kEvtNext:
690 ReadinEvent(+1);
691 return kTRUE;
692 }
693 return kTRUE;
694
695 case kCM_MENU:
696 switch (parm1)
697 {
698 case kFileSaveAs:
699 SaveAsDialog();
700 return kTRUE;
701 case kFileSaveAsRoot:
702 fCanvas->SaveAs("display.root");
703 return kTRUE;
704 case kFileSaveAsC:
705 // FIXME: The line opening the canvas is wrong.
706 fCanvas->SaveSource("display.C");
707 return kTRUE;
708 case kFileSaveAsPS:
709 fCanvas->SaveAs("display.ps");
710 return kTRUE;
711 case kFileSaveAsEPS:
712 fCanvas->SaveAs("display.eps");
713 return kTRUE;
714 case kFileSaveAsGIF:
715 fCanvas->SaveAs("display.gif");
716 return kTRUE;
717 case kFilePrint:
718 fCanvas->Print();
719 return kTRUE;
720 case kClose:
721 CloseWindow();
722 return kTRUE;
723 }
724 return kTRUE;
725 }
726 return kTRUE;
727 }
728 return kTRUE;
729}
730
Note: See TracBrowser for help on using the repository browser.