Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add assays to existing investigations #98

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions altamisa/isatab/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
from .validate_investigation import InvestigationValidator # noqa: F401
from .write_assay_study import AssayWriter, StudyWriter, RefTableBuilder # noqa: F401
from .write_investigation import InvestigationWriter # noqa: F401
from .modify_investigation import InvestigationForge # noqa: F401
88 changes: 88 additions & 0 deletions altamisa/isatab/modify_investigation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
from pathlib import Path
from typing import Union

import attr

from altamisa.isatab import InvestigationReader

__author__ = "Thomas Sell <[email protected]>"


class InvestigationForge:
"""
Provides methods to add assays to an existing investigation.

:type input_path: str | Path
:param input_path: Location of investigation to modify.
"""

def __init__(self, input_path: Union[str, Path]):
i_file = Path(input_path).expanduser().resolve()

with i_file.open("rt") as f:
self.investigation = InvestigationReader.from_stream(f).read()

if len(self.investigation.studies) != 1:
# TODO: add support for multiple studies
raise IndexError("Only single study investigations are supported.")

@staticmethod
def _join_protocols(x: dict, y: dict) -> dict:
"""
Join two dicts of ISA protocols.
For duplicate protocols, join parameter dicts.
"""
for protocol in y:
if protocol not in x:
# no conflict > add protocol
x.update({protocol: y[protocol]})
else:
# same protocol > check parameters
old_parameters = x[protocol].parameters
new_parameters = y[protocol].parameters
for parameter in new_parameters:
if parameter not in old_parameters:
# no conflict > add parameter
old_parameters.update({parameter: new_parameters[parameter]})
else:
# existing parameter: raise for ontology mismatch
if new_parameters[parameter] != old_parameters[parameter]:
raise ValueError(
f'Ontology term mismatch for parameter "{parameter}" of protocol "{protocol}".'
)
return x

def add_assay(self, input_path: Union[str, Path]):
"""
Add assay to investigation file.

:type input_path: str | Path
:param input_path: Location of bare assay definition to add.
:rtype: models.InvestigationInfo
:returns: Investigation model including all information from the investigation file.
"""
new_assay = Path(input_path).expanduser().resolve()
with new_assay.open("rt") as f:
reader = InvestigationReader(f)
new_assays = tuple(a for a in reader._read_study_assays())
new_protocols = {p.name: p for p in reader._read_study_protocols()}

old_protocols = self.investigation.studies[0].protocols
joined_protocols = self._join_protocols(
old_protocols,
new_protocols,
)

assays = self.investigation.studies[0].assays
assays += new_assays

updated_study = attr.evolve(
self.investigation.studies[0], protocols=joined_protocols, assays=assays
)
self.investigation = attr.evolve(self.investigation, studies=(updated_study,))

def add_protocol(self):
raise NotImplementedError

def remove_protocol(self):
raise NotImplementedError
8 changes: 8 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ def small2_investigation_file():
yield file


@pytest.fixture
def small2o_investigation_file():
"""This file contains an ontology reference for one of the protocol parameters."""
path = os.path.join(os.path.dirname(__file__), "data/i_small2/i_small2_o.txt")
with open(path, "rt") as file:
yield file


