EMAN2
Public Types | Public Member Functions | Private Attributes | List of all members
EMAN::PointArray Class Reference

PointArray defines a double array of points with values in a 3D space. More...

#include <pointarray.h>

Collaboration diagram for EMAN::PointArray:
Collaboration graph
[legend]

Public Types

enum  Density2PointsArrayAlgorithm { PEAKS_SUB , PEAKS_DIV , KMEANS }
 

Public Member Functions

 PointArray ()
 
 PointArray (int nn)
 
 ~PointArray ()
 
void zero ()
 
PointArraycopy ()
 
PointArrayoperator= (PointArray &pa)
 
size_t get_number_points () const
 
void set_number_points (size_t nn)
 
bool read_from_pdb (const char *file, const vector< int > &lines=vector< int >())
 
void save_to_pdb (const char *file)
 
FloatPoint get_center ()
 
void center_to_zero ()
 
Region get_bounding_box ()
 
double * get_points_array ()
 
Vec3f get_vector_at (int i)
 
double get_value_at (int i)
 
void set_vector_at (int i, Vec3f vec, double value)
 
void set_vector_at (int i, vector< double >)
 
void set_points_array (double *p)
 
vector< float > get_points ()
 Returns all x,y,z triplets packed into a vector<float> More...
 
EMDatadistmx (int sortrows=0)
 Calculates a (symmetrized) distance matrix for the current PointArray. More...
 
vector< int > match_points (PointArray *to, float max_miss=-1.0)
 Will try to establish a 1-1 correspondence between points in two different PointArray objects (this and to). More...
 
Transformalign_2d (PointArray *to, float max_dist)
 Aligns one PointArray to another in 2 dimensions. More...
 
void mask (double rmax, double rmin=0.0)
 
void mask_asymmetric_unit (const string &sym)
 
void transform (const Transform &transform)
 
void right_transform (const Transform &transform)
 Does Transform*v as opposed to v*Transform (as in the transform function) More...
 
void set_from (vector< float >)
 
void set_from (PointArray *source, const string &sym="", Transform *transform=0)
 
void set_from (double *source, int num, const string &sym="", Transform *transform=0)
 
void set_from_density_map (EMData *map, int num, float thresh, float apix, Density2PointsArrayAlgorithm mode=PEAKS_DIV)
 
void sort_by_axis (int axis=1)
 
EMDatapdb2mrc_by_nfft (int map_size, float apix, float res)
 
EMDatapdb2mrc_by_summation (int map_size, float apix, float res, int addpdbbfactor)
 
EMDataprojection_by_nfft (int image_size, float apix, float res=0)
 
EMDataprojection_by_summation (int image_size, float apix, float res)
 
void replace_by_summation (EMData *image, int i, Vec3f vec, float amp, float apix, float res)
 
void opt_from_proj (const vector< EMData * > &proj, float pixres)
 Optimizes a pointarray based on a set of projection images (EMData objects) This is effectively a 3D reconstruction algorithm. More...
 
double sim_pointpotential (double dist, double ang, double dihed)
 Computes a potential value for a single point from a set of angles/distances using current energy settings. More...
 
double sim_potential ()
 Computes overall potential for the configuration. More...
 
double sim_potentiald (int ind)
 Compute a single point potential value. More...
 
double sim_potentialdxyz (int i, double dx, double dy, double dz)
 Compute a potential value for a perturbed point, including +-2 nearest neighbors which will also be impacted. More...
 
void sim_updategeom ()
 Updates the dist, ang, dihed parameters. More...
 
Vec3f sim_descent (int i)
 returns a vector pointing downhill for a single point More...
 
void sim_minstep (double maxshift)
 Takes a step to minimize the potential. More...
 
void sim_minstep_seq (double meanshift)
 Takes a step to minimize the potential. More...
 
void sim_rescale ()
 rescale the entire set so the mean bond length matches dist0 More...
 
void sim_printstat ()
 prints some statistics to the screen More...
 
void sim_set_pot_parms (double pdist0, double pdistc, double pangc, double pdihed0, double pdihedc, double pmapc, EMData *pmap, double pmindistc, double pdistpenc)
 Sets the parameters for the energy function. More...
 
void sim_add_point_double ()
 Add more points during the simulation. More...
 
void sim_add_point_one ()
 
double calc_total_length ()
 Calculate total length. More...
 
vector< double > fit_helix (EMData *pmap, int minlength, float mindensity, vector< int > edge, int twodir, size_t minl)
 Fit helix from peptide chains. More...
 
vector< float > do_pca (int start, int end)
 Do principal component analysis to (a subset of) the point array, used in helix fitting in pathwalker. More...
 
vector< float > do_filter (vector< float > pts, float *ft, int num)
 Filter the point array to smooth the line, used in helix fitting in pathwalker. More...
 
vector< double > construct_helix (int start, int end, float phs, float &score, int &dir)
 Construct an ideal helix between the start and end points given phase. More...
 
void reverse_chain ()
 Reverse the pointarray chain. More...
 
void merge_to (PointArray &pa, float thr)
 Merge to another point array. More...
 
float calc_helicity (vector< double > pts)
 Calculate the helicity of some points. More...
 
void save_pdb_with_helix (const char *file, vector< float > hlxid)
 Save the point array to pdb file, including helices information. More...
 
void delete_point (int id)
 Delete one point in the array. More...
 
void remove_helix_from_map (EMData *m, vector< float > hlxid)
 Remove the corresponding density of the helix point from a density map. More...
 
bool read_ca_from_pdb (const char *file)
 Read only C-alpha atoms from a pdb file. More...
 
Transform calc_transform (PointArray *p)
 Calculate the transform to another identical pointarray. More...
 

Private Attributes

double * points
 
size_t n
 
double * bfactor
 
double * adist
 
double * aang
 
double * adihed
 
double dist0
 Used for simplistic loop dynamics simulation Assumes all points are connected sequentially in a closed loop, potential includes distance, angle and dihedral terms, with optional density based terms. More...
 
double distc
 
double angc
 
double dihed0
 
double dihedc
 
double mapc
 
double apix
 
double mindistc
 
double distpenc
 
bool map2d
 
EMDatamap
 
EMDatagradx
 
EMDatagrady
 
EMDatagradz
 
vector< Vec3foldshifts
 
int centx
 
int centy
 
int centz
 

Detailed Description

PointArray defines a double array of points with values in a 3D space.

Definition at line 51 of file pointarray.h.

Member Enumeration Documentation

◆ Density2PointsArrayAlgorithm

Enumerator
PEAKS_SUB 
PEAKS_DIV 
KMEANS 

Definition at line 54 of file pointarray.h.

Constructor & Destructor Documentation

◆ PointArray() [1/2]

PointArray::PointArray ( )

Definition at line 103 of file pointarray.cpp.

104{
105 points = 0;
106 bfactor = 0;
107 n = 0;
108
109 adist=0;
110 aang=0;
111 adihed=0;
112
114}
EMData * gradz
Definition: pointarray.h:247
double * adist
Definition: pointarray.h:227
EMData * gradx
Definition: pointarray.h:247
double * points
Definition: pointarray.h:221
double * bfactor
Definition: pointarray.h:223
double * adihed
Definition: pointarray.h:229
EMData * grady
Definition: pointarray.h:247

References aang, adihed, adist, bfactor, gradx, grady, gradz, map, n, and points.

Referenced by copy().

◆ PointArray() [2/2]

PointArray::PointArray ( int  nn)
explicit

Definition at line 116 of file pointarray.cpp.

117{
118 n = nn;
119 points = (double *) calloc(4 * n, sizeof(double));
120
121 adist=0;
122 aang=0;
123 adihed=0;
125}

References aang, adihed, adist, gradx, grady, gradz, map, n, and points.

◆ ~PointArray()

PointArray::~PointArray ( )

Definition at line 127 of file pointarray.cpp.

128{
129 if( points )
130 {
131 free(points);
132 points = 0;
133 }
134
135 if (adist) free(adist);
136 if (aang) free(aang);
137 if (adihed) free(adihed);
138// if (map!=0) delete map;
139 if (gradx!=0) delete gradx;
140 if (grady!=0) delete grady;
141 if (gradz!=0) delete gradz;
142}

References aang, adihed, adist, gradx, grady, gradz, and points.

Member Function Documentation

◆ align_2d()

Transform * PointArray::align_2d ( PointArray to,
float  max_dist 
)

Aligns one PointArray to another in 2 dimensions.

Parameters
toAnother PointArray to align to
max_dist
Returns
a Transform to map 'this' to 'to'

Definition at line 281 of file pointarray.cpp.

281 {
282vector<int> match=match_points(to,max_dist);
283Transform *ret=new Transform();
284
285// we use bilinear least squares to get 3/6 matrix components
286unsigned int i,j;
287
288vector<float> pts;
289for (i=0; i<match.size(); i++) {
290 if (match[i]==-1) continue;
291
292// printf("%d -> %d\n",i,match[i]);
293 pts.push_back(get_vector_at(i)[0]);
294 pts.push_back(get_vector_at(i)[1]);
295 pts.push_back(to->get_vector_at(match[i])[0]);
296}
297
299
300// then we get the other 3/6
301for (i=j=0; i<match.size(); i++) {
302 if (match[i]==-1) continue;
303 pts[j*3] =get_vector_at(i)[0];
304 pts[j*3+1]=get_vector_at(i)[1];
305 pts[j*3+2]=to->get_vector_at(match[i])[1];
306 j++;
307}
308
310
311//ret->set_rotation(vx[1],vx[2],0.0,vy[1],vy[2],0.0,0.0,0.0,1.0);
312//ret->set_rotation(vx[1],vy[1],0.0,vx[2],vy[2],0.0,0.0,0.0,1.0);
313//ret->set_pretrans(Vec3f(-vx[0],-vy[0],0));
314
315ret->set(0, 0, vx[1]);
316ret->set(0, 1, vy[1]);
317ret->set(0, 2, 0.0f);
318ret->set(1, 0, vx[2]);
319ret->set(1, 1, vy[2]);
320ret->set(1, 2, 0.0f);
321ret->set(2, 0, 0.0f);
322ret->set(2, 1, 0.0f);
323ret->set(2, 2, 1.0f);
324ret->set_pre_trans(Vec3f(-vx[0],-vy[0],0));
325
326return ret;
327}
vector< int > match_points(PointArray *to, float max_miss=-1.0)
Will try to establish a 1-1 correspondence between points in two different PointArray objects (this a...
Definition: pointarray.cpp:217
Vec3f get_vector_at(int i)
A Transform object is a somewhat specialized object designed specifically for EMAN2/Sparx storage of ...
Definition: transform.h:75
void set(int r, int c, float value)
Set the value stored in the internal transformation matrix at at coordinate (r,c) to value.
Definition: transform.h:400
void set_pre_trans(const type &v)
Set the translational component of the matrix as though it was MSRT_ not MTSR, where T_ is the pre tr...
Definition: transform.h:556
static Vec3f calc_bilinear_least_square(const vector< float > &points)
calculate bilinear least-square fit, z = a + b x + c y Takes a set of x,y,z vectors and produces an a...
Definition: util.cpp:577
Vec3< float > Vec3f
Definition: vec3.h:693

References EMAN::Util::calc_bilinear_least_square(), get_vector_at(), match_points(), EMAN::Transform::set(), and EMAN::Transform::set_pre_trans().

◆ calc_helicity()

float PointArray::calc_helicity ( vector< double >  pts)

Calculate the helicity of some points.

Used for correct the hand of the helices

Definition at line 2035 of file pointarray.cpp.

2035 {
2036 int npt=pts.size();
2037 vector<double> vpoint(npt-3);
2038 for (int i=0; i<npt-3; i++){
2039 vpoint[i]=pts[i+3]-pts[i];
2040 }
2041 Vec3f hlxdir(pts[npt-3]-pts[0],pts[npt-2]-pts[1],pts[npt-1]-pts[2]);
2042 Vec3f vcs(0,0,0);
2043 for (int i=0; i<npt/3-2; i++){
2044 Vec3f v0(vpoint[i*3],vpoint[i*3+1],vpoint[i*3+2]);
2045 Vec3f v1(vpoint[i*3+3],vpoint[i*3+4],vpoint[i*3+5]);
2046 vcs+=v0.cross(v1);
2047 }
2048 vcs/=(npt/3-2);
2049
2050 return hlxdir.dot(vcs);
2051}
#define v0(i)
Definition: analyzer.cpp:698

References EMAN::Vec3< Type >::dot(), and v0.

Referenced by construct_helix().

◆ calc_total_length()

double PointArray::calc_total_length ( )

Calculate total length.

Definition at line 1096 of file pointarray.cpp.

1096 {
1097 double dist=0;
1098 for(size_t i=0; i<n; i++){
1099 int k=(i+1)%n;
1100 double d=(points[i*4]-points[k*4])*(points[i*4]-points[k*4])+(points[i*4+1]-points[k*4+1])*(points[i*4+1]-points[k*4+1])+(points[i*4+2]-points[k*4+2])*(points[i*4+2]-points[k*4+2]);
1101 d=sqrt(d);
1102 dist+=d;
1103 }
1104 return dist;
1105}
EMData * sqrt() const
return square root of current image

References n, points, and sqrt().

◆ calc_transform()

Transform PointArray::calc_transform ( PointArray p)

Calculate the transform to another identical pointarray.

(The rotation part is copied from a set_rotation in transform.cpp)

Definition at line 2101 of file pointarray.cpp.

2102{
2103 Transform t;
2104
2105 // calculate translation
2106 FloatPoint c1=p->get_center(),c2=get_center();
2107 t.set_trans(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2]);
2108
2109 // calculate rotation
2110 // this rotation rotates unit vectors a,b into A,B;
2111 // The program assumes a dot b must equal A dot B
2112
2113 //pick two bonds randomly
2114 int i1=Util::get_irand(0,n-2);
2115 int i2=Util::get_irand(0,n-2);
2116 while(i1==i2)
2117 i2=Util::get_irand(0,n-2);
2118
2119 const Vec3f eahat=get_vector_at(i1+1)-get_vector_at(i1);
2120 const Vec3f ebhat=get_vector_at(i2+1)-get_vector_at(i2);
2121 const Vec3f eAhat=p->get_vector_at(i1+1)-p->get_vector_at(i1);
2122 const Vec3f eBhat=p->get_vector_at(i2+1)-p->get_vector_at(i2);
2123 Vec3f eahatcp(eahat);
2124 Vec3f ebhatcp(ebhat);
2125 Vec3f eAhatcp(eAhat);
2126 Vec3f eBhatcp(eBhat);
2127
2128 eahatcp.normalize();
2129 ebhatcp.normalize();
2130 eAhatcp.normalize();
2131 eBhatcp.normalize();
2132
2133 Vec3f aMinusA(eahatcp);
2134 aMinusA -= eAhatcp;
2135 Vec3f bMinusB(ebhatcp);
2136 bMinusB -= eBhatcp;
2137
2138
2139 Vec3f nhat;
2140 float aAlength = aMinusA.length();
2141 float bBlength = bMinusB.length();
2142 if (aAlength==0){
2143 nhat=eahatcp;
2144 }else if (bBlength==0){
2145 nhat=ebhatcp;
2146 }else{
2147 nhat= aMinusA.cross(bMinusB);
2148 nhat.normalize();
2149 }
2150
2151// printf("nhat=%f,%f,%f \n",nhat[0],nhat[1],nhat[2]);
2152
2153 Vec3f neahat = eahatcp.cross(nhat);
2154 Vec3f nebhat = ebhatcp.cross(nhat);
2155 Vec3f neAhat = eAhatcp.cross(nhat);
2156 Vec3f neBhat = eBhatcp.cross(nhat);
2157
2158 double cosomegaA = (neahat.dot(neAhat)) / (neahat.dot(neahat));
2159// float cosomegaB = (nebhat.dot(neBhat)) / (nebhat.dot(nebhat));
2160 double sinomegaA = (neahat.dot(eAhatcp)) / (neahat.dot(neahat));
2161// printf("cosomegaA=%f \n",cosomegaA); printf("sinomegaA=%f \n",sinomegaA);
2162
2163 double omegaA = atan2(sinomegaA,cosomegaA);
2164// printf("omegaA=%f \n",omegaA*180/M_PI);
2165 Dict rotation;
2166 rotation["type"]="spin";
2167 rotation["n1"]= nhat[0];
2168 rotation["n2"]= nhat[1];
2169 rotation["n3"]= nhat[2];
2170 rotation["omega"] = (float)(omegaA*180.0/M_PI);
2171 t.set_rotation(rotation);
2172 return t;
2173}
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385
FloatPoint defines a float-coordinate point in a 1D/2D/3D space.
Definition: geometry.h:278
FloatPoint get_center()
Definition: pointarray.cpp:453
void set_rotation(const Dict &rotation)
Set a rotation using a specific Euler type and the dictionary interface Works for all Euler types.
Definition: transform.cpp:519
void set_trans(const float &x, const float &y, const float &z=0)
Set the post translation component.
Definition: transform.cpp:1036
static int get_irand(int low, int high)
Get an integer random number between low and high, [low, high].
Definition: util.cpp:719
Vec3< Type > cross(const Vec3< Type2 > &v) const
Calculate the cross product of 'this' vector with a second vector.
Definition: vec3.h:384
Type dot(const Vec3< Type2 > &v) const
Calculate the dot product of 'this' vector with a second vector.
Definition: vec3.h:373
float normalize()
Normalize the vector and return its length before the normalization.
Definition: vec3.h:332
float length() const
Calculate its length.
Definition: vec3.h:352

References EMAN::Vec3< Type >::cross(), EMAN::Vec3< Type >::dot(), get_center(), EMAN::Util::get_irand(), get_vector_at(), EMAN::Vec3< Type >::length(), n, EMAN::Vec3< Type >::normalize(), EMAN::Transform::set_rotation(), and EMAN::Transform::set_trans().

◆ center_to_zero()

void PointArray::center_to_zero ( )

Definition at line 472 of file pointarray.cpp.

