Mark's method is neat. Here's an alternative that uses the function directly:

```
NamesDefaultToHere(1);
ClearLog();
// Make some representative data
dt = NewTable("Johnson Su", NewColumn("Data", Numeric, Continuous, Formula(Random Johnson Su( 5, 2, 1, 1 ))));
dt << addRows(50);
// Fit the data
dist = dt << Distribution(Continuous Distribution( Column( :Data ), Fit Distribution( Johnson Su ) ));
// Get the fitted parameters
params = Report(dist)[NumberColBox(3)] << get;
gamma = params[1]; // Shape
delta = params[2]; // Shape
theta = params[3]; // Location
sigma = params[4]; // Scale
// http://www.mathwave.com/articles/johnson_su_distribution.html
// f(x) = delta/(lambda * Sqrt(2*pi()) * Sqrt(z^2 + 1)) * exp( -1/2*(gamma + delta * ln(z + Sqrt(z^2+1)))^2 );
// where:
// z = (x - eta)/lambda;
// and:
// delta > 0 lambda > 0
jsu = Expr(delta/(lambda * Sqrt(2*pi()) * Sqrt(z^2 + 1)) * exp( -1/2*(gamma + delta * ln(z + Sqrt(z^2+1)))^2 ) );
SubstituteInto(jsu, Expr(z), Expr((x - eta)/lambda));
// Use the fitted parameter values
// Note the change in parameter names! 'lambda' -> 'sigma' and 'eta' -> 'theta'
SubstituteInto(jsu,
Expr(gamma), Eval(gamma),
Expr(delta), Eval(delta),
Expr(eta), Eval(theta),
Expr(lambda), Eval(sigma)
);
// Get upper and lower bounds for the optimisation (either side of the (assumed) single peak)
vals = Column(dt, "Data") << getValues;
low = Quantile(0.25, vals);
high = Quantile(0.75, vals);
// Do the maximization
Maximize(jsu, {x(low, high)}, << Tolerance(10^-10), << showDetails(true));
Print(x);
```

('By eye' it seems to work, but no testing of course).