00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "averager.h"
00037 #include "emdata.h"
00038 #include "xydata.h"
00039 #include "ctf.h"
00040 #include <cstring>
00041 #include "plugins/averager_template.h"
00042
00043 using namespace EMAN;
00044
00045 const string ImageAverager::NAME = "mean";
00046 const string MinMaxAverager::NAME = "minmax";
00047 const string IterationAverager::NAME = "iteration";
00048 const string WeightingAverager::NAME = "snr_weight";
00049 const string CtfCAverager::NAME = "ctfc";
00050 const string CtfCWAverager::NAME = "ctfcw";
00051 const string CtfCWautoAverager::NAME = "ctfw.auto";
00052 const string CtfCAutoAverager::NAME = "ctf.auto";
00053
00054 template <> Factory < Averager >::Factory()
00055 {
00056 force_add<ImageAverager>();
00057 force_add<MinMaxAverager>();
00058 force_add<IterationAverager>();
00059
00060
00061
00062
00063 force_add<CtfCWautoAverager>();
00064 force_add<CtfCAutoAverager>();
00065
00066 }
00067
00068 void Averager::mult(const float& s)
00069 {
00070 if ( result != 0 )
00071 {
00072 result->mult(s);
00073 }
00074 else throw NullPointerException("Error, attempted to multiply the result image, which is NULL");
00075 }
00076
00077
00078 void Averager::add_image_list(const vector<EMData*> & image_list)
00079 {
00080 for (size_t i = 0; i < image_list.size(); i++) {
00081 add_image(image_list[i]);
00082 }
00083 }
00084
00085 ImageAverager::ImageAverager()
00086 : sigma_image(0), nimg_n0(0), ignore0(0), nimg(0)
00087 {
00088
00089 }
00090
00091 void ImageAverager::add_image(EMData * image)
00092 {
00093 if (!image) {
00094 return;
00095 }
00096
00097 if (nimg >= 1 && !EMUtil::is_same_size(image, result)) {
00098 LOGERR("%sAverager can only process same-size Image",
00099 get_name().c_str());
00100 return;
00101 }
00102
00103 nimg++;
00104
00105 int nx = image->get_xsize();
00106 int ny = image->get_ysize();
00107 int nz = image->get_zsize();
00108 size_t image_size = nx * ny * nz;
00109
00110 if (nimg == 1) {
00111 result = new EMData();
00112 result->set_size(nx, ny, nz);
00113 sigma_image = params.set_default("sigma", (EMData*)0);
00114 ignore0 = params["ignore0"];
00115
00116 nimg_n0 = new int[image_size];
00117 for (size_t i = 0; i < image_size; i++) {
00118 nimg_n0[i] = 0;
00119 }
00120 }
00121
00122 float *result_data = result->get_data();
00123 float *sigma_image_data = 0;
00124 if (sigma_image) {
00125 sigma_image->set_size(nx, ny, nz);
00126 sigma_image_data = sigma_image->get_data();
00127 }
00128
00129 float * image_data = image->get_data();
00130
00131 if (!ignore0) {
00132 for (size_t j = 0; j < image_size; j++) {
00133 float f = image_data[j];
00134 result_data[j] += f;
00135 if (sigma_image_data) {
00136 sigma_image_data[j] += f * f;
00137 }
00138 }
00139 }
00140 else {
00141 for (size_t j = 0; j < image_size; j++) {
00142 float f = image_data[j];
00143 if (f) {
00144 result_data[j] += f;
00145 if (sigma_image_data) {
00146 sigma_image_data[j] += f * f;
00147 }
00148 nimg_n0[j]++;
00149 }
00150 }
00151 }
00152 }
00153
00154 EMData * ImageAverager::finish()
00155 {
00156 if (result && nimg > 1) {
00157 size_t image_size = result->get_xsize() * result->get_ysize() * result->get_zsize();
00158 float * result_data = result->get_data();
00159
00160 if (!ignore0) {
00161 for (size_t j = 0; j < image_size; j++) {
00162 result_data[j] /= nimg;
00163 }
00164
00165 if (sigma_image) {
00166 float * sigma_image_data = sigma_image->get_data();
00167
00168 for (size_t j = 0; j < image_size; j++) {
00169 float f1 = sigma_image_data[j] / nimg;
00170 float f2 = result_data[j];
00171 sigma_image_data[j] = sqrt(f1 - f2 * f2);
00172 }
00173
00174 sigma_image->update();
00175 }
00176 }
00177 else {
00178 for (size_t j = 0; j < image_size; j++) {
00179 result_data[j] /= nimg_n0[j];
00180 }
00181 if (sigma_image) {
00182 float * sigma_image_data = sigma_image->get_data();
00183
00184 for (size_t j = 0; j < image_size; j++) {
00185 float f1 = sigma_image_data[j] / nimg_n0[j];
00186 float f2 = result_data[j];
00187 sigma_image_data[j] = sqrt(f1 - f2 * f2);
00188 }
00189
00190 sigma_image->update();
00191 }
00192 }
00193
00194 result->update();
00195 }
00196
00197 if( nimg_n0 )
00198 {
00199 delete [] nimg_n0;
00200 nimg_n0 = 0;
00201 }
00202
00203 return result;
00204 }
00205
00206 #if 0
00207 EMData *ImageAverager::average(const vector < EMData * >&image_list) const
00208 {
00209 if (image_list.size() == 0) {
00210 return 0;
00211 }
00212
00213 EMData *sigma_image = params["sigma"];
00214 int ignore0 = params["ignore0"];
00215
00216 EMData *image0 = image_list[0];
00217
00218 int nx = image0->get_xsize();
00219 int ny = image0->get_ysize();
00220 int nz = image0->get_zsize();
00221 size_t image_size = nx * ny * nz;
00222
00223 EMData *result = new EMData();
00224 result->set_size(nx, ny, nz);
00225
00226 float *result_data = result->get_data();
00227 float *sigma_image_data = 0;
00228
00229 if (sigma_image) {
00230 sigma_image->set_size(nx, ny, nz);
00231 sigma_image_data = sigma_image->get_data();
00232 }
00233
00234 int c = 1;
00235 if (ignore0) {
00236 for (size_t j = 0; j < image_size; j++) {
00237 int g = 0;
00238 for (size_t i = 0; i < image_list.size(); i++) {
00239 float f = image_list[i]->get_value_at(j);
00240 if (f) {
00241 g++;
00242 result_data[j] += f;
00243 if (sigma_image_data) {
00244 sigma_image_data[j] += f * f;
00245 }
00246 }
00247 }
00248 if (g) {
00249 result_data[j] /= g;
00250 }
00251 }
00252 }
00253 else {
00254 float *image0_data = image0->get_data();
00255 if (sigma_image_data) {
00256 memcpy(sigma_image_data, image0_data, image_size * sizeof(float));
00257
00258 for (size_t j = 0; j < image_size; j++) {
00259 sigma_image_data[j] *= sigma_image_data[j];
00260 }
00261 }
00262
00263 image0->update();
00264 memcpy(result_data, image0_data, image_size * sizeof(float));
00265
00266 for (size_t i = 1; i < image_list.size(); i++) {
00267 EMData *image = image_list[i];
00268
00269 if (EMUtil::is_same_size(image, result)) {
00270 float *image_data = image->get_data();
00271
00272 for (size_t j = 0; j < image_size; j++) {
00273 result_data[j] += image_data[j];
00274 }
00275
00276 if (sigma_image_data) {
00277 for (size_t j = 0; j < image_size; j++) {
00278 sigma_image_data[j] += image_data[j] * image_data[j];
00279 }
00280 }
00281
00282 image->update();
00283 c++;
00284 }
00285 }
00286
00287 for (size_t j = 0; j < image_size; j++) {
00288 result_data[j] /= static_cast < float >(c);
00289 }
00290 }
00291
00292 if (sigma_image_data) {
00293 for (size_t j = 0; j < image_size; j++) {
00294 float f1 = sigma_image_data[j] / c;
00295 float f2 = result_data[j];
00296 sigma_image_data[j] = sqrt(f1 - f2 * f2);
00297 }
00298 }
00299
00300 if (sigma_image_data) {
00301 sigma_image->update();
00302 }
00303
00304 result->update();
00305 return result;
00306 }
00307 #endif
00308
00309 MinMaxAverager::MinMaxAverager()
00310 : nimg(0)
00311 {
00312
00313
00314 max = 0;
00315 }
00316
00317 void MinMaxAverager::add_image(EMData * image)
00318 {
00319 if (!image) {
00320 return;
00321 }
00322
00323 if (nimg >= 1 && !EMUtil::is_same_size(image, result)) {
00324 LOGERR("%sAverager can only process same-size Image",
00325 get_name().c_str());
00326 return;
00327 }
00328
00329 nimg++;
00330
00331 int nx = image->get_xsize();
00332 int ny = image->get_ysize();
00333 int nz = image->get_zsize();
00334
00335 if (nimg == 1) {
00336 result = image->copy();
00337 max = params["max"];
00338 return;
00339 }
00340
00341 for (int z=0; z<nz; z++) {
00342 for (int y=0; y<ny; y++) {
00343 for (int x=0; x<nx; x++) {
00344 if (result->get_value_at(x,y,z)>image->get_value_at(x,y,z))
00345 { if (!max) result->set_value_at(x,y,z,image->get_value_at(x,y,z)); }
00346 else { if (max) result->set_value_at(x,y,z,image->get_value_at(x,y,z)); }
00347 }
00348 }
00349 }
00350
00351 }
00352
00353 EMData *MinMaxAverager::finish()
00354 {
00355 result->update();
00356 if (result && nimg > 1) return result;
00357
00358 return NULL;
00359 }
00360
00361
00362 IterationAverager::IterationAverager() : nimg(0)
00363 {
00364
00365 }
00366
00367 void IterationAverager::add_image( EMData * image)
00368 {
00369 if (!image) {
00370 return;
00371 }
00372
00373 if (nimg >= 1 && !EMUtil::is_same_size(image, result)) {
00374 LOGERR("%sAverager can only process same-size Image",
00375 get_name().c_str());
00376 return;
00377 }
00378
00379 nimg++;
00380
00381 int nx = image->get_xsize();
00382 int ny = image->get_ysize();
00383 int nz = image->get_zsize();
00384 size_t image_size = nx * ny * nz;
00385
00386 if (nimg == 1) {
00387 result = new EMData();
00388 result->set_size(nx, ny, nz);
00389 sigma_image = new EMData();
00390 sigma_image->set_size(nx, ny, nz);
00391 }
00392
00393 float *image_data = image->get_data();
00394 float *result_data = result->get_data();
00395 float *sigma_image_data = sigma_image->get_data();
00396
00397 for (size_t j = 0; j < image_size; j++) {
00398 float f = image_data[j];
00399 result_data[j] += f;
00400 sigma_image_data[j] += f * f;
00401 }
00402
00403
00404 }
00405
00406 EMData * IterationAverager::finish()
00407 {
00408 if (nimg < 1) {
00409 return result;
00410 }
00411
00412 int nx = result->get_xsize();
00413 int ny = result->get_ysize();
00414 int nz = result->get_zsize();
00415 size_t image_size = nx * ny * nz;
00416
00417 float *result_data = result->get_data();
00418 float *sigma_image_data = sigma_image->get_data();
00419
00420 for (size_t j = 0; j < image_size; j++) {
00421 result_data[j] /= nimg;
00422 float f1 = sigma_image_data[j] / nimg;
00423 float f2 = result_data[j];
00424 sigma_image_data[j] = sqrt(f1 - f2 * f2) / sqrt((float)nimg);
00425 }
00426
00427 result->update();
00428 sigma_image->update();
00429
00430 result->append_image("iter.hed");
00431 float sigma = sigma_image->get_attr("sigma");
00432 float *sigma_image_data2 = sigma_image->get_data();
00433 float *result_data2 = result->get_data();
00434 float *d2 = new float[nx * ny];
00435 size_t sec_size = nx * ny * sizeof(float);
00436
00437 memcpy(d2, result_data2, sec_size);
00438 memcpy(sigma_image_data2, result_data2, sec_size);
00439
00440 printf("Iter sigma=%f\n", sigma);
00441
00442 for (int k = 0; k < 1000; k++) {
00443 for (int i = 1; i < nx - 1; i++) {
00444 for (int j = 1; j < ny - 1; j++) {
00445 int l = i + j * nx;
00446 float c1 = (d2[l - 1] + d2[l + 1] + d2[l - nx] + d2[l + nx]) / 4.0f - d2[l];
00447 float c2 = fabs(result_data2[l] - sigma_image_data2[l]) / sigma;
00448 result_data2[l] += c1 * Util::eman_erfc(c2) / 100.0f;
00449 }
00450 }
00451
00452 memcpy(d2, result_data2, sec_size);
00453 }
00454
00455 if( d2 )
00456 {
00457 delete[]d2;
00458 d2 = 0;
00459 }
00460
00461 sigma_image->update();
00462 if( sigma_image )
00463 {
00464 delete sigma_image;
00465 sigma_image = 0;
00466 }
00467
00468 result->update();
00469 result->append_image("iter.hed");
00470
00471
00472 return result;
00473 }
00474
00475 CtfCWautoAverager::CtfCWautoAverager()
00476 : nimg(0)
00477 {
00478
00479 }
00480
00481
00482 void CtfCWautoAverager::add_image(EMData * image)
00483 {
00484 if (!image) {
00485 return;
00486 }
00487
00488
00489
00490 EMData *fft=image->do_fft();
00491
00492 if (nimg >= 1 && !EMUtil::is_same_size(fft, result)) {
00493 LOGERR("%s Averager can only process images of the same size", get_name().c_str());
00494 return;
00495 }
00496
00497 nimg++;
00498 if (nimg == 1) {
00499 result = fft->copy_head();
00500 result->to_zero();
00501 }
00502
00503 Ctf *ctf = (Ctf *)image->get_attr("ctf");
00504 float b=ctf->bfactor;
00505 ctf->bfactor=100.0;
00506
00507 EMData *snr = result -> copy();
00508 ctf->compute_2d_complex(snr,Ctf::CTF_SNR);
00509 EMData *ctfi = result-> copy();
00510 ctf->compute_2d_complex(ctfi,Ctf::CTF_AMP);
00511
00512 ctf->bfactor=b;
00513
00514 float *outd = result->get_data();
00515 float *ind = fft->get_data();
00516 float *snrd = snr->get_data();
00517 float *ctfd = ctfi->get_data();
00518
00519 size_t sz=snr->get_xsize()*snr->get_ysize();
00520 for (size_t i = 0; i < sz; i+=2) {
00521 if (snrd[i]<0) snrd[i]=0;
00522 ctfd[i]=fabs(ctfd[i]);
00523 if (ctfd[i]<.05) {
00524 if (snrd[i]<=0) ctfd[i]=.05f;
00525 else ctfd[i]=snrd[i]*10.0f;
00526 }
00527 outd[i]+=ind[i]*snrd[i]/ctfd[i];
00528 outd[i+1]+=ind[i+1]*snrd[i]/ctfd[i];
00529 }
00530
00531 if (nimg==1) {
00532 snrsum=snr->copy_head();
00533 float *ssnrd=snrsum->get_data();
00534
00535 for (size_t i = 0; i < sz; i+=2) { ssnrd[i]=1.0; ssnrd[i+1]=0.0; }
00536 }
00537 snrsum->add(*snr);
00538
00539 delete ctf;
00540 delete fft;
00541 delete snr;
00542 delete ctfi;
00543 }
00544
00545 EMData * CtfCWautoAverager::finish()
00546 {
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 size_t sz=result->get_xsize()*result->get_ysize();
00557 float *snrsd=snrsum->get_data();
00558 float *outd=result->get_data();
00559
00560 for (size_t i=0; i<sz; i+=2) {
00561 outd[i]/=snrsd[i];
00562 outd[i+1]/=snrsd[i];
00563 }
00564 result->update();
00565 result->set_attr("ptcl_repr",nimg);
00566 result->set_attr("ctf_snr_total",snrsum->calc_radial_dist(snrsum->get_ysize()/2,0,1,false));
00567 result->set_attr("ctf_wiener_filtered",1);
00568
00569 delete snrsum;
00570 EMData *ret=result->do_ift();
00571 delete result;
00572 result=NULL;
00573 return ret;
00574 }
00575
00576 CtfCAutoAverager::CtfCAutoAverager()
00577 : nimg(0)
00578 {
00579
00580 }
00581
00582
00583 void CtfCAutoAverager::add_image(EMData * image)
00584 {
00585 if (!image) {
00586 return;
00587 }
00588
00589
00590
00591 EMData *fft=image->do_fft();
00592
00593 if (nimg >= 1 && !EMUtil::is_same_size(fft, result)) {
00594 LOGERR("%s Averager can only process images of the same size", get_name().c_str());
00595 return;
00596 }
00597
00598 nimg++;
00599 if (nimg == 1) {
00600 result = fft->copy_head();
00601 result->to_zero();
00602 }
00603
00604 Ctf *ctf = (Ctf *)image->get_attr("ctf");
00605 float b=ctf->bfactor;
00606 ctf->bfactor=0;
00607
00608 EMData *snr = result -> copy();
00609 ctf->compute_2d_complex(snr,Ctf::CTF_SNR);
00610 EMData *ctfi = result-> copy();
00611 ctf->compute_2d_complex(ctfi,Ctf::CTF_AMP);
00612
00613 ctf->bfactor=b;
00614
00615 float *outd = result->get_data();
00616 float *ind = fft->get_data();
00617 float *snrd = snr->get_data();
00618 float *ctfd = ctfi->get_data();
00619
00620 size_t sz=snr->get_xsize()*snr->get_ysize();
00621 for (size_t i = 0; i < sz; i+=2) {
00622 if (snrd[i]<0) snrd[i]=0;
00623 ctfd[i]=fabs(ctfd[i]);
00624
00625
00626 if (ctfd[i]<.05) {
00627 if (snrd[i]<=0) ctfd[i]=.05f;
00628 else ctfd[i]=snrd[i]*10.0f;
00629 }
00630
00631
00632 outd[i]+=ind[i]*snrd[i]/ctfd[i];
00633 outd[i+1]+=ind[i+1]*snrd[i]/ctfd[i];
00634 }
00635
00636 if (nimg==1) {
00637 snrsum=snr->copy_head();
00638 float *ssnrd=snrsum->get_data();
00639
00640 for (size_t i = 0; i < sz; i+=2) { ssnrd[i]=0.0; ssnrd[i+1]=0.0; }
00641 }
00642 snrsum->add(*snr);
00643
00644 delete ctf;
00645 delete fft;
00646 delete snr;
00647 delete ctfi;
00648 }
00649
00650 EMData * CtfCAutoAverager::finish()
00651 {
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661 size_t sz=result->get_xsize()*result->get_ysize();
00662 float *snrsd=snrsum->get_data();
00663 float *outd=result->get_data();
00664
00665 for (size_t i=0; i<sz; i+=2) {
00666 if (snrsd[i]==0) outd[i]=outd[i+1]=0;
00667
00668 if (snrsd[i]<.05) {
00669 outd[i]*=20.0;
00670 outd[i+1]*=20.0;
00671 }
00672 else {
00673 outd[i]/=snrsd[i];
00674 outd[i+1]/=snrsd[i];
00675 }
00676 }
00677 result->update();
00678 result->set_attr("ptcl_repr",nimg);
00679 result->set_attr("ctf_snr_total",snrsum->calc_radial_dist(snrsum->get_ysize()/2,0,1,false));
00680 result->set_attr("ctf_wiener_filtered",0);
00681
00682
00683
00684
00685 delete snrsum;
00686 EMData *ret=result->do_ift();
00687 delete result;
00688 result=NULL;
00689 return ret;
00690 }
00691
00692 #if 0
00693 EMData *IterationAverager::average(const vector < EMData * >&image_list) const
00694 {
00695 if (image_list.size() == 0) {
00696 return 0;
00697 }
00698
00699 EMData *image0 = image_list[0];
00700
00701 int nx = image0->get_xsize();
00702 int ny = image0->get_ysize();
00703 int nz = image0->get_zsize();
00704 size_t image_size = nx * ny * nz;
00705
00706 EMData *result = new EMData();
00707 result->set_size(nx, ny, nz);
00708
00709 EMData *sigma_image = new EMData();
00710 sigma_image->set_size(nx, ny, nz);
00711
00712 float *image0_data = image0->get_data();
00713 float *result_data = result->get_data();
00714 float *sigma_image_data = sigma_image->get_data();
00715
00716 memcpy(result_data, image0_data, image_size * sizeof(float));
00717 memcpy(sigma_image_data, image0_data, image_size * sizeof(float));
00718
00719 for (size_t j = 0; j < image_size; j++) {
00720 sigma_image_data[j] *= sigma_image_data[j];
00721 }
00722
00723 image0->update();
00724
00725 int nc = 1;
00726 for (size_t i = 1; i < image_list.size(); i++) {
00727 EMData *image = image_list[i];
00728
00729 if (EMUtil::is_same_size(image, result)) {
00730 float *image_data = image->get_data();
00731
00732 for (size_t j = 0; j < image_size; j++) {
00733 result_data[j] += image_data[j];
00734 sigma_image_data[j] += image_data[j] * image_data[j];
00735 }
00736
00737 image->update();
00738 nc++;
00739 }
00740 }
00741
00742 float c = static_cast < float >(nc);
00743 for (size_t j = 0; j < image_size; j++) {
00744 float f1 = sigma_image_data[j] / c;
00745 float f2 = result_data[j] / c;
00746 sigma_image_data[j] = sqrt(f1 - f2 * f2) / sqrt(c);
00747 }
00748
00749
00750 for (size_t j = 0; j < image_size; j++) {
00751 result_data[j] /= c;
00752 }
00753
00754 result->update();
00755 sigma_image->update();
00756
00757 result->append_image("iter.hed");
00758
00759 float sigma = sigma_image->get_attr("sigma");
00760 float *sigma_image_data2 = sigma_image->get_data();
00761 float *result_data2 = result->get_data();
00762 float *d2 = new float[nx * ny];
00763 size_t sec_size = nx * ny * sizeof(float);
00764
00765 memcpy(d2, result_data2, sec_size);
00766 memcpy(sigma_image_data2, result_data2, sec_size);
00767
00768 printf("Iter sigma=%f\n", sigma);
00769
00770 for (int k = 0; k < 1000; k++) {
00771 for (int i = 1; i < nx - 1; i++) {
00772 for (int j = 1; j < ny - 1; j++) {
00773 int l = i + j * nx;
00774 float c1 = (d2[l - 1] + d2[l + 1] + d2[l - nx] + d2[l + nx]) / 4.0f - d2[l];
00775 float c2 = fabs(result_data2[l] - sigma_image_data2[l]) / sigma;
00776 result_data2[l] += c1 * Util::eman_erfc(c2) / 100.0f;
00777 }
00778 }
00779
00780 memcpy(d2, result_data2, sec_size);
00781 }
00782
00783 if( d2 )
00784 {
00785 delete[]d2;
00786 d2 = 0;
00787 }
00788
00789 sigma_image->update();
00790 if( sigma_image )
00791 {
00792 delete sigma_image;
00793 sigma_image = 0;
00794 }
00795
00796 result->update();
00797 result->append_image("iter.hed");
00798
00799 return result;
00800 }
00801 #endif
00802
00803
00804 CtfAverager::CtfAverager() :
00805 sf(0), curves(0), need_snr(false), outfile(0),
00806 image0_fft(0), image0_copy(0), snri(0), snrn(0),
00807 tdr(0), tdi(0), tn(0),
00808 filter(0), nimg(0), nx(0), ny(0), nz(0)
00809 {
00810
00811 }
00812
00813 void CtfAverager::add_image(EMData * image)
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 }
00980
00981 EMData * CtfAverager::finish()
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 }
01128
01129 #if 0
01130 EMData *CtfAverager::average(const vector < EMData * >&image_list) const
01131 {
01132 if (image_list.size() == 0) {
01133 return 0;
01134 }
01135
01136 EMData *image0 = image_list[0];
01137 if (image0->get_zsize() != 1) {
01138 LOGERR("Only 2D images are currently supported");
01139 return 0;
01140 }
01141
01142 string alg_name = get_name();
01143
01144 if (alg_name == "CtfCW" || alg_name == "CtfCWauto") {
01145 if (image0->get_ctf() != 0 && !image0->has_ctff()) {
01146 LOGERR("Attempted CTF Correction with no ctf parameters");
01147 return 0;
01148 }
01149 }
01150 else {
01151 if (image0->get_ctf() != 0) {
01152 LOGERR("Attempted CTF Correction with no ctf parameters");
01153 return 0;
01154 }
01155 }
01156
01157 size_t num_images = image_list.size();
01158 vector < float >*ctf = new vector < float >[num_images];
01159 vector < float >*ctfn = new vector < float >[num_images];
01160 float **src = new float *[num_images];
01161
01162 Ctf::CtfType curve_type = Ctf::CTF_ABS_AMP;
01163 if (alg_name == "CtfCWauto") {
01164 curve_type = Ctf::CTF_AMP;
01165 }
01166
01167 for (size_t i = 0; i < num_images; i++) {
01168 EMData *image = image_list[i]->do_fft();
01169 image->ap2ri();
01170 src[i] = image->get_data();
01171 Ctf *image_ctf = image->get_ctf();
01172 int ny = image->get_ysize();
01173 ctf[i] = image_ctf->compute_1d(ny, curve_type);
01174
01175 if (ctf[i].size() == 0) {
01176 LOGERR("Unexpected CTF correction problem");
01177 return 0;
01178 }
01179
01180 if (sf) {
01181 ctfn[i] = image_ctf->compute_1d(ny, Ctf::CTF_ABS_SNR, sf);
01182 }
01183 else {
01184 ctfn[i] = image_ctf->compute_1d(ny, Ctf::CTF_RELATIVE_SNR);
01185 }
01186
01187 if(image_ctf) {delete image_ctf; image_ctf=0;}
01188 }
01189
01190 EMData *image0_fft = image0->do_fft();
01191
01192 int nx = image0_fft->get_xsize();
01193 int ny = image0_fft->get_ysize();
01194 int nz = image0_fft->get_zsize();
01195
01196 EMData *result = new EMData();
01197 result->set_size(nx - 2, ny, nz);
01198
01199 float *cd = 0;
01200 if (alg_name == "Weighting" && curves) {
01201 if (!sf) {
01202 LOGWARN("CTF curve in file will contain relative, not absolute SNR!");
01203 }
01204 curves->set_size(Ctf::CTFOS * ny / 2, 3, 1);
01205 curves->to_zero();
01206 cd = curves->get_data();
01207 }
01208
01209 float filter = 0;
01210 if (alg_name == "CtfC") {
01211 filter = params["filter"];
01212 if (filter == 0) {
01213 filter = 22.0f;
01214 }
01215 float apix_y = image0->get_attr_dict().get("apix_y");
01216 float ds = 1.0f / (apix_y * ny * Ctf::CTFOS);
01217 filter = 1.0f / (filter * ds);
01218 }
01219
01220 float *snri = 0;
01221 float *snrn = 0;
01222
01223 if (alg_name == "CtfCWauto") {
01224 snri = new float[ny / 2];
01225 snrn = new float[ny / 2];
01226
01227 for (int i = 0; i < ny / 2; i++) {
01228 snri[i] = 0;
01229 snrn[i] = 0;
01230 }
01231
01232 int j = 0;
01233 for (int y = 0; y < ny; y++) {
01234 for (int x = 0; x < nx / 2; x++, j += 2) {
01235 float r = hypot(x, y - ny / 2.0f);
01236 int l = static_cast < int >(Util::fast_floor(r));
01237
01238 if (l >= 0 && l < ny / 2) {
01239 float tdr = 1;
01240 float tdi = 1;
01241 float tn = 1;
01242
01243 for (size_t i = 0; i < num_images; i++) {
01244 tdr *= src[i][j];
01245 tdi *= src[i][j + 1];
01246 tn *= hypot(src[i][j], src[i][j + 1]);
01247 }
01248
01249 tdr += tdi / tn;
01250 snri[l] += tdr;
01251 snrn[l] += 1;
01252 }
01253 }
01254 }
01255
01256 for (int i = 0; i < ny / 2; i++) {
01257 snri[i] *= num_images / snrn[i];
01258 }
01259 if (outfile != "") {
01260 Util::save_data(0, 1, snri, ny / 2, outfile);
01261 }
01262 }
01263
01264 for (int i = 0; i < Ctf::CTFOS * ny / 2; i++) {
01265 float ctf0 = 0;
01266 for (size_t j = 0; j < num_images; j++) {
01267 ctf0 += ctfn[j][i];
01268 if (ctf[j][i] == 0) {
01269 ctf[j][i] = 1.0e-12;
01270 }
01271
01272 if (curves) {
01273 cd[i] += ctf[j][i] * ctfn[j][i];
01274 cd[i + Ctf::CTFOS * ny / 2] += ctfn[j][i];
01275 cd[i + 2 * Ctf::CTFOS * ny / 2] += ctfn[j][i];
01276 }
01277 }
01278
01279 if (alg_name == "CtfCW" && need_snr) {
01280 snr[i] = ctf0;
01281 }
01282
01283 float ctf1 = ctf0;
01284 if (alg_name == "CtfCWauto") {
01285 ctf1 = snri[i / Ctf::CTFOS];
01286 }
01287
01288 if (ctf1 <= 0.0001f) {
01289 ctf1 = 0.1f;
01290 }
01291
01292 if (alg_name == "CtfC") {
01293 for (size_t j = 0; j < num_images; j++) {
01294 ctf[j][i] = exp(-i * i / (filter * filter)) * ctfn[j][i] / (fabs(ctf[j][i]) * ctf1);
01295 }
01296 }
01297 else if (alg_name == "Weighting") {
01298 for (size_t j = 0; j < num_images; j++) {
01299 ctf[j][i] = ctfn[j][i] / ctf1;
01300 }
01301 }
01302 else if (alg_name == "CtfCW") {
01303 for (size_t j = 0; j < num_images; j++) {
01304 ctf[j][i] = (ctf1 / (ctf1 + 1)) * ctfn[j][i] / (ctf[j][i] * ctf1);
01305 }
01306 }
01307 else if (alg_name == "CtfCWauto") {
01308 for (size_t j = 0; j < num_images; j++) {
01309 ctf[j][i] = ctf1 * ctfn[j][i] / (fabs(ctf[j][i]) * ctf0);
01310 }
01311 }
01312 }
01313
01314
01315 if (curves) {
01316 for (int i = 0; i < Ctf::CTFOS * ny / 2; i++) {
01317 cd[i] /= cd[i + Ctf::CTFOS * ny / 2];
01318 }
01319 curves->update();
01320 }
01321
01322 EMData *image0_copy = image0_fft->copy_head();
01323 image0_copy->ap2ri();
01324
01325 float *tmp_data = image0_copy->get_data();
01326
01327 int j = 0;
01328 for (int y = 0; y < ny; y++) {
01329 for (int x = 0; x < nx / 2; x++, j += 2) {
01330 float r = Ctf::CTFOS * sqrt(x * x + (y - ny / 2.0f) * (y - ny / 2.0f));
01331 int l = static_cast < int >(Util::fast_floor(r));
01332 r -= l;
01333
01334 tmp_data[j] = 0;
01335 tmp_data[j + 1] = 0;
01336
01337 for (size_t i = 0; i < num_images; i++) {
01338 float f = 0;
01339 if (l <= Ctf::CTFOS * ny / 2 - 2) {
01340 f = (ctf[i][l] * (1 - r) + ctf[i][l + 1] * r);
01341 }
01342 tmp_data[j] += src[i][j] * f;
01343 tmp_data[j + 1] += src[i][j + 1] * f;
01344 }
01345 }
01346 }
01347
01348 image0_copy->update();
01349
01350 float *result_data = result->get_data();
01351 EMData *tmp_ift = image0_copy->do_ift();
01352 float *tmp_ift_data = tmp_ift->get_data();
01353 memcpy(result_data, tmp_ift_data, (nx - 2) * ny * sizeof(float));
01354
01355 tmp_ift->update();
01356
01357 if( image0_copy )
01358 {
01359 delete image0_copy;
01360 image0_copy = 0;
01361 }
01362
01363 for (size_t i = 0; i < num_images; i++) {
01364 EMData *img = image_list[i]->do_fft();
01365 img->update();
01366 }
01367
01368 if( src )
01369 {
01370 delete[]src;
01371 src = 0;
01372 }
01373
01374 if( ctf )
01375 {
01376 delete[]ctf;
01377 ctf = 0;
01378 }
01379
01380 if( ctfn )
01381 {
01382 delete[]ctfn;
01383 ctfn = 0;
01384 }
01385
01386 if (snri) {
01387 delete[]snri;
01388 snri = 0;
01389 }
01390
01391 if (snrn) {
01392 delete[]snrn;
01393 snrn = 0;
01394 }
01395
01396 result->update();
01397 return result;
01398 }
01399 #endif
01400
01401
01402 void EMAN::dump_averagers()
01403 {
01404 dump_factory < Averager > ();
01405 }
01406
01407 map<string, vector<string> > EMAN::dump_averagers_list()
01408 {
01409 return dump_factory_list < Averager > ();
01410 }