Clover icon

Coverage Report

  1. Project Clover database Thu Nov 7 2024 13:01:17 GMT
  2. Package jalview.ext.jmol

File JmolParser.java

 

Coverage histogram

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

Code metrics

84
253
38
1
798
595
116
0.46
6.66
38
3.05

Classes

Class Line # Actions
JmolParser 67 253 116
0.661333366.1%
 

Contributing tests

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