Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package org.mastodon.mamut.io.importer.trackmate;

import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.FEATURE_ATTRIBUTE;
import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.FEATURE_DIMENSION_ATTRIBUTE;
import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.FEATURE_ISINT_ATTRIBUTE;
import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.FEATURE_NAME_ATTRIBUTE;
import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.FEATURE_SHORT_NAME_ATTRIBUTE;
import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.FEATURE_TAG;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.jdom2.Element;

public class CommonTrackMateFeatureDeclarations
{

public static final List< CommonTrackMateFeatureDeclaration > spotFeatureDeclarations = Arrays.asList( new CommonTrackMateFeatureDeclaration[] {
new CommonTrackMateFeatureDeclaration( TrackMateXMLKeys.VISIBILITY_FEATURE_NAME, "Visibility", "Visibility", "NONE", true ),
new CommonTrackMateFeatureDeclaration( TrackMateXMLKeys.POSITION_X_FEATURE_NAME, "X", "X", "POSITION", false ),
new CommonTrackMateFeatureDeclaration( TrackMateXMLKeys.POSITION_Y_FEATURE_NAME, "Y", "Y", "POSITION", false ),
new CommonTrackMateFeatureDeclaration( TrackMateXMLKeys.POSITION_Z_FEATURE_NAME, "Z", "Z", "POSITION", false ),
new CommonTrackMateFeatureDeclaration( TrackMateXMLKeys.POSITION_T_FEATURE_NAME, "T", "T", "TIME", false ),
new CommonTrackMateFeatureDeclaration( TrackMateXMLKeys.FRAME_FEATURE_NAME, "Frame", "Frame", "NONE", true ),
new CommonTrackMateFeatureDeclaration( TrackMateXMLKeys.RADIUS_FEATURE_NAME, "Radius", "R", "LENGTH", false ),
new CommonTrackMateFeatureDeclaration( TrackMateXMLKeys.QUALITY_FEATURE_NAME, "Quality", "Quality", "QUALITY", false ),
} );

public static final List< CommonTrackMateFeatureDeclaration > edgeFeatureDeclarations = Arrays.asList( new CommonTrackMateFeatureDeclaration[] {
new CommonTrackMateFeatureDeclaration( TrackMateXMLKeys.EDGE_SOURCE_ATTRIBUTE, "Source spot ID", "Source ID", "NONE", true ),
new CommonTrackMateFeatureDeclaration( TrackMateXMLKeys.EDGE_TARGET_ATTRIBUTE, "Target spot ID", "Target ID", "NONE", true ),
} );

public static final List< CommonTrackMateFeatureDeclaration > trackFeatureDeclarations = Arrays.asList( new CommonTrackMateFeatureDeclaration[] {
new CommonTrackMateFeatureDeclaration( TrackMateXMLKeys.TRACK_ID_ATTRIBUTE, "Track ID", "ID", "NONE", true ),
} );

public static class CommonTrackMateFeatureDeclaration
{
public final String key;

public final String name;

public final String shortName;

public final String dimension;

public final boolean isInt;

public CommonTrackMateFeatureDeclaration( final String key, final String name, final String shortName, final String dimension, final boolean isInt )
{
this.key = key;
this.name = name;
this.shortName = shortName;
this.dimension = dimension;
this.isInt = isInt;
}

public Element toElement()
{
final Element fel = new Element( FEATURE_TAG );
fel.setAttribute( FEATURE_ATTRIBUTE, key );
fel.setAttribute( FEATURE_NAME_ATTRIBUTE, name );
fel.setAttribute( FEATURE_SHORT_NAME_ATTRIBUTE, shortName );
fel.setAttribute( FEATURE_DIMENSION_ATTRIBUTE, dimension );
fel.setAttribute( FEATURE_ISINT_ATTRIBUTE, "" + isInt );
return fel;
}
}

/**
* List of Mastodon spot projection keys, translated to the TrackMate export
* name, that are not needed in the exported XML file, as they are already
* exported via TrackMate builtin features.
*/
public static final List< String > redundantSpotProjectionKeys = Arrays.asList(
"Spot_position_X", "Spot_position_Y", "Spot_position_Z", "Spot_radius", "Spot_frame" );

/**
* List of Mastodon link projection keys, translated to the TrackMate export
* name, that are not needed in the exported XML file, as they are already
* exported via TrackMate builtin features.
*/
public static final List< String > redundantLinkProjectionKeys = Arrays.asList(
"Link_target_IDs_Source_spot_id", "Link_target_IDs_Target_spot_id" );

/**
* List of Mastodon track projection keys, translated to the TrackMate
* export name, that are not needed in the exported XML file, as they are
* already exported via TrackMate builtin features.
*/
public static final List< String > redundantTrackProjectionKeys = Collections.emptyList();
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.FOLDER_ATTRIBUTE;
import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.FRAME_ATTRIBUTE;
import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.FRAME_FEATURE_NAME;
import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.FRAME_INTERVAL_ATTRIBUTE;
import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.GUI_STATE_TAG;
import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.HEIGHT_ATTRIBUTE;
import static org.mastodon.mamut.io.importer.trackmate.TrackMateXMLKeys.ID_FEATURE_NAME;
Expand Down Expand Up @@ -361,6 +362,7 @@ private Element imageDataToXml()
attributes.add( new Attribute( PIXEL_WIDTH_ATTRIBUTE, Double.toString( pixelWidth ) ) );
attributes.add( new Attribute( PIXEL_HEIGHT_ATTRIBUTE, Double.toString( pixelHeight ) ) );
attributes.add( new Attribute( VOXEL_DEPTH_ATTRIBUTE, Double.toString( voxelDepth ) ) );
attributes.add( new Attribute( FRAME_INTERVAL_ATTRIBUTE, Double.toString( 1. ) ) );

final Element timePointsElement = document
.getRootElement()
Expand Down Expand Up @@ -540,8 +542,15 @@ private Element edgeToXml( final Link edge, final int sourceSpotID, final int ta
// Link features.
for ( final ExportFeatureProjection< Link > p : linkFeatureProjections )
{
final String attName;
final String origName = p.attributeName;
/*
* Do not export link features that are common TrackMate features
* and that we already exported above.
*/
if ( CommonTrackMateFeatureDeclarations.redundantLinkProjectionKeys.contains( origName ) )
continue;

final String attName;
/*
* If the model to export was imported from a TrackMate or a MaMuT
* file, it will already contain features with the same name that
Expand Down Expand Up @@ -634,8 +643,15 @@ private Element spotToXml( final Spot spot )

for (final ExportFeatureProjection< Spot > p : spotFeatureProjections )
{
final String attName;
final String origName = p.attributeName;
/*
* Do not export spot features that are common TrackMate features
* and that we already exported above.
*/
if ( CommonTrackMateFeatureDeclarations.redundantSpotProjectionKeys.contains( origName ) )
continue;

final String attName;
/*
* If the model to export was imported from a TrackMate or a MaMuT
* file, it will already contain features with the same name that
Expand All @@ -660,9 +676,18 @@ else if ( origName.startsWith( "IMPORTED_" ) )
attName = origName;
}

attributes.add( new Attribute(
attName,
Double.toString( p.projection.value( spot ) ) ) );

String val;
if ( p.projection instanceof IntFeatureProjection )
{
val = Integer.toString( (int) p.projection.value( spot ) );
}
else
{
// Assume double.
val = Double.toString( p.projection.value( spot ) );
}
attributes.add( new Attribute( attName, val ) );
}

final Element spotElement = new Element( SPOT_ELEMENT_TAG );
Expand All @@ -673,28 +698,61 @@ else if ( origName.startsWith( "IMPORTED_" ) )
private Element featuresDeclarationToXml()
{
final Element featuresElement = new Element( FEATURE_DECLARATION_TAG );
appendBasicFeatureDeclarations( featuresElement );
appendFeaturesDeclarationOfClass( Spot.class, featuresElement, SPOT_FEATURE_DECLARATION_TAG );
appendFeaturesDeclarationOfClass( Link.class, featuresElement, EDGE_FEATURE_DECLARATION_TAG );
// Create an empty declaration for track features, for now.
appendFeaturesDeclarationOfClass( Boolean.class, featuresElement, TRACK_FEATURE_DECLARATION_TAG );
return featuresElement;
}

private void appendBasicFeatureDeclarations( final Element featuresElement )
{
// Spots.
final Element spotFeaturesElement = getOrAddChild( featuresElement, SPOT_FEATURE_DECLARATION_TAG );
CommonTrackMateFeatureDeclarations.spotFeatureDeclarations.forEach( cf -> spotFeaturesElement.addContent( cf.toElement() ) );

// Edges.
final Element edgeFeaturesElement = getOrAddChild( featuresElement, EDGE_FEATURE_DECLARATION_TAG );
CommonTrackMateFeatureDeclarations.edgeFeatureDeclarations.forEach( cf -> edgeFeaturesElement.addContent( cf.toElement() ) );

// Tracks.
final Element trackFeaturesElement = getOrAddChild( featuresElement, TRACK_FEATURE_DECLARATION_TAG );
CommonTrackMateFeatureDeclarations.trackFeatureDeclarations.forEach( cf -> trackFeaturesElement.addContent( cf.toElement() ) );
}

@SuppressWarnings( { "unchecked", "rawtypes" } )
private < T > void appendFeaturesDeclarationOfClass( final Class< T > clazz, final Element featuresElement,
final String classFeatureDeclarationTag )
{
final List< ExportFeatureProjection< T > > projections;
List< String > redundantFeatures;
if ( clazz.equals( Spot.class ) )
{
projections = ( List ) spotFeatureProjections;
redundantFeatures = CommonTrackMateFeatureDeclarations.redundantSpotProjectionKeys;
}
else if ( clazz.equals( Link.class ) )
{
projections = ( List ) linkFeatureProjections;
redundantFeatures = CommonTrackMateFeatureDeclarations.redundantLinkProjectionKeys;
}
else
{
projections = Collections.emptyList();
redundantFeatures = CommonTrackMateFeatureDeclarations.redundantTrackProjectionKeys;
}

final Element classFeaturesElement = new Element( classFeatureDeclarationTag );
final Element classFeaturesElement = getOrAddChild( featuresElement, classFeatureDeclarationTag );
for ( final ExportFeatureProjection< T > p : projections )
{
/*
* Do not export features that are common TrackMate features and
* that we already declared.
*/
if ( redundantFeatures.contains( p.attributeName ) )
continue;

final String isint = ( p.projection instanceof IntFeatureProjection )
? "true"
: "false";
Expand All @@ -710,7 +768,17 @@ else if ( clazz.equals( Link.class ) )
fel.setAttribute( FEATURE_ISINT_ATTRIBUTE, isint );
classFeaturesElement.addContent( fel );
}
featuresElement.addContent( classFeaturesElement );
}

private Element getOrAddChild( final Element parent, final String childName )
{
Element child = parent.getChild( childName );
if ( null == child )
{
child = new Element( childName );
parent.addContent( child );
}
return child;
}

private static Document getSAXParsedDocument( final String fileName )
Expand Down Expand Up @@ -991,4 +1059,5 @@ public static final void export( final File target, final Model model, final Mam
exporter.appendGuiState();
exporter.write( target );
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ public class TrackMateXMLKeys

public static final String NFRAMES_ATTRIBUTE = "nframes";

public static final String FRAME_INTERVAL_ATTRIBUTE = "timeinterval";

public static final String PIXEL_WIDTH_ATTRIBUTE = "pixelwidth";

public static final String PIXEL_HEIGHT_ATTRIBUTE = "pixelheight";
Expand Down
Loading