473{
474 FloatPoint center = get_center();
475 for ( size_t i = 0; i < 4 * get_number_points(); i += 4) {
476 points[i] -= center[0];
477 points[i + 1] -= center[1];
478 points[i + 2] -= center[2];
479 }
480}
size_t get_number_points() const
Definition: pointarray.cpp:168

References get_center(), get_number_points(), and points.

◆ construct_helix()

vector< double > PointArray::construct_helix ( int  start,
int  end,
float  phs,
float &  score,
int &  dir 
)

Construct an ideal helix between the start and end points given phase.

Definition at line 1877 of file pointarray.cpp.

1877 {
1878 // calculate length
1879 int dir=1;
1880 rtdir=0;
1881 Vec3f d(points[end*4]-points[start*4],points[end*4+1]-points[start*4+1],points[end*4+2]-points[start*4+2]);
1882 double len=d.length();
1883 int nh=int(Util::round(len/1.54))+2;
1884 vector<double> helix(nh*3);
1885 vector<float> eigvec=do_pca(start,end);
1886 float eigval[3],vec[9];
1887
1888 Util::coveig(3,&eigvec[0],eigval,vec);
1889 float maxeigv=0;
1890// int maxvi=-1;
1891 for(int i=0; i<3; i++){
1892 if(abs(eigval[i])>maxeigv){
1893 maxeigv=abs(eigval[i]);
1894// maxvi=i;
1895 }
1896 }
1897// dir=eigval[maxvi]>0;
1898 dir=1;
1899 vector<double> pts(nh*3);
1900 for (int dd=0; dd<2; dd++){
1901 // printf("%f\t",eigval[maxvi]);
1902 // vector<float> eigv(eigvec,eigvec+sizeof(eigvec)/sizeof(float));
1903 // create helix
1904 helix[0]=0;helix[1]=0;helix[2]=0;
1905 helix[nh*3-3]=.0;helix[nh*3-2]=0;helix[nh*3-1]=len;
1906
1907 for (int i=0; i<nh-2; i++){
1908 if(dir>0){
1909 helix[(i+1)*3+0]=cos(((phs+(100*i))*M_PI)/180)*2.3;
1910 helix[(i+1)*3+1]=sin(((phs+(100*i))*M_PI)/180)*2.3;
1911 }
1912 else{
1913 helix[(i+1)*3+1]=cos(((phs+(100*i))*M_PI)/180)*2.3;
1914 helix[(i+1)*3+0]=sin(((phs+(100*i))*M_PI)/180)*2.3;
1915 }
1916 helix[(i+1)*3+2]=i*1.54;
1917 }
1918 // transform to correct position
1919 float mean[3];
1920 for (int k=0; k<3; k++) mean[k]=0;
1921 for (int k=0; k<nh; k++){
1922 for (int l=0; l<3; l++){
1923 pts[k*3+l]=helix[k*3+0]*eigvec[0*3+l]+helix[k*3+1]*eigvec[1*3+l]+helix[k*3+2]*eigvec[2*3+l];
1924 mean[l]+=pts[k*3+l];
1925 }
1926 }
1927 for (int k=0; k<3; k++) mean[k]/=nh;
1928 for (int k=0; k<nh; k++){
1929 for (int l=0; l<3; l++){
1930 pts[k*3+l]-=mean[l];
1931 }
1932 }
1933 for (int k=0; k<3; k++) mean[k]=0;
1934 for (int k=start; k<end; k++){
1935 for (int l=0; l<3; l++){
1936 mean[l]+=points[k*4+l];
1937 }
1938 }
1939 for (int k=0; k<3; k++) mean[k]/=(end-start);
1940 for (int k=0; k<nh; k++){
1941 for (int l=0; l<3; l++){
1942 pts[k*3+l]+=mean[l];
1943 }
1944 }
1945
1946
1947 // correct direction
1948 Vec3f d1(pts[0]-points[start*4],pts[1]-points[start*4+1],pts[2]-points[start*4+2]);
1949 Vec3f d2(pts[0]-points[end*4],pts[1]-points[end*4+1],pts[2]-points[end*4+2]);
1950
1951 if (d1.length()>d2.length()) { //do reverse
1952 double tmp;
1953 for (int i=0; i<nh/2; i++){
1954 for(int j=0; j<3; j++){
1955 tmp=pts[i*3+j];
1956 pts[i*3+j]=pts[(nh-i-1)*3+j];
1957 pts[(nh-i-1)*3+j]=tmp;
1958 }
1959 }
1960 }
1961
1962 // correct handness
1963 float hel=calc_helicity(pts);
1964
1965 rtdir=hel;
1966// break;
1967 if(hel>0)
1968 break;
1969 else
1970 dir=0;
1971 }
1972 // calculate score
1973// int sx=map->get_xsize(),sy=map->get_ysize(),sz=map->get_zsize();
1974 int sx=0,sy=0,sz=0;
1975 float ax=map->get_attr("apix_x"),ay=map->get_attr("apix_y"),az=map->get_attr("apix_z");
1976 score=0;
1977 float aind=0;
1978 for (int i=1; i<nh-1; i++){
1979 float ind=1;//(float(abs(i-nh/2))/float(nh))+.5;
1980 score+=ind*map->get_value_at(int(pts[i*3]/ax+sx/2),int(pts[i*3+1]/ay+sy/2),int(pts[i*3+2]/az+sz/2));
1981 aind+=ind;
1982 }
1983 score/=aind;//(nh-2);
1984// float nsc=score;
1985// score=0;
1986// for (int i=1; i<nh-1; i++){
1987// float ind=(float(abs(i-nh/2))/float(nh))+.5;
1988// float mapden=map->get_value_at(int(pts[i*3]/ax+sx/2),int(pts[i*3+1]/ay+sy/2),int(pts[i*3+2]/az+sz/2));
1989// if (mapden>nsc*1.2)
1990// mapden=nsc*1.2;
1991// if (mapden<nsc*.5)
1992// mapden=0;
1993// score+=ind*mapden;
1994// }
1995// score/=aind;//(nh-2);
1996
1997
1998 return pts;
1999}
#define eigval(i)
Definition: analyzer.cpp:594
#define eigvec(i, j)
Definition: analyzer.cpp:958
vector< float > do_pca(int start, int end)
Do principal component analysis to (a subset of) the point array, used in helix fitting in pathwalker...
float calc_helicity(vector< double > pts)
Calculate the helicity of some points.
static int round(float x)
Get ceiling round of a float number x.
Definition: util.h:465

References calc_helicity(), do_pca(), eigval, eigvec, EMAN::Vec3< Type >::length(), map, points, and EMAN::Util::round().

Referenced by fit_helix().

◆ copy()

PointArray * PointArray::copy ( )

Definition at line 149 of file pointarray.cpp.

150{
151 PointArray *pa2 = new PointArray();
153 double *pa2data = pa2->get_points_array();
154 memcpy(pa2data, get_points_array(), sizeof(double) * 4 * get_number_points());
155
156 return pa2;
157}
PointArray defines a double array of points with values in a 3D space.
Definition: pointarray.h:52
double * get_points_array()
Definition: pointarray.cpp:182
void set_number_points(size_t nn)
Definition: pointarray.cpp:173

References get_number_points(), get_points_array(), PointArray(), and set_number_points().

Referenced by mask(), and mask_asymmetric_unit().

◆ delete_point()

void PointArray::delete_point ( int  id)

Delete one point in the array.

Definition at line 2190 of file pointarray.cpp.

2190 {
2191 for (size_t i=id*4; i<n*4; i++){
2192 points[i]=points[i+4];
2193 }
2195}

References n, points, and set_number_points().

◆ distmx()

EMData * PointArray::distmx ( int  sortrows = 0)

Calculates a (symmetrized) distance matrix for the current PointArray.

Parameters
sortrowsif set, will sort the values in each row. The return will no longer be a true similarity matrix.
Returns
An EMData object containing the similarity matrix

Definition at line 192 of file pointarray.cpp.

192 {
193if (n==0) return NULL;
194
195unsigned int i,j;
196
197EMData *ret= new EMData(n,n,1);
198ret->to_zero();
199
200for (i=0; i<n; i++) {
201 for (j=i+1; j<n; j++) {
202 float r=(get_vector_at(i)-get_vector_at(j)).length();
203 ret->set_value_at(i,j,0,r);
204 ret->set_value_at(j,i,0,r);
205 }
206}
207
208if (sortrows) {
209 float *data=ret->get_data();
210 for (i=0; i<n; i++) qsort(&data[i*n],n,sizeof(float),cmp_float);
211 ret->update();
212}
213
214return ret;
215}
EMData stores an image's data and defines core image processing routines.
Definition: emdata.h:82
double length(const Vector3 &v)
Definition: vecmath.h:313
int cmp_float(const void *a, const void *b)
Definition: pointarray.cpp:91

References cmp_float(), get_vector_at(), EMAN::length(), and n.

Referenced by match_points().

◆ do_filter()

vector< float > PointArray::do_filter ( vector< float >  pts,
float *  ft,
int  num 
)

Filter the point array to smooth the line, used in helix fitting in pathwalker.

Definition at line 1546 of file pointarray.cpp.

1546 {
1547 // filter a 1D array
1548 vector<float> result(pts);
1549 for (size_t i=0; i<pts.size(); i++)
1550 result[i]=0;
1551 for (size_t i=(num-1)/2; i<pts.size()-(num-1)/2; i++){
1552 for (int j=0; j<num; j++){
1553 int k=i+j-(num-1)/2;
1554 result[i]+=pts[k]*ft[j];
1555 }
1556 }
1557 return result;
1558}

Referenced by fit_helix().

◆ do_pca()

vector< float > PointArray::do_pca ( int  start = 0,
int  end = -1 
)

Do principal component analysis to (a subset of) the point array, used in helix fitting in pathwalker.

Definition at line 1510 of file pointarray.cpp.

1510 {
1511 if (end==-1) end=n;
1512 float covmat[9],mean[3];
1513 for (int i=0; i<3; i++) mean[i]=0;
1514 for (int i=start; i<end; i++){
1515 for (int j=0; j<3; j++){
1516 mean[j]+=points[i*4+j];
1517 }
1518 }
1519 for (int i=0; i<3; i++) mean[i]/=end-start;
1520
1521 for (int i=0; i<3; i++){
1522 for (int j=0; j<3; j++){
1523 if (j<i){
1524 covmat[i*3+j]=covmat[j*3+i];
1525 }
1526 else{
1527 covmat[i*3+j]=0;
1528 for (int k=start; k<end; k++)
1529 {
1530 covmat[i*3+j]+=(points[k*4+i]-mean[i])*(points[k*4+j]-mean[j]);
1531 }
1532 }
1533
1534// printf("%f\t",covmat[i*3+j]);
1535 }
1536// printf("\n");
1537 }
1538
1539 float eigval[3],eigvec[9];
1540 Util::coveig(3,covmat,eigval,eigvec);
1541 vector<float> eigv(eigvec,eigvec+sizeof(eigvec)/sizeof(float));
1542// printf(" %f,%f,%f\n %f,%f,%f\n %f,%f,%f\n",eigvec[0],eigvec[1],eigvec[2],eigvec[3],eigvec[4],eigvec[5],eigvec[6],eigvec[7],eigvec[8]);
1543 return eigv;
1544}
#define covmat(i, j)
Definition: analyzer.cpp:452

References covmat, eigval, eigvec, n, and points.

Referenced by construct_helix(), and fit_helix().

◆ fit_helix()

vector< double > PointArray::fit_helix ( EMData pmap,
int  minlength = 13,
float  mindensity = 4,
vector< int >  edge = vector<int>(),
int  twodir = 0,
size_t  minl = 9 
)

Fit helix from peptide chains.

Definition at line 1560 of file pointarray.cpp.

