It’s very nice to have the live plot of an image slice based upon the selection defined by the current ROI.
I was hoping to use ImageJ to help some high school students process spectra derived from images, but when the image gets a wavelength calibration (unfortunately only linear - one needs a polynomial scale calibration for general purposes), the calibration doesn’t show up on the plot. I was going to sub-class Plot and PlotObject and … in order to get the required behavior, but the classes use private rather than protected variables, which makes life much harder - essentially, I’d have to copy the required code entirely. Any ideas? Please use protected variables unless private ones are ABSOLUTELY NECESSARY! Rick ------------------------------------------------------------------------------------------------ Dr. Frederic V. Hessman [hidden email] Institut für Astrophysik Tel. +49-551-39-5052 Friedrich-Hund-Platz 1 Fax +49-551-39-5043 37077 Goettingen Room F04-133 http://www.Astro.physik.Uni-Goettingen.de/~hessman ------------------------------------------------------------------------------------------------- MONET: a MOnitoring NEtwork of Telescopes http://monet.Uni-Goettingen.de ------------------------------------------------------------------------------------------------- -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Rick,
well, I must admit that I am the culprit for the protected variables and classes in the ImageJ Plot class. The reason for not making them public is that as soon as something is public, it is carved in stone; in other words, it must not be changed to ensure compatibility. At the moment, I am still working on the Plot class to enable saving of the plots including the data, so one can at a later time zoom into the plot or list values. So there might be still changes ahead... Are you plotting spectra? Then I guess the problem lies not in the Plot class but in the profile plot, because it always starts the x axis at a distance of zero, instead of the actual x value (wavelength) according to the image calibration. So you would need a custom Profiler class. At least ImageJ 1.x has only linear calibration of the x and y coordinates; For ImageJ 2.x I think that nonlinear coordinates had been discussed, but I am not aware that they would have been implemented. 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. Or maybe I misunderstood your question? Michael ________________________________________________________________ On 09/08/2017 17:46, Frederic V. Hessman wrote: > It’s very nice to have the live plot of an image slice based upon the selection defined by the current ROI. > > I was hoping to use ImageJ to help some high school students process spectra derived from images, but when the image gets a wavelength calibration (unfortunately only linear - one needs a polynomial scale calibration for general purposes), the calibration doesn’t show up on the plot. > > I was going to sub-class Plot and PlotObject and … in order to get the required behavior, but the classes use private rather than protected variables, which makes life much harder - essentially, I’d have to copy the required code entirely. > > Any ideas? > > Please use protected variables unless private ones are ABSOLUTELY NECESSARY! > > Rick > > ------------------------------------------------------------------------------------------------ > Dr. Frederic V. Hessman [hidden email] > Institut für Astrophysik Tel. +49-551-39-5052 > Friedrich-Hund-Platz 1 Fax +49-551-39-5043 > 37077 Goettingen Room F04-133 > http://www.Astro.physik.Uni-Goettingen.de/~hessman > ------------------------------------------------------------------------------------------------- -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Rick,
> 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. > 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. Regards, Curtis [1] https://github.com/imglib/imglib2-realtransform -- Curtis Rueden LOCI software architect - https://loci.wisc.edu/software ImageJ2 lead, Fiji maintainer - https://imagej.net/User:Rueden Did you know ImageJ has a forum? http://forum.imagej.net/ On Wed, Aug 9, 2017 at 12:48 PM, Michael Schmid <[hidden email]> wrote: > Hi Rick, > > well, I must admit that I am the culprit for the protected variables and > classes in the ImageJ Plot class. > The reason for not making them public is that as soon as something is > public, it is carved in stone; in other words, it must not be changed to > ensure compatibility. > At the moment, I am still working on the Plot class to enable saving of > the plots including the data, so one can at a later time zoom into the plot > or list values. So there might be still changes ahead... > > Are you plotting spectra? Then I guess the problem lies not in the Plot > class but in the profile plot, because it always starts the x axis at a > distance of zero, instead of the actual x value (wavelength) according to > the image calibration. So you would need a custom Profiler class. > > At least ImageJ 1.x has only linear calibration of the x and y > coordinates; For ImageJ 2.x I think that nonlinear coordinates had been > discussed, but I am not aware that they would have been implemented. > > 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. > > Or maybe I misunderstood your question? > > > Michael > ________________________________________________________________ > > On 09/08/2017 17:46, Frederic V. Hessman wrote: > >> It’s very nice to have the live plot of an image slice based upon the >> selection defined by the current ROI. >> >> I was hoping to use ImageJ to help some high school students process >> spectra derived from images, but when the image gets a wavelength >> calibration (unfortunately only linear - one needs a polynomial scale >> calibration for general purposes), the calibration doesn’t show up on the >> plot. >> >> I was going to sub-class Plot and PlotObject and … in order to get the >> required behavior, but the classes use private rather than protected >> variables, which makes life much harder - essentially, I’d have to copy the >> required code entirely. >> >> Any ideas? >> >> Please use protected variables unless private ones are ABSOLUTELY >> NECESSARY! >> >> Rick >> >> ------------------------------------------------------------ >> ------------------------------------ >> Dr. Frederic V. Hessman [hidden email] >> Institut für Astrophysik Tel. +49-551-39-5052 >> Friedrich-Hund-Platz 1 Fax +49-551-39-5043 >> 37077 Goettingen Room F04-133 >> http://www.Astro.physik.Uni-Goettingen.de/~hessman >> ------------------------------------------------------------ >> ------------------------------------- >> > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
> 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 |
In reply to this post by Frederic V. Hessman
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 |
Hi Frederic & everyone,
just to make sure: For the standard profile plot (CTRL-k), I think we should have the x axis always start at zero, independent of whether the image is scaled or not and also independent of whether the line or roi is horizontal. E.g. for line profiles in scanning probe microscopies (STM, AFM, ...), one usually wants the x axis to start at zero. It might be nice to have an additional ImageJ command like 'Plot x-calibrated profile' that only works with horizontal (and maybe vertical) lines and rectangular rois, and takes the x calibration (or y calibration for vertical lines and alt-rectangles) of the image (it could be some xtra code in the Profiler and ProfilePlot, with an additional 'arg' for the Profiler and an addiational three-argument constructor for the ProfilePlot). For the calibration based on two points (for the kids), a simple macro would be sufficient. It could have a dialog for the two wavelengths (if required; maybe one can always use H-alpha and H-beta?) and then use the Image>Adjust>Coordinates (available since ImageJ 1.5.g; update ImageJ if necessary). If your spectra are as wide as the image, then simply enlarge the roi rectangle to full width and call your CalibratedProfilePlot. Otherwise (for objective-prism type images with many spectra in different places), you probably know how wide the spectra are (based on the response of the CCD), so after the calibration step you can still expand the size of the rectangle to the width of the full spectrum. -- I don't see why the wavelength calibration of the spectrograph should depend on what you finally want to do with the data. When measuring radial velocities via correlation of the spectra, I think that you just have to use spectra as function of log(wavelength) instead of wavelength as an input (interpolate intensity values for equidistant log(wavelength) points). ImageJ can interpolate images using linear or cubic interpolation, and it can also do spline interpolation of arrays; this might be also useful for rescaling the x axis to log(wavelength). Best, Michael ________________________________________________________________ On 10/08/2017 15:53, Frederic V. Hessman wrote: > 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 > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Frederic V. Hessman
> > On Apr 28, 2017, at 3:04 PM, Bill Christens-Barry <[log in to unmask]
> > wrote: > > > > Hi, > > > > I've downloaded and am exploring a recent version of ImageJ (1.51m32) that includes the Java 1.8 JRE (1.8.0_101) on a Mac with 16 GB RAM and running OS 10.11.6 (Sierra). > > > > I've found that the labels on the bottom row of buttons in the "Threshold" window are too big for the buttons. As a result, those buttons show the oversize and thus unreadable text as "...". I've tried using the Edit>Options>Fonts... menu item to reduce the size of this text, but this evidently has no effect. When using this ImageJ version with Java 1.6 things behave properly. > > > > How should I try to resolve this issue? I've thought to try upgrading Java to v1.8 system wide rather than using the JRE that accompanied the ImageJ download; would that be a reasonable next step? > > I do not see this problem on my Mac with ImageJ 1.51m32, Java 1.8.0_101 and macOS 10.12.3 Sierra. > > -wayne > A user told me: This it not a problem on a clean install of ImageJ. However, if I install and run “Action bar” (http://imagejdocu.tudor.lu/doku.php?id=plugin:utilities:action_bar:start) the Java 8 version of ImageJ will become “Windows-like”. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |