CMS 3D CMS Logo

SiStripDAQPopCon.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 '''Script that runs a single O2O for SiStrip DAQ.
3 @author: Huilin Qu
4 '''
5 
6 import os
7 import atexit
8 import logging
9 import socket
10 import argparse
11 import subprocess
12 from functools import partial
13 import CondTools.SiStrip.o2o_helper as helper
14 from CondTools.SiStrip.o2o_db_cfgmap import DbManagerDAQ
15 from CondTools.SiStrip.o2o_db_gain import DbManagerGain
16 
17 jobDirVar = 'JOBDIR'
18 cfg_template = 'CondTools/SiStrip/python/SiStripO2O_cfg_template.py'
19 
20 def runjob(args):
21  if args.debug:
22  logging.debug(str(args))
23 
24  # read cfglines from input cfgfile
25  with open(args.cfgfile) as cfgfile:
26  cfglines = cfgfile.read()
27  logging.debug(cfglines)
28 
29  # create config from template
30  job_file = 'cfg_{type}_{run}.py'.format(type=args.analyzer, run=args.since)
31  output_db = '{type}_{run}.db'.format(type=args.analyzer, run=args.since)
32  if os.path.exists(output_db):
33  logging.info('Output sqlite file %s already exists! Deleting...' % output_db)
34  os.remove(output_db)
35  hashmap_db = 'hashmap_{type}_{run}.db'.format(type=args.analyzer, run=args.since)
36  if os.path.exists(hashmap_db):
37  logging.info('Hashmap sqlite file %s already exists! Deleting...' % hashmap_db)
38  os.remove(hashmap_db)
39  replace_dict = {'_CFGLINES_' : cfglines.replace('\\', ''),
40  '_ANALYZER_' : args.analyzer,
41  '_USEANALYSIS_':'False',
42  '_CONDDB_' : args.condDbRead,
43  '_DBFILE_' : 'sqlite:///%s' % output_db,
44  '_TARGETTAG_': args.inputTag,
45  '_RUNNUMBER_': args.since,
46  '_HASHMAPDB_': args.hashmapDb,
47  '_MAPDBFILE_': 'sqlite:///%s' % hashmap_db,
48  '_SKIPPED_' : '',
49  }
50  if args.analyzer == 'SiStripO2OApvGain':
51  # special treatment for G1 O2O
52  skipped = ''
53  if args.skiplistFile:
54  with open(args.skiplistFile) as skipfile:
55  skipped = skipfile.read()
56  else:
57  logging.warning('Skipped module list not provided! No module will be skipped...')
58  replace_dict['_USEANALYSIS_'] = 'True'
59  replace_dict['_SKIPPED_'] = skipped
60  replace_dict['_HASHMAPDB_'] = ''
61  replace_dict['_MAPDBFILE_'] = ''
62 
63  # find template cfg file
64  for basedir in os.environ['CMSSW_SEARCH_PATH'].split(':'):
65  templatefile = os.path.join(basedir, cfg_template)
66  if os.path.exists(templatefile):
67  logging.info('Use template config file %s' % templatefile)
68  break
69  config = helper.insert_to_file(templatefile, job_file, replace_dict)
70  logging.info('Start running O2O...')
71  logging.debug(' ... config:\n%s\n' % config)
72 
73  # run cmssw job: raise error if failed
74  command = 'cmsRun %s' % job_file
75  pipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
76  atexit.register(partial(helper.kill_subproc_noexcept, pipe))
77  out = pipe.communicate()[0]
78  logging.info('\n%s\n' % out)
79  logging.info('@@@CMSSW job return code = %d@@@' % pipe.returncode)
80  if pipe.returncode != 0:
81  raise RuntimeError('O2O job FAILED!')
82 
83  # upload: raise error if failed
84  if args.no_upload:
85  logging.info('Will not run uploading as requested!')
86  return
87  if args.use_uploader:
88  f = helper.upload_payload
89  else:
90  f = helper.copy_payload
91  f(dbFile=output_db, inputTag=args.inputTag, destTags=args.destTags, destDb=args.destDb, since=args.since,
92  userText='{type}, run: {run}'.format(type=args.analyzer, run=args.since))
93 
94  # post O2O tasks: bookkeeping for fast O2O or G1 O2O
95  if args.analyzer == 'SiStripO2OApvGain':
96  logging.info('Writting bookkeeping info to database.')
97  dbmgr = DbManagerGain(args.bookkeeping_db)
98  dbmgr.update_gain_logs(args.since, job_file)
99  else:
100  logging.info('Updating config-to-payload hash map to database.')
101  dbmgr = DbManagerDAQ(args.bookkeeping_db)
102  dbmgr.update_hashmap(hashmap_db)
103 
104  # clean up
105  try:
106  os.remove(output_db)
107  os.remove(output_db.replace('.db', '.txt'))
108  os.remove(hashmap_db) # may not exist
109  except OSError:
110  pass
111 
112 def main():
113  parser = argparse.ArgumentParser(description='Run a single O2O job for SiStrip DAQ and upload the payloads to condition database.')
114  parser.add_argument('analyzer', metavar='ANALYZER', help='Which EDAnalyzer to use to create the payload.')
115  parser.add_argument('since', metavar='SINCE', type=str, help='Run number.')
116  parser.add_argument('cfgfile', metavar='CFGLINES', help='File containing configuration lines.')
117  parser.add_argument('--destTags', required=True, help='Destination tag name(s) for upload. Use comma to separate multiple values.')
118  parser.add_argument('--destDb', required=True, help='Destination DB to upload.')
119  parser.add_argument('--inputTag', required=True, help='Tag name to be used in the sqlite file.')
120  parser.add_argument('--condDbRead', default='oracle://cms_orcon_prod/CMS_CONDITIONS', help='Connection string for the DB from which the fast O2O retrives payloads.')
121  parser.add_argument('--hashmapDb', default='', help='DB to read and write config-to-payload hash (for fast O2O).')
122  parser.add_argument('--skiplistFile', default='', help='File containing the devices to be skipped in G1 O2O.')
123 
124  parser.add_argument('--no-upload', action="store_true", default=False, help='Do not upload payload. Default: %(default)s.')
125  parser.add_argument('--use-uploader', action="store_true", default=False, help='Use conditionUploader instead of conddb copy. Default: %(default)s.')
126  parser.add_argument('--bookkeeping-db', default='prod', choices=['prod', 'dev', 'private'], help='Bookkeeping database for fast O2O and G1 O2O. Default: %(default)s.')
127  parser.add_argument('--debug', action="store_true", default=False, help='Switch on debug mode. Default: %(default)s.')
128  args = parser.parse_args()
129 
130  loglevel = logging.INFO
131  if args.debug:
132  loglevel = logging.DEBUG
133  if args.bookkeeping_db == 'prod':
134  args.bookkeeping_db = 'dev'
135  logging.basicConfig(level=loglevel, format='[%(asctime)s] %(levelname)s: %(message)s')
136 
137  if not args.since.isdigit():
138  raise RuntimeError('Since (=%s) must be a valid run number!'%(args.since))
139 
140  args.destTags = args.destTags.strip().split(',')
141 
142  logging.info('Running O2O %s on machine [%s]' % (args.analyzer, socket.gethostname()))
143 
144  try:
145  jobdirbase = os.environ[jobDirVar]
146  except KeyError:
147  jobdirbase = '/tmp'
148  logging.warning('%s not set in env, will use %s' % (jobDirVar, jobdirbase))
149 
150  # change filepaths in args to abs path
151  args.cfgfile = os.path.abspath(args.cfgfile)
152  if args.skiplistFile:
153  args.skiplistFile = os.path.abspath(args.skiplistFile)
154 
155  # change to O2O working directory
156  jobdir = os.path.join(jobdirbase, args.since, args.analyzer)
157  if not os.path.exists(jobdir):
158  os.makedirs(jobdir)
159  os.chdir(jobdir)
160  logging.info('Running O2O in %s' % jobdir)
161 
162  # run job and upload
163  runjob(args)
164 
165  logging.info('Done!')
166 
167 
168 
169 if __name__ == '__main__':
170  main()
double f[11][100]
Definition: main.py:1
double split
Definition: MVATrainer.cc:139