| Bsoft 2.0.5 Bernard's software package

Bimage_helix.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "mg_reconstruct.h"
11 #include "matrix_linear.h"
12 #include "symmetry.h"
13 #include "utilities.h"
14
15 // Declaration of global variables
16 extern int verbose; // Level of output to the screen
17
18 double Bimage::helix_interpolate(long i, double helix_rise, double helix_angle,
19 int zmin, int zmax, double radius, int norm_flag)
20 {
21 long xx, yy, zz, nn;
22 coordinates(i, xx, yy, zz, nn);
23
24 Vector3<double> d = Vector3<double>(xx - image[nn].origin()[0], yy - image[nn].origin()[1], 0);
25 double r = d.length();
26
27 if ( r > radius ) return 0;
28
29 long num(0), u;
30 double pix_rise(helix_rise/image->sampling()[2]);
31 double a, cosang, sinang, value(0);
32 double xs, ys, zs;
33 long umin = (long)((zmin-(float)zz)/pix_rise);
34 if ( zz < zmin ) umin += 1;
35 long umax = (long)((zmax-(float)zz)/pix_rise);
36 if ( zz > zmax ) umax -= 1;
37
38 for ( u = umin; u <= umax; u++ ) {
39 a = u*helix_angle;
40 cosang = cos(a);
41 sinang = sin(a);
42 zs = zz + u*pix_rise;
43 xs = d[0]*cosang - d[1]*sinang + image[nn].origin()[0];
44 ys = d[0]*sinang + d[1]*cosang + image[nn].origin()[1];
45 if ( within_boundaries((long)xs, (long)ys, (long)zs) ) {
46 value += interpolate(xs, ys, zs, nn, 0);
47 num += 1;
48 }
49 }
50
51 if ( norm_flag && num ) value /= num;
52
53 return value;
54 }
55
56 double Bimage::dyad_interpolate(long i, int norm_flag)
57 {
58 long xx, yy, zz, nn;
59 coordinates(i, xx, yy, zz, nn);
60
61 double value = (*this)[i];
62 double xd(xx);
63 double yd(2 * image[nn].origin()[1] - (double)yy);
64 double zd(2 * image[nn].origin()[2] - (double)zz);
65
66 value += interpolate(xd, yd, zd, nn, background(nn));
67
68 if ( norm_flag ) value /= 2;
69
70 return value;
71 }
72
73 double Bimage::tube_interpolate(long i, int h, int k,
74 double latconst, int zmin, int zmax, double radius, int norm_flag)
75 {
76 long xx, yy, zz, nn;
77 coordinates(i, xx, yy, zz, nn);
78
79 Vector3<double> d = Vector3<double>(xx - image[nn].origin()[0], yy - image[nn].origin()[1], 0);
80 double r = d.length();
81
82 if ( r > radius ) return 0;
83
84 long num(0);
85 double da(atan2(d[1], d[0]));
86 double pix_rise(latconst/image->sampling()[2]);
87
88 double t(sqrt(h*h + h*k + k*k));
89 double a(atan2(k*sqrt(3.0)/2, h+k/2.0));
90 Vector3<double> u(cos(a), -sin(a), 0), v(cos(M_PI/3-a), sin(M_PI/3-a), 0);
91 Vector3<double> w(v - u);
92 Vector3<double> lat, start, loc;
93 double value(0), bottom(zmin/pix_rise), top(zmax/pix_rise);
94
95 start[1] = zz/pix_rise;
96 while ( start[1] < bottom ) start += w;
97 while ( start[1] > bottom ) start -= w;
98
99 while ( lat[1] < top ) {
100 for ( lat = start; lat[0] < t + start[0]; lat += u ) {
101 if ( lat[1] >= bottom && lat[1] <= top ) {
102 a = da + TWOPI * lat[0]/t;
103 loc[0] = r*cos(a) + image[nn].origin()[0];
104 loc[1] = r*sin(a) + image[nn].origin()[1];
105 loc[2] = lat[1] * pix_rise;
106 value += interpolate(loc, nn, 0);
107 num++;
108 }
109 }
110 start += w;
111 }
112
113 if ( norm_flag && num ) value /= num;
114
115 return value;
116 }
117
133 double Bimage::helix_symmetrize(double helix_rise, double helix_angle,
134 int dyad_axis, int zmin, int zmax, double radius, int norm_flag)
135 {
136 change_type(Float);
137
138 if ( helix_rise < 0 ) {
139 helix_rise = -helix_rise;
140 helix_angle = -helix_angle;
141 }
142
143 if ( radius <= 0 ) radius = x/2;
144
145 if ( zmin < 0 ) zmin = 0;
146 if ( zmax >= z ) zmax = z - 1;
147
148 double pix_rise = helix_rise/image->sampling()[2];
149 long nun((long) ((zmax - zmin)/pix_rise));
150
151 long i;
152 double v, vr, d, nsum(0), sum1(0), sum2(0), sum1sq(0), sum2sq(0), sum12(0), R(1e37), CC(0);
153 double w, ndsum(0), dsum1(0), dsum2(0), dsum1sq(0), dsum2sq(0), dsum12(0), Rd, CCd;
154
155 float* symdata = new float[datasize];
156 for ( i=0; i<datasize; i++ ) symdata[i] = 0;
157
158 if ( verbose & VERB_LABEL ) {
159 cout << "Helical symmetrization:" << endl;
160 cout << "Helical axis origin: " << image->origin() << endl;
161 cout << "Asymmetric unit rise: " << helix_rise << " A" << endl;
162 cout << "Asymmetric unit rotation angle: " << helix_angle*180/M_PI << " degrees" << endl;
163 if ( dyad_axis == 2 ) cout << "Dyad axis along the x axis" << endl;
164 cout << "Radius: " << radius << " pixels" << endl;
165 cout << "Limits along helical axis: " << zmin << " - " << zmax << " pixels" << endl;
166 cout << "Units along helical axis: " << nun << endl;
167 }
168
169 if ( norm_flag) w = 1;
170 else w = nun;
171
172 symmetry(symmetry_helical_label(helix_rise, helix_angle, dyad_axis, 1, 1));
173
174 #ifdef HAVE_GCD
175 dispatch_apply(datasize, dispatch_get_global_queue(0, 0), ^(size_t k){
176 symdata[k] = helix_interpolate(k, helix_rise, helix_angle, zmin, zmax, radius, norm_flag);
177 });
178 #else
179 #pragma omp parallel for
180 for ( i=0; i<datasize; i++ )
181 symdata[i] = helix_interpolate(i, helix_rise, helix_angle, zmin, zmax, radius, norm_flag);
182 #endif
183
184 for ( i=0; i<datasize; i++ ) {
185 v = symdata[i];
186 if ( v ) {
187 vr = w * (*this)[i];
188 sum1 += vr;
189 sum2 += v;
190 sum1sq += vr * vr;
191 sum2sq += v * v;
192 sum12 += vr * v;
193 nsum += 1;
194 }
195 set(i, v);
196 }
197
198 if ( dyad_axis == 2 ) {
199
200 if ( !norm_flag ) w = 2;
201
202 #ifdef HAVE_GCD
203 dispatch_apply(datasize, dispatch_get_global_queue(0, 0), ^(size_t k){
204 symdata[k] = dyad_interpolate(k, norm_flag);
205 });
206 #else
207 #pragma omp parallel for
208 for ( i=0; i<datasize; i++ )
209 symdata[i] = dyad_interpolate(i, norm_flag);
210 #endif
211
212 for ( i=0; i<datasize; i++ ) {
213 v = symdata[i];
214 if ( v ) {
215 vr = w * (*this)[i];
216 dsum1 += vr;
217 dsum2 += v;
218 dsum1sq += vr * vr;
219 dsum2sq += v * v;
220 dsum12 += vr * v;
221 ndsum += 1;
222 }
223 set(i, v);
224 }
225 }
226
227 if ( nsum ) {
228 d = (sum1sq - sum1*sum1/nsum)*(sum2sq - sum2*sum2/nsum);
229 if ( d > 0 ) {
230 d = sqrt(d);
231 R = sqrt((sum1sq - 2*sum12 + sum2sq)/d);
232 CC = (sum12 - sum1*sum2/nsum)/d;
233 }
234 }
235
236 if ( ndsum ) {
237 d = (dsum1sq - dsum1*dsum1/ndsum)*(dsum2sq - dsum2*dsum2/ndsum);
238 if ( d > 0 ) {
239 d = sqrt(d);
240 Rd = sqrt((dsum1sq - 2*dsum12 + dsum2sq)/d);
241 CCd = (dsum12 - dsum1*dsum2/ndsum)/d;
242 }
243 }
244
245 if ( verbose ) {
246 cout << "Helical symmetry R factor: " << R << endl;
247 cout << "Helical symmetry correlation: " << CC << endl;
248 if ( dyad_axis == 2 ) {
249 cout << "Dyad R factor: " << Rd << endl;
250 cout << "Dyad correlation: " << CCd << endl;
251 }
252 }
253
254 if ( verbose >= VERB_LABEL )
255 cout << endl;
256
257 delete[] symdata;
258
259 statistics();
260
261 return R;
262 }
263
280 Bplot* Bimage::seamed_helix_symmetrize(double helix_rise, double helix_angle,
281 double seam_shift, int dyad_axis, int zmin, int zmax, double radius, int norm_flag)
282 {
283 change_type(Float);
284
285 if ( helix_rise < 0 ) {
286 helix_rise = -helix_rise;
287 helix_angle = -helix_angle;
288 }
289
290 if ( zmin < 0 ) zmin = 0;
291 if ( zmax >= z ) zmax = z - 1;
292 if ( zmax < zmin ) swap(zmin, zmax);
293
294 long nproto((long) (TWOPI/fabs(helix_angle) + 0.5));
295 double seam_rise(nproto*helix_rise/seam_shift);
296 double seam_angle(angle_set_negPI_to_PI(nproto*helix_angle)/seam_shift);
297 double pix_helix_rise(helix_rise/image->sampling()[2]);
298 double pix_seam_rise(seam_rise/image->sampling()[2]);
299 double hr(helix_angle*pix_seam_rise - seam_angle*pix_helix_rise);
300 double daz(seam_angle/pix_seam_rise);
301
302 if ( verbose & VERB_LABEL ) {
303 cout << "Helical symmetrization with a seam with a shift of " << seam_shift << ":" << endl;
304 cout << "Asymmetric unit rise: " << helix_rise << " A" << endl;
305 cout << "Asymmetric unit rotation angle: " << helix_angle*180/M_PI << " degrees" << endl;
306 cout << "Number of protofilaments: " << nproto << endl;
307 cout << "Seam rise: " << seam_rise << " A" << endl;
308 cout << "Seam rotation angle: " << seam_angle*180/M_PI << " degrees" << endl;
309 cout << "Origin: " << image->origin() << endl;
310 cout << "Limits along helical axis: " << zmin << " - " << zmax << " pixels" << endl;
311 cout << "Units along helical axis: " << (long) ((zmax - zmin)*nproto/pix_seam_rise) << endl << endl;
312 }
313
314 long i, xx, yy, zz, nn;
315 long u, h, k, kmin, kmax;
316 double xs, ys, zs, dx, dy, dz, d, d2;
317 double rad(0), radsq, a, sa, da, as, cosang, sinang;
318 double v, vr, CC, R(0);
319
320 float* symdata = new float[datasize];
321 float* num = new float[datasize];
322
323 long ia, na(360);
324 double* nsum = new double[na];
325 double* s1 = new double[na];
326 double* s2 = new double[na];
327 double* s1sq = new double[na];
328 double* s2sq = new double[na];
329 double* s12 = new double[na];
330
331 for ( i=0; i<datasize; i++ ) symdata[i] = num[i] = 0;
332
333 for ( u=0; u<na; u++ ) nsum[u] = s1[u] = s2[u] = s1sq[u] = s2sq[u] = s12[u] = 0;
334
335 for ( i=nn=0; nn<n; nn++ ) {
336 if ( radius > 0 ) rad = radius;
337 if ( rad > image[nn].origin()[0] ) rad = image[nn].origin()[0];
338 if ( rad > image[nn].origin()[1] ) rad = image[nn].origin()[1];
339 if ( rad > x - image[nn].origin()[0] + 1 )
340 rad = x - image[nn].origin()[0] + 1;
341 if ( rad > y - image[nn].origin()[1] + 1 )
342 rad = y - image[nn].origin()[1] + 1;
343 if ( rad < 1 ) rad = x/2;
344 radsq = rad*rad;
345 for ( zz=0; zz<z; zz++ ) {
346 dz = (double)zz - image[nn].origin()[2];
347 sa = daz*dz;
348 kmin = (long)((zmin-(double)zz)/pix_seam_rise);
349 if ( zz < zmin ) kmin += 1;
350 kmax = (long)((zmax-(double)zz)/pix_seam_rise);
351 if ( zz > zmax ) kmax -= 1;
352 for ( yy=0; yy<y; yy++ ) {
353 dy = (double)yy - image[nn].origin()[1];
354 for ( xx=0; xx<x; xx++, i++ ) {
355 dx = (double)xx - image[nn].origin()[0];
356 d2 = dx*dx + dy*dy;
357 if ( d2 <= radsq ) {
358 a = atan2(dy, dx);
359 if ( a*pix_seam_rise < seam_angle*dz ) a += TWOPI;
360 da = a - sa;
361 if ( da < 0 ) da += TWOPI;
362 if ( da >= TWOPI ) da -= TWOPI;
363 ia = (long) (na*da/TWOPI);
364 if ( ia < 0 ) ia += na;
365 if ( ia >= na ) ia -= na;
366 u = (long) ((a*pix_seam_rise - seam_angle*dz)/hr);
367 while ( u < 0 ) u += nproto;
368 while ( u >= nproto ) u -= nproto;
369 vr = (*this)[i];
370 for ( k=kmin; k<=kmax; k++ ) {
371 for ( h=-u; h<nproto-u; h++ ) {
372 zs = zz + h*pix_helix_rise + k*pix_seam_rise;
373 as = h*helix_angle + k*seam_angle;
374 cosang = cos(as);
375 sinang = sin(as);
376 xs = dx*cosang - dy*sinang + image[nn].origin()[0];
377 ys = dx*sinang + dy*cosang + image[nn].origin()[1];
378 if ( within_boundaries((long)xs, (long)ys, (long)zs) ) {
379 v = interpolate(xs, ys, zs, nn, 0.0);
380 s1[ia] += vr;
381 s2[ia] += v;
382 s1sq[ia] += vr * vr;
383 s2sq[ia] += v * v;
384 s12[ia] += vr * v;
385 nsum[ia] += 1;
386 symdata[i] += v;
387 num[i] += 1;
388 }
389 }
390 }
391 }
392 }
393 }
394 if ( verbose & VERB_PROCESS )
395 cout << "Completed: " << (nn*z+zz)*100.0/(n*z) << " %" << "\r" << flush;
396 }
397 }
398
399 if ( norm_flag )
400 for ( i=0; i<datasize; i++ )
401 if ( num[i] ) symdata[i] /= num[i];
402
403 data_assign((unsigned char *) symdata);
404
405 statistics();
406
407 symmetry(symmetry_helical_label(helix_rise, helix_angle, dyad_axis, 1, seam_shift));
408
409 for ( ia=0; ia<na; ia++ ) {
410 R = 1;
411 CC = 0;
412 if ( nsum[ia] ) {
413 d = (s1sq[ia] - s1[ia]*s1[ia]/nsum[ia])*(s2sq[ia] - s2[ia]*s2[ia]/nsum[ia]);
414 if ( d > 0 ) {
415 R = sqrt(nsum[ia]*(s1sq[ia] - 2*s12[ia] + s2sq[ia])/d);
416 CC = (s12[ia] - s1[ia]*s2[ia]/nsum[ia])/sqrt(d);
417 s12[ia] = CC;
418 }
419 }
420 }
421
422 if ( verbose & VERB_PROCESS ) {
423 cout << "Helical symmetry R factor: " << R << endl;
424 cout << "Helical symmetry correlation: " << CC << endl << endl;
425 }
426
427
428 long umin, umax, ulen(na/(2*nproto) + 1);
429 double cc_min, cc_max, cc_cut, angle_best(0);
430
431 Bstring title("Seamed helix symmetrization");
432 long ncol(2);
433 Bplot* plot = new Bplot(1, na, ncol);
434 plot->title(title);
435 plot->page(0).title(title);
436 plot->page(0).columns(ncol);
437 for ( i=0; i<ncol; i++ ) plot->page(0).column(i).number(i);
438 plot->page(0).column(0).label("Angle");
439 plot->page(0).column(0).axis(1);
440 plot->page(0).column(1).type(2);
441 plot->page(0).column(1).label("CC");
442 plot->page(0).column(1).axis(3);
443 plot->page(0).axis(1).min(0);
444 plot->page(0).axis(1).max(360);
445 plot->page(0).axis(1).inc(30);
446
447 // cout << na << endl;
448
449 if ( verbose )
450 cout << endl << "Angle\tCC" << endl;
451 for ( ia=0, CC=0, cc_min=1, cc_max=0; ia<na; ia++ ) {
452 CC += s12[ia];
453 umin = ia - ulen;
454 umax = ia + ulen;
455 for ( u = umin, s1[ia] = 0; u < umax; u++ ) { //cout << u << tab << s1[ia] << endl;
456 i = (u < 0)? u + na: u;
457 if ( i >= na ) i -= na;
458 s1[ia] += s12[i];
459 }
460 s1[ia] /= 2*ulen;
461 if ( cc_min > s1[ia] ) cc_min = s1[ia];
462 if ( cc_max < s1[ia] ) cc_max = s1[ia];
463 // cout << ia << tab << s1[ia] << endl;
464 (*plot)[ia] = ia*360.0/na;
465 (*plot)[ia+na] = s1[ia];
466 if ( verbose )
467 cout << ia*360.0/na << tab << s1[ia] << endl;
468 }
469
470 CC /= na;
471 cc_cut = (cc_max + cc_min)/2;
472
473 for ( i=1; i<na/2; i++ ) {
474 ia = na - i;
475 a = i*TWOPI*1.0L/na;
476 if ( s1[i] > cc_cut && s1[i-1] < cc_cut ) angle_best = a;
477 if ( s1[i] < cc_cut && s1[i-1] > cc_cut ) angle_best = a;
478 a = ia*TWOPI*1.0L/na;
479 if ( s1[ia] > cc_cut && s1[ia-1] < cc_cut ) angle_best = a;
480 if ( s1[ia] < cc_cut && s1[ia-1] > cc_cut ) angle_best = a;
481 }
482
483 if ( verbose ) {
484 cout << endl;
485 cout << "Correlation coefficient: " << CC << endl;
486 cout << "Best seam location angle: " << angle_best*180.0/M_PI << " degrees" << endl;
487 cout << "Min & max correlation: " << cc_min << " " << cc_max << endl << endl;
488 }
489
490 Bstring txt;
491
492 txt = Bstring(helix_rise, "Helix rise: %g A");
493 plot->page(0).add_text(txt);
494 txt = Bstring(helix_angle*180.0/M_PI, "Helix rotation angle: %g degrees");
495 plot->page(0).add_text(txt);
496 txt = Bstring(seam_rise, "Seam rise: %g A");
497 plot->page(0).add_text(txt);
498 txt = Bstring(seam_angle*180.0/M_PI, "Seam rotation angle: %g degrees");
499 plot->page(0).add_text(txt);
500 txt = Bstring(angle_best*180.0/M_PI, "Seam location angle: %g degrees");
501 plot->page(0).add_text(txt);
502 txt = Bstring(CC, "Correlation coefficient: %g");
503 plot->page(0).add_text(txt);
504
505 delete[] num;
506 delete[] nsum;
507 delete[] s1;
508 delete[] s2;
509 delete[] s1sq;
510 delete[] s2sq;
511 delete[] s12;
512
513 return plot;
514 }
515
524 Bimage* Bimage::symmetrize_cylinder(int flag)
525 {
526 long i, j, k, xx, yy, zz, nn, cc, ir;
527 long rmax = (long) sqrt(x*x + y*y);
528 long cylsize(n*z*rmax*c);
529 double dx, dy, r, f;
530
531 if ( verbose & VERB_PROCESS )
532 cout << "Symmetrizing cylindrically around " << image->origin() << endl << endl;
533
534 Bimage* pcyl = NULL;
535
536 switch ( flag ) {
537 case 1: pcyl = new Bimage(Float, compoundtype, z, rmax, 1, n); break;
538 default: pcyl = new Bimage(Float, compoundtype, rmax, 1, z, n);
539 }
540
541 float* num = new float[cylsize];
542 for ( i=0; i<cylsize; i++ ) num[i] = 0;
543
544 for ( i=nn=0; nn<n; nn++ ) {
545 for ( zz=0; zz<z; zz++ ) {
546 for ( yy=0; yy<y; yy++ ) {
547 dy = yy - image[nn].origin()[0];
548 for ( xx=0; xx<x; xx++ ) {
549 dx = xx - image[nn].origin()[0];
550 r = sqrt(dx*dx + dy*dy);
551 ir = (long) r;
552 f = r - ir;
553 if ( flag < 1 ) {
554 j = ((nn*z + zz)*rmax + ir)*c;
555 k = j + c;
556 } else {
557 j = ((nn*rmax + ir)*z + zz)*c;
558 k = j + z*c;
559 }
560 for ( cc=0; cc<c; cc++, i++, j++, k++ ) {
561 pcyl->add(j, (1-f) * (*this)[i]);
562 pcyl->add(k, f * (*this)[i]);
563 num[j] += 1 - f;
564 num[k] += f;
565 }
566 }
567 }
568 }
569 }
570
571 for ( i=0; i<cylsize; i++ ) if ( num[i] ) pcyl->set(i, (*pcyl)[i]/num[i]);
572
573 delete[] num;
574
575 return pcyl;
576 }
577
585 int Bimage::symmetrize_cylinder()
586 {
587 Bimage* pcyl = symmetrize_cylinder(0);
588
589 long rmax(pcyl->x);
590 long i, j, k, xx, yy, zz, nn, cc, ir;
591 double dx, dy, r, f;
592
593 for ( i=nn=0; nn<n; nn++ ) {
594 for ( zz=0; zz<z; zz++ ) {
595 for ( yy=0; yy<y; yy++ ) {
596 dy = yy - image[nn].origin()[0];
597 for ( xx=0; xx<x; xx++ ) {
598 dx = xx - image[nn].origin()[0];
599 r = sqrt(dx*dx + dy*dy);
600 ir = (long) r;
601 f = r - ir;
602 j = ((nn*z + zz)*rmax + ir)*c;
603 k = j + c;
604 for ( cc=0; cc<c; cc++, i++, j++, k++ )
605 set(i, (1-f)*(*pcyl)[j] + f*(*pcyl)[k]);
606 }
607 }
608 }
609 }
610
611 delete pcyl;
612
613 statistics();
614
615 return 0;
616 }
617
633 double Bimage::tube_symmetrize(int h, int k, double latconst,
634 int zmin, int zmax, double radius, int norm_flag)
635 {
636 change_type(Float);
637
638 long i;
639 double v, vr, d, nsum(0), sum1(0), sum2(0), sum1sq(0), sum2sq(0), sum12(0), R(1e37), CC(0);
640
641 if ( zmin < 0 ) zmin = 0;
642 if ( zmax >= z ) zmax = z - 1;
643
644 if ( radius <= 0 ) radius = x/2;
645
646 float* symdata = new float[datasize];
647 for ( i=0; i<datasize; i++ ) symdata[i] = 0;
648
649 if ( verbose & VERB_LABEL ) {
650 cout << "Tubular symmetrization:" << endl;
651 cout << "Tubular axis origin: " << image->origin() << endl;
652 cout << "Lattice parameters: " << h << " x " << k << endl;
653 cout << "Lattice constant: " << latconst << " A" << endl;
654 cout << "Radius: " << radius << " pixels" << endl;
655 cout << "Limits along helical axis: " << zmin << " - " << zmax << " pixels" << endl;
656 }
657
658
659 #ifdef HAVE_GCD
660 dispatch_apply(datasize, dispatch_get_global_queue(0, 0), ^(size_t k){
661 symdata[k] = tube_interpolate(k, h, k, latconst, zmin, zmax, radius, norm_flag);
662 cout << k*100.0/datasize << " % \r" << flush;
663 });
664 #else
665 #pragma omp parallel for
666 for ( i=0; i<datasize; i++ )
667 symdata[i] = tube_interpolate(i, h, k, latconst, zmin, zmax, radius, norm_flag);
668 #endif
669
670 for ( i=0; i<datasize; i++ ) {
671 v = symdata[i];
672 if ( v ) {
673 vr = (*this)[i];
674 sum1 += vr;
675 sum2 += v;
676 sum1sq += vr * vr;
677 sum2sq += v * v;
678 sum12 += vr * v;
679 nsum += 1;
680 }
681 set(i, v);
682 }
683
684 if ( nsum ) {
685 d = (sum1sq - sum1*sum1/nsum)*(sum2sq - sum2*sum2/nsum);
686 if ( d > 0 ) {
687 d = sqrt(d);
688 R = sqrt((sum1sq - 2*sum12 + sum2sq)/d);
689 CC = (sum12 - sum1*sum2/nsum)/d;
690 }
691 }
692
693 if ( verbose ) {
694 cout << "Tubular symmetry R factor: " << R << endl;
695 cout << "Tubular symmetry correlation: " << CC << endl;
696 }
697
698 if ( verbose >= VERB_LABEL )
699 cout << endl;
700
701 statistics();
702
703 return R;
704 }
705
721 double Bimage::convert_to_helix(double helix_rise, double helix_angle,
722 Vector3<double> offset)
723 {
724 change_type(Float);
725
726 long i, xx, yy, zz, nn;
727 double angle, dx, dy;
728 double distance(offset.length());
729 double angle0(atan2(offset[1], offset[0]));
730 double angle2(atan2(distance*sqrt(1-cos(helix_angle)), helix_rise*1.0));
731 Vector3<double> ori, old, rold, axis;
732 Vector3<double> u;
733 Matrix3 mat;
734
735 float* nudata = new float[datasize];
736
737 for ( i=0; i<datasize; i++ ) nudata[i] = 0;
738
739 for ( i=nn=0; nn<n; nn++ ) {
740 ori = image[nn].origin();
741 u = image[nn].sampling();
742 for ( zz=0; zz<z; zz++ ) {
743 ori[2] = zz;
744 angle = helix_angle*(zz - image[nn].origin()[2])/u[2] + angle0;
745 dx = distance*cos(angle)/u[0];
746 dy = distance*sin(angle)/u[1];
747 axis[0] = dx;
748 axis[1] = dy;
749 axis.normalize();
750 mat = Matrix3(axis, angle2);
751 for ( yy=0; yy<y; yy++ ) {
752 old[1] = yy - dy - ori[1];
753 for ( xx=0; xx<x; xx++, i++ ) {
754 old[0] = xx - dx - ori[0];
755 rold = (mat * old) + ori;
756 nudata[i] = interpolate(0, rold, nn, 0.0);
757 }
758 }
759 }
760 }
761
762 data_assign((unsigned char *) nudata);
763
764 statistics();
765
766 return 0;
767 }
768
779 int Bimage::distort_elliptically(double angle, double shift)
780 {
781 change_type(Float);
782
783 if ( verbose ) {
784 cout << "Elliptical distortion: " << endl;
785 cout << "Major axis angle: " << angle*180.0/M_PI << " degrees" << endl;
786 cout << "Shift at major axis: " << shift << " pixels" << endl << endl;
787 }
788
789 long xx, yy, zz, nn, i, j, inz, ix, iy;
790 double dx, dy, a, r, s, rx, ry, fx, fy;
791 float* nudata = new float[datasize];
792
793 for ( i=0; i<datasize; i++ ) nudata[i] = 0;
794
795 for ( j=nn=0; nn<n; nn++ ) {
796 for ( zz=0; zz<z; zz++ ) {
797 inz = (nn*z + zz)*y*x;
798 for ( yy=0; yy<y; yy++ ) {
799 dy = yy - image[nn].origin()[0];
800 for ( xx=0; xx<x; xx++, j++ ) {
801 dx = xx - image[nn].origin()[0];
802 r = sqrt(dx*dx + dy*dy);
803 a = 2*(atan2(dy, dx) - angle);
804 s = shift*cos(a)/r;
805 // cout << x << tab << y << tab << z << tab << n << tab << s << endl;
806 if ( s < 1 ) {
807 rx = dx*(1 - s) + image[nn].origin()[0];
808 ry = dy*(1 - s) + image[nn].origin()[1];
809 ix = (long) rx;
810 iy = (long) ry;
811 if ( ix < x-1 && iy < y-1 ) {
812 fx = rx - ix;
813 fy = ry - iy;
814 i = inz + iy*x + ix;
815 nudata[j] = (1-fx)*(1-fy)*(*this)[i] + fx*(1-fy)*(*this)[i+1] +
816 (1-fx)*fy*(*this)[i+x] + fx*fy*(*this)[i+x+1];
817 }
818 }
819 }
820 }
821 }
822 }
823 // cout << "***" << endl;
824 data_assign((unsigned char *) nudata);
825
826 statistics();
827
828 return 0;
829 }
830
831
832
848 Bplot* Bimage::find_helix_parameters(double angle_start, double angle_end,
849 double angle_step, int bin, double hires, double lores, double radius)
850 {
851 angle_step = fabs(angle_step);
852 if ( angle_step < 0.0001 ) angle_step = 0.0001;
853 if ( angle_start > angle_end ) swap(angle_start, angle_end);
854
855 if ( bin < 1 ) bin = 1;
856 if ( bin > 4 ) bin = 4;
857
858 if ( lores > 0 && hires > lores ) swap(hires, lores);
859 if ( hires < 2*bin*image->sampling()[0] ) hires = 2*bin*image->sampling()[0];
860 if ( lores < hires ) lores = x*image->sampling()[0];
861
862 if ( radius < 1 ) radius = x/2;
863 if ( radius > image->origin()[0] ) radius = image->origin()[0];
864 if ( radius > x - image->origin()[0] ) radius = x - image->origin()[0];
865 if ( radius > image->origin()[1] ) radius = image->origin()[1];
866 if ( radius > y - image->origin()[1] ) radius = y - image->origin()[1];
867
868 long i, j, na, max_iter(10);
869 double rise, angle, offset, bestrise(0), bestangle(0);
870 double cc, dd, bestcc(0), mincc(1);
871
872 Bimage* pt;
873
874 if ( verbose ) {
875 cout << "Searching for helical parameters by cross-correlation:" << endl;
876 cout << "Angular range " << angle_start*180.0/M_PI << " - "
877 << angle_end*180.0/M_PI << " degrees" << endl;
878 cout << "Angular increment: " << angle_step*180.0/M_PI << " degrees" << endl;
879 cout << "Resolution limits: " << hires << " - " << lores << " A" << endl;
880 cout << "Radius: " << radius << endl;
881 cout << "Binning: " << bin << endl << endl;
882 }
883
884 radius /= bin;
885 angle_end += angle_step/2; // To ensure the final angle is sampled
886
887 for ( na=0, angle = angle_start; angle <= angle_end; angle += angle_step ) na++;
888
889 Bimage* pb = copy();
890 pb->integer_interpolation(bin, 42);
891 pb->calculate_background();
892
893 if ( verbose & VERB_DEBUG )
894 cout << "DEBUG Bimage::find_helix_parameters: binned size = " << pb->size() << endl;
895
896 Vector3<double> origin(pb->image->origin());
897 Vector3<double> bestorigin, scale(1,1,1), translate, axis(0,0,1);
898 Vector3<long> mask_size((long) (2*radius), (long) (2*radius), (pb->sizeZ()*3)/4);
899 Vector3<double> mask_start(pb->image->origin()[0] - radius, pb->image->origin()[1] - radius, pb->sizeZ()/8);
900 Matrix3 mat;
901 Vector3<double> shift;
902
903 Bstring title("Helical parameter search");
904 int ncol(3);
905 Bplot* plot = new Bplot(1, na, 3);
906 plot->title(title);
907 plot->page(0).title(title);
908 plot->page(0).columns(3);
909 for ( i=0; i<ncol; i++ ) plot->page(0).column(i).number(i);
910 plot->page(0).column(0).label("Rise (A)");
911 plot->page(0).column(0).axis(1);
912 plot->page(0).column(1).type(4);
913 plot->page(0).column(1).label("Rotation angle (degrees)");
914 plot->page(0).column(1).axis(3);
915 plot->page(0).column(2).type(4);
916 plot->page(0).column(2).label("CC");
917 plot->page(0).column(2).axis(5);
918 plot->page(0).axis(3).min(angle_start*180.0/M_PI);
919 plot->page(0).axis(3).max(angle_end*180.0/M_PI);
920
921 if ( verbose )
922 cout << "Rise\tAngle\tOffset\tCC" << endl;
923 for ( i=0, angle = angle_start; angle <= angle_end; angle += angle_step, i++ ) {
924 mat = Matrix3(axis, angle);
925 translate = 0;
926 shift[2] = 1;
927 dd = 1;
928 for ( j=0; j<max_iter && fabs(shift[2]) > 0.001; j++ ) {
929 pt = pb->transform(pb->size(), scale, origin, translate, mat, FILL_BACKGROUND, 0);
930 // write_img("t.pif", pt);
931 pt->edge(2, mask_size, mask_start, 2, FILL_BACKGROUND, 0);
932 shift = pb->find_shift(pt, NULL, hires, lores, pb->sizeZ()/4.0, 0, 1, cc);
933 delete pt;
934 if ( fabs(shift[2]) > 0.001 ) {
935 translate[2] += dd*shift[2];
936 // cout << angle*180.0/M_PI << tab << shift << tab << translate[2] << tab << cc << endl;
937 }
938 dd *= 0.9;
939 }
940 rise = pb->sampling()[2]*translate[2];
941 offset = pb->sampling()[2]*sqrt(translate[0]*translate[0] + translate[1]*translate[1]);
942 (*plot)[i] = rise;
943 (*plot)[i+na] = angle*180.0/M_PI;
944 (*plot)[i+2*na] = cc;
945 if ( bestcc < cc ) {
946 bestcc = cc;
947 bestangle = angle;
948 bestrise = rise;
949 }
950 if ( mincc > cc ) mincc = cc;
951 if ( verbose )
952 cout << setprecision(6) << rise << tab << angle*180.0/M_PI
953 << tab << offset << tab << cc << endl << flush;
954 }
955
956 delete pb;
957
958 if ( bestrise < 0 ) {
959 bestrise = -bestrise;
960 bestangle = -bestangle;
961 }
962
963 if ( verbose ) {
964 cout << "Best helical rise: " << bestrise << " A" << endl;
965 cout << "Best helical rotation angle: " << bestangle*180.0/M_PI << " degrees" << endl;
966 cout << "Best correlation coefficient: " << bestcc << endl << endl;
967 }
968
969 Bstring txt;
970
971 txt = Bstring(bestrise, "Best helical rise: %g A");
972 plot->page(0).add_text(txt);
973 txt = Bstring(bestangle*180.0/M_PI, "Best helical rotation angle: %g degrees");
974 plot->page(0).add_text(txt);
975 txt = Bstring(bestcc, "Best correlation coefficient: %g");
976 plot->page(0).add_text(txt);
977 txt = Bstring(mincc, "Minimum correlation coefficient: %g");
978 plot->page(0).add_text(txt);
979
980 return plot;
981 }
982
998 Bplot* Bimage::find_helix_parameters(double rise_start, double rise_end,
999 double rise_step, double angle_start, double angle_end, double angle_step,
1000 int bin, double radius)
1001 {
1002 rise_step = fabs(rise_step);
1003 if ( rise_step < 0.001 ) rise_step = 0.001;
1004 if ( rise_start > rise_end ) swap(rise_start, rise_end);
1005
1006 angle_step = fabs(angle_step);
1007 if ( angle_step < 0.0001 ) angle_step = 0.0001;
1008 if ( angle_start > angle_end ) swap(angle_start, angle_end);
1009
1010 if ( bin < 1 ) bin = 1;
1011 if ( bin > 4 ) bin = 4;
1012
1013 if ( radius < 1 ) radius = x/2;
1014 if ( radius > image->origin()[0] ) radius = image->origin()[0];
1015 if ( radius > x - image->origin()[0] ) radius = x - image->origin()[0];
1016 if ( radius > image->origin()[1] ) radius = image->origin()[1];
1017 if ( radius > y - image->origin()[1] ) radius = y - image->origin()[1];
1018
1019 long i, na;
1020 double rise, angle, bestrise(0), bestangle(0);
1021 double cc, bestcc(0), mincc(1);
1022
1023 Bimage* pt;
1024
1025 if ( verbose ) {
1026 cout << "Searching for helical parameters:" << endl;
1027 cout << "Rise range " << rise_start << " - "
1028 << rise_end << " A" << endl;
1029 cout << "Rise increment: " << rise_step << " A" << endl;
1030 cout << "Angular range " << angle_start*180.0/M_PI << " - "
1031 << angle_end*180.0/M_PI << " degrees" << endl;
1032 cout << "Angular increment: " << angle_step*180.0/M_PI << " degrees" << endl;
1033 cout << "Binning: " << bin << endl;
1034 // cout << "Resolution limits: " << hires << " - " << lores << " A" << endl;
1035 cout << "Radius: " << radius << endl << endl;
1036 }
1037
1038 radius /= bin;
1039 rise_end += rise_step/2;
1040 angle_end += angle_step/2; // To ensure the final angle is sampled
1041
1042 for ( na=0, rise = rise_start; rise < rise_end; rise += rise_step )
1043 for ( angle = angle_start; angle <= angle_end; angle += angle_step ) na++;
1044
1045 Bimage* pb = copy();
1046 pb->integer_interpolation(bin, 42);
1047 pb->calculate_background();
1048
1049 if ( verbose & VERB_DEBUG )
1050 cout << "DEBUG Bimage::find_helix_parameters: binned size = " << pb->size() << endl;
1051
1052 Vector3<double> origin(pb->image->origin());
1053 Vector3<double> bestorigin, scale(1,1,1), translate, axis(0,0,1);
1054 Vector3<long> mask_size((int) (2*radius), (int) (2*radius), (pb->sizeZ()*3)/4);
1055 Vector3<double> mask_start(pb->image->origin()[0] - radius, pb->image->origin()[1] - radius, pb->sizeZ()/8);
1056 Matrix3 mat;
1057
1058 Bstring title("Helical parameter search");
1059 int ncol(3);
1060 Bplot* plot = new Bplot(1, na, 3);
1061 plot->title(title);
1062 plot->page(0).title(title);
1063 plot->page(0).columns(3);
1064 for ( i=0; i<ncol; i++ ) plot->page(0).column(i).number(i);
1065 plot->page(0).column(0).label("Rise (A)");
1066 plot->page(0).column(0).axis(1);
1067 plot->page(0).column(1).type(4);
1068 plot->page(0).column(1).label("Rotation angle (degrees)");
1069 plot->page(0).column(1).axis(3);
1070 plot->page(0).column(2).type(4);
1071 plot->page(0).column(2).label("CC");
1072 plot->page(0).column(2).axis(5);
1073 plot->page(0).axis(3).min(angle_start*180.0/M_PI);
1074 plot->page(0).axis(3).max(angle_end*180.0/M_PI);
1075
1076 if ( verbose )
1077 cout << "Rise\tAngle\tCC" << endl;
1078 for ( i=0, rise = rise_start; rise < rise_end; rise += rise_step ) {
1079 for ( angle = angle_start; angle <= angle_end; angle += angle_step, i++ ) {
1080 mat = Matrix3(axis, angle);
1081 translate[2] = rise/pb->sampling()[2];
1082 // pt = img_transform_copy(pb, size, scale, origin, translate, mat, FILL_BACKGROUND, 0);
1083 pt = pb->transform(pb->size(), scale, origin, translate, mat, FILL_BACKGROUND, 0);
1084 // write_img("t.pif", pt);
1085 // bexit(0);
1086 // img_edge_cylinder(pt, mask_size, mask_start, 2, 0, FILL_BACKGROUND);
1087 pt->edge(2, mask_size, mask_start, 2, FILL_USER, 0);
1088 cc = pb->correlate(pt);
1089 delete pt;
1090 (*plot)[i] = rise;
1091 (*plot)[i+na] = angle*180.0/M_PI;
1092 (*plot)[i+2*na] = cc;
1093 if ( bestcc < cc ) {
1094 bestcc = cc;
1095 bestangle = angle;
1096 bestrise = rise;
1097 }
1098 if ( mincc > cc ) mincc = cc;
1099 if ( verbose )
1100 cout << setprecision(6) << rise << tab << angle*180.0/M_PI
1101 << tab << cc << endl << flush;
1102 }
1103 }
1104
1105 delete pb;
1106
1107 if ( bestrise < 0 ) {
1108 bestrise = -bestrise;
1109 bestangle = -bestangle;
1110 }
1111
1112 if ( verbose ) {
1113 cout << "Best helical rise: " << bestrise << " A" << endl;
1114 cout << "Best helical rotation angle: " << bestangle*180.0/M_PI << " degrees" << endl;
1115 cout << "Best correlation coefficient: " << bestcc << endl << endl;
1116 }
1117
1118 Bstring txt;
1119
1120 txt = Bstring(bestrise, "Best helical rise: %g A");
1121 plot->page(0).add_text(txt);
1122 txt = Bstring(bestangle*180.0/M_PI, "Best helical rotation angle: %g degrees");
1123 plot->page(0).add_text(txt);
1124 txt = Bstring(bestcc, "Best correlation coefficient: %g");
1125 plot->page(0).add_text(txt);
1126 txt = Bstring(mincc, "Minimum correlation coefficient: %g");
1127 plot->page(0).add_text(txt);
1128
1129 return plot;
1130 }
1131
1132
1133 int Bimage::helix_segment_correlation_one(long i,
1134 double angle_start, double angle_end, double angle_step,
1135 int bin, double hires, double lores, double radius,
1136 fft_plan planf, fft_plan planb, double* cc)
1137 {
1138 long k;
1139 long m = (long) ((angle_end - angle_start)/angle_step) + 1;
1140
1141 double angle;
1142 Vector3<double> axis(0,0,1);
1143 Bimage* p1, *p2;
1144
1145 for ( k = i*m, angle = angle_start; angle <= angle_end; angle += angle_step, k++ ) {
1146 p1 = extract(i);
1147 p2 = extract(i+1);
1148 p1->rotate(axis, angle);
1149 p1->find_shift(p2, NULL, hires, lores, p1->sizeX()/4, 0, 1, planf, planb, cc[k]);
1150 delete p2;
1151 delete p1;
1152 }
1153
1154 return 0;
1155 }
1156
1175 Bplot* Bimage::helix_segment_correlation(int thickness,
1176 double angle_start, double angle_end, double angle_step,
1177 int bin, double hires, double lores, double radius)
1178 {
1179 if ( hires > lores ) swap(hires, lores);
1180
1181 if ( radius <= 0 || radius > x/2 ) radius = x/2;
1182
1183 Vector3<long> start, tile_size(x, y, thickness), step_size;
1184 Vector3<long> mask_size((long) (2*radius), (long) (2*radius), z);
1185 Vector3<double> mask_start(image->origin()[0] - radius, image->origin()[1] - radius, 0);
1186
1187 calculate_background();
1188 edge(2, mask_size, mask_start, 2, FILL_BACKGROUND, 0);
1189
1190 // cout << mask_start << tab << mask_size << endl;
1191 // cout << start << tab << p->size() << endl;
1192 // cout << tile_size << endl;
1193
1194 Bimage* ptiles = extract_tiles(0, start, size(), tile_size, step_size, 0);
1195
1196 // write_img("ptiles.pif", ptiles);
1197
1198 if ( bin > 1 ) {
1199 ptiles->integer_interpolation(bin, 42);
1200 ptiles->calculate_background();
1201 }
1202
1203 long i, k;
1204 long nt(ptiles->images());
1205 long m = (long) ((angle_end - angle_start)/angle_step) + 1;
1206 double angle;
1207
1208 // for ( i=0; i<nt; i++ ) ptiles->image[i].origin(ptiles->size()/2);
1209 ptiles->origin(ptiles->size()/2);
1210
1211 if ( verbose ) {
1212 cout << "Calculating cross-correlations between helical segments:" << endl;
1213 cout << "Thickness: " << tile_size[2] << endl;
1214 cout << "Angular range " << angle_start*180.0/M_PI << " - "
1215 << angle_end*180.0/M_PI << " degrees" << endl;
1216 cout << "Angular increment: " << angle_step*180.0/M_PI << " degrees" << endl;
1217 cout << "Resolution limits: " << hires << " - " << lores << " A" << endl;
1218 cout << "Radius: " << radius << endl;
1219 cout << "Binning: " << bin << endl << endl;
1220 }
1221
1222 double* cc = new double[m*nt];
1223 for ( i=0; i<m*nt; i++ ) cc[i] = 0;
1224
1225 fft_plan planf = ptiles->fft_setup(FFTW_FORWARD, 1);
1226 fft_plan planb = ptiles->fft_setup(FFTW_BACKWARD, 1);
1227
1228 #ifdef HAVE_GCD
1229 dispatch_apply(nt-1, dispatch_get_global_queue(0, 0), ^(size_t i){
1230 ptiles->helix_segment_correlation_one(i,
1231 angle_start, angle_end, angle_step,
1232 bin, hires, lores, radius,
1233 planf, planb, cc);
1234 });
1235 #else
1236 #pragma omp parallel for
1237 for ( long i=0; i<nt; ++i )
1238 ptiles->helix_segment_correlation_one(i,
1239 angle_start, angle_end, angle_step,
1240 bin, hires, lores, radius,
1241 planf, planb, cc);
1242 #endif
1243
1244 Bstring title("Helix segment correlation");
1245 int ncol(nt);
1246 RGB<float> color;
1247 Bplot* plot = new Bplot(1, m, ncol);
1248 plot->title(title);
1249 plot->page(0).title(title);
1250 plot->page(0).columns(ncol);
1251 for ( i=0; i<ncol; i++ ) plot->page(0).column(i).number(i);
1252 plot->page(0).column(0).label("Angle");
1253 plot->page(0).column(0).axis(1);
1254 for ( i=1; i<ncol; i++ ) {
1255 plot->page(0).column(i).type(2);
1256 plot->page(0).column(i).label("CC");
1257 plot->page(0).column(i).axis(3);
1258 color.spectrum(i,1,ncol-1);
1259 plot->page(0).column(i).color(color.r(),color.g(),color.b());
1260 }
1261 plot->page(0).axis(1).label("Angle");
1262 plot->page(0).axis(1).min(angle_start*180.0/M_PI);
1263 plot->page(0).axis(1).max(angle_end*180.0/M_PI);
1264 plot->page(0).axis(3).label("CC");
1265 plot->page(0).axis(3).min(0);
1266 plot->page(0).axis(3).max(1);
1267
1268 if ( verbose ) {
1269 cout << endl << "Angle";
1270 for ( i=0; i<nt-1; i++ ) cout << "\tCC(" << i+1 << ")";
1271 cout << endl;
1272 for ( k=0, angle = angle_start; angle <= angle_end; angle += angle_step, k++ ) {
1273 cout << setprecision(4) << angle*180.0/M_PI;
1274 for ( i=0; i<nt-1; i++ ) cout << tab << cc[i*m + k];
1275 cout << endl;
1276 }
1277 }
1278
1279 for ( k=0, angle = angle_start; angle <= angle_end; angle += angle_step, k++ ) {
1280 (*plot)[k] = angle*180.0/M_PI;
1281 for ( i=0; i<nt-1; i++ ) (*plot)[(i+1)*m+k] = cc[i*m + k];
1282 }
1283
1284 fft_destroy_plan(planf);
1285 fft_destroy_plan(planb);
1286
1287 delete[] cc;
1288 delete ptiles;
1289
1290 return plot;
1291 }
1292
1293 /*
1294 @brief Transforms rows in a 2D image and shift the phases to the origin.
1295 @return int 0, <0 on error.
1296
1297 Each row of pixels is transformed and phase shifted.
1298 Only 2D images are transformed.
1299 **/
1300 int Bimage::transform_lines()
1301 {
1302 if ( z > 1 ) {
1303 cerr << "Error: Line transforms can only be calculated from 2D images!" << endl;
1304 return -1;
1305 }
1306
1307 simple_to_complex();
1308 change_type(Float);
1309
1310 fft_plan plan = fft_setup_plan(x, 1, 1, FFTW_FORWARD, 1);
1311
1312 if ( verbose & VERB_FULL )
1313 cout << "Transforming lines of size: " << x << endl;
1314
1315 long i, xx, yy, nn, hx(x/2);
1316 double dx, shift, phi, sx(x);
1317 Complex<float>* data = (Complex<float> *) data_pointer();
1318
1319 for ( i=nn=0; nn<n; nn++ ) {
1320 shift = -image[nn].origin()[0]/x;
1321 if ( verbose & VERB_FULL )
1322 cout << "Shift: " << shift << endl;
1323 for ( yy=0; yy<y; yy++ ) {
1324 data = (Complex<float> *) (data_pointer(c*i));
1325 fftw(plan, data);
1326 for ( xx=0; xx<x; xx++, i++ ) {
1327 dx = (xx < hx)? xx: xx - sx;
1328 phi = MIN2PI*dx*shift;
1329 data[xx].shift_phi(phi);
1330 }
1331 }
1332 }
1333
1334 fft_destroy_plan(plan);
1335
1336 if ( verbose & VERB_FULL )
1337 cout << "Finished transforming" << endl << endl;
1338
1339 return 0;
1340 }
1341
1356 Bimage* Bimage::helical_cross_section(double helix_rise, double helix_angle,
1357 double scale, double hires)
1358 {
1359 if ( z > 1 ) {
1360 cerr << "Error: Cross sections can only be calculated from 2D images!" << endl;
1361 return NULL;
1362 }
1363
1364 if ( x > y ) {
1365 if ( verbose & VERB_PROCESS )
1366 cout << "Rotating image" << endl;
1367 Bstring order("-yxz");
1368 reslice(order);
1369 order = 0;
1370 }
1371
1372 if ( hires < image->sampling()[0] ) hires = image->sampling()[0];
1373
1374 Vector3<long> recsize((int) (x*scale), (int) (x*scale), 1);
1375
1376 long i, j, xx, yy, nn;
1377 long ix, iy, pad_factor(2);
1378 double a, cosang, sinang, dx;
1379 int ft_size = part_ft_size(recsize[0], 1, pad_factor);
1380 double pix_rise = helix_rise/image->sampling()[1];
1381 double apz = helix_angle/pix_rise;
1382
1383 Vector3<long> pad_size(ft_size, y, z);
1384 Bimage* pp = pad_copy(pad_size, FILL_BACKGROUND);
1385
1386 if ( verbose & VERB_PROCESS ) {
1387 cout << "2D reconstruction:" << endl;
1388 cout << "Size: " << recsize << endl;
1389 cout << "Helical rise and angle: " << helix_rise << " " << helix_angle*180/M_PI << endl;
1390 cout << "Rotation per pixel along axis: " << apz*180/M_PI << endl;
1391 cout << "Resolution limit: " << hires << " Å" << endl;
1392 cout << "Fourier transform size: " << ft_size << endl;
1393 }
1394
1395 pp->transform_lines();
1396
1397 Bimage* pcs = new Bimage(Float, TComplex, recsize, n);
1398 pcs->sampling(sampling()/scale);
1399 float* w = new float[n*pcs->image_size()];
1400 // cout << "*** Channels = " << pcs->channels() << endl;
1401 // cout << "*** Compound type = " << pcs->compound_type() << endl;
1402
1403 double sx = pp->x;
1404 double hx = sx/2;
1405 double rscale = pcs->x/(scale*sx);
1406 double mx = sx * pp->image->sampling()[0] / hires;
1407 if ( mx > sx ) mx = sx;
1408
1409 // if ( verbose & VERB_DEBUG )
1410 cout << "DEBUG Bimage::helical_cross_section: sampling=" << image->sampling()[0] << " mx=" << mx << endl;
1411
1412 for ( i=nn=0; nn<pp->n; nn++ ) {
1413 for ( yy=0; yy<pp->y; yy++ ) {
1414 // Set view
1415 a = -(yy - pp->image[nn].origin()[1])*apz;
1416 cosang = cos(a);
1417 sinang = sin(a);
1418 // Calculate from helical parameters and write line into reconstruction
1419 for ( xx=0; xx<pp->x; xx++, i++ ) {
1420 dx = ( xx < hx )? xx: xx - sx;
1421 if ( fabs(dx) <= mx ) {
1422 dx *= rscale;
1423 ix = (long) floor(dx*cosang + 0.5);
1424 iy = (long) floor(dx*sinang + 0.5);
1425 if ( ix < 0 ) ix += pcs->x;
1426 if ( iy < 0 ) iy += pcs->y;
1427 if ( ix >= 0 && iy >= 0 && ix < pcs->x && iy < pcs->y ) {
1428 j = (nn*pcs->y + iy)*pcs->x + ix;
1429 pcs->add(j, pp->complex(i));
1430 w[j] += 1;
1431 }
1432 }
1433 }
1434 }
1435 }
1436
1437 delete pp;
1438
1439 // Weigh reconstructions
1440 if ( verbose & VERB_PROCESS )
1441 cout << "Weighing reconstruction" << endl;
1442 for ( i=0; i<pcs->size().volume() * pcs->n; i++ )
1443 if ( w[i] > 0 ) pcs->set(i, pcs->complex(i) / w[i]);
1444
1445 delete[] w;
1446
1447 pcs->phase_shift_to_center();
1448
1449 if ( verbose & VERB_PROCESS )
1450 cout << "Backtransforming reconstruction" << endl << endl;
1451 pcs->fft_back();
1452
1453 pcs->statistics();
1454
1455 return pcs;
1456 }
1457
1467 double Bimage::snvariance(double snradius)
1468 {
1469 if ( snradius < 1 || snradius > x/2 ) snradius = x/4;
1470
1471 long nn, i, xx, yy, fn, bn;
1472 double x2, y2, r2(snradius*snradius), v, fa, fv, ba, bv, snr(0);
1473
1474 if ( verbose )
1475 cout << "Image\tSNR" << endl;
1476 for ( i=nn=0; nn<n; nn++ ) {
1477 fn = bn = 0;
1478 fa = fv = ba = bv = 0;
1479 for ( yy=0; yy<y; yy++ ) {
1480 y2 = yy - image[nn].origin()[1];
1481 y2 *= y2;
1482 for ( xx=0; xx<x; xx++, i++ ) {
1483 x2 = xx - image[nn].origin()[0];
1484 x2 *= x2;
1485 v = (*this)[i];
1486 if ( x2 + y2 <= r2 ) {
1487 fa += v;
1488 fv += v*v;
1489 fn++;
1490 } else {
1491 ba += v;
1492 bv += v*v;
1493 bn++;
1494 }
1495 }
1496 }
1497 fa /= fn;
1498 ba /= bn;
1499 fv = fv/fn - fa*fa;
1500 bv = bv/bn - ba*ba;
1501 if ( fv < 0 ) fv = 0;
1502 if ( bv < 0 ) bv = 0;
1503 if ( bv ) {
1504 snr = fv/bv - 1;
1505 } else {
1506 snr = 0;
1507 cerr << "Error: The background variance is zero or less! (" << bv << ")" << endl;
1508 }
1509 if ( verbose )
1510 cout << nn+1 << tab << snr << endl;
1511 }
1512
1513 if ( verbose )
1514 cout << endl;
1515
1516 return snr;
1517 }
1518
1531 int Bimage::extrude_cross_section(long length, double helix_rise,
1532 double helix_angle, int fill_type, double fill)
1533 {
1534 change_type(Float);
1535
1536 if ( fill_type == FILL_AVERAGE ) fill = avg;
1537
1538 long i, xx, yy, zz;
1539 double a, ca, sa, dx, dy, cx, cy;
1540
1541 if ( verbose ) {
1542 cout << "Extruding the image:" << endl;
1543 cout << "Helical rise and rotation: " << helix_rise << " A " << helix_angle*180.0/M_PI << "°" << endl;
1544 cout << "Length: " << length << endl;
1545 }
1546
1547 long nusize = (long) (size().volume() * length);
1548 float* nudata = new float[nusize];
1549 for ( i=0; i<nusize; i++ ) nudata[i] = 0;
1550
1551 for ( i=zz=0; zz<length; zz++ ) {
1552 a = zz*helix_angle*image->sampling()[0]/helix_rise;
1553 // cout << "z = " << z << " angle = " << a*180.0/M_PI << endl;
1554 ca = cos(a);
1555 sa = sin(a);
1556 for ( yy=0; yy<y; yy++ ) {
1557 dy = yy - image->origin()[1];
1558 for ( xx=0; xx<x; xx++, i++ ) {
1559 dx = xx - image->origin()[0];
1560 cx = dx*ca - dy*sa + image->origin()[0];
1561 cy = dx*sa + dy*ca + image->origin()[1];
1562 nudata[i] = interpolate(cx, cy, 0, 0, fill);
1563 }
1564 }
1565 }
1566
1567 sizeZ(length);
1568 data_assign((unsigned char *)nudata);
1569
1570 return 0;
1571 }
1572
1583 Bplot* Bimage::filament_width(long width, long lim_lo, long lim_hi)
1584 {
1585 if ( lim_lo > lim_hi ) swap(lim_lo, lim_hi);
1586 if ( lim_lo < 1 ) lim_lo = 1;
1587 if ( lim_hi < 1 || lim_hi > x ) lim_hi = x;
1588
1589 long i, xx, yy, zz, nn, left, right;
1590 long n1, n2, hw(width/2);
1591 double ox(image->origin()[0]), a, b, slope_max, slope_min;
1592 if ( ox < hw || ox > x - hw ) ox = x/2;
1593
1594 Vector3<double> u(image->sampling());
1595
1596 double* vx = new double[x];
1597 double* vy = new double[x];
1598
1599 long leftmin = (long) (ox - lim_hi/2);
1600 long leftmax = (long) (ox - lim_lo/2);
1601 long rightmin = (long) (ox + lim_lo/2);
1602 long rightmax = (long) (ox + lim_hi/2);
1603 if ( leftmin < 0 ) leftmin = 0;
1604 if ( leftmax <= leftmin ) leftmax = leftmin + 1;
1605 if ( rightmax >= x ) rightmax = x - 1;
1606 if ( rightmin >= rightmax ) rightmin = rightmax - 1;
1607
1608 for ( xx=0; xx<x; xx++ ) vx[xx] = xx;
1609
1610 if ( verbose ) {
1611 cout << "Calculating filament width:" << endl;
1612 cout << "Origin: " << ox << endl;
1613 cout << "Moving line window width: " << width << endl;
1614 cout << "Allowed filament width range: " << lim_lo << " - " << lim_hi << endl;
1615 cout << " " <<
1616 lim_lo*u[1] << " - " << lim_hi*u[1] << " A" << endl << endl;
1617 }
1618
1619 Bstring title("Filament width");
1620 int ncol(2);
1621 Bplot* plot = new Bplot(1, y, ncol);
1622 plot->title(title);
1623 plot->page(0).title(title);
1624 plot->page(0).columns(ncol);
1625 for ( i=0; i<ncol; i++ ) plot->page(0).column(i).number(i);
1626 plot->page(0).column(0).label("Distance (A)");
1627 plot->page(0).column(0).axis(1);
1628 plot->page(0).column(1).type(2);
1629 plot->page(0).column(1).label("Width (A)");
1630 plot->page(0).column(1).axis(3);
1631 // plot->page(0).axis(1).min(0);
1632 // plot->page(0).axis(1).max(360);
1633 // plot->page(0).axis(1).inc(30);
1634
1635 if ( verbose )
1636 cout << "y\ty(A)\tleft\tright\twidth\twidth(A)" << endl;
1637 for ( i=nn=0; nn<n; nn++ ) {
1638 for ( zz=0; zz<z; zz++ ) {
1639 for ( yy=0; yy<y; yy++ ) {
1640 left = right = 0;
1641 for ( xx=0; xx<x; xx++, i++ ) vy[xx] = (*this)[i];
1642 slope_max = slope_min = 0;
1643 for ( xx=0; xx<x; xx++ ) {
1644 n1 = (long)xx - hw;
1645 if ( n1 < 0 ) n1 = 0;
1646 n2 = xx + hw;
1647 if ( n2 >= x ) n2 = x - 1;
1648 linear_least_squares(n1, n2, vx, vy, a, b);
1649 // cout << " " << b;
1650 if ( xx >= leftmin && xx <= leftmax && slope_max < b ) {
1651 slope_max = b;
1652 left = xx;
1653 }
1654 if ( xx >= rightmin && xx <= rightmax && slope_min > b ) {
1655 slope_min = b;
1656 right = xx;
1657 }
1658 }
1659 (*plot)[yy] = yy*u[1];
1660 (*plot)[yy+y] = (right - left)*u[0];
1661 // cout << endl;
1662 if ( verbose )
1663 cout << yy << tab << yy*u[1] << tab << left << tab
1664 << right << tab << right - left << tab
1665 << (right - left)*u[0] << endl;
1666 }
1667 }
1668 }
1669
1670 delete[] vx;
1671 delete[] vy;
1672
1673 return plot;
1674 }
1675
1688 Bimage* Bimage::filament_density(double width)
1689 {
1690 if ( y < x ) {
1691 Bstring order("y-xz");
1692 reslice(order);
1693 order = 0;
1694 }
1695
1696 if ( width < 1 || width >= x ) width = x/2;
1697
1698 if ( verbose & VERB_FULL ) {
1699 cout << "Calculating filament density per pixel length:" << endl;
1700 cout << "Filament width: " << width <<
1701 " (" << width*image->sampling()[0] << " A)" << endl;
1702 cout << "Image width: " << x << endl << endl;
1703 }
1704
1705 long i, xx, yy, zz, nn;
1706 double t, tl, tr, hw((x-width)/2), hwm(x-hw);
1707
1708 Bimage* pd = new Bimage(Float, TSimple, y, 1, 1, n);
1709 pd->sampling(sampling());
1710
1711 for ( nn=0; nn<n; nn++ ) {
1712 for ( zz=0; zz<z; zz++ ) {
1713 for ( yy=0; yy<y; yy++ ) {
1714 t = tl = tr = 0;
1715 i = index(0, 0, yy, zz, nn);
1716 for ( xx=0; xx<hw; xx++, i++ )
1717 tl += (*this)[i];
1718 for ( ; xx<hwm; xx++, i++ )
1719 t += (*this)[i];
1720 for ( ; xx<x; xx++, i++ )
1721 tr += (*this)[i];
1722 tl /= hw;
1723 tr /= hw;
1724 t /= width;
1725 if ( tl < tr ) t -= tl;
1726 else t -= tr;
1727 i = nn*pd->x + yy;
1728 pd->set(i, t);
1729 // cout << i << tab << t << endl;
1730 }
1731 }
1732 }
1733
1734 pd->statistics();
1735
1736 return pd;
1737 }
1738
1739
1740
1741
1742
Baxis::inc
double inc()
Definition: Bplot.h:34
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Bimage::helical_cross_section
Bimage * helical_cross_section(double helix_rise, double helix_angle, double scale, double hires)
Calculates a helical cross section from line transforms of a filament.
Definition: Bimage_helix.cpp:1356
Bimage::extract_tiles
Bimage * extract_tiles(long nn, vector< Vector3< long >> &coords, Vector3< long > tile_size)
Extracts a set of tiles at specified positions from an image into a new image.
Definition: Bimage_extract.cpp:335
distance
double distance(vector< T1 > &v1, vector< T2 > &v2)
Definition: Vector3.h:536
Baxis::label
Bstring & label()
Definition: Bplot.h:28
FILL_BACKGROUND
#define FILL_BACKGROUND
Definition: utilities.h:174
Vector3::normalize
double normalize()
Definition: Vector3.h:236
Bimage.h
Header file for image class.
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Vector3::length
double length()
Definition: Vector3.h:222
Baxis::min
double min()
Definition: Bplot.h:30
planb
fft_plan planb
Definition: bico.cpp:24
Bimage::add
void add(long j, double v)
Definition: Bimage.h:308
Bimage::helix_segment_correlation_one
int helix_segment_correlation_one(long i, double angle_start, double angle_end, double angle_step, int bin, double hires, double lores, double radius, fft_plan planf, fft_plan planb, double *cc)
Definition: Bimage_helix.cpp:1133
Bplot::title
Bstring & title()
Definition: Bplot.h:189
Bimage::image_size
long image_size()
Definition: Bimage.h:267
RGB::g
Type g()
Definition: Color.h:46
symmetry.h
Header file for general symmetry functions.
Bimage::sizeZ
long sizeZ() const
Definition: Bimage.h:382
Bimage::fft_back
int fft_back()
Definition: Bimage.h:823
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bcolumn::label
Bstring & label()
Definition: Bplot.h:63
angle_set_negPI_to_PI
double angle_set_negPI_to_PI(double angle)
Returns an angle between -PI and PI.
Definition: utilities.cpp:594
planf
fft_plan planf
Definition: bico.cpp:24
verbose
int verbose
Bimage::edge
int edge(int type, Vector3< long > rect, Vector3< double > start, double width, int fill_type=0, double fill=0)
Smooths the image edge with a soft rectangular function.
Definition: Bimage_edit.cpp:319
Bimage::within_boundaries
bool within_boundaries(Vector3< double > loc)
Definition: Bimage.h:448
Bimage::index
long index(long nx, long ny) const
Definition: Bimage.h:383
Bimage::seamed_helix_symmetrize
Bplot * seamed_helix_symmetrize(double helix_rise, double helix_angle, double seam_shift, int dyad_axis, int zmin, int zmax, double radius, int norm_flag)
Symmetrizes an image given helical symmetry parameters and seam shift parameter.
Definition: Bimage_helix.cpp:280
Matrix3
Definition: Matrix3.h:17
FILL_AVERAGE
#define FILL_AVERAGE
Definition: utilities.h:173
Bimage::complex
Complex< double > complex(long j)
Returns a complex value at the given index.
Definition: Bimage.cpp:1005
symmetry_helical_label
string symmetry_helical_label(double helix_rise, double helix_angle, int dyad_axis, int cyclic, double seam_shift)
Returns the label for helical symmetry.
Definition: symmetry.cpp:280
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
Bcolumn::color
double * color()
Definition: Bplot.h:76
Bimage::find_helix_parameters
Bplot * find_helix_parameters(double angle_start, double angle_end, double angle_step, int bin, double hires, double lores, double radius)
Finds the best helix parameters for helical map.
Definition: Bimage_helix.cpp:848
Bimage::symmetrize_cylinder
int symmetrize_cylinder()
Calculates a cylindrically symmetrized map.
Definition: Bimage_helix.cpp:585
TComplex
Definition: Bimage.h:59
Bpage::column
Bcolumn & column(long i)
Definition: Bplot.h:110
Bimage::Bimage
Bimage()
Initializes an image.
Definition: Bimage.cpp:44
Bimage::correlate
double correlate(Bimage *p)
Calculates correlation coefficient between two images.
Definition: Bimage_correlate.cpp:36
Bimage::interpolate
double interpolate(long cc, double xx, double yy=0, double zz=0, long nn=0, double fill=0) const
Interpolates using a given location.
Definition: Bimage.cpp:1392
Complex::shift_phi
void shift_phi(const double d)
Definition: Complex.h:112
TSimple
Definition: Bimage.h:58
Baxis::max
double max()
Definition: Bplot.h:32
Bimage::snvariance
double snvariance(double snradius)
Calculates the ratio of variance inside and outside a given radius.
Definition: Bimage_helix.cpp:1467
Float
Definition: utilities.h:157
part_ft_size
int part_ft_size(int xsize, double scale, int pad_factor)
Sets the Fourier transform size for 2D particle images for reconstruction.
Definition: mg_reconstruct.cpp:37
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::tube_symmetrize
double tube_symmetrize(int h, int k, double latconst, int zmin, int zmax, double radius, int norm_flag=1)
Symmetrizes an image given tubular lattice parameters.
Definition: Bimage_helix.cpp:633
Bimage::transform
int transform(Vector3< double > scale, Vector3< double > origin, Vector3< double > translate, Matrix3 mat, int fill_type=0, double fill=0)
Transforms an image by translation, rotation, scaling and skewing, in place.
Definition: Bimage_transform.cpp:37
M_PI
#define M_PI
Definition: utilities.h:59
Bimage::filament_width
Bplot * filament_width(long width, long lim_lo, long lim_hi)
Estimates the width of a filament.
Definition: Bimage_helix.cpp:1583
Bimage::extract
Bimage * extract(long nn)
Extracts one sub-image into new image structure.
Definition: Bimage_extract.cpp:21
Bimage::shift
int shift(Vector3< double > vec, int fill_type=0, double fill=0)
Shifts an image.
Definition: Bimage_transform.cpp:587
Bimage::phase_shift_to_center
int phase_shift_to_center()
Phase shifts a set of reflections to the nominal center of the image origin.
Definition: Bimage_complex.cpp:382
Bimage::helix_symmetrize
double helix_symmetrize(double helix_rise, double helix_angle, int dyad_axis, int zmin, int zmax, double radius, int norm_flag=1)
Symmetrizes an image given helical symmetry parameters.
Definition: Bimage_helix.cpp:133
Bcolumn::number
long number()
Definition: Bplot.h:61
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
Bcolumn::type
long type()
Definition: Bplot.h:66
fft_plan
fftwf_plan fft_plan
Definition: fft.h:16
length
double length(vector< T > v)
Definition: Vector3.h:528
Bpage::axis
Baxis & axis(long id)
Definition: Bplot.h:117
Bimage::simple_to_complex
void simple_to_complex()
A simple image is converted to a complex image.
Definition: Bimage_complex.cpp:22
RGB
Definition: Color.h:24
Bpage::title
Bstring & title()
Definition: Bplot.h:100
Bimage::distort_elliptically
int distort_elliptically(double angle, double shift)
Transforms a tubular cylinder to an elliptical profile.
Definition: Bimage_helix.cpp:779
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bimage::calculate_background
int calculate_background(long nn, int flag)
Calculates the background for one sub-image.
Definition: Bimage_background.cpp:27
FILL_USER
#define FILL_USER
Definition: utilities.h:172
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bsub_image::sampling
void sampling(double x, double y, double z)
Definition: Bimage.h:123
RGB::r
Type r()
Definition: Color.h:45
Bimage::reslice
void reslice(const char *order)
Definition: Bimage.h:709
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
Bimage::helix_segment_correlation
Bplot * helix_segment_correlation(int thickness, double angle_start, double angle_end, double angle_step, int bin, double hires, double lores, double radius)
Calculates the correlation over rotation angles between helical segments.
Definition: Bimage_helix.cpp:1175
Bpage::add_text
void add_text(Bstring &s)
Definition: Bplot.h:122
Bimage::extrude_cross_section
int extrude_cross_section(long length, double helix_rise, double helix_angle, int fill_type, double fill)
Extrudes a 2D cross section into a 3D continuous helix.
Definition: Bimage_helix.cpp:1531
Complex
Definition: Complex.h:23
MIN2PI
#define MIN2PI
Definition: utilities.h:71
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
Bstring
Definition: Bstring.h:29
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2695
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
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
kmin
long kmin(long i, long hk)
Definition: Bimage_filter.cpp:17
Bplot::page
Bpage & page(long i)
Definition: Bplot.h:211
matrix_linear.h
Header file for matrix functions.
kmax
long kmax(long i, long km, long m)
Definition: Bimage_filter.cpp:22
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
Vector3< double >
Bimage::symmetry
string & symmetry()
Definition: Bimage.h:596
fft_destroy_plan
int fft_destroy_plan(fft_plan plan)
Deallocates a plan for fast Fourier transforms.
Definition: fft.cpp:87
Bimage::convert_to_helix
double convert_to_helix(double helix_rise, double helix_angle, Vector3< double > offset)
Converts a map to a helix.
Definition: Bimage_helix.cpp:721
Bimage::rotate
int rotate()
Rotates an image using parameters defined in the image in place.
Definition: Bimage_transform.cpp:253
Bimage::find_shift
int find_shift(Bimage *pref, Bimage *pmask, double hires, double lores, double radius, double sigma, int refine_flag)
Calculates a cross-correlation map to find the shift for the pair of images.
Definition: Bimage_correlate.cpp:932
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
Bimage::transform_lines
int transform_lines()
Definition: Bimage_helix.cpp:1300
Bpage::columns
void columns(long ncol)
Definition: Bplot.h:105
Bimage::integer_interpolation
int integer_interpolation(int integer_factor)
Definition: Bimage_bin.cpp:16
RGB::spectrum
void spectrum(double value, double cmin, double cmax)
Definition: Color.h:89
fftw
int fftw(fft_plan plan, Complex< float > *a)
Fast Fourier transforms a data array.
Definition: fft.cpp:106
Bimage::filament_density
Bimage * filament_density(double width)
Estimates the density per pixel length of a filament.
Definition: Bimage_helix.cpp:1688
Bimage::dyad_interpolate
double dyad_interpolate(long i, int norm_flag=1)
Definition: Bimage_helix.cpp:56
Bimage::images
long images()
Definition: Bimage.h:491
Bimage::helix_interpolate
double helix_interpolate(long i, double helix_rise, double helix_angle, int zmin, int zmax, double radius, int norm_flag=1)
Definition: Bimage_helix.cpp:18
Bimage::coordinates
void coordinates(long i, long &nx, long &ny, long &nz)
Definition: Bimage.h:416
Bimage::plot
Bplot * plot()
Converts a one-dimensional image into a plot.
Definition: Bimage.cpp:3836
Bimage::fill
void fill(double v)
Definition: Bimage.h:698
mg_reconstruct.h
Functions for reconstruction.
Vector3::volume
double volume()
Definition: Vector3.h:235
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::background
double background(long nn)
Definition: Bimage.h:542
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:106
Bimage::pad_copy
Bimage * pad_copy(long sz, int fill_type=0, double fill=0)
Pads an image to a new size with a given fill value.
Definition: Bimage_resize.cpp:392
TWOPI
#define TWOPI
Definition: utilities.h:68
RGB::b
Type b()
Definition: Color.h:47
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::tube_interpolate
double tube_interpolate(long i, int h, int k, double latconst, int zmin, int zmax, double radius, int norm_flag=1)
Definition: Bimage_helix.cpp:73
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
Bcolumn::axis
long axis()
Definition: Bplot.h:68
Bplot
Definition: Bplot.h:146
linear_least_squares
double linear_least_squares(int n1, int n2, double *x, double *y, double &a, double &b)
Does a linear least squares fit between two vectors.
Definition: matrix_linear.cpp:28