Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Analyze restriction digest fragments using Biopython Bio.Restriction. Predict fragment sizes, get fragment sequences, simulate gel electrophoresis patterns, and perform double digests. Use when analyzing restriction digest fragment patterns.
.claude/skills/bio-restriction-fragment-analysis/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-22 | ✗→✓ | ▲ Improved | 22% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 60% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 37% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 44% | 0% |
<!--
#
#
-->
pythonfrom Bio import SeqIO from Bio.Restriction import EcoRI record = SeqIO.read('sequence.fasta', 'fasta') seq = record.seq # catalyze() returns tuple: (fragments_5prime, fragments_3prime) # For standard use, take the first element fragments = EcoRI.catalyze(seq)[0] # fragments is tuple of Seq objects sizes = [len(f) for f in fragments] print(f'Fragment sizes: {sorted(sizes, reverse=True)}')
pythonfrom Bio.Restriction import EcoRI # Linear DNA fragments_linear = EcoRI.catalyze(seq, linear=True)[0] # Circular DNA (plasmid) fragments_circular = EcoRI.catalyze(seq, linear=False)[0] # Circular produces one fewer fragment (ends join) print(f'Linear: {len(fragments_linear)} fragments') print(f'Circular: {len(fragments_circular)} fragments')
pythonfrom Bio.Restriction import EcoRI fragments = EcoRI.catalyze(seq)[0] for i, frag in enumerate(fragments, 1): print(f'Fragment {i}: {len(frag)} bp') print(f' 5\' end: {frag[:20]}...') print(f' 3\' end: ...{frag[-20:]}')
pythonfrom Bio.Restriction import EcoRI, BamHI, RestrictionBatch # Method 1: Sequential digestion frags_ecori = EcoRI.catalyze(seq)[0] final_fragments = [] for frag in frags_ecori: sub_frags = BamHI.catalyze(frag)[0] final_fragments.extend(sub_frags) # Method 2: Using RestrictionBatch batch = RestrictionBatch([EcoRI, BamHI]) # Note: RestrictionBatch doesn't have catalyze, use Analysis # Method 3: Manual calculation from positions ecori_sites = EcoRI.search(seq) bamhi_sites = BamHI.search(seq) all_sites = sorted(set(ecori_sites + bamhi_sites)) fragment_sizes = [] for i in range(len(all_sites) - 1): fragment_sizes.append(all_sites[i + 1] - all_sites[i]) # Add terminal fragments fragment_sizes.insert(0, all_sites[0]) fragment_sizes.append(len(seq) - all_sites[-1])
pythondef fragments_from_positions(seq_len, cut_positions, linear=True): '''Calculate fragment sizes from cut positions''' if not cut_positions: return [seq_len] positions = sorted(cut_positions) fragments = [] if linear: # First fragment: start to first cut fragments.append(positions[0]) # Middle fragments for i in range(len(positions) - 1): fragments.append(positions[i + 1] - positions[i]) # Last fragment: last cut to end fragments.append(seq_len - positions[-1]) else: # Circular: all fragments between cuts for i in range(len(positions) - 1): fragments.append(positions[i + 1] - positions[i]) # Wrap-around fragment fragments.append((seq_len - positions[-1]) + positions[0]) return fragments # Usage sites = EcoRI.search(seq) sizes = fragments_from_positions(len(seq), sites, linear=True) print(f'Fragment sizes: {sorted(sizes, reverse=True)}')
pythondef simulate_gel(fragment_sizes, ladder=None): '''Print a text-based gel simulation''' if ladder is None: ladder = [10000, 8000, 6000, 5000, 4000, 3000, 2000, 1500, 1000, 750, 500, 250] max_size = max(max(fragment_sizes), max(ladder)) print('Ladder | Digest') print('-' * 30) for size in sorted(ladder + fragment_sizes, reverse=True): ladder_mark = f'{size:>6}' if size in ladder else ' ' digest_mark = '====' if size in fragment_sizes else '' print(f'{ladder_mark} | {digest_mark}') # Usage sizes = [len(f) for f in EcoRI.catalyze(seq)[0]] simulate_gel(sizes)
pythonfrom Bio.Restriction import EcoRI, BamHI def fragment_report(seq, enzyme, linear=True): '''Generate detailed fragment analysis''' sites = enzyme.search(seq, linear=linear) fragments = enzyme.catalyze(seq, linear=linear)[0] print(f'Enzyme: {enzyme}') print(f'Recognition site: {enzyme.site}') print(f'Number of sites: {len(sites)}') print(f'Cut positions: {sites}') print(f'\nFragments ({len(fragments)}):') sizes = sorted([len(f) for f in fragments], reverse=True) total = sum(sizes) for i, size in enumerate(sizes, 1): pct = (size / total) * 100 print(f' {i}. {size:6d} bp ({pct:5.1f}%)') print(f'\nTotal: {total} bp') return sizes # Usage sizes = fragment_report(seq, EcoRI)
pythondef compare_fragments(expected, observed, tolerance=50): '''Compare expected fragment sizes with observed (from gel)''' matched = [] unmatched_exp = list(expected) unmatched_obs = list(observed) for exp in expected: for obs in observed: if abs(exp - obs) <= tolerance: matched.append((exp, obs)) if exp in unmatched_exp: unmatched_exp.remove(exp) if obs in unmatched_obs: unmatched_obs.remove(obs) break print('Matched fragments:') for exp, obs in matched: print(f' Expected: {exp}, Observed: {obs}') if unmatched_exp: print(f'\nMissing (expected but not observed): {unmatched_exp}') if unmatched_obs: print(f'\nExtra (observed but not expected): {unmatched_obs}') # Usage expected = [3000, 2000, 1500, 500] observed = [3050, 2000, 1480, 510, 200] # From gel compare_fragments(expected, observed)
pythonfrom Bio.Restriction import EcoRI def annotated_fragments(seq, enzyme, context=50): '''Get fragments with surrounding sequence context''' sites = enzyme.search(seq) fragments = enzyme.catalyze(seq)[0] print(f'{enzyme} digest ({len(fragments)} fragments):') for i, (frag, site) in enumerate(zip(fragments, [0] + sites), 1): print(f'\nFragment {i}: {len(frag)} bp (starts at {site})') print(f" 5' sequence: {str(frag[:context])}...") print(f" 3' sequence: ...{str(frag[-context:])}") # Usage annotated_fragments(seq, EcoRI)
[0] to get 5' fragments<!-- AUTHOR_SIGNATURE: 9a7f3c2e-MD-BABU-MIA-2026-MSSM-SECURE -->
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | pass→pass | 10,978 | 7,187 | -35% | 1 | 1 | 0% | 2,220 | 3,543 | +60% | 0 | 0 | — |
case-01 | fail→fail | 12,651 | 7,479 | -41% | 1 | 1 | 0% | 2,672 | 3,749 | +40% | 0 | 0 | — |
case-02 | fail→pass | 13,782 | 10,122 | -27% | 1 | 1 | 0% | 2,900 | 4,297 | +48% | 0 | 0 | — |
case-03 | pass→pass | 11,544 | 6,392 | -45% | 1 | 1 | 0% | 2,541 | 3,484 | +37% | 0 | 0 | — |
case-04 | pass→pass | 10,848 | 4,963 | -54% | 1 | 1 | 0% | 2,167 | 3,115 | +44% | 0 | 0 | — |
case-06 | pass→pass | 13,207 | 9,361 | -29% | 1 | 1 | 0% | 2,844 | 4,276 | +50% | 0 | 0 | — |
case-07 | pass→pass | 12,333 | 5,621 | -54% | 1 | 1 | 0% | 2,489 | 3,375 | +36% | 0 | 0 | — |
case-08 | pass→pass | 12,690 | 6,116 | -52% | 1 | 1 | 0% | 2,449 | 3,403 | +39% | 0 | 0 | — |
case-09 | pass→pass | 14,576 | 10,634 | -27% | 1 | 1 | 0% | 2,755 | 4,291 | +56% | 0 | 0 | — |
case-10 | pass→pass | 8,429 | 4,032 | -52% | 1 | 1 | 0% | 1,195 | 2,837 | +137% | 0 | 0 | — |
case-11 | fail→fail | 13,636 | 10,222 | -25% | 1 | 1 | 0% | 2,916 | 4,391 | +51% | 0 | 0 | — |
case-12 | fail→fail | 19,608 | 14,493 | -26% | 1 | 1 | 0% | 3,670 | 4,966 | +35% | 0 | 0 | — |
case-13 | fail→fail | 15,232 | 12,297 | -19% | 1 | 1 | 0% | 3,060 | 4,680 | +53% | 0 | 0 | — |
case-14 | fail→fail | 7,812 | 6,348 | -19% | 1 | 1 | 0% | 1,547 | 3,401 | +120% | 0 | 0 | — |
case-15 | pass→pass | 2,750 | 2,327 | -15% | 1 | 1 | 0% | 455 | 2,512 | +452% | 0 | 0 | — |
case-16 | pass→pass | 2,642 | 2,472 | -6% | 1 | 1 | 0% | 450 | 2,528 | +462% | 0 | 0 | — |
case-17 | pass→pass | 2,841 | 1,887 | -34% | 1 | 1 | 0% | 518 | 2,523 | +387% | 0 | 0 | — |
case-18 | pass→pass | 5,128 | 3,041 | -41% | 1 | 1 | 0% | 790 | 2,633 | +233% | 0 | 0 | — |
case-19 | pass→pass | 8,751 | 3,208 | -63% | 1 | 1 | 0% | 1,851 | 2,735 | +48% | 0 | 0 | — |
case-20 | pass→pass | 8,766 | 4,919 | -44% | 1 | 1 | 0% | 1,633 | 3,113 | +91% | 0 | 0 | — |
case-21 | pass→pass | 12,091 | 3,686 | -70% | 1 | 1 | 0% | 2,263 | 2,894 | +28% | 0 | 0 | — |
case-22 | fail→pass | 13,096 | 3,814 | -71% | 1 | 1 | 0% | 2,300 | 2,805 | +22% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/24/2026 | +27% |
Other measured skills in the registry, with their headline benchmark lift.