| Bsoft 2.0.5 Bernard's software package

Bimage_fft.cpp
Go to the documentation of this file.
1
11 #include "Bimage.h"
12 #include "timer.h"
13 #include "utilities.h"
14
15 // Declaration of global variables
16 extern int verbose; // Level of output to the screen
17
29 fft_plan Bimage::fft_setup(fft_direction dir, int opt)
30 {
31 return fft_setup_plan(size(), dir, opt);
32 }
33
49 int Bimage::fft(fft_direction dir)
50 {
51 if ( fft(dir, 1) )
52 return error_show("Bimage::fft", __FILE__, __LINE__);
53
54 if ( dir == FFTW_BACKWARD ) {
55 fourier_type(NoTransform);
56 complex_to_real();
57 }
58
59 if ( verbose & VERB_DEBUG )
60 cout << "DEBUG Bimage::fft: datatype=" << datatype << " compoundtype=" << compoundtype << endl;
61
62 return 0;
63 }
64
80 int Bimage::fft(fft_direction dir, bool norm_flag)
81 {
82 if ( !d.uc )
83 return error_show("Error in Bimage::fft_complex: Cannot Fourier transform - the data block is empty!", __FILE__, __LINE__);
84
85 simple_to_complex();
86 change_type(Float);
87
88 long i, imgsize(x*y*z);
89
90 if ( sizeof(fft_complex) != c*data_type_size() ) {
91 error_show("Error in Bimage::fft_complex", __FILE__, __LINE__);
92 cerr << "The FFTW complex number size = " << sizeof(fft_complex) << " (should be " << c*data_type_size() << ")!" << endl;
93 return -1;
94 }
95
96 if ( verbose & VERB_FULL ) {
97 if ( dir == FFTW_FORWARD ) cout << "Doing a forward FFT:" << endl;
98 else cout << "Doing a backward FFT:" << endl;
99 #ifdef FFTW_VERSION
100 cout << "Using FFTW: Version " << FFTW_VERSION << endl;
101 #endif
102 cout << "Complex size: " << sizeof(fft_complex) << endl;
103 cout << "Image size: " << size() << endl;
104 cout << endl;
105 }
106
107 fft_plan plan = fft_setup(dir, 0);
108
109 if ( n == 1 ) {
110 fftw(plan, (Complex<float> *) d.uc);
111 } else {
112 #ifdef HAVE_GCD
113 if ( verbose & VERB_DEBUG )
114 cout << "DEBUG Bimage::fft_complex: GCD FFTW3" << endl;
115 dispatch_apply(n, dispatch_get_global_queue(0, 0), ^(size_t nn){
116 Complex<float>* data = (Complex<float> *) (data_pointer(2*nn*imgsize));
117 fftw(plan, data);
118 });
119 #else
120 #ifdef HAVE_OMP
121 if ( verbose & VERB_DEBUG )
122 cout << "DEBUG Bimage::fft_complex: OpenMP FFTW3" << endl;
123 #pragma omp parallel for
124 #endif
125 for ( long nn=0; nn<n; nn++ ) {
126 Complex<float>* data = (Complex<float> *) (data_pointer(2*nn*imgsize));
127 fftw(plan, data);
128 }
129 #endif
130 }
131
132 fft_destroy_plan(plan);
133
134 // Scale data
135 double scale = 1.0/imgsize;
136 if ( norm_flag == 1 ) scale = sqrt(scale);
137 if ( norm_flag ) {
138 for ( i=0, imgsize *= n; i<imgsize; i++ ) set(i, complex(i) * scale);
139 if ( verbose & VERB_DEBUG )
140 cout << "DEBUG Bimage::fft_complex: scale = " << scale << endl;
141 }
142
143 if ( verbose & VERB_DEBUG )
144 cout << "DEBUG Bimage::fft_complex: FFT done! (" << dir << ")" << endl;
145
146 data_type(Float);
147 compound_type(TComplex);
148 channels(2);
149 fourier_type(Standard);
150
151 // std = 0;
152 // check();
153 statistics();
154
155 return 0;
156 }
157
174 int Bimage::fft(fft_plan plan, bool norm_flag)
175 {
176 if ( !d.uc )
177 return error_show("Error in Bimage::fft_complex: Cannot Fourier transform - the data block is empty!", __FILE__, __LINE__);
178
179 simple_to_complex();
180 change_type(Float);
181
182 long i, nn, imgsize(x*y*z);
183
184 if ( sizeof(fft_complex) != c*data_type_size() ) {
185 error_show("Error in Bimage::fft_complex", __FILE__, __LINE__);
186 cerr << "The FFTW complex number size = " << sizeof(fft_complex) << " (should be " << c*data_type_size() << ")!" << endl;
187 return -1;
188 }
189
190 if ( verbose & VERB_FULL ) {
191 #ifdef FFTW_VERSION
192 cout << "Using FFTW: Version " << FFTW_VERSION << endl;
193 #endif
194 cout << "Complex size: " << sizeof(fft_complex) << endl;
195 cout << "Image size: " << size() << endl;
196 cout << endl;
197 }
198
199 // Specify FFTW arrays
200 Complex<float>* data = (Complex<float> *) data_pointer();
201
202 for ( nn=0; nn<n; nn++, data += imgsize ) {
203 // cout << nn << tab << data << endl;
204 fftw(plan, data);
205 }
206
207 // Scale data
208 double scale = 1.0L/imgsize;
209 if ( norm_flag == 1 ) scale = sqrt(scale);
210 if ( verbose & VERB_DEBUG )
211 cout << "DEBUG Bimage::fft_complex: scale = " << scale << endl;
212 if ( norm_flag )
213 for ( i=0, imgsize *= n; i<imgsize; i++ ) set(i, complex(i) * scale);
214
215 if ( verbose & VERB_DEBUG )
216 cout << "DEBUG Bimage::fft_complex: FFT done!" << endl << endl;
217
218 data_type(Float);
219 compound_type(TComplex);
220 channels(2);
221 fourier_type(Standard);
222
223 // std = 0;
224 // check();
225 statistics();
226
227 return 0;
228 }
229
239 Vector3<double> Bimage::change_transform_size(Vector3<long> nusize)
240 {
241 if ( verbose & VERB_DEBUG )
242 cout << "DEBUG Bimage::change_transform_size: size=" << nusize << endl;
243
244 Vector3<double> scale(nusize[0]*1.0L/x, nusize[1]*1.0L/y, nusize[2]*1.0L/z);
245
246 if ( nusize.volume() < 1 ) return scale;
247 if ( nusize == size() ) return scale;
248
249 if ( verbose & VERB_DEBUG )
250 cout << "DEBUG Bimage::change_transform_size: scale=" << scale << endl;
251
252 if ( compoundtype != TComplex ) {
253 cerr << "Error: Bimage::change_transform_size: Only complex numbers supported!" << endl;
254 return scale;
255 }
256
257 long i, j, nn, xx, yy, zz, iy, iz;
258 long xold, yold, zold, zerox, zeroy, zeroz;
259 Vector3<long> hold, h, d;
260 long ds(n*nusize.volume());
261 Complex<float> cv;
262 Complex<float>* nudata = new Complex<float>[ds];
263 float* fom = NULL;
264 float* nufom = NULL;
265 if ( next ) {
266 fom = (float *) next->data_pointer();
267 nufom = new float[ds];
268 for ( i=0; i<ds; i++ ) {
269 nudata[i] = cv;
270 nufom[i] = 0;
271 }
272 }
273
274 d = nusize - size();
275 hold = (size() - 1)/2;
276 h = (nusize - 1)/2;
277
278 if ( verbose & VERB_DEBUG )
279 cout << "DEBUG Bimage::change_transform_size: datasize=" << ds << endl;
280
281 if ( verbose & VERB_FULL )
282 cout << "Changing transform to size: " << nusize << " voxels" << endl << endl;
283
284 for ( j=nn=0; nn<n; nn++ ) {
285 for ( zz=0; zz<nusize[2]; zz++ ) {
286 zold = zz;
287 if ( zz > h[2] ) zold -= d[2];
288 zeroz = 0;
289 if ( zz > hold[2] && zz <= d[2] + hold[2] ) zeroz += 1;
290 iz = (nn*z + zold)*y;
291 for ( yy=0; yy<nusize[1]; yy++ ) {
292 yold = yy;
293 if ( yy > h[1] ) yold -= d[1];
294 zeroy = zeroz;
295 if ( yy > hold[1] && yy <= d[1] + hold[1] ) zeroy += 1;
296 iy = (iz + yold)*x;
297 for ( xx=0; xx<nusize[0]; xx++, j++ ) {
298 xold = xx;
299 if ( xx > h[0] ) xold -= d[0];
300 zerox = zeroy;
301 if ( xx > hold[0] && xx <= d[0] + hold[0] ) zerox += 1;
302 if ( zerox < 1 ) {
303 i = iy + xold;
304 nudata[j] = complex(i);
305 if ( fom ) nufom[j] = fom[i];
306 }
307 }
308 }
309 }
310 image[nn].origin(scale*image[nn].origin());
311 if ( verbose & VERB_DEBUG )
312 cout << "DEBUG Bimage::change_transform_size: origin[" << n << "]=" << image[nn].origin() << endl;
313
314 }
315
316 sampling(image->sampling()/scale);
317 size(nusize[0], nusize[1], nusize[2]);
318 page_size(size());
319
320 data_assign((unsigned char *) nudata);
321 if ( next ) {
322 next->size(nusize);
323 next->data_assign((unsigned char *) nufom);
324 }
325
326 if ( verbose & VERB_DEBUG )
327 cout << "DEBUG Bimage::change_transform_size: sampling=" << sampling() << endl;
328
329 return scale;
330 }
331
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
verbose
int verbose
Bimage.h
Header file for image class.
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Bimage::data_type_size
long data_type_size() const
Returns the size of the datatype in bytes.
Definition: Bimage.cpp:1585
Bimage::fft
int fft()
Definition: Bimage.h:822
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
Bimage::complex
Complex< double > complex(long j)
Returns a complex value at the given index.
Definition: Bimage.cpp:1005
TypePointer::uc
unsigned char * uc
Definition: Bimage.h:69
TComplex
Definition: Bimage.h:59
timer.h
Utilities for timing functions.
Float
Definition: utilities.h:157
Bimage::statistics
long statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Bimage::data_assign
unsigned char * data_assign(unsigned char *nudata)
Assign image data.
Definition: Bimage.cpp:852
fft_plan
fftwf_plan fft_plan
Definition: fft.h:16
Standard
Definition: Bimage.h:41
Bimage::simple_to_complex
void simple_to_complex()
A simple image is converted to a complex image.
Definition: Bimage_complex.cpp:22
fft_complex
fftwf_complex fft_complex
Definition: fft.h:14
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bimage::channels
long channels()
Definition: Bimage.h:371
Bsub_image::sampling
void sampling(double x, double y, double z)
Definition: Bimage.h:123
fft_direction
int fft_direction
Definition: fft.h:15
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
Bimage::next
Bimage * next
Definition: Bimage.h:165
Bimage::complex_to_real
void complex_to_real()
The real part of a complex image is written to a simple image.
Definition: Bimage_complex.cpp:50
Complex
Definition: Complex.h:23
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
Bimage::fft_setup
fft_plan fft_setup(fft_direction dir, int opt=0)
Sets up a plan for fast Fourier transforms.
Definition: Bimage_fft.cpp:29
Vector3< double >
fft_destroy_plan
int fft_destroy_plan(fft_plan plan)
Deallocates a plan for fast Fourier transforms.
Definition: fft.cpp:87
fft_setup_plan
fft_plan fft_setup_plan(long x, long y, long z, fft_direction dir, int opt)
Sets up a plan for fast Fourier transforms.
Definition: fft.cpp:31
fftw
int fftw(fft_plan plan, Complex< float > *a)
Fast Fourier transforms a data array.
Definition: fft.cpp:106
Bimage::page_size
Vector3< long > page_size()
Definition: Bimage.h:480
NoTransform
Definition: Bimage.h:40
Bimage::change_transform_size
Vector3< double > change_transform_size(Vector3< long > nusize)
Resizes a "standard" transform.
Definition: Bimage_fft.cpp:239
Vector3::volume
double volume()
Definition: Vector3.h:235
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
Bimage::fourier_type
FourierType fourier_type()
Definition: Bimage.h:367
error_show
int error_show(string message, string file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:755
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563