private final Map<String, SingleReadAlignment> cdmMap = new TreeMap<String, SingleReadAlignment>(); //TODO Move this to ContigSequenceDataProvider
private boolean dirty = false;
- public AlignmentEditor()
- {
+
+ public AlignmentEditor() {
super();
conversationHolder = CdmStore.createConversation();
//conversationHolder = null;
result.setAllowVerticalScrolling(allowVerticalScrolling);
CharacterTokenSet tokenSet = CharacterTokenSet.newDNAInstance(); //TODO Should NUCLEOTIDE be used instead?
- AlignmentModel<Character> provider = new PackedAlignmentModel<Character>(tokenSet);
- result.setAlignmentModel(provider, false);
- provider.getChangeListeners().add(DIRTY_LISTENER);
+ AlignmentModel<Character> model = new PackedAlignmentModel<Character>(tokenSet);
+ result.setAlignmentModel(model, false);
+ model.getChangeListeners().add(DIRTY_LISTENER);
result.getPaintSettings().getTokenPainterList().set(0, new NucleotideTokenPainter());
return result;
for (SingleReadAlignment singleReadAlignment : sequenceNode.getSingleReadAlignments()) {
try {
SingleRead pherogramInfo = singleReadAlignment.getSingleRead();
- URI uri = null;
- if (pherogramInfo.getPherogram() != null) {
- uri = MediaUtils.getFirstMediaRepresentationPart(pherogramInfo.getPherogram()).getUri();
- }
String id = addRead(DerivateLabelProvider.getDerivateText(pherogramInfo, conversationHolder),
- uri,
+ getPherogramURI(pherogramInfo),
singleReadAlignment.isReverseComplement(),
singleReadAlignment.getEditedSequence(),
singleReadAlignment.getFirstSeqPosition(),
}
// Set consensus sequence:
- AlignmentModel consensusProvider = getEditableConsensusArea().getAlignmentModel();
- String id = consensusProvider.addSequence(CONSENSUS_NAME);
- consensusProvider.insertTokensAt(id, 0, AlignmentModelUtils.charSequenceToTokenList(
- sequenceNode.getConsensusSequence().getString(), consensusProvider.getTokenSet()));
+ AlignmentModel consensusModel = getEditableConsensusArea().getAlignmentModel();
+ String id = consensusModel.addSequence(CONSENSUS_NAME);
+ consensusModel.insertTokensAt(id, 0, AlignmentModelUtils.charSequenceToTokenList(
+ sequenceNode.getConsensusSequence().getString(), consensusModel.getTokenSet()));
//TODO Can the consensus sequence also be null? / Should it be created here, if nothing is in the DB?
}
Integer firstSeqPos, Integer leftCutPos, Integer rightCutPos, SingleReadAlignment.Shift[] shifts)
throws IOException, UnsupportedChromatogramFormatException {
- AlignmentModel provider = getReadsArea().getAlignmentModel();
+ AlignmentModel model = getReadsArea().getAlignmentModel();
PherogramProvider pherogramProvider = null;
if (pherogramURI != null) {
pherogramProvider = readPherogram(pherogramURI); // Must happen before a sequence is added, because it might throw an exception.
}
// Create sequence:
- provider.addSequence(name);
- String id = provider.sequenceIDByName(name);
+ model.addSequence(name);
+ String id = model.sequenceIDByName(name);
// Set edited sequence:
Collection<Object> tokens = null; // First save tokens in a collection to avoid GUI updated for each token.
if (editedSequence != null) {
- tokens = AlignmentModelUtils.charSequenceToTokenList(editedSequence, provider.getTokenSet());
+ tokens = AlignmentModelUtils.charSequenceToTokenList(editedSequence, model.getTokenSet());
}
else if (pherogramProvider != null) { // Copy base call sequence into alignment:
tokens = new ArrayList<Object>();
for (int i = 0; i < pherogramProvider.getSequenceLength(); i++) {
- tokens.add(provider.getTokenSet().tokenByRepresentation(
+ tokens.add(model.getTokenSet().tokenByRepresentation(
Character.toString(pherogramProvider.getBaseCall(i))));
}
setDirty();
}
if (tokens != null) { // If either an edited sequence or a pherogram URI was provided.
- provider.insertTokensAt(id, 0, tokens);
+ model.insertTokensAt(id, 0, tokens);
if (pherogramProvider != null) {
// Create pherogram area:
new PherogramAreaModel(pherogramProvider));
// Set position properties and shifts:
- PherogramAreaModel model = pherogramArea.getModel();
+ PherogramAreaModel phergramModel = pherogramArea.getModel();
if ((firstSeqPos != null) && (leftCutPos != null)) {
- model.setFirstSeqLeftCutPos(firstSeqPos, leftCutPos);
+ phergramModel.setFirstSeqLeftCutPos(firstSeqPos, leftCutPos);
}
if (rightCutPos != null) {
- model.setRightCutPosition(rightCutPos);
+ phergramModel.setRightCutPosition(rightCutPos);
}
if ((shifts != null) && (shifts.length > 0)) {
for (int i = 0; i < shifts.length; i++) {
- model.addShiftChange(shifts[i].position, shifts[i].shift);
+ phergramModel.addShiftChange(shifts[i].position, shifts[i].shift);
}
setDirty();
}
}
return id;
}
+
+
+ public static URI getPherogramURI(SingleRead pherogramInfo) {
+ if (pherogramInfo.getPherogram() != null) {
+ return MediaUtils.getFirstMediaRepresentationPart(pherogramInfo.getPherogram()).getUri();
+ }
+ else {
+ return null;
+ }
+ }
}
\ No newline at end of file
\r
\r
import info.bioinfweb.commons.bio.CharacterStateSetType;\r
+import info.bioinfweb.commons.io.W3CXSConstants;\r
import info.bioinfweb.commons.text.StringUtils;\r
import info.bioinfweb.jphyloio.ReadWriteConstants;\r
import info.bioinfweb.jphyloio.ReadWriteParameterMap;\r
import info.bioinfweb.jphyloio.events.SequenceTokensEvent;\r
import info.bioinfweb.jphyloio.events.TokenSetDefinitionEvent;\r
import info.bioinfweb.jphyloio.events.type.EventContentType;\r
+import info.bioinfweb.jphyloio.utils.JPhyloIOWritingUtils;\r
\r
import java.io.IOException;\r
+import java.net.URI;\r
+import java.util.ArrayList;\r
import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import javax.xml.namespace.QName;\r
\r
import eu.etaxonomy.cdm.model.molecular.Sequence;\r
+import eu.etaxonomy.cdm.model.molecular.SingleReadAlignment;\r
+import eu.etaxonomy.taxeditor.molecular.editor.AlignmentEditor;\r
\r
\r
\r
/**\r
* In implementation of {@link MatrixDataAdapter} that delegates to a {@link Sequence} object.\r
+ * <p>\r
+ * Note that this adapter stores information on the {@link Sequence} in creation. Modifying the sequence or linked\r
+ * objects will require to create a new instance of this class. Otherwise unexpected behavior may be the consequence.\r
*\r
* @author Ben Stöver\r
* @date 29.04.2016\r
*/\r
-public class CDMSequenceMatrixAdapter extends NoCharDefsNoSetsMatrixDataAdapter implements ReadWriteConstants {\r
+public class CDMSequenceMatrixAdapter extends NoCharDefsNoSetsMatrixDataAdapter implements ReadWriteConstants, SingleReadAlignmentPredicates {\r
public static final String MATRIX_ID = DEFAULT_MATRIX_ID_PREFIX + "ContigAlignment";\r
public static final String SINGLE_READ_SEQUENCE_ID_PREFIX = DEFAULT_SEQUENCE_ID_PREFIX + "SingleRead";\r
public static final String CONSENSUS_SEQUENCE_ID= DEFAULT_SEQUENCE_ID_PREFIX + "Consensus";\r
\r
\r
private Sequence sequence;\r
+ private List<SingleReadAlignment> singleReadList;\r
private String consensusSequenceLabel;\r
private ObjectListDataAdapter<TokenSetDefinitionEvent> tokenSetList;\r
//TODO Also allow specifying single read labels?\r
this.sequence = sequence;\r
this.consensusSequenceLabel = consensusSequenceLabel;\r
tokenSetList = createTokenSetList();\r
+ singleReadList = new ArrayList<SingleReadAlignment>(sequence.getSingleReadAlignments()); // Store references of single reads in defined order to allow random access.\r
+ //TODO Omit single reads that do not have an edited sequece yet?\r
}\r
\r
\r
\r
@Override\r
public long getSequenceCount(ReadWriteParameterMap parameters) {\r
- return /*sequence.getSingleReadAlignments().size() +*/ 1;\r
+ return singleReadList.size() + 1; // The last sequence is the consensus sequence.\r
}\r
\r
\r
public long getSequenceLength(ReadWriteParameterMap parameters, String sequenceID) throws IllegalArgumentException {\r
int singleReadIndex = extractSingleReadIndexFromID(sequenceID);\r
if (singleReadIndex >= 0) {\r
- //TODO Determine single read length. (Current problem: Reads are not ordered in the set of the Sequence object.)\r
- return 0;\r
+ String sequence = singleReadList.get(singleReadIndex).getEditedSequence();\r
+ if (sequence != null) {\r
+ return sequence.length();\r
+ }\r
+ else { // This would happen e.g. if not edited sequence was copied from pherogram yet.\r
+ return 0;\r
+ }\r
}\r
else if (CONSENSUS_SEQUENCE_ID.equals(sequenceID)) {\r
return getCDMSequence().getSequenceString().length();\r
}\r
\r
\r
+ private void writeStringPart(JPhyloIOEventReceiver receiver, String string, long startColumn, long endColumn) throws IOException {\r
+ if (string != null) {\r
+ receiver.add(new SequenceTokensEvent(StringUtils.charSequenceToStringList(\r
+ string.substring((int)startColumn, (int)endColumn))));\r
+ }\r
+ }\r
+\r
+\r
+ private String createMetadataID(String sequenceID, QName predicate) {\r
+ return sequenceID + "META" + predicate.getLocalPart();\r
+ }\r
+\r
+\r
+ private void writeMetadataEvents(JPhyloIOEventReceiver receiver, String sequenceID, QName predicate, Object objectValue)\r
+ throws IOException {\r
+\r
+ if (objectValue != null) {\r
+ JPhyloIOWritingUtils.writeSimpleLiteralMetadata(receiver, createMetadataID(sequenceID, predicate), null,\r
+ predicate, W3CXSConstants.DATA_TYPE_BOOLEAN, objectValue, null);\r
+ }\r
+ }\r
+\r
+\r
@Override\r
- public void writeSequencePartContentData(ReadWriteParameterMap parameters, JPhyloIOEventReceiver receiver, String sequenceID, long startColumn,\r
- long endColumn) throws IOException, IllegalArgumentException {\r
+ public void writeSequencePartContentData(ReadWriteParameterMap parameters, JPhyloIOEventReceiver receiver, String sequenceID,\r
+ long startColumn, long endColumn) throws IOException, IllegalArgumentException {\r
\r
int singleReadIndex = extractSingleReadIndexFromID(sequenceID);\r
if (singleReadIndex >= 0) {\r
- //TODO Implement single read output.\r
+ SingleReadAlignment singleRead = singleReadList.get(singleReadIndex);\r
+ if (startColumn == 0) {\r
+ writeMetadataEvents(receiver, sequenceID, PREDICATE_IS_SINGLE_READ, new Boolean(true));\r
+ writeMetadataEvents(receiver, sequenceID, PREDICATE_IS_REVERSE_COMPLEMENTED, new Boolean(singleRead.isReverseComplement()));\r
+ writeMetadataEvents(receiver, sequenceID, PREDICATE_HAS_LEFT_CUT_POSITION, singleRead.getLeftCutPosition());\r
+ writeMetadataEvents(receiver, sequenceID, PREDICATE_HAS_RIGHT_CUT_POSITION, singleRead.getRightCutPosition());\r
+\r
+ URI pherogramURI = AlignmentEditor.getPherogramURI(singleRead.getSingleRead());\r
+ if (pherogramURI != null) {\r
+ JPhyloIOWritingUtils.writeTerminalResourceMetadata(receiver, createMetadataID(sequenceID, PREDICATE_HAS_PHEROGRAM),\r
+ null, PREDICATE_HAS_PHEROGRAM, pherogramURI);\r
+ }\r
+\r
+ //TODO Add pherogram alignment metadata. (Use LibrAlign DataModel writer implementation.)\r
+ }\r
+ writeStringPart(receiver, singleRead.getEditedSequence(), startColumn, endColumn);\r
}\r
else if (CONSENSUS_SEQUENCE_ID.equals(sequenceID)) {\r
if (startColumn == 0) {\r
- //TODO Add consensus sequence metadata.\r
- //TODO Possibly export additional properties of sequence (e.g. isBarcode(), getDdbjId(), ...) as metadata.\r
+ writeMetadataEvents(receiver, sequenceID, PREDICATE_IS_CONSENSUS_SEQUENCE, new Boolean(true));\r
+ //TODO Possibly export additional properties of sequence (e.g. isBarcode(), getDdbjId(), ...) as metadata?\r
}\r
- receiver.add(new SequenceTokensEvent(StringUtils.charSequenceToStringList(\r
- getCDMSequence().getSequenceString().substring((int)startColumn, (int)endColumn))));\r
+ writeStringPart(receiver, getCDMSequence().getSequenceString(), startColumn, endColumn);\r
}\r
else {\r
throw new IllegalArgumentException("No sequence with the ID \"" + sequenceID + "\" could be found.");\r
--- /dev/null
+// $Id$
+/**
+* Copyright (C) 2016 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.taxeditor.molecular.io;
+
+
+import javax.xml.namespace.QName;
+
+
+
+/**
+ * Contains constants for <i>RDF</i> predicates used in the I/O of single read alignments e.g. from and to the <i>NeXML</i> format.
+ *
+ * @author Ben Stöver
+ * @date 27.10.2016
+ */
+public interface SingleReadAlignmentPredicates {
+ public static final String NAMESPACE_URI = "http://bioinfweb.info/xmlns/PhyDE/Annotations/"; //TODO Possibly change this namespace, when according decision is made.
+ public static final String NAMESPACE_PREFIX = "phy";
+
+ public static final QName PREDICATE_IS_SINGLE_READ = new QName(NAMESPACE_URI, "isSingleRead", NAMESPACE_PREFIX);
+ public static final QName PREDICATE_IS_CONSENSUS_SEQUENCE = new QName(NAMESPACE_URI, "isConsensus", NAMESPACE_PREFIX);
+ public static final QName PREDICATE_IS_REVERSE_COMPLEMENTED = new QName(NAMESPACE_URI, "isRCed", NAMESPACE_PREFIX);
+ public static final QName PREDICATE_HAS_PHEROGRAM = new QName(NAMESPACE_URI, "hasPherogram", NAMESPACE_PREFIX);
+ public static final QName PREDICATE_HAS_PHEROGRAM_ALIGNMENT = new QName(NAMESPACE_URI, "hasPherogramAlignment", NAMESPACE_PREFIX);
+ public static final QName PREDICATE_HAS_LEFT_CUT_POSITION = new QName(NAMESPACE_URI, "hasLeftCutPosition", NAMESPACE_PREFIX);
+ public static final QName PREDICATE_HAS_RIGHT_CUT_POSITION = new QName(NAMESPACE_URI, "hasRightCutPosition", NAMESPACE_PREFIX);
+}