<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="bbPress/1.0.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>k-Wave User Forum &#187; Topic: Ultrasound B-Mode Phased Array: Image not detected</title>
		<link>http://www.k-wave.org/forum/topic/ultrasound-b-mode-phased-array-image-not-detected</link>
		<description>Support for the k-Wave MATLAB toolbox</description>
		<language>en-US</language>
		<pubDate>Wed, 13 May 2026 03:11:31 +0000</pubDate>
		<generator>http://bbpress.org/?v=1.0.2</generator>
		<textInput>
			<title><![CDATA[Search]]></title>
			<description><![CDATA[Search all topics from these forums.]]></description>
			<name>q</name>
			<link>http://www.k-wave.org/forum/search.php</link>
		</textInput>
		<atom:link href="http://www.k-wave.org/forum/rss/topic/ultrasound-b-mode-phased-array-image-not-detected" rel="self" type="application/rss+xml" />

		<item>
			<title>kpalac on "Ultrasound B-Mode Phased Array: Image not detected"</title>
			<link>http://www.k-wave.org/forum/topic/ultrasound-b-mode-phased-array-image-not-detected#post-8225</link>
			<pubDate>Wed, 23 Jun 2021 17:18:47 +0000</pubDate>
			<dc:creator>kpalac</dc:creator>
			<guid isPermaLink="false">8225@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;I'm back with the code. Still cannot see the objects. It's quite interesting since i used three different impedances and densities. Can you help me find and fix the issue?&#60;/p&#62;
