+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.rbvi.chimera;
import jalview.util.IntRangeComparator;
* </ul>
*
* <pre>
- * @see http://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/frameatom_spec.html
+ * @see http://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/frameatom_spec.html
* </pre>
*/
public class AtomSpecModel
*/
public AtomSpecModel()
{
- atomSpec = new TreeMap<Integer, Map<String, List<int[]>>>();
+ atomSpec = new TreeMap<>();
}
/**
Map<String, List<int[]>> modelData = atomSpec.get(model);
if (modelData == null)
{
- atomSpec.put(model, modelData = new TreeMap<String, List<int[]>>());
+ atomSpec.put(model, modelData = new TreeMap<>());
}
/*
List<int[]> chainData = modelData.get(chain);
if (chainData == null)
{
- chainData = new ArrayList<int[]>();
+ chainData = new ArrayList<>();
modelData.put(chain, chainData);
}
for (String chain : modelData.keySet())
{
- chain = chain.trim();
+ chain = " ".equals(chain) ? chain : chain.trim();
List<int[]> rangeList = modelData.get(chain);
/*
* we have a break so append the last range
*/
- appendRange(sb, start, end, chain, firstPositionForModel);
+ appendRange(sb, start, end, chain, firstPositionForModel,
+ false);
firstPositionForModel = false;
start = range[0];
end = range[1];
*/
if (!rangeList.isEmpty())
{
- appendRange(sb, start, end, chain, firstPositionForModel);
+ appendRange(sb, start, end, chain, firstPositionForModel, false);
firstPositionForModel = false;
}
}
* @param firstPositionForModel
*/
protected void appendRange(StringBuilder sb, int start, int end,
- String chain, boolean firstPositionForModel)
+ String chain, boolean firstPositionForModel, boolean isChimeraX)
{
if (!firstPositionForModel)
{
{
sb.append(start).append("-").append(end);
}
- if (chain.length() > 0)
+
+ if (!isChimeraX)
+ {
+ sb.append(".");
+ if (!" ".equals(chain))
+ {
+ sb.append(chain);
+ }
+ }
+ }
+
+ /**
+ * Returns the range(s) formatted as a ChimeraX atomspec, for example
+ * <p>
+ * #1/A:2-20,30-40/B:10-20|#2/A:12-30
+ *
+ * @return
+ */
+ public String getAtomSpecX()
+ {
+ StringBuilder sb = new StringBuilder(128);
+ boolean firstModel = true;
+ for (Integer model : atomSpec.keySet())
{
- sb.append(".").append(chain);
+ if (!firstModel)
+ {
+ sb.append("|");
+ }
+ firstModel = false;
+ sb.append("#").append(model);
+
+ final Map<String, List<int[]>> modelData = atomSpec.get(model);
+
+ for (String chain : modelData.keySet())
+ {
+ boolean firstPositionForChain = true;
+ chain = " ".equals(chain) ? chain : chain.trim();
+ sb.append("/").append(chain).append(":");
+ List<int[]> rangeList = modelData.get(chain);
+
+ /*
+ * sort ranges into ascending start position order
+ */
+ Collections.sort(rangeList, IntRangeComparator.ASCENDING);
+
+ int start = rangeList.isEmpty() ? 0 : rangeList.get(0)[0];
+ int end = rangeList.isEmpty() ? 0 : rangeList.get(0)[1];
+
+ Iterator<int[]> iterator = rangeList.iterator();
+ while (iterator.hasNext())
+ {
+ int[] range = iterator.next();
+ if (range[0] <= end + 1)
+ {
+ /*
+ * range overlaps or is contiguous with the last one
+ * - so just extend the end position, and carry on
+ * (unless this is the last in the list)
+ */
+ end = Math.max(end, range[1]);
+ }
+ else
+ {
+ /*
+ * we have a break so append the last range
+ */
+ appendRange(sb, start, end, chain, firstPositionForChain, true);
+ start = range[0];
+ end = range[1];
+ firstPositionForChain = false;
+ }
+ }
+
+ /*
+ * and append the last range
+ */
+ if (!rangeList.isEmpty())
+ {
+ appendRange(sb, start, end, chain, firstPositionForChain, true);
+ }
+ firstPositionForChain = false;
+ }
}
+ return sb.toString();
}
}