Skip to content

Move methods in cinnabar.stats concerning MLE to the MLEEstimator class - #211

Merged
ianmkenney merged 29 commits into
mainfrom
feat/remove_stats_mle
Jul 16, 2026
Merged

Move methods in cinnabar.stats concerning MLE to the MLEEstimator class#211
ianmkenney merged 29 commits into
mainfrom
feat/remove_stats_mle

Conversation

@ianmkenney

Copy link
Copy Markdown
Member

No description provided.

@ianmkenney

Copy link
Copy Markdown
Member Author

pre-commit.ci autofix

@codecov

codecov Bot commented May 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.31544% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.46%. Comparing base (deef019) to head (090ac2a).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
cinnabar/estimators.py 93.10% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #211      +/-   ##
==========================================
- Coverage   97.53%   97.46%   -0.07%     
==========================================
  Files          22       22              
  Lines        2470     2403      -67     
==========================================
- Hits         2409     2342      -67     
  Misses         61       61              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ianmkenney

Copy link
Copy Markdown
Member Author

pre-commit.ci autofix

@ianmkenney
ianmkenney requested a review from jthorton May 27, 2026 15:35
@ianmkenney ianmkenney changed the title [DNM] Move methods in cinnabar.stats concerning MLE to the MLEEstimator class Move methods in cinnabar.stats concerning MLE to the MLEEstimator class May 27, 2026
Comment thread cinnabar/estimators.py Outdated
)

@staticmethod
def mle(graph: nx.DiGraph, factor: str = "f_ij", node_factor: Union[str, None] = None) -> (np.ndarray, np.ndarray):

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.

We are free to change this however we want, lets update the factor and node_factor names to be more meaningful or if you think its okay we can leave them.

@ianmkenney ianmkenney Jul 9, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I've renamed them:

  • factor -> edge_data_label
  • node_factor -> node_data_label

Comment thread cinnabar/estimators.py
# populate the edges of the graph along with their computational binding free energies
for m in filter(lambda m: m.computational, measurements):
if isinstance(m.labelA, ReferenceState):
# TODO this is never hit in the tests and should be supported behavior

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.

Good point lets move this to another PR we should be able to support absolute computational values in the solver as well!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Agreed, another PR would be a good place for this

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.

Related to issue #123

Comment thread cinnabar/estimators.py
Comment on lines +355 to +361
z[i] += -deltaij / varij
z[j] += deltaij / varij

F_matrix[i, i] += 1 / varij
F_matrix[j, j] += 1 / varij
F_matrix[i, j] += -1 / varij
F_matrix[j, i] += -1 / varij

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.

Nice this should allow for the forward and backward results do you want to add support for that in this PR? We have some example data in #133 so we can add a test we can punt to another if you want though.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Even if we don't test with a full network, I think this should be a halfway decent start for bi-directionality 6fb6c2b

Comment thread cinnabar/estimators.py Outdated
return f_i, Finv

@staticmethod
def form_edge_matrix(graph: nx.Graph, label: str, step=None, action=None, node_label=None) -> np.ndarray:

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.

Lets just remove this if its not needed anymore and all tests associated with it!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Removed in 64f09e4

@jthorton jthorton left a comment

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.

Looking great just a couple of things to look at.

@jthorton jthorton self-assigned this Jun 15, 2026
Additionally, I removed a comment referencing bayesian_f_ij that
doesn't seem to apply to any code in the repository.
The meaning of the "factor" naming convention is
unclear. "node_factor", which represents the harmonic wells
restraining the movement of individual nodes from a fixed absolute
free energy, has been renamed to "node_data_label". "factor",
referring to the harmonic restraints between pairs of nodes, has been
renamed to "edge_data_label".
@ianmkenney
ianmkenney force-pushed the feat/remove_stats_mle branch from f030064 to 4c61f18 Compare July 9, 2026 13:00
@ianmkenney
ianmkenney requested a review from jthorton July 9, 2026 19:32
@ianmkenney

Copy link
Copy Markdown
Member Author

pre-commit.ci autofix

Comment thread news/stats_mle_move.rst Outdated
Comment thread cinnabar/estimators.py Outdated
Comment on lines +411 to +418
raise ValueError(
f"Multiple edges detected between nodes {m.labelA} and {m.labelB}. "
"MLE cannot be performed on graphs with multiple edges between the "
"same nodes. The results should be combined into a single estimate "
"and uncertainty before performing MLE. "
"See https://cinnabar.openfree.energy/en/latest/concepts/estimators.html"
"#limitations for more details."
)

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.

The plan is to fix this at the FEMap level in another PR. Issue - #232

Comment thread news/stats_mle_move.rst Outdated

@jthorton jthorton left a comment

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.

Thanks @ianmkenney this looks great we can handle the FEMap fixes in a nother PR.

@IAlibay IAlibay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is amazing!

