#include <averager.h>
Inheritance diagram for EMAN::CtfAverager:
Public Member Functions | |
CtfAverager () | |
void | add_image (EMData *image) |
To add an image to the Averager. | |
EMData * | finish () |
Finish up the averaging and return the result. | |
vector< float > | get_snr () const |
Protected Attributes | |
XYData * | sf |
EMData * | curves |
bool | need_snr |
const char * | outfile |
Private Attributes | |
vector< float > | snr |
EMData * | image0_fft |
EMData * | image0_copy |
vector< vector< float > > | ctf |
vector< vector< float > > | ctfn |
float * | snri |
float * | snrn |
float * | tdr |
float * | tdi |
float * | tn |
float | filter |
int | nimg |
int | nx |
int | ny |
int | nz |
Definition at line 288 of file averager.h.
CtfAverager::CtfAverager | ( | ) |
void CtfAverager::add_image | ( | EMData * | image | ) | [virtual] |
To add an image to the Averager.
This image will be averaged in this function.
image | The image to be averaged. |
Implements EMAN::Averager.
Definition at line 813 of file averager.cpp.
References EMAN::EMData::ap2ri(), EMAN::Ctf::apix, EMAN::Ctf::compute_1d(), EMAN::EMData::copy_head(), ctf, EMAN::Ctf::CTF_AMP, EMAN::Ctf::CTF_SNR, ctfn, EMAN::Ctf::CTFOS, curves, EMAN::EMData::do_fft(), EMAN::Util::fast_floor(), filter, EMAN::EMData::get_data(), EMAN::Averager::get_name(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), image0_copy, image0_fft, EMAN::EMUtil::is_same_size(), LOGERR, LOGWARN, nimg, EMAN::Averager::params, EMAN::Averager::result, EMAN::EMData::set_size(), sf, snri, snrn, sqrt(), tdi, tdr, tn, EMAN::EMData::to_zero(), EMAN::EMData::update(), x, and y.
00814 { 00815 if (!image) { 00816 return; 00817 } 00818 00819 if (nimg >= 1 && !EMUtil::is_same_size(image, result)) { 00820 LOGERR("%sAverager can only process same-size Image", 00821 get_name().c_str()); 00822 return; 00823 } 00824 00825 if (image->get_zsize() != 1) { 00826 LOGERR("%sAverager: Only 2D images are currently supported", 00827 get_name().c_str()); 00828 } 00829 00830 string alg_name = get_name(); 00831 00832 if (alg_name == "CtfCW" || alg_name == "CtfCWauto") { 00833 if (image->get_ctf() != 0 && !image->has_ctff()) { 00834 LOGERR("%sAverager: Attempted CTF Correction with no ctf parameters", 00835 get_name().c_str()); 00836 } 00837 } 00838 else { 00839 if (image->get_ctf() != 0) { 00840 LOGERR("%sAverager: Attempted CTF Correction with no ctf parameters", 00841 get_name().c_str()); 00842 } 00843 } 00844 00845 nimg++; 00846 00847 00848 if (nimg == 1) { 00849 image0_fft = image->do_fft(); 00850 00851 nx = image0_fft->get_xsize(); 00852 ny = image0_fft->get_ysize(); 00853 nz = image0_fft->get_zsize(); 00854 00855 result = new EMData(); 00856 result->set_size(nx - 2, ny, nz); 00857 00858 00859 if (alg_name == "Weighting" && curves) { 00860 if (!sf) { 00861 LOGWARN("CTF curve in file will contain relative, not absolute SNR!"); 00862 } 00863 curves->set_size(Ctf::CTFOS * ny / 2, 3, 1); 00864 curves->to_zero(); 00865 } 00866 00867 00868 if (alg_name == "CtfC") { 00869 filter = params["filter"]; 00870 if (filter == 0) { 00871 filter = 22.0f; 00872 } 00873 float apix_y = image->get_attr_dict().get("apix_y"); 00874 float ds = 1.0f / (apix_y * ny * Ctf::CTFOS); 00875 filter = 1.0f / (filter * ds); 00876 } 00877 00878 if (alg_name == "CtfCWauto") { 00879 int nxy2 = nx * ny/2; 00880 00881 snri = new float[ny / 2]; 00882 snrn = new float[ny / 2]; 00883 tdr = new float[nxy2]; 00884 tdi = new float[nxy2]; 00885 tn = new float[nxy2]; 00886 00887 for (int i = 0; i < ny / 2; i++) { 00888 snri[i] = 0; 00889 snrn[i] = 0; 00890 } 00891 00892 for (int i = 0; i < nxy2; i++) { 00893 tdr[i] = 1; 00894 tdi[i] = 1; 00895 tn[i] = 1; 00896 } 00897 } 00898 00899 image0_copy = image0_fft->copy_head(); 00900 image0_copy->ap2ri(); 00901 image0_copy->to_zero(); 00902 } 00903 00904 Ctf::CtfType curve_type = Ctf::CTF_AMP; 00905 if (alg_name == "CtfCWauto") { 00906 curve_type = Ctf::CTF_AMP; 00907 } 00908 00909 float *src = image->get_data(); 00910 image->ap2ri(); 00911 Ctf *image_ctf = image->get_ctf(); 00912 int ny2 = image->get_ysize(); 00913 00914 vector<float> ctf1 = image_ctf->compute_1d(ny2,1.0f/(image_ctf->apix*image->get_ysize()), curve_type); 00915 00916 if (ctf1.size() == 0) { 00917 LOGERR("Unexpected CTF correction problem"); 00918 } 00919 00920 ctf.push_back(ctf1); 00921 00922 vector<float> ctfn1; 00923 if (sf) { 00924 ctfn1 = image_ctf->compute_1d(ny2,1.0f/(image_ctf->apix*image->get_ysize()), Ctf::CTF_SNR, sf); 00925 } 00926 else { 00927 ctfn1 = image_ctf->compute_1d(ny2,1.0f/(image_ctf->apix*image->get_ysize()), Ctf::CTF_SNR); 00928 } 00929 00930 ctfn.push_back(ctfn1); 00931 00932 if (alg_name == "CtfCWauto") { 00933 int j = 0; 00934 for (int y = 0; y < ny; y++) { 00935 for (int x = 0; x < nx / 2; x++, j += 2) { 00936 #ifdef _WIN32 00937 float r = (float)_hypot((float)x, (float)(y - ny / 2.0f)); 00938 #else 00939 float r = (float)hypot((float)x, (float)(y - ny / 2.0f)); 00940 #endif //_WIN32 00941 int l = static_cast < int >(Util::fast_floor(r)); 00942 00943 if (l >= 0 && l < ny / 2) { 00944 int k = y*nx/2 + x; 00945 tdr[k] *= src[j]; 00946 tdi[k] *= src[j + 1]; 00947 #ifdef _WIN32 00948 tn[k] *= (float)_hypot(src[j], src[j + 1]); 00949 #else 00950 tn[k] *= (float)hypot(src[j], src[j + 1]); 00951 #endif //_WIN32 00952 } 00953 } 00954 } 00955 } 00956 00957 00958 float *tmp_data = image0_copy->get_data(); 00959 00960 int j = 0; 00961 for (int y = 0; y < ny; y++) { 00962 for (int x = 0; x < nx / 2; x++, j += 2) { 00963 float r = Ctf::CTFOS * sqrt(x * x + (y - ny / 2.0f) * (y - ny / 2.0f)); 00964 int l = static_cast < int >(Util::fast_floor(r)); 00965 r -= l; 00966 00967 float f = 0; 00968 if (l <= Ctf::CTFOS * ny / 2 - 2) { 00969 f = (ctf1[l] * (1 - r) + ctf1[l + 1] * r); 00970 } 00971 tmp_data[j] += src[j] * f; 00972 tmp_data[j + 1] += src[j + 1] * f; 00973 } 00974 } 00975 00976 EMData *image_fft = image->do_fft(); 00977 image_fft->update(); 00978 if(image_ctf) {delete image_ctf; image_ctf=0;} 00979 }
EMData * CtfAverager::finish | ( | ) | [virtual] |
Finish up the averaging and return the result.
Implements EMAN::Averager.
Definition at line 981 of file averager.cpp.
References ctf, ctfn, EMAN::Ctf::CTFOS, curves, EMAN::EMData::do_ift(), EMAN::Util::fast_floor(), filter, EMAN::EMData::get_data(), EMAN::Averager::get_name(), image0_copy, need_snr, nimg, outfile, EMAN::Averager::result, EMAN::Util::save_data(), snr, snri, snrn, tdi, tdr, tn, EMAN::EMData::update(), x, and y.
00982 { 00983 int j = 0; 00984 for (int y = 0; y < ny; y++) { 00985 for (int x = 0; x < nx / 2; x++, j += 2) { 00986 #ifdef _WIN32 00987 float r = (float) _hypot(x, y - ny / 2.0f); 00988 #else 00989 float r = (float) hypot(x, y - ny / 2.0f); 00990 #endif 00991 int l = static_cast < int >(Util::fast_floor(r)); 00992 if (l >= 0 && l < ny / 2) { 00993 int k = y*nx/2 + x; 00994 snri[l] += (tdr[k] + tdi[k]/tn[k]); 00995 snrn[l] += 1; 00996 } 00997 } 00998 } 00999 01000 for (int i = 0; i < ny / 2; i++) { 01001 snri[i] *= nimg / snrn[i]; 01002 } 01003 01004 if(strcmp(outfile, "") != 0) { 01005 Util::save_data(0, 1, snri, ny / 2, outfile); 01006 } 01007 01008 01009 float *cd = 0; 01010 if (curves) { 01011 cd = curves->get_data(); 01012 } 01013 01014 for (int i = 0; i < Ctf::CTFOS * ny / 2; i++) { 01015 float ctf0 = 0; 01016 for (int j = 0; j < nimg; j++) { 01017 ctf0 += ctfn[j][i]; 01018 if (ctf[j][i] == 0) { 01019 ctf[j][i] = 1.0e-12f; 01020 } 01021 01022 if (curves) { 01023 cd[i] += ctf[j][i] * ctfn[j][i]; 01024 cd[i + Ctf::CTFOS * ny / 2] += ctfn[j][i]; 01025 cd[i + 2 * Ctf::CTFOS * ny / 2] += ctfn[j][i]; 01026 } 01027 } 01028 01029 string alg_name = get_name(); 01030 01031 if (alg_name == "CtfCW" && need_snr) { 01032 snr[i] = ctf0; 01033 } 01034 01035 float ctf1 = ctf0; 01036 if (alg_name == "CtfCWauto") { 01037 ctf1 = snri[i / Ctf::CTFOS]; 01038 } 01039 01040 if (ctf1 <= 0.0001f) { 01041 ctf1 = 0.1f; 01042 } 01043 01044 if (alg_name == "CtfC") { 01045 for (int j = 0; j < nimg; j++) { 01046 ctf[j][i] = exp(-i * i / (filter * filter)) * ctfn[j][i] / (fabs(ctf[j][i]) * ctf1); 01047 } 01048 } 01049 else if (alg_name == "Weighting") { 01050 for (int j = 0; j < nimg; j++) { 01051 ctf[j][i] = ctfn[j][i] / ctf1; 01052 } 01053 } 01054 else if (alg_name == "CtfCW") { 01055 for (int j = 0; j < nimg; j++) { 01056 ctf[j][i] = (ctf1 / (ctf1 + 1)) * ctfn[j][i] / (ctf[j][i] * ctf1); 01057 } 01058 } 01059 else if (alg_name == "CtfCWauto") { 01060 for (int j = 0; j < nimg; j++) { 01061 ctf[j][i] = ctf1 * ctfn[j][i] / (fabs(ctf[j][i]) * ctf0); 01062 } 01063 } 01064 } 01065 01066 01067 if (curves) { 01068 for (int i = 0; i < Ctf::CTFOS * ny / 2; i++) { 01069 cd[i] /= cd[i + Ctf::CTFOS * ny / 2]; 01070 } 01071 curves->update(); 01072 } 01073 01074 image0_copy->update(); 01075 01076 float *result_data = result->get_data(); 01077 EMData *tmp_ift = image0_copy->do_ift(); 01078 float *tmp_ift_data = tmp_ift->get_data(); 01079 memcpy(result_data, tmp_ift_data, (nx - 2) * ny * sizeof(float)); 01080 01081 tmp_ift->update(); 01082 result->update(); 01083 01084 if( image0_copy ) 01085 { 01086 delete image0_copy; 01087 image0_copy = 0; 01088 } 01089 01090 if (snri) { 01091 delete[]snri; 01092 snri = 0; 01093 } 01094 01095 if (snrn) { 01096 delete[]snrn; 01097 snrn = 0; 01098 } 01099 01100 if( snri ) 01101 { 01102 delete [] snri; 01103 snri = 0; 01104 } 01105 if( snrn ) 01106 { 01107 delete [] snrn; 01108 snrn = 0; 01109 } 01110 if( tdr ) 01111 { 01112 delete [] tdr; 01113 tdr = 0; 01114 } 01115 if( tdi ) 01116 { 01117 delete [] tdi; 01118 tdi = 0; 01119 } 01120 if( tn ) 01121 { 01122 delete [] tn; 01123 tn = 0; 01124 } 01125 01126 return result; 01127 }
vector< float > EMAN::CtfAverager::get_snr | ( | ) | const [inline] |
vector<vector<float> > EMAN::CtfAverager::ctf [private] |
vector<vector<float> > EMAN::CtfAverager::ctfn [private] |
EMData* EMAN::CtfAverager::curves [protected] |
Definition at line 302 of file averager.h.
Referenced by add_image(), finish(), and EMAN::WeightingAverager::set_params().
float EMAN::CtfAverager::filter [private] |
EMData* EMAN::CtfAverager::image0_copy [private] |
EMData* EMAN::CtfAverager::image0_fft [private] |
bool EMAN::CtfAverager::need_snr [protected] |
Definition at line 303 of file averager.h.
Referenced by finish(), and EMAN::CtfCWAverager::set_params().
int EMAN::CtfAverager::nimg [private] |
int EMAN::CtfAverager::nx [private] |
Definition at line 321 of file averager.h.
int EMAN::CtfAverager::ny [private] |
Definition at line 322 of file averager.h.
int EMAN::CtfAverager::nz [private] |
Definition at line 323 of file averager.h.
const char* EMAN::CtfAverager::outfile [protected] |
XYData* EMAN::CtfAverager::sf [protected] |
Definition at line 301 of file averager.h.
Referenced by add_image(), and EMAN::WeightingAverager::set_params().
vector< float > EMAN::CtfAverager::snr [mutable, private] |
float* EMAN::CtfAverager::snri [private] |
float* EMAN::CtfAverager::snrn [private] |
float* EMAN::CtfAverager::tdi [private] |
float* EMAN::CtfAverager::tdr [private] |
float* EMAN::CtfAverager::tn [private] |