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_ObjectMolecule
20 #define _H_ObjectMolecule
21 
22 #include"os_python.h"
23 
24 #include"PyMOLObject.h"
25 #include"AtomInfo.h"
26 #include"Vector.h"
27 #include"Color.h"
28 #include"Symmetry.h"
29 #include"DistSet.h"
30 #include "Executive_pre.h"
31 #include "vla.h"
32 #include "Result.h"
33 
34 #include "Sculpt.h"
35 #include <memory>
36 
37 #ifdef _WEBGL
38 #endif
39 
40 #define cKeywordAll "all"
41 #define cKeywordNone "none"
42 #define cKeywordSame "same"
43 #define cKeywordCenter "center"
44 #define cKeywordOrigin "origin"
45 
46 #define cUndoMask 0xF
47 
48 /*
49  * ObjectMolecule's Bond Path (BP) Record
50  */
51 typedef struct ObjectMoleculeBPRec {
52   int *dist;
53   int *list;
54   int n_atom;
55 } ObjectMoleculeBPRec;
56 
57 struct ObjectMolecule : public CObject {
58 	/* array of pointers to coordinate sets; one set per state */
59   pymol::vla<CoordSet*> CSet;
60 	/* number of coordinate sets */
61   int NCSet = 0;
62   struct CoordSet *CSTmpl = nullptr;      /* template for trajectories, etc. */
63 	/* array of bonds */
64   pymol::vla<BondType> Bond;
65 	/* array of atoms (infos) */
66   pymol::vla<AtomInfoType> AtomInfo;
67 	/* number of atoms and bonds */
68   int NAtom = 0, prevNAtom = 0;
69   int NBond = 0, prevNBond = 0;
70 	/* is this object loaded as a discrete object? if so, number of states */
71   int DiscreteFlag = 0;
72   pymol::vla<int> DiscreteAtmToIdx;
73   pymol::vla<CoordSet*> DiscreteCSet;
74   /* proposed, for storing uniform trajectory data more efficiently:
75      int *UniformAtmToIdx, *UniformIdxToAtm;  */
76   int SeleBase = 0;                 /* for internal usage by  selector & only valid during selection process */
77   CSymmetry *Symmetry = 0;
78   int *Neighbor = 0;
79   float *UndoCoord[cUndoMask + 1] {};
80   int UndoState[cUndoMask + 1] {};
81   int UndoNIndex[cUndoMask + 1] {};
82   int UndoIter = 0;
83   CGO *UnitCellCGO = nullptr;
84   int BondCounter = 0;
85   int AtomCounter = 0;
86   /* not stored */
87   struct CSculpt *Sculpt =  nullptr;
88   int RepVisCacheValid = 0;
89   int RepVisCache = 0;     /* for transient storage during updates */
90 
91 #ifndef _PYMOL_NO_UNDO
92 #endif
93 
94   // for reporting available assembly ids after mmCIF loading - SUBJECT TO CHANGE
95   std::shared_ptr<pymol::cif_file> m_ciffile;
96   const pymol::cif_data * m_cifdata = nullptr;
97 
98   // hetatm and ignore-flag by non-polymer classification
99   bool need_hetatm_classification = false;
100 
101   // methods
102   ObjectMolecule(PyMOLGlobals* G, int discreteFlag);
103   ~ObjectMolecule();
104   bool setNDiscrete(int natom);
105   bool updateAtmToIdx();
106   bool atomHasAnyCoordinates(size_t atm) const;
107 
108   /// Typed version of getObjectState
109   CoordSet* getCoordSet(int state);
110   const CoordSet* getCoordSet(int state) const;
111 
112   // virtual methods
113   void update() override;
114   void render(RenderInfo* info) override;
115   void invalidate(int rep, int level, int state) override;
116   int getNFrame() const override;
117   void describeElement(int index, char* buffer) const override;
118   char* getCaption(char* ch, int len) const override;
119   CSetting **getSettingHandle(int state) override;
120   CObject* clone() const override;
121   CSymmetry const* getSymmetry(int state = 0) const override
122   {
123     return Symmetry;
124   }
125   bool setSymmetry(CSymmetry const& symmetry, int state = 0) override;
126 
127 protected:
128   CObjectState* _getObjectState(int state) override;
129 };
130 
131 /* this is a record that holds information for specific types of Operatations on Molecules, eg. translation/rotation/etc */
132 typedef struct ObjectMoleculeOpRec {
133   unsigned int code;
134   Vector3f v1, v2;
135   int cs1, cs2;
136   int i1, i2, i3, i4, i5, i6, *vc1, *i1VLA, *ii1, *vp1;
137   float f1, f2, *f1VLA, *f2VLA, *ff1;
138   double d[3][3], d1;
139   float *vv1, *vv2;
140   char *charVLA;
141   const char *s1;
142   ObjectMolecule **obj1VLA, *obj3;
143   AtomInfoType *ai, **ai1VLA;
144   PyObject *py_ob1;
145 #ifdef _WEBGL
146 #endif
147   float ttt[16], *mat1;
148   int nvv1, nvv2;
149   int include_static_singletons;
150 } ObjectMoleculeOpRec;
151 
152 typedef struct {
153   float maxAngle;
154   float maxDistAtMaxAngle;
155   float maxDistAtZero;
156   float power_a, power_b;
157   float factor_a, factor_b;     /* 0.5/(maxAngle^power_a), 0.5/(maxAngle^power_b)) */
158   float cone_dangle;
159 } HBondCriteria;
160 
161 typedef struct {
162   int flag[3];
163   float matrix[16];
164 } PDBScale;
165 
166 enum {
167   PDB_VARIANT_DEFAULT = 0,
168   PDB_VARIANT_PQR,
169   PDB_VARIANT_PDBQT,
170   PDB_VARIANT_VDB,      /* VIPERdb */
171 };
172 
173 typedef struct {
174   int variant;
175   int pqr_workarounds;
176   PDBScale scale;
177   int ignore_header_names;
178   int multi_object_status;      /* 0 = unknown, 1 = is multi_object, -1 is not multi_object */
179   int multiplex;
180 
is_pqr_file__anonc0c81aa60408181   inline bool is_pqr_file() const {
182     return variant == PDB_VARIANT_PQR;
183   }
184 } PDBInfoRec;
185 
186 
187 /* these four letter code are left over from an
188    earlier multicharacter constant implementation
189    and should be replaced with something more verbose */
190 
191 #define OMOP_AVRT 2
192 #define OMOP_SFIT 3
193 #define OMOP_COLR 4
194 #define OMOP_VISI 5
195 #define OMOP_TTTF 6
196 #define OMOP_ALTR 7
197 #define OMOP_SUMC 9
198 #define OMOP_VERT 10
199 #define OMOP_SVRT 11
200 #define OMOP_MOME 12
201 #define OMOP_INVA 13
202 #define OMOP_MNMX 15
203 #define OMOP_AlterState 16
204 #define OMOP_Flag 17
205 #define OMOP_LABL 18
206 #if 0
207 #define OMOP_Identify    19
208 #endif
209 #define OMOP_Remove 20
210 #define OMOP_Protect 21
211 #define OMOP_Mask 22
212 #define OMOP_AddHydrogens 23
213 #define OMOP_SetB 24
214 #define OMOP_SaveUndo 25
215 #define OMOP_CountAtoms 26
216 #define OMOP_Cartoon 27
217 #define OMOP_Index 28
218 #define OMOP_PhiPsi 29
219 #define OMOP_SingleStateVertices 30
220 #define OMOP_IdentifyObjects 31
221 #define OMOP_FlagSet 32
222 #define OMOP_FlagClear 33
223 #define OMOP_PrepareFromTemplate 34
224 #define OMOP_SetGeometry 35
225 #define OMOP_CSetSumVertices 36
226 #define OMOP_CSetMoment 37
227 #define OMOP_CSetMinMax 38
228 #define OMOP_CSetIdxGetAndFlag 39
229 #define OMOP_CSetIdxSetFlagged 40
230 #define OMOP_GetObjects 41
231 #define OMOP_CSetMaxDistToPt 42
232 #define OMOP_MaxDistToPt 43
233 #define OMOP_CameraMinMax 44
234 #define OMOP_CSetCameraMinMax 45
235 #define OMOP_GetChains 46
236 #define OMOP_Spectrum 47
237 #if 0
238 #define OMOP_GetBFactors 48
239 #define OMOP_GetOccupancies 49
240 #define OMOP_GetPartialCharges 50
241 #endif
242 #define OMOP_StateVRT 51
243 #define OMOP_CheckVis 52
244 #define OMOP_OnOff 53
245 #define OMOP_Pop 54
246 #define OMOP_FixHydrogens 56
247 #define OMOP_Sort 57
248 #define OMOP_SetAtomicSetting 58
249 #define OMOP_CSetSumSqDistToPt 59
250 #define OMOP_RevalenceFromSource 60
251 #define OMOP_RevalenceByGuessing 61
252 #define OMOP_ReferenceStore 62
253 #define OMOP_ReferenceRecall 63
254 #define OMOP_ReferenceValidate 64
255 #define OMOP_ReferenceSwap 65
256 #define OMOP_RenameAtoms 66
257 
258 
259 typedef struct {
260   ObjectMolecule *trg_obj, *mbl_obj;    /* target and mobile objects */
261   int *trg_vla, *mbl_vla;
262   int n_pair;
263 } ObjMolPairwise;
264 
265 void ObjMolPairwiseInit(ObjMolPairwise * pairwise);
266 void ObjMolPairwisePurge(ObjMolPairwise * pairwise);
267 
268 /**
269  * loop iterators for the ObjectMolecule::Neighbor array
270  *
271  * Arguments: (Neighbor array, const int atom-index, int neighbor-atom-or-bond-index, int used-internally)
272  *
273  * Example:
274  * @verbatim
275    // iterate over neighbors of obj->AtomInfo[at]
276    int neighbor_at, tmp;
277    ITERNEIGHBORATOMS(obj->Neighbor, at, neighbor_at, tmp) {
278      // do something with obj->AtomInfo[neighbor_at]
279    }
280    @endverbatim
281  */
282 #define ITERNEIGHBORATOMS(N, a, n, i) for(i = N[a] + 1; (n = N[i]) > -1; i += 2)
283 #define ITERNEIGHBORBONDS(N, a, b, i) for(i = N[a] + 1; (b = N[i + 1]), N[i] > -1; i += 2)
284 
285 int ObjectMoleculeGetTopNeighbor(PyMOLGlobals * G,
286                                  ObjectMolecule * I, int start, int excluded);
287 
288 int ObjectMoleculeGetNearestAtomIndex(ObjectMolecule * I, const float *point, float cutoff,
289                                       int state, float *dist);
290 int ObjectMoleculeGetNearestBlendedColor(ObjectMolecule * I, const float *point, float cutoff,
291                                          int state, float *dist, float *color,
292                                          int sub_vdw);
293 
294 int *ObjectMoleculeGetPrioritizedOtherIndexList(ObjectMolecule * I, struct CoordSet *cs);
295 int ObjectMoleculeGetPrioritizedOther(const int *other, int a1, int a2, int *double_sided);
296 
297 
298 /* */
299 int ObjectMoleculeAreAtomsBonded2(ObjectMolecule * obj0, int a0, ObjectMolecule * obj1,
300                                   int a1);
301 int ObjectMoleculeIsAtomBondedToName(ObjectMolecule * obj, int a0, const char *name, int);
302 void ObjectMoleculeOpRecInit(ObjectMoleculeOpRec * op);
303 int ObjectMoleculeNewFromPyList(PyMOLGlobals * G, PyObject * list,
304                                 ObjectMolecule ** result);
305 PyObject *ObjectMoleculeAsPyList(ObjectMolecule * I);
306 pymol::Result<> ObjectMoleculeSetStateTitle(ObjectMolecule * I, int state, const char *text);
307 const char *ObjectMoleculeGetStateTitle(ObjectMolecule * I, int state);
308 int ObjectMoleculeCheckFullStateSelection(ObjectMolecule * I, int sele, int state);
309 
310 int ObjectMoleculeSetStateOrder(ObjectMolecule * I, int * order, int len);
311 
312 int ObjectMoleculeAddPseudoatom(ObjectMolecule * I, int sele_index, const char *name,
313                                 const char *resn, const char *resi, const char *chain,
314                                 const char *segi, const char *elem, float vdw,
315                                 int hetatm, float b, float q, const char *label,
316                                 const float *pos, int color, int state, int more, int quiet);
317 
318 int ObjectMoleculeSort(ObjectMolecule * I);
319 ObjectMolecule *ObjectMoleculeCopy(const ObjectMolecule * obj);
320 void ObjectMoleculeCopyNoAlloc(const ObjectMolecule * src, ObjectMolecule * dst);
321 void ObjectMoleculeFixChemistry(ObjectMolecule * I, int sele1, int sele2, int invalidate);
322 
323 ObjectMolecule *ObjectMoleculeLoadTOPFile(PyMOLGlobals * G, ObjectMolecule * obj,
324                                           const char *fname, int frame, int discrete);
325 ObjectMolecule *ObjectMoleculeLoadChemPyModel(PyMOLGlobals * G, ObjectMolecule * I,
326                                               PyObject * model, int frame, int discrete);
327 
328 ObjectMolecule *ObjectMoleculeLoadTRJFile(PyMOLGlobals * G, ObjectMolecule * obj,
329                                           const char *fname, int frame, int interval,
330                                           int average, int start, int stop, int max,
331                                           const char *sele, int image, float *shift, int quiet);
332 
333 ObjectMolecule *ObjectMoleculeLoadRSTFile(PyMOLGlobals * G, ObjectMolecule * obj,
334                                           const char *fname, int frame, int quiet, char mode);
335 
336 ObjectMolecule *ObjectMoleculeLoadCoords(PyMOLGlobals * G, ObjectMolecule * I,
337                                          PyObject * coords, int frame);
338 ObjectMolecule *ObjectMoleculeLoadCoords(PyMOLGlobals * G, ObjectMolecule * I,
339                                          const float * coords, int coords_len, int frame=-1);
340 ObjectMolecule *ObjectMoleculeLoadCoords(PyMOLGlobals * G, const char * name,
341                                          const float * coords, int coords_len, int frame=-1);
342 
343 ObjectMolecule *ObjectMoleculeReadStr(PyMOLGlobals * G, ObjectMolecule * I,
344                                       const char **next_entry,
345                                       cLoadType_t content_format, int frame,
346                                       int discrete, int quiet, int multiplex,
347                                       char *new_name,
348 				      short loadpropertiesall=false, OVLexicon *loadproplex=NULL);
349 
350 ObjectMolecule *ObjectMoleculeReadPDBStr(PyMOLGlobals * G, ObjectMolecule * obj,
351                                          const char *molstr, int frame, int discrete,
352                                          char *pdb_name,
353                                          const char **next_pdb, PDBInfoRec * pdb_info,
354                                          int quiet, int *model_number);
355 
356 int ObjectMoleculeExtendIndices(ObjectMolecule * I, int state);
357 
358 void ObjectMoleculeInvalidateAtomType(ObjectMolecule *I, int state);
359 
360 void ObjectMoleculeRenderSele(ObjectMolecule * I, int curState, int sele, int vis_only SELINDICATORARG);
361 
362 void ObjectMoleculeSeleOp(ObjectMolecule * I, int sele, ObjectMoleculeOpRec * op);
363 
364 int ObjectMoleculeMerge(ObjectMolecule * I, pymol::vla<AtomInfoType>&& ai,
365 			struct CoordSet *cs, int bondSearchFlag,
366 			int aic_mask, int invalidate);
367 void ObjectMoleculeUpdateNonbonded(ObjectMolecule * I);
368 int ObjectMoleculeUpdateNeighbors(ObjectMolecule * I);
369 int ObjectMoleculeMoveAtom(ObjectMolecule * I, int state, int index, const float *v, int mode,
370                            int log);
371 int ObjectMoleculeMoveAtomLabel(ObjectMolecule * I, int state, int index, float *v, int log, float *diff);
372 int ObjectMoleculeGetAtomVertex(ObjectMolecule * I, int state, int index, float *v);
373 int ObjectMoleculeGetAtomTxfVertex(ObjectMolecule * I, int state, int index, float *v);
374 int ObjectMoleculeGetAtomIndex(ObjectMolecule * I, int sele);
375 int ObjectMoleculeTransformSelection(ObjectMolecule * I, int state,
376                                      int sele, const float *TTT, int log,
377                                      const char *sname, int homogenous, int global);
378 int ObjectMoleculeDoesAtomNeighborSele(ObjectMolecule * I, int index, int sele);
379 void ObjectMoleculeInferChemFromNeighGeom(ObjectMolecule * I, int state);
380 void ObjectMoleculeInferChemForProtein(ObjectMolecule * I, int state);
381 void ObjectMoleculeInferChemFromBonds(ObjectMolecule * I, int state);
382 void ObjectMoleculePurge(ObjectMolecule * I);
383 
384 int ObjectMoleculeXferValences(ObjectMolecule * Ia, int sele1, int sele2,
385                                int target_state, ObjectMolecule * Ib, int sele3,
386                                int source_state, int quiet);
387 void ObjectMoleculeGuessValences(ObjectMolecule * I, int state, int *flag1, int *flag2,
388                                  int reset);
389 int ObjectMoleculeAddBond(ObjectMolecule * I, int sele0, int sele1, int order);
390 pymol::Result<> ObjectMoleculeAddBondByIndices(
391     ObjectMolecule* I, unsigned atm1, unsigned atm2, int order);
392 int ObjectMoleculeRemoveBonds(ObjectMolecule * I, int sele1, int sele2);
393 
394 int ObjectMoleculeAutoDisableAtomNameWildcard(ObjectMolecule * I);
395 
396 void ObjectMoleculeSaveUndo(ObjectMolecule * I, int state, int log);
397 void ObjectMoleculeUndo(ObjectMolecule * I, int dir);
398 int ObjectMoleculePrepareAtom(ObjectMolecule * I, int index, AtomInfoType * ai, bool uniquefy=true);
399 void ObjectMoleculeReplaceAtom(ObjectMolecule * I, int index, AtomInfoType&& ai);
400 int ObjectMoleculePreposReplAtom(ObjectMolecule * I, int index, AtomInfoType * ai);
401 void ObjectMoleculeCreateSpheroid(ObjectMolecule * I, int average);
402 int ObjectMoleculeSetAtomVertex(ObjectMolecule * I, int state, int index, float *v);
403 int ObjectMoleculeVerifyChemistry(ObjectMolecule * I, int state);
404 int ObjectMoleculeFindOpenValenceVector(ObjectMolecule * I, int state,
405                                         int index, float *v, float *seek,
406                                         int ignore_index);
407 int ObjectMoleculeFillOpenValences(ObjectMolecule * I, int index);
408 int ObjectMoleculeGetTotalAtomValence(ObjectMolecule * I, int atom);
409 int ObjectMoleculeAdjustBonds(ObjectMolecule * I, int sele0, int sele1, int mode,
410                               int order);
411 int ObjectMoleculeAttach(ObjectMolecule * I, int index,
412     pymol::vla<AtomInfoType>&& nai);
413 int ObjectMoleculeFuse(ObjectMolecule * I, int index0, ObjectMolecule * src, int index1,
414                         int mode, int move_flag);
415 int ObjectMoleculeRenameAtoms(ObjectMolecule * I, int *flag, int force);
416 int ObjectMoleculeAreAtomsBonded(ObjectMolecule * I, int i0, int i1);
417 void ObjectGotoState(CObject* I, int state);
418 float ObjectMoleculeGetAvgHBondVector(ObjectMolecule * I, int atom, int state, float *v,
419                                       float *incoming);
420 int ObjectMoleculeCheckBondSep(ObjectMolecule * I, int a0, int a1, int dist);
421 int ObjectMoleculeGetPhiPsi(ObjectMolecule * I, int ca, float *phi, float *psi,
422                             int state);
423 void ObjectMoleculeGetAtomSele(const ObjectMolecule * I, int index, char *buffer);
424 
425 /**
426  * Retrives selection string of an Object Molecule's atom
427  * @param I ObjectMolecule whose info is retrieved
428  * @param index atom index of I whose info is retrieved
429  * @return selection string unique to the atom
430  */
431 std::string ObjectMoleculeGetAtomSeleFast(const ObjectMolecule * I, int index);
432 
433 void ObjectMoleculeGetAtomSeleLog(const ObjectMolecule * I, int index, char *buffer, int quote);
434 
435 void ObjectMoleculeUpdateIDNumbers(ObjectMolecule * I);
436 
437 void ObjectMoleculeSculptImprint(ObjectMolecule * I, int state, int match_state,
438                                  int match_by_segment);
439 float ObjectMoleculeSculptIterate(ObjectMolecule * I, int state, int n_cycle,
440                                   float *center);
441 void ObjectMoleculeSculptClear(ObjectMolecule * I);
442 
443 /* bond paths */
444 int ObjectMoleculeGetBondPaths(ObjectMolecule * I, int atom, int max,
445                                ObjectMoleculeBPRec * bp);
446 int ObjectMoleculeInitBondPath(ObjectMolecule * I, ObjectMoleculeBPRec * bp);
447 int ObjectMoleculePurgeBondPath(ObjectMolecule * I, ObjectMoleculeBPRec * bp);
448 int ***ObjectMoleculeGetBondPrint(ObjectMolecule * I, int max_bond, int max_type,
449                                   int *dim);
450 
451 bool ObjectMoleculeConnect(ObjectMolecule* I, CoordSet* cs,
452     bool searchFlag = true, int connectModeOverride = -1);
453 bool ObjectMoleculeConnect(ObjectMolecule* I, int& nbond, pymol::vla<BondType>& bond,
454                           struct CoordSet *cs, int searchFlag, int connectModeOverride);
455 int ObjectMoleculeSetDiscrete(PyMOLGlobals * G, ObjectMolecule * I, int discrete);
456 
457 float ObjectMoleculeGetMaxVDW(ObjectMolecule * I);
458 int ObjectMoleculeGetCheckHBond(AtomInfoType **h_real,
459                                 float *h_crd_ret,
460                                 ObjectMolecule * don_obj,
461                                 int don_atom,
462                                 int don_state,
463                                 ObjectMolecule * acc_obj,
464                                 int acc_atom, int acc_state, HBondCriteria * hbc);
465 void ObjectMoleculeInitHBondCriteria(PyMOLGlobals * G, HBondCriteria * hbc);
466 int ObjectMoleculeConvertIDsToIndices(ObjectMolecule * I, int *id, int n_id);
467 
468 #define cObjectMoleculeDummyOrigin 1
469 #define cObjectMoleculeDummyCenter 2
470 
471 ObjectMolecule *ObjectMoleculeDummyNew(PyMOLGlobals * G, int mode);
472 void ObjectMoleculeDummyUpdate(ObjectMolecule * I, int mode);
473 
474 void ObjectMoleculeTransformState44f(ObjectMolecule * I, int state, const float *matrix,
475                                      int log_trans, int homogenous, int transformed);
476 
477 
478 /* internal to ObjectMolecule */
479 
480 struct CoordSet *ObjectMoleculePDBStr2CoordSet(PyMOLGlobals * G,
481                                                const char *buffer,
482                                                AtomInfoType ** atInfoPtr,
483                                                const char **restart_model,
484                                                char *segi_override,
485                                                char *pdb_name,
486                                                const char **next_pdb,
487                                                PDBInfoRec * pdb_info,
488                                                int quiet, int *model_number);
489 
490 #ifndef NO_MMLIBS
491 int ObjectMoleculeUpdateAtomTypeInfoForState(PyMOLGlobals * G, ObjectMolecule * obj, int state, int initialize, int format);
492 #endif
493 
494 #ifdef _PYMOL_IP_EXTRAS
495 int ObjectMoleculeUpdateMMStereoInfoForState(PyMOLGlobals * G, ObjectMolecule * obj, int state, int initialize=1);
496 #endif
497 
498 #ifndef _PYMOL_NO_UNDO
499 void ObjectMoleculeSetAtomBondInfoTypeOldId(PyMOLGlobals * G, ObjectMolecule * obj);
500 void ObjectMoleculeSetAtomBondInfoTypeOldIdToNegOne(PyMOLGlobals * G, ObjectMolecule * obj);
501 #endif
502 
503 void ObjectMoleculeAdjustDiscreteAtmIdx(ObjectMolecule *I, int *lookup, int nAtom);
504 
505 void AtomInfoSettingGenerateSideEffects(PyMOLGlobals * G, ObjectMolecule *obj, int index, int id);
506 
507 int *AtomInfoGetSortedIndex(PyMOLGlobals * G,
508     const ObjectMolecule* obj,
509     const AtomInfoType* rec, int n,
510                             int **outdex);
511 
512 ObjectMolecule *ObjectMoleculeReadMmtfStr(PyMOLGlobals * G, ObjectMolecule * I,
513     const char *st, int st_len, int frame, int discrete, int quiet, int multiplex, int zoom);
514 ObjectMolecule *ObjectMoleculeReadCifStr(PyMOLGlobals * G, ObjectMolecule * I,
515     const char *st, int frame, int discrete, int quiet, int multiplex, int zoom);
516 
517 // object and object-state level setting
518 template <typename V> void SettingSet(int index, V value, ObjectMolecule * I, int state=-1) {
519   SettingSet(index, value, (CObject*)I, state);
520 }
521 
522 std::unique_ptr<int[]> LoadTrajSeleHelper(
523     const ObjectMolecule* obj, CoordSet* cs, const char* selection);
524 
525 int ObjectMoleculeSetGeometry(PyMOLGlobals* G, ObjectMolecule* I, int sele, int geom, int valence);
526 #endif
527