f4fe55b3d57d26f237ec3356f49111546bab4b98
[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 boolean relaxedIdMatching=false;
152
153   public JalviewDataset()
154   {
155     seqDetails = new Hashtable();
156     al = new ArrayList<AlignmentSet>();
157     parentDataset = null;
158     featureColours = new Hashtable();
159   }
160   /**
161    * context created from an existing alignment.
162    * @param parentAlignment
163    */
164   public JalviewDataset(AlignmentI aldataset, Hashtable fc, Hashtable seqDets)
165   {
166     this(aldataset, fc, seqDets, null);
167   }
168   /**
169    * 
170    * @param aldataset - parent dataset for any new alignment/sequence data (must not be null)
171    * @param fc  (may be null) feature settings for the alignment where new feature renderstyles are stored
172    * @param seqDets - (may be null) anonymised sequence information created by Sequence uniquifier 
173    * @param parentAlignment (may be null) alignment to associate new annotation and trees with.
174    */
175   public JalviewDataset(AlignmentI aldataset, Hashtable fc, Hashtable seqDets, AlignmentI parentAlignment)
176   {
177     this();
178     parentDataset = aldataset;
179     if (parentAlignment!=null)
180     {
181       parentDataset = parentAlignment.getDataset();
182       if (parentDataset==null)
183       {
184         parentDataset = parentAlignment;
185       } else {
186         addAlignment(parentAlignment);
187       }
188     }
189     if (seqDets!=null)
190     {
191       seqDetails = seqDets;
192     }
193     if (fc!=null)
194     {
195       featureColours = fc;
196     }
197     
198     
199   }
200
201   public boolean hasAlignments()
202   {
203     return al!=null && al.size()>0;
204   }
205
206   public AlignmentI getLastAlignment()
207   {
208     return (al==null || al.size()<1) ? null: al.get(al.size()-1).al;
209   }
210   public AlignmentSet getLastAlignmentSet()
211   {
212     return (al==null || al.size()<1) ? null: al.get(al.size()-1);
213   }
214
215   /**
216    * post process (deuniquify) the current alignment and its dependent data, and then add newal to the dataset.
217    * @param newal
218    */
219 public void addAlignment(AlignmentI newal) {
220   if (!hasAlignments())
221   {
222     al = new ArrayList<AlignmentSet>();
223   } 
224   AlignmentSet last = getLastAlignmentSet();
225   if (last!=null) {
226     System.err.println("Deuniquifying last alignment set.");
227     last.deuniquifyAlignment();
228   }
229   al.add(new AlignmentSet(newal));
230 }
231
232 public void addTreeFromFile(NewickFile nf)
233 {
234   AlignmentSet lal = getLastAlignmentSet();
235   lal.trees.add(nf);
236 }
237
238 public boolean hasSequenceAssoc()
239 {
240   // TODO: discover where sequence associated data should be put.
241   return false;
242 }
243 public SequenceI getLastAssociatedSequence() {
244   // TODO: delineate semantics for associating uniquified data with potentially de-uniquified sequence.
245   return null;
246 }
247 /**
248  * update the modified state flag for the current set with the given modification state
249  * @param modified - this will be ored with current modification state
250  */
251 public void updateSetModified(boolean modified)
252 {
253   getLastAlignmentSet().updateSetModified(modified);
254 }
255 }