/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
DQM/SiStripMonitorClient/scripts/submitDQMOfflineCAF.py
857 строк
34 KB
Shahzad Malik Muzaffar
[DQM] py2/3 compatibility:drop use of __future__
22 ноя 2024, 20:16
22 ноя 2024, 20:16
e462f8e
Код
Авторство
О чём код?
#!/usr/bin/env python3 # # ## CMSSW/DQM/SiStripMonitorClient/scripts/submitDQMOfflineCAF.py # # This script submits CRAB/LSF jobs to the CAF in order to process the full # granularity SiStrip offline DQM. # Questions and comments to: volker.adler@cern.ch import sys import os import os.path import subprocess import shutil import string import math import urllib import time import datetime import smtplib # Constants # numbers OCT_rwx_r_r = 0o744 LFLOAT_valueMagField = [0.0,2.0,3.0,3.5,3.8,4.0] TD_shiftUTC = datetime.timedelta(hours = 2) # positive for timezones with later time than UTC # strings LSTR_true = ['1','TRUE' ,'True' ,'true' ] LSTR_false = ['0','FALSE','False','false'] STR_default = 'DEFAULT' STR_none = 'None' LSTR_auto = ['AUTO','Auto','auto'] STR_nameCmsswPackage = 'DQM/SiStripMonitorClient' STR_textUsage = """ CMSSW/DQM/SiStripMonitorClient/scripts/submitDQMOfflineCAF.py This script submits batch jobs to the CAF in order to process the full granularity SiStrip offline DQM. Questions and comments to: volker.adler@cern.ch Func_Usage(): submitDQMOfflineCAF.py (-s, --submit | -c, --create | -h, --help) [-r, --run] [-C, --CRAB] [-S, --server] [-e, --email] [-j, --jobs] [-f, --filter] [-d, --dataset] [-o, --outpath] [-m, --mergepath] Function letters: One of the following options m u s t be used. -s, --submit create jobs and submit them to CAF; requires option '-r' -c, --create create jobs, but do not submit them; requires option '-r' -h, --help print this message Other options: -r, --run RUNNUMBER number of run to process; required by funtion letters '-s' and '-c' -d, --dataset PRIMARY_DATASET specify dataset for DBS query; required by funtion letters '-s' and '-c' -C, --CRAB TRUE/FALSE submit or submit not using CRAB; default: TRUE NOTE: This script runs only with CRAB 2.4.0 or higher. -S, --server CRAB_SERVER CRAB server to use; available: None (default) caf (works, but slow) bari (CRAB version >= 2.4.1, s. https://twiki.cern.ch/twiki/bin/view/CMS/CrabServer#Server_available_for_users) NOTE: CRAB server submission is disabled at the moment. -e, --email EMAIL_ADDRESS where the CRAB server should send its messages; default: volker.adler@cern.ch -j, --jobs NUMBER number of jobs to create; default: 10 -g, --global-tag GLOBAL_TAG global tag to be used; default: CRAFT_V4P::All -M, --magnetic-field FIELD specification of field to be used; can be: - average field during run in Tesla, given as float (e.g.: 3.8), - specification referring to existing configuration files (e.g.: 38T) (s. Configuration/StandardSequences/python/MagneticField_[FIELD]_cff.py), - usage of automatic average field determination from CMS WBM by using "auto" default: 38T NOTE: "auto" is disabled for the moment due to unavailablity of CMS WBM outside '.cms' network. -f, --filter TRUE/FALSE use or use not HLT filters to select events to process; default: FALSE -o, --outpath PATH path to copy job output *.root files to; currently (almost) no check performed; must be in AFS or CASTOR default: /castor/cern.ch/user/c/cctrack/DQM -m, --mergepath PATH path to merge the job output *.root files; currently (almost) no check performed; must be in AFS or on local computer (e.g. /tmp/[user]) default: /afs/cern.ch/cms/CAF/CMSCOMM/COMM_TRACKER/DQM/SiStrip/jobs/merged """ LSTR_datatiers = ['RECO','RAW'] # argument vector LSTR_wordArgument = sys.argv[1:] # default arguments BOOL_CRAB = True LSTR_server = [STR_none,'caf','bari'] STR_server = LSTR_server[0] STR_email = 'volker.adler@cern.ch' INT_jobs = 10 STR_globalTag = 'CRAFT_V4P::All' STR_magField = '38T' BOOL_magFieldAuto = False BOOL_filter = False STR_outpath = '/castor/cern.ch/user/c/cctrack/DQM' BOOL_useCastor = True STR_mergepath = '/afs/cern.ch/cms/CAF/CMSCOMM/COMM_TRACKER/DQM/SiStrip/jobs/merged' # option lists LSTR_functionLetters = ['-s','-c','-h'] DICT_functionLetters = {'--submit':LSTR_functionLetters[0], '--create':LSTR_functionLetters[1], '--help' :LSTR_functionLetters[2]} LSTR_optionLetters = ['-r','-C','-S','-e','-j','-M','-g','-f','-d','-o','-m'] DICT_optionLetters = {'--run' :LSTR_optionLetters[0], '--CRAB' :LSTR_optionLetters[1], '--server' :LSTR_optionLetters[2], '--email' :LSTR_optionLetters[3], '--jobs' :LSTR_optionLetters[4], '--magnetic-field':LSTR_optionLetters[5], '--global-tag' :LSTR_optionLetters[6], '--filter' :LSTR_optionLetters[7], '--dataset' :LSTR_optionLetters[8], '--outpath' :LSTR_optionLetters[9], '--mergepath' :LSTR_optionLetters[10]} STR_mailSmtp = 'localhost' STR_mailServer = '@mail.cern.ch' STR_mailTextOpener = """Dear """ + os.getenv('USER').capitalize() + """, on """ + str(time.ctime()) + """, you have submitted run """ STR_mailText = """ for SiStrip offline DQM at the CAF. Unfortunately, this needed to be done from your private account. So, only you are able to finalize this submission -- even after the end of your shift. To do so, please forward all emails from the LSF batch system referring to the respective jobs to the list t h i s message was sent to. -- and then your shift is r e a l l y done :-) We are very sorry for the inconvenience. Thanks a lot! Best regards, your SiStrip DQM team P.S.: To reply to this email, simply use the "Reply to all" function of your email client. """ # Globals # arguments global Dict_arguments global Str_run global Bool_CRAB global Str_server global Str_email global Int_jobs global Str_globalTag global Bool_filter global Str_dataset global Str_datatier global Str_magField global Float_magField global Bool_magFieldAuto global Str_outpath global Bool_useCastor global Str_mergepath # others global Str_pathCurrentDir global Str_pathCmsswBase global Str_nameCmsswRel global Str_pathCmsswBasePackage global Str_nameRun global Str_pathRunIncludeDir global Str_pathInputFilesCAFCff global Int_jobsNew global Str_magField # initialize arguments Dict_arguments = {} Bool_CRAB = BOOL_CRAB Str_server = STR_server Str_email = STR_email Int_jobs = INT_jobs Str_globalTag = STR_globalTag Bool_filter = BOOL_filter Str_magField = STR_magField Float_magField = float(Str_magField[:-1])/10. Bool_magFieldAuto = BOOL_magFieldAuto Str_outpath = STR_outpath Bool_useCastor = BOOL_useCastor Str_mergepath = STR_mergepath ## Function Func_Usage() # # Displays usage of the script def Func_Usage(): """ Function Func_Usage(): Displays usage of the script """ print(STR_textUsage) ## Function Func_Exit() # # Exit after error def Func_Exit(): """ Function Func_Exit(): Exit after error """ print(' exit') print() sys.exit(1) ## Function Func_ExitUsage() # # Exit after wrong invocation of script def Func_ExitUsage(): """ Function Func_ExitUsage(): Exit after wrong invocation of script """ print(' exit') print() Func_Usage() sys.exit(1) ## Function Func_ExitBool() # # Exit after wrong assignment of bool option def Func_ExitBool(int_index): """ Function Func_ExitBool(): Exit after wrong assignment of bool option """ print('> submitDQMOfflineCAF.py > option %s expects 0/1, FALSE/TRUE, False/True or false/true' %(DICT_optionLetters.items()[int_index])) Func_Exit() ## Function Func_MkDir() # # Create new directory def Func_MkDir(str_path): """ Function Func_MkDir(): Create new directory """ shutil.rmtree(str_path, True) os.mkdir(str_path) ## Function Func_MagConfig(float_magFieldMeasured) # # Determine configuration to be used for a given magnetic field def Func_MagConfig(float_magFieldMeasured): """ Func_MagConfig(float_magFieldMeasured): Determine configuration to be used for a given magnetic field """ float_magField = 0.0 for float_valueMagField in LFLOAT_valueMagField: if math.fabs(float_valueMagField-float_magFieldMeasured) < math.fabs(float_magField-float_magFieldMeasured): float_magField = float_valueMagField return float_magField ## Main program print() # Current environment Str_pathCurrentDir = os.getcwd() Str_pathCmsswBase = os.getenv('CMSSW_BASE') if not Str_pathCmsswBase: print('> submitDQMOfflineCAF.py > CMSSW environment not set properly;') print(' first do') print() print(' $ cd [your/CMSSW/release/area]/src') print(' $ cmsenv') print() Func_Exit() Str_nameCmsswRel = os.getenv('CMSSW_VERSION') Str_pathCmsswBasePackage = Str_pathCmsswBase + '/src/' + STR_nameCmsswPackage str_suffixShell = 'csh' if not os.getenv('SHELL')[-3:] == str_suffixShell: str_suffixShell = 'sh' # Check function letters if len(LSTR_wordArgument) == 0: Func_ExitUsage() int_nFunctionLetters = 0 for str_argument in LSTR_wordArgument: if str_argument in LSTR_functionLetters or\ str_argument in DICT_functionLetters : int_nFunctionLetters += 1 if int_nFunctionLetters == 0: print('> submitDQMOfflineCAF.py > no or unknown function letter used') Func_ExitUsage() elif int_nFunctionLetters > 1: print('> submitDQMOfflineCAF.py > too many function letter used') Func_ExitUsage() # Check options str_argumentFormer = '' bool_standBy = False for str_argument in LSTR_wordArgument: if not ( str_argument in LSTR_functionLetters or str_argument in DICT_functionLetters or\ str_argument in LSTR_optionLetters or str_argument in DICT_optionLetters ): if str_argument[0] == '-': print('> submitDQMOfflineCAF.py > unknown option used') Func_ExitUsage() if not bool_standBy: print('> submitDQMOfflineCAF.py > value without option used') Func_ExitUsage() Dict_arguments[str_argumentFormer] = str_argument bool_standBy = False else: if bool_standBy: Dict_arguments[str_argumentFormer] = STR_default if str_argumentFormer in LSTR_optionLetters or\ str_argumentFormer in DICT_optionLetters: print('> submitDQMOfflineCAF.py > option "%s" w/o value' %(str_argumentFormer)) print(' default used') print() bool_standBy = not ( str_argument in LSTR_functionLetters or\ str_argument in DICT_functionLetters ) if not bool_standBy: Dict_arguments[str_argument] = STR_default str_argumentFormer = str_argument if bool_standBy: Dict_arguments[str_argumentFormer] = STR_default if str_argumentFormer in LSTR_optionLetters or\ str_argumentFormer in DICT_optionLetters : print('> submitDQMOfflineCAF.py > option "%s" w/o value' %(str_argumentFormer)) print(' default used') print() # Correct arguments' dictionary dict_arguments = Dict_arguments for str_key, str_value in dict_arguments.items(): if str_key in DICT_functionLetters.keys(): del Dict_arguments[str_key] Dict_arguments[DICT_functionLetters[str_key]] = str_value if str_key in DICT_optionLetters.keys(): del Dict_arguments[str_key] Dict_arguments[DICT_optionLetters[str_key]] = str_value # Help (exit) if LSTR_functionLetters[2] in Dict_arguments: Func_Usage() sys.exit(0) # Check and assign arguments # run number if LSTR_optionLetters[0] in Dict_arguments and\ Dict_arguments[LSTR_optionLetters[0]] != STR_default : Str_run = Dict_arguments[LSTR_optionLetters[0]] else: print('> submitDQMOfflineCAF.py > no run number given') Func_Exit() # use CRAB if LSTR_optionLetters[1] in Dict_arguments and\ Dict_arguments[LSTR_optionLetters[1]] != STR_default : if Dict_arguments[LSTR_optionLetters[1]] in LSTR_true: Bool_CRAB = True elif Dict_arguments[LSTR_optionLetters[1]] in LSTR_false: Bool_CRAB = False else: Func_ExitBool(1) # name of CRAB server if LSTR_optionLetters[2] in Dict_arguments and\ Dict_arguments[LSTR_optionLetters[2]] != STR_default : Str_server = Dict_arguments[LSTR_optionLetters[2]] # email address to be used by CRAB server if LSTR_optionLetters[3] in Dict_arguments and\ Dict_arguments[LSTR_optionLetters[3]] != STR_default : Str_email = Dict_arguments[LSTR_optionLetters[3]] # number of jobs to create if LSTR_optionLetters[4] in Dict_arguments and\ Dict_arguments[LSTR_optionLetters[4]] != STR_default : Int_jobs = int(Dict_arguments[LSTR_optionLetters[4]]) # magnetic field if LSTR_optionLetters[5] in Dict_arguments and\ Dict_arguments[LSTR_optionLetters[5]] != STR_default : Str_magField = Dict_arguments[LSTR_optionLetters[5]] if Str_magField in LSTR_auto: # Bool_magFieldAuto = True print('> submitDQMOfflineCAF.py > automatic determination of magnetic field disabled at the moment') Func_Exit() # global tag if LSTR_optionLetters[6] in Dict_arguments and\ Dict_arguments[LSTR_optionLetters[6]] != STR_default : Str_globalTag = Dict_arguments[LSTR_optionLetters[6]] # use HLT to filter events if LSTR_optionLetters[7] in Dict_arguments and\ Dict_arguments[LSTR_optionLetters[7]] != STR_default : if Dict_arguments[LSTR_optionLetters[7]] in LSTR_true: Bool_filter = True elif Dict_arguments[LSTR_optionLetters[7]] in LSTR_false: Bool_filter = False else: Func_ExitBool(7) # primary dataset if LSTR_optionLetters[8] in Dict_arguments and\ Dict_arguments[LSTR_optionLetters[8]] != STR_default : Str_dataset = Dict_arguments[LSTR_optionLetters[8]] else: print('> submitDQMOfflineCAF.py > no primary dataset given') Func_Exit() # path for job output if LSTR_optionLetters[9] in Dict_arguments and\ Dict_arguments[LSTR_optionLetters[9]] != STR_default : Str_outpath = Dict_arguments[LSTR_optionLetters[9]] # path for merged output if LSTR_optionLetters[10] in Dict_arguments and\ Dict_arguments[LSTR_optionLetters[10]] != STR_default : Str_mergepath = Dict_arguments[LSTR_optionLetters[10]] # React on arguments # on use CRAB if Bool_CRAB: str_buffer = subprocess.getoutput('which crab') if str_buffer.find('which: no crab in') >= 0: str_suffixShell = 'csh' if not os.getenv('SHELL')[-3:] == str_suffixShell: str_suffixShell = 'sh' print('> submitDQMOfflineCAF.py > CRAB environment not set properly;') print(' please use') print() print(' $ source /afs/cern.ch/cms/ccs/wm/scripts/Crab/crab.%s' %(str_suffixShell)) print() Func_Exit() # on name of CRAB server if not Str_server in LSTR_server: print('> submitDQMOfflineCAF.py > CRAB server "%s" not available' %(Str_server)) Func_Exit() # on number of jobs if Int_jobs == 0: Int_jobs = 1 print('> submitDQMOfflineCAF.py > number of requested jobs was 0') print(' set to 1') # on magnetic field if Str_magField in LSTR_auto: # Bool_magFieldAuto = True print('> submitDQMOfflineCAF.py > automatic determination of magnetic field disabled at the moment') Func_Exit() elif Str_magField[-1] == 'T': bool_foundField = False for float_valueMagField in LFLOAT_valueMagField: if str(int(float_valueMagField*10)) == Str_magField[:-1]: Float_magField = float_valueMagField bool_foundField = True break if not bool_foundField: print('> submitDQMOfflineCAF.py > no magnet configuration for \'%s\' available' %(Str_magField)) Func_Exit() else: Float_magField = float(Str_magField) # FIXME protect better from wrong user input # on primary dataset # data tier str_datatier = Str_dataset.split('/')[-1] if str_datatier == 'RAW-RECO': Str_datatier = LSTR_datatiers[1] # FIXME: This should be an option else: Str_datatier = str_datatier Str_datatier = Str_dataset.split('/')[-1] if not Str_datatier in LSTR_datatiers: print('> submitDQMOfflineCAF.py > datatier "%s" not processable' %(Str_datatier)) Func_Exit() # on path for job output # use CASTOR if Str_outpath.split('/')[1] == 'afs': Bool_useCastor = False elif Str_outpath.split('/')[1] != 'castor': print('> submitDQMOfflineCAF.py > output path not accepted') Func_ExitUsage() str_castorCp = 'cp' if Bool_useCastor: str_castorCp = 'rfcp' # on path for merged output if Str_mergepath.split('/')[1] != 'afs': print('> submitDQMOfflineCAF.py > merge path not accepted') Func_ExitUsage() # Prepare work area # string identifying run (run name) Str_nameRun = 'R' + Str_run.zfill(9) # directories Func_MkDir(Str_nameRun) Str_pathRunIncludeDir = Str_pathCmsswBasePackage + '/python/' + Str_nameRun Func_MkDir(Str_pathRunIncludeDir) str_nameInputFilesFile = Str_nameRun + '/' + Str_nameRun + '.txt' str_nameRunIncludeDir = STR_nameCmsswPackage.replace('/','.') + '.' + Str_nameRun # Retrieving information from the web # input files int_nInputFiles = 0 file_inputFilesCff = file(str_nameInputFilesFile, 'w') # DBS query for list of input files str_dbsParams = urllib.urlencode({'dbsInst':'cms_dbs_prod_global', 'blockName':'*', 'dataset':Str_dataset, 'userMode':'user', 'run':Str_run, 'what':'py'}) file_dbsOutput = urllib.urlopen("https://cmsweb.cern.ch/dbs_discovery/getLFN_txt", str_dbsParams) for str_iLine in file_dbsOutput.readlines(): lstr_wordsLine = str_iLine.split("/") if len(lstr_wordsLine) >= 5: if lstr_wordsLine[1] == 'store' and\ lstr_wordsLine[2] == 'data' and\ Str_dataset.find(lstr_wordsLine[3]) >= 0 and\ Str_dataset.find(lstr_wordsLine[4]) >= 0 and\ lstr_wordsLine[5] == str_datatier : int_nInputFiles += 1 file_inputFilesCff.write(str_iLine) if int_nInputFiles == 0: print('> submitDQMOfflineCAF.py > no input files found in DBS for run %s in dataset %s' %(Str_run,Str_dataset)) Func_Exit() file_inputFilesCff.close() print('> submitDQMOfflineCAF.py > input files for run %s: %i' %(Str_run,int_nInputFiles)) if int_nInputFiles < Int_jobs: Int_jobs = int_nInputFiles print(' number of requested jobs reduced accordingly') Int_jobsNew = Int_jobs print() # magnetic field if Bool_magFieldAuto: # extract time stamps of the run str_cmsmonParams = urllib.urlencode({'RUN':Str_run}) file_cmsmonOutput = urllib.urlopen("http://cmsmon.cern.ch/cmsdb/servlet/RunSummary", str_cmsmonParams) str_timeBegin = '' str_timeEnd = '' for str_cmsmonOutput in file_cmsmonOutput.readlines(): if str_cmsmonOutput.find('HREF=Component?RUN=' + Str_run + '&NAME=TRACKER') >= 0: lstr_timeQuery = str_cmsmonOutput.split('HREF=Component?RUN=' + Str_run + '&NAME=TRACKER&')[1].split('>TRACKER')[0].split('&') for str_timeQuery in lstr_timeQuery: str_nameStamp = str_timeQuery.split('=')[0] lstr_timeDate = str_timeQuery.split('=')[1].split('_')[0].split('.') lstr_timeTime = str_timeQuery.split('=')[1].split('_')[1].split(':') dt_stampOld = datetime.datetime(int(lstr_timeDate[0]),int(lstr_timeDate[1]),int(lstr_timeDate[2]),int(lstr_timeTime[0]),int(lstr_timeTime[1]),int(lstr_timeTime[2])) dt_stampNew = dt_stampOld - TD_shiftUTC str_timeStamp = str(dt_stampNew).replace('-','.') if str_nameStamp == 'TIME_BEGIN': str_timeBegin = str_timeStamp elif str_nameStamp == 'TIME_END': str_timeEnd = str_timeStamp # get magnetic field itself str_cmsmonParams = urllib.urlencode({'TIME_BEGIN':str_timeBegin, 'TIME_END':str_timeEnd}) file_cmsmonOutput = urllib.urlopen("http://cmsmon.cern.ch/cmsdb/servlet/MagnetHistory", str_cmsmonParams) bool_foundField = False for str_cmsmonOutput in file_cmsmonOutput.readlines(): if str_cmsmonOutput.find('BFIELD, Tesla') >= 0: Float_magField = float(str_cmsmonOutput.split('</A>')[0].split('>')[-1]) bool_foundField = True break if not bool_foundField: print('> submitDQMOfflineCAF.py > could not extract magnetic field') print(' please provide value') Func_Exit() # determine corresponding configuration file to be included float_magField = Func_MagConfig(Float_magField) Str_magField = str(int(float_magField*10)) + 'T' print('> submitDQMOfflineCAF.py > (average) magnetic field in run %s: %s T' %(Str_run,Float_magField)) print(' using %s T for configuration' %(float_magField)) print() # Create scripts int_nLinesRead = 0 file_inputFilesCff = file(str_nameInputFilesFile) lstr_linesInput = file_inputFilesCff.readlines() file_inputFilesCff.close() # create harvesting config file and job script str_sedCommand = 'sed ' str_sedCommand += '-e \"s#xMAG_FIELDx#' + Str_magField + '#g\" ' str_sedCommand += '-e \"s#xGLOBAL_TAGx#' + Str_globalTag + '#g\" ' str_sedCommand += '-e \"s#xINCLUDE_DIRECTORYx#' + str_nameRunIncludeDir + '#g\" ' str_sedCommand += '-e \"s#xMERGE_PATHx#' + Str_mergepath + '#g\" ' str_sedCommand += Str_pathCmsswBasePackage + '/test/SiStripCAFHarvest_template_cfg.py > ' + Str_nameRun + '/SiStripCAFHarvest_cfg.py' os.system(str_sedCommand) str_sedCommand = 'sed ' str_sedCommand += '-e \"s#xCMSSW_BASEx#' + Str_pathCmsswBase + '#g\" ' str_sedCommand += '-e \"s#xRUN_NAMEx#' + Str_nameRun + '#g\" ' str_sedCommand += '-e \"s#xMERGE_PATHx#' + Str_mergepath + '#g\" ' str_sedCommand += '-e \"s#xCURRENT_DIRx#' + Str_pathCurrentDir + '#g\" ' str_sedCommand += '-e \"s#xDATA_TIERx#' + Str_datatier + '#g\" ' str_sedCommand += '-e \"s#xCMSSW_VERSIONx#' + Str_nameCmsswRel + '#g\" ' str_sedCommand += Str_pathCmsswBasePackage + '/scripts/SiStripDQMCAFHarvest_template.job > ' + Str_nameRun + '/SiStripCAFHarvest.job' os.system(str_sedCommand) # create included CAF input files list (mainly for compilation) Str_pathInputFilesCAFCff = Str_pathRunIncludeDir + '/inputFilesCAF_cff.py' file_inputFilesCAFCff = file(Str_pathInputFilesCAFCff, 'w') file_inputFilesCAFCff.write('import FWCore.ParameterSet.Config as cms\n\nsource = cms.Source ("PoolSource",\n processingMode = cms.untracked.string( \'Runs\' ),\n fileNames = cms.untracked.vstring(\n') for int_iJob in range(1,Int_jobs+1): str_lineInput = Str_outpath + '/SiStripDQMOfflineGlobalRunCAF-' + Str_nameRun + '_' + str(int_iJob) + '.root' if Bool_useCastor: str_lineInput = 'rfio:' + str_lineInput str_lineInput = ' \'' + str_lineInput + '\'' if int_iJob == Int_jobs: str_lineInput += '\n' file_inputFilesCAFCff.write(str_lineInput) break str_lineInput += ',\n' file_inputFilesCAFCff.write(str_lineInput) file_inputFilesCAFCff.write(' )\n)\n') file_inputFilesCAFCff.close() str_sedCommandCommon = 'sed ' if Bool_filter: str_sedCommandCommon += '-e \"s#xHLT_FILTERx# #g\" ' else: str_sedCommandCommon += '-e \"s#xHLT_FILTERx#\# #g\" ' if Str_datatier == 'RECO': str_sedCommandCommon += '-e \"s#xRECO_FROM_RAWx#\# #g\" ' str_sedCommandCommon += '-e \"s#xDQM_FROM_RAWx#\# #g\" ' else: str_sedCommandCommon += '-e \"s#xRECO_FROM_RAWx# #g\" ' str_sedCommandCommon += '-e \"s#xDQM_FROM_RAWx# #g\" ' str_sedCommandCommon += '-e \"s#xMAG_FIELDx#' + Str_magField + '#g\" ' str_sedCommandCommon += '-e \"s#xGLOBAL_TAGx#' + Str_globalTag + '#g\" ' str_sedCommandCommon += '-e \"s#xRUN_NAMEx#' + Str_nameRun + '#g\" ' if Bool_CRAB: os.chdir(Str_nameRun) str_outputDir = '.' # create main configuration file str_sedCommand = str_sedCommandCommon str_sedCommand += '-e \"s#xINCLUDE_DIRECTORYx#' + str_nameRunIncludeDir + '#g\" ' str_sedCommand += '-e \"s#xOUTPUT_DIRECTORYx#' + str_outputDir + '#g\" ' str_sedCommand += Str_pathCmsswBasePackage + '/test/SiStripDQMOfflineGlobalRunCAF_template_cfg.py > SiStripDQMOfflineGlobalRunCAF_cfg.py' os.system(str_sedCommand) # create included input files list str_pathInputFilesJobCff = Str_pathRunIncludeDir + '/inputFiles_cff.py' file_inputFilesJobCff = file(str_pathInputFilesJobCff, 'w') file_inputFilesJobCff.write('import FWCore.ParameterSet.Config as cms\n\nsource = cms.Source ("PoolSource",\n fileNames = cms.untracked.vstring (\n') nLines = 0 for str_linesInput in lstr_linesInput: nLines += 1 str_correctedLine1 = str_linesInput.replace(') );',',') str_correctedLine = str_correctedLine1.replace(' ] );',',') if nLines == len(lstr_linesInput): str_actualLine = str_correctedLine.replace(',','\n )\n)\n') elif nLines%255 == 0: # FIXME add this check also to LSF str_actualLine = str_correctedLine.replace(',','\n )\n)\nsource.fileNames.extend(\n (') else: str_actualLine = str_correctedLine file_inputFilesJobCff.write(str_actualLine) file_inputFilesJobCff.close() # create CRAB configuration file lstr_outpath = Str_outpath.split('/', 3) str_outpath = lstr_outpath[0] + '/' + lstr_outpath[1] + '/' + lstr_outpath[2] str_sedCommand = 'sed ' str_sedCommand += '-e \"s#xSERVER_NAMEx#' + Str_server + '#g\" ' str_sedCommand += '-e \"s#xDATASETPATHx#' + Str_dataset + '#g\" ' str_sedCommand += '-e \"s#xRUNSELECTIONx#' + Str_run + '#g\" ' str_sedCommand += '-e \"s#xNUMBER_OF_JOBSx#' + str(Int_jobs) + '#g\" ' str_sedCommand += '-e \"s#xEMAILx#' + Str_email + '#g\" ' str_sedCommand += '-e \"s#xRUN_NAMEx#' + Str_nameRun + '#g\" ' str_sedCommand += '-e \"s#xSTORAGE_PATHx#' + str_outpath + '#g\" ' str_sedCommand += '-e \"s#xLFNx#' + lstr_outpath[3] + '#g\" ' str_sedCommand += '-e \"s#xCOPY_DATAx#' + str(int(Bool_useCastor)) + '#g\" ' str_sedCommand += Str_pathCmsswBasePackage + '/test/SiStripDQMOfflineCAF_template.crab > crab.cfg' os.system(str_sedCommand) os.chdir(Str_pathCurrentDir) else: # FIXME: following calculation has to be reviewed int_nInputFilesJob = int(int_nInputFiles/Int_jobs) + 1 if int_nInputFiles%Int_jobs == 0: int_nInputFilesJob -= 1 if int_nInputFiles == int_nInputFilesJob*(Int_jobs-1) and Int_jobs > 1: Int_jobs -= 1 # loop over single jobs for int_iJob in range(1,Int_jobs+1): str_nameJob = Str_nameRun + '_' + str(int_iJob).zfill(4) # prepare job dir str_nameJobDir = Str_nameRun + "/" + str_nameJob str_outputDir = '/tmp/' + os.getenv('USER') + '/' + str_nameJobDir str_pathJobIncludeDir = Str_pathRunIncludeDir + '/' + str_nameJob str_nameJobIncludeDir = STR_nameCmsswPackage.replace('/','.') + '.' + str_nameJobDir.replace('/','.') os.mkdir(str_nameJobDir) os.chdir(str_nameJobDir) # create job script str_sedCommand = 'sed ' str_sedCommand += '-e \"s#xCMSSW_BASEx#' + Str_pathCmsswBase + '#g\" ' str_sedCommand += '-e \"s#xRUN_NAMEx#' + Str_nameRun + '#g\" ' str_sedCommand += '-e \"s#xJOB_NAMEx#' + str_nameJob + '#g\" ' str_sedCommand += '-e \"s#xCURRENT_DIRx#' + Str_pathCurrentDir + '#g\" ' str_sedCommand += '-e \"s#xCOPYx#' + str_castorCp + '#g\" ' str_sedCommand += '-e \"s#xOUTPUT_DIRx#' + Str_outpath + '#g\" ' str_sedCommand += Str_pathCmsswBasePackage + '/scripts/SiStripDQMOfflineCAF_template.job > SiStripDQMOfflineCAF.job' os.system(str_sedCommand) # create main configuration file str_sedCommand = str_sedCommandCommon str_sedCommand += '-e \"s#xINCLUDE_DIRECTORYx#' + str_nameJobIncludeDir + '#g\" ' str_sedCommand += '-e \"s#xOUTPUT_DIRECTORYx#' + str_outputDir + '#g\" ' str_sedCommand += Str_pathCmsswBasePackage + '/test/SiStripDQMOfflineGlobalRunCAF_template_cfg.py > SiStripDQMOfflineGlobalRunCAF_cfg.py' os.system(str_sedCommand) # prepare job include dir os.mkdir(str_pathJobIncludeDir) # create included input files list str_pathInputFilesJobCff = str_pathJobIncludeDir + '/inputFiles_cff.py' file_inputFilesJobCff = file(str_pathInputFilesJobCff, 'w') file_inputFilesJobCff.write('import FWCore.ParameterSet.Config as cms\n\nsource = cms.Source ("PoolSource",\n fileNames = cms.untracked.vstring (\n') for n_iActualLine in range(int_nLinesRead, min(int_nLinesRead+int_nInputFilesJob, int_nInputFiles)): str_linesInput = lstr_linesInput[n_iActualLine].replace(') );',',') # fix commata and end of line str_actualLine = str_linesInput if (n_iActualLine+1)%int_nInputFilesJob == 0 or int_nLinesRead == int_nInputFiles-1: str_actualLine = str_linesInput.split(',')[0] + '\n' file_inputFilesJobCff.write(str_actualLine) int_nLinesRead += 1 file_inputFilesJobCff.write(' )\n)\n') file_inputFilesJobCff.close() # finalize job creation os.chdir(Str_pathCurrentDir) # FIXME: This protection is currently needed. Review calculations again! if int_nLinesRead >= int_nInputFiles: Int_jobsNew = int_iJob break # Compile os.chdir(Str_pathRunIncludeDir+'/..') os.system('scramv1 b python') os.chdir(Str_pathCurrentDir) print() # Create CRAB if Bool_CRAB: os.chdir(Str_nameRun) os.system('crab -create') print() # extract number of really created jobs bool_found = False file_logCRAB = file('crab'+Str_nameRun+'/log/crab.log') for str_iLine in file_logCRAB.readlines(): if str_iLine.startswith('Total of ') and str_iLine.endswith(' jobs created.\n'): bool_found = True Int_jobsNew = int(str_iLine.split()[2]) break file_logCRAB.close() os.chdir(Str_pathCurrentDir) if not bool_found: print('> submitDQMOfflineCAF.py > could not extract number of jobs created by CRAB; check') print(' %s' %(Str_pathInputFilesCAFCff)) print(' and modify manually, if necessary') print() # recreate included CAF input files list according to number of created jobs, if necessary print('> submitDQMOfflineCAF.py > number of created jobs: %i' %(Int_jobsNew)) print() if Int_jobsNew != Int_jobs: file_inputFilesCAFCff = file(Str_pathInputFilesCAFCff, 'w') file_inputFilesCAFCff.write('import FWCore.ParameterSet.Config as cms\n\nsource = cms.Source ("PoolSource",\n processingMode = cms.untracked.string( \'Runs\' ),\n fileNames = cms.untracked.vstring(\n') for int_iJob in range(1,Int_jobsNew+1): # FIXME use number of CRAB jobs created str_lineInput = Str_outpath + '/SiStripDQMOfflineGlobalRunCAF-' + Str_nameRun + '_' + str(int_iJob) + '.root' if Bool_useCastor: str_lineInput = 'rfio:' + str_lineInput str_lineInput = ' \'' + str_lineInput + '\'' if int_iJob == Int_jobsNew: str_lineInput += '\n' file_inputFilesCAFCff.write(str_lineInput) break str_lineInput += ',\n' file_inputFilesCAFCff.write(str_lineInput) file_inputFilesCAFCff.write(' )\n)\n') file_inputFilesCAFCff.close() # Submit jobs if LSTR_functionLetters[0] in Dict_arguments: os.chdir(Str_nameRun) if Bool_CRAB: str_crabCommand = 'crab -submit -c crab' + Str_nameRun print('> submitDQMOfflineCAF.py >') print(' %s : %s' %(os.getcwd(),str_crabCommand)) os.system(str_crabCommand) print() time.sleep(5) os.system('crab -status -c crab' + Str_nameRun) else: for int_iJob in range(Int_jobs): str_nameJobDir = Str_nameRun + '_' + str(int_iJob).zfill(4) os.chdir(str_nameJobDir) os.chmod('SiStripDQMOfflineCAF.job',OCT_rwx_r_r) str_batchCommand = 'bsub -q cmscaf SiStripDQMOfflineCAF.job' print('> submitDQMOfflineCAF.py >') print(' %s : %s' %(os.getcwd(),str_batchCommand)) os.system(str_batchCommand) print() os.chdir('../') time.sleep(5) os.system('bjobs -q cmscaf') os.chmod('SiStripCAFHarvest.job',OCT_rwx_r_r) os.chdir(Str_pathCurrentDir) # Send reminder email to submitter (not needed for CRAB) if LSTR_functionLetters[0] in Dict_arguments and not Bool_CRAB: str_mailFrom = os.getenv('USER') + STR_mailServer str_mailTo = [str_mailFrom, 'volker.adler@cern.ch', 'suchandra.dutta@cern.ch', 'domenico.giordano@cern.ch', 'vitaliano.ciulli@cern.ch'] str_mailSubject = 'Your SiStrip offline DQM shift on ' + str(datetime.date.today()) + ', run ' + Str_run str_mailText = STR_mailTextOpener + Str_run + STR_mailText str_mailMessage = """From: %s To: %s Subject: %s %s """ % (str_mailFrom, ", ".join(str_mailTo), str_mailSubject, str_mailText) server = smtplib.SMTP(STR_mailSmtp) server.sendmail(str_mailFrom, str_mailTo, str_mailMessage) server.quit()