1561{
1562 vector<float> hlxlen(n);
1563 vector<int> helix;
1564 map=pmap;
1565 float ft[7]={0.0044,0.0540,0.2420,0.3989,0.2420,0.0540,0.0044};
1566// float ft[7]={0,0,0,1,0,0,0};
1567
1568 // search for long rods in the point array globally
1569 for (int dir=twodir; dir<2; dir++){
1570 // search in both directions and combine the result
1571 if( twodir==0)
1572 reverse_chain();
1573 for (size_t i=0; i<n; i++){
1574 vector<float> dist(50);
1575 // for each point, search the following 50 points, find the longest rod
1576 for (int len=5; len<50; len++){
1577 size_t pos=i+len;
1578 if (pos>=n) break;
1579 vector<float> eigvec=do_pca(i,pos); // align the points
1580 vector<float> pts((len+1)*3);
1581 float mean[3];
1582 for (int k=0; k<3; k++) mean[k]=0;
1583 for (size_t k=i; k<pos; k++){
1584 for (int l=0; l<3; l++){
1585 pts[(k-i)*3+l]=points[k*4+0]*eigvec[l*3+0]+points[k*4+1]*eigvec[l*3+1]+points[k*4+2]*eigvec[l*3+2];
1586 mean[l]+=pts[(k-i)*3+l];
1587 }
1588 }
1589 for (int k=0; k<3; k++) mean[k]/=len;
1590 float dst=0;
1591 // distance to the center axis
1592 for (int k=0; k<len; k++){
1593 dst+=abs((pts[k*3]-mean[0])*(pts[k*3]-mean[0])+(pts[k*3+1]-mean[1])*(pts[k*3+1]-mean[1]));
1594 }
1595 dist[len]=1-dst/len/len;
1596 }
1597
1598 vector<float> nd=do_filter(dist,ft,7);
1599 nd=do_filter(nd,ft,7);
1600 // length of the first rod
1601 for (int j=7; j<49; j++){
1602 if(nd[j]>nd[j-1] && nd[j]>nd[j+1]){
1603 hlxlen[i]=j-6;
1604 break;
1605 }
1606 }
1607
1608 if(hlxlen[i]>25) hlxlen[i]=0;
1609 }
1610 // filter the array before further process
1611// hlxlen[50]=100;
1612// for (int i=0; i<n; i++) printf("%d\t%f\n",i,hlxlen[i]);
1613// for (int i=0; i<3; i++) hlxlen=do_filter(hlxlen,ft,7);
1614// for (int i=0; i<n; i++) printf("%d\t%f\n",i,hlxlen[i]);
1615 vector<float> ishlx(n);
1616 int hlx=0;
1617 float up=minlength; // rod length threshold
1618 // record position of possible helixes
1619 for (size_t i=0; i<n; i++){
1620 if(hlx<=0){
1621 if(hlxlen[i]>up){
1622 hlx=hlxlen[i];
1623 helix.push_back(i);
1624 helix.push_back(i+hlxlen[i]-5);
1625 }
1626 }
1627 else{
1628 hlx--;
1629 ishlx[i]=hlxlen[i];
1630 }
1631 }
1632 // while counting reversely
1633 if(dir==0){
1634 for (size_t i=0; i<helix.size(); i++) helix[i]=n-1-helix[i];
1635 for (size_t i=0; i<helix.size()/2; i++){
1636 int tmp=helix[i*2+1];
1637 helix[i*2+1]=helix[i*2];
1638 helix[i*2]=tmp;
1639 }
1640 }
1641
1642 }
1643
1644#ifdef DEBUG
1645 printf("potential helix counting from both sides: \n");
1646 for (size_t i=0; i<helix.size()/2; i++){
1647 printf("%d\t%d\n",helix[i*2],helix[i*2+1]);
1648 }
1649 printf("\n\n");
1650#endif
1651/*
1652
1653 // Combine the result from both side
1654 for (size_t i=0; i<helix.size()/2; i++){
1655 int change=1;
1656 while(change==1){
1657 change=0;
1658 for (size_t j=i+1; j<helix.size()/2; j++){
1659 if(helix[j*2]==0) continue;
1660 if(helix[j*2]-2<helix[i*2+1] && helix[j*2+1]+2>helix[i*2]){
1661 helix[i*2]=(helix[i*2]<helix[j*2])?helix[i*2]:helix[j*2];
1662 helix[i*2+1]=(helix[i*2+1]>helix[j*2+1])?helix[i*2+1]:helix[j*2+1];
1663 helix[j*2]=0;
1664 helix[j*2+1]=0;
1665 change=1;
1666 }
1667 }
1668 }
1669 }*/
1670
1671 vector<int> allhlx;
1672 int minid=1;
1673 while (minid>=0){
1674 int mins=10000;
1675 minid=-1;
1676 for (size_t i=0;i<helix.size()/2; i++){
1677 if(helix[i*2]<.1) continue;
1678 if(helix[i*2]<mins){
1679 mins=helix[i*2];
1680 minid=i;
1681 }
1682 }
1683 if(minid>=0){
1684 allhlx.push_back(helix[minid*2]);
1685 allhlx.push_back(helix[minid*2+1]);
1686 helix[minid*2]=-1;
1687 }
1688 }
1689
1690#ifdef DEBUG
1691 printf("combined result: \n");
1692 for (size_t i=0; i<allhlx.size()/2; i++){
1693 printf("%d\t%d\n",allhlx[i*2],allhlx[i*2+1]);
1694 }
1695 printf("\n\n");
1696#endif
1697
1698 // local search to decide the start and end point of each helix
1699// vector<float> allscore(allhlx.size()/2);
1700 for (size_t i=0; i<allhlx.size()/2; i++){
1701 int sz=5;
1702 size_t start=allhlx[i*2]-sz,end=allhlx[i*2+1]+sz;
1703 start=start>0?start:0;
1704 end=end<n?end:n;
1705 float minscr=100000;
1706 int mj=0,mk=0;
1707
1708 for (size_t j=start; j<end; j++){
1709 for (size_t k=j+6; k<end; k++){
1710 vector<float> eigvec=do_pca(j,k);
1711 vector<float> pts((k-j)*3);
1712 float mean[3];
1713 for (int u=0; u<3; u++) mean[u]=0;
1714 for (size_t u=j; u<k; u++){
1715 for (int v=0; v<3; v++){
1716 pts[(u-j)*3+v]=points[u*4+0]*eigvec[v*3+0]+points[u*4+1]*eigvec[v*3+1]+points[u*4+2]*eigvec[v*3+2];
1717 mean[v]+=pts[(u-j)*3+v];
1718 }
1719 }
1720 for (size_t u=0; u<3; u++) mean[u]/=(k-j);
1721 float dst=0;
1722 // distance to the center axis
1723 for (size_t u=0; u<k-j; u++){
1724 dst+=sqrt((pts[u*3]-mean[0])*(pts[u*3]-mean[0])+(pts[u*3+1]-mean[1])*(pts[u*3+1]-mean[1]));
1725 }
1726 float len=k-j;
1727 float scr=dst/len/len;
1728 if (scr<minscr){
1729// printf("%f\t%d\t%d\n",scr,j,k);
1730 minscr=scr;
1731 mj=j;
1732 mk=k;
1733 }
1734 }
1735 }
1736
1737// printf("%d\t%d\n",mj,mk);
1738
1739 allhlx[i*2]=mj;
1740 allhlx[i*2+1]=mk;
1741// allscore[i]=minscr;
1742// if (mk-mj>60)
1743// allscore[i]=100;
1744 }
1745
1746 for (size_t i=0; i<edge.size()/2; i++){
1747 allhlx.push_back(edge[i*2]);
1748 allhlx.push_back(edge[i*2+1]);
1749 }
1750
1751 vector<int> allhlx2;
1752 minid=1;
1753 while (minid>=0){
1754 int mins=10000;
1755 minid=-1;
1756 for (size_t i=0;i<allhlx.size()/2; i++){
1757 if(allhlx[i*2]<.1) continue;
1758 if(allhlx[i*2]<mins){
1759 mins=allhlx[i*2];
1760 minid=i;
1761 }
1762 }
1763 if(minid>=0){
1764 allhlx2.push_back(allhlx[minid*2]<allhlx[minid*2+1]?allhlx[minid*2]:allhlx[minid*2+1]);
1765 allhlx2.push_back(allhlx[minid*2]>allhlx[minid*2+1]?allhlx[minid*2]:allhlx[minid*2+1]);
1766 allhlx[minid*2]=-1;
1767 }
1768 }
1769 allhlx=allhlx2;
1770
1771#ifdef DEBUG
1772 printf("Fitted helixes: \n");
1773 for (size_t i=0; i<allhlx.size()/2; i++){
1774 printf("%d\t%d\n",allhlx[i*2],allhlx[i*2+1]);
1775 }
1776 printf("\n\n");
1777#endif
1778 // create ideal helix
1779 size_t ia=0,ka=0;
1780 int dir;
1781 vector<double> finalhlx;
1782 vector<double> hlxid;
1783 printf("Confirming helix... \n");
1784 while(ia<n){
1785 if (int(ia)==allhlx[ka*2]){
1786// int sz=(allhlx[ka*2+1]-allhlx[ka*2])>10?5:(allhlx[ka*2+1]-allhlx[ka*2])/2;
1787 int sz=3;
1788 float score=0,maxscr=0;
1789 float bestphs=0,phsscore=0,pscore=0;
1790 int mi=0,mj=0;
1791 for (int i=0; i<sz; i++){
1792 for (int j=0; j<sz; j++){
1793 int start=allhlx[ka*2]+i,end=allhlx[ka*2+1]-j;
1794 phsscore=0;bestphs=-1;
1795 for (float phs=-180; phs<180; phs+=10){ //search for phase
1796 construct_helix(start,end,phs,pscore,dir);
1797 if (pscore>phsscore){
1798 phsscore=pscore;
1799 bestphs=phs;
1800 }
1801 }
1802// printf("%f\t",bestphs);
1803 construct_helix(start,end,bestphs,score,dir);
1804 if (score>maxscr){
1805 maxscr=score;
1806 mi=i;
1807 mj=j;
1808 }
1809 }
1810 }
1811 int start=allhlx[ka*2]+mi,end=allhlx[ka*2+1]-mj;
1812 printf("%d\t%d\t%f\tden %d\t",start,end,maxscr,maxscr>mindensity);
1813 if (maxscr>mindensity){
1814 phsscore=0;
1815 for (float phs=-180; phs<180; phs+=10){ //search for phase
1816 construct_helix(start,end,phs,pscore,dir);
1817 if (pscore>phsscore){
1818 phsscore=pscore;
1819 bestphs=phs;
1820 }
1821 }
1822 vector<double> pts=construct_helix(start,end,bestphs,score,dir);
1823 int lendiff=end-start-pts.size()/3-2;
1824 printf("dir %d\t",dir);
1825 printf("len %lu\t diff %d\t",pts.size()/3-2,lendiff);
1826 if (pts.size()/3-2>minl && abs(lendiff)<15){
1827
1828 for (int i=0; i<mi; i++){
1829 finalhlx.push_back(points[(i+ia)*4]);
1830 finalhlx.push_back(points[(i+ia)*4+1]);
1831 finalhlx.push_back(points[(i+ia)*4+2]);
1832 }
1833 hlxid.push_back(finalhlx.size()/3+1);
1834 printf("%lu\t",finalhlx.size()/3+1);
1835 for (size_t j=3; j<pts.size()-3; j++)
1836 finalhlx.push_back(pts[j]);
1837 hlxid.push_back(finalhlx.size()/3-2);
1838 printf("%lu\t",finalhlx.size()/3-2);
1839 for (size_t j=0; j<3; j++)
1840 hlxid.push_back(pts[j]);
1841 for (size_t j=pts.size()-3; j<pts.size(); j++)
1842 hlxid.push_back(pts[j]);
1843 ia=end;
1844 }
1845 else{
1846 printf("\t *");
1847
1848 }
1849
1850 }
1851 printf("\n\n");
1852 ka++;
1853 while(allhlx[ka*2]<int(ia))
1854 ka++;
1855 }
1856 else{
1857// printf("%d\t",ia);
1858 finalhlx.push_back(points[ia*4]);
1859 finalhlx.push_back(points[ia*4+1]);
1860 finalhlx.push_back(points[ia*4+2]);
1861 ia++;
1862 }
1863 }
1864
1865 set_number_points(finalhlx.size()/3);
1866
1867 for (size_t i=0; i<n; i++){
1868 for (size_t j=0; j<3; j++)
1869 points[i*4+j]=finalhlx[i*3+j];
1870 points[i*4+3]=0;
1871 }
1872
1873 printf("\n\n");
1874 return hlxid;
1875}
vector< double > construct_helix(int start, int end, float phs, float &score, int &dir)
Construct an ideal helix between the start and end points given phase.
void reverse_chain()
Reverse the pointarray chain.
vector< float > do_filter(vector< float > pts, float *ft, int num)
Filter the point array to smooth the line, used in helix fitting in pathwalker.

References construct_helix(), do_filter(), do_pca(), eigvec, map, n, points, reverse_chain(), set_number_points(), and sqrt().

◆ get_bounding_box()

Region PointArray::get_bounding_box ( )

Definition at line 482 of file pointarray.cpp.

483{
484 double xmin, ymin, zmin;
485 double xmax, ymax, zmax;
486 xmin = xmax = points[0];
487 ymin = ymax = points[1];
488 zmin = zmax = points[2];
489 for ( size_t i = 0; i < 4 * get_number_points(); i += 4) {
490 if (points[i] > xmax)
491 xmax = points[i];
492 if (points[i] < xmin)
493 xmin = points[i];
494 if (points[i + 1] > ymax)
495 ymax = points[i + 1];
496 if (points[i + 1] < ymin)
497 ymin = points[i + 1];
498 if (points[i + 2] > zmax)
499 zmax = points[i + 2];
500 if (points[i + 2] < zmin)
501 zmin = points[i + 2];
502 }
503 return Region(xmin, ymin, zmin, xmax - xmin, ymax - ymin, zmax - zmin);
504}
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
Definition: geometry.h:497

References get_number_points(), and points.

◆ get_center()

FloatPoint PointArray::get_center ( )

Definition at line 453 of file pointarray.cpp.

454{
455 double xc, yc, zc;
456 xc = yc = zc = 0.0;
457 double norm = 0.0;
458 for ( size_t i = 0; i < 4 * get_number_points(); i += 4) {
459 xc += points[i] * points[i + 3];
460 yc += points[i + 1] * points[i + 3];
461 zc += points[i + 2] * points[i + 3];
462 norm += points[i + 3];
463 }
464 if (norm <= 0) {
465 fprintf(stderr, "Abnormal total value (%g) for PointArray, it should be >0\n", norm);
466 return FloatPoint(0, 0, 0);
467 }
468 else
469 return FloatPoint(xc / norm, yc / norm, zc / norm);
470}

References get_number_points(), and points.

Referenced by calc_transform(), and center_to_zero().

◆ get_number_points()

size_t PointArray::get_number_points ( ) const

◆ get_points()

vector< float > PointArray::get_points ( )

Returns all x,y,z triplets packed into a vector<float>

Returns
All points packed into a vector<float>

Definition at line 594 of file pointarray.cpp.

594 {
595vector<float> ret;
596for (unsigned int i=0; i<n; i++) {
597 ret.push_back((float)points[i*4]);
598 ret.push_back((float)points[i*4+1]);
599 ret.push_back((float)points[i*4+2]);
600}
601
602return ret;
603}

References n, and points.

◆ get_points_array()

double * PointArray::get_points_array ( )

Definition at line 182 of file pointarray.cpp.

183{
184 return points;
185}

References points.

Referenced by copy(), mask(), mask_asymmetric_unit(), operator=(), set_from(), and set_from_density_map().

◆ get_value_at()

double PointArray::get_value_at ( int  i)

Definition at line 2932 of file pointarray.cpp.

2933{
2934return points[i*4+3];
2935}

References points.

◆ get_vector_at()

Vec3f PointArray::get_vector_at ( int  i)

Definition at line 2927 of file pointarray.cpp.

2928{
2929return Vec3f((float)points[i*4],(float)points[i*4+1],(float)points[i*4+2]);
2930}

References points.

Referenced by align_2d(), calc_transform(), and distmx().

◆ mask()

void PointArray::mask ( double  rmax,
double  rmin = 0.0 
)

Definition at line 507 of file pointarray.cpp.

508{
509 double rmax2 = rmax * rmax, rmin2 = rmin * rmin;
510 PointArray *tmp = this->copy();
511 double *tmp_points = tmp->get_points_array();
512 int count = 0;
513 for ( size_t i = 0; i < 4 * tmp->get_number_points(); i += 4) {
514 double x = tmp_points[i], y = tmp_points[i + 1], z = tmp_points[i + 2], v =
515 tmp_points[i + 3];
516 double r2 = x * x + y * y + z * z;
517 if (r2 >= rmin2 && r2 <= rmax2) {
518 points[count * 4] = x;
519 points[count * 4 + 1] = y;
520 points[count * 4 + 2] = z;
521 points[count * 4 + 3] = v;
522 ++count;
523 }
524 }
525 set_number_points(count);
526 if( tmp )
527 {
528 delete tmp;
529 tmp = 0;
530 }
531}
PointArray * copy()
Definition: pointarray.cpp:149
#define y(i, j)
Definition: projector.cpp:1516
#define x(i)
Definition: projector.cpp:1517

References copy(), get_number_points(), get_points_array(), points, set_number_points(), x, and y.

◆ mask_asymmetric_unit()

void PointArray::mask_asymmetric_unit ( const string &  sym)

Definition at line 534 of file pointarray.cpp.

535{
536 if (sym == "c1" || sym == "C1")
537 return; // do nothing for C1 symmetry
538 double alt0 = 0, alt1 = M_PI, alt2 = M_PI;
539 double az0 = 0, az1 = M_PI;
540 if (sym[0] == 'c' || sym[0] == 'C') {
541 int nsym = atoi(sym.c_str() + 1);
542 az1 = 2.0 * M_PI / nsym / 2.0;
543 }
544 else if (sym[0] == 'd' || sym[0] == 'D') {
545 int nsym = atoi(sym.c_str() + 1);
546 alt1 = M_PI / 2.0;
547 alt2 = alt1;
548 az1 = 2.0 * M_PI / nsym / 2.0;
549 }
550 else if (sym == "icos" || sym == "ICOS") {
551 alt1 = 0.652358139784368185995; // 5fold to 3fold
552 alt2 = 0.55357435889704525151; // half of edge ie. 5fold to 2fold along the edge
553 az1 = 2.0 * M_PI / 5 / 2.0;
554 }
555 else {
556 LOGERR("PointArray::set_to_asymmetric_unit(): sym = %s is not implemented yet",
557 sym.c_str());
558 return;
559 }
560#ifdef DEBUG
561 printf("Sym %s: alt0 = %8g\talt1 = %8g\talt2 = %8g\taz0 = %8g\taz1 = %8g\n", sym.c_str(), alt0*180.0/M_PI, alt1*180.0/M_PI, alt2*180.0/M_PI, az0*180.0/M_PI, az1*180.0/M_PI);
562#endif
563
564 PointArray *tmp = this->copy();
565 double *tmp_points = tmp->get_points_array();
566 int count = 0;
567 for ( size_t i = 0; i < 4 * tmp->get_number_points(); i += 4) {
568 double x = tmp_points[i], y = tmp_points[i + 1], z = tmp_points[i + 2], v = tmp_points[i + 3];
569 double az = atan2(y, x);
570 double az_abs = fabs(az - az0);
571 if (az_abs < (az1 - az0)) {
572 double alt_max = alt1 + (alt2 - alt1) * az_abs / (az1 - az0);
573 double alt = acos(z / sqrt(x * x + y * y + z * z));
574 if (alt < alt_max && alt >= alt0) {
575#ifdef DEBUG
576 printf("Point %3lu: x,y,z = %8g,%8g,%8g\taz = %8g\talt = %8g\n",i/4,x,y,z,az*180.0/M_PI, alt*180.0/M_PI);
577#endif
578 points[count * 4] = x;
579 points[count * 4 + 1] = y;
580 points[count * 4 + 2] = z;
581 points[count * 4 + 3] = v;
582 count++;
583 }
584 }
585 }
586 set_number_points(count);
587 if( tmp )
588 {
589 delete tmp;
590 tmp = 0;
591 }
592}
#define LOGERR
Definition: log.h:51

References copy(), get_number_points(), get_points_array(), LOGERR, points, set_number_points(), sqrt(), x, and y.

◆ match_points()

vector< int > PointArray::match_points ( PointArray to,
float  max_miss = -1.0 
)

Will try to establish a 1-1 correspondence between points in two different PointArray objects (this and to).

Returns a vector<int> where the index is addresses the points in 'this' and the value addresses points in 'to'. A value of -1 means there was no match for that point.

Returns
A vector<int> with the mapping of points from 'this' to 'to'. e.g. - ret[2]=5 means point 2 in 'this' matches point 5 in 'to'

Definition at line 217 of file pointarray.cpp.

217 {
218EMData *mx0=distmx(1);
219EMData *mx1=to->distmx(1);
220unsigned int n2=mx1->get_xsize(); // same as get_number_points on to
221
222if (max_miss<0) max_miss=(float)mx0->get_attr("sigma")/10.0f;
223//printf("max error %f\n",max_miss);
224
225
226
227vector<int> ret(n,-1);
228vector<float> rete(n,0.0);
229unsigned int i,j,k,l;
230
231if (!mx0 || !mx1) {
232 if (mx0) delete mx0;
233 if (mx1) delete mx1;
234 return ret;
235}
236
237// i iterates over elements of 'this', j looks for a match in 'to'
238// k and l iterate over the individual distances
239for (i=0; i<n; i++) {
240 int bestn=-1; // number of best match in mx1
241 double bestd=1.0e38; // residual error distance in best match
242 for (j=0; j<n2; j++) {
243 double d=0;
244 int nd=0;
245 for (k=l=0; k<n-1 && l<n2-1; k++,l++) {
246 float d1=fabs(mx0->get_value_at(k,i)-mx1->get_value_at(l,j));
247 float d2=fabs(mx0->get_value_at(k+1,i)-mx1->get_value_at(l,j));
248 float d3=fabs(mx0->get_value_at(k,i)-mx1->get_value_at(l+1,j));
249 float d4=fabs(mx0->get_value_at(k+1,i)-mx1->get_value_at(l+1,j));
250 if (d2<d1 && d4>d2) { l--; continue; }
251 if (d3<d1 && d4>d3) { k--; continue; }
252 d+=d1;
253 nd++;
254 }
255 d/=(float)nd;
256// printf("%d -> %d\t%f\t%d\n",i,j,d,nd);
257 if (d<bestd) { bestd=d; bestn=j; }
258 }
259 ret[i]=bestn;
260 rete[i]=static_cast<float>(bestd);
261}
262
263// This will remove duplicate assignments, keeping the best one
264// also remove any assignments with large errors
265for (i=0; i<n; i++) {
266 for (j=0; j<n; j++) {
267 if (rete[i]>max_miss) { ret[i]=-1; break; }
268 if (i==j || ret[i]!=ret[j] || ret[i]==-1) continue;
269 if (rete[i]>rete[j]) { ret[i]=-1; break; }
270 }
271}
272
273delete mx0;
274delete mx1;
275
276return ret;
277}
EMData * distmx(int sortrows=0)
Calculates a (symmetrized) distance matrix for the current PointArray.
Definition: pointarray.cpp:192

References distmx(), and n.

Referenced by align_2d().

◆ merge_to()

void PointArray::merge_to ( PointArray pa,
float  thr = 3.5 
)

Merge to another point array.

Combine close points

Definition at line 2001 of file pointarray.cpp.

