Skip to content

Commit 7fe1eaf

Browse files
committed
Change SubpixelLocalization to use the Parallelization framework
1 parent 23ea534 commit 7fe1eaf

File tree

1 file changed

+53
-54
lines changed

1 file changed

+53
-54
lines changed

src/main/java/net/imglib2/algorithm/localextrema/SubpixelLocalization.java

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,19 @@
3636

3737
import java.util.ArrayList;
3838
import java.util.Arrays;
39-
import java.util.Collections;
4039
import java.util.List;
41-
import java.util.concurrent.ExecutorService;
42-
import java.util.concurrent.Executors;
43-
import java.util.concurrent.TimeUnit;
4440

41+
import net.imglib2.FinalInterval;
4542
import net.imglib2.Interval;
4643
import net.imglib2.Localizable;
4744
import net.imglib2.Point;
4845
import net.imglib2.RandomAccess;
4946
import net.imglib2.RandomAccessible;
5047
import net.imglib2.RealPoint;
5148
import net.imglib2.RealPositionable;
49+
import net.imglib2.loops.IntervalChunks;
50+
import net.imglib2.parallel.Parallelization;
51+
import net.imglib2.parallel.TaskExecutor;
5252
import net.imglib2.type.numeric.RealType;
5353
import net.imglib2.util.Intervals;
5454
import Jama.LUDecomposition;
@@ -59,7 +59,7 @@
5959
* {@link #refinePeaks(List, RandomAccessible, Interval, boolean, int, boolean, float, boolean[], int)}
6060
* method to do this, but this has a lot of parameters. Therefore, this class
6161
* can also be instantiated to encapsulate the parameter settings.
62-
*
62+
*
6363
* <p>
6464
* A List {@link RefinedPeak} for the given list of {@link Localizable} is
6565
* computed by, for each peak, fitting a quadratic function to the image and
@@ -68,7 +68,7 @@
6868
* repeated at the corresponding integer coordinates. This is repeated to
6969
* convergence, for a maximum number of iterations, or until the integer
7070
* coordinates move out of the valid image.
71-
*
71+
*
7272
* @author Stephan Preibisch
7373
* @author Tobias Pietzsch
7474
*/
@@ -93,8 +93,6 @@ public SubpixelLocalization( final int numDimensions )
9393
// principally one can move in any dimension
9494
allowedToMoveInDim = new boolean[ numDimensions ];
9595
Arrays.fill( allowedToMoveInDim, true );
96-
97-
numThreads = Runtime.getRuntime().availableProcessors();
9896
}
9997

10098
public void setAllowMaximaTolerance( final boolean allowMaximaTolerance )
@@ -164,14 +162,14 @@ public boolean getReturnInvalidPeaks()
164162

165163
public int getNumThreads()
166164
{
167-
return numThreads;
165+
return numThreads == 0 ? Parallelization.getTaskExecutor().getParallelism() : numThreads;
168166
}
169167

170168
/**
171169
* Refine a set of peaks to subpixel coordinates. Calls
172170
* {@link #refinePeaks(List, RandomAccessible, Interval, boolean, int, boolean, float, boolean[], int)}
173171
* with the parameters set to this object.
174-
*
172+
*
175173
* @param peaks
176174
* List of integer peaks.
177175
* @param img
@@ -184,7 +182,13 @@ public int getNumThreads()
184182
*/
185183
public ArrayList< RefinedPeak< P > > process( final List< P > peaks, final RandomAccessible< T > img, final Interval validInterval )
186184
{
187-
return refinePeaks( peaks, img, validInterval, returnInvalidPeaks, maxNumMoves, allowMaximaTolerance, maximaTolerance, allowedToMoveInDim, numThreads );
185+
if ( numThreads != 0 )
186+
return Parallelization.runWithNumThreads( numThreads,
187+
() -> refinePeaks( peaks, img, validInterval, returnInvalidPeaks, maxNumMoves,
188+
allowMaximaTolerance, maximaTolerance, allowedToMoveInDim ) );
189+
else
190+
return refinePeaks( peaks, img, validInterval, returnInvalidPeaks, maxNumMoves,
191+
allowMaximaTolerance, maximaTolerance, allowedToMoveInDim );
188192
}
189193

