ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.214
Committed: Wed Jun 11 12:05:58 2008 UTC (16 years, 10 months ago) by slacapra
Content type: text/x-python
Branch: MAIN
Changes since 1.213: +5 -6 lines
Log Message:
fix for correct tar ball creation with needd ProdCommon stuff (and not all)

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