2002{
2003 printf("merging\n");
2004 vector<double> result;
2005 for (size_t i=0; i<pa.n; i++){
2006 result.push_back(pa.points[i*4]);
2007 result.push_back(pa.points[i*4+1]);
2008 result.push_back(pa.points[i*4+2]);
2009 }
2010 for (size_t i=0; i<n; i++){
2011 float dist=100;
2012 for (size_t j=0; j<pa.n; j++){
2013 Vec3f d(points[i*4]-pa.points[j*4],points[i*4+1]-pa.points[j*4+1],points[i*4+2]-pa.points[j*4+2]);
2014 dist=d.length();
2015 if (dist<thr)
2016 break;
2017 }
2018 printf("%f\n",dist);
2019 if (dist>thr){
2020 result.push_back(points[i*4]);
2021 result.push_back(points[i*4+1]);
2022 result.push_back(points[i*4+2]);
2023 }
2024 }
2025 set_number_points(result.size()/3);
2026 for (size_t i=0; i<n; i++){
2027 for (size_t j=0; j<3; j++)
2028 points[i*4+j]=result[i*3+j];
2029 points[i*4+3]=0;
2030 }
2031 printf("done\n");
2032
2033}

References EMAN::Vec3< Type >::length(), n, points, and set_number_points().

◆ operator=()

PointArray & PointArray::operator= ( PointArray pa)

Definition at line 159 of file pointarray.cpp.

160{
161 if (this != &pa) {
163 memcpy(get_points_array(), pa.get_points_array(), sizeof(double) * 4 * get_number_points());
164 }
165 return *this;
166}

References get_number_points(), get_points_array(), and set_number_points().

◆ opt_from_proj()

void PointArray::opt_from_proj ( const vector< EMData * > &  proj,
float  pixres 
)

Optimizes a pointarray based on a set of projection images (EMData objects) This is effectively a 3D reconstruction algorithm.

Author
Steve Ludtke 11/27/2004
Parameters
projA vector of EMData objects containing projections with orientations
pixresSize of each Gaussian in pixels

Definition at line 2904 of file pointarray.cpp.

2904 {
2905#ifdef USE_OPTPP
2906 optdata=proj;
2907 optobj=this;
2908 optpixres=pixres;
2909
2910 FDNLF1 nlf(get_number_points()*4,calc_opt_proj,init_opt_proj);
2911// NLF1 nlf(get_number_points()*4,init_opt_proj,calc_opt_projd);
2912 nlf.initFcn();
2913
2914 OptCG opt(&nlf);
2915// OptQNewton opt(&nlf);
2916 opt.setMaxFeval(2000);
2917 opt.optimize();
2918 opt.printStatus("Done");
2919#else
2920 (void)proj; //suppress warning message
2921 (void)pixres; //suppress warning message
2922 LOGWARN("OPT++ support not enabled.\n");
2923 return;
2924#endif
2925}
#define LOGWARN
Definition: log.h:53

References get_number_points(), and LOGWARN.

◆ pdb2mrc_by_nfft()

EMData * PointArray::pdb2mrc_by_nfft ( int  map_size,
float  apix,
float  res 
)

Definition at line 2534 of file pointarray.cpp.

2535{
2536#if defined USE_NFFT
2537 nfft_3D_plan my_plan; // plan for the nfft
2538
2540 nfft_3D_init(&my_plan, map_size, get_number_points());
2541
2543 for (int j = 0, i = 0; j < my_plan.M; j++, i += 4) {
2544 // FFTW and nfft use row major array layout, EMAN uses column major
2545 my_plan.v[3 * j + 2] = (fftw_real) (points[i] / (apix * map_size));
2546 my_plan.v[3 * j + 1] = (fftw_real) (points[i + 1] / (apix * map_size));
2547 my_plan.v[3 * j] = (fftw_real) (points[i + 2] / (apix * map_size));
2548 my_plan.f[j].re = (fftw_real) (points[i + 3]);
2549 my_plan.f[j].im = 0.0;
2550 }
2551
2553 if (my_plan.nfft_flags & PRE_PSI) {
2554 nfft_3D_precompute_psi(&my_plan);
2555 }
2556
2557 // compute the uniform Fourier transform
2558 nfft_3D_transpose(&my_plan);
2559
2560 // copy the Fourier transform to EMData data array
2561 EMData *fft = new EMData();
2562 fft->set_size(map_size + 2, map_size, map_size);
2563 fft->set_complex(true);
2564 fft->set_ri(true);
2565 fft->to_zero();
2566 float *data = fft->get_data();
2567 double norm = 1.0 / (map_size * map_size * map_size);
2568 for (int k = 0; k < map_size; k++) {
2569 for (int j = 0; j < map_size; j++) {
2570 for (int i = 0; i < map_size / 2; i++) {
2571 data[k * map_size * (map_size + 2) + j * (map_size + 2) + 2 * i] =
2572 (float) (my_plan.
2573 f_hat[k * map_size * map_size + j * map_size + i +
2574 map_size / 2].re) * norm;
2575 data[k * map_size * (map_size + 2) + j * (map_size + 2) + 2 * i + 1] =
2576 (float) (my_plan.
2577 f_hat[k * map_size * map_size + j * map_size + i +
2578 map_size / 2].im) * norm * (-1.0);
2579 }
2580 }
2581 }
2583 nfft_3D_finalize(&my_plan);
2584
2585 // low pass processor
2586 double sigma2 = (map_size * apix / res) * (map_size * apix / res);
2587 int index = 0;
2588 for (int k = 0; k < map_size; k++) {
2589 double RZ2 = (k - map_size / 2) * (k - map_size / 2);
2590 for (int j = 0; j < map_size; j++) {
2591 double RY2 = (j - map_size / 2) * (j - map_size / 2);
2592 for (int i = 0; i < map_size / 2 + 1; i++, index += 2) {
2593 float val = exp(-(i * i + RY2 + RZ2) / sigma2);
2594 data[index] *= val;
2595 data[index + 1] *= val;
2596 }
2597 }
2598 }
2599 fft->update();
2600 //fft->process_inplace("filter.lowpass.gauss",Dict("cutoff_abs", map_size*apix/res));
2601
2602 fft->process_inplace("xform.phaseorigin.tocorner"); // move phase origin to center of image map_size, instead of at corner
2603 EMData *map = fft->do_ift();
2604 map->set_attr("apix_x", apix);
2605 map->set_attr("apix_y", apix);
2606 map->set_attr("apix_z", apix);
2607 map->set_attr("origin_x", -map_size/2*apix);
2608 map->set_attr("origin_y", -map_size/2*apix);
2609 map->set_attr("origin_z", -map_size/2*apix);
2610 if( fft )
2611 {
2612 delete fft;
2613 fft = 0;
2614 }
2615 return map;
2616#elif defined NFFT2
2617 nfft_plan my_plan; // plan for the nfft
2618
2620 nfft_init_3d(&my_plan, map_size, map_size, map_size, get_number_points());
2621
2623 for (int j = 0, i = 0; j < my_plan.M; j++, i += 4) {
2624 // FFTW and nfft use row major array layout, EMAN uses column major
2625 my_plan.x[3 * j + 2] = (double) (points[i] / (apix * map_size));
2626 my_plan.x[3 * j + 1] = (double) (points[i + 1] / (apix * map_size));
2627 my_plan.x[3 * j] = (double) (points[i + 2] / (apix * map_size));
2628 my_plan.f[j][0] = (double) (points[i + 3]);
2629 my_plan.f[j][1] = 0.0;
2630 }
2631
2633 if (my_plan.nfft_flags & PRE_PSI) {
2634 nfft_precompute_psi(&my_plan);
2635 if (my_plan.nfft_flags & PRE_FULL_PSI)
2636 nfft_full_psi(&my_plan, pow(10, -10));
2637 }
2638
2639 // compute the uniform Fourier transform
2640 nfft_transposed(&my_plan);
2641
2642 // copy the Fourier transform to EMData data array
2643 EMData *fft = new EMData();
2644 fft->set_size(map_size + 2, map_size, map_size);
2645 fft->set_complex(true);
2646 fft->set_ri(true);
2647 fft->to_zero();
2648 float *data = fft->get_data();
2649 double norm = 1.0 / (map_size * map_size * map_size);
2650 for (int k = 0; k < map_size; k++) {
2651 for (int j = 0; j < map_size; j++) {
2652 for (int i = 0; i < map_size / 2; i++) {
2653 data[k * map_size * (map_size + 2) + j * (map_size + 2) + 2 * i] =
2654 (float) (my_plan.
2655 f_hat[k * map_size * map_size + j * map_size + i +
2656 map_size / 2][0]) * norm;
2657 data[k * map_size * (map_size + 2) + j * (map_size + 2) + 2 * i + 1] =
2658 (float) (my_plan.
2659 f_hat[k * map_size * map_size + j * map_size + i +
2660 map_size / 2][1]) * norm;
2661 }
2662 }
2663 }
2665 nfft_finalize(&my_plan);
2666
2667 // low pass processor
2668 double sigma2 = (map_size * apix / res) * (map_size * apix / res);
2669 int index = 0;
2670 for (int k = 0; k < map_size; k++) {
2671 double RZ2 = (k - map_size / 2) * (k - map_size / 2);
2672 for (int j = 0; j < map_size; j++) {
2673 double RY2 = (j - map_size / 2) * (j - map_size / 2);
2674 for (int i = 0; i < map_size / 2 + 1; i++, index += 2) {
2675 float val = exp(-(i * i + RY2 + RZ2) / sigma2);
2676 data[index] *= val;
2677 data[index + 1] *= val;
2678 }
2679 }
2680 }
2681 fft->update();
2682 //fft->process_inplace(".filter.lowpass.gauss",Dict("cutoff_abs", map_size*apix/res));
2683
2684 fft->process_inplace("xform.phaseorigin.tocenter"); // move phase origin to center of image map_size, instead of at corner
2685 EMData *map = fft->do_ift();
2686 map->set_attr("apix_x", apix);
2687 map->set_attr("apix_y", apix);
2688 map->set_attr("apix_z", apix);
2689 map->set_attr("origin_x", -map_size / 2 * apix);
2690 map->set_attr("origin_y", -map_size / 2 * apix);
2691 map->set_attr("origin_z", -map_size / 2 * apix);
2692 if( fft )
2693 {
2694 delete fft;
2695 fft = 0;
2696 }
2697 return map;
2698#else
2699 LOGWARN("nfft support is not enabled. please recompile with nfft support enabled\n");
2700 return 0;
2701#endif
2702}

References apix, get_number_points(), LOGWARN, map, and points.

◆ pdb2mrc_by_summation()

EMData * PointArray::pdb2mrc_by_summation ( int  map_size,
float  apix,
float  res,
int  addpdbbfactor 
)

Definition at line 2276 of file pointarray.cpp.

2277{
2278#ifdef DEBUG
2279 printf("PointArray::pdb2mrc_by_summation(): %lu points\tmapsize = %4d\tapix = %g\tres = %g\n",get_number_points(),map_size, apix, res);
2280#endif
2281 //if ( gauss_real_width < apix) LOGERR("PointArray::projection_by_summation(): apix(%g) is too large for resolution (%g Angstrom in Fourier space) with %g pixels of 1/e half width", apix, res, gauss_real_width);
2282
2283 double min_table_val = 1e-7;
2284 double max_table_x = sqrt(-log(min_table_val)); // for exp(-x*x)
2285
2286 double table_step_size = 0.001; // number of steps for each pixel
2287 double inv_table_step_size = 1.0 / table_step_size;
2288
2289// sort_by_axis(2); // sort by Z-axis
2290
2291 EMData *map = new EMData();
2292 map->set_size(map_size, map_size, map_size);
2293 map->to_zero();
2294 float *pd = map->get_data();
2295
2296 vector<double> table;
2297 double gauss_real_width;
2298 int table_size;
2299 int gbox;
2300
2301
2302 for ( size_t s = 0; s < get_number_points(); ++s) {
2303 double xc = points[4 * s] / apix + map_size / 2;
2304 double yc = points[4 * s + 1] / apix + map_size / 2;
2305 double zc = points[4 * s + 2] / apix + map_size / 2;
2306 double fval = points[4 * s + 3];
2307
2308 //printf("\n bfactor=%f",bfactor[s]);
2309
2310 if(addpdbbfactor==-1){
2311 gauss_real_width = res/M_PI; // in Angstrom, res is in Angstrom
2312 }else{
2313 gauss_real_width = (bfactor[s])/(4*sqrt(2.0)*M_PI); // in Angstrom, res is in Angstrom
2314 }
2315
2316 table_size = int (max_table_x * gauss_real_width / (apix * table_step_size) * 1.25);
2317 table.resize(table_size);
2318 for (int i = 0; i < table_size; i++){
2319 table[i] = 0;
2320 }
2321
2322 for (int i = 0; i < table_size; i++) {
2323 double x = -i * table_step_size * apix / gauss_real_width;
2324 if(addpdbbfactor==-1){
2325 table[i] = exp(-x * x);
2326 }
2327 else{
2328 table[i] = exp(-x * x)/sqrt(gauss_real_width * gauss_real_width * 2 * M_PI);
2329 }
2330 }
2331
2332 gbox = int (max_table_x * gauss_real_width / apix); // local box half size in pixels to consider for each point
2333 if (gbox <= 0)
2334 gbox = 1;
2335
2336 int imin = int (xc) - gbox, imax = int (xc) + gbox;
2337 int jmin = int (yc) - gbox, jmax = int (yc) + gbox;
2338 int kmin = int (zc) - gbox, kmax = int (zc) + gbox;
2339 if (imin < 0)
2340 imin = 0;
2341 if (jmin < 0)
2342 jmin = 0;
2343 if (kmin < 0)
2344 kmin = 0;
2345 if (imax > map_size)
2346 imax = map_size;
2347 if (jmax > map_size)
2348 jmax = map_size;
2349 if (kmax > map_size)
2350 kmax = map_size;
2351
2352 for (int k = kmin; k < kmax; k++) {
2353 size_t table_index_z = size_t (fabs(k - zc) * inv_table_step_size);
2354 if ( table_index_z >= table.size() ) continue;
2355 double zval = table[table_index_z];
2356 size_t pd_index_z = k * map_size * map_size;
2357
2358 for (int j = jmin; j < jmax; j++) {
2359 size_t table_index_y = size_t (fabs(j - yc) * inv_table_step_size);
2360 if ( table_index_y >= table.size() ) continue;
2361 double yval = table[table_index_y];
2362 size_t pd_index = pd_index_z + j * map_size + imin;
2363 for (int i = imin; i < imax; i++, pd_index++) {
2364 size_t table_index_x = size_t (fabs(i - xc) * inv_table_step_size);
2365 if ( table_index_x >= table.size() ) continue;
2366 double xval = table[table_index_x];
2367 pd[pd_index] += (float) (fval * zval * yval * xval);
2368 }
2369 }
2370 }
2371 }
2372
2373 map->update();
2374 map->set_attr("apix_x", apix);
2375 map->set_attr("apix_y", apix);
2376 map->set_attr("apix_z", apix);
2377 map->set_attr("origin_x", -map_size/2*apix);
2378 map->set_attr("origin_y", -map_size/2*apix);
2379 map->set_attr("origin_z", -map_size/2*apix);
2380
2381 return map;
2382}
EMData * log() const
return natural logarithm image for a image

References apix, bfactor, get_number_points(), log(), map, points, sqrt(), and x.

◆ projection_by_nfft()

EMData * PointArray::projection_by_nfft ( int  image_size,
float  apix,
float  res = 0 
)

Definition at line 2704 of file pointarray.cpp.

