1 /**
2  * @file
3  */
4 /*
5 A* -------------------------------------------------------------------
6 B* This file contains source code for the PyMOL computer program
7 C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
8 D* -------------------------------------------------------------------
9 E* It is unlawful to modify or remove this copyright notice.
10 F* -------------------------------------------------------------------
11 G* Please see the accompanying LICENSE file for further information.
12 H* -------------------------------------------------------------------
13 I* Additional authors of this source file include:
14 -*
15 -*
16 -*
17 Z* -------------------------------------------------------------------
18 */
19 #ifndef _H_AtomInfo
20 #define _H_AtomInfo
21 
22 #include"Rep.h"
23 #include"Setting.h"
24 #include"Version.h"
25 
26 #if _PyMOL_VERSION_int < 1770
27 #define AtomInfoVERSION  176
28 #define BondInfoVERSION  176
29 #elif _PyMOL_VERSION_int < 1810
30 #define AtomInfoVERSION  177
31 #define BondInfoVERSION  177
32 #else
33 #define AtomInfoVERSION  181
34 #define BondInfoVERSION  181
35 #endif
36 
37 /* FLAGS 0-3 have the following conventional usage for molecular modeling */
38 
39 
40 /* FLAG 0 - Atoms of interest - i.e. a ligand in an active site */
41 #define cAtomFlag_focus         0x00000001
42 
43 
44 /* FLAG 1 - Free atoms - those which can move subject to a force-field */
45 #define cAtomFlag_free          0x00000002
46 
47 
48 /* FLAG 2 - Restrained atoms - atoms subject to a harmonic restraint */
49 #define cAtomFlag_restrain      0x00000004
50 
51 
52 /* FLAG 3 - Fixed atoms - no movement allowed */
53 #define cAtomFlag_fix           0x00000008
54 
55 
56 /* FLAG 4 - Exclude these atoms when performing simulation, minimization */
57 #define cAtomFlag_exclude       0x00000010
58 
59 
60 /* FLAG 5 - Study atoms  */
61 #define cAtomFlag_study         0x00000020
62 
63 
64 /* FLAGS 6-7 are for polymer sub-classification */
65 #define cAtomFlag_protein       0x00000040
66 #define cAtomFlag_nucleic       0x00000080
67 
68 
69 /* FLAGS 8-15 are free for end users to manipulate */
70 
71 
72 /* FLAGS 16-21 are reserved for external GUIs and linked applications */
73 
74 
75 /* FLAGS 22-23 are for temporary use only (inside of self-contained loops) */
76 
77 
78 /* FLAGS 24-31 are reserved for PyMOL's internal use */
79 
80 
81 /* FLAG 24 - don't surface these atoms (waters, ligands, etc.) */
82 #define cAtomFlag_exfoliate     0x01000000
83 
84 
85 /* FLAG 25 - ignore atoms altogether when surfacing */
86 #define cAtomFlag_ignore        0x02000000
87 
88 
89 /* FLAG 26 - disable cartoon smoothing for these atoms */
90 #define cAtomFlag_no_smooth     0x04000000
91 
92 
93 /* FLAG 27 - polymer */
94 #define cAtomFlag_polymer       0x08000000
95 
96 /* FLAG 28 - waters */
97 #define cAtomFlag_solvent       0x10000000
98 
99 /* FLAG 29 - organics */
100 #define cAtomFlag_organic       0x20000000
101 
102 /* FLAG 30 - inorganics */
103 #define cAtomFlag_inorganic     0x40000000
104 
105 
106 /* FLAG 31 - guide atom: e.g. CA in proteins */
107 #define cAtomFlag_guide         0x80000000
108 
109 #define cAtomFlag_class         0xF8000000
110 #define cAtomFlag_class_mask    0x07FFFFFF
111 
112 #define cResnLen 5
113 #define cResiLen 5
114 #define cAtomNameLen 4
115 #define cElemNameLen 4
116 #define cSegiLen 4
117 #define cTextTypeLen 20
118 #define cLabelTypeLen 20
119 
120 #define cAtomInfoTetrahedral 4
121 #define cAtomInfoPlanar 3
122 #define cAtomInfoLinear 2
123 #define cAtomInfoSingle 1
124 #define cAtomInfoNone 5
125 
126 #define cAN_LP  0
127 #define cAN_H   1
128 #define cAN_He  2
129 #define cAN_Li  3
130 #define cAN_Be  4
131 #define cAN_B   5
132 #define cAN_C   6
133 #define cAN_N   7
134 #define cAN_O   8
135 #define cAN_F   9
136 #define cAN_Ne 10
137 #define cAN_Na 11
138 #define cAN_Mg 12
139 #define cAN_Al 13
140 #define cAN_Si 14
141 #define cAN_P  15
142 #define cAN_S  16
143 #define cAN_Cl 17
144 #define cAN_Ar 18
145 #define cAN_K  19
146 #define cAN_Ca 20
147 
148 #define cAN_Ti 22
149 #define cAN_V  23
150 
151 #define cAN_Cr 24
152 #define cAN_Mn 25
153 #define cAN_Fe 26
154 #define cAN_Co 27
155 #define cAN_Ni 28
156 #define cAN_Cu 29
157 #define cAN_Zn 30
158 #define cAN_Ga 31
159 #define cAN_Ge 32
160 #define cAN_As 33
161 #define cAN_Se 34
162 #define cAN_Br 35
163 #define cAN_Kr 36
164 
165 #define cAN_Rb 37
166 #define cAN_Sr 38
167 #define cAN_Y  39
168 
169 #define cAN_Pd 46
170 #define cAN_Ag 47
171 #define cAN_Cd 48
172 #define cAN_In 49
173 #define cAN_Sn 50
174 #define cAN_Sb 51
175 #define cAN_Te 52
176 #define cAN_I  53
177 #define cAN_Xe 54
178 #define cAN_Cs 55
179 #define cAN_Ba 56
180 
181 #define cAN_Ce 58
182 
183 #define cAN_Pt 78
184 #define cAN_Au 79
185 #define cAN_Hg 80
186 #define cAN_Tl 81
187 #define cAN_Pb 82
188 
189 #define cAN_U  92
190 
191 #define SDF_CHIRALITY_ODD    1          // odd  / clockwise
192 #define SDF_CHIRALITY_EVEN   2          // even / counterclockwise
193 #define SDF_CHIRALITY_EITHER 3          // either or unmarked
194 
195 typedef char Chain[2];
196 typedef char SSType[2];
197 typedef char SegIdent[cSegiLen + 1];
198 typedef char ResIdent[cResiLen + 1];
199 typedef char ResName[cResnLen + 1];
200 typedef char AtomName[cAtomNameLen + 1];
201 
202 typedef char ElemName[cElemNameLen + 1];
203 
204 // for customType (not geom)
205 #define cAtomInfoNoType -9999
206 
makeInscode(char c)207 inline char makeInscode(char c) {
208   return (c <= ' ') ? '\0' : c;
209 }
210 
211 struct ElementTableItemType {
212   const char * name;
213   const char * symbol;
214   float vdw;
215   float weight;
216 };
217 
218 extern const ElementTableItemType ElementTable[];
219 extern const int ElementTableSize;
220 
221 typedef struct BondType {
222   int index[2];
223   int id;
224   int unique_id;
225 #ifdef _PYMOL_IP_EXTRAS
226   int oldid;
227 #endif
228   signed char order;    // 0-4
229   signed char temp1;    // bool? where used?
230   signed char stereo;   // 0-6 Only for SDF (MOL) format in/out
231   bool has_setting;     /* setting based on unique_id */
232 } BondType;
233 
234 typedef struct AtomInfoType {
235   float * anisou;               // only allocate with get_anisou
236 
237   lexidx_t segi;
238   lexidx_t chain;
239   lexidx_t resn;
240   lexidx_t name;
241   lexidx_t textType;
242   lexidx_t custom;
243   lexidx_t label;
244 
245   int resv;
246   int customType;
247   int priority;
248   float b, q, vdw, partialCharge;
249   int selEntry;
250   int color;
251   int id;                       // PDB ID
252   unsigned int flags;
253   int temp1;                    /* kludge fields - to remove */
254   int unique_id;                /* introduced in version 0.77 */
255   int discrete_state;           /* state+1 for atoms in discrete objects */
256   float elec_radius;            /* radius for PB calculations */
257   int rank;
258   int visRep;                   /* bitmask for all reps */
259 #ifdef _PYMOL_IP_EXTRAS
260   int oldid;                    // for undo
261   int prop_id;
262 #endif
263 
264   // boolean flags
265   bool hetatm : 1;
266   bool bonded : 1;
267   bool deleteFlag : 1;
268   bool masked : 1;
269   bool hb_donor : 1;
270   bool hb_acceptor : 1;
271   bool has_setting : 1;      /* setting based on unique_id */
272 
273   /* be careful not to write at these as (int*) */
274 
275   signed char formalCharge;     // values typically in range -2..+2
276   signed char cartoon;          /* 0 = default which is auto (use ssType) */
277   signed char geom;             // cAtomInfo*
278   signed char valence;          // 0-4
279   signed char protons;          /* atomic number */
280 
281   char inscode;
282 
283   ElemName elem;               // redundant with "protons" ?
284   SSType ssType;               /* blank or 'L' = turn/loop, 'H' = helix, 'S' = beta-strand/sheet */
285   Chain alt;
286 
287   // small value optimized bitfields
288   unsigned char stereo : 2;     // 0-3 Only for SDF (MOL) format in/out
289   unsigned char chemFlag : 2;   // 0,1,2
290   unsigned char protekted : 2;  // 0,1,2
291   unsigned char mmstereo : 2;   // 0/R/S/?
292 
293   // methods
isHydrogenAtomInfoType294   bool isHydrogen() const {
295     return protons == cAN_H;
296   }
297 
isMetalAtomInfoType298   bool isMetal() const {
299     return (
300         (protons >  2 && protons <  5) ||
301         (protons > 10 && protons < 14) ||
302         (protons > 18 && protons < 32) ||
303         (protons > 36 && protons < 51) ||
304         (protons > 54 && protons < 85) ||
305         protons > 86);
306   }
307 
308   char getInscode(bool space=false) const {
309     if (space && !inscode)
310       return ' ';
311     return inscode;
312   }
313 
setInscodeAtomInfoType314   void setInscode(char c) {
315     inscode = makeInscode(c);
316   }
317 
setResiAtomInfoType318   void setResi(const char * resi) {
319     if (sscanf(resi, "%d%c", &resv, &inscode) == 1 || inscode <= ' ')
320       inscode = '\0';
321   }
322 
323   // for AtomInfoHistory
setResiAtomInfoType324   void setResi(int resv_, char inscode_) {
325     resv = resv_;
326     setInscode(inscode_);
327   }
328 
329   /*
330    * Return true if any representation, which is displayable by this
331    * atom, is shown
332    */
isVisibleAtomInfoType333   bool isVisible() const {
334     if(visRep & (
335           // point reps
336           cRepSphereBit | cRepEllipsoidBit | cRepLabelBit |
337           // surface reps
338           cRepSurfaceBit | cRepDotBit | cRepMeshBit |
339           // polymer reps (actually only shown for guide atoms or if
340           // *_trace_atoms=1 or cartoon_ring_finder=4)
341           cRepCartoonBit | cRepRibbonBit)) {
342       return true;
343     } else if(bonded) {
344       // bond reps
345       if (visRep & (cRepCylBit | cRepLineBit))
346         return true;
347     } else {
348       // nonbonded reps
349       if (visRep & (cRepNonbondedSphereBit | cRepNonbondedBit))
350         return true;
351     }
352     return false;
353   }
354 
355   // get the anisou array, allocate if null
get_anisouAtomInfoType356   float * get_anisou() { return (anisou ? anisou : (anisou = new float[6])); }
357 
358   // read-only anisou access, no allocation
get_anisouAtomInfoType359   const float * get_anisou() const { return anisou; }
has_anisouAtomInfoType360   bool has_anisou() const { return anisou; }
361 } AtomInfoType;
362 
363 void AtomInfoFree(PyMOLGlobals * G);
364 int AtomInfoInit(PyMOLGlobals * G);
365 void BondTypeInit(BondType *bt);
366 void BondTypeInit2(BondType *bt, int i1, int i2, int order = 1);
367 void AtomInfoPurge(PyMOLGlobals * G, AtomInfoType * ai);
368 void AtomInfoCopy(PyMOLGlobals * G, const AtomInfoType * src, AtomInfoType * dst, int copy_properties=true);
369 int AtomInfoReserveUniqueID(PyMOLGlobals * G, int unique_id);
370 int AtomInfoIsUniqueIDActive(PyMOLGlobals * G, int unique_id);
371 int AtomInfoGetNewUniqueID(PyMOLGlobals * G);
372 void AtomInfoCleanAtomName(char *name);
373 
374 #ifndef _PYMOL_NOPY
375 int AtomInfoSetSettingFromPyObject(PyMOLGlobals * G, AtomInfoType *ai, int setting_id, PyObject *val);
376 #endif
377 PyObject *SettingGetIfDefinedPyObject(PyMOLGlobals * G, AtomInfoType * ai, int setting_id);
378 
379 void AtomInfoBondCopy(PyMOLGlobals * G, const BondType * src, BondType * dst);
380 
381 int AtomInfoCheckUniqueID(PyMOLGlobals * G, AtomInfoType * ai);
382 void AtomInfoAssignParameters(PyMOLGlobals * G, AtomInfoType * I);
383 void AtomInfoFreeSortedIndexes(PyMOLGlobals * G, int **index, int **outdex);
384 void AtomInfoPrimeColors(PyMOLGlobals * G);
385 void AtomInfoAssignColors(PyMOLGlobals * G, AtomInfoType * at1);
386 int AtomInfoGetColor(PyMOLGlobals * G, const AtomInfoType * at1);
387 int AtomInfoGetExpectedValence(PyMOLGlobals * G, const AtomInfoType * I);
388 int AtomInfoIsFreeCation(PyMOLGlobals * G, const AtomInfoType * I);
389 PyObject *AtomInfoAsPyList(PyMOLGlobals * G, const AtomInfoType * at);
390 int AtomInfoFromPyList(PyMOLGlobals * G, AtomInfoType * at, PyObject * list);
391 
392 int AtomInfoMatch(PyMOLGlobals * G, const AtomInfoType * at1, const AtomInfoType * at2, bool, bool);
393 int AtomInfoCompareAll(PyMOLGlobals * G, const AtomInfoType * at1, const AtomInfoType * at2);
394 int AtomInfoCompare(PyMOLGlobals * G, const AtomInfoType * at1, const AtomInfoType * at2);
395 int AtomInfoCompareIgnoreRank(PyMOLGlobals * G, const AtomInfoType * at1, const AtomInfoType * at2);
396 int AtomInfoCompareIgnoreHet(PyMOLGlobals * G, const AtomInfoType * at1, const AtomInfoType * at2);
397 int AtomInfoCompareIgnoreRankHet(PyMOLGlobals * G, const AtomInfoType * at1,
398                                  const AtomInfoType * at2);
399 float AtomInfoGetBondLength(PyMOLGlobals * G, const AtomInfoType * ai1, const AtomInfoType * ai2);
400 int AtomInfoSameResidue(PyMOLGlobals * G, const AtomInfoType * at1, const AtomInfoType * at2);
401 int AtomInfoSameResidueP(PyMOLGlobals * G, const AtomInfoType * at1, const AtomInfoType * at2);
402 int AtomInfoSameChainP(PyMOLGlobals * G, const AtomInfoType * at1, const AtomInfoType * at2);
403 int AtomInfoSameSegmentP(PyMOLGlobals * G, const AtomInfoType * at1, const AtomInfoType * at2);
404 int AtomInfoSequential(PyMOLGlobals * G, const AtomInfoType * at1, const AtomInfoType * at2,
405                        int mode);
406 
407 #define AtomInfoCheckUniqueBondID AtomInfoCheckUniqueID
408 int AtomInfoCheckUniqueBondID(PyMOLGlobals * G, BondType * bi);
409 void AtomInfoPurgeBond(PyMOLGlobals * G, BondType * bi);
410 
411 void AtomInfoBracketResidue(PyMOLGlobals * G, const AtomInfoType * ai0, int n0,
412                             const AtomInfoType * ai, int *st, int *nd);
413 void AtomInfoBracketResidueFast(PyMOLGlobals * G, const AtomInfoType * ai0, int n0, int cur,
414                                 int *st, int *nd);
415 
416 int AtomInfoUniquefyNames(PyMOLGlobals * G, const AtomInfoType * atInfo0, int n0,
417                           AtomInfoType * atInfo1, int *flag1, int n1,
418                           const ObjectMolecule* mol = nullptr);
419 int AtomInfoUniquefyNames(
420     const ObjectMolecule* mol, AtomInfoType* atoms, size_t natoms);
421 
422 bool AtomResiFromResv(char *resi, size_t size, int resv, char inscode);
AtomResiFromResv(char * resi,size_t size,const AtomInfoType * ai)423 inline bool AtomResiFromResv(char *resi, size_t size, const AtomInfoType * ai) {
424   return AtomResiFromResv(resi, size, ai->resv, ai->inscode);
425 }
426 
427 int AtomInfoKnownWaterResName(PyMOLGlobals * G, const char *resn);
428 int AtomInfoKnownPolymerResName(const char *resn);
429 int AtomInfoKnownProteinResName(const char *resn);
430 int AtomInfoKnownNucleicResName(const char *resn);
431 void AtomInfoGetPDB3LetHydroName(PyMOLGlobals * G, const char *resn, const char *iname, char *oname);
432 
433 #define cAIC_ct        0x0001
434 #define cAIC_fc        0x0002
435 #define cAIC_pc        0x0004
436 #define cAIC_b         0x0008
437 #define cAIC_q         0x0010
438 #define cAIC_id        0x0020
439 #define cAIC_flags     0x0080
440 #define cAIC_tt        0x0100
441 #define cAIC_state     0x0200
442 #define cAIC_rank      0x0400
443 #define cAIC_custom    0x0800
444 
445 #define cAIC_IDMask (cAIC_id|cAIC_rank)
446 #define cAIC_PDBMask (cAIC_b|cAIC_q|cAIC_id|cAIC_rank)
447 #define cAIC_MMDMask (cAIC_pc|cAIC_ct|cAIC_id|cAIC_rank)
448 #define cAIC_MOLMask (cAIC_fc|cAIC_id|cAIC_rank)
449 #define cAIC_AllMask 0xFFFF
450 
451 void AtomInfoCombine(PyMOLGlobals * G, AtomInfoType * dst, AtomInfoType&& src, int mask);
452 int AtomInfoNameOrder(PyMOLGlobals * G, const AtomInfoType * at1, const AtomInfoType * at2);
453 int AtomInfoUpdateAutoColor(PyMOLGlobals * G);
454 
455 typedef struct {
456   int resv1, resv2;
457   char inscode1, inscode2;
458   unsigned char chain1, chain2;
459   unsigned char type;
460   int next;
461 } SSEntry;
462 
463 int BondTypeCompare(PyMOLGlobals * G, const BondType * bt1, const BondType * bt2);
464 
465 void atomicnumber2elem(char * dst, int protons);
466 
467 /*
468  * atom-level and bond-level settings
469  */
470 
471 template <typename T>
AtomInfoCheckSetting(PyMOLGlobals * G,T * item,int index)472 int AtomInfoCheckSetting(PyMOLGlobals * G, T * item, int index) {
473   return (item->has_setting && SettingUniqueCheck(G, item->unique_id, index));
474 }
475 
476 #define AtomInfoCheckBondSetting AtomInfoCheckSetting
477 
SettingSet(PyMOLGlobals * G,int index,V value,T * ai)478 template <typename V, typename T> void SettingSet(PyMOLGlobals * G, int index, V value, T * ai) {
479   AtomInfoCheckUniqueID(G, ai);
480   ai->has_setting = true;
481   SettingUniqueSet(G, ai->unique_id, index, value);
482 }
483 
484 /**
485  * Return true if `item` has the requested setting defined and the
486  * value could be assigned to `out`.
487  */
488 template <typename V, typename T>
AtomSettingGetIfDefined(PyMOLGlobals * G,T * item,int index,V * out)489 bool AtomSettingGetIfDefined(PyMOLGlobals * G, T * item, int index, V * out) {
490   return item->has_setting &&
491     SettingUniqueGetIfDefined<V>(G, item->unique_id, index, out);
492 }
493 
494 /**
495  * Return the `item`-level setting value or `default_`, if `index` is not
496  * defined for `item`.
497  */
498 template <typename V, typename T>
AtomSettingGetWD(PyMOLGlobals * G,T * item,int index,V default_)499 V AtomSettingGetWD(PyMOLGlobals * G, T * item, int index, V default_) {
500   V out;
501   if (AtomSettingGetIfDefined<V, T>(G, item, index, &out))
502     return out;
503   return default_;
504 }
505 
506 #define BondSettingGetWD AtomSettingGetWD
507 
508 // stereochemistry
509 const char * AtomInfoGetStereoAsStr(const AtomInfoType * ai);
510 void AtomInfoSetStereo(AtomInfoType * ai, const char * stereo);
511 
512 
513 void AtomInfoGetAlignedPDBResidueName(PyMOLGlobals * G,
514     const AtomInfoType * ai,
515     ResName & resn);
516 void AtomInfoGetAlignedPDBAtomName(PyMOLGlobals * G,
517     const AtomInfoType * ai,
518     const ResName & resn,
519     AtomName & name);
520 
521 #endif
522