Revisit the way in which special pixels are being handled by the fx program
While working on Mantis #1063, an issue was brought up with how all special pixels are being handled by fx. We need to revisit this topic so that all users can weigh in on how best to handle the special pixels.
Steps to reproduce:
Janet networked with a number of folks about this. I am embedding email responses in the 'notes' for background information on this issue.
#1 Updated by Tammy Becker over 5 years ago
Email from Jeff Anderson:
Here's my thoughts ... Let's look at this case first
Basically creating a negative of the image. If we left the special
pixels alone when displayed in qview, hrs/lrs would appear bright
surrounded by dark pixels (previously bright non-special pixels before
negation). Similarly lrs/lis would appear dark surroundeded by bright
pixels (previously dark pixels before negation). That is, think about a
crater rim that is normal to the sun incidence angle. It might be
very, very bright and have some HIS pixels on the crater slope
surrounded by bright valid pixels (clementine certainly had this occur
alot). We would be negating the bright pixels but not the HIS pixels.
When displayed the HIS will show as a few white pixels surrounded by
Now consider these cases
Here's a few examples of what we could have
With multiple files which special pixel takes precedence? It probably
shouldn't always be the first file. It may actually be equation
dependent. With infinite equations it become very difficult.
What I believe was coded originally in ISIS3 was to convert LRS/LIS to
IEEE -infinity and HRS/HIS to IEEE infinity and NULL to IEEE nan (not a
number). Then apply the equations. The IEEE standards take care of
everything nicely when adding, multiplying, etc. Anything that has
nan in the equation has an output of nan. Likewise equation=neg(f1) an
infinity becomes a -infinity which eliminates the problems given in the
first case. Also, equation=3.5/0.0 become infinity.
Before writing the pixels we should convert nan back to NULL, +infinity
to HRS and -infinity to LRS. In this case we sacrifice the HIS and LIS
pixels. I believe this is how the ISIS3 code originally worked. Not
sure when it got lost but I can't find any special pixel handling in the
We probably should get together and talk about it too.
#2 Updated by Tammy Becker over 5 years ago
Email from Randy:
Here's my 2c worth (which does not entirely agree with Jeff's suggestions.
For one input, NULL remains NULL no matter what you do to the file.
Likewise HIS and LIS should remain unchanged. They record the historical
fact that the pixel got boffed in the camera so they should not be
changed by processing. You can't unsaturate a saturated pixel, nor should
you be misleading about which way it was saturated (even if the image
looks better in the display when you do). For HRS and LRS it is
tempting to swap them if the operation "negates" the image. My concern
is whether we can adequately predict out of the many possible equations
which ones will do this. For example, you'd have to treat polynomials
separately and analyze the coefficients of any given polynomial to see if
the extreme values are inverted or not. Plus the answer would be
if HRS is interpreted as +infinity or if it's intepreted as just slightly
than the highest valid value. What happens if the function is (say) a
polynomial plus a logarithm?
I don't think we want to get into the position of having to figure all
this out, so I recommend HRS and LRS remain unchanged.
For multiple inputs I think the rules can be quite simple:
all input values are valid -> valid value, or HRS/LRS if the function
exceeds the ORANGE
only one type of special pixel value among the input files (whether it's
one file or multiple files) -> propagate that value
different types of special pixel values among the inputs -> output is NULL
I'd also like to suggest that a better way to address Jeff's issue of
how the images display would be to change the display colors for
the special pixel values. This can be done (with several clicks) in the
current qview interface, but maybe the special pixel values palette
should have a button for "swap high/low saturation colors". I could
see this being really useful in other situations. Sometimes you WANT
to see where the saturated pixels are, and other times you want them
to blend in.
#3 Updated by Tammy Becker over 5 years ago
Email from Tammy:
....it's obviously not straight-forward when multiple input special pixels values are involved. Giving user options on who is propagated is a very good idea; a precedence similarly set by mapmos; Parameter flags invites the user to consider the issue and also makes it more intuitive. But, it is also important to have reasonable defaults.
In considering defaults, a good start might be to go by the historical definition of special pixel values, in-coming pixels that are HIS, LIS, and Nulls should be retained over HRS and LRS....the logic being that these are identified at ingestion and not introduced by Isis processing (Nulls are a special case, but the option to not propagate would take care of it)...Unfortunately, HIS and LIS are non-existent in 8bit data making them rare.
Going thru Jeff's examples using defaults based on a pre-defined hierarchy:
Equation=LRS+HIS+LIS+5.0 (default should be one of the HIS or LIS...would it be crazy to see what neighboring valid pixels lean toward? close to Min=LIS or close to Max=HIS?)
Equation=LRS+NULL+HIS+NULL (default = HIS)
Equation=NULL/HRS (Not sure, either one could have been introduced in Isis at some point...maybe NULL, because it has a higher probability of being an original value? unless it's 8bit :-/)
Whatever is decided should definitely be explained in the fx documentation.
#4 Updated by Jeff Anderson over 5 years ago
Found this thread and added an email I sent back to Janet.
I did some testing and confirmed that the code is working as I remembered. It was fairly simple ... just use the input cube from the $ISISROOT/src/base/apps/fx/tsts/default/input directory. I ran with the equation=neg(f1). HRS became LRS and vice versa. HIS became HRS and LIS became HRS.
I also confirmed that equa="max(0.01,f1)" produces bad results when f1 is NULL. That is it returns 0.01. When I flip the equation to equa="max(f1,0.01)" it works for f1=NULL. However it fails when f1=LRS. So there is some problems with the min and max algorithms.
I really want to make sure I am being heard as a user too and not just as a programmer I use fx a lot. If I lose the capabilities of converting to infinity/-infinity/nan I would be frustrated too. That is, I don't want to lose the ability to flip HRS to LRS and vice versa. I think we can get a win/win situation by continuing to process with the conversion of special pixels to IEEE. Then give the option to post-process each line to replace with the original special pixels from a user selected file (f1,f2,f3, etc).
I know dealing with all the special pixel situations with variable equations is a sticky situation. When I think of equation=f1/f2 then the units are really changing. F1 and F2 may be in I/F and the original instrument units no longer exist after the ratio. What I mean is that when f1 or f2 is a HIS or LIS those are units that the instrument collected. I don't think a ratio should preserve those units and outputs should be HRS or LRS.
#5 Updated by Jeff Anderson over 5 years ago
Another note from Jeff
I will add that fx is extremely fast because it uses IEEE floating point hardware to do the right thing.
log(-1) = nan
log(inf) = inf
3/0 = inf
-3/0 = -inf
This prevents us from having to do a bunch of special pixels tests within complicated equations. It just works in the hardware.
#6 Updated by Tammy Becker over 5 years ago
I respectfully disagree with how fx is changing the special pixel values.
Incoming special pixel values should be preserved (at least as an option)..for instance, when a neg(f1) is ran, HRS should stay HRS; HIS should stay HIS, LIS should stay LIS...etc. ratio shouldn't be remapping the incoming special pixels either...HRS, LRS, and NULL, should be introduced when a 'valid pixel' has been modified and exceeds an output range...The instrument collected values should not be changed by default.
There are specific applications that will change the special pixel values and remap them....'specpix' and 'stretch'...there can be a pre-processing step before 'ratios', 'fx', etc. otherwise a flag to preserve or not is definately needed.