Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
# Xperimental-data-convertor

This is a utility to link excel2sbol and excel to flapjack converter, interlink the resulting data, and upload it to synbiohub and flapjack.

## Plate-reader exports

Create a Flapjack-compatible workbook from an XDC template and a BioTek-style
CSV/TXT reader export. The template's `SBH_sampledesigns_collection` worksheet
must map its sample-design names to SynBioHub SBOL object URIs.

```python
import os

from xperimental_data_conv import create_flapjack_input

create_flapjack_input(
"Align_TF_Study.xlsm",
"2025-07-02_Align-TF-Cytom-12-plasmids_growth-plate_1-1_Neo.txt",
"Flapjack_input.xlsx",
username=os.environ["SBH_USERNAME"],
password=os.environ["SBH_PASSWORD"],
)
```

The output has `Data`, `Media`, `Strains`, `DNA`, and `Chemicals` worksheets.
The `Data` worksheet retains the reader export; the other sheets are 96-well
maps resolved from the SBOL graph. Media uses role `NCIT:C48164`, strain
assemblies use role `NCIT:C14419`, chemicals use their functional-component
definition and `Flapjack#concentration`, and plasmids become `DNA 1...N` maps.
Use `token=os.environ["SBH_TOKEN"]` instead of username/password for token
authentication.
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
excel2flapjack~=1.0.2
excel2sbol~=1.0.24
excel2sbol~=1.0.24
sbol2>=1.4,<2
openpyxl>=3.1,<4
17 changes: 17 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from setuptools import find_packages, setup

setup(name='xperimental-data-conv',
version='1.0.1b',
url='https://github.com/SynBioDex/Experimental-Data-Convertor',
license='BSD 3-clause',
maintainer='Gonzalo Vidal',
maintainer_email='Gonzalo.vidalpena@colorado.edu',
include_package_data=True,
description='Convert Excel resources into SBOL and Flapjack, uploads them to SynBioHub and Flapjack and connects them',
packages=find_packages(include=['xperimental_data_conv', 'xperimental_data_conv.*']),
long_description=open('README.md').read(),
install_requires=['excel2flapjack==1.0.8',
'excel2sbol==1.0.29',
'sbol2>=1.4,<2',
'openpyxl>=3.1,<4'],
zip_safe=False)
18 changes: 0 additions & 18 deletions temp.py

This file was deleted.

Binary file added tests/test_files/Medias.xlsm
Binary file not shown.
155 changes: 155 additions & 0 deletions tests/test_flapjack_export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import tempfile
import unittest
from pathlib import Path

from openpyxl import load_workbook

from xperimental_data_conv import (
FlapjackPlateExporter,
SampleDesignMetadata,
SynBioHubSampleDesignResolver,
TemplateSample,
)


FIXTURES = Path(__file__).parent / "test_files"


class FakeObject:
def __init__(
self,
display_id,
*,
roles=(),
properties=None,
modules=(),
functional_components=(),
):
self.displayId = display_id
self.roles = roles
self.properties = properties or {}
self.modules = modules
self.functionalComponents = functional_components


class FakeReference:
def __init__(self, definition, display_id):
self.definition = definition
self.displayId = display_id


class FakeSynBioHubClient:
def __init__(self, objects):
self.objects = objects

def get_object(self, uri):
return self.objects[uri]


class StaticResolver:
def __init__(self):
self.resolved_uris = []

def resolve(self, sample):
self.resolved_uris.append(sample.sample_design_uri)
return SampleDesignMetadata(
medium="m9",
strain="Ecolisc2",
plasmids=("pIJAI477", "pIJAI478"),
chemicals={"Arabinose": 0.004},
)


class TestSynBioHubSampleDesignResolver(unittest.TestCase):
def test_resolves_sbol_modules_by_roles_and_extended_properties(self):
sample_uri = "https://example.org/sample/1"
medium_uri = "https://example.org/m9/1"
chemical_module_uri = "https://example.org/arabinose_004/1"
chemical_uri = "https://example.org/arabinose/1"
strain_uri = "https://example.org/strain/1"
plasmid_uris = ["https://example.org/p{0}/1".format(index) for index in range(1, 5)]

