CMS 3D CMS Logo

heppy_hadd.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Copyright (C) 2014 Colin Bernet
3 # https://github.com/cbernet/heppy/blob/master/LICENSE
4 
5 import os
6 import pprint
7 import pickle
8 import shutil
9 
10 MAX_ARG_STRLEN = 131072
11 
12 def haddPck(file, odir, idirs):
13  '''add pck files in directories idirs to a directory outdir.
14  All dirs in idirs must have the same subdirectory structure.
15  Each pickle file will be opened, and the corresponding objects added to a destination pickle in odir.
16  '''
17  sum = None
18  for dir in idirs:
19  fileName = file.replace( idirs[0], dir )
20  pckfile = open(fileName)
21  obj = pickle.load(pckfile)
22  if sum is None:
23  sum = obj
24  else:
25  try:
26  sum += obj
27  except TypeError:
28  # += not implemented, nevermind
29  pass
30 
31  oFileName = file.replace( idirs[0], odir )
32  pckfile = open(oFileName, 'w')
33  pickle.dump(sum, pckfile)
34  txtFileName = oFileName.replace('.pck','.txt')
35  txtFile = open(txtFileName, 'w')
36  txtFile.write( str(sum) )
37  txtFile.write( '\n' )
38  txtFile.close()
39 
40 
41 def hadd(file, odir, idirs, appx=''):
42  if file.endswith('.pck'):
43  try:
44  haddPck( file, odir, idirs)
45  except ImportError:
46  pass
47  return
48  elif not file.endswith('.root'):
49  return
50  haddCmd = ['hadd']
51  haddCmd.append( file.replace( idirs[0], odir ).replace('.root', appx+'.root') )
52  for dir in idirs:
53  haddCmd.append( file.replace( idirs[0], dir ) )
54  # import pdb; pdb.set_trace()
55  cmd = ' '.join(haddCmd)
56  print cmd
57  if len(cmd) > MAX_ARG_STRLEN:
58  print 'Command longer than maximum unix string length; dividing into 2'
59  hadd(file, odir, idirs[:len(idirs)/2], '1')
60  hadd(file.replace(idirs[0], idirs[len(idirs)/2]), odir, idirs[len(idirs)/2:], '2')
61  haddCmd = ['hadd']
62  haddCmd.append( file.replace( idirs[0], odir ).replace('.root', appx+'.root') )
63  haddCmd.append( file.replace( idirs[0], odir ).replace('.root', '1.root') )
64  haddCmd.append( file.replace( idirs[0], odir ).replace('.root', '2.root') )
65  cmd = ' '.join(haddCmd)
66  print 'Running merge cmd:', cmd
67  os.system(cmd)
68  else:
69  os.system(cmd)
70 
71 
72 def haddRec(odir, idirs):
73  print 'adding', idirs
74  print 'to', odir
75 
76  cmd = ' '.join( ['mkdir', odir])
77  # import pdb; pdb.set_trace()
78  # os.system( cmd )
79  try:
80  os.mkdir( odir )
81  except OSError:
82  print
83  print 'ERROR: directory in the way. Maybe you ran hadd already in this directory? Remove it and try again'
84  print
85  raise
86  for root,dirs,files in os.walk( idirs[0] ):
87  # print root, dirs, files
88  for dir in dirs:
89  dir = '/'.join([root, dir])
90  dir = dir.replace(idirs[0], odir)
91  cmd = 'mkdir ' + dir
92  # print cmd
93  # os.system(cmd)
94  os.mkdir(dir)
95  for file in files:
96  hadd('/'.join([root, file]), odir, idirs)
97 
98 def haddChunks(idir, removeDestDir, cleanUp=False, odir_cmd='./'):
99  chunks = {}
100  for file in sorted(os.listdir(idir)):
101  filepath = '/'.join( [idir, file] )
102  # print filepath
103  if os.path.isdir(filepath):
104  compdir = file
105  try:
106  prefix,num = compdir.split('_Chunk')
107  except ValueError:
108  # ok, not a chunk
109  continue
110  # print prefix, num
111  chunks.setdefault( prefix, list() ).append(filepath)
112  if len(chunks)==0:
113  print 'warning: no chunk found.'
114  return
115  for comp, cchunks in chunks.iteritems():
116  odir = odir_cmd+'/'+'/'.join( [idir, comp] )
117  print odir, cchunks
118  if removeDestDir:
119  if os.path.isdir( odir ):
120  shutil.rmtree(odir)
121  haddRec(odir, cchunks)
122  if cleanUp:
123  chunkDir = 'Chunks'
124  if os.path.isdir('Chunks'):
125  shutil.rmtree(chunkDir)
126  os.mkdir(chunkDir)
127  print chunks
128  for comp, chunks in chunks.iteritems():
129  for chunk in chunks:
130  shutil.move(chunk, chunkDir)
131 
132 
133 if __name__ == '__main__':
134 
135  import os
136  import sys
137  from optparse import OptionParser
138 
139  parser = OptionParser()
140  parser.usage = """
141  %prog <dir>
142  Find chunks in dir, and run recursive hadd to group all chunks.
143  For example:
144  DYJets_Chunk0/, DYJets_Chunk1/ ... -> hadd -> DYJets/
145  WJets_Chunk0/, WJets_Chunk1/ ... -> hadd -> WJets/
146  """
147  parser.add_option("-r","--remove", dest="remove",
148  default=False,action="store_true",
149  help="remove existing destination directories.")
150  parser.add_option("-c","--clean", dest="clean",
151  default=False,action="store_true",
152  help="move chunks to Chunks/ after processing.")
153 
154  (options,args) = parser.parse_args()
155 
156  if len(args)>2:
157  print 'provide at most 2 directory as arguments: first the source, then the destination (optional)'
158  sys.exit(1)
159 
160  dir = args[0]
161  if(len(args)>1):
162  odir = args[1]
163  else:
164  odir='./'
165 
166  haddChunks(dir, options.remove, options.clean, odir)
167 
def hadd(file, odir, idirs, appx='')
Definition: heppy_hadd.py:41
def haddPck(file, odir, idirs)
Definition: heppy_hadd.py:12
def replace(string, replacements)
def haddRec(odir, idirs)
Definition: heppy_hadd.py:72
def haddChunks(idir, removeDestDir, cleanUp=False, odir_cmd='./')
Definition: heppy_hadd.py:98
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
if(dp >Float(M_PI)) dp-
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run