/*-
* #%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.fiji.spimdata.imgloaders;
import ij.ImagePlus;
import ij.io.Opener;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription;
import mpicbg.spim.data.generic.sequence.BasicViewDescription;
import mpicbg.spim.data.generic.sequence.BasicViewSetup;
import mpicbg.spim.data.sequence.Channel;
import mpicbg.spim.data.sequence.ViewId;
import mpicbg.spim.data.sequence.VoxelDimensions;
import mpicbg.spim.io.IOFunctions;
import net.imglib2.Dimensions;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.img.array.ArrayCursor;
import net.imglib2.img.array.ArrayImg;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.type.numeric.integer.UnsignedByteType;
import net.imglib2.type.numeric.integer.UnsignedShortType;
import net.imglib2.type.numeric.real.FloatType;
public class LegacyDHMImgLoader extends AbstractImgLoader
{
final File directory;
final AbstractSequenceDescription< ? extends BasicViewSetup, ? extends BasicViewDescription< ? >, ? > sd;
final List< String > timepoints;
final List< String > zPlanes;
final String stackDir;
final String amplitudeDir;
final String phaseDir;
final String extension;
final int ampChannelId;
final int phaseChannelId;
public LegacyDHMImgLoader(
final File directory,
final String stackDir,
final String amplitudeDir,
final String phaseDir,
final List< String > timepoints,
final List< String > zPlanes,
final String extension,
final int ampChannelId,
final int phaseChannelId,
final AbstractSequenceDescription< ? extends BasicViewSetup, ? extends BasicViewDescription< ? >, ? > sd )
{
this.directory = directory;
this.stackDir = stackDir;
this.amplitudeDir = amplitudeDir;
this.phaseDir = phaseDir;
this.timepoints = timepoints;
this.zPlanes = zPlanes;
this.extension = extension;
this.ampChannelId = ampChannelId;
this.phaseChannelId = phaseChannelId;
this.sd = sd;
}
public String getStackDir() { return stackDir; }
public String getAmplitudeDir() { return amplitudeDir; }
public String getPhaseDir() { return phaseDir; }
public List< String > getZPlanes() { return zPlanes; }
public List< String > getTimepoints() { return timepoints; }
public int getAmpChannelId() { return ampChannelId; }
public int getPhaseChannelId() { return phaseChannelId; }
public String getExt() { return extension; }
@Override
public RandomAccessibleInterval< FloatType > getFloatImage( final ViewId view, final boolean normalize )
{
final BasicViewDescription< ? > vd = sd.getViewDescriptions().get( view );
final Dimensions d = vd.getViewSetup().getSize();
final VoxelDimensions dv = vd.getViewSetup().getVoxelSize();
final ArrayImg< FloatType, ? > img = ArrayImgs.floats( d.dimension( 0 ), d.dimension( 1 ), d.dimension( 2 ) );
final String ampOrPhaseDir;
if ( vd.getViewSetup().getAttribute( Channel.class ).getId() == ampChannelId )
ampOrPhaseDir = amplitudeDir;
else if ( vd.getViewSetup().getAttribute( Channel.class ).getId() == phaseChannelId )
ampOrPhaseDir = phaseDir;
else
throw new RuntimeException( "viewSetupId=" + view.getViewSetupId() + " is not Amplitude nor phase." );
populateImage( img, directory, stackDir, ampOrPhaseDir, zPlanes, timepoints.get( view.getTimePointId() ), extension );
if ( normalize )
normalize( img );
updateMetaDataCache( view, (int)d.dimension( 0 ), (int)d.dimension( 1 ), (int)d.dimension( 2 ), dv.dimension( 0 ), dv.dimension( 1 ), dv.dimension( 2 ) );
return img;
}
@Override
public RandomAccessibleInterval< UnsignedShortType > getImage( final ViewId view )
{
final BasicViewDescription< ? > vd = sd.getViewDescriptions().get( view );
final Dimensions d = vd.getViewSetup().getSize();
final VoxelDimensions dv = vd.getViewSetup().getVoxelSize();
final ArrayImg< UnsignedShortType, ? > img = ArrayImgs.unsignedShorts( d.dimension( 0 ), d.dimension( 1 ), d.dimension( 2 ) );
final String ampOrPhaseDir;
if ( vd.getViewSetup().getAttribute( Channel.class ).getId() == ampChannelId )
ampOrPhaseDir = amplitudeDir;
else if ( vd.getViewSetup().getAttribute( Channel.class ).getId() == phaseChannelId )
ampOrPhaseDir = phaseDir;
else
throw new RuntimeException( "viewSetupId=" + view.getViewSetupId() + " is not Amplitude nor phase." );
populateImage( img, directory, stackDir, ampOrPhaseDir, zPlanes, timepoints.get( view.getTimePointId() ), extension );
updateMetaDataCache( view, (int)d.dimension( 0 ), (int)d.dimension( 1 ), (int)d.dimension( 2 ), dv.dimension( 0 ), dv.dimension( 1 ), dv.dimension( 2 ) );
return img;
}
@Override
protected void loadMetaData( ViewId view )
{
final BasicViewDescription< ? > vd = sd.getViewDescriptions().get( view );
final Dimensions d = vd.getViewSetup().getSize();
final VoxelDimensions dv = vd.getViewSetup().getVoxelSize();
updateMetaDataCache( view, (int)d.dimension( 0 ), (int)d.dimension( 1 ), (int)d.dimension( 2 ), dv.dimension( 0 ), dv.dimension( 1 ), dv.dimension( 2 ) );
}
final public static < T extends RealType< T > & NativeType< T > > void populateImage(
final ArrayImg< T, ? > img,
final File directory,
final String stackDir,
final String ampOrPhaseDirectory,
final List< String > zPlanes,
final String timepoint,
final String extension )
{
final Opener io = new Opener();
final ArrayCursor< T > cursor = img.cursor();
int countDroppedFrames = 0;
ArrayList< Integer > slices = null;
for ( int z = 0; z < zPlanes.size(); ++z )
{
final File imgF = new File( new File( new File( new File( directory.getAbsolutePath(), stackDir ), ampOrPhaseDirectory ), zPlanes.get( z ) ), timepoint + extension );
final ImagePlus imp = io.openImage( imgF.getAbsolutePath() );
if ( imp == null )
{
++countDroppedFrames;
if ( slices == null )
slices = new ArrayList< Integer >();
slices.add( z );
// leave the slice empty
for ( int j = 0; j < img.dimension( 0 ) * img.dimension( 1 ); ++j )
cursor.next();
continue;
}
final Object o = imp.getProcessor().getPixels();
if ( o instanceof byte[] )
for ( final byte b : (byte[])o )
cursor.next().setReal( UnsignedByteType.getUnsignedByte( b ) );
else if ( o instanceof short[] )
for ( final short s : (short[])o )
cursor.next().setReal( UnsignedShortType.getUnsignedShort( s ) );
else if ( o instanceof float[] )
for ( final float s : (float[])o )
cursor.next().setReal( s );
}
if ( countDroppedFrames > 0 )
{
IOFunctions.printlnSafe(
"(" + new Date( System.currentTimeMillis() ) + "): WARNING!!! " + countDroppedFrames +
" DROPPED FRAME(s) in timepoint=" + timepoint + " channel=" + ampOrPhaseDirectory + " following slices:" );
for ( final int z : slices )
IOFunctions.printlnSafe( "(" + new Date( System.currentTimeMillis() ) + "): sliceindex=" + z + ", slice=" + zPlanes.get( z ));
}
}
}