> ## Documentation Index
> Fetch the complete documentation index at: https://proto.evodesign.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Puffin

> Puffin is a sequence-based deep learning model for transcription initiation that predicts per-base initiation signal from DNA and decomposes the prediction into a small set of learned promoter motifs. This toolkit exposes a fast prediction path (`puffin-prediction`) and a gradient-based motif-decomposition path (`puffin-interpretation`) over the same checkpoint.

<div class="page-hero"><img class="page-hero-banner" src="https://proto-bio.github.io/proto-assets/images/tool/puffin/hero.png" alt="Puffin" /><div class="tool-org-badges page-hero-badges"><a href="/docs/tools/organizations/ut-southwestern-medical-center" class="tool-org-badge" style={{background: "#00659F"}} title="UT Southwestern Medical Center"><img src="https://mintcdn.com/bio-pro/UeudeF7pW-Dj-pIN/assets/images/cached/82d09f068327.jpg?fit=max&auto=format&n=UeudeF7pW-Dj-pIN&q=85&s=479067e64dd13953c310718deca3de58" alt="" class="tool-org-badge-logo" width="200" height="200" data-path="assets/images/cached/82d09f068327.jpg" /> UT Southwestern</a> <a href="/docs/tools/organizations/st-jude-children-s-research-hospital" class="tool-org-badge" style={{background: "#E31837"}} title="St. Jude Children's Research Hospital"><img src="https://mintcdn.com/bio-pro/UeudeF7pW-Dj-pIN/assets/images/cached/575f31e057f1.png?fit=max&auto=format&n=UeudeF7pW-Dj-pIN&q=85&s=255e24df50e55bd2375b7633d7cd74aa" alt="" class="tool-org-badge-logo" width="200" height="200" data-path="assets/images/cached/575f31e057f1.png" /> St. Jude</a></div></div>

