Something went wrong on our end
-
Cyril Danilevski authoredCyril Danilevski authored
update_config.py 5.98 KiB
import argparse
import json
import sys
import yaml
import zmq
# Defining available options
agipd_options = {
"force-hg-if-below": {'typ': int},
"rel-gain": {'typ': bool},
"xray-gain": {'typ': bool},
"blc-noise": {'typ': bool},
"blc-set-min": {'typ': bool},
"dont-zero-nans": {'typ': bool},
"dont-zero-orange": {'typ': bool},
"max-pulses": {'typ': list,
'msg': "Range list of maximum pulse indices "
"(--max-pulses start end step). "
"3 max input elements. "},
"calfile": {'typ': str},
}
data_mapping = {
"karabo-da": {'typ': list,
'choices': ["AGIPD{:02d}".format(i) for i in range(16)],
'msg': "Choices: [AGIPD00 ... AGIPD15]. "}
}
available_options = {
"SPB_DET_AGIPD1M-1": [agipd_options, data_mapping],
"MID_DET_AGIPD1M-1": [agipd_options, data_mapping]
}
formatter = lambda prog: argparse.HelpFormatter(prog, max_help_position=52)
parser = argparse.ArgumentParser(
description='Request update of configuration', formatter_class=formatter)
required_args = parser.add_argument_group('required arguments')
required_args.add_argument('--karabo-id', type=str,
choices=['SPB_DET_AGIPD1M-1',
'MID_DET_AGIPD1M-1'])
required_args.add_argument('--proposal', type=str,
help='The proposal number, without leading p, '
'but with leading zeros.')
required_args.add_argument('--cycle', type=str, help='The facility cycle.')
parser.add_argument('--apply', action='store_true',
help='Apply and push the requested '
'configuration update to the git.')
# remove help calls as they will cause the argument parser to exit
add_help = False
if "-h" in sys.argv:
sys.argv.remove("-h")
add_help = True
if "--help" in sys.argv:
sys.argv.remove("--help")
add_help = True
known, remaining = parser.parse_known_args()
args = vars(known)
karabo_id = args["karabo_id"]
bool_keys = []
# Avoid erros when karabo_id not yet given through the command line.
if karabo_id is not None:
# adding "no" bools to available options
for det, val in available_options[karabo_id][0].items():
if val['typ'] == bool:
bool_keys.append(det)
for b in bool_keys:
available_options[karabo_id][0]['no-{}'.format(det)] = {'typ': bool}
for exposed_options in available_options[karabo_id]:
for option, info in exposed_options.items():
metavar = None
if info['typ'] == list:
nargs = '+'
typ = str
action = 'append'
# Avoid having a big line of choices in the help message.
if 'choices' in info.keys():
metavar = option.upper()
else:
action = None
nargs = None
typ = info['typ']
# Add help messages
help_msg = ""
if 'msg' in info.keys():
help_msg += info['msg']
if 'choices' in info.keys():
choices = info['choices']
else:
choices = None
help_msg += f"Type: {info['typ'].__name__} ".upper()
parser.add_argument(f"--{option}", type=typ, action=action,
metavar=metavar, nargs=nargs, choices=choices,
help=help_msg)
parser.add_argument('--instrument', type=str, choices=["CALLAB"],
help='This is only used for testing purposes.')
if add_help:
sys.argv.append("--help")
args = vars(parser.parse_args())
task = "correct"
# check if instrument is not given from CLI (e.g. CALLAB)
if args['instrument'] is None:
# extract instrument from karabo_id
instrument = karabo_id.split("_")[0]
else:
instrument = args['instrument']
proposal = args['proposal']
cycle = args['cycle']
if instrument is None or proposal is None or cycle is None:
print("Need to define all fields")
exit()
new_conf = {task: {instrument: {karabo_id: {}}}}
for key, value in args.items():
key = key.replace("_", "-")
for exposed_options in available_options[karabo_id]:
if key in exposed_options and value is not None:
if isinstance(value, list):
value = value[0]
# convert no arguments to bool false
if 'no-' in key and isinstance(value, bool):
if key not in bool_keys:
new_conf[task][instrument][karabo_id][key.replace('no-', '')] = False # noqa
# avoid saving the "no-"key into the updated config
continue
# Assure adding an empty string for new empty
# str. updates (e.g. calfile)
if isinstance(key, str) and (value == '' or value == ' '):
value = '""'
# checking if data-mapping was updated.
if key in data_mapping.keys():
if 'data-mapping' not in new_conf.keys():
new_conf['data-mapping'] = {karabo_id: {key: {}}}
new_conf['data-mapping'][karabo_id][key] = value
else:
new_conf[task][instrument][karabo_id][key] = value
pyaml = yaml.dump(new_conf, default_flow_style=False)
if not args["apply"]:
print("\n")
print("-" * 80)
print("THIS IS A DRY RUN ONLY, NO CHANGES ARE MADE")
print("\n")
print("-" * 80)
print(f"Sending the following update: \n {pyaml}")
print("-" * 80)
con = zmq.Context()
socket = con.socket(zmq.REQ)
con = socket.connect("tcp://max-exfl016:5555")
msg = "','".join(["update_conf", "SASEX", args["karabo_id"],
instrument, args["cycle"], args["proposal"],
json.dumps(new_conf), str(args["apply"])])
socket.send("['{}']".format(msg).encode())
resp = socket.recv_multipart()[0]
print("Configuration now in place is:")
print(resp.decode())