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

BlockSupplier API and block algorithm improvements #104

Merged
merged 24 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
982d2d8
POM: Bump parent to pom-scijava-38.0.1
tpietzsch Sep 15, 2024
9bc46b6
POM: Bump dependency versions
tpietzsch Sep 15, 2024
94762e8
Simplify BlockProcessor.setTargetInterval(long[], int[]) default impl…
tpietzsch Sep 15, 2024
2cd828c
bugfix
tpietzsch Sep 14, 2024
86a679c
Add BlockSupplier.numDimensions()
tpietzsch Jul 1, 2024
48c90c2
Add UnaryBlockOperator.numDimensions()
tpietzsch Jul 3, 2024
11580a5
Add BlockSupplier.tile(int...) default method
tpietzsch Jul 6, 2024
f9f3c30
Add auto-generation comment to TransformLine2D/3D
tpietzsch Jul 3, 2024
b7206d2
Add BlockSupplier.andThen(...) with operator-generating Function
tpietzsch Jul 1, 2024
c0f3bb7
Convert: add operator factories, refactor, javadoc
tpietzsch Jul 4, 2024
529c004
Remove unnecessary type arguments from ConvertBlockProcessor
tpietzsch Jul 15, 2024
c12668b
ConvertScalars: make public, move to blocks.util package, add _clamp_…
tpietzsch Jul 17, 2024
9f537f6
Make ClampType global
tpietzsch Jul 22, 2024
97d84ec
ConvertLoops: clamp_min
tpietzsch Sep 15, 2024
965387f
Downsample: add operator factories, refactor, javadoc
tpietzsch Sep 15, 2024
58ade11
Transform: add operator factories, refactor, javadoc
tpietzsch Jul 4, 2024
c181a81
Make ComputationType global
tpietzsch Jul 22, 2024
6a0d711
New BlockAvg Downsample variants
tpietzsch Sep 3, 2024
8e793cc
fix javadoc
tpietzsch Sep 11, 2024
bc74610
Add No-Op UnaryBlockOperator that is used when converting type to itself
tpietzsch Sep 11, 2024
4546a8a
Pull BlockSupplier.threadSafe() implementation into AbstractBlockSupp…
tpietzsch Sep 11, 2024
c41149a
Wrap BlockProcessor.setTargetInterval(long[] pos, int[] size) as Inte…
tpietzsch Sep 11, 2024
0ebbccc
Add AbstractBlockProcessor to reduce boiler-plate in BlockProcessor i…
tpietzsch Sep 11, 2024
3db98ed
Add javadoc
tpietzsch Sep 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.scijava</groupId>
<artifactId>pom-scijava</artifactId>
<version>37.0.0</version>
<version>38.0.1</version>
<relativePath />
</parent>

Expand Down Expand Up @@ -201,11 +201,11 @@ Jean-Yves Tinevez and Michael Zinsmaier.</license.copyrightOwners>
<!-- NB: Deploy releases to the SciJava Maven repository. -->
<releaseProfiles>sign,deploy-to-scijava</releaseProfiles>

<imglib2.version>7.0.3</imglib2.version>
<imglib2.version>7.1.1</imglib2.version>
<imglib2-realtransform.version>4.0.3</imglib2-realtransform.version>
<imglib2-roi.version>0.15.0</imglib2-roi.version>
<imglib2-roi.version>0.15.1</imglib2-roi.version>
<imglib2-cache.version>1.0.0-beta-18</imglib2-cache.version>
<sc.fiji.bigdataviewer-core.version>10.4.16</sc.fiji.bigdataviewer-core.version>
<sc.fiji.bigdataviewer-core.version>10.6.1</sc.fiji.bigdataviewer-core.version>
</properties>

<repositories>
Expand Down Expand Up @@ -255,11 +255,6 @@ Jean-Yves Tinevez and Michael Zinsmaier.</license.copyrightOwners>
<artifactId>bigdataviewer-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>sc.fiji</groupId>
<artifactId>bigdataviewer-vistools</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.imglib2</groupId>
<artifactId>imglib2-ij</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package net.imglib2.algorithm.blocks;

import static net.imglib2.util.Util.safeInt;

import java.util.Arrays;

import net.imglib2.Interval;
import net.imglib2.algorithm.blocks.util.BlockProcessorSourceInterval;
import net.imglib2.blocks.TempArray;
import net.imglib2.type.PrimitiveType;
import net.imglib2.util.Intervals;

