int perp_line_fit (double **point, int no_of_points,
		   double p[], double cm[], double avg[]) {

    /* p and the center of the mass define a line */
    /* we need a new set of lines perpencidular through this one,
       going through the points given in the array */
    int i, j;
    double dp, d[3], p_perp[3], p_perp_0[3], cosine, norm;
    double normalize (double *p);

    memset (avg, 0, 3*sizeof(double));
    
    /* if d is the vector from CM to the atom O,
       p_perp = d -(dp)p (all vectors) */
    for (i=0; i< no_of_points; i++) {
	dp = 0;
	for (j=0; j<3; j++) {
	    d[j] = point[i][j] - cm[j];
	    dp += d[j]*p[j];
	}
	norm = 0;
	for (j=0; j<3; j++) {
	    p_perp[j] = d[j] - dp*p[j];
	    norm +=  p_perp[j]*p_perp[j];
	}
	norm = sqrt (norm);
	for (j=0; j<3; j++) p_perp[j] /= norm;

	if ( i== 0 ) {
	    for (j=0; j<3; j++) p_perp_0[j] = p_perp[j];
	}
	unnorm_dot (p_perp_0, p_perp, &cosine);
	if ( cosine < 0 ) {
	    for (j=0; j<3; j++)  p_perp[j] = -p_perp[j] ;
	    cosine = -cosine;
	}
	for (j=0; j<3; j++) avg[j] +=  p_perp[j];
# if 0
	/* TODO - this might be the place to start
	   cleaning up the line fit - all vectors should
	   be parallel */ 
	for (j=0; j<3; j++)  printf (" %8.2lf", p_perp[j]);
	printf ("   %8.2lf\n", cosine);
# endif
    }

    norm = 0;
    for (j=0; j<3; j++) {
	avg[j] /= no_of_points;
	norm +=  avg[j]*avg[j];
    }
    norm = sqrt (norm);
    for (j=0; j<3; j++) avg[j] /= norm;
    
     
    return 0;      
}
Example #2
0
int store_sse_pair_score ( Representation *X_rep,  Representation *Y_rep, 
		  double **R, double alpha,  Map *map ){
    
    int i,j, i_is_helix;
    int NX=X_rep->N_full, NY=Y_rep->N_full;
    double cosine;
    double alpha_sq = alpha*alpha;
    double ** x_full_rotated = NULL, **y_full = Y_rep->full;
    double length_dif, exponent;

    if ( ! (x_full_rotated=dmatrix (NX,3) ) ) return 1;
    
    rotate (x_full_rotated, X_rep->N_full, R, X_rep->full);
    
    for (i=0; i < NX; i++ ) {
	i_is_helix =  ( X_rep->full_type[i] == HELIX);
	for (j=0; j < NY; j++) {

	    if ( X_rep->full_type[i] == Y_rep->full_type[j] ) {
		unnorm_dot (x_full_rotated[i], y_full[j], &cosine);
		exponent = 2*(1.0-cosine)/alpha_sq;
		if ( exponent < 10 ) {
		    map->sse_pair_score[i][j]  = exp (-exponent);
		    /* are we using the info about the length? */
		    if (options.use_length && cosine > 0.0) {
			length_dif = abs (X_rep->length[i] - Y_rep->length[j]);
			if ( i_is_helix ) {
			    map->sse_pair_score[i][j]  *=  1/(1.0+length_dif/options.H_length_mismatch_tol);
			} else {
			    map->sse_pair_score[i][j]  *=  1/(1.0+length_dif/options.S_length_mismatch_tol);
			}
		    }
		} else {
		    map->sse_pair_score[i][j] = 0.0;
		}
		map->cosine[i][j] = cosine;
	    } else {
		map->sse_pair_score[i][j]  = options.far_far_away;
		map->cosine[i][j] = -0.9999;
	    }
	}
    }
    free_dmatrix (x_full_rotated);
    
    return 0;
}
Example #3
0
/* check that the two are not mirror images - count on it being  a triple*/
int hand (Representation * X_rep,  int *set_of_directions_x) {
      
    double **x    = X_rep->full;
    double **x_cm = X_rep->cm;
    double cm_vector[3], avg_cm[3], cross[3], d, aux;
    int i, ray_a, ray_b,  ray_c, a, b, c;
    
    a = 0;
    b = 1;
    c = 2;
    /*****************************/
    /*****************************/
    ray_a = set_of_directions_x[a];
    ray_b = set_of_directions_x[b];
    ray_c = set_of_directions_x[c];
    /* I better not use the cross prod here: a small diff
       int he angle makeing them pointing toward each other or
       away from each other changes the direction of cross prod;
       rather, use one vector, and distance between the cm's as the other */
    for (i=0; i<3; i++ ) {
	cm_vector[i] = x_cm[ray_b][i] - x_cm[ray_a][i];
    }
    normalized_cross (x[ray_a], x[ray_b], cross, &aux); 
    /* note I am making another cm vector here */
    for (i=0; i<3; i++ ) {
	avg_cm[i] = (x_cm[ray_b][i] + x_cm[ray_a][i])/2;
	cm_vector[i] = x_cm[ray_c][i] - avg_cm[i];
    }
    unnorm_dot (cm_vector, cross, &d);

    if ( d > 0 ) {
	return 0;
    } else {
	return 1;
    }
}
Example #4
0
/* check that the two are not mirror images - count on it being  a triple*/
int same_hand_triple (Representation * X_rep,  int *set_of_directions_x,
		      Representation * Y_rep, int *set_of_directions_y, int set_size) {
    
    
    double **x    = X_rep->full;
    double **x_cm = X_rep->cm;
    double **y    = Y_rep->full;
    double **y_cm = Y_rep->cm;
    double cm_vector[3], avg_cm[3], cross[3],  dx, dy, aux;
    int i, ray_a, ray_b,  ray_c, a, b, c;
    
    if (set_size !=3 ) return 0;

 
    a = 0;
    b = 1;
    c = 2;
    
    /*****************************/
    /*****************************/
    ray_a = set_of_directions_x[a];
    ray_b = set_of_directions_x[b];
    ray_c = set_of_directions_x[c];
    
    /* I better not use the cross prod here: a small diff
       int he angle makeing them pointing toward each other or
       away from each other changes the direction of cross prod;
       rather, use one vector, and distance between the cm's as the other */
    for (i=0; i<3; i++ ) {
	cm_vector[i] = x_cm[ray_b][i] - x_cm[ray_a][i];
    }

    /* note that the cross product here is between the direction
       vector of SSE labeled a, and the vector spanning the geeometric
       centers of a and b - this cross prod can be undefined only if
       the two are stacked */
    if ( ! normalized_cross (x[ray_a], cm_vector, cross, &aux)) {
	/* the function returns 0 on success, i.e. retval==0 means
	   the cross product can be calculated ok. */ 
	
	/* note I am making another cm vector here */
	for (i=0; i<3; i++ ) {
	    avg_cm[i]    = (x_cm[ray_b][i] + x_cm[ray_a][i])/2;
	    cm_vector[i] =  x_cm[ray_c][i] - avg_cm[i];
	}
	unnorm_dot (cm_vector, cross, &dx);

	/*****************************/
	/*****************************/
	ray_a = set_of_directions_y[a];
	ray_b = set_of_directions_y[b];
	ray_c = set_of_directions_y[c];
	for (i=0; i<3; i++ ) {
	    cm_vector[i] = y_cm[ray_b][i] - y_cm[ray_a][i];
	}
	if (normalized_cross (y[ray_a], cm_vector, cross, &aux)) {
	    /* if  I can calculate the cross product for one triplet
	       but not for the other, I declare it a different hand (this will
	       be dropped from further consideration) */
	    return 0;
	}
	/* note I am making another cm vector here */
	for (i=0; i<3; i++ ) {
	    avg_cm[i]    = (y_cm[ray_b][i] + y_cm[ray_a][i])/2;
	    cm_vector[i] =  y_cm[ray_c][i] - avg_cm[i];
	}
	/*note: unnorm_dot thinks it is getting unit vectors,
	  and evrything that is >1 will be "rounded" to 1
	  (similarly for -1) - it doesn't do the normalization itself*/
	unnorm_dot (cm_vector, cross, &dy);

	if ( dx*dy < 0 ) {
	    return 0;
	} else {
 	    return 1;   /* this isn't err value - the handedness is the same */
	}

    } else {

	/* if the vectors linking cms are parallel, the hand is the same (my defintion) */
	double cm_vector_2[3], dot;
	
	ray_a = set_of_directions_y[a];
	ray_b = set_of_directions_y[b];
	ray_c = set_of_directions_y[c];
	for (i=0; i<3; i++ ) {
	    cm_vector_2[i] = y_cm[ray_b][i] - y_cm[ray_a][i];
	}

	unnorm_dot(cm_vector, cm_vector_2, &dot);

	if ( dot > 0) {
	    return 1;
	} else {
	    return 0;
	}

	/* (hey, at least I am checking the retvals of my functions) */
    }

    return 0; /* better safe than sorry */
}
Example #5
0
int fit_line (double **point, int no_points, double center[3], double direction[3]) {

    int i, j, point_ctr;
    double I[3][3] = {{0.0}};
    double translated_point[3];
    
    void dsyev_(char * jobz, char * uplo, int* N,
		double * A, int * leading_dim,
		double * eigenvalues,
		double *workspace, int *workspace_size,
		int * retval);
    if (!no_points) {
	fprintf (stderr, "Error in %s:%d: in fit_line() - no points given\n",
		 __FILE__, __LINE__);
	exit (1);
    }
  
    for (i=0; i<3; i++) center[i] = 0;
    for (point_ctr = 0; point_ctr < no_points; point_ctr++) {
	for (i=0; i<3; i++) center[i] += point[point_ctr][i];
    }
    for (i=0; i<3; i++) center[i] /= no_points;
    
    for (point_ctr = 0; point_ctr < no_points; point_ctr++) {

	for (i=0; i<3; i++) {
	    translated_point[i] = point[point_ctr][i] - center[i];
	}
	/* moments of inertia */
	for (i=0; i<3; i++) {  /* modulo = circular permutation */
	    I[i][i] += translated_point[(i+1)%3]*translated_point[(i+1)%3] +
		translated_point[(i+2)%3]*translated_point[(i+2)%3];
	    for ( j=i+1; j<3; j++) { /* offdiag elements */
		I[i][j] -= translated_point[i]*translated_point[j];
	    }
	}
    }
    for (i=0; i<3; i++) {
	for ( j=i+1; j<3; j++) { 
	    I[j][i] =  I[i][j];
	}
    }


    /*****************************************/
    /* diagonalize I[][], pick the direction
       with the smallest moment of inertia,
       and rotate back to the initial frame  */
    /*****************************************/
    char jobz = 'V'; /* find evalues and evectors */
    char uplo = 'L'; /* matrix is stored as lower (fortran convention) */
    int  N = 3; /* the order of matrix */
    int leading_dim = N;
    int retval = 0;
    int workspace_size = 3*N;
    double A[N*N];
    double eigenvalues[N];
    double workspace[3*N];
    double NC_direction[3];
    
    for (i=0; i<3; i++) {
	for ( j=0; j<3; j++) {
	    A[i*3+j] = I[i][j];
	}
    }

    
    dsyev_ ( &jobz, &uplo, &N, A, &leading_dim, eigenvalues,
	     workspace, &workspace_size, &retval);
    
    if ( retval ) {
	fprintf (stderr, "Error in %s:%d: dsyev() returns %d.\n",
		 __FILE__, __LINE__, retval);
	exit (1);
    }
    for (i=0; i<3; i++)  direction[i] = A[i];

    /* sum of squared dist is egeinvalues[0];
       in case we need it */

    /* force the direction to be N-->C */
    for (i=0; i<3; i++) {
	NC_direction[i] = point[no_points-1][i] - point[0][i];
    }

    double dot;
    unnorm_dot (NC_direction,direction, &dot);
    if ( dot<0 ) {
	for (i=0; i<3; i++) direction[i] *= -1;
    }

    return 0;
}
/* check that the two are not mirror images - count on it being  a triple*/
int same_hand_triple (Representation * X_rep,  int *set_of_directions_x,
	       Representation * Y_rep, int *set_of_directions_y, int set_size) {
    
    double **x    = X_rep->full;
    double **x_cm = X_rep->cm;
    double **y    = Y_rep->full;
    double **y_cm = Y_rep->cm;
    double cm_vector[3], avg_cm[3], cross[3],  dx, dy, aux;
    int i, ray_a, ray_b,  ray_c, a, b, c;
    
    if (set_size !=3 ) return 0;

 
    a = 0;
    b = 1;
    c = 2;
    
    /*****************************/
    /*****************************/
    ray_a = set_of_directions_x[a];
    ray_b = set_of_directions_x[b];
    ray_c = set_of_directions_x[c];
    /* I better not use the cross prod here: a small diff
       int he angle makeing them pointing toward each other or
       away from each other changes the direction of cross prod;
       rather, use one vector, and distance between the cm's as the other */
    for (i=0; i<3; i++ ) {
	cm_vector[i] = x_cm[ray_b][i] - x_cm[ray_a][i];
    }
    normalized_cross (x[ray_a], x[ray_b], cross, &aux); 
    /* note I am makning another cm vector here */
    for (i=0; i<3; i++ ) {
	avg_cm[i] = (x_cm[ray_b][i] + x_cm[ray_a][i])/2;
	cm_vector[i] = x_cm[ray_c][i] - avg_cm[i];
    }
    unnorm_dot (cm_vector, cross, &dx);

    /*****************************/
    /*****************************/
    ray_a = set_of_directions_y[a];
    ray_b = set_of_directions_y[b];
    ray_c = set_of_directions_y[c];
    for (i=0; i<3; i++ ) {
	cm_vector[i] = y_cm[ray_b][i] - y_cm[ray_a][i];
    }
    normalized_cross (y[ray_a], y[ray_b], cross, &aux); 
    /* note I am makning another cm vector here */
    for (i=0; i<3; i++ ) {
	avg_cm[i] = (y_cm[ray_b][i] + y_cm[ray_a][i])/2;
	cm_vector[i] = y_cm[ray_c][i] - avg_cm[i];
    }
    /*note: unnorm_dot thinks it is getting unit vectors,
      and evrything that is >1 will be "rounded" to 1
      (similarly for -1) - it doesn't do the normalization itself*/
    unnorm_dot (cm_vector, cross, &dy);

     
    if ( dx*dy < 0 ) return 0;

    
    return 1;   /* this isn't err value - the handedness is the same */
}
Example #7
0
int  qmap (double *x0, double *x1, double *y0, double *y1, double * quat){

    double q1[4], q2[4];
    double v[3], v2[3], cosine = 0, theta =0, sine;
    double x_prime[3];
    int i,j;
    
    int  normalized_cross (double *x, double *y, double * v, double *norm_ptr);
    int  unnorm_dot (double *x, double *y, double * dot);
    
   
    /* 1) find any quat for  x0 -->  y0 */

    /* check that it is not the same vector already: */
    unnorm_dot (x0, y0, &cosine);
    if ( 1-cosine > 0.001 ) {
	
	double ** R;
	
	if ( normalized_cross (x0, y0, v, NULL) )return 1;

	theta = acos (cosine);

	q1[0] = cos (theta/2);
	sine = sin(theta/2);
	for (i=0; i<3; i++ ) {
	    q1[i+1] = sine*v[i];
	}

	if ( ! (R=dmatrix(3,3) ) ) return 1; /* compiler is bugging me otherwise */
	quat_to_R (q1, R);

	for (i=0; i<3; i++ ) {
	    x_prime[i] = 0;
	    for (j=0; j<3; j++ ) {
		x_prime[i] += R[i][j]*x1[j];
	    }
	}
	free_dmatrix (R);
	
    } else {
	memcpy (x_prime, x1, 3*sizeof(double) );
	memset (q1, 0,  4*sizeof(double) );
	q1[0] = 1.0;
    }

    
    /* 2) find quat thru y0 which maps
       x' to the plane <y0,y1> */
   
    unnorm_dot (x_prime, y1, &cosine);
    /* determining theta: angle btw planes = angle btw the normals */
    if ( 1-cosine > 0.001 ) {
	if ( normalized_cross (x_prime, y0,v, NULL)) return 1;
	if ( normalized_cross (y1, y0, v2, NULL)) return 1;
	unnorm_dot (v, v2, &cosine);
	
	theta = acos (cosine);
	
	/*still need to determine the sign
	  of rotation */
	if (normalized_cross (x_prime, y1,v, NULL)) return 1;
	unnorm_dot (v, y0, &cosine);
	if ( cosine > 0.0 ) { 
	    sine =  sin(theta/2);
	} else {
	    sine =  -sin(theta/2);
	}
	for (i=0; i<3; i++ ) {
	    v[i]    = y0[i];
	}
	q2[0] = cos (theta/2);
	for (i=0; i<3; i++ ) {
	    q2[i+1] = sine*v[i];
	}

    } else {
	memset (q2, 0,  4*sizeof(double) );
	q2[0] = 1.0;
    }

    /* multiply the two quats */
    multiply (q2, q1, 0, quat);
    

    return 0;
       
}
Example #8
0
int  qmap_bisec (double *x0, double *x1, double *y0, double *y1, double * quat){

    
    double q1[4], q2[4];
    double v[3], cosine = 0, theta =0, sine;
    double bisec_x[3], bisec_y[3];
    double norm_x[3], norm_y[3];
    double bisec_x_prime[3];
    double norm;
    int i,j;
    
    int  normalized_cross (double *x, double *y, double * v, double *norm_ptr);
    int  unnorm_dot (double *x, double *y, double * dot);

    /* 0) find normals and bisectors */
    if ( normalized_cross (x0, x1, norm_x, NULL) )return 1;
    if ( normalized_cross (y0, y1, norm_y, NULL) )return 1;

    norm = 0;
    for (i=0; i<3; i++ ) {
	bisec_x[i] = (x0[i] + x1[i])/2;
	norm += bisec_x[i]*bisec_x[i];
    }
    norm += sqrt(norm);
    if (norm) for (i=0; i<3; i++ ) bisec_x[i] /= norm;
    
    norm = 0;
    for (i=0; i<3; i++ ) {
	bisec_y[i] = (y0[i] + y1[i])/2;
	norm += bisec_y[i]*bisec_y[i];
    }
    norm += sqrt(norm);
    if (norm) for (i=0; i<3; i++ ) bisec_y[i] /= norm;
    
    /* 1) find any quat that will match the normals */
    /* check that it is not the same vector already: */
    unnorm_dot (norm_x, norm_y, &cosine);
    if ( 1-cosine > 0.001 ) {
	
	double ** R;
	
	if ( normalized_cross (norm_x, norm_y, v,  NULL) )return 1;

	theta = acos (cosine);

	q1[0] = cos (theta/2);
	sine = sin(theta/2);
	for (i=0; i<3; i++ ) {
	    q1[i+1] = sine*v[i];
	}

	if ( ! (R=dmatrix(3,3) ) ) return 1; /* compiler is bugging me otherwise */
	quat_to_R (q1, R);

	for (i=0; i<3; i++ ) {
	    bisec_x_prime[i] = 0;
	    for (j=0; j<3; j++ ) {
		bisec_x_prime[i] += R[i][j]*bisec_x[j];
	    }
	}
	free_dmatrix (R);
	
    } else {
	memcpy (bisec_x_prime, bisec_x, 3*sizeof(double));
	memset (q1, 0,  4*sizeof(double) );
	q1[0] = 1.0;
    }

    
    /* 2) find quat thru norm_y which maps bisectors one onto another */
   
    unnorm_dot (bisec_x_prime, bisec_y, &cosine);
    /* determining theta: angle btw planes = angle btw the normals */
    if ( 1-cosine > 0.001 ) {
	
	
	theta = acos (cosine);
	
	/*still need to determine the sign of rotation */
	if (normalized_cross (bisec_x_prime, bisec_y, v, NULL)) return 1;
	
	unnorm_dot (v, norm_y, &cosine);
	if ( cosine > 0.0 ) { 
	    sine =  sin(theta/2);
	} else {
	    sine =  -sin(theta/2);
	}
	for (i=0; i<3; i++ ) {
	    v[i]    = norm_y[i];
	}
	q2[0] = cos (theta/2);
	for (i=0; i<3; i++ ) {
	    q2[i+1] = sine*v[i];
	}

    } else {
	memset (q2, 0,  4*sizeof(double) );
	q2[0] = 1.0;
    }

    /* multiply the two quats */
    multiply (q2, q1, 0, quat);
    
    return 0;
       
}
Example #9
0
/* we'll need neighbrohoods as a measure of similarity between elements */
int find_neighborhoods (Representation *rep, Representation **  hood) {
    
    double **x    =  rep->full;
    double **x_cm =  rep->cm;
    double d, hood_radius = 10;
    double cm_vector[3], cross[3], csq, component;
    int NX = rep->N_full;
    int max_hood_size = NX - 1;
    int a, b, i;
    int index_a, index_b;

    for (a=0; a<NX; a++) hood[a]->N_full = 0; // just in case
    
    for (a=0; a<NX; a++) {
	
	for (b=a+1; b<NX; b++) {

	    csq = 0;
	    for (i=0; i<3; i++ ) {
		/* from b to a  */
		component    = x_cm[a][i] - x_cm[b][i];
		cm_vector[i] = component;
		csq += component*component;
	    }
	    /* how far is it? use distance of nearest approach; if too far, move on */

	    /* distance from a to the nearest point in b */
	    normalized_cross (cm_vector, x[b], cross,  &d);
	    if (d < hood_radius) {
		index_a = hood[a]->N_full;
		/* what is the direction to this nearest point? */
		/* dir = -cm - b*sqrt(csq-d*d) */
		double dist_from_cm_b = sqrt(csq-d*d);
		for (i=0; i<3; i++ ) {
		    hood[a]->full [index_a] [i] = -cm_vector[i] -x[b][i]*dist_from_cm_b ;
		}
		hood[a]->N_full ++;
		/* type */
		hood[a]->full_type[index_a] = rep->full_type[b];
	    }
		
	    /* distance from b  to the nearest point in a */
	    normalized_cross (cm_vector, x[a], cross,  &d);
	    if (d < hood_radius) { // d is now different number then above

		index_b = hood[b]->N_full;
		/* what is the direction to this nearest point? */
		/* dir = -cm - a*sqrt(csq-d*d) */
		double dist_from_cm_a = sqrt(csq-d*d);
		for (i=0; i<3; i++ ) { // note the oopsite dir for the cm vector
		    hood[b]->full [index_b] [i] = cm_vector[i] -x[a][i]*dist_from_cm_a ;
		}
		hood[b]->N_full ++;
		/* type */
		hood[a]->full_type[index_b] = rep->full_type[a];
	    }
	}
    }

    /* rotate to the frame in which the sse vector is pointing up (0,0,1) */
    double rotation_axis[3], z_direction[3] = {0, 0, 1}, theta, cosine, sine;
    double quat[4], **R;
    double **rotated_hood;
    
    if ( ! (R=dmatrix(3,3) )) return 1; /* compiler is bugging me otherwise */
    if ( ! (rotated_hood = dmatrix(max_hood_size,3) )) return 1; 
    
    for (a=0; a<NX; a++) {
 	unnorm_dot (x[a], z_direction, &cosine);
	if ( 1 - cosine <= 0.0001) { // x[a] already pretty much is z-direction
	    // do nothing: hood is already rotated 
	} else {
	    normalized_cross (x[a], z_direction, rotation_axis, &d);
	    // quaternion
	    theta = acos (cosine);
	    quat[0] = cos (theta/2);
	    sine = sin(theta/2);
	    for (i=0; i<3; i++ ) {
		quat[i+1] = sine*rotation_axis[i];
	    }
	    // rotation
	    quat_to_R (quat, R);
	    // rotate all hood vectors
	    rotate(rotated_hood, hood[a]->N_full, R, hood[a]->full );
	    //copy rotated hood into the old one
	    memcpy (hood[a]->full[0], rotated_hood[0], hood[a]->N_full*3*sizeof(double));
	}
    }

    free_dmatrix (R);
    free_dmatrix (rotated_hood);

    return 0;
}