match.c

来自「最经典的分子对结软件」· C语言 代码 · 共 2,459 行 · 第 1/4 页

C
2,459
字号
  copy_transform (&match->ligand_center, molecule);/** Calculate distance matrix* 3/97 te*/  calculate_distances  (    &match->ligand_center,    &match->ligand_distances,    &match->ligand_distance_size  );/** Compute vectors for chirality checking* 1/97 te*/  calculate_vectors  (    &match->ligand_center,    &match->ligand_vectors,    &match->ligand_vector_size  );  return TRUE;}/* ////////////////////////////////////////////////////////////// Routine to free ligand centers5/97 te////////////////////////////////////////////////////////////// */void free_ligand_centers (MATCH *match){  free_molecule (&match->ligand_center);  efree ((void **) &match->ligand_key);  free_distances  (    &match->ligand_distances,    &match->ligand_distance_size  );  free_vectors  (    &match->ligand_vectors,    &match->ligand_vector_size  );}/* ////////////////////////////////////////////////////////////// Routine to extract ligand keys from a ligand3/96 te////////////////////////////////////////////////////////////// */int get_ligand_keys(  MATCH		*match,  MOLECULE	*molecule){  int i;  if (molecule->transform.fold_flag == TRUE)    exit (fprintf (global.outfile,      "ERROR get_ligand_keys: ligand keys are folded\n"));  if (molecule->total.atoms > match->ligand_center.max.atoms)    exit (fprintf      (global.outfile, "ERROR get_ligand_keys: too many ligand atoms\n"));  match->ligand_center.total.atoms = molecule->total.atoms;  for (i = 0; i < molecule->total.atoms; i++)    match->ligand_center.atom[i].chem_id = molecule->atom[i].chem_id;  copy_keys (&match->ligand_center, molecule);  return TRUE;}/* ////////////////////////////////////////////////////////////// Routine to make the chemical matching filter.7/95 te////////////////////////////////////////////////////////////// */void make_chemical_filter(  LABEL_CHEMICAL *label_chemical,  MATCH		*match){  int i, j, node;  for (i = node = 0; i < match->receptor_site.total.atoms; i++)    for (j = 0; j < match->ligand_center.total.atoms; j++, node++)      match->chemical_filter[node] = (char) label_chemical->match_table        [match->ligand_center.atom[j].chem_id]        [match->receptor_site.atom[i].chem_id];}    /* ////////////////////////////////////////////////////////////// Routine to construct the critical cluster filter used during matching.7/95////////////////////////////////////////////////////////////// */void make_critical_filter (MATCH *match){  int i, j;/** Reset critical filters* 7/95 te*/  for (i = 0; i < match->cluster_total; i++)    memset (match->critical_filter[i], 0, match->node_max);  memset (match->critical_filter[match->cluster_total], 1, match->node_max);/** Turn ON selected elements in filters* 7/95 te*/  for (i = 0; i < match->receptor_site.total.atoms; i++)    for (j = i * match->ligand_center.total.atoms;       j < (i + 1) * match->ligand_center.total.atoms; j++)      match->critical_filter[match->receptor_site.atom[i].subst_id][j] = 1;/** If user wants MULTIPLE selections from each critical cluster,* then make each screen INCLUDE selection from all preceding clusters* 7/95 te*/  if (match->multiple_flag)    for (i = 0; i < match->cluster_total - 1; i++)      for (j = 0; j < match->node_max; j++)        match->critical_filter[i + 1][j] |=          match->critical_filter[i][j];}/* ////////////////////////////////////////////////////////////// Routine to construct the node adjacency matrices used to guide cliqueformation during the matching routine.  7/95 te////////////////////////////////////////////////////////////// */void compute_adjacency (MATCH *match){  int li, lj;		/* Ligand atom iterators */  int ri, rj;		/* Receptor point iterators */  int inode, jnode;	/* Node values */  int bin_id;		/* Bin position */  int bin_tolerance;	/* Tolerance in bin position */  int bin_center;	/* Center bin to query */  int bin_initial;	/* Initial bin to query */  int bin_final;	/* Final bin to query */  SLINT2 *bin;		/* Bin pointer */  float residual;	/* Difference in distances */  int compare_nodes ();  bin_tolerance = (int)    (match->cycle * match->distance_tolerance / match->bin_width + .9999);/** Loop through all possible ligand center pairs* 7/95 te*/  for (li = 0; li < match->ligand_center.total.atoms; li++)    for (lj = li + 1; lj < match->ligand_center.total.atoms; lj++)    {/**     Check first geometric criteria for adjacency*     7/95 te*/      if (match->ligand_distances[li][lj] < match->distance_minimum)        continue;/**     Determine which receptor distance bins to check*     1/97 te*/      bin_center =        NINT (match->ligand_distances[li][lj] / match->bin_width);      bin_initial = MAX (0, bin_center - bin_tolerance);      bin_final = MIN (match->bin_total, bin_center + bin_tolerance + 1);/**     Loop through all retrieved site point pairs*     1/97 te*/      for (bin_id = bin_initial; bin_id < bin_final; bin_id++)        for (bin = match->bin[bin_id]; bin != NULL; bin = bin->next)        {/**         Extract the site point id*         1/97 te*/          ri = bin->i;          rj = bin->j;/**         Determine if the two receptor site points can join the two*         ligand centers to form two adjacent nodes.  Node adjacency is*         determined by the following geometric criteria:**           1) satisfies *distance_tolerance**           2) satisfies *distance_minimum***         1/97 te*/          residual =            match->ligand_distances[li][lj] -            match->receptor_distances[ri][rj];          residual = ABS (residual);          if ((residual > match->cycle * match->distance_tolerance) ||            (match->receptor_distances[ri][rj] < match->distance_minimum))            continue;/**         Compute the first two of four possible nodes and update*         adjacency matrices.*         7/95 te*/          inode = ri * match->ligand_center.total.atoms + li;          jnode = rj * match->ligand_center.total.atoms + lj;          append_adjacency (match, inode, jnode, residual);          if (match->degeneracy_flag)            append_adjacency (match, jnode, inode, residual);/**         Compute the second two of four possible nodes and update*         adjacency matrices.*         7/95 te*/          inode = ri * match->ligand_center.total.atoms + lj;          jnode = rj * match->ligand_center.total.atoms + li;          append_adjacency (match, inode, jnode, residual);          if (match->degeneracy_flag)            append_adjacency (match, jnode, inode, residual);        }    }/** Sort each adjacency list by ascending order* 7/95 te*/  for (li = 0; li < match->node_total; li++)  {    if (!match->chemical_flag || match->chemical_filter[li])      qsort      (        match->adjacency_list[li],        match->adjacency_total[li],        sizeof (EDGE),        compare_nodes      );  }/*  for (li = 0; li < match->node_total; li++)  {    fprintf (global.outfile, "node %d:", li);    for (lj = 0; lj < match->adjacency_total[li]; li++)      fprintf (global.outfile, " %d", match->adjacency_list[li][lj].node);    fprintf (global.outfile, "\n");  }*/}/* ////////////////////////////////////////////////////////////// Routine to construct the node adjacency matrices used to guide cliqueformation during the matching routine (for chemical screening).  7/95 te////////////////////////////////////////////////////////////// */void compute_chemical_adjacency (MATCH *match, LABEL *label){  int li, lj;		/* Ligand atom iterators */  int ri, rj;		/* Receptor point iterators */  int inode, jnode;	/* Node values */  int lil, ljl;		/* Label id of ligand iterators */  int ril, rjl;		/* Label id of receptor iterators */  int compare_nodes ();  update_uncertainty  (    &label->chemical,    match->distance_tolerance,    &match->ligand_center  );/** Loop through all possible ligand center pairs* 11/96 te*/  for (ri = 0; ri < match->receptor_site.total.atoms; ri++)  {    ril = match->receptor_site.atom[ri].chem_id;    for (rj = ri + 1; rj < match->receptor_site.total.atoms; rj++)    {      if (match->receptor_distances[ri][rj] < match->distance_minimum)        continue;      rjl = match->receptor_site.atom[rj].chem_id;      for (li = 0; li < match->ligand_center.total.atoms; li++)      {        lil = match->ligand_center.atom[li].chem_id;        if (!label->chemical.match_table[ril][lil])          continue;        for (lj = li + 1; lj < match->ligand_center.total.atoms; lj++)        {          ljl = match->ligand_center.atom[lj].chem_id;          if (!label->chemical.match_table[rjl][ljl])            continue;          if (!(match->receptor_site.key[ri][rj].distance &            match->ligand_center.key[li][lj].distance))            continue;          inode = ri * match->ligand_center.total.atoms + li;          jnode = rj * match->ligand_center.total.atoms + lj;          append_adjacency (match, inode, jnode, 0);        }      }    }  }/** Sort each adjacency list by ascending order* 11/96 te*/  for (li = 0; li < match->node_total; li++)  {    if (match->chemical_filter[li])      qsort      (        match->adjacency_list[li],        match->adjacency_total[li],        sizeof (EDGE),        compare_nodes      );  }}/* ////////////////////////////////////////////////////////////// Routine used by qsort to determine the order of the adjacency lists.7/95 te////////////////////////////////////////////////////////////// */int compare_nodes(  EDGE *pta,  EDGE *ptb){  return (pta->node == ptb->node) ? 0 : ((pta->node > ptb->node) ? 1 : -1);}/* ////////////////////////////////////////////////////////////// Routine to add a node to an adjacency list.11/96 te////////////////////////////////////////////////////////////// */void append_adjacency (MATCH *match, int list, int node, float residual){  if (match->adjacency_total[list] + 1 >    match->adjacency_max[list])  {    match->adjacency_max[list] += 10;    erealloc    (      (void **) &match->adjacency_list[list],      match->adjacency_max[list] * sizeof (EDGE),      "adjacency list",      global.outfile    );  }  match->adjacency_list    [list][match->adjacency_total[list]].node = node;  match->adjacency_list    [list][match->adjacency_total[list]].residual = residual;  match->adjacency_total[list]++;}/* ////////////////////////////////////////////////////////////// Routine to assemble all matches for a given distance toleranceReturn values:	TRUE	matches recorded	EOF	insufficient matches recorded (terminate orienting)1/97 te////////////////////////////////////////////////////////////// */int compute_matches (MATCH *match){  int i;  int previous_max;		/* Record of the number of previous matches */  SLCLIQUE *current = NULL;	/* Pointer to current clique */  SLCLIQUE *previous = NULL;	/* Pointer to previous clique */  int compare_cliques ();/** Loop through all matches* 1/97 te*/  for  (    previous_max = match->max, match->max = 0;    match_distance (match) != EOF;    match->max++  )  {    ecalloc    (      (void **) &current,      1,      sizeof (SLCLIQUE),      "clique link list",      global.outfile    );    copy_clique (&current->clique, &match->clique);    if (match->clique_link != NULL)      previous->next = current;    else      match->clique_link = current;    previous = current;    current = NULL;  }/** Copy cliques over to linear array and sort them* 1/97 te*/  if (match->clique_sort_total < match->max)  {    free_clique_list (match);    match->clique_sort_total = match->max;    ecalloc    (      (void **) &match->clique_sort,      match->clique_sort_total,      sizeof (CLIQUE),      "clique sort list",      global.outfile    );  }  for  (    i = 0, current = match->clique_link;    (i < match->max) && (current != NULL);    i++, current = current->next  )    copy_clique (&match->clique_sort[i], &current->clique);  if (i != match->max)    exit (fprintf (global.outfile,      "ERROR compute_matches: Insufficient cliques copied\n"));  qsort  (    match->clique_sort,    match->max,    sizeof (CLIQUE),    compare_cliques  );  free_clique_link (match);/** Check if sufficient matches were made* 1/97 te*/  if  (    (match->cycle >= 10) &&    ((match->max == 0) ||    (match->max <= previous_max))  )    return EOF;  else    return TRUE;}/* //////////////////////////////////////////////////////////////////// */void free_clique_list (MATCH *match){  int i;  for (i = 0; i < match->clique_sort_total; i++)    free_clique (&match->clique_sort[i]);  efree ((void **) &match->clique_sort);  match->clique_sort_total = 0;}/* //////////////////////////////////////////////////////////////////// */void free_clique_link (MATCH *match){  SLCLIQUE *current = NULL;	/* Pointer to current clique */  SLCLIQUE *previous = NULL;	/* Pointer to previous clique *//** Free up linked list* 3/97 te*/  for  (    previous = match->clique_link;    previous != NULL;    previous = current  )  {    current = previous->next;    free_clique (&previous->clique);    efree ((void **) &previous);  }  match->clique_link = NULL;}int compare_cliques(  CLIQUE *pta,  CLIQUE *ptb){  return (pta->residual == ptb->residual) ? 0 :    ((pta->residual > ptb->residual) ? 1 : -1);}/* ////////////////////////////////////////////////////////////// Routine to generate ligand orientations by finding subsets ofligand atoms to superimpose on receptor site points.1.  At start, no nodes are in clique, and all nodes are available    in clique adjacency list.2.  Successive nodes are taken from the initial clique adjacency list    to seed the clique.3.  A new adjacency list is formed by the intersection of the previous    adjacency list and the new node adjacency list.4.  The clique is grown in a depth-first fashion until no more nodes    are available in the adjacency list.  If the clique is large enough,    it is returned as a match.5.  Backtracking is implemented by successively removing nodes from    the clique to try alternative nodes from the previous adjacency list.6.  When backtracking has exhausted all nodes in the clique and all    nodes in the initial clique adjacency list, then matching terminates.Return values:	TRUE:	suitable match found	EOF:	no more matches can be formed11/96 te////////////////////////////////////////////////////////////// */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?