/*-
* #%L
* Fiji distribution of ImageJ for the life sciences.
* %%
* Copyright (C) 2007 - 2017 Fiji developers.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-2.0.html>.
* #L%
*/
package spim.process.fusion.deconvolution;
import java.util.ArrayList;
import java.util.Random;
import java.util.Vector;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import spim.Threads;
import spim.process.fusion.FusionHelper;
import spim.process.fusion.ImagePortion;
import net.imglib2.Cursor;
import net.imglib2.IterableInterval;
import net.imglib2.type.numeric.real.FloatType;
import mpicbg.spim.io.IOFunctions;
import mpicbg.util.RealSum;
public class AdjustInput
{
public static Random rnd = new Random( 14235235 );
/**
* Norms an image so that the sum over all pixels is 1.
*
* @param img - the {@link IterableInterval} to normalize
*/
final public static void normImg( final IterableInterval< FloatType > img )
{
final double sum = sumImg( img );
for ( final FloatType t : img )
t.set( (float) ((double)t.get() / sum) );
}
/**
* @param img - the input {@link IterableInterval}
* @return - the sum of all pixels using {@link RealSum}
*/
final public static double sumImg( final IterableInterval< FloatType > img )
{
final int numPortions = Threads.numThreads() * 2;
final RealSum[] sums = new RealSum[ numPortions ];
final AtomicInteger ai = new AtomicInteger( 0 );
// split up into many parts for multithreading
final Vector< ImagePortion > portions = FusionHelper.divideIntoPortions( img.size(), numPortions );
// set up executor service
final ExecutorService taskExecutor = Executors.newFixedThreadPool( Threads.numThreads() );
final ArrayList< Callable< Void > > tasks = new ArrayList< Callable< Void > >();
for ( final ImagePortion portion : portions )
{
tasks.add( new Callable< Void >()
{
@Override
public Void call() throws Exception
{
final int id = ai.getAndIncrement();
final RealSum sum = new RealSum();
final Cursor< FloatType > c = img.cursor();
c.jumpFwd( portion.getStartPosition() );
for ( long j = 0; j < portion.getLoopSize(); ++j )
sum.add( c.next().get() );
sums[ id ] = sum;
return null;
}
});
}
try
{
// invokeAll() returns when all tasks are complete
taskExecutor.invokeAll( tasks );
}
catch ( final InterruptedException e )
{
IOFunctions.println( "Failed to compute sumImage: " + e );
e.printStackTrace();
return Double.NaN;
}
taskExecutor.shutdown();
final RealSum sum = new RealSum();
sum.add( sums[ 0 ].getSum() );
for ( final RealSum s : sums )
sum.add( s.getSum() );
return sum.getSum();
}
}