1 ## Copyright (C) 2016 Loriane Weber
3 ## This program is free software; you can redistribute it and/or modify
4 ## it under the terms of the GNU General Public License as published by
5 ## the Free Software Foundation; either version 3 of the License, or
6 ## (at your option) any later version.
8 ## This program is distributed in the hope that it will be useful,
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 ## GNU General Public License for more details.
13 ## You should have received a copy of the GNU General Public License
14 ## along with Octave; see the file COPYING. If not, see
15 ## <http://www.gnu.org/licenses/>.
17 ## SimuPBI_3WiresPhant_func
19 ## Author: Loriane Weber <lweber@gpid16a-1802>
20 ## Created: 2016-03-30
23 ## SimuPBI_3WiresPhant_func('Analytical', 2, 'test', [0 0.1 0.5], 19, 2.7, 300, 180, 1, 0, '', 'gaussian', 35)
25 ## Please note that dir_out, noise_type, noise_amount are optional arguments.
27 function [] = SimuPBI_3WiresPhant_func (vers, oversamp, basename_output, dist, energy, ps, nbProj, range_angle, model_ctf, model_Fresnel, height, dir_out, noise_type, noise_amount)
29 addpath('utilities_ESRF')
30 addpath('utilities_LW')
31 addpath('octave_packages/image-1.0.15')
32 addpath('octave_packages/signal-1.1.3')
34 ################################################
35 ############### INPUT parameters ###############
36 ################################################
38 ################################
39 ######### Parameter related to the computation - and names of the result
40 ################################
42 ## vers: are the projections calculated analytically or using the Radon transform? use 'Radon' OR 'Analytical'
45 ## Oversampling of the projections : use 2 or 4
48 ## Basename of the result file
49 %basename_output='phantom_al_mg_PET_thibaut_3dist';
51 ################################
52 ######### Parameter related to the physics
53 ################################
55 ## Distances of propagation (in m)
58 ## Energy of the incoming X-ray beam (in keV)
61 ## Pixel size of the detector (in um)
64 ## Number of projections
67 ## Range of the tomography : 180 or 360 degrees
70 ## Which model do you want to use for the propagation? use 1 or 0
71 ## model_ctf refers to the Contrast Transfer Function propagation model. use 1 if you want to simulate propagation with the CTF model, or 0 otherwise.
72 ## should be equal to 0 or 1
76 ## model_Fresnel refers to the Fresnel propagation model. Use 1 if you want to simulate propagation with the fresnel model, or 0 otherwise.
77 ## should be equal to 0 or 1
81 ################################
82 ############# Parameters related to the object
83 ################################
85 ## height of the object. If height == 1, the simulation is computed in 1D. If height >=2 , the simulation turns into 2D.
89 ################################
90 ############# OPTIONAL Parameters
91 ################################
92 ## Output directory : to be removed
93 %dir_out='/mntdirect/_users/lweber/Matlab/SimulationsPBI/Results_PhantTibo';
97 ## Noise addition to the simulated data?
98 ## Use noise='gaussian' (addition of gaussian noise) or noise='poisson' ( generation of Poisson noise) or '' (no noise is added).
100 %noise_type='gaussian'
101 % default value is '' (no noise)
104 ## If 'gaussian' (additive noise), please specify the Peak-to-peak Signe-to-noise ratio (PPSNR, in dB)
106 %default value is 35 dB
107 ## if 'poisson', please specify the amount of noise
109 % default value is 5%.
110 ## !! note that poisson noise is here not implemented yet
112 #######################################################
113 ############### End of INPUT parameters ###############
114 #######################################################
116 #################################################
117 ############### OUTPUT parameters ###############
118 #################################################
120 ## None, file directly save
122 ########################################################
123 ############### End of OUTPUT parameters ###############
124 ########################################################
126 ############################# check varargin - optional arguments ###########################
128 error("Some arguments are missing.\n");
135 if strcmp(noise_type, 'gaussian')
137 elseif strcmp(noise_type, 'poisson')
138 error("poisson noise is not implemented yet")
139 return; %noise_amount=0.05;
141 error("Unknown type of noise.\n")
146 ############# Unchanged parameters ##############
147 if !strcmp(dir_out, '')
148 dir_out=strcat(dir_out, '/');
151 z1=145; % source to sample distance (in m)
154 angles=[0:1:nbProj-1];
155 delta_angle=range_angle/nbProj;
156 angles=angles*delta_angle;
158 % Wavelength, in meter
159 lambda=12.4*10^-10/energy;
160 ps=ps*10^-6; % put the pixel size in meter
162 % Effective prop distance
163 D = (z1*dist)./(z1+dist);
164 betash = lambda*D; % in meter^2
169 % Absorption image ('mu', in cm-1)
170 mu=edfread('images/attenuation.edf'); % map of mu in cm-1
173 absorption=mu*100; % in m-1 , to be consistant with lambda!! /10 to have less attenuation
174 beta=(lambda/(4*pi))*absorption; % one slice of beta /!\ units
176 delta_beta=edfread('images/delta_beta_map_1200.edf');
177 delta=delta_beta.*beta;
180 if(strcmp(noise_type, 'gaussian'))
182 noise_str=strcat(noise_type, num2str(PPSNR), 'dB_');
183 %elseif(strcmp(noise_type, 'poisson'))
184 %scale_fact=noise_amount;
185 %noise_str=strcat(noise_type, num2str(scale_fact), '_');
186 elseif(strcmp(noise_type, ''))
192 basename_output=strcat(basename_output, '-1D_');
194 basename_output=strcat(basename_output, '-2D_');
197 %############# END OF Unchanged parameters ##############
199 %############# Simulations des donnees ##############
202 ## Creation of the sinogram
203 if(strcmp(vers, 'Radon'))
204 sino_abs=radon(absorption, angles)*ps*oversamp; % to get rif of oversamp in the pixelsize
205 sino_delta=radon(delta, angles)*ps*oversamp;
206 elseif(strcmp(vers, 'Analytical'))
207 [sino_abs, sino_delta, sino_beta] = PhantTibo_Analytical (angles, ps*oversamp, 1);
209 disp('error in the variable vers')
213 ## Creation of the projections
214 abs_proj=cell(1, nbProj);
215 B_proj=cell(1, nbProj);
216 Phi_proj=cell(1, nbProj);
222 abs_proj{j}=interp(sino_abs(:,j), oversamp);
223 B_proj{j}=(1/2)*abs_proj{j};
224 Phi_proj{j}=(-2*pi/lambda)*interp(sino_delta(:,j), oversamp);
228 [mp np]=size(Phi_proj{j});
229 [ftot]=FrequencySpace1(2*mp, ps);
233 IdCTF=cell(length(D), nbProj);
234 sino_IdCTF=cell(length(D),1);
239 sino_IdCTF{k}(:,j)=CTFPropagation_1D(Phi_proj{j}, B_proj{j}, D(k), lambda, oversamp, ftot);
242 if strcmp(noise_type, 'gaussian')
243 ampsignal=max(max(sino_IdCTF{k}))-min(min(sino_IdCTF{k})); %add the amount of noise wrt the amplitude at the first dist
244 bruit=randn(size(sino_IdCTF{k})); % gaussian white noise
245 bruit=bruit/max(max(bruit));
246 bruit=bruit*ampsignal*10^(-PPSNR/20); %/2;
247 sino_IdCTF{k}=sino_IdCTF{k}+bruit;
250 name_ctf=strcat(dir_out, basename_output, 'CTF_', vers, '_oversamp', num2str(oversamp), '_', noise_str, num2str(nbProj), 'proj_', num2str(k), '_.edf')
251 edfwrite(name_ctf, sino_IdCTF{k}, 'float32');
253 end % end of model CTF
255 ### Fresnel model ###
257 IdFresnel=cell(length(D), nbProj);
258 sino_IdFresnel=cell(length(D),1);
262 tmp=FresnelTransform_1D(Phi_proj{j}, B_proj{j}, D(k), lambda, oversamp, ftot);
264 sino_IdFresnel{k}(:,j)=tmp;
267 if strcmp(noise_type, 'gaussian')
268 ampsignal=max(max(sino_IdFresnel{k}))-min(min(sino_IdFresnel{k})); %add the amount of noise wrt the amplitude at the first dist
269 bruit=randn(size(sino_IdFresnel{k})); % gaussian white noise
270 bruit=bruit/max(max(bruit));
271 bruit=bruit*ampsignal*10^(-PPSNR/20); %/2;
272 sino_IdFresnel{k}=sino_IdFresnel{k}+bruit;
275 name_fre=strcat(dir_out, basename_output, 'Fresnel_', vers, '_oversamp', num2str(oversamp), '_', noise_str, num2str(nbProj), 'proj_', num2str(k), '_.edf')
276 edfwrite(name_fre, sino_IdFresnel{k}, 'float32');
278 end % end of Fresnel model
280 ##### case height >=2 (2D) #####
284 abs_proj{j}=repmat(interp(sino_abs(:,j), oversamp), [1 oversamp*height]);
285 B_proj{j}=(1/2)*abs_proj{j};
286 Phi_proj{j}=repmat( interp(sino_delta(:,j), oversamp), [1 oversamp*height]);
287 Phi_proj{j}=(-2*pi/lambda)*Phi_proj{j};
291 [mp np]=size(Phi_proj{j}); % take into account the oversampling
292 [ftot, gtot]=FrequencySpace(2*mp, 2*np, ps);
296 IdCTF=cell(length(D), nbProj);
299 nom=strcat(basename_output, 'CTF_', vers, '_oversamp', num2str(oversamp), '_', noise_str, num2str(nbProj), 'proj_', num2str(k), '_' );
301 if(exist(strcat(dir_out, nom))!=7)
302 unix(['mkdir ' dir_out nom]); % create directory
304 unix(['rm ' dir_out nom '/' basename_output 'CTF*' vers '*edf']); % erase existing proj
305 end % end create directory
308 IdCTF{k, j}=CTFPropagation_2D(Phi_proj{j}, B_proj{j}, D(k), lambda, oversamp, ftot, gtot);
310 if strcmp(noise_type, 'gaussian')
311 ampsignal=max(max(IdCTF{k, j}))-min(min(IdCTF{k, j})); %add the amount of noise wrt the amplitude at the first dist
312 bruit=randn(size(IdCTF{k, j})); % gaussian white noise
313 bruit=bruit/max(max(bruit));
314 bruit=bruit*ampsignal*10^(-PPSNR/20); %/2;
315 IdCTF{k, j}=IdCTF{k, j}+bruit;
318 name_ctf=strcat(dir_out, nom, '/', nom, num2str(j-1, '%0.4d'), '.edf');
319 edfwrite(name_ctf, IdCTF{k,j}, 'float32');
324 #### Fresnel model ###
326 IdFresnel=cell(length(D), nbProj);
329 nom=strcat(basename_output, 'Fresnel_', vers, '_oversamp', num2str(oversamp), '_', noise_str, num2str(nbProj), 'proj_', num2str(k), '_' );
331 if(exist(strcat(dir_out, nom))!=7)
332 unix(['mkdir ' dir_out nom]); % create directory
334 unix(['rm ' dir_out nom '/' basename_output 'Fresnel*' vers '*edf']); % erase existing proj
335 end % end create directory
338 IdFresnel{k, j}=FresnelTransform_2D(Phi_proj{j}, B_proj{j}, D(k), lambda, oversamp, ftot, gtot);
339 if strcmp(noise_type, 'gaussian')
340 ampsignal=max(max(IdFresnel{k, j}))-min(min(IdFresnel{k, j})); %add the amount of noise wrt the amplitude at the first dist
341 bruit=randn(size(IdFresnel{k, j})); % gaussian white noise
342 bruit=bruit/max(max(bruit));
343 bruit=bruit*ampsignal*10^(-PPSNR/20); %/2;
344 IdFresnel{k, j}=IdFresnel{k, j}+bruit;
346 name_fre=strcat(dir_out, nom, '/', nom, num2str(j-1, '%0.4d'), '.edf');
347 edfwrite(name_fre, IdFresnel{k,j}, 'float32');