Skip to content

Commit 6c775ab

Browse files
committed
Fix parsing of one-to-one metadata
for samples with no data objects of certain process type or missing samples in the collection
1 parent e33c210 commit 6c775ab

2 files changed

Lines changed: 51 additions & 23 deletions

File tree

docs/CHANGELOG.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ Fixed
1212
-----
1313
- Raise an error if a user calls the download method
1414
on a data object and inputs a non-existing file or field name
15+
Changed
16+
-----
17+
- Change the parsing logic for the one-to-one metadata table
18+
in ``BaseTables`` class so it does not fail when the table
19+
index does not reflect the state of samples in the collection
1520

1621

1722
===================

src/resdk/tables/base.py

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,34 @@ def _get_orange_object(self) -> Data:
371371
)
372372

373373
def _get_orange_data(self) -> pd.DataFrame:
374+
def map_and_filter_samples(
375+
df: pd.DataFrame, column_name: str, mapping: dict[str, int]
376+
) -> pd.DataFrame:
377+
"""Map values from a predefined column to a new ``sample_id`` column.
378+
379+
The original column is dropped from the returned DataFrame.
380+
381+
Samples with no corresponding entry in ``mapping`` are omitted because they are
382+
not present in the collection or do not have a data object with the required
383+
process type.
384+
"""
385+
mask = df[column_name].isin(mapping)
386+
discarded = df.loc[~mask]
387+
388+
if not discarded.empty:
389+
na_samples = discarded[column_name].unique().tolist()
390+
warnings.warn(
391+
f"The following samples in the one-to-one metadata table are not present in "
392+
f"the collection or do not have a data object with a required process type."
393+
f" These samples will be omitted from the output: {na_samples}",
394+
Warning,
395+
)
396+
397+
df = df.loc[mask].copy()
398+
df["sample_id"] = df[column_name].map(mapping)
399+
df = df.drop(columns=[column_name])
400+
return df
401+
374402
try:
375403
orange_meta = self._get_orange_object()
376404
except LookupError:
@@ -400,30 +428,25 @@ def _get_orange_data(self) -> pd.DataFrame:
400428
df = df.rename(columns={"Sample ID": "sample_id"})
401429
elif "mS#Sample ID" in df.columns:
402430
df = df.rename(columns={"mS#Sample ID": "sample_id"})
403-
elif "Sample slug" in df.columns:
404-
mapping = {s.slug: s.id for s in self._samples}
405-
df["sample_id"] = [mapping[value] for value in df["Sample slug"]]
406-
df = df.drop(columns=["Sample slug"])
407-
elif "mS#Sample slug" in df.columns:
408-
mapping = {s.slug: s.id for s in self._samples}
409-
df["sample_id"] = [mapping[value] for value in df["mS#Sample slug"]]
410-
df = df.drop(columns=["mS#Sample slug"])
411-
elif "Sample name" in df.columns or "Sample name" in df.columns:
412-
mapping = {s.name: s.id for s in self._samples}
413-
if len(mapping) != len(self._samples):
414-
raise ValueError(
415-
"Duplicate sample names. Cannot map orange table data to other metadata"
416-
)
417-
df["sample_id"] = [mapping[value] for value in df["Sample name"]]
418-
df = df.drop(columns=["Sample name"])
419-
elif "mS#Sample name" in df.columns:
420-
mapping = {s.name: s.id for s in self._samples}
421-
if len(mapping) != len(self._samples):
422-
raise ValueError(
423-
"Duplicate sample names. Cannot map orange table data to other metadata"
431+
else:
432+
columns_map = {
433+
"Sample slug": "slug",
434+
"mS#Sample slug": "slug",
435+
"Sample name": "name",
436+
"mS#Sample name": "name",
437+
}
438+
for column_name, attr in columns_map.items():
439+
if column_name not in df.columns:
440+
continue
441+
mapping = {getattr(s, attr): s.id for s in self._samples}
442+
if attr == "name" and len(mapping) != len(self._samples):
443+
raise ValueError(
444+
"Duplicate sample names. Cannot map orange table data to other metadata"
445+
)
446+
df = map_and_filter_samples(
447+
df=df, column_name=column_name, mapping=mapping
424448
)
425-
df["sample_id"] = [mapping[value] for value in df["mS#Sample name"]]
426-
df = df.drop(columns=["mS#Sample name"])
449+
break
427450

428451
return df.set_index("sample_id")
429452

0 commit comments

Comments
 (0)