// @(#)root/ged:$Id$ // Author: Carsten Hof 16/08/04 /************************************************************************* * 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. * *************************************************************************/ ////////////////////////////////////////////////////////////////////////// // // // TH1Editor // // Editor for changing TH1 histogram attributes, rebinning & fitting. // // For all possible draw options (there are a few which are not imple- // // mentable in 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 TH1Editor: // // 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: // // 'Error' : ComboBox: add different error bars to the histogram // // (no errors, simple, ..., see THistPainter::Paint // // 'Add' : ComboBox: further things which can be added to the // // histogram (None, simple/smooth line, fill area // // 'Simple Drawing': CheckBox: draw a simple histogram without // // errors (= "HIST" drawoption). In combination with // // some other draw options an outer line is drawn on // // top of the histogram // // 'Show markers': CheckBox: draw a marker on to of each bin (="P" // // drawoption) // // 'Draw bar chart': CheckBox: draw a bar chart (="B" drawoption) // // change the Fill Color with Fill in the Style Tab // // => will show Bar menue in the Style Tab // // 'Bar option': CheckBox: draw a bar chart (="BAR" drawoption) // // => will show Bar menue in the Style Tab // // 3d Plot: // // 'Type' : ComboBox: set histogram type Lego-Plot or Surface // // draw(Lego, Lego1.2, Surf, Surf1..5) // // see THistPainter::Paint // // 'Coords' : ComboBox: set the coordinate system (Cartesian, .. // // Spheric) see THistPainter::Paint // // 'Error' : see 2D plot // // 'Bar' : change the bar attributes // // 'W' : change Bar Width // // 'O' : change Bar Offset // // 'Percentage': specifies the percentage of the bar which is drawn// // brighter and darker (10% == BAR1 drawoption) // // 'Horizontal Bar': draw a horizontal bar chart // // // // 'Marker' : change the Marker attributes (color, appearance, // // thickness) see TAttMarkerEditor // //Begin_Html /* */ //End_Html // 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: // // TFile f("hsimple.root"); // // hpx->Draw("BAR1"); // non ntuple histogram // // ntuple->Draw("px"); // ntuple histogram // // Non ntuple histogram: // // 'Rebin': with the Slider 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 slider 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 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. // ////////////////////////////////////////////////////////////////////////// // //Begin_Html /* */ //End_Html //Begin_Html /* */ //End_Html #include "TH1Editor.h" #include "TH1.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 #include "TG3DLine.h" #include "TGDoubleSlider.h" #include "TGSlider.h" #include "TView.h" #include "TCanvas.h" #include "TTreePlayer.h" #include "TSelectorDraw.h" #include "TGMsgBox.h" #include "TGTab.h" #include "TROOT.h" ClassImp(TH1Editor) enum ETH1Wid{ kTH1_TITLE, kTYPE_HIST, kTYPE_LEGO, kTYPE_LEGO1, kTYPE_LEGO2, kTYPE_SURF, kTYPE_SURF1, kTYPE_SURF2, kTYPE_SURF3, kTYPE_SURF4, kTYPE_SURF5, kCOORDS_CAR, kCOORDS_CYL, kCOORDS_POL, kCOORDS_PSR, kCOORDS_SPH, kERRORS_NO, kERRORS_SIMPLE, kERRORS_EDGES, kERRORS_REC, kERRORS_FILL, kERRORS_CONTOUR, kHIST_TYPE, kCOORD_TYPE, kERROR_TYPE, kMARKER_ONOFF, kB_ONOFF, kBAR_ONOFF, kADD_TYPE, kADD_NONE, kADD_SIMPLE, kADD_SMOOTH, kADD_FILL, kADD_BAR, kADD_LINE, kDIM_SIMPLE, kDIM_COMPLEX, kPERCENT_TYPE, kPER_0, kPER_10, kPER_20, kPER_30, kPER_40, kBAR_H, kBAR_WIDTH, kBAR_OFFSET, kSLIDER_MAX, kSLIDER_MIN, kDELAYED_DRAWING, kBINSLIDER, kBINSLIDER1, kBINOFFSET }; //______________________________________________________________________________ TH1Editor::TH1Editor(const TGWindow *p, Int_t width, Int_t height, UInt_t options, Pixel_t back) : TGedFrame(p, width, height, options | kVerticalFrame, back), fHist(0), fSameOpt(kFALSE), fBin(0), fBinHist(0) { // Constructor of histogram attribute GUI. // TextEntry for changing the title of the histogram MakeTitle("Title"); fTitlePrec = 2; fTitle = new TGTextEntry(this, new TGTextBuffer(50), kTH1_TITLE); fTitle->Resize(135, fTitle->GetDefaultHeight()); fTitle->SetToolTipText("Enter the histogram title string"); AddFrame(fTitle, new TGLayoutHints(kLHintsLeft, 3, 1, 2, 5)); // Histogram draw options TGCompositeFrame *fHistLbl = new TGCompositeFrame(this, 145, 10, kHorizontalFrame | kLHintsExpandX | kFixedWidth | kOwnBackground); fHistLbl->AddFrame(new TGLabel(fHistLbl,"Histogram"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); fHistLbl->AddFrame(new TGHorizontal3DLine(fHistLbl), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 0)); AddFrame(fHistLbl, new TGLayoutHints(kLHintsTop,0,0,2,0)); // TGButtonGroup to change: 2D plot <-> 3D plot TGCompositeFrame *f2 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame); fDimGroup = new TGHButtonGroup(f2,"Plot"); fDimGroup->SetRadioButtonExclusive(); 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, 8)); // Set the type of histogram (Lego0..2, Surf0..5) for 3D plot f3 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame); AddFrame(f3, new TGLayoutHints(kLHintsTop, 1, 1, 0, 0)); TGCompositeFrame *f3a = new TGCompositeFrame(f3, 40, 20); f3->AddFrame(f3a, new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); TGLabel *fType = new TGLabel(f3a, "Add: "); f3a->AddFrame(fType, new TGLayoutHints(kLHintsLeft, 6, 1, 4, 4)); TGLabel *fCoords = new TGLabel(f3a, "Coords:"); f3a->AddFrame(fCoords, new TGLayoutHints(kLHintsLeft, 6, 1, 4, 1)); TGCompositeFrame *f3b = new TGCompositeFrame(f3, 40, 20); f3->AddFrame(f3b, new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); fTypeCombo = BuildHistTypeComboBox(f3b, kHIST_TYPE); f3b->AddFrame(fTypeCombo, new TGLayoutHints(kLHintsLeft, 3, 1, 2, 1)); fTypeCombo->Resize(80, 20); fTypeCombo->Associate(this); //Set the coordinate system (Cartesian, Spheric, ...) fCoordsCombo = BuildHistCoordsComboBox(f3b, kCOORD_TYPE); f3b->AddFrame(fCoordsCombo, new TGLayoutHints(kLHintsLeft, 3, 1, 2, 1)); fCoordsCombo->Resize(80, 20); fCoordsCombo->Associate(this); // Set the Error (No error, error1..5) TGCompositeFrame *f5 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame); AddFrame(f5, new TGLayoutHints(kLHintsTop, 1, 1, 0, 0)); TGCompositeFrame *f5a = new TGCompositeFrame(f5, 40, 20); f5->AddFrame(f5a, new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); TGLabel *fError = new TGLabel(f5a, "Error:"); f5a->AddFrame(fError, new TGLayoutHints(kLHintsLeft, 6, 2, 4, 1)); TGCompositeFrame *f5b = new TGCompositeFrame(f5, 40, 20); f5->AddFrame(f5b, new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); fErrorCombo = BuildHistErrorComboBox(f5b, kERROR_TYPE); f5b->AddFrame(fErrorCombo, new TGLayoutHints(kLHintsLeft, 15, 1, 2, 1)); fErrorCombo->Resize(80, 20); fErrorCombo->Associate(this); // Further draw options: Smooth/Simple Line, Fill Area for 2D plot f6 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame); AddFrame(f6, new TGLayoutHints(kLHintsTop, 1, 1, 0, 3)); TGCompositeFrame *f6a = new TGCompositeFrame(f6, 40, 20); f6->AddFrame(f6a, new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); TGLabel *fAddLabel = new TGLabel(f6a, "Style:"); f6a->AddFrame(fAddLabel, new TGLayoutHints(kLHintsLeft, 6, 2, 4, 1)); TGCompositeFrame *f6b = new TGCompositeFrame(f6, 40, 20); f6->AddFrame(f6b, new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); fAddCombo = BuildHistAddComboBox(f6b, kADD_TYPE); f6b->AddFrame(fAddCombo, new TGLayoutHints(kLHintsLeft, 15, 1, 2, 1)); fAddCombo->Resize(80, 20); fAddCombo->Associate(this); // option related to HIST: some changes needed here! // because of inconsistencies f15 = new TGCompositeFrame(this, 80, 20, kVerticalFrame); fAddSimple = new TGCheckButton(f15, "Simple Drawing", kADD_LINE); fAddSimple ->SetToolTipText("A simple histogram without errors is drawn (draw option: Hist)"); f15->AddFrame(fAddSimple, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 0)); AddFrame(f15, new TGLayoutHints(kLHintsTop, 1, 1, 0, -1)); // Show Marker Checkbox: draw marker (or not) f7 = new TGCompositeFrame(this, 80, 20, kVerticalFrame); fAddMarker = new TGCheckButton(f7, "Show markers", kMARKER_ONOFF); fAddMarker ->SetToolTipText("Make marker visible/invisible"); f7->AddFrame(fAddMarker, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 0)); AddFrame(f7, new TGLayoutHints(kLHintsTop, 1, 1, 2, 0)); // Bar Chart Checkbox: draw with option B f8 = new TGCompositeFrame(this, 80, 20, kVerticalFrame); fAddB = new TGCheckButton(f8, "Draw bar chart", kB_ONOFF); fAddB ->SetToolTipText("Draw a bar chart"); f8->AddFrame(fAddB, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 0)); AddFrame(f8, new TGLayoutHints(kLHintsTop, 1, 1, 0, 0)); // Bar CheckBox: draw with option BAR +option selected by // fPercentCombo (0..4) e.g. BAR2 f9 = new TGCompositeFrame(this, 80, 20, kVerticalFrame); fAddBar = new TGCheckButton(f9, "Bar option", kBAR_ONOFF); fAddBar ->SetToolTipText("Draw bar chart with bar-option"); f9->AddFrame(fAddBar, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 0)); AddFrame(f9, new TGLayoutHints(kLHintsTop, 1, 1, 0, 0)); // Bar Menu => appears when the BAR checkbox is set f10 = new TGCompositeFrame(this, 145, 10, kHorizontalFrame | kLHintsExpandX | kFixedWidth | kOwnBackground); f10->AddFrame(new TGLabel(f10,"Bar"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); f10->AddFrame(new TGHorizontal3DLine(f10), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); AddFrame(f10, new TGLayoutHints(kLHintsTop,0,0,6,4)); // NumberEntry to change the Bar Width f11 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame); TGLabel *fWidthLbl = new TGLabel(f11, "W:"); f11->AddFrame(fWidthLbl, new TGLayoutHints(kLHintsLeft, 1, 3, 4, 1)); fBarWidth = new TGNumberEntry(f11, 1.00, 6, kBAR_WIDTH, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0.01, 1.); fBarWidth->GetNumberEntry()->SetToolTipText("Set bin bar width"); fBarWidth->Resize(45,20); f11->AddFrame(fBarWidth, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 1)); // NumberEntry to change the Bar OFfset TGLabel *foffsetLbl = new TGLabel(f11, "O:"); f11->AddFrame(foffsetLbl, new TGLayoutHints(kLHintsLeft, 6,3, 4, 1)); fBarOffset = new TGNumberEntry(f11, 0.00, 5, kBAR_OFFSET, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -1., 1.); fBarOffset->GetNumberEntry()->SetToolTipText("Set bin bar offset"); fBarOffset->Resize(50,20); f11->AddFrame(fBarOffset, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 1)); AddFrame(f11, new TGLayoutHints(kLHintsTop, 1, 1, 0, 4)); // ComboBox which specifies the width of the Bar which should be drawn // in another color i.e. specifies the number in BAR option e.g. BAR2 f12 = new TGCompositeFrame(this, 80, 20, kVerticalFrame); TGCompositeFrame *f13 = new TGCompositeFrame(f12, 80, 20, kHorizontalFrame); TGLabel *percentLabel = new TGLabel(f13, "Percentage:"); f13->AddFrame(percentLabel, new TGLayoutHints(kLHintsLeft, 6, 1, 3, 1)); fPercentCombo = BuildPercentComboBox(f13, kPERCENT_TYPE); fPercentCombo->Resize(51, 20); fPercentCombo->Associate(f13); f13->AddFrame(fPercentCombo, new TGLayoutHints(kLHintsLeft, 14, 1, 2, 1)); f12->AddFrame(f13,new TGLayoutHints(kLHintsLeft, 0, 0, 0, 0)); // CHeckBox for horizontal drawing of the Histogram fMakeHBar = new TGCheckButton(f12, "Horizontal Bar", kBAR_H); fMakeHBar ->SetToolTipText("Draw a horizontal bar chart with hBar-Option"); f12->AddFrame(fMakeHBar, new TGLayoutHints(kLHintsLeft, 6, 1, 3, 0)); AddFrame(f12, new TGLayoutHints(kLHintsTop, 1, 1, 0, 0)); CreateBinTab(); // add itself in the least of cleanups to be notified when attached histogram is deleted gROOT->GetListOfCleanups()->Add(this); } //______________________________________________________________________________ void TH1Editor::CreateBinTab() { // Create binning tab. fBin = CreateEditorTabSubFrame("Binning"); TGCompositeFrame *title1 = new TGCompositeFrame(fBin, 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)); fBin->AddFrame(title1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); // Widgets for rebinning a histogram which does NOT derive from a ntuple fBinCont = new TGCompositeFrame(fBin, 80, 20, kVerticalFrame); TGCompositeFrame *f18 = new TGCompositeFrame(fBinCont, 80, 20, kHorizontalFrame); fBinSlider = new TGHSlider(f18, 100, kSlider1 | kScaleBoth); fBinSlider->Resize(107,20); f18->AddFrame(fBinSlider, new TGLayoutHints(kLHintsLeft, 3,0,0,3)); fBinCont->AddFrame(f18, new TGLayoutHints(kLHintsTop, 15, 7, 3, 5)); TGCompositeFrame *f20 = new TGCompositeFrame(fBinCont, 80, 20, kHorizontalFrame); TGLabel *binLabel1 = new TGLabel(f20, "# of Bins:"); f20->AddFrame(binLabel1, new TGLayoutHints(kLHintsLeft, 7, 1, 2, 1)); fBinNumberEntry = new TGNumberEntryField(f20, kBINSLIDER, 0.0, TGNumberFormat::kNESInteger); ((TGTextEntry*)fBinNumberEntry)->SetToolTipText("Set the number of bins in the rebinned histogram"); fBinNumberEntry->Resize(57,20); f20->AddFrame(fBinNumberEntry, new TGLayoutHints(kLHintsRight, 21, 0, 0, 0)); fBinCont->AddFrame(f20, new TGLayoutHints(kLHintsTop, 0, 7, 3, 4)); // Text buttons to Apply or Delete the rebinned histogram TGCompositeFrame *f23 = new TGCompositeFrame(fBinCont, 118, 20, kHorizontalFrame | kFixedWidth); fApply = new TGTextButton(f23, " &Apply "); f23->AddFrame(fApply, new TGLayoutHints(kLHintsExpandX | kLHintsLeft , 0, 3, 4, 4)); fCancel = new TGTextButton(f23, " &Ignore "); f23->AddFrame(fCancel, new TGLayoutHints(kLHintsExpandX | kLHintsLeft, 3, 0, 4, 4)); fBinCont->AddFrame(f23, new TGLayoutHints(kLHintsTop, 20, 3, 3, 4)); fBin->AddFrame(fBinCont,new TGLayoutHints(kLHintsTop| kLHintsExpandX)); // Widgets for rebinning a histogram which derives from a ntuple fBinCont1 = new TGCompositeFrame(fBin, 80, 20, kVerticalFrame); TGCompositeFrame *f21 = new TGCompositeFrame(fBinCont1, 80, 20, kHorizontalFrame); fBinSlider1 = new TGHSlider(f21, 100, kSlider1 | kScaleBoth); fBinSlider1->Resize(107,20); fBinSlider1->SetRange(1,9); fBinSlider1->SetScale(12); fBinSlider1->SetPosition(5); f21->AddFrame(fBinSlider1, new TGLayoutHints(kLHintsLeft, 3,0,0,3)); fBinCont1->AddFrame(f21, new TGLayoutHints(kLHintsTop, 15, 7, 5, 0)); // Lettering of the Rebin Slider TGCompositeFrame *f24 = new TGCompositeFrame(fBinCont1, 80, 20, kHorizontalFrame); TGLabel *l1 = new TGLabel(f24, "-5"); f24->AddFrame(l1, new TGLayoutHints(kLHintsLeft, 18, 1, -1, 0)); TGLabel *l2 = new TGLabel(f24, "-2"); f24->AddFrame(l2, new TGLayoutHints(kLHintsLeft, 26, 2, -1, 0)); TGLabel *l3 = new TGLabel(f24, "2"); f24->AddFrame(l3, new TGLayoutHints(kLHintsLeft, 17, 2, -1, 0)); TGLabel *l4 = new TGLabel(f24, "5"); f24->AddFrame(l4, new TGLayoutHints(kLHintsLeft, 32, 3, -1, 0)); fBinCont1->AddFrame(f24, new TGLayoutHints(kLHintsTop, 0, 0, 0, 0)); TGCompositeFrame *f22 = new TGCompositeFrame(fBinCont1, 140, 20, kHorizontalFrame); TGLabel *binLabel2 = new TGLabel(f22, "# of Bins:"); f22->AddFrame(binLabel2, new TGLayoutHints(kLHintsLeft, 7, 1, 4, 1)); fBinNumberEntry1 = new TGNumberEntryField(f22, kBINSLIDER1, 0.0, TGNumberFormat::kNESInteger); ((TGTextEntry*)fBinNumberEntry1)->SetToolTipText("Set the number of bins in the rebinned histogram"); fBinNumberEntry1->Resize(57,20); f22->AddFrame(fBinNumberEntry1, new TGLayoutHints(kLHintsLeft, 21, 0, 2, 0)); fBinCont1->AddFrame(f22, new TGLayoutHints(kLHintsTop, 0, 7, 2, 4)); TGCompositeFrame *f26 = new TGCompositeFrame(fBinCont1, 80, 20, kHorizontalFrame); TGLabel *offsetLbl = new TGLabel(f26, "BinOffset:"); f26->AddFrame(offsetLbl, new TGLayoutHints(kLHintsLeft, 6, 1, 2, 1)); fOffsetNumberEntry = new TGNumberEntryField(f26, kBINOFFSET, 0.0, TGNumberFormat::kNESRealFour, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, 0., 1.); ((TGTextEntry*)fOffsetNumberEntry)->SetToolTipText("Add an offset to the origin of the histogram"); fOffsetNumberEntry->Resize(57,20); f26->AddFrame(fOffsetNumberEntry, new TGLayoutHints(kLHintsRight, 21, 0, 0, 0)); fBinCont1->AddFrame(f26, new TGLayoutHints(kLHintsTop, 0, 7, 3, 1)); TGCompositeFrame *f25 = new TGCompositeFrame(fBinCont1, 80, 20, kHorizontalFrame); fBinOffsetSld = new TGHSlider(f25, 100, kSlider1 | kScaleBoth); fBinOffsetSld->Resize(107,20); f25->AddFrame(fBinOffsetSld, new TGLayoutHints(kLHintsLeft, 15,0,0,2)); fBinCont1->AddFrame(f25, new TGLayoutHints(kLHintsTop, 3, 7, 3, 3)); fBin->AddFrame(fBinCont1, new TGLayoutHints(kLHintsTop)); // Sliders for axis range TGCompositeFrame *sldCont = new TGCompositeFrame(fBin, 80, 20, kVerticalFrame); TGCompositeFrame *title2 = new TGCompositeFrame(sldCont, 145, 10, kHorizontalFrame | kLHintsExpandX | kFixedWidth | kOwnBackground); title2->AddFrame(new TGLabel(title2, "Axis Range"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); title2->AddFrame(new TGHorizontal3DLine(title2), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); sldCont->AddFrame(title2, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); TGCompositeFrame *f14 = new TGCompositeFrame(sldCont, 80, 20, kHorizontalFrame); TGLabel *fSliderLbl = new TGLabel(f14,"x:"); f14->AddFrame(fSliderLbl, new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 4,4, 4, 1)); fSlider = new TGDoubleHSlider(f14, 1, 2); fSlider->Resize(118,20); f14->AddFrame(fSlider, new TGLayoutHints(kLHintsLeft)); sldCont->AddFrame(f14, new TGLayoutHints(kLHintsTop, 3, 7, 4, 1)); TGCompositeFrame *f16 = new TGCompositeFrame(sldCont, 80, 20, kHorizontalFrame); fSldMin = new TGNumberEntryField(f16, kSLIDER_MIN, 0.0, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEAAnyNumber); ((TGTextEntry*)fSldMin)->SetToolTipText("Set the minimum value of the x-axis"); fSldMin->Resize(57,20); f16->AddFrame(fSldMin, new TGLayoutHints(kLHintsLeft, 0, 0, 0, 0)); fSldMax = new TGNumberEntryField(f16, kSLIDER_MAX, 0.0, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEAAnyNumber); ((TGTextEntry*)fSldMax)->SetToolTipText("Set the maximum value of the x-axis"); fSldMax->Resize(57,20); f16->AddFrame(fSldMax, new TGLayoutHints(kLHintsLeft, 4, 0, 0, 0)); sldCont->AddFrame(f16, new TGLayoutHints(kLHintsTop, 20, 3, 5, 0)); TGCompositeFrame *f17 = new TGCompositeFrame(sldCont, 80, 20, kVerticalFrame); fDelaydraw = new TGCheckButton(f17, "Delayed drawing", kDELAYED_DRAWING); fDelaydraw ->SetToolTipText("Draw the new histogram only when any Slider is released"); f17->AddFrame(fDelaydraw, new TGLayoutHints(kLHintsLeft, 6, 1, 2, 0)); sldCont->AddFrame(f17, new TGLayoutHints(kLHintsTop, 1, 1, 5, 0)); fBin->AddFrame(sldCont, new TGLayoutHints(kLHintsTop)); // to avoid jumping from DoAddBar to DoAddB and vice versa fMakeB=kTRUE; // to avoid calling SetDrawoption after every change fMake=kTRUE; fBinHist = 0; // used to save a copy of the histogram // (when not drawn from an ntuple) fBinOffsetSld->SetRange(0,100); fBinOffsetSld->SetPosition(0); fOffsetNumberEntry->SetNumber(0.0000); fCancel->SetState(kButtonDisabled); fApply->SetState(kButtonDisabled); } // end bin tab //______________________________________________________________________________ TH1Editor::~TH1Editor() { // Destructor of TH1 editor. // 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; } //______________________________________________________________________________ void TH1Editor::ConnectSignals2Slots() { // Connect signals to slots. //widgets for draw options fAddB->Connect("Toggled(Bool_t)", "TH1Editor", this, "DoAddB(Bool_t)"); fAddBar->Connect("Toggled(Bool_t)", "TH1Editor", this, "DoAddBar(Bool_t)"); fTitle->Connect("TextChanged(const char *)", "TH1Editor", this, "DoTitle(const char *)"); fTypeCombo->Connect("Selected(Int_t)", "TH1Editor", this, "DoHistChanges()"); fCoordsCombo->Connect("Selected(Int_t)", "TH1Editor", this, "DoHistChanges()"); fErrorCombo->Connect("Selected(Int_t)", "TH1Editor", this, "DoHistChanges()"); fAddCombo->Connect("Selected(Int_t)", "TH1Editor", this, "DoHistChanges()"); fAddMarker->Connect("Toggled(Bool_t)", "TH1Editor", this, "DoAddMarker(Bool_t)"); fAddSimple->Connect("Toggled(Bool_t)", "TH1Editor", this, "DoAddSimple(Bool_t)"); //change 2D <-> 3D plot fDimGroup->Connect("Clicked(Int_t)","TH1Editor",this,"DoHistView()"); // change Bar Width/Offset, the second connection is needed to have the ability to confirm the value also with enter fBarWidth->Connect("ValueSet(Long_t)", "TH1Editor", this, "DoBarWidth()"); (fBarWidth->GetNumberEntry())->Connect("ReturnPressed()", "TH1Editor", this, "DoBarWidth()"); fBarOffset->Connect("ValueSet(Long_t)", "TH1Editor", this, "DoBarOffset()"); (fBarOffset->GetNumberEntry())->Connect("ReturnPressed()", "TH1Editor", this, "DoBarOffset()"); fPercentCombo->Connect("Selected(Int_t)", "TH1Editor", this, "DoPercent()"); fMakeHBar-> Connect("Toggled(Bool_t)","TH1Editor",this,"DoHBar(Bool_t))"); // Connections for rebinning are created - i.e. slider is // connected to the slots that perform the rebinning in the // case of a histogram not derived from an ntuple. fBinSlider->Connect("PositionChanged(Int_t)","TH1Editor",this, "DoBinMoved(Int_t)"); fBinSlider->Connect("Released()","TH1Editor",this, "DoBinReleased()"); fBinSlider->Connect("Pressed()","TH1Editor",this, "DoBinPressed()"); // numberEntry which shows/sets the actual number of bins fBinNumberEntry->Connect("ReturnPressed()", "TH1Editor", this, "DoBinLabel()"); // Buttons to accept/reject the rebinned histogram fApply->Connect("Clicked()", "TH1Editor", this, "DoApply()"); fCancel->Connect("Pressed()", "TH1Editor", this, "DoCancel()"); // in case of a histogram which is derived from an ntuple these slots are used fBinSlider1->Connect("Released()","TH1Editor",this, "DoBinReleased1()"); fBinSlider1->Connect("PositionChanged(Int_t)","TH1Editor",this, "DoBinMoved1()"); fBinNumberEntry1->Connect("ReturnPressed()", "TH1Editor", this, "DoBinLabel1()"); // slider/slots to change the offset of the histogram fBinOffsetSld->Connect("PositionChanged(Int_t)", "TH1Editor", this,"DoOffsetMoved(Int_t)"); fBinOffsetSld->Connect("Released()", "TH1Editor", this, "DoOffsetReleased()"); fBinOffsetSld->Connect("Pressed()", "TH1Editor", this, "DoOffsetPressed()"); fOffsetNumberEntry->Connect("ReturnPressed()", "TH1Editor", this, "DoBinOffset()"); // slider/slots to set the visible axisrange fSlider->Connect("PositionChanged()","TH1Editor", this,"DoSliderMoved()"); fSlider->Connect("Pressed()","TH1Editor", this, "DoSliderPressed()"); fSlider->Connect("Released()","TH1Editor", this, "DoSliderReleased()"); fSldMin->Connect("ReturnPressed()", "TH1Editor", this, "DoAxisRange()"); fSldMax->Connect("ReturnPressed()", "TH1Editor", this, "DoAxisRange()"); fInit = kFALSE; } //______________________________________________________________________________ Bool_t TH1Editor::AcceptModel(TObject* obj) { // Check if object is able to configure with this editor. if (obj == 0 || !obj->InheritsFrom(TH1::Class()) || ((TH1*)obj)->GetDimension()!=1 || ((TH1*)obj)->GetEntries() == 0 /*|| obj->InheritsFrom("TH2") || obj->InheritsFrom("TProfile")*/) { return kFALSE; } return kTRUE; } //______________________________________________________________________________ void TH1Editor::SetModel(TObject* obj) { // Pick up current values of histogram attributes. 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()); fHist->Add(fBinHist); } // delete in anycase fBinHist also when fHist is zero (i.e when it has been deleted) delete fBinHist; fBinHist = 0; } fHist = (TH1*)obj; fAvoidSignal = kTRUE; const char *text = fHist->GetTitle(); fTitle->SetText(text); fMake=kFALSE; TString str = GetDrawOption(); str.ToUpper(); if (str.Contains("SAME")) fSameOpt = kTRUE; else fSameOpt = kFALSE; Bool_t errorset = kFALSE; // if no draw option is specified: (default options) if (str.IsNull() || str=="" ) { fDimGroup->SetButton(kDIM_SIMPLE, kTRUE); fDimGroup->SetButton(kDIM_COMPLEX, kFALSE); HideFrame(f3); // Hiding the histogram type combo box ShowFrame(f6); ShowFrame(f7); ShowFrame(f8); ShowFrame(f9); HideFrame(f10); HideFrame(f11); HideFrame(f12); ShowFrame(f15); fCoordsCombo->Select(kCOORDS_CAR); fErrorCombo->Select(kERRORS_NO); errorset=kTRUE; fAddCombo->Select(kADD_NONE); fAddMarker->SetState(kButtonUp); fAddB->SetState(kButtonUp); fAddBar->SetState(kButtonUp); fAddSimple->SetState(kButtonDisabled); ChangeErrorCombo(1); // in case of a 2D plot: } else if (!str.Contains("LEGO") && !str.Contains("SURF")){ fDimGroup->SetButton(kDIM_SIMPLE,kTRUE); fDimGroup->SetButton(kDIM_COMPLEX,kFALSE); HideFrame(f3); // Hiding the histogram type combo box ShowFrame(f7); ShowFrame(f8); ShowFrame(f9); ShowFrame(f15); fCoordsCombo->Select(kCOORDS_CAR); // initialising fAddCombo if (str.Contains("C")) { if (str.Contains("CYL")) { TString dum = str; dum.Remove(strstr(dum.Data(),"CYL")-dum.Data(),3); if (dum.Contains("C")) fAddCombo->Select(kADD_SMOOTH); } else fAddCombo->Select(kADD_SMOOTH); } else if (str.Contains("LF2")) fAddCombo->Select(kADD_FILL); else if (str.Contains("L")){ TString dum = str; if (str.Contains("CYL")) { dum.Remove(strstr(dum.Data(),"CYL")-dum.Data(),3); if (dum.Contains("L")) fAddCombo->Select(kADD_SIMPLE); } if (str.Contains("POL")) { dum.Remove(strstr(dum.Data(),"POL")-dum.Data(),3); if (dum.Contains("L")) fAddCombo->Select(kADD_SIMPLE); } else fAddCombo->Select(kADD_SIMPLE); } else fAddCombo->Select(kADD_NONE); if (fAddCombo->GetSelected()!=kADD_NONE) fAddSimple->SetState(kButtonDisabled); else if (str.Contains("HIST")) { if (str=="HIST") fAddSimple->SetState(kButtonDisabled); else fAddSimple->SetState(kButtonDown); } else fAddSimple->SetState(kButtonUp); if (str.Contains("B")) { TString dum = str; if (str.Contains("BAR")) { fAddBar->SetState(kButtonDown); fAddB->SetState(kButtonDisabled); ShowFrame(f10); ShowFrame(f11); ShowFrame(f12); } else { fAddB->SetState(kButtonDown); fAddBar->SetState(kButtonDisabled); fAddSimple->SetState(kButtonDisabled); ShowFrame(f10); ShowFrame(f11); HideFrame(f12); } } else { fAddB->SetState(kButtonUp); fAddBar->SetState(kButtonUp); HideFrame(f10); HideFrame(f11); HideFrame(f12); } if (str.Contains("P") ) { fAddMarker->SetState(kButtonDown); fAddSimple->SetState(kButtonDisabled); } else if (!str.Contains("BAR")) fAddMarker->SetState(kButtonUp); ChangeErrorCombo(1); // in case of a 3D plot } else if (str.Contains("LEGO") || str.Contains("SURF")){ fDimGroup->SetButton(kDIM_COMPLEX,kTRUE); fDimGroup->SetButton(kDIM_SIMPLE,kFALSE); TGListBox* lb; ChangeErrorCombo(0); // set Coordinate ComboBox if (str.Contains("SURF")){ // surf cannot be combined with spheric and cartesian coordinates // i.e. remove them from the combobox fCoordsCombo->RemoveEntry(kCOORDS_SPH); fCoordsCombo->RemoveEntry(kCOORDS_CAR); lb = fCoordsCombo->GetListBox(); lb->Resize(lb->GetWidth(), 49); } else { // surf cannot be combined with spheric and cartesian coordinates // if surf was selected before here the removed items were added the combobox again if (((TGLBContainer*)((TGListBox*)fCoordsCombo->GetListBox())->GetContainer())->GetPos(kCOORDS_SPH)==-1) fCoordsCombo->AddEntry("Spheric", kCOORDS_SPH); if (((TGLBContainer*)((TGListBox*)fCoordsCombo->GetListBox())->GetContainer())->GetPos(kCOORDS_CAR)==-1) { fCoordsCombo->AddEntry("Cartesian", kCOORDS_CAR); lb = fCoordsCombo->GetListBox(); lb->Resize(lb->GetWidth(), 83); } } // initialising the Type Combobox 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 HideFrame(f6); HideFrame(f7); HideFrame(f8); HideFrame(f9); HideFrame(f15); if (str.Contains("LEGO")) { ShowFrame(f10); ShowFrame(f11); HideFrame(f12); } else { HideFrame(f10); HideFrame(f11); HideFrame(f12); } fAddMarker->SetState(kButtonDisabled); fAddB->SetState(kButtonDisabled); } if (!errorset) { if (str.Contains("E1")) fErrorCombo->Select(kERRORS_EDGES); else if (str.Contains("E2")) fErrorCombo->Select(kERRORS_REC); else if (str.Contains("E3")) fErrorCombo->Select(kERRORS_FILL); else if (str.Contains("E4")) fErrorCombo->Select(kERRORS_CONTOUR); else if (str.Contains("E")) { if (str.Contains("LEGO")) { TString dum=str; dum.Remove(strstr(dum.Data(),"LEGO")-dum.Data(),4); if (dum.Contains("E")) fErrorCombo->Select(kERRORS_SIMPLE); } else fErrorCombo->Select(kERRORS_SIMPLE); } else fErrorCombo->Select(kERRORS_NO); //default } if (fErrorCombo->GetSelected() != kERRORS_NO){ HideFrame(f7); HideFrame(f8); } if (str.Contains("BAR") || ((fAddBar->GetState()==kButtonDown) && (fDim->GetState()==kButtonDown))) { ShowFrame(f10); ShowFrame(f11); ShowFrame(f12); fBarWidth->SetNumber(fHist->GetBarWidth()); fBarOffset->SetNumber(fHist->GetBarOffset()); if (str.Contains("HBAR")) fMakeHBar->SetState(kButtonDown); else fMakeHBar->SetState(kButtonUp); if (str.Contains("BAR4")) fPercentCombo->Select(kPER_40); else if (str.Contains("BAR3")) fPercentCombo->Select(kPER_30); else if (str.Contains("BAR2")) fPercentCombo->Select(kPER_20); else if (str.Contains("BAR1")) fPercentCombo->Select(kPER_10); else fPercentCombo->Select(kPER_0); } Int_t nx = fHist -> GetXaxis() -> GetNbins(); Int_t nxbinmin = fHist -> GetXaxis() -> GetFirst(); Int_t nxbinmax = fHist -> GetXaxis() -> GetLast(); if (fDelaydraw->GetState()!=kButtonDown) fDelaydraw->SetState(kButtonUp); 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 fBinNumberEntry 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 n = 0; if (fBinHist) n = fBinHist->GetXaxis()->GetNbins(); else n = nx; if (n < 1) n = 1; fBin->HideFrame(fBinCont1); fBin->ShowFrame(fBinCont); Int_t* div = Dividers(n); Int_t up = 0; if (div[0]-1 <= 1) up = 2; else up = div[0]-1; fBinSlider->SetRange(1,up); Int_t i = 1; if (fBinSlider->GetMaxPosition()==2 && fBinSlider->GetPosition()==2) fBinSlider->SetPosition(2); else { while ( div[i] != nx) i ++; fBinSlider->SetPosition(div[0] - i + 1); } fBinNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax , 2, n); fBinNumberEntry->SetIntNumber(nx); delete [] div; } else if (player && fHist==player->GetHistogram() && fHist->GetEntries() == player->GetNfill()) { // in case of a ntupla/tree based histogram with number of entries not exceeding the TTreePlayer cache fBin->HideFrame(fBinCont); fBin->ShowFrame(fBinCont1); fBinSlider->SetRange(0,1); fBinSlider->SetPosition(0); fBinSlider1->SetPosition(5); fBinNumberEntry1->SetLimits(TGNumberFormat::kNELLimitMinMax , 2, 10000); fBinNumberEntry1->SetIntNumber(nxbinmax-nxbinmin+1); } fSlider->SetRange(1,nx); fSlider->SetPosition((Double_t)nxbinmin,(Double_t)nxbinmax); fSldMin->SetNumber(fHist->GetXaxis()->GetBinLowEdge(nxbinmin)); fSldMax->SetNumber(fHist->GetXaxis()->GetBinUpEdge(nxbinmax)); fOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, fHist->GetXaxis()->GetBinWidth(1)); if (fInit) ConnectSignals2Slots(); fMake=kTRUE; fGedEditor->GetTab()->SetEnabled(1, kTRUE); fAvoidSignal = kFALSE; } //______________________________________________________________________________ void TH1Editor::DoTitle(const char *text) { // Slot connected to the histogram title setting. if (fAvoidSignal) return; fHist->SetTitle(text); Update(); } //______________________________________________________________________________ void TH1Editor::DoAddMarker(Bool_t on) { // Slot connected to the show markers check box. if (fAvoidSignal) return; TString str = GetDrawOption(); str.ToUpper(); if (str.Contains("SAME")) fSameOpt = kTRUE; else fSameOpt = kFALSE; TString dum = str; if (dum.Contains("POL")) dum.Remove(strstr(dum.Data(),"POL")-dum.Data(),3); if (dum.Contains("SPH")) dum.Remove(strstr(dum.Data(),"SPH")-dum.Data(),3); if (dum.Contains("PSR")) dum.Remove(strstr(dum.Data(),"PSR")-dum.Data(),3); if (on) { if (!dum.Contains("P")) str += "P"; fAddSimple->SetState(kButtonDisabled); if (str.Contains("HIST")) str.Remove(strstr(str.Data(),"HIST")-str.Data(),4); } else if (fAddMarker->GetState()==kButtonUp) { if (str.Contains("POL") || str.Contains("SPH")) { while (dum.Contains("P")) dum.Remove(strstr(dum.Data(),"P")-dum.Data(),1); if (str.Contains("POL")) str = dum + "POL"; if (str.Contains("SPH")) str = dum + "SPH"; if (str.Contains("PSR")) str = dum + "PSR"; } else if (str.Contains("P")) str.Remove(str.First("P"),1); if ((str=="HIST") || (str=="") || (fAddB->GetState()==kButtonDown) || fAddCombo->GetSelected() != kADD_NONE) fAddSimple->SetState(kButtonDisabled); else if (str.Contains("HIST")) fAddSimple->SetState(kButtonDown); else fAddSimple->SetState(kButtonUp); } if (fMake) { if (fSameOpt) str += "SAME"; SetDrawOption(str); Update(); } } //______________________________________________________________________________ void TH1Editor::DoAddB(Bool_t on) { // Slot connected to the bar Add check box. if (fAvoidSignal) return; TString str = GetDrawOption(); str.ToUpper(); if (str.Contains("SAME")) fSameOpt = kTRUE; else fSameOpt = kFALSE; if (fMakeB) { fMakeB=kFALSE; if (on) { if (!str.Contains("B")) str += "B"; ShowFrame(f10); ShowFrame(f11); HideFrame(f12); fAddBar->SetState(kButtonDisabled); fAddSimple->SetState(kButtonDisabled); fBarOffset->SetNumber(fHist->GetBarOffset()); fBarWidth->SetNumber(fHist->GetBarWidth()); } else if (fAddB->GetState()==kButtonUp) { while (str.Contains("B")) str.Remove(str.First("B"),1); HideFrame(f10); HideFrame(f11); HideFrame(f12); fAddBar->SetState(kButtonUp); if (fAddMarker->GetState()!=kButtonDown && !(str=="" || str=="HIST" || fAddCombo->GetSelected()!=kADD_NONE)) fAddSimple->SetState(kButtonUp); } if (fSameOpt) str += "SAME"; if (fMake) SetDrawOption(str); Update(); fMakeB=kTRUE; } } //______________________________________________________________________________ void TH1Editor::DoAddBar(Bool_t on) { // Slot connected to the bar Add check box. if (fAvoidSignal) return; Disconnect(fAddMarker); TString str = GetDrawOption(); str.ToUpper(); if (str.Contains("SAME")) fSameOpt = kTRUE; else fSameOpt = kFALSE; if (fMakeB) { fMakeB=kFALSE; Int_t o = 0; if (str.Contains("HBAR")) o=1; if (str.Contains("BAR4")) str.Remove(strstr(str.Data(),"BAR4")-str.Data()-o,4+o); else if (str.Contains("BAR3")) str.Remove(strstr(str.Data(),"BAR3")-str.Data()-o,4+o); else if (str.Contains("BAR2")) str.Remove(strstr(str.Data(),"BAR2")-str.Data()-o,4+o); else if (str.Contains("BAR1")) str.Remove(strstr(str.Data(),"BAR1")-str.Data()-o,4+o); else if (str.Contains("BAR0")) str.Remove(strstr(str.Data(),"BAR0")-str.Data()-o,4+o); else if (str.Contains("BAR")) str.Remove(strstr(str.Data(),"BAR")-str.Data()-o,3+o); if (on) { if ((fAddMarker->GetState()==kButtonDown) && (fErrorCombo->GetSelected()==kERRORS_NO) && (fAddSimple->GetState()!=kButtonDisabled)) fAddSimple->SetState(kButtonDisabled); else if ((fAddMarker->GetState()!=kButtonDown) && (fAddSimple->GetState()==kButtonDisabled)) { if (str.Contains("HIST")) fAddSimple->SetState(kButtonDown); else if (fAddCombo->GetSelected()!=kADD_NONE) fAddSimple->SetState(kButtonDisabled); else fAddSimple->SetState(kButtonUp); } switch (fPercentCombo->GetSelected()){ case(-1): { str += "BAR"; fPercentCombo->Select(kPER_0); break; } case(kPER_0): { str += "BAR"; break; } case(kPER_10): { str += "BAR1"; break; } case(kPER_20): { str += "BAR2"; break; } case(kPER_30): { str += "BAR3"; break; } case(kPER_40): { str += "BAR4"; break; } } ShowFrame(f10); ShowFrame(f11); ShowFrame(f12); if (fMakeHBar->GetState()==kButtonDown) str.Insert(strstr(str.Data(),"BAR")-str.Data(),"H"); fBarOffset->SetNumber(fHist->GetBarOffset()); fBarWidth->SetNumber(fHist->GetBarWidth()); fAddB->SetState(kButtonDisabled); } else if (fAddBar->GetState()==kButtonUp) { HideFrame(f10); HideFrame(f11); HideFrame(f12); fAddB->SetState(kButtonUp); if (fAddMarker->GetState()==kButtonDisabled) fAddMarker->SetState(kButtonUp); if (str=="" || str=="HIST" || fAddCombo->GetSelected() != kADD_NONE || ((fAddMarker->GetState() == kButtonDown) && fErrorCombo->GetSelected() == kERRORS_NO) ) fAddSimple->SetState(kButtonDisabled); } if (fSameOpt) str += "SAME"; if (fMake) SetDrawOption(str); Update(); ((TGMainFrame*)GetMainFrame())->Layout(); fMakeB=kTRUE; } fAddMarker->Connect("Toggled(Bool_t)", "TH1Editor", this, "DoAddMarker(Bool_t)"); } //______________________________________________________________________________ void TH1Editor::DoAddSimple(Bool_t on) { // Slot connected to fAddSimple check box for drawing a simple histogram // without errors (== HIST draw option) in combination with some other // draw options. It draws an additional line on the top of the bins. if (fAvoidSignal) return; Disconnect(fAddMarker); // Bool_t make=kFALSE; fMake = kFALSE; TString str = GetDrawOption(); str.ToUpper(); if (str.Contains("SAME")) fSameOpt = kTRUE; else fSameOpt = kFALSE; if (on) { if (!str.Contains("HIST")) { str += "HIST"; fAddMarker->SetState(kButtonDisabled); fMake=kTRUE; } } else if (fAddSimple->GetState()==kButtonUp) { if (str.Contains("HIST")) { str.Remove(strstr(str.Data(),"HIST")-str.Data(),4); fAddMarker->SetState(kButtonUp); fMake=kTRUE; } } if (fSameOpt) str += "SAME"; if (fMake) SetDrawOption(str); fAddMarker->Connect("Toggled(Bool_t)", "TH1Editor", this, "DoAddMarker(Bool_t)"); Update(); } //______________________________________________________________________________ void TH1Editor::DoHistView() { // Slot connected to the 'Plot' button group. 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)); } //______________________________________________________________________________ void TH1Editor::DoHistSimple() { // Slot connected to the 2D radio button. if (fAvoidSignal) return; if (fDim->GetState()==kButtonDown){ TString str =""; fMake=kFALSE; TGListBox* lb; HideFrame(f3); ShowFrame(f6); ShowFrame(f9); ShowFrame(f15); ChangeErrorCombo(1); if ((fAddBar->GetState() != kButtonDown || fAddMarker->GetState()==kButtonDown ) && (fErrorCombo->GetSelected()==kERRORS_NO)) fAddSimple->SetState(kButtonDisabled); else if ((fAddSimple->GetState()==kButtonDisabled) && (fAddMarker->GetState()!=kButtonDown)) fAddSimple->SetState(kButtonUp); else if (fAddSimple->GetState()!=kButtonUp) fAddSimple->SetState(kButtonDown); if (fAddMarker->GetState()==kButtonDisabled && fAddSimple->GetState()!=kButtonDown) fAddMarker->SetState(kButtonUp); if (fErrorCombo->GetSelected()==kERRORS_NO) { ShowFrame(f7); ShowFrame(f8); } else { HideFrame(f7); HideFrame(f8); if (fAddBar->GetState()==kButtonDisabled) fAddBar->SetState(kButtonUp); } if ((fAddB->GetState() == kButtonDisabled)) { if (fAddBar->GetState()==kButtonDown) { ShowFrame(f10); ShowFrame(f11); ShowFrame(f12); } else { HideFrame(f10); HideFrame(f11); HideFrame(f12); } } if (fAddBar->GetState() == kButtonDisabled){ ShowFrame(f10); ShowFrame(f11); HideFrame(f12); } if ((fAddBar->GetState() == kButtonUp) && (fAddB->GetState() == kButtonUp)) { HideFrame(f10); HideFrame(f11); HideFrame(f12); } if (fAddCombo->GetSelected()== -1 )fAddCombo->Select(kADD_NONE); if (fErrorCombo->GetSelected()!=kERRORS_NO) { fAddCombo->RemoveEntries(kADD_SIMPLE,kADD_FILL); lb = fAddCombo->GetListBox(); lb->Resize(lb->GetWidth(),19); Disconnect(fAddCombo); fAddCombo->Select(kADD_NONE); fAddCombo->Connect("Selected(Int_t)", "TH1Editor", this, "DoHistChanges()"); } else { if (((TGLBContainer*)((TGListBox*)fAddCombo->GetListBox())->GetContainer())->GetPos(kADD_SIMPLE)==-1) ((TGListBox*)fAddCombo->GetListBox())->AddEntry("Simple Line", kADD_SIMPLE); if (((TGLBContainer*)((TGListBox*)fAddCombo->GetListBox())->GetContainer())->GetPos(kADD_SMOOTH)==-1) ((TGListBox*)fAddCombo->GetListBox())->AddEntry("Smooth Line", kADD_SMOOTH); if (((TGLBContainer*)((TGListBox*)fAddCombo->GetListBox())->GetContainer())->GetPos(kADD_FILL)==-1) { ((TGListBox*)fAddCombo->GetListBox())->AddEntry("Fill Area",kADD_FILL); lb = fAddCombo->GetListBox(); lb->Resize(lb->GetWidth(),76); } } if (fAddSimple->GetState()==kButtonDown) str+="HIST"; str += GetHistErrorLabel()+GetHistAddLabel(); if (fSameOpt) str += "SAME"; SetDrawOption(str); Update(); //fGedEditor->GetTab()->Layout(); ((TGMainFrame*)GetMainFrame())->Layout(); fMake=kTRUE; } } //______________________________________________________________________________ void TH1Editor::DoHistComplex() { // Slot connected to the 3D radio button. if (fAvoidSignal) return; if (fDim0->GetState()==kButtonDown) { TString str =""; fMake=kFALSE; ShowFrame(f3); HideFrame(f6); HideFrame(f7); HideFrame(f8); HideFrame(f9); HideFrame(f15); ChangeErrorCombo(0); if (fTypeCombo->GetSelected()==-1 && fCoordsCombo->GetSelected()==-1) { str = "LEGO"+GetHistErrorLabel(); fTypeCombo->Select(kTYPE_LEGO); fCoordsCombo->Select(kCOORDS_CAR); } else if (fTypeCombo->GetSelected()==-1){ str = "LEGO"+GetHistErrorLabel(); fTypeCombo->Select(kTYPE_LEGO); } else if (fCoordsCombo->GetSelected()==-1) { str = GetHistTypeLabel()+GetHistErrorLabel(); fCoordsCombo->Select(kCOORDS_CAR); } else { str = GetHistTypeLabel()+GetHistCoordsLabel()+GetHistErrorLabel(); } if (str.Contains("LEGO")) { ShowFrame(f10); ShowFrame(f11); HideFrame(f12); } else { HideFrame(f10); HideFrame(f11); HideFrame(f12); } if (fSameOpt) str += "SAME"; SetDrawOption(str); Update(); ((TGMainFrame*)GetMainFrame())->Layout(); fGedEditor->GetTab()->Layout(); fMake=kTRUE; } } //______________________________________________________________________________ void TH1Editor::DoHistChanges() { // Slot connected to the histogram type, the coordinate type, the error type // and the Add combo box. if (fAvoidSignal) return; fMakeB= kFALSE; TGListBox* lb; if (GetHistTypeLabel().Contains("SURF")) { if (fCoordsCombo->GetSelected()==kCOORDS_CAR || fCoordsCombo->GetSelected()==kCOORDS_SPH) fCoordsCombo->Select(kCOORDS_POL); fCoordsCombo->RemoveEntry(kCOORDS_SPH); fCoordsCombo->RemoveEntry(kCOORDS_CAR); lb = fCoordsCombo->GetListBox(); lb->Resize(lb->GetWidth(), 49); } else { if (((TGLBContainer*)((TGListBox*)fCoordsCombo->GetListBox())->GetContainer())->GetPos(kCOORDS_SPH)==-1) ((TGListBox*)fCoordsCombo->GetListBox())->AddEntrySort("Spheric", kCOORDS_SPH); if (((TGLBContainer*)((TGListBox*)fCoordsCombo->GetListBox())->GetContainer())->GetPos(kCOORDS_CAR)==-1) { ((TGListBox*)fCoordsCombo->GetListBox())->AddEntrySort("Cartesian", kCOORDS_CAR); lb = fCoordsCombo->GetListBox(); lb->Resize(lb->GetWidth(), 83); } } if (fDim->GetState()!=kButtonUp){ if (fErrorCombo->GetSelected() != kERRORS_NO){ HideFrame(f7); HideFrame(f8); ShowFrame(f9); fAddMarker->SetState(kButtonDisabled); fAddB->SetState(kButtonDisabled); if (fAddBar->GetState()==kButtonDisabled) fAddBar->SetState(kButtonUp); if (fAddSimple->GetState()==kButtonDisabled) fAddSimple->SetState(kButtonUp); fAddCombo->RemoveEntries(kADD_SIMPLE,kADD_FILL); lb = fAddCombo->GetListBox(); lb->Resize(lb->GetWidth(),19); Disconnect(fAddCombo); fAddCombo->Select(kADD_NONE); fAddCombo->Connect("Selected(Int_t)", "TH1Editor", this, "DoHistChanges()"); if (fAddBar->GetState()==kButtonDown) { ShowFrame(f10); ShowFrame(f11); ShowFrame(f12); } else { HideFrame(f10); HideFrame(f11); HideFrame(f12); } } else { Bool_t on = fMake; fMake=kFALSE; ShowFrame(f7); ShowFrame(f8); ShowFrame(f9); if (fAddMarker->GetState()==kButtonDisabled) fAddMarker->SetState(kButtonUp); if (fAddBar->GetState() != kButtonDown && fAddB->GetState()==kButtonDisabled) fAddB->SetState(kButtonUp); if (((TGLBContainer*)((TGListBox*)fAddCombo->GetListBox())->GetContainer())->GetPos(kADD_SIMPLE)==-1) ((TGListBox*)fAddCombo->GetListBox())->AddEntry("Simple Line", kADD_SIMPLE); if (((TGLBContainer*)((TGListBox*)fAddCombo->GetListBox())->GetContainer())->GetPos(kADD_SMOOTH)==-1) ((TGListBox*)fAddCombo->GetListBox())->AddEntry("Smooth Line", kADD_SMOOTH); if (((TGLBContainer*)((TGListBox*)fAddCombo->GetListBox())->GetContainer())->GetPos(kADD_FILL)==-1) { ((TGListBox*)fAddCombo->GetListBox())->AddEntry("Fill Area",kADD_FILL); lb = fAddCombo->GetListBox(); lb->Resize(lb->GetWidth(),76); } fMake=on; } if (fAddCombo->GetSelected()!=kADD_NONE) { fAddSimple->SetState(kButtonDisabled); } else { if (fAddMarker->GetState()==kButtonDown) fAddSimple->SetState(kButtonDisabled); else if (fAddSimple->GetState()==kButtonDisabled) fAddSimple->SetState(kButtonUp); } } else if (fDim0->GetState()==kButtonDown) { if (GetHistTypeLabel().Contains("LEGO")) { ShowFrame(f10); ShowFrame(f11); HideFrame(f12); } else { HideFrame(f10); HideFrame(f11); HideFrame(f12); } } if (fMake) { TString str = ""; if (fDim->GetState()==kButtonDown) str = GetHistErrorLabel()+GetHistAddLabel(); else if (fDim0->GetState()==kButtonDown) str = GetHistTypeLabel()+GetHistCoordsLabel()+GetHistErrorLabel(); if (fAddSimple->GetState()==kButtonDown) str += "HIST"; if (fSameOpt) str += "SAME"; SetDrawOption(str); if (str=="" || str=="HIST") fAddSimple->SetState(kButtonDisabled); Update(); } ((TGMainFrame*)GetMainFrame())->Layout(); // fGedEditor->GetTab()->Layout(); fMakeB=kTRUE; } //______________________________________________________________________________ void TH1Editor::DoBarWidth() { // Slot connected to the Bar Width of the Bar Charts. if (fAvoidSignal) return; fHist->SetBarWidth(fBarWidth->GetNumber()); Update(); } //______________________________________________________________________________ void TH1Editor::DoBarOffset() { // Slot connected to the Bar Offset of the Bar Charts. if (fAvoidSignal) return; Float_t f = fBarOffset->GetNumber(); fHist->SetBarOffset(f); Update(); } //______________________________________________________________________________ void TH1Editor::DoPercent() { // Slot connected to the bar percentage settings. if (fAvoidSignal) return; TString str = GetDrawOption(); str.ToUpper(); if (str.Contains("SAME")) fSameOpt = kTRUE; else fSameOpt = kFALSE; Int_t o = 0; if (str.Contains("HBAR")) o=1; if (str.Contains("BAR4")) str.Remove(strstr(str.Data(),"BAR4")-str.Data()-1,4+o); else if (str.Contains("BAR3")) str.Remove(strstr(str.Data(),"BAR3")-str.Data()-o,4+o); else if (str.Contains("BAR2")) str.Remove(strstr(str.Data(),"BAR2")-str.Data()-o,4+o); else if (str.Contains("BAR1")) str.Remove(strstr(str.Data(),"BAR1")-str.Data()-o,4+o); else if (str.Contains("BAR0")) str.Remove(strstr(str.Data(),"BAR0")-str.Data()-o,4+o); else if (str.Contains("BAR")) str.Remove(strstr(str.Data(),"BAR")-str.Data()-o,3+o); if (fMakeHBar->GetState()==kButtonDown) str+="H"; switch (fPercentCombo->GetSelected()){ case (kPER_0) :{ str += "BAR"; break;} case (kPER_10):{ str += "BAR1"; break;} case (kPER_20):{ str += "BAR2"; break;} case (kPER_30):{ str += "BAR3"; break;} case (kPER_40):{ str += "BAR4"; break;} } if (fSameOpt) str += "SAME"; if (fMake) SetDrawOption(str); Update(); } //______________________________________________________________________________ void TH1Editor::DoHBar(Bool_t on) { // Slot connected to the Horizontal Bar check button. if (fAvoidSignal) return; TString str = GetDrawOption(); str.ToUpper(); if (str.Contains("SAME")) fSameOpt = kTRUE; else fSameOpt = kFALSE; if (on) { if (!str.Contains("HBAR")) str.Insert(strstr(str.Data(),"BAR")-str.Data(),"H"); } else if (fMakeHBar->GetState()==kButtonUp) { if (str.Contains("HBAR")) str.Remove(strstr(str.Data(),"BAR")-str.Data()-1,1); } if (fSameOpt) str += "SAME"; if (fMake) SetDrawOption(str); Update(); } //______________________________________________________________________________ void TH1Editor::DoSliderMoved() { // Slot connected to the x-Slider for redrawing of the histogram // according to the new Slider range. if (fAvoidSignal) return; if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE); fGedEditor->GetPad()->cd(); if (fDelaydraw->GetState()==kButtonDown && fDim->GetState()==kButtonDown) { static Int_t px1,py1,px2,py2; static Float_t ymin,ymax,xleft,xright; xleft = fHist->GetXaxis()->GetBinLowEdge((Int_t)((fSlider->GetMinPosition())+0.5)); xright = fHist->GetXaxis()->GetBinUpEdge((Int_t)((fSlider->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()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); fGedEditor->GetPad()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); fGedEditor->GetPad()->cd(); 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); fSldMin->SetNumber(xleft); fSldMax->SetNumber(xright); } else if (fDelaydraw->GetState() == kButtonDown && fDim0->GetState() == kButtonDown && fCoordsCombo->GetSelected() == kCOORDS_CAR) { static Float_t p1[3], p2[3], p3[3], p4[3], p5[3], p6[3], p7[3], p8[3]; 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] = fHist->GetXaxis()->GetBinLowEdge((Int_t)((fSlider->GetMinPosition())+0.5)); p2[0] = p3[0] = p6[0] = p7[0] = fHist->GetXaxis()->GetBinUpEdge((Int_t)((fSlider->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(fP2old, fP3old, fP7old, fP6old); PaintBox3D(fP1old, fP4old, fP8old, fP5old); PaintBox3D(p2, p3, p7, p6); PaintBox3D(p1, p4, p8, p5); for (Int_t i = 0; i<3; i++){ fP1old[i] = p1[i]; fP2old[i] = p2[i]; fP3old[i] = p3[i]; fP4old[i] = p4[i]; fP5old[i] = p5[i]; fP6old[i] = p6[i]; fP7old[i] = p7[i]; fP8old[i] = p8[i]; } fSldMin->SetNumber(p1[0]); fSldMax->SetNumber(p2[0]); } else if (fDelaydraw->GetState() == kButtonDown && fDim0->GetState() == kButtonDown) { fSldMin->SetNumber(fHist->GetXaxis()->GetBinLowEdge((Int_t)((fSlider->GetMinPosition())+0.5))); fSldMax->SetNumber(fHist->GetXaxis()->GetBinUpEdge((Int_t)((fSlider->GetMaxPosition())+0.5))); } else { fHist->GetXaxis()->SetRange((Int_t)((fSlider->GetMinPosition())+0.5), (Int_t)((fSlider->GetMaxPosition())+0.5)); fSldMin->SetNumber(fHist->GetXaxis()->GetBinLowEdge(fHist->GetXaxis()->GetFirst())); fSldMax->SetNumber(fHist->GetXaxis()->GetBinUpEdge(fHist->GetXaxis()->GetLast())); fClient->NeedRedraw(fSlider,kTRUE); Update(); } TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (player && player->GetHistogram() == fHist) { Int_t last = fHist->GetXaxis()->GetLast(); Int_t first = fHist->GetXaxis()->GetFirst(); fBinNumberEntry1->SetIntNumber(last-first+1); // How to redraw the NumberEntry without calling Update?? // Update kills the "virtual" painted box in Delayed draw mode fClient->NeedRedraw(fBinNumberEntry1,kTRUE); // fGedEditor->GetTab()->Layout(); } fClient->NeedRedraw(fSldMin,kTRUE); fClient->NeedRedraw(fSldMax,kTRUE); } //______________________________________________________________________________ void TH1Editor::DoSliderPressed() { // Slot connected to the x-axis Range slider for initialising the // values of the slider movement. if (fAvoidSignal) return; if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE); fGedEditor->GetPad()->cd(); static Float_t ymin,ymax,xleft,xright; Int_t sldmin = (Int_t)((fSlider->GetMinPosition())+0.5); Int_t sldmax = (Int_t)((fSlider->GetMaxPosition())+0.5); if (fDelaydraw->GetState() == kButtonDown && fDim->GetState()==kButtonDown) { if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE); fGedEditor->GetPad()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); xleft = fHist->GetXaxis()->GetBinLowEdge(sldmin); xright = fHist->GetXaxis()->GetBinUpEdge(sldmax); 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) { TView *fView = fGedEditor->GetPad()->GetView(); if (!fView) return; Double_t *rmin = fView->GetRmin(); if (!rmin) return; Double_t *rmax = fView->GetRmax(); if (!rmax) return; fP1old[0] = fP4old[0] = fP5old[0] = fP8old[0] = fHist->GetXaxis()->GetBinLowEdge(sldmin); fP2old[0] = fP3old[0] = fP6old[0] = fP7old[0] = fHist->GetXaxis()->GetBinUpEdge(sldmax); fP1old[1] = fP2old[1] = fP3old[1] = fP4old[1] = rmin[1]; fP5old[1] = fP6old[1] = fP7old[1] = fP8old[1] = rmax[1]; fP1old[2] = fP2old[2] = fP5old[2] = fP6old[2] = rmin[2]; fP3old[2] = fP4old[2] = fP7old[2] = fP8old[2] = rmax[2]; if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE); fGedEditor->GetPad()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); PaintBox3D(fP2old, fP3old, fP7old, fP6old); PaintBox3D(fP1old, fP4old, fP8old, fP5old); } Update(); } //______________________________________________________________________________ void TH1Editor::DoSliderReleased() { // Slot connected to the x-axis Range slider for finalizing the // values of the slider movement. if (fAvoidSignal) return; if (fDelaydraw->GetState()==kButtonDown) { fHist->GetXaxis()->SetRange((Int_t)((fSlider->GetMinPosition())+0.5), (Int_t)((fSlider->GetMaxPosition())+0.5)); fSldMin->SetNumber(fHist->GetXaxis()->GetBinLowEdge(fHist->GetXaxis()->GetFirst())); fSldMax->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(); fBinNumberEntry1->SetIntNumber(last-first+1); Update(); } } //______________________________________________________________________________ void TH1Editor::DoAxisRange() { // Slot connected to the number entry fields containing the Max/Min // value of the x-axis. if (fAvoidSignal) return; Int_t nx = fHist->GetXaxis()->GetNbins(); Double_t width = fHist->GetXaxis()->GetBinWidth(1); Double_t lowLimit = fHist->GetXaxis()->GetBinLowEdge(1); Double_t upLimit = fHist->GetXaxis()->GetBinUpEdge(nx); if ((fSldMin->GetNumber()+width/2) < (lowLimit)) fSldMin->SetNumber(lowLimit); if ((fSldMax->GetNumber()-width/2) > (upLimit)) fSldMax->SetNumber(upLimit); // Set the histogram range and the axis range slider fHist->GetXaxis()->SetRangeUser(fSldMin->GetNumber()+width/2, fSldMax->GetNumber()-width/2); Int_t nxbinmin = fHist->GetXaxis()->GetFirst(); Int_t nxbinmax = fHist->GetXaxis()->GetLast(); fSlider->SetPosition((Double_t)(nxbinmin),(Double_t)(nxbinmax)); Update(); } //______________________________________________________________________________ void TH1Editor::DoBinReleased() { // Slot connected to the rebin slider in case of a not ntuple histogram // Updates some other widgets which are related to the rebin slider. // draw the rebinned histogram in case of delay draw mode if (fAvoidSignal) return; if (fDelaydraw->GetState()==kButtonDown){ if (!fBinHist) { fBinHist = (TH1*)fHist->Clone("BinHist"); // we will manage this histogram fBinHist->SetDirectory(0); } Int_t nx = fBinHist->GetXaxis()->GetNbins(); Int_t numx = fBinSlider->GetPosition(); Int_t* divx = Dividers(nx); if (divx[0]==2) fBinSlider->SetPosition(2); if (divx[0]==2) { delete [] divx; return; } // delete the histogram which is on the screen fGedEditor->GetPad()->cd(); fHist->Reset(); fHist->SetBins(nx,fBinHist->GetXaxis()->GetXmin(), fBinHist->GetXaxis()->GetXmax()); fHist->Add(fBinHist); fHist->ResetBit(TH1::kCanRebin); fHist->Rebin(divx[numx]); // fModel=fHist; if (divx[0]!=2) { TAxis* xaxis = fHist->GetXaxis(); Double_t xBinWidth = xaxis->GetBinWidth(1); xaxis->SetRangeUser(fSldMin->GetNumber()+xBinWidth/2, fSldMax->GetNumber()-xBinWidth/2); fSlider->SetRange(1,(Int_t)nx/divx[numx]); fSlider->SetPosition(xaxis->FindBin(fSldMin->GetNumber()+xBinWidth/2), xaxis->FindBin(fSldMax->GetNumber()-xBinWidth/2)); // the x-axis range could be changed a little bit by Rebin algorithm fSldMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); } if (fCancel->GetState()==kButtonDisabled) fCancel->SetState(kButtonUp); if (fApply->GetState()==kButtonDisabled) fApply->SetState(kButtonUp); Update(); delete [] divx; } // fGedEditor->GetPad()->GetCanvas()->Selected(fGedEditor->GetPad(), fHist, 0); // fModel = fHist; Refresh(fHist); } //______________________________________________________________________________ void TH1Editor::DoBinMoved(Int_t numx) { // Slot connected to the rebin slider in case of a not ntuple histogram // (does the Rebinning of the histogram). // create a clone in the background, when the slider is moved for // the first time if (fAvoidSignal) return; if (!fBinHist /*&& fDelaydraw->GetState()!=kButtonDown*/) { Int_t* divx = Dividers(fHist->GetXaxis()->GetNbins()); if (divx[0]==2) { delete [] divx; return; } fBinHist = (TH1*)fHist->Clone("BinHist"); // the TH1Editor class manage this histogram fBinHist->SetDirectory(0); delete [] divx; } // if the slider already has been moved and the clone is saved Int_t nx = fBinHist->GetXaxis()->GetNbins(); Int_t* divx = Dividers(nx); if (divx[0]==2) { fBinSlider->SetPosition(2); numx=1; delete [] divx; return; } Int_t maxx = (Int_t)nx/divx[numx]; if (maxx==1) maxx=2; if (fDelaydraw->GetState() == kButtonUp) { fGedEditor->GetPad()->cd(); fHist->Reset(); fHist->SetBins(nx,fBinHist->GetXaxis()->GetXmin(), fBinHist->GetXaxis()->GetXmax()); fHist->Add(fBinHist); fHist->ResetBit(TH1::kCanRebin); fHist->Rebin(divx[numx]); //fModel=fHist; TAxis* xaxis = fHist->GetXaxis(); Double_t xBinWidth = xaxis->GetBinWidth(1); xaxis->SetRangeUser(fSldMin->GetNumber()+xBinWidth/2, fSldMax->GetNumber()-xBinWidth/2); fSlider->SetRange(1,maxx); fSlider->SetPosition(xaxis->FindBin(fSldMin->GetNumber()+xBinWidth/2), xaxis->FindBin(fSldMax->GetNumber()-xBinWidth/2)); // the axis range could be changed a little bit by the Rebin algorithm fSldMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fClient->NeedRedraw(fBinSlider,kTRUE); Update(); } if (fCancel->GetState()==kButtonDisabled) fCancel->SetState(kButtonUp); if (fApply->GetState()==kButtonDisabled) fApply->SetState(kButtonUp); if (fBinNumberEntry->GetNumber()!=maxx) fBinNumberEntry->SetNumber(maxx); delete [] divx; } //______________________________________________________________________________ void TH1Editor::DoBinPressed() { // Slot connected to the rebin slider in case of a not ntuple histogram. if (fAvoidSignal) return; Int_t* d = Dividers(fHist->GetXaxis()->GetNbins()); if (d[0]==2 && !fBinHist) { new TGMsgBox(fClient->GetDefaultRoot(), this->GetMainFrame(), "TH1 Editor", "It is not possible to rebin the histogram", kMBIconExclamation, kMBOk, 0, kVerticalFrame); gVirtualX->GrabPointer(fBinSlider->GetId(),0,0,0); } delete [] d; // calling the MessageBox again does NOT work!*/ } //______________________________________________________________________________ void TH1Editor::DoBinReleased1() { // Slot connected to the BinNumber Slider in case of a ntuple histogram // (does the Rebinning of the histogram). if (fAvoidSignal) return; Double_t oldOffset = fOffsetNumberEntry->GetNumber(); Int_t number = fBinSlider1->GetPosition(); if (number==5) return; Int_t fact = 0; Int_t binNumber = 0; TAxis* xaxis = fHist->GetXaxis(); // "compute" the scaling factor: if (number > 5) fact = number - 4; else fact = number - 6; TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (!player) return; Int_t first = xaxis->GetFirst(); Int_t last = xaxis->GetLast(); Int_t nx = xaxis->GetNbins(); Double_t min = xaxis->GetBinLowEdge(1); // overall min in user coords Double_t max = xaxis->GetBinUpEdge(nx); // overall max in user coords Double_t rmin = xaxis->GetBinLowEdge(first); // recent min in user coords Double_t rmax = xaxis->GetBinUpEdge(last); // recent max in user coords ((TH1*)player->GetHistogram())->ResetBit(TH1::kCanRebin); ((TH1*)player->GetHistogram())->Reset(); // get new Number of bins if (fact > 0) binNumber = fact*nx; if (fact < 0) binNumber = (Int_t) ((-1)*nx/fact+0.5); if (binNumber < 1) binNumber = 1; if (binNumber > 10000) binNumber= 10000; Double_t newOffset = 1.*fBinOffsetSld->GetPosition()/100*((max-min)/binNumber); // create new histogram - the main job is done by sel->TakeAction() ((TH1*)player->GetHistogram())->SetBins(binNumber, min-oldOffset+newOffset, max-oldOffset+newOffset); TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector(); if (!sel) return; sel->TakeAction(); // restore and set all the attributes which were changed by TakeAction() fHist = (TH1*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram(); fSlider->SetRange(1,binNumber); Double_t binWidth = fHist->GetXaxis()->GetBinWidth(1); fSlider->SetPosition(xaxis->FindBin(rmin), xaxis->FindBin(rmax)); Double_t offset = 1.*fBinOffsetSld->GetPosition()/100*binWidth; xaxis->SetRange(xaxis->FindBin(rmin+binWidth/2), xaxis->FindBin(rmax-binWidth/2)); // SetRange in binNumbers! fSldMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fBinNumberEntry1->SetNumber(xaxis->GetLast() - xaxis->GetFirst() + 1); fBinSlider1->SetPosition(5); fOffsetNumberEntry->SetNumber(offset); fOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, xaxis->GetBinWidth(1)); fClient->NeedRedraw(fBinSlider1); Update(); } //______________________________________________________________________________ void TH1Editor::DoBinMoved1() { // Slot connected to the rebin slider in case of an ntuple histogram. // It updates the BinNumberEntryField during the BinSlider movement. if (fAvoidSignal) return; TAxis* xaxis = fHist->GetXaxis(); Int_t first = xaxis->GetFirst(); Int_t last = xaxis->GetLast(); Int_t number = fBinSlider1->GetPosition(); Int_t n = last -first+1; Int_t fact = 0; Int_t binNumber = 0; if (number >= 5) fact = number - 4; else fact = number - 6; if (fact > 0) binNumber = fact*n; if (fact < 0) binNumber = (Int_t) ((-1)*n/fact+0.5); if (binNumber < 1) binNumber = 1; if (binNumber > 10000) binNumber= 10000; fBinNumberEntry1->SetIntNumber(binNumber); // Update(); } //______________________________________________________________________________ void TH1Editor::DoBinLabel() { // Slot connected to the Bin number entry of the Rebinning tab. if (fAvoidSignal) return; Int_t num = (Int_t)(fBinNumberEntry->GetNumber()); Int_t nx = 0; if (fBinHist) nx = fBinHist->GetXaxis()->GetNbins(); else nx = fHist->GetXaxis()->GetNbins(); if (nx < 2) return; Int_t *div = Dividers(nx); Int_t diff = TMath::Abs(num - div[1]); Int_t c = 1; for (Int_t i = 2; i <= div[0]; i++) { if ((TMath::Abs(num - div[i])) < diff) { c = i; diff = TMath::Abs(num - div[i]); } } fBinNumberEntry->SetNumber(div[c]); fBinSlider->SetPosition(div[0] - c +1); if (fDelaydraw->GetState()==kButtonUp) DoBinMoved(div[0] - c +1); else DoBinReleased(); // fGedEditor->GetPad()->GetCanvas()->Selected(fGedEditor->GetPad(), fHist, 0); // fModel = fHist; Refresh(fHist); delete [] div; } //______________________________________________________________________________ void TH1Editor::DoBinLabel1() { // Slot connected to the Bin number entry of the Rebinning tab. if (fAvoidSignal) return; Double_t oldOffset = fOffsetNumberEntry->GetNumber(); Int_t num = (Int_t)fBinNumberEntry1->GetNumber(); TAxis* xaxis = fHist->GetXaxis(); TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (!player) return; Int_t first = xaxis->GetFirst(); Int_t last = xaxis->GetLast(); Int_t nx = xaxis->GetNbins(); Double_t min = xaxis->GetBinLowEdge(1); // overall min in user coords Double_t max = xaxis->GetBinUpEdge(nx); // overall max in user coords Double_t rmin = xaxis->GetBinLowEdge(first); // recent min in user coords Double_t rmax = xaxis->GetBinUpEdge(last); // recent max in user coords ((TH1*)player->GetHistogram())->ResetBit(TH1::kCanRebin); ((TH1*)player->GetHistogram())->Reset(); // Calculate the new number of bins in the complete range Int_t binNumber = (Int_t) ((max-min)/(rmax - rmin)*num + 0.5); if (binNumber < 1) binNumber = 1; if (binNumber > 10000) binNumber = 10000; Double_t offset = 1.*(fBinOffsetSld->GetPosition())/100*(max-min)/binNumber; // create new histogram - the main job is done by sel->TakeAction() ((TH1*)player->GetHistogram())->SetBins(binNumber, min-oldOffset+offset, max-oldOffset+offset); TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector(); if (!sel) return; sel->TakeAction(); // Restore and set all the attributes which were changed by TakeAction() fHist = (TH1*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram(); fSlider->SetRange(1,binNumber); Double_t binWidth = xaxis->GetBinWidth(1); fSlider->SetPosition(xaxis->FindBin(rmin), xaxis->FindBin(rmax)); offset = 1.*fBinOffsetSld->GetPosition()/100*binWidth; xaxis->SetRange(xaxis->FindBin(rmin+binWidth/2), xaxis->FindBin(rmax-binWidth/2)); // SetRange in binNumbers! fSldMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fOffsetNumberEntry->SetNumber(offset); fOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, binWidth); Update(); } //______________________________________________________________________________ void TH1Editor::DoOffsetPressed() { // Slot connected to the OffSetSlider that saves the OldBinOffset // (nessesary for delay draw mode). if (fAvoidSignal) return; fOldOffset = fOffsetNumberEntry->GetNumber(); } //______________________________________________________________________________ void TH1Editor::DoOffsetReleased() { // Slot connected to the OffSetSlider. // It changes the origin of the histogram inbetween a binwidth and // rebin the histogram with the new Offset given by the Slider. // !!problem: histogram with variable binwidth?? // computes the new histogram in "delay draw" mode if (fAvoidSignal) return; if (fDelaydraw->GetState()==kButtonDown) { Int_t num = (Int_t) fBinOffsetSld->GetPosition(); TAxis* xaxis = fHist->GetXaxis(); Double_t binWidth = xaxis->GetBinWidth(1); Double_t offset = 1.*num/100*binWidth; Double_t oldOffset = fOldOffset; Int_t nx = xaxis->GetNbins(); TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (!player) return; Int_t first = xaxis->GetFirst(); Int_t last = xaxis->GetLast(); Double_t min = xaxis->GetBinLowEdge(1); // overall min in user coords Double_t max = xaxis->GetBinUpEdge(nx); // overall max in user coords Double_t rmin = xaxis->GetBinLowEdge(first); // recent min in user coords Double_t rmax = xaxis->GetBinUpEdge(last); // recent max in user coords ((TH1*)player->GetHistogram())->ResetBit(TH1::kCanRebin); ((TH1*)player->GetHistogram())->Reset(); ((TH1*)player->GetHistogram())->SetBins(nx, min+offset-oldOffset, max+offset-oldOffset); TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector(); if (!sel) return; sel->TakeAction(); // Restore all the attributes which were changed by TakeAction() fHist = (TH1*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram(); xaxis->SetRange(xaxis->FindBin(rmin+offset-oldOffset+binWidth/2), xaxis->FindBin(rmax+offset-oldOffset-binWidth/2)); // in binNumbers! fSldMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fOffsetNumberEntry->SetNumber(offset); Update(); } } //______________________________________________________________________________ void TH1Editor::DoOffsetMoved(Int_t num) { // Slot connected to the OffSetSlider. // It changes the origin of the histogram inbetween a binwidth and // rebin the histogram with the new offset given by the Slider. // !!histogram with variable binwidth?? // !!only works for histograms with fixed binwidth if (fAvoidSignal) return; TAxis* xaxis = fHist->GetXaxis(); Double_t binWidth = xaxis->GetBinWidth(1); Double_t offset = 1.*num/100*binWidth; if (fDelaydraw->GetState()==kButtonUp) { Double_t oldOffset = fOffsetNumberEntry->GetNumber(); Int_t nx = xaxis->GetNbins(); TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (!player) return; Int_t first = xaxis->GetFirst(); Int_t last = xaxis->GetLast(); Double_t min = xaxis->GetBinLowEdge(1); // overall min in user coords Double_t max = xaxis->GetBinUpEdge(nx); // overall max in user coords Double_t rmin = xaxis->GetBinLowEdge(first); // recent min in user coords Double_t rmax = xaxis->GetBinUpEdge(last); // recent max in user coords ((TH1*)player->GetHistogram())->ResetBit(TH1::kCanRebin); ((TH1*)player->GetHistogram())->Reset(); ((TH1*)player->GetHistogram())->SetBins(nx, min+offset-oldOffset, max+offset-oldOffset); TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector(); if (!sel) return; sel->TakeAction(); // Restore all the attributes which were changed by TakeAction() fHist = (TH1*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram(); xaxis->SetRange(xaxis->FindBin(rmin+offset-oldOffset+binWidth/2), xaxis->FindBin(rmax+offset-oldOffset-binWidth/2)); // in binNumbers! fSldMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fClient->NeedRedraw(fBinOffsetSld,kTRUE); } fOffsetNumberEntry->SetNumber(offset); fClient->NeedRedraw(fOffsetNumberEntry,kTRUE); Update(); } //______________________________________________________________________________ void TH1Editor::DoBinOffset() { // Slot connected to the OffSetNumberEntry which is related to the // OffSetSlider changes the origin of the histogram inbetween a binwidth. if (fAvoidSignal) return; TAxis* xaxis = fHist->GetXaxis(); Double_t binWidth = xaxis->GetBinWidth(1); Double_t offset = fOffsetNumberEntry->GetNumber(); Double_t oldOffset = 1.*fBinOffsetSld->GetPosition()/100*binWidth; Int_t nx = xaxis->GetNbins(); TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer(); if (!player) return; Int_t first = xaxis->GetFirst(); Int_t last = xaxis->GetLast(); Double_t min = xaxis->GetBinLowEdge(1); // overall min in user coords Double_t max = xaxis->GetBinUpEdge(nx); // overall max in user coords Double_t rmin = xaxis->GetBinLowEdge(first); // recent min in user coords Double_t rmax = xaxis->GetBinUpEdge(last); // recent max in user coords ((TH1*)player->GetHistogram())->ResetBit(TH1::kCanRebin); ((TH1*)player->GetHistogram())->Reset(); ((TH1*)player->GetHistogram())->SetBins(nx, min+offset-oldOffset, max+offset-oldOffset); TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector(); if (!sel) return; sel->TakeAction(); // Restore all the attributes which were changed by TakeAction() fHist = (TH1*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram(); xaxis->SetRange(xaxis->FindBin(rmin+offset-oldOffset+binWidth/2), xaxis->FindBin(rmax+offset-oldOffset-binWidth/2)); // in binNumbers! fSldMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst())); fSldMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast())); fBinOffsetSld->SetPosition((Int_t)(offset/binWidth*100)); Update(); } //______________________________________________________________________________ void TH1Editor::DoApply() { // Slot connected to the Apply button of the Binning tab. Int_t ret = 0; new TGMsgBox(fClient->GetDefaultRoot(), this->GetMainFrame(), "TH1 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 *div = Dividers(nx); Int_t up = 0; if (div[0]-1 <= 1) up = 2; else up = div[0]-1; fBinSlider->SetRange(1,up); if (fBinSlider->GetMaxPosition()==2 && div[0]==2 ) fBinSlider->SetPosition(2); else fBinSlider->SetPosition(1); fCancel->SetState(kButtonDisabled); fApply->SetState(kButtonDisabled); Update(); delete [] div; } else if (ret==2) DoCancel(); } //______________________________________________________________________________ void TH1Editor::DoCancel() { // Slot connected to the Cancel button of the Binning tab. if (fBinHist) { fGedEditor->GetPad()->cd(); fHist->Reset(); fHist->SetBins(fBinHist->GetXaxis()->GetNbins(), fBinHist->GetXaxis()->GetXmin(), fBinHist->GetXaxis()->GetXmax()); fHist->Add(fBinHist); fHist->GetXaxis()->SetRange(fBinHist->GetXaxis()->GetFirst(), fBinHist->GetXaxis()->GetLast()); delete fBinHist; fBinHist = 0; fCancel->SetState(kButtonDisabled); fApply->SetState(kButtonDisabled); Int_t* divx = Dividers(fHist->GetXaxis()->GetNbins()); if (divx[0]!=2) fBinSlider->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; } } //______________________________________________________________________________ TString TH1Editor::GetHistTypeLabel() { // Returns the selected histogram type (HIST, LEGO1-2, SURF1-5). TString s=""; switch (fTypeCombo->GetSelected()){ case (-1) : {s = "LEGO"; break;} case (kTYPE_LEGO ): {s = "LEGO"; break;} case (kTYPE_LEGO1): {s = "LEGO1"; break;} case (kTYPE_LEGO2): {s = "LEGO2"; 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; } //______________________________________________________________________________ TString TH1Editor::GetHistCoordsLabel() { // Return the selected coordinate system of the histogram (POL,CYL,SPH,PSR). TString s=""; if (fDim->GetState()!=kButtonDown) { switch (fCoordsCombo->GetSelected()){ case (-1) : {s = "POL"; 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; } //______________________________________________________________________________ TString TH1Editor::GetHistErrorLabel() { // Return the selected error type (E,E1-5). TString s=""; switch (fErrorCombo->GetSelected()){ case (-1) : {s = ""; break;} case (kERRORS_NO) : {s = ""; break;} case (kERRORS_SIMPLE) : {s = "E"; break;} case (kERRORS_EDGES) : {s = "E1"; break;} case (kERRORS_REC) : {s = "E2"; break;} case (kERRORS_FILL) : {s = "E3"; break;} case (kERRORS_CONTOUR): {s = "E4"; break;} default: break; } return s; } //______________________________________________________________________________ TString TH1Editor::GetHistAddLabel() { // Return the selected shape of the histogram (C, L, LF2). TString s=""; switch (fAddCombo->GetSelected()){ case (-1) : {s = "" ; break;} case (kADD_NONE) : {s = "" ; break;} case (kADD_SMOOTH): {s = "C"; break;} case (kADD_SIMPLE): {s = "L"; break;} case (kADD_FILL) : {s = "LF2"; break;} default : break; } if (fAddMarker->GetState()==kButtonDown) s += "P"; if (fAddB->GetState()==kButtonDown) s += "B"; if (fAddBar->GetState()==kButtonDown){ if (fMakeHBar->GetState()==kButtonDown) s+="H"; switch (fPercentCombo->GetSelected()){ case (kPER_0) : { s += "BAR" ; break;} case (kPER_10): { s += "BAR1"; break;} case (kPER_20): { s += "BAR2"; break;} case (kPER_30): { s += "BAR3"; break;} case (kPER_40): { s += "BAR4"; break;} } } return s; } //______________________________________________________________________________ TGComboBox* TH1Editor::BuildHistTypeComboBox(TGFrame* parent, Int_t id) { // Create histogram type combo box. TGComboBox *c = new TGComboBox(parent, id); c->AddEntry("Lego" , kTYPE_LEGO); c->AddEntry("Lego1", kTYPE_LEGO1); c->AddEntry("Lego2", kTYPE_LEGO2); 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; } //______________________________________________________________________________ TGComboBox* TH1Editor::BuildHistCoordsComboBox(TGFrame* parent, Int_t id) { // Create coordinate system type combo box. 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; } //______________________________________________________________________________ TGComboBox* TH1Editor::BuildHistErrorComboBox(TGFrame* parent, Int_t id) { // Create error type combo box. TGComboBox *c = new TGComboBox(parent, id); c->AddEntry("No Errors", kERRORS_NO); c->AddEntry("Simple", kERRORS_SIMPLE); c->AddEntry("Edges", kERRORS_EDGES); c->AddEntry("Rectangles",kERRORS_REC); c->AddEntry("Fill", kERRORS_FILL); c->AddEntry("Contour", kERRORS_CONTOUR); return c; } //______________________________________________________________________________ TGComboBox* TH1Editor::BuildHistAddComboBox(TGFrame* parent, Int_t id) { // Create Line/Bar combo box. TGComboBox *c = new TGComboBox(parent, id); c->AddEntry("No Line", kADD_NONE); c->AddEntry("Simple Line", kADD_SIMPLE); c->AddEntry("Smooth Line", kADD_SMOOTH); c->AddEntry("Fill Area",kADD_FILL); TGListBox* lb = c->GetListBox(); lb->Resize(lb->GetWidth(), 76); return c; } //______________________________________________________________________________ TGComboBox* TH1Editor::BuildPercentComboBox(TGFrame* parent, Int_t id) { // Create Percentage combo box for bar option. TGComboBox *c = new TGComboBox(parent, id); c->AddEntry(" 0 %", kPER_0); c->AddEntry("10 %", kPER_10); c->AddEntry("20 %", kPER_20); c->AddEntry("30 %", kPER_30); c->AddEntry("40 %", kPER_40); TGListBox* lb = c->GetListBox(); lb->Resize(lb->GetWidth(), 83); return c; } //______________________________________________________________________________ void TH1Editor::ChangeErrorCombo(Int_t i) { // Change the error combo box entry. switch (i){ case 0: { if (((TGLBContainer*)((TGListBox*)fErrorCombo->GetListBox())->GetContainer())->GetPos(kERRORS_EDGES)!=-1) fErrorCombo->RemoveEntries(kERRORS_EDGES,kERRORS_CONTOUR); if (!((fErrorCombo->GetSelected()== kERRORS_NO) || (fErrorCombo->GetSelected()== kERRORS_SIMPLE))) fErrorCombo->Select(kERRORS_NO); TGListBox* lb = fErrorCombo->GetListBox(); lb->Resize(lb->GetWidth(),36); break; } case 1: { if (((TGLBContainer*)((TGListBox*)fErrorCombo->GetListBox())->GetContainer())->GetPos(kERRORS_EDGES)==-1) { fErrorCombo->AddEntry("Edges", kERRORS_EDGES); fErrorCombo->AddEntry("Rectangles",kERRORS_REC); fErrorCombo->AddEntry("Fill", kERRORS_FILL); fErrorCombo->AddEntry("Contour", kERRORS_CONTOUR); TGListBox* lb = fErrorCombo->GetListBox(); lb->Resize(lb->GetWidth(),100); } break; } } } //______________________________________________________________________________ void TH1Editor::PaintBox3D(Float_t *p1, Float_t *p2,Float_t *p3, Float_t *p4) { // Paint a 3D box. if (fGedEditor->GetPad()->GetCanvas()) fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE); fGedEditor->GetPad()->SetLineWidth(1); fGedEditor->GetPad()->SetLineColor(2); fGedEditor->GetPad()->cd(); fGedEditor->GetPad()->PaintLine3D(p1, p2); fGedEditor->GetPad()->PaintLine3D(p2, p3); fGedEditor->GetPad()->PaintLine3D(p3, p4); fGedEditor->GetPad()->PaintLine3D(p4, p1); } //______________________________________________________________________________ Int_t* TH1Editor::Dividers(Int_t n) { // Return an array of dividers of n (without the trivial divider n). // The number of dividers is saved in the first entry. 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; // for (Int_t a=0; a <= div[0]; a++) printf("div[%d] = %d\n", a , div[a]); } return div; } //_____________________________________________________________________________ void TH1Editor::RecursiveRemove(TObject* obj) { // If the contained histogram obj is deleted we must set its pointer to zero if (obj == fHist) { fHist = 0; } }