Calling CurveFitter from Java; only 4 fit functions work

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Calling CurveFitter from Java; only 4 fit functions work

Tihamer
I've used ImageJ in the past purely as a graphic application and it's great.

Today I needed to use some of its functionality in my own Java program, so I
loaded up my project pom:

             
                <dependency>
                    <groupId>net.imagej</groupId>
                    <artifactId>ij</artifactId>
                    <version>1.52n</version>
                    <scope>test</scope>
                </dependency>

I generated some test data and called CurveFitter from main:

public static void main(String[] args) {
                double[] xData = {0.0, 1.0, 2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,  9.0,
10.0};
                double[] yData = {2.0, 5.0, 8.0, 11.0, 14.0, 17.0, 20.0, 23.0, 26.0, 29.0,
32.0}; // linear
                double[] zData = {0.0, 2.0, 16.0, 54.0, 128.0, 250.0, 432.0, 686.0,
1024.0, 1458.0, 2000.0};
                System.out.println("\nLinear Test:");
                fitMyData(xData, yData);
                System.out.println("\nPower (linear regression) Test:");
                fitMyData(xData, zData);
        }
       
        public static void fitMyData(double[] xData, double[] yData) {
                CurveFitter curveFitter = new CurveFitter(xData, yData);
                for (int functionType : CurveFitter.sortedTypes) {
                        if ( functionType != POLY3 && functionType != POLY4 && functionType !=
POLY5 &&
                                        functionType != POLY6 && functionType != POLY7 && functionType != POLY8
&&
                                        functionType != EXPONENTIAL && functionType != EXP_REGRESSION &&
                                        functionType != EXP_WITH_OFFSET && functionType != EXP_RECOVERY &&
                                        functionType != EXP_RECOVERY_NOOFFSET && functionType != LOG &&
functionType != LOG2 &&
                                        functionType != GAUSSIAN && functionType != GAUSSIAN_NOOFFSET &&
functionType != ERF &&
                                        functionType != RODBARD && functionType != RODBARD2 && functionType !=
INV_RODBARD &&
                                        functionType != GAMMA_VARIATE && functionType != CHAPMAN) {
                        System.out.print("\n\n " + functionType + " Function Type: " +
CurveFitter.fitList[functionType] + " ");
                        curveFitter.doFit(functionType);
                        System.out.print(curveFitter.getResultString());
                        }
                }
        }

The results are very nice. E.g.:

Linear Test:

 0 Function Type: Straight Line
Formula: y = a+bx
Status: Success
Number of iterations: 1
Time: 0 ms
Sum of residuals squared: 1.53560E-11
Standard deviation: 0.00000E0
R^2: 1.00000
Parameters:
        a = 2.00000
        b = 3.00000

<snip>

Power (linear regression) Test:
16 Function Type: Power (linear regression)
Formula: y = a*x^b
Status: Success
Number of iterations: 1
Time: 0 ms
Sum of residuals squared: 1.14026E-12
Standard deviation: 2.46117E-13
R^2: 1.00000
Parameters:
        a = 2.00000
        b = 3.00000

However, you can see my problem:  only four of the fit functions work; the
rest of them throw a ava.lang.ArrayIndexOutOfBoundsException.  For example:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
        at
ij.measure.CurveFitter.modifyInitialParamsAndVariations(CurveFitter.java:891)
        at ij.measure.CurveFitter.doFit(CurveFitter.java:204)
        at ij.measure.CurveFitter.doFit(CurveFitter.java:169)
        at myproject.MyTest.fitMyData(MyTest.java:85)

I looked at the source code, and I can't figure out what
modifyInitialParamsAndVariations is trying to do.

What am I doing wrong?



--
Sent from: http://imagej.1557.x6.nabble.com/

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Calling CurveFitter from Java; only 4 fit functions work

Wayne Rasband-2
> On Apr 18, 2019, at 4:00 PM, Tihamer <[hidden email]> wrote:
>
> I've used ImageJ in the past purely as a graphic application and it's great.
>
> Today I needed to use some of its functionality in my own Java program, so I
> loaded up my project pom:

The following JavaScript version of your program should work better. It requires the latest ImageJ daily build (1.52o38), which fixes a CurveFitter.getResultString() bug that caused it to fail when there was a fitting error. Note that you have to construct a new CurveFitter for each fit.

