From cfa406a916d754e600c60f7dae29b053bf045ace Mon Sep 17 00:00:00 2001 From: jprocter Date: Tue, 25 Sep 2007 09:32:33 +0000 Subject: [PATCH] ascii file --- src/jalview/io/vamsas/DatastoreItem.java | 469 +++++----- src/jalview/io/vamsas/Dbref.java | 230 ++--- src/jalview/io/vamsas/LocalDocSyncObject.java | 170 ++-- src/jalview/io/vamsas/Rangetype.java | 538 ++++++------ src/jalview/io/vamsas/Sequencemapping.java | 654 +++++++------- src/jalview/io/vamsas/Tree.java | 1136 ++++++++++++------------- 6 files changed, 1598 insertions(+), 1599 deletions(-) diff --git a/src/jalview/io/vamsas/DatastoreItem.java b/src/jalview/io/vamsas/DatastoreItem.java index 1a57dc3..4cc540d 100644 --- a/src/jalview/io/vamsas/DatastoreItem.java +++ b/src/jalview/io/vamsas/DatastoreItem.java @@ -1,235 +1,234 @@ -package jalview.io.vamsas; - -import jalview.bin.Cache; -import jalview.gui.TreePanel; -import jalview.io.VamsasAppDatastore; - -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.IdentityHashMap; -import java.util.Vector; - -import uk.ac.vamsas.client.IClientDocument; -import uk.ac.vamsas.client.Vobject; -import uk.ac.vamsas.client.VorbaId; -import uk.ac.vamsas.objects.core.Entry; -import uk.ac.vamsas.objects.core.Provenance; -import uk.ac.vamsas.objects.core.Seg; - -/** - * Holds all the common machinery for binding objects to vamsas objects - * @author JimP - * - */ -public class DatastoreItem -{ - /** - * - */ - Entry provEntry = null; - - IClientDocument cdoc; - - Hashtable vobj2jv; - - IdentityHashMap jv2vobj; - /** - * @return the Vobject bound to Jalview datamodel object - */ - protected Vobject getjv2vObj(Object jvobj) - { - if (jv2vobj.containsKey(jvobj)) - { - return cdoc.getObject( (VorbaId) jv2vobj.get(jvobj)); - } - if (Cache.log.isDebugEnabled()) - { - Cache.log.debug("Returning null VorbaID binding for jalview object "+jvobj); - } - return null; - } - - /** - * - * @param vobj - * @return Jalview datamodel object bound to the vamsas document object - */ - protected Object getvObj2jv(uk.ac.vamsas.client.Vobject vobj) - { - if (vobj2jv==null) - return null; - VorbaId id = vobj.getVorbaId(); - if (id == null) - { - id = cdoc.registerObject(vobj); - Cache.log - .debug("Registering new object and returning null for getvObj2jv"); - return null; - } - if (vobj2jv.containsKey(vobj.getVorbaId())) - { - return vobj2jv.get(vobj.getVorbaId()); - } - return null; - } - - protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj) - { - VorbaId id = vobj.getVorbaId(); - if (id == null) - { - id = cdoc.registerObject(vobj); - if (id == null || vobj.getVorbaId() == null || cdoc.getObject(id)!=vobj) - { - Cache.log.error("Failed to get id for " + - (vobj.isRegisterable() ? "registerable" : - "unregisterable") + " object " + vobj); - } - } - - if (vobj2jv.containsKey(vobj.getVorbaId()) && - ! ( (VorbaId) vobj2jv.get(vobj.getVorbaId())).equals(jvobj)) - { - Cache.log.debug("Warning? Overwriting existing vamsas id binding for " + - vobj.getVorbaId(), - new Exception("Overwriting vamsas id binding.")); - } - else if (jv2vobj.containsKey(jvobj) && - ! ( (VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId())) - { - Cache.log.debug( - "Warning? Overwriting existing jalview object binding for " + jvobj, - new Exception("Overwriting jalview object binding.")); - } - /* Cache.log.error("Attempt to make conflicting object binding! "+vobj+" id " +vobj.getVorbaId()+" already bound to "+getvObj2jv(vobj)+" and "+jvobj+" already bound to "+getjv2vObj(jvobj),new Exception("Excessive call to bindjvvobj")); - }*/ - // we just update the hash's regardless! - Cache.log.debug("Binding "+vobj.getVorbaId()+" to "+jvobj); - vobj2jv.put(vobj.getVorbaId(), jvobj); - // JBPNote - better implementing a hybrid invertible hash. - jv2vobj.put(jvobj, vobj.getVorbaId()); - } - - public DatastoreItem() { - super(); - } - public DatastoreItem(VamsasAppDatastore datastore) - { - this(); - initDatastoreItem(datastore); - // TODO Auto-generated constructor stub - } - VamsasAppDatastore datastore = null; - public void initDatastoreItem(VamsasAppDatastore ds) - { - datastore = ds; - initDatastoreItem(ds.getProvEntry(), ds.getClientDocument(), ds.getVamsasObjectBinding(), ds.getJvObjectBinding()); - } - public void initDatastoreItem(Entry provEntry, IClientDocument cdoc, Hashtable vobj2jv, IdentityHashMap jv2vobj) - { - this.provEntry = provEntry; - this.cdoc = cdoc; - this.vobj2jv = vobj2jv; - this.jv2vobj = jv2vobj; - } - - protected boolean isModifiable(String modifiable) - { - return modifiable==null; // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS) - } - - protected Vector getjv2vObjs(Vector alsq) - { - Vector vObjs = new Vector(); - Enumeration elm = alsq.elements(); - while (elm.hasMoreElements()) - { - vObjs.addElement(getjv2vObj(elm.nextElement())); - } - return vObjs; - } - // utility functions - /** - * get start0) - { - // TODO: Jalview ignores all the other maps - if (dbref.getMapCount()>1) - { - jalview.bin.Cache.log.debug("Ignoring additional mappings on DbRef: "+dbentry.getSource()+":"+dbentry.getAccessionId()); - } - jalview.datamodel.Mapping mp = new jalview.datamodel.Mapping(parsemapType(dbref.getMap(0))); - dbentry.setMap(mp); - } - // TODO: jalview ignores links and properties because it doesn't know what to do with them. - - bindjvvobj(dbentry, dbref); - } - private void add() - { - DbRef dbref = new DbRef(); - bindjvvobj(dbentry, dbref); - dbref.setAccessionId(dbentry.getAccessionId()); - dbref.setSource(dbentry.getSource()); - dbref.setVersion(dbentry.getVersion()); - if (dbentry.getMap()!=null) - { - jalview.datamodel.Mapping mp = dbentry.getMap(); - if (mp.getMap()!=null) - { - Map vMap = new Map(); - initMapType(vMap, mp.getMap(), true); - dbref.addMap(vMap); - } else { - jalview.bin.Cache.log.debug("Ignoring mapless DbRef.Map "+dbentry.getSrcAccString()); - } - } - sequence.addDbRef(dbref); - } - -} +package jalview.io.vamsas; + +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.SequenceI; +import uk.ac.vamsas.objects.core.DbRef; +import uk.ac.vamsas.objects.core.Map; +import uk.ac.vamsas.objects.core.Sequence; +import jalview.io.VamsasAppDatastore; + +public class Dbref extends Rangetype +{ + jalview.datamodel.SequenceI sq = null; + uk.ac.vamsas.objects.core.Sequence sequence = null; + DbRef dbref = null; + DBRefEntry dbentry=null; + public Dbref(VamsasAppDatastore datastore, DBRefEntry dbentry, jalview.datamodel.SequenceI sq2, uk.ac.vamsas.objects.core.Sequence sequence2) + { + super(datastore); + dbref = (DbRef) getjv2vObj(dbentry); + sq = sq2; + sequence = sequence2; + this.dbentry = dbentry; + if (dbref==null) + { + add(); + } else { + if (dbref.isUpdated()) + { + conflict(); + } else { + update(); + } + + } + + } + + public Dbref(VamsasAppDatastore datastore, DbRef ref, Sequence vdseq, SequenceI dsseq) + { + super(datastore); + dbref = ref; + sequence = vdseq; + sq = dsseq; + dbentry = (jalview.datamodel.DBRefEntry) getvObj2jv(dbref); + if (dbentry == null) + { + addFromDocument(); + } else { + if (dbref.isUpdated()) + { + update(); + } + } + } + + private void update() + { + // TODO: verify and update dbrefs in vamsas document + // there will be trouble when a dataset sequence is modified to + // contain more residues than were originally referenced - we must + // then make a number of dataset sequence entries - this info is already stored + jalview.bin.Cache.log.debug("TODO verify update of dataset sequence database references."); + } + + private void conflict() + { + jalview.bin.Cache.log.debug("Conflict in dbentry update for "+dbref.getAccessionId()+dbref.getSource()+" "+dbref.getVorbaId()); + // TODO Auto-generated method stub + + } + private void addFromDocument() + { + // add new dbref + sq.addDBRef(dbentry = new jalview.datamodel.DBRefEntry + ( + dbref.getSource().toString(), + dbref.getVersion().toString(), + dbref.getAccessionId().toString())); + if (dbref.getMapCount()>0) + { + // TODO: Jalview ignores all the other maps + if (dbref.getMapCount()>1) + { + jalview.bin.Cache.log.debug("Ignoring additional mappings on DbRef: "+dbentry.getSource()+":"+dbentry.getAccessionId()); + } + jalview.datamodel.Mapping mp = new jalview.datamodel.Mapping(parsemapType(dbref.getMap(0))); + dbentry.setMap(mp); + } + // TODO: jalview ignores links and properties because it doesn't know what to do with them. + + bindjvvobj(dbentry, dbref); + } + private void add() + { + DbRef dbref = new DbRef(); + bindjvvobj(dbentry, dbref); + dbref.setAccessionId(dbentry.getAccessionId()); + dbref.setSource(dbentry.getSource()); + dbref.setVersion(dbentry.getVersion()); + if (dbentry.getMap()!=null) + { + jalview.datamodel.Mapping mp = dbentry.getMap(); + if (mp.getMap()!=null) + { + Map vMap = new Map(); + initMapType(vMap, mp.getMap(), true); + dbref.addMap(vMap); + } else { + jalview.bin.Cache.log.debug("Ignoring mapless DbRef.Map "+dbentry.getSrcAccString()); + } + } + sequence.addDbRef(dbref); + } + +} diff --git a/src/jalview/io/vamsas/LocalDocSyncObject.java b/src/jalview/io/vamsas/LocalDocSyncObject.java index 344d40b..bfc2123 100644 --- a/src/jalview/io/vamsas/LocalDocSyncObject.java +++ b/src/jalview/io/vamsas/LocalDocSyncObject.java @@ -1,85 +1,85 @@ -package jalview.io.vamsas; - -import uk.ac.vamsas.client.Vobject; - -/** - * Implement the basic logic for synchronising changes to or from the Vamsas Document - * @author JimP - */ -public abstract class LocalDocSyncObject extends DatastoreItem -{ - /** - * - * @return null or the local object that is being worked on. - */ - public abstract Object getLObject(); - /** - * - * @return null or the document object that is being worked on - */ - public abstract Vobject getVObject(); - - /** - * endpoint for synchronize when all opreations are finished. - */ - public abstract void nextObject(); - /** - * called if the local object can be safely updated from the bound document object. - */ - public abstract void updateFromDoc(); - /** - * called if the associated document object can be safely updated with the local changes - */ - public abstract void updateToDoc(); - /** - * @return true if the local object is modified - */ - public abstract boolean locallyModified(); - /** - * - * @return true if the bound document object is modified - */ - public abstract boolean documentModified(); - /** - * - * @return true if the document object is locked w.r.t. this object's update. - */ - public abstract boolean documentObjectLocked(); - /** - * - * @return a new datastore item instance which binds the local object to a new document object - */ - public abstract LocalDocSyncObject newDocumentObject(); // could make this constructor(Lobject) - /** - * - * @return a new datastore item instance which binds the document object to a new local object. - */ - public abstract LocalDocSyncObject newLocalObject(); // make this constructor(Vobject) - /** - * apply the update/commit logic as defined in the vamsas paper - * @param documentIsUpdated true if a document update event is being handled - */ - public void synchronize(boolean documentIsUpdated) { - Object Lobject = getLObject(); - Vobject Vobject = getVObject(); - if (Lobject==null) - { - // no local binding for document object - newLocalObject().synchronize(documentIsUpdated); - return; - } - if (Vobject==null) - { - // no document binding for local object - newDocumentObject().synchronize(documentIsUpdated); - } - // Check binding is valid - if (getjv2vObj(Lobject)!=Vobject) - { - // no local binding for document object - newLocalObject().synchronize(documentIsUpdated); - // no document binding for local object - newDocumentObject().synchronize(documentIsUpdated); - } - } -} +package jalview.io.vamsas; + +import uk.ac.vamsas.client.Vobject; + +/** + * Implement the basic logic for synchronising changes to or from the Vamsas Document + * @author JimP + */ +public abstract class LocalDocSyncObject extends DatastoreItem +{ + /** + * + * @return null or the local object that is being worked on. + */ + public abstract Object getLObject(); + /** + * + * @return null or the document object that is being worked on + */ + public abstract Vobject getVObject(); + + /** + * endpoint for synchronize when all opreations are finished. + */ + public abstract void nextObject(); + /** + * called if the local object can be safely updated from the bound document object. + */ + public abstract void updateFromDoc(); + /** + * called if the associated document object can be safely updated with the local changes + */ + public abstract void updateToDoc(); + /** + * @return true if the local object is modified + */ + public abstract boolean locallyModified(); + /** + * + * @return true if the bound document object is modified + */ + public abstract boolean documentModified(); + /** + * + * @return true if the document object is locked w.r.t. this object's update. + */ + public abstract boolean documentObjectLocked(); + /** + * + * @return a new datastore item instance which binds the local object to a new document object + */ + public abstract LocalDocSyncObject newDocumentObject(); // could make this constructor(Lobject) + /** + * + * @return a new datastore item instance which binds the document object to a new local object. + */ + public abstract LocalDocSyncObject newLocalObject(); // make this constructor(Vobject) + /** + * apply the update/commit logic as defined in the vamsas paper + * @param documentIsUpdated true if a document update event is being handled + */ + public void synchronize(boolean documentIsUpdated) { + Object Lobject = getLObject(); + Vobject Vobject = getVObject(); + if (Lobject==null) + { + // no local binding for document object + newLocalObject().synchronize(documentIsUpdated); + return; + } + if (Vobject==null) + { + // no document binding for local object + newDocumentObject().synchronize(documentIsUpdated); + } + // Check binding is valid + if (getjv2vObj(Lobject)!=Vobject) + { + // no local binding for document object + newLocalObject().synchronize(documentIsUpdated); + // no document binding for local object + newDocumentObject().synchronize(documentIsUpdated); + } + } +} diff --git a/src/jalview/io/vamsas/Rangetype.java b/src/jalview/io/vamsas/Rangetype.java index f6a6ecc..b7e6f79 100644 --- a/src/jalview/io/vamsas/Rangetype.java +++ b/src/jalview/io/vamsas/Rangetype.java @@ -1,270 +1,270 @@ -package jalview.io.vamsas; - - -import java.util.Vector; - -import uk.ac.vamsas.objects.core.Local; -import uk.ac.vamsas.objects.core.Map; -import uk.ac.vamsas.objects.core.MapType; -import uk.ac.vamsas.objects.core.Mapped; -import uk.ac.vamsas.objects.core.RangeType; -import uk.ac.vamsas.objects.core.Seg; -import jalview.datamodel.Mapping; -import jalview.io.VamsasAppDatastore; - -public class Rangetype extends DatastoreItem -{ - - public Rangetype() - { - super(); - } - - public Rangetype(VamsasAppDatastore datastore) - { - super(datastore); - } - - /** - * get real bounds of a RangeType's specification. start and end are an - * inclusive range within which all segments and positions lie. - * TODO: refactor to vamsas utils - * @param dseta - * @return int[] { start, end} - */ - protected int[] getBounds(RangeType dseta) - { - if (dseta != null) - { - int[] se = null; - if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0) - { - throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!"); - } - if (dseta.getSegCount() > 0) - { - se = getSegRange(dseta.getSeg(0), true); - for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++) - { - int nse[] = getSegRange(dseta.getSeg(s), true); - if (se[0] > nse[0]) - { - se[0] = nse[0]; - } - if (se[1] < nse[1]) - { - se[1] = nse[1]; - } - } - } - if (dseta.getPosCount() > 0) - { - // could do a polarity for pos range too. and pass back indication of discontinuities. - int pos = dseta.getPos(0).getI(); - se = new int[] - { - pos, pos}; - for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++) - { - pos = dseta.getPos(p).getI(); - if (se[0] > pos) - { - se[0] = pos; - } - if (se[1] < pos) - { - se[1] = pos; - } - } - } - return se; - } - return null; - } - - /** - * map from a rangeType's internal frame to the referenced object's coordinate frame. - * @param dseta - * @return int [] { ref(pos)...} for all pos in rangeType's frame. - */ - protected int[] getMapping(RangeType dseta) - { - Vector posList = new Vector(); - if (dseta != null) - { - int[] se = null; - if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0) - { - throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!"); - } - if (dseta.getSegCount() > 0) - { - for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++) - { - se = getSegRange(dseta.getSeg(s), false); - int se_end = se[1 - se[2]] + (se[2] == 0 ? 1 : -1); - for (int p = se[se[2]]; p != se_end; p += se[2] == 0 ? 1 : -1) - { - posList.add(new Integer(p)); - } - } - } - else if (dseta.getPosCount() > 0) - { - int pos = dseta.getPos(0).getI(); - - for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++) - { - pos = dseta.getPos(p).getI(); - posList.add(new Integer(pos)); - } - } - } - if (posList != null && posList.size() > 0) - { - int[] range = new int[posList.size()]; - for (int i = 0; i < range.length; i++) - { - range[i] = ( (Integer) posList.elementAt(i)).intValue(); - } - posList.clear(); - return range; - } - return null; - } - - protected int[] getIntervals(RangeType range) - { - int[] intervals=null; - Vector posList = new Vector(); - if (range != null) - { - int[] se = null; - if (range.getSegCount() > 0 && range.getPosCount() > 0) - { - throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!"); - } - if (range.getSegCount() > 0) - { - for (int s = 0, sSize = range.getSegCount(); s < sSize; s++) - { - se = getSegRange(range.getSeg(s), false); - posList.addElement(new Integer(se[0])); - posList.addElement(new Integer(se[1])); - } - } - else if (range.getPosCount() > 0) - { - int pos = range.getPos(0).getI(); - - for (int p = 0, pSize = range.getPosCount(); p < pSize; p++) - { - pos = range.getPos(p).getI(); - posList.add(new Integer(pos)); - posList.add(new Integer(pos)); - } - } - } - if (posList != null && posList.size() > 0) - { - intervals=new int[posList.size()]; - java.util.Enumeration e = posList.elements(); - int i=0; - while (e.hasMoreElements()) - { - intervals[i++] = ((Integer)e.nextElement()).intValue(); - } - } - return intervals; - } - /** - * initialise a range type object from a set of start/end inclusive intervals - * @param mrt - * @param range - */ - protected void initRangeType(RangeType mrt, int[] range) - { - for (int i=0; i "+map.toString()))); - } - return parsemapType(map, 1, 1); - } - - /** - * initialise a MapType object from a MapList object. - * @param maprange - * @param ml - * @param setUnits - */ - protected void initMapType(MapType maprange, jalview.util.MapList ml, boolean setUnits) - { - initMapType(maprange, ml, setUnits, false); - } - /** - * - * @param maprange - * @param ml - * @param setUnits - * @param reverse - reverse MapList mapping for Local and Mapped ranges and units - */ - protected void initMapType(MapType maprange, jalview.util.MapList ml, boolean setUnits, boolean reverse) - { - if (ml==null) - { - throw new Error("Implementation error. MapList is null for initMapType."); - } - maprange.setLocal(new Local()); - maprange.setMapped(new Mapped()); - if (!reverse) - { - initRangeType(maprange.getLocal(), ml.getFromRanges()); - initRangeType(maprange.getMapped(), ml.getToRanges()); - } else { - initRangeType(maprange.getLocal(), ml.getToRanges()); - initRangeType(maprange.getMapped(), ml.getFromRanges()); - } - if (setUnits) - { - if (!reverse) - { - maprange.getLocal().setUnit(ml.getFromRatio()); - maprange.getMapped().setUnit(ml.getToRatio()); - } else { - maprange.getLocal().setUnit(ml.getToRatio()); - maprange.getMapped().setUnit(ml.getFromRatio()); - } - } - } - +package jalview.io.vamsas; + + +import java.util.Vector; + +import uk.ac.vamsas.objects.core.Local; +import uk.ac.vamsas.objects.core.Map; +import uk.ac.vamsas.objects.core.MapType; +import uk.ac.vamsas.objects.core.Mapped; +import uk.ac.vamsas.objects.core.RangeType; +import uk.ac.vamsas.objects.core.Seg; +import jalview.datamodel.Mapping; +import jalview.io.VamsasAppDatastore; + +public class Rangetype extends DatastoreItem +{ + + public Rangetype() + { + super(); + } + + public Rangetype(VamsasAppDatastore datastore) + { + super(datastore); + } + + /** + * get real bounds of a RangeType's specification. start and end are an + * inclusive range within which all segments and positions lie. + * TODO: refactor to vamsas utils + * @param dseta + * @return int[] { start, end} + */ + protected int[] getBounds(RangeType dseta) + { + if (dseta != null) + { + int[] se = null; + if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0) + { + throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!"); + } + if (dseta.getSegCount() > 0) + { + se = getSegRange(dseta.getSeg(0), true); + for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++) + { + int nse[] = getSegRange(dseta.getSeg(s), true); + if (se[0] > nse[0]) + { + se[0] = nse[0]; + } + if (se[1] < nse[1]) + { + se[1] = nse[1]; + } + } + } + if (dseta.getPosCount() > 0) + { + // could do a polarity for pos range too. and pass back indication of discontinuities. + int pos = dseta.getPos(0).getI(); + se = new int[] + { + pos, pos}; + for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++) + { + pos = dseta.getPos(p).getI(); + if (se[0] > pos) + { + se[0] = pos; + } + if (se[1] < pos) + { + se[1] = pos; + } + } + } + return se; + } + return null; + } + + /** + * map from a rangeType's internal frame to the referenced object's coordinate frame. + * @param dseta + * @return int [] { ref(pos)...} for all pos in rangeType's frame. + */ + protected int[] getMapping(RangeType dseta) + { + Vector posList = new Vector(); + if (dseta != null) + { + int[] se = null; + if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0) + { + throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!"); + } + if (dseta.getSegCount() > 0) + { + for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++) + { + se = getSegRange(dseta.getSeg(s), false); + int se_end = se[1 - se[2]] + (se[2] == 0 ? 1 : -1); + for (int p = se[se[2]]; p != se_end; p += se[2] == 0 ? 1 : -1) + { + posList.add(new Integer(p)); + } + } + } + else if (dseta.getPosCount() > 0) + { + int pos = dseta.getPos(0).getI(); + + for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++) + { + pos = dseta.getPos(p).getI(); + posList.add(new Integer(pos)); + } + } + } + if (posList != null && posList.size() > 0) + { + int[] range = new int[posList.size()]; + for (int i = 0; i < range.length; i++) + { + range[i] = ( (Integer) posList.elementAt(i)).intValue(); + } + posList.clear(); + return range; + } + return null; + } + + protected int[] getIntervals(RangeType range) + { + int[] intervals=null; + Vector posList = new Vector(); + if (range != null) + { + int[] se = null; + if (range.getSegCount() > 0 && range.getPosCount() > 0) + { + throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!"); + } + if (range.getSegCount() > 0) + { + for (int s = 0, sSize = range.getSegCount(); s < sSize; s++) + { + se = getSegRange(range.getSeg(s), false); + posList.addElement(new Integer(se[0])); + posList.addElement(new Integer(se[1])); + } + } + else if (range.getPosCount() > 0) + { + int pos = range.getPos(0).getI(); + + for (int p = 0, pSize = range.getPosCount(); p < pSize; p++) + { + pos = range.getPos(p).getI(); + posList.add(new Integer(pos)); + posList.add(new Integer(pos)); + } + } + } + if (posList != null && posList.size() > 0) + { + intervals=new int[posList.size()]; + java.util.Enumeration e = posList.elements(); + int i=0; + while (e.hasMoreElements()) + { + intervals[i++] = ((Integer)e.nextElement()).intValue(); + } + } + return intervals; + } + /** + * initialise a range type object from a set of start/end inclusive intervals + * @param mrt + * @param range + */ + protected void initRangeType(RangeType mrt, int[] range) + { + for (int i=0; i "+map.toString()))); + } + return parsemapType(map, 1, 1); + } + + /** + * initialise a MapType object from a MapList object. + * @param maprange + * @param ml + * @param setUnits + */ + protected void initMapType(MapType maprange, jalview.util.MapList ml, boolean setUnits) + { + initMapType(maprange, ml, setUnits, false); + } + /** + * + * @param maprange + * @param ml + * @param setUnits + * @param reverse - reverse MapList mapping for Local and Mapped ranges and units + */ + protected void initMapType(MapType maprange, jalview.util.MapList ml, boolean setUnits, boolean reverse) + { + if (ml==null) + { + throw new Error("Implementation error. MapList is null for initMapType."); + } + maprange.setLocal(new Local()); + maprange.setMapped(new Mapped()); + if (!reverse) + { + initRangeType(maprange.getLocal(), ml.getFromRanges()); + initRangeType(maprange.getMapped(), ml.getToRanges()); + } else { + initRangeType(maprange.getLocal(), ml.getToRanges()); + initRangeType(maprange.getMapped(), ml.getFromRanges()); + } + if (setUnits) + { + if (!reverse) + { + maprange.getLocal().setUnit(ml.getFromRatio()); + maprange.getMapped().setUnit(ml.getToRatio()); + } else { + maprange.getLocal().setUnit(ml.getToRatio()); + maprange.getMapped().setUnit(ml.getFromRatio()); + } + } + } + } \ No newline at end of file diff --git a/src/jalview/io/vamsas/Sequencemapping.java b/src/jalview/io/vamsas/Sequencemapping.java index 4cede9a..746a7d0 100644 --- a/src/jalview/io/vamsas/Sequencemapping.java +++ b/src/jalview/io/vamsas/Sequencemapping.java @@ -1,328 +1,328 @@ -package jalview.io.vamsas; - -import java.util.Vector; - -import jalview.datamodel.AlignedCodonFrame; -import jalview.datamodel.Mapping; -import jalview.datamodel.SequenceI; -import jalview.io.VamsasAppDatastore; -import uk.ac.vamsas.client.Vobject; -import uk.ac.vamsas.objects.core.AlignmentSequence; -import uk.ac.vamsas.objects.core.DataSet; -import uk.ac.vamsas.objects.core.Local; -import uk.ac.vamsas.objects.core.RangeType; -import uk.ac.vamsas.objects.core.Seg; -import uk.ac.vamsas.objects.core.Sequence; -import uk.ac.vamsas.objects.core.SequenceMapping; -import uk.ac.vamsas.objects.core.SequenceType; - -public class Sequencemapping extends Rangetype -{ - public Sequencemapping(VamsasAppDatastore datastore, SequenceMapping sequenceMapping) - { - super(datastore); - Object mjvmapping = getvObj2jv(sequenceMapping); - if (mjvmapping==null) - { - add(sequenceMapping); - } else { - if (sequenceMapping.isUpdated()) - { - update((jalview.util.MapList) mjvmapping, sequenceMapping); - } - } - } - /** - * create or update a vamsas sequence mapping corresponding to a jalview - * Mapping between two dataset sequences - * - * @param datastore - * @param mjvmapping - * @param from - * @param ds - */ - public Sequencemapping(VamsasAppDatastore datastore, jalview.datamodel.Mapping mjvmapping, uk.ac.vamsas.objects.core.SequenceType from, uk.ac.vamsas.objects.core.DataSet ds) - { - super(datastore); - SequenceMapping sequenceMapping = (SequenceMapping) getjv2vObj(mjvmapping); - if (sequenceMapping==null) - { - add(mjvmapping, from, ds); - } else { - if (from!=null && sequenceMapping.getLoc()!=from) - { - jalview.bin.Cache.log.warn("Probable IMPLEMENTATION ERROR: "+from+" doesn't match the local mapping sequence."); - } - if (ds!=null && sequenceMapping.is__stored_in_document() && sequenceMapping.getV_parent()!=ds) - { - jalview.bin.Cache.log.warn("Probable IMPLEMENTATION ERROR: "+ds+" doesn't match the parent of the bound sequence mapping object."); - } - if (sequenceMapping.isUpdated()) - { - conflict(mjvmapping, sequenceMapping); - } else { - update(mjvmapping, sequenceMapping); - } - } - } - private void conflict(Mapping mjvmapping, SequenceMapping sequenceMapping) - { - // TODO Auto-generated method stub - - } - private void add(Mapping mjvmapping, uk.ac.vamsas.objects.core.SequenceType from, DataSet ds) - { - SequenceI jvto = mjvmapping.getTo(); - while (jvto.getDatasetSequence()!=null) - { - jvto = jvto.getDatasetSequence(); - } - SequenceType to = (SequenceType) getjv2vObj(jvto); - if (to==null) - { - jalview.bin.Cache.log.warn("NONFATAL - do a second update: Ignoring Forward Reference to seuqence not yet bound to vamsas seuqence object"); - return; - } - SequenceMapping sequenceMapping = new SequenceMapping(); - sequenceMapping.setLoc(from); - sequenceMapping.setMap(to); - boolean dnaToProt=false,sense=false; - // ensure that we create a mapping with the correct sense - if (((Sequence) sequenceMapping.getLoc()) - .getDictionary() - .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA)) - { - if (((Sequence) sequenceMapping.getMap()) - .getDictionary() - .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA)) - { - dnaToProt=true; - sense=true; - } - } else { - if (((Sequence) sequenceMapping.getMap()) - .getDictionary() - .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA)) - { - dnaToProt=true; - sense=false; - } - } - - if (!dnaToProt) - { - jalview.bin.Cache.log.warn("Ignoring Mapping - don't support protein to protein mapping in vamsas document yet."); - return; - } - if (ds==null) - { - // locate dataset for storage of SequenceMapping - if (sense) - { - ds = (DataSet) ((uk.ac.vamsas.client.Vobject) sequenceMapping.getLoc()).getV_parent(); - } else { - ds = (DataSet) ((uk.ac.vamsas.client.Vobject) sequenceMapping.getMap()).getV_parent(); - } - } - if (sense) - { - this.initMapType(sequenceMapping, mjvmapping.getMap(), true); - } else { - this.initMapType(sequenceMapping, mjvmapping.getMap().getInverse(), true); - } - ds.addSequenceMapping(sequenceMapping); - sequenceMapping.setProvenance(this.dummyProvenance("user defined coding region translation")); // TODO: - // correctly - // construct - // provenance - // based - // on - // source - // of - // mapping - bindjvvobj(mjvmapping, sequenceMapping); - - jalview.bin.Cache.log.debug("Successfully created mapping "+sequenceMapping.getVorbaId()); - } - private void update(jalview.util.MapList mjvmapping, SequenceMapping sequenceMapping) - { - jalview.bin.Cache.log.error("Not implemented: Jalview Update Alcodon Mapping:TODO!"); - } - private void update(jalview.datamodel.Mapping mjvmapping, SequenceMapping sequenceMapping) - { - jalview.bin.Cache.log.error("Not implemented: Jalview Update Sequence DBRef Mapping"); - } - /** - * limitations: Currently, jalview only deals with mappings between dataset - * sequences, and even then, only between those that map from DNA to Protein. - * - * @param sequenceMapping - */ - private void add(SequenceMapping sequenceMapping) - { - Object mobj; - SequenceI from=null,to=null; - boolean dnaToProt=false,sense=false; - Sequence sdloc=null, sdmap=null; - if (sequenceMapping.getLoc() instanceof AlignmentSequence) - { - sdloc = (Sequence) ((AlignmentSequence) sequenceMapping.getLoc()).getRefid(); - } else { - sdloc = ((Sequence) sequenceMapping.getLoc()); - } - if (sequenceMapping.getMap() instanceof AlignmentSequence) - { - sdmap = (Sequence) ((AlignmentSequence) sequenceMapping.getMap()).getRefid(); - } else { - sdmap = ((Sequence) sequenceMapping.getMap()); - } - if (sdloc==null || sdmap == null) - { - jalview.bin.Cache.log.info("Ignoring non sequence-sequence mapping"); - return; - } - mobj = this.getvObj2jv((Vobject) sdloc); - if (mobj instanceof SequenceI) - { - from = (SequenceI) mobj; - } - mobj = this.getvObj2jv((Vobject) sdmap); - if (mobj instanceof SequenceI) - { - to = (SequenceI) mobj; - } - if (from == null || to == null) - { - - jalview.bin.Cache.log.error("Probable Vamsas implementation error : unbound dataset sequences involved in a mapping are being parsed!"); - return; - } - - if (sdloc.getDictionary() - .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA)) - { - if (sdmap.getDictionary() - .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA)) - { - dnaToProt=true; - sense=true; - } - // else { - - // } - } else { - if (sdmap.getDictionary() - .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA)) - { - dnaToProt=true; - sense=false; - } - } - // create mapping storage object and make each dataset alignment reference - // it. - jalview.datamodel.AlignmentI dsLoc = (jalview.datamodel.AlignmentI) getvObj2jv(sdloc.getV_parent()); - jalview.datamodel.AlignmentI dsMap = (jalview.datamodel.AlignmentI) getvObj2jv(sdmap.getV_parent()); - AlignedCodonFrame afc = new AlignedCodonFrame(0); - - if (dsLoc!=null && dsLoc!=dsMap) - { - dsLoc.addCodonFrame(afc); - } - if (dsMap!=null) - { - dsMap.addCodonFrame(afc); - } - // create and add the new mapping to (each) dataset's codonFrame - - jalview.util.MapList mapping = null; - if (!sense) - { - mapping = this.parsemapType(sequenceMapping, 1, 3); // invert sense - mapping = new jalview.util.MapList(mapping.getToRanges(), mapping.getFromRanges(), mapping.getToRatio(), mapping.getFromRatio()); - afc.addMap(to, from, mapping); - } else { - mapping = this.parsemapType(sequenceMapping, 3, 1); // correct sense - afc.addMap(from, to, mapping); - } - bindjvvobj(mapping, sequenceMapping); - jalview.structure.StructureSelectionManager.getStructureSelectionManager().addMappings(new AlignedCodonFrame[] { afc }); - // Try to link up any conjugate database references in the two sequences - // matchConjugateDBRefs(from, to, mapping); - // Try to propagate any dbrefs across this mapping. - - } - /** - * Complete any 'to' references in jalview.datamodel.Mapping objects associated with conjugate DBRefEntry under given mapping - * @param from sequence corresponding to from reference for sequence mapping - * @param to sequence correspondeing to to reference for sequence mapping - * @param smap maplist parsed in same sense as from and to - */ - private void matchConjugateDBRefs(SequenceI from, SequenceI to, - jalview.util.MapList smap) - { - if (from.getDBRef()==null && to.getDBRef()==null) - { - if (jalview.bin.Cache.log.isDebugEnabled()) - { - jalview.bin.Cache.log.debug("Not matching conjugate refs for "+from.getName()+" and "+to.getName()); - } - return; - } - if (jalview.bin.Cache.log.isDebugEnabled()) - { - jalview.bin.Cache.log.debug("Matching conjugate refs for "+from.getName()+" and "+to.getName()); - } - jalview.datamodel.DBRefEntry[] fdb = from.getDBRef(); - jalview.datamodel.DBRefEntry[] tdb = new jalview.datamodel.DBRefEntry[to.getDBRef().length]; - int tdblen = to.getDBRef().length; - System.arraycopy(to.getDBRef(), 0, tdb, 0, tdblen); - Vector matched = new Vector(); - jalview.util.MapList smapI = smap.getInverse(); - for (int f=0;f dataset or - - // other kind of tree - private NewickFile ntree; - - private String title; - - private AlignmentView inputData = null; - - public static void updateFrom(VamsasAppDatastore datastore, - jalview.gui.AlignFrame alignFrame, - uk.ac.vamsas.objects.core.Tree vtree) - { - Tree toTree = new Tree(datastore, alignFrame, vtree); - - } - - public Tree(VamsasAppDatastore datastore, - jalview.gui.AlignFrame alignFrame, - uk.ac.vamsas.objects.core.Tree vtree) - { - super(datastore); - tree = vtree; - TreePanel tp = (TreePanel) getvObj2jv(tree); - if (tp != null) - { - if (tree.isUpdated()) - { - Cache.log - .info("Update from vamsas document to alignment associated tree not implemented yet."); - } - } - else - { - // make a new tree - Object[] idata = recoverInputData(tree.getProvenance()); - try - { - if (idata != null && idata[0] != null) - { - inputData = (AlignmentView) idata[0]; - } - ntree = getNtree(); - title = tree.getNewick(0).getTitle(); - if (title == null || title.length() == 0) - { - title = tree.getTitle(); // hack!!!! - } - } catch (Exception e) - { - Cache.log.warn("Problems parsing treefile '" - + tree.getNewick(0).getContent() + "'", e); - } - } - } - - private NewickFile getNtree() throws IOException - { - return new jalview.io.NewickFile(tree.getNewick(0).getContent()); - } - - public Tree(VamsasAppDatastore datastore, TreePanel tp2, AlignmentI jal2, - uk.ac.vamsas.objects.core.Alignment alignment2) - { - super(datastore); - - jal = jal2; - tp = tp2; - alignment = alignment2; - - tree = (uk.ac.vamsas.objects.core.Tree) getjv2vObj(tp); - if (tree == null) - { - add(); - } - else - { - if (isModifiable(tree.getModifiable())) - { - // synchronize(); // update(); - // verify any changes. - System.out.println("Update tree in document."); - } - else - { - // handle conflict - System.out.println("Add modified tree as new tree in document."); - } - } - } - - /** - * correctly creates provenance for trees calculated on an alignment by - * jalview. - * - * @param jal - * @param tp - * @return - */ - private Provenance makeTreeProvenance(AlignmentI jal, TreePanel tp) - { - Cache.log.debug("Making Tree provenance for " + tp.getTitle()); - Provenance prov = new Provenance(); - prov.addEntry(new Entry()); - prov.getEntry(0).setAction("imported " + tp.getTitle()); - prov.getEntry(0).setUser(provEntry.getUser()); - prov.getEntry(0).setApp(provEntry.getApp()); - prov.getEntry(0).setDate(provEntry.getDate()); - if (tp.getTree().hasOriginalSequenceData()) - { - Input vInput = new Input(); - // LATER: check to see if tree input data is contained in this alignment - - // or just correctly resolve the tree's seqData to the correct alignment - // in - // the document. - Vector alsqrefs = getjv2vObjs(findAlignmentSequences(jal, tp - .getTree().seqData.getSequences())); - Object[] alsqs = new Object[alsqrefs.size()]; - alsqrefs.copyInto(alsqs); - vInput.setObjRef(alsqs); - // now create main provenance data - prov.getEntry(0).setAction("created " + tp.getTitle()); - prov.getEntry(0).addInput(vInput); - // jalview's special input parameter for distance matrix calculations - vInput.setName("jalview:seqdist"); // TODO: settle on appropriate name. - prov.getEntry(0).addParam(new Param()); - prov.getEntry(0).getParam(0).setName("treeType"); - prov.getEntry(0).getParam(0).setType("utf8"); - prov.getEntry(0).getParam(0).setContent("NJ"); // TODO: type of tree is a - // general parameter - int ranges[] = tp.getTree().seqData.getVisibleContigs(); - // VisibleContigs are with respect to alignment coordinates. Still need - // offsets - int start = tp.getTree().seqData.getAlignmentOrigin(); - for (int r = 0; r < ranges.length; r += 2) - { - Seg visSeg = new Seg(); - visSeg.setStart(1 + start + ranges[r]); - visSeg.setEnd(start + ranges[r + 1]); - visSeg.setInclusive(true); - vInput.addSeg(visSeg); - } - } - Cache.log.debug("Finished Tree provenance for " + tp.getTitle()); - return prov; - } - - /** - * look up SeqCigars in an existing alignment. - * - * @param jal - * @param sequences - * @return vector of alignment sequences in order of SeqCigar array (but - * missing unfound seqcigars) - */ - private Vector findAlignmentSequences(AlignmentI jal, SeqCigar[] sequences) - { - SeqCigar[] tseqs = new SeqCigar[sequences.length]; - System.arraycopy(sequences, 0, tseqs, 0, sequences.length); - Vector alsq = new Vector(); - Enumeration as = jal.getSequences().elements(); - while (as.hasMoreElements()) - { - SequenceI asq = (SequenceI) as.nextElement(); - for (int t = 0; t < sequences.length; t++) - { - if (tseqs[t] != null - && (tseqs[t].getRefSeq() == asq || tseqs[t].getRefSeq() == asq - .getDatasetSequence())) - // && tseqs[t].getStart()>=asq.getStart() && - // tseqs[t].getEnd()<=asq.getEnd()) - { - tseqs[t] = null; - alsq.add(asq); - } - } - } - if (alsq.size() < sequences.length) - Cache.log - .warn("Not recovered all alignment sequences for given set of input sequence CIGARS"); - return alsq; - } - - /** - * - * Update jalview newick representation with TreeNode map - * - * @param tp - * the treepanel that this tree is bound to. - */ - public void UpdateSequenceTreeMap(TreePanel tp) - { - if (tp == null || tree != null) - return; - Vector leaves = new Vector(); - tp.getTree().findLeaves(tp.getTree().getTopNode(), leaves); - Treenode[] tn = tree.getTreenode(); // todo: select nodes for this - // particular tree - int sz = tn.length; - int i = 0; - - while (i < sz) - { - Treenode node = tn[i++]; - BinaryNode mappednode = findNodeSpec(node.getNodespec(), leaves); - if (mappednode != null && mappednode instanceof SequenceNode) - { - SequenceNode leaf = (SequenceNode) leaves.elementAt(i++); - // check if we can make the specified association - Object jvseq = null; - int vrf = 0, refv = 0; - while (jvseq == null && vrf < node.getVrefCount()) - { - if (refv < node.getVref(vrf).getRefsCount()) - { - Object noderef = node.getVref(vrf).getRefs(refv++); - if (noderef instanceof AlignmentSequence) - { - // we only make these kind of associations - jvseq = getvObj2jv((Vobject) noderef); - } - } - else - { - refv = 0; - vrf++; - } - } - if (jvseq instanceof SequenceI) - { - leaf.setElement(jvseq); - leaf.setPlaceholder(false); - } - else - { - leaf.setPlaceholder(true); - leaf - .setElement(new Sequence(leaf.getName(), - "THISISAPLACEHLDER")); - } - } - } - } - - // / TODO: refactor to vamsas :start - /** - * construct treenode mappings for mapped sequences - * - * @param ntree - * @param newick - * @return - */ - public Treenode[] makeTreeNodes(NJTree ntree, Newick newick) - { - Vector leaves = new Vector(); - ntree.findLeaves(ntree.getTopNode(), leaves); - Vector tnv = new Vector(); - Enumeration l = leaves.elements(); - Hashtable nodespecs = new Hashtable(); - while (l.hasMoreElements()) - { - jalview.datamodel.BinaryNode tnode = (jalview.datamodel.BinaryNode) l - .nextElement(); - if (tnode instanceof jalview.datamodel.SequenceNode) - { - if (!((jalview.datamodel.SequenceNode) tnode).isPlaceholder()) - { - Object assocseq = ((jalview.datamodel.SequenceNode) tnode) - .element(); - if (assocseq instanceof SequenceI) - { - Vobject vobj = this.getjv2vObj(assocseq); - if (vobj != null) - { - Treenode node = new Treenode(); - if (newick.isRegisterable()) - { - this.cdoc.registerObject(newick); - node.addTreeId(newick); - } - node.setNodespec(makeNodeSpec(nodespecs, tnode)); - node.setName(tnode.getName()); - Vref vr = new Vref(); - vr.addRefs(vobj); - node.addVref(vr); - tnv.addElement(node); - } - else - { - System.err.println("WARNING: Unassociated treeNode " - + tnode.element().toString() - + " " - + ((tnode.getName() != null) ? " label " - + tnode.getName() : "")); - } - } - } - } - } - if (tnv.size() > 0) - { - Treenode[] tn = new Treenode[tnv.size()]; - tnv.copyInto(tn); - return tn; - } - return new Treenode[] - {}; - } - - private String makeNodeSpec(Hashtable nodespecs, - jalview.datamodel.BinaryNode tnode) - { - String nname = new String(tnode.getName()); - Integer nindx = (Integer) nodespecs.get(nname); - if (nindx == null) - { - nindx = new Integer(1); - } - nname = nindx.toString() + " " + nname; - return nname; - } - - /** - * call to match up Treenode specs to NJTree parsed from document object. - * - * @param nodespec - * @param leaves - * as returned from NJTree.findLeaves( .., ..) .. - * @return - */ - private jalview.datamodel.BinaryNode findNodeSpec(String nodespec, - Vector leaves) - { - int occurence = -1; - String nspec = nodespec.substring(nodespec.indexOf(' ') + 1); - String oval = nodespec.substring(0, nodespec.indexOf(' ')); - try - { - occurence = new Integer(oval).intValue(); - } catch (Exception e) - { - System.err.println("Invalid nodespec '" + nodespec + "'"); - return null; - } - jalview.datamodel.BinaryNode bn = null; - - int nocc = 0; - Enumeration en = leaves.elements(); - while (en.hasMoreElements() && nocc < occurence) - { - bn = (jalview.datamodel.BinaryNode) en.nextElement(); - if (bn instanceof jalview.datamodel.SequenceNode - && bn.getName().equals(nspec)) - { - --occurence; - } - else - bn = null; - } - return bn; - } - - // todo: end refactor to vamsas library - /** - * add jalview object to vamsas document - * - */ - public void add() - { - tree = new uk.ac.vamsas.objects.core.Tree(); - bindjvvobj(tp, tree); - tree.setTitle(tp.getTitle()); - Newick newick = new Newick(); - newick.setContent(tp.getTree().toString()); - newick.setTitle(tp.getTitle()); - tree.addNewick(newick); - tree.setProvenance(makeTreeProvenance(jal, tp)); - tree.setTreenode(makeTreeNodes(tp.getTree(), newick)); - - alignment.addTree(tree); - } - - /** - * note: this function assumes that all sequence and alignment objects - * referenced in input data has already been associated with jalview objects. - * - * @param tp - * @param alignFrame - * @return Object[] { AlignmentView, AlignmentI - reference alignment for - * input } - */ - public Object[] recoverInputData(Provenance tp) - { - AlignViewport javport = null; - jalview.datamodel.AlignmentI jal = null; - jalview.datamodel.CigarArray view = null; - for (int pe = 0; pe < tp.getEntryCount(); pe++) - { - if (tp.getEntry(pe).getInputCount() > 0) - { - if (tp.getEntry(pe).getInputCount() > 1) - { - Cache.log - .warn("Ignoring additional input spec in provenance entry " - + tp.getEntry(pe).toString()); - } - // LATER: deal sensibly with multiple inputs - Input vInput = tp.getEntry(pe).getInput(0); - // is this the whole alignment or a specific set of sequences ? - if (vInput.getObjRefCount() == 0) - { - if (tree.getV_parent()!=null && tree.getV_parent() instanceof uk.ac.vamsas.objects.core.Alignment) - { - javport = getViewport(tree.getV_parent()); - jal = javport.getAlignment(); - view = javport.getAlignment().getCompactAlignment(); - } - } - else - { - // Explicit reference - to alignment, sequences or what. - if (vInput.getObjRefCount() == 1 - && vInput.getObjRef(0) instanceof uk.ac.vamsas.objects.core.Alignment) - { - // recover an AlignmentView for the input data - javport = getViewport((Vobject) vInput.getObjRef(0)); - jal = javport.getAlignment(); - view = javport.getAlignment().getCompactAlignment(); - } - else if (vInput.getObjRef(0) instanceof uk.ac.vamsas.objects.core.AlignmentSequence) - { - // recover an AlignmentView for the input data - javport = getViewport(((Vobject) vInput.getObjRef(0)).getV_parent()); - jal = javport.getAlignment(); - jalview.datamodel.SequenceI[] seqs = new jalview.datamodel.SequenceI[vInput - .getObjRefCount()]; - for (int i = 0, iSize = vInput.getObjRefCount(); i < iSize; i++) - { - SequenceI seq = (SequenceI) getvObj2jv((Vobject) vInput - .getObjRef(i)); - seqs[i] = seq; - } - view = new jalview.datamodel.Alignment(seqs) - .getCompactAlignment(); - - } - } - int from = 1, to = jal.getWidth(); - int offset = 0; // deleteRange modifies its frame of reference - for (int r = 0, s = vInput.getSegCount(); r < s; r++) - { - Seg visSeg = vInput.getSeg(r); - int se[] = getSegRange(visSeg, true); // jalview doesn't do - // bidirection alignments yet. - if (to < se[1]) - { - Cache.log.warn("Ignoring invalid segment in InputData spec."); - } - else - { - if (se[0] > from) - { - view.deleteRange(offset + from - 1, offset + se[0] - 2); - offset -= se[0] - from; - } - from = se[1] + 1; - } - } - if (from < to) - { - view.deleteRange(offset + from - 1, offset + to - 1); // final - // deletion - - // TODO: check - // off by - // one for to - } - return new Object[] - { new AlignmentView(view), jal }; - } - } - Cache.log - .debug("Returning null for input data recovery from provenance."); - return null; - } - - private AlignViewport getViewport(Vobject v_parent) - { - if (v_parent instanceof uk.ac.vamsas.objects.core.Alignment) - { - return datastore - .findViewport((uk.ac.vamsas.objects.core.Alignment) v_parent); - } - return null; - } - - public NewickFile getNewickTree() - { - return ntree; - } - - public String getTitle() - { - return title; - } - - public AlignmentView getInputData() - { - return inputData; - } - - public boolean isValidTree() - { - try - { - ntree.parse(); - if (ntree.getTree() != null) - { - ntree = getNtree(); - } - return true; - } catch (Exception e) - { - Cache.log.debug("Failed to parse newick tree string", e); - } - return false; - } -} +package jalview.io.vamsas; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +import jalview.analysis.NJTree; +import jalview.analysis.SequenceIdMatcher; +import jalview.bin.Cache; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.AlignmentView; +import jalview.datamodel.BinaryNode; +import jalview.datamodel.SeqCigar; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; +import jalview.datamodel.SequenceNode; +import jalview.gui.AlignFrame; +import jalview.gui.AlignViewport; +import jalview.gui.TreePanel; +import jalview.io.NewickFile; +import jalview.io.VamsasAppDatastore; +import uk.ac.vamsas.client.Vobject; +import uk.ac.vamsas.objects.core.AlignmentSequence; +import uk.ac.vamsas.objects.core.Entry; +import uk.ac.vamsas.objects.core.Input; +import uk.ac.vamsas.objects.core.Newick; +import uk.ac.vamsas.objects.core.Param; +import uk.ac.vamsas.objects.core.Provenance; +import uk.ac.vamsas.objects.core.Seg; +import uk.ac.vamsas.objects.core.Treenode; +import uk.ac.vamsas.objects.core.Vref; + +public class Tree extends DatastoreItem +{ + AlignmentI jal; + + TreePanel tp; + + uk.ac.vamsas.objects.core.Tree tree; + + uk.ac.vamsas.objects.core.Alignment alignment; // may be null => dataset or + + // other kind of tree + private NewickFile ntree; + + private String title; + + private AlignmentView inputData = null; + + public static void updateFrom(VamsasAppDatastore datastore, + jalview.gui.AlignFrame alignFrame, + uk.ac.vamsas.objects.core.Tree vtree) + { + Tree toTree = new Tree(datastore, alignFrame, vtree); + + } + + public Tree(VamsasAppDatastore datastore, + jalview.gui.AlignFrame alignFrame, + uk.ac.vamsas.objects.core.Tree vtree) + { + super(datastore); + tree = vtree; + TreePanel tp = (TreePanel) getvObj2jv(tree); + if (tp != null) + { + if (tree.isUpdated()) + { + Cache.log + .info("Update from vamsas document to alignment associated tree not implemented yet."); + } + } + else + { + // make a new tree + Object[] idata = recoverInputData(tree.getProvenance()); + try + { + if (idata != null && idata[0] != null) + { + inputData = (AlignmentView) idata[0]; + } + ntree = getNtree(); + title = tree.getNewick(0).getTitle(); + if (title == null || title.length() == 0) + { + title = tree.getTitle(); // hack!!!! + } + } catch (Exception e) + { + Cache.log.warn("Problems parsing treefile '" + + tree.getNewick(0).getContent() + "'", e); + } + } + } + + private NewickFile getNtree() throws IOException + { + return new jalview.io.NewickFile(tree.getNewick(0).getContent()); + } + + public Tree(VamsasAppDatastore datastore, TreePanel tp2, AlignmentI jal2, + uk.ac.vamsas.objects.core.Alignment alignment2) + { + super(datastore); + + jal = jal2; + tp = tp2; + alignment = alignment2; + + tree = (uk.ac.vamsas.objects.core.Tree) getjv2vObj(tp); + if (tree == null) + { + add(); + } + else + { + if (isModifiable(tree.getModifiable())) + { + // synchronize(); // update(); + // verify any changes. + System.out.println("Update tree in document."); + } + else + { + // handle conflict + System.out.println("Add modified tree as new tree in document."); + } + } + } + + /** + * correctly creates provenance for trees calculated on an alignment by + * jalview. + * + * @param jal + * @param tp + * @return + */ + private Provenance makeTreeProvenance(AlignmentI jal, TreePanel tp) + { + Cache.log.debug("Making Tree provenance for " + tp.getTitle()); + Provenance prov = new Provenance(); + prov.addEntry(new Entry()); + prov.getEntry(0).setAction("imported " + tp.getTitle()); + prov.getEntry(0).setUser(provEntry.getUser()); + prov.getEntry(0).setApp(provEntry.getApp()); + prov.getEntry(0).setDate(provEntry.getDate()); + if (tp.getTree().hasOriginalSequenceData()) + { + Input vInput = new Input(); + // LATER: check to see if tree input data is contained in this alignment - + // or just correctly resolve the tree's seqData to the correct alignment + // in + // the document. + Vector alsqrefs = getjv2vObjs(findAlignmentSequences(jal, tp + .getTree().seqData.getSequences())); + Object[] alsqs = new Object[alsqrefs.size()]; + alsqrefs.copyInto(alsqs); + vInput.setObjRef(alsqs); + // now create main provenance data + prov.getEntry(0).setAction("created " + tp.getTitle()); + prov.getEntry(0).addInput(vInput); + // jalview's special input parameter for distance matrix calculations + vInput.setName("jalview:seqdist"); // TODO: settle on appropriate name. + prov.getEntry(0).addParam(new Param()); + prov.getEntry(0).getParam(0).setName("treeType"); + prov.getEntry(0).getParam(0).setType("utf8"); + prov.getEntry(0).getParam(0).setContent("NJ"); // TODO: type of tree is a + // general parameter + int ranges[] = tp.getTree().seqData.getVisibleContigs(); + // VisibleContigs are with respect to alignment coordinates. Still need + // offsets + int start = tp.getTree().seqData.getAlignmentOrigin(); + for (int r = 0; r < ranges.length; r += 2) + { + Seg visSeg = new Seg(); + visSeg.setStart(1 + start + ranges[r]); + visSeg.setEnd(start + ranges[r + 1]); + visSeg.setInclusive(true); + vInput.addSeg(visSeg); + } + } + Cache.log.debug("Finished Tree provenance for " + tp.getTitle()); + return prov; + } + + /** + * look up SeqCigars in an existing alignment. + * + * @param jal + * @param sequences + * @return vector of alignment sequences in order of SeqCigar array (but + * missing unfound seqcigars) + */ + private Vector findAlignmentSequences(AlignmentI jal, SeqCigar[] sequences) + { + SeqCigar[] tseqs = new SeqCigar[sequences.length]; + System.arraycopy(sequences, 0, tseqs, 0, sequences.length); + Vector alsq = new Vector(); + Enumeration as = jal.getSequences().elements(); + while (as.hasMoreElements()) + { + SequenceI asq = (SequenceI) as.nextElement(); + for (int t = 0; t < sequences.length; t++) + { + if (tseqs[t] != null + && (tseqs[t].getRefSeq() == asq || tseqs[t].getRefSeq() == asq + .getDatasetSequence())) + // && tseqs[t].getStart()>=asq.getStart() && + // tseqs[t].getEnd()<=asq.getEnd()) + { + tseqs[t] = null; + alsq.add(asq); + } + } + } + if (alsq.size() < sequences.length) + Cache.log + .warn("Not recovered all alignment sequences for given set of input sequence CIGARS"); + return alsq; + } + + /** + * + * Update jalview newick representation with TreeNode map + * + * @param tp + * the treepanel that this tree is bound to. + */ + public void UpdateSequenceTreeMap(TreePanel tp) + { + if (tp == null || tree != null) + return; + Vector leaves = new Vector(); + tp.getTree().findLeaves(tp.getTree().getTopNode(), leaves); + Treenode[] tn = tree.getTreenode(); // todo: select nodes for this + // particular tree + int sz = tn.length; + int i = 0; + + while (i < sz) + { + Treenode node = tn[i++]; + BinaryNode mappednode = findNodeSpec(node.getNodespec(), leaves); + if (mappednode != null && mappednode instanceof SequenceNode) + { + SequenceNode leaf = (SequenceNode) leaves.elementAt(i++); + // check if we can make the specified association + Object jvseq = null; + int vrf = 0, refv = 0; + while (jvseq == null && vrf < node.getVrefCount()) + { + if (refv < node.getVref(vrf).getRefsCount()) + { + Object noderef = node.getVref(vrf).getRefs(refv++); + if (noderef instanceof AlignmentSequence) + { + // we only make these kind of associations + jvseq = getvObj2jv((Vobject) noderef); + } + } + else + { + refv = 0; + vrf++; + } + } + if (jvseq instanceof SequenceI) + { + leaf.setElement(jvseq); + leaf.setPlaceholder(false); + } + else + { + leaf.setPlaceholder(true); + leaf + .setElement(new Sequence(leaf.getName(), + "THISISAPLACEHLDER")); + } + } + } + } + + // / TODO: refactor to vamsas :start + /** + * construct treenode mappings for mapped sequences + * + * @param ntree + * @param newick + * @return + */ + public Treenode[] makeTreeNodes(NJTree ntree, Newick newick) + { + Vector leaves = new Vector(); + ntree.findLeaves(ntree.getTopNode(), leaves); + Vector tnv = new Vector(); + Enumeration l = leaves.elements(); + Hashtable nodespecs = new Hashtable(); + while (l.hasMoreElements()) + { + jalview.datamodel.BinaryNode tnode = (jalview.datamodel.BinaryNode) l + .nextElement(); + if (tnode instanceof jalview.datamodel.SequenceNode) + { + if (!((jalview.datamodel.SequenceNode) tnode).isPlaceholder()) + { + Object assocseq = ((jalview.datamodel.SequenceNode) tnode) + .element(); + if (assocseq instanceof SequenceI) + { + Vobject vobj = this.getjv2vObj(assocseq); + if (vobj != null) + { + Treenode node = new Treenode(); + if (newick.isRegisterable()) + { + this.cdoc.registerObject(newick); + node.addTreeId(newick); + } + node.setNodespec(makeNodeSpec(nodespecs, tnode)); + node.setName(tnode.getName()); + Vref vr = new Vref(); + vr.addRefs(vobj); + node.addVref(vr); + tnv.addElement(node); + } + else + { + System.err.println("WARNING: Unassociated treeNode " + + tnode.element().toString() + + " " + + ((tnode.getName() != null) ? " label " + + tnode.getName() : "")); + } + } + } + } + } + if (tnv.size() > 0) + { + Treenode[] tn = new Treenode[tnv.size()]; + tnv.copyInto(tn); + return tn; + } + return new Treenode[] + {}; + } + + private String makeNodeSpec(Hashtable nodespecs, + jalview.datamodel.BinaryNode tnode) + { + String nname = new String(tnode.getName()); + Integer nindx = (Integer) nodespecs.get(nname); + if (nindx == null) + { + nindx = new Integer(1); + } + nname = nindx.toString() + " " + nname; + return nname; + } + + /** + * call to match up Treenode specs to NJTree parsed from document object. + * + * @param nodespec + * @param leaves + * as returned from NJTree.findLeaves( .., ..) .. + * @return + */ + private jalview.datamodel.BinaryNode findNodeSpec(String nodespec, + Vector leaves) + { + int occurence = -1; + String nspec = nodespec.substring(nodespec.indexOf(' ') + 1); + String oval = nodespec.substring(0, nodespec.indexOf(' ')); + try + { + occurence = new Integer(oval).intValue(); + } catch (Exception e) + { + System.err.println("Invalid nodespec '" + nodespec + "'"); + return null; + } + jalview.datamodel.BinaryNode bn = null; + + int nocc = 0; + Enumeration en = leaves.elements(); + while (en.hasMoreElements() && nocc < occurence) + { + bn = (jalview.datamodel.BinaryNode) en.nextElement(); + if (bn instanceof jalview.datamodel.SequenceNode + && bn.getName().equals(nspec)) + { + --occurence; + } + else + bn = null; + } + return bn; + } + + // todo: end refactor to vamsas library + /** + * add jalview object to vamsas document + * + */ + public void add() + { + tree = new uk.ac.vamsas.objects.core.Tree(); + bindjvvobj(tp, tree); + tree.setTitle(tp.getTitle()); + Newick newick = new Newick(); + newick.setContent(tp.getTree().toString()); + newick.setTitle(tp.getTitle()); + tree.addNewick(newick); + tree.setProvenance(makeTreeProvenance(jal, tp)); + tree.setTreenode(makeTreeNodes(tp.getTree(), newick)); + + alignment.addTree(tree); + } + + /** + * note: this function assumes that all sequence and alignment objects + * referenced in input data has already been associated with jalview objects. + * + * @param tp + * @param alignFrame + * @return Object[] { AlignmentView, AlignmentI - reference alignment for + * input } + */ + public Object[] recoverInputData(Provenance tp) + { + AlignViewport javport = null; + jalview.datamodel.AlignmentI jal = null; + jalview.datamodel.CigarArray view = null; + for (int pe = 0; pe < tp.getEntryCount(); pe++) + { + if (tp.getEntry(pe).getInputCount() > 0) + { + if (tp.getEntry(pe).getInputCount() > 1) + { + Cache.log + .warn("Ignoring additional input spec in provenance entry " + + tp.getEntry(pe).toString()); + } + // LATER: deal sensibly with multiple inputs + Input vInput = tp.getEntry(pe).getInput(0); + // is this the whole alignment or a specific set of sequences ? + if (vInput.getObjRefCount() == 0) + { + if (tree.getV_parent()!=null && tree.getV_parent() instanceof uk.ac.vamsas.objects.core.Alignment) + { + javport = getViewport(tree.getV_parent()); + jal = javport.getAlignment(); + view = javport.getAlignment().getCompactAlignment(); + } + } + else + { + // Explicit reference - to alignment, sequences or what. + if (vInput.getObjRefCount() == 1 + && vInput.getObjRef(0) instanceof uk.ac.vamsas.objects.core.Alignment) + { + // recover an AlignmentView for the input data + javport = getViewport((Vobject) vInput.getObjRef(0)); + jal = javport.getAlignment(); + view = javport.getAlignment().getCompactAlignment(); + } + else if (vInput.getObjRef(0) instanceof uk.ac.vamsas.objects.core.AlignmentSequence) + { + // recover an AlignmentView for the input data + javport = getViewport(((Vobject) vInput.getObjRef(0)).getV_parent()); + jal = javport.getAlignment(); + jalview.datamodel.SequenceI[] seqs = new jalview.datamodel.SequenceI[vInput + .getObjRefCount()]; + for (int i = 0, iSize = vInput.getObjRefCount(); i < iSize; i++) + { + SequenceI seq = (SequenceI) getvObj2jv((Vobject) vInput + .getObjRef(i)); + seqs[i] = seq; + } + view = new jalview.datamodel.Alignment(seqs) + .getCompactAlignment(); + + } + } + int from = 1, to = jal.getWidth(); + int offset = 0; // deleteRange modifies its frame of reference + for (int r = 0, s = vInput.getSegCount(); r < s; r++) + { + Seg visSeg = vInput.getSeg(r); + int se[] = getSegRange(visSeg, true); // jalview doesn't do + // bidirection alignments yet. + if (to < se[1]) + { + Cache.log.warn("Ignoring invalid segment in InputData spec."); + } + else + { + if (se[0] > from) + { + view.deleteRange(offset + from - 1, offset + se[0] - 2); + offset -= se[0] - from; + } + from = se[1] + 1; + } + } + if (from < to) + { + view.deleteRange(offset + from - 1, offset + to - 1); // final + // deletion - + // TODO: check + // off by + // one for to + } + return new Object[] + { new AlignmentView(view), jal }; + } + } + Cache.log + .debug("Returning null for input data recovery from provenance."); + return null; + } + + private AlignViewport getViewport(Vobject v_parent) + { + if (v_parent instanceof uk.ac.vamsas.objects.core.Alignment) + { + return datastore + .findViewport((uk.ac.vamsas.objects.core.Alignment) v_parent); + } + return null; + } + + public NewickFile getNewickTree() + { + return ntree; + } + + public String getTitle() + { + return title; + } + + public AlignmentView getInputData() + { + return inputData; + } + + public boolean isValidTree() + { + try + { + ntree.parse(); + if (ntree.getTree() != null) + { + ntree = getNtree(); + } + return true; + } catch (Exception e) + { + Cache.log.debug("Failed to parse newick tree string", e); + } + return false; + } +} -- 1.7.10.2