]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EVE/Reve/CascadeEditors.cxx
Getting rid of effC++ warnings about missing copy constructor and assignment operator.
[u/mrichter/AliRoot.git] / EVE / Reve / CascadeEditors.cxx
CommitLineData
9b7b1a97 1
2/***********************************************************************
3 This editor appears in the Reve window when v0 are visualize.
4It allows to select the v0 as a function of some useful parameters.
5
6Ludovic Gaudichet (gaudichet@to.infn.it)
7************************************************************************/
8
9
10
11
12#include "CascadeEditors.h"
13#include <Reve/Cascade.h>
14
15#include <Reve/RGValuators.h>
16
17#include <TVirtualPad.h>
18#include <TColor.h>
19
20#include <TGLabel.h>
21#include <TGButton.h>
22#include <TGNumberEntry.h>
23#include <TGColorSelect.h>
24#include <TGDoubleSlider.h>
25
26#include <TGTab.h>
27#include <TRootEmbeddedCanvas.h>
28#include <TCanvas.h>
29#include <TH1.h>
30#include <TH1F.h>
31#include <TH2F.h>
32
33
34using namespace Reve;
35
36//______________________________________________________________________
37// CascadeListEditor
38//
39
40ClassImp(CascadeListEditor)
41
42CascadeListEditor::CascadeListEditor(const TGWindow *p,
43 Int_t width, Int_t height,
44 UInt_t options, Pixel_t back) :
45 TGedFrame(p, width, height, options | kVerticalFrame, back),
46 fMList(0),
47 fRnrV0Daughters(0),
48 fRnrV0path(0),
49 fRnrVtx(0),
50 fRnrBach(0),
51 fRnrCasPath(0),
52 fMainTabA(0),
53 fMainTabB(0)
54{
55 MakeTitle("CascadeList");
56
57 //TGHorizontalFrame* frame = new TGHorizontalFrame(this);
58
59 // --- Rendering control
60
61 fRnrVtx = new TGCheckButton(this, "Render v0 and cascade vertices");
62 AddFrame(fRnrVtx, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
63 fRnrVtx->Connect("Toggled(Bool_t)",
64 "Reve::CascadeListEditor", this, "DoRnrVtx()");
65
66 fRnrV0path = new TGCheckButton(this, "Render v0 path");
67 AddFrame(fRnrV0path, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
68 fRnrV0path->Connect("Toggled(Bool_t)",
69 "Reve::CascadeListEditor", this, "DoRnrV0path()");
70
71 fRnrCasPath = new TGCheckButton(this, "Render cascade path");
72 AddFrame(fRnrCasPath, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
73 fRnrCasPath->Connect("Toggled(Bool_t)",
74 "Reve::CascadeListEditor", this, "DoRnrCasPath()");
75
76 fRnrV0Daughters = new TGCheckButton(this, "Render v0 daughter tracks");
77 AddFrame(fRnrV0Daughters, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
78 fRnrV0Daughters->Connect("Toggled(Bool_t)",
79 "Reve::CascadeListEditor", this, "DoRnrV0Daughters()");
80
81 fRnrBach = new TGCheckButton(this, "Render bachelor track");
82 AddFrame(fRnrBach, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
83 fRnrBach->Connect("Toggled(Bool_t)",
84 "Reve::CascadeListEditor", this, "DoRnrBach()");
85
86 for (Int_t i=0; i<fgkNRange; i++) fRange[i]=0;
87 for (Int_t i=0; i<fgkNCanvas; i++) fCanvasA[i]=0;
88 for (Int_t i=0; i<fgkNCanvas; i++) fCanvasB[i]=0;
89
90 AddSelectTab();
91 AddSeeTab();
92
93 TGTextButton* resetCutsButton = new TGTextButton(this, "Reset all cuts", 40);
94 resetCutsButton->Connect("Clicked()", "Reve::CascadeListEditor", this, "ResetCuts()");
95 AddFrame(resetCutsButton, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
96}
97
98CascadeListEditor::~CascadeListEditor()
99{}
100
101
102//_________________________________________________________________________
103void CascadeListEditor::SetModel(TObject* obj)
104{
105 fMList = dynamic_cast<CascadeList*>(obj);
106
107 for (Int_t i=0; i<fgkNRange; i++)
108 if (fRange[i])
109 fRange[i]->SetValues( fMList->GetMin(i), fMList->GetMax(i) );
110
111 fRnrV0Daughters->SetState(fMList->GetRnrV0Daughters() ? kButtonDown : kButtonUp);
112 fRnrV0path->SetState(fMList->GetRnrV0path() ? kButtonDown : kButtonUp);
113 fRnrVtx->SetState(fMList->GetRnrCasVtx() ? kButtonDown : kButtonUp);
114 fRnrBach->SetState(fMList->GetRnrBachelor() ? kButtonDown : kButtonUp);
115 fRnrCasPath->SetState(fMList->GetRnrCasPath() ? kButtonDown : kButtonUp);
116
117 FillCanvas();
118}
119
120
121//_________________________________________________________________________
122TGCompositeFrame* CascadeListEditor::AddTab(TGTab* tab, Int_t i, Int_t can,
123 char *name) {
124
125 TGCompositeFrame* frameTab = tab->AddTab(name);
126 frameTab->SetLayoutManager(new TGVerticalLayout( frameTab ));
127
128 TRootEmbeddedCanvas** embeddedCanvas = 0;
129
130 if (can==1) embeddedCanvas = &fCanvasA[i];
131 else if (can==2) embeddedCanvas = &fCanvasB[i];
132
133 *embeddedCanvas = new TRootEmbeddedCanvas("EmbeddedCanvas", frameTab, 200, 200);
134 TCanvas *c1 = (*embeddedCanvas)->GetCanvas();
135 c1->SetBorderMode(0);
136 c1->SetTicks(1,0);
137 c1->SetGrid();
138 c1->SetBorderMode(0);
139
140 frameTab->AddFrame(*embeddedCanvas, new TGLayoutHints(kLHintsTop|kLHintsExpandX,
141 0, 0, 0, 0));
142 return frameTab;
143}
144
145
146//_________________________________________________________________________
147TGCompositeFrame** CascadeListEditor::CreateTab(TGTab **pMainTab, TGTab **ptab, Int_t can) {
148
149 //------
150 // tab widget
151 pMainTab[0] = new TGTab(this,0,0);
152 pMainTab[0]->Connect("Selected(Int_t)", "Reve::CascadeListEditor", this, "UpdateSelectedTab()");
153 this->AddFrame(pMainTab[0], new TGLayoutHints( kLHintsTop | kLHintsExpandX,2,2,2,2));
154
155 //------
156 // container of "Tab1"
157 TGCompositeFrame *frameTab1 = pMainTab[0]->AddTab("ident.");
158 frameTab1->SetLayoutManager(new TGVerticalLayout(frameTab1));
159
160 // tab widget
161 ptab[0] = new TGTab(frameTab1,2,2);
162 ptab[0]->Resize(ptab[0]->GetDefaultSize());
163 // The following is for updating the canvas of a tab if this one is selected
164 // (it updates every canvas)
165 ptab[0]->Connect("Selected(Int_t)", "Reve::CascadeListEditor", this, "UpdateSelectedTab()");
166 frameTab1->AddFrame(ptab[0], new TGLayoutHints(kLHintsLeft| kLHintsExpandX,0,0,0,0));
167
168 //------
169 // container of "Tab2"
170 TGCompositeFrame *frameTab2 = pMainTab[0]->AddTab("cascade");
171 frameTab2->SetLayoutManager(new TGVerticalLayout(frameTab2));
172
173 // tab widget
174 ptab[1] = new TGTab(frameTab2,440,299);
175 ptab[1]->Resize(ptab[1]->GetDefaultSize());
176 ptab[1]->Connect("Selected(Int_t)", "Reve::CascadeListEditor", this, "UpdateSelectedTab()");
177 frameTab2->AddFrame(ptab[1], new TGLayoutHints(kLHintsLeft| kLHintsExpandX ,0,0,0,0));
178
179 //------
180 // container of "Tab3"
181 TGCompositeFrame *frameTab3 = pMainTab[0]->AddTab("V0daugh/bach.");
182 frameTab3->SetLayoutManager(new TGVerticalLayout(frameTab3));
183
184 // tab widget
185 ptab[2] = new TGTab(frameTab3,440,299);
186 ptab[2]->Resize(ptab[2]->GetDefaultSize());
187 ptab[2]->Connect("Selected(Int_t)", "Reve::CascadeListEditor", this, "UpdateSelectedTab()");
188 frameTab3->AddFrame(ptab[2], new TGLayoutHints(kLHintsLeft| kLHintsExpandX ,0,0,0,0));
189
190 //------
191 TGCompositeFrame **frameTab = new TGCompositeFrame*[fgkNCanvas];
192
193 frameTab[0] = AddTab(ptab[0], 0, can, "Xi");
194 frameTab[1] = AddTab(ptab[0], 1, can, "Omega");
195 frameTab[2] = AddTab(ptab[0], 2, can, "Arm.Podo.");
196 frameTab[3] = AddTab(ptab[0], 3, can, "Index");
197
198 frameTab[4] = AddTab(ptab[1], 4, can, "cosPointing");
199 frameTab[5] = AddTab(ptab[1], 5, can, "bachV0DCA");
200 frameTab[6] = AddTab(ptab[1], 6, can, "radius");
201 frameTab[7] = AddTab(ptab[1], 7, can, "Pt");
202 frameTab[8] = AddTab(ptab[1], 8, can, "eta");
203
204 frameTab[9] = AddTab(ptab[2], 9, can, "neg Pt");
205 frameTab[10] = AddTab(ptab[2], 10, can, "neg eta");
206 frameTab[11] = AddTab(ptab[2], 11, can, "pos Pt");
207 frameTab[12] = AddTab(ptab[2], 12, can, "pos eta");
208 frameTab[13] = AddTab(ptab[2], 13, can, "bach Pt");
209 frameTab[14] = AddTab(ptab[2], 14, can, "bach eta");
210
211 pMainTab[0]->SetTab(0);
212 ptab[0]->SetTab(0);
213 ptab[1]->SetTab(0);
214 ptab[2]->SetTab(0);
215
216 Pixel_t darkgrey;
217 gClient->GetColorByName("grey50", darkgrey);
218 ptab[0]->SetBackgroundColor(darkgrey);
219 ptab[1]->SetBackgroundColor(darkgrey);
220 ptab[2]->SetBackgroundColor(darkgrey);
221
222 return frameTab;
223}
224
225
226//_________________________________________________________________________
227void CascadeListEditor::AddValuator(TGCompositeFrame* frame, char *name,
228 Float_t min, Float_t max, Int_t pres,
229 char *func, Int_t iHist) {
230
231 TGCompositeFrame* downFrame = new TGCompositeFrame(frame,
232 60, 60, kHorizontalFrame);
233
234 // --- Selectors
235 fRange[iHist] = new RGDoubleValuator(downFrame, name, 200, 0);
236 fRange[iHist]->SetNELength(6);
237 fRange[iHist]->Build();
238 fRange[iHist]->GetSlider()->SetWidth(200);
239
240 fRange[iHist]->SetLimits(min, max, TGNumberFormat::kNESRealTwo);
241 if (pres==0)
242 fRange[iHist]->SetLimits(min, max, TGNumberFormat::kNESInteger);
243 else if (pres==3)
244 fRange[iHist]->SetLimits(min, max, TGNumberFormat::kNESRealThree);
245 else if (pres==4)
246 fRange[iHist]->SetLimits(min, max, TGNumberFormat::kNESRealFour);
247 else if (pres==5)
248 fRange[iHist]->SetLimits(min, max, TGNumberFormat::kNESReal);
249
250 fRange[iHist]->Connect("ValueSet()",
251 "Reve::CascadeListEditor", this, func);
252 downFrame->AddFrame(fRange[iHist], new TGLayoutHints(kLHintsLeft,
253 0, 0, 0, 0));
254
255 TGTextButton* adjustButton = new TGTextButton(downFrame, "Adjust Hist", 40);
256
257 char ch[40];
258 sprintf(ch,"AdjustHist(=%i)",iHist);
259 adjustButton->Connect("Clicked()", "Reve::CascadeListEditor", this, ch);
260 downFrame->AddFrame(adjustButton, new TGLayoutHints(kLHintsTop, 0, 0, 0, 0));
261
262 frame->AddFrame(downFrame, new TGLayoutHints(kLHintsTop| kLHintsExpandY,
263 0, 0, 0, 0));
264}
265
266
267//_________________________________________________________________________
268void CascadeListEditor::AddSelectTab() {
269
270 TGCompositeFrame** tab = CreateTab(&fMainTabA, fTabA, 1);
271
272 AddValuator(tab[0], "mass Xi", 0, 5, 3, "MassXiRange()", 0);
273 AddValuator(tab[1], "mass Omega", 0, 5, 3, "MassOmegaRange()", 1);
274
275 AddValuator(tab[3], "Index", 0, 1e5, 0, "IndexRange()", 2);
276 AddValuator(tab[4], "cos pointing angle", 0.8, 1, 5, "CosPointingRange()", 3);
277 AddValuator(tab[5], "bach-V0 DCA", 0, 5, 3, "BachV0DCARange()", 4);
278 AddValuator(tab[6], "radius", 0, 100, 2, "RadiusRange()", 5);
279 AddValuator(tab[7], "Pt", 0, 10, 2, "PtRange()", 6);
280 AddValuator(tab[8], "Pseudo-rapidity", -2, 2, 2, "PseudoRapRange()", 7);
281
282 AddValuator(tab[9], "neg Pt", 0, 10, 2, "NegPtRange()", 8);
283 AddValuator(tab[10], "neg pseudo-rapidity", -2, 2, 2, "NegEtaRange()", 9);
284 AddValuator(tab[11], "pos Pt", 0, 10, 2, "PosPtRange()", 10);
285 AddValuator(tab[12], "pos pseudo-rapidity", -2, 2, 2, "PosEtaRange()", 11);
286 AddValuator(tab[13], "bach. Pt", 0, 10, 2, "BachPtRange()", 12);
287 AddValuator(tab[14], "bach. pseudo-rapidity", -2, 2, 2, "BachEtaRange()", 13);
288
289 delete[] tab;
290}
291
292
293//_________________________________________________________________________
294void CascadeListEditor::AddSeeTab() {
295
296 TGCompositeFrame** tab = CreateTab(&fMainTabB, fTabB, 2);
297 delete[] tab;
298}
299
300
301//_________________________________________________________________________
302void CascadeListEditor::AdjustHist(Int_t iHist) {
303
304 if (! fMList) return;
305 fMList->AdjustHist(iHist);
306
307 FillCanvas();
308}
309
310//_________________________________________________________________________
311void CascadeListEditor::ResetCuts() {
312
313 if (! fMList) return;
314
315 Float_t min,max;
316
317 for (Int_t i=0; i<fgkNRange;i++) {
318
319 if (i==2) continue;
320 min = fRange[i]->GetLimitMin();
321 max = fRange[i]->GetLimitMax();
322 fMList->SetMin(i, min);
323 fMList->SetMax(i, max);
324 fRange[i]->SetValues(min, max);
325 fMList->AdjustHist(i);
326 }
327
328 // for the Index we scan its actual range
329 Int_t imin, imax;
330 fMList->GetCasIndexRange(imin, imax);
331 if (imin<imax) {
332 Int_t minH = imin-(imax-imin)/20;
333 Int_t maxH = imax+(imax-imin)/20;
334 fMList->SetMin(2, minH);
335 fMList->SetMax(2, maxH);
336 fRange[2]->SetLimits(minH, maxH, TGNumberFormat::kNESInteger);
337 fRange[2]->SetValues(minH, maxH);
338 fMList->AdjustHist(2);
339
340 }
341 FillCanvas();
342 Update();
343}
344
345
346//_________________________________________________________________________
347void CascadeListEditor::FillCanvas() {
348
349 fMList->FilterAll();
350
351 TCanvas *c1, *c1b;
352 TH1F *hist = 0;
353 TH2F *hist2D = 0;
354 Bool_t is2D;
355
356 Int_t canvasMap[fgkNCanvas]={0,1,1000,2,3,4,5,6,7,8,9,10,11,12,13};
357
358 for (Int_t i=0; i<fgkNCanvas; i++)
359 if (fCanvasA[i]) {
360
361 is2D = canvasMap[i]>999;
362
363 if (is2D) hist2D = fMList->GetHist2D(canvasMap[i]-1000);
364 else hist = fMList->GetHist(canvasMap[i]);
365
366 c1 = fCanvasA[i]->GetCanvas();
367 c1->cd();
368 if (is2D) hist2D->Draw("colz"); else hist->Draw();
369 c1->Modified();
370 c1->Update();
371
372 c1b = fCanvasB[i]->GetCanvas();
373 c1b->cd();
374 if (is2D) hist2D->Draw("colz"); else hist->Draw();
375 c1b->Modified();
376 c1b->Update();
377 }
378 UpdateSelectedTab();
379}
380//_________________________________________________________________________
381void CascadeListEditor::UpdateSelectedTab() {
382
5ba491d8 383 Int_t i,j;
9b7b1a97 384 Pixel_t yellow;
385 Pixel_t grey;
386 gClient->GetColorByName("yellow", yellow);
387 gClient->GetColorByName("grey", grey);
388
389 TGTabElement *tabElem;
5ba491d8 390 for (i=0; i<fMainTabA->GetNumberOfTabs(); i++) {
9b7b1a97 391
392 tabElem = fMainTabA->GetTabTab(i);
393 tabElem->ChangeBackground(grey);
394
5ba491d8 395 for (j=0; j<fTabA[i]->GetNumberOfTabs();j++) {
9b7b1a97 396 tabElem = fTabA[i]->GetTabTab(j);
397 tabElem->ChangeBackground(grey);
398 }
399 }
400
401 Int_t currentTab = fMainTabA->GetCurrent();
402 Int_t currentSubTab = fTabA[currentTab]->GetCurrent();
403 tabElem = fMainTabA->GetTabTab(currentTab);
404 tabElem->ChangeBackground(yellow);
405 tabElem = fTabA[currentTab]->GetTabTab(currentSubTab);
406 tabElem->ChangeBackground(yellow);
407
408 TCanvas *c1;
409 Int_t iCan = 0;
5ba491d8 410 i=0;
9b7b1a97 411
412 while (currentTab>i) {
413 iCan += fTabA[i]->GetNumberOfTabs();
414 i++;
415 }
416 iCan += currentSubTab;
417 c1 = fCanvasA[iCan]->GetCanvas();
418 c1->GetCanvas()->Modified();
419 c1->GetCanvas()->Update();
420
421 //---
422
5ba491d8 423 for (i=0; i<fMainTabB->GetNumberOfTabs(); i++) {
9b7b1a97 424
425 tabElem = fMainTabB->GetTabTab(i);
426 tabElem->ChangeBackground(grey);
427
5ba491d8 428 for (j=0; j<fTabB[i]->GetNumberOfTabs();j++) {
9b7b1a97 429 tabElem = fTabB[i]->GetTabTab(j);
430 tabElem->ChangeBackground(grey);
431 }
432 }
433
434 currentTab = fMainTabB->GetCurrent();
435 currentSubTab = fTabB[currentTab]->GetCurrent();
436 tabElem = fMainTabB->GetTabTab(currentTab);
437 tabElem->ChangeBackground(yellow);
438 tabElem = fTabB[currentTab]->GetTabTab(currentSubTab);
439 tabElem->ChangeBackground(yellow);
440
441 iCan = 0;
442 i=0;
443
444 while (currentTab>i) {
445 iCan += fTabB[i]->GetNumberOfTabs();
446 i++;
447 }
448 iCan += currentSubTab;
449 c1 = fCanvasB[iCan]->GetCanvas();
450 c1->GetCanvas()->Modified();
451 c1->GetCanvas()->Update();
452}
453
454
455//_________________________________________________________________________
456void CascadeListEditor::UpdateAll(Int_t iCanA) {
457
458 TCanvas *c1 = fCanvasA[iCanA]->GetCanvas();
459 c1->Modified();
460 c1->Update();
461
462 static Int_t iCan, i;
463 iCan=0;
464 i=0;
465 while (fMainTabB->GetCurrent()>i) {
466 iCan += fTabB[i]->GetNumberOfTabs();
467 i++;
468 }
469 iCan += fTabB[i]->GetCurrent();
470 c1 = fCanvasB[iCan]->GetCanvas();
471 c1->GetCanvas()->Modified();
472 c1->GetCanvas()->Update();
473
474 Update();
475}
476
477
478//_________________________________________________________________________
479
480void CascadeListEditor::DoRnrVtx()
481{
482 fMList->SetRnrCasVtx(fRnrVtx->IsOn());
483 Update();
484}
485
486void CascadeListEditor::DoRnrV0path()
487{
488 fMList->SetRnrV0path(fRnrV0path->IsOn());
489 Update();
490}
491
492void CascadeListEditor::DoRnrV0Daughters()
493{
494 fMList->SetRnrV0Daughters(fRnrV0Daughters->IsOn());
495 Update();
496}
497
498void CascadeListEditor::DoRnrBach()
499{
500 fMList->SetRnrBachelor(fRnrBach->IsOn());
501 Update();
502}
503
504void CascadeListEditor::DoRnrCasPath()
505{
506 fMList->SetRnrCasPath(fRnrCasPath->IsOn());
507 Update();
508}
509
510
511//_________________________________________________________________________
512void CascadeListEditor::MassXiRange() {
513
514 fMList->XiMassFilter(fRange[0]->GetMin(), fRange[0]->GetMax());
515 UpdateAll(0);
516}
517
518//_________________________________________________________________________
519 void CascadeListEditor::MassOmegaRange() {
520 fMList->OmegaMassFilter(fRange[1]->GetMin(), fRange[1]->GetMax());
521 UpdateAll(1);
522}
523
524//_________________________________________________________________________
525 void CascadeListEditor::IndexRange() {
526 fMList->IndexFilter(fRange[2]->GetMin(), fRange[2]->GetMax());
527 UpdateAll(3);
528}
529//_________________________________________________________________________
530 void CascadeListEditor::CosPointingRange() {
531 fMList->CosPointingFilter(fRange[3]->GetMin(), fRange[3]->GetMax());
532 UpdateAll(4);
533}
534
535//_________________________________________________________________________
536 void CascadeListEditor::BachV0DCARange() {
537 fMList->BachV0DCAFilter(fRange[4]->GetMin(), fRange[4]->GetMax());
538 UpdateAll(5);
539}
540
541//_________________________________________________________________________
542 void CascadeListEditor::RadiusRange() {
543 fMList->RadiusFilter(fRange[5]->GetMin(), fRange[5]->GetMax());
544 UpdateAll(6);
545}
546
547//_________________________________________________________________________
548 void CascadeListEditor::PtRange() {
549 fMList->PtFilter(fRange[6]->GetMin(), fRange[6]->GetMax());
550 UpdateAll(7);
551}
552
553//_________________________________________________________________________
554 void CascadeListEditor::PseudoRapRange() {
555 fMList->PseudoRapFilter(fRange[7]->GetMin(), fRange[7]->GetMax());
556 UpdateAll(8);
557}
558
559//_________________________________________________________________________
560 void CascadeListEditor::NegPtRange() {
561 fMList->NegPtFilter(fRange[8]->GetMin(), fRange[8]->GetMax());
562 UpdateAll(9);
563}
564
565//_________________________________________________________________________
566 void CascadeListEditor::NegEtaRange() {
567 fMList->NegEtaFilter(fRange[9]->GetMin(), fRange[9]->GetMax());
568 UpdateAll(10);
569}
570
571//_________________________________________________________________________
572 void CascadeListEditor::PosPtRange() {
573 fMList->PosPtFilter(fRange[10]->GetMin(), fRange[10]->GetMax());
574 UpdateAll(11);
575}
576
577//_________________________________________________________________________
578 void CascadeListEditor::PosEtaRange() {
579 fMList->PosEtaFilter(fRange[11]->GetMin(), fRange[11]->GetMax());
580 UpdateAll(12);
581}
582
583//_________________________________________________________________________
584 void CascadeListEditor::BachPtRange() {
585 fMList->BachPtFilter(fRange[12]->GetMin(), fRange[12]->GetMax());
586 UpdateAll(13);
587}
588
589//_________________________________________________________________________
590 void CascadeListEditor::BachEtaRange() {
591 fMList->BachEtaFilter(fRange[13]->GetMin(), fRange[13]->GetMax());
592 UpdateAll(14);
593}
594
595