11from typing import List , Tuple , Dict
2+ from pathlib import Path
23import json
34import warnings
4- from pathlib import Path
55
66from .validate import validate
7- from .parser import parse_elegant
7+ from .parse import parse_elegant
8+
9+
10+ LATTICEJSON_ELEGANT_MAP : Tuple [Tuple [str , Tuple [str , ...]], ...] = (
11+ ("Drift" , ("DRIF" , "DRIFT" )),
12+ ("Dipole" , ("CSBEND" , "SBEND" , "BEND" )),
13+ ("Quadrupole" , ("KQUAD" , "QUAD" , "QUADRUPOLE" )),
14+ ("Sextupole" , ("KSEXT" , "SEXT" , "SEXTUPOLE" )),
15+ ("Lattice" , ("LINE" ,)),
16+ ("length" , ("L" ,)),
17+ ("angle" , ("ANGLE" ,)),
18+ ("e1" , ("E1" ,)),
19+ ("e2" , ("E2" ,)),
20+ ("k1" , ("K1" ,)),
21+ ("k2" , ("K2" ,)),
22+ )
23+ JSON_TO_ELE : Dict [str , str ] = {x : y [0 ] for x , y in LATTICEJSON_ELEGANT_MAP }
24+ ELE_TO_JSON : Dict [str , str ] = {y : x for x , tup in LATTICEJSON_ELEGANT_MAP for y in tup }
825
926
10- LATTICEJSON_ELEGANT_MAPPING : Dict [str , Tuple ] = {
11- "Drift" : ("DRIF" , "DRIFT" ,),
12- "Dipole" : ("CSBEND" , "SBEND" , "BEND" ,),
13- "Quadrupole" : ("KQUAD" , "QUAD" ,),
14- "Sextupole" : ("KSEXT" , "SEXT" ,),
15- "Lattice" : ("LINE" ,),
16- "length" : ("L" ,),
17- "angle" : ("ANGLE" ,),
18- "e1" : ("E1" ,),
19- "e2" : ("E2" ,),
20- "k1" : ("K1" ,),
21- "k2" : ("K2" ,),
22- }
27+ def latticejson_to_elegant (lattice_dict ) -> str :
28+ """Convert latticeJSON dict to elegant lattice file format.
29+ :param dict: dict in latticeJSON format
30+ :return: string with in elegant lattice file format
31+ """
32+ elements = lattice_dict ["elements" ]
33+ sub_lattices = lattice_dict ["sub_lattices" ]
34+
35+ strings = []
36+ element_template = "{}: {}, {}" .format
37+ for name , (type_ , attributes ) in elements .items ():
38+ attrs = ", " .join (f"{ JSON_TO_ELE [k ]} ={ v } " for k , v in attributes .items ())
39+ elegant_type = JSON_TO_ELE [type_ ]
40+ strings .append (element_template (name , elegant_type , attrs ))
2341
42+ lattice_template = "{}: LINE=({})" .format
43+ for name in sort_lattices (sub_lattices ):
44+ strings .append (lattice_template (name , ", " .join (sub_lattices [name ])))
2445
25- JSON_TO_ELEGANT = { k : v [ 0 ] for k , v in LATTICEJSON_ELEGANT_MAPPING . items ()}
26- ELEGANT_TO_JSON = { v : k for k , tup in LATTICEJSON_ELEGANT_MAPPING . items () for v in tup }
27- ELEGANT_ELEMENT_TEMPLATE = "{name}: {type}, {attributes}" . format
28- ELEGANT_LATTICE_TEMPLATE = "{name}: LINE=({objects})" . format
46+ name = lattice_dict [ "name" ]
47+ strings . append ( lattice_template ( name , ", " . join ( lattice_dict [ "lattice" ])))
48+ strings . append ( " \n " )
49+ return " \n " . join ( strings )
2950
3051
3152def elegant_to_latticejson (string ):
@@ -42,16 +63,16 @@ def elegant_to_latticejson(string):
4263
4364 elements = {}
4465 for name , (elegant_type , elegant_attributes ) in elegant_dict ["elements" ].items ():
45- latticejson_type = ELEGANT_TO_JSON .get (elegant_type )
66+ latticejson_type = ELE_TO_JSON .get (elegant_type )
4667 if latticejson_type is None :
47- elements [name ] = "Drift" , {"length" : elegant_attributes [ "L" ]}
48- warnings .warn (f"Element with type { elegant_type } gets replaced by Drift." )
68+ elements [name ] = [ "Drift" , {"length" : elegant_attributes . get ( "L" , 0 )}]
69+ warnings .warn (f"{ name } with type { elegant_type } is replaced by Drift." )
4970 continue
5071
5172 attributes = {}
52- elements [name ] = latticejson_type , attributes
73+ elements [name ] = [ latticejson_type , attributes ]
5374 for elegant_key , value in elegant_attributes .items ():
54- latticejson_key = ELEGANT_TO_JSON .get (elegant_key )
75+ latticejson_key = ELE_TO_JSON .get (elegant_key )
5576 if latticejson_key is not None :
5677 attributes [latticejson_key ] = value
5778 else :
@@ -67,47 +88,41 @@ def elegant_to_latticejson(string):
6788 )
6889
6990
70- def latticejson_to_elegant (lattice_dict ) -> str :
71- """Convert latticeJSON dict to elegant lattice file format.
72- :param dict: dict in latticeJSON format
73- :return: string with in elegant lattice file format
74- """
75- elements = lattice_dict ["elements" ]
76- sub_lattices = lattice_dict ["sub_lattices" ]
91+ def sort_lattices_old (lattices : Dict [str , List [str ]]) -> List [str ]:
92+ """Returns a sorted list of lattice names for a given dict of lattices."""
7793
78- strings = []
79- for name , element in elements .items ():
80- type_ = JSON_TO_ELEGANT [element .pop ("type" )]
81- attributes = ", " .join (f"{ JSON_TO_ELEGANT [k ]} ={ v } " for k , v in element .items ())
82- string = ELEGANT_ELEMENT_TEMPLATE (name = name , type = type_ , attributes = attributes )
83- strings .append (string )
94+ lattices_copy = lattices .copy ()
95+ lattice_names = []
8496
85- for name in order_lattices (sub_lattices ):
86- objects = ", " .join (sub_lattices [name ])
87- strings .append (ELEGANT_LATTICE_TEMPLATE (name = name , objects = objects ))
97+ def _sort_lattices (name , arrangement : List [str ]):
98+ for child_name in arrangement :
99+ if child_name in lattices_copy :
100+ _sort_lattices (child_name , lattices_copy [child_name ])
88101
89- name = lattice_dict ["name" ]
90- objects = ", " .join (lattice_dict ["lattice" ])
91- strings .append (ELEGANT_LATTICE_TEMPLATE (name = name , objects = objects ))
92- strings .append ("\n " )
93- return "\n " .join (strings )
102+ lattice_names .append (name )
103+ lattices_copy .pop (name )
104+
105+ for name , arrangement in lattices .items ():
106+ _sort_lattices (name , arrangement )
107+
108+ return lattice_names
94109
95110
96- def order_lattices ( cells_dict : Dict [str , List [str ]]):
97- """Order a dict of lattices."""
111+ def sort_lattices ( lattices : Dict [str , List [str ]]) -> List [ str ] :
112+ """Returns a sorted list of lattice names for a given dict of lattices."""
98113
99- cells_dict_copy = cells_dict . copy ( )
100- ordered_cells = []
114+ lattices_set = set ( lattices )
115+ lattice_names = []
101116
102- def _order_lattices (name , cell : List [str ]):
103- for lattice_name in cell :
104- if lattice_name in cells_dict_copy :
105- _order_lattices (lattice_name , cells_dict_copy [lattice_name ])
117+ def _sort_lattices (name ):
118+ for child_name in lattices [name ]:
119+ if child_name in lattices_set :
120+ lattices_set .remove (child_name )
121+ _sort_lattices (child_name )
106122
107- ordered_cells .append (name )
108- cells_dict_copy .pop (name )
123+ lattice_names .append (name )
109124
110- for name , cell in cells_dict . items () :
111- _order_lattices ( name , cell )
125+ while len ( lattices_set ) > 0 :
126+ _sort_lattices ( lattices_set . pop () )
112127
113- return ordered_cells
128+ return lattice_names
0 commit comments