Skip to content
Snippets Groups Projects
Commit c9518d43 authored by Alexander Rose's avatar Alexander Rose
Browse files

moved stats out of VolumeIsoValue

parent 97168acc
No related branches found
No related tags found
No related merge requests found
...@@ -40,7 +40,7 @@ function print(data: Volume) { ...@@ -40,7 +40,7 @@ function print(data: Volume) {
} }
async function doMesh(data: Volume, filename: string) { async function doMesh(data: Volume, filename: string) {
const mesh = await Task.create('', runtime => createVolumeIsosurfaceMesh({ runtime }, data.volume, createEmptyTheme(), { isoValue: VolumeIsoValue.absolute(data.volume.dataStats, 1.5) } )).run(); const mesh = await Task.create('', runtime => createVolumeIsosurfaceMesh({ runtime }, data.volume, createEmptyTheme(), { isoValue: VolumeIsoValue.absolute(1.5) } )).run();
console.log({ vc: mesh.vertexCount, tc: mesh.triangleCount }); console.log({ vc: mesh.vertexCount, tc: mesh.triangleCount });
// Export the mesh in OBJ format. // Export the mesh in OBJ format.
......
...@@ -44,11 +44,11 @@ namespace VolumeData { ...@@ -44,11 +44,11 @@ namespace VolumeData {
type VolumeIsoValue = VolumeIsoValue.Absolute | VolumeIsoValue.Relative type VolumeIsoValue = VolumeIsoValue.Absolute | VolumeIsoValue.Relative
namespace VolumeIsoValue { namespace VolumeIsoValue {
export type Relative = Readonly<{ kind: 'relative', stats: VolumeData['dataStats'], relativeValue: number }> export type Relative = Readonly<{ kind: 'relative', relativeValue: number }>
export type Absolute = Readonly<{ kind: 'absolute', stats: VolumeData['dataStats'], absoluteValue: number }> export type Absolute = Readonly<{ kind: 'absolute', absoluteValue: number }>
export function absolute(stats: VolumeData['dataStats'], value: number): Absolute { return { kind: 'absolute', stats, absoluteValue: value }; } export function absolute(value: number): Absolute { return { kind: 'absolute', absoluteValue: value }; }
export function relative(stats: VolumeData['dataStats'], value: number): Relative { return { kind: 'relative', stats, relativeValue: value }; } export function relative(value: number): Relative { return { kind: 'relative', relativeValue: value }; }
export function calcAbsolute(stats: VolumeData['dataStats'], relativeValue: number): number { export function calcAbsolute(stats: VolumeData['dataStats'], relativeValue: number): number {
return relativeValue * stats.sigma + stats.mean return relativeValue * stats.sigma + stats.mean
...@@ -58,22 +58,12 @@ namespace VolumeIsoValue { ...@@ -58,22 +58,12 @@ namespace VolumeIsoValue {
return stats.sigma === 0 ? 0 : ((absoluteValue - stats.mean) / stats.sigma) return stats.sigma === 0 ? 0 : ((absoluteValue - stats.mean) / stats.sigma)
} }
export function toAbsolute(value: VolumeIsoValue): Absolute { export function toAbsolute(value: VolumeIsoValue, stats: VolumeData['dataStats']): Absolute {
if (value.kind === 'absolute') return value; return value.kind === 'absolute' ? value : { kind: 'absolute', absoluteValue: VolumeIsoValue.calcAbsolute(stats, value.relativeValue) }
return {
kind: 'absolute',
stats: value.stats,
absoluteValue: calcAbsolute(value.stats, value.relativeValue)
}
} }
export function toRelative(value: VolumeIsoValue): Relative { export function toRelative(value: VolumeIsoValue, stats: VolumeData['dataStats']): Relative {
if (value.kind === 'relative') return value; return value.kind === 'relative' ? value : { kind: 'relative', relativeValue: VolumeIsoValue.calcRelative(stats, value.absoluteValue) }
return {
kind: 'relative',
stats: value.stats,
relativeValue: calcRelative(value.stats, value.absoluteValue)
}
} }
} }
......
...@@ -20,21 +20,21 @@ import { NullLocation } from 'mol-model/location'; ...@@ -20,21 +20,21 @@ import { NullLocation } from 'mol-model/location';
import { Lines } from 'mol-geo/geometry/lines/lines'; import { Lines } from 'mol-geo/geometry/lines/lines';
const IsoValueParam = PD.Conditioned( const IsoValueParam = PD.Conditioned(
VolumeIsoValue.relative(VolumeData.Empty.dataStats, 2), VolumeIsoValue.relative(2),
{ {
'absolute': PD.Converted( 'absolute': PD.Converted(
(v: VolumeIsoValue) => VolumeIsoValue.toAbsolute(v).absoluteValue, (v: VolumeIsoValue) => VolumeIsoValue.toAbsolute(v, VolumeData.Empty.dataStats).absoluteValue,
(v: number) => VolumeIsoValue.absolute(VolumeData.Empty.dataStats, v), (v: number) => VolumeIsoValue.absolute(v),
PD.Numeric(0.5, { min: -1, max: 1, step: 0.01 }) PD.Numeric(0.5, { min: -1, max: 1, step: 0.01 })
), ),
'relative': PD.Converted( 'relative': PD.Converted(
(v: VolumeIsoValue) => VolumeIsoValue.toRelative(v).relativeValue, (v: VolumeIsoValue) => VolumeIsoValue.toRelative(v, VolumeData.Empty.dataStats).relativeValue,
(v: number) => VolumeIsoValue.relative(VolumeData.Empty.dataStats, v), (v: number) => VolumeIsoValue.relative(v),
PD.Numeric(2, { min: -10, max: 10, step: 0.01 }) PD.Numeric(2, { min: -10, max: 10, step: 0.01 })
) )
}, },
(v: VolumeIsoValue) => v.kind === 'absolute' ? 'absolute' : 'relative', (v: VolumeIsoValue) => v.kind === 'absolute' ? 'absolute' : 'relative',
(v: VolumeIsoValue, c: 'absolute' | 'relative') => c === 'absolute' ? VolumeIsoValue.toAbsolute(v) : VolumeIsoValue.toRelative(v) (v: VolumeIsoValue, c: 'absolute' | 'relative') => c === 'absolute' ? VolumeIsoValue.toAbsolute(v, VolumeData.Empty.dataStats) : VolumeIsoValue.toRelative(v, VolumeData.Empty.dataStats)
) )
type IsoValueParam = typeof IsoValueParam type IsoValueParam = typeof IsoValueParam
...@@ -50,7 +50,7 @@ export async function createVolumeIsosurfaceMesh(ctx: VisualContext, volume: Vol ...@@ -50,7 +50,7 @@ export async function createVolumeIsosurfaceMesh(ctx: VisualContext, volume: Vol
ctx.runtime.update({ message: 'Marching cubes...' }); ctx.runtime.update({ message: 'Marching cubes...' });
const surface = await computeMarchingCubesMesh({ const surface = await computeMarchingCubesMesh({
isoLevel: VolumeIsoValue.toAbsolute(props.isoValue).absoluteValue, isoLevel: VolumeIsoValue.toAbsolute(props.isoValue, volume.dataStats).absoluteValue,
scalarField: volume.data scalarField: volume.data
}, mesh).runAsChild(ctx.runtime); }, mesh).runAsChild(ctx.runtime);
...@@ -88,7 +88,7 @@ export async function createVolumeIsosurfaceWireframe(ctx: VisualContext, volume ...@@ -88,7 +88,7 @@ export async function createVolumeIsosurfaceWireframe(ctx: VisualContext, volume
ctx.runtime.update({ message: 'Marching cubes...' }); ctx.runtime.update({ message: 'Marching cubes...' });
const wireframe = await computeMarchingCubesLines({ const wireframe = await computeMarchingCubesLines({
isoLevel: VolumeIsoValue.toAbsolute(props.isoValue).absoluteValue, isoLevel: VolumeIsoValue.toAbsolute(props.isoValue, volume.dataStats).absoluteValue,
scalarField: volume.data scalarField: volume.data
}, lines).runAsChild(ctx.runtime) }, lines).runAsChild(ctx.runtime)
...@@ -135,23 +135,24 @@ export const IsosurfaceParams = { ...@@ -135,23 +135,24 @@ export const IsosurfaceParams = {
export type IsosurfaceParams = typeof IsosurfaceParams export type IsosurfaceParams = typeof IsosurfaceParams
export function getIsosurfaceParams(ctx: ThemeRegistryContext, volume: VolumeData) { export function getIsosurfaceParams(ctx: ThemeRegistryContext, volume: VolumeData) {
const p = PD.clone(IsosurfaceParams) const p = PD.clone(IsosurfaceParams)
const { min, max, mean, sigma } = volume.dataStats const stats = volume.dataStats
const { min, max, mean, sigma } = stats
p.isoValue = PD.Conditioned( p.isoValue = PD.Conditioned(
VolumeIsoValue.relative(volume.dataStats, 2), VolumeIsoValue.relative(2),
{ {
'absolute': PD.Converted( 'absolute': PD.Converted(
(v: VolumeIsoValue) => VolumeIsoValue.toAbsolute(v).absoluteValue, (v: VolumeIsoValue) => VolumeIsoValue.toAbsolute(v, stats).absoluteValue,
(v: number) => VolumeIsoValue.absolute(volume.dataStats, v), (v: number) => VolumeIsoValue.absolute(v),
PD.Numeric(mean, { min, max, step: sigma / 100 }) PD.Numeric(mean, { min, max, step: sigma / 100 })
), ),
'relative': PD.Converted( 'relative': PD.Converted(
(v: VolumeIsoValue) => VolumeIsoValue.toRelative(v).relativeValue, (v: VolumeIsoValue) => VolumeIsoValue.toRelative(v, stats).relativeValue,
(v: number) => VolumeIsoValue.relative(volume.dataStats, v), (v: number) => VolumeIsoValue.relative(v),
PD.Numeric(2, { min: -10, max: 10, step: 0.001 }) PD.Numeric(2, { min: -10, max: 10, step: 0.001 })
) )
}, },
(v: VolumeIsoValue) => v.kind === 'absolute' ? 'absolute' : 'relative', (v: VolumeIsoValue) => v.kind === 'absolute' ? 'absolute' : 'relative',
(v: VolumeIsoValue, c: 'absolute' | 'relative') => c === 'absolute' ? VolumeIsoValue.toAbsolute(v) : VolumeIsoValue.toRelative(v) (v: VolumeIsoValue, c: 'absolute' | 'relative') => c === 'absolute' ? VolumeIsoValue.toAbsolute(v, stats) : VolumeIsoValue.toRelative(v, stats)
) )
return p return p
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment