ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.207
Committed: Fri Jun 6 11:45:22 2008 UTC (16 years, 10 months ago) by slacapra
Content type: text/x-python
Branch: MAIN
Changes since 1.206: +6 -29 lines
Log Message:
move func fileNumber from cms_cmssw to crab_util

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 slacapra 1.207 self.output_file = [x.strip() for x in tmp.split(',')]
101 slacapra 1.153 else:
102 gutsche 1.92 log.message("No output file defined: only stdout/err and the CRAB Framework Job Report will be available\n")
103 slacapra 1.153 pass
104 slacapra 1.1
105     # script_exe file as additional file in inputSandbox
106 slacapra 1.153 self.scriptExe = cfg_params.get('USER.script_exe',None)
107     if self.scriptExe :
108 slacapra 1.176 if not os.path.isfile(self.scriptExe):
109     msg ="ERROR. file "+self.scriptExe+" not found"
110     raise CrabException(msg)
111     self.additional_inbox_files.append(string.strip(self.scriptExe))
112 slacapra 1.70
113 spiga 1.42 if self.datasetPath == None and self.pset == None and self.scriptExe == '' :
114 slacapra 1.176 msg ="Error. script_exe not defined"
115     raise CrabException(msg)
116 spiga 1.42
117 spiga 1.204 # use parent files...
118     self.useParent = self.cfg_params.get('CMSSW.use_parent',False)
119    
120 slacapra 1.1 ## additional input files
121 slacapra 1.153 if cfg_params.has_key('USER.additional_input_files'):
122 slacapra 1.29 tmpAddFiles = string.split(cfg_params['USER.additional_input_files'],',')
123 slacapra 1.70 for tmp in tmpAddFiles:
124     tmp = string.strip(tmp)
125     dirname = ''
126     if not tmp[0]=="/": dirname = "."
127 corvo 1.85 files = []
128     if string.find(tmp,"*")>-1:
129     files = glob.glob(os.path.join(dirname, tmp))
130     if len(files)==0:
131     raise CrabException("No additional input file found with this pattern: "+tmp)
132     else:
133     files.append(tmp)
134 slacapra 1.70 for file in files:
135     if not os.path.exists(file):
136     raise CrabException("Additional input file not found: "+file)
137 slacapra 1.45 pass
138 slacapra 1.105 self.additional_inbox_files.append(string.strip(file))
139 slacapra 1.1 pass
140     pass
141 slacapra 1.70 common.logger.debug(5,"Additional input files: "+str(self.additional_inbox_files))
142 slacapra 1.153 pass
143 gutsche 1.3
144 slacapra 1.9 ## Events per job
145 slacapra 1.153 if cfg_params.has_key('CMSSW.events_per_job'):
146 slacapra 1.10 self.eventsPerJob =int( cfg_params['CMSSW.events_per_job'])
147 slacapra 1.9 self.selectEventsPerJob = 1
148 slacapra 1.153 else:
149 slacapra 1.9 self.eventsPerJob = -1
150     self.selectEventsPerJob = 0
151 ewv 1.131
152 slacapra 1.22 ## number of jobs
153 slacapra 1.153 if cfg_params.has_key('CMSSW.number_of_jobs'):
154 slacapra 1.22 self.theNumberOfJobs =int( cfg_params['CMSSW.number_of_jobs'])
155     self.selectNumberOfJobs = 1
156 slacapra 1.153 else:
157 slacapra 1.22 self.theNumberOfJobs = 0
158     self.selectNumberOfJobs = 0
159 slacapra 1.10
160 slacapra 1.153 if cfg_params.has_key('CMSSW.total_number_of_events'):
161 gutsche 1.35 self.total_number_of_events = int(cfg_params['CMSSW.total_number_of_events'])
162     self.selectTotalNumberEvents = 1
163 spiga 1.193 if self.selectNumberOfJobs == 1:
164 spiga 1.202 if (self.total_number_of_events != -1) and int(self.total_number_of_events) < int(self.theNumberOfJobs):
165 spiga 1.193 msg = 'Must specify at least one event per job. total_number_of_events > number_of_jobs '
166     raise CrabException(msg)
167 slacapra 1.153 else:
168 gutsche 1.35 self.total_number_of_events = 0
169     self.selectTotalNumberEvents = 0
170    
171 spiga 1.187 if self.pset != None:
172 spiga 1.42 if ( (self.selectTotalNumberEvents + self.selectEventsPerJob + self.selectNumberOfJobs) != 2 ):
173     msg = 'Must define exactly two of total_number_of_events, events_per_job, or number_of_jobs.'
174     raise CrabException(msg)
175     else:
176     if (self.selectNumberOfJobs == 0):
177     msg = 'Must specify number_of_jobs.'
178     raise CrabException(msg)
179 gutsche 1.35
180 ewv 1.160 ## New method of dealing with seeds
181     self.incrementSeeds = []
182     self.preserveSeeds = []
183     if cfg_params.has_key('CMSSW.preserve_seeds'):
184     tmpList = cfg_params['CMSSW.preserve_seeds'].split(',')
185     for tmp in tmpList:
186     tmp.strip()
187     self.preserveSeeds.append(tmp)
188     if cfg_params.has_key('CMSSW.increment_seeds'):
189     tmpList = cfg_params['CMSSW.increment_seeds'].split(',')
190     for tmp in tmpList:
191     tmp.strip()
192     self.incrementSeeds.append(tmp)
193    
194     ## Old method of dealing with seeds
195     ## FUTURE: This is for old CMSSW and old CRAB. Can throw exceptions after a couple of CRAB releases and then
196     ## remove
197 slacapra 1.153 self.sourceSeed = cfg_params.get('CMSSW.pythia_seed',None)
198 ewv 1.160 if self.sourceSeed:
199 slacapra 1.177 print "pythia_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
200     self.incrementSeeds.append('sourceSeed')
201 ewv 1.185 self.incrementSeeds.append('theSource')
202 slacapra 1.153
203     self.sourceSeedVtx = cfg_params.get('CMSSW.vtx_seed',None)
204 ewv 1.160 if self.sourceSeedVtx:
205 slacapra 1.177 print "vtx_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
206     self.incrementSeeds.append('VtxSmeared')
207 slacapra 1.22
208 slacapra 1.153 self.sourceSeedG4 = cfg_params.get('CMSSW.g4_seed',None)
209 ewv 1.160 if self.sourceSeedG4:
210 slacapra 1.177 print "g4_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
211     self.incrementSeeds.append('g4SimHits')
212 slacapra 1.90
213 slacapra 1.153 self.sourceSeedMix = cfg_params.get('CMSSW.mix_seed',None)
214 ewv 1.160 if self.sourceSeedMix:
215 slacapra 1.177 print "mix_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
216     self.incrementSeeds.append('mix')
217 slacapra 1.90
218 slacapra 1.153 self.firstRun = cfg_params.get('CMSSW.first_run',None)
219 slacapra 1.90
220 spiga 1.42 if self.pset != None: #CarlosDaniele
221 ewv 1.131 import PsetManipulator as pp
222 slacapra 1.97 PsetEdit = pp.PsetManipulator(self.pset) #Daniele Pset
223 gutsche 1.3
224 ewv 1.147 # Copy/return
225    
226 slacapra 1.153 self.copy_data = int(cfg_params.get('USER.copy_data',0))
227     self.return_data = int(cfg_params.get('USER.return_data',0))
228 ewv 1.147
229 slacapra 1.1 #DBSDLS-start
230 ewv 1.131 ## Initialize the variables that are extracted from DBS/DLS and needed in other places of the code
231 slacapra 1.1 self.maxEvents=0 # max events available ( --> check the requested nb. of evts in Creator.py)
232     self.DBSPaths={} # all dbs paths requested ( --> input to the site local discovery script)
233 gutsche 1.35 self.jobDestination=[] # Site destination(s) for each job (list of lists)
234 slacapra 1.1 ## Perform the data location and discovery (based on DBS/DLS)
235 slacapra 1.9 ## SL: Don't if NONE is specified as input (pythia use case)
236 gutsche 1.35 blockSites = {}
237 slacapra 1.9 if self.datasetPath:
238 gutsche 1.35 blockSites = self.DataDiscoveryAndLocation(cfg_params)
239 ewv 1.131 #DBSDLS-end
240 slacapra 1.1
241 ewv 1.131
242 slacapra 1.9 ## Select Splitting
243 ewv 1.131 if self.selectNoInput:
244 spiga 1.187 if self.pset == None:
245 spiga 1.42 self.jobSplittingForScript()
246     else:
247     self.jobSplittingNoInput()
248 gutsche 1.92 else:
249 corvo 1.56 self.jobSplittingByBlocks(blockSites)
250 gutsche 1.5
251 slacapra 1.22 # modify Pset
252 ewv 1.192 if self.pset != None:
253 slacapra 1.86 try:
254 ewv 1.160 # Add FrameworkJobReport to parameter-set, set max events.
255     # Reset later for data jobs by writeCFG which does all modifications
256 ewv 1.182 PsetEdit.addCrabFJR(self.fjrFileName) # FUTURE: Job report addition not needed by CMSSW>1.5
257 ewv 1.160 PsetEdit.maxEvent(self.eventsPerJob)
258 slacapra 1.90 PsetEdit.psetWriter(self.configFilename())
259 slacapra 1.86 except:
260 ewv 1.184 msg='Error while manipulating ParameterSet: exiting...'
261 slacapra 1.86 raise CrabException(msg)
262 spiga 1.179 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 slacapra 1.137 self.pubdata=DataDiscovery.DataDiscovery(datasetPath, cfg_params)
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 gutsche 1.3 def split(self, jobParams):
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 gutsche 1.3 for job in range(njobs):
650 slacapra 1.17 jobParams[job] = arglist[job]
651 spiga 1.167 listID.append(job+1)
652 spiga 1.162 job_ToSave ={}
653 spiga 1.169 concString = ' '
654 spiga 1.165 argu=''
655     if len(jobParams[job]):
656     argu += concString.join(jobParams[job] )
657 spiga 1.187 job_ToSave['arguments']= str(job+1)+' '+argu
658     job_ToSave['dlsDestination']= self.jobDestination[job]
659 spiga 1.165 listField.append(job_ToSave)
660 spiga 1.169 msg="Job "+str(job)+" Arguments: "+str(job+1)+" "+argu+"\n" \
661 spiga 1.165 +" Destination: "+str(self.jobDestination[job])
662     common.logger.debug(5,msg)
663 spiga 1.187 common._db.updateJob_(listID,listField)
664 spiga 1.181 self.argsList = (len(jobParams[0])+1)
665 gutsche 1.3
666     return
667 ewv 1.131
668 gutsche 1.3 def numberOfJobs(self):
669     return self.total_number_of_jobs
670    
671 slacapra 1.1 def getTarBall(self, exe):
672     """
673     Return the TarBall with lib and exe
674     """
675 corvo 1.56 self.tgzNameWithPath = common.work_space.pathForTgz()+'share/'+self.tgz_name
676 slacapra 1.1 if os.path.exists(self.tgzNameWithPath):
677     return self.tgzNameWithPath
678    
679     # Prepare a tar gzipped file with user binaries.
680     self.buildTar_(exe)
681    
682     return string.strip(self.tgzNameWithPath)
683    
684     def buildTar_(self, executable):
685    
686     # First of all declare the user Scram area
687     swArea = self.scram.getSWArea_()
688     swReleaseTop = self.scram.getReleaseTop_()
689 ewv 1.131
690 slacapra 1.1 ## check if working area is release top
691     if swReleaseTop == '' or swArea == swReleaseTop:
692 afanfani 1.172 common.logger.debug(3,"swArea = "+swArea+" swReleaseTop ="+swReleaseTop)
693 slacapra 1.1 return
694    
695 slacapra 1.61 import tarfile
696     try: # create tar ball
697     tar = tarfile.open(self.tgzNameWithPath, "w:gz")
698     ## First find the executable
699 slacapra 1.86 if (self.executable != ''):
700 slacapra 1.61 exeWithPath = self.scram.findFile_(executable)
701     if ( not exeWithPath ):
702     raise CrabException('User executable '+executable+' not found')
703 ewv 1.131
704 slacapra 1.61 ## then check if it's private or not
705     if exeWithPath.find(swReleaseTop) == -1:
706     # the exe is private, so we must ship
707     common.logger.debug(5,"Exe "+exeWithPath+" to be tarred")
708     path = swArea+'/'
709 corvo 1.85 # distinguish case when script is in user project area or given by full path somewhere else
710     if exeWithPath.find(path) >= 0 :
711     exe = string.replace(exeWithPath, path,'')
712 slacapra 1.129 tar.add(path+exe,exe)
713 corvo 1.85 else :
714     tar.add(exeWithPath,os.path.basename(executable))
715 slacapra 1.61 pass
716     else:
717     # the exe is from release, we'll find it on WN
718     pass
719 ewv 1.131
720 slacapra 1.61 ## Now get the libraries: only those in local working area
721     libDir = 'lib'
722     lib = swArea+'/' +libDir
723     common.logger.debug(5,"lib "+lib+" to be tarred")
724     if os.path.exists(lib):
725     tar.add(lib,libDir)
726 ewv 1.131
727 slacapra 1.61 ## Now check if module dir is present
728     moduleDir = 'module'
729     module = swArea + '/' + moduleDir
730     if os.path.isdir(module):
731     tar.add(module,moduleDir)
732    
733     ## Now check if any data dir(s) is present
734 spiga 1.179 self.dataExist = False
735 slacapra 1.206 #print "Starting walk."
736     #timer = -time.time()
737     todo_list = [(os.path.join(swArea, i), i) for i in os.listdir(swArea)]
738     while len(todo_list):
739     entry, name = todo_list.pop()
740     if name.startswith('crab_0_') or name.startswith('.'):
741     continue
742     if os.path.isdir(entry):
743     entryPath = entry + '/'
744     todo_list += [(entryPath + i, i) for i in os.listdir(entry)]
745     if name == 'data':
746     self.dataExist=True
747     common.logger.debug(5,"data "+entry+" to be tarred")
748     tar.add(entry, swArea)
749     pass
750     pass
751     #timer += time.time()
752     #print "Finished walk.", timer
753 ewv 1.182
754 spiga 1.179 ### CMSSW ParameterSet
755     if not self.pset is None:
756     cfg_file = common.work_space.jobDir()+self.configFilename()
757 ewv 1.182 tar.add(cfg_file,self.configFilename())
758 spiga 1.179 common.logger.debug(5,"File added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
759 slacapra 1.61
760 fanzago 1.93
761 fanzago 1.152 ## Add ProdCommon dir to tar
762 fanzago 1.93 prodcommonDir = 'ProdCommon'
763 slacapra 1.205 prodcommonPath = os.environ['CRABDIR'] + '/' + 'external/'
764 fanzago 1.93 if os.path.isdir(prodcommonPath):
765     tar.add(prodcommonPath,prodcommonDir)
766 spiga 1.179 common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
767    
768     ##### ML stuff
769     ML_file_list=['report.py', 'DashboardAPI.py', 'Logger.py', 'ProcInfo.py', 'apmon.py']
770     path=os.environ['CRABDIR'] + '/python/'
771     for file in ML_file_list:
772     tar.add(path+file,file)
773     common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
774    
775     ##### Utils
776 spiga 1.203 Utils_file_list=['parseCrabFjr.py','writeCfg.py', 'fillCrabFjr.py']
777 spiga 1.179 for file in Utils_file_list:
778     tar.add(path+file,file)
779     common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
780 ewv 1.131
781 ewv 1.182 ##### AdditionalFiles
782 spiga 1.179 for file in self.additional_inbox_files:
783     tar.add(file,string.split(file,'/')[-1])
784 slacapra 1.61 common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
785 ewv 1.182
786 slacapra 1.61 tar.close()
787 slacapra 1.206 except TarError:
788     raise CrabException('Could not create tar-ball '+self.tgzNameWithPath)
789 gutsche 1.72
790     ## check for tarball size
791     tarballinfo = os.stat(self.tgzNameWithPath)
792     if ( tarballinfo.st_size > self.MaxTarBallSize*1024*1024 ) :
793     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.')
794    
795 slacapra 1.61 ## create tar-ball with ML stuff
796 slacapra 1.97
797 spiga 1.165 def wsSetupEnvironment(self, nj=0):
798 slacapra 1.1 """
799     Returns part of a job script which prepares
800     the execution environment for the job 'nj'.
801     """
802 ewv 1.184 if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
803     psetName = 'pset.py'
804     else:
805     psetName = 'pset.cfg'
806 slacapra 1.1 # Prepare JobType-independent part
807 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupEnvironment\n'
808 fanzago 1.133 txt += 'echo ">>> setup environment"\n'
809 ewv 1.131 txt += 'if [ $middleware == LCG ]; then \n'
810 gutsche 1.3 txt += self.wsSetupCMSLCGEnvironment_()
811     txt += 'elif [ $middleware == OSG ]; then\n'
812 gutsche 1.43 txt += ' WORKING_DIR=`/bin/mktemp -d $OSG_WN_TMP/cms_XXXXXXXXXXXX`\n'
813 ewv 1.132 txt += ' if [ ! $? == 0 ] ;then\n'
814 fanzago 1.161 txt += ' echo "ERROR ==> OSG $WORKING_DIR could not be created on WN `hostname`"\n'
815     txt += ' job_exit_code=10016\n'
816     txt += ' func_exit\n'
817 gutsche 1.3 txt += ' fi\n'
818 fanzago 1.133 txt += ' echo ">>> Created working directory: $WORKING_DIR"\n'
819 gutsche 1.3 txt += '\n'
820     txt += ' echo "Change to working directory: $WORKING_DIR"\n'
821     txt += ' cd $WORKING_DIR\n'
822 fanzago 1.133 txt += ' echo ">>> current directory (WORKING_DIR): $WORKING_DIR"\n'
823 ewv 1.131 txt += self.wsSetupCMSOSGEnvironment_()
824 gutsche 1.3 txt += 'fi\n'
825 slacapra 1.1
826     # Prepare JobType-specific part
827     scram = self.scram.commandName()
828     txt += '\n\n'
829 fanzago 1.133 txt += 'echo ">>> specific cmssw setup environment:"\n'
830     txt += 'echo "CMSSW_VERSION = '+self.version+'"\n'
831 slacapra 1.1 txt += scram+' project CMSSW '+self.version+'\n'
832     txt += 'status=$?\n'
833     txt += 'if [ $status != 0 ] ; then\n'
834 fanzago 1.161 txt += ' echo "ERROR ==> CMSSW '+self.version+' not found on `hostname`" \n'
835     txt += ' job_exit_code=10034\n'
836 fanzago 1.163 txt += ' func_exit\n'
837 slacapra 1.1 txt += 'fi \n'
838     txt += 'cd '+self.version+'\n'
839 fanzago 1.99 txt += 'SOFTWARE_DIR=`pwd`\n'
840 fanzago 1.133 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
841 slacapra 1.1 txt += 'eval `'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME`\n'
842 fanzago 1.180 txt += 'if [ $? != 0 ] ; then\n'
843     txt += ' echo "ERROR ==> Problem with the command: "\n'
844     txt += ' echo "eval \`'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME \` at `hostname`"\n'
845     txt += ' job_exit_code=10034\n'
846     txt += ' func_exit\n'
847     txt += 'fi \n'
848 slacapra 1.1 # Handle the arguments:
849     txt += "\n"
850 gutsche 1.7 txt += "## number of arguments (first argument always jobnumber)\n"
851 slacapra 1.1 txt += "\n"
852 spiga 1.165 txt += "if [ $nargs -lt "+str(self.argsList)+" ]\n"
853 slacapra 1.1 txt += "then\n"
854 fanzago 1.161 txt += " echo 'ERROR ==> Too few arguments' +$nargs+ \n"
855     txt += ' job_exit_code=50113\n'
856     txt += " func_exit\n"
857 slacapra 1.1 txt += "fi\n"
858     txt += "\n"
859    
860     # Prepare job-specific part
861     job = common.job_list[nj]
862 ewv 1.131 if (self.datasetPath):
863 fanzago 1.93 txt += '\n'
864     txt += 'DatasetPath='+self.datasetPath+'\n'
865    
866     datasetpath_split = self.datasetPath.split("/")
867 ewv 1.131
868 fanzago 1.93 txt += 'PrimaryDataset='+datasetpath_split[1]+'\n'
869     txt += 'DataTier='+datasetpath_split[2]+'\n'
870 fanzago 1.96 txt += 'ApplicationFamily=cmsRun\n'
871 fanzago 1.93
872     else:
873     txt += 'DatasetPath=MCDataTier\n'
874     txt += 'PrimaryDataset=null\n'
875     txt += 'DataTier=null\n'
876     txt += 'ApplicationFamily=MCDataTier\n'
877 ewv 1.170 if self.pset != None:
878 spiga 1.42 pset = os.path.basename(job.configFilename())
879     txt += '\n'
880 spiga 1.95 txt += 'cp $RUNTIME_AREA/'+pset+' .\n'
881 spiga 1.42 if (self.datasetPath): # standard job
882 ewv 1.160 txt += 'InputFiles=${args[1]}; export InputFiles\n'
883 spiga 1.204 if (self.useParent):
884     txt += 'ParentFiles=${args[2]}; export ParentFiles\n'
885     txt += 'MaxEvents=${args[3]}; export MaxEvents\n'
886     txt += 'SkipEvents=${args[4]}; export SkipEvents\n'
887     else:
888     txt += 'MaxEvents=${args[2]}; export MaxEvents\n'
889     txt += 'SkipEvents=${args[3]}; export SkipEvents\n'
890 spiga 1.42 txt += 'echo "Inputfiles:<$InputFiles>"\n'
891 spiga 1.204 if (self.useParent): txt += 'echo "ParentFiles:<$ParentFiles>"\n'
892 spiga 1.42 txt += 'echo "MaxEvents:<$MaxEvents>"\n'
893     txt += 'echo "SkipEvents:<$SkipEvents>"\n'
894     else: # pythia like job
895 ewv 1.160 txt += 'PreserveSeeds=' + ','.join(self.preserveSeeds) + '; export PreserveSeeds\n'
896     txt += 'IncrementSeeds=' + ','.join(self.incrementSeeds) + '; export IncrementSeeds\n'
897     txt += 'echo "PreserveSeeds: <$PreserveSeeds>"\n'
898     txt += 'echo "IncrementSeeds:<$IncrementSeeds>"\n'
899 slacapra 1.90 if (self.firstRun):
900 ewv 1.160 txt += 'FirstRun=${args[1]}; export FirstRun\n'
901 spiga 1.57 txt += 'echo "FirstRun: <$FirstRun>"\n'
902 slacapra 1.90
903 ewv 1.184 txt += 'mv -f ' + pset + ' ' + psetName + '\n'
904 slacapra 1.1
905    
906 fanzago 1.163 if self.pset != None:
907 ewv 1.184 # FUTURE: Can simply for 2_1_x and higher
908 spiga 1.42 txt += '\n'
909 spiga 1.197 if self.debug_wrapper==True:
910 spiga 1.188 txt += 'echo "***** cat ' + psetName + ' *********"\n'
911     txt += 'cat ' + psetName + '\n'
912     txt += 'echo "****** end ' + psetName + ' ********"\n'
913     txt += '\n'
914 ewv 1.184 txt += 'PSETHASH=`edmConfigHash < ' + psetName + '` \n'
915 fanzago 1.94 txt += 'echo "PSETHASH = $PSETHASH" \n'
916 fanzago 1.93 txt += '\n'
917 gutsche 1.3 return txt
918 slacapra 1.176
919 fanzago 1.166 def wsUntarSoftware(self, nj=0):
920 gutsche 1.3 """
921     Put in the script the commands to build an executable
922     or a library.
923     """
924    
925 fanzago 1.166 txt = '\n#Written by cms_cmssw::wsUntarSoftware\n'
926 gutsche 1.3
927     if os.path.isfile(self.tgzNameWithPath):
928 fanzago 1.133 txt += 'echo ">>> tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+' :" \n'
929 gutsche 1.3 txt += 'tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'\n'
930 spiga 1.199 if self.debug_wrapper:
931     txt += 'ls -Al \n'
932 gutsche 1.3 txt += 'untar_status=$? \n'
933     txt += 'if [ $untar_status -ne 0 ]; then \n'
934 fanzago 1.161 txt += ' echo "ERROR ==> Untarring .tgz file failed"\n'
935     txt += ' job_exit_code=$untar_status\n'
936     txt += ' func_exit\n'
937 gutsche 1.3 txt += 'else \n'
938     txt += ' echo "Successful untar" \n'
939     txt += 'fi \n'
940 gutsche 1.50 txt += '\n'
941 fanzago 1.152 txt += 'echo ">>> Include ProdCommon in PYTHONPATH:"\n'
942 gutsche 1.50 txt += 'if [ -z "$PYTHONPATH" ]; then\n'
943 fanzago 1.166 txt += ' export PYTHONPATH=$RUNTIME_AREA/ProdCommon\n'
944 gutsche 1.50 txt += 'else\n'
945 fanzago 1.166 txt += ' export PYTHONPATH=$RUNTIME_AREA/ProdCommon:${PYTHONPATH}\n'
946 fanzago 1.93 txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
947 gutsche 1.50 txt += 'fi\n'
948     txt += '\n'
949    
950 gutsche 1.3 pass
951 ewv 1.131
952 slacapra 1.1 return txt
953 ewv 1.170
954 fanzago 1.166 def wsBuildExe(self, nj=0):
955     """
956     Put in the script the commands to build an executable
957     or a library.
958     """
959    
960     txt = '\n#Written by cms_cmssw::wsBuildExe\n'
961     txt += 'echo ">>> moving CMSSW software directories in `pwd`" \n'
962    
963 ewv 1.170 txt += 'rm -r lib/ module/ \n'
964     txt += 'mv $RUNTIME_AREA/lib/ . \n'
965     txt += 'mv $RUNTIME_AREA/module/ . \n'
966 spiga 1.186 if self.dataExist == True:
967     txt += 'rm -r src/ \n'
968     txt += 'mv $RUNTIME_AREA/src/ . \n'
969 ewv 1.182 if len(self.additional_inbox_files)>0:
970 spiga 1.179 for file in self.additional_inbox_files:
971 spiga 1.191 txt += 'mv $RUNTIME_AREA/'+os.path.basename(file)+' . \n'
972 ewv 1.170 txt += 'mv $RUNTIME_AREA/ProdCommon/ . \n'
973    
974 fanzago 1.166 txt += 'if [ -z "$PYTHONPATH" ]; then\n'
975     txt += ' export PYTHONPATH=$SOFTWARE_DIR/ProdCommon\n'
976     txt += 'else\n'
977     txt += ' export PYTHONPATH=$SOFTWARE_DIR/ProdCommon:${PYTHONPATH}\n'
978     txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
979     txt += 'fi\n'
980     txt += '\n'
981    
982     return txt
983 slacapra 1.1
984     def modifySteeringCards(self, nj):
985     """
986 ewv 1.131 modify the card provided by the user,
987 slacapra 1.1 writing a new card into share dir
988     """
989 ewv 1.131
990 slacapra 1.1 def executableName(self):
991 ewv 1.192 if self.scriptExe:
992 spiga 1.42 return "sh "
993     else:
994     return self.executable
995 slacapra 1.1
996     def executableArgs(self):
997 ewv 1.160 # FUTURE: This function tests the CMSSW version. Can be simplified as we drop support for old versions
998 slacapra 1.70 if self.scriptExe:#CarlosDaniele
999 spiga 1.42 return self.scriptExe + " $NJob"
1000 fanzago 1.115 else:
1001 ewv 1.160 ex_args = ""
1002 ewv 1.171 # FUTURE: This tests the CMSSW version. Can remove code as versions deprecated
1003 ewv 1.160 # Framework job report
1004 ewv 1.184 if (self.CMSSW_major >= 1 and self.CMSSW_minor >= 5) or (self.CMSSW_major >= 2):
1005 fanzago 1.166 ex_args += " -j $RUNTIME_AREA/crab_fjr_$NJob.xml"
1006 ewv 1.184 # Type of config file
1007     if self.CMSSW_major >= 2 :
1008 ewv 1.171 ex_args += " -p pset.py"
1009 fanzago 1.115 else:
1010 ewv 1.160 ex_args += " -p pset.cfg"
1011     return ex_args
1012 slacapra 1.1
1013     def inputSandbox(self, nj):
1014     """
1015     Returns a list of filenames to be put in JDL input sandbox.
1016     """
1017     inp_box = []
1018     if os.path.isfile(self.tgzNameWithPath):
1019     inp_box.append(self.tgzNameWithPath)
1020 spiga 1.168 wrapper = os.path.basename(str(common._db.queryTask('scriptName')))
1021     inp_box.append(common.work_space.pathForTgz() +'job/'+ wrapper)
1022 slacapra 1.1 return inp_box
1023    
1024     def outputSandbox(self, nj):
1025     """
1026     Returns a list of filenames to be put in JDL output sandbox.
1027     """
1028     out_box = []
1029    
1030     ## User Declared output files
1031 slacapra 1.54 for out in (self.output_file+self.output_file_sandbox):
1032 ewv 1.131 n_out = nj + 1
1033 slacapra 1.207 out_box.append(numberFile(out,str(n_out)))
1034 slacapra 1.1 return out_box
1035    
1036     def prepareSteeringCards(self):
1037     """
1038     Make initial modifications of the user's steering card file.
1039     """
1040     return
1041    
1042     def wsRenameOutput(self, nj):
1043     """
1044     Returns part of a job script which renames the produced files.
1045     """
1046    
1047 ewv 1.160 txt = '\n#Written by cms_cmssw::wsRenameOutput\n'
1048 fanzago 1.148 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
1049     txt += 'echo ">>> current directory content:"\n'
1050 spiga 1.199 if self.debug_wrapper:
1051     txt += 'ls -Al\n'
1052 fanzago 1.145 txt += '\n'
1053 slacapra 1.54
1054 fanzago 1.128 for fileWithSuffix in (self.output_file):
1055 slacapra 1.207 output_file_num = numberFile(fileWithSuffix, '$NJob')
1056 slacapra 1.1 txt += '\n'
1057 gutsche 1.7 txt += '# check output file\n'
1058 slacapra 1.106 txt += 'if [ -e ./'+fileWithSuffix+' ] ; then\n'
1059 ewv 1.147 if (self.copy_data == 1): # For OSG nodes, file is in $WORKING_DIR, should not be moved to $RUNTIME_AREA
1060     txt += ' mv '+fileWithSuffix+' '+output_file_num+'\n'
1061 ewv 1.198 #txt += ' ln -s `pwd`/'+output_file_num+' $RUNTIME_AREA/'+fileWithSuffix+'\n'
1062 ewv 1.147 else:
1063     txt += ' mv '+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
1064     txt += ' ln -s $RUNTIME_AREA/'+output_file_num+' $RUNTIME_AREA/'+fileWithSuffix+'\n'
1065 slacapra 1.106 txt += 'else\n'
1066 fanzago 1.161 txt += ' job_exit_code=60302\n'
1067     txt += ' echo "WARNING: Output file '+fileWithSuffix+' not found"\n'
1068 ewv 1.156 if common.scheduler.name().upper() == 'CONDOR_G':
1069 gutsche 1.7 txt += ' if [ $middleware == OSG ]; then \n'
1070     txt += ' echo "prepare dummy output file"\n'
1071     txt += ' echo "Processing of job output failed" > $RUNTIME_AREA/'+output_file_num+'\n'
1072     txt += ' fi \n'
1073 slacapra 1.1 txt += 'fi\n'
1074 slacapra 1.105 file_list = []
1075     for fileWithSuffix in (self.output_file):
1076 slacapra 1.207 file_list.append(numberFile(fileWithSuffix, '$NJob'))
1077 ewv 1.131
1078 slacapra 1.105 txt += 'file_list="'+string.join(file_list,' ')+'"\n'
1079 fanzago 1.149 txt += '\n'
1080 fanzago 1.148 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
1081     txt += 'echo ">>> current directory content:"\n'
1082 spiga 1.199 if self.debug_wrapper:
1083     txt += 'ls -Al\n'
1084 fanzago 1.148 txt += '\n'
1085 gutsche 1.7 txt += 'cd $RUNTIME_AREA\n'
1086 fanzago 1.133 txt += 'echo ">>> current directory (RUNTIME_AREA): $RUNTIME_AREA"\n'
1087 slacapra 1.1 return txt
1088    
1089 slacapra 1.63 def getRequirements(self, nj=[]):
1090 slacapra 1.1 """
1091 ewv 1.131 return job requirements to add to jdl files
1092 slacapra 1.1 """
1093     req = ''
1094 slacapra 1.47 if self.version:
1095 slacapra 1.10 req='Member("VO-cms-' + \
1096 slacapra 1.47 self.version + \
1097 slacapra 1.10 '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1098 ewv 1.192 if self.executable_arch:
1099 gutsche 1.107 req+=' && Member("VO-cms-' + \
1100 slacapra 1.105 self.executable_arch + \
1101     '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1102 gutsche 1.35
1103     req = req + ' && (other.GlueHostNetworkAdapterOutboundIP)'
1104 afanfani 1.158 if common.scheduler.name() == "glitecoll":
1105     req += ' && other.GlueCEStateStatus == "Production" '
1106 gutsche 1.35
1107 slacapra 1.1 return req
1108 gutsche 1.3
1109     def configFilename(self):
1110     """ return the config filename """
1111 ewv 1.182 # FUTURE: Can remove cfg mode for CMSSW >= 2_1_x
1112 ewv 1.184 if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
1113 ewv 1.182 return self.name()+'.py'
1114     else:
1115     return self.name()+'.cfg'
1116 gutsche 1.3
1117     def wsSetupCMSOSGEnvironment_(self):
1118     """
1119     Returns part of a job script which is prepares
1120     the execution environment and which is common for all CMS jobs.
1121     """
1122 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupCMSOSGEnvironment_\n'
1123     txt += ' echo ">>> setup CMS OSG environment:"\n'
1124 fanzago 1.133 txt += ' echo "set SCRAM ARCH to ' + self.executable_arch + '"\n'
1125     txt += ' export SCRAM_ARCH='+self.executable_arch+'\n'
1126 fanzago 1.136 txt += ' echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
1127 ewv 1.135 txt += ' if [ -f $OSG_APP/cmssoft/cms/cmsset_default.sh ] ;then\n'
1128 mkirn 1.40 txt += ' # Use $OSG_APP/cmssoft/cms/cmsset_default.sh to setup cms software\n'
1129 fanzago 1.133 txt += ' source $OSG_APP/cmssoft/cms/cmsset_default.sh '+self.version+'\n'
1130     txt += ' else\n'
1131 fanzago 1.161 txt += ' echo "ERROR ==> $OSG_APP/cmssoft/cms/cmsset_default.sh file not found"\n'
1132     txt += ' job_exit_code=10020\n'
1133     txt += ' func_exit\n'
1134 fanzago 1.133 txt += ' fi\n'
1135 gutsche 1.3 txt += '\n'
1136 fanzago 1.161 txt += ' echo "==> setup cms environment ok"\n'
1137 fanzago 1.136 txt += ' echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
1138 gutsche 1.3
1139     return txt
1140 ewv 1.131
1141 gutsche 1.3 def wsSetupCMSLCGEnvironment_(self):
1142     """
1143     Returns part of a job script which is prepares
1144     the execution environment and which is common for all CMS jobs.
1145     """
1146 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupCMSLCGEnvironment_\n'
1147     txt += ' echo ">>> setup CMS LCG environment:"\n'
1148 fanzago 1.133 txt += ' echo "set SCRAM ARCH and BUILD_ARCH to ' + self.executable_arch + ' ###"\n'
1149     txt += ' export SCRAM_ARCH='+self.executable_arch+'\n'
1150     txt += ' export BUILD_ARCH='+self.executable_arch+'\n'
1151     txt += ' if [ ! $VO_CMS_SW_DIR ] ;then\n'
1152 fanzago 1.161 txt += ' echo "ERROR ==> CMS software dir not found on WN `hostname`"\n'
1153     txt += ' job_exit_code=10031\n'
1154     txt += ' func_exit\n'
1155 fanzago 1.133 txt += ' else\n'
1156     txt += ' echo "Sourcing environment... "\n'
1157     txt += ' if [ ! -s $VO_CMS_SW_DIR/cmsset_default.sh ] ;then\n'
1158 fanzago 1.161 txt += ' echo "ERROR ==> cmsset_default.sh file not found into dir $VO_CMS_SW_DIR"\n'
1159     txt += ' job_exit_code=10020\n'
1160     txt += ' func_exit\n'
1161 fanzago 1.133 txt += ' fi\n'
1162     txt += ' echo "sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1163     txt += ' source $VO_CMS_SW_DIR/cmsset_default.sh\n'
1164     txt += ' result=$?\n'
1165     txt += ' if [ $result -ne 0 ]; then\n'
1166 fanzago 1.161 txt += ' echo "ERROR ==> problem sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1167     txt += ' job_exit_code=10032\n'
1168     txt += ' func_exit\n'
1169 fanzago 1.133 txt += ' fi\n'
1170     txt += ' fi\n'
1171     txt += ' \n'
1172 fanzago 1.161 txt += ' echo "==> setup cms environment ok"\n'
1173 gutsche 1.3 return txt
1174 gutsche 1.5
1175 fanzago 1.93 def modifyReport(self, nj):
1176     """
1177 ewv 1.131 insert the part of the script that modifies the FrameworkJob Report
1178 fanzago 1.93 """
1179 ewv 1.160 txt = '\n#Written by cms_cmssw::modifyReport\n'
1180 slacapra 1.176 publish_data = int(self.cfg_params.get('USER.publish_data',0))
1181 ewv 1.131 if (publish_data == 1):
1182 fanzago 1.94 processedDataset = self.cfg_params['USER.publish_data_name']
1183 fanzago 1.173 LFNBaseName = LFNBase(processedDataset)
1184 fanzago 1.175
1185     txt += 'if [ $copy_exit_status -eq 0 ]; then\n'
1186 fanzago 1.173 txt += ' FOR_LFN=%s_${PSETHASH}/\n'%(LFNBaseName)
1187 fanzago 1.175 txt += 'else\n'
1188     txt += ' FOR_LFN=/copy_problems/ \n'
1189     txt += ' SE=""\n'
1190     txt += ' SE_PATH=""\n'
1191     txt += 'fi\n'
1192 ewv 1.182
1193 fanzago 1.175 txt += 'echo ">>> Modify Job Report:" \n'
1194     txt += 'chmod a+x $SOFTWARE_DIR/ProdCommon/ProdCommon/FwkJobRep/ModifyJobReport.py\n'
1195     txt += 'ProcessedDataset='+processedDataset+'\n'
1196     txt += 'echo "ProcessedDataset = $ProcessedDataset"\n'
1197     txt += 'echo "SE = $SE"\n'
1198     txt += 'echo "SE_PATH = $SE_PATH"\n'
1199     txt += 'echo "FOR_LFN = $FOR_LFN" \n'
1200     txt += 'echo "CMSSW_VERSION = $CMSSW_VERSION"\n\n'
1201     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'
1202     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'
1203     txt += 'modifyReport_result=$?\n'
1204     txt += 'if [ $modifyReport_result -ne 0 ]; then\n'
1205     txt += ' modifyReport_result=70500\n'
1206     txt += ' job_exit_code=$modifyReport_result\n'
1207     txt += ' echo "ModifyReportResult=$modifyReport_result" | tee -a $RUNTIME_AREA/$repo\n'
1208     txt += ' echo "WARNING: Problem with ModifyJobReport"\n'
1209     txt += 'else\n'
1210     txt += ' mv NewFrameworkJobReport.xml $RUNTIME_AREA/crab_fjr_$NJob.xml\n'
1211 spiga 1.103 txt += 'fi\n'
1212 fanzago 1.93 return txt
1213 fanzago 1.99
1214 ewv 1.192 def wsParseFJR(self):
1215 spiga 1.189 """
1216 ewv 1.192 Parse the FrameworkJobReport to obtain useful infos
1217 spiga 1.189 """
1218     txt = '\n#Written by cms_cmssw::wsParseFJR\n'
1219     txt += 'echo ">>> Parse FrameworkJobReport crab_fjr.xml"\n'
1220     txt += 'if [ -s $RUNTIME_AREA/crab_fjr_$NJob.xml ]; then\n'
1221     txt += ' if [ -s $RUNTIME_AREA/parseCrabFjr.py ]; then\n'
1222 spiga 1.197 txt += ' cmd_out=`python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --dashboard $MonitorID,$MonitorJobID '+self.debugWrap+'`\n'
1223     if self.debug_wrapper :
1224     txt += ' echo "Result of parsing the FrameworkJobReport crab_fjr.xml: $cmd_out"\n'
1225     txt += ' executable_exit_status=`python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --exitcode`\n'
1226 spiga 1.189 txt += ' if [ $executable_exit_status -eq 50115 ];then\n'
1227     txt += ' echo ">>> crab_fjr.xml contents: "\n'
1228     txt += ' cat $RUNTIME_AREA/crab_fjr_NJob.xml\n'
1229     txt += ' echo "Wrong FrameworkJobReport --> does not contain useful info. ExitStatus: $executable_exit_status"\n'
1230 spiga 1.197 txt += ' elif [ $executable_exit_status -eq -999 ];then\n'
1231     txt += ' echo "ExitStatus from FrameworkJobReport not available. not available. Using exit code of executable from command line."\n'
1232 spiga 1.189 txt += ' else\n'
1233     txt += ' echo "Extracted ExitStatus from FrameworkJobReport parsing output: $executable_exit_status"\n'
1234     txt += ' fi\n'
1235     txt += ' else\n'
1236     txt += ' echo "CRAB python script to parse CRAB FrameworkJobReport crab_fjr.xml is not available, using exit code of executable from command line."\n'
1237     txt += ' fi\n'
1238     #### Patch to check input data reading for CMSSW16x Hopefully we-ll remove it asap
1239    
1240     if self.datasetPath:
1241     # VERIFY PROCESSED DATA
1242     txt += ' if [ $executable_exit_status -eq 0 ];then\n'
1243     txt += ' echo ">>> Verify list of processed files:"\n'
1244 ewv 1.196 txt += ' echo $InputFiles |tr -d \'\\\\\' |tr \',\' \'\\n\'|tr -d \'"\' > input-files.txt\n'
1245 spiga 1.200 txt += ' python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --lfn > processed-files.txt\n'
1246 spiga 1.189 txt += ' cat input-files.txt | sort | uniq > tmp.txt\n'
1247     txt += ' mv tmp.txt input-files.txt\n'
1248     txt += ' echo "cat input-files.txt"\n'
1249     txt += ' echo "----------------------"\n'
1250     txt += ' cat input-files.txt\n'
1251     txt += ' cat processed-files.txt | sort | uniq > tmp.txt\n'
1252     txt += ' mv tmp.txt processed-files.txt\n'
1253     txt += ' echo "----------------------"\n'
1254     txt += ' echo "cat processed-files.txt"\n'
1255     txt += ' echo "----------------------"\n'
1256     txt += ' cat processed-files.txt\n'
1257     txt += ' echo "----------------------"\n'
1258     txt += ' diff -q input-files.txt processed-files.txt\n'
1259     txt += ' fileverify_status=$?\n'
1260     txt += ' if [ $fileverify_status -ne 0 ]; then\n'
1261     txt += ' executable_exit_status=30001\n'
1262     txt += ' echo "ERROR ==> not all input files processed"\n'
1263     txt += ' echo " ==> list of processed files from crab_fjr.xml differs from list in pset.cfg"\n'
1264     txt += ' echo " ==> diff input-files.txt processed-files.txt"\n'
1265     txt += ' fi\n'
1266     txt += ' fi\n'
1267     txt += '\n'
1268     txt += 'else\n'
1269     txt += ' echo "CRAB FrameworkJobReport crab_fjr.xml is not available, using exit code of executable from command line."\n'
1270     txt += 'fi\n'
1271     txt += '\n'
1272     txt += 'echo "ExeExitCode=$executable_exit_status" | tee -a $RUNTIME_AREA/$repo\n'
1273     txt += 'echo "EXECUTABLE_EXIT_STATUS = $executable_exit_status"\n'
1274     txt += 'job_exit_code=$executable_exit_status\n'
1275    
1276     return txt
1277    
1278 gutsche 1.5 def setParam_(self, param, value):
1279     self._params[param] = value
1280    
1281     def getParams(self):
1282     return self._params
1283 gutsche 1.8
1284 gutsche 1.35 def uniquelist(self, old):
1285     """
1286     remove duplicates from a list
1287     """
1288     nd={}
1289     for e in old:
1290     nd[e]=0
1291     return nd.keys()
1292 mcinquil 1.121
1293 spiga 1.169 def outList(self):
1294 mcinquil 1.121 """
1295     check the dimension of the output files
1296     """
1297 spiga 1.169 txt = ''
1298     txt += 'echo ">>> list of expected files on output sandbox"\n'
1299 mcinquil 1.121 listOutFiles = []
1300 ewv 1.170 stdout = 'CMSSW_$NJob.stdout'
1301 spiga 1.169 stderr = 'CMSSW_$NJob.stderr'
1302 fanzago 1.148 if (self.return_data == 1):
1303 spiga 1.157 for file in (self.output_file+self.output_file_sandbox):
1304 slacapra 1.207 listOutFiles.append(numberFile(file, '$NJob'))
1305 spiga 1.169 listOutFiles.append(stdout)
1306     listOutFiles.append(stderr)
1307 ewv 1.156 else:
1308 spiga 1.157 for file in (self.output_file_sandbox):
1309 slacapra 1.207 listOutFiles.append(numberFile(file, '$NJob'))
1310 spiga 1.169 listOutFiles.append(stdout)
1311     listOutFiles.append(stderr)
1312 fanzago 1.161 txt += 'echo "output files: '+string.join(listOutFiles,' ')+'"\n'
1313 spiga 1.157 txt += 'filesToCheck="'+string.join(listOutFiles,' ')+'"\n'
1314 spiga 1.169 txt += 'export filesToCheck\n'
1315 ewv 1.170 return txt