Skip to content

Commit

Permalink
moved to new version number in preparation of V 1.0.9. Added access t…
Browse files Browse the repository at this point in the history
…o fitted data in conrad.fitting

akm
  • Loading branch information
Andreas Maier authored and Andreas Maier committed Mar 16, 2019
1 parent 47938ad commit 4ce59b7
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 62 deletions.
53 changes: 50 additions & 3 deletions src/edu/stanford/rsl/conrad/fitting/Function.java
Expand Up @@ -2,31 +2,53 @@

import java.io.Serializable;

import edu.stanford.rsl.jpop.FunctionOptimizer;
import edu.stanford.rsl.jpop.OptimizableFunction;


/**
* Class to describe an abstract function that can be fiited to a set of 2D Points.
*
* @author akmaier
*
*/
public abstract class Function implements Serializable {
public abstract class Function implements Serializable, OptimizableFunction{

/**
*
*/
private boolean debug = false;
private static final long serialVersionUID = 5067981485975476424L;
protected boolean fittingDone = false;
protected int numberOfParameters = 0;
public abstract double [] getParametersAsDoubleArray();

public abstract void setParametersFromDoubleArray(double [] param);
private double fitdatax[];
private double fitdatay[];

/**
* Fits the function to the given input data
* @param x the input data
* @param y the output data
*/
public abstract void fitToPoints(double [] x, double [] y);
public void fitToPoints(double [] x, double [] y){
fitdatax = x;
fitdatay = y;
FunctionOptimizer funcOpt = new FunctionOptimizer(this.getNumberOfParameters());
funcOpt.setInitialX(this.getInitialX());
funcOpt.optimizeFunction(this);
double [] solved = funcOpt.getOptimum();
this.setParametersFromDoubleArray(solved);
fittingDone = true;
};

protected double[] getInitialX() {
double init [] = new double [this.getNumberOfParameters()];
for (int i=0; i < this.getNumberOfParameters(); i++){
init[i] = 0;
}
return init;
}
public void fitToPoints(float []x, float []y){
double [] dx = new double[x.length];
double [] dy = new double[y.length];
Expand Down Expand Up @@ -61,4 +83,29 @@ public int getNumberOfParameters() {
return numberOfParameters;
}


@Override
public void setNumberOfProcessingBlocks(int number) {
}

@Override
public int getNumberOfProcessingBlocks() {
// TODO Auto-generated method stub
return 1;
}

@Override
public double evaluate(double[] x, int block) {
double value = 0;
this.setParametersFromDoubleArray(x);
for (int i=0; i < fitdatax.length; i++){
value += Math.pow(this.evaluate(fitdatax[i])- fitdatay[i], 2);
}
value = Math.sqrt(value);
// Catch parameterization errors and assign maximal cost.
if (!Double.isFinite(value)) value = Double.MAX_VALUE;
if (debug) System.out.println("Value " + value);
return value;
}

}
6 changes: 6 additions & 0 deletions src/edu/stanford/rsl/conrad/fitting/GaussianFunction.java
Expand Up @@ -79,4 +79,10 @@ public double[] getParametersAsDoubleArray() {
return new double[]{mu, sigma};
}

@Override
public void setParametersFromDoubleArray(double[] param) {
mu = param[0];
sigma = param[1];
}

}
5 changes: 5 additions & 0 deletions src/edu/stanford/rsl/conrad/fitting/IdentityFunction.java
Expand Up @@ -30,4 +30,9 @@ public double[] getParametersAsDoubleArray() {
return new double[] {};
}

@Override
public void setParametersFromDoubleArray(double[] param) {

}

}
6 changes: 6 additions & 0 deletions src/edu/stanford/rsl/conrad/fitting/LinearFunction.java
Expand Up @@ -98,4 +98,10 @@ public double[] getParametersAsDoubleArray() {
return new double[]{m,t};
}

@Override
public void setParametersFromDoubleArray(double[] param) {
m = param[0];
t = param[1];
}

}
76 changes: 36 additions & 40 deletions src/edu/stanford/rsl/conrad/fitting/LogarithmicFunction.java
@@ -1,10 +1,7 @@
package edu.stanford.rsl.conrad.fitting;

import java.util.Random;