2705{
2706#if defined USE_NFFT
2707 nfft_2D_plan my_plan; // plan for the nfft
2708 int N[2], n[2];
2709 N[0] = image_size;
2710 n[0] = next_power_of_2(2 * image_size);
2711 N[1] = image_size;
2712 n[1] = next_power_of_2(2 * image_size);
2713
2715 nfft_2D_init(&my_plan, image_size, get_number_points());
2716 //nfft_2D_init_specific(&my_plan, N, get_number_points(), n, 3,
2717 // PRE_PHI_HUT | PRE_PSI,
2718 // FFTW_ESTIMATE | FFTW_OUT_OF_PLACE);
2720 for (int j = 0, i = 0; j < my_plan.M; j++, i += 4) {
2721 // FFTW and nfft use row major array layout, EMAN uses column major
2722 my_plan.v[2 * j + 1] = (fftw_real) (points[i] / (apix * image_size));
2723 my_plan.v[2 * j] = (fftw_real) (points[i + 1] / (apix * image_size));
2724 my_plan.f[j].re = (fftw_real) points[i + 3];
2725 my_plan.f[j].im = 0.0;
2726 }
2727
2729 if (my_plan.nfft_flags & PRE_PSI) {
2730 nfft_2D_precompute_psi(&my_plan);
2731 }
2732
2733 // compute the uniform Fourier transform
2734 nfft_2D_transpose(&my_plan);
2735
2736 // copy the Fourier transform to EMData data array
2737 EMData *fft = new EMData();
2738 fft->set_size(image_size + 2, image_size, 1);
2739 fft->set_complex(true);
2740 fft->set_ri(true);
2741 fft->to_zero();
2742 float *data = fft->get_data();
2743 double norm = 1.0 / (image_size * image_size);
2744 for (int j = 0; j < image_size; j++) {
2745 for (int i = 0; i < image_size / 2; i++) {
2746 data[j * (image_size + 2) + 2 * i] =
2747 (float) (my_plan.f_hat[j * image_size + i + image_size / 2].re) * norm;
2748 data[j * (image_size + 2) + 2 * i + 1] =
2749 (float) (my_plan.f_hat[j * image_size + i + image_size / 2].im) * norm * (-1.0);
2750 }
2751 }
2753 nfft_2D_finalize(&my_plan);
2754
2755 if (res > 0) {
2756 // Gaussian low pass processor
2757 double sigma2 = (image_size * apix / res) * (image_size * apix / res);
2758 int index = 0;
2759 for (int j = 0; j < image_size; j++) {
2760 double RY2 = (j - image_size / 2) * (j - image_size / 2);
2761 for (int i = 0; i < image_size / 2 + 1; i++, index += 2) {
2762 double val = exp(-(i * i + RY2) / sigma2);
2763 data[index] *= val;
2764 data[index + 1] *= val;
2765 }
2766 }
2767 }
2768 fft->update();
2769 //fft->process_inplace("filter.lowpass.gauss",Dict("cutoff_abs", box*apix/res));
2770
2771 fft->process_inplace("xform.phaseorigin.tocenter"); // move phase origin to center of image box, instead of at corner
2772
2773 return fft;
2774#elif defined NFFT2
2775 nfft_plan my_plan; // plan for the nfft
2776 int N[2], n[2];
2777 N[0] = image_size;
2778 n[0] = next_power_of_2(2 * image_size);
2779 N[1] = image_size;
2780 n[1] = next_power_of_2(2 * image_size);
2781
2783 //nfft_init_2d(&my_plan,image_size,image_size,get_number_points());
2784 nfft_init_specific(&my_plan, 2, N, get_number_points(), n, 3,
2785 PRE_PHI_HUT | PRE_PSI |
2786 MALLOC_X | MALLOC_F_HAT | MALLOC_F, FFTW_ESTIMATE | FFTW_DESTROY_INPUT);
2788 for (int j = 0, i = 0; j < my_plan.M; j++, i += 4) {
2789 // FFTW and nfft use row major array layout, EMAN uses column major
2790 my_plan.x[2 * j + 1] = (double) (points[i] / (apix * image_size));
2791 my_plan.x[2 * j] = (double) (points[i + 1] / (apix * image_size));
2792 my_plan.f[j][0] = (double) points[i + 3];
2793 my_plan.f[j][1] = 0.0;
2794 }
2795
2797 if (my_plan.nfft_flags & PRE_PSI) {
2798 nfft_precompute_psi(&my_plan);
2799 if (my_plan.nfft_flags & PRE_FULL_PSI)
2800 nfft_full_psi(&my_plan, pow(10, -6));
2801 }
2802
2803 // compute the uniform Fourier transform
2804 nfft_transposed(&my_plan);
2805
2806 // copy the Fourier transform to EMData data array
2807 EMData *fft = new EMData();
2808 fft->set_size(image_size + 2, image_size, 1);
2809 fft->set_complex(true);
2810 fft->set_ri(true);
2811 fft->to_zero();
2812 float *data = fft->get_data();
2813 double norm = 1.0 / (image_size * image_size);
2814 for (int j = 0; j < image_size; j++) {
2815 for (int i = 0; i < image_size / 2; i++) {
2816 data[j * (image_size + 2) + 2 * i] =
2817 (float) (my_plan.f_hat[j * image_size + i + image_size / 2][0]) * norm;
2818 data[j * (image_size + 2) + 2 * i + 1] =
2819 (float) (my_plan.f_hat[j * image_size + i + image_size / 2][1]) * norm;
2820 }
2821 }
2823 nfft_finalize(&my_plan);
2824
2825 if (res > 0) {
2826 // Gaussian low pass process
2827 double sigma2 = (image_size * apix / res) * (image_size * apix / res);
2828 int index = 0;
2829 for (int j = 0; j < image_size; j++) {
2830 double RY2 = (j - image_size / 2) * (j - image_size / 2);
2831 for (int i = 0; i < image_size / 2 + 1; i++, index += 2) {
2832 double val = exp(-(i * i + RY2) / sigma2);
2833 data[index] *= val;
2834 data[index + 1] *= val;
2835 }
2836 }
2837 }
2838 fft->update();
2839 //fft->process_inplace("filter.lowpass.gauss",Dict("cutoff_abs", box*apix/res));
2840
2841 fft->process_inplace("xform.phaseorigin.tocenter"); // move phase origin to center of image box, instead of at corner
2842
2843 return fft;
2844#else
2845 LOGWARN("nfft support is not enabled. please recompile with nfft support enabled\n");
2846 return 0;
2847#endif
2848}

References apix, get_number_points(), LOGWARN, n, and points.

◆ projection_by_summation()

EMData * PointArray::projection_by_summation ( int  image_size,
float  apix,
float  res 
)

Definition at line 2385 of file pointarray.cpp.

2386{
2387 double gauss_real_width = res / (M_PI); // in Angstrom, res is in Angstrom
2388 //if ( gauss_real_width < apix) LOGERR("PointArray::projection_by_summation(): apix(%g) is too large for resolution (%g Angstrom in Fourier space) with %g pixels of 1/e half width", apix, res, gauss_real_width);
2389
2390 double min_table_val = 1e-7;
2391 double max_table_x = sqrt(-log(min_table_val)); // for exp(-x*x)
2392
2393 //double table_step_size = 0.001; // number of steps for x=[0,1] in exp(-x*x)
2394 //int table_size = int(max_table_x / table_step_size *1.25);
2395 //double* table = (double*)malloc(sizeof(double) * table_size);
2396 //for(int i=0; i<table_size; i++) table[i]=exp(-i*i*table_step_size*table_step_size);
2397
2398 double table_step_size = 0.001; // number of steps for each pixel
2399 double inv_table_step_size = 1.0 / table_step_size;
2400 int table_size = int (max_table_x * gauss_real_width / (apix * table_step_size) * 1.25);
2401 double *table = (double *) malloc(sizeof(double) * table_size);
2402 for (int i = 0; i < table_size; i++) {
2403 double x = -i * table_step_size * apix / gauss_real_width;
2404 table[i] = exp(-x * x);
2405 }
2406
2407 int gbox = int (max_table_x * gauss_real_width / apix); // local box half size in pixels to consider for each point
2408 if (gbox <= 0)
2409 gbox = 1;
2410 EMData *proj = new EMData();
2411 proj->set_size(image_size, image_size, 1);
2412 proj->to_zero();
2413 float *pd = proj->get_data();
2414 for ( size_t s = 0; s < get_number_points(); ++s) {
2415 double xc = points[4 * s] / apix + image_size / 2;
2416 double yc = points[4 * s + 1] / apix + image_size / 2;
2417 double fval = points[4 * s + 3];
2418 int imin = int (xc) - gbox, imax = int (xc) + gbox;
2419 int jmin = int (yc) - gbox, jmax = int (yc) + gbox;
2420 if (imin < 0)
2421 imin = 0;
2422 if (jmin < 0)
2423 jmin = 0;
2424 if (imax > image_size)
2425 imax = image_size;
2426 if (jmax > image_size)
2427 jmax = image_size;
2428
2429 for (int j = jmin; j < jmax; j++) {
2430 //int table_index_y = int(fabs(j-yc)*apix/gauss_real_width/table_step_size);
2431 int table_index_y = int (fabs(j - yc) * inv_table_step_size);
2432 double yval = table[table_index_y];
2433#ifdef DEBUG
2434 //double yval2 = exp( - (j-yc)*(j-yc)*apix*apix/(gauss_real_width*gauss_real_width));
2435 //if(fabs(yval2-yval)/yval2>1e-2) printf("s=%d\txc,yc=%g,%g\tyval,yval2=%g,%g\tdiff=%g\n",s,xc,yc,yval,yval2,fabs(yval2-yval)/yval2);
2436#endif
2437 int pd_index = j * image_size + imin;
2438 for (int i = imin; i < imax; i++, pd_index++) {
2439 //int table_index_x = int(fabs(i-xc)*apix/gauss_real_width/table_step_size);
2440 int table_index_x = int (fabs(i - xc) * inv_table_step_size);
2441 double xval = table[table_index_x];
2442#ifdef DEBUG
2443 //double xval2 = exp( - (i-xc)*(i-xc)*apix*apix/(gauss_real_width*gauss_real_width));
2444 //if(fabs(xval2-xval)/xval2>1e-2) printf("\ts=%d\txc,yc=%g,%g\txval,xval2=%g,%g\tdiff=%g\n",s,xc,yc,xval,xval2,fabs(xval2-xval)/xval2);
2445#endif
2446 pd[pd_index] += (float)(fval * yval * xval);
2447 }
2448 }
2449 }
2450 for (int i = 0; i < image_size * image_size; i++)
2451 pd[i] /= sqrt(M_PI);
2452 proj->update();
2453 return proj;
2454}

References apix, get_number_points(), log(), points, sqrt(), and x.

◆ read_ca_from_pdb()

bool PointArray::read_ca_from_pdb ( const char *  file)

Read only C-alpha atoms from a pdb file.

Definition at line 2197 of file pointarray.cpp.

2198{
2199 struct stat filestat;
2200 stat(file, &filestat);
2201 set_number_points(( int)(filestat.st_size / 80 + 1));
2202
2203 #ifdef DEBUG
2204 printf("PointArray::read_from_pdb(): try %4lu atoms first\n", get_number_points());
2205 #endif
2206
2207 FILE *fp = fopen(file, "r");
2208 if(!fp) {
2209 fprintf(stderr,"ERROR in PointArray::read_from_pdb(): cannot open file %s\n",file);
2210 throw;
2211 }
2212 char s[200];
2213 size_t count = 0;
2214
2215 while ((fgets(s, 200, fp) != NULL)) {
2216 if (strncmp(s, "ENDMDL", 6) == 0)
2217 break;
2218 if (strncmp(s, "ATOM", 4) != 0)
2219 continue;
2220
2221 if (s[13] == ' ')
2222 s[13] = s[14];
2223 if (s[13] == ' ')
2224 s[13] = s[15];
2225
2226 float e = 6;
2227 char ctt, ctt2 = ' ';
2228 if (s[13] == ' ')
2229 ctt = s[14];
2230 else if (s[12] == ' ') {
2231 ctt = s[13];
2232 ctt2 = s[14];
2233 }
2234 else {
2235 ctt = s[12];
2236 ctt2 = s[13];
2237 }
2238 if (ctt != 'C' || ctt2 != 'A')
2239 continue;
2240
2241 float x, y, z, q;
2242 sscanf(&s[28], " %f %f %f", &x, &y, &z);
2243 sscanf(&s[60], " %f", &q);
2244
2245 if (count + 1 > get_number_points())
2246 set_number_points(2 * (count + 1)); //makes sure point array is big enough
2247
2248#ifdef DEBUG
2249 printf("Atom %4lu: x,y,z = %8g,%8g,%8g\te = %g\n", count, x, y, z, e);
2250#endif
2251 points[4 * count] = x;
2252 points[4 * count + 1] = y;
2253 points[4 * count + 2] = z;
2254 points[4 * count + 3] = e;
2255 bfactor[count] = q;
2256 count++;
2257 }
2258 fclose(fp);
2259 set_number_points(count);
2260 return true;
2261}

References bfactor, get_number_points(), points, set_number_points(), x, and y.

◆ read_from_pdb()

bool PointArray::read_from_pdb ( const char *  file,
const vector< int > &  lines = vector<int>() 
)

Definition at line 329 of file pointarray.cpp.

330{
331 struct stat filestat;
332 stat(file, &filestat);
333 set_number_points(( int)(filestat.st_size / 80 + 1));
334
335 #ifdef DEBUG
336 printf("PointArray::read_from_pdb(): try %4lu atoms first\n", get_number_points());
337 #endif
338
339 FILE *fp = fopen(file, "r");
340 if(!fp) {
341 fprintf(stderr,"ERROR in PointArray::read_from_pdb(): cannot open file %s\n",file);
342 throw;
343 }
344 char s[200];
345 size_t count = 0;
346
347 int line_num = -1;
348
349 set<int> lines_set(begin(lines), end(lines)); // searching in sets should be faster than vectors
350
351 while ((fgets(s, 200, fp) != NULL)) {
352 line_num++;
353
354 if(find(begin(lines_set), end(lines_set), line_num) == end(lines_set))
355 continue;
356
357 if (strncmp(s, "ENDMDL", 6) == 0)
358 break;
359 if (strncmp(s, "ATOM", 4) != 0)
360 continue;
361
362 if (s[13] == ' ')
363 s[13] = s[14];
364 if (s[13] == ' ')
365 s[13] = s[15];
366
367 float e = 0;
368 char ctt, ctt2 = ' ';
369 if (s[13] == ' ')
370 ctt = s[14];
371 else if (s[12] == ' ') {
372 ctt = s[13];
373 ctt2 = s[14];
374 }
375 else {
376 ctt = s[12];
377 ctt2 = s[13];
378 }
379
380 switch (ctt) {
381 case 'H':
382 e = 1.0;
383 break;
384 case 'C':
385 e = 6.0;
386 break;
387 case 'A':
388 if (ctt2 == 'U') {
389 e = 79.0;
390 break;
391 }
392 // treat 'A'mbiguous atoms as N, not perfect, but good enough
393 case 'N':
394 e = 7.0;
395 break;
396 case 'O':
397 e = 8.0;
398 break;
399 case 'P':
400 e = 15.0;
401 break;
402 case 'S':
403 e = 16.0;
404 break;
405 case 'W':
406 e = 18.0;
407 break; // ficticious water 'atom'
408 case 'K':
409 e = 19.0;
410 break;
411 default:
412 fprintf(stderr, "Unknown atom %c%c\n", ctt, ctt2);
413 e = 0;
414 }
415 if (e == 0)
416 continue;
417
418 float x, y, z, q;
419 sscanf(&s[28], " %f %f %f", &x, &y, &z);
420 sscanf(&s[60], " %f", &q);
421
422 if (count + 1 > get_number_points())
423 set_number_points(2 * (count + 1)); //makes sure point array is big enough
424
425#ifdef DEBUG
426 printf("Atom %4lu: x,y,z = %8g,%8g,%8g\te = %g\n", count, x, y, z, e);
427#endif
428 points[4 * count] = x;
429 points[4 * count + 1] = y;
430 points[4 * count + 2] = z;
431 points[4 * count + 3] = e;
432 bfactor[count] = q;
433 count++;
434 }
435 fclose(fp);
436 set_number_points(count);
437 return true;
438}

References bfactor, get_number_points(), points, set_number_points(), x, and y.

Referenced by EMAN::PDBReader::makePointArray().

◆ remove_helix_from_map()

void PointArray::remove_helix_from_map ( EMData m,
vector< float >  hlxid 
)

Remove the corresponding density of the helix point from a density map.

Definition at line 2071 of file pointarray.cpp.

2071 {
2072
2073 int sx=m->get_xsize(),sy=m->get_ysize(),sz=m->get_zsize();
2074 float ax=m->get_attr("apix_x"),ay=m->get_attr("apix_y"),az=m->get_attr("apix_z");
2075 for (int x=0; x<sx; x++){
2076 for (int y=0; y<sy; y++){
2077 for (int z=0; z<sz; z++){
2078 Vec3f p0((x)*ax,(y)*ay,(z)*az);
2079 bool inhlx=false;
2080 for (size_t i=0; i<hlxid.size()/8; i++){
2081 Vec3f p1(hlxid[i*8+2],hlxid[i*8+3],hlxid[i*8+4]),p2(hlxid[i*8+5],hlxid[i*8+6],hlxid[i*8+7]);
2082 Vec3f dp=p2-p1;
2083 float l=dp.length();
2084 float d=((p0-p1).cross(p0-p2)).length()/l;
2085 float t=-(p1-p0).dot(p2-p1)/(l*l);
2086 if (d<5 && t>0 && t<1){
2087 inhlx=true;
2088 break;
2089 }
2090 }
2091 if(inhlx){
2092 m->set_value_at(x,y,z,0);
2093 }
2094
2095 }
2096 }
2097 }
2098}
Vector3 cross(const Vector3 &w, const Vector3 &v)
Definition: vecmath.h:309
double dot(const Vector3 &w, const Vector3 &v)
Definition: vecmath.h:305

References EMAN::cross(), EMAN::dot(), EMAN::Vec3< Type >::length(), EMAN::length(), x, and y.

◆ replace_by_summation()

void PointArray::replace_by_summation ( EMData image,
int  i,
Vec3f  vec,
float  amp,
float  apix,
float  res 
)

Definition at line 2456 of file pointarray.cpp.

2457{
2458 double gauss_real_width = res / (M_PI); // in Angstrom, res is in Angstrom
2459
2460 double min_table_val = 1e-7;
2461 double max_table_x = sqrt(-log(min_table_val)); // for exp(-x*x)
2462
2463 double table_step_size = 0.001; // number of steps for each pixel
2464 double inv_table_step_size = 1.0 / table_step_size;
2465 int table_size = int (max_table_x * gauss_real_width / (apix * table_step_size) * 1.25);
2466 double *table = (double *) malloc(sizeof(double) * table_size);
2467 for (int i = 0; i < table_size; i++) {
2468 double x = -i * table_step_size * apix / gauss_real_width;
2469 table[i] = exp(-x * x)/pow((float)M_PI,.25f);
2470 }
2471 int image_size=proj->get_xsize();
2472
2473 // subtract the old point
2474 int gbox = int (max_table_x * gauss_real_width / apix); // local box half size in pixels to consider for each point
2475 if (gbox <= 0)
2476 gbox = 1;
2477 float *pd = proj->get_data();
2478 int s = ind;
2479 double xc = points[4 * s] / apix + image_size / 2;
2480 double yc = points[4 * s + 1] / apix + image_size / 2;
2481 double fval = points[4 * s + 3];
2482 int imin = int (xc) - gbox, imax = int (xc) + gbox;
2483 int jmin = int (yc) - gbox, jmax = int (yc) + gbox;
2484
2485 if (imin < 0) imin = 0;
2486 if (jmin < 0) jmin = 0;
2487 if (imax > image_size) imax = image_size;
2488 if (jmax > image_size) jmax = image_size;
2489
2490 for (int j = jmin; j < jmax; j++) {
2491 int table_index_y = int (fabs(j - yc) * inv_table_step_size);
2492 double yval = table[table_index_y];
2493 int pd_index = j * image_size + imin;
2494 for (int i = imin; i < imax; i++, pd_index++) {
2495 int table_index_x = int (fabs(i - xc) * inv_table_step_size);
2496 double xval = table[table_index_x];
2497 pd[pd_index] -= (float)(fval * yval * xval);
2498 }
2499 }
2500
2501 // add the new point
2502 gbox = int (max_table_x * gauss_real_width / apix); // local box half size in pixels to consider for each point
2503 if (gbox <= 0)
2504 gbox = 1;
2505 pd = proj->get_data();
2506 s = ind;
2507 xc = vec[0] / apix + image_size / 2;
2508 yc = vec[1] / apix + image_size / 2;
2509 fval = amp;
2510 imin = int (xc) - gbox, imax = int (xc) + gbox;
2511 jmin = int (yc) - gbox, jmax = int (yc) + gbox;
2512
2513 if (imin < 0) imin = 0;
2514 if (jmin < 0) jmin = 0;
2515 if (imax > image_size) imax = image_size;
2516 if (jmax > image_size) jmax = image_size;
2517
2518 for (int j = jmin; j < jmax; j++) {
2519 int table_index_y = int (fabs(j - yc) * inv_table_step_size);
2520 double yval = table[table_index_y];
2521 int pd_index = j * image_size + imin;
2522 for (int i = imin; i < imax; i++, pd_index++) {
2523 int table_index_x = int (fabs(i - xc) * inv_table_step_size);
2524 double xval = table[table_index_x];
2525 pd[pd_index] -= (float)(fval * yval * xval);
2526 }
2527 }
2528
2529 proj->update();
2530 return;
2531}

