/*- * #%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.datasetmanager; import java.io.File; import java.util.ArrayList; import mpicbg.spim.data.SpimData; import mpicbg.spim.data.registration.ViewRegistrations; import mpicbg.spim.data.sequence.Angle; import mpicbg.spim.data.sequence.Channel; import mpicbg.spim.data.sequence.FinalVoxelDimensions; import mpicbg.spim.data.sequence.Illumination; import mpicbg.spim.data.sequence.ImgLoader; import mpicbg.spim.data.sequence.MissingViews; import mpicbg.spim.data.sequence.SequenceDescription; import mpicbg.spim.data.sequence.TimePoint; import mpicbg.spim.data.sequence.TimePoints; import mpicbg.spim.data.sequence.ViewSetup; import mpicbg.spim.data.sequence.VoxelDimensions; import mpicbg.spim.io.IOFunctions; import net.imglib2.Dimensions; import net.imglib2.FinalDimensions; import spim.fiji.spimdata.SpimData2; import spim.fiji.spimdata.boundingbox.BoundingBoxes; import spim.fiji.spimdata.imgloaders.DHMImgLoader; import spim.fiji.spimdata.interestpoints.ViewInterestPoints; import fiji.util.gui.GenericDialogPlus; public class DHM implements MultiViewDatasetDefinition { public static String defaultDir = ""; public static double defaulCalX = 0.1725; //3.45 / 20.0; public static double defaulCalY = 0.1725; //3.45 / 20.0; public static double defaulCalZ = 1.25; //( 0.5 / ( 20.0 * 20.0 ) ) * 1000; public static String defaulCalUnit = "um"; public static boolean defaultOpenAll = false; @Override public String getTitle() { return "Holographic Imaging Dataset"; } @Override public String getExtendedDescription() { return "This dataset definition supports data as created by a holographic microscope\n" + "(Amplitude & Phase stacks in 3d over time)"; } @Override public SpimData2 createDataset() { final DHMMetaData meta = queryDirectoryAndRatio(); if ( meta == null ) return null; if ( !meta.loadMetaData() ) return null; // assemble timepints, viewsetups, missingviews and the imgloader final TimePoints timepoints = this.createTimePoints( meta ); final ArrayList< ViewSetup > setups = this.createViewSetups( meta ); final MissingViews missingViews = null; // instantiate the sequencedescription final SequenceDescription sequenceDescription = new SequenceDescription( timepoints, setups, null, missingViews ); final ImgLoader imgLoader = new DHMImgLoader( meta.getDir(), meta.getStackDir(), meta.getAmplitudeDir(), meta.getPhaseDir(), meta.getTimepoints(), meta.getZPlanes(), meta.getExt(), meta.getAmpChannelId(), meta.getPhaseChannelId(), sequenceDescription ); sequenceDescription.setImgLoader( imgLoader ); // get the minimal resolution of all calibrations final double minResolution = Math.min( Math.min( meta.calX, meta.calY ), meta.calZ ); IOFunctions.println( "Minimal resolution in all dimensions is: " + minResolution ); IOFunctions.println( "(The smallest resolution in any dimension; the distance between two pixels in the output image will be that wide)" ); // create the initial view registrations (they are all the identity transform) final ViewRegistrations viewRegistrations = StackList.createViewRegistrations( sequenceDescription.getViewDescriptions(), minResolution ); // create the initial view interest point object final ViewInterestPoints viewInterestPoints = new ViewInterestPoints(); viewInterestPoints.createViewInterestPoints( sequenceDescription.getViewDescriptions() ); // finally create the SpimData itself based on the sequence description and the view registration final SpimData2 spimData = new SpimData2( meta.getDir(), sequenceDescription, viewRegistrations, viewInterestPoints, new BoundingBoxes() ); return spimData; } /** * Creates the {@link TimePoints} for the {@link SpimData} object */ protected TimePoints createTimePoints( final DHMMetaData meta ) { final ArrayList< TimePoint > timepoints = new ArrayList< TimePoint >(); for ( int t = 0; t < meta.getTimepoints().size(); ++t ) timepoints.add( new TimePoint( Integer.parseInt( meta.getTimepoints().get( t ) ) ) ); return new TimePoints( timepoints ); } /** * Creates the List of {@link ViewSetup} for the {@link SpimData} object. * The {@link ViewSetup} are defined independent of the {@link TimePoint}, * each {@link TimePoint} should have the same {@link ViewSetup}s. The {@link MissingViews} * class defines if some of them are missing for some of the {@link TimePoint}s * * @return */ protected ArrayList< ViewSetup > createViewSetups( final DHMMetaData meta ) { final ArrayList< Channel > channels = new ArrayList< Channel >(); channels.add( new Channel( meta.getAmpChannelId(), meta.getAmplitudeDir() ) ); channels.add( new Channel( meta.getPhaseChannelId(), meta.getPhaseDir() ) ); final ArrayList< Illumination > illuminations = new ArrayList< Illumination >(); illuminations.add( new Illumination( 0, String.valueOf( 0 ) ) ); final ArrayList< Angle > angles = new ArrayList< Angle >(); angles.add( new Angle( 0, String.valueOf( 0 ) ) ); final ArrayList< ViewSetup > viewSetups = new ArrayList< ViewSetup >(); for ( final Channel c : channels ) for ( final Illumination i : illuminations ) for ( final Angle a : angles ) { final VoxelDimensions voxelSize = new FinalVoxelDimensions( meta.calUnit, meta.calX, meta.calY, meta.calZ ); final Dimensions dim = new FinalDimensions( new long[]{ meta.getWidth(), meta.getHeight(), meta.getDepth() } ); viewSetups.add( new ViewSetup( viewSetups.size(), null, dim, voxelSize, c, a, i ) ); } return viewSetups; } protected DHMMetaData queryDirectoryAndRatio() { GenericDialogPlus gd = new GenericDialogPlus( "Specify Holographic Acquistion Directory" ); gd.addDirectoryField( "Holographic_Acquisition main directory", defaultDir, 50 ); gd.addMessage( "" ); gd.addMessage( "Camera pixel size (e.g. 3.45um) / Magnification (e.g. 20):" ); gd.addNumericField( "Pixel_distance_x", defaulCalX, 5 ); gd.addNumericField( "Pixel_distance_y", defaulCalY, 5 ); gd.addMessage( "Depth between planes (e.g. 0.5mm) / Magnification^2 (e.g. 20^2) * 1000 (mm to um):" ); gd.addNumericField( "Pixel_distance_z", defaulCalZ, 5 ); gd.addStringField( "Pixel_unit", defaulCalUnit ); gd.addMessage( "" ); gd.addCheckbox( "Open_all planes to ensure they have the same dimensions (takes time!)", defaultOpenAll ); gd.showDialog(); if ( gd.wasCanceled() ) return null; return new DHMMetaData( new File( defaultDir = gd.getNextString() ), defaulCalX = gd.getNextNumber(), defaulCalY = gd.getNextNumber(), defaulCalZ = gd.getNextNumber(), defaulCalUnit = gd.getNextString(), defaultOpenAll = gd.getNextBoolean() ); } @Override public MultiViewDatasetDefinition newInstance() { return new DHM(); } public static void main( String[] args ) { new DHM().createDataset(); } }