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.178 by spiga, Sun Apr 20 09:34:40 2008 UTC vs.
Revision 1.226 by ewv, Thu Jul 3 19:30:07 2008 UTC

# Line 10 | Line 10 | from LFNBaseName import *
10   import os, string, glob
11  
12   class Cmssw(JobType):
13 <    def __init__(self, cfg_params, ncjobs):
13 >    def __init__(self, cfg_params, ncjobs,skip_blocks, isNew):
14          JobType.__init__(self, 'CMSSW')
15          common.logger.debug(3,'CMSSW::__init__')
16 +        self.skip_blocks = skip_blocks
17  
18          self.argsList = []
19  
# Line 34 | Line 35 | class Cmssw(JobType):
35          self.executable = ''
36          self.executable_arch = self.scram.getArch()
37          self.tgz_name = 'default.tgz'
37        self.additional_tgz_name = 'additional.tgz'
38          self.scriptName = 'CMSSW.sh'
39 <        self.pset = ''      #scrip use case Da
40 <        self.datasetPath = '' #scrip use case Da
39 >        self.pset = ''
40 >        self.datasetPath = ''
41  
42          # set FJR file name
43          self.fjrFileName = 'crab_fjr.xml'
44  
45          self.version = self.scram.getSWVersion()
46 <
47 <        #
48 <        # Try to block creation in case of arch/version mismatch
49 <        #
50 <
51 < #        a = string.split(self.version, "_")
52 < #
53 < #        if int(a[1]) == 1 and (int(a[2]) < 5 and self.executable_arch.find('slc4') == 0):
54 < #            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)
55 < #            common.logger.message(msg)
56 < #        if int(a[1]) == 1 and (int(a[2]) >= 5 and self.executable_arch.find('slc3') == 0):
57 < #            msg = "Error: CMS does not support %s with %s architecture"%(self.version, self.executable_arch)
58 < #            raise CrabException(msg)
59 < #
60 <
46 >        version_array = self.version.split('_')
47 >        self.CMSSW_major = 0
48 >        self.CMSSW_minor = 0
49 >        self.CMSSW_patch = 0
50 >        try:
51 >            self.CMSSW_major = int(version_array[1])
52 >            self.CMSSW_minor = int(version_array[2])
53 >            self.CMSSW_patch = int(version_array[3])
54 >        except:
55 >            msg = "Cannot parse CMSSW version string: " + self.version + " for major and minor release number!"
56 >            raise CrabException(msg)
57  
58          ### collect Data cards
59  
60          if not cfg_params.has_key('CMSSW.datasetpath'):
61              msg = "Error: datasetpath not defined "
62              raise CrabException(msg)
63 +
64 +        ### Temporary: added to remove input file control in the case of PU
65 +        self.dataset_pu = cfg_params.get('CMSSW.dataset_pu', None)
66 +
67          tmp =  cfg_params['CMSSW.datasetpath']
68          log.debug(6, "CMSSW::CMSSW(): datasetPath = "+tmp)
69          if string.lower(tmp)=='none':
# Line 74 | Line 74 | class Cmssw(JobType):
74              self.selectNoInput = 0
75  
76          self.dataTiers = []
77 <
77 >        self.debugWrap = ''
78 >        self.debug_wrapper = cfg_params.get('USER.debug_wrapper',False)
79 >        if self.debug_wrapper: self.debugWrap='--debug'
80          ## now the application
81          self.executable = cfg_params.get('CMSSW.executable','cmsRun')
82          log.debug(6, "CMSSW::CMSSW(): executable = "+self.executable)
# Line 97 | Line 99 | class Cmssw(JobType):
99          self.output_file_sandbox.append(self.fjrFileName)
100  
101          # other output files to be returned via sandbox or copied to SE
102 +        outfileflag = False
103          self.output_file = []
104          tmp = cfg_params.get('CMSSW.output_file',None)
105          if tmp :
106 <            tmpOutFiles = string.split(tmp,',')
107 <            log.debug(7, 'cmssw::cmssw(): output files '+str(tmpOutFiles))
108 <            for tmp in tmpOutFiles:
109 <                tmp=string.strip(tmp)
107 <                self.output_file.append(tmp)
108 <                pass
109 <        else:
110 <            log.message("No output file defined: only stdout/err and the CRAB Framework Job Report will be available\n")
111 <        pass
106 >            self.output_file = [x.strip() for x in tmp.split(',')]
107 >            outfileflag = True #output found
108 >        #else:
109 >        #    log.message("No output file defined: only stdout/err and the CRAB Framework Job Report will be available\n")
110  
111          # script_exe file as additional file in inputSandbox
112          self.scriptExe = cfg_params.get('USER.script_exe',None)
# Line 118 | Line 116 | class Cmssw(JobType):
116                  raise CrabException(msg)
117              self.additional_inbox_files.append(string.strip(self.scriptExe))
118  
121        #CarlosDaniele
119          if self.datasetPath == None and self.pset == None and self.scriptExe == '' :
120              msg ="Error. script_exe  not defined"
121              raise CrabException(msg)
122  
123 +        # use parent files...
124 +        self.useParent = self.cfg_params.get('CMSSW.use_parent',False)
125 +
126          ## additional input files
127          if cfg_params.has_key('USER.additional_input_files'):
128              tmpAddFiles = string.split(cfg_params['USER.additional_input_files'],',')
# Line 141 | Line 141 | class Cmssw(JobType):
141                      if not os.path.exists(file):
142                          raise CrabException("Additional input file not found: "+file)
143                      pass
144                    # fname = string.split(file, '/')[-1]
145                    # storedFile = common.work_space.pathForTgz()+'share/'+fname
146                    # shutil.copyfile(file, storedFile)
144                      self.additional_inbox_files.append(string.strip(file))
145                  pass
146              pass
# Line 169 | Line 166 | class Cmssw(JobType):
166          if cfg_params.has_key('CMSSW.total_number_of_events'):
167              self.total_number_of_events = int(cfg_params['CMSSW.total_number_of_events'])
168              self.selectTotalNumberEvents = 1
169 +            if self.selectNumberOfJobs  == 1:
170 +                if (self.total_number_of_events != -1) and int(self.total_number_of_events) < int(self.theNumberOfJobs):
171 +                    msg = 'Must specify at least one event per job. total_number_of_events > number_of_jobs '
172 +                    raise CrabException(msg)
173          else:
174              self.total_number_of_events = 0
175              self.selectTotalNumberEvents = 0
176  
177 <        if self.pset != None: #CarlosDaniele
177 >        if self.pset != None:
178               if ( (self.selectTotalNumberEvents + self.selectEventsPerJob + self.selectNumberOfJobs) != 2 ):
179                   msg = 'Must define exactly two of total_number_of_events, events_per_job, or number_of_jobs.'
180                   raise CrabException(msg)
# Line 203 | Line 204 | class Cmssw(JobType):
204          if self.sourceSeed:
205              print "pythia_seed is a deprecated parameter. Use preserve_seeds or increment_seeds in the future.\n","Added to increment_seeds."
206              self.incrementSeeds.append('sourceSeed')
207 +            self.incrementSeeds.append('theSource')
208  
209          self.sourceSeedVtx = cfg_params.get('CMSSW.vtx_seed',None)
210          if self.sourceSeedVtx:
# Line 221 | Line 223 | class Cmssw(JobType):
223  
224          self.firstRun = cfg_params.get('CMSSW.first_run',None)
225  
224        if self.pset != None: #CarlosDaniele
225            import PsetManipulator as pp
226            PsetEdit = pp.PsetManipulator(self.pset) #Daniele Pset
226  
227          # Copy/return
229
228          self.copy_data = int(cfg_params.get('USER.copy_data',0))
229          self.return_data = int(cfg_params.get('USER.return_data',0))
230  
# Line 242 | Line 240 | class Cmssw(JobType):
240              blockSites = self.DataDiscoveryAndLocation(cfg_params)
241          #DBSDLS-end
242  
245        self.tgzNameWithPath = self.getTarBall(self.executable)
246
243          ## Select Splitting
244          if self.selectNoInput:
245 <            if self.pset == None: #CarlosDaniele
245 >            if self.pset == None:
246                  self.jobSplittingForScript()
247              else:
248                  self.jobSplittingNoInput()
249          else:
250              self.jobSplittingByBlocks(blockSites)
251  
252 <        # modify Pset
253 <        if self.pset != None: #CarlosDaniele
254 <            try:
255 <                # Add FrameworkJobReport to parameter-set, set max events.
256 <                # Reset later for data jobs by writeCFG which does all modifications
257 <                PsetEdit.addCrabFJR(self.fjrFileName)
258 <                PsetEdit.maxEvent(self.eventsPerJob)
259 <                PsetEdit.psetWriter(self.configFilename())
260 <            except:
261 <                msg='Error while manipuliating ParameterSet: exiting...'
262 <                raise CrabException(msg)
252 >        # modify Pset only the first time
253 >        if isNew:
254 >            if self.pset != None:
255 >                import PsetManipulator as pp
256 >                PsetEdit = pp.PsetManipulator(self.pset)
257 >                try:
258 >                    # Add FrameworkJobReport to parameter-set, set max events.
259 >                    # Reset later for data jobs by writeCFG which does all modifications
260 >                    PsetEdit.addCrabFJR(self.fjrFileName) # FUTURE: Job report addition not needed by CMSSW>1.5
261 >                    PsetEdit.maxEvent(self.eventsPerJob)
262 >                    PsetEdit.psetWriter(self.configFilename())
263 >                    ## If present, add TFileService to output files
264 >                    if not int(cfg_params.get('CMSSW.skip_TFileService_output',0)):
265 >                        tfsOutput = PsetEdit.getTFileService()
266 >                        if tfsOutput:
267 >                            if tfsOutput in self.output_file:
268 >                                common.logger.debug(5,"Output from TFileService "+tfsOutput+" already in output files")
269 >                            else:
270 >                                outfileflag = True #output found
271 >                                self.output_file.append(tfsOutput)
272 >                                common.logger.message("Adding "+tfsOutput+" to output files (from TFileService)")
273 >                            pass
274 >                        pass
275 >                    ## If present and requested, add PoolOutputModule to output files
276 >                    if int(cfg_params.get('CMSSW.get_edm_output',0)):
277 >                        edmOutput = PsetEdit.getPoolOutputModule()
278 >                        if edmOutput:
279 >                            if edmOutput in self.output_file:
280 >                                common.logger.debug(5,"Output from PoolOutputModule "+edmOutput+" already in output files")
281 >                            else:
282 >                                self.output_file.append(edmOutput)
283 >                                common.logger.message("Adding "+edmOutput+" to output files (from PoolOutputModule)")
284 >                            pass
285 >                        pass
286 >                except CrabException:
287 >                    msg='Error while manipulating ParameterSet: exiting...'
288 >                    raise CrabException(msg)
289 >            ## Prepare inputSandbox TarBall (only the first time)
290 >            self.tgzNameWithPath = self.getTarBall(self.executable)
291  
292      def DataDiscoveryAndLocation(self, cfg_params):
293  
# Line 276 | Line 300 | class Cmssw(JobType):
300          ## Contact the DBS
301          common.logger.message("Contacting Data Discovery Services ...")
302          try:
303 <            self.pubdata=DataDiscovery.DataDiscovery(datasetPath, cfg_params)
303 >            self.pubdata=DataDiscovery.DataDiscovery(datasetPath, cfg_params,self.skip_blocks)
304              self.pubdata.fetchDBSInfo()
305  
306          except DataDiscovery.NotExistingDatasetError, ex :
# Line 292 | Line 316 | class Cmssw(JobType):
316          self.filesbyblock=self.pubdata.getFiles()
317          self.eventsbyblock=self.pubdata.getEventsPerBlock()
318          self.eventsbyfile=self.pubdata.getEventsPerFile()
319 +        self.parentFiles=self.pubdata.getParent()
320  
321          ## get max number of events
322 <        self.maxEvents=self.pubdata.getMaxEvents() ##  self.maxEvents used in Creator.py
322 >        self.maxEvents=self.pubdata.getMaxEvents()
323  
324          ## Contact the DLS and build a list of sites hosting the fileblocks
325          try:
# Line 318 | Line 343 | class Cmssw(JobType):
343  
344          return sites
345  
321  # to Be Removed  DS -- BL
322  #  def setArgsList(self, argsList):
323  #      self.argsList = argsList
324
346      def jobSplittingByBlocks(self, blockSites):
347          """
348          Perform job splitting. Jobs run over an integer number of files
# Line 412 | Line 433 | class Cmssw(JobType):
433  
434                  # ---- Iterate over the files in the block until we've met the requested ---- #
435                  # ---- total # of events or we've gone over all the files in this block  ---- #
436 +                pString=''
437                  while ( (eventsRemaining > 0) and (fileCount < numFilesInBlock) and (jobCount < totalNumberOfJobs) ):
438                      file = files[fileCount]
439 +                    if self.useParent:
440 +                        parent = self.parentFiles[file]
441 +                        for f in parent :
442 +                            pString += '\\\"' + f + '\\\"\,'
443 +                        common.logger.debug(6, "File "+str(file)+" has the following parents: "+str(parent))
444 +                        common.logger.write("File "+str(file)+" has the following parents: "+str(parent))
445                      if newFile :
446                          try:
447                              numEventsInFile = self.eventsbyfile[file]
# Line 434 | Line 462 | class Cmssw(JobType):
462                              # end job using last file, use remaining events in block
463                              # close job and touch new file
464                              fullString = parString[:-2]
465 <                            list_of_lists.append([fullString,str(-1),str(jobSkipEventCount)])
465 >                            if self.useParent:
466 >                                fullParentString = pString[:-2]
467 >                                list_of_lists.append([fullString,fullParentString,str(-1),str(jobSkipEventCount)])
468 >                            else:
469 >                                list_of_lists.append([fullString,str(-1),str(jobSkipEventCount)])
470                              common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(filesEventCount - jobSkipEventCount)+" events (last file in block).")
471                              self.jobDestination.append(blockSites[block])
472                              common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
# Line 446 | Line 478 | class Cmssw(JobType):
478                              eventsRemaining = eventsRemaining - filesEventCount + jobSkipEventCount
479                              jobSkipEventCount = 0
480                              # reset file
481 +                            pString = ""
482                              parString = ""
483                              filesEventCount = 0
484                              newFile = 1
# Line 458 | Line 491 | class Cmssw(JobType):
491                      elif ( filesEventCount - jobSkipEventCount == eventsPerJobRequested ) :
492                          # close job and touch new file
493                          fullString = parString[:-2]
494 <                        list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
494 >                        if self.useParent:
495 >                            fullParentString = pString[:-2]
496 >                            list_of_lists.append([fullString,fullParentString,str(eventsPerJobRequested),str(jobSkipEventCount)])
497 >                        else:
498 >                            list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
499                          common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(eventsPerJobRequested)+" events.")
500                          self.jobDestination.append(blockSites[block])
501                          common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
# Line 469 | Line 506 | class Cmssw(JobType):
506                          eventsRemaining = eventsRemaining - eventsPerJobRequested
507                          jobSkipEventCount = 0
508                          # reset file
509 +                        pString = ""
510                          parString = ""
511                          filesEventCount = 0
512                          newFile = 1
# Line 478 | Line 516 | class Cmssw(JobType):
516                      else :
517                          # close job but don't touch new file
518                          fullString = parString[:-2]
519 <                        list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
519 >                        if self.useParent:
520 >                            fullParentString = pString[:-2]
521 >                            list_of_lists.append([fullString,fullParentString,str(eventsPerJobRequested),str(jobSkipEventCount)])
522 >                        else:
523 >                            list_of_lists.append([fullString,str(eventsPerJobRequested),str(jobSkipEventCount)])
524                          common.logger.debug(3,"Job "+str(jobCount+1)+" can run over "+str(eventsPerJobRequested)+" events.")
525                          self.jobDestination.append(blockSites[block])
526                          common.logger.debug(5,"Job "+str(jobCount+1)+" Destination: "+str(self.jobDestination[jobCount]))
# Line 492 | Line 534 | class Cmssw(JobType):
534                          jobSkipEventCount = eventsPerJobRequested - (filesEventCount - jobSkipEventCount - self.eventsbyfile[file])
535                          # remove all but the last file
536                          filesEventCount = self.eventsbyfile[file]
537 +                        if self.useParent:
538 +                            for f in parent : pString += '\\\"' + f + '\\\"\,'
539                          parString = '\\\"' + file + '\\\"\,'
540                      pass # END if
541                  pass # END while (iterate over files in the block)
# Line 600 | Line 644 | class Cmssw(JobType):
644          return
645  
646  
647 <    def jobSplittingForScript(self):#CarlosDaniele
647 >    def jobSplittingForScript(self):
648          """
649          Perform job splitting based on number of job
650          """
# Line 616 | Line 660 | class Cmssw(JobType):
660          # argument is seed number.$i
661          self.list_of_args = []
662          for i in range(self.total_number_of_jobs):
619            ## Since there is no input, any site is good
620           # self.jobDestination.append(["Any"])
663              self.jobDestination.append([""])
622            ## no random seed
664              self.list_of_args.append([str(i)])
665          return
666  
667 <    def split(self, jobParams):
667 >    def split(self, jobParams,firstJobID):
668  
628        #### Fabio
669          njobs = self.total_number_of_jobs
670          arglist = self.list_of_args
671          # create the empty structure
# Line 634 | Line 674 | class Cmssw(JobType):
674  
675          listID=[]
676          listField=[]
677 <        for job in range(njobs):
678 <            jobParams[job] = arglist[job]
677 >        for id in range(njobs):
678 >            job = id + int(firstJobID)
679 >            jobParams[id] = arglist[id]
680              listID.append(job+1)
681              job_ToSave ={}
682              concString = ' '
683              argu=''
684 <            if len(jobParams[job]):
685 <                argu +=   concString.join(jobParams[job] )
686 <            job_ToSave['arguments']= str(job+1)+' '+argu## new BL--DS
687 <            job_ToSave['dlsDestination']= self.jobDestination[job]## new BL--DS
647 <            #common._db.updateJob_(job,job_ToSave)## new BL--DS
684 >            if len(jobParams[id]):
685 >                argu +=   concString.join(jobParams[id] )
686 >            job_ToSave['arguments']= str(job+1)+' '+argu
687 >            job_ToSave['dlsDestination']= self.jobDestination[id]
688              listField.append(job_ToSave)
689              msg="Job "+str(job)+" Arguments:   "+str(job+1)+" "+argu+"\n"  \
690 <            +"                     Destination: "+str(self.jobDestination[job])
690 >            +"                     Destination: "+str(self.jobDestination[id])
691              common.logger.debug(5,msg)
692 <            #common.logger.debug(5,"Job "+str(job)+" Destination: "+str(self.jobDestination[job]))
693 <        common._db.updateJob_(listID,listField)## new BL--DS
654 <        ## Pay Attention Here....DS--BL
655 <        self.argsList = (len(jobParams[1])+1)
692 >        common._db.updateJob_(listID,listField)
693 >        self.argsList = (len(jobParams[0])+1)
694  
695          return
696  
697      def numberOfJobs(self):
660        # Fabio
698          return self.total_number_of_jobs
699  
700      def getTarBall(self, exe):
701          """
702          Return the TarBall with lib and exe
703          """
667
668        # if it exist, just return it
669        #
670        # Marco. Let's start to use relative path for Boss XML files
671        #
704          self.tgzNameWithPath = common.work_space.pathForTgz()+'share/'+self.tgz_name
705          if os.path.exists(self.tgzNameWithPath):
706              return self.tgzNameWithPath
# Line 682 | Line 714 | class Cmssw(JobType):
714  
715          # First of all declare the user Scram area
716          swArea = self.scram.getSWArea_()
685        #print "swArea = ", swArea
686        # swVersion = self.scram.getSWVersion()
687        # print "swVersion = ", swVersion
717          swReleaseTop = self.scram.getReleaseTop_()
689        #print "swReleaseTop = ", swReleaseTop
718  
719          ## check if working area is release top
720          if swReleaseTop == '' or swArea == swReleaseTop:
# Line 732 | Line 760 | class Cmssw(JobType):
760                  tar.add(module,moduleDir)
761  
762              ## Now check if any data dir(s) is present
763 <            swAreaLen=len(swArea)
764 <            for root, dirs, files in os.walk(swArea):
765 <                if "data" in dirs:
766 <                    common.logger.debug(5,"data "+root+"/data"+" to be tarred")
767 <                    tar.add(root+"/data",root[swAreaLen:]+"/data")
763 >            self.dataExist = False
764 >            todo_list = [(i, i) for i in  os.listdir(swArea+"/src")]
765 >            while len(todo_list):
766 >                entry, name = todo_list.pop()
767 >                if name.startswith('crab_0_') or  name.startswith('.') or name == 'CVS':
768 >                    continue
769 >                if os.path.isdir(swArea+"/src/"+entry):
770 >                    entryPath = entry + '/'
771 >                    todo_list += [(entryPath + i, i) for i in  os.listdir(swArea+"/src/"+entry)]
772 >                    if name == 'data':
773 >                        self.dataExist=True
774 >                        common.logger.debug(5,"data "+entry+" to be tarred")
775 >                        tar.add(swArea+"/src/"+entry,"src/"+entry)
776 >                    pass
777 >                pass
778 >
779 >            ### CMSSW ParameterSet
780 >            if not self.pset is None:
781 >                cfg_file = common.work_space.jobDir()+self.configFilename()
782 >                tar.add(cfg_file,self.configFilename())
783 >                common.logger.debug(5,"File added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
784  
785  
786              ## Add ProdCommon dir to tar
787 <            prodcommonDir = 'ProdCommon'
788 <            prodcommonPath = os.environ['CRABDIR'] + '/' + 'ProdCommon'
789 <            if os.path.isdir(prodcommonPath):
790 <                tar.add(prodcommonPath,prodcommonDir)
787 >            prodcommonDir = './'
788 >            prodcommonPath = os.environ['CRABDIR'] + '/' + 'external/'
789 >            neededStuff = ['ProdCommon/__init__.py','ProdCommon/FwkJobRep', 'ProdCommon/CMSConfigTools','ProdCommon/Core','ProdCommon/MCPayloads', 'IMProv']
790 >            for file in neededStuff:
791 >                tar.add(prodcommonPath+file,prodcommonDir+file)
792 >            common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
793 >
794 >            ##### ML stuff
795 >            ML_file_list=['report.py', 'DashboardAPI.py', 'Logger.py', 'ProcInfo.py', 'apmon.py']
796 >            path=os.environ['CRABDIR'] + '/python/'
797 >            for file in ML_file_list:
798 >                tar.add(path+file,file)
799 >            common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
800 >
801 >            ##### Utils
802 >            Utils_file_list=['parseCrabFjr.py','writeCfg.py', 'fillCrabFjr.py']
803 >            for file in Utils_file_list:
804 >                tar.add(path+file,file)
805 >            common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
806  
807 +            ##### AdditionalFiles
808 +            for file in self.additional_inbox_files:
809 +                tar.add(file,string.split(file,'/')[-1])
810              common.logger.debug(5,"Files added to "+self.tgzNameWithPath+" : "+str(tar.getnames()))
811 +
812              tar.close()
813 <        except :
814 <            raise CrabException('Could not create tar-ball')
813 >        except IOError:
814 >            raise CrabException('Could not create tar-ball '+self.tgzNameWithPath)
815 >        except tarfile.TarError:
816 >            raise CrabException('Could not create tar-ball '+self.tgzNameWithPath)
817  
818          ## check for tarball size
819          tarballinfo = os.stat(self.tgzNameWithPath)
# Line 756 | Line 821 | class Cmssw(JobType):
821              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.')
822  
823          ## create tar-ball with ML stuff
759        self.MLtgzfile =  common.work_space.pathForTgz()+'share/MLfiles.tgz'
760        try:
761            tar = tarfile.open(self.MLtgzfile, "w:gz")
762            path=os.environ['CRABDIR'] + '/python/'
763            for file in ['report.py', 'DashboardAPI.py', 'Logger.py', 'ProcInfo.py', 'apmon.py', 'parseCrabFjr.py','writeCfg.py', 'JobReportErrorCode.py']:
764                tar.add(path+file,file)
765            common.logger.debug(5,"Files added to "+self.MLtgzfile+" : "+str(tar.getnames()))
766            tar.close()
767        except :
768            raise CrabException('Could not create ML files tar-ball')
769
770        return
771
772    def additionalInputFileTgz(self):
773        """
774        Put all additional files into a tar ball and return its name
775        """
776        import tarfile
777        tarName=  common.work_space.pathForTgz()+'share/'+self.additional_tgz_name
778        tar = tarfile.open(tarName, "w:gz")
779        for file in self.additional_inbox_files:
780            tar.add(file,string.split(file,'/')[-1])
781        common.logger.debug(5,"Files added to "+self.additional_tgz_name+" : "+str(tar.getnames()))
782        tar.close()
783        return tarName
824  
825      def wsSetupEnvironment(self, nj=0):
826          """
827          Returns part of a job script which prepares
828          the execution environment for the job 'nj'.
829          """
830 +        if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
831 +            psetName = 'pset.py'
832 +        else:
833 +            psetName = 'pset.cfg'
834          # Prepare JobType-independent part
835          txt = '\n#Written by cms_cmssw::wsSetupEnvironment\n'
836          txt += 'echo ">>> setup environment"\n'
# Line 805 | Line 849 | class Cmssw(JobType):
849          txt += '    cd $WORKING_DIR\n'
850          txt += '    echo ">>> current directory (WORKING_DIR): $WORKING_DIR"\n'
851          txt += self.wsSetupCMSOSGEnvironment_()
808        #txt += '    echo "### Set SCRAM ARCH to ' + self.executable_arch + ' ###"\n'
809        #txt += '    export SCRAM_ARCH='+self.executable_arch+'\n'
852          txt += 'fi\n'
853  
854          # Prepare JobType-specific part
# Line 822 | Line 864 | class Cmssw(JobType):
864          txt += '    func_exit\n'
865          txt += 'fi \n'
866          txt += 'cd '+self.version+'\n'
825        ########## FEDE FOR DBS2 ######################
867          txt += 'SOFTWARE_DIR=`pwd`\n'
868          txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
828        ###############################################
829        ### needed grep for bug in scramv1 ###
869          txt += 'eval `'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME`\n'
870 +        txt += 'if [ $? != 0 ] ; then\n'
871 +        txt += '    echo "ERROR ==> Problem with the command: "\n'
872 +        txt += '    echo "eval \`'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME \` at `hostname`"\n'
873 +        txt += '    job_exit_code=10034\n'
874 +        txt += '    func_exit\n'
875 +        txt += 'fi \n'
876          # Handle the arguments:
877          txt += "\n"
878          txt += "## number of arguments (first argument always jobnumber)\n"
# Line 842 | Line 887 | class Cmssw(JobType):
887  
888          # Prepare job-specific part
889          job = common.job_list[nj]
845        ### FEDE FOR DBS OUTPUT PUBLICATION
890          if (self.datasetPath):
891              txt += '\n'
892              txt += 'DatasetPath='+self.datasetPath+'\n'
# Line 864 | Line 908 | class Cmssw(JobType):
908              txt += 'cp  $RUNTIME_AREA/'+pset+' .\n'
909              if (self.datasetPath): # standard job
910                  txt += 'InputFiles=${args[1]}; export InputFiles\n'
911 <                txt += 'MaxEvents=${args[2]}; export MaxEvents\n'
912 <                txt += 'SkipEvents=${args[3]}; export SkipEvents\n'
911 >                if (self.useParent):
912 >                    txt += 'ParentFiles=${args[2]}; export ParentFiles\n'
913 >                    txt += 'MaxEvents=${args[3]}; export MaxEvents\n'
914 >                    txt += 'SkipEvents=${args[4]}; export SkipEvents\n'
915 >                else:
916 >                    txt += 'MaxEvents=${args[2]}; export MaxEvents\n'
917 >                    txt += 'SkipEvents=${args[3]}; export SkipEvents\n'
918                  txt += 'echo "Inputfiles:<$InputFiles>"\n'
919 +                if (self.useParent): txt += 'echo "ParentFiles:<$ParentFiles>"\n'
920                  txt += 'echo "MaxEvents:<$MaxEvents>"\n'
921                  txt += 'echo "SkipEvents:<$SkipEvents>"\n'
922              else:  # pythia like job
# Line 878 | Line 928 | class Cmssw(JobType):
928                      txt += 'FirstRun=${args[1]}; export FirstRun\n'
929                      txt += 'echo "FirstRun: <$FirstRun>"\n'
930  
931 <            txt += 'mv -f '+pset+' pset.cfg\n'
931 >            txt += 'mv -f ' + pset + ' ' + psetName + '\n'
932  
883        if len(self.additional_inbox_files) > 0:
884            txt += 'if [ -e $RUNTIME_AREA/'+self.additional_tgz_name+' ] ; then\n'
885            txt += '  tar xzvf $RUNTIME_AREA/'+self.additional_tgz_name+'\n'
886            txt += 'fi\n'
887            pass
933  
934          if self.pset != None:
935 +            # FUTURE: Can simply for 2_1_x and higher
936              txt += '\n'
937 <            txt += 'echo "***** cat pset.cfg *********"\n'
938 <            txt += 'cat pset.cfg\n'
939 <            txt += 'echo "****** end pset.cfg ********"\n'
940 <            txt += '\n'
941 <            txt += 'PSETHASH=`EdmConfigHash < pset.cfg` \n'
937 >            if self.debug_wrapper==True:
938 >                txt += 'echo "***** cat ' + psetName + ' *********"\n'
939 >                txt += 'cat ' + psetName + '\n'
940 >                txt += 'echo "****** end ' + psetName + ' ********"\n'
941 >                txt += '\n'
942 >            if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
943 >                txt += 'PSETHASH=`edmConfigHash ' + psetName + '` \n'
944 >            else:
945 >                txt += 'PSETHASH=`edmConfigHash < ' + psetName + '` \n'
946              txt += 'echo "PSETHASH = $PSETHASH" \n'
947              txt += '\n'
948          return txt
# Line 908 | Line 958 | class Cmssw(JobType):
958          if os.path.isfile(self.tgzNameWithPath):
959              txt += 'echo ">>> tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+' :" \n'
960              txt += 'tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'\n'
961 +            if  self.debug_wrapper:
962 +                txt += 'ls -Al \n'
963              txt += 'untar_status=$? \n'
964              txt += 'if [ $untar_status -ne 0 ]; then \n'
965              txt += '   echo "ERROR ==> Untarring .tgz file failed"\n'
# Line 917 | Line 969 | class Cmssw(JobType):
969              txt += '   echo "Successful untar" \n'
970              txt += 'fi \n'
971              txt += '\n'
972 <            txt += 'echo ">>> Include ProdCommon in PYTHONPATH:"\n'
972 >            txt += 'echo ">>> Include $RUNTIME_AREA in PYTHONPATH:"\n'
973              txt += 'if [ -z "$PYTHONPATH" ]; then\n'
974 <            txt += '   export PYTHONPATH=$RUNTIME_AREA/ProdCommon\n'
974 >            txt += '   export PYTHONPATH=$RUNTIME_AREA/\n'
975              txt += 'else\n'
976 <            txt += '   export PYTHONPATH=$RUNTIME_AREA/ProdCommon:${PYTHONPATH}\n'
976 >            txt += '   export PYTHONPATH=$RUNTIME_AREA/:${PYTHONPATH}\n'
977              txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
978              txt += 'fi\n'
979              txt += '\n'
# Line 942 | Line 994 | class Cmssw(JobType):
994          txt += 'rm -r lib/ module/ \n'
995          txt += 'mv $RUNTIME_AREA/lib/ . \n'
996          txt += 'mv $RUNTIME_AREA/module/ . \n'
997 <        txt += 'mv $RUNTIME_AREA/ProdCommon/ . \n'
997 >        if self.dataExist == True:
998 >            txt += 'rm -r src/ \n'
999 >            txt += 'mv $RUNTIME_AREA/src/ . \n'
1000 >        if len(self.additional_inbox_files)>0:
1001 >            for file in self.additional_inbox_files:
1002 >                txt += 'mv $RUNTIME_AREA/'+os.path.basename(file)+' . \n'
1003 >        # txt += 'mv $RUNTIME_AREA/ProdCommon/ . \n'
1004 >        # txt += 'mv $RUNTIME_AREA/IMProv/ . \n'
1005  
1006 +        txt += 'echo ">>> Include $RUNTIME_AREA in PYTHONPATH:"\n'
1007          txt += 'if [ -z "$PYTHONPATH" ]; then\n'
1008 <        txt += '   export PYTHONPATH=$SOFTWARE_DIR/ProdCommon\n'
1008 >        txt += '   export PYTHONPATH=$RUNTIME_AREA/\n'
1009          txt += 'else\n'
1010 <        txt += '   export PYTHONPATH=$SOFTWARE_DIR/ProdCommon:${PYTHONPATH}\n'
1010 >        txt += '   export PYTHONPATH=$RUNTIME_AREA/:${PYTHONPATH}\n'
1011          txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
1012          txt += 'fi\n'
1013          txt += '\n'
1014  
1015          return txt
1016  
957    def modifySteeringCards(self, nj):
958        """
959        modify the card provided by the user,
960        writing a new card into share dir
961        """
1017  
1018      def executableName(self):
1019 <        if self.scriptExe: #CarlosDaniele
1019 >        if self.scriptExe:
1020              return "sh "
1021          else:
1022              return self.executable
# Line 971 | Line 1026 | class Cmssw(JobType):
1026          if self.scriptExe:#CarlosDaniele
1027              return   self.scriptExe + " $NJob"
1028          else:
974            version_array = self.scram.getSWVersion().split('_')
975            major = 0
976            minor = 0
977            try:
978                major = int(version_array[1])
979                minor = int(version_array[2])
980            except:
981                msg = "Cannot parse CMSSW version string: " + "_".join(version_array) + " for major and minor release number!"
982                raise CrabException(msg)
983
1029              ex_args = ""
1030              # FUTURE: This tests the CMSSW version. Can remove code as versions deprecated
1031              # Framework job report
1032 <            if major >= 1 and minor >= 5 :
1032 >            if (self.CMSSW_major >= 1 and self.CMSSW_minor >= 5) or (self.CMSSW_major >= 2):
1033                  ex_args += " -j $RUNTIME_AREA/crab_fjr_$NJob.xml"
1034 <            # Type of cfg file
1035 <            if major >= 2 :
1034 >            # Type of config file
1035 >            if self.CMSSW_major >= 2 :
1036                  ex_args += " -p pset.py"
1037              else:
1038                  ex_args += " -p pset.cfg"
# Line 998 | Line 1043 | class Cmssw(JobType):
1043          Returns a list of filenames to be put in JDL input sandbox.
1044          """
1045          inp_box = []
1001        # # dict added to delete duplicate from input sandbox file list
1002        # seen = {}
1003        ## code
1046          if os.path.isfile(self.tgzNameWithPath):
1047              inp_box.append(self.tgzNameWithPath)
1006        if os.path.isfile(self.MLtgzfile):
1007            inp_box.append(self.MLtgzfile)
1008        ## config
1009        if not self.pset is None:
1010            inp_box.append(common.work_space.pathForTgz() + 'job/' + self.configFilename())
1011        ## additional input files
1012        tgz = self.additionalInputFileTgz()
1013        inp_box.append(tgz)
1014        ## executable
1048          wrapper = os.path.basename(str(common._db.queryTask('scriptName')))
1049          inp_box.append(common.work_space.pathForTgz() +'job/'+ wrapper)
1050          return inp_box
# Line 1025 | Line 1058 | class Cmssw(JobType):
1058          ## User Declared output files
1059          for out in (self.output_file+self.output_file_sandbox):
1060              n_out = nj + 1
1061 <            out_box.append(self.numberFile_(out,str(n_out)))
1061 >            out_box.append(numberFile(out,str(n_out)))
1062          return out_box
1063  
1031    def prepareSteeringCards(self):
1032        """
1033        Make initial modifications of the user's steering card file.
1034        """
1035        return
1064  
1065      def wsRenameOutput(self, nj):
1066          """
# Line 1042 | Line 1070 | class Cmssw(JobType):
1070          txt = '\n#Written by cms_cmssw::wsRenameOutput\n'
1071          txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
1072          txt += 'echo ">>> current directory content:"\n'
1073 <        txt += 'ls \n'
1073 >        if self.debug_wrapper:
1074 >            txt += 'ls -Al\n'
1075          txt += '\n'
1076  
1077          for fileWithSuffix in (self.output_file):
1078 <            output_file_num = self.numberFile_(fileWithSuffix, '$NJob')
1078 >            output_file_num = numberFile(fileWithSuffix, '$NJob')
1079              txt += '\n'
1080              txt += '# check output file\n'
1081              txt += 'if [ -e ./'+fileWithSuffix+' ] ; then\n'
# Line 1067 | Line 1096 | class Cmssw(JobType):
1096              txt += 'fi\n'
1097          file_list = []
1098          for fileWithSuffix in (self.output_file):
1099 <             file_list.append(self.numberFile_(fileWithSuffix, '$NJob'))
1099 >             file_list.append(numberFile(fileWithSuffix, '$NJob'))
1100  
1101          txt += 'file_list="'+string.join(file_list,' ')+'"\n'
1102          txt += '\n'
1103          txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
1104          txt += 'echo ">>> current directory content:"\n'
1105 <        txt += 'ls \n'
1105 >        if self.debug_wrapper:
1106 >            txt += 'ls -Al\n'
1107          txt += '\n'
1108          txt += 'cd $RUNTIME_AREA\n'
1109          txt += 'echo ">>> current directory (RUNTIME_AREA):  $RUNTIME_AREA"\n'
1110          return txt
1111  
1082    def numberFile_(self, file, txt):
1083        """
1084        append _'txt' before last extension of a file
1085        """
1086        p = string.split(file,".")
1087        # take away last extension
1088        name = p[0]
1089        for x in p[1:-1]:
1090            name=name+"."+x
1091        # add "_txt"
1092        if len(p)>1:
1093            ext = p[len(p)-1]
1094            result = name + '_' + txt + "." + ext
1095        else:
1096            result = name + '_' + txt
1097
1098        return result
1099
1112      def getRequirements(self, nj=[]):
1113          """
1114          return job requirements to add to jdl files
# Line 1106 | Line 1118 | class Cmssw(JobType):
1118              req='Member("VO-cms-' + \
1119                   self.version + \
1120                   '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
1121 <        ## SL add requirement for OS version only if SL4
1110 <        #reSL4 = re.compile( r'slc4' )
1111 <        if self.executable_arch: # and reSL4.search(self.executable_arch):
1121 >        if self.executable_arch:
1122              req+=' && Member("VO-cms-' + \
1123                   self.executable_arch + \
1124                   '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
# Line 1121 | Line 1131 | class Cmssw(JobType):
1131  
1132      def configFilename(self):
1133          """ return the config filename """
1134 <        return self.name()+'.cfg'
1134 >        # FUTURE: Can remove cfg mode for CMSSW >= 2_1_x
1135 >        if (self.CMSSW_major >= 2 and self.CMSSW_minor >= 1) or (self.CMSSW_major >= 3):
1136 >          return self.name()+'.py'
1137 >        else:
1138 >          return self.name()+'.cfg'
1139  
1140      def wsSetupCMSOSGEnvironment_(self):
1141          """
# Line 1147 | Line 1161 | class Cmssw(JobType):
1161  
1162          return txt
1163  
1150    ### OLI_DANIELE
1164      def wsSetupCMSLCGEnvironment_(self):
1165          """
1166          Returns part of a job script which is prepares
# Line 1182 | Line 1195 | class Cmssw(JobType):
1195          txt += '    echo "==> setup cms environment ok"\n'
1196          return txt
1197  
1185    ### FEDE FOR DBS OUTPUT PUBLICATION
1198      def modifyReport(self, nj):
1199          """
1200          insert the part of the script that modifies the FrameworkJob Report
1201          """
1190
1202          txt = '\n#Written by cms_cmssw::modifyReport\n'
1203          publish_data = int(self.cfg_params.get('USER.publish_data',0))
1204          if (publish_data == 1):
1205              processedDataset = self.cfg_params['USER.publish_data_name']
1206 <            LFNBaseName = LFNBase(processedDataset)
1206 >            ### FEDE  for publication with LSF and CAF schedulers ####
1207 >            print "common.scheduler.name().upper() = ", common.scheduler.name().upper()
1208 >            if (common.scheduler.name().upper() == "CAF" or common.scheduler.name().upper() == "LSF"):
1209 >                print "chiamo LFNBaseName con localUser = true"
1210 >                LFNBaseName = LFNBase(processedDataset, LocalUser=True)
1211 >            else :    
1212 >                LFNBaseName = LFNBase(processedDataset)
1213 >            ####    
1214  
1215              txt += 'if [ $copy_exit_status -eq 0 ]; then\n'
1216              txt += '    FOR_LFN=%s_${PSETHASH}/\n'%(LFNBaseName)
# Line 1201 | Line 1219 | class Cmssw(JobType):
1219              txt += '    SE=""\n'
1220              txt += '    SE_PATH=""\n'
1221              txt += 'fi\n'
1222 <            
1222 >
1223              txt += 'echo ">>> Modify Job Report:" \n'
1224 <            txt += 'chmod a+x $SOFTWARE_DIR/ProdCommon/ProdCommon/FwkJobRep/ModifyJobReport.py\n'
1224 >            txt += 'chmod a+x $RUNTIME_AREA/ProdCommon/FwkJobRep/ModifyJobReport.py\n'
1225              txt += 'ProcessedDataset='+processedDataset+'\n'
1226              txt += 'echo "ProcessedDataset = $ProcessedDataset"\n'
1227              txt += 'echo "SE = $SE"\n'
1228              txt += 'echo "SE_PATH = $SE_PATH"\n'
1229              txt += 'echo "FOR_LFN = $FOR_LFN" \n'
1230              txt += 'echo "CMSSW_VERSION = $CMSSW_VERSION"\n\n'
1231 <            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'
1232 <            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'
1231 >            txt += 'echo "$RUNTIME_AREA/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'
1232 >            txt += '$RUNTIME_AREA/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'
1233              txt += 'modifyReport_result=$?\n'
1234              txt += 'if [ $modifyReport_result -ne 0 ]; then\n'
1235              txt += '    modifyReport_result=70500\n'
# Line 1223 | Line 1241 | class Cmssw(JobType):
1241              txt += 'fi\n'
1242          return txt
1243  
1244 +    def wsParseFJR(self):
1245 +        """
1246 +        Parse the FrameworkJobReport to obtain useful infos
1247 +        """
1248 +        txt = '\n#Written by cms_cmssw::wsParseFJR\n'
1249 +        txt += 'echo ">>> Parse FrameworkJobReport crab_fjr.xml"\n'
1250 +        txt += 'if [ -s $RUNTIME_AREA/crab_fjr_$NJob.xml ]; then\n'
1251 +        txt += '    if [ -s $RUNTIME_AREA/parseCrabFjr.py ]; then\n'
1252 +        txt += '        cmd_out=`python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --dashboard $MonitorID,$MonitorJobID '+self.debugWrap+'`\n'
1253 +        if self.debug_wrapper :
1254 +            txt += '        echo "Result of parsing the FrameworkJobReport crab_fjr.xml: $cmd_out"\n'
1255 +        txt += '        executable_exit_status=`python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --exitcode`\n'
1256 +        txt += '        if [ $executable_exit_status -eq 50115 ];then\n'
1257 +        txt += '            echo ">>> crab_fjr.xml contents: "\n'
1258 +        txt += '            cat $RUNTIME_AREA/crab_fjr_$NJob.xml\n'
1259 +        txt += '            echo "Wrong FrameworkJobReport --> does not contain useful info. ExitStatus: $executable_exit_status"\n'
1260 +        txt += '        elif [ $executable_exit_status -eq -999 ];then\n'
1261 +        txt += '            echo "ExitStatus from FrameworkJobReport not available. not available. Using exit code of executable from command line."\n'
1262 +        txt += '        else\n'
1263 +        txt += '            echo "Extracted ExitStatus from FrameworkJobReport parsing output: $executable_exit_status"\n'
1264 +        txt += '        fi\n'
1265 +        txt += '    else\n'
1266 +        txt += '        echo "CRAB python script to parse CRAB FrameworkJobReport crab_fjr.xml is not available, using exit code of executable from command line."\n'
1267 +        txt += '    fi\n'
1268 +          #### Patch to check input data reading for CMSSW16x Hopefully we-ll remove it asap
1269 +
1270 +        if (self.datasetPath and not self.dataset_pu ):
1271 +          # VERIFY PROCESSED DATA
1272 +            txt += '    if [ $executable_exit_status -eq 0 ];then\n'
1273 +            txt += '      echo ">>> Verify list of processed files:"\n'
1274 +            txt += '      echo $InputFiles |tr -d \'\\\\\' |tr \',\' \'\\n\'|tr -d \'"\' > input-files.txt\n'
1275 +            txt += '      python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --lfn > processed-files.txt\n'
1276 +            txt += '      cat input-files.txt  | sort | uniq > tmp.txt\n'
1277 +            txt += '      mv tmp.txt input-files.txt\n'
1278 +            txt += '      echo "cat input-files.txt"\n'
1279 +            txt += '      echo "----------------------"\n'
1280 +            txt += '      cat input-files.txt\n'
1281 +            txt += '      cat processed-files.txt | sort | uniq > tmp.txt\n'
1282 +            txt += '      mv tmp.txt processed-files.txt\n'
1283 +            txt += '      echo "----------------------"\n'
1284 +            txt += '      echo "cat processed-files.txt"\n'
1285 +            txt += '      echo "----------------------"\n'
1286 +            txt += '      cat processed-files.txt\n'
1287 +            txt += '      echo "----------------------"\n'
1288 +            txt += '      diff -q input-files.txt processed-files.txt\n'
1289 +            txt += '      fileverify_status=$?\n'
1290 +            txt += '      if [ $fileverify_status -ne 0 ]; then\n'
1291 +            txt += '         executable_exit_status=30001\n'
1292 +            txt += '         echo "ERROR ==> not all input files processed"\n'
1293 +            txt += '         echo "      ==> list of processed files from crab_fjr.xml differs from list in pset.cfg"\n'
1294 +            txt += '         echo "      ==> diff input-files.txt processed-files.txt"\n'
1295 +            txt += '      fi\n'
1296 +            txt += '    fi\n'
1297 +            txt += '\n'
1298 +        txt += 'else\n'
1299 +        txt += '    echo "CRAB FrameworkJobReport crab_fjr.xml is not available, using exit code of executable from command line."\n'
1300 +        txt += 'fi\n'
1301 +        txt += '\n'
1302 +        txt += 'echo "ExeExitCode=$executable_exit_status" | tee -a $RUNTIME_AREA/$repo\n'
1303 +        txt += 'echo "EXECUTABLE_EXIT_STATUS = $executable_exit_status"\n'
1304 +        txt += 'job_exit_code=$executable_exit_status\n'
1305 +
1306 +        return txt
1307 +
1308      def setParam_(self, param, value):
1309          self._params[param] = value
1310  
# Line 1249 | Line 1331 | class Cmssw(JobType):
1331          stderr = 'CMSSW_$NJob.stderr'
1332          if (self.return_data == 1):
1333              for file in (self.output_file+self.output_file_sandbox):
1334 <                listOutFiles.append(self.numberFile_(file, '$NJob'))
1334 >                listOutFiles.append(numberFile(file, '$NJob'))
1335              listOutFiles.append(stdout)
1336              listOutFiles.append(stderr)
1337          else:
1338              for file in (self.output_file_sandbox):
1339 <                listOutFiles.append(self.numberFile_(file, '$NJob'))
1339 >                listOutFiles.append(numberFile(file, '$NJob'))
1340              listOutFiles.append(stdout)
1341              listOutFiles.append(stderr)
1342          txt += 'echo "output files: '+string.join(listOutFiles,' ')+'"\n'

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines