def add_shape(self, f): #Create shape S = Shape(f, self.R, self.SHAPE_R) #Add to shape list S.shape_num = len(self.shape_list) self.shape_list.append(S) row = [] for k in range(len(self.shape_list)): T = self.shape_list[k] ift = real(ipfft(pft_mult(pft_rotate(S.pft, 2.*pi/6.), T.pft), 2*self.SHAPE_R+1,2*self.SHAPE_R+1)) Spad = imrotate(cpad(S.indicator, array([2*self.SHAPE_R+1,2*self.SHAPE_R+1])), 360./6.) Tpad = cpad(T.indicator, array([2*self.SHAPE_R+1,2*self.SHAPE_R+1])) pind = real(fftconvolve(Spad, Tpad, mode='same')) imshow(pind) imshow(ift) obst = to_ind(pind, 0.001) imshow(obst) cutoff = best_cutoff(ift, obst, S.radius + T.radius) print cutoff imshow(to_ind(ift, cutoff)) row.append(cutoff * self.tarea) self.cutoff_matrix.append(row) return S
def __init__(self, mass_field, R, SHAPE_R): #Set basic parameters self.R = R self.SHAPE_R = SHAPE_R self.mass_field = mass_field self.mass = sum(mass_field.flatten()) #Recenter shape so that its center of mass is at the center of image center = array(ndi.center_of_mass(mass_field)) offset = array(mass_field.shape)/2 - center nshape = (array(mass_field.shape) + 2. * abs(offset)).round() tmp = cpad(mass_field, nshape) self.mass_field = ndi.shift(tmp, offset, order=1) self.center = array(self.mass_field.shape) / 2 assert(self.mass_field.shape[0] <= SHAPE_R) assert(self.mass_field.shape[1] <= SHAPE_R) #Set indicator/shape area self.indicator = to_ind(self.mass_field, 0.01) self.area = sum(self.indicator.flatten()) #Compute moment of inertia and radius self.moment = 0. self.radius = 0. for x,p in ndenumerate(self.mass_field): r = array(x) - self.center self.moment += p * dot(r,r) if(p > 0.01): self.radius = max(self.radius, norm(r)) #Set shape indicator self.shape_num = -1 #Compute polar fourier truncation of indicator pind = cpad(self.indicator, array([2*SHAPE_R+1,2*SHAPE_R+1])) self.pft = pfft(pind, R) ift = real(ipfft(self.pft, pind.shape[0], pind.shape[1])) self.pft[0][0] -= min(ift.flatten()) * ((2. * SHAPE_R + 1) ** 2) #Enforce positivity self.pdft = map(pds.diff, self.pft) #Compute cutoff parameters ift = real(ipfft(self.pft, pind.shape[0], pind.shape[1])) self.cutoff = best_cutoff(ift, pind, self.radius) ind_ift = to_ind(ift, self.cutoff) self.int_res = sum((ift * ind_ift).flatten()) self.ext_res = sum((ift * (1. - ind_ift)).flatten()) self.res_area = sum(ind_ift.flatten()) imshow(pind) imshow(to_ind(ift, self.cutoff)) #Compute residual energy terms self.energy = [] s = real(self.pft[0][0]) * pi for r,l in enumerate(self.pft): s += sum(abs(self.pft[r])) * (r * 2. * pi / len(self.pft[r])) self.energy.append(s) self.total_energy = s for r,e in enumerate(self.energy): self.energy[r] = s - self.energy[r]