ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.219
Committed: Mon Jun 16 15:35:53 2008 UTC (16 years, 10 months ago) by slacapra
Content type: text/x-python
Branch: MAIN
Changes since 1.218: +1 -1 lines
Log Message:
allow automatical addition of EDM output file produced via PoolOutputModule to the list of output_files.

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.212 except tarfile.TarError:
810 slacapra 1.206 raise CrabException('Could not create tar-ball '+self.tgzNameWithPath)
811 gutsche 1.72
812     ## check for tarball size
813     tarballinfo = os.stat(self.tgzNameWithPath)
814     if ( tarballinfo.st_size > self.MaxTarBallSize*1024*1024 ) :
815     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.')
816    
817 slacapra 1.61 ## create tar-ball with ML stuff
818 slacapra 1.97
819 spiga 1.165 def wsSetupEnvironment(self, nj=0):
820 slacapra 1.1 """
821     Returns part of a job script which prepares
822     the execution environment for the job 'nj'.
823     """
824 ewv 1.184 if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
825     psetName = 'pset.py'
826     else:
827     psetName = 'pset.cfg'
828 slacapra 1.1 # Prepare JobType-independent part
829 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupEnvironment\n'
830 fanzago 1.133 txt += 'echo ">>> setup environment"\n'
831 ewv 1.131 txt += 'if [ $middleware == LCG ]; then \n'
832 gutsche 1.3 txt += self.wsSetupCMSLCGEnvironment_()
833     txt += 'elif [ $middleware == OSG ]; then\n'
834 gutsche 1.43 txt += ' WORKING_DIR=`/bin/mktemp -d $OSG_WN_TMP/cms_XXXXXXXXXXXX`\n'
835 ewv 1.132 txt += ' if [ ! $? == 0 ] ;then\n'
836 fanzago 1.161 txt += ' echo "ERROR ==> OSG $WORKING_DIR could not be created on WN `hostname`"\n'
837     txt += ' job_exit_code=10016\n'
838     txt += ' func_exit\n'
839 gutsche 1.3 txt += ' fi\n'
840 fanzago 1.133 txt += ' echo ">>> Created working directory: $WORKING_DIR"\n'
841 gutsche 1.3 txt += '\n'
842     txt += ' echo "Change to working directory: $WORKING_DIR"\n'
843     txt += ' cd $WORKING_DIR\n'
844 fanzago 1.133 txt += ' echo ">>> current directory (WORKING_DIR): $WORKING_DIR"\n'
845 ewv 1.131 txt += self.wsSetupCMSOSGEnvironment_()
846 gutsche 1.3 txt += 'fi\n'
847 slacapra 1.1
848     # Prepare JobType-specific part
849     scram = self.scram.commandName()
850     txt += '\n\n'
851 fanzago 1.133 txt += 'echo ">>> specific cmssw setup environment:"\n'
852     txt += 'echo "CMSSW_VERSION = '+self.version+'"\n'
853 slacapra 1.1 txt += scram+' project CMSSW '+self.version+'\n'
854     txt += 'status=$?\n'
855     txt += 'if [ $status != 0 ] ; then\n'
856 fanzago 1.161 txt += ' echo "ERROR ==> CMSSW '+self.version+' not found on `hostname`" \n'
857     txt += ' job_exit_code=10034\n'
858 fanzago 1.163 txt += ' func_exit\n'
859 slacapra 1.1 txt += 'fi \n'
860     txt += 'cd '+self.version+'\n'
861 fanzago 1.99 txt += 'SOFTWARE_DIR=`pwd`\n'
862 fanzago 1.133 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
863 slacapra 1.1 txt += 'eval `'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME`\n'
864 fanzago 1.180 txt += 'if [ $? != 0 ] ; then\n'
865     txt += ' echo "ERROR ==> Problem with the command: "\n'
866     txt += ' echo "eval \`'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME \` at `hostname`"\n'
867     txt += ' job_exit_code=10034\n'
868     txt += ' func_exit\n'
869     txt += 'fi \n'
870 slacapra 1.1 # Handle the arguments:
871     txt += "\n"
872 gutsche 1.7 txt += "## number of arguments (first argument always jobnumber)\n"
873 slacapra 1.1 txt += "\n"
874 spiga 1.165 txt += "if [ $nargs -lt "+str(self.argsList)+" ]\n"
875 slacapra 1.1 txt += "then\n"
876 fanzago 1.161 txt += " echo 'ERROR ==> Too few arguments' +$nargs+ \n"
877     txt += ' job_exit_code=50113\n'
878     txt += " func_exit\n"
879 slacapra 1.1 txt += "fi\n"
880     txt += "\n"
881    
882     # Prepare job-specific part
883     job = common.job_list[nj]
884 ewv 1.131 if (self.datasetPath):
885 fanzago 1.93 txt += '\n'
886     txt += 'DatasetPath='+self.datasetPath+'\n'
887    
888     datasetpath_split = self.datasetPath.split("/")
889 ewv 1.131
890 fanzago 1.93 txt += 'PrimaryDataset='+datasetpath_split[1]+'\n'
891     txt += 'DataTier='+datasetpath_split[2]+'\n'
892 fanzago 1.96 txt += 'ApplicationFamily=cmsRun\n'
893 fanzago 1.93
894     else:
895     txt += 'DatasetPath=MCDataTier\n'
896     txt += 'PrimaryDataset=null\n'
897     txt += 'DataTier=null\n'
898     txt += 'ApplicationFamily=MCDataTier\n'
899 ewv 1.170 if self.pset != None:
900 spiga 1.42 pset = os.path.basename(job.configFilename())
901     txt += '\n'
902 spiga 1.95 txt += 'cp $RUNTIME_AREA/'+pset+' .\n'
903 spiga 1.42 if (self.datasetPath): # standard job
904 ewv 1.160 txt += 'InputFiles=${args[1]}; export InputFiles\n'
905 spiga 1.204 if (self.useParent):
906     txt += 'ParentFiles=${args[2]}; export ParentFiles\n'
907     txt += 'MaxEvents=${args[3]}; export MaxEvents\n'
908     txt += 'SkipEvents=${args[4]}; export SkipEvents\n'
909     else:
910     txt += 'MaxEvents=${args[2]}; export MaxEvents\n'
911     txt += 'SkipEvents=${args[3]}; export SkipEvents\n'
912 spiga 1.42 txt += 'echo "Inputfiles:<$InputFiles>"\n'
913 spiga 1.204 if (self.useParent): txt += 'echo "ParentFiles:<$ParentFiles>"\n'
914 spiga 1.42 txt += 'echo "MaxEvents:<$MaxEvents>"\n'
915     txt += 'echo "SkipEvents:<$SkipEvents>"\n'
916     else: # pythia like job
917 ewv 1.160 txt += 'PreserveSeeds=' + ','.join(self.preserveSeeds) + '; export PreserveSeeds\n'
918     txt += 'IncrementSeeds=' + ','.join(self.incrementSeeds) + '; export IncrementSeeds\n'
919     txt += 'echo "PreserveSeeds: <$PreserveSeeds>"\n'
920     txt += 'echo "IncrementSeeds:<$IncrementSeeds>"\n'
921 slacapra 1.90 if (self.firstRun):
922 ewv 1.160 txt += 'FirstRun=${args[1]}; export FirstRun\n'
923 spiga 1.57 txt += 'echo "FirstRun: <$FirstRun>"\n'
924 slacapra 1.90
925 ewv 1.184 txt += 'mv -f ' + pset + ' ' + psetName + '\n'
926 slacapra 1.1
927    
928 fanzago 1.163 if self.pset != None:
929 ewv 1.184 # FUTURE: Can simply for 2_1_x and higher
930 spiga 1.42 txt += '\n'
931 spiga 1.197 if self.debug_wrapper==True:
932 spiga 1.188 txt += 'echo "***** cat ' + psetName + ' *********"\n'
933     txt += 'cat ' + psetName + '\n'
934     txt += 'echo "****** end ' + psetName + ' ********"\n'
935     txt += '\n'
936 ewv 1.184 txt += 'PSETHASH=`edmConfigHash < ' + psetName + '` \n'
937 fanzago 1.94 txt += 'echo "PSETHASH = $PSETHASH" \n'
938 fanzago 1.93 txt += '\n'
939 gutsche 1.3 return txt
940 slacapra 1.176
941 fanzago 1.166 def wsUntarSoftware(self, nj=0):
942 gutsche 1.3 """
943     Put in the script the commands to build an executable
944     or a library.
945     """
946    
947 fanzago 1.166 txt = '\n#Written by cms_cmssw::wsUntarSoftware\n'
948 gutsche 1.3
949     if os.path.isfile(self.tgzNameWithPath):
950 fanzago 1.133 txt += 'echo ">>> tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+' :" \n'
951 gutsche 1.3 txt += 'tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'\n'
952 spiga 1.199 if self.debug_wrapper:
953     txt += 'ls -Al \n'
954 gutsche 1.3 txt += 'untar_status=$? \n'
955     txt += 'if [ $untar_status -ne 0 ]; then \n'
956 fanzago 1.161 txt += ' echo "ERROR ==> Untarring .tgz file failed"\n'
957     txt += ' job_exit_code=$untar_status\n'
958     txt += ' func_exit\n'
959 gutsche 1.3 txt += 'else \n'
960     txt += ' echo "Successful untar" \n'
961     txt += 'fi \n'
962 gutsche 1.50 txt += '\n'
963 slacapra 1.211 txt += 'echo ">>> Include $RUNTIME_AREA in PYTHONPATH:"\n'
964 gutsche 1.50 txt += 'if [ -z "$PYTHONPATH" ]; then\n'
965 slacapra 1.211 txt += ' export PYTHONPATH=$RUNTIME_AREA/\n'
966 gutsche 1.50 txt += 'else\n'
967 slacapra 1.211 txt += ' export PYTHONPATH=$RUNTIME_AREA/:${PYTHONPATH}\n'
968 fanzago 1.93 txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
969 gutsche 1.50 txt += 'fi\n'
970     txt += '\n'
971    
972 gutsche 1.3 pass
973 ewv 1.131
974 slacapra 1.1 return txt
975 ewv 1.170
976 fanzago 1.166 def wsBuildExe(self, nj=0):
977     """
978     Put in the script the commands to build an executable
979     or a library.
980     """
981    
982     txt = '\n#Written by cms_cmssw::wsBuildExe\n'
983     txt += 'echo ">>> moving CMSSW software directories in `pwd`" \n'
984    
985 ewv 1.170 txt += 'rm -r lib/ module/ \n'
986     txt += 'mv $RUNTIME_AREA/lib/ . \n'
987     txt += 'mv $RUNTIME_AREA/module/ . \n'
988 spiga 1.186 if self.dataExist == True:
989     txt += 'rm -r src/ \n'
990     txt += 'mv $RUNTIME_AREA/src/ . \n'
991 ewv 1.182 if len(self.additional_inbox_files)>0:
992 spiga 1.179 for file in self.additional_inbox_files:
993 spiga 1.191 txt += 'mv $RUNTIME_AREA/'+os.path.basename(file)+' . \n'
994 slacapra 1.214 # txt += 'mv $RUNTIME_AREA/ProdCommon/ . \n'
995     # txt += 'mv $RUNTIME_AREA/IMProv/ . \n'
996 ewv 1.170
997 slacapra 1.211 txt += 'echo ">>> Include $RUNTIME_AREA in PYTHONPATH:"\n'
998 fanzago 1.166 txt += 'if [ -z "$PYTHONPATH" ]; then\n'
999 slacapra 1.211 txt += ' export PYTHONPATH=$RUNTIME_AREA/\n'
1000 fanzago 1.166 txt += 'else\n'
1001 slacapra 1.211 txt += ' export PYTHONPATH=$RUNTIME_AREA/:${PYTHONPATH}\n'
1002 fanzago 1.166 txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
1003     txt += 'fi\n'
1004     txt += '\n'
1005    
1006     return txt
1007 slacapra 1.1
1008 ewv 1.131
1009 slacapra 1.1 def executableName(self):
1010 ewv 1.192 if self.scriptExe:
1011 spiga 1.42 return "sh "
1012     else:
1013     return self.executable
1014 slacapra 1.1
1015     def executableArgs(self):
1016 ewv 1.160 # FUTURE: This function tests the CMSSW version. Can be simplified as we drop support for old versions
1017 slacapra 1.70 if self.scriptExe:#CarlosDaniele
1018 spiga 1.42 return self.scriptExe + " $NJob"
1019 fanzago 1.115 else:
1020 ewv 1.160 ex_args = ""
1021 ewv 1.171 # FUTURE: This tests the CMSSW version. Can remove code as versions deprecated
1022 ewv 1.160 # Framework job report
1023 ewv 1.184 if (self.CMSSW_major >= 1 and self.CMSSW_minor >= 5) or (self.CMSSW_major >= 2):
1024 fanzago 1.166 ex_args += " -j $RUNTIME_AREA/crab_fjr_$NJob.xml"
1025 ewv 1.184 # Type of config file
1026     if self.CMSSW_major >= 2 :
1027 ewv 1.171 ex_args += " -p pset.py"
1028 fanzago 1.115 else:
1029 ewv 1.160 ex_args += " -p pset.cfg"
1030     return ex_args
1031 slacapra 1.1
1032     def inputSandbox(self, nj):
1033     """
1034     Returns a list of filenames to be put in JDL input sandbox.
1035     """
1036     inp_box = []
1037     if os.path.isfile(self.tgzNameWithPath):
1038     inp_box.append(self.tgzNameWithPath)
1039 spiga 1.168 wrapper = os.path.basename(str(common._db.queryTask('scriptName')))
1040     inp_box.append(common.work_space.pathForTgz() +'job/'+ wrapper)
1041 slacapra 1.1 return inp_box
1042    
1043     def outputSandbox(self, nj):
1044     """
1045     Returns a list of filenames to be put in JDL output sandbox.
1046     """
1047     out_box = []
1048    
1049     ## User Declared output files
1050 slacapra 1.54 for out in (self.output_file+self.output_file_sandbox):
1051 ewv 1.131 n_out = nj + 1
1052 slacapra 1.207 out_box.append(numberFile(out,str(n_out)))
1053 slacapra 1.1 return out_box
1054    
1055    
1056     def wsRenameOutput(self, nj):
1057     """
1058     Returns part of a job script which renames the produced files.
1059     """
1060    
1061 ewv 1.160 txt = '\n#Written by cms_cmssw::wsRenameOutput\n'
1062 fanzago 1.148 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
1063     txt += 'echo ">>> current directory content:"\n'
1064 spiga 1.199 if self.debug_wrapper:
1065     txt += 'ls -Al\n'
1066 fanzago 1.145 txt += '\n'
1067 slacapra 1.54
1068 fanzago 1.128 for fileWithSuffix in (self.output_file):
1069 slacapra 1.207 output_file_num = numberFile(fileWithSuffix, '$NJob')
1070 slacapra 1.1 txt += '\n'
1071 gutsche 1.7 txt += '# check output file\n'
1072 slacapra 1.106 txt += 'if [ -e ./'+fileWithSuffix+' ] ; then\n'
1073 ewv 1.147 if (self.copy_data == 1): # For OSG nodes, file is in $WORKING_DIR, should not be moved to $RUNTIME_AREA
1074     txt += ' mv '+fileWithSuffix+' '+output_file_num+'\n'
1075 spiga 1.209 txt += ' ln -s `pwd`/'+output_file_num+' $RUNTIME_AREA/'+fileWithSuffix+'\n'
1076 ewv 1.147 else:
1077     txt += ' mv '+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
1078     txt += ' ln -s $RUNTIME_AREA/'+output_file_num+' $RUNTIME_AREA/'+fileWithSuffix+'\n'
1079 slacapra 1.106 txt += 'else\n'
1080 fanzago 1.161 txt += ' job_exit_code=60302\n'
1081     txt += ' echo "WARNING: Output file '+fileWithSuffix+' not found"\n'
1082 ewv 1.156 if common.scheduler.name().upper() == 'CONDOR_G':
1083 gutsche 1.7 txt += ' if [ $middleware == OSG ]; then \n'
1084     txt += ' echo "prepare dummy output file"\n'
1085     txt += ' echo "Processing of job output failed" > $RUNTIME_AREA/'+output_file_num+'\n'
1086     txt += ' fi \n'
1087 slacapra 1.1 txt += 'fi\n'
1088 slacapra 1.105 file_list = []
1089     for fileWithSuffix in (self.output_file):
1090 slacapra 1.207 file_list.append(numberFile(fileWithSuffix, '$NJob'))
1091 ewv 1.131
1092 slacapra 1.105 txt += 'file_list="'+string.join(file_list,' ')+'"\n'
1093 fanzago 1.149 txt += '\n'
1094 fanzago 1.148 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
1095     txt += 'echo ">>> current directory content:"\n'
1096 spiga 1.199 if self.debug_wrapper:
1097     txt += 'ls -Al\n'
1098 fanzago 1.148 txt += '\n'
1099 gutsche 1.7 txt += 'cd $RUNTIME_AREA\n'
1100 fanzago 1.133 txt += 'echo ">>> current directory (RUNTIME_AREA): $RUNTIME_AREA"\n'
1101 slacapra 1.1 return txt
1102    
1103 slacapra 1.63 def getRequirements(self, nj=[]):
1104 slacapra 1.1 """
1105 ewv 1.131 return job requirements to add to jdl files
1106 slacapra 1.1 """
1107     req = ''
1108 slacapra 1.47 if self.version:
1109 slacapra 1.10 req='Member("VO-cms-' + \
1110 slacapra 1.47 self.version + \
1111 slacapra 1.10 '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1112 ewv 1.192 if self.executable_arch:
1113 gutsche 1.107 req+=' && Member("VO-cms-' + \
1114 slacapra 1.105 self.executable_arch + \
1115     '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1116 gutsche 1.35
1117     req = req + ' && (other.GlueHostNetworkAdapterOutboundIP)'
1118 afanfani 1.158 if common.scheduler.name() == "glitecoll":
1119     req += ' && other.GlueCEStateStatus == "Production" '
1120 gutsche 1.35
1121 slacapra 1.1 return req
1122 gutsche 1.3
1123     def configFilename(self):
1124     """ return the config filename """
1125 ewv 1.182 # FUTURE: Can remove cfg mode for CMSSW >= 2_1_x
1126 ewv 1.184 if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
1127 ewv 1.182 return self.name()+'.py'
1128     else:
1129     return self.name()+'.cfg'
1130 gutsche 1.3
1131     def wsSetupCMSOSGEnvironment_(self):
1132     """
1133     Returns part of a job script which is prepares
1134     the execution environment and which is common for all CMS jobs.
1135     """
1136 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupCMSOSGEnvironment_\n'
1137     txt += ' echo ">>> setup CMS OSG environment:"\n'
1138 fanzago 1.133 txt += ' echo "set SCRAM ARCH to ' + self.executable_arch + '"\n'
1139     txt += ' export SCRAM_ARCH='+self.executable_arch+'\n'
1140 fanzago 1.136 txt += ' echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
1141 ewv 1.135 txt += ' if [ -f $OSG_APP/cmssoft/cms/cmsset_default.sh ] ;then\n'
1142 mkirn 1.40 txt += ' # Use $OSG_APP/cmssoft/cms/cmsset_default.sh to setup cms software\n'
1143 fanzago 1.133 txt += ' source $OSG_APP/cmssoft/cms/cmsset_default.sh '+self.version+'\n'
1144     txt += ' else\n'
1145 fanzago 1.161 txt += ' echo "ERROR ==> $OSG_APP/cmssoft/cms/cmsset_default.sh file not found"\n'
1146     txt += ' job_exit_code=10020\n'
1147     txt += ' func_exit\n'
1148 fanzago 1.133 txt += ' fi\n'
1149 gutsche 1.3 txt += '\n'
1150 fanzago 1.161 txt += ' echo "==> setup cms environment ok"\n'
1151 fanzago 1.136 txt += ' echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
1152 gutsche 1.3
1153     return txt
1154 ewv 1.131
1155 gutsche 1.3 def wsSetupCMSLCGEnvironment_(self):
1156     """
1157     Returns part of a job script which is prepares
1158     the execution environment and which is common for all CMS jobs.
1159     """
1160 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupCMSLCGEnvironment_\n'
1161     txt += ' echo ">>> setup CMS LCG environment:"\n'
1162 fanzago 1.133 txt += ' echo "set SCRAM ARCH and BUILD_ARCH to ' + self.executable_arch + ' ###"\n'
1163     txt += ' export SCRAM_ARCH='+self.executable_arch+'\n'
1164     txt += ' export BUILD_ARCH='+self.executable_arch+'\n'
1165     txt += ' if [ ! $VO_CMS_SW_DIR ] ;then\n'
1166 fanzago 1.161 txt += ' echo "ERROR ==> CMS software dir not found on WN `hostname`"\n'
1167     txt += ' job_exit_code=10031\n'
1168     txt += ' func_exit\n'
1169 fanzago 1.133 txt += ' else\n'
1170     txt += ' echo "Sourcing environment... "\n'
1171     txt += ' if [ ! -s $VO_CMS_SW_DIR/cmsset_default.sh ] ;then\n'
1172 fanzago 1.161 txt += ' echo "ERROR ==> cmsset_default.sh file not found into dir $VO_CMS_SW_DIR"\n'
1173     txt += ' job_exit_code=10020\n'
1174     txt += ' func_exit\n'
1175 fanzago 1.133 txt += ' fi\n'
1176     txt += ' echo "sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1177     txt += ' source $VO_CMS_SW_DIR/cmsset_default.sh\n'
1178     txt += ' result=$?\n'
1179     txt += ' if [ $result -ne 0 ]; then\n'
1180 fanzago 1.161 txt += ' echo "ERROR ==> problem sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1181     txt += ' job_exit_code=10032\n'
1182     txt += ' func_exit\n'
1183 fanzago 1.133 txt += ' fi\n'
1184     txt += ' fi\n'
1185     txt += ' \n'
1186 fanzago 1.161 txt += ' echo "==> setup cms environment ok"\n'
1187 gutsche 1.3 return txt
1188 gutsche 1.5
1189 fanzago 1.93 def modifyReport(self, nj):
1190     """
1191 ewv 1.131 insert the part of the script that modifies the FrameworkJob Report
1192 fanzago 1.93 """
1193 ewv 1.160 txt = '\n#Written by cms_cmssw::modifyReport\n'
1194 slacapra 1.176 publish_data = int(self.cfg_params.get('USER.publish_data',0))
1195 ewv 1.131 if (publish_data == 1):
1196 fanzago 1.94 processedDataset = self.cfg_params['USER.publish_data_name']
1197 fanzago 1.173 LFNBaseName = LFNBase(processedDataset)
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     txt += ' cat $RUNTIME_AREA/crab_fjr_NJob.xml\n'
1243     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     if self.datasetPath:
1255     # 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