2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2006 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.SequenceI;
22 import java.util.Vector;
23 public class ModellerDescription
26 * Translates between a String containing a set of colon-separated values
27 * on a single line, and sequence start/end and other properties.
28 * See PIRFile IO for its use.
30 final String[] seqTypes =
32 "sequence", "structure", "structureX", "structureN"};
33 final String[] Fields =
35 "objectType", "objectId",
36 "startField", "startCode",
37 "endField", "endCode",
38 "description1", "description2",
39 "resolutionField", "tailField"};
41 final int LOCALID = 1;
43 final int START_CHAIN = 3;
45 final int END_CHAIN = 5;
46 final int DESCRIPTION1 = 6;
47 final int DESCRIPTION2 = 7;
48 final int RESOLUTION = 8;
52 * 0 is free text or empty
53 * 1 is something that parses to an integer, or \@
57 0, 0, 1, 0, 1, 0, 0, 0, 0, 0
59 final char Padding[] =
61 ' ', ' ', ' ', '.', ' ', '.', '.', '.', '.', '.'
64 java.util.Hashtable fields = new java.util.Hashtable();
67 fields.put(Fields[TAIL], "");
74 resCode(String f, Integer v)
83 field = val.toString();
87 private resCode validResidueCode(String field)
90 com.stevesoft.pat.Regex r = new com.stevesoft.pat.Regex("\\s*((([-0-9]+).?)|FIRST|LAST|@)");
94 return null; // invalid
96 String value = r.stringMatched(3);
99 value = r.stringMatched(1);
101 // jalview.bin.Cache.log.debug("from '" + field + "' matched '" + value +
105 val = Integer.valueOf(value);
106 return new resCode(field, val); // successful numeric extraction
111 return new resCode(field, null);
114 private java.util.Hashtable parseDescription(String desc)
116 java.util.Hashtable fields = new java.util.Hashtable();
117 java.util.StringTokenizer st = new java.util.StringTokenizer(desc, ":");
120 if (st.countTokens() > 0)
122 // parse colon-fields
124 field = st.nextToken(":");
127 if (seqTypes[i].equalsIgnoreCase(field) )
132 while (++i < seqTypes.length);
134 if (i < seqTypes.length)
136 // valid seqType for modeller
138 i = 1; // continue parsing fields
139 while (i < TAIL && st.hasMoreTokens())
141 if ( (field = st.nextToken(":")) != null)
143 // validate residue field value
146 resCode val = validResidueCode(field);
149 fields.put(new String(Fields[i] + "num"), val);
153 // jalview.bin.Cache.log.debug(
154 // "Ignoring non-Modeller description: invalid integer-like field '" + field + "'");
155 type = -1; /* invalid field! - throw the FieldSet away */
159 fields.put(Fields[i++], field);
164 // slurp remaining fields
165 while (st.hasMoreTokens())
167 field += ":" + st.nextToken(":");
169 fields.put(Fields[TAIL], field);
175 // object is not a proper ModellerPIR object
176 fields = new java.util.Hashtable();
177 fields.put(Fields[TAIL], new String(desc));
181 fields.put(Fields[TYPE], seqTypes[type]);
186 ModellerDescription(String desc)
192 fields = parseDescription(desc);
195 void setStartCode(int v)
198 fields.put(Fields[START] + "num", r = new resCode(v));
199 fields.put(Fields[START], r.field);
202 void setEndCode(int v)
205 fields.put(Fields[END] + "num", r = new resCode(v));
206 fields.put(Fields[END], r.field);
210 * make a possibly updated modeller field line for the sequence object
211 * @param seq SequenceI
213 ModellerDescription(SequenceI seq)
216 if (seq.getDescription() != null)
218 fields = parseDescription(seq.getDescription());
221 if (isModellerFieldset())
223 // Set start and end before we update the type (in the case of a synthesized field set)
224 if (getStartNum() != seq.getStart() && getStartCode().val != null)
226 setStartCode(seq.getStart());
229 if (getEndNum() != seq.getEnd() && getStartCode().val != null)
231 setEndCode(seq.getEnd());
237 setStartCode(seq.getStart());
238 setEndCode(seq.getEnd());
239 fields.put(Fields[LOCALID], seq.getName()); // this may be overwritten below...
240 // type - decide based on evidence of PDB database references - this also sets the local reference field
241 int t = 0; // sequence
242 if (seq.getDatasetSequence() != null &&
243 seq.getDatasetSequence().getDBRef() != null)
245 jalview.datamodel.DBRefEntry [] dbr = seq.getDatasetSequence().getDBRef();
247 for (i = 0, j = dbr.length; i < j; i++)
251 // JBPNote PDB dbRefEntry needs properties to propagate onto ModellerField
252 // JBPNote Need to get info from the user about whether the sequence is the one being modelled, or if it is a template.
253 if (dbr[i].getSource().equals(jalview.datamodel.DBRefSource.PDB))
255 fields.put(Fields[LOCALID], dbr[i].getAccessionId());
262 fields.put(Fields[TYPE], seqTypes[t]);
268 * Indicate if fields parsed to a modeller-like colon-separated value line
271 boolean isModellerFieldset()
273 return (fields.containsKey(Fields[TYPE]));
276 String getDescriptionLine()
279 int lastfield = Fields.length - 1;
281 if (isModellerFieldset())
284 // try to write a minimal modeller field set, so..
286 // find the last valid field in the entry
288 for (; lastfield > 6; lastfield--)
290 if (fields.containsKey(Fields[lastfield]))
296 for (int i = 0; i < lastfield; i++)
298 value = (String) fields.get(Fields[i]);
299 if (value != null && value.length() > 0)
301 desc += ( (String) fields.get(Fields[i])) + ":";
305 desc += Padding[i] + ":";
309 // just return the last field if no others were defined.
310 if (fields.containsKey(Fields[lastfield]))
312 desc += (String) fields.get(Fields[lastfield]);
324 resCode val = getStartCode();
327 return val.val.intValue();
332 resCode getStartCode()
334 if (isModellerFieldset() && fields.containsKey(Fields[START] + "num"))
336 return (resCode) fields.get(Fields[START] + "num");
343 if (isModellerFieldset() && fields.containsKey(Fields[END] + "num"))
345 return (resCode) fields.get(Fields[END] + "num");
353 resCode val = getEndCode();
356 return val.val.intValue();
362 * returns true if sequence object was modifed with a valid modellerField set
363 * @param newSeq SequenceI
366 boolean updateSequenceI(SequenceI newSeq)
368 if (isModellerFieldset())
370 if (getStartCode().val != null)
372 newSeq.setStart(getStartNum());
378 if (getEndCode().val != null)
380 newSeq.setEnd(getEndNum());
384 newSeq.setEnd(newSeq.getStart() + newSeq.getLength());