Skip to content

Conversation

@oleg-alexandrov
Copy link
Contributor

Description

These are proposed fixes for jigsaw issues #5821 and #5818.

  • When an invalid control point is encountered, it should be ignored with a warning, rather than the program failing.
  • When solving for both twist and radius, and not setting point radius sigma, the tool will print a warning about the problem being under-constrained. This is not a fatal failure, for now, as I don't fully understand the implications of prohibiting this mode, but usually the program will fail soon enough in either case if the solution goes wild, and then the warning at least will explain why that may be.

How Has This Been Validated?

I tested with a control network I had.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Documentation change (update to the documentation; no code change)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Infrastructure change (changes to things like CI or the build system that do not impact users)

Checklist:

  • I have read and agree to abide by the Code of Conduct
  • I have read the CONTRIBUTING document.
  • My change requires a change to the documentation and I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • I have added myself to the .zenodo.json document.
  • I have added my user impacting change to the CHANGELOG.md document.

Licensing

This project is mostly composed of free and unencumbered software released into the public domain, and we are unlikely to accept contributions that are not also released into the public domain. Somewhere near the top of each file should have these words:

This work is free and unencumbered software released into the public domain. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain.

  • I dedicate any and all copyright interest in this software to the public domain. I make this dedication for the benefit of the public at large and to the detriment of my heirs and successors. I intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law.

@github-actions
Copy link

The build and test suite have started for your pull request.

To view your build log, please reference the build with source version: "PR_5833".

Additionally, check the latest "dev" source version to identify existing test failures. Please note that you are not responsible for the test failures that exist on both your PR and the dev branch.

@github-actions
Copy link

The build and test suite have started for your pull request.

To view your build log, please reference the build with source version: "PR_5833".

Additionally, check the latest "dev" source version to identify existing test failures. Please note that you are not responsible for the test failures that exist on both your PR and the dev branch.

Copy link
Collaborator

@acpaquette acpaquette left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good! A couple of user facing questions that could use some discussion

"failure may result.";
PvlGroup radiusSolveWarning("RadiusSolveWarning");
radiusSolveWarning.addKeyword(PvlKeyword("Warning", msg.c_str()));
Application::Log(radiusSolveWarning);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use Application::AppendAndLog for CLI and application compatibility

Comment on lines +967 to +970
QString msg = "In method ControlPoint::ComputeApriori(): ControlPoint [" + GetId() + "] has ";
msg += "no measures which project to the body. Will ignore it.";
SetIgnored(true);
std::cerr << msg << std::endl;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the warning but for most users this will still dump to the terminal, or most won't pipe the error message to another output. We need a way to silence the warnings in the preference file or some other setting. @Kelvinrr Thoughts on this? I know we had issues when we added a deprecation warning for users, not sure what discussions came out of that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes many control points will fail to work. I am not sure what you have in mind, but we probably would not want a popup for each of them. This could even be silent, with failed points simply glossed over. Fine with me whichever way this would be dealt with.

Copy link
Collaborator

@Kelvinrr Kelvinrr Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah we almost universally get complaints about warnings, it can mess up people who parse app outputs which is very common since ISIS often returns PVL. It might be possible to use the log for this since that can be suppressed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you suggest what this line should be changed to? There appear to be various choices in several places.

Copy link
Contributor

@lwellerastro lwellerastro Jun 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi All - could someone please be more explicit about this what is being discussed here as this is a program my job depends on and changes have impact. Is this a situation where measures for a point fail to intersect the body? If so, these should not be silenced and the program either needs to fail outright (as it does now) and/or that information should go to a log file. I want to know about these situations as they indicate some sort of a problem and should be removed and/or my network building needs additional checks. More importantly I need to understand why it is happening and hiding the error does not give me that opportunity.

It is recommended that users run cnetcheck on their network prior to passing it to jigsaw which will identify measures that do not intersect the target via the nolatlon output file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will cnetcheck go through all the same motions as jigsaw? Can then the failure message refer to these two?

Copy link
Contributor

@lwellerastro lwellerastro Jun 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cnetcheck will report if the measure does not intersect body when nolatlon=True (default) and send the information to an output file (which is not the most user friendly format so you might need a script to parse the output to send to cnetedit to remove the offending measures). It doesn't iterate like jigsaw, it will only check the state of the network based on spice and the line/sample information of the measures (probably similar to what jigsaw does before it starts to iterate). But it will report on off target measures along with free points having single measures, points having nocontrol (because all measures are invalid (ignored), etc.

cnetcheck is more robust that cnetstats.

It might be useful if jigsaw referred the user to cnetcheck in the case where a measure does not intersect the target body. But I'm not sure the particular bundle error I'm referring to for off-body targets is the same as what you are experiencing with your networks.

I won't go into all of the detail, but this is the jigsaw failure output for voyager data where measures essentially had no spice because they were off the target:

  Group = Error
    Program = jigsaw
    Class   = "USER ERROR"
    Code    = 2
    Message = "Unable to bundle adjust network [tb_vgr_voygalnet_Epos.net]"
    File    = main.cpp
    Line    = 157
  End_Group

  Group = Error
    Program = jigsaw
    Class   = "USER ERROR"
    Code    = 2
    Message = "Could not solve bundle adjust"
    File    = BundleAdjust.cpp
    Line    = 982
  End_Group

  Group = Error
    Program = jigsaw
    Class   = "USER ERROR"
    Code    = 2
    Message = "Unable to map apriori surface point for measure
               Voyager2/NAC/2064922 on point 133 into focal plane"
    File    = BundleAdjust.cpp
    Line    = 1887
  End_Group

I can't tell if this is the same sort of error you were encountering with your Juno data though.
I will add that for my Voyager and some Galileo disk data of Europa we attempted to avoid this sort of problem by manually moving the spice onto the target for images having issues. Very user intensive, but the process works (I can share those details in an email if you are interested and if applicable to your particular situation).

I have also encountered problems with Galileo SSI Europa, Cassini ISS Enceladus, Titan and MEX SRC and HRSC Phobos data where points end up right on the limb for images (having spice mostly on the target) because a measure is a fraction away of having spice or not. Cnetcheck has found those instances (reported in nolatlon output) and they are removed from the network prior to running the network through the bundle adjustment. If this is more in line with what you are experiencing with you JunoCam data you might see if cnetcheck spots your known problems.

And so I understand better, in the suggested warning message

QString msg = "In method ControlPoint::ComputeApriori(): ControlPoint [" + GetId() + "] has ";
      msg += "no measures which project to the body. Will ignore it.";
      SetIgnored(true);
      std::cerr << msg << std::endl;

Does "ignore" mean literally setting a measure in the network to ignore or does it simply mean not using it in calculations during any or all iterations?

If it is that latter (either really, the user needs to know if jigsaw is modifying the state of measures), maybe it could be flagged as "rejected" which would show up in the residuals.csv file in a similar way as measures are via the use of OUTLIER_REJECTION. But the user would need to know to look in the residuals file for rejected measures and be able to discern rejection due to outlier_rejection use versus rejection due to failing to intersect the target. That seems messy, so maybe ignore that idea. Which is why I think depending on jigsaw to validate a network should be discouraged and cnetcheck should be run to catch some of the most egregious issues before hand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does "ignore" mean literally setting a measure in the network to ignore or does it simply mean not using it in calculations during any or all iterations?

The control point will be flagged as ignored in the control network, and will be skipped when forming the optimization problem.

I will add that for my Voyager and some Galileo disk data of Europa we attempted to avoid this sort of problem by manually moving the spice onto the target for images having issues. Very user intensive, but the process works

This is likely not a great solution. Jigsaw should have the ability to filter out various problematic points without failing. It should print a report of the fraction of points that cannot be processed.

I rarely use this, so will defer to actual users and maintainers, but I think this is a case of a tool that should be more robust and give the user more choices of how to handle borderline data.

Copy link
Contributor

@lwellerastro lwellerastro Jun 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is likely not a great solution. Jigsaw should have the ability to filter out various problematic points without failing. It should print a report of the fraction of points that cannot be processed.

No, not fun, but in the case of Voyager data of Europa there was no choice - the spice was completely off the target and had to be moved. Extreme case.

I don't completely disagree that jigsaw should be capable of ignoring problem measures, reporting on it and continuing to iterate if possible. However it may be tough parsing the various possible errors (with some level of specificity) into a single new output report.

And I apologize for commenting on these possible changes so late in the process. I missed the original issue post and only saw the PR today.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However it may be tough parsing the various possible errors (with some level of specificity) into a single new output report.

One has to start somewhere. Ignoring failed control points and adding a report file is a good place. But since regular users seem not to see it as a problem, I guess maybe it is fine, most of the time.

BTW, for JunoCam I ran into systematic problems in produced terrain models that were due to intrinsics. ASP can tune those, and we have a doc.

@kledmundson
Copy link
Contributor

kledmundson commented Jun 16, 2025

Quick comment regarding the underconstrained warning. We certainly need this in some form, but I suspect that this check is insufficient. I'm not sure that it takes into consideration constraints on individual control point coordinates that may satisfy (or more than satisfy) the datum defect of 7 (set for example in cneteditor or qnet). Or constraints that have been placed on spk position and/or pointing.

@github-actions
Copy link

The build and test suite have started for your pull request.

To view your build log, please reference the build with source version: "PR_5833".

Additionally, check the latest "dev" source version to identify existing test failures. Please note that you are not responsible for the test failures that exist on both your PR and the dev branch.

@github-actions
Copy link

The build and test suite have started for your pull request.

To view your build log, please reference the build with source version: "PR_5833".

Additionally, check the latest "dev" source version to identify existing test failures. Please note that you are not responsible for the test failures that exist on both your PR and the dev branch.

@oleg-alexandrov
Copy link
Contributor Author

oleg-alexandrov commented Jun 16, 2025

@kledmundson I am not familiar enough with the tool to say for sure. I guess user expertise is needed in either case, and if the user knows some constraints were already set, they may choose to set this one to a relaxed value or simply ignore the warning.

Any sensible use of this tool likely needs some ground constraint in either case (and likely constrain at least 3 points), as for very high focal length any constraint on camera position and orientation alone may still result in too much of displacement on the ground.

@github-actions
Copy link

Thank you for your contribution!

Unfortunately, this pull request hasn't received much attention lately, so it is labeled as 'stale.'

If no additional action is taken, this pull request will be automatically closed in 180 days.

If you want to participate in our support prioritization meetings or be notified when support sprints are happening, you can sign up the support sprint notification emails here.

Read more about our support processs here

@github-actions github-actions bot added the inactive Issue that has been inactive for at least 6 months label Dec 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

inactive Issue that has been inactive for at least 6 months

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants