2 * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
3 * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 import jalview.datamodel.*;
23 public class ModellerDescription
26 * Translates between a String containing a set of colon-separated values on a
27 * single line, and sequence start/end and other properties. See PIRFile IO
30 final String[] seqTypes =
31 { "sequence", "structure", "structureX", "structureN" };
33 final String[] Fields =
34 { "objectType", "objectId", "startField", "startCode", "endField",
35 "endCode", "description1", "description2", "resolutionField",
40 final int LOCALID = 1;
44 final int START_CHAIN = 3;
48 final int END_CHAIN = 5;
50 final int DESCRIPTION1 = 6;
52 final int DESCRIPTION2 = 7;
54 final int RESOLUTION = 8;
59 * 0 is free text or empty 1 is something that parses to an integer, or \@
62 { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 };
64 final char Padding[] =
65 { ' ', ' ', ' ', '.', ' ', '.', '.', '.', '.', '.' };
67 java.util.Hashtable fields = new java.util.Hashtable();
71 fields.put(Fields[TAIL], "");
80 resCode(String f, Integer v)
89 field = val.toString();
93 private resCode validResidueCode(String field)
96 com.stevesoft.pat.Regex r = new com.stevesoft.pat.Regex(
97 "\\s*((([-0-9]+).?)|FIRST|LAST|@)");
101 return null; // invalid
103 String value = r.stringMatched(3);
106 value = r.stringMatched(1);
108 // jalview.bin.Cache.log.debug("from '" + field + "' matched '" + value +
112 val = Integer.valueOf(value);
113 return new resCode(field, val); // successful numeric extraction
114 } catch (Exception e)
117 return new resCode(field, null);
120 private java.util.Hashtable parseDescription(String desc)
122 java.util.Hashtable fields = new java.util.Hashtable();
123 java.util.StringTokenizer st = new java.util.StringTokenizer(desc, ":");
126 if (st.countTokens() > 0)
128 // parse colon-fields
130 field = st.nextToken(":");
133 if (seqTypes[i].equalsIgnoreCase(field))
137 } while (++i < seqTypes.length);
139 if (i < seqTypes.length)
141 // valid seqType for modeller
143 i = 1; // continue parsing fields
144 while (i < TAIL && st.hasMoreTokens())
146 if ((field = st.nextToken(":")) != null)
148 // validate residue field value
151 resCode val = validResidueCode(field);
154 fields.put(new String(Fields[i] + "num"), val);
158 // jalview.bin.Cache.log.debug(
159 // "Ignoring non-Modeller description: invalid integer-like
160 // field '" + field + "'");
161 type = -1; /* invalid field! - throw the FieldSet away */
165 fields.put(Fields[i++], field);
170 // slurp remaining fields
171 while (st.hasMoreTokens())
173 field += ":" + st.nextToken(":");
175 fields.put(Fields[TAIL], field);
181 // object is not a proper ModellerPIR object
182 fields = new java.util.Hashtable();
183 fields.put(Fields[TAIL], new String(desc));
187 fields.put(Fields[TYPE], seqTypes[type]);
192 ModellerDescription(String desc)
198 fields = parseDescription(desc);
201 void setStartCode(int v)
204 fields.put(Fields[START] + "num", r = new resCode(v));
205 fields.put(Fields[START], r.field);
208 void setEndCode(int v)
211 fields.put(Fields[END] + "num", r = new resCode(v));
212 fields.put(Fields[END], r.field);
216 * make a possibly updated modeller field line for the sequence object
221 ModellerDescription(SequenceI seq)
224 if (seq.getDescription() != null)
226 fields = parseDescription(seq.getDescription());
229 if (isModellerFieldset())
231 // Set start and end before we update the type (in the case of a
232 // synthesized field set)
233 if (getStartNum() != seq.getStart() && getStartCode().val != null)
235 setStartCode(seq.getStart());
238 if (getEndNum() != seq.getEnd() && getStartCode().val != null)
240 setEndCode(seq.getEnd());
246 setStartCode(seq.getStart());
247 setEndCode(seq.getEnd());
248 fields.put(Fields[LOCALID], seq.getName()); // this may be overwritten
250 // type - decide based on evidence of PDB database references - this also
251 // sets the local reference field
252 int t = 0; // sequence
253 if (seq.getDatasetSequence() != null
254 && seq.getDatasetSequence().getDBRef() != null)
256 jalview.datamodel.DBRefEntry[] dbr = seq.getDatasetSequence()
259 for (i = 0, j = dbr.length; i < j; i++)
263 // JBPNote PDB dbRefEntry needs properties to propagate onto
265 // JBPNote Need to get info from the user about whether the sequence
266 // is the one being modelled, or if it is a template.
267 if (dbr[i].getSource()
268 .equals(jalview.datamodel.DBRefSource.PDB))
270 fields.put(Fields[LOCALID], dbr[i].getAccessionId());
277 fields.put(Fields[TYPE], seqTypes[t]);
283 * Indicate if fields parsed to a modeller-like colon-separated value line
287 boolean isModellerFieldset()
289 return (fields.containsKey(Fields[TYPE]));
292 String getDescriptionLine()
295 int lastfield = Fields.length - 1;
297 if (isModellerFieldset())
300 // try to write a minimal modeller field set, so..
302 // find the last valid field in the entry
304 for (; lastfield > 6; lastfield--)
306 if (fields.containsKey(Fields[lastfield]))
312 for (int i = 0; i < lastfield; i++)
314 value = (String) fields.get(Fields[i]);
315 if (value != null && value.length() > 0)
317 desc += ((String) fields.get(Fields[i])) + ":";
321 desc += Padding[i] + ":";
325 // just return the last field if no others were defined.
326 if (fields.containsKey(Fields[lastfield]))
328 desc += (String) fields.get(Fields[lastfield]);
340 resCode val = getStartCode();
343 return val.val.intValue();
348 resCode getStartCode()
350 if (isModellerFieldset() && fields.containsKey(Fields[START] + "num"))
352 return (resCode) fields.get(Fields[START] + "num");
359 if (isModellerFieldset() && fields.containsKey(Fields[END] + "num"))
361 return (resCode) fields.get(Fields[END] + "num");
369 resCode val = getEndCode();
372 return val.val.intValue();
378 * returns true if sequence object was modifed with a valid modellerField set
384 boolean updateSequenceI(SequenceI newSeq)
386 if (isModellerFieldset())
388 if (getStartCode().val != null)
390 newSeq.setStart(getStartNum());
396 if (getEndCode().val != null)
398 newSeq.setEnd(getEndNum());
402 newSeq.setEnd(newSeq.getStart() + newSeq.getLength());