/*-
* #%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.Arrays;
import java.util.List;
import mpicbg.spim.data.sequence.Angle;
import mpicbg.spim.data.sequence.Channel;
import mpicbg.spim.data.sequence.Illumination;
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.ImgLib2Temp.Pair;
import spim.fiji.ImgLib2Temp.ValuePair;
import spim.fiji.plugin.queryXML.LoadParseQueryXML;
import spim.fiji.plugin.removedetections.InteractiveProjections;
import spim.fiji.spimdata.SpimData2;
import spim.fiji.spimdata.interestpoints.InterestPoint;
import spim.fiji.spimdata.interestpoints.InterestPointList;
import spim.fiji.spimdata.interestpoints.ViewInterestPointLists;
import spim.fiji.spimdata.interestpoints.ViewInterestPoints;
public class Interactive_Remove_Detections implements PlugIn
{
public static int defaultAngleChoice = 0;
public static int defaultChannelChoice = 0;
public static int defaultIlluminationChoice = 0;
public static int defaultTimepointChoice = 0;
public static int defaultProjectionChoice = 0;
public static int defaultLabel = 0;
public static String defaultNewLabel = "Manually removed";
protected static String[] projectionChoice = new String[]{ "XY (Z-Projection)", "XZ (Y-Projection)", "YZ (X-Projection)" };
@Override
public void run( final String arg0 )
{
// ask for everything but the channels
final LoadParseQueryXML result = new LoadParseQueryXML();
if ( !result.queryXML( "Interactively remove detections", false, false, false, false ) )
return;
final GenericDialog gd = new GenericDialog( "Select View" );
final List< TimePoint > timepoints = result.getTimePointsToProcess();
final String[] timepointNames = new String[ timepoints.size() ];
for ( int i = 0; i < timepointNames.length; ++i )
timepointNames[ i ] = result.getTimePointsToProcess().get( i ).getName();
final List< Angle > angles = result.getData().getSequenceDescription().getAllAnglesOrdered();
final String[] angleNames = new String[ angles.size() ];
for ( int i = 0; i < angles.size(); ++i )
angleNames[ i ] = angles.get( i ).getName();
final List< Channel > channels = result.getData().getSequenceDescription().getAllChannelsOrdered();
final String[] channelNames = new String[ channels.size() ];
for ( int i = 0; i < channels.size(); ++i )
channelNames[ i ] = channels.get( i ).getName();
final List< Illumination > illuminations = result.getData().getSequenceDescription().getAllIlluminationsOrdered();
final String[] illuminationNames = new String[ illuminations.size() ];
for ( int i = 0; i < illuminations.size(); ++i )
illuminationNames[ i ] = illuminations.get( i ).getName();
gd.addChoice( "Angle", angleNames, angleNames[ defaultAngleChoice ] );
gd.addChoice( "Channel", channelNames, channelNames[ defaultChannelChoice ] );
gd.addChoice( "Illumination", illuminationNames, illuminationNames[ defaultIlluminationChoice ] );
gd.addChoice( "Timepoint", timepointNames, timepointNames[ defaultTimepointChoice ] );
gd.addMessage( "" );
gd.addChoice( "Projection", projectionChoice, projectionChoice[ defaultProjectionChoice ] );
gd.showDialog();
if ( gd.wasCanceled() )
return;
final Angle angle = angles.get( defaultAngleChoice = gd.getNextChoiceIndex() );
final Channel channel = channels.get( defaultChannelChoice = gd.getNextChoiceIndex() );
final Illumination illumination = illuminations.get( defaultIlluminationChoice = gd.getNextChoiceIndex() );
final TimePoint tp = timepoints.get( defaultTimepointChoice = gd.getNextChoiceIndex() );
final int projection = defaultProjectionChoice = gd.getNextChoiceIndex();
// get the corresponding viewid
final ViewId viewId = SpimData2.getViewId( result.getData().getSequenceDescription(), tp, channel, angle, illumination );
final String name = "angle: " + angle.getName() + " channel: " + channel.getName() + " illum: " + illumination.getName() + " timepoint: " + tp.getName();
// this happens only if a viewsetup is not present in any timepoint
// (e.g. after appending fusion to a dataset)
if ( viewId == null )
{
IOFunctions.println( "This ViewSetup is not present for this timepoint: angle: " + name );
return;
}
// get the viewdescription
final ViewDescription viewDescription = result.getData().getSequenceDescription().getViewDescription(
viewId.getTimePointId(), viewId.getViewSetupId() );
// check if this viewid is present in the current timepoint
if ( !viewDescription.isPresent() )
{
IOFunctions.println( "This ViewSetup is not present for this timepoint: angle: " + name );
return;
}
// XY == along z(2)
// XZ == along y(1)
// yz == along x(0)
final int projectionDim = 2 - projection;
final Pair< String, String > labels = queryLabelAndNewLabel( result.getData(), viewDescription );
if ( labels == null )
return;
if ( !removeDetections( result.getData(), viewDescription, projectionDim, labels.getA(), labels.getB() ) )
return;
// now save it
SpimData2.saveXML( result.getData(), result.getXMLFileName(), result.getClusterExtension() );
}
public static Pair< String, String > queryLabelAndNewLabel( final SpimData2 spimData, final ViewDescription vd )
{
final ViewInterestPoints interestPoints = spimData.getViewInterestPoints();
final ViewInterestPointLists lists = interestPoints.getViewInterestPointLists( vd );
if ( lists.getHashMap().keySet().size() == 0 )
{
IOFunctions.println(
"No interest points available for angle: " + vd.getViewSetup().getAngle().getName() +
" channel: " + vd.getViewSetup().getChannel().getName() +
" illum: " + vd.getViewSetup().getIllumination().getName() +
" timepoint: " + vd.getTimePoint().getName() );
return null;
}
final String[] labels = new String[ lists.getHashMap().keySet().size() ];
int i = 0;
for ( final String label : lists.getHashMap().keySet() )
labels[ i++ ] = label;
if ( defaultLabel >= labels.length )
defaultLabel = 0;
Arrays.sort( labels );
final GenericDialog gd = new GenericDialog( "Select Interest Points To Remove" );
gd.addChoice( "Interest_Point_Label", labels, labels[ defaultLabel ]);
gd.addStringField( "New_Label", defaultNewLabel, 20 );
gd.showDialog();
if ( gd.wasCanceled() )
return null;
final String label = labels[ defaultLabel = gd.getNextChoiceIndex() ];
final String newLabel = gd.getNextString();
return new ValuePair< String, String>( label, newLabel );
}
public static boolean removeDetections( final SpimData2 spimData, final ViewDescription vd, final int projectionDim, final String label, final String newLabel )
{
final ViewInterestPoints interestPoints = spimData.getViewInterestPoints();
final ViewInterestPointLists lists = interestPoints.getViewInterestPointLists( vd );
final InteractiveProjections ip = new InteractiveProjections( spimData, vd, label, newLabel, projectionDim );
do
{
try
{
Thread.sleep( 100 );
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
while ( ip.isRunning() );
if ( ip.wasCanceled() )
return false;
final List< InterestPoint > ipList = ip.getInterestPointList();
if ( ipList.size() == 0 )
{
IOFunctions.println( "No detections remaining. Quitting." );
return false;
}
// add new label
final InterestPointList newIpl = new InterestPointList(
lists.getInterestPointList( label ).getBaseDir(),
new File(
lists.getInterestPointList( label ).getFile().getParentFile(),
"tpId_" + vd.getTimePointId() + "_viewSetupId_" + vd.getViewSetupId() + "." + newLabel ) );
newIpl.setInterestPoints( ipList );
newIpl.setParameters( "manually removed detections from '" +label + "'" );
newIpl.saveInterestPoints();
lists.addInterestPointList( newLabel, newIpl );
return true;
}
public static void main( final String[] args )
{
new ImageJ();
new Interactive_Remove_Detections().run( null );
}
}