ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.220
Committed: Tue Jun 17 14:38:55 2008 UTC (16 years, 10 months ago) by slacapra
Content type: text/x-python
Branch: MAIN
Changes since 1.219: +2 -0 lines
Log Message:
add IOError to exception list while creating the tar-ball

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