References apix, log(), points, sqrt(), and x.

◆ reverse_chain()

void PointArray::reverse_chain ( )

Reverse the pointarray chain.

Definition at line 2175 of file pointarray.cpp.

2175 {
2176 // reverse the point array chain, from the last to the first point
2177 double tmp;
2178// for(int i=0; i<n/2; i++){
2179// for (int j=0; j<4; j++){
2180// printf("%f\t",
2181 for(size_t i=0; i<n/2; i++){
2182 for (size_t j=0; j<4; j++){
2183 tmp=points[(n-1-i)*4+j];
2184 points[(n-1-i)*4+j]=points[i*4+j];
2185 points[i*4+j]=tmp;
2186 }
2187 }
2188}

References n, and points.

Referenced by fit_helix().

◆ right_transform()

void PointArray::right_transform ( const Transform transform)

Does Transform*v as opposed to v*Transform (as in the transform function)

Parameters
transforman EMAN2 Transform object

Definition at line 617 of file pointarray.cpp.

617 {
618 for ( unsigned int i = 0; i < 4 * n; i += 4) {
619 Transform s = transform.transpose();
620 Vec3f v((float)points[i],(float)points[i+1],(float)points[i+2]);
621 v= s*v;
622 points[i] =v[0];
623 points[i+1]=v[1];
624 points[i+2]=v[2];
625 }
626}
void transform(const Transform &transform)
Definition: pointarray.cpp:605

References n, points, and transform().

◆ save_pdb_with_helix()

void PointArray::save_pdb_with_helix ( const char *  file,
vector< float >  hlxid 
)

Save the point array to pdb file, including helices information.

Definition at line 2053 of file pointarray.cpp.

2054{
2055
2056 FILE *fp = fopen(file, "w");
2057
2058 for (size_t i=0; i<hlxid.size()/8; i++){
2059 fprintf(fp, "HELIX%5lu A ALA A%5d ALA A%5d 1 %5d\n",
2060 i, (int)hlxid[i*8], (int)hlxid[i*8+1], int(hlxid[i*8+1]-hlxid[i*8]+4));
2061 }
2062 for ( size_t i = 0; i < get_number_points(); i++) {
2063 fprintf(fp, "ATOM %5lu CA ALA A%4lu %8.3f%8.3f%8.3f%6.2f%6.2f%8s\n", i, i,
2064 points[4 * i], points[4 * i + 1], points[4 * i + 2], points[4 * i + 3], 0.0, " ");
2065 }
2066 fprintf(fp, "TER %5lu ALA A%4lu\nEND", get_number_points(),get_number_points()-1);
2067
2068 fclose(fp);
2069}

References get_number_points(), and points.

◆ save_to_pdb()

void PointArray::save_to_pdb ( const char *  file)

Definition at line 441 of file pointarray.cpp.

442{
443 FILE *fp = fopen(file, "w");
444 for ( size_t i = 0; i < get_number_points(); i++) {
445 fprintf(fp, "ATOM %5lu CA ALA A%4lu %8.3f%8.3f%8.3f%6.2f%6.2f%8s\n", i, i,
446 points[4 * i], points[4 * i + 1], points[4 * i + 2], points[4 * i + 3], 0.0, " ");
447 }
448 fprintf(fp, "TER %5lu ALA A%4lu\nEND", get_number_points(),get_number_points()-1);
449 fclose(fp);
450}

References get_number_points(), and points.

◆ set_from() [1/3]

void PointArray::set_from ( double *  source,
int  num,
const string &  sym = "",
Transform transform = 0 
)

Definition at line 632 of file pointarray.cpp.

633{
634 int nsym = xform->get_nsym(sym);
635 if (xform==0){
636 Transform tr;
637 xform=&tr;
638 }
639
640 if (get_number_points() != (size_t)nsym * num)
641 set_number_points((size_t)nsym * num);
642
643 double *target = get_points_array();
644
645 for ( int s = 0; s < nsym; s++) {
646 int index = s * 4 * num;
647 for ( int i = 0; i < 4 * num; i += 4, index += 4) {
648 Vec3f v((float)src[i],(float)src[i+1],(float)src[i+2]);
649 v=v*xform->get_sym(sym,s);
650 target[index] =v[0];
651 target[index+1]=v[1];
652 target[index+2]=v[2];
653 target[index+3]=src[i+3];
654 }
655 }
656}

References EMAN::Transform::get_nsym(), get_number_points(), get_points_array(), EMAN::Transform::get_sym(), and set_number_points().

◆ set_from() [2/3]

void PointArray::set_from ( PointArray source,
const string &  sym = "",
Transform transform = 0 
)

Definition at line 627 of file pointarray.cpp.

628{
629 set_from(source->get_points_array(), source->get_number_points(), sym, transform);
630}
void set_from(vector< float >)
Definition: pointarray.cpp:658

References get_number_points(), get_points_array(), set_from(), and transform().

◆ set_from() [3/3]

void PointArray::set_from ( vector< float >  pts)

Definition at line 658 of file pointarray.cpp.

658 {
659 set_number_points(pts.size()/4);
660 for (unsigned int i=0; i<pts.size(); i++) points[i]=pts[i];
661}

References points, and set_number_points().

Referenced by set_from().

◆ set_from_density_map()

void PointArray::set_from_density_map ( EMData map,
int  num,
float  thresh,
float  apix,
Density2PointsArrayAlgorithm  mode = PEAKS_DIV 
)

Definition at line 663 of file pointarray.cpp.

665{
666 if (mode == PEAKS_SUB || mode == PEAKS_DIV) {
667 // find out how many voxels are useful voxels
668 int num_voxels = 0;
669 int nx = map->get_xsize(), ny = map->get_ysize(), nz = map->get_zsize();
670 size_t size = (size_t)nx * ny * nz;
671 EMData *tmp_map = map->copy();
672 float *pd = tmp_map->get_data();
673 for (size_t i = 0; i < size; ++i) {
674 if (pd[i] > thresh)
675 ++num_voxels;
676 }
677
678 double pointvol = double (num_voxels) / double (num);
679 double gauss_real_width = pow(pointvol, 1. / 3.); // in pixels
680#ifdef DEBUG
681 printf("Average point range radius = %g pixels for %d points from %d used voxels\n",
682 gauss_real_width, num, num_voxels);
683#endif
684
685 double min_table_val = 1e-4;
686 double max_table_x = sqrt(-log(min_table_val)); // for exp(-x*x)
687
688 double table_step_size = 1.; // number of steps for each pixel
689 double inv_table_step_size = 1.0 / table_step_size;
690 int table_size = int (max_table_x * gauss_real_width / (table_step_size) * 1.25) + 1;
691 double *table = (double *) malloc(sizeof(double) * table_size);
692 for (int i = 0; i < table_size; i++) {
693 double x = i * table_step_size / gauss_real_width;
694 table[i] = exp(-x * x);
695 }
696
697 int gbox = int (max_table_x * gauss_real_width); // local box half size in pixels to consider for each point
698 if (gbox <= 0)
699 gbox = 1;
700
702 for (int count = 0; count < num; count++) {
703 float cmax = pd[0];
704 int cmaxpos = 0;
705 for (size_t i = 0; i < size; ++i) {
706 if (pd[i] > cmax) {
707 cmax = pd[i];
708 cmaxpos = i;
709 }
710 }
711 int iz = cmaxpos / (nx * ny), iy = (cmaxpos - iz * nx * ny) / nx, ix =
712 cmaxpos - iz * nx * ny - iy * nx;
713
714 // update coordinates in pixels
715 points[4*count ] = ix;
716 points[4*count+1] = iy;
717 points[4*count+2] = iz;
718 points[4*count+3] = cmax;
719#ifdef DEBUG
720 printf("Point %d: val = %g\tat %d, %d, %d\n", count, cmax, ix, iy, iz);
721#endif
722
723 int imin = ix - gbox, imax = ix + gbox;
724 int jmin = iy - gbox, jmax = iy + gbox;
725 int kmin = iz - gbox, kmax = iz + gbox;
726 if (imin < 0)
727 imin = 0;
728 if (jmin < 0)
729 jmin = 0;
730 if (kmin < 0)
731 kmin = 0;
732 if (imax > nx)
733 imax = nx;
734 if (jmax > ny)
735 jmax = ny;
736 if (kmax > nz)
737 kmax = nz;
738
739 for (int k = kmin; k < kmax; ++k) {
740 int table_index_z = int (fabs(double (k - iz)) * inv_table_step_size);
741 double zval = table[table_index_z];
742 size_t pd_index_z = k * nx * ny;
743 //printf("k = %8d\tx = %8g\tval = %8g\n", k, float(k-iz), zval);
744 for (int j = jmin; j < jmax; ++j) {
745 int table_index_y = int (fabs(double (j - iy)) * inv_table_step_size);
746 double yval = table[table_index_y];
747 size_t pd_index = pd_index_z + j * nx + imin;
748 for (int i = imin; i < imax; ++i, ++pd_index) {
749 int table_index_x = int (fabs(double (i - ix)) * inv_table_step_size);
750 double xval = table[table_index_x];
751 if (mode == PEAKS_SUB)
752 pd[pd_index] -= (float)(cmax * zval * yval * xval);
753 else
754 pd[pd_index] *= (float)(1.0 - zval * yval * xval); // mode == PEAKS_DIV
755 }
756 }
757 }
758 }
760 tmp_map->update();
761 if( tmp_map )
762 {
763 delete tmp_map;
764 tmp_map = 0;
765 }
766 }
767 else if (mode == KMEANS) {
769 zero();
770
771 PointArray tmp_pa;
772 tmp_pa.set_number_points(num);
773 tmp_pa.zero();
774
775 int nx = map->get_xsize(), ny = map->get_ysize(), nz = map->get_zsize();
776 float *pd = map->get_data();
777
778 // initialize segments with random centers at pixels with values > thresh
779#ifdef DEBUG
780 printf("Start initial random seeding\n");
781#endif
782 for ( size_t i = 0; i < get_number_points(); i++) {
783 int x, y, z;
784 double v;
785 do {
786 x = ( int) Util::get_frand(0, nx - 1);
787 y = ( int) Util::get_frand(0, ny - 1);
788 z = ( int) Util::get_frand(0, nz - 1);
789 v = pd[z * nx * ny + y * nx + x];
790#ifdef DEBUG
791 printf("Trying Point %lu: val = %g\tat %d, %d, %d\tfrom map (%d,%d,%d)\n", i, v, x,
792 y, z, nx, ny, nz);
793#endif
794 } while (v <= thresh);
795 points[4 * i] = (double) x;
796 points[4 * i + 1] = (double) y;
797 points[4 * i + 2] = (double) z;
798 points[4 * i + 3] = (double) v;
799#ifdef DEBUG
800 printf("Point %lu: val = %g\tat %g, %g, %g\n", i, points[4 * i + 3], points[4 * i],
801 points[4 * i + 1], points[4 * i + 2]);
802#endif
803 }
804
805 double min_dcen = 1e0; // minimal mean segment center shift as convergence criterion
806 double dcen = 0.0;
807 int iter = 0, max_iter = 100;
808 do {
809#ifdef DEBUG
810 printf("Iteration %3d, start\n", iter);
811#endif
812 double *tmp_points = tmp_pa.get_points_array();
813
814 // reassign each pixel to the best segment
815 for ( int k = 0; k < nz; k++) {
816 for ( int j = 0; j < ny; j++) {
817 for ( int i = 0; i < nx; i++) {
818 size_t idx = k * nx * ny + j * nx + i;
819 if (pd[idx] > thresh) {
820 double min_dist = 1e60; // just a large distance
821 int min_s = 0;
822 for ( size_t s = 0; s < get_number_points(); ++s) {
823 double x = points[4 * s];
824 double y = points[4 * s + 1];
825 double z = points[4 * s + 2];
826 double dist =
827 (k - z) * (k - z) + (j - y) * (j - y) + (i - x) * (i - x);
828 if (dist < min_dist) {
829 min_dist = dist;
830 min_s = s;
831 }
832 }
833 tmp_points[4 * min_s] += i;
834 tmp_points[4 * min_s + 1] += j;
835 tmp_points[4 * min_s + 2] += k;
836 tmp_points[4 * min_s + 3] += 1.0;
837 }
838 }
839 }
840 }
841#ifdef DEBUG
842 printf("Iteration %3d, finished reassigning segments\n", iter);
843#endif
844 // update each segment's center
845 dcen = 0.0;
846 for ( size_t s = 0; s < get_number_points(); ++s) {
847 if (tmp_points[4 * s + 3]) {
848 tmp_points[4 * s] /= tmp_points[4 * s + 3];
849 tmp_points[4 * s + 1] /= tmp_points[4 * s + 3];
850 tmp_points[4 * s + 2] /= tmp_points[4 * s + 3];
851#ifdef DEBUG
852 printf("Iteration %3d, Point %3lu at %8g, %8g, %8g -> %8g, %8g, %8g\n", iter, s,
853 points[4 * s], points[4 * s + 1], points[4 * s + 2], tmp_points[4 * s],
854 tmp_points[4 * s + 1], tmp_points[4 * s + 2]);
855#endif
856 }
857 else { // empty segments are reseeded
858 int x, y, z;
859 double v;
860 do {
861 x = ( int) Util::get_frand(0, nx - 1);
862 y = ( int) Util::get_frand(0, ny - 1);
863 z = ( int) Util::get_frand(0, nz - 1);
864 v = pd[z * nx * ny + y * nx + x];
865 } while (v <= thresh);
866 tmp_points[4 * s] = (double) x;
867 tmp_points[4 * s + 1] = (double) y;
868 tmp_points[4 * s + 2] = (double) z;
869 tmp_points[4 * s + 3] = (double) v;
870#ifdef DEBUG
871 printf
872 ("Iteration %3d, Point %3lu reseeded from %8g, %8g, %8g -> %8g, %8g, %8g\n",
873 iter, s, points[4 * s], points[4 * s + 1], points[4 * s + 2],
874 tmp_points[4 * s], tmp_points[4 * s + 1], tmp_points[4 * s + 2]);
875#endif
876 }
877 double dx = tmp_points[4 * s] - points[4 * s];
878 double dy = tmp_points[4 * s + 1] - points[4 * s + 1];
879 double dz = tmp_points[4 * s + 2] - points[4 * s + 2];
880 dcen += dx * dx + dy * dy + dz * dz;
881 }
882 dcen = sqrt(dcen / get_number_points());
883 //swap pointter, faster but risky
884#ifdef DEBUG
885 printf("before swap: points = %ld\ttmp_points = %ld\n", (long)get_points_array(),
886 (long)tmp_pa.get_points_array());
887#endif
888 double *tp = get_points_array();
889 set_points_array(tmp_points);
890 tmp_pa.set_points_array(tp);
891 tmp_pa.zero();
892#ifdef DEBUG
893 printf("after swap: points = %ld\ttmp_points = %ld\n", (long)get_points_array(),
894 (long)tmp_pa.get_points_array());
895 printf("Iteration %3d, finished updating segment centers with dcen = %g pixels\n", iter,
896 dcen);
897#endif
898
899 iter++;
900 } while (dcen > min_dcen && iter <= max_iter);
901 map->update();
902
903 sort_by_axis(2); // x,y,z axes = 0, 1, 2
904 }
905 else {
906 LOGERR("PointArray::set_from_density_map(): mode = %d is not implemented yet", mode);
907 }
908 //update to use apix and origin
909 int nx = map->get_xsize(), ny = map->get_ysize(), nz = map->get_zsize();
910 float origx, origy, origz;
911 try {
912 origx = map->get_attr("origin_x");
913 origy = map->get_attr("origin_y");
914 origz = map->get_attr("origin_z");
915 }
916 catch(...) {
917 origx = -nx / 2 * apix;
918 origy = -ny / 2 * apix;
919 origz = -nz / 2 * apix;
920 }
921
922#ifdef DEBUG
923 printf("Apix = %g\torigin x,y,z = %8g,%8g,%8g\n",apix, origx, origy, origz);
924#endif
925
926 float *pd = map->get_data();
927 for ( size_t i = 0; i < get_number_points(); ++i) {
928#ifdef DEBUG
929 printf("Point %4lu: x,y,z,v = %8g,%8g,%8g,%8g",i, points[4 * i],points[4 * i + 1],points[4 * i + 2],points[4 * i + 3]);
930#endif
931 points[4 * i + 3] =
932 pd[(int) points[4 * i + 2] * nx * ny + (int) points[4 * i + 1] * nx +
933 (int) points[4 * i]];
934 points[4 * i] = points[4 * i] * apix + origx;
935 points[4 * i + 1] = points[4 * i + 1] * apix + origy;
936 points[4 * i + 2] = points[4 * i + 2] * apix + origz;
937#ifdef DEBUG
938 printf("\t->\t%8g,%8g,%8g,%8g\n",points[4 * i],points[4 * i + 1],points[4 * i + 2],points[4 * i + 3]);
939#endif
940 }
941 map->update();
942}
void sort_by_axis(int axis=1)
void set_points_array(double *p)
Definition: pointarray.cpp:187
static float get_frand(int low, int high)
Get a float random number between low and high, [low, high)
Definition: util.cpp:725

