ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.206
Committed: Fri Jun 6 09:36:22 2008 UTC (16 years, 10 months ago) by slacapra
Content type: text/x-python
Branch: MAIN
Changes since 1.205: +20 -8 lines
Log Message:
improvement in dir walking to find data/ directory, thanks to Brian bbockelm@cse.unl.edu

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 fanzago 1.115 from BlackWhiteListParser import BlackWhiteListParser
6 slacapra 1.1 import common
7     import Scram
8 fanzago 1.173 from LFNBaseName import *
9 slacapra 1.1
10 slacapra 1.105 import os, string, glob
11 slacapra 1.1
12     class Cmssw(JobType):
13 mcinquil 1.144 def __init__(self, cfg_params, ncjobs):
14 slacapra 1.1 JobType.__init__(self, 'CMSSW')
15     common.logger.debug(3,'CMSSW::__init__')
16    
17 mcinquil 1.140 self.argsList = []
18 mcinquil 1.144
19 gutsche 1.3 self._params = {}
20     self.cfg_params = cfg_params
21 fanzago 1.115 # init BlackWhiteListParser
22     self.blackWhiteListParser = BlackWhiteListParser(cfg_params)
23    
24 slacapra 1.153 self.MaxTarBallSize = float(self.cfg_params.get('EDG.maxtarballsize',9.5))
25 gutsche 1.72
26 gutsche 1.44 # number of jobs requested to be created, limit obj splitting
27 gutsche 1.38 self.ncjobs = ncjobs
28    
29 slacapra 1.1 log = common.logger
30 ewv 1.131
31 slacapra 1.1 self.scram = Scram.Scram(cfg_params)
32     self.additional_inbox_files = []
33     self.scriptExe = ''
34     self.executable = ''
35 slacapra 1.71 self.executable_arch = self.scram.getArch()
36 slacapra 1.1 self.tgz_name = 'default.tgz'
37 corvo 1.56 self.scriptName = 'CMSSW.sh'
38 ewv 1.192 self.pset = ''
39 spiga 1.187 self.datasetPath = ''
40 gutsche 1.3
41 gutsche 1.50 # set FJR file name
42     self.fjrFileName = 'crab_fjr.xml'
43    
44 slacapra 1.1 self.version = self.scram.getSWVersion()
45 ewv 1.182 version_array = self.version.split('_')
46 ewv 1.184 self.CMSSW_major = 0
47     self.CMSSW_minor = 0
48     self.CMSSW_patch = 0
49 ewv 1.182 try:
50 ewv 1.184 self.CMSSW_major = int(version_array[1])
51     self.CMSSW_minor = int(version_array[2])
52     self.CMSSW_patch = int(version_array[3])
53 ewv 1.182 except:
54 ewv 1.184 msg = "Cannot parse CMSSW version string: " + self.version + " for major and minor release number!"
55 ewv 1.182 raise CrabException(msg)
56    
57 slacapra 1.1 ### collect Data cards
58 gutsche 1.66
59 slacapra 1.153 if not cfg_params.has_key('CMSSW.datasetpath'):
60 ewv 1.131 msg = "Error: datasetpath not defined "
61 slacapra 1.1 raise CrabException(msg)
62 slacapra 1.153 tmp = cfg_params['CMSSW.datasetpath']
63     log.debug(6, "CMSSW::CMSSW(): datasetPath = "+tmp)
64     if string.lower(tmp)=='none':
65     self.datasetPath = None
66     self.selectNoInput = 1
67     else:
68     self.datasetPath = tmp
69     self.selectNoInput = 0
70 gutsche 1.5
71 slacapra 1.1 self.dataTiers = []
72 spiga 1.197 self.debugWrap = ''
73     self.debug_wrapper = cfg_params.get('USER.debug_wrapper',False)
74     if self.debug_wrapper: self.debugWrap='--debug'
75 slacapra 1.1 ## now the application
76 slacapra 1.153 self.executable = cfg_params.get('CMSSW.executable','cmsRun')
77     log.debug(6, "CMSSW::CMSSW(): executable = "+self.executable)
78 slacapra 1.1
79 slacapra 1.153 if not cfg_params.has_key('CMSSW.pset'):
80 slacapra 1.1 raise CrabException("PSet file missing. Cannot run cmsRun ")
81 slacapra 1.153 self.pset = cfg_params['CMSSW.pset']
82     log.debug(6, "Cmssw::Cmssw(): PSet file = "+self.pset)
83     if self.pset.lower() != 'none' :
84     if (not os.path.exists(self.pset)):
85     raise CrabException("User defined PSet file "+self.pset+" does not exist")
86     else:
87     self.pset = None
88 slacapra 1.1
89     # output files
90 slacapra 1.53 ## stuff which must be returned always via sandbox
91     self.output_file_sandbox = []
92    
93     # add fjr report by default via sandbox
94     self.output_file_sandbox.append(self.fjrFileName)
95    
96     # other output files to be returned via sandbox or copied to SE
97 slacapra 1.153 self.output_file = []
98     tmp = cfg_params.get('CMSSW.output_file',None)
99     if tmp :
100     tmpOutFiles = string.split(tmp,',')
101     log.debug(7, 'cmssw::cmssw(): output files '+str(tmpOutFiles))
102     for tmp in tmpOutFiles:
103     tmp=string.strip(tmp)
104     self.output_file.append(tmp)
105 slacapra 1.1 pass
106 slacapra 1.153 else:
107 gutsche 1.92 log.message("No output file defined: only stdout/err and the CRAB Framework Job Report will be available\n")
108 slacapra 1.153 pass
109 slacapra 1.1
110     # script_exe file as additional file in inputSandbox
111 slacapra 1.153 self.scriptExe = cfg_params.get('USER.script_exe',None)
112     if self.scriptExe :
113 slacapra 1.176 if not os.path.isfile(self.scriptExe):
114     msg ="ERROR. file "+self.scriptExe+" not found"
115     raise CrabException(msg)
116     self.additional_inbox_files.append(string.strip(self.scriptExe))
117 slacapra 1.70
118 spiga 1.42 if self.datasetPath == None and self.pset == None and self.scriptExe == '' :
119 slacapra 1.176 msg ="Error. script_exe not defined"
120     raise CrabException(msg)
121 spiga 1.42
122 spiga 1.204 # use parent files...
123     self.useParent = self.cfg_params.get('CMSSW.use_parent',False)
124    
125 slacapra 1.1 ## additional input files
126 slacapra 1.153 if cfg_params.has_key('USER.additional_input_files'):
127 slacapra 1.29 tmpAddFiles = string.split(cfg_params['USER.additional_input_files'],',')
128 slacapra 1.70 for tmp in tmpAddFiles:
129     tmp = string.strip(tmp)
130     dirname = ''
131     if not tmp[0]=="/": dirname = "."
132 corvo 1.85 files = []
133     if string.find(tmp,"*")>-1:
134     files = glob.glob(os.path.join(dirname, tmp))
135     if len(files)==0:
136     raise CrabException("No additional input file found with this pattern: "+tmp)
137     else:
138     files.append(tmp)
139 slacapra 1.70 for file in files:
140     if not os.path.exists(file):
141     raise CrabException("Additional input file not found: "+file)
142 slacapra 1.45 pass
143 slacapra 1.105 self.additional_inbox_files.append(string.strip(file))
144 slacapra 1.1 pass
145     pass
146 slacapra 1.70 common.logger.debug(5,"Additional input files: "+str(self.additional_inbox_files))
147 slacapra 1.153 pass
148 gutsche 1.3
149 slacapra 1.9 ## Events per job
150 slacapra 1.153 if cfg_params.has_key('CMSSW.events_per_job'):
151 slacapra 1.10 self.eventsPerJob =int( cfg_params['CMSSW.events_per_job'])
152 slacapra 1.9 self.selectEventsPerJob = 1
153 slacapra 1.153 else:
154 slacapra 1.9 self.eventsPerJob = -1
155     self.selectEventsPerJob = 0
156 ewv 1.131
157 slacapra 1.22 ## number of jobs
158 slacapra 1.153 if cfg_params.has_key('CMSSW.number_of_jobs'):
159 slacapra 1.22 self.theNumberOfJobs =int( cfg_params['CMSSW.number_of_jobs'])
160     self.selectNumberOfJobs = 1
161 slacapra 1.153 else:
162 slacapra 1.22 self.theNumberOfJobs = 0
163     self.selectNumberOfJobs = 0
164 slacapra 1.10
165 slacapra 1.153 if cfg_params.has_key('CMSSW.total_number_of_events'):
166 gutsche 1.35 self.total_number_of_events = int(cfg_params['CMSSW.total_number_of_events'])
167     self.selectTotalNumberEvents = 1
168 spiga 1.193 if self.selectNumberOfJobs == 1:
169 spiga 1.202 if (self.total_number_of_events != -1) and int(self.total_number_of_events) < int(self.theNumberOfJobs):
170 spiga 1.193 msg = 'Must specify at least one event per job. total_number_of_events > number_of_jobs '
171     raise CrabException(msg)
172 slacapra 1.153 else:
173 gutsche 1.35 self.total_number_of_events = 0
174     self.selectTotalNumberEvents = 0
175    
176 spiga 1.187 if self.pset != None:
177 spiga 1.42 if ( (self.selectTotalNumberEvents + self.selectEventsPerJob + self.selectNumberOfJobs) != 2 ):
178     msg = 'Must define exactly two of total_number_of_events, events_per_job, or number_of_jobs.'
179     raise CrabException(msg)
180     else:
181     if (self.selectNumberOfJobs == 0):
182     msg = 'Must specify number_of_jobs.'
183     raise CrabException(msg)
184 gutsche 1.35
185 ewv 1.160 ## New method of dealing with seeds
186     self.incrementSeeds = []
187     self.preserveSeeds = []
188     if cfg_params.has_key('CMSSW.preserve_seeds'):
189     tmpList = cfg_params['CMSSW.preserve_seeds'].split(',')
190     for tmp in tmpList:
191     tmp.strip()
192     self.preserveSeeds.append(tmp)
193     if cfg_params.has_key('CMSSW.increment_seeds'):
194     tmpList = cfg_params['CMSSW.increment_seeds'].split(',')
195     for tmp in tmpList:
196     tmp.strip()
197     self.incrementSeeds.append(tmp)
198    
199     ## Old method of dealing with seeds
200     ## FUTURE: This is for old CMSSW and old CRAB. Can throw exceptions after a couple of CRAB releases and then
201     ## remove
202 slacapra 1.153 self.sourceSeed = cfg_params.get('CMSSW.pythia_seed',None)
203 ewv 1.160 if self.sourceSeed:
204 slacapra 1.177 print "pythia_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
205     self.incrementSeeds.append('sourceSeed')
206 ewv 1.185 self.incrementSeeds.append('theSource')
207 slacapra 1.153
208     self.sourceSeedVtx = cfg_params.get('CMSSW.vtx_seed',None)
209 ewv 1.160 if self.sourceSeedVtx:
210 slacapra 1.177 print "vtx_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
211     self.incrementSeeds.append('VtxSmeared')
212 slacapra 1.22
213 slacapra 1.153 self.sourceSeedG4 = cfg_params.get('CMSSW.g4_seed',None)
214 ewv 1.160 if self.sourceSeedG4:
215 slacapra 1.177 print "g4_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
216     self.incrementSeeds.append('g4SimHits')
217 slacapra 1.90
218 slacapra 1.153 self.sourceSeedMix = cfg_params.get('CMSSW.mix_seed',None)
219 ewv 1.160 if self.sourceSeedMix:
220 slacapra 1.177 print "mix_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
221     self.incrementSeeds.append('mix')
222 slacapra 1.90
223 slacapra 1.153 self.firstRun = cfg_params.get('CMSSW.first_run',None)
224 slacapra 1.90
225 spiga 1.42 if self.pset != None: #CarlosDaniele
226 ewv 1.131 import PsetManipulator as pp
227 slacapra 1.97 PsetEdit = pp.PsetManipulator(self.pset) #Daniele Pset
228 gutsche 1.3
229 ewv 1.147 # Copy/return
230    
231 slacapra 1.153 self.copy_data = int(cfg_params.get('USER.copy_data',0))
232     self.return_data = int(cfg_params.get('USER.return_data',0))
233 ewv 1.147
234 slacapra 1.1 #DBSDLS-start
235 ewv 1.131 ## Initialize the variables that are extracted from DBS/DLS and needed in other places of the code
236 slacapra 1.1 self.maxEvents=0 # max events available ( --> check the requested nb. of evts in Creator.py)
237     self.DBSPaths={} # all dbs paths requested ( --> input to the site local discovery script)
238 gutsche 1.35 self.jobDestination=[] # Site destination(s) for each job (list of lists)
239 slacapra 1.1 ## Perform the data location and discovery (based on DBS/DLS)
240 slacapra 1.9 ## SL: Don't if NONE is specified as input (pythia use case)
241 gutsche 1.35 blockSites = {}
242 slacapra 1.9 if self.datasetPath:
243 gutsche 1.35 blockSites = self.DataDiscoveryAndLocation(cfg_params)
244 ewv 1.131 #DBSDLS-end
245 slacapra 1.1
246 ewv 1.131
247 slacapra 1.9 ## Select Splitting
248 ewv 1.131 if self.selectNoInput:
249 spiga 1.187 if self.pset == None:
250 spiga 1.42 self.jobSplittingForScript()
251     else:
252     self.jobSplittingNoInput()
253 gutsche 1.92 else:
254 corvo 1.56 self.jobSplittingByBlocks(blockSites)
255 gutsche 1.5
256 slacapra 1.22 # modify Pset
257 ewv 1.192 if self.pset != None:
258 slacapra 1.86 try:
259 ewv 1.160 # Add FrameworkJobReport to parameter-set, set max events.
260     # Reset later for data jobs by writeCFG which does all modifications
261 ewv 1.182 PsetEdit.addCrabFJR(self.fjrFileName) # FUTURE: Job report addition not needed by CMSSW>1.5
262 ewv 1.160 PsetEdit.maxEvent(self.eventsPerJob)
263 slacapra 1.90 PsetEdit.psetWriter(self.configFilename())
264 slacapra 1.86 except:
265 ewv 1.184 msg='Error while manipulating ParameterSet: exiting...'
266 slacapra 1.86 raise CrabException(msg)
267 spiga 1.179 self.tgzNameWithPath = self.getTarBall(self.executable)
268 gutsche 1.3
269 slacapra 1.1 def DataDiscoveryAndLocation(self, cfg_params):
270    
271 slacapra 1.86 import DataDiscovery
272     import DataLocation
273 gutsche 1.3 common.logger.debug(10,"CMSSW::DataDiscoveryAndLocation()")
274    
275     datasetPath=self.datasetPath
276    
277 slacapra 1.1 ## Contact the DBS
278 gutsche 1.92 common.logger.message("Contacting Data Discovery Services ...")
279 slacapra 1.1 try:
280 slacapra 1.137 self.pubdata=DataDiscovery.DataDiscovery(datasetPath, cfg_params)
281 slacapra 1.1 self.pubdata.fetchDBSInfo()
282    
283 slacapra 1.41 except DataDiscovery.NotExistingDatasetError, ex :
284 slacapra 1.1 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
285     raise CrabException(msg)
286 slacapra 1.41 except DataDiscovery.NoDataTierinProvenanceError, ex :
287 slacapra 1.1 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
288     raise CrabException(msg)
289 slacapra 1.41 except DataDiscovery.DataDiscoveryError, ex:
290 gutsche 1.66 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
291 slacapra 1.1 raise CrabException(msg)
292    
293 gutsche 1.35 self.filesbyblock=self.pubdata.getFiles()
294 mkirn 1.37 self.eventsbyblock=self.pubdata.getEventsPerBlock()
295     self.eventsbyfile=self.pubdata.getEventsPerFile()
296 spiga 1.204 self.parentFiles=self.pubdata.getParent()
297 gutsche 1.3
298 slacapra 1.1 ## get max number of events
299 ewv 1.192 self.maxEvents=self.pubdata.getMaxEvents()
300 slacapra 1.1
301     ## Contact the DLS and build a list of sites hosting the fileblocks
302     try:
303 slacapra 1.41 dataloc=DataLocation.DataLocation(self.filesbyblock.keys(),cfg_params)
304 gutsche 1.6 dataloc.fetchDLSInfo()
305 slacapra 1.41 except DataLocation.DataLocationError , ex:
306 slacapra 1.1 msg = 'ERROR ***: failed Data Location in DLS \n %s '%ex.getErrorMessage()
307     raise CrabException(msg)
308 ewv 1.131
309 slacapra 1.1
310 gutsche 1.35 sites = dataloc.getSites()
311     allSites = []
312     listSites = sites.values()
313 slacapra 1.63 for listSite in listSites:
314     for oneSite in listSite:
315 gutsche 1.35 allSites.append(oneSite)
316     allSites = self.uniquelist(allSites)
317 gutsche 1.3
318 gutsche 1.92 # screen output
319     common.logger.message("Requested dataset: " + datasetPath + " has " + str(self.maxEvents) + " events in " + str(len(self.filesbyblock.keys())) + " blocks.\n")
320    
321 gutsche 1.35 return sites
322 ewv 1.131
323 gutsche 1.35 def jobSplittingByBlocks(self, blockSites):
324 slacapra 1.9 """
325 gutsche 1.35 Perform job splitting. Jobs run over an integer number of files
326     and no more than one block.
327     ARGUMENT: blockSites: dictionary with blocks as keys and list of host sites as values
328     REQUIRES: self.selectTotalNumberEvents, self.selectEventsPerJob, self.selectNumberofJobs,
329     self.total_number_of_events, self.eventsPerJob, self.theNumberOfJobs,
330     self.maxEvents, self.filesbyblock
331     SETS: self.jobDestination - Site destination(s) for each job (a list of lists)
332     self.total_number_of_jobs - Total # of jobs
333     self.list_of_args - File(s) job will run on (a list of lists)
334     """
335    
336     # ---- Handle the possible job splitting configurations ---- #
337     if (self.selectTotalNumberEvents):
338     totalEventsRequested = self.total_number_of_events
339     if (self.selectEventsPerJob):
340     eventsPerJobRequested = self.eventsPerJob
341     if (self.selectNumberOfJobs):
342     totalEventsRequested = self.theNumberOfJobs * self.eventsPerJob
343    
344     # If user requested all the events in the dataset
345     if (totalEventsRequested == -1):
346     eventsRemaining=self.maxEvents
347     # If user requested more events than are in the dataset
348     elif (totalEventsRequested > self.maxEvents):
349     eventsRemaining = self.maxEvents
350     common.logger.message("Requested "+str(self.total_number_of_events)+ " events, but only "+str(self.maxEvents)+" events are available.")
351     # If user requested less events than are in the dataset
352     else:
353     eventsRemaining = totalEventsRequested
354 slacapra 1.22
355 slacapra 1.41 # If user requested more events per job than are in the dataset
356     if (self.selectEventsPerJob and eventsPerJobRequested > self.maxEvents):
357     eventsPerJobRequested = self.maxEvents
358    
359 gutsche 1.35 # For user info at end
360     totalEventCount = 0
361 gutsche 1.3
362 gutsche 1.35 if (self.selectTotalNumberEvents and self.selectNumberOfJobs):
363     eventsPerJobRequested = int(eventsRemaining/self.theNumberOfJobs)
364 slacapra 1.22
365 gutsche 1.35 if (self.selectNumberOfJobs):
366     common.logger.message("May not create the exact number_of_jobs requested.")
367 slacapra 1.23
368 gutsche 1.38 if ( self.ncjobs == 'all' ) :
369     totalNumberOfJobs = 999999999
370     else :
371     totalNumberOfJobs = self.ncjobs
372 ewv 1.131
373 gutsche 1.35 blocks = blockSites.keys()
374     blockCount = 0
375     # Backup variable in case self.maxEvents counted events in a non-included block
376     numBlocksInDataset = len(blocks)
377 gutsche 1.3
378 gutsche 1.35 jobCount = 0
379     list_of_lists = []
380 gutsche 1.3
381 gutsche 1.92 # list tracking which jobs are in which jobs belong to which block
382     jobsOfBlock = {}
383    
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 gutsche 1.104 if block not in jobsOfBlock.keys() :
390     jobsOfBlock[block] = []
391 ewv 1.131
392 gutsche 1.68 if self.eventsbyblock.has_key(block) :
393     numEventsInBlock = self.eventsbyblock[block]
394     common.logger.debug(5,'Events in Block File '+str(numEventsInBlock))
395 ewv 1.131
396 gutsche 1.68 files = self.filesbyblock[block]
397     numFilesInBlock = len(files)
398     if (numFilesInBlock <= 0):
399     continue
400     fileCount = 0
401    
402     # ---- New block => New job ---- #
403 ewv 1.131 parString = ""
404 gutsche 1.68 # counter for number of events in files currently worked on
405     filesEventCount = 0
406     # flag if next while loop should touch new file
407     newFile = 1
408     # job event counter
409     jobSkipEventCount = 0
410 ewv 1.131
411 gutsche 1.68 # ---- Iterate over the files in the block until we've met the requested ---- #
412     # ---- total # of events or we've gone over all the files in this block ---- #
413 spiga 1.204 pString=''
414 gutsche 1.68 while ( (eventsRemaining > 0) and (fileCount < numFilesInBlock) and (jobCount < totalNumberOfJobs) ):
415     file = files[fileCount]
416 spiga 1.204 if self.useParent:
417     parent = self.parentFiles[file]
418     for f in parent :
419     pString += '\\\"' + f + '\\\"\,'
420     common.logger.debug(6, "File "+str(file)+" has the following parents: "+str(parent))
421     common.logger.write("File "+str(file)+" has the following parents: "+str(parent))
422 gutsche 1.68 if newFile :
423     try:
424     numEventsInFile = self.eventsbyfile[file]
425     common.logger.debug(6, "File "+str(file)+" has "+str(numEventsInFile)+" events")
426     # increase filesEventCount
427     filesEventCount += numEventsInFile
428     # Add file to current job
429     parString += '\\\"' + file + '\\\"\,'
430     newFile = 0
431     except KeyError:
432     common.logger.message("File "+str(file)+" has unknown number of events: skipping")
433 ewv 1.131
434 slacapra 1.177 eventsPerJobRequested = min(eventsPerJobRequested, eventsRemaining)
435 gutsche 1.68 # if less events in file remain than eventsPerJobRequested
436 slacapra 1.177 if ( filesEventCount - jobSkipEventCount < eventsPerJobRequested):
437 gutsche 1.68 # if last file in block
438     if ( fileCount == numFilesInBlock-1 ) :
439     # end job using last file, use remaining events in block
440     # close job and touch new file
441     fullString = parString[:-2]
442 spiga 1.204 if self.useParent:
443     fullParentString = pString[:-2]
444     list_of_lists.append([fullString,fullParentString,str(-1),str(jobSkipEventCount)])
445     else:
446     list_of_lists.append([fullString,str(-1),str(jobSkipEventCount)])
447 gutsche 1.68 common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(filesEventCount - jobSkipEventCount)+" events (last file in block).")
448     self.jobDestination.append(blockSites[block])
449     common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
450 gutsche 1.92 # fill jobs of block dictionary
451 gutsche 1.104 jobsOfBlock[block].append(jobCount+1)
452 gutsche 1.68 # reset counter
453     jobCount = jobCount + 1
454     totalEventCount = totalEventCount + filesEventCount - jobSkipEventCount
455     eventsRemaining = eventsRemaining - filesEventCount + jobSkipEventCount
456     jobSkipEventCount = 0
457     # reset file
458 spiga 1.204 pString = ""
459 ewv 1.131 parString = ""
460 gutsche 1.68 filesEventCount = 0
461     newFile = 1
462     fileCount += 1
463     else :
464     # go to next file
465     newFile = 1
466     fileCount += 1
467     # if events in file equal to eventsPerJobRequested
468     elif ( filesEventCount - jobSkipEventCount == eventsPerJobRequested ) :
469 gutsche 1.38 # close job and touch new file
470     fullString = parString[:-2]
471 spiga 1.204 if self.useParent:
472     fullParentString = pString[:-2]
473     list_of_lists.append([fullString,fullParentString,str(eventsPerJobRequested),str(jobSkipEventCount)])
474     else:
475     list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
476 gutsche 1.68 common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(eventsPerJobRequested)+" events.")
477 gutsche 1.38 self.jobDestination.append(blockSites[block])
478     common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
479 gutsche 1.104 jobsOfBlock[block].append(jobCount+1)
480 gutsche 1.38 # reset counter
481     jobCount = jobCount + 1
482 gutsche 1.68 totalEventCount = totalEventCount + eventsPerJobRequested
483     eventsRemaining = eventsRemaining - eventsPerJobRequested
484 gutsche 1.38 jobSkipEventCount = 0
485     # reset file
486 spiga 1.204 pString = ""
487 ewv 1.131 parString = ""
488 gutsche 1.38 filesEventCount = 0
489     newFile = 1
490     fileCount += 1
491 ewv 1.131
492 gutsche 1.68 # if more events in file remain than eventsPerJobRequested
493 gutsche 1.38 else :
494 gutsche 1.68 # close job but don't touch new file
495     fullString = parString[:-2]
496 spiga 1.204 if self.useParent:
497     fullParentString = pString[:-2]
498     list_of_lists.append([fullString,fullParentString,str(eventsPerJobRequested),str(jobSkipEventCount)])
499     else:
500     list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
501 gutsche 1.68 common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(eventsPerJobRequested)+" events.")
502     self.jobDestination.append(blockSites[block])
503     common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
504 gutsche 1.104 jobsOfBlock[block].append(jobCount+1)
505 gutsche 1.68 # increase counter
506     jobCount = jobCount + 1
507     totalEventCount = totalEventCount + eventsPerJobRequested
508     eventsRemaining = eventsRemaining - eventsPerJobRequested
509     # calculate skip events for last file
510     # use filesEventCount (contains several files), jobSkipEventCount and eventsPerJobRequest
511     jobSkipEventCount = eventsPerJobRequested - (filesEventCount - jobSkipEventCount - self.eventsbyfile[file])
512     # remove all but the last file
513     filesEventCount = self.eventsbyfile[file]
514 spiga 1.204 if self.useParent:
515     for f in parent : pString += '\\\"' + f + '\\\"\,'
516 ewv 1.160 parString = '\\\"' + file + '\\\"\,'
517 gutsche 1.68 pass # END if
518     pass # END while (iterate over files in the block)
519 gutsche 1.35 pass # END while (iterate over blocks in the dataset)
520 slacapra 1.41 self.ncjobs = self.total_number_of_jobs = jobCount
521 gutsche 1.38 if (eventsRemaining > 0 and jobCount < totalNumberOfJobs ):
522 gutsche 1.35 common.logger.message("Could not run on all requested events because some blocks not hosted at allowed sites.")
523 gutsche 1.92 common.logger.message(str(jobCount)+" job(s) can run on "+str(totalEventCount)+" events.\n")
524 ewv 1.131
525 gutsche 1.92 # screen output
526     screenOutput = "List of jobs and available destination sites:\n\n"
527    
528 mcinquil 1.124 # keep trace of block with no sites to print a warning at the end
529     noSiteBlock = []
530     bloskNoSite = []
531    
532 gutsche 1.92 blockCounter = 0
533 gutsche 1.104 for block in blocks:
534     if block in jobsOfBlock.keys() :
535     blockCounter += 1
536 slacapra 1.176 screenOutput += "Block %5i: jobs %20s: sites: %s\n" % (blockCounter,spanRanges(jobsOfBlock[block]),
537     ','.join(self.blackWhiteListParser.checkWhiteList(self.blackWhiteListParser.checkBlackList(blockSites[block],block),block)))
538 mcinquil 1.124 if len(self.blackWhiteListParser.checkWhiteList(self.blackWhiteListParser.checkBlackList(blockSites[block],block),block)) == 0:
539 ewv 1.131 noSiteBlock.append( spanRanges(jobsOfBlock[block]) )
540 mcinquil 1.124 bloskNoSite.append( blockCounter )
541 ewv 1.131
542 mcinquil 1.124 common.logger.message(screenOutput)
543 fanzago 1.127 if len(noSiteBlock) > 0 and len(bloskNoSite) > 0:
544 mcinquil 1.126 msg = 'WARNING: No sites are hosting any part of data for block:\n '
545     virgola = ""
546     if len(bloskNoSite) > 1:
547     virgola = ","
548     for block in bloskNoSite:
549     msg += ' ' + str(block) + virgola
550     msg += '\n Related jobs:\n '
551     virgola = ""
552     if len(noSiteBlock) > 1:
553     virgola = ","
554     for range_jobs in noSiteBlock:
555     msg += str(range_jobs) + virgola
556     msg += '\n will not be submitted and this block of data can not be analyzed!\n'
557 slacapra 1.155 if self.cfg_params.has_key('EDG.se_white_list'):
558     msg += 'WARNING: SE White List: '+self.cfg_params['EDG.se_white_list']+'\n'
559     msg += '(Hint: By whitelisting you force the job to run at this particular site(s).\n'
560     msg += 'Please check if the dataset is available at this site!)\n'
561     if self.cfg_params.has_key('EDG.ce_white_list'):
562     msg += 'WARNING: CE White List: '+self.cfg_params['EDG.ce_white_list']+'\n'
563     msg += '(Hint: By whitelisting you force the job to run at this particular site(s).\n'
564     msg += 'Please check if the dataset is available at this site!)\n'
565    
566 mcinquil 1.126 common.logger.message(msg)
567 gutsche 1.92
568 slacapra 1.9 self.list_of_args = list_of_lists
569     return
570    
571 slacapra 1.21 def jobSplittingNoInput(self):
572 slacapra 1.9 """
573     Perform job splitting based on number of event per job
574     """
575     common.logger.debug(5,'Splitting per events')
576 fanzago 1.130
577 ewv 1.131 if (self.selectEventsPerJob):
578 fanzago 1.130 common.logger.message('Required '+str(self.eventsPerJob)+' events per job ')
579     if (self.selectNumberOfJobs):
580     common.logger.message('Required '+str(self.theNumberOfJobs)+' jobs in total ')
581     if (self.selectTotalNumberEvents):
582     common.logger.message('Required '+str(self.total_number_of_events)+' events in total ')
583 slacapra 1.9
584 slacapra 1.10 if (self.total_number_of_events < 0):
585     msg='Cannot split jobs per Events with "-1" as total number of events'
586     raise CrabException(msg)
587    
588 slacapra 1.22 if (self.selectEventsPerJob):
589 spiga 1.65 if (self.selectTotalNumberEvents):
590     self.total_number_of_jobs = int(self.total_number_of_events/self.eventsPerJob)
591 ewv 1.131 elif(self.selectNumberOfJobs) :
592 spiga 1.65 self.total_number_of_jobs =self.theNumberOfJobs
593 ewv 1.131 self.total_number_of_events =int(self.theNumberOfJobs*self.eventsPerJob)
594 spiga 1.65
595 slacapra 1.22 elif (self.selectNumberOfJobs) :
596     self.total_number_of_jobs = self.theNumberOfJobs
597     self.eventsPerJob = int(self.total_number_of_events/self.total_number_of_jobs)
598 ewv 1.131
599 slacapra 1.9 common.logger.debug(5,'N jobs '+str(self.total_number_of_jobs))
600    
601     # is there any remainder?
602     check = int(self.total_number_of_events) - (int(self.total_number_of_jobs)*self.eventsPerJob)
603    
604     common.logger.debug(5,'Check '+str(check))
605    
606 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')
607 slacapra 1.9 if check > 0:
608 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))
609 slacapra 1.9
610 slacapra 1.10 # argument is seed number.$i
611 slacapra 1.9 self.list_of_args = []
612     for i in range(self.total_number_of_jobs):
613 gutsche 1.35 ## Since there is no input, any site is good
614 ewv 1.131 self.jobDestination.append([""]) #must be empty to write correctly the xml
615 slacapra 1.90 args=[]
616 spiga 1.57 if (self.firstRun):
617 slacapra 1.138 ## pythia first run
618 slacapra 1.90 args.append(str(self.firstRun)+str(i))
619     self.list_of_args.append(args)
620 ewv 1.131
621 gutsche 1.3 return
622    
623 spiga 1.42
624 spiga 1.187 def jobSplittingForScript(self):
625 spiga 1.42 """
626     Perform job splitting based on number of job
627     """
628     common.logger.debug(5,'Splitting per job')
629     common.logger.message('Required '+str(self.theNumberOfJobs)+' jobs in total ')
630    
631     self.total_number_of_jobs = self.theNumberOfJobs
632    
633     common.logger.debug(5,'N jobs '+str(self.total_number_of_jobs))
634    
635     common.logger.message(str(self.total_number_of_jobs)+' jobs can be created')
636    
637     # argument is seed number.$i
638     self.list_of_args = []
639     for i in range(self.total_number_of_jobs):
640     self.jobDestination.append([""])
641     self.list_of_args.append([str(i)])
642     return
643    
644 gutsche 1.3 def split(self, jobParams):
645 ewv 1.131
646 gutsche 1.3 njobs = self.total_number_of_jobs
647 slacapra 1.9 arglist = self.list_of_args
648 gutsche 1.3 # create the empty structure
649     for i in range(njobs):
650     jobParams.append("")
651 ewv 1.131
652 spiga 1.165 listID=[]
653     listField=[]
654 gutsche 1.3 for job in range(njobs):
655 slacapra 1.17 jobParams[job] = arglist[job]
656 spiga 1.167 listID.append(job+1)
657 spiga 1.162 job_ToSave ={}
658 spiga 1.169 concString = ' '
659 spiga 1.165 argu=''
660     if len(jobParams[job]):
661     argu += concString.join(jobParams[job] )
662 spiga 1.187 job_ToSave['arguments']= str(job+1)+' '+argu
663     job_ToSave['dlsDestination']= self.jobDestination[job]
664 spiga 1.165 listField.append(job_ToSave)
665 spiga 1.169 msg="Job "+str(job)+" Arguments: "+str(job+1)+" "+argu+"\n" \
666 spiga 1.165 +" Destination: "+str(self.jobDestination[job])
667     common.logger.debug(5,msg)
668 spiga 1.187 common._db.updateJob_(listID,listField)
669 spiga 1.181 self.argsList = (len(jobParams[0])+1)
670 gutsche 1.3
671     return
672 ewv 1.131
673 gutsche 1.3 def numberOfJobs(self):
674     return self.total_number_of_jobs
675    
676 slacapra 1.1 def getTarBall(self, exe):
677     """
678     Return the TarBall with lib and exe
679     """
680 corvo 1.56 self.tgzNameWithPath = common.work_space.pathForTgz()+'share/'+self.tgz_name
681 slacapra 1.1 if os.path.exists(self.tgzNameWithPath):
682     return self.tgzNameWithPath
683    
684     # Prepare a tar gzipped file with user binaries.
685     self.buildTar_(exe)
686    
687     return string.strip(self.tgzNameWithPath)
688    
689     def buildTar_(self, executable):
690    
691     # First of all declare the user Scram area
692     swArea = self.scram.getSWArea_()
693     swReleaseTop = self.scram.getReleaseTop_()
694 ewv 1.131
695 slacapra 1.1 ## check if working area is release top
696     if swReleaseTop == '' or swArea == swReleaseTop:
697 afanfani 1.172 common.logger.debug(3,"swArea = "+swArea+" swReleaseTop ="+swReleaseTop)
698 slacapra 1.1 return
699    
700 slacapra 1.61 import tarfile
701     try: # create tar ball
702     tar = tarfile.open(self.tgzNameWithPath, "w:gz")
703     ## First find the executable
704 slacapra 1.86 if (self.executable != ''):
705 slacapra 1.61 exeWithPath = self.scram.findFile_(executable)
706     if ( not exeWithPath ):
707     raise CrabException('User executable '+executable+' not found')
708 ewv 1.131
709 slacapra 1.61 ## then check if it's private or not
710     if exeWithPath.find(swReleaseTop) == -1:
711     # the exe is private, so we must ship
712     common.logger.debug(5,"Exe "+exeWithPath+" to be tarred")
713     path = swArea+'/'
714 corvo 1.85 # distinguish case when script is in user project area or given by full path somewhere else
715     if exeWithPath.find(path) >= 0 :
716     exe = string.replace(exeWithPath, path,'')
717 slacapra 1.129 tar.add(path+exe,exe)
718 corvo 1.85 else :
719     tar.add(exeWithPath,os.path.basename(executable))
720 slacapra 1.61 pass
721     else:
722     # the exe is from release, we'll find it on WN
723     pass
724 ewv 1.131
725 slacapra 1.61 ## Now get the libraries: only those in local working area
726     libDir = 'lib'
727     lib = swArea+'/' +libDir
728     common.logger.debug(5,"lib "+lib+" to be tarred")
729     if os.path.exists(lib):
730     tar.add(lib,libDir)
731 ewv 1.131
732 slacapra 1.61 ## Now check if module dir is present
733     moduleDir = 'module'
734     module = swArea + '/' + moduleDir
735     if os.path.isdir(module):
736     tar.add(module,moduleDir)
737    
738     ## Now check if any data dir(s) is present
739 spiga 1.179 self.dataExist = False
740 slacapra 1.206 #print "Starting walk."
741     #timer = -time.time()
742     todo_list = [(os.path.join(swArea, i), i) for i in os.listdir(swArea)]
743     while len(todo_list):
744     entry, name = todo_list.pop()
745     if name.startswith('crab_0_') or name.startswith('.'):
746     continue
747     if os.path.isdir(entry):
748     entryPath = entry + '/'
749     todo_list += [(entryPath + i, i) for i in os.listdir(entry)]
750     if name == 'data':
751     self.dataExist=True
752     common.logger.debug(5,"data "+entry+" to be tarred")
753     tar.add(entry, swArea)
754     pass
755     pass
756     #timer += time.time()
757     #print "Finished walk.", timer
758 ewv 1.182
759 spiga 1.179 ### CMSSW ParameterSet
760     if not self.pset is None:
761     cfg_file = common.work_space.jobDir()+self.configFilename()
762 ewv 1.182 tar.add(cfg_file,self.configFilename())
763 spiga 1.179 common.logger.debug(5,"File added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
764 slacapra 1.61
765 fanzago 1.93
766 fanzago 1.152 ## Add ProdCommon dir to tar
767 fanzago 1.93 prodcommonDir = 'ProdCommon'
768 slacapra 1.205 prodcommonPath = os.environ['CRABDIR'] + '/' + 'external/'
769 fanzago 1.93 if os.path.isdir(prodcommonPath):
770     tar.add(prodcommonPath,prodcommonDir)
771 spiga 1.179 common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
772    
773     ##### ML stuff
774     ML_file_list=['report.py', 'DashboardAPI.py', 'Logger.py', 'ProcInfo.py', 'apmon.py']
775     path=os.environ['CRABDIR'] + '/python/'
776     for file in ML_file_list:
777     tar.add(path+file,file)
778     common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
779    
780     ##### Utils
781 spiga 1.203 Utils_file_list=['parseCrabFjr.py','writeCfg.py', 'fillCrabFjr.py']
782 spiga 1.179 for file in Utils_file_list:
783     tar.add(path+file,file)
784     common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
785 ewv 1.131
786 ewv 1.182 ##### AdditionalFiles
787 spiga 1.179 for file in self.additional_inbox_files:
788     tar.add(file,string.split(file,'/')[-1])
789 slacapra 1.61 common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
790 ewv 1.182
791 slacapra 1.61 tar.close()
792 slacapra 1.206 except TarError:
793     raise CrabException('Could not create tar-ball '+self.tgzNameWithPath)
794 gutsche 1.72
795     ## check for tarball size
796     tarballinfo = os.stat(self.tgzNameWithPath)
797     if ( tarballinfo.st_size > self.MaxTarBallSize*1024*1024 ) :
798     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.')
799    
800 slacapra 1.61 ## create tar-ball with ML stuff
801 slacapra 1.97
802 spiga 1.165 def wsSetupEnvironment(self, nj=0):
803 slacapra 1.1 """
804     Returns part of a job script which prepares
805     the execution environment for the job 'nj'.
806     """
807 ewv 1.184 if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
808     psetName = 'pset.py'
809     else:
810     psetName = 'pset.cfg'
811 slacapra 1.1 # Prepare JobType-independent part
812 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupEnvironment\n'
813 fanzago 1.133 txt += 'echo ">>> setup environment"\n'
814 ewv 1.131 txt += 'if [ $middleware == LCG ]; then \n'
815 gutsche 1.3 txt += self.wsSetupCMSLCGEnvironment_()
816     txt += 'elif [ $middleware == OSG ]; then\n'
817 gutsche 1.43 txt += ' WORKING_DIR=`/bin/mktemp -d $OSG_WN_TMP/cms_XXXXXXXXXXXX`\n'
818 ewv 1.132 txt += ' if [ ! $? == 0 ] ;then\n'
819 fanzago 1.161 txt += ' echo "ERROR ==> OSG $WORKING_DIR could not be created on WN `hostname`"\n'
820     txt += ' job_exit_code=10016\n'
821     txt += ' func_exit\n'
822 gutsche 1.3 txt += ' fi\n'
823 fanzago 1.133 txt += ' echo ">>> Created working directory: $WORKING_DIR"\n'
824 gutsche 1.3 txt += '\n'
825     txt += ' echo "Change to working directory: $WORKING_DIR"\n'
826     txt += ' cd $WORKING_DIR\n'
827 fanzago 1.133 txt += ' echo ">>> current directory (WORKING_DIR): $WORKING_DIR"\n'
828 ewv 1.131 txt += self.wsSetupCMSOSGEnvironment_()
829 gutsche 1.3 txt += 'fi\n'
830 slacapra 1.1
831     # Prepare JobType-specific part
832     scram = self.scram.commandName()
833     txt += '\n\n'
834 fanzago 1.133 txt += 'echo ">>> specific cmssw setup environment:"\n'
835     txt += 'echo "CMSSW_VERSION = '+self.version+'"\n'
836 slacapra 1.1 txt += scram+' project CMSSW '+self.version+'\n'
837     txt += 'status=$?\n'
838     txt += 'if [ $status != 0 ] ; then\n'
839 fanzago 1.161 txt += ' echo "ERROR ==> CMSSW '+self.version+' not found on `hostname`" \n'
840     txt += ' job_exit_code=10034\n'
841 fanzago 1.163 txt += ' func_exit\n'
842 slacapra 1.1 txt += 'fi \n'
843     txt += 'cd '+self.version+'\n'
844 fanzago 1.99 txt += 'SOFTWARE_DIR=`pwd`\n'
845 fanzago 1.133 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
846 slacapra 1.1 txt += 'eval `'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME`\n'
847 fanzago 1.180 txt += 'if [ $? != 0 ] ; then\n'
848     txt += ' echo "ERROR ==> Problem with the command: "\n'
849     txt += ' echo "eval \`'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME \` at `hostname`"\n'
850     txt += ' job_exit_code=10034\n'
851     txt += ' func_exit\n'
852     txt += 'fi \n'
853 slacapra 1.1 # Handle the arguments:
854     txt += "\n"
855 gutsche 1.7 txt += "## number of arguments (first argument always jobnumber)\n"
856 slacapra 1.1 txt += "\n"
857 spiga 1.165 txt += "if [ $nargs -lt "+str(self.argsList)+" ]\n"
858 slacapra 1.1 txt += "then\n"
859 fanzago 1.161 txt += " echo 'ERROR ==> Too few arguments' +$nargs+ \n"
860     txt += ' job_exit_code=50113\n'
861     txt += " func_exit\n"
862 slacapra 1.1 txt += "fi\n"
863     txt += "\n"
864    
865     # Prepare job-specific part
866     job = common.job_list[nj]
867 ewv 1.131 if (self.datasetPath):
868 fanzago 1.93 txt += '\n'
869     txt += 'DatasetPath='+self.datasetPath+'\n'
870    
871     datasetpath_split = self.datasetPath.split("/")
872 ewv 1.131
873 fanzago 1.93 txt += 'PrimaryDataset='+datasetpath_split[1]+'\n'
874     txt += 'DataTier='+datasetpath_split[2]+'\n'
875 fanzago 1.96 txt += 'ApplicationFamily=cmsRun\n'
876 fanzago 1.93
877     else:
878     txt += 'DatasetPath=MCDataTier\n'
879     txt += 'PrimaryDataset=null\n'
880     txt += 'DataTier=null\n'
881     txt += 'ApplicationFamily=MCDataTier\n'
882 ewv 1.170 if self.pset != None:
883 spiga 1.42 pset = os.path.basename(job.configFilename())
884     txt += '\n'
885 spiga 1.95 txt += 'cp $RUNTIME_AREA/'+pset+' .\n'
886 spiga 1.42 if (self.datasetPath): # standard job
887 ewv 1.160 txt += 'InputFiles=${args[1]}; export InputFiles\n'
888 spiga 1.204 if (self.useParent):
889     txt += 'ParentFiles=${args[2]}; export ParentFiles\n'
890     txt += 'MaxEvents=${args[3]}; export MaxEvents\n'
891     txt += 'SkipEvents=${args[4]}; export SkipEvents\n'
892     else:
893     txt += 'MaxEvents=${args[2]}; export MaxEvents\n'
894     txt += 'SkipEvents=${args[3]}; export SkipEvents\n'
895 spiga 1.42 txt += 'echo "Inputfiles:<$InputFiles>"\n'
896 spiga 1.204 if (self.useParent): txt += 'echo "ParentFiles:<$ParentFiles>"\n'
897 spiga 1.42 txt += 'echo "MaxEvents:<$MaxEvents>"\n'
898     txt += 'echo "SkipEvents:<$SkipEvents>"\n'
899     else: # pythia like job
900 ewv 1.160 txt += 'PreserveSeeds=' + ','.join(self.preserveSeeds) + '; export PreserveSeeds\n'
901     txt += 'IncrementSeeds=' + ','.join(self.incrementSeeds) + '; export IncrementSeeds\n'
902     txt += 'echo "PreserveSeeds: <$PreserveSeeds>"\n'
903     txt += 'echo "IncrementSeeds:<$IncrementSeeds>"\n'
904 slacapra 1.90 if (self.firstRun):
905 ewv 1.160 txt += 'FirstRun=${args[1]}; export FirstRun\n'
906 spiga 1.57 txt += 'echo "FirstRun: <$FirstRun>"\n'
907 slacapra 1.90
908 ewv 1.184 txt += 'mv -f ' + pset + ' ' + psetName + '\n'
909 slacapra 1.1
910    
911 fanzago 1.163 if self.pset != None:
912 ewv 1.184 # FUTURE: Can simply for 2_1_x and higher
913 spiga 1.42 txt += '\n'
914 spiga 1.197 if self.debug_wrapper==True:
915 spiga 1.188 txt += 'echo "***** cat ' + psetName + ' *********"\n'
916     txt += 'cat ' + psetName + '\n'
917     txt += 'echo "****** end ' + psetName + ' ********"\n'
918     txt += '\n'
919 ewv 1.184 txt += 'PSETHASH=`edmConfigHash < ' + psetName + '` \n'
920 fanzago 1.94 txt += 'echo "PSETHASH = $PSETHASH" \n'
921 fanzago 1.93 txt += '\n'
922 gutsche 1.3 return txt
923 slacapra 1.176
924 fanzago 1.166 def wsUntarSoftware(self, nj=0):
925 gutsche 1.3 """
926     Put in the script the commands to build an executable
927     or a library.
928     """
929    
930 fanzago 1.166 txt = '\n#Written by cms_cmssw::wsUntarSoftware\n'
931 gutsche 1.3
932     if os.path.isfile(self.tgzNameWithPath):
933 fanzago 1.133 txt += 'echo ">>> tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+' :" \n'
934 gutsche 1.3 txt += 'tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'\n'
935 spiga 1.199 if self.debug_wrapper:
936     txt += 'ls -Al \n'
937 gutsche 1.3 txt += 'untar_status=$? \n'
938     txt += 'if [ $untar_status -ne 0 ]; then \n'
939 fanzago 1.161 txt += ' echo "ERROR ==> Untarring .tgz file failed"\n'
940     txt += ' job_exit_code=$untar_status\n'
941     txt += ' func_exit\n'
942 gutsche 1.3 txt += 'else \n'
943     txt += ' echo "Successful untar" \n'
944     txt += 'fi \n'
945 gutsche 1.50 txt += '\n'
946 fanzago 1.152 txt += 'echo ">>> Include ProdCommon in PYTHONPATH:"\n'
947 gutsche 1.50 txt += 'if [ -z "$PYTHONPATH" ]; then\n'
948 fanzago 1.166 txt += ' export PYTHONPATH=$RUNTIME_AREA/ProdCommon\n'
949 gutsche 1.50 txt += 'else\n'
950 fanzago 1.166 txt += ' export PYTHONPATH=$RUNTIME_AREA/ProdCommon:${PYTHONPATH}\n'
951 fanzago 1.93 txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
952 gutsche 1.50 txt += 'fi\n'
953     txt += '\n'
954    
955 gutsche 1.3 pass
956 ewv 1.131
957 slacapra 1.1 return txt
958 ewv 1.170
959 fanzago 1.166 def wsBuildExe(self, nj=0):
960     """
961     Put in the script the commands to build an executable
962     or a library.
963     """
964    
965     txt = '\n#Written by cms_cmssw::wsBuildExe\n'
966     txt += 'echo ">>> moving CMSSW software directories in `pwd`" \n'
967    
968 ewv 1.170 txt += 'rm -r lib/ module/ \n'
969     txt += 'mv $RUNTIME_AREA/lib/ . \n'
970     txt += 'mv $RUNTIME_AREA/module/ . \n'
971 spiga 1.186 if self.dataExist == True:
972     txt += 'rm -r src/ \n'
973     txt += 'mv $RUNTIME_AREA/src/ . \n'
974 ewv 1.182 if len(self.additional_inbox_files)>0:
975 spiga 1.179 for file in self.additional_inbox_files:
976 spiga 1.191 txt += 'mv $RUNTIME_AREA/'+os.path.basename(file)+' . \n'
977 ewv 1.170 txt += 'mv $RUNTIME_AREA/ProdCommon/ . \n'
978    
979 fanzago 1.166 txt += 'if [ -z "$PYTHONPATH" ]; then\n'
980     txt += ' export PYTHONPATH=$SOFTWARE_DIR/ProdCommon\n'
981     txt += 'else\n'
982     txt += ' export PYTHONPATH=$SOFTWARE_DIR/ProdCommon:${PYTHONPATH}\n'
983     txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
984     txt += 'fi\n'
985     txt += '\n'
986    
987     return txt
988 slacapra 1.1
989     def modifySteeringCards(self, nj):
990     """
991 ewv 1.131 modify the card provided by the user,
992 slacapra 1.1 writing a new card into share dir
993     """
994 ewv 1.131
995 slacapra 1.1 def executableName(self):
996 ewv 1.192 if self.scriptExe:
997 spiga 1.42 return "sh "
998     else:
999     return self.executable
1000 slacapra 1.1
1001     def executableArgs(self):
1002 ewv 1.160 # FUTURE: This function tests the CMSSW version. Can be simplified as we drop support for old versions
1003 slacapra 1.70 if self.scriptExe:#CarlosDaniele
1004 spiga 1.42 return self.scriptExe + " $NJob"
1005 fanzago 1.115 else:
1006 ewv 1.160 ex_args = ""
1007 ewv 1.171 # FUTURE: This tests the CMSSW version. Can remove code as versions deprecated
1008 ewv 1.160 # Framework job report
1009 ewv 1.184 if (self.CMSSW_major >= 1 and self.CMSSW_minor >= 5) or (self.CMSSW_major >= 2):
1010 fanzago 1.166 ex_args += " -j $RUNTIME_AREA/crab_fjr_$NJob.xml"
1011 ewv 1.184 # Type of config file
1012     if self.CMSSW_major >= 2 :
1013 ewv 1.171 ex_args += " -p pset.py"
1014 fanzago 1.115 else:
1015 ewv 1.160 ex_args += " -p pset.cfg"
1016     return ex_args
1017 slacapra 1.1
1018     def inputSandbox(self, nj):
1019     """
1020     Returns a list of filenames to be put in JDL input sandbox.
1021     """
1022     inp_box = []
1023     if os.path.isfile(self.tgzNameWithPath):
1024     inp_box.append(self.tgzNameWithPath)
1025 spiga 1.168 wrapper = os.path.basename(str(common._db.queryTask('scriptName')))
1026     inp_box.append(common.work_space.pathForTgz() +'job/'+ wrapper)
1027 slacapra 1.1 return inp_box
1028    
1029     def outputSandbox(self, nj):
1030     """
1031     Returns a list of filenames to be put in JDL output sandbox.
1032     """
1033     out_box = []
1034    
1035     ## User Declared output files
1036 slacapra 1.54 for out in (self.output_file+self.output_file_sandbox):
1037 ewv 1.131 n_out = nj + 1
1038 slacapra 1.1 out_box.append(self.numberFile_(out,str(n_out)))
1039     return out_box
1040    
1041     def prepareSteeringCards(self):
1042     """
1043     Make initial modifications of the user's steering card file.
1044     """
1045     return
1046    
1047     def wsRenameOutput(self, nj):
1048     """
1049     Returns part of a job script which renames the produced files.
1050     """
1051    
1052 ewv 1.160 txt = '\n#Written by cms_cmssw::wsRenameOutput\n'
1053 fanzago 1.148 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
1054     txt += 'echo ">>> current directory content:"\n'
1055 spiga 1.199 if self.debug_wrapper:
1056     txt += 'ls -Al\n'
1057 fanzago 1.145 txt += '\n'
1058 slacapra 1.54
1059 fanzago 1.128 for fileWithSuffix in (self.output_file):
1060 slacapra 1.1 output_file_num = self.numberFile_(fileWithSuffix, '$NJob')
1061     txt += '\n'
1062 gutsche 1.7 txt += '# check output file\n'
1063 slacapra 1.106 txt += 'if [ -e ./'+fileWithSuffix+' ] ; then\n'
1064 ewv 1.147 if (self.copy_data == 1): # For OSG nodes, file is in $WORKING_DIR, should not be moved to $RUNTIME_AREA
1065     txt += ' mv '+fileWithSuffix+' '+output_file_num+'\n'
1066 ewv 1.198 #txt += ' ln -s `pwd`/'+output_file_num+' $RUNTIME_AREA/'+fileWithSuffix+'\n'
1067 ewv 1.147 else:
1068     txt += ' mv '+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
1069     txt += ' ln -s $RUNTIME_AREA/'+output_file_num+' $RUNTIME_AREA/'+fileWithSuffix+'\n'
1070 slacapra 1.106 txt += 'else\n'
1071 fanzago 1.161 txt += ' job_exit_code=60302\n'
1072     txt += ' echo "WARNING: Output file '+fileWithSuffix+' not found"\n'
1073 ewv 1.156 if common.scheduler.name().upper() == 'CONDOR_G':
1074 gutsche 1.7 txt += ' if [ $middleware == OSG ]; then \n'
1075     txt += ' echo "prepare dummy output file"\n'
1076     txt += ' echo "Processing of job output failed" > $RUNTIME_AREA/'+output_file_num+'\n'
1077     txt += ' fi \n'
1078 slacapra 1.1 txt += 'fi\n'
1079 slacapra 1.105 file_list = []
1080     for fileWithSuffix in (self.output_file):
1081     file_list.append(self.numberFile_(fileWithSuffix, '$NJob'))
1082 ewv 1.131
1083 slacapra 1.105 txt += 'file_list="'+string.join(file_list,' ')+'"\n'
1084 fanzago 1.149 txt += '\n'
1085 fanzago 1.148 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
1086     txt += 'echo ">>> current directory content:"\n'
1087 spiga 1.199 if self.debug_wrapper:
1088     txt += 'ls -Al\n'
1089 fanzago 1.148 txt += '\n'
1090 gutsche 1.7 txt += 'cd $RUNTIME_AREA\n'
1091 fanzago 1.133 txt += 'echo ">>> current directory (RUNTIME_AREA): $RUNTIME_AREA"\n'
1092 slacapra 1.1 return txt
1093    
1094     def numberFile_(self, file, txt):
1095     """
1096     append _'txt' before last extension of a file
1097     """
1098     p = string.split(file,".")
1099     # take away last extension
1100     name = p[0]
1101     for x in p[1:-1]:
1102 slacapra 1.90 name=name+"."+x
1103 slacapra 1.1 # add "_txt"
1104     if len(p)>1:
1105 slacapra 1.90 ext = p[len(p)-1]
1106     result = name + '_' + txt + "." + ext
1107 slacapra 1.1 else:
1108 slacapra 1.90 result = name + '_' + txt
1109 ewv 1.131
1110 slacapra 1.1 return result
1111    
1112 slacapra 1.63 def getRequirements(self, nj=[]):
1113 slacapra 1.1 """
1114 ewv 1.131 return job requirements to add to jdl files
1115 slacapra 1.1 """
1116     req = ''
1117 slacapra 1.47 if self.version:
1118 slacapra 1.10 req='Member("VO-cms-' + \
1119 slacapra 1.47 self.version + \
1120 slacapra 1.10 '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1121 ewv 1.192 if self.executable_arch:
1122 gutsche 1.107 req+=' && Member("VO-cms-' + \
1123 slacapra 1.105 self.executable_arch + \
1124     '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1125 gutsche 1.35
1126     req = req + ' && (other.GlueHostNetworkAdapterOutboundIP)'
1127 afanfani 1.158 if common.scheduler.name() == "glitecoll":
1128     req += ' && other.GlueCEStateStatus == "Production" '
1129 gutsche 1.35
1130 slacapra 1.1 return req
1131 gutsche 1.3
1132     def configFilename(self):
1133     """ return the config filename """
1134 ewv 1.182 # FUTURE: Can remove cfg mode for CMSSW >= 2_1_x
1135 ewv 1.184 if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
1136 ewv 1.182 return self.name()+'.py'
1137     else:
1138     return self.name()+'.cfg'
1139 gutsche 1.3
1140     def wsSetupCMSOSGEnvironment_(self):
1141     """
1142     Returns part of a job script which is prepares
1143     the execution environment and which is common for all CMS jobs.
1144     """
1145 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupCMSOSGEnvironment_\n'
1146     txt += ' echo ">>> setup CMS OSG environment:"\n'
1147 fanzago 1.133 txt += ' echo "set SCRAM ARCH to ' + self.executable_arch + '"\n'
1148     txt += ' export SCRAM_ARCH='+self.executable_arch+'\n'
1149 fanzago 1.136 txt += ' echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
1150 ewv 1.135 txt += ' if [ -f $OSG_APP/cmssoft/cms/cmsset_default.sh ] ;then\n'
1151 mkirn 1.40 txt += ' # Use $OSG_APP/cmssoft/cms/cmsset_default.sh to setup cms software\n'
1152 fanzago 1.133 txt += ' source $OSG_APP/cmssoft/cms/cmsset_default.sh '+self.version+'\n'
1153     txt += ' else\n'
1154 fanzago 1.161 txt += ' echo "ERROR ==> $OSG_APP/cmssoft/cms/cmsset_default.sh file not found"\n'
1155     txt += ' job_exit_code=10020\n'
1156     txt += ' func_exit\n'
1157 fanzago 1.133 txt += ' fi\n'
1158 gutsche 1.3 txt += '\n'
1159 fanzago 1.161 txt += ' echo "==> setup cms environment ok"\n'
1160 fanzago 1.136 txt += ' echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
1161 gutsche 1.3
1162     return txt
1163 ewv 1.131
1164 gutsche 1.3 def wsSetupCMSLCGEnvironment_(self):
1165     """
1166     Returns part of a job script which is prepares
1167     the execution environment and which is common for all CMS jobs.
1168     """
1169 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupCMSLCGEnvironment_\n'
1170     txt += ' echo ">>> setup CMS LCG environment:"\n'
1171 fanzago 1.133 txt += ' echo "set SCRAM ARCH and BUILD_ARCH to ' + self.executable_arch + ' ###"\n'
1172     txt += ' export SCRAM_ARCH='+self.executable_arch+'\n'
1173     txt += ' export BUILD_ARCH='+self.executable_arch+'\n'
1174     txt += ' if [ ! $VO_CMS_SW_DIR ] ;then\n'
1175 fanzago 1.161 txt += ' echo "ERROR ==> CMS software dir not found on WN `hostname`"\n'
1176     txt += ' job_exit_code=10031\n'
1177     txt += ' func_exit\n'
1178 fanzago 1.133 txt += ' else\n'
1179     txt += ' echo "Sourcing environment... "\n'
1180     txt += ' if [ ! -s $VO_CMS_SW_DIR/cmsset_default.sh ] ;then\n'
1181 fanzago 1.161 txt += ' echo "ERROR ==> cmsset_default.sh file not found into dir $VO_CMS_SW_DIR"\n'
1182     txt += ' job_exit_code=10020\n'
1183     txt += ' func_exit\n'
1184 fanzago 1.133 txt += ' fi\n'
1185     txt += ' echo "sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1186     txt += ' source $VO_CMS_SW_DIR/cmsset_default.sh\n'
1187     txt += ' result=$?\n'
1188     txt += ' if [ $result -ne 0 ]; then\n'
1189 fanzago 1.161 txt += ' echo "ERROR ==> problem sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1190     txt += ' job_exit_code=10032\n'
1191     txt += ' func_exit\n'
1192 fanzago 1.133 txt += ' fi\n'
1193     txt += ' fi\n'
1194     txt += ' \n'
1195 fanzago 1.161 txt += ' echo "==> setup cms environment ok"\n'
1196 gutsche 1.3 return txt
1197 gutsche 1.5
1198 fanzago 1.93 def modifyReport(self, nj):
1199     """
1200 ewv 1.131 insert the part of the script that modifies the FrameworkJob Report
1201 fanzago 1.93 """
1202 ewv 1.160 txt = '\n#Written by cms_cmssw::modifyReport\n'
1203 slacapra 1.176 publish_data = int(self.cfg_params.get('USER.publish_data',0))
1204 ewv 1.131 if (publish_data == 1):
1205 fanzago 1.94 processedDataset = self.cfg_params['USER.publish_data_name']
1206 fanzago 1.173 LFNBaseName = LFNBase(processedDataset)
1207 fanzago 1.175
1208     txt += 'if [ $copy_exit_status -eq 0 ]; then\n'
1209 fanzago 1.173 txt += ' FOR_LFN=%s_${PSETHASH}/\n'%(LFNBaseName)
1210 fanzago 1.175 txt += 'else\n'
1211     txt += ' FOR_LFN=/copy_problems/ \n'
1212     txt += ' SE=""\n'
1213     txt += ' SE_PATH=""\n'
1214     txt += 'fi\n'
1215 ewv 1.182
1216 fanzago 1.175 txt += 'echo ">>> Modify Job Report:" \n'
1217     txt += 'chmod a+x $SOFTWARE_DIR/ProdCommon/ProdCommon/FwkJobRep/ModifyJobReport.py\n'
1218     txt += 'ProcessedDataset='+processedDataset+'\n'
1219     txt += 'echo "ProcessedDataset = $ProcessedDataset"\n'
1220     txt += 'echo "SE = $SE"\n'
1221     txt += 'echo "SE_PATH = $SE_PATH"\n'
1222     txt += 'echo "FOR_LFN = $FOR_LFN" \n'
1223     txt += 'echo "CMSSW_VERSION = $CMSSW_VERSION"\n\n'
1224     txt += 'echo "$SOFTWARE_DIR/ProdCommon/ProdCommon/FwkJobRep/ModifyJobReport.py $RUNTIME_AREA/crab_fjr_$NJob.xml $NJob $FOR_LFN $PrimaryDataset $DataTier $ProcessedDataset $ApplicationFamily $executable $CMSSW_VERSION $PSETHASH $SE $SE_PATH"\n'
1225     txt += '$SOFTWARE_DIR/ProdCommon/ProdCommon/FwkJobRep/ModifyJobReport.py $RUNTIME_AREA/crab_fjr_$NJob.xml $NJob $FOR_LFN $PrimaryDataset $DataTier $ProcessedDataset $ApplicationFamily $executable $CMSSW_VERSION $PSETHASH $SE $SE_PATH\n'
1226     txt += 'modifyReport_result=$?\n'
1227     txt += 'if [ $modifyReport_result -ne 0 ]; then\n'
1228     txt += ' modifyReport_result=70500\n'
1229     txt += ' job_exit_code=$modifyReport_result\n'
1230     txt += ' echo "ModifyReportResult=$modifyReport_result" | tee -a $RUNTIME_AREA/$repo\n'
1231     txt += ' echo "WARNING: Problem with ModifyJobReport"\n'
1232     txt += 'else\n'
1233     txt += ' mv NewFrameworkJobReport.xml $RUNTIME_AREA/crab_fjr_$NJob.xml\n'
1234 spiga 1.103 txt += 'fi\n'
1235 fanzago 1.93 return txt
1236 fanzago 1.99
1237 ewv 1.192 def wsParseFJR(self):
1238 spiga 1.189 """
1239 ewv 1.192 Parse the FrameworkJobReport to obtain useful infos
1240 spiga 1.189 """
1241     txt = '\n#Written by cms_cmssw::wsParseFJR\n'
1242     txt += 'echo ">>> Parse FrameworkJobReport crab_fjr.xml"\n'
1243     txt += 'if [ -s $RUNTIME_AREA/crab_fjr_$NJob.xml ]; then\n'
1244     txt += ' if [ -s $RUNTIME_AREA/parseCrabFjr.py ]; then\n'
1245 spiga 1.197 txt += ' cmd_out=`python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --dashboard $MonitorID,$MonitorJobID '+self.debugWrap+'`\n'
1246     if self.debug_wrapper :
1247     txt += ' echo "Result of parsing the FrameworkJobReport crab_fjr.xml: $cmd_out"\n'
1248     txt += ' executable_exit_status=`python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --exitcode`\n'
1249 spiga 1.189 txt += ' if [ $executable_exit_status -eq 50115 ];then\n'
1250     txt += ' echo ">>> crab_fjr.xml contents: "\n'
1251     txt += ' cat $RUNTIME_AREA/crab_fjr_NJob.xml\n'
1252     txt += ' echo "Wrong FrameworkJobReport --> does not contain useful info. ExitStatus: $executable_exit_status"\n'
1253 spiga 1.197 txt += ' elif [ $executable_exit_status -eq -999 ];then\n'
1254     txt += ' echo "ExitStatus from FrameworkJobReport not available. not available. Using exit code of executable from command line."\n'
1255 spiga 1.189 txt += ' else\n'
1256     txt += ' echo "Extracted ExitStatus from FrameworkJobReport parsing output: $executable_exit_status"\n'
1257     txt += ' fi\n'
1258     txt += ' else\n'
1259     txt += ' echo "CRAB python script to parse CRAB FrameworkJobReport crab_fjr.xml is not available, using exit code of executable from command line."\n'
1260     txt += ' fi\n'
1261     #### Patch to check input data reading for CMSSW16x Hopefully we-ll remove it asap
1262    
1263     if self.datasetPath:
1264     # VERIFY PROCESSED DATA
1265     txt += ' if [ $executable_exit_status -eq 0 ];then\n'
1266     txt += ' echo ">>> Verify list of processed files:"\n'
1267 ewv 1.196 txt += ' echo $InputFiles |tr -d \'\\\\\' |tr \',\' \'\\n\'|tr -d \'"\' > input-files.txt\n'
1268 spiga 1.200 txt += ' python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --lfn > processed-files.txt\n'
1269 spiga 1.189 txt += ' cat input-files.txt | sort | uniq > tmp.txt\n'
1270     txt += ' mv tmp.txt input-files.txt\n'
1271     txt += ' echo "cat input-files.txt"\n'
1272     txt += ' echo "----------------------"\n'
1273     txt += ' cat input-files.txt\n'
1274     txt += ' cat processed-files.txt | sort | uniq > tmp.txt\n'
1275     txt += ' mv tmp.txt processed-files.txt\n'
1276     txt += ' echo "----------------------"\n'
1277     txt += ' echo "cat processed-files.txt"\n'
1278     txt += ' echo "----------------------"\n'
1279     txt += ' cat processed-files.txt\n'
1280     txt += ' echo "----------------------"\n'
1281     txt += ' diff -q input-files.txt processed-files.txt\n'
1282     txt += ' fileverify_status=$?\n'
1283     txt += ' if [ $fileverify_status -ne 0 ]; then\n'
1284     txt += ' executable_exit_status=30001\n'
1285     txt += ' echo "ERROR ==> not all input files processed"\n'
1286     txt += ' echo " ==> list of processed files from crab_fjr.xml differs from list in pset.cfg"\n'
1287     txt += ' echo " ==> diff input-files.txt processed-files.txt"\n'
1288     txt += ' fi\n'
1289     txt += ' fi\n'
1290     txt += '\n'
1291     txt += 'else\n'
1292     txt += ' echo "CRAB FrameworkJobReport crab_fjr.xml is not available, using exit code of executable from command line."\n'
1293     txt += 'fi\n'
1294     txt += '\n'
1295     txt += 'echo "ExeExitCode=$executable_exit_status" | tee -a $RUNTIME_AREA/$repo\n'
1296     txt += 'echo "EXECUTABLE_EXIT_STATUS = $executable_exit_status"\n'
1297     txt += 'job_exit_code=$executable_exit_status\n'
1298    
1299     return txt
1300    
1301 gutsche 1.5 def setParam_(self, param, value):
1302     self._params[param] = value
1303    
1304     def getParams(self):
1305     return self._params
1306 gutsche 1.8
1307 gutsche 1.35 def uniquelist(self, old):
1308     """
1309     remove duplicates from a list
1310     """
1311     nd={}
1312     for e in old:
1313     nd[e]=0
1314     return nd.keys()
1315 mcinquil 1.121
1316 spiga 1.169 def outList(self):
1317 mcinquil 1.121 """
1318     check the dimension of the output files
1319     """
1320 spiga 1.169 txt = ''
1321     txt += 'echo ">>> list of expected files on output sandbox"\n'
1322 mcinquil 1.121 listOutFiles = []
1323 ewv 1.170 stdout = 'CMSSW_$NJob.stdout'
1324 spiga 1.169 stderr = 'CMSSW_$NJob.stderr'
1325 fanzago 1.148 if (self.return_data == 1):
1326 spiga 1.157 for file in (self.output_file+self.output_file_sandbox):
1327     listOutFiles.append(self.numberFile_(file, '$NJob'))
1328 spiga 1.169 listOutFiles.append(stdout)
1329     listOutFiles.append(stderr)
1330 ewv 1.156 else:
1331 spiga 1.157 for file in (self.output_file_sandbox):
1332     listOutFiles.append(self.numberFile_(file, '$NJob'))
1333 spiga 1.169 listOutFiles.append(stdout)
1334     listOutFiles.append(stderr)
1335 fanzago 1.161 txt += 'echo "output files: '+string.join(listOutFiles,' ')+'"\n'
1336 spiga 1.157 txt += 'filesToCheck="'+string.join(listOutFiles,' ')+'"\n'
1337 spiga 1.169 txt += 'export filesToCheck\n'
1338 ewv 1.170 return txt