Skip to content
Snippets Groups Projects
Commit 804f8aee authored by Daniel Felipe  GONZALEZ OBANDO's avatar Daniel Felipe GONZALEZ OBANDO
Browse files

First code commit

parent 317b59a2
No related branches found
No related tags found
No related merge requests found
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="ICY_JAR"/>
<classpathentry kind="var" path="ICY_PLUGINS/adufour/ezplug/EzPlug.jar"/>
<classpathentry kind="var" path="ICY_PLUGINS/adufour/blocks/Blocks.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
/*.jar
/bin/
.project 0 → 100644
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>fft</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
FFT.png 0 → 100644
FFT.png

31.4 KiB

FFT_icon.png

6.04 KiB

<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?>
<jardesc>
<jar path="fft/fftPlugin.jar"/>
<options buildIfNeeded="true" compress="true" descriptionLocation="/fft/export.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="true" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
<storedRefactorings deprecationInfo="true" structuralOnly="false"/>
<selectedProjects/>
<manifest generateManifest="true" manifestLocation="/Jython/META-INF/MANIFEST.MF" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
<sealing sealJar="false">
<packagesToSeal/>
<packagesToUnSeal/>
</sealing>
</manifest>
<selectedElements exportClassFiles="true" exportJavaFiles="true" exportOutputFolder="false">
<javaElement handleIdentifier="=fft/src"/>
<file path="/fft/export.jardesc"/>
<file path="/fft/.classpath"/>
<file path="/fft/.project"/>
</selectedElements>
</jardesc>
package plugins.praveen.fft;
import cern.colt.function.tdouble.DoubleDoubleFunction;
public interface AssignFunction2D {
void assign(double[] in, double[] out, int _w, int _h,
DoubleDoubleFunction Function);
}
package plugins.praveen.fft;
import cern.colt.function.tdouble.DoubleDoubleFunction;
public interface AssignFunction3D {
void assign(double[] in, double[][][] out, int _w, int _h, int _z, int c,
DoubleDoubleFunction function);
}
package plugins.praveen.fft;
import cern.colt.function.tdouble.DoubleDoubleFunction;
public class AssignFunctions {
//function that walks the 2D FFT from JTransforms and fills the sequence data array
//this is the version that does not swap the quadrants
public static class DirectAssign2D implements AssignFunction2D {
public void assign(double[] in, double[] out, int _w, int _h,
DoubleDoubleFunction function) {
for (int i = 0; i < in.length/2; i++)
{
double real = in[2*i];
double imag = in[2*i + 1];
out[i] = function.apply(real, imag);
}
}
}
//function that walks the 3D FFT from JTransforms and fills the sequence data array
//this is the version that does not swap the quadrants
public static class DirectAssign3D implements AssignFunction3D {
public void assign(double[] in, double[][][] out, int _w, int _h, int _z, int c,
DoubleDoubleFunction function) {
for(int z = 0; z < _z; z++)
{
for(int y = 0; y < _h; y++)
{
for(int x = 0; x < _w; x++)
{
double real = in[(x + (y * _w) + (z * _w * _h))*2 + 0];
double imag = in[(x + (y * _w) + (z * _w * _h))*2 + 1];
out[z][c][x + _w*y] = function.apply(real, imag);
}
}
}
}
}
// function that walks the 2D FFT from JTransforms and fills the sequence data array
// this is the version that swaps the quadrants
public static class SwapAssign2D implements AssignFunction2D{
public void assign(double[] in, double[] out, int _w, int _h,
DoubleDoubleFunction function)
{
int wc = (int) Math.ceil(_w/2);
int hc = (int) Math.ceil(_h/2);
for(int y = 0; y < _h; y++)
{
for(int x = 0; x < _w; x++)
{
double real = in[(x + y*_w)*2 + 0];
double imag = in[(x + y*_w)*2 + 1];
int sx = (x + wc)%_w; // swap quadrants !
int sy = (y + hc)%_h;
out[sx + _w*sy] = function.apply(real, imag);
}
}
}
}
//function that walks the 3D FFT from JTransforms and fills the sequence data array
//this is the version that swaps the quadrants
public static class SwapAssign3D implements AssignFunction3D {
public void assign(double[] in, double[][][] out, int _w, int _h, int _z, int c,
DoubleDoubleFunction function) {
int wc = (int) Math.ceil(_w/2);
int hc = (int) Math.ceil(_h/2);
int zc = (int) Math.ceil(_z/2);
for(int z = 0; z < _z; z++)
{
for(int y = 0; y < _h; y++)
{
for(int x = 0; x < _w; x++)
{
double real = in[(x + y * _w + z * _w * _h)*2 + 0];
double imag = in[(x + y * _w + z * _w * _h)*2 + 1];
int sx = (x + wc)%_w; // swap quadrants !
int sy = (y + hc)%_h;
int sz = (z + zc)%_z;
out[sz][c][sx + _w*sy] = function.apply(real, imag);
}
}
}
}
}
}
package plugins.praveen.fft;
import cern.colt.function.tdouble.DoubleDoubleFunction;
public class ComplexFunctions {
public static class Real implements DoubleDoubleFunction
{
public double apply(double real, double imag)
{
return real;
}
};
public static class Imag implements DoubleDoubleFunction
{
public double apply(double real, double imag)
{
return imag;
}
};
public static class Magnitude implements DoubleDoubleFunction
{
public double apply(double real, double imag)
{
return Math.sqrt(Math.pow(real, 2) + Math.pow(imag, 2));
}
};
public static class Angle implements DoubleDoubleFunction
{
public double apply(double real, double imag)
{
return Math.atan2(imag, real);
}
};
}
package plugins.praveen.fft;
import cern.colt.function.tdouble.DoubleDoubleFunction;
import edu.emory.mathcs.jtransforms.fft.DoubleFFT_2D;
import edu.emory.mathcs.jtransforms.fft.DoubleFFT_3D;
import icy.image.IcyBufferedImage;
import icy.sequence.Sequence;
import icy.type.DataType;
import icy.type.collection.array.Array1DUtil;
import plugins.adufour.blocks.lang.Block;
import plugins.adufour.blocks.util.VarList;
import plugins.adufour.ezplug.EzPlug;
import plugins.adufour.ezplug.EzVarBoolean;
import plugins.adufour.ezplug.EzVarEnum;
import plugins.adufour.ezplug.EzVarSequence;
import plugins.adufour.vars.lang.VarSequence;
public class FFT extends EzPlug implements Block {
public static enum FFTDims {
FFT_2D("2D (xy)"), FFT_3D("3D (xyz)");
private String stringValue;
FFTDims(String s) { stringValue = s; }
public String toString() { return stringValue; }
}
public static enum FFTOutputType {
MAGNITUDE_PHASE("Magnitude/Phase Pair"), REAL_IMAG("Real/Imaginary Pair");
private String stringValue;
FFTOutputType(String s) { stringValue = s; }
public String toString() { return stringValue; }
}
EzVarSequence input = new EzVarSequence("Input");
EzVarEnum<FFTDims> ndims = new EzVarEnum<FFTDims>("Type", FFTDims.values(), 0);
EzVarEnum<FFTOutputType> outputType = new EzVarEnum<FFTOutputType>("Output as", FFTOutputType.values(), 0);
EzVarBoolean swap = new EzVarBoolean("Swap Quadrants?", false);
VarSequence fSequenceVar = new VarSequence("FFT sequence", null);
@Override
protected void initialize() {
super.addEzComponent(input);
super.addEzComponent(ndims);
super.addEzComponent(outputType);
super.addEzComponent(swap);
super.setTimeDisplay(true);
}
// declare ourself to Blocks
@Override
public void declareInput(VarList inputMap) {
inputMap.add(input.name, input.getVariable());
inputMap.add(ndims.name, ndims.getVariable());
inputMap.add(outputType.name, outputType.getVariable());
inputMap.add(swap.name, swap.getVariable());
}
// declare ourself to Blocks
@Override
public void declareOutput(VarList outputMap) {
outputMap.add(fSequenceVar.getName(), fSequenceVar);
}
@Override
protected void execute() {
Sequence sequence = input.getValue();
Sequence fSequence = null;
if(ndims.getValue()==FFTDims.FFT_2D)
{
fSequence = FFT_2D(sequence, swap.getValue(), outputType.getValue());
}
else
{
if (sequence.getSizeZ() >= 2)
{
fSequence = FFT_3D(sequence, swap.getValue(), outputType.getValue());
}
else
{
System.err.println("Sequence depth is 1, so computing 2D FFT instead of 3D.");
fSequence = FFT_2D(sequence, swap.getValue(), outputType.getValue());
}
}
if (!isHeadLess()) {
addSequence(fSequence);
}
fSequenceVar.setValue(fSequence);
}
private Sequence FFT_3D(Sequence sequence, boolean swap, FFTOutputType outputType) {
int _w = sequence.getSizeX();
int _h = sequence.getSizeY();
int _z = sequence.getSizeZ();
final DoubleFFT_3D fft = new DoubleFFT_3D(_z, _h, _w);
Sequence fSequence = new Sequence();
fSequence.setName("Fourier Transform 3D");
// allocate the output sequence
for(int k = 0; k < _z; k++)
{
IcyBufferedImage fImage = new IcyBufferedImage(_w, _h, 2, DataType.DOUBLE);
fSequence.setImage(0, k, fImage);
}
double[] fArray = new double[_w*_h*_z*2];
// copy the data in fArray, with proper structure
for(int k = 0; k < _z; k++)
{
Array1DUtil.arrayToDoubleArray(sequence.getDataXY(0, k, 0), 0, fArray, k*_w*_h, _w*_h, sequence.isSignedDataType());
}
fft.realForwardFull(fArray);
// direct reference to 3D byte array data [Z][C][XY] for specified t
double[][][] resultData = fSequence.getDataXYCZAsDouble(0);
DoubleDoubleFunction channel0ApplyFunction = null;
DoubleDoubleFunction channel1ApplyFunction = null;
if(outputType == FFTOutputType.MAGNITUDE_PHASE)
{
channel0ApplyFunction = new ComplexFunctions.Magnitude();
channel1ApplyFunction = new ComplexFunctions.Angle();
fSequence.setChannelName(0, "Magnitude");
fSequence.setChannelName(1, "Phase");
}
else
{
channel0ApplyFunction = new ComplexFunctions.Real();
channel1ApplyFunction = new ComplexFunctions.Imag();
fSequence.setChannelName(0, "Real");
fSequence.setChannelName(1, "Imaginary");
}
AssignFunction3D assignFunction = null;
if(!swap) // No Quadrant swapping. Leave as it is.
{
assignFunction = new AssignFunctions.DirectAssign3D();
}
else
{
assignFunction = new AssignFunctions.SwapAssign3D(); // Swap Quadrants
}
assignFunction.assign(fArray, resultData, _w, _h, _z, 0, channel0ApplyFunction);
assignFunction.assign(fArray, resultData, _w, _h, _z, 1, channel1ApplyFunction);
fSequence.dataChanged();
return fSequence;
}
private Sequence FFT_2D(Sequence sequence, boolean swap, FFTOutputType outputType)
{
Sequence fSequence = new Sequence();
fSequence.setName("Fourier Transform 2D");
int _w = sequence.getSizeX();
int _h = sequence.getSizeY();
int _z = sequence.getSizeZ();
final DoubleFFT_2D fft = new DoubleFFT_2D(_h, _w);
DoubleDoubleFunction channel0Function = null;
DoubleDoubleFunction channel1Function = null;
if(outputType == FFTOutputType.MAGNITUDE_PHASE)
{
channel0Function = new ComplexFunctions.Magnitude();
channel1Function = new ComplexFunctions.Angle();
fSequence.setChannelName(0, "Magnitude");
fSequence.setChannelName(1, "Phase");
}
else // Real/Imaginary Pair
{
channel0Function = new ComplexFunctions.Real();
channel1Function = new ComplexFunctions.Imag();
fSequence.setChannelName(0, "Real");
fSequence.setChannelName(1, "Imaginary");
}
AssignFunction2D assignFunction = null;
if(!swap) //No Quadrant swapping
{
assignFunction = new AssignFunctions.DirectAssign2D();
}
else //Swap quadrants
{
assignFunction = new AssignFunctions.SwapAssign2D();
}
for(int k = 0; k < _z; k++)
{
double[] fArray = new double[_w*_h*2];
Array1DUtil.arrayToDoubleArray(sequence.getDataXY(0, k, 0), 0, fArray, 0, _w*_h, sequence.isSignedDataType());
// Computes 2D forward DFT of real data leaving the result in fArray
// Because the result is stored in fArray, fArray must be of size rows*2*columns,
// with only the first rows*columns elements filled with real data.
fft.realForwardFull(fArray);
IcyBufferedImage resultArray = new IcyBufferedImage(_w, _h, 2, DataType.DOUBLE);
double[][] resultData = resultArray.getDataXYCAsDouble();
assignFunction.assign(fArray, resultData[0], _w, _h, channel0Function);
assignFunction.assign(fArray, resultData[1], _w, _h, channel1Function);
resultArray.dataChanged();
fSequence.setImage(0, k, resultArray);
}
return fSequence;
}
@Override
public void clean() {
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment