averager.cpp

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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         // These commented out until we're happy they're working. (d.woolford, Feb 3rd 2009)
00051 //      force_add(&CtfCAverager::NEW);
00052 //      force_add(&CtfCWAverager::NEW);
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         /*move max out of initializer list, since this max(0) is considered as a macro
00301          * in Visual Studio, which we defined somewhere else*/
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;                     // FIXME - this is a temporary fixed B-factor which does a (very) little sharpening
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; // return to its original value
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                 // we're only using the real component, and we need to start with 1.0
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 /*      EMData *tmp=result->do_ift();
00536         tmp->write_image("ctfcw.hdf",0);
00537         delete tmp;
00538 
00539         tmp=snrsum->do_ift();
00540         tmp->write_image("ctfcw.hdf",1);
00541         delete tmp;*/
00542 
00543 //      snrsum->write_image("snrsum.hdf",-1);
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];              // snrsd contains total SNR+1
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 }

Generated on Sat Nov 21 02:19:14 2009 for EMAN2 by  doxygen 1.5.6