1
2 /*
3 A* -------------------------------------------------------------------
4 B* This file contains source code for the PyMOL computer program
5 C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
6 D* -------------------------------------------------------------------
7 E* It is unlawful to modify or remove this copyright notice.
8 F* -------------------------------------------------------------------
9 G* Please see the accompanying LICENSE file for further information.
10 H* -------------------------------------------------------------------
11 I* Additional authors of this source file include:
12 -*
13 -*
14 -*
15 Z* -------------------------------------------------------------------
16 */
17 #include"os_python.h"
18
19 #include"os_predef.h"
20 #include"os_python.h"
21 #include"os_std.h"
22
23 #include"MemoryDebug.h"
24 #include"Err.h"
25 #include"Base.h"
26 #include"OOMac.h"
27 #include"Symmetry.h"
28 #include"Setting.h"
29 #include"Ortho.h"
30 #include"Matrix.h"
31 #include"P.h"
32 #include"PConv.h"
33 #include"Util.h"
34 #include"PConv.h"
35
SymmetryAsPyList(CSymmetry * I)36 PyObject *SymmetryAsPyList(CSymmetry * I)
37 {
38 PyObject *result = NULL;
39
40 if(I) {
41 result = PyList_New(2);
42 PyList_SetItem(result, 0, CrystalAsPyList(&I->Crystal));
43 PyList_SetItem(result, 1, PyString_FromString(I->SpaceGroup));
44 }
45 return (PConvAutoNone(result));
46 }
47
SymmetryFromPyList(CSymmetry * I,PyObject * list)48 static int SymmetryFromPyList(CSymmetry * I, PyObject * list)
49 {
50 int ok = true;
51 ov_size ll;
52 PyObject *secondval;
53
54 if(ok)
55 ok = (I != NULL);
56 if(ok)
57 ok = (list != NULL);
58 if(ok)
59 ok = PyList_Check(list);
60 if(ok)
61 ll = PyList_Size(list);
62 if (ok && ll>=2){
63 secondval = PyList_GetItem(list, 1);
64 if (PyList_Check(secondval)){
65 /* if only the crystal, read it */
66 if(ok)
67 ok = CrystalFromPyList(&I->Crystal, list);
68 } else {
69 if(ok)
70 ok = CrystalFromPyList(&I->Crystal, PyList_GetItem(list, 0));
71 if(ok)
72 PConvPyStrToStr(PyList_GetItem(list, 1), I->SpaceGroup, sizeof(WordType));
73 }
74 }
75 if(ok) {
76 SymmetryUpdate(I);
77 }
78 /* TO SUPPORT BACKWARDS COMPATIBILITY...
79 Always check ll when adding new PyList_GetItem's */
80 return (ok);
81 }
82
SymmetryNewFromPyList(PyMOLGlobals * G,PyObject * list)83 CSymmetry *SymmetryNewFromPyList(PyMOLGlobals * G, PyObject * list)
84 {
85 CSymmetry *I = NULL;
86 I = new CSymmetry(G);
87 if(I) {
88 if(!SymmetryFromPyList(I, list)) {
89 SymmetryFree(I);
90 I = NULL;
91 }
92 }
93 return (I);
94 }
95
96 #ifndef _PYMOL_NOPY
97 #ifdef _PYMOL_XRAY
SymmetryDump44f(PyMOLGlobals * G,const float * m,const char * prefix)98 static void SymmetryDump44f(PyMOLGlobals * G, const float *m, const char *prefix)
99 {
100 if(prefix) {
101 PRINTF "%s %12.5f %12.5f %12.5f %12.5f\n", prefix, m[0], m[1], m[2], m[3] ENDF(G);
102 PRINTF "%s %12.5f %12.5f %12.5f %12.5f\n", prefix, m[4], m[5], m[6], m[7] ENDF(G);
103 PRINTF "%s %12.5f %12.5f %12.5f %12.5f\n", prefix, m[8], m[9], m[10], m[11] ENDF(G);
104 PRINTF "%s %12.5f %12.5f %12.5f %12.5f\n", prefix, m[12], m[13], m[14], m[15] ENDF(G);
105 } else {
106 PRINTF "%12.5f %12.5f %12.5f %12.5f\n", m[0], m[1], m[2], m[3] ENDF(G);
107 PRINTF "%12.5f %12.5f %12.5f %12.5f\n", m[4], m[5], m[6], m[7] ENDF(G);
108 PRINTF "%12.5f %12.5f %12.5f %12.5f\n", m[8], m[9], m[10], m[11] ENDF(G);
109 PRINTF "%12.5f %12.5f %12.5f %12.5f\n", m[12], m[13], m[14], m[15] ENDF(G);
110 }
111 }
112 #endif
113 #endif
114
115 /*
116 * Lookup the symmetry operations by space group symbol (from Python with
117 * pymol.xray) and populate SymMatVLA.
118 *
119 * Return false if space group unknown.
120 */
SymmetryAttemptGeneration(CSymmetry * I,int quiet)121 int SymmetryAttemptGeneration(CSymmetry * I, int quiet)
122 {
123 if (I->SymMatVLA) {
124 // don't re-run unless SymmetryUpdate() was called
125 return true;
126 }
127
128 int ok = false;
129 #ifndef _PYMOL_NOPY
130 #ifdef _PYMOL_XRAY
131 PyMOLGlobals *G = I->G;
132 CrystalUpdate(&I->Crystal);
133 if(!quiet) {
134 if(Feedback(G, FB_Symmetry, FB_Blather)) {
135 CrystalDump(&I->Crystal);
136 }
137 }
138 /* TAKEN OUT BB 2/2012 SpaceGroup can be blank,
139 sg_sym_to_mat_list has a blank entry with no operations
140 if(!I->SpaceGroup[0]) {
141 ErrMessage(G, "Symmetry", "Missing space group symbol");
142 } else */
143 if(P_xray) {
144 int blocked = PAutoBlock(G);
145 ov_size a, l;
146 PyObject *mats;
147 mats = PYOBJECT_CALLMETHOD(P_xray, "sg_sym_to_mat_list", "s", I->SpaceGroup);
148 if(mats && (mats != Py_None)) {
149 l = PyList_Size(mats);
150 I->SymMatVLA = pymol::vla<float>(16*l);
151 if(!quiet) {
152 PRINTFB(G, FB_Symmetry, FB_Details)
153 " Symmetry: Found %d symmetry operators.\n", (int) l ENDFB(G);
154 }
155 for(a = 0; a < l; a++) {
156 PConv44PyListTo44f(PyList_GetItem(mats, a), I->SymMatVLA + (a * 16));
157 if(!quiet) {
158 if(Feedback(G, FB_Symmetry, FB_Blather)) {
159 SymmetryDump44f(G, I->SymMatVLA + (a * 16), " Symmetry:");
160 }
161 }
162 }
163 ok = true;
164 Py_DECREF(mats);
165 } else {
166 ErrMessage(G, "Symmetry", "Unable to get matrices.");
167 }
168 PAutoUnblock(G, blocked);
169 }
170 #endif
171 #endif
172 return (ok);
173 }
174
SymmetryFree(CSymmetry * I)175 void SymmetryFree(CSymmetry * I)
176 {
177 if (!I)
178 return;
179
180 delete I;
181 }
182
SymmetryUpdate(CSymmetry * I)183 void SymmetryUpdate(CSymmetry * I)
184 {
185 CrystalUpdate(&I->Crystal);
186 I->SymMatVLA.freeP();
187 }
188
SymmetryDump(CSymmetry * I)189 void SymmetryDump(CSymmetry * I)
190 {
191 }
192
193 /*
194 * Get the number of symmetry matrices
195 */
getNSymMat() const196 int CSymmetry::getNSymMat() const {
197 if (!SymMatVLA)
198 return 0;
199 return VLAGetSize(SymMatVLA) / 16;
200 }
201
202 /*
203 * Register a a space group with symmetry operations (if not already registered)
204 *
205 * sg: space group symbol, e.g. "P 1"
206 * sym_op: list of symmetry operations, e.g. ["x,y,z", "-x,-y,z"]
207 */
SymmetrySpaceGroupRegister(PyMOLGlobals * G,const char * sg,const std::vector<std::string> & sym_op)208 void SymmetrySpaceGroupRegister(PyMOLGlobals * G, const char* sg, const std::vector<std::string>& sym_op) {
209 #if !defined(_PYMOL_NOPY) && defined(_PYMOL_XRAY)
210 if (!P_xray)
211 return;
212
213 int blocked = PAutoBlock(G);
214 PYOBJECT_CALLMETHOD(P_xray,
215 "sg_register_if_unknown", "sN", sg, PConvToPyObject(sym_op));
216 PAutoUnblock(G, blocked);
217 #endif
218 }
219