References apix, EMAN::Util::get_frand(), get_number_points(), get_points_array(), KMEANS, log(), LOGERR, map, PEAKS_DIV, PEAKS_SUB, points, set_number_points(), set_points_array(), sort_by_axis(), sqrt(), x, y, and zero().

◆ set_number_points()

void PointArray::set_number_points ( size_t  nn)

Definition at line 173 of file pointarray.cpp.

174{
175 if (n != nn) {
176 n = nn;
177 points = (double *) realloc(points, 4 * n * sizeof(double));
178 bfactor = (double *) realloc(bfactor, n * sizeof(double));
179 }
180}

References bfactor, n, and points.

Referenced by copy(), delete_point(), fit_helix(), mask(), mask_asymmetric_unit(), merge_to(), operator=(), read_ca_from_pdb(), read_from_pdb(), set_from(), set_from_density_map(), and sim_add_point_double().

◆ set_points_array()

void PointArray::set_points_array ( double *  p)

Definition at line 187 of file pointarray.cpp.

188{
189 points = p;
190}

References points.

Referenced by set_from_density_map(), sim_add_point_double(), and sim_add_point_one().

◆ set_vector_at() [1/2]

void PointArray::set_vector_at ( int  i,
Vec3f  vec,
double  value 
)

Definition at line 2937 of file pointarray.cpp.

2938{
2939points[i*4]=vec[0];
2940points[i*4+1]=vec[1];
2941points[i*4+2]=vec[2];
2942points[i*4+3]=value;
2943}

References points.

◆ set_vector_at() [2/2]

void PointArray::set_vector_at ( int  i,
vector< double >  v 
)

Definition at line 2945 of file pointarray.cpp.

2946{
2947points[i*4] =v[0];
2948points[i*4+1]=v[1];
2949points[i*4+2]=v[2];
2950if (v.size()>=4) points[i*4+3]=v[3];
2951}

References points.

◆ sim_add_point_double()

void PointArray::sim_add_point_double ( )

Add more points during the simulation.

Definition at line 1345 of file pointarray.cpp.

1345 {
1346
1347 int nn=n*2;
1348 int tmpn=n;
1350 double* pa2data=(double *) calloc(4 * nn, sizeof(double));
1351 bool *newpt=new bool[nn];
1352 for (int i=0;i<nn;i++){
1353 if (i%2==0)
1354 newpt[i]=1;
1355 else
1356 newpt[i]=0;
1357 }
1358 int i=0;
1359 for (int ii=0;ii<nn;ii++){
1360 if (newpt[ii]) {
1361
1362 pa2data[ii*4]=points[i*4];
1363 pa2data[ii*4+1]=points[i*4+1];
1364 pa2data[ii*4+2]=points[i*4+2];
1365 pa2data[ii*4+3]=1;
1366 i++;
1367 }
1368 else{
1369 int k;
1370 if (i<tmpn)
1371 k=i;
1372 else
1373 k=0;
1374 pa2data[ii*4]=(points[k*4]+points[(i-1)*4])/2;
1375 pa2data[ii*4+1]=(points[k*4+1]+points[(i-1)*4+1])/2;
1376 pa2data[ii*4+2]=(points[k*4+2]+points[(i-1)*4+2])/2;
1377 pa2data[ii*4+3]=1;
1378 }
1379
1380 }
1381
1382 delete []newpt;
1383 free(points);
1384 set_points_array(pa2data);
1385
1386 if (adist) free(adist);
1387 if (aang) free(aang);
1388 if (adihed) free(adihed);
1389 adist=aang=adihed=0;
1391}
void sim_updategeom()
Updates the dist, ang, dihed parameters.
Definition: pointarray.cpp:945

References aang, adihed, adist, n, points, set_number_points(), set_points_array(), and sim_updategeom().

◆ sim_add_point_one()

void PointArray::sim_add_point_one ( )

Definition at line 1395 of file pointarray.cpp.

1395 {
1396
1397 double maxpot=-1000000,pot,meanpot=0;
1398 size_t ipt=0;
1399 bool onedge=0;
1400 // Find the highest potential point
1401 for (size_t i=0; i<n; i++) {
1402 meanpot+=sim_pointpotential(adist[i],aang[i],adihed[i]);
1403 pot=/*sim_pointpotential(adist[i],aang[i],adihed[i])*/-mapc*map->sget_value_at_interp(points[i*4]/apix+centx,points[i*4+1]/apix+centy,points[i*4+2]/apix+centz);
1404 if (pot>maxpot){
1405 maxpot=pot;
1406 ipt=i;
1407 }
1408 }
1409 meanpot/=n;
1410
1411 for (size_t i=0; i<n; i++) {
1412 int k=(i+1)%n;
1413 double pt0,pt1,pt2;
1414 pt0=(points[k*4]+points[i*4])/2;
1415 pt1=(points[k*4+1]+points[i*4+1])/2;
1416 pt2=(points[k*4+2]+points[i*4+2])/2;
1417 pot=/*meanpot*/-mapc*map->sget_value_at_interp(pt0/apix+centx,pt1/apix+centy,pt2/apix+centz);
1418 if (pot>maxpot){
1419 maxpot=pot;
1420 ipt=i;
1421 onedge=1;
1422 }
1423 }
1424
1425 // The rest points remain the same
1426 size_t i;
1427 double* pa2data=(double *) calloc(4 * (n+1), sizeof(double));
1428 for (size_t ii=0; ii<n+1; ii++) {
1429 if(ii!=ipt && ii!=ipt+1){
1430 if(ii<ipt)
1431 i=ii;
1432 else // shift the points after the adding position
1433 i=ii-1;
1434
1435 pa2data[ii*4]=points[i*4];
1436 pa2data[ii*4+1]=points[i*4+1];
1437 pa2data[ii*4+2]=points[i*4+2];
1438 pa2data[ii*4+3]=1;
1439 }
1440 }
1441 // Adding points
1442 if( onedge ) {
1443 size_t k1;
1444// k0=((ipt+n-1)%n);
1445 k1=((ipt+1)%n);
1446 pa2data[ipt*4]=points[ipt*4];
1447 pa2data[ipt*4+1]=points[ipt*4+1];
1448 pa2data[ipt*4+2]=points[ipt*4+2];
1449 pa2data[ipt*4+3]=1;
1450
1451 pa2data[(ipt+1)*4]=(points[ipt*4]+points[k1*4])/2;
1452 pa2data[(ipt+1)*4+1]=(points[ipt*4+1]+points[k1*4+1])/2;
1453 pa2data[(ipt+1)*4+2]=(points[ipt*4+2]+points[k1*4+2])/2;
1454 pa2data[(ipt+1)*4+3]=1;
1455
1456 }
1457 else {
1458 size_t k0,k1;
1459 k0=((ipt+n-1)%n);
1460 k1=((ipt+1)%n);
1461 pa2data[ipt*4]=(points[ipt*4]+points[k0*4])/2;
1462 pa2data[ipt*4+1]=(points[ipt*4+1]+points[k0*4+1])/2;
1463 pa2data[ipt*4+2]=(points[ipt*4+2]+points[k0*4+2])/2;
1464 pa2data[ipt*4+3]=1;
1465
1466 pa2data[(ipt+1)*4]=(points[ipt*4]+points[k1*4])/2;
1467 pa2data[(ipt+1)*4+1]=(points[ipt*4+1]+points[k1*4+1])/2;
1468 pa2data[(ipt+1)*4+2]=(points[ipt*4+2]+points[k1*4+2])/2;
1469 pa2data[(ipt+1)*4+3]=1;
1470
1471 }
1472 free(points);
1473 n++;
1474 set_points_array(pa2data);
1475
1476 if (adist) free(adist);
1477 if (aang) free(aang);
1478 if (adihed) free(adihed);
1479 adist=aang=adihed=0;
1481
1482 // search for the best position for the new points
1483 if (onedge){
1484 i=ipt+1;
1485 double bestpot=10000,nowpot;
1486 Vec3f old(points[i*4],points[(i+1)*4],points[(i+2)*4]);
1487 Vec3f newpt(points[i*4],points[(i+1)*4],points[(i+2)*4]);
1488 for (int ii=0;ii<5000;ii++){
1489 // Try to minimize potential globally
1490 boost::mt19937 rng;
1491 boost::normal_distribution<> nd(0.0, 0.0);
1492 boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor(rng, nd);
1493 points[i*4]=old[0]+var_nor();
1494 points[i*4+1]=old[1]+var_nor();
1495 points[i*4+2]=old[2]+var_nor();
1496 nowpot=sim_potentiald(i);
1497 if (nowpot<bestpot) {
1498 bestpot=nowpot;
1499 newpt[0]=points[i*4];
1500 newpt[1]=points[(i+1)*4];
1501 newpt[2]=points[(i+2)*4];
1502 }
1503 }
1504 points[i*4]=newpt[0];
1505 points[i*4+1]=newpt[1];
1506 points[i*4+2]=newpt[2];
1507 }
1508}
double sim_potentiald(int ind)
Compute a single point potential value.
double sim_pointpotential(double dist, double ang, double dihed)
Computes a potential value for a single point from a set of angles/distances using current energy set...
Definition: pointarray.h:142

References aang, adihed, adist, apix, centx, centy, centz, map, mapc, n, points, set_points_array(), sim_pointpotential(), sim_potentiald(), and sim_updategeom().

◆ sim_descent()

Vec3f PointArray::sim_descent ( int  i)

returns a vector pointing downhill for a single point

Definition at line 1108 of file pointarray.cpp.

1108 {
1109 Vec3f old(points[i*4],points[i*4+1],points[i*4+2]);
1110 double pot=0.,potx=0.,poty=0.,potz=0.;
1111 double stepsz=0.01;
1112
1113 for (int ii=i-2; ii<=i+2; ii++) pot+=sim_potentiald(ii);
1114// pot=potential();
1115
1116 points[i*4]=old[0]+stepsz;
1117 for (int ii=i-2; ii<=i+2; ii++) potx+=sim_potentiald(ii);
1118// potx=potential();
1119 points[i*4]=old[0];
1120
1121 points[i*4+1]=old[1]+stepsz;
1122 for (int ii=i-2; ii<=i+2; ii++) poty+=sim_potentiald(ii);
1123// poty=potential();
1124 points[i*4+1]=old[1];
1125
1126 points[i*4+2]=old[2]+stepsz;
1127 for (int ii=i-2; ii<=i+2; ii++) potz+=sim_potentiald(ii);
1128// potz=potential();
1129 points[i*4+2]=old[2];
1130
1131 // printf("%1.4g\t%1.4g\t%1.4g\t%1.4g\t%1.4g\t%1.4g\t%1.4g\n",pot,potx,poty,potz,(pot-potx),(pot-poty),(pot-potz));
1132
1133// if (pot==potx) potx=pot+1000000.0;
1134// if (pot==potx) potx=pot+1000000.0;
1135// if (pot==potx) potx=pot+1000000.0;
1136 return Vec3f((pot-potx),(pot-poty),(pot-potz));
1137}

References points, and sim_potentiald().

Referenced by sim_minstep(), and sim_minstep_seq().

◆ sim_minstep()

void PointArray::sim_minstep ( double  maxshift)

Takes a step to minimize the potential.

Definition at line 1140 of file pointarray.cpp.

1140 {
1141 vector<Vec3f> shifts;
1142
1143 double max=0.0;
1144 double mean=0.0;
1145 for (size_t i=0; i<n; i++) {
1146 if (oldshifts.size()==n) shifts.push_back((sim_descent(i)+oldshifts[i])/2.0);
1147 else shifts.push_back(sim_descent(i));
1148 float len=shifts[i].length();
1149 if (len>max) max=len;
1150 mean+=len;
1151 }
1152 oldshifts=shifts;
1153
1154// printf("max vec %1.2f\tmean %1.3f\n",max,mean/n);
1155
1156 for (size_t i=0; i<n; i++) {
1157// if (std::isnan(shifts[i][0]) ||std::isnan(shifts[i][1]) ||std::isnan(shifts[i][2])) { printf("Nan: %d\n",i); shifts[i]=Vec3f(max,max,max); }
1158 points[i*4]+=shifts[i][0]*maxshift/max;
1159 points[i*4+1]+=shifts[i][1]*maxshift/max;
1160 points[i*4+2]+=shifts[i][2]*maxshift/max;
1161// printf("%d. %1.2f\t%1.2f\t%1.2f\n",i,shifts[i][0]*maxshift/max,shifts[i][1]*maxshift/max,shifts[i][2]*maxshift/max);
1162 }
1163}
Vec3f sim_descent(int i)
returns a vector pointing downhill for a single point
vector< Vec3f > oldshifts
Definition: pointarray.h:248

References n, oldshifts, points, and sim_descent().

◆ sim_minstep_seq()

void PointArray::sim_minstep_seq ( double  meanshift)

Takes a step to minimize the potential.

Definition at line 1166 of file pointarray.cpp.

1166 {
1167 /*
1168 // Try to minimize potential globally
1169 boost::mt19937 rng;
1170 boost::normal_distribution<> nd(0.0, 20.0);
1171 boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor(rng, nd);
1172 double *oldpts=new double[4*get_number_points()];
1173 double *bestpts=new double[4*get_number_points()];
1174 double best_pot,new_pot;
1175 memcpy(oldpts, get_points_array(), sizeof(double) * 4 * get_number_points());
1176 memcpy(bestpts, get_points_array(), sizeof(double) * 4 * get_number_points());
1177 best_pot=sim_potential();
1178 double disttmp=0;
1179 for (int k=0; k<n; k++) disttmp+=adist[k];
1180 best_pot+=distc*pow((disttmp-336*3.3),2.0);
1181 for (int i=0; i<1000; i++){
1182 for (int j=0; j<n; j++){
1183 points[4*j]=oldpts[4*j]+var_nor();
1184 points[4*j+1]=oldpts[4*j+1]+var_nor();
1185 points[4*j+2]=oldpts[4*j+2]+var_nor();
1186 }
1187 new_pot=sim_potential();
1188 disttmp=0;
1189 for (int k=0; k<n; k++) disttmp+=adist[k];
1190 new_pot+=distc*pow((disttmp-336*3.3),2.0);
1191 if (new_pot<best_pot){
1192 memcpy(bestpts, get_points_array(), sizeof(double) * 4 * get_number_points());
1193 best_pot=new_pot;
1194 printf("%f\t",best_pot);
1195 }
1196 }
1197 memcpy(get_points_array(),bestpts, sizeof(double) * 4 * get_number_points());
1198
1199 delete []oldpts;
1200 delete []bestpts;
1201 */
1202 // we compute 10 random gradients and use these to adjust stepsize
1203 double mean=0.0;
1204 for (int i=0; i<10; i++) {
1205// Vec3f shift=sim_descent(random()%n);
1206 Vec3f shift=sim_descent(Util::get_irand(0,n-1));
1207 mean+=shift.length();
1208 }
1209 mean/=10.0;
1210 double stepadj=meanshift/mean;
1211// printf("\t%1.4g\n",stepadj);
1212
1213 // Now we go through all points sequentially and move each downhill
1214 // The trick here is the sequential part, as each point is impacted by the point already moved before it.
1215 // This may create a "seam" at the first point which won't be adjusted to compensate for the last point (wraparound)
1216 // until the next cycle
1217 Vec3f oshifts;
1218 for (size_t ii=0; ii<n; ii++) {
1219 size_t i=2*(ii%(n/2))+2*ii/n; // this maps a linear sequence to an all-even -> all odd sequence
1220 Vec3f shift,d;
1221 if (ii==n) {
1222 d=sim_descent(i);
1223 shift=(d+oshifts)/2.0;
1224 oshifts=d;
1225 }
1226 else {
1227 shift=sim_descent(i);
1228 oshifts=shift;
1229 }
1230
1231// double p2=potential();
1232// double pot=sim_potentialdxyz(i,0.0,0.0,0.0);
1233// double pots=sim_potentialdxyz(i,shift[0]*stepadj,shift[1]*stepadj,shift[2]*stepadj);
1234
1235 // only step if it actually improves the potential for this particle (note that it does not need to improve the overall potential)
1236// if (pots<pot) {
1237 points[i*4]+=shift[0]*stepadj;
1238 points[i*4+1]+=shift[1]*stepadj;
1239 if (!map2d)
1240 points[i*4+2]+=shift[2]*stepadj;
1241// printf("%d. %1.4g -> %1.4g %1.3g %1.3g %1.3g %1.3g\n",i,pot,pots,shift[0],shift[1],shift[2],stepadj);
1242// if (potential()>p2) printf("%d. %1.4g %1.4g\t%1.4g %1.4g\n",i,pot,pots,p2,potential());
1243// }
1244
1245 }
1246}

References EMAN::Util::get_irand(), EMAN::Vec3< Type >::length(), map2d, n, points, and sim_descent().

◆ sim_pointpotential()

double EMAN::PointArray::sim_pointpotential ( double  dist,
double  ang,
double  dihed 
)
inline

Computes a potential value for a single point from a set of angles/distances using current energy settings.

Definition at line 142 of file pointarray.h.

142 {
143 return pow(dist-dist0,2.0)*distc+ang*ang*angc+pow(dihed-dihed0,2.0)*dihedc;
144 }
double dist0
Used for simplistic loop dynamics simulation Assumes all points are connected sequentially in a close...
Definition: pointarray.h:244

References angc, dihed0, dihedc, dist0, and distc.

Referenced by sim_add_point_one(), sim_potential(), and sim_potentiald().

◆ sim_potential()

double PointArray::sim_potential ( )

Computes overall potential for the configuration.

Definition at line 988 of file pointarray.cpp.

988 {
989 double ret=0;
991
992 if (map &&mapc) {
993 for (size_t i=0; i<n; i++) ret+=sim_pointpotential(adist[i],aang[i],adihed[i])-mapc*map->sget_value_at_interp(points[i*4]/apix+centx,points[i*4+1]/apix+centy,points[i*4+2]/apix+centz);
994 }
995 else {
996 for (size_t i=0; i<n; i++) ret+=sim_pointpotential(adist[i],aang[i],adihed[i]);
997 }
998
999 return ret/n;
1000}

