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