List<SequenceI> rseqs;
/**
- * mappings constructed
- */
- AlignedCodonFrame cf;
-
- /**
* Constructor
*
* @param seqs
*
* @param seq
* the sequence whose dbrefs we are searching against
+ * @param fromDna
+ * when true, context is DNA - so sources identifying protein
+ * products will be returned.
* @param sources
* a list of sources to add matches to
*/
* 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());
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);
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;
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
- * - search all references or only subset
+ * - indicates the type of relationship between returned sequences,
+ * xrf, and sequenceI that is required.
+ * <ul>
+ * <li>direct implies xrf is a primary reference for sequenceI AND
+ * the sequences to be located (eg a uniprot ID for a protein
+ * sequence, and a uniprot ref on a transcript sequence).</li>
+ * <li>indirect means xrf is a cross reference with respect to
+ * sequenceI or all the returned sequences (eg a genomic reference
+ * associated with a locus and one or more transcripts)</li>
+ * </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
}
}
}