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
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
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
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
The call to the plugin manager needs to be slightly modified, from your initial example:
TPluginManager *pm = gROOT->GetPluginManager();
"Minuit3Minimizer(const char *)");
to (you can directly use the
"MyMinimizerName", // needs to match the call to minimizer.setMinimizerType
"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.
Thanks for the solution! It works perfectly.
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.
This is despite me baking the library path into my executable (note
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).
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.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.