moved some eco components to bernina repo

This commit is contained in:
2022-07-07 12:07:02 +02:00
parent 222c82773d
commit a5a92cdaed
6 changed files with 313 additions and 2 deletions

View File

@ -3,7 +3,7 @@ import logging
from epics import PV
from slic.utils.eco_components.aliases import NamespaceCollection
from slic.utils.eco_components.ecoinit import ecoinit
from eco_components.ecoinit import ecoinit
from devices import components, config

2
devices.py Executable file → Normal file
View File

@ -11,7 +11,7 @@
# if arg or kwarg is of type slic.utils.Component (dummy class)
# this indicates that an earlier initialized object is used
# (e.g. from same configuration).
from slic.utils.eco_components.config import (
from eco_components.config import (
Component,
Alias,
init_device,

View File

247
eco_components/config.py Normal file
View File

@ -0,0 +1,247 @@
import json
import importlib
from pathlib import Path
import sys
from colorama import Fore as _color
from functools import partial
from slic.utils.eco_components.aliases import Alias
import getpass
import colorama
import socket
#TODO: add lazy_object_proxy as dep?
try:
from lazy_object_proxy import Proxy
except ImportError:
print(_color.RED + "Cannot import lazy_object_proxy, thus cannot create lazy objects" + _color.RESET)
Proxy = None
class Component:
def __init__(self, namestring):
self.name = namestring
def init_name_obj(obj, args, kwargs, name=None):
try:
return obj(*args, **kwargs, name=name)
except TypeError:
return obj(*args, **kwargs)
def init_device(type_string, name, args=[], kwargs={}, verbose=True, lazy=True):
if verbose:
print(("Configuring %s " % (name)).ljust(25), end="")
sys.stdout.flush()
imp_p, type_name = type_string.split(sep=":")
imp_p = imp_p.split(sep=".")
if verbose:
print(("(%s)" % (type_name)).ljust(25), end="")
sys.stdout.flush()
try:
tg = importlib.import_module(".".join(imp_p)).__dict__[type_name]
if lazy and Proxy:
tdev = Proxy(partial(init_name_obj, tg, args, kwargs, name=name))
if verbose:
print((_color.YELLOW + "LAZY" + _color.RESET).rjust(5))
sys.stdout.flush()
else:
tdev = init_name_obj(tg, args, kwargs, name=name)
if verbose:
print((_color.GREEN + "OK" + _color.RESET).rjust(5))
sys.stdout.flush()
return tdev
except Exception as expt:
# tb = traceback.format_exc()
if verbose:
print((_color.RED + "FAILED" + _color.RESET).rjust(5))
# print(sys.exc_info())
raise expt
def get_dependencies(inp):
outp = []
if isinstance(inp, dict):
inp = inp.values()
for ta in inp:
if isinstance(ta, Component):
outp.append(ta.name)
elif isinstance(ta, dict) or isinstance(ta, list):
outp.append(get_dependencies(ta))
return outp
def replaceComponent(inp, dict_all, config_all, lazy=False):
if isinstance(inp, list):
outp = []
for ta in inp:
if isinstance(ta, Component):
if ta.name in dict_all.keys():
outp.append(dict_all[ta.name])
else:
ind = [ta.name==tca['name'] for tca in config_all].index(True)
outp.append(initFromConfigList(config_list[ind:ind+1],config_all,lazy=lazy))
elif isinstance(ta, dict) or isinstance(ta, list):
outp.append(replaceComponent(ta, dict_all,config_all, lazy=lazy))
else:
outp.append(ta)
elif isinstance(inp, dict):
outp = {}
for tk, ta in inp.items():
if isinstance(ta, Component):
if ta.name in dict_all.keys():
outp[tk] = dict_all[ta.name]
else:
ind = [tk.name==tca['name'] for tca in config_all].index(True)
outp[tk] = initFromConfigList(config_list[ind:ind+1],config_all,lazy=lazy)
elif isinstance(ta, dict) or isinstance(ta, list):
outp[tk] = replaceComponent(ta, dict_all, config_all, lazy=lazy)
else:
outp[tk] = ta
else:
return inp
return outp
def initFromConfigList(config_list, config_all, lazy=False):
op = {}
for td in config_list:
# args = [op[ta.name] if isinstance(ta, Component) else ta for ta in td["args"]]
# kwargs = {
# tkwk: op[tkwv.name] if isinstance(tkwv, Component) else tkwv
# for tkwk, tkwv in td["kwargs"].items()
# }
try:
tlazy = td["lazy"]
except:
tlazy = lazy
op[td["name"]] = init_device(
td["type"],
td["name"],
replaceComponent(td["args"], op, config_all, lazy=lazy),
replaceComponent(td["kwargs"], op, config_all, lazy=lazy),
lazy=tlazy,
)
return op
class Configuration:
"""Configuration collector object collecting important settings for arbitrary use,
linking to one or few standard config files in the file system. Sould also be used
for config file writing."""
def __init__(self, configFile, name=None):
self.name = name
self.configFile = Path(configFile)
self._config = {}
if self.configFile:
self.readConfigFile()
def readConfigFile(self):
self._config = loadConfig(self.configFile)
assert (
type(self._config) is dict
), f"Problem reading {self.configFile} json file, seems not to be a valid dictionary structure!"
# self.__dict__.update(self._config)
def __setitem__(self, key, item):
self._config[key] = item
# self.__dict__.update(self._config)
self.saveConfigFile()
def __getitem__(self, key):
return self._config[key]
def saveConfigFile(self, filename=None, force=False):
if not filename:
filename = self.configFile
if (not force) and filename.exists():
if (
not input(
f"File {filename.absolute().as_posix()} exists,\n would you like to overwrite? (y/n)"
).strip()
== "y"
):
return
writeConfig(filename, self._config)
def _ipython_key_completions_(self):
return list(self._config.keys())
def __repr__(self):
return json.dumps(self._config, indent=4)
def loadConfig(fina):
with open(fina, "r") as f:
return json.load(f)
def writeConfig(fina, obj):
with open(fina, "w") as f:
json.dump(obj, f, indent=4)
class ChannelList(list):
def __init__(self,*args,**kwargs):
self.file_name = kwargs.pop("file_name")
# list.__init__(*args,**kwargs)
self.load()
def load(self):
self.clear()
self.extend(parseChannelListFile(self.file_name))
def parseChannelListFile(fina):
out = []
with open(fina, "r") as f:
done = False
while not done:
d = f.readline()
if not d:
done = True
if len(d) > 0:
if not d.isspace():
if not d[0] == "#":
out.append(d.strip())
return out
def append_to_path(*args):
for targ in args:
sys.path.append(targ)
def prepend_to_path(*args):
for targ in args:
sys.path.insert(0, targ)
class Terminal:
def __init__(self,title='eco',scope=None):
self.title = title
self.scope = scope
@property
def user(self):
return getpass.getuser()
@property
def host(self):
return socket.gethostname()
@property
def user(self):
return getpass.getuser()
def get_string(self):
s = f'{self.title}'
if self.scope:
s +=f'-{self.scope}'
s += f' ({self.user}@{self.host})'
return s
def set_title(self,extension=''):
print(colorama.ansi.set_title("♻️ "+self.get_string()+extension))

15
eco_components/ecocnf.py Normal file
View File

@ -0,0 +1,15 @@
#import logging
#import json
#from pathlib import Path
#from .utilities.config import Configuration
startup_lazy = False
scopes = [
{"name": "Alvra", "facility": "SwissFEL", "module": "alvra"},
{"name": "Bernina", "facility": "SwissFEL", "module": "bernina"},
{"name": "SwissMX", "facility": "SwissFEL", "module": "swissmx"},
]
# settings = Configuration(Path.home() / '.ecorc', name='eco_startup_settings')

49
eco_components/ecoinit.py Normal file
View File

@ -0,0 +1,49 @@
from .config import initFromConfigList
from . import ecocnf
def ecoinit(*args, _mod=None, alias_namespaces=None, components=None, lazy=None):
#TODO: workaround for *args being used here
msg = "ecoinit: \"{}\" is mandatory, even though it is a keyword argument"
if _mod is None:
raise TypeError(msg.format("_mod"))
if alias_namespaces is None:
raise TypeError(msg.format("alias_namespaces"))
if components is None:
raise TypeError(msg.format("components"))
if args:
allnames = [tc['name'] for tc in components]
comp_toinit = []
for arg in args:
if not arg in allnames:
raise Exception(f'The component {arg} has no configuration defined!')
else:
comp_toinit.append(components[allnames.index(arg)])
else:
comp_toinit = components
if lazy is None:
lazy=ecocnf.startup_lazy
op = {}
for key, value in initFromConfigList(comp_toinit, components, lazy=lazy).items():
# _namespace[key] = value
_mod.__dict__[key] = value
op[key]= value
if not ecocnf.startup_lazy:
try:
for ta in value.alias.get_all():
alias_namespaces.bernina.update(
ta["alias"], ta["channel"], ta["channeltype"]
)
except:
pass
# alias_namespaces.bernina.store()
return op