Skip to content

Improve convergence handling in fit_fims by wrapping nlminb calls with tryCatch#1385

Open
aman-raj-srivastva wants to merge 2 commits intoNOAA-FIMS:devfrom
aman-raj-srivastva:feature/convergence-checks
Open

Improve convergence handling in fit_fims by wrapping nlminb calls with tryCatch#1385
aman-raj-srivastva wants to merge 2 commits intoNOAA-FIMS:devfrom
aman-raj-srivastva:feature/convergence-checks

Conversation

@aman-raj-srivastva
Copy link
Copy Markdown

@aman-raj-srivastva aman-raj-srivastva commented Mar 30, 2026

This PR improves convergence handling in fit_fims by wrapping nlminb calls in tryCatch blocks.

Changes include:

  • Wrapped initial nlminb call with tryCatch
  • Wrapped nlminb calls inside optimizer restart loop
  • Added graceful handling of optimization failures
  • Ensured valid FIMSFit object is returned even when optimization fails
  • Added informative warnings for debugging

This addresses issue #1370 and improves robustness and user feedback during optimization.


Instructions for code reviewer

👋Hello reviewer👋, thank you for taking the time to review this PR!

  • Please use this checklist during your review, checking off items that you have verified are complete but feel free to skip over items that are not relevant!
  • See the GitHub documentation for how to comment on a PR to indicate where you have questions or changes are needed before approving the PR.
  • Please use standard conventional messages for both commit messages and comments
  • PR reviews are a great way to learn so feel free to share your tips and tricks. However, when suggesting changes to the PR that are optional please include nit: (for nitpicking) as the comment type. For example, nit: I prefer using a data.frame() instead of a matrix because ...
  • Engage with the developer. Make it clear when the PR is approved by selecting the approved status, and potentially commenting on the PR with something like This PR is now ready to be merged.

Checklist

  • The PR requests the appropriate base branch (dev for features and main for hot fixes)
  • The code is well-designed
  • The code is designed well for both users and developers
  • Code coverage remains high- [ ] Comments are clear, useful, and explain why instead of what
  • Code is appropriately documented (doxygen and roxygen)

@github-actions
Copy link
Copy Markdown
Contributor

Thank you for contributing to FIMS and opening your first PR here! We are happy to have your contributions. Please ensure that the PR is made to the dev branch and let us know if you need any help! Also, we encourage you to introduce yourself to the community on the introduction thread in our Discussions.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 30, 2026

🎨 Chore: code formatting workflow

Our automated workflows cannot run on forks because of permission issues, and thus, we ask that you run the following code locally and push any changes that are created to your feature branch. You will only be reminded of this once per PR. Thank you!

Format C++ code

  1. Install clang-format version 18.0.0
  2. Run the following command from the repository root:
    clang-format -i --style="{BasedOnStyle: Google, SortIncludes: false}" $(find ./inst/include ./src ./tests/gtest -name "*.hpp" -o -name "*.cpp")

Format R code

  1. Install {styler} and {roxygen2}
  2. Run the following commands in R from the repository root:
styler::style_pkg() # Style R code
roxygen2::roxygenise() # Update documentation
styler::style_pkg() # Style R code again
roxygen2::roxygenise() # Update documentation again
usethis::use_tidy_description() # Style DESCRIPTION file

Push changes

  1. Commit the formatting with a commit message of "Chore: format feature branch"
  2. Push to your fork

@aman-raj-srivastva
Copy link
Copy Markdown
Author

Hi, thanks again for assigning this issue.
I have opened this draft PR implementing the convergence handling improvements.
Looking forward to your feedback!

Copy link
Copy Markdown
Contributor

@kellijohnson-NOAA kellijohnson-NOAA left a comment

Choose a reason for hiding this comment

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

Thanks for the speedy PR. I have some inline comments and I am also wondering about the location of "convergence", where I am assuming this is a typical item in opt so we just recreate that but with a non-converged value of 1.0? Also, should it be 1L to force it to be an integer?

R/fimsfit.R Outdated
},
error = function(e) {
cli::cli_warn(c(
"!" = paste("nlminb failed:", e$message)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

{cli} allows one to use inherit functionality of {glue} so you do not have to use paste, e.g.,

Suggested change
"!" = paste("nlminb failed:", e$message)
"!" = "nlminb failed: {e$message}"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I will replace paste() with glue-style formatting as suggested.

R/fimsfit.R Outdated
)

if (is.null(opt)) {
cli::cli_warn("Optimization failed. Returning partial results.")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
cli::cli_warn("Optimization failed. Returning partial results.")

I added this to the vector of warnings above.

R/fimsfit.R Outdated
},
error = function(e) {
cli::cli_warn(c(
"!" = paste("nlminb failed during loop:", e$message)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same comment as above.

)

if (is.null(opt)) {
break
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should this just break or should it return the same style of non-converged item that is returned above? If this loop doesn't converge does it go back to the previous object that did converge? I am confused on what the outcome of break leads to here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

You are right, using break with a NULL opt can lead to ambiguity. I will update the logic to retain the last successful optimization result and use that as a fallback if a failure occurs during the loop. This ensures that the returned object remains consistent.

@aman-raj-srivastva
Copy link
Copy Markdown
Author

Thanks for the feedback! I have addressed the comments and pushed the updates.
Please let me know if any further changes are needed!

@aman-raj-srivastva aman-raj-srivastva marked this pull request as ready for review March 31, 2026 09:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants