@jbrowse/render-core 5.0.0-beta.1 → 5.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. package/esm/RenderCanvas.d.ts +2 -2
  2. package/esm/RenderLifecycleMixin.d.ts +52 -20
  3. package/esm/RenderLifecycleMixin.js +89 -23
  4. package/esm/canvas2dUtils.d.ts +90 -23
  5. package/esm/canvas2dUtils.js +119 -36
  6. package/esm/colorRampLut.d.ts +5 -5
  7. package/esm/colorRampLut.js +6 -6
  8. package/esm/computePipeline.d.ts +14 -0
  9. package/esm/computePipeline.js +62 -0
  10. package/esm/contractReports.d.ts +54 -0
  11. package/esm/contractReports.js +112 -0
  12. package/esm/coverageBand.d.ts +13 -8
  13. package/esm/coverageBand.js +15 -5
  14. package/esm/coverageBandBuffers.d.ts +2 -9
  15. package/esm/coverageBandBuffers.js +1 -13
  16. package/esm/createRenderingBackend.d.ts +14 -18
  17. package/esm/createRenderingBackend.js +4 -2
  18. package/esm/displayPhase.d.ts +83 -104
  19. package/esm/displayPhase.js +42 -82
  20. package/esm/encodeMemo.d.ts +14 -0
  21. package/esm/encodeMemo.js +48 -0
  22. package/esm/gpuContextLostError.d.ts +30 -0
  23. package/esm/gpuContextLostError.js +40 -0
  24. package/esm/gpuDevice.d.ts +29 -10
  25. package/esm/gpuDevice.js +35 -16
  26. package/esm/graphicsCapabilities.d.ts +27 -19
  27. package/esm/graphicsCapabilities.js +40 -18
  28. package/esm/hal/createHal.d.ts +4 -5
  29. package/esm/hal/createHal.js +14 -4
  30. package/esm/hal/deviceGpuCache.d.ts +25 -30
  31. package/esm/hal/deviceGpuCache.js +88 -97
  32. package/esm/hal/gpuHalBase.d.ts +5 -4
  33. package/esm/hal/gpuHalBase.js +25 -14
  34. package/esm/hal/index.d.ts +2 -2
  35. package/esm/hal/index.js +1 -1
  36. package/esm/hal/mockHal.d.ts +15 -10
  37. package/esm/hal/mockHal.js +31 -18
  38. package/esm/hal/oomReporter.d.ts +7 -0
  39. package/esm/hal/oomReporter.js +10 -0
  40. package/esm/hal/passIds.d.ts +8 -7
  41. package/esm/hal/passIds.js +11 -10
  42. package/esm/hal/regionRegistry.d.ts +0 -1
  43. package/esm/hal/regionRegistry.js +3 -15
  44. package/esm/hal/types.d.ts +55 -18
  45. package/esm/hal/webgl2Hal.d.ts +23 -6
  46. package/esm/hal/webgl2Hal.js +161 -155
  47. package/esm/hal/webgpuHal.d.ts +29 -13
  48. package/esm/hal/webgpuHal.js +221 -153
  49. package/esm/installUpload.d.ts +16 -3
  50. package/esm/installUpload.js +13 -41
  51. package/esm/instanceCache.d.ts +10 -7
  52. package/esm/instanceCache.js +14 -15
  53. package/esm/instancePass.d.ts +2 -1
  54. package/esm/mapUploadSync.d.ts +2 -10
  55. package/esm/mapUploadSync.js +2 -3
  56. package/esm/marks/barMark.d.ts +30 -0
  57. package/esm/marks/barMark.js +149 -0
  58. package/esm/marks/colorFill.d.ts +17 -0
  59. package/esm/marks/colorFill.js +26 -0
  60. package/esm/marks/drawAgainstHit.d.ts +113 -0
  61. package/esm/marks/drawAgainstHit.js +407 -0
  62. package/esm/marks/ellipseDistance.d.ts +10 -0
  63. package/esm/marks/ellipseDistance.js +136 -0
  64. package/esm/marks/glyphPaint.d.ts +36 -0
  65. package/esm/marks/glyphPaint.js +77 -0
  66. package/esm/marks/index.d.ts +33 -0
  67. package/esm/marks/index.js +20 -0
  68. package/esm/marks/lineMark.d.ts +37 -0
  69. package/esm/marks/lineMark.js +416 -0
  70. package/esm/marks/linkMark.d.ts +76 -0
  71. package/esm/marks/linkMark.js +585 -0
  72. package/esm/marks/markBackend.d.ts +118 -0
  73. package/esm/marks/markBackend.js +196 -0
  74. package/esm/marks/markHit.d.ts +32 -0
  75. package/esm/marks/markHit.js +61 -0
  76. package/esm/marks/markInk.d.ts +18 -0
  77. package/esm/marks/markInk.js +71 -0
  78. package/esm/marks/markPaint.d.ts +14 -0
  79. package/esm/marks/markPaint.js +32 -0
  80. package/esm/marks/markPlan.d.ts +25 -0
  81. package/esm/marks/markPlan.js +20 -0
  82. package/esm/marks/markRamp.d.ts +72 -0
  83. package/esm/marks/markRamp.js +197 -0
  84. package/esm/marks/nearestMarkHit.d.ts +55 -0
  85. package/esm/marks/nearestMarkHit.js +158 -0
  86. package/esm/marks/pathRecorder.d.ts +14 -0
  87. package/esm/marks/pathRecorder.js +80 -0
  88. package/esm/marks/pointMark.d.ts +42 -0
  89. package/esm/marks/pointMark.js +125 -0
  90. package/esm/marks/rowLane.d.ts +39 -0
  91. package/esm/marks/rowLane.js +41 -0
  92. package/esm/marks/rowSpanIndex.d.ts +29 -0
  93. package/esm/marks/rowSpanIndex.js +141 -0
  94. package/esm/marks/rowTable.d.ts +41 -0
  95. package/esm/marks/rowTable.js +75 -0
  96. package/esm/marks/ruleMark.d.ts +21 -0
  97. package/esm/marks/ruleMark.js +91 -0
  98. package/esm/marks/spanMark.d.ts +42 -0
  99. package/esm/marks/spanMark.js +81 -0
  100. package/esm/marks/types.d.ts +261 -0
  101. package/esm/marks/types.js +175 -0
  102. package/esm/marks/valueScale.d.ts +23 -0
  103. package/esm/marks/valueScale.js +11 -0
  104. package/esm/namedReactions.d.ts +3 -4
  105. package/esm/namedReactions.js +3 -4
  106. package/esm/perRegionRenderingBackend.d.ts +21 -3
  107. package/esm/perRegionRenderingBackend.js +37 -3
  108. package/esm/regionDataMap.d.ts +2 -2
  109. package/esm/regionDataMap.js +25 -23
  110. package/esm/renderBlock.d.ts +14 -0
  111. package/esm/renderBlock.js +25 -0
  112. package/esm/renderingBackendBase.d.ts +20 -14
  113. package/esm/renderingBackendBase.js +12 -7
  114. package/esm/scoreScale.d.ts +27 -0
  115. package/esm/scoreScale.js +88 -0
  116. package/esm/shaders/barMark.generated.d.ts +3 -0
  117. package/esm/shaders/barMark.generated.js +7 -0
  118. package/esm/shaders/barMark.glsl.generated.d.ts +2 -0
  119. package/esm/shaders/barMark.glsl.generated.js +4 -0
  120. package/esm/shaders/barMark.iface.generated.d.ts +90 -0
  121. package/esm/shaders/barMark.iface.generated.js +205 -0
  122. package/esm/shaders/barMark.wgsl.generated.d.ts +1 -0
  123. package/esm/shaders/barMark.wgsl.generated.js +3 -0
  124. package/esm/shaders/capsule.js.generated.d.ts +1 -0
  125. package/esm/shaders/capsule.js.generated.js +11 -0
  126. package/esm/shaders/clipStrip.generated.d.ts +2 -0
  127. package/esm/shaders/clipStrip.generated.js +4 -0
  128. package/esm/shaders/clipStrip.js.generated.d.ts +1 -0
  129. package/esm/shaders/clipStrip.js.generated.js +21 -0
  130. package/esm/shaders/colorRampLut.js.generated.d.ts +1 -0
  131. package/esm/shaders/colorRampLut.js.generated.js +17 -0
  132. package/esm/shaders/coverageBar.generated.d.ts +2 -3
  133. package/esm/shaders/coverageBar.generated.js +4 -3
  134. package/esm/shaders/coverageBar.glsl.generated.d.ts +2 -0
  135. package/esm/shaders/coverageBar.glsl.generated.js +4 -0
  136. package/esm/shaders/coverageBar.iface.generated.js +1 -1
  137. package/esm/shaders/coverageBar.wgsl.generated.d.ts +1 -0
  138. package/esm/shaders/coverageBar.wgsl.generated.js +3 -0
  139. package/esm/shaders/coverageClip.generated.d.ts +3 -0
  140. package/esm/shaders/coverageClip.generated.js +7 -0
  141. package/esm/shaders/coverageClip.glsl.generated.d.ts +2 -0
  142. package/esm/shaders/coverageClip.glsl.generated.js +4 -0
  143. package/esm/shaders/coverageClip.iface.generated.d.ts +85 -0
  144. package/esm/shaders/coverageClip.iface.generated.js +114 -0
  145. package/esm/shaders/coverageClip.wgsl.generated.d.ts +1 -0
  146. package/esm/shaders/coverageClip.wgsl.generated.js +3 -0
  147. package/esm/shaders/coverageIndicator.generated.d.ts +2 -3
  148. package/esm/shaders/coverageIndicator.generated.js +4 -3
  149. package/esm/shaders/coverageIndicator.glsl.generated.d.ts +2 -0
  150. package/esm/shaders/coverageIndicator.glsl.generated.js +4 -0
  151. package/esm/shaders/coverageIndicator.iface.generated.js +1 -1
  152. package/esm/shaders/coverageIndicator.wgsl.generated.d.ts +1 -0
  153. package/esm/shaders/coverageIndicator.wgsl.generated.js +3 -0
  154. package/esm/shaders/coverageInterbase.generated.d.ts +2 -3
  155. package/esm/shaders/coverageInterbase.generated.js +4 -3
  156. package/esm/shaders/coverageInterbase.glsl.generated.d.ts +2 -0
  157. package/esm/shaders/coverageInterbase.glsl.generated.js +4 -0
  158. package/esm/shaders/coverageInterbase.iface.generated.js +1 -1
  159. package/esm/shaders/coverageInterbase.wgsl.generated.d.ts +1 -0
  160. package/esm/shaders/coverageInterbase.wgsl.generated.js +3 -0
  161. package/esm/shaders/coverageMod.generated.d.ts +2 -3
  162. package/esm/shaders/coverageMod.generated.js +4 -3
  163. package/esm/shaders/coverageMod.glsl.generated.d.ts +2 -0
  164. package/esm/shaders/coverageMod.glsl.generated.js +4 -0
  165. package/esm/shaders/coverageMod.iface.generated.js +1 -1
  166. package/esm/shaders/coverageMod.wgsl.generated.d.ts +1 -0
  167. package/esm/shaders/coverageMod.wgsl.generated.js +3 -0
  168. package/esm/shaders/coverageSnp.generated.d.ts +2 -3
  169. package/esm/shaders/coverageSnp.generated.js +4 -3
  170. package/esm/shaders/coverageSnp.glsl.generated.d.ts +2 -0
  171. package/esm/shaders/coverageSnp.glsl.generated.js +4 -0
  172. package/esm/shaders/coverageSnp.iface.generated.js +1 -1
  173. package/esm/shaders/coverageSnp.wgsl.generated.d.ts +1 -0
  174. package/esm/shaders/coverageSnp.wgsl.generated.js +3 -0
  175. package/esm/shaders/curveDistance.js.generated.d.ts +5 -0
  176. package/esm/shaders/curveDistance.js.generated.js +87 -0
  177. package/esm/shaders/hpmath.js.generated.d.ts +2 -1
  178. package/esm/shaders/hpmath.js.generated.js +5 -2
  179. package/esm/shaders/lineCenterMark.generated.d.ts +3 -0
  180. package/esm/shaders/lineCenterMark.generated.js +7 -0
  181. package/esm/shaders/lineCenterMark.glsl.generated.d.ts +2 -0
  182. package/esm/shaders/lineCenterMark.glsl.generated.js +4 -0
  183. package/esm/shaders/lineCenterMark.iface.generated.d.ts +104 -0
  184. package/esm/shaders/lineCenterMark.iface.generated.js +237 -0
  185. package/esm/shaders/lineCenterMark.wgsl.generated.d.ts +1 -0
  186. package/esm/shaders/lineCenterMark.wgsl.generated.js +3 -0
  187. package/esm/shaders/lineCommon.generated.d.ts +2 -0
  188. package/esm/shaders/lineCommon.generated.js +4 -0
  189. package/esm/shaders/lineStepMark.generated.d.ts +3 -0
  190. package/esm/shaders/lineStepMark.generated.js +7 -0
  191. package/esm/shaders/lineStepMark.glsl.generated.d.ts +2 -0
  192. package/esm/shaders/lineStepMark.glsl.generated.js +4 -0
  193. package/esm/shaders/lineStepMark.iface.generated.d.ts +98 -0
  194. package/esm/shaders/lineStepMark.iface.generated.js +225 -0
  195. package/esm/shaders/lineStepMark.wgsl.generated.d.ts +1 -0
  196. package/esm/shaders/lineStepMark.wgsl.generated.js +3 -0
  197. package/esm/shaders/linkMark.consts.generated.d.ts +14 -0
  198. package/esm/shaders/linkMark.consts.generated.js +16 -0
  199. package/esm/shaders/linkMark.generated.d.ts +4 -0
  200. package/esm/shaders/linkMark.generated.js +8 -0
  201. package/esm/shaders/linkMark.glsl.generated.d.ts +2 -0
  202. package/esm/shaders/linkMark.glsl.generated.js +4 -0
  203. package/esm/shaders/linkMark.iface.generated.d.ts +142 -0
  204. package/esm/shaders/linkMark.iface.generated.js +1829 -0
  205. package/esm/shaders/linkMark.js.generated.d.ts +7 -0
  206. package/esm/shaders/linkMark.js.generated.js +159 -0
  207. package/esm/shaders/linkMark.wgsl.generated.d.ts +1 -0
  208. package/esm/shaders/linkMark.wgsl.generated.js +3 -0
  209. package/esm/shaders/markColor.generated.d.ts +9 -0
  210. package/esm/shaders/markColor.generated.js +11 -0
  211. package/esm/shaders/pointGlyph.js.generated.d.ts +2 -0
  212. package/esm/shaders/pointGlyph.js.generated.js +15 -0
  213. package/esm/shaders/pointMark.consts.generated.d.ts +7 -0
  214. package/esm/shaders/pointMark.consts.generated.js +9 -0
  215. package/esm/shaders/pointMark.generated.d.ts +4 -0
  216. package/esm/shaders/pointMark.generated.js +8 -0
  217. package/esm/shaders/pointMark.glsl.generated.d.ts +2 -0
  218. package/esm/shaders/pointMark.glsl.generated.js +4 -0
  219. package/esm/shaders/pointMark.iface.generated.d.ts +98 -0
  220. package/esm/shaders/pointMark.iface.generated.js +219 -0
  221. package/esm/shaders/pointMark.js.generated.d.ts +3 -0
  222. package/esm/shaders/pointMark.js.generated.js +93 -0
  223. package/esm/shaders/pointMark.wgsl.generated.d.ts +1 -0
  224. package/esm/shaders/pointMark.wgsl.generated.js +3 -0
  225. package/esm/shaders/rowRect.generated.d.ts +0 -1
  226. package/esm/shaders/rowRect.generated.js +0 -1
  227. package/esm/shaders/rowTable.generated.d.ts +1 -0
  228. package/esm/shaders/rowTable.generated.js +3 -0
  229. package/esm/shaders/rowTable.js.generated.d.ts +5 -0
  230. package/esm/shaders/rowTable.js.generated.js +29 -0
  231. package/esm/shaders/scoreScale.generated.d.ts +2 -0
  232. package/esm/shaders/scoreScale.generated.js +4 -0
  233. package/esm/shaders/scoreScale.js.generated.d.ts +1 -0
  234. package/esm/shaders/scoreScale.js.generated.js +50 -23
  235. package/esm/shaders/spanMark.generated.d.ts +3 -0
  236. package/esm/shaders/spanMark.generated.js +7 -0
  237. package/esm/shaders/spanMark.glsl.generated.d.ts +2 -0
  238. package/esm/shaders/spanMark.glsl.generated.js +4 -0
  239. package/esm/shaders/spanMark.iface.generated.d.ts +81 -0
  240. package/esm/shaders/spanMark.iface.generated.js +215 -0
  241. package/esm/shaders/spanMark.wgsl.generated.d.ts +1 -0
  242. package/esm/shaders/spanMark.wgsl.generated.js +3 -0
  243. package/esm/sharedBackendKey.d.ts +18 -0
  244. package/esm/{keyedRenderingBackend.js → sharedBackendKey.js} +5 -0
  245. package/esm/slangPass.d.ts +18 -11
  246. package/esm/slangPass.js +12 -4
  247. package/esm/useGraphicsCapabilities.d.ts +1 -1
  248. package/esm/useGraphicsCapabilities.js +1 -1
  249. package/esm/useRenderingBackend.d.ts +13 -13
  250. package/esm/useRenderingBackend.js +58 -20
  251. package/esm/webgpuUtils.d.ts +3 -11
  252. package/esm/webgpuUtils.js +12 -33
  253. package/package.json +32 -7
  254. package/src/shaders/antialias.slang +46 -0
  255. package/src/shaders/arcHull.test.ts +267 -0
  256. package/src/shaders/barMark.generated.ts +11 -0
  257. package/src/shaders/barMark.glsl.generated.ts +6 -0
  258. package/src/shaders/barMark.iface.generated.ts +285 -0
  259. package/src/shaders/barMark.slang +167 -0
  260. package/src/shaders/barMark.wgsl.generated.ts +4 -0
  261. package/src/shaders/capsule.js.generated.ts +14 -0
  262. package/src/shaders/capsule.slang +12 -4
  263. package/src/shaders/clipStrip.generated.ts +6 -0
  264. package/src/shaders/clipStrip.js.generated.ts +22 -0
  265. package/src/shaders/clipStrip.slang +34 -0
  266. package/src/shaders/clipStrip.test.ts +39 -0
  267. package/src/shaders/colorPack.slang +5 -1
  268. package/src/shaders/colorRampLut.js.generated.ts +22 -0
  269. package/src/shaders/colorRampLut.slang +15 -1
  270. package/src/shaders/coverageBand.slang +64 -32
  271. package/src/shaders/coverageBar.generated.ts +6 -5
  272. package/src/shaders/coverageBar.glsl.generated.ts +6 -0
  273. package/src/shaders/coverageBar.iface.generated.ts +1 -1
  274. package/src/shaders/coverageBar.slang +10 -10
  275. package/src/shaders/coverageBar.wgsl.generated.ts +4 -0
  276. package/src/shaders/coverageClip.generated.ts +11 -0
  277. package/src/shaders/coverageClip.glsl.generated.ts +6 -0
  278. package/src/shaders/coverageClip.iface.generated.ts +172 -0
  279. package/src/shaders/coverageClip.slang +38 -0
  280. package/src/shaders/coverageClip.wgsl.generated.ts +4 -0
  281. package/src/shaders/coverageIndicator.generated.ts +6 -5
  282. package/src/shaders/coverageIndicator.glsl.generated.ts +6 -0
  283. package/src/shaders/coverageIndicator.iface.generated.ts +1 -1
  284. package/src/shaders/coverageIndicator.wgsl.generated.ts +4 -0
  285. package/src/shaders/coverageInterbase.generated.ts +6 -5
  286. package/src/shaders/coverageInterbase.glsl.generated.ts +6 -0
  287. package/src/shaders/coverageInterbase.iface.generated.ts +1 -1
  288. package/src/shaders/coverageInterbase.wgsl.generated.ts +4 -0
  289. package/src/shaders/coverageMod.generated.ts +6 -5
  290. package/src/shaders/coverageMod.glsl.generated.ts +6 -0
  291. package/src/shaders/coverageMod.iface.generated.ts +1 -1
  292. package/src/shaders/coverageMod.wgsl.generated.ts +4 -0
  293. package/src/shaders/coverageSnp.generated.ts +6 -5
  294. package/src/shaders/coverageSnp.glsl.generated.ts +6 -0
  295. package/src/shaders/coverageSnp.iface.generated.ts +1 -1
  296. package/src/shaders/coverageSnp.wgsl.generated.ts +4 -0
  297. package/src/shaders/curveDistance.js.generated.ts +91 -0
  298. package/src/shaders/curveDistance.slang +265 -0
  299. package/src/shaders/hpClampFloor.test.ts +87 -0
  300. package/src/shaders/hpmath.js.generated.ts +6 -2
  301. package/src/shaders/hpmath.slang +100 -48
  302. package/src/shaders/insetValueScale.test.ts +67 -0
  303. package/src/shaders/lineCenterMark.generated.ts +11 -0
  304. package/src/shaders/lineCenterMark.glsl.generated.ts +6 -0
  305. package/src/shaders/lineCenterMark.iface.generated.ts +328 -0
  306. package/src/shaders/lineCenterMark.slang +127 -0
  307. package/src/shaders/lineCenterMark.wgsl.generated.ts +4 -0
  308. package/src/shaders/lineCommon.generated.ts +6 -0
  309. package/src/shaders/lineCommon.slang +102 -0
  310. package/src/shaders/lineStepMark.generated.ts +11 -0
  311. package/src/shaders/lineStepMark.glsl.generated.ts +6 -0
  312. package/src/shaders/lineStepMark.iface.generated.ts +311 -0
  313. package/src/shaders/lineStepMark.slang +125 -0
  314. package/src/shaders/lineStepMark.wgsl.generated.ts +4 -0
  315. package/src/shaders/linkMark.consts.generated.ts +30 -0
  316. package/src/shaders/linkMark.generated.ts +12 -0
  317. package/src/shaders/linkMark.glsl.generated.ts +6 -0
  318. package/src/shaders/linkMark.iface.generated.ts +1954 -0
  319. package/src/shaders/linkMark.js.generated.ts +167 -0
  320. package/src/shaders/linkMark.slang +439 -0
  321. package/src/shaders/linkMark.wgsl.generated.ts +4 -0
  322. package/src/shaders/markColor.generated.ts +20 -0
  323. package/src/shaders/markColor.slang +128 -0
  324. package/src/shaders/pointGlyph.js.generated.ts +20 -0
  325. package/src/shaders/pointGlyph.slang +23 -7
  326. package/src/shaders/pointGlyphPad.test.ts +242 -0
  327. package/src/shaders/pointMark.consts.generated.ts +16 -0
  328. package/src/shaders/pointMark.generated.ts +12 -0
  329. package/src/shaders/pointMark.glsl.generated.ts +6 -0
  330. package/src/shaders/pointMark.iface.generated.ts +304 -0
  331. package/src/shaders/pointMark.js.generated.ts +99 -0
  332. package/src/shaders/pointMark.slang +227 -0
  333. package/src/shaders/pointMark.wgsl.generated.ts +4 -0
  334. package/src/shaders/rowRect.generated.ts +0 -2
  335. package/src/shaders/rowRect.slang +39 -58
  336. package/src/shaders/rowTable.generated.ts +4 -0
  337. package/src/shaders/rowTable.js.generated.ts +37 -0
  338. package/src/shaders/rowTable.slang +98 -0
  339. package/src/shaders/scoreScale.generated.ts +6 -0
  340. package/src/shaders/scoreScale.js.generated.ts +48 -23
  341. package/src/shaders/scoreScale.slang +49 -55
  342. package/src/shaders/sdEllipse.test.ts +211 -0
  343. package/src/shaders/spanMark.generated.ts +11 -0
  344. package/src/shaders/spanMark.glsl.generated.ts +6 -0
  345. package/src/shaders/spanMark.iface.generated.ts +289 -0
  346. package/src/shaders/spanMark.slang +77 -0
  347. package/src/shaders/spanMark.wgsl.generated.ts +4 -0
  348. package/src/shaders/valueScale.slang +26 -0
  349. package/src/shaders/wideCircleLeg.test.ts +85 -0
  350. package/esm/globalRenderingBackend.d.ts +0 -90
  351. package/esm/globalRenderingBackend.js +0 -53
  352. package/esm/keyedRenderingBackend.d.ts +0 -41
