]> Creatis software - CreaPhase.git/blob - SimuPBI_3WiresPhant_func.m
change the path of the images contained in "images" directory (attenuation and phase...
[CreaPhase.git] / SimuPBI_3WiresPhant_func.m
1 ## Copyright (C) 2016 Loriane Weber
2 ## 
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.
7 ## 
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.
12 ## 
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/>.
16
17 ## SimuPBI_3WiresPhant_func
18
19 ## Author: Loriane Weber <lweber@gpid16a-1802>
20 ## Created: 2016-03-30
21
22 ## Example of use :
23 ## SimuPBI_3WiresPhant_func('Analytical', 2, 'test', [0 0.1 0.5], 19, 2.7, 300, 180, 1, 0, '', 'gaussian', 35)
24
25 ## Please note that dir_out, noise_type, noise_amount are optional arguments.
26
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)
28
29 addpath('utilities_ESRF')
30 addpath('utilities_LW')
31 addpath(genpath('octave_packages'))
32
33 ################################################
34 ############### INPUT parameters ############### 
35 ################################################
36
37 ################################
38 ######### Parameter related to the computation - and names of the result
39 ################################
40
41 ## vers: are the projections calculated analytically or using the Radon transform? use 'Radon' OR 'Analytical'
42 %vers='Radon' ; 
43
44 ## Oversampling of the projections : use 2 or 4
45 %oversamp=2
46
47 ## Basename of the result file
48 %basename_output='phantom_al_mg_PET_thibaut_3dist';
49
50 ################################
51 ######### Parameter related to the physics
52 ################################
53
54 ## Distances of propagation (in m)
55 %dist=[0 0.28 0.560]; 
56
57 ## Energy of the incoming X-ray beam (in keV)
58 %energy=19 
59
60 ## Pixel size of the detector (in um)
61 %ps=3.5; 
62
63 ## Number of projections
64 %nbProj=100;
65
66 ## Range of the tomography : 180 or 360 degrees
67 %range_angle=180; 
68
69 ## Which model do you want to use for the propagation? use 1 or 0
70 ## 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.
71 ## should be equal to 0 or 1 
72 % model_ctf = 1
73 % model_ctf = 0
74
75 ## model_Fresnel refers to the Fresnel propagation model. Use 1 if you want to simulate propagation with the fresnel model, or 0 otherwise.
76 ## should be equal to 0 or 1 
77 % model_Fresnel = 1
78 % model_Fresnel = 0
79
80 ################################
81 ############# Parameters related to the object
82 ################################
83
84 ## height of the object. If height == 1, the simulation is computed in 1D. If height >=2 , the simulation turns into 2D.
85 %height=10;
86
87
88 ################################
89 ############# OPTIONAL Parameters
90 ################################
91 ## Output directory : to be removed
92 %dir_out='/mntdirect/_users/lweber/Matlab/SimulationsPBI/Results_PhantTibo'; 
93 %dir_out='';
94
95 ## Noise-related part
96 ## Noise addition to the simulated data? 
97 ## Use noise='gaussian' (addition of gaussian noise) or noise='poisson' ( generation of Poisson noise) or '' (no noise is added).
98
99 %noise_type='gaussian' 
100 % default value is '' (no noise)
101
102 ## Amount of noise
103 ## If 'gaussian' (additive noise), please specify the Peak-to-peak Signe-to-noise ratio (PPSNR, in dB)
104 % noise_amount=40;
105 %default value is 35 dB
106 ## if 'poisson', please specify the amount of noise 
107 %noise_amount=0.05; 
108 % default value is 5%. 
109 ## !! note that poisson noise is here not implemented yet
110
111 #######################################################
112 ############### End of INPUT parameters ############### 
113 #######################################################
114
115 #################################################
116 ############### OUTPUT parameters ############### 
117 #################################################
118
119 ## None, file directly save 
120
121 ########################################################
122 ############### End of OUTPUT parameters ############### 
123 ########################################################
124
125 ############################# check varargin - optional arguments ###########################
126  if nargin<11
127        error("Some arguments are missing.\n");
128  elseif nargin==11
129     dir_out='';
130     noise_type='';
131  elseif nargin==12
132         noise_type='';
133  elseif nargin==13
134         if strcmp(noise_type, 'gaussian')
135                 noise_amount=35;
136         elseif strcmp(noise_type, 'poisson')
137         error("poisson noise is not implemented yet")
138         return; %noise_amount=0.05;
139         else 
140                 error("Unknown type of noise.\n")
141     endif
142 endif
143
144
145 ############# Unchanged parameters ##############
146 if !strcmp(dir_out, '')
147         dir_out=strcat(dir_out, '/');
148 end
149
150 z1=145; % source to sample distance (in m)
151
152 % calcul des angles
153 angles=[0:1:nbProj-1];
154 delta_angle=range_angle/nbProj;
155 angles=angles*delta_angle;
156
157 % Wavelength, in meter
158 lambda=12.4*10^-10/energy;
159 ps=ps*10^-6; % put the pixel size in meter
160
161 % Effective prop distance
162 D = (z1*dist)./(z1+dist);
163 betash = lambda*D; % in meter^2
164
165 % pading method
166 pad_method='extend';
167
168 % Absorption image ('mu', in cm-1)
169 mu=edfread('images/attenuation.edf'); % map of mu in cm-1
170 [m n]=size(mu)
171
172 absorption=mu*100; % in m-1 , to be consistant with lambda!! /10  to have less attenuation
173 beta=(lambda/(4*pi))*absorption; % one slice of beta /!\ units
174
175 delta_beta=edfread('images/delta_beta_map_1200.edf');
176 delta=delta_beta.*beta;
177
178 ## Noise addition
179 if(strcmp(noise_type, 'gaussian'))
180         PPSNR=noise_amount;
181         noise_str=strcat(noise_type, num2str(PPSNR), 'dB_');
182 %elseif(strcmp(noise_type, 'poisson'))
183         %scale_fact=noise_amount;
184         %noise_str=strcat(noise_type, num2str(scale_fact), '_');
185 elseif(strcmp(noise_type, ''))
186         noise_str=''; 
187 end
188
189
190 if height ==1
191         basename_output=strcat(basename_output, '-1D_');
192 else
193         basename_output=strcat(basename_output, '-2D_');
194 end
195
196 %############# END OF Unchanged parameters ##############
197
198 %############# Simulations des donnees ##############
199 ps=ps/oversamp;
200
201 ## Creation of the sinogram
202 if(strcmp(vers, 'Radon'))
203         sino_abs=radon(absorption, angles)*ps*oversamp; % to get rif of oversamp in the pixelsize
204         sino_delta=radon(delta, angles)*ps*oversamp;
205 elseif(strcmp(vers, 'Analytical'))
206         [sino_abs, sino_delta, sino_beta] = PhantTibo_Analytical (angles, ps*oversamp, 1);
207 else
208         disp('error in the variable vers')
209         return;
210 endif
211
212 ## Creation of the projections
213 abs_proj=cell(1, nbProj);
214 B_proj=cell(1, nbProj);
215 Phi_proj=cell(1, nbProj);
216
217
218 if height ==1
219
220         for j=1:nbProj
221                 abs_proj{j}=interp(sino_abs(:,j), oversamp);
222                 B_proj{j}=(1/2)*abs_proj{j}; 
223                 Phi_proj{j}=(-2*pi/lambda)*interp(sino_delta(:,j), oversamp); 
224         end
225         
226         ## Fourier domain
227         [mp np]=size(Phi_proj{j});
228         [ftot]=FrequencySpace1(2*mp, ps);
229
230         ### CTF model ###
231         if(model_ctf==1)
232                 IdCTF=cell(length(D), nbProj);
233                 sino_IdCTF=cell(length(D),1);
234                 
235                 for k=1:length(D)
236
237                         for j=1:nbProj
238                                 sino_IdCTF{k}(:,j)=CTFPropagation_1D(Phi_proj{j}, B_proj{j}, D(k), lambda, oversamp, ftot);
239                         end
240                 
241                         if strcmp(noise_type, 'gaussian')
242                                 ampsignal=max(max(sino_IdCTF{k}))-min(min(sino_IdCTF{k})); %add the amount of noise wrt the amplitude at the first dist
243                                 bruit=randn(size(sino_IdCTF{k})); % gaussian white noise 
244                                 bruit=bruit/max(max(bruit)); 
245                                 bruit=bruit*ampsignal*10^(-PPSNR/20); %/2;
246                                 sino_IdCTF{k}=sino_IdCTF{k}+bruit;
247                         end
248
249                         name_ctf=strcat(dir_out, basename_output, 'CTF_', vers, '_oversamp', num2str(oversamp), '_', noise_str, num2str(nbProj), 'proj_', num2str(k),  '_.edf')
250                         edfwrite(name_ctf, sino_IdCTF{k}, 'float32');
251                 end
252         end % end of model CTF
253
254         ### Fresnel model ###
255         if(model_Fresnel==1)
256                 IdFresnel=cell(length(D), nbProj);
257                 sino_IdFresnel=cell(length(D),1);
258
259                 for k=1:length(D)
260                         for j=1:nbProj
261                                 tmp=FresnelTransform_1D(Phi_proj{j}, B_proj{j}, D(k), lambda, oversamp, ftot);
262                                 IdFresnel{k, j}=tmp;
263                                 sino_IdFresnel{k}(:,j)=tmp;
264                         end
265
266                         if strcmp(noise_type, 'gaussian') 
267                                 ampsignal=max(max(sino_IdFresnel{k}))-min(min(sino_IdFresnel{k})); %add the amount of noise wrt the amplitude at the first dist
268                                 bruit=randn(size(sino_IdFresnel{k})); % gaussian white noise 
269                                 bruit=bruit/max(max(bruit)); 
270                                 bruit=bruit*ampsignal*10^(-PPSNR/20); %/2;
271                                 sino_IdFresnel{k}=sino_IdFresnel{k}+bruit;
272                         end
273                         
274                         name_fre=strcat(dir_out, basename_output, 'Fresnel_', vers, '_oversamp', num2str(oversamp), '_', noise_str, num2str(nbProj), 'proj_', num2str(k), '_.edf')
275                         edfwrite(name_fre, sino_IdFresnel{k}, 'float32');
276                 end
277         end % end of Fresnel model
278
279 ##### case height >=2 (2D) #####
280 else
281
282         for j=1:nbProj
283                 abs_proj{j}=repmat(interp(sino_abs(:,j), oversamp), [1 oversamp*height]);
284                 B_proj{j}=(1/2)*abs_proj{j}; 
285                 Phi_proj{j}=repmat( interp(sino_delta(:,j), oversamp), [1 oversamp*height]);
286                 Phi_proj{j}=(-2*pi/lambda)*Phi_proj{j};
287         end
288
289         ## Fourier domain
290         [mp np]=size(Phi_proj{j}); % take into account the oversampling
291         [ftot, gtot]=FrequencySpace(2*mp, 2*np, ps);
292
293         ### CTF model ###
294         if(model_ctf==1)
295                 IdCTF=cell(length(D), nbProj);
296
297                 for k=1:length(D)
298                         nom=strcat(basename_output, 'CTF_', vers, '_oversamp', num2str(oversamp), '_', noise_str, num2str(nbProj), 'proj_', num2str(k), '_' );
299                 
300                                 if(exist(strcat(dir_out, nom))!=7)
301                                         unix(['mkdir ' dir_out nom]); % create directory
302                                 else 
303                                         unix(['rm ' dir_out nom '/' basename_output 'CTF*' vers '*edf']); % erase existing proj
304                                 end % end create directory
305                 
306                         for j=1:nbProj
307                                 IdCTF{k, j}=CTFPropagation_2D(Phi_proj{j}, B_proj{j}, D(k), lambda, oversamp, ftot, gtot);
308
309                                 if strcmp(noise_type, 'gaussian') 
310                                         ampsignal=max(max(IdCTF{k, j}))-min(min(IdCTF{k, j})); %add the amount of noise wrt the amplitude at the first dist
311                                         bruit=randn(size(IdCTF{k, j})); % gaussian white noise 
312                                         bruit=bruit/max(max(bruit)); 
313                                         bruit=bruit*ampsignal*10^(-PPSNR/20); %/2;
314                                         IdCTF{k, j}=IdCTF{k, j}+bruit;
315                                 end
316                 
317                                 name_ctf=strcat(dir_out, nom, '/', nom, num2str(j-1, '%0.4d'), '.edf');
318                                 edfwrite(name_ctf, IdCTF{k,j}, 'float32');
319                         end % end proj
320                 end % end length
321         end % end ctf
322
323         #### Fresnel model ###
324         if(model_Fresnel==1)
325                 IdFresnel=cell(length(D), nbProj);
326                 
327                 for k=1:length(D)       
328                         nom=strcat(basename_output, 'Fresnel_', vers, '_oversamp', num2str(oversamp), '_', noise_str, num2str(nbProj), 'proj_', num2str(k), '_' );
329                         
330                         if(exist(strcat(dir_out, nom))!=7)
331                                 unix(['mkdir ' dir_out nom]); % create directory
332                         else 
333                                 unix(['rm ' dir_out nom '/' basename_output 'Fresnel*' vers '*edf']); % erase existing proj
334                         end % end create directory
335                         
336                         for j=1:nbProj
337                                 IdFresnel{k, j}=FresnelTransform_2D(Phi_proj{j}, B_proj{j}, D(k), lambda, oversamp, ftot, gtot);
338                                 if strcmp(noise_type, 'gaussian')
339                                         ampsignal=max(max(IdFresnel{k, j}))-min(min(IdFresnel{k, j})); %add the amount of noise wrt the amplitude at the first dist
340                                         bruit=randn(size(IdFresnel{k, j})); % gaussian white noise 
341                                         bruit=bruit/max(max(bruit)); 
342                                         bruit=bruit*ampsignal*10^(-PPSNR/20); %/2;
343                                         IdFresnel{k, j}=IdFresnel{k, j}+bruit;
344                                 end
345                                 name_fre=strcat(dir_out, nom, '/', nom, num2str(j-1, '%0.4d'), '.edf');
346                                 edfwrite(name_fre, IdFresnel{k,j}, 'float32');
347                         end     % end proj
348                 end % end distances
349
350         end %end Fresnel
351
352 end
353         
354
355
356 endfunction