1 |
slacapra |
1.1 |
#!/usr/bin/env python
|
2 |
|
|
import sys, os, time, string, shutil
|
3 |
|
|
from crab_util import *
|
4 |
|
|
from crab import *
|
5 |
|
|
import common
|
6 |
|
|
|
7 |
|
|
###########################################################################
|
8 |
|
|
class MultiCrab:
|
9 |
|
|
def __init__(self, opts):
|
10 |
|
|
self.prog_name='multicrab'
|
11 |
|
|
# Configuration file
|
12 |
|
|
self.cfg_fname = None
|
13 |
|
|
# Continuation flag
|
14 |
|
|
self.flag_continue = 0
|
15 |
|
|
self.continue_dir = None
|
16 |
|
|
self.processContinueOption_(opts)
|
17 |
|
|
|
18 |
|
|
self.processIniFile_(opts)
|
19 |
|
|
# configuration
|
20 |
|
|
self.opts=opts
|
21 |
|
|
|
22 |
|
|
if not self.flag_continue:
|
23 |
|
|
self.createWorkSpace()
|
24 |
|
|
|
25 |
|
|
print self.prog_name + ' running on ' + time.ctime(time.time())
|
26 |
|
|
print ' working directory ' + self.continue_dir
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
def processContinueOption_(self,opts):
|
30 |
|
|
|
31 |
|
|
# Look for the '-continue' option.
|
32 |
|
|
|
33 |
|
|
for opt in opts.keys():
|
34 |
|
|
if ( opt in ('-continue','-c') ):
|
35 |
|
|
self.flag_continue = 1
|
36 |
|
|
val = opts[opt]
|
37 |
|
|
if val:
|
38 |
|
|
if val[0] == '/': self.continue_dir = val # abs path
|
39 |
|
|
else: self.continue_dir = os.getcwd() + '/' + val # rel path
|
40 |
|
|
pass
|
41 |
|
|
break
|
42 |
|
|
pass
|
43 |
|
|
|
44 |
|
|
# Look for actions which has sense only with '-continue'
|
45 |
|
|
|
46 |
|
|
if "-create" not in opts.keys() :
|
47 |
|
|
self.flag_continue = 1
|
48 |
|
|
|
49 |
|
|
if not self.flag_continue: return
|
50 |
|
|
|
51 |
|
|
if not self.continue_dir:
|
52 |
|
|
prefix = self.prog_name + '_'
|
53 |
|
|
self.continue_dir = findLastWorkDir(prefix)
|
54 |
|
|
pass
|
55 |
|
|
|
56 |
|
|
if not self.continue_dir:
|
57 |
|
|
raise CrabException('Cannot find last working directory.')
|
58 |
|
|
|
59 |
|
|
if not os.path.exists(self.continue_dir):
|
60 |
|
|
msg = 'Cannot continue because the working directory <'
|
61 |
|
|
msg += self.continue_dir
|
62 |
|
|
msg += '> does not exist.'
|
63 |
|
|
raise CrabException(msg)
|
64 |
|
|
|
65 |
|
|
return
|
66 |
|
|
|
67 |
|
|
def createWorkSpace(self):
|
68 |
|
|
# create WorkingDir for Multicrab
|
69 |
|
|
if 'MULTICRAB.working_dir' in self.opts.keys():
|
70 |
|
|
self.continue_dir = os.path.abspath(self.opts['MULTICRAB.working_dir'])
|
71 |
|
|
else:
|
72 |
|
|
current_time = time.strftime('%y%m%d_%H%M%S', time.localtime(time.time()))
|
73 |
|
|
self.continue_dir = os.getcwd() + '/' + self.prog_name + '_' + current_time
|
74 |
|
|
|
75 |
|
|
if self.continue_dir and not os.path.exists(self.continue_dir):
|
76 |
|
|
try:
|
77 |
|
|
os.mkdir(self.continue_dir)
|
78 |
|
|
except OSError:
|
79 |
|
|
msg = 'Cannot create '+str(self.continue_dir) +' directory.\n'
|
80 |
|
|
raise CrabException(msg)
|
81 |
|
|
pass
|
82 |
|
|
else:
|
83 |
|
|
msg = 'Directory '+str(self.continue_dir) +' already exist.\n'
|
84 |
|
|
raise CrabException(msg)
|
85 |
|
|
|
86 |
|
|
shutil.copyfile('multicrab.cfg',self.continue_dir+'/multicrab.cfg')
|
87 |
|
|
|
88 |
|
|
return
|
89 |
|
|
|
90 |
|
|
def processIniFile_(self, opts):
|
91 |
|
|
"""
|
92 |
|
|
Processes a configuration INI-file.
|
93 |
|
|
"""
|
94 |
|
|
|
95 |
|
|
# Extract cfg-file name from the cmd-line options.
|
96 |
|
|
|
97 |
|
|
for opt in opts.keys():
|
98 |
|
|
if ( opt == '-cfg' ):
|
99 |
|
|
if self.flag_continue:
|
100 |
|
|
raise CrabException('-continue and -cfg cannot coexist.')
|
101 |
slacapra |
1.8 |
if opts[opt] :
|
102 |
|
|
self.cfg_fname = opts[opt]
|
103 |
slacapra |
1.11 |
del opts[opt] # do not pass cfg further on
|
104 |
slacapra |
1.1 |
else : processHelpOptions()
|
105 |
|
|
pass
|
106 |
|
|
pass
|
107 |
|
|
|
108 |
|
|
# Set default cfg-fname
|
109 |
|
|
|
110 |
|
|
if self.cfg_fname == None:
|
111 |
|
|
if self.flag_continue:
|
112 |
|
|
self.cfg_fname = self.continue_dir + '/multicrab.cfg'
|
113 |
|
|
else:
|
114 |
|
|
self.cfg_fname = 'multicrab.cfg'
|
115 |
|
|
pass
|
116 |
|
|
pass
|
117 |
|
|
|
118 |
|
|
# Load cfg-file
|
119 |
|
|
|
120 |
slacapra |
1.7 |
cfg_params = {}
|
121 |
slacapra |
1.1 |
if self.cfg_fname != None:
|
122 |
|
|
if os.path.exists(self.cfg_fname):
|
123 |
slacapra |
1.7 |
cfg_params = self.loadMultiConfig(self.cfg_fname)
|
124 |
slacapra |
1.1 |
pass
|
125 |
|
|
else:
|
126 |
|
|
msg = 'cfg-file '+self.cfg_fname+' not found.'
|
127 |
|
|
raise CrabException(msg)
|
128 |
|
|
pass
|
129 |
|
|
pass
|
130 |
|
|
|
131 |
|
|
# process the [CRAB] section
|
132 |
|
|
|
133 |
|
|
lhp = len('MULTICRAB.')
|
134 |
slacapra |
1.7 |
for k in cfg_params.keys():
|
135 |
slacapra |
1.1 |
if len(k) >= lhp and k[:lhp] == 'MULTICRAB.':
|
136 |
|
|
opt = '-'+k[lhp:]
|
137 |
|
|
if len(opt) >= 3 and opt[:3] == '-__': continue
|
138 |
|
|
if opt not in opts.keys():
|
139 |
slacapra |
1.7 |
opts[opt] = cfg_params[k]
|
140 |
slacapra |
1.1 |
pass
|
141 |
|
|
pass
|
142 |
|
|
pass
|
143 |
|
|
|
144 |
|
|
self.cfg_params_dataset = {}
|
145 |
slacapra |
1.3 |
common_opts = {}
|
146 |
slacapra |
1.1 |
# first get common sections
|
147 |
slacapra |
1.7 |
for sec in cfg_params:
|
148 |
slacapra |
1.1 |
if sec in ['MULTICRAB']:
|
149 |
slacapra |
1.8 |
if 'cfg' in cfg_params[sec]:
|
150 |
|
|
common_opts['cfg']=cfg_params[sec]['cfg']
|
151 |
slacapra |
1.1 |
continue
|
152 |
|
|
if sec in ['COMMON']:
|
153 |
slacapra |
1.8 |
common_opts.update(cfg_params[sec])
|
154 |
slacapra |
1.1 |
continue
|
155 |
|
|
pass
|
156 |
|
|
|
157 |
slacapra |
1.8 |
crab_cfg='crab.cfg'
|
158 |
|
|
if common_opts.has_key('cfg') : crab_cfg=common_opts['cfg']
|
159 |
|
|
|
160 |
slacapra |
1.1 |
# then Dataset's specific
|
161 |
slacapra |
1.7 |
for sec in cfg_params:
|
162 |
slacapra |
1.1 |
if sec in ['MULTICRAB', 'COMMON']: continue
|
163 |
slacapra |
1.7 |
self.cfg_params_dataset[sec]=cfg_params[sec]
|
164 |
slacapra |
1.1 |
# add common to all dataset
|
165 |
slacapra |
1.3 |
for key in common_opts:
|
166 |
|
|
self.cfg_params_dataset[sec][key]=common_opts[key]
|
167 |
slacapra |
1.1 |
pass
|
168 |
|
|
|
169 |
slacapra |
1.2 |
# read crab.cfg file and search for storage_path
|
170 |
slacapra |
1.8 |
crab_cfg_params = loadConfig(crab_cfg,{})
|
171 |
slacapra |
1.16 |
# also USER.ui_working_dir USER.outputdir and USER.logdir need special treatment
|
172 |
slacapra |
1.7 |
if cfg_params.has_key("COMMON"):
|
173 |
|
|
self.user_remote_dir = cfg_params["COMMON"].get("user.user_remote_dir", crab_cfg_params.get("USER.user_remote_dir",None))
|
174 |
slacapra |
1.16 |
self.outputdir = cfg_params["COMMON"].get("user.outputdir", crab_cfg_params.get("USER.outputdir",None))
|
175 |
|
|
self.logdir = cfg_params["COMMON"].get("user.logdir", crab_cfg_params.get("USER.logdir",None))
|
176 |
|
|
self.ui_working_dir = cfg_params["COMMON"].get("user.ui_working_dir", crab_cfg_params.get("USER.ui_working_dir",None))
|
177 |
slacapra |
1.6 |
else:
|
178 |
slacapra |
1.7 |
self.user_remote_dir = crab_cfg_params.get("USER.user_remote_dir",None)
|
179 |
slacapra |
1.16 |
self.outputdir = crab_cfg_params.get("USER.outputdir",None)
|
180 |
|
|
self.logdir = crab_cfg_params.get("USER.logdir",None)
|
181 |
|
|
self.ui_working_dir = crab_cfg_params.get("USER.ui_working_dir",None)
|
182 |
|
|
|
183 |
slacapra |
1.1 |
return
|
184 |
|
|
|
185 |
|
|
def loadMultiConfig(self, file):
|
186 |
|
|
"""
|
187 |
|
|
returns a dictionary with keys of the form
|
188 |
|
|
<section>.<option> and the corresponding values
|
189 |
|
|
"""
|
190 |
|
|
config={}
|
191 |
|
|
cp = ConfigParser.ConfigParser()
|
192 |
|
|
cp.read(file)
|
193 |
|
|
for sec in cp.sections():
|
194 |
|
|
# print 'Section',sec
|
195 |
|
|
config[sec]={}
|
196 |
|
|
for opt in cp.options(sec):
|
197 |
|
|
#print 'config['+sec+'.'+opt+'] = '+string.strip(cp.get(sec,opt))
|
198 |
|
|
config[sec][opt] = string.strip(cp.get(sec,opt))
|
199 |
|
|
return config
|
200 |
|
|
|
201 |
|
|
def run(self):
|
202 |
|
|
#run crabs
|
203 |
slacapra |
1.16 |
runFileName = 'multicrab.exe'
|
204 |
|
|
runFile = open(runFileName,"w")
|
205 |
slacapra |
1.1 |
for sec in self.cfg_params_dataset:
|
206 |
|
|
options={}
|
207 |
|
|
if self.flag_continue:
|
208 |
|
|
options['-c']=sec
|
209 |
|
|
# DatasetName to be used
|
210 |
|
|
options['-USER.ui_working_dir']=sec
|
211 |
|
|
# options from multicrab.cfg
|
212 |
|
|
for opt in self.cfg_params_dataset[sec]:
|
213 |
slacapra |
1.8 |
tmp = "-"+str(opt)
|
214 |
|
|
if len(opt.split("."))==2:
|
215 |
|
|
tmp="-"+string.upper(opt.split(".")[0])+"."+opt.split(".")[1]
|
216 |
|
|
|
217 |
slacapra |
1.1 |
options[tmp]=self.cfg_params_dataset[sec][opt]
|
218 |
slacapra |
1.16 |
|
219 |
slacapra |
1.23 |
# check if user_remote_dir is set in multicrab.cfg
|
220 |
spiga |
1.24 |
# protect against no user_remote_dir
|
221 |
slacapra |
1.26 |
self.user_remote_dir =self.cfg_params_dataset[sec].get("user.user_remote_dir",self.user_remote_dir)
|
222 |
|
|
if not self.user_remote_dir:
|
223 |
slacapra |
1.22 |
self.user_remote_dir = "./"
|
224 |
slacapra |
1.2 |
# add section to storage_path if exist in crab.cfg
|
225 |
slacapra |
1.6 |
if not self.cfg_params_dataset.has_key("USER.user_remote_dir") and self.user_remote_dir:
|
226 |
slacapra |
1.5 |
options["-USER.user_remote_dir"]=self.user_remote_dir+"/"+sec
|
227 |
slacapra |
1.27 |
# print options["-USER.user_remote_dir"]
|
228 |
slacapra |
1.16 |
# also for ui_working_dir
|
229 |
|
|
if not self.cfg_params_dataset.has_key("USER.ui_working_dir") and self.ui_working_dir:
|
230 |
|
|
options["-USER.ui_working_dir"]=self.ui_working_dir+"/"+sec
|
231 |
slacapra |
1.25 |
# if ui_working_dir is set, change -c dir accordnigly
|
232 |
|
|
options['-c']=self.ui_working_dir+"/"+sec
|
233 |
|
|
|
234 |
slacapra |
1.16 |
# also for logDir
|
235 |
|
|
if not self.cfg_params_dataset.has_key("USER.logdir") and self.logdir:
|
236 |
|
|
options["-USER.logdir"]=self.logdir+"/"+sec
|
237 |
|
|
# also for outputdir
|
238 |
|
|
if not self.cfg_params_dataset.has_key("USER.outputdir") and self.outputdir:
|
239 |
|
|
options["-USER.outputdir"]=self.outputdir+"/"+sec
|
240 |
|
|
|
241 |
slacapra |
1.1 |
# Input options (command)
|
242 |
|
|
for opt in self.opts:
|
243 |
|
|
options[opt]=self.opts[opt]
|
244 |
slacapra |
1.9 |
if self.flag_continue and options.has_key("-cfg"):
|
245 |
|
|
del options['-cfg']
|
246 |
slacapra |
1.13 |
pass
|
247 |
slacapra |
1.20 |
|
248 |
|
|
# write crab command to be executed later...
|
249 |
|
|
cmd='crab '
|
250 |
|
|
for o in options:
|
251 |
|
|
if options[o]==None:
|
252 |
|
|
cmd+=str(o)+' '
|
253 |
|
|
else:
|
254 |
|
|
options[o] = ''.join(options[o].split())
|
255 |
|
|
cmd+=str(o)+'='+str(options[o])+' '
|
256 |
|
|
pass
|
257 |
|
|
cmd+="\n"
|
258 |
|
|
#print cmd
|
259 |
|
|
|
260 |
|
|
runFile.write(cmd)
|
261 |
|
|
|
262 |
|
|
# SL this does not work for complex, multi include pset.py
|
263 |
|
|
|
264 |
|
|
# crab = Crab()
|
265 |
|
|
# try:
|
266 |
|
|
# crab.initialize_(options)
|
267 |
|
|
# crab.run()
|
268 |
|
|
# del crab
|
269 |
|
|
# print 'Log file is %s%s.log'%(common.work_space.logDir(),common.prog_name)
|
270 |
|
|
# print '\n############################## E N D ####################################\n'
|
271 |
|
|
# except CrabException, e:
|
272 |
|
|
# del crab
|
273 |
|
|
# print '\n' + common.prog_name + ': ' + str(e) + '\n'
|
274 |
|
|
# pass
|
275 |
|
|
# pass
|
276 |
|
|
# if (common.logger): common.logger.delete()
|
277 |
slacapra |
1.1 |
pass
|
278 |
|
|
|
279 |
|
|
|
280 |
|
|
###########################################################################
|
281 |
|
|
if __name__ == '__main__':
|
282 |
|
|
## Get rid of some useless warning
|
283 |
|
|
try:
|
284 |
|
|
import warnings
|
285 |
|
|
warnings.simplefilter("ignore", RuntimeWarning)
|
286 |
|
|
except ImportError:
|
287 |
|
|
pass # too bad, you'll get the warning
|
288 |
|
|
|
289 |
|
|
# Parse command-line options and create a dictionary with
|
290 |
|
|
# key-value pairs.
|
291 |
|
|
options = parseOptions(sys.argv[1:])
|
292 |
|
|
|
293 |
|
|
# Process "help" options, such as '-help', '-version'
|
294 |
|
|
if processHelpOptions(options) : sys.exit(0)
|
295 |
|
|
|
296 |
|
|
# Create, initialize, and run a Crab object
|
297 |
|
|
try:
|
298 |
|
|
multicrab = MultiCrab(options)
|
299 |
|
|
multicrab.run()
|
300 |
|
|
except CrabException, e:
|
301 |
|
|
print '\n' + common.prog_name + ': ' + str(e) + '\n'
|
302 |
|
|
|
303 |
|
|
pass
|