36#include "sparx/analyzer_sparx.h"
39#include "sparx/lapackblas.h"
40#include "sparx/varimax.h"
46 const string PCAsmall::NAME =
"pca";
47 const string PCAlarge::NAME =
"pca_large";
48 const string varimax::NAME =
"varimax";
57 force_add<PCAsmall>();
58 force_add<PCAlarge>();
60 force_add<InertiaMatrixAnalyzer>();
61 force_add<ShapeAnalyzer>();
62 force_add<KMeansAnalyzer>();
63 force_add<SVDAnalyzer>();
64 force_add<CircularAverageAnalyzer>();
69int Analyzer::insert_images_list(vector<EMData *> image_list)
71 vector<EMData *>::const_iterator iter;
72 for(iter=image_list.begin(); iter!=image_list.end(); ++iter) {
85 int nx=
images[0]->get_xsize();
86 int ny=
images[0]->get_ysize();
87 int nz=
images[0]->get_zsize();
90 if (
verbose>0) printf(
"Inertia volume size: %d %d %d\n",nx,ny,nz);
92 for (
int z=0; z<nz; z++) {
93 for (
int y=0;
y<ny;
y++) {
94 for (
int x=0;
x<nx;
x++) {
98 float v=
images[0]->get_value_at(
x,
y,z);
99 mx->set_value_at(0,0,mx->get_value_at(0,0)+v*(yy*yy+zz*zz));
100 mx->set_value_at(0,1,mx->get_value_at(0,1)+v*(-xx*yy));
101 mx->set_value_at(0,2,mx->get_value_at(0,2)+v*(-xx*zz));
102 mx->set_value_at(1,0,mx->get_value_at(1,0)+v*(-xx*yy));
103 mx->set_value_at(1,1,mx->get_value_at(1,1)+v*(zz*zz+xx*xx));
104 mx->set_value_at(1,2,mx->get_value_at(1,2)+v*(-yy*zz));
105 mx->set_value_at(2,0,mx->get_value_at(2,0)+v*(-xx*zz));
106 mx->set_value_at(2,1,mx->get_value_at(2,1)+v*(-yy*zz));
107 mx->set_value_at(2,2,mx->get_value_at(2,2)+v*(xx*xx+yy*yy));
111 mx->mult(1.0f/(nx*ny*nz));
114 printf(
"%1.3g\t%1.3g\t%1.3g\n",mx->get_value_at(0,0),mx->get_value_at(1,0),mx->get_value_at(2,0));
115 printf(
"%1.3g\t%1.3g\t%1.3g\n",mx->get_value_at(0,1),mx->get_value_at(1,1),mx->get_value_at(2,1));
116 printf(
"%1.3g\t%1.3g\t%1.3g\n",mx->get_value_at(0,2),mx->get_value_at(1,2),mx->get_value_at(2,2));
129 int nx=
images[0]->get_xsize();
130 int ny=
images[0]->get_ysize();
131 int nz=
images[0]->get_zsize();
134 if (
verbose>0) printf(
"Shape size: %d %d %d\n",nx,ny,nz);
136 for (
int z=0; z<nz; z++) {
137 for (
int y=0;
y<ny;
y++) {
138 for (
int x=0;
x<nx;
x++) {
142 float v=
images[0]->get_value_at(
x,
y,z);
143 mx->set_value_at(0,0,mx->get_value_at(0,0)+v*(xx*xx));
144 mx->set_value_at(1,0,mx->get_value_at(1,0)+v*(yy*yy));
145 mx->set_value_at(2,0,mx->get_value_at(2,0)+v*(zz*zz));
146 mx->set_value_at(3,0,mx->get_value_at(3,0)+v*(xx*xx+yy*yy+zz*zz));
148 mx->set_value_at(0,1,mx->get_value_at(0,0)+v*abs(xx));
149 mx->set_value_at(1,1,mx->get_value_at(1,0)+v*abs(yy));
150 mx->set_value_at(2,1,mx->get_value_at(2,0)+v*abs(zz));
151 mx->set_value_at(3,1,mx->get_value_at(3,0)+v*(
float)
sqrt((
float)(xx*xx+yy*yy+zz*zz)));
155 mx->mult(1.0f/(nx*ny*nz));
176if (
ncls<=1)
return vector<EMData *>();
189 for (
int i=0; i<nptcl; i++)
images[i]->
set_attr(
"is_ok_center",(
int)5);
199 for (
int i=0; i<
ncls; i++) {
204else if (seedmode==1) {
210 for (
int i=0; i<nptcl; i++) {
211 float m =
images[i]->get_attr(
"mean");
212 if (m<minv) { minv=m; min=
images[i]; }
213 if (m>maxv) { maxv=m; max=
images[i]; }
219 for (
int i=1; i<
ncls-1; i++) {
223 tmp->mult(i/(
ncls-1.0f));
258vector<int> repr(
ncls);
260for (
int i=0; i<
ncls; i++) {
264 centers[i]->set_attr(
"worst_ptcldist",0.0f);
268for (
int i=0; i<nptcl; i++) {
269 int cid=
images[i]->get_attr(
"class_id");
275 float imdist=
images[i]->get_attr(
"class_cendist");
277 centers[cid]->set_attr(
"worst_ptcldist",imdist);
278 centers[cid]->set_attr(
"worst_ptcl",i);
283for (
int i=0; i<
ncls; i++) {
289 for (
int j=0; j<nptcl; j++) {
291 if (
verbose) printf(
"outlier: %d\n",j);
299 for (
int j=0; j<nptcl; j++) {
310 centers[i]->mult((
float)1.0/(
float)(repr[i]));
311 centers[i]->set_attr(
"ptcl_repr",repr[i]);
313 centers[i+
ncls]->mult((
float)1.0/(
float)(repr[i]));
320 if (
verbose>1) printf(
"%d(%d)\t",i,(
int)repr[i]);
334for (i=0; i<
ncls; i++) {
342 for (
int i=0; i<nptcl; i++) {
if ((
int)
images[i]->
get_attr(
"class_id")!=
nclstot-1) goodcen.push_back(i); }
346 for (
int i=0; i<nptcl; i++) {
if ((
int)
images[i]->
get_attr(
"is_ok_center")>0) goodcen.push_back(i); }
349if (goodcen.size()==0) {
350 printf(
"Kmeans ran out of valid center particles, disabling outlier mode and finishing. Results not valid.\n");
351 for (
int i=0; i<nptcl; i++) goodcen.push_back(i);
367for (i=0; i<
ncls; i++) {
374 printf(
"reseed %d -> worst (cls %d)\n",i,j);
379 printf(
"reseed %d -> %d\n",i,j);
381 centers[i]->set_attr(
"ptcl_repr",1);
389 size_t n = a->get_size();
390 float *d1=a->get_data();
391 float *d2=b->get_data();
394 for (
size_t i=0; i<n; i++) ret+=pow(d1[i]-d2[i],2);
409 for (
int i=1; i<sortmax; i++) {
411 for (
int j=i; j<sortmax; j++) {
433for (
int i=0; i<nptcl; i++) {
439 for (
int j=0; j<lim; j++) {
442 if (d<best) { best=d; bestn=j; }
444 int oldn=
images[i]->get_attr_default(
"class_id",0);
446 images[i]->set_attr(
"class_id",bestn);
447 images[i]->set_attr(
"class_cendist",best);
452#define covmat(i,j) covmat[ ((j)-1)*nx + (i)-1 ]
453#define imgdata(i) imgdata[ (i)-1 ]
454int PCAsmall::insert_image(
EMData * image)
459 EMData *maskedimage = Util::compress_image_mask(image,mask);
461 int nx = maskedimage->get_xsize();
462 float *
imgdata = maskedimage->get_data();
464 fprintf(stderr,
"insert_image: something is wrong...\n");
470 for (
int j = 1; j <= nx; j++)
471 for (
int i = 1; i<=nx; i++) {
480#define eigvec(i,j) eigvec[(j)*ncov + (i)]
481vector<EMData*> PCAsmall::analyze()
486 eigval = (
float*)calloc(ncov,
sizeof(
float));
487 eigvec = (
float*)calloc(ncov*ncov,
sizeof(
float));
494 eigenimage->set_size(ncov,1,1);
495 float *
rdata = eigenimage->get_data();
496 for (
int j = 1; j<= nvec; j++) {
497 for (
int i = 0; i < ncov; i++)
rdata[i] =
eigvec(i,ncov-j);
499 EMData* recons_eigvec = Util::reconstitute_image_mask(eigenimage,mask);
500 recons_eigvec->set_attr(
"eigval",
eigval[j-1] );
501 images.push_back(recons_eigvec);
511void PCAsmall::set_params(
const Dict & new_params)
514 mask = params[
"mask"];
515 nvec = params[
"nvec"];
521 int nx = mask->get_xsize();
522 int ny = mask->get_ysize();
523 int nz = mask->get_zsize();
525 dummy->set_size(nx,ny,nz);
527 EMData *dummy1d = Util::compress_image_mask(dummy,mask);
528 ncov = dummy1d->get_xsize();
534 covmat = (
float*)calloc(ncov*ncov,
sizeof(
float));
540int PCAlarge::insert_image(
EMData * image)
545 EMData *maskedimage = Util::compress_image_mask(image,mask);
548 string scratchfile = params.set_default(
"tmpfile",
"maskedimages.scratch");
550 fp = fopen(scratchfile.c_str(),
"ab");
552 int nx = maskedimage->get_xsize();
553 float *
imgdata = maskedimage->get_data();
554 fwrite(
imgdata,
sizeof(
float), nx, fp);
564void PCAlarge::set_params(
const Dict & new_params)
567 mask = params[
"mask"];
568 nvec = params[
"nvec"];
574 int nx = mask->get_xsize();
575 int ny = mask->get_ysize();
576 int nz = mask->get_zsize();
578 dummy->set_size(nx,ny,nz);
580 EMData *dummy1d = Util::compress_image_mask(dummy,mask);
582 ncov = dummy1d->get_xsize();
590#define qmat(i,j) qmat[((j)-1)*kstep + (i) -1]
591#define diag(i) diag[(i)-1]
592#define rdata(i) rdata[(i)-1]
593#define eigvec(i,j) eigvec[((j)-1)*ncov + (i)-1]
594#define eigval(i) eigval[(i)-1]
596vector<EMData*> PCAlarge::analyze()
600 float one = 1.0, zero = 0.0;
603 string scratchfile = (string) params[
"tmpfile"];
610 if ( nvec > nimages || nvec ==0 ) nvec = nimages;
614 int kstep = nvec*2 + 20;
615 if (kstep > nimages) kstep = nimages;
617 float *
diag =
new float[kstep];
618 float *
subdiag =
new float[kstep-1];
619 float *vmat =
new float[nx*kstep];
622 status = Lanczos(scratchfile, &kstep,
diag,
subdiag,
627 if (_unlink(scratchfile.c_str()) == -1) {
628 fprintf(stderr,
"PCAlarge: cannot remove scratchfile\n");
631 sprintf(command,
"rm -f %s\n", scratchfile.c_str());
632 status = system(command);
634 fprintf(stderr,
"PCAlarge: cannot remove scratchfile\n");
639 float *
qmat =
new float[kstep*kstep];
641 int lwork = 100 + 4*kstep + kstep*kstep;
642 int liwork = 3+5*kstep;
644 float *work =
new float[lwork];
645 int *iwork =
new int[liwork];
650 iwork, &liwork, &info);
653 eigval = (
float*)calloc(ncov,
sizeof(
float));
654 eigvec = (
float*)calloc(ncov*nvec,
sizeof(
float));
656 for (
int j = 0; j < nvec; j++) {
664 for (
int j=1; j<=nvec; j++) {
666 sgemv_(&trans, &nx, &kstep, &one, vmat, &nx, &
qmat(1,kstep-j+1),
667 &ione, &zero, &
eigvec(1,j), &ione);
672 eigenimage->set_size(ncov,1,1);
673 float *
rdata = eigenimage->get_data();
674 for (
int j = 1; j<= nvec; j++) {
675 for (
int i = 1; i <= ncov; i++)
678 EMData* recons_eigvec = Util::reconstitute_image_mask(eigenimage,mask);
680 recons_eigvec->set_attr(
"eigval",
eigval[j-1] );
682 images.push_back( recons_eigvec );
697#define V(i,j) V[((j)-1)*imgsize + (i) - 1]
698#define v0(i) v0[(i)-1]
699#define Av(i) Av[(i)-1]
700#define subdiag(i) subdiag[(i)-1]
701#define diag(i) diag[(i)-1]
702#define hvec(i) hvec[(i)-1]
704int PCAlarge::Lanczos(
const string &maskedimages,
int *kstep,
741 float zero = 0.0, one = 1.0, mone = -1.0;
760 v0 =
new float[imgsize];
761 Av =
new float[imgsize];
762 hvec =
new float[*kstep];
763 htmp =
new float[*kstep];
766 if (
v0 == NULL ||
Av == NULL ||
hvec == NULL ||
767 htmp == NULL ||
imgdata == NULL) {
768 fprintf(stderr,
"Lanczos: failed to allocate v0,Av,hvec,htmp\n");
774 for ( i = 1; i <= imgsize; i++)
781 *beta = snrm2_(&imgsize,
v0, &ione);
782 for (i = 1; i<=imgsize; i++)
783 V(i,1) =
v0(i) / (*beta);
786 fp = fopen(maskedimages.c_str(),
"rb");
788 fprintf(stderr,
"Lanczos: cannot open %s\n", maskedimages.c_str());
790 for (i = 0; i < nimages; i++) {
791 fread(
imgdata,
sizeof(
float), imgsize, fp);
792 alpha = sdot_(&imgsize,
imgdata, &ione,
V, &ione);
793 saxpy_(&imgsize, &alpha,
imgdata, &ione,
Av, &ione);
799 diag(1) = sdot_(&imgsize,
V, &ione,
Av, &ione);
801 saxpy_(&imgsize, &alpha,
V, &ione,
Av, &ione);
804 for ( iter = 2 ; iter <= *kstep ; iter++ ) {
805 *beta = snrm2_(&imgsize,
Av, &ione);
814 for ( i = 1 ; i <= imgsize ; i++ ) {
815 V(i,iter) =
Av(i) / (*beta);
819 for (i = 0; i < imgsize; i++)
Av[i] = 0;
820 fp = fopen(maskedimages.c_str(),
"rb");
821 for (i = 0; i < nimages; i++) {
822 fread(
imgdata,
sizeof(
float), imgsize, fp);
823 alpha = sdot_(&imgsize,
imgdata, &ione, &
V(1,iter), &ione);
824 saxpy_(&imgsize, &alpha,
imgdata, &ione,
Av, &ione);
830 status = sgemv_(&trans, &imgsize, &iter, &one,
V, &imgsize,
Av, &ione,
831 &zero ,
hvec , &ione);
833 status = sgemv_(&trans, &imgsize, &iter, &mone,
V, &imgsize,
hvec,
834 &ione , &one ,
Av, &ione);
838 status = sgemv_(&trans, &imgsize, &iter, &one,
V, &imgsize,
Av, &ione,
839 &zero , htmp , &ione);
840 saxpy_(&iter, &one, htmp, &ione,
hvec, &ione);
842 status = sgemv_(&trans, &imgsize, &iter, &mone,
V, &imgsize, htmp,
843 &ione , &one ,
Av, &ione);
865void varimax::set_params(
const Dict & new_params)
868 m_mask = params[
"mask"];
874 int nx = m_mask->get_xsize();
875 int ny = m_mask->get_ysize();
876 int nz = m_mask->get_zsize();
878 dummy->set_size(nx,ny,nz);
880 EMData *dummy1d = Util::compress_image_mask(dummy,m_mask);
882 m_nlen = dummy1d->get_xsize();
889int varimax::insert_image(
EMData* image)
894 EMData* img1d = Util::compress_image_mask(image,m_mask);
896 m_data.insert( m_data.end(), img1d->get_data(), img1d->get_data() + m_nlen );
900 Assert( (
int)m_data.size() == m_nfac*m_nlen);
905vector<EMData*> varimax::analyze()
912 varmx( &m_data[0], m_nlen, m_nfac, IVARIMAX, params, NULL, itmax, eps, verbose);
917 img1d->set_size(m_nlen, 1, 1);
918 for(
int i=0; i < m_nfac; ++i )
920 float*
imgdata = img1d->get_data();
922 int offset = i * m_nlen;
923 for(
int i=0; i < m_nlen; ++i )
928 EMData* img = Util::reconstitute_image_mask(img1d,m_mask);
943 size_t totpix=
mask->get_xsize()*
mask->get_ysize()*
mask->get_zsize();
944 float *d=image->get_data();
945 float *md=
mask ->get_data();
946 for (
size_t i=0,j=0; i<totpix; ++i) {
948 gsl_matrix_set(
A,j,
nsofar,d[i]);
958#define eigvec(i,j) eigvec[(j)*ncov + (i)]
962gsl_vector *work=gsl_vector_alloc(
nimg);
963gsl_vector *S=gsl_vector_alloc(
nimg);
964gsl_matrix *
V=gsl_matrix_alloc(
nimg,
nimg);
965gsl_matrix *X=gsl_matrix_alloc(
nimg,
nimg);
969gsl_linalg_SV_decomp_mod (
A,X,
V, S, work);
974float *md=
mask->get_data();
975size_t totpix=
mask->get_xsize()*
mask->get_ysize()*
mask->get_zsize();
976for (
int k=0; k<
nvec; k++) {
978 img->set_size(
mask->get_xsize(),
mask->get_ysize(),
mask->get_zsize());
980 float *d=img->get_data();
981 for (
size_t i=0,j=0; i<totpix; ++i) {
983 d[i]=(float)gsl_matrix_get(
A,j,k);
987 img->set_attr(
"eigval", gsl_vector_get(S,k));
991gsl_vector_free(work);
1012 size_t totpix=
mask->get_xsize()*
mask->get_ysize()*
mask->get_zsize();
1013 float *d=
mask->get_data();
1014 for (
size_t i=0; i<totpix; ++i)
if (d[i]) ++
pixels;
1024 dump_factory < Analyzer > ();
1029 return dump_factory_list < Analyzer > ();
1039 int nx=
images[0]->get_xsize();
1040 int ny=
images[0]->get_ysize();
1041 int nz=
images[0]->get_zsize();
1050 for (it=0; it<maxr; it+=step){
1053 for (ix=-maxr-1; ix<=maxr+1; ix++){
1054 for (iy=-maxr-1; iy<=maxr+1; iy++){
1056 if (d2>=it*it && d2<(it+step)*(it+step)){
1058 mn+=
images[0]->sget_value_at(ix+nx/2,iy+ny/2);
1065 if(
verbose>0) printf(
"%d,%d,%f\n",it,count,mn);
1066 avg->set_value_at(it/step,0,mn);
float qsqcmp(EMData *a, EMData *b)
virtual int insert_image(EMData *image)=0
insert a image to the list of input images
vector< EMData * > images
virtual vector< EMData * > analyze()
main function for Analyzer, analyze input images and create output images
Dict is a dictionary to store <string, EMObject> pair.
type set_default(const string &key, type val)
Default setting behavior This can be achieved using a template - d.woolford Jan 2008 (before there wa...
bool has_key(const string &key) const
Ask the Dictionary if it as a particular key.
EMData stores an image's data and defines core image processing routines.
Factory is used to store objects to create new instances.
virtual vector< EMData * > analyze()
main function for Analyzer, analyze input images and create output images
void set_params(const Dict &new_params)
Set the Analyzer parameters using a key/value dictionary.
vector< EMData * > centers
void update_centers(int sigmas=0)
virtual vector< EMData * > analyze()
main function for Analyzer, analyze input images and create output images
virtual int insert_image(EMData *image)
insert a image to the list of input images
virtual vector< EMData * > analyze()
main function for Analyzer, analyze input images and create output images
void set_params(const Dict &new_params)
Set the Analyzer parameters using a key/value dictionary.
virtual vector< EMData * > analyze()
main function for Analyzer, analyze input images and create output images
static int get_irand(int low, int high)
Get an integer random number between low and high, [low, high].
#define Assert(s)
Define Assert() function that is effective only when -DDEBUG is used.
EMData * sqrt() const
return square root of current image
#define ImageDimensionException(desc)
#define NullPointerException(desc)
map< string, vector< string > > dump_analyzers_list()