CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
submitDQMOfflineCAF.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 #
4 #
5 
6 ## CMSSW/DQM/SiStripMonitorClient/scripts/submitDQMOfflineCAF.py
7 #
8 # This script submits CRAB/LSF jobs to the CAF in order to process the full
9 # granularity SiStrip offline DQM.
10 # Questions and comments to: volker.adler@cern.ch
11 
12 
13 import sys
14 import os
15 import os.path
16 import commands
17 import shutil
18 import string
19 import math
20 import urllib
21 import time
22 import datetime
23 import smtplib
24 
25 # Constants
26 
27 # numbers
28 OCT_rwx_r_r = 0744
29 LFLOAT_valueMagField = [0.0,2.0,3.0,3.5,3.8,4.0]
30 TD_shiftUTC = datetime.timedelta(hours = 2) # positive for timezones with later time than UTC
31 # strings
32 LSTR_true = ['1','TRUE' ,'True' ,'true' ]
33 LSTR_false = ['0','FALSE','False','false']
34 STR_default = 'DEFAULT'
35 STR_none = 'None'
36 LSTR_auto = ['AUTO','Auto','auto']
37 STR_nameCmsswPackage = 'DQM/SiStripMonitorClient'
38 STR_textUsage = """ CMSSW/DQM/SiStripMonitorClient/scripts/submitDQMOfflineCAF.py
39 
40  This script submits batch jobs to the CAF in order to process the full
41  granularity SiStrip offline DQM.
42  Questions and comments to: volker.adler@cern.ch
43 
44  Func_Usage(): submitDQMOfflineCAF.py (-s, --submit | -c, --create |
45  -h, --help)
46  [-r, --run]
47  [-C, --CRAB]
48  [-S, --server]
49  [-e, --email]
50  [-j, --jobs]
51  [-f, --filter]
52  [-d, --dataset]
53  [-o, --outpath]
54  [-m, --mergepath]
55 
56  Function letters: One of the following options m u s t be used.
57 
58  -s, --submit
59  create jobs and submit them to CAF;
60  requires option '-r'
61 
62  -c, --create
63  create jobs, but do not submit them;
64  requires option '-r'
65 
66  -h, --help
67  print this message
68 
69  Other options:
70 
71  -r, --run RUNNUMBER
72  number of run to process;
73  required by funtion letters '-s' and '-c'
74 
75  -d, --dataset PRIMARY_DATASET
76  specify dataset for DBS query;
77  required by funtion letters '-s' and '-c'
78 
79  -C, --CRAB TRUE/FALSE
80  submit or submit not using CRAB;
81  default: TRUE
82 
83  NOTE: This script runs only with CRAB 2.4.0 or higher.
84 
85  -S, --server CRAB_SERVER
86  CRAB server to use;
87  available: None (default)
88  caf (works, but slow)
89  bari (CRAB version >= 2.4.1,
90  s. https://twiki.cern.ch/twiki/bin/view/CMS/CrabServer#Server_available_for_users)
91 
92  NOTE: CRAB server submission is disabled at the moment.
93 
94  -e, --email EMAIL_ADDRESS
95  where the CRAB server should send its messages;
96  default: volker.adler@cern.ch
97 
98  -j, --jobs NUMBER
99  number of jobs to create;
100  default: 10
101 
102  -g, --global-tag GLOBAL_TAG
103  global tag to be used;
104  default: CRAFT_V4P::All
105 
106  -M, --magnetic-field FIELD
107  specification of field to be used;
108  can be:
109  - average field during run in Tesla, given as float (e.g.: 3.8),
110  - specification referring to existing configuration files (e.g.: 38T)
111  (s. Configuration/StandardSequences/python/MagneticField_[FIELD]_cff.py),
112  - usage of automatic average field determination from CMS WBM by using "auto"
113  default: 38T
114 
115  NOTE: "auto" is disabled for the moment due to unavailablity of CMS WBM outside '.cms' network.
116 
117  -f, --filter TRUE/FALSE
118  use or use not HLT filters to select events to process;
119  default: FALSE
120 
121  -o, --outpath PATH
122  path to copy job output *.root files to;
123  currently (almost) no check performed;
124  must be in AFS or CASTOR
125  default: /castor/cern.ch/user/c/cctrack/DQM
126 
127  -m, --mergepath PATH
128  path to merge the job output *.root files;
129  currently (almost) no check performed;
130  must be in AFS or on local computer (e.g. /tmp/[user])
131  default: /afs/cern.ch/cms/CAF/CMSCOMM/COMM_TRACKER/DQM/SiStrip/jobs/merged
132 """
133 LSTR_datatiers = ['RECO','RAW']
134 # argument vector
135 LSTR_wordArgument = sys.argv[1:]
136 # default arguments
137 BOOL_CRAB = True
138 LSTR_server = [STR_none,'caf','bari']
139 STR_server = LSTR_server[0]
140 STR_email = 'volker.adler@cern.ch'
141 INT_jobs = 10
142 STR_globalTag = 'CRAFT_V4P::All'
143 STR_magField = '38T'
144 BOOL_magFieldAuto = False
145 BOOL_filter = False
146 STR_outpath = '/castor/cern.ch/user/c/cctrack/DQM'
147 BOOL_useCastor = True
148 STR_mergepath = '/afs/cern.ch/cms/CAF/CMSCOMM/COMM_TRACKER/DQM/SiStrip/jobs/merged'
149 # option lists
150 LSTR_functionLetters = ['-s','-c','-h']
151 DICT_functionLetters = {'--submit':LSTR_functionLetters[0],
152  '--create':LSTR_functionLetters[1],
153  '--help' :LSTR_functionLetters[2]}
154 LSTR_optionLetters = ['-r','-C','-S','-e','-j','-M','-g','-f','-d','-o','-m']
155 DICT_optionLetters = {'--run' :LSTR_optionLetters[0],
156  '--CRAB' :LSTR_optionLetters[1],
157  '--server' :LSTR_optionLetters[2],
158  '--email' :LSTR_optionLetters[3],
159  '--jobs' :LSTR_optionLetters[4],
160  '--magnetic-field':LSTR_optionLetters[5],
161  '--global-tag' :LSTR_optionLetters[6],
162  '--filter' :LSTR_optionLetters[7],
163  '--dataset' :LSTR_optionLetters[8],
164  '--outpath' :LSTR_optionLetters[9],
165  '--mergepath' :LSTR_optionLetters[10]}
166 STR_mailSmtp = 'localhost'
167 STR_mailServer = '@mail.cern.ch'
168 STR_mailTextOpener = """Dear """ + os.getenv('USER').capitalize() + """,
169 
170 on """ + str(time.ctime()) + """, you have submitted run """
171 STR_mailText = """
172 for SiStrip offline DQM at the CAF.
173 Unfortunately, this needed to be done from your private account. So, only you
174 are able to finalize this submission -- even after the end of your shift.
175 To do so, please forward all emails from the LSF batch system referring to the
176 respective jobs to the list t h i s message was sent to.
177 -- and then your shift is r e a l l y done :-)
178 
179 We are very sorry for the inconvenience.
180 Thanks a lot!
181 
182 Best regards,
183 your SiStrip DQM team
184 
185 P.S.:
186 To reply to this email, simply use the "Reply to all" function of your email
187 client.
188 """
189 
190 # Globals
191 
192 # arguments
193 global Dict_arguments
194 global Str_run
195 global Bool_CRAB
196 global Str_server
197 global Str_email
198 global Int_jobs
199 global Str_globalTag
200 global Bool_filter
201 global Str_dataset
202 global Str_datatier
203 global Str_magField
204 global Float_magField
205 global Bool_magFieldAuto
206 global Str_outpath
207 global Bool_useCastor
208 global Str_mergepath
209 # others
210 global Str_pathCurrentDir
211 global Str_pathCmsswBase
212 global Str_nameCmsswRel
213 global Str_pathCmsswBasePackage
214 global Str_nameRun
215 global Str_pathRunIncludeDir
216 global Str_pathInputFilesCAFCff
217 global Int_jobsNew
218 global Str_magField
219 # initialize arguments
220 Dict_arguments = {}
221 Bool_CRAB = BOOL_CRAB
222 Str_server = STR_server
223 Str_email = STR_email
224 Int_jobs = INT_jobs
225 Str_globalTag = STR_globalTag
226 Bool_filter = BOOL_filter
227 Str_magField = STR_magField
228 Float_magField = float(Str_magField[:-1])/10.
229 Bool_magFieldAuto = BOOL_magFieldAuto
230 Str_outpath = STR_outpath
231 Bool_useCastor = BOOL_useCastor
232 Str_mergepath = STR_mergepath
233 
234 ## Function Func_Usage()
235 #
236 # Displays usage of the script
238  """ Function Func_Usage():
239  Displays usage of the script
240  """
241  print STR_textUsage
242 
243 ## Function Func_Exit()
244 #
245 # Exit after error
246 def Func_Exit():
247  """ Function Func_Exit():
248  Exit after error
249  """
250  print ' exit'
251  print
252  sys.exit(1)
253 
254 ## Function Func_ExitUsage()
255 #
256 # Exit after wrong invocation of script
258  """ Function Func_ExitUsage():
259  Exit after wrong invocation of script
260  """
261  print ' exit'
262  print
263  Func_Usage()
264  sys.exit(1)
265 
266 ## Function Func_ExitBool()
267 #
268 # Exit after wrong assignment of bool option
269 def Func_ExitBool(int_index):
270  """ Function Func_ExitBool():
271  Exit after wrong assignment of bool option
272  """
273  print '> submitDQMOfflineCAF.py > option %s expects 0/1, FALSE/TRUE, False/True or false/true' %(DICT_optionLetters.items()[int_index])
274  Func_Exit()
275 
276 ## Function Func_MkDir()
277 #
278 # Create new directory
279 def Func_MkDir(str_path):
280  """ Function Func_MkDir():
281  Create new directory
282  """
283  shutil.rmtree(str_path, True)
284  os.mkdir(str_path)
285 
286 ## Function Func_MagConfig(float_magFieldMeasured)
287 #
288 # Determine configuration to be used for a given magnetic field
289 def Func_MagConfig(float_magFieldMeasured):
290  """ Func_MagConfig(float_magFieldMeasured):
291  Determine configuration to be used for a given magnetic field
292  """
293  float_magField = 0.0
294  for float_valueMagField in LFLOAT_valueMagField:
295  if math.fabs(float_valueMagField-float_magFieldMeasured) < math.fabs(float_magField-float_magFieldMeasured):
296  float_magField = float_valueMagField
297  return float_magField
298 
299 ## Main program
300 
301 print
302 
303 # Current environment
304 
305 Str_pathCurrentDir = os.getcwd()
306 Str_pathCmsswBase = os.getenv('CMSSW_BASE')
307 if not Str_pathCmsswBase:
308  print '> submitDQMOfflineCAF.py > CMSSW environment not set properly;'
309  print ' first do'
310  print
311  print ' $ cd [your/CMSSW/release/area]/src'
312  print ' $ cmsenv'
313  print
314  Func_Exit()
315 Str_nameCmsswRel = os.getenv('CMSSW_VERSION')
316 Str_pathCmsswBasePackage = Str_pathCmsswBase + '/src/' + STR_nameCmsswPackage
317 str_suffixShell = 'csh'
318 if not os.getenv('SHELL')[-3:] == str_suffixShell:
319  str_suffixShell = 'sh'
320 
321 # Check function letters
322 
323 if len(LSTR_wordArgument) == 0:
325 int_nFunctionLetters = 0
326 for str_argument in LSTR_wordArgument:
327  if str_argument in LSTR_functionLetters or\
328  DICT_functionLetters.has_key(str_argument) :
329  int_nFunctionLetters += 1
330 if int_nFunctionLetters == 0:
331  print '> submitDQMOfflineCAF.py > no or unknown function letter used'
333 elif int_nFunctionLetters > 1:
334  print '> submitDQMOfflineCAF.py > too many function letter used'
336 
337 # Check options
338 
339 str_argumentFormer = ''
340 bool_standBy = False
341 for str_argument in LSTR_wordArgument:
342  if not ( str_argument in LSTR_functionLetters or DICT_functionLetters.has_key(str_argument) or\
343  str_argument in LSTR_optionLetters or DICT_optionLetters.has_key(str_argument) ):
344  if str_argument[0] == '-':
345  print '> submitDQMOfflineCAF.py > unknown option used'
347  if not bool_standBy:
348  print '> submitDQMOfflineCAF.py > value without option used'
350  Dict_arguments[str_argumentFormer] = str_argument
351  bool_standBy = False
352  else:
353  if bool_standBy:
354  Dict_arguments[str_argumentFormer] = STR_default
355  if str_argumentFormer in LSTR_optionLetters or\
356  DICT_optionLetters.has_key(str_argumentFormer):
357  print '> submitDQMOfflineCAF.py > option "%s" w/o value' %(str_argumentFormer)
358  print ' default used'
359  print
360  bool_standBy = not ( str_argument in LSTR_functionLetters or\
361  DICT_functionLetters.has_key(str_argument) )
362  if not bool_standBy:
363  Dict_arguments[str_argument] = STR_default
364  str_argumentFormer = str_argument
365 if bool_standBy:
366  Dict_arguments[str_argumentFormer] = STR_default
367  if str_argumentFormer in LSTR_optionLetters or\
368  DICT_optionLetters.has_key(str_argumentFormer) :
369  print '> submitDQMOfflineCAF.py > option "%s" w/o value' %(str_argumentFormer)
370  print ' default used'
371  print
372 
373 # Correct arguments' dictionary
374 
375 dict_arguments = Dict_arguments
376 for str_key, str_value in dict_arguments.items():
377  if str_key in DICT_functionLetters.keys():
378  del Dict_arguments[str_key]
379  Dict_arguments[DICT_functionLetters[str_key]] = str_value
380  if str_key in DICT_optionLetters.keys():
381  del Dict_arguments[str_key]
382  Dict_arguments[DICT_optionLetters[str_key]] = str_value
383 
384 # Help (exit)
385 
386 if Dict_arguments.has_key(LSTR_functionLetters[2]):
387  Func_Usage()
388  sys.exit(0)
389 
390 # Check and assign arguments
391 
392 # run number
393 if Dict_arguments.has_key(LSTR_optionLetters[0]) and\
394  Dict_arguments[LSTR_optionLetters[0]] != STR_default :
395  Str_run = Dict_arguments[LSTR_optionLetters[0]]
396 else:
397  print '> submitDQMOfflineCAF.py > no run number given'
398  Func_Exit()
399 # use CRAB
400 if Dict_arguments.has_key(LSTR_optionLetters[1]) and\
401  Dict_arguments[LSTR_optionLetters[1]] != STR_default :
402  if Dict_arguments[LSTR_optionLetters[1]] in LSTR_true:
403  Bool_CRAB = True
404  elif Dict_arguments[LSTR_optionLetters[1]] in LSTR_false:
405  Bool_CRAB = False
406  else:
407  Func_ExitBool(1)
408 # name of CRAB server
409 if Dict_arguments.has_key(LSTR_optionLetters[2]) and\
410  Dict_arguments[LSTR_optionLetters[2]] != STR_default :
411  Str_server = Dict_arguments[LSTR_optionLetters[2]]
412 # email address to be used by CRAB server
413 if Dict_arguments.has_key(LSTR_optionLetters[3]) and\
414  Dict_arguments[LSTR_optionLetters[3]] != STR_default :
415  Str_email = Dict_arguments[LSTR_optionLetters[3]]
416 # number of jobs to create
417 if Dict_arguments.has_key(LSTR_optionLetters[4]) and\
418  Dict_arguments[LSTR_optionLetters[4]] != STR_default :
419  Int_jobs = int(Dict_arguments[LSTR_optionLetters[4]])
420 # magnetic field
421 if Dict_arguments.has_key(LSTR_optionLetters[5]) and\
422  Dict_arguments[LSTR_optionLetters[5]] != STR_default :
423  Str_magField = Dict_arguments[LSTR_optionLetters[5]]
424 if Str_magField in LSTR_auto:
425 # Bool_magFieldAuto = True
426  print '> submitDQMOfflineCAF.py > automatic determination of magnetic field disabled at the moment'
427  Func_Exit()
428 # global tag
429 if Dict_arguments.has_key(LSTR_optionLetters[6]) and\
430  Dict_arguments[LSTR_optionLetters[6]] != STR_default :
431  Str_globalTag = Dict_arguments[LSTR_optionLetters[6]]
432 # use HLT to filter events
433 if Dict_arguments.has_key(LSTR_optionLetters[7]) and\
434  Dict_arguments[LSTR_optionLetters[7]] != STR_default :
435  if Dict_arguments[LSTR_optionLetters[7]] in LSTR_true:
436  Bool_filter = True
437  elif Dict_arguments[LSTR_optionLetters[7]] in LSTR_false:
438  Bool_filter = False
439  else:
440  Func_ExitBool(7)
441 # primary dataset
442 if Dict_arguments.has_key(LSTR_optionLetters[8]) and\
443  Dict_arguments[LSTR_optionLetters[8]] != STR_default :
444  Str_dataset = Dict_arguments[LSTR_optionLetters[8]]
445 else:
446  print '> submitDQMOfflineCAF.py > no primary dataset given'
447  Func_Exit()
448 # path for job output
449 if Dict_arguments.has_key(LSTR_optionLetters[9]) and\
450  Dict_arguments[LSTR_optionLetters[9]] != STR_default :
451  Str_outpath = Dict_arguments[LSTR_optionLetters[9]]
452 # path for merged output
453 if Dict_arguments.has_key(LSTR_optionLetters[10]) and\
454  Dict_arguments[LSTR_optionLetters[10]] != STR_default :
455  Str_mergepath = Dict_arguments[LSTR_optionLetters[10]]
456 
457 # React on arguments
458 
459 # on use CRAB
460 if Bool_CRAB:
461  str_buffer = commands.getoutput('which crab')
462  if str_buffer.find('which: no crab in') >= 0:
463  str_suffixShell = 'csh'
464  if not os.getenv('SHELL')[-3:] == str_suffixShell:
465  str_suffixShell = 'sh'
466  print '> submitDQMOfflineCAF.py > CRAB environment not set properly;'
467  print ' please use'
468  print
469  print ' $ source /afs/cern.ch/cms/ccs/wm/scripts/Crab/crab.%s' %(str_suffixShell)
470  print
471  Func_Exit()
472 # on name of CRAB server
473 if not Str_server in LSTR_server:
474  print '> submitDQMOfflineCAF.py > CRAB server "%s" not available' %(Str_server)
475  Func_Exit()
476 # on number of jobs
477 if Int_jobs == 0:
478  Int_jobs = 1
479  print '> submitDQMOfflineCAF.py > number of requested jobs was 0'
480  print ' set to 1'
481 # on magnetic field
482 if Str_magField in LSTR_auto:
483 # Bool_magFieldAuto = True
484  print '> submitDQMOfflineCAF.py > automatic determination of magnetic field disabled at the moment'
485  Func_Exit()
486 elif Str_magField[-1] == 'T':
487  bool_foundField = False
488  for float_valueMagField in LFLOAT_valueMagField:
489  if str(int(float_valueMagField*10)) == Str_magField[:-1]:
490  Float_magField = float_valueMagField
491  bool_foundField = True
492  break
493  if not bool_foundField:
494  print '> submitDQMOfflineCAF.py > no magnet configuration for \'%s\' available' %(Str_magField)
495  Func_Exit()
496 else:
497  Float_magField = float(Str_magField) # FIXME protect better from wrong user input
498 # on primary dataset
499 # data tier
500 str_datatier = Str_dataset.split('/')[-1]
501 if str_datatier == 'RAW-RECO':
502  Str_datatier = LSTR_datatiers[1] # FIXME: This should be an option
503 else:
504  Str_datatier = str_datatier
505 Str_datatier = Str_dataset.split('/')[-1]
506 if not Str_datatier in LSTR_datatiers:
507  print '> submitDQMOfflineCAF.py > datatier "%s" not processable' %(Str_datatier)
508  Func_Exit()
509 # on path for job output
510 # use CASTOR
511 if Str_outpath.split('/')[1] == 'afs':
512  Bool_useCastor = False
513 elif Str_outpath.split('/')[1] != 'castor':
514  print '> submitDQMOfflineCAF.py > output path not accepted'
516 str_castorCp = 'cp'
517 if Bool_useCastor:
518  str_castorCp = 'rfcp'
519 # on path for merged output
520 if Str_mergepath.split('/')[1] != 'afs':
521  print '> submitDQMOfflineCAF.py > merge path not accepted'
523 
524 # Prepare work area
525 
526 # string identifying run (run name)
527 Str_nameRun = 'R' + Str_run.zfill(9)
528 # directories
529 Func_MkDir(Str_nameRun)
530 Str_pathRunIncludeDir = Str_pathCmsswBasePackage + '/python/' + Str_nameRun
531 Func_MkDir(Str_pathRunIncludeDir)
532 str_nameInputFilesFile = Str_nameRun + '/' + Str_nameRun + '.txt'
533 str_nameRunIncludeDir = STR_nameCmsswPackage.replace('/','.') + '.' + Str_nameRun
534 
535 # Retrieving information from the web
536 
537 # input files
538 int_nInputFiles = 0
539 file_inputFilesCff = file(str_nameInputFilesFile, 'w')
540 # DBS query for list of input files
541 str_dbsParams = urllib.urlencode({'dbsInst':'cms_dbs_prod_global', 'blockName':'*', 'dataset':Str_dataset, 'userMode':'user', 'run':Str_run, 'what':'py'})
542 file_dbsOutput = urllib.urlopen("https://cmsweb.cern.ch/dbs_discovery/getLFN_txt", str_dbsParams)
543 for str_iLine in file_dbsOutput.readlines():
544  lstr_wordsLine = str_iLine.split("/")
545  if len(lstr_wordsLine) >= 5:
546  if lstr_wordsLine[1] == 'store' and\
547  lstr_wordsLine[2] == 'data' and\
548  Str_dataset.find(lstr_wordsLine[3]) >= 0 and\
549  Str_dataset.find(lstr_wordsLine[4]) >= 0 and\
550  lstr_wordsLine[5] == str_datatier :
551  int_nInputFiles += 1
552  file_inputFilesCff.write(str_iLine)
553 if int_nInputFiles == 0:
554  print '> submitDQMOfflineCAF.py > no input files found in DBS for run %s in dataset %s' %(Str_run,Str_dataset)
555  Func_Exit()
556 file_inputFilesCff.close()
557 print '> submitDQMOfflineCAF.py > input files for run %s: %i' %(Str_run,int_nInputFiles)
558 if int_nInputFiles < Int_jobs:
559  Int_jobs = int_nInputFiles
560  print ' number of requested jobs reduced accordingly'
561 Int_jobsNew = Int_jobs
562 print
563 
564 # magnetic field
565 if Bool_magFieldAuto:
566  # extract time stamps of the run
567  str_cmsmonParams = urllib.urlencode({'RUN':Str_run})
568  file_cmsmonOutput = urllib.urlopen("http://cmsmon.cern.ch/cmsdb/servlet/RunSummary", str_cmsmonParams)
569  str_timeBegin = ''
570  str_timeEnd = ''
571  for str_cmsmonOutput in file_cmsmonOutput.readlines():
572  if str_cmsmonOutput.find('HREF=Component?RUN=' + Str_run + '&NAME=TRACKER') >= 0:
573  lstr_timeQuery = str_cmsmonOutput.split('HREF=Component?RUN=' + Str_run + '&NAME=TRACKER&')[1].split('>TRACKER')[0].split('&')
574  for str_timeQuery in lstr_timeQuery:
575  str_nameStamp = str_timeQuery.split('=')[0]
576  lstr_timeDate = str_timeQuery.split('=')[1].split('_')[0].split('.')
577  lstr_timeTime = str_timeQuery.split('=')[1].split('_')[1].split(':')
578  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]))
579  dt_stampNew = dt_stampOld - TD_shiftUTC
580  str_timeStamp = str(dt_stampNew).replace('-','.')
581  if str_nameStamp == 'TIME_BEGIN':
582  str_timeBegin = str_timeStamp
583  elif str_nameStamp == 'TIME_END':
584  str_timeEnd = str_timeStamp
585  # get magnetic field itself
586  str_cmsmonParams = urllib.urlencode({'TIME_BEGIN':str_timeBegin, 'TIME_END':str_timeEnd})
587  file_cmsmonOutput = urllib.urlopen("http://cmsmon.cern.ch/cmsdb/servlet/MagnetHistory", str_cmsmonParams)
588  bool_foundField = False
589  for str_cmsmonOutput in file_cmsmonOutput.readlines():
590  if str_cmsmonOutput.find('BFIELD, Tesla') >= 0:
591  Float_magField = float(str_cmsmonOutput.split('</A>')[0].split('>')[-1])
592  bool_foundField = True
593  break
594  if not bool_foundField:
595  print '> submitDQMOfflineCAF.py > could not extract magnetic field'
596  print ' please provide value'
597  Func_Exit()
598 # determine corresponding configuration file to be included
599 float_magField = Func_MagConfig(Float_magField)
600 Str_magField = str(int(float_magField*10)) + 'T'
601 print '> submitDQMOfflineCAF.py > (average) magnetic field in run %s: %s T' %(Str_run,Float_magField)
602 print ' using %s T for configuration' %(float_magField)
603 print
604 
605 # Create scripts
606 
607 int_nLinesRead = 0
608 file_inputFilesCff = file(str_nameInputFilesFile)
609 lstr_linesInput = file_inputFilesCff.readlines()
610 file_inputFilesCff.close()
611 
612 # create harvesting config file and job script
613 str_sedCommand = 'sed '
614 str_sedCommand += '-e \"s#xMAG_FIELDx#' + Str_magField + '#g\" '
615 str_sedCommand += '-e \"s#xGLOBAL_TAGx#' + Str_globalTag + '#g\" '
616 str_sedCommand += '-e \"s#xINCLUDE_DIRECTORYx#' + str_nameRunIncludeDir + '#g\" '
617 str_sedCommand += '-e \"s#xMERGE_PATHx#' + Str_mergepath + '#g\" '
618 str_sedCommand += Str_pathCmsswBasePackage + '/test/SiStripCAFHarvest_template_cfg.py > ' + Str_nameRun + '/SiStripCAFHarvest_cfg.py'
619 os.system(str_sedCommand)
620 str_sedCommand = 'sed '
621 str_sedCommand += '-e \"s#xCMSSW_BASEx#' + Str_pathCmsswBase + '#g\" '
622 str_sedCommand += '-e \"s#xRUN_NAMEx#' + Str_nameRun + '#g\" '
623 str_sedCommand += '-e \"s#xMERGE_PATHx#' + Str_mergepath + '#g\" '
624 str_sedCommand += '-e \"s#xCURRENT_DIRx#' + Str_pathCurrentDir + '#g\" '
625 str_sedCommand += '-e \"s#xDATA_TIERx#' + Str_datatier + '#g\" '
626 str_sedCommand += '-e \"s#xCMSSW_VERSIONx#' + Str_nameCmsswRel + '#g\" '
627 str_sedCommand += Str_pathCmsswBasePackage + '/scripts/SiStripDQMCAFHarvest_template.job > ' + Str_nameRun + '/SiStripCAFHarvest.job'
628 os.system(str_sedCommand)
629 # create included CAF input files list (mainly for compilation)
630 Str_pathInputFilesCAFCff = Str_pathRunIncludeDir + '/inputFilesCAF_cff.py'
631 file_inputFilesCAFCff = file(Str_pathInputFilesCAFCff, 'w')
632 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')
633 for int_iJob in range(1,Int_jobs+1):
634  str_lineInput = Str_outpath + '/SiStripDQMOfflineGlobalRunCAF-' + Str_nameRun + '_' + str(int_iJob) + '.root'
635  if Bool_useCastor:
636  str_lineInput = 'rfio:' + str_lineInput
637  str_lineInput = ' \'' + str_lineInput + '\''
638  if int_iJob == Int_jobs:
639  str_lineInput += '\n'
640  file_inputFilesCAFCff.write(str_lineInput)
641  break
642  str_lineInput += ',\n'
643  file_inputFilesCAFCff.write(str_lineInput)
644 file_inputFilesCAFCff.write(' )\n)\n')
645 file_inputFilesCAFCff.close()
646 
647 str_sedCommandCommon = 'sed '
648 if Bool_filter:
649  str_sedCommandCommon += '-e \"s#xHLT_FILTERx# #g\" '
650 else:
651  str_sedCommandCommon += '-e \"s#xHLT_FILTERx#\# #g\" '
652 if Str_datatier == 'RECO':
653  str_sedCommandCommon += '-e \"s#xRECO_FROM_RAWx#\# #g\" '
654  str_sedCommandCommon += '-e \"s#xDQM_FROM_RAWx#\# #g\" '
655 else:
656  str_sedCommandCommon += '-e \"s#xRECO_FROM_RAWx# #g\" '
657  str_sedCommandCommon += '-e \"s#xDQM_FROM_RAWx# #g\" '
658 str_sedCommandCommon += '-e \"s#xMAG_FIELDx#' + Str_magField + '#g\" '
659 str_sedCommandCommon += '-e \"s#xGLOBAL_TAGx#' + Str_globalTag + '#g\" '
660 str_sedCommandCommon += '-e \"s#xRUN_NAMEx#' + Str_nameRun + '#g\" '
661 
662 if Bool_CRAB:
663  os.chdir(Str_nameRun)
664  str_outputDir = '.'
665  # create main configuration file
666  str_sedCommand = str_sedCommandCommon
667  str_sedCommand += '-e \"s#xINCLUDE_DIRECTORYx#' + str_nameRunIncludeDir + '#g\" '
668  str_sedCommand += '-e \"s#xOUTPUT_DIRECTORYx#' + str_outputDir + '#g\" '
669  str_sedCommand += Str_pathCmsswBasePackage + '/test/SiStripDQMOfflineGlobalRunCAF_template_cfg.py > SiStripDQMOfflineGlobalRunCAF_cfg.py'
670  os.system(str_sedCommand)
671  # create included input files list
672  str_pathInputFilesJobCff = Str_pathRunIncludeDir + '/inputFiles_cff.py'
673  file_inputFilesJobCff = file(str_pathInputFilesJobCff, 'w')
674  file_inputFilesJobCff.write('import FWCore.ParameterSet.Config as cms\n\nsource = cms.Source ("PoolSource",\n fileNames = cms.untracked.vstring (\n')
675  nLines = 0
676  for str_linesInput in lstr_linesInput:
677  nLines += 1
678  str_correctedLine1 = str_linesInput.replace(') );',',')
679  str_correctedLine = str_correctedLine1.replace(' ] );',',')
680  if nLines == len(lstr_linesInput):
681  str_actualLine = str_correctedLine.replace(',','\n )\n)\n')
682  elif nLines%255 == 0: # FIXME add this check also to LSF
683  str_actualLine = str_correctedLine.replace(',','\n )\n)\nsource.fileNames.extend(\n (')
684  else:
685  str_actualLine = str_correctedLine
686  file_inputFilesJobCff.write(str_actualLine)
687  file_inputFilesJobCff.close()
688  # create CRAB configuration file
689  lstr_outpath = Str_outpath.split('/', 3)
690  str_outpath = lstr_outpath[0] + '/' + lstr_outpath[1] + '/' + lstr_outpath[2]
691  str_sedCommand = 'sed '
692  str_sedCommand += '-e \"s#xSERVER_NAMEx#' + Str_server + '#g\" '
693  str_sedCommand += '-e \"s#xDATASETPATHx#' + Str_dataset + '#g\" '
694  str_sedCommand += '-e \"s#xRUNSELECTIONx#' + Str_run + '#g\" '
695  str_sedCommand += '-e \"s#xNUMBER_OF_JOBSx#' + str(Int_jobs) + '#g\" '
696  str_sedCommand += '-e \"s#xEMAILx#' + Str_email + '#g\" '
697  str_sedCommand += '-e \"s#xRUN_NAMEx#' + Str_nameRun + '#g\" '
698  str_sedCommand += '-e \"s#xSTORAGE_PATHx#' + str_outpath + '#g\" '
699  str_sedCommand += '-e \"s#xLFNx#' + lstr_outpath[3] + '#g\" '
700  str_sedCommand += '-e \"s#xCOPY_DATAx#' + str(int(Bool_useCastor)) + '#g\" '
701  str_sedCommand += Str_pathCmsswBasePackage + '/test/SiStripDQMOfflineCAF_template.crab > crab.cfg'
702  os.system(str_sedCommand)
703  os.chdir(Str_pathCurrentDir)
704 else:
705  # FIXME: following calculation has to be reviewed
706  int_nInputFilesJob = int(int_nInputFiles/Int_jobs) + 1
707  if int_nInputFiles%Int_jobs == 0:
708  int_nInputFilesJob -= 1
709  if int_nInputFiles == int_nInputFilesJob*(Int_jobs-1) and Int_jobs > 1:
710  Int_jobs -= 1
711  # loop over single jobs
712  for int_iJob in range(1,Int_jobs+1):
713  str_nameJob = Str_nameRun + '_' + str(int_iJob).zfill(4)
714  # prepare job dir
715  str_nameJobDir = Str_nameRun + "/" + str_nameJob
716  str_outputDir = '/tmp/' + os.getenv('USER') + '/' + str_nameJobDir
717  str_pathJobIncludeDir = Str_pathRunIncludeDir + '/' + str_nameJob
718  str_nameJobIncludeDir = STR_nameCmsswPackage.replace('/','.') + '.' + str_nameJobDir.replace('/','.')
719  os.mkdir(str_nameJobDir)
720  os.chdir(str_nameJobDir)
721  # create job script
722  str_sedCommand = 'sed '
723  str_sedCommand += '-e \"s#xCMSSW_BASEx#' + Str_pathCmsswBase + '#g\" '
724  str_sedCommand += '-e \"s#xRUN_NAMEx#' + Str_nameRun + '#g\" '
725  str_sedCommand += '-e \"s#xJOB_NAMEx#' + str_nameJob + '#g\" '
726  str_sedCommand += '-e \"s#xCURRENT_DIRx#' + Str_pathCurrentDir + '#g\" '
727  str_sedCommand += '-e \"s#xCOPYx#' + str_castorCp + '#g\" '
728  str_sedCommand += '-e \"s#xOUTPUT_DIRx#' + Str_outpath + '#g\" '
729  str_sedCommand += Str_pathCmsswBasePackage + '/scripts/SiStripDQMOfflineCAF_template.job > SiStripDQMOfflineCAF.job'
730  os.system(str_sedCommand)
731  # create main configuration file
732  str_sedCommand = str_sedCommandCommon
733  str_sedCommand += '-e \"s#xINCLUDE_DIRECTORYx#' + str_nameJobIncludeDir + '#g\" '
734  str_sedCommand += '-e \"s#xOUTPUT_DIRECTORYx#' + str_outputDir + '#g\" '
735  str_sedCommand += Str_pathCmsswBasePackage + '/test/SiStripDQMOfflineGlobalRunCAF_template_cfg.py > SiStripDQMOfflineGlobalRunCAF_cfg.py'
736  os.system(str_sedCommand)
737  # prepare job include dir
738  os.mkdir(str_pathJobIncludeDir)
739  # create included input files list
740  str_pathInputFilesJobCff = str_pathJobIncludeDir + '/inputFiles_cff.py'
741  file_inputFilesJobCff = file(str_pathInputFilesJobCff, 'w')
742  file_inputFilesJobCff.write('import FWCore.ParameterSet.Config as cms\n\nsource = cms.Source ("PoolSource",\n fileNames = cms.untracked.vstring (\n')
743  for n_iActualLine in range(int_nLinesRead, min(int_nLinesRead+int_nInputFilesJob, int_nInputFiles)):
744  str_linesInput = lstr_linesInput[n_iActualLine].replace(') );',',')
745  # fix commata and end of line
746  str_actualLine = str_linesInput
747  if (n_iActualLine+1)%int_nInputFilesJob == 0 or int_nLinesRead == int_nInputFiles-1:
748  str_actualLine = str_linesInput.split(',')[0] + '\n'
749  file_inputFilesJobCff.write(str_actualLine)
750  int_nLinesRead += 1
751  file_inputFilesJobCff.write(' )\n)\n')
752  file_inputFilesJobCff.close()
753  # finalize job creation
754  os.chdir(Str_pathCurrentDir)
755  # FIXME: This protection is currently needed. Review calculations again!
756  if int_nLinesRead >= int_nInputFiles:
757  Int_jobsNew = int_iJob
758  break
759 
760 # Compile
761 
762 os.chdir(Str_pathRunIncludeDir+'/..')
763 os.system('scramv1 b python')
764 os.chdir(Str_pathCurrentDir)
765 print
766 
767 # Create CRAB
768 
769 if Bool_CRAB:
770  os.chdir(Str_nameRun)
771  os.system('crab -create')
772  print
773  # extract number of really created jobs
774  bool_found = False
775  file_logCRAB = file('crab'+Str_nameRun+'/log/crab.log')
776  for str_iLine in file_logCRAB.readlines():
777  if str_iLine.startswith('Total of ') and str_iLine.endswith(' jobs created.\n'):
778  bool_found = True
779  Int_jobsNew = int(str_iLine.split()[2])
780  break
781  file_logCRAB.close()
782  os.chdir(Str_pathCurrentDir)
783  if not bool_found:
784  print '> submitDQMOfflineCAF.py > could not extract number of jobs created by CRAB; check'
785  print ' %s' %(Str_pathInputFilesCAFCff)
786  print ' and modify manually, if necessary'
787  print
788 
789 # recreate included CAF input files list according to number of created jobs, if necessary
790 
791 print '> submitDQMOfflineCAF.py > number of created jobs: %i' %(Int_jobsNew)
792 print
793 if Int_jobsNew != Int_jobs:
794  file_inputFilesCAFCff = file(Str_pathInputFilesCAFCff, 'w')
795  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')
796  for int_iJob in range(1,Int_jobsNew+1): # FIXME use number of CRAB jobs created
797  str_lineInput = Str_outpath + '/SiStripDQMOfflineGlobalRunCAF-' + Str_nameRun + '_' + str(int_iJob) + '.root'
798  if Bool_useCastor:
799  str_lineInput = 'rfio:' + str_lineInput
800  str_lineInput = ' \'' + str_lineInput + '\''
801  if int_iJob == Int_jobsNew:
802  str_lineInput += '\n'
803  file_inputFilesCAFCff.write(str_lineInput)
804  break
805  str_lineInput += ',\n'
806  file_inputFilesCAFCff.write(str_lineInput)
807  file_inputFilesCAFCff.write(' )\n)\n')
808  file_inputFilesCAFCff.close()
809 
810 # Submit jobs
811 
812 if Dict_arguments.has_key(LSTR_functionLetters[0]):
813  os.chdir(Str_nameRun)
814  if Bool_CRAB:
815  str_crabCommand = 'crab -submit -c crab' + Str_nameRun
816  print '> submitDQMOfflineCAF.py >'
817  print ' %s : %s' %(os.getcwd(),str_crabCommand)
818  os.system(str_crabCommand)
819  print
820  time.sleep(5)
821  os.system('crab -status -c crab' + Str_nameRun)
822  else:
823  for int_iJob in range(Int_jobs):
824  str_nameJobDir = Str_nameRun + '_' + str(int_iJob).zfill(4)
825  os.chdir(str_nameJobDir)
826  os.chmod('SiStripDQMOfflineCAF.job',OCT_rwx_r_r)
827  str_batchCommand = 'bsub -q cmscaf SiStripDQMOfflineCAF.job'
828  print '> submitDQMOfflineCAF.py >'
829  print ' %s : %s' %(os.getcwd(),str_batchCommand)
830  os.system(str_batchCommand)
831  print
832  os.chdir('../')
833  time.sleep(5)
834  os.system('bjobs -q cmscaf')
835  os.chmod('SiStripCAFHarvest.job',OCT_rwx_r_r)
836  os.chdir(Str_pathCurrentDir)
837 
838 # Send reminder email to submitter (not needed for CRAB)
839 
840 if Dict_arguments.has_key(LSTR_functionLetters[0]) and not Bool_CRAB:
841  str_mailFrom = os.getenv('USER') + STR_mailServer
842  str_mailTo = [str_mailFrom,
843  'volker.adler@cern.ch',
844  'suchandra.dutta@cern.ch',
845  'domenico.giordano@cern.ch',
846  'vitaliano.ciulli@cern.ch']
847  str_mailSubject = 'Your SiStrip offline DQM shift on ' + str(datetime.date.today()) + ', run ' + Str_run
848  str_mailText = STR_mailTextOpener + Str_run + STR_mailText
849  str_mailMessage = """From: %s
850 To: %s
851 Subject: %s
852 
853 %s
854 """ % (str_mailFrom, ", ".join(str_mailTo), str_mailSubject, str_mailText)
855  server = smtplib.SMTP(STR_mailSmtp)
856  server.sendmail(str_mailFrom, str_mailTo, str_mailMessage)
857  server.quit()
def Func_Usage
Function Func_Usage()
def Func_MkDir
Function Func_MkDir()
def Func_MagConfig
Function Func_MagConfig(float_magFieldMeasured)
def Func_Exit
Function Func_Exit()
T min(T a, T b)
Definition: MathUtil.h:58
def Func_ExitBool
Function Func_ExitBool()
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def Func_ExitUsage
Function Func_ExitUsage()
double split
Definition: MVATrainer.cc:139