Skip to content

Commit 99b2d21

Browse files
authored
Release 0.1.19
Merge pull request #65 from PEtab-dev/release_0.1.19
2 parents 0917194 + b6c2333 commit 99b2d21

17 files changed

+2024
-45
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
## 0.1 series
44

5+
### 0.1.19
6+
7+
* Visualization: refactoring (#58) including various bug fixes
8+
* Validation: Fixed detection of missing observable/noise parameter overrides
9+
(#64)
10+
* Optional relative paths in generated YAML (#57)
11+
512
### 0.1.18
613

714
* Fixed various documentation issues
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
plotId xOffset yScale
2+
figure_b 100 log
3+
figure_a 500 lin

petab/C.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,23 @@
124124
Y_SCALE = 'yScale'
125125
LEGEND_ENTRY = 'legendEntry'
126126

127+
VISUALIZATION_DF_REQUIRED_COLS = [PLOT_ID]
128+
129+
VISUALIZATION_DF_OPTIONAL_COLS = [
130+
PLOT_NAME, PLOT_TYPE_SIMULATION, PLOT_TYPE_DATA, X_VALUES, X_OFFSET,
131+
X_LABEL, X_SCALE, Y_VALUES, Y_OFFSET, Y_LABEL, Y_SCALE, LEGEND_ENTRY,
132+
DATASET_ID]
133+
134+
VISUALIZATION_DF_COLS = [
135+
*VISUALIZATION_DF_REQUIRED_COLS, *VISUALIZATION_DF_OPTIONAL_COLS]
136+
137+
VISUALIZATION_DF_SUBPLOT_LEVEL_COLS = [
138+
PLOT_ID, PLOT_NAME, PLOT_TYPE_SIMULATION, PLOT_TYPE_DATA,
139+
X_LABEL, X_SCALE, Y_LABEL, Y_SCALE]
140+
141+
VISUALIZATION_DF_SINGLE_PLOT_LEVEL_COLS = [
142+
X_VALUES, X_OFFSET, Y_VALUES, Y_OFFSET, LEGEND_ENTRY, DATASET_ID]
143+
127144
LINE_PLOT = 'LinePlot'
128145
BAR_PLOT = 'BarPlot'
129146
SCATTER_PLOT = 'ScatterPlot'

petab/measurements.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -289,13 +289,13 @@ def assert_overrides_match_parameter_count(
289289
actual = len(split_parameter_replacement_list(
290290
row.get(OBSERVABLE_PARAMETERS, None)))
291291
# No overrides are also allowed
292-
if actual not in [0, expected]:
292+
if actual != expected:
293293
formula = observable_df.loc[row[OBSERVABLE_ID], OBSERVABLE_FORMULA]
294294
raise AssertionError(
295295
f'Mismatch of observable parameter overrides for '
296296
f'{row[OBSERVABLE_ID]} ({formula})'
297297
f'in:\n{row}\n'
298-
f'Expected 0 or {expected} but got {actual}')
298+
f'Expected {expected} but got {actual}')
299299

300300
# check noise parameters
301301
replacements = split_parameter_replacement_list(
@@ -304,10 +304,10 @@ def assert_overrides_match_parameter_count(
304304
expected = noise_parameters_count[row[OBSERVABLE_ID]]
305305

306306
# No overrides are also allowed
307-
if not (len(replacements) == 0 or len(replacements) == expected):
307+
if len(replacements) != expected:
308308
raise AssertionError(
309309
f'Mismatch of noise parameter overrides in:\n{row}\n'
310-
f'Expected 0 or {expected} but got {actual}')
310+
f'Expected {expected} but got {actual}')
311311
except KeyError:
312312
# no overrides defined, but a numerical sigma can be provided
313313
# anyways

petab/parameter_mapping.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -360,14 +360,7 @@ def _apply_overrides_for_observable(
360360
"""
361361
for i, override in enumerate(overrides):
362362
overridee_id = f'{override_type}Parameter{i+1}_{observable_id}'
363-
try:
364-
mapping[overridee_id] = override
365-
except KeyError as e:
366-
raise TypeError(f'Cannot override {override_type} parameter '
367-
f'{overridee_id} for observable {observable_id}.'
368-
f'Ensure there exists an {override_type} '
369-
'definition containing the correct number of '
370-
'placeholder parameters.') from e
363+
mapping[overridee_id] = override
371364

372365

373366
def _apply_condition_parameters(par_mapping: ParMappingDict,

petab/problem.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,8 @@ def to_files(self,
271271
parameter_file: Optional[str] = None,
272272
visualization_file: Optional[str] = None,
273273
observable_file: Optional[str] = None,
274-
yaml_file: Optional[str] = None) -> None:
274+
yaml_file: Optional[str] = None,
275+
relative_paths: bool = True,) -> None:
275276
"""
276277
Write PEtab tables to files for this problem
277278
@@ -289,6 +290,9 @@ def to_files(self,
289290
visualization_file: Visualization table destination
290291
observable_file: Observables table destination
291292
yaml_file: YAML file destination
293+
relative_paths: whether all paths in the YAML file should be
294+
relative to the location of the YAML file. If `False`, then paths
295+
are left unchanged.
292296
293297
Raises:
294298
ValueError:
@@ -344,7 +348,8 @@ def error(name: str) -> ValueError:
344348
yaml.create_problem_yaml(sbml_file, condition_file,
345349
measurement_file, parameter_file,
346350
observable_file, yaml_file,
347-
visualization_file)
351+
visualization_file,
352+
relative_paths=relative_paths,)
348353

349354
def get_optimization_parameters(self):
350355
"""

petab/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
"""PEtab library version"""
2-
__version__ = '0.1.18'
2+
__version__ = '0.1.19'

petab/visualize/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@
1010
from .plot_data_and_simulation import (plot_data_and_simulation,
1111
plot_petab_problem,
1212
plot_measurements_by_observable,
13+
plot_without_vis_spec,
14+
plot_with_vis_spec,
15+
plot_problem,
1316
save_vis_spec)
1417

1518
__all__ = ["plot_data_and_simulation",
1619
"plot_petab_problem",
1720
"plot_measurements_by_observable",
21+
"plot_without_vis_spec",
22+
"plot_with_vis_spec",
23+
"plot_problem",
1824
"save_vis_spec"
1925
]

petab/visualize/helper_functions.py

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
from typing import Dict, List, Optional, Tuple, Union
2222

23-
sns.set()
23+
# sns.set() This messes up plotting settings if one just imports this file
2424

2525
# for typehints
2626
IdsList = List[str]
@@ -42,14 +42,16 @@ def import_from_files(
4242
"""
4343
Helper function for plotting data and simulations, which imports data
4444
from PEtab files. If `visualization_file_path` is not provided, the
45-
visualisation specification DataFrame will be generated automatically.
45+
visualization specification DataFrame will be generated automatically.
4646
4747
For documentation, see main function plot_data_and_simulation()
4848
4949
Returns:
5050
A tuple of experimental data, experimental conditions,
5151
visualization specification and simulation data DataFrames.
5252
"""
53+
warnings.warn("This function will be removed in future releases. ",
54+
DeprecationWarning)
5355

5456
# import measurement data and experimental condition
5557
exp_data = petab.get_measurement_df(data_file_path)
@@ -95,6 +97,8 @@ def check_vis_spec_consistency(
9597
group_by:
9698
Specifies the grouping of data to plot.
9799
"""
100+
warnings.warn("This function will be removed in future releases. ",
101+
DeprecationWarning)
98102

99103
# We have no vis_spec file. Check how data should be grouped
100104
group_by = ''
@@ -187,6 +191,9 @@ def create_dataset_id_list(
187191
188192
For additional documentation, see main function plot_data_and_simulation()
189193
"""
194+
warnings.warn("This function will be removed in future releases. ",
195+
DeprecationWarning)
196+
190197
# create a column of dummy datasetIDs and legend entries: preallocate
191198
dataset_id_column = []
192199
legend_dict = {}
@@ -197,7 +204,7 @@ def create_dataset_id_list(
197204
tmp_obs = list(exp_data[OBSERVABLE_ID])
198205
for ind, cond_id in enumerate(tmp_simcond):
199206
# create and add dummy datasetID
200-
dataset_id = tmp_simcond[ind] + '_' + tmp_obs[ind]
207+
dataset_id = cond_id + '_' + tmp_obs[ind]
201208
dataset_id_column.append(dataset_id)
202209

203210
# create nicer legend entries from condition names instead of IDs
@@ -272,6 +279,77 @@ def create_dataset_id_list(
272279
return exp_data, dataset_id_list, legend_dict, yvalues_dict
273280

274281

282+
def generate_dataset_id_col(exp_data: pd.DataFrame) -> List[str]:
283+
"""
284+
generate DATASET_ID column from condition_ids and observable_ids
285+
286+
Parameters
287+
----------
288+
exp_data
289+
290+
Returns
291+
-------
292+
293+
"""
294+
295+
# create a column of dummy datasetIDs and legend entries: preallocate
296+
dataset_id_column = []
297+
298+
# loop over experimental data table, create datasetId for each entry
299+
tmp_simcond = list(exp_data[SIMULATION_CONDITION_ID])
300+
tmp_obs = list(exp_data[OBSERVABLE_ID])
301+
302+
for ind, cond_id in enumerate(tmp_simcond):
303+
# create and add dummy datasetID
304+
dataset_id = cond_id + '_' + tmp_obs[ind]
305+
dataset_id_column.append(dataset_id)
306+
307+
return dataset_id_column
308+
309+
310+
def create_dataset_id_list_new(df: pd.DataFrame,
311+
group_by: str,
312+
id_list: List[IdsList]
313+
) -> List[IdsList]:
314+
"""
315+
Create dataset id list.
316+
317+
Parameters:
318+
df: measurements or simulations df
319+
group_by: defines grouping of data to plot
320+
id_list:
321+
322+
Returns:
323+
A list of datasetIds
324+
325+
"""
326+
if DATASET_ID not in df.columns:
327+
raise ValueError(f'{DATASET_ID} column must be in exp_data DataFrame')
328+
329+
dataset_id_list = []
330+
331+
if group_by == 'simulation':
332+
groupping_col = SIMULATION_CONDITION_ID
333+
elif group_by == 'observable':
334+
groupping_col = OBSERVABLE_ID
335+
if id_list is None:
336+
# this is the default case. If no grouping is specified,
337+
# all observables are plotted. One observable per plot.
338+
unique_obs_list = df[OBSERVABLE_ID].unique()
339+
id_list = [[obs_id] for obs_id in unique_obs_list]
340+
else:
341+
raise ValueError
342+
343+
for sublist in id_list:
344+
plot_id_list = []
345+
for cond_id in sublist:
346+
plot_id_list.extend(list(
347+
df[df[groupping_col] == cond_id][
348+
DATASET_ID].unique()))
349+
dataset_id_list.append(plot_id_list)
350+
return dataset_id_list
351+
352+
275353
def create_figure(
276354
uni_plot_ids: np.ndarray,
277355
plots_to_file: bool) -> Tuple[plt.Figure,
@@ -292,6 +370,8 @@ def create_figure(
292370
fig: Figure object of the created plot.
293371
ax: Axis object of the created plot.
294372
"""
373+
warnings.warn("This function will be removed in future releases. ",
374+
DeprecationWarning)
295375

296376
# Set Options for plots
297377
# possible options: see: plt.rcParams.keys()
@@ -415,6 +495,8 @@ def get_vis_spec_dependent_columns_dict(
415495
columns PLOT_ID, DATASET_ID, LEGEND_ENTRY, Y_VALUES for visualization
416496
specification file.
417497
"""
498+
warnings.warn("This function will be removed in future releases. ",
499+
DeprecationWarning)
418500

419501
# check consistency of settings
420502
group_by = check_vis_spec_consistency(
@@ -533,6 +615,9 @@ def create_or_update_vis_spec(
533615
A tuple of visualization specification DataFrame and experimental
534616
DataFrame.
535617
"""
618+
warnings.warn("This function will be removed in future releases. ",
619+
DeprecationWarning)
620+
536621
if vis_spec is None:
537622
# create dataframe
538623
exp_data, columns_dict = \
@@ -572,7 +657,9 @@ def create_or_update_vis_spec(
572657
vis_spec = expand_vis_spec_settings(vis_spec, columns_dict)
573658

574659
# if dataset_id is there, then nothing to expand?
575-
vis_spec[PLOT_TYPE_DATA] = plotted_noise
660+
661+
if PLOT_TYPE_DATA not in vis_spec.columns:
662+
vis_spec[PLOT_TYPE_DATA] = plotted_noise
576663

577664
# check columns, and add non-mandatory default columns
578665
vis_spec = check_ex_visu_columns(vis_spec, exp_data, exp_conditions)
@@ -589,6 +676,9 @@ def check_ex_visu_columns(vis_spec: pd.DataFrame,
589676
Returns:
590677
Updated visualization specification DataFrame
591678
"""
679+
warnings.warn("This function will be removed in future releases. ",
680+
DeprecationWarning)
681+
592682
if PLOT_NAME not in vis_spec.columns:
593683
vis_spec[PLOT_NAME] = ''
594684
if PLOT_TYPE_SIMULATION not in vis_spec.columns:
@@ -658,6 +748,9 @@ def check_ex_exp_columns(
658748
A tuple of experimental DataFrame, list of datasetIds and
659749
dictionary of plot legends, corresponding to the datasetIds
660750
"""
751+
warnings.warn("This function will be removed in future releases. ",
752+
DeprecationWarning)
753+
661754
data_type = MEASUREMENT
662755
if sim:
663756
data_type = SIMULATION
@@ -692,6 +785,7 @@ def check_ex_exp_columns(
692785
value='')
693786
legend_dict = {}
694787
if DATASET_ID not in exp_data.columns:
788+
# TODO: ?
695789
if dataset_id_list is not None:
696790
exp_data.insert(loc=4, column=DATASET_ID,
697791
value=dataset_id_list)
@@ -712,6 +806,7 @@ def check_ex_exp_columns(
712806
sim_cond_id_list, sim_cond_num_list, observable_id_list,
713807
observable_num_list, exp_data, exp_conditions, group_by)
714808

809+
# if DATASET_ID is in exp_data.columns, legend dict will be empty
715810
return exp_data, dataset_id_list, legend_dict
716811

717812

@@ -723,6 +818,9 @@ def handle_dataset_plot(plot_spec: pd.Series,
723818
"""
724819
Handle dataset plot
725820
"""
821+
warnings.warn("This function will be removed in future releases. ",
822+
DeprecationWarning)
823+
726824
# get datasetID and independent variable of first entry of plot1
727825
dataset_id = plot_spec[DATASET_ID]
728826
indep_var = plot_spec[X_VALUES]
@@ -795,6 +893,9 @@ def matches_plot_spec(df: pd.DataFrame,
795893
Boolean series that can be used for subsetting of the passed
796894
dataframe
797895
"""
896+
warnings.warn("This function will be removed in future releases. ",
897+
DeprecationWarning)
898+
798899
subset = (
799900
(df[col_id] == x_value) &
800901
(df[DATASET_ID] == plot_spec[DATASET_ID])
@@ -843,6 +944,8 @@ def get_data_to_plot(plot_spec: pd.Series,
843944
Contains the data which should be plotted
844945
(Mean and Std)
845946
"""
947+
warnings.warn("This function will be removed in future releases. ",
948+
DeprecationWarning)
846949

847950
# create empty dataframe for means and SDs
848951
data_to_plot = pd.DataFrame(

0 commit comments

Comments
 (0)