Skip to content

Instantly share code, notes, and snippets.

@tinevez
Last active January 29, 2019 14:45
Show Gist options
  • Save tinevez/522d0db6ba895625cb054b274d73fdd2 to your computer and use it in GitHub Desktop.
Save tinevez/522d0db6ba895625cb054b274d73fdd2 to your computer and use it in GitHub Desktop.
A binning op based on Image-Ops.
@Plugin( type = BinningOp.class )
public class BinningOp< T extends RealType< T > > extends AbstractUnaryFunctionOp< RandomAccessibleInterval< T >, Img< T > >
{
@Parameter( type = ItemIO.INPUT )
private int[] binfactors;
@Parameter( type = ItemIO.INPUT, required = false )
private Class< ? extends Op > ocClass = Ops.Stats.Mean.class;
@Override
public Img< T > calculate( final RandomAccessibleInterval< T > input )
{
final int numDimensions = input.numDimensions();
if ( numDimensions != binfactors.length )
throw new IllegalArgumentException( "Bin n-dimensions and input n-dimensions must be equal. Bins have "
+ binfactors.length + " dimensions and input has " + numDimensions + " dimensions." );
// Prepare output.
final long[] imgSize = new long[ numDimensions ];
input.dimensions( imgSize );
final long[] newSize = new long[ numDimensions ];
for ( int d = 0; d < input.numDimensions(); ++d )
newSize[ d ] = input.dimension( d ) / binfactors[ d ];
final ImgFactory< T > factory = Util.getSuitableImgFactory( FinalDimensions.wrap( newSize ),
Util.getTypeFromInterval( input ) );
final Img< T > binned = factory.create( FinalDimensions.wrap( newSize ) );
final NotCenteredRectangleShape shape = new NotCenteredRectangleShape( binfactors );
final RandomAccessible< Neighborhood< T > > ran = shape.neighborhoodsRandomAccessible( Views.extendMirrorSingle( input ) );
@SuppressWarnings( { "rawtypes", "unchecked" } )
final UnaryComputerOp< Iterable< T >, T > op = ( UnaryComputerOp ) Computers.unary( ops(), ocClass, binned.firstElement().getClass(), Iterable.class );
// Multithread.
ops().run( ChunkerOp.class, new CursorBasedChunk()
{
@Override
public void execute( final int startIndex, final int stepSize, final int numSteps )
{
final RandomAccess< Neighborhood< T > > ra = ran.randomAccess( input );
final long[] currPos = new long[ input.numDimensions() ];
final Cursor< T > cursor = binned.localizingCursor();
cursor.jumpFwd( startIndex );
for ( int i = 0; i < numSteps; ++i )
{
cursor.next();
cursor.localize( currPos );
// 'Transform' coordinates.
for ( int d = 0; d < numDimensions; d++ )
currPos[ d ] *= binfactors[ d ];
// Iterate and compute.
ra.setPosition( currPos );
op.compute( ra.get(), cursor.get() );
}
}
}, binned.size() );
return binned;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment