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(format(
115 " Atom %s has a null alternate location. Likely cause: attempting X-ray refinement from a .xyz file", a));
116 }
117 if (!a.getAltLoc().equals(' ') || a.getOccupancy() < 1.0) {
118 if (iNode instanceof Residue) {
119 tempResidues = new ArrayList<>();
120 tempResidues.add((Residue) iNode);
121 altResidues.add(tempResidues);
122 alternateConformer = true;
123 break;
124 } else if (iNode instanceof Molecule) {
125 if (refineMolOcc) {
126 tempMolecules = new ArrayList<>();
127 tempMolecules.add((Molecule) iNode);
128 altMolecules.add(tempMolecules);
129 }
130 alternateConformer = true;
131 break;
132 }
133 }
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 xIndex = new ArrayList<>(molecularAssemblies.length);
165 for (int i = 0; i < molecularAssemblies.length; i++) {
166 xIndex.add(new ArrayList<>());
167 }
168
169
170 totalAtomList = new ArrayList<>();
171
172
173 activeAtomList = new ArrayList<>();
174
175
176 atomList = molecularAssemblies[0].getAtomList();
177 int index = 0;
178 for (Atom a : atomList) {
179 if (!a.getUse()) {
180 continue;
181 }
182 totalAtomList.add(a);
183 if (a.isActive()) {
184 activeAtomList.add(a);
185 a.setFormFactorIndex(index);
186 xIndex.getFirst().add(index);
187 index++;
188 }
189 }
190
191
192 for (int i = 1; i < molecularAssemblies.length; i++) {
193 atomList = molecularAssemblies[i].getAtomList();
194 for (Atom a : atomList) {
195 if (!a.getUse()) {
196 continue;
197 }
198 Atom root = molecularAssemblies[0].findAtom(a, false);
199 Atom deuteriumMatch = molecularAssemblies[0].findAtom(a, true);
200 if (root != null && root.getAltLoc().equals(a.getAltLoc())) {
201 if (a.isActive()) {
202 xIndex.get(i).add(root.getFormFactorIndex());
203 a.setFormFactorIndex(root.getFormFactorIndex());
204 }
205 } else if (deuteriumMatch != null) {
206 if (a.isActive()) {
207 xIndex.get(i).add(deuteriumMatch.getFormFactorIndex());
208 a.setFormFactorIndex(deuteriumMatch.getFormFactorIndex());
209 }
210 } else {
211 totalAtomList.add(a);
212 if (a.isActive()) {
213 activeAtomList.add(a);
214 a.setFormFactorIndex(index);
215 xIndex.get(i).add(index);
216 index++;
217 }
218 }
219 }
220 }
221
222 totalAtomArray = totalAtomList.toArray(new Atom[0]);
223 activeAtomArray = activeAtomList.toArray(new Atom[0]);
224
225
226
227
228
229 for (List<Residue> list : altResidues) {
230 double tocc = 0.0;
231 for (Residue r : list) {
232 for (Atom a : r.getAtomList()) {
233 if (a.getOccupancy() < 1.0 || a.getOccupancy() > 1.0) {
234 tocc += a.getOccupancy();
235 break;
236 }
237 }
238 }
239 if (list.size() == 1) {
240 Residue r = list.getFirst();
241 logger.log(Level.INFO,
242 " Residue {0} is a single conformer with non-unity occupancy.\n Occupancy will be refined independently.\n",
243 r.getChainID() + " " + r);
244 } else if (tocc < 1.0 || tocc > 1.0) {
245 Residue r = list.getFirst();
246 logger.log(Level.INFO,
247 " Residue {0} occupancy does not sum to 1.0.\n This should be fixed or checked due to possible instability in refinement.\n",
248 r.getChainID() + " " + r);
249 }
250 }
251 }
252
253
254
255
256
257
258 public Atom[] getActiveAtomArray() {
259 return activeAtomArray;
260 }
261
262
263
264
265
266
267 public List<Atom> getActiveAtomList() {
268 return activeAtomList;
269 }
270
271
272
273
274
275
276 public List<List<Molecule>> getAltMolecules() {
277 return altMolecules;
278 }
279
280
281
282
283
284
285 public List<List<Residue>> getAltResidues() {
286 return altResidues;
287 }
288
289
290
291
292
293
294 public Atom[] getTotalAtomArray() {
295 return totalAtomArray;
296 }
297
298
299
300
301
302
303 List<List<Integer>> getxIndex() {
304 return xIndex;
305 }
306
307
308
309
310
311
312 List<Atom> getTotalAtomList() {
313 return totalAtomList;
314 }
315 }