// @(#)root/ged:$Id$ // Author: Carsten Hof 09/08/04 // Authors mail: Carsten_Hof@web.de /************************************************************************* * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ ////////////////////////////////////////////////////////////////////////// // // // TH2Editor // // Editor for changing TH2 histogram attributes, rebinning & fitting. // // For all possible draw options (there are a few which are not imple- // // mentable in a graphical user interface) see THistPainter::Paint in // // root/histpainter/THistPainter.cxx // // //Begin_Html /* */ //End_Html //Begin_Html /* */ //End_Html // These changes can be made via the TH2Editor: // // Style Tab: // // 'Line' : change Line attributes (color, thickness) // // see TAttLineEditor // // 'Fill' : change Fill attributes (color, pattern) // // see TAttFillEditor // // 'Title' : TextEntry: set the title of the histogram // // 'Histogram': change the draw options of the histogram // // 'Plot' : Radiobutton: draw a 2D or 3D plot of the histogram // // according to the Plot dimension there will be // // different drawing possibilities (ComboBoxes/ // // CheckBoxes) // // 2d Plot: // // 'Contour' : ComboBox: draw a contour plot (None, Cont0..4) // // 'Cont #' : TGNumberEntry: set the number of Contours // // 2d Plot checkboxes: // // 'Arrow' : arrow mode. Shows gradient between adjacent cells // // 'Col' : a box is drawn for each cell with a color scale // // varying with contents // // 'Text' : Draw bin contents as text // // 'Box' : a box is drawn for each cell with surface // // proportional to contents // // 'Scat' : Draw a scatter-plot (default) // // 'Palette' : the color palette is drawn // // // // 3d Plot: // // 'Type' : ComboBox: set histogram type Lego or Surface-Plot // // draw(Lego, Lego1..4, Surf, Surf1..5) // // see THistPainter::Paint // // 'Coords' : ComboBox: set the coordinate system (Cartesian, .. // // Spheric) see THistPainter::Paint // // 'Cont #' : TGNumberEntry: set the number of Contours (for e.g. // // Lego2 drawoption // // 3d Plot checkboxes: // // 'Errors' : draw errors in a cartesian lego plot // // 'Palette' : the color palette is drawn // // 'Front' : draw the front box of a cartesian lego plot // // 'Back' : draw the back box of a cartesian lego plot // // Available for a 3D lego plot: // // 'Bar' : change the bar attributes // // 'W' : change Bar Width // // 'O' : change Bar Offset // // Further Editor: // // 'Marker' : change the Marker attributes (color, appearance, // // thickness) see TAttMarkerEditor // // // //Begin_Html /* */ //End_Html //Begin_Html /* */ //End_Html // // // Rebinning Tab: // // This Tab has two different layouts. One is for a histogram which// // is not drawn from an ntuple. The other one is available for a // // histogram which is drawn from an ntuple. In this case the rebin // // algorithm can create a rebinned histogram from the original data// // i.e. the ntuple. // // To see te differences do for example: // // TFile f("hsimple.root"); // // hpxpy->Draw("Lego2"); // non ntuple histogram // // ntuple->Draw("px:py","","Lego2"); // ntuple histogram // // Non ntuple histogram: // // 'Rebin': with the Sliders (one for the x, one for the y axis) // // the number of bins (shown in the field below the // // Slider) can be changed to any number which divides // // the number of bins of the original histogram. // // Pushing 'Apply' will delete the origin histogram and // // replace it by the rebinned one on the screen. // // Pushing 'Ignore' the origin histogram will be restored// // Histogram drawn from an ntuple: // // 'Rebin' with the sliders the number of bins can be enlarged by// // a factor of 2,3,4,5 (moving to the right) or reduced // // by a factor of 1/2, 1/3, 1/4, 1/5 // // 'BinOffset': with the BinOffset slider the origin of the // // histogram can be changed within one binwidth // // Using this slider the effect of binning the data into // // bins can be made visible => statistical fluctuations // // 'Axis Range': with the DoubleSlider it is possible to zoom into// // the specified axis range. It is also possible to set // // the upper and lower limit in fields below the slider // // 'Delayed drawing': all the Binning sliders can be set to delay // // draw mode. Then the changes on the histogram are only // // updated, when the Slider is released. This should be // // activated if the redrawing of the histogram is too // // time consuming. // ////////////////////////////////////////////////////////////////////////// #include "TH2Editor.h" #include "TGedEditor.h" #include "TGComboBox.h" #include "TGTextEntry.h" #include "TGToolTip.h" #include "TGLabel.h" #include "TVirtualPad.h" #include "TStyle.h" #include "TString.h" #include "TGButtonGroup.h" #include "TGNumberEntry.h" #include "TG3DLine.h" #include "TGDoubleSlider.h" #include "TGSlider.h" #include "TView.h" #include "TCanvas.h" #include "TGedPatternSelect.h" #include "TGColorSelect.h" #include "TColor.h" #include "TTreePlayer.h" #include "TSelectorDraw.h" #include "TGTab.h" #include "TGMsgBox.h" #include "TH2.h" #include "TROOT.h" #include "TVirtualX.h" ClassImp(TH2Editor); enum ETH2Wid { kTH2_TITLE, kDIM_SIMPLE, kDIM_COMPLEX, kHIST_TYPE, kTYPE_LEGO, kTYPE_LEGO1, kTYPE_LEGO2, kTYPE_LEGO3, kTYPE_LEGO4, kTYPE_SURF, kTYPE_SURF1, kTYPE_SURF2, kTYPE_SURF3, kTYPE_SURF4, kTYPE_SURF5, kCOORD_TYPE, kCOORDS_CAR, kCOORDS_CYL, kCOORDS_POL, kCOORDS_PSR, kCOORDS_SPH, kCONT_TYPE, kERROR_ONOFF, kPALETTE_ONOFF, kPALETTE_ONOFF1, kARROW_ONOFF,kBOX_ONOFF, kSCAT_ONOFF, kCOL_ONOFF, kTEXT_ONOFF, kFRONTBOX_ONOFF, kBACKBOX_ONOFF, kBAR_WIDTH, kBAR_OFFSET, kCONT_NONE, kCONT_0, kCONT_1, kCONT_2, kCONT_3, kCONT_4, kCONT_LEVELS, kCONT_LEVELS1, kSLIDERX_MIN, kSLIDERX_MAX, kSLIDERY_MIN, kSLIDERY_MAX, kDELAYED_DRAWING, kCOLOR, kPATTERN, kBINXSLIDER, kBINYSLIDER, kBINXSLIDER1, kBINYSLIDER1, kXBINOFFSET, kYBINOFFSET }; //////////////////////////////////////////////////////////////////////////////// /// Constructor of histogram attribute GUI. TH2Editor::TH2Editor(const TGWindow *p, Int_t width, Int_t height, UInt_t options, Pixel_t back) : TGedFrame(p, width, height, options | kVerticalFrame, back), fHist(0), fBin(0), fBinHist(0) { MakeTitle("Title"); // Histogram title fTitlePrec = 2; fTitle = new TGTextEntry(this, new TGTextBuffer(50), kTH2_TITLE); fTitle->Resize(135, fTitle->GetDefaultHeight()); fTitle->SetToolTipText("Enter the histogram title string"); AddFrame(fTitle, new TGLayoutHints(kLHintsLeft, 3, 1, 2, 5)); // 2D or 3D Plot? TGCompositeFrame *f2 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame); fDimGroup = new TGHButtonGroup(f2,"Plot"); fDim = new TGRadioButton(fDimGroup,"2-D",kDIM_SIMPLE); fDim->SetToolTipText("A 2-d plot of the histogram is dawn"); fDim0 = new TGRadioButton(fDimGroup,"3-D",kDIM_COMPLEX); fDim0->SetToolTipText("A 3-d plot of the histogram is dawn"); fDimGroup->SetLayoutHints(fDimlh=new TGLayoutHints(kLHintsLeft ,-2,3,3,-7),fDim); fDimGroup->SetLayoutHints(fDim0lh=new TGLayoutHints(kLHintsLeft ,16,-1,3,-7),fDim0); fDimGroup->Show(); fDimGroup->ChangeOptions(kFitWidth|kChildFrame|kHorizontalFrame); f2->AddFrame(fDimGroup, new TGLayoutHints(kLHintsTop, 4, 1, 0, 0)); AddFrame(f2, new TGLayoutHints(kLHintsTop, 1, 1, 2, 5)); // 2D Plot drawoptions f6 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame); AddFrame(f6, new TGLayoutHints(kLHintsTop, 3, 1, 4, 2)); TGCompositeFrame *f7 = new TGCompositeFrame(f6, 40, 20); f6->AddFrame(f7, new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); TGLabel *fAddLabel = new TGLabel(f7, "Contour:"); f7->AddFrame(fAddLabel, new TGLayoutHints(kLHintsLeft, 6, 4, 4, 4)); fColContLbl = new TGLabel(f7, "Cont #:"); f7->AddFrame(fColContLbl, new TGLayoutHints( kLHintsLeft, 6, 4, 4, 4)); fAddArr = new TGCheckButton(f7, "Arrow", kARROW_ONOFF); fAddArr ->SetToolTipText("Shows gradient between adjacent cells"); f7->AddFrame(fAddArr, new TGLayoutHints(kLHintsLeft, 6, 1, 2, 0)); fAddCol = new TGCheckButton(f7, "Col", kCOL_ONOFF); fAddCol ->SetToolTipText("A box is drawn for each cell with a color scale varying with contents"); f7->AddFrame(fAddCol, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 0)); fAddText = new TGCheckButton(f7, "Text", kTEXT_ONOFF); fAddText ->SetToolTipText("Draw bin contents as text"); f7->AddFrame(fAddText, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 3)); TGCompositeFrame *f8 = new TGCompositeFrame(f6, 40, 20, kVerticalFrame); f6->AddFrame(f8, new TGLayoutHints(kLHintsLeft, 5, 1, 0, 0)); fContCombo = BuildHistContComboBox(f8, kCONT_TYPE); f8->AddFrame(fContCombo, new TGLayoutHints(kLHintsLeft, 6, 1, 2, 1)); fContCombo->Resize(61, 20); fContCombo->Associate(this); fContLevels = new TGNumberEntry(f8, 20, 0, kCONT_LEVELS, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 1, 99); f8->AddFrame(fContLevels, new TGLayoutHints(kLHintsLeft, 6, 1, 3, 1)); fContLevels->GetNumberEntry()->SetToolTipText("Set number of contours (1..99)"); fContLevels->Resize(60,20); fAddBox = new TGCheckButton(f8, "Box", kBOX_ONOFF); fAddBox ->SetToolTipText("A box is drawn for each cell with surface proportional to contents"); f8->AddFrame(fAddBox, new TGLayoutHints(kLHintsLeft, 6, 1, 3, 0)); fAddScat = new TGCheckButton(f8, "Scat", kSCAT_ONOFF); fAddScat ->SetToolTipText("Draw a scatter-plot"); f8->AddFrame(fAddScat, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 0)); fAddPalette = new TGCheckButton(f8, "Palette", kPALETTE_ONOFF); fAddPalette ->SetToolTipText("Add color palette beside the histogram"); f8->AddFrame(fAddPalette, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 0)); f9 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame); AddFrame(f9, new TGLayoutHints(kLHintsTop, 3, 1, 2, 0)); TGCompositeFrame *f10 = new TGCompositeFrame(f9, 40, 20); f9->AddFrame(f10, new TGLayoutHints(kLHintsLeft, 0, 0, 3, 0)); TGLabel *fType = new TGLabel(f10, "Type:"); f10->AddFrame(fType, new TGLayoutHints(kLHintsNormal, 1, 1, 1, 1)); TGLabel *fCoords = new TGLabel(f10, "Coords:"); f10->AddFrame(fCoords, new TGLayoutHints(kLHintsLeft, 1, 1, 5, 1)); fColContLbl1 = new TGLabel(f10, "Cont #:"); f10->AddFrame(fColContLbl1, new TGLayoutHints( kLHintsLeft, 1, 1, 5, 3)); fAddFB = new TGCheckButton(f10, "Front", kFRONTBOX_ONOFF); fAddFB ->SetToolTipText("Supress the drawing of the front box"); f10->AddFrame(fAddFB, new TGLayoutHints(kLHintsLeft, 0, 1, 6, 0)); fAddBB = new TGCheckButton(f10, "Back", kBACKBOX_ONOFF); fAddBB ->SetToolTipText("Supress the drawing of the back box"); f10->AddFrame(fAddBB, new TGLayoutHints(kLHintsLeft, 0, 1, 3, 0)); TGCompositeFrame *f11 = new TGCompositeFrame(f9, 40, 20); f9->AddFrame(f11, new TGLayoutHints(kLHintsLeft, 5, 1, 0, 0)); fTypeCombo = BuildHistTypeComboBox(f11, kHIST_TYPE); f11->AddFrame(fTypeCombo, new TGLayoutHints(kLHintsLeft, 0, 1, 2, 1)); fTypeCombo->Resize(80, 20); fTypeCombo->Associate(this); fCoordsCombo = BuildHistCoordsComboBox(f11, kCOORD_TYPE); f11->AddFrame(fCoordsCombo, new TGLayoutHints(kLHintsLeft, 0, 1, 2, 1)); fCoordsCombo->Resize(80, 20); fCoordsCombo->Associate(this); fContLevels1 = new TGNumberEntry(f11, 20, 0, kCONT_LEVELS1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 1, 99); fContLevels1->GetNumberEntry()->SetToolTipText("Set number of contours (1..99)"); fContLevels1->Resize(78,20); f11->AddFrame(fContLevels1, new TGLayoutHints(kLHintsLeft, 0, 1, 2, 1)); fAddError = new TGCheckButton(f11, "Errors", kERROR_ONOFF); fAddError ->SetToolTipText("Add color palette beside the histogram"); f11->AddFrame(fAddError, new TGLayoutHints(kLHintsLeft, 0, 1, 4, 0)); fAddPalette1 = new TGCheckButton(f11, "Palette", kPALETTE_ONOFF1); fAddPalette1 ->SetToolTipText("Add color palette beside the histogram"); f11->AddFrame(fAddPalette1, new TGLayoutHints(kLHintsLeft, 0, 1, 3, 0)); // Bin bar settings f12 = new TGCompositeFrame(this, 145, 10, kHorizontalFrame | kLHintsExpandX | kFixedWidth | kOwnBackground); f12->AddFrame(new TGLabel(f12,"Bar"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); f12->AddFrame(new TGHorizontal3DLine(f12), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); AddFrame(f12, new TGLayoutHints(kLHintsTop,0,0,6,4)); f13 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame); TGLabel *fWidthLbl = new TGLabel(f13, "W:"); f13->AddFrame(fWidthLbl, new TGLayoutHints( kLHintsLeft, 1, 3, 4, 1)); fBarWidth = new TGNumberEntry(f13, 1.00, 6, kBAR_WIDTH, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0.01, 1.); fBarWidth->GetNumberEntry()->SetToolTipText("Set bar chart width"); fBarWidth->Resize(45,20); f13->AddFrame(fBarWidth, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 1)); TGLabel *fOffsetLbl = new TGLabel(f13, "O:"); f13->AddFrame(fOffsetLbl, new TGLayoutHints(kLHintsLeft, 6,3, 4, 1)); fBarOffset = new TGNumberEntry(f13, 0.00, 5, kBAR_OFFSET, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -1., 1.); fBarOffset->GetNumberEntry()->SetToolTipText("Set bar chart offset"); fBarOffset->Resize(50,20); f13->AddFrame(fBarOffset, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 1)); AddFrame(f13, new TGLayoutHints(kLHintsTop, 1, 1, 0, 4)); // Set the color and pattern of the Frame (only for Cartesian 3D plot). f38 = new TGCompositeFrame(this, 80, 20, kVerticalFrame); TGCompositeFrame *f39 = new TGCompositeFrame(f38, 145, 10, kHorizontalFrame | kLHintsExpandX | kFixedWidth | kOwnBackground); f39->AddFrame(new TGLabel(f39,"Frame Fill"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); f39->AddFrame(new TGHorizontal3DLine(f39), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); f38->AddFrame(f39, new TGLayoutHints(kLHintsTop,0,0,6,1)); TGCompositeFrame *f21 = new TGCompositeFrame(f38, 80, 20, kHorizontalFrame); fFrameColor = new TGColorSelect(f21, 0, kCOLOR); f21->AddFrame(fFrameColor, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 0)); fFrameColor->Associate(f38); fFramePattern = new TGedPatternSelect(f21, 1, kPATTERN); f21->AddFrame(fFramePattern, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 0)); fFramePattern->Associate(f38); f38->AddFrame(f21, new TGLayoutHints(kLHintsTop, 1, 1, 0, 0)); AddFrame(f38, new TGLayoutHints(kLHintsTop)); fCutString = ""; CreateBinTab(); // add itself in the least of cleanups to be notified when attached histogram is deleted gROOT->GetListOfCleanups()->Add(this); } //////////////////////////////////////////////////////////////////////////////// /// Create the Binning tab. void TH2Editor::CreateBinTab() { fBin = CreateEditorTabSubFrame("Binning"); // Editor for rebinning a histogram which does NOT derive from an Ntuple fBinXCont = new TGCompositeFrame(fBin, 80, 20, kVerticalFrame); TGCompositeFrame *title1 = new TGCompositeFrame(fBinXCont, 145, 10, kHorizontalFrame | kLHintsExpandX | kFixedWidth | kOwnBackground); title1->AddFrame(new TGLabel(title1, "Rebin"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); title1->AddFrame(new TGHorizontal3DLine(title1), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); fBinXCont->AddFrame(title1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); TGCompositeFrame *f22 = new TGCompositeFrame(fBinXCont, 80, 20, kHorizontalFrame); TGLabel *binSliderXLbl = new TGLabel(f22,"x:"); f22->AddFrame(binSliderXLbl, new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 4,0, 4, 1)); fBinXSlider = new TGHSlider(f22, 100, kSlider1 | kScaleBoth); fBinXSlider->Resize(107,20); f22->AddFrame(fBinXSlider, new TGLayoutHints(kLHintsLeft, 2,0,0,3)); fBinXCont->AddFrame(f22, new TGLayoutHints(kLHintsTop, 3, 7, 3, 5)); TGCompositeFrame *f23 = new TGCompositeFrame(fBinXCont, 80, 20, kHorizontalFrame); TGLabel *binXLabel1 = new TGLabel(f23, "# of Bins:"); f23->AddFrame(binXLabel1, new TGLayoutHints(kLHintsLeft, 20, 1, 2, 1)); fBinXNumberEntry = new TGNumberEntryField(f23, kBINXSLIDER, 0.0, TGNumberFormat::kNESInteger); ((TGTextEntry*)fBinXNumberEntry)->SetToolTipText("Set the number of x axis bins in the rebinned histogram"); fBinXNumberEntry->Resize(57,20); f23->AddFrame(fBinXNumberEntry, new TGLayoutHints(kLHintsRight, 8, 0, 0, 0)); fBinXCont->AddFrame(f23, new TGLayoutHints(kLHintsTop, 0, 7, 3, 4)); TGCompositeFrame *f37 = new TGCompositeFrame(fBinXCont, 80, 20, kHorizontalFrame); TGLabel *binSliderYLbl = new TGLabel(f37,"y:"); f37->AddFrame(binSliderYLbl, new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 4,0, 4, 1)); fBinYSlider = new TGHSlider(f37, 100, kSlider1 | kScaleBoth); fBinYSlider->Resize(107,20); f37->AddFrame(fBinYSlider, new TGLayoutHints(kLHintsLeft, 1,0,0,3)); fBinXCont->AddFrame(f37, new TGLayoutHints(kLHintsTop, 3, 7, 3, 5)); TGCompositeFrame *f36 = new TGCompositeFrame(fBinXCont, 80, 20, kHorizontalFrame); TGLabel *binYLabel1 = new TGLabel(f36, "# of Bins:"); f36->AddFrame(binYLabel1, new TGLayoutHints(kLHintsLeft, 20, 1, 2, 1)); fBinYNumberEntry = new TGNumberEntryField(f36, kBINYSLIDER, 0.0, TGNumberFormat::kNESInteger); ((TGTextEntry*)fBinYNumberEntry)->SetToolTipText("Set the number of y axis bins in the rebinned histogram"); fBinYNumberEntry->Resize(57,20); f36->AddFrame(fBinYNumberEntry, new TGLayoutHints(kLHintsRight, 8, 0, 0, 0)); fBinXCont->AddFrame(f36, new TGLayoutHints(kLHintsTop, 0, 7, 3, 4)); // Text buttons Apply & Ignore for rebinned histogram shown on the screen. TGCompositeFrame *f24 = new TGCompositeFrame(fBinXCont, 118, 20, kHorizontalFrame | kFixedWidth); fApply = new TGTextButton(f24, " &Apply "); f24->AddFrame(fApply, new TGLayoutHints(kLHintsExpandX | kLHintsLeft ,0, 3, 4, 4)); fCancel = new TGTextButton(f24, " &Ignore "); f24->AddFrame(fCancel, new TGLayoutHints(kLHintsExpandX | kLHintsLeft, 3, 0, 4, 4)); fBinXCont->AddFrame(f24, new TGLayoutHints(kLHintsTop, 20, 3, 3, 4)); fBin->AddFrame(fBinXCont,new TGLayoutHints(kLHintsTop)); // Widgets for rebinning a histogram which derives from an Ntuple fBinXCont1 = new TGCompositeFrame(fBin, 80, 20, kVerticalFrame); TGCompositeFrame *title2 = new TGCompositeFrame(fBinXCont1, 145, 10, kHorizontalFrame | kLHintsExpandX | kFixedWidth | kOwnBackground); title2->AddFrame(new TGLabel(title2, "X-Axis"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); title2->AddFrame(new TGHorizontal3DLine(title2), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); fBinXCont1->AddFrame(title2, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); TGCompositeFrame *f26 = new TGCompositeFrame(fBinXCont1, 80, 20, kHorizontalFrame); fBinXSlider1 = new TGHSlider(f26, 100, kSlider1 | kScaleBoth); fBinXSlider1->Resize(120,20); fBinXSlider1->SetRange(1,9); fBinXSlider1->SetScale(14); fBinXSlider1->SetPosition(5); f26->AddFrame(fBinXSlider1, new TGLayoutHints(kLHintsLeft, 2,0,0,0)); fBinXCont1->AddFrame(f26, new TGLayoutHints(kLHintsTop, 3, 7, 3, 0)); // Lettering of the Rebin Slider TGCompositeFrame *f27 = new TGCompositeFrame(fBinXCont1, 80, 20, kHorizontalFrame); TGLabel *l1 = new TGLabel(f27, "-5"); f27->AddFrame(l1, new TGLayoutHints(kLHintsLeft, 5, 1, -1, 0)); TGLabel *l2 = new TGLabel(f27, "-2"); f27->AddFrame(l2, new TGLayoutHints(kLHintsLeft, 31, 2, -1, 0)); TGLabel *l3 = new TGLabel(f27, "2"); f27->AddFrame(l3, new TGLayoutHints(kLHintsLeft, 21, 2, -1, 0)); TGLabel *l4 = new TGLabel(f27, "5"); f27->AddFrame(l4, new TGLayoutHints(kLHintsLeft, 36, 3, -1, 0)); fBinXCont1->AddFrame(f27, new TGLayoutHints(kLHintsTop, 0, 0, 0, 0)); TGCompositeFrame *f28 = new TGCompositeFrame(fBinXCont1, 140, 20, kHorizontalFrame); TGLabel *binXLabel2 = new TGLabel(f28, "# of Bins:"); f28->AddFrame(binXLabel2, new TGLayoutHints(kLHintsLeft, 8, 1, 4, 1)); fBinXNumberEntry1 = new TGNumberEntryField(f28, kBINXSLIDER1, 0.0, TGNumberFormat::kNESInteger); ((TGTextEntry*)fBinXNumberEntry1)->SetToolTipText("Set the number of x axis bins in the rebinned histogram"); fBinXNumberEntry1->Resize(57,20); f28->AddFrame(fBinXNumberEntry1, new TGLayoutHints(kLHintsLeft, 21, 0, 2, 0)); fBinXCont1->AddFrame(f28, new TGLayoutHints(kLHintsTop, 0, 7, 2, 4)); TGCompositeFrame *f29 = new TGCompositeFrame(fBinXCont1, 80, 20, kHorizontalFrame); TGLabel *xOffsetLbl = new TGLabel(f29, "BinOffset:"); f29->AddFrame(xOffsetLbl, new TGLayoutHints(kLHintsLeft, 7, 1, 2, 1)); fXOffsetNumberEntry = new TGNumberEntryField(f29, kXBINOFFSET, 0.0, TGNumberFormat::kNESRealFour, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, 0., 1.); ((TGTextEntry*)fXOffsetNumberEntry)->SetToolTipText("Add an x-offset to the origin of the histogram"); fXOffsetNumberEntry->Resize(57,20); f29->AddFrame(fXOffsetNumberEntry, new TGLayoutHints(kLHintsRight, 21, 0, 0, 0)); fBinXCont1->AddFrame(f29, new TGLayoutHints(kLHintsTop, 0, 7, 3, 1)); TGCompositeFrame *f30 = new TGCompositeFrame(fBinXCont1, 80, 20, kHorizontalFrame); fXBinOffsetSld = new TGHSlider(f30, 100, kSlider1 | kScaleBoth); fXBinOffsetSld->Resize(120,20); f30->AddFrame(fXBinOffsetSld, new TGLayoutHints(kLHintsLeft, 2,0,0,0)); fBinXCont1->AddFrame(f30, new TGLayoutHints(kLHintsTop, 3, 7, 3, 3)); fBin->AddFrame(fBinXCont1, new TGLayoutHints(kLHintsTop)); // Same for Y-Axis: // Widgets for rebinning a histogram which derives from an Ntuple fBinYCont1 = new TGCompositeFrame(fBin, 80, 20, kVerticalFrame); TGCompositeFrame *title3 = new TGCompositeFrame(fBinYCont1, 145, 10, kHorizontalFrame | kLHintsExpandX | kFixedWidth | kOwnBackground); title3->AddFrame(new TGLabel(title3, "Y-Axis"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); title3->AddFrame(new TGHorizontal3DLine(title3), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); fBinYCont1->AddFrame(title3, new TGLayoutHints(kLHintsTop, 0, 0, 7, 0)); TGCompositeFrame *f31 = new TGCompositeFrame(fBinYCont1, 80, 20, kHorizontalFrame); fBinYSlider1 = new TGHSlider(f31, 100, kSlider1 | kScaleBoth); fBinYSlider1->Resize(120,20); fBinYSlider1->SetRange(1,9); fBinYSlider1->SetScale(14); fBinYSlider1->SetPosition(5); f31->AddFrame(fBinYSlider1, new TGLayoutHints(kLHintsLeft, 2,0,0,0)); fBinYCont1->AddFrame(f31, new TGLayoutHints(kLHintsTop, 3, 7, 3, 0)); // Lettering of the Rebin Slider TGCompositeFrame *f32 = new TGCompositeFrame(fBinYCont1, 80, 20, kHorizontalFrame); TGLabel *l5 = new TGLabel(f32, "-5"); f32->AddFrame(l5, new TGLayoutHints(kLHintsLeft, 5, 1, -1, 0)); TGLabel *l6 = new TGLabel(f32, "-2"); f32->AddFrame(l6, new TGLayoutHints(kLHintsLeft, 31, 2, -1, 0)); TGLabel *l7 = new TGLabel(f32, "2"); f32->AddFrame(l7, new TGLayoutHints(kLHintsLeft, 21, 2, -1, 0)); TGLabel *l8 = new TGLabel(f32, "5"); f32->AddFrame(l8, new TGLayoutHints(kLHintsLeft, 36, 3, -1, 0)); fBinYCont1->AddFrame(f32, new TGLayoutHints(kLHintsTop, 0, 0, 0, 0)); TGCompositeFrame *f33 = new TGCompositeFrame(fBinYCont1, 140, 20, kHorizontalFrame); TGLabel *binYLabel2 = new TGLabel(f33, "# of Bins:"); f33->AddFrame(binYLabel2, new TGLayoutHints(kLHintsLeft, 8, 1, 4, 1)); fBinYNumberEntry1 = new TGNumberEntryField(f33, kBINYSLIDER1, 0.0, TGNumberFormat::kNESInteger); ((TGTextEntry*)fBinYNumberEntry1)->SetToolTipText("Set the number of Y axis bins in the rebinned histogram"); fBinYNumberEntry1->Resize(57,20); f33->AddFrame(fBinYNumberEntry1, new TGLayoutHints(kLHintsLeft, 21, 0, 2, 0)); fBinYCont1->AddFrame(f33, new TGLayoutHints(kLHintsTop, 0, 7, 2, 4)); TGCompositeFrame *f34 = new TGCompositeFrame(fBinYCont1, 80, 20, kHorizontalFrame); TGLabel *yOffsetLbl = new TGLabel(f34, "BinOffset:"); f34->AddFrame(yOffsetLbl, new TGLayoutHints(kLHintsLeft, 7, 1, 2, 1)); fYOffsetNumberEntry = new TGNumberEntryField(f34, kYBINOFFSET, 0.0, TGNumberFormat::kNESRealFour, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, 0., 1.); ((TGTextEntry*)fYOffsetNumberEntry)->SetToolTipText("Add an Y-offset to the origin of the histogram"); fYOffsetNumberEntry->Resize(57,20); f34->AddFrame(fYOffsetNumberEntry, new TGLayoutHints(kLHintsRight, 21, 0, 0, 0)); fBinYCont1->AddFrame(f34, new TGLayoutHints(kLHintsTop, 0, 7, 3, 1)); TGCompositeFrame *f35 = new TGCompositeFrame(fBinYCont1, 80, 20, kHorizontalFrame); fYBinOffsetSld = new TGHSlider(f35, 100, kSlider1 | kScaleBoth); fYBinOffsetSld->Resize(120,20); fYBinOffsetSld->Associate(f35); f35->AddFrame(fYBinOffsetSld, new TGLayoutHints(kLHintsLeft, 2,0,0,0)); fBinYCont1->AddFrame(f35, new TGLayoutHints(kLHintsTop, 3, 7, 3, 3)); fBin->AddFrame(fBinYCont1, new TGLayoutHints(kLHintsTop)); // Axis ranges TGCompositeFrame *title4 = new TGCompositeFrame(fBin, 145, 10, kHorizontalFrame | kLHintsExpandX | kFixedWidth | kOwnBackground); title4->AddFrame(new TGLabel(title4, "Axis Range"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); title4->AddFrame(new TGHorizontal3DLine(title4), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); fBin->AddFrame(title4, new TGLayoutHints(kLHintsTop, 0, 0, 5, 0)); TGCompositeFrame *f14 = new TGCompositeFrame(fBin, 80, 20, kHorizontalFrame); TGLabel *fSliderXLbl = new TGLabel(f14,"x:"); f14->AddFrame(fSliderXLbl, new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 4,3, 2, 1)); fSliderX = new TGDoubleHSlider(f14, 1, 2); fSliderX->Resize(119,20); f14->AddFrame(fSliderX, new TGLayoutHints(kLHintsLeft)); fBin->AddFrame(f14, new TGLayoutHints(kLHintsTop, 3, 7, 4, 1)); TGCompositeFrame *f17 = new TGCompositeFrame(fBin, 80, 20, kHorizontalFrame); fSldXMin = new TGNumberEntryField(f17, kSLIDERX_MIN, 0.0, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEAAnyNumber); ((TGTextEntry*)fSldXMin)->SetToolTipText("Set the minimum value of the x-axis"); fSldXMin->Resize(57,20); f17->AddFrame(fSldXMin, new TGLayoutHints(kLHintsLeft, 0, 0, 0, 0)); fSldXMax = new TGNumberEntryField(f17, kSLIDERX_MAX, 0.0, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEAAnyNumber); ((TGTextEntry*)fSldXMax)->SetToolTipText("Set the maximum value of the x-axis"); fSldXMax->Resize(57,20); f17->AddFrame(fSldXMax, new TGLayoutHints(kLHintsLeft, 4, 0, 0, 0)); fBin->AddFrame(f17, new TGLayoutHints(kLHintsTop, 20, 3, 5, 0)); TGCompositeFrame *f15 = new TGCompositeFrame(fBin, 80, 20, kHorizontalFrame); TGLabel *fSliderYLbl = new TGLabel(f15,"y:"); f15->AddFrame(fSliderYLbl, new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 4,2, 4, 1)); fSliderY = new TGDoubleHSlider(f15, 1, 2); fSliderY->Resize(119,20); f15->AddFrame(fSliderY, new TGLayoutHints(kLHintsLeft)); fBin->AddFrame(f15, new TGLayoutHints(kLHintsTop, 3, 7, 4, 1)); TGCompositeFrame *f18 = new TGCompositeFrame(fBin, 80, 20, kHorizontalFrame); fSldYMin = new TGNumberEntryField(f18, kSLIDERY_MIN, 0.0, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEAAnyNumber); ((TGTextEntry*)fSldYMin)->SetToolTipText("Set the minimum value of the y-axis"); fSldYMin->Resize(57,20); f18->AddFrame(fSldYMin, new TGLayoutHints(kLHintsLeft, 0, 0, 0, 0)); fSldYMax = new TGNumberEntryField(f18, kSLIDERY_MAX, 0.0, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEAAnyNumber); ((TGTextEntry*)fSldYMax)->SetToolTipText("Set the maximum value of the y-axis"); fSldYMax->Resize(57,20); f18->AddFrame(fSldYMax, new TGLayoutHints(kLHintsLeft, 4, 0, 0, 0)); fBin->AddFrame(f18, new TGLayoutHints(kLHintsTop, 20, 3, 5, 0)); TGCompositeFrame *f20 = new TGCompositeFrame(fBin, 80, 20, kVerticalFrame); fDelaydraw = new TGCheckButton(f20, "Delayed drawing", kDELAYED_DRAWING); fDelaydraw ->SetToolTipText("Draw the new axis range when the Slider is released"); f20->AddFrame(fDelaydraw, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 0)); fBin->AddFrame(f20, new TGLayoutHints(kLHintsTop, 2, 1, 5, 3)); fXBinOffsetSld->SetRange(0,100); fXBinOffsetSld->SetPosition(0); fXOffsetNumberEntry->SetNumber(0.0000); fYBinOffsetSld->SetRange(0,100); fYBinOffsetSld->SetPosition(0); fYOffsetNumberEntry->SetNumber(0.0000); fCancel->SetState(kButtonDisabled); fApply->SetState(kButtonDisabled); } //////////////////////////////////////////////////////////////////////////////// /// Destructor. TH2Editor::~TH2Editor() { // remove itselef from the list of cleanups gROOT->GetListOfCleanups()->Remove(this); // children of TGButonGroup are not deleted delete fDim; delete fDim0; delete fDimlh; delete fDim0lh; if (fBinHist) delete fBinHist; fBinHist = 0; } //////////////////////////////////////////////////////////////////////////////// /// Connect signals to slots. void TH2Editor::ConnectSignals2Slots() { fTitle->Connect("TextChanged(const char *)", "TH2Editor", this, "DoTitle(const char *)"); fDimGroup->Connect("Clicked(Int_t)","TH2Editor",this,"DoHistView()"); fTypeCombo->Connect("Selected(Int_t)", "TH2Editor", this, "DoHistChanges()"); fCoordsCombo->Connect("Selected(Int_t)", "TH2Editor", this, "DoHistChanges()"); fContCombo->Connect("Selected(Int_t)", "TH2Editor", this, "DoHistChanges()"); fAddArr->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddArr(Bool_t)"); fAddBox->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddBox(Bool_t)"); fAddCol->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddCol(Bool_t)"); fAddScat->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddScat(Bool_t)"); fAddText->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddText(Bool_t)"); fAddError->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddError(Bool_t)"); fAddPalette->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddPalette(Bool_t)"); fAddPalette1->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddPalette(Bool_t)"); fAddFB->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddFB()"); fAddBB->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddBB()"); fContLevels->Connect("ValueSet(Long_t)", "TH2Editor", this, "DoContLevel()"); (fContLevels->GetNumberEntry())->Connect("ReturnPressed()", "TH2Editor", this,"DoContLevel()"); fContLevels1->Connect("ValueSet(Long_t)", "TH2Editor", this, "DoContLevel1()"); (fContLevels1->GetNumberEntry())->Connect("ReturnPressed()", "TH2Editor", this,"DoContLevel1()"); fBarWidth->Connect("ValueSet(Long_t)", "TH2Editor", this, "DoBarWidth()"); (fBarWidth->GetNumberEntry())->Connect("ReturnPressed()", "TH2Editor", this, "DoBarWidth()"); fBarOffset->Connect("ValueSet(Long_t)", "TH2Editor", this, "DoBarOffset()"); (fBarOffset->GetNumberEntry())->Connect("ReturnPressed()", "TH2Editor", this, "DoBarOffset()"); fBinXSlider->Connect("PositionChanged(Int_t)","TH2Editor",this, "DoBinMoved()"); fBinXSlider->Connect("Released()","TH2Editor",this, "DoBinReleased()"); fBinXSlider->Connect("Pressed()","TH2Editor",this, "DoBinPressed()"); fBinYSlider->Connect("PositionChanged(Int_t)","TH2Editor",this, "DoBinMoved()"); fBinYSlider->Connect("Released()","TH2Editor",this, "DoBinReleased()"); fBinYSlider->Connect("Pressed()","TH2Editor",this, "DoBinPressed()"); fBinXNumberEntry->Connect("ReturnPressed()", "TH2Editor", this, "DoBinLabel()"); fBinYNumberEntry->Connect("ReturnPressed()", "TH2Editor", this, "DoBinLabel()"); fApply->Connect("Clicked()", "TH2Editor", this, "DoApply()"); fCancel->Connect("Pressed()", "TH2Editor", this, "DoCancel()"); fBinXSlider1->Connect("Released()","TH2Editor",this, "DoBinReleased1()"); fBinXSlider1->Connect("PositionChanged(Int_t)","TH2Editor",this, "DoBinMoved1()"); fBinXNumberEntry1->Connect("ReturnPressed()", "TH2Editor", this, "DoBinLabel1()"); fXBinOffsetSld->Connect("PositionChanged(Int_t)","TH2Editor",this, "DoOffsetMoved()"); fXBinOffsetSld->Connect("Released()","TH2Editor",this, "DoOffsetReleased()"); fXBinOffsetSld->Connect("Pressed()","TH2Editor",this, "DoOffsetPressed()"); fXOffsetNumberEntry->Connect("ReturnPressed()", "TH2Editor", this, "DoBinOffset()"); fBinYSlider1->Connect("Released()","TH2Editor",this, "DoBinReleased1()"); fBinYSlider1->Connect("PositionChanged(Int_t)","TH2Editor",this, "DoBinMoved1()"); fBinYNumberEntry1->Connect("ReturnPressed()", "TH2Editor", this, "DoBinLabel1()"); fYBinOffsetSld->Connect("PositionChanged(Int_t)","TH2Editor",this,"DoOffsetMoved()"); fYBinOffsetSld->Connect("Released()","TH2Editor",this, "DoOffsetReleased()"); fYBinOffsetSld->Connect("Pressed()","TH2Editor",this, "DoOffsetPressed()"); fYOffsetNumberEntry->Connect("ReturnPressed()", "TH2Editor", this,"DoBinOffset()"); fSliderX->Connect("PositionChanged()","TH2Editor",this, "DoSliderXMoved()"); fSliderX->Connect("Pressed()","TH2Editor",this, "DoSliderXPressed()"); fSliderX->Connect("Released()","TH2Editor",this, "DoSliderXReleased()"); fSldXMin->Connect("ReturnPressed()", "TH2Editor", this, "DoXAxisRange()"); fSldXMax->Connect("ReturnPressed()", "TH2Editor", this, "DoXAxisRange()"); fSliderY->Connect("PositionChanged()","TH2Editor",this, "DoSliderYMoved()"); fSliderY->Connect("Pressed()","TH2Editor",this, "DoSliderYPressed()"); fSliderY->Connect("Released()","TH2Editor",this, "DoSliderYReleased()"); fSldYMin->Connect("ReturnPressed()", "TH2Editor", this, "DoYAxisRange()"); fSldYMax->Connect("ReturnPressed()", "TH2Editor", this, "DoYAxisRange()"); fFrameColor->Connect("ColorSelected(Pixel_t)", "TH2Editor", this, "DoFillColor(Pixel_t)"); fFramePattern->Connect("PatternSelected(Style_t)", "TH2Editor", this, "DoFillPattern(Style_t)"); fInit = kFALSE; } //////////////////////////////////////////////////////////////////////////////// /// Check if object is able to configure with this editor. Bool_t TH2Editor::AcceptModel(TObject* obj) { if (obj == 0 || !obj->InheritsFrom(TH2::Class()) || (!strcmp(((TH2 *)obj)->GetName(),"htemp") && ((TH2*)obj)->GetEntries() == 0)) { // htemp is an empty histogram return kFALSE; } return kTRUE; } //////////////////////////////////////////////////////////////////////////////// /// Pick up the values of current histogram attributes. void TH2Editor::SetModel(TObject* obj) { fAvoidSignal = kTRUE; if (fBinHist && (obj != fHist)) { //we have probably moved to a different pad. //let's restore the original histogram if (fHist) { fHist->Reset(); fHist->SetBins(fBinHist->GetXaxis()->GetNbins(), fBinHist->GetXaxis()->GetXmin(), fBinHist->GetXaxis()->GetXmax(), fBinHist->GetYaxis()->GetNbins(), fBinHist->GetYaxis()->GetXmin(), fBinHist->GetYaxis()->GetXmax()); fHist->Add(fBinHist); } // delete in anycase fBinHist also when fHist is zero (i.e when it has been deleted) delete fBinHist; fBinHist = 0; if (fGedEditor->GetPad()) { fGedEditor->GetPad()->Modified(); fGedEditor->GetPad()->Update(); } } fHist = (TH2*) obj; const char *text = fHist->GetTitle(); fTitle->SetText(text); TString str = GetDrawOption(); fCutString = GetCutOptionString(); str.ToUpper(); if (str == "") { // default options = Scatter-Plot ShowFrame(f6); HideFrame(f9); HideFrame(f12); HideFrame(f13); HideFrame(f38); fDimGroup->SetButton(kDIM_SIMPLE, kTRUE); fDimGroup->SetButton(kDIM_COMPLEX, kFALSE); if (fTypeCombo->GetSelected()==-1) fTypeCombo->Select(kTYPE_LEGO); if (fCoordsCombo->GetSelected()==-1) fCoordsCombo->Select(kCOORDS_CAR); if (fContCombo->GetSelected()==-1) fContCombo->Select(kCONT_NONE); fAddArr->SetState(kButtonUp); fAddBox->SetState(kButtonUp); fAddCol->SetState(kButtonUp); fAddScat->SetState(kButtonDisabled); fAddText->SetState(kButtonUp); fAddError->SetState(kButtonUp); fAddPalette->SetState(kButtonDisabled); fAddPalette1->SetState(kButtonUp); fAddFB->SetState(kButtonDown); fAddBB->SetState(kButtonDown); } else if (!str.Contains("LEGO") && !str.Contains("SURF")) { ShowFrame(f6); HideFrame(f9); HideFrame(f12); HideFrame(f13); HideFrame(f38); fDimGroup->SetButton(kDIM_SIMPLE, kTRUE); fDimGroup->SetButton(kDIM_COMPLEX, kFALSE); if (fTypeCombo->GetSelected()==-1) fTypeCombo->Select(kTYPE_LEGO); if (fCoordsCombo->GetSelected()==-1) fCoordsCombo->Select(kCOORDS_CAR); if (str.Contains("CONT")){ if (str.Contains("CONT1")) fContCombo->Select(kCONT_1); else if (str.Contains("CONT2")) fContCombo->Select(kCONT_2); else if (str.Contains("CONT3")) fContCombo->Select(kCONT_3); else if (str.Contains("CONT4")) fContCombo->Select(kCONT_4); else if (str.Contains("CONT0") || str.Contains("CONT")) fContCombo->Select(kCONT_0); } else fContCombo->Select(kCONT_NONE); if (str.Contains("ARR")) fAddArr->SetState(kButtonDown); else fAddArr->SetState(kButtonUp); if (str.Contains("BOX")) fAddBox->SetState(kButtonDown); else fAddBox->SetState(kButtonUp); if (str.Contains("COL")) fAddCol->SetState(kButtonDown); else fAddCol->SetState(kButtonUp); if (str.Contains("SCAT")) { if (str=="SCAT") fAddScat->SetState(kButtonDisabled); else fAddScat->SetState(kButtonDown); } else fAddScat->SetState(kButtonUp); if (str.Contains("TEXT")) fAddText->SetState(kButtonDown); else fAddText->SetState(kButtonUp); fAddError->SetState(kButtonUp); if (str.Contains("COL") || (str.Contains("CONT") && !str.Contains("CONT2") && !str.Contains("CONT3"))) { if (str.Contains("Z")) fAddPalette->SetState(kButtonDown); else fAddPalette->SetState(kButtonUp); } else fAddPalette->SetState(kButtonDisabled); fAddPalette1->SetState(kButtonUp); fAddFB->SetState(kButtonDown); fAddBB->SetState(kButtonDown); } else if (str.Contains("LEGO") || str.Contains("SURF")) { HideFrame(f6); ShowFrame(f9); ShowFrame(f12); ShowFrame(f13); ShowFrame(f38); fDimGroup->SetButton(kDIM_COMPLEX, kTRUE); fDimGroup->SetButton(kDIM_SIMPLE, kFALSE); if (str.Contains("LEGO4")) fTypeCombo->Select(kTYPE_LEGO4); else if (str.Contains("LEGO3")) fTypeCombo->Select(kTYPE_LEGO3); else if (str.Contains("LEGO2")) fTypeCombo->Select(kTYPE_LEGO2); else if (str.Contains("LEGO1")) fTypeCombo->Select(kTYPE_LEGO1); else if (str.Contains("LEGO")) fTypeCombo->Select(kTYPE_LEGO); else if (str.Contains("SURF5")) fTypeCombo->Select(kTYPE_SURF5); else if (str.Contains("SURF4")) fTypeCombo->Select(kTYPE_SURF4); else if (str.Contains("SURF3")) fTypeCombo->Select(kTYPE_SURF3); else if (str.Contains("SURF2")) fTypeCombo->Select(kTYPE_SURF2); else if (str.Contains("SURF1")) fTypeCombo->Select(kTYPE_SURF1); else if (str.Contains("SURF")) fTypeCombo->Select(kTYPE_SURF); if (str.Contains("CYL")) fCoordsCombo->Select(kCOORDS_CYL); else if (str.Contains("POL")) fCoordsCombo->Select(kCOORDS_POL); else if (str.Contains("SPH")) fCoordsCombo->Select(kCOORDS_SPH); else if (str.Contains("PSR")) fCoordsCombo->Select(kCOORDS_PSR); else fCoordsCombo->Select(kCOORDS_CAR); //default if (fContCombo->GetSelected()==-1) fContCombo->Select(kCONT_NONE); fAddArr->SetState(kButtonUp); fAddBox->SetState(kButtonUp); fAddCol->SetState(kButtonUp); fAddScat->SetState(kButtonDisabled); fAddText->SetState(kButtonUp); if (fCoordsCombo->GetSelected()!=kCOORDS_CAR) { if (fAddFB->GetState()!=kButtonDisabled) fAddFB->SetState(kButtonDisabled); if (fAddBB->GetState()!=kButtonDisabled) fAddBB->SetState(kButtonDisabled); if (fAddError->GetState()!=kButtonDisabled) fAddError->SetState(kButtonDisabled); } else { if (str.Contains("FB")) fAddFB->SetState(kButtonUp); else fAddFB->SetState(kButtonDown); if (str.Contains("BB")) fAddBB->SetState(kButtonUp); else fAddBB->SetState(kButtonDown); if (str.Contains("E")){ TString dum = str; if (str.Contains("LEGO")) dum.Remove(strstr(dum.Data(),"LEGO")-dum.Data(),4); if (str.Contains("TEXT")) dum.Remove(strstr(dum.Data(),"TEXT")-dum.Data(),4); if (dum.Contains("E")) fAddError->SetState(kButtonDown); else fAddError->SetState(kButtonUp); } else fAddError->SetState(kButtonUp); } if ((fTypeCombo->GetSelected()==kTYPE_LEGO) || (fTypeCombo->GetSelected()==kTYPE_LEGO1)|| (fTypeCombo->GetSelected()==kTYPE_LEGO3)|| (fTypeCombo->GetSelected()==kTYPE_LEGO4)|| (fTypeCombo->GetSelected()==kTYPE_SURF) || (fTypeCombo->GetSelected()==kTYPE_SURF4)) fAddPalette1->SetState(kButtonDisabled); else if (str.Contains("Z")) fAddPalette1->SetState(kButtonDown); else fAddPalette1->SetState(kButtonUp); } fBarWidth->SetNumber(fHist->GetBarWidth()); fBarOffset->SetNumber(fHist->GetBarOffset()); Int_t nx = fHist -> GetXaxis() -> GetNbins(); Int_t nxbinmin = fHist -> GetXaxis() -> GetFirst(); Int_t nxbinmax = fHist -> GetXaxis() -> GetLast(); fSliderX->SetRange(1,nx); fSliderX->SetPosition((Double_t)nxbinmin,(Double_t)nxbinmax); fSldXMin->SetNumber(fHist->GetXaxis()->GetBinLowEdge(nxbinmin)); fSldXMax->SetNumber(fHist->GetXaxis()->GetBinUpEdge(nxbinmax)); Int_t ny = fHist -> GetYaxis() -> GetNbins(); Int_t nybinmin = fHist -> GetYaxis() -> GetFirst(); Int_t nybinmax = fHist -> GetYaxis() -> GetLast(); fSliderY->SetRange(1,ny); fSliderY->SetPosition((Double_t)nybinmin,(Double_t)nybinmax); fSldYMin->SetNumber(fHist->GetYaxis()->GetBinLowEdge(nybinmin)); fSldYMax->SetNumber(fHist->GetYaxis()->GetBinUpEdge(nybinmax)); if (fDelaydraw->GetState()!=kButtonDown) fDelaydraw->SetState(kButtonUp); if (str.Contains("COL") || fContCombo->GetSelected()!= kCONT_NONE) fColContLbl->Enable() ; else fColContLbl->Disable(); if (str.Contains("LEGO2") || str.Contains("SURF1") || str.Contains("SURF2") || str.Contains("SURF3") || str.Contains("SURF5")) fColContLbl1->Enable(); else fColContLbl1->Disable(); fContLevels->SetIntNumber(fHist->GetContour()); fContLevels1->SetIntNumber(fHist->GetContour()); fFrameColor->SetColor(TColor::Number2Pixel(fGedEditor->GetPad()->GetFrameFillColor())); fFramePattern->SetPattern(fGedEditor->GetPad()->GetFrameFillStyle()); TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); // Check if histogram is from ntupla/tree or not. // If it is a standard histogram or a ntupla based histogram // show a different frame in case of rebinning (fBinCont) with sliders and bin number entries // connected to different methods. // For example the entry field fBinXNumberEntry is connected to // the method DoBinLabel in case of non-ntupla histograms which just call Th1::Rebin // In csae of a tree based histogram the entry field fBinNumberEntry1 is used which is connected to // TH1Editor::DoBinLabel1 which is re-filling the histograms with the cached values from the TTreePlayer. // Since the actual number of histogram entry can be larger than the cache size of the TTreePlayer // (see JIRA ROOT-5900 or http://root.cern.ch/phpBB3/viewtopic.php?f=3&t=17107 ) // the GUI frame based on a non-tupla histogram is used when the number of entries of the histogram is // not the same as the number of filled entries in the TTreePlayer object. if (!player || player->GetHistogram()!=fHist || fHist->GetEntries() != player->GetNfill()) { Int_t n1 = 0, n2 =0; Int_t upx =0, upy =0; if (fBinHist) n1 = fBinHist->GetXaxis()->GetNbins(); else n1 = nx; if (fBinHist) n2 = fBinHist->GetYaxis()->GetNbins(); else n2 = ny; fBin->HideFrame(fBinXCont1); fBin->ShowFrame(fBinXCont); fBin->HideFrame(fBinYCont1); if (n1 < 1) n1 = 1; if (n2 < 1) n2 = 1; Int_t* divx = Dividers(n1); Int_t* divy = Dividers(n2); if (divx[0]-1 <= 1) upx = 2; else upx = divx[0]-1; fBinXSlider->SetRange(1,upx); if (divy[0]-1 <= 1) upy = 2; else upy = divy[0]-1; fBinYSlider->SetRange(1,upy); Int_t i = 1; Int_t j = 1; if (fBinXSlider->GetMaxPosition()==2 && fBinXSlider->GetPosition()==2) fBinXSlider->SetPosition(2); else { while ( divx[i] != nx) i ++; fBinXSlider->SetPosition(divx[0] - i + 1); } if (fBinYSlider->GetMaxPosition()==2 && fBinYSlider->GetPosition()==2) fBinYSlider->SetPosition(2); else { while ( divy [j] != ny) j ++; fBinYSlider->SetPosition(divy[0] - j + 1); } fBinXNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 2, n1); fBinXNumberEntry->SetIntNumber(nx); fBinYNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 2, n2); fBinYNumberEntry->SetIntNumber(ny); delete [] divx; delete [] divy; } else if (player && fHist==player->GetHistogram() && fHist->GetEntries() == player->GetNfill()) { fBin->HideFrame(fBinXCont); fBin->ShowFrame(fBinXCont1); fBin->ShowFrame(fBinYCont1); fBinXSlider1->SetPosition(5); fBinXNumberEntry1->SetLimits(TGNumberFormat::kNELLimitMinMax, 1, 1000); fBinXNumberEntry1->SetIntNumber(nxbinmax-nxbinmin+1); fBinYSlider1->SetPosition(5); fBinYNumberEntry1->SetLimits(TGNumberFormat::kNELLimitMinMax, 1, 1000); fBinYNumberEntry1->SetIntNumber(nybinmax-nybinmin+1); } fXOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, fHist->GetXaxis()->GetBinWidth(1)); fYOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, fHist->GetYaxis()->GetBinWidth(1)); if (!fGedEditor->GetTab()->IsEnabled(fGedEditor->GetTab()->GetCurrent())) fGedEditor->GetTab()->SetTab(0); if (fInit) ConnectSignals2Slots(); fGedEditor->GetTab()->SetEnabled(1, kTRUE); fAvoidSignal = kFALSE; } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the histogram title setting. void TH2Editor::DoTitle(const char *text) { if (fAvoidSignal) return; fHist->SetTitle(text); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the 'Plot' button group. void TH2Editor::DoHistView() { if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kWatch); gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kWatch)); if (fDim->GetState() == kButtonDown) DoHistSimple(); else DoHistComplex(); if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kPointer); gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kPointer)); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the 2D-Plot radio button. void TH2Editor::DoHistSimple() { if (fAvoidSignal) return; TString str = ""; ShowFrame(f6); HideFrame(f9); HideFrame(f12); HideFrame(f13); HideFrame(f38); if (fContCombo->GetSelected()==-1) fContCombo->Select(kCONT_NONE); if ((fContCombo->GetSelected()!= kCONT_NONE) && fAddPalette->GetState()==kButtonDisabled) fAddPalette->SetState(kButtonUp); str = GetHistContLabel()+GetHistAdditiveLabel(); if (str=="" || str=="SCAT" || str==fCutString) { fAddScat->SetState(kButtonDisabled); fAddPalette->SetState(kButtonDisabled); } else if (fAddScat->GetState()==kButtonDisabled) fAddScat->SetState(kButtonUp); if (str.Contains("COL") || fContCombo->GetSelected()!= kCONT_NONE) fColContLbl->Enable(); else fColContLbl->Disable(); ((TGMainFrame*)GetMainFrame())->Layout(); TString ocut = fCutString; ocut.ToUpper(); if (!str.Contains(fCutString) && !str.Contains(ocut)) str+=fCutString; SetDrawOption(str); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the 3D-Plot radio button. void TH2Editor::DoHistComplex() { if (fAvoidSignal) return; TString str = ""; HideFrame(f6); ShowFrame(f9); ShowFrame(f38); if (GetHistTypeLabel().Contains("LEGO")) { ShowFrame(f12); ShowFrame(f13); } else { HideFrame(f12); HideFrame(f13); } if (fTypeCombo->GetSelected()==-1) fTypeCombo->Select(kTYPE_LEGO); if (fCoordsCombo->GetSelected()==-1) fCoordsCombo->Select(kCOORDS_CAR); str = GetHistTypeLabel()+GetHistCoordsLabel()+GetHistAdditiveLabel(); if (str.Contains("LEGO2") || str.Contains("SURF1") || str.Contains("SURF2") || str.Contains("SURF3") || str.Contains("SURF5")) { fColContLbl1->Enable(); if (fAddPalette1->GetState()==kButtonDisabled) fAddPalette1->SetState(kButtonUp); } else { fColContLbl1->Disable(); fAddPalette1->SetState(kButtonDisabled); } ((TGMainFrame*)GetMainFrame())->Layout(); TString ocut = fCutString; ocut.ToUpper(); if (!str.Contains(fCutString) && !str.Contains(ocut)) str+=fCutString; SetDrawOption(str); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to histogram type, coordinate system, contour combo box. void TH2Editor::DoHistChanges() { if (fAvoidSignal) return; TString str = ""; if (fDim->GetState() == kButtonDown) { str = GetHistContLabel()+GetHistAdditiveLabel(); if ((fContCombo->GetSelected()!=kCONT_NONE && fContCombo->GetSelected()!=kCONT_2 && fContCombo->GetSelected()!=kCONT_3) || str.Contains("COL")) { if (str.Contains("Z")) fAddPalette->SetState(kButtonDown); else fAddPalette->SetState(kButtonUp); } else fAddPalette->SetState(kButtonDisabled); if (str=="" || str=="SCAT" || str==fCutString) { fAddScat->SetState(kButtonDisabled); fAddPalette->SetState(kButtonDisabled); } else if (fAddScat->GetState()==kButtonDisabled) fAddScat->SetState(kButtonUp); str = GetHistContLabel()+GetHistAdditiveLabel(); if (str.Contains("COL") || fContCombo->GetSelected()!= kCONT_NONE) fColContLbl->Enable(); else fColContLbl->Disable(); } else if (fDim0->GetState() == kButtonDown) { if (fCoordsCombo->GetSelected()!=kCOORDS_CAR) { if (fAddFB->GetState()!=kButtonDisabled) fAddFB->SetState(kButtonDisabled); if (fAddBB->GetState()!=kButtonDisabled) fAddBB->SetState(kButtonDisabled); if (fAddError->GetState()!=kButtonDisabled) fAddError->SetState(kButtonDisabled); } else { if (fAddFB->GetState()==kButtonDisabled) fAddFB->SetState(kButtonDown); if (fAddBB->GetState()==kButtonDisabled) fAddBB->SetState(kButtonDown); if (fAddError->GetState()==kButtonDisabled) fAddError->SetState(kButtonUp); } if ((fTypeCombo->GetSelected()==kTYPE_LEGO) || (fTypeCombo->GetSelected()==kTYPE_LEGO1)|| (fTypeCombo->GetSelected()==kTYPE_LEGO3)|| (fTypeCombo->GetSelected()==kTYPE_LEGO4)|| (fTypeCombo->GetSelected()==kTYPE_SURF) || (fTypeCombo->GetSelected()==kTYPE_SURF4)) fAddPalette1->SetState(kButtonDisabled); else if (fAddPalette1->GetState()==kButtonDisabled) fAddPalette1->SetState(kButtonUp); if (GetHistTypeLabel().Contains("LEGO")) { ShowFrame(f12); ShowFrame(f13); } else { HideFrame(f12); HideFrame(f13); } ((TGMainFrame*)GetMainFrame())->Layout(); str = GetHistTypeLabel()+GetHistCoordsLabel()+GetHistAdditiveLabel(); if (str.Contains("LEGO2") || str.Contains("SURF1") || str.Contains("SURF2") || str.Contains("SURF3") || str.Contains("SURF5")) fColContLbl1->Enable(); else fColContLbl1->Disable() ; } TString ocut = fCutString; ocut.ToUpper(); if (!str.Contains(fCutString) && !str.Contains(ocut)) str+=fCutString; SetDrawOption(str); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the "Arrow draw option" check button. void TH2Editor::DoAddArr(Bool_t on) { if (fAvoidSignal) return; Bool_t make=kFALSE; TString str = GetDrawOption(); str.ToUpper(); if (on) { if (!str.Contains("ARR")) { str += "ARR"; if (fAddScat->GetState()==kButtonDisabled) fAddScat->SetState(kButtonUp); make=kTRUE; } } else if (fAddArr->GetState()==kButtonUp) { if (str.Contains("ARR")) { str.Remove(strstr(str.Data(),"ARR")-str.Data(),3); if (str=="" || str=="SCAT" || str==fCutString) { fAddScat->SetState(kButtonDisabled); fAddPalette->SetState(kButtonDisabled); } make=kTRUE; } } if (make) { DoHistChanges(); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the "Box draw option" check button. void TH2Editor::DoAddBox(Bool_t on) { if (fAvoidSignal) return; Bool_t make=kFALSE; TString str = GetDrawOption(); str.ToUpper(); if (on) { if (!str.Contains("BOX")) { str += "BOX"; if (fAddScat->GetState()==kButtonDisabled) fAddScat->SetState(kButtonUp); make=kTRUE; } } else if (fAddBox->GetState()==kButtonUp) { if (str.Contains("BOX")) { str.Remove(strstr(str.Data(),"BOX")-str.Data(),3); if (str=="" || str=="SCAT" || str==fCutString) { fAddScat->SetState(kButtonDisabled); fAddPalette->SetState(kButtonDisabled); } make=kTRUE; } } if (make) { DoHistChanges(); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the "Col draw option" check button. void TH2Editor::DoAddCol(Bool_t on) { if (fAvoidSignal) return; Bool_t make=kFALSE; TString str = GetDrawOption(); str.ToUpper(); if (on) { if (!str.Contains("COL")) { str += "COL"; fColContLbl->Enable() ; if (fAddScat->GetState()==kButtonDisabled) fAddScat->SetState(kButtonUp); if (fAddPalette->GetState()==kButtonDisabled) fAddPalette->SetState(kButtonUp); make=kTRUE; } } else if (fAddCol->GetState()==kButtonUp) { if (str.Contains("COL")) { str.Remove(strstr(str.Data(),"COL")-str.Data(),3); if (fAddBox->GetState()==kButtonDisabled) fAddBox->SetState(kButtonUp); if (fContCombo->GetSelected()==kCONT_NONE) { fAddPalette->SetState(kButtonDisabled); if (str.Contains("Z")) str.Remove(strstr(str.Data(),"Z")-str.Data(),1); } if (str=="" || str=="SCAT" || str==fCutString) fAddScat->SetState(kButtonDisabled); if (fContCombo->GetSelected()!= kCONT_NONE) fColContLbl->Enable() ; else fColContLbl->Disable(); make=kTRUE; } } if (make) { DoHistChanges(); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the "Scat draw option" check button. void TH2Editor::DoAddScat(Bool_t on) { if (fAvoidSignal) return; Bool_t make=kFALSE; TString str = GetDrawOption(); str.ToUpper(); if (on) { if (!str.Contains("SCAT")) { str += "SCAT"; make=kTRUE; } } else if (fAddScat->GetState()==kButtonUp) { if (str.Contains("SCAT")) { str.Remove(strstr(str.Data(),"SCAT")-str.Data(),4); make=kTRUE; } } if (make) { DoHistChanges(); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the "Text draw option" check button. void TH2Editor::DoAddText(Bool_t on) { if (fAvoidSignal) return; Bool_t make=kFALSE; TString str = GetDrawOption(); str.ToUpper(); if (on) { if (!str.Contains("TEXT")) { str += "TEXT"; if (fAddScat->GetState()==kButtonDisabled) fAddScat->SetState(kButtonUp); make=kTRUE; } } else if (fAddText->GetState()==kButtonUp) { if (str.Contains("TEXT")) { str.Remove(strstr(str.Data(),"TEXT")-str.Data(),4); if (str=="" || str=="SCAT" || str==fCutString) fAddScat->SetState(kButtonDisabled); make=kTRUE; } } if (make) { DoHistChanges(); // next line is needed for marker editor refresh fGedEditor->GetCanvas()->Selected(fGedEditor->GetPad(), fHist, 1); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the "Error" check button. void TH2Editor::DoAddError(Bool_t on) { if (fAvoidSignal) return; Bool_t make=kFALSE; TString str = GetDrawOption(); str.ToUpper(); TString dum = str; if (str.Contains("LEGO")) dum.Remove(strstr(dum.Data(),"LEGO")-dum.Data(),4); if (str.Contains("TEXT")) dum.Remove(strstr(dum.Data(),"TEXT")-dum.Data(),4); if (on) { if (!dum.Contains("E")) { str += "E"; make=kTRUE; } } else if (fAddError->GetState() == kButtonUp) { if (str.Contains("E")) { if (fDim->GetState() == kButtonDown) str = GetHistContLabel()+GetHistAdditiveLabel(); else str= GetHistTypeLabel()+GetHistCoordsLabel()+ GetHistAdditiveLabel(); make=kTRUE; } } if (make) { DoHistChanges(); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the color palette check button. void TH2Editor::DoAddPalette(Bool_t on) { if (fAvoidSignal) return; Bool_t make=kFALSE; TString str = GetDrawOption(); str.ToUpper(); if (on) { if (!str.Contains("Z")) { str += "Z"; make=kTRUE; } } else if (fAddPalette->GetState()==kButtonUp || fAddPalette1->GetState()==kButtonUp) { if (str.Contains("Z")) { str.Remove(strstr(str.Data(),"Z")-str.Data(),1); make=kTRUE; } } if (make) { DoHistChanges(); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the "FB front-box draw option" check button. void TH2Editor::DoAddFB() { if (fAvoidSignal) return; Bool_t make=kFALSE; TString str = GetDrawOption(); str.ToUpper(); if (fAddFB->GetState()==kButtonDown) { if (str.Contains("FB")) { if (str.Contains("SURF") && !(str.Contains("1") || str.Contains("2") || str.Contains("3") || str.Contains("4") || str.Contains("5"))) { TString dum = str; dum.Remove(strstr(dum.Data(),"SURF")-dum.Data(),4); if (dum.Contains("FB")) dum.Remove(strstr(dum.Data(),"FB")-dum.Data(),2); str = "SURF" + dum; } else str.Remove(strstr(str.Data(),"FB")-str.Data(),2); make = kTRUE; } } else if (fAddFB->GetState()==kButtonUp){ if (!str.Contains("FB")) { str += "FB"; make=kTRUE; } } if (make) { DoHistChanges(); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the "BB back-box draw option" check button. void TH2Editor::DoAddBB() { if (fAvoidSignal) return; Bool_t make=kFALSE; TString str = GetDrawOption(); str.ToUpper(); if (fAddBB->GetState()==kButtonDown) { if (str.Contains("BB")) { if (str.Contains("FB")) { TString dum = str; dum.Remove(strstr(dum.Data(),"FB")-dum.Data(),2); dum.Remove(strstr(dum.Data(),"BB")-dum.Data(),2); str=dum+"FB"; } else str.Remove(strstr(str.Data(),"BB")-str.Data(),2); make = kTRUE; } } else if (fAddBB->GetState()==kButtonUp){ if (!str.Contains("BB")) { str += "BB"; make=kTRUE; } } if (make) { DoHistChanges(); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the contour level number entry fContLevels. void TH2Editor::DoContLevel() { if (fAvoidSignal) return; fHist->SetContour((Int_t)fContLevels->GetNumber()); fContLevels1->SetNumber((Int_t)fContLevels->GetNumber()); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the contour level number entry fContLevels1. void TH2Editor::DoContLevel1() { if (fAvoidSignal) return; fHist->SetContour((Int_t)fContLevels1->GetNumber()); fContLevels->SetNumber((Int_t)fContLevels1->GetNumber()); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the bar width of the bar chart. void TH2Editor::DoBarWidth() { if (fAvoidSignal) return; fHist->SetBarWidth(fBarWidth->GetNumber()); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the bar offset of the bar chart. void TH2Editor::DoBarOffset() { if (fAvoidSignal) return; fHist->SetBarOffset((Float_t)fBarOffset->GetNumber()); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the rebin slider in case of no ntuple histogram. /// It updates some other widgets related to the rebin slider. void TH2Editor::DoBinReleased() { // Draw the rebinned histogram in case of the delay draw mode if (fAvoidSignal) return; if (fDelaydraw->GetState()==kButtonDown){ if (!fBinHist) { fBinHist = (TH2*)fHist->Clone("BinHist"); fBinHist->SetDirectory(0); // TH2Editor manages this histogram } Int_t nx = fBinHist->GetXaxis()->GetNbins(); Int_t ny = fBinHist->GetYaxis()->GetNbins(); Int_t numx = fBinXSlider->GetPosition(); Int_t numy = fBinYSlider->GetPosition(); Int_t* divx = Dividers(nx); Int_t* divy = Dividers(ny); if (divx[0]==2) fBinXSlider->SetPosition(2); if (divy[0]==2) fBinYSlider->SetPosition(2); if (divx[0]==2 && divy[0]==2) { delete [] divx; delete [] divy; return; } // delete the histogram which is on the screen fGedEditor->GetPad()->cd(); fHist->Reset(); fHist->SetBins(nx,fBinHist->GetXaxis()->GetXmin(), fBinHist->GetXaxis()->GetXmax(), ny,fBinHist->GetYaxis()->GetXmin(), fBinHist->GetYaxis()->GetXmax()); fHist->Add(fBinHist); fHist->SetCanExtend(TH1::kNoAxis); fHist->Rebin2D(divx[numx], divy[numy]); //fModel=fHist; if (divx[0]!=2) { TAxis* xaxis = fHist->GetXaxis(); Double_t xBinWidth = xaxis->GetBinWidth(1); xaxis->SetRangeUser(fSldXMin->GetNumber()+xBinWidth/2, fSldXMax->GetNumber()-xBinWidth/2); fSliderX->SetRange(1,(Int_t)nx/divx[numx]); fSliderX->SetPosition(xaxis->FindBin(fSldXMin->GetNumber()+xBinWidth/2), xaxis->FindBin(fSldXMax->GetNumber()-xBinWidth/2)); // the axis range could be changed a little bit by the Rebin algorithm fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); } if (divy[0]!=2) { TAxis* yaxis = fHist->GetYaxis(); Double_t yBinWidth = yaxis->GetBinWidth(1); yaxis->SetRangeUser(fSldYMin->GetNumber()+yBinWidth/2, fSldYMax->GetNumber()-yBinWidth/2); fSliderY->SetRange(1,(Int_t)ny/divy[numy]); fSliderY->SetPosition(yaxis->FindBin(fSldYMin->GetNumber()+yBinWidth/2), yaxis->FindBin(fSldYMax->GetNumber()-yBinWidth/2)); fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst())); fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast())); } if (fCancel->GetState()==kButtonDisabled) fCancel->SetState(kButtonUp); if (fApply->GetState()==kButtonDisabled) fApply->SetState(kButtonUp); Update(); delete [] divx; delete [] divy; } // fGedEditor->GetPad()->GetCanvas()->Selected(fGedEditor->GetPad(), fHist, 0); // fModel = fHist; Refresh(fHist); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the rebin slider in case of no ntuple histogram. void TH2Editor::DoBinPressed() { if (fAvoidSignal) return; Int_t* divx = Dividers(fHist->GetXaxis()->GetNbins()); Int_t* divy = Dividers(fHist->GetYaxis()->GetNbins()); if (divx[0]==2 && divy[0]==2 && !fBinHist) new TGMsgBox(fClient->GetDefaultRoot(), this->GetMainFrame(), "TH2Editor", "It is not possible to rebin the histogram", kMBIconExclamation, kMBOk, 0, kVerticalFrame); // calling the MessageBox again does NOT work!*/ delete [] divx; delete [] divy; } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the rebin sliders in case of no ntuple histogram /// does the rebinning of the selected histogram. void TH2Editor::DoBinMoved() { // create a clone in the background, when the slider is moved for 1st time if (fAvoidSignal) return; if (!fBinHist /*&& fDelaydraw->GetState()!=kButtonDown*/) { Int_t* divx = Dividers(fHist->GetXaxis()->GetNbins()); Int_t* divy = Dividers(fHist->GetYaxis()->GetNbins()); // if there is nothing to rebin: if (divx[0]==2 && divy[0]==2) { delete [] divx; delete [] divy; return; } fBinHist = (TH2*)fHist->Clone("BinHist"); fBinHist->SetDirectory(0); // TH2Editor manages this histogram delete [] divx; delete [] divy; } // if the slider already has been moved and the clone is saved Int_t nx = fBinHist->GetXaxis()->GetNbins(); Int_t ny = fBinHist->GetYaxis()->GetNbins(); Int_t numx = fBinXSlider->GetPosition(); Int_t numy = fBinYSlider->GetPosition(); if (nx < 1 || ny < 1) return; Int_t* divx = Dividers(nx); Int_t* divy = Dividers(ny); if (divx[0]==2) { fBinXSlider->SetPosition(2); numx=1; } if (divy[0]==2) { fBinYSlider->SetPosition(2); numy=1; } Int_t maxx = (Int_t)nx/divx[numx]; Int_t maxy = (Int_t)ny/divy[numy]; if (maxx==1) maxx=2; if (maxy==1) maxy=2; if (fDelaydraw->GetState()==kButtonUp){ // delete the histogram which is on the screen fGedEditor->GetPad()->cd(); fHist->Reset(); fHist->SetBins(nx,fBinHist->GetXaxis()->GetXmin(), fBinHist->GetXaxis()->GetXmax(), ny,fBinHist->GetYaxis()->GetXmin(), fBinHist->GetYaxis()->GetXmax()); fHist->Add(fBinHist); fHist->SetCanExtend(TH1::kNoAxis); fHist->Rebin2D(divx[numx], divy[numy]); //fModel=fHist; if (divx[0]!=2) { TAxis* xaxis = fHist->GetXaxis(); Double_t xBinWidth = xaxis->GetBinWidth(1); // if the user has zoomed into a special area the range will be reset: xaxis->SetRangeUser(fSldXMin->GetNumber()+xBinWidth/2, fSldXMax->GetNumber()-xBinWidth/2); fSliderX->SetRange(1,maxx); fSliderX->SetPosition(xaxis->FindBin(fSldXMin->GetNumber()+xBinWidth/2), xaxis->FindBin(fSldXMax->GetNumber()-xBinWidth/2)); // the axis range could be changed a little bit by the Rebin algorithm fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fClient->NeedRedraw(fBinXSlider,kTRUE); } if (divy[0]!=2) { TAxis* yaxis = fHist->GetYaxis(); Double_t yBinWidth = yaxis->GetBinWidth(1); yaxis->SetRangeUser(fSldYMin->GetNumber()+yBinWidth/2, fSldYMax->GetNumber()-yBinWidth/2); fSliderY->SetRange(1,maxy); fSliderY->SetPosition(yaxis->FindBin(fSldYMin->GetNumber()+yBinWidth/2), yaxis->FindBin(fSldYMax->GetNumber()-yBinWidth/2)); fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst())); fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast())); fClient->NeedRedraw(fBinYSlider,kTRUE); } Update(); } // set the according NumberEntries if (fCancel->GetState()==kButtonDisabled) fCancel->SetState(kButtonUp); if (fApply->GetState()==kButtonDisabled) fApply->SetState(kButtonUp); fBinXNumberEntry->SetNumber(maxx); fBinYNumberEntry->SetNumber(maxy); delete [] divx; delete [] divy; } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the Bin Number Entry for the Rebin. void TH2Editor::DoBinLabel() { if (fAvoidSignal) return; Int_t i; Int_t numx = (Int_t)(fBinXNumberEntry->GetNumber()); Int_t numy = (Int_t)(fBinYNumberEntry->GetNumber()); Int_t nx = 0; if (fBinHist) nx = fBinHist->GetXaxis()->GetNbins(); else nx = fHist->GetXaxis()->GetNbins(); Int_t ny = 0; if (fBinHist) ny = fBinHist->GetYaxis()->GetNbins(); else ny = fHist->GetYaxis()->GetNbins(); if (nx < 2 || ny < 2) return; // Get the divider of nx/ny which is closest to numx/numy Int_t *divx = Dividers(nx); Int_t *divy = Dividers(ny); Int_t diff = TMath::Abs(numx - divx[1]); Int_t c = 1; Int_t d = 1; for (i = 2; i <= divx[0]; i++) { if ((TMath::Abs(numx - divx[i])) < diff) { c = i; diff = TMath::Abs(numx - divx[i]); } } diff = TMath::Abs(numy - divy[1]); for (i = 2; i <= divy[0]; i++) { if ((TMath::Abs(numy - divy[i])) < diff) { d = i; diff = TMath::Abs(numy - divy[i]); } } if (divx[c]!= fHist->GetXaxis()->GetNbins() || divy[d]!= fHist->GetYaxis()->GetNbins()) { fBinXNumberEntry->SetNumber(divx[c]); fBinXSlider->SetPosition(divx[0] - c +1); fBinYNumberEntry->SetNumber(divy[d]); fBinYSlider->SetPosition(divy[0] - d +1); if (fDelaydraw->GetState()==kButtonUp) DoBinMoved(); else DoBinReleased(); } // fGedEditor->GetPad()->GetCanvas()->Selected(fGedEditor->GetPad(), fHist, 0); // fModel = fHist; Refresh(fHist); delete [] divx; delete [] divy; } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the Apply Button in the Rebinned histogram Window. void TH2Editor::DoApply() { Int_t ret = 0; new TGMsgBox(fClient->GetDefaultRoot(), this->GetMainFrame(), "TH2 Editor", "Replace origin histogram with rebinned one?", kMBIconQuestion, kMBYes | kMBNo, &ret, kVerticalFrame); if (ret==1) { if (fBinHist) { delete fBinHist; fBinHist = 0; } Int_t nx = fHist->GetXaxis()->GetNbins(); Int_t ny = fHist->GetYaxis()->GetNbins(); Int_t *divx = Dividers(nx); Int_t *divy = Dividers(ny); Int_t upx = 0, upy = 0; if (divx[0]-1 <= 1) upx = 2; else upx = divx[0]-1; if (divy[0]-1 <= 1) upy = 2; else upy = divy[0]-1; fBinXSlider->SetRange(1,upx); fBinYSlider->SetRange(1,upy); if (fBinXSlider->GetMaxPosition()==2 && divx[0]==2 ) fBinXSlider->SetPosition(2); else fBinXSlider->SetPosition(1); if (fBinYSlider->GetMaxPosition()==2 && divy[0]==2 ) fBinYSlider->SetPosition(2); else fBinYSlider->SetPosition(1); fCancel->SetState(kButtonDisabled); fApply->SetState(kButtonDisabled); Update(); delete [] divx; delete [] divy; } else if (ret==2) DoCancel(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the Cancel Button in the Rebinned histogram Window. void TH2Editor::DoCancel() { if (fBinHist) { fGedEditor->GetPad()->cd(); fHist->Reset(); fHist->SetBins(fBinHist->GetXaxis()->GetNbins(), fBinHist->GetXaxis()->GetXmin(), fBinHist->GetXaxis()->GetXmax(), fBinHist->GetYaxis()->GetNbins(), fBinHist->GetYaxis()->GetXmin(), fBinHist->GetYaxis()->GetXmax()); fHist->Add(fBinHist); fHist->GetXaxis()->SetRange(fBinHist->GetXaxis()->GetFirst(), fBinHist->GetXaxis()->GetLast()); fHist->GetYaxis()->SetRange(fBinHist->GetYaxis()->GetFirst(), fBinHist->GetYaxis()->GetLast()); delete fBinHist; fBinHist = 0; fCancel->SetState(kButtonDisabled); fApply->SetState(kButtonDisabled); Int_t* divx = Dividers(fHist->GetXaxis()->GetNbins()); Int_t* divy = Dividers(fHist->GetYaxis()->GetNbins()); if (divx[0]!=2) fBinXSlider->SetPosition(1); if (divy[0]!=2) fBinYSlider->SetPosition(1); // Consigning the new Histogram to all other Editors // fGedEditor->GetPad()->GetCanvas()->Selected(fGedEditor->GetPad(), fHist, 0); Update(); // fModel = fHist; Refresh(fHist); delete [] divx; delete [] divy; } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the BinNumber Slider in case of a 'ntuple histogram'. /// It does the rebin. void TH2Editor::DoBinReleased1() { if (fAvoidSignal) return; Double_t oldXOffset = fXOffsetNumberEntry->GetNumber(); Int_t xnumber = fBinXSlider1->GetPosition(); Double_t oldYOffset = fYOffsetNumberEntry->GetNumber(); Int_t ynumber = fBinYSlider1->GetPosition(); if (xnumber==5 && ynumber==5) return; Int_t xfact = 0; Int_t yfact = 0; Int_t xBinNumber = 0; Int_t yBinNumber = 0; TAxis* xaxis = fHist->GetXaxis(); TAxis* yaxis = fHist->GetYaxis(); //"compute" the scaling factor: if (xnumber >= 5) xfact = xnumber - 4; else xfact = xnumber - 6; if (ynumber >= 5) yfact = ynumber - 4; else yfact = ynumber - 6; TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (!player) return; Int_t nx = xaxis->GetNbins(); Int_t ny = yaxis->GetNbins(); Int_t firstx = xaxis->GetFirst(); Int_t lastx = xaxis->GetLast(); Int_t firsty = yaxis->GetFirst(); Int_t lasty = yaxis->GetLast(); Double_t minx = xaxis->GetBinLowEdge(1); // overall min in user coords Double_t maxx = xaxis->GetBinUpEdge(nx); // overall max in user coords Double_t miny = yaxis->GetBinLowEdge(1); // overall min in user coords Double_t maxy = yaxis->GetBinUpEdge(ny); // overall max in user coords Double_t rminx = xaxis->GetBinLowEdge(firstx); // recent min in user coords Double_t rmaxx = xaxis->GetBinUpEdge(lastx); // recent max in user coords Double_t rminy = yaxis->GetBinLowEdge(firsty); // recent min in user coords Double_t rmaxy = yaxis->GetBinUpEdge(lasty); // recent max in user coords ((TH2*)player->GetHistogram())->SetCanExtend(TH1::kNoAxis); ((TH2*)player->GetHistogram())->Reset(); // Get new Number of bins if (xfact > 0) xBinNumber = xfact*nx; if (xfact < 0) xBinNumber = (Int_t) ((-1)*nx/xfact+0.5); if (xBinNumber < 1) xBinNumber = 1; if (xBinNumber > 1000) xBinNumber= 1000; if (yfact > 0) yBinNumber = yfact*ny; if (yfact < 0) yBinNumber = (Int_t) ((-1)*ny/yfact+0.5); if (yBinNumber < 1) yBinNumber = 1; if (yBinNumber > 1000) yBinNumber= 1000; Double_t xOffset = 1.*fXBinOffsetSld->GetPosition()/100*((maxx-minx)/xBinNumber); Double_t yOffset = 1.*fYBinOffsetSld->GetPosition()/100*((maxy-miny)/yBinNumber); // create new histogram - the main job is done by sel->TakeAction() ((TH2*)player->GetHistogram())->SetBins(xBinNumber, minx-oldXOffset+xOffset, maxx-oldXOffset+xOffset, yBinNumber, miny-oldYOffset+yOffset, maxy-oldYOffset+yOffset); TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector(); if (!sel) return; sel->TakeAction(); // Restore and set all the attributes which were changed by TakeAction() fHist = (TH2*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram(); fSliderX->SetRange(1,xBinNumber); fSliderY->SetRange(1,yBinNumber); Double_t xBinWidth = xaxis->GetBinWidth(1); Double_t yBinWidth = yaxis->GetBinWidth(1); fSliderX->SetPosition(xaxis->FindBin(rminx+xBinWidth/2), xaxis->FindBin(rmaxx-xBinWidth/2)); fSliderY->SetPosition(yaxis->FindBin(rminy+yBinWidth/2), yaxis->FindBin(rmaxy-yBinWidth/2)); xOffset = 1.*fXBinOffsetSld->GetPosition()/100*xBinWidth; // nessesary ?? yOffset = 1.*fYBinOffsetSld->GetPosition()/100*yBinWidth; // nessesary ?? // SetRange in BinNumbers along x and y! xaxis->SetRange(xaxis->FindBin(rminx+xBinWidth/2), xaxis->FindBin(rmaxx-xBinWidth/2)); yaxis->SetRange(yaxis->FindBin(rminy+yBinWidth/2), yaxis->FindBin(rmaxy-yBinWidth/2)); fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst())); fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast())); fBinXNumberEntry1->SetNumber(xaxis->GetLast() - xaxis->GetFirst()+1); fBinYNumberEntry1->SetNumber(yaxis->GetLast() - yaxis->GetFirst()+1); fBinXSlider1->SetPosition(5); fBinYSlider1->SetPosition(5); fXOffsetNumberEntry->SetNumber(xOffset); fYOffsetNumberEntry->SetNumber(yOffset); fXOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, xaxis->GetBinWidth(1)); fYOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, yaxis->GetBinWidth(1)); fClient->NeedRedraw(fBinXSlider1, kTRUE); // when you 2-clicks on a slider, sometimes it gets caught on wrong position! (2 or -2) fClient->NeedRedraw(fBinYSlider1, kTRUE); // when you 2-clicks on a slider, sometimes it gets caught on wrong position! (2 or -2) Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the rebin slider in case of an ntuple histogram. /// Updates the BinNumberEntryField during the BinSlider movement. void TH2Editor::DoBinMoved1() { if (fAvoidSignal) return; TAxis* xaxis = fHist->GetXaxis(); TAxis* yaxis = fHist->GetYaxis(); Int_t firstx = xaxis->GetFirst(); Int_t lastx = xaxis->GetLast(); Int_t firsty = yaxis->GetFirst(); Int_t lasty = yaxis->GetLast(); Int_t xnumber = fBinXSlider1->GetPosition(); Int_t ynumber = fBinYSlider1->GetPosition(); Int_t numx = lastx-firstx+1; Int_t numy = lasty-firsty+1; Int_t xfact = 0; Int_t yfact = 0; Int_t xBinNumber = 0; Int_t yBinNumber = 0; if (xnumber >= 5) xfact = xnumber - 4; else xfact = xnumber - 6; if (xfact > 0) xBinNumber = xfact*numx; if (xfact < 0) xBinNumber = (Int_t) ((-1)*numx/xfact+0.5); if (xBinNumber < 1) xBinNumber = 1; if (xBinNumber > 1000) xBinNumber= 1000; if (fBinXNumberEntry1->GetNumber()!=xBinNumber) fBinXNumberEntry1->SetIntNumber(xBinNumber); if (ynumber >= 5) yfact = ynumber - 4; else yfact = ynumber - 6; if (yfact > 0) yBinNumber = yfact*numy; if (yfact < 0) yBinNumber = (Int_t) ((-1)*numy/yfact+0.5); if (yBinNumber < 1) yBinNumber = 1; if (yBinNumber > 1000) yBinNumber= 1000; if (fBinYNumberEntry1->GetNumber()!=yBinNumber) fBinYNumberEntry1->SetIntNumber(yBinNumber); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the Bin Number Entry for the Rebin. void TH2Editor::DoBinLabel1() { if (fAvoidSignal) return; Double_t oldXOffset = fXOffsetNumberEntry->GetNumber(); Int_t numx = (Int_t)fBinXNumberEntry1->GetNumber(); Double_t oldYOffset = fYOffsetNumberEntry->GetNumber(); Int_t numy = (Int_t)fBinYNumberEntry1->GetNumber(); TAxis* xaxis = fHist->GetXaxis(); TAxis* yaxis = fHist->GetYaxis(); TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (!player) return; Int_t firstx = xaxis->GetFirst(); Int_t lastx = xaxis->GetLast(); Int_t firsty = yaxis->GetFirst(); Int_t lasty = yaxis->GetLast(); Int_t nx = xaxis->GetNbins(); Int_t ny = yaxis->GetNbins(); Double_t minx = xaxis->GetBinLowEdge(1); // overall min in user coords Double_t maxx = xaxis->GetBinUpEdge(nx); // overall max in user coords Double_t miny = yaxis->GetBinLowEdge(1); // overall min in user coords Double_t maxy = yaxis->GetBinUpEdge(ny); // overall max in user coords Double_t rminx = xaxis->GetBinLowEdge(firstx); // recent min in user coords Double_t rmaxx = xaxis->GetBinUpEdge(lastx); // recent max in user coords Double_t rminy = yaxis->GetBinLowEdge(firsty); // recent min in user coords Double_t rmaxy = yaxis->GetBinUpEdge(lasty); // recent max in user coords ((TH2*)player->GetHistogram())->SetCanExtend(TH1::kNoAxis); ((TH2*)player->GetHistogram())->Reset(); // Calculate the new number of bins in the complete range Int_t xBinNumber = (Int_t) ((maxx-minx)/(rmaxx - rminx)*numx + 0.5); if (xBinNumber < 1) xBinNumber = 1; if (xBinNumber > 1000) xBinNumber= 1000; Double_t xOffset = 1.*(fXBinOffsetSld->GetPosition())/100*(maxx-minx)/xBinNumber; Int_t yBinNumber = (Int_t) ((maxy-miny)/(rmaxy - rminy)*numy + 0.5); if (yBinNumber < 1) yBinNumber = 1; if (yBinNumber > 1000) yBinNumber= 1000; Double_t yOffset = 1.*(fYBinOffsetSld->GetPosition())/100*(maxy-miny)/yBinNumber; // create new histogram - the main job is done by sel->TakeAction() ((TH2*)player->GetHistogram())->SetBins(xBinNumber, minx-oldXOffset+xOffset, maxx-oldXOffset+xOffset, yBinNumber, miny-oldYOffset+yOffset, maxy-oldYOffset+yOffset); TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector(); if (!sel) return; sel->TakeAction(); // Restore and set all the attributes which were changed by TakeAction() fHist = (TH2*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram(); fSliderX->SetRange(1,xBinNumber); fSliderY->SetRange(1,yBinNumber); Double_t xBinWidth = xaxis->GetBinWidth(1); Double_t yBinWidth = yaxis->GetBinWidth(1); fSliderX->SetPosition(xaxis->FindBin(rminx+xBinWidth/2), xaxis->FindBin(rmaxx-xBinWidth/2)); fSliderY->SetPosition(yaxis->FindBin(rminy+yBinWidth/2), yaxis->FindBin(rmaxy-yBinWidth/2)); xOffset = 1.*fXBinOffsetSld->GetPosition()/100*xBinWidth; //nesessary ?? yOffset = 1.*fYBinOffsetSld->GetPosition()/100*yBinWidth; //nesessary ?? // SetRange in BinNumbers along x and y! xaxis->SetRange(xaxis->FindBin(rminx+xBinWidth/2), xaxis->FindBin(rmaxx-xBinWidth/2)); yaxis->SetRange(yaxis->FindBin(rminy+yBinWidth/2), yaxis->FindBin(rmaxy-yBinWidth/2)); fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst())); fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast())); fXOffsetNumberEntry->SetNumber(xOffset); fXOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax,0,xBinWidth); fYOffsetNumberEntry->SetNumber(yOffset); fYOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax,0,yBinWidth); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the OffSetSlider. It saves the OldBinOffset /// (nessesary for delay draw mode). void TH2Editor::DoOffsetPressed() { if (fAvoidSignal) return; fOldXOffset = fXOffsetNumberEntry->GetNumber(); fOldYOffset = fYOffsetNumberEntry->GetNumber(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the OffSetSlider that /// changes the origin of the histogram inbetween a binwidth; /// rebin the histogram with the new Offset given by the slider. /// problem: histogram with variable binwidth?? void TH2Editor::DoOffsetReleased() { if (fAvoidSignal) return; if (fDelaydraw->GetState()==kButtonDown){ Int_t numx = (Int_t)fXBinOffsetSld->GetPosition(); Int_t numy = (Int_t)fYBinOffsetSld->GetPosition(); TAxis* xaxis = fHist->GetXaxis(); TAxis* yaxis = fHist->GetYaxis(); Double_t xBinWidth = xaxis->GetBinWidth(1); Double_t yBinWidth = yaxis->GetBinWidth(1); Double_t xOffset = 1.*numx/100*xBinWidth; Double_t yOffset = 1.*numy/100*yBinWidth; Double_t oldXOffset = fOldXOffset; Double_t oldYOffset = fOldYOffset; Int_t nx = xaxis->GetNbins(); Int_t ny = yaxis->GetNbins(); TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (!player) return; Int_t firstx = xaxis->GetFirst(); Int_t lastx = xaxis->GetLast(); Int_t firsty = yaxis->GetFirst(); Int_t lasty = yaxis->GetLast(); Double_t minx = xaxis->GetBinLowEdge(1); // overall min in user coords Double_t maxx = xaxis->GetBinUpEdge(nx); // overall max in user coords Double_t miny = yaxis->GetBinLowEdge(1); // overall min in user coords Double_t maxy = yaxis->GetBinUpEdge(ny); // overall max in user coords Double_t rminx = xaxis->GetBinLowEdge(firstx); // recent min in user coords Double_t rmaxx = xaxis->GetBinUpEdge(lastx); // recent max in user coords Double_t rminy = yaxis->GetBinLowEdge(firsty); // recent min in user coords Double_t rmaxy = yaxis->GetBinUpEdge(lasty); // recent max in user coords ((TH2*)player->GetHistogram())->SetCanExtend(TH1::kNoAxis); ((TH2*)player->GetHistogram())->Reset(); ((TH2*)player->GetHistogram())->SetBins(nx, minx-oldXOffset+xOffset, maxx-oldXOffset+xOffset, ny, miny-oldYOffset+yOffset, maxy-oldYOffset+yOffset); TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector(); if (!sel) return; sel->TakeAction(); // Restore all the attributes which were changed by TakeAction() fHist = (TH2*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram(); // SetRange in BinNumbers along x and y! xaxis->SetRange(xaxis->FindBin(rminx+xOffset-oldXOffset+xBinWidth/2), xaxis->FindBin(rmaxx+xOffset-oldXOffset-xBinWidth/2)); yaxis->SetRange(yaxis->FindBin(rminy+yOffset-oldYOffset+yBinWidth/2), yaxis->FindBin(rmaxy+yOffset-oldYOffset-yBinWidth/2)); fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst())); fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast())); fXOffsetNumberEntry->SetNumber(xOffset); fYOffsetNumberEntry->SetNumber(yOffset); Update(); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the OffSetSlider. /// It changes the origin of the histogram inbetween a binwidth; /// rebin the histogram with the new offset given by the slider. /// problem: histogram with variable binwidth?? void TH2Editor::DoOffsetMoved() { if (fAvoidSignal) return; Int_t numx = (Int_t)fXBinOffsetSld->GetPosition(); Int_t numy = (Int_t)fYBinOffsetSld->GetPosition(); TAxis* xaxis = fHist->GetXaxis(); TAxis* yaxis = fHist->GetYaxis(); Double_t xBinWidth = xaxis->GetBinWidth(1); Double_t yBinWidth = yaxis->GetBinWidth(1); Double_t xOffset = 1.*numx/100*xBinWidth; Double_t yOffset = 1.*numy/100*yBinWidth; if (fDelaydraw->GetState()==kButtonUp){ Double_t oldXOffset = fXOffsetNumberEntry->GetNumber(); Double_t oldYOffset = fYOffsetNumberEntry->GetNumber(); Int_t nx = xaxis->GetNbins(); Int_t ny = yaxis->GetNbins(); TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (!player) return; Int_t firstx = xaxis->GetFirst(); Int_t lastx = xaxis->GetLast(); Int_t firsty = yaxis->GetFirst(); Int_t lasty = yaxis->GetLast(); Double_t minx = xaxis->GetBinLowEdge(1); // overall min in user coords Double_t maxx = xaxis->GetBinUpEdge(nx); // overall max in user coords Double_t miny = yaxis->GetBinLowEdge(1); // overall min in user coords Double_t maxy = yaxis->GetBinUpEdge(ny); // overall max in user coords Double_t rminx = xaxis->GetBinLowEdge(firstx); // recent min in user coords Double_t rmaxx = xaxis->GetBinUpEdge(lastx); // recent max in user coords Double_t rminy = yaxis->GetBinLowEdge(firsty); // recent min in user coords Double_t rmaxy = yaxis->GetBinUpEdge(lasty); // recent max in user coords ((TH2*)player->GetHistogram())->SetCanExtend(TH1::kNoAxis); ((TH2*)player->GetHistogram())->Reset(); ((TH2*)player->GetHistogram())->SetBins(nx,minx-oldXOffset+xOffset, maxx-oldXOffset+xOffset, ny, miny-oldYOffset+yOffset, maxy-oldYOffset+yOffset); TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector(); if (!sel) return; sel->TakeAction(); // Restore all the attributes which were changed by TakeAction() fHist = (TH2*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram(); // SetRange in BinNumbers along x and y! xaxis->SetRange(xaxis->FindBin(rminx+xOffset-oldXOffset+xBinWidth/2), xaxis->FindBin(rmaxx+xOffset-oldXOffset-xBinWidth/2)); yaxis->SetRange(yaxis->FindBin(rminy+yOffset-oldYOffset+yBinWidth/2), yaxis->FindBin(rmaxy+yOffset-oldYOffset-yBinWidth/2)); fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst())); fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast())); fClient->NeedRedraw(fXBinOffsetSld, kTRUE); fClient->NeedRedraw(fYBinOffsetSld, kTRUE); Update(); } fXOffsetNumberEntry->SetNumber(xOffset); fYOffsetNumberEntry->SetNumber(yOffset); fClient->NeedRedraw(fXOffsetNumberEntry, kTRUE); fClient->NeedRedraw(fYOffsetNumberEntry, kTRUE); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the OffSetNumberEntry, related to the OffSetSlider /// changes the origin of the histogram inbetween a binwidth. void TH2Editor::DoBinOffset() { if (fAvoidSignal) return; TAxis* xaxis = fHist->GetXaxis(); TAxis* yaxis = fHist->GetYaxis(); Double_t xBinWidth = xaxis->GetBinWidth(1); Double_t yBinWidth = yaxis->GetBinWidth(1); Double_t xOffset = fXOffsetNumberEntry->GetNumber(); Double_t oldXOffset = 1.*fXBinOffsetSld->GetPosition()/100*xBinWidth; Double_t yOffset = fYOffsetNumberEntry->GetNumber(); Double_t oldYOffset = 1.*fYBinOffsetSld->GetPosition()/100*yBinWidth; Int_t nx = xaxis->GetNbins(); Int_t ny = yaxis->GetNbins(); TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (!player) return; Int_t firstx = xaxis->GetFirst(); Int_t lastx = xaxis->GetLast(); Int_t firsty = yaxis->GetFirst(); Int_t lasty = yaxis->GetLast(); Double_t minx = xaxis->GetBinLowEdge(1); // overall min in user coords Double_t maxx = xaxis->GetBinUpEdge(nx); // overall max in user coords Double_t miny = yaxis->GetBinLowEdge(1); // overall min in user coords Double_t maxy = yaxis->GetBinUpEdge(ny); // overall max in user coords Double_t rminx = xaxis->GetBinLowEdge(firstx); // recent min in user coords Double_t rmaxx = xaxis->GetBinUpEdge(lastx); // recent max in user coords Double_t rminy = yaxis->GetBinLowEdge(firsty); // recent min in user coords Double_t rmaxy = yaxis->GetBinUpEdge(lasty); // recent max in user coords ((TH2*)player->GetHistogram())->SetCanExtend(TH1::kNoAxis); ((TH2*)player->GetHistogram())->Reset(); ((TH2*)player->GetHistogram())->SetBins(nx,minx+xOffset-oldXOffset, maxx+xOffset-oldXOffset, ny,miny+yOffset-oldYOffset, maxy+yOffset-oldYOffset); TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector(); if (!sel) return; sel->TakeAction(); // Restore all the attributes which were changed by TakeAction() fHist = (TH2*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram(); // SetRange in BinNumbers along x and y! xaxis->SetRange(xaxis->FindBin(rminx+xOffset-oldXOffset+xBinWidth/2), xaxis->FindBin(rmaxx+xOffset-oldXOffset-xBinWidth/2)); yaxis->SetRange(yaxis->FindBin(rminy+yOffset-oldYOffset+yBinWidth/2), yaxis->FindBin(rmaxy+yOffset-oldYOffset-yBinWidth/2)); fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fXBinOffsetSld->SetPosition((Int_t)(xOffset/xBinWidth*100)); fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst())); fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast())); fYBinOffsetSld->SetPosition((Int_t)(yOffset/yBinWidth*100)); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the x-Slider that redraws the histogram /// with the new slider range. void TH2Editor::DoSliderXMoved() { if (fAvoidSignal) return; TAxis* xaxis = fHist->GetXaxis(); if (fDelaydraw->GetState()==kButtonDown && fDim->GetState()==kButtonDown) { // 2D plot Int_t px1,py1,px2,py2; Float_t ymin,ymax,xleft,xright; xleft = xaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5)); xright = xaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5)); ymin = fGedEditor->GetPad()->GetUymin(); ymax = fGedEditor->GetPad()->GetUymax(); px1 = fGedEditor->GetPad()->XtoAbsPixel(xleft); py1 = fGedEditor->GetPad()->YtoAbsPixel(ymin); px2 = fGedEditor->GetPad()->XtoAbsPixel(xright); py2 = fGedEditor->GetPad()->YtoAbsPixel(ymax); if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE); fGedEditor->GetPad()->cd(); fGedEditor->GetPad()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); gVirtualX->DrawBox(fPx1old, fPy1old, fPx2old, fPy2old, TVirtualX::kHollow); gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow); fPx1old = px1; fPy1old = py1; fPx2old = px2 ; fPy2old = py2; gVirtualX->Update(0); fSldXMin->SetNumber(xleft); fSldXMax->SetNumber(xright); } else if (fDelaydraw->GetState()==kButtonDown && fDim0->GetState()==kButtonDown && fCoordsCombo->GetSelected()==kCOORDS_CAR) { // 3D plot Float_t p1[3], p2[3], p3[3], p4[3], p5[3], p6[3], p7[3], p8[3]; if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE); fGedEditor->GetPad()->cd(); TView *fView = fGedEditor->GetPad()->GetView(); if (!fView) return; Double_t *rmin = fView->GetRmin(); if (!rmin) return; Double_t *rmax = fView->GetRmax(); if (!rmax) return; p1[0] = p4[0] = p5[0] = p8[0] = xaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5)); p2[0] = p3[0] = p6[0] = p7[0] = xaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5)); p1[1] = p2[1] = p3[1] = p4[1] = rmin[1]; p5[1] = p6[1] = p7[1] = p8[1] = rmax[1]; p1[2] = p2[2] = p5[2] = p6[2] = rmin[2]; p3[2] = p4[2] = p7[2] = p8[2] = rmax[2]; fGedEditor->GetPad()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); PaintBox3D(fP2oldx, fP3oldx, fP7oldx, fP6oldx); PaintBox3D(fP1oldx, fP4oldx, fP8oldx, fP5oldx); PaintBox3D(p2, p3, p7, p6); PaintBox3D(p1, p4, p8, p5); for (Int_t i = 0; i<3; i++){ fP1oldx[i] = p1[i]; fP2oldx[i] = p2[i]; fP3oldx[i] = p3[i]; fP4oldx[i] = p4[i]; fP5oldx[i] = p5[i]; fP6oldx[i] = p6[i]; fP7oldx[i] = p7[i]; fP8oldx[i] = p8[i]; } fSldXMin->SetNumber(p1[0]); fSldXMax->SetNumber(p2[0]); } else if (fDelaydraw->GetState()==kButtonDown && fDim0->GetState()==kButtonDown) { fSldXMin->SetNumber(xaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5))); fSldXMax->SetNumber(xaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5))); } else { fHist->GetXaxis()->SetRange((Int_t)((fSliderX->GetMinPosition())+0.5), (Int_t)((fSliderX->GetMaxPosition())+0.5)); fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fClient->NeedRedraw(fSliderX,kTRUE); Update(); } fClient->NeedRedraw(fSldXMin,kTRUE); fClient->NeedRedraw(fSldXMax,kTRUE); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the x axis range slider that initialises /// the "virtual" box which is drawn in delay draw mode. void TH2Editor::DoSliderXPressed() { if (fAvoidSignal) return; TAxis* xaxis = fHist->GetXaxis(); Float_t ymin,ymax,xleft,xright; if (fDelaydraw->GetState()==kButtonDown && fDim->GetState()==kButtonDown) { // 2D Plot if (!fGedEditor->GetPad()) return; fGedEditor->GetPad()->cd(); if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kFALSE); fGedEditor->GetPad()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); xleft = xaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5)); xright = xaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5)); ymin = fGedEditor->GetPad()->GetUymin(); ymax = fGedEditor->GetPad()->GetUymax(); fPx1old = fGedEditor->GetPad()->XtoAbsPixel(xleft); fPy1old = fGedEditor->GetPad()->YtoAbsPixel(ymin); fPx2old = fGedEditor->GetPad()->XtoAbsPixel(xright); fPy2old = fGedEditor->GetPad()->YtoAbsPixel(ymax); gVirtualX->DrawBox(fPx1old, fPy1old, fPx2old, fPy2old, TVirtualX::kHollow); } else if (fDelaydraw->GetState()==kButtonDown && fDim0->GetState()==kButtonDown && fCoordsCombo->GetSelected()==kCOORDS_CAR) { // 3D plot if (!fGedEditor->GetPad()) return; fGedEditor->GetPad()->cd(); TView *fView = fGedEditor->GetPad()->GetView(); if (!fView) return; Double_t *rmin = fView->GetRmin(); if (!rmin) return; Double_t *rmax = fView->GetRmax(); if (!rmax) return; fP1oldx[0] = fP4oldx[0] = fP5oldx[0] = fP8oldx[0] = xaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5)); fP2oldx[0] = fP3oldx[0] = fP6oldx[0] = fP7oldx[0] = xaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5)); fP1oldx[1] = fP2oldx[1] = fP3oldx[1] = fP4oldx[1] = rmin[1]; fP5oldx[1] = fP6oldx[1] = fP7oldx[1] = fP8oldx[1] = rmax[1]; fP1oldx[2] = fP2oldx[2] = fP5oldx[2] = fP6oldx[2] = rmin[2]; fP3oldx[2] = fP4oldx[2] = fP7oldx[2] = fP8oldx[2] = rmax[2]; if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE); fGedEditor->GetPad()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); PaintBox3D(fP2oldx, fP3oldx, fP7oldx, fP6oldx); PaintBox3D(fP1oldx, fP4oldx, fP8oldx, fP5oldx); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the x-axis slider finalizing values after /// the slider movement. void TH2Editor::DoSliderXReleased() { if (fAvoidSignal) return; if (fDelaydraw->GetState()==kButtonDown) { fHist->GetXaxis()->SetRange((Int_t)((fSliderX->GetMinPosition())+0.5), (Int_t)((fSliderX->GetMaxPosition())+0.5)); fSldXMin->SetNumber(fHist->GetXaxis()->GetBinLowEdge(fHist->GetXaxis()->GetFirst())); fSldXMax->SetNumber(fHist->GetXaxis()->GetBinUpEdge(fHist->GetXaxis()->GetLast())); Update(); } TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (player) if (player->GetHistogram() == fHist) { Int_t last = fHist->GetXaxis()->GetLast(); Int_t first = fHist->GetXaxis()->GetFirst(); fBinXNumberEntry1->SetIntNumber(last-first+1); Update(); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the Max/Min number entry fields showing x-axis range. void TH2Editor::DoXAxisRange() { TAxis* xaxis = fHist->GetXaxis(); Int_t nx = xaxis->GetNbins(); Double_t width = xaxis->GetBinWidth(1); if ((fSldXMin->GetNumber()+width/2) < (xaxis->GetBinLowEdge(1))) fSldXMin->SetNumber(xaxis->GetBinLowEdge(1)); if ((fSldXMax->GetNumber()-width/2) > (xaxis->GetBinUpEdge(nx))) fSldXMax->SetNumber(xaxis->GetBinUpEdge(nx)); xaxis->SetRangeUser(fSldXMin->GetNumber()+width/2, fSldXMax->GetNumber()-width/2); Int_t nxbinmin = xaxis->GetFirst(); Int_t nxbinmax = xaxis->GetLast(); fSliderX->SetPosition((Double_t)(nxbinmin),(Double_t)(nxbinmax)); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the x-slider for redrawing the /// histogram with the new slider Range (immediately). void TH2Editor::DoSliderYMoved() { if (fAvoidSignal) return; TAxis* yaxis = fHist->GetYaxis(); if (fDelaydraw->GetState()==kButtonDown && fDim->GetState()==kButtonDown) { Int_t px1,py1,px2,py2; Float_t xmin,xmax,ybottom,ytop; ybottom = yaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5)); ytop = yaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5)); xmin = fGedEditor->GetPad()->GetUxmin(); xmax = fGedEditor->GetPad()->GetUxmax(); px1 = fGedEditor->GetPad()->XtoAbsPixel(xmin); py1 = fGedEditor->GetPad()->YtoAbsPixel(ybottom); px2 = fGedEditor->GetPad()->XtoAbsPixel(xmax); py2 = fGedEditor->GetPad()->YtoAbsPixel(ytop); if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE); fGedEditor->GetPad()->cd(); fGedEditor->GetPad()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); gVirtualX->DrawBox(fPx1old, fPy1old, fPx2old, fPy2old, TVirtualX::kHollow); gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow); fPx1old = px1; fPy1old = py1; fPx2old = px2 ; fPy2old = py2; gVirtualX->Update(0); fSldYMin->SetNumber(ybottom); fSldYMax->SetNumber(ytop); } else if (fDelaydraw->GetState()==kButtonDown && fDim0->GetState()==kButtonDown && fCoordsCombo->GetSelected()==kCOORDS_CAR) { // 3D plot Float_t p1[3], p2[3], p3[3], p4[3], p5[3], p6[3], p7[3], p8[3]; if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE); fGedEditor->GetPad()->cd(); TView *fView = fGedEditor->GetPad()->GetView(); if (!fView) return; Double_t *rmin = fView->GetRmin(); if (!rmin) return; Double_t *rmax = fView->GetRmax(); if (!rmax) return; p1[0] = p2[0] = p3[0] = p4[0] = rmin[0]; p5[0] = p6[0] = p7[0] = p8[0] = rmax[0]; p1[1] = p4[1] = p5[1] = p8[1] = yaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5)); p2[1] = p3[1] = p6[1] = p7[1] = yaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5)); p1[2] = p2[2] = p5[2] = p6[2] = rmin[2]; p3[2] = p4[2] = p7[2] = p8[2] = rmax[2]; fGedEditor->GetPad()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); PaintBox3D(fP2oldy, fP3oldy, fP7oldy, fP6oldy); PaintBox3D(fP1oldy, fP4oldy, fP8oldy, fP5oldy); PaintBox3D(p2, p3, p7, p6); PaintBox3D(p1, p4, p8, p5); for (Int_t i = 0; i<3; i++) { fP1oldy[i] = p1[i]; fP2oldy[i] = p2[i]; fP3oldy[i] = p3[i]; fP4oldy[i] = p4[i]; fP5oldy[i] = p5[i]; fP6oldy[i] = p6[i]; fP7oldy[i] = p7[i]; fP8oldy[i] = p8[i]; } fSldYMin->SetNumber(p1[1]); fSldYMax->SetNumber(p2[1]); } else if (fDelaydraw->GetState()==kButtonDown && fDim0->GetState()==kButtonDown) { fSldYMin->SetNumber(yaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5))); fSldYMax->SetNumber(yaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5))); } else { yaxis->SetRange((Int_t)((fSliderY->GetMinPosition())+0.5), (Int_t)((fSliderY->GetMaxPosition())+0.5)); fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst())); fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast())); fClient->NeedRedraw(fSliderY,kTRUE); Update(); } fClient->NeedRedraw(fSldYMin,kTRUE); fClient->NeedRedraw(fSldYMax,kTRUE); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to y-axis slider which initialises /// the "virtual" box which is drawn in delay draw mode. void TH2Editor::DoSliderYPressed() { if (fAvoidSignal) return; TAxis* yaxis = fHist->GetYaxis(); Float_t xmin,xmax,ytop,ybottom; if (fDelaydraw->GetState()==kButtonDown && fDim->GetState()==kButtonDown) { // 2D plot: if (!fGedEditor->GetPad()) return; fGedEditor->GetPad()->cd(); if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kFALSE); fGedEditor->GetPad()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); ybottom = yaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5)); ytop = yaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5)); xmin = fGedEditor->GetPad()->GetUxmin(); xmax = fGedEditor->GetPad()->GetUxmax(); fPx1old = fGedEditor->GetPad()->XtoAbsPixel(xmin); fPy1old = fGedEditor->GetPad()->YtoAbsPixel(ybottom); fPx2old = fGedEditor->GetPad()->XtoAbsPixel(xmax); fPy2old = fGedEditor->GetPad()->YtoAbsPixel(ytop); gVirtualX->DrawBox(fPx1old, fPy1old, fPx2old, fPy2old, TVirtualX::kHollow); } else if (fDelaydraw->GetState()==kButtonDown && fDim0->GetState()==kButtonDown && fCoordsCombo->GetSelected()==kCOORDS_CAR) { // 3D plot if (!fGedEditor->GetPad()) return; fGedEditor->GetPad()->cd(); TView *fView = fGedEditor->GetPad()->GetView(); if (!fView) return; Double_t *rmin = fView->GetRmin(); if (!rmin) return; Double_t *rmax = fView->GetRmax(); if (!rmax) return; fP1oldy[0] = fP2oldy[0] = fP3oldy[0] = fP4oldy[0] = rmin[0]; fP5oldy[0] = fP6oldy[0] = fP7oldy[0] = fP8oldy[0] = rmax[0]; fP1oldy[1] = fP4oldy[1] = fP5oldy[1] = fP8oldy[1] = yaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5)); fP2oldy[1] = fP3oldy[1] = fP6oldy[1] = fP7oldy[1] = yaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5)); fP1oldy[2] = fP2oldy[2] = fP5oldy[2] = fP6oldy[2] = rmin[2]; fP3oldy[2] = fP4oldy[2] = fP7oldy[2] = fP8oldy[2] = rmax[2]; if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE); fGedEditor->GetPad()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); PaintBox3D(fP2oldy, fP3oldy, fP7oldy, fP6oldy); PaintBox3D(fP1oldy, fP4oldy, fP8oldy, fP5oldy); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the y-axis slider finalizing values after /// the slider movement. void TH2Editor::DoSliderYReleased() { if (fAvoidSignal) return; if (fDelaydraw->GetState()==kButtonDown) { fHist->GetYaxis()->SetRange((Int_t)((fSliderY->GetMinPosition())+0.5), (Int_t)((fSliderY->GetMaxPosition())+0.5)); fSldYMin->SetNumber(fHist->GetYaxis()->GetBinLowEdge(fHist->GetYaxis()->GetFirst())); fSldYMax->SetNumber(fHist->GetYaxis()->GetBinUpEdge(fHist->GetYaxis()->GetLast())); Update(); } TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (player) if (player->GetHistogram() == fHist) { Int_t last = fHist->GetYaxis()->GetLast(); Int_t first = fHist->GetYaxis()->GetFirst(); fBinYNumberEntry1->SetIntNumber(last-first+1); Update(); } } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the Max/Min number entry fields showing y-axis range. void TH2Editor::DoYAxisRange() { if (fAvoidSignal) return; TAxis* yaxis = fHist->GetYaxis(); Int_t ny = yaxis->GetNbins(); Double_t width = yaxis->GetBinWidth(1); if ((fSldYMin->GetNumber()+width/2) < (yaxis->GetBinLowEdge(1))) fSldYMin->SetNumber(yaxis->GetBinLowEdge(1)); if ((fSldYMax->GetNumber()-width/2) > (yaxis->GetBinUpEdge(ny))) fSldYMax->SetNumber(yaxis->GetBinUpEdge(ny)); yaxis->SetRangeUser(fSldYMin->GetNumber()+width/2, fSldYMax->GetNumber()-width/2); Int_t nybinmin = yaxis -> GetFirst(); Int_t nybinmax = yaxis -> GetLast(); fSliderY->SetPosition((Double_t)(nybinmin),(Double_t)(nybinmax)); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the fill area color. void TH2Editor::DoFillColor(Pixel_t color) { if (fAvoidSignal || !fGedEditor->GetPad()) return; fGedEditor->GetPad()->cd(); fGedEditor->GetPad()->SetFrameFillColor(TColor::GetColor(color)); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Slot connected to the fill area pattern. void TH2Editor::DoFillPattern(Style_t pattern) { if (fAvoidSignal || !fGedEditor->GetPad()) return; fGedEditor->GetPad()->cd(); fGedEditor->GetPad()->SetFrameFillStyle(pattern); Update(); } //////////////////////////////////////////////////////////////////////////////// /// Return the immediate histogram type (HIST, LEGO1-4, SURF1-5). TString TH2Editor::GetHistTypeLabel() { TString s=""; switch (fTypeCombo->GetSelected()){ case (-1) : {s = ""; break;} case (kTYPE_LEGO ): {s = "LEGO"; break;} case (kTYPE_LEGO1): {s = "LEGO1"; break;} case (kTYPE_LEGO2): {s = "LEGO2"; break;} case (kTYPE_LEGO3): {s = "LEGO3"; break;} case (kTYPE_LEGO4): {s = "LEGO4"; break;} case (kTYPE_SURF ): {s = "SURF"; break;} case (kTYPE_SURF1): {s = "SURF1"; break;} case (kTYPE_SURF2): {s = "SURF2"; break;} case (kTYPE_SURF3): {s = "SURF3"; break;} case (kTYPE_SURF4): {s = "SURF4"; break;} case (kTYPE_SURF5): {s = "SURF5"; break;} default: break; } return s; } //////////////////////////////////////////////////////////////////////////////// /// Return the immediate coordinate system of the histogram. /// (POL, CYL, SPH,PSR) TString TH2Editor::GetHistCoordsLabel() { TString s=""; switch (fCoordsCombo->GetSelected()){ case (-1) : {s = ""; break;} case (kCOORDS_CAR): {s = ""; break;} case (kCOORDS_POL): {s = "POL"; break;} case (kCOORDS_CYL): {s = "CYL"; break;} case (kCOORDS_SPH): {s = "SPH"; break;} case (kCOORDS_PSR): {s = "PSR"; break;} default: break; } return s; } //////////////////////////////////////////////////////////////////////////////// /// Returns histogram contour option (None,Cont0..5). TString TH2Editor::GetHistContLabel() { TString s=""; switch (fContCombo->GetSelected()){ case (-1) : {s = ""; break;} case (kCONT_NONE) : {s = ""; break;} case (kCONT_0) : {s = "CONT0"; break;} case (kCONT_1) : {s = "CONT1"; break;} case (kCONT_2) : {s = "CONT2"; break;} case (kCONT_3) : {s = "CONT3"; break;} case (kCONT_4) : {s = "CONT4"; break;} default: break; } return s; } //////////////////////////////////////////////////////////////////////////////// /// Return histogram additive options (Arr,Box,Col,Scat,Col,Text,E,Z,FB,BB). TString TH2Editor::GetHistAdditiveLabel() { TString s=""; if (fDim->GetState()==kButtonDown) { if (fAddArr->GetState()==kButtonDown) s+="ARR"; if (fAddBox->GetState()==kButtonDown) s+="BOX"; if (fAddCol->GetState()==kButtonDown) s+="COL"; if (fAddScat->GetState()==kButtonDown) s+="SCAT"; if (fAddText->GetState()==kButtonDown) s+="TEXT"; if (fAddPalette->GetState()==kButtonDown) s+="Z"; } else if (fDim0->GetState()==kButtonDown){ if (fAddPalette1->GetState()==kButtonDown) s+="Z"; if (fAddError->GetState()==kButtonDown) s+="E"; if (fAddFB->GetState()==kButtonUp) s+="FB"; if (fAddBB->GetState()==kButtonUp) s+="BB"; } return s; } //////////////////////////////////////////////////////////////////////////////// /// Return draw option string related to graphical cut in use. TString TH2Editor::GetCutOptionString() { TString cutopt = " "; TString opt = GetDrawOption(); Int_t scut = opt.First('['); if (scut != -1) { Int_t ecut = opt.First(']'); cutopt += opt(scut,ecut); } return cutopt; } //////////////////////////////////////////////////////////////////////////////// /// Create histogram type combo box. TGComboBox* TH2Editor::BuildHistTypeComboBox(TGFrame* parent, Int_t id) { TGComboBox *c = new TGComboBox(parent, id); c->AddEntry("Lego" , kTYPE_LEGO); c->AddEntry("Lego1", kTYPE_LEGO1); c->AddEntry("Lego2", kTYPE_LEGO2); c->AddEntry("Lego3", kTYPE_LEGO3); c->AddEntry("Lego4", kTYPE_LEGO4); c->AddEntry("Surf" , kTYPE_SURF); c->AddEntry("Surf1", kTYPE_SURF1); c->AddEntry("Surf2", kTYPE_SURF2); c->AddEntry("Surf3", kTYPE_SURF3); c->AddEntry("Surf4", kTYPE_SURF4); c->AddEntry("Surf5", kTYPE_SURF5); return c; } //////////////////////////////////////////////////////////////////////////////// /// Create coordinate system combo box. TGComboBox* TH2Editor::BuildHistCoordsComboBox(TGFrame* parent, Int_t id) { TGComboBox *c = new TGComboBox(parent, id); c->AddEntry("Cartesian", kCOORDS_CAR); c->AddEntry("Cylindric", kCOORDS_CYL); c->AddEntry("Polar", kCOORDS_POL); c->AddEntry("Rapidity", kCOORDS_PSR); c->AddEntry("Spheric", kCOORDS_SPH); TGListBox* lb = c->GetListBox(); lb->Resize(lb->GetWidth(), 83); return c; } //////////////////////////////////////////////////////////////////////////////// /// Create contour combo box. TGComboBox* TH2Editor::BuildHistContComboBox(TGFrame* parent, Int_t id) { TGComboBox *c = new TGComboBox(parent, id); c->AddEntry("None" , kCONT_NONE); c->AddEntry("Cont0", kCONT_0); c->AddEntry("Cont1", kCONT_1); c->AddEntry("Cont2", kCONT_2); c->AddEntry("Cont3", kCONT_3); c->AddEntry("Cont4", kCONT_4); return c; } //////////////////////////////////////////////////////////////////////////////// /// Paint a square in 3D. void TH2Editor::PaintBox3D(Float_t *p1, Float_t *p2,Float_t *p3, Float_t *p4) { fGedEditor->GetPad()->PaintLine3D(p1, p2); fGedEditor->GetPad()->PaintLine3D(p2, p3); fGedEditor->GetPad()->PaintLine3D(p3, p4); fGedEditor->GetPad()->PaintLine3D(p4, p1); } //////////////////////////////////////////////////////////////////////////////// /// Give an array of dividers of n (without the trivial divider n)) /// in the first entry the number of dividers is saved. Int_t* TH2Editor::Dividers(Int_t n) { Int_t* div; if (n <= 0) { div = new Int_t[1]; div[0]=0; } else if (n == 1) { div = new Int_t[2]; div[0]=div[1]=1; } else { div = new Int_t[(Int_t) n/2+2]; div[0]=0; div[1]=1; Int_t num = 1; for (Int_t i=2; i <= n/2; i++) { if (n % i == 0) { num++; div[num] = i; } } num++; div[num]=n; div[0] = num; } return div; } //////////////////////////////////////////////////////////////////////////////// /// Skip TH1Editor in building list of editors. void TH2Editor::ActivateBaseClassEditors(TClass* /*cl*/) { fGedEditor->ActivateEditors(TH1::Class()->GetListOfBases(), kTRUE); } //////////////////////////////////////////////////////////////////////////////// /// If the contained histogram obj is deleted we must set its pointer to zero void TH2Editor::RecursiveRemove(TObject* obj) { if (obj == fHist) { fHist = 0; } }