1- from typing import List , Dict
2- from pathlib import Path
31import json
2+ from pathlib import Path
3+ from typing import Dict , List
44from warnings import warn
5+
6+ from .exceptions import UnknownAttributeWarning , UnknownElementTypeWarning
57from .parse import parse_elegant , parse_madx
6- from .exceptions import UnknownElementWarning , UnknownAttributeWarning
8+ from .utils import sort_lattices
9+ from .validate import schema_version
710
811NAME_MAP = json .loads ((Path (__file__ ).parent / "map.json" ).read_text ())["map" ]
9- JSON_TO_ELE = {x : y [0 ][0 ] for x , * y in NAME_MAP }
10- ELE_TO_JSON = {y : x for x , * tup in NAME_MAP for y in tup [0 ]}
11- JSON_TO_MADX = {x : y [1 ][0 ] for x , * y in NAME_MAP }
12- MADX_TO_JSON = {y : x for x , * tup in NAME_MAP for y in tup [1 ]}
12+ TO_ELEGANT = {x : y [0 ][0 ] for x , * y in NAME_MAP }
13+ FROM_ELEGANT = {y : x for x , * tup in NAME_MAP for y in tup [0 ]}
14+ TO_MADX = {x : y [1 ][0 ] for x , * y in NAME_MAP }
15+ FROM_MADX = {y : x for x , * tup in NAME_MAP for y in tup [1 ]}
1316
1417
1518def from_elegant (string ):
@@ -22,7 +25,7 @@ def from_elegant(string):
2225 :type str, optional
2326 :return: dict in LatticeJSON format
2427 """
25- return _map_names_from_elegant (parse_elegant (string ))
28+ return _map_names (parse_elegant (string ), FROM_ELEGANT )
2629
2730
2831def from_madx (string ):
@@ -35,15 +38,7 @@ def from_madx(string):
3538 :type str, optional
3639 :return: dict in LatticeJSON format
3740 """
38- return _map_names_from_madx (parse_madx (string ))
39-
40-
41- def _map_names_from_madx (madx_dict : dict ):
42- return _map_names (madx_dict , MADX_TO_JSON )
43-
44-
45- def _map_names_from_elegant (elegant_dict : dict ):
46- return _map_names (elegant_dict , ELE_TO_JSON )
41+ return _map_names (parse_madx (string ), FROM_MADX )
4742
4843
4944def _map_names (lattice_data : dict , name_map : dict ):
@@ -52,7 +47,7 @@ def _map_names(lattice_data: dict, name_map: dict):
5247 latticejson_type = name_map .get (other_type )
5348 if latticejson_type is None :
5449 elements [name ] = ["Drift" , {"length" : other_attributes .get ("L" , 0 )}]
55- warn (UnknownElementWarning (name , other_type ), stacklevel = 2 )
50+ warn (UnknownElementTypeWarning (name , other_type ))
5651 continue
5752
5853 attributes = {}
@@ -62,15 +57,17 @@ def _map_names(lattice_data: dict, name_map: dict):
6257 if latticejson_key is not None :
6358 attributes [latticejson_key ] = value
6459 else :
65- warn (UnknownAttributeWarning (other_key , name ), stacklevel = 2 )
60+ warn (UnknownAttributeWarning (other_key , name ))
6661
6762 lattices = lattice_data ["lattices" ]
68- lattice_name , main_lattice = lattices .popitem () # use last lattice as main_lattice
63+ root = lattice_data .get ("root" , tuple (lattices .keys ())[- 1 ])
64+ title = lattice_data .get ("title" , "" )
6965 return dict (
70- name = lattice_name ,
71- lattice = main_lattice ,
72- sub_lattices = lattices ,
66+ version = str ( schema_version ) ,
67+ title = title ,
68+ root = root ,
7369 elements = elements ,
70+ lattices = lattices ,
7471 )
7572
7673
@@ -81,21 +78,21 @@ def to_elegant(latticejson: dict) -> str:
8178 :return: string with in elegant lattice file format
8279 """
8380 elements = latticejson ["elements" ]
84- sub_lattices = latticejson ["sub_lattices " ]
81+ lattices = latticejson ["lattices " ]
8582
86- strings = [f"! TITLE: { latticejson ['name ' ]} " ]
83+ strings = [f"! TITLE: { latticejson ['title ' ]} " ]
8784 element_template = "{}: {}, {}" .format
85+ # TODO: check if equivalent type exists in elegant
8886 for name , (type_ , attributes ) in elements .items ():
89- attrs = ", " .join (f"{ JSON_TO_ELE [k ]} ={ v } " for k , v in attributes .items ())
90- elegant_type = JSON_TO_ELE [type_ ]
87+ attrs = ", " .join (f"{ TO_ELEGANT [k ]} ={ v } " for k , v in attributes .items ())
88+ elegant_type = TO_ELEGANT [type_ ]
9189 strings .append (element_template (name , elegant_type , attrs ))
9290
9391 lattice_template = "{}: LINE=({})" .format
94- for name in sort_lattices (sub_lattices ):
95- strings .append (lattice_template (name , ", " .join (sub_lattices [ name ] )))
92+ for name , children in sort_lattices (latticejson ). items ( ):
93+ strings .append (lattice_template (name , ", " .join (children )))
9694
97- strings .append (lattice_template ("__MAIN__" , ", " .join (latticejson ["lattice" ])))
98- strings .append ("USE, __MAIN__\n " )
95+ strings .append (f"USE, { latticejson ['root' ]} \n " )
9996 return "\n " .join (strings )
10097
10198
@@ -106,39 +103,19 @@ def to_madx(latticejson: dict) -> str:
106103 :return: string with in elegant lattice file format
107104 """
108105 elements = latticejson ["elements" ]
109- sub_lattices = latticejson ["sub_lattices " ]
106+ lattices = latticejson ["lattices " ]
110107
111- strings = [f"TITLE, \" { latticejson ['name ' ]} \" " ]
108+ strings = [f"TITLE, \" { latticejson ['title ' ]} \" ; " ]
112109 element_template = "{}: {}, {};" .format
110+ # TODO: check if equivalent type exists in madx
113111 for name , (type_ , attributes ) in elements .items ():
114- attrs = ", " .join (f"{ JSON_TO_MADX [k ]} ={ v } " for k , v in attributes .items ())
115- elegant_type = JSON_TO_MADX [type_ ]
112+ attrs = ", " .join (f"{ TO_MADX [k ]} ={ v } " for k , v in attributes .items ())
113+ elegant_type = TO_MADX [type_ ]
116114 strings .append (element_template (name , elegant_type , attrs ))
117115
118116 lattice_template = "{}: LINE=({});" .format
119- for name in sort_lattices (sub_lattices ):
120- strings .append (lattice_template (name , ", " .join (sub_lattices [ name ] )))
117+ for name , children in sort_lattices (latticejson ). items ( ):
118+ strings .append (lattice_template (name , ", " .join (children )))
121119
122- strings .append (lattice_template ("__MAIN__" , ", " .join (latticejson ["lattice" ])))
123- strings .append ("USE, __MAIN__;\n " )
120+ strings .append (f"USE, SEQUENCE={ latticejson ['root' ]} ;\n " )
124121 return "\n " .join (strings )
125-
126-
127- def sort_lattices (lattices : Dict [str , List [str ]]) -> List [str ]:
128- """Returns a sorted list of lattice names for a given dict of lattices."""
129-
130- lattices_set = set (lattices )
131- lattice_names = []
132-
133- def _sort_lattices (name ):
134- for child_name in lattices [name ]:
135- if child_name in lattices_set :
136- lattices_set .remove (child_name )
137- _sort_lattices (child_name )
138-
139- lattice_names .append (name )
140-
141- while len (lattices_set ) > 0 :
142- _sort_lattices (lattices_set .pop ())
143-
144- return lattice_names
0 commit comments