Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions gui/fitpanel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ ROOT_STANDARD_LIBRARY_PACKAGE(FitPanel
Tree
TreePlayer
)

ROOT_ADD_TEST_SUBDIRECTORY(test)
12 changes: 12 additions & 0 deletions gui/fitpanel/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright (C) 1995-2026, Rene Brun and Fons Rademakers.
# All rights reserved.
#
# For the licensing terms see $ROOTSYS/LICENSE.
# For the list of contributors see $ROOTSYS/README/CREDITS.

# @author Danilo Piparo CERN

ROOT_EXECUTABLE(fitPanelUnitTesting UnitTesting.cxx LIBRARIES FitPanel Gui Tree Hist MathCore)
ROOT_ADD_TEST(test-fitpanel-UnitTesting COMMAND fitPanelUnitTesting)
set_tests_properties(test-fitpanel-UnitTesting PROPERTIES WILL_FAIL true) # Problems with batch mode https://github.com/root-project/root/issues/21881
target_include_directories(fitPanelUnitTesting PRIVATE ../src/)
47 changes: 0 additions & 47 deletions gui/fitpanel/test/Makefile

This file was deleted.

80 changes: 69 additions & 11 deletions gui/fitpanel/test/UnitTesting.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,27 @@

#include "TGComboBox.h"

#include "TF2.h"
#include "TMath.h"
#include "TRandom2.h"
#include "TTree.h"

#include <iostream>
#include <exception>
#include <stdexcept>
#include <cmath>
#include <cstdio>

#include "CommonDefs.h"

#ifdef WIN32
#include "io.h"
#else
#include "unistd.h"
#endif

// Function that compares to doubles up to an error limit
int equals(Double_t n1, Double_t n2, double ERRORLIMIT = 1.E-10)
int equals(Double_t n1, Double_t n2, double ERRORLIMIT = 1.E-5)
{
return fabs( n1 - n2 ) > ERRORLIMIT * fabs(n1);
}
Expand All @@ -34,6 +46,35 @@ int SelectEntry(TGComboBox* cb, const char* name)
return findEntry->EntryId();
}

void createTree(int n = 100)
{
TTree *tree = new TTree("tree","2 var gaus tree");
double x, y, z, u, v, w;
tree->Branch("x", &x, "x/D");
tree->Branch("y", &y, "y/D");
tree->Branch("z", &z, "z/D");
tree->Branch("u", &u, "u/D");
tree->Branch("v", &v, "v/D");
tree->Branch("w", &w, "w/D");
TRandom2 rndm;
double origPars[13] = {1,2,3,0.5, 0.5, 0, 3, 0, 4, 0, 5, 1, 10 };
TF2 f2("f2", "bigaus", -10, 10,-10, 10);
f2.FixParameter(0, 1. / (2. * TMath::Pi() * origPars[1] * origPars[3] * TMath::Sqrt(origPars[4]))); // constant (max-value), irrelevant
f2.FixParameter(1, origPars[0]); // mu_x
f2.FixParameter(2, origPars[1]); // sigma_x
f2.FixParameter(3, origPars[2]); // mu_y
f2.FixParameter(4, origPars[3]); // sigma_y
f2.FixParameter(5, origPars[4]); // rho
for (Int_t i = 0 ; i < n; i++) {
f2.GetRandom2(x, y, &rndm);
z = rndm.Gaus(origPars[5],origPars[6]);
u = rndm.Gaus(origPars[7],origPars[8]);
v = rndm.Gaus(origPars[9],origPars[10]);
w = rndm.Gaus(origPars[11],origPars[12]);
tree->Fill();
}
}

// Class to make the Unit Testing. It is important than the test
// methods are inside the class as this in particular is defined as a
// friend of the TFitEditor. This way, we can access the private
Expand All @@ -58,22 +99,37 @@ class FitEditorUnitTesting
const char* _exp;
public:
InvalidPointer(const char* exp): _exp(exp) {};
const char* what() { return _exp; };
const char* what() const noexcept override { return _exp; };
};

