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.13 by gutsche, Tue Jun 27 02:31:31 2006 UTC vs.
Revision 1.41 by slacapra, Wed Sep 20 17:29:52 2006 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 + import math
6   import common
7   import PsetManipulator  
8  
9 < import DBSInfo_EDM
10 < import DataDiscovery_EDM
11 < import DataLocation_EDM
9 > import DBSInfo
10 > import DataDiscovery
11 > import DataLocation
12   import Scram
13  
14   import os, string, re
15  
16   class Cmssw(JobType):
17 <    def __init__(self, cfg_params):
17 >    def __init__(self, cfg_params, ncjobs):
18          JobType.__init__(self, 'CMSSW')
19          common.logger.debug(3,'CMSSW::__init__')
20  
# Line 21 | Line 22 | class Cmssw(JobType):
22          # Marco.
23          self._params = {}
24          self.cfg_params = cfg_params
25 +
26 +        # number of jobs requested to be created, limit ojb splitting
27 +        self.ncjobs = ncjobs
28 +
29          log = common.logger
30          
31          self.scram = Scram.Scram(cfg_params)
# Line 44 | Line 49 | class Cmssw(JobType):
49              log.debug(6, "CMSSW::CMSSW(): datasetPath = "+tmp)
50              if string.lower(tmp)=='none':
51                  self.datasetPath = None
52 +                self.selectNoInput = 1
53              else:
54                  self.datasetPath = tmp
55 +                self.selectNoInput = 0
56          except KeyError:
57              msg = "Error: datasetpath not defined "  
58              raise CrabException(msg)
# Line 120 | Line 127 | class Cmssw(JobType):
127                    
128          ## additional input files
129          try:
130 <            tmpAddFiles = string.split(cfg_params['CMSSW.additional_input_files'],',')
130 >            tmpAddFiles = string.split(cfg_params['USER.additional_input_files'],',')
131              for tmp in tmpAddFiles:
132                  if not os.path.exists(tmp):
133                      raise CrabException("Additional input file not found: "+tmp)
134 <                tmp=string.strip(tmp)
128 <                self.additional_inbox_files.append(tmp)
134 >                self.additional_inbox_files.append(string.strip(tmp))
135                  pass
136              pass
137          except KeyError:
# Line 133 | Line 139 | class Cmssw(JobType):
139  
140          # files per job
141          try:
142 <            self.filesPerJob = int(cfg_params['CMSSW.files_per_jobs']) #Daniele
143 <            self.selectFilesPerJob = 1
142 >            if (cfg_params['CMSSW.files_per_jobs']):
143 >                raise CrabException("files_per_jobs no longer supported.  Quitting.")
144          except KeyError:
145 <            self.filesPerJob = 0
140 <            self.selectFilesPerJob = 0
145 >            pass
146  
147          ## Events per job
148          try:
# Line 147 | Line 152 | class Cmssw(JobType):
152              self.eventsPerJob = -1
153              self.selectEventsPerJob = 0
154      
155 <        # To be implemented
156 <        # ## number of jobs
157 <        # try:
158 <        #     self.numberOfJobs =int( cfg_params['CMSSW.number_of_job'])
159 <        #     self.selectNumberOfJobs = 1
160 <        # except KeyError:
161 <        #     self.selectNumberOfJobs = 0
157 <
158 <        if (self.selectFilesPerJob == self.selectEventsPerJob):
159 <            msg = 'Must define either files_per_jobs or events_per_job'
160 <            raise CrabException(msg)
155 >        ## number of jobs
156 >        try:
157 >            self.theNumberOfJobs =int( cfg_params['CMSSW.number_of_jobs'])
158 >            self.selectNumberOfJobs = 1
159 >        except KeyError:
160 >            self.theNumberOfJobs = 0
161 >            self.selectNumberOfJobs = 0
162  
162        if (self.selectEventsPerJob  and not self.datasetPath == None):
163            msg = 'Splitting according to events_per_job available only with None as datasetpath'
164            raise CrabException(msg)
165    
163          try:
164              self.total_number_of_events = int(cfg_params['CMSSW.total_number_of_events'])
165 +            self.selectTotalNumberEvents = 1
166          except KeyError:
167 <            msg = 'Must define total_number_of_events'
167 >            self.total_number_of_events = 0
168 >            self.selectTotalNumberEvents = 0
169 >
170 >        if ( (self.selectTotalNumberEvents + self.selectEventsPerJob + self.selectNumberOfJobs) != 2 ):
171 >            msg = 'Must define exactly two of total_number_of_events, events_per_job, or number_of_jobs.'
172              raise CrabException(msg)
173 <        
174 <        CEBlackList = []
173 >
174 >        ## source seed for pythia
175          try:
176 <            tmpBad = string.split(cfg_params['EDG.ce_black_list'],',')
175 <            for tmp in tmpBad:
176 <                tmp=string.strip(tmp)
177 <                CEBlackList.append(tmp)
176 >            self.sourceSeed = int(cfg_params['CMSSW.pythia_seed'])
177          except KeyError:
178 <            pass
178 >            self.sourceSeed = None
179 >            common.logger.debug(5,"No seed given")
180  
181        self.reCEBlackList=[]
182        for bad in CEBlackList:
183            self.reCEBlackList.append(re.compile( bad ))
184
185        common.logger.debug(5,'CEBlackList: '+str(CEBlackList))
186
187        CEWhiteList = []
181          try:
182 <            tmpGood = string.split(cfg_params['EDG.ce_white_list'],',')
190 <            for tmp in tmpGood:
191 <                tmp=string.strip(tmp)
192 <                CEWhiteList.append(tmp)
182 >            self.sourceSeedVtx = int(cfg_params['CMSSW.vtx_seed'])
183          except KeyError:
184 <            pass
185 <
196 <        #print 'CEWhiteList: ',CEWhiteList
197 <        self.reCEWhiteList=[]
198 <        for Good in CEWhiteList:
199 <            self.reCEWhiteList.append(re.compile( Good ))
200 <
201 <        common.logger.debug(5,'CEWhiteList: '+str(CEWhiteList))
184 >            self.sourceSeedVtx = None
185 >            common.logger.debug(5,"No vertex seed given")
186  
187          self.PsetEdit = PsetManipulator.PsetManipulator(self.pset) #Daniele Pset
188  
# Line 206 | Line 190 | class Cmssw(JobType):
190          ## Initialize the variables that are extracted from DBS/DLS and needed in other places of the code
191          self.maxEvents=0  # max events available   ( --> check the requested nb. of evts in Creator.py)
192          self.DBSPaths={}  # all dbs paths requested ( --> input to the site local discovery script)
193 +        self.jobDestination=[]  # Site destination(s) for each job (list of lists)
194          ## Perform the data location and discovery (based on DBS/DLS)
195          ## SL: Don't if NONE is specified as input (pythia use case)
196 <        common.analisys_common_info['sites']=None
196 >        blockSites = {}
197          if self.datasetPath:
198 <            self.DataDiscoveryAndLocation(cfg_params)
198 >            blockSites = self.DataDiscoveryAndLocation(cfg_params)
199          #DBSDLS-end          
200  
201          self.tgzNameWithPath = self.getTarBall(self.executable)
217
218        # modify Pset
219        if (self.datasetPath): # standard job
220            self.PsetEdit.maxEvent(self.eventsPerJob) #Daniele  
221            self.PsetEdit.inputModule("INPUT") #Daniele
222
223        else:  # pythia like job
224            self.PsetEdit.maxEvent(self.eventsPerJob) #Daniele  
225            self.PsetEdit.pythiaSeed("INPUT") #Daniele
226            try:
227                self.sourceSeed = int(cfg_params['CMSSW.pythia_seed'])
228            except KeyError:
229                self.sourceSeed = 123456
230                common.logger.message("No seed given, will use "+str(self.sourceSeed))
231        
232        self.PsetEdit.psetWriter(self.configFilename())
202      
203          ## Select Splitting
204 <        if self.selectFilesPerJob: self.jobSplittingPerFiles()
205 <        elif self.selectEventsPerJob: self.jobSplittingPerEvents()
237 <        else:
238 <            msg = 'Don\'t know how to split...'
239 <            raise CrabException(msg)
204 >        if self.selectNoInput: self.jobSplittingNoInput()
205 >        else: self.jobSplittingByBlocks(blockSites)
206  
207 +        # modify Pset
208 +        try:
209 +            if (self.datasetPath): # standard job
210 +                # allow to processa a fraction of events in a file
211 +                self.PsetEdit.inputModule("INPUT")
212 +                self.PsetEdit.maxEvent("INPUTMAXEVENTS")
213 +                self.PsetEdit.skipEvent("INPUTSKIPEVENTS")
214 +
215 +            else:  # pythia like job
216 +                self.PsetEdit.maxEvent(self.eventsPerJob)
217 +                if (self.sourceSeed) :
218 +                    self.PsetEdit.pythiaSeed("INPUT")
219 +                    if (self.sourceSeedVtx) :
220 +                        self.PsetEdit.pythiaSeedVtx("INPUTVTX")
221 +            self.PsetEdit.psetWriter(self.configFilename())
222 +        except:
223 +            msg='Error while manipuliating ParameterSet: exiting...'
224 +            raise CrabException(msg)
225  
226      def DataDiscoveryAndLocation(self, cfg_params):
227  
# Line 250 | Line 234 | class Cmssw(JobType):
234          dataTiers = dataTiersList.split(',')
235  
236          ## Contact the DBS
237 +        common.logger.message("Contacting DBS...")
238          try:
239 <            self.pubdata=DataDiscovery_EDM.DataDiscovery_EDM(datasetPath, dataTiers, cfg_params)
239 >            self.pubdata=DataDiscovery.DataDiscovery(datasetPath, dataTiers, cfg_params)
240              self.pubdata.fetchDBSInfo()
241  
242 <        except DataDiscovery_EDM.NotExistingDatasetError, ex :
242 >        except DataDiscovery.NotExistingDatasetError, ex :
243              msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
244              raise CrabException(msg)
245  
246 <        except DataDiscovery_EDM.NoDataTierinProvenanceError, ex :
246 >        except DataDiscovery.NoDataTierinProvenanceError, ex :
247              msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
248              raise CrabException(msg)
249 <        except DataDiscovery_EDM.DataDiscoveryError, ex:
249 >        except DataDiscovery.DataDiscoveryError, ex:
250              msg = 'ERROR ***: failed Data Discovery in DBS  %s'%ex.getErrorMessage()
251              raise CrabException(msg)
252  
# Line 269 | Line 254 | class Cmssw(JobType):
254          ## self.DBSPaths=self.pubdata.getDBSPaths()
255          common.logger.message("Required data are :"+self.datasetPath)
256  
257 <        filesbyblock=self.pubdata.getFiles()
258 <        self.AllInputFiles=filesbyblock.values()
259 <        self.files = self.AllInputFiles        
260 <
261 <        ## TEMP
262 <    #    self.filesTmp = filesbyblock.values()
278 <    #    self.files = []
279 <    #    locPath='rfio:cmsbose2.bo.infn.it:/flatfiles/SE00/cms/fanfani/ProdTest/'
280 <    #    locPath=''
281 <    #    tmp = []
282 <    #    for file in self.filesTmp[0]:
283 <    #        tmp.append(locPath+file)
284 <    #    self.files.append(tmp)
285 <        ## END TEMP
257 >        self.filesbyblock=self.pubdata.getFiles()
258 >        self.eventsbyblock=self.pubdata.getEventsPerBlock()
259 >        self.eventsbyfile=self.pubdata.getEventsPerFile()
260 >        # print str(self.filesbyblock)
261 >        # print 'self.eventsbyfile',len(self.eventsbyfile)
262 >        # print str(self.eventsbyfile)
263  
264          ## get max number of events
288        #common.logger.debug(10,"number of events for primary fileblocks %i"%self.pubdata.getMaxEvents())
265          self.maxEvents=self.pubdata.getMaxEvents() ##  self.maxEvents used in Creator.py
266          common.logger.message("\nThe number of available events is %s"%self.maxEvents)
267  
268 +        common.logger.message("Contacting DLS...")
269          ## Contact the DLS and build a list of sites hosting the fileblocks
270          try:
271 <            dataloc=DataLocation_EDM.DataLocation_EDM(filesbyblock.keys(),cfg_params)
271 >            dataloc=DataLocation.DataLocation(self.filesbyblock.keys(),cfg_params)
272              dataloc.fetchDLSInfo()
273 <        except DataLocation_EDM.DataLocationError , ex:
273 >        except DataLocation.DataLocationError , ex:
274              msg = 'ERROR ***: failed Data Location in DLS \n %s '%ex.getErrorMessage()
275              raise CrabException(msg)
276          
300        allsites=dataloc.getSites()
301        common.logger.debug(5,"sites are %s"%allsites)
302        sites=self.checkBlackList(allsites)
303        common.logger.debug(5,"sites are (after black list) %s"%sites)
304        sites=self.checkWhiteList(sites)
305        common.logger.debug(5,"sites are (after white list) %s"%sites)
277  
278 <        if len(sites)==0:
279 <            msg = 'No sites hosting all the needed data! Exiting... '
280 <            raise CrabException(msg)
278 >        sites = dataloc.getSites()
279 >        allSites = []
280 >        listSites = sites.values()
281 >        for list in listSites:
282 >            for oneSite in list:
283 >                allSites.append(oneSite)
284 >        allSites = self.uniquelist(allSites)
285  
286 <        common.logger.message("List of Sites hosting the data : "+str(sites))
287 <        common.logger.debug(6, "List of Sites: "+str(sites))
288 <        common.analisys_common_info['sites']=sites    ## used in SchedulerEdg.py in createSchScript
314 <        self.setParam_('TargetCE', ','.join(sites))
315 <        return
286 >        common.logger.message("Sites ("+str(len(allSites))+") hosting part/all of dataset: "+str(allSites))
287 >        common.logger.debug(6, "List of Sites: "+str(allSites))
288 >        return sites
289      
290 <    def jobSplittingPerFiles(self):
290 >    def jobSplittingByBlocks(self, blockSites):
291          """
292 <        Perform job splitting based on number of files to be accessed per job
293 <        """
294 <        common.logger.debug(5,'Splitting per input files')
295 <        common.logger.message('Required '+str(self.filesPerJob)+' files per job ')
296 <        common.logger.message('Required '+str(self.total_number_of_events)+' events in total ')
297 <
298 <        ## TODO: SL need to have (from DBS) a detailed list of how many events per each file
299 <        n_tot_files = (len(self.files[0]))
300 <        #print "n_tot_files = ", n_tot_files
301 <        ## SL: this is wrong if the files have different number of events
302 <        #print "self.maxEvents = ", self.maxEvents
303 <        evPerFile = int(self.maxEvents)/n_tot_files
304 <        #print "evPerFile = int(self.maxEvents)/n_tot_files =  ", evPerFile
305 <
306 <        common.logger.debug(5,'Events per File '+str(evPerFile))
307 <
308 <        ## if asked to process all events, do it
309 <        if self.total_number_of_events == -1:
310 <            self.total_number_of_events=self.maxEvents
311 <            self.total_number_of_jobs = int(n_tot_files)*1/int(self.filesPerJob)
312 <            common.logger.message(str(self.total_number_of_jobs)+' jobs will be created for all available events '+str(self.total_number_of_events)+' events')
313 <        
292 >        Perform job splitting. Jobs run over an integer number of files
293 >        and no more than one block.
294 >        ARGUMENT: blockSites: dictionary with blocks as keys and list of host sites as values
295 >        REQUIRES: self.selectTotalNumberEvents, self.selectEventsPerJob, self.selectNumberofJobs,
296 >                  self.total_number_of_events, self.eventsPerJob, self.theNumberOfJobs,
297 >                  self.maxEvents, self.filesbyblock
298 >        SETS: self.jobDestination - Site destination(s) for each job (a list of lists)
299 >              self.total_number_of_jobs - Total # of jobs
300 >              self.list_of_args - File(s) job will run on (a list of lists)
301 >        """
302 >
303 >        # ---- Handle the possible job splitting configurations ---- #
304 >        if (self.selectTotalNumberEvents):
305 >            totalEventsRequested = self.total_number_of_events
306 >        if (self.selectEventsPerJob):
307 >            eventsPerJobRequested = self.eventsPerJob
308 >            if (self.selectNumberOfJobs):
309 >                totalEventsRequested = self.theNumberOfJobs * self.eventsPerJob
310 >
311 >        # If user requested all the events in the dataset
312 >        if (totalEventsRequested == -1):
313 >            eventsRemaining=self.maxEvents
314 >        # If user requested more events than are in the dataset
315 >        elif (totalEventsRequested > self.maxEvents):
316 >            eventsRemaining = self.maxEvents
317 >            common.logger.message("Requested "+str(self.total_number_of_events)+ " events, but only "+str(self.maxEvents)+" events are available.")
318 >        # If user requested less events than are in the dataset
319          else:
320 <            #print "self.total_number_of_events = ", self.total_number_of_events
321 <            #print "evPerFile = ", evPerFile
322 <            self.total_number_of_files = int(self.total_number_of_events/evPerFile)
323 <            #print "self.total_number_of_files = int(self.total_number_of_events/evPerFile) = " , self.total_number_of_files
324 <            ## SL: if ask for less event than what is computed to be available on a
325 <            ##     file, process the first file anyhow.
326 <            if self.total_number_of_files == 0:
327 <                self.total_number_of_files = self.total_number_of_files + 1
328 <                
320 >            eventsRemaining = totalEventsRequested
321 >
322 >        # If user requested more events per job than are in the dataset
323 >        if (self.selectEventsPerJob and eventsPerJobRequested > self.maxEvents):
324 >            eventsPerJobRequested = self.maxEvents
325 >
326 >        # For user info at end
327 >        totalEventCount = 0
328 >
329 >        if (self.selectTotalNumberEvents and self.selectNumberOfJobs):
330 >            eventsPerJobRequested = int(eventsRemaining/self.theNumberOfJobs)
331  
332 <            common.logger.debug(5,'N files  '+str(self.total_number_of_files))
332 >        if (self.selectNumberOfJobs):
333 >            common.logger.message("May not create the exact number_of_jobs requested.")
334  
335 <            check = 0
335 >        if ( self.ncjobs == 'all' ) :
336 >            totalNumberOfJobs = 999999999
337 >        else :
338 >            totalNumberOfJobs = self.ncjobs
339              
356            ## Compute the number of jobs
357            #self.total_number_of_jobs = int(n_tot_files)*1/int(self.filesPerJob)
358            #print "self.total_number_of_files = ", self.total_number_of_files
359            #print "self.filesPerJob = ", self.filesPerJob
360            self.total_number_of_jobs = int(self.total_number_of_files/self.filesPerJob)
361            #print "self.total_number_of_jobs = ", self.total_number_of_jobs
362            common.logger.debug(5,'N jobs  '+str(self.total_number_of_jobs))
363
364            ## is there any remainder?
365            check = int(self.total_number_of_files) - (int(self.total_number_of_jobs)*self.filesPerJob)
366
367            common.logger.debug(5,'Check  '+str(check))
368
369            if check > 0:
370                self.total_number_of_jobs =  self.total_number_of_jobs + 1
371                common.logger.message('Warning: last job will be created with '+str(check)+' files')
340  
341 <            #common.logger.message(str(self.total_number_of_jobs)+' jobs will be created for a total of '+str((self.total_number_of_jobs-1)*self.filesPerJob*evPerFile + check*evPerFile)+' events')
342 <            common.logger.message(str(self.total_number_of_jobs)+' jobs will be created for a total of '+str((self.total_number_of_jobs)*self.filesPerJob*evPerFile + check*evPerFile)+' events')
343 <            pass
341 >        blocks = blockSites.keys()
342 >        blockCount = 0
343 >        # Backup variable in case self.maxEvents counted events in a non-included block
344 >        numBlocksInDataset = len(blocks)
345  
346 +        jobCount = 0
347          list_of_lists = []
348 <        for i in xrange(0, int(n_tot_files), self.filesPerJob):
349 <            parString = "\\{"
348 >
349 >        # ---- Iterate over the blocks in the dataset until ---- #
350 >        # ---- we've met the requested total # of events    ---- #
351 >        while ( (eventsRemaining > 0) and (blockCount < numBlocksInDataset) and (jobCount < totalNumberOfJobs)):
352 >            block = blocks[blockCount]
353 >
354 >
355 >            evInBlock = self.eventsbyblock[block]
356 >            common.logger.debug(5,'Events in Block File '+str(evInBlock))
357 >
358 >            #Correct - switch to this when DBS up
359 >            #numEventsInBlock = self.eventsbyblock[block]
360 >            numEventsInBlock = evInBlock
361              
362 <            params = self.files[0][i: i+self.filesPerJob]
363 <            for i in range(len(params) - 1):
364 <                parString += '\\\"' + params[i] + '\\\"\,'
362 >            files = self.filesbyblock[block]
363 >            numFilesInBlock = len(files)
364 >            if (numFilesInBlock <= 0):
365 >                continue
366 >            fileCount = 0
367 >
368 >            # ---- New block => New job ---- #
369 >            parString = "\\{"
370 >            # counter for number of events in files currently worked on
371 >            filesEventCount = 0
372 >            # flag if next while loop should touch new file
373 >            newFile = 1
374 >            # job event counter
375 >            jobSkipEventCount = 0
376              
377 <            parString += '\\\"' + params[len(params) - 1] + '\\\"\\}'
378 <            list_of_lists.append(parString)
379 <            pass
380 <
377 >            # ---- Iterate over the files in the block until we've met the requested ---- #
378 >            # ---- total # of events or we've gone over all the files in this block  ---- #
379 >            while ( (eventsRemaining > 0) and (fileCount < numFilesInBlock) and (jobCount < totalNumberOfJobs) ):
380 >                file = files[fileCount]
381 >                if newFile :
382 >                    try:
383 >                        numEventsInFile = self.eventsbyfile[file]
384 >                        common.logger.debug(6, "File "+str(file)+" has "+str(numEventsInFile)+" events")
385 >                        # increase filesEventCount
386 >                        filesEventCount += numEventsInFile
387 >                        # Add file to current job
388 >                        parString += '\\\"' + file + '\\\"\,'
389 >                        newFile = 0
390 >                    except KeyError:
391 >                        common.logger.message("File "+str(file)+" has unknown numbe of events: skipping")
392 >                        
393 >
394 >                # if less events in file remain than eventsPerJobRequested
395 >                if ( filesEventCount - jobSkipEventCount < eventsPerJobRequested ) :
396 >                    # if last file in block
397 >                    if ( fileCount == numFilesInBlock ) :
398 >                        # end job using last file, use remaining events in block
399 >                        # close job and touch new file
400 >                        fullString = parString[:-2]
401 >                        fullString += '\\}'
402 >                        list_of_lists.append([fullString,str(-1),str(jobSkipEventCount)])
403 >                        common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(filesEventCount - jobSkipEventCount)+" events (last file in block).")
404 >                        self.jobDestination.append(blockSites[block])
405 >                        common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
406 >                        # reset counter
407 >                        jobCount = jobCount + 1
408 >                        totalEventCount = totalEventCount + eventsPerJobRequested
409 >                        eventsRemaining = eventsRemaining - eventsPerJobRequested
410 >                        jobSkipEventCount = 0
411 >                        # reset file
412 >                        parString = "\\{"
413 >                        filesEventCount = 0
414 >                        newFile = 1
415 >                        fileCount += 1
416 >                    else :
417 >                        # go to next file
418 >                        newFile = 1
419 >                        fileCount += 1
420 >                # if events in file equal to eventsPerJobRequested
421 >                elif ( filesEventCount - jobSkipEventCount == eventsPerJobRequested ) :
422 >                    # close job and touch new file
423 >                    fullString = parString[:-2]
424 >                    fullString += '\\}'
425 >                    list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
426 >                    common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(eventsPerJobRequested)+" events.")
427 >                    self.jobDestination.append(blockSites[block])
428 >                    common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
429 >                    # reset counter
430 >                    jobCount = jobCount + 1
431 >                    totalEventCount = totalEventCount + eventsPerJobRequested
432 >                    eventsRemaining = eventsRemaining - eventsPerJobRequested
433 >                    jobSkipEventCount = 0
434 >                    # reset file
435 >                    parString = "\\{"
436 >                    filesEventCount = 0
437 >                    newFile = 1
438 >                    fileCount += 1
439 >                    
440 >                # if more events in file remain than eventsPerJobRequested
441 >                else :
442 >                    # close job but don't touch new file
443 >                    fullString = parString[:-2]
444 >                    fullString += '\\}'
445 >                    list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
446 >                    common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(eventsPerJobRequested)+" events.")
447 >                    self.jobDestination.append(blockSites[block])
448 >                    common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
449 >                    # increase counter
450 >                    jobCount = jobCount + 1
451 >                    totalEventCount = totalEventCount + eventsPerJobRequested
452 >                    eventsRemaining = eventsRemaining - eventsPerJobRequested
453 >                    # calculate skip events for last file
454 >                    # use filesEventCount (contains several files), jobSkipEventCount and eventsPerJobRequest
455 >                    jobSkipEventCount = eventsPerJobRequested - (filesEventCount - jobSkipEventCount - self.eventsbyfile[file])
456 >                    # remove all but the last file
457 >                    filesEventCount = self.eventsbyfile[file]
458 >                    parString = "\\{"
459 >                    parString += '\\\"' + file + '\\\"\,'
460 >                pass # END if
461 >            pass # END while (iterate over files in the block)
462 >        pass # END while (iterate over blocks in the dataset)
463 >        self.ncjobs = self.total_number_of_jobs = jobCount
464 >        if (eventsRemaining > 0 and jobCount < totalNumberOfJobs ):
465 >            common.logger.message("Could not run on all requested events because some blocks not hosted at allowed sites.")
466 >        common.logger.message("\n"+str(jobCount)+" job(s) can run on "+str(totalEventCount)+" events.\n")
467 >        
468          self.list_of_args = list_of_lists
390        #print self.list_of_args
469          return
470  
471 <    def jobSplittingPerEvents(self):
471 >    def jobSplittingNoInput(self):
472          """
473          Perform job splitting based on number of event per job
474          """
475          common.logger.debug(5,'Splitting per events')
476          common.logger.message('Required '+str(self.eventsPerJob)+' events per job ')
477 +        common.logger.message('Required '+str(self.theNumberOfJobs)+' jobs in total ')
478          common.logger.message('Required '+str(self.total_number_of_events)+' events in total ')
479  
480          if (self.total_number_of_events < 0):
481              msg='Cannot split jobs per Events with "-1" as total number of events'
482              raise CrabException(msg)
483  
484 <        self.total_number_of_jobs = int(self.total_number_of_events/self.eventsPerJob)
484 >        if (self.selectEventsPerJob):
485 >            self.total_number_of_jobs = int(self.total_number_of_events/self.eventsPerJob)
486 >        elif (self.selectNumberOfJobs) :
487 >            self.total_number_of_jobs = self.theNumberOfJobs
488 >            self.eventsPerJob = int(self.total_number_of_events/self.total_number_of_jobs)
489  
407        print "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
408        print "self.total_number_of_events = ", self.total_number_of_events
409        print "self.eventsPerJob = ", self.eventsPerJob
410        print "self.total_number_of_jobs = ", self.total_number_of_jobs
411        print "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
412        
490          common.logger.debug(5,'N jobs  '+str(self.total_number_of_jobs))
491  
492          # is there any remainder?
# Line 417 | Line 494 | class Cmssw(JobType):
494  
495          common.logger.debug(5,'Check  '+str(check))
496  
497 +        common.logger.message(str(self.total_number_of_jobs)+' jobs can be created, each for '+str(self.eventsPerJob)+' for a total of '+str(self.total_number_of_jobs*self.eventsPerJob)+' events')
498          if check > 0:
499 <            common.logger.message('Warning: asked '+self.total_number_of_events+' but will do only '+(int(self.total_number_of_jobs)*self.eventsPerJob))
422 <
423 <        common.logger.message(str(self.total_number_of_jobs)+' jobs will be created for a total of '+str(self.total_number_of_jobs*self.eventsPerJob)+' events')
499 >            common.logger.message('Warning: asked '+str(self.total_number_of_events)+' but can do only '+str(int(self.total_number_of_jobs)*self.eventsPerJob))
500  
501          # argument is seed number.$i
502          self.list_of_args = []
503          for i in range(self.total_number_of_jobs):
504 <            self.list_of_args.append(int(str(self.sourceSeed)+str(i)))
505 <        print self.list_of_args
504 >            ## Since there is no input, any site is good
505 >            self.jobDestination.append(["Any"])
506 >            if (self.sourceSeed):
507 >                if (self.sourceSeedVtx):
508 >                    ## pythia + vtx random seed
509 >                    self.list_of_args.append([
510 >                                              str(self.sourceSeed)+str(i),
511 >                                              str(self.sourceSeedVtx)+str(i)
512 >                                              ])
513 >                else:
514 >                    ## only pythia random seed
515 >                    self.list_of_args.append([(str(self.sourceSeed)+str(i))])
516 >            else:
517 >                ## no random seed
518 >                self.list_of_args.append([str(i)])
519 >        #print self.list_of_args
520  
521          return
522  
# Line 441 | Line 531 | class Cmssw(JobType):
531              jobParams.append("")
532          
533          for job in range(njobs):
534 <            jobParams[job] = str(arglist[job])
534 >            jobParams[job] = arglist[job]
535 >            # print str(arglist[job])
536 >            # print jobParams[job]
537              common.jobDB.setArguments(job, jobParams[job])
538 +            common.logger.debug(5,"Job "+str(job)+" Destination: "+str(self.jobDestination[job]))
539 +            common.jobDB.setDestination(job, self.jobDestination[job])
540  
541          common.jobDB.save()
542          return
543      
544      def getJobTypeArguments(self, nj, sched):
545 <        return common.jobDB.arguments(nj)
545 >        result = ''
546 >        for i in common.jobDB.arguments(nj):
547 >            result=result+str(i)+" "
548 >        return result
549    
550      def numberOfJobs(self):
551          # Fabio
552          return self.total_number_of_jobs
553  
457    def checkBlackList(self, allSites):
458        if len(self.reCEBlackList)==0: return allSites
459        sites = []
460        for site in allSites:
461            common.logger.debug(10,'Site '+site)
462            good=1
463            for re in self.reCEBlackList:
464                if re.search(site):
465                    common.logger.message('CE in black list, skipping site '+site)
466                    good=0
467                pass
468            if good: sites.append(site)
469        if len(sites) == 0:
470            common.logger.debug(3,"No sites found after BlackList")
471        return sites
472
473    def checkWhiteList(self, allSites):
474
475        if len(self.reCEWhiteList)==0: return allSites
476        sites = []
477        for site in allSites:
478            good=0
479            for re in self.reCEWhiteList:
480                if re.search(site):
481                    common.logger.debug(5,'CE in white list, adding site '+site)
482                    good=1
483                if not good: continue
484                sites.append(site)
485        if len(sites) == 0:
486            common.logger.message("No sites found after WhiteList\n")
487        else:
488            common.logger.debug(5,"Selected sites via WhiteList are "+str(sites)+"\n")
489        return sites
490
554      def getTarBall(self, exe):
555          """
556          Return the TarBall with lib and exe
# Line 594 | Line 657 | class Cmssw(JobType):
657          txt += '        dumpStatus $RUNTIME_AREA/$repo\n'
658          txt += '        rm -f $RUNTIME_AREA/$repo \n'
659          txt += '        echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
597        txt += '        echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
660          txt += '        echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
661          txt += '        exit 1\n'
662          txt += '    fi\n'
# Line 617 | Line 679 | class Cmssw(JobType):
679          txt += '   dumpStatus $RUNTIME_AREA/$repo\n'
680          txt += '   rm -f $RUNTIME_AREA/$repo \n'
681          txt += '   echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
620        txt += '   echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
682          txt += '   echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
683          ## OLI_Daniele
684          txt += '    if [ $middleware == OSG ]; then \n'
# Line 631 | Line 692 | class Cmssw(JobType):
692          txt += '            dumpStatus $RUNTIME_AREA/$repo\n'
693          txt += '            rm -f $RUNTIME_AREA/$repo \n'
694          txt += '            echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
634        txt += '            echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
695          txt += '            echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
696          txt += '        fi\n'
697          txt += '    fi \n'
# Line 646 | Line 706 | class Cmssw(JobType):
706          txt += "\n"
707          txt += "## number of arguments (first argument always jobnumber)\n"
708          txt += "\n"
709 <        txt += "narg=$#\n"
710 <        txt += "if [ $narg -lt 2 ]\n"
709 > #        txt += "narg=$#\n"
710 >        txt += "if [ $nargs -lt 2 ]\n"
711          txt += "then\n"
712 <        txt += "    echo 'SET_EXE_ENV 1 ==> ERROR Too few arguments' +$narg+ \n"
712 >        txt += "    echo 'SET_EXE_ENV 1 ==> ERROR Too few arguments' +$nargs+ \n"
713          txt += '    echo "JOB_EXIT_STATUS = 50113"\n'
714          txt += '    echo "JobExitCode=50113" | tee -a $RUNTIME_AREA/$repo\n'
715          txt += '    dumpStatus $RUNTIME_AREA/$repo\n'
716          txt += '    rm -f $RUNTIME_AREA/$repo \n'
717          txt += '    echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
658        txt += '    echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
718          txt += '    echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
719          ## OLI_Daniele
720          txt += '    if [ $middleware == OSG ]; then \n'
# Line 669 | Line 728 | class Cmssw(JobType):
728          txt += '            dumpStatus $RUNTIME_AREA/$repo\n'
729          txt += '            rm -f $RUNTIME_AREA/$repo \n'
730          txt += '            echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
672        txt += '            echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
731          txt += '            echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
732          txt += '        fi\n'
733          txt += '    fi \n'
# Line 682 | Line 740 | class Cmssw(JobType):
740          pset = os.path.basename(job.configFilename())
741          txt += '\n'
742          if (self.datasetPath): # standard job
743 <            txt += 'InputFiles=$2\n'
743 >            #txt += 'InputFiles=$2\n'
744 >            txt += 'InputFiles=${args[1]}\n'
745 >            txt += 'MaxEvents=${args[2]}\n'
746 >            txt += 'SkipEvents=${args[3]}\n'
747              txt += 'echo "Inputfiles:<$InputFiles>"\n'
748 <            txt += 'sed "s#{\'INPUT\'}#$InputFiles#" $RUNTIME_AREA/'+pset+' > pset.cfg\n'
748 >            txt += 'sed "s#{\'INPUT\'}#$InputFiles#" $RUNTIME_AREA/'+pset+' > pset_tmp_1.cfg\n'
749 >            txt += 'echo "MaxEvents:<$MaxEvents>"\n'
750 >            txt += 'sed "s#INPUTMAXEVENTS#$MaxEvents#" $RUNTIME_AREA/ pset_tmp_1.cfg > pset_tmp_2.cfg\n'
751 >            txt += 'echo "SkipEvents:<$SkipEvents>"\n'
752 >            txt += 'sed "s#INPUTSKIPEVENTS#$SkipEvents#" $RUNTIME_AREA/ pset_tmp_2.cfg > pset.cfg\n'
753          else:  # pythia like job
754 <            txt += 'Seed=$2\n'
755 <            txt += 'echo "Seed: <$Seed>"\n'
756 <            txt += 'sed "s#INPUT#$Seed#" $RUNTIME_AREA/'+pset+' > pset.cfg\n'
754 >            if (self.sourceSeed):
755 > #                txt += 'Seed=$2\n'
756 >                txt += 'Seed=${args[1]}\n'
757 >                txt += 'echo "Seed: <$Seed>"\n'
758 >                txt += 'sed "s#\<INPUT\>#$Seed#" $RUNTIME_AREA/'+pset+' > tmp.cfg\n'
759 >                if (self.sourceSeedVtx):
760 > #                    txt += 'VtxSeed=$3\n'
761 >                    txt += 'VtxSeed=${args[2]}\n'
762 >                    txt += 'echo "VtxSeed: <$VtxSeed>"\n'
763 >                    txt += 'sed "s#INPUTVTX#$VtxSeed#" tmp.cfg > pset.cfg\n'
764 >                else:
765 >                    txt += 'mv tmp.cfg pset.cfg\n'
766 >            else:
767 >                txt += '# Copy untouched pset\n'
768 >                txt += 'cp $RUNTIME_AREA/'+pset+' pset.cfg\n'
769 >
770  
771          if len(self.additional_inbox_files) > 0:
772              for file in self.additional_inbox_files:
773 <                txt += 'if [ -e $RUNTIME_AREA/'+file+' ] ; then\n'
774 <                txt += '   cp $RUNTIME_AREA/'+file+' .\n'
775 <                txt += '   chmod +x '+file+'\n'
773 >                relFile = file.split("/")[-1]
774 >                txt += 'if [ -e $RUNTIME_AREA/'+relFile+' ] ; then\n'
775 >                txt += '   cp $RUNTIME_AREA/'+relFile+' .\n'
776 >                txt += '   chmod +x '+relFile+'\n'
777                  txt += 'fi\n'
778              pass
779  
# Line 737 | Line 816 | class Cmssw(JobType):
816              txt += '           dumpStatus $RUNTIME_AREA/$repo\n'
817              txt += '           rm -f $RUNTIME_AREA/$repo \n'
818              txt += '           echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
740            txt += '           echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
819              txt += '           echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
820              txt += '       fi\n'
821              txt += '   fi \n'
# Line 816 | Line 894 | class Cmssw(JobType):
894              txt += '\n'
895              txt += '# check output file\n'
896              txt += 'ls '+fileWithSuffix+'\n'
897 <            txt += 'exe_result=$?\n'
898 <            txt += 'if [ $exe_result -ne 0 ] ; then\n'
899 <            txt += '   echo "ERROR: No output file to manage"\n'
900 <            txt += '   echo "JOB_EXIT_STATUS = $exe_result"\n'
901 <            txt += '   echo "JobExitCode=60302" | tee -a $RUNTIME_AREA/$repo\n'
902 <            txt += '   dumpStatus $RUNTIME_AREA/$repo\n'
903 <            txt += '   rm -f $RUNTIME_AREA/$repo \n'
826 <            txt += '   echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
827 <            txt += '   echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
828 <            txt += '   echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
897 >            txt += 'ls_result=$?\n'
898 >            #txt += 'exe_result=$?\n'
899 >            txt += 'if [ $ls_result -ne 0 ] ; then\n'
900 >            txt += '   echo "ERROR: Problem with output file"\n'
901 >            #txt += '   echo "JOB_EXIT_STATUS = $exe_result"\n'
902 >            #txt += '   echo "JobExitCode=60302" | tee -a $RUNTIME_AREA/$repo\n'
903 >            #txt += '   dumpStatus $RUNTIME_AREA/$repo\n'
904              ### OLI_DANIELE
905              if common.scheduler.boss_scheduler_name == 'condor_g':
906                  txt += '    if [ $middleware == OSG ]; then \n'
# Line 839 | Line 914 | class Cmssw(JobType):
914          txt += 'cd $RUNTIME_AREA\n'
915          file_list=file_list[:-1]
916          txt += 'file_list="'+file_list+'"\n'
917 +        txt += 'cd $RUNTIME_AREA\n'
918          ### OLI_DANIELE
919          txt += 'if [ $middleware == OSG ]; then\n'  
920          txt += '    cd $RUNTIME_AREA\n'
# Line 851 | Line 927 | class Cmssw(JobType):
927          txt += '        dumpStatus $RUNTIME_AREA/$repo\n'
928          txt += '        rm -f $RUNTIME_AREA/$repo \n'
929          txt += '        echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
854        txt += '        echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
930          txt += '        echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
931          txt += '    fi\n'
932          txt += 'fi\n'
# Line 870 | Line 945 | class Cmssw(JobType):
945          # add "_txt"
946          if len(p)>1:
947            ext = p[len(p)-1]
873          #result = name + '_' + str(txt) + "." + ext
948            result = name + '_' + txt + "." + ext
949          else:
876          #result = name + '_' + str(txt)
950            result = name + '_' + txt
951          
952          return result
# Line 887 | Line 960 | class Cmssw(JobType):
960              req='Member("VO-cms-' + \
961                   common.analisys_common_info['sw_version'] + \
962                   '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
963 <        if common.analisys_common_info['sites']:
964 <            if len(common.analisys_common_info['sites'])>0:
965 <                req = req + ' && ('
893 <                for i in range(len(common.analisys_common_info['sites'])):
894 <                    req = req + 'other.GlueCEInfoHostName == "' \
895 <                         + common.analisys_common_info['sites'][i] + '"'
896 <                    if ( i < (int(len(common.analisys_common_info['sites']) - 1)) ):
897 <                        req = req + ' || '
898 <            req = req + ')'
899 <        #print "req = ", req
963 >
964 >        req = req + ' && (other.GlueHostNetworkAdapterOutboundIP)'
965 >
966          return req
967  
968      def configFilename(self):
# Line 914 | Line 980 | class Cmssw(JobType):
980          txt += '   if [ -f $GRID3_APP_DIR/cmssoft/cmsset_default.sh ] ;then\n'
981          txt += '      # Use $GRID3_APP_DIR/cmssoft/cmsset_default.sh to setup cms software\n'
982          txt += '       source $GRID3_APP_DIR/cmssoft/cmsset_default.sh '+self.version+'\n'
983 <        txt += '   elif [ -f $OSG_APP/cmssoft/cmsset_default.sh ] ;then\n'
984 <        txt += '      # Use $OSG_APP/cmssoft/cmsset_default.sh to setup cms software\n'
985 <        txt += '       source $OSG_APP/cmssoft/cmsset_default.sh '+self.version+'\n'
983 >        txt += '   elif [ -f $OSG_APP/cmssoft/cms/cmsset_default.sh ] ;then\n'
984 >        txt += '      # Use $OSG_APP/cmssoft/cms/cmsset_default.sh to setup cms software\n'
985 >        txt += '       source $OSG_APP/cmssoft/cms/cmsset_default.sh '+self.version+'\n'
986          txt += '   else\n'
987 <        txt += '       echo "SET_CMS_ENV 10020 ==> ERROR $GRID3_APP_DIR/cmssoft/cmsset_default.sh and $OSG_APP/cmssoft/cmsset_default.sh file not found"\n'
987 >        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'
988          txt += '       echo "JOB_EXIT_STATUS = 10020"\n'
989          txt += '       echo "JobExitCode=10020" | tee -a $RUNTIME_AREA/$repo\n'
990          txt += '       dumpStatus $RUNTIME_AREA/$repo\n'
991          txt += '       rm -f $RUNTIME_AREA/$repo \n'
992          txt += '       echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
927        txt += '       echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
993          txt += '       echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
994          txt += '       exit 1\n'
995          txt += '\n'
# Line 932 | Line 997 | class Cmssw(JobType):
997          txt += '       cd $RUNTIME_AREA\n'
998          txt += '       /bin/rm -rf $WORKING_DIR\n'
999          txt += '       if [ -d $WORKING_DIR ] ;then\n'
1000 <        txt += '            echo "SET_CMS_ENV 10017 ==> OSG $WORKING_DIR could not be deleted on WN `hostname` after $GRID3_APP_DIR/cmssoft/cmsset_default.sh and $OSG_APP/cmssoft/cmsset_default.sh file not found"\n'
1000 >        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'
1001          txt += '            echo "JOB_EXIT_STATUS = 10017"\n'
1002          txt += '            echo "JobExitCode=10017" | tee -a $RUNTIME_AREA/$repo\n'
1003          txt += '            dumpStatus $RUNTIME_AREA/$repo\n'
1004          txt += '            rm -f $RUNTIME_AREA/$repo \n'
1005          txt += '            echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
941        txt += '            echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
1006          txt += '            echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1007          txt += '       fi\n'
1008          txt += '\n'
# Line 965 | Line 1029 | class Cmssw(JobType):
1029          txt += '       dumpStatus $RUNTIME_AREA/$repo\n'
1030          txt += '       rm -f $RUNTIME_AREA/$repo \n'
1031          txt += '       echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
968        txt += '       echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
1032          txt += '       echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1033          txt += '       exit 1\n'
1034          txt += '   else\n'
# Line 977 | Line 1040 | class Cmssw(JobType):
1040          txt += '           dumpStatus $RUNTIME_AREA/$repo\n'
1041          txt += '           rm -f $RUNTIME_AREA/$repo \n'
1042          txt += '           echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
980        txt += '           echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
1043          txt += '           echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1044          txt += '           exit 1\n'
1045          txt += '       fi\n'
# Line 991 | Line 1053 | class Cmssw(JobType):
1053          txt += '           dumpStatus $RUNTIME_AREA/$repo\n'
1054          txt += '           rm -f $RUNTIME_AREA/$repo \n'
1055          txt += '           echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
994        txt += '           echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
1056          txt += '           echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1057          txt += '           exit 1\n'
1058          txt += '       fi\n'
# Line 1011 | Line 1072 | class Cmssw(JobType):
1072          txt += '       dumpStatus $RUNTIME_AREA/$repo\n'
1073          txt += '       rm -f $RUNTIME_AREA/$repo \n'
1074          txt += '       echo "MonitorJobID=`echo $MonitorJobID`" | tee -a $RUNTIME_AREA/$repo \n'
1014        txt += '       echo "SyncGridJobId=`echo $SyncGridJobId`" | tee -a $RUNTIME_AREA/$repo \n'
1075          txt += '       echo "MonitorID=`echo $MonitorID`" | tee -a $RUNTIME_AREA/$repo\n'
1076          txt += '       exit 1\n'
1077          txt += '   fi\n'
# Line 1030 | Line 1090 | class Cmssw(JobType):
1090          
1091      def getTaskid(self):
1092          return self._taskId
1093 +
1094 + #######################################################################
1095 +    def uniquelist(self, old):
1096 +        """
1097 +        remove duplicates from a list
1098 +        """
1099 +        nd={}
1100 +        for e in old:
1101 +            nd[e]=0
1102 +        return nd.keys()

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines