ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.216
Committed: Thu Jun 12 15:47:56 2008 UTC (16 years, 10 months ago) by mcinquil
Content type: text/x-python
Branch: MAIN
Changes since 1.215: +9 -3 lines
Log Message:
Correct print when output file is not in crab.cfg/TFileService

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