Gamgee
You miserable little maggot. I'll stove your head in!
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
individual_field_value.h
Go to the documentation of this file.
1 #ifndef gamgee__individual_field_value__guard
2 #define gamgee__individual_field_value__guard
3 
5 
6 #include "../missing.h"
7 #include "../utils/hts_memory.h"
8 #include "../utils/utils.h"
9 #include "../utils/variant_field_type.h"
10 
11 #include "htslib/vcf.h"
12 
13 #include <memory>
14 
15 namespace gamgee {
16 
52 template<class VALUE_TYPE>
54  public:
55 
63  IndividualFieldValue(const std::shared_ptr<bcf1_t>& body, const bcf_fmt_t* const format_ptr, uint8_t* const data_ptr) :
64  m_body {body},
65  m_format_ptr {format_ptr},
66  m_data_ptr {data_ptr},
67  m_num_bytes {utils::size_for_type(static_cast<utils::VariantFieldType>(format_ptr->type), format_ptr)}
68  {}
69 
74  IndividualFieldValue(const IndividualFieldValue& other) = delete;
75 
81  m_body {std::move(other.m_body)},
82  m_format_ptr {other.m_format_ptr},
83  m_data_ptr {other.m_data_ptr},
84  m_num_bytes {other.m_num_bytes}
85  {}
86 
90  IndividualFieldValue& operator=(const IndividualFieldValue& other) = delete;
91 
97  if (this != &other)
98  return *this;
99  m_body = std::move(other.m_body);
100  m_format_ptr = other.m_format_ptr;
101  m_data_ptr = other.m_data_ptr;
102  m_num_bytes = other.m_num_bytes;
103  return *this;
104  }
105 
111  bool operator==(const IndividualFieldValue& other) const {
112  if (this == &other)
113  return true;
114  //Use iterators where possible as they take care of field sizes, bcf_*_vector_end
115  auto other_iter = other.begin();
116  auto other_end = other.end();
117  for(const auto& curr_val : *this)
118  {
119  if(other_iter == other_end) //different length, this is longer (more valid values) than other
120  return false;
121  if(!utils::bcf_check_equal_element(curr_val, *other_iter))
122  return false;
123  ++other_iter;
124  }
125  //Check if other still has more valid values
126  if(other_iter != other_end)
127  return false;
128  return true;
129  }
130 
136  bool operator!=(const IndividualFieldValue& other) const {
137  return !(*this == other);
138  }
139 
147  VALUE_TYPE operator[](const uint32_t index) const {
148  utils::check_max_boundary(index, m_format_ptr->n);
149  return convert_from_byte_array(index);
150  }
151 
156  return IndividualFieldValueIterator<VALUE_TYPE>{m_body, m_data_ptr, m_data_ptr + m_format_ptr->size, m_num_bytes, static_cast<utils::VariantFieldType>(m_format_ptr->type)};
157  }
158 
163  return IndividualFieldValueIterator<VALUE_TYPE>{m_body, m_data_ptr + m_format_ptr->size, m_data_ptr + m_format_ptr->size, m_num_bytes, static_cast<utils::VariantFieldType>(m_format_ptr->type)};
164  }
165 
166  uint32_t size() const { return m_format_ptr->n; }
167  VALUE_TYPE front() const { return operator[](0); }
168  VALUE_TYPE back() const { return operator[](m_format_ptr->n - 1); }
169 
173  bool missing() const {
174  // Important: relies on IndividualFieldValueIterator to skip vector end values, if there are any
175  for (const auto& value : *this) {
176  // use qualifier to avoid recursion
177  if (!gamgee::missing(value))
178  return false;
179  }
180  return true;
181  }
182 
183  private:
184  std::shared_ptr<bcf1_t> m_body;
185  const bcf_fmt_t* m_format_ptr;
186  uint8_t* m_data_ptr;
187  uint8_t m_num_bytes;
188 
189  VALUE_TYPE convert_from_byte_array(int index) const;
190 };
191 
195 template<> inline
196 int32_t IndividualFieldValue<int32_t>::convert_from_byte_array(int index) const {
197  return utils::convert_data_to_integer(m_data_ptr, index, m_num_bytes, static_cast<utils::VariantFieldType>(m_format_ptr->type));
198 }
199 
203 template<> inline
204 float IndividualFieldValue<float>::convert_from_byte_array(int index) const {
205  return utils::convert_data_to_float(m_data_ptr, index, m_num_bytes, static_cast<utils::VariantFieldType>(m_format_ptr->type));
206 }
207 
211 template<> inline
212 std::string IndividualFieldValue<std::string>::convert_from_byte_array(int index) const {
213  return utils::convert_data_to_string(m_data_ptr, index, m_num_bytes, static_cast<utils::VariantFieldType>(m_format_ptr->type));
214 }
215 
220 template<> inline
221 std::string IndividualFieldValue<std::string>::operator[](const uint32_t index) const {
222  auto is_string_type = utils::is_string_type(m_format_ptr->type);
223  auto limit = size();
224  auto prefix_msg = "";
225  if(is_string_type)
226  {
227  limit = 1u;
228  prefix_msg = "FORMAT fields of type string in VCFs have only 1 element per sample :: ";
229  }
230  utils::check_max_boundary(index, limit, prefix_msg);
231  return convert_from_byte_array(index);
232 }
233 
234 }
235 
236 #endif // gamgee__individual_field_value__guard
VALUE_TYPE operator[](const uint32_t index) const
random access to the value of a given sample for reading or writing
Definition: individual_field_value.h:147
VariantFieldType
an enumeration of the types in htslib for the format field values
Definition: variant_field_type.h:16
void check_max_boundary(const uint32_t index, const uint32_t size, const std::string &prefix_msg)
checks that an index is greater than or equal to size
Definition: utils.h:63
VALUE_TYPE back() const
convenience function to access the last element
Definition: individual_field_value.h:168
std::string convert_data_to_string(const uint8_t *data_ptr, const int index, const uint8_t num_bytes_per_value, const VariantFieldType &type)
converts the value in an index from the byte array into string
Definition: variant_field_type.cpp:77
IndividualFieldValue & operator=(const IndividualFieldValue &other)=delete
bool missing() const
returns true if all of the values are missing
Definition: individual_field_value.h:173
VALUE_TYPE front() const
convenience function to access the first element
Definition: individual_field_value.h:167
bool is_string_type(const int32_t &type)
check if type is of type string
Definition: variant_field_type.h:59
IndividualFieldValue(const std::shared_ptr< bcf1_t > &body, const bcf_fmt_t *const format_ptr, uint8_t *const data_ptr)
creates a new IndividualFieldValue poiinting to the shared byte array inside the variant object ...
Definition: individual_field_value.h:63
Definition: vcf.h:136
bool operator!=(const IndividualFieldValue &other) const
compares two IndividualFieldValue objects in the following order: memory address, size and values...
Definition: individual_field_value.h:136
uint32_t size() const
the number of values in this IndividualFieldValue (values per sample)
Definition: individual_field_value.h:166
IndividualFieldValueIterator< VALUE_TYPE > end() const
create a new end iterator over the values for this sample
Definition: individual_field_value.h:162
int n
Definition: vcf.h:138
bool bcf_check_equal_element(const TYPE &x, const TYPE &y)
Check whether two values from VCF fields of primitive types (for which the == operator is defined) * ...
Definition: utils.h:85
Definition: exceptions.h:9
IndividualFieldValueIterator< VALUE_TYPE > begin() const
create a new begin iterator over the values for this sample
Definition: individual_field_value.h:155
int type
Definition: vcf.h:138
iterator for FormatFieldGenericValue objects.
Definition: individual_field_value_iterator.h:31
uint8_t size_for_type(const VariantFieldType &type, const bcf_fmt_t *const format_ptr)
returns the number of bytes for a given VariantFieldType
Definition: variant_field_type.cpp:102
IndividualFieldValue(IndividualFieldValue &&other)
safely moves the data from one IndividualFieldValue to a new one without making any copies ...
Definition: individual_field_value.h:80
int size
Definition: vcf.h:138
IndividualFieldValue & operator=(IndividualFieldValue &&other)
safely moves the data from one IndividualField to the other without making any copies ...
Definition: individual_field_value.h:96
int32_t convert_data_to_integer(const uint8_t *data_ptr, const int index, const uint8_t num_bytes_per_value, const VariantFieldType &type)
converts the value in an index from the byte array into int32_t
Definition: variant_field_type.cpp:11
A class template to hold the values a format field for a particular sample.
Definition: individual_field_value.h:53
bool missing(const bool value)
Returns true if bool is false (missing).
Definition: missing.h:23
bool operator==(const IndividualFieldValue &other) const
compares two IndividualFieldValue objects in the following order: memory address, size and values...
Definition: individual_field_value.h:111
float convert_data_to_float(const uint8_t *data_ptr, const int index, const uint8_t num_bytes_per_value, const VariantFieldType &type)
converts the value in an index from the byte array into float
Definition: variant_field_type.cpp:41