Skip to content

[BUG] protspace annotate discards FASTA sequences, so sequence-derived annotations never run #412

Description

@tsenoner

Bug Description

protspace annotate accepts a FASTA file as its input, but only extracts the identifiers from it and then throws the sequences away. It constructs ProteinAnnotationManager without sequences=:

# Fetch annotations
df = ProteinAnnotationManager(
headers=headers,
annotations=annotations_list,
output_path=None,
).to_pd()

Every construction site in the pipeline passes sequences=sequences; annotate is the only one that does not:

api_df = ProteinAnnotationManager(
headers=headers,
annotations=annotations_list,
output_path=cache_path,
sequences=sequences,
cached_data=cached_df,
sources_to_fetch=sources,
).to_pd()
return self._merge_csv(api_df, csv_df)
else:
api_df = ProteinAnnotationManager(
headers=headers,
annotations=annotations_list,
output_path=cache_path,
sequences=sequences,
).to_pd()
return self._merge_csv(api_df, csv_df)
else:
api_df = ProteinAnnotationManager(
headers=headers,
annotations=annotations_list,
output_path=None,
sequences=sequences,
).to_pd()
return self._merge_csv(api_df, csv_df)

The -i/--input help text already advertises FASTA support ("HDF5 or FASTA file (to extract protein identifiers)"), so the sequences are sitting right there in the file the user supplied.

Consequence

Any annotation that is derived from the sequence rather than from a UniProt lookup silently yields nothing through this command:

Evidence from a real user dataset

The dataset behind #337, #336 and #339 has 149 proteins: 37 real UniProt accessions and 112 custom GT* identifiers. In the bundle generated from it, every sequence-derived column is populated for exactly the 37 mapped proteins and empty for all 112 custom ones:

column UniProt-mapped (37) custom GT* (112)
predicted_transmembrane none empty
predicted_signal_peptide False empty
predicted_membrane Soluble empty
length populated empty

The 112 custom-named proteins have perfectly good sequences in the FASTA. They get nothing because the identifier did not resolve against UniProt, not because the prediction was unavailable.

This is why #339 will still look broken to that reporter even after PR #406 lands: the sentinel fix correctly turns 37 rows into non-transmembrane, but the remaining 112 stay N/A.

Suggested fix

Parse sequences (not just headers) when the input is a FASTA and pass them through as sequences=, matching what ReductionPipeline already does. Worth checking at the same time whether the hosted prepare service routes through this command, since that would extend the gap to web uploads.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions