Laboratory Open Procotol Language (LabOP) is a representation designed to simplify the exchange of protocols between laboratories. This project includes both an ontology describing LabOP and a python library to manipulate LabOP documents, which are stored as RDF. The LabOP specification is in the LabOP-specification repository.
The LabOP package is available by PyPI:
pip3 install labop
LabOP visualizations currently depend on the graphviz
application. To install graphviz, run (per https://github.com/ts-graphviz/setup-graphviz):
brew install graphviz
apt-get install graphviz libgraphviz-dev pkg-config
choco install graphviz
To use LabOP in your client application, import the LabOP, UML, and SBOL3 modules:
import labop, uml, sbol3
The LabOP data model is encoded as an ontology using the Web Ontology Language (OWL). (A Turtle serialization of the LabOP ontology can be found in the labop
directory, and uses the UML ontology found in the uml
directory.) The module's API is dynamically generated directly from this OWL specification immediately upon import of the module into the user's Python environment. The ontology specifies the Python classes, their attributes, their types, and their cardinality.
All file I/O is handled through an SBOL Document
object. In the following example, we read a file that describes the protocol for an OD calibration using water and LUDOX. The file format can be any RDF format:
doc = sbol3.Document()
doc.read('test/testfiles/igem_ludox_test.nt')
Once a Document
is loaded, you can inspect and manipulate its contents. For example, the following prints an inventory of objects and their metadata:
for obj in doc.objects:
print(obj.identity)
print(obj.name)
print(obj.description)
print()
The name
attribute is used for human-readable and/or lab-specific identifiers. The identity
attribute specifies the unique Uniform Resource Identifier (URI) for each object. The URI can be used to retrieve specific objects from the Document.
ludox = doc.find('https://bbn.com/scratch/LUDOX')
Every LabOP object is identified by a unique URI. Objects come in two types, "top-level" objects that can stand alone, such as a Protocol
or a Primitive
, and "child" objects that only make sense within the context of their top-level object, such as a protocol step (ActivityNode
) or a Parameter
.
When a new "top-level" object is created, the full URI can be either prodiced or automatically generated from a local identifier. Every constructor for a top-level LabOP object takes a local ID or URI as its first argument. If given a local ID, the full URI is then generated from a namespace and the local ID. This local ID must consist of only alphanumeric characters and/or underscores.
When constructing a new Document
, the general workflow is as follows. First, set the namespace that governs new objects. Second, create new objects. Finally, add the new object to the Document
. For example:
sbol3.set_namespace('http://example.org/synbio/')
doc = sbol3.Document()
protocol = labop.Protocol('TimeSeries')
doc.add(protocol)
doc.find('http://example.org/synbio/TimeSeries')
Child objects are not named by the user, but receive their names automatically when added to a parent. For example:
step = uml.CallBehaviorAction()
protocol.nodes += [step]
step.identity # http://example.org/synbio/TimeSeries/CallBehaviorAction1
Note that in many cases, it is better to create child objects by means of helper functions:
labop.import_library('sample_arrays')
four_wells = protocol.primitive_step('PlateCoordinates', coordinates='A2:D2') # Note: still needs source plate indicated
A Document
can be validated as follows:
for issue in doc.validate():
print(issue)
A Protocol
may be executed an arbitrary amount of times, resulting in a unique history each time that captured by an Execution
. Such Executions
may record actual times or feedback measurements from instruments during execution.
The ExecutionEngine
class is used to carry out a protocol. An ExecutionEngine
interprets a Protocol
in an application-specific manner using a BehaviorSpecialization
object. For example, a BehaviorSpecialization
might translate a protocol encoded in LabOP into specific instructions that a particular laboratory's instrumentation or robotics can interpret. Converter tools can also be implemented. Currently the LabOP project includes a Markdown converter that will convert a LabOP-encoded protocol into a human-readable Markdown document. If no BehaviorSpecialization
is provided, the default will be used, which is essentially a no-op, but provides some utility for testing and development.
Each protocol execution requires an Agent
, used to record the person, laboratory, or machine executing the protocol. An execution may also require input ParameterValues
to configure the protocol.
Following is an example execution that converts a protocol for optical density measurement into Markdown format to the example.md
file:
agent = sbol3.Agent("2022_Hogwart_iGEM_team") # Used to describe the person or machine executing the protocol
ee = ExecutionEngine(specializations=[MarkdownSpecialization("example.md")])
parameter_values = [
labop.ParameterValue(parameter=protocol.get_input("wavelength"),
value=sbol3.Measure(600, tyto.OM.nanometer))
]
execution = ee.execute(protocol, agent, id="OD_measurement", parameter_values=parameter_values)
See notebooks for examples of how to use LabOP. An interactive version of the main demonstration notebook notebooks/labop_demo.ipynb is also hosted on Google Collab. The interactive version is shared as view only, but you can make a copy to modify with File -> Save a copy in Drive
by saving it on your own Google Drive account.
The secrets
directory includes a template to configure Strateos credentials. It requires renaming and editing the provided sample. (Please, never commit or share actual credentials!)
cp secrets/strateos_secrets.json.sample secrets/strateos_secrets.json
# Edit contents of secrets/strateos_secrets.json
The secrets for the Strateos API are used by the notebook notebooks/Autoprotocol.ipynb
and pytest test/test_convert.py
. Additional user permissions may be required to submit runs to Strateos. Please contact Strateos support for assistance.
The LabOP documentation can be generated from its RDF specification (e.g., labop.ttl
). The following instructions will generate the latex source in the <labop_root>/Labop-Specification
directory. The project https://github.com/Bioprotocols/labop-specification contains static files that include the generated source. Generating the specification involves running the following in labop
(i.e., <labop_root>
):
python3 doc/generate_specification_content.py
cd ..
git clone https://github.com/Bioprotocols/labop-specification.git
cd labop-specification
cp -r ../labop/LabOP-specification/* .
pdflatex labop
bibtex labop
pdflatex labop