Open jlaura opened 3 years ago
Hmmmmmmmmm. First off, I'm not 100% sure, but I have opinions (you know, as always).
I will say that we uncovered some bugs working together with the UofA in their resolve_jitter program in 2012. We worked on a conversion of their MATLAB version of resolve_jitter to C++ in order to free their processing nodes from needing MATLAB licenses and to speed up processing. At the time, they did not have the capacity to investigate these issues, critically evaluate our changes, or even change over to this code, and they continue to use the MATLAB version to this day, and incur the costs of licensing and extra processing time (which always made me sad).
Oleg's C++ version (which has not been publicly released) was much kinder and had #if
statements that allowed you to compile the code with the bugs faithfully reproduced (bless him) or with the fixes enabled. I didn't bother with that nonsense in the Python version of resolve_jitter, I just fixed the damn bugs.
Anyway, resolve_jitter is what produces the files that are fed to hijitter
to actually do the ephemeris corrections, and so some minor changes there could be the source of the differences you're seeing.
I suppose I could write the bugs into the Python version (please don't make me), or I could run hiproc
using the "with bugs" version of Oleg's resolve_jitter on your image (may take some time to get to), and then you can compare the results maybe, and see if that's the difference?
I guess it is also possible that the SPICE data that were available when the U of A created this dejittered product have gotten a reconstruction since then, and this is entirely due to different SPICE kernels used? That one seems like a long shot. Not sure if those are carried along with the dejittered product you have or not so you could compare?
I wonder if this is not, in some way, related that this ISIS issue then: https://github.com/USGS-Astrogeology/ISIS3/issues/3257. The offsets in that issue look like they are along track and of a lesser magnitude, but it would not be surprising if these are somehow related.
I also do not want to reproduce bugs in order to get a matching solution for the sake of matching! I realize too that I do not know when the image I tested against was dejittered, so I do not know what version of the UA pipeline was used. Glad to know a bit more of the lineage, but bummed to see another variable added. 😢
If you have some time this FY, it would be sweet to see if the 'with bugs' in Oleg's version produces output that is identical to the original UA output. If you are able to run it, feel free to just send me a link to the RED NOPROJ mosaic and I can download and run the comparison. No pressure, timeline, or rush getting to that as these offsets are quite small and quite consistent. I am going to proceed with testing these on ingest into Socet.
Thanks for the response and I'll keep you in the loop as I run these end-to-end tests (preempting your unit test style validation - sheesh, users are a pain! 😆).
I suppose it could be related to whatever the mystery is that is causing that issue. However, I hate to just wash my hands of it and say that "there was a change in the Matrix" and this is just where we are now, live with it. I will try and give this observation a run through using the version we have "with bugs" and let you know. Hopefully in the next month.
Of course, let's not forget that this could also be some wonderful new error that I have introduced by attempting to rewrite things.
:+1: One more image to perhaps assist. Here is the diff image (using ISIS's fx
). Left image is the diff, right image is the diff after running another round of processing that is done before ingest into socet.
The noise on the far left of the image is what I was hoping to see over the entire image (assuming the magnitude is low). The fact that we are seeing structure suggests to me that we have a systematic offset between the two results on some of the CCDs. Maybe? - I am not familiar enough with the sensor to do anything more than make a guess.
Hunh. So the Python HiCal program in hiproc contains improvements in noise processing that are currently staged for inclusion in the actual HiRISE pipelines. For this image (if I have it right in my head) that should only contribute an almost negligible downtrack gradient. There are more severe noise cases where new, extra processing kicks in, but it doesn't for this image.
What "structure" are you talking about? Are you talking about being able to see surface features in the left-hand diff, or are you talking about the vertical patterns (which are Channel and CCD joins) in the right-hand diff? And for whichever diff you're worried about, what are the stats? Whats the magnitude of the diff we're talking about here?
@rbeyer Apologies for the delay getting back to you. The structure I am talking about are the surface features. I assumed that the vertical striping was a function of the CCD stitching. That vertical striping is visible in the left hand image two and I think that whatever processing we are doing to prepare for Socet is making that more pronounced in the right image.
Here are the stats for the left image:
Band 1 Block=500x500 Type=Float32, ColorInterp=Undefined
Description = Red
Minimum=-0.269, Maximum=0.154, Mean=-0.010, StdDev=0.002
NoData Value=-3.40282265508890445e+38
Mask Flags:
Metadata:
BANDWIDTH=300.000000
BANDWIDTH_UNIT=NANOMETERS
STATISTICS_MAXIMUM=0.15375693142414
STATISTICS_MEAN=-0.0097139199355598
STATISTICS_MINIMUM=-0.26859384775162
STATISTICS_STDDEV=0.0023013041853695
STATISTICS_VALID_PERCENT=99.09
WAVELENGTH=700.000000
WAVELENGTH_UNIT=NANOMETERS
Okay, so about the diff images: yeah, the vertical striping is from CCD and channel stitching artifacts, welcome to our HiRISE world of trying to make 20 different images "appear" to be just one image. I'm not sure what "additional" processing you're doing to get the right-hand diff, but whatever it is, it appears to be removing the surface feature structures, and while the vertical striping looks "more pronounced" in the right-hand diff it is probably the same, and just shows up better here, because the dynamic range has been collapsed by removal of the surface features, and qview auto-stretches (i.e., they were there, at that magnitude all along).
So I ran this observation through using the "with bugs" version of our C++ version of resolve_jitter
and without, and then diff'ed the RED NOPROJ images, and the diff looks like your right-hand diff, no large image-scale surface features like you're seeing in the left-hand diff. If you zoom into the diff, you can see some small surface texture, but that's to be expected. So that means that the bug-fixes to resolve_jitter
aren't the cause of the big differences you're seeing in the left-hand diff.
Unfortunately, this means that I don't know why the RED NOPROJ that hiproc is producing is so different from the one that you got from the UofA. Admittedly, I have not done a complete verification of all of the software pieces in hiproc against the output of the "living" HiRISE processing pipelines (I've just studied and aped them in Python code). So there is certainly the possibility that there are bugs that I have introduced in my implementation that could be the cause. When you see hiproc hit 1.0, then you'll know I've finished that verification. However, it is likely to take a long time, as even starting it is waiting on upstream changes in Tucson to settle down, and then I have to do a bunch of verification, which isn't as fun, so odds are good it'll get back-burnered.
Assuming that it isn't me (which, you know, it probably is), tracking down the source of the difference is going to be very difficult. We'd have to recapture the state of the HiRISE Team versions of their processing software at the time this cube you have was made, as well as the state of ISIS, and the ISISDATA area. It could be done, but it would be a lot of digital forensics work. That issue you referenced was about hundreds of HiRISE pixels of offset, and we still don't know why that is.
In an attempt to make us feel better about "letting go," the standard deviation of the diff is only 0.002 I/F, which tells us that the brightness variations between these two images are very, very small. Sure, there are outliers, but overall, maybe we can live with this?
Getting back to your original question: why are the reported spacecraft positions different by almost 15 m? That's got a more complicated answer that I don't know the answer to either (surprising, I know), but my guess is that it is related to the surface features we see between the images in your left-hand diff. The fact that we see structure that looks like surface features in the diff means that the surface features in the parent images aren't identically aligned in the two images, and since the NOPROJ images that you're seeing are the result of a dejittering process that is feature-based and outputs a new camera kernel, it is at least "consistent" such that seeing the structure differences in the left-hand diff should correlate with offsets in the spacecraft position. However, I don't know how to investigate that further, but I'm open to suggestions.
You should get an e-mail from NASA's Box service with a link to pull down the "with bugs" version of ESP_018957_2655_RED.NOPROJ.cub shortly.
@rbeyer I spoke with the DTM group here and here is our plan given the challenges in 'ground' truthing this.
ESP_019195_2655
and share the C++ dejittered version? No rush on this if you are able to and completely understand if the timing is bad!I am not 100% sure what the processing in the right image is. Something the DTM group does before ingestion into socet. I can inquire if you like? I am happy to simply let it go too. The post processing isn't something this library should ever worry about!
Thanks for processing through the C++ with bugs. It is a bummer to have the diffs, but at 0.002 I/F that is exceptionally small. The above proposed experiments are to test the livability of the approach. Before I say sure, I want the DTM generation folks to give the :+1: on the resultant DTM. So, tentative yes. I am really sensitive to the challenge here as well since 'truth' is not exactly a stable thing right now.
For the surface structure, I am pretty content to let that live for a bit to see what the resultant DTMs look like. We know that the HiRISE pipeline has reported similar shifts (albeit along track). It could be that the reported offsets are the egregious instances and that smaller offsets like these exist at different processing points. To really understand this, I suspect we would need a bunch of time and time machine.
So - very much appreciate you digging into this! Let me know what you think about the second item above, generating one more with bugs version from the C++ code. And we will go from there with generating a DTM and doing comparison of the results.
I am not 100% sure what the processing in the right image is. Something the DTM group does before ingestion into socet. I can inquire if you like? I am happy to simply let it go too. The post processing isn't something this library should ever worry about!
Nah, I don't care about the details, but the important thing is that after this processing the two versions of this "dejittered" cube are even more similar to one another, which means that "going into SOCET" there isn't much difference. So I will make the bold prediction that the resulting models will also be similar.
I am really sensitive to the challenge here as well since 'truth' is not exactly a stable thing right now.
For the surface structure, I am pretty content to let that live for a bit to see what the resultant DTMs look like. We know that the HiRISE pipeline has reported similar shifts (albeit along track). It could be that the reported offsets are the egregious instances and that smaller offsets like these exist at different processing points. To really understand this, I suspect we would need a bunch of time and time machine.
Yeah, this is a philosophy thing. We have a tendency to assume that something made by unknown other experts was "right" but in truth it could be just as flawed as something we make now.
And yes, short of a time machine, we may not even be able to per-pixel re-create the dejittered image that you have. So that might actually be another kind of test. Figure out how "old" your UofA dejittered cubes are, and if they're a few years old, then ask for a "new" version (maybe after HiRISE gets itself updated to ISIS 4.3 later this fall), and see if the new version is the same or different.
If it is different, then who knows what changed? If it is the same, then I've screwed up something somewhere in hiproc. I'll note that this kind of comparison is the sort of thing that I plan to do to get hiproc to version 1.0 as I mentioned above, I just haven't done it yet. So you could also wait on requesting this, as it kind of falls on my to-do list.
So - very much appreciate you digging into this! Let me know what you think about the second item above, generating one more with bugs version from the C++ code. And we will go from there with generating a DTM and doing comparison of the results.
I can do this, but I don't think there's much utility here, unless I'm misunderstanding something (which is always likely). The with-bugs-resolve_jitter version is very, very similar to the vanilla-hiproc version, and both of them are very different from the UofA version. Again, it is straightforward for me to do, but doing so implies a whole lot more work on your part downstream to make a third terrain model and do a bunch of comparison, and if we already know that the with-bugs-resolve_jitter version isn't substantially different from the vanilla-hiproc version, is there value in exercising that whole work process? Not sure. You tell me.
I chatted some more with the DTM folks and we are good to go with the test using the dejittered data generated by this library and the older UA generated data. I'll keep you in the loop as they build the DTMs!
Description
Seeing differences in the ephemeris information between UA dejittered, noproj data, and hiproc dejittered noproj data. Seeking input on the differences.
What I Did
Ran the full pipeline on
ESP_018957_2655
using:
hiproc --keep --verbose --precision --max_workers 8 "$@"
This ran HiJACK and generated a RED NOPROJ mosaic as expected (awesome). I then compared a UA dejittered, NOPROJ RED cube and the hiproc generated cube, looking at the ephemeris information.
Ephemeris times and look vectors are identical between the two data products. Again, awesome! The spacecraft XYZ positions differ though. isisA is the UA dejittered RED NOPROJ cube and isisB is the hiproc dejittered RED NOPROJ cube. Differences in spacecraft position are measures at 100 points over the image. I have truncated the results below. The interesting thing is that the differences in x, y, and z are relatively consistent along and across track. I say relatively because the magnitude of the difference is monotonically increasing across and along track.
Is this expected behavior? Where might this systematic offset be coming from? Operator error?
@rbeyer If you want the UA cub and the notebook I am using for comparisons just let me know an I can get you a URL / gist.