-wayne

  xData = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0];
  yData = [2.0,5.0,8.0,11.0,14.0,17.0,20.0,23.0,26.0,29.0,32.0];
  zData = [0.0,2.0,16.0,54.0,128.0,250.0,432.0,686.0,1024.0,1458.0,2000.0];
  fit("a", xData, yData);
  fit("b", xData, zData);
   
  function fit(type, xData, yData) {
      for (func in CurveFitter.sortedTypes) {
         cf = new CurveFitter(xData, yData);
         IJ.log("\n"+func +type+": "+ CurveFitter.fitList[func]);
         cf.doFit(func);
         IJ.log(cf.getResultString());
      }
  }

-wayne

>
> <dependency>
>    <groupId>net.imagej</groupId>
>    <artifactId>ij</artifactId>
>    <version>1.52n</version>
>    <scope>test</scope>
> </dependency>
>
> I generated some test data and called CurveFitter from main:
>
> public static void main(String[] args) {
> double[] xData = {0.0, 1.0, 2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,  9.0,
> 10.0};
> double[] yData = {2.0, 5.0, 8.0, 11.0, 14.0, 17.0, 20.0, 23.0, 26.0, 29.0,
> 32.0}; // linear
> double[] zData = {0.0, 2.0, 16.0, 54.0, 128.0, 250.0, 432.0, 686.0,
> 1024.0, 1458.0, 2000.0};
> System.out.println("\nLinear Test:");
> fitMyData(xData, yData);
> System.out.println("\nPower (linear regression) Test:");
> fitMyData(xData, zData);
> }
>
> public static void fitMyData(double[] xData, double[] yData) {
> CurveFitter curveFitter = new CurveFitter(xData, yData);
> for (int functionType : CurveFitter.sortedTypes) {
> if ( functionType != POLY3 && functionType != POLY4 && functionType !=
> POLY5 &&
> functionType != POLY6 && functionType != POLY7 && functionType != POLY8
> &&
> functionType != EXPONENTIAL && functionType != EXP_REGRESSION &&
> functionType != EXP_WITH_OFFSET && functionType != EXP_RECOVERY &&
> functionType != EXP_RECOVERY_NOOFFSET && functionType != LOG &&
> functionType != LOG2 &&
> functionType != GAUSSIAN && functionType != GAUSSIAN_NOOFFSET &&
> functionType != ERF &&
> functionType != RODBARD && functionType != RODBARD2 && functionType !=
> INV_RODBARD &&
> functionType != GAMMA_VARIATE && functionType != CHAPMAN) {
> System.out.print("\n\n " + functionType + " Function Type: " +
> CurveFitter.fitList[functionType] + " ");
> curveFitter.doFit(functionType);
> System.out.print(curveFitter.getResultString());
> }
> }
> }
>
> The results are very nice. E.g.:
>
> Linear Test:
>
> 0 Function Type: Straight Line
> Formula: y = a+bx
> Status: Success
> Number of iterations: 1
> Time: 0 ms
> Sum of residuals squared: 1.53560E-11
> Standard deviation: 0.00000E0
> R^2: 1.00000
> Parameters:
> a = 2.00000
> b = 3.00000
>
> <snip>
>
> Power (linear regression) Test:
> 16 Function Type: Power (linear regression)
> Formula: y = a*x^b
> Status: Success
> Number of iterations: 1
> Time: 0 ms
> Sum of residuals squared: 1.14026E-12
> Standard deviation: 2.46117E-13
> R^2: 1.00000
> Parameters:
> a = 2.00000
> b = 3.00000
>
> However, you can see my problem:  only four of the fit functions work; the
> rest of them throw a ava.lang.ArrayIndexOutOfBoundsException.  For example:
>
> Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
> at
> ij.measure.CurveFitter.modifyInitialParamsAndVariations(CurveFitter.java:891)
> at ij.measure.CurveFitter.doFit(CurveFitter.java:204)
> at ij.measure.CurveFitter.doFit(CurveFitter.java:169)
> at myproject.MyTest.fitMyData(MyTest.java:85)
>
> I looked at the source code, and I can't figure out what
> modifyInitialParamsAndVariations is trying to do.
>
> What am I doing wrong?

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Calling CurveFitter from Java; only 4 fit functions work

Tihamer
Thanks for the quick reply, Wayne.

Executive Summary:  I can't get a copy of the 1.52o38 jar file.

You wrote:
     >The following JavaScript version of your program should work better.