190194
/**
@@ -197,7 +201,7 @@ public ArrayList< RefinedPeak< P > > process( final List< P > peaks, final Rando
197201
* fit is repeated at the corresponding integer coordinates. This is
198202
* repeated to convergence, for a maximum number of iterations, or until the
199203
* integer coordinates move out of the valid image.
200-
*
204+
*
201205
* @param peaks
202206
* List of integer peaks.
203207
* @param img
@@ -231,45 +235,9 @@ public static < T extends RealType< T >, P extends Localizable > ArrayList< Refi
231235
final int maxNumMoves, final boolean allowMaximaTolerance, final float maximaTolerance, final boolean[] allowedToMoveInDim,
232236
final int numThreads )
233237
{
234-
final int numPeaks = peaks.size();
235-
final ArrayList< RefinedPeak< P > > allRefinedPeaks = new ArrayList< RefinedPeak< P > >( numPeaks );
236-
237-
if ( numPeaks == 0 )
238-
return allRefinedPeaks;
239-
240-
final int numTasks = numThreads <= 1 ? 1 : ( int ) Math.min( numPeaks, numThreads * 20 );
241-
final int taskSize = numPeaks / numTasks;
242-
243-
final ExecutorService ex = Executors.newFixedThreadPool( numThreads );
244-
final List< RefinedPeak< P > > synchronizedAllRefinedPeaks = Collections.synchronizedList( allRefinedPeaks );
245-
for ( int taskNum = 0; taskNum < numTasks; ++taskNum )
246-
{
247-
final int fromIndex = taskNum * taskSize;
248-
final int toIndex = ( taskNum == numTasks - 1 ) ? numPeaks : fromIndex + taskSize;
249-
final Runnable r = new Runnable()
250-
{
251-
@Override
252-
public void run()
253-
{
254-
final ArrayList< RefinedPeak< P > > refinedPeaks = refinePeaks(
255-
peaks.subList( fromIndex, toIndex ),
256-
img, validInterval, returnInvalidPeaks, maxNumMoves, allowMaximaTolerance, maximaTolerance, allowedToMoveInDim );
257-
synchronizedAllRefinedPeaks.addAll( refinedPeaks );
258-
}
259-
};
260-
ex.execute( r );
261-
}
262-
ex.shutdown();
263-
try
264-
{
265-
ex.awaitTermination( 1000, TimeUnit.DAYS );
266-
}
267-
catch ( final InterruptedException e )
268-
{
269-
e.printStackTrace();
270-
}
271-
272-
return allRefinedPeaks;
238+
return Parallelization.runWithNumThreads( numThreads,
239+
() -> refinePeaks( peaks, img, validInterval, returnInvalidPeaks, maxNumMoves, allowMaximaTolerance, maximaTolerance,
240+
allowedToMoveInDim ) );
273241
}
274242

275243
/**
@@ -282,7 +250,7 @@ public void run()
282250
* fit is repeated at the corresponding integer coordinates. This is
283251
* repeated to convergence, for a maximum number of iterations, or until the
284252
* integer coordinates move out of the valid image.
285-
*
253+
*
286254
* @param peaks
287255
* List of integer peaks.
288256
* @param img
@@ -313,7 +281,38 @@ public static < T extends RealType< T >, P extends Localizable > ArrayList< Refi
313281
final List< P > peaks, final RandomAccessible< T > img, final Interval validInterval, final boolean returnInvalidPeaks,
314282
final int maxNumMoves, final boolean allowMaximaTolerance, final float maximaTolerance, final boolean[] allowedToMoveInDim )
315283
{
316-
final ArrayList< RefinedPeak< P >> refinedPeaks = new ArrayList< RefinedPeak< P > >();
284+
final int numPeaks = peaks.size();
285+
286+
if ( numPeaks == 0 )
287+
return new ArrayList<>();
288+
289+
TaskExecutor taskExecutor = Parallelization.getTaskExecutor();
290+
291+
List< Interval > chunks = IntervalChunks.chunkInterval( new FinalInterval( numPeaks ), taskExecutor.suggestNumberOfTasks() );
292+
293+
List< ArrayList< RefinedPeak< P > > > result = taskExecutor.forEachApply( chunks, chunk ->
294+
refinePeaksChunk(
295+
peaks.subList( ( int ) chunk.min( 0 ), ( int ) chunk.max( 0 ) + 1 ),
296+
img, validInterval, returnInvalidPeaks, maxNumMoves, allowMaximaTolerance,
297+
maximaTolerance, allowedToMoveInDim )
298+
);
299+
300+
return concatenate( result );
301+
}
302+
303+
private static < P > ArrayList< P > concatenate( List< ? extends List< ? extends P > > lists )
304+
{
305+
int size = lists.stream().mapToInt( List::size ).sum();
306+
ArrayList< P > result = new ArrayList<>( size );
307+
lists.forEach( result::addAll );
308+
return result;
309+
}
310+
311+
public static < T extends RealType< T >, P extends Localizable > ArrayList< RefinedPeak< P > > refinePeaksChunk(
312+
final List< P > peaks, final RandomAccessible< T > img, final Interval validInterval, final boolean returnInvalidPeaks,
313+
final int maxNumMoves, final boolean allowMaximaTolerance, final float maximaTolerance, final boolean[] allowedToMoveInDim )
314+
{
315+
final ArrayList< RefinedPeak< P > > refinedPeaks = new ArrayList< RefinedPeak< P > >();
317316

318317
final int n = img.numDimensions();
319318

@@ -420,7 +419,7 @@ else if ( returnInvalidPeaks )
420419
/**
421420
* Estimate subpixel {@code offset} of extremum of quadratic function
422421
* fitted at {@code p}.
423-
*
422+
*
424423
* @param p
425424
* integer position at which to fit quadratic.
426425
* @param access

0 commit comments

Comments
 (0)