ff129a4317d7b26e6416dc02f956a0315ff32b61
[jalview.git] / src / jalview / io / JSONFile.java
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
22 package jalview.io;
23
24 import java.awt.Color;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.Hashtable;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Vector;
31
32 import org.json.simple.JSONArray;
33 import org.json.simple.JSONObject;
34 import org.json.simple.parser.JSONParser;
35
36 import jalview.api.AlignViewportI;
37 import jalview.api.ComplexAlignFile;
38 import jalview.api.FeatureRenderer;
39 import jalview.api.FeaturesDisplayedI;
40 import jalview.datamodel.AlignmentAnnotation;
41 import jalview.datamodel.Annotation;
42 import jalview.datamodel.ColumnSelection;
43 import jalview.datamodel.HiddenSequences;
44 import jalview.datamodel.Sequence;
45 import jalview.datamodel.SequenceFeature;
46 import jalview.datamodel.SequenceGroup;
47 import jalview.datamodel.SequenceI;
48 import jalview.json.binding.v1.AlignmentAnnotationPojo;
49 import jalview.json.binding.v1.AlignmentPojo;
50 import jalview.json.binding.v1.AlignmentPojo.JalviewBioJsColorSchemeMapper;
51 import jalview.json.binding.v1.AnnotationPojo;
52 import jalview.json.binding.v1.SequenceFeaturesPojo;
53 import jalview.json.binding.v1.SequenceGrpPojo;
54 import jalview.json.binding.v1.SequencePojo;
55 import jalview.schemes.ColourSchemeI;
56 import jalview.schemes.ColourSchemeProperty;
57
58 public class JSONFile extends AlignFile implements ComplexAlignFile
59 {
60   private ColourSchemeI colourScheme;
61
62   private String version = "2.9";
63
64   private String webstartUrl = "www.jalview.org/services/launchApp";
65
66   private String application = "Jalview";
67
68   public static final String FILE_EXT = "json";
69
70   public static final String FILE_DESC = "JSON";
71
72   private String globalColorScheme;
73
74   private boolean showSeqFeatures;
75
76   private Hashtable<String, Sequence> seqMap;
77
78   private FeaturesDisplayedI displayedFeatures;
79
80   private FeatureRenderer fr;
81
82   private JSONExportSettings jsonExportSettings;
83
84   private List<int[]> hiddenColumns;
85
86   private ColumnSelection columnSelection;
87
88   private List<String> hiddenSeqRefs;
89
90   private ArrayList<SequenceI> hiddenSequences;
91
92   public JSONFile()
93   {
94     super();
95   }
96
97   public JSONFile(FileParse source) throws IOException
98   {
99     super(source);
100   }
101
102   public JSONFile(String inFile, String type) throws IOException
103   {
104     super(inFile, type);
105   }
106
107   @Override
108   public void parse() throws IOException
109   {
110     StringBuilder jsonStringBuilder = new StringBuilder();
111     String currentLine;
112     while ((currentLine = nextLine()) != null)
113     {
114       jsonStringBuilder.append(currentLine);
115     }
116     parse(jsonStringBuilder.toString());
117
118   }
119
120   @Override
121   public String print()
122   {
123     String jsonOutput = null;
124     try
125     {
126       if (getJsonExportSettings() == null)
127       {
128         jsonExportSettings = new JSONExportSettings();
129         jsonExportSettings.setExportAnnotations(true);
130         jsonExportSettings.setExportGroups(true);
131         jsonExportSettings.setExportJalviewSettings(true);
132         jsonExportSettings.setExportSequenceFeatures(true);
133       }
134
135       AlignmentPojo jsonAlignmentPojo = new AlignmentPojo();
136       if (getViewport() != null)
137       {
138         globalColorScheme = ColourSchemeProperty
139                 .getColourName(getViewport()
140                 .getGlobalColourScheme());
141         setDisplayedFeatures(getViewport().getFeaturesDisplayed());
142         showSeqFeatures = getViewport().isShowSequenceFeatures();
143         fr = getViewport().getFeatureRenderer();
144       }
145
146       int count = 0;
147       for (SequenceI seq : seqs)
148       {
149         StringBuilder name = new StringBuilder();
150         name.append(seq.getName()).append("/").append(seq.getStart())
151                 .append("-").append(seq.getEnd());
152         SequencePojo jsonSeqPojo = new SequencePojo();
153         jsonSeqPojo.setId(String.valueOf(seq.hashCode()));
154         jsonSeqPojo.setOrder(++count);
155         jsonSeqPojo.setEnd(seq.getEnd());
156         jsonSeqPojo.setStart(seq.getStart());
157         jsonSeqPojo.setName(name.toString());
158         jsonSeqPojo.setSeq(seq.getSequenceAsString());
159         jsonAlignmentPojo.getSeqs().add(jsonSeqPojo);
160       }
161
162       if (jsonExportSettings.isExportJalviewSettings())
163       {
164         jsonAlignmentPojo.setGlobalColorScheme(globalColorScheme);
165         jsonAlignmentPojo.getAppSettings().put("application", application);
166         jsonAlignmentPojo.getAppSettings().put("version", version);
167         jsonAlignmentPojo.getAppSettings().put("webStartUrl", webstartUrl);
168         jsonAlignmentPojo.getAppSettings().put("showSeqFeatures",
169                 String.valueOf(showSeqFeatures));
170
171         String[] hiddenSections = exportHiddenSections();
172         if (hiddenSections != null && getViewport().isIncludeHiddenRegion())
173         {
174           if (hiddenSections[0] != null)
175           {
176             jsonAlignmentPojo.getAppSettings().put("hiddenCols",
177                     String.valueOf(hiddenSections[0]));
178           }
179           if (hiddenSections[1] != null)
180           {
181             jsonAlignmentPojo.getAppSettings().put("hiddenSeqs",
182                     String.valueOf(hiddenSections[1]));
183           }
184         }
185       }
186
187       if (jsonExportSettings.isExportAnnotations())
188       {
189         jsonAlignmentPojo
190                 .setAlignAnnotation(annotationToJsonPojo(annotations));
191       }
192
193       if (jsonExportSettings.isExportSequenceFeatures())
194       {
195         jsonAlignmentPojo
196                 .setSeqFeatures(sequenceFeatureToJsonPojo(seqs, fr));
197       }
198
199       if (jsonExportSettings.isExportGroups() && seqGroups != null
200               && seqGroups.size() > 0)
201       {
202         for (SequenceGroup seqGrp : seqGroups)
203         {
204           SequenceGrpPojo seqGrpPojo = new SequenceGrpPojo();
205           seqGrpPojo.setGroupName(seqGrp.getName());
206           seqGrpPojo.setColourScheme(ColourSchemeProperty
207                   .getColourName(seqGrp.cs));
208           seqGrpPojo.setColourText(seqGrp.getColourText());
209           seqGrpPojo.setDescription(seqGrp.getDescription());
210           seqGrpPojo.setDisplayBoxes(seqGrp.getDisplayBoxes());
211           seqGrpPojo.setDisplayText(seqGrp.getDisplayText());
212           seqGrpPojo.setEndRes(seqGrp.getEndRes());
213           seqGrpPojo.setStartRes(seqGrp.getStartRes());
214           seqGrpPojo.setShowNonconserved(seqGrp.getShowNonconserved());
215           for (SequenceI seq : seqGrp.getSequences())
216           {
217             seqGrpPojo.getSeqsHash().add(String.valueOf(seq.hashCode()));
218           }
219           jsonAlignmentPojo.getSeqGroups().add(seqGrpPojo);
220         }
221       }
222       org.json.JSONObject generatedJSon = new org.json.JSONObject(
223               jsonAlignmentPojo);
224       jsonOutput = generatedJSon.toString();
225       return jsonOutput.replaceAll("xstart", "xStart").replaceAll("xend",
226               "xEnd");
227     } catch (Exception e)
228     {
229       e.printStackTrace();
230     }
231     return jsonOutput;
232   }
233
234   public String[] exportHiddenSections()
235   {
236     String[] hiddenSections = new String[2];
237     if (getViewport() == null)
238     {
239       return null;
240     }
241
242     // hidden column business
243     if (getViewport().hasHiddenColumns())
244     {
245       List<int[]> hiddenCols = getViewport().getColumnSelection()
246               .getHiddenColumns();
247       StringBuilder hiddenColsBuilder = new StringBuilder();
248       for (int[] range : hiddenCols)
249       {
250         hiddenColsBuilder.append(";").append(range[0]).append("-")
251                 .append(range[1]);
252       }
253
254       hiddenColsBuilder.deleteCharAt(0);
255       hiddenSections[0] = hiddenColsBuilder.toString();
256     }
257
258     // hidden rows/seqs business
259     HiddenSequences hiddenSeqsObj = getViewport().getAlignment()
260             .getHiddenSequences();
261     if (hiddenSeqsObj == null || hiddenSeqsObj.hiddenSequences == null)
262     {
263       return hiddenSections;
264     }
265
266     SequenceI[] hiddenSeqs = hiddenSeqsObj.hiddenSequences;
267     StringBuilder hiddenSeqsBuilder = new StringBuilder();
268     for (SequenceI hiddenSeq : hiddenSeqs)
269     {
270       if (hiddenSeq != null)
271       {
272         hiddenSeqsBuilder.append(";").append(hiddenSeq.hashCode());
273       }
274     }
275     if (hiddenSeqsBuilder.length() > 0)
276     {
277       hiddenSeqsBuilder.deleteCharAt(0);
278     }
279     hiddenSections[1] = hiddenSeqsBuilder.toString();
280
281     return hiddenSections;
282   }
283
284   public static List<SequenceFeaturesPojo> sequenceFeatureToJsonPojo(
285           List<SequenceI> seqs, FeatureRenderer fr)
286   {
287     FeaturesDisplayedI displayedFeatures = (fr == null) ? null : fr
288             .getFeaturesDisplayed();
289     List<SequenceFeaturesPojo> sequenceFeaturesPojo = new ArrayList<SequenceFeaturesPojo>();
290     for (SequenceI seq : seqs)
291     {
292       SequenceI dataSetSequence = seq.getDatasetSequence();
293       SequenceFeature[] seqFeatures = (dataSetSequence == null) ? null
294               : seq.getDatasetSequence().getSequenceFeatures();
295
296       seqFeatures = (seqFeatures == null) ? seq.getSequenceFeatures()
297               : seqFeatures;
298       if (seqFeatures == null)
299       {
300         continue;
301       }
302
303       for (SequenceFeature sf : seqFeatures)
304       {
305         if (displayedFeatures != null
306                 && displayedFeatures.isVisible(sf.getType()))
307         {
308           SequenceFeaturesPojo jsonFeature = new SequenceFeaturesPojo(
309                   String.valueOf(seq.hashCode()));
310           String featureColour = (fr == null) ? null : jalview.util.Format
311                   .getHexString(fr
312                   .findFeatureColour(Color.white, seq,
313                           seq.findIndex(sf.getBegin())));
314           jsonFeature.setXstart(seq.findIndex(sf.getBegin()) - 1);
315           jsonFeature.setXend(seq.findIndex(sf.getEnd()));
316           jsonFeature.setType(sf.getType());
317           jsonFeature.setDescription(sf.getDescription());
318           jsonFeature.setLinks(sf.links);
319           jsonFeature.setOtherDetails(sf.otherDetails);
320           jsonFeature.setScore(sf.getScore());
321           jsonFeature.setFillColor(featureColour);
322           jsonFeature.setFeatureGroup(sf.getFeatureGroup());
323           sequenceFeaturesPojo.add(jsonFeature);
324         }
325       }
326     }
327     return sequenceFeaturesPojo;
328   }
329
330   public static List<AlignmentAnnotationPojo> annotationToJsonPojo(
331           Vector<AlignmentAnnotation> annotations)
332   {
333     List<AlignmentAnnotationPojo> jsonAnnotations = new ArrayList<AlignmentAnnotationPojo>();
334     if (annotations == null)
335     {
336       return jsonAnnotations;
337     }
338     for (AlignmentAnnotation annot : annotations)
339     {
340       AlignmentAnnotationPojo alignAnnotPojo = new AlignmentAnnotationPojo();
341       alignAnnotPojo.setDescription(annot.description);
342       alignAnnotPojo.setLabel(annot.label);
343       for (Annotation annotation : annot.annotations)
344       {
345         AnnotationPojo annotationPojo = new AnnotationPojo();
346         if (annotation != null)
347         {
348           annotationPojo.setDescription(annotation.description);
349           annotationPojo.setValue(annotation.value);
350           annotationPojo
351                   .setSecondaryStructure(annotation.secondaryStructure);
352           annotationPojo.setDisplayCharacter(annotation.displayCharacter);
353           alignAnnotPojo.getAnnotations().add(annotationPojo);
354         }
355         else
356         {
357           alignAnnotPojo.getAnnotations().add(annotationPojo);
358         }
359       }
360       jsonAnnotations.add(alignAnnotPojo);
361     }
362     return jsonAnnotations;
363   }
364
365   @SuppressWarnings("unchecked")
366   public JSONFile parse(String jsonAlignmentString)
367   {
368     try
369     {
370       JSONParser jsonParser = new JSONParser();
371       JSONObject alignmentJsonObj = (JSONObject) jsonParser
372               .parse(jsonAlignmentString);
373       JSONArray seqJsonArray = (JSONArray) alignmentJsonObj.get("seqs");
374       JSONArray alAnnotJsonArray = (JSONArray) alignmentJsonObj
375               .get("alignAnnotation");
376       JSONArray jsonSeqArray = (JSONArray) alignmentJsonObj
377               .get("seqFeatures");
378       JSONArray seqGrpJsonArray = (JSONArray) alignmentJsonObj
379               .get("seqGroups");
380       JSONObject jvSettingsJsonObj = (JSONObject) alignmentJsonObj
381               .get("appSettings");
382
383       if (jvSettingsJsonObj != null)
384       {
385         String jsColourScheme = (String) jvSettingsJsonObj
386                 .get("globalColorScheme");
387         Boolean showFeatures = Boolean.valueOf(jvSettingsJsonObj.get(
388                 "showSeqFeatures").toString());
389         setColourScheme(getJalviewColorScheme(jsColourScheme));
390         setShowSeqFeatures(showFeatures);
391         parseHiddenSeqRefsAsList(jvSettingsJsonObj);
392         parseHiddenCols(jvSettingsJsonObj);
393       }
394
395       hiddenSequences = new ArrayList<SequenceI>();
396       seqMap = new Hashtable<String, Sequence>();
397       for (Iterator<JSONObject> sequenceIter = seqJsonArray.iterator(); sequenceIter
398               .hasNext();)
399       {
400         JSONObject sequence = sequenceIter.next();
401         String sequcenceString = sequence.get("seq").toString();
402         String sequenceName = sequence.get("name").toString();
403         String seqUniqueId = sequence.get("id").toString();
404         int start = Integer.valueOf(sequence.get("start").toString());
405         int end = Integer.valueOf(sequence.get("end").toString());
406         Sequence seq = new Sequence(sequenceName, sequcenceString, start,
407                 end);
408         if (hiddenSeqRefs != null && hiddenSeqRefs.contains(seqUniqueId))
409         {
410           hiddenSequences.add(seq);
411         }
412         seqs.add(seq);
413         seqMap.put(seqUniqueId, seq);
414       }
415       parseFeatures(jsonSeqArray);
416
417       for (Iterator<JSONObject> seqGrpIter = seqGrpJsonArray.iterator(); seqGrpIter
418               .hasNext();)
419       {
420         JSONObject seqGrpObj = seqGrpIter.next();
421         String grpName = seqGrpObj.get("groupName").toString();
422         String colourScheme = seqGrpObj.get("colourScheme").toString();
423         String description = (seqGrpObj.get("description") == null) ? null
424                 : seqGrpObj.get("description").toString();
425         boolean displayBoxes = Boolean.valueOf(seqGrpObj
426                 .get("displayBoxes").toString());
427         boolean displayText = Boolean.valueOf(seqGrpObj.get("displayText")
428                 .toString());
429         boolean colourText = Boolean.valueOf(seqGrpObj.get("colourText")
430                 .toString());
431         boolean showNonconserved = Boolean.valueOf(seqGrpObj.get(
432                 "showNonconserved").toString());
433         int startRes = Integer
434                 .valueOf(seqGrpObj.get("startRes").toString());
435         int endRes = Integer.valueOf(seqGrpObj.get("endRes").toString());
436         JSONArray seqsHashArray = (JSONArray) seqGrpObj.get("seqsHash");
437
438         ArrayList<SequenceI> grpSeqs = new ArrayList<SequenceI>();
439         if (seqsHashArray.size() > 0)
440         {
441           Iterator<String> seqHashIter = seqsHashArray.iterator();
442           while (seqHashIter.hasNext())
443           {
444             String seqHash = seqHashIter.next();
445             Sequence sequence = seqMap.get(seqHash);
446             if (sequence != null)
447             {
448               grpSeqs.add(sequence);
449             }
450           }
451         }
452         ColourSchemeI scheme = getJalviewColorScheme(colourScheme);
453         SequenceGroup seqGrp = new SequenceGroup(grpSeqs, grpName, scheme,
454                 displayBoxes, displayText, colourText, startRes, endRes);
455         seqGrp.setShowNonconserved(showNonconserved);
456         seqGrp.setDescription(description);
457         this.seqGroups.add(seqGrp);
458
459       }
460
461       for (Iterator<JSONObject> alAnnotIter = alAnnotJsonArray.iterator(); alAnnotIter
462               .hasNext();)
463       {
464         JSONObject alAnnot = alAnnotIter.next();
465         JSONArray annotJsonArray = (JSONArray) alAnnot.get("annotations");
466         Annotation[] annotations = new Annotation[annotJsonArray.size()];
467         int count = 0;
468         for (Iterator<JSONObject> annotIter = annotJsonArray.iterator(); annotIter
469                 .hasNext();)
470         {
471           JSONObject annot = annotIter.next();
472           if (annot == null)
473           {
474             annotations[count] = null;
475           }
476           else
477           {
478             float val = annot.get("value") == null ? null : Float
479                     .valueOf(annot.get("value").toString());
480             String desc = annot.get("description") == null ? null : annot
481                     .get("description").toString();
482
483             char ss = annot.get("secondaryStructure") == null ? ' '
484                     : annot.get("secondaryStructure").toString().charAt(0);
485             String displayChar = annot.get("displayCharacter").toString();
486
487             annotations[count] = new Annotation(displayChar, desc, ss, val);
488           }
489           ++count;
490         }
491
492         AlignmentAnnotation alignAnnot = new AlignmentAnnotation(alAnnot
493                 .get("label").toString(), alAnnot.get("description")
494                 .toString(), annotations);
495         this.annotations.add(alignAnnot);
496       }
497
498     } catch (Exception e)
499     {
500       e.printStackTrace();
501     }
502     return this;
503   }
504
505   public void parseHiddenSeqRefsAsList(JSONObject jvSettingsJson)
506   {
507     hiddenSeqRefs = new ArrayList<String>();
508     String hiddenSeqs = (String) jvSettingsJson.get("hiddenSeqs");
509     if(hiddenSeqs != null && !hiddenSeqs.isEmpty()){
510       String[] seqRefs = hiddenSeqs.split(";");
511       for(String seqRef : seqRefs){
512         hiddenSeqRefs.add(seqRef);
513       }
514     }
515   }
516
517   public void parseHiddenCols(JSONObject jvSettingsJson)
518   {
519     // hiddenColumns = new ArrayList<int[]>();
520     String hiddenCols = (String) jvSettingsJson.get("hiddenCols");
521     if(hiddenCols != null && !hiddenCols.isEmpty()){
522       columnSelection = new ColumnSelection();
523       String[] rangeStrings = hiddenCols.split(";");
524       for(String rangeString : rangeStrings){
525         String[] range = rangeString.split("-");
526         // hiddenColumns.add(new int[]
527         // { Integer.valueOf(range[0]), Integer.valueOf(range[1]) });
528         columnSelection.hideColumns(Integer.valueOf(range[0]),
529                 Integer.valueOf(range[1]));
530       }
531     }
532   }
533
534   @SuppressWarnings("unchecked")
535   private void parseFeatures(JSONArray jsonSeqFeatures)
536   {
537     if (jsonSeqFeatures != null)
538     {
539       for (Iterator<JSONObject> seqFeatureItr = jsonSeqFeatures.iterator(); seqFeatureItr
540               .hasNext();)
541       {
542         JSONObject jsonFeature = seqFeatureItr.next();
543         Long begin = (Long) jsonFeature.get("xStart");
544         Long end = (Long) jsonFeature.get("xEnd");
545         String type = (String) jsonFeature.get("type");
546         String featureGrp = (String) jsonFeature.get("featureGroup");
547         String descripiton = (String) jsonFeature.get("description");
548         String seqRef = (String) jsonFeature.get("sequenceRef");
549         Float score = Float.valueOf(jsonFeature.get("score").toString());
550         // Hashtable otherDetails = (Hashtable) jsonFeature
551         // .get("otherDetails");
552         // sequenceFeature.otherDetails = otherDetails;
553
554         Sequence seq = seqMap.get(seqRef);
555         SequenceFeature sequenceFeature = new SequenceFeature();
556         JSONArray linksJsonArray = (JSONArray) jsonFeature.get("links");
557         if (linksJsonArray != null && linksJsonArray.size() > 0)
558         {
559           Iterator<String> linkList = linksJsonArray.iterator();
560           while (linkList.hasNext())
561           {
562             String link = linkList.next();
563             sequenceFeature.addLink(link);
564           }
565         }
566         sequenceFeature.setFeatureGroup(featureGrp);
567         sequenceFeature.setScore(score);
568         sequenceFeature.setDescription(descripiton);
569         sequenceFeature.setType(type);
570         sequenceFeature.setBegin(seq.findPosition(begin.intValue()));
571         sequenceFeature.setEnd(seq.findPosition(end.intValue()) - 1);
572         seq.addSequenceFeature(sequenceFeature);
573       }
574     }
575   }
576
577   public static ColourSchemeI getJalviewColorScheme(
578           String bioJsColourSchemeName)
579   {
580     ColourSchemeI jalviewColor = null;
581     for (JalviewBioJsColorSchemeMapper cs : JalviewBioJsColorSchemeMapper
582             .values())
583     {
584       if (cs.getBioJsName().equalsIgnoreCase(bioJsColourSchemeName))
585       {
586         jalviewColor = cs.getJvColourScheme();
587         break;
588       }
589     }
590     return jalviewColor;
591   }
592
593   public String getGlobalColorScheme()
594   {
595     return globalColorScheme;
596   }
597
598   public void setGlobalColorScheme(String globalColorScheme)
599   {
600     this.globalColorScheme = globalColorScheme;
601   }
602
603   public ColourSchemeI getColourScheme()
604   {
605     return colourScheme;
606   }
607
608   public void setColourScheme(ColourSchemeI colourScheme)
609   {
610     this.colourScheme = colourScheme;
611   }
612
613   public FeaturesDisplayedI getDisplayedFeatures()
614   {
615     return displayedFeatures;
616   }
617
618   public void setDisplayedFeatures(FeaturesDisplayedI displayedFeatures)
619   {
620     this.displayedFeatures = displayedFeatures;
621   }
622
623   public JSONExportSettings getJsonExportSettings()
624   {
625     return jsonExportSettings;
626   }
627
628   public void setJsonExportSettings(JSONExportSettings jsonExportSettings)
629   {
630     this.jsonExportSettings = jsonExportSettings;
631   }
632
633
634   public static String getJSONData(AlignViewportI av)
635   {
636     JSONFile jsonFile = new JSONFile();
637     jsonFile.setViewport(av);
638     jsonFile.seqGroups = av.getAlignment().getGroups();
639     jsonFile.setDisplayedFeatures(av.getFeaturesDisplayed());
640
641     for (SequenceI seq : av.getAlignment().getSequences())
642     {
643       jsonFile.seqs.add(seq);
644     }
645   
646     // Add non auto calculated annotation to AlignFile
647     for (AlignmentAnnotation annot : av.getAlignment()
648             .getAlignmentAnnotation())
649     {
650       if (annot != null && !annot.autoCalculated)
651       {
652         if (annot.label.equals("PDB.CATempFactor"))
653         {
654           continue;
655         }
656         jsonFile.annotations.add(annot);
657       }
658     }
659     String jsonString = jsonFile.print();
660     return jsonString;
661   }
662
663   public boolean isShowSeqFeatures()
664   {
665     return showSeqFeatures;
666   }
667
668   public void setShowSeqFeatures(boolean showSeqFeatures)
669   {
670     this.showSeqFeatures = showSeqFeatures;
671   }
672
673   public Vector<AlignmentAnnotation> getAnnotations()
674   {
675     return annotations;
676   }
677
678   public List<int[]> getHiddenColumns()
679   {
680     return hiddenColumns;
681   }
682
683   public ColumnSelection getColumnSelection()
684   {
685     return columnSelection;
686   }
687
688   public void setColumnSelection(ColumnSelection columnSelection)
689   {
690     this.columnSelection = columnSelection;
691   }
692
693   public SequenceI[] getHiddenSequences()
694   {
695     if (hiddenSequences == null || hiddenSequences.isEmpty())
696     {
697       return new SequenceI[]
698       {};
699     }
700     synchronized (hiddenSequences)
701     {
702       return hiddenSequences.toArray(new SequenceI[hiddenSequences.size()]);
703     }
704   }
705
706   public void setHiddenSequences(ArrayList<SequenceI> hiddenSequences)
707   {
708     this.hiddenSequences = hiddenSequences;
709   }
710
711   public class JSONExportSettings
712   {
713     private boolean exportSequence;
714
715     private boolean exportSequenceFeatures;
716
717     private boolean exportAnnotations;
718
719     private boolean exportGroups;
720
721     private boolean exportJalviewSettings;
722
723     public boolean isExportSequence()
724     {
725       return exportSequence;
726     }
727
728     public void setExportSequence(boolean exportSequence)
729     {
730       this.exportSequence = exportSequence;
731     }
732
733     public boolean isExportSequenceFeatures()
734     {
735       return exportSequenceFeatures;
736     }
737
738     public void setExportSequenceFeatures(boolean exportSequenceFeatures)
739     {
740       this.exportSequenceFeatures = exportSequenceFeatures;
741     }
742
743     public boolean isExportAnnotations()
744     {
745       return exportAnnotations;
746     }
747
748     public void setExportAnnotations(boolean exportAnnotations)
749     {
750       this.exportAnnotations = exportAnnotations;
751     }
752
753     public boolean isExportGroups()
754     {
755       return exportGroups;
756     }
757
758     public void setExportGroups(boolean exportGroups)
759     {
760       this.exportGroups = exportGroups;
761     }
762
763     public boolean isExportJalviewSettings()
764     {
765       return exportJalviewSettings;
766     }
767
768     public void setExportJalviewSettings(boolean exportJalviewSettings)
769     {
770       this.exportJalviewSettings = exportJalviewSettings;
771     }
772   }
773 }