/*- * #%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; import ij.ImageJ; import ij.gui.GenericDialog; import ij.plugin.PlugIn; import java.io.File; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import mpicbg.spim.data.sequence.Channel; import mpicbg.spim.data.sequence.SequenceDescription; import mpicbg.spim.data.sequence.TimePoint; import mpicbg.spim.data.sequence.ViewDescription; import mpicbg.spim.data.sequence.ViewId; import mpicbg.spim.io.IOFunctions; import spim.fiji.plugin.interestpointdetection.DifferenceOf; import spim.fiji.plugin.interestpointdetection.DifferenceOfGaussian; import spim.fiji.plugin.interestpointdetection.DifferenceOfMean; import spim.fiji.plugin.interestpointdetection.InterestPointDetection; import spim.fiji.plugin.queryXML.LoadParseQueryXML; import spim.fiji.plugin.util.GUIHelper; import spim.fiji.spimdata.SpimData2; import spim.fiji.spimdata.imgloaders.AbstractImgLoader; import spim.fiji.spimdata.interestpoints.CorrespondingInterestPoints; import spim.fiji.spimdata.interestpoints.InterestPoint; import spim.fiji.spimdata.interestpoints.InterestPointList; import spim.fiji.spimdata.interestpoints.ViewInterestPointLists; /** * Plugin to detect interest points, store them on disk, and link them into the XML * * Different plugins to detect interest points are supported, needs to implement the * {@link InterestPointDetection} interface * * @author Stephan Preibisch (stephan.preibisch@gmx.de) * */ public class Interest_Point_Detection implements PlugIn { public static ArrayList< InterestPointDetection > staticAlgorithms = new ArrayList< InterestPointDetection >(); public static int defaultAlgorithm = 1; public static boolean defaultDownSample = true; public static boolean defaultDefineAnisotropy = false; public static boolean defaultAdditionalSmoothing = false; public static boolean defaultSetMinMax = false; public static boolean defaultLimitDetections = false; public static String defaultLabel = "beads"; static { IOFunctions.printIJLog = true; staticAlgorithms.add( new DifferenceOfMean( null, null ) ); staticAlgorithms.add( new DifferenceOfGaussian( null, null ) ); } @Override public void run( final String arg ) { // ask for everything but the channels final LoadParseQueryXML result = new LoadParseQueryXML(); if ( !result.queryXML( "perfoming interest point detection", true, true, true, true ) ) return; detectInterestPoints( result.getData(), SpimData2.getAllViewIdsSorted( result.getData(), result.getViewSetupsToProcess(), result.getTimePointsToProcess() ), result.getClusterExtension(), result.getXMLFileName(), true ); } /** * Does just the detection, no saving * * @param data * @param viewIds * @return */ public boolean detectInterestPoints( final SpimData2 data, final List< ViewId > viewIds ) { return detectInterestPoints( data, viewIds, "", null, false ); } public boolean detectInterestPoints( final SpimData2 data, final List< ViewId > viewIds, final String xmlFileName, final boolean saveXML ) { return detectInterestPoints( data, viewIds, "", xmlFileName, saveXML ); } public boolean detectInterestPoints( final SpimData2 data, final List< ViewId > viewIds, final String clusterExtension, final String xmlFileName, final boolean saveXML ) { // the GenericDialog needs a list[] of String final String[] descriptions = new String[ staticAlgorithms.size() ]; for ( int i = 0; i < staticAlgorithms.size(); ++i ) descriptions[ i ] = staticAlgorithms.get( i ).getDescription(); if ( defaultAlgorithm >= descriptions.length ) defaultAlgorithm = 0; final GenericDialog gd = new GenericDialog( "Detect Interest Points" ); gd.addChoice( "Type_of_interest_point_detection", descriptions, descriptions[ defaultAlgorithm ] ); gd.addStringField( "Label_interest_points", defaultLabel ); gd.addMessage( "" ); gd.addMessage( "Channels to detect interest points in", GUIHelper.largefont ); final ArrayList< Channel > channels = SpimData2.getAllChannelsSorted( data, viewIds ); for ( int i = 0; i < channels.size(); ++i ) gd.addMessage( "Channel " + channels.get( i ).getName(), GUIHelper.smallStatusFont ); gd.addMessage( "" ); gd.addCheckbox( "Downsample_images prior to segmentation", defaultDownSample ); gd.addCheckbox( "Define_anisotropy for segmentation", defaultDefineAnisotropy ); gd.addCheckbox( "Additional_smoothing", defaultAdditionalSmoothing ); gd.addCheckbox( "Set_minimal_and_maximal_intensity", defaultSetMinMax ); gd.addCheckbox( "Limit_amount_of_detections" , defaultLimitDetections ); gd.addMessage( "" ); GUIHelper.addWebsite( gd ); gd.showDialog(); if ( gd.wasCanceled() ) return false; final int algorithm = defaultAlgorithm = gd.getNextChoiceIndex(); // how are the detections called (e.g. beads, nuclei, ...) final String label = defaultLabel = gd.getNextString(); final ArrayList< Channel> channelsToProcess = new ArrayList< Channel >(); for ( int i = 0; i < channels.size(); ++i ) channelsToProcess.add( channels.get( i ) ); final boolean downsample = defaultDownSample = gd.getNextBoolean(); final boolean defineAnisotropy = defaultDefineAnisotropy = gd.getNextBoolean(); final boolean additionalSmoothing = defaultAdditionalSmoothing = gd.getNextBoolean(); final boolean setMinMax = defaultSetMinMax = gd.getNextBoolean(); final boolean limitDetections = defaultLimitDetections = gd.getNextBoolean(); final InterestPointDetection ipd = staticAlgorithms.get( algorithm ).newInstance( data, viewIds ); // the interest point detection should query its parameters if ( !ipd.queryParameters( downsample, defineAnisotropy, additionalSmoothing, setMinMax, limitDetections ) ) return false; // now extract all the detections for ( final TimePoint tp : SpimData2.getAllTimePointsSorted( data, viewIds ) ) { final HashMap< ViewId, List< InterestPoint > > points = ipd.findInterestPoints( tp ); if ( ipd instanceof DifferenceOf ) { IOFunctions.println( "Opening of files took: " + ((DifferenceOf)ipd).getBenchmark().openFiles/1000 + " sec." ); IOFunctions.println( "Detecting interest points took: " + ((DifferenceOf)ipd).getBenchmark().computation/1000 + " sec." ); } // save the file and the path in the XML final SequenceDescription seqDesc = data.getSequenceDescription(); for ( final ViewId viewId : points.keySet() ) { final ViewDescription viewDesc = seqDesc.getViewDescription( viewId.getTimePointId(), viewId.getViewSetupId() ); final int channelId = viewDesc.getViewSetup().getChannel().getId(); final InterestPointList list = new InterestPointList( data.getBasePath(), new File( "interestpoints", "tpId_" + viewId.getTimePointId() + "_viewSetupId_" + viewId.getViewSetupId() + "." + label ) ); list.setParameters( ipd.getParameters( channelId ) ); list.setInterestPoints( points.get( viewId ) ); if ( saveXML ) { if ( !list.saveInterestPoints() ) { IOFunctions.println( "Error saving interest point list: " + new File( list.getBaseDir(), list.getFile().toString() + list.getInterestPointsExt() ) ); return false; } list.setCorrespondingInterestPoints( new ArrayList< CorrespondingInterestPoints >() ); if ( !list.saveCorrespondingInterestPoints() ) IOFunctions.println( "Failed to clear corresponding interest point list: " + new File( list.getBaseDir(), list.getFile().toString() + list.getCorrespondencesExt() ) ); } final ViewInterestPointLists vipl = data.getViewInterestPoints().getViewInterestPointLists( viewId ); vipl.addInterestPointList( label, list ); } // update metadata if necessary if ( data.getSequenceDescription().getImgLoader() instanceof AbstractImgLoader ) { IOFunctions.println( "(" + new Date( System.currentTimeMillis() ) + "): Updating metadata ... " ); try { ( (AbstractImgLoader)data.getSequenceDescription().getImgLoader() ).updateXMLMetaData( data, false ); } catch( Exception e ) { IOFunctions.println( "Failed to update metadata, this should not happen: " + e ); } } // save the xml if ( saveXML ) SpimData2.saveXML( data, xmlFileName, clusterExtension ); } return true; } public static void main( final String[] args ) { new ImageJ(); new Interest_Point_Detection().run( null ); } }