> modelData = colourData.get(model);
for (String chain : modelData.keySet())
{
boolean hasChain = !"".equals(chain.trim());
for (int[] range : modelData.get(chain))
{
if (!firstPositionForModel)
{
sb.append(",");
}
if (range[0] == range[1])
{
sb.append(range[0]);
}
else
{
sb.append(range[0]).append("-").append(range[1]);
}
if (hasChain)
{
sb.append(".").append(chain);
}
firstPositionForModel = false;
}
}
}
}
commands.add(sb.toString());
return commands;
}
/**
*
* Build a data structure which maps contiguous subsequences for each colour.
* This generates a data structure from which we can easily generate the
* Chimera command for colour by sequence.
* Color
* Model number
* Chain
* list of start/end ranges
* Ordering is by order of addition (for colours and positions), natural ordering (for models and chains)
*
*/
protected static Map>>> buildColoursMap(
StructureSelectionManager ssm, String[] files,
SequenceI[][] sequence, SequenceRenderer sr, FeatureRenderer fr,
AlignmentI alignment)
{
Map>>> colourMap = new LinkedHashMap>>>();
Color lastColour = null;
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
if (mapping == null || mapping.length < 1)
{
continue;
}
int startPos = -1, lastPos = -1;
String lastChain = "";
for (int s = 0; s < sequence[pdbfnum].length; s++)
{
for (int sp, m = 0; m < mapping.length; m++)
{
final SequenceI seq = sequence[pdbfnum][s];
if (mapping[m].getSequence() == seq
&& (sp = alignment.findIndex(seq)) > -1)
{
SequenceI asp = alignment.getSequenceAt(sp);
for (int r = 0; r < asp.getLength(); r++)
{
// no mapping to gaps in sequence
if (Comparison.isGap(asp.getCharAt(r)))
{
continue;
}
int pos = mapping[m].getPDBResNum(asp.findPosition(r));
if (pos < 1 || pos == lastPos)
{
continue;
}
Color colour = sr.getResidueColour(seq, r, fr);
final String chain = mapping[m].getChain();
/*
* Just keep incrementing the end position for this colour range
* _unless_ colour, PDB model or chain has changed, or there is a
* gap in the mapped residue sequence
*/
final boolean newColour = !colour.equals(lastColour);
final boolean nonContig = lastPos + 1 != pos;
final boolean newChain = !chain.equals(lastChain);
if (newColour || nonContig || newChain)
{
if (startPos != -1)
{
addColourRange(colourMap, lastColour, pdbfnum, startPos,
lastPos, lastChain);
}
startPos = pos;
}
lastColour = colour;
lastPos = pos;
lastChain = chain;
}
// final colour range
if (lastColour != null)
{
addColourRange(colourMap, lastColour, pdbfnum, startPos,
lastPos, lastChain);
}
// break;
}
}
}
}
return colourMap;
}
/**
* Helper method to add one contiguous colour range to the colour map.
*
* @param colourMap
* @param colour
* @param model
* @param startPos
* @param endPos
* @param chain
*/
protected static void addColourRange(
Map>>> colourMap,
Color colour, int model, int startPos, int endPos, String chain)
{
/*
* Get/initialize map of data for the colour
*/
Map>> colourData = colourMap
.get(colour);
if (colourData == null)
{
colourMap
.put(colour,
colourData = new TreeMap>>());
}
/*
* Get/initialize map of data for the colour and model
*/
Map> modelData = colourData.get(model);
if (modelData == null)
{
colourData.put(model, modelData = new TreeMap>());
}
/*
* Get/initialize map of data for colour, model and chain
*/
List chainData = modelData.get(chain);
if (chainData == null)
{
modelData.put(chain, chainData = new ArrayList());
}
/*
* Add the start/end positions
*/
chainData.add(new int[] { startPos, endPos });
}
}