IntaRNA 3.4.1
RNA-RNA interaction prediction | C++ API
Loading...
Searching...
No Matches
AccessibilityArchive.h
Go to the documentation of this file.
1#ifndef INTARNA_ACCESSIBILITYARCHIVE_H_
2#define INTARNA_ACCESSIBILITYARCHIVE_H_
3
5#include "IntaRNA/Matrix.h"
6
7#include <boost/serialization/access.hpp>
8#include <boost/serialization/array.hpp>
9#include <boost/serialization/split_member.hpp>
10#include <algorithm>
11#include <cstdint>
12#include <limits>
13#include <stdexcept>
14#include <string>
15#include <vector>
16
17namespace IntaRNA {
18
32public:
34
41 explicit AccessibilityArchive( const Accessibility & source, const EdMatrix * matrix = nullptr );
42
44 AccessibilityArchive( const RnaSequence & sequence, size_t maxLength, EdMatrix & target );
45
47 size_t getMaxLength() const;
48
49private:
51 const RnaSequence & sequence;
52 size_t maxLength;
53 const Accessibility * source;
55 const EdMatrix * sourceMatrix;
56 EdMatrix * target;
57
58 template<class Archive> void save( Archive & archive, unsigned int version ) const;
59 template<class Archive> void load( Archive & archive, unsigned int version );
60 BOOST_SERIALIZATION_SPLIT_MEMBER()
61};
62
63inline
65 : sequence(source.getSequence()), maxLength(source.getMaxLength()), source(&source)
66 , sourceMatrix(source.getAccConstraint().isEmpty() ? matrix : nullptr), target(nullptr)
67{}
68
69inline
70AccessibilityArchive::AccessibilityArchive( const RnaSequence & sequence, size_t maxLength, EdMatrix & target )
71 : sequence(sequence), maxLength(maxLength), source(nullptr), sourceMatrix(nullptr), target(&target)
72{}
73
74inline size_t
76{
77 return maxLength;
78}
79
80template<class Archive> void
81AccessibilityArchive::save( Archive & archive, unsigned int ) const
82{
83 const std::uint32_t magic = 0x49414343; // IACC: IntaRNA accessibility
84 const std::uint32_t formatVersion = 1;
85 const std::uint64_t length = sequence.size(), band = maxLength;
87 archive & magic & formatVersion & length & band & infinity;
88 archive & boost::serialization::make_array(sequence.asString().data(), sequence.size());
89 // Avoid maxLength+1 overflow when the entire sequence is covered.
90 const size_t width = maxLength < sequence.size() ? maxLength+1 : sequence.size();
91 if (sourceMatrix && (sourceMatrix->size1() != sequence.size() || sourceMatrix->size2() != sequence.size()))
92 throw std::runtime_error("Accessibility archive: source matrix shape mismatch");
93 std::vector<E_type> scratch(sourceMatrix ? 0 : width);
94 for (size_t i = 0; i < sequence.size(); ++i) {
95 const size_t count = std::min(width, sequence.size()-i);
96 std::span<const E_type> row;
97 if (sourceMatrix) {
98 row = sourceMatrix->row(i);
99 if (row.size() < count)
100 throw std::runtime_error("Accessibility archive: source matrix band too narrow");
101 row = row.first(count);
102 } else {
103 for (size_t k = 0; k < count; ++k) scratch[k] = source->getED(i, i+k);
104 row = std::span<const E_type>(scratch.data(), count);
105 }
106 for (const E_type value : row)
107 if (value < 0 || value > infinity)
108 throw std::runtime_error("Accessibility archive: invalid ED value");
109 archive & boost::serialization::make_array(row.data(), row.size());
110 }
111}
112
113template<class Archive> void
114AccessibilityArchive::load( Archive & archive, unsigned int )
115{
116 std::uint32_t magic, formatVersion;
117 std::uint64_t length, band;
118 E_type infinity;
119 archive & magic & formatVersion & length & band & infinity;
120 if (magic != 0x49414343 || formatVersion != 1)
121 throw std::runtime_error("Accessibility archive: invalid signature or unsupported format version");
122 if (length == 0 || length != sequence.size() || band > length)
123 throw std::runtime_error("Accessibility archive: sequence length or matrix band mismatch");
124 if (infinity != Accessibility::ED_UPPER_BOUND)
125 throw std::runtime_error("Accessibility archive: incompatible energy representation");
126 std::string storedSequence(sequence.size(), '\0');
127 archive & boost::serialization::make_array(storedSequence.data(), storedSequence.size());
128 if (storedSequence != sequence.asString())
129 throw std::runtime_error("Accessibility archive: sequence mismatch");
130
131 const size_t storedMaxLength = static_cast<size_t>(band);
132 maxLength = std::min(maxLength, storedMaxLength);
133 const size_t storedWidth = storedMaxLength < sequence.size() ? storedMaxLength+1 : sequence.size();
134 const size_t width = maxLength < sequence.size() ? maxLength+1 : sequence.size();
135 if (sequence.size() > std::numeric_limits<size_t>::max() / width / sizeof(E_type))
136 throw std::runtime_error("Accessibility archive: matrix size overflow");
137 target->resize(sequence.size(), sequence.size(), 0, width-1, false);
138 // Read retained cells straight into their final storage. Only the discarded
139 // suffix of a wider input band needs scratch space, and it is still validated.
140 std::vector<E_type> discarded(storedWidth-width);
141 for (size_t i = 0; i < sequence.size(); ++i) {
142 const size_t count = std::min(storedWidth, sequence.size()-i);
143 auto row = target->row(i);
144 archive & boost::serialization::make_array(row.data(), row.size());
145 const size_t tailSize = count-row.size();
146 if (tailSize) archive & boost::serialization::make_array(discarded.data(), tailSize);
147 for (const auto values : {std::span<const E_type>(row), std::span<const E_type>(discarded.data(), tailSize)})
148 for (const E_type value : values)
149 if (value < 0 || value > infinity)
150 throw std::runtime_error("Accessibility archive: invalid ED value");
151 }
152}
153
154} // namespace IntaRNA
155#endif
Definition AccessibilityArchive.h:31
size_t getMaxLength() const
Definition AccessibilityArchive.h:75
UpperBandedMatrix< E_type > EdMatrix
Definition AccessibilityArchive.h:33
AccessibilityArchive(const Accessibility &source, const EdMatrix *matrix=nullptr)
Definition AccessibilityArchive.h:64
friend class boost::serialization::access
Definition AccessibilityArchive.h:50
Definition Accessibility.h:25
static const E_type ED_UPPER_BOUND
upper bound for all ED return values
Definition Accessibility.h:30
virtual E_type getED(const size_t from, const size_t to) const =0
Definition RnaSequence.h:29
const String_type & asString() const
Definition RnaSequence.h:442
size_t size() const
Definition RnaSequence.h:366
Definition Matrix.h:433
std::span< T > row(std::size_t i)
Definition Matrix.h:607
std::size_t size1() const noexcept
Definition Matrix.h:575
std::size_t size2() const noexcept
Definition Matrix.h:580
void resize(std::size_t rows, std::size_t newColumns, std::size_t lower, std::size_t upper, bool preserve=true)
Definition Matrix.h:638
Definition Accessibility.h:13
int E_type
type for energy values (energy + accessibility [ED]) (internally)
Definition general.h:78