References aang, adihed, adist, apix, centx, centy, centz, map, mapc, n, points, sim_pointpotential(), and sim_updategeom().

Referenced by sim_printstat().

◆ sim_potentiald()

double PointArray::sim_potentiald ( int  ind)

Compute a single point potential value.

Definition at line 1003 of file pointarray.cpp.

1003 {
1004 if (!adist) sim_updategeom(); // wasteful, but only once
1005
1006// if (i<0 || i>=n) throw InvalidParameterException("Point number out of range");
1007 size_t i;
1008 if (ind<0)
1009 i=ind-n*(ind/n-1);
1010 else
1011 i=ind;
1012 if (i>=n) i=i%n;
1013
1014 // how expensive is % ? Worth replacing ?
1015 int ib=4*((i+n-1)%n); // point before i with wraparound
1016 int ibb=4*((i+n-2)%n); // 2 points before i with wraparound
1017 int ia=4*((i+1)%n); // 1 point after
1018 int ii=i*4;
1019
1020 Vec3f a(points[ib]-points[ibb],points[ib+1]-points[ibb+1],points[ib+2]-points[ibb+2]); // -2 -> -1
1021 Vec3f b(points[ii]-points[ib],points[ii+1]-points[ib+1],points[ii+2]-points[ib+2]); // -1 -> 0
1022 Vec3f c(points[ia]-points[ii],points[ia+1]-points[ii+1],points[ia+2]-points[ii+2]); // 0 -> 1
1023 double dist=b.length();
1024 adist[i]=dist;
1025 // Angle, tests should avoid isnan being necessary
1026 double ang=b.dot(c);
1027 if (ang!=0.0) { // if b.dot(c) is 0, we set it to the last determined value...
1028 ang/=(dist*c.length());
1029 if (ang>1.0) ang=1.0; // should never happen, but just in case of roundoff error
1030 if (ang<-1.0) ang=-1.0;
1031 ang=acos(ang);
1032 }
1033 else ang=aang[i];
1034 aang[i]=ang;
1035
1036 // Dihedral
1037 Vec3f cr1=a.cross(b);
1038 Vec3f cr2=b.cross(c);
1039 double dihed;
1040 double denom=cr1.length()*cr2.length();
1041 if (denom==0) dihed=adihed[i]; // set the dihedral to the last determined value if indeterminate
1042 else {
1043 dihed=cr1.dot(cr2)/denom;
1044 if (dihed>1.0) dihed=1.0; // should never happen, but just in case of roundoff error
1045 if (dihed<-1.0) dihed=-1.0;
1046 dihed=acos(dihed);
1047 }
1048 adihed[i]=dihed;
1049//* Do not need for small amount of points
1050 // Distance to the closest neighbor
1051 double mindist=10000;
1052 for (size_t j=0;j<n;j++){
1053 if(j==i)
1054 continue;
1055 int ja=4*j;
1056 Vec3f d(points[ii]-points[ja],points[ii+1]-points[ja+1],points[ii+2]-points[ja+2]);
1057 double jdst=d.length();
1058 if(jdst<mindist)
1059 mindist=jdst;
1060 }
1061 double distpen=0;
1062 if (mindist<mindistc)
1063 distpen=distpenc/mindist;
1064//*/
1065
1066
1067// if (std::isnan(dist) || std::isnan(ang) || std::isnan(dihed)) printf("%d\t%g\t%g\t%g\t%g\t%g\t%g\n",i,dist,ang,dihed,b.length(),c.length(),b.dot(c)/(dist*c.length()));
1068// if (std::isnan(dihed)) dihed=dihed0;
1069// if (std::isnan(ang)) ang=0;
1070// if (std::isnan(dist)) dist=3.3;
1071// if (isnan(dihed)) dihed=dihed0;
1072// if (isnan(ang)) ang=0;
1073 if (map && mapc) {
1074 return distpen+sim_pointpotential(dist,ang,dihed)-mapc*map->sget_value_at_interp(points[ii]/apix+centx,points[ii+1]/apix+centy,points[ii+2]/apix+centz);
1075 }
1076 return sim_pointpotential(dist,ang,dihed);
1077}

References aang, adihed, adist, apix, centx, centy, centz, EMAN::Vec3< Type >::cross(), distpenc, EMAN::Vec3< Type >::dot(), EMAN::Vec3< Type >::length(), map, mapc, mindistc, n, points, sim_pointpotential(), and sim_updategeom().

Referenced by sim_add_point_one(), sim_descent(), and sim_potentialdxyz().

◆ sim_potentialdxyz()

double PointArray::sim_potentialdxyz ( int  i,
double  dx,
double  dy,
double  dz 
)

Compute a potential value for a perturbed point, including +-2 nearest neighbors which will also be impacted.

Definition at line 1080 of file pointarray.cpp.

1080 {
1081 Vec3f old(points[i*4],points[i*4+1],points[i*4+2]);
1082 double potd=0.;
1083
1084 points[i*4]=old[0]+dx;
1085 points[i*4+1]=old[1]+dy;
1086 points[i*4+2]=old[2]+dz;
1087 for (int ii=i-2; ii<=i+2; ii++) potd+=sim_potentiald(ii);
1088// potd=potential();
1089 points[i*4]=old[0];
1090 points[i*4+1]=old[1];
1091 points[i*4+2]=old[2];
1092
1093 return potd;
1094}

References points, and sim_potentiald().

◆ sim_printstat()

void PointArray::sim_printstat ( )

prints some statistics to the screen

Definition at line 1275 of file pointarray.cpp.

1275 {
1276 sim_updategeom();
1277
1278 double mdist=0.0,mang=0.0,mdihed=0.0;
1279 double midist=1000.0,miang=M_PI*2,midihed=M_PI*2;
1280 double madist=0.0,maang=0.0,madihed=0.0;
1281 double mmap=0.0;
1282 if (map &&mapc) {
1283 for (size_t i=0; i<n; i++) {
1284 double m=map->sget_value_at_interp(points[i*4]/apix+centx,points[i*4+1]/apix+centy,points[i*4+2]/apix+centz);
1285 mmap+=m;
1286// printf("%f,%f,%f\t %f\n",points[i*4]/apix+centx,points[i*4+1]/apix+centy,points[i*4+2]/apix+centz,m);
1287 }
1288 mmap/=n;
1289 }
1290 for (size_t i=0; i<n; i++) {
1291 mdist+=adist[i];
1292 mang+=aang[i];
1293 mdihed+=adihed[i];
1294
1295
1296
1297 midist=adist[i]<midist?adist[i]:midist;
1298 madist=adist[i]>madist?adist[i]:madist;
1299
1300 miang=aang[i]<miang?aang[i]:miang;
1301 maang=aang[i]>maang?aang[i]:maang;
1302
1303 midihed=adihed[i]<midihed?adihed[i]:midihed;
1304 madihed=adihed[i]>madihed?adihed[i]:madihed;
1305 }
1306 double p=sim_potential();
1307 double anorm = 180.0/M_PI;
1308 printf(" potential: %1.1f\t map: %1.2f\tdist: %1.2f || %1.2f / %1.2f / %1.2f\tang: %1.2f / %1.2f / %1.2f\tdihed: %1.2f / %1.2f / %1.2f ln=%1.1f\n",p,mmap,dist0,midist,mdist/n,madist,miang*anorm,mang/n*anorm,maang*anorm,midihed*anorm,mdihed/n*anorm,madihed*anorm,mdihed/(M_PI*2.0)-n/10.0);
1309}
double sim_potential()
Computes overall potential for the configuration.
Definition: pointarray.cpp:988

References aang, adihed, adist, apix, centx, centy, centz, dist0, map, mapc, n, points, sim_potential(), and sim_updategeom().

◆ sim_rescale()

void PointArray::sim_rescale ( )

rescale the entire set so the mean bond length matches dist0

Definition at line 1249 of file pointarray.cpp.

1249 {
1250 double meandist=0.0;
1251 double max=0.0,min=dist0*1000.0;
1252
1253 for (size_t ii=0; ii<n; ii++) {
1254 int ib=4*((ii+n-1)%n); // point before i with wraparound
1255 int i=4*ii;
1256
1257 Vec3f b(points[i]-points[ib],points[i+1]-points[ib+1],points[i+2]-points[ib+2]); // -1 -> 0
1258 double len=b.length();
1259 meandist+=len;
1260 max=len>max?len:max;
1261 min=len<min?len:min;
1262 }
1263 meandist/=n;
1264 double scale=dist0/meandist;
1265
1266 printf("mean = %1.3f rescaled: %1.3f - %1.3f\n",meandist,min*scale,max*scale);
1267
1268 for (size_t i=0; i<n; i++) {
1269 points[i*4]*=scale;
1270 points[i*4+1]*=scale;
1271 points[i*4+2]*=scale;
1272 }
1273
1274}

References dist0, EMAN::Vec3< Type >::length(), n, and points.

◆ sim_set_pot_parms()

void PointArray::sim_set_pot_parms ( double  pdist0,
double  pdistc,
double  pangc,
double  pdihed0,
double  pdihedc,
double  pmapc,
EMData pmap,
double  pmindistc,
double  pdistpenc 
)

Sets the parameters for the energy function.

Definition at line 1311 of file pointarray.cpp.

1311 {
1312 dist0=pdist0;
1313 distc=pdistc;
1314 angc=pangc;
1315 dihed0=pdihed0;
1316 dihedc=pdihedc;
1317 mapc=pmapc;
1318 mindistc=pmindistc;
1319 distpenc=pdistpenc;
1320 if (pmap!=0 && pmap!=map) {
1321// if (map!=0) delete map;
1322 if (gradx!=0) delete gradx;
1323 if (grady!=0) delete grady;
1324 if (gradz!=0) delete gradz;
1325
1326 map=pmap;
1327 apix=map->get_attr("apix_x");
1328 if (map->get_zsize()==1)
1329 map2d=true;
1330 else
1331 map2d=false;
1332// centx=map->get_xsize()/2;
1333// centy=map->get_ysize()/2;
1334// centz=map->get_zsize()/2;
1335 centx=0;
1336 centy=0;
1337 centz=0;
1338// gradx=map->process("math.edge.xgradient"); // we compute the gradient to make the minimization easier
1339// grady=map->process("math.edge.ygradient");
1340// gradz=map->process("math.edge.zgradient");
1341 }
1342}

References angc, apix, centx, centy, centz, dihed0, dihedc, dist0, distc, distpenc, gradx, grady, gradz, map, map2d, mapc, and mindistc.

◆ sim_updategeom()

void PointArray::sim_updategeom ( )

Updates the dist, ang, dihed parameters.

Definition at line 945 of file pointarray.cpp.

945 {
946 if (!adist) adist=(double *)malloc(sizeof(double)*n);
947 if (!aang) aang=(double *)malloc(sizeof(double)*n);
948 if (!adihed) adihed=(double *)malloc(sizeof(double)*n);
949
950 for (size_t ii=0; ii<n; ii++) {
951 // how expensive is % ? Worth replacing ?
952 int ib=4*((ii+n-1)%n); // point before i with wraparound
953 int ibb=4*((ii+n-2)%n); // 2 points before i with wraparound
954 int ia=4*((ii+1)%n); // 1 point after
955 int i=4*ii;
956
957 Vec3f a(points[ib]-points[ibb],points[ib+1]-points[ibb+1],points[ib+2]-points[ibb+2]); // -2 -> -1
958 Vec3f b(points[i]-points[ib],points[i+1]-points[ib+1],points[i+2]-points[ib+2]); // -1 -> 0
959 Vec3f c(points[ia]-points[i],points[ia+1]-points[i+1],points[ia+2]-points[i+2]); // 0 -> 1
960 adist[ii]=b.length();
961
962 // angle
963 aang[ii]=b.dot(c);
964 if (aang[ii]!=0) {
965 aang[ii]/=(adist[ii]*c.length());
966 if (aang[ii]>=1.0) aang[ii]=0.0;
967 else if (aang[ii]<=-1.0) aang[ii]=M_PI;
968 else aang[ii]=acos(aang[ii]);
969 }
970
971 // dihedral
972 Vec3f cr1=a.cross(b);
973 Vec3f cr2=b.cross(c);
974 double denom=cr1.length()*cr2.length();
975 if (denom==0) adihed[ii]=0;
976 else {
977 double tmp=cr1.dot(cr2)/(denom);
978 if (tmp>1) tmp=1;
979 if (tmp<-1) tmp=-1;
980 adihed[ii]=acos(tmp);
981 }
982
983// if (std::isnan(ang[ii])) ang[ii]=0;
984
985 }
986}

References aang, adihed, adist, EMAN::Vec3< Type >::cross(), EMAN::Vec3< Type >::dot(), EMAN::Vec3< Type >::length(), n, and points.

Referenced by sim_add_point_double(), sim_add_point_one(), sim_potential(), sim_potentiald(), and sim_printstat().

◆ sort_by_axis()

void PointArray::sort_by_axis ( int  axis = 1)

Definition at line 2263 of file pointarray.cpp.

2264{
2265 if (axis == 0)
2266 qsort(points, n, sizeof(double) * 4, cmp_axis_x);
2267 else if (axis == 1)
2268 qsort(points, n, sizeof(double) * 4, cmp_axis_y);
2269 else if (axis == 2)
2270 qsort(points, n, sizeof(double) * 4, cmp_axis_z);
2271 else
2272 qsort(points, n, sizeof(double) * 4, cmp_val);
2273}
int cmp_val(const void *a, const void *b)
Definition: pointarray.cpp:80
int cmp_axis_y(const void *a, const void *b)
Definition: pointarray.cpp:60
int cmp_axis_x(const void *a, const void *b)
Definition: pointarray.cpp:50
int cmp_axis_z(const void *a, const void *b)
Definition: pointarray.cpp:70

References cmp_axis_x(), cmp_axis_y(), cmp_axis_z(), cmp_val(), n, and points.

Referenced by set_from_density_map().

◆ transform()

void PointArray::transform ( const Transform transform)

Definition at line 605 of file pointarray.cpp.

605 {
606
607 for ( unsigned int i = 0; i < 4 * n; i += 4) {
608 Vec3f v((float)points[i],(float)points[i+1],(float)points[i+2]);
609 v=v*xf;
610 points[i] =v[0];
611 points[i+1]=v[1];
612 points[i+2]=v[2];
613 }
614
615}

References n, and points.

Referenced by right_transform(), and set_from().

◆ zero()

void PointArray::zero ( )

Definition at line 144 of file pointarray.cpp.

145{
146 memset((void *) points, 0, 4 * n * sizeof(double));
147}

References n, and points.

Referenced by set_from_density_map().

Member Data Documentation

◆ aang

double* EMAN::PointArray::aang
private

◆ adihed

double* EMAN::PointArray::adihed
private

◆ adist

double* EMAN::PointArray::adist
private

◆ angc

double EMAN::PointArray::angc
private

Definition at line 244 of file pointarray.h.

Referenced by sim_pointpotential(), and sim_set_pot_parms().

◆ apix

double EMAN::PointArray::apix
private

◆ bfactor

double* EMAN::PointArray::bfactor
private

◆ centx

int EMAN::PointArray::centx
private

◆ centy

int EMAN::PointArray::centy
private

◆ centz

int EMAN::PointArray::centz
private

◆ dihed0

double EMAN::PointArray::dihed0
private

Definition at line 244 of file pointarray.h.

Referenced by sim_pointpotential(), and sim_set_pot_parms().

◆ dihedc

double EMAN::PointArray::dihedc
private

Definition at line 244 of file pointarray.h.

Referenced by sim_pointpotential(), and sim_set_pot_parms().

◆ dist0

double EMAN::PointArray::dist0
private

Used for simplistic loop dynamics simulation Assumes all points are connected sequentially in a closed loop, potential includes distance, angle and dihedral terms, with optional density based terms.

Parameters
dist0- center distance for quadratic energy term
distc- quadratic distance coefficient c(dist-dist0)^2
angc- quadratic angle coefficient c*(180-ang)^2
dihed0- dihedral center angle
dihedc- dihedral angle coefficient c*(dihed-dihed0)^2
mapc- coefficient for map energy
map- EMData representing map to match/fit
mindistc- minimum distance between two points
distpenc- penalty for close points

Definition at line 244 of file pointarray.h.

Referenced by sim_pointpotential(), sim_printstat(), sim_rescale(), and sim_set_pot_parms().

◆ distc

double EMAN::PointArray::distc
private

Definition at line 244 of file pointarray.h.

Referenced by sim_pointpotential(), and sim_set_pot_parms().

◆ distpenc

double EMAN::PointArray::distpenc
private

Definition at line 244 of file pointarray.h.

Referenced by sim_potentiald(), and sim_set_pot_parms().

◆ gradx

EMData* EMAN::PointArray::gradx
private

Definition at line 247 of file pointarray.h.

Referenced by PointArray(), sim_set_pot_parms(), and ~PointArray().

◆ grady

EMData * EMAN::PointArray::grady
private

Definition at line 247 of file pointarray.h.

Referenced by PointArray(), sim_set_pot_parms(), and ~PointArray().

◆ gradz

EMData * EMAN::PointArray::gradz
private

Definition at line 247 of file pointarray.h.

Referenced by PointArray(), sim_set_pot_parms(), and ~PointArray().

◆ map

EMData* EMAN::PointArray::map
private

◆ map2d

bool EMAN::PointArray::map2d
private

Definition at line 245 of file pointarray.h.

Referenced by sim_minstep_seq(), and sim_set_pot_parms().

◆ mapc

double EMAN::PointArray::mapc
private

◆ mindistc

double EMAN::PointArray::mindistc
private

Definition at line 244 of file pointarray.h.

Referenced by sim_potentiald(), and sim_set_pot_parms().

◆ n

size_t EMAN::PointArray::n
private

◆ oldshifts

vector<Vec3f> EMAN::PointArray::oldshifts
private

Definition at line 248 of file pointarray.h.

Referenced by sim_minstep().

◆ points

double* EMAN::PointArray::points
private

The documentation for this class was generated from the following files: