Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

EMAN::OptVarianceCmp Class Reference

Variance between two data sets after various modifications. More...

#include <cmp.h>

Inheritance diagram for EMAN::OptVarianceCmp:

Inheritance graph
[legend]
Collaboration diagram for EMAN::OptVarianceCmp:

Collaboration graph
[legend]
List of all members.

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

CmpNEW ()

Static Public Attributes

const string NAME = "optvariance"

Private Attributes

float scale
float shift

Detailed Description

Variance between two data sets after various modifications.

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.


Constructor & Destructor Documentation

EMAN::OptVarianceCmp::OptVarianceCmp  )  [inline]
 

Definition at line 403 of file cmp.h.

00403 : scale(0), shift(0) {}


Member Function Documentation

float OptVarianceCmp::cmp EMData image,
EMData with
const [virtual]
 

To compare 'image' with another image passed in through its parameters.

An optional transformation may be used to transform the 2 images.

Parameters:
image The first image to be compared.
with The second image to be comppared.
Returns:
The comparison result. Smaller better by default

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 }

string EMAN::OptVarianceCmp::get_desc  )  const [inline, virtual]
 

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                 }

string EMAN::OptVarianceCmp::get_name  )  const [inline, virtual]
 

Get the Cmp's name.

Each Cmp is identified by a unique name.

Returns:
The Cmp's name.

Implements EMAN::Cmp.

Definition at line 407 of file cmp.h.

00408                 {
00409                         return NAME;
00410                 }

TypeDict EMAN::OptVarianceCmp::get_param_types  )  const [inline, virtual]
 

Get Cmp parameter information in a dictionary.

Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.

Returns:
A dictionary containing the parameter info.

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                 }

float EMAN::OptVarianceCmp::get_scale  )  const [inline]
 

Definition at line 434 of file cmp.h.

00435                 {
00436                         return scale;
00437                 }

float EMAN::OptVarianceCmp::get_shift  )  const [inline]
 

Definition at line 439 of file cmp.h.

00440                 {
00441                         return shift;
00442                 }

Cmp* EMAN::OptVarianceCmp::NEW  )  [inline, static]
 

Definition at line 417 of file cmp.h.

00418                 {
00419                         return new OptVarianceCmp();
00420                 }


Member Data Documentation

const string OptVarianceCmp::NAME = "optvariance" [static]
 

Definition at line 49 of file cmp.cpp.

float EMAN::OptVarianceCmp::scale [mutable, private]
 

Definition at line 447 of file cmp.h.

Referenced by cmp().

float EMAN::OptVarianceCmp::shift [mutable, private]
 

Definition at line 448 of file cmp.h.

Referenced by cmp().


The documentation for this class was generated from the following files:
Generated on Thu Dec 9 13:47:19 2010 for EMAN2 by  doxygen 1.3.9.1