Merge branch 'JAL-3878_ws-overhaul-3' into with_ws_overhaul-3
[jalview.git] / src / jalview / ws2 / actions / alignment / AlignmentJob.java
1 package jalview.ws2.actions.alignment;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.LinkedHashMap;
6 import java.util.List;
7 import java.util.Map;
8
9 import jalview.analysis.AlignSeq;
10 import jalview.analysis.SeqsetUtils;
11 import jalview.analysis.SeqsetUtils.SequenceInfo;
12 import jalview.datamodel.AlignmentI;
13 import jalview.datamodel.Sequence;
14 import jalview.datamodel.SequenceI;
15 import jalview.util.Comparison;
16 import jalview.ws2.actions.BaseJob;
17 import jalview.ws2.api.WebServiceJobHandle;
18
19 /**
20  * A wrapper class that extends basic job container with data specific to
21  * alignment services. It stores input and empty sequences (with uniquified
22  * names) along the original sequence information. {@link AlignmentJob} objects
23  * are created by {@link AlignmentTask} during a preparation stage.
24  * 
25  * @author mmwarowny
26  *
27  */
28 class AlignmentJob extends BaseJob
29 {
30   private final List<SequenceI> emptySeqs;
31
32   private final Map<String, SequenceInfo> names;
33
34   private AlignmentI alignmentResult;
35
36   AlignmentJob(List<SequenceI> inputSeqs, List<SequenceI> emptySeqs,
37       Map<String, SequenceInfo> names)
38   {
39     super(Collections.unmodifiableList(inputSeqs));
40     this.emptySeqs = Collections.unmodifiableList(emptySeqs);
41     this.names = Collections.unmodifiableMap(names);
42   }
43
44   public static AlignmentJob create(SequenceI[] seqs, int minlen, boolean keepGaps)
45   {
46     int nseqs = 0;
47     for (int i = 0; i < seqs.length; i++)
48     {
49       if (seqs[i].getEnd() - seqs[i].getStart() >= minlen)
50         nseqs++;
51     }
52     boolean valid = nseqs > 1; // need at least two sequences
53     Map<String, SequenceInfo> names = new LinkedHashMap<>();
54     List<SequenceI> inputSeqs = new ArrayList<>();
55     List<SequenceI> emptySeqs = new ArrayList<>();
56     for (int i = 0; i < seqs.length; i++)
57     {
58       SequenceI seq = seqs[i];
59       String newName = SeqsetUtils.unique_name(i);
60       names.put(newName, SeqsetUtils.SeqCharacterHash(seq));
61       if (valid && seq.getEnd() - seq.getStart() >= minlen)
62       {
63         // make new input sequence
64         String seqString = seq.getSequenceAsString();
65         if (!keepGaps)
66           seqString = AlignSeq.extractGaps(Comparison.GapChars, seqString);
67         inputSeqs.add(new Sequence(newName, seqString));
68       }
69       else
70       {
71         String seqString = "";
72         if (seq.getEnd() >= seq.getStart()) // true if gaps only
73         {
74           seqString = seq.getSequenceAsString();
75           if (!keepGaps)
76             seqString = AlignSeq.extractGaps(Comparison.GapChars, seqString);
77         }
78         emptySeqs.add(new Sequence(newName, seqString));
79       }
80     }
81     return new AlignmentJob(inputSeqs, emptySeqs, names);
82   }
83
84   @Override
85   public boolean isInputValid()
86   {
87     return inputSeqs.size() >= 2;
88   }
89
90   List<SequenceI> getEmptySequences()
91   {
92     return emptySeqs;
93   }
94
95   Map<String, SequenceInfo> getNames()
96   {
97     return names;
98   }
99
100   boolean hasResult()
101   {
102     return alignmentResult != null;
103   }
104
105   AlignmentI getAlignmentResult()
106   {
107     return alignmentResult;
108   }
109
110   void setAlignmentResult(AlignmentI alignment)
111   {
112     this.alignmentResult = alignment;
113   }
114 }