How to Build Plasmid Engineering Workbench with Circular Mapping, Restriction Analysis, Virtual Gels, and Primer Design


def _ang(bp, L):  return math.pi/2 - 2*math.pi*(bp/L)
def _pt(bp, r, L):
   a = _ang(bp, L); return r*math.cos(a), r*math.sin(a)
def _arc(s, e, r, L, n=240):
   if e < s: e += L
   bps = np.linspace(s, e, max(2, int(n*(e-s)/L)+2))
   return ([r*math.cos(_ang(b, L)) for b in bps],
           [r*math.sin(_ang(b, L)) for b in bps])
def gc_percent(seq):
   s = str(seq).upper(); n = len(s) or 1
   return 100.0 * (s.count("G") + s.count("C")) / n
def circular_map(rec, title=None, show_gc=True):
   L = len(rec.seq); feats = norm_features(rec)
   fig, ax = plt.subplots(figsize=(8, 8)); R = 1.0
   if show_gc:
       w = max(30, L // 120); step = max(1, w // 2); mean = gc_percent(rec.seq)
       s = str(rec.seq).upper()
       for i in range(0, L, step):
           win = s[i:i+w] or s[i:] + s[:(i+w) % L]
           dev = (gc_percent(win) - mean) / 100.0
           rr = 0.72 + dev * 0.9
           x0, y0 = _pt(i, 0.72, L); x1, y1 = _pt(i, rr, L)
           ax.plot([x0, x1], [y0, y1],
                   color="#2e86ab" if dev >= 0 else "#d1495b", lw=1, alpha=0.5, zorder=1)
   xs, ys = _arc(0, L, R, L); ax.plot(xs, ys, color="#333", lw=2.5, zorder=2)
   step = max(1, round(L/12/100)*100) or max(1, L//12)
   for t in range(0, L, step):
       x0, y0 = _pt(t, R*1.015, L); x1, y1 = _pt(t, R*1.045, L)
       ax.plot([x0, x1], [y0, y1], color="#999", lw=1, zorder=2)
       lx, ly = _pt(t, R*1.10, L)
       ax.text(lx, ly, f"{t:,}", ha="center", va="center", fontsize=7, color="#777")
   for f in feats:
       outer = f["strand"] >= 0
       rr = R + 0.09 if outer else R - 0.09
       xs, ys = _arc(f["start"], f["end"], rr, L)
       ax.plot(xs, ys, color=f["color"], lw=10, solid_capstyle="butt", alpha=0.9, zorder=3)
       tip = f["end"] if outer else f["start"]
       a = _ang(tip, L); tx, ty = rr*math.cos(a), rr*math.sin(a)
       d = -1 if outer else 1
       tanx, tany = -math.sin(a)*d, math.cos(a)*d
       px, py = math.cos(a), math.sin(a)
       ln, wd = 0.055, 0.052
       ax.add_patch(Polygon([(tx+tanx*ln, ty+tany*ln),
                             (tx+px*wd,   ty+py*wd),
                             (tx-px*wd,   ty-py*wd)],
                            color=f["color"], zorder=4))
       span = (f["end"] - f["start"]) % L
       mid = (f["start"] + span/2) % L
       lx, ly = _pt(mid, (rr + 0.16) if outer else (rr - 0.16), L)
       ax.text(lx, ly, f["label"], ha="center", va="center",
               fontsize=8.5, color=f["color"], weight="bold", zorder=5)
   circ = "circular" if rec.annotations.get("topology") == "circular" else "linear"
   ax.text(0,  0.05, title or rec.name, ha="center", va="center", fontsize=15, weight="bold")
   ax.text(0, -0.07, f"{L:,} bp · {gc_percent(rec.seq):.1f}% GC · {circ}",
           ha="center", va="center", fontsize=9.5, color="#555")
   ax.set_xlim(-1.45, 1.45); ax.set_ylim(-1.45, 1.45)
   ax.set_aspect("equal"); ax.axis("off"); plt.tight_layout(); plt.show()



Source link

  • Related Posts

    Google Cloud’s Always-On Memory Agent Replaces RAG and Embeddings With Continuous LLM Consolidation on Gemini 3.1 Flash-Lite

    Most AI agents forget. They process a request, answer it, then drop the context. Google Cloud’s generative-ai repository now ships a sample that tackles this directly. It is the Always-On…

    Sakana AI’s Error Diffusion Trains Dale-Compliant Dual-Stream Networks, Reaching 96.7% MNIST and 61.7% CIFAR-10 Without Backpropagation

    Backpropagation dominates deep learning, yet it uses a mechanism the brain likely cannot. Specifically, the backward pass needs exact transposes of forward weight matrices. This is the weight transport problem.…

    Leave a Reply

    Your email address will not be published. Required fields are marked *