Пример #1
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;
    }
}
Пример #2
0
int cull_by_dna (Representation * X_rep, int *set_of_directions_x,
		 Representation * Y_rep, int *set_of_directions_y,
		 int set_size, Map *map, double cutoff_rmsd) {
    
    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], cross[3],  distance_x, distance_y;
    double aux, rmsd;
    int NX=X_rep->N_full;
    int i, j, ray_a, ray_b, a;
    int in_triple, coord_ctr, norm;
    
    if (set_size < 1 ) return 1;


    for (i=0; i<NX; i++) {
	j = map->x2y[i];
	if ( j<0) continue;

	/* check that i is not in the triple here */
	in_triple = 0;
	for (a=0; a<set_size; a++) {
	    if ( i==set_of_directions_x[a]) {
		in_triple =1;
		break;
	    }
	}
	if (in_triple) continue;

	rmsd = 0.0;
	norm = 0;
	/* the rmsd for the dna of this element to the triple */
	for (a=0; a<set_size; a++) {

	    /**************************************/
	    ray_a = set_of_directions_x[a];
	    ray_b = i;
	    /* distance of nearest approach of ray b
	       to the cm of a, in the set of directions x */
	    for (coord_ctr=0; coord_ctr<3; coord_ctr++ ) {
		cm_vector[coord_ctr] = x_cm[ray_b][coord_ctr] - x_cm[ray_a][coord_ctr];
	    }
	    normalized_cross (cm_vector, x[ray_a], cross, &distance_x);

	    ray_a = set_of_directions_y[a];
	    ray_b = j;
	    /* distance of nearest approach of ray b
	       to the cm of a, in the set of directions y */
	    for (coord_ctr=0; coord_ctr<3; coord_ctr++ ) {
		cm_vector[coord_ctr] = y_cm[ray_b][coord_ctr] - y_cm[ray_a][coord_ctr];
	    }
	    normalized_cross (cm_vector, y[ray_a], cross, &distance_y);

	    aux   = distance_x-distance_y;
	    rmsd += aux*aux;
	    norm ++;

	    /**************************************/
	    ray_b = set_of_directions_x[a];
	    ray_a = i;
	    /* distance of nearest approach of ray b
	       to the cm of a, in the set of directions x */
	    for (coord_ctr=0; coord_ctr<3; coord_ctr++ ) {
		cm_vector[coord_ctr] = x_cm[ray_b][coord_ctr] - x_cm[ray_a][coord_ctr];
	    }
	    normalized_cross (cm_vector, x[ray_a], cross, &distance_x);

	    ray_b = set_of_directions_y[a];
	    ray_a = j;
	    /* distance of nearest approach of ray b
	       to the cm of a, in the set of directions y */
	    for (coord_ctr=0; coord_ctr<3; coord_ctr++ ) {
		cm_vector[coord_ctr] = y_cm[ray_b][coord_ctr] - y_cm[ray_a][coord_ctr];
	    }
	    normalized_cross (cm_vector, y[ray_a], cross, &distance_y);

	    aux   = distance_x-distance_y;
	    rmsd += aux*aux;
	    norm ++;

	}

	rmsd /= norm;
	rmsd = sqrt(rmsd);

	/* if rmsd is bigger than the cutoff, lose this from the mapping */
	if ( rmsd > cutoff_rmsd) {
	    map->x2y[i] = -1;
	    map->y2x[j] = -1;
	}
    }
    
     
    return 0;
}
Пример #3
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 */
}
Пример #4
0
int distance_of_nearest_approach ( Representation * X_rep,  int *set_of_directions_x,
	       Representation * Y_rep, int *set_of_directions_y,
	       int set_size,  double * rmsd_ptr) {
    
    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], cross[3],  distance_x, distance_y;
    double aux, rmsd;
    int i, ray_a, ray_b, a, b, prev_next, norm;
    
    if (set_size <=1 ) return 1;

    rmsd = 0.0;
    norm = 0;
    /* the rmsd for the remaining vectors is ... */
    for (a=0; a<set_size; a++) {

	for ( prev_next = -1;  prev_next <= +1; prev_next +=2 ) {
	    b = (set_size+a+prev_next)%set_size;
	
	    ray_a = set_of_directions_x[a];
	    ray_b = set_of_directions_x[b];
	    /* distance of nearest approach of ray a
	       to the cm of b, in the set of directions x */
	    for (i=0; i<3; i++ ) {
		cm_vector[i] = x_cm[ray_b][i] - x_cm[ray_a][i];
	    }
	    /* the norm of the cross product is ||cm_vector||*sin(alpha),
	       bc the norm of  the rep vectors is 1 */
	    normalized_cross (cm_vector, x[ray_a], cross, &distance_x);

	    ray_a = set_of_directions_y[a];
	    ray_b = set_of_directions_y[b];
 	    /* distance of nearest approach of ray a
	       to the cm of b, in the set of directions y */
	    for (i=0; i<3; i++ ) {
		cm_vector[i] = y_cm[ray_b][i] - y_cm[ray_a][i];
	    }
	    normalized_cross (cm_vector, y[ray_a], cross, &distance_y);


	    aux   = distance_x-distance_y;
	    rmsd += aux*aux;
	    norm ++;
# if 0
	    printf ("%d, %d   x:  %2d  %2d  y:  %2d  %2d  \n", a, b,
		    set_of_directions_x[a], set_of_directions_x[b], 
		    set_of_directions_y[a], set_of_directions_y[b]); 
	    printf (" distance x:  %8.3lf  distance y:  %8.3lf   difference:   %8.3lf \n",
		    distance_x,  distance_y, fabs (distance_x-distance_y));
# endif
	}
	
    }

    rmsd /= norm;
    rmsd  = sqrt(rmsd);
    
    //printf ("***** rmsd:  %8.3lf  \n\n", rmsd);

    *rmsd_ptr = rmsd;
    
    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 */
}
Пример #6
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;
       
}
Пример #7
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;
       
}
Пример #8
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;
}