mirror of
https://github.com/schrodinger/pymol-open-source.git
synced 2026-06-03 19:54:24 +08:00
- Use proper doxygen syntax for all function comments - ObjectMoleculeUpdateNeighbors allow const argument - Remove obsolete ObjectMolecule::BondCounter
163 lines
4.9 KiB
C++
163 lines
4.9 KiB
C++
/*
|
|
* This file contains source code for the PyMOL computer program
|
|
* Copyright (c) Schrodinger, LLC.
|
|
*/
|
|
|
|
#include <algorithm>
|
|
|
|
#include "os_std.h"
|
|
|
|
#include "SideChainHelper.h"
|
|
#include "Lex.h"
|
|
|
|
/**
|
|
* Mark side_chain_helper atoms that are bonded to atoms without a visible
|
|
* cartoon or ribbon
|
|
*/
|
|
void SideChainHelperMarkNonCartoonBonded(bool * marked,
|
|
const ObjectMolecule * obj,
|
|
const CoordSet * cs,
|
|
bool cartoon_side_chain_helper,
|
|
bool ribbon_side_chain_helper)
|
|
{
|
|
auto G = obj->G;
|
|
|
|
auto b = obj->Bond.data();
|
|
auto b_end = b + obj->NBond;
|
|
|
|
for(; b < b_end; ++b) {
|
|
auto b1 = b->index[0];
|
|
auto b2 = b->index[1];
|
|
|
|
auto a1 = cs->atmToIdx(b1);
|
|
auto a2 = cs->atmToIdx(b2);
|
|
|
|
if (a1 < 0 || a2 < 0)
|
|
continue;
|
|
|
|
auto ati1 = obj->AtomInfo + b1;
|
|
auto ati2 = obj->AtomInfo + b2;
|
|
|
|
if (!(ati1->flags & ati2->flags & cAtomFlag_polymer))
|
|
continue;
|
|
|
|
if (!marked[b1]) {
|
|
marked[b1] =
|
|
((ati1->visRep & cRepCartoonBit) && !(ati2->visRep & cRepCartoonBit) &&
|
|
AtomSettingGetWD(G, ati1, cSetting_cartoon_side_chain_helper, cartoon_side_chain_helper)) ||
|
|
((ati1->visRep & cRepRibbonBit) && !(ati2->visRep & cRepRibbonBit) &&
|
|
AtomSettingGetWD(G, ati1, cSetting_ribbon_side_chain_helper, ribbon_side_chain_helper));
|
|
}
|
|
|
|
if (!marked[b2]) {
|
|
marked[b2] =
|
|
((ati2->visRep & cRepCartoonBit) && !(ati1->visRep & cRepCartoonBit) &&
|
|
AtomSettingGetWD(G, ati2, cSetting_cartoon_side_chain_helper, cartoon_side_chain_helper)) ||
|
|
((ati2->visRep & cRepRibbonBit) && !(ati1->visRep & cRepRibbonBit) &&
|
|
AtomSettingGetWD(G, ati2, cSetting_ribbon_side_chain_helper, ribbon_side_chain_helper));
|
|
}
|
|
}
|
|
}
|
|
|
|
// matches c0[35][*']
|
|
inline bool is_35prime(const char * p, char c0) {
|
|
return p[0] == c0 &&
|
|
(p[1] == '3' || p[1] == '5') &&
|
|
(p[2] == '*' || p[2] == '\'') && !p[3];
|
|
}
|
|
|
|
// matches C[45][*']
|
|
inline bool is_C45prime(const char * p) {
|
|
return p[0] == 'C' &&
|
|
(p[1] == '4' || p[1] == '5') &&
|
|
(p[2] == '*' || p[2] == '\'') && !p[3];
|
|
}
|
|
|
|
/**
|
|
* Return true if bond is hidden with side_chain_helper.
|
|
* c1/c2 are in-out variables for color transfer.
|
|
*/
|
|
bool SideChainHelperFilterBond(PyMOLGlobals * G,
|
|
const bool *marked,
|
|
const AtomInfoType *ati1,
|
|
const AtomInfoType *ati2,
|
|
int b1, int b2, int na_mode, int *c1, int *c2)
|
|
{
|
|
if (ati1->protons == cAN_H ||
|
|
ati2->protons == cAN_N ||
|
|
ati2->protons == cAN_O ||
|
|
(ati1->protons == cAN_C && ati2->protons == cAN_C && ati2->name == G->lex_const.CA)
|
|
) {
|
|
std::swap(ati1, ati2);
|
|
std::swap(b1, b2);
|
|
std::swap(c1, c2);
|
|
}
|
|
|
|
const char *name1 = LexStr(G, ati1->name);
|
|
int prot1 = ati1->protons;
|
|
const char *name2 = LexStr(G, ati2->name);
|
|
int prot2 = ati2->protons;
|
|
|
|
switch (prot1) {
|
|
case cAN_C:
|
|
if (ati1->name == G->lex_const.CA) { /* CA */
|
|
if(prot2 == cAN_C) {
|
|
if(ati2->name == G->lex_const.CB)
|
|
*c1 = *c2; /* CA-CB */
|
|
else if(ati2->name == G->lex_const.C && (!marked[b2]))
|
|
return true; /* suppress CA-C */
|
|
} else if(prot2 == cAN_H)
|
|
return true; /* suppress all CA-hydrogens */
|
|
} else if((na_mode == 1) && (prot2 == cAN_C)) {
|
|
if (is_C45prime(name2) && is_C45prime(name1))
|
|
/* supress C[45][*']-C[45][*'] */
|
|
return true;
|
|
}
|
|
break;
|
|
case cAN_N:
|
|
if (ati1->name == G->lex_const.N) { /* N */
|
|
if(prot2 == cAN_C) {
|
|
if (ati2->name == G->lex_const.CD)
|
|
*c1 = *c2; /* N->CD in PRO */
|
|
else if (ati2->name == G->lex_const.CA
|
|
&& (!marked[b1])) {
|
|
if(ati2->resn != G->lex_const.PRO)
|
|
return true; /* suppress N-CA, except in pro */
|
|
*c1 = *c2;
|
|
} else if (ati2->name == G->lex_const.C && (!marked[b1]))
|
|
return true; /* suppress N-C */
|
|
} else if(prot2 == cAN_H)
|
|
return true; /* suppress all N-hydrogens */
|
|
}
|
|
break;
|
|
case cAN_O:
|
|
if(prot2 == cAN_C) {
|
|
if ( ati2->name == G->lex_const.C &&
|
|
(ati1->name == G->lex_const.O ||
|
|
ati1->name == G->lex_const.OXT)
|
|
&& (!marked[b2]))
|
|
return true; /* suppress C-O,OXT */
|
|
else if(na_mode == 1) {
|
|
if (is_35prime(name2, 'C') && is_35prime(name1, 'O'))
|
|
/* supress O[35][*']-C[35][*'] */
|
|
return true;
|
|
}
|
|
} else if(prot2 == cAN_P) {
|
|
if (ati2->name == G->lex_const.P &&
|
|
strlen(name1) == 3 && name1[0] == 'O' && (
|
|
(name1[2] == 'P' && name1[1] >= '1' && name1[1] <= '3') ||
|
|
(name1[1] == 'P' && name1[2] >= '1' && name1[2] <= '3')))
|
|
/* suppress P-O([123]P|P[123]) */
|
|
return true;
|
|
else if(na_mode == 1) {
|
|
if (ati2->name == G->lex_const.P && is_35prime(name1, 'O'))
|
|
/* supress P-O[35][*'] */
|
|
return true;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|