-package jalview.io;
-
-import jalview.datamodel.SequenceI;
-import java.util.Vector;
-import com.stevesoft.pat.Regex;
-public class ModellerDescription
-{
- /**
- * Translates between a String containing a set of colon-separated values
- * on a single line, and sequence start/end and other properties.
- * See PIRFile IO for its use.
- */
- final String[] seqTypes =
- {
- "sequence", "structure", "structureX", "structureN"};
- final String[] Fields =
- {
- "objectType", "objectId",
- "startField", "startCode",
- "endField", "endCode",
- "description1", "description2",
- "resolutionField", "tailField"};
- final int TYPE = 0;
- final int LOCALID = 1;
- final int START = 2;
- final int START_CHAIN = 3;
- final int END = 4;
- final int END_CHAIN = 5;
- final int DESCRIPTION1 = 6;
- final int DESCRIPTION2 = 7;
- final int RESOLUTION = 8;
- final int TAIL = 9;
-
- /**
- * 0 is free text or empty
- * 1 is something that parses to an integer, or \@
- */
- final int Types[] =
- {
- 0, 0, 1, 0, 1, 0, 0, 0, 0, 0
- };
- final char Padding[] =
- {
- ' ', ' ', ' ', '.', ' ', '.', '.', '.', '.', '.'
- };
-
- java.util.Hashtable fields = new java.util.Hashtable();
- ModellerDescription()
- {
- fields.put(Fields[TAIL], "");
- }
-
- class resCode
- {
- Integer val;
- String field;
- resCode(String f, Integer v)
- {
- val = v;
- field = f;
- }
-
- resCode(int v)
- {
- val = new Integer(v);
- field = val.toString();
- }
- };
-
- private resCode validResidueCode(String field)
- {
- Integer val = null;
- com.stevesoft.pat.Regex r = new Regex("\\s*((([-0-9]+).?)|FIRST|LAST|@)");
-
- if (!r.search(field))
- {
- return null; // invalid
- }
- String value = r.stringMatched(3);
- if (value == null)
- {
- value = r.stringMatched(1);
- }
- jalview.bin.Cache.log.debug("from '" + field + "' matched '" + value +
- "'");
- try
- {
- val = Integer.valueOf(value);
- return new resCode(field, val); // successful numeric extraction
- }
- catch (Exception e)
- {
- }
- return new resCode(field, null);
- }
-
- private java.util.Hashtable parseDescription(String desc)
- {
- java.util.Hashtable fields = new java.util.Hashtable();
- java.util.StringTokenizer st = new java.util.StringTokenizer(desc, ":");
- String field;
- int type = -1;
- if (st.countTokens() > 0)
- {
- // parse colon-fields
- int i = 0;
- field = st.nextToken(":");
- do
- {
- if (seqTypes[i].compareToIgnoreCase(field) == 0)
- {
- break;
- }
- }
- while (++i < seqTypes.length);
-
- if (i < seqTypes.length)
- {
- // valid seqType for modeller
- type = i;
- i = 1; // continue parsing fields
- while (i < TAIL && st.hasMoreTokens())
- {
- if ( (field = st.nextToken(":")) != null)
- {
- // validate residue field value
- if (Types[i] == 1)
- {
- resCode val = validResidueCode(field);
- if (val != null)
- {
- fields.put(new String(Fields[i] + "num"), val);
- }
- else
- {
- jalview.bin.Cache.log.debug(
- "Ignoring non-Modeller description: invalid integer-like field '" + field + "'");
- type = -1; /* invalid field! - throw the FieldSet away */
- }
- ;
- }
- fields.put(Fields[i++], field);
- }
- }
- if (i == TAIL)
- {
- // slurp remaining fields
- while (st.hasMoreTokens())
- {
- field += ":" + st.nextToken(":");
- }
- fields.put(Fields[TAIL], field);
- }
- }
- }
- if (type == -1)
- {
- // object is not a proper ModellerPIR object
- fields = new java.util.Hashtable();
- fields.put(Fields[TAIL], new String(desc));
- }
- else
- {
- fields.put(Fields[TYPE], seqTypes[type]);
- }
- return fields;
- }
-
- ModellerDescription(String desc)
- {
- if (desc == null)
- {
- desc = "";
- }
- fields = parseDescription(desc);
- }
-
- void setStartCode(int v)
- {
- resCode r;
- fields.put(Fields[START] + "num", r = new resCode(v));
- fields.put(Fields[START], r.field);
- }
-
- void setEndCode(int v)
- {
- resCode r;
- fields.put(Fields[END] + "num", r = new resCode(v));
- fields.put(Fields[END], r.field);
- }
-
- /**
- * make a possibly updated modeller field line for the sequence object
- * @param seq SequenceI
- */
- ModellerDescription(SequenceI seq)
- {
-
- if (seq.getDescription() != null)
- {
- fields = parseDescription(seq.getDescription());
- }
-
- if (isModellerFieldset())
- {
- // Set start and end before we update the type (in the case of a synthesized field set)
- if (getStartNum() != seq.getStart() && getStartCode().val != null)
- {
- setStartCode(seq.getStart());
- }
-
- if (getEndNum() != seq.getEnd() && getStartCode().val != null)
- {
- setEndCode(seq.getEnd());
- }
- }
- else
- {
- // synthesize fields
- setStartCode(seq.getStart());
- setEndCode(seq.getEnd());
- fields.put(Fields[LOCALID], seq.getName()); // this may be overwritten below...
- // type - decide based on evidence of PDB database references - this also sets the local reference field
- int t = 0; // sequence
- if (seq.getDatasetSequence() != null &&
- seq.getDatasetSequence().getDBRef() != null)
- {
- Vector dbr = seq.getDatasetSequence().getDBRef();
- int i, j;
- for (i = 0, j = dbr.size(); i < j; i++)
- {
- jalview.datamodel.DBRefEntry dref = (jalview.datamodel.DBRefEntry)
- dbr.get(i);
- if (dref != null)
- {
- // JBPNote PDB dbRefEntry needs properties to propagate onto ModellerField
- // JBPNote Need to get info from the user about whether the sequence is the one being modelled, or if it is a template.
- if (dref.getSource().equals("PDB"))
- {
- fields.put(Fields[LOCALID], dref.getAccessionId());
- t = 2;
- break;
- }
- }
- }
- }
- fields.put(Fields[TYPE], seqTypes[t]);
- }
-
- }
-
- /**
- * Indicate if fields parsed to a modeller-like colon-separated value line
- * @return boolean
- */
- boolean isModellerFieldset()
- {
- return (fields.containsKey(Fields[TYPE]));
- }
-
- String getDescriptionLine()
- {
- String desc = "";
- int lastfield = Fields.length - 1;
-
- if (isModellerFieldset())
- {
- String value;
- // try to write a minimal modeller field set, so..
-
- // find the last valid field in the entry
-
- for (; lastfield > 6; lastfield--)
- {
- if (fields.containsKey(Fields[lastfield]))
- {
- break;
- }
- }
-
- for (int i = 0; i < lastfield; i++)
- {
- value = (String) fields.get(Fields[i]);
- if (value != null && value.length() > 0)
- {
- desc += ( (String) fields.get(Fields[i])) + ":";
- }
- else
- {
- desc += Padding[i] + ":";
- }
- }
- }
- // just return the last field if no others were defined.
- if (fields.containsKey(Fields[lastfield]))
- {
- desc += (String) fields.get(Fields[lastfield]);
- }
- else
- {
- desc += ".";
- }
- return desc;
- }
-
- int getStartNum()
- {
- int start = 0;
- resCode val = getStartCode();
- if (val.val != null)
- {
- return val.val.intValue();
- }
- return start;
- }
-
- resCode getStartCode()
- {
- if (isModellerFieldset() && fields.containsKey(Fields[START] + "num"))
- {
- return (resCode) fields.get(Fields[START] + "num");
- }
- return null;
- }
-
- resCode getEndCode()
- {
- if (isModellerFieldset() && fields.containsKey(Fields[END] + "num"))
- {
- return (resCode) fields.get(Fields[END] + "num");
- }
- return null;
- }
-
- int getEndNum()
- {
- int end = 0;
- resCode val = getEndCode();
- if (val.val != null)
- {
- return val.val.intValue();
- }
- return end;
- }
-
- /**
- * returns true if sequence object was modifed with a valid modellerField set
- * @param newSeq SequenceI
- * @return boolean
- */
- boolean updateSequenceI(SequenceI newSeq)
- {
- if (isModellerFieldset())
- {
- if (getStartCode().val != null)
- {
- newSeq.setStart(getStartNum());
- }
- else
- {
- newSeq.setStart(1);
- }
- if (getEndCode().val != null)
- {
- newSeq.setEnd(getEndNum());
- }
- else
- {
- newSeq.setEnd(newSeq.getStart() + newSeq.getLength());
- }
- return true;
- }
- return false;
- }
-}
-
+package jalview.io;\r
+\r
+import jalview.datamodel.SequenceI;\r
+import java.util.Vector;\r
+import com.stevesoft.pat.Regex;\r
+public class ModellerDescription\r
+{\r
+ /**\r
+ * Translates between a String containing a set of colon-separated values\r
+ * on a single line, and sequence start/end and other properties.\r
+ * See PIRFile IO for its use.\r
+ */\r
+ final String[] seqTypes =\r
+ {\r
+ "sequence", "structure", "structureX", "structureN"};\r
+ final String[] Fields =\r
+ {\r
+ "objectType", "objectId",\r
+ "startField", "startCode",\r
+ "endField", "endCode",\r
+ "description1", "description2",\r
+ "resolutionField", "tailField"};\r
+ final int TYPE = 0;\r
+ final int LOCALID = 1;\r
+ final int START = 2;\r
+ final int START_CHAIN = 3;\r
+ final int END = 4;\r
+ final int END_CHAIN = 5;\r
+ final int DESCRIPTION1 = 6;\r
+ final int DESCRIPTION2 = 7;\r
+ final int RESOLUTION = 8;\r
+ final int TAIL = 9;\r
+\r
+ /**\r
+ * 0 is free text or empty\r
+ * 1 is something that parses to an integer, or \@\r
+ */\r
+ final int Types[] =\r
+ {\r
+ 0, 0, 1, 0, 1, 0, 0, 0, 0, 0\r
+ };\r
+ final char Padding[] =\r
+ {\r
+ ' ', ' ', ' ', '.', ' ', '.', '.', '.', '.', '.'\r
+ };\r
+\r
+ java.util.Hashtable fields = new java.util.Hashtable();\r
+ ModellerDescription()\r
+ {\r
+ fields.put(Fields[TAIL], "");\r
+ }\r
+\r
+ class resCode\r
+ {\r
+ Integer val;\r
+ String field;\r
+ resCode(String f, Integer v)\r
+ {\r
+ val = v;\r
+ field = f;\r
+ }\r
+\r
+ resCode(int v)\r
+ {\r
+ val = new Integer(v);\r
+ field = val.toString();\r
+ }\r
+ };\r
+\r
+ private resCode validResidueCode(String field)\r
+ {\r
+ Integer val = null;\r
+ com.stevesoft.pat.Regex r = new Regex("\\s*((([-0-9]+).?)|FIRST|LAST|@)");\r
+\r
+ if (!r.search(field))\r
+ {\r
+ return null; // invalid\r
+ }\r
+ String value = r.stringMatched(3);\r
+ if (value == null)\r
+ {\r
+ value = r.stringMatched(1);\r
+ }\r
+ // jalview.bin.Cache.log.debug("from '" + field + "' matched '" + value +\r
+ // "'");\r
+ try\r
+ {\r
+ val = Integer.valueOf(value);\r
+ return new resCode(field, val); // successful numeric extraction\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ }\r
+ return new resCode(field, null);\r
+ }\r
+\r
+ private java.util.Hashtable parseDescription(String desc)\r
+ {\r
+ java.util.Hashtable fields = new java.util.Hashtable();\r
+ java.util.StringTokenizer st = new java.util.StringTokenizer(desc, ":");\r
+ String field;\r
+ int type = -1;\r
+ if (st.countTokens() > 0)\r
+ {\r
+ // parse colon-fields\r
+ int i = 0;\r
+ field = st.nextToken(":");\r
+ do\r
+ {\r
+ if (seqTypes[i].equalsIgnoreCase(field) )\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ while (++i < seqTypes.length);\r
+\r
+ if (i < seqTypes.length)\r
+ {\r
+ // valid seqType for modeller\r
+ type = i;\r
+ i = 1; // continue parsing fields\r
+ while (i < TAIL && st.hasMoreTokens())\r
+ {\r
+ if ( (field = st.nextToken(":")) != null)\r
+ {\r
+ // validate residue field value\r
+ if (Types[i] == 1)\r
+ {\r
+ resCode val = validResidueCode(field);\r
+ if (val != null)\r
+ {\r
+ fields.put(new String(Fields[i] + "num"), val);\r
+ }\r
+ else\r
+ {\r
+ // jalview.bin.Cache.log.debug(\r
+ // "Ignoring non-Modeller description: invalid integer-like field '" + field + "'");\r
+ type = -1; /* invalid field! - throw the FieldSet away */\r
+ }\r
+ ;\r
+ }\r
+ fields.put(Fields[i++], field);\r
+ }\r
+ }\r
+ if (i == TAIL)\r
+ {\r
+ // slurp remaining fields\r
+ while (st.hasMoreTokens())\r
+ {\r
+ field += ":" + st.nextToken(":");\r
+ }\r
+ fields.put(Fields[TAIL], field);\r
+ }\r
+ }\r
+ }\r
+ if (type == -1)\r
+ {\r
+ // object is not a proper ModellerPIR object\r
+ fields = new java.util.Hashtable();\r
+ fields.put(Fields[TAIL], new String(desc));\r
+ }\r
+ else\r
+ {\r
+ fields.put(Fields[TYPE], seqTypes[type]);\r
+ }\r
+ return fields;\r
+ }\r
+\r
+ ModellerDescription(String desc)\r
+ {\r
+ if (desc == null)\r
+ {\r
+ desc = "";\r
+ }\r
+ fields = parseDescription(desc);\r
+ }\r
+\r
+ void setStartCode(int v)\r
+ {\r
+ resCode r;\r
+ fields.put(Fields[START] + "num", r = new resCode(v));\r
+ fields.put(Fields[START], r.field);\r
+ }\r
+\r
+ void setEndCode(int v)\r
+ {\r
+ resCode r;\r
+ fields.put(Fields[END] + "num", r = new resCode(v));\r
+ fields.put(Fields[END], r.field);\r
+ }\r
+\r
+ /**\r
+ * make a possibly updated modeller field line for the sequence object\r
+ * @param seq SequenceI\r
+ */\r
+ ModellerDescription(SequenceI seq)\r
+ {\r
+\r
+ if (seq.getDescription() != null)\r
+ {\r
+ fields = parseDescription(seq.getDescription());\r
+ }\r
+\r
+ if (isModellerFieldset())\r
+ {\r
+ // Set start and end before we update the type (in the case of a synthesized field set)\r
+ if (getStartNum() != seq.getStart() && getStartCode().val != null)\r
+ {\r
+ setStartCode(seq.getStart());\r
+ }\r
+\r
+ if (getEndNum() != seq.getEnd() && getStartCode().val != null)\r
+ {\r
+ setEndCode(seq.getEnd());\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // synthesize fields\r
+ setStartCode(seq.getStart());\r
+ setEndCode(seq.getEnd());\r
+ fields.put(Fields[LOCALID], seq.getName()); // this may be overwritten below...\r
+ // type - decide based on evidence of PDB database references - this also sets the local reference field\r
+ int t = 0; // sequence\r
+ if (seq.getDatasetSequence() != null &&\r
+ seq.getDatasetSequence().getDBRef() != null)\r
+ {\r
+ Vector dbr = seq.getDatasetSequence().getDBRef();\r
+ int i, j;\r
+ for (i = 0, j = dbr.size(); i < j; i++)\r
+ {\r
+ jalview.datamodel.DBRefEntry dref = (jalview.datamodel.DBRefEntry)\r
+ dbr.elementAt(i);\r
+ if (dref != null)\r
+ {\r
+ // JBPNote PDB dbRefEntry needs properties to propagate onto ModellerField\r
+ // JBPNote Need to get info from the user about whether the sequence is the one being modelled, or if it is a template.\r
+ if (dref.getSource().equals("PDB"))\r
+ {\r
+ fields.put(Fields[LOCALID], dref.getAccessionId());\r
+ t = 2;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ fields.put(Fields[TYPE], seqTypes[t]);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Indicate if fields parsed to a modeller-like colon-separated value line\r
+ * @return boolean\r
+ */\r
+ boolean isModellerFieldset()\r
+ {\r
+ return (fields.containsKey(Fields[TYPE]));\r
+ }\r
+\r
+ String getDescriptionLine()\r
+ {\r
+ String desc = "";\r
+ int lastfield = Fields.length - 1;\r
+\r
+ if (isModellerFieldset())\r
+ {\r
+ String value;\r
+ // try to write a minimal modeller field set, so..\r
+\r
+ // find the last valid field in the entry\r
+\r
+ for (; lastfield > 6; lastfield--)\r
+ {\r
+ if (fields.containsKey(Fields[lastfield]))\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ for (int i = 0; i < lastfield; i++)\r
+ {\r
+ value = (String) fields.get(Fields[i]);\r
+ if (value != null && value.length() > 0)\r
+ {\r
+ desc += ( (String) fields.get(Fields[i])) + ":";\r
+ }\r
+ else\r
+ {\r
+ desc += Padding[i] + ":";\r
+ }\r
+ }\r
+ }\r
+ // just return the last field if no others were defined.\r
+ if (fields.containsKey(Fields[lastfield]))\r
+ {\r
+ desc += (String) fields.get(Fields[lastfield]);\r
+ }\r
+ else\r
+ {\r
+ desc += ".";\r
+ }\r
+ return desc;\r
+ }\r
+\r
+ int getStartNum()\r
+ {\r
+ int start = 0;\r
+ resCode val = getStartCode();\r
+ if (val.val != null)\r
+ {\r
+ return val.val.intValue();\r
+ }\r
+ return start;\r
+ }\r
+\r
+ resCode getStartCode()\r
+ {\r
+ if (isModellerFieldset() && fields.containsKey(Fields[START] + "num"))\r
+ {\r
+ return (resCode) fields.get(Fields[START] + "num");\r
+ }\r
+ return null;\r
+ }\r
+\r
+ resCode getEndCode()\r
+ {\r
+ if (isModellerFieldset() && fields.containsKey(Fields[END] + "num"))\r
+ {\r
+ return (resCode) fields.get(Fields[END] + "num");\r
+ }\r
+ return null;\r
+ }\r
+\r
+ int getEndNum()\r
+ {\r
+ int end = 0;\r
+ resCode val = getEndCode();\r
+ if (val.val != null)\r
+ {\r
+ return val.val.intValue();\r
+ }\r
+ return end;\r
+ }\r
+\r
+ /**\r
+ * returns true if sequence object was modifed with a valid modellerField set\r
+ * @param newSeq SequenceI\r
+ * @return boolean\r
+ */\r
+ boolean updateSequenceI(SequenceI newSeq)\r
+ {\r
+ if (isModellerFieldset())\r
+ {\r
+ if (getStartCode().val != null)\r
+ {\r
+ newSeq.setStart(getStartNum());\r
+ }\r
+ else\r
+ {\r
+ newSeq.setStart(1);\r
+ }\r
+ if (getEndCode().val != null)\r
+ {\r
+ newSeq.setEnd(getEndNum());\r
+ }\r
+ else\r
+ {\r
+ newSeq.setEnd(newSeq.getStart() + newSeq.getLength());\r
+ }\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+}\r
+\r