Newer
Older
from multikeydict.nestedmkdict import NestedMKDict
from multikeydict.visitor import NestedMKDictVisitor
from typing import Union, Tuple, List, Optional
from tabulate import tabulate
from pandas import DataFrame
import pandas as pd
pd.set_option('display.max_rows', None)
pd.set_option('display.max_colwidth', 100)
from shutil import get_terminal_size
def trunc(text: str, width: int) -> str:
return '\n'.join(line[:width] for line in text.split('\n'))
class ParametersStorage(NestedMKDict):
def to_dict(self, **kwargs) -> list:
return self.visit(ParametersVisitor(kwargs)).data
def to_df(self, *, columns: Optional[List[str]]=None, **kwargs) -> DataFrame:
dct = self.to_dict(**kwargs)
if columns is None:
columns = ['path', 'value', 'central', 'sigma', 'label']
df = DataFrame(dct, columns=columns)
df.insert(4, 'sigma_rel_perc', df['sigma'])
df['sigma_rel_perc'] = df['sigma']/df['central']*100.
df['sigma_rel_perc'].mask(df['central']==0, nan, inplace=True)
for key in ('central', 'sigma', 'sigma_rel_perc'):
if df[key].isna().all():
del df[key]
else:
df[key].fillna('-', inplace=True)
df['value'].fillna('-', inplace=True)
df['label'].fillna('', inplace=True)
return df
def to_string(self, **kwargs) -> str:
df = self.to_df()
return df.to_string(**kwargs)
def to_table(
self,
*,
df_kwargs: dict={},
truncate: Union[int, bool] = False,
**kwargs
) -> str:
df = self.to_df(**df_kwargs)
kwargs.setdefault('headers', df.columns)
ret = tabulate(df, **kwargs)
if truncate:
if isinstance(truncate, bool):
truncate = get_terminal_size().columns
return trunc(ret, width=truncate)
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
return ret
def to_latex(self, *, return_df: bool=False, **kwargs) -> Union[str, Tuple[str, DataFrame]]:
df = self.to_df(label_from='latex', **kwargs)
tex = df.to_latex(escape=False)
if return_df:
return tex, df
return tex
class ParametersVisitor(NestedMKDictVisitor):
__slots__ = ('_kwargs', '_data', '_localdata', '_path')
_kwargs: dict
_data: List[dict]
_localdata: List[dict]
_paths: List[Tuple[str, ...]]
_path: Tuple[str, ...]
# _npars: List[int]
def __init__(self, kwargs: dict):
self._kwargs = kwargs
# self._npars = []
@property
def data(self):
return self._data
def start(self, dct):
self._data = []
self._path = ()
self._paths = []
self._localdata = []
def enterdict(self, k, v):
if self._localdata:
self.exitdict(self._path, None)
self._path = k
self._paths.append(self._path)
self._localdata = []
def visit(self, key, value):
try:
dct = value.to_dict(**self._kwargs)
except AttributeError:
return
subkey = key[len(self._path):]
subkeystr = '.'.join(subkey)
if self._path:
dct['path'] = f'.. {subkeystr}'
else:
dct['path'] = subkeystr
self._localdata.append(dct)
def exitdict(self, k, v):
if self._localdata:
self._data.append({
'path': f"group: {'.'.join(self._path)} [{len(self._localdata)}]"
})
self._data.extend(self._localdata)
self._localdata = []
if self._paths:
del self._paths[-1]
self._path = self._paths[-1] if self._paths else ()
def stop(self, dct):
pass