ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.232
Committed: Mon Aug 25 16:50:23 2008 UTC (16 years, 8 months ago) by spiga
Content type: text/x-python
Branch: MAIN
CVS Tags: CRAB_2_3_2_pre4
Changes since 1.231: +7 -3 lines
Log Message:
wrapper exit if cmsRun fails. bug #39675

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 ewv 1.228 from BlackWhiteListParser import SEBlackWhiteListParser
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 ewv 1.228 self.blackWhiteListParser = SEBlackWhiteListParser(cfg_params)
24 fanzago 1.115
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 fanzago 1.230 ### FEDE FOR NEW LFN ###
880     self.primaryDataset = datasetpath_split[1]
881     ########################
882 fanzago 1.93 txt += 'PrimaryDataset='+datasetpath_split[1]+'\n'
883     txt += 'DataTier='+datasetpath_split[2]+'\n'
884 fanzago 1.96 txt += 'ApplicationFamily=cmsRun\n'
885 fanzago 1.93
886     else:
887     txt += 'DatasetPath=MCDataTier\n'
888 fanzago 1.230 ### FEDE FOR NEW LFN ###
889     self.primaryDataset = 'null'
890     ########################
891 fanzago 1.93 txt += 'PrimaryDataset=null\n'
892     txt += 'DataTier=null\n'
893     txt += 'ApplicationFamily=MCDataTier\n'
894 ewv 1.170 if self.pset != None:
895 spiga 1.42 pset = os.path.basename(job.configFilename())
896     txt += '\n'
897 spiga 1.95 txt += 'cp $RUNTIME_AREA/'+pset+' .\n'
898 spiga 1.42 if (self.datasetPath): # standard job
899 ewv 1.160 txt += 'InputFiles=${args[1]}; export InputFiles\n'
900 ewv 1.226 if (self.useParent):
901 spiga 1.204 txt += 'ParentFiles=${args[2]}; export ParentFiles\n'
902     txt += 'MaxEvents=${args[3]}; export MaxEvents\n'
903     txt += 'SkipEvents=${args[4]}; export SkipEvents\n'
904     else:
905     txt += 'MaxEvents=${args[2]}; export MaxEvents\n'
906     txt += 'SkipEvents=${args[3]}; export SkipEvents\n'
907 spiga 1.42 txt += 'echo "Inputfiles:<$InputFiles>"\n'
908 spiga 1.204 if (self.useParent): txt += 'echo "ParentFiles:<$ParentFiles>"\n'
909 spiga 1.42 txt += 'echo "MaxEvents:<$MaxEvents>"\n'
910     txt += 'echo "SkipEvents:<$SkipEvents>"\n'
911     else: # pythia like job
912 ewv 1.160 txt += 'PreserveSeeds=' + ','.join(self.preserveSeeds) + '; export PreserveSeeds\n'
913     txt += 'IncrementSeeds=' + ','.join(self.incrementSeeds) + '; export IncrementSeeds\n'
914     txt += 'echo "PreserveSeeds: <$PreserveSeeds>"\n'
915     txt += 'echo "IncrementSeeds:<$IncrementSeeds>"\n'
916 slacapra 1.90 if (self.firstRun):
917 ewv 1.160 txt += 'FirstRun=${args[1]}; export FirstRun\n'
918 spiga 1.57 txt += 'echo "FirstRun: <$FirstRun>"\n'
919 slacapra 1.90
920 ewv 1.184 txt += 'mv -f ' + pset + ' ' + psetName + '\n'
921 slacapra 1.1
922    
923 fanzago 1.163 if self.pset != None:
924 ewv 1.184 # FUTURE: Can simply for 2_1_x and higher
925 spiga 1.42 txt += '\n'
926 spiga 1.197 if self.debug_wrapper==True:
927 spiga 1.188 txt += 'echo "***** cat ' + psetName + ' *********"\n'
928     txt += 'cat ' + psetName + '\n'
929     txt += 'echo "****** end ' + psetName + ' ********"\n'
930     txt += '\n'
931 ewv 1.226 if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
932     txt += 'PSETHASH=`edmConfigHash ' + psetName + '` \n'
933     else:
934     txt += 'PSETHASH=`edmConfigHash < ' + psetName + '` \n'
935 fanzago 1.94 txt += 'echo "PSETHASH = $PSETHASH" \n'
936 fanzago 1.93 txt += '\n'
937 gutsche 1.3 return txt
938 slacapra 1.176
939 fanzago 1.166 def wsUntarSoftware(self, nj=0):
940 gutsche 1.3 """
941     Put in the script the commands to build an executable
942     or a library.
943     """
944    
945 fanzago 1.166 txt = '\n#Written by cms_cmssw::wsUntarSoftware\n'
946 gutsche 1.3
947     if os.path.isfile(self.tgzNameWithPath):
948 fanzago 1.133 txt += 'echo ">>> tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+' :" \n'
949 gutsche 1.3 txt += 'tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'\n'
950 spiga 1.199 if self.debug_wrapper:
951     txt += 'ls -Al \n'
952 gutsche 1.3 txt += 'untar_status=$? \n'
953     txt += 'if [ $untar_status -ne 0 ]; then \n'
954 fanzago 1.161 txt += ' echo "ERROR ==> Untarring .tgz file failed"\n'
955     txt += ' job_exit_code=$untar_status\n'
956     txt += ' func_exit\n'
957 gutsche 1.3 txt += 'else \n'
958     txt += ' echo "Successful untar" \n'
959     txt += 'fi \n'
960 gutsche 1.50 txt += '\n'
961 slacapra 1.211 txt += 'echo ">>> Include $RUNTIME_AREA in PYTHONPATH:"\n'
962 gutsche 1.50 txt += 'if [ -z "$PYTHONPATH" ]; then\n'
963 slacapra 1.211 txt += ' export PYTHONPATH=$RUNTIME_AREA/\n'
964 gutsche 1.50 txt += 'else\n'
965 slacapra 1.211 txt += ' export PYTHONPATH=$RUNTIME_AREA/:${PYTHONPATH}\n'
966 fanzago 1.93 txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
967 gutsche 1.50 txt += 'fi\n'
968     txt += '\n'
969    
970 gutsche 1.3 pass
971 ewv 1.131
972 slacapra 1.1 return txt
973 ewv 1.170
974 fanzago 1.166 def wsBuildExe(self, nj=0):
975     """
976     Put in the script the commands to build an executable
977     or a library.
978     """
979    
980     txt = '\n#Written by cms_cmssw::wsBuildExe\n'
981     txt += 'echo ">>> moving CMSSW software directories in `pwd`" \n'
982    
983 ewv 1.170 txt += 'rm -r lib/ module/ \n'
984     txt += 'mv $RUNTIME_AREA/lib/ . \n'
985     txt += 'mv $RUNTIME_AREA/module/ . \n'
986 spiga 1.186 if self.dataExist == True:
987     txt += 'rm -r src/ \n'
988     txt += 'mv $RUNTIME_AREA/src/ . \n'
989 ewv 1.182 if len(self.additional_inbox_files)>0:
990 spiga 1.179 for file in self.additional_inbox_files:
991 spiga 1.191 txt += 'mv $RUNTIME_AREA/'+os.path.basename(file)+' . \n'
992 slacapra 1.214 # txt += 'mv $RUNTIME_AREA/ProdCommon/ . \n'
993     # txt += 'mv $RUNTIME_AREA/IMProv/ . \n'
994 ewv 1.170
995 slacapra 1.211 txt += 'echo ">>> Include $RUNTIME_AREA in PYTHONPATH:"\n'
996 fanzago 1.166 txt += 'if [ -z "$PYTHONPATH" ]; then\n'
997 slacapra 1.211 txt += ' export PYTHONPATH=$RUNTIME_AREA/\n'
998 fanzago 1.166 txt += 'else\n'
999 slacapra 1.211 txt += ' export PYTHONPATH=$RUNTIME_AREA/:${PYTHONPATH}\n'
1000 fanzago 1.166 txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
1001     txt += 'fi\n'
1002     txt += '\n'
1003    
1004     return txt
1005 slacapra 1.1
1006 ewv 1.131
1007 slacapra 1.1 def executableName(self):
1008 ewv 1.192 if self.scriptExe:
1009 spiga 1.42 return "sh "
1010     else:
1011     return self.executable
1012 slacapra 1.1
1013     def executableArgs(self):
1014 ewv 1.160 # FUTURE: This function tests the CMSSW version. Can be simplified as we drop support for old versions
1015 slacapra 1.70 if self.scriptExe:#CarlosDaniele
1016 spiga 1.42 return self.scriptExe + " $NJob"
1017 fanzago 1.115 else:
1018 ewv 1.160 ex_args = ""
1019 ewv 1.171 # FUTURE: This tests the CMSSW version. Can remove code as versions deprecated
1020 ewv 1.160 # Framework job report
1021 ewv 1.184 if (self.CMSSW_major >= 1 and self.CMSSW_minor >= 5) or (self.CMSSW_major >= 2):
1022 fanzago 1.166 ex_args += " -j $RUNTIME_AREA/crab_fjr_$NJob.xml"
1023 ewv 1.184 # Type of config file
1024     if self.CMSSW_major >= 2 :
1025 ewv 1.171 ex_args += " -p pset.py"
1026 fanzago 1.115 else:
1027 ewv 1.160 ex_args += " -p pset.cfg"
1028     return ex_args
1029 slacapra 1.1
1030     def inputSandbox(self, nj):
1031     """
1032     Returns a list of filenames to be put in JDL input sandbox.
1033     """
1034     inp_box = []
1035     if os.path.isfile(self.tgzNameWithPath):
1036     inp_box.append(self.tgzNameWithPath)
1037 spiga 1.168 wrapper = os.path.basename(str(common._db.queryTask('scriptName')))
1038     inp_box.append(common.work_space.pathForTgz() +'job/'+ wrapper)
1039 slacapra 1.1 return inp_box
1040    
1041     def outputSandbox(self, nj):
1042     """
1043     Returns a list of filenames to be put in JDL output sandbox.
1044     """
1045     out_box = []
1046    
1047     ## User Declared output files
1048 slacapra 1.54 for out in (self.output_file+self.output_file_sandbox):
1049 ewv 1.131 n_out = nj + 1
1050 slacapra 1.207 out_box.append(numberFile(out,str(n_out)))
1051 slacapra 1.1 return out_box
1052    
1053    
1054     def wsRenameOutput(self, nj):
1055     """
1056     Returns part of a job script which renames the produced files.
1057     """
1058    
1059 ewv 1.160 txt = '\n#Written by cms_cmssw::wsRenameOutput\n'
1060 fanzago 1.148 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
1061     txt += 'echo ">>> current directory content:"\n'
1062 ewv 1.226 if self.debug_wrapper:
1063 spiga 1.199 txt += 'ls -Al\n'
1064 fanzago 1.145 txt += '\n'
1065 slacapra 1.54
1066 fanzago 1.128 for fileWithSuffix in (self.output_file):
1067 slacapra 1.207 output_file_num = numberFile(fileWithSuffix, '$NJob')
1068 slacapra 1.1 txt += '\n'
1069 gutsche 1.7 txt += '# check output file\n'
1070 slacapra 1.106 txt += 'if [ -e ./'+fileWithSuffix+' ] ; then\n'
1071 ewv 1.147 if (self.copy_data == 1): # For OSG nodes, file is in $WORKING_DIR, should not be moved to $RUNTIME_AREA
1072     txt += ' mv '+fileWithSuffix+' '+output_file_num+'\n'
1073 spiga 1.209 txt += ' ln -s `pwd`/'+output_file_num+' $RUNTIME_AREA/'+fileWithSuffix+'\n'
1074 ewv 1.147 else:
1075     txt += ' mv '+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
1076     txt += ' ln -s $RUNTIME_AREA/'+output_file_num+' $RUNTIME_AREA/'+fileWithSuffix+'\n'
1077 slacapra 1.106 txt += 'else\n'
1078 fanzago 1.161 txt += ' job_exit_code=60302\n'
1079     txt += ' echo "WARNING: Output file '+fileWithSuffix+' not found"\n'
1080 ewv 1.156 if common.scheduler.name().upper() == 'CONDOR_G':
1081 gutsche 1.7 txt += ' if [ $middleware == OSG ]; then \n'
1082     txt += ' echo "prepare dummy output file"\n'
1083     txt += ' echo "Processing of job output failed" > $RUNTIME_AREA/'+output_file_num+'\n'
1084     txt += ' fi \n'
1085 slacapra 1.1 txt += 'fi\n'
1086 slacapra 1.105 file_list = []
1087     for fileWithSuffix in (self.output_file):
1088 slacapra 1.207 file_list.append(numberFile(fileWithSuffix, '$NJob'))
1089 ewv 1.131
1090 slacapra 1.105 txt += 'file_list="'+string.join(file_list,' ')+'"\n'
1091 fanzago 1.149 txt += '\n'
1092 fanzago 1.148 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
1093     txt += 'echo ">>> current directory content:"\n'
1094 ewv 1.226 if self.debug_wrapper:
1095 spiga 1.199 txt += 'ls -Al\n'
1096 fanzago 1.148 txt += '\n'
1097 gutsche 1.7 txt += 'cd $RUNTIME_AREA\n'
1098 fanzago 1.133 txt += 'echo ">>> current directory (RUNTIME_AREA): $RUNTIME_AREA"\n'
1099 slacapra 1.1 return txt
1100    
1101 slacapra 1.63 def getRequirements(self, nj=[]):
1102 slacapra 1.1 """
1103 ewv 1.131 return job requirements to add to jdl files
1104 slacapra 1.1 """
1105     req = ''
1106 slacapra 1.47 if self.version:
1107 slacapra 1.10 req='Member("VO-cms-' + \
1108 slacapra 1.47 self.version + \
1109 slacapra 1.10 '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1110 ewv 1.192 if self.executable_arch:
1111 gutsche 1.107 req+=' && Member("VO-cms-' + \
1112 slacapra 1.105 self.executable_arch + \
1113     '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1114 gutsche 1.35
1115     req = req + ' && (other.GlueHostNetworkAdapterOutboundIP)'
1116 afanfani 1.229 if ( common.scheduler.name() == "glitecoll" ) or ( common.scheduler.name() == "glite"):
1117 afanfani 1.158 req += ' && other.GlueCEStateStatus == "Production" '
1118 gutsche 1.35
1119 slacapra 1.1 return req
1120 gutsche 1.3
1121     def configFilename(self):
1122     """ return the config filename """
1123 ewv 1.182 # FUTURE: Can remove cfg mode for CMSSW >= 2_1_x
1124 ewv 1.184 if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
1125 ewv 1.182 return self.name()+'.py'
1126     else:
1127     return self.name()+'.cfg'
1128 gutsche 1.3
1129     def wsSetupCMSOSGEnvironment_(self):
1130     """
1131     Returns part of a job script which is prepares
1132     the execution environment and which is common for all CMS jobs.
1133     """
1134 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupCMSOSGEnvironment_\n'
1135     txt += ' echo ">>> setup CMS OSG environment:"\n'
1136 fanzago 1.133 txt += ' echo "set SCRAM ARCH to ' + self.executable_arch + '"\n'
1137     txt += ' export SCRAM_ARCH='+self.executable_arch+'\n'
1138 fanzago 1.136 txt += ' echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
1139 ewv 1.135 txt += ' if [ -f $OSG_APP/cmssoft/cms/cmsset_default.sh ] ;then\n'
1140 mkirn 1.40 txt += ' # Use $OSG_APP/cmssoft/cms/cmsset_default.sh to setup cms software\n'
1141 fanzago 1.133 txt += ' source $OSG_APP/cmssoft/cms/cmsset_default.sh '+self.version+'\n'
1142     txt += ' else\n'
1143 fanzago 1.161 txt += ' echo "ERROR ==> $OSG_APP/cmssoft/cms/cmsset_default.sh file not found"\n'
1144     txt += ' job_exit_code=10020\n'
1145     txt += ' func_exit\n'
1146 fanzago 1.133 txt += ' fi\n'
1147 gutsche 1.3 txt += '\n'
1148 fanzago 1.161 txt += ' echo "==> setup cms environment ok"\n'
1149 fanzago 1.136 txt += ' echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
1150 gutsche 1.3
1151     return txt
1152 ewv 1.131
1153 gutsche 1.3 def wsSetupCMSLCGEnvironment_(self):
1154     """
1155     Returns part of a job script which is prepares
1156     the execution environment and which is common for all CMS jobs.
1157     """
1158 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupCMSLCGEnvironment_\n'
1159     txt += ' echo ">>> setup CMS LCG environment:"\n'
1160 fanzago 1.133 txt += ' echo "set SCRAM ARCH and BUILD_ARCH to ' + self.executable_arch + ' ###"\n'
1161     txt += ' export SCRAM_ARCH='+self.executable_arch+'\n'
1162     txt += ' export BUILD_ARCH='+self.executable_arch+'\n'
1163     txt += ' if [ ! $VO_CMS_SW_DIR ] ;then\n'
1164 fanzago 1.161 txt += ' echo "ERROR ==> CMS software dir not found on WN `hostname`"\n'
1165     txt += ' job_exit_code=10031\n'
1166     txt += ' func_exit\n'
1167 fanzago 1.133 txt += ' else\n'
1168     txt += ' echo "Sourcing environment... "\n'
1169     txt += ' if [ ! -s $VO_CMS_SW_DIR/cmsset_default.sh ] ;then\n'
1170 fanzago 1.161 txt += ' echo "ERROR ==> cmsset_default.sh file not found into dir $VO_CMS_SW_DIR"\n'
1171     txt += ' job_exit_code=10020\n'
1172     txt += ' func_exit\n'
1173 fanzago 1.133 txt += ' fi\n'
1174     txt += ' echo "sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1175     txt += ' source $VO_CMS_SW_DIR/cmsset_default.sh\n'
1176     txt += ' result=$?\n'
1177     txt += ' if [ $result -ne 0 ]; then\n'
1178 fanzago 1.161 txt += ' echo "ERROR ==> problem sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1179     txt += ' job_exit_code=10032\n'
1180     txt += ' func_exit\n'
1181 fanzago 1.133 txt += ' fi\n'
1182     txt += ' fi\n'
1183     txt += ' \n'
1184 fanzago 1.161 txt += ' echo "==> setup cms environment ok"\n'
1185 gutsche 1.3 return txt
1186 gutsche 1.5
1187 fanzago 1.93 def modifyReport(self, nj):
1188     """
1189 ewv 1.131 insert the part of the script that modifies the FrameworkJob Report
1190 fanzago 1.93 """
1191 ewv 1.160 txt = '\n#Written by cms_cmssw::modifyReport\n'
1192 slacapra 1.176 publish_data = int(self.cfg_params.get('USER.publish_data',0))
1193 ewv 1.131 if (publish_data == 1):
1194 fanzago 1.94 processedDataset = self.cfg_params['USER.publish_data_name']
1195 fanzago 1.230 if (self.primaryDataset == 'null'):
1196     self.primaryDataset = processedDataset
1197 fanzago 1.225 if (common.scheduler.name().upper() == "CAF" or common.scheduler.name().upper() == "LSF"):
1198 fanzago 1.230 ### FEDE FOR NEW LFN ###
1199     LFNBaseName = LFNBase(self.primaryDataset, processedDataset, LocalUser=True)
1200     self.user = getUserName(LocalUser=True)
1201     ########################
1202 ewv 1.227 else :
1203 fanzago 1.230 ### FEDE FOR NEW LFN ###
1204     LFNBaseName = LFNBase(self.primaryDataset, processedDataset)
1205     self.user = getUserName()
1206     ########################
1207 fanzago 1.175
1208     txt += 'if [ $copy_exit_status -eq 0 ]; then\n'
1209 fanzago 1.230 ### FEDE FOR NEW LFN ###
1210     #txt += ' FOR_LFN=%s_${PSETHASH}/\n'%(LFNBaseName)
1211     txt += ' FOR_LFN=%s/${PSETHASH}/\n'%(LFNBaseName)
1212     ########################
1213 fanzago 1.175 txt += 'else\n'
1214     txt += ' FOR_LFN=/copy_problems/ \n'
1215     txt += ' SE=""\n'
1216     txt += ' SE_PATH=""\n'
1217     txt += 'fi\n'
1218 ewv 1.182
1219 fanzago 1.175 txt += 'echo ">>> Modify Job Report:" \n'
1220 fanzago 1.217 txt += 'chmod a+x $RUNTIME_AREA/ProdCommon/FwkJobRep/ModifyJobReport.py\n'
1221 fanzago 1.175 txt += 'ProcessedDataset='+processedDataset+'\n'
1222     txt += 'echo "ProcessedDataset = $ProcessedDataset"\n'
1223     txt += 'echo "SE = $SE"\n'
1224     txt += 'echo "SE_PATH = $SE_PATH"\n'
1225     txt += 'echo "FOR_LFN = $FOR_LFN" \n'
1226     txt += 'echo "CMSSW_VERSION = $CMSSW_VERSION"\n\n'
1227 fanzago 1.230 ### FEDE FOR NEW LFN ###
1228     txt += 'echo "$RUNTIME_AREA/ProdCommon/FwkJobRep/ModifyJobReport.py $RUNTIME_AREA/crab_fjr_$NJob.xml $NJob $FOR_LFN $PrimaryDataset $DataTier ' + self.user + '-$ProcessedDataset-$PSETHASH $ApplicationFamily $executable $CMSSW_VERSION $PSETHASH $SE $SE_PATH"\n'
1229     txt += '$RUNTIME_AREA/ProdCommon/FwkJobRep/ModifyJobReport.py $RUNTIME_AREA/crab_fjr_$NJob.xml $NJob $FOR_LFN $PrimaryDataset $DataTier ' + self.user + '-$ProcessedDataset-$PSETHASH $ApplicationFamily $executable $CMSSW_VERSION $PSETHASH $SE $SE_PATH\n'
1230     ########################
1231 fanzago 1.175 txt += 'modifyReport_result=$?\n'
1232     txt += 'if [ $modifyReport_result -ne 0 ]; then\n'
1233     txt += ' modifyReport_result=70500\n'
1234     txt += ' job_exit_code=$modifyReport_result\n'
1235     txt += ' echo "ModifyReportResult=$modifyReport_result" | tee -a $RUNTIME_AREA/$repo\n'
1236     txt += ' echo "WARNING: Problem with ModifyJobReport"\n'
1237     txt += 'else\n'
1238     txt += ' mv NewFrameworkJobReport.xml $RUNTIME_AREA/crab_fjr_$NJob.xml\n'
1239 spiga 1.103 txt += 'fi\n'
1240 fanzago 1.93 return txt
1241 fanzago 1.99
1242 ewv 1.192 def wsParseFJR(self):
1243 spiga 1.189 """
1244 ewv 1.192 Parse the FrameworkJobReport to obtain useful infos
1245 spiga 1.189 """
1246     txt = '\n#Written by cms_cmssw::wsParseFJR\n'
1247     txt += 'echo ">>> Parse FrameworkJobReport crab_fjr.xml"\n'
1248     txt += 'if [ -s $RUNTIME_AREA/crab_fjr_$NJob.xml ]; then\n'
1249     txt += ' if [ -s $RUNTIME_AREA/parseCrabFjr.py ]; then\n'
1250 spiga 1.197 txt += ' cmd_out=`python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --dashboard $MonitorID,$MonitorJobID '+self.debugWrap+'`\n'
1251     if self.debug_wrapper :
1252     txt += ' echo "Result of parsing the FrameworkJobReport crab_fjr.xml: $cmd_out"\n'
1253     txt += ' executable_exit_status=`python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --exitcode`\n'
1254 spiga 1.189 txt += ' if [ $executable_exit_status -eq 50115 ];then\n'
1255     txt += ' echo ">>> crab_fjr.xml contents: "\n'
1256 spiga 1.222 txt += ' cat $RUNTIME_AREA/crab_fjr_$NJob.xml\n'
1257 spiga 1.189 txt += ' echo "Wrong FrameworkJobReport --> does not contain useful info. ExitStatus: $executable_exit_status"\n'
1258 spiga 1.197 txt += ' elif [ $executable_exit_status -eq -999 ];then\n'
1259     txt += ' echo "ExitStatus from FrameworkJobReport not available. not available. Using exit code of executable from command line."\n'
1260 spiga 1.189 txt += ' else\n'
1261     txt += ' echo "Extracted ExitStatus from FrameworkJobReport parsing output: $executable_exit_status"\n'
1262     txt += ' fi\n'
1263     txt += ' else\n'
1264     txt += ' echo "CRAB python script to parse CRAB FrameworkJobReport crab_fjr.xml is not available, using exit code of executable from command line."\n'
1265     txt += ' fi\n'
1266     #### Patch to check input data reading for CMSSW16x Hopefully we-ll remove it asap
1267    
1268 spiga 1.232 txt += ' if [ $executable_exit_status -eq 0 ];then\n'
1269     txt += ' echo ">>> Executable succeded $executable_exit_status"\n'
1270 spiga 1.231 if (self.datasetPath and not (self.dataset_pu or self.useParent) :
1271 spiga 1.189 # VERIFY PROCESSED DATA
1272     txt += ' echo ">>> Verify list of processed files:"\n'
1273 ewv 1.196 txt += ' echo $InputFiles |tr -d \'\\\\\' |tr \',\' \'\\n\'|tr -d \'"\' > input-files.txt\n'
1274 spiga 1.200 txt += ' python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --lfn > processed-files.txt\n'
1275 spiga 1.189 txt += ' cat input-files.txt | sort | uniq > tmp.txt\n'
1276     txt += ' mv tmp.txt input-files.txt\n'
1277     txt += ' echo "cat input-files.txt"\n'
1278     txt += ' echo "----------------------"\n'
1279     txt += ' cat input-files.txt\n'
1280     txt += ' cat processed-files.txt | sort | uniq > tmp.txt\n'
1281     txt += ' mv tmp.txt processed-files.txt\n'
1282     txt += ' echo "----------------------"\n'
1283     txt += ' echo "cat processed-files.txt"\n'
1284     txt += ' echo "----------------------"\n'
1285     txt += ' cat processed-files.txt\n'
1286     txt += ' echo "----------------------"\n'
1287     txt += ' diff -q input-files.txt processed-files.txt\n'
1288     txt += ' fileverify_status=$?\n'
1289     txt += ' if [ $fileverify_status -ne 0 ]; then\n'
1290     txt += ' executable_exit_status=30001\n'
1291     txt += ' echo "ERROR ==> not all input files processed"\n'
1292     txt += ' echo " ==> list of processed files from crab_fjr.xml differs from list in pset.cfg"\n'
1293     txt += ' echo " ==> diff input-files.txt processed-files.txt"\n'
1294     txt += ' fi\n'
1295 spiga 1.232 txt += ' elif [ $executable_exit_status -ne 0 ] || [ $executable_exit_status -ne 50015 ] || [ $executable_exit_status -ne 50017 ];then\n'
1296     txt += ' echo ">>> Executable failed $executable_exit_status"\n'
1297     txt += ' func_exit\n'
1298     txt += ' fi\n'
1299     txt += '\n'
1300 spiga 1.189 txt += 'else\n'
1301     txt += ' echo "CRAB FrameworkJobReport crab_fjr.xml is not available, using exit code of executable from command line."\n'
1302     txt += 'fi\n'
1303     txt += '\n'
1304     txt += 'echo "ExeExitCode=$executable_exit_status" | tee -a $RUNTIME_AREA/$repo\n'
1305     txt += 'echo "EXECUTABLE_EXIT_STATUS = $executable_exit_status"\n'
1306     txt += 'job_exit_code=$executable_exit_status\n'
1307    
1308     return txt
1309    
1310 gutsche 1.5 def setParam_(self, param, value):
1311     self._params[param] = value
1312    
1313     def getParams(self):
1314     return self._params
1315 gutsche 1.8
1316 gutsche 1.35 def uniquelist(self, old):
1317     """
1318     remove duplicates from a list
1319     """
1320     nd={}
1321     for e in old:
1322     nd[e]=0
1323     return nd.keys()
1324 mcinquil 1.121
1325 spiga 1.169 def outList(self):
1326 mcinquil 1.121 """
1327     check the dimension of the output files
1328     """
1329 spiga 1.169 txt = ''
1330     txt += 'echo ">>> list of expected files on output sandbox"\n'
1331 mcinquil 1.121 listOutFiles = []
1332 ewv 1.170 stdout = 'CMSSW_$NJob.stdout'
1333 spiga 1.169 stderr = 'CMSSW_$NJob.stderr'
1334 fanzago 1.148 if (self.return_data == 1):
1335 spiga 1.157 for file in (self.output_file+self.output_file_sandbox):
1336 slacapra 1.207 listOutFiles.append(numberFile(file, '$NJob'))
1337 spiga 1.169 listOutFiles.append(stdout)
1338     listOutFiles.append(stderr)
1339 ewv 1.156 else:
1340 spiga 1.157 for file in (self.output_file_sandbox):
1341 slacapra 1.207 listOutFiles.append(numberFile(file, '$NJob'))
1342 spiga 1.169 listOutFiles.append(stdout)
1343     listOutFiles.append(stderr)
1344 fanzago 1.161 txt += 'echo "output files: '+string.join(listOutFiles,' ')+'"\n'
1345 spiga 1.157 txt += 'filesToCheck="'+string.join(listOutFiles,' ')+'"\n'
1346 spiga 1.169 txt += 'export filesToCheck\n'
1347 ewv 1.170 return txt