CMS 3D CMS Logo

chain.py
Go to the documentation of this file.
1 # Copyright (C) 2014 Colin Bernet
2 # https://github.com/cbernet/heppy/blob/master/LICENSE
3 
4 import glob
5 import os
6 import pprint
7 from ROOT import TChain, TFile, TTree, gSystem
8 
9 def is_pfn(fn):
10  return not (is_lfn(fn) or is_rootfn(fn))
11 
12 def is_lfn(fn):
13  return fn.startswith("/store")
14 
15 def is_rootfn(fn):
16  """
17  To open files like root://, file:// which os.isfile won't find.
18  """
19  return "://" in fn
20 
21 
22 class Chain( object ):
23  """Wrapper to TChain, with a python iterable interface.
24 
25  Example of use: #TODO make that a doctest / nose?
26  from chain import Chain
27  the_chain = Chain('../test/test_*.root', 'test_tree')
28  event3 = the_chain[2]
29  print event3.var1
30 
31  for event in the_chain:
32  print event.var1
33  """
34 
35  def __init__(self, input, tree_name=None):
36  """
37  Create a chain.
38 
39  Parameters:
40  input = either a list of files or a wildcard (e.g. 'subdir/*.root').
41  In the latter case all files matching the pattern will be used
42  to build the chain.
43  tree_name = key of the tree in each file.
44  if None and if each file contains only one TTree,
45  this TTree is used.
46  """
47  self.files = input
48  if isinstance(input, str): # input is a pattern
49  self.files = glob.glob(input)
50  if len(self.files)==0:
51  raise ValueError('no matching file name: '+input)
52  else: # case of a list of files
53  if False in [
54  ((is_pfn(fnam) and os.path.isfile(fnam)) or
55  is_lfn(fnam)) or is_rootfn(fnam)
56  for fnam in self.files]:
57  err = 'at least one input file does not exist\n'
58  err += pprint.pformat(self.files)
59  raise ValueError(err)
60  if tree_name is None:
61  tree_name = self._guessTreeName(input)
62  self.chain = TChain(tree_name)
63  for file in self.files:
64  self.chain.Add(file)
65 
66  def _guessTreeName(self, pattern):
67  """
68  Find the set of keys of all TTrees in all files matching pattern.
69  If the set contains only one key
70  Returns: the TTree key
71  else raises ValueError.
72  """
73  names = []
74  for fnam in self.files:
75  rfile = TFile(fnam)
76  for key in rfile.GetListOfKeys():
77  obj = rfile.Get(key.GetName())
78  if isinstance(obj, TTree):
79  names.append( key.GetName() )
80  thename = set(names)
81  if len(thename)==1:
82  return list(thename)[0]
83  else:
84  err = [
85  'several TTree keys in {pattern}:'.format(
86  pattern=pattern
87  ),
88  ','.join(thename)
89  ]
90  raise ValueError('\n'.join(err))
91 
92  def __getattr__(self, attr):
93  """
94  All functions of the wrapped TChain are made available
95  """
96  return getattr(self.chain, attr)
97 
98  def __iter__(self):
99  return iter(self.chain)
100 
101  def __len__(self):
102  return int(self.chain.GetEntries())
103 
104  def __getitem__(self, index):
105  """
106  Returns the event at position index.
107  """
108  self.chain.GetEntry(index)
109  return self.chain
110 
111 
def __getattr__(self, attr)
Definition: chain.py:92
def is_rootfn(fn)
Definition: chain.py:15
def is_lfn(fn)
Definition: chain.py:12
def is_pfn(fn)
Definition: chain.py:9
def __getitem__(self, index)
Definition: chain.py:104
def __init__(self, input, tree_name=None)
Definition: chain.py:35
static std::string join(char **cmd)
Definition: RemoteFile.cc:21
def __iter__(self)
Definition: chain.py:98
def __len__(self)
Definition: chain.py:101
def _guessTreeName(self, pattern)
Definition: chain.py:66