Skip to content

Commit 53719a8

Browse files
committed
Attempt to add dataset specification as defined in #61
1 parent d38fed4 commit 53719a8

File tree

4 files changed

+73
-52
lines changed

4 files changed

+73
-52
lines changed

src/main/java/org/janelia/saalfeldlab/paintera/N5Helpers.java

+40-4
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ public class N5Helpers
113113

114114
public static final String MAX_NUM_ENTRIES_KEY = "maxNumEntries";
115115

116+
public static final String PAINTERA_DATA_KEY = "painteraData";
117+
118+
public static final String PAINTERA_DATA_DATASET = "data";
119+
120+
public static final String PAINTERA_FRAGMENT_SEGMENT_ASSIGNMENT_DATASTE = "fragment-segment-assignment";
121+
116122
private static final Logger LOG = LoggerFactory.getLogger( MethodHandles.lookup().lookupClass() );
117123

118124
public static boolean isIntegerType( final DataType type )
@@ -133,6 +139,11 @@ public static boolean isIntegerType( final DataType type )
133139
}
134140
}
135141

142+
public static boolean isPainteraDataset( final N5Reader n5, final String group ) throws IOException
143+
{
144+
return n5.exists( group ) && n5.listAttributes( group ).containsKey( PAINTERA_DATA_KEY );
145+
}
146+
136147
public static boolean isMultiScale( final N5Reader n5, final String dataset ) throws IOException
137148
{
138149
/* based on attribute */
@@ -245,6 +256,14 @@ public static String[] listAndSortScaleDatasets( final N5Reader n5, final String
245256
return scaleDirs;
246257
}
247258

259+
public static DataType getDataType( final N5Reader n5, final String group ) throws IOException
260+
{
261+
LOG.warn( "Getting data type for group/dataset {}", group );
262+
if ( isPainteraDataset( n5, group ) ) { return getDataType( n5, group + "/" + PAINTERA_DATA_DATASET ); }
263+
if ( isMultiScale( n5, group ) ) { return getDataType( n5, getFinestLevel( n5, group ) ); }
264+
return n5.getDatasetAttributes( group ).getDataType();
265+
}
266+
248267
public static void sortScaleDatasets( final String[] scaleDatasets )
249268
{
250269
Arrays.sort( scaleDatasets, ( f1, f2 ) -> {
@@ -319,7 +338,14 @@ public static void discoverSubdirectories(
319338
{
320339
try
321340
{
322-
if ( n5.datasetExists( pathName ) )
341+
if ( isPainteraDataset( n5, pathName ) )
342+
{
343+
synchronized ( datasets )
344+
{
345+
datasets.add( pathName );
346+
}
347+
}
348+
else if ( n5.datasetExists( pathName ) )
323349
{
324350
synchronized ( datasets )
325351
{
@@ -328,8 +354,10 @@ public static void discoverSubdirectories(
328354
}
329355
else
330356
{
357+
331358
String[] groups = null;
332359
/* based on attribute */
360+
333361
boolean isMipmapGroup = Optional.ofNullable( n5.getAttribute( pathName, MULTI_SCALE_KEY, Boolean.class ) ).orElse( false );
334362

335363
/* based on groupd content (the old way) */
@@ -802,12 +830,19 @@ public static AffineTransform3D considerDownsampling(
802830
return transform.concatenate( new Translation3D( shift ) );
803831
}
804832

805-
public static FragmentSegmentAssignmentState assignments( final N5Writer writer, final String ds ) throws IOException
833+
public static FragmentSegmentAssignmentState assignments( final N5Writer writer, final String group ) throws IOException
806834
{
807-
final String dataset = ds + ".fragment-segment-assignment";
835+
836+
if ( !isPainteraDataset( writer, group ) ) { return new FragmentSegmentAssignmentOnlyLocal(
837+
TLongLongHashMap::new,
838+
( ks, vs ) -> {
839+
throw new UnableToPersist( "Persisting assignments not supported for non Paintera group/dataset " + group );
840+
} ); }
841+
842+
final String dataset = group + "/" + PAINTERA_FRAGMENT_SEGMENT_ASSIGNMENT_DATASTE;
808843

809844
final Persister persister = ( keys, values ) -> {
810-
// TODO handle zero length assignments?
845+
// TODO how to handle zero length assignments?
811846
if ( keys.length == 0 ) { throw new UnableToPersist( "Zero length data, will not persist fragment-segment-assignment." ); }
812847
try
813848
{
@@ -959,6 +994,7 @@ public static String getFinestLevel(
959994
final N5Reader n5,
960995
final String dataset ) throws IOException
961996
{
997+
LOG.warn( "Getting finest level for dataset {}", dataset );
962998
final String[] scaleDirs = listAndSortScaleDatasets( n5, dataset );
963999
return Paths.get( dataset, scaleDirs[ 0 ] ).toString();
9641000
}

src/main/java/org/janelia/saalfeldlab/paintera/data/n5/CommitCanvasN5.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,14 @@ public void accept( final CachedCellImg< UnsignedLongType, ? > canvas, final lon
6969
{
7070
try
7171
{
72-
final boolean isMultiscale = !n5.datasetExists( dataset );
72+
final String dataset = N5Helpers.isPainteraDataset( n5, this.dataset ) ? this.dataset + "/" + N5Helpers.PAINTERA_DATA_DATASET : this.dataset;
73+
final boolean isMultiscale = N5Helpers.isMultiScale( n5, dataset );
7374

7475
final CellGrid canvasGrid = canvas.getCellGrid();
7576

7677
final String highestResolutionDataset = isMultiscale ? Paths.get( dataset, N5Helpers.listAndSortScaleDatasets( n5, dataset )[ 0 ] ).toString() : dataset;
7778

78-
if ( !Optional.ofNullable( n5.getAttribute( highestResolutionDataset, N5Helpers.LABEL_MULTISETTYPE_KEY, Boolean.class ) ).orElse( false ) ) {
79-
throw new RuntimeException( "Only label multiset type accepted currently!" );
80-
}
79+
if ( !Optional.ofNullable( n5.getAttribute( highestResolutionDataset, N5Helpers.LABEL_MULTISETTYPE_KEY, Boolean.class ) ).orElse( false ) ) { throw new RuntimeException( "Only label multiset type accepted currently!" ); }
8180

8281
final DatasetAttributes highestResolutionAttributes = n5.getDatasetAttributes( highestResolutionDataset );
8382
final CellGrid highestResolutionGrid = new CellGrid( highestResolutionAttributes.getDimensions(), highestResolutionAttributes.getBlockSize() );

src/main/java/org/janelia/saalfeldlab/paintera/data/n5/N5DataSource.java

+10-9
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ private static < T extends NativeType< T > > Function< Interpolation, Interpolat
8181
{
8282
return N5Helpers.isLabelMultisetType( n5, dataset )
8383
? i -> new NearestNeighborInterpolatorFactory<>()
84-
: ( Function ) realTypeInterpolation();
84+
: ( Function ) realTypeInterpolation();
8585
}
8686

8787
private static < T extends RealType< T > > Function< Interpolation, InterpolatorFactory< T, RandomAccessible< T > > > realTypeInterpolation()
@@ -91,27 +91,28 @@ private static < T extends RealType< T > > Function< Interpolation, Interpolator
9191

9292
@SuppressWarnings( { "unchecked", "rawtypes" } )
9393
private static < D extends NativeType< D >, T extends Volatile< D > & NativeType< T > >
94-
Triple< RandomAccessibleInterval< D >[], RandomAccessibleInterval< T >[], AffineTransform3D[] > getData(
95-
final N5Reader reader,
96-
final String dataset,
97-
final AffineTransform3D transform,
98-
final SharedQueue sharedQueue,
99-
final int priority ) throws IOException
94+
Triple< RandomAccessibleInterval< D >[], RandomAccessibleInterval< T >[], AffineTransform3D[] > getData(
95+
final N5Reader reader,
96+
final String dataset,
97+
final AffineTransform3D transform,
98+
final SharedQueue sharedQueue,
99+
final int priority ) throws IOException
100100
{
101+
if ( N5Helpers.isPainteraDataset( reader, dataset ) ) { return getData( reader, dataset + "/" + N5Helpers.PAINTERA_DATA_DATASET, transform, sharedQueue, priority ); }
101102
final boolean isMultiscale = N5Helpers.isMultiScale( reader, dataset );
102103
final boolean isLabelMultiset = N5Helpers.isLabelMultisetType( reader, dataset, isMultiscale );
103104

104105
if ( isLabelMultiset )
105106
{
106107
return isMultiscale
107108
? ( Triple ) N5Helpers.openLabelMultisetMultiscale( reader, dataset, transform, sharedQueue, priority )
108-
: ( Triple ) N5Helpers.asArrayTriple( N5Helpers.openLabelMutliset( reader, dataset, transform, sharedQueue, priority ) );
109+
: ( Triple ) N5Helpers.asArrayTriple( N5Helpers.openLabelMutliset( reader, dataset, transform, sharedQueue, priority ) );
109110
}
110111
else
111112
{
112113
return isMultiscale
113114
? ( Triple ) N5Helpers.openRawMultiscale( reader, dataset, transform, sharedQueue, priority )
114-
: ( Triple ) N5Helpers.asArrayTriple( N5Helpers.openRaw( reader, dataset, transform, sharedQueue, priority ) );
115+
: ( Triple ) N5Helpers.asArrayTriple( N5Helpers.openRaw( reader, dataset, transform, sharedQueue, priority ) );
115116
}
116117
}
117118
}

src/main/java/org/janelia/saalfeldlab/paintera/ui/opendialog/GenericBackendDialogN5.java

+20-35
Original file line numberDiff line numberDiff line change
@@ -219,21 +219,21 @@ public GenericBackendDialogN5(
219219
dataset.set( "" );
220220
}
221221

222-
public void updateDatasetInfo( final String dataset, final DatasetInfo info )
222+
public void updateDatasetInfo( final String group, final DatasetInfo info )
223223
{
224224

225-
LOG.debug( "Updating dataset info for dataset {}", dataset );
225+
LOG.debug( "Updating dataset info for dataset {}", group );
226226
try
227227
{
228228
final N5Reader n5 = this.n5.get();
229-
final String ds = N5Helpers.isMultiScale( n5, dataset ) ? N5Helpers.getFinestLevel( n5, dataset ) : dataset;
230-
LOG.debug( "Got dataset={}, ds={}", dataset, ds );
231-
232-
setResolution( N5Helpers.getResolution( n5, dataset ) );
233-
setOffset( N5Helpers.getOffset( n5, dataset ) );
234-
final DatasetAttributes dsAttrs = n5.getDatasetAttributes( ds );
235-
this.datasetInfo.minProperty().set( Optional.ofNullable( n5.getAttribute( dataset, MIN_KEY, Double.class ) ).orElse( N5Helpers.minForType( dsAttrs.getDataType() ) ) );
236-
this.datasetInfo.maxProperty().set( Optional.ofNullable( n5.getAttribute( dataset, MAX_KEY, Double.class ) ).orElse( N5Helpers.maxForType( dsAttrs.getDataType() ) ) );
229+
230+
setResolution( N5Helpers.getResolution( n5, group ) );
231+
setOffset( N5Helpers.getOffset( n5, group ) );
232+
233+
final DataType dataType = N5Helpers.getDataType( n5, group );
234+
235+
this.datasetInfo.minProperty().set( Optional.ofNullable( n5.getAttribute( group, MIN_KEY, Double.class ) ).orElse( N5Helpers.minForType( dataType ) ) );
236+
this.datasetInfo.maxProperty().set( Optional.ofNullable( n5.getAttribute( group, MAX_KEY, Double.class ) ).orElse( N5Helpers.maxForType( dataType ) ) );
237237
}
238238
catch ( final IOException e )
239239
{
@@ -290,17 +290,19 @@ public IdService idService()
290290
final String dataset = this.dataset.get();
291291

292292
final Long maxId = n5.getAttribute( dataset, "maxId", Long.class );
293+
final boolean isPainteraData = N5Helpers.isPainteraDataset( n5, dataset );
293294
final long actualMaxId;
294295
if ( maxId == null )
295296
{
297+
final String ds = isPainteraData ? dataset + "/" + N5Helpers.PAINTERA_DATA_DATASET : dataset;
296298
if ( isLabelMultisetType() )
297299
{
298300
LOG.debug( "Getting id service for label multisets" );
299-
actualMaxId = maxIdLabelMultiset( n5, dataset );
301+
actualMaxId = maxIdLabelMultiset( n5, ds );
300302
}
301303
else if ( isIntegerType() )
302304
{
303-
actualMaxId = maxId( n5, dataset );
305+
actualMaxId = maxId( n5, ds );
304306
}
305307
else
306308
{
@@ -490,7 +492,12 @@ public boolean isLabelType() throws Exception
490492

491493
public boolean isLabelMultisetType() throws Exception
492494
{
493-
final Boolean attribute = getAttribute( LABEL_MULTISETTYPE_KEY, Boolean.class );
495+
final N5Writer n5 = this.n5.get();
496+
final String dataset = this.dataset.get();
497+
final Boolean attribute = n5.getAttribute(
498+
N5Helpers.isPainteraDataset( n5, dataset ) ? dataset + "/" + N5Helpers.PAINTERA_DATA_DATASET : dataset,
499+
N5Helpers.LABEL_MULTISETTYPE_KEY,
500+
Boolean.class );
494501
LOG.debug( "Getting label multiset attribute: {}", attribute );
495502
return Optional.ofNullable( attribute ).orElse( false );
496503
}
@@ -535,28 +542,6 @@ public boolean isIntegerType() throws Exception
535542
return new CommitCanvasN5( writer, dataset );
536543
}
537544

538-
public < T > T getAttribute( final String key, final Class< T > clazz ) throws IOException
539-
{
540-
final N5Reader n5 = this.n5.get();
541-
final String ds = this.dataset.get();
542-
543-
if ( n5.datasetExists( ds ) )
544-
{
545-
LOG.debug( "Getting attributes for {} and {}", n5, ds );
546-
return n5.getAttribute( ds, key, clazz );
547-
}
548-
549-
final String[] scaleDirs = N5Helpers.listAndSortScaleDatasets( n5, ds );
550-
551-
if ( scaleDirs.length > 0 )
552-
{
553-
LOG.warn( "Getting attributes for mipmap dataset: {} and {}", n5, scaleDirs[ 0 ] );
554-
return n5.getAttribute( Paths.get( ds, scaleDirs[ 0 ] ).toString(), key, clazz );
555-
}
556-
557-
throw new RuntimeException( String.format( "Cannot read dataset attributes for group %s and dataset %s.", n5, ds ) );
558-
}
559-
560545
public ExecutorService propagationExecutor()
561546
{
562547
return this.propagationExecutor;

0 commit comments

Comments
 (0)