Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

util.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 "byteorder.h"
00037 #include "emassert.h"
00038 #include "emdata.h"
00039 #include "util.h"
00040 #include "marchingcubes.h"
00041 #include "randnum.h"
00042 
00043 #include <fcntl.h>
00044 #include <iomanip>
00045 #include <sstream>
00046 
00047 #include <cstring>
00048 
00049 #include <sys/types.h>
00050 #include <gsl/gsl_linalg.h>
00051 #include <algorithm> // using accumulate, inner_product, transform
00052 
00053 #ifndef WIN32
00054         #include <unistd.h>
00055         #include <sys/param.h>
00056 #else
00057         #include <ctime>
00058         #include <io.h>
00059         #define access _access
00060         #define F_OK 00
00061 #endif  //WIN32
00062 
00063 using namespace std;
00064 using namespace boost;
00065 using namespace EMAN;
00066 
00067 void Util::ap2ri(float *data, size_t n)
00068 {
00069         Assert(n > 0);
00070 
00071         if (!data) {
00072                 throw NullPointerException("pixel data array");
00073         }
00074 
00075         for (size_t i = 0; i < n; i += 2) {
00076                 float f = data[i] * sin(data[i + 1]);
00077                 data[i] = data[i] * cos(data[i + 1]);
00078                 data[i + 1] = f;
00079         }
00080 }
00081 
00082 void Util::flip_complex_phase(float *data, size_t n)
00083 {
00084         Assert(n > 0);
00085 
00086         if (!data) {
00087                 throw NullPointerException("pixel data array");
00088         }
00089 
00090         for (size_t i = 0; i < n; i += 2) {
00091                 data[i + 1] *= -1;
00092         }
00093 }
00094 
00095 void Util::rotate_phase_origin(float *data, size_t nx, size_t ny, size_t nz)
00096 {
00097         if(ny==1 && nz==1) {    //1D, do nothing
00098                 return;
00099         }
00100         else if(ny!=1 && nz==1) {       //2D, rotate vertically by ny/2
00101                 size_t i, j, k, l;
00102                 float re;
00103                 l=ny/2*nx;
00104                 for (i=0; i<ny/2; i++) {
00105                         for (j=0; j<nx; j++) {
00106                                 k=j+i*nx;
00107                                 re=data[k];
00108                                 data[k]=data[k+l];
00109                                 data[k+l]=re;
00110                         }
00111                 }
00112         }
00113         else {  //3D, in the y,z plane, swaps quadrants I,III and II,IV, this is the 'rotation' in y and z
00114                 size_t i, j, k, l, ii, jj;
00115                 char * t=(char *)malloc(sizeof(float)*nx);
00116 
00117                 k=nx*ny*(nz+1)/2;
00118                 l=nx*ny*(nz-1)/2;
00119                 jj=nx*sizeof(float);
00120                 for (j=ii=0; j<nz/2; ++j) {
00121                         for (i=0; i<ny; ++i,ii+=nx) {
00122                                 memcpy(t,data+ii,jj);
00123                                 if (i<ny/2) {
00124                                         memcpy(data+ii,data+ii+k,jj);
00125                                         memcpy(data+ii+k,t,jj);
00126                                 }
00127                                 else {
00128                                         memcpy(data+ii,data+ii+l,jj);
00129                                         memcpy(data+ii+l,t,jj);
00130                                 }
00131                         }
00132                 }
00133                 free(t);
00134         }
00135 }
00136 
00137 int Util::file_lock_wait(FILE * file)
00138 {
00139 #ifdef WIN32
00140         return 1;
00141 #else
00142 
00143         if (!file) {
00144                 throw NullPointerException("Tried to lock NULL file");
00145         }
00146 
00147         int fdes = fileno(file);
00148 
00149         struct flock fl;
00150         fl.l_type = F_WRLCK;
00151         fl.l_whence = SEEK_SET;
00152         fl.l_start = 0;
00153         fl.l_len = 0;
00154 #ifdef WIN32
00155         fl.l_pid = _getpid();
00156 #else
00157         fl.l_pid = getpid();
00158 #endif
00159 
00160 #if defined __sgi
00161         fl.l_sysid = getpid();
00162 #endif
00163 
00164         int err = 0;
00165         if (fcntl(fdes, F_SETLKW, &fl) == -1) {
00166                 LOGERR("file locking error! NFS problem?");
00167 
00168                 int i = 0;
00169                 for (i = 0; i < 5; i++) {
00170                         if (fcntl(fdes, F_SETLKW, &fl) != -1) {
00171                                 break;
00172                         }
00173                         else {
00174 #ifdef WIN32
00175                                 Sleep(1000);
00176 #else
00177                                 sleep(1);
00178 #endif
00179 
00180                         }
00181                 }
00182                 if (i == 5) {
00183                         LOGERR("Fatal file locking error");
00184                         err = 1;
00185                 }
00186         }
00187 
00188         return err;
00189 #endif
00190 }
00191 
00192 
00193 
00194 bool Util::check_file_by_magic(const void *first_block, const char *magic)
00195 {
00196         if (!first_block || !magic) {
00197                 throw NullPointerException("first_block/magic");
00198         }
00199 
00200         const char *buf = static_cast < const char *>(first_block);
00201 
00202         if (strncmp(buf, magic, strlen(magic)) == 0) {
00203                 return true;
00204         }
00205         return false;
00206 }
00207 
00208 bool Util::is_file_exist(const string & filename)
00209 {
00210         if (access(filename.c_str(), F_OK) == 0) {
00211                 return true;
00212         }
00213         return false;
00214 }
00215 
00216 
00217 void Util::flip_image(float *data, size_t nx, size_t ny)
00218 {
00219         if (!data) {
00220                 throw NullPointerException("image data array");
00221         }
00222         Assert(nx > 0);
00223         Assert(ny > 0);
00224 
00225         float *buf = new float[nx];
00226         size_t row_size = nx * sizeof(float);
00227 
00228         for (size_t i = 0; i < ny / 2; i++) {
00229                 memcpy(buf, &data[i * nx], row_size);
00230                 memcpy(&data[i * nx], &data[(ny - 1 - i) * nx], row_size);
00231                 memcpy(&data[(ny - 1 - i) * nx], buf, row_size);
00232         }
00233 
00234         if( buf )
00235         {
00236                 delete[]buf;
00237                 buf = 0;
00238         }
00239 }
00240 
00241 string Util::str_to_lower(const string& s) {
00242         string ret(s);
00243         std::transform(s.begin(),s.end(),ret.begin(), (int (*)(int) ) std::tolower);
00244         return ret;
00245 }
00246 
00247 bool Util::sstrncmp(const char *s1, const char *s2)
00248 {
00249         if (!s1 || !s2) {
00250                 throw NullPointerException("Null string");
00251         }
00252 
00253         if (strncmp(s1, s2, strlen(s2)) == 0) {
00254                 return true;
00255         }
00256 
00257         return false;
00258 }
00259 
00260 string Util::int2str(int n)
00261 {
00262         char s[32] = {'\0'};
00263         sprintf(s, "%d", n);
00264         return string(s);
00265 }
00266 
00267 string Util::get_line_from_string(char **slines)
00268 {
00269         if (!slines || !(*slines)) {
00270                 throw NullPointerException("Null string");
00271         }
00272 
00273         string result = "";
00274         char *str = *slines;
00275 
00276         while (*str != '\n' && *str != '\0') {
00277                 result.push_back(*str);
00278                 str++;
00279         }
00280         if (*str != '\0') {
00281                 str++;
00282         }
00283         *slines = str;
00284 
00285         return result;
00286 }
00287 
00288 vector<EMData *> Util::svdcmp(const vector<EMData *> &data,int nvec) {
00289         int nimg=data.size();
00290         if (nvec==0) nvec=nimg;
00291         vector<EMData *> ret(nvec);
00292         if (nimg==0) return ret;
00293         int pixels=data[0]->get_xsize()*data[0]->get_ysize()*data[0]->get_zsize();
00294 
00295         // Allocate the working space
00296         gsl_vector *work=gsl_vector_alloc(nimg);
00297         gsl_vector *S=gsl_vector_alloc(nimg);
00298         gsl_matrix *A=gsl_matrix_alloc(pixels,nimg);
00299         gsl_matrix *V=gsl_matrix_alloc(nimg,nimg);
00300         gsl_matrix *X=gsl_matrix_alloc(nimg,nimg);
00301 
00302         int im,x,y,z,i;
00303         for (im=0; im<nimg; im++) {
00304                 for (z=0,i=0; z<data[0]->get_zsize(); z++) {
00305                         for (y=0; y<data[0]->get_ysize(); y++) {
00306                                 for (x=0; x<data[0]->get_xsize(); x++,i++) {
00307                                         gsl_matrix_set(A,i,im,data[im]->get_value_at(x,y,z));
00308                                 }
00309                         }
00310                 }
00311         }
00312 
00313         // This calculates the SVD
00314         gsl_linalg_SV_decomp_mod (A,X, V, S, work);
00315 
00316         for (im=0; im<nvec; im++) {
00317                 EMData *a=data[0]->copy_head();
00318                 ret[im]=a;
00319                 for (z=0,i=0; z<data[0]->get_zsize(); z++) {
00320                         for (y=0; y<data[0]->get_ysize(); y++) {
00321                                 for (x=0; x<data[0]->get_xsize(); x++,i++) {
00322                                         a->set_value_at(x,y,z,static_cast<float>(gsl_matrix_get(A,i,im)));
00323                                 }
00324                         }
00325                 }
00326         }
00327         return ret;
00328 }
00329 
00330 bool Util::get_str_float(const char *s, const char *float_var, float *p_val)
00331 {
00332         if (!s || !float_var || !p_val) {
00333                 throw NullPointerException("string float");
00334         }
00335         size_t n = strlen(float_var);
00336         if (strncmp(s, float_var, n) == 0) {
00337                 *p_val = (float) atof(&s[n]);
00338                 return true;
00339         }
00340 
00341         return false;
00342 }
00343 
00344 bool Util::get_str_float(const char *s, const char *float_var, float *p_v1, float *p_v2)
00345 {
00346         if (!s || !float_var || !p_v1 || !p_v2) {
00347                 throw NullPointerException("string float");
00348         }
00349 
00350         size_t n = strlen(float_var);
00351         if (strncmp(s, float_var, n) == 0) {
00352                 sscanf(&s[n], "%f,%f", p_v1, p_v2);
00353                 return true;
00354         }
00355 
00356         return false;
00357 }
00358 
00359 bool Util::get_str_float(const char *s, const char *float_var,
00360                                                  int *p_v0, float *p_v1, float *p_v2)
00361 {
00362         if (!s || !float_var || !p_v0 || !p_v1 || !p_v2) {
00363                 throw NullPointerException("string float");
00364         }
00365 
00366         size_t n = strlen(float_var);
00367         *p_v0 = 0;
00368         if (strncmp(s, float_var, n) == 0) {
00369                 if (s[n] == '=') {
00370                         *p_v0 = 2;
00371                         sscanf(&s[n + 1], "%f,%f", p_v1, p_v2);
00372                 }
00373                 else {
00374                         *p_v0 = 1;
00375                 }
00376                 return true;
00377         }
00378         return false;
00379 }
00380 
00381 bool Util::get_str_int(const char *s, const char *int_var, int *p_val)
00382 {
00383         if (!s || !int_var || !p_val) {
00384                 throw NullPointerException("string int");
00385         }
00386 
00387         size_t n = strlen(int_var);
00388         if (strncmp(s, int_var, n) == 0) {
00389                 *p_val = atoi(&s[n]);
00390                 return true;
00391         }
00392         return false;
00393 }
00394 
00395 bool Util::get_str_int(const char *s, const char *int_var, int *p_v1, int *p_v2)
00396 {
00397         if (!s || !int_var || !p_v1 || !p_v2) {
00398                 throw NullPointerException("string int");
00399         }
00400 
00401         size_t n = strlen(int_var);
00402         if (strncmp(s, int_var, n) == 0) {
00403                 sscanf(&s[n], "%d,%d", p_v1, p_v2);
00404                 return true;
00405         }
00406         return false;
00407 }
00408 
00409 bool Util::get_str_int(const char *s, const char *int_var, int *p_v0, int *p_v1, int *p_v2)
00410 {
00411         if (!s || !int_var || !p_v0 || !p_v1 || !p_v2) {
00412                 throw NullPointerException("string int");
00413         }
00414 
00415         size_t n = strlen(int_var);
00416         *p_v0 = 0;
00417         if (strncmp(s, int_var, n) == 0) {
00418                 if (s[n] == '=') {
00419                         *p_v0 = 2;
00420                         sscanf(&s[n + 1], "%d,%d", p_v1, p_v2);
00421                 }
00422                 else {
00423                         *p_v0 = 1;
00424                 }
00425                 return true;
00426         }
00427         return false;
00428 }
00429 
00430 string Util::change_filename_ext(const string & old_filename,
00431                                                                  const string & ext)
00432 {
00433         Assert(old_filename != "");
00434         if (ext == "") {
00435                 return old_filename;
00436         }
00437 
00438         string filename = old_filename;
00439         size_t dot_pos = filename.rfind(".");
00440         if (dot_pos != string::npos) {
00441                 filename = filename.substr(0, dot_pos+1);
00442         }
00443         else {
00444                 filename = filename + ".";
00445         }
00446         filename = filename + ext;
00447         return filename;
00448 }
00449 
00450 string Util::remove_filename_ext(const string& filename)
00451 {
00452     if (filename == "") {
00453         return "";
00454     }
00455 
00456         char *buf = new char[filename.size()+1];
00457         strcpy(buf, filename.c_str());
00458         char *old_ext = strrchr(buf, '.');
00459         if (old_ext) {
00460                 buf[strlen(buf) - strlen(old_ext)] = '\0';
00461         }
00462         string result = string(buf);
00463         if( buf )
00464         {
00465                 delete [] buf;
00466                 buf = 0;
00467         }
00468         return result;
00469 }
00470 
00471 string Util::sbasename(const string & filename)
00472 {
00473     if (filename == "") {
00474         return "";
00475     }
00476 
00477         char s = '/';
00478 #ifdef _WIN32
00479         s = '\\';
00480 #endif
00481         const char * c = strrchr(filename.c_str(), s);
00482     if (!c) {
00483         return filename;
00484     }
00485         else {
00486                 c++;
00487         }
00488     return string(c);
00489 }
00490 
00491 
00492 string Util::get_filename_ext(const string& filename)
00493 {
00494     if (filename == "") {
00495         return "";
00496     }
00497 
00498         string result = "";
00499         const char *ext = strrchr(filename.c_str(), '.');
00500         if (ext) {
00501                 ext++;
00502                 result = string(ext);
00503         }
00504         return result;
00505 }
00506 
00507 
00508 
00509 void Util::calc_least_square_fit(size_t nitems, const float *data_x, const float *data_y,
00510                                                                  float *slope, float *intercept, bool ignore_zero,float absmax)
00511 {
00512         Assert(nitems > 0);
00513 
00514         if (!data_x || !data_y || !slope || !intercept) {
00515                 throw NullPointerException("null float pointer");
00516         }
00517         double sum = 0;
00518         double sum_x = 0;
00519         double sum_y = 0;
00520         double sum_xx = 0;
00521         double sum_xy = 0;
00522 
00523         for (size_t i = 0; i < nitems; i++) {
00524                 if ((!ignore_zero || (data_x[i] != 0 && data_y[i] != 0))&&(!absmax ||(data_y[i]<absmax && data_y[i]>-absmax))) {
00525                         double y = data_y[i];
00526                         double x = i;
00527                         if (data_x) {
00528                                 x = data_x[i];
00529                         }
00530 
00531                         sum_x += x;
00532                         sum_y += y;
00533                         sum_xx += x * x;
00534                         sum_xy += x * y;
00535                         sum++;
00536                 }
00537         }
00538 
00539         double div = sum * sum_xx - sum_x * sum_x;
00540         if (div == 0) {
00541                 div = 0.0000001f;
00542         }
00543 
00544         *intercept = (float) ((sum_xx * sum_y - sum_x * sum_xy) / div);
00545         *slope = (float) ((sum * sum_xy - sum_x * sum_y) / div);
00546 }
00547 
00548 Vec3f Util::calc_bilinear_least_square(const vector<float> &p) {
00549 unsigned int i;
00550 
00551 // various sums used in the final solution
00552 double Sx=0,Sy=0,Sxy=0,Sxx=0,Syy=0,Sz=0,Sxz=0,Syz=0,S=0;
00553 for (i=0; i<p.size(); i+=3) {
00554         Sx+=p[i];
00555         Sy+=p[i+1];
00556         Sz+=p[i+2];
00557         Sxx+=p[i]*p[i];
00558         Syy+=p[i+1]*p[i+1];
00559         Sxy+=p[i]*p[i+1];
00560         S+=1.0;
00561         Sxz+=p[i]*p[i+2];
00562         Syz+=p[i+1]*p[i+2];
00563 }
00564 double d=S*Sxy*Sxy - 2*Sx*Sxy*Sy + Sxx*Sy*Sy  + Sx*Sx*Syy - S*Sxx*Syy;
00565 
00566 Vec3f ret(0,0,0);
00567 
00568 ret[0]=static_cast<float>(-((Sxy*Sxz*Sy - Sx*Sxz*Syy + Sx*Sxy*Syz - Sxx*Sy*Syz - Sxy*Sxy*Sz +Sxx*Syy*Sz)/d));
00569 ret[1]=static_cast<float>(-((-Sxz*Sy*Sy  + S*Sxz*Syy - S*Sxy*Syz + Sx*Sy*Syz + Sxy*Sy*Sz -Sx*Syy*Sz) /d));
00570 ret[2]=static_cast<float>(-((-S*Sxy*Sxz + Sx*Sxz*Sy - Sx*Sx*Syz + S*Sxx*Syz + Sx*Sxy*Sz -Sxx*Sy*Sz) /d));
00571 
00572 return ret;
00573 }
00574 
00575 void Util::save_data(const vector < float >&x_array, const vector < float >&y_array,
00576                                          const string & filename)
00577 {
00578         Assert(x_array.size() > 0);
00579         Assert(y_array.size() > 0);
00580         Assert(filename != "");
00581 
00582         if (x_array.size() != y_array.size()) {
00583                 LOGERR("array x and array y have different size: %d != %d\n",
00584                            x_array.size(), y_array.size());
00585                 return;
00586         }
00587 
00588         FILE *out = fopen(filename.c_str(), "wb");
00589         if (!out) {
00590                 throw FileAccessException(filename);
00591         }
00592 
00593         for (size_t i = 0; i < x_array.size(); i++) {
00594                 fprintf(out, "%g\t%g\n", x_array[i], y_array[i]);
00595         }
00596         fclose(out);
00597 }
00598 
00599 void Util::save_data(float x0, float dx, const vector < float >&y_array,
00600                                          const string & filename)
00601 {
00602         Assert(dx != 0);
00603         Assert(y_array.size() > 0);
00604         Assert(filename != "");
00605 
00606         FILE *out = fopen(filename.c_str(), "wb");
00607         if (!out) {
00608                 throw FileAccessException(filename);
00609         }
00610 
00611         for (size_t i = 0; i < y_array.size(); i++) {
00612                 fprintf(out, "%g\t%g\n", x0 + dx * i, y_array[i]);
00613         }
00614         fclose(out);
00615 }
00616 
00617 
00618 void Util::save_data(float x0, float dx, float *y_array,
00619                                          size_t array_size, const string & filename)
00620 {
00621         Assert(dx > 0);
00622         Assert(array_size > 0);
00623         Assert(filename != "");
00624 
00625         if (!y_array) {
00626                 throw NullPointerException("y array");
00627         }
00628 
00629         FILE *out = fopen(filename.c_str(), "wb");
00630         if (!out) {
00631                 throw FileAccessException(filename);
00632         }
00633 
00634         for (size_t i = 0; i < array_size; i++) {
00635                 fprintf(out, "%g\t%g\n", x0 + dx * i, y_array[i]);
00636         }
00637         fclose(out);
00638 }
00639 
00640 
00641 void Util::sort_mat(float *left, float *right, int *leftPerm, int *rightPerm)
00642 // Adapted by PRB from a macro definition posted on SourceForge by evildave
00643 {
00644         float *pivot ; int *pivotPerm;
00645 
00646         {
00647                 float *pLeft  =   left; int *pLeftPerm  =  leftPerm;
00648                 float *pRight =  right; int *pRightPerm = rightPerm;
00649                 float scratch =  *left; int scratchPerm = *leftPerm;
00650 
00651                 while (pLeft < pRight) {
00652                         while ((*pRight > scratch) && (pLeft < pRight)) {
00653                                 pRight--; pRightPerm--;
00654                         }
00655                         if (pLeft != pRight) {
00656                                 *pLeft = *pRight; *pLeftPerm = *pRightPerm;
00657                                 pLeft++; pLeftPerm++;
00658                         }
00659                         while ((*pLeft < scratch) && (pLeft < pRight)) {
00660                                 pLeft++; pLeftPerm++;
00661                         }
00662                         if (pLeft != pRight) {
00663                                 *pRight = *pLeft; *pRightPerm = *pLeftPerm;
00664                                 pRight--; pRightPerm--;
00665                         }
00666                 }
00667                 *pLeft = scratch; *pLeftPerm = scratchPerm;
00668                 pivot = pLeft; pivotPerm= pLeftPerm;
00669         }
00670         if (left < pivot) {
00671                 sort_mat(left, pivot - 1,leftPerm,pivotPerm-1);
00672         }
00673         if (right > pivot) {
00674                 sort_mat(pivot + 1, right,pivotPerm+1,rightPerm);
00675         }
00676 }
00677 
00678 void Util::set_randnum_seed(unsigned long int seed)
00679 {
00680         Randnum* randnum = Randnum::Instance();
00681         randnum->set_seed(seed);
00682 }
00683 
00684 unsigned long int Util::get_randnum_seed()
00685 {
00686         Randnum* randnum = Randnum::Instance();
00687         return  randnum->get_seed();
00688 }
00689 
00690 int Util::get_irand(int lo, int hi)
00691 {
00692         Randnum* randnum = Randnum::Instance();
00693         return randnum->get_irand(lo, hi);
00694 }
00695 
00696 float Util::get_frand(int lo, int hi)
00697 {
00698         return get_frand((float)lo, (float)hi);
00699 }
00700 
00701 float Util::get_frand(float lo, float hi)
00702 {
00703         Randnum* randnum = Randnum::Instance();
00704         return randnum->get_frand(lo, hi);
00705 }
00706 
00707 float Util::get_frand(double lo, double hi)
00708 {
00709         Randnum* randnum = Randnum::Instance();
00710         return randnum->get_frand(lo, hi);
00711 }
00712 
00713 float Util::hypot_fast(int x, int y)
00714 {
00715 static float *mem = (float *)malloc(4*128*128);
00716 static int dim = 0;
00717 x=abs(x);
00718 y=abs(y);
00719 
00720 if (x>=dim || y>=dim) {
00721         if (x>2048 || y>2048) return (float)hypot((float)x,(float)y);           // We won't cache anything bigger than 4096^2
00722         dim=x>=dim?x+1:dim;
00723         dim=y>=dim?y+1:dim;
00724         mem=(float*)realloc(mem,4*dim*dim);
00725         for (int y=0; y<dim; y++) {
00726                 for (int x=0; x<dim; x++) {
00727 #ifdef  _WIN32
00728                         mem[x+y*dim]=(float)_hypot((float)x,(float)y);
00729 #else
00730                         mem[x+y*dim]=hypot((float)x,(float)y);
00731 #endif
00732                 }
00733         }
00734 }
00735 
00736 return mem[x+y*dim];
00737 }
00738 
00739 short Util::hypot_fast_int(int x, int y)
00740 {
00741 static short *mem = (short *)malloc(2*128*128);
00742 static int dim = 0;
00743 x=abs(x);
00744 y=abs(y);
00745 
00746 if (x>=dim || y>=dim) {
00747         if (x>4095 || y>4095) return (short)hypot((float)x,(float)y);           // We won't cache anything bigger than 4096^2
00748         dim=x>=dim?x+1:dim;
00749         dim=y>=dim?y+1:dim;
00750         mem=(short*)realloc(mem,2*dim*dim);
00751         for (int y=0; y<dim; y++) {
00752                 for (int x=0; x<dim; x++) {
00753 #ifdef  _WIN32
00754                         mem[x+y*dim]=(short)Util::round(_hypot((float)x,(float)y));
00755 #else
00756                         mem[x+y*dim]=(short)Util::round(hypot((float)x,(float)y));
00757 #endif
00758                 }
00759         }
00760 }
00761 
00762 return mem[x+y*dim];
00763 }
00764 
00765 // Uses a precached table to return a good approximate to exp(x)
00766 // if outside the cached range, uses regular exp
00767 float Util::fast_exp(const float &f) {
00768 static float *mem = (float *)malloc(sizeof(float)*1000);
00769 static bool needinit=true;
00770 
00771 if (needinit) {
00772         needinit=false;
00773         for (int i=0; i<1000; i++) mem[i]=(float)exp(-i/50.0);
00774 }
00775 if (f>0 || f<-19.98) return exp(f);
00776 int g=(int)(-f*50.0+0.5);
00777 
00778 return mem[g];
00779 }
00780 
00781 // Uses a precached table to return a good approximate to acos(x)
00782 // tolerates values outside the -1 - 1 domain by clamping to PI,0
00783 float Util::fast_acos(const float &f) {
00784 if (f>=1.0) return 0.0;
00785 if (f<=-1.0) return M_PI;
00786 
00787 static float *mem = (float *)malloc(sizeof(float)*2001);
00788 static bool needinit=true;
00789 
00790 
00791 if (needinit) {
00792         needinit=false;
00793         for (int i=0; i<=2000; i++) mem[i]=(float)acos(i/1000.0-1.0);
00794 }
00795 float f2=f*1000.0f+1000.0f;
00796 
00797 int g=(int)(f2+.5);
00798 
00799 return mem[g];
00800 
00801 // This version interpolates, but is slower
00802 /*int g=(int)f2;
00803 f2-=g;
00804 return mem[g+1]*f2+mem[g]*(1.0-f2);*/
00805 }
00806 
00807 
00808 float Util::get_gauss_rand(float mean, float sigma)
00809 {
00810         Randnum* randnum = Randnum::Instance();
00811         return randnum->get_gauss_rand(mean, sigma);
00812 }
00813 
00814 void Util::find_max(const float *data, size_t nitems, float *max_val, int *max_index)
00815 {
00816         Assert(nitems > 0);
00817 
00818         if (!data || !max_val || !max_index) {
00819                 throw NullPointerException("data/max_val/max_index");
00820         }
00821         float max = -FLT_MAX;
00822         int m = 0;
00823 
00824         for (size_t i = 0; i < nitems; i++) {
00825                 if (data[i] > max) {
00826                         max = data[i];
00827                         m = (int)i;
00828                 }
00829         }
00830 
00831         *max_val = (float)m;
00832 
00833         if (max_index) {
00834                 *max_index = m;
00835         }
00836 }
00837 
00838 void Util::find_min_and_max(const float *data, size_t nitems,
00839                                                         float *max_val, float *min_val,
00840                                                         int *max_index, int *min_index)
00841 {
00842         Assert(nitems > 0);
00843 
00844         if (!data || !max_val || !min_val || !max_index || !min_index) {
00845                 throw NullPointerException("data/max_val/min_val/max_index/min_index");
00846         }
00847         float max = -FLT_MAX;
00848         float min = FLT_MAX;
00849         int max_i = 0;
00850         int min_i = 0;
00851 
00852         for (size_t i = 0; i < nitems; i++) {
00853                 if (data[i] > max) {
00854                         max = data[i];
00855                         max_i = (int)i;
00856                 }
00857                 if (data[i] < min) {
00858                         min = data[i];
00859                         min_i = (int)i;
00860                 }
00861         }
00862 
00863         *max_val = max;
00864         *min_val = min;
00865 
00866         if (min_index) {
00867                 *min_index = min_i;
00868         }
00869 
00870         if (max_index) {
00871                 *max_index = max_i;
00872         }
00873 
00874 }
00875 
00876 Dict Util::get_stats( const vector<float>& data )
00877 {
00878         // Note that this is a heavy STL approach using generic algorithms - some memory could be saved
00879         // using plain c style code, as in get_stats_cstyle below
00880 
00881         if (data.size() == 0) EmptyContainerException("Error, attempting to call get stats on an empty container (vector<double>)");
00882 
00883         double sum = accumulate(data.begin(), data.end(), 0.0);
00884 
00885         double mean = sum / static_cast<double> (data.size());
00886 
00887         double std_dev = 0.0, skewness = 0.0, kurtosis = 0.0;
00888 
00889         if (data.size() > 1)
00890         {
00891                 // read mm is "minus_mean"
00892                 vector<double> data_mm(data.size());
00893                 // read ts as "then squared"
00894                 vector<double> data_mm_sq(data.size());
00895 
00896                 // Subtract the mean from the data and store it in data_mm
00897                 transform(data.begin(), data.end(), data_mm.begin(), std::bind2nd(std::minus<double>(), mean));
00898 
00899                 // Get the square of the data minus the mean and store it in data_mm_sq
00900                 transform(data_mm.begin(), data_mm.end(), data_mm.begin(), data_mm_sq.begin(), std::multiplies<double>());
00901 
00902                 // Get the sum of the squares for the calculation of the standard deviation
00903                 double square_sum = accumulate(data_mm_sq.begin(), data_mm_sq.end(), 0.0);
00904 
00905                 //Calculate teh standard deviation
00906                 std_dev = sqrt(square_sum / static_cast<double>(data.size()-1));
00907                 double std_dev_sq = std_dev * std_dev;
00908 
00909                 // The numerator for the skewness fraction, as defined in http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm
00910                 double cubic_sum = inner_product(data_mm.begin(), data_mm.end(),data_mm_sq.begin(), 0.0);
00911 
00912                 // The numerator for the kurtosis fraction, as defined in http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm
00913                 double quartic_sum = inner_product(data_mm_sq.begin(), data_mm_sq.end(),data_mm_sq.begin(), 0.0);
00914 
00915                 // Finalize the calculation of the skewness and kurtosis, as defined in
00916                 // http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm
00917                 skewness = cubic_sum / ((data.size()-1) * std_dev_sq * std_dev );
00918                 kurtosis = quartic_sum / ((data.size()-1) * std_dev_sq * std_dev_sq );
00919 
00920         }
00921 
00922         Dict parms;
00923         parms["mean"] = mean;
00924         parms["std_dev"] = std_dev;
00925         parms["skewness"] = skewness;
00926         parms["kurtosis"] = kurtosis;
00927 
00928         return parms;
00929 }
00930 
00931 
00932 Dict Util::get_stats_cstyle( const vector<float>& data )
00933 {
00934         if (data.size() == 0) EmptyContainerException("Error, attempting to call get stats on an empty container (vector<double>)");
00935 
00936         double square_sum = 0.0, sum = 0.0, cube_sum = 0.0, quart_sum = 0.0;
00937         for( vector<float>::const_iterator it = data.begin(); it != data.end(); ++it )
00938         {
00939                 double val = *it;
00940                 double square = val*val;
00941                 quart_sum += square*square;
00942                 cube_sum += square*val;
00943                 square_sum += square;
00944                 sum += val;
00945         }
00946 
00947         double mean = sum/(double)data.size();
00948 
00949         double std_dev = 0.0, skewness = 0.0, kurtosis = 0.0;
00950 
00951         if (data.size() > 1)
00952         {
00953                 // The standard deviation is calculated here
00954                 std_dev = sqrt( (square_sum - mean*sum)/(double)(data.size()-1));
00955 
00956                 double square_mean = mean*mean;
00957                 double cube_mean = mean*square_mean;
00958 
00959                 double square_std_dev = std_dev*std_dev;
00960 
00961                 // This is the numerator of the skewness fraction, if you expand the brackets, as defined in
00962                 // http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm
00963                 double cubic_sum = cube_sum - 3*square_sum*mean + 3*sum*square_mean - cube_mean*data.size();
00964                 // Complete the skewness fraction
00965                 skewness = cubic_sum/((data.size()-1)*square_std_dev*std_dev);
00966 
00967                 // This is the numerator of the kurtosis fraction, if you expand the brackets, as defined in
00968                 // http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm
00969                 double quartic_sum = quart_sum - 4*cube_sum*mean + 6*square_sum*square_mean - 4*sum*cube_mean  + square_mean*square_mean*data.size();
00970                 // Complete the kurtosis fraction
00971                 kurtosis = quartic_sum /( (data.size()-1)*square_std_dev*square_std_dev);
00972         }
00973 
00974         Dict parms;
00975         parms["mean"] = mean;
00976         parms["std_dev"] = std_dev;
00977         parms["skewness"] = skewness;
00978         parms["kurtosis"] = kurtosis;
00979 
00980         return parms;
00981 }
00982 
00983 
00984 int Util::calc_best_fft_size(int low)
00985 {
00986         Assert(low >= 0);
00987 
00988         //array containing valid sizes <1024 for speed
00989         static char *valid = NULL;
00990 
00991         if (!valid) {
00992                 valid = (char *) calloc(4096, 1);
00993 
00994                 for (float i2 = 1; i2 < 12.0; i2 += 1.0) {
00995 
00996                         float f1 = pow((float) 2.0, i2);
00997                         for (float i3 = 0; i3 < 8.0; i3 += 1.0) {
00998 
00999                                 float f2 = pow((float) 3.0, i3);
01000                                 for (float i5 = 0; i5 < 6.0; i5 += 1.0) {
01001 
01002                                         float f3 = pow((float) 5.0, i5);
01003                                         for (float i7 = 0; i7 < 5.0; i7 += 1.0) {
01004 
01005                                                 float f = f1 * f2 * f3 * pow((float) 7.0, i7);
01006                                                 if (f <= 4095.0) {
01007                                                         int n = (int) f;
01008                                                         valid[n] = 1;
01009                                                 }
01010                                         }
01011                                 }
01012                         }
01013                 }
01014         }
01015 
01016         for (int i = low; i < 4096; i++) {
01017                 if (valid[i]) {
01018                         return i;
01019                 }
01020         }
01021 
01022         LOGERR("Sorry, can only find good fft sizes up to 4096 right now.");
01023 
01024         return 1;
01025 }
01026 
01027 #ifndef _WIN32
01028 #include <sys/types.h>
01029 #include <sys/socket.h>
01030 #include "byteorder.h"
01031 // This is the structure of a broadcast packet
01032 // Transmitter assumes little endian
01033 struct BPKT {
01034         char hdr[4];
01035         int uid;        // user id on transmitter
01036         int len;        // length of total object
01037         int oseq;       // object id
01038         int pseq;       // packet id within object
01039         unsigned char data[1024]; };
01040 
01041 string Util::recv_broadcast(int sock) {
01042 //      struct sockaddr_in sadr = { AF_INET, 9989, INADDR_ANY};
01043 //      int sock=socket(AF_INET,SOCK_DGRAM,0);
01044 //      if (bind(sock,&sadr,sizeof(sockaddr_in))) return string();
01045 
01046         if (ByteOrder::is_host_big_endian()) {
01047                 printf("No cache mirroring on Big endian machines yet\n");
01048                 return string();        // FIXME: no support for big endian hosts
01049         }
01050 
01051         BPKT pkt;
01052         string ret;
01053         vector<char> fill;
01054         int obj=-1;
01055         unsigned int i=0;
01056 //      printf ("Listening\n");
01057 
01058         while (1) {
01059                 int l = recv(sock,&pkt,1044,0);
01060                 if (l<=0) {
01061                         if (obj!=-1) printf("Timeout with incomplete obj %d  %d/%d\n",obj,i,(int)fill.size());
01062                         return string();                // probably a timeout
01063                 }
01064                 if (l<20) {
01065                         printf("Bad packet from broadcast");
01066                         continue;
01067                 }
01068 
01069                 if (strncmp(pkt.hdr,"EMAN",4)!=0) continue;
01070 
01071                 // new object coming in
01072                 if (obj!=pkt.oseq) {
01073                         obj=pkt.oseq;
01074                         ret.resize(pkt.len);
01075                         fill.resize((pkt.len-1)/1024+1);
01076                         for (i=0; i<fill.size(); i++) fill[i]=0;
01077                 }
01078                 if (obj==-1) printf("Something wierd happened. please report\n");
01079 
01080                 // copy the packet into the output buffer
01081                 fill[pkt.pseq]=1;
01082                 ret.replace(pkt.pseq*1024,l-20,(char *)pkt.data,l-20);
01083 
01084                 // see if we got everything
01085                 for (i=0; i<fill.size(); i++) {
01086                         if (fill[i]!=1) break;
01087                 }
01088 //              printf("\t\t\tObj %d  %d/%d      \r",obj,i,(int)fill.size());
01089                 fflush(stdout);
01090 
01091                 if (i==fill.size()) return ret;         // Yea !  We got a good packet
01092         }
01093 
01094 }
01095 #endif  //_WIN32
01096 
01097 string Util::get_time_label()
01098 {
01099         time_t t0 = time(0);
01100         struct tm *t = localtime(&t0);
01101         char label[32];
01102         sprintf(label, "%d/%02d/%04d %d:%02d",
01103                         t->tm_mon + 1, t->tm_mday, t->tm_year + 1900, t->tm_hour, t->tm_min);
01104         return string(label);
01105 }
01106 
01107 
01108 void Util::set_log_level(int argc, char *argv[])
01109 {
01110         if (argc > 1 && strncmp(argv[1], "-v", 2) == 0) {
01111                 char level_str[32];
01112                 strcpy(level_str, argv[1] + 2);
01113                 Log::LogLevel log_level = (Log::LogLevel) atoi(level_str);
01114                 Log::logger()->set_level(log_level);
01115         }
01116 }
01117 
01118 void Util::printMatI3D(MIArray3D& mat, const string str, ostream& out) {
01119         // Note: Don't need to check if 3-D because 3D is part of
01120         //       the MIArray3D typedef.
01121         out << "Printing 3D Integer data: " << str << std::endl;
01122         const multi_array_types::size_type* sizes = mat.shape();
01123         int nx = sizes[0], ny = sizes[1], nz = sizes[2];
01124         const multi_array_types::index* indices = mat.index_bases();
01125         int bx = indices[0], by = indices[1], bz = indices[2];
01126         for (int iz = bz; iz < nz+bz; iz++) {
01127                 cout << "(z = " << iz << " slice)" << endl;
01128                 for (int ix = bx; ix < nx+bx; ix++) {
01129                         for (int iy = by; iy < ny+by; iy++) {
01130                                 cout << setiosflags(ios::fixed) << setw(5)
01131                                          << mat[ix][iy][iz] << "  ";
01132                         }
01133                         cout << endl;
01134                 }
01135         }
01136 }
01137 
01138 #include <gsl/gsl_matrix.h>
01139 #include <gsl/gsl_vector.h>
01140 #include <gsl/gsl_linalg.h>
01141 
01142 void printmatrix( gsl_matrix* M, const int n, const int m, const string& message = "")
01143 {
01144         cout << message << endl;
01145         for(int i = 0; i < n; ++i ){
01146                 for (int j = 0; j < m; ++j ){
01147                         cout << gsl_matrix_get(M,i,j) << "\t";
01148                 }
01149                 cout << endl;
01150         }
01151 }
01152 
01153 void printvector( gsl_vector* M, const int n, const string& message = "")
01154 {
01155         cout << message << endl;
01156         for(int i = 0; i < n; ++i ){
01157                 cout << gsl_vector_get(M,i) << "\t";
01158         }
01159         cout << endl;
01160 }
01161 
01162 float* Util::getBaldwinGridWeights( const int& freq_cutoff, const float& P, const float& r, const float& dfreq, const float& alpha, const float& beta)
01163 {
01164         int i = 0;
01165         int discs = (int)(1+2*freq_cutoff/dfreq);
01166 
01167         float*  W = new float[discs];
01168 
01169         int fc = (int)(2*freq_cutoff + 1);
01170         gsl_matrix* M = gsl_matrix_calloc(fc,fc);
01171 
01172         gsl_vector* rhs = gsl_vector_calloc(fc);
01173         cout << i++ << endl;
01174         for(int k = -freq_cutoff; k <= freq_cutoff; ++k){
01175                 for(int kp = -freq_cutoff; kp <= freq_cutoff; ++kp){
01176                         int kdiff =abs( k-kp);
01177                         int evenoddfac = ( kdiff % 2 == 0 ? 1 : -1);
01178 
01179                         if (kdiff !=0){
01180                                 float val = sin(M_PI*(float)kdiff*r)/(sin(M_PI*(float)kdiff/(float)P))*(alpha+2.0f*beta*evenoddfac);
01181                                 gsl_matrix_set(M,int(k+freq_cutoff),int(kp+freq_cutoff),val);
01182                         }
01183                 }
01184                 gsl_matrix_set(M,int(k+freq_cutoff),int(k+freq_cutoff),r*P* (alpha+2*beta));
01185                 float val = alpha*sin(M_PI*k*r)/(sin(M_PI*(float)k/(float)P));
01186                 if (k!=0) {
01187                         gsl_vector_set(rhs,int(k+freq_cutoff),val);
01188                 }
01189         }
01190         printmatrix(M,fc,fc,"M");
01191 
01192         gsl_vector_set(rhs,int(freq_cutoff),alpha*r*P);
01193         gsl_matrix* V = gsl_matrix_calloc(fc,fc);
01194         gsl_vector* S = gsl_vector_calloc(fc);
01195         gsl_vector* soln = gsl_vector_calloc(fc);
01196         gsl_linalg_SV_decomp(M,V,S,soln);
01197 
01198         gsl_linalg_SV_solve(M, V, S, rhs, soln); // soln now runs from -freq_cutoff to + freq_cutoff
01199         printvector(soln,fc,"soln");
01200 
01201         // we want to solve for W, which ranges from -freq_cutoff to +freq_cutoff in steps of dfreq                            2
01202         int Count=0;
01203         for(float q = (float)(-freq_cutoff); q <= (float)(freq_cutoff); q+= dfreq){
01204                 float temp=0;
01205                 for(int k = -freq_cutoff; k <= freq_cutoff; ++k){
01206                         float dtemp;
01207                         if (q!=k) {
01208                                 dtemp=(1/(float) P)* (float)gsl_vector_get(soln,int(k+freq_cutoff))  * sin(M_PI*(q-k))/sin(M_PI*(q-k)/((float) P));
01209                         } else{
01210                                 dtemp = (1/(float) P)* (float)gsl_vector_get(soln,int(k+freq_cutoff))  * P;
01211                         }
01212                         temp +=dtemp;
01213                 }
01214                 W[Count]=temp;
01215                 cout << W[Count] << " ";
01216                 Count+=1;
01217         }
01218         cout << endl;
01219         return W;
01220 }
01221 
01222 
01223 void Util::equation_of_plane(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3, float * plane )
01224 {
01225         int x=0,y=1,z=2;
01226         plane[0] = p1[y]*(p2[z]-p3[z])+p2[y]*(p3[z]-p1[z])+p3[y]*(p1[z]-p2[z]);
01227         plane[1] = p1[z]*(p2[x]-p3[x])+p2[z]*(p3[x]-p1[x])+p3[z]*(p1[x]-p2[x]);
01228         plane[2] = p1[x]*(p2[y]-p3[y])+p2[x]*(p3[y]-p1[y])+p3[x]*(p1[y]-p2[y]);
01229         plane[3] = p1[x]*(p2[y]*p3[z]-p3[y]*p2[z])+p2[x]*(p3[y]*p1[z]-p1[y]*p3[z])+p3[x]*(p1[y]*p2[z]-p2[y]*p1[z]);
01230         plane[3] = -plane[3];
01231 }
01232 
01233 
01234 bool Util::point_is_in_triangle_2d(const Vec2f& p1, const Vec2f& p2, const Vec2f& p3,const Vec2f& point)
01235 {
01236 
01237         Vec2f u = p2 - p1;
01238         Vec2f v = p3 - p1;
01239         Vec2f w = point - p1;
01240 
01241         float udotu = u.dot(u);
01242         float udotv = u.dot(v);
01243         float udotw = u.dot(w);
01244         float vdotv = v.dot(v);
01245         float vdotw = v.dot(w);
01246 
01247         float d = 1.0f/(udotv*udotv - udotu*vdotv);
01248         float s = udotv*vdotw - vdotv*udotw;
01249         s *= d;
01250 
01251         float t = udotv*udotw - udotu*vdotw;
01252         t *= d;
01253 
01254         // We've done a few multiplications, so detect when there are tiny residuals that may throw off the final
01255         // decision
01256         if (fabs(s) < Transform::ERR_LIMIT ) s = 0;
01257         if (fabs(t) < Transform::ERR_LIMIT ) t = 0;
01258 
01259         if ( fabs((fabs(s)-1.0)) < Transform::ERR_LIMIT ) s = 1;
01260         if ( fabs((fabs(t)-1.0)) < Transform::ERR_LIMIT ) t = 1;
01261 
01262 //      cout << "s and t are " << s << " " << t << endl;
01263 
01264         // The final decision, if this is true then we've hit the jackpot
01265         if ( s >= 0 && t >= 0 && (s+t) <= 1 ) return true;
01266         else return false;
01267 }
01268 
01269 bool Util::point_is_in_convex_polygon_2d(const Vec2f& p1, const Vec2f& p2, const Vec2f& p3, const Vec2f& p4,const Vec2f& actual_point)
01270 {
01271 
01272         if (point_is_in_triangle_2d(p1,p2,p4,actual_point)) return true;
01273         else return point_is_in_triangle_2d(p3,p2,p4,actual_point);
01274 }
01275 
01276 /*
01277 Dict Util::get_isosurface(EMData * image, float surface_palue, bool smooth)
01278 {
01279         if (image->get_ndim() != 3) {
01280                 throw ImageDimensionException("3D only");
01281         }
01282 
01283         MarchingCubes * mc = new MarchingCubes(image, smooth);
01284         mc->set_surface_palue(surface_palue);
01285 
01286         Dict d;
01287         if(smooth) {
01288                 d.put("points", *(mc->get_points()));
01289                 d.put("faces", *(mc->get_faces()));
01290                 d.put("normals", *(mc->get_normalsSm()));
01291         }
01292         else {
01293                 d.put("points", *(mc->get_points()));
01294                 d.put("faces", *(mc->get_faces()));
01295                 d.put("normals", *(mc->get_normals()));
01296         }
01297 
01298         delete mc;
01299         mc = 0;
01300 
01301         return d;
01302 }
01303 */

Generated on Thu Dec 9 13:45:51 2010 for EMAN2 by  doxygen 1.3.9.1