746a7d0a8ede4d228fc5b5de302dfae4f3b7b943
[jalview.git] / src / jalview / io / vamsas / Sequencemapping.java
1 package jalview.io.vamsas;
2
3 import java.util.Vector;
4
5 import jalview.datamodel.AlignedCodonFrame;
6 import jalview.datamodel.Mapping;
7 import jalview.datamodel.SequenceI;
8 import jalview.io.VamsasAppDatastore;
9 import uk.ac.vamsas.client.Vobject;
10 import uk.ac.vamsas.objects.core.AlignmentSequence;
11 import uk.ac.vamsas.objects.core.DataSet;
12 import uk.ac.vamsas.objects.core.Local;
13 import uk.ac.vamsas.objects.core.RangeType;
14 import uk.ac.vamsas.objects.core.Seg;
15 import uk.ac.vamsas.objects.core.Sequence;
16 import uk.ac.vamsas.objects.core.SequenceMapping;
17 import uk.ac.vamsas.objects.core.SequenceType;
18
19 public class Sequencemapping extends Rangetype
20 {
21   public Sequencemapping(VamsasAppDatastore datastore, SequenceMapping sequenceMapping)
22   {
23     super(datastore);
24     Object mjvmapping = getvObj2jv(sequenceMapping);
25     if (mjvmapping==null)
26     {
27       add(sequenceMapping);
28     } else {
29       if (sequenceMapping.isUpdated())
30       {
31         update((jalview.util.MapList) mjvmapping, sequenceMapping);
32       }
33     }
34   }
35   /**
36    * create or update a vamsas sequence mapping corresponding to a jalview
37    * Mapping between two dataset sequences
38    * 
39    * @param datastore
40    * @param mjvmapping
41    * @param from
42    * @param ds
43    */
44   public Sequencemapping(VamsasAppDatastore datastore, jalview.datamodel.Mapping mjvmapping, uk.ac.vamsas.objects.core.SequenceType from, uk.ac.vamsas.objects.core.DataSet ds)
45   {
46     super(datastore);
47     SequenceMapping sequenceMapping = (SequenceMapping) getjv2vObj(mjvmapping);
48     if (sequenceMapping==null)
49     {
50       add(mjvmapping, from, ds);
51     } else {
52       if (from!=null && sequenceMapping.getLoc()!=from)
53       {
54         jalview.bin.Cache.log.warn("Probable IMPLEMENTATION ERROR: "+from+" doesn't match the local mapping sequence.");
55       }
56       if (ds!=null && sequenceMapping.is__stored_in_document() && sequenceMapping.getV_parent()!=ds)
57       {
58         jalview.bin.Cache.log.warn("Probable IMPLEMENTATION ERROR: "+ds+" doesn't match the parent of the bound sequence mapping object.");
59       }
60       if (sequenceMapping.isUpdated())
61       { 
62         conflict(mjvmapping, sequenceMapping);
63       } else {
64         update(mjvmapping, sequenceMapping);
65       }
66     }
67   }
68   private void conflict(Mapping mjvmapping, SequenceMapping sequenceMapping)
69   {
70     // TODO Auto-generated method stub
71
72   }
73   private void add(Mapping mjvmapping, uk.ac.vamsas.objects.core.SequenceType from, DataSet ds)
74   {
75     SequenceI jvto = mjvmapping.getTo();
76     while (jvto.getDatasetSequence()!=null)
77     {
78       jvto = jvto.getDatasetSequence();
79     }
80     SequenceType to = (SequenceType) getjv2vObj(jvto);
81     if (to==null)
82     {
83       jalview.bin.Cache.log.warn("NONFATAL - do a second update: Ignoring Forward Reference to seuqence not yet bound to vamsas seuqence object");
84       return;
85     } 
86     SequenceMapping sequenceMapping = new SequenceMapping();
87     sequenceMapping.setLoc(from);
88     sequenceMapping.setMap(to);
89     boolean dnaToProt=false,sense=false;
90     // ensure that we create a mapping with the correct sense
91     if (((Sequence) sequenceMapping.getLoc())
92             .getDictionary()
93             .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))
94     {
95       if (((Sequence) sequenceMapping.getMap())
96               .getDictionary()
97               .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA))
98       {
99         dnaToProt=true;
100         sense=true;
101       } 
102     } else {
103       if (((Sequence) sequenceMapping.getMap())
104               .getDictionary()
105               .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))
106       {
107         dnaToProt=true;
108         sense=false;
109       } 
110     }
111
112     if (!dnaToProt)
113     {
114       jalview.bin.Cache.log.warn("Ignoring Mapping - don't support protein to protein mapping in vamsas document yet.");
115       return;
116     }
117     if (ds==null)
118     {
119       // locate dataset for storage of SequenceMapping
120       if (sense)
121       {
122         ds = (DataSet) ((uk.ac.vamsas.client.Vobject) sequenceMapping.getLoc()).getV_parent();
123       } else {
124         ds = (DataSet) ((uk.ac.vamsas.client.Vobject) sequenceMapping.getMap()).getV_parent();
125       } 
126     }
127     if (sense)
128     {
129       this.initMapType(sequenceMapping, mjvmapping.getMap(), true);
130     } else {
131       this.initMapType(sequenceMapping, mjvmapping.getMap().getInverse(), true);
132     }
133     ds.addSequenceMapping(sequenceMapping);
134     sequenceMapping.setProvenance(this.dummyProvenance("user defined coding region translation")); // TODO:
135     // correctly
136     // construct
137     // provenance
138     // based
139     // on
140     // source
141     // of
142     // mapping
143     bindjvvobj(mjvmapping, sequenceMapping);
144
145     jalview.bin.Cache.log.debug("Successfully created mapping "+sequenceMapping.getVorbaId());
146   }
147   private void update(jalview.util.MapList mjvmapping, SequenceMapping sequenceMapping)
148   {
149     jalview.bin.Cache.log.error("Not implemented: Jalview Update Alcodon Mapping:TODO!"); 
150   }
151   private void update(jalview.datamodel.Mapping mjvmapping, SequenceMapping sequenceMapping)
152   {
153     jalview.bin.Cache.log.error("Not implemented: Jalview Update Sequence DBRef Mapping"); 
154   }
155   /**
156    * limitations: Currently, jalview only deals with mappings between dataset
157    * sequences, and even then, only between those that map from DNA to Protein.
158    * 
159    * @param sequenceMapping
160    */
161   private void add(SequenceMapping sequenceMapping)
162   {
163     Object mobj;
164     SequenceI from=null,to=null;
165     boolean dnaToProt=false,sense=false;
166     Sequence sdloc=null, sdmap=null;
167     if (sequenceMapping.getLoc() instanceof AlignmentSequence)
168     {
169       sdloc = (Sequence) ((AlignmentSequence) sequenceMapping.getLoc()).getRefid();
170     } else {
171       sdloc = ((Sequence) sequenceMapping.getLoc());
172     }
173     if (sequenceMapping.getMap() instanceof AlignmentSequence)
174     {
175       sdmap = (Sequence) ((AlignmentSequence) sequenceMapping.getMap()).getRefid();
176     } else {
177       sdmap = ((Sequence) sequenceMapping.getMap());
178     }
179     if (sdloc==null || sdmap == null)
180     {
181       jalview.bin.Cache.log.info("Ignoring non sequence-sequence mapping");
182       return;
183     }
184     mobj = this.getvObj2jv((Vobject) sdloc);
185     if (mobj instanceof SequenceI)
186     {
187       from = (SequenceI) mobj;
188     }
189     mobj = this.getvObj2jv((Vobject) sdmap);
190     if (mobj instanceof SequenceI)
191     {
192       to = (SequenceI) mobj;
193     }
194     if (from == null || to == null)
195     {
196
197       jalview.bin.Cache.log.error("Probable Vamsas implementation error : unbound dataset sequences involved in a mapping are being parsed!");
198       return;
199     } 
200
201     if (sdloc.getDictionary()
202             .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))
203     {
204       if (sdmap.getDictionary()
205               .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA))
206       {
207         dnaToProt=true;
208         sense=true;
209       } 
210       // else {
211
212       // }
213     } else {
214       if (sdmap.getDictionary()
215               .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))
216       {
217         dnaToProt=true;
218         sense=false;
219       } 
220     }
221     // create mapping storage object and make each dataset alignment reference
222     // it.
223     jalview.datamodel.AlignmentI dsLoc = (jalview.datamodel.AlignmentI) getvObj2jv(sdloc.getV_parent());
224     jalview.datamodel.AlignmentI dsMap = (jalview.datamodel.AlignmentI) getvObj2jv(sdmap.getV_parent());
225     AlignedCodonFrame afc = new AlignedCodonFrame(0);
226
227     if (dsLoc!=null && dsLoc!=dsMap)
228     {
229       dsLoc.addCodonFrame(afc);
230     }
231     if (dsMap!=null)
232     {
233       dsMap.addCodonFrame(afc);
234     }
235     // create and add the new mapping to (each) dataset's codonFrame
236
237     jalview.util.MapList mapping = null; 
238     if (!sense)
239     {
240       mapping = this.parsemapType(sequenceMapping, 1, 3); // invert sense
241       mapping = new jalview.util.MapList(mapping.getToRanges(), mapping.getFromRanges(), mapping.getToRatio(), mapping.getFromRatio());
242       afc.addMap(to, from, mapping);
243     } else {
244       mapping = this.parsemapType(sequenceMapping, 3, 1); // correct sense
245       afc.addMap(from, to, mapping);
246     }
247     bindjvvobj(mapping, sequenceMapping);
248     jalview.structure.StructureSelectionManager.getStructureSelectionManager().addMappings(new AlignedCodonFrame[] { afc });
249     // Try to link up any conjugate database references in the two sequences
250     // matchConjugateDBRefs(from, to,  mapping);
251     // Try to propagate any dbrefs across this mapping.
252
253   }
254   /**
255    * Complete any 'to' references in jalview.datamodel.Mapping objects associated with conjugate DBRefEntry under given mapping  
256    * @param from sequence corresponding to from reference for sequence mapping
257    * @param to sequence correspondeing to to reference for sequence mapping
258    * @param smap maplist parsed in same sense as from and to
259    */
260   private void matchConjugateDBRefs(SequenceI from, SequenceI to,
261           jalview.util.MapList smap)
262   {
263     if (from.getDBRef()==null && to.getDBRef()==null)
264     {
265       if (jalview.bin.Cache.log.isDebugEnabled())
266       {
267         jalview.bin.Cache.log.debug("Not matching conjugate refs for "+from.getName()+" and "+to.getName());
268       }
269       return; 
270     }
271     if (jalview.bin.Cache.log.isDebugEnabled())
272     {
273       jalview.bin.Cache.log.debug("Matching conjugate refs for "+from.getName()+" and "+to.getName());
274     }
275     jalview.datamodel.DBRefEntry[] fdb = from.getDBRef();
276     jalview.datamodel.DBRefEntry[] tdb = new jalview.datamodel.DBRefEntry[to.getDBRef().length];
277     int tdblen = to.getDBRef().length;
278     System.arraycopy(to.getDBRef(), 0, tdb, 0, tdblen);
279     Vector matched = new Vector();
280     jalview.util.MapList smapI = smap.getInverse();
281     for (int f=0;f<fdb.length; f++)
282     {
283       jalview.datamodel.DBRefEntry fe = fdb[f];
284       jalview.datamodel.Mapping fmp = fe.getMap();
285       boolean fmpnnl = fmp!=null;
286       // if (fmpnnl && fmp.getTo()!=null)
287       //{
288       //  jalview.bin.Cache.log.debug("Not overwriting existing To reference in "+fe);
289       //  continue;
290       //}
291       // smap from maps from fe.local to fe.map
292       boolean smapfromlocal2fe = (fmpnnl) ? smap.equals(fmp.getMap()) : false;
293       // smap from maps from fe.map to fe.local.
294       boolean smapfromfemap2local = (fmpnnl) ? smapI.equals(fmp.getMap()) : false;
295       for (int t=0; t<tdblen; t++)
296       {
297         jalview.datamodel.DBRefEntry te = tdb[t];
298         if (te!=null)
299         {
300           if (fe.getSource().equals(te.getSource())
301               && fe.getAccessionId().equals(te.getAccessionId()))
302           {
303             jalview.datamodel.Mapping tmp = te.getMap();
304             boolean tmpnnl = tmp!=null;
305             if (tmpnnl && tmp.getTo()!=null)
306             {
307               
308             }
309             // smap to maps from te.local to te.map
310             boolean smaptolocal2tm = (tmpnnl) ? smap.equals(tmp.getMap()) : false;
311             // smap to maps from te.map to te.local
312             boolean smaptotemap2local = (tmpnnl) ? smapI.equals(fmp.getMap()) : false;
313             if (smapfromlocal2fe && smaptotemap2local)
314             {
315               // smap implies mapping from to to from
316               fmp.setTo(to);
317               tmp.setTo(from);
318             } else 
319               if (smapfromfemap2local && smaptolocal2tm) {
320                 fmp.setTo(to);
321               }
322             }
323             
324         }
325       }
326     }
327     }
328 }