@@ -176,7 +176,7 @@ def write_points_to_imod(
176176 """Write point annotations to a .mod file for IMOD.
177177
178178 Args:
179- coordinates: Array with the point coordinates.
179+ coordinates: Array with the point coordinates. #2D or 3D
180180 radii: Array with the point radii.
181181 shape: Shape of the volume to be exported.
182182 min_radius: Minimum radius for export.
@@ -193,19 +193,32 @@ def _pad(inp, n=3):
193193 pw = plen * " "
194194 return f"{ pw } { inp } .00"
195195
196+ is_3d = coordinates .shape [1 ] == 3
197+ if not is_3d and coordinates .shape [1 ] != 2 :
198+ raise ValueError ("Coordinates must have shape (N, 2) for 2D or (N, 3) for 3D." )
199+
196200 with tempfile .NamedTemporaryFile () as tmp_file :
197201 fname = tmp_file .name
198202 with open (fname , "w" ) as f :
199203 for coord , radius in zip (coordinates , radii ):
200204 if radius < min_radius :
201205 continue
202- # IMOD needs peculiar whitespace padding
203- x = _pad (coord [2 ])
204- y = _pad (shape [1 ] - coord [1 ])
205- z = _pad (coord [0 ])
206- f .write (f"{ x } { y } { z } { _pad (radius , 2 )} \n " )
207206
207+ if is_3d :
208+ # (z, y, x) indexing
209+ x = _pad (coord [2 ])
210+ y = _pad (shape [1 ] - coord [1 ])
211+ z = _pad (coord [0 ])
212+
213+ else :
214+ # (y, x) indexing, single z-plane
215+ x = _pad (coord [1 ])
216+ y = _pad (shape [0 ] - coord [0 ])
217+ z = _pad (1 )
218+
219+ f .write (f"{ x } { y } { z } { _pad (radius , 2 )} \n " )
208220 cmd = [cmd , "-si" , "-scat" , fname , output_path ]
221+
209222 if color is not None :
210223 assert len (color ) == 3
211224 r , g , b = [str (co ) for co in color ]
@@ -214,6 +227,7 @@ def _pad(inp, n=3):
214227 run (cmd )
215228
216229
230+
217231def write_segmentation_to_imod_as_points (
218232 mrc_path : str ,
219233 segmentation : Union [str , np .ndarray ],
0 commit comments