match.c
来自「最经典的分子对结软件」· C语言 代码 · 共 2,459 行 · 第 1/4 页
C
2,459 行
int match_distance (MATCH *match){ int i, j; /* Counter variable */ EDGE edge; /* Edge under consideration */ EDGE iedge, jedge; /* Edge comparisons */ int valid_clique; /* Flag for whether an valid_clique found */ int match_chirality (MATCH *, int);/** If a prior clique existed, then erase the last node and* decrement the clique size* 11/96 te*/ if (match->clique.edge_total > 0) { match->clique.edge_total--; match->clique.edge[match->clique.edge_total].node = 0; match->clique.edge[match->clique.edge_total].residual = 0; }/** Perform clique detection until valid clique is found* 11/96 te*/ for (valid_clique = FALSE; !valid_clique;) {/** Can we expand the current clique? Check if:* 1. The clique is smaller than the maximum size* 2. There are unused nodes in the clique adjacency list* 11/96 te*/ if ( (match->clique.edge_total < match->clique_size_max) && (match->adjacent[match->clique.edge_total] < match->clique_adjacency_total[match->clique.edge_total]) ) {/** Identify the next adjacent node and increment the adjacency list* 11/96 te*/ edge = match->clique_adjacency_list [match->clique.edge_total] [match->adjacent[match->clique.edge_total]++];/** STAGE 1: The node is geometrically feasible, if* 1. The node passes the critical cluster filter:* a. The filter is not requested, OR* b. The filter indicates valid node, AND* 2. The clique has proper chirality:* a. Chirality checking is not necessary, OR* b. The node is not being added to a three-node clique, OR* c. The chirality of the new clique is correct, OR* d. The ligand is allowed to be reflected* 11/96 te*/ if ( ( !match->critical_flag || (((match->clique.edge_total == 0) && match->critical_filter[0][edge.node]) || ((match->clique.edge_total > 0) && match->critical_filter [match->receptor_site.atom [match->clique.edge[match->clique.edge_total - 1].node / match->ligand_center.total.atoms].subst_id + 1][edge.node])) ) && ( !match->chiral_flag || (match->clique.edge_total != 3) || !(match->clique.reflect_flag = match_chirality (match, edge.node)) || match->reflect_flag ) ) {/** STAGE 2: The node is worth adding, if:* 1. The current node isn't forming a redundant clique:* a. We don't care, OR* b. It the first in the clique, OR* c. The node is numerically above the previously added node, AND* 2. The current node passes the chemical filter* a. The filter is not requested, OR* a. The filter indicates a valid node* 11/96 te*/ if ( ( !match->degeneracy_flag || !match->clique.edge_total || (edge.node > match->clique.edge[match->clique.edge_total - 1].node) ) && ( !match->chemical_flag || match->chemical_filter[edge.node] ) ) {/** Record the node in the clique and increment the clique size.* Also, document the finding of a clique of this size,* and erase the record of the next larger one.* 11/96 te*/ match->clique.edge[match->clique.edge_total++] = edge; if (match->degeneracy_flag) { match->degenerate[match->clique.edge_total - 1] = TRUE; match->degenerate[match->clique.edge_total] = FALSE; }/** Construct an adjacency list for the new clique* 11/96 te*/ for ( i = j = match->adjacent[match->clique.edge_total] = match->clique_adjacency_total[match->clique.edge_total] = 0; (i < match->clique_adjacency_total[match->clique.edge_total - 1]) && (j < match->adjacency_total[edge.node]); ) { iedge = match->clique_adjacency_list [match->clique.edge_total - 1][i]; jedge = match->adjacency_list[edge.node][j]; if (jedge.node < iedge.node) j++; else if (iedge.node < jedge.node) i++; else { match->clique_adjacency_list [match->clique.edge_total] [match->clique_adjacency_total[match->clique.edge_total]++] = (iedge.residual > jedge.residual) ? iedge : jedge; i++, j++; } } }/** If this node fails STAGE2 check, then for the sake of degeneracy* checking, record that this clique *could* have existed* 11/96 te*/ else if (match->degeneracy_flag) match->degenerate[match->clique.edge_total] = TRUE; } }/** If we cannot expand the current clique, then process it.* 10/96 te*/ else if (match->clique.edge_total > 0) {/** Compute residual of clique and check its validity* 1/97 te*/ for (i = match->clique.residual = 0; i < match->clique.edge_total; i++) match->clique.residual = MAX (match->clique.residual, match->clique.edge[i].residual);/** This clique is sufficient for generating an orientation, if:* 1. The clique is large enough, AND* 2. The clique passes the degeneracy filter* a. The filter is not requested, OR* b. The filter indicates the cliqe is not degenerate* 11/96 te*/ if ( (match->clique.edge_total >= match->clique_size_min) && (!match->degeneracy_flag || !match->degenerate[match->clique.edge_total]) && (match->clique.residual > ((match->cycle - 1) * match->distance_tolerance)) ) valid_clique = TRUE;/** Otherwise, erase the last node and decrement the clique size* 11/96 te*/ else { match->clique.edge_total--; match->clique.edge[match->clique.edge_total].node = 0; match->clique.edge[match->clique.edge_total].residual = 0; } } else return EOF; }/** Update match statistics* 11/96 te*/ match->histogram[match->clique.edge_total - 1]++;/** Reset ligand reflection state* 1/97 te*/ if (match->clique.edge_total < 4) match->clique.reflect_flag = FALSE; return TRUE;}/* ////////////////////////////////////////////////////////////// Routine to check if the ligand and receptor portions of a cliquehave the same or opposite chirality.Return values: TRUE: The ligand must be reflected FALSE: The ligand must not be reflected7/95 te////////////////////////////////////////////////////////////// */int match_chirality (MATCH *match, int node){ int i; static int atoms[4], sites[4]; float calc_chirality (int *, XYZ **); for (i = 0; i < 3; i++) { atoms[i] = match->clique.edge[i].node % match->ligand_center.total.atoms; sites[i] = match->clique.edge[i].node / match->ligand_center.total.atoms; } atoms[3] = node % match->ligand_center.total.atoms; sites[3] = node / match->ligand_center.total.atoms; if (calc_chirality (atoms, match->ligand_vectors) * calc_chirality (sites, match->receptor_vectors) < 0.0) return TRUE; else return FALSE;}/* ////////////////////////////////////////////////////////////// Routine to calculate the whether the fourth member is above orbelow the plane defined by the first three members of a group.7/95 te////////////////////////////////////////////////////////////// */float calc_chirality (int atoms[4], XYZ **vector){ static XYZ normal; void vcrossv3 (XYZ, XYZ, XYZ); float vdotv3 (XYZ, XYZ); vcrossv3 (vector[atoms[0]][atoms[1]], vector[atoms[0]][atoms[2]], normal); return vdotv3 (vector[atoms[0]][atoms[3]], normal);}/* ////////////////////////////////////////////////////////////// Routine to output match routine statistics7/95 te////////////////////////////////////////////////////////////// */void output_match_info (MATCH *match){ int i;/** Output histogram of clique formation* 6/95 te*/ if ((global.output_volume != 't') && (match->total > 0)) { fprintf (global.outfile, "\n_______Matching_Histogram______\n"); for (i = 0; i < match->clique_size_max; i++) if (match->histogram[i] > 0) fprintf (global.outfile, "%7d node%s: %9d\n", i + 1, (i == 0 ? " " : "s"), match->histogram[i]); fprintf (global.outfile, "\n"); }}/* ///////////////////////////////////////////////////////////// */void extract_clique (MATCH *match, MOLECULE *molecule){ int i, lig, rec; molecule->transform.refl_flag = match->clique.reflect_flag; for (i = 0; i < match->clique.edge_total; i++) { rec = match->clique.edge[i].node / match->ligand_center.total.atoms; copy_atom (&match->receptor_clique.atom[i], &match->receptor_site.atom[rec]); copy_coord (match->receptor_clique.coord[i], match->receptor_site.coord[rec]); } for (i = 0; i < match->clique.edge_total; i++) { lig = match->clique.edge[i].node % match->ligand_center.total.atoms; copy_atom (&match->ligand_clique.atom[i], &match->ligand_center.atom[lig]); copy_coord (match->ligand_clique.coord[i], match->ligand_center.coord[lig]); } match->ligand_clique.total.atoms = match->receptor_clique.total.atoms = match->clique.edge_total;}/* ////////////////////////////////////////////////////////////// Routine to construct a random match3/97 te////////////////////////////////////////////////////////////// */int get_random_match( MATCH *match, LABEL *label, MOLECULE *mol_conf, int molecule_id, int conformation_id, int orientation_id){ int i, j; int unique; if (orientation_id == 0) { if ((molecule_id == 0) && (conformation_id == 0)) { get_site (match, label); get_centers (match, label); match->clique.edge_max = match->clique_size_min; allocate_clique (&match->clique); match->clique.edge_total = match->clique_size_min; allocate_clique_atoms (match); } if (!match->centers_flag) get_ligand_centers (match, mol_conf); if (conformation_id == 0) match->node_total = match->ligand_center.total.atoms * match->receptor_site.total.atoms; }/** Assign nodes to clique* 3/97 te*/ for (i = 0; i < match->clique.edge_total;) { match->clique.edge[i].node = rand () % match->node_total; for (j = 0, unique = TRUE; j < i; j++) if ((match->clique.edge[i].node % match->ligand_center.total.atoms == match->clique.edge[j].node % match->ligand_center.total.atoms) || (match->clique.edge[i].node / match->ligand_center.total.atoms == match->clique.edge[j].node / match->ligand_center.total.atoms)) unique = FALSE; if (unique) i++; } return TRUE;}/* ////////////////////////////////////////////////////////////// Routine to free random matching arrays5/97 te////////////////////////////////////////////////////////////// */void free_random_matches (MATCH *match){ free_clique (&match->clique); free_ligand_centers (match); free_molecule (&match->receptor_site); free_molecule (&match->ligand_clique); free_molecule (&match->receptor_clique);}/* ////////////////////////////////////////////////////////////// Routine to manage chemical screening3/96 te////////////////////////////////////////////////////////////// */int check_screen( MATCH *match, LABEL *label, MOLECULE *molecule, int molecule_id){ static MOLECULE temporary = {0}; match->chiral_flag = FALSE; if (label->chemical.screen.pharmaco_flag) { if (molecule_id == 0) { init_match_site (match, label); update_keys (&label->chemical, &match->receptor_site, 0); } if (label->chemical.screen.fold_flag) return check_pharmacophore ( &label->chemical, match->distance_tolerance, &match->receptor_site, molecule ); else { get_ligand_keys (match, molecule); init_match_ligand (match, label); initialize_adjacency (match, label); if (match_distance (match) != EOF) return TRUE; else return FALSE; } } else if (label->chemical.screen.similar_flag) { if (molecule_id == 0) init_similar_site (match, label); molecule->score.total = molecule->score.inter.total = check_dissimilarity (&label->chemical, &match->receptor_site, molecule); if (molecule->score.total <= label->chemical.screen.dissimilar_maximum) return TRUE; else return FALSE; } else if (label->chemical.screen.fold_flag) { if (!label->chemical.init_flag) get_chemical_labels (&label->chemical); fold_keys (&label->chemical, &temporary, molecule); copy_keys (molecule, &temporary); return TRUE; } else return FALSE;}/* ////////////////////////////////////////////////////////////// Routine to free chemical screening arrays5/97 te////////////////////////////////////////////////////////////// */void free_screen( MATCH *match, LABEL *label){ if (label->chemical.screen.pharmaco_flag) { free_match_site (match, label);/* if (label->chemical.screen.fold_flag) return check_pharmacophore ( &label->chemical, match->distance_tolerance, &match->receptor_site, molecule ); else { get_ligand_keys (match, molecule); init_match_ligand (match, label); initialize_adjacency (match, label); if (match_distance (match) != EOF) return TRUE; else return FALSE; }*/ } else if (label->chemical.screen.similar_flag) { free_molecule (&match->receptor_site); free_table (&label->chemical, &label->chemical.screen_table); }/* else if (label->chemical.screen.fold_flag) { if (!label->chemical.init_flag) get_chemical_labels (&label->chemical); fold_keys (&label->chemical, &temporary, molecule); copy_keys (molecule, &temporary); return TRUE; }*/}/* ////////////////////////////////////////////////////////////// Routine to prepare for similarity search3/96 te////////////////////////////////////////////////////////////// */void init_similar_site( MATCH *match, LABEL *label){ FILE *file; get_chemical_labels (&label->chemical);/** Read in reference molecule for similarity search* 11/96 te*/ file = efopen (match->receptor_file_name, "r", global.outfile); if (read_molecule (&match->receptor_site, NULL, match->receptor_file_name, file, FALSE) != TRUE) exit (fprintf (global.outfile, "ERROR init_similar_site: Error reading in reference molecule.\n")); fclose (file);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?