#include <cmp.h>
Inheritance diagram for EMAN::OptVarianceCmp:
Public Member Functions | |
OptVarianceCmp () | |
float | cmp (EMData *image, EMData *with) const |
To compare 'image' with another image passed in through its parameters. | |
string | get_name () const |
Get the Cmp's name. | |
string | get_desc () const |
TypeDict | get_param_types () const |
Get Cmp parameter information in a dictionary. | |
float | get_scale () const |
float | get_shift () const |
Static Public Member Functions | |
Cmp * | NEW () |
Static Public Attributes | |
const string | NAME = "optvariance" |
Private Attributes | |
float | scale |
float | shift |
Generally, 'this' should be noisy and 'with' should be less noisy. linear scaling (mx + b) of the densities in 'this' is performed to produce the smallest possible variance between images.
If keepzero is set, then zero pixels are left at zero (b is not added). if matchfilt is set, then 'with' is filtered so its radial power spectrum matches 'this' If invert is set, then (y-b)/m is applied to the second image rather than mx+b to the first.
To modify 'this' to match the operation performed here, scale should be applied first, then b should be added
Definition at line 400 of file cmp.h.
|
Definition at line 403 of file cmp.h.
|
|
To compare 'image' with another image passed in through its parameters. An optional transformation may be used to transform the 2 images.
Implements EMAN::Cmp. Definition at line 669 of file cmp.cpp. References EMAN::EMData::ap2ri(), EMAN::EMData::apply_radial_func(), b, EMAN::Util::calc_least_square_fit(), EMAN::EMData::calc_radial_dist(), EMAN::EMData::do_fft(), EMAN::EMData::do_ift(), EMAN::EMData::get_const_data(), EMAN::EMData::get_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageDimensionException, nx, EMAN::EMData::ri2ap(), scale, EMAN::EMData::set_attr(), EMAN::Dict::set_default(), shift, square, EMAN::EMData::update(), EMAN::Cmp::validate_input_args(), EMAN::EMData::write_image(), x, and y. 00670 { 00671 ENTERFUNC; 00672 validate_input_args(image, with); 00673 00674 int keepzero = params.set_default("keepzero", 1); 00675 int invert = params.set_default("invert",0); 00676 int matchfilt = params.set_default("matchfilt",1); 00677 int matchamp = params.set_default("matchamp",0); 00678 int radweight = params.set_default("radweight",0); 00679 int dbug = params.set_default("debug",0); 00680 00681 size_t size = image->get_xsize() * image->get_ysize() * image->get_zsize(); 00682 00683 00684 EMData *with2=NULL; 00685 if (matchfilt) { 00686 EMData *a = image->do_fft(); 00687 EMData *b = with->do_fft(); 00688 00689 vector <float> rfa=a->calc_radial_dist(a->get_ysize()/2,0.0f,1.0f,1); 00690 vector <float> rfb=b->calc_radial_dist(b->get_ysize()/2,0.0f,1.0f,1); 00691 00692 float avg=0; 00693 for (size_t i=0; i<a->get_ysize()/2.0f; i++) { 00694 rfa[i]=(rfb[i]==0?0.0f:(rfa[i]/rfb[i])); 00695 avg+=rfa[i]; 00696 } 00697 00698 avg/=a->get_ysize()/2.0f; 00699 for (size_t i=0; i<a->get_ysize()/2.0f; i++) { 00700 if (rfa[i]>avg*10.0) rfa[i]=10.0; // If some particular location has a small but non-zero value, we don't want to overcorrect it 00701 } 00702 rfa[0]=0.0; 00703 00704 if (dbug) b->write_image("a.hdf",-1); 00705 00706 b->apply_radial_func(0.0f,1.0f/a->get_ysize(),rfa); 00707 with2=b->do_ift(); 00708 00709 if (dbug) b->write_image("a.hdf",-1); 00710 if (dbug) a->write_image("a.hdf",-1); 00711 00712 /* if (dbug) { 00713 FILE *out=fopen("a.txt","w"); 00714 for (int i=0; i<a->get_ysize()/2.0; i++) fprintf(out,"%d\t%f\n",i,rfa[i]); 00715 fclose(out); 00716 00717 out=fopen("b.txt","w"); 00718 for (int i=0; i<a->get_ysize()/2.0; i++) fprintf(out,"%d\t%f\n",i,rfb[i]); 00719 fclose(out); 00720 }*/ 00721 00722 00723 delete a; 00724 delete b; 00725 00726 if (dbug) { 00727 with2->write_image("a.hdf",-1); 00728 image->write_image("a.hdf",-1); 00729 } 00730 00731 // with2->process_inplace("matchfilt",Dict("to",this)); 00732 // x_data = with2->get_data(); 00733 } 00734 00735 // This applies the individual Fourier amplitudes from 'image' and 00736 // applies them to 'with' 00737 if (matchamp) { 00738 EMData *a = image->do_fft(); 00739 EMData *b = with->do_fft(); 00740 size_t size2 = a->get_xsize() * a->get_ysize() * a->get_zsize(); 00741 00742 a->ri2ap(); 00743 b->ri2ap(); 00744 00745 const float *const ad=a->get_const_data(); 00746 float * bd=b->get_data(); 00747 00748 for (size_t i=0; i<size2; i+=2) bd[i]=ad[i]; 00749 b->update(); 00750 00751 b->ap2ri(); 00752 with2=b->do_ift(); 00753 //with2->write_image("a.hdf",-1); 00754 delete a; 00755 delete b; 00756 } 00757 00758 const float * x_data; 00759 if (with2) x_data=with2->get_const_data(); 00760 else x_data = with->get_const_data(); 00761 const float *const y_data = image->get_const_data(); 00762 00763 size_t nx = image->get_xsize(); 00764 float m = 0; 00765 float b = 0; 00766 00767 // This will write the x vs y file used to calculate the density 00768 // optimization. This behavior may change in the future 00769 if (dbug) { 00770 FILE *out=fopen("dbug.optvar.txt","w"); 00771 if (out) { 00772 for (size_t i=0; i<size; i++) { 00773 if ( !keepzero || (x_data[i] && y_data[i])) fprintf(out,"%g\t%g\n",x_data[i],y_data[i]); 00774 } 00775 fclose(out); 00776 } 00777 } 00778 00779 00780 Util::calc_least_square_fit(size, x_data, y_data, &m, &b, keepzero); 00781 if (m == 0) { 00782 m = FLT_MIN; 00783 } 00784 b = -b / m; 00785 m = 1.0f / m; 00786 00787 // While negative slopes are really not a valid comparison in most cases, we 00788 // still want to detect these instances, so this if is removed 00789 /* if (m < 0) { 00790 b = 0; 00791 m = 1000.0; 00792 }*/ 00793 00794 double result = 0; 00795 int count = 0; 00796 00797 if (radweight) { 00798 if (image->get_zsize()!=1) throw ImageDimensionException("radweight option is 2D only"); 00799 if (keepzero) { 00800 for (size_t i = 0,y=0; i < size; y++) { 00801 for (size_t x=0; x<nx; i++,x++) { 00802 if (y_data[i] && x_data[i]) { 00803 #ifdef _WIN32 00804 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(_hypot((float)x,(float)y)+nx/4.0); 00805 else result += Util::square((x_data[i] * m) + b - y_data[i])*(_hypot((float)x,(float)y)+nx/4.0); 00806 #else 00807 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(hypot((float)x,(float)y)+nx/4.0); 00808 else result += Util::square((x_data[i] * m) + b - y_data[i])*(hypot((float)x,(float)y)+nx/4.0); 00809 #endif 00810 count++; 00811 } 00812 } 00813 } 00814 result/=count; 00815 } 00816 else { 00817 for (size_t i = 0,y=0; i < size; y++) { 00818 for (size_t x=0; x<nx; i++,x++) { 00819 #ifdef _WIN32 00820 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(_hypot((float)x,(float)y)+nx/4.0); 00821 else result += Util::square((x_data[i] * m) + b - y_data[i])*(_hypot((float)x,(float)y)+nx/4.0); 00822 #else 00823 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(hypot((float)x,(float)y)+nx/4.0); 00824 else result += Util::square((x_data[i] * m) + b - y_data[i])*(hypot((float)x,(float)y)+nx/4.0); 00825 #endif 00826 } 00827 } 00828 result = result / size; 00829 } 00830 } 00831 else { 00832 if (keepzero) { 00833 for (size_t i = 0; i < size; i++) { 00834 if (y_data[i] && x_data[i]) { 00835 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m); 00836 else result += Util::square((x_data[i] * m) + b - y_data[i]); 00837 count++; 00838 } 00839 } 00840 result/=count; 00841 } 00842 else { 00843 for (size_t i = 0; i < size; i++) { 00844 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m); 00845 else result += Util::square((x_data[i] * m) + b - y_data[i]); 00846 } 00847 result = result / size; 00848 } 00849 } 00850 scale = m; 00851 shift = b; 00852 00853 image->set_attr("ovcmp_m",m); 00854 image->set_attr("ovcmp_b",b); 00855 if (with2) delete with2; 00856 EXITFUNC; 00857 00858 #if 0 00859 return (1 - result); 00860 #endif 00861 00862 return static_cast<float>(result); 00863 }
|
|
Implements EMAN::Cmp. Definition at line 412 of file cmp.h. 00413 { 00414 return "Real-space variance after density optimization, self should be noisy and target less noisy. Linear transform applied to density to minimize variance."; 00415 }
|
|
Get the Cmp's name. Each Cmp is identified by a unique name.
Implements EMAN::Cmp. Definition at line 407 of file cmp.h. 00408 {
00409 return NAME;
00410 }
|
|
Get Cmp parameter information in a dictionary. Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.
Implements EMAN::Cmp. Definition at line 422 of file cmp.h. References EMAN::TypeDict::put(). 00423 { 00424 TypeDict d; 00425 d.put("invert", EMObject::INT, "If set, 'with' is rescaled rather than 'this'. 'this' should still be the noisier image. (default=0)"); 00426 d.put("keepzero", EMObject::INT, "If set, zero pixels will not be adjusted in the linear density optimization. (default=1)"); 00427 d.put("matchfilt", EMObject::INT, "If set, with will be filtered so its radial power spectrum matches 'this' before density optimization of this. (default=1)"); 00428 d.put("matchamp", EMObject::INT, "Takes per-pixel Fourier amplitudes from self and imposes them on the target, but leaves the phases alone. (default=0)"); 00429 d.put("radweight", EMObject::INT, "Upweight variances closer to the edge of the image. (default=0)"); 00430 d.put("debug", EMObject::INT, "Performs various debugging actions if set."); 00431 return d; 00432 }
|
|
Definition at line 434 of file cmp.h. 00435 {
00436 return scale;
00437 }
|
|
Definition at line 439 of file cmp.h. 00440 {
00441 return shift;
00442 }
|
|
Definition at line 417 of file cmp.h. 00418 { 00419 return new OptVarianceCmp(); 00420 }
|
|
|
|
Definition at line 447 of file cmp.h. Referenced by cmp(). |
|
Definition at line 448 of file cmp.h. Referenced by cmp(). |