// Path: src/main/java/fiji/plugin/mamut/feature/spot/SpotSourceIdAnalyzerFactory.java
// @Plugin( type = MamutSpotAnalyzerFactory.class )
// public class SpotSourceIdAnalyzerFactory< T extends RealType< T > & NativeType< T > > implements MamutSpotAnalyzerFactory< T >
// {
// 
// 	/** The name of the spot source id feature. */
// 	public static final String SOURCE_ID = "SOURCE_ID";
// 
// 	/** Additional spot features used in MaMuT. */
// 	public final static List< String > FEATURES = new ArrayList<>();
// 	public final static Map< String, String > FEATURE_NAMES = new HashMap<>();
// 	public final static Map< String, String > FEATURE_SHORT_NAMES = new HashMap<>();
// 	public final static Map< String, Dimension > FEATURE_DIMENSIONS = new HashMap<>();
// 	public static final Map< String, Boolean > IS_INT = new HashMap<>();
// 	public static final String KEY = "Spot Source ID";
// 
// 	static
// 	{
// 		FEATURES.add( SOURCE_ID );
// 		FEATURE_NAMES.put( SOURCE_ID, "Source ID" );
// 		FEATURE_SHORT_NAMES.put( SOURCE_ID, "Source" );
// 		FEATURE_DIMENSIONS.put( SOURCE_ID, Dimension.NONE );
// 		IS_INT.put( SOURCE_ID, Boolean.TRUE );
// 	}
// 
// 	@Override
// 	public String getKey()
// 	{
// 		return KEY;
// 	}
// 
// 	@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;
// 	}
// 
// 
// 	@Override
// 	public SpotAnalyzer< T > getAnalyzer( final ImgPlus< T > img, final int frame, final int channel )
// 	{
// 		return SpotAnalyzer.dummyAnalyzer();
// 	}
// 
// 	@Override
// 	public String getInfoText()
// 	{
// 		return "";
// 	}
// 
// 	@Override
// 	public ImageIcon getIcon()
// 	{
// 		return null;
// 	}
// 
// 	@Override
// 	public String getName()
// 	{
// 		return "Spot source analyzer";
// 	}
// 
// 	@Override
// 	public Map< String, Boolean > getIsIntFeature()
// 	{
// 		return IS_INT;
// 	}
// 
// 	@Override
// 	public boolean isManualFeature()
// 	{
// 		return true;
// 	}
// }


