JAL-2434 omit unmapped positions from mapping
[jalview.git] / src / jalview / structure / StructureMappingClient.java
index 1e78c3c..bcc4d46 100644 (file)
@@ -4,26 +4,36 @@ import jalview.datamodel.SequenceI;
 import jalview.io.StructureFile;
 import jalview.structures.models.MappingOutputModel;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import MCview.Atom;
 import MCview.PDBChain;
 
 public abstract class StructureMappingClient
 {
-
   protected StructureFile structureFile;
 
-  public static final int UNASSIGNED = -1;
-
-  private static final int PDB_RES_POS = 0;
+  private static final int PDB_RES_POS = StructureMapping.PDB_RES_NUM_INDEX; // 0
 
-  private static final int PDB_ATOM_POS = 1;
+  private static final int PDB_ATOM_POS = StructureMapping.PDB_ATOM_NUM_INDEX; // 1
 
+  /**
+   * Populates the atom positions mapped to by finding the atom number (if any)
+   * for each structure residue number in the map. If no atom is found (as is
+   * the case for residues missing in a PDB file), then deletes the residue from
+   * the map.
+   * 
+   * @param chainId
+   * @param mapping
+   * @throws IllegalArgumentException
+   * @throws StructureMappingException
+   */
   public void populateAtomPositions(String chainId,
-          Map<Integer, int[]> mapping)
- throws IllegalArgumentException,
+          Map<Integer, int[]> mapping) throws IllegalArgumentException,
           StructureMappingException
   {
     try
@@ -35,13 +45,31 @@ public abstract class StructureMappingClient
         throw new IllegalArgumentException(
                 "Chain id or mapping must not be null.");
       }
-      for (int[] map : mapping.values())
+
+      List<Integer> notFound = new ArrayList<Integer>();
+      for (Entry<Integer, int[]> map : mapping.entrySet())
       {
-        if (map[PDB_RES_POS] != UNASSIGNED)
+        int structureResNo = map.getValue()[PDB_RES_POS];
+
+        /*
+         * find the atom number in the chain for this residue number
+         * NB only CA or P atoms have been saved in the chain - see
+         * JmolParser.convertSignificantAtoms
+         */
+        int atomIndex = getAtomIndex(structureResNo, chain.atoms);
+        if (atomIndex == StructureMapping.UNASSIGNED)
+        {
+          notFound.add(map.getKey());
+        }
+        else
         {
-          map[PDB_ATOM_POS] = getAtomIndex(map[PDB_RES_POS], chain.atoms);
+          map.getValue()[PDB_ATOM_POS] = atomIndex;
         }
       }
+      for (Integer missing : notFound)
+      {
+        mapping.remove(missing);
+      }
     } catch (Exception e)
     {
       throw new StructureMappingException(
@@ -71,7 +99,7 @@ public abstract class StructureMappingClient
         return atom.atomIndex;
       }
     }
-    return UNASSIGNED;
+    return StructureMapping.UNASSIGNED;
   }
 
   public class StructureMappingException extends Exception