int print_transformation_0 (FILE* fptr, Map * map, int depth){ double **R; int i, j, ctr; if ( ! (R=dmatrix(3,3) ) ) return 1; /* compiler is bugging me otherwise */ quat_to_R (map->q, R); fprintf (fptr,"rotation\n"); for (i=0; i<3; i++) { if ( depth) for ( ctr=0; ctr < depth; ctr++) fprintf (fptr, "\t"); for (j=0; j<3; j++) fprintf (fptr,"%8.3lf ", R[i][j]); fprintf (fptr,"\n"); } free_dmatrix (R); return 0; }
int christmas_tree_similarity(Representation * hoodX, Representation * hoodY, double *max_score) { double **x = hoodX->full; double **y = hoodY->full; double NX = hoodX->N_full; double NY = hoodY->N_full; int *typeX = hoodX->full_type; int *typeY = hoodY->full_type; double score, theta, cosine, sine; double quat[4], **R, **Ry, **y_prev; int step; if ( ! (R=dmatrix(3,3) )) return 1; /* compiler is bugging me otherwise */ if ( ! (y_prev = dmatrix(NY,3) )) return 1; /* compiler is bugging me otherwise */ if ( ! (Ry = dmatrix(NY,3) )) return 1; /* compiler is bugging me otherwise */ theta = M_PI/1000; cosine = cos(theta/2); sine = sin(theta/2); // rotation about the z-axis quat[0] = cosine; quat[1] = 0; quat[2] = 0; quat[3] = sine; quat_to_R (quat, R); *max_score = exp_score(x, y, NX, NY); memcpy (Ry[0], y[0], NY*3*sizeof(double)); for (step=1; step<1000; step++) { double ** tmp; tmp = y_prev; y_prev = Ry; Ry = tmp; rotate (Ry, NY, R, y_prev); score = hood_score(x, Ry, NX, NY, typeX, typeY); if (score > *max_score) *max_score = score; } free_dmatrix (R); free_dmatrix (Ry); free_dmatrix (y_prev); return 0; }
int mappedCoords2rotation (double **x, double **y, int no_vectors, double q[4], double **R, double T[3], double *rmsd) { double x_mp[3], y_mp[3]; int ctr; int i, j; double ATA [4][4] = {{0.0}}; double prev_ATA[4][4] = {{0.0}}; double ATA_sum [4][4] = {{0.0}}; double a[3] = {0.0}, b[3] = {0.0}; int add_matrices (double matrix1[4][4],double matrix2[4][4], double result[4][4]); int construct_ATA (double ATA[4][4], double a[3], double b[3]); /* note how we pass the matrix: pointer to the first element in the block */ void dsyev_ (char * jobz, char *uplo, int *n, double *A, int * lda, double * w, double * work, int * lwork, int *info); if (!no_vectors) { *rmsd = -1; return 1; } memset ( &(q[0]), 0, 4*sizeof(double) ); /* turn the matching atoms into vectors x and y - use only c-alphas*/ /* check: */ if (0) { printf (" Number of vectors read in: %d. \n", no_vectors); for ( ctr =0; ctr < no_vectors; ctr++ ) { printf ("\t x%1d %10.4lf %10.4lf %10.4lf ", ctr, x[0][ctr], x[1][ctr], x[2][ctr]); printf ("\t y%1d %10.4lf %10.4lf %10.4lf \n", ctr, y[0][ctr], y[1][ctr], y[2][ctr]); } exit (1); } /* find the meanpoints: */ for ( i =0; i < 3; i++ ) { x_mp[i] = 0.0; y_mp[i] = 0.0; } for ( ctr =0; ctr < no_vectors; ctr++ ) { for ( i =0; i < 3; i++ ) { x_mp[i] += x[i][ctr]; y_mp[i] += y[i][ctr]; } } for ( i =0; i < 3; i++ ) { x_mp[i] /= no_vectors; y_mp[i] /= no_vectors; } /* subtract them from x, y */ for ( ctr =0; ctr < no_vectors; ctr++ ) { for ( i =0; i < 3; i++ ) { x[i][ctr] -= x_mp[i]; y[i][ctr] -= y_mp[i]; } } /* B = ATA_sum matrix to diagonalize in order to get the quaternion */ for ( ctr =0; ctr < no_vectors; ctr++ ) { for (i=0; i<3; i++ ) { a[i] = y[i][ctr] + x[i][ctr]; b[i] = y[i][ctr] - x[i][ctr]; } construct_ATA (ATA, a, b); add_matrices (prev_ATA, ATA, ATA_sum); memcpy (prev_ATA[0], ATA_sum[0], 4*4*sizeof(double)); } for (i=0; i<4; i++ ) { for (j=0; j<4; j++ ) { ATA_sum[i][j] /= no_vectors; } } /* diagonalize ATA_sum - the eigenvector corresponsing to the smallest lambda is the quaternion we are looking for; the eigenvalue is the rmsd*/ /* use the nomenclature from dsyev*/ char jobz= 'V'; /*Compute eigenvalues and eigenvectors.*/ char uplo= 'U'; /* Upper triangle of A (the matrix we are diagonalizing) is stored; */ int n = 4; /* order and the leading dimension of A */ int lda = 4; double ** A; int info; int lwork = 200; double w [4]; double work[200]; if ( !( A=dmatrix(4,4) ) ) exit (1); memcpy (A[0], ATA_sum[0], 4*4*sizeof(double)); /* note how we pass the matrix: */ dsyev_ ( &jobz, &uplo, &n, A[0], &lda, w, work, &lwork, &info); if ( ! info) { *rmsd = sqrt (w[0]); for (i=0; i<4; i++ ) q[i] = A[0][i]; if (0) { /* w contains the eigenvalues */ printf ("\n"); for (i=0; i<4; i++ ) printf ("%8.3lf ", w[i]); printf ("\nrmsd: %8.3lf \n", *rmsd); printf ("quat:\n"); for (i=0; i<4; i++ ) printf ("%8.3lf ", q[i]); printf ("\n"); /* printf (" opt lwork: %d\n", (int) work[0]); */ } } else { fprintf (stderr, "Error in dsyev().\n"); exit (1); } /* construct the rotation matrix R */ quat_to_R (q,R); /* T = y_mp - R x_mp */ for (i=0; i<3; i++ ) { T[i] = y_mp[i]; for (j=0; j<3; j++ ) { T[i] -= R[i][j]*x_mp[j]; } } free_dmatrix(A); return 0; }
int single_map_align_backbone (Descr *descr1, Protein * protein1, Representation *rep1, Descr *descr2, Protein * protein2, Representation *rep2, Map * map) { /* for now, we will just postprocess the best map */ int no_res_1 = protein1->length, no_res_2= protein2->length; int resctr1, resctr2; int map_size; int *residue_map_i2j, *residue_map_j2i; int *type_1, *type_2; int longest_element_length = (protein1->length > protein2->length) ? protein1->length : protein2->length; double d0 = options.distance_tol_in_bb_almt; double aln_score, rmsd; double ** similarity; double ** sim_in_element; double **x, **y; double **R, T[3], q[4]; double total_score = 0; /* for the MC: */ int max_no_steps = 20, no_steps = 0; int done = 0, toggle = 0; double *current_q, *old_q, *current_T, *old_T; double *best_q, *best_T; double old_score = total_score, current_score = 0.0, d_mc = 0.5; double max_score; double t_mc, d_init; int alignment_size (int * residue_map_i2j, int no_res_1 ); int closeness_score_for_sse_almt (Descr *descr1, Representation *rep1, Representation *rep2, Map * map, Protein *protein1, Protein *protein2, double **R, double *T, double d0, double ** similarity, double * score_ptr); int following_loop (int *element_begin, int *element_end, int no_of_elements, int no_of_res, int element_ctr, int * first_res, int * last_res); int map2rotation (Protein *protein1, Protein *protein2, int *residue_map_i2j, double **x, double **y, double *q, double *T, double *rmsd); int out_of_order_alignment (Descr *descr1, Descr *descr2, Map *map, int *element_1_begin, int *element_1_end, int *element_2_begin, int *element_2_end, int longest_element_length, double ** similarity, double ** sim_in_element, int *residue_map_i2j, int *residue_map_j2i, double * score_ptr); int preceding_loop (int *element_begin, int *element_end, int element_ctr, int * first_res, int * last_res); if ( ! (R=dmatrix(3,3) ) ) return 1; /* compiler is bugging me otherwise */ construct_translation_vecs (rep1, rep2, map); /* make sure that we have all the info we might need */ /* define matrix, the size of nr of residues in set of SSEs x nr of residues in the other set of SSEs, and fill it with -1 */ similarity = dmatrix (no_res_1, no_res_2); if ( !similarity ) return 1; sim_in_element = dmatrix (no_res_1, no_res_2); if ( !similarity ) return 1; for (resctr1=0; resctr1<no_res_1; resctr1++) { for (resctr2=0; resctr2<no_res_2; resctr2++) { similarity[resctr1][resctr2] = -1; } } /* alloc */ type_1 = protein1->sse_sequence; type_2 = protein2->sse_sequence; if ( ! (residue_map_i2j = emalloc (no_res_1*sizeof(int))) ) return 1; if ( ! (residue_map_j2i = emalloc (no_res_2*sizeof(int))) ) return 2; if ( ! (x = dmatrix (3, no_res_1+no_res_2))) exit(1); if ( ! (y = dmatrix (3, no_res_1+no_res_2))) exit(1); /*********************************************************************/ /*********************************************************************/ /* aliases */ int *element_1_begin, *element_1_end; /* "element" here means SSE */ int *element_2_begin, *element_2_end; element_1_begin = protein1->element_begin; element_1_end = protein1->element_end; element_2_begin = protein2->element_begin; element_2_end = protein2->element_end; /************************************************************/ /************************************************************/ /* ALIGNMENT, round 1 */ /************************************************************/ /* for all mapped blocks calculate similarity as exp (-d/d0) */ total_score = 0.0; quat_to_R (map->q, R); closeness_score_for_sse_almt (descr1, rep1, rep2, map, protein1, protein2, R, NULL, d0, similarity, &total_score); /* run Smith-Waterman and use the mapped CA to find the transformation */ /* I have another copy of SW here (the first one is in struct_map.c) */ /* so I wouldn't fumble with parameters - the two should be joined eventually */ if ( options.search_algorithm == SEQUENTIAL ) { smith_waterman_2 (no_res_1, no_res_2, similarity, residue_map_i2j, residue_map_j2i, &aln_score); } else { out_of_order_alignment (descr1, descr2, map, element_1_begin, element_1_end, element_2_begin, element_2_end, longest_element_length, similarity, sim_in_element, residue_map_i2j, residue_map_j2i, &aln_score); } map2rotation (protein1, protein2, residue_map_i2j, x, y, q, T, &rmsd); quat_to_R (q, R); current_score = alignment_score (protein1, protein2, residue_map_i2j, R, T, d0); /*********************************************************/ /* fiddle iteratively with the transformation */ if ( ! (current_q = emalloc (4*sizeof(double)) )) return 1; if ( ! (old_q = emalloc (4*sizeof(double)) )) return 1; if ( ! (best_q = emalloc (4*sizeof(double)) )) return 1; if ( ! (current_T = emalloc (3*sizeof(double)) )) return 1; if ( ! (old_T = emalloc (3*sizeof(double)) )) return 1; if ( ! (best_T = emalloc (3*sizeof(double)) )) return 1; srand48 (time (0)); memcpy (current_q, q, 4*sizeof(double)); memcpy ( old_q, q, 4*sizeof(double)); memcpy ( best_q, q, 4*sizeof(double)); memcpy ( old_T, T, 3*sizeof(double)); memcpy ( best_T, T, 3*sizeof(double)); memcpy (current_T, T, 3*sizeof(double)); quat_to_R ( current_q, R); d_init = d0; /* t_mc = exp ( (1.0- (double)anneal_round)/10.0); */ d_mc = d_init; t_mc = 5; memcpy (current_q, best_q, 4*sizeof(double)); memcpy (current_T, best_T, 3*sizeof(double)); memcpy (old_q, best_q, 4*sizeof(double)); memcpy (old_T, best_T, 3*sizeof(double)); old_score = 0; max_score = 0; no_steps = 0; toggle = 1; done = 0; while (no_steps < max_no_steps && !done ) { closeness_score_for_sse_almt (descr1, NULL, NULL, map, protein1, protein2, R, current_T, d_mc, similarity, &total_score); if ( options.search_algorithm == SEQUENTIAL ) { smith_waterman_2 (no_res_1, no_res_2, similarity, residue_map_i2j, residue_map_j2i, &aln_score); } else { out_of_order_alignment (descr1, descr2, map, element_1_begin, element_1_end, element_2_begin, element_2_end, longest_element_length, similarity, sim_in_element, residue_map_i2j, residue_map_j2i, &aln_score); } map2rotation (protein1, protein2, residue_map_i2j, x, y, current_q, current_T, &rmsd); quat_to_R ( current_q, R); current_score = alignment_score (protein1, protein2, residue_map_i2j, R, current_T, d_mc); if ( current_score > max_score ) { max_score = current_score; memcpy (best_q, current_q, 4*sizeof(double)); memcpy (best_T, current_T, 3*sizeof(double)); } if (old_score) done = ( fabs(old_score-current_score)/old_score < 0.01); old_score = current_score; no_steps++; } memcpy (q, best_q, 4*sizeof(double)); memcpy (T, best_T, 3*sizeof(double)); free (current_q); free (old_q); free (best_q); free (current_T); free (old_T); free (best_T); /************************************************************/ /************************************************************/ /* ALIGNMENT, round 2 */ /************************************************************/ /************************************************************/ /* find the similarity matrix for this new rotation -- this*/ /* time extending to neighboring elements */ closeness_score_for_bb_almt (map, protein1, protein2, R, T, d0, similarity, &total_score); /************************************************************/ memset (residue_map_i2j, 0, no_res_1*sizeof(int)); memset (residue_map_j2i, 0, no_res_2*sizeof(int)); if ( options.search_algorithm == SEQUENTIAL ) { smith_waterman_2 (no_res_1, no_res_2, similarity, residue_map_i2j, residue_map_j2i, &aln_score); } else { out_of_order_alignment (descr1, descr2, map, element_1_begin, element_1_end, element_2_begin, element_2_end, longest_element_length, similarity, sim_in_element, residue_map_i2j, residue_map_j2i, &aln_score); } map2rotation (protein1, protein2, residue_map_i2j, x, y, q, T, &rmsd); quat_to_R (q, R); //aln_score = alignment_score (protein1, protein2, residue_map_i2j, R, T, d0); map_size = alignment_size (residue_map_i2j, protein1->length); memcpy (&(map->q[0]), &q[0], 4*sizeof(double)); memcpy (&(map->T[0]), &T[0], 3*sizeof(double)); map->x2y_residue_level = residue_map_i2j; map->y2x_residue_level = residue_map_j2i; map->x2y_residue_l_size = no_res_1; map->y2x_residue_l_size = no_res_2; /*************************************************************************/ map->res_almt_length = map_size; map->aln_score = aln_score; map->res_rmsd = rmsd; free_dmatrix(R); free_dmatrix (similarity); free_dmatrix (sim_in_element); free_dmatrix (x); free_dmatrix (y); return 0; }
int complement_match (Representation* X_rep, Representation* Y_rep, Map * map, int map_max, int * map_ctr, int * map_best, int best_max, int parent_map){ Penalty_parametrization penalty_params; /* for SW */ double **x = X_rep->full; int * x_type = X_rep->full_type; int NX = X_rep->N_full; double **y = Y_rep->full; int * y_type = Y_rep->full_type; int NY = Y_rep->N_full; double F_effective = 0.0; double F_current; double q[4] = {0.0}, q_init[4] = {0.0}; double **x_rotated = NULL; double **tr_x_rotated = NULL; double **R; double z_scr = 0.0, *z_best; double avg, avg_sq, stdev; double alpha = options.alpha; double rmsd, best_rmsd[TOP_RMSD]; double **best_quat; double cutoff_rmsd = 3.0; /* <<<<<<<<<<<<<<<<< hardcoded */ int *x_type_fudg, *y_type_fudg; int *anchor_x, *anchor_y, no_anchors; int no_top_rmsd = TOP_RMSD, chunk; int x_ctr, y_ctr, top_ctr; int **best_triple_x; int **best_triple_y; int x_triple[3], y_triple[3]; int retval, done = 0; int best_ctr; int i, j; int t; int smaller; int my_map_ctr; int stored_new; int * x2y, map_unstable; //time_t time_now, time_start; 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); 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); int same_hand_triple (Representation * X_rep, int *set_of_directions_x, Representation * Y_rep, int *set_of_directions_y, int set_size); int find_map (Penalty_parametrization * params, Representation *X_rep, Representation *Y_rep, double ** R, double alpha, double * F_effective, Map *map, int *anchor_x, int * anchor_y, int anchor_size ); int find_next_triple (double **X, double **Y, int *x_type, int *y_type, int NX, int NY, int *x_triple, int *y_triple); int gradient_descent (int first_call, double alpha, double **x, int * x_type, int NX, double **y, int * y_type, int NY, double *q_best, double *F_best_ptr) ; int map_quality_metrics (Representation *X_rep, Representation *Y_rep, double ** tr_x_rotated, Map * map, int *reasonable_angle_ct); int monte_carlo (double alpha, double **x, int * x_type, int NX, double **y, int * y_type, int NY, double *q_best, double *F_best_ptr); int opt_quat (double ** x, int NX, int *set_of_directions_x, double ** y, int NY, int *set_of_directions_y, int set_size, double * q, double * rmsd); int qmap (double *x0, double *x1, double *y0, double *y1, double * quat); int store_sorted (Map * map, int NX, int NY, int *map_best, int map_max, double * z_best, int best_ctr, double z_scr, int my_map_ctr, int *stored); map_best[0] = -1; /* it is the end-of-array flag */ if ( *map_ctr >= map_max ) { fprintf (stderr, "Map array undersized.\n"); exit (1); } smaller = (NX <= NY) ? NX : NY; /***********************/ /* memory allocation */ /***********************/ if ( ! (R=dmatrix(3,3) ) ) return 1; /* compiler is bugging me otherwise */ if ( ! (x_rotated = dmatrix (NX,3)) ) return 1; if ( ! (tr_x_rotated = dmatrix (NX,3)) ) return 1; if ( ! (best_quat = dmatrix (no_top_rmsd,4)) ) return 1; if ( ! (best_triple_x = intmatrix (no_top_rmsd,3)) ) return 1; if ( ! (best_triple_y = intmatrix (no_top_rmsd,3)) ) return 1; if ( ! (z_best = emalloc(NX*NY*sizeof(double) )) ) return 1; if ( ! (x_type_fudg = emalloc(NX*sizeof(int) )) ) return 1; if ( ! (y_type_fudg = emalloc(NY*sizeof(int) )) ) return 1; if ( ! (anchor_x = emalloc(NX*sizeof(int) )) ) return 1; if ( ! (anchor_y = emalloc(NY*sizeof(int) )) ) return 1; penalty_params.custom_gap_penalty_x = NULL; penalty_params.custom_gap_penalty_y = NULL; //if ( ! (penalty_params.custom_gap_penalty_x = emalloc(NX*sizeof(double) )) ) return 1; //if ( ! (penalty_params.custom_gap_penalty_y = emalloc(NY*sizeof(double) )) ) return 1; /***********************/ /***********************/ /* expected quantities */ /***********************/ avg = avg_sq = stdev = 0.0; //if (options.postprocess) { if (0) { if (F_moments (x, x_type, NX, y, y_type, NY, alpha, &avg, &avg_sq, &stdev)) return 1; } /***********************/ /***********************/ /* initialization */ /***********************/ best_ctr = 0; penalty_params.gap_opening = options.gap_open; penalty_params.gap_extension = options.gap_extend; penalty_params.endgap = options.endgap; penalty_params.endgap_special_treatment = options.use_endgap; /***********************/ /***************************************/ /* find reasonble triples of SSEs */ /* that correspond in type */ /* and can be mapped onto each other */ /***************************************/ for (top_ctr=0; top_ctr<no_top_rmsd; top_ctr++) { best_rmsd[top_ctr] = BAD_RMSD+1; best_triple_x[top_ctr][0] = -1; } for (x_ctr=0; x_ctr < NX-2 && !done; x_ctr++) { for (y_ctr=0; y_ctr < NY-2 && !done; y_ctr++) { if ( y_type[y_ctr] != x_type[x_ctr] ) continue; x_triple[0] = x_ctr; y_triple[0] = y_ctr; if (find_next_triple (x, y, x_type, y_type, NX, NY, x_triple, y_triple) ){ continue; } if ( x_triple[1] < 0 || x_triple[2] < 0 ) continue; if ( y_triple[1] < 0 || y_triple[2] < 0 ) continue; /* do these three have kind-of similar layout in space?*/ /* is handedness the same? */ if ( ! same_hand_triple ( X_rep, x_triple, Y_rep, y_triple, 3)) continue; /* are distances comparab;e? */ if (distance_of_nearest_approach ( X_rep, x_triple, Y_rep, y_triple, 3, &rmsd)) continue; if ( rmsd > cutoff_rmsd) continue; /* find q_init that maps the two triples as well as possible*/ if ( opt_quat ( x, NX, x_triple, y, NY, y_triple, 3, q_init, &rmsd)) continue; for (top_ctr=0; top_ctr<no_top_rmsd; top_ctr++) { if ( rmsd <= best_rmsd[top_ctr] ) { chunk = no_top_rmsd - top_ctr -1; if (chunk) { memmove (best_rmsd+top_ctr+1, best_rmsd+top_ctr, chunk*sizeof(double)); memmove (best_quat[top_ctr+1], best_quat[top_ctr], chunk*4*sizeof(double)); memmove (best_triple_x[top_ctr+1], best_triple_x[top_ctr], chunk*3*sizeof(int)); memmove (best_triple_y[top_ctr+1], best_triple_y[top_ctr], chunk*3*sizeof(int)); } best_rmsd[top_ctr] = rmsd; memcpy (best_quat[top_ctr], q_init, 4*sizeof(double)); memcpy (best_triple_x[top_ctr], x_triple, 3*sizeof(int)); memcpy (best_triple_y[top_ctr], y_triple, 3*sizeof(int)); break; } } } } # if 0 for (top_ctr=0; top_ctr<no_top_rmsd; top_ctr++) { if ( best_rmsd[top_ctr] > BAD_RMSD ) break; printf (" %3d %8.3lf ", top_ctr, best_rmsd[top_ctr]); vec_out ( best_quat[top_ctr], 4, "quat: "); for (t=0; t<3; t++ ) { printf ("\t %3d %3d \n", best_triple_x[top_ctr][t]+1, best_triple_y[top_ctr][t]+1 ); } } exit (1); # endif /*********************************************/ /* main loop */ /*********************************************/ for (top_ctr=0; top_ctr<no_top_rmsd; top_ctr++) { if ( best_rmsd[top_ctr] > BAD_RMSD ) break; quat_to_R (best_quat[top_ctr], R); rotate (x_rotated, NX, R, x); F_current = F( y, y_type, NY, x_rotated, x_type, NX, alpha); # if 0 printf ("\n***********************************\n"); printf (" %3d %8.3lf %8.3lf ", top_ctr, best_rmsd[top_ctr], F_current); vec_out ( best_quat[top_ctr], 4, "quat: "); for (t=0; t<3; t++ ) { printf ("\t %3d %3d \n", best_triple_x[top_ctr][t]+1, best_triple_y[top_ctr][t]+1 ); } # endif /* find map which uses the 2 triples as anchors */ no_anchors = 3; find_map (&penalty_params, X_rep, Y_rep, R, alpha, &F_effective, map + (*map_ctr), best_triple_x[top_ctr], best_triple_y[top_ctr], no_anchors); x2y = ( map + (*map_ctr) ) ->x2y; map_unstable = 0; for (t=0; t<3; t++ ) { if ( x2y[best_triple_x[top_ctr][t]] != best_triple_y[top_ctr][t] ) { map_unstable = 1; } } if ( map_unstable) continue; /* dna here is not DNA but "distance of nearest approach" */ cull_by_dna ( X_rep, best_triple_x[top_ctr], Y_rep, best_triple_y[top_ctr], 3, map + (*map_ctr), cutoff_rmsd ); //printf ("map after culling by dna:\n"); //print_map (stdout, map+ (*map_ctr), NULL, NULL, NULL, NULL, 1); /* monte that optimizes the aligned vectors only */ for (i=0; i<NX; i++) { x_type_fudg[i] = JACKFRUIT; } for (j=0; j<NY; j++) { y_type_fudg[j] = JACKFRUIT*2; } no_anchors = 0; for (i=0; i<NX; i++) { j = (map+(*map_ctr))->x2y[i]; if (j < 0 ) continue; x_type_fudg[i] = x_type[i]; y_type_fudg[j] = y_type[j]; anchor_x[no_anchors] = i; anchor_y[no_anchors] = j; no_anchors ++; } if ( opt_quat ( x, NX, anchor_x, y, NY, anchor_y, no_anchors, q, &rmsd)) continue; retval = monte_carlo ( alpha, x, x_type_fudg, NX, y, y_type_fudg, NY, q, &F_current); if (retval) return retval; if (options.postprocess) { z_scr = stdev ? (F_current - avg)/stdev : 0.0; } else { z_scr = 0.0; } quat_to_R (q, R); /* store_image() is waste of time, but perhaps not critical */ store_image (X_rep, Y_rep, R, alpha, map + (*map_ctr)); map_assigned_score ( X_rep, map + (*map_ctr)); //printf ("map %2d assigned score: %8.3lf z_score: %8.3lf \n\n", // *map_ctr+1, (map + (*map_ctr)) -> assigned_score, z_scr); /* store the map that passed all the filters down to here*/ my_map_ctr = *map_ctr; map[my_map_ctr].F = F_current; map[my_map_ctr].avg = avg; map[my_map_ctr].avg_sq = avg_sq; map[my_map_ctr].z_score = z_scr; memcpy ( map[my_map_ctr].q, q, 4*sizeof(double) ); /* recalculate the assigned score*/ //if (top_ctr==24) exit (1); /************************/ /* store sorted */ /************************/ /* find the place for the new z-score */ store_sorted (map, NX, NY, map_best, map_max, z_best, best_ctr, -map[my_map_ctr].assigned_score, my_map_ctr, &stored_new); if ( stored_new ) { /* we want to keep this map */ (*map_ctr) ++; best_ctr++; } /* otherwise this map space is reusable */ /* is this pretty much as good as it can get ? */ if ( fabs (map[my_map_ctr].assigned_score - smaller) < options.tol ) done = 1; } map_best[best_ctr] = -1; /******************************************************/ /* look for the sub-map of a couple of best hits */ /******************************************************/ /* initialization:*/ map_consistence ( NX, NY, NULL, NULL, NULL, NULL, NULL); best_ctr = 0; while ( map_best[best_ctr] > -1 ) { best_ctr ++; } //exit (1); if (best_ctr) { int nr_maps = (best_ctr<options.number_maps_cpl)? best_ctr : options.number_maps_cpl; int best_i; int consistent; double z; double total_assigned_score, score, best_score = -100; double gap_score; for (i=0; i<nr_maps; i++) { /* look for the complement */ best_i = map_best[i]; /*intialize the (list of) submatch map(s) */ if ( !map[best_i].submatch_best) { /* for now look for a single map only */ /* TODO - would it be worth any to look at more maps?*/ int map_max = 1; map[best_i].submatch_best = emalloc (map_max*sizeof(int) ); if (! map[best_i].submatch_best) return 1; } map[best_i].submatch_best[0] = -1; map[best_i].score_with_children = 0; map[best_i].compl_z_score = 0; for (j=0; j<best_ctr; j++) { if (i==j) continue; map_complementarity ( map+best_i, map + map_best[j], &z); map_consistence ( NX, NY, map+best_i, map + map_best[j], &total_assigned_score, &gap_score, NULL); consistent = ( (map+best_i)->assigned_score < total_assigned_score && (map + map_best[j])->assigned_score < total_assigned_score); if ( consistent ) { score = total_assigned_score; if ( score > best_score ) { best_score = score; map[best_i].submatch_best[0] = map_best[j]; map[best_i].score_with_children = total_assigned_score; map[best_i].compl_z_score = z; } } } } } /**********************/ /* garbage collection */ gradient_descent (1, 0.0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL); free_dmatrix (R); free_dmatrix (x_rotated); free_dmatrix (tr_x_rotated); free_dmatrix (best_quat); free_imatrix (best_triple_x); free_imatrix (best_triple_y); free (z_best); free (x_type_fudg); free (y_type_fudg); free (anchor_x); free (anchor_y); if (penalty_params.custom_gap_penalty_x) free (penalty_params.custom_gap_penalty_x); if (penalty_params.custom_gap_penalty_y) free (penalty_params.custom_gap_penalty_y); /*********************/ return 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; }
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; }
/* 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; }