gt: 												if (combW.length > 0)
context: package mpicbg.spim.fusion;
  
  import ij.IJ;
  
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.concurrent.atomic.AtomicInteger;
  
  import org.scijava.vecmath.Point3d;
  
  import mpicbg.imglib.cursor.LocalizableCursor;
  import mpicbg.imglib.image.Image;
  import mpicbg.imglib.image.ImageFactory;
  import mpicbg.imglib.image.display.imagej.ImageJFunctions;
  import mpicbg.imglib.interpolation.Interpolator;
  import mpicbg.imglib.multithreading.SimpleMultiThreading;
  import mpicbg.imglib.type.numeric.real.FloatType;
  import mpicbg.imglib.util.Util;
  import mpicbg.models.AbstractAffineModel3D;
  import mpicbg.models.NoninvertibleModelException;
  import mpicbg.spim.io.IOFunctions;
  import mpicbg.spim.registration.ViewDataBeads;
  import mpicbg.spim.registration.ViewStructure;
  
  public class MappingFusionSequentialDifferentOutput extends SPIMImageFusion
  {
  	final Image<FloatType> fusedImages[];
  	final int numViews;
  	final int numParalellStacks;
  	
  	public static int[] angleIndiciesStatic = null;
  	public int[] angleIndicies = null;
  
  	public MappingFusionSequentialDifferentOutput( final ViewStructure viewStructure, final ViewStructure referenceViewStructure,
  			  									   final ArrayList<IsolatedPixelWeightenerFactory<?>> isolatedWeightenerFactories,
  			  									   final ArrayList<CombinedPixelWeightenerFactory<?>> combinedWeightenerFactories,
  			  									   final int numParalellStacks )
  	{
  		super( viewStructure, referenceViewStructure, isolatedWeightenerFactories, combinedWeightenerFactories );
  
  		numViews = viewStructure.getNumViews();
  
  		if ( viewStructure.getDebugLevel() <= ViewStructure.DEBUG_MAIN )
  			IOFunctions.println("(" + new Date(System.currentTimeMillis()) + "): Reserving memory for fused images.");
  
  		if ( angleIndiciesStatic == null )
  		{
  			angleIndicies = new int[ numViews ];
  
  			for ( int view = 0; view < numViews; view++ )
  				angleIndicies[ view ] = view;
  		}
  		else
  		{
  			if ( viewStructure.getDebugLevel() <= ViewStructure.DEBUG_MAIN )
  				IOFunctions.println("(" + new Date(System.currentTimeMillis()) + "): WARNING: Using statically defined angle-indices from class mpicbg.spim.fusion.MappingFusionSequentialDifferentOutput: " + Util.printCoordinates( angleIndicies ) );
  			
  			angleIndicies = angleIndiciesStatic.clone();
  		}
  
  		this.numParalellStacks = numParalellStacks;
  
  		IJ.log( "nump = " + numParalellStacks );
  
  		fusedImages = new Image[ angleIndicies.length ];
  		final ImageFactory<FloatType> fusedImageFactory = new ImageFactory<FloatType>( new FloatType(), conf.processImageFactory );
  
  		final long size = (4l * imgW * imgH * imgD)/(1000l*1000l);
  
  		for (int i = 0; i < angleIndicies.length; i++)
  		{
  			if ( viewStructure.getDebugLevel() <= ViewStructure.DEBUG_MAIN )
  				IOFunctions.println( "(" + new Date(System.currentTimeMillis()) + "): Reserving " + size + " MiB for '" + viewStructure.getViews().get( angleIndicies[i] ).getName() + "'" );
  
  			fusedImages[ i ] = fusedImageFactory.createImage( new int[]{ imgW, imgH, imgD }, "Fused image" );
  
  			if ( fusedImages[i] == null && viewStructure.getDebugLevel() <= ViewStructure.DEBUG_ERRORONLY )
  				IOFunctions.printErr("MappingFusionSequentialDifferentOutput.constructor: Cannot create output image: " + conf.processImageFactory.getErrorMessage());
  		}
  	}
  
  	@Override
  	public void fuseSPIMImages( final int channelIndex )
  	{
  		// here we do all at once
  		if ( channelIndex > 0 )
  			return;
  
  		if ( viewStructure.getDebugLevel() <= ViewStructure.DEBUG_MAIN )
  			IOFunctions.println("(" + new Date(System.currentTimeMillis()) + "): Unloading source images.");
  
  		//
  		// get all views of all channels
  		//
  		final ArrayList<ViewDataBeads> views = viewStructure.getViews();
  		final int numViews = angleIndicies.length;
  
  		// unload images
  		for ( final ViewDataBeads view : views )
  			view.closeImage();
  
  		if ( viewStructure.getDebugLevel() <= ViewStructure.DEBUG_MAIN )
  			IOFunctions.println("(" + new Date(System.currentTimeMillis()) + "): Computing output image.");
  
  		// iterate over input images in steps of numParalellStacks
  		for ( int v = 0; v < angleIndicies.length; v += numParalellStacks )
  		{
  			final int viewIndexStart = v;
  			final int viewIndexEnd = Math.min( v + numParalellStacks, numViews );
  		
  			// open input images
  			//for ( int viewIndex = 0; viewIndex < angleIndicies.length; viewIndex++ )
  			for ( int viewIndex = viewIndexStart; viewIndex < viewIndexEnd; viewIndex++ )
  			{
  				if ( viewStructure.getDebugLevel() <= ViewStructure.DEBUG_MAIN )
  					IOFunctions.println("(" + new Date(System.currentTimeMillis()) + "): Loading view: " + views.get( angleIndicies[ viewIndex ] ).getName() );
  				
  				views.get( angleIndicies[ viewIndex ] ).getImage( false );
  			}
  			
  			// compute output images in paralell
  			final AtomicInteger ai = new AtomicInteger(0);
  	        final Thread[] threads = SimpleMultiThreading.newThreads(conf.numberOfThreads);
  	        final int numThreads = threads.length;
  	
  			for (int ithread = 0; ithread < threads.length; ++ithread)
  	            threads[ithread] = new Thread(new Runnable()
  	            {
  	                @Override
  					public void run()
  	                {
  	                	final int myNumber = ai.getAndIncrement();
  	
  						//for ( int viewIndex = 0; viewIndex < angleIndicies.length; viewIndex++ )
  						for ( int viewIndex = viewIndexStart; viewIndex < viewIndexEnd; viewIndex++ )
  							if ( viewIndex % numThreads == myNumber)
  							{
  								final ViewDataBeads view = views.get( angleIndicies[ viewIndex ] );
  	
  								IOFunctions.println( "(" + new Date(System.currentTimeMillis()) + "): Computing individual registered image for '" + view.getName() + "'" );
  	
  								if ( Math.max( view.getTile().getConnectedTiles().size(), view.getViewErrorStatistics().getNumConnectedViews() ) <= 0 && view.getViewStructure().getNumViews() > 1 )
  								{
  									if ( viewStructure.getDebugLevel() <= ViewStructure.DEBUG_ERRORONLY )
  										IOFunctions.println("(" + new Date(System.currentTimeMillis()) + "): Cannot use view '" + view.getName() + ", view is not connected to any other view.");
  	
  									continue;
  								}
  	
  								final Image<FloatType> img = view.getImage( conf.inputImageFactory, false );
  								final Interpolator<FloatType> interpolator = img.createInterpolator( conf.interpolatorFactorOutput );
  	
  								final Point3d tmpCoordinates = new Point3d();
  	
  								final int[] imageSize = view.getImageSize();
  								final int w = imageSize[ 0 ];
  								final int h = imageSize[ 1 ];
  								final int d = imageSize[ 2 ];
  	
  								final AbstractAffineModel3D<?> model = (AbstractAffineModel3D<?>)view.getTile().getModel();
  	
  								// temporary float array
  					        	final double[] tmp = new double[ 3 ];
  	
  	
  					    		final CombinedPixelWeightener<?>[] combW = new CombinedPixelWeightener<?>[combinedWeightenerFactories.size()];
  					    		for (int i = 0; i < combW.length; i++)
  					    			combW[i] = combinedWeightenerFactories.get(i).createInstance( views );
  	
  								final double[][] loc = new double[ numViews ][ 3 ];
  								final boolean[] use = new boolean[ numViews ];
  	
  								for ( int v = 0; v < numViews; ++v )
  								{
  									use[ v ] = true;
  									for ( int i = 0; i < 3; ++i )
  										loc[ v ][ i ] = viewStructure.getViews().get( v ).getImageSize()[ i ] / 2;
  								}
  	
  								if ( viewStructure.getDebugLevel() <= ViewStructure.DEBUG_MAIN )
  									IOFunctions.println("(" + new Date(System.currentTimeMillis()) + "): Starting fusion for: " + view.getName());
  	
  								final LocalizableCursor<FloatType> iteratorFused = fusedImages[ viewIndex ].createLocalizableCursor();
  	
  								try
  								{
  									while (iteratorFused.hasNext())
  									{
  										iteratorFused.next();
  	
  										// get the coordinates if cropped
  										final int x = iteratorFused.getPosition(0) + cropOffsetX;
  										final int y = iteratorFused.getPosition(1) + cropOffsetY;
  										final int z = iteratorFused.getPosition(2) + cropOffsetZ;
  	
  										tmpCoordinates.x = x * scale + min.x;
  										tmpCoordinates.y = y * scale + min.y;
  										tmpCoordinates.z = z * scale + min.z;
  	
  										mpicbg.spim.mpicbg.Java3d.applyInverseInPlace( model, tmpCoordinates, tmp );
  	
  										final int locX = (int)Util.round( tmpCoordinates.x );
  										final int locY = (int)Util.round( tmpCoordinates.y );
  										final int locZ = (int)Util.round( tmpCoordinates.z );
  	
  										// do we hit the source image?
  										if (locX >= 0 && locY >= 0 && locZ >= 0 &&
  											locX < w  && locY < h  && locZ < d )
  											{
  												float weight = 1;
  	
  												// update combined weighteners
  