509 def run_card_consistency_check(self):
510 """Checks the consistency of runCardDict.
511 This function should be called before writing runCardDict to disk to ensure that the run card is consistent and has appropriate settings.
512 """
513 self.compare_runCardCasing()
514
515
516
517 if self.runCardDict.
get(
'event_norm',
None) ==
'sum':
518 self.runCardDict['event_norm'] = 'average'
519 mglog.warning("setting event_norm to average, there is basically no use case where event_norm=sum is a good idea")
520
521 if not self.isNLO:
522
523 if 'ktdurham' in self.runCardDict and float(self.runCardDict['ktdurham']) > 0 and int(self.runCardDict['ickkw']) != 0:
524 log='Bad combination of settings for CKKW-L merging! ktdurham=%s and ickkw=%s.'%(self.runCardDict['ktdurham'],self.runCardDict['ickkw'])
525 mglog.error(log)
526 raise RuntimeError(log)
527
528
529 if 'systematics_program' not in self.runCardDict or self.runCardDict['systematics_program']=='systematics':
530 syscalc_settings = ['sys_pdf', 'sys_scalefact', 'sys_alpsfact', 'sys_matchscale']
531 found_syscalc_setting = False
532 for s in syscalc_settings:
533 if s in self.runCardDict:
534 mglog.warning('Using syscalc setting '+s+' with new systematics script. Systematics script is default from 2.6.2 and steered differently (https://cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Systematics#Systematicspythonmodule)')
535 found_syscalc_setting = True
536 if found_syscalc_setting:
537 syst_arguments = convertSysCalcArguments(self.runCardDict)
538 mglog.info('Converted syscalc arguments to systematics arguments: '+syst_arguments)
539 syst_settings_update = {'systematics_arguments':syst_arguments}
540 for s in syscalc_settings:
541 syst_settings_update[s] = None
542 self.runCardDict.update(syst_settings_update)
543
544
545 mglog.info('Checking PDF and systematics settings')
546 if not self.base_fragment_setup_check(self.pdf_setting,self.runCardDict,self.isNLO):
547
548 syst_settings = get_pdf_and_systematic_settings(self.pdf_setting,self.isNLO)
549 self.runCardDict.update(syst_settings)
550
551 if 'systematics_arguments' in self.runCardDict:
552 systematics_arguments = parse_systematics_arguments(self.runCardDict['systematics_arguments'])
553 if 'weight_info' not in systematics_arguments:
554 mglog.info('Enforcing systematic weight name convention')
555 dyn = None
556 if '--dyn' in systematics_arguments or ' dyn' in systematics_arguments:
557 if '--dyn' in systematics_arguments:
558 dyn = systematics_arguments.split('--dyn')[1]
559 if ' dyn' in systematics_arguments:
560 dyn = systematics_arguments.split(' dyn')[1]
562 if dyn is not None and len(dyn.split(','))>1:
563 systematics_arguments['weight_info'] = SYSTEMATICS_WEIGHT_INFO_ALTDYNSCALES
564 else:
565 systematics_arguments['weight_info'] = SYSTEMATICS_WEIGHT_INFO
566 self.runCardDict['systematics_arguments'] = write_systematics_arguments(systematics_arguments)
567
568 if not self.isNLO:
569 if 'python_seed' not in self.runCardDict:
570 mglog.warning('No python seed set in run_card -- adding one with same value as iseed')
571 self.runCardDict['python_seed'] = self.runCardDict['iseed']
572
573
574
575 FS_updates={}
576 proton_5flav = False
577 jet_5flav = False
578 with open(self.process_dir+'/Cards/proc_card_mg5.dat', 'r') as file:
579 content = file.readlines()
580
581 for rawline in content:
582 line = rawline.split('#')[0]
583 if line.startswith("define p"):
584 if ('b' in line.split() and 'b~' in line.split()) or ('5' in line.split() and '-5' in line.split()):
585
586 proton_5flav = True
587 if 'j' in line.split() and jet_5flav:
588 proton_5flav = True
589 if line.startswith("define j"):
590 if ('b' in line.split() and 'b~' in line.split()) or ('5' in line.split() and '-5' in line.split()):
591
592 jet_5flav = True
593 if 'p' in line.split() and proton_5flav:
594 jet_5flav = True
595 if proton_5flav or jet_5flav:
596 FS_updates['asrwgtflavor'] = 5
597
598 if not proton_5flav:
599 mglog.warning('Found 5-flavour jets but 4-flavour proton. This is inconsistent - please pick one.')
600 mglog.warning('Will proceed assuming 5-flavour scheme.')
601 if not jet_5flav:
602 mglog.warning('Found 5-flavour protons but 4-flavour jets. This is inconsistent - please pick one.')
603 mglog.warning('Will proceed assuming 5-flavour scheme.')
604 else:
605 FS_updates['asrwgtflavor'] = 4
606
607 if len(FS_updates)==0:
608 mglog.warning(f'Could not identify 4- or 5-flavor scheme from process card {self.process_dir}/Cards/proc_card_mg5.dat')
609
610
611 if 'asrwgtflavor' in self.runCardDict or 'maxjetflavor' in self.runCardDict or 'pdgs_for_merging_cut' in self.runCardDict:
612 if FS_updates['asrwgtflavor'] == 5:
613
614 if ('asrwgtflavor' in self.runCardDict and int(self.runCardDict['asrwgtflavor']) != 5) or ('maxjetflavor' in self.runCardDict and int(self.runCardDict['maxjetflavor']) != 5) or ('pdgs_for_merging_cut' in self.runCardDict and '5' not in self.runCardDict['pdgs_for_merging_cut']):
615
616 mglog.warning('b and b~ included in p and j for 5-flavor scheme but run card settings are inconsistent; adjusting run card')
617 run_card_updates = {'asrwgtflavor': 5, 'maxjetflavor': 5, 'pdgs_for_merging_cut': '1, 2, 3, 4, 5, 21'}
618
619 self.runCardDict.update( run_card_updates )
620 self.paramCard.modify_paramCardDict(params={'MASS': {'5': '0.000000e+00'}})
621 else:
622 mglog.debug('Consistent 5-flavor scheme setup detected.')
623
624 if FS_updates['asrwgtflavor'] == 4:
625
626 if ('asrwgtflavor' in self.runCardDict and int(self.runCardDict['asrwgtflavor']) != 4) or ('maxjetflavor' in self.runCardDict and int(self.runCardDict['maxjetflavor']) != 4) or ('pdgs_for_merging_cut' in self.runCardDict and '5' in self.runCardDict['pdgs_for_merging_cut']):
627
628 mglog.warning('b and b~ not included in p and j (4-flavor scheme) but run card settings are inconsistent; adjusting run card')
629 run_card_updates = {'asrwgtflavor': 4, 'maxjetflavor': 4, 'pdgs_for_merging_cut': '1, 2, 3, 4, 21'}
630
631 self.runCardDict.update( run_card_updates )
632 self.paramCard.modify_paramCardDict(params={'MASS': {'5': '4.700000e+00'}})
633 else:
634 mglog.debug('Consistent 4-flavor scheme setup detected.')
635 else:
636
637 if FS_updates['asrwgtflavor'] == 4:
638
639 mglog.warning('Flavor scheme setup is missing, adding by hand according to process card - b and b~ not included in p and j, 4-flavor scheme setup will be used; adjusting run card.')
640 if self.isNLO:
641 run_card_updates = {'maxjetflavor': 4}
642 else:
643 run_card_updates = {'asrwgtflavor': 4, 'maxjetflavor': 4, 'pdgs_for_merging_cut': '1, 2, 3, 4, 21'}
644
645 self.runCardDict.update( run_card_updates )
646 self.paramCard.modify_paramCardDict(params={'MASS': {'5': '4.700000e+00'}})
647 elif FS_updates['asrwgtflavor'] == 5:
648 mglog.warning('Flavor scheme setup is missing, adding by hand according to process card - b and b~ included in p and j, 5-flavor scheme setup will be used; adjusting run card.')
649 if self.isNLO:
650 run_card_updates = {'maxjetflavor': 5}
651 else:
652 run_card_updates = {'asrwgtflavor': 5, 'maxjetflavor': 5, 'pdgs_for_merging_cut': '1, 2, 3, 4, 5, 21'}
653
654
655 self.runCardDict.update( run_card_updates )
656 self.paramCard.modify_paramCardDict(params={'MASS': {'5': '0.000000e+00'}})
657
658
659 if '91.188' not in self.runCardDict.
get(
'scale',
'91.188')
and self.runCardDict.
get(
'fixed_ren_scale',
'f').lower()
in [
'f',
'false']:
660 mglog.error('Seems you set "scale" in the run card without setting "fixed_ren_scale" to True. Not sure what to do here, throwing an error.')
661 raise ValueError("Renormalization scale setting incorrect")
662 if (
'91.188' not in self.runCardDict.
get(
'dsqrt_q2fact1',
'91.188')
or '91.188' not in self.runCardDict.
get(
'dsqrt_q2fact2',
'91.188')) \
663 and self.runCardDict.
get(
'fixed_fac_scale',
'f').lower()
in [
'f',
'false']:
664 mglog.error('Seems you set "dsqrt_q2fact1" or "dsqrt_q2fact2" in the run card without setting "fixed_fac_scale" to True. Not sure what to do here, throwing an error.')
665 raise ValueError("Factorization scale setting incorrect")
666
667 mglog.info('Finished checking run card - All OK!')
668
669
std::string replace(std::string s, const std::string &s2, const std::string &s3)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)