rDataFrame Snapshot after opening a different file

Hi,

I’m using rDataFrame I am creating a new Branch computed from some values from a TH1D that I import through a local file.
When I try to make a Snapshot of the Tree with the newly added branch however the process crashes. A reduced snippet showing what I am trying to do is below.

int snippet(const string mcFilepath){

   ROOT::RDataFrame frame("tree", mcFilepath);

   TFile f2("fit_file.root");
   TH1D *fit_histo_first = (TH1D*)f2.Get("fit_histo_first");
   TH1D *fit_histo_second = (TH1D*)f2.Get("fit_histo_second");

   TH1D* operation = new TH1D("operation", "", fit_histo_first->GetNbinsX(), 1, fit_histo_first->GetNbinsX() );
   operation->Divide(fit_histo_first, fit_histo_second);
   operation->Write();

 

   auto mcIncident_selected_primaryPi = frame
      .Define("new_branch", [operation](const std::vector<double> &existing_branch1, double existing_branch2){
             int cnt = 1; double branch_value;
             for(auto i : existing_branch1){
                branch_value = existing_branch2  - i * operation->GetBinContent(cnt);
                cnt ++;
              }
            return branch_value;
            }
            ,{"existing_branch1", "existing_branch2"});

   delete fit_dEdX_lifetime_mpv;
   delete fit_pitch_mean;
   f2.Close();

  frame.Snapshot("directory/tree", "test.root");
  return 0;
}

The program crashes and I get the error:

Processing eSliceMethod_branchPrep.C+("../prod4_files/eventSelection_Prod4_mc_1GeV_all_1_14_21.root")...
Error in <TFile::WriteTObject>: Directory fit_file.root is not writable
Error in <TFile::WriteTObject>: Directory fit_file.root is not writable

Has anyone encountered this problem?

Thanks
francesca

ROOT Version: 6.22/06
Platform: Built for macosx64

Hi Francesca,

That looks indeed wrong, thanks for reporting.

@swunsch can you reproduce this while @eguiraud is gone?

Cheers, Axel.

Hi!

I think the issue is that you open the file fit_file.root in READ mode but not in UPDATE mode. If you replace TFile f2("fit_file.root"); by TFile f2("fit_file.root", "UPDATE");, it should work. The error comes then from the line operation->Write();, which tries to write into fit_file.root, but does not have write permissions.

Best,
Stefan

Hi @swunsch ,
thanks, sorry this one I missed, the operation->Write() is not essential, I forgot to take it out from the macro. unfortunately the macro crashes when doing the snapshot.
If I comment the line that does the RDF Snapshot the macro works well.
the problem is the Snapshot operations, somehow ROOT seems not to be able to save this normally to the working directory as it does when just simply opening a RDF in a macro and creating new columns without using information from a different file like I am doing now.

have you encountered this problem?

Ah alright, I was confused :slight_smile:
Here is an example program which mocks your input files. Could you try to make it break with this standalone example? I wasn’t able to reproduce it!

#include "ROOT/RDataFrame.hxx"
#include "TFile.h"
#include "TTree.h"
#include "TH1D.h"

#include <vector>

void create_files() {
    auto f = TFile::Open("fit_file.root", "RECREATE");
    TH1D* fit_histo_first = new TH1D("fit_histo_first", "", 1, 0, 1);
    TH1D* fit_histo_second = new TH1D("fit_histo_second", "", 1, 0, 1);
    f->Write();
    f->Close();

    ROOT::RDataFrame df(1);
    df.Define("existing_branch1", "std::vector<double>({42.0})").Define("existing_branch2", "double(42.0)").Snapshot("tree", "file.root");
}

void test() {
    ROOT::RDataFrame frame("tree", "file.root");

    TFile f2("fit_file.root", "UPDATE");
    TH1D *fit_histo_first = (TH1D*)f2.Get("fit_histo_first");
    TH1D *fit_histo_second = (TH1D*)f2.Get("fit_histo_second");
    TH1D* operation = new TH1D("operation", "", fit_histo_first->GetNbinsX(), 1, fit_histo_first->GetNbinsX() );
    operation->Write();

    auto frame2 = frame.Define("new_branch", [operation](const std::vector<double> &b1, double b2){
                                   int cnt = 1;
                                   double branch_value = 42;
                                   /*
                                   for(auto i : existing_branch1){
                                       branch_value = existing_branch2  - i * operation->GetBinContent(cnt);
                                       cnt ++;
                                    }
                                    */
                                   return branch_value;
                                }
                               ,{"existing_branch1", "existing_branch2"});

    delete fit_histo_first;
    delete fit_histo_second;
    f2.Close();

    frame2.Snapshot("directory/tree", "test.root");
}

int main() {
    create_files();
    test();
}

Best
Stefan

I may have spotted the issue! :slight_smile:

You create the TH1D called operation in the scope of the TFile f2, but then you close the file before you call Snapshot on the dataframe. This causes your event loop, just triggered at the time of running the Snapshot, to access the already deleted histogram operation.

So I guess you should move the f2.Close() after the frame.Snapshot().

Best
Stefan

1 Like

Hi @swunsch

thanks so much, this solved the issue. I totally forgot that the event loop is only triggered at the moment of calling Snapshot("","").

Thanks a lot,
Francesca

1 Like

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