id summary reporter owner description type status priority milestone component version severity resolution keywords cc blockedby blocking
2012 Support general text specified axis class bdezonia bdezonia "There are good reasons to support one kind of axis that has it's equation defined by a string. I have mocked up a class below. This is not a simple endeavor but would eliminate a lot of (sometimes redundant) concrete CalibratedAxis implementations. See notes in code below for pointers.
{{{
package net.imglib2.meta.axis;
import net.imglib2.meta.AxisType;
/**
* A very general text driven axis class.
*
* @author Barry DeZonia
*/
public class UberAsciiAxis extends VariableAxis {
// I might be getting carried away but think it would be nice to define axes
// by equation alone. IJ1 has lots of one off definitions in CurveFitter that
// have offsets or not or powers or not. I've generalized some of this by
// always having an offset that can be 0. But really we'd like the flexibility
// of not needing a new concrete axis class every time someone comes up with a
// new formula. This class would parse the equation and build an appropriate
// function that can scale coords as needed. The nice thing here is that the
// parsed axis can be queried for variables and then a curve fitting algo can
// determine appropriate variable values. Curtis' idea of the EditAxes plugin
// directly tweaking the variables of a displayed equation is correct. There
// remains the trick of determining when an axis is linear. This can be done
// by testing that an axis.equals(some general linear axis string) as noted
// below.
// TODO - bad name: Equation is more general than our 1d case
private interface Equation {
// This might be involved to determine but it would be fun to write!
Equation inverse(); // if doesn't exist we will return a NullEquation
double eval(double input);
// TODO - maybe one String method rather than two.
String generalEquation();
String particularEquation(); // likely in an abstract class
}
// equation string can be things like:
// y = m*x + b
// y = 74*x + b
// y = q*sin(slope*x+19.4)^(33*power)+fred (here only x & y are predefined)
// constants and vars automatically detected
private final String equationString;
private final Equation eqn;
private final Equation eqnInverse;
public UberAsciiAxis(AxisType type, String unit, String equationString) {
super(type, unit);
this.eqn = parse(equationString);
this.eqnInverse = eqn.inverse();
this.equationString = equationString;
}
public UberAsciiAxis(AxisType type, String unit, Equation equation) {
super(type, unit);
this.eqn = equation;
this.eqnInverse = eqn.inverse();
this.equationString = equation.generalEquation(); // or particular?
}
@Override
public double calibratedValue(double rawValue) {
return eqn.eval(rawValue);
}
@Override
public double rawValue(double calibratedValue) {
return eqnInverse.eval(calibratedValue);
}
@Override
public String generalEquation() {
return equationString;
}
@Override
public UberAsciiAxis copy() {
return new UberAsciiAxis(type(), unit(), equationString);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof UberAsciiAxis)) return false;
UberAsciiAxis other = (UberAsciiAxis) o;
// TODO: do something really cool. compare syntax trees and variables of the
// two UberAxes. Even trickier: detect when vars of two eqns are the same
// due to coeffs being 1 or 0. For example y = 1*x + 0 is same as y = x
// though they would have different syntax trees.
// TEMP: only equal to self
return other == this;
}
// For generality and reuse elsewhere maybe make parser return multidim
// equation. We'd need to test that it has a single dim of input to qualify as
// a valid axis equation
private Equation parse(String equationString) {
// TODO
return new NullEquation();
}
// return one of these as an Equation::inverse() when it is not invertible
private class NullEquation implements Equation {
@Override
public double eval(double input) {
return Double.NaN;
}
@Override
public Equation inverse() {
return this;
}
@Override
public String generalEquation() {
return ""y = NaN"";
}
@Override
public String particularEquation() {
return ""y = NaN"";
}
}
}
}}}
" defect closed major imagej-2.0.0 ImgLib2 serious moved 1400