src.acoustools.Intepreter

  1from acoustools.Utilities import create_points, TOP_BOARD, BOTTOM_BOARD, TRANSDUCERS, add_lev_sig
  2from acoustools.Solvers import wgs, gspat, iterative_backpropagation, naive, gorkov_target
  3from acoustools.Levitator import LevitatorController
  4from acoustools.Mesh import load_scatterer
  5from acoustools.BEM import compute_E, get_cache_or_compute_H
  6
  7import torch, time, pickle
  8from vedo import Mesh
  9from torch import Tensor
 10from types import FunctionType
 11
 12
 13def read_lcode(pth:str, ids:tuple[int]=(1000,), mesh:Mesh=None, thickness:float=0.001, BEM_path='../BEMMedia', 
 14               save_holo_name:str|None=None, wait_for_key_press:bool=False, C0_function:FunctionType|None = None, C0_params:dict={}, 
 15               extruder:Tensor|None = None, print_eval:bool=False, return_holos:bool=False, points_per_batch:int=1):
 16    '''
 17    Reads lcode and runs the commands on the levitator device \n
 18    :param pth: Path to lcode file
 19    :param ids: Ids for the levitator 
 20    :param mesh: Mesh to be printed
 21    :param thickness: The wall thickness of the object
 22    :param BEM_path: Path to BEM folder
 23    :param save_holo_name: Out to save holograms to, if any:
 24    :param wait_for_key_press: If true will wait for keypress after first hologram
 25    :param C0_function: Function to use when C0 command seen
 26    :param C0_params: Parameters for the function to use when C0 command seen
 27    :params print_eval: If True will print memory and time used
 28    :params return_holos: If True will save a return holograms
 29    '''
 30
 31    iterations = 100
 32    board = TOP_BOARD
 33    A = None
 34    H = None
 35    solver = wgs
 36    delay = 0
 37    layer_z = 0
 38    cut_mesh = None
 39    in_function = None
 40
 41    target_U = None
 42    target_P = None
 43
 44    reflector = None
 45
 46    current_points = []
 47    if extruder is None:
 48        extruder = create_points(1,1,0,-0.04, 0.04)
 49        
 50    extruder_text = str(extruder[:,0].item()) + ',' + str(extruder[:,1].item()) + ',' + str(extruder[:,2].item())
 51    last_L = 'L2'
 52
 53    functions = {}
 54
 55    start_from_focal_point = ['L0','L1','L2','L3']
 56    signature = ['Focal','Trap','Twin','Vortex']
 57
 58    name_to_solver = {'wgs':wgs,'gspat':gspat, 'iterative_backpropagation':iterative_backpropagation,'naive':naive, 'gorkov_target':gorkov_target}
 59
 60    lev = LevitatorController(ids=ids)
 61
 62    t0 = time.time_ns()
 63    done_one_holo= False
 64    with open(pth,'r') as file:
 65        lines = file.read().rstrip().replace(';','').split('\n')
 66        # lines=lines[:-1]
 67        N_lines = len(lines)
 68
 69        total_size = 0
 70        holograms = []
 71        for i,line in enumerate(lines):
 72            if print_eval: print(f"{i}/{len(lines)}", end='\r')
 73            line = line.rstrip()
 74            if  (line[0] != '#'): #ignore comments
 75                line = line.split('#')[0] #ignore comments
 76                groups = line.split(':')
 77                command = groups[0]
 78
 79                if command.startswith('F'): #the command starts a Functions 
 80                    xs = functions[command]
 81
 82                    lev.levitate(xs)
 83                    
 84        
 85                elif command in start_from_focal_point:
 86                    current_points.append(groups[1:])
 87                    if len(current_points) >= points_per_batch or (i + points_per_batch) >= points_per_batch:
 88                        x = L0(*current_points, iterations=iterations, board=board, A=A, solver=solver, mesh=cut_mesh,
 89                            BEM_path=BEM_path, H=H, U_target=target_U, reflector=reflector)
 90                        sig = signature[start_from_focal_point.index(command)]
 91                        x = add_lev_sig(x, board=board,mode=sig)
 92                        last_L = command
 93
 94                        if in_function is not None:
 95                            functions[in_function].append(x)
 96
 97
 98                        total_size += x.element_size() * x.nelement()
 99                        if save_holo_name is not None or return_holos: 
100                            holograms.append(x)
101                        lev.levitate(x)
102
103            
104
105                        # layer_z = float(groups[1].split(',')[2])
106
107                elif command == 'L4':
108                    lev.turn_off()
109                elif command == 'C0':
110                    current_points_ext = current_points
111                    current_points_ext.append(extruder_text)
112                    x = L0(*current_points_ext, iterations=iterations, board=board, A=A, solver=solver, 
113                           mesh=cut_mesh,BEM_path=BEM_path, H=H, reflector=reflector)
114                    try:
115                        sig = signature[start_from_focal_point.index(command)]
116                    except ValueError as e:
117                        sig = 'Twin'
118
119                    x = add_lev_sig(x, board=board,mode=sig)
120                                            
121                    total_size += x.element_size() * x.nelement()
122                    if save_holo_name is not None or return_holos: holograms.append(x.clone())
123                    lev.levitate(x)
124
125                    if wait_for_key_press :
126                        input('Press enter to start...')
127                    
128                    if C0_function is not None:                    
129                        C0_function(**C0_params)
130
131                    else:
132                        C0()
133                elif command == 'C1':
134                    C1()
135                elif command == 'C2':
136                    C2()
137                elif command == 'C3':
138                    time.sleep(float(groups[1])/1000)
139                elif command == 'C4':
140                    delay = float(groups[1])/1000
141                elif command == 'C5':
142                    solver= name_to_solver[groups[1].lower()]
143                elif command == 'C6':
144                    for group in groups:
145                        if "I" in group:
146                            it = group.split("I")[-1]
147                            iterations = int(it)
148                        if "U" in group:
149                            U = group.split("U")[-1]
150                            target_U = float(U)
151                        if "P" in group:
152                            P = group.split("P")[-1]
153                            target_P = float(P)
154                elif command == 'C7':
155                    board = TRANSDUCERS
156                elif command == 'C8':
157                    board = TOP_BOARD
158                elif command == 'C9':
159                    board = BOTTOM_BOARD
160                elif command == 'C10':
161                    print('C10 Currently Disabled...')
162                    # cut_mesh = cut_mesh_to_walls(mesh, layer_z=layer_z, wall_thickness=thickness)
163                    # H = get_cache_or_compute_H(cut_mesh,board=board,path=BEM_path)
164                elif command == 'C11':
165                    frame_rate = float(groups[1])
166                    lev.set_frame_rate(frame_rate)
167                elif command == 'C12':
168                    z = float(groups[1])
169                    reflector = load_scatterer(BEM_path+'/flat-lam2.stl', dz=z)
170                    H = get_cache_or_compute_H(reflector,board=board,path=BEM_path)
171                elif command == 'function':
172                    name = groups[1]
173                    in_function = name
174                    functions[name] = []
175                elif command == 'end':
176                    name = groups[1]
177                    in_function = None
178                elif command.startswith('O'):
179                    pass
180                else:
181                    raise NotImplementedError(command)
182                
183                if delay > 0: time.sleep(delay)
184
185    t1 = time.time_ns()
186    if print_eval:
187        print((t1-t0)/1e9,'seconds')
188        print(total_size/1e6, 'MB')
189    if save_holo_name is not None: pickle.dump(holograms, open(save_holo_name,'wb'))
190    if return_holos: return holograms
191
192def L0(*args, solver:FunctionType=wgs, iterations:int=50, board:Tensor=TOP_BOARD, A:Tensor=None, 
193       mesh:Mesh=None, BEM_path:str='', H:Tensor=None, reflector:Mesh=None, U_target=None):
194    '''
195    @private
196    '''
197    batches = []
198    for batch in args:
199        ps = []
200        for group in batch:
201            group = [float(g) for g in group.split(',')]
202            p = create_points(1,1,group[0], group[1], group[2])
203            ps.append(p)
204        points = torch.concatenate(ps, dim=2) 
205        batches.append(points)
206    points = torch.concatenate(batches, dim=0) 
207
208    if (mesh is not None or reflector is not None) and A is None:
209        if mesh is None and reflector is not None:
210            A = compute_E(reflector, points=points, board=board, print_lines=False, path=BEM_path,H=H)
211        else:
212            A = compute_E(mesh, points=points, board=board, print_lines=False, path=BEM_path,H=H)
213    
214    if solver == wgs:
215        x = wgs(points, iter=iterations,board=board, A=A )
216    elif solver == gspat:
217        x = gspat(points, board=board,A=A,iterations=iterations)
218    elif solver == iterative_backpropagation:
219        x = iterative_backpropagation(points, iterations=iterations, board=board, A=A)
220    elif solver == naive:
221        x = naive(points, board=board)
222    elif solver == gorkov_target:
223        x = gorkov_target(p,board=board, U_targets=U_target, reflector=reflector, path=BEM_path)
224    else:
225        raise NotImplementedError()
226    
227
228    return x
229
230def C0(): #Dispense Droplets
231    '''
232    @private
233    '''
234    pass
235
236def C1(): #Activate UV
237    '''
238    @private
239    '''
240    pass
241
242def C2(): #Turn off UV
243    '''
244    @private
245    '''
246    pass
def read_lcode( pth: str, ids: tuple[int] = (1000,), mesh: vedo.mesh.Mesh = None, thickness: float = 0.001, BEM_path='../BEMMedia', save_holo_name: str | None = None, wait_for_key_press: bool = False, C0_function: function | None = None, C0_params: dict = {}, extruder: torch.Tensor | None = None, print_eval: bool = False, return_holos: bool = False, points_per_batch: int = 1):
 14def read_lcode(pth:str, ids:tuple[int]=(1000,), mesh:Mesh=None, thickness:float=0.001, BEM_path='../BEMMedia', 
 15               save_holo_name:str|None=None, wait_for_key_press:bool=False, C0_function:FunctionType|None = None, C0_params:dict={}, 
 16               extruder:Tensor|None = None, print_eval:bool=False, return_holos:bool=False, points_per_batch:int=1):
 17    '''
 18    Reads lcode and runs the commands on the levitator device \n
 19    :param pth: Path to lcode file
 20    :param ids: Ids for the levitator 
 21    :param mesh: Mesh to be printed
 22    :param thickness: The wall thickness of the object
 23    :param BEM_path: Path to BEM folder
 24    :param save_holo_name: Out to save holograms to, if any:
 25    :param wait_for_key_press: If true will wait for keypress after first hologram
 26    :param C0_function: Function to use when C0 command seen
 27    :param C0_params: Parameters for the function to use when C0 command seen
 28    :params print_eval: If True will print memory and time used
 29    :params return_holos: If True will save a return holograms
 30    '''
 31
 32    iterations = 100
 33    board = TOP_BOARD
 34    A = None
 35    H = None
 36    solver = wgs
 37    delay = 0
 38    layer_z = 0
 39    cut_mesh = None
 40    in_function = None
 41
 42    target_U = None
 43    target_P = None
 44
 45    reflector = None
 46
 47    current_points = []
 48    if extruder is None:
 49        extruder = create_points(1,1,0,-0.04, 0.04)
 50        
 51    extruder_text = str(extruder[:,0].item()) + ',' + str(extruder[:,1].item()) + ',' + str(extruder[:,2].item())
 52    last_L = 'L2'
 53
 54    functions = {}
 55
 56    start_from_focal_point = ['L0','L1','L2','L3']
 57    signature = ['Focal','Trap','Twin','Vortex']
 58
 59    name_to_solver = {'wgs':wgs,'gspat':gspat, 'iterative_backpropagation':iterative_backpropagation,'naive':naive, 'gorkov_target':gorkov_target}
 60
 61    lev = LevitatorController(ids=ids)
 62
 63    t0 = time.time_ns()
 64    done_one_holo= False
 65    with open(pth,'r') as file:
 66        lines = file.read().rstrip().replace(';','').split('\n')
 67        # lines=lines[:-1]
 68        N_lines = len(lines)
 69
 70        total_size = 0
 71        holograms = []
 72        for i,line in enumerate(lines):
 73            if print_eval: print(f"{i}/{len(lines)}", end='\r')
 74            line = line.rstrip()
 75            if  (line[0] != '#'): #ignore comments
 76                line = line.split('#')[0] #ignore comments
 77                groups = line.split(':')
 78                command = groups[0]
 79
 80                if command.startswith('F'): #the command starts a Functions 
 81                    xs = functions[command]
 82
 83                    lev.levitate(xs)
 84                    
 85        
 86                elif command in start_from_focal_point:
 87                    current_points.append(groups[1:])
 88                    if len(current_points) >= points_per_batch or (i + points_per_batch) >= points_per_batch:
 89                        x = L0(*current_points, iterations=iterations, board=board, A=A, solver=solver, mesh=cut_mesh,
 90                            BEM_path=BEM_path, H=H, U_target=target_U, reflector=reflector)
 91                        sig = signature[start_from_focal_point.index(command)]
 92                        x = add_lev_sig(x, board=board,mode=sig)
 93                        last_L = command
 94
 95                        if in_function is not None:
 96                            functions[in_function].append(x)
 97
 98
 99                        total_size += x.element_size() * x.nelement()
100                        if save_holo_name is not None or return_holos: 
101                            holograms.append(x)
102                        lev.levitate(x)
103
104            
105
106                        # layer_z = float(groups[1].split(',')[2])
107
108                elif command == 'L4':
109                    lev.turn_off()
110                elif command == 'C0':
111                    current_points_ext = current_points
112                    current_points_ext.append(extruder_text)
113                    x = L0(*current_points_ext, iterations=iterations, board=board, A=A, solver=solver, 
114                           mesh=cut_mesh,BEM_path=BEM_path, H=H, reflector=reflector)
115                    try:
116                        sig = signature[start_from_focal_point.index(command)]
117                    except ValueError as e:
118                        sig = 'Twin'
119
120                    x = add_lev_sig(x, board=board,mode=sig)
121                                            
122                    total_size += x.element_size() * x.nelement()
123                    if save_holo_name is not None or return_holos: holograms.append(x.clone())
124                    lev.levitate(x)
125
126                    if wait_for_key_press :
127                        input('Press enter to start...')
128                    
129                    if C0_function is not None:                    
130                        C0_function(**C0_params)
131
132                    else:
133                        C0()
134                elif command == 'C1':
135                    C1()
136                elif command == 'C2':
137                    C2()
138                elif command == 'C3':
139                    time.sleep(float(groups[1])/1000)
140                elif command == 'C4':
141                    delay = float(groups[1])/1000
142                elif command == 'C5':
143                    solver= name_to_solver[groups[1].lower()]
144                elif command == 'C6':
145                    for group in groups:
146                        if "I" in group:
147                            it = group.split("I")[-1]
148                            iterations = int(it)
149                        if "U" in group:
150                            U = group.split("U")[-1]
151                            target_U = float(U)
152                        if "P" in group:
153                            P = group.split("P")[-1]
154                            target_P = float(P)
155                elif command == 'C7':
156                    board = TRANSDUCERS
157                elif command == 'C8':
158                    board = TOP_BOARD
159                elif command == 'C9':
160                    board = BOTTOM_BOARD
161                elif command == 'C10':
162                    print('C10 Currently Disabled...')
163                    # cut_mesh = cut_mesh_to_walls(mesh, layer_z=layer_z, wall_thickness=thickness)
164                    # H = get_cache_or_compute_H(cut_mesh,board=board,path=BEM_path)
165                elif command == 'C11':
166                    frame_rate = float(groups[1])
167                    lev.set_frame_rate(frame_rate)
168                elif command == 'C12':
169                    z = float(groups[1])
170                    reflector = load_scatterer(BEM_path+'/flat-lam2.stl', dz=z)
171                    H = get_cache_or_compute_H(reflector,board=board,path=BEM_path)
172                elif command == 'function':
173                    name = groups[1]
174                    in_function = name
175                    functions[name] = []
176                elif command == 'end':
177                    name = groups[1]
178                    in_function = None
179                elif command.startswith('O'):
180                    pass
181                else:
182                    raise NotImplementedError(command)
183                
184                if delay > 0: time.sleep(delay)
185
186    t1 = time.time_ns()
187    if print_eval:
188        print((t1-t0)/1e9,'seconds')
189        print(total_size/1e6, 'MB')
190    if save_holo_name is not None: pickle.dump(holograms, open(save_holo_name,'wb'))
191    if return_holos: return holograms

Reads lcode and runs the commands on the levitator device

Parameters
  • pth: Path to lcode file
  • ids: Ids for the levitator
  • mesh: Mesh to be printed
  • thickness: The wall thickness of the object
  • BEM_path: Path to BEM folder
  • save_holo_name: Out to save holograms to, if any:
  • wait_for_key_press: If true will wait for keypress after first hologram
  • C0_function: Function to use when C0 command seen
  • C0_params: Parameters for the function to use when C0 command seen :params print_eval: If True will print memory and time used :params return_holos: If True will save a return holograms