Source code for dnaweaver.DnaSupplier.builtin_suppliers.DnaSuppliersComparator

from ...DnaQuote import DnaQuote
from ..DnaSupplier import DnaSupplier


[docs]class DnaSuppliersComparator(DnaSupplier): """Special source that compares quotes from other DnaSuppliers. Upon receiving a sequence, that source will submit the sequence to Downstream sources, which deliver each one optimal quote. The comparator then returns the one quote with the lowest price. Parameters ---------- suppliers List of `DnaSuppliers`. memoize Whether the quotes should be kept in memory to avoid re-computing the same quote several times. Can accelerate computations but is RAM-expensive. """ class_description = "DNA sources comparator" operation_type = "comparison" report_fa_symbol = u"" report_fa_symbol_plain = u"circle-o" report_color = "#000000" def __init__( self, suppliers=(), memoize=False, sequence_constraints=(), return_first_accepted_quote=False, name="comparator", ): self.set_suppliers(suppliers) self.memoize = memoize self.sequence_constraints = sequence_constraints self.return_first_accepted_quote = return_first_accepted_quote self.memoize_dict = {} self.name = name
[docs] def get_best_price( self, sequence, max_lead_time=None, with_assembly_plan=False, ): """Returns a price-optimal DnaQuote for the given sequence. Parameters ---------- sequence (str) The sequence submitted to the Dna Source for a quote. max_lead_time (float) If provided, the quote returned is the best quote (price-wise) whose lead time is less or equal to max_lead_time. with_assembly_plan If True, the assembly plan is added to the quote. """ best_quote = None best_basepair_price = 1e8 for source in sorted(self.suppliers, key=lambda s: s.min_basepair_price): # print (self.name, len(sequence), source) if source.min_basepair_price > best_basepair_price: break quote = source.get_quote( sequence, max_lead_time=max_lead_time, with_assembly_plan=with_assembly_plan, ) # print ('=>', quote.accepted, quote.price) if not quote.accepted: continue if self.return_first_accepted_quote: best_quote = quote break quote_basepair_price = quote.price / float(len(sequence)) if quote_basepair_price < best_basepair_price: best_quote = quote best_basepair_price = quote_basepair_price if best_quote is None: return DnaQuote( self, sequence, accepted=False, message="Sequence was rejected by all sources.", ) if "via" not in best_quote.metadata: best_quote.metadata["via"] = [] best_quote.metadata["via"].append(self) return best_quote
def additional_dict_description(self): return { "dna sources": [source.name for source in self.suppliers], } @staticmethod def from_dict(data): return DnaSuppliersComparator(name=data["name"], suppliers=data["suppliers"]) def set_suppliers(self, suppliers): self.suppliers = suppliers if len(suppliers): self.min_basepair_price = min( [supplier.min_basepair_price for supplier in suppliers] ) else: self.min_basepair_price = None def suggest_cuts(self, sequence): return sorted( set( [ cut for supplier in self.suppliers if hasattr(supplier, "suggest_cuts") for cut in supplier.suggest_cuts(sequence) ] ) )