Skip to content

Commit 5cd7dae

Browse files
lp698claude
andcommitted
Multi-oracle report: add missing noise-floor/p99 scale block (6ed117f gap)
Commit 6ed117f ("IGV normalization explanation: causal report + LegNet stub parity") fixed the causal report and LegNet stub but missed the multi-oracle report, which had its own terser IGV intro. Re-audit of the 4-part IGV contract across all 17 shipped HTMLs found rs12740374_SORT1_multioracle_report.html was missing 4/5 of the scale- explanation markers the other reports ship ("noise floor", "p95", "peak threshold", "rescaled using") — only "p99" appeared, in a different phrasing. ## What users saw Before: the multi-oracle IGV block said only "Signals are floor-rescaled to [0, 3.0] where 1.0 is the genome-wide p99 peak for that assay." No mention of the p95 noise floor or "top 1% of bins" framing that every single-oracle + causal report uses, so users opening the multi-oracle view in isolation got a less-explicit explanation than in the per-oracle reports. ## Fix chorus/analysis/multi_oracle_report.py:712-724 — split the existing single-paragraph intro into two paragraphs: the window/coverage caveat stays, plus the same "noise floor (p95) and peak threshold (p99)" block the single-oracle and causal reports emit. Future regenerations of the multi-oracle HTML will ship the new block automatically. Also hand-patched the shipped examples/walkthroughs/validation/SORT1_rs12740374_multioracle/rs12740374_SORT1_multioracle_report.html to insert the same paragraph at the matching location, since regenerating via scripts/regenerate_multioracle.py --consolidate would also rebuild the IGV section from scratch — but without the prediction pickles (not committed), that rebuild drops the IGV entirely. The hand-patch preserves the existing IGV tracks while adding the new explanation. ## 4-part audit result All 17 IGV-containing HTMLs now pass: - (a) IGV embedded — 17/17 - (b) ymax=3.0 signal tracks / 1.0 summary tracks — 17/17 consistent - (c) scale explanation (5/5 markers) — 17/17 (was 16/17) - (d) assay:cell_type track provenance — 17/17 (bare "SPLICE_SITES" labels on AlphaGenome donor/acceptor/padding tracks are correctly cell-type-agnostic per AG metadata) ## Known follow-up scripts/regenerate_multioracle.py --consolidate from committed JSONs silently drops the IGV section because the per-oracle prediction pickles aren't persisted. Either persist them or mark IGV-rebuild as requiring --oracle runs. Filed as a note; not blocking this fix. Tests: 339 passed / 1 skipped. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 6ed117f commit 5cd7dae

2 files changed

Lines changed: 12 additions & 3 deletions

File tree

chorus/analysis/multi_oracle_report.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -715,9 +715,17 @@ def _build_multioracle_html(report: "MultiOracleReport") -> str:
715715
"signal tracks on a single IGV. Default locus is the widest "
716716
"oracle's prediction window — narrower-window oracles show "
717717
"blank outside their coverage (expected: LegNet is ~200 bp "
718-
"and ChromBPNet ~1 kb while AlphaGenome reaches ±500 kb). "
719-
"Signals are floor-rescaled to [0, 3.0] where 1.0 is the "
720-
"genome-wide p99 peak for that assay.</p>"
718+
"and ChromBPNet ~1 kb while AlphaGenome reaches ±500 kb).</p>"
719+
)
720+
# Same scale-explanation block the single-oracle + causal reports
721+
# ship, so the meaning of the [0, 3.0] y-axis is spelled out
722+
# consistently across every IGV view chorus emits.
723+
p.append(
724+
"<p class='meta' style='margin-top:-.5rem'>Signal rescaled "
725+
"using each track's genome-wide noise floor (p95) and peak "
726+
"threshold (p99): <b>0</b> = noise floor, <b>1.0</b> = top "
727+
"1% of bins genome-wide. Peak shape preserved; tracks "
728+
"comparable across cell types.</p>"
721729
)
722730
p.append(igv_html)
723731

examples/walkthroughs/validation/SORT1_rs12740374_multioracle/rs12740374_SORT1_multioracle_report.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ <h2>Cross-oracle consensus</h2>
134134
</tbody></table>
135135
<h2>Cross-oracle genome browser</h2>
136136
<p class='meta'>All oracles' ref (grey) / alt (coloured) signal tracks on a single IGV. Default locus is the widest oracle's prediction window — narrower-window oracles show blank outside their coverage (expected: LegNet is ~200 bp and ChromBPNet ~1 kb while AlphaGenome reaches ±500 kb). Signals are floor-rescaled to [0, 3.0] where 1.0 is the genome-wide p99 peak for that assay.</p>
137+
<p class='meta' style='margin-top:-.5rem'>Signal rescaled using each track's genome-wide noise floor (p95) and peak threshold (p99): <b>0</b> = noise floor, <b>1.0</b> = top 1% of bins genome-wide. Peak shape preserved; tracks comparable across cell types.</p>
137138

