2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
3 * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import jalview.datamodel.*;
22 public class ModellerDescription
25 * Translates between a String containing a set of colon-separated values on a
26 * single line, and sequence start/end and other properties. See PIRFile IO
29 final String[] seqTypes =
30 { "sequence", "structure", "structureX", "structureN" };
32 final String[] Fields =
33 { "objectType", "objectId", "startField", "startCode", "endField",
34 "endCode", "description1", "description2", "resolutionField",
39 final int LOCALID = 1;
43 final int START_CHAIN = 3;
47 final int END_CHAIN = 5;
49 final int DESCRIPTION1 = 6;
51 final int DESCRIPTION2 = 7;
53 final int RESOLUTION = 8;
58 * 0 is free text or empty 1 is something that parses to an integer, or \@
61 { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 };
63 final char Padding[] =
64 { ' ', ' ', ' ', '.', ' ', '.', '.', '.', '.', '.' };
66 java.util.Hashtable fields = new java.util.Hashtable();
70 fields.put(Fields[TAIL], "");
79 resCode(String f, Integer v)
88 field = val.toString();
92 private resCode validResidueCode(String field)
95 com.stevesoft.pat.Regex r = new com.stevesoft.pat.Regex(
96 "\\s*((([-0-9]+).?)|FIRST|LAST|@)");
100 return null; // invalid
102 String value = r.stringMatched(3);
105 value = r.stringMatched(1);
107 // jalview.bin.Cache.log.debug("from '" + field + "' matched '" + value +
111 val = Integer.valueOf(value);
112 return new resCode(field, val); // successful numeric extraction
113 } catch (Exception e)
116 return new resCode(field, null);
119 private java.util.Hashtable parseDescription(String desc)
121 java.util.Hashtable fields = new java.util.Hashtable();
122 java.util.StringTokenizer st = new java.util.StringTokenizer(desc, ":");
125 if (st.countTokens() > 0)
127 // parse colon-fields
129 field = st.nextToken(":");
132 if (seqTypes[i].equalsIgnoreCase(field))
136 } while (++i < seqTypes.length);
138 if (i < seqTypes.length)
140 // valid seqType for modeller
142 i = 1; // continue parsing fields
143 while (i < TAIL && st.hasMoreTokens())
145 if ((field = st.nextToken(":")) != null)
147 // validate residue field value
150 resCode val = validResidueCode(field);
153 fields.put(new String(Fields[i] + "num"), val);
157 // jalview.bin.Cache.log.debug(
158 // "Ignoring non-Modeller description: invalid integer-like
159 // field '" + field + "'");
160 type = -1; /* invalid field! - throw the FieldSet away */
164 fields.put(Fields[i++], field);
169 // slurp remaining fields
170 while (st.hasMoreTokens())
172 field += ":" + st.nextToken(":");
174 fields.put(Fields[TAIL], field);
180 // object is not a proper ModellerPIR object
181 fields = new java.util.Hashtable();
182 fields.put(Fields[TAIL], new String(desc));
186 fields.put(Fields[TYPE], seqTypes[type]);
191 ModellerDescription(String desc)
197 fields = parseDescription(desc);
200 void setStartCode(int v)
203 fields.put(Fields[START] + "num", r = new resCode(v));
204 fields.put(Fields[START], r.field);
207 void setEndCode(int v)
210 fields.put(Fields[END] + "num", r = new resCode(v));
211 fields.put(Fields[END], r.field);
215 * make a possibly updated modeller field line for the sequence object
220 ModellerDescription(SequenceI seq)
223 if (seq.getDescription() != null)
225 fields = parseDescription(seq.getDescription());
228 if (isModellerFieldset())
230 // Set start and end before we update the type (in the case of a
231 // synthesized field set)
232 if (getStartNum() != seq.getStart() && getStartCode().val != null)
234 setStartCode(seq.getStart());
237 if (getEndNum() != seq.getEnd() && getStartCode().val != null)
239 setEndCode(seq.getEnd());
245 setStartCode(seq.getStart());
246 setEndCode(seq.getEnd());
247 fields.put(Fields[LOCALID], seq.getName()); // this may be overwritten
249 // type - decide based on evidence of PDB database references - this also
250 // sets the local reference field
251 int t = 0; // sequence
252 if (seq.getDatasetSequence() != null
253 && seq.getDatasetSequence().getDBRef() != null)
255 jalview.datamodel.DBRefEntry[] dbr = seq.getDatasetSequence()
258 for (i = 0, j = dbr.length; i < j; i++)
262 // JBPNote PDB dbRefEntry needs properties to propagate onto
264 // JBPNote Need to get info from the user about whether the sequence
265 // is the one being modelled, or if it is a template.
266 if (dbr[i].getSource()
267 .equals(jalview.datamodel.DBRefSource.PDB))
269 fields.put(Fields[LOCALID], dbr[i].getAccessionId());
276 fields.put(Fields[TYPE], seqTypes[t]);
282 * Indicate if fields parsed to a modeller-like colon-separated value line
286 boolean isModellerFieldset()
288 return (fields.containsKey(Fields[TYPE]));
291 String getDescriptionLine()
294 int lastfield = Fields.length - 1;
296 if (isModellerFieldset())
299 // try to write a minimal modeller field set, so..
301 // find the last valid field in the entry
303 for (; lastfield > 6; lastfield--)
305 if (fields.containsKey(Fields[lastfield]))
311 for (int i = 0; i < lastfield; i++)
313 value = (String) fields.get(Fields[i]);
314 if (value != null && value.length() > 0)
316 desc += ((String) fields.get(Fields[i])) + ":";
320 desc += Padding[i] + ":";
324 // just return the last field if no others were defined.
325 if (fields.containsKey(Fields[lastfield]))
327 desc += (String) fields.get(Fields[lastfield]);
339 resCode val = getStartCode();
342 return val.val.intValue();
347 resCode getStartCode()
349 if (isModellerFieldset() && fields.containsKey(Fields[START] + "num"))
351 return (resCode) fields.get(Fields[START] + "num");
358 if (isModellerFieldset() && fields.containsKey(Fields[END] + "num"))
360 return (resCode) fields.get(Fields[END] + "num");
368 resCode val = getEndCode();
371 return val.val.intValue();
377 * returns true if sequence object was modifed with a valid modellerField set
383 boolean updateSequenceI(SequenceI newSeq)
385 if (isModellerFieldset())
387 if (getStartCode().val != null)
389 newSeq.setStart(getStartNum());
395 if (getEndCode().val != null)
397 newSeq.setEnd(getEndNum());
401 newSeq.setEnd(newSeq.getStart() + newSeq.getLength());