ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.10
Committed: Thu Jun 22 16:05:18 2006 UTC (18 years, 10 months ago) by slacapra
Content type: text/x-python
Branch: MAIN
CVS Tags: CRAB_1_2_0_pre7
Changes since 1.9: +54 -24 lines
Log Message:
support for None input

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     import common
6 gutsche 1.3 import PsetManipulator
7 slacapra 1.1
8 gutsche 1.3 import DBSInfo_EDM
9     import DataDiscovery_EDM
10     import DataLocation_EDM
11 slacapra 1.1 import Scram
12    
13     import os, string, re
14    
15     class Cmssw(JobType):
16     def __init__(self, cfg_params):
17     JobType.__init__(self, 'CMSSW')
18     common.logger.debug(3,'CMSSW::__init__')
19    
20     self.analisys_common_info = {}
21 gutsche 1.3 # Marco.
22     self._params = {}
23     self.cfg_params = cfg_params
24 slacapra 1.1 log = common.logger
25    
26     self.scram = Scram.Scram(cfg_params)
27     scramArea = ''
28     self.additional_inbox_files = []
29     self.scriptExe = ''
30     self.executable = ''
31     self.tgz_name = 'default.tgz'
32    
33 gutsche 1.3
34 slacapra 1.1 self.version = self.scram.getSWVersion()
35 gutsche 1.5 self.setParam_('application', self.version)
36 slacapra 1.1 common.analisys_common_info['sw_version'] = self.version
37 gutsche 1.3 ### FEDE
38     common.analisys_common_info['copy_input_data'] = 0
39     common.analisys_common_info['events_management'] = 1
40 slacapra 1.1
41     ### collect Data cards
42     try:
43 slacapra 1.9 tmp = cfg_params['CMSSW.datasetpath']
44     log.debug(6, "CMSSW::CMSSW(): datasetPath = "+tmp)
45     if string.lower(tmp)=='none':
46     self.datasetPath = None
47     else:
48     self.datasetPath = tmp
49 slacapra 1.1 except KeyError:
50 gutsche 1.3 msg = "Error: datasetpath not defined "
51 slacapra 1.1 raise CrabException(msg)
52 gutsche 1.5
53     # ML monitoring
54     # split dataset path style: /PreProdR3Minbias/SIM/GEN-SIM
55 slacapra 1.9 if not self.datasetPath:
56     self.setParam_('dataset', 'None')
57     self.setParam_('owner', 'None')
58     else:
59     datasetpath_split = self.datasetPath.split("/")
60     self.setParam_('dataset', datasetpath_split[1])
61     self.setParam_('owner', datasetpath_split[-1])
62    
63 gutsche 1.8 self.setTaskid_()
64     self.setParam_('taskId', self.cfg_params['taskId'])
65 gutsche 1.5
66 slacapra 1.1 self.dataTiers = []
67    
68     ## now the application
69     try:
70     self.executable = cfg_params['CMSSW.executable']
71 gutsche 1.5 self.setParam_('exe', self.executable)
72 slacapra 1.1 log.debug(6, "CMSSW::CMSSW(): executable = "+self.executable)
73     msg = "Default executable cmsRun overridden. Switch to " + self.executable
74     log.debug(3,msg)
75     except KeyError:
76     self.executable = 'cmsRun'
77 gutsche 1.5 self.setParam_('exe', self.executable)
78 slacapra 1.1 msg = "User executable not defined. Use cmsRun"
79     log.debug(3,msg)
80     pass
81    
82     try:
83     self.pset = cfg_params['CMSSW.pset']
84     log.debug(6, "Cmssw::Cmssw(): PSet file = "+self.pset)
85     if (not os.path.exists(self.pset)):
86     raise CrabException("User defined PSet file "+self.pset+" does not exist")
87     except KeyError:
88     raise CrabException("PSet file missing. Cannot run cmsRun ")
89    
90     # output files
91     try:
92     self.output_file = []
93    
94     tmp = cfg_params['CMSSW.output_file']
95     if tmp != '':
96     tmpOutFiles = string.split(cfg_params['CMSSW.output_file'],',')
97     log.debug(7, 'cmssw::cmssw(): output files '+str(tmpOutFiles))
98     for tmp in tmpOutFiles:
99     tmp=string.strip(tmp)
100     self.output_file.append(tmp)
101     pass
102     else:
103     log.message("No output file defined: only stdout/err will be available")
104     pass
105     pass
106     except KeyError:
107     log.message("No output file defined: only stdout/err will be available")
108     pass
109    
110     # script_exe file as additional file in inputSandbox
111     try:
112 slacapra 1.10 self.scriptExe = cfg_params['USER.script_exe']
113     self.additional_inbox_files.append(self.scriptExe)
114     if self.scriptExe != '':
115     if not os.path.isfile(self.scriptExe):
116     msg ="WARNING. file "+self.scriptExe+" not found"
117     raise CrabException(msg)
118 slacapra 1.1 except KeyError:
119     pass
120    
121     ## additional input files
122     try:
123     tmpAddFiles = string.split(cfg_params['CMSSW.additional_input_files'],',')
124     for tmp in tmpAddFiles:
125 gutsche 1.3 if not os.path.exists(tmp):
126     raise CrabException("Additional input file not found: "+tmp)
127 slacapra 1.1 tmp=string.strip(tmp)
128     self.additional_inbox_files.append(tmp)
129     pass
130     pass
131     except KeyError:
132     pass
133    
134 slacapra 1.9 # files per job
135 slacapra 1.1 try:
136 gutsche 1.3 self.filesPerJob = int(cfg_params['CMSSW.files_per_jobs']) #Daniele
137 slacapra 1.9 self.selectFilesPerJob = 1
138 gutsche 1.3 except KeyError:
139 slacapra 1.9 self.filesPerJob = 0
140     self.selectFilesPerJob = 0
141 gutsche 1.3
142 slacapra 1.9 ## Events per job
143 gutsche 1.3 try:
144 slacapra 1.10 self.eventsPerJob =int( cfg_params['CMSSW.events_per_job'])
145 slacapra 1.9 self.selectEventsPerJob = 1
146 gutsche 1.3 except KeyError:
147 slacapra 1.9 self.eventsPerJob = -1
148     self.selectEventsPerJob = 0
149    
150 slacapra 1.10 # To be implemented
151     # ## number of jobs
152     # try:
153     # self.numberOfJobs =int( cfg_params['CMSSW.number_of_job'])
154     # self.selectNumberOfJobs = 1
155     # except KeyError:
156     # self.selectNumberOfJobs = 0
157    
158 slacapra 1.9 if (self.selectFilesPerJob == self.selectEventsPerJob):
159 slacapra 1.10 msg = 'Must define either files_per_jobs or events_per_job'
160 slacapra 1.9 raise CrabException(msg)
161    
162 slacapra 1.10 if (self.selectEventsPerJob and not self.datasetPath == None):
163     msg = 'Splitting according to events_per_job available only with None as datasetpath'
164     raise CrabException(msg)
165    
166 gutsche 1.3 try:
167 slacapra 1.1 self.total_number_of_events = int(cfg_params['CMSSW.total_number_of_events'])
168     except KeyError:
169 gutsche 1.3 msg = 'Must define total_number_of_events'
170 slacapra 1.1 raise CrabException(msg)
171    
172     CEBlackList = []
173     try:
174     tmpBad = string.split(cfg_params['EDG.ce_black_list'],',')
175     for tmp in tmpBad:
176     tmp=string.strip(tmp)
177     CEBlackList.append(tmp)
178     except KeyError:
179     pass
180    
181     self.reCEBlackList=[]
182     for bad in CEBlackList:
183     self.reCEBlackList.append(re.compile( bad ))
184    
185     common.logger.debug(5,'CEBlackList: '+str(CEBlackList))
186    
187     CEWhiteList = []
188     try:
189     tmpGood = string.split(cfg_params['EDG.ce_white_list'],',')
190     for tmp in tmpGood:
191     tmp=string.strip(tmp)
192     CEWhiteList.append(tmp)
193     except KeyError:
194     pass
195    
196     #print 'CEWhiteList: ',CEWhiteList
197     self.reCEWhiteList=[]
198     for Good in CEWhiteList:
199     self.reCEWhiteList.append(re.compile( Good ))
200    
201     common.logger.debug(5,'CEWhiteList: '+str(CEWhiteList))
202    
203 gutsche 1.3 self.PsetEdit = PsetManipulator.PsetManipulator(self.pset) #Daniele Pset
204    
205 slacapra 1.1 #DBSDLS-start
206     ## Initialize the variables that are extracted from DBS/DLS and needed in other places of the code
207     self.maxEvents=0 # max events available ( --> check the requested nb. of evts in Creator.py)
208     self.DBSPaths={} # all dbs paths requested ( --> input to the site local discovery script)
209     ## Perform the data location and discovery (based on DBS/DLS)
210 slacapra 1.9 ## SL: Don't if NONE is specified as input (pythia use case)
211     common.analisys_common_info['sites']=None
212     if self.datasetPath:
213     self.DataDiscoveryAndLocation(cfg_params)
214 slacapra 1.1 #DBSDLS-end
215    
216     self.tgzNameWithPath = self.getTarBall(self.executable)
217    
218 slacapra 1.10 # modify Pset
219     if (self.datasetPath): # standard job
220     self.PsetEdit.maxEvent(self.eventsPerJob) #Daniele
221     self.PsetEdit.inputModule("INPUT") #Daniele
222    
223     else: # pythia like job
224     self.PsetEdit.maxEvent(self.eventsPerJob) #Daniele
225     self.PsetEdit.pythiaSeed("INPUT") #Daniele
226     try:
227     self.sourceSeed = int(cfg_params['CMSSW.pythia_seed'])
228     except KeyError:
229     self.sourceSeed = 123456
230     common.logger.message("No seed given, will use "+str(self.sourceSeed))
231    
232     self.PsetEdit.psetWriter(self.configFilename())
233    
234 slacapra 1.9 ## Select Splitting
235     if self.selectFilesPerJob: self.jobSplittingPerFiles()
236     elif self.selectEventsPerJob: self.jobSplittingPerEvents()
237     else:
238     msg = 'Don\'t know how to split...'
239     raise CrabException(msg)
240 gutsche 1.5
241 gutsche 1.3
242 slacapra 1.1 def DataDiscoveryAndLocation(self, cfg_params):
243    
244 gutsche 1.3 common.logger.debug(10,"CMSSW::DataDiscoveryAndLocation()")
245    
246     datasetPath=self.datasetPath
247    
248     ## TODO
249     dataTiersList = ""
250     dataTiers = dataTiersList.split(',')
251 slacapra 1.1
252     ## Contact the DBS
253     try:
254 afanfani 1.4 self.pubdata=DataDiscovery_EDM.DataDiscovery_EDM(datasetPath, dataTiers, cfg_params)
255 slacapra 1.1 self.pubdata.fetchDBSInfo()
256    
257 gutsche 1.3 except DataDiscovery_EDM.NotExistingDatasetError, ex :
258 slacapra 1.1 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
259     raise CrabException(msg)
260    
261 gutsche 1.3 except DataDiscovery_EDM.NoDataTierinProvenanceError, ex :
262 slacapra 1.1 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
263     raise CrabException(msg)
264 gutsche 1.3 except DataDiscovery_EDM.DataDiscoveryError, ex:
265 slacapra 1.1 msg = 'ERROR ***: failed Data Discovery in DBS %s'%ex.getErrorMessage()
266     raise CrabException(msg)
267    
268     ## get list of all required data in the form of dbs paths (dbs path = /dataset/datatier/owner)
269 gutsche 1.3 ## self.DBSPaths=self.pubdata.getDBSPaths()
270     common.logger.message("Required data are :"+self.datasetPath)
271    
272     filesbyblock=self.pubdata.getFiles()
273     self.AllInputFiles=filesbyblock.values()
274     self.files = self.AllInputFiles
275    
276     ## TEMP
277     # self.filesTmp = filesbyblock.values()
278     # self.files = []
279     # locPath='rfio:cmsbose2.bo.infn.it:/flatfiles/SE00/cms/fanfani/ProdTest/'
280     # locPath=''
281     # tmp = []
282     # for file in self.filesTmp[0]:
283     # tmp.append(locPath+file)
284     # self.files.append(tmp)
285     ## END TEMP
286 slacapra 1.1
287     ## get max number of events
288 gutsche 1.3 #common.logger.debug(10,"number of events for primary fileblocks %i"%self.pubdata.getMaxEvents())
289 slacapra 1.1 self.maxEvents=self.pubdata.getMaxEvents() ## self.maxEvents used in Creator.py
290     common.logger.message("\nThe number of available events is %s"%self.maxEvents)
291    
292     ## Contact the DLS and build a list of sites hosting the fileblocks
293     try:
294 gutsche 1.6 dataloc=DataLocation_EDM.DataLocation_EDM(filesbyblock.keys(),cfg_params)
295     dataloc.fetchDLSInfo()
296 gutsche 1.3 except DataLocation_EDM.DataLocationError , ex:
297 slacapra 1.1 msg = 'ERROR ***: failed Data Location in DLS \n %s '%ex.getErrorMessage()
298     raise CrabException(msg)
299    
300     allsites=dataloc.getSites()
301     common.logger.debug(5,"sites are %s"%allsites)
302     sites=self.checkBlackList(allsites)
303     common.logger.debug(5,"sites are (after black list) %s"%sites)
304     sites=self.checkWhiteList(sites)
305     common.logger.debug(5,"sites are (after white list) %s"%sites)
306    
307     if len(sites)==0:
308     msg = 'No sites hosting all the needed data! Exiting... '
309     raise CrabException(msg)
310 gutsche 1.3
311 slacapra 1.1 common.logger.message("List of Sites hosting the data : "+str(sites))
312     common.logger.debug(6, "List of Sites: "+str(sites))
313     common.analisys_common_info['sites']=sites ## used in SchedulerEdg.py in createSchScript
314 gutsche 1.5 self.setParam_('TargetCE', ','.join(sites))
315 slacapra 1.1 return
316 gutsche 1.3
317 slacapra 1.9 def jobSplittingPerFiles(self):
318     """
319     Perform job splitting based on number of files to be accessed per job
320 gutsche 1.3 """
321 slacapra 1.9 common.logger.debug(5,'Splitting per input files')
322 gutsche 1.3 common.logger.message('Required '+str(self.filesPerJob)+' files per job ')
323     common.logger.message('Required '+str(self.total_number_of_events)+' events in total ')
324    
325     ## TODO: SL need to have (from DBS) a detailed list of how many events per each file
326     n_tot_files = (len(self.files[0]))
327     ## SL: this is wrong if the files have different number of events
328     evPerFile = int(self.maxEvents)/n_tot_files
329    
330     common.logger.debug(5,'Events per File '+str(evPerFile))
331    
332     ## if asked to process all events, do it
333     if self.total_number_of_events == -1:
334     self.total_number_of_events=self.maxEvents
335     self.total_number_of_jobs = int(n_tot_files)*1/int(self.filesPerJob)
336     common.logger.message(str(self.total_number_of_jobs)+' jobs will be created for all available events '+str(self.total_number_of_events)+' events')
337    
338     else:
339     self.total_number_of_files = int(self.total_number_of_events/evPerFile)
340     ## SL: if ask for less event than what is computed to be available on a
341     ## file, process the first file anyhow.
342     if self.total_number_of_files == 0:
343     self.total_number_of_files = self.total_number_of_files + 1
344    
345     common.logger.debug(5,'N files '+str(self.total_number_of_files))
346    
347     check = 0
348    
349     ## Compute the number of jobs
350     #self.total_number_of_jobs = int(n_tot_files)*1/int(self.filesPerJob)
351     self.total_number_of_jobs = int(self.total_number_of_files/self.filesPerJob)
352     common.logger.debug(5,'N jobs '+str(self.total_number_of_jobs))
353    
354     ## is there any remainder?
355     check = int(self.total_number_of_files) - (int(self.total_number_of_jobs)*self.filesPerJob)
356    
357     common.logger.debug(5,'Check '+str(check))
358    
359     if check > 0:
360     self.total_number_of_jobs = self.total_number_of_jobs + 1
361     common.logger.message('Warning: last job will be created with '+str(check)+' files')
362    
363     common.logger.message(str(self.total_number_of_jobs)+' jobs will be created for a total of '+str((self.total_number_of_jobs-1)*self.filesPerJob*evPerFile + check*evPerFile)+' events')
364     pass
365    
366     list_of_lists = []
367     for i in xrange(0, int(n_tot_files), self.filesPerJob):
368 slacapra 1.9 parString = "\\{"
369    
370     params = self.files[0][i: i+self.filesPerJob]
371     for i in range(len(params) - 1):
372     parString += '\\\"' + params[i] + '\\\"\,'
373    
374     parString += '\\\"' + params[len(params) - 1] + '\\\"\\}'
375     list_of_lists.append(parString)
376     pass
377    
378     self.list_of_args = list_of_lists
379     print self.list_of_args
380     return
381    
382     def jobSplittingPerEvents(self):
383     """
384     Perform job splitting based on number of event per job
385     """
386     common.logger.debug(5,'Splitting per events')
387     common.logger.message('Required '+str(self.eventsPerJob)+' events per job ')
388     common.logger.message('Required '+str(self.total_number_of_events)+' events in total ')
389    
390 slacapra 1.10 if (self.total_number_of_events < 0):
391     msg='Cannot split jobs per Events with "-1" as total number of events'
392     raise CrabException(msg)
393    
394 slacapra 1.9 self.total_number_of_jobs = int(self.total_number_of_events/self.eventsPerJob)
395    
396     common.logger.debug(5,'N jobs '+str(self.total_number_of_jobs))
397    
398     # is there any remainder?
399     check = int(self.total_number_of_events) - (int(self.total_number_of_jobs)*self.eventsPerJob)
400    
401     common.logger.debug(5,'Check '+str(check))
402    
403     if check > 0:
404     common.logger.message('Warning: asked '+self.total_number_of_events+' but will do only '+(int(self.total_number_of_jobs)*self.eventsPerJob))
405    
406     common.logger.message(str(self.total_number_of_jobs)+' jobs will be created for a total of '+str(self.total_number_of_jobs*self.eventsPerJob)+' events')
407    
408 slacapra 1.10 # argument is seed number.$i
409 slacapra 1.9 self.list_of_args = []
410     for i in range(self.total_number_of_jobs):
411 slacapra 1.10 self.list_of_args.append(int(str(self.sourceSeed)+str(i)))
412 slacapra 1.9 print self.list_of_args
413 gutsche 1.3
414     return
415    
416     def split(self, jobParams):
417    
418     common.jobDB.load()
419     #### Fabio
420     njobs = self.total_number_of_jobs
421 slacapra 1.9 arglist = self.list_of_args
422 gutsche 1.3 # create the empty structure
423     for i in range(njobs):
424     jobParams.append("")
425    
426     for job in range(njobs):
427 slacapra 1.9 jobParams[job] = str(arglist[job])
428 gutsche 1.3 common.jobDB.setArguments(job, jobParams[job])
429    
430     common.jobDB.save()
431     return
432    
433     def getJobTypeArguments(self, nj, sched):
434 slacapra 1.9 return common.jobDB.arguments(nj)
435 gutsche 1.3
436     def numberOfJobs(self):
437     # Fabio
438     return self.total_number_of_jobs
439    
440 slacapra 1.1 def checkBlackList(self, allSites):
441     if len(self.reCEBlackList)==0: return allSites
442     sites = []
443     for site in allSites:
444     common.logger.debug(10,'Site '+site)
445     good=1
446     for re in self.reCEBlackList:
447     if re.search(site):
448     common.logger.message('CE in black list, skipping site '+site)
449     good=0
450     pass
451     if good: sites.append(site)
452     if len(sites) == 0:
453     common.logger.debug(3,"No sites found after BlackList")
454     return sites
455    
456 gutsche 1.3 def checkWhiteList(self, allSites):
457 slacapra 1.1
458 gutsche 1.3 if len(self.reCEWhiteList)==0: return allSites
459 slacapra 1.1 sites = []
460 gutsche 1.3 for site in allSites:
461 slacapra 1.1 good=0
462     for re in self.reCEWhiteList:
463     if re.search(site):
464     common.logger.debug(5,'CE in white list, adding site '+site)
465     good=1
466     if not good: continue
467     sites.append(site)
468     if len(sites) == 0:
469     common.logger.message("No sites found after WhiteList\n")
470     else:
471     common.logger.debug(5,"Selected sites via WhiteList are "+str(sites)+"\n")
472     return sites
473    
474     def getTarBall(self, exe):
475     """
476     Return the TarBall with lib and exe
477     """
478    
479     # if it exist, just return it
480     self.tgzNameWithPath = common.work_space.shareDir()+self.tgz_name
481     if os.path.exists(self.tgzNameWithPath):
482     return self.tgzNameWithPath
483    
484     # Prepare a tar gzipped file with user binaries.
485     self.buildTar_(exe)
486    
487     return string.strip(self.tgzNameWithPath)
488    
489     def buildTar_(self, executable):
490    
491     # First of all declare the user Scram area
492     swArea = self.scram.getSWArea_()
493     #print "swArea = ", swArea
494     swVersion = self.scram.getSWVersion()
495     #print "swVersion = ", swVersion
496     swReleaseTop = self.scram.getReleaseTop_()
497     #print "swReleaseTop = ", swReleaseTop
498    
499     ## check if working area is release top
500     if swReleaseTop == '' or swArea == swReleaseTop:
501     return
502    
503     filesToBeTarred = []
504     ## First find the executable
505     if (self.executable != ''):
506     exeWithPath = self.scram.findFile_(executable)
507     # print exeWithPath
508     if ( not exeWithPath ):
509     raise CrabException('User executable '+executable+' not found')
510    
511     ## then check if it's private or not
512     if exeWithPath.find(swReleaseTop) == -1:
513     # the exe is private, so we must ship
514     common.logger.debug(5,"Exe "+exeWithPath+" to be tarred")
515     path = swArea+'/'
516     exe = string.replace(exeWithPath, path,'')
517     filesToBeTarred.append(exe)
518     pass
519     else:
520     # the exe is from release, we'll find it on WN
521     pass
522    
523     ## Now get the libraries: only those in local working area
524     libDir = 'lib'
525     lib = swArea+'/' +libDir
526     common.logger.debug(5,"lib "+lib+" to be tarred")
527     if os.path.exists(lib):
528     filesToBeTarred.append(libDir)
529    
530 gutsche 1.3 ## Now check if module dir is present
531     moduleDir = 'module'
532     if os.path.isdir(swArea+'/'+moduleDir):
533     filesToBeTarred.append(moduleDir)
534    
535 slacapra 1.1 ## Now check if the Data dir is present
536     dataDir = 'src/Data/'
537     if os.path.isdir(swArea+'/'+dataDir):
538     filesToBeTarred.append(dataDir)
539    
540     ## Create the tar-ball
541     if len(filesToBeTarred)>0:
542     cwd = os.getcwd()
543     os.chdir(swArea)
544     tarcmd = 'tar zcvf ' + self.tgzNameWithPath + ' '
545     for line in filesToBeTarred:
546     tarcmd = tarcmd + line + ' '
547     cout = runCommand(tarcmd)
548     if not cout:
549     raise CrabException('Could not create tar-ball')
550     os.chdir(cwd)
551     else:
552     common.logger.debug(5,"No files to be to be tarred")
553    
554     return
555    
556     def wsSetupEnvironment(self, nj):
557     """
558     Returns part of a job script which prepares
559     the execution environment for the job 'nj'.
560     """
561     # Prepare JobType-independent part
562 gutsche 1.3 txt = ''
563    
564     ## OLI_Daniele at this level middleware already known
565    
566     txt += 'if [ $middleware == LCG ]; then \n'
567     txt += self.wsSetupCMSLCGEnvironment_()
568     txt += 'elif [ $middleware == OSG ]; then\n'
569     txt += ' time=`date -u +"%s"`\n'
570     txt += ' WORKING_DIR=$OSG_WN_TMP/cms_$time\n'
571     txt += ' echo "Creating working directory: $WORKING_DIR"\n'
572     txt += ' /bin/mkdir -p $WORKING_DIR\n'
573     txt += ' if [ ! -d $WORKING_DIR ] ;then\n'
574 gutsche 1.7 txt += ' echo "SET_CMS_ENV 10016 ==> OSG $WORKING_DIR could not be created on WN `hostname`"\n'
575     txt += ' echo "JOB_EXIT_STATUS = 10016"\n'
576     txt += ' echo "JobExitCode=10016" | tee -a $RUNTIME_AREA/$repo\n'
577     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
578 gutsche 1.3 txt += ' exit 1\n'
579     txt += ' fi\n'
580     txt += '\n'
581     txt += ' echo "Change to working directory: $WORKING_DIR"\n'
582     txt += ' cd $WORKING_DIR\n'
583     txt += self.wsSetupCMSOSGEnvironment_()
584     txt += 'fi\n'
585 slacapra 1.1
586     # Prepare JobType-specific part
587     scram = self.scram.commandName()
588     txt += '\n\n'
589     txt += 'echo "### SPECIFIC JOB SETUP ENVIRONMENT ###"\n'
590     txt += scram+' project CMSSW '+self.version+'\n'
591     txt += 'status=$?\n'
592     txt += 'if [ $status != 0 ] ; then\n'
593 gutsche 1.7 txt += ' echo "SET_EXE_ENV 10034 ==>ERROR CMSSW '+self.version+' not found on `hostname`" \n'
594 gutsche 1.3 txt += ' echo "JOB_EXIT_STATUS = 10034"\n'
595 gutsche 1.7 txt += ' echo "JobExitCode=10034" | tee -a $RUNTIME_AREA/$repo\n'
596 slacapra 1.1 txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
597 gutsche 1.3 ## OLI_Daniele
598     txt += ' if [ $middleware == OSG ]; then \n'
599     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
600     txt += ' cd $RUNTIME_AREA\n'
601     txt += ' /bin/rm -rf $WORKING_DIR\n'
602     txt += ' if [ -d $WORKING_DIR ] ;then\n'
603 gutsche 1.7 txt += ' echo "SET_CMS_ENV 10018 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after CMSSW CMSSW_0_6_1 not found on `hostname`"\n'
604     txt += ' echo "JOB_EXIT_STATUS = 10018"\n'
605     txt += ' echo "JobExitCode=10018" | tee -a $RUNTIME_AREA/$repo\n'
606     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
607 gutsche 1.3 txt += ' fi\n'
608     txt += ' fi \n'
609     txt += ' exit 1 \n'
610 slacapra 1.1 txt += 'fi \n'
611     txt += 'echo "CMSSW_VERSION = '+self.version+'"\n'
612     txt += 'cd '+self.version+'\n'
613     ### needed grep for bug in scramv1 ###
614     txt += 'eval `'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME`\n'
615    
616     # Handle the arguments:
617     txt += "\n"
618 gutsche 1.7 txt += "## number of arguments (first argument always jobnumber)\n"
619 slacapra 1.1 txt += "\n"
620     txt += "narg=$#\n"
621 gutsche 1.3 txt += "if [ $narg -lt 2 ]\n"
622 slacapra 1.1 txt += "then\n"
623     txt += " echo 'SET_EXE_ENV 1 ==> ERROR Too few arguments' +$narg+ \n"
624 gutsche 1.3 txt += ' echo "JOB_EXIT_STATUS = 50113"\n'
625 gutsche 1.7 txt += ' echo "JobExitCode=50113" | tee -a $RUNTIME_AREA/$repo\n'
626 slacapra 1.1 txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
627 gutsche 1.3 ## OLI_Daniele
628     txt += ' if [ $middleware == OSG ]; then \n'
629     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
630     txt += ' cd $RUNTIME_AREA\n'
631     txt += ' /bin/rm -rf $WORKING_DIR\n'
632     txt += ' if [ -d $WORKING_DIR ] ;then\n'
633 gutsche 1.7 txt += ' echo "SET_EXE_ENV 50114 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after Too few arguments for CRAB job wrapper"\n'
634     txt += ' echo "JOB_EXIT_STATUS = 50114"\n'
635     txt += ' echo "JobExitCode=50114" | tee -a $RUNTIME_AREA/$repo\n'
636     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
637 gutsche 1.3 txt += ' fi\n'
638     txt += ' fi \n'
639 slacapra 1.1 txt += " exit 1\n"
640     txt += "fi\n"
641     txt += "\n"
642    
643     # Prepare job-specific part
644     job = common.job_list[nj]
645     pset = os.path.basename(job.configFilename())
646     txt += '\n'
647 slacapra 1.10 if (self.datasetPath): # standard job
648     txt += 'InputFiles=$2\n'
649     txt += 'echo "Inputfiles:<$InputFiles>"\n'
650     txt += 'sed "s#{\'INPUT\'}#$InputFiles#" $RUNTIME_AREA/'+pset+' > pset.cfg\n'
651     else: # pythia like job
652     txt += 'Seed=$2\n'
653     txt += 'echo "Seed: <$Seed>"\n'
654     txt += 'sed "s#INPUT#$Seed#" $RUNTIME_AREA/'+pset+' > pset.cfg\n'
655 slacapra 1.1
656     if len(self.additional_inbox_files) > 0:
657     for file in self.additional_inbox_files:
658     txt += 'if [ -e $RUNTIME_AREA/'+file+' ] ; then\n'
659     txt += ' cp $RUNTIME_AREA/'+file+' .\n'
660     txt += ' chmod +x '+file+'\n'
661     txt += 'fi\n'
662     pass
663    
664     txt += 'echo "### END JOB SETUP ENVIRONMENT ###"\n\n'
665    
666     txt += '\n'
667     txt += 'echo "***** cat pset.cfg *********"\n'
668     txt += 'cat pset.cfg\n'
669     txt += 'echo "****** end pset.cfg ********"\n'
670 gutsche 1.3 txt += '\n'
671     # txt += 'echo "***** cat pset1.cfg *********"\n'
672     # txt += 'cat pset1.cfg\n'
673     # txt += 'echo "****** end pset1.cfg ********"\n'
674     return txt
675    
676     def wsBuildExe(self, nj):
677     """
678     Put in the script the commands to build an executable
679     or a library.
680     """
681    
682     txt = ""
683    
684     if os.path.isfile(self.tgzNameWithPath):
685     txt += 'echo "tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'"\n'
686     txt += 'tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'\n'
687     txt += 'untar_status=$? \n'
688     txt += 'if [ $untar_status -ne 0 ]; then \n'
689     txt += ' echo "SET_EXE 1 ==> ERROR Untarring .tgz file failed"\n'
690     txt += ' echo "JOB_EXIT_STATUS = $untar_status" \n'
691 gutsche 1.7 txt += ' echo "JobExitCode=$untar_status" | tee -a $RUNTIME_AREA/$repo\n'
692 gutsche 1.3 txt += ' if [ $middleware == OSG ]; then \n'
693     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
694     txt += ' cd $RUNTIME_AREA\n'
695     txt += ' /bin/rm -rf $WORKING_DIR\n'
696     txt += ' if [ -d $WORKING_DIR ] ;then\n'
697 gutsche 1.7 txt += ' echo "SET_EXE 50999 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after Untarring .tgz file failed"\n'
698     txt += ' echo "JOB_EXIT_STATUS = 50999"\n'
699     txt += ' echo "JobExitCode=50999" | tee -a $RUNTIME_AREA/$repo\n'
700     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
701 gutsche 1.3 txt += ' fi\n'
702     txt += ' fi \n'
703     txt += ' \n'
704 gutsche 1.7 txt += ' exit 1 \n'
705 gutsche 1.3 txt += 'else \n'
706     txt += ' echo "Successful untar" \n'
707     txt += 'fi \n'
708     pass
709    
710 slacapra 1.1 return txt
711    
712     def modifySteeringCards(self, nj):
713     """
714     modify the card provided by the user,
715     writing a new card into share dir
716     """
717    
718     def executableName(self):
719     return self.executable
720    
721     def executableArgs(self):
722 gutsche 1.3 return " -p pset.cfg"
723 slacapra 1.1
724     def inputSandbox(self, nj):
725     """
726     Returns a list of filenames to be put in JDL input sandbox.
727     """
728     inp_box = []
729     # dict added to delete duplicate from input sandbox file list
730     seen = {}
731     ## code
732     if os.path.isfile(self.tgzNameWithPath):
733     inp_box.append(self.tgzNameWithPath)
734     ## config
735     inp_box.append(common.job_list[nj].configFilename())
736     ## additional input files
737 gutsche 1.3 #for file in self.additional_inbox_files:
738     # inp_box.append(common.work_space.cwdDir()+file)
739 slacapra 1.1 return inp_box
740    
741     def outputSandbox(self, nj):
742     """
743     Returns a list of filenames to be put in JDL output sandbox.
744     """
745     out_box = []
746    
747     stdout=common.job_list[nj].stdout()
748     stderr=common.job_list[nj].stderr()
749    
750     ## User Declared output files
751     for out in self.output_file:
752     n_out = nj + 1
753     out_box.append(self.numberFile_(out,str(n_out)))
754     return out_box
755     return []
756    
757     def prepareSteeringCards(self):
758     """
759     Make initial modifications of the user's steering card file.
760     """
761     return
762    
763     def wsRenameOutput(self, nj):
764     """
765     Returns part of a job script which renames the produced files.
766     """
767    
768     txt = '\n'
769 gutsche 1.7 txt += '# directory content\n'
770     txt += 'ls \n'
771 slacapra 1.1 file_list = ''
772     for fileWithSuffix in self.output_file:
773     output_file_num = self.numberFile_(fileWithSuffix, '$NJob')
774 gutsche 1.7 file_list=file_list+output_file_num+' '
775 slacapra 1.1 txt += '\n'
776 gutsche 1.7 txt += '# check output file\n'
777 slacapra 1.1 txt += 'ls '+fileWithSuffix+'\n'
778     txt += 'exe_result=$?\n'
779     txt += 'if [ $exe_result -ne 0 ] ; then\n'
780     txt += ' echo "ERROR: No output file to manage"\n'
781 gutsche 1.7 txt += ' echo "JOB_EXIT_STATUS = $exe_result"\n'
782     txt += ' echo "JobExitCode=60302" | tee -a $RUNTIME_AREA/$repo\n'
783     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
784 gutsche 1.3 ### OLI_DANIELE
785 gutsche 1.7 if common.scheduler.boss_scheduler_name == 'condor_g':
786     txt += ' if [ $middleware == OSG ]; then \n'
787     txt += ' echo "prepare dummy output file"\n'
788     txt += ' echo "Processing of job output failed" > $RUNTIME_AREA/'+output_file_num+'\n'
789     txt += ' fi \n'
790 slacapra 1.1 txt += 'else\n'
791     txt += ' cp '+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
792     txt += 'fi\n'
793    
794 gutsche 1.7 txt += 'cd $RUNTIME_AREA\n'
795 slacapra 1.1 file_list=file_list[:-1]
796 slacapra 1.2 txt += 'file_list="'+file_list+'"\n'
797 gutsche 1.3 ### OLI_DANIELE
798     txt += 'if [ $middleware == OSG ]; then\n'
799     txt += ' cd $RUNTIME_AREA\n'
800     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
801     txt += ' /bin/rm -rf $WORKING_DIR\n'
802     txt += ' if [ -d $WORKING_DIR ] ;then\n'
803 gutsche 1.7 txt += ' echo "SET_EXE 60999 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after cleanup of WN"\n'
804     txt += ' echo "JOB_EXIT_STATUS = 60999"\n'
805     txt += ' echo "JobExitCode=60999" | tee -a $RUNTIME_AREA/$repo\n'
806     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
807 gutsche 1.3 txt += ' fi\n'
808     txt += 'fi\n'
809     txt += '\n'
810 slacapra 1.1 return txt
811    
812     def numberFile_(self, file, txt):
813     """
814     append _'txt' before last extension of a file
815     """
816     p = string.split(file,".")
817     # take away last extension
818     name = p[0]
819     for x in p[1:-1]:
820     name=name+"."+x
821     # add "_txt"
822     if len(p)>1:
823     ext = p[len(p)-1]
824     #result = name + '_' + str(txt) + "." + ext
825     result = name + '_' + txt + "." + ext
826     else:
827     #result = name + '_' + str(txt)
828     result = name + '_' + txt
829    
830     return result
831    
832     def getRequirements(self):
833     """
834     return job requirements to add to jdl files
835     """
836     req = ''
837 slacapra 1.10 if common.analisys_common_info['sw_version']:
838     req='Member("VO-cms-' + \
839     common.analisys_common_info['sw_version'] + \
840     '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
841 slacapra 1.1 if common.analisys_common_info['sites']:
842     if len(common.analisys_common_info['sites'])>0:
843     req = req + ' && ('
844     for i in range(len(common.analisys_common_info['sites'])):
845     req = req + 'other.GlueCEInfoHostName == "' \
846     + common.analisys_common_info['sites'][i] + '"'
847     if ( i < (int(len(common.analisys_common_info['sites']) - 1)) ):
848     req = req + ' || '
849     req = req + ')'
850     #print "req = ", req
851     return req
852 gutsche 1.3
853     def configFilename(self):
854     """ return the config filename """
855     return self.name()+'.cfg'
856    
857     ### OLI_DANIELE
858     def wsSetupCMSOSGEnvironment_(self):
859     """
860     Returns part of a job script which is prepares
861     the execution environment and which is common for all CMS jobs.
862     """
863     txt = '\n'
864     txt += ' echo "### SETUP CMS OSG ENVIRONMENT ###"\n'
865     txt += ' if [ -f $GRID3_APP_DIR/cmssoft/cmsset_default.sh ] ;then\n'
866     txt += ' # Use $GRID3_APP_DIR/cmssoft/cmsset_default.sh to setup cms software\n'
867     txt += ' source $GRID3_APP_DIR/cmssoft/cmsset_default.sh '+self.version+'\n'
868     txt += ' elif [ -f $OSG_APP/cmssoft/cmsset_default.sh ] ;then\n'
869     txt += ' # Use $OSG_APP/cmssoft/cmsset_default.sh to setup cms software\n'
870     txt += ' source $OSG_APP/cmssoft/cmsset_default.sh '+self.version+'\n'
871     txt += ' else\n'
872     txt += ' echo "SET_CMS_ENV 10020 ==> ERROR $GRID3_APP_DIR/cmssoft/cmsset_default.sh and $OSG_APP/cmssoft/cmsset_default.sh file not found"\n'
873     txt += ' echo "JOB_EXIT_STATUS = 10020"\n'
874     txt += ' echo "JobExitCode=10020" | tee -a $RUNTIME_AREA/$repo\n'
875     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
876 gutsche 1.7 txt += ' exit 1\n'
877 gutsche 1.3 txt += '\n'
878     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
879     txt += ' cd $RUNTIME_AREA\n'
880     txt += ' /bin/rm -rf $WORKING_DIR\n'
881     txt += ' if [ -d $WORKING_DIR ] ;then\n'
882 gutsche 1.7 txt += ' echo "SET_CMS_ENV 10017 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after $GRID3_APP_DIR/cmssoft/cmsset_default.sh and $OSG_APP/cmssoft/cmsset_default.sh file not found"\n'
883     txt += ' echo "JOB_EXIT_STATUS = 10017"\n'
884     txt += ' echo "JobExitCode=10017" | tee -a $RUNTIME_AREA/$repo\n'
885     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
886 gutsche 1.3 txt += ' fi\n'
887     txt += '\n'
888 gutsche 1.7 txt += ' exit 1\n'
889 gutsche 1.3 txt += ' fi\n'
890     txt += '\n'
891     txt += ' echo "SET_CMS_ENV 0 ==> setup cms environment ok"\n'
892     txt += ' echo " END SETUP CMS OSG ENVIRONMENT "\n'
893    
894     return txt
895    
896     ### OLI_DANIELE
897     def wsSetupCMSLCGEnvironment_(self):
898     """
899     Returns part of a job script which is prepares
900     the execution environment and which is common for all CMS jobs.
901     """
902     txt = ' \n'
903     txt += ' echo " ### SETUP CMS LCG ENVIRONMENT ### "\n'
904     txt += ' if [ ! $VO_CMS_SW_DIR ] ;then\n'
905     txt += ' echo "SET_CMS_ENV 10031 ==> ERROR CMS software dir not found on WN `hostname`"\n'
906     txt += ' echo "JOB_EXIT_STATUS = 10031" \n'
907     txt += ' echo "JobExitCode=10031" | tee -a $RUNTIME_AREA/$repo\n'
908     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
909 gutsche 1.7 txt += ' exit 1\n'
910 gutsche 1.3 txt += ' else\n'
911     txt += ' echo "Sourcing environment... "\n'
912     txt += ' if [ ! -s $VO_CMS_SW_DIR/cmsset_default.sh ] ;then\n'
913     txt += ' echo "SET_CMS_ENV 10020 ==> ERROR cmsset_default.sh file not found into dir $VO_CMS_SW_DIR"\n'
914     txt += ' echo "JOB_EXIT_STATUS = 10020"\n'
915     txt += ' echo "JobExitCode=10020" | tee -a $RUNTIME_AREA/$repo\n'
916     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
917 gutsche 1.7 txt += ' exit 1\n'
918 gutsche 1.3 txt += ' fi\n'
919     txt += ' echo "sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
920     txt += ' source $VO_CMS_SW_DIR/cmsset_default.sh\n'
921     txt += ' result=$?\n'
922     txt += ' if [ $result -ne 0 ]; then\n'
923     txt += ' echo "SET_CMS_ENV 10032 ==> ERROR problem sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
924     txt += ' echo "JOB_EXIT_STATUS = 10032"\n'
925     txt += ' echo "JobExitCode=10032" | tee -a $RUNTIME_AREA/$repo\n'
926     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
927 gutsche 1.7 txt += ' exit 1\n'
928 gutsche 1.3 txt += ' fi\n'
929     txt += ' fi\n'
930     txt += ' \n'
931     txt += ' string=`cat /etc/redhat-release`\n'
932     txt += ' echo $string\n'
933     txt += ' if [[ $string = *alhalla* ]]; then\n'
934     txt += ' echo "SCRAM_ARCH= $SCRAM_ARCH"\n'
935     txt += ' elif [[ $string = *Enterprise* ]] || [[ $string = *cientific* ]]; then\n'
936     txt += ' export SCRAM_ARCH=slc3_ia32_gcc323\n'
937     txt += ' echo "SCRAM_ARCH= $SCRAM_ARCH"\n'
938     txt += ' else\n'
939 gutsche 1.7 txt += ' echo "SET_CMS_ENV 10033 ==> ERROR OS unknown, LCG environment not initialized"\n'
940 gutsche 1.3 txt += ' echo "JOB_EXIT_STATUS = 10033"\n'
941     txt += ' echo "JobExitCode=10033" | tee -a $RUNTIME_AREA/$repo\n'
942     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
943 gutsche 1.7 txt += ' exit 1\n'
944 gutsche 1.3 txt += ' fi\n'
945     txt += ' echo "SET_CMS_ENV 0 ==> setup cms environment ok"\n'
946     txt += ' echo "### END SETUP CMS LCG ENVIRONMENT ###"\n'
947     return txt
948 gutsche 1.5
949     def setParam_(self, param, value):
950     self._params[param] = value
951    
952     def getParams(self):
953     return self._params
954 gutsche 1.8
955     def setTaskid_(self):
956     self._taskId = self.cfg_params['taskId']
957    
958     def getTaskid(self):
959     return self._taskId