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

static CmpNEW ()

Static Public Attributes

static 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 403 of file cmp.h.


Constructor & Destructor Documentation

EMAN::OptVarianceCmp::OptVarianceCmp (  )  [inline]

Definition at line 406 of file cmp.h.

Referenced by NEW().

00406 : 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 734 of file cmp.cpp.

References b, EMAN::Util::calc_least_square_fit(), EMAN::EMData::calc_radial_dist(), EMAN::EMData::do_fft(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_const_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageDimensionException, nx, EMAN::Cmp::params, EMAN::EMData::ri2ap(), scale, EMAN::EMData::set_attr(), EMAN::Dict::set_default(), shift, square, EMAN::Util::square(), EMAN::Cmp::validate_input_args(), EMAN::EMData::write_image(), x, and y.

00735 {
00736         ENTERFUNC;
00737         validate_input_args(image, with);
00738 
00739         int keepzero = params.set_default("keepzero", 1);
00740         int invert = params.set_default("invert",0);
00741         int matchfilt = params.set_default("matchfilt",1);
00742         int matchamp = params.set_default("matchamp",0);
00743         int radweight = params.set_default("radweight",0);
00744         int dbug = params.set_default("debug",0);
00745 
00746         size_t size = (size_t)image->get_xsize() * image->get_ysize() * image->get_zsize();
00747 
00748 
00749         EMData *with2=NULL;
00750         if (matchfilt) {
00751                 EMData *a = image->do_fft();
00752                 EMData *b = with->do_fft();
00753 
00754                 vector <float> rfa=a->calc_radial_dist(a->get_ysize()/2,0.0f,1.0f,1);
00755                 vector <float> rfb=b->calc_radial_dist(b->get_ysize()/2,0.0f,1.0f,1);
00756 
00757                 float avg=0;
00758                 for (size_t i=0; i<a->get_ysize()/2.0f; i++) {
00759                         rfa[i]=(rfb[i]==0?0.0f:(rfa[i]/rfb[i]));
00760                         avg+=rfa[i];
00761                 }
00762 
00763                 avg/=a->get_ysize()/2.0f;
00764                 for (size_t i=0; i<a->get_ysize()/2.0f; i++) {
00765                         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
00766                 }
00767                 rfa[0]=0.0;
00768 
00769                 if (dbug) b->write_image("a.hdf",-1);
00770 
00771                 b->apply_radial_func(0.0f,1.0f/a->get_ysize(),rfa);
00772                 with2=b->do_ift();
00773 
00774                 if (dbug) b->write_image("a.hdf",-1);
00775                 if (dbug) a->write_image("a.hdf",-1);
00776 
00777 /*              if (dbug) {
00778                         FILE *out=fopen("a.txt","w");
00779                         for (int i=0; i<a->get_ysize()/2.0; i++) fprintf(out,"%d\t%f\n",i,rfa[i]);
00780                         fclose(out);
00781 
00782                         out=fopen("b.txt","w");
00783                         for (int i=0; i<a->get_ysize()/2.0; i++) fprintf(out,"%d\t%f\n",i,rfb[i]);
00784                         fclose(out);
00785                 }*/
00786 
00787 
00788                 delete a;
00789                 delete b;
00790 
00791                 if (dbug) {
00792                         with2->write_image("a.hdf",-1);
00793                         image->write_image("a.hdf",-1);
00794                 }
00795 
00796 //              with2->process_inplace("matchfilt",Dict("to",this));
00797 //              x_data = with2->get_data();
00798         }
00799 
00800         // This applies the individual Fourier amplitudes from 'image' and
00801         // applies them to 'with'
00802         if (matchamp) {
00803                 EMData *a = image->do_fft();
00804                 EMData *b = with->do_fft();
00805                 size_t size2 = (size_t)a->get_xsize() * a->get_ysize() * a->get_zsize();
00806 
00807                 a->ri2ap();
00808                 b->ri2ap();
00809 
00810                 const float *const ad=a->get_const_data();
00811                 float * bd=b->get_data();
00812 
00813                 for (size_t i=0; i<size2; i+=2) bd[i]=ad[i];
00814                 b->update();
00815 
00816                 b->ap2ri();
00817                 with2=b->do_ift();
00818 //with2->write_image("a.hdf",-1);
00819                 delete a;
00820                 delete b;
00821         }
00822 
00823         const float * x_data;
00824         if (with2) x_data=with2->get_const_data();
00825         else x_data = with->get_const_data();
00826         const float *const y_data = image->get_const_data();
00827 
00828         size_t nx = image->get_xsize();
00829         float m = 0;
00830         float b = 0;
00831 
00832         // This will write the x vs y file used to calculate the density
00833         // optimization. This behavior may change in the future
00834         if (dbug) {
00835                 FILE *out=fopen("dbug.optvar.txt","w");
00836                 if (out) {
00837                         for (size_t i=0; i<size; i++) {
00838                                 if ( !keepzero || (x_data[i] && y_data[i])) fprintf(out,"%g\t%g\n",x_data[i],y_data[i]);
00839                         }
00840                         fclose(out);
00841                 }
00842         }
00843 
00844 
00845         Util::calc_least_square_fit(size, x_data, y_data, &m, &b, keepzero);
00846         if (m == 0) {
00847                 m = FLT_MIN;
00848         }
00849         b = -b / m;
00850         m = 1.0f / m;
00851 
00852         // While negative slopes are really not a valid comparison in most cases, we
00853         // still want to detect these instances, so this if is removed
00854 /*      if (m < 0) {
00855                 b = 0;
00856                 m = 1000.0;
00857         }*/
00858 
00859         double  result = 0;
00860         int count = 0;
00861 
00862         if (radweight) {
00863                 if (image->get_zsize()!=1) throw ImageDimensionException("radweight option is 2D only");
00864                 if (keepzero) {
00865                         for (size_t i = 0,y=0; i < size; y++) {
00866                                 for (size_t x=0; x<nx; i++,x++) {
00867                                         if (y_data[i] && x_data[i]) {
00868 #ifdef  _WIN32
00869                                                 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(_hypot((float)x,(float)y)+nx/4.0);
00870                                                 else result += Util::square((x_data[i] * m) + b - y_data[i])*(_hypot((float)x,(float)y)+nx/4.0);
00871 #else
00872                                                 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(hypot((float)x,(float)y)+nx/4.0);
00873                                                 else result += Util::square((x_data[i] * m) + b - y_data[i])*(hypot((float)x,(float)y)+nx/4.0);
00874 #endif
00875                                                 count++;
00876                                         }
00877                                 }
00878                         }
00879                         result/=count;
00880                 }
00881                 else {
00882                         for (size_t i = 0,y=0; i < size; y++) {
00883                                 for (size_t x=0; x<nx; i++,x++) {
00884 #ifdef  _WIN32
00885                                         if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(_hypot((float)x,(float)y)+nx/4.0);
00886                                         else result += Util::square((x_data[i] * m) + b - y_data[i])*(_hypot((float)x,(float)y)+nx/4.0);
00887 #else
00888                                         if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(hypot((float)x,(float)y)+nx/4.0);
00889                                         else result += Util::square((x_data[i] * m) + b - y_data[i])*(hypot((float)x,(float)y)+nx/4.0);
00890 #endif
00891                                 }
00892                         }
00893                         result = result / size;
00894                 }
00895         }
00896         else {
00897                 if (keepzero) {
00898                         for (size_t i = 0; i < size; i++) {
00899                                 if (y_data[i] && x_data[i]) {
00900                                         if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m);
00901                                         else result += Util::square((x_data[i] * m) + b - y_data[i]);
00902                                         count++;
00903                                 }
00904                         }
00905                         result/=count;
00906                 }
00907                 else {
00908                         for (size_t i = 0; i < size; i++) {
00909                                 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m);
00910                                 else result += Util::square((x_data[i] * m) + b - y_data[i]);
00911                         }
00912                         result = result / size;
00913                 }
00914         }
00915         scale = m;
00916         shift = b;
00917 
00918         image->set_attr("ovcmp_m",m);
00919         image->set_attr("ovcmp_b",b);
00920         if (with2) delete with2;
00921         EXITFUNC;
00922 
00923 #if 0
00924         return (1 - result);
00925 #endif
00926 
00927         return static_cast<float>(result);
00928 }

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

