Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Commit 5c5e582

Browse files
authored
Retrieve spike time units in SpikePopulation (#363)
1 parent 919be1f commit 5c5e582

File tree

8 files changed

+24
-3
lines changed

8 files changed

+24
-3
lines changed

include/bbp/sonata/report_reader.h

+6
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,19 @@ class SONATA_API SpikeReader
7272
*/
7373
Sorting getSorting() const;
7474

75+
/**
76+
* Return the unit of time
77+
*/
78+
std::string getTimeUnits() const;
79+
7580
private:
7681
Population(const std::string& filename, const std::string& populationName);
7782

7883
SpikeTimes spike_times_;
7984
Sorting sorting_ = Sorting::none;
8085
// Use for clamping of user values
8186
double tstart_, tstop_;
87+
std::string time_units_;
8288

8389
void filterNode(Spikes& spikes, const Selection& node_ids) const;
8490
void filterTimestamp(Spikes& spikes, double tstart, double tstop) const;

python/bindings.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -1283,7 +1283,10 @@ PYBIND11_MODULE(_libsonata, m) {
12831283
DOC_SPIKEREADER_POP(getSorting))
12841284
.def_property_readonly("times",
12851285
&SpikeReader::Population::getTimes,
1286-
DOC_SPIKEREADER_POP(getTimes));
1286+
DOC_SPIKEREADER_POP(getTimes))
1287+
.def_property_readonly("time_units",
1288+
&SpikeReader::Population::getTimeUnits,
1289+
DOC_REPORTREADER_POP(getTimeUnits));
12871290
py::class_<SpikeReader>(m, "SpikeReader", DOC(bbp, sonata, SpikeReader))
12881291
.def(py::init([](py::object h5_filepath) { return SpikeReader(py::str(h5_filepath)); }),
12891292
"h5_filepath"_a)

python/generated/docstrings.h

+2
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,8 @@ static const char *__doc_bbp_sonata_SpikeReader_Population_getSorting = R"doc(Re
13241324

13251325
static const char *__doc_bbp_sonata_SpikeReader_Population_getTimes = R"doc(Return (tstart, tstop) of the population)doc";
13261326

1327+
static const char *__doc_bbp_sonata_SpikeReader_Population_getTimeUnits = R"doc(Return the unit of time)doc";
1328+
13271329
static const char *__doc_bbp_sonata_SpikeReader_Population_sorting = R"doc()doc";
13281330

13291331
static const char *__doc_bbp_sonata_SpikeReader_Population_spike_times = R"doc()doc";

python/tests/test_reports.py

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def test_get_spikes_from_population(self):
4444
self.assertEqual(self.test_obj['All'].sorting, "by_time")
4545
self.assertEqual(self.test_obj['spikes1'].sorting, "by_id")
4646
self.assertEqual(self.test_obj['spikes2'].sorting, "none")
47+
self.assertEqual(self.test_obj['spikes2'].time_units, 'ms')
4748
self.assertEqual(self.test_obj['empty'].get(), [])
4849

4950
self.assertEqual(len(self.test_obj['All'].get(node_ids=[])), 0)

src/report_reader.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ SpikeReader::Population::Sorting SpikeReader::Population::getSorting() const {
196196
return sorting_;
197197
}
198198

199+
std::string SpikeReader::Population::getTimeUnits() const {
200+
return time_units_;
201+
}
202+
199203
SpikeReader::Population::Population(const std::string& filename,
200204
const std::string& populationName) {
201205
HighFive::File file(filename, HighFive::File::ReadOnly);
@@ -206,6 +210,7 @@ SpikeReader::Population::Population(const std::string& filename,
206210

207211
pop.getDataSet("node_ids").read(node_ids);
208212
pop.getDataSet("timestamps").read(timestamps);
213+
pop.getDataSet("timestamps").getAttribute("units").read(time_units_);
209214

210215
if (node_ids.size() != timestamps.size()) {
211216
throw SonataError(

tests/data/generate.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,15 @@ def write_spikes(filepath):
204204
gpop_all = h5f.create_group('/spikes/' + population_names[0])
205205
gpop_all.attrs.create('sorting', data=2, dtype=sorting_type)
206206
timestamps, node_ids = zip(*sorted(zip(timestamps_base, node_ids_base)))
207-
set = gpop_all.create_dataset('timestamps', data=timestamps, dtype=np.double)
207+
dtimestamps = gpop_all.create_dataset('timestamps', data=timestamps, dtype=np.double)
208+
dtimestamps.attrs.create('units', data="ms", dtype=string_dtype)
208209
gpop_all.create_dataset('node_ids', data=node_ids, dtype=np.uint64)
209210

210211
gpop_spikes1 = h5f.create_group('/spikes/' + population_names[1])
211212
gpop_spikes1.attrs.create('sorting', data=1, dtype=sorting_type)
212213
node_ids, timestamps = zip(*sorted(zip(node_ids_base, timestamps_base)))
213-
gpop_spikes1.create_dataset('timestamps', data=timestamps, dtype=np.double)
214+
dtimestamps = gpop_spikes1.create_dataset('timestamps', data=timestamps, dtype=np.double)
215+
dtimestamps.attrs.create('units', data="ms", dtype=string_dtype)
214216
gpop_spikes1.create_dataset('node_ids', data=node_ids, dtype=np.uint64)
215217

216218
gpop_spikes2 = h5f.create_group('/spikes/' + population_names[2])
@@ -222,6 +224,7 @@ def write_spikes(filepath):
222224
gpop_empty = h5f.create_group('/spikes/' + population_names[3])
223225
gpop_empty.attrs.create('sorting', data=1, dtype=sorting_type)
224226
dtimestamps = gpop_empty.create_dataset('timestamps', data=[], dtype=np.double)
227+
dtimestamps.attrs.create('units', data="ms", dtype=string_dtype)
225228
gpop_empty.create_dataset('node_ids', data=[], dtype=np.uint64)
226229

227230
if __name__ == '__main__':

tests/data/spikes.h5

-80 Bytes
Binary file not shown.

tests/test_report_reader.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ TEST_CASE("SpikeReader", "[base]") {
3535
REQUIRE(reader.openPopulation("empty").get() == std::vector<std::pair<uint64_t, double>>{});
3636

3737
REQUIRE(reader.openPopulation("All").getTimes() == std::make_tuple(0.1, 1.3));
38+
REQUIRE(reader.openPopulation("All").getTimeUnits() == "ms");
3839
}
3940

4041
TEST_CASE("SomaReportReader limits", "[base]") {

0 commit comments

Comments
 (0)