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 ()

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


Constructor & Destructor Documentation

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

Definition at line 354 of file cmp.h.

Referenced by NEW().

00354 : 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 526 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(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_const_data(), EMAN::EMData::get_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::EMData::update(), EMAN::Cmp::validate_input_args(), EMAN::EMData::write_image(), x, and y.

00527 {
00528         ENTERFUNC;
00529         validate_input_args(image, with);
00530 
00531         int keepzero = params.set_default("keepzero", 1);
00532         int invert = params.set_default("invert",0);
00533         int matchfilt = params.set_default("matchfilt",1);
00534         int matchamp = params.set_default("matchamp",0);
00535         int radweight = params.set_default("radweight",0);
00536         int dbug = params.set_default("debug",0);
00537 
00538         size_t size = image->get_xsize() * image->get_ysize() * image->get_zsize();
00539 
00540 
00541         EMData *with2=NULL;
00542         if (matchfilt) {
00543                 EMData *a = image->do_fft();
00544                 EMData *b = with->do_fft();
00545 
00546                 vector <float> rfa=a->calc_radial_dist(a->get_ysize()/2,0.0f,1.0f,1);
00547                 vector <float> rfb=b->calc_radial_dist(b->get_ysize()/2,0.0f,1.0f,1);
00548 
00549                 float avg=0;
00550                 for (size_t i=0; i<a->get_ysize()/2.0f; i++) {
00551                         rfa[i]=(rfb[i]==0?0.0f:(rfa[i]/rfb[i]));
00552                         avg+=rfa[i];
00553                 }
00554 
00555                 avg/=a->get_ysize()/2.0f;
00556                 for (size_t i=0; i<a->get_ysize()/2.0f; i++) {
00557                         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
00558                 }
00559                 rfa[0]=0.0;
00560 
00561                 if (dbug) b->write_image("a.hdf",-1);
00562 
00563                 b->apply_radial_func(0.0f,1.0f/a->get_ysize(),rfa);
00564                 with2=b->do_ift();
00565 
00566                 if (dbug) b->write_image("a.hdf",-1);
00567                 if (dbug) a->write_image("a.hdf",-1);
00568 
00569 /*              if (dbug) {
00570                         FILE *out=fopen("a.txt","w");
00571                         for (int i=0; i<a->get_ysize()/2.0; i++) fprintf(out,"%d\t%f\n",i,rfa[i]);
00572                         fclose(out);
00573 
00574                         out=fopen("b.txt","w");
00575                         for (int i=0; i<a->get_ysize()/2.0; i++) fprintf(out,"%d\t%f\n",i,rfb[i]);
00576                         fclose(out);
00577                 }*/
00578 
00579 
00580                 delete a;
00581                 delete b;
00582 
00583                 if (dbug) {
00584                         with2->write_image("a.hdf",-1);
00585                         image->write_image("a.hdf",-1);
00586                 }
00587 
00588 //              with2->process_inplace("matchfilt",Dict("to",this));
00589 //              x_data = with2->get_data();
00590         }
00591 
00592         // This applies the individual Fourier amplitudes from 'image' and
00593         // applies them to 'with'
00594         if (matchamp) {
00595                 EMData *a = image->do_fft();
00596                 EMData *b = with->do_fft();
00597                 size_t size2 = a->get_xsize() * a->get_ysize() * a->get_zsize();
00598 
00599                 a->ri2ap();
00600                 b->ri2ap();
00601 
00602                 const float *const ad=a->get_const_data();
00603                 float * bd=b->get_data();
00604 
00605                 for (size_t i=0; i<size2; i+=2) bd[i]=ad[i];
00606                 b->update();
00607 
00608                 b->ap2ri();
00609                 with2=b->do_ift();
00610 //with2->write_image("a.hdf",-1);
00611                 delete a;
00612                 delete b;
00613         }
00614 
00615         const float * x_data;
00616         if (with2) x_data=with2->get_const_data();
00617         else x_data = with->get_const_data();
00618         const float *const y_data = image->get_const_data();
00619 
00620         size_t nx = image->get_xsize();
00621         float m = 0;
00622         float b = 0;
00623 
00624         // This will write the x vs y file used to calculate the density
00625         // optimization. This behavior may change in the future
00626         if (dbug) {
00627                 FILE *out=fopen("dbug.optvar.txt","w");
00628                 if (out) {
00629                         for (size_t i=0; i<size; i++) {
00630                                 if ( !keepzero || (x_data[i] && y_data[i])) fprintf(out,"%g\t%g\n",x_data[i],y_data[i]);
00631                         }
00632                         fclose(out);
00633                 }
00634         }
00635 
00636 
00637         Util::calc_least_square_fit(size, x_data, y_data, &m, &b, keepzero);
00638         if (m == 0) {
00639                 m = FLT_MIN;
00640         }
00641         b = -b / m;
00642         m = 1.0f / m;
00643 
00644         // While negative slopes are really not a valid comparison in most cases, we
00645         // still want to detect these instances, so this if is removed
00646 /*      if (m < 0) {
00647                 b = 0;
00648                 m = 1000.0;
00649         }*/
00650 
00651         double  result = 0;
00652         int count = 0;
00653 
00654         if (radweight) {
00655                 if (image->get_zsize()!=1) throw ImageDimensionException("radweight option is 2D only");
00656                 if (keepzero) {
00657                         for (size_t i = 0,y=0; i < size; y++) {
00658                                 for (size_t x=0; x<nx; i++,x++) {
00659                                         if (y_data[i] && x_data[i]) {
00660 #ifdef  _WIN32
00661                                                 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(_hypot((float)x,(float)y)+nx/4.0);
00662                                                 else result += Util::square((x_data[i] * m) + b - y_data[i])*(_hypot((float)x,(float)y)+nx/4.0);
00663 #else
00664                                                 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(hypot((float)x,(float)y)+nx/4.0);
00665                                                 else result += Util::square((x_data[i] * m) + b - y_data[i])*(hypot((float)x,(float)y)+nx/4.0);
00666 #endif
00667                                                 count++;
00668                                         }
00669                                 }
00670                         }
00671                         result/=count;
00672                 }
00673                 else {
00674                         for (size_t i = 0,y=0; i < size; y++) {
00675                                 for (size_t x=0; x<nx; i++,x++) {
00676 #ifdef  _WIN32
00677                                         if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(_hypot((float)x,(float)y)+nx/4.0);
00678                                         else result += Util::square((x_data[i] * m) + b - y_data[i])*(_hypot((float)x,(float)y)+nx/4.0);
00679 #else
00680                                         if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(hypot((float)x,(float)y)+nx/4.0);
00681                                         else result += Util::square((x_data[i] * m) + b - y_data[i])*(hypot((float)x,(float)y)+nx/4.0);
00682 #endif
00683                                 }
00684                         }
00685                         result = result / size;
00686                 }
00687         }
00688         else {
00689                 if (keepzero) {
00690                         for (size_t i = 0; i < size; i++) {
00691                                 if (y_data[i] && x_data[i]) {
00692                                         if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m);
00693                                         else result += Util::square((x_data[i] * m) + b - y_data[i]);
00694                                         count++;
00695                                 }
00696                         }
00697                         result/=count;
00698                 }
00699                 else {
00700                         for (size_t i = 0; i < size; i++) {
00701                                 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m);
00702                                 else result += Util::square((x_data[i] * m) + b - y_data[i]);
00703                         }
00704                         result = result / size;
00705                 }
00706         }
00707         scale = m;
00708         shift = b;
00709 
00710         image->set_attr("ovcmp_m",m);
00711         image->set_attr("ovcmp_b",b);
00712         if (with2) delete with2;
00713         EXITFUNC;
00714 
00715 #if 0
00716         return (1 - result);
00717 #endif
00718 
00719         return static_cast<float>(result);
00720 }

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

