Skip to content

Commit fa6bd3b

Browse files
committed
use the average calibration
1 parent 210c86a commit fa6bd3b

3 files changed

Lines changed: 53 additions & 30 deletions

File tree

src/main/java/net/preibisch/bigstitcher/spark/CreateFusionContainer.java

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,21 @@
66
import java.util.ArrayList;
77
import java.util.Arrays;
88
import java.util.Collection;
9+
import java.util.Collections;
910
import java.util.HashMap;
11+
import java.util.HashSet;
1012
import java.util.List;
1113
import java.util.Map;
14+
import java.util.Set;
1215
import java.util.concurrent.Callable;
1316
import java.util.function.Function;
1417

18+
import mpicbg.spim.data.generic.base.Entity;
19+
import mpicbg.spim.data.registration.ViewRegistrations;
20+
import mpicbg.spim.data.sequence.SequenceDescription;
21+
import net.imglib2.util.Pair;
22+
import net.imglib2.util.ValuePair;
23+
import net.preibisch.mvrecon.process.interestpointregistration.pairwise.constellation.grouping.Group;
1524
import org.janelia.saalfeldlab.n5.Compression;
1625
import org.janelia.saalfeldlab.n5.DataType;
1726
import org.janelia.saalfeldlab.n5.N5Writer;
@@ -117,7 +126,10 @@ public class CreateFusionContainer extends AbstractBasic implements Callable<Voi
117126
@Option(names = { "--group" }, description = "Container group path")
118127
private String groupPath = "";
119128

120-
URI outPathURI = null, xmlOutURI = null;
129+
private URI outPathURI = null, xmlOutURI = null;
130+
private double[] cal = new double[] { 1, 1, 1 };
131+
private String calUnit = "micrometer";
132+
private double avgAnisotropy = Double.NaN;
121133

