JAL-975 JAL-1119 - prototype adjustable AACons parameters for the currrent alignment...
[jalview.git] / src / jalview / ws / jws2 / SequenceAnnotationWSClient.java
1 /**
2  * 
3  */
4 package jalview.ws.jws2;
5
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.util.List;
9
10 import javax.swing.JCheckBoxMenuItem;
11 import javax.swing.JMenu;
12 import javax.swing.JMenuItem;
13 import javax.swing.JOptionPane;
14 import javax.swing.event.AncestorEvent;
15 import javax.swing.event.AncestorListener;
16 import javax.swing.event.MenuEvent;
17 import javax.swing.event.MenuListener;
18
19 import compbio.metadata.Argument;
20
21 import jalview.api.AlignCalcWorkerI;
22 import jalview.datamodel.AlignmentView;
23 import jalview.gui.AlignFrame;
24 import jalview.gui.Desktop;
25 import jalview.gui.JalviewDialog;
26 import jalview.gui.JvSwingUtils;
27 import jalview.ws.jws2.dm.AAConsSettings;
28 import jalview.ws.jws2.jabaws2.Jws2Instance;
29 import jalview.ws.params.WsParamSetI;
30
31 /**
32  * @author jimp
33  * 
34  */
35 public class SequenceAnnotationWSClient extends Jws2Client
36 {
37
38   /**
39    * initialise a client so its attachWSMenuEntry method can be called.
40    */
41   public SequenceAnnotationWSClient()
42   {
43     // TODO Auto-generated constructor stub
44   }
45
46   public SequenceAnnotationWSClient(final Jws2Instance sh,
47           AlignFrame alignFrame, WsParamSetI preset, boolean editParams)
48   {
49     super(alignFrame, preset, null);
50     initSequenceAnnotationWSClient(sh, alignFrame, preset, editParams);
51   }
52   
53   public void initSequenceAnnotationWSClient(final Jws2Instance sh,
54           AlignFrame alignFrame, WsParamSetI preset, boolean editParams)
55   {
56     if (alignFrame.getViewport().getAlignment().isNucleotide())
57     {
58       JOptionPane.showMessageDialog(Desktop.desktop, sh.serviceType
59               + " can only be used\nfor amino acid alignments.",
60               "Wrong type of sequences!", JOptionPane.WARNING_MESSAGE);
61       return;
62
63     }
64     if (sh.action.toLowerCase().contains("conservation"))
65     {
66       // Build an AACons style client - take alignment, return annotation for
67       // columns
68
69       List<AlignCalcWorkerI> clnts = alignFrame.getViewport()
70               .getCalcManager()
71               .getRegisteredWorkersOfClass(AAConsClient.class);
72       if (clnts == null || clnts.size() == 0)
73       {
74         if (!processParams(sh, editParams))
75         {
76           return;
77         }
78         AAConsClient worker;
79         alignFrame
80                 .getViewport()
81                 .getCalcManager()
82                 .registerWorker(
83                         worker = new AAConsClient(sh, alignFrame, this.preset,
84                                 paramset));
85         alignFrame.getViewport().setPreferredAAConsSettings(new AAConsSettings(true, sh, this.preset, paramset));
86         alignFrame.getViewport().getCalcManager().startWorker(worker);
87
88       }
89       else
90       {
91         AAConsClient worker = (AAConsClient) clnts.get(0);
92         if (editParams)
93         {
94           paramset = worker.getArguments();
95           preset = worker.getPreset();
96         }
97
98         if (!processParams(sh, editParams, true))
99         {
100           return;
101         }
102         alignFrame.getViewport().setPreferredAAConsSettings(new AAConsSettings(true, sh, preset, paramset));
103         // reinstate worker if it was blacklisted (might have happened due to
104         // invalid parameters)
105         alignFrame.getViewport().getCalcManager().workerMayRun(worker);
106         worker.updateParameters(preset, paramset);
107
108       }
109     }
110     if (sh.action.toLowerCase().contains("disorder"))
111     {
112       // build IUPred style client. take sequences, returns annotation per
113       // sequence.
114       if (!processParams(sh, editParams))
115       {
116         return;
117       }
118
119       alignFrame
120               .getViewport()
121               .getCalcManager()
122               .startWorker(
123                       new AADisorderClient(sh, alignFrame, preset, paramset));
124     }
125
126   }
127
128   public SequenceAnnotationWSClient(AAConsSettings fave,
129           AlignFrame alignFrame, boolean b)
130   {
131     super(alignFrame, fave.getPreset(), fave.getJobArgset());
132     initSequenceAnnotationWSClient(fave.getService(), alignFrame, fave.getPreset(), b);
133   }
134
135   /*
136    * (non-Javadoc)
137    * 
138    * @see jalview.ws.jws2.Jws2Client#attachWSMenuEntry(javax.swing.JMenu,
139    * jalview.ws.jws2.jabaws2.Jws2Instance, jalview.gui.AlignFrame)
140    */
141   public void attachWSMenuEntry(JMenu wsmenu, final Jws2Instance service,
142           final AlignFrame alignFrame)
143   {
144     if (service.serviceType.equals(compbio.ws.client.Services.AAConWS
145             .toString()))
146     {
147       registerAAConsWSInstance(wsmenu, service, alignFrame);
148       return;
149     }
150     boolean hasparams = service.hasParameters();
151     // Assume name ends in WS
152     String calcName = service.serviceType.substring(0,
153             service.serviceType.length() - 2);
154
155     JMenuItem aacons = new JMenuItem(calcName + " Defaults");
156     aacons.addActionListener(new ActionListener()
157     {
158
159       @Override
160       public void actionPerformed(ActionEvent e)
161       {
162         new SequenceAnnotationWSClient(service, alignFrame, null, false);
163       }
164     });
165     wsmenu.add(aacons);
166     if (hasparams)
167     {
168       // only add these menu options if the service has user-modifiable
169       // arguments
170       aacons = new JMenuItem("Edit settings and run ...");
171       aacons.setToolTipText("View and change parameters before running calculation");
172
173       aacons.addActionListener(new ActionListener()
174       {
175         public void actionPerformed(ActionEvent e)
176         {
177           new SequenceAnnotationWSClient(service, alignFrame, null, true);
178         }
179       });
180       wsmenu.add(aacons);
181       List<WsParamSetI> presets = service.getParamStore().getPresets();
182       if (presets != null && presets.size() > 0)
183       {
184         JMenu presetlist = new JMenu("Run " + calcName + "with preset");
185
186         for (final WsParamSetI preset : presets)
187         {
188           final JMenuItem methodR = new JMenuItem(preset.getName());
189           methodR.setToolTipText("<html><p>"
190                   + JvSwingUtils.wrapTooltip("<strong>"
191                           + (preset.isModifiable() ? "User Preset"
192                                   : "Service Preset") + "</strong><br/>"
193                           + preset.getDescription() + "</p>") + "</html>");
194           methodR.addActionListener(new ActionListener()
195           {
196             public void actionPerformed(ActionEvent e)
197             {
198               new SequenceAnnotationWSClient(service, alignFrame, preset,
199                       false);
200             }
201
202           });
203           presetlist.add(methodR);
204         }
205         wsmenu.add(presetlist);
206       }
207
208     }
209   }
210
211   private final String AAconsToggle = "AACons Calculations",
212           AAconsToggleTooltip = "When checked, AACons calculations are updated automatically.",
213           AAeditSettings = "Change AACons Settings...",
214           AAeditSettingsTooltip = "Modify settings for AACons calculations.";
215
216   private SequenceAnnotationWSClient preferredAAConsClient = null;
217
218   // private final enableAAConsCalculation(final AlignFrame alignFrame, )
219   private void registerAAConsWSInstance(final JMenu wsmenu,
220           final Jws2Instance service, final AlignFrame alignFrame)
221   {
222     // register this in the AACons settings set
223     JCheckBoxMenuItem _aaConsEnabled = null;
224     for (int i = 0; i < wsmenu.getItemCount(); i++)
225     {
226       JMenuItem item = wsmenu.getItem(i);
227       if (item instanceof JCheckBoxMenuItem
228               && item.getText().equals(AAconsToggle))
229       {
230         _aaConsEnabled = (JCheckBoxMenuItem) item;
231       }
232     }
233
234     // is there a service already registered ?
235     if (_aaConsEnabled == null)
236     {
237       final JCheckBoxMenuItem aaConsEnabled = new JCheckBoxMenuItem(
238               AAconsToggle);
239       wsmenu.addMenuListener(new MenuListener()
240       {
241
242         @Override
243         public void menuSelected(MenuEvent arg0)
244         {
245           wsmenu.setEnabled(!alignFrame.getViewport().getAlignment()
246                   .isNucleotide());
247           List<AlignCalcWorkerI> aaconsClient = alignFrame.getViewport()
248                   .getCalcManager()
249                   .getRegisteredWorkersOfClass(AAConsClient.class);
250           if (aaconsClient != null && aaconsClient.size() > 0)
251           {
252             aaConsEnabled.setSelected(true);
253           }
254           else
255           {
256             aaConsEnabled.setSelected(false);
257           }
258         }
259
260         @Override
261         public void menuDeselected(MenuEvent arg0)
262         {
263           // TODO Auto-generated method stub
264
265         }
266
267         @Override
268         public void menuCanceled(MenuEvent arg0)
269         {
270           // TODO Auto-generated method stub
271
272         }
273       });
274       aaConsEnabled.setToolTipText("<html><p>"
275               + JvSwingUtils.wrapTooltip(AAconsToggleTooltip + "</p>")
276               + "</html>");
277       aaConsEnabled.addActionListener(new ActionListener()
278       {
279         @Override
280         public void actionPerformed(ActionEvent arg0)
281         {
282           // aaConsEnabled.setSelected(!aaConsEnabled.isSelected());
283           List<AlignCalcWorkerI> aaconsClient = alignFrame.getViewport()
284                   .getCalcManager()
285                   .getRegisteredWorkersOfClass(AAConsClient.class);
286           if (aaconsClient != null && aaconsClient.size() > 0)
287           {
288             removeCurrentAAConsWorkerFor(alignFrame);
289           }
290           else
291           {
292             buildCurrentAAConsWorkerFor(alignFrame);
293
294           }
295         }
296
297       });
298       wsmenu.add(aaConsEnabled);
299       JMenuItem modifyParams = new JMenuItem(AAeditSettings);
300       modifyParams.setToolTipText("<html><p>"
301               + JvSwingUtils.wrapTooltip(AAeditSettingsTooltip + "</p>")
302               + "</html>");
303       modifyParams.addActionListener(new ActionListener()
304       {
305
306         @Override
307         public void actionPerformed(ActionEvent arg0)
308         {
309           showAAConsAnnotationSettingsFor(alignFrame);
310         }
311       });
312       wsmenu.add(modifyParams);
313
314     }
315
316   }
317
318   private static void showAAConsAnnotationSettingsFor(AlignFrame alignFrame)
319   {
320     /*
321      * preferred settings
322      * Whether AACons is automatically recalculated
323      * Which AACons server to use
324      * What parameters to use
325      */
326     AAConsSettings fave= alignFrame.getViewport().getPreferredAAConsSettings();
327     if (fave==null)
328     {
329       fave = createDefaultAAConsSettings();
330     }
331     new SequenceAnnotationWSClient(fave, alignFrame, true);
332
333   }
334   private static void buildCurrentAAConsWorkerFor(AlignFrame alignFrame)
335   {
336     /*
337      * preferred settings
338      * Whether AACons is automatically recalculated
339      * Which AACons server to use
340      * What parameters to use
341      */
342     AAConsSettings fave= alignFrame.getViewport().getPreferredAAConsSettings();
343     if (fave==null)
344     {
345       fave = createDefaultAAConsSettings();
346     }
347     new SequenceAnnotationWSClient(fave, alignFrame, false);
348   }
349
350   private static AAConsSettings createDefaultAAConsSettings()
351   {
352     Jws2Instance service=null;
353     // set sensible defaults
354     for (Jws2Instance sv: Jws2Discoverer.getDiscoverer().getServices()) {
355       if (sv.serviceType.toString().equals(compbio.ws.client.Services.AAConWS.toString()))
356       {
357         service = sv;
358         break;
359       }
360     }
361     if (service==null)
362     {
363       // TODO raise dialog box explaining error, and/or open the JABA preferences menu.
364       throw new Error("No AACons service found.");
365     }
366     return new AAConsSettings(true, service, null, null);
367   }
368
369   private static void removeCurrentAAConsWorkerFor(AlignFrame alignFrame)
370   {
371     alignFrame.getViewport().getCalcManager()
372             .removeRegisteredWorkersOfClass(AAConsClient.class);
373     // AAConsClient.removeAAConsAnnotation(alignFrame.alignPanel);
374
375   }
376 }