JAL-1499 patch from Mungo Carstairs
[jalview.git] / src / jalview / io / FormatAdapter.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 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 jalview.datamodel.Alignment;
24 import jalview.datamodel.AlignmentAnnotation;
25 import jalview.datamodel.AlignmentI;
26 import jalview.datamodel.ColumnSelection;
27 import jalview.datamodel.Sequence;
28 import jalview.datamodel.SequenceGroup;
29 import jalview.datamodel.SequenceI;
30
31 /**
32  * Additional formatting methods used by the application in a number of places.
33  * 
34  * @author $author$
35  * @version $Revision$
36  */
37 public class FormatAdapter extends AppletFormatAdapter
38 {
39
40   public String formatSequences(String format, SequenceI[] seqs,
41           String[] omitHiddenColumns)
42   {
43
44     return formatSequences(format, replaceStrings(seqs, omitHiddenColumns));
45   }
46
47   /**
48    * create sequences with each sequence string replaced with the one given in
49    * omitHiddenCOlumns
50    * 
51    * @param seqs
52    * @param omitHiddenColumns
53    * @return new sequences
54    */
55   public SequenceI[] replaceStrings(SequenceI[] seqs,
56           String[] omitHiddenColumns)
57   {
58     if (omitHiddenColumns != null)
59     {
60       SequenceI[] tmp = new SequenceI[seqs.length];
61       for (int i = 0; i < seqs.length; i++)
62       {
63         tmp[i] = new Sequence(seqs[i].getName(), omitHiddenColumns[i],
64                 seqs[i].getStart(), seqs[i].getEnd());
65         tmp[i].setDescription(seqs[i].getDescription());
66       }
67       seqs = tmp;
68     }
69     return seqs;
70   }
71
72   /**
73    * Format a vector of sequences as a flat alignment file. TODO: allow caller
74    * to detect errors and warnings encountered when generating output
75    * 
76    * 
77    * @param format
78    *          Format string as givien in the AppletFormatAdaptor list (exact
79    *          match to name of class implementing file io for that format)
80    * @param seqs
81    *          vector of sequences to write
82    * 
83    * @return String containing sequences in desired format
84    */
85   public String formatSequences(String format, SequenceI[] seqs)
86   {
87
88     try
89     {
90       AlignFile afile = null;
91
92       if (format.equalsIgnoreCase("FASTA"))
93       {
94         afile = new FastaFile();
95         afile.addJVSuffix(jalview.bin.Cache.getDefault("FASTA_JVSUFFIX",
96                 true));
97       }
98       else if (format.equalsIgnoreCase("MSF"))
99       {
100         afile = new MSFfile();
101         afile.addJVSuffix(jalview.bin.Cache
102                 .getDefault("MSF_JVSUFFIX", true));
103       }
104       else if (format.equalsIgnoreCase("PileUp"))
105       {
106         afile = new PileUpfile();
107         afile.addJVSuffix(jalview.bin.Cache.getDefault("PILEUP_JVSUFFIX",
108                 true));
109       }
110       else if (format.equalsIgnoreCase("CLUSTAL"))
111       {
112         afile = new ClustalFile();
113         afile.addJVSuffix(jalview.bin.Cache.getDefault("CLUSTAL_JVSUFFIX",
114                 true));
115       }
116       else if (format.equalsIgnoreCase("BLC"))
117       {
118         afile = new BLCFile();
119         afile.addJVSuffix(jalview.bin.Cache
120                 .getDefault("BLC_JVSUFFIX", true));
121       }
122       else if (format.equalsIgnoreCase("PIR"))
123       {
124         afile = new PIRFile();
125         afile.addJVSuffix(jalview.bin.Cache
126                 .getDefault("PIR_JVSUFFIX", true));
127       }
128       else if (format.equalsIgnoreCase("PFAM"))
129       {
130         afile = new PfamFile();
131         afile.addJVSuffix(jalview.bin.Cache.getDefault("PFAM_JVSUFFIX",
132                 true));
133       }
134       else if (format.equalsIgnoreCase("MEGA"))
135       {
136         afile = new MegaFile();
137         afile.addJVSuffix(jalview.bin.Cache.getDefault("MEGA_JVSUFFIX",
138                 true));
139       }
140       /*
141        * amsa is not supported by this function - it requires an alignment
142        * rather than a sequence vector else if (format.equalsIgnoreCase("AMSA"))
143        * { afile = new AMSAFile(); afile.addJVSuffix(
144        * jalview.bin.Cache.getDefault("AMSA_JVSUFFIX", true)); }
145        */
146
147       afile.setSeqs(seqs);
148       String afileresp = afile.print();
149       if (afile.hasWarningMessage())
150       {
151         System.err.println("Warning raised when writing as " + format
152                 + " : " + afile.getWarningMessage());
153       }
154       return afileresp;
155     } catch (Exception e)
156     {
157       System.err.println("Failed to write alignment as a '" + format
158               + "' file\n");
159       e.printStackTrace();
160     }
161
162     return null;
163   }
164
165   public boolean getCacheSuffixDefault(String format)
166   {
167     if (isValidFormat(format))
168       return jalview.bin.Cache.getDefault(format.toUpperCase()
169               + "_JVSUFFIX", true);
170     return false;
171   }
172
173   public String formatSequences(String format, AlignmentI alignment,
174           String[] omitHidden, ColumnSelection colSel)
175   {
176     return formatSequences(format, alignment, omitHidden,
177             getCacheSuffixDefault(format), colSel, null);
178   }
179
180   public String formatSequences(String format, AlignmentI alignment,
181           String[] omitHidden, ColumnSelection colSel, SequenceGroup sgp)
182   {
183     return formatSequences(format, alignment, omitHidden,
184             getCacheSuffixDefault(format), colSel, sgp);
185   }
186
187   /**
188    * hack function to replace seuqences with visible sequence strings before
189    * generating a string of the alignment in the given format.
190    * 
191    * @param format
192    * @param alignment
193    * @param omitHidden
194    *          sequence strings to write out in order of sequences in alignment
195    * @param colSel
196    *          defines hidden columns that are edited out of annotation
197    * @return string representation of the alignment formatted as format
198    */
199   public String formatSequences(String format, AlignmentI alignment,
200           String[] omitHidden, boolean suffix, ColumnSelection colSel)
201   {
202     return formatSequences(format, alignment, omitHidden, suffix, colSel,
203             null);
204   }
205
206   public String formatSequences(String format, AlignmentI alignment,
207           String[] omitHidden, boolean suffix, ColumnSelection colSel,
208           jalview.datamodel.SequenceGroup selgp)
209   {
210     if (omitHidden != null)
211     {
212       // TODO consider using AlignmentView to prune to visible region
213       // TODO prune sequence annotation and groups to visible region
214       // TODO: JAL-1486 - set start and end for output correctly. basically,
215       // AlignmentView.getVisibleContigs does this.
216       Alignment alv = new Alignment(replaceStrings(
217               alignment.getSequencesArray(), omitHidden));
218       AlignmentAnnotation[] ala = alignment.getAlignmentAnnotation();
219       if (ala != null)
220       {
221         for (int i = 0; i < ala.length; i++)
222         {
223           AlignmentAnnotation na = new AlignmentAnnotation(ala[i]);
224           if (selgp != null)
225           {
226             colSel.makeVisibleAnnotation(selgp.getStartRes(),
227                     selgp.getEndRes(), na);
228           }
229           else
230           {
231             colSel.makeVisibleAnnotation(na);
232           }
233           alv.addAnnotation(na);
234         }
235       }
236       return this.formatSequences(format, alv, suffix);
237     }
238     return this.formatSequences(format, alignment, suffix);
239   }
240
241   /**
242    * validate format is valid for IO in Application. This is basically the
243    * AppletFormatAdapter.isValidFormat call with additional checks for
244    * Application only formats like 'Jalview'.
245    * 
246    * @param format
247    *          a format string to be compared with list of readable or writable
248    *          formats (READABLE_FORMATS or WRITABLE_FORMATS)
249    * @param forwriting
250    *          when true, format is checked against list of writable formats.
251    * @return true if format is valid
252    */
253   public static final boolean isValidIOFormat(String format,
254           boolean forwriting)
255   {
256     if (format.equalsIgnoreCase("jalview"))
257     {
258       return true;
259     }
260     return AppletFormatAdapter.isValidFormat(format, forwriting);
261   }
262 }