简介
本文是致力于使用您自己的模块扩展 TrackMate 的系列文章中的第二篇文章。在这里,我们专注于创建特征分析器:计算 TrackMate 结果的一个或多个数值的小型算法。previous article专注于编写的边缘分析器:用于两个点之间的链接分配数值的算法。
在本文中,我们将创建一个轨道特征分析器,用于计算整个轨道的数值。为了简单入门,也为了回答同事的请求,我们将创建一个分析器来报告轨道起点和终点的位置。
事实上,除了我们之前看到的之外,我们不会学到太多的东西。唯一的小变化是我们的分析器将生成 6 个数值,而不是 1 个。我们将像以前一样使用 SciJava 发现机制,但只是为了它,我们将介绍如何 消除 模块。
跟踪分析器
所有轨道特征分析器必须实现EdgeAnalyzer。与TrackAnalyzer interface接口一样,它扩展了
- TrackMateModule帮助您声明您的计算结果,
- 和FeatureAnalyzer,负责TrackMate中的集成。
对我们来说唯一的变化是两个特定于轨道的方法:
public void process( final Collection< Integer > trackIDs, final Model model );
对指定轨道进行实际特征计算,并且
public boolean isLocal();
指定一个轨迹的特征计算仅影响该轨迹或所有轨迹。对于局部与非局部特征分析器的讨论,我向previous article item报告。
跟踪特征分析器头
与所有 TrackMate 模块一样,您需要注意您的类别可以被 TrackMate 发现。它采用以下形状:
@Plugin( type = TrackAnalyzer.class )
public class TrackStartSpotAnalyzer implements TrackAnalyzer
{
// etc...
这已经够了。
声明特性
您声明提供的功能与以前相同。这次,单个分析器返回 6 个值,因此您需要声明它们。这是相关代码:
@Plugin( type = TrackAnalyzer.class )
public class TrackStartSpotAnalyzer implements TrackAnalyzer
{
private static final String KEY = "TRACK_START_SPOT_ANALYZER";
public static final String TRACK_START_X = "TRACK_START_X";
public static final String TRACK_START_Y = "TRACK_START_Y";
public static final String TRACK_START_Z = "TRACK_START_Z";
public static final String TRACK_STOP_X = "TRACK_STOP_X";
public static final String TRACK_STOP_Y = "TRACK_STOP_Y";
public static final String TRACK_STOP_Z = "TRACK_STOP_Z";
private static final List< String > FEATURES = new ArrayList< String >( 6 );
private static final Map< String, String > FEATURE_SHORT_NAMES = new HashMap< String, String >( 6 );
private static final Map< String, String > FEATURE_NAMES = new HashMap< String, String >( 6 );
private static final Map< String, Dimension > FEATURE_DIMENSIONS = new HashMap< String, Dimension >( 6 );
static
{
FEATURES.add( TRACK_START_X );
FEATURES.add( TRACK_START_Y );
FEATURES.add( TRACK_START_Z );
FEATURES.add( TRACK_STOP_X );
FEATURES.add( TRACK_STOP_Y );
FEATURES.add( TRACK_STOP_Z );
FEATURE_NAMES.put( TRACK_START_X, "Track start X" );
FEATURE_NAMES.put( TRACK_START_Y, "Track start Y" );
FEATURE_NAMES.put( TRACK_START_Z, "Track start Z" );
FEATURE_NAMES.put( TRACK_STOP_X, "Track stop X" );
FEATURE_NAMES.put( TRACK_STOP_Y, "Track stop Y" );
FEATURE_NAMES.put( TRACK_STOP_Z, "Track stop Z" );
FEATURE_SHORT_NAMES.put( TRACK_START_X, "X start" );
FEATURE_SHORT_NAMES.put( TRACK_START_Y, "Y start" );
FEATURE_SHORT_NAMES.put( TRACK_START_Z, "Z start" );
FEATURE_SHORT_NAMES.put( TRACK_STOP_X, "X stop" );
FEATURE_SHORT_NAMES.put( TRACK_STOP_Y, "Y stop" );
FEATURE_SHORT_NAMES.put( TRACK_STOP_Z, "Z stop" );
FEATURE_DIMENSIONS.put( TRACK_START_X, Dimension.POSITION );
FEATURE_DIMENSIONS.put( TRACK_START_Y, Dimension.POSITION );
FEATURE_DIMENSIONS.put( TRACK_START_Z, Dimension.POSITION );
FEATURE_DIMENSIONS.put( TRACK_STOP_X, Dimension.POSITION );
FEATURE_DIMENSIONS.put( TRACK_STOP_Y, Dimension.POSITION );
FEATURE_DIMENSIONS.put( TRACK_STOP_Z, Dimension.POSITION );
}
/*
* FEATUREANALYZER METHODS
*/
@Override
public List< String > getFeatures()
{
return FEATURES;
}
@Override
public Map< String, String > getFeatureShortNames()
{
return FEATURE_SHORT_NAMES;
}
@Override
public Map< String, String > getFeatureNames()
{
return FEATURE_NAMES;
}
@Override
public Map< String, Dimension > getFeatureDimensions()
{
return FEATURE_DIMENSIONS;
}
现在让我们计算一下它们。
访问 TrackMate 中的曲目
在上一篇文章中,我们可能快速地介绍了如何访问 TrackMate 中的数据。这不是本系列的目标,但这里有一个快速回顾:
所有轨道结构都存储在模型的一个子组件中,称为here。它存储图形构建的两个点之间的链接集合,并具有一些相当复杂的逻辑来维护连接组件的列表:轨道。
轨道本身通过其ID进行索引,存储为int,没有特殊意义。一旦你获得了轨道的ID,你就可以得到它包含的点
trackModel.trackSpots( trackID )
其链接(或边缘)
trackModel.trackEdges( trackID )
让我们利用这一点。
计算起点和终点的位置
嗯,它只是搜索轨道并识别其起点和终点。下面是处理方法的完整代码:
@Override
public void process( final Collection< Integer > trackIDs, final Model model )
{
// The feature model where we store the feature values:
final FeatureModel fm = model.getFeatureModel();
// Loop over all the tracks we have to process.
for ( final Integer trackID : trackIDs )
{
// The tracks are indexed by their ID. Here is how to get their
// content:
final Set< Spot > spots = model.getTrackModel().trackSpots( trackID );
// Or .trackEdges( trackID ) if you want the edges.
// This set is NOT ordered. If we want the first one and last one we
// have to sort them:
final Comparator< Spot > comparator = Spot.frameComparator;
final List< Spot > sorted = new ArrayList< Spot >( spots );
Collections.sort( sorted, comparator );
// Extract and store feature values.
final Spot first = sorted.get( 0 );
fm.putTrackFeature( trackID, TRACK_START_X, Double.valueOf( first.getDoublePosition( 0 ) ) );
fm.putTrackFeature( trackID, TRACK_START_Y, Double.valueOf( first.getDoublePosition( 1 ) ) );
fm.putTrackFeature( trackID, TRACK_START_Z, Double.valueOf( first.getDoublePosition( 2 ) ) );
final Spot last = sorted.get( sorted.size() - 1 );
fm.putTrackFeature( trackID, TRACK_STOP_X, Double.valueOf( last.getDoublePosition( 0 ) ) );
fm.putTrackFeature( trackID, TRACK_STOP_Y, Double.valueOf( last.getDoublePosition( 1 ) ) );
fm.putTrackFeature( trackID, TRACK_STOP_Z, Double.valueOf( last.getDoublePosition( 2 ) ) );
// Et voilà!
}
}
分析器的完整代码可以在TrackModel中找到。
总结
等马尔凯!

在下一篇文章中,我们将构建一个点分析器,并通过引入优先级的概念使事情变得复杂一些。但在此之前,先简单介绍一下如何取消模块。
如何取消模块
假设您的代码树中有一个您不想再使用的 TrackMate 模块。最简单的方法是删除它的类,但这是另一种允许我们引入SciJava插件注释参数的方法。
@Plugin( type = TrackAnalyzer.class )注释在type之上接受额外的参数。它们均采用key = value对形状,其中一些允许对TrackMate模块集成进行偏好。
我们将看到的第一个是 enabled 值。它接受 boolean 作为值,默认情况下它是 true。它的用法很明显:
If you want to disable a TrackMate module, add the enabled = false annotation parameter.
像这样:
@Plugin( type = TrackAnalyzer.class, enabled = false )
取消的模块甚至不会被实例化。他们就像死了一样,只不过你可以轻易改变主意。顺便说一句,你可以看到 TrackMate 源代码树有很多这样的取消模块……
Jean-Yves Tinevez 14:23, 11 March 2014 (CDT)