/*- * #%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.concurrent.Callable; import net.imglib2.Cursor; import net.imglib2.IterableInterval; import net.imglib2.RandomAccess; import net.imglib2.RandomAccessibleInterval; import net.imglib2.type.numeric.real.FloatType; import net.imglib2.util.RealSum; import net.imglib2.view.Views; import spim.fiji.ImgLib2Temp.Pair; import spim.fiji.ImgLib2Temp.ValuePair; import spim.process.fusion.ImagePortion; /** * Fuse one portion of a paralell fusion, supports no weights * * @author Stephan Preibisch (stephan.preibisch@gmx.de) */ public class FirstIteration implements Callable< Pair< RealSum, Long > > { final ImagePortion portion; final RandomAccessibleInterval< FloatType > psi; final ArrayList< RandomAccessibleInterval< FloatType > > imgs; final IterableInterval< FloatType > psiIterable; final ArrayList< IterableInterval< FloatType > > iterableImgs; final RealSum realSum; boolean compatibleIteration; public FirstIteration( final ImagePortion portion, final RandomAccessibleInterval< FloatType > psi, final ArrayList< RandomAccessibleInterval< FloatType > > imgs ) { this.portion = portion; this.psi = psi; this.imgs = imgs; this.psiIterable = Views.iterable( psi ); this.iterableImgs = new ArrayList< IterableInterval< FloatType > >(); this.realSum = new RealSum(); compatibleIteration = true; for ( final RandomAccessibleInterval< FloatType > img : imgs ) { final IterableInterval< FloatType > imgIterable = Views.iterable( img ); if ( !psiIterable.iterationOrder().equals( imgIterable.iterationOrder() ) ) compatibleIteration = false; this.iterableImgs.add( imgIterable ); } } @Override public Pair< RealSum, Long > call() throws Exception { final Cursor< FloatType > psiCursor = psiIterable.localizingCursor(); psiCursor.jumpFwd( portion.getStartPosition() ); final int m = iterableImgs.size(); long count = 0; if ( compatibleIteration ) { final ArrayList< Cursor< FloatType > > cursorImgs = new ArrayList< Cursor< FloatType > >(); for ( final IterableInterval< FloatType > img : iterableImgs ) { final Cursor< FloatType > imgCursor = img.cursor(); imgCursor.jumpFwd( portion.getStartPosition() ); cursorImgs.add( imgCursor ); } for ( int j = 0; j < portion.getLoopSize(); ++j ) if ( compatibleLoop( psiCursor, cursorImgs, realSum, m ) > 0 ) ++count; } else { final ArrayList< RandomAccess< FloatType > > randomAccessImgs = new ArrayList< RandomAccess< FloatType > >(); for ( final RandomAccessibleInterval< FloatType > img : imgs ) randomAccessImgs.add( img.randomAccess() ); for ( int j = 0; j < portion.getLoopSize(); ++j ) if ( incompatibleLoop( psiCursor, randomAccessImgs, realSum, m ) > 0 ) ++count; } return new ValuePair< RealSum, Long >( realSum, new Long( count ) ); } private static final int compatibleLoop( final Cursor< FloatType > psiCursor, final ArrayList< Cursor< FloatType > > cursorImgs, final RealSum realSum, final int m ) { double sum = 0; int count = 0; for ( int j = 0; j < m; ++j ) { final double i = cursorImgs.get( j ).next().get(); if ( i > 0 ) { sum += i; ++count; } } if ( count > 0 ) { final double i = sum / count; realSum.add( i ); psiCursor.next().set( count ); // has data from n views (to be replaced with average intensity later) } else { psiCursor.next().set( 0 ); // no data (to be replaced with average intensity later) } return count; } private static final int incompatibleLoop( final Cursor< FloatType > psiCursor, final ArrayList< RandomAccess< FloatType > > randomAccessImgs, final RealSum realSum, final int m ) { final FloatType p = psiCursor.next(); double sum = 0; int count = 0; for ( int j = 0; j < m; ++j ) { final RandomAccess< FloatType > randomAccessImg = randomAccessImgs.get( j ); randomAccessImg.setPosition( psiCursor ); final double i = randomAccessImg.get().get(); if ( i > 0 ) { sum += i; ++count; } } if ( count > 0 ) { final double i = sum / count; realSum.add( i ); p.set( count ); // has data from n views (to be replaced with average intensity later) } else { p.set( 0 ); // no data (to be replaced with average intensity later) } return count; } }