Spaces:
Runtime error
Runtime error
import altair as alt | |
import molmass | |
import gradio as gr | |
import pandas as pd | |
import re | |
# def ms(formula): | |
# mf = molmass.Formula(formula) | |
# return mf.spectrum().dataframe().round(4).query("Fraction > .001").drop(columns=["Fraction"]) | |
# def plot_ms(spec_df): | |
# chart = alt.Chart(spec_df).mark_bar().encode( | |
# x=alt.X("m\/z:O").title('mz'), | |
# y=alt.Y("Intensity\ %:Q").title("relative intensity (%)") | |
# ) | |
# return chart | |
example1 = """# Lines starting with '#' are comments | |
# Lines with "=" are fragment definitions | |
Azide = H2NCH(CH2CH2N3)COOH | |
Alkyne = HCCCH2NPh2 | |
# Starting materials | |
Azide + H+ | |
Alkyne + H+ | |
#Products | |
Click = Azide + Alkyne | |
Click + H+ | |
Click + Na+ | |
Click + H+2 | |
2*Click + H+ | |
Click - H+ | |
""" | |
example2 = """NH4+""" | |
examples_dict = { | |
"addition": example1, | |
"substitution": example2, | |
} | |
def make_formula(line): | |
"""Recursively splits line on ' + ' and ' - ' (signs padded with spaces) to construct formula. | |
Parsing precedence: | |
1) '+' over '-' | |
2) if a group is recognized as a key in GROUPS, the GROUPS[line] value is returned | |
Don't go crazy, it's not a full string calculator. | |
""" | |
if " + " in line: | |
term1, term2 = line.split(" + ", maxsplit=1) | |
return make_formula(term1) + make_formula(term2) | |
elif " - " in line: | |
term1, term2 = line.split(" - ", maxsplit=1) | |
return make_formula(term1) - make_formula(term2) | |
else: | |
group_lookup = molmass.GROUPS.get(line) | |
return group_lookup or molmass.Formula(line) | |
class FormulaBox: | |
"""Parsing formulabox""" | |
def __init__(self, inputs, **kwargs): | |
self.min_intensity = kwargs.get("min_intensity") or 1e-4 | |
self.lines = inputs.split("\n") | |
self.ions = {} | |
self.parse() | |
def parse(self): | |
"""lines are either definitions ('=') or ions (no '=')""" | |
for _line in self.lines: | |
line = re.sub("\s+", "", _line) | |
if line == "" or line.startswith("#"): | |
continue | |
elif "=" in line: | |
self.add_group(line) | |
else: | |
self.ions[line] = make_formula(_line) | |
return | |
def add_group(self, line): | |
alias, value = line.split("=") | |
# self.groups[alias] = make_formula(value) | |
molmass.GROUPS[alias] = make_formula(value) | |
# GROUPS.update(**self.groups) | |
return | |
def get_spectra(self): | |
self.spectra = { | |
k: v.spectrum(min_intensity=self.min_intensity) | |
for k, v in self.ions.items() | |
} | |
return | |
def df(self): | |
frame = pd.DataFrame([ | |
{ | |
"molecule": k, | |
"mf": v.formula, | |
"charge": v.charge, | |
"mz": v.spectrum(min_intensity=1e-4).peak.mz, | |
"top_isotope_fraction": v.spectrum(min_intensity=1e-4).peak.fraction, | |
"monoisotopic_mass": v.monoisotopic_mass, | |
} | |
for k, v in self.ions.items() | |
]).round(5) | |
return frame | |
def spectra(self): | |
return | |
fb1 = FormulaBox(example1) | |
with gr.Blocks() as demo: | |
gr.Markdown(""" | |
# Edit fragment definitions and ions to calculate MS for | |
## Click Submit or press Tab to calculate | |
""") | |
with gr.Row(): | |
with gr.Column(scale=1): | |
formula_box = gr.Textbox(value=example1, lines=12, max_lines=256, label="FormulaBox") | |
btn = gr.Button("Submit") | |
with gr.Column(scale=2): | |
# examples = gr.Examples(examples=["addition", "substitution"], inputs=formula_box, run_on_click=True, fn=get_example) | |
# examples2 = gr.Examples(examples=[example1, example2], inputs=formula_box, run_on_click=True, fn=lambda x:x, preprocess=get_example) | |
ms_df_box = gr.Dataframe(value=fb1.df, label="MS DF") | |
def make_ms_df(formula_box): | |
try: | |
fb = FormulaBox(formula_box) | |
return fb.df | |
except Exception as e: | |
return pd.DataFrame({"error": [e.__str__()]}) | |
demo.launch() |