from typing import List
from feynmodel.feyn_model import FeynModel
from feynmodel.interface.qgraf import feynmodel_to_qgraf, pdg_id_to_qgraf_name
from feynmodel.interface.ufo import load_ufo_model # noqa: F401
from xsdata.formats.dataclass.parsers import XmlParser
from feynml.feynml import FeynML
style = r"""
<prologue>
<<!--
file generated by <program>
<command_loop><command_line_loop> <command_data><end><end>
You must add x= and y= with suitable vertex positions.
Some lines may need manual bending to render properly.
-->>
<<feynml>>
<diagram>
<back>
<<diagram
id="Diagram<diagram_index>"
incoming="<legs_in>"
outgoing="<legs_out>"
sign="<sign>"
symmmetry_factor="<symmetry_factor>"
>>
<vertex_loop>
<<vertex id="Vert<vertex_index>">>
<</vertex>>
<end>
<in_loop>
<<leg id="In<in_index>">>
<<name>><field><</name>>
<<sense>>incoming<</sense>>
<<target>>Vert<vertex_index><</target>>
<<momentum>>
<<name>><momentum><</name>>
<</momentum>>
<</leg>>
<end>
<out_loop>
<<leg id="Out<out_index>">>
<<name>><field><</name>>
<<sense>>outgoing<</sense>>
<<target>>Vert<vertex_index><</target>>
<<momentum>>
<<name>><momentum><</name>>
<</momentum>>
<</leg>>
<end>
<propagator_loop>
<<propagator id="Prop<propagator_index>">>
<<name>><field><</name>>
<<source>>Vert<dual-vertex_index><</source>>
<<target>>Vert<vertex_index><</target>>
<<momentum>>
<<name>><momentum><</name>>
<</momentum>>
<</propagator>>
<end>
<</diagram>>
<epilogue>
<</feynml>>
<<!-- end -->>
<exit>
"""
"""Style for qgraf to produce feynml."""
[docs]
def get_style() -> str:
"""Get the style for qgraf to produce feynml."""
global style
return style
[docs]
def generate_fml(
feyn_model: FeynModel,
incoming_pdgs: List[int],
outgoing_pdgs: List[int],
loops: int = 0,
) -> FeynML:
"""Generate a feynml object from a feyn_model and incoming/outgoing pdgs."""
try:
from pyqgraf import qgraf
except ImportError:
raise ImportError("Please install the pyqgraf package")
fm = feyn_model
assert isinstance(fm, FeynModel)
qfm = feynmodel_to_qgraf(fm, True, False)
# make sure qgraf is installed
qgraf.install()
momentum_index = 1
incoming = []
outgoing = []
for pdg in incoming_pdgs:
str_pdg = pdg_id_to_qgraf_name(fm, pdg, True) # Same bool as qfm call above
incoming.append(f"{str_pdg}[p{momentum_index}]")
momentum_index += 1
for pdg in outgoing_pdgs:
str_pdg = pdg_id_to_qgraf_name(fm, pdg, True) # Same bool as qfm call above
outgoing.append(f"{str_pdg}[p{momentum_index}]")
momentum_index += 1
# run it
xml_string = qgraf.run(
", ".join(incoming),
", ".join(outgoing),
loops=loops,
loop_momentum="l",
model=qfm,
style=get_style(),
)
parser = XmlParser()
fml = parser.from_string(xml_string, FeynML)
return fml