Clover icon

Coverage Report

  1. Project Clover database Thu Nov 28 2024 11:45:30 GMT
  2. Package jalview.io

File AlignFile.java

 

Coverage histogram

../../img/srcFileCovDistChart9.png
13% of files have more coverage

Code metrics

32
82
32
1
492
258
51
0.62
2.56
32
1.59

Classes

Class Line # Actions
AlignFile 44 82 51
0.8424657684.2%
 

Contributing tests

This file is covered by 278 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
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
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.io;
22   
23    import java.io.IOException;
24    import java.util.ArrayList;
25    import java.util.Enumeration;
26    import java.util.Hashtable;
27    import java.util.List;
28    import java.util.Vector;
29   
30    import jalview.datamodel.AlignmentAnnotation;
31    import jalview.datamodel.AlignmentI;
32    import jalview.datamodel.Sequence;
33    import jalview.datamodel.SequenceGroup;
34    import jalview.datamodel.SequenceI;
35    import jalview.util.MessageManager;
36    import jalview.util.StringUtils;
37   
38    /**
39    * DOCUMENT ME!
40    *
41    * @author $author$
42    * @version $Revision$
43    */
 
44    public abstract class AlignFile extends FileParse
45    implements AlignmentFileReaderI, AlignmentFileWriterI
46    {
47    int noSeqs = 0;
48   
49    int maxLength = 0;
50   
51    /**
52    * Sequences to be added to form a new alignment. TODO: remove vector in this
53    * class
54    */
55    protected Vector<SequenceI> seqs;
56   
57    /**
58    * annotation to be added to generated alignment object
59    */
60    protected Vector<AlignmentAnnotation> annotations;
61   
62    /**
63    * SequenceGroups to be added to the alignment object
64    */
65    protected List<SequenceGroup> seqGroups;
66   
67    /**
68    * Properties to be added to generated alignment object
69    */
70    private Hashtable properties;
71   
72    long start;
73   
74    long end;
75   
76    /**
77    * true if parse() has been called
78    */
79    private boolean parseCalled = false;
80   
81    private boolean parseImmediately = true;
82   
83    private boolean dataClosed = false;
84   
85    private boolean doXferSettings = true;
86   
87    /**
88    * @return if doParse() was called at construction time
89    */
 
90  175 toggle protected boolean isParseImmediately()
91    {
92  175 return parseImmediately;
93    }
94   
95    /**
96    * Creates a new AlignFile object.
97    */
 
98  226 toggle public AlignFile()
99    {
100    // Shouldn't we init data structures (JBPNote: not sure - initData is for
101    // initialising the structures used for reading from a datasource, and the
102    // bare constructor hasn't got any datasource)
103  226 initData();
104    }
105   
 
106  0 toggle public AlignFile(SequenceI[] seqs)
107    {
108  0 this();
109  0 setSeqs(seqs);
110    }
111   
112    /**
113    * Constructor which parses the data from a file of some specified type.
114    *
115    * @param dataObject
116    * Filename, URL or Pasted String to read from.
117    * @param sourceType
118    * What type of file to read from (File, URL, Pasted String)
119    */
 
120  13 toggle public AlignFile(Object dataObject, DataSourceType sourceType)
121    throws IOException
122    {
123  13 this(true, dataObject, sourceType);
124    }
125   
126    /**
127    * Constructor which (optionally delays) parsing of data from a file of some
128    * specified type.
129    *
130    * @param parseImmediately
131    * if false, need to call 'doParse()' to begin parsing data
132    * @param dataObject
133    * Filename, URL or Pasted String to read from.
134    * @param sourceType
135    * What type of file to read from (File, URL)
136    * @throws IOException
137    */
 
138  212 toggle public AlignFile(boolean parseImmediately, Object dataObject,
139    DataSourceType sourceType) throws IOException
140    {
141    // BH allows File or String
142  212 super(dataObject, sourceType);
143  212 initData();
144  212 if (parseImmediately)
145    {
146  14 doParse();
147    }
148    }
149   
150    /**
151    * Attempt to read from the position where some other parsing process left
152    * off.
153    *
154    * @param source
155    * @throws IOException
156    */
 
157  5 toggle public AlignFile(FileParse source, boolean doXferSettings)
158    throws IOException
159    {
160  5 this(true, source, true, doXferSettings);
161    }
162   
 
163  82 toggle public AlignFile(FileParse source) throws IOException
164    {
165  82 this(true, source);
166    }
167   
168    /**
169    * Construct a new parser to read from the position where some other parsing
170    * process left
171    *
172    * @param parseImmediately
173    * if false, need to call 'doParse()' to begin parsing data
174    * @param source
175    */
 
176  438 toggle public AlignFile(boolean parseImmediately, FileParse source)
177    throws IOException
178    {
179  438 this(parseImmediately, source, true);
180    }
181   
 
182  843 toggle public AlignFile(boolean parseImmediately, FileParse source,
183    boolean closeData) throws IOException
184    {
185  843 this(parseImmediately, source, closeData, true);
186    }
187   
 
188  848 toggle public AlignFile(boolean parseImmediately, FileParse source,
189    boolean closeData, boolean doXferSettings) throws IOException
190    {
191  848 super(source);
192  848 initData();
193   
194    // stash flag in case parse needs to know if it has to autoconfigure or was
195    // configured after construction
196  848 this.parseImmediately = parseImmediately;
197  848 this.doXferSettings = doXferSettings;
198   
199  848 if (parseImmediately)
200    {
201  492 doParse(closeData);
202    }
203    }
204   
205    /**
206    * called if parsing was delayed till after parser was constructed
207    *
208    * @throws IOException
209    */
 
210  200 toggle public void doParse() throws IOException
211    {
212  200 doParse(true);
213    }
214   
 
215  692 toggle public void doParse(boolean closeData) throws IOException
216    {
217  692 if (parseCalled)
218    {
219  0 throw new IOException(
220    "Implementation error: Parser called twice for same data.\n"
221    + "Need to call initData() again before parsing can be reattempted.");
222    }
223  692 parseCalled = true;
224  692 parse(this.doXferSettings);
225  692 if (closeData && !dataClosed)
226    {
227  688 dataIn.close();
228  688 dataClosed = true;
229    }
230    }
231   
232    /**
233    * Return the seqs Vector
234    */
 
235  36 toggle public Vector<SequenceI> getSeqs()
236    {
237  36 return seqs;
238    }
239   
 
240  501 toggle public List<SequenceGroup> getSeqGroups()
241    {
242  501 return seqGroups;
243    }
244   
245    /**
246    * Return the Sequences in the seqs Vector as an array of Sequences
247    */
 
248  514 toggle @Override
249    public SequenceI[] getSeqsAsArray()
250    {
251  514 SequenceI[] s = new SequenceI[seqs.size()];
252   
253  4909 for (int i = 0; i < seqs.size(); i++)
254    {
255  4395 s[i] = seqs.elementAt(i);
256    }
257   
258  514 return s;
259    }
260   
261    /**
262    * called by AppletFormatAdapter to generate an annotated alignment, rather
263    * than bare sequences.
264    *
265    * @param al
266    */
 
267  510 toggle @Override
268    public void addAnnotations(AlignmentI al)
269    {
270  510 addProperties(al);
271  981 for (int i = 0; i < annotations.size(); i++)
272    {
273    // detect if annotations.elementAt(i) rna secondary structure
274    // if so then do:
275    /*
276    * SequenceFeature[] pairArray =
277    * Rna.GetBasePairsFromAlignmentAnnotation(annotations.elementAt(i));
278    * Rna.HelixMap(pairArray);
279    */
280  471 AlignmentAnnotation an = annotations.elementAt(i);
281  471 an.validateRangeAndDisplay();
282  471 al.addAnnotation(an);
283    }
284   
285    }
286   
287    /**
288    * register sequence groups on the alignment for **output**
289    *
290    * @param al
291    */
 
292  0 toggle public void addSeqGroups(AlignmentI al)
293    {
294  0 this.seqGroups = al.getGroups();
295   
296    }
297   
298    /**
299    * Add any additional information extracted from the file to the alignment
300    * properties.
301    *
302    * @note implicitly called by addAnnotations()
303    * @param al
304    */
 
305  511 toggle public void addProperties(AlignmentI al)
306    {
307  511 if (properties != null && properties.size() > 0)
308    {
309  8 Enumeration keys = properties.keys();
310  8 Enumeration vals = properties.elements();
311  119 while (keys.hasMoreElements())
312    {
313  111 al.setProperty(keys.nextElement(), vals.nextElement());
314    }
315    }
316    }
317   
318    /**
319    * Store a non-null key-value pair in a hashtable used to set alignment
320    * properties note: null keys will raise an error, null values will result in
321    * the key/value pair being silently ignored.
322    *
323    * @param key
324    * - non-null key object
325    * @param value
326    * - non-null value
327    */
 
328  153 toggle protected void setAlignmentProperty(Object key, Object value)
329    {
330  153 if (key == null)
331    {
332  0 throw new Error(MessageManager.getString(
333    "error.implementation_error_cannot_have_null_alignment"));
334    }
335  153 if (value == null)
336    {
337  0 return; // null properties are ignored.
338    }
339  153 if (properties == null)
340    {
341  8 properties = new Hashtable();
342    }
343  153 properties.put(key, value);
344    }
345   
 
346  51 toggle protected Object getAlignmentProperty(Object key)
347    {
348  51 if (properties != null && key != null)
349    {
350  13 return properties.get(key);
351    }
352  38 return null;
353    }
354   
355    /**
356    * Initialise objects to store sequence data in.
357    */
 
358  1286 toggle protected void initData()
359    {
360  1286 seqs = new Vector<SequenceI>();
361  1286 annotations = new Vector<AlignmentAnnotation>();
362  1286 seqGroups = new ArrayList<SequenceGroup>();
363  1286 parseCalled = false;
364    }
365   
366    /**
367    * DOCUMENT ME!
368    *
369    * @param s
370    * DOCUMENT ME!
371    */
 
372  4 toggle @Override
373    public void setSeqs(SequenceI[] s)
374    {
375  4 seqs = new Vector<SequenceI>();
376   
377  11 for (int i = 0; i < s.length; i++)
378    {
379  7 seqs.addElement(s[i]);
380    }
381    }
382   
383    /**
384    * This method must be implemented to parse the contents of the file.
385    */
386    public abstract void parse() throws IOException;
387   
388    /**
389    * This method is only overridden by JmolParser because of its use in
390    * StructureFile to parse annotations
391    *
392    * @param doXferSettings
393    * @throws IOException
394    */
 
395  517 toggle public void parse(boolean doXferSettings) throws IOException
396    {
397  517 parse();
398    }
399   
400    /**
401    * A general parser for ids.
402    *
403    * @String id Id to be parsed
404    */
 
405  3322 toggle Sequence parseId(String id)
406    {
407  3322 Sequence seq = null;
408  3322 id = id.trim();
409  3322 int space = StringUtils.indexOfFirstWhitespace(id);
410  3322 if (space > -1)
411    {
412  2724 seq = new Sequence(id.substring(0, space), "");
413  2724 String desc = id.substring(space + 1);
414  2724 seq.setDescription(desc);
415   
416    /*
417    * it is tempting to parse Ensembl style gene description e.g.
418    * chromosome:GRCh38:7:140696688:140721955:1 and set the
419    * start position of the sequence, but this causes much confusion
420    * for reverse strand feature locations
421    */
422    }
423    else
424    {
425  598 seq = new Sequence(id, "");
426    }
427   
428  3322 return seq;
429    }
430   
431    /**
432    * Creates the output id. Adds prefix Uniprot format source|id and optionally
433    * suffix Jalview /start-end
434    *
435    * @param jvsuffix
436    *
437    * @String id Id to be parsed
438    */
 
439  3872 toggle String printId(SequenceI seq, boolean jvsuffix)
440    {
441  3872 return seq.getDisplayId(jvsuffix);
442    }
443   
 
444  0 toggle String printId(SequenceI seq)
445    {
446  0 return printId(seq, true);
447    }
448   
449    /**
450    * vector of String[] treeName, newickString pairs
451    */
452    Vector<String[]> newickStrings = null;
453   
 
454  0 toggle protected void addNewickTree(String treeName, String newickString)
455    {
456  0 if (newickStrings == null)
457    {
458  0 newickStrings = new Vector<String[]>();
459    }
460  0 newickStrings.addElement(new String[] { treeName, newickString });
461    }
462   
 
463  0 toggle protected int getTreeCount()
464    {
465  0 return newickStrings == null ? 0 : newickStrings.size();
466    }
467   
 
468  501 toggle @Override
469    public void addGroups(AlignmentI al)
470    {
471   
472  501 for (SequenceGroup sg : getSeqGroups())
473    {
474  11 al.addGroup(sg);
475    }
476    }
477   
 
478  4 toggle protected void addSequence(SequenceI seq)
479    {
480  4 seqs.add(seq);
481    }
482   
 
483  298 toggle public void setDoXferSettings(boolean b)
484    {
485  298 doXferSettings = b;
486    }
487   
 
488  267 toggle public boolean getDoXferSettings()
489    {
490  267 return doXferSettings;
491    }
492    }