Skip to content

Added test and improved implementation of RooMultiPdf class in codegen #19231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

GalinBistrev2
Copy link
Contributor

@GalinBistrev2 GalinBistrev2 commented Jun 30, 2025

Here is the implementation of RooMultiPdf in codegen.A new MathFunc was added for RooMultiPdf and was used in the CodegenImpl.cxx file along with ternary expression genarator which serves the same purpose as the MathFunc.Those two methods do the same thing.The difference is that MathFunc works better for more than 2 pdfs listed.An additional sequence of lines was added for also for RooCategory since the implementation of the RooMultiPdf in the codegen can't work without it. A gtest file was made in order to test wheter the NLL is calculated correctly and whether the RooMultiPdf object correctly chooses the pdf.
The output of the test is the following

Running main() from ./googletest/src/gtest_main.cc
[==========] Running 2 tests from 2 test suites.
[----------] Global test environment set-up.
[----------] 1 test from RooMultiPdf
[ RUN      ] RooMultiPdf.SelectsCorrectPdf
[       OK ] RooMultiPdf.SelectsCorrectPdf (0 ms)
[----------] 1 test from RooMultiPdf (0 ms total)

[----------] 1 test from RooMultiPdfTest
[ RUN      ] RooMultiPdfTest.FitConvergesAndReturnsReasonableResult
[#1] INFO:Fitting -- RooAbsPdf::fitTo(roomultipdf) fixing normalization set for coefficient determination to observables in data
[#1] INFO:Fitting -- Creation of NLL object took 150.757 μs
[#1] INFO:Fitting -- using generic CPU library compiled with no vectorizations
[codegen debug] Category 'my_special_index' mapped to obs[1]
[#1] INFO:Fitting -- Function JIT time: 130.753 ms
In module 'RooFitCore':
/home/gbistrev/root_work/root_install/include/RooFit/Detail/MathFuncs.h:401:45: warning: function 'LnGamma' was not differentiated because clad failed to differentiate it and no suitable overload was found in namespace 'custom_derivatives'
      return pdf - weight * std::log(pdf) + TMath::LnGamma(weight + 1);
                                            ^
/home/gbistrev/root_work/root_install/include/RooFit/Detail/MathFuncs.h:401:45: note: falling back to numerical differentiation for 'LnGamma' since no suitable overload was found and clad could not derive it; to disable this feature, compile your programs with -DCLAD_NO_NUM_DIFF
[#1] INFO:Fitting -- Gradient generation time: 38.7014 ms
[#1] INFO:Fitting -- Gradient IR to machine code time: 42.8013 ms
Minuit2Minimizer: Minimize with max-calls 2000 convergence for edm < 1 strategy 0
Info in <Minuit2>: MnSeedGenerator Using analytical (external) gradient calculator but cannot compute G2 - use then numerical gradient for G2
Info in <Minuit2>: MnSeedGenerator Computing seed using NumericalGradient calculator
Info in <Minuit2>: MnSeedGenerator Evaluated function and gradient in 623.563 μs
Info in <Minuit2>: MnSeedGenerator Initial state: FCN =       1457.866472 Edm =       1.378378943 NCalls =     17
Info in <Minuit2>: NegativeG2LineSearch Doing a NegativeG2LineSearch since one of the G2 component is negative
Info in <Minuit2>: NegativeG2LineSearch Done after 5.818 μs
Info in <Minuit2>: MnSeedGenerator Negative G2 found - new state: 
  Minimum value : 1457.866472
  Edm           : 1.378378943
  Internal parameters:	[      1.126362609     -1.370461484     -1.370461484     -0.927595308]	
  Internal gradient  :	[                0                0                0     -233.4581708]	
  Internal covariance matrix:
[[              2              0              0              0]
 [              0              2              0              0]
 [              0              0              2              0]
 [              0              0              0  0.00010116038]]]
Info in <Minuit2>: MnSeedGenerator Initial state  
  Minimum value : 1457.866472
  Edm           : 1.378378943
  Internal parameters:	[      1.126362609     -1.370461484     -1.370461484     -0.927595308]	
  Internal gradient  :	[                0                0                0     -233.4581708]	
  Internal covariance matrix:
[[              2              0              0              0]
 [              0              2              0              0]
 [              0              0              2              0]
 [              0              0              0  0.00010116038]]]
Info in <Minuit2>: VariableMetricBuilder Start iterating until Edm is < 0.001 with call limit = 2000
Info in <Minuit2>: VariableMetricBuilder    0 - FCN =       1457.866472 Edm =       1.378378943 NCalls =     17
Info in <Minuit2>: VariableMetricBuilder    1 - FCN =         1456.4313 Edm =    0.005162270386 NCalls =     18
Info in <Minuit2>: VariableMetricBuilder    2 - FCN =       1456.425418 Edm =   1.532979833e-08 NCalls =     20
Info in <Minuit2>: VariableMetricBuilder Stop iterating after 428.289 μs
Minuit2Minimizer : Valid minimum - status = 0
FVAL  = 1456.42541771124661
Edm   = 1.53297983275155071e-08
Nfcn  = 20
expo_1	  = -0.01	 +/-  0.0414417	(limited)
poly_1	  = 0.02	 +/-  0.450504	(limited)
poly_2	  = 0.02	 +/-  0.450504	(limited)
sigma1	  = 1.03819	 +/-  0.0231629	(limited)
[#1] INFO:Fitting -- RooAbsPdf::fitTo(gaus1_over_gaus1_Int[x]) fixing normalization set for coefficient determination to observables in data
[#1] INFO:Fitting -- Creation of NLL object took 99.678 μs
[#1] INFO:Fitting -- Function JIT time: 4.17018 ms
[#1] INFO:Fitting -- Gradient generation time: 5.95955 ms
[#1] INFO:Fitting -- Gradient IR to machine code time: 5.58796 ms
Minuit2Minimizer: Minimize with max-calls 2000 convergence for edm < 1 strategy 0
Info in <Minuit2>: MnSeedGenerator Using analytical (external) gradient calculator but cannot compute G2 - use then numerical gradient for G2
Info in <Minuit2>: MnSeedGenerator Computing seed using NumericalGradient calculator
Info in <Minuit2>: MnSeedGenerator Evaluated function and gradient in 526.22 μs
Info in <Minuit2>: MnSeedGenerator Initial state: FCN =       1457.866472 Edm =       1.378378943 NCalls =     17
Info in <Minuit2>: NegativeG2LineSearch Doing a NegativeG2LineSearch since one of the G2 component is negative
Info in <Minuit2>: NegativeG2LineSearch Done after 2.534 μs
Info in <Minuit2>: MnSeedGenerator Negative G2 found - new state: 
  Minimum value : 1457.866472
  Edm           : 1.378378943
  Internal parameters:	[      1.126362609     -1.370461484     -1.370461484     -0.927595308]	
  Internal gradient  :	[                0                0                0     -233.4581708]	
  Internal covariance matrix:
[[              2              0              0              0]
 [              0              2              0              0]
 [              0              0              2              0]
 [              0              0              0  0.00010116038]]]
Info in <Minuit2>: MnSeedGenerator Initial state  
  Minimum value : 1457.866472
  Edm           : 1.378378943
  Internal parameters:	[      1.126362609     -1.370461484     -1.370461484     -0.927595308]	
  Internal gradient  :	[                0                0                0     -233.4581708]	
  Internal covariance matrix:
[[              2              0              0              0]
 [              0              2              0              0]
 [              0              0              2              0]
 [              0              0              0  0.00010116038]]]
Info in <Minuit2>: VariableMetricBuilder Start iterating until Edm is < 0.001 with call limit = 2000
Info in <Minuit2>: VariableMetricBuilder    0 - FCN =       1457.866472 Edm =       1.378378943 NCalls =     17
Info in <Minuit2>: VariableMetricBuilder    1 - FCN =         1456.4313 Edm =    0.005162270386 NCalls =     18
Info in <Minuit2>: VariableMetricBuilder    2 - FCN =       1456.425418 Edm =   1.532979833e-08 NCalls =     20
Info in <Minuit2>: VariableMetricBuilder Stop iterating after 402.511 μs
Minuit2Minimizer : Valid minimum - status = 0
FVAL  = 1456.42541771124661
Edm   = 1.53297983275155071e-08
Nfcn  = 20
expo_1	  = -0.01	 +/-  0.0414417	(limited)
poly_1	  = 0.02	 +/-  0.450504	(limited)
poly_2	  = 0.02	 +/-  0.450504	(limited)
sigma1	  = 1.03819	 +/-  0.0231629	(limited)
[#1] INFO:Fitting -- RooAbsPdf::fitTo(roomultipdf) fixing normalization set for coefficient determination to observables in data
[#1] INFO:Fitting -- Creation of NLL object took 146.911 μs
[codegen debug] Category 'my_special_index' mapped to obs[1]
[#1] INFO:Fitting -- Function JIT time: 5.39508 ms
[#1] INFO:Fitting -- Gradient generation time: 10.2351 ms
[#1] INFO:Fitting -- Gradient IR to machine code time: 7.95936 ms
[#1] INFO:Fitting -- RooAbsPdf::fitTo(gaus1_over_gaus1_Int[x]) fixing normalization set for coefficient determination to observables in data
[#1] INFO:Fitting -- Creation of NLL object took 106.265 μs
[#1] INFO:Fitting -- Function JIT time: 3.58719 ms
[#1] INFO:Fitting -- Gradient generation time: 5.88378 ms
[#1] INFO:Fitting -- Gradient IR to machine code time: 5.6292 ms
[#1] INFO:Fitting -- RooAbsPdf::fitTo(roomultipdf) fixing normalization set for coefficient determination to observables in data
[#1] INFO:Fitting -- Creation of NLL object took 144.296 μs
[codegen debug] Category 'my_special_index' mapped to obs[1]
[#1] INFO:Fitting -- Function JIT time: 4.7029 ms
[#1] INFO:Fitting -- Gradient generation time: 10.3127 ms
[#1] INFO:Fitting -- Gradient IR to machine code time: 7.74175 ms
[#1] INFO:Fitting -- RooAbsPdf::fitTo(polynomial_over_polynomial_Int[x]) fixing normalization set for coefficient determination to observables in data
[#1] INFO:Fitting -- Creation of NLL object took 106.189 μs
[#1] INFO:Fitting -- Function JIT time: 4.31379 ms
[#1] INFO:Fitting -- Gradient generation time: 7.98519 ms
[#1] INFO:Fitting -- Gradient IR to machine code time: 5.45793 ms
[#1] INFO:Fitting -- RooAbsPdf::fitTo(roomultipdf) fixing normalization set for coefficient determination to observables in data
[#1] INFO:Fitting -- Creation of NLL object took 159.243 μs
[codegen debug] Category 'my_special_index' mapped to obs[1]
[#1] INFO:Fitting -- Function JIT time: 5.9376 ms
[#1] INFO:Fitting -- Gradient generation time: 9.86931 ms
[#1] INFO:Fitting -- Gradient IR to machine code time: 7.90473 ms
[#1] INFO:Fitting -- RooAbsPdf::fitTo(exponential_over_exponential_Int[x]) fixing normalization set for coefficient determination to observables in data
[#1] INFO:Fitting -- Creation of NLL object took 101.168 μs
[#1] INFO:Fitting -- Function JIT time: 3.7478 ms
[#1] INFO:Fitting -- Gradient generation time: 5.15601 ms
[#1] INFO:Fitting -- Gradient IR to machine code time: 5.43311 ms
[       OK ] RooMultiPdfTest.FitConvergesAndReturnsReasonableResult (723 ms)
[----------] 1 test from RooMultiPdfTest (723 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 2 test suites ran. (723 ms total)
[  PASSED  ] 2 tests.

Copy link

github-actions bot commented Jul 1, 2025

Test Results

    19 files      19 suites   3d 19h 35m 15s ⏱️
 3 158 tests  3 158 ✅ 0 💤 0 ❌
58 465 runs  58 465 ✅ 0 💤 0 ❌

Results for commit ec3b07d.

♻️ This comment has been updated with latest results.

@@ -36,6 +37,7 @@ class RooExtendPdf;
class RooFormulaVar;
class RooGamma;
class RooGaussian;
class RooMultiPdf;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you keep the list of classes here in alphabetical order like before? Thanks

@@ -81,6 +83,7 @@ void codegenImpl(ParamHistFunc &arg, CodegenContext &ctx);
void codegenImpl(PiecewiseInterpolation &arg, CodegenContext &ctx);
void codegenImpl(RooAbsArg &arg, CodegenContext &ctx);
void codegenImpl(RooAddPdf &arg, CodegenContext &ctx);
void codegenImpl(RooCategory &arg, CodegenContext &ctx);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alphabetical order

@@ -105,6 +108,7 @@ void codegenImpl(RooParamHistFunc &arg, CodegenContext &ctx);
void codegenImpl(RooPoisson &arg, CodegenContext &ctx);
void codegenImpl(RooPolyVar &arg, CodegenContext &ctx);
void codegenImpl(RooPolynomial &arg, CodegenContext &ctx);
void codegenImpl(RooMultiPdf &arg, CodegenContext &ctx);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alphabetical order

@@ -80,4 +80,4 @@ void rf101_basics()
gPad->SetLeftMargin(0.15);
xframe2->GetYaxis()->SetTitleOffset(1.6);
xframe2->Draw();
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change in the rf101_basics.C file is unnecessary.

Copy link
Contributor

@guitargeek guitargeek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @GalinBistrev2, thank you very much for this PR! I have made a few change requests, mostly related to code style.

@GalinBistrev2 GalinBistrev2 force-pushed the fix-root-rebased branch 3 times, most recently from 36653b5 to 6fe76c2 Compare July 2, 2025 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants