Clover icon

Coverage Report

  1. Project Clover database Fri Nov 15 2024 13:56:46 GMT
  2. Package jalview.ext.jmol

File JmolParser.java

 

Coverage histogram

../../../img/srcFileCovDistChart7.png
29% of files have more coverage

Code metrics

86
255
38
1
803
600
117
0.46
6.71
38
3.08

Classes

Class Line # Actions
JmolParser 68 255 117
0.64643864.6%
 

Contributing tests

This file is covered by 53 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.ext.jmol;
22   
23    import java.io.File;
24    import java.io.IOException;
25    import java.util.ArrayList;
26    import java.util.HashMap;
27    import java.util.List;
28    import java.util.Locale;
29    import java.util.Map;
30    import java.util.Vector;
31   
32    import org.jmol.api.JmolStatusListener;
33    import org.jmol.api.JmolViewer;
34    import org.jmol.c.CBK;
35    import org.jmol.c.STR;
36    import org.jmol.modelset.ModelSet;
37    import org.jmol.viewer.Viewer;
38   
39    import com.stevesoft.pat.Regex;
40   
41    import jalview.bin.Console;
42    import jalview.datamodel.Alignment;
43    import jalview.datamodel.AlignmentAnnotation;
44    import jalview.datamodel.Annotation;
45    import jalview.datamodel.PDBEntry;
46    import jalview.datamodel.SequenceI;
47    import jalview.datamodel.annotations.AlphaFoldAnnotationRowBuilder;
48    import jalview.datamodel.annotations.AnnotationRowBuilder;
49    import jalview.datamodel.annotations.QMEANDISCORowBuilder;
50    import jalview.io.DataSourceType;
51    import jalview.io.FileParse;
52    import jalview.io.StructureFile;
53    import jalview.schemes.ResidueProperties;
54    import jalview.structure.StructureImportSettings;
55    import jalview.util.Format;
56    import jalview.util.MessageManager;
57    import jalview.ws.dbsources.EBIAlfaFold;
58    import mc_view.Atom;
59    import mc_view.PDBChain;
60    import mc_view.Residue;
61   
62    /**
63    * Import and process files with Jmol for file like PDB, mmCIF
64    *
65    * @author jprocter
66    *
67    */
 
68    public class JmolParser extends StructureFile implements JmolStatusListener
69    {
70    Viewer viewer = null;
71   
 
72  150 toggle public JmolParser(boolean immediate, Object inFile,
73    DataSourceType sourceType) throws IOException
74    {
75    // BH 2018 File or String for filename
76  150 super(immediate, inFile, sourceType);
77   
78    }
79   
 
80  6 toggle public JmolParser(Object inFile, DataSourceType sourceType)
81    throws IOException
82    {
83  6 this(inFile, sourceType, null);
84    }
85   
 
86  21 toggle public JmolParser(Object inFile, DataSourceType sourceType,
87    StructureImportSettings.TFType tempfacType) throws IOException
88    {
89  21 super(inFile, sourceType, tempfacType);
90    }
91   
 
92  5 toggle public JmolParser(FileParse fp, boolean doXferSettings) throws IOException
93    {
94  5 super(fp, doXferSettings);
95    }
96   
 
97  0 toggle public JmolParser(FileParse fp) throws IOException
98    {
99  0 super(fp);
100    }
101   
 
102  1 toggle public JmolParser()
103    {
104    }
105   
106    /**
107    * Calls the Jmol library to parse the PDB/mmCIF file, and then inspects the
108    * resulting object model to generate Jalview-style sequences, with secondary
109    * structure annotation added where available (i.e. where it has been computed
110    * by Jmol using DSSP).
111    *
112    * @see jalview.io.AlignFile#parse()
113    */
 
114  0 toggle @Override
115    public void parse() throws IOException
116    {
117  0 parse(true);
118    }
119   
 
120  176 toggle @Override
121    public void parse(boolean doXferSettings) throws IOException
122    {
123  176 setChains(new Vector<PDBChain>());
124  176 Viewer jmolModel = getJmolData();
125  176 jmolModel.openReader(getDataName(), getDataName(), getReader());
126  176 waitForScript(jmolModel);
127   
128    /*
129    * Convert one or more Jmol Model objects to Jalview sequences
130    */
131  176 if (jmolModel.ms.mc > 0)
132    {
133    // ideally we do this
134    // try
135    // {
136    // setStructureFileType(jmolModel.evalString("show _fileType"));
137    // } catch (Exception q)
138    // {
139    // }
140    // ;
141    // instead, we distinguish .cif from non-.cif by filename
142  176 setStructureFileType(
143  176 getDataName().toLowerCase(Locale.ROOT).endsWith(".cif")
144    ? PDBEntry.Type.MMCIF.toString()
145    : "PDB");
146   
147  176 transformJmolModelToJalview(jmolModel.ms, doXferSettings);
148    }
149    }
150   
151    /**
152    * create a headless jmol instance for dataprocessing
153    *
154    * @return
155    */
 
156  176 toggle private Viewer getJmolData()
157    {
158  176 if (viewer == null)
159    {
160  176 try
161    {
162    /*
163    * params -o (output to sysout) -n (nodisplay) -x (exit when finished)
164    * see http://wiki.jmol.org/index.php/Jmol_Application
165    */
166   
167  176 viewer = JalviewJmolBinding.getJmolData(this);
168    // ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used
169  176 viewer.setBooleanProperty("defaultStructureDSSP", true);
170    } catch (ClassCastException x)
171    {
172  0 throw new Error(MessageManager.formatMessage(
173    "error.jmol_version_not_compatible_with_jalview_version",
174    new String[]
175    { JmolViewer.getJmolVersion() }), x);
176    }
177    }
178  176 return viewer;
179    }
180   
 
181  176 toggle public static Regex getNewAlphafoldValidator()
182    {
183  176 Regex validator = new Regex("(AF-[A-Z]+[0-9]+[A-Z0-9]+-F1)");
184  176 validator.setIgnoreCase(true);
185  176 return validator;
186    }
187   
188    PDBEntry.Type jmolFiletype = null;
189   
190    /**
191    * resolve a jmol filetype string and update the jmolFiletype field
192    * accordingly
193    *
194    * @param jmolIdentifiedFileType
195    * @return true if filetype was identified as MMCIF, PDB
196    */
 
197  176 toggle public boolean updateFileType(String jmolIdentifiedFileType)
198    {
199  176 if (jmolIdentifiedFileType == null
200    || jmolIdentifiedFileType.trim().equals(""))
201    {
202  0 return false;
203    }
204  176 if ("mmcif".equalsIgnoreCase(jmolIdentifiedFileType))
205    {
206  18 jmolFiletype = PDBEntry.Type.MMCIF;
207  18 return true;
208    }
209  158 if ("pdb".equalsIgnoreCase(jmolIdentifiedFileType))
210    {
211  158 jmolFiletype = PDBEntry.Type.PDB;
212  158 return true;
213    }
214  0 return false;
215    }
216   
 
217  176 toggle public void transformJmolModelToJalview(ModelSet ms,
218    boolean localDoXferSettings) throws IOException
219    {
220  176 try
221    {
222  176 Regex alphaFold = getNewAlphafoldValidator();
223  176 String lastID = "";
224  176 List<SequenceI> rna = new ArrayList<SequenceI>();
225  176 List<SequenceI> prot = new ArrayList<SequenceI>();
226  176 PDBChain tmpchain;
227  176 String pdbId = (String) ms.getInfo(0, "title");
228  176 boolean isMMCIF = false;
229  176 String jmolFileType_String = (String) ms.getInfo(0, "fileType");
230  176 if (updateFileType(jmolFileType_String))
231    {
232  176 setStructureFileType(jmolFiletype.toString());
233    }
234   
235  176 isMMCIF = PDBEntry.Type.MMCIF.equals(jmolFiletype);
236   
237  176 if (pdbId == null)
238    {
239  60 setId(safeName(getDataName()));
240  60 setPDBIdAvailable(false);
241    }
242    else
243    {
244  116 setId(pdbId);
245  116 setPDBIdAvailable(true);
246  116 setAlphafoldModel(alphaFold.search(pdbId) && isMMCIF);
247    }
248  176 List<Atom> significantAtoms = convertSignificantAtoms(ms);
249  176 for (Atom tmpatom : significantAtoms)
250    {
251  41042 if (tmpatom.resNumIns.trim().equals(lastID))
252    {
253    // phosphorylated protein - seen both CA and P..
254  1 continue;
255    }
256  41041 tmpchain = findChain(tmpatom.chain);
257  41041 if (tmpchain != null)
258    {
259  40773 tmpchain.atoms.addElement(tmpatom);
260    }
261    else
262    {
263  268 AnnotationRowBuilder builder = null;
264  268 if (isAlphafoldModel()
265    || getTemperatureFactorType() == StructureImportSettings.TFType.PLDDT)
266    {
267  41 builder = new AlphaFoldAnnotationRowBuilder();
268    }
269  268 if (getTemperatureFactorType() == StructureImportSettings.TFType.QMEANDISCO)
270    {
271  0 builder = new QMEANDISCORowBuilder();
272    }
273   
274  268 tmpchain = new PDBChain(getId(), tmpatom.chain, builder);
275  268 getChains().add(tmpchain);
276  268 tmpchain.atoms.addElement(tmpatom);
277    }
278  41041 lastID = tmpatom.resNumIns.trim();
279    }
280  176 if (isParseImmediately() && localDoXferSettings)
281    {
282    // configure parsing settings from the static singleton
283  119 xferSettings();
284    }
285   
286  176 makeResidueList();
287  176 makeCaBondList();
288   
289  176 for (PDBChain chain : getChains())
290    {
291  268 SequenceI chainseq = postProcessChain(chain);
292  268 if (isRNA(chainseq))
293    {
294  0 rna.add(chainseq);
295    }
296    else
297    {
298  268 prot.add(chainseq);
299    }
300   
301    // look at local setting for adding secondary tructure
302  268 if (predictSecondaryStructure)
303    {
304  238 createAnnotation(chainseq, chain, ms.at);
305    }
306    }
307    // if Alphafold, fetch the PAE matrix if doesn't already have one
308  176 if (isAlphafoldModel() && !hasPAEMatrix())
309    {
310  0 try
311    {
312  0 Console.info("Retrieving PAE for " + pdbId);
313  0 File paeFile = EBIAlfaFold.fetchAlphaFoldPAE(pdbId, null);
314  0 this.setPAEMatrix(paeFile.getAbsolutePath());
315    } catch (Throwable t)
316    {
317  0 Console.error("Couldn't get the pAE for " + pdbId, t);
318    }
319    }
320    // add a PAEMatrix if set (either by above or otherwise)
321  176 if (hasPAEMatrix())
322    {
323  57 try
324    {
325  57 Alignment al = new Alignment(prot.toArray(new SequenceI[0]));
326  57 EBIAlfaFold.addAlphaFoldPAE(al, new File(this.getPAEMatrix()), 0,
327    null, false, false, null);
328   
329  57 if (al.getAlignmentAnnotation() != null)
330    {
331  57 for (AlignmentAnnotation alann : al.getAlignmentAnnotation())
332    {
333  57 annotations.add(alann);
334    }
335    }
336    } catch (Throwable ff)
337    {
338  0 Console.error("Couldn't import PAE Matrix from " + getPAEMatrix(),
339    ff);
340  0 warningMessage += "Couldn't import PAE Matrix"
341    + getNewlineString() + ff.getLocalizedMessage()
342    + getNewlineString();
343    }
344    }
345    } catch (OutOfMemoryError er)
346    {
347  0 jalview.bin.Console.outPrintln(
348    "OUT OF MEMORY LOADING TRANSFORMING JMOL MODEL TO JALVIEW MODEL");
349  0 throw new IOException(MessageManager
350    .getString("exception.outofmemory_loading_mmcif_file"));
351    }
352    }
353   
 
354  176 toggle private List<Atom> convertSignificantAtoms(ModelSet ms)
355    {
356  176 List<Atom> significantAtoms = new ArrayList<Atom>();
357  176 HashMap<String, org.jmol.modelset.Atom> chainTerMap = new HashMap<String, org.jmol.modelset.Atom>();
358  176 org.jmol.modelset.Atom prevAtom = null;
359  176 for (org.jmol.modelset.Atom atom : ms.at)
360    {
361  211582 if (atom.getAtomName().equalsIgnoreCase("CA")
362    || atom.getAtomName().equalsIgnoreCase("P"))
363    {
364  41070 if (!atomValidated(atom, prevAtom, chainTerMap))
365    {
366  24 continue;
367    }
368  41046 Atom curAtom = new Atom(atom.x, atom.y, atom.z);
369  41046 curAtom.atomIndex = atom.getIndex();
370  41046 curAtom.chain = atom.getChainIDStr();
371  41046 curAtom.insCode = atom.group.getInsertionCode() == '\000' ? ' '
372    : atom.group.getInsertionCode();
373  41046 curAtom.name = atom.getAtomName();
374  41046 curAtom.number = atom.getAtomNumber();
375  41046 curAtom.resName = atom.getGroup3(true);
376  41046 curAtom.resNumber = atom.getResno();
377  41046 curAtom.occupancy = ms.occupancies != null
378    ? ms.occupancies[atom.getIndex()]
379    : Float.valueOf(atom.getOccupancy100());
380  41046 String fmt = new Format("%4i").form(curAtom.resNumber);
381  41046 curAtom.resNumIns = (fmt + curAtom.insCode);
382  41046 curAtom.tfactor = atom.getBfactor100() / 100f;
383  41046 curAtom.type = 0;
384    // significantAtoms.add(curAtom);
385    // ignore atoms from subsequent models
386  41046 if (!significantAtoms.contains(curAtom))
387    {
388  41042 significantAtoms.add(curAtom);
389    }
390  41046 prevAtom = atom;
391    }
392    }
393  176 return significantAtoms;
394    }
395   
 
396  41070 toggle private boolean atomValidated(org.jmol.modelset.Atom curAtom,
397    org.jmol.modelset.Atom prevAtom,
398    HashMap<String, org.jmol.modelset.Atom> chainTerMap)
399    {
400    // jalview.bin.Console.outPrintln("Atom: " + curAtom.getAtomNumber()
401    // + " Last atom index " + curAtom.group.lastAtomIndex);
402  41070 if (chainTerMap == null || prevAtom == null)
403    {
404  176 return true;
405    }
406  40894 String curAtomChId = curAtom.getChainIDStr();
407  40894 String prevAtomChId = prevAtom.getChainIDStr();
408    // new chain encoutered
409  40894 if (!prevAtomChId.equals(curAtomChId))
410    {
411    // On chain switch add previous chain termination to xTerMap if not exists
412  116 if (!chainTerMap.containsKey(prevAtomChId))
413    {
414  104 chainTerMap.put(prevAtomChId, prevAtom);
415    }
416    // if current atom belongs to an already terminated chain and the resNum
417    // diff < 5 then mark as valid and update termination Atom
418  116 if (chainTerMap.containsKey(curAtomChId))
419    {
420  24 if (curAtom.getResno() < chainTerMap.get(curAtomChId).getResno())
421    {
422  0 return false;
423    }
424  24 if ((curAtom.getResno()
425    - chainTerMap.get(curAtomChId).getResno()) < 5)
426    {
427  0 chainTerMap.put(curAtomChId, curAtom);
428  0 return true;
429    }
430  24 return false;
431    }
432    }
433    // atom with previously terminated chain encountered
434  40778 else if (chainTerMap.containsKey(curAtomChId))
435    {
436  0 if (curAtom.getResno() < chainTerMap.get(curAtomChId).getResno())
437    {
438  0 return false;
439    }
440  0 if ((curAtom.getResno()
441    - chainTerMap.get(curAtomChId).getResno()) < 5)
442    {
443  0 chainTerMap.put(curAtomChId, curAtom);
444  0 return true;
445    }
446  0 return false;
447    }
448    // HETATM with resNum jump > 2
449  40870 return !(curAtom.isHetero()
450    && ((curAtom.getResno() - prevAtom.getResno()) > 2));
451    }
452   
 
453  238 toggle private void createAnnotation(SequenceI sequence, PDBChain chain,
454    org.jmol.modelset.Atom[] jmolAtoms)
455    {
456  238 char[] secstr = new char[sequence.getLength()];
457  238 char[] secstrcode = new char[sequence.getLength()];
458   
459    // Ensure Residue size equals Seq size
460  238 if (chain.residues.size() != sequence.getLength())
461    {
462  0 return;
463    }
464  238 int annotIndex = 0;
465  238 for (Residue residue : chain.residues)
466    {
467  37775 Atom repAtom = residue.getAtoms().get(0);
468  37775 STR proteinStructureSubType = jmolAtoms[repAtom.atomIndex].group
469    .getProteinStructureSubType();
470  37775 setSecondaryStructure(proteinStructureSubType, annotIndex, secstr,
471    secstrcode);
472  37775 ++annotIndex;
473    }
474  238 addSecondaryStructureAnnotation(chain.pdbid, sequence, secstr,
475    secstrcode, chain.id, sequence.getStart());
476    }
477   
478    /**
479    * Helper method that adds an AlignmentAnnotation for secondary structure to
480    * the sequence, provided at least one secondary structure assignment has been
481    * made
482    *
483    * @param modelTitle
484    * @param seq
485    * @param secstr
486    * @param secstrcode
487    * @param chainId
488    * @param firstResNum
489    * @return
490    */
 
491  238 toggle protected void addSecondaryStructureAnnotation(String modelTitle,
492    SequenceI sq, char[] secstr, char[] secstrcode, String chainId,
493    int firstResNum)
494    {
495  238 int length = sq.getLength();
496  238 boolean ssFound = false;
497  238 Annotation asecstr[] = new Annotation[length
498    + (firstResNum - sq.getStart())];
499  38013 for (int p = 0; p < length; p++)
500    {
501  37775 if (secstr[p] >= 'A' && secstr[p] <= 'z')
502    {
503  14682 try
504    {
505  14682 asecstr[p] = new Annotation(null, null, secstrcode[p], Float.NaN);
506  14682 ssFound = true;
507    } catch (Exception e)
508    {
509    // e.printStackTrace();
510    }
511    }
512    }
513   
514  238 if (ssFound)
515    {
516  216 String mt = modelTitle == null ? getDataName() : modelTitle;
517  216 mt += chainId;
518  216 AlignmentAnnotation ann = new AlignmentAnnotation(
519    "Secondary Structure", "Secondary Structure for " + mt,
520    asecstr);
521  216 ann.belowAlignment = true;
522  216 ann.visible = true;
523  216 ann.autoCalculated = false;
524  216 ann.setCalcId(getClass().getName());
525  216 ann.adjustForAlignment();
526  216 ann.validateRangeAndDisplay();
527  216 annotations.add(ann);
528  216 sq.addAlignmentAnnotation(ann);
529    }
530    }
531   
 
532  176 toggle private void waitForScript(Viewer jmd)
533    {
534  176 while (jmd.isScriptExecuting())
535    {
536  0 try
537    {
538  0 Thread.sleep(50);
539   
540    } catch (InterruptedException x)
541    {
542    }
543    }
544    }
545   
546    /**
547    * Convert Jmol's secondary structure code to Jalview's, and stored it in the
548    * secondary structure arrays at the given sequence position
549    *
550    * @param proteinStructureSubType
551    * @param pos
552    * @param secstr
553    * @param secstrcode
554    */
 
555  37781 toggle protected void setSecondaryStructure(STR proteinStructureSubType, int pos,
556    char[] secstr, char[] secstrcode)
557    {
558  37781 switch (proteinStructureSubType)
559    {
560  662 case HELIX310:
561  662 secstr[pos] = '3';
562  662 break;
563  4177 case HELIX:
564  4885 case HELIXALPHA:
565  9062 secstr[pos] = 'H';
566  9062 break;
567  1 case HELIXPI:
568  1 secstr[pos] = 'P';
569  1 break;
570  5623 case SHEET:
571  5623 secstr[pos] = 'E';
572  5623 break;
573  22433 default:
574  22433 secstr[pos] = 0;
575    }
576   
577  37781 switch (proteinStructureSubType)
578    {
579  662 case HELIX310:
580  4885 case HELIXALPHA:
581  1 case HELIXPI:
582  4177 case HELIX:
583  9725 secstrcode[pos] = 'H';
584  9725 break;
585  5623 case SHEET:
586  5623 secstrcode[pos] = 'E';
587  5623 break;
588  22433 default:
589  22433 secstrcode[pos] = 0;
590    }
591    }
592   
593    /**
594    * Convert any non-standard peptide codes to their standard code table
595    * equivalent. (Initial version only does Selenomethionine MSE->MET.)
596    *
597    * @param threeLetterCode
598    * @param seq
599    * @param pos
600    */
 
601  0 toggle protected void replaceNonCanonicalResidue(String threeLetterCode,
602    char[] seq, int pos)
603    {
604  0 String canonical = ResidueProperties
605    .getCanonicalAminoAcid(threeLetterCode);
606  0 if (canonical != null && !canonical.equalsIgnoreCase(threeLetterCode))
607    {
608  0 seq[pos] = ResidueProperties.getSingleCharacterCode(canonical);
609    }
610    }
611   
612    /**
613    * Not implemented - returns null
614    */
 
615  0 toggle @Override
616    public String print(SequenceI[] seqs, boolean jvSuffix)
617    {
618  0 return null;
619    }
620   
621    /**
622    * Not implemented
623    */
 
624  0 toggle @Override
625    public void setCallbackFunction(String callbackType,
626    String callbackFunction)
627    {
628    }
629   
 
630  0 toggle @Override
631    public void notifyCallback(CBK cbType, Object[] data)
632    {
633  0 String strInfo = (data == null || data[1] == null ? null
634    : data[1].toString());
635  0 switch (cbType)
636    {
637  0 case ECHO:
638  0 sendConsoleEcho(strInfo);
639  0 break;
640  0 case SCRIPT:
641  0 notifyScriptTermination((String) data[2],
642    ((Integer) data[3]).intValue());
643  0 break;
644  0 case MEASURE:
645  0 String mystatus = (String) data[3];
646  0 if (mystatus.indexOf("Picked") >= 0
647    || mystatus.indexOf("Sequence") >= 0)
648    {
649    // Picking mode
650  0 sendConsoleMessage(strInfo);
651    }
652  0 else if (mystatus.indexOf("Completed") >= 0)
653    {
654  0 sendConsoleEcho(strInfo.substring(strInfo.lastIndexOf(",") + 2,
655    strInfo.length() - 1));
656    }
657  0 break;
658  0 case MESSAGE:
659  0 sendConsoleMessage(data == null ? null : strInfo);
660  0 break;
661  0 case PICK:
662  0 sendConsoleMessage(strInfo);
663  0 break;
664  0 default:
665  0 break;
666    }
667    }
668   
669    String lastConsoleEcho = "";
670   
 
671  0 toggle private void sendConsoleEcho(String string)
672    {
673  0 lastConsoleEcho += string;
674  0 lastConsoleEcho += "\n";
675    }
676   
677    String lastConsoleMessage = "";
678   
 
679  0 toggle private void sendConsoleMessage(String string)
680    {
681  0 lastConsoleMessage += string;
682  0 lastConsoleMessage += "\n";
683    }
684   
685    int lastScriptTermination = -1;
686   
687    String lastScriptMessage = "";
688   
 
689  0 toggle private void notifyScriptTermination(String string, int intValue)
690    {
691  0 lastScriptMessage += string;
692  0 lastScriptMessage += "\n";
693  0 lastScriptTermination = intValue;
694    }
695   
 
696  0 toggle @Override
697    public boolean notifyEnabled(CBK callbackPick)
698    {
699  0 switch (callbackPick)
700    {
701  0 case MESSAGE:
702  0 case SCRIPT:
703  0 case ECHO:
704  0 case LOADSTRUCT:
705  0 case ERROR:
706  0 return true;
707  0 default:
708  0 return false;
709    }
710    }
711   
712    /**
713    * Not implemented - returns null
714    */
 
715  0 toggle @Override
716    public String eval(String strEval)
717    {
718  0 return null;
719    }
720   
721    /**
722    * Not implemented - returns null
723    */
 
724  0 toggle @Override
725    public float[][] functionXY(String functionName, int x, int y)
726    {
727  0 return null;
728    }
729   
730    /**
731    * Not implemented - returns null
732    */
 
733  0 toggle @Override
734    public float[][][] functionXYZ(String functionName, int nx, int ny,
735    int nz)
736    {
737  0 return null;
738    }
739   
740    /**
741    * Not implemented - returns null
742    */
 
743  0 toggle @Override
744    public String createImage(String fileName, String imageType,
745    Object text_or_bytes, int quality)
746    {
747  0 return null;
748    }
749   
750    /**
751    * Not implemented - returns null
752    */
 
753  0 toggle @Override
754    public Map<String, Object> getRegistryInfo()
755    {
756  0 return null;
757    }
758   
759    /**
760    * Not implemented
761    */
 
762  0 toggle @Override
763    public void showUrl(String url)
764    {
765    }
766   
767    /**
768    * Not implemented - returns null
769    */
 
770  0 toggle @Override
771    public int[] resizeInnerPanel(String data)
772    {
773  0 return null;
774    }
775   
 
776  0 toggle @Override
777    public Map<String, Object> getJSpecViewProperty(String arg0)
778    {
779  0 return null;
780    }
781   
 
782  0 toggle public boolean isPredictSecondaryStructure()
783    {
784  0 return predictSecondaryStructure;
785    }
786   
 
787  0 toggle public void setPredictSecondaryStructure(
788    boolean predictSecondaryStructure)
789    {
790  0 this.predictSecondaryStructure = predictSecondaryStructure;
791    }
792   
 
793  0 toggle public boolean isVisibleChainAnnotation()
794    {
795  0 return visibleChainAnnotation;
796    }
797   
 
798  0 toggle public void setVisibleChainAnnotation(boolean visibleChainAnnotation)
799    {
800  0 this.visibleChainAnnotation = visibleChainAnnotation;
801    }
802   
803    }