ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.227
Committed: Wed Jul 9 16:16:50 2008 UTC (16 years, 9 months ago) by ewv
Content type: text/x-python
Branch: MAIN
Changes since 1.226: +8 -24 lines
Log Message:
Raise exception if old seed manipulation is attempted

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