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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines