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