← 输入框|github.com|刷新
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
843c117
Changes to fix a number of issues we have seen including empty locus
Oct 3, 2022
ab221dc
Removed getLocusName()
Oct 3, 2022
b68ba30
Merge branch 'biojava:master' into master
jamesmorris Oct 3, 2022
a4d7729
updated the source of the accession to GENBANK
Oct 3, 2022
f0967f8
Merge branch 'master' of https://github.com/jamesmorris/biojava-942.git
Oct 3, 2022
232372d
added file to test for handling features containing joins
Oct 12, 2022
a69e00a
Changed the file used for testing to one whith a much smaller sequence
Oct 12, 2022
21ec595
Handle partial locations in typical cases
Oct 12, 2022
f27305e
maintain quotes around feature qualifiers if they are present
Oct 12, 2022
78a6e21
Updated test file
Oct 12, 2022
1443478
updated the test data and tests
Oct 12, 2022
72347b0
updated test data and tests
Oct 12, 2022
fc978f7
Changed the 'name' set by the super() call to the Qualifier constructor
Oct 18, 2022
df591fd
Set if a db_xref qualifier requires quotes
Oct 18, 2022
4dcfbed
When writing out feature qualifiers if they are db_xref values handle
Oct 18, 2022
a44070c
Changes to improve the testGithub942 test
Oct 18, 2022
d872145
undone formatting changes
Oct 18, 2022
14def30
more fixes to formatting
Oct 18, 2022
63b5d85
added back empty line that was removed
Oct 18, 2022
339ef92
fixed formatting change
Oct 18, 2022
7f116c9
removed unused import
Oct 18, 2022
2dac5d9
reversing formatting changes made during development
Oct 18, 2022
f3212e3
More formatting changes
Oct 18, 2022
54640b7
more formatting changes
Oct 18, 2022
0737dfe
formatting changes
Oct 18, 2022
199a50e
formatting changes
Oct 18, 2022
6365b6b
formatting changes
Oct 18, 2022
1df1734
formatting changes
Oct 18, 2022
61b1412
changed to use primitive boolean rather than the wrapper class
Oct 19, 2022
95f5d20
Changed comments to javadoc
Oct 19, 2022
26f3866
Merge branch 'biojava:master' into master
jamesmorris Oct 26, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class DBReferenceInfo extends Qualifier {
* @param id
*/
public DBReferenceInfo(String database, String id){
super("dbxref","");
super("db_xref","");
this.database = database;
this.id = id;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
package org.biojava.nbio.core.sequence.io;

import org.biojava.nbio.core.exceptions.CompoundNotFoundException;
import org.biojava.nbio.core.sequence.AccessionID;
import org.biojava.nbio.core.sequence.DataSource;
import org.biojava.nbio.core.sequence.TaxonomyID;
import org.biojava.nbio.core.sequence.features.DBReferenceInfo;
Expand Down Expand Up @@ -162,8 +163,14 @@ public LinkedHashMap<String,S> process(final int max) throws IOException, Compou
if(seqString==null) break;
@SuppressWarnings("unchecked")
S sequence = (S) sequenceCreator.getSequence(seqString, 0);
genbankParser.getSequenceHeaderParser().parseHeader(genbankParser.getHeader(), sequence);

GenericGenbankHeaderParser<S, C> genbankHeaderParser = genbankParser.getSequenceHeaderParser();
genbankHeaderParser.parseHeader(genbankParser.getHeader(), sequence);
String id = genbankHeaderParser.getAccession();
int version = genbankHeaderParser.getVersion();
String identifier = genbankHeaderParser.getIdentifier();
AccessionID accession = new AccessionID(id , DataSource.GENBANK, version, identifier);
sequence.setAccession(accession);

// add features to new sequence
genbankParser.getFeatures().values().stream()
.flatMap(List::stream)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,10 @@ public class GenbankSequenceParser<S extends AbstractSequence<C>, C extends Comp
protected static final String PRIMARY = "PRIMARY";
protected static final String DBLINK = "DBLINK";
protected static final String END_SEQUENCE_TAG = "//";
// locus line
protected static final Pattern lp = Pattern.compile("^(\\S+)\\s+(\\d+)\\s+(bp|BP|aa|AA)\\s{0,4}(([dmsDMS][sS]-)?(\\S+))?\\s*(circular|CIRCULAR|linear|LINEAR)?\\s*(\\S+)?\\s*(\\S+)?$");
// locus line with name that may contain spaces but must start and end with non whitespace character
protected static final Pattern lp = Pattern.compile("^(\\S+[\\S ]*\\S*)\\s+(\\d+)\\s+(bp|BP|aa|AA)\\s{0,4}(([dmsDMS][sS]-)?(\\S+))?\\s*(circular|CIRCULAR|linear|LINEAR)?\\s*(\\S+)?\\s*(\\S+)?$");
// locus line with no name
protected static final Pattern lp2 = Pattern.compile("^(\\d+)\\s+(bp|BP|aa|AA)\\s{0,4}(([dmsDMS][sS]-)?(\\S+))?\\s*(circular|CIRCULAR|linear|LINEAR)?\\s*(\\S+)?\\s*(\\S+)?$");
// version line
protected static final Pattern vp = Pattern.compile("^(\\S*?)(\\.(\\d+))?(\\s+GI:(\\S+))?$");
// reference line
Expand Down Expand Up @@ -198,10 +200,12 @@ private void parseFeatureTag(List<String[]> section) {
if (gbFeature == null) {
throw new ParserException("Malformed GenBank file: found a qualifier without feature.");
}
Boolean needsQuotes = false;
key = key.substring(1); // strip leading slash
val = val.replaceAll("\\s*[\\n\\r]+\\s*", " ").trim();
val = val.replaceAll("\\s*[\\n\\r]+\\s*", " ").trim();
if (val.endsWith("\"")) {
val = val.substring(1, val.length() - 1); // strip quotes
needsQuotes = true; // as the value has quotes then set that it needs quotes when written back out
}
// parameter on old feature
if (key.equals("db_xref")) {
Expand All @@ -210,6 +214,7 @@ private void parseFeatureTag(List<String[]> section) {
String dbname = m.group(1);
String raccession = m.group(2);
DBReferenceInfo xref = new DBReferenceInfo(dbname, raccession);
xref.setNeedsQuotes(needsQuotes);
gbFeature.addQualifier(key, xref);

ArrayList<DBReferenceInfo> listDBEntry = new ArrayList<>();
Expand All @@ -219,17 +224,17 @@ private void parseFeatureTag(List<String[]> section) {
throw new ParserException("Bad dbxref");
}
} else if (key.equalsIgnoreCase("organism")) {
Qualifier q = new Qualifier(key, val.replace('\n', ' '));
Qualifier q = new Qualifier(key, val.replace('\n', ' '), needsQuotes);
gbFeature.addQualifier(key, q);
} else {
if (key.equalsIgnoreCase("translation") || key.equals("anticodon")
|| key.equals("transl_except")) {
// strip spaces from sequence
val = val.replaceAll("\\s+", "");
Qualifier q = new Qualifier(key, val);
Qualifier q = new Qualifier(key, val, needsQuotes);
gbFeature.addQualifier(key, q);
} else {
Qualifier q = new Qualifier(key, val);
Qualifier q = new Qualifier(key, val, needsQuotes);
gbFeature.addQualifier(key, q);
}
}
Expand Down Expand Up @@ -304,9 +309,12 @@ private void parseLocusTag(List<String[]> section) {
String loc = section.get(0)[1];
header = loc;
Matcher m = lp.matcher(loc);
Matcher m2 = lp2.matcher(loc);
if (m.matches()) {
headerParser.setName(m.group(1));
headerParser.setAccession(m.group(1)); // default if no accession found
//remove any preceding or trailing whitespace from the locus name
String name = m.group(1).trim().replaceAll(" ","_");
headerParser.setName(name);
headerParser.setAccession(name); // default if no accession found
long sequenceLength = Long.valueOf(m.group(2));
String lengthUnits = m.group(3);
String type = m.group(6);
Expand All @@ -333,6 +341,37 @@ private void parseLocusTag(List<String[]> section) {

log.debug("compound type: {}", compoundType.getClass().getSimpleName());

} else if (m2.matches()) {
// Locus Name Missing - use different Locus regex
headerParser.setName("");
headerParser.setAccession(""); // default if no accession found
long sequenceLength = Long.valueOf(m2.group(1));
String lengthUnits = m2.group(2);
String type = m2.group(5);

if (lengthUnits.equalsIgnoreCase("aa")) {
compoundType = AminoAcidCompoundSet.getAminoAcidCompoundSet();
} else if (lengthUnits.equalsIgnoreCase("bp")) {
if (type != null) {
if (type.contains("RNA")) {
compoundType = RNACompoundSet.getRNACompoundSet();
} else {
compoundType = DNACompoundSet.getDNACompoundSet();
}
} else {
compoundType = DNACompoundSet.getDNACompoundSet();
}
}

if (m2.group(6) != null) isCircularSequence = m2.group(6).equalsIgnoreCase("circular");

// configure location parser with needed information
locationParser.setSequenceLength(sequenceLength);
locationParser.setSequenceCircular(isCircularSequence);

log.debug("compound type: {}", compoundType.getClass().getSimpleName());


} else {
throw new ParserException("Bad locus line");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,9 @@ public void process() throws Exception {
PrintWriter writer = new PrintWriter(os);
for (S sequence : sequences) {
String header = headerFormat.getHeader(sequence);
writer.format(header);
writer.print(header);
writer.println();
// os.write(lineSep);

// os.write(lineSep);
/*
* if isinstance(record.seq, UnknownSeq): #We have already recorded
* the length, and there is no need #to record a long sequence of
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,24 @@ public static void writeNucleotideSequence(OutputStream outputStream,
genbankWriter.process();
}

/**
* Write a collection of NucleotideSequences to a file using the NucleotideSequences
* original header as the LOCUS line rather than generating it
*
* @param outputStream
* @param dnaSequences
* @throws Exception
*/

public static void writeNucleotideSequenceOriginal(OutputStream outputStream, Collection<DNASequence> dnaSequences)
throws Exception {
GenericGenbankHeaderFormat<DNASequence, NucleotideCompound> genericGenbankHeaderFormat = new GenericGenbankHeaderFormat<DNASequence, NucleotideCompound>(
true);
GenbankWriter<DNASequence, NucleotideCompound> genbankWriter = new GenbankWriter<DNASequence, NucleotideCompound>(
outputStream, dnaSequences, genericGenbankHeaderFormat);
genbankWriter.process();
}

/**
* Write a sequence to a file
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*/
package org.biojava.nbio.core.sequence.io;

import org.biojava.nbio.core.sequence.AccessionID;
import org.biojava.nbio.core.sequence.compound.AminoAcidCompoundSet;
import org.biojava.nbio.core.sequence.compound.DNACompoundSet;
import org.biojava.nbio.core.sequence.compound.RNACompoundSet;
Expand All @@ -38,6 +39,7 @@ public class GenericGenbankHeaderFormat<S extends AbstractSequence<C>, C extends
private static final int HEADER_WIDTH = 12;
private static final String lineSep = "%n";
private String seqType = null;
private boolean useOriginalHeader = false;

public GenericGenbankHeaderFormat() {
seqType = null;
Expand All @@ -46,6 +48,10 @@ public GenericGenbankHeaderFormat() {
public GenericGenbankHeaderFormat(String seqType) {
this.seqType = seqType;
}

public GenericGenbankHeaderFormat(boolean useOriginalHeader) {
this.useOriginalHeader = useOriginalHeader;
}

/**
* Used in the the 'header' of each GenBank record.
Expand Down Expand Up @@ -222,6 +228,22 @@ private String _write_the_first_line(S sequence) {
*/
}

/**
* Write the original LOCUS line.
*
* @param sequence
*/
private String _write_original_first_line(S sequence) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: could you keep the method name as per usual camel case convention?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure happy to change, I would normally but I was just following the convention already used in the class
e.g. _write_single_line, _write_multi_line etc

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I didn't realise that was the style already for that file. Well I guess we can live with that a bit longer...


StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb, Locale.US);
formatter.format("LOCUS %s" + lineSep,
StringManipulationHelper.padRight(sequence.getOriginalHeader(), 16));
String output = formatter.toString();
formatter.close();
return output;
}

/**
* This is a bit complicated due to the range of possible ways people might
* have done their annotation... Currently the parser uses a single string
Expand All @@ -243,12 +265,30 @@ private String _write_comment(S sequence) {

@Override
public String getHeader(S sequence) {
String header = _write_the_first_line(sequence);
String acc_with_version;

String header;

if (useOriginalHeader) {
header = _write_original_first_line(sequence);
} else {
header = _write_the_first_line(sequence);
}

AccessionID accessionIdObj = sequence.getAccession();
String accession;
String acc_with_version;

try {
acc_with_version = sequence.getAccession().getID();
accession = acc_with_version.split("\\.", 1)[0];
accession = accessionIdObj.getID();

if (accessionIdObj.getIdentifier() != null) {
acc_with_version = sequence.getAccession().getID() + "." + sequence.getAccession().getVersion() + " GI:"
+ accessionIdObj.getIdentifier();

} else {
acc_with_version = sequence.getAccession().getID() + "." + sequence.getAccession().getVersion();
}

} catch (Exception e) {
acc_with_version = "";
accession = "";
Expand All @@ -262,13 +302,6 @@ public String getHeader(S sequence) {
header += _write_multi_line("VERSION", acc_with_version);

/*
* gi = self._get_annotation_str(record, "gi", just_first=True)
*
* self._write_single_line("ACCESSION", accession) if gi != ".":
* self._write_single_line("VERSION", "%s GI:%s" \ % (acc_with_version,
* gi)) else: self._write_single_line("VERSION", "%s" %
* (acc_with_version))
*
* #The NCBI only expect two types of link so far, #e.g. "Project:28471"
* and "Trace Assembly Archive:123456" #TODO - Filter the dbxrefs list
* to just these? self._write_multi_entries("DBLINK", record.dbxrefs)
Expand Down Expand Up @@ -319,7 +352,7 @@ public String getHeader(S sequence) {
header += _write_feature(feature, rec_length);
}

return header;
return String.format(header);
}

}
Loading