@pytest.fixture
def small2_study_file():
path = os.path.join(os.path.dirname(__file__), "data/i_small2/s_small2.txt")
Expand Down
6 changes: 3 additions & 3 deletions tests/data/i_small2/i_small2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ Study Protocol Type Term Source REF
Study Protocol Description
Study Protocol URI
Study Protocol Version
Study Protocol Parameters Name
Study Protocol Parameters Name Term Accession Number
Study Protocol Parameters Name Term Source REF
Study Protocol Parameters Name method;instrument
Study Protocol Parameters Name Term Accession Number ;
Study Protocol Parameters Name Term Source REF ;
Study Protocol Components Name
Study Protocol Components Type
Study Protocol Components Type Term Accession Number
Expand Down
93 changes: 93 additions & 0 deletions tests/data/i_small2/i_small2_o.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
ONTOLOGY SOURCE REFERENCE
Term Source Name OBI NCBITAXON ROLEO
Term Source File http://data.bioontology.org/ontologies/OBI http://data.bioontology.org/ontologies/NCBITAXON http://data.bioontology.org/ontologies/ROLEO
Term Source Version 31 8 1
Term Source Description Ontology for Biomedical Investigations National Center for Biotechnology Information (NCBI) Organismal Classification Role Ontology
INVESTIGATION
Investigation Identifier i_small2
Investigation Title Small Investigation
Investigation Description
Investigation Submission Date
Investigation Public Release Date
INVESTIGATION PUBLICATIONS
Investigation PubMed ID
Investigation Publication DOI
Investigation Publication Author List
Investigation Publication Title
Investigation Publication Status
Investigation Publication Status Term Accession Number
Investigation Publication Status Term Source REF
INVESTIGATION CONTACTS
Investigation Person Last Name
Investigation Person First Name
Investigation Person Mid Initials
Investigation Person Email
Investigation Person Phone
Investigation Person Fax
Investigation Person Address
Investigation Person Affiliation
Investigation Person Roles
Investigation Person Roles Term Accession Number
Investigation Person Roles Term Source REF
STUDY
Study Identifier s_small2
Study Title Small Germline Study
Study Description
Comment[Study Grant Number]
Comment[Study Funding Agency]
Study Submission Date
Study Public Release Date
Study File Name s_small2.txt
STUDY DESIGN DESCRIPTORS
Study Design Type
Study Design Type Term Accession Number
Study Design Type Term Source REF
STUDY PUBLICATIONS
Study PubMed ID
Study Publication DOI
Study Publication Author List
Study Publication Title
Study Publication Status
Study Publication Status Term Accession Number
Study Publication Status Term Source REF
STUDY FACTORS
Study Factor Name
Study Factor Type
Study Factor Type Term Accession Number
Study Factor Type Term Source REF
STUDY ASSAYS
Study Assay File Name a_small2.txt
Study Assay Measurement Type protein expression profiling
Study Assay Measurement Type Term Accession Number http://purl.obolibrary.org/obo/OBI_0000615
Study Assay Measurement Type Term Source REF OBI
Study Assay Technology Type mass spectrometry
Study Assay Technology Type Term Accession Number http://purl.obolibrary.org/obo/OBI_0000470
Study Assay Technology Type Term Source REF OBI
Study Assay Technology Platform LC-MS/MS
STUDY PROTOCOLS
Study Protocol Name sample collection extraction labeling chromatography mass spectrometry data transformation
Study Protocol Type sample collection extraction labeling chromatography mass spectrometry data transformation
Study Protocol Type Term Accession Number
Study Protocol Type Term Source REF
Study Protocol Description
Study Protocol URI
Study Protocol Version
Study Protocol Parameters Name method;instrument
Study Protocol Parameters Name Term Accession Number ;123
Study Protocol Parameters Name Term Source REF ;OBI
Study Protocol Components Name
Study Protocol Components Type
Study Protocol Components Type Term Accession Number
Study Protocol Components Type Term Source REF
STUDY CONTACTS
Study Person Last Name Doe
Study Person First Name John
Study Person Mid Initials
Study Person Email
Study Person Phone
Study Person Fax
Study Person Address
Study Person Affiliation
Study Person Roles author
Study Person Roles Term Accession Number http://purl.obolibrary.org/obo/RoleO_0000061
Study Person Roles Term Source REF ROLEO
30 changes: 30 additions & 0 deletions tests/test_modify_investigation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pytest

from altamisa.isatab import InvestigationForge


def test_forge(assays_investigation_file):
# multiple studies
with pytest.raises(IndexError):
InvestigationForge(assays_investigation_file.name)


def test_add_assay(
small_investigation_file,
small2_investigation_file,
assays_investigation_file,
small2o_investigation_file,
):
forge = InvestigationForge(small_investigation_file.name)
forge.add_assay(small2_investigation_file.name)
output = forge.investigation
assert len(output.studies[0].assays) == 2
assert len(output.studies[0].protocols) == 8

# multiple studies
with pytest.raises(IndexError):
forge.add_assay(assays_investigation_file.name)

# ontology reference mismatch
with pytest.raises(ValueError):
forge.add_assay(small2o_investigation_file.name)
Loading