RDataFrame not making a new .root file


Please read tips for efficient and successful posting and posting code

ROOT Version: 6.32.02
Platform: Windows 11
Compiler: MSVC 19.39.33521.0


I am attempting to write a macro that will take an existing root file, make cuts (proton momentum, phi mass, etc), and make a new version of the file containing only the events that pass the cuts.

There are no error messages when I run the code, but I can’t seem to find the new file anywhere. I’ve created new root files before (this is the first time I’m trying RDataFrame) so I know the specific directory that the new file should be in, but alas! Nothing!

I’d appreciate any help I can get. Thanks!

using PxPyPzE = ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<double>>;

void cutter_Macro() {
    ROOT::EnableImplicitMT();

    //Input File and input tree
    auto inFileName = "flat_pi0pippim__B4.root";
    auto outFileName = "flat_pi0pippim__B4_cut.root";
    auto treeName = "pi0pippim__B4;1";
    TFile *filein = new TFile(inFileName);
    TTree *tree = (TTree *)filein->Get(treeName);

    //Making the 4-vectors
    PxPyPzE Gamma1P4, Gamma2P4, Pi0P4, ProtonP4, PiMinusP4, PiPlusP4, PhiP4;

    auto proton_4Vec = [&ProtonP4](PxPyPzE p_p4_kin) { return ProtonP4.SetPxPyPzE(p_p4_kin.Px(), p_p4_kin.Py(), p_p4_kin.Pz(), p_p4_kin.E()); };
    auto pim_4Vec = [&PiMinusP4](PxPyPzE pim_p4_kin) { return PiMinusP4.SetPxPyPzE(pim_p4_kin.Px(), pim_p4_kin.Py(), pim_p4_kin.Pz(), pim_p4_kin.E()); };
    auto pip_4Vec = [&PiPlusP4](PxPyPzE pip_p4_kin) { return PiPlusP4.SetPxPyPzE(pip_p4_kin.Px(), pip_p4_kin.Py(), pip_p4_kin.Pz(), pip_p4_kin.E()); };
    auto g1_4Vec = [&Gamma1P4](PxPyPzE g1_p4_kin) { return Gamma1P4.SetPxPyPzE(g1_p4_kin.Px(), g1_p4_kin.Py(), g1_p4_kin.Pz(), g1_p4_kin.E()); };
    auto g2_4Vec = [&Gamma2P4](PxPyPzE g2_p4_kin) { return Gamma2P4.SetPxPyPzE(g2_p4_kin.Px(), g2_p4_kin.Py(), g2_p4_kin.Pz(), g2_p4_kin.E()); };

    auto pi0_4Vec = [&Pi0P4, Gamma1P4, Gamma2P4]() { return Gamma1P4 + Gamma2P4; };
    auto phi_4Vec = [&PhiP4, PiPlusP4, PiMinusP4, Pi0P4]() { return PiPlusP4 + PiMinusP4 + Pi0P4; };

    //Create an RDataFrame from the input
    ROOT::RDataFrame d(treeName, inFileName);

    //Adding columns
    auto d_4Vec = d.Define("Gamma1_4Vec", g1_4Vec, {"g1_p4_kin"})
        .Define("Gamma2_4Vec", g2_4Vec, {"g2_p4_kin"})
        .Define("PiPlus_4Vec", pip_4Vec, {"pip_p4_kin"})
        .Define("PiMinus_4Vec", pim_4Vec, {"pim_p4_kin"})
        .Define("Pi0_4Vec", pi0_4Vec, {"Gamma1_4Vec", "Gamma2_4Vec"})
        .Define("Proton_4Vec", proton_4Vec, {"p_p4_kin"})
            .Define("ProtonMom", "Proton_4Vec.P()")
        .Define("Phi_4Vec", phi_4Vec, {"PiPlus_4Vec", "PiMinus_4Vec", "Pi0_4Vec"})
            .Define("PhiMass", "Phi_4Vec.M()");

    //Cutting the RDataFrame
    auto t_cut = [](float Mandlestam_t) { return -Mandlestam_t < 1; };
    auto chi2NDF_cut = [](UInt_t kin_ndf, float kin_chisq) { return (kin_chisq / kin_ndf) < 6; };
    auto protonMom_cut = [](double ProtonMom) { return ProtonMom > 0.3; };
    auto phiMass_cut = [](double PhiMass) { return 0.9 < PhiMass < 1.14; };

    auto d_4Vec_cut = d_4Vec.Filter(chi2NDF_cut, {"kin_ndf", "kin_chisq"})
        .Filter(t_cut, {"Mandlestam_t"})
        .Filter(protonMom_cut, {"ProtonMom"})
        .Filter(phiMass_cut, {"PhiMass"});

    //Snapshot and create new file
    d_4Vec_cut.Snapshot("pi0pippim__B4_cut", "flat_pi0pippim__B4_cut.root");
}

Dear @jbrom ,

Thanks for reaching out to the forum! I don’t see anything immediately suspicious from the code you sent. Do I understand correctly that if you run run cutter_Macro.C, the file flat_pi0pippim__B4_cut.root is not produced in the same directory from where you are running the macro? Just to confirm that the RDataFrame has run, can you print the number of event loops after the Snapshot operation, e.g.

std::cout << "RDataFrame has run " << d.GetNRuns() << " times.\n";

