Skip to content

Commit dc4949d

Browse files
authored
Merge pull request #257 from mwang87/formula-distribution
upadting formula distribution
2 parents de7cfde + fb32c84 commit dc4949d

8 files changed

Lines changed: 28 additions & 6 deletions

massql/msql.ebnf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ factor: floating
146146
| "formula(" moleculeformula ")"
147147
| "aminoaciddelta(" aminoacids ")"
148148
| peptidefunction
149-
| "(" numericalexpression ")"
149+
| "(" numericalexpression ")" -> factor_parens
150150
peptidefunction: "peptide(" peptide "," "charge=" peptidecharge "," "ion=" peptideion ")"
151151
multiply: "*"
152152
divide: "/"

massql/msql_parser.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,9 @@ def divide(self, s):
367367
def factor(self, s):
368368
return s[0]
369369

370+
def factor_parens(self, items):
371+
return f"({items[0]})"
372+
370373
def term(self, items):
371374
if len(items) == 1:
372375
return items[0]

tests/reference_parses/QUERY_scaninfo_MS2DATA__WHERE_MS1MZ_X-2INTENSITYMA___61a2da302d53487ba89667bb7b7433a3.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"qualifierintensitymatch": {
77
"comparator": "equal",
88
"name": "qualifierintensitymatch",
9-
"value": "Y*0.0608+2e-06*X"
9+
"value": "Y*(0.0608+(2e-06*X))"
1010
},
1111
"qualifierintensitytolpercent": {
1212
"comparator": "equal",

tests/reference_parses/QUERY_scaninfo_MS2DATA__WHERE_MS2PROD_X_AND_MS2PRO___8ee2287663d6ad552d20963061530a3b.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"conditiontype": "where",
1212
"type": "ms2productcondition",
1313
"value": [
14-
"2.0*X-55.9349375"
14+
"2.0*(X-55.9349375)"
1515
]
1616
}
1717
],

tests/reference_parses/QUERY_scaninfo_MS2DATA__WHERE_MS2PROD_X_And_MS2PRO___4fe070795d41b0ea705398a6e5d940ab.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"conditiontype": "where",
1212
"type": "ms2productcondition",
1313
"value": [
14-
"2.0*X-55.9349375"
14+
"2.0*(X-55.9349375)"
1515
]
1616
}
1717
],

tests/reference_parses/QUERY_scaninfo_MS2DATA__WHERE_MS2PROD_X_and_MS2PRO___09ccf26b267546b40a6acd472bbea037.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"conditiontype": "where",
1212
"type": "ms2productcondition",
1313
"value": [
14-
"2.0*X-55.9349375"
14+
"2.0*(X-55.9349375)"
1515
]
1616
}
1717
],

tests/reference_parses/QUERY_scaninfo_MS2DATA__WHERE_X_range_min_100,_max___ce48d94145b8fe9dd12d4257ffda9ad1.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"qualifierintensitymatch": {
1313
"comparator": "equal",
1414
"name": "qualifierintensitymatch",
15-
"value": "Y*0.0608+2e-06*X"
15+
"value": "Y*(0.0608+(2e-06*X))"
1616
},
1717
"qualifierintensitytolpercent": {
1818
"comparator": "equal",

tests/test_parse.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,25 @@ def test_variable_formula_parse2():
112112
parsed_output = msql_parser.parse_msql(query)
113113
print(json.dumps(parsed_output, indent=4))
114114

115+
def test_formula_distribution():
116+
"""Verify that formula() is correctly distributed through multiplication in X-expressions.
117+
118+
Previously, 2*(X - formula(Fe)) was parsed as 2*X - 55.93 instead of 2*(X - 55.93),
119+
which is a ~56 Da error when evaluated.
120+
"""
121+
query = "QUERY scaninfo(MS2DATA) WHERE MS2PROD=X AND MS2PROD=2.0*(X - formula(Fe))"
122+
parsed_output = msql_parser.parse_msql(query)
123+
124+
value = parsed_output["conditions"][1]["value"][0]
125+
assert value == "2.0*(X-55.9349375)", f"Expected parenthesized form, got: {value}"
126+
127+
# Verify the expression evaluates correctly
128+
from py_expression_eval import Parser
129+
p = Parser()
130+
result = p.parse(value).evaluate({"X": 100.0})
131+
expected = 2.0 * (100.0 - 55.9349375)
132+
assert abs(result - expected) < 1e-6, f"Expected {expected}, got {result}"
133+
115134
def test_xrange_parse():
116135
query = "QUERY scaninfo(MS2DATA) WHERE MS2PROD=X AND MS2PROD=2.0*(X - formula(Fe)) AND X=range(min=5, max=100)"
117136

0 commit comments

Comments
 (0)