1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.xray;
39
40 import ffx.potential.MolecularAssembly;
41 import ffx.potential.bonded.Atom;
42 import ffx.potential.bonded.MSNode;
43 import ffx.potential.bonded.Molecule;
44 import ffx.potential.bonded.Residue;
45
46 import java.util.ArrayList;
47 import java.util.List;
48 import java.util.logging.Level;
49 import java.util.logging.Logger;
50
51 import static java.lang.String.format;
52
53
54
55
56
57
58
59 public class RefinementModel {
60
61 private static final Logger logger = Logger.getLogger(RefinementModel.class.getName());
62
63 private final List<Atom> totalAtomList;
64
65 private final Atom[] totalAtomArray;
66
67 private final List<Atom> activeAtomList;
68
69 private final Atom[] activeAtomArray;
70
71 private final List<List<Integer>> xIndex;
72
73 private final List<List<Residue>> altResidues;
74 private final List<List<Molecule>> altMolecules;
75
76
77
78
79
80
81 public RefinementModel(MolecularAssembly[] molecularAssemblies) {
82 this(molecularAssemblies, false);
83 }
84
85
86
87
88
89
90
91 @SuppressWarnings("unchecked")
92 public RefinementModel(MolecularAssembly[] molecularAssemblies, boolean refineMolOcc) {
93 List<Atom> atomList;
94
95
96 altResidues = new ArrayList<>();
97 altMolecules = new ArrayList<>();
98 List<MSNode> nodeList0 = molecularAssemblies[0].getNodeList();
99 List<Residue> tempResidues = null;
100 List<Molecule> tempMolecules = null;
101 boolean alternateConformer;
102
103
104 for (int i = 0; i < nodeList0.size(); i++) {
105 alternateConformer = false;
106 MSNode iNode = nodeList0.get(i);
107
108
109 for (Atom a : iNode.getAtomList()) {
110 if (!a.getUse()) {
111 continue;
112 }
113 if (a.getAltLoc() == null) {
114 logger.severe(
115 format(
116 " Atom %s has a null alternate location. Likely cause: attempting X-ray refinement from a .xyz file",
117 a));
118 }
119 if (!a.getAltLoc().equals(' ') || a.getOccupancy() < 1.0) {
120 if (iNode instanceof Residue) {
121 tempResidues = new ArrayList<>();
122 tempResidues.add((Residue) iNode);
123 altResidues.add(tempResidues);
124 alternateConformer = true;
125 break;
126 } else if (iNode instanceof Molecule) {
127 if (refineMolOcc) {
128 tempMolecules = new ArrayList<>();
129 tempMolecules.add((Molecule) iNode);
130 altMolecules.add(tempMolecules);
131 }
132 alternateConformer = true;
133 break;
134 }
135 }
136 }
137 if (alternateConformer) {
138 for (int j = 1; j < molecularAssemblies.length; j++) {
139 List<MSNode> nlist = molecularAssemblies[j].getNodeList();
140 MSNode node = nlist.get(i);
141 for (Atom a : node.getAtomList()) {
142 if (!a.getUse()) {
143 continue;
144 }
145 if (!a.getAltLoc().equals(' ') && !a.getAltLoc().equals('A')) {
146 if (node instanceof Residue) {
147 if (tempResidues != null) {
148 tempResidues.add((Residue) node);
149 }
150 break;
151 } else if (node instanceof Molecule) {
152 if (tempMolecules != null) {
153 tempMolecules.add((Molecule) node);
154 }
155 break;
156 }
157 }
158 }
159 }
160 }
161 }
162
163
164
165 xIndex = new ArrayList<>(molecularAssemblies.length);
166 for (int i = 0; i < molecularAssemblies.length; i++) {
167
168 xIndex.add(new ArrayList<>());
169 }
170
171
172 totalAtomList = new ArrayList<>();
173
174
175 activeAtomList = new ArrayList<>();
176
177
178 atomList = molecularAssemblies[0].getAtomList();
179 int index = 0;
180 for (Atom a : atomList) {
181 if (!a.getUse()) {
182 continue;
183 }
184 totalAtomList.add(a);
185
186
187
188 if (a.isActive()) {
189 activeAtomList.add(a);
190 a.setFormFactorIndex(index);
191
192 xIndex.get(0).add(index);
193 index++;
194 }
195 }
196
197
198 for (int i = 1; i < molecularAssemblies.length; i++) {
199 atomList = molecularAssemblies[i].getAtomList();
200 for (Atom a : atomList) {
201 if (!a.getUse()) {
202 continue;
203 }
204 Atom root = molecularAssemblies[0].findAtom(a);
205 if (root != null && root.getAltLoc().equals(a.getAltLoc())) {
206
207
208 if (a.isActive()) {
209
210 xIndex.get(i).add(root.getFormFactorIndex());
211 a.setFormFactorIndex(root.getFormFactorIndex());
212 }
213 } else {
214
215
216 totalAtomList.add(a);
217 if (a.isActive()) {
218 activeAtomList.add(a);
219
220 xIndex.get(i).add(index);
221 index++;
222 }
223 }
224 }
225 }
226
227 totalAtomArray = totalAtomList.toArray(new Atom[0]);
228 activeAtomArray = activeAtomList.toArray(new Atom[0]);
229
230
231
232
233
234 for (List<Residue> list : altResidues) {
235 double tocc = 0.0;
236 for (Residue r : list) {
237 for (Atom a : r.getAtomList()) {
238 if (a.getOccupancy() < 1.0 || a.getOccupancy() > 1.0) {
239 tocc += a.getOccupancy();
240 break;
241 }
242 }
243 }
244 if (list.size() == 1) {
245 Residue r = list.get(0);
246 logger.log(Level.INFO,
247 " Residue {0} is a single conformer with non-unity occupancy.\n Occupancy will be refined independently.\n",
248 r.getChainID() + " " + r);
249 } else if (tocc < 1.0 || tocc > 1.0) {
250 Residue r = list.get(0);
251 logger.log(Level.INFO,
252 " Residue {0} occupancy does not sum to 1.0.\n This should be fixed or checked due to possible instability in refinement.\n",
253 r.getChainID() + " " + r);
254 }
255 }
256 }
257
258
259
260
261
262
263 public Atom[] getActiveAtomArray() {
264 return activeAtomArray;
265 }
266
267
268
269
270
271
272 public List<Atom> getActiveAtomList() {
273 return activeAtomList;
274 }
275
276
277
278
279
280
281 public List<List<Molecule>> getAltMolecules() {
282 return altMolecules;
283 }
284
285
286
287
288
289
290 public List<List<Residue>> getAltResidues() {
291 return altResidues;
292 }
293
294
295
296
297
298
299 public Atom[] getTotalAtomArray() {
300 return totalAtomArray;
301 }
302
303
304
305
306
307
308 List<List<Integer>> getxIndex() {
309 return xIndex;
310 }
311
312
313
314
315
316
317 List<Atom> getTotalAtomList() {
318 return totalAtomList;
319 }
320 }