metric_stream.h
Go to the documentation of this file.
1 
9 #include <string>
10 #include <fstream>
11 #include "interop/util/exception.h"
14 #include "interop/io/paths.h"
16 #include "interop/util/assert.h"
17 
18 #pragma once
19 namespace illumina { namespace interop { namespace io
20 {
30  template<class MetricType>
31  std::string interop_filename(const std::string &run_directory, bool use_out = true)
32  {
33  return paths::interop_filename<MetricType>(run_directory, use_out);
34  }
35 
44  template<class MetricType>
45  std::string interop_basename(bool use_out = true)
46  {
47  return paths::interop_basename<MetricType>(use_out);
48  }
49 
54  template<class MetricType, typename OutputIterator>
55  void copy_versions(OutputIterator oit)
56  {
57  typedef metric_format_factory<MetricType> factory_t;
58  typedef typename factory_t::metric_format_map metric_format_map;
59  metric_format_map &format_map = factory_t::metric_formats();
60  for(typename metric_format_map::const_iterator it = format_map.begin();it != format_map.end();++it, ++oit)
61  {
62  if(it->second->is_deprecated()) continue;
63  *oit = it->first;
64  }
65  }
72  template<class MetricSet>
73  size_t read_header(std::istream &in, MetricSet &metrics)
74  {
75  typedef typename MetricSet::metric_type metric_t;
76  typedef metric_format_factory<metric_t> factory_t;
77  typedef typename factory_t::metric_format_map metric_format_map;
78  metric_format_map &format_map = factory_t::metric_formats();
79  if (!in.good()) INTEROP_THROW(incomplete_file_exception, "Empty file found");
80  const int version = in.get();
81  if (version == -1) INTEROP_THROW(incomplete_file_exception, "Empty file found");
82  if (format_map.find(version) == format_map.end())
83  INTEROP_THROW(bad_format_exception, "No format found to parse " << paths::interop_basename<MetricSet>()
84  << " with version: " << version << " of "
85  << format_map.size() );
86  INTEROP_ASSERT(format_map[version]);
87  metrics.set_version(static_cast< ::int16_t>(version));
88  return format_map[version]->read_header(in, metrics);
89  }
90 
98  template<class MetricSet>
99  void read_metrics(std::istream &in, MetricSet &metrics, const size_t file_size, const bool rebuild=true)
100  {
101  typedef typename MetricSet::metric_type metric_t;
102  typedef metric_format_factory<metric_t> factory_t;
103  typedef typename factory_t::metric_format_map metric_format_map;
104  metric_format_map &format_map = factory_t::metric_formats();
105  if (!in.good()) INTEROP_THROW(incomplete_file_exception, "Empty file found");
106  const int version = in.get();
107  if (version == -1) INTEROP_THROW(incomplete_file_exception, "Empty file found");
108  if (format_map.find(version) == format_map.end())
109  INTEROP_THROW(bad_format_exception, "No format found to parse " << paths::interop_basename<MetricSet>()
110  << " with version: " << version << " of "
111  << format_map.size() );
112  INTEROP_ASSERT(format_map[version]);
113  if(format_map[version]->is_deprecated()) return; // This version of the format is unsupported
114  metrics.set_version(static_cast< ::int16_t>(version));
115  try
116  {
117  format_map[version]->read_metrics(in, metrics, file_size);
118  }
119  catch(const incomplete_file_exception& ex)
120  {
121  if(rebuild)metrics.rebuild_index();
122  throw ex;
123  }
124  if(rebuild)metrics.rebuild_index();
125  }
126 
133  template<class MetricType>
134  size_t record_size(const typename MetricType::header_type &header,
135  const ::int16_t version = MetricType::LATEST_VERSION)
136  {
137  typedef metric_format_factory<MetricType> factory_type;
138  typedef typename factory_type::metric_format_map metric_format_map;
139  metric_format_map &format_map = factory_type::metric_formats();
140 
141  if (format_map.find(version) == format_map.end())
142  INTEROP_THROW(bad_format_exception, "No format found to write file with version: " <<
143  version << " of " << format_map.size());
144 
145  INTEROP_ASSERT(format_map[version]);
146  return format_map[version]->record_size(header);
147  }
148 
155  template<class MetricType, class HeaderType>
156  size_t size_of_record(const HeaderType &header,
157  const ::int16_t version = MetricType::LATEST_VERSION)
158  {
159  typedef metric_format_factory<MetricType> factory_type;
160  typedef typename factory_type::metric_format_map metric_format_map;
161  metric_format_map &format_map = factory_type::metric_formats();
162 
163  if (format_map.find(version) == format_map.end())
164  INTEROP_THROW(bad_format_exception, "No format found to write file with version: " <<
165  version << " of " << format_map.size());
166 
167  INTEROP_ASSERT(format_map[version]);
168  return format_map[version]->record_size(header);
169  }
176  template<class MetricSet>
177  bool is_multi_record(const MetricSet &header,
178  ::int16_t version = -1)
179  {
180  typedef typename MetricSet::metric_type metric_t;
181  typedef metric_format_factory<metric_t> factory_type;
182  typedef typename factory_type::metric_format_map metric_format_map;
183  metric_format_map &format_map = factory_type::metric_formats();
184  if(version < 1) version = header.version();
185 
186  if (format_map.find(version) == format_map.end())
187  INTEROP_THROW(bad_format_exception, "No format found to write file with version: " <<
188  version << " of " << format_map.size());
189 
190  INTEROP_ASSERT(format_map[version]);
191  return format_map[version]->is_multi_record();
192  }
193 
194 
201  template<class MetricSet>
202  size_t size_of_buffer(const MetricSet &metric_set,
203  ::int16_t version=-1)
204  {
205  typedef typename MetricSet::metric_type metric_t;
206  typedef metric_format_factory<metric_t> factory_type;
207  typedef typename factory_type::metric_format_map metric_format_map;
208  if(version < 1) version = metric_set.version();
209  metric_format_map &format_map = factory_type::metric_formats();
210  if (format_map.find(version) == format_map.end())
211  INTEROP_THROW(bad_format_exception, "No format found to write file with version: "
212  << version << " of " << format_map.size());
213 
214  INTEROP_ASSERT(format_map[version]);
215  return format_map[version]->buffer_size(metric_set);
216  }
217 
218 
225  template<class MetricType, class Header>
226  size_t size_of_header(const Header &header,
227  const ::int16_t version=MetricType::LATEST_VERSION)
228  {
229  typedef metric_format_factory<MetricType> factory_type;
230  typedef typename factory_type::metric_format_map metric_format_map;
231  metric_format_map &format_map = factory_type::metric_formats();
232  if (format_map.find(version) == format_map.end())
233  INTEROP_THROW(bad_format_exception, "No format found to write file with version: " <<
234  version << " of " << format_map.size());
235 
236  INTEROP_ASSERT(format_map[version]);
237  return format_map[version]->header_size(header);
238  }
239 
246  template<class MetricSet>
247  size_t header_size(const MetricSet &header,
248  ::int16_t version = -1)
249  {
250  typedef typename MetricSet::metric_type metric_t;
251  if(version < 1) version = header.version();
252  return size_of_header<metric_t>(header, version);
253  }
254 
262  template<class MetricType>
263  void write_metric(std::ostream &out,
264  const MetricType &metric,
265  const typename MetricType::header_type &header,
266  const ::int16_t version)
267  {
268  typedef metric_format_factory<MetricType> factory_type;
269  typedef typename factory_type::metric_format_map metric_format_map;
270  metric_format_map &format_map = factory_type::metric_formats();
271 
272  if (format_map.find(version) == format_map.end())
273  INTEROP_THROW(bad_format_exception, "No format found to write file with version: " <<
274  version << " of " << format_map.size());
275 
276  INTEROP_ASSERT(format_map[version]);
277  format_map[version]->write_metric(out, metric, header);
278  }
279 
286  template<class MetricType>
287  void write_metric_header(std::ostream &out,
288  const ::int16_t version,
289  const typename MetricType::header_type &header = typename MetricType::header_type())
290  {
291  typedef metric_format_factory<MetricType> factory_type;
292  typedef typename factory_type::metric_format_map metric_format_map;
293  metric_format_map &format_map = factory_type::metric_formats();
294  if (format_map.find(version) == format_map.end())
295  INTEROP_THROW(bad_format_exception, "No format found to write file with version: " <<
296  version << " of " << format_map.size());
297 
298  INTEROP_ASSERT(format_map[version]);
299  format_map[version]->write_metric_header(out, header);
300  }
301 
308  template<class MetricSet>
309  static void write_metrics(std::ostream &out, const MetricSet &metrics, ::int16_t version = -1)
310  {
311  typedef typename MetricSet::metric_type metric_type;
312  typedef metric_format_factory<metric_type> factory_type;
313  typedef typename factory_type::metric_format_map metric_format_map;
314  metric_format_map &format_map = factory_type::metric_formats();
315 
316  if (version < 0) version = metrics.version();
317  if (format_map.find(version) == format_map.end())
318  INTEROP_THROW(bad_format_exception, "No format found to write file with version: " <<
319  version << " of " << format_map.size()
320  << " for " << metric_type::prefix() << "" << metric_type::suffix()
321  << " with " << metrics.size() << " metrics");
322 
323  INTEROP_ASSERT(format_map[version]);
324  format_map[version]->write_metric_header(out, metrics);
325  for (typename MetricSet::const_iterator it = metrics.begin();
326  it != metrics.end(); it++)
327  format_map[version]->write_metric(out, *it, metrics);
328  }
339  template<class MetricSet>
340  static void write_text(std::ostream &out,
341  const MetricSet &metrics,
342  const std::vector<std::string>& channel_names,
343  ::int16_t version = -1,
344  const char sep=',',
345  const char eol='\n',
346  const char missing='-')
347  {
348  typedef typename MetricSet::metric_type metric_type;
349  typedef text_format_factory<metric_type> factory_type;
350  typedef typename factory_type::abstract_text_format_t* abstract_text_format_pointer_t;
351 
352  factory_type &factory = factory_type::instance();
353  abstract_text_format_pointer_t format = factory.find(version);
354  if (format == 0)
355  INTEROP_THROW(bad_format_exception,
356  "No format found to write file with version: "
357  << version << " of " << factory.size()
358  << " for " << metric_type::prefix() << "" << metric_type::suffix()
359  << " with " << metrics.size() << " metrics");
360  INTEROP_ASSERT(format);
361  format->write_header(out, metrics, channel_names, sep, eol);
362  for (typename MetricSet::const_iterator it = metrics.begin();
363  it != metrics.end(); it++)
364  format->write_metric(out, *it, metrics, sep, eol, missing);
365 
366  }
367 
378  template<class MetricType>
379  std::string interop_filename(const std::string &run_directory, const size_t cycle, bool use_out = true)
380  {
381  return paths::interop_filename<MetricType>(run_directory, cycle, use_out);
382  }
383 }}}
384 
385 
void write_metric(std::ostream &out, const MetricType &metric, const typename MetricType::header_type &header, const ::int16_t version)
Definition: metric_stream.h:263
metric_type
Definition: enums.h:284
Definition: enum_description.h:15
void write_metric_header(std::ostream &out, const ::int16_t version, const typename MetricType::header_type &header=typename MetricType::header_type())
Definition: metric_stream.h:287
#define INTEROP_THROW(EXCEPTION, MESSAGE)
Definition: exception.h:18
Definition: metric_format_factory.h:48
size_t header_size(const MetricSet &header,::int16_t version=-1)
Definition: metric_stream.h:247
bool is_multi_record(const MetricSet &header,::int16_t version=-1)
Definition: metric_stream.h:177
#define INTEROP_ASSERT(TST)
Definition: assert.h:21
void copy_versions(OutputIterator oit)
Definition: metric_stream.h:55
size_t size_of_header(const Header &header, const ::int16_t version=MetricType::LATEST_VERSION)
Definition: metric_stream.h:226
size_t record_size(const typename MetricType::header_type &header, const ::int16_t version=MetricType::LATEST_VERSION)
Definition: metric_stream.h:134
std::string format(const float val, const int width, const int precision, const char fill= ' ', const bool fixed=true)
Definition: lexical_cast.h:278
std::string interop_basename(bool use_out=true)
Definition: metric_stream.h:45
std::string interop_filename(const std::string &run_directory, bool use_out=true)
Definition: metric_stream.h:31
Definition: stream_exceptions.h:59
Definition: stream_exceptions.h:73
size_t size_of_record(const HeaderType &header, const ::int16_t version=MetricType::LATEST_VERSION)
Definition: metric_stream.h:156
bool is_deprecated(const int version)
Definition: metric_file_stream.h:375
size_t size_of_buffer(const MetricSet &metric_set,::int16_t version=-1)
Definition: metric_stream.h:202
::int64_t file_size(const std::string &path)
Definition: filesystem.cpp:156
void read_metrics(std::istream &in, MetricSet &metrics, const size_t file_size, const bool rebuild=true)
Definition: metric_stream.h:99
size_t read_header(std::istream &in, MetricSet &metrics)
Definition: metric_stream.h:73