| Bsoft 1.9 Bernard's software package

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
img_radial.cpp
Go to the documentation of this file.
1
9 #include "img_radial.h"
10 #include "Matrix.h"
11 #include "trigonometry.h"
12 #include "simplex.h"
13 #include "utilities.h"
14
15 // Declaration of global variables
16 extern int verbose; // Level of output to the screen
17
18 // Internal function prototypes
19 double img_radial_R(Bsimplex* simp);
20
45 Bimage* img_radial(Bimage* p, double minrad, double maxrad, double rad_step,
46 int wrap, double ellipticity, double angle, double threshold, Bimage* pmask)
47 {
48 unsigned long i, j, k, n, x, y, z, iradius, imin, imax, imax1, nrad(0);
49 double a, xx, yy, zz, radius, f, f1;
50 Vector3<double> origin;
51
52 if ( maxrad < minrad ) swap(minrad, maxrad);
53 if ( minrad < 0 ) minrad = 0;
54
55 if ( rad_step < 0.1 ) {
56 if ( p->sizeX() > 1 ) rad_step = p->sampling().x();
57 if ( p->sizeY() > 1 && rad_step > p->sampling().y() ) rad_step = p->sampling().y();
58 if ( p->sizeZ() > 1 && rad_step > p->sampling().z() ) rad_step = p->sampling().z();
59 }
60
61 if ( p->sizeZ() < 2 ) p->sampling(p->sampling().x(), p->sampling().y(), 1);
62
63 imin = (int) (minrad/rad_step);
64 imax = (int) (maxrad/rad_step + 1);
65 radius = p->real_size().length()/rad_step;
66 if ( maxrad <= 0 || imax > radius ) imax = (unsigned long) radius;
67 imax1 = imax - 1;
68 maxrad = imax1*rad_step;
69
70 if ( verbose & VERB_DEBUG )
71 cout << "DEBUG img_radial: radius=" << radius << " maxrad=" << maxrad << endl;
72
73 Bimage* prad = new Bimage(Float, TSimple, imax, 1, 1, p->images());
74 prad->file_name() = p->file_name();
75 prad->sampling(rad_step, 1, 1);
76 prad->origin(0,0,0);
77
78 float* num = new float[imax];
79
80 if ( verbose & VERB_PROCESS ) {
81 cout << "Calculating radial profile:" << endl;
82 cout << "Radial step size: " << rad_step << " A" << endl;
83 cout << "Minimum and maximum radius: " << minrad << " " << maxrad << " A" << endl;
84 cout << "Minimum and maximum pixels: " << imin << " " << imax1 << endl;
85 cout << "Ellipticity and angle: " << ellipticity << " " << angle << endl;
86 if ( threshold > p->minimum() )
87 cout << "Threshold: " << threshold << endl;
88 if ( pmask )
89 cout << "Mask: " << pmask->file_name() << endl;
90 cout << endl;
91 } else if ( verbose & VERB_LABEL )
92 cout << "Calculating a radial profile" << endl << endl;
93
94 for ( i=n=0; n<p->images(); n++ ) {
95 for ( j=0; j<imax; j++ ) num[j] = 0;
96 if ( p->sizeX() > 1 ) origin[0] = p->image[n].origin().x();
97 if ( p->sizeY() > 1 ) origin[1] = p->image[n].origin().y();
98 if ( p->sizeZ() > 1 ) origin[2] = p->image[n].origin().z();
99 for ( z=0; z<p->sizeZ(); z++ ) {
100 zz = z - origin.z();
101 if ( wrap && 2*fabs(zz) >= p->sizeZ() ) zz += (zz < 0)? p->sizeZ(): -p->sizeZ();
102 zz *= p->sampling().z();
103 for ( y=0; y<p->sizeY(); y++ ) {
104 yy = y - origin.y();
105 if ( wrap && 2*fabs(yy) >= p->sizeY() ) yy += (yy < 0)? p->sizeY(): -p->sizeY();
106 yy *= p->sampling().y();
107 for ( x=0; x<p->sizeX(); x++, i++ ) if ( ( !pmask ) || ( pmask && (*pmask)[i] ) ) {
108 xx = x - origin.x();
109 if ( wrap && 2*fabs(xx) >= p->sizeX() ) xx += (xx < 0)? p->sizeX(): -p->sizeX();
110 xx *= p->sampling().x();
111 radius = sqrt(xx*xx + yy*yy + zz*zz)/rad_step;
112 if ( ellipticity != 1 ) {
113 a = atan2(yy, xx) - angle;
114 radius *= sqrt((ellipticity*ellipticity+1)/
115 (2*(ellipticity*ellipticity*bcos(a)*bcos(a)+
116 bsin(a)*bsin(a))));
117 }
118 iradius = (unsigned long) radius;
119 if ( iradius >= imin && iradius < imax1 ) {
120 f = radius - iradius;
121 f1 = 1 - f;
122 num[iradius] += f1;
123 num[iradius+1] += f;
124 iradius += n*imax; // Add for multiple images
125 if ( threshold < p->minimum() ) {
126 prad->add(iradius, f1*(*p)[i]);
127 prad->add(iradius+1, f*(*p)[i]);
128 } else if ( (*p)[i] > threshold ) {
129 prad->add(iradius, f1);
130 prad->add(iradius+1, f);
131 }
132 nrad++;
133 }
134 }
135 }
136 }
137 if ( threshold < p->minimum() ) for ( j=0, k=imax*n; j<imax; j++, k++ )
138 if ( num[j] ) prad->set(k, (*prad)[k]/num[j]);
139 }
140
141 delete[] num;
142
143 if ( verbose & VERB_PROCESS )
144 cout << "Pixels in profile: " << nrad << endl;
145
146 if ( verbose & VERB_DEBUG )
147 cout << "DEBUG img_radial: Calculating statistics" << endl;
148
149 prad->statistics();
150
151 return prad;
152 }
153
154
155 Bimage* img_radial_average(Bimage* p, int minrad, int maxrad, int wrap)
156 {
157 return img_radial_average(p, minrad*p->sampling().x(), maxrad*p->sampling().x(), p->sampling().x(), wrap);
158 }
159
177 Bimage* img_radial_average(Bimage* p, double minrad, double maxrad,
178 double rad_step, int wrap)
179 {
180 return img_radial_average(p, minrad, maxrad, rad_step, wrap, NULL);
181 }
182
183 Bimage* img_radial_average(Bimage* p, double minrad, double maxrad,
184 double rad_step, int wrap, Bimage* pmask)
185 {
186 unsigned long i, j, n, x, y, z, iradius, imin, imax, imax1, nrad=0;
187 double xx, yy, zz, radius, f, f1;
188
189 if ( maxrad < minrad ) swap(minrad, maxrad);
190 if ( minrad < 0 ) minrad = 0;
191
192 if ( rad_step < 0.1 ) {
193 if ( p->sizeX() > 1 ) rad_step = p->sampling().x();
194 if ( p->sizeY() > 1 && rad_step > p->sampling().y() ) rad_step = p->sampling().y();
195 if ( p->sizeZ() > 1 && rad_step > p->sampling().z() ) rad_step = p->sampling().z();
196 }
197
198 Vector3<double> origin;
199 Vector3<double> scale(p->sampling()/rad_step);
200 if ( p->sizeZ() < 2 ) scale[2] = 1;
201
202 imin = (unsigned long) (minrad/rad_step);
203 imax = (unsigned long) (maxrad/rad_step + 1);
204 radius = sqrt((p->real_size()).length())/(2*rad_step);
205 if ( maxrad <= 0 ) imax = (unsigned long) radius;
206 imax1 = imax - 1;
207 maxrad = imax1*rad_step;
208
209 Bimage* prad = new Bimage(Float, TSimple, imax, 1, 1, p->images());
210 prad->sampling(rad_step, 1, 1);
211
212 float* fom = p->FOM();
213 float* radfom = NULL;
214 if ( fom ) radfom = prad->FOM_initialize();
215
216 float* num = new float[imax];
217
218 if ( pmask )
219 if ( pmask->data_type() != UCharacter || pmask->minimum() != 0 || pmask->maximum() != 1 )
220 pmask->to_mask();
221
222 if ( verbose & VERB_PROCESS ) {
223 cout << "Calculating a radial profile:" << endl;
224 cout << "Radial step size: " << rad_step << " A" << endl;
225 cout << "Minimum and maximum radius: " << minrad << " " << maxrad << " A" << endl;
226 cout << "Minimum and maximum pixels: " << imin << " " << imax1 << endl;
227 if ( wrap ) cout << "With wrapping" << endl;
228 if ( pmask )
229 cout << "Mask file: " << pmask->file_name() << endl;
230 } else if ( verbose & VERB_LABEL )
231 cout << "Calculating a radial profile" << endl << endl;
232
233 if ( verbose & VERB_PROCESS )
234 cout << "Image\toriX\toriY\toriZ" << endl;
235 for ( i=n=0; n<p->images(); n++ ) {
236 for ( j=0; j<imax; j++ ) num[j] = 0;
237 if ( p->sizeX() > 1 ) origin[0] = p->image[n].origin().x();
238 if ( p->sizeY() > 1 ) origin[1] = p->image[n].origin().y();
239 if ( p->sizeZ() > 1 ) origin[2] = p->image[n].origin().z();
240 if ( verbose & VERB_PROCESS )
241 cout << n+1 << tab << origin.x() << tab << origin.y() << tab << origin.z() << endl;
242 for ( z=0; z<p->sizeZ(); z++ ) {
243 zz = fabs(z - origin.z());
244 if ( wrap && 2*zz >= p->sizeZ() ) zz = p->sizeZ() - zz;
245 zz *= scale.z();
246 zz *= zz;
247 for ( y=0; y<p->sizeY(); y++ ) {
248 yy = fabs(y - origin.y());
249 if ( wrap && 2*yy >= p->sizeY() ) yy = p->sizeY() - yy;
250 yy *= scale.y();
251 yy *= yy;
252 for ( x=0; x<p->sizeX(); x++, i++ ) if ( ( !pmask ) || ( pmask && (*pmask)[i] ) ) {
253 xx = fabs(x - origin.x());
254 if ( wrap && 2*xx >= p->sizeX() ) xx = p->sizeX() - xx;
255 xx *= scale.x();
256 xx *= xx;
257 radius = sqrt(xx + yy + zz);
258 iradius = (unsigned long) radius;
259 if ( ( iradius >= imin ) && ( iradius < imax1 ) ) {
260 f = radius - iradius;
261 f1 = 1 - f;
262 num[iradius] += f1;
263 num[iradius+1] += f;
264 iradius += n*imax; // Add for multiple images
265 prad->add(iradius, f1*(*p)[i]);
266 prad->add(iradius+1, f*(*p)[i]);
267 nrad++;
268 if ( fom ) {
269 radfom[iradius] += f1*fom[i];
270 radfom[iradius+1] += f*fom[i];
271 }
272 }
273 }
274 }
275 }
276 for ( j=0, iradius = n*imax; j<imax; j++, iradius++ ) {
277 if ( num[j] ) {
278 prad->set(iradius, (*prad)[iradius]/num[j]);
279 if ( fom ) radfom[iradius] /= num[j];
280 }
281 }
282 prad->image[n].origin(0,0,0);
283 }
284
285 delete[] num;
286
287 if ( verbose & VERB_PROCESS )
288 cout << "Pixels in radial averages: " << nrad << endl;
289
290 if ( verbose & VERB_DEBUG )
291 cout << "DEBUG img_radial_average: Calculating statistics" << endl;
292
293 prad->statistics();
294
295 return prad;
296 }
297
320 Bimage* img_elliptical_average(Bimage* p, int rmin, int rmax, double ellipticity, double ellipse_angle)
321 {
322 unsigned long nrad = p->sizeX()/2;
323
324 Bimage* prad = new Bimage(Float, TSimple, nrad, 1, 1, p->images());
325
326 unsigned long i, x, y, n;
327 long ir, npix(0);
328 double dx, dy, r, angle, f, f1, cosang, sinang;
329 double ellmin = 1-ellipticity;
330 double ellmax = 1+ellipticity;
331 double* num = new double[nrad];
332
333 if ( verbose & VERB_FULL ) {
334 cout << "Elliptical average:" << endl;
335 cout << "Minimum and maximum radii: " << rmin << " " << rmax << endl;
336 cout << "Origin: " << p->image->origin() << endl;
337 cout << "Ellipticity and angle: " <<
338 ellipticity << " " << ellipse_angle*180.0/M_PI << endl;
339 }
340
341 for ( n=0; n<p->images(); n++ ) {
342 if ( verbose & VERB_DEBUG )
343 cout << "DEBUG img_elliptical_average: doing image " << n+1 << endl;
344 for ( i=0; i<nrad; i++ ) num[i] = 0;
345 for ( y=0; y<p->sizeY(); y++ ) {
346 dy = (double)y - p->image[n].origin().y();
347 for ( x=0; x<p->sizeX(); x++ ) {
348 dx = (double)x - p->image[n].origin().x();
349 r = sqrt(dx*dx + dy*dy);
350 if ( ellipticity ) {
351 ir = (long) r;
352 angle = atan2(dy, dx) - ellipse_angle;
353 cosang = bcos(angle);
354 sinang = bsin(angle);
355 r *= sqrt(ellmax*cosang*cosang + ellmin*sinang*sinang);
356 if ( !isfinite(r) )
357 cerr << "Warning: r for " << ir << " not finite!" << endl;
358 }
359 if ( r >= rmin && r <= rmax ) {
360 ir = (long) r;
361 if ( ir < nrad ) {
362 f = r - ir;
363 f1 = 1 - f;
364 num[ir] += f1;
365 i = (n*p->sizeY() + y)*p->sizeX() + x;
366 prad->add(n*nrad+ir, f1*(*p)[i]);
367 ir++;
368 if ( ir < nrad ) {
369 num[ir] += f;
370 prad->add(n*nrad+ir, f*(*p)[i]);
371 npix++;
372 }
373 }
374 }
375 }
376 }
377 for ( ir=0, i=n*nrad; ir<nrad; ir++, i++ ) {
378 if ( num[ir] ) prad->set(i, (*prad)[i]/num[ir]);
379 else prad->set(i, 0);
380 }
381 }
382
383 delete[] num;
384
385 if ( verbose & VERB_FULL )
386 cout << "Pixels in elliptical averages: " << npix << endl << endl;
387
388 prad->statistics();
389
390 return prad;
391 }
392
411 Bimage* img_directional_average(Bimage* p, double angle, double minrad, double maxrad,
412 double rad_step)
413 {
414 return img_directional_average(p, angle, minrad, maxrad, rad_step, NULL);
415 }
416
417 Bimage* img_directional_average(Bimage* p, double angle, double minrad, double maxrad,
418 double rad_step, Bimage* pmask)
419 {
420 angle = angle_set_negPI_to_PI(angle);
421
422 int aflag(0);
423 unsigned long i, j, k, n, x, y, z, iradius, imin, imax;
424 double dx, dy, dz, dx2, dy2, dz2, da, radius, f, f1;
425
426 if ( maxrad < minrad ) swap(minrad, maxrad);
427 if ( minrad < 0 ) minrad = 0;
428
429 if ( rad_step < 0.1 ) {
430 if ( p->sizeX() > 1 ) rad_step = p->sampling().x();
431 if ( p->sizeY() > 1 && rad_step > p->sampling().y() ) rad_step = p->sampling().y();
432 if ( p->sizeZ() > 1 && rad_step > p->sampling().z() ) rad_step = p->sampling().z();
433 }
434
435 Vector3<double> scale(p->sampling()/rad_step);
436 if ( p->sizeZ() < 2 ) scale[2] = 1;
437
438 imin = (unsigned long) (minrad/rad_step);
439 imax = (unsigned long) (maxrad/rad_step + 1);
440 radius = sqrt((p->real_size()).length2())/(2*rad_step);
441 if ( maxrad <= 0 || imax > radius ) imax = (unsigned long) radius;
442 maxrad = (imax - 1)*rad_step;
443
444 Bimage* prad = new Bimage(Float, TSimple, imax, 2, 1, p->images());
445 prad->sampling(rad_step, 1, 1);
446
447 float* num = new float[2*imax];
448
449 if ( pmask )
450 if ( pmask->data_type() != UCharacter || pmask->minimum() != 0 || pmask->maximum() != 1 )
451 pmask->to_mask();
452
453 if ( verbose & VERB_PROCESS ) {
454 cout << "Calculating a directional radial profile:" << endl;
455 cout << "Angle: " << angle*180.0/M_PI << endl;
456 cout << "Radial step size: " << rad_step << " A" << endl;
457 cout << "Minimum and maximum radius: " << minrad << " " << maxrad << " A" << endl;
458 cout << "Minimum and maximum pixels: " << imin << " " << imax - 1 << endl;
459 if ( pmask )
460 cout << "Mask file: " << pmask->file_name() << endl;
461 cout << endl;
462 } else if ( verbose & VERB_LABEL )
463 cout << "Calculating a radial profile" << endl << endl;
464
465 for ( i=n=0; n<p->images(); n++ ) {
466 for ( j=0; j<2*imax; j++ ) num[j] = 0;
467 for ( z=0; z<p->sizeZ(); z++ ) {
468 dz = (z - p->image[n].origin().z())*scale.z();
469 dz2 = dz*dz;
470 for ( y=0; y<p->sizeY(); y++ ) {
471 dy = (y - p->image[n].origin().y())*scale.y();
472 dy2 = dy*dy;
473 for ( x=0; x<p->sizeX(); x++, i++ ) if ( !pmask || ( pmask && (*pmask)[i] ) ) {
474 dx = (x - p->image[n].origin().x())*scale.x();
475 dx2 = dx*dx;
476 aflag = -1;
477 da = atan2(dy, dx) - angle;
478 while ( da < -M_PI_2 ) da += M_PI;
479 while ( da > M_PI_2 ) da -= M_PI;
480 da = fabs(da);
481 if ( da <= 0.1 ) aflag = 0;
482 else if ( da >= M_PI_2 - 0.1 ) aflag = 1;
483 if ( aflag >= 0 ) {
484 radius = sqrt(dx2 + dy2 + dz2);
485 iradius = (unsigned long) radius;
486 if ( iradius >= imin && iradius < imax - 1 ) {
487 f = radius - iradius;
488 f1 = 1 - f;
489 if ( aflag == 1 ) iradius += imax;
490 num[iradius] += f1;
491 num[iradius+1] += f;
492 iradius += n*2*imax; // Add for multiple images
493 prad->add(iradius, f1*(*p)[i]);
494 prad->add(iradius+1, f*(*p)[i]);
495 }
496 }
497 }
498 }
499 }
500 for ( j=0, k=2*imax*n; j<2*imax; j++, k++ )
501 if ( num[j] ) prad->set(k, (*prad)[k]/num[j]);
502 prad->image[n].origin();
503 }
504
505 delete[] num;
506
507 if ( verbose & VERB_DEBUG )
508 cout << "DEBUG img_directional_average: Calculating statistics" << endl;
509
510 prad->statistics();
511
512 return prad;
513 }
514
525 Bimage* img_radial_to_full(Bimage* prad, Vector3<int> size, Vector3<float> origin)
526 {
527 if ( size.volume() < 1 ) return NULL;
528
529 Bimage* p = prad->copy_header(prad->images());
530 p->data_type(Float);
531 p->size(size);
532 if ( p->sizeX() < 2 ) origin[0] = 0;
533 if ( p->sizeY() < 2 ) origin[1] = 0;
534 if ( p->sizeZ() < 2 ) origin[2] = 0;
535 p->data_alloc();
536
537 unsigned long i, n, x, y, z, ir, nexp(0);
538 double r, f, v;
539 Vector3<float> d;
540
541 if ( verbose ) {
542 cout << "Calculating a full image from a radial profile:" << endl;
543 cout << "Size: " << p->size() << endl;
544 cout << "Origin: " << origin << endl;
545 }
546
547 for ( n=i=0; n<p->images(); n++ ) {
548 for ( z=0; z<p->sizeZ(); z++ ) {
549 d[2] = z - origin.z();
550 for ( y=0; y<p->sizeY(); y++ ) {
551 d[1] = y - origin.y();
552 for ( x=0; x<p->sizeX(); x++, i++ ) {
553 d[0] = x - origin.x();
554 r = d.length();
555 ir = (unsigned long) r;
556 v = (*p)[i];
557 if ( ir < prad->sizeX() ) {
558 f = 1 - r + ir;
559 v += f*(*prad)[ir];
560 ir++;
561 f = 1 - f;
562 if ( ir < prad->sizeX() ) v += f*(*prad)[ir];
563 else v += f*prad->image[n].background();
564 nexp++;
565 } else {
566 v = prad->image[n].background();
567 }
568 p->set(i, v);
569 }
570 }
571 }
572 p->image[n].origin(origin);
573 }
574
575 if ( verbose )
576 cout << "Pixels generated: " << nexp << endl << endl;
577
578 p->statistics();
579
580 return p;
581 }
582
598 float* img_radial_fit(Bimage* p, Bimage* pref)
599 {
600 int i, npoint = p->sizeX();
601 if ( p->sizeX() < pref->sizeX() ) npoint = pref->sizeX();
602
603 // 3 parameters: Dimension scaling, amplitude scaling, amplitude shift
604 Bsimplex* simp = init_simplex(1, 3, 0, npoint);
605 for ( i=0; i<pref->sizeX(); i++ ) simp->x[i] = (*pref)[i];
606 for ( i=0; i<p->sizeX(); i++ ) simp->fx[i] = (*p)[i];
607
608 // Dimension scaling estimated from the input units
609 simp->param[0] = p->sampling().x()/pref->sampling().x();
610
611 // Amplitude scaling estimated from the standard deviations
612 simp->param[1] = 1;
613 if ( p->standard_deviation() != 0 && pref->standard_deviation() != 0 )
614 simp->param[1] = pref->standard_deviation()/p->standard_deviation();
615 else if ( p->maximum() - p->minimum() > 0 && pref->maximum() - pref->minimum() > 0 )
616 simp->param[1] = (pref->maximum() - pref->minimum())/(p->maximum() - p->minimum());
617
618 // Amplitude shift estimated from the averages
619 simp->param[2] = pref->average() - p->average()*simp->param[1];
620 // if ( simp->param[2] < 1e-6 && p->maximum() - p->minimum() > 0 && pref->maximum() - pref->minimum() > 0 )
621 // simp->param[2] = (pref->maximum() - pref->minimum() + p->maximum() - p->minimum())/2.0;
622
623 // Parameter limits
624 simp->lolimit[0] = 0.8*simp->param[0];
625 simp->hilimit[0] = 1.2*simp->param[0];
626 simp->lolimit[1] = 0.1*simp->param[1];
627 simp->hilimit[1] = 10*simp->param[1];
628 simp->lolimit[2] = simp->param[2] - 10*pref->standard_deviation();
629 simp->hilimit[2] = simp->param[2] + 10*pref->standard_deviation();
630
631 if ( verbose & VERB_PROCESS ) {
632 cout << "Radial fit initial parameters:" << endl;
633 cout << "Dimension scale: " << simp->param[0] << endl;
634 cout << "Amplitude scale and shift: " << simp->param[1] << " " << simp->param[2] << endl;
635 }
636
637 // Do the downhill simplex iterative fit
638 double R = simplex(simp, 10000, 1e-12*pref->standard_deviation(), img_radial_R) / pref->standard_deviation();
639
640 int idat;
641 double fraction, xdat, f;
642
643 if ( verbose & VERB_PROCESS ) {
644 cout << "Radial fit final parameters:" << endl;
645 cout << "Dimension scale: " << simp->param[0] << endl;
646 cout << "Relative dimension scale: " << simp->param[0]*pref->sampling().x()/p->sampling().x() << endl;
647 cout << "Amplitude scale and shift: " << simp->param[1] << " " << simp->param[2] << endl;
648 cout << "R: " << R << endl << endl;
649 cout << "Radial averages:" << endl;
650 cout << "Radius(A) " << p->file_name() << " " << pref->file_name() << endl;
651 } else if ( verbose & VERB_LABEL )
652 cout << "Radial fit final parameters" << endl << endl;
653
654 if ( verbose & VERB_PROCESS ) {
655 for ( i=0; i<pref->sizeX(); i++ ) {
656 xdat = i/simp->param[0];
657 idat = (int) xdat;
658 if ( idat >= 0 && idat < p->sizeX() - 1 ) {
659 fraction = xdat - idat;
660 f = simp->param[1]*((1.0 - fraction)*(*p)[idat]
661 + fraction*(*p)[idat+1]) + simp->param[2];
662 } else {
663 f = 0;
664 }
665 cout << pref->sampling().x()*i << " " << f << " " << (*pref)[i] << endl;
666 }
667 }
668
669 float* result = new float[simp->nparam];
670 for ( i=0; i<simp->nparam; i++ ) result[i] = simp->param[i];
671
672 kill_simplex(simp);
673
674 return result;
675 }
676
677 /*
678 @brief Least squares function for the img_radial_fit function.
679 @param Bsimplex* simp a simplex structure.
680 @return double the least squares R value.
681
682 A radial profile is fitted to a reference profile using an iterative
683 simplex down-hill method. The equations solved are:
684 xref = x*m
685 yref(xref) = y(x)*a + b
686 where m is the dimension scaling (or magnification).
687 a is the amplitude scaling.
688 b is the amplitude shift.
689 The least squares function is:
690 sum(weight*(yref(xref) - y(x)*a - b)^2)
691 R = sqrt(---------------------------------------)
692 sum(weight)
693 **/
694 double img_radial_R(Bsimplex* simp)
695 {
696 float* y = simp->fx;
697 float* yref = simp->x;
698
699 int i, iref, n(0);
700 double fraction, xref, df, R(0), sum(0), weight;
701
702 for ( i=0; i<simp->npoint; i++ ) {
703 xref = simp->param[0]*i;
704 iref = (int) xref;
705 if ( iref >= 0 && iref < simp->npoint - 1 ) {
706 fraction = xref - iref;
707 df = (1.0 - fraction)*yref[iref] + fraction*yref[iref + 1]
708 - simp->param[1]*y[i] - simp->param[2];
709 // weight = i*(fabs(yref[iref]) + fabs(y[i]));
710 weight = i;
711 // weight = fabs(y[i]);
712 sum += weight;
713 R += df*df*weight;
714 n++;
715 }
716 }
717 if ( sum && n > 0.2*simp->npoint ) R = sqrt(R/sum);
718 else R = 1e30; // Out of range
719
720 if ( verbose & VERB_DEBUG )
721 cout << "DEBUG img_radial_R: " << simp->param[0] << " " <<
722 simp->param[1] << " " << simp->param[2] << " R=" << R << endl;
723
724 return R;
725 }
726
Vector3::z
Type z()
Definition: Vector3.h:141
Bimage::sizeZ
void sizeZ(size_t nz)
Definition: Bimage.h:321
M_PI_2
#define M_PI_2
Definition: utilities.h:54
Bimage::copy_header
Bimage * copy_header()
Definition: Bimage.h:493
init_simplex
Bsimplex * init_simplex(int nvar, int nparam, int nconstant, int npoint)
Initializes a Bsimplex structure.
Definition: simplex.cpp:245
Bsimplex::fx
float * fx
Definition: simplex.h:53
bcos
double bcos(double x)
Avoid non-zero values for cos(PI/2) and cos(-PI/2).
Definition: trigonometry.cpp:27
Vector3::length
double length()
Definition: Vector3.h:198
Bsimplex::nparam
int nparam
Definition: simplex.h:45
Bsimplex
Definition: simplex.h:43
utilities.h
Header file for general utilities.
img_directional_average
Bimage * img_directional_average(Bimage *p, double angle, double minrad, double maxrad, double rad_step)
Calculates the radial average of an image.
Definition: img_radial.cpp:411
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:104
img_elliptical_average
Bimage * img_elliptical_average(Bimage *p, int rmin, int rmax, double ellipticity, double ellipse_angle)
Calculates the elliptical average of an image.
Definition: img_radial.cpp:320
Bsimplex::x
float * x
Definition: simplex.h:52
angle_set_negPI_to_PI
double angle_set_negPI_to_PI(double angle)
Returns an angle between -PI and PI.
Definition: utilities.cpp:530
Bsub_image::background
double background()
Definition: Bimage.h:127
Bsimplex::param
double * param
Definition: simplex.h:48
Float
Definition: Bimage.h:60
Vector3< double >
kill_simplex
int kill_simplex(Bsimplex *simp)
Frees all memory associated with a Bsimplex structure.
Definition: simplex.cpp:297
Matrix.h
Generalized matrix class.
verbose
int verbose
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:99
Bimage::average
double average(size_t cc, double xf, double yf, double zf, size_t nn, double iscale)
Averages in the xy plane when scaling is less than 1.
Definition: Bimage.cpp:1118
img_radial
Bimage * img_radial(Bimage *p, double minrad, double maxrad, double rad_step, int wrap, double ellipticity, double angle, double threshold, Bimage *pmask)
Calculates the elliptical radial average or volume of an image.
Definition: img_radial.cpp:45
Bimage::statistics
size_t statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
bsin
double bsin(double x)
Avoid non-zero values for sin(PI) and sin(-PI).
Definition: trigonometry.cpp:48
TSimple
Definition: Bimage.h:71
Bimage
General image parameter class.
Definition: Bimage.h:153
Bimage::real_size
Vector3< double > real_size()
Definition: Bimage.h:400
UCharacter
Definition: Bimage.h:52
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:225
M_PI
#define M_PI
Definition: utilities.h:51
Bsimplex::hilimit
double * hilimit
Definition: simplex.h:50
Bsimplex::npoint
int npoint
Definition: simplex.h:47
Bsimplex::lolimit
double * lolimit
Definition: simplex.h:49
Bimage::maximum
double maximum()
Definition: Bimage.h:419
Bimage::FOM_initialize
float * FOM_initialize()
Allocates and initializes the FOM block.
Definition: Bimage.cpp:598
Bimage::sampling
void sampling(double s)
Definition: Bimage.h:403
Bimage::FOM
float * FOM()
Definition: Bimage.h:238
Vector3::x
Type x()
Definition: Vector3.h:139
Bimage::file_name
void file_name(Bstring s)
Definition: Bimage.h:212
trigonometry.h
Header file for trigonometry functions.
Bimage::size
Vector3< size_t > size()
Definition: Bimage.h:316
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:133
Bimage::add
void add(size_t j, double v)
Definition: Bimage.h:264
Bimage::set
void set(size_t j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:884
Bimage::standard_deviation
double standard_deviation()
Definition: Bimage.h:421
Bimage::images
size_t images()
Definition: Bimage.h:401
simplex.h
Nelder and Mead downhill simplex method for generalized parameter fitting.
Bimage::sizeX
void sizeX(size_t nx)
Definition: Bimage.h:319
img_radial.h
Library routines for radial transformations and calculations.
img_radial_to_full
Bimage * img_radial_to_full(Bimage *prad, Vector3< int > size, Vector3< float > origin)
Generates a full 2D or 3D image from a radial profile in a 1D image.
Definition: img_radial.cpp:525
Bimage::sizeY
void sizeY(size_t ny)
Definition: Bimage.h:320
img_radial_R
double img_radial_R(Bsimplex *simp)
Definition: img_radial.cpp:694
img_radial_average
Bimage * img_radial_average(Bimage *p, int minrad, int maxrad, int wrap)
Definition: img_radial.cpp:155
simplex
double simplex(Bsimplex *simp, int maxcycles, double tolerance, double(funk)(Bsimplex *))
Estimates parameters using a generalized search algorithm.
Definition: simplex.cpp:44
Bimage::to_mask
size_t to_mask()
Definition: Bimage.h:828
img_radial_fit
float * img_radial_fit(Bimage *p, Bimage *pref)
Fits a radial profile to a reference radial profile.
Definition: img_radial.cpp:598
VERB_FULL
#define VERB_FULL
Definition: utilities.h:101
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:98
Bimage::data_type
DataType data_type()
Definition: Bimage.h:294
Vector3::volume
double volume()
Definition: Vector3.h:207
Vector3::y
Type y()
Definition: Vector3.h:140
Bimage::minimum
double minimum()
Definition: Bimage.h:418
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::image
Bsub_image * image
Definition: Bimage.h:184
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:439