|
|
@ -3,7 +3,14 @@ |
|
|
|
#include <pybind11/stl.h> |
|
|
|
#include <pybind11/stl.h> |
|
|
|
#include <vector> |
|
|
|
#include <vector> |
|
|
|
#include <fstream> |
|
|
|
#include <fstream> |
|
|
|
|
|
|
|
#include <iostream> |
|
|
|
|
|
|
|
#include <ctime> |
|
|
|
|
|
|
|
#include <cmath> |
|
|
|
#include "stormpci.h" |
|
|
|
#include "stormpci.h" |
|
|
|
|
|
|
|
#include "string.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace py = pybind11; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define STRINGIFY(x) #x |
|
|
|
#define STRINGIFY(x) #x |
|
|
|
#define MACRO_STRINGIFY(x) STRINGIFY(x) |
|
|
|
#define MACRO_STRINGIFY(x) STRINGIFY(x) |
|
|
@ -18,13 +25,35 @@ typedef struct { |
|
|
|
} BlockBinary; |
|
|
|
} BlockBinary; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double haversine(double angle){ |
|
|
|
|
|
|
|
return sin(angle / 2.0)*sin(angle / 2.0); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double inverse_haversine(double value){ |
|
|
|
|
|
|
|
return 2.0 * asin(sqrt(value)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double distance(double lat1, double lon1, double lat2, double lon2) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
double theta = (lon2 - lon1) * M_PI / 180; |
|
|
|
|
|
|
|
double phi1 = lat1 * M_PI / 180; |
|
|
|
|
|
|
|
double phi2 = lat2 * M_PI / 180; |
|
|
|
|
|
|
|
double curve = inverse_haversine(haversine(phi1 - phi2) + |
|
|
|
|
|
|
|
cos(phi1) * cos(phi2) * haversine(theta)); |
|
|
|
|
|
|
|
return curve * 6'371'000; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BlockReader |
|
|
|
class BlockReader |
|
|
|
{ |
|
|
|
{ |
|
|
|
public: |
|
|
|
public: |
|
|
|
BlockReader(const std::string &fn){ |
|
|
|
BlockReader(const std::string &fn, long int seek_position){ |
|
|
|
f = std::ifstream(fn, std::fstream::binary); |
|
|
|
f = std::ifstream(fn, std::fstream::binary); |
|
|
|
|
|
|
|
pos = seek_position; |
|
|
|
} |
|
|
|
} |
|
|
|
BlockBinary& read_block(){ |
|
|
|
BlockBinary& read_block(){ |
|
|
|
|
|
|
|
f.seekg(pos); |
|
|
|
f.read(reinterpret_cast<char*>(&_single_block), sizeof(BlockBinary)); |
|
|
|
f.read(reinterpret_cast<char*>(&_single_block), sizeof(BlockBinary)); |
|
|
|
if (not f){ |
|
|
|
if (not f){ |
|
|
|
throw; |
|
|
|
throw; |
|
|
@ -34,13 +63,16 @@ public: |
|
|
|
return _single_block; |
|
|
|
return _single_block; |
|
|
|
} |
|
|
|
} |
|
|
|
std::vector<BlockBinary>& read_all_blocks(){ |
|
|
|
std::vector<BlockBinary>& read_all_blocks(){ |
|
|
|
|
|
|
|
f.seekg(pos); |
|
|
|
bool read_successfully = true; |
|
|
|
bool read_successfully = true; |
|
|
|
while (read_successfully){ |
|
|
|
while (read_successfully){ |
|
|
|
f.read(reinterpret_cast<char*>(&_single_block), sizeof(BlockBinary)); |
|
|
|
f.read(reinterpret_cast<char*>(&_single_block), sizeof(BlockBinary)); |
|
|
|
if (not f){ |
|
|
|
if (f) { |
|
|
|
|
|
|
|
_blocks_vector.push_back(_single_block); |
|
|
|
|
|
|
|
pos += sizeof(BlockBinary); |
|
|
|
|
|
|
|
} else { |
|
|
|
read_successfully = false; |
|
|
|
read_successfully = false; |
|
|
|
} |
|
|
|
} |
|
|
|
_blocks_vector.push_back(_single_block); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return _blocks_vector; |
|
|
|
return _blocks_vector; |
|
|
|
} |
|
|
|
} |
|
|
@ -54,7 +86,6 @@ private: |
|
|
|
std::vector<BlockBinary> _blocks_vector; |
|
|
|
std::vector<BlockBinary> _blocks_vector; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
namespace py = pybind11; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PYBIND11_MODULE(stormpci_bin_reader, m) { |
|
|
|
PYBIND11_MODULE(stormpci_bin_reader, m) { |
|
|
|
m.doc() = R"pbdoc( |
|
|
|
m.doc() = R"pbdoc( |
|
|
@ -70,7 +101,7 @@ PYBIND11_MODULE(stormpci_bin_reader, m) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
py::class_<BlockReader>(m, "BlockReader") |
|
|
|
py::class_<BlockReader>(m, "BlockReader") |
|
|
|
.def(py::init<const std::string &>()) |
|
|
|
.def(py::init<const std::string &, long int>(), py::arg("fn"), py::arg("seek")=int(0)) |
|
|
|
.def("read_block", &BlockReader::read_block) |
|
|
|
.def("read_block", &BlockReader::read_block) |
|
|
|
.def("read_all_blocks", &BlockReader::read_all_blocks); |
|
|
|
.def("read_all_blocks", &BlockReader::read_all_blocks); |
|
|
|
|
|
|
|
|
|
|
@ -78,6 +109,9 @@ PYBIND11_MODULE(stormpci_bin_reader, m) { |
|
|
|
.def_readonly("strike", &BlockBinary::strike) |
|
|
|
.def_readonly("strike", &BlockBinary::strike) |
|
|
|
.def_readonly("device_id", &BlockBinary::device_id) |
|
|
|
.def_readonly("device_id", &BlockBinary::device_id) |
|
|
|
.def_readonly("experiment_id", &BlockBinary::experiment_id) |
|
|
|
.def_readonly("experiment_id", &BlockBinary::experiment_id) |
|
|
|
|
|
|
|
.def_property_readonly("raw_data", [](const BlockBinary bb) { |
|
|
|
|
|
|
|
return py::bytes(reinterpret_cast<const char*>(&bb), sizeof(bb)); |
|
|
|
|
|
|
|
}) |
|
|
|
.def("__repr__", |
|
|
|
.def("__repr__", |
|
|
|
[](const BlockBinary &bb) { |
|
|
|
[](const BlockBinary &bb) { |
|
|
|
std::stringstream stream; |
|
|
|
std::stringstream stream; |
|
|
@ -155,6 +189,43 @@ PYBIND11_MODULE(stormpci_bin_reader, m) { |
|
|
|
.def_readonly("EastPol", &StrikeData::EastPol) |
|
|
|
.def_readonly("EastPol", &StrikeData::EastPol) |
|
|
|
.def_readonly("EFieldPol", &StrikeData::EFieldPol) |
|
|
|
.def_readonly("EFieldPol", &StrikeData::EFieldPol) |
|
|
|
.def_readonly("lts2_data", &StrikeData::lts2_data) |
|
|
|
.def_readonly("lts2_data", &StrikeData::lts2_data) |
|
|
|
|
|
|
|
.def_property_readonly("_timestamp_ns", [](const StrikeData &strike) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::tm tm {}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tm.tm_year = (int)strike.lts2_data.year - 1900; |
|
|
|
|
|
|
|
tm.tm_mon = (int)strike.lts2_data.month - 1; |
|
|
|
|
|
|
|
tm.tm_mday = (int)strike.lts2_data.day; |
|
|
|
|
|
|
|
tm.tm_hour = (int)strike.lts2_data.hours; |
|
|
|
|
|
|
|
tm.tm_min = (int)strike.lts2_data.minutes; |
|
|
|
|
|
|
|
tm.tm_sec = (int)strike.lts2_data.seconds; |
|
|
|
|
|
|
|
tm.tm_isdst = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::time_t epoch_s = std::mktime(&tm); |
|
|
|
|
|
|
|
unsigned long long oscillator_ns = ((unsigned long long)strike.lts2_data.TS_time*1'000'000'000)/(unsigned long long)strike.lts2_data.TS_Osc; |
|
|
|
|
|
|
|
unsigned long long timestamp_ns = epoch_s*1'000'000'000 + oscillator_ns; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return timestamp_ns; |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
.def_property_readonly("_station_coords", [](const StrikeData &strike) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double lat = (double)strike.lts2_data.latitude_mas / 324000000 * 90; |
|
|
|
|
|
|
|
double lon = (double)strike.lts2_data.longitude_mas / 648000000 * 180; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch(strike.lts2_data.latitude_ns) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
case 'N': break; |
|
|
|
|
|
|
|
case 'S': lat = -lat; break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
switch(strike.lts2_data.longitude_ew) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
case 'E': break; |
|
|
|
|
|
|
|
case 'W': lon = -lon; break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return std::pair(lat, lon); |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
|
; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|