def test_get_voxels_in_large_range(grid: RectangularGrid): for voxel, distance in grid.get_voxels_in_range(Point(x=4, y=4, z=4), 10): assert distance <= 10 assert grid.is_valid_voxel(voxel)
def test_valid_voxel(grid: RectangularGrid, voxel, valid): assert grid.is_valid_voxel(voxel) == valid
def chemotaxis( self, molecule, drift_lambda, drift_bias, tissue, grid: RectangularGrid, ): # 'molecule' = state.'molecule'.concentration # prob = 0-1 random number to determine which voxel is chosen to move # 1. Get cells that are alive for index in self.alive(): prob = rg.random() # 2. Get voxel for each cell to get molecule in that voxel cell = self[index] vox = grid.get_voxel(cell['point']) # 3. Set prob for neighboring voxels p = [] vox_list = [] p_tot = 0.0 i = -1 # calculate individual probability for x in [0, 1, -1]: for y in [0, 1, -1]: for z in [0, 1, -1]: p.append(0.0) vox_list.append([x, y, z]) i += 1 zk = vox.z + z yj = vox.y + y xi = vox.x + x if grid.is_valid_voxel(Voxel(x=xi, y=yj, z=zk)): if tissue[zk, yj, xi] in [ TissueType.SURFACTANT.value, TissueType.BLOOD.value, TissueType.EPITHELIUM.value, TissueType.PORE.value, ]: p[i] = logistic(molecule[zk, yj, xi], drift_lambda, drift_bias) p_tot += p[i] # scale to sum of probabilities if p_tot: for i in range(len(p)): p[i] = p[i] / p_tot # chose vox from neighbors cum_p = 0.0 for i in range(len(p)): cum_p += p[i] if prob <= cum_p: cell['point'] = Point( x=random.uniform(grid.xv[vox.x + vox_list[i][0]], grid.xv[vox.x + vox_list[i][0] + 1]), y=random.uniform(grid.yv[vox.y + vox_list[i][1]], grid.yv[vox.y + vox_list[i][1] + 1]), z=random.uniform(grid.zv[vox.z + vox_list[i][2]], grid.zv[vox.z + vox_list[i][2] + 1]), ) self.update_voxel_index([index]) break