The plasmid assessment class.
+Set a name for the assessment.
+Evaluate plasmid for Golden Gate.
+Flag enzyme sites that are within the retained backbone.
+class Assessment(
- record,
- enzyme
+get_number_of_sites
+def get_number_of_sites(
+ self
)
-The plasmid assessment class.
-Parameters
-record
-
-A Biopython SeqRecord
.
-
-enzyme
-
-A restriction enzyme (str
). A Biopython RestrictionType
will be looked
-up using the string.
-
-View Source
class Assessment:
+View Source
def get_number_of_sites(self):
- """The plasmid assessment class.
+ if "is_circular" in self.results:
- **Parameters**
+ is_linear = not self.results["is_circular"]
- **record**
+ else:
- > A Biopython `SeqRecord`.
+ is_linear = False
- **enzyme**
+ restriction_batch = Bio.Restriction.RestrictionBatch([self.enzyme])
- > A restriction enzyme (`str`). A Biopython `RestrictionType` will be looked
+ analysis = Bio.Restriction.Analysis(
- up using the string.
+ restriction_batch, sequence=self.record.seq, linear=is_linear
- """
+ )
- def __init__(self, record, enzyme):
+ self.analysis_results = analysis.full(linear=is_linear)
- self.record = record
+ self.results["number_of_sites"] = len(self.analysis_results[self.enzyme])
- self.enzyme = Bio.Restriction.__dict__[enzyme]
+ # Add as features for plot in report:
- self.results = {}
+ for enzyme, sites in self.analysis_results.items():
- def assess_plasmid(self, other_enzymes=None):
+ for site in sites:
- """Evaluate plasmid for Golden Gate.
+ self.record.features.append(
- **Parameters**
+ SeqFeature(
- **other_enzymes**
+ FeatureLocation(site, site + 1),
- > List of enzymes used in higher level assemblies (`list`).
+ id=str(enzyme),
- """
+ type="misc_feature",
- self.check_circularity()
+ qualifiers={
- self.get_number_of_sites()
+ "label": str(enzyme),
- self.evaluate_orientation()
+ "plasmid_assessment": "enzyme",
- self.digest_plasmid()
+ },
- self.count_other_sites(other_enzymes)
+ )
- self.sum_results()
+ )
+
- def check_circularity(self):
- if "topology" not in self.record.annotations:
+
+plot_plasmid
+def plot_plasmid(
+ self
+)
+
- self.results["is_circular"] = False
- elif self.record.annotations["topology"] == "circular":
+Plot an outline of the plasmid.
+View Source
def plot_plasmid(self):
- self.results["is_circular"] = True
+ """Plot an outline of the plasmid."""
- else:
+ fig, ax = plt.subplots(figsize=(7, 4))
- self.results["is_circular"] = False
+ graphic_record = AssessmentTranslator().translate_record(self.record)
- def get_number_of_sites(self):
+ graphic_record.plot(ax=ax, with_ruler=False, strand_in_label_threshold=2)
- if "is_circular" in self.results:
+ self.fig = fig
+
- is_linear = not self.results["is_circular"]
- else:
+
+sum_results
+def sum_results(
+ self
+)
+
- is_linear = False
- restriction_batch = Bio.Restriction.RestrictionBatch([self.enzyme])
+View Source
def sum_results(self):
- analysis = Bio.Restriction.Analysis(
+ self.results["pass"] = True
- restriction_batch, sequence=self.record.seq, linear=is_linear
+ if self.results["is_circular"] is False:
- )
+ self.results["pass"] = False
- analysis_results = analysis.full(linear=is_linear)
+ return
- self.results["number_of_sites"] = len(analysis_results[self.enzyme])
+ if self.results["is_site_orientation_correct"] is False:
- def evaluate_orientation(self):
+ # implicitly checks number of sites too
- self.results["is_site_orientation_correct"] = False # default
+ self.results["pass"] = False
+
+ return
+
+ if self.sites_outside_excised_region_txt:
+
+ self.results["pass"] = False
+
+ return
+
+
+
+
+AssessmentTranslator
+class AssessmentTranslator(
+ features_filters=(),
+ features_properties=None
+)
+
- # Forward strand:
- iter = (match for match in re.finditer(self.enzyme.site, str(self.record.seq)))
+Custom translator for highlighting key features.
+View Source
class AssessmentTranslator:
+
+ """Please install dna_features_viewer to use this class."""
+
+ def __init__(self):
+
+ raise Exception("Please install dna_features_viewer to use this class.")
+
+
+
+
+
+Ancestors (in MRO)
+
+- dna_features_viewer.BiopythonTranslator.BiopythonTranslator.BiopythonTranslator
+- dna_features_viewer.BiopythonTranslator.BiopythonTranslatorBase.BiopythonTranslatorBase
+
+Class variables
+
- if sum(1 for _ in iter) == 1:
- rev_complement = str(self.record.seq.reverse_complement())
+graphic_record_parameters
+
- iter_reverse = (m for m in re.finditer(self.enzyme.site, rev_complement))
- if sum(1 for _ in iter_reverse) == 1: # 1 site in both strands:
+
- self.results["is_site_orientation_correct"] = True
- def digest_plasmid(self):
+
- # Obtain fragments and get the backbone's overhangs.
- # This method has two assumptions:
+Static methods
+quick_class_plot
+def quick_class_plot(
+ record,
+ figure_width=12,
+ **kwargs
+)
+
- # - the sequence has two, correctly oriented enzyme sites.
- # - the sequence is circular.
+Allows super quick and dirty plotting of Biopython records.
+This is really meant for use in a Jupyter/Ipython notebook with
+the "%matplotlib inline" setting.
+
+
+
+from dna_features_viewer import BiopythonTranslator
+BiopythonTranslator.quick_plot(my_record)
+
+
+
+View Source
@classmethod
- # Therefore there will be exactly two fragments, with one containing both sites.
+ def quick_class_plot(cls, record, figure_width=12, **kwargs):
- self.results["digest"] = {}
+ """Allows super quick and dirty plotting of Biopython records.
- if not self.results["is_circular"]:
+ This is really meant for use in a Jupyter/Ipython notebook with
- return
+ the "%matplotlib inline" setting.
- if not self.results["is_site_orientation_correct"]:
+ >>> from dna_features_viewer import BiopythonTranslator
- return
+ >>> BiopythonTranslator.quick_plot(my_record)
- record_fragments = dc.StickyEndFragment.list_from_record_digestion(
+ """
- record=self.record, enzyme=self.enzyme, linear=False
+ graphic_record = cls().translate_record(record)
- )
+ ax, _ = graphic_record.plot(figure_width=figure_width, **kwargs)
- if self.enzyme.site in record_fragments[0].to_standard_string():
+ return ax
+
- backbone_index = 1 # there are only two fragments
- excise_index = 0
+
+Methods
+compute_feature_box_color
+def compute_feature_box_color(
+ self,
+ feature
+)
+
- else:
- backbone_index = 0
+Compute a box_color for this feature.
+View Source
def compute_feature_box_color(self, feature):
- excise_index = 1 # reversed
+ """Compute a box_color for this feature."""
- self.results["digest"]["backbone_seq"] = record_fragments[backbone_index]
+ return "auto"
+
- self.results["digest"]["excised_seq"] = record_fragments[excise_index]
- self.results["digest"]["first_overhang"] = str(
+
+compute_feature_box_linewidth
+def compute_feature_box_linewidth(
+ self,
+ feature
+)
+
- record_fragments[excise_index].seq.left_end
- )
+Compute a box_linewidth for this feature.
+View Source
def compute_feature_box_linewidth(self, feature):
- self.results["digest"]["last_overhang"] = str(
+ """Compute a box_linewidth for this feature."""
- record_fragments[excise_index].seq.right_end
+ return 0.3
+
- )
- def count_other_sites(self, other_enzymes):
+
+compute_feature_color
+def compute_feature_color(
+ self,
+ feature
+)
+
- self.results["other_sites"] = {}
- if other_enzymes is None:
+Compute a color for this feature.
+If the feature has a color
qualifier it will be used. Otherwise,
+the classe's default_feature_color
is used.
+To change the behaviour, create a subclass of BiopythonTranslator
+and overwrite this method.
+View Source
def compute_feature_color(self, feature):
- return
+ assessment_ref = "plasmid_assessment"
- bio_enzymes = [Bio.Restriction.__dict__[enzyme] for enzyme in other_enzymes]
+ if assessment_ref in feature.qualifiers:
- restriction_batch = Bio.Restriction.RestrictionBatch(bio_enzymes)
+ if feature.qualifiers[assessment_ref] == "enzyme":
- # Work with the assumption that the sequence is circular:
+ return "red"
- analysis = Bio.Restriction.Analysis(
+ elif feature.qualifiers[assessment_ref] == "excised":
- restriction_batch, sequence=self.record.seq, linear=False
+ return "yellow"
- )
+ elif feature.qualifiers[assessment_ref] == "backbone":
- self.results["other_sites"]["enzyme"] = analysis.full(linear=False)
+ return "tab:cyan"
- self.results["other_sites"]["has_any_other_sites"] = False
+ else:
- for enzyme, matches in self.results["other_sites"]["enzyme"].items():
+ return "tab:blue" # default dna_features_viewer color
- if len(matches) != 0:
+ else:
- self.results["other_sites"]["has_any_other_sites"] = True
+ return "tab:blue"
+
- def sum_results(self):
- self.results["pass"] = True
+
+compute_feature_fontdict
+def compute_feature_fontdict(
+ self,
+ feature
+)
+
- if self.results["is_circular"] is False:
- self.results["pass"] = False
+Compute a font dict for this feature.
+View Source
def compute_feature_fontdict(self, feature):
- return
+ """Compute a font dict for this feature."""
- if self.results["is_site_orientation_correct"] is False:
+ return None
+
- # implicitly checks number of sites too
- self.results["pass"] = False
+
+compute_feature_html
+def compute_feature_html(
+ self,
+ feature
+)
+
- return
- if self.results["other_sites"]["has_any_other_sites"]:
+Gets the 'label' of the feature.
+View Source
def compute_feature_html(self, feature):
- self.results["pass"] = False
+ """Gets the 'label' of the feature."""
- return
+ return self.compute_feature_label(feature)
-
-Methods
-assess_plasmid
-def assess_plasmid(
+compute_feature_label
+def compute_feature_label(
self,
- other_enzymes=None
+ feature
)
-Evaluate plasmid for Golden Gate.
-Parameters
-other_enzymes
-
-List of enzymes used in higher level assemblies (list
).
-
-View Source
def assess_plasmid(self, other_enzymes=None):
-
- """Evaluate plasmid for Golden Gate.
-
- **Parameters**
+Compute the label of the feature.
+View Source
def compute_feature_label(self, feature):
- **other_enzymes**
+ """Compute the label of the feature."""
- > List of enzymes used in higher level assemblies (`list`).
+ label = feature.type
- """
+ for key in self.label_fields:
- self.check_circularity()
+ if key in feature.qualifiers and len(feature.qualifiers[key]):
- self.get_number_of_sites()
+ label = feature.qualifiers[key]
- self.evaluate_orientation()
+ break
- self.digest_plasmid()
+ if isinstance(label, list):
- self.count_other_sites(other_enzymes)
+ label = "|".join(label)
- self.sum_results()
+ return label
-check_circularity
-def check_circularity(
- self
+compute_feature_label_link_color
+def compute_feature_label_link_color(
+ self,
+ feature
)
-View Source
def check_circularity(self):
+Compute the color of the line linking the label to its feature.
+View Source
def compute_feature_label_link_color(self, feature):
- if "topology" not in self.record.annotations:
+ """Compute the color of the line linking the label to its feature."""
- self.results["is_circular"] = False
+ return "black"
+
- elif self.record.annotations["topology"] == "circular":
- self.results["is_circular"] = True
+
+compute_feature_legend_text
+def compute_feature_legend_text(
+ self,
+ feature
+)
+
- else:
- self.results["is_circular"] = False
+View Source
def compute_feature_legend_text(self, feature):
+
+ return None
-count_other_sites
-def count_other_sites(
+compute_feature_linewidth
+def compute_feature_linewidth(
self,
- other_enzymes
+ feature
)
-View Source
def count_other_sites(self, other_enzymes):
+Compute the edge width of the feature's arrow/rectangle.
+View Source
def compute_feature_linewidth(self, feature):
- self.results["other_sites"] = {}
+ """Compute the edge width of the feature's arrow/rectangle."""
- if other_enzymes is None:
+ return 1.0
+
- return
- bio_enzymes = [Bio.Restriction.__dict__[enzyme] for enzyme in other_enzymes]
+
+compute_filtered_features
+def compute_filtered_features(
+ self,
+ features
+)
+
- restriction_batch = Bio.Restriction.RestrictionBatch(bio_enzymes)
- # Work with the assumption that the sequence is circular:
+Return the list of features minus the ignored ones.
+By the method keeps any feature whose type is not in
+ignored_features_types and for which all filter(f) pass.
+View Source
def compute_filtered_features(self, features):
- analysis = Bio.Restriction.Analysis(
+ """Return the list of features minus the ignored ones.
- restriction_batch, sequence=self.record.seq, linear=False
+ By the method keeps any feature whose type is not in
- )
+ ignored_features_types and for which all filter(f) pass.
- self.results["other_sites"]["enzyme"] = analysis.full(linear=False)
+ """
- self.results["other_sites"]["has_any_other_sites"] = False
+ return [
- for enzyme, matches in self.results["other_sites"]["enzyme"].items():
+ f
- if len(matches) != 0:
+ for f in features
- self.results["other_sites"]["has_any_other_sites"] = True
+ if all([fl(f) for fl in self.features_filters])
+
+ and f.type not in self.ignored_features_types
+
+ ]
-digest_plasmid
-def digest_plasmid(
- self
+quick_plot
+def quick_plot(
+ self,
+ record,
+ figure_width=12,
+ **kwargs
)
-View Source
def digest_plasmid(self):
-
- # Obtain fragments and get the backbone's overhangs.
-
- # This method has two assumptions:
-
- # - the sequence has two, correctly oriented enzyme sites.
+Allows super quick and dirty plotting of Biopython records.
+This is really meant for use in a Jupyter/Ipython notebook with
+the "%matplotlib inline" setting.
+
+
+
+from dna_features_viewer import BiopythonTranslator
+BiopythonTranslator.quick_plot(my_record)
+
+
+
+View Source
def quick_plot(self, record, figure_width=12, **kwargs):
- # - the sequence is circular.
+ """Allows super quick and dirty plotting of Biopython records.
- # Therefore there will be exactly two fragments, with one containing both sites.
+ This is really meant for use in a Jupyter/Ipython notebook with
- self.results["digest"] = {}
+ the "%matplotlib inline" setting.
- if not self.results["is_circular"]:
+ >>> from dna_features_viewer import BiopythonTranslator
- return
+ >>> BiopythonTranslator.quick_plot(my_record)
- if not self.results["is_site_orientation_correct"]:
+ """
- return
+ graphic_record = self.translate_record(record)
- record_fragments = dc.StickyEndFragment.list_from_record_digestion(
+ ax, _ = graphic_record.plot(figure_width=figure_width, **kwargs)
- record=self.record, enzyme=self.enzyme, linear=False
+ return ax
+
- )
- if self.enzyme.site in record_fragments[0].to_standard_string():
+
+translate_feature
+def translate_feature(
+ self,
+ feature
+)
+
- backbone_index = 1 # there are only two fragments
- excise_index = 0
+Translate a Biopython feature into a Dna Features Viewer feature.
+View Source
def translate_feature(self, feature):
- else:
+ """Translate a Biopython feature into a Dna Features Viewer feature."""
- backbone_index = 0
+ properties = dict(
- excise_index = 1 # reversed
+ label=self.compute_feature_label(feature),
- self.results["digest"]["backbone_seq"] = record_fragments[backbone_index]
+ color=self.compute_feature_color(feature),
- self.results["digest"]["excised_seq"] = record_fragments[excise_index]
+ html=self.compute_feature_html(feature),
- self.results["digest"]["first_overhang"] = str(
+ fontdict=self.compute_feature_fontdict(feature),
- record_fragments[excise_index].seq.left_end
+ box_linewidth=self.compute_feature_box_linewidth(feature),
- )
+ box_color=self.compute_feature_box_color(feature),
- self.results["digest"]["last_overhang"] = str(
+ linewidth=self.compute_feature_linewidth(feature),
- record_fragments[excise_index].seq.right_end
+ label_link_color=self.compute_feature_label_link_color(feature),
- )
-
+ legend_text=self.compute_feature_legend_text(feature),
+ )
-
-evaluate_orientation
-def evaluate_orientation(
- self
-)
-
+ if self.features_properties is not None:
+ other_properties = self.features_properties
-View Source
def evaluate_orientation(self):
+ if hasattr(other_properties, "__call__"):
- self.results["is_site_orientation_correct"] = False # default
+ other_properties = other_properties(feature)
- # Forward strand:
+ properties.update(other_properties)
- iter = (match for match in re.finditer(self.enzyme.site, str(self.record.seq)))
+ return GraphicFeature(
- if sum(1 for _ in iter) == 1:
+ start=feature.location.start,
- rev_complement = str(self.record.seq.reverse_complement())
+ end=feature.location.end,
- iter_reverse = (m for m in re.finditer(self.enzyme.site, rev_complement))
+ strand=feature.location.strand,
- if sum(1 for _ in iter_reverse) == 1: # 1 site in both strands:
+ **properties
- self.results["is_site_orientation_correct"] = True
+ )
-get_number_of_sites
-def get_number_of_sites(
- self
+translate_record
+def translate_record(
+ self,
+ record,
+ record_class=None,
+ filetype=None
)
-View Source
def get_number_of_sites(self):
+Create a new GraphicRecord from a BioPython Record object.
+Parameters
+record
+ A BioPython Record object or the path to a Genbank or a GFF file.
+record_class
+ The graphic record class to use, e.g. GraphicRecord (default) or
+ CircularGraphicRecord. Strings 'circular' and 'linear' can also be
+ provided.
+filetype
+ Used only when a Genbank or a GFF file is provided; one of "genbank"
+ or "gff" to be used. Default None infers from file extension.
+View Source
def translate_record(self, record, record_class=None, filetype=None):
- if "is_circular" in self.results:
+ """Create a new GraphicRecord from a BioPython Record object.
- is_linear = not self.results["is_circular"]
+ Parameters
- else:
+ ----------
- is_linear = False
+ record
- restriction_batch = Bio.Restriction.RestrictionBatch([self.enzyme])
+ A BioPython Record object or the path to a Genbank or a GFF file.
- analysis = Bio.Restriction.Analysis(
+ record_class
- restriction_batch, sequence=self.record.seq, linear=is_linear
+ The graphic record class to use, e.g. GraphicRecord (default) or
- )
+ CircularGraphicRecord. Strings 'circular' and 'linear' can also be
- analysis_results = analysis.full(linear=is_linear)
+ provided.
- self.results["number_of_sites"] = len(analysis_results[self.enzyme])
-
+ filetype
+ Used only when a Genbank or a GFF file is provided; one of "genbank"
-
-sum_results
-def sum_results(
- self
-)
-
+ or "gff" to be used. Default None infers from file extension.
+
+ """
+ classes = {
-View Source
def sum_results(self):
+ "linear": GraphicRecord,
- self.results["pass"] = True
+ "circular": CircularGraphicRecord,
- if self.results["is_circular"] is False:
+ None: GraphicRecord,
- self.results["pass"] = False
+ }
- return
+ if record_class in classes:
- if self.results["is_site_orientation_correct"] is False:
+ record_class = classes[record_class]
- # implicitly checks number of sites too
+ if isinstance(record, str) or hasattr(record, "read"):
- self.results["pass"] = False
+ record = load_record(record, filetype=filetype)
- return
+ filtered_features = self.compute_filtered_features(record.features)
- if self.results["other_sites"]["has_any_other_sites"]:
+ return record_class(
- self.results["pass"] = False
+ sequence_length=len(record),
- return
+ sequence=str(record.seq),
+
+ features=[
+
+ self.translate_feature(feature)
+
+ for feature in filtered_features
+
+ if feature.location is not None
+
+ ],
+
+ **self.graphic_record_parameters
+
+ )
diff --git a/docs/reference/plasmid_assessor/reports/index.html b/docs/reference/plasmid_assessor/reports/index.html
index d5f6926..f3d73e9 100644
--- a/docs/reference/plasmid_assessor/reports/index.html
+++ b/docs/reference/plasmid_assessor/reports/index.html
@@ -457,25 +457,33 @@ Module plasmid_assessor.reports
import os
-import matplotlib.pyplot as plt
+try:
-import pandas
+ import pdf_reports.tools as pdf_tools
-from pdf_reports import (
+ from pdf_reports import (
- add_css_class,
+ add_css_class,
- dataframe_to_html,
+ dataframe_to_html,
- pug_to_html,
+ pug_to_html,
- style_table_rows,
+ style_table_rows,
- write_report,
+ write_report,
-)
+ )
+
+ import pandas
+
+ import matplotlib
+
+ REPORT_PKGS_AVAILABLE = True
-import pdf_reports.tools as pdf_tools
+except ImportError:
+
+ REPORT_PKGS_AVAILABLE = False
from .version import __version__
@@ -497,7 +505,7 @@ Module plasmid_assessor.reports
% (now, __version__),
- "plasma_logo_url": os.path.join(ASSETS_PATH, "imgs", "logo.png"),
+ "plasma_logo_url": os.path.join(ASSETS_PATH, "imgs", "plasma_logo.png"),
}
@@ -525,7 +533,15 @@ Module plasmid_assessor.reports
"""
- # assessment.figure_data = pdf_tools.figure_data(assessment.fig, fmt="svg")
+ if not REPORT_PKGS_AVAILABLE:
+
+ raise ImportError(
+
+ "Install extra packages with `pip install plasmid_assessor[report]`"
+
+ )
+
+ assessment.figure_data = pdf_tools.figure_data(assessment.fig, fmt="svg")
html = end_pug_to_html(REPORT_TEMPLATE, assessment=assessment,)
@@ -539,6 +555,10 @@ Variables
+
+
+
@@ -570,7 +590,7 @@ end_pug_to_html
% (now, __version__),
- "plasma_logo_url": os.path.join(ASSETS_PATH, "imgs", "logo.png"),
+ "plasma_logo_url": os.path.join(ASSETS_PATH, "imgs", "plasma_logo.png"),
}
@@ -603,27 +623,35 @@ write_pdf_report
Assessment instance.
-View Source
def write_pdf_report(target, assessment):
+View Source
def write_pdf_report(target, assessment):
- """Write an assessment report with a PDF summary.
+ """Write an assessment report with a PDF summary.
- **Parameters**
+ **Parameters**
- **target**
+ **target**
- > Path for PDF file.
+ > Path for PDF file.
- **assessment**
+ **assessment**
- > Assessment instance.
+ > Assessment instance.
- """
+ """
- # assessment.figure_data = pdf_tools.figure_data(assessment.fig, fmt="svg")
+ if not REPORT_PKGS_AVAILABLE:
- html = end_pug_to_html(REPORT_TEMPLATE, assessment=assessment,)
+ raise ImportError(
- write_report(html, target, extra_stylesheets=(STYLESHEET,))
+ "Install extra packages with `pip install plasmid_assessor[report]`"
+
+ )
+
+ assessment.figure_data = pdf_tools.figure_data(assessment.fig, fmt="svg")
+
+ html = end_pug_to_html(REPORT_TEMPLATE, assessment=assessment,)
+
+ write_report(html, target, extra_stylesheets=(STYLESHEET,))
diff --git a/docs/search/search_index.json b/docs/search/search_index.json
index 60c23ed..5afa69c 100644
--- a/docs/search/search_index.json
+++ b/docs/search/search_index.json
@@ -1 +1 @@
-{"config":{"lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Plasmid assessor Plasmid assessment for Golden Gate cloning. An important task in DNA assembly is creating or adapting a plasmid to serve as a backbone for the assembled parts. This package provides tools for quickly checking a few basic backbone requirements on a plasmid sequence. The most important steps of vector (backbone) adaptation are ensuring that there are: two sites for the chosen restriction enzyme, flanking the insert segment no other sites for the restriction enzyme The choice of the two backbone overhangs are also important, because they will be involved in all assemblies using that plasmid. Additionally, we can add selection for proper assembly (for example, by including a ccdB suicide cassette at the insertion location) and for presence of plasmid in the bacterium (for example, by using antibiotic resistance). Finally, we can check that the replicon and the partitioning system in the plasmid suits the strain, compatibility and other requirements. Install pip install plasmid_assessor # pip install plasmid_assessor [ report ] # install with dependencies for pdf reports Usage import plasmid_assessor as plasma # Load your Genbank or FASTA file as a Biopython SeqRecord, or create a new one: from Bio.SeqRecord import SeqRecord from Bio.Seq import Seq sequence = SeqRecord ( Seq ( \"CGTCTCAACTG\" + \"AAA\" + \"TATCAGAGACG\" + \"AGGTCTC\" ), annotations = { \"topology\" : \"circular\" }) # Evaluate plasmid: design = plasma . Assessment ( sequence , \"BsmBI\" ) design . assess_plasmid ( other_enzymes = [ \"BsaI\" ]) # also check for the enzyme of the 2nd level assembly # Results are stored in: design . results # Save as a PDF report: plasma . write_pdf_report ( \"report.pdf\" , design ) Versioning Plasmid assessor uses the semantic versioning scheme. License = MIT Plasmid assessor is free/libre and open-source software, which means the users have the freedom to run, study, change and distribute the software. Plasmid assessor was written at the Edinburgh Genome Foundry by Peter Vegh . Copyright 2021 Edinburgh Genome Foundry, University of Edinburgh","title":"Home"},{"location":"#plasmid-assessor","text":"Plasmid assessment for Golden Gate cloning. An important task in DNA assembly is creating or adapting a plasmid to serve as a backbone for the assembled parts. This package provides tools for quickly checking a few basic backbone requirements on a plasmid sequence. The most important steps of vector (backbone) adaptation are ensuring that there are: two sites for the chosen restriction enzyme, flanking the insert segment no other sites for the restriction enzyme The choice of the two backbone overhangs are also important, because they will be involved in all assemblies using that plasmid. Additionally, we can add selection for proper assembly (for example, by including a ccdB suicide cassette at the insertion location) and for presence of plasmid in the bacterium (for example, by using antibiotic resistance). Finally, we can check that the replicon and the partitioning system in the plasmid suits the strain, compatibility and other requirements.","title":"Plasmid assessor"},{"location":"#install","text":"pip install plasmid_assessor # pip install plasmid_assessor [ report ] # install with dependencies for pdf reports","title":"Install"},{"location":"#usage","text":"import plasmid_assessor as plasma # Load your Genbank or FASTA file as a Biopython SeqRecord, or create a new one: from Bio.SeqRecord import SeqRecord from Bio.Seq import Seq sequence = SeqRecord ( Seq ( \"CGTCTCAACTG\" + \"AAA\" + \"TATCAGAGACG\" + \"AGGTCTC\" ), annotations = { \"topology\" : \"circular\" }) # Evaluate plasmid: design = plasma . Assessment ( sequence , \"BsmBI\" ) design . assess_plasmid ( other_enzymes = [ \"BsaI\" ]) # also check for the enzyme of the 2nd level assembly # Results are stored in: design . results # Save as a PDF report: plasma . write_pdf_report ( \"report.pdf\" , design )","title":"Usage"},{"location":"#versioning","text":"Plasmid assessor uses the semantic versioning scheme.","title":"Versioning"},{"location":"#license-mit","text":"Plasmid assessor is free/libre and open-source software, which means the users have the freedom to run, study, change and distribute the software. Plasmid assessor was written at the Edinburgh Genome Foundry by Peter Vegh . Copyright 2021 Edinburgh Genome Foundry, University of Edinburgh","title":"License = MIT"},{"location":"reference/plasmid_assessor/","text":"Module plasmid_assessor View Source from .Assessment import Assessment from .reports import write_pdf_report Sub-modules plasmid_assessor.Assessment plasmid_assessor.reports plasmid_assessor.version","title":"Index"},{"location":"reference/plasmid_assessor/#module-plasmid_assessor","text":"View Source from .Assessment import Assessment from .reports import write_pdf_report","title":"Module plasmid_assessor"},{"location":"reference/plasmid_assessor/#sub-modules","text":"plasmid_assessor.Assessment plasmid_assessor.reports plasmid_assessor.version","title":"Sub-modules"},{"location":"reference/plasmid_assessor/Assessment/","text":"Module plasmid_assessor.Assessment View Source import re import Bio import Bio.Restriction import dnacauldron as dc class Assessment : \"\"\"The plasmid assessment class. **Parameters** **record** > A Biopython `SeqRecord`. **enzyme** > A restriction enzyme (`str`). A Biopython `RestrictionType` will be looked up using the string. \"\"\" def __init__ ( self , record , enzyme ): self . record = record self . enzyme = Bio . Restriction . __dict__ [ enzyme ] self . results = {} def assess_plasmid ( self , other_enzymes = None ): \"\"\"Evaluate plasmid for Golden Gate. **Parameters** **other_enzymes** > List of enzymes used in higher level assemblies (`list`). \"\"\" self . check_circularity () self . get_number_of_sites () self . evaluate_orientation () self . digest_plasmid () self . count_other_sites ( other_enzymes ) self . sum_results () def check_circularity ( self ): if \"topology\" not in self . record . annotations : self . results [ \"is_circular\" ] = False elif self . record . annotations [ \"topology\" ] == \"circular\" : self . results [ \"is_circular\" ] = True else : self . results [ \"is_circular\" ] = False def get_number_of_sites ( self ): if \"is_circular\" in self . results : is_linear = not self . results [ \"is_circular\" ] else : is_linear = False restriction_batch = Bio . Restriction . RestrictionBatch ([ self . enzyme ]) analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = is_linear ) analysis_results = analysis . full ( linear = is_linear ) self . results [ \"number_of_sites\" ] = len ( analysis_results [ self . enzyme ]) def evaluate_orientation ( self ): self . results [ \"is_site_orientation_correct\" ] = False # default # Forward strand: iter = ( match for match in re . finditer ( self . enzyme . site , str ( self . record . seq ))) if sum ( 1 for _ in iter ) == 1 : rev_complement = str ( self . record . seq . reverse_complement ()) iter_reverse = ( m for m in re . finditer ( self . enzyme . site , rev_complement )) if sum ( 1 for _ in iter_reverse ) == 1 : # 1 site in both strands: self . results [ \"is_site_orientation_correct\" ] = True def digest_plasmid ( self ): # Obtain fragments and get the backbone's overhangs. # This method has two assumptions: # - the sequence has two, correctly oriented enzyme sites. # - the sequence is circular. # Therefore there will be exactly two fragments, with one containing both sites. self . results [ \"digest\" ] = {} if not self . results [ \"is_circular\" ]: return if not self . results [ \"is_site_orientation_correct\" ]: return record_fragments = dc . StickyEndFragment . list_from_record_digestion ( record = self . record , enzyme = self . enzyme , linear = False ) if self . enzyme . site in record_fragments [ 0 ] . to_standard_string (): backbone_index = 1 # there are only two fragments excise_index = 0 else : backbone_index = 0 excise_index = 1 # reversed self . results [ \"digest\" ][ \"backbone_seq\" ] = record_fragments [ backbone_index ] self . results [ \"digest\" ][ \"excised_seq\" ] = record_fragments [ excise_index ] self . results [ \"digest\" ][ \"first_overhang\" ] = str ( record_fragments [ excise_index ] . seq . left_end ) self . results [ \"digest\" ][ \"last_overhang\" ] = str ( record_fragments [ excise_index ] . seq . right_end ) def count_other_sites ( self , other_enzymes ): self . results [ \"other_sites\" ] = {} if other_enzymes is None : return bio_enzymes = [ Bio . Restriction . __dict__ [ enzyme ] for enzyme in other_enzymes ] restriction_batch = Bio . Restriction . RestrictionBatch ( bio_enzymes ) # Work with the assumption that the sequence is circular: analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = False ) self . results [ \"other_sites\" ][ \"enzyme\" ] = analysis . full ( linear = False ) self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = False for enzyme , matches in self . results [ \"other_sites\" ][ \"enzyme\" ] . items (): if len ( matches ) != 0 : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = True def sum_results ( self ): self . results [ \"pass\" ] = True if self . results [ \"is_circular\" ] is False : self . results [ \"pass\" ] = False return if self . results [ \"is_site_orientation_correct\" ] is False : # implicitly checks number of sites too self . results [ \"pass\" ] = False return if self . results [ \"other_sites\" ][ \"has_any_other_sites\" ]: self . results [ \"pass\" ] = False return Classes Assessment class Assessment ( record , enzyme ) The plasmid assessment class. Parameters record A Biopython SeqRecord . enzyme A restriction enzyme ( str ). A Biopython RestrictionType will be looked up using the string. View Source class Assessment : \"\"\"The plasmid assessment class. **Parameters** **record** > A Biopython `SeqRecord`. **enzyme** > A restriction enzyme (`str`). A Biopython `RestrictionType` will be looked up using the string. \"\"\" def __init__ ( self , record , enzyme ) : self . record = record self . enzyme = Bio . Restriction . __dict__ [ enzyme ] self . results = {} def assess_plasmid ( self , other_enzymes = None ) : \"\"\"Evaluate plasmid for Golden Gate. **Parameters** **other_enzymes** > List of enzymes used in higher level assemblies (`list`). \"\"\" self . check_circularity () self . get_number_of_sites () self . evaluate_orientation () self . digest_plasmid () self . count_other_sites ( other_enzymes ) self . sum_results () def check_circularity ( self ) : if \"topology\" not in self . record . annotations : self . results [ \"is_circular\" ] = False elif self . record . annotations [ \"topology\" ] == \"circular\" : self . results [ \"is_circular\" ] = True else : self . results [ \"is_circular\" ] = False def get_number_of_sites ( self ) : if \"is_circular\" in self . results : is_linear = not self . results [ \"is_circular\" ] else : is_linear = False restriction_batch = Bio . Restriction . RestrictionBatch ( [ self.enzyme ] ) analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = is_linear ) analysis_results = analysis . full ( linear = is_linear ) self . results [ \"number_of_sites\" ] = len ( analysis_results [ self.enzyme ] ) def evaluate_orientation ( self ) : self . results [ \"is_site_orientation_correct\" ] = False # default # Forward strand : iter = ( match for match in re . finditer ( self . enzyme . site , str ( self . record . seq ))) if sum ( 1 for _ in iter ) == 1 : rev_complement = str ( self . record . seq . reverse_complement ()) iter_reverse = ( m for m in re . finditer ( self . enzyme . site , rev_complement )) if sum ( 1 for _ in iter_reverse ) == 1 : # 1 site in both strands : self . results [ \"is_site_orientation_correct\" ] = True def digest_plasmid ( self ) : # Obtain fragments and get the backbone ' s overhangs . # This method has two assumptions : # - the sequence has two , correctly oriented enzyme sites . # - the sequence is circular . # Therefore there will be exactly two fragments , with one containing both sites . self . results [ \"digest\" ] = {} if not self . results [ \"is_circular\" ] : return if not self . results [ \"is_site_orientation_correct\" ] : return record_fragments = dc . StickyEndFragment . list_from_record_digestion ( record = self . record , enzyme = self . enzyme , linear = False ) if self . enzyme . site in record_fragments [ 0 ] . to_standard_string () : backbone_index = 1 # there are only two fragments excise_index = 0 else : backbone_index = 0 excise_index = 1 # reversed self . results [ \"digest\" ][ \"backbone_seq\" ] = record_fragments [ backbone_index ] self . results [ \"digest\" ][ \"excised_seq\" ] = record_fragments [ excise_index ] self . results [ \"digest\" ][ \"first_overhang\" ] = str ( record_fragments [ excise_index ] . seq . left_end ) self . results [ \"digest\" ][ \"last_overhang\" ] = str ( record_fragments [ excise_index ] . seq . right_end ) def count_other_sites ( self , other_enzymes ) : self . results [ \"other_sites\" ] = {} if other_enzymes is None : return bio_enzymes = [ Bio.Restriction.__dict__[enzyme ] for enzyme in other_enzymes ] restriction_batch = Bio . Restriction . RestrictionBatch ( bio_enzymes ) # Work with the assumption that the sequence is circular : analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = False ) self . results [ \"other_sites\" ][ \"enzyme\" ] = analysis . full ( linear = False ) self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = False for enzyme , matches in self . results [ \"other_sites\" ][ \"enzyme\" ] . items () : if len ( matches ) != 0 : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = True def sum_results ( self ) : self . results [ \"pass\" ] = True if self . results [ \"is_circular\" ] is False : self . results [ \"pass\" ] = False return if self . results [ \"is_site_orientation_correct\" ] is False : # implicitly checks number of sites too self . results [ \"pass\" ] = False return if self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] : self . results [ \"pass\" ] = False return Methods assess_plasmid def assess_plasmid ( self , other_enzymes = None ) Evaluate plasmid for Golden Gate. Parameters other_enzymes List of enzymes used in higher level assemblies ( list ). View Source def assess_plasmid ( self , other_enzymes = None ) : \" \"\" Evaluate plasmid for Golden Gate. **Parameters** **other_enzymes** > List of enzymes used in higher level assemblies (`list`). \"\" \" self . check_circularity () self . get_number_of_sites () self . evaluate_orientation () self . digest_plasmid () self . count_other_sites ( other_enzymes ) self . sum_results () check_circularity def check_circularity ( self ) View Source def check_circularity ( self ) : if \" topology \" not in self . record . annotations : self . results [ \" is_circular \" ] = False elif self . record . annotations [ \" topology \" ] == \" circular \" : self . results [ \" is_circular \" ] = True else : self . results [ \" is_circular \" ] = False count_other_sites def count_other_sites ( self , other_enzymes ) View Source def count_other_sites ( self , other_enzymes ) : self . results [ \"other_sites\" ] = {} if other_enzymes is None : return bio_enzymes = [ Bio.Restriction.__dict__[enzyme ] for enzyme in other_enzymes ] restriction_batch = Bio . Restriction . RestrictionBatch ( bio_enzymes ) # Work with the assumption that the sequence is circular : analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = False ) self . results [ \"other_sites\" ][ \"enzyme\" ] = analysis . full ( linear = False ) self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = False for enzyme , matches in self . results [ \"other_sites\" ][ \"enzyme\" ] . items () : if len ( matches ) != 0 : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = True digest_plasmid def digest_plasmid ( self ) View Source def digest_plasmid ( self ) : # Obtain fragments and get the backbone ' s overhangs . # This method has two assumptions : # - the sequence has two , correctly oriented enzyme sites . # - the sequence is circular . # Therefore there will be exactly two fragments , with one containing both sites . self . results [ \"digest\" ] = {} if not self . results [ \"is_circular\" ] : return if not self . results [ \"is_site_orientation_correct\" ] : return record_fragments = dc . StickyEndFragment . list_from_record_digestion ( record = self . record , enzyme = self . enzyme , linear = False ) if self . enzyme . site in record_fragments [ 0 ] . to_standard_string () : backbone_index = 1 # there are only two fragments excise_index = 0 else : backbone_index = 0 excise_index = 1 # reversed self . results [ \"digest\" ][ \"backbone_seq\" ] = record_fragments [ backbone_index ] self . results [ \"digest\" ][ \"excised_seq\" ] = record_fragments [ excise_index ] self . results [ \"digest\" ][ \"first_overhang\" ] = str ( record_fragments [ excise_index ] . seq . left_end ) self . results [ \"digest\" ][ \"last_overhang\" ] = str ( record_fragments [ excise_index ] . seq . right_end ) evaluate_orientation def evaluate_orientation ( self ) View Source def evaluate_orientation ( self ) : self . results [ \" is_site_orientation_correct \" ] = False # default # Forward strand : iter = ( match for match in re . finditer ( self . enzyme . site , str ( self . record . seq ))) if sum ( 1 for _ in iter ) == 1 : rev_complement = str ( self . record . seq . reverse_complement ()) iter_reverse = ( m for m in re . finditer ( self . enzyme . site , rev_complement )) if sum ( 1 for _ in iter_reverse ) == 1 : # 1 site in both strands : self . results [ \" is_site_orientation_correct \" ] = True get_number_of_sites def get_number_of_sites ( self ) View Source def get_number_of_sites ( self ) : if \" is_circular \" in self . results : is_linear = not self . results [ \" is_circular \" ] else : is_linear = False restriction_batch = Bio . Restriction . RestrictionBatch ( [ self . enzyme ] ) analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = is_linear ) analysis_results = analysis . full ( linear = is_linear ) self . results [ \" number_of_sites \" ] = len ( analysis_results [ self . enzyme ] ) sum_results def sum_results ( self ) View Source def sum_results ( self ) : self . results [ \" pass \" ] = True if self . results [ \" is_circular \" ] is False : self . results [ \" pass \" ] = False return if self . results [ \" is_site_orientation_correct \" ] is False : # implicitly checks number of sites too self . results [ \" pass \" ] = False return if self . results [ \" other_sites \" ][ \" has_any_other_sites \" ]: self . results [ \" pass \" ] = False return","title":"Assessment"},{"location":"reference/plasmid_assessor/Assessment/#module-plasmid_assessorassessment","text":"View Source import re import Bio import Bio.Restriction import dnacauldron as dc class Assessment : \"\"\"The plasmid assessment class. **Parameters** **record** > A Biopython `SeqRecord`. **enzyme** > A restriction enzyme (`str`). A Biopython `RestrictionType` will be looked up using the string. \"\"\" def __init__ ( self , record , enzyme ): self . record = record self . enzyme = Bio . Restriction . __dict__ [ enzyme ] self . results = {} def assess_plasmid ( self , other_enzymes = None ): \"\"\"Evaluate plasmid for Golden Gate. **Parameters** **other_enzymes** > List of enzymes used in higher level assemblies (`list`). \"\"\" self . check_circularity () self . get_number_of_sites () self . evaluate_orientation () self . digest_plasmid () self . count_other_sites ( other_enzymes ) self . sum_results () def check_circularity ( self ): if \"topology\" not in self . record . annotations : self . results [ \"is_circular\" ] = False elif self . record . annotations [ \"topology\" ] == \"circular\" : self . results [ \"is_circular\" ] = True else : self . results [ \"is_circular\" ] = False def get_number_of_sites ( self ): if \"is_circular\" in self . results : is_linear = not self . results [ \"is_circular\" ] else : is_linear = False restriction_batch = Bio . Restriction . RestrictionBatch ([ self . enzyme ]) analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = is_linear ) analysis_results = analysis . full ( linear = is_linear ) self . results [ \"number_of_sites\" ] = len ( analysis_results [ self . enzyme ]) def evaluate_orientation ( self ): self . results [ \"is_site_orientation_correct\" ] = False # default # Forward strand: iter = ( match for match in re . finditer ( self . enzyme . site , str ( self . record . seq ))) if sum ( 1 for _ in iter ) == 1 : rev_complement = str ( self . record . seq . reverse_complement ()) iter_reverse = ( m for m in re . finditer ( self . enzyme . site , rev_complement )) if sum ( 1 for _ in iter_reverse ) == 1 : # 1 site in both strands: self . results [ \"is_site_orientation_correct\" ] = True def digest_plasmid ( self ): # Obtain fragments and get the backbone's overhangs. # This method has two assumptions: # - the sequence has two, correctly oriented enzyme sites. # - the sequence is circular. # Therefore there will be exactly two fragments, with one containing both sites. self . results [ \"digest\" ] = {} if not self . results [ \"is_circular\" ]: return if not self . results [ \"is_site_orientation_correct\" ]: return record_fragments = dc . StickyEndFragment . list_from_record_digestion ( record = self . record , enzyme = self . enzyme , linear = False ) if self . enzyme . site in record_fragments [ 0 ] . to_standard_string (): backbone_index = 1 # there are only two fragments excise_index = 0 else : backbone_index = 0 excise_index = 1 # reversed self . results [ \"digest\" ][ \"backbone_seq\" ] = record_fragments [ backbone_index ] self . results [ \"digest\" ][ \"excised_seq\" ] = record_fragments [ excise_index ] self . results [ \"digest\" ][ \"first_overhang\" ] = str ( record_fragments [ excise_index ] . seq . left_end ) self . results [ \"digest\" ][ \"last_overhang\" ] = str ( record_fragments [ excise_index ] . seq . right_end ) def count_other_sites ( self , other_enzymes ): self . results [ \"other_sites\" ] = {} if other_enzymes is None : return bio_enzymes = [ Bio . Restriction . __dict__ [ enzyme ] for enzyme in other_enzymes ] restriction_batch = Bio . Restriction . RestrictionBatch ( bio_enzymes ) # Work with the assumption that the sequence is circular: analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = False ) self . results [ \"other_sites\" ][ \"enzyme\" ] = analysis . full ( linear = False ) self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = False for enzyme , matches in self . results [ \"other_sites\" ][ \"enzyme\" ] . items (): if len ( matches ) != 0 : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = True def sum_results ( self ): self . results [ \"pass\" ] = True if self . results [ \"is_circular\" ] is False : self . results [ \"pass\" ] = False return if self . results [ \"is_site_orientation_correct\" ] is False : # implicitly checks number of sites too self . results [ \"pass\" ] = False return if self . results [ \"other_sites\" ][ \"has_any_other_sites\" ]: self . results [ \"pass\" ] = False return","title":"Module plasmid_assessor.Assessment"},{"location":"reference/plasmid_assessor/Assessment/#classes","text":"","title":"Classes"},{"location":"reference/plasmid_assessor/Assessment/#assessment","text":"class Assessment ( record , enzyme ) The plasmid assessment class. Parameters record A Biopython SeqRecord . enzyme A restriction enzyme ( str ). A Biopython RestrictionType will be looked up using the string. View Source class Assessment : \"\"\"The plasmid assessment class. **Parameters** **record** > A Biopython `SeqRecord`. **enzyme** > A restriction enzyme (`str`). A Biopython `RestrictionType` will be looked up using the string. \"\"\" def __init__ ( self , record , enzyme ) : self . record = record self . enzyme = Bio . Restriction . __dict__ [ enzyme ] self . results = {} def assess_plasmid ( self , other_enzymes = None ) : \"\"\"Evaluate plasmid for Golden Gate. **Parameters** **other_enzymes** > List of enzymes used in higher level assemblies (`list`). \"\"\" self . check_circularity () self . get_number_of_sites () self . evaluate_orientation () self . digest_plasmid () self . count_other_sites ( other_enzymes ) self . sum_results () def check_circularity ( self ) : if \"topology\" not in self . record . annotations : self . results [ \"is_circular\" ] = False elif self . record . annotations [ \"topology\" ] == \"circular\" : self . results [ \"is_circular\" ] = True else : self . results [ \"is_circular\" ] = False def get_number_of_sites ( self ) : if \"is_circular\" in self . results : is_linear = not self . results [ \"is_circular\" ] else : is_linear = False restriction_batch = Bio . Restriction . RestrictionBatch ( [ self.enzyme ] ) analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = is_linear ) analysis_results = analysis . full ( linear = is_linear ) self . results [ \"number_of_sites\" ] = len ( analysis_results [ self.enzyme ] ) def evaluate_orientation ( self ) : self . results [ \"is_site_orientation_correct\" ] = False # default # Forward strand : iter = ( match for match in re . finditer ( self . enzyme . site , str ( self . record . seq ))) if sum ( 1 for _ in iter ) == 1 : rev_complement = str ( self . record . seq . reverse_complement ()) iter_reverse = ( m for m in re . finditer ( self . enzyme . site , rev_complement )) if sum ( 1 for _ in iter_reverse ) == 1 : # 1 site in both strands : self . results [ \"is_site_orientation_correct\" ] = True def digest_plasmid ( self ) : # Obtain fragments and get the backbone ' s overhangs . # This method has two assumptions : # - the sequence has two , correctly oriented enzyme sites . # - the sequence is circular . # Therefore there will be exactly two fragments , with one containing both sites . self . results [ \"digest\" ] = {} if not self . results [ \"is_circular\" ] : return if not self . results [ \"is_site_orientation_correct\" ] : return record_fragments = dc . StickyEndFragment . list_from_record_digestion ( record = self . record , enzyme = self . enzyme , linear = False ) if self . enzyme . site in record_fragments [ 0 ] . to_standard_string () : backbone_index = 1 # there are only two fragments excise_index = 0 else : backbone_index = 0 excise_index = 1 # reversed self . results [ \"digest\" ][ \"backbone_seq\" ] = record_fragments [ backbone_index ] self . results [ \"digest\" ][ \"excised_seq\" ] = record_fragments [ excise_index ] self . results [ \"digest\" ][ \"first_overhang\" ] = str ( record_fragments [ excise_index ] . seq . left_end ) self . results [ \"digest\" ][ \"last_overhang\" ] = str ( record_fragments [ excise_index ] . seq . right_end ) def count_other_sites ( self , other_enzymes ) : self . results [ \"other_sites\" ] = {} if other_enzymes is None : return bio_enzymes = [ Bio.Restriction.__dict__[enzyme ] for enzyme in other_enzymes ] restriction_batch = Bio . Restriction . RestrictionBatch ( bio_enzymes ) # Work with the assumption that the sequence is circular : analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = False ) self . results [ \"other_sites\" ][ \"enzyme\" ] = analysis . full ( linear = False ) self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = False for enzyme , matches in self . results [ \"other_sites\" ][ \"enzyme\" ] . items () : if len ( matches ) != 0 : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = True def sum_results ( self ) : self . results [ \"pass\" ] = True if self . results [ \"is_circular\" ] is False : self . results [ \"pass\" ] = False return if self . results [ \"is_site_orientation_correct\" ] is False : # implicitly checks number of sites too self . results [ \"pass\" ] = False return if self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] : self . results [ \"pass\" ] = False return","title":"Assessment"},{"location":"reference/plasmid_assessor/Assessment/#methods","text":"","title":"Methods"},{"location":"reference/plasmid_assessor/Assessment/#assess_plasmid","text":"def assess_plasmid ( self , other_enzymes = None ) Evaluate plasmid for Golden Gate. Parameters other_enzymes List of enzymes used in higher level assemblies ( list ). View Source def assess_plasmid ( self , other_enzymes = None ) : \" \"\" Evaluate plasmid for Golden Gate. **Parameters** **other_enzymes** > List of enzymes used in higher level assemblies (`list`). \"\" \" self . check_circularity () self . get_number_of_sites () self . evaluate_orientation () self . digest_plasmid () self . count_other_sites ( other_enzymes ) self . sum_results ()","title":"assess_plasmid"},{"location":"reference/plasmid_assessor/Assessment/#check_circularity","text":"def check_circularity ( self ) View Source def check_circularity ( self ) : if \" topology \" not in self . record . annotations : self . results [ \" is_circular \" ] = False elif self . record . annotations [ \" topology \" ] == \" circular \" : self . results [ \" is_circular \" ] = True else : self . results [ \" is_circular \" ] = False","title":"check_circularity"},{"location":"reference/plasmid_assessor/Assessment/#count_other_sites","text":"def count_other_sites ( self , other_enzymes ) View Source def count_other_sites ( self , other_enzymes ) : self . results [ \"other_sites\" ] = {} if other_enzymes is None : return bio_enzymes = [ Bio.Restriction.__dict__[enzyme ] for enzyme in other_enzymes ] restriction_batch = Bio . Restriction . RestrictionBatch ( bio_enzymes ) # Work with the assumption that the sequence is circular : analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = False ) self . results [ \"other_sites\" ][ \"enzyme\" ] = analysis . full ( linear = False ) self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = False for enzyme , matches in self . results [ \"other_sites\" ][ \"enzyme\" ] . items () : if len ( matches ) != 0 : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = True","title":"count_other_sites"},{"location":"reference/plasmid_assessor/Assessment/#digest_plasmid","text":"def digest_plasmid ( self ) View Source def digest_plasmid ( self ) : # Obtain fragments and get the backbone ' s overhangs . # This method has two assumptions : # - the sequence has two , correctly oriented enzyme sites . # - the sequence is circular . # Therefore there will be exactly two fragments , with one containing both sites . self . results [ \"digest\" ] = {} if not self . results [ \"is_circular\" ] : return if not self . results [ \"is_site_orientation_correct\" ] : return record_fragments = dc . StickyEndFragment . list_from_record_digestion ( record = self . record , enzyme = self . enzyme , linear = False ) if self . enzyme . site in record_fragments [ 0 ] . to_standard_string () : backbone_index = 1 # there are only two fragments excise_index = 0 else : backbone_index = 0 excise_index = 1 # reversed self . results [ \"digest\" ][ \"backbone_seq\" ] = record_fragments [ backbone_index ] self . results [ \"digest\" ][ \"excised_seq\" ] = record_fragments [ excise_index ] self . results [ \"digest\" ][ \"first_overhang\" ] = str ( record_fragments [ excise_index ] . seq . left_end ) self . results [ \"digest\" ][ \"last_overhang\" ] = str ( record_fragments [ excise_index ] . seq . right_end )","title":"digest_plasmid"},{"location":"reference/plasmid_assessor/Assessment/#evaluate_orientation","text":"def evaluate_orientation ( self ) View Source def evaluate_orientation ( self ) : self . results [ \" is_site_orientation_correct \" ] = False # default # Forward strand : iter = ( match for match in re . finditer ( self . enzyme . site , str ( self . record . seq ))) if sum ( 1 for _ in iter ) == 1 : rev_complement = str ( self . record . seq . reverse_complement ()) iter_reverse = ( m for m in re . finditer ( self . enzyme . site , rev_complement )) if sum ( 1 for _ in iter_reverse ) == 1 : # 1 site in both strands : self . results [ \" is_site_orientation_correct \" ] = True","title":"evaluate_orientation"},{"location":"reference/plasmid_assessor/Assessment/#get_number_of_sites","text":"def get_number_of_sites ( self ) View Source def get_number_of_sites ( self ) : if \" is_circular \" in self . results : is_linear = not self . results [ \" is_circular \" ] else : is_linear = False restriction_batch = Bio . Restriction . RestrictionBatch ( [ self . enzyme ] ) analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = is_linear ) analysis_results = analysis . full ( linear = is_linear ) self . results [ \" number_of_sites \" ] = len ( analysis_results [ self . enzyme ] )","title":"get_number_of_sites"},{"location":"reference/plasmid_assessor/Assessment/#sum_results","text":"def sum_results ( self ) View Source def sum_results ( self ) : self . results [ \" pass \" ] = True if self . results [ \" is_circular \" ] is False : self . results [ \" pass \" ] = False return if self . results [ \" is_site_orientation_correct \" ] is False : # implicitly checks number of sites too self . results [ \" pass \" ] = False return if self . results [ \" other_sites \" ][ \" has_any_other_sites \" ]: self . results [ \" pass \" ] = False return","title":"sum_results"},{"location":"reference/plasmid_assessor/reports/","text":"Module plasmid_assessor.reports View Source from datetime import datetime import os import matplotlib.pyplot as plt import pandas from pdf_reports import ( add_css_class , dataframe_to_html , pug_to_html , style_table_rows , write_report , ) import pdf_reports.tools as pdf_tools from .version import __version__ THIS_PATH = os . path . dirname ( os . path . realpath ( __file__ )) ASSETS_PATH = os . path . join ( THIS_PATH , \"report_assets\" ) REPORT_TEMPLATE = os . path . join ( ASSETS_PATH , \"assessment_report.pug\" ) STYLESHEET = os . path . join ( ASSETS_PATH , \"report_style.css\" ) def end_pug_to_html ( template , ** context ): now = datetime . now () . strftime ( \"%Y-%m- %d \" ) defaults = { \"sidebar_text\" : \"Generated on %s by EGF's Plasmid assessor (version %s )\" % ( now , __version__ ), \"plasma_logo_url\" : os . path . join ( ASSETS_PATH , \"imgs\" , \"logo.png\" ), } for k in defaults : if k not in context : context [ k ] = defaults [ k ] return pug_to_html ( template , ** context ) def write_pdf_report ( target , assessment ): \"\"\"Write an assessment report with a PDF summary. **Parameters** **target** > Path for PDF file. **assessment** > Assessment instance. \"\"\" # assessment.figure_data = pdf_tools.figure_data(assessment.fig, fmt=\"svg\") html = end_pug_to_html ( REPORT_TEMPLATE , assessment = assessment ,) write_report ( html , target , extra_stylesheets = ( STYLESHEET ,)) Variables ASSETS_PATH REPORT_TEMPLATE STYLESHEET THIS_PATH Functions end_pug_to_html def end_pug_to_html ( template , ** context ) View Source def end_pug_to_html ( template , ** context ) : now = datetime . now (). strftime ( \"%Y-%m-%d\" ) defaults = { \"sidebar_text\" : \"Generated on %s by EGF's Plasmid assessor (version %s)\" % ( now , __version__ ), \"plasma_logo_url\" : os . path . join ( ASSETS_PATH , \"imgs\" , \"logo.png\" ), } for k in defaults : if k not in context : context [ k ] = defaults [ k ] return pug_to_html ( template , ** context ) write_pdf_report def write_pdf_report ( target , assessment ) Write an assessment report with a PDF summary. Parameters target Path for PDF file. assessment Assessment instance. View Source def write_pdf_report ( target , assessment ): \"\"\"Write an assessment report with a PDF summary. **Parameters** **target** > Path for PDF file. **assessment** > Assessment instance. \"\"\" # assessment.figure_data = pdf_tools.figure_data(assessment.fig, fmt=\"svg\") html = end_pug_to_html ( REPORT_TEMPLATE , assessment = assessment ,) write_report ( html , target , extra_stylesheets = ( STYLESHEET ,))","title":"Reports"},{"location":"reference/plasmid_assessor/reports/#module-plasmid_assessorreports","text":"View Source from datetime import datetime import os import matplotlib.pyplot as plt import pandas from pdf_reports import ( add_css_class , dataframe_to_html , pug_to_html , style_table_rows , write_report , ) import pdf_reports.tools as pdf_tools from .version import __version__ THIS_PATH = os . path . dirname ( os . path . realpath ( __file__ )) ASSETS_PATH = os . path . join ( THIS_PATH , \"report_assets\" ) REPORT_TEMPLATE = os . path . join ( ASSETS_PATH , \"assessment_report.pug\" ) STYLESHEET = os . path . join ( ASSETS_PATH , \"report_style.css\" ) def end_pug_to_html ( template , ** context ): now = datetime . now () . strftime ( \"%Y-%m- %d \" ) defaults = { \"sidebar_text\" : \"Generated on %s by EGF's Plasmid assessor (version %s )\" % ( now , __version__ ), \"plasma_logo_url\" : os . path . join ( ASSETS_PATH , \"imgs\" , \"logo.png\" ), } for k in defaults : if k not in context : context [ k ] = defaults [ k ] return pug_to_html ( template , ** context ) def write_pdf_report ( target , assessment ): \"\"\"Write an assessment report with a PDF summary. **Parameters** **target** > Path for PDF file. **assessment** > Assessment instance. \"\"\" # assessment.figure_data = pdf_tools.figure_data(assessment.fig, fmt=\"svg\") html = end_pug_to_html ( REPORT_TEMPLATE , assessment = assessment ,) write_report ( html , target , extra_stylesheets = ( STYLESHEET ,))","title":"Module plasmid_assessor.reports"},{"location":"reference/plasmid_assessor/reports/#variables","text":"ASSETS_PATH REPORT_TEMPLATE STYLESHEET THIS_PATH","title":"Variables"},{"location":"reference/plasmid_assessor/reports/#functions","text":"","title":"Functions"},{"location":"reference/plasmid_assessor/reports/#end_pug_to_html","text":"def end_pug_to_html ( template , ** context ) View Source def end_pug_to_html ( template , ** context ) : now = datetime . now (). strftime ( \"%Y-%m-%d\" ) defaults = { \"sidebar_text\" : \"Generated on %s by EGF's Plasmid assessor (version %s)\" % ( now , __version__ ), \"plasma_logo_url\" : os . path . join ( ASSETS_PATH , \"imgs\" , \"logo.png\" ), } for k in defaults : if k not in context : context [ k ] = defaults [ k ] return pug_to_html ( template , ** context )","title":"end_pug_to_html"},{"location":"reference/plasmid_assessor/reports/#write_pdf_report","text":"def write_pdf_report ( target , assessment ) Write an assessment report with a PDF summary. Parameters target Path for PDF file. assessment Assessment instance. View Source def write_pdf_report ( target , assessment ): \"\"\"Write an assessment report with a PDF summary. **Parameters** **target** > Path for PDF file. **assessment** > Assessment instance. \"\"\" # assessment.figure_data = pdf_tools.figure_data(assessment.fig, fmt=\"svg\") html = end_pug_to_html ( REPORT_TEMPLATE , assessment = assessment ,) write_report ( html , target , extra_stylesheets = ( STYLESHEET ,))","title":"write_pdf_report"},{"location":"reference/plasmid_assessor/version/","text":"Module plasmid_assessor.version View Source __version__ = \"0.1.0\"","title":"Version"},{"location":"reference/plasmid_assessor/version/#module-plasmid_assessorversion","text":"View Source __version__ = \"0.1.0\"","title":"Module plasmid_assessor.version"}]}
\ No newline at end of file
+{"config":{"lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Plasmid assessor Plasmid assessment for Golden Gate cloning. An important task in DNA assembly is creating or adapting a plasmid to serve as a backbone for the assembled parts. This package provides tools for quickly checking a few basic backbone requirements on a plasmid sequence. The most important steps of vector (backbone) adaptation are ensuring that there are: two sites for the chosen restriction enzyme, flanking the insert segment no other sites for the restriction enzyme The choice of the two backbone overhangs are also important, because they will be involved in all assemblies using that plasmid. Additionally, we can add selection for proper assembly (for example, by including a ccdB suicide cassette at the insertion location) and for presence of plasmid in the bacterium (for example, by using antibiotic resistance). Finally, we can check that the replicon and the partitioning system in the plasmid suits the strain, compatibility and other requirements. Install pip install plasmid_assessor # pip install plasmid_assessor [ report ] # install with dependencies for pdf reports Usage import plasmid_assessor as plasma # Load your Genbank or FASTA file as a Biopython SeqRecord, or create a new one: from Bio import SeqIO sequence = SeqIO . read ( \"HC_Amp_ccdB.gb\" , \"genbank\" ) # sequence.annotations[\"topology\"] = \"circular\" # make sure it's circular # sequence.id = \"HC_Amp_ccdB\" # can specify a name for the plasmid # Evaluate plasmid: design = plasma . Assessment ( sequence , \"BsmBI\" ) design . assess_plasmid ( other_enzymes = [ \"BsaI\" ]) # also check for the enzyme(s) of the 2nd (3rd..) level assembly # Results are stored in: design . results # Save as a PDF report: plasma . write_pdf_report ( \"report.pdf\" , design ) Plasmid assessor checks the properties listed in the introduction and if the plamid passes, then it gets a green \u2611 symbol; if there are errors, it's flagged with a red \u2612 symbol. Warning comments are marked with a yellow \u26a0 sign. Versioning Plasmid assessor uses the semantic versioning scheme. License = MIT Plasmid assessor is free/libre and open-source software, which means the users have the freedom to run, study, change and distribute the software. Plasmid assessor was written at the Edinburgh Genome Foundry by Peter Vegh . Copyright 2021 Edinburgh Genome Foundry, University of Edinburgh","title":"Home"},{"location":"#plasmid-assessor","text":"Plasmid assessment for Golden Gate cloning. An important task in DNA assembly is creating or adapting a plasmid to serve as a backbone for the assembled parts. This package provides tools for quickly checking a few basic backbone requirements on a plasmid sequence. The most important steps of vector (backbone) adaptation are ensuring that there are: two sites for the chosen restriction enzyme, flanking the insert segment no other sites for the restriction enzyme The choice of the two backbone overhangs are also important, because they will be involved in all assemblies using that plasmid. Additionally, we can add selection for proper assembly (for example, by including a ccdB suicide cassette at the insertion location) and for presence of plasmid in the bacterium (for example, by using antibiotic resistance). Finally, we can check that the replicon and the partitioning system in the plasmid suits the strain, compatibility and other requirements.","title":"Plasmid assessor"},{"location":"#install","text":"pip install plasmid_assessor # pip install plasmid_assessor [ report ] # install with dependencies for pdf reports","title":"Install"},{"location":"#usage","text":"import plasmid_assessor as plasma # Load your Genbank or FASTA file as a Biopython SeqRecord, or create a new one: from Bio import SeqIO sequence = SeqIO . read ( \"HC_Amp_ccdB.gb\" , \"genbank\" ) # sequence.annotations[\"topology\"] = \"circular\" # make sure it's circular # sequence.id = \"HC_Amp_ccdB\" # can specify a name for the plasmid # Evaluate plasmid: design = plasma . Assessment ( sequence , \"BsmBI\" ) design . assess_plasmid ( other_enzymes = [ \"BsaI\" ]) # also check for the enzyme(s) of the 2nd (3rd..) level assembly # Results are stored in: design . results # Save as a PDF report: plasma . write_pdf_report ( \"report.pdf\" , design ) Plasmid assessor checks the properties listed in the introduction and if the plamid passes, then it gets a green \u2611 symbol; if there are errors, it's flagged with a red \u2612 symbol. Warning comments are marked with a yellow \u26a0 sign.","title":"Usage"},{"location":"#versioning","text":"Plasmid assessor uses the semantic versioning scheme.","title":"Versioning"},{"location":"#license-mit","text":"Plasmid assessor is free/libre and open-source software, which means the users have the freedom to run, study, change and distribute the software. Plasmid assessor was written at the Edinburgh Genome Foundry by Peter Vegh . Copyright 2021 Edinburgh Genome Foundry, University of Edinburgh","title":"License = MIT"},{"location":"reference/plasmid_assessor/","text":"Module plasmid_assessor View Source from .Assessment import Assessment from .reports import write_pdf_report Sub-modules plasmid_assessor.Assessment plasmid_assessor.reports plasmid_assessor.version","title":"Index"},{"location":"reference/plasmid_assessor/#module-plasmid_assessor","text":"View Source from .Assessment import Assessment from .reports import write_pdf_report","title":"Module plasmid_assessor"},{"location":"reference/plasmid_assessor/#sub-modules","text":"plasmid_assessor.Assessment plasmid_assessor.reports plasmid_assessor.version","title":"Sub-modules"},{"location":"reference/plasmid_assessor/Assessment/","text":"Module plasmid_assessor.Assessment View Source import re import matplotlib.pyplot as plt import Bio import Bio.Restriction from Bio.Seq import Seq from Bio.SeqFeature import SeqFeature , FeatureLocation import dnacauldron as dc try : from dna_features_viewer import BiopythonTranslator except ImportError : class AssessmentTranslator : \"\"\"Please install dna_features_viewer to use this class.\"\"\" def __init__ ( self ): raise Exception ( \"Please install dna_features_viewer to use this class.\" ) else : class AssessmentTranslator ( BiopythonTranslator ): \"\"\"Custom translator for highlighting key features.\"\"\" def compute_feature_color ( self , feature ): assessment_ref = \"plasmid_assessment\" if assessment_ref in feature . qualifiers : if feature . qualifiers [ assessment_ref ] == \"enzyme\" : return \"red\" elif feature . qualifiers [ assessment_ref ] == \"excised\" : return \"yellow\" elif feature . qualifiers [ assessment_ref ] == \"backbone\" : return \"tab:cyan\" else : return \"tab:blue\" # default dna_features_viewer color else : return \"tab:blue\" class Assessment : \"\"\"The plasmid assessment class. **Parameters** **record** > A Biopython `SeqRecord`. **enzyme** > A restriction enzyme (`str`). A Biopython `RestrictionType` will be looked up using the string. \"\"\" UNKNOWN_IDS = [ \"None\" , \"\" , \"\" , \".\" , \"EXPORTED\" , \"\" , \"Exported\" , ] def __init__ ( self , record , enzyme ): self . record = record self . enzyme = Bio . Restriction . __dict__ [ enzyme ] self . enzyme_name = str ( self . enzyme ) self . results = {} def assess_plasmid ( self , other_enzymes = None ): \"\"\"Evaluate plasmid for Golden Gate. **Parameters** **other_enzymes** > List of enzymes used in higher level assemblies (`list`). \"\"\" if other_enzymes : self . other_enzymes = \", \" . join ([ str ( enz ) for enz in other_enzymes ]) self . add_name () self . check_circularity () self . get_number_of_sites () self . evaluate_orientation () self . digest_plasmid () self . count_other_sites ( other_enzymes ) self . check_enzyme_site_locations () self . sum_results () self . plot_plasmid () def add_name ( self ): \"\"\"Set a name for the assessment.\"\"\" # To display on the report: if str ( self . record . id ) . strip () in self . UNKNOWN_IDS : self . name = \"Unnamed plasmid\" else : if len ( self . record . id ) > 16 : # Genbank limit, also for width in report self . name = self . record . id [: 16 ] + \"...\" else : self . name = self . record . id def check_circularity ( self ): if \"topology\" not in self . record . annotations : self . results [ \"is_circular\" ] = False elif self . record . annotations [ \"topology\" ] == \"circular\" : self . results [ \"is_circular\" ] = True else : self . results [ \"is_circular\" ] = False def get_number_of_sites ( self ): if \"is_circular\" in self . results : is_linear = not self . results [ \"is_circular\" ] else : is_linear = False restriction_batch = Bio . Restriction . RestrictionBatch ([ self . enzyme ]) analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = is_linear ) self . analysis_results = analysis . full ( linear = is_linear ) self . results [ \"number_of_sites\" ] = len ( self . analysis_results [ self . enzyme ]) # Add as features for plot in report: for enzyme , sites in self . analysis_results . items (): for site in sites : self . record . features . append ( SeqFeature ( FeatureLocation ( site , site + 1 ), id = str ( enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : str ( enzyme ), \"plasmid_assessment\" : \"enzyme\" , }, ) ) def evaluate_orientation ( self ): self . results [ \"is_site_orientation_correct\" ] = False # default # Forward strand: self . iter_forward = [ match . end () for match in re . finditer ( self . enzyme . site , str ( self . record . seq )) ] if sum ( 1 for _ in self . iter_forward ) == 1 : self . forward_enzyme = self . iter_forward [ 0 ] # rev_complement_site = str(self.record.seq.reverse_complement()) rev_complement_site = str ( Seq ( self . enzyme . site ) . reverse_complement ()) self . iter_reverse = [ m . start () for m in re . finditer ( rev_complement_site , str ( self . record . seq )) ] if sum ( 1 for _ in self . iter_reverse ) == 1 : # 1 site in both strands: self . results [ \"is_site_orientation_correct\" ] = True self . reverse_enzyme = self . iter_reverse [ 0 ] if self . results [ \"is_site_orientation_correct\" ]: if self . reverse_enzyme < self . forward_enzyme : self . record . features . append ( SeqFeature ( FeatureLocation ( self . reverse_enzyme - 1 , self . forward_enzyme + 1 ), id = str ( self . enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : \"Excised\" , \"plasmid_assessment\" : \"excised\" , }, ) ) else : # put annotation together from two pieces: self . record . features . append ( SeqFeature ( FeatureLocation ( 0 , self . forward_enzyme + 1 ), id = str ( self . enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : \"Excised\" , \"plasmid_assessment\" : \"excised\" , }, ) ) self . record . features . append ( SeqFeature ( FeatureLocation ( self . reverse_enzyme - 1 , len ( self . record )), id = str ( self . enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : \"Excised\" , \"plasmid_assessment\" : \"excised\" , }, ) ) def digest_plasmid ( self ): # Obtain fragments and get the backbone's overhangs. # This method has two assumptions: # - the sequence has two, correctly oriented enzyme sites. # - the sequence is circular. # Therefore there will be exactly two fragments, with one containing both sites. self . results [ \"digest\" ] = {} if not self . results [ \"is_circular\" ]: return if not self . results [ \"is_site_orientation_correct\" ]: return record_fragments = dc . StickyEndFragment . list_from_record_digestion ( record = self . record , enzyme = self . enzyme , linear = False ) if self . enzyme . site in record_fragments [ 0 ] . to_standard_string (): backbone_index = 1 # there are only two fragments excise_index = 0 else : backbone_index = 0 excise_index = 1 # reversed self . results [ \"digest\" ][ \"backbone_seq\" ] = record_fragments [ backbone_index ] self . results [ \"digest\" ][ \"excised_seq\" ] = record_fragments [ excise_index ] self . results [ \"digest\" ][ \"first_overhang\" ] = str ( record_fragments [ excise_index ] . seq . left_end ) self . results [ \"digest\" ][ \"last_overhang\" ] = str ( record_fragments [ excise_index ] . seq . right_end ) def count_other_sites ( self , other_enzymes ): self . results [ \"other_sites\" ] = {} self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = False if other_enzymes is None : return bio_enzymes = [ Bio . Restriction . __dict__ [ enzyme ] for enzyme in other_enzymes ] restriction_batch = Bio . Restriction . RestrictionBatch ( bio_enzymes ) # Work with the assumption that the sequence is circular: analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = False ) self . results [ \"other_sites\" ][ \"enzyme\" ] = analysis . full ( linear = False ) for enzyme , matches in self . results [ \"other_sites\" ][ \"enzyme\" ] . items (): if len ( matches ) != 0 : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = True # Also add as features for plot in report: for site in matches : self . record . features . append ( SeqFeature ( FeatureLocation ( site , site + 1 ), id = str ( enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : str ( enzyme ), \"plasmid_assessment\" : \"enzyme\" , }, ) ) def check_enzyme_site_locations ( self ): \"\"\"Flag enzyme sites that are within the retained backbone.\"\"\" try : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] self . results [ \"is_site_orientation_correct\" ] except KeyError : print ( \"Run assessment methods first!\" ) else : self . sites_outside_excised_region = {} if ( self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] and self . results [ \"is_site_orientation_correct\" ] ): # if there are no other sites, no need to run: if self . reverse_enzyme < self . forward_enzyme : # orientation = reverse -> forward for enzyme , sites in self . results [ \"other_sites\" ][ \"enzyme\" ] . items (): problem_sites = [] for site in sites : if self . reverse_enzyme < site < self . forward_enzyme : pass else : problem_sites += [ str ( site )] if problem_sites != []: self . sites_outside_excised_region [ str ( enzyme ) ] = problem_sites txt = \"\" # for the pdf report for ( enzyme , problem_sites , ) in self . sites_outside_excised_region . items (): txt += enzyme + \": \" + \" \" . join ( problem_sites ) + \";\" self . sites_outside_excised_region_txt = txt else : # orientation = forward -> reverse for enzyme , sites in self . results [ \"other_sites\" ][ \"enzyme\" ] . items (): problem_sites = [] for site in sites : if self . forward_enzyme < site < self . reverse_enzyme : # in this case the site is within the retained backbone problem_sites += [ str ( site )] if problem_sites != []: self . sites_outside_excised_region [ str ( enzyme ) ] = problem_sites txt = \"\" # for the pdf report for ( enzyme , problem_sites , ) in self . sites_outside_excised_region . items (): txt += enzyme + \": \" + \" \" . join ( problem_sites ) + \";\" self . sites_outside_excised_region_txt = txt else : # no other sites or orientation not correct self . sites_outside_excised_region_txt = \"\" def sum_results ( self ): self . results [ \"pass\" ] = True if self . results [ \"is_circular\" ] is False : self . results [ \"pass\" ] = False return if self . results [ \"is_site_orientation_correct\" ] is False : # implicitly checks number of sites too self . results [ \"pass\" ] = False return if self . sites_outside_excised_region_txt : self . results [ \"pass\" ] = False return # if self.results[\"other_sites\"][\"has_any_other_sites\"]: # self.results[\"pass\"] = False # return def plot_plasmid ( self ): \"\"\"Plot an outline of the plasmid.\"\"\" fig , ax = plt . subplots ( figsize = ( 7 , 4 )) graphic_record = AssessmentTranslator () . translate_record ( self . record ) graphic_record . plot ( ax = ax , with_ruler = False , strand_in_label_threshold = 2 ) self . fig = fig Classes Assessment class Assessment ( record , enzyme ) The plasmid assessment class. Parameters record A Biopython SeqRecord . enzyme A restriction enzyme ( str ). A Biopython RestrictionType will be looked up using the string. View Source class Assessment : \"\"\"The plasmid assessment class. **Parameters** **record** > A Biopython `SeqRecord`. **enzyme** > A restriction enzyme (`str`). A Biopython `RestrictionType` will be looked up using the string. \"\"\" UNKNOWN_IDS = [ \"None\", \"\", \"\", \".\", \"EXPORTED\", \"\", \"Exported\", ] def __init__ ( self , record , enzyme ) : self . record = record self . enzyme = Bio . Restriction . __dict__ [ enzyme ] self . enzyme_name = str ( self . enzyme ) self . results = {} def assess_plasmid ( self , other_enzymes = None ) : \"\"\"Evaluate plasmid for Golden Gate. **Parameters** **other_enzymes** > List of enzymes used in higher level assemblies (`list`). \"\"\" if other_enzymes : self . other_enzymes = \", \" . join ( [ str(enz) for enz in other_enzymes ] ) self . add_name () self . check_circularity () self . get_number_of_sites () self . evaluate_orientation () self . digest_plasmid () self . count_other_sites ( other_enzymes ) self . check_enzyme_site_locations () self . sum_results () self . plot_plasmid () def add_name ( self ) : \"\"\"Set a name for the assessment.\"\"\" # To display on the report : if str ( self . record . id ). strip () in self . UNKNOWN_IDS : self . name = \"Unnamed plasmid\" else : if len ( self . record . id ) > 16 : # Genbank limit , also for width in report self . name = self . record . id [ :16 ] + \"...\" else : self . name = self . record . id def check_circularity ( self ) : if \"topology\" not in self . record . annotations : self . results [ \"is_circular\" ] = False elif self . record . annotations [ \"topology\" ] == \"circular\" : self . results [ \"is_circular\" ] = True else : self . results [ \"is_circular\" ] = False def get_number_of_sites ( self ) : if \"is_circular\" in self . results : is_linear = not self . results [ \"is_circular\" ] else : is_linear = False restriction_batch = Bio . Restriction . RestrictionBatch ( [ self.enzyme ] ) analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = is_linear ) self . analysis_results = analysis . full ( linear = is_linear ) self . results [ \"number_of_sites\" ] = len ( self . analysis_results [ self.enzyme ] ) # Add as features for plot in report : for enzyme , sites in self . analysis_results . items () : for site in sites : self . record . features . append ( SeqFeature ( FeatureLocation ( site , site + 1 ), id = str ( enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : str ( enzyme ), \"plasmid_assessment\" : \"enzyme\" , } , ) ) def evaluate_orientation ( self ) : self . results [ \"is_site_orientation_correct\" ] = False # default # Forward strand : self . iter_forward = [ match.end() for match in re.finditer(self.enzyme.site, str(self.record.seq)) ] if sum ( 1 for _ in self . iter_forward ) == 1 : self . forward_enzyme = self . iter_forward [ 0 ] # rev_complement_site = str ( self . record . seq . reverse_complement ()) rev_complement_site = str ( Seq ( self . enzyme . site ). reverse_complement ()) self . iter_reverse = [ m.start() for m in re.finditer(rev_complement_site, str(self.record.seq)) ] if sum ( 1 for _ in self . iter_reverse ) == 1 : # 1 site in both strands : self . results [ \"is_site_orientation_correct\" ] = True self . reverse_enzyme = self . iter_reverse [ 0 ] if self . results [ \"is_site_orientation_correct\" ] : if self . reverse_enzyme < self . forward_enzyme : self . record . features . append ( SeqFeature ( FeatureLocation ( self . reverse_enzyme - 1 , self . forward_enzyme + 1 ), id = str ( self . enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : \"Excised\" , \"plasmid_assessment\" : \"excised\" , } , ) ) else : # put annotation together from two pieces : self . record . features . append ( SeqFeature ( FeatureLocation ( 0 , self . forward_enzyme + 1 ), id = str ( self . enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : \"Excised\" , \"plasmid_assessment\" : \"excised\" , } , ) ) self . record . features . append ( SeqFeature ( FeatureLocation ( self . reverse_enzyme - 1 , len ( self . record )), id = str ( self . enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : \"Excised\" , \"plasmid_assessment\" : \"excised\" , } , ) ) def digest_plasmid ( self ) : # Obtain fragments and get the backbone ' s overhangs . # This method has two assumptions : # - the sequence has two , correctly oriented enzyme sites . # - the sequence is circular . # Therefore there will be exactly two fragments , with one containing both sites . self . results [ \"digest\" ] = {} if not self . results [ \"is_circular\" ] : return if not self . results [ \"is_site_orientation_correct\" ] : return record_fragments = dc . StickyEndFragment . list_from_record_digestion ( record = self . record , enzyme = self . enzyme , linear = False ) if self . enzyme . site in record_fragments [ 0 ] . to_standard_string () : backbone_index = 1 # there are only two fragments excise_index = 0 else : backbone_index = 0 excise_index = 1 # reversed self . results [ \"digest\" ][ \"backbone_seq\" ] = record_fragments [ backbone_index ] self . results [ \"digest\" ][ \"excised_seq\" ] = record_fragments [ excise_index ] self . results [ \"digest\" ][ \"first_overhang\" ] = str ( record_fragments [ excise_index ] . seq . left_end ) self . results [ \"digest\" ][ \"last_overhang\" ] = str ( record_fragments [ excise_index ] . seq . right_end ) def count_other_sites ( self , other_enzymes ) : self . results [ \"other_sites\" ] = {} self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = False if other_enzymes is None : return bio_enzymes = [ Bio.Restriction.__dict__[enzyme ] for enzyme in other_enzymes ] restriction_batch = Bio . Restriction . RestrictionBatch ( bio_enzymes ) # Work with the assumption that the sequence is circular : analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = False ) self . results [ \"other_sites\" ][ \"enzyme\" ] = analysis . full ( linear = False ) for enzyme , matches in self . results [ \"other_sites\" ][ \"enzyme\" ] . items () : if len ( matches ) != 0 : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = True # Also add as features for plot in report : for site in matches : self . record . features . append ( SeqFeature ( FeatureLocation ( site , site + 1 ), id = str ( enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : str ( enzyme ), \"plasmid_assessment\" : \"enzyme\" , } , ) ) def check_enzyme_site_locations ( self ) : \"\"\"Flag enzyme sites that are within the retained backbone.\"\"\" try : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] self . results [ \"is_site_orientation_correct\" ] except KeyError : print ( \"Run assessment methods first!\" ) else : self . sites_outside_excised_region = {} if ( self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] and self . results [ \"is_site_orientation_correct\" ] ) : # if there are no other sites , no need to run : if self . reverse_enzyme < self . forward_enzyme : # orientation = reverse -> forward for enzyme , sites in self . results [ \"other_sites\" ][ \"enzyme\" ] . items () : problem_sites = [] for site in sites : if self . reverse_enzyme < site < self . forward_enzyme : pass else : problem_sites += [ str(site) ] if problem_sites != []: self . sites_outside_excised_region [ str(enzyme) ] = problem_sites txt = \"\" # for the pdf report for ( enzyme , problem_sites , ) in self . sites_outside_excised_region . items () : txt += enzyme + \": \" + \" \" . join ( problem_sites ) + \";\" self . sites_outside_excised_region_txt = txt else : # orientation = forward -> reverse for enzyme , sites in self . results [ \"other_sites\" ][ \"enzyme\" ] . items () : problem_sites = [] for site in sites : if self . forward_enzyme < site < self . reverse_enzyme : # in this case the site is within the retained backbone problem_sites += [ str(site) ] if problem_sites != []: self . sites_outside_excised_region [ str(enzyme) ] = problem_sites txt = \"\" # for the pdf report for ( enzyme , problem_sites , ) in self . sites_outside_excised_region . items () : txt += enzyme + \": \" + \" \" . join ( problem_sites ) + \";\" self . sites_outside_excised_region_txt = txt else : # no other sites or orientation not correct self . sites_outside_excised_region_txt = \"\" def sum_results ( self ) : self . results [ \"pass\" ] = True if self . results [ \"is_circular\" ] is False : self . results [ \"pass\" ] = False return if self . results [ \"is_site_orientation_correct\" ] is False : # implicitly checks number of sites too self . results [ \"pass\" ] = False return if self . sites_outside_excised_region_txt : self . results [ \"pass\" ] = False return # if self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] : # self . results [ \"pass\" ] = False # return def plot_plasmid ( self ) : \"\"\"Plot an outline of the plasmid.\"\"\" fig , ax = plt . subplots ( figsize = ( 7 , 4 )) graphic_record = AssessmentTranslator (). translate_record ( self . record ) graphic_record . plot ( ax = ax , with_ruler = False , strand_in_label_threshold = 2 ) self . fig = fig Class variables UNKNOWN_IDS Methods add_name def add_name ( self ) Set a name for the assessment. View Source def add_name ( self ) : \"\"\" Set a name for the assessment. \"\"\" # To display on the report : if str ( self . record . id ) . strip () in self . UNKNOWN_IDS : self . name = \" Unnamed plasmid \" else : if len ( self . record . id ) > 16 : # Genbank limit , also for width in report self . name = self . record . id [: 16 ] + \" ... \" else : self . name = self . record . id assess_plasmid def assess_plasmid ( self , other_enzymes = None ) Evaluate plasmid for Golden Gate. Parameters other_enzymes List of enzymes used in higher level assemblies ( list ). View Source def assess_plasmid ( self , other_enzymes = None ) : \" \"\" Evaluate plasmid for Golden Gate. **Parameters** **other_enzymes** > List of enzymes used in higher level assemblies (`list`). \"\" \" if other_enzymes : self . other_enzymes = \", \" . join ( [ str ( enz ) for enz in other_enzymes ] ) self . add_name () self . check_circularity () self . get_number_of_sites () self . evaluate_orientation () self . digest_plasmid () self . count_other_sites ( other_enzymes ) self . check_enzyme_site_locations () self . sum_results () self . plot_plasmid () check_circularity def check_circularity ( self ) View Source def check_circularity ( self ) : if \" topology \" not in self . record . annotations : self . results [ \" is_circular \" ] = False elif self . record . annotations [ \" topology \" ] == \" circular \" : self . results [ \" is_circular \" ] = True else : self . results [ \" is_circular \" ] = False check_enzyme_site_locations def check_enzyme_site_locations ( self ) Flag enzyme sites that are within the retained backbone. View Source def check_enzyme_site_locations ( self ) : \"\"\"Flag enzyme sites that are within the retained backbone.\"\"\" try: self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] self . results [ \"is_site_orientation_correct\" ] except KeyError: print ( \"Run assessment methods first!\" ) else : self . sites_outside_excised_region = {} if ( self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] and self . results [ \"is_site_orientation_correct\" ] ) : # if there are no other sites , no need to run: if self . reverse_enzyme < self . forward_enzyme: # orientation = reverse -> forward for enzyme , sites in self . results [ \"other_sites\" ][ \"enzyme\" ]. items () : problem_sites = [] for site in sites: if self . reverse_enzyme < site < self . forward_enzyme: pass else : problem_sites += [ str ( site )] if problem_sites != [] : self . sites_outside_excised_region [ str ( enzyme ) ] = problem_sites txt = \"\" # for the pdf report for ( enzyme , problem_sites , ) in self . sites_outside_excised_region . items () : txt += enzyme + \": \" + \" \" . join ( problem_sites ) + \";\" self . sites_outside_excised_region_txt = txt else : # orientation = forward -> reverse for enzyme , sites in self . results [ \"other_sites\" ][ \"enzyme\" ]. items () : problem_sites = [] for site in sites: if self . forward_enzyme < site < self . reverse_enzyme: # in this case the site is within the retained backbone problem_sites += [ str ( site )] if problem_sites != [] : self . sites_outside_excised_region [ str ( enzyme ) ] = problem_sites txt = \"\" # for the pdf report for ( enzyme , problem_sites , ) in self . sites_outside_excised_region . items () : txt += enzyme + \": \" + \" \" . join ( problem_sites ) + \";\" self . sites_outside_excised_region_txt = txt else : # no other sites or orientation not correct self . sites_outside_excised_region_txt = \"\" count_other_sites def count_other_sites ( self , other_enzymes ) View Source def count_other_sites ( self , other_enzymes ) : self . results [ \"other_sites\" ] = {} self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = False if other_enzymes is None : return bio_enzymes = [ Bio.Restriction.__dict__[enzyme ] for enzyme in other_enzymes ] restriction_batch = Bio . Restriction . RestrictionBatch ( bio_enzymes ) # Work with the assumption that the sequence is circular : analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = False ) self . results [ \"other_sites\" ][ \"enzyme\" ] = analysis . full ( linear = False ) for enzyme , matches in self . results [ \"other_sites\" ][ \"enzyme\" ] . items () : if len ( matches ) != 0 : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = True # Also add as features for plot in report : for site in matches : self . record . features . append ( SeqFeature ( FeatureLocation ( site , site + 1 ), id = str ( enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : str ( enzyme ), \"plasmid_assessment\" : \"enzyme\" , } , ) ) digest_plasmid def digest_plasmid ( self ) View Source def digest_plasmid ( self ) : # Obtain fragments and get the backbone ' s overhangs . # This method has two assumptions : # - the sequence has two , correctly oriented enzyme sites . # - the sequence is circular . # Therefore there will be exactly two fragments , with one containing both sites . self . results [ \"digest\" ] = {} if not self . results [ \"is_circular\" ] : return if not self . results [ \"is_site_orientation_correct\" ] : return record_fragments = dc . StickyEndFragment . list_from_record_digestion ( record = self . record , enzyme = self . enzyme , linear = False ) if self . enzyme . site in record_fragments [ 0 ] . to_standard_string () : backbone_index = 1 # there are only two fragments excise_index = 0 else : backbone_index = 0 excise_index = 1 # reversed self . results [ \"digest\" ][ \"backbone_seq\" ] = record_fragments [ backbone_index ] self . results [ \"digest\" ][ \"excised_seq\" ] = record_fragments [ excise_index ] self . results [ \"digest\" ][ \"first_overhang\" ] = str ( record_fragments [ excise_index ] . seq . left_end ) self . results [ \"digest\" ][ \"last_overhang\" ] = str ( record_fragments [ excise_index ] . seq . right_end ) evaluate_orientation def evaluate_orientation ( self ) View Source def evaluate_orientation ( self ) : self . results [ \" is_site_orientation_correct \" ] = False # default # Forward strand : self . iter_forward = [ match . end () for match in re . finditer ( self . enzyme . site , str ( self . record . seq )) ] if sum ( 1 for _ in self . iter_forward ) == 1 : self . forward_enzyme = self . iter_forward [ 0 ] # rev_complement_site = str ( self . record . seq . reverse_complement ()) rev_complement_site = str ( Seq ( self . enzyme . site ) . reverse_complement ()) self . iter_reverse = [ m . start () for m in re . finditer ( rev_complement_site , str ( self . record . seq )) ] if sum ( 1 for _ in self . iter_reverse ) == 1 : # 1 site in both strands : self . results [ \" is_site_orientation_correct \" ] = True self . reverse_enzyme = self . iter_reverse [ 0 ] if self . results [ \" is_site_orientation_correct \" ]: if self . reverse_enzyme < self . forward_enzyme : self . record . features . append ( SeqFeature ( FeatureLocation ( self . reverse_enzyme - 1 , self . forward_enzyme + 1 ) , id = str ( self . enzyme ) , type = \" misc_feature \" , qualifiers = { \" label \" : \" Excised \" , \" plasmid_assessment \" : \" excised \" , }, ) ) else : # put annotation together from two pieces : self . record . features . append ( SeqFeature ( FeatureLocation ( 0 , self . forward_enzyme + 1 ) , id = str ( self . enzyme ) , type = \" misc_feature \" , qualifiers = { \" label \" : \" Excised \" , \" plasmid_assessment \" : \" excised \" , }, ) ) self . record . features . append ( SeqFeature ( FeatureLocation ( self . reverse_enzyme - 1 , len ( self . record )) , id = str ( self . enzyme ) , type = \" misc_feature \" , qualifiers = { \" label \" : \" Excised \" , \" plasmid_assessment \" : \" excised \" , }, ) ) get_number_of_sites def get_number_of_sites ( self ) View Source def get_number_of_sites ( self ) : if \" is_circular \" in self . results : is_linear = not self . results [ \" is_circular \" ] else : is_linear = False restriction_batch = Bio . Restriction . RestrictionBatch ( [ self . enzyme ] ) analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = is_linear ) self . analysis_results = analysis . full ( linear = is_linear ) self . results [ \" number_of_sites \" ] = len ( self . analysis_results [ self . enzyme ] ) # Add as features for plot in report : for enzyme , sites in self . analysis_results . items () : for site in sites : self . record . features . append ( SeqFeature ( FeatureLocation ( site , site + 1 ) , id = str ( enzyme ) , type = \" misc_feature \" , qualifiers = { \" label \" : str ( enzyme ) , \" plasmid_assessment \" : \" enzyme \" , }, ) ) plot_plasmid def plot_plasmid ( self ) Plot an outline of the plasmid. View Source def plot_plasmid(self): \"\"\"Plot an outline of the plasmid.\"\"\" fig, ax = plt.subplots(figsize=(7, 4)) graphic_record = AssessmentTranslator().translate_record(self.record) graphic_record.plot(ax=ax, with_ruler=False, strand_in_label_threshold=2) self.fig = fig sum_results def sum_results ( self ) View Source def sum_results ( self ) : self . results [ \"pass\" ] = True if self . results [ \"is_circular\" ] is False: self . results [ \"pass\" ] = False return if self . results [ \"is_site_orientation_correct\" ] is False: # implicitly checks number of sites too self . results [ \"pass\" ] = False return if self . sites_outside_excised_region_txt: self . results [ \"pass\" ] = False return AssessmentTranslator class AssessmentTranslator ( features_filters = (), features_properties = None ) Custom translator for highlighting key features. View Source class AssessmentTranslator: \"\"\"Please install dna_features_viewer to use this class.\"\"\" def __init__ ( self ): raise Exception ( \"Please install dna_features_viewer to use this class.\" ) Ancestors (in MRO) dna_features_viewer.BiopythonTranslator.BiopythonTranslator.BiopythonTranslator dna_features_viewer.BiopythonTranslator.BiopythonTranslatorBase.BiopythonTranslatorBase Class variables default_feature_color graphic_record_parameters ignored_features_types label_fields Static methods quick_class_plot def quick_class_plot ( record , figure_width = 12 , ** kwargs ) Allows super quick and dirty plotting of Biopython records. This is really meant for use in a Jupyter/Ipython notebook with the \"%matplotlib inline\" setting. from dna_features_viewer import BiopythonTranslator BiopythonTranslator.quick_plot(my_record) View Source @classmethod def quick_class_plot ( cls , record , figure_width = 12 , ** kwargs ): \"\"\"Allows super quick and dirty plotting of Biopython records. This is really meant for use in a Jupyter/Ipython notebook with the \"%matplotlib inline\" setting. >>> from dna_features_viewer import BiopythonTranslator >>> BiopythonTranslator.quick_plot(my_record) \"\"\" graphic_record = cls () . translate_record ( record ) ax , _ = graphic_record . plot ( figure_width = figure_width , ** kwargs ) return ax Methods compute_feature_box_color def compute_feature_box_color ( self , feature ) Compute a box_color for this feature. View Source def compute_feature_box_color ( self , feature ) : \"\"\" Compute a box_color for this feature. \"\"\" return \" auto \" compute_feature_box_linewidth def compute_feature_box_linewidth ( self , feature ) Compute a box_linewidth for this feature. View Source def compute_feature_box_linewidth ( self , feature ) : \"\"\" Compute a box_linewidth for this feature. \"\"\" return 0 . 3 compute_feature_color def compute_feature_color ( self , feature ) Compute a color for this feature. If the feature has a color qualifier it will be used. Otherwise, the classe's default_feature_color is used. To change the behaviour, create a subclass of BiopythonTranslator and overwrite this method. View Source def compute_feature_color ( self , feature ) : assessment_ref = \"plasmid_assessment\" if assessment_ref in feature . qualifiers : if feature . qualifiers [ assessment_ref ] == \"enzyme\" : return \"red\" elif feature . qualifiers [ assessment_ref ] == \"excised\" : return \"yellow\" elif feature . qualifiers [ assessment_ref ] == \"backbone\" : return \"tab:cyan\" else : return \"tab:blue\" # default dna_features_viewer color else : return \"tab:blue\" compute_feature_fontdict def compute_feature_fontdict ( self , feature ) Compute a font dict for this feature. View Source def compute_feature_fontdict ( self , feature ) : \"\"\" Compute a font dict for this feature. \"\"\" return None compute_feature_html def compute_feature_html ( self , feature ) Gets the 'label' of the feature. View Source def compute_feature_html ( self , feature ) : \"\"\" Gets the 'label' of the feature. \"\"\" return self . compute_feature_label ( feature ) compute_feature_label def compute_feature_label ( self , feature ) Compute the label of the feature. View Source def compute_feature_label ( self , feature ) : \"\"\"Compute the label of the feature.\"\"\" label = feature . type for key in self . label_fields : if key in feature . qualifiers and len ( feature . qualifiers [ key ] ) : label = feature . qualifiers [ key ] break if isinstance ( label , list ) : label = \"|\" . join ( label ) return label compute_feature_label_link_color def compute_feature_label_link_color ( self , feature ) Compute the color of the line linking the label to its feature. View Source def compute_feature_label_link_color ( self , feature ) : \"\"\" Compute the color of the line linking the label to its feature. \"\"\" return \" black \" compute_feature_legend_text def compute_feature_legend_text ( self , feature ) View Source def compute_feature_legend_text ( self , feature ) : return None compute_feature_linewidth def compute_feature_linewidth ( self , feature ) Compute the edge width of the feature's arrow/rectangle. View Source def compute_feature_linewidth ( self , feature ) : \"\"\" Compute the edge width of the feature's arrow/rectangle. \"\"\" return 1 . 0 compute_filtered_features def compute_filtered_features ( self , features ) Return the list of features minus the ignored ones. By the method keeps any feature whose type is not in ignored_features_types and for which all filter(f) pass. View Source def compute_filtered_features ( self , features ) : \"\"\" Return the list of features minus the ignored ones. By the method keeps any feature whose type is not in ignored_features_types and for which all filter ( f ) pass . \"\"\" return [ f for f in features if all ( [ fl ( f ) for fl in self . features_filters ] ) and f . type not in self . ignored_features_types ] quick_plot def quick_plot ( self , record , figure_width = 12 , ** kwargs ) Allows super quick and dirty plotting of Biopython records. This is really meant for use in a Jupyter/Ipython notebook with the \"%matplotlib inline\" setting. from dna_features_viewer import BiopythonTranslator BiopythonTranslator.quick_plot(my_record) View Source def quick_plot ( self , record , figure_width = 12 , ** kwargs ): \"\"\"Allows super quick and dirty plotting of Biopython records. This is really meant for use in a Jupyter/Ipython notebook with the \"%matplotlib inline\" setting. >>> from dna_features_viewer import BiopythonTranslator >>> BiopythonTranslator.quick_plot(my_record) \"\"\" graphic_record = self . translate_record ( record ) ax , _ = graphic_record . plot ( figure_width = figure_width , ** kwargs ) return ax translate_feature def translate_feature ( self , feature ) Translate a Biopython feature into a Dna Features Viewer feature. View Source def translate_feature ( self , feature ) : \"\"\" Translate a Biopython feature into a Dna Features Viewer feature. \"\"\" properties = dict ( label = self . compute_feature_label ( feature ) , color = self . compute_feature_color ( feature ) , html = self . compute_feature_html ( feature ) , fontdict = self . compute_feature_fontdict ( feature ) , box_linewidth = self . compute_feature_box_linewidth ( feature ) , box_color = self . compute_feature_box_color ( feature ) , linewidth = self . compute_feature_linewidth ( feature ) , label_link_color = self . compute_feature_label_link_color ( feature ) , legend_text = self . compute_feature_legend_text ( feature ) , ) if self . features_properties is not None : other_properties = self . features_properties if hasattr ( other_properties , \" __call__ \" ) : other_properties = other_properties ( feature ) properties . update ( other_properties ) return GraphicFeature ( start = feature . location . start , end = feature . location . end , strand = feature . location . strand , ** properties ) translate_record def translate_record ( self , record , record_class = None , filetype = None ) Create a new GraphicRecord from a BioPython Record object. Parameters record A BioPython Record object or the path to a Genbank or a GFF file. record_class The graphic record class to use, e.g. GraphicRecord (default) or CircularGraphicRecord. Strings 'circular' and 'linear' can also be provided. filetype Used only when a Genbank or a GFF file is provided; one of \"genbank\" or \"gff\" to be used. Default None infers from file extension. View Source def translate_record ( self , record , record_class = None , filetype = None ) : \"\"\"Create a new GraphicRecord from a BioPython Record object. Parameters ---------- record A BioPython Record object or the path to a Genbank or a GFF file. record_class The graphic record class to use, e.g. GraphicRecord (default) or CircularGraphicRecord. Strings 'circular' and 'linear' can also be provided. filetype Used only when a Genbank or a GFF file is provided; one of \" genbank \" or \" gff \" to be used. Default None infers from file extension. \"\"\" classes = { \"linear\" : GraphicRecord , \"circular\" : CircularGraphicRecord , None : GraphicRecord , } if record_class in classes : record_class = classes [ record_class ] if isinstance ( record , str ) or hasattr ( record , \"read\" ) : record = load_record ( record , filetype = filetype ) filtered_features = self . compute_filtered_features ( record . features ) return record_class ( sequence_length = len ( record ), sequence = str ( record . seq ), features =[ self.translate_feature(feature) for feature in filtered_features if feature.location is not None ] , ** self . graphic_record_parameters )","title":"Assessment"},{"location":"reference/plasmid_assessor/Assessment/#module-plasmid_assessorassessment","text":"View Source import re import matplotlib.pyplot as plt import Bio import Bio.Restriction from Bio.Seq import Seq from Bio.SeqFeature import SeqFeature , FeatureLocation import dnacauldron as dc try : from dna_features_viewer import BiopythonTranslator except ImportError : class AssessmentTranslator : \"\"\"Please install dna_features_viewer to use this class.\"\"\" def __init__ ( self ): raise Exception ( \"Please install dna_features_viewer to use this class.\" ) else : class AssessmentTranslator ( BiopythonTranslator ): \"\"\"Custom translator for highlighting key features.\"\"\" def compute_feature_color ( self , feature ): assessment_ref = \"plasmid_assessment\" if assessment_ref in feature . qualifiers : if feature . qualifiers [ assessment_ref ] == \"enzyme\" : return \"red\" elif feature . qualifiers [ assessment_ref ] == \"excised\" : return \"yellow\" elif feature . qualifiers [ assessment_ref ] == \"backbone\" : return \"tab:cyan\" else : return \"tab:blue\" # default dna_features_viewer color else : return \"tab:blue\" class Assessment : \"\"\"The plasmid assessment class. **Parameters** **record** > A Biopython `SeqRecord`. **enzyme** > A restriction enzyme (`str`). A Biopython `RestrictionType` will be looked up using the string. \"\"\" UNKNOWN_IDS = [ \"None\" , \"\" , \"\" , \".\" , \"EXPORTED\" , \"\" , \"Exported\" , ] def __init__ ( self , record , enzyme ): self . record = record self . enzyme = Bio . Restriction . __dict__ [ enzyme ] self . enzyme_name = str ( self . enzyme ) self . results = {} def assess_plasmid ( self , other_enzymes = None ): \"\"\"Evaluate plasmid for Golden Gate. **Parameters** **other_enzymes** > List of enzymes used in higher level assemblies (`list`). \"\"\" if other_enzymes : self . other_enzymes = \", \" . join ([ str ( enz ) for enz in other_enzymes ]) self . add_name () self . check_circularity () self . get_number_of_sites () self . evaluate_orientation () self . digest_plasmid () self . count_other_sites ( other_enzymes ) self . check_enzyme_site_locations () self . sum_results () self . plot_plasmid () def add_name ( self ): \"\"\"Set a name for the assessment.\"\"\" # To display on the report: if str ( self . record . id ) . strip () in self . UNKNOWN_IDS : self . name = \"Unnamed plasmid\" else : if len ( self . record . id ) > 16 : # Genbank limit, also for width in report self . name = self . record . id [: 16 ] + \"...\" else : self . name = self . record . id def check_circularity ( self ): if \"topology\" not in self . record . annotations : self . results [ \"is_circular\" ] = False elif self . record . annotations [ \"topology\" ] == \"circular\" : self . results [ \"is_circular\" ] = True else : self . results [ \"is_circular\" ] = False def get_number_of_sites ( self ): if \"is_circular\" in self . results : is_linear = not self . results [ \"is_circular\" ] else : is_linear = False restriction_batch = Bio . Restriction . RestrictionBatch ([ self . enzyme ]) analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = is_linear ) self . analysis_results = analysis . full ( linear = is_linear ) self . results [ \"number_of_sites\" ] = len ( self . analysis_results [ self . enzyme ]) # Add as features for plot in report: for enzyme , sites in self . analysis_results . items (): for site in sites : self . record . features . append ( SeqFeature ( FeatureLocation ( site , site + 1 ), id = str ( enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : str ( enzyme ), \"plasmid_assessment\" : \"enzyme\" , }, ) ) def evaluate_orientation ( self ): self . results [ \"is_site_orientation_correct\" ] = False # default # Forward strand: self . iter_forward = [ match . end () for match in re . finditer ( self . enzyme . site , str ( self . record . seq )) ] if sum ( 1 for _ in self . iter_forward ) == 1 : self . forward_enzyme = self . iter_forward [ 0 ] # rev_complement_site = str(self.record.seq.reverse_complement()) rev_complement_site = str ( Seq ( self . enzyme . site ) . reverse_complement ()) self . iter_reverse = [ m . start () for m in re . finditer ( rev_complement_site , str ( self . record . seq )) ] if sum ( 1 for _ in self . iter_reverse ) == 1 : # 1 site in both strands: self . results [ \"is_site_orientation_correct\" ] = True self . reverse_enzyme = self . iter_reverse [ 0 ] if self . results [ \"is_site_orientation_correct\" ]: if self . reverse_enzyme < self . forward_enzyme : self . record . features . append ( SeqFeature ( FeatureLocation ( self . reverse_enzyme - 1 , self . forward_enzyme + 1 ), id = str ( self . enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : \"Excised\" , \"plasmid_assessment\" : \"excised\" , }, ) ) else : # put annotation together from two pieces: self . record . features . append ( SeqFeature ( FeatureLocation ( 0 , self . forward_enzyme + 1 ), id = str ( self . enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : \"Excised\" , \"plasmid_assessment\" : \"excised\" , }, ) ) self . record . features . append ( SeqFeature ( FeatureLocation ( self . reverse_enzyme - 1 , len ( self . record )), id = str ( self . enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : \"Excised\" , \"plasmid_assessment\" : \"excised\" , }, ) ) def digest_plasmid ( self ): # Obtain fragments and get the backbone's overhangs. # This method has two assumptions: # - the sequence has two, correctly oriented enzyme sites. # - the sequence is circular. # Therefore there will be exactly two fragments, with one containing both sites. self . results [ \"digest\" ] = {} if not self . results [ \"is_circular\" ]: return if not self . results [ \"is_site_orientation_correct\" ]: return record_fragments = dc . StickyEndFragment . list_from_record_digestion ( record = self . record , enzyme = self . enzyme , linear = False ) if self . enzyme . site in record_fragments [ 0 ] . to_standard_string (): backbone_index = 1 # there are only two fragments excise_index = 0 else : backbone_index = 0 excise_index = 1 # reversed self . results [ \"digest\" ][ \"backbone_seq\" ] = record_fragments [ backbone_index ] self . results [ \"digest\" ][ \"excised_seq\" ] = record_fragments [ excise_index ] self . results [ \"digest\" ][ \"first_overhang\" ] = str ( record_fragments [ excise_index ] . seq . left_end ) self . results [ \"digest\" ][ \"last_overhang\" ] = str ( record_fragments [ excise_index ] . seq . right_end ) def count_other_sites ( self , other_enzymes ): self . results [ \"other_sites\" ] = {} self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = False if other_enzymes is None : return bio_enzymes = [ Bio . Restriction . __dict__ [ enzyme ] for enzyme in other_enzymes ] restriction_batch = Bio . Restriction . RestrictionBatch ( bio_enzymes ) # Work with the assumption that the sequence is circular: analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = False ) self . results [ \"other_sites\" ][ \"enzyme\" ] = analysis . full ( linear = False ) for enzyme , matches in self . results [ \"other_sites\" ][ \"enzyme\" ] . items (): if len ( matches ) != 0 : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = True # Also add as features for plot in report: for site in matches : self . record . features . append ( SeqFeature ( FeatureLocation ( site , site + 1 ), id = str ( enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : str ( enzyme ), \"plasmid_assessment\" : \"enzyme\" , }, ) ) def check_enzyme_site_locations ( self ): \"\"\"Flag enzyme sites that are within the retained backbone.\"\"\" try : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] self . results [ \"is_site_orientation_correct\" ] except KeyError : print ( \"Run assessment methods first!\" ) else : self . sites_outside_excised_region = {} if ( self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] and self . results [ \"is_site_orientation_correct\" ] ): # if there are no other sites, no need to run: if self . reverse_enzyme < self . forward_enzyme : # orientation = reverse -> forward for enzyme , sites in self . results [ \"other_sites\" ][ \"enzyme\" ] . items (): problem_sites = [] for site in sites : if self . reverse_enzyme < site < self . forward_enzyme : pass else : problem_sites += [ str ( site )] if problem_sites != []: self . sites_outside_excised_region [ str ( enzyme ) ] = problem_sites txt = \"\" # for the pdf report for ( enzyme , problem_sites , ) in self . sites_outside_excised_region . items (): txt += enzyme + \": \" + \" \" . join ( problem_sites ) + \";\" self . sites_outside_excised_region_txt = txt else : # orientation = forward -> reverse for enzyme , sites in self . results [ \"other_sites\" ][ \"enzyme\" ] . items (): problem_sites = [] for site in sites : if self . forward_enzyme < site < self . reverse_enzyme : # in this case the site is within the retained backbone problem_sites += [ str ( site )] if problem_sites != []: self . sites_outside_excised_region [ str ( enzyme ) ] = problem_sites txt = \"\" # for the pdf report for ( enzyme , problem_sites , ) in self . sites_outside_excised_region . items (): txt += enzyme + \": \" + \" \" . join ( problem_sites ) + \";\" self . sites_outside_excised_region_txt = txt else : # no other sites or orientation not correct self . sites_outside_excised_region_txt = \"\" def sum_results ( self ): self . results [ \"pass\" ] = True if self . results [ \"is_circular\" ] is False : self . results [ \"pass\" ] = False return if self . results [ \"is_site_orientation_correct\" ] is False : # implicitly checks number of sites too self . results [ \"pass\" ] = False return if self . sites_outside_excised_region_txt : self . results [ \"pass\" ] = False return # if self.results[\"other_sites\"][\"has_any_other_sites\"]: # self.results[\"pass\"] = False # return def plot_plasmid ( self ): \"\"\"Plot an outline of the plasmid.\"\"\" fig , ax = plt . subplots ( figsize = ( 7 , 4 )) graphic_record = AssessmentTranslator () . translate_record ( self . record ) graphic_record . plot ( ax = ax , with_ruler = False , strand_in_label_threshold = 2 ) self . fig = fig","title":"Module plasmid_assessor.Assessment"},{"location":"reference/plasmid_assessor/Assessment/#classes","text":"","title":"Classes"},{"location":"reference/plasmid_assessor/Assessment/#assessment","text":"class Assessment ( record , enzyme ) The plasmid assessment class. Parameters record A Biopython SeqRecord . enzyme A restriction enzyme ( str ). A Biopython RestrictionType will be looked up using the string. View Source class Assessment : \"\"\"The plasmid assessment class. **Parameters** **record** > A Biopython `SeqRecord`. **enzyme** > A restriction enzyme (`str`). A Biopython `RestrictionType` will be looked up using the string. \"\"\" UNKNOWN_IDS = [ \"None\", \"\", \"\", \".\", \"EXPORTED\", \"\", \"Exported\", ] def __init__ ( self , record , enzyme ) : self . record = record self . enzyme = Bio . Restriction . __dict__ [ enzyme ] self . enzyme_name = str ( self . enzyme ) self . results = {} def assess_plasmid ( self , other_enzymes = None ) : \"\"\"Evaluate plasmid for Golden Gate. **Parameters** **other_enzymes** > List of enzymes used in higher level assemblies (`list`). \"\"\" if other_enzymes : self . other_enzymes = \", \" . join ( [ str(enz) for enz in other_enzymes ] ) self . add_name () self . check_circularity () self . get_number_of_sites () self . evaluate_orientation () self . digest_plasmid () self . count_other_sites ( other_enzymes ) self . check_enzyme_site_locations () self . sum_results () self . plot_plasmid () def add_name ( self ) : \"\"\"Set a name for the assessment.\"\"\" # To display on the report : if str ( self . record . id ). strip () in self . UNKNOWN_IDS : self . name = \"Unnamed plasmid\" else : if len ( self . record . id ) > 16 : # Genbank limit , also for width in report self . name = self . record . id [ :16 ] + \"...\" else : self . name = self . record . id def check_circularity ( self ) : if \"topology\" not in self . record . annotations : self . results [ \"is_circular\" ] = False elif self . record . annotations [ \"topology\" ] == \"circular\" : self . results [ \"is_circular\" ] = True else : self . results [ \"is_circular\" ] = False def get_number_of_sites ( self ) : if \"is_circular\" in self . results : is_linear = not self . results [ \"is_circular\" ] else : is_linear = False restriction_batch = Bio . Restriction . RestrictionBatch ( [ self.enzyme ] ) analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = is_linear ) self . analysis_results = analysis . full ( linear = is_linear ) self . results [ \"number_of_sites\" ] = len ( self . analysis_results [ self.enzyme ] ) # Add as features for plot in report : for enzyme , sites in self . analysis_results . items () : for site in sites : self . record . features . append ( SeqFeature ( FeatureLocation ( site , site + 1 ), id = str ( enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : str ( enzyme ), \"plasmid_assessment\" : \"enzyme\" , } , ) ) def evaluate_orientation ( self ) : self . results [ \"is_site_orientation_correct\" ] = False # default # Forward strand : self . iter_forward = [ match.end() for match in re.finditer(self.enzyme.site, str(self.record.seq)) ] if sum ( 1 for _ in self . iter_forward ) == 1 : self . forward_enzyme = self . iter_forward [ 0 ] # rev_complement_site = str ( self . record . seq . reverse_complement ()) rev_complement_site = str ( Seq ( self . enzyme . site ). reverse_complement ()) self . iter_reverse = [ m.start() for m in re.finditer(rev_complement_site, str(self.record.seq)) ] if sum ( 1 for _ in self . iter_reverse ) == 1 : # 1 site in both strands : self . results [ \"is_site_orientation_correct\" ] = True self . reverse_enzyme = self . iter_reverse [ 0 ] if self . results [ \"is_site_orientation_correct\" ] : if self . reverse_enzyme < self . forward_enzyme : self . record . features . append ( SeqFeature ( FeatureLocation ( self . reverse_enzyme - 1 , self . forward_enzyme + 1 ), id = str ( self . enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : \"Excised\" , \"plasmid_assessment\" : \"excised\" , } , ) ) else : # put annotation together from two pieces : self . record . features . append ( SeqFeature ( FeatureLocation ( 0 , self . forward_enzyme + 1 ), id = str ( self . enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : \"Excised\" , \"plasmid_assessment\" : \"excised\" , } , ) ) self . record . features . append ( SeqFeature ( FeatureLocation ( self . reverse_enzyme - 1 , len ( self . record )), id = str ( self . enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : \"Excised\" , \"plasmid_assessment\" : \"excised\" , } , ) ) def digest_plasmid ( self ) : # Obtain fragments and get the backbone ' s overhangs . # This method has two assumptions : # - the sequence has two , correctly oriented enzyme sites . # - the sequence is circular . # Therefore there will be exactly two fragments , with one containing both sites . self . results [ \"digest\" ] = {} if not self . results [ \"is_circular\" ] : return if not self . results [ \"is_site_orientation_correct\" ] : return record_fragments = dc . StickyEndFragment . list_from_record_digestion ( record = self . record , enzyme = self . enzyme , linear = False ) if self . enzyme . site in record_fragments [ 0 ] . to_standard_string () : backbone_index = 1 # there are only two fragments excise_index = 0 else : backbone_index = 0 excise_index = 1 # reversed self . results [ \"digest\" ][ \"backbone_seq\" ] = record_fragments [ backbone_index ] self . results [ \"digest\" ][ \"excised_seq\" ] = record_fragments [ excise_index ] self . results [ \"digest\" ][ \"first_overhang\" ] = str ( record_fragments [ excise_index ] . seq . left_end ) self . results [ \"digest\" ][ \"last_overhang\" ] = str ( record_fragments [ excise_index ] . seq . right_end ) def count_other_sites ( self , other_enzymes ) : self . results [ \"other_sites\" ] = {} self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = False if other_enzymes is None : return bio_enzymes = [ Bio.Restriction.__dict__[enzyme ] for enzyme in other_enzymes ] restriction_batch = Bio . Restriction . RestrictionBatch ( bio_enzymes ) # Work with the assumption that the sequence is circular : analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = False ) self . results [ \"other_sites\" ][ \"enzyme\" ] = analysis . full ( linear = False ) for enzyme , matches in self . results [ \"other_sites\" ][ \"enzyme\" ] . items () : if len ( matches ) != 0 : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = True # Also add as features for plot in report : for site in matches : self . record . features . append ( SeqFeature ( FeatureLocation ( site , site + 1 ), id = str ( enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : str ( enzyme ), \"plasmid_assessment\" : \"enzyme\" , } , ) ) def check_enzyme_site_locations ( self ) : \"\"\"Flag enzyme sites that are within the retained backbone.\"\"\" try : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] self . results [ \"is_site_orientation_correct\" ] except KeyError : print ( \"Run assessment methods first!\" ) else : self . sites_outside_excised_region = {} if ( self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] and self . results [ \"is_site_orientation_correct\" ] ) : # if there are no other sites , no need to run : if self . reverse_enzyme < self . forward_enzyme : # orientation = reverse -> forward for enzyme , sites in self . results [ \"other_sites\" ][ \"enzyme\" ] . items () : problem_sites = [] for site in sites : if self . reverse_enzyme < site < self . forward_enzyme : pass else : problem_sites += [ str(site) ] if problem_sites != []: self . sites_outside_excised_region [ str(enzyme) ] = problem_sites txt = \"\" # for the pdf report for ( enzyme , problem_sites , ) in self . sites_outside_excised_region . items () : txt += enzyme + \": \" + \" \" . join ( problem_sites ) + \";\" self . sites_outside_excised_region_txt = txt else : # orientation = forward -> reverse for enzyme , sites in self . results [ \"other_sites\" ][ \"enzyme\" ] . items () : problem_sites = [] for site in sites : if self . forward_enzyme < site < self . reverse_enzyme : # in this case the site is within the retained backbone problem_sites += [ str(site) ] if problem_sites != []: self . sites_outside_excised_region [ str(enzyme) ] = problem_sites txt = \"\" # for the pdf report for ( enzyme , problem_sites , ) in self . sites_outside_excised_region . items () : txt += enzyme + \": \" + \" \" . join ( problem_sites ) + \";\" self . sites_outside_excised_region_txt = txt else : # no other sites or orientation not correct self . sites_outside_excised_region_txt = \"\" def sum_results ( self ) : self . results [ \"pass\" ] = True if self . results [ \"is_circular\" ] is False : self . results [ \"pass\" ] = False return if self . results [ \"is_site_orientation_correct\" ] is False : # implicitly checks number of sites too self . results [ \"pass\" ] = False return if self . sites_outside_excised_region_txt : self . results [ \"pass\" ] = False return # if self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] : # self . results [ \"pass\" ] = False # return def plot_plasmid ( self ) : \"\"\"Plot an outline of the plasmid.\"\"\" fig , ax = plt . subplots ( figsize = ( 7 , 4 )) graphic_record = AssessmentTranslator (). translate_record ( self . record ) graphic_record . plot ( ax = ax , with_ruler = False , strand_in_label_threshold = 2 ) self . fig = fig","title":"Assessment"},{"location":"reference/plasmid_assessor/Assessment/#class-variables","text":"UNKNOWN_IDS","title":"Class variables"},{"location":"reference/plasmid_assessor/Assessment/#methods","text":"","title":"Methods"},{"location":"reference/plasmid_assessor/Assessment/#add_name","text":"def add_name ( self ) Set a name for the assessment. View Source def add_name ( self ) : \"\"\" Set a name for the assessment. \"\"\" # To display on the report : if str ( self . record . id ) . strip () in self . UNKNOWN_IDS : self . name = \" Unnamed plasmid \" else : if len ( self . record . id ) > 16 : # Genbank limit , also for width in report self . name = self . record . id [: 16 ] + \" ... \" else : self . name = self . record . id","title":"add_name"},{"location":"reference/plasmid_assessor/Assessment/#assess_plasmid","text":"def assess_plasmid ( self , other_enzymes = None ) Evaluate plasmid for Golden Gate. Parameters other_enzymes List of enzymes used in higher level assemblies ( list ). View Source def assess_plasmid ( self , other_enzymes = None ) : \" \"\" Evaluate plasmid for Golden Gate. **Parameters** **other_enzymes** > List of enzymes used in higher level assemblies (`list`). \"\" \" if other_enzymes : self . other_enzymes = \", \" . join ( [ str ( enz ) for enz in other_enzymes ] ) self . add_name () self . check_circularity () self . get_number_of_sites () self . evaluate_orientation () self . digest_plasmid () self . count_other_sites ( other_enzymes ) self . check_enzyme_site_locations () self . sum_results () self . plot_plasmid ()","title":"assess_plasmid"},{"location":"reference/plasmid_assessor/Assessment/#check_circularity","text":"def check_circularity ( self ) View Source def check_circularity ( self ) : if \" topology \" not in self . record . annotations : self . results [ \" is_circular \" ] = False elif self . record . annotations [ \" topology \" ] == \" circular \" : self . results [ \" is_circular \" ] = True else : self . results [ \" is_circular \" ] = False","title":"check_circularity"},{"location":"reference/plasmid_assessor/Assessment/#check_enzyme_site_locations","text":"def check_enzyme_site_locations ( self ) Flag enzyme sites that are within the retained backbone. View Source def check_enzyme_site_locations ( self ) : \"\"\"Flag enzyme sites that are within the retained backbone.\"\"\" try: self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] self . results [ \"is_site_orientation_correct\" ] except KeyError: print ( \"Run assessment methods first!\" ) else : self . sites_outside_excised_region = {} if ( self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] and self . results [ \"is_site_orientation_correct\" ] ) : # if there are no other sites , no need to run: if self . reverse_enzyme < self . forward_enzyme: # orientation = reverse -> forward for enzyme , sites in self . results [ \"other_sites\" ][ \"enzyme\" ]. items () : problem_sites = [] for site in sites: if self . reverse_enzyme < site < self . forward_enzyme: pass else : problem_sites += [ str ( site )] if problem_sites != [] : self . sites_outside_excised_region [ str ( enzyme ) ] = problem_sites txt = \"\" # for the pdf report for ( enzyme , problem_sites , ) in self . sites_outside_excised_region . items () : txt += enzyme + \": \" + \" \" . join ( problem_sites ) + \";\" self . sites_outside_excised_region_txt = txt else : # orientation = forward -> reverse for enzyme , sites in self . results [ \"other_sites\" ][ \"enzyme\" ]. items () : problem_sites = [] for site in sites: if self . forward_enzyme < site < self . reverse_enzyme: # in this case the site is within the retained backbone problem_sites += [ str ( site )] if problem_sites != [] : self . sites_outside_excised_region [ str ( enzyme ) ] = problem_sites txt = \"\" # for the pdf report for ( enzyme , problem_sites , ) in self . sites_outside_excised_region . items () : txt += enzyme + \": \" + \" \" . join ( problem_sites ) + \";\" self . sites_outside_excised_region_txt = txt else : # no other sites or orientation not correct self . sites_outside_excised_region_txt = \"\"","title":"check_enzyme_site_locations"},{"location":"reference/plasmid_assessor/Assessment/#count_other_sites","text":"def count_other_sites ( self , other_enzymes ) View Source def count_other_sites ( self , other_enzymes ) : self . results [ \"other_sites\" ] = {} self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = False if other_enzymes is None : return bio_enzymes = [ Bio.Restriction.__dict__[enzyme ] for enzyme in other_enzymes ] restriction_batch = Bio . Restriction . RestrictionBatch ( bio_enzymes ) # Work with the assumption that the sequence is circular : analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = False ) self . results [ \"other_sites\" ][ \"enzyme\" ] = analysis . full ( linear = False ) for enzyme , matches in self . results [ \"other_sites\" ][ \"enzyme\" ] . items () : if len ( matches ) != 0 : self . results [ \"other_sites\" ][ \"has_any_other_sites\" ] = True # Also add as features for plot in report : for site in matches : self . record . features . append ( SeqFeature ( FeatureLocation ( site , site + 1 ), id = str ( enzyme ), type = \"misc_feature\" , qualifiers = { \"label\" : str ( enzyme ), \"plasmid_assessment\" : \"enzyme\" , } , ) )","title":"count_other_sites"},{"location":"reference/plasmid_assessor/Assessment/#digest_plasmid","text":"def digest_plasmid ( self ) View Source def digest_plasmid ( self ) : # Obtain fragments and get the backbone ' s overhangs . # This method has two assumptions : # - the sequence has two , correctly oriented enzyme sites . # - the sequence is circular . # Therefore there will be exactly two fragments , with one containing both sites . self . results [ \"digest\" ] = {} if not self . results [ \"is_circular\" ] : return if not self . results [ \"is_site_orientation_correct\" ] : return record_fragments = dc . StickyEndFragment . list_from_record_digestion ( record = self . record , enzyme = self . enzyme , linear = False ) if self . enzyme . site in record_fragments [ 0 ] . to_standard_string () : backbone_index = 1 # there are only two fragments excise_index = 0 else : backbone_index = 0 excise_index = 1 # reversed self . results [ \"digest\" ][ \"backbone_seq\" ] = record_fragments [ backbone_index ] self . results [ \"digest\" ][ \"excised_seq\" ] = record_fragments [ excise_index ] self . results [ \"digest\" ][ \"first_overhang\" ] = str ( record_fragments [ excise_index ] . seq . left_end ) self . results [ \"digest\" ][ \"last_overhang\" ] = str ( record_fragments [ excise_index ] . seq . right_end )","title":"digest_plasmid"},{"location":"reference/plasmid_assessor/Assessment/#evaluate_orientation","text":"def evaluate_orientation ( self ) View Source def evaluate_orientation ( self ) : self . results [ \" is_site_orientation_correct \" ] = False # default # Forward strand : self . iter_forward = [ match . end () for match in re . finditer ( self . enzyme . site , str ( self . record . seq )) ] if sum ( 1 for _ in self . iter_forward ) == 1 : self . forward_enzyme = self . iter_forward [ 0 ] # rev_complement_site = str ( self . record . seq . reverse_complement ()) rev_complement_site = str ( Seq ( self . enzyme . site ) . reverse_complement ()) self . iter_reverse = [ m . start () for m in re . finditer ( rev_complement_site , str ( self . record . seq )) ] if sum ( 1 for _ in self . iter_reverse ) == 1 : # 1 site in both strands : self . results [ \" is_site_orientation_correct \" ] = True self . reverse_enzyme = self . iter_reverse [ 0 ] if self . results [ \" is_site_orientation_correct \" ]: if self . reverse_enzyme < self . forward_enzyme : self . record . features . append ( SeqFeature ( FeatureLocation ( self . reverse_enzyme - 1 , self . forward_enzyme + 1 ) , id = str ( self . enzyme ) , type = \" misc_feature \" , qualifiers = { \" label \" : \" Excised \" , \" plasmid_assessment \" : \" excised \" , }, ) ) else : # put annotation together from two pieces : self . record . features . append ( SeqFeature ( FeatureLocation ( 0 , self . forward_enzyme + 1 ) , id = str ( self . enzyme ) , type = \" misc_feature \" , qualifiers = { \" label \" : \" Excised \" , \" plasmid_assessment \" : \" excised \" , }, ) ) self . record . features . append ( SeqFeature ( FeatureLocation ( self . reverse_enzyme - 1 , len ( self . record )) , id = str ( self . enzyme ) , type = \" misc_feature \" , qualifiers = { \" label \" : \" Excised \" , \" plasmid_assessment \" : \" excised \" , }, ) )","title":"evaluate_orientation"},{"location":"reference/plasmid_assessor/Assessment/#get_number_of_sites","text":"def get_number_of_sites ( self ) View Source def get_number_of_sites ( self ) : if \" is_circular \" in self . results : is_linear = not self . results [ \" is_circular \" ] else : is_linear = False restriction_batch = Bio . Restriction . RestrictionBatch ( [ self . enzyme ] ) analysis = Bio . Restriction . Analysis ( restriction_batch , sequence = self . record . seq , linear = is_linear ) self . analysis_results = analysis . full ( linear = is_linear ) self . results [ \" number_of_sites \" ] = len ( self . analysis_results [ self . enzyme ] ) # Add as features for plot in report : for enzyme , sites in self . analysis_results . items () : for site in sites : self . record . features . append ( SeqFeature ( FeatureLocation ( site , site + 1 ) , id = str ( enzyme ) , type = \" misc_feature \" , qualifiers = { \" label \" : str ( enzyme ) , \" plasmid_assessment \" : \" enzyme \" , }, ) )","title":"get_number_of_sites"},{"location":"reference/plasmid_assessor/Assessment/#plot_plasmid","text":"def plot_plasmid ( self ) Plot an outline of the plasmid. View Source def plot_plasmid(self): \"\"\"Plot an outline of the plasmid.\"\"\" fig, ax = plt.subplots(figsize=(7, 4)) graphic_record = AssessmentTranslator().translate_record(self.record) graphic_record.plot(ax=ax, with_ruler=False, strand_in_label_threshold=2) self.fig = fig","title":"plot_plasmid"},{"location":"reference/plasmid_assessor/Assessment/#sum_results","text":"def sum_results ( self ) View Source def sum_results ( self ) : self . results [ \"pass\" ] = True if self . results [ \"is_circular\" ] is False: self . results [ \"pass\" ] = False return if self . results [ \"is_site_orientation_correct\" ] is False: # implicitly checks number of sites too self . results [ \"pass\" ] = False return if self . sites_outside_excised_region_txt: self . results [ \"pass\" ] = False return","title":"sum_results"},{"location":"reference/plasmid_assessor/Assessment/#assessmenttranslator","text":"class AssessmentTranslator ( features_filters = (), features_properties = None ) Custom translator for highlighting key features. View Source class AssessmentTranslator: \"\"\"Please install dna_features_viewer to use this class.\"\"\" def __init__ ( self ): raise Exception ( \"Please install dna_features_viewer to use this class.\" )","title":"AssessmentTranslator"},{"location":"reference/plasmid_assessor/Assessment/#ancestors-in-mro","text":"dna_features_viewer.BiopythonTranslator.BiopythonTranslator.BiopythonTranslator dna_features_viewer.BiopythonTranslator.BiopythonTranslatorBase.BiopythonTranslatorBase","title":"Ancestors (in MRO)"},{"location":"reference/plasmid_assessor/Assessment/#class-variables_1","text":"default_feature_color graphic_record_parameters ignored_features_types label_fields","title":"Class variables"},{"location":"reference/plasmid_assessor/Assessment/#static-methods","text":"","title":"Static methods"},{"location":"reference/plasmid_assessor/Assessment/#quick_class_plot","text":"def quick_class_plot ( record , figure_width = 12 , ** kwargs ) Allows super quick and dirty plotting of Biopython records. This is really meant for use in a Jupyter/Ipython notebook with the \"%matplotlib inline\" setting. from dna_features_viewer import BiopythonTranslator BiopythonTranslator.quick_plot(my_record) View Source @classmethod def quick_class_plot ( cls , record , figure_width = 12 , ** kwargs ): \"\"\"Allows super quick and dirty plotting of Biopython records. This is really meant for use in a Jupyter/Ipython notebook with the \"%matplotlib inline\" setting. >>> from dna_features_viewer import BiopythonTranslator >>> BiopythonTranslator.quick_plot(my_record) \"\"\" graphic_record = cls () . translate_record ( record ) ax , _ = graphic_record . plot ( figure_width = figure_width , ** kwargs ) return ax","title":"quick_class_plot"},{"location":"reference/plasmid_assessor/Assessment/#methods_1","text":"","title":"Methods"},{"location":"reference/plasmid_assessor/Assessment/#compute_feature_box_color","text":"def compute_feature_box_color ( self , feature ) Compute a box_color for this feature. View Source def compute_feature_box_color ( self , feature ) : \"\"\" Compute a box_color for this feature. \"\"\" return \" auto \"","title":"compute_feature_box_color"},{"location":"reference/plasmid_assessor/Assessment/#compute_feature_box_linewidth","text":"def compute_feature_box_linewidth ( self , feature ) Compute a box_linewidth for this feature. View Source def compute_feature_box_linewidth ( self , feature ) : \"\"\" Compute a box_linewidth for this feature. \"\"\" return 0 . 3","title":"compute_feature_box_linewidth"},{"location":"reference/plasmid_assessor/Assessment/#compute_feature_color","text":"def compute_feature_color ( self , feature ) Compute a color for this feature. If the feature has a color qualifier it will be used. Otherwise, the classe's default_feature_color is used. To change the behaviour, create a subclass of BiopythonTranslator and overwrite this method. View Source def compute_feature_color ( self , feature ) : assessment_ref = \"plasmid_assessment\" if assessment_ref in feature . qualifiers : if feature . qualifiers [ assessment_ref ] == \"enzyme\" : return \"red\" elif feature . qualifiers [ assessment_ref ] == \"excised\" : return \"yellow\" elif feature . qualifiers [ assessment_ref ] == \"backbone\" : return \"tab:cyan\" else : return \"tab:blue\" # default dna_features_viewer color else : return \"tab:blue\"","title":"compute_feature_color"},{"location":"reference/plasmid_assessor/Assessment/#compute_feature_fontdict","text":"def compute_feature_fontdict ( self , feature ) Compute a font dict for this feature. View Source def compute_feature_fontdict ( self , feature ) : \"\"\" Compute a font dict for this feature. \"\"\" return None","title":"compute_feature_fontdict"},{"location":"reference/plasmid_assessor/Assessment/#compute_feature_html","text":"def compute_feature_html ( self , feature ) Gets the 'label' of the feature. View Source def compute_feature_html ( self , feature ) : \"\"\" Gets the 'label' of the feature. \"\"\" return self . compute_feature_label ( feature )","title":"compute_feature_html"},{"location":"reference/plasmid_assessor/Assessment/#compute_feature_label","text":"def compute_feature_label ( self , feature ) Compute the label of the feature. View Source def compute_feature_label ( self , feature ) : \"\"\"Compute the label of the feature.\"\"\" label = feature . type for key in self . label_fields : if key in feature . qualifiers and len ( feature . qualifiers [ key ] ) : label = feature . qualifiers [ key ] break if isinstance ( label , list ) : label = \"|\" . join ( label ) return label","title":"compute_feature_label"},{"location":"reference/plasmid_assessor/Assessment/#compute_feature_label_link_color","text":"def compute_feature_label_link_color ( self , feature ) Compute the color of the line linking the label to its feature. View Source def compute_feature_label_link_color ( self , feature ) : \"\"\" Compute the color of the line linking the label to its feature. \"\"\" return \" black \"","title":"compute_feature_label_link_color"},{"location":"reference/plasmid_assessor/Assessment/#compute_feature_legend_text","text":"def compute_feature_legend_text ( self , feature ) View Source def compute_feature_legend_text ( self , feature ) : return None","title":"compute_feature_legend_text"},{"location":"reference/plasmid_assessor/Assessment/#compute_feature_linewidth","text":"def compute_feature_linewidth ( self , feature ) Compute the edge width of the feature's arrow/rectangle. View Source def compute_feature_linewidth ( self , feature ) : \"\"\" Compute the edge width of the feature's arrow/rectangle. \"\"\" return 1 . 0","title":"compute_feature_linewidth"},{"location":"reference/plasmid_assessor/Assessment/#compute_filtered_features","text":"def compute_filtered_features ( self , features ) Return the list of features minus the ignored ones. By the method keeps any feature whose type is not in ignored_features_types and for which all filter(f) pass. View Source def compute_filtered_features ( self , features ) : \"\"\" Return the list of features minus the ignored ones. By the method keeps any feature whose type is not in ignored_features_types and for which all filter ( f ) pass . \"\"\" return [ f for f in features if all ( [ fl ( f ) for fl in self . features_filters ] ) and f . type not in self . ignored_features_types ]","title":"compute_filtered_features"},{"location":"reference/plasmid_assessor/Assessment/#quick_plot","text":"def quick_plot ( self , record , figure_width = 12 , ** kwargs ) Allows super quick and dirty plotting of Biopython records. This is really meant for use in a Jupyter/Ipython notebook with the \"%matplotlib inline\" setting. from dna_features_viewer import BiopythonTranslator BiopythonTranslator.quick_plot(my_record) View Source def quick_plot ( self , record , figure_width = 12 , ** kwargs ): \"\"\"Allows super quick and dirty plotting of Biopython records. This is really meant for use in a Jupyter/Ipython notebook with the \"%matplotlib inline\" setting. >>> from dna_features_viewer import BiopythonTranslator >>> BiopythonTranslator.quick_plot(my_record) \"\"\" graphic_record = self . translate_record ( record ) ax , _ = graphic_record . plot ( figure_width = figure_width , ** kwargs ) return ax","title":"quick_plot"},{"location":"reference/plasmid_assessor/Assessment/#translate_feature","text":"def translate_feature ( self , feature ) Translate a Biopython feature into a Dna Features Viewer feature. View Source def translate_feature ( self , feature ) : \"\"\" Translate a Biopython feature into a Dna Features Viewer feature. \"\"\" properties = dict ( label = self . compute_feature_label ( feature ) , color = self . compute_feature_color ( feature ) , html = self . compute_feature_html ( feature ) , fontdict = self . compute_feature_fontdict ( feature ) , box_linewidth = self . compute_feature_box_linewidth ( feature ) , box_color = self . compute_feature_box_color ( feature ) , linewidth = self . compute_feature_linewidth ( feature ) , label_link_color = self . compute_feature_label_link_color ( feature ) , legend_text = self . compute_feature_legend_text ( feature ) , ) if self . features_properties is not None : other_properties = self . features_properties if hasattr ( other_properties , \" __call__ \" ) : other_properties = other_properties ( feature ) properties . update ( other_properties ) return GraphicFeature ( start = feature . location . start , end = feature . location . end , strand = feature . location . strand , ** properties )","title":"translate_feature"},{"location":"reference/plasmid_assessor/Assessment/#translate_record","text":"def translate_record ( self , record , record_class = None , filetype = None ) Create a new GraphicRecord from a BioPython Record object.","title":"translate_record"},{"location":"reference/plasmid_assessor/Assessment/#parameters","text":"record A BioPython Record object or the path to a Genbank or a GFF file. record_class The graphic record class to use, e.g. GraphicRecord (default) or CircularGraphicRecord. Strings 'circular' and 'linear' can also be provided. filetype Used only when a Genbank or a GFF file is provided; one of \"genbank\" or \"gff\" to be used. Default None infers from file extension. View Source def translate_record ( self , record , record_class = None , filetype = None ) : \"\"\"Create a new GraphicRecord from a BioPython Record object. Parameters ---------- record A BioPython Record object or the path to a Genbank or a GFF file. record_class The graphic record class to use, e.g. GraphicRecord (default) or CircularGraphicRecord. Strings 'circular' and 'linear' can also be provided. filetype Used only when a Genbank or a GFF file is provided; one of \" genbank \" or \" gff \" to be used. Default None infers from file extension. \"\"\" classes = { \"linear\" : GraphicRecord , \"circular\" : CircularGraphicRecord , None : GraphicRecord , } if record_class in classes : record_class = classes [ record_class ] if isinstance ( record , str ) or hasattr ( record , \"read\" ) : record = load_record ( record , filetype = filetype ) filtered_features = self . compute_filtered_features ( record . features ) return record_class ( sequence_length = len ( record ), sequence = str ( record . seq ), features =[ self.translate_feature(feature) for feature in filtered_features if feature.location is not None ] , ** self . graphic_record_parameters )","title":"Parameters"},{"location":"reference/plasmid_assessor/reports/","text":"Module plasmid_assessor.reports View Source from datetime import datetime import os try : import pdf_reports.tools as pdf_tools from pdf_reports import ( add_css_class , dataframe_to_html , pug_to_html , style_table_rows , write_report , ) import pandas import matplotlib REPORT_PKGS_AVAILABLE = True except ImportError : REPORT_PKGS_AVAILABLE = False from .version import __version__ THIS_PATH = os . path . dirname ( os . path . realpath ( __file__ )) ASSETS_PATH = os . path . join ( THIS_PATH , \"report_assets\" ) REPORT_TEMPLATE = os . path . join ( ASSETS_PATH , \"assessment_report.pug\" ) STYLESHEET = os . path . join ( ASSETS_PATH , \"report_style.css\" ) def end_pug_to_html ( template , ** context ): now = datetime . now () . strftime ( \"%Y-%m- %d \" ) defaults = { \"sidebar_text\" : \"Generated on %s by EGF's Plasmid assessor (version %s )\" % ( now , __version__ ), \"plasma_logo_url\" : os . path . join ( ASSETS_PATH , \"imgs\" , \"plasma_logo.png\" ), } for k in defaults : if k not in context : context [ k ] = defaults [ k ] return pug_to_html ( template , ** context ) def write_pdf_report ( target , assessment ): \"\"\"Write an assessment report with a PDF summary. **Parameters** **target** > Path for PDF file. **assessment** > Assessment instance. \"\"\" if not REPORT_PKGS_AVAILABLE : raise ImportError ( \"Install extra packages with `pip install plasmid_assessor[report]`\" ) assessment . figure_data = pdf_tools . figure_data ( assessment . fig , fmt = \"svg\" ) html = end_pug_to_html ( REPORT_TEMPLATE , assessment = assessment ,) write_report ( html , target , extra_stylesheets = ( STYLESHEET ,)) Variables ASSETS_PATH REPORT_PKGS_AVAILABLE REPORT_TEMPLATE STYLESHEET THIS_PATH Functions end_pug_to_html def end_pug_to_html ( template , ** context ) View Source def end_pug_to_html ( template , ** context ) : now = datetime . now (). strftime ( \"%Y-%m-%d\" ) defaults = { \"sidebar_text\" : \"Generated on %s by EGF's Plasmid assessor (version %s)\" % ( now , __version__ ), \"plasma_logo_url\" : os . path . join ( ASSETS_PATH , \"imgs\" , \"plasma_logo.png\" ), } for k in defaults : if k not in context : context [ k ] = defaults [ k ] return pug_to_html ( template , ** context ) write_pdf_report def write_pdf_report ( target , assessment ) Write an assessment report with a PDF summary. Parameters target Path for PDF file. assessment Assessment instance. View Source def write_pdf_report ( target , assessment ) : \"\"\"Write an assessment report with a PDF summary. **Parameters** **target** > Path for PDF file. **assessment** > Assessment instance. \"\"\" if not REPORT_PKGS_AVAILABLE : raise ImportError ( \"Install extra packages with `pip install plasmid_assessor[report]`\" ) assessment . figure_data = pdf_tools . figure_data ( assessment . fig , fmt = \"svg\" ) html = end_pug_to_html ( REPORT_TEMPLATE , assessment = assessment ,) write_report ( html , target , extra_stylesheets = ( STYLESHEET ,))","title":"Reports"},{"location":"reference/plasmid_assessor/reports/#module-plasmid_assessorreports","text":"View Source from datetime import datetime import os try : import pdf_reports.tools as pdf_tools from pdf_reports import ( add_css_class , dataframe_to_html , pug_to_html , style_table_rows , write_report , ) import pandas import matplotlib REPORT_PKGS_AVAILABLE = True except ImportError : REPORT_PKGS_AVAILABLE = False from .version import __version__ THIS_PATH = os . path . dirname ( os . path . realpath ( __file__ )) ASSETS_PATH = os . path . join ( THIS_PATH , \"report_assets\" ) REPORT_TEMPLATE = os . path . join ( ASSETS_PATH , \"assessment_report.pug\" ) STYLESHEET = os . path . join ( ASSETS_PATH , \"report_style.css\" ) def end_pug_to_html ( template , ** context ): now = datetime . now () . strftime ( \"%Y-%m- %d \" ) defaults = { \"sidebar_text\" : \"Generated on %s by EGF's Plasmid assessor (version %s )\" % ( now , __version__ ), \"plasma_logo_url\" : os . path . join ( ASSETS_PATH , \"imgs\" , \"plasma_logo.png\" ), } for k in defaults : if k not in context : context [ k ] = defaults [ k ] return pug_to_html ( template , ** context ) def write_pdf_report ( target , assessment ): \"\"\"Write an assessment report with a PDF summary. **Parameters** **target** > Path for PDF file. **assessment** > Assessment instance. \"\"\" if not REPORT_PKGS_AVAILABLE : raise ImportError ( \"Install extra packages with `pip install plasmid_assessor[report]`\" ) assessment . figure_data = pdf_tools . figure_data ( assessment . fig , fmt = \"svg\" ) html = end_pug_to_html ( REPORT_TEMPLATE , assessment = assessment ,) write_report ( html , target , extra_stylesheets = ( STYLESHEET ,))","title":"Module plasmid_assessor.reports"},{"location":"reference/plasmid_assessor/reports/#variables","text":"ASSETS_PATH REPORT_PKGS_AVAILABLE REPORT_TEMPLATE STYLESHEET THIS_PATH","title":"Variables"},{"location":"reference/plasmid_assessor/reports/#functions","text":"","title":"Functions"},{"location":"reference/plasmid_assessor/reports/#end_pug_to_html","text":"def end_pug_to_html ( template , ** context ) View Source def end_pug_to_html ( template , ** context ) : now = datetime . now (). strftime ( \"%Y-%m-%d\" ) defaults = { \"sidebar_text\" : \"Generated on %s by EGF's Plasmid assessor (version %s)\" % ( now , __version__ ), \"plasma_logo_url\" : os . path . join ( ASSETS_PATH , \"imgs\" , \"plasma_logo.png\" ), } for k in defaults : if k not in context : context [ k ] = defaults [ k ] return pug_to_html ( template , ** context )","title":"end_pug_to_html"},{"location":"reference/plasmid_assessor/reports/#write_pdf_report","text":"def write_pdf_report ( target , assessment ) Write an assessment report with a PDF summary. Parameters target Path for PDF file. assessment Assessment instance. View Source def write_pdf_report ( target , assessment ) : \"\"\"Write an assessment report with a PDF summary. **Parameters** **target** > Path for PDF file. **assessment** > Assessment instance. \"\"\" if not REPORT_PKGS_AVAILABLE : raise ImportError ( \"Install extra packages with `pip install plasmid_assessor[report]`\" ) assessment . figure_data = pdf_tools . figure_data ( assessment . fig , fmt = \"svg\" ) html = end_pug_to_html ( REPORT_TEMPLATE , assessment = assessment ,) write_report ( html , target , extra_stylesheets = ( STYLESHEET ,))","title":"write_pdf_report"},{"location":"reference/plasmid_assessor/version/","text":"Module plasmid_assessor.version View Source __version__ = \"0.1.0\"","title":"Version"},{"location":"reference/plasmid_assessor/version/#module-plasmid_assessorversion","text":"View Source __version__ = \"0.1.0\"","title":"Module plasmid_assessor.version"}]}
\ No newline at end of file
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
index 2fa95b4..c21d9a9 100644
--- a/docs/sitemap.xml
+++ b/docs/sitemap.xml
@@ -1,23 +1,23 @@
None
- 2021-09-29
+ 2021-10-06
daily
None
- 2021-09-29
+ 2021-10-06
daily
None
- 2021-09-29
+ 2021-10-06
daily
None
- 2021-09-29
+ 2021-10-06
daily
None
- 2021-09-29
+ 2021-10-06
daily
\ No newline at end of file
diff --git a/docs/sitemap.xml.gz b/docs/sitemap.xml.gz
index 6b058a9..d7e8123 100644
Binary files a/docs/sitemap.xml.gz and b/docs/sitemap.xml.gz differ