Revision 54807d9b7051c0e88d7074c9d2205bbd884e0210 authored by Axel Naumann on 12 April 2022, 16:24:02 UTC, committed by Axel Naumann on 12 April 2022, 16:24:02 UTC
1 parent c67b5e1
RootShower.cxx
// Author: Bertrand Bellenot 22/08/02
/*************************************************************************
* Copyright (C) 1995-2002, Bertrand Bellenot. *
* All rights reserved. *
* *
* For the licensing terms see the LICENSE file. *
*************************************************************************/
#include <ctime>
#include <iostream>
#include <string>
#include <TROOT.h>
#include <TStyle.h>
#include <TRint.h>
#include <TVirtualX.h>
#include <TEnv.h>
#include <KeySymbols.h>
#include <TFile.h>
#include <TTree.h>
#include <TBranch.h>
#include <TFrame.h>
#include <TH1.h>
#include <TF1.h>
#include <TGMenu.h>
#include <TGFileDialog.h>
#include <TGTextEdit.h>
#include <TGToolTip.h>
#include <TG3DLine.h>
#include <TRootEmbeddedCanvas.h>
#include <TCanvas.h>
#include <TRandom.h>
#include <TSystem.h>
#include <TRootHelpDialog.h>
#include <TGStatusBar.h>
#include <TBrowser.h>
#include <TParticle.h>
#include <TContextMenu.h>
#include "RootShower.h"
#include "MyParticle.h"
#include "GTitleFrame.h"
#include "GButtonFrame.h"
#include "RSMsgBox.h"
#include "RSAbout.h"
#include "SettingsDlg.h"
#include "RSHelpText.h"
#include "MyEvent.h"
#include <TGeoManager.h>
#include <TView.h>
#include <TGToolBar.h>
#include <TGSplitter.h>
#include <TColor.h>
#include <THtml.h>
#include <TPluginManager.h>
#include <TVirtualGL.h>
#include "constants.h"
enum RootShowerMessageTypes {
M_FILE_OPEN,
M_FILE_SAVEAS,
M_FILE_HTML,
M_FILE_EXIT,
M_EVENT_NEXT,
M_EVENT_SELECT,
M_INTERRUPT_SIMUL,
M_ZOOM_PLUS,
M_ZOOM_MOINS,
M_ZOOM_PLUS2,
M_ZOOM_MOINS2,
M_SHOW_PROCESS,
M_ANIMATE_GIF,
M_SETTINGS_DLG,
M_SETTINGS_SAVE,
M_SHOW_INFOS,
M_SHOW_3D,
M_SHOW_TRACK,
M_VIEW_TOOLBAR,
M_INSPECT_BROWSER,
M_HELP_PHYSICS,
M_HELP_SIMULATION,
M_HELP_LICENSE,
M_HELP_ABOUT
};
const char *xpm_names[] = {
"open.xpm",
"save.xpm",
"",
"settings.xpm",
"",
"infos.xpm",
"view3d.xpm",
"",
"browser.xpm",
"",
"manual.xpm",
"help.xpm",
"license.xpm",
"about.xpm",
"",
"quit.xpm",
0
};
ToolBarData_t tb_data[] = {
{ "", "Open Root event file", kFALSE, M_FILE_OPEN, NULL },
{ "", "Save event in Root file", kFALSE, M_FILE_SAVEAS, NULL },
{ "", 0, 0, -1, NULL },
{ "", "Event settings", kFALSE, M_SETTINGS_DLG, NULL },
{ "", 0, 0, -1, NULL },
{ "", "Infos on current event", kFALSE, M_SHOW_INFOS, NULL },
{ "", "Open 3D viewer", kFALSE, M_SHOW_3D, NULL },
{ "", 0, 0, -1, NULL },
{ "", "Start Root browser", kFALSE, M_INSPECT_BROWSER, NULL },
{ "", 0, 0, -1, NULL },
{ "", "Physics recalls", kFALSE, M_HELP_PHYSICS, NULL },
{ "", "RootShower help", kFALSE, M_HELP_SIMULATION, NULL },
{ "", "Display license", kFALSE, M_HELP_LICENSE, NULL },
{ "", "About RootShower", kFALSE, M_HELP_ABOUT, NULL },
{ "", 0, 0, -1, NULL },
{ "", "Exit Application", kFALSE, M_FILE_EXIT, NULL },
{ NULL, NULL, 0, 0, NULL }
};
RootShower *gRootShower;
Int_t gColIndex;
TGListTree *gEventListTree; // event selection TGListTree
TGListTreeItem *gBaseLTI;
TGListTreeItem *gTmpLTI;
TGListTreeItem *gLTI[MAX_PARTICLE];
const TGPicture *bpic, *bspic;
const TGPicture *lpic, *lspic;
const Char_t *filetypes[] = {
"ROOT files", "*.root",
"ROOT macros", "*.C",
"GIF files", "*.gif",
"PS files", "*.ps",
"EPS files", "*.eps",
"All files", "*",
0, 0
};
enum EGeometrySettingsDialogMessageTypes {
kM_BUTTON_OK,
kM_BUTTON_CANCEL,
kM_COMBOBOX_CHANNELID,
kM_COMBOBOX_TDC
};
//_________________________________________________
// RootShower
//
Int_t RootShower::fgDefaultXPosition = 20;
Int_t RootShower::fgDefaultYPosition = 20;
////////////////////////////////////////////////////////////////////////////////
/// Create (the) Event Display.
///
/// p = pointer to GMainFrame (not owner)
/// w = width of RootShower frame
/// h = width of RootShower frame
RootShower::RootShower(const TGWindow *p, UInt_t w, UInt_t h):
TGMainFrame(p, w, h)
{
fOk = kFALSE;
fModified = kFALSE;
fSettingsModified = kFALSE;
fIsRunning = kFALSE;
fShowProcess = kFALSE;
fCreateGIFs = kFALSE;
fTimer = 0;
fPicIndex = 1;
fRootShowerEnv = new TEnv(".rootshowerrc");
fFirstParticle = fRootShowerEnv->GetValue("RootShower.fFirstParticle", PHOTON);
fE0 = fRootShowerEnv->GetValue("RootShower.fE0", 10.0);
fB = fRootShowerEnv->GetValue("RootShower.fB", 20.000);
fPicNumber = fRootShowerEnv->GetValue("RootShower.fPicNumber", 24);
fPicDelay = fRootShowerEnv->GetValue("RootShower.fPicDelay", 100);
fPicReset = fRootShowerEnv->GetValue("RootShower.fPicReset", 1);
fEventNr = 0;
fNRun = 0;
bpic = gClient->GetPicture("branch_t.xpm");
bspic = gClient->GetPicture("branch_t.xpm");
lpic = gClient->GetPicture("leaf_t.xpm");
lspic = gClient->GetPicture("leaf_t.xpm");
// Create menubar and popup menus.
MakeMenuBarFrame();
//---- toolbar
int spacing = 8;
fToolBar = new TGToolBar(this, 60, 20, kHorizontalFrame | kRaisedFrame);
for (int i = 0; xpm_names[i]; i++) {
TString iconname(gProgPath);
#ifdef R__WIN32
iconname += "\\icons\\";
#else
iconname += "/icons/";
#endif
iconname += xpm_names[i];
tb_data[i].fPixmap = iconname.Data();
if (strlen(xpm_names[i]) == 0) {
fToolBar->AddFrame(new TGVertical3DLine(fToolBar), new TGLayoutHints(kLHintsExpandY, 4, 4));
continue;
}
const TGPicture *pic = fClient->GetPicture(tb_data[i].fPixmap);
TGPictureButton *pb = new TGPictureButton(fToolBar, pic, tb_data[i].fId);
pb->SetToolTipText(tb_data[i].fTipText);
tb_data[i].fButton = pb;
fToolBar->AddButton(this, pb, spacing);
spacing = 0;
}
AddFrame(fToolBar, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 0, 0));
fToolBar->GetButton(M_SHOW_3D)->SetState(kButtonDisabled);
fToolBar->GetButton(M_FILE_SAVEAS)->SetState(kButtonDisabled);
// Layout hints
fL1 = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 0, 0);
fL2 = new TGLayoutHints(kLHintsCenterX | kLHintsExpandX, 0, 0, 0, 0);
fL3 = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY,
0, 0, 0, 0);
fL4 = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandY, 5, 5, 2, 2);
fL5 = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY,
2, 2, 2, 2);
fL6 = new TGLayoutHints(kLHintsBottom| kLHintsExpandX, 0, 0, 0, 0);
fL7 = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY,
5, 5, 2, 2);
fL8 = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 0, 0);
// CREATE TITLE FRAME
fTitleFrame = new GTitleFrame(this, "ROOT Shower Monte Carlo", "Event Display", 100, 100);
AddFrame(fTitleFrame, fL2);
// CREATE MAIN FRAME
fMainFrame = new TGCompositeFrame(this, 100, 100, kHorizontalFrame | kRaisedFrame);
TGVerticalFrame *fV1 = new TGVerticalFrame(fMainFrame, 150, 10, kSunkenFrame | kFixedWidth);
TGVerticalFrame *fV2 = new TGVerticalFrame(fMainFrame, 10, 10, kSunkenFrame);
TGLayoutHints *lo;
lo = new TGLayoutHints(kLHintsLeft | kLHintsExpandY,2,0,2,2);
fMainFrame->AddFrame(fV1, lo);
TGVSplitter *splitter = new TGVSplitter(fMainFrame, 5);
splitter->SetFrame(fV1, kTRUE);
lo = new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 0, 0 ,0, 0);
fMainFrame->AddFrame(splitter, lo);
lo = new TGLayoutHints(kLHintsRight | kLHintsExpandX | kLHintsExpandY,0,2,2,2);
fMainFrame->AddFrame(fV2, lo);
// Create Selection frame (i.e. with buttons and geometry selection widgets)
fSelectionFrame = new TGCompositeFrame(fV1, 100, 100, kVerticalFrame);
// create button frame
fButtonFrame = new GButtonFrame (fSelectionFrame, this, M_EVENT_NEXT,
M_EVENT_SELECT, M_INTERRUPT_SIMUL);
lo = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 2, 5, 1, 2);
fSelectionFrame->AddFrame(fButtonFrame, lo);
fTreeView = new TGCanvas(fSelectionFrame, 150, 10, kSunkenFrame | kDoubleBorder);
fEventListTree = new TGListTree(fTreeView->GetViewPort(), 10, 10, kHorizontalFrame);
gEventListTree = fEventListTree;
fEventListTree->SetCanvas(fTreeView);
fEventListTree->Associate(this);
BuildEventTree();
fTreeView->SetContainer(fEventListTree);
fSelectionFrame->AddFrame(fTreeView, fL5);
lo = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
fV1->AddFrame(fSelectionFrame, lo);
fContextMenu = new TContextMenu("RSContextMenu");
//__________________________________________________________________________________
// Create Display frame
fDisplayFrame = new TGTab(fV2, 580, 360);
// Create Display Canvas Tab (where the actual main event is displayed)
TGCompositeFrame *tFrame = fDisplayFrame->AddTab("Main Event (Shower)");
// Create Layout hints
fZoomButtonsLayout = new TGLayoutHints(kLHintsBottom | kLHintsLeft | kLHintsExpandX, 5, 2, 2, 2);
fHFrame = new TGHorizontalFrame(tFrame,0,0,0);
tFrame->AddFrame(fHFrame, new TGLayoutHints(kLHintsBottom | kLHintsLeft | kLHintsExpandX, 5, 5, 5, 5));
// Create Zoom Buttons
fZoomPlusButton = new TGTextButton(fHFrame, "&Zoom Forward", M_ZOOM_PLUS);
fZoomPlusButton->Associate(this);
fZoomPlusButton->SetToolTipText("Zoom forward event view");
fHFrame->AddFrame(fZoomPlusButton, fZoomButtonsLayout);
fZoomMoinsButton = new TGTextButton(fHFrame, "Zoom &Backward", M_ZOOM_MOINS);
fZoomMoinsButton->Associate(this);
fZoomMoinsButton->SetToolTipText("Zoom backward event view");
fHFrame->AddFrame(fZoomMoinsButton, fZoomButtonsLayout);
fEmbeddedCanvas = new TRootEmbeddedCanvas("fEmbeddedCanvas", tFrame, 580, 360);
tFrame->AddFrame(fEmbeddedCanvas, fL5);
fEmbeddedCanvas->GetCanvas()->SetBorderMode(0);
fCA = fEmbeddedCanvas->GetCanvas();
fCA->SetFillColor(1);
// Create Display Canvas Tab (where the selected event is displayed)
TGCompositeFrame *tFrame2 = fDisplayFrame->AddTab("Selected Track");
fHFrame2 = new TGHorizontalFrame(tFrame2,0,0,0);
tFrame2->AddFrame(fHFrame2, new TGLayoutHints(kLHintsBottom | kLHintsLeft | kLHintsExpandX, 5, 5, 5, 5));
// Create Zoom Buttons
fZoomPlusButton2 = new TGTextButton(fHFrame2, "&Zoom Forward", M_ZOOM_PLUS2);
fZoomPlusButton2->Associate(this);
fZoomPlusButton2->SetToolTipText("Zoom forward event view");
fHFrame2->AddFrame(fZoomPlusButton2, fZoomButtonsLayout);
fZoomMoinsButton2 = new TGTextButton(fHFrame2, "Zoom &Backward", M_ZOOM_MOINS2);
fZoomMoinsButton2->Associate(this);
fZoomMoinsButton2->SetToolTipText("Zoom backward event view");
fHFrame2->AddFrame(fZoomMoinsButton2, fZoomButtonsLayout);
fEmbeddedCanvas2 = new TRootEmbeddedCanvas("fEmbeddedCanvas2", tFrame2, 580, 360);
tFrame2->AddFrame(fEmbeddedCanvas2, fL5);
fEmbeddedCanvas2->GetCanvas()->SetBorderMode(0);
fCB = fEmbeddedCanvas2->GetCanvas();
fCB->SetFillColor(1);
// Create Display Canvas Tab (where the histogram is displayed)
TGCompositeFrame *tFrame3 = fDisplayFrame->AddTab("Statistics");
fEmbeddedCanvas3 = new TRootEmbeddedCanvas("fEmbeddedCanvas3", tFrame3, 580, 360);
tFrame3->AddFrame(fEmbeddedCanvas3, fL5);
fEmbeddedCanvas3->GetCanvas()->SetBorderMode(0);
fCC = fEmbeddedCanvas3->GetCanvas();
fCC->SetFillColor(10);
fCC->cd();
fPadC = new TPad("fPadC","Histogram",0.0,0.0,1.0,1.0,10,3,1);
fPadC->SetFillColor(10);
fPadC->SetBorderMode(0);
fPadC->SetBorderSize(0);
fPadC->Draw();
// Creation of histogram for particle's energy loss
fHisto_dEdX = new TH1F("Statistics","Energy loss for each particle",100,0,0.025); // Max at 25 MeV
fHisto_dEdX->SetFillColor(38);
fHisto_dEdX->SetStats(kTRUE);
fHisto_dEdX->SetXTitle("Energy Loss [GeV]");
fHisto_dEdX->SetLabelFont(42,"X");
fHisto_dEdX->SetLabelSize(0.03f, "X");
fHisto_dEdX->GetXaxis()->SetTitleFont(42);
fHisto_dEdX->SetYTitle("Number");
fHisto_dEdX->SetLabelFont(42,"Y");
fHisto_dEdX->SetLabelSize(0.03f, "Y");
fHisto_dEdX->GetYaxis()->SetTitleFont(42);
fCC->Update();
// Create text display Tab
tFrame = fDisplayFrame->AddTab("PDG Table");
fTextView = new TGTextEdit(tFrame, 300, 100, kSunkenFrame | kDoubleBorder);
tFrame->AddFrame(fTextView, fL5);
TString pdgFilename = gSystem->Getenv("ROOTSYS");
pdgFilename.Append("/etc/pdg_table.txt");
fTextView->LoadFile(pdgFilename);
lo = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
fV2->AddFrame(fDisplayFrame, lo);
AddFrame(fMainFrame, lo);
// Create status bar
Int_t parts[] = {45, 45, 10};
fStatusBar = new TGStatusBar(this, 50, 10, kHorizontalFrame);
fStatusBar->SetParts(parts, 3);
AddFrame(fStatusBar, fL6);
fStatusBar->SetText("Waiting to start simulation...",0);
// Finish RootShower for display...
SetWindowName("Root Shower Event Display");
SetIconName("Root Shower Event Display");
MapSubwindows();
Resize(GetDefaultSize()); // this is used here to init layout algoritme
MapWindow();
fEvent = new MyEvent();
fEvent->GetDetector()->Init();
fEvent->Init(0, fFirstParticle, fE0, fB);
Initialize(1);
gROOT->GetListOfBrowsables()->Add(fEvent,"RootShower Event");
gSystem->Load("libTreeViewer");
AddInput(kKeyPressMask | kKeyReleaseMask);
gVirtualX->SetInputFocus(GetId());
gRootShower = this;
}
////////////////////////////////////////////////////////////////////////////////
/// Create menubar and popup menus.
void RootShower::MakeMenuBarFrame()
{
// layout hint items
fMenuBarLayout = new TGLayoutHints(kLHintsTop| kLHintsLeft | kLHintsExpandX,
0, 0, 0, 0);
fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
fMenuBarHelpLayout = new TGLayoutHints(kLHintsTop | kLHintsRight);
fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame | kRaisedFrame);
// file popup menu
fMenuFile = new TGPopupMenu(gClient->GetRoot());
fMenuFile->AddEntry("&Open...\tCtrl+O", M_FILE_OPEN);
fMenuFile->AddEntry("S&ave as...\tCtrl+A", M_FILE_SAVEAS);
fMenuFile->AddEntry("&Close", -1);
fMenuFile->AddSeparator();
fMenuFile->AddEntry("&Print", -1);
fMenuFile->AddEntry("P&rint setup...", -1);
fMenuFile->AddSeparator();
fMenuFile->AddEntry("E&xit\tCtrl+Q", M_FILE_EXIT);
fMenuFile->DisableEntry(M_FILE_SAVEAS);
fMenuFile->Associate(this);
fMenuEvent = new TGPopupMenu(gClient->GetRoot());
fMenuEvent->AddLabel("Simulation Settings...");
fMenuEvent->AddSeparator();
fMenuEvent->AddEntry("&Settings...", M_SETTINGS_DLG);
fMenuEvent->AddEntry("Save &Parameters", M_SETTINGS_SAVE);
fMenuEvent->AddEntry("Show &Process", M_SHOW_PROCESS);
fMenuEvent->AddEntry("Animated &GIF", M_ANIMATE_GIF);
fMenuEvent->AddEntry("&Infos...\tCtrl+I", M_SHOW_INFOS);
fMenuEvent->AddSeparator();
fMenuEvent->AddEntry("&3D View", M_SHOW_3D);
fMenuEvent->AddEntry("&Show Selected Track", M_SHOW_TRACK);
fMenuEvent->DisableEntry(M_SHOW_INFOS);
fMenuEvent->DisableEntry(M_SHOW_3D);
fMenuEvent->DisableEntry(M_SHOW_TRACK);
fMenuEvent->DisableEntry(M_SHOW_PROCESS);
fMenuEvent->DisableEntry(M_ANIMATE_GIF);
fMenuEvent->Associate(this);
fMenuTools = new TGPopupMenu(gClient->GetRoot());
fMenuTools->AddLabel("Simulation Tools...");
fMenuTools->AddSeparator();
fMenuTools->AddEntry("Start &Browser\tCtrl+B", M_INSPECT_BROWSER);
fMenuTools->AddEntry("&Create Html Doc", M_FILE_HTML);
fMenuTools->Associate(this);
fMenuView = new TGPopupMenu(gClient->GetRoot());
fMenuView->AddEntry("&Toolbar", M_VIEW_TOOLBAR);
fMenuView->Associate(this);
fMenuView->CheckEntry(M_VIEW_TOOLBAR);
fMenuHelp = new TGPopupMenu(gClient->GetRoot());
fMenuHelp->AddEntry("&Physics", M_HELP_PHYSICS);
fMenuHelp->AddEntry("&Simulation", M_HELP_SIMULATION);
fMenuHelp->AddSeparator();
fMenuHelp->AddEntry("&License...", M_HELP_LICENSE);
fMenuHelp->AddEntry("&About...", M_HELP_ABOUT);
fMenuHelp->Associate(this);
fMenuBar->AddPopup("&File", fMenuFile, fMenuBarItemLayout);
fMenuBar->AddPopup("&Event", fMenuEvent, fMenuBarItemLayout);
fMenuBar->AddPopup("&Tools", fMenuTools, fMenuBarItemLayout);
fMenuBar->AddPopup("&View", fMenuView, fMenuBarItemLayout);
fMenuBar->AddPopup("&Help", fMenuHelp, fMenuBarHelpLayout);
AddFrame(fMenuBar, fMenuBarLayout);
}
////////////////////////////////////////////////////////////////////////////////
/// Destroy menubar and popup menus.
void RootShower::CloseMenuBarFrame()
{
delete fMenuHelp;
delete fMenuEvent;
delete fMenuTools;
delete fMenuFile;
delete fMenuBarItemLayout;
delete fMenuBarHelpLayout;
delete fMenuBar;
delete fMenuBarLayout;
}
////////////////////////////////////////////////////////////////////////////////
/// Show or hide toolbar.
void RootShower::ShowToolBar(Bool_t show)
{
if (show) {
ShowFrame(fToolBar);
fMenuView->CheckEntry(M_VIEW_TOOLBAR);
} else {
HideFrame(fToolBar);
fMenuView->UnCheckEntry(M_VIEW_TOOLBAR);
}
}
////////////////////////////////////////////////////////////////////////////////
/// Destroy RootShower object. Delete all created widgets
/// GUI MEMBERS
RootShower::~RootShower()
{
CloseMenuBarFrame();
delete fContextMenu;
delete fZoomPlusButton2;
delete fZoomMoinsButton2;
delete fZoomPlusButton;
delete fZoomMoinsButton;
delete fHFrame;
delete fHFrame2;
delete fZoomButtonsLayout;
delete fEmbeddedCanvas;
delete fTextView;
delete fDisplayFrame;
delete fEventListTree;
delete fTreeView;
delete fButtonFrame;
delete fSelectionFrame;
delete fMainFrame;
delete fTitleFrame;
delete fL8;
delete fL7;
delete fL6;
delete fL5;
delete fL4;
delete fL3;
delete fL2;
delete fL1;
}
////////////////////////////////////////////////////////////////////////////////
/// Set the default position on the screen of new RootShower instances.
void RootShower::setDefaultPosition(Int_t x, Int_t y)
{
fgDefaultXPosition = x;
fgDefaultYPosition = y;
}
////////////////////////////////////////////////////////////////////////////////
/// Apply layout on the main frame.
void RootShower::Layout()
{
TGMainFrame::Layout();
}
////////////////////////////////////////////////////////////////////////////////
/// Got close message for this RootShower. The EventDislay and the
/// application will be terminated.
void RootShower::CloseWindow()
{
if (fModified) {
new RootShowerMsgBox(gClient->GetRoot(),this, 400, 200);
if ( fOk ) {
fRootShowerEnv->SetValue("RootShower.fFirstParticle",fFirstParticle);
fRootShowerEnv->SetValue("RootShower.fE0",fE0);
fRootShowerEnv->SetValue("RootShower.fB",fB);
fRootShowerEnv->SaveLevel(kEnvLocal);
std::cout << " Saving stuff .... " << std::endl;
#ifdef R__WIN32
gSystem->Exec("del .rootshowerrc");
gSystem->Rename(".rootshowerrc.new",".rootshowerrc");
#endif
}
}
std::cout << "Terminating RootShower" << std::endl;
DeleteWindow();
gApplication->Terminate(0);
}
////////////////////////////////////////////////////////////////////////////////
/// This event is generated when the frame is resized.
Bool_t RootShower::HandleConfigureNotify(Event_t *event)
{
TGFrame* f = (TGFrame*)this;
if ((event->fWidth != f->GetWidth()) || (event->fHeight != f->GetHeight())) {
UInt_t w = event->fWidth;
UInt_t h = event->fHeight;
f->Resize(w,h);
f->Layout();
}
return kTRUE;
}
////////////////////////////////////////////////////////////////////////////////
/// Handle messages send to the RootShower object.
Bool_t RootShower::ProcessMessage(Longptr_t msg, Longptr_t parm1, Longptr_t parm2)
{
Window_t wdummy;
int ax, ay;
TRootHelpDialog *hd;
TGListTreeItem *item;
TGFileInfo fi;
Char_t strtmp[250];
switch (GET_MSG(msg)) {
case kC_COMMAND:
switch (GET_SUBMSG(msg)) {
case kCM_BUTTON:
case kCM_MENU:
switch (parm1) {
case M_EVENT_NEXT:
if (fDisplayFrame->GetCurrent() != 0)
fDisplayFrame->SetTab(0);
Initialize(0);
fStatusBar->SetText("Simulation running, please wait...",0);
fButtonFrame->SetState(GButtonFrame::kNoneActive);
fMenuEvent->DisableEntry(M_SETTINGS_DLG);
OnShowerProduce();
fEventListTree->ClearViewPort();
fClient->NeedRedraw(fEventListTree);
fButtonFrame->SetState(GButtonFrame::kAllActive);
fMenuEvent->EnableEntry(M_SETTINGS_DLG);
sprintf(strtmp,"Done - Total particles : %d - Waiting for next simulation",
fEvent->GetTotal());
fStatusBar->SetText(strtmp,0);
break;
case M_EVENT_SELECT:
if (fDisplayFrame->GetCurrent() != 1)
fDisplayFrame->SetTab(1);
if ((item = fEventListTree->GetSelected()) != 0)
OnShowSelected(item);
break;
case M_INTERRUPT_SIMUL:
Interrupt();
break;
case M_ZOOM_PLUS:
fCA->cd();
fCA->GetView()->ZoomView(0, 1.25);
fCA->Modified();
fCA->Update();
break;
case M_ZOOM_MOINS:
fCA->cd();
fCA->GetView()->UnzoomView(0, 1.25);
fCA->Modified();
fCA->Update();
break;
case M_ZOOM_PLUS2:
fCB->cd();
fCB->GetView()->ZoomView(0, 1.25);
fCB->Modified();
fCB->Update();
break;
case M_ZOOM_MOINS2:
fCB->cd();
fCB->GetView()->UnzoomView(0, 1.25);
fCB->Modified();
fCB->Update();
break;
case M_FILE_OPEN:
if (fIsRunning) break;
fi.fFileTypes = filetypes;
new TGFileDialog(fClient->GetRoot(), this, kFDOpen,&fi);
if (!fi.fFilename) return kTRUE;
OnOpenFile(fi.fFilename);
break;
case M_FILE_HTML:
{
THtml html;
html.SetInputDir(gProgPath);
html.MakeClass("MyParticle");
html.MakeClass("MyDetector");
html.MakeClass("EventHeader");
html.MakeClass("MyEvent");
html.MakeIndex();
}
break;
case M_FILE_SAVEAS:
if (fIsRunning) break;
fi.fFileTypes = filetypes;
new TGFileDialog(fClient->GetRoot(), this, kFDSave,&fi);
if (!fi.fFilename) return kTRUE;
OnSaveFile(fi.fFilename);
break;
case M_FILE_EXIT:
CloseWindow(); // this also terminates theApp
break;
case M_SHOW_PROCESS:
if (fShowProcess) {
fMenuEvent->UnCheckEntry(M_SHOW_PROCESS);
fShowProcess = kFALSE;
}
else {
fMenuEvent->CheckEntry(M_SHOW_PROCESS);
fShowProcess = kTRUE;
}
break;
case M_ANIMATE_GIF:
if (fCreateGIFs) {
fMenuEvent->UnCheckEntry(M_ANIMATE_GIF);
fCreateGIFs = kFALSE;
}
else {
fMenuEvent->CheckEntry(M_ANIMATE_GIF);
fCreateGIFs = kTRUE;
}
break;
case M_SETTINGS_DLG:
if (fIsRunning) break;
new SettingsDialog(fClient->GetRoot(), this, 400, 200);
if (fSettingsModified) {
fEvent->Init(0, fFirstParticle, fE0, fB);
Initialize(0);
gRootShower->Modified();
gRootShower->SettingsModified(kFALSE);
}
break;
case M_SETTINGS_SAVE:
fRootShowerEnv->SetValue("RootShower.fFirstParticle",fFirstParticle);
fRootShowerEnv->SetValue("RootShower.fE0",fE0);
fRootShowerEnv->SetValue("RootShower.fB",fB);
fRootShowerEnv->SaveLevel(kEnvLocal);
#ifdef R__WIN32
gSystem->Exec("del .rootshowerrc");
gSystem->Rename(".rootshowerrc.new",".rootshowerrc");
#endif
gRootShower->Modified(kFALSE);
break;
case M_SHOW_INFOS:
if (fIsRunning) break;
ShowInfos();
break;
case M_INSPECT_BROWSER:
new TBrowser;
break;
case M_VIEW_TOOLBAR:
if (fMenuView->IsEntryChecked(M_VIEW_TOOLBAR))
ShowToolBar(kFALSE);
else
ShowToolBar();
break;
case M_HELP_PHYSICS:
#ifdef R__WIN32
sprintf(strtmp, "start winhlp32 %s\\Physics.hlp",gProgPath);
gSystem->Exec(strtmp);
#else
sprintf(strtmp, "Help on Physics");
hd = new TRootHelpDialog(this, strtmp, 620, 350);
hd->SetText(gPhysicsHelpText);
gVirtualX->TranslateCoordinates(GetId(), GetParent()->GetId(),
(Int_t)(GetWidth() - 620) >> 1,
(Int_t)(GetHeight() - 350) >> 1,
ax, ay, wdummy);
hd->Move(ax, ay);
hd->Popup();
fClient->WaitFor(hd);
#endif
break;
case M_HELP_SIMULATION:
sprintf(strtmp, "Help on Simulation");
hd = new TRootHelpDialog(this, strtmp, 620, 350);
hd->SetText(gSimulationHelpText);
gVirtualX->TranslateCoordinates(GetId(), GetParent()->GetId(),
(Int_t)(GetWidth() - 620) >> 1,
(Int_t)(GetHeight() - 350) >> 1,
ax, ay, wdummy);
hd->Move(ax, ay);
hd->Popup();
fClient->WaitFor(hd);
break;
case M_HELP_LICENSE:
sprintf(strtmp, "RootShower License");
hd = new TRootHelpDialog(this, strtmp, 640, 380);
hd->SetText(gHelpLicense);
gVirtualX->TranslateCoordinates(GetId(), GetParent()->GetId(),
(Int_t)(GetWidth() - 640) >> 1,
(Int_t)(GetHeight() - 380) >> 1,
ax, ay, wdummy);
hd->Move(ax, ay);
hd->Popup();
fClient->WaitFor(hd);
break;
case M_HELP_ABOUT:
new RootShowerAbout(gClient->GetRoot(),this, 400, 200);
break;
case M_SHOW_3D:
if (gGLManager) {
if (fIsRunning) break;
TString cmd;
fCA->cd();
TVirtualViewer3D *viewer3D = fCA->GetViewer3D("ogl");
cmd.Form("((TGLViewer *)0x%zx)->SetCurrentCamera(TGLViewer::kCameraPerspXOY)",
(size_t)viewer3D);
gROOT->ProcessLine(cmd);
cmd.Form("((TGLViewer *)0x%zx)->CurrentCamera().RotateRad(0.0, TMath::Pi())",
(size_t)viewer3D);
gROOT->ProcessLine(cmd);
cmd.Form("((TGLViewer *)0x%zx)->CurrentCamera().Dolly(-100, 0, 0)",
(size_t)viewer3D);
gROOT->ProcessLine(cmd);
}
break;
case M_SHOW_TRACK:
if (fIsRunning) break;
if (fDisplayFrame->GetCurrent() != 1)
fDisplayFrame->SetTab(1);
if ((item = fEventListTree->GetSelected()) != 0)
OnShowSelected(item);
break;
} // switch parm1
break; // M_MENU
} // switch submsg
break; // case kC_COMMAND
case kC_LISTTREE:
switch (GET_SUBMSG(msg)) {
case kCT_ITEMDBLCLICK:
if (parm1 == kButton1) {
if (fEventListTree->GetSelected()) {
fEventListTree->ClearViewPort();
fClient->NeedRedraw(fEventListTree);
}
}
break;
case kCT_ITEMCLICK:
if (parm1 == kButton3) {
if (fEventListTree->GetSelected()) {
Int_t x = (Int_t)(parm2 & 0xffff);
Int_t y = (Int_t)((parm2 >> 16) & 0xffff);
Clicked(fEventListTree->GetSelected(), x, y);
}
}
break;
} // switch submsg
break; // case kC_LISTTREE
} // switch msg
return kTRUE;
}
////////////////////////////////////////////////////////////////////////////////
/// Add item to the TGListTree of the event display. It will be connected
/// to the current TGListTreeItem (i.e. fCurEventListItem)
TGListTreeItem* RootShower::AddToTree(const char *name)
{
TGListTreeItem *e = 0;
e = fEventListTree->AddItem(fCurListItem, name);
return e;
}
////////////////////////////////////////////////////////////////////////////////
/// Add recursively stations and layers (and cells) in TGListTree.
void RootShower::BuildEventTree()
{
fCurListItem = 0;
TGListTreeItem *eventLTItem = AddToTree("Event");
fCurListItem = eventLTItem;
gBaseLTI = eventLTItem;
}
////////////////////////////////////////////////////////////////////////////////
/// Initialize RootShower display.
void RootShower::Initialize(Int_t set_angles)
{
Interrupt(kFALSE);
fEventListTree->DeleteChildren(fCurListItem);
fEventListTree->ClearViewPort();
fClient->NeedRedraw(fEventListTree);
fCB->cd();
fCB->SetFillColor(1);
fCB->Clear();
gGeoManager->GetTopVolume()->Draw();
fCB->GetView()->SetPerspective();
if (set_angles)
fCB->GetView()->SideView();
gGeoManager->GetTopVolume()->Draw();
fCB->cd();
fCB->Update();
fCA->cd();
fCA->SetFillColor(1);
fCA->Clear();
gGeoManager->GetTopVolume()->Draw();
fCA->GetView()->SetPerspective();
if (set_angles)
fCA->GetView()->SideView();
gGeoManager->GetTopVolume()->Draw();
fCA->cd();
fCA->Update();
fStatusBar->SetText("",1);
}
////////////////////////////////////////////////////////////////////////////////
/// Produce (generate) one event.
void RootShower::Produce()
{
Int_t local_num,local_last,local_end;
Int_t old_num;
Bool_t first_pass;
Char_t strtmp[80];
// Check if some Event parameters have changed
if ((fEvent->GetHeader()->GetDate() != fEventTime) ||
(fEvent->GetHeader()->GetPrimary() != fFirstParticle) ||
(fEvent->GetHeader()->GetEnergy() != fE0) ||
(fEvent->GetB() != fB)) {
fEventNr++;
fNRun = 0;
}
fEvent->SetHeader(fEventNr, fNRun++, fEventTime, fFirstParticle, fE0);
fEvent->Init(0, fFirstParticle, fE0, fB);
fMenuFile->DisableEntry(M_FILE_SAVEAS);
fMenuEvent->DisableEntry(M_SHOW_3D);
fToolBar->GetButton(M_SHOW_3D)->SetState(kButtonDisabled);
fToolBar->GetButton(M_FILE_SAVEAS)->SetState(kButtonDisabled);
Interrupt(kFALSE);
first_pass = kTRUE;
old_num = -1;
// loop events until user interrupt or until all particles are dead
while ((!IsInterrupted()) && (fEvent->GetNAlives() > 0)) {
if (first_pass && fEvent->GetTotal() > 1) {
fEventListTree->OpenItem(gBaseLTI);
fEventListTree->OpenItem(gLTI[0]);
fEventListTree->ClearViewPort();
fClient->NeedRedraw(fEventListTree);
first_pass = kFALSE;
}
if (fEvent->GetTotal() > old_num) {
sprintf(strtmp,"Simulation running, particles : %4d, please wait...",fEvent->GetTotal());
old_num = fEvent->GetTotal();
fStatusBar->SetText(strtmp,0);
// Update display here to not slow down too much...
gSystem->ProcessEvents();
}
local_last = fEvent->GetLast();
local_num = 0;
local_end = kFALSE;
while ((!IsInterrupted()) && (local_end == kFALSE) && (local_num < (local_last + 1))) {
// Update display here if fast machine...
if (fEvent->GetParticle(local_num)->GetStatus() != DEAD) {
gSystem->ProcessEvents();
if (fEvent->Action(local_num) == DEAD)
local_end = kTRUE;
if (fEvent->GetParticle(local_num)->GetStatus() == CREATED)
fEvent->GetParticle(local_num)->SetStatus(ALIVE);
}
local_num ++;
}
}
fMenuEvent->EnableEntry(M_SHOW_INFOS);
if (!IsInterrupted()) {
if (gGLManager) {
fMenuEvent->EnableEntry(M_SHOW_3D);
fToolBar->GetButton(M_SHOW_3D)->SetState(kButtonUp);
}
fToolBar->GetButton(M_FILE_SAVEAS)->SetState(kButtonUp);
fMenuFile->EnableEntry(M_FILE_SAVEAS);
}
}
////////////////////////////////////////////////////////////////////////////////
/// Initialize and generate one event.
void RootShower::OnShowerProduce()
{
Int_t i, j;
fStatusBar->SetText("",1);
SetWindowName("Root Shower Event Display");
// animation logo handling
if (fPicReset > 0) fPicIndex = 1;
// animation timer
if (!fTimer) fTimer = new TTimer(this, fPicDelay);
fTimer->Reset();
fTimer->TurnOn();
fEventTime.Set();
fIsRunning = kTRUE;
fHisto_dEdX->Reset();
Produce();
Interrupt(kFALSE);
for (i=0;i<=fEvent->GetTotal();i++) {
gSystem->ProcessEvents(); // handle GUI events
if (IsInterrupted()) break;
// if particle has no child, represent it by a leaf,
// otherwise by a branch
if (fEvent->GetParticle(i)->GetChildId(0) == 0) {
lpic = gClient->GetPicture("leaf_t.xpm");
lspic = gClient->GetPicture("leaf_t.xpm");
gLTI[i]->SetPictures(lpic, lspic);
}
else {
bpic = gClient->GetPicture("branch_t.xpm");
bspic = gClient->GetPicture("branch_t.xpm");
gLTI[i]->SetPictures(bpic, bspic);
}
// Show only charged and massive particles...
if ((fEvent->GetParticle(i)->GetPdgCode() != PHOTON) &&
(fEvent->GetParticle(i)->GetPdgCode() != NEUTRINO_E) &&
(fEvent->GetParticle(i)->GetPdgCode() != NEUTRINO_MUON) &&
(fEvent->GetParticle(i)->GetPdgCode() != NEUTRINO_TAU) &&
(fEvent->GetParticle(i)->GetPdgCode() != ANTINEUTRINO_E) &&
(fEvent->GetParticle(i)->GetPdgCode() != ANTINEUTRINO_MUON) &&
(fEvent->GetParticle(i)->GetPdgCode() != ANTINEUTRINO_TAU) ) {
// Fill histogram for particle's energy loss
fHisto_dEdX->Fill(fEvent->GetParticle(i)->GetELoss());
for (j=0;j<fEvent->GetParticle(i)->GetNTracks();j++)
fEvent->GetParticle(i)->GetTrack(j)->Draw();
// show track by track if "show process" has been chosen
// into the menu
if (fShowProcess) {
fCA->Modified();
fCA->Update();
// create one gif image by step if "Animated GIF"
// has been chosen into the menu
if (fCreateGIFs) {
fCA->SaveAs("RSEvent.gif+");
}
}
}
}
AppendPad();
fCA->GetView()->SetPerspective();
fCA->cd();
fCA->Modified();
fCA->Update();
fPadC->cd();
// do not fit if not enough particles
if (fHisto_dEdX->GetEntries() > 10) {
fHisto_dEdX->Fit("landau","L");
TF1 *f1 = fHisto_dEdX->GetFunction("landau");
//delete fit function is fit is a non sense
if (f1 && f1->GetNDF() > 0) {
f1->SetLineColor(kRed);
f1->SetLineWidth(1);
} else {
delete f1;
}
}
fHisto_dEdX->Draw();
fPadC->Modified();
fPadC->Update();
fCC->Update();
fPadC->cd();
fPadC->SetFillColor(16);
fPadC->GetFrame()->SetFillColor(10);
fPadC->Draw();
fPadC->Update();
// Open first list tree items
fEventListTree->OpenItem(gBaseLTI);
fEventListTree->OpenItem(gLTI[0]);
fTimer->TurnOff();
fIsRunning = kFALSE;
if (fPicReset > 0)
fTitleFrame->ChangeRightLogo(1);
}
////////////////////////////////////////////////////////////////////////////////
/// No comment...
void RootShower::HighLight(TGListTreeItem * /*item*/)
{
}
////////////////////////////////////////////////////////////////////////////////
/// Shows track which has been selected into the list tree
void RootShower::OnShowSelected(TGListTreeItem *item)
{
Int_t i, j, retval;
fCB->cd();
fCB->SetFillColor(1);
fCB->SetBorderMode(0);
fCB->SetBorderSize(0);
fCB->Clear();
fCB->cd();
// draw geometry
gGeoManager->GetTopVolume()->Draw();
fCB->GetView()->SetPerspective();
fCB->cd();
fCB->Update();
retval = -1;
for (i=0;i<=fEvent->GetTotal();i++) {
if (gLTI[i] == item) {
retval = i;
break;
}
}
if ((retval > -1) &&
(fEvent->GetParticle(i)->GetPdgCode() != PHOTON) &&
(fEvent->GetParticle(i)->GetPdgCode() != NEUTRINO_E) &&
(fEvent->GetParticle(i)->GetPdgCode() != NEUTRINO_MUON) &&
(fEvent->GetParticle(i)->GetPdgCode() != NEUTRINO_TAU) &&
(fEvent->GetParticle(i)->GetPdgCode() != ANTINEUTRINO_E) &&
(fEvent->GetParticle(i)->GetPdgCode() != ANTINEUTRINO_MUON) &&
(fEvent->GetParticle(i)->GetPdgCode() != ANTINEUTRINO_TAU) ) {
for (j=0;j<fEvent->GetParticle(retval)->GetNTracks();j++)
fEvent->GetParticle(retval)->GetTrack(j)->Draw();
}
fCB->GetView()->SetPerspective();
fCB->cd();
fCB->Modified();
fCB->Update();
}
////////////////////////////////////////////////////////////////////////////////
/// Opens a root file into which a previous event has been saved.
void RootShower::OnOpenFile(const Char_t *filename)
{
char strtmp[256];
Int_t i,j;
TFile *f = new TFile(filename);
TTree *tree;
TBranch *branch;
fStatusBar->SetText("",1);
fEvent->Init(0, fFirstParticle, fE0, fB);
fHisto_dEdX->Reset();
tree = (TTree *)f->Get("RootShower");
if (tree == NULL) return;
branch = tree->GetBranch("Event");
branch->SetAddress(&fEvent);
tree->GetEntry(0, 1);
f->Close();
// take back detector dimensions for selection geometry
gGeoManager->Import(filename, "detector");
Initialize(1);
for (i=0;i<=fEvent->GetTotal();i++) {
gTmpLTI = fEventListTree->AddItem(gBaseLTI, fEvent->GetParticle(i)->GetName());
gTmpLTI->SetUserData(fEvent->GetParticle(i));
sprintf(strtmp,"%1.2f GeV",fEvent->GetParticle(i)->Energy());
fEventListTree->SetToolTipItem(gTmpLTI, strtmp);
gLTI[i] = gTmpLTI;
if (fEvent->GetParticle(i)->GetChildId(0) == 0) {
lpic = gClient->GetPicture("leaf_t.xpm");
lspic = gClient->GetPicture("leaf_t.xpm");
gLTI[i]->SetPictures(lpic, lspic);
}
else {
bpic = gClient->GetPicture("branch_t.xpm");
bspic = gClient->GetPicture("branch_t.xpm");
gLTI[i]->SetPictures(bpic, bspic);
}
if ((fEvent->GetParticle(i)->GetPdgCode() != PHOTON) &&
(fEvent->GetParticle(i)->GetPdgCode() != NEUTRINO_E) &&
(fEvent->GetParticle(i)->GetPdgCode() != NEUTRINO_MUON) &&
(fEvent->GetParticle(i)->GetPdgCode() != NEUTRINO_TAU) &&
(fEvent->GetParticle(i)->GetPdgCode() != ANTINEUTRINO_E) &&
(fEvent->GetParticle(i)->GetPdgCode() != ANTINEUTRINO_MUON) &&
(fEvent->GetParticle(i)->GetPdgCode() != ANTINEUTRINO_TAU) ) {
// Fill histogram for particle's energy loss
fHisto_dEdX->Fill(fEvent->GetParticle(i)->GetELoss());
for (j=0;j<fEvent->GetParticle(i)->GetNTracks();j++)
fEvent->GetParticle(i)->GetTrack(j)->Draw();
}
}
// Reparent each list tree item regarding the
// corresponding particle relations
for (i=1;i<=fEvent->GetTotal();i++) {
fEventListTree->Reparent(gLTI[i],
gLTI[fEvent->GetParticle(i)->GetFirstMother()]);
}
fEventListTree->OpenItem(gBaseLTI);
fEventListTree->OpenItem(gLTI[0]);
fEventListTree->ClearViewPort();
fClient->NeedRedraw(fEventListTree);
AppendPad();
sprintf(strtmp,"Done - Total particles : %d - Waiting for next simulation",
fEvent->GetTotal());
fStatusBar->SetText(strtmp,0);
fPadC->cd();
// do not fit if not enough particles
if (fHisto_dEdX->GetEntries() > 10) {
fHisto_dEdX->Fit("landau","L");
TF1 *f1 = fHisto_dEdX->GetFunction("landau");
//delete fit function is fit is a non sense
if (f1 && f1->GetNDF() > 0) {
f1->SetLineColor(kRed);
f1->SetLineWidth(1);
} else {
delete f1;
}
}
fHisto_dEdX->Draw();
fPadC->Modified();
fPadC->Update();
fCC->Update();
fPadC->cd();
fPadC->SetFillColor(16);
fPadC->GetFrame()->SetFillColor(10);
fPadC->Draw();
fPadC->Update();
fCA->cd();
fCA->Modified();
fCA->Update();
fMenuEvent->EnableEntry(M_SHOW_INFOS);
if (gGLManager) {
fMenuEvent->EnableEntry(M_SHOW_3D);
fToolBar->GetButton(M_SHOW_3D)->SetState(kButtonUp);
}
fToolBar->GetButton(M_FILE_SAVEAS)->SetState(kButtonUp);
fMenuFile->EnableEntry(M_FILE_SAVEAS);
fButtonFrame->SetState(GButtonFrame::kAllActive);
sprintf(strtmp,"Root Shower Event Display - %s",filename);
SetWindowName(strtmp);
}
////////////////////////////////////////////////////////////////////////////////
/// Saves current event into a Root file
void RootShower::OnSaveFile(const Char_t *filename)
{
TFile *hfile;
char strtmp[256];
gGeoManager->Export(filename, "detector");
hfile = new TFile(filename,"UPDATE","Root Shower file");
hfile->SetCompressionLevel(9);
TTree *hTree = new TTree("RootShower","Root Shower tree");
hTree->Branch("Event", "MyEvent", &fEvent, 8000, 2);
hTree->Fill(); //fill the tree
hTree->Write();
hTree->Print();
hfile->Close();
sprintf(strtmp,"Root Shower Event Display - %s",filename);
SetWindowName(strtmp);
}
////////////////////////////////////////////////////////////////////////////////
/// Gives infos on current event
void RootShower::ShowInfos()
{
Window_t wdummy;
int ax, ay;
TRootHelpDialog *hd;
Char_t str[32];
Char_t Msg[500];
Double_t dimx,dimy,dimz;
fEvent->GetDetector()->GetDimensions(&dimx, &dimy, &dimz);
sprintf(Msg, " Some information about the current shower\n");
sprintf(Msg, "%s Dimensions of the target\n", Msg);
sprintf(Msg, "%s X .................... : %1.2e [cm] \n", Msg, dimx);
sprintf(Msg, "%s Y .................... : %1.2e [cm] \n", Msg, dimy);
sprintf(Msg, "%s Z .................... : %1.2e [cm] \n", Msg, dimz);
sprintf(Msg, "%s Magnetic field ....... : %1.2e [kGauss]\n", Msg,
fEvent->GetB());
sprintf(Msg, "%s Initial particle ..... : %s \n", Msg,
fEvent->GetParticle(0)->GetName());
sprintf(Msg, "%s Initial energy ....... : %1.2e [GeV] \n", Msg,
fEvent->GetHeader()->GetEnergy());
sprintf(Msg, "%s Total Energy loss .... : %1.2e [GeV]", Msg,
fEvent->GetDetector()->GetTotalELoss());
sprintf(str, "Infos on current shower");
hd = new TRootHelpDialog(this, str, 420, 155);
hd->SetText(Msg);
gVirtualX->TranslateCoordinates( GetId(), GetParent()->GetId(),
(Int_t)(GetWidth() - 420) >> 1,(Int_t)(GetHeight() - 155) >> 1,
ax, ay, wdummy);
hd->Move(ax, ay);
hd->Popup();
fClient->WaitFor(hd);
}
////////////////////////////////////////////////////////////////////////////////
/// Handle keyboard events.
Bool_t RootShower::HandleKey(Event_t *event)
{
char input[10];
UInt_t keysym;
if (event->fType == kGKeyPress) {
gVirtualX->LookupString(event, input, sizeof(input), keysym);
switch ((EKeySym)keysym) { // ignore these keys
case kKey_Shift:
case kKey_Control:
case kKey_Meta:
case kKey_Alt:
case kKey_CapsLock:
case kKey_NumLock:
case kKey_ScrollLock:
return kTRUE;
case kKey_F1:
SendMessage(this, MK_MSG(kC_COMMAND, kCM_MENU),
M_HELP_SIMULATION, 0);
return kTRUE;
default:
break;
}
if (event->fState & kKeyControlMask) { // Cntrl key modifier pressed
switch ((EKeySym)keysym & ~0x20) { // treat upper and lower the same
case kKey_A:
SendMessage(this, MK_MSG(kC_COMMAND, kCM_MENU),
M_FILE_SAVEAS, 0);
return kTRUE;
case kKey_B:
SendMessage(this, MK_MSG(kC_COMMAND, kCM_MENU),
M_INSPECT_BROWSER, 0);
return kTRUE;
case kKey_I:
SendMessage(this, MK_MSG(kC_COMMAND, kCM_MENU),
M_SHOW_INFOS, 0);
return kTRUE;
case kKey_O:
SendMessage(this, MK_MSG(kC_COMMAND, kCM_MENU),
M_FILE_OPEN, 0);
return kTRUE;
case kKey_Q:
SendMessage(this, MK_MSG(kC_COMMAND, kCM_MENU),
M_FILE_EXIT, 0);
return kTRUE;
default:
break;
}
}
}
return TGMainFrame::HandleKey(event);
}
////////////////////////////////////////////////////////////////////////////////
/// Logo animation timer handling.
Bool_t RootShower::HandleTimer(TTimer *)
{
if (fPicIndex > fPicNumber) fPicIndex = 1;
fTitleFrame->ChangeRightLogo(fPicIndex);
fPicIndex++;
fTimer->Reset();
return kTRUE;
}
////////////////////////////////////////////////////////////////////////////////
/// Compute distance from point px,py to objects in event
Int_t RootShower::DistancetoPrimitive(Int_t px, Int_t py)
{
Int_t i, j;
Int_t dist = 9999;
if (fEvent->GetTotal() <= 0) return 0;
// Browse every track and get related particle infos.
for (i=0;i<fEvent->GetTotal();i++) {
for (j=0;j<fEvent->GetParticle(i)->GetNTracks();j++) {
dist = fEvent->GetParticle(i)->GetTrack(j)->DistancetoPrimitive(px, py);
if (dist < 2) {
gPad->SetSelected((TObject*)fEvent->GetParticle(i));
fStatusBar->SetText(fEvent->GetParticle(i)->GetObjectInfo(px, py),1);
gPad->SetCursor(kPointer);
return 0;
}
}
}
gPad->SetSelected((TObject*)gPad->GetView());
return gPad->GetView()->DistancetoPrimitive(px,py);
}
////////////////////////////////////////////////////////////////////////////////
/// Process mouse clicks in TGListTree.
void RootShower::Clicked(TGListTreeItem *item, Int_t x, Int_t y)
{
MyParticle *part = (MyParticle *) item->GetUserData();
if (part) {
fContextMenu->Popup(x, y, part);
}
fEventListTree->ClearViewPort();
}
////////////////////////////////////////////////////////////////////////////////
/// Main (entry point).
int main(int argc, char **argv)
{
Bool_t rint = kFALSE;
for (int i = 0; i < argc; i++) {
if (!strcmp(argv[i], "-d")) rint = kTRUE;
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-?")) {
printf("Usage: %s [-d] [-h | -?]\n", argv[0]);
printf(" -d: debug and inspect mode via ROOT prompt\n");
printf(" -h, -?: this message\n");
return 0;
}
}
TApplication *theApp;
if (rint)
theApp = new TRint("App", &argc, argv);
else
theApp = new TApplication("App", &argc, argv);
gStyle->SetOptStat(1111);
gStyle->SetOptFit(1111);
gStyle->SetStatFont(42);
if (!gGLManager) {
TString x = "win32";
if (gVirtualX->InheritsFrom("TGX11"))
x = "x11";
TPluginHandler *ph = gROOT->GetPluginManager()->FindHandler("TGLManager", x);
if (ph && ph->LoadPlugin() != -1)
ph->ExecPlugin(0);
}
gRandom->SetSeed( (UInt_t)time( NULL ) );
const Int_t NRGBs = 5;
Double_t Stops[NRGBs] = { 0.00, 0.50, 0.75, 0.875, 1.00 };
Double_t Red[NRGBs] = { 1.00, 1.00, 1.00, 1.00, 1.00 };
Double_t Green[NRGBs] = { 1.00, 0.75, 0.50, 0.25, 0.00 };
Double_t Blue[NRGBs] = { 0.00, 0.00, 0.00, 0.00, 0.00 };
gColIndex = TColor::CreateGradientColorTable(NRGBs, Stops, Red, Green, Blue, 17);
// Create RootShower
RootShower theShower(gClient->GetRoot(), 400, 200);
// run ROOT application
theApp->Run();
// pro forma, never reached
delete theApp;
return 0;
}
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...