merge
[jalview.git] / src / jalview / io / packed / JalviewDataset.java
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.packed;
22
23 import jalview.datamodel.AlignmentI;
24 import jalview.datamodel.SequenceI;
25 import jalview.io.NewickFile;
26
27 import java.util.ArrayList;
28 import java.util.Hashtable;
29 import java.util.List;
30
31 public class JalviewDataset
32 {
33   /**
34    * dataset that new data (sequences, alignments) will be added to
35    */
36   AlignmentI parentDataset;
37
38   /**
39    * @return the parentDataset
40    */
41   public AlignmentI getParentDataset()
42   {
43     return parentDataset;
44   }
45
46   /**
47    * @param parentDataset
48    *          the parentDataset to set
49    */
50   public void setParentDataset(AlignmentI parentDataset)
51   {
52     this.parentDataset = parentDataset;
53   }
54
55   /**
56    * @return the featureColours
57    */
58   public Hashtable getFeatureColours()
59   {
60     return featureColours;
61   }
62
63   /**
64    * @param featureColours
65    *          the featureColours to set
66    */
67   public void setFeatureColours(Hashtable featureColours)
68   {
69     this.featureColours = featureColours;
70   }
71
72   /**
73    * @return the seqDetails
74    */
75   public Hashtable getSeqDetails()
76   {
77     return seqDetails;
78   }
79
80   /**
81    * @param seqDetails
82    *          the seqDetails to set
83    */
84   public void setSeqDetails(Hashtable seqDetails)
85   {
86     this.seqDetails = seqDetails;
87   }
88
89   /**
90    * @return the al
91    */
92   public List<AlignmentSet> getAl()
93   {
94     return (al == null) ? new ArrayList<AlignmentSet>() : al;
95   }
96
97   /**
98    * current alignment being worked on.
99    */
100   List<AlignmentSet> al;
101
102   public class AlignmentSet
103   {
104     public AlignmentI al;
105
106     public List<jalview.io.NewickFile> trees;
107
108     AlignmentSet(AlignmentI a)
109     {
110       al = a;
111       trees = new ArrayList<jalview.io.NewickFile>();
112     }
113
114     /**
115      * deuniquify the current alignment in the context, merging any new
116      * annotation/features with the existing set
117      * 
118      * @param context
119      */
120     void deuniquifyAlignment()
121     {
122       if (seqDetails == null || seqDetails.size() == 0)
123       {
124         // nothing to do
125         return;
126       }
127       // 1. recover correct names and attributes for each sequence in alignment.
128       /*
129        * TODO: housekeeping w.r.t. recovery of dataset and annotation references
130        * for input sequences, and then dataset sequence creation for new
131        * sequences retrieved from service // finally, attempt to de-uniquify to
132        * recover input sequence identity, and try to map back onto dataset Note:
133        * this jalview.analysis.SeqsetUtils.deuniquify(SeqNames, alseqs, true);
134        * will NOT WORK - the returned alignment may contain multiple versions of
135        * the input sequence, each being a subsequence of the original.
136        * deuniquify also removes existing annotation and features added in the
137        * previous step... al.setDataset(dataset); // add in new sequences
138        * retrieved from sequence search which are not already in dataset. //
139        * trigger a 'fetchDBids' to annotate sequences with database ids...
140        */
141       // jalview.analysis.SeqsetUtils.deuniquifyAndMerge(parentDataset,
142       // seqDetails, al,true);
143
144       jalview.analysis.SeqsetUtils.deuniquify(seqDetails,
145               al.getSequencesArray(), true);
146       // 2. Update names of associated nodes in any trees
147       for (NewickFile nf : trees)
148       {
149         // the following works because all trees are already had node/SequenceI
150         // associations created.
151         jalview.analysis.NJTree njt = new jalview.analysis.NJTree(
152                 al.getSequencesArray(), nf);
153         // this just updates the displayed leaf name on the tree according to
154         // the SequenceIs.
155         njt.renameAssociatedNodes();
156       }
157
158     }
159
160     /**
161      * set modification flag. If anything modifies the alignment in the current
162      * set, this flag should be true
163      */
164     private boolean modified = false;
165
166     /**
167      * @return the modified
168      */
169     public boolean isModified()
170     {
171       return modified;
172     }
173
174     /**
175      * or the modification state with the given state
176      * 
177      * @param modifiedFromAction
178      */
179     public void updateSetModified(boolean modifiedFromAction)
180     {
181       modified |= modifiedFromAction;
182     }
183   }
184
185   /**
186    * current set of feature colours
187    */
188   Hashtable featureColours;
189
190   /**
191    * original identity of each sequence in results
192    */
193   Hashtable seqDetails;
194
195   public boolean relaxedIdMatching = false;
196
197   public JalviewDataset()
198   {
199     seqDetails = new Hashtable();
200     al = new ArrayList<AlignmentSet>();
201     parentDataset = null;
202     featureColours = new Hashtable();
203   }
204
205   /**
206    * context created from an existing alignment.
207    * 
208    * @param parentAlignment
209    */
210   public JalviewDataset(AlignmentI aldataset, Hashtable fc,
211           Hashtable seqDets)
212   {
213     this(aldataset, fc, seqDets, null);
214   }
215
216   /**
217    * 
218    * @param aldataset
219    *          - parent dataset for any new alignment/sequence data (must not be
220    *          null)
221    * @param fc
222    *          (may be null) feature settings for the alignment where new feature
223    *          renderstyles are stored
224    * @param seqDets
225    *          - (may be null) anonymised sequence information created by
226    *          Sequence uniquifier
227    * @param parentAlignment
228    *          (may be null) alignment to associate new annotation and trees
229    *          with.
230    */
231   public JalviewDataset(AlignmentI aldataset, Hashtable fc,
232           Hashtable seqDets, AlignmentI parentAlignment)
233   {
234     this();
235     parentDataset = aldataset;
236     if (parentAlignment != null)
237     {
238       parentDataset = parentAlignment.getDataset();
239       if (parentDataset == null)
240       {
241         parentDataset = parentAlignment;
242       }
243       else
244       {
245         addAlignment(parentAlignment);
246       }
247     }
248     if (seqDets != null)
249     {
250       seqDetails = seqDets;
251     }
252     if (fc != null)
253     {
254       featureColours = fc;
255     }
256
257   }
258
259   public boolean hasAlignments()
260   {
261     return al != null && al.size() > 0;
262   }
263
264   public AlignmentI getLastAlignment()
265   {
266     return (al == null || al.size() < 1) ? null : al.get(al.size() - 1).al;
267   }
268
269   public AlignmentSet getLastAlignmentSet()
270   {
271     return (al == null || al.size() < 1) ? null : al.get(al.size() - 1);
272   }
273
274   /**
275    * post process (deuniquify) the current alignment and its dependent data, and
276    * then add newal to the dataset.
277    * 
278    * @param newal
279    */
280   public void addAlignment(AlignmentI newal)
281   {
282     if (!hasAlignments())
283     {
284       al = new ArrayList<AlignmentSet>();
285     }
286     AlignmentSet last = getLastAlignmentSet();
287     if (last != null)
288     {
289       System.err.println("Deuniquifying last alignment set.");
290       last.deuniquifyAlignment();
291     }
292     al.add(new AlignmentSet(newal));
293   }
294
295   public void addTreeFromFile(NewickFile nf)
296   {
297     AlignmentSet lal = getLastAlignmentSet();
298     lal.trees.add(nf);
299   }
300
301   public boolean hasSequenceAssoc()
302   {
303     // TODO: discover where sequence associated data should be put.
304     return false;
305   }
306
307   public SequenceI getLastAssociatedSequence()
308   {
309     // TODO: delineate semantics for associating uniquified data with
310     // potentially de-uniquified sequence.
311     return null;
312   }
313
314   /**
315    * update the modified state flag for the current set with the given
316    * modification state
317    * 
318    * @param modified
319    *          - this will be ored with current modification state
320    */
321   public void updateSetModified(boolean modified)
322   {
323     getLastAlignmentSet().updateSetModified(modified);
324   }
325 }