import edu.stanford.rsl.conrad.utils.DoubleArrayUtil;

public class LogarithmicFunction extends Function{
public class LogarithmicFunction extends Function {

/**
*
Expand All @@ -14,7 +11,8 @@ public class LogarithmicFunction extends Function{
private double b;
private double c;
private double d;



public LogarithmicFunction(){
numberOfParameters = 4;
}
Expand Down Expand Up @@ -43,7 +41,7 @@ private static double estimateD(double a, double b, double c, double x, double y

@Override
public double evaluate(double x){
return (a * Math.log((x - b) / c)) + d;
return (a * Math.log((x - b) / Math.abs(c))) + d;
}

private static double estimateB(double x1, double x2, double x3, double y1, double y2, double y3){
Expand All @@ -64,9 +62,9 @@ private static double estimateB(double x1, double x2, double x3, double y1, doub
public String toString(){
if (fittingDone){
return "y = (" + a + " * log((x - " +
b + ") / " +
c + ")) + " +
d;
b + ") / |" +
c + "|)) + " +
d;
} else {
return "y = (a * log((x - b) / c)) + d";
}
Expand All @@ -80,7 +78,7 @@ public void fitToThreePoints(double x1, double x2, double x3, double y1, double
fittingDone = true;
}

private boolean isValidEstimate(){
protected boolean isValidEstimate(){
boolean revan = true;
if (Double.isInfinite(a) || Double.isNaN(a)) revan = false;
if (Double.isInfinite(b) || Double.isNaN(b)) revan = false;
Expand Down Expand Up @@ -122,41 +120,18 @@ public void setD(double d) {
fittingDone = true;
}

@Override
protected double [] getInitialX(){
return new double []{1,1,1,0};
}


@Override
public void fitToPoints(double[] x, double [] y) {
if (x.length == 3) {
fitToThreePoints(x[0], x[1], x[2], y[0], y[1], y[2]);
} else {
Random random = new Random();
double [] stats = DoubleArrayUtil.minAndMaxOfArray(x);
double range = stats[1] - stats[0];
int tries = 20;
double a = 0;
double b = 0;
double c = 0;
double d = 0;
for (int i = 0; i < tries; i ++){
// select three random indices in the first the second and the third third
int fraction = 10;
int one = DoubleArrayUtil.findClosestIndex(stats[0] + (random.nextDouble() * (range / fraction)), x);
int two = DoubleArrayUtil.findClosestIndex(stats[0] + (range/2) +(random.nextDouble() * (range / fraction)), x);
int three = DoubleArrayUtil.findClosestIndex(stats[0] + range - (random.nextDouble() * (range / fraction)), x);
fitToThreePoints(x[one], x[two], x[three], y[one], y[two], y[three]);
if (isValidEstimate()){
a += this.a / tries;
b += this.b / tries;
c += this.c / tries;
d += this.d / tries;
} else {
// retry
i--;
}
}
this.a = a;
this.b = b;
this.c = c;
this.d = d;
fittingDone = true;
super.fitToPoints(x, y);
}
}

Expand All @@ -170,4 +145,25 @@ public double[] getParametersAsDoubleArray() {
return new double[]{a,b,c,d};
}

public static void main(String [] args){
LogarithmicFunction func = new LogarithmicFunction();
double [] x = {10000, 50000, 100000, 2000000, 600000000};
double [] y = {10, 20, 30, 500, 3000};
func.fitToPoints(x, y);
System.out.println(func
+ "\n" + func.evaluate(10000)
+ "\n" + func.evaluate(50000)
+ "\n" + func.evaluate(2000000)
+ "\n" + func.evaluate(600000000)
+ "\n" + func.evaluate(83000000*1000));
}

@Override
public void setParametersFromDoubleArray(double[] param) {
this.a = param[0];
this.b = param[1];
this.c = param[2];
this.d = param[3];
}

}
21 changes: 20 additions & 1 deletion src/edu/stanford/rsl/conrad/fitting/PolynomialFunction.java
Expand Up @@ -69,7 +69,7 @@ public double evaluate(double x) {
public String toString() {
String revan = "" + params[0] + " ";
for (int i=1; i <= degree; i++){
revan += params[i] + " x^" +i;
revan += "+ " +params[i] + " x^" +i;
}
return revan;
}
Expand All @@ -79,4 +79,23 @@ public int getMinimumNumberOfCorrespondences() {
return degree + 1;
}

@Override
public void setParametersFromDoubleArray(double[] param) {
params = param;
}

public static void main(String [] args){
PolynomialFunction func = new PolynomialFunction();
func.setDegree(5);
double [] x = {10000, 50000, 100000, 2000000, 600000000};
double [] y = {10, 50, 75, 500, 3000};
func.fitToPoints(x, y);
System.out.println(func
+ "\n" + func.evaluate(10000)
+ "\n" + func.evaluate(50000)
+ "\n" + func.evaluate(2000000)
+ "\n" + func.evaluate(600000000)
+ "\n" + func.evaluate(83000000*1000));
}

}
5 changes: 5 additions & 0 deletions src/edu/stanford/rsl/conrad/fitting/RANSACFittedFunction.java
Expand Up @@ -145,4 +145,9 @@ public double[] getParametersAsDoubleArray() {
return baseFunction.getParametersAsDoubleArray();
}

@Override
public void setParametersFromDoubleArray(double[] param) {
baseFunction.setParametersFromDoubleArray(param);
}

}
2 changes: 1 addition & 1 deletion src/edu/stanford/rsl/conrad/utils/CONRAD.java
Expand Up @@ -21,7 +21,7 @@
import edu.stanford.rsl.apps.gui.RawDataOpener;

public abstract class CONRAD {
public static final String VersionString = "Version 1.0.8";
public static final String VersionString = "Version 1.0.9";
public static final String CONRADBibtex = "@article{Maier13-CSF," +
" author = {A. Maier, H. G. Hofmann, M. Berger, P. Fischer, C. Schwemmer, H. Wu, K. Müller, J. Hornegger, J. H. Choi, C. Riess, A. Keil, and R. Fahrig},\n" +
" title={{CONRAD - A software framework for cone-beam imaging in radiology}},\n" +
Expand Down
36 changes: 19 additions & 17 deletions src/edu/stanford/rsl/tutorial/phantoms/FilePhantom.java
@@ -1,5 +1,6 @@
package edu.stanford.rsl.tutorial.phantoms;

import ij.IJ;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;

Expand All @@ -13,31 +14,32 @@ public class FilePhantom extends Phantom {

public FilePhantom(int imgSzXGU, int imgSzYGU, String filename) {
super(imgSzXGU, imgSzYGU, filename);
FloatProcessor fip =null;
try {
ProjectionSource pSource = FileProjectionSource.openProjectionStream(filename);
Grid2D iProcessor = pSource.getNextProjection();
FloatProcessor fip = new FloatProcessor(iProcessor.getWidth(), iProcessor.getHeight(), iProcessor.getBuffer(), null);
if (iProcessor.getWidth()!= imgSzXGU || iProcessor.getHeight()!=imgSzYGU){
ImageProcessor resize = fip.resize(imgSzXGU, imgSzXGU);
for (int j=0;j<imgSzYGU; j++){
for (int i=0;i<imgSzXGU; i++){
setAtIndex(i, j, resize.getf(i, j));
}
fip = new FloatProcessor(iProcessor.getWidth(), iProcessor.getHeight(), iProcessor.getBuffer(), null);

} catch (IOException e1) {
IJ.open(filename);
fip = IJ.getImage().getProcessor().toFloat(0, null);
}
if (fip.getWidth()!= imgSzXGU || fip.getHeight()!=imgSzYGU){
ImageProcessor resize = fip.resize(imgSzXGU, imgSzXGU);
for (int j=0;j<imgSzYGU; j++){
for (int i=0;i<imgSzXGU; i++){
setAtIndex(i, j, resize.getf(i, j));
}
}
else
{
for (int j=0;j<imgSzYGU; j++){
for (int i=0;i<imgSzXGU; i++){
setAtIndex(i, j, fip.getf(i,j));
}
}
else
{
for (int j=0;j<imgSzYGU; j++){
for (int i=0;i<imgSzXGU; i++){
setAtIndex(i, j, fip.getf(i,j));
}
}
} catch (IOException e1) {
e1.printStackTrace();
}


}

}
Expand Down

0 comments on commit 4ce59b7

Please sign in to comment.