3 from datetime
import datetime
4 from optparse
import OptionParser
12 import eostools
as castortools
16 This class manages batch jobs
32 self.parser_.add_option(
"-o",
"--output-dir", dest=
"outputDir",
33 help=
"Name of the local output directory for your jobs. This directory will be created automatically.",
35 self.parser_.add_option(
"-r",
"--remote-copy", dest=
"remoteCopy",
36 help=
"remote output directory for your jobs. Example: /store/cmst3/user/cbern/CMG/HT/Run2011A-PromptReco-v1/AOD/PAT_CMG/RA2. This directory *must* be provided as a logical file name (LFN). When this option is used, all root files produced by a job are copied to the remote directory, and the job index is appended to the root file name. The Logger directory will be sent back to the submision directory. For remote copy to PSI specify path like: '/pnfs/psi.ch/...'. Note: enviromental variable X509_USER_PROXY must point to home area before renewing proxy",
38 self.parser_.add_option(
"-f",
"--force", action=
"store_true",
39 dest=
"force", default=
False,
40 help=
"Don't ask any questions, just over-write")
42 self.parser_.add_option(
"-n",
"--negate", action=
"store_true",
43 dest=
"negate", default=
False,
44 help=
"create jobs, but does not submit the jobs.")
45 self.parser_.add_option(
"-b",
"--batch", dest=
"batch",
46 help=
"batch command. default is: 'bsub -q 8nh < batchScript.sh'. You can also use 'nohup < ./batchScript.sh &' to run locally.",
47 default=
"bsub -q 8nh < ./batchScript.sh")
50 (self.options_,self.args_) = self.parser_.parse_args()
51 if self.options_.remoteCopy ==
None:
58 if self.remoteOutputDir_.startswith(
"/pnfs/psi.ch"):
59 ld_lib_path = os.environ.get(
'LD_LIBRARY_PATH')
60 if ld_lib_path !=
"None":
61 os.environ[
'LD_LIBRARY_PATH'] =
"/usr/lib64/:"+ld_lib_path
63 outputDir = self.options_.outputDir
65 today = datetime.today()
66 outputDir =
'OutCmsBatch_%s' % today.strftime(
"%d%h%y_%H%M")
69 if ld_lib_path !=
"None":
70 os.environ[
'LD_LIBRARY_PATH'] = ld_lib_path
72 print "remote directory must start with /pnfs/psi.ch to send to the tier3 at PSI"
77 print 'When providing an output directory, you must give its LFN, starting by /store. You gave:'
93 if self.options_.negate
is False and self.options_.force
is False:
101 return (self.options_, self.args_)
105 print 'PREPARING JOBS ======== '
108 if listOfDirNames
is None:
109 for value
in listOfValues:
112 for value, name
in zip( listOfValues, listOfDirNames):
114 print "list of jobs:"
115 pp = pprint.PrettyPrinter(indent=4)
127 outputDir = self.options_.outputDir
130 today = datetime.today()
131 outputDir =
'OutCmsBatch_%s' % today.strftime(
"%d%h%y_%H%M%S")
132 print 'output directory not specified, using %s' % outputDir
138 if not self.options_.force:
139 while input !=
'y' and input !=
'n':
140 input = raw_input(
'The directory ' + self.
outputDir_ +
' exists. Are you sure you want to continue? its contents will be overwritten [y/n] ' )
150 '''Prepare a job for a given value.
152 calls PrepareJobUser, which should be overloaded by the user.
154 print 'PrepareJob : %s' % value
157 dname =
'Job_{value}'.
format( value=value )
161 self.listOfJobs_.append( jobDir )
165 '''Hook allowing user to define how one of his jobs should be prepared.'''
166 print '\to be customized'
170 '''Submit all jobs. Possibly wait between each job'''
172 if(self.options_.negate):
173 print '*NOT* SUBMITTING JOBS - exit '
175 print 'SUBMITTING JOBS ======== '
179 print 'processing ', jobDir
184 print 'waiting %s seconds...' % waitingTimeInSec
185 time.sleep( waitingTimeInSec )
189 '''Hook for job submission.'''
190 print 'submitting (to be customized): ', jobDir
191 os.system( self.options_.batch )
195 '''Hook for array job submission.'''
196 print 'Submitting array with %s jobs' % numbOfJobs
200 if batchScript ==
'':
203 if( os.path.isfile(batchScript)==
False ):
204 print 'file ',batchScript,
' does not exist'
208 ifile = open(batchScript)
210 print 'cannot open input %s' % batchScript
214 p = re.compile(
"\s*cp.*\$jobdir\s+(\S+)$");
217 if os.path.isdir( os.path.expandvars(m.group(1)) ):
218 print 'output directory ', m.group(1),
'already exists!'
222 if self.options_.negate==
False:
223 os.mkdir( os.path.expandvars(m.group(1)) )
225 print 'not making dir', self.options_.negate
230 mkdir =
'mkdir -p %s' % dirname
231 ret = os.system( mkdir )
233 print 'please remove or rename directory: ', dirname
239 '''Return "LXPUS", "PSI", "NAF", "LOCAL", or None,
241 "LXPLUS" : batch command is bsub, and logged on lxplus
242 "PSI" : batch command is qsub, and logged to t3uiXX
243 "NAF" : batch command is qsub, and logged on naf
244 "IC" : batch command is qsub, and logged on hep.ph.ic.ac.uk
245 "LOCAL" : batch command is nohup.
247 In all other cases, a CmsBatchException is raised
250 hostName = os.environ[
'HOSTNAME']
252 onLxplus = hostName.startswith(
'lxplus')
253 onPSI = hostName.startswith(
't3ui')
254 onNAF = hostName.startswith(
'naf')
256 batchCmd = batch.split()[0]
258 if batchCmd ==
'bsub':
260 err =
'Cannot run %s on %s' % (batchCmd, hostName)
261 raise ValueError( err )
263 print 'running on LSF : %s from %s' % (batchCmd, hostName)
266 elif batchCmd ==
"qsub":
268 print 'running on SGE : %s from %s' % (batchCmd, hostName)
271 print 'running on NAF : %s from %s' % (batchCmd, hostName)
274 print 'running on IC : %s from %s' % (batchCmd, hostName)
277 err =
'Cannot run %s on %s' % (batchCmd, hostName)
278 raise ValueError( err )
280 elif batchCmd ==
'nohup' or batchCmd ==
'./batchScript.sh':
281 print 'running locally : %s on %s' % (batchCmd, hostName)
284 err =
'unknown batch command: X%sX' % batchCmd
285 raise ValueError( err )
static std::string join(char **cmd)
if(conf.exists("allCellsPositionCalc"))