def test_edge_sym(self): """ Scatter outside four edges """ width = 1.0 kerf = 0.0 height = 1.0 a = fnm.ApertureFloat(1, width, kerf, height) a.c = 1.0 a.f0 = 1.0 a.nSubH = 20 a.nSubW = 20 pos = np.r_[1.5, 0, 5] pos = pos.reshape([1, 3]).astype(np.float32) hp = a.CalcCwFieldFourRef(pos)[1] hpr = np.ones(4) * hp hps = [] for iEdge in range(4): rotm = euler2rot(iEdge * np.pi / 2.0, 0, 0, conv='zxz', intrinsic=True) pos1 = np.dot(rotm, pos.T).astype(np.float32).T hp = a.CalcCwFieldFourRef(pos1)[1] hps.append(hp) self.assertTrue(np.allclose(hps, hpr))
def corners(self): """ Corners of the rectangle ordered clock-wise in the orientation dictated by the 'Euler' angles, the convention and the intrinsic property. """ rotm = euler2rot(self.euler[0],self.euler[1],self.euler[2], conv = self.conv, intrinsic = self.intrinsic) # Ordered clock-wise a = np.array([[1,1],[-1,1],[-1,-1],[1,-1]]) corners = np.c_[a * np.r_[self.hw,self.hh],[0,0,0,0]] corners = np.r_[[np.dot(rotm,corners[i]) + self.center for i in range(4)]] return corners
def corners(self): """ Corners of the rectangle ordered clock-wise in the orientation dictated by the 'Euler' angles, the convention and the intrinsic property. """ rotm = euler2rot(self.euler[0], self.euler[1], self.euler[2], conv=self.conv, intrinsic=self.intrinsic) # Ordered clock-wise a = np.array([[1, 1], [-1, 1], [-1, -1], [1, -1]]) corners = np.c_[a * np.r_[self.hw, self.hh], [0, 0, 0, 0]] corners = np.r_[[ np.dot(rotm, corners[i]) + self.center for i in range(4) ]] return corners
def rotate_axes(self, limits): retval = True maxdiff = 0.0 for alpha in np.r_[limits[0,0]:limits[0,1]:limits[0,2]]: for beta in np.r_[limits[1,0]:limits[1,1]:limits[1,2]]: for gamma in np.r_[limits[2,0]:limits[2,1]:limits[2,2]]: rmat = euler2rot(alpha,beta,gamma,conv='yxy') pos2 = np.dot(rmat,self.pos.T).T pos2 = pos2.astype(np.float32) elements = self.a.elements elements[0,5:8] = [alpha,beta,gamma] self.a.elements = elements self.a.focus = pos2.flatten() _, hp2 = self.a.CalcCwFieldNaive(pos2) hp2 = hp2.flatten() diff = np.abs(self.ref-hp2) / (np.abs(self.ref)+np.abs(hp2)) maxdiff = max(maxdiff, diff[0]) retval = retval and (diff[0] < 0.05) if not(retval): print('max. diff: %f' % maxdiff) return retval
def rotate_axes(self, limits): retval = True maxdiff = 0.0 for alpha in np.r_[limits[0, 0]:limits[0, 1]:limits[0, 2]]: for beta in np.r_[limits[1, 0]:limits[1, 1]:limits[1, 2]]: for gamma in np.r_[limits[2, 0]:limits[2, 1]:limits[2, 2]]: rmat = euler2rot(alpha, beta, gamma, conv='yxy') pos2 = np.dot(rmat, self.pos.T).T pos2 = pos2.astype(np.float32) elements = self.a.elements elements[0, 5:8] = [alpha, beta, gamma] self.a.elements = elements self.a.focus = pos2.flatten() _, hp2 = self.a.CalcCwFieldNaive(pos2) hp2 = hp2.flatten() diff = np.abs(self.ref - hp2) / (np.abs(self.ref) + np.abs(hp2)) maxdiff = max(maxdiff, diff[0]) retval = retval and (diff[0] < 0.05) if not (retval): print('max. diff: %f' % maxdiff) return retval
def convex_array3(*args,**kwargs): """ Tissue-side ceramic radius, azimuth is outer radius """ opt = dotdict({'radius' : 6.1e-2, 'nElements' : 192, 'nSubH' : 1, # Elevation 'nSubW' : 1, # Not used 'pitch' : 2.3e-4, 'kerf' : None, 'height' : 1.0e-2, 'efocus' : 0.0, 'elePlacement' : 'Outer', }) opt.updateset(**kwargs) focus = opt.efocus if (focus == None): focus = 0.0 azR = opt.radius # Arc-length from center to center azArcLength = opt.pitch * (opt.nElements-1.0) azSegment = azArcLength / azR dAz = azSegment / max(opt.nElements - 1.0,1.0) azTanLength = 2.0 * azR * np.tan(dAz/2.0) azAngles = (np.r_[0:opt.nElements] - (opt.nElements - 1.0)/2) * dAz elR = np.sqrt(focus**2 + (opt.height / 2.0)**2) # Sector from outer edge to outer edge elSector = 2.0 * np.arctan2(opt.height/2.0, focus) dEl = elSector / opt.nSubH elChordLength = 2.0 * elR * np.sin(dEl/2.0) if (focus != 0.0): elTanLength = 2.0 * elR * np.tan(dEl/2.0) else: elTanLength = opt.height / 2.0 if opt.elePlacement == 'Outer': elAngles = (np.r_[0:(opt.nSubH)] - (opt.nSubH-1.0)/2.0) * dEl hh = elTanLength / 2.0 else: elAngles = (np.r_[0:(opt.nSubH+1)] - opt.nSubH/2.0) * dEl hh = elChordLength / 2.0 hw = 0.5*(opt.pitch - opt.kerf)#azTanLength / 2.0 rects = [] for iEl in range(opt.nSubH): # Rotation in elevation center = \ np.r_[0.0, np.sin(elAngles[iEl])*elR, -(np.cos(elAngles[iEl])*elR - elR) + azR] # focus replaced by elR for iAz in range(opt.nElements): # Rotation in azimuth rotm = \ euler2rot(azAngles[iAz],0,0,conv='yxz',intrinsic=True) # Rotate about origin center1 = np.dot(rotm,center) - np.r_[0,0,azR] r = rect(hw=hw,hh=hh, center=center1, euler=[azAngles[iAz],elAngles[iEl],0],conv='yxz',intrinsic=True) rects.append(r) elements = np.r_[[rects[i].element() for i in range(len(rects))]] elements = elements.reshape((opt.nElements, opt.nSubH * opt.nSubW, 8)) a = fnm.ApertureFloat() a.subelements = elements.astype(np.float32) return a
def convex_array(*args,**kwargs): opt = dotdict({'radius' : 6.1e-2, 'nElements' : 192, 'nSubH' : 1, # Elevation 'nSubW' : 1, # Not used 'pitch' : None, 'kerf' : None, 'height' : 1.0e-2, 'efocus' : 0.02, 'sector' : 60.0/180 * np.pi, # Redundant }) opt.updateset(**kwargs) half_width = (opt.pitch - opt.kerf) / 2.0 half_height = opt.height / 2.0 R = 1.0 focus = 1.0 bFocused = opt.efocus != None and opt.nSubH > 1 if bFocused: focus = opt.efocus elSector = 2 * np.arctan2(half_height, focus) R = np.sqrt(focus**2 + (half_height)**2) else: elSector = 0 if (opt.sector != None): dAz = opt.sector / max((opt.nElements - 1),1) if (opt.pitch == None): # We compute a pitch based on sector size opt.pitch = 2.0*opt.radius*np.sin(dAz/2.0) print('pitch is %f' % opt.pitch) else: # We compute sector based on pitch opt.sector = \ (opt.nElements - 1) * 2.0 * np.arcsin(0.5 * opt.pitch / opt.radius) dAz = opt.sector / max((opt.nElements - 1),1) azAngles = (np.r_[0:opt.nElements] - (opt.nElements - 1.0)/2) * dAz rects = [] el = 0.0 dEl = elSector / max((opt.nSubH-1),1) elAngles = (np.r_[0:opt.nSubH] - (opt.nSubH - 1.0)/2) * dEl chordLength = \ {True : 2 * focus * np.sin(dEl/2), False : opt.height}[opt.nSubH > 1] R = np.sqrt(focus**2 + (opt.height / 2.0)**2) if opt.kerf == None: opt.kerf = 0.0 half_width = (opt.pitch - opt.kerf) / 2.0 for iAz in range(opt.nElements): for iEl in range(opt.nSubH): # Center position on element center = np.r_[0,0,opt.radius] # Candidate (no rotation is done around elevation focus) center = center + np.r_[0, focus * np.tan(elAngles[iEl]), -(R * np.cos(elAngles[iEl]) - focus) ] rotm = \ euler2rot(azAngles[iAz],0,0,conv='yxz',intrinsic=True) # Rotate about origin center = np.dot(rotm,center) # Translate center = center - [0,0,opt.radius] # Translate sub-elements rots = euler2rot(azAngles[iAz],elAngles[iEl],0,conv='yxz',intrinsic=True) for iSubW in range(opt.nSubW): # Shift center coordinate center1 = center + 2 * half_width/opt.nSubW * rots[:,0] * (iSubW - (opt.nSubW-1)/2.0) r = rect(hw=half_width/opt.nSubW,hh=chordLength/2.0, center=center1, euler=[azAngles[iAz],-elAngles[iEl],0],conv='yxz',intrinsic=True) rects.append(r) elements = np.r_[[rects[i].element() for i in range(len(rects))]] elements = elements.reshape((opt.nElements, opt.nSubH * opt.nSubW, 8)) a = fnm.ApertureFloat() a.subelements = elements.astype(np.float32) return a
def convex_array3(*args, **kwargs): """ Tissue-side ceramic radius, azimuth is outer radius """ opt = dotdict({ 'radius': 6.1e-2, 'nElements': 192, 'nSubH': 1, # Elevation 'nSubW': 1, # Not used 'pitch': 2.3e-4, 'kerf': None, 'height': 1.0e-2, 'efocus': 0.0, 'elePlacement': 'Outer', }) opt.updateset(**kwargs) focus = opt.efocus if (focus == None): focus = 0.0 azR = opt.radius # Arc-length from center to center azArcLength = opt.pitch * (opt.nElements - 1.0) azSegment = azArcLength / azR dAz = azSegment / max(opt.nElements - 1.0, 1.0) azTanLength = 2.0 * azR * np.tan(dAz / 2.0) azAngles = (np.r_[0:opt.nElements] - (opt.nElements - 1.0) / 2) * dAz elR = np.sqrt(focus**2 + (opt.height / 2.0)**2) # Sector from outer edge to outer edge elSector = 2.0 * np.arctan2(opt.height / 2.0, focus) dEl = elSector / opt.nSubH elChordLength = 2.0 * elR * np.sin(dEl / 2.0) if (focus != 0.0): elTanLength = 2.0 * elR * np.tan(dEl / 2.0) else: elTanLength = opt.height / 2.0 if opt.elePlacement == 'Outer': elAngles = (np.r_[0:(opt.nSubH)] - (opt.nSubH - 1.0) / 2.0) * dEl hh = elTanLength / 2.0 else: elAngles = (np.r_[0:(opt.nSubH + 1)] - opt.nSubH / 2.0) * dEl hh = elChordLength / 2.0 hw = 0.5 * (opt.pitch - opt.kerf) #azTanLength / 2.0 rects = [] for iEl in range(opt.nSubH): # Rotation in elevation center = \ np.r_[0.0, np.sin(elAngles[iEl])*elR, -(np.cos(elAngles[iEl])*elR - elR) + azR] # focus replaced by elR for iAz in range(opt.nElements): # Rotation in azimuth rotm = \ euler2rot(azAngles[iAz],0,0,conv='yxz',intrinsic=True) # Rotate about origin center1 = np.dot(rotm, center) - np.r_[0, 0, azR] r = rect(hw=hw, hh=hh, center=center1, euler=[azAngles[iAz], elAngles[iEl], 0], conv='yxz', intrinsic=True) rects.append(r) elements = np.r_[[rects[i].element() for i in range(len(rects))]] elements = elements.reshape((opt.nElements, opt.nSubH * opt.nSubW, 8)) a = fnm.ApertureFloat() a.subelements = elements.astype(np.float32) return a
def convex_array(*args, **kwargs): opt = dotdict({ 'radius': 6.1e-2, 'nElements': 192, 'nSubH': 1, # Elevation 'nSubW': 1, # Not used 'pitch': None, 'kerf': None, 'height': 1.0e-2, 'efocus': 0.02, 'sector': 60.0 / 180 * np.pi, # Redundant }) opt.updateset(**kwargs) half_width = (opt.pitch - opt.kerf) / 2.0 half_height = opt.height / 2.0 R = 1.0 focus = 1.0 bFocused = opt.efocus != None and opt.nSubH > 1 if bFocused: focus = opt.efocus elSector = 2 * np.arctan2(half_height, focus) R = np.sqrt(focus**2 + (half_height)**2) else: elSector = 0 if (opt.sector != None): dAz = opt.sector / max((opt.nElements - 1), 1) if (opt.pitch == None): # We compute a pitch based on sector size opt.pitch = 2.0 * opt.radius * np.sin(dAz / 2.0) print('pitch is %f' % opt.pitch) else: # We compute sector based on pitch opt.sector = \ (opt.nElements - 1) * 2.0 * np.arcsin(0.5 * opt.pitch / opt.radius) dAz = opt.sector / max((opt.nElements - 1), 1) azAngles = (np.r_[0:opt.nElements] - (opt.nElements - 1.0) / 2) * dAz rects = [] el = 0.0 dEl = elSector / max((opt.nSubH - 1), 1) elAngles = (np.r_[0:opt.nSubH] - (opt.nSubH - 1.0) / 2) * dEl chordLength = \ {True : 2 * focus * np.sin(dEl/2), False : opt.height}[opt.nSubH > 1] R = np.sqrt(focus**2 + (opt.height / 2.0)**2) if opt.kerf == None: opt.kerf = 0.0 half_width = (opt.pitch - opt.kerf) / 2.0 for iAz in range(opt.nElements): for iEl in range(opt.nSubH): # Center position on element center = np.r_[0, 0, opt.radius] # Candidate (no rotation is done around elevation focus) center = center + np.r_[0, focus * np.tan(elAngles[iEl]), -(R * np.cos(elAngles[iEl]) - focus)] rotm = \ euler2rot(azAngles[iAz],0,0,conv='yxz',intrinsic=True) # Rotate about origin center = np.dot(rotm, center) # Translate center = center - [0, 0, opt.radius] # Translate sub-elements rots = euler2rot(azAngles[iAz], elAngles[iEl], 0, conv='yxz', intrinsic=True) for iSubW in range(opt.nSubW): # Shift center coordinate center1 = center + 2 * half_width / opt.nSubW * rots[:, 0] * ( iSubW - (opt.nSubW - 1) / 2.0) r = rect(hw=half_width / opt.nSubW, hh=chordLength / 2.0, center=center1, euler=[azAngles[iAz], -elAngles[iEl], 0], conv='yxz', intrinsic=True) rects.append(r) elements = np.r_[[rects[i].element() for i in range(len(rects))]] elements = elements.reshape((opt.nElements, opt.nSubH * opt.nSubW, 8)) a = fnm.ApertureFloat() a.subelements = elements.astype(np.float32) return a