10 #include <ecl/modules/eclDisplay/EclFrame.h>
13 #include <ecl/mapper/ECLChannelMapper.h>
14 #include <ecl/modules/eclDisplay/geometry.h>
15 #include <ecl/modules/eclDisplay/MultilineWidget.h>
16 #include <ecl/modules/eclDisplay/EclPainter.h>
17 #include <ecl/modules/eclDisplay/EclPainter1D.h>
22 #include <TGComboBox.h>
23 #include <TGDoubleSlider.h>
24 #include <TGFileDialog.h>
26 #include <TGListTree.h>
28 #include <TGNumberEntry.h>
29 #include <TRootEmbeddedCanvas.h>
35 using namespace ECLDisplayUtility;
40 "Encapsulated PostScript",
"*.eps",
45 "ROOT files",
"*.root",
58 m_subsys = EclData::ALL;
66 for (
int i = 1; i <= data->getCrystalCount(); i++) {
67 int phi_id = data->getPhiId(i);
68 int theta_id = data->getThetaId(i);
70 if (phi_id == -1 || theta_id == -1)
71 data->excludeChannel(i);
76 m_auto_display = auto_display;
78 gStyle->SetOptStat(0);
91 B2DEBUG(100,
"EclFrame:: initializing GUI.");
93 SetLayoutManager(
new TGVerticalLayout(
this));
94 TGCompositeFrame* frame_container =
new TGCompositeFrame(
this, w, h, kHorizontalFrame);
98 TGPopupMenu* menu_file =
new TGPopupMenu(gClient->GetRoot());
99 menu_file->AddEntry(
"&Open...", M_FILE_OPEN);
100 menu_file->AddEntry(
"&Export TTree...", M_FILE_EXPORT_TREE);
101 menu_file->AddEntry(
"&Save As...", M_FILE_SAVE);
102 menu_file->AddSeparator();
103 menu_file->AddEntry(
"&Exit", M_FILE_EXIT);
104 TGPopupMenu* menu_view =
new TGPopupMenu(gClient->GetRoot());
105 menu_view->AddEntry(
"&Show event counts in histograms", M_VIEW_EVENTS);
106 menu_view->AddEntry(
"&Show energy in histograms", M_VIEW_ENERGY);
107 menu_view->AddSeparator();
108 menu_view->AddEntry(
"&Show events from all ECL subsystems", M_VIEW_DET_FULL);
109 menu_view->AddEntry(
"&Show events from ECL barrel", M_VIEW_DET_BARR);
110 menu_view->AddEntry(
"&Show events from ECL forward endcap", M_VIEW_DET_FORW);
111 menu_view->AddEntry(
"&Show events from ECL backward endcap", M_VIEW_DET_BACK);
113 TGMenuBar* menubar =
new TGMenuBar(
this, w, 30);
114 menubar->AddPopup(
"&File", menu_file,
new TGLayoutHints(kLHintsTop | kLHintsLeft));
115 menubar->AddPopup(
"&View", menu_view,
new TGLayoutHints(kLHintsTop | kLHintsLeft));
117 menu_file->Connect(
"Activated(Int_t)",
"Belle2::EclFrame",
118 this,
"handleMenu(Int_t)");
119 menu_view->Connect(
"Activated(Int_t)",
"Belle2::EclFrame",
120 this,
"handleMenu(Int_t)");
122 AddFrame(menubar,
new TGLayoutHints(kLHintsExpandX | kLHintsTop, 0, 0, 1, 1));
126 m_settings =
new TGVerticalFrame(frame_container, w / 6, h);
130 TGComboBox* diagram_type =
new TGComboBox(m_settings, -1);
131 diagram_type->SetName(
"DiagramType");
134 for (
int i = 0; i < types_count; i++)
135 diagram_type->AddEntry(types_names[i], i);
136 diagram_type->Select(m_painter_type);
137 diagram_type->SetHeight(16);
138 m_settings->AddFrame(diagram_type,
new TGLayoutHints(kLHintsExpandX));
139 diagram_type->Connect(
"Selected(Int_t)",
"Belle2::EclFrame",
this,
140 "changeType(Int_t)");
145 m_frame1->setLineCount(4);
147 m_settings->AddFrame(m_frame1,
new TGLayoutHints(kLHintsExpandX));
151 m_frame2 =
new TGGroupFrame(m_settings,
"Range of displayed events");
152 m_frame2->SetLayoutManager(
new TGVerticalLayout(m_frame2));
154 TGHorizontalFrame* frame2_1 =
new TGHorizontalFrame(m_frame2);
155 TGLabel* ev_min_label =
new TGLabel(frame2_1,
"Min: ");
156 frame2_1->AddFrame(ev_min_label,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
157 m_events_min =
new TGNumberEntry(frame2_1, 0, 6, -1, TGNumberFormat::kNESInteger);
158 frame2_1->AddFrame(m_events_min,
new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2));
159 TGLabel* ev_max_label =
new TGLabel(frame2_1,
"Max: ");
160 frame2_1->AddFrame(ev_max_label,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
161 m_events_max =
new TGNumberEntry(frame2_1, 0, 6, -1, TGNumberFormat::kNESInteger);
162 frame2_1->AddFrame(m_events_max,
new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2));
163 m_frame2->AddFrame(frame2_1);
165 m_ev_slider =
new TGDoubleHSlider(m_frame2, w / 6, 2);
166 m_frame2->AddFrame(m_ev_slider,
new TGLayoutHints(kLHintsExpandX, 5, 5, 3, 4));
168 TGHorizontalFrame* frame2_2 =
new TGHorizontalFrame(m_frame2);
169 TGTextButton* prev =
new TGTextButton(frame2_2,
"&Prev");
170 prev->Connect(
"Clicked()",
"Belle2::EclFrame",
this,
"showPrevEvents()");
171 frame2_2->AddFrame(prev,
new TGLayoutHints(kLHintsLeft, 5, 5, 3, 4));
172 TGTextButton* next =
new TGTextButton(frame2_2,
"&Next");
173 next->Connect(
"Clicked()",
"Belle2::EclFrame",
this,
"showNextEvents()");
174 frame2_2->AddFrame(next,
new TGLayoutHints(kLHintsRight, 5, 5, 3, 4));
175 m_frame2->AddFrame(frame2_2,
new TGLayoutHints(kLHintsExpandX));
177 m_settings->AddFrame(m_frame2,
new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
183 m_frame3 =
new TGGroupFrame(m_settings,
"Displayed channels");
185 TGCanvas* list_canvas =
new TGCanvas(m_frame3, 1, 100);
186 m_list_tree =
new TGListTree(list_canvas, kHorizontalFrame);
187 m_list_tree->Associate(m_frame3);
188 TGListTreeItem* root = m_list_tree->AddItem(0,
"Detector");
189 m_list_tree->OpenItem(root);
190 for (
int i = 0; i < 52; i++) {
191 sprintf(temp,
"Collector %d", i);
192 TGListTreeItem* parent = m_list_tree->AddItem(root, temp);
193 parent->SetUserData((
void*)((intptr_t)i));
194 for (
int j = 0; j < 12; j++) {
195 sprintf(temp,
"Shaper %d", i * 12 + j);
196 TGListTreeItem* item = m_list_tree->AddItem(parent, temp);
197 item->SetUserData((
void*)((intptr_t)j));
201 m_list_tree->Connect(
"Clicked(TGListTreeItem*, Int_t)",
"Belle2::EclFrame",
this,
202 "changeRange(TGListTreeItem*, Int_t)");
204 m_frame3->AddFrame(list_canvas,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
205 m_settings->AddFrame(m_frame3,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2));
209 m_frame4 =
new TGGroupFrame(m_settings,
"Channel exclusion");
210 m_frame4->SetLayoutManager(
new TGHorizontalLayout(m_frame4));
211 m_channel_id =
new TGNumberEntry(m_frame4, 0, 6, -1, TGNumberFormat::kNESInteger);
212 m_frame4->AddFrame(m_channel_id,
new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2));
213 TGTextButton* exclude =
new TGTextButton(m_frame4,
"&Exclude");
214 exclude->Connect(
"Clicked()",
"Belle2::EclFrame",
this,
"excludeChannel()");
215 m_frame4->AddFrame(exclude,
new TGLayoutHints(kLHintsRight, 5, 5, 3, 4));
217 m_settings->AddFrame(m_frame4,
new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
221 m_frame5 =
new TGGroupFrame(m_settings,
"Energy threshold");
222 TGHorizontalFrame* frame5_1 =
new TGHorizontalFrame(m_frame5);
223 frame5_1->SetLayoutManager(
new TGHorizontalLayout(frame5_1));
224 m_min_en_threshold =
new TGNumberEntry(frame5_1, 2.5, 6, -1);
225 TGLabel* min_lab =
new TGLabel(frame5_1,
"MeV");
226 m_max_en_threshold =
new TGNumberEntry(frame5_1, 150, 6, -1);
227 TGLabel* max_lab =
new TGLabel(frame5_1,
"MeV");
228 frame5_1->AddFrame(m_min_en_threshold,
new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2));
229 frame5_1->AddFrame(min_lab,
new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2));
230 frame5_1->AddFrame(max_lab,
new TGLayoutHints(kLHintsRight, 2, 2, 2, 2));
231 frame5_1->AddFrame(m_max_en_threshold,
new TGLayoutHints(kLHintsRight, 2, 2, 2, 2));
233 m_frame5->AddFrame(frame5_1);
234 m_threshold_switch =
new TGCheckButton(m_frame5,
"Enable energy threshold");
235 m_threshold_switch->SetState(kButtonDown);
236 m_frame5->AddFrame(m_threshold_switch);
238 m_settings->AddFrame(m_frame5,
new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
242 m_draw =
new TGTextButton(m_settings,
"&Draw");
243 m_draw->Connect(
"Clicked()",
"Belle2::EclFrame",
this,
"doDraw()");
244 m_settings->AddFrame(m_draw,
new TGLayoutHints(kLHintsCenterX, 5, 5, 3, 4));
246 m_draw_all =
new TGTextButton(m_settings,
"&Draw All");
247 m_draw_all->Connect(
"Clicked()",
"Belle2::EclFrame",
this,
"doDrawAll()");
248 m_settings->AddFrame(m_draw_all,
new TGLayoutHints(kLHintsCenterX, 5, 5, 3, 4));
252 frame_container->AddFrame(m_settings);
256 m_ecanvas =
new TRootEmbeddedCanvas(
"Ecanvas", frame_container, w / 2, h / 2);
257 m_ecanvas->GetCanvas()->SetRightMargin(0.125);
258 m_ecanvas->GetCanvas()->SetLeftMargin(0.1);
259 frame_container->AddFrame(m_ecanvas,
new TGLayoutHints(
260 kLHintsExpandX | kLHintsExpandY, 10, 10, 10, 1));
262 m_ecanvas->GetCanvas()->
263 Connect(
"TCanvas",
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
264 "Belle2::EclFrame",
this,
"updateInfo(Int_t, Int_t, Int_t, TObject*)");
268 AddFrame(frame_container,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,
271 B2DEBUG(100,
"EclFrame:: GUI initialized.");
273 frame_container->SetMinWidth(w / 2);
277 SetWindowName(
"ECL Data");
282 B2DEBUG(100,
"EclFrame:: Initializing data.");
284 B2DEBUG(100,
"EclFrame:: Data initialized.");
289 m_events_min->SetLimits(TGNumberFormat::kNELLimitMinMax,
290 0, m_ecl_data->getLastEventId());
291 m_events_max->SetLimits(TGNumberFormat::kNELLimitMinMax,
292 0, m_ecl_data->getLastEventId());
294 B2DEBUG(500,
"Last event id: " << m_ecl_data->getLastEventId());
295 m_ev_slider->SetRange(0, m_ecl_data->getLastEventId());
296 m_ev_slider->SetPosition(0, 0);
297 m_ev_slider->Connect(
"TGDoubleHSlider",
"PositionChanged()",
298 "Belle2::EclFrame",
this,
"updateEventRange()");
304 static TString dir(
".");
311 fi.fIniDir = StrDup(dir);
312 new TGFileDialog(gClient->GetRoot(),
this, kFDOpen, &fi);
314 if (gSystem->AccessPathName(fi.fFilename, kFileExists) == 0) {
315 B2DEBUG(50,
"ECLFrame:: Opening file " << fi.fFilename);
316 m_ecl_data->loadRootFile(fi.fFilename);
323 fi.fFileTypes = filetypes;
324 fi.fIniDir = StrDup(dir);
325 new TGFileDialog(gClient->GetRoot(),
this, kFDSave, &fi);
326 B2DEBUG(50,
"Save file: " << fi.fFilename
327 <<
"(dir: " << fi.fIniDir <<
")");
328 m_ecanvas->GetCanvas()->SaveAs(fi.fFilename);
330 case M_FILE_EXPORT_TREE:
331 static const char* filetypes_root[] = {
"Root",
"*.root", 0, 0};
332 fi.fFileTypes = filetypes_root;
333 fi.fIniDir = StrDup(dir);
334 new TGFileDialog(gClient->GetRoot(),
this, kFDSave, &fi);
335 B2DEBUG(50,
"Save file: " << fi.fFilename
336 <<
"(dir: " << fi.fIniDir <<
")");
337 file =
new TFile(fi.fFilename,
"RECREATE");
338 m_ecl_data->getTree()->Write(
"tree");
352 case M_VIEW_DET_FULL:
353 m_subsys = EclData::ALL;
354 m_ecl_painter->setDisplayedSubsystem(m_subsys);
357 case M_VIEW_DET_BARR:
358 m_subsys = EclData::BARR;
359 m_ecl_painter->setDisplayedSubsystem(m_subsys);
362 case M_VIEW_DET_FORW:
363 m_subsys = EclData::FORW;
364 m_ecl_painter->setDisplayedSubsystem(m_subsys);
367 case M_VIEW_DET_BACK:
368 m_subsys = EclData::BACKW;
369 m_ecl_painter->setDisplayedSubsystem(m_subsys);
379 m_ev_slider->SetRange(0, m_ecl_data->getLastEventId());
380 m_events_min->SetLimits(TGNumberFormat::kNELLimitMinMax,
381 0, m_ecl_data->getLastEventId());
382 m_events_max->SetLimits(TGNumberFormat::kNELLimitMinMax,
383 0, m_ecl_data->getLastEventId());
385 if (m_last_event < m_ecl_data->getLastEventId() &&
386 (m_auto_display || m_last_event == -1)) {
388 if (m_last_event <= 1) {
391 m_settings->MapSubwindows();
394 m_ev_slider->SetPosition(0, 0);
402 TCanvas* fCanvas = m_ecanvas->GetCanvas();
406 m_ecl_painter->Draw();
407 updateInfo(51, 0, 0, 0);
413 Float_t ev_min, ev_max;
414 m_ev_slider->GetPosition(&ev_min, &ev_max);
416 m_events_min->SetNumber(ev_min);
417 m_events_max->SetNumber(ev_max);
419 m_ev_slider->MapWindow();
420 m_ev_slider->MapSubwindows();
425 Float_t ev_min, ev_max, diff;
427 ev_min = m_events_min->GetNumber();
428 ev_max = m_events_max->GetNumber();
433 diff = ev_max - ev_min + 1;
439 m_ev_slider->SetPosition(ev_min, ev_max);
446 Float_t ev_min, ev_max, diff;
448 ev_min = m_events_min->GetNumber();
449 ev_max = m_events_max->GetNumber();
451 if (ev_max >= m_ecl_data->getLastEventId())
454 diff = ev_max - ev_min + 1;
457 if (ev_max > m_ecl_data->getLastEventId())
458 ev_max = m_ecl_data->getLastEventId();
460 m_ev_slider->SetPosition(ev_min, ev_max);
467 int ch = m_channel_id->GetNumber();
468 m_ecl_data->excludeChannel(ch,
true);
474 m_ecl_data->setEventRange(m_events_min->GetIntNumber(),
475 m_events_max->GetIntNumber());
477 float en_min = m_min_en_threshold->GetNumber();
478 float en_max = m_max_en_threshold->GetNumber();
479 if (m_threshold_switch->GetState() == kButtonDown)
480 m_ecl_data->setEnergyThreshold(en_min, en_max);
482 m_ecl_data->setEnergyThreshold(0, -1);
489 m_ecl_data->setEventRange(0, m_ecl_data->getLastEventId());
499 if (new_painter !=
nullptr) {
500 delete m_ecl_painter;
501 m_ecl_painter = new_painter;
510 m_ecl_painter->getInformation(px, py, m_frame1);
518 m_frame1->setLineCount(0);
522 TGListTreeItem* parent = entry->GetParent();
527 TGListTreeItem* grandparent = parent->GetParent();
531 long crate = (long)entry->GetUserData();
532 m_ecl_painter->setXRange(crate * 12, crate * 12 + 11);
537 long shaper = (long)entry->GetUserData();
538 long crate = (long)parent->GetUserData();
539 shaper = 12 * crate + shaper;
540 ((
EclPainter1D*)m_ecl_painter)->setShaper(crate + 1, shaper + 1);
555 delete m_ecl_painter;
556 m_ecl_painter = new_painter;
557 m_frame1->setLineCount(0);
558 m_ecanvas->GetCanvas()->Clear();
560 updateInfo(51, 0, 0, 0);
This class provides access to ECL channel map that is either a) Loaded from the database (see ecl/dbo...
This class contains data for ECLSimHit's and provides several relevant conversion functions for bette...
void initData()
Initialize data.
void doDrawAll()
Draw all events on m_ecanvas.
void updateInfo(int event, int px, int py, TObject *)
Update information on the cursor position in the histogram.
static const char * filetypes[]
Possible export filetypes for histograms.
void showNextEvents()
Show next range of events.
EclFrame(int painter_type, EclData *data, bool auto_display, ECL::ECLChannelMapper *mapper)
void showPrevEvents()
Show previous range of events.
void handleMenu(int id)
Apply action from menu.
virtual ~EclFrame()
ECLFrame destructor.
void changeType(int type, bool redraw=true)
Change EclPainter type when selected in drop-down menu.
void initGUI(int w, int h)
Initialize GUI.
void changeRange(TGListTreeItem *entry, int btn)
Opens shapers of specific crate/channels of specific shaper.
void doDraw()
Get view parameters from GUI and call updateCanvas().
void loadNewData()
Update view of the data.
void updateCanvas()
Redraw m_ecanvas.
void excludeChannel()
Exclude channel specified in the GUI.
void updateEventRange()
Change event range and pass information to m_ecl_data.
Painter for EclData, 1D histograms.
static EclPainter * createPainter(EclPainterType type, EclData *data, ECL::ECLChannelMapper *mapper, EclData::EclSubsystem subsys=EclData::ALL)
Creates EclPainter of the specified type.
static const char ** getTypeTitles()
Returns array of titles for each EclPainter type.
static int getTypeTitlesCount()
Size of array from getTypeTitles()
Painter for EclData, parent class, created with EclPainterFactory.
virtual EclPainter * handleClick(int px, int py)
Some EclPainters can shift to another view upon click.
void SetMode(int i)
Changes between display of events (0) and energy (1).
EclPainterType
Enum for type of EclPainter to create.
@ PAINTER_CHANNEL
Event count/energy distribution per channel.
@ PAINTER_COLLECTOR
Event count/energy distribution per crate/ECLCollector.
@ PAINTER_SHAPER
Event count/energy distribution per shaperDSP.
Abstract base class for different kinds of events.