ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.215
Committed: Wed Jun 11 17:55:30 2008 UTC (16 years, 10 months ago) by slacapra
Content type: text/x-python
Branch: MAIN
CVS Tags: CRAB_2_2_2_pre5
Changes since 1.214: +10 -1 lines
Log Message:
automatically add file produced via TFileService to list of output files if present

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