Python reference¶
These are the calls a script makes. The list is kept by hand, so it stays short. Anything not
here is read from the source in src/mbio/ and src/synbio/.
What to import¶
The root package re-exports only __version__. Import a name from the module that owns it.
from mbio.io import read_record
from mbio.cloning.goldengate import plan_assembly
A few names are spelled more than once, and each one means something different. The module path is what tells them apart.
| Name | Resolves to |
|---|---|
Check |
mbio.checks.Check is the judged check, with the value it measured. mbio.protocol.Check is how a protocol page shows one |
Plan |
Four of them, one per cloning method, each with its own fields. All four are on this page |
Build, read_build |
synbio.igga and synbio.dmx each define both, with different fields. Both pairs are on this page |
Protocol |
mbio.protocol.Protocol is the bench protocol. synbio.igga.protocols.protocol.Protocol is one page of a library run |
Files |
Six of them, one per pipeline. None is on this page. Read what write returns |
Open and save a record¶
read_record takes a SnapGene .dna file, a GenBank file or a FASTA file. read_region
pulls one span out of a large FASTA, through the .fai index beside it.
mbio.io.read_record
¶
read_record(path: str | PathLike[str]) -> SequenceRecord
Read a .dna, GenBank or FASTA file holding one sequence.
The colours SnapGene writes into a GenBank file's notes become Feature.color and
Segment.color, and those notes leave the qualifiers.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the suffix names no reader, or the file holds no single record. |
Source code in src/mbio/io.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | |
mbio.io.read_region
¶
read_region(
path: str | PathLike[str],
sequence_name: str,
start: int,
end: int,
) -> SequenceRecord
Read one span of one sequence of a FASTA, through the .fai index beside it.
Only the bytes the index points at are read, so a region of a chromosome costs the same on
a whole genome as on a small file. start and end are 0-based and half-open: a start
below zero reads from the first base, and an end past the sequence reads to its last. The
record comes back linear and upper-case, named as the FASTA spells it.
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If no index lies beside the FASTA. |
ValueError
|
If the index names no such sequence, the span holds no base of it, or the FASTA does not read as the index describes. |
Examples:
>>> read_region("hg38.fa", "chr1", 156710401, 156710421).sequence
'ACCTAGGAGAAGTGGCCAGC'
Source code in src/mbio/io.py
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 | |
mbio.snapgene.write_dna
¶
write_dna(
record: SequenceRecord, path: str | PathLike[str]
) -> None
Write record as a SnapGene .dna file.
A feature or primer unchanged since the file it was read from is written back verbatim, so that what the model does not hold survives. A feature with no colour takes SnapGene's default grey.
Source code in src/mbio/snapgene.py
259 260 261 262 263 264 265 266 | |
The record¶
Coordinates are 0-based and half-open. The first base is 0, and a span's end is the first base after it. A span that crosses the origin of a circular record ends past the record's length.
mbio.sequence.SequenceRecord
dataclass
¶
A DNA sequence with its topology, features, primers and notes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sequence
|
str
|
Stored upper-case. |
required |
topology
|
Topology
|
|
'linear'
|
name
|
str
|
The name shown on a map. |
''
|
features
|
tuple[Feature, ...]
|
Every feature and primer binding site must fit the sequence under its topology. On a circular record a feature's first segment fits, the rest follow it in ascending order, and the whole spans at most one turn. |
()
|
primers
|
tuple[Feature, ...]
|
Every feature and primer binding site must fit the sequence under its topology. On a circular record a feature's first segment fits, the rest follow it in ascending order, and the whole spans at most one turn. |
()
|
notes
|
Mapping[str, str]
|
Descriptive fields, such as |
dict()
|
extras
|
Mapping[str, object]
|
Format-specific data a reader keeps for its writer. Ignored by |
dict()
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/mbio/sequence.py
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 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | |
__len__
¶
__len__() -> int
Return the number of bases.
Source code in src/mbio/sequence.py
274 275 276 | |
__post_init__
¶
__post_init__() -> None
Upper-case the sequence and check every span fits.
Source code in src/mbio/sequence.py
263 264 265 266 267 268 269 270 271 272 | |
bases
¶
bases(start: int, end: int) -> str
Return the top-strand bases in [start, end), reading across the origin.
On a circular record a position counts round the circle, so start may lie outside the
record; the span is at most one turn long.
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
>>> SequenceRecord("AACCGGTTAC", topology="circular").bases(-2, 2)
'ACAA'
Source code in src/mbio/sequence.py
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 | |
covers
¶
Whether span holds a position, or the whole of a shorter span, across the origin too.
A feature holds what one of its segments holds. On a circular record a position counts round the circle, so one past the length names the base it reaches there.
Examples:
>>> SequenceRecord("AACCGGTTAC", topology="circular").covers(Segment(8, 12), 1)
True
Source code in src/mbio/sequence.py
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | |
extract
¶
Return the bases under a feature or segment, reading across the origin.
A reverse-strand feature reads as the reverse complement of its joined segments. A bare
segment reads off the top strand. Each segment reads as bases reads it.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the feature or segment does not fit this record, as an annotation must. |
Examples:
>>> SequenceRecord("AACCGGTTAC", topology="circular").extract(Segment(8, 12))
'ACAA'
Source code in src/mbio/sequence.py
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 | |
fits
¶
fits(start: int, end: int) -> bool
Whether [start, end) lies on this record, as every span it annotates must.
On a linear record it lies inside the bases. On a circular one it starts inside them and is at most one turn long, ending past the length across the origin. An empty span fits wherever a base could be inserted.
Examples:
>>> SequenceRecord("AACCGGTTAC", topology="circular").fits(8, 12)
True
Source code in src/mbio/sequence.py
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | |
span
¶
span(start: int, width: int) -> Segment
Return the width bases at start, counted round the origin, clipped on a line.
A circular record counts start round the circle, so a span reaching past the last
base ends past the record's length. A linear record has nothing outside its bases, so
a span hanging off either end is cut back to them. bases is handed the far end
instead of a width.
Raises:
| Type | Description |
|---|---|
ValueError
|
If nothing is left: a width of no bases, or a linear span wholly off the record. |
Examples:
>>> SequenceRecord("AACCGGTTAC", topology="circular").span(18, 4)
Segment(start=8, end=12, name='', color=None)
>>> SequenceRecord("AACCGGTTAC").span(-2, 6)
Segment(start=0, end=4, name='', color=None)
Source code in src/mbio/sequence.py
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | |
mbio.sequence.Feature
dataclass
¶
A named, typed annotation over one or more segments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The label shown on a map. |
required |
type
|
str
|
A GenBank feature key, such as |
required |
segments
|
tuple[Segment, ...]
|
In the order the feature reads them along the top strand, so a reverse-strand feature reads them last to first. On a circular record they start in ascending order: a segment after the origin starts past the record's length, as one across it ends past it. A linear record has no origin to cross, so a feature cut apart at its two ends lists the higher start first. |
required |
strand
|
Strand
|
The strand the feature reads along. |
NONE
|
qualifiers
|
Mapping[str, tuple[str | int, ...]]
|
GenBank-style qualifiers, each holding one or more values. |
dict()
|
color
|
str | None
|
|
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/mbio/sequence.py
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 | |
__post_init__
¶
__post_init__() -> None
Refuse a feature with no segment.
Source code in src/mbio/sequence.py
139 140 141 142 | |
counted_round
¶
counted_round(length: int) -> Feature
Return this feature as a circular record of length bases holds it.
Each segment keeps its width and its place in the reading order, starts where it lies in the record, and is then counted round past the length if it comes after the origin.
Examples:
>>> Feature("f", "CDS", (Segment(91, 98), Segment(2, 8))).counted_round(100).segments[1]
Segment(start=102, end=108, name='', color=None)
Source code in src/mbio/sequence.py
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | |
mbio.sequence.Segment
dataclass
¶
One contiguous span of a feature.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
int
|
0-based, half-open. |
required |
end
|
int
|
0-based, half-open. |
required |
name
|
str
|
A label for this segment alone, such as a promoter's |
''
|
color
|
str | None
|
|
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
Unless |
Source code in src/mbio/sequence.py
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 | |
__post_init__
¶
__post_init__() -> None
Refuse an empty or negative span.
Source code in src/mbio/sequence.py
97 98 99 | |
mbio.sequence.Primer
dataclass
¶
A named oligonucleotide.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name it is ordered under. |
required |
sequence
|
str
|
5' to 3', tail included. Stored upper-case. |
required |
binding_sites
|
tuple[BindingSite, ...]
|
Where it anneals to the record that carries it. |
()
|
description
|
str
|
Free text. |
''
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/mbio/sequence.py
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 | |
__post_init__
¶
__post_init__() -> None
Upper-case and check the sequence.
Source code in src/mbio/sequence.py
221 222 223 | |
mbio.sequence.Strand
¶
Bases: IntEnum
The strand a feature or primer binding site lies on.
Source code in src/mbio/sequence.py
60 61 62 63 64 65 66 67 | |
mbio.sequence.reverse_complement
¶
reverse_complement(sequence: str) -> str
Return the reverse complement of an IUPAC DNA sequence, keeping its case.
Examples:
>>> reverse_complement("GGTCTC")
'GAGACC'
Source code in src/mbio/sequence.py
37 38 39 40 41 42 43 44 45 | |
A check¶
Most of what the package judges comes back as a list of these. One check holds the name of what was measured, the measurement, and a status. Where no sourced threshold can judge the value, the check carries no verdict rather than a pass.
mbio.checks.Check
dataclass
¶
One verdict on a primer, a pair or an assembled product, with the value it judged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
What was measured, such as |
required |
status
|
Status | None
|
One of |
required |
value
|
float
|
The measurement, in the unit the module that judged it documents. |
required |
detail
|
str
|
What a reader needs besides the number. |
''
|
Source code in src/mbio/checks.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
Plan a cloning job¶
Four methods, four ways in. Each one returns a Plan. Each Plan.write puts the product, the
oligo sheet and the protocol into one directory.
One field name collides. gibson.Plan.product is the assembly kit: the reaction mix and the
rules that come with it. The plasmid the assembly makes is gibson.Plan.plasmid. Every other
method's .product is the record.
Two other fields are easy to miss. restriction.Plan.refusals says why every other enzyme
pair was refused. gateway.Plan.write adds the entry clone as a fifth file, where a BP
reaction was planned.
mbio.cloning.goldengate.plan_assembly
¶
plan_assembly(
vector: SequenceRecord | str | PathLike[str],
*inserts: SequenceRecord | str | PathLike[str],
site: Site = None,
orientation: Orientation
| Sequence[Orientation] = "forward",
in_frame: bool | Sequence[bool] = False,
enzyme: EnzymeLike | None = None,
codon_table: str = DEFAULT_TABLE,
profile: LigaseProfile
| str
| PathLike[str]
| None = None,
prefer_profile: bool = False,
polymerase: Polymerase = Q5,
host: str = DEFAULT_HOST,
cleanup_kit: str = "",
name: str = "",
window: int = VECTOR_WINDOW,
thresholds: Mapping[
PrimerRole, Thresholds
] = THRESHOLDS_FOR,
) -> Plan
Plan one Golden Gate experiment putting inserts into vector.
One reaction joins as many inserts as the overhangs allow, given in the order they go round
the product. The vector is opened by PCR across the span they replace, each insert is
amplified with tails of its own, and every junction is scarless: it takes the bases the part
already spells there. Only the vector junction may slide, by up to window bases, to get
past an overhang rule, which moves where the vector is cut and not what the inserts spell.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vector
|
SequenceRecord | str | PathLike[str]
|
A record, or a path to a |
required |
inserts
|
SequenceRecord | str | PathLike[str]
|
A record, or a path to a |
required |
site
|
Site
|
Where the inserts go: a feature name, a |
None
|
orientation
|
Orientation | Sequence[Orientation]
|
|
'forward'
|
in_frame
|
bool | Sequence[bool]
|
Hold an insert's junction on a codon boundary of the coding sequence it lies in. One value covers every insert; a sequence gives one for each. |
False
|
enzyme
|
EnzymeLike | None
|
The Type IIS enzyme to use. Chosen by |
None
|
codon_table
|
str
|
Whose codon usage a proposed domestication picks its codons from, named as
|
DEFAULT_TABLE
|
profile
|
LigaseProfile | str | PathLike[str] | None
|
A ligase fidelity matrix the caller holds, as a path or an already read |
None
|
prefer_profile
|
bool
|
Use it even where a shipped matrix covers the enzyme. |
False
|
polymerase
|
Polymerase
|
For the PCRs. The colony PCR uses OneTaq, which is what NEB's protocol asks for. |
Q5
|
host
|
str
|
The strain the protocol names, and what to call the product. |
DEFAULT_HOST
|
name
|
str
|
The strain the protocol names, and what to call the product. |
DEFAULT_HOST
|
cleanup_kit
|
str
|
The spin-column kit the protocol names, by catalogue number or by name, as
|
''
|
window
|
int
|
How far the vector junction may slide. |
VECTOR_WINDOW
|
thresholds
|
Mapping[PrimerRole, Thresholds]
|
For each role, what its oligos are designed and judged by in |
THRESHOLDS_FOR
|
Returns:
| Type | Description |
|---|---|
Plan
|
The design, the simulated product and the validation. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If no shipped codon usage table is called |
ValueError
|
If no insert is given, if no insertion site is named and the vector annotates none, if
the enzyme reads a site in a part, if no overhang passes every rule, if |
Source code in src/mbio/cloning/goldengate/plan.py
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 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 | |
mbio.cloning.goldengate.Plan
dataclass
¶
One planned Golden Gate experiment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vector
|
SequenceRecord
|
The records the plan was made from, the inserts in the order they go round the product and each on the strand that goes in. |
required |
inserts
|
SequenceRecord
|
The records the plan was made from, the inserts in the order they go round the product and each on the strand that goes in. |
required |
span
|
tuple[int, int]
|
The vector bases the assembly replaces, after any junction slide. |
required |
choice
|
EnzymeChoice
|
The enzyme the plan uses, and what using it costs. |
required |
ranking
|
tuple[EnzymeChoice, ...]
|
Every candidate enzyme, best first. |
required |
overhangs
|
OverhangSet
|
The overhang every junction takes, with the fidelity of the whole set. An assembly of n inserts has n + 1 junctions. |
required |
linearised_vector
|
Part
|
The part the vector is opened into. |
required |
insert_parts
|
tuple[Part, ...]
|
The part each insert is amplified into, in insert order. |
required |
assembly
|
Assembly
|
The simulated product, the parts and the junctions. |
required |
colony
|
ColonyCheck
|
The colony PCR that reads every junction and tells a correct clone from an empty vector. No insert can go in the other way round, so there is no lane for one. |
required |
reads
|
tuple[SangerRead, SangerRead]
|
A sequencing primer reading in from outside the first junction and the last. |
required |
amounts
|
tuple[Amount, ...]
|
What to put in the assembly reaction, vector first. |
required |
phenotype
|
Phenotype
|
What the product says about itself. |
required |
designed_oligos
|
tuple[DesignedOligo, ...]
|
Every designed oligo and what it is for, in order: each part's PCR, the colony PCR, the reads. |
required |
host
|
str
|
The choices the protocol names. |
required |
polymerase
|
str
|
The choices the protocol names. |
required |
cleanup_kit
|
Material
|
The spin-column kit the protocol names, as |
kit()
|
thresholds
|
Mapping[PrimerRole, Thresholds]
|
What those oligos were designed and judged by, for each role, so a page prints the band beside the value. |
THRESHOLDS_FOR
|
Source code in src/mbio/cloning/goldengate/plan.py
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 | |
write
¶
write(directory: str | PathLike[str]) -> Files
Write the product, the amplicons, the primer sheet, the protocol, its page and maps.
The directory is made when it is not there. The files are named by PRODUCT_FILE,
amplicon_files and PRIMER_FILE, and by mbio.protocol.render for the protocol
pair, and a second run over the same inputs writes the same bytes.
Source code in src/mbio/cloning/goldengate/plan.py
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | |
mbio.cloning.gibson.plan_gibson
¶
plan_gibson(
vector: SequenceRecord | str | PathLike[str],
*inserts: SequenceRecord | str | PathLike[str],
site: Site = None,
orientation: Orientation
| Sequence[Orientation] = "forward",
route: Route | Sequence[Route] = "amplify",
bridge: Sequence[tuple[str, str]] = (),
product: AssemblyProduct = NEBUILDER_HIFI,
polymerase: Polymerase = Q5,
host: str = DEFAULT_HOST,
cleanup_kit: str = "",
name: str = "",
thresholds: Mapping[
PrimerRole, Thresholds
] = THRESHOLDS_FOR,
) -> Plan
Plan one Gibson experiment putting inserts into vector.
The inserts go round the product in the order they are given. A circular vector is opened
by PCR across the span they replace; one that is already linear is taken as the opened part
as it is. Every junction takes its overlap at the length and melting temperature product
documents, by the rules mbio.cloning.gibson.design states, and the part on the
other side carries those bases as a 5' tail, so the junction adds nothing.
Which side the bases come from is the note's vector rule: a junction with the vector on either side takes the vector's own bases, so the opened backbone needs no tail and can be made once and reused. Every other junction takes the bases of the insert before it.
A colony PCR and two sequencing primers are then designed over
mbio.cloning.gibson.assembly.Assembly.boundaries, where one part gives way to the
next: the overlap is one part's own bases, so the boundary is not where the junction begins.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vector
|
SequenceRecord | str | PathLike[str]
|
A record, or a path to a |
required |
inserts
|
SequenceRecord | str | PathLike[str]
|
A record, or a path to a |
required |
site
|
Site
|
Where the inserts go: a feature name, a |
None
|
orientation
|
Orientation | Sequence[Orientation]
|
|
'forward'
|
route
|
Route | Sequence[Route]
|
|
'amplify'
|
bridge
|
Sequence[tuple[str, str]]
|
Junctions joined by one oligo carrying homology to both ends, each named by the two parts it joins in the order they go round the product. Neither of the two then carries a tail, so a fragment amplified for something else goes in as it is. |
()
|
product
|
AssemblyProduct
|
The assembly product on the bench, which sets the overlap rule, the reaction, the incubation, the molar ratio and the fragment count it is documented for. |
NEBUILDER_HIFI
|
polymerase
|
Polymerase
|
For the PCRs. |
Q5
|
host
|
str
|
The strain the protocol names, and what to call the plasmid. |
DEFAULT_HOST
|
name
|
str
|
The strain the protocol names, and what to call the plasmid. |
DEFAULT_HOST
|
cleanup_kit
|
str
|
The spin-column kit the protocol names, by catalogue number or by name, as
|
''
|
thresholds
|
Mapping[PrimerRole, Thresholds]
|
For each role, what its oligos are designed and judged by in |
THRESHOLDS_FOR
|
Returns:
| Type | Description |
|---|---|
Plan
|
The design, the simulated plasmid and what the bench takes. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no insert is given, if an orientation is neither |
Source code in src/mbio/cloning/gibson/plan.py
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 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 | |
mbio.cloning.gibson.Plan
dataclass
¶
One planned Gibson experiment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vector
|
SequenceRecord
|
The records the plan was made from, each insert on the strand that goes in. |
required |
inserts
|
SequenceRecord
|
The records the plan was made from, each insert on the strand that goes in. |
required |
span
|
tuple[int, int]
|
The vector bases the inserts replace. Empty, at the vector's end, where the vector was handed in linear and nothing was taken out of it. |
required |
product
|
AssemblyProduct
|
The assembly product on the bench, which sets the overlap rule, the reaction and the incubation. |
required |
linearised_vector
|
Part
|
The part the vector is opened into. |
required |
insert_parts
|
tuple[Part, ...]
|
The part each insert is amplified into, in insert order. |
required |
assembly
|
Assembly
|
The simulated plasmid, the parts and the junctions. |
required |
colony
|
ColonyCheck
|
The colony PCR that reads every junction and tells a correct clone from an empty vector. No insert can go in the other way round, so there is no lane for one. |
required |
reads
|
tuple[SangerRead, SangerRead]
|
A sequencing primer reading in from outside the first junction and the last. |
required |
amounts
|
tuple[Amount, ...]
|
What to put in the assembly reaction, vector first. |
required |
phenotype
|
Phenotype
|
What the plasmid says about itself. |
required |
designed_oligos
|
tuple[DesignedOligo, ...]
|
Every designed oligo and what it is for, in order: each part's forward and reverse primer, the colony PCR, the reads. |
required |
ordered_oligos
|
tuple[OrderedOligo, ...]
|
Every oligo the plan orders that primes nothing: a stitched part's, then any bridging oligo. Nothing measures one, so its row carries no verdict. |
required |
host
|
str
|
The choices the protocol names. |
required |
polymerase
|
str
|
The choices the protocol names. |
required |
cleanup_kit
|
Material
|
The spin-column kit the protocol names, as |
kit()
|
thresholds
|
Mapping[PrimerRole, Thresholds]
|
What those oligos were designed and judged by, for each role, so a page prints the band beside the value. |
THRESHOLDS_FOR
|
Source code in src/mbio/cloning/gibson/plan.py
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 | |
plasmid
property
¶
plasmid: SequenceRecord
The circular plasmid the assembly makes.
Named apart from product, which is the kit the reaction is run with.
checks
property
¶
checks: tuple[Check, ...]
What the plan is judged on: the plasmid, every overlap, the reaction and the oligos.
The ones no sourced threshold judges carry no verdict, and say in their detail that nothing measured them.
write
¶
write(directory: str | PathLike[str]) -> Files
Write the plasmid, the oligo sheet, the protocol, its page and its maps into directory.
The directory is made when it is not there. The files are named by
mbio.cloning.plan and mbio.protocol.render, and a second run over the same inputs
writes the same bytes.
Source code in src/mbio/cloning/gibson/plan.py
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | |
mbio.cloning.restriction.plan_restriction
¶
plan_restriction(
vector: SequenceRecord | str | PathLike[str],
insert: SequenceRecord | str | PathLike[str],
*,
enzymes: Sequence[EnzymeLike] = (),
polymerase: Polymerase = Q5,
host: str = DEFAULT_HOST,
cleanup_kit: str = "",
name: str = "",
thresholds: Mapping[
PrimerRole, Thresholds
] = THRESHOLDS_FOR,
) -> Plan
Plan getting an insert to two cut ends and ligating it into vector.
The vector is cut with the enzymes named and its longest piece is the backbone, gel-purified from what the same digest leaves beside it.
insert reaches the same two ends by one of two routes, and what it carries picks one. A
record already reading a site of either enzyme is cut, and the piece between the two sites is
what goes in -- a plasmid the insert already sits in, or a fragment ordered with the sites on
it. A record reading no site of either is amplified first: each primer carries a spacer and a
recognition site as a 5' tail, and the amplicon is cut instead. Either way the insert is
written on whichever strand closes the circle, so which way round it lay does not matter.
Naming no enzyme hands the choice to mbio.cloning.restriction.design.choose_pair,
which weighs every pair the package ships and leaves Plan.refusals saying what refused the
rest. Naming enzymes wins over it, and an unusable pair is refused in the chooser's own words.
The junction is not scarless. The two ends came from a recognition site and ligating them
puts that site back, so the product gains those bases and Plan.junctions says what each one
spells.
Where the backbone's two ends anneal to each other -- one enzyme cutting both, two enzymes leaving compatible ends, or blunt ends -- the vector closes on itself with no insert and the insert goes in either way round. Neither is refused: the plan dephosphorylates the backbone, and its colony PCR reads out of the insert itself, which is what tells a reversed clone from a correct one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vector
|
SequenceRecord | str | PathLike[str]
|
A record, or a path to a |
required |
insert
|
SequenceRecord | str | PathLike[str]
|
A record, or a path to a |
required |
enzymes
|
Sequence[EnzymeLike]
|
One or two enzymes, each an |
()
|
polymerase
|
Polymerase
|
For the insert's PCR, where one is run. |
Q5
|
host
|
str
|
The competent strain the protocol names, and what to call the product. The colony PCR uses OneTaq, which is what NEB's protocol asks for. |
DEFAULT_HOST
|
name
|
str
|
The competent strain the protocol names, and what to call the product. The colony PCR uses OneTaq, which is what NEB's protocol asks for. |
DEFAULT_HOST
|
cleanup_kit
|
str
|
The spin-column kit the protocol names, by catalogue number or by name, as
|
''
|
thresholds
|
Mapping[PrimerRole, Thresholds]
|
For each role, what its oligos are designed and judged by in |
THRESHOLDS_FOR
|
Returns:
| Type | Description |
|---|---|
Plan
|
The digests, the simulated product and the validation. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If a name is not one the package ships. |
ValueError
|
If the vector is not circular, if an enzyme does not cut what is cut or the enzymes cut it too often, if no tail spells one site, if the insert's ends do not anneal to the backbone's, or if no pair can be chosen at all. |
Source code in src/mbio/cloning/restriction/plan.py
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 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | |
mbio.cloning.restriction.Plan
dataclass
¶
One planned restriction and ligation cloning.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vector
|
SequenceRecord
|
The records the plan was made from: the plasmid the backbone comes out of, and the one the insert comes from -- the plasmid it is cut out of, or the insert itself. |
required |
source
|
SequenceRecord
|
The records the plan was made from: the plasmid the backbone comes out of, and the one the insert comes from -- the plasmid it is cut out of, or the insert itself. |
required |
enzymes
|
tuple[Enzyme, ...]
|
The enzymes both digests use, in the order they were named. |
required |
vector_pieces
|
tuple[Piece, ...]
|
Every piece each digest leaves, the one that goes on first. The rest is what the gel separates it from. |
required |
source_pieces
|
tuple[Piece, ...]
|
Every piece each digest leaves, the one that goes on first. The rest is what the gel separates it from. |
required |
amplicon
|
Amplicon | None
|
The PCR that put a site on each end of the insert, or |
required |
ligation
|
Ligation
|
The simulated product, the pieces and the junctions. |
required |
span
|
tuple[int, int]
|
The vector bases the insert replaces. |
required |
digests
|
tuple[Amount, Amount]
|
What each digest takes, the vector's first. |
required |
amounts
|
tuple[Amount, Amount]
|
What to put in the ligation, the backbone first. |
required |
diagnostic
|
Diagnostic
|
The digest that says a miniprep carries the insert, and the bands it should give. |
required |
colony
|
ColonyCheck
|
The colony PCR that reads both junctions and tells a correct clone from an empty vector. |
required |
reads
|
tuple[SangerRead, SangerRead]
|
A sequencing primer reading in from outside the first junction and the last. |
required |
designed_oligos
|
tuple[DesignedOligo, ...]
|
Every oligo the plan designs and what it is for, in the order the sheet lists them: the amplification pair where there is one, then the colony PCR, then the sequencing. |
required |
phenotype
|
Phenotype
|
What the product says about itself. |
required |
host
|
str
|
The competent strain the protocol names, and what the insert is amplified with. |
required |
polymerase
|
str
|
The competent strain the protocol names, and what the insert is amplified with. |
required |
cleanup_kit
|
Material
|
The spin-column kit the protocol names, as |
kit()
|
thresholds
|
Mapping[PrimerRole, Thresholds]
|
What the oligos were designed and judged by, for each role, so a page prints the band beside the value. |
THRESHOLDS_FOR
|
refusals
|
tuple[Refusal, ...]
|
Every pair the chooser weighed and refused, with the rule that refused each. Empty where the enzymes were named, because then nothing was weighed against them. |
()
|
Source code in src/mbio/cloning/restriction/plan.py
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 | |
checks
property
¶
checks: tuple[Check, ...]
Every verdict the plan carries, in the order the bench meets them.
The digest's five first, then the product's own, then what the ligation takes and what
confirms it. mbio.cloning.restriction.verdicts is where each one's threshold and
its source are written down, and the buffer is the one nothing sourced can judge.
write
¶
write(directory: str | PathLike[str]) -> Files
Write the product, the oligo sheet, the protocol, its page and its maps into directory.
The directory is made when it is not there. The names are mbio.cloning.plan's and
mbio.protocol.render's, and a second run over the same inputs writes the same bytes.
Source code in src/mbio/cloning/restriction/plan.py
286 287 288 289 290 291 292 293 294 295 296 297 298 299 | |
mbio.cloning.gateway.plan_gateway
¶
plan_gateway(
carrier: SequenceRecord | str | PathLike[str],
destination: SequenceRecord | str | PathLike[str],
*,
donor: SequenceRecord
| str
| PathLike[str]
| None = None,
amplify: bool = False,
fusion: Fusion = "none",
polymerase: Polymerase = Q5,
host: str = DEFAULT_HOST,
cleanup_kit: str = "",
name: str = "",
thresholds: Mapping[
PrimerRole, Thresholds
] = THRESHOLDS_FOR,
) -> Plan
Plan the reactions that put one insert into a destination vector.
There are three routes. With no donor vector the carrier is an entry clone and one LR
reaction is planned. With a donor vector the carrier is an attB-flanked insert -- a
synthesised fragment, or an amplicon made elsewhere -- and BP is planned first, its entry
clone feeding LR. With amplify as well, the carrier is a plain insert carrying no att
site: it is amplified onto attB ends first, and that amplicon is what BP takes.
The att sites are found in every record rather than matched against a constant, because the vendor states that the sequences drift between products. Each record is then read on the strand its site 1 lies on, the segment between the carrier's sites is recombined into the acceptor's backbone, and each product is simulated base for base. The four G residues an attB primer carries leave with the by-product, so the entry clone is the same record whichever of the two BP routes made it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
carrier
|
SequenceRecord | str | PathLike[str]
|
The entry clone, the attB-flanked insert when |
required |
destination
|
SequenceRecord | str | PathLike[str]
|
The destination vector, the same way. It must be circular. |
required |
donor
|
SequenceRecord | str | PathLike[str] | None
|
The donor vector, the same way, to plan the BP reaction that makes the entry clone. It must be circular. |
None
|
amplify
|
bool
|
Design attB-tailed primers for the carrier and amplify it, for an insert carrying no att site of its own. |
False
|
fusion
|
Fusion
|
Which tag the insert is read into: it decides the frame bases the tails carry, and which att junctions the reading frame is judged at. |
'none'
|
polymerase
|
Polymerase
|
For the attB PCR. |
Q5
|
host
|
str
|
The strain the protocol names for selecting each clone. |
DEFAULT_HOST
|
cleanup_kit
|
str
|
The spin-column kit the protocol names, by catalogue number or by name, as
|
''
|
name
|
str
|
What to call the expression clone. |
''
|
thresholds
|
Mapping[PrimerRole, Thresholds]
|
For each role, what its oligos are designed and judged by in |
THRESHOLDS_FOR
|
Returns:
| Type | Description |
|---|---|
Plan
|
The reactions planned, what each takes, the oligos designed, and the checks. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If any record does not carry the pair of att sites its side of a reaction needs, pointing at each other; if a vector that must be circular is not; if no annealing region fits an end of an insert being amplified; or if the DNA does not fit a reaction. |
Source code in src/mbio/cloning/gateway/plan.py
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 346 347 348 349 350 351 352 | |
mbio.cloning.gateway.Plan
dataclass
¶
One planned Gateway experiment: the LR reaction, and the BP that fed it or not.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lr
|
PlannedReaction
|
The LR reaction, which every plan runs. |
required |
bp
|
PlannedReaction | None
|
The BP reaction before it, or |
required |
host
|
str
|
The strain the protocol names for selecting each clone. |
required |
colony
|
ColonyCheck
|
The colony PCR reading across both attB junctions, and the lanes it should give: the correct clone and the destination vector that never recombined. |
required |
reads
|
tuple[SangerRead, SangerRead]
|
A sequencing primer reading in from outside the first attB junction and the last. |
required |
designed_oligos
|
tuple[DesignedOligo, ...]
|
Every oligo the plan designs and what it is for, in the order the sheet lists them: the attB pair where there is one, then the colony PCR, then the sequencing. |
required |
amplicon
|
Amplicon | None
|
The attB PCR that made the DNA BP takes, or |
None
|
cleanup_kit
|
Material
|
The spin-column kit the protocol names, as |
kit()
|
fusion
|
Fusion
|
Which tag the insert is read into, which is what says where a fusion reads through an att junction and so where the reading frame is judged. |
'none'
|
thresholds
|
Mapping[PrimerRole, Thresholds]
|
What the oligos were designed and judged by, for each role, so a page prints the band beside the value. |
THRESHOLDS_FOR
|
Source code in src/mbio/cloning/gateway/plan.py
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 | |
entry
property
¶
entry: SequenceRecord
The entry clone LR ran on: the one given, or the one BP made.
checks
property
¶
checks: tuple[Check, ...]
Every verdict the plan carries, in the order the bench meets them.
The oligos come first, then each reaction's own, then the plan's, which span both -- the insert, the host, the markers and the frame. One of those carries no verdict, because the sources judge no threshold for it.
write
¶
write(directory: str | PathLike[str]) -> Files
Write the clones, the oligo sheet, the protocol, its page and its maps into directory.
The directory is made when it is not there. The entry clone is written only where BP
was planned, under ENTRY_FILE; the rest are named by PRODUCT_FILE, PRIMER_FILE and
by mbio.protocol.render for the protocol pair. A second run over the same inputs
writes the same bytes.
Source code in src/mbio/cloning/gateway/plan.py
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | |
Design primers¶
The mbio primers design command covers the usual job, and the
command line reference describes it. What a script adds is control. You can name a
placement by hand, read every ranked pair instead of the winner, judge an oligo you already
hold, and read each check that fired.
POLYMERASES is the four polymerases the package ships. Each one carries the buffer its Tm is
computed in, and its own cycling rules.
mbio.primers.design_pair
¶
design_pair(
template: SequenceRecord,
start: int,
end: int,
*,
forward_placement: Placement | None = None,
reverse_placement: Placement | None = None,
forward_tail: str = "",
reverse_tail: str = "",
forward_name: str = "",
reverse_name: str = "",
target_tm: float = TARGET_TM,
polymerase: Polymerase = Q5,
thresholds: Thresholds = THRESHOLDS,
exclude: Container[BindingSite] = (),
) -> tuple[Primer, Primer]
Design a pair amplifying start to end, judged on what a pair adds as well.
end passes the length of a circular template when the amplicon crosses the origin. Each
candidate is judged as in design_primer, and every pair of them adds pair_checks: the
gap between the two Tms, the heterodimers and the products. The pair chosen ranks best on
its worst status, then on the same keys summed over both primers, so a pair worse than a
pass means nothing here passes; ranked_pairs gives the rest in that order. A placement
widens either primer's search; the two bound the amplicon between them, which is why
nothing takes an amplicon size. Neither primer takes a binding site in exclude.
Raises:
| Type | Description |
|---|---|
ValueError
|
If no annealing region fits the template at either end, or fits that end's placement,
or |
Examples:
>>> template = SequenceRecord(
... "GGCGTAATCATGGTCATAGCTGTTTCCTGTGTGAAATTGTTATCCGCT"
... "TACAGGATCCACTAGTAACGGCCGCCAGTGTGCTGGAATTCGCCCTTA"
... )
>>> [primer.sequence for primer in design_pair(template, 0, len(template))]
['GGCGTAATCATGGTCATAGC', 'TAAGGGCGAATTCCAGCA']
In a region, where each primer is free inside its own flank and the two bound the amplicon:
>>> forward = Placement(five_prime=Segment(0, 6), three_prime=Segment(15, 35))
>>> reverse = Placement(five_prime=Segment(90, 96), three_prime=Segment(60, 80))
>>> pair = design_pair(
... template,
... 0,
... len(template),
... forward_placement=forward,
... reverse_placement=reverse,
... )
>>> [primer.sequence for primer in pair]
['CGTAATCATGGTCATAGCTGTT', 'CGAATTCCAGCACACTGG']
Source code in src/mbio/primers/design.py
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 | |
mbio.primers.design_primer
¶
design_primer(
template: SequenceRecord,
position: int,
strand: Strand,
*,
placement: Placement | None = None,
tail: str = "",
name: str = "",
target_tm: float = TARGET_TM,
polymerase: Polymerase = Q5,
thresholds: Thresholds = THRESHOLDS,
) -> Primer
Design a primer annealing at a position on a template, or anywhere a Placement allows.
A forward primer's annealing region starts at position and reads towards higher
coordinates; a reverse primer's ends there and reads back. Either crosses the origin of a
circular template. placement widens the search to every binding site it allows, and
position stays the 5' end asked for. Each candidate, at every length Thresholds.length
does not fail, is judged whole by evaluate_primer on the template, structures, runs and
off-target sites included, so a designed primer is worse than a pass only where nothing the
placement allows passes. Candidates rank by worst status, then by how many checks did not
pass, then by the band a length passes on, then by the Tm nearest target_tm, then by
nearness to position, and the shorter primer breaks a tie. tail joins its 5' end and
stays out of the binding site.
Raises:
| Type | Description |
|---|---|
ValueError
|
If no annealing region fits the template there, or fits the placement. |
Examples:
>>> template = SequenceRecord(
... "GGCGTAATCATGGTCATAGCTGTTTCCTGTGTGAAATTGTTATCCGCT"
... "TACAGGATCCACTAGTAACGGCCGCCAGTGTGCTGGAATTCGCCCTTA"
... )
>>> design_primer(template, 0, Strand.FORWARD, name="MCS fwd").sequence
'GGCGTAATCATGGTCATAGC'
Anchored, where a tail has to join the 5' end at one place and only the length may vary:
>>> anchored = Placement(five_prime=Segment(48, 49))
>>> design_primer(template, 48, Strand.FORWARD, placement=anchored, tail="TTGGTCTCA").sequence
'TTGGTCTCATACAGGATCCACTAGTAACGG'
Near a target, where the 3' end has to land 10 to 21 bases before a junction:
>>> junction = 48
>>> near = Placement(three_prime=Segment(junction - 21, junction - 9))
>>> primer = design_primer(template, junction - 40, Strand.FORWARD, placement=near)
>>> primer.sequence, junction - primer.binding_sites[0].end
('ATCATGGTCATAGCTGTTTCC', 21)
In a region, where both ends are free inside a flank:
>>> region = Placement(five_prime=Segment(0, 6), three_prime=Segment(20, 40))
>>> design_primer(template, 0, Strand.FORWARD, placement=region).sequence
'CGTAATCATGGTCATAGCTGTT'
Source code in src/mbio/primers/design.py
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 | |
mbio.primers.ranked_pairs
¶
ranked_pairs(
template: SequenceRecord,
start: int,
end: int,
*,
forward_placement: Placement | None = None,
reverse_placement: Placement | None = None,
forward_tail: str = "",
reverse_tail: str = "",
forward_name: str = "",
reverse_name: str = "",
target_tm: float = TARGET_TM,
polymerase: Polymerase = Q5,
thresholds: Thresholds = THRESHOLDS,
exclude: Container[BindingSite] = (),
) -> Iterator[PairReport]
Yield every pair design_pair chooses between, best first, judged as by evaluate_pair.
The first is the pair design_pair chooses. A pair is judged only once no pair still to
judge could rank above it, so taking the first few judges few. A pair holding a binding site
in exclude is passed over, and exclude is read as pairs are taken: a site added to it
between two pairs stays out of every later one.
Raises:
| Type | Description |
|---|---|
ValueError
|
As |
Examples:
>>> template = SequenceRecord(
... "GGCGTAATCATGGTCATAGCTGTTTCCTGTGTGAAATTGTTATCCGCT"
... "TACAGGATCCACTAGTAACGGCCGCCAGTGTGCTGGAATTCGCCCTTA"
... )
>>> excluded = set()
>>> pairs = ranked_pairs(template, 0, len(template), exclude=excluded)
>>> best = next(pairs)
>>> [primer.sequence for primer in (best.forward.primer, best.reverse.primer)]
['GGCGTAATCATGGTCATAGC', 'TAAGGGCGAATTCCAGCA']
A site excluded once a pair is taken stays out of every pair after it:
>>> excluded.add(best.reverse.primer.binding_sites[0])
>>> after = next(pairs)
>>> [primer.sequence for primer in (after.forward.primer, after.reverse.primer)]
['GGCGTAATCATGGTCATAGC', 'TAAGGGCGAATTCCAGCAC']
Source code in src/mbio/primers/design.py
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 | |
mbio.primers.evaluate_primer
¶
evaluate_primer(
primer: Primer,
template: SequenceRecord | None = None,
*,
polymerase: Polymerase = Q5,
thresholds: Thresholds = THRESHOLDS,
) -> PrimerReport
Judge one primer, and where it anneals when a template is given.
The annealing region is the 3' part its binding site covers; a primer carrying none is
placed on the template by find_binding_sites, and judged whole without one. Length, GC
and Tm are of the annealing region, runs and structures of the whole primer. A primer
longer than primer3 will align is judged on its 3'-terminal bases. The full-primer Tm and
the 3'-end stability are reported without a verdict.
Examples:
>>> report = evaluate_primer(Primer("M13 fwd", "GTAAAACGACGGCCAGT"))
>>> report["gc_clamp"].value, report.status
(3, 'warn')
Source code in src/mbio/primers/evaluation.py
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | |
mbio.primers.evaluate_pair
¶
evaluate_pair(
forward: Primer,
reverse: Primer,
template: SequenceRecord,
*,
polymerase: Polymerase = Q5,
thresholds: Thresholds = THRESHOLDS,
) -> PairReport
Judge a primer pair on a template, with the amplicon it makes.
Each primer is judged as on its own, and the pair adds the gap between their Tms, their heterodimers, and every product their binding sites can make. An amplicon runs from one primer's 5' end to the other's, tails counted, across the origin where it must.
Examples:
>>> from mbio.primers.design import design_pair
>>> template = SequenceRecord("GGCGTAATCATGGTCATAGCTGTTTCCTGTGTGAAATTGTTATCCGCT")
>>> pair = design_pair(template, 0, len(template))
>>> report = evaluate_pair(pair[0], pair[1], template)
>>> report.amplicon_length, report["products"].status
(48, 'pass')
Source code in src/mbio/primers/evaluation.py
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 | |
mbio.primers.Placement
dataclass
¶
Where a primer's binding site may lie: the positions each of its two ends may take.
A tail fixes the 5' end, a target to read across bounds each end's distance from it, and a
region bounds the amplicon. A position is a boundary, 0-based and half-open as everywhere:
a forward site's 5' end is its start and its 3' end its end, and a reverse site's the other
way round, which is the position design_primer reads. A span runs past the length of a
circular template when it crosses the origin.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
five_prime
|
Segment | None
|
The positions its 5' end may take. |
None
|
three_prime
|
Segment | None
|
The positions its 3' end may take, the same way. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If neither end is bounded, which would say nothing at all. |
Examples:
>>> template = SequenceRecord("ACGT" * 12)
>>> anchored = Placement(five_prime=Segment(0, 1))
>>> anchored.allows(BindingSite(0, 20, Strand.FORWARD), template)
True
>>> anchored.allows(BindingSite(1, 21, Strand.FORWARD), template)
False
Source code in src/mbio/primers/placement.py
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 | |
__post_init__
¶
__post_init__() -> None
Refuse a placement that bounds neither end.
Source code in src/mbio/primers/placement.py
57 58 59 60 | |
allows
¶
allows(site: BindingSite, template: SequenceRecord) -> bool
Return whether both ends of a binding site lie where this placement puts them.
Source code in src/mbio/primers/placement.py
62 63 64 65 66 67 68 | |
mbio.primers.PrimerReport
dataclass
¶
Every check on one primer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
primer
|
Primer
|
The primer judged. |
required |
checks
|
tuple[Check, ...]
|
In the order they were run. |
required |
Source code in src/mbio/primers/evaluation.py
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 | |
__getitem__
¶
__getitem__(name: str) -> Check
Return the check of that name.
Raises:
| Type | Description |
|---|---|
KeyError
|
If no check has it. |
Source code in src/mbio/primers/evaluation.py
58 59 60 61 62 63 64 65 66 | |
mbio.primers.PairReport
dataclass
¶
Every check on a primer pair, and the numbers its PCR needs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
forward
|
PrimerReport
|
What each primer scored on its own. |
required |
reverse
|
PrimerReport
|
What each primer scored on its own. |
required |
checks
|
tuple[Check, ...]
|
What only a pair can be judged on. |
required |
annealing_temperature
|
float
|
°C, by the polymerase's rule over the two annealing regions. |
required |
amplicon_length
|
int | None
|
Bases between the primers' 5' ends, tails included, or |
required |
extension_seconds
|
int | None
|
For that amplicon, or |
required |
Source code in src/mbio/primers/evaluation.py
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 | |
status
property
¶
status: Status
Return the worst status of either primer or of any pair check that was judged.
__getitem__
¶
__getitem__(name: str) -> Check
Return the pair check of that name.
Raises:
| Type | Description |
|---|---|
KeyError
|
If no check has it. |
Source code in src/mbio/primers/evaluation.py
195 196 197 198 199 200 201 202 203 | |
mbio.primers.melting_temperature
¶
melting_temperature(
sequence: str, polymerase: Polymerase = Q5
) -> float
Return the Tm of a sequence in a polymerase's buffer, °C.
The value NEB's Tm Calculator gives for that polymerase.
Examples:
>>> round(melting_temperature("GTAAAACGACGGCCAGT"))
62
Source code in src/mbio/primers/polymerase.py
287 288 289 290 291 292 293 294 295 296 297 298 299 | |
mbio.primers.POLYMERASES
module-attribute
¶
POLYMERASES: tuple[Polymerase, ...] = (
Q5,
PHUSION,
TAQ,
ONETAQ,
)
mbio.primers.design_pair_on_genome
¶
design_pair_on_genome(
fasta: str | Path,
assembly: str,
region: Locus,
*,
flank: int,
forward_tail: str = "",
reverse_tail: str = "",
forward_name: str = "",
reverse_name: str = "",
target_tm: float = TARGET_TM,
polymerase: Polymerase = Q5,
thresholds: Thresholds = THRESHOLDS,
timeout: float = 300.0,
) -> GenomeDesign
Design the best-ranked pair amplifying a genome region that is specific on that genome.
The template is the region and a flank each side, read through the FASTA's index and
clipped to the sequence. The forward primer is placed in the left flank and the reverse in
the right, so the amplicon covers the region whole and ties go to the pair nearest it, as
design_pair ranks one. Thresholds.genome_pairs_per_search pairs are then checked in one
genome search, best-ranked first, and the first making no off-target amplicon wins.
Where none does, the round leaves the search narrower: a primer that makes an off-target
amplicon on its own is kept out of every later pair, as is every binding site sharing its
3' end, which primes the same place; a pair that makes one only together is passed over,
each of its primers still free to pair with another. After Thresholds.genome_rounds
searches, or once the pairs run out, the best-ranked pair checked comes back with its
off-target amplicons, marked not specific.
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If no index lies beside the FASTA. |
RuntimeError
|
If |
TimeoutError
|
If a search runs past |
ValueError
|
If the sequence does not hold the region, or a flank holds no annealing region. |
Examples:
>>> region = Locus("chr1", 156710401, 156710701)
>>> design = design_pair_on_genome("hg38.fa", "hg38", region, flank=100)
>>> design.specific, design.rounds, design.forward.sequence
(True, 1, 'ACCTAGGAGAAGTGGCCAGC')
Source code in src/mbio/primers/genome.py
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 | |
mbio.primers.evaluate_pair_on_genome
¶
evaluate_pair_on_genome(
forward: Primer,
reverse: Primer,
fasta: str | Path,
assembly: str,
*,
intended: Locus | None = None,
circular: bool = False,
thresholds: Thresholds = THRESHOLDS,
timeout: float = 300.0,
) -> GenomeReport
Check one primer pair against a genome FASTA, as evaluate_on_genome checks several.
Examples:
>>> forward = Primer("fwd", "ACCTAGGAGAAGTGGCCAGC")
>>> reverse = Primer("rev", "GCCTTGGAGAGGAGTTCTGC")
>>> target = Locus("chr1", 156710301, 156710801)
>>> report = evaluate_pair_on_genome(forward, reverse, "hg38.fa", "hg38", intended=target)
>>> report.status, report.near_matches_checked
('pass', False)
Source code in src/mbio/primers/genome.py
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 | |
mbio.primers.GenomeReport
dataclass
¶
What one primer pair makes on a genome, and the checks on it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
assembly
|
str
|
The genome's name, such as |
required |
forward
|
Primer
|
The pair checked. |
required |
reverse
|
Primer
|
The pair checked. |
required |
amplicons
|
tuple[Amplicon, ...]
|
Every amplicon, by sequence name and then position. |
required |
mismatches
|
int
|
The most a binding site could carry: zero is a perfect-match screen. |
required |
terminal_window
|
int
|
The 3'-terminal bases held to a perfect match. |
required |
checks
|
tuple[Check, ...]
|
Off-target amplicons, and the intended amplicon where one was named. |
required |
Source code in src/mbio/primers/genome.py
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 | |
near_matches_checked
property
¶
near_matches_checked: bool
Return whether the search found binding sites that do not match perfectly.
__getitem__
¶
__getitem__(name: str) -> Check
Return the check of that name.
Raises:
| Type | Description |
|---|---|
KeyError
|
If no check has it. |
Source code in src/mbio/primers/genome.py
130 131 132 133 134 135 136 137 138 139 140 141 | |
Check a clone's sequencing¶
mbio sequence-verify checks one clone from the command line. From a script you choose what to
judge, and read every difference and where each result landed.
read_trace reads a Sanger .ab1 or .abi file. A whole-plasmid consensus is a SequencingResult made
from its bases. regions finds the junctions a cloning plan marked in its product, and the
inserts between them. verify gives each of those a verdict, and the clone one too.
draw_page lays that out as one page to write, and read_channels reads a trace's four channels
so the page can draw each one under its bases.
mbio.verification.read_trace
¶
read_trace(path: str | PathLike[str]) -> SequencingResult
Read an .ab1 trace into a sequencing result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
An |
required |
Returns:
| Type | Description |
|---|---|
SequencingResult
|
Named for the file. A base called A, C, G or T is mixed, and written as the IUPAC code of its two bases, where another channel's signal at its peak reaches 25% of the called base's. That signal is counted from the higher of its lowest points between this peak and each neighbouring base's, so the tail of a neighbouring peak in the same channel makes no base mixed. Any other code the basecaller wrote is kept. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the file lacks the bases, qualities, peak positions or analysed channels. |
Source code in src/mbio/verification/trace.py
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 | |
mbio.verification.SequencingResult
dataclass
¶
One sample's sequencing, read into the bases called for it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
What the sample is called, such as the read's file name. |
required |
bases
|
str
|
The called bases, stored upper-case. An |
required |
quality
|
tuple[int, ...] | None
|
A Phred value per base, where the route gives one. |
None
|
depth
|
tuple[int, ...] | None
|
How many reads stand behind each base, where the route gives it. |
None
|
reads
|
int | None
|
How many reads stood behind the whole. |
None
|
trusted
|
tuple[int, int] | None
|
The stretch worth trusting, half-open in the result's own coordinates. It may be empty,
when a reader trusts nothing; |
None
|
others
|
tuple[str, ...]
|
Any further consensus the same sample gave, which makes it mixed. Stored upper-case. |
()
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
>>> SequencingResult("A1", "acgt", trusted=(1, 3)).bases
'ACGT'
Source code in src/mbio/verification/result.py
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 | |
trusted_span
property
¶
trusted_span: tuple[int, int]
The trusted stretch, half-open: all of the bases when nothing narrowed it.
__post_init__
¶
__post_init__() -> None
Upper-case the bases and refuse a field that does not fit them.
Source code in src/mbio/verification/result.py
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | |
mbio.verification.regions
¶
regions(
record: SequenceRecord, names: Iterable[str] = ()
) -> tuple[Feature, ...]
Return the features a verification of record judges, in record order.
These are the junctions tagged with JUNCTION_TAG, and the insert between each two
consecutive ones, named for the part the first one's tag names. The stretch the junction
tagged BACKBONE opens is the vector, and is left out. A name that repeats takes an
ordinal. Given names, the features of record so named are returned instead.
Raises:
| Type | Description |
|---|---|
ValueError
|
If one of |
Examples:
>>> tags = ((10, "GFP"), (30, BACKBONE))
>>> joins = [Feature("j", "misc_feature", (Segment(at, at + 2),),
... qualifiers={JUNCTION_TAG: (part,)}) for at, part in tags]
>>> plasmid = SequenceRecord("A" * 50, topology="circular", features=tuple(joins))
>>> [(one.name, one.segments[0].start) for one in regions(plasmid)]
[('j', 10), ('GFP insert', 12), ('j', 30)]
Source code in src/mbio/verification/judge.py
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 | |
mbio.verification.verify
¶
verify(
expected: SequenceRecord,
results: Sequence[SequencingResult],
regions: Sequence[Feature],
) -> Verification
Hold one clone's sequencing results against the record it should be.
A base of a result counts only inside its trusted span, at quality 20 or better where it
carries a quality, and read by more than 10 reads where it carries a depth: both, where it
carries both. An N reads nothing. Bases running past either end of a linear record are
not listed and count for nothing below.
A result does not read as this product when more than a tenth of its counted bases are substitutions, mixed bases or bases inserted or left unplaced: ten times the error a Q20 base allows. Such a result's check fails, and its disagreements and placement are withheld, so it reads no region; the other results are judged as before. A result carrying a second consensus fails as mixed, and one trusting no base carries no verdict.
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
>>> record = SequenceRecord("GATTACAGGCATTCGACCTA")
>>> region = Feature("insert", "misc_feature", (Segment(4, 16),))
>>> verify(record, (SequencingResult("r", "GATTACAGGCATTCGACCTA"),), (region,)).verified
True
Source code in src/mbio/verification/judge.py
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 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | |
mbio.verification.Verification
dataclass
¶
What a clone's sequencing results came to against its record.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
checks
|
tuple[Check, ...]
|
One per region, in record order, named for it. Its value is how many of the region's bases were read. |
required |
result_checks
|
tuple[Check, ...]
|
One per result, in the order given, named for it. Its value is the share of the result's counted bases that disagree or do not line up. |
required |
disagreements
|
tuple[Disagreement, ...]
|
Every place the results read otherwise than the record, in record order. |
required |
placements
|
tuple[Placement, ...]
|
Where each result landed, in the order given. |
required |
Source code in src/mbio/verification/judge.py
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 | |
mbio.verification.Disagreement
dataclass
¶
One place the results read otherwise than the record.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
Kind
|
A substitution, an insertion, a deletion or a mixed base. |
required |
start
|
int
|
Where it lies on the record, as an ADR 0001 span. An insertion is empty, at the point its bases go in. |
required |
end
|
int
|
Where it lies on the record, as an ADR 0001 span. An insertion is empty, at the point its bases go in. |
required |
bases
|
str
|
What the results read there, on the record's top strand; nothing for a deletion. |
required |
results
|
tuple[str, ...]
|
The names of the results that show it. |
required |
regions
|
tuple[str, ...]
|
The regions it falls in, in record order; empty when it falls outside every one. |
()
|
features
|
tuple[str, ...]
|
The record's features it falls in, named only when it falls outside every region. |
()
|
Source code in src/mbio/verification/judge.py
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 | |
said
¶
said(length: int) -> str
Return what it is and where, as a person reads it on a record of length bases.
Source code in src/mbio/verification/judge.py
104 105 106 107 108 | |
mbio.verification.draw_page
¶
draw_page(
expected: SequenceRecord,
results: Sequence[SequencingResult],
verification: Verification,
*,
channels: Sequence[Channels | None] = (),
) -> Page
Lay out the page for one clone's verification of results against expected.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
expected
|
SequenceRecord
|
The record the results were held against. |
required |
results
|
Sequence[SequencingResult]
|
The results |
required |
verification
|
Verification
|
What |
required |
channels
|
Sequence[Channels | None]
|
Each result's channels and peaks, in the order of |
()
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/mbio/verification/page.py
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 | |
mbio.verification.Page
dataclass
¶
One clone's verification laid out, to write as one page.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
What the page is called. |
required |
verified
|
bool
|
Whether the clone is verified. |
required |
rows
|
tuple[TableRow, ...]
|
The table, in the page's order. |
required |
map
|
Drawing | None
|
The record with its reads and disagreements; |
required |
close_ups
|
tuple[CloseUp, ...]
|
One per disagreement, in record order. |
required |
Source code in src/mbio/verification/page.py
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 | |
write
¶
write(path: str | PathLike[str]) -> Path
Write the page to path, making its directory if it is not there, and return it.
Source code in src/mbio/verification/page.py
184 185 186 187 188 189 | |
mbio.verification.read_channels
¶
read_channels(path: str | PathLike[str]) -> Channels
Read an .ab1 trace's four channels and the scan at each base's peak.
A page takes it in the place of the result read_trace reads from the same file.
Raises:
| Type | Description |
|---|---|
ValueError
|
As |
Source code in src/mbio/verification/trace.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | |
Design barcodes¶
mbio barcode-design draws a set from the command line. From a script you set the rules
yourself, check a set someone already holds, and ask how far apart the closest two members
stand.
mbio.barcodes.BarcodeRules
dataclass
¶
What every barcode of one part list holds to, checked as it is read.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
length
|
int
|
How many bases name one part. |
required |
scar
|
str
|
The cloning scar joining one barcode to the next, |
''
|
phase
|
int | None
|
The reading frame at a barcode's first base: how many bases of that codon were read
before it, 0, 1 or 2. |
0
|
forbidden
|
Iterable[EnzymeLike]
|
Enzymes whose recognition sites no barcode may spell, on either strand. Each an
|
()
|
distance
|
int
|
The fewest mismatches, or edits, two barcodes of one part list may stand apart. |
MIN_DISTANCE
|
max_homopolymer
|
int | None
|
The longest run of one base a barcode may carry, scar included, or |
MAX_HOMOPOLYMER
|
gc_band
|
tuple[float, float] | None
|
The share of G and C a barcode must hold, low and high inclusive, each 0 to 1. |
GC_BAND
|
metric
|
Metric
|
How |
METRIC
|
Raises:
| Type | Description |
|---|---|
ValueError
|
Naming what cannot be designed under: a length or a distance that is not positive, a scar that is not definite bases, a phase outside 0 to 2, a barcode and scar that are not a whole number of codons together, a GC band outside 0 to 1, or a metric that is neither. |
KeyError
|
If a forbidden enzyme is not one the package ships. |
Source code in src/mbio/barcodes.py
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 | |
__post_init__
¶
__post_init__() -> None
Normalise the scar, then refuse rules no set could be designed under.
Source code in src/mbio/barcodes.py
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 | |
mbio.barcodes.design_barcodes
¶
design_barcodes(
count: int, rules: BarcodeRules, *, seed: int = SEED
) -> tuple[str, ...]
Design count barcodes for one part list, holding every rule of rules.
Candidates are drawn from the whole space in a seeded random order and kept when they pass,
so one seed returns one set. Walking the space in order instead opens the set on a run of
one base and leaves it poor in G and C, which no filter here repairs — the reason the draw
is shuffled is measured in docs/research/barcode-design.md.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
count
|
int
|
How many barcodes the part list needs. |
required |
rules
|
BarcodeRules
|
What each barcode, and each pair of them, must hold to. |
required |
seed
|
int
|
The seed the draw is made with. |
SEED
|
Returns:
| Type | Description |
|---|---|
tuple of str
|
The barcodes, 5' to 3', in the order they were accepted. |
Raises:
| Type | Description |
|---|---|
SpaceExhaustedError
|
If no further barcode can be found, naming which rule rejected the most candidates. |
ValueError
|
If |
KeyError
|
If a forbidden enzyme is not one the package ships. |
Examples:
>>> design_barcodes(3, BarcodeRules(6))
('TACCAT', 'GACAGC', 'TTGATA')
>>> design_barcodes(3, BarcodeRules(6)) == design_barcodes(3, BarcodeRules(6))
True
Source code in src/mbio/barcodes.py
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 | |
mbio.barcodes.check_barcodes
¶
check_barcodes(
barcodes: Iterable[str], rules: BarcodeRules
) -> tuple[str, ...]
Return one message per rule these barcodes break, empty where the set holds.
Each barcode is judged on its own and each pair on its distance, so a set from anywhere — a published one, or one a user wrote by hand — is read by the rules a design works to.
Examples:
>>> check_barcodes(["TACCAT", "GACAGC"], BarcodeRules(6))
()
>>> check_barcodes(["AAAAAA", "AAAAAC"], BarcodeRules(6))[0]
'AAAAAA carries a run of 6 A, over the cap of 5'
Source code in src/mbio/barcodes.py
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 | |
mbio.barcodes.separation
¶
separation(
barcodes: Iterable[str], *, metric: Metric = METRIC
) -> int
Return the fewest units any two of these barcodes stand apart: how far apart the set is.
The unit is the metric's — mismatches for "hamming", edits for
"sequence-levenshtein" — and the answer is the number a distance rule is read against.
check_barcodes says which pair it is and which rule that breaks.
Raises:
| Type | Description |
|---|---|
ValueError
|
If fewer than two barcodes are given, which have no pair to measure, or if |
Examples:
>>> separation(["ACGTT", "ACGAA", "TTTTT"])
2
Source code in src/mbio/barcodes.py
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 | |
Write a protein as DNA¶
Write a protein with the codons your host uses most, then take out any restriction or Type IIS
site you name by synonymous codon change. codon_tables says which hosts ship.
mbio.translate.optimize_protein
¶
optimize_protein(
protein: str,
*,
host: str,
forbidden: Iterable[EnzymeLike] = (),
name: str = DEFAULT_NAME,
) -> CodingSequence
Write protein as a coding sequence for host with no forbidden site in it.
The codons are the ones host counts most often, and a forbidden site they spell is taken
away by synonymous change, so the protein that comes back is the protein that went in.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
protein
|
str
|
One-letter amino acids, a stop written |
required |
host
|
str
|
The name of a codon usage table. |
required |
forbidden
|
Iterable[EnzymeLike]
|
Enzymes whose recognition sites the DNA must not spell, on either strand. Each an
|
()
|
name
|
str
|
What to call this sequence in the report and in a refusal. |
DEFAULT_NAME
|
Returns:
| Type | Description |
|---|---|
CodingSequence
|
The DNA, the protein it spells, and every codon change that took a site away. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If no shipped table is called |
ValueError
|
If |
Examples:
>>> gene = optimize_protein("MSGRW*", host="e-coli-k12", forbidden=["NotI"])
>>> gene.protein
'MSGRW*'
>>> (gene.changes[0].old_codon, gene.changes[0].new_codon)
('CGC', 'CGT')
Source code in src/mbio/translate.py
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 | |
mbio.translate.optimize_coding_sequence
¶
optimize_coding_sequence(
dna: str,
*,
host: str,
forbidden: Iterable[EnzymeLike] = (),
name: str = DEFAULT_NAME,
) -> CodingSequence
Check a coding sequence someone already holds, and take any forbidden site out of it.
A codon spelling no forbidden site is left exactly as it stands: a sequence already coded is checked, never written again. Only the codons a site sits on move, and they move to a synonym.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dna
|
str
|
The coding sequence, 5' to 3', definite bases and a whole number of codons. |
required |
host
|
str
|
The name of a codon usage table, which decides which synonym a change reaches for. |
required |
forbidden
|
Iterable[EnzymeLike]
|
Enzymes whose recognition sites the DNA must not spell, on either strand. |
()
|
name
|
str
|
What to call this sequence in the report and in a refusal. |
DEFAULT_NAME
|
Returns:
| Type | Description |
|---|---|
CodingSequence
|
The DNA, the protein it spells, and every codon change that took a site away. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If no shipped table is called |
ValueError
|
If |
Examples:
>>> gene = optimize_coding_sequence("ATGGGTCTCAAGACCTAA", host="e-coli-k12",
... forbidden=["BsaI", "BbsI"])
>>> gene.dna
'ATGGGCCTCAAGACCTAA'
>>> gene.recoded
False
Source code in src/mbio/translate.py
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 | |
mbio.translate.CodingSequence
dataclass
¶
One synthesis-ready coding sequence, and what writing it changed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
What this sequence is called, as the report and any refusal name it. |
required |
dna
|
str
|
The coding sequence, 5' to 3', a whole number of codons and free of every forbidden site on both strands. |
required |
protein
|
str
|
The amino acids |
required |
host
|
str
|
The codon usage table it was written for. |
required |
forbidden
|
tuple[str, ...]
|
The enzymes whose sites it is free of, by name. |
()
|
changes
|
tuple[Domestication, ...]
|
Each synonymous codon change that took a forbidden site away, in the order they were
made. |
()
|
recoded
|
bool
|
|
False
|
Source code in src/mbio/translate.py
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 | |
mbio.codons.codon_tables
¶
codon_tables() -> tuple[str, ...]
Return the name of every codon usage table the package ships.
Examples:
>>> codon_tables()
('e-coli-k12', 'human', 'mouse')
Source code in src/mbio/codons.py
85 86 87 88 89 90 91 92 93 | |
Enzymes and cut sites¶
get_enzyme finds one enzyme by its name, its trade name or an isoschizomer's name.
free_enzymes returns the enzymes that cut none of the records you give it, which is how you
pick an enzyme for a new site.
mbio.enzymes.enzymes
¶
enzymes() -> tuple[Enzyme, ...]
Return every shipped enzyme, ordered by name.
Source code in src/mbio/enzymes.py
214 215 216 | |
mbio.enzymes.get_enzyme
¶
get_enzyme(name: str) -> Enzyme
Return one enzyme by its name, its commercial name, or an isoschizomer's name.
Raises:
| Type | Description |
|---|---|
KeyError
|
If no shipped enzyme answers to |
Examples:
>>> get_enzyme("BsaI-HFv2").site
'GGTCTC'
Source code in src/mbio/enzymes.py
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | |
mbio.enzymes.Enzyme
dataclass
¶
One restriction enzyme and where it cuts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The REBASE name, such as |
required |
site
|
str
|
The recognition site, IUPAC, 5' to 3'. Stored upper-case. |
required |
top_cut
|
int
|
Cut offsets, as described in the module docstring. |
required |
bottom_cut
|
int
|
Cut offsets, as described in the module docstring. |
required |
isoschizomers
|
tuple[str, ...]
|
Enzymes a supplier sells that read and cut exactly this site. Neoschizomers — the same site cut elsewhere, as XmaI cuts SmaI's — are not among them. |
()
|
commercial_name
|
str | None
|
The product the other supplier fields describe, such as |
None
|
catalog_number
|
str | None
|
The product the other supplier fields describe, such as |
None
|
supplier
|
str | None
|
The product the other supplier fields describe, such as |
None
|
supplied_buffer
|
str | None
|
The buffer that product is sold in, such as |
None
|
incubation_celsius
|
int | None
|
The supplier's digestion temperature, which is not always a protocol's temperature. |
None
|
heat_inactivation_celsius
|
int | None
|
|
None
|
heat_inactivation_minutes
|
int | None
|
|
None
|
methylation
|
Mapping[str, str]
|
The supplier's Dam, Dcm and CpG sensitivity, keyed |
dict()
|
unverified
|
tuple[str, ...]
|
Fields no source stated. Never a guess. |
()
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/mbio/enzymes.py
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 | |
end
property
¶
end: EndType
The end left behind: "5'", "3'" or "blunt".
Examples:
>>> Enzyme("KpnI", "GGTACC", top_cut=5, bottom_cut=1).end
"3'"
supplier_label
property
¶
supplier_label: str
The enzyme as its supplier sells it: the commercial name and the catalogue number.
Examples:
>>> Enzyme("BsaI", "GGTCTC", top_cut=7, bottom_cut=11).supplier_label
'BsaI'
>>> sold = Enzyme("BsaI", "GGTCTC", top_cut=7, bottom_cut=11, commercial_name="BsaI-HFv2",
... catalog_number="R3733")
>>> sold.supplier_label
'BsaI-HFv2 (R3733)'
__post_init__
¶
__post_init__() -> None
Upper-case the site and refuse one that is not IUPAC DNA.
Source code in src/mbio/enzymes.py
81 82 83 84 85 86 87 88 | |
cut_positions
¶
cut_positions(
start: int, strand: Strand = FORWARD
) -> tuple[int, int]
Where this enzyme cuts a record holding its site at start.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
int
|
The 0-based index where the site begins on the top strand. A reverse-strand site is
the reverse complement of |
required |
strand
|
Strand
|
Which strand carries the site. |
FORWARD
|
Returns:
| Type | Description |
|---|---|
tuple[int, int]
|
The top-strand cut and the bottom-strand cut, in record coordinates and in that order whatever the strand. Either may fall outside the record, which is what a circular record's caller reduces modulo its length. |
Examples:
>>> Enzyme("BsaI", "GGTCTC", top_cut=7, bottom_cut=11).cut_positions(4)
(11, 15)
Source code in src/mbio/enzymes.py
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 | |
overhang
¶
overhang(
record: SequenceRecord,
start: int,
strand: Strand = FORWARD,
) -> str
Return the top-strand bases this enzyme leaves single-stranded, 5' to 3'.
Empty for a blunt cutter. On a circular record the overhang reads across the origin.
Raises:
| Type | Description |
|---|---|
ValueError
|
If either cut falls off the end of a linear record. |
Source code in src/mbio/enzymes.py
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |
mbio.sites.find_sites
¶
find_sites(
record: SequenceRecord,
enzymes: EnzymeLike | Iterable[EnzymeLike],
) -> tuple[CutSite, ...]
Return every site one or more enzymes read in record, in top-strand order.
Both strands are searched, and a circular record is searched across its origin.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
record
|
SequenceRecord
|
The record to search. |
required |
enzymes
|
EnzymeLike | Iterable[EnzymeLike]
|
One enzyme or several, each an |
required |
Raises:
| Type | Description |
|---|---|
KeyError
|
If a name is not one the package ships. |
Examples:
>>> record = SequenceRecord("AAAAGGTCTCGTTTTCCCC")
>>> [(site.start, site.overhang) for site in find_sites(record, "BsaI")]
[(4, 'TTTT')]
Source code in src/mbio/sites.py
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 | |
mbio.sites.CutSite
dataclass
¶
One recognition site found in a record, and where its enzyme cuts there.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enzyme
|
Enzyme
|
The enzyme that reads this site. |
required |
start
|
int
|
0-based index of the first base of the match on the TOP strand, whichever strand the site lies on. |
required |
strand
|
Strand
|
|
required |
top_cut
|
int
|
Where the two strands are severed, in the record's own coordinates and in that order
whatever the strand. Reduced modulo the length on a circular record; on a linear one
either may fall outside the record, which is what |
required |
bottom_cut
|
int
|
Where the two strands are severed, in the record's own coordinates and in that order
whatever the strand. Reduced modulo the length on a circular record; on a linear one
either may fall outside the record, which is what |
required |
overhang
|
str | None
|
The top-strand bases the two cuts leave single-stranded, 5' to 3'; |
required |
certain
|
bool
|
|
True
|
Source code in src/mbio/sites.py
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 | |
mbio.sites.free_enzymes
¶
free_enzymes(
records: Iterable[SequenceRecord],
enzymes: Iterable[EnzymeLike] | None = None,
) -> tuple[Enzyme, ...]
Return the enzymes with no site in any of records, in the order they were given.
These are the enzymes a Golden Gate design can use without domesticating anything.
Source code in src/mbio/sites.py
293 294 295 296 297 298 299 300 301 302 | |
Draw a map¶
draw_map lays a record out as a circle or a line. Drawing.write then writes that layout as
an HTML page that opens offline, as a PNG or as a PDF. The layout is done once, however many
formats you ask for.
mbio.plot.draw_map
¶
draw_map(
record: SequenceRecord | str | PathLike[str],
*,
region: Region | None = None,
highlight: str | Iterable[str] = (),
linear: bool = False,
sequence_view: bool = False,
features: bool = True,
primers: bool = True,
cut_sites: bool = True,
enzymes: str | Iterable[str] | None = None,
hide_types: Iterable[str] = (),
source: bool = False,
bases_per_row: int = 60,
both_strands: bool = True,
insertions: Iterable[Insertion] = (),
tracks: Iterable[Track] = (),
) -> Drawing
Lay out a record as a map of its features, primers and cut sites: a circle or a line.
A circular record is drawn as a circle, and opened as a line when linear. A linear record,
and a region of any record, is always drawn as a line, numbered as the record is. The sequence
view draws the same stretch base by base, as the map numbers it.
A highlight points the map at what it names: those items keep their colours and every other
one, its label with it, dims to one pale grey. Nothing moves, so each label keeps the box it
was measured in; a lit label is the last to hide where labels crowd.
What is switched off is left out of a PNG or a PDF, and a page keeps it behind its switches,
shown first as asked: the layers, the feature types, the sequence view of a stretch up to
sequence_view.LIMIT bases, and its bottom strand. Nothing is laid out until it is needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
record
|
SequenceRecord | str | PathLike[str]
|
A record, or a |
required |
region
|
Region | None
|
The stretch to draw: the name of a feature, whose first segment's start to its last's end
is drawn, or a |
None
|
highlight
|
str | Iterable[str]
|
The name, or names, of what the map points at: a feature, a primer, or an enzyme, which lights every cut site naming it. A name matches whatever its case, and every item answering to one lights. Nothing is lit, and nothing dims, when it is empty. |
()
|
linear
|
bool
|
Whether a circular record drawn whole is opened as a line. |
False
|
sequence_view
|
bool
|
Whether the sequence view is switched on, at most |
False
|
features
|
bool
|
Whether each is switched on. |
True
|
primers
|
bool
|
Whether each is switched on. |
True
|
cut_sites
|
bool
|
Whether each is switched on. |
True
|
enzymes
|
str | Iterable[str] | None
|
The names of the enzymes whose every cut site is drawn; the shipped unique cutters when
|
None
|
hide_types
|
Iterable[str]
|
The feature types switched off. |
()
|
source
|
bool
|
Whether a |
False
|
bases_per_row
|
int
|
How many bases each row of the sequence view holds; a page also carries rows of half as many, rounded up, for a narrow page. |
60
|
both_strands
|
bool
|
Whether the sequence view's bottom strand, under the top one, is switched on. |
True
|
insertions
|
Iterable[Insertion]
|
Bases the record lacks, each marked at the point between two bases it lies at, labelled with how many it adds. A highlight lights one by its name. |
()
|
tracks
|
Iterable[Track]
|
Values along the record's bases, each drawn as curves in a strip under every row of the sequence view its peaks reach. |
()
|
Raises:
| Type | Description |
|---|---|
KeyError
|
If no shipped enzyme answers to a name in |
ValueError
|
If the file cannot be read as a record, the record has no bases, |
Examples:
>>> draw_map("pUC19.dna").write("pUC19.html")
PosixPath('pUC19.html')
Source code in src/mbio/plot/drawing.py
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 | |
mbio.plot.Drawing
dataclass
¶
A record to lay out as a map, to write once per format without laying it out again.
A PNG or a PDF draws only the items that show, and the sequence view only when it is switched
on. A page carries every item the record draws, laid out together, and the sequence view of
any stretch up to sequence_view.LIMIT bases with both its strands, at bases_per_row and at
half of it for a narrow page; it shows first what is switched on, and switches the rest in
place. Each distinct layout runs when it is first needed, and is kept.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
record
|
SequenceRecord
|
What is drawn. |
required |
switches
|
Switches
|
Which items show. |
required |
enzymes
|
str | tuple[str, ...] | None
|
The names of the enzymes whose every cut site is drawn; the shipped unique cutters when
|
required |
span
|
tuple[int, int] | None
|
The stretch drawn, 0-based and half-open, ending past the record's length across the
origin; the whole record when |
required |
linear
|
bool
|
Whether a circular record drawn whole is opened as a line. |
required |
with_sequence_view
|
bool
|
Whether the sequence view is switched on. |
required |
bases_per_row
|
int
|
How many bases each row of the sequence view holds. |
required |
both_strands
|
bool
|
Whether the sequence view's bottom strand, under the top one, is switched on. |
required |
highlight
|
tuple[str, ...]
|
The names lit; every other item is dimmed, in every view and every format. Nothing is lit when it is empty. |
()
|
insertions
|
tuple[Insertion, ...]
|
Each marked where it lies, in every view. |
()
|
tracks
|
tuple[Track, ...]
|
Each drawn under the sequence view's rows. |
()
|
Source code in src/mbio/plot/drawing.py
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 | |
answering
property
¶
answering: frozenset[str]
Return every name the record draws something under, casefolded, for a highlight.
A feature's or a primer's name, and the name of every enzyme that cuts. A caller lighting one name across several records asks each which of them it answers to.
hidden
property
¶
hidden: tuple[Item, ...]
The item of each label the map left out for want of room, in the order they hid.
Each gives its kind, its name and the spans where it lies. layers.notice words them as
the map does. This is the map a PNG or a PDF draws; a page counts what its own layout hid.
layout
property
¶
layout: CircularMap | LinearMap
Where everything that shows went on the map, as a PNG or a PDF draws it.
sequence_view
property
¶
sequence_view: SequenceView | None
Where everything that shows went in the sequence view, when it is switched on.
element
¶
element(*, outlines: bool = False) -> str
Return the map as one SVG element, for a page or a protocol to embed.
It draws what a PNG draws: the items that show, with the sequence view under the map where
it is switched on, and no switch to turn any of them off. With outlines it is drawn on
white, every letter as its outline; as text it needs the faces it was measured in, which
the page embedding it writes into its own styles.
Source code in src/mbio/plot/drawing.py
151 152 153 154 155 156 157 158 159 160 | |
write
¶
write(
path: str | PathLike[str], *, dpi: float = 300
) -> Path
Write the drawing to path, in the format its suffix names, and return the path.
A .html page keeps its text as text, and puts the sequence view beside the map, or
under it on a narrow page, in rows half as long where full ones would shrink. A .png
at dpi and a .pdf draw every letter as its outline, so they look the same on any
machine; dpi counts for the PNG alone. The PNG is one image, the sequence view under the
map. The PDF has the map on its first page, and the sequence view's rows on the pages
after, as many to a page as fit whole.
A page carries every item behind its switches, a circular record drawn whole both as a
circle and as a line, the line laid out again at two, four and eight times its length to
zoom in steps, and the sequence view of a stretch up to sequence_view.LIMIT bases. A PNG
and a PDF draw only what is switched on, the line at its one length.
A directory path names and that is not there is made, as every verb taking an output
directory makes its own.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the suffix names no format this writes, or a PNG at |
Source code in src/mbio/plot/drawing.py
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 | |
Edit a protocol¶
Every pipeline writes protocol.json beside the HTML page rendered from it. Read the JSON,
reword a step or drop one, write it back, and render the page again.
mbio.protocol.read_protocol
¶
read_protocol(path: str | PathLike[str]) -> Protocol
Read a protocol from a JSON file; see Protocol.from_dict.
Source code in src/mbio/protocol/model.py
2101 2102 2103 | |
mbio.protocol.Protocol
dataclass
¶
A bench protocol.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
The page heading. |
required |
key
|
str
|
What the rendered page remembers the bench's check marks under, minted from the content where a pipeline writes the JSON and left alone after, so an agent's edit keeps the ticks already made. Empty where nobody has minted one. |
''
|
summary
|
str
|
One paragraph: what the protocol does. |
''
|
overview
|
Mapping[str, str]
|
Short facts, label to value, shown as a grid of cards. A handful of words each, at most
|
dict()
|
highlights
|
tuple[str, ...]
|
What a fact means, a sentence each, shown as prose under the cards. A statement a reader
has to read rather than scan goes here and not in |
()
|
background
|
tuple[Topic, ...]
|
Why the work is shaped as it is, a topic at a time, read before the first step. A run of
several protocols says it once, on |
()
|
checks
|
tuple[Check, ...]
|
Verdicts on the work, shown as a strip of badges, so a warning is seen and not read. |
()
|
choice
|
str
|
The job this protocol is one way of doing, where several ways are offered. Protocols
naming the same job are the ways: they stand together in |
''
|
consumes
|
tuple[Item, ...]
|
What the bench is handed before this protocol, and what it leaves for the next one. A
|
()
|
produces
|
tuple[Item, ...]
|
What the bench is handed before this protocol, and what it leaves for the next one. A
|
()
|
materials
|
tuple[Material, ...]
|
The reagents, the oligos to order, and the hardware. Three lists and not one, because an order sheet and a reagent list want different columns. |
()
|
oligos
|
tuple[Material, ...]
|
The reagents, the oligos to order, and the hardware. Three lists and not one, because an order sheet and a reagent list want different columns. |
()
|
equipment
|
tuple[Material, ...]
|
The reagents, the oligos to order, and the hardware. Three lists and not one, because an order sheet and a reagent list want different columns. |
()
|
order_sheet
|
str
|
The file holding |
''
|
files
|
tuple[str, ...]
|
The files the run writes, each as a path from the page. Rendered text naming one by its file name links it, so a bare filename is never one the reader cannot open. A file the page never names costs nothing, so a run declares what it writes once rather than each page declaring what it mentions. |
()
|
vessels
|
tuple[Vessel, ...]
|
What the run holds material in, and where each thing sits. |
()
|
plates
|
tuple[Vessel, ...]
|
What the run holds material in, and where each thing sits. |
()
|
steps
|
tuple[Step, ...]
|
In the order they are shown. |
()
|
sources
|
Mapping[str, Source]
|
Every document a claim on the page rests on, keyed by what a |
dict()
|
holes
|
tuple[Hole, ...]
|
Numbers missing from the run as a whole. One belonging to a step sits on that step. |
()
|
bill
|
Bill | None
|
What the run consumes, and what it costs where a price record prices it. |
None
|
Source code in src/mbio/protocol/model.py
1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 | |
all_holes
property
¶
all_holes: tuple[Hole, ...]
Every hole the protocol carries, the run's own first, then each step's, then the bill's.
One id is one hole: a number the run and a step both miss is the same number, so it is collected once, where it is first shown.
citations
property
¶
citations: tuple[Citation, ...]
Every citation this protocol's own rows and its bill carry, kind by kind.
Examples:
>>> Protocol("Demo").citations
()
cited
property
¶
cited: frozenset[str]
Every source key this protocol's own citations name.
Examples:
>>> Protocol("Demo").cited
frozenset()
held_seconds
property
¶
held_seconds: tuple[float, int]
How long this protocol holds the bench, and how many of its steps hold nothing.
One place computes it, so a protocol's own page and the schedule a project draws can never disagree. A step nothing times is counted, never summed as a zero.
Examples:
>>> steps = (Step("Mix", key="mix"), Step("Rest", key="rest", timers=(Timer("rest", 60),)))
>>> Protocol("Demo", steps=steps).held_seconds
(60.0, 1)
__post_init__
¶
__post_init__() -> None
Refuse an empty title, or an overview value too long to be a card; slug the key.
Source code in src/mbio/protocol/model.py
1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 | |
audit
¶
audit() -> tuple[Check, ...]
Judge the protocol itself: its citations, its wells, its rules and its holes.
The protocol is its own gate. A check it carries is paid by the protocol; a gate added to the repo's own is paid by everyone who works here afterwards.
Examples:
>>> [check.name for check in Protocol("Demo").audit()]
['sources', 'wells', 'rules', 'holes']
Source code in src/mbio/protocol/model.py
1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 | |
cautions_for
¶
cautions_for(step: Step) -> tuple[Caution, ...]
Return every caution step shows: its materials' first, then its own, each once.
A step's own stands where no material carries one. Where one sentence is both, the one naming a document wins, so deduplication never costs the page a citation.
Source code in src/mbio/protocol/model.py
1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 | |
contents_of
¶
contents_of(step: Step) -> tuple[str, ...]
Return what is in the step's tubes: what it pipettes, and what each of those brings.
Source code in src/mbio/protocol/model.py
1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 | |
from_dict
classmethod
¶
from_dict(data: Mapping[str, Any]) -> Protocol
Build a protocol from parsed JSON; keys are the field names, lists become tuples.
Each value takes its field's JSON type: a whole number for an int, any number but
not true or false for a float, and null only where the field is optional.
Raises:
| Type | Description |
|---|---|
ValueError
|
On an unknown or missing key or a value of another JSON type, naming where it is, or on a value the model refuses. |
Source code in src/mbio/protocol/model.py
1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 | |
materials_for
¶
materials_for(step: Step) -> tuple[Material, ...]
Return the materials step names, which are the ones whose facts reach it.
What a material carries reaches a step through this and nowhere else.
Source code in src/mbio/protocol/model.py
1705 1706 1707 1708 1709 1710 | |
rules_for
¶
rules_for(step: Step) -> tuple[tuple[str, Rule], ...]
Return each rule that bears on step, with the name of whatever carries it.
A material, a plate, or anything the protocol is handed or leaves bears on a step that names it, and its rules come with it: a rule cannot be edited out of a step because it was never written into one. Only the carrier's name is handed back, which is all a reader and the audit need.
Source code in src/mbio/protocol/model.py
1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 | |
mbio.protocol.Step
dataclass
¶
One numbered step of a protocol.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
What the step achieves, such as |
required |
key
|
str
|
What this step is, whatever its title is reworded to: the handle its anchor and the bench's check mark are kept under. The builder assigns it, for the step's job and not its wording, and it is slugged as a title is. Empty, it falls back to the title's slug. |
''
|
section
|
str
|
What stage of the protocol the step belongs to, such as |
''
|
instructions
|
tuple[str, ...]
|
Ordered actions, one sentence each. |
()
|
cautions
|
tuple[Caution | str, ...]
|
Shown before the instructions. A bare string is a caution citing nothing. |
()
|
notes
|
tuple[Note | str, ...]
|
Shown after them. A bare string is a note citing nothing. |
()
|
tables
|
tuple[ReactionTable, ...]
|
Reaction tables, thermocycler programs and countdowns the step uses. |
()
|
programs
|
tuple[ReactionTable, ...]
|
Reaction tables, thermocycler programs and countdowns the step uses. |
()
|
timers
|
tuple[ReactionTable, ...]
|
Reaction tables, thermocycler programs and countdowns the step uses. |
()
|
waits
|
tuple[Wait, ...]
|
Time the step spends waiting on someone else, which nobody attends. |
()
|
hands_on_seconds
|
int | None
|
How much of the step someone stands over, which |
None
|
transfers
|
tuple[Transfer, ...]
|
What the step moves between wells. A step references a well by holding the transfer, never by describing where a thing is. |
()
|
figures
|
tuple[Figure, ...]
|
The records the step draws, shown under its instructions. |
()
|
gels
|
tuple[Gel, ...]
|
What a successful step looks like. A bare expected line is one citing nothing, and the
tuple is left as it was written, since most of the package reads an expected line as
text; |
()
|
expected
|
tuple[Gel, ...]
|
What a successful step looks like. A bare expected line is one citing nothing, and the
tuple is left as it was written, since most of the package reads an expected line as
text; |
()
|
calculator
|
CountToNet | None
|
Where the reader has a count of their own to work out and read against what |
None
|
troubleshooting
|
tuple[Troubleshooting, ...]
|
Problems the reader may see here. |
()
|
holes
|
tuple[Hole, ...]
|
The numbers this step would otherwise have to invent. |
()
|
Source code in src/mbio/protocol/model.py
1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 | |
cautioned
property
¶
cautioned: tuple[Caution, ...]
Every caution, each a Caution: __post_init__ makes one of any bare string.
Examples:
>>> Step("Thaw the mix", cautions=("Keep it on ice.",)).cautioned
(Caution(text='Keep it on ice.', citation=None),)
expectations
property
¶
expectations: tuple[Expectation, ...]
Every expected line, each an Expectation, a bare string being one citing nothing.
Examples:
>>> Step("Run the gel", expected=("One band at 749 bp.",)).expectations
(Expectation(text='One band at 749 bp.', citation=None),)
held_seconds
property
¶
held_seconds: float | None
How long this step holds the bench, where anything in it bounds the time.
Summed over its timers and its thermocycler programs. None where nothing bounds
one — a step with neither, or one whose only program runs to an open end — because a
step holding nothing is a question and never a zero.
Examples:
>>> Step("Rest the tube", key="rest", timers=(Timer("rest", 600),)).held_seconds
600.0
>>> Step("Mix the reaction", key="mix").held_seconds is None
True
named
property
¶
named: tuple[str, ...]
Everything the step names: its title, its actions, what it pipettes and what it runs.
A Rule's subject is matched against these.
noted
property
¶
noted: tuple[Note, ...]
Every note, each a Note: __post_init__ makes one of any bare string.
Examples:
>>> Step("Rest the tube", notes=("It settles.",)).noted
(Note(text='It settles.', citation=None),)
pipetted
property
¶
pipetted: tuple[str, ...]
What the step puts in a tube: every reaction table's component names.
__post_init__
¶
__post_init__() -> None
Refuse an empty title or a negative hands-on time; slug the key; make each text one.
Source code in src/mbio/protocol/model.py
1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 | |
mbio.protocol.write_protocol
¶
write_protocol(
protocol: Protocol, path: str | PathLike[str]
) -> Path
Write protocol to path as JSON that read_protocol reads back equal; return the path.
Every field is written, empty and default ones too, in the order its class declares them, indented two spaces and as UTF-8 ending in a newline, so one protocol always writes the same bytes.
Source code in src/mbio/protocol/model.py
2106 2107 2108 2109 2110 2111 2112 2113 | |
mbio.protocol.write_html
¶
write_html(
protocol: Protocol,
path: str | PathLike[str],
*,
folder: Folder | None = None,
base: str | PathLike[str] | None = None,
) -> Path
Write render_html(protocol) to path as UTF-8 and return the path.
Inside a folder, the file's own name is the address the other pages link it by. A figure's
record is read from base, and from beside the page where nobody says: a pipeline writes the
records, the data and the page into one directory. The map each figure's record opens to is
written beside the page first, so the page has it to open.
Source code in src/mbio/protocol/render.py
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | |
Build a library¶
iGGA is the lab's iterative Golden Gate method. It builds a barcoded library of every
combination of the part lists it is given, one round at a time. plan_igga is the way in, and
it reads what one build chooses from a Build. check_library judges a design that nothing
here planned, by the same rules.
synbio.igga.plan_igga
¶
plan_igga(
build: Build | str | PathLike[str],
*,
parts: Sequence[Mapping[str, str]] | None = None,
kind: Kind = "protein",
site: Site | None = None,
working_site: Site | None = None,
pattern: str = NAME_PATTERN,
rules: BarcodeRules | None = None,
min_distance: int = MIN_DISTANCE,
allow_uniform: bool = False,
prices: PriceRecord | str | PathLike[str] | None = None,
profile: LigaseProfile
| str
| PathLike[str]
| None = None,
profile_sheet: str | int | None = None,
) -> LibraryPlan
Plan the whole library build asks for, by the method build is built under.
One round appends one part list to every member of the library at once, so the rounds run in the build's own order and the product of each opens the next. The same inputs return the same design: the barcodes are drawn from the build's seed, and nothing else here is random.
Where the build names a working vector, the enzyme that admits cargo to it is chosen from that vector alone before any block is designed, and reserved so no block spells it. The ordering is the pipeline's, not the user's.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
build
|
Build | str | PathLike[str]
|
What this build chooses, or a path to the JSON holding it;
|
required |
parts
|
Sequence[Mapping[str, str]] | None
|
One already-sorted mapping per position, in the build's order. The build's own parts FASTA is read where this is not given. |
None
|
kind
|
Kind
|
What the part lists hold. |
'protein'
|
site
|
Site | None
|
Where to put an internal stuffer, as a feature name or a |
None
|
working_site
|
Site | None
|
The same, for the ccdB cassette of the working vector the build names. Read only where that vector carries none. |
None
|
pattern
|
str
|
How a record's name says which part list it belongs to; see |
NAME_PATTERN
|
rules
|
BarcodeRules | None
|
What every barcode holds to. Built from the build's own barcode length and distance by
default; see |
None
|
min_distance
|
int
|
How far apart the standard's overhangs must stand, and whether one base kind is allowed. |
MIN_DISTANCE
|
allow_uniform
|
int
|
How far apart the standard's overhangs must stand, and whether one base kind is allowed. |
MIN_DISTANCE
|
prices
|
PriceRecord | str | PathLike[str] | None
|
A price record the user holds, or a path to one;
|
None
|
profile
|
LigaseProfile | str | PathLike[str] | None
|
A ligase's own matrix the user holds, or a path to one, and which sheet of it to read;
|
None
|
profile_sheet
|
LigaseProfile | str | PathLike[str] | None
|
A ligase's own matrix the user holds, or a path to one, and which sheet of it to read;
|
None
|
Returns:
| Type | Description |
|---|---|
LibraryPlan
|
The design, the simulated rounds, what the bench has to do, and the gate's verdict on all
of it. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a record's name says no position of the build or says more than one, if two records
share a name, if a part is not a protein or not a coding sequence, if no overhang
standard fits the part lists, if a block spells a site the method does not expect or
gives up no cargo, if the vector cannot be made a destination, if a round cannot ligate,
if |
KeyError
|
If the build names a codon usage table or an enzyme this package does not ship. |
SpaceExhaustedError
|
If a part list is larger than the barcodes its rules allow. |
Examples:
>>> plan = plan_igga("project.json")
>>> plan.write("library/")
Source code in src/synbio/igga/plan.py
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 | |
synbio.igga.LibraryPlan
dataclass
¶
One planned library: what it costs, what it makes, and what the bench has to do.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
build
|
Build
|
What this build chose: its positions, its inputs and its dials. |
required |
scheme
|
Scheme
|
The method the build was planned by. |
required |
vector
|
SequenceRecord
|
The record the plan was made from, before any retrofit. |
required |
destination
|
Destination
|
The vector a round can open, and what making it one changed. |
required |
block_vectors
|
tuple[Destination, ...]
|
The block vector a position's cargo closes into, one a position in the build's order. A part enters on its own position's entry overhang, so each offers that overhang and nothing else about them differs. Empty where the build names no primer set and the blocks are ordered whole. |
required |
part_lists
|
tuple[PartList, ...]
|
One per position, in the build's order: each member's name and the protein it codes for, whether it was given as protein or read off DNA. |
required |
coding
|
tuple[Mapping[str, str], ...]
|
One per position: the coding sequence a member came already coded in, empty for a member written from the host's codon usage. |
required |
standard
|
Standard
|
The overhang standard the build works to, and what it charges each part. |
required |
parts
|
tuple[Part, ...]
|
Every part's synthesis sequence, in position order and then list order. |
required |
rounds
|
tuple[Round, ...]
|
One a position, in the order they run. The last round's product is the representative construct and the ones before it are the intermediates. |
required |
coverage
|
tuple[RoundCoverage, ...]
|
What each round has to cover, and what its colony floor leaves out. |
required |
bench
|
tuple[RoundBench, ...]
|
What each round takes at the bench, computed from that round's own lengths. |
required |
verdict
|
Verdict
|
What |
required |
host
|
str
|
The codon usage table the coding bases were written for. |
required |
name
|
str
|
What each round's product is called. |
''
|
prices
|
PriceRecord | None
|
The price record the protocol's bill is costed against, if the caller holds one. Its quantities compute either way; with no record every money cell is a hole. |
None
|
pool
|
PoolPlan | None
|
The oligo pool every block is synthesised from, where the build names a primer set.
|
None
|
working
|
Working | None
|
The vector the finished library is moved into, where the build names one, and the
enzyme chosen to admit it. |
None
|
seated
|
SeatedParts | None
|
Every part in its own well of the carrier the build names. |
None
|
Source code in src/synbio/igga/plan.py
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 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 | |
checks
property
¶
checks: tuple[Check, ...]
Every check the gate made, in the order it made them.
The plan judges nothing itself: these are verdict's, so a design this pipeline wrote
and one an agent composed are judged by the same code.
write
¶
write(directory: str | PathLike[str]) -> Files
Write the sheets, the records, the protocol data and its page into directory.
The directory is made when it is not there. The files are named by PARTS_FILE,
BARCODE_FILE, CHANGE_FILE and BLOCK_VECTOR_FILE, by synbio.igga.rounds
for the records and by mbio.protocol.render, which puts a chain of protocols in
its own PROTOCOL_DIR, and a second run over the same inputs writes the same bytes.
Source code in src/synbio/igga/plan.py
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 | |
synbio.igga.read_build
¶
read_build(path: str | PathLike[str]) -> Build
Read a build from JSON, resolving every file path against the file's own directory.
Raises:
| Type | Description |
|---|---|
ValueError
|
On a missing or unknown key, a value of another JSON type, a path naming no file, or any
check |
KeyError
|
If it names an enzyme or a codon usage table this package does not ship. |
Examples:
>>> read_build("project.json").positions
('N', 'DBD', 'C')
Source code in src/synbio/igga/project.py
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 | |
synbio.igga.Build
dataclass
¶
What one build chooses, checked on construction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
What the run and each round's product is called. |
required |
positions
|
tuple[str, ...]
|
The positions, in the order the rounds fill them, so the last is the terminal one. A position is a name: every one of them carries the method's own stuffers. |
required |
parts
|
Path
|
The FASTA of every part list, each record named for the position it fills. |
required |
vector
|
Path
|
The destination vector, circular: a |
required |
working_vector
|
Path | None
|
The vector the finished library is moved into, circular, before its ccdB cassette: a stock the lab holds and an application chooses. Omitted, the library stays in the destination vector and the final assembly is written as what it cannot say. |
None
|
carrier
|
Path | None
|
The plasmid each part is kept in until a round wants it, circular and supplied
linearised: a stock the lab holds. Named, the run opens by seating every part in it;
omitted, the parts are already in hand and nothing is seated. The carrier plasmid and
the enzyme releasing a part from it are the method's, in
|
None
|
host
|
str
|
The codon usage table the coding bases are written for. |
required |
oligo_length
|
int
|
How long one synthesised oligo of the pool may be. |
required |
primers
|
Path | None
|
The orthogonal primer set the pool is amplified by, as a two-column sheet the user holds. Without one no oligo can be written, because the sites are templated on it. |
None
|
bands
|
Mapping[str, tuple[str, ...]]
|
The vendor's bands for each quantity the pool is banded by, written |
dict()
|
batch_size
|
int
|
How many parts one batch of the bench work carries. |
required |
completeness
|
float
|
The chance each round is sized for that none of its products is missing. |
required |
validate_from
|
int | None
|
The fragment-count floor at or above which a design is read back one well at a time.
Omitted, nothing is read and the library stays polyclonal; |
None
|
routes
|
tuple[str, ...]
|
Which of |
()
|
index_plate
|
str
|
What this lab calls its prepared plate of barcoded primer pairs. Only the index PCR route takes one, so only that route may name it. |
''
|
seed
|
int
|
The seed the barcodes are drawn with. |
SEED
|
reserved_extra
|
tuple[str, ...]
|
Further enzymes this build needs a block kept clear of, added to the method's own. |
()
|
representation_seen
|
float | None
|
What this build holds the representation read to: the share of combinations that must be
read at all, the skew ratio the counts must stay under, and the depth both are judged at.
Each takes |
None
|
representation_skew
|
float | None
|
What this build holds the representation read to: the share of combinations that must be
read at all, the skew ratio the counts must stay under, and the depth both are judged at.
Each takes |
None
|
reads_per_member
|
float | None
|
What this build holds the representation read to: the share of combinations that must be
read at all, the skew ratio the counts must stay under, and the depth both are judged at.
Each takes |
None
|
linkage_fidelity
|
float | None
|
The share of reads whose barcode must still name its part. No default: nothing published sets a mark for it, so a build that states none is read against no mark at all. |
None
|
final_assembly
|
FinalAssembly | None
|
What this lab measured the one-pot assembly at: the working vector's mass, which is the whole of it. The cargo follows from the release. No default, as for the two cycle counts below: a build that has run the pilot states it and one that has not leaves the hole standing. |
None
|
pcr1_cycles
|
int | None
|
The cycle counts this lab measured for PCR1, against the polymerase it runs, and for PCR2. No default: nobody published either, so a build stating neither prints the band Twist gives for another polymerase and no PCR2 count at all. |
None
|
pcr2_cycles
|
int | None
|
The cycle counts this lab measured for PCR1, against the polymerase it runs, and for PCR2. No default: nobody published either, so a build stating neither prints the band Twist gives for another polymerase and no PCR2 count at all. |
None
|
barcode
|
Barcode
|
What one part's barcode holds to. |
Barcode()
|
primer_plates
|
PrimerPlates | None
|
How this lab lays the pool's primers out as a stock plate and its working copies.
Omitted, no such protocol is written: an empty page is worse than a step, and the
amounts are nobody's to guess. It needs |
None
|
scheme
|
Scheme
|
The method the build is made by. There is one, and it is |
IGGA
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If a position is repeated or missing, a number is not positive, the completeness does not
lie between 0 and 1, the floor is negative, a route is neither of the two or named twice,
the floor and the routes are not both there or both absent, an index plate is named
without the route that takes one, a route is named over cargo DMX cannot pick, a
representation mark loosens the sourced one, or the barcode and the method's cloning
scar are not whole codons together — which names |
KeyError
|
If |
Source code in src/synbio/igga/project.py
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 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | |
barcode_block_length
property
¶
barcode_block_length: int
How long the finished barcode block is: one barcode a position, joined by the scar.
marks
property
¶
marks: RepresentationMarks
What this build holds its representation reads to: the sourced marks, as tightened.
reserved
property
¶
reserved: tuple[str, ...]
Every enzyme a block is kept clear of: the method's, then this build's own.
A build adds and never replaces, so an enzyme the method reserves stays reserved whatever a build says.
retained_length
property
¶
retained_length: int
What the finished product keeps past its last part: stuffer and barcode block.
__post_init__
¶
__post_init__() -> None
Normalise the lists and paths, then check everything a designer will read.
Source code in src/synbio/igga/project.py
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | |
synbio.igga.check_library
¶
check_library(
build: Build,
*,
destination: SequenceRecord,
blocks: Mapping[str, Sequence[SequenceRecord]],
products: Sequence[SequenceRecord],
barcodes: Mapping[str, Sequence[str]],
working: SequenceRecord | None = None,
cargo: Enzyme | None = None,
profile: LigaseProfile | None = None,
) -> Verdict
Judge a whole build: its vector, every tube, every cargo, every barcode set and the product.
Nothing here is read off a plan. The molecules are finished records, the barcodes are the
table that decodes the sequencing, and the reactions are composed from the chain's own order,
so a design an agent wrote is judged exactly as one plan_igga wrote is.
The rounds run in the DMX vector, so the destination is where a build accepts one and
check_dmx_vector judges it here. A destination no primer that reads a well binds carries no
DMX backbone -- a minimal stand-in -- and has no blunt site any primer could reach, so
nothing judges it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
build
|
Build
|
What the build chose. |
required |
destination
|
SequenceRecord
|
The vector the first round opens, judged as a rebuilt DMX vector where one is given. |
required |
blocks
|
Mapping[str, Sequence[SequenceRecord]]
|
The synthesised blocks of each position, keyed by position name. |
required |
products
|
Sequence[SequenceRecord]
|
One record a round, in the order the rounds ran. The last is the library product. |
required |
barcodes
|
Mapping[str, Sequence[str]]
|
Each position's barcodes, keyed by position name. |
required |
working
|
SequenceRecord | None
|
The working vector the library is moved into and the enzyme that admits it, where the build names one. Both or neither: the final assembly is judged only where there is a vector to judge it in. |
None
|
cargo
|
SequenceRecord | None
|
The working vector the library is moved into and the enzyme that admits it, where the build names one. Both or neither: the final assembly is judged only where there is a vector to judge it in. |
None
|
profile
|
LigaseProfile | None
|
A ligase's own matrix the user holds, read by |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If there is not one product, one part list and one barcode list a position, or if one of
|
Source code in src/synbio/igga/gate.py
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 | |
Read wells back¶
DMX reads back designs the lab already holds. One design sits in one well, and that well is
marked, sequenced and called on its own. The 96 barcode sequences do not ship, so read_kit
reads a copy you hold; see the DMX barcode kit for the file it reads.
synbio.dmx.plan_dmx
¶
plan_dmx(
build: Build | str | PathLike[str],
) -> ReadBackPlan
Plan the read-back build asks for: which designs, on which route, and what that takes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
build
|
Build | str | PathLike[str]
|
What this run chooses, or a path to the JSON holding it;
|
required |
Returns:
| Type | Description |
|---|---|
ReadBackPlan
|
The plan, whose |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the build or its designs sheet cannot be read, or its floor reads no design back. |
Examples:
>>> plan_dmx("build.json").validation.wells
8
Source code in src/synbio/dmx/plan.py
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 | |
synbio.dmx.ReadBackPlan
dataclass
¶
One planned read-back: which designs are read, on which route, and what that takes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
build
|
Build
|
What this run chose: its designs, its archive, its route and its floor. |
required |
designs
|
tuple[Design, ...]
|
Every design the sheet named, before the floor chose among them. |
required |
validation
|
Validation
|
What reading the chosen designs back takes: the wells, the plates and the depth. |
required |
Source code in src/synbio/dmx/plan.py
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 | |
protocol
¶
protocol() -> Protocol
Return the page someone works through, its three sections labelled.
Source code in src/synbio/dmx/plan.py
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | |
write
¶
write(directory: str | PathLike[str]) -> Files
Write the run's data and its page into directory.
The directory is made when it is not there, the files are named by
mbio.protocol.render, and a second run over the same inputs writes the same
bytes. A run of one protocol is one page, so nothing here is a folder.
Source code in src/synbio/dmx/plan.py
118 119 120 121 122 123 124 125 126 | |
synbio.dmx.read_kit
¶
read_kit(path: str | PathLike[str] | None = None) -> Kit
Read the 96 barcode sequences from a copy the user holds.
The package ships none. path names the file, or KIT_ENV does.
Raises:
| Type | Description |
|---|---|
ValueError
|
If no file is named, or the file is not one of these, saying what one is. |
Examples:
>>> read_kit("dmx-barcodes.tsv").barcodes[0].group
1
Source code in src/synbio/dmx/kit.py
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 | |
synbio.dmx.Kit
dataclass
¶
The 96 barcodes a user holds, grouped as the kit groups them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
The file they were read from, so a report can say which copy was used. |
required |
barcodes
|
tuple[KitBarcode, ...]
|
Every barcode, in group and then index order. |
required |
Source code in src/synbio/dmx/kit.py
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 | |
at
¶
at(group: int, index: int) -> KitBarcode
Return the barcode at one group and index, both counting from one.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the kit holds no barcode there. |
Source code in src/synbio/dmx/kit.py
96 97 98 99 100 101 102 103 104 105 106 107 | |
group
¶
group(group: int) -> tuple[KitBarcode, ...]
Return one group's barcodes, in index order.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the kit has no such group. |
Source code in src/synbio/dmx/kit.py
84 85 86 87 88 89 90 91 92 93 94 | |