Skip to content

Commit

Permalink
feat: add assays to existing investigations
Browse files Browse the repository at this point in the history
  • Loading branch information
sellth committed Oct 11, 2023
1 parent 34b864c commit 5d27ab5
Showing 1 changed file with 79 additions and 0 deletions.
79 changes: 79 additions & 0 deletions altamisa/isatab/modify_investigation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from pathlib import Path

import attr

from altamisa.isatab import InvestigationReader


class InvestigationForge(InvestigationReader):
"""
Provides methods to add assays to an existing investigation.
:type input_path: str
:param input_path: Location of investigation to modify.
"""

def __init__(self, input_path: str):
i_file = Path(input_path).expanduser().resolve()
with i_file.open("rt") as f:
self.investigation = InvestigationReader.from_stream(f).read()

@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: str) -> models.InvestigationInfo:
"""
Add assay to investigation file.
:type input_path: str
:param input_path: Location of investigation to modify.
:rtype: models.InvestigationInfo
:returns: Investigation model including all information from the investigation file.
"""
i_file = Path(input_path).expanduser().resolve()
with i_file.open("rt") as f:
investigation2 = InvestigationReader.from_stream(f).read()

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

protocols = self.investigation.studies[0].protocols
# the following will also update the investigation object
protocols = self._join_protocols(
protocols,
investigation2.studies[0].protocols,
)

# the following will NOT update the investigation object (?)
assays = self.investigation.studies[0].assays
assays += investigation2.studies[0].assays

new_study = attr.evolve(
self.investigation.studies[0], protocols=protocols, assays=assays
)
modified_inv = attr.evolve(self.investigation, studies=(new_study,))
return modified_inv

0 comments on commit 5d27ab5

Please sign in to comment.