20 import Alignment.MillePedeAlignmentAlgorithm.mpslib.Mpslibclass
as mpslib
21 import Alignment.MillePedeAlignmentAlgorithm.mpslib.tools
as mps_tools
22 from Alignment.MillePedeAlignmentAlgorithm.alignmentsetup.helper
import checked_out_MPS
23 from functools
import reduce
27 """Extracts different weight configurations from `config`. 30 - `config`: ConfigParser object containing the alignment configuration 33 weight_dict = collections.OrderedDict()
37 for section
in config.sections():
38 if 'general' in section:
40 elif section ==
"weights":
41 for option
in config.options(section):
42 common_weights[option] = [x.strip()
for x
in 43 config.get(section, option).
split(
",")]
44 elif section.startswith(
"dataset:"):
46 if config.has_option(section,
'weight'):
47 weight_dict[name] = [x.strip()
for x
in 48 config.get(section,
"weight").
split(
",")]
50 weight_dict[name] = [
'1.0']
52 weights_list = [[(name, weight)
for weight
in weight_dict[name]]
53 for name
in weight_dict]
55 common_weights_list = [[(name, weight)
for weight
in common_weights[name]]
56 for name
in common_weights]
57 common_weights_dicts = []
58 for item
in itertools.product(*common_weights_list):
60 for name,weight
in item:
62 common_weights_dicts.append(d)
65 for weight_conf
in itertools.product(*weights_list):
66 if len(common_weights) > 0:
67 for common_weight
in common_weights_dicts:
68 configs.append([(dataset[0],
69 reduce(
lambda x,y: x.replace(y, common_weight[y]),
70 common_weight, dataset[1]))
71 for dataset
in weight_conf])
73 configs.append(weight_conf)
80 Create sqlite file with single-IOV tags and use it to override the GT. If 81 the GT is already customized by the user, the customization has higher 82 priority. Returns a snippet to be appended to the configuration file 85 - `cms_process`: cms.Process object 86 - `run_number`: run from which to extract the alignment payloads 89 run_number =
int(run_number)
90 if not run_number > 0:
91 print "'FirstRunForStartGeometry' must be positive, but is", run_number
94 input_db_name = os.path.abspath(
"alignment_input.db")
95 tags = mps_tools.create_single_iov_db(
97 run_number, input_db_name)
100 for record,tag
in tags.iteritems():
102 result += (
"\nimport " 103 "Alignment.MillePedeAlignmentAlgorithm.alignmentsetup." 104 "SetCondition as tagwriter\n")
105 result += (
"\ntagwriter.setCondition(process,\n" 106 " connect = \""+tag[
"connect"]+
"\",\n" 107 " record = \""+record+
"\",\n" 108 " tag = \""+tag[
"tag"]+
"\")\n")
115 Check consistency of input alignment payloads and IOV definition. 116 Returns a dictionary with the information needed to override possibly 117 problematic input taken from the global tag. 120 - `cms_process`: cms.Process object containing the CMSSW configuration 121 - `first_run`: first run for start geometry 124 print "Checking consistency of IOV definition..." 125 iovs = mps_tools.make_unique_runranges(cms_process.AlignmentProducer)
127 if first_run != iovs[0]:
128 print "Value of 'FirstRunForStartGeometry' has to match first defined",
130 print first_run,
"!=", iovs[0]
135 "TrackerAlignmentRcd":
None,
136 "TrackerSurfaceDeformationRcd":
None,
137 "TrackerAlignmentErrorExtendedRcd":
None,
140 for condition
in cms_process.GlobalTag.toGet.value():
141 if condition.record.value()
in inputs:
142 inputs[condition.record.value()] = {
143 "tag": condition.tag.value(),
145 if not condition.hasParameter(
"connect")
146 else condition.connect.value())
149 inputs_from_gt = [record
for record
in inputs
if inputs[record]
is None]
150 inputs.update(mps_tools.get_tags(cms_process.GlobalTag.globaltag.value(),
153 for inp
in inputs.itervalues():
154 inp[
"iovs"] = mps_tools.get_iovs(inp[
"connect"], inp[
"tag"])
157 problematic_gt_inputs = {}
158 input_indices = {key: len(value[
"iovs"]) -1
159 for key,value
in inputs.iteritems()}
160 for iov
in reversed(iovs):
162 if inp
in problematic_gt_inputs:
continue 163 if input_indices[inp] < 0:
164 print "First output IOV boundary at run", iov,
165 print "is before the first input IOV boundary at",
166 print inputs[inp][
"iovs"][0],
"for '"+inp+
"'." 167 print "Please check your run range selection." 169 input_iov = inputs[inp][
"iovs"][input_indices[inp]]
171 if inp
in inputs_from_gt:
172 problematic_gt_inputs[inp] = inputs[inp]
173 print "Found problematic input taken from global tag." 174 print "Input IOV boundary at run",input_iov,
175 print "for '"+inp+
"' is within output IOV starting with",
176 print "run",
str(iov)+
"." 177 print "Deriving an alignment with coarse IOV granularity",
178 print "starting from finer granularity leads to wrong",
180 print "A single IOV input using the IOV of",
181 print "'FirstRunForStartGeometry' ("+
str(first_run)+
") is",
182 print "automatically created and used." 184 print "Found input IOV boundary at run",input_iov,
185 print "for '"+inp+
"' which is within output IOV starting with",
186 print "run",
str(iov)+
"." 187 print "Deriving an alignment with coarse IOV granularity",
188 print "starting from finer granularity leads to wrong results." 189 print "Please check your run range selection." 191 elif iov == input_iov:
192 input_indices[inp] -= 1
195 input_indices = {key: len(value[
"iovs"]) -1
196 for key,value
in inputs.iteritems()
197 if (key !=
"TrackerAlignmentRcd")
198 and (inp
not in problematic_gt_inputs)}
199 for iov
in reversed(inputs[
"TrackerAlignmentRcd"][
"iovs"]):
200 for inp
in input_indices:
201 input_iov = inputs[inp][
"iovs"][input_indices[inp]]
203 print "Found input IOV boundary at run",input_iov,
204 print "for '"+inp+
"' which is within 'TrackerAlignmentRcd'",
205 print "IOV starting with run",
str(iov)+
"." 206 print "Deriving an alignment with inconsistent IOV boundaries",
207 print "leads to wrong results." 208 print "Please check your input IOVs." 210 elif iov == input_iov:
211 input_indices[inp] -= 1
213 print "IOV consistency check successful." 216 return problematic_gt_inputs
222 helpEpilog =
'''Builds the config-templates from a universal config-template for each 223 dataset specified in .ini-file that is passed to this script. 224 Then calls mps_setup.pl for all datasets.''' 226 description=
'Setup the alignment as configured in the alignment_config file.',
229 parser.add_argument(
'-v',
'--verbose', action=
'store_true',
230 help=
'display detailed output of mps_setup')
232 parser.add_argument(
'-w',
'--weight', action=
'store_true',
233 help=
'create an additional mergejob with (possibly new) weights from .ini-config')
235 parser.add_argument(
'alignmentConfig', action=
'store',
236 help=
'name of the .ini config file that specifies the datasets to be used')
238 args = parser.parse_args()
239 aligmentConfig = args.alignmentConfig
242 config = ConfigParser.ConfigParser()
243 config.optionxform = str
244 config.read(aligmentConfig)
252 mpsTemplates = os.path.join(
"src",
"Alignment",
"MillePedeAlignmentAlgorithm",
"templates")
254 mpsTemplates = os.path.join(os.environ[
"CMSSW_BASE"], mpsTemplates)
256 mpsTemplates = os.path.join(os.environ[
"CMSSW_RELEASE_BASE"], mpsTemplates)
257 milleScript = os.path.join(mpsTemplates,
"mps_runMille_template.sh")
258 pedeScript = os.path.join(mpsTemplates,
"mps_runPede_rfcp_template.sh")
261 currentDir = os.getcwd()
263 match = re.search(re.compile(
'mpproduction\/mp(.+?)$', re.M|re.I),currentDir)
265 mpsdirname =
'mp'+match.group(1)
267 print "Current location does not seem to be a MillePede campaign directory:",
272 mssDir =
'/store/caf/user/'+os.environ[
'USER']+
'/MPproduction/'+mpsdirname
275 eos =
'/afs/cern.ch/project/eos/installation/cms/bin/eos.select' 276 os.system(eos+
' mkdir -p '+mssDir)
285 for var
in [
"classInf",
"pedeMem",
"jobname",
"FirstRunForStartGeometry"]:
287 generalOptions[var] = config.get(
'general',var)
288 except ConfigParser.NoOptionError:
289 print "No", var,
"found in [general] section. Please check ini-file." 293 generalOptions[
'datasetdir'] =
'' 294 if config.has_option(
'general',
'datasetdir'):
295 generalOptions[
'datasetdir'] = config.get(
'general',
'datasetdir')
297 os.environ[
"datasetdir"] = generalOptions[
'datasetdir']
299 print "No datasetdir given in [general] section.",
300 print "Be sure to give a full path in inputFileList." 303 for var
in [
'globaltag',
'configTemplate',
'json']:
305 generalOptions[var] = config.get(
'general',var)
306 except ConfigParser.NoOptionError:
307 print 'No default', var,
'given in [general] section.' 311 pedesettings = ([x.strip()
for x
in config.get(
"general",
"pedesettings").
split(
",")]
312 if config.has_option(
"general",
"pedesettings")
else [
None])
322 if not os.path.isdir(
"jobData"):
323 print "No jobData-folder found. Properly set up the alignment before using the -w option." 325 if not os.path.exists(
"mps.db"):
326 print "No mps.db found. Properly set up the alignment before using the -w option." 331 configTemplate = config.get(
'general',
'configTemplate')
332 except ConfigParser.NoOptionError:
333 print 'No default configTemplate given in [general] section.' 334 print 'When using -w, a default configTemplate is needed to build a merge-config.' 339 globalTag = config.get(
'general',
'globaltag')
340 except ConfigParser.NoOptionError:
341 print "No default 'globaltag' given in [general] section." 342 print "When using -w, a default configTemplate is needed to build a merge-config." 346 first_run = config.get(
"general",
"FirstRunForStartGeometry")
347 except ConfigParser.NoOptionError:
348 print "Missing mandatory option 'FirstRunForStartGeometry' in [general] section." 351 for section
in config.sections():
352 if section.startswith(
"dataset:"):
354 collection = config.get(section,
"collection")
356 except ConfigParser.NoOptionError:
357 print "Missing mandatory option 'collection' in section ["+section+
"]." 361 with open(configTemplate,
"r") as f: 364 print "The config-template '"+configTemplate+
"' cannot be found." 367 tmpFile = re.sub(
'setupGlobaltag\s*\=\s*[\"\'](.*?)[\"\']',
368 'setupGlobaltag = \"'+globalTag+
'\"',
370 tmpFile = re.sub(
'setupCollection\s*\=\s*[\"\'](.*?)[\"\']',
371 'setupCollection = \"'+collection+
'\"',
373 tmpFile = re.sub(re.compile(
"setupRunStartGeometry\s*\=\s*.*$", re.M),
374 "setupRunStartGeometry = "+first_run,
377 thisCfgTemplate =
"tmp.py" 378 with open(thisCfgTemplate,
"w")
as f: f.write(tmpFile)
380 cms_process = mps_tools.get_process_object(thisCfgTemplate)
383 with open(thisCfgTemplate,
"a")
as f: f.write(overrideGT)
385 for setting
in pedesettings:
389 print "Creating pede job." 391 print "Creating pede jobs using settings from '{0}'.".
format(setting)
392 for weight_conf
in weight_confs:
395 os.system(
"mps_weight.pl -c > /dev/null")
397 for name,weight
in weight_conf:
398 os.system(
"mps_weight.pl -N "+name+
" "+weight)
401 os.system(
"mps_setupm.pl")
404 lib = mpslib.jobdatabase()
408 command =
"rm -f jobData/"+lib.JOBDIR[-1]+
"/alignment_merge.py" 413 command = (
"mps_merge.py -w "+thisCfgTemplate+
" jobData/"+
414 lib.JOBDIR[-1]+
"/alignment_merge.py jobData/"+
415 lib.JOBDIR[-1]+
" "+
str(lib.nJobs))
416 if setting
is not None: command +=
" -a "+setting
419 subprocess.call(command, stderr=subprocess.STDOUT, shell=
True)
421 with open(os.devnull,
'w')
as FNULL:
422 subprocess.call(command, stdout=FNULL,
423 stderr=subprocess.STDOUT, shell=
True)
426 os.system(
"rm "+thisCfgTemplate)
428 if overrideGT.strip() !=
"":
430 msg = (
"Overriding global tag with single-IOV tags extracted from '{}' " 431 "for run number '{}'.".
format(generalOptions[
"globaltag"],
444 for section
in config.sections():
445 if 'general' in section:
447 elif section.startswith(
"dataset:"):
452 datasetOptions[
'name'] = section[8:]
455 for var
in [
'inputFileList',
'collection']:
457 datasetOptions[var] = config.get(section,var)
458 except ConfigParser.NoOptionError:
459 print 'No', var,
'found in', section+
'. Please check ini-file.' 463 for var
in [
'configTemplate',
'globaltag']:
464 if config.has_option(section,var):
465 datasetOptions[var] = config.get(section,var)
468 datasetOptions[var] = generalOptions[var]
470 print "No",var,
"found in ["+section+
"]",
471 print "and no default in [general] section." 475 datasetOptions[
'cosmicsZeroTesla'] =
False 476 if config.has_option(section,
'cosmicsZeroTesla'):
477 datasetOptions[
'cosmicsZeroTesla'] = config.getboolean(section,
'cosmicsZeroTesla')
479 datasetOptions[
'cosmicsDecoMode'] =
False 480 if config.has_option(section,
'cosmicsDecoMode'):
481 datasetOptions[
'cosmicsDecoMode'] = config.getboolean(section,
'cosmicsDecoMode')
483 datasetOptions[
'primaryWidth'] = -1.0
484 if config.has_option(section,
'primaryWidth'):
485 datasetOptions[
'primaryWidth'] = config.getfloat(section,
'primaryWidth')
487 datasetOptions[
'json'] =
'' 488 if config.has_option(section,
'json'):
489 datasetOptions[
'json'] = config.get(section,
'json')
492 datasetOptions[
'json'] = generalOptions[
'json']
494 print "No json given in either [general] or ["+section+
"] sections.",
495 print "Proceeding without json-file." 499 datasetOptions[
'inputFileList'] = os.path.expandvars(datasetOptions[
'inputFileList'])
502 datasetOptions[
'configTemplate'] = os.path.expandvars(datasetOptions[
'configTemplate'])
506 datasetOptions[
'njobs'] = 0
508 with open(datasetOptions[
'inputFileList'],
'r') as filelist: 509 for line
in filelist:
510 if 'CastorPool' in line:
513 if not line.strip()==
'':
514 datasetOptions[
'njobs'] += 1
516 print 'Inputfilelist', datasetOptions[
'inputFileList'],
'does not exist.' 518 if datasetOptions[
'njobs'] == 0:
519 print 'Number of jobs is 0. There may be a problem with the inputfilelist:' 520 print datasetOptions[
'inputFileList']
524 if config.has_option(section,
'njobs'):
525 if config.getint(section,
'njobs')<=datasetOptions[
'njobs']:
526 datasetOptions[
'njobs'] = config.getint(section,
'njobs')
528 print 'njobs is bigger than the default',datasetOptions[
'njobs'],
'. Using default.' 530 print 'No number of jobs specified. Using number of files in inputfilelist as the number of jobs.' 535 with open(datasetOptions[
'configTemplate'],
'r') as INFILE: 536 tmpFile = INFILE.read() 538 print 'The config-template called',datasetOptions[
'configTemplate'],
'cannot be found.' 541 tmpFile = re.sub(
'setupGlobaltag\s*\=\s*[\"\'](.*?)[\"\']',
542 'setupGlobaltag = \"'+datasetOptions[
'globaltag']+
'\"',
544 tmpFile = re.sub(re.compile(
"setupRunStartGeometry\s*\=\s*.*$", re.M),
545 "setupRunStartGeometry = "+
546 generalOptions[
"FirstRunForStartGeometry"], tmpFile)
547 tmpFile = re.sub(
'setupCollection\s*\=\s*[\"\'](.*?)[\"\']',
548 'setupCollection = \"'+datasetOptions[
'collection']+
'\"',
550 if datasetOptions[
'cosmicsZeroTesla']:
551 tmpFile = re.sub(re.compile(
'setupCosmicsZeroTesla\s*\=\s*.*$', re.M),
552 'setupCosmicsZeroTesla = True',
554 if datasetOptions[
'cosmicsDecoMode']:
555 tmpFile = re.sub(re.compile(
'setupCosmicsDecoMode\s*\=\s*.*$', re.M),
556 'setupCosmicsDecoMode = True',
558 if datasetOptions[
'primaryWidth'] > 0.0:
559 tmpFile = re.sub(re.compile(
'setupPrimaryWidth\s*\=\s*.*$', re.M),
560 'setupPrimaryWidth = '+
str(datasetOptions[
'primaryWidth']),
562 if datasetOptions[
'json'] !=
'':
563 tmpFile = re.sub(re.compile(
'setupJson\s*\=\s*.*$', re.M),
564 'setupJson = \"'+datasetOptions[
'json']+
'\"',
567 thisCfgTemplate =
'tmp.py' 568 with open(thisCfgTemplate,
'w')
as OUTFILE:
569 OUTFILE.write(tmpFile)
577 configTemplate = tmpFile
578 cms_process = mps_tools.get_process_object(thisCfgTemplate)
580 generalOptions[
"FirstRunForStartGeometry"])
582 with open(thisCfgTemplate,
"a")
as f: f.write(overrideGT)
586 command =
'mps_setup.pl -m%s -M %s -N %s %s %s %s %d %s %s %s cmscafuser:%s' % (
588 generalOptions[
'pedeMem'],
589 datasetOptions[
'name'],
592 datasetOptions[
'inputFileList'],
593 datasetOptions[
'njobs'],
594 generalOptions[
'classInf'],
595 generalOptions[
'jobname'],
599 print 'Submitting dataset:', datasetOptions[
'name']
600 print 'Baseconfig: ', datasetOptions[
'configTemplate']
601 print 'Collection: ', datasetOptions[
'collection']
602 if datasetOptions[
"collection"]
in (
"ALCARECOTkAlCosmicsCTF0T",
603 "ALCARECOTkAlCosmicsInCollisions"):
604 print 'cosmicsDecoMode: ', datasetOptions[
'cosmicsDecoMode']
605 print 'cosmicsZeroTesla: ', datasetOptions[
'cosmicsZeroTesla']
606 print 'Globaltag: ', datasetOptions[
'globaltag']
607 print 'Number of jobs: ', datasetOptions[
'njobs']
608 print 'Inputfilelist: ', datasetOptions[
'inputFileList']
609 if datasetOptions[
'json'] !=
'':
610 print 'Jsonfile: ', datasetOptions[
'json']
611 print 'Pass to mps_setup: ', command
615 subprocess.call(command, stderr=subprocess.STDOUT, shell=
True)
617 with open(os.devnull,
'w')
as FNULL:
618 subprocess.call(command, stdout=FNULL,
619 stderr=subprocess.STDOUT, shell=
True)
622 os.system(
"rm "+thisCfgTemplate)
625 print "No dataset section defined in '{0}'".
format(aligmentConfig)
626 print "At least one section '[dataset:<name>]' is required." 629 firstPedeConfig =
True 630 for setting
in pedesettings:
634 print "Creating pede job." 636 print "Creating pede jobs using settings from '{0}'.".
format(setting)
637 for weight_conf
in weight_confs:
640 os.system(
"mps_weight.pl -c > /dev/null")
642 for name,weight
in weight_conf:
643 os.system(
"mps_weight.pl -N "+name+
" "+weight)
646 firstPedeConfig =
False 649 os.system(
"mps_setupm.pl")
652 lib = mpslib.jobdatabase()
656 command =
"rm -f jobData/"+lib.JOBDIR[-1]+
"/alignment_merge.py" 660 thisCfgTemplate =
"tmp.py" 661 with open(thisCfgTemplate,
"w")
as f:
662 f.write(configTemplate+overrideGT)
665 command = (
"mps_merge.py -w "+thisCfgTemplate+
" jobData/"+lib.JOBDIR[-1]+
666 "/alignment_merge.py jobData/"+lib.JOBDIR[-1]+
" "+
668 if setting
is not None: command +=
" -a "+setting
671 subprocess.call(command, stderr=subprocess.STDOUT, shell=
True)
673 with open(os.devnull,
'w')
as FNULL:
674 subprocess.call(command, stdout=FNULL,
675 stderr=subprocess.STDOUT, shell=
True)
678 os.system(
"rm "+thisCfgTemplate)
680 if overrideGT.strip() !=
"":
682 msg = (
"Overriding global tag with single-IOV tags extracted from '{}' for " 683 "run number '{}'.".
format(generalOptions[
"globaltag"],
684 generalOptions[
"FirstRunForStartGeometry"]))
def check_iov_definition(cms_process, first_run)
def create_input_db(cms_process, run_number)
def get_weight_configs(config)