def disambiguate_best_fit_strips(self, potential_strip_locs, M, N, graph): ''' given a list of equally full potential strip locations, assign an objective plausibility score to each strip based on the density of electrodes near missing points in the strip. to do this, we interpolate the missing points based on the available geometry. then we calculate the distances of these points to the nearest unrelated point (to account for image artifacts that may cause us to lose the electrode to a nearby cluster). each individual distance is capped at 2*delta to limit the effect of outliers. we return the sum of each of these distances in the grid as an objective penalty function. the configuration that returns the lowest penalty function is returned along with a list of its points in 3D space, including interpolated points if the strip locations all have the same penalty value, one of them is returned arbitrarily (but not pseudorandomly) ''' if len(potential_strip_locs) == 1: print( 'Only one strip location possible, possibly the result of ' 'user intervention, returning it') else: print '%i potential %ix%i strip locations to check' % ( len(potential_strip_locs), M, N) print potential_strip_locs #graph = self.repr_as_2d_graph(pad_zeros = max(M,N)) best_penalty = np.inf best_points = [] #best_loc = None best_loc = potential_strip_locs[0] origin = v, w = zip(*np.where(graph == 2))[0] #set the critical distance before we start adding points critdist = self.critdist() for r, c, orient in potential_strip_locs: cur_penalty = 0 cur_points = [] interpolated_points = [] interpolated_gridpoints = [] #total_points = 0 strip_graph = (graph[r:r + N, c:c + M] if orient == 'horiz' else graph[c:c + M, r:r + N]) for x, y in zip(*np.where(strip_graph)): #print "Added the existing point (%i,%i)"%(x+r-v,y+c-w) #print ("Added the existing point " # "(%i,%i) which is %s"%(x+c-v,y+r-w, # None if self.get_3d_point((x+c-v, y+r-w)) is None # else 'not None') cur_points.append( self.get_3d_point((x + r - v, y + c - w) if orient == 'horiz' else (x + c - v, y + r - w))) #total_points += 1 print 'starting disambiguation with %i points' % (len(cur_points)) iter = 0 while len(interpolated_points) < M * N - len(cur_points): #for iter in xrange(M*N): iter += 1 if iter > M * N: raise ValueError("Infinite loop") for x, y in zip(*np.where(strip_graph == 0)): i = x + r - v if orient == 'horiz' else x + c - v j = y + c - w if orient == 'horiz' else y + r - w if (i, j) in interpolated_gridpoints: continue connectivity, orientation = ( self.get_local_connectivity_2d((i, j))) pN = self.get_3d_point((i, j + 1)) pE = self.get_3d_point((i + 1, j)) pS = self.get_3d_point((i, j - 1)) pW = self.get_3d_point((i - 1, j)) pNN = self.get_3d_point((i, j + 2)) pEE = self.get_3d_point((i + 2, j)) pSS = self.get_3d_point((i, j - 2)) pWW = self.get_3d_point((i - 2, j)) if connectivity == 'FULL': pInterp = (pN + pE + pS + pW) / 4 elif connectivity == 'TSHAPE': if orientation in ('north', 'south'): pInterp = (pE + pW) / 2 else: pInterp = (pN + pS) / 2 elif connectivity == 'LINE': if orientation in ('north', 'south'): pInterp = (pN + pS) / 2 else: pInterp = (pE + pW) / 2 elif connectivity in ('MOTIF', 'LEAF'): if pNN is not None and (orientation == 'north' or (connectivity == 'MOTIF' and orientation == 'east')): pInterp = 2 * pN - pNN elif pWW is not None and (orientation == 'west' or (connectivity == 'MOTIF' and orientation == 'north')): pInterp = 2 * pW - pWW elif pSS is not None and (orientation == 'south' or (connectivity == 'MOTIF' and orientation == 'west')): pInterp = 2 * pS - pSS elif pEE is not None and (orientation == 'east' or (connectivity == 'MOTIF' and orientation == 'south')): pInterp = 2 * pE - pEE else: continue # if we found a singleton it means not enough of the other # points have been interpolated yet # we pass and wait elif connectivity == 'SINGLETON': pInterp = None continue #from PyQt4.QtCore import pyqtRemoveInputHook #pyqtRemoveInputHook() #import pdb #pdb.set_trace() if pInterp is None: raise ValueError('Could not interpolate point with ' 'current methods') elif self.get_3d_point((i, j)) is not None: # in case the nonexistent point was added in a # previous iteration dont add it again #if GridPoint(pInterp) in interpolated_gridpoints: # continue # greedily growing the grid here might cause bias. but # check for bugs adding the same point multiple times if (i, j) in interpolated_gridpoints: raise ValueError( "Internal error: should never be" "adding a point that already exists") #otherwise, we added this point on another strip #choice. We should add it to the interpolated #points as normally, but not add the point to the Grid elif GridPoint(pInterp) in self.connectivity: # suppose the exact point to be interpolated at i,j is actually # already in the grid at m,n and the grid has horribly # twisted over itself. To gracefully handle this (the # solution will be bad), we would like to allow this # configuration. # we previously got an error because we can't add two points # (i,j) and also (m,n) with the same coordinates. # give it a different value px, py, pz = pInterp pInterp = np.array((px + .01, py, pz)) print 'adding the repeat point (%i,%i), %s' % ( i, j, str(pInterp)) self.add_point(pInterp, (i, j)) if graph[i, j] == 0: graph[i, j] = 1 else: print 'adding the point (%i,%i), %s' % (i, j, str(pInterp)) self.add_point(pInterp, (i, j)) if graph[i, j] == 0: graph[i, j] = 1 #total_points += 1 interpolated_points.append(pInterp) #interpolated_gridpoints.append(GridPoint(pInterp)) interpolated_gridpoints.append((i, j)) points_left = rm_pts(cur_points, self.all_elecs) if len(points_left) > 0: pPenalty, _ = find_nearest_pt( pInterp, rm_pts(cur_points, self.all_elecs)) cur_penalty += np.min((norm(pPenalty - pInterp), 2 * self.delta * critdist)) else: cur_penalty = np.inf #update the winner if cur_penalty < best_penalty: best_penalty = cur_penalty best_points = cur_points best_points.extend(interpolated_points) best_loc = (r, c, orient) return best_loc, best_points
def disambiguate_best_fit_strips(self, potential_strip_locs, M, N): ''' given a list of equally full potential strip locations, assign an objective plausibility score to each strip based on the density of electrodes near missing points in the strip. to do this, we interpolate the missing points based on the available geometry. then we calculate the distances of these points to the nearest unrelated point (to account for image artifacts that may cause us to lose the electrode to a nearby cluster). each individual distance is capped at 2*delta to limit the effect of outliers. we return the sum of each of these distances in the grid as an objective penalty function. the configuration that returns the lowest penalty function is returned along with a list of its points in 3D space, including interpolated points if the strip locations all have the same penalty value, one of them is returned arbitrarily (but not pseudorandomly) ''' if len(potential_strip_locs) == 1: print ('Only one strip location possible, possibly the result of ' 'user intervention, returning it') else: print '%i potential %ix%i strip locations to check' % ( len(potential_strip_locs), M, N) print potential_strip_locs graph = self.repr_as_2d_graph(pad_zeros = max(M,N)) best_penalty = np.inf best_points = [] #best_loc = None best_loc = potential_strip_locs[0] origin = v,w = zip(*np.where(graph==2))[0] #set the critical distance before we start adding points critdist = self.critdist() for r,c,orient in potential_strip_locs: cur_penalty = 0 cur_points = [] interpolated_points = [] interpolated_gridpoints = [] #total_points = 0 strip_graph = (graph[r:r+N,c:c+M] if orient=='horiz' else graph[c:c+M, r:r+N]) for x,y in zip(*np.where(strip_graph)): #print "Added the existing point (%i,%i)"%(x+r-v,y+c-w) #print ("Added the existing point " # "(%i,%i) which is %s"%(x+c-v,y+r-w, # None if self.get_3d_point((x+c-v, y+r-w)) is None # else 'not None') cur_points.append(self.get_3d_point( (x+r-v, y+c-w) if orient=='horiz' else (x+c-v, y+r-w) )) #total_points += 1 print 'starting disambiguation with %i points'%(len(cur_points)) iter = 0 while len(interpolated_points) < M*N - len(cur_points): #for iter in xrange(M*N): iter += 1 if iter > M*N: raise ValueError("Infinite loop") for x,y in zip(*np.where(strip_graph==0)): i = x+r-v if orient=='horiz' else x+c-v j = y+c-w if orient=='horiz' else y+r-w if (i,j) in interpolated_gridpoints: continue connectivity, orientation = (self. get_local_connectivity_2d( (i,j) )) pN = self.get_3d_point( (i, j+1) ) pE = self.get_3d_point( (i+1, j) ) pS = self.get_3d_point( (i, j-1) ) pW = self.get_3d_point( (i-1, j) ) pNN = self.get_3d_point( (i, j+2) ) pEE = self.get_3d_point( (i+2, j) ) pSS = self.get_3d_point( (i, j-2) ) pWW = self.get_3d_point( (i-2, j) ) if connectivity == 'FULL': pInterp = (pN+pE+pS+pW)/4 elif connectivity=='TSHAPE': if orientation in ('north','south'): pInterp = (pE+pW)/2 else: pInterp = (pN+pS)/2 elif connectivity=='LINE': if orientation in ('north','south'): pInterp = (pN+pS)/2 else: pInterp = (pE+pW)/2 elif connectivity in ('MOTIF', 'LEAF'): if pNN is not None and (orientation=='north' or (connectivity=='MOTIF' and orientation=='east')): pInterp = 2*pN-pNN elif pWW is not None and (orientation=='west' or (connectivity=='MOTIF' and orientation=='north')): pInterp = 2*pW-pWW elif pSS is not None and (orientation=='south' or (connectivity=='MOTIF' and orientation=='west')): pInterp = 2*pS-pSS elif pEE is not None and (orientation=='east' or (connectivity=='MOTIF' and orientation=='south')): pInterp = 2*pE-pEE else: continue # if we found a singleton it means not enough of the other # points have been interpolated yet # we pass and wait elif connectivity == 'SINGLETON': pInterp = None continue if pInterp is None: raise ValueError('Could not interpolate point with ' 'current methods') elif self.get_3d_point((i,j)) is not None: # in case the nonexistent point was added in a # previous iteration dont add it again #if GridPoint(pInterp) in interpolated_gridpoints: # continue # greedily growing the grid here might cause bias. but # check for bugs adding the same point multiple times if (i,j) in interpolated_gridpoints: raise ValueError("Internal error: should never be" "adding a point that already exists") #otherwise, we added this point on another strip #choice. We should add it to the interpolated #points as normally, but not add the point to the Grid else: print 'adding the point (%i,%i), %s'%(i,j,str(pInterp)) self.add_point(pInterp, (i,j)) #total_points += 1 interpolated_points.append(pInterp) #interpolated_gridpoints.append(GridPoint(pInterp)) interpolated_gridpoints.append((i,j)) points_left = rm_pts(cur_points, self.all_elecs) if len(points_left) > 0: pPenalty, _ = find_nearest_pt(pInterp, rm_pts(cur_points, self.all_elecs)) cur_penalty += np.min((norm(pPenalty-pInterp), 2*self.delta*critdist)) else: cur_penalty = np.inf #update the winner if cur_penalty < best_penalty: best_penalty = cur_penalty best_points = cur_points best_points.extend(interpolated_points) best_loc = (r,c,orient) return best_loc, best_points
def remaining_points(self): return rm_pts(self.points, self.all_elecs)
def remaining_points(self): return rm_pts( self.points, self.all_elecs )