/*- * #%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.plugin.fusion; import ij.gui.GenericDialog; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import mpicbg.spim.data.sequence.Channel; import mpicbg.spim.data.sequence.TimePoint; import mpicbg.spim.data.sequence.ViewDescription; import mpicbg.spim.data.sequence.ViewId; import mpicbg.spim.data.sequence.ViewSetup; import net.imglib2.util.Intervals; import spim.fiji.spimdata.SpimData2; import spim.fiji.spimdata.ViewSetupUtils; import spim.process.fusion.boundingbox.BoundingBoxGUI; import spim.process.fusion.boundingbox.BoundingBoxGUI.ManageListeners; import spim.process.fusion.export.ImgExport; public abstract class Fusion { public static String[] interpolationTypes = new String[]{ "Nearest Neighbor", "Linear Interpolation" }; public static int defaultInterpolation = 1; protected int interpolation = 1; public static boolean defaultUseBlending = true; protected boolean useBlending = true; public static boolean defaultUseContentBased = false; protected boolean useContentBased = false; /** * Maps from an old Viewsetup to a new ViewSetup that is created by the fusion */ protected Map< ViewSetup, ViewSetup > newViewsetups = null; /** * which ViewId to process, set in queryParameters */ final protected List< ViewId > viewIdsToProcess; final protected List< TimePoint > timepointsToProcess; final protected List< Channel > channelsToProcess; final protected SpimData2 spimData; final int maxNumViews; final protected long avgPixels; /** * @param spimData * @param viewIdsToProcess - which viewIds to fuse */ public Fusion( final SpimData2 spimData, final List< ViewId > viewIdsToProcess ) { this.spimData = spimData; this.viewIdsToProcess = viewIdsToProcess; if ( viewIdsToProcess != null ) { this.timepointsToProcess = SpimData2.getAllTimePointsSorted( spimData, viewIdsToProcess ); this.channelsToProcess = SpimData2.getAllChannelsSorted( spimData, viewIdsToProcess ); if ( spimData == null ) { avgPixels = 0; maxNumViews = 0; } else { avgPixels = computeAvgImageSize(); maxNumViews = computeMaxNumViews(); } } else { this.timepointsToProcess = null; this.channelsToProcess = null; this.avgPixels = 0; this.maxNumViews = 0; } } public abstract long totalRAM( final long fusedSizeMB, final int bytePerPixel ); public int getMaxNumViewsPerTimepoint() { return maxNumViews; } public int getInterpolation() { return interpolation; } /** * Fuses and saves/displays * * @param bb * @return */ public abstract boolean fuseData( final BoundingBoxGUI bb, final ImgExport exporter ); /** * @return - which timepoints will be processed, this is maybe inquired by the exporter * if it needs to assemble a new XML dataset or append to the current XML dataset */ public List< TimePoint > getTimepointsToProcess() { return timepointsToProcess; } /** * @return - a sorted List of ViewSetup(s) that are created by this fusion, this maybe requested * if the exporter creates a new XML dataset or appends to an existing XML dataset */ public List< ViewSetup > getNewViewSetups() { final ArrayList< ViewSetup > newSetups = new ArrayList< ViewSetup >(); newSetups.addAll( new HashSet< ViewSetup >( newViewsetups.values() ) ); Collections.sort( newSetups ); return newSetups; } /** * Set up the list of new viewsetups that are created with this fusion. This maybe required * if the exporter needs to assemble a new XML dataset or append to the current XML dataset. * * It maps from an old ViewSetup to a new ViewSetup * * @param bb - the bounding box used for fusing the data * @return the list of new viewsetups (in the order as the viewsetups are processed) */ protected abstract Map< ViewSetup, ViewSetup > createNewViewSetups( final BoundingBoxGUI bb ); public void defineNewViewSetups( final BoundingBoxGUI bb ) { this.newViewsetups = createNewViewSetups( bb ); } public abstract boolean supports16BitUnsigned(); public abstract boolean supportsDownsampling(); /** * compress the bounding box dialog as much as possible to let more space for extra parameters * @return */ public abstract boolean compressBoundingBoxDialog(); /** * Query the necessary parameters for the fusion (new dialog has to be made) * * @return */ public abstract boolean queryParameters(); /** * Query additional parameters within the bounding box dialog */ public abstract void queryAdditionalParameters( final GenericDialog gd ); /** * In case there are some other Listener upon whom the memory needs to be recomputed in the Manual Bounding Box. * * @param m */ public void registerAdditionalListeners( final ManageListeners m ) {}; /** * Parse the additional parameters added before within the bounding box dialog * @param gd * @return */ public abstract boolean parseAdditionalParameters( final GenericDialog gd ); /** * @param spimData * @param viewIdsToProcess- which viewIds to fuse * @return - a new instance without any special properties */ public abstract Fusion newInstance( final SpimData2 spimData, final List< ViewId > viewIdsToProcess ); /** * @return - to be displayed in the generic dialog */ public abstract String getDescription(); protected long computeAvgImageSize() { long avgSize = 0; int countImgs = 0; for ( final ViewId viewId : viewIdsToProcess ) { final ViewDescription desc = spimData.getSequenceDescription().getViewDescription( viewId ); if ( desc.isPresent() ) { final ViewSetup viewSetup = desc.getViewSetup(); final long numPixel = Intervals.numElements( ViewSetupUtils.getSizeOrLoad( viewSetup, desc.getTimePoint(), spimData.getSequenceDescription().getImgLoader() ) ); avgSize += numPixel; ++countImgs; } } return avgSize / countImgs; } /** * @return - max num views per fused image */ protected int computeMaxNumViews() { int maxViews = 0; for ( final TimePoint t : timepointsToProcess ) for ( final Channel c : channelsToProcess ) { int views = 0; for ( final ViewId viewId : viewIdsToProcess ) { final ViewDescription vd = spimData.getSequenceDescription().getViewDescription( viewId ); if ( vd.isPresent() && vd.getTimePointId() == t.getId() && vd.getViewSetup().getChannel().getId() == c.getId() ) ++views; } maxViews = Math.max( maxViews, views ); } return maxViews; } }