ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.88
Committed: Thu Jun 7 17:07:30 2007 UTC (17 years, 10 months ago) by spiga
Content type: text/x-python
Branch: MAIN
CVS Tags: CRAB_2_0_0_pre3, CRAB_1_5_2
Changes since 1.87: +4 -0 lines
Log Message:
fix for reporting correct error code if output file is missing

File Contents

# User Rev Content
1 slacapra 1.1 from JobType import JobType
2     from crab_logger import Logger
3     from crab_exceptions import *
4     from crab_util import *
5     import common
6 gutsche 1.3 import PsetManipulator
7 slacapra 1.86 # import DataDiscovery
8     # import DataDiscovery_DBS2
9     # import DataLocation
10 slacapra 1.1 import Scram
11    
12 slacapra 1.70 import os, string, re, shutil, glob
13 slacapra 1.1
14     class Cmssw(JobType):
15 gutsche 1.38 def __init__(self, cfg_params, ncjobs):
16 slacapra 1.1 JobType.__init__(self, 'CMSSW')
17     common.logger.debug(3,'CMSSW::__init__')
18    
19 gutsche 1.3 # Marco.
20     self._params = {}
21     self.cfg_params = cfg_params
22 gutsche 1.38
23 gutsche 1.72 try:
24     self.MaxTarBallSize = float(self.cfg_params['EDG.maxtarballsize'])
25     except KeyError:
26 slacapra 1.86 self.MaxTarBallSize = 9.5
27 gutsche 1.72
28 gutsche 1.44 # number of jobs requested to be created, limit obj splitting
29 gutsche 1.38 self.ncjobs = ncjobs
30    
31 slacapra 1.1 log = common.logger
32    
33     self.scram = Scram.Scram(cfg_params)
34     self.additional_inbox_files = []
35     self.scriptExe = ''
36     self.executable = ''
37 slacapra 1.71 self.executable_arch = self.scram.getArch()
38 slacapra 1.1 self.tgz_name = 'default.tgz'
39 corvo 1.56 self.scriptName = 'CMSSW.sh'
40 spiga 1.42 self.pset = '' #scrip use case Da
41     self.datasetPath = '' #scrip use case Da
42 gutsche 1.3
43 gutsche 1.50 # set FJR file name
44     self.fjrFileName = 'crab_fjr.xml'
45    
46 slacapra 1.1 self.version = self.scram.getSWVersion()
47 slacapra 1.55 common.taskDB.setDict('codeVersion',self.version)
48 gutsche 1.5 self.setParam_('application', self.version)
49 slacapra 1.47
50 slacapra 1.1 ### collect Data cards
51 gutsche 1.66
52     ## get DBS mode
53     try:
54 slacapra 1.86 self.use_dbs_1 = int(self.cfg_params['CMSSW.use_dbs_1'])
55 gutsche 1.66 except KeyError:
56 slacapra 1.86 self.use_dbs_1 = 0
57 gutsche 1.66
58 slacapra 1.1 try:
59 slacapra 1.9 tmp = cfg_params['CMSSW.datasetpath']
60     log.debug(6, "CMSSW::CMSSW(): datasetPath = "+tmp)
61     if string.lower(tmp)=='none':
62     self.datasetPath = None
63 slacapra 1.21 self.selectNoInput = 1
64 slacapra 1.9 else:
65     self.datasetPath = tmp
66 slacapra 1.21 self.selectNoInput = 0
67 slacapra 1.1 except KeyError:
68 gutsche 1.3 msg = "Error: datasetpath not defined "
69 slacapra 1.1 raise CrabException(msg)
70 gutsche 1.5
71     # ML monitoring
72     # split dataset path style: /PreProdR3Minbias/SIM/GEN-SIM
73 slacapra 1.9 if not self.datasetPath:
74     self.setParam_('dataset', 'None')
75     self.setParam_('owner', 'None')
76     else:
77     datasetpath_split = self.datasetPath.split("/")
78 slacapra 1.86 if self.use_dbs_1 == 1 :
79     self.setParam_('dataset', datasetpath_split[1])
80     self.setParam_('owner', datasetpath_split[-1])
81     else:
82 corvo 1.85 self.setParam_('dataset', datasetpath_split[1])
83     self.setParam_('owner', datasetpath_split[2])
84 gutsche 1.8 self.setTaskid_()
85     self.setParam_('taskId', self.cfg_params['taskId'])
86 gutsche 1.5
87 slacapra 1.1 self.dataTiers = []
88    
89     ## now the application
90     try:
91     self.executable = cfg_params['CMSSW.executable']
92 gutsche 1.5 self.setParam_('exe', self.executable)
93 slacapra 1.1 log.debug(6, "CMSSW::CMSSW(): executable = "+self.executable)
94     msg = "Default executable cmsRun overridden. Switch to " + self.executable
95     log.debug(3,msg)
96     except KeyError:
97     self.executable = 'cmsRun'
98 gutsche 1.5 self.setParam_('exe', self.executable)
99 slacapra 1.1 msg = "User executable not defined. Use cmsRun"
100     log.debug(3,msg)
101     pass
102    
103     try:
104     self.pset = cfg_params['CMSSW.pset']
105     log.debug(6, "Cmssw::Cmssw(): PSet file = "+self.pset)
106 spiga 1.42 if self.pset.lower() != 'none' :
107     if (not os.path.exists(self.pset)):
108     raise CrabException("User defined PSet file "+self.pset+" does not exist")
109     else:
110     self.pset = None
111 slacapra 1.1 except KeyError:
112     raise CrabException("PSet file missing. Cannot run cmsRun ")
113    
114     # output files
115 slacapra 1.53 ## stuff which must be returned always via sandbox
116     self.output_file_sandbox = []
117    
118     # add fjr report by default via sandbox
119     self.output_file_sandbox.append(self.fjrFileName)
120    
121     # other output files to be returned via sandbox or copied to SE
122 slacapra 1.1 try:
123     self.output_file = []
124     tmp = cfg_params['CMSSW.output_file']
125     if tmp != '':
126     tmpOutFiles = string.split(cfg_params['CMSSW.output_file'],',')
127     log.debug(7, 'cmssw::cmssw(): output files '+str(tmpOutFiles))
128     for tmp in tmpOutFiles:
129     tmp=string.strip(tmp)
130     self.output_file.append(tmp)
131     pass
132     else:
133 gutsche 1.50 log.message("No output file defined: only stdout/err and the CRAB Framework Job Report will be available")
134 slacapra 1.1 pass
135     pass
136     except KeyError:
137 gutsche 1.50 log.message("No output file defined: only stdout/err and the CRAB Framework Job Report will be available")
138 slacapra 1.1 pass
139    
140     # script_exe file as additional file in inputSandbox
141     try:
142 slacapra 1.10 self.scriptExe = cfg_params['USER.script_exe']
143     if self.scriptExe != '':
144     if not os.path.isfile(self.scriptExe):
145 slacapra 1.64 msg ="ERROR. file "+self.scriptExe+" not found"
146 slacapra 1.10 raise CrabException(msg)
147 spiga 1.42 self.additional_inbox_files.append(string.strip(self.scriptExe))
148 slacapra 1.1 except KeyError:
149 spiga 1.42 self.scriptExe = ''
150 slacapra 1.70
151 spiga 1.42 #CarlosDaniele
152     if self.datasetPath == None and self.pset == None and self.scriptExe == '' :
153 slacapra 1.70 msg ="Error. script_exe not defined"
154 spiga 1.42 raise CrabException(msg)
155    
156 slacapra 1.1 ## additional input files
157     try:
158 slacapra 1.29 tmpAddFiles = string.split(cfg_params['USER.additional_input_files'],',')
159 slacapra 1.70 for tmp in tmpAddFiles:
160     tmp = string.strip(tmp)
161     dirname = ''
162     if not tmp[0]=="/": dirname = "."
163 corvo 1.85 files = []
164     if string.find(tmp,"*")>-1:
165     files = glob.glob(os.path.join(dirname, tmp))
166     if len(files)==0:
167     raise CrabException("No additional input file found with this pattern: "+tmp)
168     else:
169     files.append(tmp)
170 slacapra 1.70 for file in files:
171     if not os.path.exists(file):
172     raise CrabException("Additional input file not found: "+file)
173 slacapra 1.45 pass
174 corvo 1.85 fname = string.split(file, '/')[-1]
175     storedFile = common.work_space.pathForTgz()+'share/'+fname
176 slacapra 1.70 shutil.copyfile(file, storedFile)
177     self.additional_inbox_files.append(string.strip(storedFile))
178 slacapra 1.1 pass
179     pass
180 slacapra 1.70 common.logger.debug(5,"Additional input files: "+str(self.additional_inbox_files))
181 slacapra 1.1 except KeyError:
182     pass
183    
184 slacapra 1.9 # files per job
185 slacapra 1.1 try:
186 gutsche 1.35 if (cfg_params['CMSSW.files_per_jobs']):
187     raise CrabException("files_per_jobs no longer supported. Quitting.")
188 gutsche 1.3 except KeyError:
189 gutsche 1.35 pass
190 gutsche 1.3
191 slacapra 1.9 ## Events per job
192 gutsche 1.3 try:
193 slacapra 1.10 self.eventsPerJob =int( cfg_params['CMSSW.events_per_job'])
194 slacapra 1.9 self.selectEventsPerJob = 1
195 gutsche 1.3 except KeyError:
196 slacapra 1.9 self.eventsPerJob = -1
197     self.selectEventsPerJob = 0
198    
199 slacapra 1.22 ## number of jobs
200     try:
201     self.theNumberOfJobs =int( cfg_params['CMSSW.number_of_jobs'])
202     self.selectNumberOfJobs = 1
203     except KeyError:
204     self.theNumberOfJobs = 0
205     self.selectNumberOfJobs = 0
206 slacapra 1.10
207 gutsche 1.35 try:
208     self.total_number_of_events = int(cfg_params['CMSSW.total_number_of_events'])
209     self.selectTotalNumberEvents = 1
210     except KeyError:
211     self.total_number_of_events = 0
212     self.selectTotalNumberEvents = 0
213    
214 spiga 1.42 if self.pset != None: #CarlosDaniele
215     if ( (self.selectTotalNumberEvents + self.selectEventsPerJob + self.selectNumberOfJobs) != 2 ):
216     msg = 'Must define exactly two of total_number_of_events, events_per_job, or number_of_jobs.'
217     raise CrabException(msg)
218     else:
219     if (self.selectNumberOfJobs == 0):
220     msg = 'Must specify number_of_jobs.'
221     raise CrabException(msg)
222 gutsche 1.35
223 slacapra 1.22 ## source seed for pythia
224     try:
225     self.sourceSeed = int(cfg_params['CMSSW.pythia_seed'])
226     except KeyError:
227 slacapra 1.23 self.sourceSeed = None
228     common.logger.debug(5,"No seed given")
229 slacapra 1.22
230 slacapra 1.28 try:
231     self.sourceSeedVtx = int(cfg_params['CMSSW.vtx_seed'])
232     except KeyError:
233     self.sourceSeedVtx = None
234     common.logger.debug(5,"No vertex seed given")
235 spiga 1.57 try:
236     self.firstRun = int(cfg_params['CMSSW.first_run'])
237     except KeyError:
238     self.firstRun = None
239     common.logger.debug(5,"No first run given")
240 spiga 1.42 if self.pset != None: #CarlosDaniele
241     self.PsetEdit = PsetManipulator.PsetManipulator(self.pset) #Daniele Pset
242 gutsche 1.3
243 slacapra 1.1 #DBSDLS-start
244     ## Initialize the variables that are extracted from DBS/DLS and needed in other places of the code
245     self.maxEvents=0 # max events available ( --> check the requested nb. of evts in Creator.py)
246     self.DBSPaths={} # all dbs paths requested ( --> input to the site local discovery script)
247 gutsche 1.35 self.jobDestination=[] # Site destination(s) for each job (list of lists)
248 slacapra 1.1 ## Perform the data location and discovery (based on DBS/DLS)
249 slacapra 1.9 ## SL: Don't if NONE is specified as input (pythia use case)
250 gutsche 1.35 blockSites = {}
251 slacapra 1.9 if self.datasetPath:
252 gutsche 1.35 blockSites = self.DataDiscoveryAndLocation(cfg_params)
253 slacapra 1.1 #DBSDLS-end
254    
255     self.tgzNameWithPath = self.getTarBall(self.executable)
256 slacapra 1.10
257 slacapra 1.9 ## Select Splitting
258 spiga 1.42 if self.selectNoInput:
259     if self.pset == None: #CarlosDaniele
260     self.jobSplittingForScript()
261     else:
262     self.jobSplittingNoInput()
263 corvo 1.56 else:
264     self.jobSplittingByBlocks(blockSites)
265 gutsche 1.5
266 slacapra 1.22 # modify Pset
267 spiga 1.42 if self.pset != None: #CarlosDaniele
268 slacapra 1.86 try:
269     if (self.datasetPath): # standard job
270     # allow to processa a fraction of events in a file
271     self.PsetEdit.inputModule("INPUT")
272     self.PsetEdit.maxEvent("INPUTMAXEVENTS")
273     self.PsetEdit.skipEvent("INPUTSKIPEVENTS")
274     else: # pythia like job
275     self.PsetEdit.maxEvent(self.eventsPerJob)
276     if (self.firstRun):
277     self.PsetEdit.pythiaFirstRun("INPUTFIRSTRUN") #First Run
278     if (self.sourceSeed) :
279     self.PsetEdit.pythiaSeed("INPUT")
280     if (self.sourceSeedVtx) :
281     self.PsetEdit.pythiaSeedVtx("INPUTVTX")
282     # add FrameworkJobReport to parameter-set
283     self.PsetEdit.addCrabFJR(self.fjrFileName)
284     self.PsetEdit.psetWriter(self.configFilename())
285     except:
286     msg='Error while manipuliating ParameterSet: exiting...'
287     raise CrabException(msg)
288 gutsche 1.3
289 slacapra 1.1 def DataDiscoveryAndLocation(self, cfg_params):
290    
291 slacapra 1.86 import DataDiscovery
292     import DataDiscovery_DBS2
293     import DataLocation
294 gutsche 1.3 common.logger.debug(10,"CMSSW::DataDiscoveryAndLocation()")
295    
296     datasetPath=self.datasetPath
297    
298 slacapra 1.1 ## Contact the DBS
299 slacapra 1.41 common.logger.message("Contacting DBS...")
300 slacapra 1.1 try:
301 gutsche 1.66
302 slacapra 1.86 if self.use_dbs_1 == 1 :
303     self.pubdata=DataDiscovery.DataDiscovery(datasetPath, cfg_params)
304     else :
305 corvo 1.85 self.pubdata=DataDiscovery_DBS2.DataDiscovery_DBS2(datasetPath, cfg_params)
306 slacapra 1.1 self.pubdata.fetchDBSInfo()
307    
308 slacapra 1.41 except DataDiscovery.NotExistingDatasetError, ex :
309 slacapra 1.1 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
310     raise CrabException(msg)
311 slacapra 1.41 except DataDiscovery.NoDataTierinProvenanceError, ex :
312 slacapra 1.1 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
313     raise CrabException(msg)
314 slacapra 1.41 except DataDiscovery.DataDiscoveryError, ex:
315 gutsche 1.66 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
316 slacapra 1.1 raise CrabException(msg)
317 gutsche 1.67 except DataDiscovery_DBS2.NotExistingDatasetError_DBS2, ex :
318     msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
319     raise CrabException(msg)
320     except DataDiscovery_DBS2.NoDataTierinProvenanceError_DBS2, ex :
321     msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
322     raise CrabException(msg)
323     except DataDiscovery_DBS2.DataDiscoveryError_DBS2, ex:
324     msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
325     raise CrabException(msg)
326 slacapra 1.1
327     ## get list of all required data in the form of dbs paths (dbs path = /dataset/datatier/owner)
328 gutsche 1.3 common.logger.message("Required data are :"+self.datasetPath)
329    
330 gutsche 1.35 self.filesbyblock=self.pubdata.getFiles()
331 mkirn 1.37 self.eventsbyblock=self.pubdata.getEventsPerBlock()
332     self.eventsbyfile=self.pubdata.getEventsPerFile()
333 gutsche 1.3
334 slacapra 1.1 ## get max number of events
335     self.maxEvents=self.pubdata.getMaxEvents() ## self.maxEvents used in Creator.py
336 gutsche 1.44 common.logger.message("The number of available events is %s\n"%self.maxEvents)
337 slacapra 1.1
338 slacapra 1.41 common.logger.message("Contacting DLS...")
339 slacapra 1.1 ## Contact the DLS and build a list of sites hosting the fileblocks
340     try:
341 slacapra 1.41 dataloc=DataLocation.DataLocation(self.filesbyblock.keys(),cfg_params)
342 gutsche 1.6 dataloc.fetchDLSInfo()
343 slacapra 1.41 except DataLocation.DataLocationError , ex:
344 slacapra 1.1 msg = 'ERROR ***: failed Data Location in DLS \n %s '%ex.getErrorMessage()
345     raise CrabException(msg)
346    
347    
348 gutsche 1.35 sites = dataloc.getSites()
349     allSites = []
350     listSites = sites.values()
351 slacapra 1.63 for listSite in listSites:
352     for oneSite in listSite:
353 gutsche 1.35 allSites.append(oneSite)
354     allSites = self.uniquelist(allSites)
355 gutsche 1.3
356 gutsche 1.35 common.logger.message("Sites ("+str(len(allSites))+") hosting part/all of dataset: "+str(allSites))
357     common.logger.debug(6, "List of Sites: "+str(allSites))
358     return sites
359 gutsche 1.3
360 gutsche 1.35 def jobSplittingByBlocks(self, blockSites):
361 slacapra 1.9 """
362 gutsche 1.35 Perform job splitting. Jobs run over an integer number of files
363     and no more than one block.
364     ARGUMENT: blockSites: dictionary with blocks as keys and list of host sites as values
365     REQUIRES: self.selectTotalNumberEvents, self.selectEventsPerJob, self.selectNumberofJobs,
366     self.total_number_of_events, self.eventsPerJob, self.theNumberOfJobs,
367     self.maxEvents, self.filesbyblock
368     SETS: self.jobDestination - Site destination(s) for each job (a list of lists)
369     self.total_number_of_jobs - Total # of jobs
370     self.list_of_args - File(s) job will run on (a list of lists)
371     """
372    
373     # ---- Handle the possible job splitting configurations ---- #
374     if (self.selectTotalNumberEvents):
375     totalEventsRequested = self.total_number_of_events
376     if (self.selectEventsPerJob):
377     eventsPerJobRequested = self.eventsPerJob
378     if (self.selectNumberOfJobs):
379     totalEventsRequested = self.theNumberOfJobs * self.eventsPerJob
380    
381     # If user requested all the events in the dataset
382     if (totalEventsRequested == -1):
383     eventsRemaining=self.maxEvents
384     # If user requested more events than are in the dataset
385     elif (totalEventsRequested > self.maxEvents):
386     eventsRemaining = self.maxEvents
387     common.logger.message("Requested "+str(self.total_number_of_events)+ " events, but only "+str(self.maxEvents)+" events are available.")
388     # If user requested less events than are in the dataset
389     else:
390     eventsRemaining = totalEventsRequested
391 slacapra 1.22
392 slacapra 1.41 # If user requested more events per job than are in the dataset
393     if (self.selectEventsPerJob and eventsPerJobRequested > self.maxEvents):
394     eventsPerJobRequested = self.maxEvents
395    
396 gutsche 1.35 # For user info at end
397     totalEventCount = 0
398 gutsche 1.3
399 gutsche 1.35 if (self.selectTotalNumberEvents and self.selectNumberOfJobs):
400     eventsPerJobRequested = int(eventsRemaining/self.theNumberOfJobs)
401 slacapra 1.22
402 gutsche 1.35 if (self.selectNumberOfJobs):
403     common.logger.message("May not create the exact number_of_jobs requested.")
404 slacapra 1.23
405 gutsche 1.38 if ( self.ncjobs == 'all' ) :
406     totalNumberOfJobs = 999999999
407     else :
408     totalNumberOfJobs = self.ncjobs
409    
410    
411 gutsche 1.35 blocks = blockSites.keys()
412     blockCount = 0
413     # Backup variable in case self.maxEvents counted events in a non-included block
414     numBlocksInDataset = len(blocks)
415 gutsche 1.3
416 gutsche 1.35 jobCount = 0
417     list_of_lists = []
418 gutsche 1.3
419 gutsche 1.35 # ---- Iterate over the blocks in the dataset until ---- #
420     # ---- we've met the requested total # of events ---- #
421 gutsche 1.38 while ( (eventsRemaining > 0) and (blockCount < numBlocksInDataset) and (jobCount < totalNumberOfJobs)):
422 gutsche 1.35 block = blocks[blockCount]
423 gutsche 1.44 blockCount += 1
424    
425 gutsche 1.68 if self.eventsbyblock.has_key(block) :
426     numEventsInBlock = self.eventsbyblock[block]
427     common.logger.debug(5,'Events in Block File '+str(numEventsInBlock))
428 slacapra 1.9
429 gutsche 1.68 files = self.filesbyblock[block]
430     numFilesInBlock = len(files)
431     if (numFilesInBlock <= 0):
432     continue
433     fileCount = 0
434    
435     # ---- New block => New job ---- #
436     parString = "\\{"
437     # counter for number of events in files currently worked on
438     filesEventCount = 0
439     # flag if next while loop should touch new file
440     newFile = 1
441     # job event counter
442     jobSkipEventCount = 0
443 slacapra 1.9
444 gutsche 1.68 # ---- Iterate over the files in the block until we've met the requested ---- #
445     # ---- total # of events or we've gone over all the files in this block ---- #
446     while ( (eventsRemaining > 0) and (fileCount < numFilesInBlock) and (jobCount < totalNumberOfJobs) ):
447     file = files[fileCount]
448     if newFile :
449     try:
450     numEventsInFile = self.eventsbyfile[file]
451     common.logger.debug(6, "File "+str(file)+" has "+str(numEventsInFile)+" events")
452     # increase filesEventCount
453     filesEventCount += numEventsInFile
454     # Add file to current job
455     parString += '\\\"' + file + '\\\"\,'
456     newFile = 0
457     except KeyError:
458     common.logger.message("File "+str(file)+" has unknown number of events: skipping")
459 slacapra 1.41
460 gutsche 1.38
461 gutsche 1.68 # if less events in file remain than eventsPerJobRequested
462     if ( filesEventCount - jobSkipEventCount < eventsPerJobRequested ) :
463     # if last file in block
464     if ( fileCount == numFilesInBlock-1 ) :
465     # end job using last file, use remaining events in block
466     # close job and touch new file
467     fullString = parString[:-2]
468     fullString += '\\}'
469     list_of_lists.append([fullString,str(-1),str(jobSkipEventCount)])
470     common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(filesEventCount - jobSkipEventCount)+" events (last file in block).")
471     self.jobDestination.append(blockSites[block])
472     common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
473     # reset counter
474     jobCount = jobCount + 1
475     totalEventCount = totalEventCount + filesEventCount - jobSkipEventCount
476     eventsRemaining = eventsRemaining - filesEventCount + jobSkipEventCount
477     jobSkipEventCount = 0
478     # reset file
479     parString = "\\{"
480     filesEventCount = 0
481     newFile = 1
482     fileCount += 1
483     else :
484     # go to next file
485     newFile = 1
486     fileCount += 1
487     # if events in file equal to eventsPerJobRequested
488     elif ( filesEventCount - jobSkipEventCount == eventsPerJobRequested ) :
489 gutsche 1.38 # close job and touch new file
490     fullString = parString[:-2]
491     fullString += '\\}'
492 gutsche 1.68 list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
493     common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(eventsPerJobRequested)+" events.")
494 gutsche 1.38 self.jobDestination.append(blockSites[block])
495     common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
496     # reset counter
497     jobCount = jobCount + 1
498 gutsche 1.68 totalEventCount = totalEventCount + eventsPerJobRequested
499     eventsRemaining = eventsRemaining - eventsPerJobRequested
500 gutsche 1.38 jobSkipEventCount = 0
501     # reset file
502     parString = "\\{"
503     filesEventCount = 0
504     newFile = 1
505     fileCount += 1
506 gutsche 1.68
507     # if more events in file remain than eventsPerJobRequested
508 gutsche 1.38 else :
509 gutsche 1.68 # close job but don't touch new file
510     fullString = parString[:-2]
511     fullString += '\\}'
512     list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
513     common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(eventsPerJobRequested)+" events.")
514     self.jobDestination.append(blockSites[block])
515     common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
516     # increase counter
517     jobCount = jobCount + 1
518     totalEventCount = totalEventCount + eventsPerJobRequested
519     eventsRemaining = eventsRemaining - eventsPerJobRequested
520     # calculate skip events for last file
521     # use filesEventCount (contains several files), jobSkipEventCount and eventsPerJobRequest
522     jobSkipEventCount = eventsPerJobRequested - (filesEventCount - jobSkipEventCount - self.eventsbyfile[file])
523     # remove all but the last file
524     filesEventCount = self.eventsbyfile[file]
525     parString = "\\{"
526     parString += '\\\"' + file + '\\\"\,'
527     pass # END if
528     pass # END while (iterate over files in the block)
529 gutsche 1.35 pass # END while (iterate over blocks in the dataset)
530 slacapra 1.41 self.ncjobs = self.total_number_of_jobs = jobCount
531 gutsche 1.38 if (eventsRemaining > 0 and jobCount < totalNumberOfJobs ):
532 gutsche 1.35 common.logger.message("Could not run on all requested events because some blocks not hosted at allowed sites.")
533 mkirn 1.37 common.logger.message("\n"+str(jobCount)+" job(s) can run on "+str(totalEventCount)+" events.\n")
534 slacapra 1.22
535 slacapra 1.9 self.list_of_args = list_of_lists
536     return
537    
538 slacapra 1.21 def jobSplittingNoInput(self):
539 slacapra 1.9 """
540     Perform job splitting based on number of event per job
541     """
542     common.logger.debug(5,'Splitting per events')
543     common.logger.message('Required '+str(self.eventsPerJob)+' events per job ')
544 slacapra 1.22 common.logger.message('Required '+str(self.theNumberOfJobs)+' jobs in total ')
545 slacapra 1.9 common.logger.message('Required '+str(self.total_number_of_events)+' events in total ')
546    
547 slacapra 1.10 if (self.total_number_of_events < 0):
548     msg='Cannot split jobs per Events with "-1" as total number of events'
549     raise CrabException(msg)
550    
551 slacapra 1.22 if (self.selectEventsPerJob):
552 spiga 1.65 if (self.selectTotalNumberEvents):
553     self.total_number_of_jobs = int(self.total_number_of_events/self.eventsPerJob)
554     elif(self.selectNumberOfJobs) :
555     self.total_number_of_jobs =self.theNumberOfJobs
556     self.total_number_of_events =int(self.theNumberOfJobs*self.eventsPerJob)
557    
558 slacapra 1.22 elif (self.selectNumberOfJobs) :
559     self.total_number_of_jobs = self.theNumberOfJobs
560     self.eventsPerJob = int(self.total_number_of_events/self.total_number_of_jobs)
561 spiga 1.65
562 slacapra 1.9 common.logger.debug(5,'N jobs '+str(self.total_number_of_jobs))
563    
564     # is there any remainder?
565     check = int(self.total_number_of_events) - (int(self.total_number_of_jobs)*self.eventsPerJob)
566    
567     common.logger.debug(5,'Check '+str(check))
568    
569 gutsche 1.35 common.logger.message(str(self.total_number_of_jobs)+' jobs can be created, each for '+str(self.eventsPerJob)+' for a total of '+str(self.total_number_of_jobs*self.eventsPerJob)+' events')
570 slacapra 1.9 if check > 0:
571 gutsche 1.35 common.logger.message('Warning: asked '+str(self.total_number_of_events)+' but can do only '+str(int(self.total_number_of_jobs)*self.eventsPerJob))
572 slacapra 1.9
573 slacapra 1.10 # argument is seed number.$i
574 slacapra 1.9 self.list_of_args = []
575     for i in range(self.total_number_of_jobs):
576 gutsche 1.35 ## Since there is no input, any site is good
577 slacapra 1.86 # self.jobDestination.append(["Any"])
578 spiga 1.42 self.jobDestination.append([""]) #must be empty to write correctly the xml
579 slacapra 1.86 args=''
580 spiga 1.57 if (self.firstRun):
581     ## pythia first run
582 slacapra 1.86 #self.list_of_args.append([(str(self.firstRun)+str(i))])
583     args=args+(str(self.firstRun)+str(i))
584 spiga 1.57 else:
585     ## no first run
586 slacapra 1.86 #self.list_of_args.append([str(i)])
587     args=args+str(i)
588 slacapra 1.23 if (self.sourceSeed):
589 slacapra 1.28 if (self.sourceSeedVtx):
590 slacapra 1.86 ## pythia + vtx random seed
591     #self.list_of_args.append([
592     # str(self.sourceSeed)+str(i),
593     # str(self.sourceSeedVtx)+str(i)
594     # ])
595     args=args+str(',')+str(self.sourceSeed)+str(i)+str(',')+str(self.sourceSeedVtx)+str(i)
596     else:
597     ## only pythia random seed
598     #self.list_of_args.append([(str(self.sourceSeed)+str(i))])
599     args=args +str(',')+str(self.sourceSeed)+str(i)
600     else:
601     ## no random seed
602     if str(args)=='': args=args+(str(self.firstRun)+str(i))
603     arguments=args.split(',')
604     if len(arguments)==3:self.list_of_args.append([str(arguments[0]),str(arguments[1]),str(arguments[2])])
605     elif len(arguments)==2:self.list_of_args.append([str(arguments[0]),str(arguments[1])])
606     else :self.list_of_args.append([str(arguments[0])])
607    
608     # print self.list_of_args
609 gutsche 1.3
610     return
611    
612 spiga 1.42
613     def jobSplittingForScript(self):#CarlosDaniele
614     """
615     Perform job splitting based on number of job
616     """
617     common.logger.debug(5,'Splitting per job')
618     common.logger.message('Required '+str(self.theNumberOfJobs)+' jobs in total ')
619    
620     self.total_number_of_jobs = self.theNumberOfJobs
621    
622     common.logger.debug(5,'N jobs '+str(self.total_number_of_jobs))
623    
624     common.logger.message(str(self.total_number_of_jobs)+' jobs can be created')
625    
626     # argument is seed number.$i
627     self.list_of_args = []
628     for i in range(self.total_number_of_jobs):
629     ## Since there is no input, any site is good
630     # self.jobDestination.append(["Any"])
631     self.jobDestination.append([""])
632     ## no random seed
633     self.list_of_args.append([str(i)])
634     return
635    
636 gutsche 1.3 def split(self, jobParams):
637    
638     common.jobDB.load()
639     #### Fabio
640     njobs = self.total_number_of_jobs
641 slacapra 1.9 arglist = self.list_of_args
642 gutsche 1.3 # create the empty structure
643     for i in range(njobs):
644     jobParams.append("")
645    
646     for job in range(njobs):
647 slacapra 1.17 jobParams[job] = arglist[job]
648     # print str(arglist[job])
649     # print jobParams[job]
650 gutsche 1.3 common.jobDB.setArguments(job, jobParams[job])
651 gutsche 1.35 common.logger.debug(5,"Job "+str(job)+" Destination: "+str(self.jobDestination[job]))
652     common.jobDB.setDestination(job, self.jobDestination[job])
653 gutsche 1.3
654     common.jobDB.save()
655     return
656    
657     def getJobTypeArguments(self, nj, sched):
658 slacapra 1.17 result = ''
659     for i in common.jobDB.arguments(nj):
660     result=result+str(i)+" "
661     return result
662 gutsche 1.3
663     def numberOfJobs(self):
664     # Fabio
665     return self.total_number_of_jobs
666    
667 slacapra 1.1 def getTarBall(self, exe):
668     """
669     Return the TarBall with lib and exe
670     """
671    
672     # if it exist, just return it
673 corvo 1.56 #
674     # Marco. Let's start to use relative path for Boss XML files
675     #
676     self.tgzNameWithPath = common.work_space.pathForTgz()+'share/'+self.tgz_name
677 slacapra 1.1 if os.path.exists(self.tgzNameWithPath):
678     return self.tgzNameWithPath
679    
680     # Prepare a tar gzipped file with user binaries.
681     self.buildTar_(exe)
682    
683     return string.strip(self.tgzNameWithPath)
684    
685     def buildTar_(self, executable):
686    
687     # First of all declare the user Scram area
688     swArea = self.scram.getSWArea_()
689     #print "swArea = ", swArea
690 slacapra 1.63 # swVersion = self.scram.getSWVersion()
691     # print "swVersion = ", swVersion
692 slacapra 1.1 swReleaseTop = self.scram.getReleaseTop_()
693     #print "swReleaseTop = ", swReleaseTop
694    
695     ## check if working area is release top
696     if swReleaseTop == '' or swArea == swReleaseTop:
697     return
698    
699 slacapra 1.61 import tarfile
700     try: # create tar ball
701     tar = tarfile.open(self.tgzNameWithPath, "w:gz")
702     ## First find the executable
703 slacapra 1.86 if (self.executable != ''):
704 slacapra 1.61 exeWithPath = self.scram.findFile_(executable)
705     if ( not exeWithPath ):
706     raise CrabException('User executable '+executable+' not found')
707    
708     ## then check if it's private or not
709     if exeWithPath.find(swReleaseTop) == -1:
710     # the exe is private, so we must ship
711     common.logger.debug(5,"Exe "+exeWithPath+" to be tarred")
712     path = swArea+'/'
713 corvo 1.85 # distinguish case when script is in user project area or given by full path somewhere else
714     if exeWithPath.find(path) >= 0 :
715     exe = string.replace(exeWithPath, path,'')
716     tar.add(path+exe,os.path.basename(executable))
717     else :
718     tar.add(exeWithPath,os.path.basename(executable))
719 slacapra 1.61 pass
720     else:
721     # the exe is from release, we'll find it on WN
722     pass
723    
724     ## Now get the libraries: only those in local working area
725     libDir = 'lib'
726     lib = swArea+'/' +libDir
727     common.logger.debug(5,"lib "+lib+" to be tarred")
728     if os.path.exists(lib):
729     tar.add(lib,libDir)
730    
731     ## Now check if module dir is present
732     moduleDir = 'module'
733     module = swArea + '/' + moduleDir
734     if os.path.isdir(module):
735     tar.add(module,moduleDir)
736    
737     ## Now check if any data dir(s) is present
738     swAreaLen=len(swArea)
739     for root, dirs, files in os.walk(swArea):
740     if "data" in dirs:
741     common.logger.debug(5,"data "+root+"/data"+" to be tarred")
742     tar.add(root+"/data",root[swAreaLen:]+"/data")
743    
744     ## Add ProdAgent dir to tar
745     paDir = 'ProdAgentApi'
746     pa = os.environ['CRABDIR'] + '/' + 'ProdAgentApi'
747     if os.path.isdir(pa):
748     tar.add(pa,paDir)
749    
750     common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
751     tar.close()
752     except :
753     raise CrabException('Could not create tar-ball')
754 gutsche 1.72
755     ## check for tarball size
756     tarballinfo = os.stat(self.tgzNameWithPath)
757     if ( tarballinfo.st_size > self.MaxTarBallSize*1024*1024 ) :
758     raise CrabException('Input sandbox size of ' + str(float(tarballinfo.st_size)/1024.0/1024.0) + ' MB is larger than the allowed ' + str(self.MaxTarBallSize) + ' MB input sandbox limit and not supported by the used GRID submission system. Please make sure that no unnecessary files are in all data directories in your local CMSSW project area as they are automatically packed into the input sandbox.')
759    
760 slacapra 1.61 ## create tar-ball with ML stuff
761 corvo 1.58 self.MLtgzfile = common.work_space.pathForTgz()+'share/MLfiles.tgz'
762 slacapra 1.61 try:
763     tar = tarfile.open(self.MLtgzfile, "w:gz")
764     path=os.environ['CRABDIR'] + '/python/'
765     for file in ['report.py', 'DashboardAPI.py', 'Logger.py', 'ProcInfo.py', 'apmon.py', 'parseCrabFjr.py']:
766     tar.add(path+file,file)
767     common.logger.debug(5,"Files added to "+self.MLtgzfile+" : "+str(tar.getnames()))
768     tar.close()
769     except :
770 corvo 1.58 raise CrabException('Could not create ML files tar-ball')
771    
772 slacapra 1.1 return
773    
774     def wsSetupEnvironment(self, nj):
775     """
776     Returns part of a job script which prepares
777     the execution environment for the job 'nj'.
778     """
779     # Prepare JobType-independent part
780 gutsche 1.3 txt = ''
781    
782     ## OLI_Daniele at this level middleware already known
783    
784     txt += 'if [ $middleware == LCG ]; then \n'
785     txt += self.wsSetupCMSLCGEnvironment_()
786     txt += 'elif [ $middleware == OSG ]; then\n'
787 gutsche 1.43 txt += ' WORKING_DIR=`/bin/mktemp -d $OSG_WN_TMP/cms_XXXXXXXXXXXX`\n'
788     txt += ' echo "Created working directory: $WORKING_DIR"\n'
789 gutsche 1.3 txt += ' if [ ! -d $WORKING_DIR ] ;then\n'
790 gutsche 1.7 txt += ' echo "SET_CMS_ENV 10016 ==> OSG $WORKING_DIR could not be created on WN `hostname`"\n'
791     txt += ' echo "JOB_EXIT_STATUS = 10016"\n'
792     txt += ' echo "JobExitCode=10016" | tee -a $RUNTIME_AREA/$repo\n'
793     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
794 gutsche 1.13 txt += ' rm -f $RUNTIME_AREA/$repo \n'
795     txt += ' echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
796     txt += ' echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
797 gutsche 1.3 txt += ' exit 1\n'
798     txt += ' fi\n'
799     txt += '\n'
800     txt += ' echo "Change to working directory: $WORKING_DIR"\n'
801     txt += ' cd $WORKING_DIR\n'
802     txt += self.wsSetupCMSOSGEnvironment_()
803     txt += 'fi\n'
804 slacapra 1.1
805     # Prepare JobType-specific part
806     scram = self.scram.commandName()
807     txt += '\n\n'
808     txt += 'echo "### SPECIFIC JOB SETUP ENVIRONMENT ###"\n'
809 slacapra 1.86 txt += 'echo "Setting SCRAM_ARCH='+self.executable_arch+'"\n'
810     txt += 'export SCRAM_ARCH='+self.executable_arch+'\n'
811 slacapra 1.1 txt += scram+' project CMSSW '+self.version+'\n'
812     txt += 'status=$?\n'
813     txt += 'if [ $status != 0 ] ; then\n'
814 gutsche 1.7 txt += ' echo "SET_EXE_ENV 10034 ==>ERROR CMSSW '+self.version+' not found on `hostname`" \n'
815 gutsche 1.3 txt += ' echo "JOB_EXIT_STATUS = 10034"\n'
816 gutsche 1.7 txt += ' echo "JobExitCode=10034" | tee -a $RUNTIME_AREA/$repo\n'
817 slacapra 1.1 txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
818 gutsche 1.13 txt += ' rm -f $RUNTIME_AREA/$repo \n'
819     txt += ' echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
820     txt += ' echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
821 gutsche 1.3 ## OLI_Daniele
822     txt += ' if [ $middleware == OSG ]; then \n'
823     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
824     txt += ' cd $RUNTIME_AREA\n'
825     txt += ' /bin/rm -rf $WORKING_DIR\n'
826     txt += ' if [ -d $WORKING_DIR ] ;then\n'
827 gutsche 1.7 txt += ' echo "SET_CMS_ENV 10018 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after CMSSW CMSSW_0_6_1 not found on `hostname`"\n'
828     txt += ' echo "JOB_EXIT_STATUS = 10018"\n'
829     txt += ' echo "JobExitCode=10018" | tee -a $RUNTIME_AREA/$repo\n'
830     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
831 gutsche 1.13 txt += ' rm -f $RUNTIME_AREA/$repo \n'
832     txt += ' echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
833     txt += ' echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
834 gutsche 1.3 txt += ' fi\n'
835     txt += ' fi \n'
836     txt += ' exit 1 \n'
837 slacapra 1.1 txt += 'fi \n'
838     txt += 'echo "CMSSW_VERSION = '+self.version+'"\n'
839     txt += 'cd '+self.version+'\n'
840     ### needed grep for bug in scramv1 ###
841 corvo 1.58 txt += scram+' runtime -sh\n'
842 slacapra 1.1 txt += 'eval `'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME`\n'
843 corvo 1.58 txt += 'echo $PATH\n'
844 slacapra 1.1
845     # Handle the arguments:
846     txt += "\n"
847 gutsche 1.7 txt += "## number of arguments (first argument always jobnumber)\n"
848 slacapra 1.1 txt += "\n"
849 mkirn 1.32 # txt += "narg=$#\n"
850     txt += "if [ $nargs -lt 2 ]\n"
851 slacapra 1.1 txt += "then\n"
852 mkirn 1.33 txt += " echo 'SET_EXE_ENV 1 ==> ERROR Too few arguments' +$nargs+ \n"
853 gutsche 1.3 txt += ' echo "JOB_EXIT_STATUS = 50113"\n'
854 gutsche 1.7 txt += ' echo "JobExitCode=50113" | tee -a $RUNTIME_AREA/$repo\n'
855 slacapra 1.1 txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
856 gutsche 1.13 txt += ' rm -f $RUNTIME_AREA/$repo \n'
857     txt += ' echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
858     txt += ' echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
859 gutsche 1.3 ## OLI_Daniele
860     txt += ' if [ $middleware == OSG ]; then \n'
861     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
862     txt += ' cd $RUNTIME_AREA\n'
863     txt += ' /bin/rm -rf $WORKING_DIR\n'
864     txt += ' if [ -d $WORKING_DIR ] ;then\n'
865 gutsche 1.7 txt += ' echo "SET_EXE_ENV 50114 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after Too few arguments for CRAB job wrapper"\n'
866     txt += ' echo "JOB_EXIT_STATUS = 50114"\n'
867     txt += ' echo "JobExitCode=50114" | tee -a $RUNTIME_AREA/$repo\n'
868     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
869 gutsche 1.13 txt += ' rm -f $RUNTIME_AREA/$repo \n'
870     txt += ' echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
871     txt += ' echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
872 gutsche 1.3 txt += ' fi\n'
873     txt += ' fi \n'
874 slacapra 1.1 txt += " exit 1\n"
875     txt += "fi\n"
876     txt += "\n"
877    
878     # Prepare job-specific part
879     job = common.job_list[nj]
880 spiga 1.42 if self.pset != None: #CarlosDaniele
881     pset = os.path.basename(job.configFilename())
882     txt += '\n'
883     if (self.datasetPath): # standard job
884     #txt += 'InputFiles=$2\n'
885     txt += 'InputFiles=${args[1]}\n'
886     txt += 'MaxEvents=${args[2]}\n'
887     txt += 'SkipEvents=${args[3]}\n'
888     txt += 'echo "Inputfiles:<$InputFiles>"\n'
889 slacapra 1.86 txt += 'sed "s#{\'INPUT\'}#$InputFiles#" $RUNTIME_AREA/'+pset+' > pset_tmp_1.cfg\n'
890 spiga 1.42 txt += 'echo "MaxEvents:<$MaxEvents>"\n'
891 slacapra 1.86 txt += 'sed "s#INPUTMAXEVENTS#$MaxEvents#" pset_tmp_1.cfg > pset_tmp_2.cfg\n'
892 spiga 1.42 txt += 'echo "SkipEvents:<$SkipEvents>"\n'
893 slacapra 1.86 txt += 'sed "s#INPUTSKIPEVENTS#$SkipEvents#" pset_tmp_2.cfg > pset.cfg\n'
894 spiga 1.42 else: # pythia like job
895 slacapra 1.86 if (self.sourceSeed):
896     txt += 'FirstRun=${args[1]}\n'
897 spiga 1.57 txt += 'echo "FirstRun: <$FirstRun>"\n'
898 slacapra 1.86 txt += 'sed "s#\<INPUTFIRSTRUN\>#$FirstRun#" $RUNTIME_AREA/'+pset+' > tmp_1.cfg\n'
899     else:
900     txt += '# Copy untouched pset\n'
901     txt += 'cp $RUNTIME_AREA/'+pset+' tmp_1.cfg\n'
902 spiga 1.57 if (self.sourceSeed):
903 slacapra 1.86 # txt += 'Seed=$2\n'
904     txt += 'Seed=${args[2]}\n'
905 spiga 1.42 txt += 'echo "Seed: <$Seed>"\n'
906 slacapra 1.86 txt += 'sed "s#\<INPUT\>#$Seed#" tmp_1.cfg > tmp_2.cfg\n'
907 spiga 1.42 if (self.sourceSeedVtx):
908 slacapra 1.86 # txt += 'VtxSeed=$3\n'
909     txt += 'VtxSeed=${args[3]}\n'
910 spiga 1.42 txt += 'echo "VtxSeed: <$VtxSeed>"\n'
911 slacapra 1.86 txt += 'sed "s#INPUTVTX#$VtxSeed#" tmp_2.cfg > pset.cfg\n'
912     else:
913     txt += 'mv tmp_2.cfg pset.cfg\n'
914     else:
915     txt += 'mv tmp_1.cfg pset.cfg\n'
916     # txt += '# Copy untouched pset\n'
917     # txt += 'cp $RUNTIME_AREA/'+pset+' pset.cfg\n'
918 slacapra 1.24
919 slacapra 1.1
920     if len(self.additional_inbox_files) > 0:
921     for file in self.additional_inbox_files:
922 mkirn 1.31 relFile = file.split("/")[-1]
923     txt += 'if [ -e $RUNTIME_AREA/'+relFile+' ] ; then\n'
924     txt += ' cp $RUNTIME_AREA/'+relFile+' .\n'
925     txt += ' chmod +x '+relFile+'\n'
926 slacapra 1.1 txt += 'fi\n'
927     pass
928    
929 spiga 1.42 if self.pset != None: #CarlosDaniele
930     txt += 'echo "### END JOB SETUP ENVIRONMENT ###"\n\n'
931    
932     txt += '\n'
933     txt += 'echo "***** cat pset.cfg *********"\n'
934     txt += 'cat pset.cfg\n'
935     txt += 'echo "****** end pset.cfg ********"\n'
936     txt += '\n'
937     # txt += 'echo "***** cat pset1.cfg *********"\n'
938     # txt += 'cat pset1.cfg\n'
939     # txt += 'echo "****** end pset1.cfg ********"\n'
940 gutsche 1.3 return txt
941    
942 slacapra 1.63 def wsBuildExe(self, nj=0):
943 gutsche 1.3 """
944     Put in the script the commands to build an executable
945     or a library.
946     """
947    
948     txt = ""
949    
950     if os.path.isfile(self.tgzNameWithPath):
951     txt += 'echo "tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'"\n'
952     txt += 'tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'\n'
953     txt += 'untar_status=$? \n'
954     txt += 'if [ $untar_status -ne 0 ]; then \n'
955     txt += ' echo "SET_EXE 1 ==> ERROR Untarring .tgz file failed"\n'
956     txt += ' echo "JOB_EXIT_STATUS = $untar_status" \n'
957 gutsche 1.7 txt += ' echo "JobExitCode=$untar_status" | tee -a $RUNTIME_AREA/$repo\n'
958 gutsche 1.3 txt += ' if [ $middleware == OSG ]; then \n'
959     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
960     txt += ' cd $RUNTIME_AREA\n'
961     txt += ' /bin/rm -rf $WORKING_DIR\n'
962     txt += ' if [ -d $WORKING_DIR ] ;then\n'
963 gutsche 1.13 txt += ' echo "SET_EXE 50999 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after Untarring .tgz file failed"\n'
964     txt += ' echo "JOB_EXIT_STATUS = 50999"\n'
965     txt += ' echo "JobExitCode=50999" | tee -a $RUNTIME_AREA/$repo\n'
966     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
967     txt += ' rm -f $RUNTIME_AREA/$repo \n'
968     txt += ' echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
969     txt += ' echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
970 gutsche 1.3 txt += ' fi\n'
971     txt += ' fi \n'
972     txt += ' \n'
973 gutsche 1.7 txt += ' exit 1 \n'
974 gutsche 1.3 txt += 'else \n'
975     txt += ' echo "Successful untar" \n'
976     txt += 'fi \n'
977 gutsche 1.50 txt += '\n'
978     txt += 'echo "Include ProdAgentApi in PYTHONPATH"\n'
979     txt += 'if [ -z "$PYTHONPATH" ]; then\n'
980     txt += ' export PYTHONPATH=ProdAgentApi\n'
981     txt += 'else\n'
982     txt += ' export PYTHONPATH=ProdAgentApi:${PYTHONPATH}\n'
983     txt += 'fi\n'
984     txt += '\n'
985    
986 gutsche 1.3 pass
987    
988 slacapra 1.1 return txt
989    
990     def modifySteeringCards(self, nj):
991     """
992     modify the card provided by the user,
993     writing a new card into share dir
994     """
995    
996     def executableName(self):
997 slacapra 1.70 if self.scriptExe: #CarlosDaniele
998 spiga 1.42 return "sh "
999     else:
1000     return self.executable
1001 slacapra 1.1
1002     def executableArgs(self):
1003 slacapra 1.70 if self.scriptExe:#CarlosDaniele
1004 spiga 1.42 return self.scriptExe + " $NJob"
1005     else:
1006     return " -p pset.cfg"
1007 slacapra 1.1
1008     def inputSandbox(self, nj):
1009     """
1010     Returns a list of filenames to be put in JDL input sandbox.
1011     """
1012     inp_box = []
1013 slacapra 1.53 # # dict added to delete duplicate from input sandbox file list
1014     # seen = {}
1015 slacapra 1.1 ## code
1016     if os.path.isfile(self.tgzNameWithPath):
1017     inp_box.append(self.tgzNameWithPath)
1018 corvo 1.58 if os.path.isfile(self.MLtgzfile):
1019     inp_box.append(self.MLtgzfile)
1020 slacapra 1.1 ## config
1021 slacapra 1.70 if not self.pset is None:
1022 corvo 1.56 inp_box.append(common.work_space.pathForTgz() + 'job/' + self.configFilename())
1023 slacapra 1.1 ## additional input files
1024 slacapra 1.70 for file in self.additional_inbox_files:
1025     inp_box.append(file)
1026 slacapra 1.1 return inp_box
1027    
1028     def outputSandbox(self, nj):
1029     """
1030     Returns a list of filenames to be put in JDL output sandbox.
1031     """
1032     out_box = []
1033    
1034     ## User Declared output files
1035 slacapra 1.54 for out in (self.output_file+self.output_file_sandbox):
1036 slacapra 1.1 n_out = nj + 1
1037     out_box.append(self.numberFile_(out,str(n_out)))
1038     return out_box
1039    
1040     def prepareSteeringCards(self):
1041     """
1042     Make initial modifications of the user's steering card file.
1043     """
1044     return
1045    
1046     def wsRenameOutput(self, nj):
1047     """
1048     Returns part of a job script which renames the produced files.
1049     """
1050    
1051     txt = '\n'
1052 gutsche 1.7 txt += '# directory content\n'
1053     txt += 'ls \n'
1054 slacapra 1.54
1055     for fileWithSuffix in (self.output_file+self.output_file_sandbox):
1056 slacapra 1.1 output_file_num = self.numberFile_(fileWithSuffix, '$NJob')
1057     txt += '\n'
1058 gutsche 1.7 txt += '# check output file\n'
1059 slacapra 1.1 txt += 'ls '+fileWithSuffix+'\n'
1060 fanzago 1.18 txt += 'ls_result=$?\n'
1061     txt += 'if [ $ls_result -ne 0 ] ; then\n'
1062 spiga 1.88 #txt += ' JOB_EXIT_STATUS=60302\n'
1063     ### FEDE
1064     txt += ' exit_status=60302\n'
1065     ####
1066 fanzago 1.18 txt += ' echo "ERROR: Problem with output file"\n'
1067 gutsche 1.7 if common.scheduler.boss_scheduler_name == 'condor_g':
1068     txt += ' if [ $middleware == OSG ]; then \n'
1069     txt += ' echo "prepare dummy output file"\n'
1070     txt += ' echo "Processing of job output failed" > $RUNTIME_AREA/'+output_file_num+'\n'
1071     txt += ' fi \n'
1072 slacapra 1.1 txt += 'else\n'
1073     txt += ' cp '+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
1074     txt += 'fi\n'
1075    
1076 gutsche 1.7 txt += 'cd $RUNTIME_AREA\n'
1077 fanzago 1.18 txt += 'cd $RUNTIME_AREA\n'
1078 gutsche 1.3 ### OLI_DANIELE
1079     txt += 'if [ $middleware == OSG ]; then\n'
1080     txt += ' cd $RUNTIME_AREA\n'
1081     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
1082     txt += ' /bin/rm -rf $WORKING_DIR\n'
1083     txt += ' if [ -d $WORKING_DIR ] ;then\n'
1084 gutsche 1.7 txt += ' echo "SET_EXE 60999 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after cleanup of WN"\n'
1085     txt += ' echo "JOB_EXIT_STATUS = 60999"\n'
1086     txt += ' echo "JobExitCode=60999" | tee -a $RUNTIME_AREA/$repo\n'
1087     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
1088 gutsche 1.13 txt += ' rm -f $RUNTIME_AREA/$repo \n'
1089     txt += ' echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1090     txt += ' echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1091 gutsche 1.3 txt += ' fi\n'
1092     txt += 'fi\n'
1093     txt += '\n'
1094 slacapra 1.54
1095     file_list = ''
1096     ## Add to filelist only files to be possibly copied to SE
1097     for fileWithSuffix in self.output_file:
1098     output_file_num = self.numberFile_(fileWithSuffix, '$NJob')
1099     file_list=file_list+output_file_num+' '
1100     file_list=file_list[:-1]
1101     txt += 'file_list="'+file_list+'"\n'
1102    
1103 slacapra 1.1 return txt
1104    
1105     def numberFile_(self, file, txt):
1106     """
1107     append _'txt' before last extension of a file
1108     """
1109     p = string.split(file,".")
1110     # take away last extension
1111     name = p[0]
1112     for x in p[1:-1]:
1113     name=name+"."+x
1114     # add "_txt"
1115     if len(p)>1:
1116     ext = p[len(p)-1]
1117     result = name + '_' + txt + "." + ext
1118     else:
1119     result = name + '_' + txt
1120    
1121     return result
1122    
1123 slacapra 1.63 def getRequirements(self, nj=[]):
1124 slacapra 1.1 """
1125     return job requirements to add to jdl files
1126     """
1127     req = ''
1128 slacapra 1.47 if self.version:
1129 slacapra 1.10 req='Member("VO-cms-' + \
1130 slacapra 1.47 self.version + \
1131 slacapra 1.10 '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1132 gutsche 1.35
1133     req = req + ' && (other.GlueHostNetworkAdapterOutboundIP)'
1134    
1135 slacapra 1.1 return req
1136 gutsche 1.3
1137     def configFilename(self):
1138     """ return the config filename """
1139     return self.name()+'.cfg'
1140    
1141     ### OLI_DANIELE
1142     def wsSetupCMSOSGEnvironment_(self):
1143     """
1144     Returns part of a job script which is prepares
1145     the execution environment and which is common for all CMS jobs.
1146     """
1147     txt = '\n'
1148     txt += ' echo "### SETUP CMS OSG ENVIRONMENT ###"\n'
1149     txt += ' if [ -f $GRID3_APP_DIR/cmssoft/cmsset_default.sh ] ;then\n'
1150     txt += ' # Use $GRID3_APP_DIR/cmssoft/cmsset_default.sh to setup cms software\n'
1151 spiga 1.87 txt += ' export SCRAM_ARCH='+self.executable_arch+'\n'
1152 gutsche 1.3 txt += ' source $GRID3_APP_DIR/cmssoft/cmsset_default.sh '+self.version+'\n'
1153 mkirn 1.40 txt += ' elif [ -f $OSG_APP/cmssoft/cms/cmsset_default.sh ] ;then\n'
1154     txt += ' # Use $OSG_APP/cmssoft/cms/cmsset_default.sh to setup cms software\n'
1155 spiga 1.87 txt += ' export SCRAM_ARCH='+self.executable_arch+'\n'
1156 mkirn 1.40 txt += ' source $OSG_APP/cmssoft/cms/cmsset_default.sh '+self.version+'\n'
1157 gutsche 1.3 txt += ' else\n'
1158 mkirn 1.40 txt += ' echo "SET_CMS_ENV 10020 ==> ERROR $GRID3_APP_DIR/cmssoft/cmsset_default.sh and $OSG_APP/cmssoft/cms/cmsset_default.sh file not found"\n'
1159 gutsche 1.3 txt += ' echo "JOB_EXIT_STATUS = 10020"\n'
1160     txt += ' echo "JobExitCode=10020" | tee -a $RUNTIME_AREA/$repo\n'
1161     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
1162 gutsche 1.13 txt += ' rm -f $RUNTIME_AREA/$repo \n'
1163     txt += ' echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1164     txt += ' echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1165 gutsche 1.7 txt += ' exit 1\n'
1166 gutsche 1.3 txt += '\n'
1167     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
1168     txt += ' cd $RUNTIME_AREA\n'
1169     txt += ' /bin/rm -rf $WORKING_DIR\n'
1170     txt += ' if [ -d $WORKING_DIR ] ;then\n'
1171 mkirn 1.40 txt += ' echo "SET_CMS_ENV 10017 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after $GRID3_APP_DIR/cmssoft/cmsset_default.sh and $OSG_APP/cmssoft/cms/cmsset_default.sh file not found"\n'
1172 gutsche 1.7 txt += ' echo "JOB_EXIT_STATUS = 10017"\n'
1173     txt += ' echo "JobExitCode=10017" | tee -a $RUNTIME_AREA/$repo\n'
1174     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
1175 gutsche 1.13 txt += ' rm -f $RUNTIME_AREA/$repo \n'
1176     txt += ' echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1177     txt += ' echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1178 gutsche 1.3 txt += ' fi\n'
1179     txt += '\n'
1180 gutsche 1.7 txt += ' exit 1\n'
1181 gutsche 1.3 txt += ' fi\n'
1182     txt += '\n'
1183     txt += ' echo "SET_CMS_ENV 0 ==> setup cms environment ok"\n'
1184     txt += ' echo " END SETUP CMS OSG ENVIRONMENT "\n'
1185    
1186     return txt
1187    
1188     ### OLI_DANIELE
1189     def wsSetupCMSLCGEnvironment_(self):
1190     """
1191     Returns part of a job script which is prepares
1192     the execution environment and which is common for all CMS jobs.
1193     """
1194     txt = ' \n'
1195     txt += ' echo " ### SETUP CMS LCG ENVIRONMENT ### "\n'
1196     txt += ' if [ ! $VO_CMS_SW_DIR ] ;then\n'
1197     txt += ' echo "SET_CMS_ENV 10031 ==> ERROR CMS software dir not found on WN `hostname`"\n'
1198     txt += ' echo "JOB_EXIT_STATUS = 10031" \n'
1199     txt += ' echo "JobExitCode=10031" | tee -a $RUNTIME_AREA/$repo\n'
1200     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
1201 gutsche 1.13 txt += ' rm -f $RUNTIME_AREA/$repo \n'
1202     txt += ' echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1203     txt += ' echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1204 gutsche 1.7 txt += ' exit 1\n'
1205 gutsche 1.3 txt += ' else\n'
1206     txt += ' echo "Sourcing environment... "\n'
1207     txt += ' if [ ! -s $VO_CMS_SW_DIR/cmsset_default.sh ] ;then\n'
1208     txt += ' echo "SET_CMS_ENV 10020 ==> ERROR cmsset_default.sh file not found into dir $VO_CMS_SW_DIR"\n'
1209     txt += ' echo "JOB_EXIT_STATUS = 10020"\n'
1210     txt += ' echo "JobExitCode=10020" | tee -a $RUNTIME_AREA/$repo\n'
1211     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
1212 gutsche 1.13 txt += ' rm -f $RUNTIME_AREA/$repo \n'
1213     txt += ' echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1214     txt += ' echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1215 gutsche 1.7 txt += ' exit 1\n'
1216 gutsche 1.3 txt += ' fi\n'
1217     txt += ' echo "sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1218     txt += ' source $VO_CMS_SW_DIR/cmsset_default.sh\n'
1219     txt += ' result=$?\n'
1220     txt += ' if [ $result -ne 0 ]; then\n'
1221     txt += ' echo "SET_CMS_ENV 10032 ==> ERROR problem sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1222     txt += ' echo "JOB_EXIT_STATUS = 10032"\n'
1223     txt += ' echo "JobExitCode=10032" | tee -a $RUNTIME_AREA/$repo\n'
1224     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
1225 gutsche 1.13 txt += ' rm -f $RUNTIME_AREA/$repo \n'
1226     txt += ' echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1227     txt += ' echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1228 gutsche 1.7 txt += ' exit 1\n'
1229 gutsche 1.3 txt += ' fi\n'
1230     txt += ' fi\n'
1231     txt += ' \n'
1232     txt += ' echo "SET_CMS_ENV 0 ==> setup cms environment ok"\n'
1233     txt += ' echo "### END SETUP CMS LCG ENVIRONMENT ###"\n'
1234     return txt
1235 gutsche 1.5
1236     def setParam_(self, param, value):
1237     self._params[param] = value
1238    
1239     def getParams(self):
1240     return self._params
1241 gutsche 1.8
1242     def setTaskid_(self):
1243     self._taskId = self.cfg_params['taskId']
1244    
1245     def getTaskid(self):
1246     return self._taskId
1247 gutsche 1.35
1248     #######################################################################
1249     def uniquelist(self, old):
1250     """
1251     remove duplicates from a list
1252     """
1253     nd={}
1254     for e in old:
1255     nd[e]=0
1256     return nd.keys()