122134
/**
123135
* @return container group path always terminated with a '/'
@@ -376,34 +388,29 @@ else if ( storageType == StorageFormat.N5 || storageType == StorageFormat.ZARR )
376388
final Function<Integer, AffineTransform3D> levelToMipmapTransform =
377389
(level) -> MipmapTransforms.getMipmapTransformDefault( mrInfo[level].absoluteDownsamplingDouble() );
378390

391+
updateAnisotropyAndCalibration(dataGlobal, viewIdsGlobal);
379392
// extract the resolution of the s0 export
380-
final VoxelDimensions vx = dataGlobal.getSequenceDescription().getViewSetupsOrdered().iterator().next().getVoxelSize();
381-
final double[] resolutionS0 = OMEZarrAttibutes.getResolutionS0( vx );
393+
final double[] resolutionS0 = OMEZarrAttibutes.getResolutionS0( cal, avgAnisotropy, Double.NaN );
382394

383-
System.out.println( "Resolution of level 0: " + Util.printCoordinates( resolutionS0 ) + " " + "micrometer" ); //vx.unit() might not be OME-ZARR compatiblevx.unit() );
395+
System.out.println( "Resolution of level 0: " + Util.printCoordinates( resolutionS0 ) + " " + calUnit );
384396

385397
// create metadata
386398
final OmeNgffMultiScaleMetadata[] meta = OMEZarrAttibutes.createOMEZarrMetadata(
387399
5, // int n
388400
getContainerGroupPath(), // String name, I also saw "/"
389401
resolutionS0, // double[] resolutionS0,
390-
"micrometer", //vx.unit() might not be OME-ZARR compatible // String unitXYZ, // e.g micrometer
402+
calUnit, //vx.unit() might not be OME-ZARR compatible // String unitXYZ, // e.g micrometer
391403
mrInfos[ 0 ].length, // int numResolutionLevels,
392404
(level) -> "/" + level, // OME-ZARR metadata will be created relative to the provided group
393405
levelToMipmapTransform );
394406

395407
// save metadata
396-
397-
//org.janelia.saalfeldlab.n5.universe.metadata.ome.ngff.v04.OmeNgffMetadata
398-
// for this to work you need to register an adapter in the N5Factory class
399-
// final GsonBuilder builder = new GsonBuilder().registerTypeAdapter( CoordinateTransformation.class, new CoordinateTransformationAdapter() );
400408
driverVolumeWriter.setAttribute( getContainerGroupPath(), "multiscales", meta );
401409
}
402410

403411
if ( bdv )
404412
{
405413
System.out.println( "Creating BDV compatible container at '" + outPathURI + "' ... " );
406-
407414
if ( storageType == StorageFormat.N5 )
408415
driverVolumeWriter.setAttribute( getContainerGroupPath(), "Bigstitcher-Spark/FusionFormat", "BDV/N5" );
409416
else if ( storageType == StorageFormat.ZARR )
@@ -422,14 +429,12 @@ else if ( storageType == StorageFormat.ZARR )
422429
tps.add( new TimePoint( t ) );
423430

424431
// extract the resolution of the s0 export
425-
// TODO: this is inaccurate, we should actually estimate it from the final transformn that is applied
426-
// TODO: this is a hack (returns 1,1,1) so the export downsampling pyramid is working
427-
final VoxelDimensions vx = new FinalVoxelDimensions( "micrometer", new double[] { 1, 1, 1 } );// dataGlobal.getSequenceDescription().getViewSetupsOrdered().iterator().next().getVoxelSize();
428-
final double[] resolutionS0 = OMEZarrAttibutes.getResolutionS0( vx );
432+
433+
final double[] resolutionS0 = OMEZarrAttibutes.getResolutionS0( cal, avgAnisotropy, Double.NaN );
429434

430435
System.out.println( "Resolution of level 0: " + Util.printCoordinates( resolutionS0 ) + " " + "m" ); //vx.unit() might not be OME-ZARR compatiblevx.unit() );
431436

432-
final VoxelDimensions vxNew = new FinalVoxelDimensions( "micrometer", resolutionS0 );
437+
final VoxelDimensions vxNew = new FinalVoxelDimensions( calUnit, resolutionS0 );
433438

434439
for ( int c = 0; c < numChannels; ++c )
435440
{
@@ -535,6 +540,31 @@ else if ( storageType == StorageFormat.N5 || storageType == StorageFormat.HDF5 )
535540
return null;
536541
}
537542

543+
private void updateAnisotropyAndCalibration( SpimData2 dataGlobal, List<ViewId> viewIdsGlobal )
544+
{
545+
ViewRegistrations registrations = dataGlobal.getViewRegistrations();
546+
// get all view descriptions
547+
List<ViewDescription> vds = SpimData2.getAllViewDescriptionsSorted(dataGlobal, viewIdsGlobal);
548+
// group by timepoint and channel
549+
Set<Class<? extends Entity>> groupingFactors = new HashSet<>(Arrays.asList(TimePoint.class, Channel.class));
550+
List<Group<ViewDescription>> fusionGroups = Group.splitBy( vds, groupingFactors );
551+
Pair<double[], String> calAndUnit = fusionGroups.stream().findFirst()
552+
.map(group -> TransformationTools.computeAverageCalibration(group, registrations))
553+
.orElse(new ValuePair<>(new double[]{ 1, 1, 1 }, "micrometer"));
554+
cal = calAndUnit.getA();
555+
calUnit = calAndUnit.getB();
556+
557+
if (preserveAnisotropy) {
558+
if (!Double.isNaN(this.anisotropyFactor)) {
559+
avgAnisotropy = this.anisotropyFactor;
560+
} else {
561+
avgAnisotropy = TransformationTools.getAverageAnisotropyFactor(dataGlobal, viewIdsGlobal);
562+
}
563+
} else {
564+
avgAnisotropy = Double.NaN;
565+
}
566+
}
567+
538568
public static void main(final String... args) throws SpimDataException
539569
{
540570
System.out.println(Arrays.toString(args));

src/main/java/net/preibisch/bigstitcher/spark/SparkAffineFusion.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import java.util.concurrent.Callable;
3434
import java.util.concurrent.ExecutorService;
3535
import java.util.concurrent.Executors;
36-
import java.util.stream.Collectors;
3736

3837
import org.apache.spark.SparkConf;
3938
import org.apache.spark.api.java.JavaRDD;
@@ -767,18 +766,18 @@ else if ( dataType == DataType.UINT16 )
767766

768767
rddDSResult.cache();
769768
rddDSResult.count();
770-
769+
771770
// extract all blocks that failed
772771
final Set<long[][]> failedBlocksSet =
773772
retryTrackerDS.processWithSpark( rddDSResult, grid );
774-
773+
775774
// Use RetryTracker to handle retry counting and removal
776775
if (!retryTrackerDS.processFailures(failedBlocksSet))
777776
{
778777
System.out.println( "Stopping." );
779778
System.exit( 1 );
780779
}
781-
780+
782781
// Update grid for next iteration with remaining failed blocks
783782
grid.clear();
784783
grid.addAll(failedBlocksSet);
@@ -792,13 +791,6 @@ else if ( dataType == DataType.UINT16 )
792791
// close main writer (is shared over Spark-threads if it's HDF5, thus just closing it here)
793792
driverVolumeWriter.close();
794793

795-
/*
796-
if ( multiRes )
797-
System.out.println( "Saved, e.g. view with './n5-view -i " + n5PathURI + " -d " + n5Dataset.substring( 0, n5Dataset.length() - 3) + "'" );
798-
else
799-
System.out.println( "Saved, e.g. view with './n5-view -i " + n5PathURI + " -d " + n5Dataset + "'" );
800-
*/
801-
802794
System.out.println( "done, took: " + (System.currentTimeMillis() - totalTime ) + " ms." );
803795

