Replace Minuit2 in PluginManager

Dear experts,

I want to use a slightly modified Minuit2Minimizer class for my analysis. Since I’m using the conda version of ROOT v6.24, I cannot recompile the source code. I wrote some c++ code (attached) and compiled it into a shared library. Then I added the new class to PluginManager and to force Factory.cxx to instantiate my implementation but it clearly did not worked, since the dynamic cast failed.

The question is: how can I properly add my modified Minuit2Minimizer to PluginManager so that RooFit uses it instead of the default Minuit2Minimizer?

To run the test scripts:

g++ -O3 -Wall -fPIC -W -I. $( root-config --cflags ) $( root-config --libs ) -lRooFitCore -lRooFit -lMinuit2 Minuit3Minimizer.cxx -shared -o libMinuit3Minimizer.so
g++ -O3 -Wall -fPIC -W -I. $( root-config --cflags ) $( root-config --libs ) -lRooFitCore -lRooFit -lMinuit2 -Wl,-rpath=. -L. -lMinuit3Minimizer test_Minuit3.C -o test_Minuit3
./test_Minuit3

A feature request: Can Minuit2Minimizer expose the fMinimum private member variable via a public function? Being able to get the first derivatives is very useful to debug problematic and complex fits. I know Minuit2 can print first derivatives with printLevel set to DEBUG, but the log files are excessively large and I need to parse the strings into floats.

Thank you for looking at my post!

Minuit3Minimizer.cxx (43.3 KB)
Minuit3Minimizer.h (12.6 KB)
test_Minuit3.C (2.7 KB)

Hi @Da_Yu_Tou ,

Thank you for posting your question on the forum! You are very close to a working example, just a couple of small details left in your test_Minuit3.C script:

  1. Other than loading the shared library, you should also declare the header with the class definition for things to be properly setup, just add a call to

    gInterpreter->Declare("#include \"Minuit3Minimizer.h\"");
    

    Before calling gSystem->Load().

  2. The call to the plugin manager needs to be slightly modified, from your initial example:

    TPluginManager *pm = gROOT->GetPluginManager();
    pm->AddHandler(
        "ROOT::Math::Minimizer",
        "Minuit2",
        "ROOT::Minuit2::Minuit3Minimizer",
        "Minuit2",
        "Minuit3Minimizer(const char *)");
    

    to (you can directly use the gPluginMgr object)

    gPluginMgr->AddHandler(
    "ROOT::Math::Minimizer",
    "MyMinimizerName", // needs to match the call to minimizer.setMinimizerType
    "ROOT::Minuit2::Minuit3Minimizer",
    "Minuit3Minimizer",
    "Minuit3Minimizer(const char *)");
    

    Note especially that the secret sauce is the second argument to this function. Here I used the randomly chosen name MyMinimizerName, this name needs to match what you are calling later on in the line minimizer.setMinimizerType("MyMinimizerName") (it can actually be also a matching regex, but for simplicity and sanity it’s easier if it just matches 1:1).

Let me know if this helps.

Cheers,
Vincenzo

2 Likes

Hi Vincenzo,

Thanks for the solution! It works perfectly.

Cheers,
Da Yu

Dear Vincenzo,

One more question about implementing this in an analysis. It seems I have to add the include path and library path to gInterpreter during runtime.

    gInterpreter->AddIncludePath(HEADER_DIR);
    gInterpreter->Declare("#include \"Minuit3Minimizer.h\"");
    gSystem->AddDynamicPath(MYLIB_DIR);
    gSystem->Load("libMinuit3Minimizer");

This is despite me baking the library path into my executable (note rpath)

g++ -O3 -Wall -fPIC -W -I. $( root-config --cflags ) $( root-config --libs ) -lRooFitCore -lRooFit -lMinuit2 -Wl,-rpath=<dir/to/libMinuit3Minimizer> -L<dir/to/libMinuit3Minimizer> -lMinuit3Minimizer test_Minuit3.C -o test_Minuit3

Is this unavoidable for the shared lib directory? I guess the another method is to set environment variables PATH (for header) and LD_LIBRARY_PATH (for shared library).

Cheers,
Da Yu

Hi,

That is indeed a good question. I guess here the problem is more letting the ROOT interpreter know where it can find headers/shared libraries (i.e. include path and dynamic path) rather than embedding that information in the library itself with the rpath. So I would say that indeed you need to extend those variables somehow (either of the two approaches that you describe should work).

I will invite @pcanal or @vvassilev to comment further if I’m missing anything here.

Cheers,
Vincenzo

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.