class myGraph : public TGraph { public: myGraph() = default; myGraph(Int_t n, double* x, double* y) : TGraph(n, x, y) {} using TGraph::RemovePoint; // to use the function with integer index as argument Int_t RemovePoint() override; // *MENU* private: /// \cond CLASSIMP ClassDefOverride(myGraph, 1) // NOLINT(readability-else-after-return) /// \endcond }; Int_t myGraph::RemovePoint() { Int_t px = gPad->GetEventX(); Int_t py = gPad->GetEventY(); double mx1, mx2, my1, my2, rx1, rx2, ry1, ry2; gPad->GetRange(mx1, my1, mx2, my2); gPad->GetRangeAxis(rx1, ry1, rx2, ry2); std::cout << "Using x, y " << px << ", " << py << " on " << gPad->GetName() << ": abs to x,y " << gPad->AbsPixeltoX(px) << ", " << gPad->AbsPixeltoY(py) << ", pix to x,y " << gPad->PixeltoX(px) << ", " << gPad->PixeltoY(py - gPad->GetWh()) << std::endl; std::cout << "x1 " << gPad->GetX1() << ", x2 " << gPad->GetX2() << ", y1 " << gPad->GetY1() << ", y2 " << gPad->GetY2() << ", Wh " << gPad->GetWh() << ", Ww " << gPad->GetWw() << ", uxmin " << gPad->GetUxmin() << ", uxmax " << gPad->GetUxmax() << ", uymin " << gPad->GetUymin() << ", uymax " << gPad->GetUymax() << ", range " << mx1 << ", " << my1 << "; " << mx2 << ", " << my2 << ", axis " << rx1 << ", " << ry1 << "; " << rx2 << ", " << ry2 << std::endl; return px; } void Test() { int nChannels = 3; int nSources = 2; auto mainFrame = new TGMainFrame(); auto tab = new TGTab(mainFrame, 1200, 600); for(int ch = 1; ch <= nChannels; ++ch) { auto channelTab = tab->AddTab(Form("Channel %d", ch)); channelTab->SetLayoutManager(new TGHorizontalLayout(channelTab)); auto subTab1 = new TGTab(channelTab, 600, 500); for(int s = 1; s <= nSources; ++s) { auto sourceTab = subTab1->AddTab(Form("Source %d", s)); auto projectionCanvas = new TRootEmbeddedCanvas(Form("ProjectionCanvas%d", s), sourceTab, 600, 400); sourceTab->AddFrame(projectionCanvas, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandY | kLHintsExpandX, 2, 2, 2, 2)); auto fStatusBar = new TGStatusBar(sourceTab, 600, 50); sourceTab->AddFrame(fStatusBar, new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 2, 2, 2, 2)); std::array x = { ch*0.+s, ch*1.+s, ch*2.+s, ch*4.+s, ch*5.+s, ch*6.+s, ch*7.+s, ch*8.5+s, ch*9.+s, ch*10.+s }; std::array x2; for(size_t i = 0; i < x.size(); ++i) { x2[i] = x[i]*x[i]; } auto* graph1 = new myGraph(x.size(), x.data(), x2.data()); projectionCanvas->GetCanvas()->cd(); graph1->Draw("a*"); } auto subTab2 = new TGTab(channelTab, 600, 500); auto plotTab1 = subTab2->AddTab("Plot 1"); auto plotTab2 = subTab2->AddTab("Plot 2"); auto calibrationCanvas = new TRootEmbeddedCanvas("CalibrationCanvas", plotTab1, 600, 400); plotTab1->AddFrame(calibrationCanvas, new TGLayoutHints(kLHintsRight | kLHintsTop | kLHintsExpandY | kLHintsExpandX, 2, 2, 2, 2)); auto fwhmCanvas = new TRootEmbeddedCanvas("FwhmCanvas", plotTab2, 600, 400); plotTab2->AddFrame(fwhmCanvas, new TGLayoutHints(kLHintsRight | kLHintsTop | kLHintsExpandY | kLHintsExpandX, 2, 2, 2, 2)); channelTab->AddFrame(subTab1, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandY, 2, 2, 2, 2)); channelTab->AddFrame(subTab2, new TGLayoutHints(kLHintsTop | kLHintsRight | kLHintsExpandY, 2, 2, 2, 2)); calibrationCanvas->GetCanvas()->cd(); auto* calibrationPad = new TPad("cal_1", "calibration for 1", 0.2, 0., 1., 1.); calibrationPad->SetNumber(1); calibrationPad->Draw(); calibrationCanvas->GetCanvas()->cd(); auto* residualPad = new TPad("res_1", "residual for 1", 0.0, 0., 0.2, 1.); residualPad->SetNumber(2); residualPad->Draw(); std::array x = { ch*0., ch*1., ch*2., ch*4., ch*5., ch*6., ch*7., ch*8.5, ch*9., ch*10. }; std::array sqrtX; for(size_t i = 0; i < x.size(); ++i) { sqrtX[i] = TMath::Sqrt(x[i]); } auto* graph2 = new myGraph(x.size(), x.data(), sqrtX.data()); calibrationPad->cd(); graph2->Draw("a*"); //// plot 1D histogram on projection canvas //projectionCanvas1->GetCanvas()->cd(); //GH1D::VerboseLevel(3); //auto* hist = new GH1D(static_cast(_file0->Get("hEnergyVsCrystal"))->ProjectionY()); //hist->Draw(); } // bottom frame with navigation button group, text entries, etc. auto bottomFrame = new TGHorizontalFrame(mainFrame, 1200, 50); auto leftFrame = new TGVerticalFrame(bottomFrame, 600, 50); auto navigationGroup = new TGHButtonGroup(leftFrame, "test"); auto previousButton = new TGTextButton(navigationGroup, "Previous"); auto calibrateButton = new TGTextButton(navigationGroup, "Calibrate"); auto doneButton = new TGTextButton(navigationGroup, "Done"); auto nextButton = new TGTextButton(navigationGroup, "Next"); leftFrame->AddFrame(navigationGroup, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 2, 2, 2)); bottomFrame->AddFrame(leftFrame, new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 2, 2, 2, 2)); auto rightFrame = new TGVerticalFrame(bottomFrame, 600, 50); auto sigmaEntry = new TGNumberEntry(rightFrame, 2., 5, 0, TGNumberFormat::EStyle::kNESRealOne, TGNumberFormat::EAttribute::kNEAPositive); auto thresholdEntry = new TGNumberEntry(rightFrame, 0.05, 5, 1, TGNumberFormat::EStyle::kNESRealTwo, TGNumberFormat::EAttribute::kNEAPositive, TGNumberFormat::ELimit::kNELLimitMinMax, 0., 1.); auto quadraticButton = new TGCheckButton(rightFrame, "Include quadratic term"); rightFrame->AddFrame(sigmaEntry, new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 2, 2, 2, 2)); rightFrame->AddFrame(thresholdEntry, new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 2, 2, 2, 2)); rightFrame->AddFrame(quadraticButton, new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 2, 2, 2, 2)); bottomFrame->AddFrame(rightFrame, new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 2, 2, 2, 2)); mainFrame->AddFrame(tab, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 0, 0, 0, 0)); mainFrame->AddFrame(bottomFrame, new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 2, 2, 2, 2)); // Map all subwindows of main frame mainFrame->MapSubwindows(); // Initialize the layout algorithm mainFrame->Resize(TGDimension(1200, 600)); // Map main frame mainFrame->MapWindow(); }