Source code for buzz.iodutil

import warnings

[docs] def combineiod(input_dict, output_dict): """combines the input and output dictionaries into a single dictionary Args: i (dict): dictionary of the input names and values o (dict): dictionary of the output names and values Returns: dict: dictionary of the input and output names and values """ return {**input_dict, **output_dict}
[docs] def iskeyinput(key: str): """returns True if the key is an input to the control system and False if it is an output Args: key (str): string of the input or output name Returns: boolean: is the name an input or output name. true if input, false if output, none if not a valid name """ splitlist = key.split('.') if 'in' in splitlist and 'out' not in splitlist: # if 'in' is in the key return True # then it is an input so return True elif 'out' in splitlist and 'in' not in splitlist: # if 'out' is in the key return False # then it is an output so return False else: # if neither 'in' or 'out' is in the key then it is not an input or output print('cannot identify if key is input or output. KEY:' + key) return if splitlist[1]=='in': # if 'in' is in the key return True # then it is an input so return True elif splitlist[1]=='out': # if 'out' is in the key return False # then it is an output so return False else: # if neither 'in' or 'out' is in the key then it is not an input or output print('cannot identify if key is input or output. KEY:' + key) return
[docs] def listinputs(iod, values=False): """returns a list of the inputs to the control system either their names or their values Args: iod (dict): dictionary of the input and output names and indices or wield.control.mimo iod object values (bool, optional): if True, return the values of the inputs. Defaults to False. Returns: list: list of the input names or values if values is True """ if type(iod) is not dict: try: iod = iod.iod except: iod = dict(iod) if values: return [iod[key] for key in iod.keys() if iskeyinput(key)] else: return [key for key in iod.keys() if iskeyinput(key)] # return list of input names
[docs] def listoutputs(iod, values=False): """returns a list of the outputs to the control system either their names or their values Args: iod (dict): dictionary of the input and output names and indices or wield.control.mimo iod object values (bool, optional): if True, return the values of the outputs. Defaults to False. Returns: list: list of the output names or values if values is True """ if type(iod) is not dict: try: iod = iod.iod except: iod = dict(iod) if values: return [iod[key] for key in iod.keys() if not iskeyinput(key)] else: return [key for key in iod.keys() if not iskeyinput(key)] # return list of output names
[docs] def connectDicts(d1, d2, inlist=None, outlist=None): """Combine input and output dictionaries Args: d1 (dict): first dictionary d2 (dict): second dictionary inlist (list, optional): list of inputs to connect. Defaults to None. outlist (list, optional): list of outputs to connect. Defaults to None. Returns: dict: combined dictionary """ connectedDict = d1.copy() d1_num_ins = len(listinputs(d1)) d1_num_outs = len(listoutputs(d1)) d2_tmp = d2.copy() for key in d2.keys(): if iskeyinput(key): d2_tmp[key] += d1_num_ins else: d2_tmp[key] += d1_num_outs connectedDict.update(d2_tmp) for key in connectedDict.keys(): if iskeyinput(key) and inlist is not None and connectedDict[key] not in inlist: del connectedDict['key'] if not iskeyinput(key) and outlist is not None and connectedDict[key] not in outlist: del connectedDict['key'] connectedDict = squareDict(connectedDict) return connectedDict
[docs] def squareDict(d): """Square the dictionary by removing any holes in the indices and moving down those with higher indices to fill the holes Args: d (dict): dictionary to square Returns: dict: squared dictionary """ inputs = [] outputs = [] d = d.copy() for key in d.keys(): if iskeyinput(key): inputs.append(d[key]) else: outputs.append(d[key]) inputs.sort() outputs.sort() #missing_inputs = [ele for ele in range(max(inputs)+1) if ele not in inputs] #missing_outputs = [ele for ele in range(max(outputs)+1) if ele not in outputs] for key in d.keys(): if iskeyinput(key): d[key]= inputs.index(d[key]) else: d[key]= outputs.index(d[key]) return d
[docs] def changedictnamespace(dict, namespace, append=False): """Change the namespace of a dictionary. Args: dict (dict): The dictionary to change the namespace of. namespace (str): The new namespace. append (bool): wheather to just append the new name space to the old one 'A.in' becomes 'EA.in' Returns: dict: The dictionary with the new namespace. """ newdict = {} for key, value in dict.items(): if append: newdict[namespace + '.'.join(key.split('.'))] = value else: newdict[namespace + '.' + '.'.join(key.split('.')[1:])] = value return newdict
[docs] def removeIodIndices(iod, inputs_to_remove, outputs_to_remove): """Take an iod and remove the inputs and outputs specified by the indices and or names provided in the `inputs_to_remove` and `outputs_to_remove` lists Args: iod (dict or Bunch): input/output dictionary or bunch system with iod as attribute inputs_to_remove (list): List of indices or names of inputs to remove outputs_to_remove (list): List of indices or names of outputs to remove Returns: dict: Input/output dictionary with the removed inputs and outputs """ # Set the iod so that this function can be passed a Bunch or a dict try: iod = iod.iod except: pass newiod = {} # Create a new iod inputs_removed = 0 # Keep track of how many inputs have been removed outputs_removed = 0 # Keep track of how many outputs have been removed for i in iod.keys(): # Loop over all keys if iskeyinput(i): # If the key is an input if iod[i] not in inputs_to_remove: #and i not in inputs_to_remove: # If the input is not to be removed newiod[i] = iod[i] # Add the input to the new iod else: inputs_removed += 1 # Increment the number of inputs removed else: # If the key is an output if iod[i] not in outputs_to_remove: #and i not in outputs_to_remove: # If the output is not to be removed newiod[i] = iod[i] # Add the output to the new iod else: outputs_removed += 1 # Increment the number of outputs removed # Warn the user if any inputs or outputs were removed if inputs_removed!=len(inputs_to_remove): warnings.warn(f'problem removing inputs: {inputs_removed} inputs removed, {len(inputs_to_remove)} inputs to remove. This error is likely caused by an input being listed that does not exist in the iod.') if outputs_removed!=len(outputs_to_remove): warnings.warn(f'problem removing outputs: {outputs_removed} outputs removed, {len(outputs_to_remove)} outputs to remove. This error is likely caused by an output being listed that does not exist in the iod.') newiod = squareDict(newiod) # Square the new iod return newiod
[docs] def getNamespace(sys): """Get the namespace of a system Args: sys (dict or Bunch): State space model or bunch system with mod as attribute Returns: dict: Namespace """ try: iod = sys.iod except: iod = sys namespace = [] for i in iod.keys(): namespace.append(i[0]) if ([namespace[0]]*len(namespace) == namespace): namespace = namespace[0] else: warnings.warn('Not all keys have the same namespace') print('all namespaces: {}'.format(namespace)) namespace = None return namespace