mirror of
https://github.com/fjosw/pyerrors.git
synced 2026-08-04 11:31:21 +02:00
[Fix] Removed the possibility to create an Obs from data on several replica (#258)
* [Fix] Removed the possibility to create an Obs from data on several replica * [Fix] extended tests and corrected a small bug in the previous commit --------- Co-authored-by: Simon Kuberski <simon.kuberski@cern.ch>
This commit is contained in:
parent
dd4f8525f7
commit
17792418ed
6 changed files with 111 additions and 61 deletions
|
|
@ -529,7 +529,8 @@ def import_dobs_string(content, full_output=False, separator_insertion=True):
|
|||
deltas.append(repdeltas)
|
||||
idl.append(repidl)
|
||||
|
||||
res.append(Obs(deltas, obs_names, idl=idl))
|
||||
obsmeans = [np.average(deltas[j]) for j in range(len(deltas))]
|
||||
res.append(Obs([np.array(deltas[j]) - obsmeans[j] for j in range(len(obsmeans))], obs_names, idl=idl, means=obsmeans))
|
||||
res[-1]._value = mean[i]
|
||||
_check(len(e_names) == ne)
|
||||
|
||||
|
|
|
|||
|
|
@ -133,10 +133,11 @@ def create_json_string(ol, description='', indent=1):
|
|||
names = []
|
||||
idl = []
|
||||
for key, value in obs.idl.items():
|
||||
samples.append([np.nan] * len(value))
|
||||
samples.append(np.array([np.nan] * len(value)))
|
||||
names.append(key)
|
||||
idl.append(value)
|
||||
my_obs = Obs(samples, names, idl)
|
||||
my_obs = Obs(samples, names, idl, means=[np.nan for n in names])
|
||||
my_obs._value = np.nan
|
||||
my_obs._covobs = obs._covobs
|
||||
for name in obs._covobs:
|
||||
my_obs.names.append(name)
|
||||
|
|
@ -331,7 +332,8 @@ def _parse_json_dict(json_dict, verbose=True, full_output=False):
|
|||
cd = _gen_covobsd_from_cdatad(o.get('cdata', {}))
|
||||
|
||||
if od:
|
||||
ret = Obs([[ddi[0] + values[0] for ddi in di] for di in od['deltas']], od['names'], idl=od['idl'])
|
||||
r_offsets = [np.average([ddi[0] for ddi in di]) for di in od['deltas']]
|
||||
ret = Obs([np.array([ddi[0] for ddi in od['deltas'][i]]) - r_offsets[i] for i in range(len(od['deltas']))], od['names'], idl=od['idl'], means=[ro + values[0] for ro in r_offsets])
|
||||
ret._value = values[0]
|
||||
else:
|
||||
ret = Obs([], [], means=[])
|
||||
|
|
@ -356,7 +358,8 @@ def _parse_json_dict(json_dict, verbose=True, full_output=False):
|
|||
taglist = o.get('tag', layout * [None])
|
||||
for i in range(layout):
|
||||
if od:
|
||||
ret.append(Obs([list(di[:, i] + values[i]) for di in od['deltas']], od['names'], idl=od['idl']))
|
||||
r_offsets = np.array([np.average(di[:, i]) for di in od['deltas']])
|
||||
ret.append(Obs([od['deltas'][j][:, i] - r_offsets[j] for j in range(len(od['deltas']))], od['names'], idl=od['idl'], means=[ro + values[i] for ro in r_offsets]))
|
||||
ret[-1]._value = values[i]
|
||||
else:
|
||||
ret.append(Obs([], [], means=[]))
|
||||
|
|
@ -383,7 +386,8 @@ def _parse_json_dict(json_dict, verbose=True, full_output=False):
|
|||
taglist = o.get('tag', N * [None])
|
||||
for i in range(N):
|
||||
if od:
|
||||
ret.append(Obs([di[:, i] + values[i] for di in od['deltas']], od['names'], idl=od['idl']))
|
||||
r_offsets = np.array([np.average(di[:, i]) for di in od['deltas']])
|
||||
ret.append(Obs([od['deltas'][j][:, i] - r_offsets[j] for j in range(len(od['deltas']))], od['names'], idl=od['idl'], means=[ro + values[i] for ro in r_offsets]))
|
||||
ret[-1]._value = values[i]
|
||||
else:
|
||||
ret.append(Obs([], [], means=[]))
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ class Obs:
|
|||
raise ValueError('Names are not unique.')
|
||||
if not all(isinstance(x, str) for x in names):
|
||||
raise TypeError('All names have to be strings.')
|
||||
if len(set([o.split('|')[0] for o in names])) > 1:
|
||||
raise ValueError('Cannot initialize Obs based on multiple ensembles. Please average separate Obs from each ensemble.')
|
||||
else:
|
||||
if not isinstance(names[0], str):
|
||||
raise TypeError('All names have to be strings.')
|
||||
|
|
@ -1407,6 +1409,8 @@ def reweight(weight, obs, **kwargs):
|
|||
raise ValueError('Error: Not possible to reweight an Obs that contains covobs!')
|
||||
if not set(obs[i].names).issubset(weight.names):
|
||||
raise ValueError('Error: Ensembles do not fit')
|
||||
if len(obs[i].mc_names) > 1 or len(weight.mc_names) > 1:
|
||||
raise ValueError('Error: Cannot reweight an Obs that contains multiple ensembles.')
|
||||
for name in obs[i].names:
|
||||
if not set(obs[i].idl[name]).issubset(weight.idl[name]):
|
||||
raise ValueError('obs[%d] has to be defined on a subset of the configs in weight.idl[%s]!' % (i, name))
|
||||
|
|
@ -1442,9 +1446,12 @@ def correlate(obs_a, obs_b):
|
|||
-----
|
||||
Keep in mind to only correlate primary observables which have not been reweighted
|
||||
yet. The reweighting has to be applied after correlating the observables.
|
||||
Currently only works if ensembles are identical (this is not strictly necessary).
|
||||
Only works if a single ensemble is present in the Obs.
|
||||
Currently only works if ensemble content is identical (this is not strictly necessary).
|
||||
"""
|
||||
|
||||
if len(obs_a.mc_names) > 1 or len(obs_b.mc_names) > 1:
|
||||
raise ValueError('Error: Cannot correlate Obs that contain multiple ensembles.')
|
||||
if sorted(obs_a.names) != sorted(obs_b.names):
|
||||
raise ValueError(f"Ensembles do not fit {set(sorted(obs_a.names)) ^ set(sorted(obs_b.names))}")
|
||||
if len(obs_a.cov_names) or len(obs_b.cov_names):
|
||||
|
|
@ -1755,7 +1762,11 @@ def import_bootstrap(boots, name, random_numbers):
|
|||
|
||||
|
||||
def merge_obs(list_of_obs):
|
||||
"""Combine all observables in list_of_obs into one new observable
|
||||
"""Combine all observables in list_of_obs into one new observable.
|
||||
This allows to merge Obs that have been computed on multiple replica
|
||||
of the same ensemble.
|
||||
If you like to merge Obs that are based on several ensembles, please
|
||||
average them yourself.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue