Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.ext.rbvi.chimera

File AtomSpecModel.java

 

Coverage histogram

../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

24
45
4
1
201
97
16
0.36
11.25
4
4

Classes

Class Line # Actions
AtomSpecModel 52 45 16 3
0.958904195.9%
 

Contributing tests

This file is covered by 4 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.ext.rbvi.chimera;
22   
23    import jalview.util.IntRangeComparator;
24   
25    import java.util.ArrayList;
26    import java.util.Collections;
27    import java.util.Iterator;
28    import java.util.List;
29    import java.util.Map;
30    import java.util.TreeMap;
31   
32    /**
33    * A class to model a Chimera atomspec pattern, for example
34    *
35    * <pre>
36    * #0:15.A,28.A,54.A,63.A,70-72.A,83-84.A,97-98.A|#1:2.A,6.A,11.A,13-14.A,70.A,82.A,96-97.A
37    * </pre>
38    *
39    * where
40    * <ul>
41    * <li>#0 is a model number</li>
42    * <li>15 or 70-72 is a residue number, or range of residue numbers</li>
43    * <li>.A is a chain identifier</li>
44    * <li>residue ranges are separated by comma</li>
45    * <li>atomspecs for distinct models are separated by | (or)</li>
46    * </ul>
47    *
48    * <pre>
49    * &#64;see http://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/frameatom_spec.html
50    * </pre>
51    */
 
52    public class AtomSpecModel
53    {
54    private Map<Integer, Map<String, List<int[]>>> atomSpec;
55   
56    /**
57    * Constructor
58    */
 
59  12 toggle public AtomSpecModel()
60    {
61  12 atomSpec = new TreeMap<Integer, Map<String, List<int[]>>>();
62    }
63   
64    /**
65    * Adds one contiguous range to this atom spec
66    *
67    * @param model
68    * @param startPos
69    * @param endPos
70    * @param chain
71    */
 
72  34 toggle public void addRange(int model, int startPos, int endPos, String chain)
73    {
74    /*
75    * Get/initialize map of data for the colour and model
76    */
77  34 Map<String, List<int[]>> modelData = atomSpec.get(model);
78  34 if (modelData == null)
79    {
80  19 atomSpec.put(model, modelData = new TreeMap<String, List<int[]>>());
81    }
82   
83    /*
84    * Get/initialize map of data for colour, model and chain
85    */
86  34 List<int[]> chainData = modelData.get(chain);
87  34 if (chainData == null)
88    {
89  24 chainData = new ArrayList<int[]>();
90  24 modelData.put(chain, chainData);
91    }
92   
93    /*
94    * Add the start/end positions
95    */
96  34 chainData.add(new int[] { startPos, endPos });
97    // TODO add intelligently, using a RangeList class
98    }
99   
100    /**
101    * Returns the range(s) formatted as a Chimera atomspec
102    *
103    * @return
104    */
 
105  25 toggle public String getAtomSpec()
106    {
107  25 StringBuilder sb = new StringBuilder(128);
108  25 boolean firstModel = true;
109  25 for (Integer model : atomSpec.keySet())
110    {
111  37 if (!firstModel)
112    {
113  13 sb.append("|");
114    }
115  37 firstModel = false;
116  37 sb.append("#").append(model).append(":");
117   
118  37 boolean firstPositionForModel = true;
119  37 final Map<String, List<int[]>> modelData = atomSpec.get(model);
120   
121  37 for (String chain : modelData.keySet())
122    {
123  54 chain = " ".equals(chain) ? chain : chain.trim();
124   
125  54 List<int[]> rangeList = modelData.get(chain);
126   
127    /*
128    * sort ranges into ascending start position order
129    */
130  54 Collections.sort(rangeList, IntRangeComparator.ASCENDING);
131   
132  54 int start = rangeList.isEmpty() ? 0 : rangeList.get(0)[0];
133  54 int end = rangeList.isEmpty() ? 0 : rangeList.get(0)[1];
134   
135  54 Iterator<int[]> iterator = rangeList.iterator();
136  142 while (iterator.hasNext())
137    {
138  88 int[] range = iterator.next();
139  88 if (range[0] <= end + 1)
140    {
141    /*
142    * range overlaps or is contiguous with the last one
143    * - so just extend the end position, and carry on
144    * (unless this is the last in the list)
145    */
146  77 end = Math.max(end, range[1]);
147    }
148    else
149    {
150    /*
151    * we have a break so append the last range
152    */
153  11 appendRange(sb, start, end, chain, firstPositionForModel);
154  11 firstPositionForModel = false;
155  11 start = range[0];
156  11 end = range[1];
157    }
158    }
159   
160    /*
161    * and append the last range
162    */
163  54 if (!rangeList.isEmpty())
164    {
165  54 appendRange(sb, start, end, chain, firstPositionForModel);
166  54 firstPositionForModel = false;
167    }
168    }
169    }
170  25 return sb.toString();
171    }
172   
173    /**
174    * @param sb
175    * @param start
176    * @param end
177    * @param chain
178    * @param firstPositionForModel
179    */
 
180  65 toggle protected void appendRange(StringBuilder sb, int start, int end,
181    String chain, boolean firstPositionForModel)
182    {
183  65 if (!firstPositionForModel)
184    {
185  28 sb.append(",");
186    }
187  65 if (end == start)
188    {
189  16 sb.append(start);
190    }
191    else
192    {
193  49 sb.append(start).append("-").append(end);
194    }
195   
196  65 sb.append(".");
197  65 if (!" ".equals(chain)) {
198  64 sb.append(chain);
199    }
200    }
201    }