Skip to content

Commit 88f570a

Browse files
FFroehlichdweindl
andauthored
fix timepoint specific mapping check (#44)
* update using AMICI implementation * Update petab/lint.py Co-authored-by: Daniel Weindl <[email protected]> Co-authored-by: Daniel Weindl <[email protected]>
1 parent a1d3d80 commit 88f570a

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

petab/lint.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import logging
55
import numbers
66
import re
7-
from typing import Optional, Iterable
7+
from typing import Optional, Iterable, Union
88
from collections import Counter
99

1010
import libsbml
@@ -542,12 +542,29 @@ def measurement_table_has_timepoint_specific_mappings(
542542
# since we edit it, copy it first
543543
measurement_df = copy.deepcopy(measurement_df)
544544

545-
if NOISE_PARAMETERS not in measurement_df:
546-
measurement_df[NOISE_PARAMETERS] = np.nan
547-
548-
measurement_df.loc[
549-
measurement_df.noiseParameters.apply(isinstance, args=(
550-
numbers.Number,)), NOISE_PARAMETERS] = np.nan
545+
def is_numeric(x: Union[str, numbers.Number]) -> bool:
546+
"""
547+
Checks whether x can be transformed into a (list of) float(s)
548+
:param x:
549+
number or string containing numbers seperated by ;
550+
:return:
551+
True if conversion is possible for all values
552+
"""
553+
if isinstance(x, numbers.Number):
554+
return True
555+
if not isinstance(x, str):
556+
return False
557+
try:
558+
[float(y) for y in x.split(';')]
559+
return True
560+
except (ValueError, TypeError):
561+
return False
562+
563+
# mask numeric values
564+
for col in [OBSERVABLE_PARAMETERS, NOISE_PARAMETERS]:
565+
if col not in measurement_df:
566+
continue
567+
measurement_df.loc[measurement_df[col].apply(is_numeric), col] = np.nan
551568

552569
grouping_cols = core.get_notnull_columns(
553570
measurement_df,
@@ -557,8 +574,8 @@ def measurement_table_has_timepoint_specific_mappings(
557574
OBSERVABLE_PARAMETERS,
558575
NOISE_PARAMETERS,
559576
])
560-
grouped_df = measurement_df.fillna('').groupby(grouping_cols).size()\
561-
.reset_index()
577+
grouped_df = measurement_df.groupby(grouping_cols,
578+
dropna=False).size().reset_index()
562579

563580
grouping_cols = core.get_notnull_columns(
564581
grouped_df,
@@ -567,11 +584,10 @@ def measurement_table_has_timepoint_specific_mappings(
567584
PREEQUILIBRATION_CONDITION_ID])
568585
grouped_df2 = grouped_df.groupby(grouping_cols).size().reset_index()
569586

570-
if len(grouped_df.index) != len(grouped_df2.index):
571-
logger.warning("Measurement table has timepoint-specific "
572-
f"mappings:\n{grouped_df}")
573-
return True
574-
return False
587+
# data frame has timepoint specific overrides if grouping by noise
588+
# parameters and observable parameters in addition to observable,
589+
# condition and preeq id yields more groups
590+
return len(grouped_df.index) != len(grouped_df2.index)
575591

576592

577593
def measurement_table_has_observable_parameter_numeric_overrides(

0 commit comments

Comments
 (0)