TChain::Process() and Non-existent Files


I am wondering if there is a way to make TChain::Process() to notify a user if it could not open a file.

For example, consider the following PyROOT code:

#!/usr/bin/env python

from ROOT import *
import ROOT

dset = TFileCollection("test","","nonexistentfile.root")

T = TChain("physics")
print T.AddFile("nonexistentfile.root",0)

gROOT.ProcessLine(".L test.C+")

print 'process',T.Process(t,"")

The output of this is as follows. You can see that TChain::Process returned 0, which should mean no errors occurred. However the only file it ran over did not exist.

Error in <TFileCollection::AddFromFile>: unable to open file nonexistentfile.root (nonexistentfile.root)
Error in <TFile::TFile>: file nonexistentfile.root does not exist
process 0
status 0

Right now, my solution is to call TChain::AddFile with nEntries=0, which causes it to open the file and return 0 on failure. I am wondering if there are ways to do so inside TChain:Process, so I can check for file open errors when I am actually processing the file (ie: I am reading from an xrd server, which goes down between addFile and Process).

This is using ROOT 5.34.14 installed on ATLAS CVMFS.


what is in test.C? Normally, Process() should return -1 on failure.



test.C is just the skeleton class that I created using TTree::MakeSelector. It does not do anything other than print out “HI” for each event. I’ve attached it.

I was also expecting Process to return -1 if it can’t open a root file. But it just seems to skip the non-existent file and return success ( 0 ).

Karol Krizka
test.h (2.56 KB)
test.C (3.16 KB)


digging through the code, it’s clear that any reference to the non-existent file is totally lost after failing to add it, so yes, you need to detect this early as at Process() it is too late. AddFile() (which also does not further track it) seems to be the right place to report it. Alternatively, you can call any of the Add functions for the TFileCollection and use their result: they return the number of files added on success, 0 on failure. The constructor eats all error messages (other than printing them; exceptions were invented to report from constructors, but none is thrown).

As for checking in TSelector: the call ends up in TTreePlayer, which simply sees 0 entries, thus does not actually loop, and it reports the result of TSelector::GetStatus(). GetStatus() is AFAICS not set in any other way than by user code. There is no knowledge at that point of any missing files of course, so the only thing I can think of, is to report SetStatus(-1) if in SlaveBegin() tree-GetCurrentFile() comes up with 0.