Implements EMAN::Cmp.

Definition at line 415 of file cmp.h.

00416                 {
00417                         return "Real-space variance after density optimization, self should be noisy and target less noisy. Linear transform applied to density to minimize variance.";
00418                 }

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 410 of file cmp.h.

References NAME.

00411                 {
00412                         return NAME;
00413                 }

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 425 of file cmp.h.

References EMAN::EMObject::INT, and EMAN::TypeDict::put().

00426                 {
00427                         TypeDict d;
00428                         d.put("invert", EMObject::INT, "If set, 'with' is rescaled rather than 'this'. 'this' should still be the noisier image. (default=0)");
00429                         d.put("keepzero", EMObject::INT, "If set, zero pixels will not be adjusted in the linear density optimization. (default=1)");
00430                         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)");
00431                         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)");
00432                         d.put("radweight", EMObject::INT, "Upweight variances closer to the edge of the image. (default=0)");
00433                         d.put("debug", EMObject::INT, "Performs various debugging actions if set.");
00434                         return d;
00435                 }

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

Definition at line 437 of file cmp.h.

References scale.

00438                 {
00439                         return scale;
00440                 }

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

Definition at line 442 of file cmp.h.

References shift.

00443                 {
00444                         return shift;
00445                 }

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

Definition at line 420 of file cmp.h.

References OptVarianceCmp().

00421                 {
00422                         return new OptVarianceCmp();
00423                 }


Member Data Documentation

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

Definition at line 447 of file cmp.h.

Referenced by get_name().

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

Definition at line 450 of file cmp.h.

Referenced by cmp(), and get_scale().

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

Definition at line 451 of file cmp.h.

Referenced by cmp(), and get_shift().


The documentation for this class was generated from the following files:
Generated on Thu Nov 17 12:45:24 2011 for EMAN2 by  doxygen 1.4.7