3 import jalview.datamodel.SequenceI;
\r
4 import java.util.Vector;
\r
5 public class ModellerDescription
\r
8 * Translates between a String containing a set of colon-separated values
\r
9 * on a single line, and sequence start/end and other properties.
\r
10 * See PIRFile IO for its use.
\r
12 final String[] seqTypes =
\r
14 "sequence", "structure", "structureX", "structureN"};
\r
15 final String[] Fields =
\r
17 "objectType", "objectId",
\r
18 "startField", "startCode",
\r
19 "endField", "endCode",
\r
20 "description1", "description2",
\r
21 "resolutionField", "tailField"};
\r
23 final int LOCALID = 1;
\r
24 final int START = 2;
\r
25 final int START_CHAIN = 3;
\r
27 final int END_CHAIN = 5;
\r
28 final int DESCRIPTION1 = 6;
\r
29 final int DESCRIPTION2 = 7;
\r
30 final int RESOLUTION = 8;
\r
34 * 0 is free text or empty
\r
35 * 1 is something that parses to an integer, or \@
\r
39 0, 0, 1, 0, 1, 0, 0, 0, 0, 0
\r
41 final char Padding[] =
\r
43 ' ', ' ', ' ', '.', ' ', '.', '.', '.', '.', '.'
\r
46 java.util.Hashtable fields = new java.util.Hashtable();
\r
47 ModellerDescription()
\r
49 fields.put(Fields[TAIL], "");
\r
56 resCode(String f, Integer v)
\r
64 val = new Integer(v);
\r
65 field = val.toString();
\r
69 private resCode validResidueCode(String field)
\r
72 com.stevesoft.pat.Regex r = new com.stevesoft.pat.Regex("\\s*((([-0-9]+).?)|FIRST|LAST|@)");
\r
74 if (!r.search(field))
\r
76 return null; // invalid
\r
78 String value = r.stringMatched(3);
\r
81 value = r.stringMatched(1);
\r
83 // jalview.bin.Cache.log.debug("from '" + field + "' matched '" + value +
\r
87 val = Integer.valueOf(value);
\r
88 return new resCode(field, val); // successful numeric extraction
\r
93 return new resCode(field, null);
\r
96 private java.util.Hashtable parseDescription(String desc)
\r
98 java.util.Hashtable fields = new java.util.Hashtable();
\r
99 java.util.StringTokenizer st = new java.util.StringTokenizer(desc, ":");
\r
102 if (st.countTokens() > 0)
\r
104 // parse colon-fields
\r
106 field = st.nextToken(":");
\r
109 if (seqTypes[i].equalsIgnoreCase(field) )
\r
114 while (++i < seqTypes.length);
\r
116 if (i < seqTypes.length)
\r
118 // valid seqType for modeller
\r
120 i = 1; // continue parsing fields
\r
121 while (i < TAIL && st.hasMoreTokens())
\r
123 if ( (field = st.nextToken(":")) != null)
\r
125 // validate residue field value
\r
128 resCode val = validResidueCode(field);
\r
131 fields.put(new String(Fields[i] + "num"), val);
\r
135 // jalview.bin.Cache.log.debug(
\r
136 // "Ignoring non-Modeller description: invalid integer-like field '" + field + "'");
\r
137 type = -1; /* invalid field! - throw the FieldSet away */
\r
141 fields.put(Fields[i++], field);
\r
146 // slurp remaining fields
\r
147 while (st.hasMoreTokens())
\r
149 field += ":" + st.nextToken(":");
\r
151 fields.put(Fields[TAIL], field);
\r
157 // object is not a proper ModellerPIR object
\r
158 fields = new java.util.Hashtable();
\r
159 fields.put(Fields[TAIL], new String(desc));
\r
163 fields.put(Fields[TYPE], seqTypes[type]);
\r
168 ModellerDescription(String desc)
\r
174 fields = parseDescription(desc);
\r
177 void setStartCode(int v)
\r
180 fields.put(Fields[START] + "num", r = new resCode(v));
\r
181 fields.put(Fields[START], r.field);
\r
184 void setEndCode(int v)
\r
187 fields.put(Fields[END] + "num", r = new resCode(v));
\r
188 fields.put(Fields[END], r.field);
\r
192 * make a possibly updated modeller field line for the sequence object
\r
193 * @param seq SequenceI
\r
195 ModellerDescription(SequenceI seq)
\r
198 if (seq.getDescription() != null)
\r
200 fields = parseDescription(seq.getDescription());
\r
203 if (isModellerFieldset())
\r
205 // Set start and end before we update the type (in the case of a synthesized field set)
\r
206 if (getStartNum() != seq.getStart() && getStartCode().val != null)
\r
208 setStartCode(seq.getStart());
\r
211 if (getEndNum() != seq.getEnd() && getStartCode().val != null)
\r
213 setEndCode(seq.getEnd());
\r
218 // synthesize fields
\r
219 setStartCode(seq.getStart());
\r
220 setEndCode(seq.getEnd());
\r
221 fields.put(Fields[LOCALID], seq.getName()); // this may be overwritten below...
\r
222 // type - decide based on evidence of PDB database references - this also sets the local reference field
\r
223 int t = 0; // sequence
\r
224 if (seq.getDatasetSequence() != null &&
\r
225 seq.getDatasetSequence().getDBRef() != null)
\r
227 jalview.datamodel.DBRefEntry [] dbr = seq.getDatasetSequence().getDBRef();
\r
229 for (i = 0, j = dbr.length; i < j; i++)
\r
231 if (dbr[i] != null)
\r
233 // JBPNote PDB dbRefEntry needs properties to propagate onto ModellerField
\r
234 // JBPNote Need to get info from the user about whether the sequence is the one being modelled, or if it is a template.
\r
235 if (dbr[i].getSource().equals(jalview.datamodel.DBRefSource.PDB))
\r
237 fields.put(Fields[LOCALID], dbr[i].getAccessionId());
\r
244 fields.put(Fields[TYPE], seqTypes[t]);
\r
250 * Indicate if fields parsed to a modeller-like colon-separated value line
\r
253 boolean isModellerFieldset()
\r
255 return (fields.containsKey(Fields[TYPE]));
\r
258 String getDescriptionLine()
\r
261 int lastfield = Fields.length - 1;
\r
263 if (isModellerFieldset())
\r
266 // try to write a minimal modeller field set, so..
\r
268 // find the last valid field in the entry
\r
270 for (; lastfield > 6; lastfield--)
\r
272 if (fields.containsKey(Fields[lastfield]))
\r
278 for (int i = 0; i < lastfield; i++)
\r
280 value = (String) fields.get(Fields[i]);
\r
281 if (value != null && value.length() > 0)
\r
283 desc += ( (String) fields.get(Fields[i])) + ":";
\r
287 desc += Padding[i] + ":";
\r
291 // just return the last field if no others were defined.
\r
292 if (fields.containsKey(Fields[lastfield]))
\r
294 desc += (String) fields.get(Fields[lastfield]);
\r
306 resCode val = getStartCode();
\r
307 if (val.val != null)
\r
309 return val.val.intValue();
\r
314 resCode getStartCode()
\r
316 if (isModellerFieldset() && fields.containsKey(Fields[START] + "num"))
\r
318 return (resCode) fields.get(Fields[START] + "num");
\r
323 resCode getEndCode()
\r
325 if (isModellerFieldset() && fields.containsKey(Fields[END] + "num"))
\r
327 return (resCode) fields.get(Fields[END] + "num");
\r
335 resCode val = getEndCode();
\r
336 if (val.val != null)
\r
338 return val.val.intValue();
\r
344 * returns true if sequence object was modifed with a valid modellerField set
\r
345 * @param newSeq SequenceI
\r
348 boolean updateSequenceI(SequenceI newSeq)
\r
350 if (isModellerFieldset())
\r
352 if (getStartCode().val != null)
\r
354 newSeq.setStart(getStartNum());
\r
358 newSeq.setStart(1);
\r
360 if (getEndCode().val != null)
\r
362 newSeq.setEnd(getEndNum());
\r
366 newSeq.setEnd(newSeq.getStart() + newSeq.getLength());
\r