diff --git a/isatools/model/datafile.py b/isatools/model/datafile.py
index 04aa8f742..ea0f35b4a 100644
--- a/isatools/model/datafile.py
+++ b/isatools/model/datafile.py
@@ -202,6 +202,42 @@ def __ne__(self, other):
return not self == other
+class ImageFile(DataFile):
+ """Represents an Image file in an experimental graph."""
+
+ def __init__(self, filename="", id_="", generated_from=None, comments=None):
+ super().__init__(filename=filename, id_=id_, generated_from=generated_from, comments=comments)
+
+ self.label = "Image File"
+
+ def __repr__(self):
+ return (
+ "isatools.model.ImageFile(filename='{0.filename}', "
+ "generated_from={0.generated_from}, comments={0.comments})".format(self)
+ )
+
+ def __str__(self):
+ return """ImageFile(
+ filename={data_file.filename}
+ generated_from={num_generated_from} Sample objects
+ comments={num_comments} Comment objects
+)""".format(data_file=self, num_generated_from=len(self.generated_from), num_comments=len(self.comments))
+
+ def __hash__(self):
+ return hash(repr(self))
+
+ def __eq__(self, other):
+ return (
+ isinstance(other, ImageFile)
+ and self.filename == other.filename
+ and self.generated_from == other.generated_from
+ and self.comments == other.comments
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+
class RawSpectralDataFile(DataFile):
"""Represents a raw spectral data file in an experimental graph."""
@@ -428,6 +464,44 @@ def __ne__(self, other):
return not self == other
+class MetaboliteAssignmentFile(DataFile):
+ """Represents a metabolite assignment file in an experimental graph."""
+
+ def __init__(self, filename="", id_="", generated_from=None, comments=None):
+ super().__init__(filename=filename, id_=id_, generated_from=generated_from, comments=comments)
+
+ self.label = "Metabolite Assignment File"
+
+ def __repr__(self):
+ return (
+ "isatools.model.MetaboliteAssignmentFile("
+ "filename='{data_file.filename}', "
+ "generated_from={data_file.generated_from}, "
+ "comments={data_file.comments})".format(data_file=self)
+ )
+
+ def __str__(self):
+ return """MetaboliteAssignmentFile(
+ filename={data_file.filename}
+ generated_from={num_generated_from} Sample objects
+ comments={num_comments} Comment objects
+)""".format(data_file=self, num_generated_from=len(self.generated_from), num_comments=len(self.comments))
+
+ def __hash__(self):
+ return hash(repr(self))
+
+ def __eq__(self, other):
+ return (
+ isinstance(other, MetaboliteAssignmentFile)
+ and self.filename == other.filename
+ and self.generated_from == other.generated_from
+ and self.comments == other.comments
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+
class DerivedArrayDataMatrixFile(DataFile):
"""Represents a derived array data matrix file in an experimental graph."""
diff --git a/isatools/resources/config/xml/histology.xml b/isatools/resources/config/xml/histology.xml
index 2255a4454..8a8ef0360 100644
--- a/isatools/resources/config/xml/histology.xml
+++ b/isatools/resources/config/xml/histology.xml
@@ -1 +1,50 @@
-[INSTITUTION].Group-[GROUP_NO].Subject-[SUBJECT_NO].[SAMPLE_EXTRACT].Extract-[EXTRACT_COUNT].LE-[LABEL_COUNT].ASSAY-[HYB_COUNT][INSTITUTION].Group-[GROUP_NO].Subject-[SUBJECT_NO].[SAMPLE_EXTRACT]
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [INSTITUTION].Group-[GROUP_NO].Subject-[SUBJECT_NO].[SAMPLE_EXTRACT].Extract-[EXTRACT_COUNT].LE-[LABEL_COUNT].ASSAY-[HYB_COUNT]
+
+
+
+
+
+
+
+
+
+ [INSTITUTION].Group-[GROUP_NO].Subject-[SUBJECT_NO].[SAMPLE_EXTRACT]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/isatools/resources/config/xml/phenotyping_imaging.xml b/isatools/resources/config/xml/phenotyping_imaging.xml
new file mode 100644
index 000000000..b4de93680
--- /dev/null
+++ b/isatools/resources/config/xml/phenotyping_imaging.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+ [INSTITUTION].Group-[GROUP_NO].Subject-[SUBJECT_NO].[SAMPLE_EXTRACT]
+
+
+
+
+
+
+
+ [INSTITUTION].Group-[GROUP_NO].Subject-[SUBJECT_NO].[SAMPLE_EXTRACT].Extract-[EXTRACT_COUNT].LE-[LABEL_COUNT].ASSAY-[HYB_COUNT]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/isajson/test_isajson.py b/tests/isajson/test_isajson.py
index 6f8ea1a29..91b36019e 100644
--- a/tests/isajson/test_isajson.py
+++ b/tests/isajson/test_isajson.py
@@ -460,6 +460,18 @@ def test_json_load_and_dump_bii_s_test(self):
assays = [a for a in studies["assays"] if a["filename"] == "a_assay.txt"][0]
self.assertEqual(assays["materials"]["otherMaterials"][1]["type"], "Extract Name")
+
+ def test_json_load_and_dump_imagefile_test(self):
+ # Load into ISA objects
+ with open(os.path.join(utils.JSON_DATA_DIR, "ISA-Image", "isa-image.json")) as isajson_fp:
+ investigation = isajson.load(isajson_fp)
+
+ # Dump into ISA JSON from ISA objects
+ investigation_reload = json.loads(json.dumps(investigation, cls=isajson.ISAJSONEncoder))
+ studies = [s for s in investigation_reload["studies"] if s["filename"] == "s_study.txt"][0]
+ assays = [a for a in studies["assays"] if a["filename"] == "a_assay.txt"][0]
+ self.assertEqual(assays["dataFiles"][1]["type"], "Image File")
+
def test_json_load_and_dump_isa_labeled_extract(self):
# Load into ISA objects
with open(os.path.join(utils.JSON_DATA_DIR, "TEST-ISA-LabeledExtract1", "isa-test-le1.json")) as isajson_fp:
diff --git a/tests/isatab/validate/test_core.py b/tests/isatab/validate/test_core.py
index cfb5b9f8f..45cd333ca 100644
--- a/tests/isatab/validate/test_core.py
+++ b/tests/isatab/validate/test_core.py
@@ -43,6 +43,14 @@ def test_bii_s_7(self):
report = validate(fp=data_file, config_dir=self.default_conf)
self.assertEqual(len(report["warnings"]), 1)
+ def test_imaging(self):
+ data_path = path.join(path.dirname(path.abspath(__file__)), "..", "..", "data", "tab", "Imaging")
+ with open(path.join(data_path, "i_Investigation.txt"), "r") as data_file:
+ report = validate(fp=data_file, config_dir=self.default_conf)
+ print(report["errors"])
+ self.assertEqual(len(report["errors"]), 0)
+
+
def test_print_rule(self):
raw_rule = INVESTIGATION_RULES_MAPPING[0]
rule = Rule(**raw_rule)
diff --git a/tests/model/test_datafile.py b/tests/model/test_datafile.py
index 0d2a35f51..3ce831293 100644
--- a/tests/model/test_datafile.py
+++ b/tests/model/test_datafile.py
@@ -81,6 +81,7 @@ class TestSubDataFile(TestCase):
def setUp(self):
self.types = {
"RawDataFile": RawDataFile,
+ "ImageFile": ImageFile,
"DerivedDataFile": DerivedDataFile,
"RawSpectralDataFile": RawSpectralDataFile,
"DerivedArrayDataFile": DerivedArrayDataFile,
@@ -92,6 +93,7 @@ def setUp(self):
"PostTranslationalModificationAssignmentFile": PostTranslationalModificationAssignmentFile,
"AcquisitionParameterDataFile": AcquisitionParameterDataFile,
"FreeInductionDecayDataFile": FreeInductionDecayDataFile,
+ "MetaboliteAssignmentFile": MetaboliteAssignmentFile
}
self.classes = {}
for filetype in self.types:
diff --git a/tests/utils/test_isatab_configurator.py b/tests/utils/test_isatab_configurator.py
index 2e172541e..434e5550f 100644
--- a/tests/utils/test_isatab_configurator.py
+++ b/tests/utils/test_isatab_configurator.py
@@ -50,7 +50,7 @@ def test_load_config_metagenome_seq(self):
from isatools.io import isatab_configurator as configurator
config_dict = configurator.load(self._config_dir)
- self.assertEqual(len(config_dict), 30)
+ self.assertEqual(len(config_dict), 31)
self.assertEqual(
config_dict[("metagenome sequencing", "nucleotide sequencing")].isatab_configuration[0].table_name,
"metagenome_seq",