+ Property prop = new Property();
+ prop.setName(pr);
+ prop.setValue(aa[i].getProperty(pr));
+ an.addProperty(prop);
+ }
+ }
+
+ AnnotationElement ae;
+ if (aa[i].annotations != null)
+ {
+ an.setScoreOnly(false);
+ for (int a = 0; a < aa[i].annotations.length; a++)
+ {
+ if ((aa[i] == null) || (aa[i].annotations[a] == null))
+ {
+ continue;
+ }
+
+ ae = new AnnotationElement();
+ if (aa[i].annotations[a].description != null)
+ {
+ ae.setDescription(aa[i].annotations[a].description);
+ }
+ if (aa[i].annotations[a].displayCharacter != null)
+ {
+ ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
+ }
+
+ if (!Float.isNaN(aa[i].annotations[a].value))
+ {
+ ae.setValue(aa[i].annotations[a].value);
+ }
+
+ ae.setPosition(a);
+ if (aa[i].annotations[a].secondaryStructure > ' ')
+ {
+ ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
+ + "");
+ }
+
+ if (aa[i].annotations[a].colour != null
+ && aa[i].annotations[a].colour != java.awt.Color.black)
+ {
+ ae.setColour(aa[i].annotations[a].colour.getRGB());
+ }
+
+ an.addAnnotationElement(ae);
+ if (aa[i].autoCalculated)
+ {
+ // only write one non-null entry into the annotation row -
+ // sufficient to get the visualization attributes necessary to
+ // display data
+ continue;
+ }
+ }
+ }
+ else
+ {
+ an.setScoreOnly(true);
+ }
+ if (!storeDS || (storeDS && !aa[i].autoCalculated))
+ {
+ // skip autocalculated annotation - these are only provided for
+ // alignments
+ vamsasSet.addAnnotation(an);
+ }
+ }
+
+ }
+
+ private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
+ {
+ AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
+ if (settings != null)
+ {
+ CalcIdParam vCalcIdParam = new CalcIdParam();
+ vCalcIdParam.setCalcId(calcId);
+ vCalcIdParam.addServiceURL(settings.getServiceURI());
+ // generic URI allowing a third party to resolve another instance of the
+ // service used for this calculation
+ for (String urls : settings.getServiceURLs())
+ {
+ vCalcIdParam.addServiceURL(urls);
+ }
+ vCalcIdParam.setVersion("1.0");
+ if (settings.getPreset() != null)
+ {
+ WsParamSetI setting = settings.getPreset();
+ vCalcIdParam.setName(setting.getName());
+ vCalcIdParam.setDescription(setting.getDescription());
+ }
+ else
+ {
+ vCalcIdParam.setName("");
+ vCalcIdParam.setDescription("Last used parameters");
+ }
+ // need to be able to recover 1) settings 2) user-defined presets or
+ // recreate settings from preset 3) predefined settings provided by
+ // service - or settings that can be transferred (or discarded)
+ vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
+ "|\\n|"));
+ vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
+ // todo - decide if updateImmediately is needed for any projects.
+
+ return vCalcIdParam;
+ }
+ return null;
+ }
+
+ private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
+ AlignViewport av)
+ {
+ if (calcIdParam.getVersion().equals("1.0"))
+ {
+ Jws2Instance service = Jws2Discoverer.getDiscoverer()
+ .getPreferredServiceFor(calcIdParam.getServiceURL());
+ if (service != null)
+ {
+ WsParamSetI parmSet = null;
+ try
+ {
+ parmSet = service.getParamStore().parseServiceParameterFile(
+ calcIdParam.getName(), calcIdParam.getDescription(),
+ calcIdParam.getServiceURL(),
+ calcIdParam.getParameters().replace("|\\n|", "\n"));
+ } catch (IOException x)
+ {
+ warn("Couldn't parse parameter data for "
+ + calcIdParam.getCalcId(), x);
+ return false;
+ }
+ List<ArgumentI> argList = null;
+ if (calcIdParam.getName().length() > 0)
+ {
+ parmSet = service.getParamStore()
+ .getPreset(calcIdParam.getName());
+ if (parmSet != null)
+ {
+ // TODO : check we have a good match with settings in AACon -
+ // otherwise we'll need to create a new preset
+ }
+ }
+ else
+ {
+ argList = parmSet.getArguments();
+ parmSet = null;
+ }
+ AAConSettings settings = new AAConSettings(
+ calcIdParam.isAutoUpdate(), service, parmSet, argList);
+ av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
+ calcIdParam.isNeedsUpdate());
+ return true;
+ }
+ else
+ {
+ warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
+ return false;
+ }
+ }
+ throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
+ }
+
+ /**
+ * External mapping between jalview objects and objects yielding a valid and
+ * unique object ID string. This is null for normal Jalview project IO, but
+ * non-null when a jalview project is being read or written as part of a
+ * vamsas session.
+ */
+ IdentityHashMap jv2vobj = null;
+
+ /**
+ * Construct a unique ID for jvobj using either existing bindings or if none
+ * exist, the result of the hashcode call for the object.
+ *
+ * @param jvobj
+ * jalview data object
+ * @return unique ID for referring to jvobj
+ */
+ private String makeHashCode(Object jvobj, String altCode)
+ {
+ if (jv2vobj != null)
+ {
+ Object id = jv2vobj.get(jvobj);
+ if (id != null)
+ {
+ return id.toString();
+ }
+ // check string ID mappings
+ if (jvids2vobj != null && jvobj instanceof String)
+ {
+ id = jvids2vobj.get(jvobj);
+ }
+ if (id != null)
+ {
+ return id.toString();
+ }
+ // give up and warn that something has gone wrong
+ warn("Cannot find ID for object in external mapping : " + jvobj);
+ }
+ return altCode;
+ }
+
+ /**
+ * return local jalview object mapped to ID, if it exists
+ *
+ * @param idcode
+ * (may be null)
+ * @return null or object bound to idcode
+ */
+ private Object retrieveExistingObj(String idcode)
+ {
+ if (idcode != null && vobj2jv != null)
+ {
+ return vobj2jv.get(idcode);
+ }
+ return null;
+ }
+
+ /**
+ * binding from ID strings from external mapping table to jalview data model
+ * objects.
+ */
+ private Hashtable vobj2jv;
+
+ private Sequence createVamsasSequence(String id, SequenceI jds)
+ {
+ return createVamsasSequence(true, id, jds, null);
+ }
+
+ private Sequence createVamsasSequence(boolean recurse, String id,
+ SequenceI jds, SequenceI parentseq)
+ {
+ Sequence vamsasSeq = new Sequence();
+ vamsasSeq.setId(id);
+ vamsasSeq.setName(jds.getName());
+ vamsasSeq.setSequence(jds.getSequenceAsString());
+ vamsasSeq.setDescription(jds.getDescription());
+ jalview.datamodel.DBRefEntry[] dbrefs = null;
+ if (jds.getDatasetSequence() != null)
+ {
+ vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
+ if (jds.getDatasetSequence().getDBRef() != null)
+ {
+ dbrefs = jds.getDatasetSequence().getDBRef();
+ }
+ }
+ else
+ {
+ vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
+ // dataset sequences only
+ dbrefs = jds.getDBRef();
+ }
+ if (dbrefs != null)
+ {
+ for (int d = 0; d < dbrefs.length; d++)
+ {
+ DBRef dbref = new DBRef();
+ dbref.setSource(dbrefs[d].getSource());
+ dbref.setVersion(dbrefs[d].getVersion());
+ dbref.setAccessionId(dbrefs[d].getAccessionId());
+ if (dbrefs[d].hasMap())
+ {
+ Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
+ jds, recurse);
+ dbref.setMapping(mp);
+ }
+ vamsasSeq.addDBRef(dbref);
+ }
+ }
+ return vamsasSeq;
+ }
+
+ private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
+ SequenceI parentseq, SequenceI jds, boolean recurse)
+ {
+ Mapping mp = null;
+ if (jmp.getMap() != null)
+ {
+ mp = new Mapping();
+
+ jalview.util.MapList mlst = jmp.getMap();
+ int r[] = mlst.getFromRanges();
+ for (int s = 0; s < r.length; s += 2)
+ {
+ MapListFrom mfrom = new MapListFrom();
+ mfrom.setStart(r[s]);
+ mfrom.setEnd(r[s + 1]);
+ mp.addMapListFrom(mfrom);
+ }
+ r = mlst.getToRanges();
+ for (int s = 0; s < r.length; s += 2)
+ {
+ MapListTo mto = new MapListTo();
+ mto.setStart(r[s]);
+ mto.setEnd(r[s + 1]);
+ mp.addMapListTo(mto);
+ }
+ mp.setMapFromUnit(mlst.getFromRatio());
+ mp.setMapToUnit(mlst.getToRatio());
+ if (jmp.getTo() != null)
+ {
+ MappingChoice mpc = new MappingChoice();
+ if (recurse
+ && (parentseq != jmp.getTo() || parentseq
+ .getDatasetSequence() != jmp.getTo()))
+ {
+ mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
+ jmp.getTo(), jds));
+ }
+ else
+ {
+ String jmpid = "";
+ SequenceI ps = null;
+ if (parentseq != jmp.getTo()
+ && parentseq.getDatasetSequence() != jmp.getTo())
+ {
+ // chaining dbref rather than a handshaking one
+ jmpid = seqHash(ps = jmp.getTo());
+ }
+ else
+ {
+ jmpid = seqHash(ps = parentseq);
+ }
+ mpc.setDseqFor(jmpid);
+ if (!seqRefIds.containsKey(mpc.getDseqFor()))
+ {
+ jalview.bin.Cache.log.debug("creatign new DseqFor ID");
+ seqRefIds.put(mpc.getDseqFor(), ps);
+ }
+ else
+ {
+ jalview.bin.Cache.log.debug("reusing DseqFor ID");
+ }
+ }
+ mp.setMappingChoice(mpc);
+ }
+ }
+ return mp;
+ }
+
+ String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
+ List<UserColourScheme> userColours, JalviewModelSequence jms)
+ {
+ String id = null;
+ jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
+ boolean newucs = false;
+ if (!userColours.contains(ucs))
+ {
+ userColours.add(ucs);
+ newucs = true;
+ }
+ id = "ucs" + userColours.indexOf(ucs);
+ if (newucs)
+ {
+ // actually create the scheme's entry in the XML model
+ java.awt.Color[] colours = ucs.getColours();
+ jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
+ jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
+
+ for (int i = 0; i < colours.length; i++)
+ {
+ jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
+ col.setName(ResidueProperties.aa[i]);
+ col.setRGB(jalview.util.Format.getHexString(colours[i]));
+ jbucs.addColour(col);
+ }
+ if (ucs.getLowerCaseColours() != null)
+ {
+ colours = ucs.getLowerCaseColours();
+ for (int i = 0; i < colours.length; i++)
+ {
+ jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
+ col.setName(ResidueProperties.aa[i].toLowerCase());
+ col.setRGB(jalview.util.Format.getHexString(colours[i]));
+ jbucs.addColour(col);
+ }
+ }
+
+ uc.setId(id);
+ uc.setUserColourScheme(jbucs);
+ jms.addUserColours(uc);
+ }
+
+ return id;
+ }
+
+ jalview.schemes.UserColourScheme getUserColourScheme(
+ JalviewModelSequence jms, String id)
+ {
+ UserColours[] uc = jms.getUserColours();
+ UserColours colours = null;
+
+ for (int i = 0; i < uc.length; i++)
+ {
+ if (uc[i].getId().equals(id))
+ {
+ colours = uc[i];
+
+ break;
+ }
+ }
+
+ java.awt.Color[] newColours = new java.awt.Color[24];
+
+ for (int i = 0; i < 24; i++)
+ {
+ newColours[i] = new java.awt.Color(Integer.parseInt(colours
+ .getUserColourScheme().getColour(i).getRGB(), 16));
+ }
+
+ jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
+ newColours);
+
+ if (colours.getUserColourScheme().getColourCount() > 24)
+ {
+ newColours = new java.awt.Color[23];
+ for (int i = 0; i < 23; i++)
+ {
+ newColours[i] = new java.awt.Color(Integer.parseInt(colours
+ .getUserColourScheme().getColour(i + 24).getRGB(), 16));
+ }
+ ucs.setLowerCaseColours(newColours);
+ }
+
+ return ucs;
+ }
+
+ /**
+ * contains last error message (if any) encountered by XML loader.
+ */
+ String errorMessage = null;
+
+ /**
+ * flag to control whether the Jalview2XML_V1 parser should be deferred to if
+ * exceptions are raised during project XML parsing
+ */
+ public boolean attemptversion1parse = true;
+
+ /**
+ * Load a jalview project archive from a jar file
+ *
+ * @param file
+ * - HTTP URL or filename
+ */
+ public AlignFrame loadJalviewAlign(final String file)
+ {
+
+ jalview.gui.AlignFrame af = null;
+
+ try
+ {
+ // create list to store references for any new Jmol viewers created
+ newStructureViewers = new Vector<JalviewStructureDisplayI>();
+ // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
+ // Workaround is to make sure caller implements the JarInputStreamProvider
+ // interface
+ // so we can re-open the jar input stream for each entry.
+
+ jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
+ af = loadJalviewAlign(jprovider);
+
+ } catch (MalformedURLException e)
+ {
+ errorMessage = "Invalid URL format for '" + file + "'";
+ reportErrors();
+ } finally
+ {
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable()
+ {
+ public void run()
+ {
+ setLoadingFinishedForNewStructureViewers();
+ };
+ });
+ } catch (Exception x)
+ {
+
+ }
+ }
+ return af;
+ }
+
+ private jarInputStreamProvider createjarInputStreamProvider(
+ final String file) throws MalformedURLException
+ {
+ URL url = null;
+ errorMessage = null;
+ uniqueSetSuffix = null;
+ seqRefIds = null;
+ viewportsAdded = null;
+ frefedSequence = null;
+
+ if (file.startsWith("http://"))
+ {
+ url = new URL(file);
+ }
+ final URL _url = url;
+ return new jarInputStreamProvider()
+ {
+
+ @Override
+ public JarInputStream getJarInputStream() throws IOException
+ {
+ if (_url != null)
+ {
+ return new JarInputStream(_url.openStream());
+ }
+ else
+ {
+ return new JarInputStream(new FileInputStream(file));
+ }
+ }
+
+ @Override
+ public String getFilename()
+ {
+ return file;
+ }
+ };
+ }
+
+ /**
+ * Recover jalview session from a jalview project archive. Caller may
+ * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
+ * themselves. Any null fields will be initialised with default values,
+ * non-null fields are left alone.
+ *
+ * @param jprovider
+ * @return
+ */
+ public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
+ {
+ errorMessage = null;
+ if (uniqueSetSuffix == null)
+ {
+ uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
+ }
+ if (seqRefIds == null)
+ {
+ seqRefIds = new HashMap<String, SequenceI>();
+ }
+ if (viewportsAdded == null)
+ {
+ viewportsAdded = new Hashtable();
+ }
+ if (frefedSequence == null)
+ {
+ frefedSequence = new Vector();
+ }
+
+ jalview.gui.AlignFrame af = null, _af = null;
+ Hashtable gatherToThisFrame = new Hashtable();
+ final String file = jprovider.getFilename();
+ try
+ {
+ JarInputStream jin = null;
+ JarEntry jarentry = null;
+ int entryCount = 1;
+
+ do
+ {
+ jin = jprovider.getJarInputStream();
+ for (int i = 0; i < entryCount; i++)
+ {
+ jarentry = jin.getNextJarEntry();
+ }
+
+ if (jarentry != null && jarentry.getName().endsWith(".xml"))
+ {
+ InputStreamReader in = new InputStreamReader(jin, "UTF-8");
+ JalviewModel object = new JalviewModel();
+
+ Unmarshaller unmar = new Unmarshaller(object);
+ unmar.setValidation(false);
+ object = (JalviewModel) unmar.unmarshal(in);
+ if (true) // !skipViewport(object))
+ {
+ _af = loadFromObject(object, file, true, jprovider);
+ if (object.getJalviewModelSequence().getViewportCount() > 0)
+ {
+ af = _af;
+ if (af.viewport.gatherViewsHere)
+ {
+ gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
+ }
+ }
+ }
+ entryCount++;
+ }
+ else if (jarentry != null)
+ {
+ // Some other file here.
+ entryCount++;
+ }
+ } while (jarentry != null);
+ resolveFrefedSequences();
+ } catch (java.io.FileNotFoundException ex)
+ {
+ ex.printStackTrace();
+ errorMessage = "Couldn't locate Jalview XML file : " + file;
+ System.err.println("Exception whilst loading jalview XML file : "
+ + ex + "\n");
+ } catch (java.net.UnknownHostException ex)
+ {
+ ex.printStackTrace();
+ errorMessage = "Couldn't locate Jalview XML file : " + file;
+ System.err.println("Exception whilst loading jalview XML file : "
+ + ex + "\n");
+ } catch (Exception ex)
+ {
+ System.err.println("Parsing as Jalview Version 2 file failed.");
+ ex.printStackTrace(System.err);
+ if (attemptversion1parse)
+ {
+ // Is Version 1 Jar file?
+ try
+ {
+ af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
+ } catch (Exception ex2)
+ {
+ System.err.println("Exception whilst loading as jalviewXMLV1:");
+ ex2.printStackTrace();
+ af = null;
+ }
+ }
+ if (Desktop.instance != null)
+ {
+ Desktop.instance.stopLoading();
+ }
+ if (af != null)
+ {
+ System.out.println("Successfully loaded archive file");
+ return af;
+ }
+ ex.printStackTrace();
+
+ System.err.println("Exception whilst loading jalview XML file : "
+ + ex + "\n");
+ } catch (OutOfMemoryError e)
+ {
+ // Don't use the OOM Window here
+ errorMessage = "Out of memory loading jalview XML file";
+ System.err.println("Out of memory whilst loading jalview XML file");
+ e.printStackTrace();
+ }
+
+ if (Desktop.instance != null)
+ {
+ Desktop.instance.stopLoading();
+ }
+
+ Enumeration en = gatherToThisFrame.elements();
+ while (en.hasMoreElements())
+ {
+ Desktop.instance.gatherViews((AlignFrame) en.nextElement());
+ }
+ if (errorMessage != null)
+ {
+ reportErrors();
+ }
+ return af;
+ }
+
+ /**
+ * check errorMessage for a valid error message and raise an error box in the
+ * GUI or write the current errorMessage to stderr and then clear the error
+ * state.
+ */
+ protected void reportErrors()
+ {
+ reportErrors(false);
+ }
+
+ protected void reportErrors(final boolean saving)
+ {
+ if (errorMessage != null)
+ {
+ final String finalErrorMessage = errorMessage;
+ if (raiseGUI)
+ {
+ javax.swing.SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ JOptionPane.showInternalMessageDialog(Desktop.desktop,
+ finalErrorMessage, "Error "
+ + (saving ? "saving" : "loading")
+ + " Jalview file", JOptionPane.WARNING_MESSAGE);
+ }
+ });
+ }
+ else
+ {
+ System.err.println("Problem loading Jalview file: " + errorMessage);
+ }
+ }
+ errorMessage = null;
+ }
+
+ Hashtable<String, String> alreadyLoadedPDB;
+
+ /**
+ * when set, local views will be updated from view stored in JalviewXML
+ * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
+ * sync if this is set to true.
+ */
+ private final boolean updateLocalViews = false;
+
+ String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
+ {
+ if (alreadyLoadedPDB == null)
+ {
+ alreadyLoadedPDB = new Hashtable();
+ }
+
+ if (alreadyLoadedPDB.containsKey(pdbId))
+ {
+ return alreadyLoadedPDB.get(pdbId).toString();
+ }
+
+ try
+ {
+ JarInputStream jin = jprovider.getJarInputStream();
+ /*
+ * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
+ * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
+ * FileInputStream(jprovider)); }
+ */
+
+ JarEntry entry = null;
+ do
+ {
+ entry = jin.getNextJarEntry();
+ } while (entry != null && !entry.getName().equals(pdbId));
+ if (entry != null)
+ {
+ BufferedReader in = new BufferedReader(new InputStreamReader(jin));
+ File outFile = File.createTempFile("jalview_pdb", ".txt");
+ outFile.deleteOnExit();
+ PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
+ String data;
+
+ while ((data = in.readLine()) != null)
+ {
+ out.println(data);
+ }
+ try
+ {
+ out.flush();
+ } catch (Exception foo)
+ {
+ }
+ ;
+ out.close();
+ String t = outFile.getAbsolutePath();
+ alreadyLoadedPDB.put(pdbId, t);
+ return t;
+ }
+ else
+ {
+ warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
+ }
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ return null;
+ }
+
+ private class JvAnnotRow
+ {
+ public JvAnnotRow(int i, AlignmentAnnotation jaa)
+ {
+ order = i;
+ template = jaa;
+ }
+
+ /**
+ * persisted version of annotation row from which to take vis properties
+ */
+ public jalview.datamodel.AlignmentAnnotation template;
+
+ /**
+ * original position of the annotation row in the alignment
+ */
+ public int order;
+ }
+
+ /**
+ * Load alignment frame from jalview XML DOM object
+ *
+ * @param object
+ * DOM
+ * @param file
+ * filename source string
+ * @param loadTreesAndStructures
+ * when false only create Viewport
+ * @param jprovider
+ * data source provider
+ * @return alignment frame created from view stored in DOM
+ */
+ AlignFrame loadFromObject(JalviewModel object, String file,
+ boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
+ {
+ SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
+ Sequence[] vamsasSeq = vamsasSet.getSequence();
+
+ JalviewModelSequence jms = object.getJalviewModelSequence();
+
+ Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
+ : null;
+
+ // ////////////////////////////////
+ // LOAD SEQUENCES
+
+ Vector hiddenSeqs = null;
+ jalview.datamodel.Sequence jseq;
+
+ ArrayList tmpseqs = new ArrayList();
+
+ boolean multipleView = false;
+
+ JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
+ int vi = 0; // counter in vamsasSeq array
+ for (int i = 0; i < jseqs.length; i++)
+ {
+ String seqId = jseqs[i].getId();
+
+ if (seqRefIds.get(seqId) != null)
+ {
+ tmpseqs.add(seqRefIds.get(seqId));
+ multipleView = true;
+ }
+ else
+ {
+ jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
+ vamsasSeq[vi].getSequence());
+ jseq.setDescription(vamsasSeq[vi].getDescription());
+ jseq.setStart(jseqs[i].getStart());
+ jseq.setEnd(jseqs[i].getEnd());
+ jseq.setVamsasId(uniqueSetSuffix + seqId);
+ seqRefIds.put(vamsasSeq[vi].getId(), jseq);
+ tmpseqs.add(jseq);
+ vi++;
+ }
+
+ if (jseqs[i].getHidden())
+ {
+ if (hiddenSeqs == null)
+ {
+ hiddenSeqs = new Vector();
+ }
+
+ hiddenSeqs.addElement(seqRefIds.get(seqId));
+ }
+
+ }
+
+ // /
+ // Create the alignment object from the sequence set
+ // ///////////////////////////////
+ jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
+ .size()];
+
+ tmpseqs.toArray(orderedSeqs);
+
+ jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
+ orderedSeqs);
+
+ // / Add the alignment properties
+ for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
+ {
+ SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
+ al.setProperty(ssp.getKey(), ssp.getValue());
+ }
+
+ // /
+ // SequenceFeatures are added to the DatasetSequence,
+ // so we must create or recover the dataset before loading features
+ // ///////////////////////////////
+ if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
+ {
+ // older jalview projects do not have a dataset id.
+ al.setDataset(null);
+ }
+ else
+ {
+ // recover dataset - passing on flag indicating if this a 'viewless'
+ // sequence set (a.k.a. a stored dataset for the project)
+ recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
+ .getViewportCount() == 0);
+ }
+ // ///////////////////////////////
+
+ Hashtable pdbloaded = new Hashtable();
+ if (!multipleView)
+ {
+ // load sequence features, database references and any associated PDB
+ // structures for the alignment
+ for (int i = 0; i < vamsasSeq.length; i++)
+ {
+ if (jseqs[i].getFeaturesCount() > 0)
+ {
+ Features[] features = jseqs[i].getFeatures();
+ for (int f = 0; f < features.length; f++)
+ {
+ jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
+ features[f].getType(), features[f].getDescription(),
+ features[f].getStatus(), features[f].getBegin(),
+ features[f].getEnd(), features[f].getFeatureGroup());
+
+ sf.setScore(features[f].getScore());
+ for (int od = 0; od < features[f].getOtherDataCount(); od++)
+ {
+ OtherData keyValue = features[f].getOtherData(od);
+ if (keyValue.getKey().startsWith("LINK"))
+ {
+ sf.addLink(keyValue.getValue());
+ }
+ else
+ {
+ sf.setValue(keyValue.getKey(), keyValue.getValue());
+ }
+
+ }
+
+ al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
+ }
+ }
+ if (vamsasSeq[i].getDBRefCount() > 0)
+ {
+ addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
+ }
+ if (jseqs[i].getPdbidsCount() > 0)
+ {
+ Pdbids[] ids = jseqs[i].getPdbids();
+ for (int p = 0; p < ids.length; p++)
+ {
+ jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
+ entry.setId(ids[p].getId());
+ entry.setType(ids[p].getType());
+ if (ids[p].getFile() != null)
+ {
+ if (!pdbloaded.containsKey(ids[p].getFile()))
+ {
+ entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
+ }
+ else
+ {
+ entry.setFile(pdbloaded.get(ids[p].getId()).toString());
+ }
+ }
+ StructureSelectionManager.getStructureSelectionManager(
+ Desktop.instance)
+ .registerPDBEntry(entry);
+ al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
+ }
+ }
+ }
+ } // end !multipleview
+
+ // ///////////////////////////////
+ // LOAD SEQUENCE MAPPINGS
+
+ if (vamsasSet.getAlcodonFrameCount() > 0)
+ {
+ // TODO Potentially this should only be done once for all views of an
+ // alignment
+ AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
+ for (int i = 0; i < alc.length; i++)
+ {
+ jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
+ alc[i].getAlcodonCount());
+ if (alc[i].getAlcodonCount() > 0)
+ {
+ Alcodon[] alcods = alc[i].getAlcodon();
+ for (int p = 0; p < cf.codons.length; p++)
+ {
+ if (alcods[p].hasPos1() && alcods[p].hasPos2()
+ && alcods[p].hasPos3())
+ {
+ // translated codons require three valid positions
+ cf.codons[p] = new int[3];
+ cf.codons[p][0] = (int) alcods[p].getPos1();
+ cf.codons[p][1] = (int) alcods[p].getPos2();
+ cf.codons[p][2] = (int) alcods[p].getPos3();
+ }
+ else
+ {
+ cf.codons[p] = null;
+ }
+ }
+ }
+ if (alc[i].getAlcodMapCount() > 0)
+ {
+ AlcodMap[] maps = alc[i].getAlcodMap();
+ for (int m = 0; m < maps.length; m++)
+ {
+ SequenceI dnaseq = seqRefIds
+ .get(maps[m].getDnasq());
+ // Load Mapping
+ jalview.datamodel.Mapping mapping = null;
+ // attach to dna sequence reference.
+ if (maps[m].getMapping() != null)
+ {
+ mapping = addMapping(maps[m].getMapping());
+ }
+ if (dnaseq != null)
+ {
+ cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
+ }
+ else
+ {
+ // defer to later
+ frefedSequence.add(new Object[]
+ { maps[m].getDnasq(), cf, mapping });
+ }
+ }
+ }
+ al.addCodonFrame(cf);
+ }
+
+ }
+
+ // ////////////////////////////////
+ // LOAD ANNOTATIONS
+ ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
+ /**
+ * store any annotations which forward reference a group's ID
+ */
+ Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
+
+ if (vamsasSet.getAnnotationCount() > 0)
+ {
+ Annotation[] an = vamsasSet.getAnnotation();
+
+ for (int i = 0; i < an.length; i++)
+ {
+ /**
+ * test if annotation is automatically calculated for this view only
+ */
+ boolean autoForView = false;
+ if (an[i].getLabel().equals("Quality")
+ || an[i].getLabel().equals("Conservation")
+ || an[i].getLabel().equals("Consensus"))
+ {
+ // Kludge for pre 2.5 projects which lacked the autocalculated flag
+ autoForView = true;
+ if (!an[i].hasAutoCalculated())
+ {
+ an[i].setAutoCalculated(true);
+ }
+ }
+ if (autoForView
+ || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
+ {
+ // remove ID - we don't recover annotation from other views for
+ // view-specific annotation
+ an[i].setId(null);
+ }
+
+ // set visiblity for other annotation in this view
+ if (an[i].getId() != null
+ && annotationIds.containsKey(an[i].getId()))
+ {
+ jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
+ .get(an[i].getId());
+ // in principle Visible should always be true for annotation displayed
+ // in multiple views
+ if (an[i].hasVisible())
+ {
+ jda.visible = an[i].getVisible();
+ }
+
+ al.addAnnotation(jda);
+
+ continue;
+ }
+ // Construct new annotation from model.
+ AnnotationElement[] ae = an[i].getAnnotationElement();
+ jalview.datamodel.Annotation[] anot = null;
+ java.awt.Color firstColour = null;
+ int anpos;
+ if (!an[i].getScoreOnly())
+ {
+ anot = new jalview.datamodel.Annotation[al.getWidth()];
+ for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
+ {
+ anpos = ae[aa].getPosition();
+
+ if (anpos >= anot.length)
+ {
+ continue;
+ }
+
+ anot[anpos] = new jalview.datamodel.Annotation(
+
+ ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
+ (ae[aa].getSecondaryStructure() == null || ae[aa]
+ .getSecondaryStructure().length() == 0) ? ' '
+ : ae[aa].getSecondaryStructure().charAt(0),
+ ae[aa].getValue()
+
+ );
+ // JBPNote: Consider verifying dataflow for IO of secondary
+ // structure annotation read from Stockholm files
+ // this was added to try to ensure that
+ // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
+ // {
+ // anot[ae[aa].getPosition()].displayCharacter = "";
+ // }
+ anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
+ if (firstColour == null)
+ {
+ firstColour = anot[anpos].colour;
+ }
+ }
+ }
+ jalview.datamodel.AlignmentAnnotation jaa = null;
+
+ if (an[i].getGraph())
+ {
+ float llim = 0, hlim = 0;
+ // if (autoForView || an[i].isAutoCalculated()) {
+ // hlim=11f;
+ // }
+ jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
+ an[i].getDescription(), anot, llim, hlim,
+ an[i].getGraphType());
+
+ jaa.graphGroup = an[i].getGraphGroup();
+ jaa._linecolour = firstColour;
+ if (an[i].getThresholdLine() != null)
+ {
+ jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
+ .getThresholdLine().getValue(), an[i]
+ .getThresholdLine().getLabel(), new java.awt.Color(
+ an[i].getThresholdLine().getColour())));
+
+ }
+ if (autoForView || an[i].isAutoCalculated())
+ {
+ // Hardwire the symbol display line to ensure that labels for
+ // histograms are displayed
+ jaa.hasText = true;
+ }
+ }
+ else
+ {
+ jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
+ an[i].getDescription(), anot);
+ jaa._linecolour = firstColour;
+ }
+ // register new annotation
+ if (an[i].getId() != null)
+ {
+ annotationIds.put(an[i].getId(), jaa);
+ jaa.annotationId = an[i].getId();
+ }
+ // recover sequence association
+ if (an[i].getSequenceRef() != null)
+ {
+ if (al.findName(an[i].getSequenceRef()) != null)
+ {
+ jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
+ 1, true);
+ al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
+ }
+ }
+ // and make a note of any group association
+ if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
+ {
+ ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
+ .get(an[i].getGroupRef());
+ if (aal == null)
+ {
+ aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
+ groupAnnotRefs.put(an[i].getGroupRef(), aal);
+ }
+ aal.add(jaa);
+ }
+
+ if (an[i].hasScore())
+ {
+ jaa.setScore(an[i].getScore());
+ }
+ if (an[i].hasVisible())
+ {
+ jaa.visible = an[i].getVisible();
+ }
+
+ if (an[i].hasCentreColLabels())
+ {
+ jaa.centreColLabels = an[i].getCentreColLabels();
+ }
+
+ if (an[i].hasScaleColLabels())
+ {
+ jaa.scaleColLabel = an[i].getScaleColLabels();
+ }
+ if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
+ {
+ // newer files have an 'autoCalculated' flag and store calculation
+ // state in viewport properties
+ jaa.autoCalculated = true; // means annotation will be marked for
+ // update at end of load.
+ }
+ if (an[i].hasGraphHeight())
+ {
+ jaa.graphHeight = an[i].getGraphHeight();
+ }
+ if (an[i].hasBelowAlignment())
+ {
+ jaa.belowAlignment = an[i].isBelowAlignment();
+ }
+ jaa.setCalcId(an[i].getCalcId());
+ if (an[i].getPropertyCount() > 0)
+ {
+ for (jalview.schemabinding.version2.Property prop : an[i]
+ .getProperty())
+ {
+ jaa.setProperty(prop.getName(), prop.getValue());
+ }
+ }
+ if (jaa.autoCalculated)
+ {
+ autoAlan.add(new JvAnnotRow(i, jaa));
+ }
+ else
+ // if (!autoForView)
+ {
+ // add autocalculated group annotation and any user created annotation
+ // for the view
+ al.addAnnotation(jaa);
+ }
+ }
+ }
+ // ///////////////////////
+ // LOAD GROUPS
+ // Create alignment markup and styles for this view
+ if (jms.getJGroupCount() > 0)
+ {
+ JGroup[] groups = jms.getJGroup();
+ boolean addAnnotSchemeGroup = false;
+ for (int i = 0; i < groups.length; i++)
+ {
+ ColourSchemeI cs = null;
+
+ if (groups[i].getColour() != null)
+ {
+ if (groups[i].getColour().startsWith("ucs"))
+ {
+ cs = getUserColourScheme(jms, groups[i].getColour());
+ }
+ else if (groups[i].getColour().equals("AnnotationColourGradient")
+ && groups[i].getAnnotationColours() != null)
+ {
+ addAnnotSchemeGroup = true;
+ cs = null;
+ }
+ else
+ {
+ cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
+ }
+
+ if (cs != null)
+ {
+ cs.setThreshold(groups[i].getPidThreshold(), true);
+ }
+ }
+
+ Vector seqs = new Vector();
+
+ for (int s = 0; s < groups[i].getSeqCount(); s++)
+ {
+ String seqId = groups[i].getSeq(s) + "";
+ jalview.datamodel.SequenceI ts = seqRefIds
+ .get(seqId);
+
+ if (ts != null)
+ {
+ seqs.addElement(ts);
+ }
+ }
+
+ if (seqs.size() < 1)
+ {
+ continue;
+ }
+
+ jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
+ seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
+ groups[i].getDisplayText(), groups[i].getColourText(),
+ groups[i].getStart(), groups[i].getEnd());
+
+ sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
+
+ sg.textColour = new java.awt.Color(groups[i].getTextCol1());
+ sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
+ sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
+ .isShowUnconserved() : false);
+ sg.thresholdTextColour = groups[i].getTextColThreshold();
+ if (groups[i].hasShowConsensusHistogram())
+ {
+ sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
+ }
+ ;
+ if (groups[i].hasShowSequenceLogo())
+ {
+ sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
+ }
+ if (groups[i].hasNormaliseSequenceLogo())
+ {
+ sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
+ }
+ if (groups[i].hasIgnoreGapsinConsensus())
+ {
+ sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
+ }
+ if (groups[i].getConsThreshold() != 0)
+ {
+ jalview.analysis.Conservation c = new jalview.analysis.Conservation(
+ "All", ResidueProperties.propHash, 3,
+ sg.getSequences(null), 0, sg.getWidth() - 1);
+ c.calculate();
+ c.verdict(false, 25);
+ sg.cs.setConservation(c);
+ }
+
+ if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
+ {
+ // re-instate unique group/annotation row reference
+ ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
+ .get(groups[i].getId());
+ if (jaal != null)
+ {
+ for (jalview.datamodel.AlignmentAnnotation jaa : jaal)