Clover icon

Coverage Report

  1. Project Clover database Mon Nov 11 2024 16:01:40 GMT
  2. Package jalview.structure

File StructureMapping.java

 

Coverage histogram

../../img/srcFileCovDistChart7.png
29% of files have more coverage

Code metrics

74
104
15
1
368
249
53
0.51
6.93
15
3.53

Classes

Class Line # Actions
StructureMapping 31 104 53
0.709844671%
 

Contributing tests

This file is covered by 51 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.structure;
22   
23    import jalview.datamodel.AlignmentAnnotation;
24    import jalview.datamodel.Mapping;
25    import jalview.datamodel.SequenceI;
26   
27    import java.util.ArrayList;
28    import java.util.HashMap;
29    import java.util.List;
30   
 
31    public class StructureMapping
32    {
33    public static final int UNASSIGNED_VALUE = Integer.MIN_VALUE;
34   
35    private static final int PDB_RES_NUM_INDEX = 0;
36   
37    private static final int PDB_ATOM_NUM_INDEX = 1;
38   
39    String mappingDetails;
40   
41    SequenceI sequence;
42   
43    String pdbfile;
44   
45    String pdbid;
46   
47    String pdbchain;
48   
49    // Mapping key is residue index while value is an array containing PDB resNum,
50    // and atomNo
51    HashMap<Integer, int[]> mapping;
52   
53    jalview.datamodel.Mapping seqToPdbMapping = null;
54   
55    /**
56    * Constructor
57    *
58    * @param seq
59    * @param pdbfile
60    * @param pdbid
61    * @param chain
62    * @param mapping
63    * a map from sequence to two values, { resNo, atomNo } in the
64    * structure
65    * @param mappingDetails
66    */
 
67  214 toggle public StructureMapping(SequenceI seq, String pdbfile, String pdbid,
68    String chain, HashMap<Integer, int[]> mapping,
69    String mappingDetails)
70    {
71  214 sequence = seq;
72  214 this.pdbfile = pdbfile;
73  214 this.pdbid = pdbid;
74  214 this.pdbchain = chain;
75  214 this.mapping = mapping;
76  214 this.mappingDetails = mappingDetails;
77    }
78   
 
79  9 toggle public StructureMapping(SequenceI seq, String pdbFile2, String pdbId2,
80    String chain, HashMap<Integer, int[]> mapping2,
81    String mappingOutput, Mapping seqToPdbMapping)
82    {
83  9 this(seq, pdbFile2, pdbId2, chain, mapping2, mappingOutput);
84  9 this.seqToPdbMapping = seqToPdbMapping;
85    }
86   
 
87  501 toggle public SequenceI getSequence()
88    {
89  501 return sequence;
90    }
91   
 
92  32491 toggle public String getChain()
93    {
94  32491 return pdbchain;
95    }
96   
 
97  9 toggle public String getPdbId()
98    {
99  9 return pdbid;
100    }
101   
102    /**
103    *
104    * @param seqpos
105    * @return 0 or corresponding atom number for the sequence position
106    */
 
107  0 toggle public int getAtomNum(int seqpos)
108    {
109  0 int[] resNumAtomMap = mapping.get(seqpos);
110  0 if (resNumAtomMap != null)
111    {
112  0 return resNumAtomMap[PDB_ATOM_NUM_INDEX];
113    }
114    else
115    {
116  0 return UNASSIGNED_VALUE;
117    }
118    }
119   
120    /**
121    *
122    * @param seqpos
123    * @return UNASSIGNED_VALUE or the corresponding residue number for the
124    * sequence position
125    */
 
126  33379 toggle public int getPDBResNum(int seqpos)
127    {
128  33379 int[] resNumAtomMap = mapping.get(seqpos);
129  33379 if (resNumAtomMap != null)
130    {
131  33357 return resNumAtomMap[PDB_RES_NUM_INDEX];
132    }
133    else
134    {
135  21 return UNASSIGNED_VALUE;
136    }
137    }
138   
139    /**
140    * Returns a (possibly empty) list of [start, end] residue positions in the
141    * mapped structure, corresponding to the given range of sequence positions
142    *
143    * @param fromSeqPos
144    * @param toSeqPos
145    * @return
146    */
 
147  5 toggle public List<int[]> getPDBResNumRanges(int fromSeqPos, int toSeqPos)
148    {
149  5 List<int[]> result = new ArrayList<>();
150  5 int startRes = -1;
151  5 int endRes = -1;
152   
153  18 for (int i = fromSeqPos; i <= toSeqPos; i++)
154    {
155  13 int resNo = getPDBResNum(i);
156  13 if (resNo == UNASSIGNED_VALUE)
157    {
158  7 continue; // no mapping from this sequence position
159    }
160  6 if (startRes == -1)
161    {
162  3 startRes = resNo;
163  3 endRes = resNo;
164    }
165  6 if (resNo >= startRes && resNo <= endRes)
166    {
167    // within the current range - no change
168  3 continue;
169    }
170  3 if (resNo == startRes - 1)
171    {
172    // extend beginning of current range
173  0 startRes--;
174  0 continue;
175    }
176  3 if (resNo == endRes + 1)
177    {
178    // extend end of current range
179  2 endRes++;
180  2 continue;
181    }
182   
183    /*
184    * resNo is not within or contiguous with last range,
185    * so write out the last range
186    */
187  1 result.add(new int[] { startRes, endRes });
188  1 startRes = resNo;
189  1 endRes = resNo;
190    }
191   
192    /*
193    * and add the last range
194    */
195  5 if (startRes != -1)
196    {
197  3 result.add(new int[] { startRes, endRes });
198    }
199   
200  5 return result;
201    }
202   
203    /**
204    *
205    * @param pdbResNum
206    * @return -1 or the corresponding sequence position for a pdb residue number
207    */
 
208  1 toggle public int getSeqPos(int pdbResNum)
209    {
210  1 for (Integer seqPos : mapping.keySet())
211    {
212  276 if (pdbResNum == getPDBResNum(seqPos))
213    {
214  1 return seqPos;
215    }
216    }
217  0 return UNASSIGNED_VALUE;
218    }
219   
220    /**
221    * transfer a copy of an alignment annotation row in the PDB chain coordinate
222    * system onto the mapped sequence
223    *
224    * @param ana
225    * @return the copy that was remapped to the mapped sequence
226    * @note this method will create a copy and add it to the dataset sequence for
227    * the mapped sequence as well as the mapped sequence (if it is not a
228    * dataset sequence).
229    */
 
230  0 toggle public AlignmentAnnotation transfer(AlignmentAnnotation ana)
231    {
232  0 AlignmentAnnotation ala_copy = new AlignmentAnnotation(ana);
233  0 SequenceI ds = sequence;
234  0 while (ds.getDatasetSequence() != null)
235    {
236  0 ds = ds.getDatasetSequence();
237    }
238    // need to relocate annotation from pdb coordinates to local sequence
239    // -1,-1 doesn't look at pdbresnum but fails to remap sequence positions...
240   
241  0 ala_copy.remap(ds, mapping, -1, -1, 0);
242  0 ds.addAlignmentAnnotation(ala_copy);
243  0 if (ds != sequence)
244    {
245    // mapping wasn't to an original dataset sequence, so we make a copy on
246    // the mapped sequence too
247  0 ala_copy = new AlignmentAnnotation(ala_copy);
248  0 sequence.addAlignmentAnnotation(ala_copy);
249    }
250  0 return ala_copy;
251    }
252   
 
253  0 toggle public String getMappingDetailsOutput()
254    {
255  0 return mappingDetails;
256    }
257   
 
258  0 toggle public HashMap<Integer, int[]> getMapping()
259    {
260  0 return mapping;
261    }
262   
 
263  0 toggle public Mapping getSeqToPdbMapping()
264    {
265  0 return seqToPdbMapping;
266    }
267   
268    /**
269    * A hash function that satisfies the contract that if two mappings are
270    * equal(), they have the same hashCode
271    */
 
272  2 toggle @Override
273    public int hashCode()
274    {
275  2 final int prime = 31;
276  2 int result = 1;
277  2 result = prime * result
278  2 + ((mappingDetails == null) ? 0 : mappingDetails.hashCode());
279  2 result = prime * result
280  2 + ((pdbchain == null) ? 0 : pdbchain.hashCode());
281  2 result = prime * result + ((pdbfile == null) ? 0 : pdbfile.hashCode());
282  2 result = prime * result + ((pdbid == null) ? 0 : pdbid.hashCode());
283  2 result = prime * result
284  2 + ((seqToPdbMapping == null) ? 0 : seqToPdbMapping.hashCode());
285  2 result = prime * result
286  2 + ((sequence == null) ? 0 : sequence.hashCode());
287  2 return result;
288    }
289   
 
290  192 toggle @Override
291    public boolean equals(Object obj)
292    {
293  192 if (this == obj)
294    {
295  0 return true;
296    }
297  192 if (obj == null)
298    {
299  1 return false;
300    }
301  191 if (getClass() != obj.getClass())
302    {
303  1 return false;
304    }
305  190 StructureMapping other = (StructureMapping) obj;
306  190 if (mappingDetails == null)
307    {
308  5 if (other.mappingDetails != null)
309    {
310  0 return false;
311    }
312    }
313  185 else if (!mappingDetails.equals(other.mappingDetails))
314    {
315  81 return false;
316    }
317  109 if (pdbchain == null)
318    {
319  3 if (other.pdbchain != null)
320    {
321  0 return false;
322    }
323    }
324  106 else if (!pdbchain.equals(other.pdbchain))
325    {
326  4 return false;
327    }
328  105 if (pdbfile == null)
329    {
330  0 if (other.pdbfile != null)
331    {
332  0 return false;
333    }
334    }
335  105 else if (!pdbfile.equals(other.pdbfile))
336    {
337  20 return false;
338    }
339  85 if (pdbid == null)
340    {
341  0 if (other.pdbid != null)
342    {
343  0 return false;
344    }
345    }
346  85 else if (!pdbid.equals(other.pdbid))
347    {
348  2 return false;
349    }
350  83 if (seqToPdbMapping == null)
351    {
352  75 if (other.seqToPdbMapping != null)
353    {
354  0 return false;
355    }
356    }
357  8 else if (!seqToPdbMapping.equals(other.seqToPdbMapping))
358    {
359  2 return false;
360    }
361  81 if (sequence != other.sequence)
362    {
363  8 return false;
364    }
365   
366  73 return true;
367    }
368    }