import numpy as np import datetime import glob import Globals as g import matplotlib.pyplot as plt def get_item_in_dict(dic, address): for step in address: dic = dic[step] return dic def print_dict(dictionary, ident = '', braces=1, plot = True): """ Recursively prints nested dictionaries.""" for key, value in dictionary.items(): if isinstance(value, dict): print ('%s%s%s%s' %(ident,braces*'[',key,braces*']')) print_dict(value, ident+' ', braces+1) else: if type(value).__name__ == 'ndarray' and plot == True: print (ident+key+' (see plot below)' ) if value.ndim == 1: plt.figure() plt.plot(value) plt.title(key+' level = '+str(braces)) if value.ndim == 2: from matplotlib import cm plt.figure() plt.imshow(value, cmap='gray') plt.title(key+' level = '+str(braces)) plt.colorbar() else: print (ident+'%s = %s' %(key, value)) def get_subfolders(base_folder): from glob import glob subfolders = [] while True: folders = glob(base_folder+"*/") if folders == []: break subfolders += folders base_folder += '*/' return subfolders def find_configs(base_folder, output = True): subfolders = get_subfolders(base_folder) configs = [] for folder in subfolders: new_configs = IO(folder).search(output = False) for config in new_configs: config['folder'] = folder configs += new_configs return configs def get_differences(dics, headids = []): if len(dics) < 2: return [] ids = [] ref_dic = dics[0] for dic in dics[1:]: for name, item in dic.items(): if headids + [name] in ids: continue if not name in ref_dic: ids += [headids + [name]] continue if ref_dic[name] == item: continue if isinstance(item, dict): subdiff = get_differences(extract(dics,name),headids = headids + [name]) for diff in subdiff: if diff in ids: continue ids += [diff] continue ids += [headids + [name]] ref_dic = dics[-1] for dic in dics[:-1]: for name, item in dic.items(): if headids + [name] in ids: continue if not name in ref_dic: ids += [headids + [name]] continue if ref_dic[name] == item: continue if isinstance(item, dict): subdiff = get_differences(extract(dics,name),headids = headids + [name]) for diff in subdiff: if diff in ids: continue ids += [diff] continue ids += [headids + [name]] return ids def extract(measurements, list_of_ids): try: measurements = list(measurements) except: pass if type(list_of_ids) == str: list_of_ids = [list_of_ids] if type(measurements) is not list: measurements = [measurements] ms = measurements for i in list_of_ids: ms_new = [] one_contains = False for m in ms: if isinstance(m,dict) and i in m: ms_new += [m[i]] one_contains = True else: ms_new += [None] if not one_contains: print (ms) ms_wo_none = filter(None.__ne__, ms) import itertools print ("id ",i," doesn't exsist. Choose from: ",set(itertools.chain(*[m.keys() for m in ms_wo_none]))) assert (False) ms = ms_new return ms def print_data(data, plot = True): print_dict(data, plot = plot) def plot_measure(data, devices, plot_config = {}, sleep = 0): if plot_config == {}: measure, config = (data['measure'], data['config']) for device in devices: device_name = type(device).__name__ if hasattr(device, 'plot_measure'): device.plot_measure(measure[device_name], config = config[device_name]) return else: try: g.plot_hist except: g.plot_hist = {} try: g.plot_servers except: g.plot_servers = {} measure, config = (data['measure'], data['config']) for device in devices: device_name = type(device).__name__ try: g.plot_hist[device_name] except: g.plot_hist[device_name] = {} for item in plot_config[device_name].items(): if item[0] == 'plot_measure' : if item[1]: device.plot_measure(measure[device_name], config = config[device_name]) else: if not item[1]: continue try: g.plot_hist[device_name][item[0]] =g.plot_hist[device_name][item[0]] + [measure[device_name][item[0]]] except: g.plot_hist[device_name][item[0]] = [measure[device_name][item[0]]] try: ps1d = g.plot_servers['history: '+device_name+' '+item[0]] except: from PlottingServers import Plot1DServer ps1d = Plot1DServer({'xlabel' : 'last measurements','ylabel' : 'value', 'title': 'history: '+device_name+' '+item[0]}) g.plot_servers['history: '+device_name+' '+item[0]] = ps1d xx = range(-len(g.plot_hist[device_name][item[0]])+1,1) ps1d.update(xx,g.plot_hist[device_name][item[0]]) #important: sort by time and plot sepecific elements def dict_contains(d, item): for it in d.items(): if isinstance(it[1], dict): if dict_contains(it[1], item): return True if it == item: return True return False def set_config(devices, config): for device in devices: device_name = type(device).__name__ try: device.set_config(config[device_name]) except: print ('Device '+device_name+' is not in this config') def get_config(devices): time = str(datetime.datetime.now()).replace(':','-').replace(' ','_') config = {'time': time} for device in devices: import time t = time.time() device_name = type(device).__name__ config[device_name] = device.get_config() print (device_name,' config time: ',time.time() - t) return config def meas(dev): dn = type(dev).__name__ if hasattr(dev, 'measure'): import time tt = time.time() d = dev.measure() print (dn,' measure time: ',time.time() - tt) return dn, d def measure(devices, devices2measure = 'all', parallel = True): time = str(datetime.datetime.now()).replace(':','-').replace(' ','_') data = {'time': time} data['config'] = get_config(devices) data['measure'] = {} if devices2measure == 'all': devices2measure = devices if parallel: from joblib import Parallel, delayed res = Parallel(n_jobs= 4, backend="threading")(delayed(meas)(device) for device in devices2measure) for i in range(len(res)): data['measure'][res[i][0]]= res[i][1] return data for device in devices2measure: device_name = type(device).__name__ if hasattr(device, 'measure'): import time t = time.time() data['measure'][device_name] = device.measure() print (device_name,' measure time: ',time.time() - t) return data class IO: def __init__(self, path): self.path = path try: import elog as el self.logbook = el.open('https://elog-gfa.psi.ch', 'AMAS', user='sauerwein_n', password='Dark374Fields!', use_ssl=True, subdir='', encrypt_pwd=True) except: print ('This computer does not support elog') def save(self, data, name = None, elog = False, kind = 'config', comment = '', folder = ''): data['comment'] = comment if name == None: name = kind+data['time'] np.save(self.path+folder+name+'.npy',data) print (kind+' saved as '+name+'.npy') if elog: class elogobj: def __init__(self,dic): self.name = 'config.txt' self.dic = dic def read(self): return str(self.dic) obj = elogobj(data) import time self.logbook.post('Configuration with Comment: '+comment, attributes={'Titel':'Configuration of LWFA', 'Autor':'Sauerwein Nick Jacob (SQ84)', 'Projekt': 'LPWA', 'Dates': int(time.time())}, attachments=[obj]) return data def load(self, name_id = -1, kind = 'config', gui = False, elog = False): if elog: import requests response = requests.get(self.logbook.read(name_id)[-1][0], verify=False, auth=('sauerwein_n', 'Dark374Fields!')) return eval(response.content.decode()) if gui: from tkinter import Tk from tkinter.filedialog import askopenfilename root = Tk() root.withdraw() root.update() filename = askopenfilename(initialdir=self.path) root.distroy() return np.load(filename).item() if type(name_id) == int: return np.load([filen for filen in glob.iglob(self.path+kind+'*.npy')][name_id]).item() return np.load(self.path+str(name_id)+'.npy').item() def search(self, key_dict = {}, kind = 'config', output = True): datas = [] if output: print ('n \t ',[item[0] for item in key_dict.items()]) n = 0 for filename in glob.iglob(self.path+kind+'*.npy'): data = np.load(filename).item() test = [dict_contains(data,item) for item in key_dict.items()] if output: print (n,' \t ',test) if np.all(test) or len(key_dict) == 0: datas += [data] n += 1 return datas def select(self, keys = [{}], kind = 'measure'): #example of key: {'address': ['where', 'to', 'find', 'data'], 'value': [val, 'b', error]} # 'b': bigger, 's': smaller, 'e': equals, in case of 'e' the error variable should be defined. results = [] for filename in glob.iglob(self.path+kind+'*.npy'): data = np.load(filename).item() take = True for key in keys: try: if key['value'][1] == 'b': if key['value'][0] >= get_item_in_dict(data, key['address']): take = False print ('test') if key['value'][1] == 's': if key['value'][0] <= get_item_in_dict(data, key['address']): take = False if key['value'][1] == 'e': if key['value'][0] - key['value'][2] <= get_item_in_dict(data, key['address']) or key['value'][0] + key['value'][2] >= get_item_in_dict(data, key['address']): take = False except: take = False if take: results += [data] return results