3 import jalview.datamodel.SequenceI;
4 import java.util.Vector;
5 import com.stevesoft.pat.Regex;
6 public class ModellerDescription
9 * Translates between a String containing a set of colon-separated values
10 * on a single line, and sequence start/end and other properties.
11 * See PIRFile IO for its use.
13 final String[] seqTypes =
15 "sequence", "structure", "structureX", "structureN"};
16 final String[] Fields =
18 "objectType", "objectId",
19 "startField", "startCode",
20 "endField", "endCode",
21 "description1", "description2",
22 "resolutionField", "tailField"};
24 final int LOCALID = 1;
26 final int START_CHAIN = 3;
28 final int END_CHAIN = 5;
29 final int DESCRIPTION1 = 6;
30 final int DESCRIPTION2 = 7;
31 final int RESOLUTION = 8;
35 * 0 is free text or empty
36 * 1 is something that parses to an integer, or \@
40 0, 0, 1, 0, 1, 0, 0, 0, 0, 0
42 final char Padding[] =
44 ' ', ' ', ' ', '.', ' ', '.', '.', '.', '.', '.'
47 java.util.Hashtable fields = new java.util.Hashtable();
50 fields.put(Fields[TAIL], "");
57 resCode(String f, Integer v)
66 field = val.toString();
70 private resCode validResidueCode(String field)
73 com.stevesoft.pat.Regex r = new Regex("\\s*((([-0-9]+).?)|FIRST|LAST|@)");
77 return null; // invalid
79 String value = r.stringMatched(3);
82 value = r.stringMatched(1);
84 jalview.bin.Cache.log.debug("from '" + field + "' matched '" + value +
88 val = Integer.valueOf(value);
89 return new resCode(field, val); // successful numeric extraction
94 return new resCode(field, null);
97 private java.util.Hashtable parseDescription(String desc)
99 java.util.Hashtable fields = new java.util.Hashtable();
100 java.util.StringTokenizer st = new java.util.StringTokenizer(desc, ":");
103 if (st.countTokens() > 0)
105 // parse colon-fields
107 field = st.nextToken(":");
110 if (seqTypes[i].compareToIgnoreCase(field) == 0)
115 while (++i < seqTypes.length);
117 if (i < seqTypes.length)
119 // valid seqType for modeller
121 i = 1; // continue parsing fields
122 while (i < TAIL && st.hasMoreTokens())
124 if ( (field = st.nextToken(":")) != null)
126 // validate residue field value
129 resCode val = validResidueCode(field);
132 fields.put(new String(Fields[i] + "num"), val);
136 jalview.bin.Cache.log.debug(
137 "Ignoring non-Modeller description: invalid integer-like field '" + field + "'");
138 type = -1; /* invalid field! - throw the FieldSet away */
142 fields.put(Fields[i++], field);
147 // slurp remaining fields
148 while (st.hasMoreTokens())
150 field += ":" + st.nextToken(":");
152 fields.put(Fields[TAIL], field);
158 // object is not a proper ModellerPIR object
159 fields = new java.util.Hashtable();
160 fields.put(Fields[TAIL], new String(desc));
164 fields.put(Fields[TYPE], seqTypes[type]);
169 ModellerDescription(String desc)
175 fields = parseDescription(desc);
178 void setStartCode(int v)
181 fields.put(Fields[START] + "num", r = new resCode(v));
182 fields.put(Fields[START], r.field);
185 void setEndCode(int v)
188 fields.put(Fields[END] + "num", r = new resCode(v));
189 fields.put(Fields[END], r.field);
193 * make a possibly updated modeller field line for the sequence object
194 * @param seq SequenceI
196 ModellerDescription(SequenceI seq)
199 if (seq.getDescription() != null)
201 fields = parseDescription(seq.getDescription());
204 if (isModellerFieldset())
206 // Set start and end before we update the type (in the case of a synthesized field set)
207 if (getStartNum() != seq.getStart() && getStartCode().val != null)
209 setStartCode(seq.getStart());
212 if (getEndNum() != seq.getEnd() && getStartCode().val != null)
214 setEndCode(seq.getEnd());
220 setStartCode(seq.getStart());
221 setEndCode(seq.getEnd());
222 fields.put(Fields[LOCALID], seq.getName()); // this may be overwritten below...
223 // type - decide based on evidence of PDB database references - this also sets the local reference field
224 int t = 0; // sequence
225 if (seq.getDatasetSequence() != null &&
226 seq.getDatasetSequence().getDBRef() != null)
228 Vector dbr = seq.getDatasetSequence().getDBRef();
230 for (i = 0, j = dbr.size(); i < j; i++)
232 jalview.datamodel.DBRefEntry dref = (jalview.datamodel.DBRefEntry)
236 // JBPNote PDB dbRefEntry needs properties to propagate onto ModellerField
237 // JBPNote Need to get info from the user about whether the sequence is the one being modelled, or if it is a template.
238 if (dref.getSource().equals("PDB"))
240 fields.put(Fields[LOCALID], dref.getAccessionId());
247 fields.put(Fields[TYPE], seqTypes[t]);
253 * Indicate if fields parsed to a modeller-like colon-separated value line
256 boolean isModellerFieldset()
258 return (fields.containsKey(Fields[TYPE]));
261 String getDescriptionLine()
264 int lastfield = Fields.length - 1;
266 if (isModellerFieldset())
269 // try to write a minimal modeller field set, so..
271 // find the last valid field in the entry
273 for (; lastfield > 6; lastfield--)
275 if (fields.containsKey(Fields[lastfield]))
281 for (int i = 0; i < lastfield; i++)
283 value = (String) fields.get(Fields[i]);
284 if (value != null && value.length() > 0)
286 desc += ( (String) fields.get(Fields[i])) + ":";
290 desc += Padding[i] + ":";
294 // just return the last field if no others were defined.
295 if (fields.containsKey(Fields[lastfield]))
297 desc += (String) fields.get(Fields[lastfield]);
309 resCode val = getStartCode();
312 return val.val.intValue();
317 resCode getStartCode()
319 if (isModellerFieldset() && fields.containsKey(Fields[START] + "num"))
321 return (resCode) fields.get(Fields[START] + "num");
328 if (isModellerFieldset() && fields.containsKey(Fields[END] + "num"))
330 return (resCode) fields.get(Fields[END] + "num");
338 resCode val = getEndCode();
341 return val.val.intValue();
347 * returns true if sequence object was modifed with a valid modellerField set
348 * @param newSeq SequenceI
351 boolean updateSequenceI(SequenceI newSeq)
353 if (isModellerFieldset())
355 if (getStartCode().val != null)
357 newSeq.setStart(getStartNum());
363 if (getEndCode().val != null)
365 newSeq.setEnd(getEndNum());
369 newSeq.setEnd(newSeq.getStart() + newSeq.getLength());