@@ -75,29 +75,48 @@ def _get_structure_info(self):
75
75
"""
76
76
77
77
def _get_atom_table_data (self ):
78
- structure = self .structure .get_ase ()
79
- data = [
80
- [
81
- "Atom index" ,
82
- "Chemical symbol" ,
83
- "Tag" ,
84
- "x (Å)" ,
85
- "y (Å)" ,
86
- "z (Å)" ,
87
- ]
88
- ]
89
- positions = structure .positions
90
- chemical_symbols = structure .get_chemical_symbols ()
91
- tags = structure .get_tags ()
92
-
93
- for index , (symbol , tag , position ) in enumerate (
94
- zip (chemical_symbols , tags , positions ), start = 1
95
- ):
96
- formatted_position = [f"{ coord :.2f} " for coord in position ]
97
- data .append ([index , symbol , tag , * formatted_position ])
78
+ """Build table data; if 'fixed_atoms' is present in structure attributes,
79
+ add a 'Free x,y,z' column showing '✓' for free (1) and 'x' for fixed (0)."""
80
+ # Try to get fixed_atoms from AiiDA StructureData attributes
81
+ fixed_atoms = None
82
+ try :
83
+ fixed_atoms = self .structure .base .attributes .all ['fixed_atoms' ]
84
+ except KeyError :
85
+ fixed_atoms = None
86
+
87
+ ase_atoms = self .structure .get_ase ()
88
+
89
+ # Header
90
+ data = [["Atom index" , "Chemical symbol" , "Tag" , "x (Å)" , "y (Å)" , "z (Å)" ]]
91
+ if fixed_atoms is not None :
92
+ data [0 ].append ("Free x,y,z" )
93
+
94
+ positions = ase_atoms .positions
95
+ chemical_symbols = ase_atoms .get_chemical_symbols ()
96
+ tags = ase_atoms .get_tags ()
97
+
98
+ def fmt_free (mask ):
99
+ """mask: tuple/list of three 0/1; 0=free -> 'X', 1=fixed -> ' '."""
100
+ try :
101
+ x , y , z = mask
102
+ except Exception :
103
+ x = y = z = 0
104
+ # If your UI collapses spaces, replace ' ' with '·' or '\u00A0' (NBSP).
105
+ return f"({ 'x' if x == 0 else '✓' } { 'x' if y == 0 else '✓' } { 'x' if z == 0 else '✓' } )"
106
+
107
+ for idx , (symbol , tag , pos ) in enumerate (zip (chemical_symbols , tags , positions ), start = 1 ):
108
+ formatted_position = [f"{ coord :.2f} " for coord in pos ]
109
+ row = [idx , symbol , tag , * formatted_position ]
110
+
111
+ if fixed_atoms is not None :
112
+ mask = fixed_atoms [idx - 1 ] if idx - 1 < len (fixed_atoms ) else (0 , 0 , 0 )
113
+ row .append (fmt_free (mask ))
114
+
115
+ data .append (row )
98
116
99
117
return data
100
118
119
+
101
120
def get_model_state (self ):
102
121
return {
103
122
"selected_view" : self .selected_view ,
0 commit comments