/**
* Boilerplate for {@link BlockProcessor} to simplify implementations.
* <p>
* This is intented as a base class for {@code BlockProcessor} that have source
* dimensionality fixed at construction. For {@code BlockProcessor} with
* adaptable number of dimensions (such as converters), see {@link
* AbstractDimensionlessBlockProcessor}.
* <p>
* {@link BlockProcessor#getSourcePos() getSourcePos()}, {@link
* BlockProcessor#getSourceSize() getSourceSize()}, and {@link
* BlockProcessor#getSourceInterval() getSourceInterval()} are implemented to
* return the {@code protected} fields {@code long[] sourcePos} and {@code
* }int[] sourceSize}. The {@code }protected} method {@code }int sourceLength()}
* can be used to get the number of elements in the source interval.
* <p>
* {@link BlockProcessor#getSourceBuffer() getSourceBuffer()} is implemented
* according to the {@code sourcePrimitiveType} specified at construction.
*
* @param <I>
* input primitive array type, e.g., float[]
* @param <O>
* output primitive array type, e.g., float[]
*/
public abstract class AbstractBlockProcessor< I, O > implements BlockProcessor< I, O >
{
private final TempArray< I > tempArray;

protected final long[] sourcePos;

protected final int[] sourceSize;

private final BlockProcessorSourceInterval sourceInterval = new BlockProcessorSourceInterval( this );

protected AbstractBlockProcessor( final PrimitiveType sourcePrimitiveType, final int numSourceDimensions )
{
tempArray = TempArray.forPrimitiveType( sourcePrimitiveType );
sourcePos = new long[ numSourceDimensions ];
sourceSize = new int[ numSourceDimensions ];
}

protected AbstractBlockProcessor( final AbstractBlockProcessor< I, O > proc )
{
tempArray = proc.tempArray.newInstance();
final int numSourceDimensions = proc.sourcePos.length;
sourcePos = new long[ numSourceDimensions ];
sourceSize = new int[ numSourceDimensions ];
}

protected int sourceLength()
{
return safeInt( Intervals.numElements( sourceSize ) );
}

@Override
public void setTargetInterval( final Interval interval )
{
interval.min( sourcePos );
Arrays.setAll( sourceSize, d -> safeInt( interval.dimension( d ) ) );
}

@Override
public long[] getSourcePos()
{
return sourcePos;
}

@Override
public int[] getSourceSize()
{
return sourceSize;
}

@Override
public Interval getSourceInterval()
{
return sourceInterval;
}

@Override
public I getSourceBuffer()
{
return tempArray.get( sourceLength() );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package net.imglib2.algorithm.blocks;

import java.util.function.Supplier;

import net.imglib2.type.NativeType;
import net.imglib2.util.CloseableThreadLocal;

/**
* Boilerplate for {@link BlockSupplier} to simplify implementations.
* <p>
* Implements {@link BlockSupplier#threadSafe()} as a wrapper that makes {@link
* ThreadLocal} {@link BlockSupplier#independentCopy()} copies.
*/
public abstract class AbstractBlockSupplier< T extends NativeType< T > > implements BlockSupplier< T >
{
private Supplier< BlockSupplier< T > > threadSafeSupplier;

@Override
public BlockSupplier< T > threadSafe()
{
if ( threadSafeSupplier == null )
threadSafeSupplier = CloseableThreadLocal.withInitial( this::independentCopy )::get;
return new BlockSupplier< T >()
{
@Override
public T getType()
{
return AbstractBlockSupplier.this.getType();
}

@Override
public int numDimensions()
{
return AbstractBlockSupplier.this.numDimensions();
}

@Override
public void copy( final long[] srcPos, final Object dest, final int[] size )
{
threadSafeSupplier.get().copy( srcPos, dest, size );
}

@Override
public BlockSupplier< T > independentCopy()
{
return AbstractBlockSupplier.this.independentCopy().threadSafe();
}

@Override
public BlockSupplier< T > threadSafe()
{
return this;
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package net.imglib2.algorithm.blocks;

import static net.imglib2.util.Util.safeInt;

import java.util.Arrays;

import net.imglib2.Interval;
import net.imglib2.algorithm.blocks.util.BlockProcessorSourceInterval;
import net.imglib2.blocks.TempArray;
import net.imglib2.type.PrimitiveType;
import net.imglib2.util.Intervals;

/**
* Boilerplate for {@link BlockProcessor} to simplify implementations.
* <p>
* This is intented as a base class for {@code BlockProcessor} with an adaptable
* number of dimensions (such as converters). For {@code BlockProcessor} with a
* fixed number of source dimensions, see {@link AbstractBlockProcessor}.
* <p>
* {@link BlockProcessor#getSourcePos() getSourcePos()}, {@link
* BlockProcessor#getSourceSize() getSourceSize()}, and {@link
* BlockProcessor#getSourceInterval() getSourceInterval()} are implemented to
* return the {@code protected} fields {@code long[] sourcePos} and {@code
* }int[] sourceSize}. The {@code }protected} method {@code }int sourceLength()}
* can be used to get the number of elements in the source interval.
* <p>
* {@link BlockProcessor#getSourceBuffer() getSourceBuffer()} is implemented
* according to the {@code sourcePrimitiveType} specified at construction.
*
* @param <I>
* input primitive array type, e.g., float[]
* @param <O>
* output primitive array type, e.g., float[]
*/
public abstract class AbstractDimensionlessBlockProcessor< I, O > implements BlockProcessor< I, O >
{
private final TempArray< I > tempArray;

protected long[] sourcePos;

protected int[] sourceSize;

private final BlockProcessorSourceInterval sourceInterval = new BlockProcessorSourceInterval( this );

protected AbstractDimensionlessBlockProcessor( final PrimitiveType sourcePrimitiveType )
{
tempArray = TempArray.forPrimitiveType( sourcePrimitiveType );
}

protected AbstractDimensionlessBlockProcessor( final AbstractDimensionlessBlockProcessor< I, O > proc )
{
tempArray = proc.tempArray.newInstance();
}

@Override
public void setTargetInterval( final Interval interval )
{
updateNumSourceDimsensions( interval.numDimensions() );
interval.min( sourcePos );
Arrays.setAll( sourceSize, d -> safeInt( interval.dimension( d ) ) );
}

/**
* Re-allocates {@code sourcePos} and {@code sourceSize} arrays if they do
* not already exist and have {@code length==n}.
*
* @param n
* new number of source dimensions
*
* @return {@code true} if {@code sourcePos} and {@code sourceSize} arrays were re-allocated
*/
protected boolean updateNumSourceDimsensions( final int n )
{
if ( sourcePos == null || sourcePos.length != n )
{
sourcePos = new long[ n ];
sourceSize = new int[ n ];
return true;
}
return false;
}

protected int sourceLength()
{
return safeInt( Intervals.numElements( sourceSize ) );
}

@Override
public long[] getSourcePos()
{
return sourcePos;
}

@Override
public int[] getSourceSize()
{
return sourceSize;
}

@Override
public Interval getSourceInterval()
{
return sourceInterval;
}

@Override
public I getSourceBuffer()
{
return tempArray.get( sourceLength() );
}
}
12 changes: 2 additions & 10 deletions src/main/java/net/imglib2/algorithm/blocks/BlockProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@
*/
package net.imglib2.algorithm.blocks;

import java.util.Arrays;

import net.imglib2.FinalInterval;
import net.imglib2.Interval;
import net.imglib2.blocks.PrimitiveBlocks;

Expand All @@ -59,20 +56,15 @@ public interface BlockProcessor< I, O >

void setTargetInterval( Interval interval );

default void setTargetInterval( long[] srcPos, int[] size )
default void setTargetInterval( long[] pos, int[] size )
{
final long[] srcMax = new long[ srcPos.length ];
Arrays.setAll( srcMax, d -> srcPos[ d ] + size[ d ] - 1 );
setTargetInterval( FinalInterval.wrap( srcPos, srcMax ) );
setTargetInterval( new BlockProcessorTargetInterval( pos, size ) );
}

long[] getSourcePos();

int[] getSourceSize();

// TODO: Its cumbersome to have both getSourcePos()/getSourceSize() *and* getSourceInterval()
// Only have getSourcePos()/getSourceSize() ?
// Have a modifiable SourceInterval class exposing getSourcePos()/getSourceSize() ?
Interval getSourceInterval();

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package net.imglib2.algorithm.blocks;

import net.imglib2.Interval;

/**
* Wraps {@code long[] pos} and {@code int[] size} as a {@code Interval}, for
* the default implementation of {@link BlockProcessor#setTargetInterval(long[],
* int[])}.
*/
class BlockProcessorTargetInterval implements Interval
{
private final long[] min;

private final int[] size;

BlockProcessorTargetInterval( long[] min, int[] size )
{
this.min = min;
this.size = size;
}

@Override
public long min( final int i )
{
return min[ i ];
}

@Override
public long max( final int i )
{
return min[ i ] + size[ i ] - 1;
}

@Override
public long dimension( final int d )
{
return size[ d ];
}

@Override
public int numDimensions()
{
return min.length;
}
}
Loading
Loading