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
00042 using namespace EMAN;
00043
00044 template <> Factory < Averager >::Factory()
00045 {
00046 force_add(&ImageAverager::NEW);
00047 force_add(&MinMaxAverager::NEW);
00048 force_add(&IterationAverager::NEW);
00049 force_add(&WeightingAverager::NEW);
00050
00051
00052
00053 force_add(&CtfCWautoAverager::NEW);
00054 }
00055
00056 void Averager::mult(const float& s)
00057 {
00058 if ( result != 0 )
00059 {
00060 result->mult(s);
00061 }
00062 else throw NullPointerException("Error, attempted to multiply the result image, which is NULL");
00063 }
00064
00065
00066 void Averager::add_image_list(const vector<EMData*> & image_list)
00067 {
00068 for (size_t i = 0; i < image_list.size(); i++) {
00069 add_image(image_list[i]);
00070 }
00071 }
00072
00073 ImageAverager::ImageAverager()
00074 : sigma_image(0), nimg_n0(0), ignore0(0), nimg(0)
00075 {
00076
00077 }
00078
00079 void ImageAverager::add_image(EMData * image)
00080 {
00081 if (!image) {
00082 return;
00083 }
00084
00085 if (nimg >= 1 && !EMUtil::is_same_size(image, result)) {
00086 LOGERR("%sAverager can only process same-size Image",
00087 get_name().c_str());
00088 return;
00089 }
00090
00091 nimg++;
00092
00093 int nx = image->get_xsize();
00094 int ny = image->get_ysize();
00095 int nz = image->get_zsize();
00096 size_t image_size = nx * ny * nz;
00097
00098 if (nimg == 1) {
00099 result = new EMData();
00100 result->set_size(nx, ny, nz);
00101 sigma_image = params.set_default("sigma", (EMData*)0);
00102 ignore0 = params["ignore0"];
00103
00104 nimg_n0 = new int[image_size];
00105 for (size_t i = 0; i < image_size; i++) {
00106 nimg_n0[i] = 0;
00107 }
00108 }
00109
00110 float *result_data = result->get_data();
00111 float *sigma_image_data = 0;
00112 if (sigma_image) {
00113 sigma_image->set_size(nx, ny, nz);
00114 sigma_image_data = sigma_image->get_data();
00115 }
00116
00117 float * image_data = image->get_data();
00118
00119 if (!ignore0) {
00120 for (size_t j = 0; j < image_size; j++) {
00121 float f = image_data[j];
00122 result_data[j] += f;
00123 if (sigma_image_data) {
00124 sigma_image_data[j] += f * f;
00125 }
00126 }
00127 }
00128 else {
00129 for (size_t j = 0; j < image_size; j++) {
00130 float f = image_data[j];
00131 if (f) {
00132 result_data[j] += f;
00133 if (sigma_image_data) {
00134 sigma_image_data[j] += f * f;
00135 }
00136 nimg_n0[j]++;
00137 }
00138 }
00139 }
00140 }
00141
00142 EMData * ImageAverager::finish()
00143 {
00144 if (result && nimg > 1) {
00145 size_t image_size = result->get_xsize() * result->get_ysize() * result->get_zsize();
00146 float * result_data = result->get_data();
00147
00148 if (!ignore0) {
00149 for (size_t j = 0; j < image_size; j++) {
00150 result_data[j] /= nimg;
00151 }
00152
00153 if (sigma_image) {
00154 float * sigma_image_data = sigma_image->get_data();
00155
00156 for (size_t j = 0; j < image_size; j++) {
00157 float f1 = sigma_image_data[j] / nimg;
00158 float f2 = result_data[j];
00159 sigma_image_data[j] = sqrt(f1 - f2 * f2);
00160 }
00161
00162 sigma_image->update();
00163 }
00164 }
00165 else {
00166 for (size_t j = 0; j < image_size; j++) {
00167 result_data[j] /= nimg_n0[j];
00168 }
00169 if (sigma_image) {
00170 float * sigma_image_data = sigma_image->get_data();
00171
00172 for (size_t j = 0; j < image_size; j++) {
00173 float f1 = sigma_image_data[j] / nimg_n0[j];
00174 float f2 = result_data[j];
00175 sigma_image_data[j] = sqrt(f1 - f2 * f2);
00176 }
00177
00178 sigma_image->update();
00179 }
00180 }
00181
00182 result->update();
00183 }
00184
00185 if( nimg_n0 )
00186 {
00187 delete [] nimg_n0;
00188 nimg_n0 = 0;
00189 }
00190
00191 return result;
00192 }
00193
00194 #if 0
00195 EMData *ImageAverager::average(const vector < EMData * >&image_list) const
00196 {
00197 if (image_list.size() == 0) {
00198 return 0;
00199 }
00200
00201 EMData *sigma_image = params["sigma"];
00202 int ignore0 = params["ignore0"];
00203
00204 EMData *image0 = image_list[0];
00205
00206 int nx = image0->get_xsize();
00207 int ny = image0->get_ysize();
00208 int nz = image0->get_zsize();
00209 size_t image_size = nx * ny * nz;
00210
00211 EMData *result = new EMData();
00212 result->set_size(nx, ny, nz);
00213
00214 float *result_data = result->get_data();
00215 float *sigma_image_data = 0;
00216
00217 if (sigma_image) {
00218 sigma_image->set_size(nx, ny, nz);
00219 sigma_image_data = sigma_image->get_data();
00220 }
00221
00222 int c = 1;
00223 if (ignore0) {
00224 for (size_t j = 0; j < image_size; j++) {
00225 int g = 0;
00226 for (size_t i = 0; i < image_list.size(); i++) {
00227 float f = image_list[i]->get_value_at(j);
00228 if (f) {
00229 g++;
00230 result_data[j] += f;
00231 if (sigma_image_data) {
00232 sigma_image_data[j] += f * f;
00233 }
00234 }
00235 }
00236 if (g) {
00237 result_data[j] /= g;
00238 }
00239 }
00240 }
00241 else {
00242 float *image0_data = image0->get_data();
00243 if (sigma_image_data) {
00244 memcpy(sigma_image_data, image0_data, image_size * sizeof(float));
00245
00246 for (size_t j = 0; j < image_size; j++) {
00247 sigma_image_data[j] *= sigma_image_data[j];
00248 }
00249 }
00250
00251 image0->update();
00252 memcpy(result_data, image0_data, image_size * sizeof(float));
00253
00254 for (size_t i = 1; i < image_list.size(); i++) {
00255 EMData *image = image_list[i];
00256
00257 if (EMUtil::is_same_size(image, result)) {
00258 float *image_data = image->get_data();
00259
00260 for (size_t j = 0; j < image_size; j++) {
00261 result_data[j] += image_data[j];
00262 }
00263
00264 if (sigma_image_data) {
00265 for (size_t j = 0; j < image_size; j++) {
00266 sigma_image_data[j] += image_data[j] * image_data[j];
00267 }
00268 }
00269
00270 image->update();
00271 c++;
00272 }
00273 }
00274
00275 for (size_t j = 0; j < image_size; j++) {
00276 result_data[j] /= static_cast < float >(c);
00277 }
00278 }
00279
00280 if (sigma_image_data) {
00281 for (size_t j = 0; j < image_size; j++) {
00282 float f1 = sigma_image_data[j] / c;
00283 float f2 = result_data[j];
00284 sigma_image_data[j] = sqrt(f1 - f2 * f2);
00285 }
00286 }
00287
00288 if (sigma_image_data) {
00289 sigma_image->update();
00290 }
00291
00292 result->update();
00293 return result;
00294 }
00295 #endif
00296
00297 MinMaxAverager::MinMaxAverager()
00298 : nimg(0)
00299 {
00300
00301
00302 max = 0;
00303 }
00304
00305 void MinMaxAverager::add_image(EMData * image)
00306 {
00307 if (!image) {
00308 return;
00309 }
00310
00311 if (nimg >= 1 && !EMUtil::is_same_size(image, result)) {
00312 LOGERR("%sAverager can only process same-size Image",
00313 get_name().c_str());
00314 return;
00315 }
00316
00317 nimg++;
00318
00319 int nx = image->get_xsize();
00320 int ny = image->get_ysize();
00321 int nz = image->get_zsize();
00322
00323 if (nimg == 1) {
00324 result = image->copy();
00325 max = params["max"];
00326 return;
00327 }
00328
00329 for (int z=0; z<nz; z++) {
00330 for (int y=0; y<ny; y++) {
00331 for (int x=0; x<nx; x++) {
00332 if (result->get_value_at(x,y,z)>image->get_value_at(x,y,z))
00333 { if (!max) result->set_value_at(x,y,z,image->get_value_at(x,y,z)); }
00334 else { if (max) result->set_value_at(x,y,z,image->get_value_at(x,y,z)); }
00335 }
00336 }
00337 }
00338
00339 }
00340
00341 EMData *MinMaxAverager::finish()
00342 {
00343 result->update();
00344 if (result && nimg > 1) return result;
00345
00346 return NULL;
00347 }
00348
00349
00350 IterationAverager::IterationAverager() : nimg(0)
00351 {
00352
00353 }
00354
00355 void IterationAverager::add_image( EMData * image)
00356 {
00357 if (!image) {
00358 return;
00359 }
00360
00361 if (nimg >= 1 && !EMUtil::is_same_size(image, result)) {
00362 LOGERR("%sAverager can only process same-size Image",
00363 get_name().c_str());
00364 return;
00365 }
00366
00367 nimg++;
00368
00369 int nx = image->get_xsize();
00370 int ny = image->get_ysize();
00371 int nz = image->get_zsize();
00372 size_t image_size = nx * ny * nz;
00373
00374 if (nimg == 1) {
00375 result = new EMData();
00376 result->set_size(nx, ny, nz);
00377 sigma_image = new EMData();
00378 sigma_image->set_size(nx, ny, nz);
00379 }
00380
00381 float *image_data = image->get_data();
00382 float *result_data = result->get_data();
00383 float *sigma_image_data = sigma_image->get_data();
00384
00385 for (size_t j = 0; j < image_size; j++) {
00386 float f = image_data[j];
00387 result_data[j] += f;
00388 sigma_image_data[j] += f * f;
00389 }
00390
00391
00392 }
00393
00394 EMData * IterationAverager::finish()
00395 {
00396 if (nimg < 1) {
00397 return result;
00398 }
00399
00400 int nx = result->get_xsize();
00401 int ny = result->get_ysize();
00402 int nz = result->get_zsize();
00403 size_t image_size = nx * ny * nz;
00404
00405 float *result_data = result->get_data();
00406 float *sigma_image_data = sigma_image->get_data();
00407
00408 for (size_t j = 0; j < image_size; j++) {
00409 result_data[j] /= nimg;
00410 float f1 = sigma_image_data[j] / nimg;
00411 float f2 = result_data[j];
00412 sigma_image_data[j] = sqrt(f1 - f2 * f2) / sqrt((float)nimg);
00413 }
00414
00415 result->update();
00416 sigma_image->update();
00417
00418 result->append_image("iter.hed");
00419 float sigma = sigma_image->get_attr("sigma");
00420 float *sigma_image_data2 = sigma_image->get_data();
00421 float *result_data2 = result->get_data();
00422 float *d2 = new float[nx * ny];
00423 size_t sec_size = nx * ny * sizeof(float);
00424
00425 memcpy(d2, result_data2, sec_size);
00426 memcpy(sigma_image_data2, result_data2, sec_size);
00427
00428 printf("Iter sigma=%f\n", sigma);
00429
00430 for (int k = 0; k < 1000; k++) {
00431 for (int i = 1; i < nx - 1; i++) {
00432 for (int j = 1; j < ny - 1; j++) {
00433 int l = i + j * nx;
00434 float c1 = (d2[l - 1] + d2[l + 1] + d2[l - nx] + d2[l + nx]) / 4.0f - d2[l];
00435 float c2 = fabs(result_data2[l] - sigma_image_data2[l]) / sigma;
00436 result_data2[l] += c1 * Util::eman_erfc(c2) / 100.0f;
00437 }
00438 }
00439
00440 memcpy(d2, result_data2, sec_size);
00441 }
00442
00443 if( d2 )
00444 {
00445 delete[]d2;
00446 d2 = 0;
00447 }
00448
00449 sigma_image->update();
00450 if( sigma_image )
00451 {
00452 delete sigma_image;
00453 sigma_image = 0;
00454 }
00455
00456 result->update();
00457 result->append_image("iter.hed");
00458
00459
00460 return result;
00461 }
00462
00463 CtfCWautoAverager::CtfCWautoAverager()
00464 : nimg(0)
00465 {
00466
00467 }
00468
00469
00470 void CtfCWautoAverager::add_image(EMData * image)
00471 {
00472 if (!image) {
00473 return;
00474 }
00475
00476
00477
00478 EMData *fft=image->do_fft();
00479
00480 if (nimg >= 1 && !EMUtil::is_same_size(fft, result)) {
00481 LOGERR("%s Averager can only process images of the same size", get_name().c_str());
00482 return;
00483 }
00484
00485 nimg++;
00486 if (nimg == 1) {
00487 result = fft->copy_head();
00488 result->to_zero();
00489 }
00490
00491 Ctf *ctf = (Ctf *)image->get_attr("ctf");
00492 float b=ctf->bfactor;
00493 ctf->bfactor=100.0;
00494
00495 EMData *snr = result -> copy();
00496 ctf->compute_2d_complex(snr,Ctf::CTF_SNR);
00497 EMData *ctfi = result-> copy();
00498 ctf->compute_2d_complex(ctfi,Ctf::CTF_AMP);
00499
00500 ctf->bfactor=b;
00501
00502 float *outd = result->get_data();
00503 float *ind = fft->get_data();
00504 float *snrd = snr->get_data();
00505 float *ctfd = ctfi->get_data();
00506
00507 size_t sz=snr->get_xsize()*snr->get_ysize();
00508 for (size_t i = 0; i < sz; i+=2) {
00509 if (snrd[i]<0) snrd[i]=0;
00510 ctfd[i]=fabs(ctfd[i]);
00511 if (ctfd[i]<.05) {
00512 if (snrd[i]<=0) ctfd[i]=.05f;
00513 else ctfd[i]=snrd[i]*10.0f;
00514 }
00515 outd[i]+=ind[i]*snrd[i]/ctfd[i];
00516 outd[i+1]+=ind[i+1]*snrd[i]/ctfd[i];
00517 }
00518
00519 if (nimg==1) {
00520 snrsum=snr->copy_head();
00521 float *ssnrd=snrsum->get_data();
00522
00523 for (size_t i = 0; i < sz; i+=2) { ssnrd[i]=1.0; ssnrd[i+1]=0.0; }
00524 }
00525 snrsum->add(*snr);
00526
00527 delete ctf;
00528 delete fft;
00529 delete snr;
00530 delete ctfi;
00531 }
00532
00533 EMData * CtfCWautoAverager::finish()
00534 {
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 size_t sz=result->get_xsize()*result->get_ysize();
00545 float *snrsd=snrsum->get_data();
00546 float *outd=result->get_data();
00547
00548 for (size_t i=0; i<sz; i+=2) {
00549 outd[i]/=snrsd[i];
00550 outd[i+1]/=snrsd[i];
00551 }
00552 result->update();
00553 result->set_attr("ptcl_repr",nimg);
00554
00555 delete snrsum;
00556 EMData *ret=result->do_ift();
00557 delete result;
00558 result=NULL;
00559 return ret;
00560 }
00561
00562
00563 #if 0
00564 EMData *IterationAverager::average(const vector < EMData * >&image_list) const
00565 {
00566 if (image_list.size() == 0) {
00567 return 0;
00568 }
00569
00570 EMData *image0 = image_list[0];
00571
00572 int nx = image0->get_xsize();
00573 int ny = image0->get_ysize();
00574 int nz = image0->get_zsize();
00575 size_t image_size = nx * ny * nz;
00576
00577 EMData *result = new EMData();
00578 result->set_size(nx, ny, nz);
00579
00580 EMData *sigma_image = new EMData();
00581 sigma_image->set_size(nx, ny, nz);
00582
00583 float *image0_data = image0->get_data();
00584 float *result_data = result->get_data();
00585 float *sigma_image_data = sigma_image->get_data();
00586
00587 memcpy(result_data, image0_data, image_size * sizeof(float));
00588 memcpy(sigma_image_data, image0_data, image_size * sizeof(float));
00589
00590 for (size_t j = 0; j < image_size; j++) {
00591 sigma_image_data[j] *= sigma_image_data[j];
00592 }
00593
00594 image0->update();
00595
00596 int nc = 1;
00597 for (size_t i = 1; i < image_list.size(); i++) {
00598 EMData *image = image_list[i];
00599
00600 if (EMUtil::is_same_size(image, result)) {
00601 float *image_data = image->get_data();
00602
00603 for (size_t j = 0; j < image_size; j++) {
00604 result_data[j] += image_data[j];
00605 sigma_image_data[j] += image_data[j] * image_data[j];
00606 }
00607
00608 image->update();
00609 nc++;
00610 }
00611 }
00612
00613 float c = static_cast < float >(nc);
00614 for (size_t j = 0; j < image_size; j++) {
00615 float f1 = sigma_image_data[j] / c;
00616 float f2 = result_data[j] / c;
00617 sigma_image_data[j] = sqrt(f1 - f2 * f2) / sqrt(c);
00618 }
00619
00620
00621 for (size_t j = 0; j < image_size; j++) {
00622 result_data[j] /= c;
00623 }
00624
00625 result->update();
00626 sigma_image->update();
00627
00628 result->append_image("iter.hed");
00629
00630 float sigma = sigma_image->get_attr("sigma");
00631 float *sigma_image_data2 = sigma_image->get_data();
00632 float *result_data2 = result->get_data();
00633 float *d2 = new float[nx * ny];
00634 size_t sec_size = nx * ny * sizeof(float);
00635
00636 memcpy(d2, result_data2, sec_size);
00637 memcpy(sigma_image_data2, result_data2, sec_size);
00638
00639 printf("Iter sigma=%f\n", sigma);
00640
00641 for (int k = 0; k < 1000; k++) {
00642 for (int i = 1; i < nx - 1; i++) {
00643 for (int j = 1; j < ny - 1; j++) {
00644 int l = i + j * nx;
00645 float c1 = (d2[l - 1] + d2[l + 1] + d2[l - nx] + d2[l + nx]) / 4.0f - d2[l];
00646 float c2 = fabs(result_data2[l] - sigma_image_data2[l]) / sigma;
00647 result_data2[l] += c1 * Util::eman_erfc(c2) / 100.0f;
00648 }
00649 }
00650
00651 memcpy(d2, result_data2, sec_size);
00652 }
00653
00654 if( d2 )
00655 {
00656 delete[]d2;
00657 d2 = 0;
00658 }
00659
00660 sigma_image->update();
00661 if( sigma_image )
00662 {
00663 delete sigma_image;
00664 sigma_image = 0;
00665 }
00666
00667 result->update();
00668 result->append_image("iter.hed");
00669
00670 return result;
00671 }
00672 #endif
00673
00674
00675 CtfAverager::CtfAverager() :
00676 sf(0), curves(0), need_snr(false), outfile(0),
00677 image0_fft(0), image0_copy(0), snri(0), snrn(0),
00678 tdr(0), tdi(0), tn(0),
00679 filter(0), nimg(0), nx(0), ny(0), nz(0)
00680 {
00681
00682 }
00683
00684 void CtfAverager::add_image(EMData * image)
00685 {
00686 if (!image) {
00687 return;
00688 }
00689
00690 if (nimg >= 1 && !EMUtil::is_same_size(image, result)) {
00691 LOGERR("%sAverager can only process same-size Image",
00692 get_name().c_str());
00693 return;
00694 }
00695
00696 if (image->get_zsize() != 1) {
00697 LOGERR("%sAverager: Only 2D images are currently supported",
00698 get_name().c_str());
00699 }
00700
00701 string alg_name = get_name();
00702
00703 if (alg_name == "CtfCW" || alg_name == "CtfCWauto") {
00704 if (image->get_ctf() != 0 && !image->has_ctff()) {
00705 LOGERR("%sAverager: Attempted CTF Correction with no ctf parameters",
00706 get_name().c_str());
00707 }
00708 }
00709 else {
00710 if (image->get_ctf() != 0) {
00711 LOGERR("%sAverager: Attempted CTF Correction with no ctf parameters",
00712 get_name().c_str());
00713 }
00714 }
00715
00716 nimg++;
00717
00718
00719 if (nimg == 1) {
00720 image0_fft = image->do_fft();
00721
00722 nx = image0_fft->get_xsize();
00723 ny = image0_fft->get_ysize();
00724 nz = image0_fft->get_zsize();
00725
00726 result = new EMData();
00727 result->set_size(nx - 2, ny, nz);
00728
00729
00730 if (alg_name == "Weighting" && curves) {
00731 if (!sf) {
00732 LOGWARN("CTF curve in file will contain relative, not absolute SNR!");
00733 }
00734 curves->set_size(Ctf::CTFOS * ny / 2, 3, 1);
00735 curves->to_zero();
00736 }
00737
00738
00739 if (alg_name == "CtfC") {
00740 filter = params["filter"];
00741 if (filter == 0) {
00742 filter = 22.0f;
00743 }
00744 float apix_y = image->get_attr_dict().get("apix_y");
00745 float ds = 1.0f / (apix_y * ny * Ctf::CTFOS);
00746 filter = 1.0f / (filter * ds);
00747 }
00748
00749 if (alg_name == "CtfCWauto") {
00750 int nxy2 = nx * ny/2;
00751
00752 snri = new float[ny / 2];
00753 snrn = new float[ny / 2];
00754 tdr = new float[nxy2];
00755 tdi = new float[nxy2];
00756 tn = new float[nxy2];
00757
00758 for (int i = 0; i < ny / 2; i++) {
00759 snri[i] = 0;
00760 snrn[i] = 0;
00761 }
00762
00763 for (int i = 0; i < nxy2; i++) {
00764 tdr[i] = 1;
00765 tdi[i] = 1;
00766 tn[i] = 1;
00767 }
00768 }
00769
00770 image0_copy = image0_fft->copy_head();
00771 image0_copy->ap2ri();
00772 image0_copy->to_zero();
00773 }
00774
00775 Ctf::CtfType curve_type = Ctf::CTF_AMP;
00776 if (alg_name == "CtfCWauto") {
00777 curve_type = Ctf::CTF_AMP;
00778 }
00779
00780 float *src = image->get_data();
00781 image->ap2ri();
00782 Ctf *image_ctf = image->get_ctf();
00783 int ny2 = image->get_ysize();
00784
00785 vector<float> ctf1 = image_ctf->compute_1d(ny2,1.0f/(image_ctf->apix*image->get_ysize()), curve_type);
00786
00787 if (ctf1.size() == 0) {
00788 LOGERR("Unexpected CTF correction problem");
00789 }
00790
00791 ctf.push_back(ctf1);
00792
00793 vector<float> ctfn1;
00794 if (sf) {
00795 ctfn1 = image_ctf->compute_1d(ny2,1.0f/(image_ctf->apix*image->get_ysize()), Ctf::CTF_SNR, sf);
00796 }
00797 else {
00798 ctfn1 = image_ctf->compute_1d(ny2,1.0f/(image_ctf->apix*image->get_ysize()), Ctf::CTF_SNR);
00799 }
00800
00801 ctfn.push_back(ctfn1);
00802
00803 if (alg_name == "CtfCWauto") {
00804 int j = 0;
00805 for (int y = 0; y < ny; y++) {
00806 for (int x = 0; x < nx / 2; x++, j += 2) {
00807 #ifdef _WIN32
00808 float r = (float)_hypot((float)x, (float)(y - ny / 2.0f));
00809 #else
00810 float r = (float)hypot((float)x, (float)(y - ny / 2.0f));
00811 #endif //_WIN32
00812 int l = static_cast < int >(Util::fast_floor(r));
00813
00814 if (l >= 0 && l < ny / 2) {
00815 int k = y*nx/2 + x;
00816 tdr[k] *= src[j];
00817 tdi[k] *= src[j + 1];
00818 #ifdef _WIN32
00819 tn[k] *= (float)_hypot(src[j], src[j + 1]);
00820 #else
00821 tn[k] *= (float)hypot(src[j], src[j + 1]);
00822 #endif //_WIN32
00823 }
00824 }
00825 }
00826 }
00827
00828
00829 float *tmp_data = image0_copy->get_data();
00830
00831 int j = 0;
00832 for (int y = 0; y < ny; y++) {
00833 for (int x = 0; x < nx / 2; x++, j += 2) {
00834 float r = Ctf::CTFOS * sqrt(x * x + (y - ny / 2.0f) * (y - ny / 2.0f));
00835 int l = static_cast < int >(Util::fast_floor(r));
00836 r -= l;
00837
00838 float f = 0;
00839 if (l <= Ctf::CTFOS * ny / 2 - 2) {
00840 f = (ctf1[l] * (1 - r) + ctf1[l + 1] * r);
00841 }
00842 tmp_data[j] += src[j] * f;
00843 tmp_data[j + 1] += src[j + 1] * f;
00844 }
00845 }
00846
00847 EMData *image_fft = image->do_fft();
00848 image_fft->update();
00849 if(image_ctf) {delete image_ctf; image_ctf=0;}
00850 }
00851
00852 EMData * CtfAverager::finish()
00853 {
00854 int j = 0;
00855 for (int y = 0; y < ny; y++) {
00856 for (int x = 0; x < nx / 2; x++, j += 2) {
00857 #ifdef _WIN32
00858 float r = (float) _hypot(x, y - ny / 2.0f);
00859 #else
00860 float r = (float) hypot(x, y - ny / 2.0f);
00861 #endif
00862 int l = static_cast < int >(Util::fast_floor(r));
00863 if (l >= 0 && l < ny / 2) {
00864 int k = y*nx/2 + x;
00865 snri[l] += (tdr[k] + tdi[k]/tn[k]);
00866 snrn[l] += 1;
00867 }
00868 }
00869 }
00870
00871 for (int i = 0; i < ny / 2; i++) {
00872 snri[i] *= nimg / snrn[i];
00873 }
00874
00875 if(strcmp(outfile, "") != 0) {
00876 Util::save_data(0, 1, snri, ny / 2, outfile);
00877 }
00878
00879
00880 float *cd = 0;
00881 if (curves) {
00882 cd = curves->get_data();
00883 }
00884
00885 for (int i = 0; i < Ctf::CTFOS * ny / 2; i++) {
00886 float ctf0 = 0;
00887 for (int j = 0; j < nimg; j++) {
00888 ctf0 += ctfn[j][i];
00889 if (ctf[j][i] == 0) {
00890 ctf[j][i] = 1.0e-12f;
00891 }
00892
00893 if (curves) {
00894 cd[i] += ctf[j][i] * ctfn[j][i];
00895 cd[i + Ctf::CTFOS * ny / 2] += ctfn[j][i];
00896 cd[i + 2 * Ctf::CTFOS * ny / 2] += ctfn[j][i];
00897 }
00898 }
00899
00900 string alg_name = get_name();
00901
00902 if (alg_name == "CtfCW" && need_snr) {
00903 snr[i] = ctf0;
00904 }
00905
00906 float ctf1 = ctf0;
00907 if (alg_name == "CtfCWauto") {
00908 ctf1 = snri[i / Ctf::CTFOS];
00909 }
00910
00911 if (ctf1 <= 0.0001f) {
00912 ctf1 = 0.1f;
00913 }
00914
00915 if (alg_name == "CtfC") {
00916 for (int j = 0; j < nimg; j++) {
00917 ctf[j][i] = exp(-i * i / (filter * filter)) * ctfn[j][i] / (fabs(ctf[j][i]) * ctf1);
00918 }
00919 }
00920 else if (alg_name == "Weighting") {
00921 for (int j = 0; j < nimg; j++) {
00922 ctf[j][i] = ctfn[j][i] / ctf1;
00923 }
00924 }
00925 else if (alg_name == "CtfCW") {
00926 for (int j = 0; j < nimg; j++) {
00927 ctf[j][i] = (ctf1 / (ctf1 + 1)) * ctfn[j][i] / (ctf[j][i] * ctf1);
00928 }
00929 }
00930 else if (alg_name == "CtfCWauto") {
00931 for (int j = 0; j < nimg; j++) {
00932 ctf[j][i] = ctf1 * ctfn[j][i] / (fabs(ctf[j][i]) * ctf0);
00933 }
00934 }
00935 }
00936
00937
00938 if (curves) {
00939 for (int i = 0; i < Ctf::CTFOS * ny / 2; i++) {
00940 cd[i] /= cd[i + Ctf::CTFOS * ny / 2];
00941 }
00942 curves->update();
00943 }
00944
00945 image0_copy->update();
00946
00947 float *result_data = result->get_data();
00948 EMData *tmp_ift = image0_copy->do_ift();
00949 float *tmp_ift_data = tmp_ift->get_data();
00950 memcpy(result_data, tmp_ift_data, (nx - 2) * ny * sizeof(float));
00951
00952 tmp_ift->update();
00953 result->update();
00954
00955 if( image0_copy )
00956 {
00957 delete image0_copy;
00958 image0_copy = 0;
00959 }
00960
00961 if (snri) {
00962 delete[]snri;
00963 snri = 0;
00964 }
00965
00966 if (snrn) {
00967 delete[]snrn;
00968 snrn = 0;
00969 }
00970
00971 if( snri )
00972 {
00973 delete [] snri;
00974 snri = 0;
00975 }
00976 if( snrn )
00977 {
00978 delete [] snrn;
00979 snrn = 0;
00980 }
00981 if( tdr )
00982 {
00983 delete [] tdr;
00984 tdr = 0;
00985 }
00986 if( tdi )
00987 {
00988 delete [] tdi;
00989 tdi = 0;
00990 }
00991 if( tn )
00992 {
00993 delete [] tn;
00994 tn = 0;
00995 }
00996
00997 return result;
00998 }
00999
01000 #if 0
01001 EMData *CtfAverager::average(const vector < EMData * >&image_list) const
01002 {
01003 if (image_list.size() == 0) {
01004 return 0;
01005 }
01006
01007 EMData *image0 = image_list[0];
01008 if (image0->get_zsize() != 1) {
01009 LOGERR("Only 2D images are currently supported");
01010 return 0;
01011 }
01012
01013 string alg_name = get_name();
01014
01015 if (alg_name == "CtfCW" || alg_name == "CtfCWauto") {
01016 if (image0->get_ctf() != 0 && !image0->has_ctff()) {
01017 LOGERR("Attempted CTF Correction with no ctf parameters");
01018 return 0;
01019 }
01020 }
01021 else {
01022 if (image0->get_ctf() != 0) {
01023 LOGERR("Attempted CTF Correction with no ctf parameters");
01024 return 0;
01025 }
01026 }
01027
01028 size_t num_images = image_list.size();
01029 vector < float >*ctf = new vector < float >[num_images];
01030 vector < float >*ctfn = new vector < float >[num_images];
01031 float **src = new float *[num_images];
01032
01033 Ctf::CtfType curve_type = Ctf::CTF_ABS_AMP;
01034 if (alg_name == "CtfCWauto") {
01035 curve_type = Ctf::CTF_AMP;
01036 }
01037
01038 for (size_t i = 0; i < num_images; i++) {
01039 EMData *image = image_list[i]->do_fft();
01040 image->ap2ri();
01041 src[i] = image->get_data();
01042 Ctf *image_ctf = image->get_ctf();
01043 int ny = image->get_ysize();
01044 ctf[i] = image_ctf->compute_1d(ny, curve_type);
01045
01046 if (ctf[i].size() == 0) {
01047 LOGERR("Unexpected CTF correction problem");
01048 return 0;
01049 }
01050
01051 if (sf) {
01052 ctfn[i] = image_ctf->compute_1d(ny, Ctf::CTF_ABS_SNR, sf);
01053 }
01054 else {
01055 ctfn[i] = image_ctf->compute_1d(ny, Ctf::CTF_RELATIVE_SNR);
01056 }
01057
01058 if(image_ctf) {delete image_ctf; image_ctf=0;}
01059 }
01060
01061 EMData *image0_fft = image0->do_fft();
01062
01063 int nx = image0_fft->get_xsize();
01064 int ny = image0_fft->get_ysize();
01065 int nz = image0_fft->get_zsize();
01066
01067 EMData *result = new EMData();
01068 result->set_size(nx - 2, ny, nz);
01069
01070 float *cd = 0;
01071 if (alg_name == "Weighting" && curves) {
01072 if (!sf) {
01073 LOGWARN("CTF curve in file will contain relative, not absolute SNR!");
01074 }
01075 curves->set_size(Ctf::CTFOS * ny / 2, 3, 1);
01076 curves->to_zero();
01077 cd = curves->get_data();
01078 }
01079
01080 float filter = 0;
01081 if (alg_name == "CtfC") {
01082 filter = params["filter"];
01083 if (filter == 0) {
01084 filter = 22.0f;
01085 }
01086 float apix_y = image0->get_attr_dict().get("apix_y");
01087 float ds = 1.0f / (apix_y * ny * Ctf::CTFOS);
01088 filter = 1.0f / (filter * ds);
01089 }
01090
01091 float *snri = 0;
01092 float *snrn = 0;
01093
01094 if (alg_name == "CtfCWauto") {
01095 snri = new float[ny / 2];
01096 snrn = new float[ny / 2];
01097
01098 for (int i = 0; i < ny / 2; i++) {
01099 snri[i] = 0;
01100 snrn[i] = 0;
01101 }
01102
01103 int j = 0;
01104 for (int y = 0; y < ny; y++) {
01105 for (int x = 0; x < nx / 2; x++, j += 2) {
01106 float r = hypot(x, y - ny / 2.0f);
01107 int l = static_cast < int >(Util::fast_floor(r));
01108
01109 if (l >= 0 && l < ny / 2) {
01110 float tdr = 1;
01111 float tdi = 1;
01112 float tn = 1;
01113
01114 for (size_t i = 0; i < num_images; i++) {
01115 tdr *= src[i][j];
01116 tdi *= src[i][j + 1];
01117 tn *= hypot(src[i][j], src[i][j + 1]);
01118 }
01119
01120 tdr += tdi / tn;
01121 snri[l] += tdr;
01122 snrn[l] += 1;
01123 }
01124 }
01125 }
01126
01127 for (int i = 0; i < ny / 2; i++) {
01128 snri[i] *= num_images / snrn[i];
01129 }
01130 if (outfile != "") {
01131 Util::save_data(0, 1, snri, ny / 2, outfile);
01132 }
01133 }
01134
01135 for (int i = 0; i < Ctf::CTFOS * ny / 2; i++) {
01136 float ctf0 = 0;
01137 for (size_t j = 0; j < num_images; j++) {
01138 ctf0 += ctfn[j][i];
01139 if (ctf[j][i] == 0) {
01140 ctf[j][i] = 1.0e-12;
01141 }
01142
01143 if (curves) {
01144 cd[i] += ctf[j][i] * ctfn[j][i];
01145 cd[i + Ctf::CTFOS * ny / 2] += ctfn[j][i];
01146 cd[i + 2 * Ctf::CTFOS * ny / 2] += ctfn[j][i];
01147 }
01148 }
01149
01150 if (alg_name == "CtfCW" && need_snr) {
01151 snr[i] = ctf0;
01152 }
01153
01154 float ctf1 = ctf0;
01155 if (alg_name == "CtfCWauto") {
01156 ctf1 = snri[i / Ctf::CTFOS];
01157 }
01158
01159 if (ctf1 <= 0.0001f) {
01160 ctf1 = 0.1f;
01161 }
01162
01163 if (alg_name == "CtfC") {
01164 for (size_t j = 0; j < num_images; j++) {
01165 ctf[j][i] = exp(-i * i / (filter * filter)) * ctfn[j][i] / (fabs(ctf[j][i]) * ctf1);
01166 }
01167 }
01168 else if (alg_name == "Weighting") {
01169 for (size_t j = 0; j < num_images; j++) {
01170 ctf[j][i] = ctfn[j][i] / ctf1;
01171 }
01172 }
01173 else if (alg_name == "CtfCW") {
01174 for (size_t j = 0; j < num_images; j++) {
01175 ctf[j][i] = (ctf1 / (ctf1 + 1)) * ctfn[j][i] / (ctf[j][i] * ctf1);
01176 }
01177 }
01178 else if (alg_name == "CtfCWauto") {
01179 for (size_t j = 0; j < num_images; j++) {
01180 ctf[j][i] = ctf1 * ctfn[j][i] / (fabs(ctf[j][i]) * ctf0);
01181 }
01182 }
01183 }
01184
01185
01186 if (curves) {
01187 for (int i = 0; i < Ctf::CTFOS * ny / 2; i++) {
01188 cd[i] /= cd[i + Ctf::CTFOS * ny / 2];
01189 }
01190 curves->update();
01191 }
01192
01193 EMData *image0_copy = image0_fft->copy_head();
01194 image0_copy->ap2ri();
01195
01196 float *tmp_data = image0_copy->get_data();
01197
01198 int j = 0;
01199 for (int y = 0; y < ny; y++) {
01200 for (int x = 0; x < nx / 2; x++, j += 2) {
01201 float r = Ctf::CTFOS * sqrt(x * x + (y - ny / 2.0f) * (y - ny / 2.0f));
01202 int l = static_cast < int >(Util::fast_floor(r));
01203 r -= l;
01204
01205 tmp_data[j] = 0;
01206 tmp_data[j + 1] = 0;
01207
01208 for (size_t i = 0; i < num_images; i++) {
01209 float f = 0;
01210 if (l <= Ctf::CTFOS * ny / 2 - 2) {
01211 f = (ctf[i][l] * (1 - r) + ctf[i][l + 1] * r);
01212 }
01213 tmp_data[j] += src[i][j] * f;
01214 tmp_data[j + 1] += src[i][j + 1] * f;
01215 }
01216 }
01217 }
01218
01219 image0_copy->update();
01220
01221 float *result_data = result->get_data();
01222 EMData *tmp_ift = image0_copy->do_ift();
01223 float *tmp_ift_data = tmp_ift->get_data();
01224 memcpy(result_data, tmp_ift_data, (nx - 2) * ny * sizeof(float));
01225
01226 tmp_ift->update();
01227
01228 if( image0_copy )
01229 {
01230 delete image0_copy;
01231 image0_copy = 0;
01232 }
01233
01234 for (size_t i = 0; i < num_images; i++) {
01235 EMData *img = image_list[i]->do_fft();
01236 img->update();
01237 }
01238
01239 if( src )
01240 {
01241 delete[]src;
01242 src = 0;
01243 }
01244
01245 if( ctf )
01246 {
01247 delete[]ctf;
01248 ctf = 0;
01249 }
01250
01251 if( ctfn )
01252 {
01253 delete[]ctfn;
01254 ctfn = 0;
01255 }
01256
01257 if (snri) {
01258 delete[]snri;
01259 snri = 0;
01260 }
01261
01262 if (snrn) {
01263 delete[]snrn;
01264 snrn = 0;
01265 }
01266
01267 result->update();
01268 return result;
01269 }
01270 #endif
01271
01272
01273 void EMAN::dump_averagers()
01274 {
01275 dump_factory < Averager > ();
01276 }
01277
01278 map<string, vector<string> > EMAN::dump_averagers_list()
01279 {
01280 return dump_factory_list < Averager > ();
01281 }