|
28 | 28 | import java.util.Date; |
29 | 29 | import java.util.HashMap; |
30 | 30 | import java.util.List; |
| 31 | +import java.util.Map; |
31 | 32 | import java.util.Set; |
32 | 33 | import java.util.concurrent.Callable; |
33 | 34 | import java.util.concurrent.ExecutorService; |
|
77 | 78 | import net.preibisch.mvrecon.fiji.spimdata.SpimData2; |
78 | 79 | import net.preibisch.mvrecon.fiji.spimdata.boundingbox.BoundingBox; |
79 | 80 | import net.preibisch.mvrecon.process.fusion.blk.BlkAffineFusion; |
| 81 | +import net.preibisch.mvrecon.process.fusion.intensity.Coefficients; |
| 82 | +import net.preibisch.mvrecon.process.fusion.intensity.IntensityCorrection; |
80 | 83 | import net.preibisch.mvrecon.process.fusion.transformed.TransformVirtual; |
81 | 84 | import net.preibisch.mvrecon.process.interestpointregistration.pairwise.constellation.grouping.Group; |
82 | 85 | import net.preibisch.mvrecon.process.n5api.N5ApiTools; |
@@ -146,12 +149,28 @@ public static enum DataTypeFusion |
146 | 149 | @Option(names = { "--prefetch" }, description = "prefetch all blocks required for fusion in each Spark job using unlimited threads, useful in cloud environments (default: false)") |
147 | 150 | protected boolean prefetch = false; |
148 | 151 |
|
| 152 | + |
| 153 | + // TODO: add support for loading coefficients during fusion |
| 154 | + @CommandLine.Option(names = { "--intensityN5Path" }, description = "N5/ZARR/HDF5 base path for loading coefficients (e.g. s3://myBucket/coefficients.n5)") |
| 155 | + private String intensityN5PathURIString = null; |
| 156 | + |
| 157 | + @CommandLine.Option(names = { "--intensityN5Storage" }, description = "output storage type, can be used to override guessed format (default: guess from n5Path file/directory-ending)") |
| 158 | + private StorageFormat intensityN5StorageType = null; |
| 159 | + |
| 160 | + @CommandLine.Option(names = { "--intensityN5Group" }, description = "group under which coefficient datasets are stored (default: \"\")") |
| 161 | + private String intensityN5Group = ""; |
| 162 | + |
| 163 | + @CommandLine.Option(names = { "--intensityN5Dataset" }, description = "dataset name for each coefficient dataset (default: \"intensity\"). The coefficients for view(s,t) are stored in dataset \"{-n5Group}/setup{s}/timepoint{t}/{n5Dataset}\"") |
| 164 | + private String intensityN5Dataset = "intensity"; |
| 165 | + |
149 | 166 | URI outPathURI = null; |
150 | 167 | /** |
151 | 168 | * Prefetching now works with a Executors.newCachedThreadPool(); |
152 | 169 | */ |
153 | 170 | //static final int N_PREFETCH_THREADS = 72; |
154 | 171 |
|
| 172 | + URI intensityN5PathURI = null; |
| 173 | + |
155 | 174 | @Override |
156 | 175 | public Void call() throws Exception |
157 | 176 | { |
@@ -336,10 +355,44 @@ else if ( dataType == DataType.UINT16 ) |
336 | 355 | else |
337 | 356 | System.out.println( "Fusing to FLOAT32" ); |
338 | 357 |
|
| 358 | + // |
| 359 | + // intensity correction coefficients dataset |
| 360 | + // |
| 361 | + if ( intensityN5PathURIString != null ) |
| 362 | + { |
| 363 | + intensityN5PathURI = URITools.toURI( intensityN5PathURIString ); |
| 364 | + System.out.println( "Intensity coefficients: " + outPathURI ); |
| 365 | + |
| 366 | + if ( intensityN5StorageType == null ) |
| 367 | + { |
| 368 | + if ( intensityN5PathURIString.toLowerCase().endsWith( ".zarr" ) ) |
| 369 | + intensityN5StorageType = StorageFormat.ZARR; |
| 370 | + else if ( intensityN5PathURIString.toLowerCase().endsWith( ".n5" ) ) |
| 371 | + intensityN5StorageType = StorageFormat.N5; |
| 372 | + else if ( intensityN5PathURIString.toLowerCase().endsWith( ".h5" ) || intensityN5PathURI.toString().toLowerCase().endsWith( ".hdf5" ) ) |
| 373 | + intensityN5StorageType = StorageFormat.HDF5; |
| 374 | + else |
| 375 | + { |
| 376 | + System.out.println( "Unable to guess format from URI '" + intensityN5PathURI + "', please specify using '-s'"); |
| 377 | + return null; |
| 378 | + } |
| 379 | + |
| 380 | + System.out.println( "Guessed format " + intensityN5StorageType + " will be used to open URI '" + intensityN5PathURI + "', you can override it using '-s'"); |
| 381 | + } |
| 382 | + else |
| 383 | + { |
| 384 | + System.out.println( "Format " + intensityN5StorageType + " will be used to open " + intensityN5PathURI ); |
| 385 | + } |
| 386 | + } |
| 387 | + |
339 | 388 | // |
340 | 389 | // final variables for Spark |
341 | 390 | // |
342 | 391 | final long[] dimensions = boundingBox.dimensionsAsLongArray(); |
| 392 | + final StorageFormat intensityN5StorageType = this.intensityN5StorageType; |
| 393 | + final URI intensityN5PathURI = this.intensityN5PathURI; |
| 394 | + final String intensityN5Group = this.intensityN5Group; |
| 395 | + final String intensityN5Dataset = this.intensityN5Dataset; |
343 | 396 |
|
344 | 397 | // TODO: do we still need this? |
345 | 398 | try |
@@ -487,6 +540,25 @@ else if ( dataType == DataType.UINT16 ) |
487 | 540 | if ( overlappingViews.size() == 0 ) |
488 | 541 | return gridBlock; |
489 | 542 |
|
| 543 | + // load intensity correction coefficients for all overlapping views |
| 544 | + |
| 545 | + |
| 546 | + final Map< ViewId, Coefficients > coefficients; |
| 547 | + |
| 548 | + |
| 549 | + if ( intensityN5PathURI != null ) |
| 550 | + { |
| 551 | + coefficients = new HashMap<>(); |
| 552 | + try ( N5Reader intensityN5Reader = URITools.instantiateN5Reader( intensityN5StorageType, intensityN5PathURI ) ) |
| 553 | + { |
| 554 | + overlappingViews.forEach( v -> { |
| 555 | + coefficients.put( v, IntensityCorrection.readCoefficients( intensityN5Reader, intensityN5Group, intensityN5Dataset, v ) ); |
| 556 | + } ); |
| 557 | + } |
| 558 | + } else { |
| 559 | + coefficients = null; |
| 560 | + } |
| 561 | + |
490 | 562 | //final RandomAccessibleInterval img; |
491 | 563 | final BlockSupplier blockSupplier; |
492 | 564 | final FinalInterval interval = new FinalInterval( bbMin, bbMax ); |
@@ -536,15 +608,16 @@ else if ( firstTileWinsInverse ) |
536 | 608 | fusionType = FusionType.AVG_BLEND; |
537 | 609 |
|
538 | 610 | // returns a zero-min interval |
539 | | - blockSupplier = BlkAffineFusion.init( |
| 611 | + //blockSupplier = BlkAffineFusion.init( |
| 612 | + blockSupplier = BlkAffineFusion.initWithIntensityCoefficients( |
540 | 613 | conv, |
541 | 614 | dataLocal.getSequenceDescription().getImgLoader(), |
542 | 615 | viewIds, |
543 | 616 | registrations, |
544 | 617 | dataLocal.getSequenceDescription().getViewDescriptions(), |
545 | 618 | fusionType,//fusion.getFusionType(), |
546 | 619 | 1, // linear interpolation |
547 | | - null, // intensity correction |
| 620 | + coefficients, // intensity correction |
548 | 621 | new BoundingBox( interval ), |
549 | 622 | (RealType & NativeType)type, |
550 | 623 | blockSize ); |
|
0 commit comments