Skip to content

FASTA

Support reading and writing fasta files 🔗. All classes/functions are available in the ivio::fasta namespace.

Record and RecordView (record, record_view)

IVio provides the datastructures ivio::fasta::record and ivio::fasta::record_view. These are typically used as input/output arguments of the readers and writers. These datastructures convertible to each other.

The record_view layout

struct record_view {
    std::string_view id;
    std::string_view seq;
};
The record layout
struct record {
    std::string id;
    std::string seq;
};

Reader (reader, reader::config)

The ivio::fasta::reader accepts a ivio::fasta::reader::config object for initialization. It initializes an object that enables you to iterate over the records of a file. It is is for-range compatible, meaning it fulfills c++ concepts of range and LegacyInputIterator. When looping over a reader it returns record_view objects that are only valid until next record is being requested from the reader. To get ownership of the data, it is required to create an object of type record.

To configure the reader one must fill the ivio::fasta::reader::config struct which declares the input file and if gzip compression is expected.

struct ivio::fasta::reader::config {
    // Source: file or stream
    std::variant<std::filesystem::path, std::reference_wrapper<std::istream>> input;

    // This is only relevant if a stream is being used
    bool compressed{};
};

Overview of the member functions of ivio::fasta::reader

struct ivio::fasta::reader {
    /*...*/
    auto next() -> std::optional<record_view>; // reads the next record
    void close() const; // closes the read file
};

Writer (writer, writer::config)

The ivio::fasta::writer provides a single function write which takes a ivio::fasta::record_view as input. The class is initialized with a ivio::fasta::writer::config object which has the options:

struct ivio::fasta::writer::config {
    // Source: file or stream
    std::variant<std::filesystem::path, std::reference_wrapper<std::ostream>> output;

    // This is only relevant if a stream is being used
    bool compressed{};

    size_t length{80}; // Break after 80 characters
};

Examples

Example - Reading record by record

In this example a file is being opened and print to command line

#include <iostream>
#include <ivio/ivio.h>

int main(int /*argc*/, char** argv) {
    auto inputFile = std::filesystem::path{argv[1]};
    auto reader = ivio::fasta::reader{{.input = inputFile}};

    for (auto record_view : reader) {
        std::cout << "id: " << record_view.id << "\n";
        std::cout << "seq: " << record_view.seq << "\n";
    }
}
Output
id: Seq1
seq: ACGT
id: Seq2
seq: NNNN

Example - Copying a file

In this example the data is read from the standard input and written to standard output

#include <iostream>
#include <ivio/ivio.h>

int main(int, char**) {
    auto reader = ivio::fasta::reader{{.input = std::cin}};
    auto writer = ivio::fasta::writer{{.input = std::cout}};

    for (auto record_view : reader) {
        writer.write(record_view);
    }
}

Example - Reading complete file

Load complete fasta file into memory:

#include <iostream>
#include <ivio/ivio.h>

int main(int, char**) {
    auto reader = ivio::fasta::reader{{.input = std::cin,
                                       .compressed = false, // false by default, if true a gzip file is expected
    }};

    // creates a vector of type `std::vector<ivio::fasta::record>` even though reader returns `record_view`
    auto vec = std::vector{begin(reader), end(reader)};
}