Last active
August 29, 2022 20:38
-
-
Save bogovicj/6de68b76f290cfb517ad1de67abc0170 to your computer and use it in GitHub Desktop.
Visualize the hemibrain and fafb together
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.util.Arrays; | |
import java.util.Collections; | |
import org.janelia.saalfeldlab.n5.N5DatasetDiscoverer; | |
import org.janelia.saalfeldlab.n5.N5FSReader; | |
import org.janelia.saalfeldlab.n5.N5Reader; | |
import org.janelia.saalfeldlab.n5.N5TreeNode; | |
import org.janelia.saalfeldlab.n5.hdf5.N5HDF5Reader; | |
import org.janelia.saalfeldlab.n5.ij.N5Importer; | |
import org.janelia.saalfeldlab.n5.imglib2.N5DisplacementField; | |
import org.janelia.saalfeldlab.n5.imglib2.N5Utils; | |
import org.janelia.saalfeldlab.n5.metadata.MultiscaleMetadata; | |
import org.janelia.saalfeldlab.n5.metadata.N5GenericSingleScaleMetadataParser; | |
import org.janelia.saalfeldlab.n5.metadata.N5Metadata; | |
import org.janelia.saalfeldlab.n5.metadata.N5SingleScaleMetadata; | |
import bdv.tools.transformation.TransformedSource; | |
import bdv.util.BdvFunctions; | |
import bdv.util.BdvOptions; | |
import bdv.util.BdvStackSource; | |
import bdv.util.RandomAccessibleIntervalMipmapSource; | |
import bdv.util.volatiles.SharedQueue; | |
import bdv.util.volatiles.VolatileViews; | |
import bdv.viewer.Source; | |
import mpicbg.spim.data.sequence.FinalVoxelDimensions; | |
import net.imglib2.RandomAccessibleInterval; | |
import net.imglib2.cache.volatiles.CacheHints; | |
import net.imglib2.cache.volatiles.LoadingStrategy; | |
import net.imglib2.realtransform.AffineTransform3D; | |
import net.imglib2.realtransform.ExplicitInvertibleRealTransform; | |
import net.imglib2.realtransform.InvertibleRealTransform; | |
import net.imglib2.realtransform.InvertibleRealTransformSequence; | |
import net.imglib2.type.volatiles.VolatileUnsignedByteType; | |
public class Hemi2Fafb | |
{ | |
public static String FAFB_JRC18 = "/groups/saalfeld/public/jrc2018/transformations/public_transforms/JRC2018F_FAFB.h5"; | |
public static String HEMI_JRC18 = "/groups/saalfeld/public/jrc2018/transformations/public_transforms/JRC2018F_JRCFIB2018F.h5"; | |
public static String FAFB_N5 = "/nrs/saalfeld/FAFB00/v14_align_tps_20170818_dmg.n5/volumes/raw"; | |
public static String FAFB_DSET = ""; | |
public static String HEMI_N5 = "/nrs/flyem/data/tmp/Z0115-22.export.n5/22-34"; | |
public static void main( String[] args ) throws Exception | |
{ | |
final SharedQueue queue = new SharedQueue( 32 ); | |
final Source<?> hemiSrc = loadHemiN5Pix( HEMI_N5, queue); | |
final Source< ? > hemiTransformedSrc = transformSource( hemiSrc, loadHemibrainN5ToFAFB() ); | |
final BdvOptions opts = BdvOptions.options().numRenderingThreads( 32 ); | |
final BdvStackSource< ? > bdv = BdvFunctions.show( hemiTransformedSrc, opts ); | |
final Source<?> fafbSrc = loadFafbUm(queue); | |
BdvFunctions.show( fafbSrc, opts.addTo( bdv ) ); | |
} | |
public static Source<?> transformSource( Source<?> src, InvertibleRealTransform transform ) | |
{ | |
System.out.println("tform src"); | |
final RealTransformedSource wsrc = new RealTransformedSource(src, src.getName()+" transformed" ); | |
wsrc.updateTransform( transform ); | |
wsrc.setIsTransformed( true ); | |
return wsrc; | |
} | |
public static Source<?> affineSource( Source<?> src, AffineTransform3D transform ) | |
{ | |
System.out.println("affine src"); | |
TransformedSource tsrc = new TransformedSource( src ); | |
tsrc.setFixedTransform( transform ); | |
return tsrc; | |
} | |
public static AffineTransform3D hemiN5ToDvid() | |
{ | |
final AffineTransform3D toDvid = new AffineTransform3D(); | |
toDvid.set( | |
0.0, 0.0, -1.0, 34427, | |
1.0, 0.0, 0.0, 0.0, | |
0.0, 1.0, 0.0, 0.0 ); | |
return toDvid; | |
} | |
public static AffineTransform3D hemiN5ToDvidUm() | |
{ | |
final AffineTransform3D xfm = hemiN5ToDvid(); | |
final AffineTransform3D res = new AffineTransform3D(); | |
res.scale( 0.008, 0.008, 0.008 ); | |
xfm.preConcatenate( res ); | |
return xfm; | |
} | |
public static InvertibleRealTransform loadHemibrainN5ToFAFB() throws Exception | |
{ | |
final N5HDF5Reader n5 = new N5HDF5Reader( HEMI_JRC18, 3, 32, 32, 32 ); | |
final ExplicitInvertibleRealTransform dfield = N5DisplacementField.openInvertible(n5, 0); | |
final InvertibleRealTransform hemi2Fafb = loadJrc2018ToFafb(); | |
final InvertibleRealTransformSequence seq = new InvertibleRealTransformSequence(); | |
seq.add( hemi2Fafb ); | |
seq.add( dfield ); | |
seq.add( hemiN5ToDvidUm().inverse() ); | |
return seq; | |
} | |
public static InvertibleRealTransform loadHemibrainN5ToJrc2018() throws Exception | |
{ | |
final N5HDF5Reader n5 = new N5HDF5Reader( HEMI_JRC18, 3, 32, 32, 32 ); | |
final ExplicitInvertibleRealTransform dfield = N5DisplacementField.openInvertible(n5, 0); | |
final InvertibleRealTransformSequence seq = new InvertibleRealTransformSequence(); | |
seq.add( dfield ); | |
seq.add( hemiN5ToDvidUm().inverse() ); | |
return seq; | |
} | |
public static InvertibleRealTransform loadJrc2018ToHemibrain() throws Exception | |
{ | |
N5HDF5Reader n5 = new N5HDF5Reader( HEMI_JRC18, 3, 32, 32, 32 ); | |
return N5DisplacementField.openInvertible(n5, 0).inverse(); | |
} | |
public static InvertibleRealTransform loadFafbToJrc2018() throws Exception | |
{ | |
N5HDF5Reader n5 = new N5HDF5Reader( FAFB_JRC18, 3, 32, 32, 32 ); | |
return N5DisplacementField.openInvertible(n5, 0); | |
} | |
public static InvertibleRealTransform loadJrc2018ToFafb() throws Exception | |
{ | |
N5HDF5Reader n5 = new N5HDF5Reader( FAFB_JRC18, 3, 32, 32, 32 ); | |
return N5DisplacementField.openInvertible(n5, 0).inverse(); | |
} | |
public static Source< ? > loadHemiN5Pix( final SharedQueue queue ) throws IOException | |
{ | |
return loadHemiN5Pix( HEMI_N5, queue ); | |
} | |
public static Source< ? > loadFafbNm( final SharedQueue queue ) throws IOException | |
{ | |
N5Reader n5 = new N5FSReader( FAFB_N5 ); | |
return getRandomAccessibleIntervalMipmapSourceV( n5, FAFB_DSET, "fafb", queue, false, new double[] {4,4,40} ); | |
} | |
public static Source< ? > loadFafbUm( final SharedQueue queue ) throws IOException | |
{ | |
N5Reader n5 = new N5FSReader( FAFB_N5 ); | |
return getRandomAccessibleIntervalMipmapSourceV( n5, FAFB_DSET, "fafb", queue, false, new double[] {0.004, 0.004 ,0.04} ); | |
} | |
public static Source< ? > loadHemiN5Pix( final String hemiN5Path, final SharedQueue queue ) throws IOException | |
{ | |
N5Reader n5hemi = new N5FSReader( hemiN5Path ); | |
return getRandomAccessibleIntervalMipmapSourceV( n5hemi, "hemibrain", "hemibrain", queue ); | |
} | |
public static Source< ? > loadHemiN5Um( final String hemiN5Path, final SharedQueue queue ) throws IOException | |
{ | |
N5Reader n5hemi = new N5FSReader( hemiN5Path ); | |
return getRandomAccessibleIntervalMipmapSourceV( n5hemi, "hemibrain", "hemibrain", queue, true, new double[] {0.004, 0.004, 0.004 }); | |
} | |
public static Source<?> getRandomAccessibleIntervalMipmapSourceV( | |
final N5Reader n5, final String dataset, final String name, final SharedQueue queue ) throws IOException | |
{ | |
return getRandomAccessibleIntervalMipmapSourceV( n5, dataset, name, queue, true ); | |
} | |
public static Source<?> getRandomAccessibleIntervalMipmapSourceV( | |
final N5Reader n5, final String dataset, final String name, final SharedQueue queue, boolean relativeScales ) throws IOException | |
{ | |
return getRandomAccessibleIntervalMipmapSourceV( n5, dataset, name, queue, relativeScales, new double[]{1,1,1} ); | |
} | |
public static Source<?> getRandomAccessibleIntervalMipmapSourceV( | |
final N5Reader n5, final String dataset, final String name, final SharedQueue queue, boolean relativeScales, double[] res ) throws IOException | |
{ | |
N5GenericSingleScaleMetadataParser metaParser = new N5GenericSingleScaleMetadataParser( | |
"min", "max", | |
"resolution", "offset", "unit", | |
"downsamplingFactors"); | |
N5DatasetDiscoverer disc = new N5DatasetDiscoverer( n5, Collections.singletonList(metaParser), Arrays.asList( N5Importer.GROUP_PARSERS)); | |
N5TreeNode node = disc.discoverAndParseRecursive("/"); | |
N5Metadata meta = node.getMetadata(); | |
MultiscaleMetadata<N5SingleScaleMetadata> ms = (MultiscaleMetadata)meta; | |
int N = ms.getPaths().length; | |
double[][] scales = new double[N][]; | |
final RandomAccessibleInterval< ? >[] scaleLevelImgs = new RandomAccessibleInterval[ scales.length ]; | |
int i = 0; | |
for ( N5SingleScaleMetadata scaleMeta : ms.getChildrenMetadata() ) | |
{ | |
N5Utils.openVolatile( n5, scaleMeta.getPath() ); | |
// scales[i] = scaleMeta.getPixelResolution(); | |
scales[i] = scaleMeta.getDownsamplingFactors(); | |
for( int d = 0; d < 3; d++ ) | |
{ | |
scales[i][d] *= res[d]; | |
} | |
System.out.println( String.format( "s%d", i ) + " " + Arrays.toString(scales[i])); | |
i++; | |
} | |
for ( int s = 0; s < scales.length; ++s ) | |
{ | |
RandomAccessibleInterval<?> rai = N5Utils.openVolatile( n5, getScaleGroupPath( s ) ); | |
scaleLevelImgs[ s ] = VolatileViews.wrapAsVolatile( rai, queue, | |
new CacheHints(LoadingStrategy.VOLATILE, 0, true)); | |
} | |
final RandomAccessibleIntervalMipmapSource< ? > source = | |
new RandomAccessibleIntervalMipmapSource( | |
scaleLevelImgs, | |
new VolatileUnsignedByteType(), | |
scales, | |
new FinalVoxelDimensions("", 1, 1, 1 ), | |
name ); | |
return source; | |
} | |
public static String getScaleGroupPath( final int scale ) | |
{ | |
return String.format( "s%d", scale ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment