initial implementation for JAL-718
[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    * current alignment being worked on.
20    */
21   List<AlignmentSet> al;
22   public class AlignmentSet {
23     AlignmentI al;
24     List<jalview.io.NewickFile> trees;
25     AlignmentSet(AlignmentI a) {
26       al = a;
27       trees = new ArrayList<jalview.io.NewickFile>();
28     }
29     /**
30      * deuniquify the current alignment in the context, merging any new
31      * annotation/features with the existing set
32      * 
33      * @param context
34      */
35       void deuniquifyAlignment()
36       {
37         if (seqDetails==null || seqDetails.size()==0)
38         {
39           // nothing to do
40           return;
41         }
42         // 1. recover correct names and attributes for each sequence in alignment.
43         /*
44          * TODO: housekeeping w.r.t. recovery of dataset and annotation
45          * references for input sequences, and then dataset sequence creation
46          * for new sequences retrieved from service // finally, attempt to
47          * de-uniquify to recover input sequence identity, and try to map back
48          * onto dataset Note: this
49          * jalview.analysis.SeqsetUtils.deuniquify(SeqNames, alseqs, true); will
50          * NOT WORK - the returned alignment may contain multiple versions of
51          * the input sequence, each being a subsequence of the original.
52          * deuniquify also removes existing annotation and features added in the
53          * previous step... al.setDataset(dataset); // add in new sequences
54          * retrieved from sequence search which are not already in dataset. //
55          * trigger a 'fetchDBids' to annotate sequences with database ids...
56          */
57         //jalview.analysis.SeqsetUtils.deuniquifyAndMerge(parentDataset, seqDetails, al,true);
58         
59         jalview.analysis.SeqsetUtils.deuniquify(seqDetails, al.getSequencesArray(),true);
60         // 2. Update names of associated nodes in any trees
61         for (NewickFile nf:trees)
62         {
63           // the following works because all trees are already had node/SequenceI associations created.
64           jalview.analysis.NJTree njt = new jalview.analysis.NJTree(al.getSequencesArray(), nf);
65           // this just updates the displayed leaf name on the try according to the SequenceIs.
66           njt.renameAssociatedNodes();
67         }
68         
69       }
70   }
71
72   /**
73    * current set of feature colours
74    */
75   Hashtable featureColours;
76
77   /**
78    * original identity of each sequence in results
79    */
80   Hashtable seqDetails;
81
82   public JalviewDataset()
83   {
84     seqDetails = new Hashtable();
85     al = new ArrayList<AlignmentSet>();
86     parentDataset = null;
87     featureColours = new Hashtable();
88   }
89   /**
90    * context created from an existing alignment.
91    * @param parentAlignment
92    */
93   public JalviewDataset(AlignmentI aldataset, Hashtable fc, Hashtable seqDets)
94   {
95     this(aldataset, fc, seqDets, null);
96   }
97   /**
98    * 
99    * @param aldataset - parent dataset for any new alignment/sequence data (must not be null)
100    * @param fc  (may be null) feature settings for the alignment where new feature renderstyles are stored
101    * @param seqDets - (may be null) anonymised sequence information created by Sequence uniquifier 
102    * @param parentAlignment (may be null) alignment to associate new annotation and trees with.
103    */
104   public JalviewDataset(AlignmentI aldataset, Hashtable fc, Hashtable seqDets, AlignmentI parentAlignment)
105   {
106     this();
107     parentDataset = aldataset;
108     if (parentAlignment!=null)
109     {
110       parentDataset = parentAlignment.getDataset();
111       if (parentDataset==null)
112       {
113         parentDataset = parentAlignment;
114       } else {
115         addAlignment(parentAlignment);
116       }
117     }
118     if (seqDets!=null)
119     {
120       seqDetails = seqDets;
121     }
122     if (fc!=null)
123     {
124       featureColours = fc;
125     }
126     
127     
128   }
129
130   public boolean hasAlignments()
131   {
132     return al!=null && al.size()>0;
133   }
134
135   public AlignmentI getLastAlignment()
136   {
137     return (al==null || al.size()<1) ? null: al.get(al.size()-1).al;
138   }
139   public AlignmentSet getLastAlignmentSet()
140   {
141     return (al==null || al.size()<1) ? null: al.get(al.size()-1);
142   }
143
144   /**
145    * post process (deuniquify) the current alignment and its dependent data, and then add newal to the dataset.
146    * @param newal
147    */
148 public void addAlignment(AlignmentI newal) {
149   if (!hasAlignments())
150   {
151     al = new ArrayList<AlignmentSet>();
152   } 
153   AlignmentSet last = getLastAlignmentSet();
154   if (last!=null) {
155     System.err.println("Deuniquifying last alignment set.");
156     last.deuniquifyAlignment();
157   }
158   al.add(new AlignmentSet(newal));
159 }
160
161 public void addTreeFromFile(NewickFile nf)
162 {
163   AlignmentSet lal = getLastAlignmentSet();
164   lal.trees.add(nf);
165 }
166
167 public boolean hasSequenceAssoc()
168 {
169   // TODO: discover where sequence associated data should be put.
170   return false;
171 }
172 public SequenceI getLastAssociatedSequence() {
173   // TODO: delineate semantics for associating uniquified data with potentially de-uniquified sequence.
174   return null;
175 }
176 }