// Copyright 2024 DeepMind Technologies Limited // // AlphaFold 3 source code is licensed under CC BY-NC-SA 4.0. To view a copy of // this license, visit https://creativecommons.org/licenses/by-nc-sa/4.0/ // // To request access to the AlphaFold 3 model parameters, follow the process set // out at https://github.com/google-deepmind/alphafold3. You may only use these // if received directly from Google. Use is subject to terms of use available at // https://github.com/google-deepmind/alphafold3/blob/main/WEIGHTS_TERMS_OF_USE.md #include "alphafold3/parsers/cpp/fasta_iterator_lib.h" #include #include #include #include #include #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/ascii.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_split.h" #include "absl/strings/string_view.h" #include "absl/strings/strip.h" namespace alphafold3 { // Parse FASTA string and return list of strings with amino acid sequences. // Returns a list of amino acid sequences only. std::vector ParseFasta(absl::string_view fasta_string) { std::vector sequences; std::string* sequence = nullptr; for (absl::string_view line_raw : absl::StrSplit(fasta_string, '\n')) { absl::string_view line = absl::StripAsciiWhitespace(line_raw); if (absl::ConsumePrefix(&line, ">")) { sequence = &sequences.emplace_back(); } else if (!line.empty() && sequence != nullptr) { absl::StrAppend(sequence, line); } } return sequences; } // Parse FASTA string and return list of strings with amino acid sequences. // Returns two lists: The first one with amino acid sequences, the second with // the descriptions associated with each sequence. std::pair, std::vector> ParseFastaIncludeDescriptions(absl::string_view fasta_string) { std::pair, std::vector> result; auto& [sequences, descriptions] = result; std::string* sequence = nullptr; for (absl::string_view line_raw : absl::StrSplit(fasta_string, '\n')) { absl::string_view line = absl::StripAsciiWhitespace(line_raw); if (absl::ConsumePrefix(&line, ">")) { descriptions.emplace_back(line); sequence = &sequences.emplace_back(); } else if (!line.empty() && sequence != nullptr) { absl::StrAppend(sequence, line); } } return result; } absl::StatusOr> FastaFileIterator::Next() { std::string line_str; while (std::getline(reader_, line_str)) { absl::string_view line = line_str; line = absl::StripAsciiWhitespace(line); if (absl::ConsumePrefix(&line, ">")) { if (!description_.has_value()) { description_ = line; } else { std::pair output(sequence_, *description_); description_ = line; sequence_ = ""; return output; } } else if (description_.has_value()) { absl::StrAppend(&sequence_, line); } } has_next_ = false; reader_.close(); if (description_.has_value()) { return std::pair(sequence_, *description_); } else { return absl::InvalidArgumentError( absl::StrCat("Invalid FASTA file: ", filename_)); } } absl::StatusOr> FastaStringIterator::Next() { size_t consumed = 0; for (absl::string_view line_raw : absl::StrSplit(fasta_string_, '\n')) { consumed += line_raw.size() + 1; // +1 for the newline character. absl::string_view line = absl::StripAsciiWhitespace(line_raw); if (absl::ConsumePrefix(&line, ">")) { if (!description_.has_value()) { description_ = line; } else { std::pair output(sequence_, *description_); description_ = line; sequence_ = ""; fasta_string_.remove_prefix(consumed); return output; } } else if (description_.has_value()) { absl::StrAppend(&sequence_, line); } } has_next_ = false; if (description_.has_value()) { return std::pair(sequence_, *description_); } else { return absl::InvalidArgumentError("Invalid FASTA string"); } } } // namespace alphafold3