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