List<SequenceI> rseqs;
/**
- * mappings constructed
- */
- AlignedCodonFrame cf;
-
- /**
* Constructor
*
* @param seqs
* find sequence's direct (dna-to-dna, peptide-to-peptide) xrefs
*/
DBRefEntry[] lrfs = DBRefUtils.selectDbRefs(fromDna, seq.getDBRefs());
- List<SequenceI> rseqs = new ArrayList<SequenceI>();
+ List<SequenceI> foundSeqs = new ArrayList<SequenceI>();
/*
* find sequences in the alignment which xref one of these DBRefs
* i.e. is xref-ed to a common sequence identifier
*/
- searchDatasetXrefs(fromDna, seq, lrfs, rseqs, null);
+ searchDatasetXrefs(fromDna, seq, lrfs, foundSeqs, null);
/*
* add those sequences' (dna-to-peptide or peptide-to-dna) dbref sources
*/
- for (SequenceI rs : rseqs)
+ for (SequenceI rs : foundSeqs)
{
DBRefEntry[] xrs = DBRefUtils
.selectDbRefs(!fromDna, rs.getDBRefs());
{
rseqs = new ArrayList<SequenceI>();
- cf = new AlignedCodonFrame();
+ AlignedCodonFrame cf = new AlignedCodonFrame();
matcher = new SequenceIdMatcher(
dataset.getSequences());
* but findInDataset() matches ENSP when looking for Uniprot...
*/
SequenceI matchInDataset = findInDataset(xref);
+ if (matchInDataset != null && xref.getMap().getTo() != null
+ && matchInDataset != xref.getMap().getTo())
+ {
+ System.err
+ .println("Implementation problem (reopen JAL-2154): CrossRef.findInDataset seems to have recovered a different sequence than the one explicitly mapped for xref."
+ + "Found:"
+ + matchInDataset
+ + "\nExpected:"
+ + xref.getMap().getTo()
+ + "\nFor xref:"
+ + xref);
+ }
/*matcher.findIdMatch(mappedTo);*/
if (matchInDataset != null)
{
if (!rseqs.contains(matchInDataset))
{
rseqs.add(matchInDataset);
+ // need to try harder to only add unique mappings
+ if (xref.getMap().getMap().isTripletMap()
+ && dataset.getMapping(seq, matchInDataset) == null
+ && cf.getMappingBetween(seq, matchInDataset) == null)
+ {
+ // materialise a mapping for highlighting between these sequences
+ if (fromDna)
+ {
+ cf.addMap(dss, matchInDataset, xref.getMap().getMap(), xref.getMap().getMappedFromId());
+ } else {
+ cf.addMap(matchInDataset, dss, xref.getMap().getMap().getInverse(), xref.getMap().getMappedFromId());
+ }
+ }
}
refIterator.remove();
continue;
}
+ // TODO: need to determine if this should be a deriveSequence
SequenceI rsq = new Sequence(mappedTo);
rseqs.add(rsq);
- if (xref.getMap().getMap().getFromRatio() != xref.getMap()
- .getMap().getToRatio())
+ if (xref.getMap().getMap().isTripletMap())
{
// get sense of map correct for adding to product alignment.
if (fromDna)
{
// map is from dna seq to a protein product
- cf.addMap(dss, rsq, xref.getMap().getMap());
+ cf.addMap(dss, rsq, xref.getMap().getMap(), xref.getMap()
+ .getMappedFromId());
}
else
{
// map should be from protein seq to its coding dna
- cf.addMap(rsq, dss, xref.getMap().getMap().getInverse());
+ cf.addMap(rsq, dss, xref.getMap().getMap().getInverse(),
+ xref.getMap().getMappedFromId());
}
}
}
*/
if (!sourceRefs.isEmpty())
{
- retrieveCrossRef(sourceRefs, seq, xrfs, fromDna);
+ retrieveCrossRef(sourceRefs, seq, xrfs, fromDna, cf);
}
}
}
private void retrieveCrossRef(List<DBRefEntry> sourceRefs, SequenceI seq,
- DBRefEntry[] xrfs, boolean fromDna)
+ DBRefEntry[] xrfs, boolean fromDna, AlignedCodonFrame cf)
{
ASequenceFetcher sftch = SequenceFetcherFactory.getSequenceFetcher();
SequenceI[] retrieved = null;
- SequenceI dss = null;
+ SequenceI dss = seq.getDatasetSequence() == null ? seq : seq
+ .getDatasetSequence();
try
{
retrieved = sftch.getSequences(sourceRefs, !fromDna);
}
else
{
+ dataset.addSequence(map.getTo());
matcher.add(map.getTo());
}
try
void updateDbrefMappings(SequenceI mapFrom, DBRefEntry[] xrefs,
SequenceI[] retrieved, AlignedCodonFrame acf, boolean fromDna)
{
- SequenceIdMatcher matcher = new SequenceIdMatcher(retrieved);
+ SequenceIdMatcher idMatcher = new SequenceIdMatcher(retrieved);
for (DBRefEntry xref : xrefs)
{
if (!xref.hasMap())
{
String targetSeqName = xref.getSource() + "|"
+ xref.getAccessionId();
- SequenceI[] matches = matcher.findAllIdMatches(targetSeqName);
+ SequenceI[] matches = idMatcher.findAllIdMatches(targetSeqName);
if (matches == null)
{
return;
DBRefEntry xref, AlignedCodonFrame mappings, boolean fromDna)
{
MapList mapping = null;
-
+ SequenceI dsmapFrom = mapFrom.getDatasetSequence() == null ? mapFrom
+ : mapFrom.getDatasetSequence();
+ SequenceI dsmapTo = mapFrom.getDatasetSequence() == null ? mapTo
+ : mapTo.getDatasetSequence();
/*
- * look for a reverse mapping, if found make its inverse
+ * look for a reverse mapping, if found make its inverse.
+ * Note - we do this on dataset sequences only.
*/
- if (mapTo.getDBRefs() != null)
+ if (dsmapTo.getDBRefs() != null)
{
- for (DBRefEntry dbref : mapTo.getDBRefs())
+ for (DBRefEntry dbref : dsmapTo.getDBRefs())
{
String name = dbref.getSource() + "|" + dbref.getAccessionId();
- if (dbref.hasMap() && mapFrom.getName().startsWith(name))
+ if (dbref.hasMap() && dsmapFrom.getName().startsWith(name))
{
/*
* looks like we've found a map from 'mapTo' to 'mapFrom'
* - invert it to make the mapping the other way
*/
MapList reverse = dbref.getMap().getMap().getInverse();
- xref.setMap(new Mapping(mapTo, reverse));
- mappings.addMap(mapFrom, mapTo, reverse);
+ xref.setMap(new Mapping(dsmapTo, reverse));
+ mappings.addMap(mapFrom, dsmapTo, reverse);
return true;
}
}
return false;
}
xref.setMap(new Mapping(mapTo, mapping));
+
+ /*
+ * and add a reverse DbRef with the inverse mapping
+ */
+ if (mapFrom.getDatasetSequence() != null
+ && mapFrom.getDatasetSequence().getSourceDBRef() != null)
+ {
+ DBRefEntry dbref = new DBRefEntry(mapFrom.getDatasetSequence()
+ .getSourceDBRef());
+ dbref.setMap(new Mapping(mapFrom.getDatasetSequence(), mapping
+ .getInverse()));
+ mapTo.addDBRef(dbref);
+ }
+
if (fromDna)
{
AlignmentUtils.computeProteinFeatures(mapFrom, mapTo, mapping);
* context was searching from Protein sequences
* @param sequenceI
* @param lrfs
- * @param rseqs
+ * @param foundSeqs
* @return true if matches were found.
*/
private boolean searchDatasetXrefs(boolean fromDna, SequenceI sequenceI,
- DBRefEntry[] lrfs, List<SequenceI> rseqs, AlignedCodonFrame cf)
+ DBRefEntry[] lrfs, List<SequenceI> foundSeqs, AlignedCodonFrame cf)
{
boolean found = false;
if (lrfs == null)
// add in wildcards
xref.setVersion(null);
xref.setMap(null);
- found |= searchDataset(fromDna, sequenceI, xref, rseqs, cf, false);
+ found |= searchDataset(fromDna, sequenceI, xref, foundSeqs, cf, false);
}
return found;
}
* @param fromDna
* true if context was searching for refs *from* dna sequence, false
* if context was searching for refs *from* protein sequence
- * @param sequenceI
+ * @param fromSeq
* a sequence to ignore (start point of search)
* @param xrf
* a cross-reference to try to match
- * @param rseqs
+ * @param foundSeqs
* result list to add to
- * @param cf
+ * @param mappings
* a set of sequence mappings to add to
* @param direct
* - indicates the type of relationship between returned sequences,
* </ul>
* @return true if relationship found and sequence added.
*/
- boolean searchDataset(boolean fromDna, SequenceI sequenceI,
- DBRefEntry xrf, List<SequenceI> rseqs, AlignedCodonFrame cf,
+ boolean searchDataset(boolean fromDna, SequenceI fromSeq,
+ DBRefEntry xrf, List<SequenceI> foundSeqs, AlignedCodonFrame mappings,
boolean direct)
{
boolean found = false;
if (nxt.getDatasetSequence() != null)
{
System.err
- .println("Implementation warning: getProducts passed a dataset alignment without dataset sequences in it!");
+ .println("Implementation warning: CrossRef initialised with a dataset alignment with non-dataset sequences in it! ("
+ + nxt.getDisplayId(true)
+ + " has ds reference "
+ + nxt.getDatasetSequence().getDisplayId(true)
+ + ")");
}
- if (nxt == sequenceI || nxt == sequenceI.getDatasetSequence())
+ if (nxt == fromSeq || nxt == fromSeq.getDatasetSequence())
{
continue;
}
// look for direct or indirect references in common
DBRefEntry[] poss = nxt.getDBRefs();
List<DBRefEntry> cands = null;
- /*
- * TODO does this make any sense?
- * if 'direct', search the dbrefs for xrf
- * else, filter the dbrefs by type and then search for xrf
- * - the result is the same isn't it?
- */
- if (direct)
- {
- cands = DBRefUtils.searchRefs(poss, xrf);
- }
- else
- {
- poss = DBRefUtils.selectDbRefs(!fromDna, poss);
- cands = DBRefUtils.searchRefs(poss, xrf);
- }
+
+ // todo: indirect specifies we select either direct references to nxt
+ // that match xrf which is indirect to sequenceI, or indirect
+ // references to nxt that match xrf which is direct to sequenceI
+ cands = DBRefUtils.searchRefs(poss, xrf);
+ // else
+ // {
+ // poss = DBRefUtils.selectDbRefs(nxt.isProtein()!fromDna, poss);
+ // cands = DBRefUtils.searchRefs(poss, xrf);
+ // }
if (!cands.isEmpty())
{
- if (!rseqs.contains(nxt))
+ if (!foundSeqs.contains(nxt))
{
found = true;
- rseqs.add(nxt);
- if (cf != null)
+ foundSeqs.add(nxt);
+ if (mappings != null && !direct)
{
- // don't search if we aren't given a codon map object
+ /*
+ * if the matched sequence has mapped dbrefs to
+ * protein product / cdna, add equivalent mappings to
+ * our source sequence
+ */
for (DBRefEntry candidate : cands)
{
Mapping mapping = candidate.getMap();
if (mapping.getTo() != null
&& map.getFromRatio() != map.getToRatio())
{
- // get sense of map correct for adding to product
- // alignment.
- if (fromDna)
+ /*
+ * add a mapping, as from dna to peptide sequence
+ */
+ if (map.getFromRatio() == 3)
{
- // map is from dna seq to a protein product
- cf.addMap(sequenceI, nxt, map);
+ mappings.addMap(nxt, fromSeq, map);
}
else
{
- // map should be from protein seq to its coding dna
- cf.addMap(nxt, sequenceI, map.getInverse());
+ mappings.addMap(nxt, fromSeq, map.getInverse());
}
}
}
}
}
- // TODO: add mapping between sequences if necessary
}
}
}