// Constructor: Receives the instance of the TFitEditor
FitEditorUnitTesting() {
// Redirect the stdout to a file outputUnitTesting.txt
#ifdef WIN32
old_stdout = _dup (_fileno (stdout));
#else
old_stdout = dup (fileno (stdout));
(void) freopen ("outputUnitTesting.txt", "w", stdout);
#endif
auto res = freopen ("outputUnitTesting.txt", "w", stdout);
if (!res) {
throw InvalidPointer("In FitEditorUnitTesting constructor cannot freopen");
}
#ifdef WIN32
out = _fdopen (old_stdout, "w");
#else
out = fdopen (old_stdout, "w");
#endif

// Execute the initial script
gROOT->ProcessLine(".x $ROOTSYS/tutorials/fit/FittingDemo.C+");
TString scriptLine = TString(".x ") + TROOT::GetTutorialDir() + "/math/fit/FittingDemo.C+";
gROOT->ProcessLine(scriptLine.Data());

// Get an instance of the TFitEditor
TCanvas* c1 = static_cast<TCanvas*>( gROOT->FindObject("c1") );
TH1* h = static_cast<TH1*> ( gROOT->FindObject("histo") );
if (!c1 || !h) {
throw InvalidPointer("In c1 or h initialization");
}

f = TFitEditor::GetInstance(c1,h);

Expand Down Expand Up @@ -176,7 +232,9 @@ class FitEditorUnitTesting
for ( unsigned int i = 0; i < f->fFuncPars.size(); ++i ) {
for ( unsigned int j = 0; j < 3; ++j) {
int internalStatus = equals(pars[i][j], f->fFuncPars[i][j]);
//fprintf(out, "i: %d, j: %d, e: %d\n", i, j, internalStatus);
if (internalStatus != 0) {
fprintf(out, "i: %d, j: %d, e: %d, diff %g\n", i, j, internalStatus, TMath::Abs(pars[i][j] - f->fFuncPars[i][j]));
}
status += internalStatus;
}
}
Expand All @@ -186,7 +244,7 @@ class FitEditorUnitTesting

// From here, the implementation of the different tests. The names
// of the test should be enough to know what they are testing, as
// these tests are mean to be as simple as possible.
// these tests are meant to be as simple as possible.

int TestHistogramFit() {
f->fTypeFit->Select(kFP_UFUNC, kTRUE);
Expand Down Expand Up @@ -222,7 +280,8 @@ class FitEditorUnitTesting
}

int TestUpdate() {
gROOT->ProcessLine(".x $ROOTSYS/tutorials/fit/ConfidenceIntervals.C+");
TString scriptLine = TString(".x ") + TROOT::GetTutorialsDir() + "/math/fit/ConfidenceIntervals.C+";
gROOT->ProcessLine(scriptLine.Data());
f->DoUpdate();

return 0;
Expand Down Expand Up @@ -311,7 +370,7 @@ class FitEditorUnitTesting
}

int TestUpdateTree() {
gROOT->ProcessLine(".x ~/tmp/fitpanel/createTree.C++");
createTree();
f->DoUpdate();
return 0;
}
Expand All @@ -326,11 +385,10 @@ class FitEditorUnitTesting
f->ProcessTreeInput(objSelected, selected, "x", "y>1");
f->fTypeFit->Select(kFP_PRED1D, kTRUE);
SelectEntry(f->fFuncList, "gausn");

f->fFuncPars.resize(3);
f->fFuncPars[0][0] = f->fFuncPars[0][1] = f->fFuncPars[0][2] = 1;
f->fFuncPars[1][0] = 0;
f->fFuncPars[2][0] = 1;
f->fFuncPars[1][0] = 0; f->fFuncPars[1][1] = f->fFuncPars[1][2] = 0;
f->fFuncPars[2][0] = 1; f->fFuncPars[2][1] = f->fFuncPars[2][2] = 0;

f->DoFit();

Expand Down
10 changes: 7 additions & 3 deletions hist/hist/src/TFormula.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,15 @@ std::string vectorizedArgType()
- `cheb0,1,2,...N` is a substitute for a Chebyshev polynomial of degree `N`:
`ROOT::Math::Chebyshev10(x,[p0],[p1],[p2],...[pN])`. Note the maximum N allowed here is 10.
2. Two Dimensional functions:
- `xygaus` is a substitute for `[Constant]*exp(-0.5*pow(((x-[MeanX])/[SigmaX]),2 )- 0.5*pow(((y-[MeanY])/[SigmaY]),2))`, a 2d Gaussian without correlation.
- `bigaus` is a substitute for `[Constant]*ROOT::Math::bigaussian_pdf (x,y,[SigmaX],[SigmaY],[Rho],[MeanX],[MeanY])`, a 2d gaussian including a correlation parameter.
- `xygaus` is a substitute for `[Constant]*exp(-0.5*pow(((x-[MeanX])/[SigmaX]),2 )-
0.5*pow(((y-[MeanY])/[SigmaY]),2))`, a 2d Gaussian without correlation.
- `bigaus` is a substitute for `[Constant]*ROOT::Math::bigaussian_pdf
(x,y,[SigmaX],[SigmaY],[Rho],[MeanX],[MeanY])`, a 2d gaussian including a correlation parameter. Note the different
order of parameters for bigaus: [Constant]=[0], [SigmaX]=[2], [SigmaY]=[4], [Rho]=[5], [MeanX]=[1], [MeanY]=[3]
3. Three Dimensional functions:
- `xyzgaus` is for a 3d Gaussians without correlations:
`[Constant]*exp(-0.5*pow(((x-[MeanX])/[SigmaX]),2 )- 0.5*pow(((y-[MeanY])/[SigmaY]),2 )- 0.5*pow(((z-[MeanZ])/[SigmaZ]),2))`
`[Constant]*exp(-0.5*pow(((x-[MeanX])/[SigmaX]),2 )- 0.5*pow(((y-[MeanY])/[SigmaY]),2 )-
0.5*pow(((z-[MeanZ])/[SigmaZ]),2))`


### An expanded note on variables and parameters
Expand Down
Loading