ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
(Generate patch)

Comparing COMP/CRAB/python/cms_cmssw.py (file contents):
Revision 1.93 by fanzago, Tue Jun 19 17:22:21 2007 UTC vs.
Revision 1.187 by spiga, Mon May 26 16:53:39 2008 UTC

# Line 2 | Line 2 | from JobType import JobType
2   from crab_logger import Logger
3   from crab_exceptions import *
4   from crab_util import *
5 + from BlackWhiteListParser import BlackWhiteListParser
6   import common
7   import Scram
8 + from LFNBaseName import *
9  
10 < import os, string, re, shutil, glob
10 > import os, string, glob
11  
12   class Cmssw(JobType):
13      def __init__(self, cfg_params, ncjobs):
14          JobType.__init__(self, 'CMSSW')
15          common.logger.debug(3,'CMSSW::__init__')
16  
17 <        # Marco.
17 >        self.argsList = []
18 >
19          self._params = {}
20          self.cfg_params = cfg_params
21 +        # init BlackWhiteListParser
22 +        self.blackWhiteListParser = BlackWhiteListParser(cfg_params)
23  
24 <        try:
20 <            self.MaxTarBallSize = float(self.cfg_params['EDG.maxtarballsize'])
21 <        except KeyError:
22 <            self.MaxTarBallSize = 9.5
24 >        self.MaxTarBallSize = float(self.cfg_params.get('EDG.maxtarballsize',9.5))
25  
26          # number of jobs requested to be created, limit obj splitting
27          self.ncjobs = ncjobs
28  
29          log = common.logger
30 <        
30 >
31          self.scram = Scram.Scram(cfg_params)
32          self.additional_inbox_files = []
33          self.scriptExe = ''
# Line 33 | Line 35 | class Cmssw(JobType):
35          self.executable_arch = self.scram.getArch()
36          self.tgz_name = 'default.tgz'
37          self.scriptName = 'CMSSW.sh'
38 <        self.pset = ''      #scrip use case Da  
39 <        self.datasetPath = '' #scrip use case Da
38 >        self.pset = ''  
39 >        self.datasetPath = ''
40  
41          # set FJR file name
42          self.fjrFileName = 'crab_fjr.xml'
43  
44          self.version = self.scram.getSWVersion()
45 <        common.taskDB.setDict('codeVersion',self.version)
46 <        self.setParam_('application', self.version)
45 >        version_array = self.version.split('_')
46 >        self.CMSSW_major = 0
47 >        self.CMSSW_minor = 0
48 >        self.CMSSW_patch = 0
49 >        try:
50 >            self.CMSSW_major = int(version_array[1])
51 >            self.CMSSW_minor = int(version_array[2])
52 >            self.CMSSW_patch = int(version_array[3])
53 >        except:
54 >            msg = "Cannot parse CMSSW version string: " + self.version + " for major and minor release number!"
55 >            raise CrabException(msg)
56  
57          ### collect Data cards
58  
59 <        ## get DBS mode
60 <        try:
50 <            self.use_dbs_1 = int(self.cfg_params['CMSSW.use_dbs_1'])
51 <        except KeyError:
52 <            self.use_dbs_1 = 0
53 <            
54 <        try:
55 <            tmp =  cfg_params['CMSSW.datasetpath']
56 <            log.debug(6, "CMSSW::CMSSW(): datasetPath = "+tmp)
57 <            if string.lower(tmp)=='none':
58 <                self.datasetPath = None
59 <                self.selectNoInput = 1
60 <            else:
61 <                self.datasetPath = tmp
62 <                self.selectNoInput = 0
63 <        except KeyError:
64 <            msg = "Error: datasetpath not defined "  
59 >        if not cfg_params.has_key('CMSSW.datasetpath'):
60 >            msg = "Error: datasetpath not defined "
61              raise CrabException(msg)
62 <
63 <        # ML monitoring
64 <        # split dataset path style: /PreProdR3Minbias/SIM/GEN-SIM
65 <        if not self.datasetPath:
66 <            self.setParam_('dataset', 'None')
71 <            self.setParam_('owner', 'None')
62 >        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 <            try:
69 <                datasetpath_split = self.datasetPath.split("/")
75 <                # standard style
76 <                if self.use_dbs_1 == 1 :
77 <                    self.setParam_('dataset', datasetpath_split[1])
78 <                    self.setParam_('owner', datasetpath_split[-1])
79 <                else:
80 <                    self.setParam_('dataset', datasetpath_split[1])
81 <                    self.setParam_('owner', datasetpath_split[2])
82 <            except:
83 <                self.setParam_('dataset', self.datasetPath)
84 <                self.setParam_('owner', self.datasetPath)
85 <                
86 <        self.setTaskid_()
87 <        self.setParam_('taskId', self.cfg_params['taskId'])
68 >            self.datasetPath = tmp
69 >            self.selectNoInput = 0
70  
71          self.dataTiers = []
72  
73          ## now the application
74 <        try:
75 <            self.executable = cfg_params['CMSSW.executable']
94 <            self.setParam_('exe', self.executable)
95 <            log.debug(6, "CMSSW::CMSSW(): executable = "+self.executable)
96 <            msg = "Default executable cmsRun overridden. Switch to " + self.executable
97 <            log.debug(3,msg)
98 <        except KeyError:
99 <            self.executable = 'cmsRun'
100 <            self.setParam_('exe', self.executable)
101 <            msg = "User executable not defined. Use cmsRun"
102 <            log.debug(3,msg)
103 <            pass
74 >        self.executable = cfg_params.get('CMSSW.executable','cmsRun')
75 >        log.debug(6, "CMSSW::CMSSW(): executable = "+self.executable)
76  
77 <        try:
106 <            self.pset = cfg_params['CMSSW.pset']
107 <            log.debug(6, "Cmssw::Cmssw(): PSet file = "+self.pset)
108 <            if self.pset.lower() != 'none' :
109 <                if (not os.path.exists(self.pset)):
110 <                    raise CrabException("User defined PSet file "+self.pset+" does not exist")
111 <            else:
112 <                self.pset = None
113 <        except KeyError:
77 >        if not cfg_params.has_key('CMSSW.pset'):
78              raise CrabException("PSet file missing. Cannot run cmsRun ")
79 +        self.pset = cfg_params['CMSSW.pset']
80 +        log.debug(6, "Cmssw::Cmssw(): PSet file = "+self.pset)
81 +        if self.pset.lower() != 'none' :
82 +            if (not os.path.exists(self.pset)):
83 +                raise CrabException("User defined PSet file "+self.pset+" does not exist")
84 +        else:
85 +            self.pset = None
86  
87          # output files
88          ## stuff which must be returned always via sandbox
# Line 121 | Line 92 | class Cmssw(JobType):
92          self.output_file_sandbox.append(self.fjrFileName)
93  
94          # other output files to be returned via sandbox or copied to SE
95 <        try:
96 <            self.output_file = []
97 <            tmp = cfg_params['CMSSW.output_file']
98 <            if tmp != '':
99 <                tmpOutFiles = string.split(cfg_params['CMSSW.output_file'],',')
100 <                log.debug(7, 'cmssw::cmssw(): output files '+str(tmpOutFiles))
101 <                for tmp in tmpOutFiles:
102 <                    tmp=string.strip(tmp)
132 <                    self.output_file.append(tmp)
133 <                    pass
134 <            else:
135 <                log.message("No output file defined: only stdout/err and the CRAB Framework Job Report will be available\n")
95 >        self.output_file = []
96 >        tmp = cfg_params.get('CMSSW.output_file',None)
97 >        if tmp :
98 >            tmpOutFiles = string.split(tmp,',')
99 >            log.debug(7, 'cmssw::cmssw(): output files '+str(tmpOutFiles))
100 >            for tmp in tmpOutFiles:
101 >                tmp=string.strip(tmp)
102 >                self.output_file.append(tmp)
103                  pass
104 <            pass
138 <        except KeyError:
104 >        else:
105              log.message("No output file defined: only stdout/err and the CRAB Framework Job Report will be available\n")
106 <            pass
106 >        pass
107  
108          # script_exe file as additional file in inputSandbox
109 <        try:
110 <            self.scriptExe = cfg_params['USER.script_exe']
111 <            if self.scriptExe != '':
112 <               if not os.path.isfile(self.scriptExe):
113 <                  msg ="ERROR. file "+self.scriptExe+" not found"
114 <                  raise CrabException(msg)
149 <               self.additional_inbox_files.append(string.strip(self.scriptExe))
150 <        except KeyError:
151 <            self.scriptExe = ''
109 >        self.scriptExe = cfg_params.get('USER.script_exe',None)
110 >        if self.scriptExe :
111 >            if not os.path.isfile(self.scriptExe):
112 >                msg ="ERROR. file "+self.scriptExe+" not found"
113 >                raise CrabException(msg)
114 >            self.additional_inbox_files.append(string.strip(self.scriptExe))
115  
153        #CarlosDaniele
116          if self.datasetPath == None and self.pset == None and self.scriptExe == '' :
117 <           msg ="Error. script_exe  not defined"
118 <           raise CrabException(msg)
117 >            msg ="Error. script_exe  not defined"
118 >            raise CrabException(msg)
119  
120          ## additional input files
121 <        try:
121 >        if cfg_params.has_key('USER.additional_input_files'):
122              tmpAddFiles = string.split(cfg_params['USER.additional_input_files'],',')
123              for tmp in tmpAddFiles:
124                  tmp = string.strip(tmp)
# Line 173 | Line 135 | class Cmssw(JobType):
135                      if not os.path.exists(file):
136                          raise CrabException("Additional input file not found: "+file)
137                      pass
138 <                    fname = string.split(file, '/')[-1]
177 <                    storedFile = common.work_space.pathForTgz()+'share/'+fname
178 <                    shutil.copyfile(file, storedFile)
179 <                    self.additional_inbox_files.append(string.strip(storedFile))
138 >                    self.additional_inbox_files.append(string.strip(file))
139                  pass
140              pass
141              common.logger.debug(5,"Additional input files: "+str(self.additional_inbox_files))
142 <        except KeyError:
184 <            pass
185 <
186 <        # files per job
187 <        try:
188 <            if (cfg_params['CMSSW.files_per_jobs']):
189 <                raise CrabException("files_per_jobs no longer supported.  Quitting.")
190 <        except KeyError:
191 <            pass
142 >        pass
143  
144          ## Events per job
145 <        try:
145 >        if cfg_params.has_key('CMSSW.events_per_job'):
146              self.eventsPerJob =int( cfg_params['CMSSW.events_per_job'])
147              self.selectEventsPerJob = 1
148 <        except KeyError:
148 >        else:
149              self.eventsPerJob = -1
150              self.selectEventsPerJob = 0
151 <    
151 >
152          ## number of jobs
153 <        try:
153 >        if cfg_params.has_key('CMSSW.number_of_jobs'):
154              self.theNumberOfJobs =int( cfg_params['CMSSW.number_of_jobs'])
155              self.selectNumberOfJobs = 1
156 <        except KeyError:
156 >        else:
157              self.theNumberOfJobs = 0
158              self.selectNumberOfJobs = 0
159  
160 <        try:
160 >        if cfg_params.has_key('CMSSW.total_number_of_events'):
161              self.total_number_of_events = int(cfg_params['CMSSW.total_number_of_events'])
162              self.selectTotalNumberEvents = 1
163 <        except KeyError:
163 >        else:
164              self.total_number_of_events = 0
165              self.selectTotalNumberEvents = 0
166  
167 <        if self.pset != None: #CarlosDaniele
167 >        if self.pset != None:
168               if ( (self.selectTotalNumberEvents + self.selectEventsPerJob + self.selectNumberOfJobs) != 2 ):
169                   msg = 'Must define exactly two of total_number_of_events, events_per_job, or number_of_jobs.'
170                   raise CrabException(msg)
# Line 222 | Line 173 | class Cmssw(JobType):
173                   msg = 'Must specify  number_of_jobs.'
174                   raise CrabException(msg)
175  
176 <        ## source seed for pythia
177 <        try:
178 <            self.sourceSeed = int(cfg_params['CMSSW.pythia_seed'])
179 <        except KeyError:
180 <            self.sourceSeed = None
181 <            common.logger.debug(5,"No seed given")
176 >        ## New method of dealing with seeds
177 >        self.incrementSeeds = []
178 >        self.preserveSeeds = []
179 >        if cfg_params.has_key('CMSSW.preserve_seeds'):
180 >            tmpList = cfg_params['CMSSW.preserve_seeds'].split(',')
181 >            for tmp in tmpList:
182 >                tmp.strip()
183 >                self.preserveSeeds.append(tmp)
184 >        if cfg_params.has_key('CMSSW.increment_seeds'):
185 >            tmpList = cfg_params['CMSSW.increment_seeds'].split(',')
186 >            for tmp in tmpList:
187 >                tmp.strip()
188 >                self.incrementSeeds.append(tmp)
189 >
190 >        ## Old method of dealing with seeds
191 >        ## FUTURE: This is for old CMSSW and old CRAB. Can throw exceptions after a couple of CRAB releases and then
192 >        ## remove
193 >        self.sourceSeed = cfg_params.get('CMSSW.pythia_seed',None)
194 >        if self.sourceSeed:
195 >            print "pythia_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
196 >            self.incrementSeeds.append('sourceSeed')
197 >            self.incrementSeeds.append('theSource')
198 >
199 >        self.sourceSeedVtx = cfg_params.get('CMSSW.vtx_seed',None)
200 >        if self.sourceSeedVtx:
201 >            print "vtx_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
202 >            self.incrementSeeds.append('VtxSmeared')
203 >
204 >        self.sourceSeedG4 = cfg_params.get('CMSSW.g4_seed',None)
205 >        if self.sourceSeedG4:
206 >            print "g4_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
207 >            self.incrementSeeds.append('g4SimHits')
208 >
209 >        self.sourceSeedMix = cfg_params.get('CMSSW.mix_seed',None)
210 >        if self.sourceSeedMix:
211 >            print "mix_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
212 >            self.incrementSeeds.append('mix')
213  
214 <        try:
233 <            self.sourceSeedVtx = int(cfg_params['CMSSW.vtx_seed'])
234 <        except KeyError:
235 <            self.sourceSeedVtx = None
236 <            common.logger.debug(5,"No vertex seed given")
214 >        self.firstRun = cfg_params.get('CMSSW.first_run',None)
215  
216 <        try:
217 <            self.sourceSeedG4 = int(cfg_params['CMSSW.g4_seed'])
218 <        except KeyError:
241 <            self.sourceSeedG4 = None
242 <            common.logger.debug(5,"No g4 sim hits seed given")
216 >        if self.pset != None: #CarlosDaniele
217 >            import PsetManipulator as pp
218 >            PsetEdit = pp.PsetManipulator(self.pset) #Daniele Pset
219  
220 <        try:
245 <            self.sourceSeedMix = int(cfg_params['CMSSW.mix_seed'])
246 <        except KeyError:
247 <            self.sourceSeedMix = None
248 <            common.logger.debug(5,"No mix seed given")
220 >        # Copy/return
221  
222 <        try:
223 <            self.firstRun = int(cfg_params['CMSSW.first_run'])
252 <        except KeyError:
253 <            self.firstRun = None
254 <            common.logger.debug(5,"No first run given")
255 <        if self.pset != None: #CarlosDaniele
256 <            import PsetManipulator  
257 <            PsetEdit = PsetManipulator.PsetManipulator(self.pset) #Daniele Pset
222 >        self.copy_data = int(cfg_params.get('USER.copy_data',0))
223 >        self.return_data = int(cfg_params.get('USER.return_data',0))
224  
225          #DBSDLS-start
226 <        ## Initialize the variables that are extracted from DBS/DLS and needed in other places of the code
226 >        ## Initialize the variables that are extracted from DBS/DLS and needed in other places of the code
227          self.maxEvents=0  # max events available   ( --> check the requested nb. of evts in Creator.py)
228          self.DBSPaths={}  # all dbs paths requested ( --> input to the site local discovery script)
229          self.jobDestination=[]  # Site destination(s) for each job (list of lists)
# Line 266 | Line 232 | class Cmssw(JobType):
232          blockSites = {}
233          if self.datasetPath:
234              blockSites = self.DataDiscoveryAndLocation(cfg_params)
235 <        #DBSDLS-end          
235 >        #DBSDLS-end
236 >
237  
271        self.tgzNameWithPath = self.getTarBall(self.executable)
272    
238          ## Select Splitting
239 <        if self.selectNoInput:
240 <            if self.pset == None: #CarlosDaniele
239 >        if self.selectNoInput:
240 >            if self.pset == None:
241                  self.jobSplittingForScript()
242              else:
243                  self.jobSplittingNoInput()
# Line 280 | Line 245 | class Cmssw(JobType):
245              self.jobSplittingByBlocks(blockSites)
246  
247          # modify Pset
248 <        if self.pset != None: #CarlosDaniele
248 >        if self.pset != None:
249              try:
250 <                if (self.datasetPath): # standard job
251 <                    # allow to processa a fraction of events in a file
252 <                    PsetEdit.inputModule("INPUT")
253 <                    PsetEdit.maxEvent("INPUTMAXEVENTS")
289 <                    PsetEdit.skipEvent("INPUTSKIPEVENTS")
290 <                else:  # pythia like job
291 <                    PsetEdit.maxEvent(self.eventsPerJob)
292 <                    if (self.firstRun):
293 <                        PsetEdit.pythiaFirstRun("INPUTFIRSTRUN")  #First Run
294 <                    if (self.sourceSeed) :
295 <                        PsetEdit.pythiaSeed("INPUT")
296 <                        if (self.sourceSeedVtx) :
297 <                            PsetEdit.vtxSeed("INPUTVTX")
298 <                        if (self.sourceSeedG4) :
299 <                            self.PsetEdit.g4Seed("INPUTG4")
300 <                        if (self.sourceSeedMix) :
301 <                            self.PsetEdit.mixSeed("INPUTMIX")
302 <                # add FrameworkJobReport to parameter-set
303 <                PsetEdit.addCrabFJR(self.fjrFileName)
250 >                # Add FrameworkJobReport to parameter-set, set max events.
251 >                # Reset later for data jobs by writeCFG which does all modifications
252 >                PsetEdit.addCrabFJR(self.fjrFileName) # FUTURE: Job report addition not needed by CMSSW>1.5
253 >                PsetEdit.maxEvent(self.eventsPerJob)
254                  PsetEdit.psetWriter(self.configFilename())
255              except:
256 <                msg='Error while manipuliating ParameterSet: exiting...'
256 >                msg='Error while manipulating ParameterSet: exiting...'
257                  raise CrabException(msg)
258 +        self.tgzNameWithPath = self.getTarBall(self.executable)
259  
260      def DataDiscoveryAndLocation(self, cfg_params):
261  
262          import DataDiscovery
312        import DataDiscovery_DBS2
263          import DataLocation
264          common.logger.debug(10,"CMSSW::DataDiscoveryAndLocation()")
265  
# Line 318 | Line 268 | class Cmssw(JobType):
268          ## Contact the DBS
269          common.logger.message("Contacting Data Discovery Services ...")
270          try:
271 <
322 <            if self.use_dbs_1 == 1 :
323 <                self.pubdata=DataDiscovery.DataDiscovery(datasetPath, cfg_params)
324 <            else :
325 <                self.pubdata=DataDiscovery_DBS2.DataDiscovery_DBS2(datasetPath, cfg_params)
271 >            self.pubdata=DataDiscovery.DataDiscovery(datasetPath, cfg_params)
272              self.pubdata.fetchDBSInfo()
273  
274          except DataDiscovery.NotExistingDatasetError, ex :
# Line 334 | Line 280 | class Cmssw(JobType):
280          except DataDiscovery.DataDiscoveryError, ex:
281              msg = 'ERROR ***: failed Data Discovery in DBS :  %s'%ex.getErrorMessage()
282              raise CrabException(msg)
337        except DataDiscovery_DBS2.NotExistingDatasetError_DBS2, ex :
338            msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
339            raise CrabException(msg)
340        except DataDiscovery_DBS2.NoDataTierinProvenanceError_DBS2, ex :
341            msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
342            raise CrabException(msg)
343        except DataDiscovery_DBS2.DataDiscoveryError_DBS2, ex:
344            msg = 'ERROR ***: failed Data Discovery in DBS :  %s'%ex.getErrorMessage()
345            raise CrabException(msg)
283  
284          self.filesbyblock=self.pubdata.getFiles()
285          self.eventsbyblock=self.pubdata.getEventsPerBlock()
286          self.eventsbyfile=self.pubdata.getEventsPerFile()
287  
288          ## get max number of events
289 <        self.maxEvents=self.pubdata.getMaxEvents() ##  self.maxEvents used in Creator.py
289 >        self.maxEvents=self.pubdata.getMaxEvents()
290  
291          ## Contact the DLS and build a list of sites hosting the fileblocks
292          try:
# Line 358 | Line 295 | class Cmssw(JobType):
295          except DataLocation.DataLocationError , ex:
296              msg = 'ERROR ***: failed Data Location in DLS \n %s '%ex.getErrorMessage()
297              raise CrabException(msg)
298 <        
298 >
299  
300          sites = dataloc.getSites()
301          allSites = []
# Line 372 | Line 309 | class Cmssw(JobType):
309          common.logger.message("Requested dataset: " + datasetPath + " has " + str(self.maxEvents) + " events in " + str(len(self.filesbyblock.keys())) + " blocks.\n")
310  
311          return sites
312 <    
312 >
313      def jobSplittingByBlocks(self, blockSites):
314          """
315          Perform job splitting. Jobs run over an integer number of files
# Line 422 | Line 359 | class Cmssw(JobType):
359              totalNumberOfJobs = 999999999
360          else :
361              totalNumberOfJobs = self.ncjobs
425            
362  
363          blocks = blockSites.keys()
364          blockCount = 0
# Line 440 | Line 376 | class Cmssw(JobType):
376          while ( (eventsRemaining > 0) and (blockCount < numBlocksInDataset) and (jobCount < totalNumberOfJobs)):
377              block = blocks[blockCount]
378              blockCount += 1
379 <            
379 >            if block not in jobsOfBlock.keys() :
380 >                jobsOfBlock[block] = []
381 >
382              if self.eventsbyblock.has_key(block) :
383                  numEventsInBlock = self.eventsbyblock[block]
384                  common.logger.debug(5,'Events in Block File '+str(numEventsInBlock))
385 <            
385 >
386                  files = self.filesbyblock[block]
387                  numFilesInBlock = len(files)
388                  if (numFilesInBlock <= 0):
# Line 452 | Line 390 | class Cmssw(JobType):
390                  fileCount = 0
391  
392                  # ---- New block => New job ---- #
393 <                parString = "\\{"
393 >                parString = ""
394                  # counter for number of events in files currently worked on
395                  filesEventCount = 0
396                  # flag if next while loop should touch new file
397                  newFile = 1
398                  # job event counter
399                  jobSkipEventCount = 0
400 <            
400 >
401                  # ---- Iterate over the files in the block until we've met the requested ---- #
402                  # ---- total # of events or we've gone over all the files in this block  ---- #
403                  while ( (eventsRemaining > 0) and (fileCount < numFilesInBlock) and (jobCount < totalNumberOfJobs) ):
# Line 475 | Line 413 | class Cmssw(JobType):
413                              newFile = 0
414                          except KeyError:
415                              common.logger.message("File "+str(file)+" has unknown number of events: skipping")
478                        
416  
417 +                    eventsPerJobRequested = min(eventsPerJobRequested, eventsRemaining)
418                      # if less events in file remain than eventsPerJobRequested
419 <                    if ( filesEventCount - jobSkipEventCount < eventsPerJobRequested ) :
419 >                    if ( filesEventCount - jobSkipEventCount < eventsPerJobRequested):
420                          # if last file in block
421                          if ( fileCount == numFilesInBlock-1 ) :
422                              # end job using last file, use remaining events in block
423                              # close job and touch new file
424                              fullString = parString[:-2]
487                            fullString += '\\}'
425                              list_of_lists.append([fullString,str(-1),str(jobSkipEventCount)])
426                              common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(filesEventCount - jobSkipEventCount)+" events (last file in block).")
427                              self.jobDestination.append(blockSites[block])
428                              common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
429                              # fill jobs of block dictionary
430 <                            if block in jobsOfBlock.keys() :
494 <                                jobsOfBlock[block].append(jobCount+1)
495 <                            else:
496 <                                jobsOfBlock[block] = [jobCount+1]
430 >                            jobsOfBlock[block].append(jobCount+1)
431                              # reset counter
432                              jobCount = jobCount + 1
433                              totalEventCount = totalEventCount + filesEventCount - jobSkipEventCount
434                              eventsRemaining = eventsRemaining - filesEventCount + jobSkipEventCount
435                              jobSkipEventCount = 0
436                              # reset file
437 <                            parString = "\\{"
437 >                            parString = ""
438                              filesEventCount = 0
439                              newFile = 1
440                              fileCount += 1
# Line 512 | Line 446 | class Cmssw(JobType):
446                      elif ( filesEventCount - jobSkipEventCount == eventsPerJobRequested ) :
447                          # close job and touch new file
448                          fullString = parString[:-2]
515                        fullString += '\\}'
449                          list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
450                          common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(eventsPerJobRequested)+" events.")
451                          self.jobDestination.append(blockSites[block])
452                          common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
453 <                        if block in jobsOfBlock.keys() :
521 <                            jobsOfBlock[block].append(jobCount+1)
522 <                        else:
523 <                            jobsOfBlock[block] = [jobCount+1]
453 >                        jobsOfBlock[block].append(jobCount+1)
454                          # reset counter
455                          jobCount = jobCount + 1
456                          totalEventCount = totalEventCount + eventsPerJobRequested
457                          eventsRemaining = eventsRemaining - eventsPerJobRequested
458                          jobSkipEventCount = 0
459                          # reset file
460 <                        parString = "\\{"
460 >                        parString = ""
461                          filesEventCount = 0
462                          newFile = 1
463                          fileCount += 1
464 <                        
464 >
465                      # if more events in file remain than eventsPerJobRequested
466                      else :
467                          # close job but don't touch new file
468                          fullString = parString[:-2]
539                        fullString += '\\}'
469                          list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
470                          common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(eventsPerJobRequested)+" events.")
471                          self.jobDestination.append(blockSites[block])
472                          common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
473 <                        if block in jobsOfBlock.keys() :
545 <                            jobsOfBlock[block].append(jobCount+1)
546 <                        else:
547 <                            jobsOfBlock[block] = [jobCount+1]
473 >                        jobsOfBlock[block].append(jobCount+1)
474                          # increase counter
475                          jobCount = jobCount + 1
476                          totalEventCount = totalEventCount + eventsPerJobRequested
# Line 554 | Line 480 | class Cmssw(JobType):
480                          jobSkipEventCount = eventsPerJobRequested - (filesEventCount - jobSkipEventCount - self.eventsbyfile[file])
481                          # remove all but the last file
482                          filesEventCount = self.eventsbyfile[file]
483 <                        parString = "\\{"
558 <                        parString += '\\\"' + file + '\\\"\,'
483 >                        parString = '\\\"' + file + '\\\"\,'
484                      pass # END if
485                  pass # END while (iterate over files in the block)
486          pass # END while (iterate over blocks in the dataset)
# Line 563 | Line 488 | class Cmssw(JobType):
488          if (eventsRemaining > 0 and jobCount < totalNumberOfJobs ):
489              common.logger.message("Could not run on all requested events because some blocks not hosted at allowed sites.")
490          common.logger.message(str(jobCount)+" job(s) can run on "+str(totalEventCount)+" events.\n")
491 <        
491 >
492          # screen output
493          screenOutput = "List of jobs and available destination sites:\n\n"
494  
495 +        # keep trace of block with no sites to print a warning at the end
496 +        noSiteBlock = []
497 +        bloskNoSite = []
498 +
499          blockCounter = 0
500 <        for block in jobsOfBlock.keys():
501 <            blockCounter += 1
502 <            screenOutput += "Block %5i: jobs %20s: sites: %s\n" % (blockCounter,spanRanges(jobsOfBlock[block]),','.join(blockSites[block]))
500 >        for block in blocks:
501 >            if block in jobsOfBlock.keys() :
502 >                blockCounter += 1
503 >                screenOutput += "Block %5i: jobs %20s: sites: %s\n" % (blockCounter,spanRanges(jobsOfBlock[block]),
504 >                    ','.join(self.blackWhiteListParser.checkWhiteList(self.blackWhiteListParser.checkBlackList(blockSites[block],block),block)))
505 >                if len(self.blackWhiteListParser.checkWhiteList(self.blackWhiteListParser.checkBlackList(blockSites[block],block),block)) == 0:
506 >                    noSiteBlock.append( spanRanges(jobsOfBlock[block]) )
507 >                    bloskNoSite.append( blockCounter )
508  
509          common.logger.message(screenOutput)
510 +        if len(noSiteBlock) > 0 and len(bloskNoSite) > 0:
511 +            msg = 'WARNING: No sites are hosting any part of data for block:\n                '
512 +            virgola = ""
513 +            if len(bloskNoSite) > 1:
514 +                virgola = ","
515 +            for block in bloskNoSite:
516 +                msg += ' ' + str(block) + virgola
517 +            msg += '\n               Related jobs:\n                 '
518 +            virgola = ""
519 +            if len(noSiteBlock) > 1:
520 +                virgola = ","
521 +            for range_jobs in noSiteBlock:
522 +                msg += str(range_jobs) + virgola
523 +            msg += '\n               will not be submitted and this block of data can not be analyzed!\n'
524 +            if self.cfg_params.has_key('EDG.se_white_list'):
525 +                msg += 'WARNING: SE White List: '+self.cfg_params['EDG.se_white_list']+'\n'
526 +                msg += '(Hint: By whitelisting you force the job to run at this particular site(s).\n'
527 +                msg += 'Please check if the dataset is available at this site!)\n'
528 +            if self.cfg_params.has_key('EDG.ce_white_list'):
529 +                msg += 'WARNING: CE White List: '+self.cfg_params['EDG.ce_white_list']+'\n'
530 +                msg += '(Hint: By whitelisting you force the job to run at this particular site(s).\n'
531 +                msg += 'Please check if the dataset is available at this site!)\n'
532 +
533 +            common.logger.message(msg)
534  
535          self.list_of_args = list_of_lists
536          return
# Line 582 | Line 540 | class Cmssw(JobType):
540          Perform job splitting based on number of event per job
541          """
542          common.logger.debug(5,'Splitting per events')
543 <        common.logger.message('Required '+str(self.eventsPerJob)+' events per job ')
544 <        common.logger.message('Required '+str(self.theNumberOfJobs)+' jobs in total ')
545 <        common.logger.message('Required '+str(self.total_number_of_events)+' events in total ')
543 >
544 >        if (self.selectEventsPerJob):
545 >            common.logger.message('Required '+str(self.eventsPerJob)+' events per job ')
546 >        if (self.selectNumberOfJobs):
547 >            common.logger.message('Required '+str(self.theNumberOfJobs)+' jobs in total ')
548 >        if (self.selectTotalNumberEvents):
549 >            common.logger.message('Required '+str(self.total_number_of_events)+' events in total ')
550  
551          if (self.total_number_of_events < 0):
552              msg='Cannot split jobs per Events with "-1" as total number of events'
# Line 593 | Line 555 | class Cmssw(JobType):
555          if (self.selectEventsPerJob):
556              if (self.selectTotalNumberEvents):
557                  self.total_number_of_jobs = int(self.total_number_of_events/self.eventsPerJob)
558 <            elif(self.selectNumberOfJobs) :  
558 >            elif(self.selectNumberOfJobs) :
559                  self.total_number_of_jobs =self.theNumberOfJobs
560 <                self.total_number_of_events =int(self.theNumberOfJobs*self.eventsPerJob)
560 >                self.total_number_of_events =int(self.theNumberOfJobs*self.eventsPerJob)
561  
562          elif (self.selectNumberOfJobs) :
563              self.total_number_of_jobs = self.theNumberOfJobs
564              self.eventsPerJob = int(self.total_number_of_events/self.total_number_of_jobs)
565 <
565 >
566          common.logger.debug(5,'N jobs  '+str(self.total_number_of_jobs))
567  
568          # is there any remainder?
# Line 616 | Line 578 | class Cmssw(JobType):
578          self.list_of_args = []
579          for i in range(self.total_number_of_jobs):
580              ## Since there is no input, any site is good
581 <           # self.jobDestination.append(["Any"])
620 <            self.jobDestination.append([""]) #must be empty to write correctly the xml
581 >            self.jobDestination.append([""]) #must be empty to write correctly the xml
582              args=[]
583              if (self.firstRun):
584 <                    ## pythia first run
624 <                #self.list_of_args.append([(str(self.firstRun)+str(i))])
584 >                ## pythia first run
585                  args.append(str(self.firstRun)+str(i))
626            else:
627                ## no first run
628                #self.list_of_args.append([str(i)])
629                args.append(str(i))
630            if (self.sourceSeed):
631                args.append(str(self.sourceSeed)+str(i))
632                if (self.sourceSeedVtx):
633                    ## + vtx random seed
634                    args.append(str(self.sourceSeedVtx)+str(i))
635                if (self.sourceSeedG4):
636                    ## + G4 random seed
637                    args.append(str(self.sourceSeedG4)+str(i))
638                if (self.sourceSeedMix):    
639                    ## + Mix random seed
640                    args.append(str(self.sourceSeedMix)+str(i))
641                pass
642            pass
586              self.list_of_args.append(args)
644        pass
645            
646        # print self.list_of_args
587  
588          return
589  
590  
591 <    def jobSplittingForScript(self):#CarlosDaniele
591 >    def jobSplittingForScript(self):
592          """
593          Perform job splitting based on number of job
594          """
# Line 664 | Line 604 | class Cmssw(JobType):
604          # argument is seed number.$i
605          self.list_of_args = []
606          for i in range(self.total_number_of_jobs):
667            ## Since there is no input, any site is good
668           # self.jobDestination.append(["Any"])
607              self.jobDestination.append([""])
670            ## no random seed
608              self.list_of_args.append([str(i)])
609          return
610  
611      def split(self, jobParams):
612 <
676 <        common.jobDB.load()
677 <        #### Fabio
612 >
613          njobs = self.total_number_of_jobs
614          arglist = self.list_of_args
615          # create the empty structure
616          for i in range(njobs):
617              jobParams.append("")
618 <        
618 >
619 >        listID=[]
620 >        listField=[]
621          for job in range(njobs):
622              jobParams[job] = arglist[job]
623 <            # print str(arglist[job])
624 <            # print jobParams[job]
625 <            common.jobDB.setArguments(job, jobParams[job])
626 <            common.logger.debug(5,"Job "+str(job)+" Destination: "+str(self.jobDestination[job]))
627 <            common.jobDB.setDestination(job, self.jobDestination[job])
623 >            listID.append(job+1)
624 >            job_ToSave ={}
625 >            concString = ' '
626 >            argu=''
627 >            if len(jobParams[job]):
628 >                argu +=   concString.join(jobParams[job] )
629 >            job_ToSave['arguments']= str(job+1)+' '+argu
630 >            job_ToSave['dlsDestination']= self.jobDestination[job]
631 >            listField.append(job_ToSave)
632 >            msg="Job "+str(job)+" Arguments:   "+str(job+1)+" "+argu+"\n"  \
633 >            +"                     Destination: "+str(self.jobDestination[job])
634 >            common.logger.debug(5,msg)
635 >        common._db.updateJob_(listID,listField)
636 >        self.argsList = (len(jobParams[0])+1)
637  
692        common.jobDB.save()
638          return
639 <    
695 <    def getJobTypeArguments(self, nj, sched):
696 <        result = ''
697 <        for i in common.jobDB.arguments(nj):
698 <            result=result+str(i)+" "
699 <        return result
700 <  
639 >
640      def numberOfJobs(self):
702        # Fabio
641          return self.total_number_of_jobs
642  
643      def getTarBall(self, exe):
644          """
645          Return the TarBall with lib and exe
646          """
709        
710        # if it exist, just return it
711        #
712        # Marco. Let's start to use relative path for Boss XML files
713        #
647          self.tgzNameWithPath = common.work_space.pathForTgz()+'share/'+self.tgz_name
648          if os.path.exists(self.tgzNameWithPath):
649              return self.tgzNameWithPath
# Line 724 | Line 657 | class Cmssw(JobType):
657  
658          # First of all declare the user Scram area
659          swArea = self.scram.getSWArea_()
727        #print "swArea = ", swArea
728        # swVersion = self.scram.getSWVersion()
729        # print "swVersion = ", swVersion
660          swReleaseTop = self.scram.getReleaseTop_()
661 <        #print "swReleaseTop = ", swReleaseTop
732 <        
661 >
662          ## check if working area is release top
663          if swReleaseTop == '' or swArea == swReleaseTop:
664 +            common.logger.debug(3,"swArea = "+swArea+" swReleaseTop ="+swReleaseTop)
665              return
666  
667          import tarfile
# Line 742 | Line 672 | class Cmssw(JobType):
672                  exeWithPath = self.scram.findFile_(executable)
673                  if ( not exeWithPath ):
674                      raise CrabException('User executable '+executable+' not found')
675 <    
675 >
676                  ## then check if it's private or not
677                  if exeWithPath.find(swReleaseTop) == -1:
678                      # the exe is private, so we must ship
# Line 751 | Line 681 | class Cmssw(JobType):
681                      # distinguish case when script is in user project area or given by full path somewhere else
682                      if exeWithPath.find(path) >= 0 :
683                          exe = string.replace(exeWithPath, path,'')
684 <                        tar.add(path+exe,os.path.basename(executable))
684 >                        tar.add(path+exe,exe)
685                      else :
686                          tar.add(exeWithPath,os.path.basename(executable))
687                      pass
688                  else:
689                      # the exe is from release, we'll find it on WN
690                      pass
691 <    
691 >
692              ## Now get the libraries: only those in local working area
693              libDir = 'lib'
694              lib = swArea+'/' +libDir
695              common.logger.debug(5,"lib "+lib+" to be tarred")
696              if os.path.exists(lib):
697                  tar.add(lib,libDir)
698 <    
698 >
699              ## Now check if module dir is present
700              moduleDir = 'module'
701              module = swArea + '/' + moduleDir
# Line 774 | Line 704 | class Cmssw(JobType):
704  
705              ## Now check if any data dir(s) is present
706              swAreaLen=len(swArea)
707 +            self.dataExist = False
708              for root, dirs, files in os.walk(swArea):
709                  if "data" in dirs:
710 +                    self.dataExist=True
711                      common.logger.debug(5,"data "+root+"/data"+" to be tarred")
712                      tar.add(root+"/data",root[swAreaLen:]+"/data")
713  
714 <            ## Add ProdAgent dir to tar
715 <            paDir = 'ProdAgentApi'
716 <            pa = os.environ['CRABDIR'] + '/' + 'ProdAgentApi'
717 <            if os.path.isdir(pa):
718 <                tar.add(pa,paDir)
714 >            ### CMSSW ParameterSet
715 >            if not self.pset is None:
716 >                cfg_file = common.work_space.jobDir()+self.configFilename()
717 >                tar.add(cfg_file,self.configFilename())
718 >                common.logger.debug(5,"File added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
719  
720 <            ### FEDE FOR DBS PUBLICATION
721 <            ## Add PRODCOMMON dir to tar
720 >
721 >            ## Add ProdCommon dir to tar
722              prodcommonDir = 'ProdCommon'
723              prodcommonPath = os.environ['CRABDIR'] + '/' + 'ProdCommon'
724              if os.path.isdir(prodcommonPath):
725                  tar.add(prodcommonPath,prodcommonDir)
794            #############################    
795        
726              common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
727 +
728 +            ##### ML stuff
729 +            ML_file_list=['report.py', 'DashboardAPI.py', 'Logger.py', 'ProcInfo.py', 'apmon.py']
730 +            path=os.environ['CRABDIR'] + '/python/'
731 +            for file in ML_file_list:
732 +                tar.add(path+file,file)
733 +            common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
734 +
735 +            ##### Utils
736 +            Utils_file_list=['parseCrabFjr.py','writeCfg.py', 'JobReportErrorCode.py']
737 +            for file in Utils_file_list:
738 +                tar.add(path+file,file)
739 +            common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
740 +
741 +            ##### AdditionalFiles
742 +            for file in self.additional_inbox_files:
743 +                tar.add(file,string.split(file,'/')[-1])
744 +            common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
745 +
746              tar.close()
747          except :
748              raise CrabException('Could not create tar-ball')
# Line 804 | Line 753 | class Cmssw(JobType):
753              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.')
754  
755          ## create tar-ball with ML stuff
756 <        self.MLtgzfile =  common.work_space.pathForTgz()+'share/MLfiles.tgz'
757 <        try:
809 <            tar = tarfile.open(self.MLtgzfile, "w:gz")
810 <            path=os.environ['CRABDIR'] + '/python/'
811 <            for file in ['report.py', 'DashboardAPI.py', 'Logger.py', 'ProcInfo.py', 'apmon.py', 'parseCrabFjr.py']:
812 <                tar.add(path+file,file)
813 <            common.logger.debug(5,"Files added to "+self.MLtgzfile+" : "+str(tar.getnames()))
814 <            tar.close()
815 <        except :
816 <            raise CrabException('Could not create ML files tar-ball')
817 <        
818 <        return
819 <        
820 <    def wsSetupEnvironment(self, nj):
756 >
757 >    def wsSetupEnvironment(self, nj=0):
758          """
759          Returns part of a job script which prepares
760          the execution environment for the job 'nj'.
761          """
762 +        if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
763 +            psetName = 'pset.py'
764 +        else:
765 +            psetName = 'pset.cfg'
766          # Prepare JobType-independent part
767 <        txt = ''
768 <  
769 <        ## OLI_Daniele at this level  middleware already known
829 <
830 <        txt += 'if [ $middleware == LCG ]; then \n'
767 >        txt = '\n#Written by cms_cmssw::wsSetupEnvironment\n'
768 >        txt += 'echo ">>> setup environment"\n'
769 >        txt += 'if [ $middleware == LCG ]; then \n'
770          txt += self.wsSetupCMSLCGEnvironment_()
771          txt += 'elif [ $middleware == OSG ]; then\n'
772          txt += '    WORKING_DIR=`/bin/mktemp  -d $OSG_WN_TMP/cms_XXXXXXXXXXXX`\n'
773 <        txt += '    echo "Created working directory: $WORKING_DIR"\n'
774 <        txt += '    if [ ! -d $WORKING_DIR ] ;then\n'
775 <        txt += '        echo "SET_CMS_ENV 10016 ==> OSG $WORKING_DIR could not be created on WN `hostname`"\n'
776 <        txt += '    echo "JOB_EXIT_STATUS = 10016"\n'
838 <        txt += '    echo "JobExitCode=10016" | tee -a $RUNTIME_AREA/$repo\n'
839 <        txt += '    dumpStatus $RUNTIME_AREA/$repo\n'
840 <        txt += '        rm -f $RUNTIME_AREA/$repo \n'
841 <        txt += '        echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
842 <        txt += '        echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
843 <        txt += '        exit 1\n'
773 >        txt += '    if [ ! $? == 0 ] ;then\n'
774 >        txt += '        echo "ERROR ==> OSG $WORKING_DIR could not be created on WN `hostname`"\n'
775 >        txt += '        job_exit_code=10016\n'
776 >        txt += '        func_exit\n'
777          txt += '    fi\n'
778 +        txt += '    echo ">>> Created working directory: $WORKING_DIR"\n'
779          txt += '\n'
780          txt += '    echo "Change to working directory: $WORKING_DIR"\n'
781          txt += '    cd $WORKING_DIR\n'
782 <        txt += self.wsSetupCMSOSGEnvironment_()
782 >        txt += '    echo ">>> current directory (WORKING_DIR): $WORKING_DIR"\n'
783 >        txt += self.wsSetupCMSOSGEnvironment_()
784          txt += 'fi\n'
785  
786          # Prepare JobType-specific part
787          scram = self.scram.commandName()
788          txt += '\n\n'
789 <        txt += 'echo "### SPECIFIC JOB SETUP ENVIRONMENT ###"\n'
790 <        txt += 'echo "Setting SCRAM_ARCH='+self.executable_arch+'"\n'
856 <        txt += 'export SCRAM_ARCH='+self.executable_arch+'\n'
789 >        txt += 'echo ">>> specific cmssw setup environment:"\n'
790 >        txt += 'echo "CMSSW_VERSION =  '+self.version+'"\n'
791          txt += scram+' project CMSSW '+self.version+'\n'
792          txt += 'status=$?\n'
793          txt += 'if [ $status != 0 ] ; then\n'
794 <        txt += '   echo "SET_EXE_ENV 10034 ==>ERROR CMSSW '+self.version+' not found on `hostname`" \n'
795 <        txt += '   echo "JOB_EXIT_STATUS = 10034"\n'
796 <        txt += '   echo "JobExitCode=10034" | tee -a $RUNTIME_AREA/$repo\n'
863 <        txt += '   dumpStatus $RUNTIME_AREA/$repo\n'
864 <        txt += '   rm -f $RUNTIME_AREA/$repo \n'
865 <        txt += '   echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
866 <        txt += '   echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
867 <        ## OLI_Daniele
868 <        txt += '    if [ $middleware == OSG ]; then \n'
869 <        txt += '        echo "Remove working directory: $WORKING_DIR"\n'
870 <        txt += '        cd $RUNTIME_AREA\n'
871 <        txt += '        /bin/rm -rf $WORKING_DIR\n'
872 <        txt += '        if [ -d $WORKING_DIR ] ;then\n'
873 <        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'
874 <        txt += '        echo "JOB_EXIT_STATUS = 10018"\n'
875 <        txt += '        echo "JobExitCode=10018" | tee -a $RUNTIME_AREA/$repo\n'
876 <        txt += '        dumpStatus $RUNTIME_AREA/$repo\n'
877 <        txt += '            rm -f $RUNTIME_AREA/$repo \n'
878 <        txt += '            echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
879 <        txt += '            echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
880 <        txt += '        fi\n'
881 <        txt += '    fi \n'
882 <        txt += '   exit 1 \n'
794 >        txt += '    echo "ERROR ==> CMSSW '+self.version+' not found on `hostname`" \n'
795 >        txt += '    job_exit_code=10034\n'
796 >        txt += '    func_exit\n'
797          txt += 'fi \n'
884        txt += 'echo "CMSSW_VERSION =  '+self.version+'"\n'
798          txt += 'cd '+self.version+'\n'
799 <        ### needed grep for bug in scramv1 ###
800 <        txt += scram+' runtime -sh\n'
799 >        txt += 'SOFTWARE_DIR=`pwd`\n'
800 >        txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
801          txt += 'eval `'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME`\n'
802 <        txt += 'echo $PATH\n'
803 <
802 >        txt += 'if [ $? != 0 ] ; then\n'
803 >        txt += '    echo "ERROR ==> Problem with the command: "\n'
804 >        txt += '    echo "eval \`'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME \` at `hostname`"\n'
805 >        txt += '    job_exit_code=10034\n'
806 >        txt += '    func_exit\n'
807 >        txt += 'fi \n'
808          # Handle the arguments:
809          txt += "\n"
810          txt += "## number of arguments (first argument always jobnumber)\n"
811          txt += "\n"
812 < #        txt += "narg=$#\n"
896 <        txt += "if [ $nargs -lt 2 ]\n"
812 >        txt += "if [ $nargs -lt "+str(self.argsList)+" ]\n"
813          txt += "then\n"
814 <        txt += "    echo 'SET_EXE_ENV 1 ==> ERROR Too few arguments' +$nargs+ \n"
815 <        txt += '    echo "JOB_EXIT_STATUS = 50113"\n'
816 <        txt += '    echo "JobExitCode=50113" | tee -a $RUNTIME_AREA/$repo\n'
901 <        txt += '    dumpStatus $RUNTIME_AREA/$repo\n'
902 <        txt += '    rm -f $RUNTIME_AREA/$repo \n'
903 <        txt += '    echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
904 <        txt += '    echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
905 <        ## OLI_Daniele
906 <        txt += '    if [ $middleware == OSG ]; then \n'
907 <        txt += '        echo "Remove working directory: $WORKING_DIR"\n'
908 <        txt += '        cd $RUNTIME_AREA\n'
909 <        txt += '        /bin/rm -rf $WORKING_DIR\n'
910 <        txt += '        if [ -d $WORKING_DIR ] ;then\n'
911 <        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'
912 <        txt += '        echo "JOB_EXIT_STATUS = 50114"\n'
913 <        txt += '        echo "JobExitCode=50114" | tee -a $RUNTIME_AREA/$repo\n'
914 <        txt += '        dumpStatus $RUNTIME_AREA/$repo\n'
915 <        txt += '            rm -f $RUNTIME_AREA/$repo \n'
916 <        txt += '            echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
917 <        txt += '            echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
918 <        txt += '        fi\n'
919 <        txt += '    fi \n'
920 <        txt += "    exit 1\n"
814 >        txt += "    echo 'ERROR ==> Too few arguments' +$nargs+ \n"
815 >        txt += '    job_exit_code=50113\n'
816 >        txt += "    func_exit\n"
817          txt += "fi\n"
818          txt += "\n"
819  
820          # Prepare job-specific part
821          job = common.job_list[nj]
822 <        ### FEDE FOR DBS OUTPUT PUBLICATION
927 <        if (self.datasetPath):
822 >        if (self.datasetPath):
823              txt += '\n'
824              txt += 'DatasetPath='+self.datasetPath+'\n'
825  
826              datasetpath_split = self.datasetPath.split("/")
827 <            
827 >
828              txt += 'PrimaryDataset='+datasetpath_split[1]+'\n'
829              txt += 'DataTier='+datasetpath_split[2]+'\n'
830 <            txt += 'ProcessedDataset='+datasetpath_split[3]+'\n'
936 <            txt += 'ApplicationFamily=Online\n'
830 >            txt += 'ApplicationFamily=cmsRun\n'
831  
832          else:
833              txt += 'DatasetPath=MCDataTier\n'
834              txt += 'PrimaryDataset=null\n'
835              txt += 'DataTier=null\n'
942            txt += 'ProcessedDataset=null\n'
836              txt += 'ApplicationFamily=MCDataTier\n'
837 <        ##################    
945 <        if self.pset != None: #CarlosDaniele
837 >        if self.pset != None:
838              pset = os.path.basename(job.configFilename())
839              txt += '\n'
840 +            txt += 'cp  $RUNTIME_AREA/'+pset+' .\n'
841              if (self.datasetPath): # standard job
842 <                #txt += 'InputFiles=$2\n'
843 <                txt += 'InputFiles=${args[1]}\n'
844 <                txt += 'MaxEvents=${args[2]}\n'
952 <                txt += 'SkipEvents=${args[3]}\n'
842 >                txt += 'InputFiles=${args[1]}; export InputFiles\n'
843 >                txt += 'MaxEvents=${args[2]}; export MaxEvents\n'
844 >                txt += 'SkipEvents=${args[3]}; export SkipEvents\n'
845                  txt += 'echo "Inputfiles:<$InputFiles>"\n'
954                txt += 'sed "s#{\'INPUT\'}#$InputFiles#" '+pset+' > tmp && mv -f tmp '+pset+'\n'
846                  txt += 'echo "MaxEvents:<$MaxEvents>"\n'
956                txt += 'sed "s#INPUTMAXEVENTS#$MaxEvents#" '+pset+' > tmp && mv -f tmp '+pset+'\n'
847                  txt += 'echo "SkipEvents:<$SkipEvents>"\n'
958                txt += 'sed "s#INPUTSKIPEVENTS#$SkipEvents#" '+pset+' > tmp && mv -f tmp '+pset+'\n'
848              else:  # pythia like job
849 <                seedIndex=1
849 >                txt += 'PreserveSeeds='  + ','.join(self.preserveSeeds)  + '; export PreserveSeeds\n'
850 >                txt += 'IncrementSeeds=' + ','.join(self.incrementSeeds) + '; export IncrementSeeds\n'
851 >                txt += 'echo "PreserveSeeds: <$PreserveSeeds>"\n'
852 >                txt += 'echo "IncrementSeeds:<$IncrementSeeds>"\n'
853                  if (self.firstRun):
854 <                    txt += 'FirstRun=${args['+str(seedIndex)+']}\n'
854 >                    txt += 'FirstRun=${args[1]}; export FirstRun\n'
855                      txt += 'echo "FirstRun: <$FirstRun>"\n'
964                    txt += 'sed "s#\<INPUTFIRSTRUN\>#$FirstRun#" '+pset+' > tmp && mv -f tmp '+pset+'\n'
965                    seedIndex=seedIndex+1
856  
857 <                if (self.sourceSeed):
968 <                    txt += 'Seed=${args['+str(seedIndex)+']}\n'
969 <                    txt += 'sed "s#\<INPUT\>#$Seed#" '+pset+' > tmp && mv -f tmp '+pset+'\n'
970 <                    seedIndex=seedIndex+1
971 <                    ## the following seeds are not always present
972 <                    if (self.sourceSeedVtx):
973 <                        txt += 'VtxSeed=${args['+str(seedIndex)+']}\n'
974 <                        txt += 'echo "VtxSeed: <$VtxSeed>"\n'
975 <                        txt += 'sed "s#\<INPUTVTX\>#$VtxSeed#" '+pset+' > tmp && mv -f tmp '+pset+'\n'
976 <                        seedIndex += 1
977 <                    if (self.sourceSeedG4):
978 <                        txt += 'G4Seed=${args['+str(seedIndex)+']}\n'
979 <                        txt += 'echo "G4Seed: <$G4Seed>"\n'
980 <                        txt += 'sed "s#\<INPUTG4\>#$G4Seed#" '+pset+' > tmp && mv -f tmp '+pset+'\n'
981 <                        seedIndex += 1
982 <                    if (self.sourceSeedMix):
983 <                        txt += 'mixSeed=${args['+str(seedIndex)+']}\n'
984 <                        txt += 'echo "MixSeed: <$mixSeed>"\n'
985 <                        txt += 'sed "s#\<INPUTMIX\>#$mixSeed#" '+pset+' > tmp && mv -f tmp '+pset+'\n'
986 <                        seedIndex += 1
987 <                    pass
988 <                pass
989 <            txt += 'mv -f '+pset+' pset.cfg\n'
857 >            txt += 'mv -f ' + pset + ' ' + psetName + '\n'
858  
991        if len(self.additional_inbox_files) > 0:
992            for file in self.additional_inbox_files:
993                relFile = file.split("/")[-1]
994                txt += 'if [ -e $RUNTIME_AREA/'+relFile+' ] ; then\n'
995                txt += '   cp $RUNTIME_AREA/'+relFile+' .\n'
996                txt += '   chmod +x '+relFile+'\n'
997                txt += 'fi\n'
998            pass
859  
860 <        if self.pset != None: #CarlosDaniele
861 <            txt += 'echo "### END JOB SETUP ENVIRONMENT ###"\n\n'
1002 <        
860 >        if self.pset != None:
861 >            # FUTURE: Can simply for 2_1_x and higher
862              txt += '\n'
863 <            txt += 'echo "***** cat pset.cfg *********"\n'
864 <            txt += 'cat pset.cfg\n'
865 <            txt += 'echo "****** end pset.cfg ********"\n'
863 >            txt += 'echo "***** cat ' + psetName + ' *********"\n'
864 >            txt += 'cat ' + psetName + '\n'
865 >            txt += 'echo "****** end ' + psetName + ' ********"\n'
866              txt += '\n'
867 <            ### FEDE FOR DBS OUTPUT PUBLICATION
868 <            txt += 'PSETHASH=`EdmConfigHash < pset.cfg`'
1010 <            ##############
867 >            txt += 'PSETHASH=`edmConfigHash < ' + psetName + '` \n'
868 >            txt += 'echo "PSETHASH = $PSETHASH" \n'
869              txt += '\n'
1012            # txt += 'echo "***** cat pset1.cfg *********"\n'
1013            # txt += 'cat pset1.cfg\n'
1014            # txt += 'echo "****** end pset1.cfg ********"\n'
870          return txt
871  
872 <    def wsBuildExe(self, nj=0):
872 >    def wsUntarSoftware(self, nj=0):
873          """
874          Put in the script the commands to build an executable
875          or a library.
876          """
877  
878 <        txt = ""
878 >        txt = '\n#Written by cms_cmssw::wsUntarSoftware\n'
879  
880          if os.path.isfile(self.tgzNameWithPath):
881 <            txt += 'echo "tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'"\n'
881 >            txt += 'echo ">>> tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+' :" \n'
882              txt += 'tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'\n'
883 +            txt += 'ls -Al \n'
884              txt += 'untar_status=$? \n'
885              txt += 'if [ $untar_status -ne 0 ]; then \n'
886 <            txt += '   echo "SET_EXE 1 ==> ERROR Untarring .tgz file failed"\n'
887 <            txt += '   echo "JOB_EXIT_STATUS = $untar_status" \n'
888 <            txt += '   echo "JobExitCode=$untar_status" | tee -a $RUNTIME_AREA/$repo\n'
1033 <            txt += '   if [ $middleware == OSG ]; then \n'
1034 <            txt += '       echo "Remove working directory: $WORKING_DIR"\n'
1035 <            txt += '       cd $RUNTIME_AREA\n'
1036 <            txt += '       /bin/rm -rf $WORKING_DIR\n'
1037 <            txt += '       if [ -d $WORKING_DIR ] ;then\n'
1038 <            txt += '           echo "SET_EXE 50999 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after Untarring .tgz file failed"\n'
1039 <            txt += '           echo "JOB_EXIT_STATUS = 50999"\n'
1040 <            txt += '           echo "JobExitCode=50999" | tee -a $RUNTIME_AREA/$repo\n'
1041 <            txt += '           dumpStatus $RUNTIME_AREA/$repo\n'
1042 <            txt += '           rm -f $RUNTIME_AREA/$repo \n'
1043 <            txt += '           echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1044 <            txt += '           echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1045 <            txt += '       fi\n'
1046 <            txt += '   fi \n'
1047 <            txt += '   \n'
1048 <            txt += '   exit 1 \n'
886 >            txt += '   echo "ERROR ==> Untarring .tgz file failed"\n'
887 >            txt += '   job_exit_code=$untar_status\n'
888 >            txt += '   func_exit\n'
889              txt += 'else \n'
890              txt += '   echo "Successful untar" \n'
891              txt += 'fi \n'
892              txt += '\n'
893 <            txt += 'echo "Include ProdAgentApi and PRODCOMMON in PYTHONPATH"\n'
893 >            txt += 'echo ">>> Include ProdCommon in PYTHONPATH:"\n'
894              txt += 'if [ -z "$PYTHONPATH" ]; then\n'
895 <            #### FEDE FOR DBS OUTPUT PUBLICATION
1056 <            txt += '   export PYTHONPATH=`pwd`/ProdAgentApi:`pwd`/ProdCommon\n'
1057 <            #txt += '   export PYTHONPATH=ProdAgentApi\n'
895 >            txt += '   export PYTHONPATH=$RUNTIME_AREA/ProdCommon\n'
896              txt += 'else\n'
897 <            txt += '   export PYTHONPATH=`pwd`/ProdAgentApi:`pwd`/ProdCommon:${PYTHONPATH}\n'
1060 <            #txt += '   export PYTHONPATH=ProdAgentApi:${PYTHONPATH}\n'
897 >            txt += '   export PYTHONPATH=$RUNTIME_AREA/ProdCommon:${PYTHONPATH}\n'
898              txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
1062            ###################  
899              txt += 'fi\n'
900              txt += '\n'
901  
902              pass
903 <        
903 >
904 >        return txt
905 >
906 >    def wsBuildExe(self, nj=0):
907 >        """
908 >        Put in the script the commands to build an executable
909 >        or a library.
910 >        """
911 >
912 >        txt = '\n#Written by cms_cmssw::wsBuildExe\n'
913 >        txt += 'echo ">>> moving CMSSW software directories in `pwd`" \n'
914 >
915 >        txt += 'rm -r lib/ module/ \n'
916 >        txt += 'mv $RUNTIME_AREA/lib/ . \n'
917 >        txt += 'mv $RUNTIME_AREA/module/ . \n'
918 >        if self.dataExist == True:
919 >            txt += 'rm -r src/ \n'
920 >            txt += 'mv $RUNTIME_AREA/src/ . \n'
921 >        if len(self.additional_inbox_files)>0:
922 >            for file in self.additional_inbox_files:
923 >                txt += 'mv $RUNTIME_AREA/'+file+' . \n'
924 >        txt += 'mv $RUNTIME_AREA/ProdCommon/ . \n'
925 >
926 >        txt += 'if [ -z "$PYTHONPATH" ]; then\n'
927 >        txt += '   export PYTHONPATH=$SOFTWARE_DIR/ProdCommon\n'
928 >        txt += 'else\n'
929 >        txt += '   export PYTHONPATH=$SOFTWARE_DIR/ProdCommon:${PYTHONPATH}\n'
930 >        txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
931 >        txt += 'fi\n'
932 >        txt += '\n'
933 >
934          return txt
935  
936      def modifySteeringCards(self, nj):
937          """
938 <        modify the card provided by the user,
938 >        modify the card provided by the user,
939          writing a new card into share dir
940          """
941 <        
941 >
942      def executableName(self):
943 <        if self.scriptExe: #CarlosDaniele
943 >        if self.scriptExe:
944              return "sh "
945          else:
946              return self.executable
947  
948      def executableArgs(self):
949 +        # FUTURE: This function tests the CMSSW version. Can be simplified as we drop support for old versions
950          if self.scriptExe:#CarlosDaniele
951              return   self.scriptExe + " $NJob"
952 <        else:
953 <            return " -p pset.cfg"
952 >        else:
953 >            ex_args = ""
954 >            # FUTURE: This tests the CMSSW version. Can remove code as versions deprecated
955 >            # Framework job report
956 >            if (self.CMSSW_major >= 1 and self.CMSSW_minor >= 5) or (self.CMSSW_major >= 2):
957 >                ex_args += " -j $RUNTIME_AREA/crab_fjr_$NJob.xml"
958 >            # Type of config file
959 >            if self.CMSSW_major >= 2 :
960 >                ex_args += " -p pset.py"
961 >            else:
962 >                ex_args += " -p pset.cfg"
963 >            return ex_args
964  
965      def inputSandbox(self, nj):
966          """
967          Returns a list of filenames to be put in JDL input sandbox.
968          """
969          inp_box = []
1093        # # dict added to delete duplicate from input sandbox file list
1094        # seen = {}
1095        ## code
970          if os.path.isfile(self.tgzNameWithPath):
971              inp_box.append(self.tgzNameWithPath)
972 <        if os.path.isfile(self.MLtgzfile):
973 <            inp_box.append(self.MLtgzfile)
1100 <        ## config
1101 <        if not self.pset is None:
1102 <            inp_box.append(common.work_space.pathForTgz() + 'job/' + self.configFilename())
1103 <        ## additional input files
1104 <        for file in self.additional_inbox_files:
1105 <            inp_box.append(file)
972 >        wrapper = os.path.basename(str(common._db.queryTask('scriptName')))
973 >        inp_box.append(common.work_space.pathForTgz() +'job/'+ wrapper)
974          return inp_box
975  
976      def outputSandbox(self, nj):
# Line 1113 | Line 981 | class Cmssw(JobType):
981  
982          ## User Declared output files
983          for out in (self.output_file+self.output_file_sandbox):
984 <            n_out = nj + 1
984 >            n_out = nj + 1
985              out_box.append(self.numberFile_(out,str(n_out)))
986          return out_box
987  
# Line 1128 | Line 996 | class Cmssw(JobType):
996          Returns part of a job script which renames the produced files.
997          """
998  
999 <        txt = '\n'
1000 <        txt += '# directory content\n'
999 >        txt = '\n#Written by cms_cmssw::wsRenameOutput\n'
1000 >        txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
1001 >        txt += 'echo ">>> current directory content:"\n'
1002          txt += 'ls \n'
1003 +        txt += '\n'
1004  
1005 <        for fileWithSuffix in (self.output_file+self.output_file_sandbox):
1005 >        for fileWithSuffix in (self.output_file):
1006              output_file_num = self.numberFile_(fileWithSuffix, '$NJob')
1007              txt += '\n'
1008              txt += '# check output file\n'
1009 <            txt += 'ls '+fileWithSuffix+'\n'
1010 <            txt += 'ls_result=$?\n'
1011 <            txt += 'if [ $ls_result -ne 0 ] ; then\n'
1012 <            txt += '   exit_status=60302\n'
1013 <            txt += '   echo "ERROR: Problem with output file"\n'
1014 <            if common.scheduler.boss_scheduler_name == 'condor_g':
1009 >            txt += 'if [ -e ./'+fileWithSuffix+' ] ; then\n'
1010 >            if (self.copy_data == 1):  # For OSG nodes, file is in $WORKING_DIR, should not be moved to $RUNTIME_AREA
1011 >                txt += '    mv '+fileWithSuffix+' '+output_file_num+'\n'
1012 >                txt += '    ln -s `pwd`/'+output_file_num+' $RUNTIME_AREA/'+fileWithSuffix+'\n'
1013 >            else:
1014 >                txt += '    mv '+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
1015 >                txt += '    ln -s $RUNTIME_AREA/'+output_file_num+' $RUNTIME_AREA/'+fileWithSuffix+'\n'
1016 >            txt += 'else\n'
1017 >            txt += '    job_exit_code=60302\n'
1018 >            txt += '    echo "WARNING: Output file '+fileWithSuffix+' not found"\n'
1019 >            if common.scheduler.name().upper() == 'CONDOR_G':
1020                  txt += '    if [ $middleware == OSG ]; then \n'
1021                  txt += '        echo "prepare dummy output file"\n'
1022                  txt += '        echo "Processing of job output failed" > $RUNTIME_AREA/'+output_file_num+'\n'
1023                  txt += '    fi \n'
1149            txt += 'else\n'
1150            ### FEDE FOR DBS OUTPUT PUBLICATION
1151            txt += '   mv '+fileWithSuffix+' $RUNTIME_AREA\n'
1152            txt += '   cp $RUNTIME_AREA/'+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
1153            #################################
1024              txt += 'fi\n'
1025 <      
1026 <        txt += 'cd $RUNTIME_AREA\n'
1027 <        ### OLI_DANIELE
1158 <        txt += 'if [ $middleware == OSG ]; then\n'  
1159 <        txt += '    cd $RUNTIME_AREA\n'
1160 <        txt += '    echo "Remove working directory: $WORKING_DIR"\n'
1161 <        txt += '    /bin/rm -rf $WORKING_DIR\n'
1162 <        txt += '    if [ -d $WORKING_DIR ] ;then\n'
1163 <        txt += '    echo "SET_EXE 60999 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after cleanup of WN"\n'
1164 <        txt += '    echo "JOB_EXIT_STATUS = 60999"\n'
1165 <        txt += '    echo "JobExitCode=60999" | tee -a $RUNTIME_AREA/$repo\n'
1166 <        txt += '    dumpStatus $RUNTIME_AREA/$repo\n'
1167 <        txt += '        rm -f $RUNTIME_AREA/$repo \n'
1168 <        txt += '        echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1169 <        txt += '        echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1170 <        txt += '    fi\n'
1171 <        txt += 'fi\n'
1172 <        txt += '\n'
1173 <
1174 <        file_list = ''
1175 <        ## Add to filelist only files to be possibly copied to SE
1176 <        for fileWithSuffix in self.output_file:
1177 <            output_file_num = self.numberFile_(fileWithSuffix, '$NJob')
1178 <            file_list=file_list+output_file_num+' '
1179 <        file_list=file_list[:-1]
1180 <        txt += 'file_list="'+file_list+'"\n'
1025 >        file_list = []
1026 >        for fileWithSuffix in (self.output_file):
1027 >             file_list.append(self.numberFile_(fileWithSuffix, '$NJob'))
1028  
1029 +        txt += 'file_list="'+string.join(file_list,' ')+'"\n'
1030 +        txt += '\n'
1031 +        txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
1032 +        txt += 'echo ">>> current directory content:"\n'
1033 +        txt += 'ls \n'
1034 +        txt += '\n'
1035 +        txt += 'cd $RUNTIME_AREA\n'
1036 +        txt += 'echo ">>> current directory (RUNTIME_AREA):  $RUNTIME_AREA"\n'
1037          return txt
1038  
1039      def numberFile_(self, file, txt):
# Line 1196 | Line 1051 | class Cmssw(JobType):
1051              result = name + '_' + txt + "." + ext
1052          else:
1053              result = name + '_' + txt
1054 <        
1054 >
1055          return result
1056  
1057      def getRequirements(self, nj=[]):
1058          """
1059 <        return job requirements to add to jdl files
1059 >        return job requirements to add to jdl files
1060          """
1061          req = ''
1062          if self.version:
1063              req='Member("VO-cms-' + \
1064                   self.version + \
1065                   '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1066 <        # if self.executable_arch:
1067 <        #     req='Member("VO-cms-' + \
1068 <        #          self.executable_arch + \
1069 <        #          '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1066 >        if self.executable_arch:
1067 >            req+=' && Member("VO-cms-' + \
1068 >                 self.executable_arch + \
1069 >                 '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1070  
1071          req = req + ' && (other.GlueHostNetworkAdapterOutboundIP)'
1072 +        if common.scheduler.name() == "glitecoll":
1073 +            req += ' && other.GlueCEStateStatus == "Production" '
1074  
1075          return req
1076  
1077      def configFilename(self):
1078          """ return the config filename """
1079 <        return self.name()+'.cfg'
1079 >        # FUTURE: Can remove cfg mode for CMSSW >= 2_1_x
1080 >        if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
1081 >          return self.name()+'.py'
1082 >        else:
1083 >          return self.name()+'.cfg'
1084  
1224    ### OLI_DANIELE
1085      def wsSetupCMSOSGEnvironment_(self):
1086          """
1087          Returns part of a job script which is prepares
1088          the execution environment and which is common for all CMS jobs.
1089          """
1090 <        txt = '\n'
1091 <        txt += '   echo "### SETUP CMS OSG  ENVIRONMENT ###"\n'
1092 <        txt += '   if [ -f $GRID3_APP_DIR/cmssoft/cmsset_default.sh ] ;then\n'
1093 <        txt += '      # Use $GRID3_APP_DIR/cmssoft/cmsset_default.sh to setup cms software\n'
1094 <        txt += '       export SCRAM_ARCH='+self.executable_arch+'\n'
1095 <        txt += '       source $GRID3_APP_DIR/cmssoft/cmsset_default.sh '+self.version+'\n'
1236 <        txt += '   elif [ -f $OSG_APP/cmssoft/cms/cmsset_default.sh ] ;then\n'
1090 >        txt = '\n#Written by cms_cmssw::wsSetupCMSOSGEnvironment_\n'
1091 >        txt += '    echo ">>> setup CMS OSG environment:"\n'
1092 >        txt += '    echo "set SCRAM ARCH to ' + self.executable_arch + '"\n'
1093 >        txt += '    export SCRAM_ARCH='+self.executable_arch+'\n'
1094 >        txt += '    echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
1095 >        txt += '    if [ -f $OSG_APP/cmssoft/cms/cmsset_default.sh ] ;then\n'
1096          txt += '      # Use $OSG_APP/cmssoft/cms/cmsset_default.sh to setup cms software\n'
1097 <        txt += '       export SCRAM_ARCH='+self.executable_arch+'\n'
1098 <        txt += '       source $OSG_APP/cmssoft/cms/cmsset_default.sh '+self.version+'\n'
1099 <        txt += '   else\n'
1100 <        txt += '       echo "SET_CMS_ENV 10020 ==> ERROR $GRID3_APP_DIR/cmssoft/cmsset_default.sh and $OSG_APP/cmssoft/cms/cmsset_default.sh file not found"\n'
1101 <        txt += '       echo "JOB_EXIT_STATUS = 10020"\n'
1102 <        txt += '       echo "JobExitCode=10020" | tee -a $RUNTIME_AREA/$repo\n'
1244 <        txt += '       dumpStatus $RUNTIME_AREA/$repo\n'
1245 <        txt += '       rm -f $RUNTIME_AREA/$repo \n'
1246 <        txt += '       echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1247 <        txt += '       echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1248 <        txt += '       exit 1\n'
1249 <        txt += '\n'
1250 <        txt += '       echo "Remove working directory: $WORKING_DIR"\n'
1251 <        txt += '       cd $RUNTIME_AREA\n'
1252 <        txt += '       /bin/rm -rf $WORKING_DIR\n'
1253 <        txt += '       if [ -d $WORKING_DIR ] ;then\n'
1254 <        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/cms/cmsset_default.sh file not found"\n'
1255 <        txt += '        echo "JOB_EXIT_STATUS = 10017"\n'
1256 <        txt += '        echo "JobExitCode=10017" | tee -a $RUNTIME_AREA/$repo\n'
1257 <        txt += '        dumpStatus $RUNTIME_AREA/$repo\n'
1258 <        txt += '            rm -f $RUNTIME_AREA/$repo \n'
1259 <        txt += '            echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1260 <        txt += '            echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1261 <        txt += '       fi\n'
1262 <        txt += '\n'
1263 <        txt += '       exit 1\n'
1264 <        txt += '   fi\n'
1097 >        txt += '        source $OSG_APP/cmssoft/cms/cmsset_default.sh '+self.version+'\n'
1098 >        txt += '    else\n'
1099 >        txt += '        echo "ERROR ==> $OSG_APP/cmssoft/cms/cmsset_default.sh file not found"\n'
1100 >        txt += '        job_exit_code=10020\n'
1101 >        txt += '        func_exit\n'
1102 >        txt += '    fi\n'
1103          txt += '\n'
1104 <        txt += '   echo "SET_CMS_ENV 0 ==> setup cms environment ok"\n'
1105 <        txt += '   echo " END SETUP CMS OSG  ENVIRONMENT "\n'
1104 >        txt += '    echo "==> setup cms environment ok"\n'
1105 >        txt += '    echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
1106  
1107          return txt
1108 <
1271 <    ### OLI_DANIELE
1108 >
1109      def wsSetupCMSLCGEnvironment_(self):
1110          """
1111          Returns part of a job script which is prepares
1112          the execution environment and which is common for all CMS jobs.
1113          """
1114 <        txt  = '   \n'
1115 <        txt += '   echo " ### SETUP CMS LCG  ENVIRONMENT ### "\n'
1116 <        txt += '   if [ ! $VO_CMS_SW_DIR ] ;then\n'
1117 <        txt += '       echo "SET_CMS_ENV 10031 ==> ERROR CMS software dir not found on WN `hostname`"\n'
1118 <        txt += '       echo "JOB_EXIT_STATUS = 10031" \n'
1119 <        txt += '       echo "JobExitCode=10031" | tee -a $RUNTIME_AREA/$repo\n'
1120 <        txt += '       dumpStatus $RUNTIME_AREA/$repo\n'
1121 <        txt += '       rm -f $RUNTIME_AREA/$repo \n'
1122 <        txt += '       echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1123 <        txt += '       echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1124 <        txt += '       exit 1\n'
1125 <        txt += '   else\n'
1126 <        txt += '       echo "Sourcing environment... "\n'
1127 <        txt += '       if [ ! -s $VO_CMS_SW_DIR/cmsset_default.sh ] ;then\n'
1128 <        txt += '           echo "SET_CMS_ENV 10020 ==> ERROR cmsset_default.sh file not found into dir $VO_CMS_SW_DIR"\n'
1129 <        txt += '           echo "JOB_EXIT_STATUS = 10020"\n'
1130 <        txt += '           echo "JobExitCode=10020" | tee -a $RUNTIME_AREA/$repo\n'
1131 <        txt += '           dumpStatus $RUNTIME_AREA/$repo\n'
1132 <        txt += '           rm -f $RUNTIME_AREA/$repo \n'
1133 <        txt += '           echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1134 <        txt += '           echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1135 <        txt += '           exit 1\n'
1136 <        txt += '       fi\n'
1137 <        txt += '       echo "sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1138 <        txt += '       source $VO_CMS_SW_DIR/cmsset_default.sh\n'
1139 <        txt += '       result=$?\n'
1140 <        txt += '       if [ $result -ne 0 ]; then\n'
1304 <        txt += '           echo "SET_CMS_ENV 10032 ==> ERROR problem sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1305 <        txt += '           echo "JOB_EXIT_STATUS = 10032"\n'
1306 <        txt += '           echo "JobExitCode=10032" | tee -a $RUNTIME_AREA/$repo\n'
1307 <        txt += '           dumpStatus $RUNTIME_AREA/$repo\n'
1308 <        txt += '           rm -f $RUNTIME_AREA/$repo \n'
1309 <        txt += '           echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1310 <        txt += '           echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1311 <        txt += '           exit 1\n'
1312 <        txt += '       fi\n'
1313 <        txt += '   fi\n'
1314 <        txt += '   \n'
1315 <        txt += '   echo "SET_CMS_ENV 0 ==> setup cms environment ok"\n'
1316 <        txt += '   echo "### END SETUP CMS LCG ENVIRONMENT ###"\n'
1114 >        txt = '\n#Written by cms_cmssw::wsSetupCMSLCGEnvironment_\n'
1115 >        txt += '    echo ">>> setup CMS LCG environment:"\n'
1116 >        txt += '    echo "set SCRAM ARCH and BUILD_ARCH to ' + self.executable_arch + ' ###"\n'
1117 >        txt += '    export SCRAM_ARCH='+self.executable_arch+'\n'
1118 >        txt += '    export BUILD_ARCH='+self.executable_arch+'\n'
1119 >        txt += '    if [ ! $VO_CMS_SW_DIR ] ;then\n'
1120 >        txt += '        echo "ERROR ==> CMS software dir not found on WN `hostname`"\n'
1121 >        txt += '        job_exit_code=10031\n'
1122 >        txt += '        func_exit\n'
1123 >        txt += '    else\n'
1124 >        txt += '        echo "Sourcing environment... "\n'
1125 >        txt += '        if [ ! -s $VO_CMS_SW_DIR/cmsset_default.sh ] ;then\n'
1126 >        txt += '            echo "ERROR ==> cmsset_default.sh file not found into dir $VO_CMS_SW_DIR"\n'
1127 >        txt += '            job_exit_code=10020\n'
1128 >        txt += '            func_exit\n'
1129 >        txt += '        fi\n'
1130 >        txt += '        echo "sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1131 >        txt += '        source $VO_CMS_SW_DIR/cmsset_default.sh\n'
1132 >        txt += '        result=$?\n'
1133 >        txt += '        if [ $result -ne 0 ]; then\n'
1134 >        txt += '            echo "ERROR ==> problem sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1135 >        txt += '            job_exit_code=10032\n'
1136 >        txt += '            func_exit\n'
1137 >        txt += '        fi\n'
1138 >        txt += '    fi\n'
1139 >        txt += '    \n'
1140 >        txt += '    echo "==> setup cms environment ok"\n'
1141          return txt
1142  
1319    ### FEDE FOR DBS OUTPUT PUBLICATION
1143      def modifyReport(self, nj):
1144          """
1145 <        insert the part of the script that modifies the FrameworkJob Report
1145 >        insert the part of the script that modifies the FrameworkJob Report
1146          """
1147 <        
1148 <        txt = ''
1149 <        txt += 'echo "Modify Job Report" \n'
1150 <        txt += 'chmod a+x $RUNTIME_AREA/'+self.version+'/ProdAgentApi/FwkJobRep/ModifyJobReport.py\n'
1151 <        txt += 'if [ -z "$SE" ]; then\n'
1152 <        txt += '    SE="" \n'
1153 <        txt += 'fi \n'
1154 <        txt += 'if [ -z "$SE_PATH" ]; then\n'
1155 <        txt += '    SE_PATH="" \n'
1156 <        txt += 'fi \n'
1157 <        txt += 'echo "SE = $SE"\n'
1158 <        txt += 'echo "SE_PATH = $SE_PATH"\n'
1159 <        txt += 'FOR_LFN=$DatasetPath/$MonitorID\n'
1160 <        txt += 'echo "FOR_LFN = $FOR_LFN"\n'
1161 <        txt += 'echo "CMSSW_VERSION = $CMSSW_VERSION"\n'
1162 <        txt += 'echo "$RUNTIME_AREA/'+self.version+'/ProdAgentApi/FwkJobRep/ModifyJobReport.py crab_fjr_$NJob.xml $NJob $FOR_LFN $PrimaryDataset $DataTier $ProcessedDataset $ApplicationFamily $executable $CMSSW_VERSION $PSETHASH $SE $SE_PATH"\n'
1163 <        txt += '$RUNTIME_AREA/'+self.version+'/ProdAgentApi/FwkJobRep/ModifyJobReport.py crab_fjr_$NJob.xml $NJob $FOR_LFN $PrimaryDataset $DataTier $ProcessedDataset $ApplicationFamily $executable $CMSSW_VERSION $PSETHASH $SE $SE_PATH\n'
1164 <        txt += 'modifyReport_result=$?\n'
1165 <        txt += 'echo modifyReport_result = $modifyReport_result\n'
1166 <        txt += 'if [ $modify_result -ne 0 ]; then\n'
1167 <        txt += '    exit_status=1\n'
1168 <        txt += '    echo "ERROR: Problem with ModifyJobReport"\n'
1169 <        txt += 'else\n'
1170 <        txt += '    mv NewFrameworkJobReport.xml crab_fjr_$NJob.xml\n'
1171 <        txt += 'fi\n'
1147 >
1148 >        txt = '\n#Written by cms_cmssw::modifyReport\n'
1149 >        publish_data = int(self.cfg_params.get('USER.publish_data',0))
1150 >        if (publish_data == 1):
1151 >            processedDataset = self.cfg_params['USER.publish_data_name']
1152 >            LFNBaseName = LFNBase(processedDataset)
1153 >
1154 >            txt += 'if [ $copy_exit_status -eq 0 ]; then\n'
1155 >            txt += '    FOR_LFN=%s_${PSETHASH}/\n'%(LFNBaseName)
1156 >            txt += 'else\n'
1157 >            txt += '    FOR_LFN=/copy_problems/ \n'
1158 >            txt += '    SE=""\n'
1159 >            txt += '    SE_PATH=""\n'
1160 >            txt += 'fi\n'
1161 >
1162 >            txt += 'echo ">>> Modify Job Report:" \n'
1163 >            txt += 'chmod a+x $SOFTWARE_DIR/ProdCommon/ProdCommon/FwkJobRep/ModifyJobReport.py\n'
1164 >            txt += 'ProcessedDataset='+processedDataset+'\n'
1165 >            txt += 'echo "ProcessedDataset = $ProcessedDataset"\n'
1166 >            txt += 'echo "SE = $SE"\n'
1167 >            txt += 'echo "SE_PATH = $SE_PATH"\n'
1168 >            txt += 'echo "FOR_LFN = $FOR_LFN" \n'
1169 >            txt += 'echo "CMSSW_VERSION = $CMSSW_VERSION"\n\n'
1170 >            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'
1171 >            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'
1172 >            txt += 'modifyReport_result=$?\n'
1173 >            txt += 'if [ $modifyReport_result -ne 0 ]; then\n'
1174 >            txt += '    modifyReport_result=70500\n'
1175 >            txt += '    job_exit_code=$modifyReport_result\n'
1176 >            txt += '    echo "ModifyReportResult=$modifyReport_result" | tee -a $RUNTIME_AREA/$repo\n'
1177 >            txt += '    echo "WARNING: Problem with ModifyJobReport"\n'
1178 >            txt += 'else\n'
1179 >            txt += '    mv NewFrameworkJobReport.xml $RUNTIME_AREA/crab_fjr_$NJob.xml\n'
1180 >            txt += 'fi\n'
1181          return txt
1350    #################
1182  
1183      def setParam_(self, param, value):
1184          self._params[param] = value
# Line 1355 | Line 1186 | class Cmssw(JobType):
1186      def getParams(self):
1187          return self._params
1188  
1358    def setTaskid_(self):
1359        self._taskId = self.cfg_params['taskId']
1360        
1361    def getTaskid(self):
1362        return self._taskId
1363
1364 #######################################################################
1189      def uniquelist(self, old):
1190          """
1191          remove duplicates from a list
# Line 1370 | Line 1194 | class Cmssw(JobType):
1194          for e in old:
1195              nd[e]=0
1196          return nd.keys()
1197 +
1198 +    def outList(self):
1199 +        """
1200 +        check the dimension of the output files
1201 +        """
1202 +        txt = ''
1203 +        txt += 'echo ">>> list of expected files on output sandbox"\n'
1204 +        listOutFiles = []
1205 +        stdout = 'CMSSW_$NJob.stdout'
1206 +        stderr = 'CMSSW_$NJob.stderr'
1207 +        if (self.return_data == 1):
1208 +            for file in (self.output_file+self.output_file_sandbox):
1209 +                listOutFiles.append(self.numberFile_(file, '$NJob'))
1210 +            listOutFiles.append(stdout)
1211 +            listOutFiles.append(stderr)
1212 +        else:
1213 +            for file in (self.output_file_sandbox):
1214 +                listOutFiles.append(self.numberFile_(file, '$NJob'))
1215 +            listOutFiles.append(stdout)
1216 +            listOutFiles.append(stderr)
1217 +        txt += 'echo "output files: '+string.join(listOutFiles,' ')+'"\n'
1218 +        txt += 'filesToCheck="'+string.join(listOutFiles,' ')+'"\n'
1219 +        txt += 'export filesToCheck\n'
1220 +        return txt

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines