ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.56
Committed: Mon Dec 4 11:10:33 2006 UTC (18 years, 4 months ago) by corvo
Content type: text/x-python
Branch: MAIN
CVS Tags: CRAB_1_5_0_pre2
Changes since 1.55: +20 -11 lines
Log Message:
ML files added to the tgz

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