Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling multiple Sources with different units #198

Open
bogovicj opened this issue Jul 8, 2024 · 2 comments
Open

Handling multiple Sources with different units #198

bogovicj opened this issue Jul 8, 2024 · 2 comments

Comments

@bogovicj
Copy link
Contributor

bogovicj commented Jul 8, 2024

How should Bdv behave when multiple loaded sources have different units?

Currently, the ScaleBarOverlayRenderer uses units to create a scale bar, and even does some neat unit conversion when very zoomed in or out (and units are one of a known type). I think this may be the only way units are used currently (is that right?).

Bigdataviewer appears to currently assume that the source transformations for all sources bring them into the same world coordinates with the same unit. It might be nice to handle different units simultaneously - to know that a source with 0.1um resolution is "the same" as one with 100 nm resolution. But what unit should the world coordinates use if sources use different units?

Ideas:

  • The units of the first source
    • simple but inflexible
  • The units of the current source
    • more flexible, but would need to constantly change source transforms of all sources when changing current source. maybe unintuitive?
  • User specified
    • perhaps more intuitive than the above

Note for unit conversion - ucars.udunits seems to have some nice functionality for unit conversion:

final UnitFormat format = UnitFormatManager.instance();

// all three lines below return 0.001
format.parse("nm").convertTo(1.0, format.parse("um")));
format.parse("nanometer").convertTo(1.0, format.parse("micrometer"));
format.parse("nanometer").convertTo(1.0, format.parse("micron"));
@bogovicj
Copy link
Contributor Author

bogovicj commented Jul 9, 2024

Work in progress here in case it's of interest: https://github.com/bogovicj/bigdataviewer-core/tree/unitConversion

and a small demo:

public static void convertSourceUnitDemo() {

	final TransformedSource<UnsignedByteType> srcUm = wrapSource(buildSource("a", new UnsignedByteType(128)), "um");

	final TransformedSource<UnsignedByteType> srcNm = wrapSource(buildSource("b", new UnsignedByteType(255)), "nm");
	// set resoluition to 500 nm
	final AffineTransform3D tform = new AffineTransform3D();
	tform.scale(500, 500, 500);
	Units.updateTransform(srcNm, tform);

	final BdvStackSource<UnsignedByteType> bdv = BdvFunctions.show(srcUm);

	// convert nm source to um
	final TransformedSource<UnsignedByteType> srcNm2Um = (TransformedSource<UnsignedByteType>)Units.convertUnit(srcNm, "um");
	BdvFunctions.show(srcNm2Um, BdvOptions.options().addTo(bdv));
}

public static Source<UnsignedByteType> buildSource(String name, UnsignedByteType val) {

	final ArrayImg<UnsignedByteType, ByteArray> img = ArrayImgs.unsignedBytes(16, 16, 16);
	img.forEach(x -> x.set(val));
	final RandomAccessibleIntervalSource<UnsignedByteType> src = new RandomAccessibleIntervalSource<>(img, val, name);
	return src;
}

public static TransformedSource<UnsignedByteType> wrapSource(Source<UnsignedByteType> src, final String unit) {

	final TransformedSource<UnsignedByteType> ts = new TransformedSource<>(src);
	ts.setVoxelDimensions(new FinalVoxelDimensions(unit, 1, 1, 1));
	return ts;
}

@NicoKiaru
Copy link
Contributor

Note for unit conversion - ucars.udunits seems to have some nice functionality for unit conversion:

Just FYI there's already a lot of things in bio-formats regarding units and conversions. It would be nice to keep bio-formats to avoid two repos doing the same things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants