ROOTANA
Loading...
Searching...
No Matches
TFancyHistogramCanvas.cxx
Go to the documentation of this file.
2
3#include "TMesytecData.hxx"
4#include "TH2.h"
5
7
9 std::string name, int numberChannelsInGroups,
10 bool disableAutoUpdate):
12 fHistoArray(histoArray){
13
14 if(histoArray->GetNumberChannelsInGroup() != -1){
15 fNumberChannelsInGroups = histoArray->GetNumberChannelsInGroup();
16 }else if(numberChannelsInGroups > 1)
17 fNumberChannelsInGroups = numberChannelsInGroups;
18 else
19 fNumberChannelsInGroups = -1;
20
21 fLabelframe = 0;
22 fChannelCounterButton = 0;
23 fLabelChannels = 0;
24 fChannelName = "Histogram";
25 if(histoArray->GetChannelName().compare("")!=0)
26 fChannelName = histoArray->GetChannelName();
27
28 fGroupCounterButton = 0;
29 fLabelGroup = 0;
30 fGroupName = "Group";
31 if(histoArray->GetGroupName().compare("")!=0)
32 fGroupName = histoArray->GetGroupName();
33
34 fMultiCanvasButton = 0;
35 fNCanvasButtonGroup =0;
36 fNCanvasButtons[0]=0;
37 fNCanvasButtons[1]=0;
38 fNCanvasButtons[2]=0;
39 fNCanvasButtons[3]=0;
40 fOverlayHistoButton = 0;
41 fNHistoButton = 0;
42 labelNHisto = 0;
43
44 // Construct the legend here, so that user can modify position immediately.
45 fNHistoLegend = new TLegend(0.6,0.6,0.89,0.8);
46 fNHistoLegend->SetFillColor(10);
47
48 fDisableAutoUpdate = disableAutoUpdate;
49 if(histoArray->HasAutoUpdate())
50 fDisableAutoUpdate = histoArray->GetDisableAutoUpdate();
51
52}
53
57
58/// This is the complicated part, where we create a bunch of buttons and widgets.
59void TFancyHistogramCanvas::SetUpCompositeFrame(TGCompositeFrame *compFrame, TRootanaDisplay *display){
60
61 /// Cached pointer to rootana display; needed so that we can
62 /// create new buttons with correct callbacks.
63 fDisplay = display;
64
65 // Now create my embedded canvas, along with the various buttons for this canvas.
66 // Sub-frame, to reduce space used
67 fLabelframe = new TGHorizontalFrame(compFrame,200,40);
68 compFrame->AddFrame(fLabelframe, new TGLayoutHints(kLHintsCenterX,2,2,2,2));
69
70 // ________________________________________________________________________________
71 // Add a button for the groups, if we are using groups
73
74 TGVerticalFrame *hframe1 = new TGVerticalFrame(fLabelframe, 120, 40, kFixedWidth);
75 fLabelframe->AddFrame(hframe1, new TGLayoutHints(kLHintsLeft,2,2,2,2));
76 int numberGroups = (int)(((double)fHistoArray->size())/((double)fNumberChannelsInGroups));
77
78 fGroupCounterButton = new TGNumberEntry(hframe1, 0, 9,999, TGNumberFormat::kNESInteger,
79 TGNumberFormat::kNEANonNegative,
80 TGNumberFormat::kNELLimitMinMax,
81 0, numberGroups-1);
82
83 hframe1->AddFrame(fGroupCounterButton, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 1));
84 // Add call-backs to update plots if widget is used
85 fGroupCounterButton->Connect("ValueSet(Long_t)", "TRootanaDisplay", display, "UpdatePlotsAction()");
86 fGroupCounterButton->GetNumberEntry()->Connect("ReturnPressed()", "TRootanaDisplay", display, "UpdatePlotsAction()");
87
88 // Add a label for channel selector
89 fLabelGroup = new TGLabel(hframe1, "");
90 hframe1->AddFrame(fLabelGroup, new TGLayoutHints(kLHintsLeft , 1, 1, 1, 1));
92 }
93
94 // ________________________________________________________________________________
95 // Create the default set of widgets used for all display options: namely a counter
96 // that keeps track of which channel to start from.
97
98 // Sub-frame, to reduce space used
99 TGVerticalFrame *hframe2 = new TGVerticalFrame(fLabelframe, 120, 40, kFixedWidth);
100 fLabelframe->AddFrame(hframe2, new TGLayoutHints(kLHintsLeft,2,2,2,2));
101 int numberChannels = fHistoArray->size();
103 numberChannels = fNumberChannelsInGroups;
104 }
105 fChannelCounterButton = new TGNumberEntry(hframe2, 0, 9,999, TGNumberFormat::kNESInteger,
106 TGNumberFormat::kNEANonNegative,
107 TGNumberFormat::kNELLimitMinMax,
108 0, numberChannels-1);
109
110 hframe2->AddFrame(fChannelCounterButton, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 1));
111 // Add call-backs to update plots if widget is used
112 fChannelCounterButton->Connect("ValueSet(Long_t)", "TRootanaDisplay", display, "UpdatePlotsAction()");
113 fChannelCounterButton->GetNumberEntry()->Connect("ReturnPressed()", "TRootanaDisplay", display, "UpdatePlotsAction()");
114
115 // Add a label for channel selector
116 fLabelChannels = new TGLabel(hframe2, "");
117 hframe2->AddFrame(fLabelChannels, new TGLayoutHints(kLHintsLeft, 5, 5, 5, 5));
119
120 // ________________________________________________________________________________
121 // Create a button to control whether to use multiple canvases
122 fMultiCanvasButton = new TGCheckButton(fLabelframe, new TGHotString("Multi-Canvas"));
123 fLabelframe->AddFrame(fMultiCanvasButton, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5));
124
125 // Add call-backs to update plots if button is used; ensure both not all modes are simultaneously active
126 fMultiCanvasButton->Connect("Toggled(Bool_t)", "TFancyHistogramCanvas", this, "ActivateMultiCanvasButton()");
127 fMultiCanvasButton->Connect("Toggled(Bool_t)", "TRootanaDisplay", display, "UpdatePlotsAction()");
128
129 /// Add the button group to control how many sub-canvases to plot.
130 fNCanvasButtonGroup = new TGHButtonGroup(fLabelframe, "Number of Canvases:");
131 fNCanvasButtons[0] = new TGRadioButton(fNCanvasButtonGroup, new TGHotString("2 | "),1);
132 fNCanvasButtons[1] = new TGRadioButton(fNCanvasButtonGroup, new TGHotString("4 | "),2);
133 fNCanvasButtons[2] = new TGRadioButton(fNCanvasButtonGroup, new TGHotString("8 | "),3);
134 fNCanvasButtons[3] = new TGRadioButton(fNCanvasButtonGroup, new TGHotString("16 | "),4);
135 fNCanvasButtons[0]->SetOn();
136 for(int i = 0; i < 4; i++)
137 fNCanvasButtons[i]->Connect("Toggled(Bool_t)", "TRootanaDisplay", fDisplay, "UpdatePlotsAction()");
138
139 fNCanvasButtonGroup->SetRadioButtonExclusive(kTRUE);
140
141 fNCanvasButtonGroup->Show();
142 fLabelframe->AddFrame(fNCanvasButtonGroup, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5));
143 fNCanvasButtonGroup->SetState(false);
144
145 // ________________________________________________________________________________
146 // Create a button to control whether to overlay histograms in a single canvas
147 fOverlayHistoButton = new TGCheckButton(fLabelframe, new TGHotString("Overlay-Histo"));
148 fLabelframe->AddFrame(fOverlayHistoButton, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5));
149
150 // Add call-backs to update plots if button is used; ensure both not all modes are simultaneously active
151 fOverlayHistoButton->Connect("Toggled(Bool_t)", "TFancyHistogramCanvas", this, "ActivateOverlayButton()");
152 fOverlayHistoButton->Connect("Toggled(Bool_t)", "TRootanaDisplay", display, "UpdatePlotsAction()");
153
154 /// Add the button to control how many histograns to plot to plot.
155
156 // Sub-frame, to reduce space used
157 TGVerticalFrame *hframe3 = new TGVerticalFrame(fLabelframe, 120, 40, kFixedWidth);
158 fLabelframe->AddFrame(hframe3, new TGLayoutHints(kLHintsLeft,2,2,2,2));
159
160 fNHistoButton = new TGNumberEntry(hframe3, 2, 9,999, TGNumberFormat::kNESInteger,
161 TGNumberFormat::kNEANonNegative,
162 TGNumberFormat::kNELLimitMinMax,
163 2, 20);
164 hframe3->AddFrame(fNHistoButton, new TGLayoutHints(kLHintsLeft, 5, 5, 5, 5));
165 // Add call-backs to update plots if widget is used
166 fNHistoButton->Connect("ValueSet(Long_t)", "TRootanaDisplay", display, "UpdatePlotsAction()");
167 fNHistoButton->GetNumberEntry()->Connect("ReturnPressed()", "TRootanaDisplay", display, "UpdatePlotsAction()");
168 fNHistoButton->SetState(false);
169 // Add a label
170 labelNHisto = new TGLabel(hframe3, "# Histo in Canvas");
171 hframe3->AddFrame(labelNHisto, new TGLayoutHints(kLHintsLeft, 5, 5, 5, 5));
172
173}
174
175
176
177/// Reset the histograms in fHistoArray.
179 for(unsigned int i = 0; i < fHistoArray->size(); i++)
180 (*fHistoArray)[i]->Reset();
181}
182
183/// Update the histograms for this canvas.
185
186 // If this variable is set, then skip calling the histogram updating;
187 // histogram updating will happen elsewhere.
188 if(fDisableAutoUpdate) return;
189
190 fHistoArray->UpdateHistograms(dataContainer);
191}
192
193
194// Helper method to be able to treat TH2 histograms differently
195void DrawHistogram(TH1* histo, std::string option = std::string("")){
196
197 if(dynamic_cast<TH2*>(histo)){
198 std::string fulloption = std::string("COLZ") + option;
199 histo->Draw(fulloption.c_str());
200 }else{
201 histo->Draw(option.c_str());
202 }
203
204}
205
206/// Plot the histograms for this canvas
207void TFancyHistogramCanvas::PlotCanvas(TDataContainer& dataContainer, TRootEmbeddedCanvas *embedCanvas){
208
209
210 TCanvas* c1 = embedCanvas->GetCanvas();
211 c1->Clear();
212
213 int channel = fChannelCounterButton->GetNumberEntry()->GetIntNumber();
215 channel = fGroupCounterButton->GetNumberEntry()->GetIntNumber() * fNumberChannelsInGroups
216 + fChannelCounterButton->GetNumberEntry()->GetIntNumber();
217
218 // Choose the display pattern based on which buttons have been pushed.
219
220 // Multiple canvas option
221 if(fMultiCanvasButton->IsOn()){
222
223 int ncanvas = 1;
224 if(fNCanvasButtons[0]->IsOn()){
225 c1->Divide(1,2);
226 ncanvas = 2;
227 }
228 if(fNCanvasButtons[1]->IsOn()){
229 c1->Divide(2,2);
230 ncanvas = 4;
231 }
232 if(fNCanvasButtons[2]->IsOn()){
233 c1->Divide(2,4);
234 ncanvas = 8;
235 }
236 if(fNCanvasButtons[3]->IsOn()){
237 c1->Divide(4,4);
238 ncanvas = 16;
239 }
240
241 for(int i = 0; i < ncanvas; i++){
242 c1->cd(i+1);
243 int index = i + channel;
244 if(index >=0 && index < (int)fHistoArray->size() && (*fHistoArray)[index]){
245 DrawHistogram((*fHistoArray)[index]);
246 (*fHistoArray)[index]->SetLineColor(1);
247 }
248 }
249
250 }else if(fOverlayHistoButton->IsOn()){ // Show multiple histograms on same canvas.
251
252 int nhisto = fNHistoButton->GetNumberEntry()->GetIntNumber();
253
254 // Kind of annoying; need to do two loops through the data in order to check which is
255 // the maximum histogram.
256 int first_channel = channel;
257 int last_channel = channel + nhisto;
258 if(last_channel > (int)fHistoArray->size())
259 last_channel = fHistoArray->size();
260
261 // find the maximum histogram;
262 TH1 *max_histo = 0;
263 for(int ichan = first_channel; ichan < last_channel; ichan++){
264 if(max_histo == 0)
265 max_histo = (*fHistoArray)[ichan];
266 else if((*fHistoArray)[ichan]->GetMaximum() > max_histo->GetMaximum())
267 max_histo = (*fHistoArray)[ichan];
268
269 }
270
271 // New loop again and draw as we go.
272
273 DrawHistogram(max_histo);
274 fNHistoLegend->Clear();
275 char name[100];
276 for(int ichan = first_channel; ichan < last_channel; ichan++){
277
278 (*fHistoArray)[ichan]->SetLineColor(ichan-channel+1);
279 sprintf(name,"Histogram # %i",ichan);
280 fNHistoLegend->AddEntry((*fHistoArray)[ichan],(*fHistoArray)[ichan]->GetTitle());
281
282 if((*fHistoArray)[ichan] == max_histo) continue;
283
284 DrawHistogram((*fHistoArray)[ichan],"SAME");
285 }
286
287 fNHistoLegend->Draw("SAME");
288
289 }else{ // Default: single canvas, single histogram.
290
291
292 if(channel >=0 && channel < (int) fHistoArray->size() && (*fHistoArray)[channel]){
293
294 DrawHistogram((*fHistoArray)[channel]);
295
296 (*fHistoArray)[channel]->SetLineColor(1);
297 }
298
299 }
300 c1->Modified();
301 c1->Update();
302
303}
304
305
306
307/// Take actions at begin run
308void TFancyHistogramCanvas::BeginRun(int transition,int run,int time){
309 fHistoArray->BeginRun(transition, run, time);
310};
311
312/// Take actions at end run
313void TFancyHistogramCanvas::EndRun(int transition,int run,int time){
314 fHistoArray->EndRun(transition, run, time);
315};
316
317
319 if(fMultiCanvasButton->IsOn()){
320 fOverlayHistoButton->SetDown(false); // Deactivate overlay button
321 fNCanvasButtonGroup->SetState(true); // Enable the set of Ncanvas buttons
322 fNHistoButton->SetState(false);
323 }else{
324 fNCanvasButtonGroup->SetState(false);// Disable the set of Ncanvas buttons
325
326 }
327}
329 if(fOverlayHistoButton->IsOn()){
330 fMultiCanvasButton->SetDown(false); // Deactivate multi-canvas button
331 fNCanvasButtonGroup->SetState(false); // Disable the set of Ncanvas buttons
332 fNHistoButton->SetState(true);
333 }else{
334 fNHistoButton->SetState(false);
335 }
336
337
338
339}
340
341
342void TFancyHistogramCanvas::SetGroupName(std::string groupName){
343
344 fGroupName = groupName;
345
346 if(!fLabelGroup) return;
347 int numberGroups = (int)(((double)fHistoArray->size())/((double)fNumberChannelsInGroups));
348 char tlabel[100];
349 sprintf(tlabel,"%s# (0-%i)",groupName.c_str(),(int)numberGroups-1);
350
351 fLabelGroup->SetText(tlabel);//TGLabel
352}
353
354void TFancyHistogramCanvas::SetChannelName(std::string channelName){
355
356 fChannelName = channelName;
357
358 if(!fLabelChannels) return;
359 int numberChannels = fHistoArray->size();
361 numberChannels = fNumberChannelsInGroups;
362 }
363
364 char tlabel[100];
365 sprintf(tlabel,"%s# (0-%i)",channelName.c_str(),(int)numberChannels-1);
366
367 fLabelChannels->SetText(tlabel);//TGLabel
368
369
370}
ClassImp(TFancyHistogramCanvas) TFancyHistogramCanvas
void DrawHistogram(TH1 *histo, std::string option=std::string(""))
TGLabel * fLabelChannels
A label for the histogram number button.
TGHorizontalFrame * fLabelframe
Overall frame in which we will add buttons and widgets.
TGHButtonGroup * fNCanvasButtonGroup
Button group to select how many canvases to show.
void UpdateCanvasHistograms(TDataContainer &dataContainer)
Update the histograms for this canvas.
std::string fChannelName
Name for the channel button.
TGNumberEntry * fNHistoButton
Button group to select how many histograms to show.
TGCheckButton * fMultiCanvasButton
This button controls whether to display mutliple sub-canvases.
TGRadioButton * fNCanvasButtons[4]
void BeginRun(int transition, int run, int time)
Take actions at begin run.
void PlotCanvas(TDataContainer &dataContainer, TRootEmbeddedCanvas *embedCanvas)
Plot the histograms for this canvas.
std::string fGroupName
Name for the group button.
TGLabel * fLabelGroup
A label for the group button.
void ResetCanvasHistograms()
Reset the histograms for this canvas.
TGNumberEntry * fChannelCounterButton
Button for the histogram number.
void EndRun(int transition, int run, int time)
Take actions at end run
THistogramArrayBase * fHistoArray
Pointer to the THistogramArrayBase class; memory is not owned by TFancyHistogramCanvas.
void SetChannelName(std::string channelName)
Allow the user to set explicitly the channel name.
void SetGroupName(std::string groupName)
Allow the user to set explicitly the group name.
TGCheckButton * fOverlayHistoButton
This button controls whether to display overlaid histograms.
TGNumberEntry * fGroupCounterButton
Button for the group number.
void SetUpCompositeFrame(TGCompositeFrame *compFrame, TRootanaDisplay *display)
This is the complicated part, where we create a bunch of buttons and widgets.
virtual void BeginRun(int transition, int run, int time)
Take actions at begin run.
const std::string GetChannelName()
const int GetNumberChannelsInGroup()
const std::string GetGroupName()
virtual void UpdateHistograms(TDataContainer &dataContainer)=0
Update the histograms for this canvas.
virtual void EndRun(int transition, int run, int time)
Take actions at end run
const bool GetDisableAutoUpdate()