You could also see the event loop happening with the verbosity mode, which you can activate by copy pasting the code at ROOT: ROOT::RDataFrame Class Reference

Cheers,
Vincenzo

I pasted that line of code and added a progress bar but nothing changes. This is what I get from the terminal:

PS C:\Users\gleasonc\Bromberg2024-2025> root -l cutter_Macro.C
cling::DynamicLibraryManager::loadLibrary(): LoadLibrary: returned 126: The specified module could not be found.
cling::DynamicLibraryManager::loadLibrary(): LoadLibrary: returned 126: The specified module could not be found.
root [0] 
Processing cutter_Macro.C...
PS C:\Users\gleasonc\Bromberg2024-2025> 

(Don’t worry about the cling error. That’s always there but doesn’t seem to affect anything)

I pasted that line of code and added a progress bar but nothing changes.

Nothing is supposed to “change”, it was just to show something to screen to check that at least the event loop is running. If after adding those lines you still don’t see any type of output to screen, it means that the entire application is not running, so something is extremely wrong in your environment or in you ROOT installation, or both.

cling::DynamicLibraryManager::loadLibrary(): LoadLibrary: returned 126: The specified module could not be found.

I doubt that this error is completely safe, at the very least the interpreter is not able to fully initialize (which tangentially will make most of RDataFrame and ROOT in general not work properly). I see you are running on Windows, so maybe @bellenot has something to add here, although again let me stress that I believe there is something wrong with the environment/installation.

Cheers,
Vincenzo

Hi, can you provide a minimal reproducer we can use? And as Vincenzo said, these errors:

cling::DynamicLibraryManager::loadLibrary(): LoadLibrary: returned 126: The specified module could not be found.
cling::DynamicLibraryManager::loadLibrary(): LoadLibrary: returned 126: The specified module could not be found.

Show that there is probably something wrong in your environment…

I do not have a similar file that is small enough to upload (the smallest I have is around 1 GB).

I just took the time to look at the differences between the ROOT build on my PC and my laptop (ROOT 6.26/10, win64, MSVC 19.32.31332.0) and noticed that my PC does in fact have cling built on clang 16. If I understand correctly, wouldn’t this mean that cling was built when I installed ROOT a couple months ago? Would installing the most recent version of ROOT build a version of cling without this issue?

Sorry, I don’t really understand your question, but you can indeed try the latest version of ROOT

I installed the newest version of ROOT and the same error appears. At this point should I make a separate post about this issue with the “cling” tag?

No, it’s not a cling issue but a ROOT one. You are using ROOT, right?
And as I said, it looks like something is missing in your environment. Can you describe exactly where you installed ROOT and how you start it? Since it looks like in PowerShell, did you properly execute root\bin\thisroot.ps1? Can you try to start ROOT from a x64 Native Tools Command Prompt for VS 2022 and try again? You can also try to set the gDebug value to 1 (or more, but the verbosity increase rapidly) to see which library is not loaded

I installed the Windows Visual Studio 2022 64-bit x64 binary distribution of ROOT (.exe). It is installed in C:\Program Files\ROOT\root_v6.34.02. I have set the bin folder to path so that all I have to do to open root in the terminal is type “root”

I have the default directory for the terminal set as the folder with all of my macros, data files, histograms, etc. so that everything is saved there.

I just ran thisroot.ps1 with VSCode and tried to run ROOT again. Same loadLibrary error. Then I did the same thing from x64 Native Tools Command Prompt for VS 2022 and same thing. What do I do to change the gDebug value?

Also, this is what thisroot.ps1 looks like:

$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$ROOTSYS = split-path -parent (get-item $scriptPath)
$env:PATH = $ROOTSYS + '\bin;' + $env:PATH
$env:CMAKE_PREFIX_PATH = $ROOTSYS + ';' + $env:CMAKE_PREFIX_PATH
$env:PYTHONPATH = $ROOTSYS + '\bin;' + $env:PYTHONPATH
$env:CLING_STANDARD_PCH = "none"

I don’t know much about these kinds of scripts (or most kinds) but shouldn’t the cling line have an assignment similar to the other five lines rather that just “none”?

OK, so as mentioned in the Important installation notes:

  • Do not untar in a directory with a name containing blank characters.

So can you install it in a directory not containing any blank characters (i.e. without spaces in it, so not in C:\Program Files\) and try again?

Ok. Now ROOT is installed in C:\root_v6.34.02 and the new directory is added to path. I called thisroot.ps1 by following the instructions on the ROOT website and we get this:

C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools>cd %USERPROFILE%

C:\Users\gleasonc>\root_v6.34.02\bin\thisroot.ps1

C:\Users\gleasonc>
[main 2025-01-17T21:35:16.376Z] update#setState idle
(node:10248) [DEP0168] DeprecationWarning: Uncaught N-API callback exception detected, please run node with option --force-node-api-uncaught-exceptions-policy=true to handle those exceptions properly.
(Use `Code --trace-deprecation ...` to show where the warning was created)
[main 2025-01-17T21:35:46.387Z] update#setState checking for updates
[main 2025-01-17T21:35:46.723Z] update#setState idle

It then opens up a similar file in VSCode same as before. I try to run ROOT and the same DynamicLibraryManager errors appear.

This looks totally unrelated to ROOT… And I never seen such error, so I’m out of ideas…