ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.205
Committed: Thu Jun 5 16:34:04 2008 UTC (16 years, 10 months ago) by slacapra
Content type: text/x-python
Branch: MAIN
CVS Tags: CRAB_2_2_2_pre4
Changes since 1.204: +1 -1 lines
Log Message:
remove the double ProdCommon dirname

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