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 result->set_attr("ptcl_repr",nimg);
00198
00199 if( nimg_n0 )
00200 {
00201 delete [] nimg_n0;
00202 nimg_n0 = 0;
00203 }
00204
00205 return result;
00206 }
00207
00208 #if 0
00209 EMData *ImageAverager::average(const vector < EMData * >&image_list) const
00210 {
00211 if (image_list.size() == 0) {
00212 return 0;
00213 }
00214
00215 EMData *sigma_image = params["sigma"];
00216 int ignore0 = params["ignore0"];
00217
00218 EMData *image0 = image_list[0];
00219
00220 int nx = image0->get_xsize();
00221 int ny = image0->get_ysize();
00222 int nz = image0->get_zsize();
00223 size_t image_size = nx * ny * nz;
00224
00225 EMData *result = new EMData();
00226 result->set_size(nx, ny, nz);
00227
00228 float *result_data = result->get_data();
00229 float *sigma_image_data = 0;
00230
00231 if (sigma_image) {
00232 sigma_image->set_size(nx, ny, nz);
00233 sigma_image_data = sigma_image->get_data();
00234 }
00235
00236 int c = 1;
00237 if (ignore0) {
00238 for (size_t j = 0; j < image_size; j++) {
00239 int g = 0;
00240 for (size_t i = 0; i < image_list.size(); i++) {
00241 float f = image_list[i]->get_value_at(j);
00242 if (f) {
00243 g++;
00244 result_data[j] += f;
00245 if (sigma_image_data) {
00246 sigma_image_data[j] += f * f;
00247 }
00248 }
00249 }
00250 if (g) {
00251 result_data[j] /= g;
00252 }
00253 }
00254 }
00255 else {
00256 float *image0_data = image0->get_data();
00257 if (sigma_image_data) {
00258 memcpy(sigma_image_data, image0_data, image_size * sizeof(float));
00259
00260 for (size_t j = 0; j < image_size; j++) {
00261 sigma_image_data[j] *= sigma_image_data[j];
00262 }
00263 }
00264
00265 image0->update();
00266 memcpy(result_data, image0_data, image_size * sizeof(float));
00267
00268 for (size_t i = 1; i < image_list.size(); i++) {
00269 EMData *image = image_list[i];
00270
00271 if (EMUtil::is_same_size(image, result)) {
00272 float *image_data = image->get_data();
00273
00274 for (size_t j = 0; j < image_size; j++) {
00275 result_data[j] += image_data[j];
00276 }
00277
00278 if (sigma_image_data) {
00279 for (size_t j = 0; j < image_size; j++) {
00280 sigma_image_data[j] += image_data[j] * image_data[j];
00281 }
00282 }
00283
00284 image->update();
00285 c++;
00286 }
00287 }
00288
00289 for (size_t j = 0; j < image_size; j++) {
00290 result_data[j] /= static_cast < float >(c);
00291 }
00292 }
00293
00294 if (sigma_image_data) {
00295 for (size_t j = 0; j < image_size; j++) {
00296 float f1 = sigma_image_data[j] / c;
00297 float f2 = result_data[j];
00298 sigma_image_data[j] = sqrt(f1 - f2 * f2);
00299 }
00300 }
00301
00302 if (sigma_image_data) {
00303 sigma_image->update();
00304 }
00305
00306 result->update();
00307 return result;
00308 }
00309 #endif
00310
00311 MinMaxAverager::MinMaxAverager()
00312 : nimg(0)
00313 {
00314
00315
00316 max = 0;
00317 }
00318
00319 void MinMaxAverager::add_image(EMData * image)
00320 {
00321 if (!image) {
00322 return;
00323 }
00324
00325 if (nimg >= 1 && !EMUtil::is_same_size(image, result)) {
00326 LOGERR("%sAverager can only process same-size Image",
00327 get_name().c_str());
00328 return;
00329 }
00330
00331 nimg++;
00332
00333 int nx = image->get_xsize();
00334 int ny = image->get_ysize();
00335 int nz = image->get_zsize();
00336
00337 if (nimg == 1) {
00338 result = image->copy();
00339 max = params["max"];
00340 return;
00341 }
00342
00343 for (int z=0; z<nz; z++) {
00344 for (int y=0; y<ny; y++) {
00345 for (int x=0; x<nx; x++) {
00346 if (result->get_value_at(x,y,z)>image->get_value_at(x,y,z))
00347 { if (!max) result->set_value_at(x,y,z,image->get_value_at(x,y,z)); }
00348 else { if (max) result->set_value_at(x,y,z,image->get_value_at(x,y,z)); }
00349 }
00350 }
00351 }
00352
00353 }
00354
00355 EMData *MinMaxAverager::finish()
00356 {
00357 result->update();
00358 result->set_attr("ptcl_repr",nimg);
00359
00360 if (result && nimg > 1) return result;
00361
00362 return NULL;
00363 }
00364
00365
00366 IterationAverager::IterationAverager() : nimg(0)
00367 {
00368
00369 }
00370
00371 void IterationAverager::add_image( EMData * image)
00372 {
00373 if (!image) {
00374 return;
00375 }
00376
00377 if (nimg >= 1 && !EMUtil::is_same_size(image, result)) {
00378 LOGERR("%sAverager can only process same-size Image",
00379 get_name().c_str());
00380 return;
00381 }
00382
00383 nimg++;
00384
00385 int nx = image->get_xsize();
00386 int ny = image->get_ysize();
00387 int nz = image->get_zsize();
00388 size_t image_size = nx * ny * nz;
00389
00390 if (nimg == 1) {
00391 result = new EMData();
00392 result->set_size(nx, ny, nz);
00393 sigma_image = new EMData();
00394 sigma_image->set_size(nx, ny, nz);
00395 }
00396
00397 float *image_data = image->get_data();
00398 float *result_data = result->get_data();
00399 float *sigma_image_data = sigma_image->get_data();
00400
00401 for (size_t j = 0; j < image_size; j++) {
00402 float f = image_data[j];
00403 result_data[j] += f;
00404 sigma_image_data[j] += f * f;
00405 }
00406
00407
00408 }
00409
00410 EMData * IterationAverager::finish()
00411 {
00412 if (nimg < 1) {
00413 return result;
00414 }
00415
00416 int nx = result->get_xsize();
00417 int ny = result->get_ysize();
00418 int nz = result->get_zsize();
00419 size_t image_size = nx * ny * nz;
00420
00421 float *result_data = result->get_data();
00422 float *sigma_image_data = sigma_image->get_data();
00423
00424 for (size_t j = 0; j < image_size; j++) {
00425 result_data[j] /= nimg;
00426 float f1 = sigma_image_data[j] / nimg;
00427 float f2 = result_data[j];
00428 sigma_image_data[j] = sqrt(f1 - f2 * f2) / sqrt((float)nimg);
00429 }
00430
00431 result->update();
00432 sigma_image->update();
00433
00434 result->append_image("iter.hed");
00435 float sigma = sigma_image->get_attr("sigma");
00436 float *sigma_image_data2 = sigma_image->get_data();
00437 float *result_data2 = result->get_data();
00438 float *d2 = new float[nx * ny];
00439 size_t sec_size = nx * ny * sizeof(float);
00440
00441 memcpy(d2, result_data2, sec_size);
00442 memcpy(sigma_image_data2, result_data2, sec_size);
00443
00444 printf("Iter sigma=%f\n", sigma);
00445
00446 for (int k = 0; k < 1000; k++) {
00447 for (int i = 1; i < nx - 1; i++) {
00448 for (int j = 1; j < ny - 1; j++) {
00449 int l = i + j * nx;
00450 float c1 = (d2[l - 1] + d2[l + 1] + d2[l - nx] + d2[l + nx]) / 4.0f - d2[l];
00451 float c2 = fabs(result_data2[l] - sigma_image_data2[l]) / sigma;
00452 result_data2[l] += c1 * Util::eman_erfc(c2) / 100.0f;
00453 }
00454 }
00455
00456 memcpy(d2, result_data2, sec_size);
00457 }
00458
00459 if( d2 )
00460 {
00461 delete[]d2;
00462 d2 = 0;
00463 }
00464
00465 sigma_image->update();
00466 if( sigma_image )
00467 {
00468 delete sigma_image;
00469 sigma_image = 0;
00470 }
00471
00472 result->update();
00473 result->append_image("iter.hed");
00474
00475
00476 return result;
00477 }
00478
00479 CtfCWautoAverager::CtfCWautoAverager()
00480 : nimg(0)
00481 {
00482
00483 }
00484
00485
00486 void CtfCWautoAverager::add_image(EMData * image)
00487 {
00488 if (!image) {
00489 return;
00490 }
00491
00492
00493
00494 EMData *fft=image->do_fft();
00495
00496 if (nimg >= 1 && !EMUtil::is_same_size(fft, result)) {
00497 LOGERR("%s Averager can only process images of the same size", get_name().c_str());
00498 return;
00499 }
00500
00501 nimg++;
00502 if (nimg == 1) {
00503 result = fft->copy_head();
00504 result->to_zero();
00505 }
00506
00507 Ctf *ctf = (Ctf *)image->get_attr("ctf");
00508
00509
00510
00511
00512 float b=ctf->bfactor;
00513 ctf->bfactor=100.0;
00514
00515
00516
00517 EMData *snr = result -> copy();
00518 ctf->compute_2d_complex(snr,Ctf::CTF_SNR);
00519
00520 EMData *ctfi = result-> copy();
00521 ctf->compute_2d_complex(ctfi,Ctf::CTF_AMP);
00522
00523 ctf->bfactor=b;
00524
00525 float *outd = result->get_data();
00526 float *ind = fft->get_data();
00527 float *snrd = snr->get_data();
00528 float *ctfd = ctfi->get_data();
00529
00530 size_t sz=snr->get_xsize()*snr->get_ysize();
00531 for (size_t i = 0; i < sz; i+=2) {
00532 if (snrd[i]<0) snrd[i]=0;
00533 ctfd[i]=fabs(ctfd[i]);
00534 if (ctfd[i]<.05) ctfd[i]=0.05f;
00535
00536
00537
00538
00539 outd[i]+=ind[i]*snrd[i]/ctfd[i];
00540 outd[i+1]+=ind[i+1]*snrd[i]/ctfd[i];
00541 }
00542
00543 if (nimg==1) {
00544 snrsum=snr->copy_head();
00545 float *ssnrd=snrsum->get_data();
00546
00547 for (size_t i = 0; i < sz; i+=2) { ssnrd[i]=1.0; ssnrd[i+1]=0.0; }
00548 }
00549
00550 snr->process_inplace("math.absvalue");
00551 snrsum->add(*snr);
00552
00553 delete ctf;
00554 delete fft;
00555 delete snr;
00556 delete ctfi;
00557 }
00558
00559 EMData * CtfCWautoAverager::finish()
00560 {
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 int nx=result->get_xsize();
00572 int ny=result->get_ysize();
00573 float *snrsd=snrsum->get_data();
00574 float *outd=result->get_data();
00575
00576 int rm=(ny-2)*(ny-2)/4;
00577 for (int j=0; j<ny; j++) {
00578 for (int i=0; i<nx; i+=2) {
00579 size_t ii=i+j*nx;
00580 if ((j<ny/2 && i*i/4+j*j>rm) ||(j>=ny/2 && i*i/4+(ny-j)*(ny-j)>rm) || snrsd[ii]==0) { outd[ii]=outd[ii+1]=0; continue; }
00581 outd[ii]/=snrsd[ii];
00582 outd[ii+1]/=snrsd[ii];
00583 }
00584 }
00585
00586 result->update();
00587 result->set_attr("ptcl_repr",nimg);
00588 result->set_attr("ctf_snr_total",snrsum->calc_radial_dist(snrsum->get_ysize()/2,0,1,false));
00589 result->set_attr("ctf_wiener_filtered",1);
00590
00591 delete snrsum;
00592 EMData *ret=result->do_ift();
00593 delete result;
00594 result=NULL;
00595 return ret;
00596 }
00597
00598 CtfCAutoAverager::CtfCAutoAverager()
00599 : nimg(0)
00600 {
00601
00602 }
00603
00604
00605 void CtfCAutoAverager::add_image(EMData * image)
00606 {
00607 if (!image) {
00608 return;
00609 }
00610
00611
00612
00613 EMData *fft=image->do_fft();
00614
00615 if (nimg >= 1 && !EMUtil::is_same_size(fft, result)) {
00616 LOGERR("%s Averager can only process images of the same size", get_name().c_str());
00617 return;
00618 }
00619
00620 nimg++;
00621 if (nimg == 1) {
00622 result = fft->copy_head();
00623 result->to_zero();
00624 }
00625
00626 Ctf *ctf = (Ctf *)image->get_attr("ctf");
00627 float b=ctf->bfactor;
00628 ctf->bfactor=0;
00629
00630 EMData *snr = result -> copy();
00631 ctf->compute_2d_complex(snr,Ctf::CTF_SNR);
00632 EMData *ctfi = result-> copy();
00633 ctf->compute_2d_complex(ctfi,Ctf::CTF_AMP);
00634
00635 ctf->bfactor=b;
00636
00637 float *outd = result->get_data();
00638 float *ind = fft->get_data();
00639 float *snrd = snr->get_data();
00640 float *ctfd = ctfi->get_data();
00641
00642 size_t sz=snr->get_xsize()*snr->get_ysize();
00643 for (size_t i = 0; i < sz; i+=2) {
00644 if (snrd[i]<0) snrd[i]=0;
00645 ctfd[i]=fabs(ctfd[i]);
00646
00647
00648 if (ctfd[i]<.05) ctfd[i]=0.05f;
00649
00650
00651
00652
00653
00654
00655 outd[i]+=ind[i]*snrd[i]/ctfd[i];
00656 outd[i+1]+=ind[i+1]*snrd[i]/ctfd[i];
00657 }
00658
00659 if (nimg==1) {
00660 snrsum=snr->copy_head();
00661 float *ssnrd=snrsum->get_data();
00662
00663 for (size_t i = 0; i < sz; i+=2) { ssnrd[i]=0.0; ssnrd[i+1]=0.0; }
00664 }
00665 snr->process_inplace("math.absvalue");
00666 snrsum->add(*snr);
00667
00668 delete ctf;
00669 delete fft;
00670 delete snr;
00671 delete ctfi;
00672 }
00673
00674 EMData * CtfCAutoAverager::finish()
00675 {
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686 int nx=result->get_xsize();
00687 int ny=result->get_ysize();
00688 float *snrsd=snrsum->get_data();
00689 float *outd=result->get_data();
00690
00691 int rm=(ny-2)*(ny-2)/4;
00692 for (int j=0; j<ny; j++) {
00693 for (int i=0; i<nx; i+=2) {
00694 size_t ii=i+j*nx;
00695 if ((j<ny/2 && i*i/4+j*j>rm) ||(j>=ny/2 && i*i/4+(ny-j)*(ny-j)>rm) || snrsd[ii]==0) { outd[ii]=outd[ii+1]=0; continue; }
00696
00697 if (snrsd[ii]<.05) {
00698 outd[ii]*=20.0;
00699 outd[ii+1]*=20.0;
00700 }
00701 else {
00702 outd[ii]/=snrsd[ii];
00703 outd[ii+1]/=snrsd[ii];
00704 }
00705 }
00706 }
00707 result->update();
00708 result->set_attr("ptcl_repr",nimg);
00709 result->set_attr("ctf_snr_total",snrsum->calc_radial_dist(snrsum->get_ysize()/2,0,1,false));
00710 result->set_attr("ctf_wiener_filtered",0);
00711
00712
00713
00714
00715 delete snrsum;
00716 EMData *ret=result->do_ift();
00717 delete result;
00718 result=NULL;
00719 return ret;
00720 }
00721
00722 #if 0
00723 EMData *IterationAverager::average(const vector < EMData * >&image_list) const
00724 {
00725 if (image_list.size() == 0) {
00726 return 0;
00727 }
00728
00729 EMData *image0 = image_list[0];
00730
00731 int nx = image0->get_xsize();
00732 int ny = image0->get_ysize();
00733 int nz = image0->get_zsize();
00734 size_t image_size = nx * ny * nz;
00735
00736 EMData *result = new EMData();
00737 result->set_size(nx, ny, nz);
00738
00739 EMData *sigma_image = new EMData();
00740 sigma_image->set_size(nx, ny, nz);
00741
00742 float *image0_data = image0->get_data();
00743 float *result_data = result->get_data();
00744 float *sigma_image_data = sigma_image->get_data();
00745
00746 memcpy(result_data, image0_data, image_size * sizeof(float));
00747 memcpy(sigma_image_data, image0_data, image_size * sizeof(float));
00748
00749 for (size_t j = 0; j < image_size; j++) {
00750 sigma_image_data[j] *= sigma_image_data[j];
00751 }
00752
00753 image0->update();
00754
00755 int nc = 1;
00756 for (size_t i = 1; i < image_list.size(); i++) {
00757 EMData *image = image_list[i];
00758
00759 if (EMUtil::is_same_size(image, result)) {
00760 float *image_data = image->get_data();
00761
00762 for (size_t j = 0; j < image_size; j++) {
00763 result_data[j] += image_data[j];
00764 sigma_image_data[j] += image_data[j] * image_data[j];
00765 }
00766
00767 image->update();
00768 nc++;
00769 }
00770 }
00771
00772 float c = static_cast < float >(nc);
00773 for (size_t j = 0; j < image_size; j++) {
00774 float f1 = sigma_image_data[j] / c;
00775 float f2 = result_data[j] / c;
00776 sigma_image_data[j] = sqrt(f1 - f2 * f2) / sqrt(c);
00777 }
00778
00779
00780 for (size_t j = 0; j < image_size; j++) {
00781 result_data[j] /= c;
00782 }
00783
00784 result->update();
00785 sigma_image->update();
00786
00787 result->append_image("iter.hed");
00788
00789 float sigma = sigma_image->get_attr("sigma");
00790 float *sigma_image_data2 = sigma_image->get_data();
00791 float *result_data2 = result->get_data();
00792 float *d2 = new float[nx * ny];
00793 size_t sec_size = nx * ny * sizeof(float);
00794
00795 memcpy(d2, result_data2, sec_size);
00796 memcpy(sigma_image_data2, result_data2, sec_size);
00797
00798 printf("Iter sigma=%f\n", sigma);
00799
00800 for (int k = 0; k < 1000; k++) {
00801 for (int i = 1; i < nx - 1; i++) {
00802 for (int j = 1; j < ny - 1; j++) {
00803 int l = i + j * nx;
00804 float c1 = (d2[l - 1] + d2[l + 1] + d2[l - nx] + d2[l + nx]) / 4.0f - d2[l];
00805 float c2 = fabs(result_data2[l] - sigma_image_data2[l]) / sigma;
00806 result_data2[l] += c1 * Util::eman_erfc(c2) / 100.0f;
00807 }
00808 }
00809
00810 memcpy(d2, result_data2, sec_size);
00811 }
00812
00813 if( d2 )
00814 {
00815 delete[]d2;
00816 d2 = 0;
00817 }
00818
00819 sigma_image->update();
00820 if( sigma_image )
00821 {
00822 delete sigma_image;
00823 sigma_image = 0;
00824 }
00825
00826 result->update();
00827 result->append_image("iter.hed");
00828
00829 return result;
00830 }
00831 #endif
00832
00833
00834 CtfAverager::CtfAverager() :
00835 sf(0), curves(0), need_snr(false), outfile(0),
00836 image0_fft(0), image0_copy(0), snri(0), snrn(0),
00837 tdr(0), tdi(0), tn(0),
00838 filter(0), nimg(0), nx(0), ny(0), nz(0)
00839 {
00840
00841 }
00842
00843 void CtfAverager::add_image(EMData * image)
00844 {
00845 if (!image) {
00846 return;
00847 }
00848
00849 if (nimg >= 1 && !EMUtil::is_same_size(image, result)) {
00850 LOGERR("%sAverager can only process same-size Image",
00851 get_name().c_str());
00852 return;
00853 }
00854
00855 if (image->get_zsize() != 1) {
00856 LOGERR("%sAverager: Only 2D images are currently supported",
00857 get_name().c_str());
00858 }
00859
00860 string alg_name = get_name();
00861
00862 if (alg_name == "CtfCW" || alg_name == "CtfCWauto") {
00863 if (image->get_ctf() != 0 && !image->has_ctff()) {
00864 LOGERR("%sAverager: Attempted CTF Correction with no ctf parameters",
00865 get_name().c_str());
00866 }
00867 }
00868 else {
00869 if (image->get_ctf() != 0) {
00870 LOGERR("%sAverager: Attempted CTF Correction with no ctf parameters",
00871 get_name().c_str());
00872 }
00873 }
00874
00875 nimg++;
00876
00877
00878 if (nimg == 1) {
00879 image0_fft = image->do_fft();
00880
00881 nx = image0_fft->get_xsize();
00882 ny = image0_fft->get_ysize();
00883 nz = image0_fft->get_zsize();
00884
00885 result = new EMData();
00886 result->set_size(nx - 2, ny, nz);
00887
00888
00889 if (alg_name == "Weighting" && curves) {
00890 if (!sf) {
00891 LOGWARN("CTF curve in file will contain relative, not absolute SNR!");
00892 }
00893 curves->set_size(Ctf::CTFOS * ny / 2, 3, 1);
00894 curves->to_zero();
00895 }
00896
00897
00898 if (alg_name == "CtfC") {
00899 filter = params["filter"];
00900 if (filter == 0) {
00901 filter = 22.0f;
00902 }
00903 float apix_y = image->get_attr_dict().get("apix_y");
00904 float ds = 1.0f / (apix_y * ny * Ctf::CTFOS);
00905 filter = 1.0f / (filter * ds);
00906 }
00907
00908 if (alg_name == "CtfCWauto") {
00909 int nxy2 = nx * ny/2;
00910
00911 snri = new float[ny / 2];
00912 snrn = new float[ny / 2];
00913 tdr = new float[nxy2];
00914 tdi = new float[nxy2];
00915 tn = new float[nxy2];
00916
00917 for (int i = 0; i < ny / 2; i++) {
00918 snri[i] = 0;
00919 snrn[i] = 0;
00920 }
00921
00922 for (int i = 0; i < nxy2; i++) {
00923 tdr[i] = 1;
00924 tdi[i] = 1;
00925 tn[i] = 1;
00926 }
00927 }
00928
00929 image0_copy = image0_fft->copy_head();
00930 image0_copy->ap2ri();
00931 image0_copy->to_zero();
00932 }
00933
00934 Ctf::CtfType curve_type = Ctf::CTF_AMP;
00935 if (alg_name == "CtfCWauto") {
00936 curve_type = Ctf::CTF_AMP;
00937 }
00938
00939 float *src = image->get_data();
00940 image->ap2ri();
00941 Ctf *image_ctf = image->get_ctf();
00942 int ny2 = image->get_ysize();
00943
00944 vector<float> ctf1 = image_ctf->compute_1d(ny2,1.0f/(image_ctf->apix*image->get_ysize()), curve_type);
00945
00946 if (ctf1.size() == 0) {
00947 LOGERR("Unexpected CTF correction problem");
00948 }
00949
00950 ctf.push_back(ctf1);
00951
00952 vector<float> ctfn1;
00953 if (sf) {
00954 ctfn1 = image_ctf->compute_1d(ny2,1.0f/(image_ctf->apix*image->get_ysize()), Ctf::CTF_SNR, sf);
00955 }
00956 else {
00957 ctfn1 = image_ctf->compute_1d(ny2,1.0f/(image_ctf->apix*image->get_ysize()), Ctf::CTF_SNR);
00958 }
00959
00960 ctfn.push_back(ctfn1);
00961
00962 if (alg_name == "CtfCWauto") {
00963 int j = 0;
00964 for (int y = 0; y < ny; y++) {
00965 for (int x = 0; x < nx / 2; x++, j += 2) {
00966 #ifdef _WIN32
00967 float r = (float)_hypot((float)x, (float)(y - ny / 2.0f));
00968 #else
00969 float r = (float)hypot((float)x, (float)(y - ny / 2.0f));
00970 #endif //_WIN32
00971 int l = static_cast < int >(Util::fast_floor(r));
00972
00973 if (l >= 0 && l < ny / 2) {
00974 int k = y*nx/2 + x;
00975 tdr[k] *= src[j];
00976 tdi[k] *= src[j + 1];
00977 #ifdef _WIN32
00978 tn[k] *= (float)_hypot(src[j], src[j + 1]);
00979 #else
00980 tn[k] *= (float)hypot(src[j], src[j + 1]);
00981 #endif //_WIN32
00982 }
00983 }
00984 }
00985 }
00986
00987
00988 float *tmp_data = image0_copy->get_data();
00989
00990 int j = 0;
00991 for (int y = 0; y < ny; y++) {
00992 for (int x = 0; x < nx / 2; x++, j += 2) {
00993 float r = Ctf::CTFOS * sqrt(x * x + (y - ny / 2.0f) * (y - ny / 2.0f));
00994 int l = static_cast < int >(Util::fast_floor(r));
00995 r -= l;
00996
00997 float f = 0;
00998 if (l <= Ctf::CTFOS * ny / 2 - 2) {
00999 f = (ctf1[l] * (1 - r) + ctf1[l + 1] * r);
01000 }
01001 tmp_data[j] += src[j] * f;
01002 tmp_data[j + 1] += src[j + 1] * f;
01003 }
01004 }
01005
01006 EMData *image_fft = image->do_fft();
01007 image_fft->update();
01008 if(image_ctf) {delete image_ctf; image_ctf=0;}
01009 }
01010
01011 EMData * CtfAverager::finish()
01012 {
01013 int j = 0;
01014 for (int y = 0; y < ny; y++) {
01015 for (int x = 0; x < nx / 2; x++, j += 2) {
01016 #ifdef _WIN32
01017 float r = (float) _hypot(x, y - ny / 2.0f);
01018 #else
01019 float r = (float) hypot(x, y - ny / 2.0f);
01020 #endif
01021 int l = static_cast < int >(Util::fast_floor(r));
01022 if (l >= 0 && l < ny / 2) {
01023 int k = y*nx/2 + x;
01024 snri[l] += (tdr[k] + tdi[k]/tn[k]);
01025 snrn[l] += 1;
01026 }
01027 }
01028 }
01029
01030 for (int i = 0; i < ny / 2; i++) {
01031 snri[i] *= nimg / snrn[i];
01032 }
01033
01034 if(strcmp(outfile, "") != 0) {
01035 Util::save_data(0, 1, snri, ny / 2, outfile);
01036 }
01037
01038
01039 float *cd = 0;
01040 if (curves) {
01041 cd = curves->get_data();
01042 }
01043
01044 for (int i = 0; i < Ctf::CTFOS * ny / 2; i++) {
01045 float ctf0 = 0;
01046 for (int j = 0; j < nimg; j++) {
01047 ctf0 += ctfn[j][i];
01048 if (ctf[j][i] == 0) {
01049 ctf[j][i] = 1.0e-12f;
01050 }
01051
01052 if (curves) {
01053 cd[i] += ctf[j][i] * ctfn[j][i];
01054 cd[i + Ctf::CTFOS * ny / 2] += ctfn[j][i];
01055 cd[i + 2 * Ctf::CTFOS * ny / 2] += ctfn[j][i];
01056 }
01057 }
01058
01059 string alg_name = get_name();
01060
01061 if (alg_name == "CtfCW" && need_snr) {
01062 snr[i] = ctf0;
01063 }
01064
01065 float ctf1 = ctf0;
01066 if (alg_name == "CtfCWauto") {
01067 ctf1 = snri[i / Ctf::CTFOS];
01068 }
01069
01070 if (ctf1 <= 0.0001f) {
01071 ctf1 = 0.1f;
01072 }
01073
01074 if (alg_name == "CtfC") {
01075 for (int j = 0; j < nimg; j++) {
01076 ctf[j][i] = exp(-i * i / (filter * filter)) * ctfn[j][i] / (fabs(ctf[j][i]) * ctf1);
01077 }
01078 }
01079 else if (alg_name == "Weighting") {
01080 for (int j = 0; j < nimg; j++) {
01081 ctf[j][i] = ctfn[j][i] / ctf1;
01082 }
01083 }
01084 else if (alg_name == "CtfCW") {
01085 for (int j = 0; j < nimg; j++) {
01086 ctf[j][i] = (ctf1 / (ctf1 + 1)) * ctfn[j][i] / (ctf[j][i] * ctf1);
01087 }
01088 }
01089 else if (alg_name == "CtfCWauto") {
01090 for (int j = 0; j < nimg; j++) {
01091 ctf[j][i] = ctf1 * ctfn[j][i] / (fabs(ctf[j][i]) * ctf0);
01092 }
01093 }
01094 }
01095
01096
01097 if (curves) {
01098 for (int i = 0; i < Ctf::CTFOS * ny / 2; i++) {
01099 cd[i] /= cd[i + Ctf::CTFOS * ny / 2];
01100 }
01101 curves->update();
01102 }
01103
01104 image0_copy->update();
01105
01106 float *result_data = result->get_data();
01107 EMData *tmp_ift = image0_copy->do_ift();
01108 float *tmp_ift_data = tmp_ift->get_data();
01109 memcpy(result_data, tmp_ift_data, (nx - 2) * ny * sizeof(float));
01110
01111 tmp_ift->update();
01112 result->update();
01113 result->set_attr("ptcl_repr",nimg);
01114
01115 if( image0_copy )
01116 {
01117 delete image0_copy;
01118 image0_copy = 0;
01119 }
01120
01121 if (snri) {
01122 delete[]snri;
01123 snri = 0;
01124 }
01125
01126 if (snrn) {
01127 delete[]snrn;
01128 snrn = 0;
01129 }
01130
01131 if( snri )
01132 {
01133 delete [] snri;
01134 snri = 0;
01135 }
01136 if( snrn )
01137 {
01138 delete [] snrn;
01139 snrn = 0;
01140 }
01141 if( tdr )
01142 {
01143 delete [] tdr;
01144 tdr = 0;
01145 }
01146 if( tdi )
01147 {
01148 delete [] tdi;
01149 tdi = 0;
01150 }
01151 if( tn )
01152 {
01153 delete [] tn;
01154 tn = 0;
01155 }
01156
01157 return result;
01158 }
01159
01160 #if 0
01161 EMData *CtfAverager::average(const vector < EMData * >&image_list) const
01162 {
01163 if (image_list.size() == 0) {
01164 return 0;
01165 }
01166
01167 EMData *image0 = image_list[0];
01168 if (image0->get_zsize() != 1) {
01169 LOGERR("Only 2D images are currently supported");
01170 return 0;
01171 }
01172
01173 string alg_name = get_name();
01174
01175 if (alg_name == "CtfCW" || alg_name == "CtfCWauto") {
01176 if (image0->get_ctf() != 0 && !image0->has_ctff()) {
01177 LOGERR("Attempted CTF Correction with no ctf parameters");
01178 return 0;
01179 }
01180 }
01181 else {
01182 if (image0->get_ctf() != 0) {
01183 LOGERR("Attempted CTF Correction with no ctf parameters");
01184 return 0;
01185 }
01186 }
01187
01188 size_t num_images = image_list.size();
01189 vector < float >*ctf = new vector < float >[num_images];
01190 vector < float >*ctfn = new vector < float >[num_images];
01191 float **src = new float *[num_images];
01192
01193 Ctf::CtfType curve_type = Ctf::CTF_ABS_AMP;
01194 if (alg_name == "CtfCWauto") {
01195 curve_type = Ctf::CTF_AMP;
01196 }
01197
01198 for (size_t i = 0; i < num_images; i++) {
01199 EMData *image = image_list[i]->do_fft();
01200 image->ap2ri();
01201 src[i] = image->get_data();
01202 Ctf *image_ctf = image->get_ctf();
01203 int ny = image->get_ysize();
01204 ctf[i] = image_ctf->compute_1d(ny, curve_type);
01205
01206 if (ctf[i].size() == 0) {
01207 LOGERR("Unexpected CTF correction problem");
01208 return 0;
01209 }
01210
01211 if (sf) {
01212 ctfn[i] = image_ctf->compute_1d(ny, Ctf::CTF_ABS_SNR, sf);
01213 }
01214 else { result->set_attr("ptcl_repr",nimg);
01215 ctfn[i] = image_ctf->compute_1d(ny, Ctf::CTF_RELATIVE_SNR);
01216 }
01217
01218 if(image_ctf) {delete image_ctf; image_ctf=0;}
01219 }
01220
01221 EMData *image0_fft = image0->do_fft();
01222
01223 int nx = image0_fft->get_xsize();
01224 int ny = image0_fft->get_ysize();
01225 int nz = image0_fft->get_zsize();
01226
01227 EMData *result = new EMData();
01228 result->set_size(nx - 2, ny, nz);
01229
01230 float *cd = 0;
01231 if (alg_name == "Weighting" && curves) {
01232 if (!sf) {
01233 LOGWARN("CTF curve in file will contain relative, not absolute SNR!");
01234 }
01235 curves->set_size(Ctf::CTFOS * ny / 2, 3, 1);
01236 curves->to_zero();
01237 cd = curves->get_data();
01238 }
01239
01240 float filter = 0;
01241 if (alg_name == "CtfC") {
01242 filter = params["filter"];
01243 if (filter == 0) {
01244 filter = 22.0f;
01245 }
01246 float apix_y = image0->get_attr_dict().get("apix_y");
01247 float ds = 1.0f / (apix_y * ny * Ctf::CTFOS);
01248 filter = 1.0f / (filter * ds);
01249 }
01250
01251 float *snri = 0;
01252 float *snrn = 0;
01253
01254 if (alg_name == "CtfCWauto") {
01255 snri = new float[ny / 2];
01256 snrn = new float[ny / 2];
01257
01258 for (int i = 0; i < ny / 2; i++) {
01259 snri[i] = 0;
01260 snrn[i] = 0;
01261 }
01262
01263 int j = 0;
01264 for (int y = 0; y < ny; y++) {
01265 for (int x = 0; x < nx / 2; x++, j += 2) {
01266 float r = hypot(x, y - ny / 2.0f);
01267 int l = static_cast < int >(Util::fast_floor(r));
01268
01269 if (l >= 0 && l < ny / 2) {
01270 float tdr = 1;
01271 float tdi = 1;
01272 float tn = 1;
01273
01274 for (size_t i = 0; i < num_images; i++) {
01275 tdr *= src[i][j];
01276 tdi *= src[i][j + 1];
01277 tn *= hypot(src[i][j], src[i][j + 1]);
01278 }
01279
01280 tdr += tdi / tn;
01281 snri[l] += tdr;
01282 snrn[l] += 1;
01283 }
01284 }
01285 }
01286
01287 for (int i = 0; i < ny / 2; i++) {
01288 snri[i] *= num_images / snrn[i];
01289 }
01290 if (outfile != "") {
01291 Util::save_data(0, 1, snri, ny / 2, outfile);
01292 }
01293 }
01294
01295 for (int i = 0; i < Ctf::CTFOS * ny / 2; i++) {
01296 float ctf0 = 0;
01297 for (size_t j = 0; j < num_images; j++) {
01298 ctf0 += ctfn[j][i];
01299 if (ctf[j][i] == 0) {
01300 ctf[j][i] = 1.0e-12;
01301 }
01302
01303 if (curves) {
01304 cd[i] += ctf[j][i] * ctfn[j][i];
01305 cd[i + Ctf::CTFOS * ny / 2] += ctfn[j][i];
01306 cd[i + 2 * Ctf::CTFOS * ny / 2] += ctfn[j][i];
01307 }
01308 }
01309
01310 if (alg_name == "CtfCW" && need_snr) {
01311 snr[i] = ctf0;
01312 }
01313
01314 float ctf1 = ctf0;
01315 if (alg_name == "CtfCWauto") {
01316 ctf1 = snri[i / Ctf::CTFOS];
01317 }
01318
01319 if (ctf1 <= 0.0001f) {
01320 ctf1 = 0.1f;
01321 }
01322
01323 if (alg_name == "CtfC") {
01324 for (size_t j = 0; j < num_images; j++) {
01325 ctf[j][i] = exp(-i * i / (filter * filter)) * ctfn[j][i] / (fabs(ctf[j][i]) * ctf1);
01326 }
01327 }
01328 else if (alg_name == "Weighting") {
01329 for (size_t j = 0; j < num_images; j++) {
01330 ctf[j][i] = ctfn[j][i] / ctf1;
01331 }
01332 }
01333 else if (alg_name == "CtfCW") {
01334 for (size_t j = 0; j < num_images; j++) {
01335 ctf[j][i] = (ctf1 / (ctf1 + 1)) * ctfn[j][i] / (ctf[j][i] * ctf1);
01336 }
01337 }
01338 else if (alg_name == "CtfCWauto") {
01339 for (size_t j = 0; j < num_images; j++) {
01340 ctf[j][i] = ctf1 * ctfn[j][i] / (fabs(ctf[j][i]) * ctf0);
01341 }
01342 }
01343 }
01344
01345
01346 if (curves) {
01347 for (int i = 0; i < Ctf::CTFOS * ny / 2; i++) {
01348 cd[i] /= cd[i + Ctf::CTFOS * ny / 2];
01349 }
01350 curves->update();
01351 }
01352
01353 EMData *image0_copy = image0_fft->copy_head();
01354 image0_copy->ap2ri();
01355
01356 float *tmp_data = image0_copy->get_data();
01357
01358 int j = 0;
01359 for (int y = 0; y < ny; y++) {
01360 for (int x = 0; x < nx / 2; x++, j += 2) {
01361 float r = Ctf::CTFOS * sqrt(x * x + (y - ny / 2.0f) * (y - ny / 2.0f));
01362 int l = static_cast < int >(Util::fast_floor(r));
01363 r -= l;
01364
01365 tmp_data[j] = 0;
01366 tmp_data[j + 1] = 0;
01367
01368 for (size_t i = 0; i < num_images; i++) {
01369 float f = 0;
01370 if (l <= Ctf::CTFOS * ny / 2 - 2) {
01371 f = (ctf[i][l] * (1 - r) + ctf[i][l + 1] * r);
01372 }
01373 tmp_data[j] += src[i][j] * f;
01374 tmp_data[j + 1] += src[i][j + 1] * f;
01375 }
01376 }
01377 }
01378
01379 image0_copy->update();
01380
01381 float *result_data = result->get_data();
01382 EMData *tmp_ift = image0_copy->do_ift();
01383 float *tmp_ift_data = tmp_ift->get_data();
01384 memcpy(result_data, tmp_ift_data, (nx - 2) * ny * sizeof(float));
01385
01386 tmp_ift->update();
01387
01388 if( image0_copy )
01389 {
01390 delete image0_copy;
01391 image0_copy = 0;
01392 }
01393
01394 for (size_t i = 0; i < num_images; i++) {
01395 EMData *img = image_list[i]->do_fft();
01396 img->update();
01397 }
01398
01399 if( src )
01400 {
01401 delete[]src;
01402 src = 0;
01403 }
01404
01405 if( ctf )
01406 {
01407 delete[]ctf;
01408 ctf = 0;
01409 }
01410
01411 if( ctfn )
01412 {
01413 delete[]ctfn;
01414 ctfn = 0;
01415 }
01416
01417 if (snri) {
01418 delete[]snri;
01419 snri = 0;
01420 }
01421
01422 if (snrn) {
01423 delete[]snrn;
01424 snrn = 0;
01425 }
01426
01427 result->update();
01428 return result;
01429 }
01430 #endif
01431
01432
01433 void EMAN::dump_averagers()
01434 {
01435 dump_factory < Averager > ();
01436 }
01437
01438 map<string, vector<string> > EMAN::dump_averagers_list()
01439 {
01440 return dump_factory_list < Averager > ();
01441 }