Everything looks good, but I am going to block over the one test - it should be an easy fix.

Comment thread cinnabar/estimators.py Outdated
Comment on lines +317 to +322
# if we have bidirectional edge results we need to raise an error as they can not be used with MLE
# track the edges we have seen
edges = []
for a, b in graph.edges:
edge_name = (a, b) if str(a) < str(b) else (b, a)
edges.append(edge_name)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
# if we have bidirectional edge results we need to raise an error as they can not be used with MLE
# track the edges we have seen
edges = []
for a, b in graph.edges:
edge_name = (a, b) if str(a) < str(b) else (b, a)
edges.append(edge_name)

Is this leftover code that needs removing?

Comment thread cinnabar/estimators.py Outdated
Comment on lines 212 to 213

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change

Does this need removing?

Comment thread cinnabar/estimators.py
Comment thread cinnabar/tests/test_estimators.py Outdated
Comment on lines +144 to +151
def test_mle_repeated_edge():
graph = nx.DiGraph()
graph.add_edge(0, 1, f_ij=1.0, f_dij=0.5)
graph.add_edge(0, 1, f_ij=1.5, f_dij=0.1) # repeated edge
output_absolutes, _ = MLEEstimator.mle(graph, edge_data_label="f_ij", node_data_label="f_i")
output_absolutes -= output_absolutes[0]
assert output_absolutes[1] > 1.25
assert output_absolutes[1] < 1.5

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think this does what the test claims it do do.

If you just add an edge it willl overwrite the previous entry. See the notes here: https://networkx.org/documentation/stable/reference/classes/generated/networkx.Graph.add_edge.html

I think you need to use a MultiDiGraph here, so:

Suggested change
def test_mle_repeated_edge():
graph = nx.DiGraph()
graph.add_edge(0, 1, f_ij=1.0, f_dij=0.5)
graph.add_edge(0, 1, f_ij=1.5, f_dij=0.1) # repeated edge
output_absolutes, _ = MLEEstimator.mle(graph, edge_data_label="f_ij", node_data_label="f_i")
output_absolutes -= output_absolutes[0]
assert output_absolutes[1] > 1.25
assert output_absolutes[1] < 1.5
def test_mle_repeated_edge():
graph = nx.MultiDiGraph()
graph.add_edge(0, 1, f_ij=1.0, f_dij=0.5)
graph.add_edge(0, 1, f_ij=1.5, f_dij=0.1) # repeated edge
output_absolutes, _ = MLEEstimator.mle(graph, edge_data_label="f_ij", node_data_label="f_i")
output_absolutes -= output_absolutes[0]
expected = (1.0 / 0.5**2 + 1.5 / 0.1**2) / (1 / 0.5**2 + 1 / 0.1**2)
assert output_absolutes[1] == pytest.approx(expected)

ianmkenney and others added 3 commits July 16, 2026 08:37
Co-authored-by: Irfan Alibay <IAlibay@users.noreply.github.com>
Co-authored-by: Irfan Alibay <IAlibay@users.noreply.github.com>
Co-authored-by: Irfan Alibay <IAlibay@users.noreply.github.com>

@IAlibay IAlibay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

lgtm, thanks!

ianmkenney and others added 2 commits July 16, 2026 10:05
Co-authored-by: Irfan Alibay <IAlibay@users.noreply.github.com>
@ianmkenney

Copy link
Copy Markdown
Member Author

@IAlibay 184b0ab. This should allow the estimator to fully support parallel edges. This does cause an error upstream for femap expected behavior which hasn't been fully tested yet. Do you have thoughts on this?

@IAlibay

IAlibay commented Jul 16, 2026

Copy link
Copy Markdown
Member

@IAlibay 184b0ab. This should allow the estimator to fully support parallel edges. This does cause an error upstream for femap expected behavior which hasn't been fully tested yet. Do you have thoughts on this?

I don't mind either way, I'm happy for it to be removed with the idea that femap testing / fixes will be dealt with before the next release.

Allowing parallel edges in the MLEEstimator removes the ValueError
normally produced by the FEMap.generate_absolute_values method. The
test expecting this ValueError has been removed, but does not
explicity mean that FEMap supports parallel edges.
@ianmkenney

ianmkenney commented Jul 16, 2026

Copy link
Copy Markdown
Member Author

@IAlibay 184b0ab. This should allow the estimator to fully support parallel edges. This does cause an error upstream for femap expected behavior which hasn't been fully tested yet. Do you have thoughts on this?

I don't mind either way, I'm happy for it to be removed with the idea that femap testing / fixes will be dealt with before the next release.

Perfect, I've removed it from the FEMap testing. It should be addressed after #232.

@ianmkenney
ianmkenney merged commit 7d0ce09 into main Jul 16, 2026
7 of 9 checks passed
@ianmkenney
ianmkenney deleted the feat/remove_stats_mle branch July 16, 2026 14:34
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.

3 participants