Skip to content

Add a way to keep track of dataframe actions #24057

Open

Description

@acampove

Feature description

Hi,

I have something like:

import ROOT

df = ROOT.RDataFrame(10000)

df = df.Define("B_PT", "gRandom->Uniform(0, 2000)")
df = df.Define("mass", "gRandom->Uniform(0, 5000)")

df = df.Filter("B_PT > 1000")
df = df.Define("pass_mass", "mass < 3000")

df = df.Range(1000)

Here there are actions, definitions, filters etc. How are we supposed to keep track of what happened to that dataframe? I only see Report but besides giving me a cutflow, it does not show me what was defined or how. This makes working with dataframes completely obscure, we get data from a dataframe, but where did that dataframe came from? Did any filter that was not supposed to happen was used? Was a column defined incorrectly? There is no way to know.

The only way I see to fix this problem properly is to wrap these dataframes into a class that keeps track of the actions, exposes Range, Filter etc and implements a save_actions(path, as_json = True). But wouldn't it make more sense if that method exists upstream in ROOT itself?

Cheers.

Alternatives considered

No response

Additional context

No response

Activity

  1. vepadulano commented on Nov 9, 2026

    @vepadulano
    Member

    Hi @acampove ,

    What you ask for already exists and is documented https://root.cern/doc/v632/classROOT_1_1RDataFrame.html#representgraph .

  2. self-assigned this
    on Nov 9, 2026
  3. pinned and unpinned a comment on Nov 9, 2026
  4. acampove commented on Nov 9, 2026

    @acampove
    Author

    Hi @acampove ,

    What you ask for already exists and is documented https://root.cern/doc/v632/classROOT_1_1RDataFrame.html#representgraph .

    That does not do what I asked. How will that graph show me the definition if I do:

    import ROOT
    
    df = ROOT.RDataFrame(10000)
    
    df = df.Define("B_PT", "gRandom->Uniform(0, 2000)")
    df = df.Define("mass", "gRandom->Uniform(0, 5000)")
    
    df = df.Filter("B_PT > 1000", "B_PT selection")
    df = df.Define("pass_mass", "mass < 3000")
    
    df = df.Filter("pass_mass", "Mass selection")
    df = df.Range(1000)
    
    graph = ROOT.RDF.SaveGraph(df)
    print(graph)
    
    with open("graph.dot", "w") as f:
        f.write(graph)

    I see:

    digraph {
            6 [label="Range", style="filled", fillcolor="#9574b4", shape="diamond"];
            4 [label="Mass selection", style="filled", fillcolor="#0f9d58", shape="hexagon"];
            5 [label="Define\npass_mass", style="filled", fillcolor="#4285f4", shape="ellipse"];
            1 [label="B_PT selection", style="filled", fillcolor="#0f9d58", shape="hexagon"];
            2 [label="Define\nmass", style="filled", fillcolor="#4285f4", shape="ellipse"];
            3 [label="Define\nB_PT", style="filled", fillcolor="#4285f4", shape="ellipse"];
            0 [label="Empty source\nEntries: 10000", style="filled", fillcolor="#f4b400", shape="ellipse"];
            4 -> 6;
            5 -> 4;
            1 -> 5;
            2 -> 1;
            3 -> 2;
            0 -> 3;
    }
    

    How do I know the definitions or what filter was applied? I am using range with 1000,but I do not see that 1000 anywhere. I believe the Redefine would not be tracked either.

  5. vepadulano commented on Nov 9, 2026

    @vepadulano
    Member

    Ok then IIUC what you are asking is a text form that precisely represents what the computation graph you defined is going to apply on your data, including the expressions of filters, how many entries you select with a Range, the expression of a Redefine. To me, this sounds like you want to see what your code does, but isn't the code itself already telling you that? I do not understand what's missing here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions