src.acoustools.Utilities.Utilities
1from torch import Tensor 2import torch 3from typing import Literal, Iterable 4 5 6def is_batched_points(points:Tensor) -> bool: 7 ''' 8 :param points: `Tensor` of points 9 :return: `True` is points has a batched shape 10 ''' 11 if len(points.shape)> 2 : 12 return True 13 else: 14 return False 15 16 17 18def permute_points(points: Tensor,index: int,axis:int=0) -> Tensor: 19 ''' 20 Permutes axis of a tensor \n 21 :param points: Tensor to permute 22 :param index: Indexes describing order to perumte to 23 :param axis: Axis to permute. Default `0` 24 :return: permuted points 25 ''' 26 if axis == 0: 27 return points[index,:,:,:] 28 if axis == 1: 29 return points[:,index,:,:] 30 if axis == 2: 31 return points[:,:,index,:] 32 if axis == 3: 33 return points[:,:,:,index] 34 35 36def convert_to_complex(matrix: Tensor) -> Tensor: 37 ''' 38 Comverts a real tensor of shape `B x M x N` to a complex tensor of shape `B x M/2 x N` 39 :param matrix: Matrix to convert 40 :return: converted complex tensor 41 ''' 42 # B x 1024 x N (real) -> B x N x 512 x 2 -> B x 512 x N (complex) 43 matrix = torch.permute(matrix,(0,2,1)) 44 matrix = matrix.view((matrix.shape[0],matrix.shape[1],-1,2)) 45 matrix = torch.view_as_complex(matrix.contiguous()) 46 return torch.permute(matrix,(0,2,1)) 47 48 49 50 51def return_matrix(x,y,mat=None): 52 ''' 53 @private 54 Returns value of parameter `mat` - For compatibility with other functions 55 ''' 56 return mat 57 58 59def get_convert_indexes(n:int=512, single_mode:Literal['bottom','top']='bottom') -> Tensor: 60 ''' 61 Gets indexes to swap between transducer order for acoustools and OpenMPD for two boards\n 62 Use: `row = row[:,FLIP_INDEXES]` and invert with `_,INVIDX = torch.sort(IDX)` 63 :param n: number of Transducers 64 :param single_mode: When using only one board is that board a top or bottom baord. Default bottom 65 :return: Indexes 66 ''' 67 68 indexes = torch.arange(0,n) 69 # # Flip top board 70 # if single_mode.lower() == 'top': 71 # indexes[:256] = torch.flip(indexes[:256],dims=[0]) 72 # elif single_mode.lower() == 'bottom': 73 # indexes[:256] = torch.flatten(torch.flip(torch.reshape(indexes[:256],(16,-1)),dims=[1])) 74 75 indexes[:256] = torch.flip(indexes[:256],dims=[0]) 76 77 if n > 256: 78 indexes[256:] = torch.flatten(torch.flip(torch.reshape(indexes[256:],(16,-1)),dims=[1])) 79 80 return indexes 81 82def batch_list(iterable:Iterable, batch:int=32): 83 ''' 84 Split an iterable into batch sized pieces\n 85 :param iterable: The iterable to batch 86 :param batch: The size to batch 87 ``` 88 x = range(100) 89 for b in batch_list(x): 90 print(b) 91 ``` 92 ''' 93 i = 0 94 while i <= len(iterable): 95 if i + batch <= len(iterable): 96 yield iterable[i:i+batch] 97 else: 98 yield iterable[i:] 99 i += batch 100 101def get_rows_in(a_centres, b_centres, expand = True): 102 ''' 103 Takes two tensors and returns a mask for `a_centres` where a value of true means that row exists in `b_centres` \\ 104 Asssumes in form 1x3xN -> returns mask over dim 1\\ 105 `a_centres` Tensor of points to check for inclusion in `b_centres` \\ 106 `b_centres` Tensor of points which may or maynot contain some number of points in `a_centres`\\ 107 `expand` if True returns mask as `1x3xN` if False returns mask as `1xN`. Default: True\\ 108 Returns mask for all rows in `a_centres` which are in `b_centres` 109 ''' 110 111 M = a_centres.shape[2] #Number of total elements 112 R = b_centres.shape[2] #Number of elements in b 113 114 a_reshape = torch.unsqueeze(a_centres,3).expand(-1, -1, -1, R) 115 b_reshape = torch.unsqueeze(b_centres,2).expand(-1, -1, M, -1) 116 117 mask = b_reshape == a_reshape 118 mask = mask.all(dim=1).any(dim=2) 119 120 if expand: 121 return mask.unsqueeze(1).expand(-1,3,-1) 122 else: 123 return mask
7def is_batched_points(points:Tensor) -> bool: 8 ''' 9 :param points: `Tensor` of points 10 :return: `True` is points has a batched shape 11 ''' 12 if len(points.shape)> 2 : 13 return True 14 else: 15 return False
Parameters
- points:
Tensorof points
Returns
Trueis points has a batched shape
19def permute_points(points: Tensor,index: int,axis:int=0) -> Tensor: 20 ''' 21 Permutes axis of a tensor \n 22 :param points: Tensor to permute 23 :param index: Indexes describing order to perumte to 24 :param axis: Axis to permute. Default `0` 25 :return: permuted points 26 ''' 27 if axis == 0: 28 return points[index,:,:,:] 29 if axis == 1: 30 return points[:,index,:,:] 31 if axis == 2: 32 return points[:,:,index,:] 33 if axis == 3: 34 return points[:,:,:,index]
Permutes axis of a tensor
Parameters
- points: Tensor to permute
- index: Indexes describing order to perumte to
- axis: Axis to permute. Default
0
Returns
permuted points
37def convert_to_complex(matrix: Tensor) -> Tensor: 38 ''' 39 Comverts a real tensor of shape `B x M x N` to a complex tensor of shape `B x M/2 x N` 40 :param matrix: Matrix to convert 41 :return: converted complex tensor 42 ''' 43 # B x 1024 x N (real) -> B x N x 512 x 2 -> B x 512 x N (complex) 44 matrix = torch.permute(matrix,(0,2,1)) 45 matrix = matrix.view((matrix.shape[0],matrix.shape[1],-1,2)) 46 matrix = torch.view_as_complex(matrix.contiguous()) 47 return torch.permute(matrix,(0,2,1))
Comverts a real tensor of shape B x M x N to a complex tensor of shape B x M/2 x N
Parameters
- matrix: Matrix to convert
Returns
converted complex tensor
60def get_convert_indexes(n:int=512, single_mode:Literal['bottom','top']='bottom') -> Tensor: 61 ''' 62 Gets indexes to swap between transducer order for acoustools and OpenMPD for two boards\n 63 Use: `row = row[:,FLIP_INDEXES]` and invert with `_,INVIDX = torch.sort(IDX)` 64 :param n: number of Transducers 65 :param single_mode: When using only one board is that board a top or bottom baord. Default bottom 66 :return: Indexes 67 ''' 68 69 indexes = torch.arange(0,n) 70 # # Flip top board 71 # if single_mode.lower() == 'top': 72 # indexes[:256] = torch.flip(indexes[:256],dims=[0]) 73 # elif single_mode.lower() == 'bottom': 74 # indexes[:256] = torch.flatten(torch.flip(torch.reshape(indexes[:256],(16,-1)),dims=[1])) 75 76 indexes[:256] = torch.flip(indexes[:256],dims=[0]) 77 78 if n > 256: 79 indexes[256:] = torch.flatten(torch.flip(torch.reshape(indexes[256:],(16,-1)),dims=[1])) 80 81 return indexes
Gets indexes to swap between transducer order for acoustools and OpenMPD for two boards
Use: row = row[:,FLIP_INDEXES] and invert with _,INVIDX = torch.sort(IDX)
Parameters
- n: number of Transducers
- single_mode: When using only one board is that board a top or bottom baord. Default bottom
Returns
Indexes
83def batch_list(iterable:Iterable, batch:int=32): 84 ''' 85 Split an iterable into batch sized pieces\n 86 :param iterable: The iterable to batch 87 :param batch: The size to batch 88 ``` 89 x = range(100) 90 for b in batch_list(x): 91 print(b) 92 ``` 93 ''' 94 i = 0 95 while i <= len(iterable): 96 if i + batch <= len(iterable): 97 yield iterable[i:i+batch] 98 else: 99 yield iterable[i:] 100 i += batch
Split an iterable into batch sized pieces
Parameters
- iterable: The iterable to batch
- batch: The size to batch
x = range(100)
for b in batch_list(x):
print(b)
102def get_rows_in(a_centres, b_centres, expand = True): 103 ''' 104 Takes two tensors and returns a mask for `a_centres` where a value of true means that row exists in `b_centres` \\ 105 Asssumes in form 1x3xN -> returns mask over dim 1\\ 106 `a_centres` Tensor of points to check for inclusion in `b_centres` \\ 107 `b_centres` Tensor of points which may or maynot contain some number of points in `a_centres`\\ 108 `expand` if True returns mask as `1x3xN` if False returns mask as `1xN`. Default: True\\ 109 Returns mask for all rows in `a_centres` which are in `b_centres` 110 ''' 111 112 M = a_centres.shape[2] #Number of total elements 113 R = b_centres.shape[2] #Number of elements in b 114 115 a_reshape = torch.unsqueeze(a_centres,3).expand(-1, -1, -1, R) 116 b_reshape = torch.unsqueeze(b_centres,2).expand(-1, -1, M, -1) 117 118 mask = b_reshape == a_reshape 119 mask = mask.all(dim=1).any(dim=2) 120 121 if expand: 122 return mask.unsqueeze(1).expand(-1,3,-1) 123 else: 124 return mask
Takes two tensors and returns a mask for a_centres where a value of true means that row exists in b_centres \
Asssumes in form 1x3xN -> returns mask over dim 1\
a_centres Tensor of points to check for inclusion in b_centres \
b_centres Tensor of points which may or maynot contain some number of points in a_centres\
expand if True returns mask as 1x3xN if False returns mask as 1xN. Default: True\
Returns mask for all rows in a_centres which are in b_centres