9 #include <ecl/modules/eclDisplay/EclFrame.h>
15 #include <TRootEmbeddedCanvas.h>
16 #include <TGDoubleSlider.h>
17 #include <TGNumberEntry.h>
18 #include <TGListTree.h>
19 #include <TGFileDialog.h>
22 #include <TGComboBox.h>
26 #include <ecl/modules/eclDisplay/geometry.h>
27 #include <ecl/utility/ECLChannelMapper.h>
28 #include <ecl/modules/eclDisplay/MultilineWidget.h>
29 #include <ecl/modules/eclDisplay/EclPainter.h>
30 #include <ecl/modules/eclDisplay/EclPainter1D.h>
34 using namespace ECLDisplayUtility;
39 "Encapsulated PostScript",
"*.eps",
44 "ROOT files",
"*.root",
57 m_subsys = EclData::ALL;
65 for (
int i = 1; i <= data->getCrystalCount(); i++) {
66 int phi_id = data->getPhiId(i);
67 int theta_id = data->getThetaId(i);
69 if (phi_id == -1 || theta_id == -1)
70 data->excludeChannel(i);
75 m_auto_display = auto_display;
77 gStyle->SetOptStat(0);
90 B2DEBUG(100,
"EclFrame:: initializing GUI.");
92 SetLayoutManager(
new TGVerticalLayout(
this));
93 TGCompositeFrame* frame_container =
new TGCompositeFrame(
this, w, h, kHorizontalFrame);
97 TGPopupMenu* menu_file =
new TGPopupMenu(gClient->GetRoot());
98 menu_file->AddEntry(
"&Open...", M_FILE_OPEN);
99 menu_file->AddEntry(
"&Export TTree...", M_FILE_EXPORT_TREE);
100 menu_file->AddEntry(
"&Save As...", M_FILE_SAVE);
101 menu_file->AddSeparator();
102 menu_file->AddEntry(
"&Exit", M_FILE_EXIT);
103 TGPopupMenu* menu_view =
new TGPopupMenu(gClient->GetRoot());
104 menu_view->AddEntry(
"&Show event counts in histograms", M_VIEW_EVENTS);
105 menu_view->AddEntry(
"&Show energy in histograms", M_VIEW_ENERGY);
106 menu_view->AddSeparator();
107 menu_view->AddEntry(
"&Show events from all ECL subsystems", M_VIEW_DET_FULL);
108 menu_view->AddEntry(
"&Show events from ECL barrel", M_VIEW_DET_BARR);
109 menu_view->AddEntry(
"&Show events from ECL forward endcap", M_VIEW_DET_FORW);
110 menu_view->AddEntry(
"&Show events from ECL backward endcap", M_VIEW_DET_BACK);
112 TGMenuBar* menubar =
new TGMenuBar(
this, w, 30);
113 menubar->AddPopup(
"&File", menu_file,
new TGLayoutHints(kLHintsTop | kLHintsLeft));
114 menubar->AddPopup(
"&View", menu_view,
new TGLayoutHints(kLHintsTop | kLHintsLeft));
116 menu_file->Connect(
"Activated(Int_t)",
"Belle2::EclFrame",
117 this,
"handleMenu(Int_t)");
118 menu_view->Connect(
"Activated(Int_t)",
"Belle2::EclFrame",
119 this,
"handleMenu(Int_t)");
121 AddFrame(menubar,
new TGLayoutHints(kLHintsExpandX | kLHintsTop, 0, 0, 1, 1));
125 m_settings =
new TGVerticalFrame(frame_container, w / 6, h);
129 TGComboBox* diagram_type =
new TGComboBox(m_settings, -1);
130 diagram_type->SetName(
"DiagramType");
133 for (
int i = 0; i < types_count; i++)
134 diagram_type->AddEntry(types_names[i], i);
135 diagram_type->Select(m_painter_type);
136 diagram_type->SetHeight(16);
137 m_settings->AddFrame(diagram_type,
new TGLayoutHints(kLHintsExpandX));
138 diagram_type->Connect(
"Selected(Int_t)",
"Belle2::EclFrame",
this,
139 "changeType(Int_t)");
144 m_frame1->setLineCount(4);
146 m_settings->AddFrame(m_frame1,
new TGLayoutHints(kLHintsExpandX));
150 m_frame2 =
new TGGroupFrame(m_settings,
"Range of displayed events");
151 m_frame2->SetLayoutManager(
new TGVerticalLayout(m_frame2));
153 TGHorizontalFrame* frame2_1 =
new TGHorizontalFrame(m_frame2);
154 TGLabel* ev_min_label =
new TGLabel(frame2_1,
"Min: ");
155 frame2_1->AddFrame(ev_min_label,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
156 m_events_min =
new TGNumberEntry(frame2_1, 0, 6, -1, TGNumberFormat::kNESInteger);
157 frame2_1->AddFrame(m_events_min,
new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2));
158 TGLabel* ev_max_label =
new TGLabel(frame2_1,
"Max: ");
159 frame2_1->AddFrame(ev_max_label,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
160 m_events_max =
new TGNumberEntry(frame2_1, 0, 6, -1, TGNumberFormat::kNESInteger);
161 frame2_1->AddFrame(m_events_max,
new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2));
162 m_frame2->AddFrame(frame2_1);
164 m_ev_slider =
new TGDoubleHSlider(m_frame2, w / 6, 2);
165 m_frame2->AddFrame(m_ev_slider,
new TGLayoutHints(kLHintsExpandX, 5, 5, 3, 4));
167 TGHorizontalFrame* frame2_2 =
new TGHorizontalFrame(m_frame2);
168 TGTextButton* prev =
new TGTextButton(frame2_2,
"&Prev");
169 prev->Connect(
"Clicked()",
"Belle2::EclFrame",
this,
"showPrevEvents()");
170 frame2_2->AddFrame(prev,
new TGLayoutHints(kLHintsLeft, 5, 5, 3, 4));
171 TGTextButton* next =
new TGTextButton(frame2_2,
"&Next");
172 next->Connect(
"Clicked()",
"Belle2::EclFrame",
this,
"showNextEvents()");
173 frame2_2->AddFrame(next,
new TGLayoutHints(kLHintsRight, 5, 5, 3, 4));
174 m_frame2->AddFrame(frame2_2,
new TGLayoutHints(kLHintsExpandX));
176 m_settings->AddFrame(m_frame2,
new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
182 m_frame3 =
new TGGroupFrame(m_settings,
"Displayed channels");
184 TGCanvas* list_canvas =
new TGCanvas(m_frame3, 1, 100);
185 m_list_tree =
new TGListTree(list_canvas, kHorizontalFrame);
186 m_list_tree->Associate(m_frame3);
187 TGListTreeItem* root = m_list_tree->AddItem(0,
"Detector");
188 m_list_tree->OpenItem(root);
189 for (
int i = 0; i < 52; i++) {
190 sprintf(temp,
"Collector %d", i);
191 TGListTreeItem* parent = m_list_tree->AddItem(root, temp);
192 parent->SetUserData((
void*)((intptr_t)i));
193 for (
int j = 0; j < 12; j++) {
194 sprintf(temp,
"Shaper %d", i * 12 + j);
195 TGListTreeItem* item = m_list_tree->AddItem(parent, temp);
196 item->SetUserData((
void*)((intptr_t)j));
200 m_list_tree->Connect(
"Clicked(TGListTreeItem*, Int_t)",
"Belle2::EclFrame",
this,
201 "changeRange(TGListTreeItem*, Int_t)");
203 m_frame3->AddFrame(list_canvas,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
204 m_settings->AddFrame(m_frame3,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2));
208 m_frame4 =
new TGGroupFrame(m_settings,
"Channel exclusion");
209 m_frame4->SetLayoutManager(
new TGHorizontalLayout(m_frame4));
210 m_channel_id =
new TGNumberEntry(m_frame4, 0, 6, -1, TGNumberFormat::kNESInteger);
211 m_frame4->AddFrame(m_channel_id,
new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2));
212 TGTextButton* exclude =
new TGTextButton(m_frame4,
"&Exclude");
213 exclude->Connect(
"Clicked()",
"Belle2::EclFrame",
this,
"excludeChannel()");
214 m_frame4->AddFrame(exclude,
new TGLayoutHints(kLHintsRight, 5, 5, 3, 4));
216 m_settings->AddFrame(m_frame4,
new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
220 m_frame5 =
new TGGroupFrame(m_settings,
"Energy threshold");
221 TGHorizontalFrame* frame5_1 =
new TGHorizontalFrame(m_frame5);
222 frame5_1->SetLayoutManager(
new TGHorizontalLayout(frame5_1));
223 m_min_en_threshold =
new TGNumberEntry(frame5_1, 2.5, 6, -1);
224 TGLabel* min_lab =
new TGLabel(frame5_1,
"MeV");
225 m_max_en_threshold =
new TGNumberEntry(frame5_1, 150, 6, -1);
226 TGLabel* max_lab =
new TGLabel(frame5_1,
"MeV");
227 frame5_1->AddFrame(m_min_en_threshold,
new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2));
228 frame5_1->AddFrame(min_lab,
new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2));
229 frame5_1->AddFrame(max_lab,
new TGLayoutHints(kLHintsRight, 2, 2, 2, 2));
230 frame5_1->AddFrame(m_max_en_threshold,
new TGLayoutHints(kLHintsRight, 2, 2, 2, 2));
232 m_frame5->AddFrame(frame5_1);
233 m_threshold_switch =
new TGCheckButton(m_frame5,
"Enable energy threshold");
234 m_threshold_switch->SetState(kButtonDown);
235 m_frame5->AddFrame(m_threshold_switch);
237 m_settings->AddFrame(m_frame5,
new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
241 m_draw =
new TGTextButton(m_settings,
"&Draw");
242 m_draw->Connect(
"Clicked()",
"Belle2::EclFrame",
this,
"doDraw()");
243 m_settings->AddFrame(m_draw,
new TGLayoutHints(kLHintsCenterX, 5, 5, 3, 4));
245 m_draw_all =
new TGTextButton(m_settings,
"&Draw All");
246 m_draw_all->Connect(
"Clicked()",
"Belle2::EclFrame",
this,
"doDrawAll()");
247 m_settings->AddFrame(m_draw_all,
new TGLayoutHints(kLHintsCenterX, 5, 5, 3, 4));
251 frame_container->AddFrame(m_settings);
255 m_ecanvas =
new TRootEmbeddedCanvas(
"Ecanvas", frame_container, w / 2, h / 2);
256 m_ecanvas->GetCanvas()->SetRightMargin(0.125);
257 m_ecanvas->GetCanvas()->SetLeftMargin(0.1);
258 frame_container->AddFrame(m_ecanvas,
new TGLayoutHints(
259 kLHintsExpandX | kLHintsExpandY, 10, 10, 10, 1));
261 m_ecanvas->GetCanvas()->
262 Connect(
"TCanvas",
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
263 "Belle2::EclFrame",
this,
"updateInfo(Int_t, Int_t, Int_t, TObject*)");
267 AddFrame(frame_container,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,
270 B2DEBUG(100,
"EclFrame:: GUI initialized.");
272 frame_container->SetMinWidth(w / 2);
276 SetWindowName(
"ECL Data");
281 B2DEBUG(100,
"EclFrame:: Initializing data.");
283 B2DEBUG(100,
"EclFrame:: Data initialized.");
288 m_events_min->SetLimits(TGNumberFormat::kNELLimitMinMax,
289 0, m_ecl_data->getLastEventId());
290 m_events_max->SetLimits(TGNumberFormat::kNELLimitMinMax,
291 0, m_ecl_data->getLastEventId());
293 B2DEBUG(500,
"Last event id: " << m_ecl_data->getLastEventId());
294 m_ev_slider->SetRange(0, m_ecl_data->getLastEventId());
295 m_ev_slider->SetPosition(0, 0);
296 m_ev_slider->Connect(
"TGDoubleHSlider",
"PositionChanged()",
297 "Belle2::EclFrame",
this,
"updateEventRange()");
303 static TString dir(
".");
310 fi.fIniDir = StrDup(dir);
311 new TGFileDialog(gClient->GetRoot(),
this, kFDOpen, &fi);
313 if (gSystem->AccessPathName(fi.fFilename, kFileExists) == 0) {
314 B2DEBUG(50,
"ECLFrame:: Opening file " << fi.fFilename);
315 m_ecl_data->loadRootFile(fi.fFilename);
322 fi.fFileTypes = filetypes;
323 fi.fIniDir = StrDup(dir);
324 new TGFileDialog(gClient->GetRoot(),
this, kFDSave, &fi);
325 B2DEBUG(50,
"Save file: " << fi.fFilename
326 <<
"(dir: " << fi.fIniDir <<
")");
327 m_ecanvas->GetCanvas()->SaveAs(fi.fFilename);
329 case M_FILE_EXPORT_TREE:
330 static const char* filetypes_root[] = {
"Root",
"*.root", 0, 0};
331 fi.fFileTypes = filetypes_root;
332 fi.fIniDir = StrDup(dir);
333 new TGFileDialog(gClient->GetRoot(),
this, kFDSave, &fi);
334 B2DEBUG(50,
"Save file: " << fi.fFilename
335 <<
"(dir: " << fi.fIniDir <<
")");
336 file =
new TFile(fi.fFilename,
"RECREATE");
337 m_ecl_data->getTree()->Write(
"tree");
351 case M_VIEW_DET_FULL:
352 m_subsys = EclData::ALL;
353 m_ecl_painter->setDisplayedSubsystem(m_subsys);
356 case M_VIEW_DET_BARR:
357 m_subsys = EclData::BARR;
358 m_ecl_painter->setDisplayedSubsystem(m_subsys);
361 case M_VIEW_DET_FORW:
362 m_subsys = EclData::FORW;
363 m_ecl_painter->setDisplayedSubsystem(m_subsys);
366 case M_VIEW_DET_BACK:
367 m_subsys = EclData::BACKW;
368 m_ecl_painter->setDisplayedSubsystem(m_subsys);
378 m_ev_slider->SetRange(0, m_ecl_data->getLastEventId());
379 m_events_min->SetLimits(TGNumberFormat::kNELLimitMinMax,
380 0, m_ecl_data->getLastEventId());
381 m_events_max->SetLimits(TGNumberFormat::kNELLimitMinMax,
382 0, m_ecl_data->getLastEventId());
384 if (m_last_event < m_ecl_data->getLastEventId() &&
385 (m_auto_display || m_last_event == -1)) {
387 if (m_last_event <= 1) {
390 m_settings->MapSubwindows();
393 m_ev_slider->SetPosition(0, 0);
401 TCanvas* fCanvas = m_ecanvas->GetCanvas();
405 m_ecl_painter->Draw();
406 updateInfo(51, 0, 0, 0);
412 Float_t ev_min, ev_max;
413 m_ev_slider->GetPosition(&ev_min, &ev_max);
415 m_events_min->SetNumber(ev_min);
416 m_events_max->SetNumber(ev_max);
418 m_ev_slider->MapWindow();
419 m_ev_slider->MapSubwindows();
424 Float_t ev_min, ev_max, diff;
426 ev_min = m_events_min->GetNumber();
427 ev_max = m_events_max->GetNumber();
432 diff = ev_max - ev_min + 1;
438 m_ev_slider->SetPosition(ev_min, ev_max);
445 Float_t ev_min, ev_max, diff;
447 ev_min = m_events_min->GetNumber();
448 ev_max = m_events_max->GetNumber();
450 if (ev_max >= m_ecl_data->getLastEventId())
453 diff = ev_max - ev_min + 1;
456 if (ev_max > m_ecl_data->getLastEventId())
457 ev_max = m_ecl_data->getLastEventId();
459 m_ev_slider->SetPosition(ev_min, ev_max);
466 int ch = m_channel_id->GetNumber();
467 m_ecl_data->excludeChannel(ch,
true);
473 m_ecl_data->setEventRange(m_events_min->GetIntNumber(),
474 m_events_max->GetIntNumber());
476 float en_min = m_min_en_threshold->GetNumber();
477 float en_max = m_max_en_threshold->GetNumber();
478 if (m_threshold_switch->GetState() == kButtonDown)
479 m_ecl_data->setEnergyThreshold(en_min, en_max);
481 m_ecl_data->setEnergyThreshold(0, -1);
488 m_ecl_data->setEventRange(0, m_ecl_data->getLastEventId());
498 if (new_painter !=
nullptr) {
499 delete m_ecl_painter;
500 m_ecl_painter = new_painter;
509 m_ecl_painter->getInformation(px, py, m_frame1);
517 m_frame1->setLineCount(0);
521 TGListTreeItem* parent = entry->GetParent();
526 TGListTreeItem* grandparent = parent->GetParent();
530 long crate = (long)entry->GetUserData();
531 m_ecl_painter->setXRange(crate * 12, crate * 12 + 11);
536 long shaper = (long)entry->GetUserData();
537 long crate = (long)parent->GetUserData();
538 shaper = 12 * crate + shaper;
539 ((
EclPainter1D*)m_ecl_painter)->setShaper(crate + 1, shaper + 1);
554 delete m_ecl_painter;
555 m_ecl_painter = new_painter;
556 m_frame1->setLineCount(0);
557 m_ecanvas->GetCanvas()->Clear();
559 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.
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.