| Bsoft 2.0.5 Bernard's software package

sin_gal.cpp
Go to the documentation of this file.
1
11 #include "sin_gal.h"
12 #include "fft_tool.h"
13 #include "Bimage.h"
14 #include "utilities.h"
15
16 int copy_sin (Bimage * p);
17 int expand (Bimage * p);
18 int merge (Bimage * p, int padd);
19 int cart_pol_Fourier_rad (Bimage * p, int n_theta, int padd, int range, int pf_x, int pf_y, float *pfr, float *pfi, kernel * ker);
20 int separate_ri (Bimage * p, float *pfr, float *pfi, int bordo);
21 int rephase_1D (Bimage * p);
22 int map_shift (Bimage * p, float dx, float dy);
23
34 Bimage *
35 sin_gal (Bimage * p, int tipo, Vector3<float> shift, kernel * ker, int padd, int n_theta)
36 {
37 int i, j;
38 // float t;
39 float *pr, *pfr, *pfi;
40
41 p->change_type(Float);
42
43 Bimage *prad = p->copy_header ();
44
45 prad->sizeY(n_theta / 2);
46 if (tipo != 180)
47 prad->sizeY(n_theta);
48
49 // float *pdest = (float *) malloc (prad->sizeX() * prad->sizeY() * prad->sizeZ() * sizeof (float));
50 // prad->data_assign((unsigned char *) pdest);
51
52 float *psource = (float *) p->data_pointer();
53
54 float *pdest = (float *) prad->data_alloc();
55
56 // cout << "prad size = " << prad->size() << endl;
57
58 int pf_x = p->sizeX() / 2 + ker->bordo;
59 int pf_y = p->sizeY();
60 if (padd)
61 {
62 pf_x = padd * p->sizeX() + ker->bordo;
63 pf_y = 2 * p->sizeY() * padd;
64 }
65
66 if ((pfr = (float *) calloc (2 * pf_x * pf_y, sizeof (float))) == 0)
67 {
68 perror ("sin_gal: pfr error calloc");
69 exit (0);
70 }
71 pfi = pfr + pf_x * pf_y;
72
73 Bimage *ppiano = new Bimage (Float, TSimple, p->sizeX() * (padd + 1), p->sizeY() * (padd + 1), 1, 1);
74 float *piano = (float *) ppiano->data_pointer();
75
76 Bimage *ppol = new Bimage (Float, TSimple, prad->sizeX(), prad->sizeY(), 1, 1);
77
78 // cout << "ppiano size" << ppiano->size() << endl;
79 // cout << "ppol size" << ppol->size() << endl;
80 // cout << "starting sin_gal" << endl;
81
82 char order[12] = "yxz";
83 long p_plane(p->sizeX() * p->sizeY());
84 long prad_plane(prad->sizeX() * prad->sizeY());
85 long piano_plane(ppiano->sizeX() * ppiano->sizeY());
86
87 for (i = 0; i < p->sizeZ(); i++)
88 {
89
90 // swap(ppol->x, ppol->y);
91 j = ppol->sizeX();
92 ppol->sizeX(ppol->sizeY());
93 ppol->sizeY(j);
94 if (tipo == 360)
95 ppol->sizeX(ppol->sizeX() / 2);
96
97 pr = psource + p_plane * i;
98 // cout << "slice " << i << " pointer = " << pr - psource << endl;
99
100 // need to reset because the pointer changes
101 piano = (float *) ppiano->data_pointer();
102
103 for (j = 0; j < p_plane; j++)
104 piano[j] = pr[j];
105 for (j = p_plane; j < piano_plane; j++)
106 piano[j] = 0.;
107
108 if (padd)
109 merge (ppiano, padd);
110
111 fft_2D_forward (ppiano);
112
113 zeroes (ppiano);
114
115 abtori (ppiano);
116
117 // shift 2D in FT //
118 map_shift (ppiano, shift[0], shift[1]);
119
120 // Shift origin
121 rephase_orig (ppiano);
122
123 // Transpose 2D
124 ppiano->reslice(order);
125
126 separate_ri (ppiano, pfr, pfi, ker->bordo);
127
128 cart_pol_Fourier_rad (ppol, n_theta / 2, padd, 180, pf_x, pf_y, pfr, pfi, ker);
129
130 rephase_1D (ppol);
131
132 fft_1D_backward (ppol);
133
134 ppol->reslice(order);
135
136 if (tipo == 360)
137 {
138 ppol->sizeY(ppol->sizeY() * 2);
139 ppol->data_assign((unsigned char *)realloc (ppol->data_pointer(), ppol->sizeX() * ppol->sizeY() * sizeof (float)));
140 copy_sin (ppol);
141 }
142
143 pr = (float *) ppol->data_pointer();
144 memcpy (pdest + prad_plane * i, pr, prad_plane * sizeof (float));
145 }
146
147 // cout << "ending sin_gal" << endl;
148
149 delete ppol;
150 delete ppiano;
151 free (pfr);
152
153 return (prad);
154 }
155
156
162 Bimage *
163 copy_I_part_rad (Bimage * p)
164 {
165 float *pr1, *pr2;
166 int i, j, k, k2, piano, piano2;
167
168 Bimage *p2 = new Bimage (Float, TSimple, p->sizeX() * 2, p->sizeY(), p->sizeZ(), 1);
169 piano = p->sizeX() * p->sizeY();
170 piano2 = p2->sizeX() * p2->sizeY();
171 for (k = 0; k < p->sizeZ(); k++)
172 {
173 pr1 = (float *) p->data_pointer() + k * piano;
174 pr2 = (float *) p2->data_pointer() + k * piano2;
175 for (j = 0; j < p->sizeY(); j++, pr2 += p->sizeX())
176 for (i = 0; i < p->sizeX(); i++)
177 *pr2++ = *pr1++;
178
179 k2 = (p->sizeZ() - k) % p->sizeZ();
180 pr1 = (float *) p->data_pointer() + k * piano;
181 pr2 = (float *) p2->data_pointer() + k2 * piano2 + p->sizeX();
182 for (j = 0; j < p->sizeY(); j++, pr2 += p->sizeX())
183 for (i = 0; i < p->sizeX(); i++)
184 *pr2++ = *pr1++;
185 }
186 return (p2);
187 }
188
194 int
195 copy_II_part_rad (Bimage * p)
196 {
197 float *pr1, *pr2, *pr3, *pr4;
198 int i, j, k, j1, j2;
199
200 expand (p);
201
202 float *pr = (float *) p->data_pointer();
203
204 pr1 = pr;
205 pr2 = pr + p->sizeX() * p->sizeY() / 2;
206 for (k = 0; k < p->sizeY() / 2; k++)
207 {
208 j1 = p->sizeX() / 4;
209 for (j = 0; j < p->sizeX(); j++)
210 {
211 j1 = (p->sizeX() + p->sizeX() / 4 - j) % p->sizeX();
212 j2 = (p->sizeX() + p->sizeX() / 4 + j) % p->sizeX();
213 pr3 = pr1 + j1;
214 pr4 = pr2 + j2;
215 for (i = 0; i < p->sizeZ(); i++)
216 {
217 *pr4 = *pr3;
218 pr4 += p->sizeX() * p->sizeY();
219 pr3 += p->sizeX() * p->sizeY();
220 }
221 }
222 pr1 += p->sizeX();
223 pr2 += p->sizeX();
224 }
225 return 0;
226 }
227
228
234 int
235 expand (Bimage * p)
236 {
237 float *pr1, *pr2;
238 unsigned long j, k;
239
240 unsigned long datasize = p->sizeX() * p->sizeY() * p->sizeZ() * sizeof (float);
241 unsigned long planesize = p->sizeX() * p->sizeY();
242 float *pv = (float *) p->data_pointer();
243 float *pr = (float *) malloc (datasize * 2);
244
245 memcpy (pr, pv, datasize);
246 // free (pv);
247
248 for (k = p->sizeZ() - 1; k > 0; k--)
249 {
250 pr1 = pr + k * planesize;
251 pr2 = pr + k * planesize * 2;
252 for (j = 0; j < planesize; j++)
253 *pr2++ = *pr1++;
254 }
255
256 p->data_assign((unsigned char *) pr);
257 p->sizeY(p->sizeY()*2);
258 // free(pv);
259
260 return 0;
261 }
262
269 int
270 merge (Bimage * p, int padd)
271 {
272 int i, j, offset, nr_old;
273 float *pr1, *pr2;
274
275 float *pr = (float *) p->data_pointer();
276
277 // cout << "merge: pad=" << padd << endl;
278
279 nr_old = p->sizeY() / (padd + 1);
280 offset = (int) (p->sizeY() * 3.0 / 8);
281 if (padd == 1)
282 offset = p->sizeY() / 4;
283
284 pr2 = pr;
285 pr1 = pr + p->sizeX() * offset + offset;
286 for (i = 0; i < nr_old; i++)
287 {
288 for (j = 0; j < nr_old; j++)
289 *pr1++ = *pr2++;
290 pr1 += 2 * offset;
291 }
292 j = p->sizeX() * p->sizeY() / 4;
293 pr1 = pr;
294 for (i = 0; i < j; i++)
295 *pr1++ = 0.;
296
297 return 0;
298 }
299
313 int
314 cart_pol_Fourier_rad (Bimage * p, int n_theta, int padd, int range, int pf_x, int pf_y, float *pfr, float *pfi, kernel * ker)
315 {
316 int i, j, k, jmin, jmax, kmin, kmax, row, col, nkm1, rnk, rowmax;
317 float *pr1, *pf1, *pr2, *pf2, *itbx, *itby;
318 float fat, x, y, r, theta, xyt, totx, toty, memo, weight, round;
319
320 float *pr = (float *) p->data_pointer();
321
322 round = 1. / (2 * ker->nkern);
323 weight = 1.;
324 if (padd == 1)
325 weight = 4.;
326 if (padd == 2)
327 weight = 16.;
328 rnk = ker->nk; // Kernel size
329 if (range == 360)
330 fat = 2 * M_PI / n_theta; // fat is simply radians/degrees
331 else
332 fat = M_PI / n_theta;
333 nkm1 = ker->bordo;
334 // if (ker->nk % 2 == 0)
335 // nkm1 = ker->nk / 2 - 1;
336 // else
337 // nkm1 = (ker->nk - 1) / 2;
338 rowmax = pf_y;
339 if (padd == 1)
340 rowmax /= 2;
341 if (padd == 2)
342 rowmax /= 4;
343 for (row = 0; row < rowmax; row += 2)
344 {
345 pr1 = pr + row * n_theta;
346 pr2 = pr1 + n_theta;
347 r = (float) row *.5;
348 if (padd)
349 r *= 2*padd;
350 for (col = 0; col < n_theta; col++)
351 {
352 theta = col * fat;
353 memo = 1;
354 while (theta > M_PI)
355 theta -= 2 * M_PI; // Range -PI to PI
356 while (theta < -M_PI)
357 theta += 2 * M_PI;
358 if (theta > M_PI / 2) // Range -PI/2 to PI/2
359 {
360 theta -= M_PI;
361 memo = -1;
362 }
363 if (theta < -M_PI / 2)
364 {
365 theta += M_PI;
366 memo = -1;
367 }
368 x = r * cos (theta) + ker->bordo + round;
369 y = r * sin (theta) + pf_y / 2 + round;
370
371 xyt = floor (y);
372 j = (int) (ker->nkern * (y - xyt)); // Fraction * size of kernel ( = 512 )
373 j *= rnk; // Starting pount in LUT
374 itby = ker->kern + j; // Pointer to starting point in LUT
375 i = (int) xyt;
376 i -= nkm1;
377 j = i + rnk;
378 if (i < 0 || j > pf_y)
379 {
380 if (i < 0)
381 {
382 jmin = -i;
383 jmax = rnk;
384 itby -= i;
385 i = 0;
386 }
387 else
388 {
389 jmin = 0;
390 jmax = pf_y - i;
391 }
392 }
393 else
394 {
395 jmin = 0;
396 jmax = rnk;
397 }
398
399 pf1 = pfr + i * pf_x;
400 pf2 = pfi + i * pf_x;
401
402 xyt = floor (x);
403 j = (int) (ker->nkern * (x - xyt));
404 j *= rnk;
405 itbx = ker->kern + j;
406 i = (int) xyt;
407 i -= nkm1;
408 j = i + rnk;
409 if (i < 0 || j > pf_x)
410 {
411 if (i < 0)
412 {
413 kmin = -i;
414 kmax = rnk;
415 itbx -= i;
416 i = 0;
417 }
418 else
419 {
420 kmin = 0;
421 kmax = pf_x - i;
422 }
423 }
424 else
425 {
426 kmin = 0;
427 kmax = rnk;
428 }
429
430 pf1 = pf1 + i;
431 pf2 = pf2 + i;
432
433 toty = 0;
434 for (j = jmin; j < jmax; j++)
435 {
436 totx = 0.;
437 for (k = kmin; k < kmax; k++)
438 totx += *itbx++ * *pf1++;
439 toty += *itby++ * totx;
440 itbx -= kmax - kmin;
441 pf1 += pf_x - (kmax - kmin);
442 }
443 *pr1++ = toty * weight;
444
445 itby -= jmax - jmin;
446 toty = 0;
447 for (j = jmin; j < jmax; j++)
448 {
449 totx = 0.;
450 for (k = kmin; k < kmax; k++)
451 totx += *itbx++ * *pf2++;
452 toty += *itby++ * totx;
453 itbx -= kmax - kmin;
454 pf2 += pf_x - (kmax - kmin);
455 }
456 *pr2++ = toty * memo * weight;
457 }
458 }
459 return 0;
460 }
461
470 int
471 separate_ri (Bimage * p, float *pfr, float *pfi, int bordo)
472 {
473 int i, j, row, ncol, hx, hy;
474 float *pr1, *pfr1, *pfr2, *pfi1, *pfi2;
475
476 float *pr = (float *) p->data_pointer();
477
478 hx = p->sizeX()/2;
479 hy = p->sizeY()/2;
480 ncol = hx + bordo;
481 pfr1 = pfr + ncol + bordo;
482 pfi1 = pfi + ncol + bordo;
483 for (i = -hy + 1; i < hy; i++)
484 {
485 pfr2 = pfr1;
486 row = abs (i);
487 pr1 = pr + row * p->sizeX() * 2;
488 if (i < 0)
489 pr1 += p->sizeX() + 1;
490 for (j = 0; j < hx; j++)
491 {
492 *pfr2++ = *pr1;
493 pr1 += 2;
494 }
495 pfi2 = pfi1;
496 pr1 = pr + row * p->sizeX() * 2 + 1;
497 if (i < 0)
498 pr1 += p->sizeX() - 1;
499 for (j = 0; j < hx; j++)
500 {
501 *pfi2++ = *pr1;
502 pr1 += 2;
503 }
504 pfr1 += ncol;
505 pfi1 += ncol;
506 }
507 pfr1 = pfr + ncol + bordo + 1;
508 pfr2 = pfr + ncol * (p->sizeY() - 1) + bordo - 1;
509 for (i = -hy + 1; i < hy; i++)
510 {
511 for (j = 0; j < bordo; j++)
512 *pfr2-- = *pfr1++;
513 pfr1 += ncol - bordo;
514 pfr2 -= ncol - bordo;
515 }
516 pfi1 = pfi + ncol + bordo + 1;
517 pfi2 = pfi + ncol * (p->sizeY() - 1) + bordo - 1;
518 for (i = -hy + 1; i < hy; i++)
519 {
520 for (j = 0; j < bordo; j++)
521 *pfi2-- = -*pfi1++;
522 pfi1 += ncol - bordo;
523 pfi2 -= ncol - bordo;
524 }
525 return 0;
526 }
527
533 int
534 rephase_1D (Bimage * p)
535 {
536 float *pr1, *pr2;
537 float meno;
538 int ncol2;
539
540 float *pr = (float *) p->data_pointer();
541
542 ncol2 = 2 * p->sizeX();
543 meno = 1.;
544 for (pr1 = pr + p->sizeX(); pr1 < pr + ncol2; pr1++)
545 *pr1 = 0.;
546 for (pr1 = pr + ncol2; pr1 < pr + p->sizeX() * p->sizeY(); pr1 += ncol2)
547 {
548 meno *= -1.;
549 for (pr2 = pr1; pr2 < pr1 + ncol2; pr2++)
550 *pr2 *= meno;
551 }
552
553 return 0;
554 }
555
563 int
564 map_shift (Bimage * p, float dx, float dy)
565 {
566 if (dx == 0 && dy == 0)
567 return 0;
568
569 int j, k;
570 float *Rp, *Rm, *Ip, *Im;
571 float a1, a2, cs1, sn1, cs2, sn2, csa, sna;
572 float vr, vi, val;
573
574 float *pr = (float *) p->data_pointer();
575
576 a1 = -dx * M_PI / (p->sizeY() / 2);
577 a2 = -dy * M_PI / (p->sizeX() / 2);
578 cs1 = cos (a1);
579 sn1 = sin (a1);
580 cs2 = cos (a2);
581 sn2 = sin (a2);
582
583 // shift on x //
584 csa = 1.;
585 sna = 0.;
586 for (j = 0; j < p->sizeY(); j += 2)
587 {
588 Rp = pr + j * p->sizeX();
589 Im = Rp + 1;
590 Ip = Rp + p->sizeX();
591 Rm = Ip + 1;
592 for (k = 0; k < p->sizeX(); k += 2)
593 {
594 vr = *Rp * csa - *Ip * sna;
595 vi = *Rp * sna + *Ip * csa;
596 *Rp = vr;
597 *Ip = vi;
598 vr = *Rm * csa - *Im * sna;
599 vi = *Rm * sna + *Im * csa;
600 *Rm = vr;
601 *Im = vi;
602 Rp += 2;
603 Ip += 2;
604 Rm += 2;
605 Im += 2;
606 }
607 val = csa * cs1 - sna * sn1;
608 sna = csa * sn1 + sna * cs1;
609 csa = val;
610 }
611
612 // shift on y //
613 csa = 1.;
614 sna = 0.;
615 for (j = 0; j < p->sizeX(); j += 2)
616 {
617 Rp = pr + j;
618 Im = Rp + 1;
619 Ip = Rp + p->sizeX();
620 Rm = Ip + 1;
621 for (k = 0; k < p->sizeY(); k += 2)
622 {
623 vr = *Rp * csa - *Ip * sna;
624 vi = *Rp * sna + *Ip * csa;
625 *Rp = vr;
626 *Ip = vi;
627 vr = *Rm * csa + *Im * sna;
628 vi = -*Rm * sna + *Im * csa;
629 *Rm = vr;
630 *Im = vi;
631 Rp += 2 * p->sizeX();
632 Ip += 2 * p->sizeX();
633 Rm += 2 * p->sizeX();
634 Im += 2 * p->sizeX();
635 }
636 val = csa * cs2 - sna * sn2;
637 sna = csa * sn2 + sna * cs2;
638 csa = val;
639 }
640 return 0;
641 }
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
kernel::nk
int nk
Definition: kernlut.h:15
Bimage::copy_header
Bimage * copy_header()
Definition: Bimage.h:650
copy_I_part_rad
Bimage * copy_I_part_rad(Bimage *p)
Definition: sin_gal.cpp:163
fft_tool.h
Bimage.h
Header file for image class.
utilities.h
Header file for general utilities.
kernel::nkern
int nkern
Definition: kernlut.h:17
rephase_1D
int rephase_1D(Bimage *p)
Definition: sin_gal.cpp:534
zeroes
int zeroes(Bimage *p)
Definition: fft_tool.cpp:373
copy_II_part_rad
int copy_II_part_rad(Bimage *p)
Definition: sin_gal.cpp:195
abtori
int abtori(Bimage *p)
Changes direct Fourier transform representation.
Definition: fft_tool.cpp:280
map_shift
int map_shift(Bimage *p, float dx, float dy)
Definition: sin_gal.cpp:564
TSimple
Definition: Bimage.h:58
Float
Definition: utilities.h:157
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:256
M_PI
#define M_PI
Definition: utilities.h:59
fft_2D_forward
int fft_2D_forward(Bimage *p)
Definition: fft_tool.cpp:41
Bimage::data_assign
unsigned char * data_assign(unsigned char *nudata)
Assign image data.
Definition: Bimage.cpp:852
merge
int merge(Bimage *p, int padd)
Pads an image and shifts it to the middle.
Definition: sin_gal.cpp:270
cart_pol_Fourier_rad
int cart_pol_Fourier_rad(Bimage *p, int n_theta, int padd, int range, int pf_x, int pf_y, float *pfr, float *pfi, kernel *ker)
Definition: sin_gal.cpp:314
Bimage::reslice
void reslice(const char *order)
Definition: Bimage.h:709
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
kmin
long kmin(long i, long hk)
Definition: Bimage_filter.cpp:17
kmax
long kmax(long i, long km, long m)
Definition: Bimage_filter.cpp:22
fft_1D_backward
int fft_1D_backward(Bimage *p)
Definition: fft_tool.cpp:29
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
Vector3< float >
kernel::bordo
int bordo
Definition: kernlut.h:19
sin_gal
Bimage * sin_gal(Bimage *p, int tipo, Vector3< float > shift, kernel *ker, int padd, int n_theta)
Definition: sin_gal.cpp:35
copy_sin
int copy_sin(Bimage *p)
Copy the second half of a sinogram from the first one.
Definition: pocs_tool.cpp:179
kernel
Definition: kernlut.h:13
separate_ri
int separate_ri(Bimage *p, float *pfr, float *pfi, int bordo)
Definition: sin_gal.cpp:471
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
expand
int expand(Bimage *p)
Definition: sin_gal.cpp:235
kernel::kern
float * kern
Definition: kernlut.h:20
sin_gal.h
rephase_orig
int rephase_orig(Bimage *p)
Shifting the origin by half the complex image size.
Definition: fft_tool.cpp:407