update author list in license for (JAL-826)
[jalview.git] / src / jalview / io / packed / JalviewDataset.java
1 /*******************************************************************************
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3  * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
10  *
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  *******************************************************************************/
18 package jalview.io.packed;
19
20 import jalview.datamodel.AlignmentI;
21 import jalview.datamodel.SequenceI;
22 import jalview.io.NewickFile;
23
24 import java.util.ArrayList;
25 import java.util.Hashtable;
26 import java.util.List;
27
28 public class JalviewDataset
29 {
30   /**
31    * dataset that new data (sequences, alignments) will be added to
32    */
33   AlignmentI parentDataset;
34
35   /**
36    * @return the parentDataset
37    */
38   public AlignmentI getParentDataset()
39   {
40     return parentDataset;
41   }
42   /**
43    * @param parentDataset the parentDataset to set
44    */
45   public void setParentDataset(AlignmentI parentDataset)
46   {
47     this.parentDataset = parentDataset;
48   }
49   /**
50    * @return the featureColours
51    */
52   public Hashtable getFeatureColours()
53   {
54     return featureColours;
55   }
56   /**
57    * @param featureColours the featureColours to set
58    */
59   public void setFeatureColours(Hashtable featureColours)
60   {
61     this.featureColours = featureColours;
62   }
63   /**
64    * @return the seqDetails
65    */
66   public Hashtable getSeqDetails()
67   {
68     return seqDetails;
69   }
70   /**
71    * @param seqDetails the seqDetails to set
72    */
73   public void setSeqDetails(Hashtable seqDetails)
74   {
75     this.seqDetails = seqDetails;
76   }
77   /**
78    * @return the al
79    */
80   public List<AlignmentSet> getAl()
81   {
82     return (al==null) ? new ArrayList<AlignmentSet>() : al;
83   }
84   /**
85    * current alignment being worked on.
86    */
87   List<AlignmentSet> al;
88   public class AlignmentSet {
89     public AlignmentI al;
90     public List<jalview.io.NewickFile> trees;
91     AlignmentSet(AlignmentI a) {
92       al = a;
93       trees = new ArrayList<jalview.io.NewickFile>();
94     }
95     /**
96      * deuniquify the current alignment in the context, merging any new
97      * annotation/features with the existing set
98      * 
99      * @param context
100      */
101       void deuniquifyAlignment()
102       {
103         if (seqDetails==null || seqDetails.size()==0)
104         {
105           // nothing to do
106           return;
107         }
108         // 1. recover correct names and attributes for each sequence in alignment.
109         /*
110          * TODO: housekeeping w.r.t. recovery of dataset and annotation
111          * references for input sequences, and then dataset sequence creation
112          * for new sequences retrieved from service // finally, attempt to
113          * de-uniquify to recover input sequence identity, and try to map back
114          * onto dataset Note: this
115          * jalview.analysis.SeqsetUtils.deuniquify(SeqNames, alseqs, true); will
116          * NOT WORK - the returned alignment may contain multiple versions of
117          * the input sequence, each being a subsequence of the original.
118          * deuniquify also removes existing annotation and features added in the
119          * previous step... al.setDataset(dataset); // add in new sequences
120          * retrieved from sequence search which are not already in dataset. //
121          * trigger a 'fetchDBids' to annotate sequences with database ids...
122          */
123         //jalview.analysis.SeqsetUtils.deuniquifyAndMerge(parentDataset, seqDetails, al,true);
124         
125         jalview.analysis.SeqsetUtils.deuniquify(seqDetails, al.getSequencesArray(),true);
126         // 2. Update names of associated nodes in any trees
127         for (NewickFile nf:trees)
128         {
129           // the following works because all trees are already had node/SequenceI associations created.
130           jalview.analysis.NJTree njt = new jalview.analysis.NJTree(al.getSequencesArray(), nf);
131           // this just updates the displayed leaf name on the tree according to the SequenceIs.
132           njt.renameAssociatedNodes();
133         }
134         
135       }
136       /**
137        * set modification flag. If anything modifies the alignment in the current set, this flag should be true
138        */
139       private boolean modified=false;
140       
141       /**
142        * @return the modified
143        */
144       public boolean isModified()
145       {
146         return modified;
147       }
148       /**
149        * or the modification state with the given state 
150        * @param modifiedFromAction
151        */
152     public void updateSetModified(boolean modifiedFromAction)
153     {
154       modified |= modifiedFromAction;
155     }
156   }
157
158   /**
159    * current set of feature colours
160    */
161   Hashtable featureColours;
162
163   /**
164    * original identity of each sequence in results
165    */
166   Hashtable seqDetails;
167
168   public boolean relaxedIdMatching=false;
169
170   public JalviewDataset()
171   {
172     seqDetails = new Hashtable();
173     al = new ArrayList<AlignmentSet>();
174     parentDataset = null;
175     featureColours = new Hashtable();
176   }
177   /**
178    * context created from an existing alignment.
179    * @param parentAlignment
180    */
181   public JalviewDataset(AlignmentI aldataset, Hashtable fc, Hashtable seqDets)
182   {
183     this(aldataset, fc, seqDets, null);
184   }
185   /**
186    * 
187    * @param aldataset - parent dataset for any new alignment/sequence data (must not be null)
188    * @param fc  (may be null) feature settings for the alignment where new feature renderstyles are stored
189    * @param seqDets - (may be null) anonymised sequence information created by Sequence uniquifier 
190    * @param parentAlignment (may be null) alignment to associate new annotation and trees with.
191    */
192   public JalviewDataset(AlignmentI aldataset, Hashtable fc, Hashtable seqDets, AlignmentI parentAlignment)
193   {
194     this();
195     parentDataset = aldataset;
196     if (parentAlignment!=null)
197     {
198       parentDataset = parentAlignment.getDataset();
199       if (parentDataset==null)
200       {
201         parentDataset = parentAlignment;
202       } else {
203         addAlignment(parentAlignment);
204       }
205     }
206     if (seqDets!=null)
207     {
208       seqDetails = seqDets;
209     }
210     if (fc!=null)
211     {
212       featureColours = fc;
213     }
214     
215     
216   }
217
218   public boolean hasAlignments()
219   {
220     return al!=null && al.size()>0;
221   }
222
223   public AlignmentI getLastAlignment()
224   {
225     return (al==null || al.size()<1) ? null: al.get(al.size()-1).al;
226   }
227   public AlignmentSet getLastAlignmentSet()
228   {
229     return (al==null || al.size()<1) ? null: al.get(al.size()-1);
230   }
231
232   /**
233    * post process (deuniquify) the current alignment and its dependent data, and then add newal to the dataset.
234    * @param newal
235    */
236 public void addAlignment(AlignmentI newal) {
237   if (!hasAlignments())
238   {
239     al = new ArrayList<AlignmentSet>();
240   } 
241   AlignmentSet last = getLastAlignmentSet();
242   if (last!=null) {
243     System.err.println("Deuniquifying last alignment set.");
244     last.deuniquifyAlignment();
245   }
246   al.add(new AlignmentSet(newal));
247 }
248
249 public void addTreeFromFile(NewickFile nf)
250 {
251   AlignmentSet lal = getLastAlignmentSet();
252   lal.trees.add(nf);
253 }
254
255 public boolean hasSequenceAssoc()
256 {
257   // TODO: discover where sequence associated data should be put.
258   return false;
259 }
260 public SequenceI getLastAssociatedSequence() {
261   // TODO: delineate semantics for associating uniquified data with potentially de-uniquified sequence.
262   return null;
263 }
264 /**
265  * update the modified state flag for the current set with the given modification state
266  * @param modified - this will be ored with current modification state
267  */
268 public void updateSetModified(boolean modified)
269 {
270   getLastAlignmentSet().updateSetModified(modified);
271 }
272 }