forked from SynBioDex/SBOL-specification
-
Notifications
You must be signed in to change notification settings - Fork 0
/
practices.tex
349 lines (281 loc) · 25.7 KB
/
practices.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
% -----------------------------------------------------------------------------
\section{Recommended Best Practices}
\label{sec:bestpractices}
% -----------------------------------------------------------------------------
\twozeroone{\subsection{SBOL Namespaces}
Namespaces for different versions of SBOL SHOULD NOT be semantically mixed in the same document. For example, an SBOL 2.x \sbol{ComponentInstance} SHOULD NOT refer to an SBOL 1.x DNAComponent. However, namespaces for different versions MAY be present in the same document so long as they are semantically independent (that is, so long as objects belonging to these namespaces do not refer to each other). When multiple SBOL namespaces are present in a document, libraries SHOULD default to interpreting as SBOL only those objects belonging to the namespace for the most recent version of SBOL in the document. Any remaining objects belonging to any other SBOL namespace SHOULD be interpreted as \sbol{GenericTopLevel}s and custom \sbol{Annotation}s.}
\subsection{Use of the Version Property}
Once an SBOL object has been published where others might have access it (e.g., to an online repository), it might be the case that other objects come to depend on the particular contents of the published object.
Thus, in order to avoid creating conflicting data, if a person wants to change the properties of a published object, they SHOULD do so by making a new copy of object that incorporates the change and has an \sbol{identity} property that contains a new \sbol{URI}.
The relationship between the old and new objects (i.e., that the new object was derived from the old object), however, is not visible unless it is explicitly declared. This is RECOMMENDED to be done using the \sbol{persistentIdentity}, and \sbol{version} properties. The preferred practice for declaring such a relationship is to use the same \sbol{persistentIdentity} for both objects, but give the newer object a later \sbol{version}. Then, when the new object is published, it can be clear to both humans and machines that this object is intended to update the previously published object. In this way, when a user wants the latest version of an object, they can obtain it by referencing the object via its \sbol{persistentIdentity} and rely on a tool to find the object with that \sbol{persistentIdentity} and the latest \sbol{version}.
As stated in \ref{sec:version}, it is RECOMMENDED that version numbering follow the conventions of semantic versions (\url{http://semver.org/}), particularly as implemented by Maven (\url{http://maven.apache.org/}).
This convention represents versions as sequences of numbers and qualifiers separated by the characters {\tt .} and {\tt -} and compared in lexicographical order (for example, 1 < 1.3.1 < 2.0-beta). For a full explanation, see the linked resources.
\subsection{Compliant SBOL Objects}
\label{sec:compliant}
Maintaining unique \sbol{identity} \sbol{URI}s for all SBOL objects can be a very challenging implementation task. To reduce this burden, users of SBOL 2.x are encouraged to follow a few simple rules when constructing the \sbol{identity} properties and related properties for SBOL objects. When these rules are followed in constructing an SBOL object, we say that this object is \emph{compliant}. These rules are as follows:
\begin{enumerate}
\item The \sbol{identity} of a compliant SBOL object MUST begin with a \emph{URI prefix} that maps to a domain over which the user has control. Namely, the user can guarantee uniqueness of identities within this domain.
\item The \sbol{persistentIdentity} and \sbol{displayId} properties are REQUIRED of a compliant SBOL object.
\item The \sbol{persistentIdentity} of a compliant \sbol{TopLevel} object MUST end with a delimiter ('/', '\#', or ':') followed by the \sbol{displayId} of the object.
\item The \sbol{persistentIdentity} of a compliant SBOL object that is not also a \sbol{TopLevel} object MUST begin with the \sbol{persistentIdentity} of its parent object and be immediately followed by a delimiter ('/', '\#', or ':') and the \sbol{displayId} of the compliant object.
\item If a compliant SBOL object is not given a \sbol{version}, then its \sbol{identity} and \sbol{persistentIdentity} properties MUST contain the same \sbol{URI}.
\item If a compliant SBOL object has a \sbol{version}, then its \sbol{identity} property MUST contain a \sbol{URI} of the form "\refObj{persistentIdentity}/\refObj{version}".
\item The \sbol{version} of a compliant SBOL object that is not also a \sbol{TopLevel} object MUST contain the same \sbol{String} as the \sbol{version} property of the compliant object's parent object.
\item The \sbol{identity}, \sbol{persistentIdentity}, \sbol{displayId}, and \sbol{version} properties of a compliant SBOL object MUST NOT be changed once set.
\end{enumerate}
All examples in this specification use compliant \sbol{URI}s.
\subsection{Annotations: Embedded Objects vs. External References}
When annotating an SBOL document with additional information, there are
two general methods that can be used:
\begin{itemize}
\item Embed the information in the SBOL document, either as non-SBOL
properties or \sbol{GenericTopLevel} objects.
\item Store the information separately and annotate the SBOL document
with \sbol{URI}s that point to it.
\end{itemize}
In theory, either method can be used in any case. (Note that a third case not
discussed here is to use SBOL to annotate external objects with linking
to SBOL documents, rather than annotate SBOL documents with links external objects.)
In practice,
embedding massive amounts of non-SBOL data into SBOL documents is likely
to cause problems for people and software tools trying to manage and
exchange such documents. Therefore, it is RECOMMENDED that small amounts of information (e.g., design notes or preferred graphical layout) be embedded in the SBOL model, while large amounts of information (e.g., the contents of the scientific publication from which a model was derived or flow cytometry data that characterizes performance) be linked with URIs pointing to external resources. The boundary between ``small'' and ``large'' is left deliberately vague, recognizing that it will likely depend on the particulars of a given SBOL application.
\subsection{Completeness and Validation}
RDF documents containing serialized SBOL objects might or might not be
entirely self-contained. A SBOL document is self-contained or ``complete'' if every SBOL object referred to in the document is contained in the document. It is RECOMMENDED that serializations be complete whenever practical. In order words, when serializing an SBOL object, serialize all of the other objects that it points to, then serialize all of the other objects that these objects point to, etc., until the document is complete.
It is important to note that there is no guarantee that an RDF document
contains valid SBOL. When an RDF document is deserialized to SBOL
objects, the program doing so SHOULD verify that all of the property
values encoded therein have the right data type (e.g., that the object
pointed to by the \sbol{sequences} property of a
\sbol{ComponentDefinition} is really a \sbol{Sequence}).
For complete files, this validation can be carried out entirely locally. For files that are not complete, an implementation either needs to
have a means of validating those external references (e.g., by
retrieving them from various repositories), or it needs to mark them as
unverified and not depend on their correctness.
\subsection{Recommended Ontologies for External Terms}
\label{sec:recomm_ontologies}
External ontologies and controlled vocabularies are an integral part of SBOL. SBOL uses \sbol{URI}s to access existing biological information through these resources. New SBOL specific terms are defined only when necessary. For example, \sbol{ComponentDefinition} \sbolmult{types:CD}{types}, such as DNA or protein, are described using BioPAX terms. Similarly, the roles of a DNA \twozeroone{or RNA} \sbol{ComponentDefinition} are described via SO terms. Although RECOMMENDED ontologies have been indicated in relevant sections where possible, other resources providing similar terms can also be used. A summary of these external sources can be found in \ref{tbl:preferred_external_resources}.
\begin{table}[ht]
\begin{edtable}{tabular}{p{3cm}p{1.5cm}p{4.5cm}p{6cm}}
\toprule
\textbf{SBOL Entity} & \textbf{Property} & \textbf{Preferred External Resource}
& \textbf{More Information} \\
\midrule
\textbf{ComponentDefinition} & types & BioPAX & \url{http://www.biopax.org}\\
& roles & SO (\textit{DNA} or \textit{RNA}) & \url{http://www.sequenceontology.org} \\
& roles & CHEBI (\textit{small molecule}) & \url{https://www.ebi.ac.uk/chebi/} \\
% & roles & UniProt (if type is \textit{protein}??) \\
\textbf{Interaction} & types & SBO (occurring entity branch) &
\url{http://www.ebi.ac.uk/sbo/main/} \\
\textbf{Participation} & roles & SBO (participant roles branch) &
\url{http://www.ebi.ac.uk/sbo/main/} \\
\textbf{Model} & language & EDAM & \url{http://bioportal.bioontology.org/ontologies/EDAM} \\
& framework & SBO (modeling framework branch) &
\url{http://www.ebi.ac.uk/sbo/main/} \\
\bottomrule
\end{edtable}
\caption{Preferred external resources from which to draw values for various SBOL properties.}
\label{tbl:preferred_external_resources}
\end{table}
\twozeroone{\subsection{Annotating Entities with Date \& Time}\label{sec:datetime}
Entities in an SBOL document can be annotated with creation and modification date. It is RECOMMENDED that predicates, or properties, from DCMI Metadata Terms SHOULD be used to include date and time information. The \texttt{created} and \texttt{modified} terms SHOULD respectively be used to annotate SBOL entities with creation and modification dates. Date and time values SHOULD be expressed using the XML Schema \texttt{dateTime} datatype~\citep{Biron2004}. For example, "\texttt{2016-03-16T20:12:00Z}" specifies that the day is 16 March 2016 and the time is 20:12pm in UTC (Coordinated Universal Time). An example serialization is shown below:}
\lstsetsbol
\begin{lstlisting}
<?xml version="1.0" ?>
<rdf:RDF xmlns:pr="http://partsregistry.org" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:prov="http://www.w3.org/ns/prov#" xmlns:sbol="http://sbols.org/v2#">
<sbol:CLASS_NAME rdf:about="...">
<dcterms:created>DATE_TIME_STRING</dcterms:created>
<dcterms:modified>DATE_TIME_STRING</dcterms:modified>
...
</sbol:CLASS_NAME>
...
</rdf:RDF>
\end{lstlisting}
\twoonezero{\subsection{Adding Provenance}
Provenance is central to a range of quality control and attribution tasks within the Synthetic Biology design process. Tracking attribution and derivation of one resource from another is paramount for managing intellectual property purposes. Source designs are often modified in systematic ways to generate derived designs, for example, by applying codon optimization or systematically removing all of a class of restriction enzyme sites. Documenting the transformation used, and any associated parameters, makes this explicit and potentially allows the process to be reproduced systematically. If a design has been used within other designs, and is later found to be defective, it is paramount that all uses of it, including uses of edited versions of the design, can be identified, and ideally replaced with a non-defective alternative. When importing data from external sources, it is important not only to attribute the original source (for example, GenBank), but also the tool used to perform the import, as this may have made arbitrary choices as to how to represent the source knowledge as SBOL. All these activities have in common that it is necessary to track what resource, and what transformation process was applied by whom to derive an SBOL design.
The PROV-O ontology (https://www.w3.org/TR/prov-o/) already defines a data model for provenance. PROV-O's \sbol{wasDerivedFrom} property was adopted in SBOL 2.x to describe the derivation of an SBOL entity from another in a light-weight provenance scheme. Here, a subset of PROV-O is adopted for SBOL as a best practice to describe these activities in more detail\footnote{We thank Dr Paolo Missier from the School of Computing Science, Newcastle University for discussions regarding the use of PROV-O for SBOL.}. PROV-O defines three core classes: \texttt{Entity}, \texttt{Activity} and \texttt{Agent}. An Agent (for example a software or a person) runs an Activity (according to a Plan) to generate one Entity from another. Although, PROV-O provides many other classes and rich set of terms. this specification describes the minimal subset of PROV-O that a provenance-aware SBOL tool should handle. This subset (\ref{uml:provenance}) includes the PROV-O's \sbol{Activity}, \sbol{Usage}, \sbol{Association}, \sbol{Agent} and \sbol{Plan} classes. Any SBOL's \sbol{Identified} object implicitly can act as an instance of PROV-O's \texttt{Entity} class and can include provenance through relationships to different activities. Resources representing \sbol{Agent}, \sbol{Activity} and \sbol{Plan} classes should be handled as \sbol{GenericTopLevel}, whilst \sbol{Usage} and \sbol{Association} resources should be nested within their parent activities.
%Although the full-set of PROV-O terms can be used in SBOL documents, a subset of PROV-O is adopted as a best practice. It is advised that SBOL tools should at least understand this subset, defined in Figure \ref{uml:provenance}.
Providers of provenance information are free to make use of more of PROV-O than is described here. It is acceptable for tools that understand more than this subset and use as much as they are able. Tools that only understand this subset must treat any additional data as annotations. Tools that are not aware of SBOL provenance at all must maintain and provide access to this information as annotations. This specification does not state what the newly added properties must point to. As long as they are resources that are consistent with the PROV-O property domains, they are legal. For example, a ComponentDefinition may be derived from another ComponentDefinition, but it would probably not make sense for it to be derived from a Collection.
The adopted subset of PROV-O terms and their relationships to SBOL objects are defined below.
\begin{figure}[ht]
\begin{center}
\includegraphics[scale=0.6]{uml/provenance}
\caption[]{Relationships between SBOL and PROV-O classes. PROV-O specific classes and terms are prefixed with \texttt{provo}.}
\label{uml:provenance}
\end{center}
\end{figure}
\subsubsection{Activity}
\label{sec:Activity}
A generated \texttt{Entity} is linked through a \texttt{wasGeneratedBy} relationship to an \sbol{Activity}, which is used to describe how different \sbol{Agent}s and other entities were used. An \sbol{Activity} is linked through a \sbol{qualifiedAssociation} to \sbol{Association}s, to describe the role of agents, and is linked through \sbol{qualifiedUsage} to \sbol{Usage}s to describe the role of other entities used as part of the activity. Moreover, each \sbol{Activity} includes optional startedAtTime and endedAtTime properties. When using \sbol{Activity} to capture how an entity was derived, it is expected that any additional information needed will be attached as annotations. This may include software settings or textual notes. Activities can also be linked together using the \sbol{wasInformedBy} relationship to provide dependency without explicitly specifying start and end times.
\paragraph{The \sbolheading{qualifiedAssociation} property}\label{sec:qualifiedAssociation}
The \sbol{qualifiedAssociation} property is OPTIONAL and MAY contain a set of \sbol{URI}s that refers to \sbol{Association} objects.
\paragraph{The \sbolheading{qualifiedUsage} property}\label{sec:qualifiedUsage}
The \sbol{qualifiedUsage} property is OPTIONAL and MAY contain a set of \sbol{URI}s that refers to \sbol{Usage} objects.
\paragraph{The \sbolheading{endedAtTime} property}\label{sec:endedAtTime}
The \sbol{endedAtTime} property is OPTIONAL and contains a dateTime (see section \ref{sec:datetime}) value, indicating when the activity ended.
\paragraph{The \sbolheading{startedAtTime} property}\label{sec:startedAtTime}
The \sbol{startedAtTime} property is OPTIONAL and contains a dateTime (see section \ref{sec:datetime}) value, indicating when the activity started. If this property is present, then the \sbol{endedAtTime} property is REQUIRED.
\paragraph{The \sbolheading{wasInformedBy} property}\label{sec:wasInformedBy}
The \sbol{wasInformedBy} property is OPTIONAL and contains a URI of another activity.
\paragraph{Serialization}
The serialization of an \sbol{Activity} MUST have the following form:
%\twoonezero -end
}
\lstsetsbol
\begin{lstlisting}
<prov:Activity rdf:about="...">
... [\emph{properties inherited from identified}] ...
[\emph{zero or more}] <prov:qualifiedAssociation>
<prov:Association rdf:about="...">...</prov:Association>
</prov:qualifiedAssociation> [\emph{elements}]
[\emph{zero or more}] <prov:qualifiedUsage>
<prov:Usage rdf:about="...">...</prov:Usage>
</prov:qualifiedUsage> [\emph{elements}]
[\emph{zero or one}] <prov:startedAtTime>...</prov:startedAtTime> [\emph{element}]
[\emph{zero or one}] <prov:endedAtTime>...</prov:startedAtTime> [\emph{element}]
[\emph{zero or one}] <prov:wasInformedBy rdf:resource="..."/> [\emph{element}]
</prov:Activity>
\end{lstlisting}
\twoonezero{
\subsubsection{Association}
\label{sec:Association}
An \sbol{Association} is linked to an \sbol{Agent} through the \sbol{agent} relationship. The \sbol{Association} includes the \texttt{hadRole} property to qualify the role of the \sbol{Agent} in the \sbol{Activity}.
\paragraph{The \sbolheading{agent} property}\label{sec:agent}
The \sbol{agent} property is REQUIRED and MUST contain a \sbol{URI}s that refers to an \sbol{Agent} object.
\paragraph{The \sbolheading{hadRole} property}\label{sec:hadRole}
The \sbol{hadRole} property is REQUIRED and MUST contain a \sbol{URI} that refers to a particular term describing the usage of the agent.
\paragraph{The \sbolheading{hadPlan} property}\label{sec:hadPlan}
The \sbol{hadPlan} property is OPTIONAL and contains a URI that refers to a \sbol{Plan}.
\paragraph{Serialization}
The serialization of an \sbol{Association} MUST have the following form:
}%\twoonezero{ end
\lstsetsbol
\begin{lstlisting}
<prov:Association rdf:about="...">
... [\emph{properties inherited from identified}] ...
[\emph{one}] <prov:hadRole rdf:resource="..."/> [\emph{element}]
[\emph{zero or one}] <prov:hadPlan rdf:resource="..."/> [\emph{element}]
[\emph{one}] <prov:agent rdf:resource="..."/> [\emph{element}]
</prov:Association>
\end{lstlisting}
\twoonezero{
\subsubsection{Usage}
\label{sec:Usage}
How different entities are used in an \texttt{Activity} is specified with the \texttt{Usage} class, which is linked from an \texttt{Activity} through the \texttt{qualifiedUsage} relationship. A \texttt{Usage} is then linked to an \texttt{Entity} through the \texttt{Entity}'s URI and the role of this entity is qualified with the \texttt{hadRole} property. When the \sbol{wasDerivedFrom} property is used together with the full provenance described here, the entity pointed at by the \sbol{wasDerivedFrom} property MUST be included in a \sbol{Usage}.
\paragraph{The \sbolheading{entity} property}\label{sec:entity}
The \sbol{entity} property is REQUIRED and MUST contain a \sbol{URI}s which MAY refer to an SBOL Identified object.
\paragraph{The \sbolheading{hadRole} property}\label{sec:hadRole:usage}
The \sbolmult{hadRole:usage}{hadRole} property is REQUIRED and MAY contain a \sbol{URI} that refers to a particular term describing the usage of an \sbol{entity} referenced by the \sbol{entity} property.
\paragraph{Serialization}
The serialization of an \sbol{Usage} MUST have the following form:
}%\twoonezero{ end
\lstsetsbol
\begin{lstlisting}
<prov:Association rdf:about="...">
... [\emph{properties inherited from identified}] ...
[\emph{one}] <prov:hadRole rdf:resource="..."/> [\emph{element}]
[\emph{one}] <prov:entity rdf:resource="..."/> [\emph{element}]
</prov:Association>
\end{lstlisting}
\twoonezero{
\subsubsection{Plan}
\label{sec:Plan}
The Plan entity can be used as a place holder to describe the steps (for example scripts or lab protocols) taken when an \sbol{Agent} is used in a particular \sbol{Activity}.
\paragraph{Serialization}
The serialization of an \sbol{Usage} MUST have the following form:
}%\twoonezero{ end
\lstsetsbol
\begin{lstlisting}
<prov:Plan rdf:about="...">
... [\emph{properties inherited from identified}] ...
... [\emph{other annotations}] ...
</prov:Plan>
\end{lstlisting}
\twoonezero{
\subsubsection{Agent}
\label{sec:Agent}
Examples of agents are person, organisation or software. These agents should be annotated with additional information, such as software version, needed to be able to run the same software again.
\paragraph{Serialization}
The serialization of an \sbol{Agent} MUST have the following form:
}%\twoonezero{ end
\lstsetsbol
\begin{lstlisting}
<prov:Agent rdf:about="...">
... [\emph{properties inherited from identified}] ...
... [\emph{other annotations}] ...
</prov:Agent>
\end{lstlisting}
\twoonezero{
\paragraph{Example - Codon optimisation}
Codon optimisation is a practical real-wold example where provenance properties can be applied. Using the current specification, the relationship between an original CDS and the codon-optimized version could simply be represented using the prov:wasDerivedFrom predicate, in a light-weight form. With more comprehensive use of the PROV ontology, the codon optimization can be represented as an \sbol{Activity}. This \sbol{Activity} can then include additional information, such as the \sbol{Agent} responsible (in this case, codon-optimizing software), and additional parameters.
}%\twoonezero{ end
\lstsetsbol
\begin{lstlisting}
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:prov="http://www.w3.org/ns/prov#" xmlns:sbol="http://sbols.org/v2#">
<sbol:ComponentDefinition rdf:about="http://cds/codon-optimized">
<dcterms:title>Codon Optimized CDS</dcterms:title>
<prov:wasGeneratedBy rdf:resource="http://codon-optimization-activity"/>
</sbol:ComponentDefinition>
<sbol:ComponentDefinition rdf:about="http://cds/non-codon-optimized">
<dcterms:title>Non Codon Optimized CDS</dcterms:title>
</sbol:ComponentDefinition>
<prov:Activity rdf:about="http://codon-optimization-activity">
<dcterms:title>Codon Optimization Activity</dcterms:title>
<prov:qualifiedUsage>
<prov:Usage rdf:about="http://codon-optimization-activity/usage">
<prov:entity rdf:resource="http://cds/non-codon-optimized"/>
<prov:hadRole rdf:resource="http://sbols.org/v2/role/source"/>
</prov:Usage>
</prov:qualifiedUsage>
<prov:qualifiedAssociation>
<prov:Association rdf:about="http://codon-optimization-activity/usage">
<prov:agent rdf:resource="http://codon-optimization-software"/>
<prov:hadRole rdf:resource="http://sbols.org/v2/role/codonoptimiser"/>
</prov:Association>
</prov:qualifiedAssociation>
</prov:Activity>
<prov:Agent rdf:about="http://codon-optimization-software">
<dcterms:title>Codon Optimization Software</dcterms:title>
</prov:Agent>
</rdf:RDF>
\end{lstlisting}
\twoonezero{
\paragraph{Example - Deriving strains}
Bacterial strains are often derived from other strains through modifications such as gene knockouts or mutations. For example, the \texttt{Bacillus subtilis} 168 strain was derived from the Ncib3610 strain in the 1940s through x-radiation. \textit{B. subtilis} 168 is a laboratory strain and has several advantages as a model organism in synthetic biology. Particularly, the 168 strain is easy to transform and is not motile, facilitating the analysis of engineered cells. The parent strain, on the other hand, is motile but more difficult to transform. The example below shows the derivation of the 168 strain using the new provenance classes.
}%twoonezero end
\lstsetsbol
\begin{lstlisting}
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:prov="http://www.w3.org/ns/prov#" xmlns:sbol="http://sbols.org/v2#">
<sbol:ComponentDefinition rdf:about="http://Bsubtilis168">
<dcterms:title>Bacillus subtilis 168</dcterms:title>
<prov:wasGeneratedBy rdf:resource="http://xraymutagenesis"/>
</sbol:ComponentDefinition>
<sbol:ComponentDefinition rdf:about="http://BsubtilisNcib3610">
<dcterms:title>Bacillus subtilis Ncbi 3016</dcterms:title>
</sbol:ComponentDefinition>
<prov:Activity rdf:about="http://xraymutagenesis">
<dcterms:title>X-ray mutagenesis</dcterms:title>
<prov:endedAtTime>1947</prov:endedAtTime>
<prov:qualifiedUsage>
<prov:Usage rdf:about="http://xraymutagenesis/usage/ncib3016">
<prov:entity rdf:resource="http://BsubtilisNcib3610"/>
<prov:hadRole rdf:resource="http://sbols.org/v2/role/source"/>
</prov:Usage>
</prov:qualifiedUsage>
<prov:qualifiedAssociation>
<prov:Association rdf:about="http://xraymutagenesis/x-ray">
<prov:agent rdf:resource="http://x-ray"/>
<prov:hadRole rdf:resource="http://mutagen"/>
</prov:Association>
</prov:qualifiedAssociation>
</prov:Activity>
<prov:Agent rdf:about="http://x-ray">
<dcterms:title>X-ray</dcterms:title>
</prov:Agent>
</rdf:RDF>
\end{lstlisting}