+ MapList mapList = aMapping.getMap();
+ if (mapList.getFromRatio() == 1)
+ {
+ /*
+ * not a dna-to-protein mapping (likely dna-to-cds)
+ */
+ continue;
+ }
+
+ /*
+ * skip if mapping is not to one of the target set of proteins
+ */
+ SequenceI proteinProduct = aMapping.getTo();
+ if (productSeqs != null && !productSeqs.contains(proteinProduct))
+ {
+ continue;
+ }
+
+ /*
+ * try to locate the CDS from the dataset mappings;
+ * guard against duplicate results (for the case that protein has
+ * dbrefs to both dna and cds sequences)
+ */
+ SequenceI cdsSeq = findCdsForProtein(mappings, dnaSeq,
+ seqMappings, aMapping);
+ if (cdsSeq != null)
+ {
+ if (!foundSeqs.contains(cdsSeq))
+ {
+ foundSeqs.add(cdsSeq);
+ SequenceI derivedSequence = cdsSeq.deriveSequence();
+ cdsSeqs.add(derivedSequence);
+ if (!dataset.getSequences().contains(cdsSeq))
+ {
+ dataset.addSequence(cdsSeq);
+ }
+ }
+ continue;
+ }
+
+ /*
+ * didn't find mapped CDS sequence - construct it and add
+ * its dataset sequence to the dataset
+ */
+ cdsSeq = makeCdsSequence(dnaSeq.getDatasetSequence(), aMapping,
+ dataset).deriveSequence();
+ // cdsSeq has a name constructed as CDS|<dbref>
+ // <dbref> will be either the accession for the coding sequence,
+ // marked in the /via/ dbref to the protein product accession
+ // or it will be the original nucleotide accession.
+ SequenceI cdsSeqDss = cdsSeq.getDatasetSequence();
+
+ cdsSeqs.add(cdsSeq);
+
+ if (!dataset.getSequences().contains(cdsSeqDss))
+ {
+ // check if this sequence is a newly created one
+ // so needs adding to the dataset
+ dataset.addSequence(cdsSeqDss);
+ }
+
+ /*
+ * add a mapping from CDS to the (unchanged) mapped to range
+ */
+ List<int[]> cdsRange = Collections.singletonList(new int[] { 1,
+ cdsSeq.getLength() });
+ MapList cdsToProteinMap = new MapList(cdsRange,
+ mapList.getToRanges(), mapList.getFromRatio(),
+ mapList.getToRatio());
+ AlignedCodonFrame cdsToProteinMapping = new AlignedCodonFrame();
+ cdsToProteinMapping.addMap(cdsSeqDss, proteinProduct,
+ cdsToProteinMap);
+
+ /*
+ * guard against duplicating the mapping if repeating this action
+ */
+ if (!mappings.contains(cdsToProteinMapping))
+ {
+ mappings.add(cdsToProteinMapping);
+ }
+
+ propagateDBRefsToCDS(cdsSeqDss, dnaSeq.getDatasetSequence(),
+ proteinProduct, aMapping);
+ /*
+ * add another mapping from original 'from' range to CDS
+ */
+ AlignedCodonFrame dnaToCdsMapping = new AlignedCodonFrame();
+ final MapList dnaToCdsMap = new MapList(mapList.getFromRanges(),
+ cdsRange, 1, 1);
+ dnaToCdsMapping.addMap(dnaSeq.getDatasetSequence(), cdsSeqDss,
+ dnaToCdsMap);
+ if (!mappings.contains(dnaToCdsMapping))
+ {
+ mappings.add(dnaToCdsMapping);
+ }
+
+ /*
+ * transfer dna chromosomal loci (if known) to the CDS
+ * sequence (via the mapping)
+ */
+ final MapList cdsToDnaMap = dnaToCdsMap.getInverse();
+ transferGeneLoci(dnaSeq, cdsToDnaMap, cdsSeq);
+
+ /*
+ * add DBRef with mapping from protein to CDS
+ * (this enables Get Cross-References from protein alignment)
+ * This is tricky because we can't have two DBRefs with the
+ * same source and accession, so need a different accession for
+ * the CDS from the dna sequence
+ */
+
+ // specific use case:
+ // Genomic contig ENSCHR:1, contains coding regions for ENSG01,
+ // ENSG02, ENSG03, with transcripts and products similarly named.
+ // cannot add distinct dbrefs mapping location on ENSCHR:1 to ENSG01
+
+ // JBPNote: ?? can't actually create an example that demonstrates we
+ // need to
+ // synthesize an xref.
+
+ for (DBRefEntry primRef : dnaDss.getPrimaryDBRefs())
+ {
+ /*
+ * create a cross-reference from CDS to the source sequence's
+ * primary reference and vice versa
+ */
+ String source = primRef.getSource();
+ String version = primRef.getVersion();
+ DBRefEntry cdsCrossRef = new DBRefEntry(source, source + ":"
+ + version, primRef.getAccessionId());
+ cdsCrossRef.setMap(new Mapping(dnaDss, new MapList(cdsToDnaMap)));
+ cdsSeqDss.addDBRef(cdsCrossRef);
+
+ dnaSeq.addDBRef(new DBRefEntry(source, version, cdsSeq
+ .getName(), new Mapping(cdsSeqDss, dnaToCdsMap)));
+
+ // problem here is that the cross-reference is synthesized -
+ // cdsSeq.getName() may be like 'CDS|dnaaccession' or
+ // 'CDS|emblcdsacc'
+ // assuming cds version same as dna ?!?
+
+ DBRefEntry proteinToCdsRef = new DBRefEntry(source, version,
+ cdsSeq.getName());
+ //
+ proteinToCdsRef.setMap(new Mapping(cdsSeqDss, cdsToProteinMap
+ .getInverse()));
+ proteinProduct.addDBRef(proteinToCdsRef);
+ }
+
+ /*
+ * transfer any features on dna that overlap the CDS
+ */
+ transferFeatures(dnaSeq, cdsSeq, dnaToCdsMap, null,
+ SequenceOntologyI.CDS);