@@ -1,34 +1,34 @@
1
1
  // Shared "row of colored rects" primitive: one instance is a rectangle
2
- // spanning [startBp, endBp) in absolute genomic coords, drawn on the row given
3
- // by `rowIndex` and filled with a per-instance packed ABGR color.
2
+ // spanning [x, x2) in absolute genomic coords, drawn on the row given by
3
+ // `row` and filled with a per-instance packed ABGR color.
4
4
  //
5
- // Two renderers draw exactly this: the MAF alignment renderer (run-merged
6
- // per-base cells) and the multi-row feature painter / "chromosome painting"
7
- // (features are already intervals). They shipped as byte-identical copies of
8
- // one another joined only by a "probably belongs there too" comment; owning the
9
- // geometry here makes a change to the primitive land in both by construction.
5
+ // The `span` mark draws exactly this for MAF (run-merged per-base cells) and
6
+ // the multi-row feature painter (features are already intervals), and wiggle
7
+ // density composes the same rect over a colour of its own.
10
8
  //
11
9
  // Row placement comes from uniforms rather than the instance data, so a
12
10
  // rowHeight / rowProportion change re-renders without a refetch.
13
11
  //
14
- // What the callers legitimately differ on is the min-width floor: both the
15
- // width they write into `minCellPx` and the *unit* they measure it in, via
16
- // `minCellDenomPx` (CSS px vs device px) — see GpuMafRenderer's note. Those are
17
- // uniform-write decisions, not a reason for two shaders. The unit is also
18
- // unsettled, and device px additionally makes MAF's floor depend on the
19
- // reader's monitor: `agent-docs/ideas/maf-subpixel-cells.md`.
20
- //! export-consts: MIN_DRAWN_ROW_PX, MIN_DRAWN_CELL_PX, MULTI_ROW_MIN_CELL_PX
12
+ // What the callers legitimately differ on is the min-width floor they write
13
+ // into `minCellPx` — a uniform-write decision, not a reason for two shaders.
14
+ // Whether to floor at all turns on whether the caller's marks leave GAPS: a
15
+ // floored quad grows off its start edge, so a neighbour abutting it covers the
16
+ // growth and the floor paints nothing extra. The multi-row painter's features
17
+ // are sparse intervals with nothing beside them, so it floors; MAF's cells
18
+ // never gap and it passes 0; wiggle density tiles at most zooms and gaps where
19
+ // its source does, so it floors and pays nothing for it on the tiling. Both
20
+ // halves measured — `agent-docs/reference/MAF_SUBPIXEL_CELLS.md`.
21
+ //! export-consts: MIN_DRAWN_ROW_PX, MULTI_ROW_MIN_CELL_PX
21
22
  //! js-export: drawnRowHeightPx, rowBandOffsetPx