00359                 {
00360                         return "optvariance";
00361                 }

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

Implements EMAN::Cmp.

Definition at line 363 of file cmp.h.

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

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

Definition at line 368 of file cmp.h.

References OptVarianceCmp().

00369                 {
00370                         return new OptVarianceCmp();
00371                 }

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

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

00374                 {
00375                         TypeDict d;
00376                         d.put("invert", EMObject::INT, "If set, 'with' is rescaled rather than 'this'. 'this' should still be the noisier image. (default=0)");
00377                         d.put("keepzero", EMObject::INT, "If set, zero pixels will not be adjusted in the linear density optimization. (default=1)");
00378                         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)");
00379                         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)");
00380                         d.put("radweight", EMObject::INT, "Upweight variances closer to the edge of the image. (default=0)");
00381                         d.put("debug", EMObject::INT, "Performs various debugging actions if set.");
00382                         return d;
00383                 }

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

Definition at line 385 of file cmp.h.

References scale.

00386                 {
00387                         return scale;
00388                 }

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

Definition at line 390 of file cmp.h.

References shift.

00391                 {
00392                         return shift;
00393                 }


Member Data Documentation

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

Definition at line 396 of file cmp.h.

Referenced by cmp(), and get_scale().

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

Definition at line 397 of file cmp.h.

Referenced by cmp(), and get_shift().


The documentation for this class was generated from the following files:

Generated on Sat Nov 21 02:20:17 2009 for EMAN2 by  doxygen 1.5.6