def test_closures_dimensions(self): if fnm.ApertureFloat.__dict__.keys().count('RwFloatParamSetMulti') > 0: a = fnm.ApertureFloat(5, 1.0, 0.0, 1.0) if 'FNM_PULSED_WAVE' in fnm.__dict__.keys(): params = [fnm.RwParamType.Excitation, fnm.RwParamType.Impulse] # Variable dimensions for param in params: refValue = np.random.rand(10).astype(np.float32) a.RwFloatParamSetMulti(param, refValue, 1, 10) testValue = a.RwFloatParamGet(param, 1)[1] self.assertTrue(np.all(refValue == testValue)) params = [ fnm.RwParamType.ElementDelays, fnm.RwParamType.Apodization, fnm.RwParamType.Focus, fnm.RwParamType.CenterFocus ] # Fixed dimensions for param in params: refValue = a.RwFloatParamGet(param, 1)[1] refValue = refValue + np.random.rand(len(refValue)).astype( np.float32) a.RwFloatParamSetMulti(param, refValue, 1, len(refValue)) testValue = a.RwFloatParamGet(param, 1)[1] self.assertTrue(np.all(refValue == testValue))
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 test_properties_set(self): setmethods = fnm.ApertureFloat.__swig_setmethods__.keys() if 'FNM_PULSED_WAVE' in fnm.__dict__.keys(): self.assertEqual(len(setmethods), 26) else: assert (len(setmethods) == 17) argss = [[0, 0.1, 0.1, 0.1], [1, 0.1, 0.1, 0.1], [100, 0.1, 0.1, 0.1]] nSetSuccess = 0 testMe = set() method = setmethods[0] try: for args in argss: a = fnm.ApertureFloat(*args) for method in setmethods: if not (method.find('_') == 0): try: value = eval('a.' + method) exec('a.' + method + '=value') nSetSuccess = nSetSuccess + 1 except: print('error setting ' + method) raise (Exception('error setting ' + method)) except: print('error setting ' + method) raise (Exception('error setting ' + method)) self.assertEqual(nSetSuccess / 3, self.nSetMethods)
def field_array(*args, **kwargs): f2data = args[0] (nSubElements, nValues) = f2data.shape assert (nValues == 26) nElements = int(f2data[nSubElements - 1, 0] + 1) nSubElements = int(max(f2data[:, 1]) + 1) f2data = f2data.reshape((nElements, nSubElements, 26)) widths = f2data[:, :, 2] heights = f2data[:, :, 3] tan_xz = f2data[:, :, 5] tan_yz = f2data[:, :, 6] apodization = f2data[:, :, 4] center = f2data[:, :, 7:10] corners = f2data[:, :, 10:22].reshape(nElements, nSubElements, 4, 3) delays = f2data[:, :, 22] if 0: fig = plt.figure() ax = fig.add_subplot(121, projection='3d') rects = [] for iElement in range(nElements): for jElement in range(nSubElements): if 0: show_rect(ax, corners[iElement, jElement]) # Work for focused linear array if 0: ax = fig.add_subplot(122, projection='3d') # TODO: Figure out how (tan_yz,tan_xz) -> euler for iElement in range(nElements): for jElement in range(nSubElements): r = rect(hh=heights[iElement, jElement] / 2.0, hw=widths[iElement, jElement] / 2.0, center=center[iElement, jElement], euler=[ -tan_xz[iElement, jElement], tan_yz[iElement, jElement], 0 ]) rects.append(r) if 0: show_rect(ax, r.corners()) elements = np.r_[[rects[i].element() for i in range(len(rects))]] elements = elements.reshape((nElements, nSubElements, 8)) a = fnm.ApertureFloat() a.subelements = elements.astype(np.float32) return a
def compareWithReference(**kwargs): opt = dotdict({'method0' : 'CalcCwFieldRef', 'method1' : 'CalcCwFieldRef', 'location' : 'inside', 'ndiv' : 2, 'eps' : 1e-5, 'quiet' : False}) opt.update(**kwargs) quiet = opt.quiet areas = [2.0,3.0,4.0,5.0] widths = np.array([areas[0],1.0,areas[2],1.0],dtype=np.float32) heights = np.array([1.0,areas[1],1.0,areas[3]],dtype=np.float32) xsign = np.array([1.0,-1.0,-1.0,1.0],dtype=np.float32) ysign = np.array([1.0,1.0,-1.0,-1.0],dtype=np.float32) # Ensure that we either slightly inside or outside scale = 40.0 * np.finfo(np.float32).eps epss = dict({'inside' : -scale, 'outside' : scale}) ndiv = opt.ndiv iCorners = [0,1,2,3] eps = epss[opt.location] method0 = opt.method0 method1 = opt.method1 scatters = np.c_[(widths+eps)/2.0 * xsign, (heights+eps)/2.0 * ysign, np.ones(4,dtype=np.float32)] if not(quiet): print('Testing: %s vs %s: %s' % (opt.method0,opt.method1, opt.location)) success = True for iCorner in iCorners: a = fnm.ApertureFloat(1, float(widths[iCorner]), float(0.0), float(heights[iCorner])) a.nthreads = 1 a.nDivH = ndiv a.nDivW = ndiv a.f0 = 1 a.c = 1 exec('result0 = a.'+method0+'([scatters[iCorner]])[1].flatten()') exec('result1 = a.'+method1+'([scatters[iCorner]])[1].flatten()') diff = np.abs(result0)-np.abs(result1) reldiff = diff / np.mean(np.abs(result0)+np.abs(result1)) success = success and (reldiff < opt.eps) if not(quiet): print('Relative difference: %f' % (reldiff)) return success
def test_setting_elements(self): a = fnm.ApertureFloat() elements0 = np.random.rand(32, 8).astype(np.float32) a.elements = elements0 elements1 = a.elements self.assertTrue(np.all(elements0 == elements1)) if fnm.ApertureFloat.__dict__.keys().count('RwFloatParamSetMulti') > 0: elements2 = np.random.rand(32, 8).astype(np.float32) a.RwFloatParamSetMulti(fnm.RwParamType.Elements, elements2, 2, 32, 8) elements3 = a.elements self.assertTrue(np.all(elements2 == elements3))
def on_calc_clicked(self): self.btnField.setEnabled(False) self.progressBar.setValue(0) # Get transducer model options = self.proxy.getData() options.ax = self.fig1.gca() options.update(self.gridXYZ.getData()) options.focus = float(self.leFocusDist.text()) options.order = int(self.sboxOrder.value()) options.f0 = float(self.leExcitationFrq.text()) options.f = float(self.leFNumber.text()) # Hack: Find propagator using text instead options.proptype = self.cboxPropagator.currentIndex() options.use_att = self.checkAttenuation.isChecked() dBcmMHz = float(self.leAttenuation.text()) options.alpha = dBcmMHz * 100 / 1e6 * options.f0 * fnm.ApertureFloat.Neper_dB options.beta = options.alpha / options.f0 # TODO: Use model instead options.elePlacement = str(self.cboxElePlacement.currentText()) # Hack: Get simulation type index = self.cboxDomain.currentIndex() options.simtype = index options.fs = float(self.leSampleFrq.text()) # Fractional number of cycles options.nCycles = float(self.leExcitationCycles.text()) # TEST Update options.aperture = fnm.ApertureFloat() # Consider thr = QThread(self) # worker.moveToThread(thr) # connect(worker, SIGNAL(updateprogress), self, updatemyprogress) # connect(thr, SIGNAL(destroyed), worker, SLOT(deleteLater())) # worker->run() # Transducer data worker = ComputeField(0, options) worker.signals.result.connect(self.on_calc_done) self.pool.start(worker)
def test_closures_scalar_float(self): # Not compiling using MSVC 2013 if fnm.ApertureFloat.__dict__.keys().count('RwFloatParamSetMulti') > 0: # TODO: Expose list of properties from C/C++ props = [[fnm.RwParamType.Alpha, 'alpha'], [fnm.RwParamType.Beta, 'beta'], [fnm.RwParamType.C, 'c'], [fnm.RwParamType.F0, 'f0'], [fnm.RwParamType.Fs, 'fs'], [fnm.RwParamType.W, 'w']] a = fnm.ApertureFloat(1, 1.0, 0.0, 1.0) refValue = 0.0 for prop in props: refValue = refValue + 1.0 a.RwFloatParamSetMulti(prop[0], refValue) value = eval('a.' + prop[1]) self.assertEqual(value, refValue) value1 = a.RwFloatParamGet(prop[0], 0)[1] self.assertEqual(value1, refValue)
def setUp(self): width = 1.0 kerf = 0.0 height = 2.0 self.a = fnm.ApertureFloat(1, width, kerf, height) self.a.c = 1.0 self.a.f0 = 1.0 self.nSubH = 20 self.nSubW = 20 # Outside pos = np.r_[3, 2, 5] # Inside pos = np.r_[0.4, 0.2, 5] self.pos = pos.reshape([1, 3]).astype(np.float32) self.a.focus = self.pos.flatten() # Disable phase calculation retval, self.ref = self.a.CalcCwFieldNaive(self.pos)
def test_properties_get(self): # Filter out builtin_function_type getmethods = { k: v for k, v in fnm.ApertureFloat.__swig_getmethods__.iteritems() if type(v) != types.BuiltinFunctionType } # Filter out lambda functions (constructors) getmethods = { k: v for k, v in getmethods.iteritems() if v.func_name != '<lambda>' }.keys() # Update without pulsed waves also if 'FNM_PULSED_WAVE' in fnm.__dict__.keys(): self.assertEqual(len(getmethods), 32) else: self.assertEqual(len(getmethods), 23) argss = [[0, 0.1, 0.1, 0.1], [5, 0.1, 0.1, 0.1], [100, 0.1, 0.1, 0.1]] nGetSuccess = 0 testMe = set() try: for args in argss: a = fnm.ApertureFloat(*args) for method in getmethods: try: value = eval('a.' + method) nGetSuccess = nGetSuccess + 1 except: raise (Exception('error getting ' + method)) except Exception as e: print(e.message) self.assertEqual(nGetSuccess / 3, len(getmethods))
timeString = create_time_string(end - start) print(timeString) plt.figure() result2 = np.real(np.abs(result2)) result2 = result2.reshape((nx, nz)) plt.imshow(log_compress(result2), aspect='auto', extent=np.round(1000 * np.r_[0, 2 * d, -d / 2, d / 2]), interpolation='none') plt.xlabel('Depth [mm]') plt.ylabel('Width [mm]') pos = np.c_[xs.flatten(), ys.flatten(), zs.flatten()].astype(np.float32) a = fnm.ApertureFloat(1, width, kerf, height) a.f0 = f0 a.c = soundspeed a.nDivH = ndiv a.nDivW = ndiv * factor a.apodization = np.ones(1, dtype=np.float32) start = timer() out = a.CalcCwFast(pos)[1] #out = a.CalcCwFieldRef(pos)[1] # Wrong #out = a.CalcCwField2(pos)[1] # Looks okay #out = a.CalcCwField(pos)[1] # Looks okay end = timer() timeString = create_time_string(end - start) print(timeString)
def linear_array3(*args, **kwargs): """ Works for outer/inner radius. Outer is crazy if efocus is 0.0 """ opt = dotdict({ 'nElements': 192, 'nSubH': 1, # Elevation 'elePlacement': 'Outer', 'nSubW': 1, 'pitch': 0.2e-3, 'kerf': 0.2e-4, 'height': 1.0e-2, 'efocus': 0.0 }) opt.update(**kwargs) focus = opt.efocus R = 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 hw = (opt.pitch - opt.kerf) / 2.0 chordLength = 2.0 * R * np.sin(dEl / 2.0) tanLength = 2.0 * R * np.tan(dEl / 2.0) if opt.elePlacement == 'Outer': elAngles = (np.r_[0:(opt.nSubH)] - (opt.nSubH - 1.0) / 2.0) * dEl eleSize = tanLength else: elAngles = (np.r_[0:(opt.nSubH + 1)] - opt.nSubH / 2.0) * dEl eleSize = chordLength # Sagitta (height) of the segment (not used) h = R * (1.0 - np.cos(dEl)) # Height of triangular portion (not used) d = R - h rects = [] if opt.elePlacement == 'Outer': for iElement in range(opt.nElements): for iSubH in range(opt.nSubH): center = \ np.r_[(iElement - (opt.nElements-1.0)/2)*opt.pitch, np.sin(elAngles[iSubH])*R, -(np.cos(elAngles[iSubH])*R - focus)] for iSubW in range(opt.nSubW): center1 = center + \ 2 * hw/opt.nSubW * np.r_[1,0,0] * (iSubW - (opt.nSubW-1)/2.0) r = rect(hw=hw / opt.nSubW, hh=eleSize / 2.0, center=center1, euler=[0, elAngles[iSubH], 0], conv='yxz', intrinsic=True) rects.append(r) else: for iElement in range(opt.nElements): for iSubH in range(opt.nSubH): center = \ np.r_[(iElement - (opt.nElements-1.0)/2)*opt.pitch, 0.5*(np.sin(elAngles[iSubH]) + np.sin(elAngles[iSubH+1]))*R, -(0.5*(np.cos(elAngles[iSubH]) + np.cos(elAngles[iSubH+1]))*R - focus)] for iSubW in range(opt.nSubW): center1 = center + \ 2 * hw/opt.nSubW * np.r_[1,0,0] * (iSubW - (opt.nSubW-1)/2.0) r = rect(hw=hw / opt.nSubW, hh=eleSize / 2.0, center=center1, euler=[ 0, 0.5 * (elAngles[iSubH] + elAngles[iSubH + 1]), 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 test_superposition(self): """ Test superposition with all signs """ hw = 2.0 hh = 1.0 kerf = 0.0 z = 20.0 dx = 0.5 dy = 0.5 a = fnm.ApertureFloat(1, 2 * hw, kerf, 2 * hh) a.f0 = 5 a.c = 1 a.nDivH = 4 a.nDivW = 4 method = a.CalcCwFieldFourRef #method = a.CalcCwFieldRef #method = a.CalcCwFast pos0 = np.r_[hw + dx, hh + dy, z] pos0 = pos0.reshape([1, 3]).astype(np.float32) hpr = method(pos0)[1] pos0 = pos0.flatten() hps = [] # Large rectangle w = abs(pos0[0]) + hw h = abs(pos0[1]) + hh a.elements = np.r_[np.c_[abs(w) / 2.0, abs(h) / 2.0, 0, 0, 0, 0, 0, 0]].astype(np.float32) pos = np.r_[abs(w) / 2.0, abs(h) / 2.0, z] pos = pos.reshape([1, 3]).astype(np.float32) hp = method(pos)[1] hps.append(np.sign(w) * np.sign(h) * hp) # Consider adding sign w = hw - abs(pos0[0]) h = abs(pos0[1]) + hh a.elements = np.r_[np.c_[abs(w) / 2.0, h / 2.0, 0, 0, 0, 0, 0, 0]].astype(np.float32) pos = np.r_[abs(w) / 2.0, abs(h) / 2.0, z] pos = pos.reshape([1, 3]).astype(np.float32) hp = method(pos)[1] hps.append(np.sign(w) * hp) # Consider adding sign w = abs(pos0[0]) + hw h = hh - abs(pos0[1]) a.elements = np.r_[np.c_[w / 2.0, abs(h) / 2.0, 0, 0, 0, 0, 0, 0]].astype(np.float32) pos = np.r_[abs(w) / 2.0, abs(h) / 2.0, z] pos = pos.reshape([1, 3]).astype(np.float32) hp = method(pos)[1] hps.append(np.sign(h) * hp) # Consider adding sign w = hw - abs(pos0[0]) h = hh - abs(pos0[1]) a.elements = np.r_[np.c_[abs(w) / 2.0, abs(h) / 2.0, 0, 0, 0, 0, 0, 0]].astype(np.float32) pos = np.r_[abs(w) / 2.0, abs(h) / 2.0, z] pos = pos.reshape([1, 3]).astype(np.float32) hp = method(pos)[1] hps.append(np.sign(w) * np.sign(h) * hp) hp = np.sum(hps) diff = np.abs(hp - hpr) print(diff) print(abs(hpr))
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
logp[0, 0] = 0 logp[-1, -1] = -dBrange return logp f0 = 1e6 soundspeed = 1500 lambd = soundspeed / f0 width = 5 * lambd height = 7.5 * lambd nElements = 1 fs = 100e6 hh = height / 2.0 hw = width / 2.0 a = fnm.ApertureFloat(1, width, 0.0, height) a.fs = fs a.c = soundspeed a.f0 = f0 nx = 61 nz = 101 # Reduce from 81x101 to 81x86 sym = False # Why do we need symmetry of x (need for compact and ultra) if sym: xs = np.linspace(-1.5 * width / 2, 1.5 * width / 2, nx) else: xs = np.linspace(0, 1.5 * width / 2, nx)
factor = int(height / width) ndiv = 1 rect = rect(hw=width / 2.0, hh=height / 2.0, nAbcissa=[ndiv, ndiv * factor]) k = (2 * np.pi) / lamda start = timer() xs, zs = np.meshgrid(xs, zs, indexing='ij') pos = np.c_[xs.flatten(), np.zeros(nx * nz), zs.flatten()].astype(np.float32) # Fix C++ code # Original a = lib.ApertureFloat(nelex, width, kerf, height) a.f0 = f0 a.c = soundspeed a.nDivW = 20 a.nDivH = 20 a.nthreads = 4 d = nelex * (width + kerf) a.focus = [0, 0, d] out = a.CalcCwFast(pos)[1] end = timer() timeString = create_time_string(end - start) print(timeString) plt.figure()
getmethods = fnm.ApertureFloat.__swig_getmethods__.keys() setmethods = fnm.ApertureFloat.__swig_setmethods__.keys() assert (len(getmethods) == 22) assert (len(setmethods) == 15) argss = [[0, 0.1, 0.1, 0.1], [1, 0.1, 0.1, 0.1], [100, 0.1, 0.1, 0.1]] nGetSuccess = 0 nSetSuccess = 0 doubleSupported = True testMe = set() try: for args in argss: a = fnm.ApertureFloat(*args) for method in getmethods: try: value = eval('a.' + method) nGetSuccess = nGetSuccess + 1 except: raise (Exception('error getting ' + method)) for method in setmethods: if not (method.find('_') == 0): try: value = eval('a.' + method) exec('a.' + method + '=value') nSetSuccess = nSetSuccess + 1 except: print('error setting ' + method) raise (Exception('error setting ' + method))
zs = (np.r_[0:nz]) * dz factor = int(height / width) ndiv = 20 rect = rect(hw=width / 2.0, hh=height / 2.0, nAbcissa=[ndiv, ndiv]) k = (2 * np.pi) / lamda xs, zs = np.meshgrid(xs, zs, indexing='ij') ys = 0.0 * np.ones(xs.shape) pos = np.c_[xs.flatten(), np.zeros(nx * nz), zs.flatten()].astype(np.float32) # Original a = fnm.ApertureFloat(nelex, width, kerf, height) a.f0 = f0 a.c = soundspeed a.nDivW = ndiv a.nDivH = ndiv a.nthreads = 4 d = nelex * (width + kerf) a.focus = [0, 0, d] #a.focus_type = fnm.FocusingType.Pythagorean a.focus_type = fnm.FocusingType.Rayleigh start = timer() out = a.CalcCwFast(pos)[1] #out = a.CalcCwFieldRef(pos)[1] #out = a.CalcCwField(pos)[1]
def compareWithPython(**kwargs): opt = dotdict({ 'show': False, 'method': 'CalcCwFieldRef', 'location': 'inside' }) opt.update(**kwargs) areas = [2.0, 3.0, 4.0, 5.0] widths = np.array([areas[0], 1.0, areas[2], 1.0], dtype=np.float32) heights = np.array([1.0, areas[1], 1.0, areas[3]], dtype=np.float32) xsign = np.array([1.0, -1.0, -1.0, 1.0], dtype=np.float32) ysign = np.array([1.0, 1.0, -1.0, -1.0], dtype=np.float32) show = opt.show # Ensure that we either slightly inside or outside scale = 40.0 * np.finfo(np.float32).eps epss = dict({'inside': -scale, 'outside': scale}) ndiv = 2 iCorners = [0, 1, 2, 3] eps = epss[opt.location] method = opt.method scatters = np.c_[(widths + eps) / 2.0 * xsign, (heights + eps) / 2.0 * ysign, np.ones(4, dtype=np.float32)] print('Testing: %s vs %s: %s' % (opt.method, 'H_accurate (Python)', opt.location)) for iCorner in iCorners: a = fnm.ApertureFloat(1, float(widths[iCorner]), float(0.0), float(heights[iCorner])) a.nthreads = 1 a.nDivH = ndiv a.nDivW = ndiv a.f0 = 1 a.c = 1 if show: a.show() ax = plt.gca() ax.scatter([scatters[iCorner][0]], [scatters[iCorner][1]], [scatters[iCorner][2]], color='black', marker='o', s=20) ax.set_xlim([-widths.max(), widths.max()]) ax.set_ylim([-heights.max(), heights.max()]) ax.set_zlim([-5, 5]) ax.set_aspect('equal') plt.show() exec('result = a.' + method + '([scatters[iCorner]])') r = rect(hw=widths[iCorner] / 2.0, hh=heights[iCorner] / 2.0, center=[0, 0, 0], nAbcissa=ndiv) k = 2 * np.pi / (a.c / a.f0) xs = np.ones((1, 1)) * scatters[iCorner][0] ys = np.ones((1, 1)) * scatters[iCorner][1] zs = np.ones((1, 1)) * scatters[iCorner][2] reference = r.H_accurate(xs, ys, zs, k) assert (np.abs(reference) - np.abs(result[1]) < np.finfo( np.float32).eps) diff = np.abs(reference) - np.abs(result[1]) print('Relative difference: %f' % (diff / np.mean(np.abs(reference) + np.abs(result[1]))))
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 linear_array(*args, **kwargs): """ Key-value arguments: nElements, nSubH, pitch, kerf, height, focus """ opt = dotdict({ 'nElements': 192, 'nSubH': 1, # Elevation 'nSubW': 1, 'pitch': 0.2e-3, 'kerf': 0.2e-4, 'height': 1.0e-2, 'efocus': None }) opt.update(**kwargs) half_width = (opt.pitch - opt.kerf) / 2.0 half_height = opt.height / 2.0 rects = [] focus = 1.0 R = 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 + (opt.height / 2.0)**2) else: elSector = 0 dEl = elSector / max((opt.nSubH - 1), 1) elAngles = (np.r_[0:opt.nSubH] - (opt.nSubH - 1.0) / 2) * dEl if bFocused: chordLength = 2 * focus * np.sin(dEl / 2) else: chordLength = opt.height / opt.nSubH for iElement in range(opt.nElements): for iSubH in range(opt.nSubH): if bFocused: center = np.r_[(iElement - (opt.nElements - 1.0) / 2) * opt.pitch, focus * np.tan(elAngles[iSubH]), -(R * np.cos(elAngles[iSubH]) - focus)] else: center = np.r_[(iElement - (opt.nElements - 1.0) / 2) * opt.pitch, (iSubH - (opt.nSubH - 1.0) / 2.0) * chordLength, 0] for iSubW in range(opt.nSubW): center1 = center + 2 * half_width / opt.nSubW * np.r_[ 1, 0, 0] * (iSubW - (opt.nSubW - 1) / 2.0) r = rect(hw=half_width / opt.nSubW, hh=chordLength / 2.0, center=center1, euler=[0, -elAngles[iSubH], 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 test_setting_subelements(self): a = fnm.ApertureFloat() subelements0 = np.random.rand(32, 4, 8).astype(np.float32) a.subelements = subelements0 subelements1 = a.subelements self.assertTrue(np.all(subelements0 == subelements1))