forked from IPKM/nmreval
bugfix eval expression; closes #83
This commit is contained in:
parent
91afe8224f
commit
fbf4246c7e
@ -438,7 +438,7 @@ class ExperimentContainer(QtCore.QObject):
|
|||||||
if (i is None) and (j is None):
|
if (i is None) and (j is None):
|
||||||
prefix = ''
|
prefix = ''
|
||||||
else:
|
else:
|
||||||
prefix = 'g[%i].s[%i].' % (i, j)
|
prefix = f'g[{i}].s[{j}].'
|
||||||
|
|
||||||
namespace = {prefix + 'x': (self.x, 'x values'),
|
namespace = {prefix + 'x': (self.x, 'x values'),
|
||||||
prefix + 'y': [self.y, 'y values'],
|
prefix + 'y': [self.y, 'y values'],
|
||||||
@ -459,16 +459,33 @@ class ExperimentContainer(QtCore.QObject):
|
|||||||
|
|
||||||
return namespace
|
return namespace
|
||||||
|
|
||||||
def eval_expression(self, cmds, namespace):
|
def eval_expression(self, cmds, namespace, i=None, j=None):
|
||||||
namespace.update({'x': self._data.x, 'y': self._data.y, 'y_err': self._data.y_err, 'value': self.value})
|
if i is not None:
|
||||||
|
namespace['i'] = i
|
||||||
|
|
||||||
if len(self._fits) == 1:
|
if j is not None:
|
||||||
namespace.update({"fit['%s']" % (convert(pname, old='tex', new='str')): pvalue.value
|
namespace['j'] = j
|
||||||
for (pname, pvalue) in self._manager[self._fits[0]].parameter.items()})
|
|
||||||
|
namespace.update({'x': self._data.x, 'y': self._data.y, 'y_err': self._data.y_err, 'value': self.value})
|
||||||
|
namespace['fit'] = {}
|
||||||
|
|
||||||
|
if isinstance(self, FitContainer):
|
||||||
|
namespace['fit'].update({
|
||||||
|
'%s' % convert(pname, old='latex', new='plain'): pvalue.value
|
||||||
|
for (pname, pvalue) in self._data.parameter.items()
|
||||||
|
})
|
||||||
|
|
||||||
|
elif len(self._fits) == 1:
|
||||||
|
namespace['fit'].update({
|
||||||
|
'%s' % convert(pname, old='tex', new='str'): pvalue.value
|
||||||
|
for (pname, pvalue) in self._manager[self._fits[0]].parameter.items()
|
||||||
|
})
|
||||||
else:
|
else:
|
||||||
for k, f in enumerate(self._fits):
|
for k, f in enumerate(self._fits):
|
||||||
namespace.update({"fit['%s_%i']" % (convert(pname, old='tex', new='str'), k): pvalue.value
|
namespace['fit'].update({
|
||||||
for (pname, pvalue) in self._manager[f].parameter.items()})
|
"%s_%i" % (convert(pname, old='tex', new='str'), k): pvalue.value
|
||||||
|
for (pname, pvalue) in self._manager[f].parameter.items()
|
||||||
|
})
|
||||||
|
|
||||||
new_data = self.copy()
|
new_data = self.copy()
|
||||||
for c in cmds:
|
for c in cmds:
|
||||||
|
@ -21,36 +21,53 @@ class Namespace:
|
|||||||
self.top_levels = {}
|
self.top_levels = {}
|
||||||
|
|
||||||
if basic:
|
if basic:
|
||||||
self.add_namespace({'x': (None, 'x values'), 'y': (None, 'x values'), 'y_err': (None, 'y error values'),
|
self.add_namespace(
|
||||||
'fit': (None, 'dictionary of fit parameter', 'fit["PIKA"]'), 'np': (np, 'numpy module')},
|
{'x': (None, 'x values'),
|
||||||
parents=('Basic', 'General'))
|
'y': (None, 'x values'),
|
||||||
|
'y_err': (None, 'y error values'),
|
||||||
|
'fit': (None, 'dictionary of fit parameter', 'fit["PIKA"]'),
|
||||||
|
'np': (np, 'numpy module'),
|
||||||
|
},
|
||||||
|
parents=('Basic', 'General'),
|
||||||
|
)
|
||||||
|
|
||||||
self.add_namespace({'sin': (np.sin, 'Sine', 'sin(PIKA)'), 'cos': (np.cos, 'Cosine', 'cos(PIKA)'),
|
self.add_namespace(
|
||||||
'tan': (np.tan, 'Tangens', 'tan(PIKA)'), 'ln': (np.log, 'Natural Logarithm', 'ln(PIKA)'),
|
{'sin': (np.sin, 'Sine', 'sin(PIKA)'),
|
||||||
|
'cos': (np.cos, 'Cosine', 'cos(PIKA)'),
|
||||||
|
'tan': (np.tan, 'Tangens', 'tan(PIKA)'),
|
||||||
|
'ln': (np.log, 'Natural Logarithm', 'ln(PIKA)'),
|
||||||
'log': (np.log10, 'Logarithm (base 10)', 'log(PIKA)'),
|
'log': (np.log10, 'Logarithm (base 10)', 'log(PIKA)'),
|
||||||
'exp': (np.exp, 'Exponential', 'exp(PIKA)'), 'sqrt': (np.sqrt, 'Root', 'sqrt(PIKA)'),
|
'exp': (np.exp, 'Exponential', 'exp(PIKA)'),
|
||||||
'lin_range': (np.linspace, 'N evenly spaced over interval [start, stop]',
|
'sqrt': (np.sqrt, 'Root', 'sqrt(PIKA)'),
|
||||||
'lin_range(start, stop, N)'),
|
'lin_range': (np.linspace, 'N evenly spaced over interval [start, stop]', 'lin_range(start, stop, N)'),
|
||||||
'log_range': (np.geomspace, 'N evenly spaced (log-scale) over interval [start, stop]',
|
'log_range': (np.geomspace, 'N evenly spaced (log-scale) over interval [start, stop]', 'lin_range(start, stop, N)'),
|
||||||
'lin_range(start, stop, N)')},
|
},
|
||||||
parents=('Basic', 'Functions'))
|
parents=('Basic', 'Functions'))
|
||||||
|
|
||||||
self.add_namespace({'max': (np.max, 'Maximum value', 'max(PIKA)'),
|
self.add_namespace(
|
||||||
|
{'max': (np.max, 'Maximum value', 'max(PIKA)'),
|
||||||
'min': (np.min, 'Minimum value', 'min(PIKA)'),
|
'min': (np.min, 'Minimum value', 'min(PIKA)'),
|
||||||
'argmax': (np.argmax, 'Index of maximum value', 'argmax(PIKA)'),
|
'argmax': (np.argmax, 'Index of maximum value', 'argmax(PIKA)'),
|
||||||
'argmin': (np.argmax, 'Index of minimum value', 'argmin(PIKA)')},
|
'argmin': (np.argmax, 'Index of minimum value', 'argmin(PIKA)'),
|
||||||
parents=('Basic', 'Values'))
|
},
|
||||||
|
parents=('Basic', 'Values')),
|
||||||
|
|
||||||
if const:
|
if const:
|
||||||
self.add_namespace({'e': (constants.e, 'e / As'), 'eps0': (constants.epsilon0, 'epsilon0 / As/Vm'),
|
self.add_namespace(
|
||||||
|
{'e': (constants.e, 'e / As'),
|
||||||
|
'eps0': (constants.epsilon0, 'epsilon0 / As/Vm'),
|
||||||
'Eu': (constants.Eu,), 'h': (constants.h, 'h / eVs'),
|
'Eu': (constants.Eu,), 'h': (constants.h, 'h / eVs'),
|
||||||
'hbar': (constants.hbar, 'hbar / eVs'), 'kB': (constants.kB, 'kB / eV/K'),
|
'hbar': (constants.hbar, 'hbar / eVs'), 'kB': (constants.kB, 'kB / eV/K'),
|
||||||
'mu0': (constants.mu0, 'mu0 / Vs/Am'), 'NA': (constants.NA, 'NA / 1/mol'),
|
'mu0': (constants.mu0, 'mu0 / Vs/Am'), 'NA': (constants.NA, 'NA / 1/mol'),
|
||||||
'pi': (constants.pi,), 'R': (constants.R, 'R / eV')},
|
'pi': (constants.pi,), 'R': (constants.R, 'R / eV'),
|
||||||
parents=('Constants', 'Maybe useful'))
|
},
|
||||||
|
parents=('Constants', 'Maybe useful'),
|
||||||
|
)
|
||||||
|
|
||||||
self.add_namespace({f'gamma["{k}"]': (v, k, f'gamma["{k}"]') for k, v in constants.gamma.items()},
|
self.add_namespace(
|
||||||
parents=('Constants', 'Magnetogyric ratios (in 1/(sT))'))
|
{f'gamma["{k}"]': (v, k, f'gamma["{k}"]') for k, v in constants.gamma.items()},
|
||||||
|
parents=('Constants', 'Magnetogyric ratios (in 1/(sT))')
|
||||||
|
)
|
||||||
|
|
||||||
if fitfuncs:
|
if fitfuncs:
|
||||||
self.make_dict_from_fitmodule(models)
|
self.make_dict_from_fitmodule(models)
|
||||||
@ -104,9 +121,18 @@ class Namespace:
|
|||||||
graph = namedtuple('graphs', ['s'])
|
graph = namedtuple('graphs', ['s'])
|
||||||
sets = namedtuple('sets', ['x', 'y', 'y_err', 'value', 'fit'], defaults=(None,))
|
sets = namedtuple('sets', ['x', 'y', 'y_err', 'value', 'fit'], defaults=(None,))
|
||||||
|
|
||||||
|
gamma = {}
|
||||||
|
|
||||||
gs = re.compile(r'g\[(\d+)].s\[(\d+)].(x|y(?:_err)*|value|fit)')
|
gs = re.compile(r'g\[(\d+)].s\[(\d+)].(x|y(?:_err)*|value|fit)')
|
||||||
|
gamma_re = re.compile(r'gamma\["(\w+)"\]')
|
||||||
|
|
||||||
for k, v in self.namespace.items():
|
for k, v in self.namespace.items():
|
||||||
|
m = gamma_re.match(k)
|
||||||
|
if m:
|
||||||
|
gamma[m.group(1)] = v[0]
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
m = gs.match(k)
|
m = gs.match(k)
|
||||||
if m:
|
if m:
|
||||||
if 'g' not in ret_dic:
|
if 'g' not in ret_dic:
|
||||||
@ -118,7 +144,7 @@ class Namespace:
|
|||||||
|
|
||||||
gg = ret_dic['g'][int(g_num)]
|
gg = ret_dic['g'][int(g_num)]
|
||||||
if int(s_num) not in gg.s:
|
if int(s_num) not in gg.s:
|
||||||
gg.s[int(s_num)] = sets('', '', '', '')
|
gg.s[int(s_num)] = sets('', '', '', '', {})
|
||||||
|
|
||||||
ss = gg.s[int(s_num)]
|
ss = gg.s[int(s_num)]
|
||||||
if pos == 'fit':
|
if pos == 'fit':
|
||||||
@ -130,9 +156,12 @@ class Namespace:
|
|||||||
else:
|
else:
|
||||||
ret_dic['g'][int(g_num)].s[int(s_num)] = ss._replace(**{pos: v[0]})
|
ret_dic['g'][int(g_num)].s[int(s_num)] = ss._replace(**{pos: v[0]})
|
||||||
|
|
||||||
else:
|
continue
|
||||||
|
|
||||||
ret_dic[k] = v[0]
|
ret_dic[k] = v[0]
|
||||||
|
|
||||||
|
ret_dic['gamma'] = gamma
|
||||||
|
|
||||||
return ret_dic
|
return ret_dic
|
||||||
|
|
||||||
|
|
||||||
|
@ -939,11 +939,16 @@ class UpperManagement(QtCore.QObject):
|
|||||||
self.undostack.beginMacro('Evaluate expression')
|
self.undostack.beginMacro('Evaluate expression')
|
||||||
|
|
||||||
failures = []
|
failures = []
|
||||||
for sid in set_ids:
|
for i, g in enumerate(self.graphs.values()):
|
||||||
|
for j, sid in enumerate(g.sets):
|
||||||
|
|
||||||
|
if sid not in set_ids:
|
||||||
|
continue
|
||||||
|
|
||||||
data_i = self.data[sid]
|
data_i = self.data[sid]
|
||||||
try:
|
try:
|
||||||
# use a copy of original namespace
|
# use a copy of original namespace
|
||||||
new_data = data_i.eval_expression(cmds, dict(ns))
|
new_data = data_i.eval_expression(cmds, dict(ns), i=i, j=j)
|
||||||
if overwrite:
|
if overwrite:
|
||||||
cmd = EvalCommand(self.data, sid, new_data, 'Evaluate expression')
|
cmd = EvalCommand(self.data, sid, new_data, 'Evaluate expression')
|
||||||
self.undostack.push(cmd)
|
self.undostack.push(cmd)
|
||||||
|
Loading…
Reference in New Issue
Block a user