5067ff7bfd846479db4950dbead02eaebe7e02fe
[jalview.git] / src / jalview / ws2 / actions / secstructpred / SecStructPredMsaTask.java
1 package jalview.ws2.actions.secstructpred;
2
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.List;
6 import java.util.Map;
7
8 import jalview.analysis.AlignmentAnnotationUtils;
9 import jalview.analysis.SeqsetUtils;
10 import jalview.analysis.SeqsetUtils.SequenceInfo;
11 import jalview.api.AlignViewportI;
12 import jalview.bin.Console;
13 import jalview.datamodel.Alignment;
14 import jalview.datamodel.AlignmentAnnotation;
15 import jalview.datamodel.AlignmentI;
16 import jalview.datamodel.AlignmentView;
17 import jalview.datamodel.HiddenColumns;
18 import jalview.datamodel.SeqCigar;
19 import jalview.datamodel.SequenceI;
20 import jalview.io.AlignFile;
21 import jalview.io.JPredFile;
22 import jalview.io.JnetAnnotationMaker;
23 import jalview.ws.params.ArgumentI;
24 import jalview.ws2.actions.BaseJob;
25 import jalview.ws2.actions.BaseTask;
26 import jalview.ws2.actions.ServiceInputInvalidException;
27 import jalview.ws2.api.Credentials;
28 import jalview.ws2.api.JobStatus;
29 import jalview.ws2.client.api.SecStructPredWebServiceClientI;
30
31 public class SecStructPredMsaTask
32         extends BaseTask<SecStructPredMsaTask.SecStructPredJob, AlignmentI>
33 {
34   private final SecStructPredWebServiceClientI client;
35
36   private final AlignmentView alignmentView;
37
38   private final AlignmentI currentView;
39
40   private final char gapChar;
41
42   SecStructPredMsaTask(SecStructPredWebServiceClientI client,
43           List<ArgumentI> args, Credentials credentials,
44           AlignViewportI viewport)
45   {
46     super(client, args, credentials);
47     this.client = client;
48     this.alignmentView = viewport.getAlignmentView(true);
49     this.currentView = viewport.getAlignment();
50     this.gapChar = viewport.getGapCharacter();
51   }
52
53   @Override
54   protected List<SecStructPredJob> prepareJobs()
55           throws ServiceInputInvalidException
56   {
57     SeqCigar[] msf = alignmentView.getSequences();
58     SequenceI referenceSeq = msf[0].getSeq('-');
59     int[] delMap = alignmentView
60             .getVisibleContigMapFor(referenceSeq.gapMap());
61
62     // TODO: assume MSA for now
63     SequenceI[] sequences = new SequenceI[msf.length];
64     for (int i = 0; i < msf.length; i++)
65       sequences[i] = msf[i].getSeq('-');
66     var sequenceInfo = SeqsetUtils.uniquify(sequences, true);
67     referenceSeq.setSequence(alignmentView.getASequenceString('-', 0));
68     for (int i = 0; i < sequences.length; i++)
69       sequences[i].setSequence(alignmentView.getASequenceString('-', i));
70     var sequencesList = filterEmptySequences(sequences);
71     var job = new SecStructPredJob(sequencesList, referenceSeq, delMap,
72             sequenceInfo);
73     job.setStatus(JobStatus.READY);
74     return List.of(job);
75   }
76
77   private static List<SequenceI> filterEmptySequences(SequenceI[] seqs)
78   {
79     var filtered = new ArrayList<SequenceI>();
80     for (var seq : seqs)
81       if (seq.getEnd() - seq.getStart() > 0)
82         filtered.add(seq);
83     return filtered;
84   }
85
86   @Override
87   protected AlignmentI collectResult(List<SecStructPredJob> jobs)
88           throws IOException
89   {
90     var job = jobs.get(0); // There shouldn't be more than one job
91     var status = job.getStatus();
92     Console.info(
93             String.format("sec str pred job \"%s\" finished with status %s",
94                     job.getServerJob().getJobId(), status));
95     if (status != JobStatus.COMPLETED)
96       return null;
97     JPredFile predictionFile = client.getPredictionFile(job.getServerJob());
98     AlignFile alignmentFile = client.getAlignmentFile(job.getServerJob());
99
100     Object[] alnAndHiddenCols = alignmentView
101             .getAlignmentAndHiddenColumns(gapChar);
102     Alignment aln = new Alignment((SequenceI[]) alnAndHiddenCols[0]);
103     aln.setDataset(currentView.getDataset());
104     aln.setHiddenColumns((HiddenColumns) alnAndHiddenCols[1]);
105     try
106     {
107       JnetAnnotationMaker.add_annotation(predictionFile, aln, 0, false,
108               job.getDelMap());
109     } catch (Exception e)
110     {
111       throw new IOException(e);
112     }
113
114     for (AlignmentAnnotation alnAnnot : aln.getAlignmentAnnotation())
115     {
116       if (alnAnnot.sequenceRef != null)
117       {
118         AlignmentAnnotationUtils.replaceAnnotationOnAlignmentWith(alnAnnot,
119                 alnAnnot.label, getClass().getSimpleName());
120       }
121     }
122     aln.setSeqrep(aln.getSequenceAt(0));
123     return aln;
124   }
125
126   public static class SecStructPredJob extends BaseJob
127   {
128     private final int[] delMap;
129
130     private final SequenceI refSeq;
131
132     final Map<String, SequenceInfo> seqNames;
133
134     SecStructPredJob(List<SequenceI> sequences, SequenceI refSeq,
135             int[] delMap, Map<String, SequenceInfo> seqNames)
136     {
137       super(sequences);
138       this.refSeq = refSeq;
139       this.delMap = delMap;
140       this.seqNames = seqNames;
141     }
142
143     @Override
144     public boolean isInputValid()
145     {
146       return true;
147     }
148
149     public int[] getDelMap()
150     {
151       return this.delMap;
152     }
153   }
154
155 }