As far as I can tell, your JavaScript is pretty much identical to the Java I
must use. In psudocode:
1. Create a new CurveFitter with the x and y data.
2. Call doFit().
3. Print the results.

     >It requires the latest ImageJ daily build (1.52o38),

Unfortunately, the maven repo at
https://mvnrepository.com/artifact/net.imagej/ij only goes up to 1.52n. Do
you have any idea when that will get updated?  Do you push to it every once
in a while, or do you depend on them to pull?

I found the latest source code (version 1.52o40) at
https://github.com/imagej/imagej1/blob/c56624301df300ae7e30c26ad9c71ff9025eae46/ij/measure/CurveFitter.java 
So I tried to download the entire ImageJ 1.x repository from
https://github.com/imagej/imagej1/tree/c56624301df300ae7e30c26ad9c71ff9025eae46
but it's a non-maven project that I couldn't pull into Eclipse to generate
my own jar. I noticed the build.xml file. Um... oh, yeah, ant.  I remember
using ant about a decade or two ago, but it would take me a long time to get
back up to speed.  :-(

So I tried getting ImageJA (the maven version of ImageJ), but that only goes
up to version 1.52n.  :-(

Finally, I tried grabbing just your new CurveFitter.java, but it broke with
the same array Index Out of Bounds exception.  :-(  Obviously, there are
more dependencies here--I would probably need to grab all the files manually
to make sure I have to entire fix for the Array Out of Bounds problem.  :-(

     > which fixes a CurveFitter.getResultString() bug that caused it to
fail when there was a fitting error.

The 1.52n code is breaking during the doFit() step, not during the output
printing step, though I do see how you improved CurveFitter.getResultString.

     > Note that you have to construct a new CurveFitter for each fit.

Yes, I did that. Does it look like I didn't?

I hope you can create a 1.52o38 (or later) jar file for the maven repo, or
update ImageJA sometime soon.

Thanks again for your help so far.






--
Sent from: http://imagej.1557.x6.nabble.com/

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Calling CurveFitter from Java; only 4 fit functions work

Gabriel Landini
On Monday, 22 April 2019 17:13:36 BST you wrote:
> Thanks for the quick reply, Wayne.
>
> Executive Summary:  I can't get a copy of the 1.52o38 jar file.

You can get the latest ij,jar through IJ's help menu: Update ImageJ...>daily
build

Cheers

Gabriel

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Calling CurveFitter from Java; only 4 fit functions work

Wayne Rasband-2
In reply to this post by Tihamer
> On Apr 22, 2019, at 12:13 PM, Tihamer <[hidden email]> wrote:
>
> Thanks for the quick reply, Wayne.
>
> Executive Summary:  I can't get a copy of the 1.52o38 jar file.

The latest daily build (1.52o42) has a better JavaScript curve fitting example (included below) that you can access using the Help>Examples>JavaScript>Curve Fitting command. It does all 25 built in curve fits, plots them and adds the plots to a stack. To upgrade, use the Help>Update ImageJ command and select “daily build” from the drop down menu. To get a maven version, you will need to wait for the release of ImageJ 1.52o (due in a few days) and then wait for Fiji to pick it up.

-wayne

  xpoints = [0, 1, 2, 3, 4, 5];
  ypoints = [0, 0.9, 4.5, 8, 18, 24];
  stack = new ImageStack();
  for (fit in CurveFitter.fitList) {
     cf = new CurveFitter(xpoints, ypoints);
     cf.doFit(fit);
     label = cf.getName()+"["+fit+"]";
     plot = cf.getPlot();
     stack.addSlice(label, plot.getProcessor());
  }
  new ImagePlus("Curve Fits", stack).show();


> You wrote:
>> The following JavaScript version of your program should work better.
>
> As far as I can tell, your JavaScript is pretty much identical to the Java I
> must use. In psudocode:
> 1. Create a new CurveFitter with the x and y data.
> 2. Call doFit().
> 3. Print the results.
>
>> It requires the latest ImageJ daily build (1.52o38),
>
> Unfortunately, the maven repo at
> https://mvnrepository.com/artifact/net.imagej/ij only goes up to 1.52n. Do
> you have any idea when that will get updated?  Do you push to it every once
> in a while, or do you depend on them to pull?
>
> I found the latest source code (version 1.52o40) at
> https://github.com/imagej/imagej1/blob/c56624301df300ae7e30c26ad9c71ff9025eae46/ij/measure/CurveFitter.java 
> So I tried to download the entire ImageJ 1.x repository from
> https://github.com/imagej/imagej1/tree/c56624301df300ae7e30c26ad9c71ff9025eae46
> but it's a non-maven project that I couldn't pull into Eclipse to generate
> my own jar. I noticed the build.xml file. Um... oh, yeah, ant.  I remember
> using ant about a decade or two ago, but it would take me a long time to get
> back up to speed.  :-(
>
> So I tried getting ImageJA (the maven version of ImageJ), but that only goes
> up to version 1.52n.  :-(
>
> Finally, I tried grabbing just your new CurveFitter.java, but it broke with
> the same array Index Out of Bounds exception.  :-(  Obviously, there are
> more dependencies here--I would probably need to grab all the files manually
> to make sure I have to entire fix for the Array Out of Bounds problem.  :-(
>
>> which fixes a CurveFitter.getResultString() bug that caused it to
> fail when there was a fitting error.
>
> The 1.52n code is breaking during the doFit() step, not during the output
> printing step, though I do see how you improved CurveFitter.getResultString.
>
>> Note that you have to construct a new CurveFitter for each fit.
>
> Yes, I did that. Does it look like I didn't?
>
> I hope you can create a 1.52o38 (or later) jar file for the maven repo, or
> update ImageJA sometime soon.
>
> Thanks again for your help so far.
>
>
>
>
>
>
> --
> Sent from: http://imagej.1557.x6.nabble.com/
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Calling CurveFitter from Java; only 4 fit functions work

Curtis Rueden
In reply to this post by Tihamer
Hi all,

> The latest daily build (1.52o42) has a better JavaScript curve fitting
> example

Thanks Wayne!

> To get a maven version, you will need to wait for the release of
> ImageJ 1.52o (due in a few days) and then wait for Fiji to pick it up.

I just want to clarify that the net.imagej:ij artifacts are not
Fiji-specific. The mechanism by which the Maven artifacts are produced is
described here: https://imagej.net/ImageJA. The deployment of the Maven
artifact is a separate (earlier) step from the upload of the artifact to
the ImageJ update site (https://update.imagej.net/)—which is also not
Fiji-specific. But it is true that the Fiji distribution of ImageJ is built
on top of that core update site, so Fiji will not a release of ImageJ 1.x
until its Maven artifact is deployed to maven.imagej.net and then uploaded
to update.imagej.net.

Regards,
Curtis

--
Curtis Rueden
LOCI software architect - https://loci.wisc.edu/software
ImageJ2 lead, Fiji maintainer - https://imagej.net/User:Rueden
Have you tried the Image.sc Forum? https://forum.image.sc/



On Mon, Apr 22, 2019 at 1:38 PM Wayne Rasband <[hidden email]> wrote:

> > On Apr 22, 2019, at 12:13 PM, Tihamer <[hidden email]>
> wrote:
> >
> > Thanks for the quick reply, Wayne.
> >
> > Executive Summary:  I can't get a copy of the 1.52o38 jar file.
>
> The latest daily build (1.52o42) has a better JavaScript curve fitting
> example (included below) that you can access using the
> Help>Examples>JavaScript>Curve Fitting command. It does all 25 built in
> curve fits, plots them and adds the plots to a stack. To upgrade, use the
> Help>Update ImageJ command and select “daily build” from the drop down
> menu. To get a maven version, you will need to wait for the release of
> ImageJ 1.52o (due in a few days) and then wait for Fiji to pick it up.
>
> -wayne
>
>   xpoints = [0, 1, 2, 3, 4, 5];
>   ypoints = [0, 0.9, 4.5, 8, 18, 24];
>   stack = new ImageStack();
>   for (fit in CurveFitter.fitList) {
>      cf = new CurveFitter(xpoints, ypoints);
>      cf.doFit(fit);
>      label = cf.getName()+"["+fit+"]";
>      plot = cf.getPlot();
>      stack.addSlice(label, plot.getProcessor());
>   }
>   new ImagePlus("Curve Fits", stack).show();
>
>
> > You wrote:
> >> The following JavaScript version of your program should work better.
> >
> > As far as I can tell, your JavaScript is pretty much identical to the
> Java I
> > must use. In psudocode:
> > 1. Create a new CurveFitter with the x and y data.
> > 2. Call doFit().
> > 3. Print the results.
> >
> >> It requires the latest ImageJ daily build (1.52o38),
> >
> > Unfortunately, the maven repo at
> > https://mvnrepository.com/artifact/net.imagej/ij only goes up to 1.52n.
> Do
> > you have any idea when that will get updated?  Do you push to it every
> once
> > in a while, or do you depend on them to pull?
> >
> > I found the latest source code (version 1.52o40) at
> >
> https://github.com/imagej/imagej1/blob/c56624301df300ae7e30c26ad9c71ff9025eae46/ij/measure/CurveFitter.java
> > So I tried to download the entire ImageJ 1.x repository from
> >
> https://github.com/imagej/imagej1/tree/c56624301df300ae7e30c26ad9c71ff9025eae46
> > but it's a non-maven project that I couldn't pull into Eclipse to
> generate
> > my own jar. I noticed the build.xml file. Um... oh, yeah, ant.  I
> remember
> > using ant about a decade or two ago, but it would take me a long time to
> get
> > back up to speed.  :-(
> >
> > So I tried getting ImageJA (the maven version of ImageJ), but that only
> goes
> > up to version 1.52n.  :-(
> >
> > Finally, I tried grabbing just your new CurveFitter.java, but it broke
> with
> > the same array Index Out of Bounds exception.  :-(  Obviously, there are
> > more dependencies here--I would probably need to grab all the files
> manually
> > to make sure I have to entire fix for the Array Out of Bounds problem.
> :-(
> >
> >> which fixes a CurveFitter.getResultString() bug that caused it to
> > fail when there was a fitting error.
> >
> > The 1.52n code is breaking during the doFit() step, not during the output
> > printing step, though I do see how you improved
> CurveFitter.getResultString.
> >
> >> Note that you have to construct a new CurveFitter for each fit.
> >
> > Yes, I did that. Does it look like I didn't?
> >
> > I hope you can create a 1.52o38 (or later) jar file for the maven repo,
> or
> > update ImageJA sometime soon.
> >
> > Thanks again for your help so far.
> >
> >
> >
> >
> >
> >
> > --
> > Sent from: http://imagej.1557.x6.nabble.com/
> >
> > --
> > ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Calling CurveFitter from Java; only 4 fit functions work

Tihamer
In reply to this post by Wayne Rasband-2
Thanks for the quick reply, Wayne.

Executive Summary:  I can't get a copy of the 1.52o38 jar file.

You wrote:
     >The following JavaScript version of your program should work better.

As far as I can tell, your JavaScript is pretty much identical to the Java I
must use. In pseudocode:
1. Create a new CurveFitter with the x and y data.
2. Call doFit().
3. Print the results.

     >It requires the latest ImageJ daily build (1.52o38),

Unfortunately, the maven repo at
https://mvnrepository.com/artifact/net.imagej/ij only goes up to 1.52n. Do
you have any idea when that will get updated?  Do you push to it every once
in a while, or do you depend on them to pull?

I found the latest source code (version 1.52o40) at
https://github.com/imagej/imagej1/blob/c56624301df300ae7e30c26ad9c71ff9025eae46/ij/measure/CurveFitter.java 
So I tried to download the entire ImageJ 1.x repository from
https://github.com/imagej/imagej1/tree/c56624301df300ae7e30c26ad9c71ff9025eae46
but it's a non-maven project that I couldn't pull into Eclipse to generate
my own jar. I noticed the build.xml file. Um... oh, yeah, ant.  I remember
using ant about a decade or two ago, but it would take me a long time to get
back up to speed.  :-(

So I tried getting ImageJA (the maven version of ImageJ), but that only goes
up to version 1.52n.  :-(

Finally, I tried grabbing just your new CurveFitter.java, but it broke with
the same array Index Out of Bounds exception.  :-(  Obviously, there are
more dependencies here--I would probably need to grab all the files manually
to make sure I have to entire fix for the Array Out of Bounds problem.  :-(

     > which fixes a CurveFitter.getResultString() bug that caused it to
fail when there was a fitting error.

The 1.52n code is breaking during the doFit() step, not during the output
printing step, though I do see how you improved CurveFitter.getResultString.

     > Note that you have to construct a new CurveFitter for each fit.

Yes, I did that. Does it look like I didn't?

I hope you can create a 1.52o38 (or later) jar file for the maven repo, or
update ImageJA sometime soon.

Thanks again for your help so far.






--
Sent from: http://imagej.1557.x6.nabble.com/

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html