import java.util.List;
import bdv.util.Affine3DHelpers;
import bdv.viewer.Source;
import bdv.viewer.SourceAndConverter;
import fiji.plugin.mamut.feature.spot.SpotSourceIdAnalyzerFactory;
import fiji.plugin.trackmate.Logger;
import fiji.plugin.trackmate.Model;
import fiji.plugin.trackmate.SelectionModel;
import fiji.plugin.trackmate.Spot;
import fiji.plugin.trackmate.detection.semiauto.AbstractSemiAutoTracker;
import net.imglib2.FinalInterval;
import net.imglib2.Interval;
import net.imglib2.Point;
import net.imglib2.RandomAccess;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.position.transform.Round;
import net.imglib2.realtransform.AffineTransform3D;
import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.view.Views;
		/*
		 * Build the transformation that will put back the found spot in the
		 * global coordinate system.
		 */

		final AffineTransform3D scale = new AffineTransform3D();
		for ( int i = 0; i < 3; i++ )
		{
			scale.set( 1 / cal[ i ], i, i );
		}
		final AffineTransform3D translate = new AffineTransform3D();
		for ( int i = 0; i < 3; i++ )
		{
			translate.set( min[ i ], i, 3 );
		}
		final AffineTransform3D transform = sourceToGlobal.copy().concatenate( scale );

		final SearchRegion< T > sn = new SearchRegion<>();
		sn.source = Views.dropSingletonDimensions( rai );
		sn.interval = interval;
		sn.transform = transform;
		sn.calibration = calibration;
		return sn;
	}

	@Override
	protected void exposeSpot( final Spot newSpot, final Spot previousSpot )
	{
		// We just copy the SOURCE_INDEX value from the old spot to the new
		// spot.
// Path: src/main/java/fiji/plugin/mamut/feature/spot/SpotSourceIdAnalyzerFactory.java
// @Plugin( type = MamutSpotAnalyzerFactory.class )
// public class SpotSourceIdAnalyzerFactory< T extends RealType< T > & NativeType< T > > implements MamutSpotAnalyzerFactory< T >
// {
// 
// 	/** The name of the spot source id feature. */
// 	public static final String SOURCE_ID = "SOURCE_ID";
// 
// 	/** Additional spot features used in MaMuT. */
// 	public final static List< String > FEATURES = new ArrayList<>();
// 	public final static Map< String, String > FEATURE_NAMES = new HashMap<>();
// 	public final static Map< String, String > FEATURE_SHORT_NAMES = new HashMap<>();
// 	public final static Map< String, Dimension > FEATURE_DIMENSIONS = new HashMap<>();
// 	public static final Map< String, Boolean > IS_INT = new HashMap<>();
// 	public static final String KEY = "Spot Source ID";
// 
// 	static
// 	{
// 		FEATURES.add( SOURCE_ID );
// 		FEATURE_NAMES.put( SOURCE_ID, "Source ID" );
// 		FEATURE_SHORT_NAMES.put( SOURCE_ID, "Source" );
// 		FEATURE_DIMENSIONS.put( SOURCE_ID, Dimension.NONE );
// 		IS_INT.put( SOURCE_ID, Boolean.TRUE );
// 	}
// 
// 	@Override
// 	public String getKey()
// 	{
// 		return KEY;
// 	}
// 
// 	@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;
// 	}
// 
// 
// 	@Override
// 	public SpotAnalyzer< T > getAnalyzer( final ImgPlus< T > img, final int frame, final int channel )
// 	{
// 		return SpotAnalyzer.dummyAnalyzer();
// 	}
// 
// 	@Override
// 	public String getInfoText()
// 	{
// 		return "";
// 	}
// 
// 	@Override
// 	public ImageIcon getIcon()
// 	{
// 		return null;
// 	}
// 
// 	@Override
// 	public String getName()
// 	{
// 		return "Spot source analyzer";
// 	}
// 
// 	@Override
// 	public Map< String, Boolean > getIsIntFeature()
// 	{
// 		return IS_INT;
// 	}
// 
// 	@Override
// 	public boolean isManualFeature()
// 	{
// 		return true;
// 	}
// }


// Path: src/main/java/fiji/plugin/mamut/detection/SourceSemiAutoTracker.java
import java.util.List;
import bdv.util.Affine3DHelpers;
import bdv.viewer.Source;
import bdv.viewer.SourceAndConverter;
import fiji.plugin.mamut.feature.spot.SpotSourceIdAnalyzerFactory;
import fiji.plugin.trackmate.Logger;
import fiji.plugin.trackmate.Model;
import fiji.plugin.trackmate.SelectionModel;
import fiji.plugin.trackmate.Spot;
import fiji.plugin.trackmate.detection.semiauto.AbstractSemiAutoTracker;
import net.imglib2.FinalInterval;
import net.imglib2.Interval;
import net.imglib2.Point;
import net.imglib2.RandomAccess;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.position.transform.Round;
import net.imglib2.realtransform.AffineTransform3D;
import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.view.Views;

		/*
		 * Build the transformation that will put back the found spot in the
		 * global coordinate system.
		 */

		final AffineTransform3D scale = new AffineTransform3D();
		for ( int i = 0; i < 3; i++ )
		{
			scale.set( 1 / cal[ i ], i, i );
		}
		final AffineTransform3D translate = new AffineTransform3D();
		for ( int i = 0; i < 3; i++ )
		{
			translate.set( min[ i ], i, 3 );
		}
		final AffineTransform3D transform = sourceToGlobal.copy().concatenate( scale );

		final SearchRegion< T > sn = new SearchRegion<>();
		sn.source = Views.dropSingletonDimensions( rai );
		sn.interval = interval;
		sn.transform = transform;
		sn.calibration = calibration;
		return sn;
	}

	@Override
	protected void exposeSpot( final Spot newSpot, final Spot previousSpot )
	{
		// We just copy the SOURCE_INDEX value from the old spot to the new
		// spot.
		final Double sourceIndex = previousSpot.getFeature( SpotSourceIdAnalyzerFactory.SOURCE_ID );