&#60;p&#62;% Simulating B-mode Ultrasound Images Example&#60;/p&#62;
&#60;p&#62;% This example illustrates how k-Wave can be used for the simulation of&#60;br /&#62;
% B-mode ultrasound images using a phased-array or sector transducer. It&#60;br /&#62;
% builds on the Simulating B-mode Ultrasound Images Example.&#60;br /&#62;
%&#60;br /&#62;
% To allow the simulated scan line data to be processed multiple times with&#60;br /&#62;
% different settings, the simulated RF data is saved to disk. This can be&#60;br /&#62;
% reloaded by setting RUN_SIMULATION = false within the example m-file. The&#60;br /&#62;
% data can also be downloaded from&#60;br /&#62;
% &#60;a href=&#34;http://www.k-wave.org/datasets/example_us_phased_array_scan_lines.mat&#34; rel=&#34;nofollow&#34;&#62;http://www.k-wave.org/datasets/example_us_phased_array_scan_lines.mat&#60;/a&#62;&#60;br /&#62;
%&#60;br /&#62;
% author: Bradley Treeby&#60;br /&#62;
% date: 7th September 2012&#60;br /&#62;
% last update: 22nd January 2020&#60;br /&#62;
%&#60;br /&#62;
% This function is part of the k-Wave Toolbox (&#60;a href=&#34;http://www.k-wave.org&#34; rel=&#34;nofollow&#34;&#62;http://www.k-wave.org&#60;/a&#62;)&#60;br /&#62;
% Copyright (C) 2012-2020 Bradley Treeby&#60;/p&#62;
&#60;p&#62;% This file is part of k-Wave. k-Wave is free software: you can&#60;br /&#62;
% redistribute it and/or modify it under the terms of the GNU Lesser&#60;br /&#62;
% General Public License as published by the Free Software Foundation,&#60;br /&#62;
% either version 3 of the License, or (at your option) any later version.&#60;br /&#62;
%&#60;br /&#62;
% k-Wave is distributed in the hope that it will be useful, but WITHOUT ANY&#60;br /&#62;
% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS&#60;br /&#62;
% FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for&#60;br /&#62;
% more details.&#60;br /&#62;
%&#60;br /&#62;
% You should have received a copy of the GNU Lesser General Public License&#60;br /&#62;
% along with k-Wave. If not, see &#38;lt;http://www.gnu.org/licenses/&#38;gt;. &#60;/p&#62;
&#60;p&#62;%#ok&#38;lt;*UNRCH&#60;br /&#62;
clearvars;&#60;br /&#62;
addpath('/home/kpalac/k-Wave')&#60;/p&#62;
&#60;p&#62;% simulation settings&#60;br /&#62;
DATA_CAST       = 'single';     % set to 'single' or 'gpuArray-single' to speed up computations&#60;br /&#62;
RUN_SIMULATION  = false;         % set to false to reload previous results instead of running simulation&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE K-WAVE GRID&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% set the size of the perfectly matched layer (PML)&#60;br /&#62;
pml_x_size = 15;                % [grid points]&#60;br /&#62;
pml_y_size = 10;                % [grid points]&#60;br /&#62;
pml_z_size = 10;                % [grid points]&#60;/p&#62;
&#60;p&#62;% set total number of grid points not including the PML&#60;br /&#62;
sc = 1;&#60;br /&#62;
Nx = 256/sc - 2*pml_x_size;     % [grid points]&#60;br /&#62;
Ny = 256/sc - 2*pml_y_size;     % [grid points]&#60;br /&#62;
Nz = 256/sc - 2*pml_z_size;     % [grid points]&#60;/p&#62;
&#60;p&#62;% set desired grid size in the x-direction not including the PML&#60;br /&#62;
x = 50e-3;                      % [m]&#60;/p&#62;
&#60;p&#62;% calculate the spacing between the grid points&#60;br /&#62;
dx = x / Nx;                    % [m]&#60;br /&#62;
dy = dx;                        % [m]&#60;br /&#62;
dz = dx;                        % [m]&#60;/p&#62;
&#60;p&#62;% create the k-space grid&#60;br /&#62;
kgrid = kWaveGrid(Nx, dx, Ny, dy, Nz, dz);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE MEDIUM PARAMETERS&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define the properties of the propagation medium&#60;br /&#62;
c0 = 1496.727708;                      % [m/s]&#60;br /&#62;
rho0 = 997.0751;                    % [kg/m^3]&#60;br /&#62;
medium.alpha_coeff = 0.5;      % [dB/(MHz^y cm)]&#60;br /&#62;
medium.alpha_power = 1.5;&#60;br /&#62;
medium.BonA = 6;&#60;/p&#62;
&#60;p&#62;% create the time array&#60;br /&#62;
t_end = (Nx * dx) * 2.2 / c0;   % [s]&#60;br /&#62;
kgrid.makeTime(c0, [], t_end);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE INPUT SIGNAL&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define properties of the input signal&#60;br /&#62;
source_strength = 2e6;          % [Pa]&#60;br /&#62;
tone_burst_freq = 2e6 / sc;     % [Hz]&#60;br /&#62;
tone_burst_cycles = 4;&#60;/p&#62;
&#60;p&#62;% create the input signal using toneBurst&#60;br /&#62;
input_signal = toneBurst(1/kgrid.dt, tone_burst_freq, tone_burst_cycles);&#60;/p&#62;
&#60;p&#62;% scale the source magnitude by the source_strength divided by the&#60;br /&#62;
% impedance (the source is assigned to the particle velocity)&#60;br /&#62;
input_signal = (source_strength ./ (c0 * rho0)) .* input_signal;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE ULTRASOUND TRANSDUCER&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define the physical properties of the phased array transducer&#60;br /&#62;
transducer.number_elements = 32 / sc;       % total number of transducer elements&#60;br /&#62;
transducer.element_width = 2;               % width of each element [grid points]&#60;br /&#62;
transducer.element_length = 85 / sc;        % length of each element [grid points]&#60;br /&#62;
transducer.element_spacing = 2;             % spacing (kerf  width) between the elements [grid points]&#60;/p&#62;
&#60;p&#62;% calculate the width of the transducer in grid points&#60;br /&#62;
transducer_width = transducer.number_elements * transducer.element_width ...&#60;br /&#62;
    + (transducer.number_elements - 1) * transducer.element_spacing;&#60;/p&#62;
&#60;p&#62;% use this to position the transducer in the middle of the computational grid&#60;br /&#62;
transducer.position = round([1, Ny/2 - transducer_width/2, Nz/2 - transducer.element_length/2]);&#60;/p&#62;
&#60;p&#62;% properties used to derive the beamforming delays&#60;br /&#62;
transducer.sound_speed = c0;                    % sound speed [m/s]&#60;br /&#62;
transducer.focus_distance = 25e-3;              % focus distance [m]&#60;br /&#62;
transducer.elevation_focus_distance = 25e-3;    % focus distance in the elevation plane [m]&#60;br /&#62;
transducer.steering_angle = 30;                  % steering angle [degrees]&#60;br /&#62;
transducer.steering_angle_max = 30;             % maximum steering angle [degrees]&#60;/p&#62;
&#60;p&#62;% apodization&#60;br /&#62;
transducer.transmit_apodization = 'Hanning';&#60;br /&#62;
transducer.receive_apodization = 'Rectangular';&#60;/p&#62;
&#60;p&#62;% define the transducer elements that are currently active&#60;br /&#62;
transducer.active_elements = ones(transducer.number_elements, 1);&#60;/p&#62;
&#60;p&#62;% append input signal used to drive the transducer&#60;br /&#62;
transducer.input_signal = input_signal;&#60;/p&#62;
&#60;p&#62;% create the transducer using the defined settings&#60;br /&#62;
transducer = kWaveTransducer(kgrid, transducer);&#60;/p&#62;
&#60;p&#62;% print out transducer properties&#60;br /&#62;
transducer.properties;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE MEDIUM PROPERTIES&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define a random distribution of scatterers for the medium&#60;br /&#62;
background_map_mean = 1;&#60;br /&#62;
background_map_std = 0.008;&#60;br /&#62;
background_map = background_map_mean + background_map_std * randn([Nx, Ny, Nz]);&#60;/p&#62;
&#60;p&#62;% define a random distribution of scatterers for the highly scattering&#60;br /&#62;
% region&#60;br /&#62;
scattering_map = randn([Nx, Ny, Nz]);&#60;br /&#62;
scattering_c0 = c0 + 25 + 50 * scattering_map; %&#60;br /&#62;
scattering_c0(scattering_c0 &#38;gt; 1900) = 1900;&#60;br /&#62;
scattering_c0(scattering_c0 &#38;lt; 1400) = 1400;&#60;br /&#62;
scattering_rho0 = scattering_c0 / 1.5;&#60;/p&#62;
&#60;p&#62;scattering_c1 = 1550 + 10 + 60 * scattering_map; %bone&#60;br /&#62;
scattering_rho1 = scattering_c1/1;&#60;br /&#62;
scattering_c2 = 1570 + 10 + 60 * scattering_map;&#60;br /&#62;
scattering_rho2 = scattering_c2/2;&#60;br /&#62;
%scattering_c3 = 1573 + 10 + 100 * scattering_map;&#60;br /&#62;
%scattering_rho3 = scattering_c3/1.6;&#60;br /&#62;
%scattering_c4 = 1570 + 10 + 50 * scattering_map;&#60;br /&#62;
%scattering_rho4 = scattering_c4/1.35;&#60;/p&#62;
&#60;p&#62;% define properties&#60;br /&#62;
sound_speed_map = c0 * ones(Nx, Ny, Nz) .* background_map;&#60;br /&#62;
density_map = rho0 * ones(Nx, Ny, Nz) .* background_map;&#60;/p&#62;
&#60;p&#62;% define a sphere for a highly scattering region&#60;br /&#62;
radius = 25e-3;&#60;br /&#62;
x_pos = 25e-3;&#60;br /&#62;
y_pos = dy * Ny/2;&#60;br /&#62;
scattering_region1 = makeBall(Nx, Ny, Nz, round(x_pos / dx), round(y_pos / dx), Nz/2, round(radius / dx));&#60;br /&#62;
scattering_region2 = makeBall(Nx, Ny, Nz, round(25e-3 / dx), round(25e-3 / dx), Nz/2, round(7e-3 / dx));&#60;br /&#62;
scattering_region3 = makeBall(Nx, Ny, Nz, round(20e-3 / dx), round(15e-3 / dx), Nz/2, round(4e-3 / dx));&#60;br /&#62;
%scattering_region4 = makeBall(Nx, Ny, Nz, round(25e-3 / dx), round(30 / dx), Nz/2, round(4e-3 / dx));&#60;br /&#62;
%scattering_region5 = makeBall(Nx, Ny, Nz, round(45e-3 / dx), round(40 / dx), Nz/2, round(2e-3 / dx));&#60;/p&#62;
&#60;p&#62;% assign region&#60;br /&#62;
sound_speed_map(scattering_region1 == 1) = scattering_c0(scattering_region1 == 1);&#60;br /&#62;
density_map(scattering_region1 == 1) = scattering_rho0(scattering_region1 == 1);&#60;br /&#62;
sound_speed_map(scattering_region2 == 1) = scattering_c1(scattering_region2 == 1);&#60;br /&#62;
density_map(scattering_region2 == 1) = scattering_rho1(scattering_region2 == 1);&#60;br /&#62;
sound_speed_map(scattering_region3 == 1) = scattering_c2(scattering_region3 == 1);&#60;br /&#62;
density_map(scattering_region3 == 1) = scattering_rho2(scattering_region3 == 1);&#60;br /&#62;
%sound_speed_map(scattering_region4 == 1) = scattering_c3(scattering_region4 == 1);&#60;br /&#62;
%density_map(scattering_region4 == 1) = scattering_rho3(scattering_region4 == 1);&#60;br /&#62;
%sound_speed_map(scattering_region5 == 1) = scattering_c4(scattering_region5 == 1);&#60;br /&#62;
%density_map(scattering_region5 == 1) = scattering_rho4(scattering_region5 == 1);&#60;/p&#62;
&#60;p&#62;% assign to the medium inputs&#60;br /&#62;
medium.sound_speed = sound_speed_map;&#60;br /&#62;
medium.density = density_map;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% RUN THE SIMULATION&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% range of steering angles to test&#60;br /&#62;
steering_angles = -30:10:30;&#60;/p&#62;
&#60;p&#62;% preallocate the storage&#60;br /&#62;
number_scan_lines = length(steering_angles);&#60;br /&#62;
scan_lines = zeros(number_scan_lines, kgrid.Nt);&#60;/p&#62;
&#60;p&#62;% set the input settings&#60;br /&#62;
input_args = {...&#60;br /&#62;
    'PMLInside', false, 'PMLSize', [pml_x_size, pml_y_size, pml_z_size], ...&#60;br /&#62;
    'DataCast', DATA_CAST, 'DataRecast', true, 'PlotSim', false};&#60;/p&#62;
&#60;p&#62;% run the simulation if set to true, otherwise, load previous results&#60;br /&#62;
if RUN_SIMULATION&#60;/p&#62;
&#60;p&#62;    % loop through the range of angles to test&#60;br /&#62;
    for angle_index = 1:number_scan_lines&#60;/p&#62;
&#60;p&#62;        % update the command line status&#60;br /&#62;
        disp('');&#60;br /&#62;
        disp(['Computing scan line ' num2str(angle_index) ' of ' num2str(number_scan_lines)]);&#60;/p&#62;
&#60;p&#62;        % update the current steering angle&#60;br /&#62;
        transducer.steering_angle = steering_angles(angle_index);&#60;/p&#62;
&#60;p&#62;        % run the simulation&#60;br /&#62;
        sensor_data = kspaceFirstOrder3D(kgrid, medium, transducer, transducer, input_args{:});&#60;/p&#62;
&#60;p&#62;        % extract the scan line from the sensor data&#60;br /&#62;
        scan_lines(angle_index, :) = transducer.scan_line(sensor_data);&#60;/p&#62;
&#60;p&#62;    end&#60;/p&#62;
&#60;p&#62;    % save the scan lines to disk&#60;br /&#62;
    save example_us_phased_array_scan_lines scan_lines;&#60;/p&#62;
&#60;p&#62;else&#60;/p&#62;
&#60;p&#62;    % load the scan lines from disk&#60;br /&#62;
    load example_us_phased_array_scan_lines&#60;/p&#62;
&#60;p&#62;end&#60;/p&#62;
&#60;p&#62;% trim the delay offset from the scan line data&#60;br /&#62;
t0_offset = round(length(input_signal) / 2) + (transducer.appended_zeros - transducer.beamforming_delays_offset);&#60;br /&#62;
scan_lines = scan_lines(:, t0_offset:end);&#60;/p&#62;
&#60;p&#62;% get the new length of the scan lines&#60;br /&#62;
Nt = length(scan_lines(1, :));&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% PROCESS THE RESULTS&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Remove Input Signal&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% create a window to set the first part of each scan line to zero to remove&#60;br /&#62;
% interference from the input signal&#60;br /&#62;
scan_line_win = getWin(Nt * 2, 'Tukey', 'Param', 0.05).';&#60;br /&#62;
scan_line_win = [zeros(1, t0_offset * 2), scan_line_win(1:end/2 - t0_offset * 2)];&#60;/p&#62;
&#60;p&#62;% apply the window to each of the scan lines&#60;br /&#62;
scan_lines = bsxfun(@times, scan_line_win, scan_lines);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Time Gain Compensation&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% create radius variable&#60;br /&#62;
r = c0 * (1:Nt) * kgrid.dt / 2;    % [m]&#60;/p&#62;
&#60;p&#62;% define absorption value and convert to correct units&#60;br /&#62;
tgc_alpha_db_cm = medium.alpha_coeff * (tone_burst_freq * 1e-6)^medium.alpha_power;&#60;br /&#62;
tgc_alpha_np_m = tgc_alpha_db_cm / 8.686 * 100;&#60;/p&#62;
&#60;p&#62;% create time gain compensation function based on attenuation value and&#60;br /&#62;
% round trip distance&#60;br /&#62;
tgc = exp(tgc_alpha_np_m * 2 * r);&#60;/p&#62;
&#60;p&#62;% apply the time gain compensation to each of the scan lines&#60;br /&#62;
scan_lines = bsxfun(@times, tgc, scan_lines);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Frequency Filtering&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% filter the scan lines using both the transmit frequency and the second&#60;br /&#62;
% harmonic&#60;br /&#62;
scan_lines_fund = gaussianFilter(scan_lines, 1/kgrid.dt, tone_burst_freq, 100, true);&#60;br /&#62;
scan_lines_harm = gaussianFilter(scan_lines, 1/kgrid.dt, 2 * tone_burst_freq, 30, true);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Envelope Detection&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% envelope detection&#60;br /&#62;
scan_lines_fund = envelopeDetection(scan_lines_fund);&#60;br /&#62;
scan_lines_harm = envelopeDetection(scan_lines_harm);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Log Compression&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% normalised log compression&#60;br /&#62;
compression_ratio = 3;&#60;br /&#62;
scan_lines_fund = logCompression(scan_lines_fund, compression_ratio, true);&#60;br /&#62;
scan_lines_harm = logCompression(scan_lines_harm, compression_ratio, true);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Scan Conversion&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% set the desired size of the image&#60;br /&#62;
image_size = [Nx * dx, Ny * dy];&#60;/p&#62;
&#60;p&#62;% convert the data from polar coordinates to Cartesian coordinates for&#60;br /&#62;
% display&#60;br /&#62;
b_mode_fund = scanConversion(scan_lines_fund, steering_angles, image_size, c0, kgrid.dt);&#60;br /&#62;
b_mode_harm = scanConversion(scan_lines_harm, steering_angles, image_size, c0, kgrid.dt);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% VISUALISATION&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% create the axis variables&#60;br /&#62;
x_axis = [0, Nx * dx * 1e3];    % [mm]&#60;br /&#62;
y_axis = [0, Ny * dy * 1e3];    % [mm]&#60;/p&#62;
&#60;p&#62;% plot the data before and after scan conversion&#60;br /&#62;
figure;&#60;br /&#62;
subplot(1, 3, 1);&#60;br /&#62;
imagesc(steering_angles, x_axis, scan_lines.');&#60;br /&#62;
axis square;&#60;br /&#62;
xlabel('Steering angle [deg]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('Raw Scan-Line Data');&#60;/p&#62;
&#60;p&#62;subplot(1, 3, 2);&#60;br /&#62;
imagesc(steering_angles, x_axis, scan_lines_fund.');&#60;br /&#62;
axis square;&#60;br /&#62;
xlabel('Steering angle [deg]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('Processed Scan-Line Data');&#60;/p&#62;
&#60;p&#62;subplot(1, 3, 3);&#60;br /&#62;
imagesc(y_axis, x_axis, b_mode_fund);&#60;br /&#62;
axis square;&#60;br /&#62;
xlabel('Horizontal Position [mm]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('B-Mode Image');&#60;br /&#62;
colormap(gray);&#60;/p&#62;
&#60;p&#62;scaleFig(2, 1);&#60;/p&#62;
&#60;p&#62;% plot the medium and the B-mode images&#60;br /&#62;
figure;&#60;br /&#62;
subplot(1, 3, 1);&#60;br /&#62;
imagesc(y_axis, x_axis, medium.sound_speed(:, :, end/2));&#60;br /&#62;
axis image;&#60;br /&#62;
xlabel('Horizontal Position [mm]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('Scattering Phantom');&#60;/p&#62;
&#60;p&#62;subplot(1, 3, 2);&#60;br /&#62;
imagesc(y_axis, x_axis, b_mode_fund);&#60;br /&#62;
axis image;&#60;br /&#62;
xlabel('Horizontal Position [mm]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('B-Mode Image');&#60;/p&#62;
&#60;p&#62;subplot(1, 3, 3);&#60;br /&#62;
imagesc(y_axis, x_axis, b_mode_harm);&#60;br /&#62;
colormap(gray);&#60;br /&#62;
axis image;&#60;br /&#62;
xlabel('Horizontal Position [mm]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('Harmonic Image');&#60;/p&#62;
&#60;p&#62;scaleFig(2, 1);
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Bradley Treeby on "Ultrasound B-Mode Phased Array: Image not detected"</title>
			<link>http://www.k-wave.org/forum/topic/ultrasound-b-mode-phased-array-image-not-detected#post-8094</link>
			<pubDate>Thu, 25 Mar 2021 16:48:31 +0000</pubDate>
			<dc:creator>Bradley Treeby</dc:creator>
			<guid isPermaLink="false">8094@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;I didn't run your simulation to completion, but the following is given on the command line:&#60;/p&#62;
&#60;p&#62;&#60;code&#62;WARNING: time step may be too large for a stable simulation.&#60;/code&#62;&#60;/p&#62;
&#60;p&#62;If the sensor data is filled with nans, then it sounds like classic instability. You will need to make the time step smaller.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>kpalac on "Ultrasound B-Mode Phased Array: Image not detected"</title>
			<link>http://www.k-wave.org/forum/topic/ultrasound-b-mode-phased-array-image-not-detected#post-8056</link>
			<pubDate>Mon, 08 Feb 2021 19:37:03 +0000</pubDate>
			<dc:creator>kpalac</dc:creator>
			<guid isPermaLink="false">8056@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Sure. I will add code again. &#34;$&#34; will be put at the beginning of each line that was modified:&#60;/p&#62;
&#60;p&#62;clearvars;&#60;/p&#62;
&#60;p&#62;% simulation settings&#60;br /&#62;
DATA_CAST = 'single'; % set to 'single' or 'gpuArray-single' to speed up computations&#60;br /&#62;
RUN_SIMULATION = true; % set to false to reload previous results instead of running simulation&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE K-WAVE GRID&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% set the size of the perfectly matched layer (PML)&#60;br /&#62;
pml_x_size = 15; % [grid points]&#60;br /&#62;
pml_y_size = 10; % [grid points]&#60;br /&#62;
pml_z_size = 10; % [grid points]&#60;/p&#62;
&#60;p&#62;% set total number of grid points not including the PML&#60;br /&#62;
sc = 1;&#60;br /&#62;
$ Nx = 300/sc - 2*pml_x_size; % [grid points]&#60;br /&#62;
$ Ny = 300/sc - 2*pml_y_size; % [grid points]&#60;br /&#62;
$ Nz = 300/sc - 2*pml_z_size; % [grid points]&#60;/p&#62;
&#60;p&#62;% set desired grid size in the x-direction not including the PML&#60;br /&#62;
$ x = 50e-3; % [m]&#60;/p&#62;
&#60;p&#62;% calculate the spacing between the grid points&#60;br /&#62;
dx = x / Nx; % [m]&#60;br /&#62;
dy = dx; % [m]&#60;br /&#62;
dz = dx; % [m]&#60;/p&#62;
&#60;p&#62;% create the k-space grid&#60;br /&#62;
kgrid = kWaveGrid(Nx, dx, Ny, dy, Nz, dz);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE MEDIUM PARAMETERS&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define the properties of the propagation medium&#60;br /&#62;
$ c0 = 1496.727708; % [m/s]&#60;br /&#62;
$ rho0 = 997.0751; % [kg/m^3]&#60;br /&#62;
$ medium.alpha_coeff = 0.7642; % [dB/(MHz^y cm)]&#60;br /&#62;
$ medium.alpha_power = 1.5;&#60;br /&#62;
medium.BonA = 6;&#60;/p&#62;
&#60;p&#62;% create the time array&#60;br /&#62;
t_end = (Nx * dx) * 2.2 / c0; % [s]&#60;br /&#62;
kgrid.makeTime(c0, [], t_end);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE INPUT SIGNAL&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define properties of the input signal&#60;br /&#62;
$ source_strength = 2e6; % [Pa]&#60;br /&#62;
$ tone_burst_freq = 2e6 / sc; % [Hz]&#60;br /&#62;
tone_burst_cycles = 4;&#60;/p&#62;
&#60;p&#62;% create the input signal using toneBurst&#60;br /&#62;
input_signal = toneBurst(1/kgrid.dt, tone_burst_freq, tone_burst_cycles);&#60;/p&#62;
&#60;p&#62;% scale the source magnitude by the source_strength divided by the&#60;br /&#62;
% impedance (the source is assigned to the particle velocity)&#60;br /&#62;
input_signal = (source_strength ./ (c0 * rho0)) .* input_signal;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE ULTRASOUND TRANSDUCER&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define the physical properties of the phased array transducer&#60;br /&#62;
$ transducer.number_elements = 32 / sc; % total number of transducer elements&#60;br /&#62;
$ transducer.element_width = 5; % width of each element [grid points]&#60;br /&#62;
$ transducer.element_length = 170 / sc; % length of each element [grid points]&#60;br /&#62;
$ transducer.element_spacing = 3; % spacing (kerf width) between the elements [grid points]&#60;/p&#62;
&#60;p&#62;% calculate the width of the transducer in grid points&#60;br /&#62;
transducer_width = transducer.number_elements * transducer.element_width ...&#60;br /&#62;
+ (transducer.number_elements - 1) * transducer.element_spacing;&#60;/p&#62;
&#60;p&#62;% use this to position the transducer in the middle of the computational grid&#60;br /&#62;
transducer.position = round([1, Ny/2 - transducer_width/2, Nz/2 - transducer.element_length/2]);&#60;/p&#62;
&#60;p&#62;% properties used to derive the beamforming delays&#60;br /&#62;
transducer.sound_speed = c0; % sound speed [m/s]&#60;br /&#62;
$transducer.focus_distance = 25e-3; % focus distance [m]&#60;br /&#62;
$transducer.elevation_focus_distance = 25e-3; % focus distance in the elevation plane [m]&#60;br /&#62;
$transducer.steering_angle = 20; % steering angle [degrees]&#60;br /&#62;
$transducer.steering_angle_max = 20; % maximum steering angle [degrees]&#60;/p&#62;
&#60;p&#62;% apodization&#60;br /&#62;
transducer.transmit_apodization = 'Hanning';&#60;br /&#62;
transducer.receive_apodization = 'Rectangular';&#60;/p&#62;
&#60;p&#62;% define the transducer elements that are currently active&#60;br /&#62;
transducer.active_elements = ones(transducer.number_elements, 1);&#60;/p&#62;
&#60;p&#62;% append input signal used to drive the transducer&#60;br /&#62;
transducer.input_signal = input_signal;&#60;/p&#62;
&#60;p&#62;% create the transducer using the defined settings&#60;br /&#62;
transducer = kWaveTransducer(kgrid, transducer);&#60;/p&#62;
&#60;p&#62;% print out transducer properties&#60;br /&#62;
transducer.properties;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE MEDIUM PROPERTIES&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define a random distribution of scatterers for the medium&#60;br /&#62;
background_map_mean = 1;&#60;br /&#62;
background_map_std = 0.008;&#60;br /&#62;
background_map = background_map_mean + background_map_std * randn([Nx, Ny, Nz]);&#60;/p&#62;
&#60;p&#62;% define a random distribution of scatterers for the highly scattering&#60;br /&#62;
% region&#60;br /&#62;
scattering_map = randn([Nx, Ny, Nz]);&#60;br /&#62;
$scattering_c0 = c0 + 25 + 150 * scattering_map; %&#60;br /&#62;
$scattering_c0(scattering_c0 &#38;gt; 1600) = 1600;&#60;br /&#62;
$scattering_c0(scattering_c0 &#38;lt; 1400) = 1400;&#60;br /&#62;
$scattering_rho0 = scattering_c0 / 1.5;&#60;/p&#62;
&#60;p&#62;$scattering_c1 = 4080 + 10 + 100 * scattering_map; %bone&#60;br /&#62;
scattering_rho1 = scattering_c1/1.5;&#60;br /&#62;
%scattering_c2 = 1530 + 10 + 75 * scattering_map;&#60;br /&#62;
%scattering_rho2 = scattering_c2/1.5;&#60;br /&#62;
%scattering_c3 = 1573 + 10 + 100 * scattering_map;&#60;br /&#62;
%scattering_rho3 = scattering_c3/1.6;&#60;br /&#62;
%scattering_c4 = 1570 + 10 + 50 * scattering_map;&#60;br /&#62;
%scattering_rho4 = scattering_c4/1.35;&#60;/p&#62;
&#60;p&#62;% define properties&#60;br /&#62;
sound_speed_map = c0 * ones(Nx, Ny, Nz) .* background_map;&#60;br /&#62;
density_map = rho0 * ones(Nx, Ny, Nz) .* background_map;&#60;/p&#62;
&#60;p&#62;% define a sphere for a highly scattering region&#60;br /&#62;
$radius = 25e-3;&#60;br /&#62;
$x_pos = 25e-3;&#60;br /&#62;
y_pos = dy * Ny/2;&#60;br /&#62;
scattering_region1 = makeBall(Nx, Ny, Nz, round(x_pos / dx), round(y_pos / dx), Nz/2, round(radius / dx));&#60;br /&#62;
$scattering_region2 = makeBall(Nx, Ny, Nz, round(25e-3 / dx), round(25e-3 / dx), Nz/2, round(2e-3 / dx));&#60;br /&#62;
%scattering_region3 = makeBall(Nx, Ny, Nz, round(20e-3 / dx), round(15 / dx), Nz/2, round(3e-3 / dx));&#60;br /&#62;
%scattering_region4 = makeBall(Nx, Ny, Nz, round(25e-3 / dx), round(30 / dx), Nz/2, round(4e-3 / dx));&#60;br /&#62;
%scattering_region5 = makeBall(Nx, Ny, Nz, round(45e-3 / dx), round(40 / dx), Nz/2, round(2e-3 / dx));&#60;/p&#62;
&#60;p&#62;% assign region&#60;br /&#62;
sound_speed_map(scattering_region1 == 1) = scattering_c0(scattering_region1 == 1);&#60;br /&#62;
density_map(scattering_region1 == 1) = scattering_rho0(scattering_region1 == 1);&#60;br /&#62;
$sound_speed_map(scattering_region2 == 1) = scattering_c1(scattering_region2 == 1);&#60;br /&#62;
$density_map(scattering_region2 == 1) = scattering_rho1(scattering_region2 == 1);&#60;br /&#62;
%sound_speed_map(scattering_region3 == 1) = scattering_c2(scattering_region3 == 1);&#60;br /&#62;
%density_map(scattering_region3 == 1) = scattering_rho2(scattering_region3 == 1);&#60;br /&#62;
%sound_speed_map(scattering_region4 == 1) = scattering_c3(scattering_region4 == 1);&#60;br /&#62;
%density_map(scattering_region4 == 1) = scattering_rho3(scattering_region4 == 1);&#60;br /&#62;
%sound_speed_map(scattering_region5 == 1) = scattering_c4(scattering_region5 == 1);&#60;br /&#62;
%density_map(scattering_region5 == 1) = scattering_rho4(scattering_region5 == 1);&#60;/p&#62;
&#60;p&#62;% assign to the medium inputs&#60;br /&#62;
medium.sound_speed = sound_speed_map;&#60;br /&#62;
medium.density = density_map;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% RUN THE SIMULATION&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% range of steering angles to test&#60;br /&#62;
$steering_angles = -20:10:20;&#60;/p&#62;
&#60;p&#62;% preallocate the storage&#60;br /&#62;
number_scan_lines = length(steering_angles);&#60;br /&#62;
scan_lines = zeros(number_scan_lines, kgrid.Nt);&#60;/p&#62;
&#60;p&#62;% set the input settings&#60;br /&#62;
input_args = {...&#60;br /&#62;
'PMLInside', false, 'PMLSize', [pml_x_size, pml_y_size, pml_z_size], ...&#60;br /&#62;
'DataCast', DATA_CAST, 'DataRecast', true, 'PlotSim', false};&#60;/p&#62;
&#60;p&#62;% run the simulation if set to true, otherwise, load previous results&#60;br /&#62;
if RUN_SIMULATION&#60;/p&#62;
&#60;p&#62;% loop through the range of angles to test&#60;br /&#62;
for angle_index = 1:number_scan_lines&#60;/p&#62;
&#60;p&#62;% update the command line status&#60;br /&#62;
disp('');&#60;br /&#62;
disp(['Computing scan line ' num2str(angle_index) ' of ' num2str(number_scan_lines)]);&#60;/p&#62;
&#60;p&#62;% update the current steering angle&#60;br /&#62;
transducer.steering_angle = steering_angles(angle_index);&#60;/p&#62;
&#60;p&#62;% run the simulation&#60;br /&#62;
sensor_data = kspaceFirstOrder3D(kgrid, medium, transducer, transducer, input_args{:});&#60;/p&#62;
&#60;p&#62;% extract the scan line from the sensor data&#60;br /&#62;
scan_lines(angle_index, :) = transducer.scan_line(sensor_data);&#60;/p&#62;
&#60;p&#62;end&#60;/p&#62;
&#60;p&#62;% save the scan lines to disk&#60;br /&#62;
save example_us_phased_array_scan_lines scan_lines;&#60;/p&#62;
&#60;p&#62;else&#60;/p&#62;
&#60;p&#62;% load the scan lines from disk&#60;br /&#62;
load example_us_phased_array_scan_lines&#60;/p&#62;
&#60;p&#62;end&#60;/p&#62;
&#60;p&#62;% trim the delay offset from the scan line data&#60;br /&#62;
t0_offset = round(length(input_signal) / 2) + (transducer.appended_zeros - transducer.beamforming_delays_offset);&#60;br /&#62;
scan_lines = scan_lines(:, t0_offset:end);&#60;/p&#62;
&#60;p&#62;% get the new length of the scan lines&#60;br /&#62;
Nt = length(scan_lines(1, :));&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% PROCESS THE RESULTS&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Remove Input Signal&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% create a window to set the first part of each scan line to zero to remove&#60;br /&#62;
% interference from the input signal&#60;br /&#62;
scan_line_win = getWin(Nt * 2, 'Tukey', 'Param', 0.05).';&#60;br /&#62;
scan_line_win = [zeros(1, t0_offset * 2), scan_line_win(1:end/2 - t0_offset * 2)];&#60;/p&#62;
&#60;p&#62;% apply the window to each of the scan lines&#60;br /&#62;
scan_lines = bsxfun(@times, scan_line_win, scan_lines);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Time Gain Compensation&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% create radius variable&#60;br /&#62;
r = c0 * (1:Nt) * kgrid.dt / 2; % [m]&#60;/p&#62;
&#60;p&#62;% define absorption value and convert to correct units&#60;br /&#62;
tgc_alpha_db_cm = medium.alpha_coeff * (tone_burst_freq * 1e-6)^medium.alpha_power;&#60;br /&#62;
tgc_alpha_np_m = tgc_alpha_db_cm / 8.686 * 100;&#60;/p&#62;
&#60;p&#62;% create time gain compensation function based on attenuation value and&#60;br /&#62;
% round trip distance&#60;br /&#62;
tgc = exp(tgc_alpha_np_m * 2 * r);&#60;/p&#62;
&#60;p&#62;% apply the time gain compensation to each of the scan lines&#60;br /&#62;
scan_lines = bsxfun(@times, tgc, scan_lines);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Frequency Filtering&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% filter the scan lines using both the transmit frequency and the second&#60;br /&#62;
% harmonic&#60;br /&#62;
scan_lines_fund = gaussianFilter(scan_lines, 1/kgrid.dt, tone_burst_freq, 100, true);&#60;br /&#62;
scan_lines_harm = gaussianFilter(scan_lines, 1/kgrid.dt, 2 * tone_burst_freq, 30, true);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Envelope Detection&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% envelope detection&#60;br /&#62;
scan_lines_fund = envelopeDetection(scan_lines_fund);&#60;br /&#62;
scan_lines_harm = envelopeDetection(scan_lines_harm);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Log Compression&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% normalised log compression&#60;br /&#62;
compression_ratio = 3;&#60;br /&#62;
scan_lines_fund = logCompression(scan_lines_fund, compression_ratio, true);&#60;br /&#62;
scan_lines_harm = logCompression(scan_lines_harm, compression_ratio, true);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Scan Conversion&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% set the desired size of the image&#60;br /&#62;
image_size = [Nx * dx, Ny * dy];&#60;/p&#62;
&#60;p&#62;% convert the data from polar coordinates to Cartesian coordinates for&#60;br /&#62;
% display&#60;br /&#62;
b_mode_fund = scanConversion(scan_lines_fund, steering_angles, image_size, c0, kgrid.dt);&#60;br /&#62;
b_mode_harm = scanConversion(scan_lines_harm, steering_angles, image_size, c0, kgrid.dt);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% VISUALISATION&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% create the axis variables&#60;br /&#62;
x_axis = [0, Nx * dx * 1e3]; % [mm]&#60;br /&#62;
y_axis = [0, Ny * dy * 1e3]; % [mm]&#60;/p&#62;
&#60;p&#62;% plot the data before and after scan conversion&#60;br /&#62;
figure;&#60;br /&#62;
subplot(1, 3, 1);&#60;br /&#62;
imagesc(steering_angles, x_axis, scan_lines.');&#60;br /&#62;
axis square;&#60;br /&#62;
xlabel('Steering angle [deg]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('Raw Scan-Line Data');&#60;/p&#62;
&#60;p&#62;subplot(1, 3, 2);&#60;br /&#62;
imagesc(steering_angles, x_axis, scan_lines_fund.');&#60;br /&#62;
axis square;&#60;br /&#62;
xlabel('Steering angle [deg]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('Processed Scan-Line Data');&#60;/p&#62;
&#60;p&#62;subplot(1, 3, 3);&#60;br /&#62;
imagesc(y_axis, x_axis, b_mode_fund);&#60;br /&#62;
axis square;&#60;br /&#62;
xlabel('Horizontal Position [mm]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('B-Mode Image');&#60;br /&#62;
colormap(gray);&#60;/p&#62;
&#60;p&#62;scaleFig(2, 1);&#60;/p&#62;
&#60;p&#62;% plot the medium and the B-mode images&#60;br /&#62;
figure;&#60;br /&#62;
subplot(1, 3, 1);&#60;br /&#62;
imagesc(y_axis, x_axis, medium.sound_speed(:, :, end/2));&#60;br /&#62;
axis image;&#60;br /&#62;
xlabel('Horizontal Position [mm]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('Scattering Phantom');&#60;/p&#62;
&#60;p&#62;subplot(1, 3, 2);&#60;br /&#62;
imagesc(y_axis, x_axis, b_mode_fund);&#60;br /&#62;
axis image;&#60;br /&#62;
xlabel('Horizontal Position [mm]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('B-Mode Image');&#60;/p&#62;
&#60;p&#62;subplot(1, 3, 3);&#60;br /&#62;
imagesc(y_axis, x_axis, b_mode_harm);&#60;br /&#62;
colormap(gray);&#60;br /&#62;
axis image;&#60;br /&#62;
xlabel('Horizontal Position [mm]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('Harmonic Image');&#60;/p&#62;
&#60;p&#62;scaleFig(2, 1);
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Bradley Treeby on "Ultrasound B-Mode Phased Array: Image not detected"</title>
			<link>http://www.k-wave.org/forum/topic/ultrasound-b-mode-phased-array-image-not-detected#post-8042</link>
			<pubDate>Sat, 06 Feb 2021 12:19:13 +0000</pubDate>
			<dc:creator>Bradley Treeby</dc:creator>
			<guid isPermaLink="false">8042@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi kpalac,&#60;/p&#62;
&#60;p&#62;Can you highlight which lines of code you changed from the example?&#60;/p&#62;
&#60;p&#62;Brad.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>kpalac on "Ultrasound B-Mode Phased Array: Image not detected"</title>
			<link>http://www.k-wave.org/forum/topic/ultrasound-b-mode-phased-array-image-not-detected#post-8041</link>
			<pubDate>Sat, 06 Feb 2021 10:32:16 +0000</pubDate>
			<dc:creator>kpalac</dc:creator>
			<guid isPermaLink="false">8041@http://www.k-wave.org/forum/</guid>
			<description>&#60;br /&#62;</description>
		</item>
		<item>
			<title>kpalac on "Ultrasound B-Mode Phased Array: Image not detected"</title>
			<link>http://www.k-wave.org/forum/topic/ultrasound-b-mode-phased-array-image-not-detected#post-8040</link>
			<pubDate>Wed, 03 Feb 2021 20:50:01 +0000</pubDate>
			<dc:creator>kpalac</dc:creator>
			<guid isPermaLink="false">8040@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Greetings users,&#60;/p&#62;
&#60;p&#62;I am experiencing some issues with my code. I'll be writing master thesis about b-mode phased ultrasound imaging using k-Wave. Unfortunately, I cannot get a proper image on the output. The output image is almost completely black and it is not the fault of contrast. I ask You for Your help. Here is my code (the array size is locked, I am obliged to keep kerf, width and length of transducer array)&#60;/p&#62;
&#60;p&#62;Code:&#60;/p&#62;
&#60;p&#62;clearvars;&#60;/p&#62;
&#60;p&#62;% simulation settings&#60;br /&#62;
DATA_CAST       = 'single';     % set to 'single' or 'gpuArray-single' to speed up computations&#60;br /&#62;
RUN_SIMULATION  = true;         % set to false to reload previous results instead of running simulation&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE K-WAVE GRID&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% set the size of the perfectly matched layer (PML)&#60;br /&#62;
pml_x_size = 15;                % [grid points]&#60;br /&#62;
pml_y_size = 10;                % [grid points]&#60;br /&#62;
pml_z_size = 10;                % [grid points]&#60;/p&#62;
&#60;p&#62;% set total number of grid points not including the PML&#60;br /&#62;
sc = 1;&#60;br /&#62;
Nx = 300/sc - 2*pml_x_size;     % [grid points]&#60;br /&#62;
Ny = 300/sc - 2*pml_y_size;     % [grid points]&#60;br /&#62;
Nz = 300/sc - 2*pml_z_size;     % [grid points]&#60;/p&#62;
&#60;p&#62;% set desired grid size in the x-direction not including the PML&#60;br /&#62;
x = 50e-3;                      % [m]&#60;/p&#62;
&#60;p&#62;% calculate the spacing between the grid points&#60;br /&#62;
dx = x / Nx;                    % [m]&#60;br /&#62;
dy = dx;                        % [m]&#60;br /&#62;
dz = dx;                        % [m]&#60;/p&#62;
&#60;p&#62;% create the k-space grid&#60;br /&#62;
kgrid = kWaveGrid(Nx, dx, Ny, dy, Nz, dz);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE MEDIUM PARAMETERS&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define the properties of the propagation medium&#60;br /&#62;
c0 = 1496.727708;                      % [m/s]&#60;br /&#62;
rho0 = 997.0751;                    % [kg/m^3]&#60;br /&#62;
medium.alpha_coeff = 0.7642;      % [dB/(MHz^y cm)]&#60;br /&#62;
medium.alpha_power = 1.5;&#60;br /&#62;
medium.BonA = 6;&#60;/p&#62;
&#60;p&#62;% create the time array&#60;br /&#62;
t_end = (Nx * dx) * 2.2 / c0;   % [s]&#60;br /&#62;
kgrid.makeTime(c0, [], t_end);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE INPUT SIGNAL&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define properties of the input signal&#60;br /&#62;
source_strength = 2e6;          % [Pa]&#60;br /&#62;
tone_burst_freq = 2e6 / sc;     % [Hz]&#60;br /&#62;
tone_burst_cycles = 4;&#60;/p&#62;
&#60;p&#62;% create the input signal using toneBurst&#60;br /&#62;
input_signal = toneBurst(1/kgrid.dt, tone_burst_freq, tone_burst_cycles);&#60;/p&#62;
&#60;p&#62;% scale the source magnitude by the source_strength divided by the&#60;br /&#62;
% impedance (the source is assigned to the particle velocity)&#60;br /&#62;
input_signal = (source_strength ./ (c0 * rho0)) .* input_signal;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE ULTRASOUND TRANSDUCER&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define the physical properties of the phased array transducer&#60;br /&#62;
transducer.number_elements = 32 / sc;       % total number of transducer elements&#60;br /&#62;
transducer.element_width = 5;               % width of each element [grid points]&#60;br /&#62;
transducer.element_length = 170 / sc;        % length of each element [grid points]&#60;br /&#62;
transducer.element_spacing = 3;             % spacing (kerf  width) between the elements [grid points]&#60;/p&#62;
&#60;p&#62;% calculate the width of the transducer in grid points&#60;br /&#62;
transducer_width = transducer.number_elements * transducer.element_width ...&#60;br /&#62;
    + (transducer.number_elements - 1) * transducer.element_spacing;&#60;/p&#62;
&#60;p&#62;% use this to position the transducer in the middle of the computational grid&#60;br /&#62;
transducer.position = round([1, Ny/2 - transducer_width/2, Nz/2 - transducer.element_length/2]);&#60;/p&#62;
&#60;p&#62;% properties used to derive the beamforming delays&#60;br /&#62;
transducer.sound_speed = c0;                    % sound speed [m/s]&#60;br /&#62;
transducer.focus_distance = 25e-3;              % focus distance [m]&#60;br /&#62;
transducer.elevation_focus_distance = 25e-3;    % focus distance in the elevation plane [m]&#60;br /&#62;
transducer.steering_angle = 15;                  % steering angle [degrees]&#60;br /&#62;
transducer.steering_angle_max = 25;             % maximum steering angle [degrees]&#60;/p&#62;
&#60;p&#62;% apodization&#60;br /&#62;
transducer.transmit_apodization = 'Hanning';&#60;br /&#62;
transducer.receive_apodization = 'Rectangular';&#60;/p&#62;
&#60;p&#62;% define the transducer elements that are currently active&#60;br /&#62;
transducer.active_elements = ones(transducer.number_elements, 1);&#60;/p&#62;
&#60;p&#62;% append input signal used to drive the transducer&#60;br /&#62;
transducer.input_signal = input_signal;&#60;/p&#62;
&#60;p&#62;% create the transducer using the defined settings&#60;br /&#62;
transducer = kWaveTransducer(kgrid, transducer);&#60;/p&#62;
&#60;p&#62;% print out transducer properties&#60;br /&#62;
transducer.properties;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE MEDIUM PROPERTIES&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define a random distribution of scatterers for the medium&#60;br /&#62;
background_map_mean = 1;&#60;br /&#62;
background_map_std = 0.008;&#60;br /&#62;
background_map = background_map_mean + background_map_std * randn([Nx, Ny, Nz]);&#60;/p&#62;
&#60;p&#62;% define a random distribution of scatterers for the highly scattering&#60;br /&#62;
% region&#60;br /&#62;
scattering_map = randn([Nx, Ny, Nz]);&#60;br /&#62;
scattering_c0 = c0 + 25 + 150 * scattering_map; %&#60;br /&#62;
%scattering_c0(scattering_c0 &#38;gt; 1600) = 1600;&#60;br /&#62;
%scattering_c0(scattering_c0 &#38;lt; 1400) = 1400;&#60;br /&#62;
scattering_rho0 = scattering_c0 / 1.5;&#60;/p&#62;
&#60;p&#62;scattering_c1 = 4080 + 10 + 100 * scattering_map; %bone&#60;br /&#62;
scattering_rho1 = scattering_c1/1.5;&#60;br /&#62;
%scattering_c2 = 1530 + 10 + 75 * scattering_map;&#60;br /&#62;
%scattering_rho2 = scattering_c2/1.5;&#60;br /&#62;
%scattering_c3 = 1573 + 10 + 100 * scattering_map;&#60;br /&#62;
%scattering_rho3 = scattering_c3/1.6;&#60;br /&#62;
%scattering_c4 = 1570 + 10 + 50 * scattering_map;&#60;br /&#62;
%scattering_rho4 = scattering_c4/1.35;&#60;/p&#62;
&#60;p&#62;% define properties&#60;br /&#62;
sound_speed_map = c0 * ones(Nx, Ny, Nz) .* background_map;&#60;br /&#62;
density_map = rho0 * ones(Nx, Ny, Nz) .* background_map;&#60;/p&#62;
&#60;p&#62;% define a sphere for a highly scattering region&#60;br /&#62;
radius = 25e-3;&#60;br /&#62;
x_pos = 25e-3;&#60;br /&#62;
y_pos = dy * Ny/2;&#60;br /&#62;
scattering_region1 = makeBall(Nx, Ny, Nz, round(x_pos / dx), round(y_pos / dx), Nz/2, round(radius / dx));&#60;br /&#62;
scattering_region2 = makeBall(Nx, Ny, Nz, round(25e-3 / dx), round(25e-3 / dx), Nz/2, round(2e-3 / dx));&#60;br /&#62;
%scattering_region3 = makeBall(Nx, Ny, Nz, round(20e-3 / dx), round(15 / dx), Nz/2, round(3e-3 / dx));&#60;br /&#62;
%scattering_region4 = makeBall(Nx, Ny, Nz, round(25e-3 / dx), round(30 / dx), Nz/2, round(4e-3 / dx));&#60;br /&#62;
%scattering_region5 = makeBall(Nx, Ny, Nz, round(45e-3 / dx), round(40 / dx), Nz/2, round(2e-3 / dx));&#60;/p&#62;
&#60;p&#62;% assign region&#60;br /&#62;
sound_speed_map(scattering_region1 == 1) = scattering_c0(scattering_region1 == 1);&#60;br /&#62;
density_map(scattering_region1 == 1) = scattering_rho0(scattering_region1 == 1);&#60;br /&#62;
sound_speed_map(scattering_region2 == 1) = scattering_c1(scattering_region2 == 1);&#60;br /&#62;
density_map(scattering_region2 == 1) = scattering_rho1(scattering_region2 == 1);&#60;br /&#62;
%sound_speed_map(scattering_region3 == 1) = scattering_c2(scattering_region3 == 1);&#60;br /&#62;
%density_map(scattering_region3 == 1) = scattering_rho2(scattering_region3 == 1);&#60;br /&#62;
%sound_speed_map(scattering_region4 == 1) = scattering_c3(scattering_region4 == 1);&#60;br /&#62;
%density_map(scattering_region4 == 1) = scattering_rho3(scattering_region4 == 1);&#60;br /&#62;
%sound_speed_map(scattering_region5 == 1) = scattering_c4(scattering_region5 == 1);&#60;br /&#62;
%density_map(scattering_region5 == 1) = scattering_rho4(scattering_region5 == 1);&#60;/p&#62;
&#60;p&#62;% assign to the medium inputs&#60;br /&#62;
medium.sound_speed = sound_speed_map;&#60;br /&#62;
medium.density = density_map;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% RUN THE SIMULATION&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% range of steering angles to test&#60;br /&#62;
steering_angles = -25:5:25;&#60;/p&#62;
&#60;p&#62;% preallocate the storage&#60;br /&#62;
number_scan_lines = length(steering_angles);&#60;br /&#62;
scan_lines = zeros(number_scan_lines, kgrid.Nt);&#60;/p&#62;
&#60;p&#62;% set the input settings&#60;br /&#62;
input_args = {...&#60;br /&#62;
    'PMLInside', false, 'PMLSize', [pml_x_size, pml_y_size, pml_z_size], ...&#60;br /&#62;
    'DataCast', DATA_CAST, 'DataRecast', true, 'PlotSim', false};&#60;/p&#62;
&#60;p&#62;% run the simulation if set to true, otherwise, load previous results&#60;br /&#62;
if RUN_SIMULATION&#60;/p&#62;
&#60;p&#62;    % loop through the range of angles to test&#60;br /&#62;
    for angle_index = 1:number_scan_lines&#60;/p&#62;
&#60;p&#62;        % update the command line status&#60;br /&#62;
        disp('');&#60;br /&#62;
        disp(['Computing scan line ' num2str(angle_index) ' of ' num2str(number_scan_lines)]);&#60;/p&#62;
&#60;p&#62;        % update the current steering angle&#60;br /&#62;
        transducer.steering_angle = steering_angles(angle_index);&#60;/p&#62;
&#60;p&#62;        % run the simulation&#60;br /&#62;
        sensor_data = kspaceFirstOrder3D(kgrid, medium, transducer, transducer, input_args{:});&#60;/p&#62;
&#60;p&#62;        % extract the scan line from the sensor data&#60;br /&#62;
        scan_lines(angle_index, :) = transducer.scan_line(sensor_data);&#60;/p&#62;
&#60;p&#62;    end&#60;/p&#62;
&#60;p&#62;    % save the scan lines to disk&#60;br /&#62;
    save example_us_phased_array_scan_lines scan_lines;&#60;/p&#62;
&#60;p&#62;else&#60;/p&#62;
&#60;p&#62;    % load the scan lines from disk&#60;br /&#62;
    load example_us_phased_array_scan_lines&#60;/p&#62;
&#60;p&#62;end&#60;/p&#62;
&#60;p&#62;% trim the delay offset from the scan line data&#60;br /&#62;
t0_offset = round(length(input_signal) / 2) + (transducer.appended_zeros - transducer.beamforming_delays_offset);&#60;br /&#62;
scan_lines = scan_lines(:, t0_offset:end);&#60;/p&#62;
&#60;p&#62;% get the new length of the scan lines&#60;br /&#62;
Nt = length(scan_lines(1, :));&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% PROCESS THE RESULTS&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Remove Input Signal&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% create a window to set the first part of each scan line to zero to remove&#60;br /&#62;
% interference from the input signal&#60;br /&#62;
scan_line_win = getWin(Nt * 2, 'Tukey', 'Param', 0.05).';&#60;br /&#62;
scan_line_win = [zeros(1, t0_offset * 2), scan_line_win(1:end/2 - t0_offset * 2)];&#60;/p&#62;
&#60;p&#62;% apply the window to each of the scan lines&#60;br /&#62;
scan_lines = bsxfun(@times, scan_line_win, scan_lines);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Time Gain Compensation&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% create radius variable&#60;br /&#62;
r = c0 * (1:Nt) * kgrid.dt / 2;    % [m]&#60;/p&#62;
&#60;p&#62;% define absorption value and convert to correct units&#60;br /&#62;
tgc_alpha_db_cm = medium.alpha_coeff * (tone_burst_freq * 1e-6)^medium.alpha_power;&#60;br /&#62;
tgc_alpha_np_m = tgc_alpha_db_cm / 8.686 * 100;&#60;/p&#62;
&#60;p&#62;% create time gain compensation function based on attenuation value and&#60;br /&#62;
% round trip distance&#60;br /&#62;
tgc = exp(tgc_alpha_np_m * 2 * r);&#60;/p&#62;
&#60;p&#62;% apply the time gain compensation to each of the scan lines&#60;br /&#62;
scan_lines = bsxfun(@times, tgc, scan_lines);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Frequency Filtering&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% filter the scan lines using both the transmit frequency and the second&#60;br /&#62;
% harmonic&#60;br /&#62;
scan_lines_fund = gaussianFilter(scan_lines, 1/kgrid.dt, tone_burst_freq, 100, true);&#60;br /&#62;
scan_lines_harm = gaussianFilter(scan_lines, 1/kgrid.dt, 2 * tone_burst_freq, 30, true);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Envelope Detection&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% envelope detection&#60;br /&#62;
scan_lines_fund = envelopeDetection(scan_lines_fund);&#60;br /&#62;
scan_lines_harm = envelopeDetection(scan_lines_harm);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Log Compression&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% normalised log compression&#60;br /&#62;
compression_ratio = 3;&#60;br /&#62;
scan_lines_fund = logCompression(scan_lines_fund, compression_ratio, true);&#60;br /&#62;
scan_lines_harm = logCompression(scan_lines_harm, compression_ratio, true);&#60;/p&#62;
&#60;p&#62;% -----------------------------&#60;br /&#62;
% Scan Conversion&#60;br /&#62;
% -----------------------------&#60;/p&#62;
&#60;p&#62;% set the desired size of the image&#60;br /&#62;
image_size = [Nx * dx, Ny * dy];&#60;/p&#62;
&#60;p&#62;% convert the data from polar coordinates to Cartesian coordinates for&#60;br /&#62;
% display&#60;br /&#62;
b_mode_fund = scanConversion(scan_lines_fund, steering_angles, image_size, c0, kgrid.dt);&#60;br /&#62;
b_mode_harm = scanConversion(scan_lines_harm, steering_angles, image_size, c0, kgrid.dt);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% VISUALISATION&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% create the axis variables&#60;br /&#62;
x_axis = [0, Nx * dx * 1e3];    % [mm]&#60;br /&#62;
y_axis = [0, Ny * dy * 1e3];    % [mm]&#60;/p&#62;
&#60;p&#62;% plot the data before and after scan conversion&#60;br /&#62;
figure;&#60;br /&#62;
subplot(1, 3, 1);&#60;br /&#62;
imagesc(steering_angles, x_axis, scan_lines.');&#60;br /&#62;
axis square;&#60;br /&#62;
xlabel('Steering angle [deg]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('Raw Scan-Line Data');&#60;/p&#62;
&#60;p&#62;subplot(1, 3, 2);&#60;br /&#62;
imagesc(steering_angles, x_axis, scan_lines_fund.');&#60;br /&#62;
axis square;&#60;br /&#62;
xlabel('Steering angle [deg]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('Processed Scan-Line Data');&#60;/p&#62;
&#60;p&#62;subplot(1, 3, 3);&#60;br /&#62;
imagesc(y_axis, x_axis, b_mode_fund);&#60;br /&#62;
axis square;&#60;br /&#62;
xlabel('Horizontal Position [mm]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('B-Mode Image');&#60;br /&#62;
colormap(gray);&#60;/p&#62;
&#60;p&#62;scaleFig(2, 1);&#60;/p&#62;
&#60;p&#62;% plot the medium and the B-mode images&#60;br /&#62;
figure;&#60;br /&#62;
subplot(1, 3, 1);&#60;br /&#62;
imagesc(y_axis, x_axis, medium.sound_speed(:, :, end/2));&#60;br /&#62;
axis image;&#60;br /&#62;
xlabel('Horizontal Position [mm]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('Scattering Phantom');&#60;/p&#62;
&#60;p&#62;subplot(1, 3, 2);&#60;br /&#62;
imagesc(y_axis, x_axis, b_mode_fund);&#60;br /&#62;
axis image;&#60;br /&#62;
xlabel('Horizontal Position [mm]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('B-Mode Image');&#60;/p&#62;
&#60;p&#62;subplot(1, 3, 3);&#60;br /&#62;
imagesc(y_axis, x_axis, b_mode_harm);&#60;br /&#62;
colormap(gray);&#60;br /&#62;
axis image;&#60;br /&#62;
xlabel('Horizontal Position [mm]');&#60;br /&#62;
ylabel('Depth [mm]');&#60;br /&#62;
title('Harmonic Image');&#60;/p&#62;
&#60;p&#62;scaleFig(2, 1);
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
