Re: Calibrated plots

Posted by Frederic V. Hessman on
URL: http://imagej.273.s1.nabble.com/Calibrated-plots-tp5019184p5019192.html

Getting a calibrated plot was indeed easy - vielen Dank Michael!  

Here’s the getPlot() method for CalibratedProfilePlot, my daughter of ProfilePlot :

        ...
        public Plot getPlot () {
                if (profile == null;
                        return null;
                int n = profile.length;
                Calibration cal = imp.getCalibration ();
                if (xValues==null) {
                        xValues = new float[n];
                        for (int i=0; i<n; i++) {
                                float x = (float)(i)*xInc;
                                if (cal.scaled()) // NEED TEST: IF ROI TILTED, i != x !!
                                        x = (float)cal.getX ((double)i); // USES i AND X-SCALE ONLY!!!!
                                xValues[i] = x; // SAVE ONE OR THE OTHER
                        }
                }
                return super.getPlot ();
        }
        …

(Wayne: for the next ImageJ version simply add/replace the commented lines above!).  Note that this preserves the x-scaling no matter how the ROI is tilted: this is what you want if the original x- and y-axis are really independent (e.g. on slit spectra/sonograms, x should be wavelength or frequency, y is spatial/temporal).  If the axis are not independent, then the a tilted ROI might make them more independent but the connection becomes terribly complicated: this is where the image data should have been separately transformed (e.g. by morphing the images so that the two different quantities become independent).  Thus, using the x-scale only assuming that the horizontal axis is primary makes sense.  Of course, then vertically summed data should be using y = (float)cal.getY ((double)j) and a yInc stepsize, but….

For my CalibratedProfilePlot, I had to do a little bit of getting around private variables that were absolutely needed (ahem!), but fortunately they weren’t too numerous or onerous.

I’m still missing a more convenient wavelength calibration possibility (for the kids) than simply using my Figure_Calibration plugin :

        1. Draw a rectangular ROI so that the left and right edges are at known wavelengths (e.g. two emission lines)
        2. Run Figure_Calibration and enter the two wavelengths, e.g. “400” to “700” nm.
        2. If you interested in the y-scaling, you’ll have to consider what extreme y-values you might want to use (e.g. 0 at the top and the height at the bottom?).
        3. A calibrated “spectral" plot appears that behaves like you’d expect using the X,Y coordinates derived from the ROI, whatever that means (depends upon your ROI) and where X in the plot corresponds to the original calibrated x-axis, NOT to the length along the ROI.

I need the ability to read dispersion information directly from FITS metadata.  This would be interesting if I had a SpectralCalibration substitution for the generic Calibration would make it possible to have non-linear dispersion relations; spectrographs with prisms and grisms need something like model=CUBIC

        wave(x) = a+b*x+c*x**2+d*x**3

(a cubic is probably enough for refractive optics and can be analytically reversed to yield x(wave)) while getting velocities by cross-correlating spectra requires model=LNLINEAR

        wave(x) = exp(A+B*x)

(since dv/c  = dwave/wave = B dx). This is the kind of stuff that needs to be supported by ImageJ 2.* but which a set of plugins for 1.* could provide.

I’ll make the complete package available when it’s ready.

Rick


> On 10 Aug 2017, at 07:34, Frederic V. Hessman <[hidden email]> wrote:
>
>> On 9 Aug 2017, at 20:10, Curtis Rueden <[hidden email]> wrote:
>>
>>> Please use protected variables unless private ones are ABSOLUTELY
>>> NECESSARY!
>>
>> I think that protected fields should never (or almost never) be used. For a
>> rationale, see:
>> http://imagej.net/Coding_style#Private_over_protected_fields_and_methods
>>
>> As Michael says, making fields non-private locks them in stone forever. You
>> also cannot intercept accesses or mutations, unlike getters and setters
>> where the behavior can be customized via subclassing.
>
> Depends upon which stone you’re talking about: in this case, it locked the object in stone, making it effectively impossible to subclass it meaningfully.  Yes, there are important internal variables that need to be privately protected, but variables that are simply class working variables that a daughter class necessarily has to access shouldn’t be made private - one has to consider not just the immediate class and its public access but also potential subclasses.
>
> Alternatively, the class has to provide set/get access to all (and I mean ALL) of the needed variables.  Sounds like much more work than simply thinking unless your IDE does it for you.
>
>>> For ImageJ 2.x I think that nonlinear coordinates had been discussed,
>>> but I am not aware that they would have been implemented.
>>
>> ImgLib2 has the imglib2-realtransform library [1] which offers coordinate
>> system transformations in real space, including arbitrary transforms which
>> can be nonlinear. This component has not reached 1.0.0 yet, and AFAIK there
>> are not yet many good examples of using it. However, as discussed years ago
>> when ImageJ2 first began, we do plan to continue working on this. Many of
>> the pieces are now in place, and the framework/infrastructure to support
>> registration algorithms etc. will continue to improve.
>
> One of these days…. Sorry I haven’t had time to help.
>
>> From: Michael Schmid <[hidden email]>
>> Subject: Re: Calibrated plots
>> Date: 9 August 2017 at 19:48:35 CEST
>> To: [hidden email]
>> Reply-To: [hidden email]
>>
>> What you could do is the following:
>>
>> (1) Create a plugin that calibrates a spectrum from the wavelengths of a few known points with a polynomial (CurveFitter class). Save the coefficients in the image properties.
>> (You could also save the coefficient in a file or the ImageJ prefs, to apply the calibration to other spectra taken with the same setup).
>>
>> (2) Create a plugin like the ij.plugin.Profiler that reads the coefficients and uses them to create the x values. You can get a live plot by implementing the PlotMaker interface. This could be a rather short and simple plugin.
>> Maybe you can also create a profile for the whole spectrum; then you don't need the 'live' function but you can simply zoom into the plot.
>
>
> Great idea - I’ll look into it!
>
> Rick
>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

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