<Note>
  **License:** Puffin is licensed under Custom (UTSW Academic Software License) and has restrictions around commercial use and may require explicit attribution when utilized. Please refer to [the license](https://github.com/jzhoulab/puffin/blob/main/LICENSE) for full terms.
</Note>

<p class="entity-disclaimer">Proto is not affiliated with UT Southwestern Medical Center and St. Jude Children's Research Hospital. This toolkit is open source and builds on the implementations produced by these organizations. Product names, logos, and trademarks are the property of their respective owners.</p>

<hr class="entity-rule" />

<input type="radio" name="tab-puffin" id="none-puffin" class="tab-radio-input" />

<input type="radio" name="tab-puffin" id="github-puffin" class="tab-radio-input" defaultChecked />

<input type="radio" name="tab-puffin" id="website-puffin" class="tab-radio-input" />

<input type="radio" name="tab-puffin" id="paper-puffin" class="tab-radio-input" />

<input type="radio" name="tab-puffin" id="preprint-puffin" class="tab-radio-input" />

<input type="radio" name="tab-puffin" id="cite-puffin" class="tab-radio-input" />

<input type="radio" name="tab-puffin" id="source-puffin" class="tab-radio-input" />

<input type="radio" name="tab-puffin" id="notebook-puffin" class="tab-radio-input" />

<input type="radio" name="tab-puffin" id="proto-puffin" class="tab-radio-input" />

<div class="tool-tab-bar">
  <span class="tool-tab-wrap"><label for="github-puffin" class="tool-tab tab-open badge-github"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> GitHub</label><label for="none-puffin" class="tool-tab tab-close badge-github"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> GitHub</label></span> <span class="tool-tab-wrap"><label for="website-puffin" class="tool-tab tab-open badge-website"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg> Website</label><label for="none-puffin" class="tool-tab tab-close badge-website"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg> Website</label></span> <span class="tool-tab-wrap"><label for="paper-puffin" class="tool-tab tab-open badge-paper"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Publication</label><label for="none-puffin" class="tool-tab tab-close badge-paper"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Publication</label></span> <span class="tool-tab-wrap"><label for="preprint-puffin" class="tool-tab tab-open badge-preprint"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Preprint</label><label for="none-puffin" class="tool-tab tab-close badge-preprint"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Preprint</label></span> <span class="tool-tab-wrap"><label for="cite-puffin" class="tool-tab tab-open badge-cite"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" /><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" /></svg> Cite</label><label for="none-puffin" class="tool-tab tab-close badge-cite"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" /><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" /></svg> Cite</label></span> <span class="tool-tab-wrap"><label for="source-puffin" class="tool-tab tab-open badge-source"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Tool Source</label><label for="none-puffin" class="tool-tab tab-close badge-source"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Tool Source</label></span> <span class="tool-tab-wrap"><label for="notebook-puffin" class="tool-tab tab-open badge-notebook"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg> Open as Notebook</label><label for="none-puffin" class="tool-tab tab-close badge-notebook"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg> Open as Notebook</label></span> <span class="tool-tab-wrap"><label for="proto-puffin" class="tool-tab tab-open badge-local"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5" /><line x1="12" y1="19" x2="20" y2="19" /></svg> Run Locally</label><label for="none-puffin" class="tool-tab tab-close badge-local"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5" /><line x1="12" y1="19" x2="20" y2="19" /></svg> Run Locally</label></span>
</div>

<a href="https://github.com/jzhoulab/puffin" target="_blank" class="tab-panel github-panel" data-tab="github-puffin">
  <div class="gh-card-wrap">
    <img src="https://opengraph.githubassets.com/1/jzhoulab/puffin" class="gh-card-img img-fallback" alt="jzhoulab/puffin" />

    <div class="gh-card-fallback">
      <div class="gh-fallback-org"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> jzhoulab/puffin</div>
    </div>
  </div>

  <span class="panel-goto-btn gh-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> View repo</span></span>
</a>

<a href="https://puffin.zhoulab.io" target="_blank" class="tab-panel website-panel" data-tab="website-puffin">
  <div class="website-info">
    <img src="https://www.google.com/s2/favicons?domain=puffin.zhoulab.io&sz=32" class="website-favicon" width="24" height="24" />

    <span class="website-url">puffin.zhoulab.io</span>
  </div>

  <span class="panel-goto-btn website-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg> Visit website</span></span>
</a>

<a href="https://doi.org/10.1126/science.adj0116" target="_blank" class="tab-panel paper-panel" data-tab="paper-puffin">
  <div class="paper-info">
    <div class="paper-title">Sequence basis of transcription initiation in the human genome</div>
    <div class="paper-meta">Kseniia Dudnyk, Donghong Cai, ... Jian Zhou</div>
    <div class="paper-meta paper-venue">Science (2024)</div>
  </div>

  <span class="panel-goto-btn pub-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Read paper</span></span>
</a>

<a href="https://doi.org/10.1101/2023.06.27.546584" target="_blank" class="tab-panel preprint-panel" data-tab="preprint-puffin">
  <div class="paper-info">
    <div class="paper-title">Sequence basis of transcription initiation in human genome</div>
    <div class="paper-meta">Kseniia Dudnyk, Chenlai Shi and Jian Zhou</div>
    <div class="paper-meta paper-venue">bioRxiv (2023)</div>
  </div>

  <span class="panel-goto-btn preprint-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Read preprint</span></span>
</a>

<div class="tab-panel cite-panel" data-tab="cite-puffin">
  <div class="cite-code-wrap">
    ```bibtex theme={null}
    @article{dudnyk2024puffin,
      title={Sequence basis of transcription initiation in the human genome},
      author={Dudnyk, Kseniia and Cai, Donghong and Shi, Chenlai and Xu, Jian and Zhou, Jian},
      journal={Science},
      volume={384},
      number={6694},
      year={2024},
      publisher={American Association for the Advancement of Science},
      doi={10.1126/science.adj0116},
      url={https://www.science.org/doi/10.1126/science.adj0116}
    }
    ```
  </div>

  <span class="panel-goto-btn cite-copy-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" /><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" /></svg> Copy citation</span></span>
</div>

<a href="https://github.com/evo-design/proto-tools/tree/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/sequence_scoring/puffin" target="_blank" class="tab-panel source-panel" data-tab="source-puffin">
  <div class="source-info">
    <img src="https://github.com/evo-design.png?size=40" class="source-avatar" width="36" height="36" />

    <span class="source-path">evo-design/proto-tools<span class="source-subpath">/proto\_tools/tools/sequence\_scoring/puffin</span></span>
  </div>

  <span class="panel-goto-btn source-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> View source</span></span>
</a>

<a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/sequence_scoring/puffin/examples/example.ipynb" target="_blank" class="tab-panel notebook-panel" data-tab="notebook-puffin">
  <div class="notebook-info">
    <span class="notebook-icon">
      <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
        <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />

        <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
      </svg>
    </span>

    <span class="notebook-label">Open Notebook</span>
  </div>

  <span class="panel-goto-btn notebook-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg> Open notebook</span></span>
</a>

<div class="tab-panel proto-panel run-local-panel" data-tab="proto-puffin">
  <a href="https://github.com/evo-design/proto-tools" target="_blank" class="run-local-preview">
    <img noZoom src="https://opengraph.githubassets.com/1/evo-design/proto-tools" alt="proto-tools on GitHub" />
  </a>

  <div class="run-local-install">
    <span class="run-local-label">Run locally with proto-tools</span>

    <div class="run-local-code">
      ```bash theme={null}
      pip install git+https://github.com/evo-design/proto-tools.git
      ```
    </div>
  </div>
</div>

<div class="entity-contributors"><span class="entity-contributors-label">Toolkit contributors</span><span class="entity-contributors-people"><a class="entity-contributor" href="https://github.com/bviggiano" target="_blank" rel="noopener" title="bviggiano: 7 commits"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/21143637?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">bviggiano</span></a><a class="entity-contributor" href="https://github.com/dguo8412" target="_blank" rel="noopener" title="dguo8412: 3 commits"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/46211285?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">dguo8412</span></a><a class="entity-contributor" href="https://github.com/adititm" target="_blank" rel="noopener" title="adititm: 2 commits"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/61667248?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">adititm</span></a><a class="entity-contributor" href="https://github.com/leba01" target="_blank" rel="noopener" title="leba01: 1 commit"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/124846286?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">leba01</span></a></span></div>

| Function                      | Description                                                               |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ----------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `run_puffin_interpretation()` | Motif-level interpretation of transcription initiation with Puffin (GPU)  | <a href="#api-run-puffin-interpretation" class="func-table-btn func-api-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20" /></svg> Docs</a> <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/sequence_scoring/puffin/puffin_interpretation.py#L357" target="_blank" class="func-table-btn func-source-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a> |
| `run_puffin_prediction()`     | Basepair-resolution transcription initiation prediction with Puffin (GPU) | <a href="#api-run-puffin-prediction" class="func-table-btn func-api-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20" /></svg> Docs</a> <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/sequence_scoring/puffin/puffin_prediction.py#L252" target="_blank" class="func-table-btn func-source-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>         |

## Background

In 2024, [Dudnyk et al.](https://doi.org/10.1126/science.adj0116) introduced Puffin, a deep learning model that explains transcription initiation in the human genome at basepair resolution from sequence alone. The model is trained against five [transcription initiation](https://en.wikipedia.org/wiki/Transcription_\(biology\)) assays (FANTOM CAGE, ENCODE CAGE, ENCODE RAMPAGE, GRO-cap, PRO-cap), each predicted on both strands. The output is a per-base 10-channel signal that can be interpreted as `ln(count_scale_signal + 1)`.

Puffin is structurally constrained: its first convolutional layer plays the role of a learned [motif](https://en.wikipedia.org/wiki/Sequence_motif) filter bank, and the model exposes per-base activation and contribution scores for nine promoter motifs (CREB, ETS, NFY, NRF1, SP, TATA, U1\_snRNP, YY1, ZNF143) on each strand. A tenth `Long Inr` filter is used internally by the model to construct the per-base initiator-effect track but is not exposed per-motif. The minimum input is 651 bp because the model uses 325 bp of padding on each side of the predicted output span.

The wrapper accepts raw DNA strings; the upstream coordinate / region / FASTA-file CLI modes (which require an hg38 reference) are intentionally not exposed and callers extract genomic sequences themselves.

## Tools

<a name="api-run-puffin-prediction" />

<div class="tool-section-card tool-section-card--predict">
  ### Puffin Prediction (`puffin-prediction`)

  Runs a single forward pass through Puffin and returns per-base predictions across all 10 transcription-initiation channels (5 assays × 2 strands) at single-base resolution.

  #### API Reference

  <div class="api-model-section api-input-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/sequence_scoring/puffin/puffin_prediction.py#L45" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Input: PuffinPredictionInput">
      <ParamField path="sequences" type="List[string]" required>
        DNA sequence(s) at least 651 bp long. A single string is normalized to a one-item list. Only `A`, `C`, `G`, `T`, `N` are accepted.
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-config-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/sequence_scoring/puffin/puffin_prediction.py#L136" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Config: PuffinPredictionConfig">
      <ParamField path="verbose" type="integer" default="0">
        Verbosity level (0=quiet, 1=info, 2=debug, 3=raw subprocess stderr). `True` is coerced to `1` and `False` to `0`.
      </ParamField>

      <ParamField path="device" type="string" default="cuda">
        Device used for inference.
      </ParamField>

      <ParamField path="timeout" type="integer" default="3600">
        Maximum execution time in seconds. `None` waits indefinitely.
      </ParamField>

      <ParamField path="seed" type="integer">
        Random seed. When set, tools run reproducibly up to small GPU float noise (see `BaseToolOutput.approx_equal`), and the seed participates in cache keys. When None, cacheable seed-sensitive tools skip cache until seeded.
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-output-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/sequence_scoring/puffin/puffin_prediction.py#L151" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Output: PuffinPredictionOutput">
      <ResponseField name="results" type="List[PuffinPredictionResult]" required>
        Per-sequence prediction results.

        <Expandable title="PuffinPredictionResult">
          <ResponseField name="sequence" type="string" required>
            Input DNA sequence that was scored.
          </ResponseField>

          <ResponseField name="sequence_length" type="integer" required>
            Length of the input sequence.
          </ResponseField>

          <ResponseField name="output_length" type="integer" required>
            Number of per-base output positions (= `sequence_length - 650`).
          </ResponseField>

          <ResponseField name="output_start" type="integer" required>
            0-based sequence coordinate of the first per-base output position (always `325`).
          </ResponseField>

          <ResponseField name="output_end" type="integer" required>
            0-based exclusive end of the per-base output span in the input sequence (= `sequence_length - 325`).
          </ResponseField>

          <ResponseField name="predictions" type="List[array]" required>
            Per-base predictions with shape `[output_length, 10]`. Channel order matches `TRACK_NAMES`.
          </ResponseField>
        </Expandable>
      </ResponseField>

      <ResponseField name="track_names" type="List[string]" required>
        Names of the 10 output channels in order.
      </ResponseField>
    </Accordion>
  </div>

  #### Applications

  Use this tool to score transcription start sites, rank candidate promoters, or measure the per-base effect of variants and edits across five capped-5'-end assays in one call. The fast path is the right choice when the question is *how much* signal a sequence produces rather than *why*.

  #### Usage Tips

  * **Per-base output length is `len(sequence) - 650`.** The model uses 325 bp of padding on each side; output coordinates run from 325 to `len(sequence) - 325` in the input frame.
  * **Channel order is mirrored across strands.** The first 5 channels are FANTOM\_CAGE+ → PRO\_CAP+; the next 5 are PRO\_CAP- → FANTOM\_CAGE-. Index by name via `TRACK_NAMES.index(...)` rather than memorizing positions.
  * **Outputs are in log scale.** Treat predicted values as `ln(count_scale_signal + 1)`. To compare two sequences, subtract — the difference is already in log space.

  <a name="api-run-puffin-interpretation" />
</div>

<div class="tool-section-card">
  ### Puffin Interpretation (`puffin-interpretation`)

  Runs Puffin's gradient-based decomposition for one chosen target assay and strand. Returns the per-base prediction for that target, 18 motif-activation tracks, 18 motif-effect tracks, and per-base basepair-contribution scores both as an aggregate and decomposed two ways (contribution to the predicted signal per motif, and contribution to each motif's activation per basepair; 18 tracks each). Summed motif, initiator, trinucleotide, and total-effect tracks are also returned.

  #### API Reference

  <div class="api-model-section api-input-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/sequence_scoring/puffin/puffin_interpretation.py#L44" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Input: PuffinInterpretationInput">
      <ParamField path="sequences" type="List[string]" required>
        DNA sequence(s) at least 651 bp long. A single string is normalized to a one-item list. Only `A`, `C`, `G`, `T`, `N` are accepted.
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-config-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/sequence_scoring/puffin/puffin_interpretation.py#L189" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Config: PuffinInterpretationConfig">
      <ParamField path="target_signal" type="enum" default="FANTOM_CAGE">
        Which transcription initiation assay's predictions to decompose into motif and basepair contributions.

        Available options: `FANTOM_CAGE`, `ENCODE_CAGE`, `ENCODE_RAMPAGE`, `GRO_CAP`, `PRO_CAP`
      </ParamField>

      <ParamField path="reverse_strand" type="boolean" default="False">
        If `True`, decompose the reverse-strand prediction for the chosen target instead of the forward strand.
      </ParamField>

      <ParamField path="verbose" type="integer" default="0">
        Verbosity level (0=quiet, 1=info, 2=debug, 3=raw subprocess stderr). `True` is coerced to `1` and `False` to `0`.
      </ParamField>

      <ParamField path="device" type="string" default="cuda">
        Device used for inference.
      </ParamField>

      <ParamField path="timeout" type="integer" default="3600">
        Maximum execution time in seconds. `None` waits indefinitely.
      </ParamField>

      <ParamField path="seed" type="integer">
        Random seed. When set, tools run reproducibly up to small GPU float noise (see `BaseToolOutput.approx_equal`), and the seed participates in cache keys. When None, cacheable seed-sensitive tools skip cache until seeded.
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-output-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/sequence_scoring/puffin/puffin_interpretation.py#L219" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Output: PuffinInterpretationOutput">
      <ResponseField name="results" type="List[PuffinInterpretationResult]" required>
        Per-sequence interpretation results.

        <Expandable title="PuffinInterpretationResult">
          <ResponseField name="sequence" type="string" required>
            Input DNA sequence that was scored.
          </ResponseField>

          <ResponseField name="sequence_length" type="integer" required>
            Length of the input sequence.
          </ResponseField>

          <ResponseField name="output_length" type="integer" required>
            Number of per-base output positions (= `sequence_length - 650`).
          </ResponseField>

          <ResponseField name="output_start" type="integer" required>
            0-based sequence coordinate of the first per-base output position (always `325`).
          </ResponseField>

          <ResponseField name="output_end" type="integer" required>
            0-based exclusive end of the per-base output span in the input sequence (= `sequence_length - 325`).
          </ResponseField>

          <ResponseField name="prediction" type="List[number]" required>
            Predicted transcription initiation signal for the selected `target_signal` and strand, length `output_length`.
          </ResponseField>

          <ResponseField name="motif_activations" type="Dict[string, List[number]]" required>
            Per-base motif activation scores keyed by strand-suffixed motif name (e.g. `"TATA+"`).
          </ResponseField>

          <ResponseField name="motif_effects" type="Dict[string, List[number]]" required>
            Per-base motif effect scores keyed by strand-suffixed motif name.
          </ResponseField>

          <ResponseField name="sum_motif_effects" type="List[number]" required>
            Per-base sum of motif effects across non-initiator motifs.
          </ResponseField>

          <ResponseField name="sum_initiator_effects" type="List[number]" required>
            Per-base sum of initiator-motif effects (centered to zero mean).
          </ResponseField>

          <ResponseField name="sum_trinucleotide_effects" type="List[number]" required>
            Per-base sum of trinucleotide sequence effects (centered to zero mean).
          </ResponseField>

          <ResponseField name="sum_total_effects" type="List[number]" required>
            Per-base sum of all sequence pattern effects (motif + initiator + trinucleotide).
          </ResponseField>

          <ResponseField name="bp_contribution" type="List[number]" required>
            Per-base contribution score to transcription initiation at the target.
          </ResponseField>

          <ResponseField name="bp_contribution_per_motif" type="Dict[string, List[number]]" required>
            Per-base contribution to transcription, decomposed by motif name.
          </ResponseField>

          <ResponseField name="bp_contribution_to_motif_activation" type="Dict[string, List[number]]" required>
            Per-base contribution to motif-activation scores, decomposed by motif name.
          </ResponseField>
        </Expandable>
      </ResponseField>

      <ResponseField name="target_signal" type="string" required>
        Target signal selected for interpretation.
      </ResponseField>

      <ResponseField name="reverse_strand" type="boolean" required>
        Whether the reverse-strand head was used.
      </ResponseField>

      <ResponseField name="motif_names" type="List[string]" required>
        The 9 learned motif names (without strand suffix) exposed in the per-motif tracks. Strand-suffixed names appear as keys in each result's motif-keyed dicts.
      </ResponseField>
    </Accordion>
  </div>

  #### Applications

  Use this tool to ask which motif drives a transcription start site, how a variant changes a motif activation, or how initiator and trinucleotide context shape the predicted signal. It is substantially slower than `puffin-prediction` because it computes per-base gradient contributions, so reach for it for mechanistic follow-up on specific sequences rather than for bulk scoring.

  #### Usage Tips

  * **`target_signal` picks which assay's prediction is decomposed.** Choose the one closest to the biological question; CAGE/RAMPAGE measure capped mRNA 5' ends, while GRO-cap/PRO-cap measure nascent transcription.
  * **`reverse_strand` selects which strand head to interpret.** Defaults to forward; run it twice on the same input to analyze divergent or antisense promoters.
  * **Motif dicts use strand-suffixed keys.** Access `motif_activations["TATA+"]` and `motif_activations["TATA-"]`, never the bare motif name. `MOTIF_NAMES` lists the 9 motif stems.
</div>

## Toolkit Notes

These apply to every Puffin tool in this toolkit (`puffin-prediction`, `puffin-interpretation`).

* **GPU recommended but not required.** Both tools run on CPU; `puffin-interpretation` is materially slower than `puffin-prediction` on either device because it backpropagates through every output position and motif.
* **Sequence input only.** The upstream CLI's coordinate / region / FASTA-file modes require an `hg38.fa` reference and are intentionally not wrapped; callers extract DNA themselves and pass it as a string.
* **Both tools share one persistent worker.** They dispatch against the same `puffin` toolkit and load the Puffin model once per worker process; switching between prediction and interpretation does not reload weights.

<Tip>
  **Example notebook:** See the [full working example](https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/sequence_scoring/puffin/examples/example.ipynb) for a copy-paste-ready walkthrough.
</Tip>

## Infrastructure Guides

The following guides cover how to run tools efficiently and at scale.

<CardGroup cols={2}>
  <Card title="Tool Persistence" icon="repeat" href="/docs/tools/guides/tool-persistence">Keep a tool's model warm across calls instead of reloading it every invocation.</Card>
  <Card title="Device Management" icon="cpu" href="/docs/tools/guides/device-management">How GPUs are allocated to tools and how to target specific devices.</Card>
  <Card title="Parallel Execution" icon="layers" href="/docs/tools/guides/parallel-execution">Fan a batch of inputs out across multiple GPUs.</Card>
</CardGroup>

## Additional Information

<AccordionGroup>
  <Accordion title="References">
    * Dudnyk, K., Cai, D., Shi, C., Xu, J., Zhou, J. Sequence basis of transcription initiation in the human genome. *Science* 384, eadj0116 (2024). DOI: [10.1126/science.adj0116](https://doi.org/10.1126/science.adj0116)
    * Upstream repository: [jzhoulab/puffin](https://github.com/jzhoulab/puffin)
  </Accordion>
</AccordionGroup>