138139
<div id="igv-multioracle" style="margin: 1rem 0; min-height: 400px;"></div>
139140
<script>!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).igv=t()}(this,(function(){"use strict";function e(e){return t("div",e)}function t(e,t){const i=document.createElement(e);return t&&(t.class&&i.classList.add(t.class),t.id&&(i.id=t.id),t.style&&function(e,t){for(let i of Object.keys(t))e.style[i]=t[i]}(i,t.style)),i}function i(e){const t=getComputedStyle(e);"none"!==t.display&&(e._initialDisplay=t.display),e.style.display="none"}function n(e){const t=e._initialDisplay||"block";e.style.display=t}function r(e){if(e.type.startsWith("touch")){const t=e.touches[0];return{x:t.pageX,y:t.pageY}}return{x:e.pageX,y:e.pageY}}function s(){return("0000"+(Math.random()*Math.pow(36,4)|0).toString(36)).slice(-4)}function o(e,t){const{clientX:i,clientY:n}=e;return((e,{clientX:t,clientY:i})=>{const{left:n,top:r,width:s,height:o}=e.getBoundingClientRect(),a=t-n,c=i-r;return{x:a,y:c,xNormalized:a/s,yNormalized:c/o,width:s,height:o}})(t,{clientX:i,clientY:n})}class a{constructor(){this.elem=t("div",{class:"igv-ui-panel-column"})}add(t){if(t instanceof Node)this.elem.append(t);else if("object"==typeof t)this.elem.append(t.elem);else{const i=e();i.innerHTML=t,this.elem.append(i),this.html=i}}}function c(e,t){return l(e,t)}function l(e,t){t=t||"currentColor";let i=h[e];i||(console.error(`No icon named: ${e}`),i=h.question);const n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttributeNS(null,"viewBox","0 0 "+i[0]+" "+i[1]);const r=document.createElementNS("http://www.w3.org/2000/svg","path");return r.setAttributeNS(null,"fill",t),r.setAttributeNS(null,"d",i[4]),n.appendChild(r),n}const h={check:[512,512,[],"f00c","M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"],cog:[512,512,[],"f013","M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"],exclamation:[192,512,[],"f12a","M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"],"exclamation-circle":[512,512,[],"f06a","M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],"exclamation-triangle":[576,512,[],"f071","M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],minus:[448,512,[],"f068","M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"],"minus-circle":[512,512,[],"f056","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"],"minus-square":[448,512,[],"f146","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"],plus:[448,512,[],"f067","M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"],"plus-circle":[512,512,[],"f055","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],"plus-square":[448,512,[],"f0fe","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],question:[384,512,[],"f128","M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"],save:[448,512,[],"f0c7","M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"],search:[512,512,[],"f002","M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"],share:[512,512,[],"f064","M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"],spinner:[512,512,[],"f110","M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"],square:[448,512,[],"f0c8","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"],"square-full":[512,512,[],"f45c","M512 512H0V0h512v512z"],times:[384,512,[],"f00d","M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"],"times-circle":[512,512,[],"f057","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"],wrench:[512,512,[],"f0ad","M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"]};function d(e,t){var i=document.createElement("div");e.appendChild(i),i.appendChild(c("times")),i.addEventListener("click",(function(e){e.preventDefault(),e.stopPropagation(),t()}))}let u;function f(e,t,i){t.addEventListener("mousedown",function(e){e.stopPropagation(),e.preventDefault();const t=p.bind(this),n=g.bind(this),r=getComputedStyle(this),s=this.getBoundingClientRect();u={constraint:i,dragFunction:t,dragEndFunction:n,screenX:e.screenX,screenY:e.screenY,minDy:-s.top,minDx:-s.left,top:parseInt(r.top.replace("px","")),left:parseInt(r.left.replace("px",""))},document.addEventListener("mousemove",t),document.addEventListener("mouseup",n),document.addEventListener("mouseleave",n),document.addEventListener("mouseexit",n)}.bind(e))}function p(e){if(!u)return void console.error("No drag data!");e.stopPropagation(),e.preventDefault();const t=Math.max(u.minDx,e.screenX-u.screenX),i=Math.max(u.minDy,e.screenY-u.screenY),n=u.left+t,r=u.top+i;this.style.left=`${n}px`,this.style.top=`${r}px`}function g(e){if(!u)return void console.error("No drag data!");e.stopPropagation(),e.preventDefault();const t=u.dragFunction,i=u.dragEndFunction;document.removeEventListener("mousemove",t),document.removeEventListener("mouseup",i),document.removeEventListener("mouseleave",i),document.removeEventListener("mouseexit",i),u=void 0}class m{constructor({parent:t,label:n,content:r,okHandler:s,cancelHandler:o}){this.parent=t;const a=()=>{i(this.elem),"function"==typeof o&&o(this)};this.elem=e(),this.elem.classList.add("igv-ui-generic-dialog-container","igv-ui-center-fixed");const c=e({class:"igv-ui-generic-dialog-header"});if(this.elem.appendChild(c),d(c,a),n){const t=e({class:"igv-ui-dialog-one-liner"});this.elem.appendChild(t),t.innerHTML=n}r.elem.style.margin="16px",this.elem.appendChild(r.elem),this.content=r;const l=e({class:"igv-ui-generic-dialog-ok-cancel"});this.elem.appendChild(l),this.ok=e(),l.appendChild(this.ok),this.ok.textContent="OK",this.cancel=e(),l.appendChild(this.cancel),this.cancel.textContent="Cancel",this.callback=void 0,this.ok.addEventListener("click",(e=>{i(this.elem),"function"==typeof s?s(this):this.callback&&"function"==typeof this.callback&&this.callback(this)})),this.cancel.addEventListener("click",a),f(this.elem,c),this.elem.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation()}))}present(e,t){if(e.label&&this.label&&(this.label.textContent=e.label),e.html){this.content.html.innerHTML=e.html}if(e.text){this.content.html.innerText=e.text}e.value&&this.input&&(this.input.value=e.value),e.callback&&(this.callback=e.callback),n(this.elem)}clampLocation(e,t){let i=this.elem.getBoundingClientRect(),n=this.parent.getBoundingClientRect();const r=Math.min(Math.max(t,n.y),n.y+n.height-i.height),s=Math.min(Math.max(e,n.x),n.x+n.width-i.width);this.elem.style.left=s+"px",this.elem.style.top=r+"px"}}

0 commit comments

Comments
 (0)