804796
sc.close();

src/main/java/net/preibisch/bigstitcher/spark/SparkResaveN5.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
import bdv.img.n5.N5ImageLoader;
3636
import mpicbg.spim.data.sequence.ViewId;
37+
import mpicbg.spim.data.sequence.VoxelDimensions;
3738
import net.imglib2.util.Util;
3839
import net.imglib2.util.ValuePair;
3940
import net.preibisch.bigstitcher.spark.abstractcmdline.AbstractBasic;
@@ -214,13 +215,14 @@ public Void call() throws Exception
214215
else
215216
{
216217
System.out.println( Arrays.toString( blockSize ) );
217-
218+
VoxelDimensions vx = dataGlobal.getSequenceDescription().getViewDescription( viewId ).getViewSetup().getVoxelSize();
218219
mrInfo = N5ApiTools.setupBdvDatasetsOMEZARR(
219220
n5Writer,
220221
viewId,
221222
dataTypes.get( viewId.getViewSetupId() ),
222223
dimensions.get( viewId.getViewSetupId() ),
223-
dataGlobal.getSequenceDescription().getViewDescription( viewId ).getViewSetup().getVoxelSize().dimensionsAsDoubleArray(),
224+
vx.dimensionsAsDoubleArray(),
225+
vx.unit(),
224226
compression,
225227
blockSize,
226228
downsamplings);
@@ -331,8 +333,7 @@ public Void call() throws Exception
331333
}
332334

333335
final JavaRDD<long[][]> rddsN = sc.parallelize(allBlocks, Math.min( Spark.maxPartitions, allBlocks.size() ) );
334-
335-
336+
336337
final JavaRDD<long[][]> rdds0Result = rddsN.map( gridBlock ->
337338
{
338339
final N5Writer n5Lcl = URITools.instantiateN5Writer( useN5 ? StorageFormat.N5 : StorageFormat.ZARR, n5PathURI );

0 commit comments

Comments
 (0)