objects = {
sample_uri: FakeObject(
"sample_design",
modules=(
FakeReference(medium_uri, "m9"),
FakeReference(chemical_module_uri, "arabinose_004"),
FakeReference(strain_uri, "Ecolisc2"),
),
),
medium_uri: FakeObject(
"m9", roles=("http://identifiers.org/ncit/NCIT:C48164",)
),
chemical_module_uri: FakeObject(
"arabinose_004",
properties={
"https://wiki.synbiohub.org/wiki/Terms/Flapjack#concentration": [
"0.004"
]
},
functional_components=(FakeReference(chemical_uri, "Arabinose"),),
),
chemical_uri: FakeObject("Arabinose"),
strain_uri: FakeObject(
"Ecolisc2",
roles=("https://identifiers.org/obo/ncit:C14419",),
functional_components=tuple(
FakeReference(uri, "p{0}".format(index))
for index, uri in enumerate(plasmid_uris, start=1)
),
),
}
objects.update(
{
uri: FakeObject("pIJAI{0}".format(476 + index))
for index, uri in enumerate(plasmid_uris, start=1)
}
)

resolver = SynBioHubSampleDesignResolver(FakeSynBioHubClient(objects))
metadata = resolver.resolve(
TemplateSample("sample1", "A", 1, "sample_design", sample_uri)
)

self.assertEqual("m9", metadata.medium)
self.assertEqual("Ecolisc2", metadata.strain)
self.assertEqual(
("pIJAI477", "pIJAI478", "pIJAI479", "pIJAI480"),
metadata.plasmids,
)
self.assertEqual({"Arabinose": 0.004}, metadata.chemicals)


class TestFlapjackPlateExporter(unittest.TestCase):
def test_creates_flapjack_workbook_from_align_tf_files(self):
with tempfile.TemporaryDirectory() as temporary_directory:
output = Path(temporary_directory) / "flapjack_input.xlsx"
resolver = StaticResolver()
result = FlapjackPlateExporter(
FIXTURES / "Align_TF_Study.xlsm", resolver
).export(
FIXTURES / "2025-07-02_Align-TF-Cytom-12-plasmids_growth-plate_1-1_Neo.txt",
output,
)

self.assertEqual(output, result)
self.assertTrue(resolver.resolved_uris)
workbook = load_workbook(output, data_only=True, read_only=True)
try:
self.assertEqual(
["Data", "Media", "Strains", "DNA", "Chemicals"],
workbook.sheetnames,
)
self.assertEqual("Software Version", workbook["Data"]["A2"].value)
self.assertEqual("3.11.19", workbook["Data"]["B2"].value)
self.assertEqual("m9", workbook["Media"]["B2"].value)
self.assertEqual("Ecolisc2", workbook["Strains"]["B2"].value)
self.assertEqual("DNA 1", workbook["DNA"]["A1"].value)
self.assertEqual("pIJAI477", workbook["DNA"]["B2"].value)
self.assertEqual("DNA 2", workbook["DNA"]["A11"].value)
self.assertEqual("pIJAI478", workbook["DNA"]["B12"].value)
self.assertEqual("Arabinose", workbook["Chemicals"]["A1"].value)
self.assertEqual(0.004, workbook["Chemicals"]["B2"].value)
finally:
workbook.close()
41 changes: 41 additions & 0 deletions tests/test_xdc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from xperimental_data_conv.main import XDC
import unittest
import os


fj_url = "charmmefj.synbiohub.org"
fj_user = ""
fj_pass = ""

sbh_url = "https://synbiohub.org"
sbh_user = "test@test.test"
sbh_pass = "test123"
sbh_collec = "XDC_package_test"

test_file_path ='../test_files'
excel_path = os.path.join(test_file_path, 'Medias.xlsm')

homespace = 'https://synbiohub.org/synbiotest'

fj_overwrite = False
sbh_overwrite=False

xdc = XDC(input_excel_path = excel_path,
fj_url = fj_url,
fj_user = fj_user,
fj_pass = fj_pass,
sbh_url = sbh_url,
sbh_user = sbh_user,
sbh_pass = sbh_pass,
sbh_collection = sbh_collec,
sbh_collection_description = 'XDC package test collection',
sbh_overwrite = sbh_overwrite,
fj_overwrite = fj_overwrite,
homespace = homespace,
fj_token = None,
sbh_token = None)

class Test_XDC(unittest.TestCase):
def test_initialize(self):
xdc.initialize()

1 change: 0 additions & 1 deletion xperimental-data-conv/README.md

This file was deleted.

1 change: 1 addition & 0 deletions xperimental-data-conv/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#no shared content
Loading
Loading