/*-
* #%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.export;
import ij.gui.GenericDialog;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import mpicbg.spim.data.registration.ViewRegistration;
import mpicbg.spim.data.registration.ViewTransform;
import mpicbg.spim.data.registration.ViewTransformAffine;
import mpicbg.spim.data.sequence.SequenceDescription;
import mpicbg.spim.data.sequence.TimePoint;
import mpicbg.spim.data.sequence.ViewId;
import mpicbg.spim.data.sequence.ViewSetup;
import mpicbg.spim.io.IOFunctions;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.realtransform.AffineTransform3D;
import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.type.numeric.integer.UnsignedShortType;
import net.imglib2.util.Pair;
import net.imglib2.util.Util;
import spim.fiji.plugin.resave.Generic_Resave_HDF5;
import spim.fiji.plugin.resave.Generic_Resave_HDF5.Parameters;
import spim.fiji.plugin.resave.ProgressWriterIJ;
import spim.fiji.plugin.resave.Resave_HDF5;
import spim.fiji.spimdata.SpimData2;
import spim.process.fusion.boundingbox.BoundingBoxGUI;
import bdv.export.ExportMipmapInfo;
import bdv.export.ProgressWriter;
import bdv.export.SubTaskProgressWriter;
import bdv.export.WriteSequenceToHdf5;
import bdv.img.hdf5.Hdf5ImageLoader;
import bdv.img.hdf5.Partition;
import bdv.spimdata.tools.MergePartitionList;
public class AppendSpimData2HDF5 implements ImgExport
{
public static String defaultPath = null;
private List< TimePoint > newTimepoints;
private List< ViewSetup > newViewSetups;
private Parameters params;
private SpimData2 spimData;
private SpimData2 fusionOnlySpimData;
private Map< Integer, ExportMipmapInfo > perSetupExportMipmapInfo;
private HashMap< ViewId, Partition > viewIdToPartition;
private final ProgressWriter progressWriter = new ProgressWriterIJ();
@Override
public boolean finish()
{
// this spimdata object was modified
return true;
}
@Override
public void setXMLData ( final List< TimePoint > newTimepoints, final List< ViewSetup > newViewSetups )
{
this.newTimepoints = newTimepoints;
this.newViewSetups = newViewSetups;
}
@Override
public boolean queryParameters( final SpimData2 spimData, final boolean is16bit )
{
System.out.println( "queryParameters()" );
if ( newTimepoints == null || newViewSetups == null )
{
IOFunctions.println( "new timepoints and new viewsetup list not set yet ... cannot continue" );
return false;
}
Hdf5ImageLoader il = ( Hdf5ImageLoader ) spimData.getSequenceDescription().getImgLoader();
perSetupExportMipmapInfo = Resave_HDF5.proposeMipmaps( newViewSetups );
String fn = il.getHdf5File().getAbsolutePath();
if ( fn.endsWith( ".h5" ) )
fn = fn.substring( 0, fn.length() - ".h5".length() );
String fusionHdfFilename = "";
String fusionXmlFilename = "";
for ( int i = 0;; ++i )
{
fusionHdfFilename = String.format( "%s-f%d.h5", fn, i );
fusionXmlFilename = String.format( "%s-f%d.xml", fn, i );
if ( !new File( fusionHdfFilename ).exists() && !new File( fusionXmlFilename ).exists() )
break;
}
final int firstviewSetupId = newViewSetups.get( 0 ).getId();
params = Generic_Resave_HDF5.getParameters( perSetupExportMipmapInfo.get( firstviewSetupId ), false, getDescription(), is16bit );
if ( params == null )
{
System.out.println( "abort " );
return false;
}
params.setHDF5File( new File( fusionHdfFilename ) );
params.setSeqFile( new File( fusionXmlFilename ) );
Pair< SpimData2, HashMap< ViewId, Partition > > init = ExportSpimData2HDF5.initSpimData(
newTimepoints, newViewSetups, params, perSetupExportMipmapInfo );
fusionOnlySpimData = init.getA();
viewIdToPartition = init.getB();
perSetupExportMipmapInfo.putAll(
MergePartitionList.getHdf5PerSetupExportMipmapInfos( spimData.getSequenceDescription() ) );
this.spimData = spimData;
AppendSpimData2.appendSpimData2( spimData, newTimepoints, newViewSetups );
ArrayList< Partition > mergedPartitions = MergePartitionList.getMergedHdf5PartitionList(
spimData.getSequenceDescription(), fusionOnlySpimData.getSequenceDescription() );
String mergedHdfFilename = "";
for ( int i = 0;; ++i )
{
mergedHdfFilename = String.format( "%s-m%d.h5", fn, i );
if ( !new File( mergedHdfFilename ).exists() )
break;
}
SequenceDescription seq = spimData.getSequenceDescription();
Hdf5ImageLoader newLoader = new Hdf5ImageLoader(
new File( mergedHdfFilename ), mergedPartitions, seq, false );
seq.setImgLoader( newLoader );
WriteSequenceToHdf5.writeHdf5PartitionLinkFile( spimData.getSequenceDescription(), perSetupExportMipmapInfo );
return true;
}
@Override
public < T extends RealType< T > & NativeType< T >> boolean exportImage( RandomAccessibleInterval< T > img, BoundingBoxGUI bb, TimePoint tp, ViewSetup vs )
{
System.out.println( "exportImage1()" );
return exportImage( img, bb, tp, vs, Double.NaN, Double.NaN );
}
@SuppressWarnings( { "unchecked", "rawtypes" } )
@Override
public < T extends RealType< T > & NativeType< T > > boolean exportImage( RandomAccessibleInterval< T > img, BoundingBoxGUI bb, TimePoint tp, ViewSetup vs, double min, double max )
{
System.out.println( "exportImage2()" );
// write the image
final RandomAccessibleInterval< UnsignedShortType > ushortimg;
if ( ! UnsignedShortType.class.isInstance( Util.getTypeFromInterval( img ) ) )
ushortimg = ExportSpimData2HDF5.convert( img, params );
else
ushortimg = ( RandomAccessibleInterval ) img;
final Partition partition = viewIdToPartition.get( new ViewId( tp.getId(), vs.getId() ) );
final ExportMipmapInfo mipmapInfo = perSetupExportMipmapInfo.get( vs.getId() );
final boolean writeMipmapInfo = true; // TODO: remember whether we already wrote it and write only once
final boolean deflate = params.getDeflate();
final ProgressWriter progressWriter = new SubTaskProgressWriter( this.progressWriter, 0.0, 1.0 ); // TODO
final int numThreads = Math.max( 1, Runtime.getRuntime().availableProcessors() - 2 );
WriteSequenceToHdf5.writeViewToHdf5PartitionFile( ushortimg, partition, tp.getId(), vs.getId(), mipmapInfo, writeMipmapInfo, deflate, null, null, numThreads, progressWriter );
// update the registrations
final ViewRegistration vr = spimData.getViewRegistrations().getViewRegistration( new ViewId( tp.getId(), vs.getId() ) );
final double scale = bb.getDownSampling();
final AffineTransform3D m = new AffineTransform3D();
m.set( scale, 0.0f, 0.0f, bb.min( 0 ),
0.0f, scale, 0.0f, bb.min( 1 ),
0.0f, 0.0f, scale, bb.min( 2 ) );
final ViewTransform vt = new ViewTransformAffine( "fusion bounding box", m );
vr.getTransformList().clear();
vr.getTransformList().add( vt );
return true;
}
@Override
public void queryAdditionalParameters( final GenericDialog gd, final SpimData2 spimData )
{}
@Override
public boolean parseAdditionalParameters( final GenericDialog gd, final SpimData2 spimData )
{
return true;
}
@Override
public ImgExport newInstance()
{
BoundingBoxGUI.defaultPixelType = 1; // set to 16 bit by default
return new AppendSpimData2HDF5();
}
@Override
public String getDescription()
{
return "Append to current XML Project (HDF5)";
}
}