22
23
  module rowRect;
23
24
 
24
- import colorPack;
25
25
  import hpmath;
26
26
 
27
27
  public struct RowRectInstance {
28
- public uint startBp : ATTR0;
29
- public uint endBp : ATTR1;
30
- public uint rowIndex : ATTR2;
31
- public uint color : ATTR3; // packed ABGR
28
+ public uint x : ATTR0;
29
+ public uint x2 : ATTR1;
30
+ public uint row : ATTR2;
31
+ public uint color : ATTR3; // packed ABGR
32
32
  };
33
33
 
34
34
  public struct RowRectUniforms {
@@ -36,16 +36,15 @@ public struct RowRectUniforms {
36
36
  public float canvasHeight; // CSS px
37
37
  // The width `minCellPx` is measured against, and so the thing that decides
38
38
  // what unit `minCellPx` IS. Named for that rather than for the viewport
39
- // because the three callers do not agree: multi-row and wiggle density pass
40
- // a CSS width (a 1 CSS px floor), MAF passes a device one (1 device px, so
41
- // half a CSS px on a retina screen and a floor that moves with the monitor).
42
- // That disagreement is live and parked, not settled —
43
- // agent-docs/ideas/maf-subpixel-cells.md — so the name carries it to every
44
- // call site instead of a comment forty lines away.
39
+ // because the callers that floor pass a CSS width. Pass a DEVICE width and
40
+ // the floor moves with the reader's monitor — MAF did, and rendered
41
+ // measurably differently on a retina screen until it stopped flooring.
45
42
  public float minCellDenomPx;
46
- // Narrowest a cell is painted, in whatever unit `minCellDenomPx` is in.
47
- // MIN_DRAWN_CELL_PX is the floor a caller takes when it has no reason to
48
- // widen further; the multi-row painter does (see MULTI_ROW_MIN_CELL_PX).
43
+ // Narrowest a cell is painted, in whatever unit `minCellDenomPx` is in. Zero
44
+ // is a no-op, and over marks that tile so is every other value; what a floor
45
+ // decides is what a GAP next to a sub-pixel mark looks like. MAF writes 0,
46
+ // the multi-row painter MULTI_ROW_MIN_CELL_PX, wiggle density
47
+ // MIN_FILL_WIDTH_PX.
49
48
  public float minCellPx;
50
49
  public float zero; // always 0.0 — prevents hp-split collapse
51
50
  public float rowHeight; // CSS px per row
@@ -62,24 +61,16 @@ public struct RowRectVsOut {
62
61
  public float4 color : COLOR0;
63
62
  };
64
63
 
65
- // Thinnest a row is ever painted. Vertical twin of MIN_DRAWN_CELL_PX below: a
66
- // row thinner than a pixel can miss every pixel center and disappear, so
67
- // without this rows drop out as they get denser instead of just getting
68
- // thinner. Floored, neighbours overlap instead.
69
- static const float MIN_DRAWN_ROW_PX = 1.0;
70
-
71
- // Thinnest a cell can be painted and still be drawable at all, for the same
72
- // reason as the row floor above on the other axis. A caller writes this into
73
- // `minCellPx` when a cell being *visible* is not its problem, only a cell
74
- // existing; one whose whole encoding is carried by sub-pixel cells asks for
75
- // more (MULTI_ROW_MIN_CELL_PX).
64
+ // Thinnest a row is ever painted: a row thinner than a pixel can miss every
65
+ // pixel center and disappear, so without this rows drop out as they get denser
66
+ // instead of just getting thinner. Floored, neighbours overlap instead.
76
67
  //
77
- // One caller mirrors it on the Canvas2D side and one deliberately does not: the
78
- // multi-row painter floors, MAF draws cells at their natural sub-pixel width.
79
- // That asymmetry is real and parked in `agent-docs/ideas/maf-subpixel-cells.md`;
80
- // sharing the constant does not decide it, it just stops the value being
81
- // anonymous in the places that DO agree.
82
- static const float MIN_DRAWN_CELL_PX = 1.0;
68
+ // There is no X-axis twin. A row is a container the reader is counting, so
69
+ // losing one loses a species; a cell is a sample of a tiling, so losing one to
70
+ // the blend is the honest answer and flooring it invents ink
71
+ // (`agent-docs/reference/MAF_SUBPIXEL_CELLS.md`). The caller that does want an X
72
+ // floor names its own width, below.
73
+ static const float MIN_DRAWN_ROW_PX = 1.0;
83
74
 
84
75
  // What the multi-row painter ("chromosome painting") writes into `minCellPx`.
85
76
  //
@@ -91,9 +82,9 @@ static const float MIN_DRAWN_CELL_PX = 1.0;
91
82
  // across two, so neither reaches full opacity — the tick reads as a smudge, and
92
83
  // the eye scanning for structure across the rows finds none.
93
84
  //
94
- // Both floors distort width; that is what a floor is. This one distorts more,
95
- // and only where the alternative was showing nothing legible: a feature wide
96
- // enough to matter is already past it.
85
+ // A floor distorts width; that is what a floor is. This is the only caller that
86
+ // takes the trade, and only where the alternative was showing nothing legible:
87
+ // a feature wide enough to matter is already past it.
97
88
  static const float MULTI_ROW_MIN_CELL_PX = 2.0;
98
89
 
99
90
  public struct RowBand {
@@ -148,13 +139,3 @@ public float4 rowRectClipPos(
148
139
  return float4(
149
140
  lerp(sx1, sx2, local.x), yPxToClipY(yPx, u.canvasHeight), 0.0, 1.0);
150
141
  }
151
-
152
- public RowRectVsOut rowRectVertex(
153
- RowRectInstance inst, uint vid, RowRectUniforms u
154
- ) {
155
- RowRectVsOut o;
156
- o.position = rowRectClipPos(
157
- inst.startBp, inst.endBp, float(inst.rowIndex), vid, u);
158
- o.color = unpackRGBA(inst.color);
159
- return o;
160
- }
@@ -0,0 +1,4 @@
1
+ // AUTO-GENERATED by packages/shader-tools/src/shader-codegen from rowTable.slang.
2
+ // Do not edit. Run `pnpm gen:shaders` to regenerate.
3
+
4
+ export const ROW_TABLE_MAX_WIDTH = 2048
@@ -0,0 +1,37 @@
1
+ // AUTO-GENERATED by packages/shader-tools/src/shader-codegen from rowTable.slang.
2
+ // Do not edit. Run `pnpm gen:shaders` to regenerate.
3
+
4
+ // Scalar twins of rowTable.slang, transliterated from slangc's WGSL so
5
+ // the Canvas2D and SVG paths run the shader's own math. See adr-051.
6
+
7
+ function _max(a: number, b: number) {
8
+ return b > a || Number.isNaN(a) ? b : a
9
+ }
10
+
11
+ function _min(a: number, b: number) {
12
+ return b < a || Number.isNaN(a) ? b : a
13
+ }
14
+
15
+ export function rowTableWidth(keys: number): number {
16
+ return _max(_min(keys, 2048), 1)
17
+ }
18
+
19
+ export function rowTablePlaneHeight(keys: number): number {
20
+ let w = rowTableWidth(keys)
21
+ let _t0 = Math.trunc(((((keys + w) >>> 0) - 1) >>> 0) / w)
22
+ return _max(_t0, 1)
23
+ }
24
+
25
+ export function rowTableTexelX(key: number, keys: number): number {
26
+ let _t0 = (key % rowTableWidth(keys))
27
+ return _t0
28
+ }
29
+
30
+ export function rowTableTexelY(key: number, keys: number): number {
31
+ let _t0 = Math.trunc(key / rowTableWidth(keys))
32
+ return _t0
33
+ }
34
+
35
+ export function rowBandTopPx(rowOffsetPx: number, rowHeight: number, slot: number): number {
36
+ return (rowOffsetPx + (rowHeight * (slot)))
37
+ }
@@ -0,0 +1,98 @@
1
+ // The row axis resolved on the GPU. An instance carries a stable row KEY in its
2
+ // `row` lane, and the pass binds a table mapping each key to the slot it is
3
+ // drawn on, or to hidden, with an optional colour override — so a reorder, a
4
+ // focus, a hide or a recolour uploads this table and no instance bytes, the
5
+ // property a y domain already has as a uniform (GRAMMAR_OF_GRAPHICS.md, rule 3).
6
+ //
7
+ // The table is an RGBA8 texture of two planes, one texel per key, keys wrapped
8
+ // onto rows of ROW_TABLE_MAX_WIDTH past it (the WebGL2 floor on a texture
9
+ // dimension). The slot plane holds the slot's low 24 bits in rgb and 255 in
10
+ // alpha where the key is drawn, 0 where it is hidden; the colour plane below it
11
+ // holds the override, straight alpha, and alpha 0 where the instance keeps its
12
+ // own colour. `marks/rowTable.ts` writes it through the texel twins exported
13
+ // here, and is the painter's and hit test's reading of the same bytes.
14
+ //
15
+ // Sampled at texel centres with `SampleLevel`, never `Load`: this slangc emits
16
+ // `textureLoad` on the sampler variable for `Load`, which is invalid WGSL. The
17
+ // texel index arithmetic is unsigned and the filter below is `nearest`, so the
18
+ // read-back is the byte the builder wrote — `rowTableWidth` is the key count
19
+ // itself below the cap, and `(x + 0.5) / w` at a non-power-of-two width does
20
+ // not round-trip through the sampler's fixed point, so a linear tap would blend
21
+ // two keys' slot bytes into a slot belonging to neither. A module can take a
22
+ // sampler as a parameter but not declare the binding for its importer, so each
23
+ // pass reading a table declares its own `Sampler2D<float4> rowTable` and
24
+ // inherits the filter from here.
25
+ //! texture-filter: rowTable nearest
26
+ //! export-consts: ROW_TABLE_MAX_WIDTH
27
+ //! js-export: rowTableWidth, rowTablePlaneHeight, rowTableTexelX, rowTableTexelY, rowBandTopPx
28
+ //! js-skip: byteOf — recovers a byte from a sampled texel; the TS side reads the table's bytes directly
29
+ module rowTable;
30
+
31
+ public static const uint ROW_TABLE_MAX_WIDTH = 2048u;
32
+
33
+ public struct RowPlacement {
34
+ public bool hidden;
35
+ public uint slot;
36
+ public float4 color;
37
+ };
38
+
39
+ public uint rowTableWidth(uint keys) {
40
+ return max(min(keys, ROW_TABLE_MAX_WIDTH), 1u);
41
+ }
42
+
43
+ public uint rowTablePlaneHeight(uint keys) {
44
+ uint w = rowTableWidth(keys);
45
+ return max((keys + w - 1u) / w, 1u);
46
+ }
47
+
48
+ public uint rowTableTexelX(uint key, uint keys) {
49
+ return key % rowTableWidth(keys);
50
+ }
51
+
52
+ // The key's row in the slot plane; the colour plane's is one plane height on.
53
+ public uint rowTableTexelY(uint key, uint keys) {
54
+ return key / rowTableWidth(keys);
55
+ }
56
+
57
+ // Where the band of `slot` starts, in CSS px below the canvas top: every
58
+ // mark placing an instance through the table stacks its bands this way.
59
+ public float rowBandTopPx(float rowOffsetPx, float rowHeight, uint slot) {
60
+ return rowOffsetPx + rowHeight * float(slot);
61
+ }
62
+
63
+ uint byteOf(float channel) {
64
+ return uint(channel * 255.0 + 0.5);
65
+ }
66
+
67
+ // The key's placement: its slot and colour through the table of `keys` keys,
68
+ // or the identity — its `row` as the slot, its own colour — where `keys` is
69
+ // negative, which is what a pass with no table binds.
70
+ public RowPlacement rowTableLookup(
71
+ Sampler2D<float4> table, uint key, int keys, float4 own
72
+ ) {
73
+ RowPlacement p;
74
+ p.hidden = false;
75
+ p.slot = key;
76
+ p.color = own;
77
+ if (keys < 0) {
78
+ return p;
79
+ }
80
+ uint n = uint(keys);
81
+ if (key >= n) {
82
+ p.hidden = true;
83
+ return p;
84
+ }
85
+ uint h = rowTablePlaneHeight(n);
86
+ float u = (float(rowTableTexelX(key, n)) + 0.5) / float(rowTableWidth(n));
87
+ float rows = float(2u * h);
88
+ uint y = rowTableTexelY(key, n);
89
+ float4 s = table.SampleLevel(float2(u, (float(y) + 0.5) / rows), 0.0);
90
+ if (s.a < 0.5) {
91
+ p.hidden = true;
92
+ return p;
93
+ }
94
+ p.slot = byteOf(s.r) | (byteOf(s.g) << 8) | (byteOf(s.b) << 16);
95
+ float4 c = table.SampleLevel(float2(u, (float(y + h) + 0.5) / rows), 0.0);
96
+ p.color = c.a > 0.0 ? c : own;
97
+ return p;
98
+ }
@@ -0,0 +1,6 @@
1
+ // AUTO-GENERATED by packages/shader-tools/src/shader-codegen from scoreScale.slang.
2
+ // Do not edit. Run `pnpm gen:shaders` to regenerate.
3
+
4
+ export const SCALE_TYPE_LOG = 1
5
+
6
+ export const SCALE_TYPE_SYMLOG = 2
@@ -16,36 +16,61 @@ function _min(a: number, b: number) {
16
16
  return b < a || Number.isNaN(a) ? b : a
17
17
  }
18
18
 
19
+ function log1pf(x: number): number {
20
+ let u = (1.0 + x)
21
+ let _t0: number
22
+ if ((u == 1.0)) {
23
+ _t0 = x
24
+ } else {
25
+ _t0 = (Math.log(u) * (x / (u - 1.0)))
26
+ }
27
+ return _t0
28
+ }
29
+
19
30
  function symlogTransform(x: number, c: number): number {
20
- return ((((Math.sign(x)) | 0)) * Math.log((1.0 + Math.abs((x / c)))))
31
+ return ((((Math.sign(x)) | 0)) * log1pf(Math.abs((x / c))))
21
32
  }
22
33
 
23
- export function normalizeScore(score: number, domainMin: number, domainMax: number, scaleType: number, symlogConstant: number): number {
34
+ export function normalizeScoreUnclamped(score: number, domainMin: number, domainMax: number, scaleType: number, symlogConstant: number): number {
35
+ let tMax: number
36
+ let tMin: number
37
+ let t: number
24
38
  if ((scaleType == 2)) {
25
- let tMin = symlogTransform(domainMin, symlogConstant)
26
- let tRange = (symlogTransform(domainMax, symlogConstant) - tMin)
27
- if ((tRange <= 0.0)) {
28
- return 0.0
39
+ let _t0 = symlogTransform(score, symlogConstant)
40
+ let _t1 = symlogTransform(domainMin, symlogConstant)
41
+ tMax = symlogTransform(domainMax, symlogConstant)
42
+ tMin = _t1
43
+ t = _t0
44
+ } else {
45
+ if ((scaleType == 1)) {
46
+ if ((domainMin > 0.0)) {
47
+ tMax = domainMin
48
+ } else {
49
+ tMax = 1.0
50
+ }
51
+ let _t2 = Math.log2(_max(score, tMax))
52
+ let _t3 = Math.log2(tMax)
53
+ tMax = Math.log2(_max(domainMax, tMax))
54
+ tMin = _t3
55
+ t = _t2
56
+ } else {
57
+ tMax = domainMax
58
+ tMin = domainMin
59
+ t = score
29
60
  }
30
- return _clamp(((symlogTransform(score, symlogConstant) - tMin) / tRange), 0.0, 1.0)
31
61
  }
32
- if ((scaleType == 1)) {
33
- let floorV: number
34
- if ((domainMin > 0.0)) {
35
- floorV = domainMin
62
+ let tRange = (tMax - tMin)
63
+ if ((tRange <= 0.0)) {
64
+ if ((t > tMin)) {
65
+ tMax = 1.0
36
66
  } else {
37
- floorV = 1.0
67
+ tMax = 0.0
38
68
  }
39
- let logMin = Math.log2(floorV)
40
- let logRange = (Math.log2(_max(domainMax, floorV)) - logMin)
41
- if ((logRange <= 0.0)) {
42
- return 0.0
43
- }
44
- return _clamp(((Math.log2(_max(score, floorV)) - logMin) / logRange), 0.0, 1.0)
45
- }
46
- let range = (domainMax - domainMin)
47
- if ((range <= 0.0)) {
48
- return 0.0
69
+ return tMax
49
70
  }
50
- return _clamp(((score - domainMin) / range), 0.0, 1.0)
71
+ return ((t - tMin) / tRange)
72
+ }
73
+
74
+ export function normalizeScore(score: number, domainMin: number, domainMax: number, scaleType: number, symlogConstant: number): number {
75
+ return _clamp(normalizeScoreUnclamped(score, domainMin, domainMax, scaleType, symlogConstant), 0.0, 1.0)
51
76
  }
@@ -1,68 +1,62 @@
1
- // The score → [0,1] normalizer every score-scaled track is placed by, and the
2
- // scale-type vocabulary its branches switch on.
1
+ // The score → [0,1] normalizer every score-scaled mark is placed and coloured
2
+ // by — wiggle, the coverage band, the bar and point shapes, their ramps — and
3
+ // the scale-type vocabulary its branches switch on. `makeScoreNormalizer`
4
+ // (render-core's scoreScale.ts) is its loop-hoisted twin.
3
5
  //
4
- // Two real consumers with non-obvious math, which is ADR-040's bar: the wiggle
5
- // renderer's four modes (`wiggleCommon.slang`, via `scoreToY`) and the coverage
6
- // band's depth axis (`coverageBand.slang`, via `normalizeDepthScalar`). They
7
- // carried a branch-for-branch copy each, and the copies did not agree: the
8
- // coverage one compared `scaleType` against bare 2 and 1 rather than the
9
- // constants below, and answered 0 on a degenerate domain where wiggle's divided
10
- // by a 1e-6 floor and saturated. This module is one answer to both.
11
- //
12
- // The degenerate domain answers 0, which is what the JS twin
13
- // (`makeScoreNormalizer`, packages/wiggle-core/src/normalize.ts) has always
14
- // answered. Returning 0 avoids the NaN the 1e-6 floor was there for just as
15
- // well, so the divergence bought nothing and cost a documented exception.
16
- //
17
- // `SCALE_TYPE_LINEAR` is deliberately absent: it is "neither of these", and a
18
- // third constant would be a value nothing compares against.
19
- //! js-export: normalizeScore
20
- //! js-skip: symlogTransform — the JS twin (wiggle-core normalize.ts) spells it Math.log1p, which is accurate near zero where the shader's log(1.0 + x) is not; a generated twin would be a faithful copy of the worse of the two. What both backends must agree on is normalizeScore, which is exported and swept by normalizeScoreParity.test.ts
6
+ // A domain with no range is a step: a score above its min maps to 1 and any
7
+ // other to 0, so a score above a pinned domain sits off the top everywhere.
8
+ //! export-consts: SCALE_TYPE_LOG, SCALE_TYPE_SYMLOG
9
+ //! js-export: normalizeScore, normalizeScoreUnclamped
10
+ //! js-skip: log1pf — JS has Math.log1p, so a twin of this would be the float32 workaround spelled out where the language already answers it
11
+ //! js-skip: symlogTransform — render-core scoreScale.ts reaches Math.log1p directly, one call inside a normalizer it hoists the whole log domain out of, so a per-call twin of this would have no caller. What both backends must agree on is normalizeScore, which is exported and swept by normalizeScoreParity.test.ts
21
12
  module scoreScale;
22
13
 
23
- // The values the `scaleType` uniform is compared against. Emitted into
24
- // @jbrowse/wiggle-core through `wiggleCommon.slang`'s `export-consts` — the
25
- // constant evaluator resolves through imports, and wiggle-core is where
26
- // `WiggleScaleType` is declared, so the numbers stay next to the type they
27
- // name rather than next to the module that happens to author them.
14
+ // `ScaleTypeCode` in scoreScale.ts is these two and 0, for linear.
28
15
  public static const int SCALE_TYPE_LOG = 1;
29
16
  public static const int SCALE_TYPE_SYMLOG = 2;
30
17
 
18
+ // log(1 + x) for x that `1.0 + x` rounds away: a symlog domain narrower than
19
+ // its constant lands entirely in that region, and in float32 the rounding
20
+ // survives the normalize's divide by a tiny domain range — 0.2px of a 40px row
21
+ // on domain [-1, 0.75] with constant 100.5, against the Canvas2D twin's
22
+ // Math.log1p. Kahan's identity: `u - 1.0` is exact where `u` is near 1, so the
23
+ // ratio is the correction the sum lost.
24
+ float log1pf(float x) {
25
+ float u = 1.0 + x;
26
+ return u == 1.0 ? x : log(u) * (x / (u - 1.0));
27
+ }
28
+
31
29
  public float symlogTransform(float x, float c) {
32
- return sign(x) * log(1.0 + abs(x / c));
30
+ return sign(x) * log1pf(abs(x / c));
33
31
  }
34
32
 
35
- public float normalizeScore(float score, float domainMin, float domainMax, int scaleType, float symlogConstant) {
33
+ // The fraction a score sits at, extrapolated past either end rather than
34
+ // clamped, so a value outside the domain keeps its order against every other
35
+ // one. A threshold cut is placed through this: a cut the domain excludes then
36
+ // lands off the plot, instead of tying with the scores clamped to the edge it
37
+ // would sit on and reading as crossed.
38
+ public float normalizeScoreUnclamped(float score, float domainMin, float domainMax, int scaleType, float symlogConstant) {
39
+ float t = score;
40
+ float tMin = domainMin;
41
+ float tMax = domainMax;
36
42
  if (scaleType == SCALE_TYPE_SYMLOG) {
37
- // Defined at and either side of zero, so unlike the log branch there is
38
- // nothing to floor: the domain arrives as-is and 0 lands where it belongs
39
- // instead of on the baseline with everything else below the floor. On a
40
- // coverage band that is the whole reason symlog is offered — a depth of 0
41
- // is real, common, and what log cannot separate from a depth of 1.
42
- float tMin = symlogTransform(domainMin, symlogConstant);
43
- float tMax = symlogTransform(domainMax, symlogConstant);
44
- float tRange = tMax - tMin;
45
- if (tRange <= 0.0) { return 0.0; }
46
- float t = symlogTransform(score, symlogConstant);
47
- return clamp((t - tMin) / tRange, 0.0, 1.0);
48
- }
49
- if (scaleType == SCALE_TYPE_LOG) {
50
- // Floor at the domain's own min, not at 1, so a domain sitting entirely
51
- // below 1 (mappability, a methylation fraction, any normalized ratio) still
52
- // has a range to spread over instead of collapsing to a flat baseline. Same
53
- // rule and same reasoning as JS `makeScoreNormalizer`, which keeps its own
54
- // hand-written copy because it hoists this arithmetic out of a per-feature
55
- // loop — so this one is `//! js-export`ed as the ORACLE the two are swept
56
- // against (`normalizeScoreParity.test.ts`), not to retire it.
43
+ t = symlogTransform(score, symlogConstant);
44
+ tMin = symlogTransform(domainMin, symlogConstant);
45
+ tMax = symlogTransform(domainMax, symlogConstant);
46
+ } else if (scaleType == SCALE_TYPE_LOG) {
47
+ // The domain's own min, so a domain entirely below 1 still spreads.
57
48
  float floorV = domainMin > 0.0 ? domainMin : 1.0;
58
- float logMin = log2(floorV);
59
- float logMax = log2(max(domainMax, floorV));
60
- float logRange = logMax - logMin;
61
- if (logRange <= 0.0) { return 0.0; }
62
- float logScore = log2(max(score, floorV));
63
- return clamp((logScore - logMin) / logRange, 0.0, 1.0);
49
+ t = log2(max(score, floorV));
50
+ tMin = log2(floorV);
51
+ tMax = log2(max(domainMax, floorV));
52
+ }
53
+ float tRange = tMax - tMin;
54
+ if (tRange <= 0.0) {
55
+ return t > tMin ? 1.0 : 0.0;
64
56
  }
65
- float range = domainMax - domainMin;
66
- if (range <= 0.0) { return 0.0; }
67
- return clamp((score - domainMin) / range, 0.0, 1.0);
57
+ return (t - tMin) / tRange;
58
+ }
59
+
60
+ public float normalizeScore(float score, float domainMin, float domainMax, int scaleType, float symlogConstant) {
61
+ return clamp(normalizeScoreUnclamped(score, domainMin, domainMax, scaleType, symlogConstant), 0.0, 1.0);
68
62
  }