report_reader.h
1 #pragma once
2 
3 #include <map>
4 #include <string>
5 #include <utility>
6 #include <vector>
7 
8 #include <highfive/H5File.hpp>
9 
10 #include <bbp/sonata/optional.hpp>
11 #include <bbp/sonata/population.h>
12 
13 namespace bbp {
14 namespace sonata {
15 
16 // KeyType will be NodeID for somas report and CompartmentID for elements report
17 template <typename KeyType>
18 struct SONATA_API DataFrame {
19  using DataType = std::vector<KeyType>;
20  std::vector<double> times;
21  DataType ids;
22  // data[times][ids], flattened. n_cols is ids.size()
23  std::vector<float> data;
24 };
25 
26 using Spike = std::pair<NodeID, double>;
27 using Spikes = std::vector<Spike>;
28 struct SpikeTimes {
29  std::vector<NodeID> node_ids;
30  std::vector<double> timestamps;
31 };
32 
34 class SONATA_API SpikeReader
35 {
36  public:
37  class Population
38  {
39  public:
40  enum class Sorting : char {
41  none = 0,
42  by_id = 1,
43  by_time = 2,
44  };
45 
49  std::tuple<double, double> getTimes() const;
50 
54  Spikes get(const nonstd::optional<Selection>& node_ids = nonstd::nullopt,
55  const nonstd::optional<double>& tstart = nonstd::nullopt,
56  const nonstd::optional<double>& tstop = nonstd::nullopt) const;
57 
61  const SpikeTimes& getRawArrays() const;
62 
66  SpikeTimes getArrays(const nonstd::optional<Selection>& node_ids = nonstd::nullopt,
67  const nonstd::optional<double>& tstart = nonstd::nullopt,
68  const nonstd::optional<double>& tstop = nonstd::nullopt) const;
69 
73  Sorting getSorting() const;
74 
78  std::string getTimeUnits() const;
79 
80  private:
81  Population(const std::string& filename, const std::string& populationName);
82 
83  SpikeTimes spike_times_;
84  Sorting sorting_ = Sorting::none;
85  // Use for clamping of user values
86  double tstart_, tstop_;
87  std::string time_units_;
88 
89  void filterNode(Spikes& spikes, const Selection& node_ids) const;
90  void filterTimestamp(Spikes& spikes, double tstart, double tstop) const;
94  Spikes createSpikes() const;
95 
96  friend SpikeReader;
97  };
98 
99  explicit SpikeReader(std::string filename);
100 
104  std::vector<std::string> getPopulationNames() const;
105 
106  const Population& openPopulation(const std::string& populationName) const;
107 
108  private:
109  std::string filename_;
110 
111  // Lazy loaded population
112  mutable std::map<std::string, Population> populations_;
113 };
114 
115 template <typename KeyType>
116 class SONATA_API ReportReader
117 {
118  public:
120  {
121  public:
125  std::tuple<double, double, double> getTimes() const;
126 
130  std::string getTimeUnits() const;
131 
135  std::string getDataUnits() const;
136 
140  bool getSorted() const;
141 
145  std::vector<NodeID> getNodeIds() const;
146 
160  typename DataFrame<KeyType>::DataType getNodeIdElementIdMapping(
161  const nonstd::optional<Selection>& node_ids = nonstd::nullopt,
162  const nonstd::optional<size_t>& block_gap_limit = nonstd::nullopt) const;
163 
172  DataFrame<KeyType> get(
173  const nonstd::optional<Selection>& node_ids = nonstd::nullopt,
174  const nonstd::optional<double>& tstart = nonstd::nullopt,
175  const nonstd::optional<double>& tstop = nonstd::nullopt,
176  const nonstd::optional<size_t>& tstride = nonstd::nullopt,
177  const nonstd::optional<size_t>& block_gap_limit = nonstd::nullopt) const;
178 
179  private:
180  struct NodeIdElementLayout {
181  typename DataFrame<KeyType>::DataType ids;
182  Selection::Ranges node_ranges;
183  std::vector<uint64_t> node_offsets;
184  std::vector<uint64_t> node_index;
185  Selection::Ranges min_max_blocks;
186  };
187 
188  Population(const HighFive::File& file, const std::string& populationName);
189  std::pair<size_t, size_t> getIndex(const nonstd::optional<double>& tstart,
190  const nonstd::optional<double>& tstop) const;
200  NodeIdElementLayout getNodeIdElementLayout(
201  const nonstd::optional<Selection>& node_ids = nonstd::nullopt,
202  const nonstd::optional<size_t>& block_gap_limit = nonstd::nullopt) const;
203 
204  HighFive::Group pop_group_;
205  std::vector<NodeID> node_ids_;
206  std::vector<Selection::Range> node_ranges_;
207  std::vector<uint64_t> node_offsets_;
208  std::vector<uint64_t> node_index_;
209  double tstart_, tstop_, tstep_;
210  std::vector<std::pair<size_t, double>> times_index_;
211  std::string time_units_;
212  std::string data_units_;
213  bool is_node_ids_sorted_;
214 
215  friend ReportReader;
216  };
217 
218  explicit ReportReader(const std::string& filename);
219 
223  std::vector<std::string> getPopulationNames() const;
224 
225  const Population& openPopulation(const std::string& populationName) const;
226 
227  private:
228  HighFive::File file_;
229 
230  // Lazy loaded population
231  mutable std::map<std::string, Population> populations_;
232 };
233 
236 
237 } // namespace sonata
238 } // namespace bbp
bbp::sonata::ReportReader
Definition: report_reader.h:116
bbp::sonata::SpikeTimes
Definition: report_reader.h:28
bbp::sonata::ReportReader::Population
Definition: report_reader.h:119
bbp::sonata::Selection
Definition: selection.h:12
bbp::sonata::DataFrame
Definition: report_reader.h:18
nonstd::optional_lite::optional
class optional
Definition: optional.hpp:521
bbp::sonata::SpikeReader::Population
Definition: report_reader.h:37
bbp::sonata::SpikeReader
Used to read spike files.
Definition: report_reader.h:34