Skip to content

Commit 7a75800

Browse files
committed
Merge branch 'master' into arc_reader_subclass
2 parents 09ad2c3 + be8441f commit 7a75800

File tree

17 files changed

+879
-405
lines changed

17 files changed

+879
-405
lines changed

.github/workflows/cmake.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
sudo apt update
3636
sudo apt install gcc-14 g++-14 -y
3737
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 14 --slave /usr/bin/g++ g++ /usr/bin/g++-14
38-
sudo apt-get install libbz2-dev libboost-all-dev libflac-dev libnetcdf-dev libpython3-dev
38+
sudo apt-get install libz-dev libbz2-dev liblzma-dev libboost-python-dev libflac-dev libnetcdf-dev libpython3-dev
3939
sudo pip install numpy scipy matplotlib astropy healpy sphinx --break-system-packages
4040
4141
- name: Setup python on macOS
@@ -47,7 +47,7 @@ jobs:
4747
- name: Install macOS Dependencies
4848
if: runner.environment == 'github-hosted' && runner.os == 'macOS'
4949
run: |
50-
brew install --overwrite bzip2 boost boost-python3 flac netcdf
50+
brew install --overwrite bzip2 xz boost-python3 flac netcdf
5151
python3.13 -m pip install numpy scipy matplotlib astropy healpy sphinx --break-system-packages
5252
5353
- name: Create Build Environment

.github/workflows/wheels.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ jobs:
8686
uses: pypa/cibuildwheel@v2.23.0
8787
env:
8888
CIBW_BUILD: ${{ matrix.build }}
89-
CIBW_BEFORE_ALL_LINUX: yum install -y bzip2-devel netcdf-devel
89+
CIBW_BEFORE_ALL_LINUX: yum install -y zlib-devel bzip2-devel xz-devel netcdf-devel
9090
CIBW_BEFORE_ALL_MACOS: brew install netcdf
9191
CIBW_BEFORE_BUILD_MACOS: >
9292
ln -s $(dirname $(readlink -f $(which python3)))/python3-config $(dirname $(which python3))/python3-config &&

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ set(Boost_USE_STATIC_LIBS OFF)
5252
set(Boost_USE_MULTITHREADED ON)
5353
set(Boost_USE_STATIC_RUNTIME OFF)
5454
set(Boost_PYTHON_VERSION ${Python_VERSION})
55-
find_package(Boost COMPONENTS iostreams python REQUIRED)
55+
find_package(Boost COMPONENTS python REQUIRED)
5656

5757
# Interface library for flags and library dependencies
5858
add_library(spt3g INTERFACE)

core/CMakeLists.txt

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ add_spt3g_library(core SHARED
1212
src/G3Data.cxx src/G3Vector.cxx src/G3Map.cxx src/G3Timestream.cxx
1313
src/G3Timesample.cxx
1414
src/G3TriggeredBuilder.cxx src/G3MultiFileWriter.cxx src/dataio.cxx
15-
src/crc32.c ${CORE_EXTRA_SRCS}
15+
src/compression.cxx src/crc32.c ${CORE_EXTRA_SRCS}
1616
src/G3NetworkSender.cxx src/G3SyslogLogger.cxx
1717
src/G3PipelineInfo.cxx src/G3Quat.cxx src/G3Units.cxx
1818
src/int_storage.cxx src/pybindings.cxx
@@ -40,8 +40,17 @@ if(FLAC_FOUND)
4040
target_link_libraries(core PRIVATE FLAC::FLAC)
4141
endif()
4242

43-
# Link Boost IOStreams
44-
target_link_libraries(core PRIVATE Boost::iostreams)
43+
# Link against Z library
44+
if(NOT DEFINED WITH_ZLIB)
45+
set(WITH_ZLIB TRUE CACHE BOOL "Enable gzip fie compression")
46+
endif()
47+
if(WITH_ZLIB)
48+
find_package(ZLIB)
49+
endif()
50+
if(ZLIB_FOUND)
51+
target_compile_definitions(core PRIVATE -DZLIB_FOUND)
52+
target_link_libraries(core PRIVATE ZLIB::ZLIB)
53+
endif()
4554

4655
# Link against BZIP2 library
4756
if(NOT DEFINED WITH_BZIP2)
@@ -52,6 +61,7 @@ if(WITH_BZIP2)
5261
endif()
5362
if(BZIP2_FOUND)
5463
target_compile_definitions(core PRIVATE -DBZIP2_FOUND)
64+
target_link_libraries(core PRIVATE BZip2::BZip2)
5565
endif()
5666

5767
if(NOT DEFINED WITH_LZMA)
@@ -62,6 +72,7 @@ if(WITH_LZMA)
6272
endif()
6373
if(LIBLZMA_FOUND)
6474
target_compile_definitions(core PRIVATE -DLZMA_FOUND)
75+
target_link_libraries(core PRIVATE LibLZMA::LibLZMA)
6576
endif()
6677

6778
link_python_dir()
@@ -88,7 +99,9 @@ add_spt3g_test(cuts)
8899
add_spt3g_test(fileio)
89100
add_spt3g_test(multifileio)
90101
add_spt3g_test(splitfileio)
91-
add_spt3g_test(compressedfileio)
102+
if(ZLIB_FOUND)
103+
add_spt3g_test(compressedfileio)
104+
endif()
92105
if(BZIP2_FOUND)
93106
add_spt3g_test(bz2fileio)
94107
endif()

core/include/core/G3Reader.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99

1010
class G3Reader : public G3Module {
1111
public:
12-
G3Reader(std::string filename, int n_frames_to_read = -1,
12+
G3Reader(const std::string &filename, int n_frames_to_read = -1,
1313
float timeout = -1., bool track_filename = false,
1414
size_t buffersize = 1024*1024);
15-
G3Reader(std::vector<std::string> filenames, int n_frames_to_read = -1,
15+
G3Reader(const std::vector<std::string> &filenames, int n_frames_to_read = -1,
1616
float timeout = -1., bool track_filename = false,
1717
size_t buffersize = 1024*1024);
1818

@@ -21,12 +21,12 @@ class G3Reader : public G3Module {
2121
off_t Tell();
2222

2323
protected:
24-
virtual void StartFile(std::string path);
24+
virtual void StartFile(const std::string &path);
2525
virtual G3FramePtr FillFrame();
2626
bool prefix_file_;
2727
std::string cur_file_;
2828
std::deque<std::string> filename_;
29-
std::shared_ptr<std::istream> stream_;
29+
std::istream stream_;
3030
int fd_;
3131
int n_frames_to_read_;
3232
int n_frames_read_;

core/include/core/G3Writer.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@
99
class G3Writer : public G3Module {
1010
public:
1111
G3Writer(std::string filename,
12-
std::vector<G3Frame::FrameType> streams={}, bool append=false);
12+
std::vector<G3Frame::FrameType> streams={}, bool append=false,
13+
size_t buffersize=1024*1024);
1314
// Writes to file <filename> all frames with types in <streams>.
1415
// If <streams> is empty (default), writes all frames.
1516

1617
void Process(G3FramePtr frame, std::deque<G3FramePtr> &out);
1718
void Flush();
1819
private:
1920
std::string filename_;
20-
std::shared_ptr<std::ostream> stream_;
21+
std::ostream stream_;
2122
std::vector<G3Frame::FrameType> streams_;
2223

2324
SET_LOGGER("G3Writer");

core/src/G3Frame.cxx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,12 +381,10 @@ void G3Frame::blob_encode(struct blob_container &blob)
381381
item_os.flush();
382382
}
383383

384-
template <> void G3Frame::loads(std::shared_ptr<std::istream> &is) { loads(*is); }
385384
template void G3Frame::loads(G3BufferInputStream &);
386385
template void G3Frame::loads(std::istream &);
387386
template void G3Frame::loads(std::istringstream &);
388387

389-
template <> void G3Frame::saves(std::shared_ptr<std::ostream> &os) const { saves(*os); }
390388
template void G3Frame::saves(G3BufferOutputStream &) const;
391389
template void G3Frame::saves(std::ostream &) const;
392390
template void G3Frame::saves(std::ostringstream &) const;

core/src/G3MultiFileWriter.cxx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ class G3MultiFileWriter : public G3Module {
88
public:
99
G3MultiFileWriter(boost::python::object filename,
1010
size_t size_limit,
11-
boost::python::object divide_on = boost::python::object());
11+
boost::python::object divide_on = boost::python::object(),
12+
size_t buffersize=1024*1024);
13+
1214
void Process(G3FramePtr frame, std::deque<G3FramePtr> &out);
1315
std::string CurrentFile() { return current_filename_; }
1416
private:
@@ -18,26 +20,26 @@ class G3MultiFileWriter : public G3Module {
1820
boost::python::object filename_callback_;
1921
std::string current_filename_;
2022
size_t size_limit_;
23+
size_t buffersize_;
2124

2225
std::vector<G3Frame::FrameType> always_break_on_;
2326
boost::python::object newfile_callback_;
2427

25-
std::shared_ptr<std::ostream> stream_;
28+
std::ostream stream_;
2629
std::vector<G3FramePtr> metadata_cache_;
2730
int seqno;
2831

2932
SET_LOGGER("G3MultiFileWriter");
3033
};
3134

3235
G3MultiFileWriter::G3MultiFileWriter(boost::python::object filename,
33-
size_t size_limit, boost::python::object divide_on)
34-
: size_limit_(size_limit), seqno(0)
36+
size_t size_limit, boost::python::object divide_on, size_t buffersize)
37+
: size_limit_(size_limit), buffersize_(buffersize), stream_(nullptr), seqno(0)
3538
{
3639
boost::python::extract<std::string> fstr(filename);
3740

3841
if (fstr.check()) {
3942
filename_ = fstr();
40-
g3_check_output_path(filename_);
4143

4244
if (snprintf(NULL, 0, filename_.c_str(), 0) < 0)
4345
log_fatal("Cannot format filename. Should be "
@@ -77,10 +79,10 @@ G3MultiFileWriter::CheckNewFile(G3FramePtr frame)
7779
{
7880
// If we are already saving data, check file size. Otherwise, open
7981
// a new file unconditionally.
80-
if (stream_ != nullptr) {
82+
if (stream_) {
8183
bool start_new_ = false;
8284

83-
if (g3_ostream_count(stream_) > size_limit_)
85+
if ((size_t)stream_.tellp() > size_limit_)
8486
start_new_ = true;
8587

8688
if (newfile_callback_.ptr() != Py_None &&
@@ -95,7 +97,7 @@ G3MultiFileWriter::CheckNewFile(G3FramePtr frame)
9597
return false;
9698
}
9799

98-
stream_.reset();
100+
stream_.flush();
99101

100102
std::string filename;
101103
if (filename_ != "") {
@@ -111,12 +113,10 @@ G3MultiFileWriter::CheckNewFile(G3FramePtr frame)
111113
} else {
112114
filename = boost::python::extract<std::string>(
113115
filename_callback_(frame, seqno++))();
114-
115-
g3_check_output_path(filename);
116116
}
117117

118118
current_filename_ = filename;
119-
stream_ = g3_ostream_to_path(filename, false, true);
119+
g3_ostream_to_path(stream_, filename, false, buffersize_);
120120

121121
for (auto i = metadata_cache_.begin(); i != metadata_cache_.end(); i++)
122122
(*i)->saves(stream_);
@@ -129,7 +129,7 @@ void G3MultiFileWriter::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
129129
bool new_file(false), meta_cached(false);
130130

131131
if (frame->type == G3Frame::EndProcessing) {
132-
stream_.reset();
132+
stream_.flush();
133133
goto done;
134134
}
135135

@@ -186,8 +186,8 @@ PYBINDINGS("core") {
186186
"python callable as divide_on. This callable will be passed each "
187187
"frame in turn. If it returns True (or something with positive "
188188
"truth-value), a new file will be started at that frame.",
189-
init<object, size_t, optional<object> >((arg("filename"),
190-
arg("size_limit"), arg("divide_on")=object())))
189+
init<object, size_t, optional<object, size_t> >((arg("filename"),
190+
arg("size_limit"), arg("divide_on")=object(), arg("buffersize")=1024*1024)))
191191
.def_readonly("current_file", &G3MultiFileWriter::CurrentFile)
192192
.def_readonly("__g3module__", true)
193193
;

core/src/G3Reader.cxx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,39 @@
22
#include "dataio.h"
33
#include <G3Reader.h>
44

5-
G3Reader::G3Reader(std::string filename, int n_frames_to_read,
5+
G3Reader::G3Reader(const std::string &filename, int n_frames_to_read,
66
float timeout, bool track_filename, size_t buffersize) :
7-
prefix_file_(false), fd_(-1), n_frames_to_read_(n_frames_to_read),
7+
prefix_file_(false), stream_(nullptr), fd_(-1),
8+
n_frames_to_read_(n_frames_to_read),
89
n_frames_read_(0), n_frames_cur_(0), timeout_(timeout),
910
track_filename_(track_filename), buffersize_(buffersize)
1011
{
11-
g3_check_input_path(filename);
1212
StartFile(filename);
1313
}
1414

15-
G3Reader::G3Reader(std::vector<std::string> filename, int n_frames_to_read,
15+
G3Reader::G3Reader(const std::vector<std::string> &filename, int n_frames_to_read,
1616
float timeout, bool track_filename, size_t buffersize) :
17-
prefix_file_(false), fd_(-1), n_frames_to_read_(n_frames_to_read),
17+
prefix_file_(false), stream_(nullptr), fd_(-1),
18+
n_frames_to_read_(n_frames_to_read),
1819
n_frames_read_(0), n_frames_cur_(0), timeout_(timeout),
1920
track_filename_(track_filename), buffersize_(buffersize)
2021
{
2122
if (filename.size() == 0)
2223
log_fatal("Empty file list provided to G3Reader");
2324

24-
for (auto i = filename.begin(); i != filename.end(); i++){
25-
g3_check_input_path(*i);
25+
for (auto i = filename.begin(); i != filename.end(); i++)
2626
filename_.push_back(*i);
27-
}
27+
2828
StartFile(filename_.front());
2929
filename_.pop_front();
3030
}
3131

32-
void G3Reader::StartFile(std::string path)
32+
void G3Reader::StartFile(const std::string &path)
3333
{
3434
log_info("Starting file %s\n", path.c_str());
3535
cur_file_ = path;
3636
n_frames_cur_ = 0;
37-
stream_ = g3_istream_from_path(path, timeout_, buffersize_);
37+
g3_istream_from_path(stream_, path, timeout_, buffersize_);
3838
fd_ = g3_istream_handle(stream_);
3939
}
4040

@@ -79,7 +79,7 @@ void G3Reader::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
7979
// function reacquire the lock, if it was released.
8080
G3PythonContext ctx("G3Reader", false);
8181

82-
while (stream_->peek() == EOF) {
82+
while (stream_.peek() == EOF) {
8383
if (n_frames_cur_ == 0)
8484
log_error("Empty file %s", cur_file_.c_str());
8585
if (filename_.size() > 0) {
@@ -107,14 +107,14 @@ void G3Reader::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
107107
}
108108

109109
off_t G3Reader::Seek(off_t offset) {
110-
if (stream_->peek() == EOF && offset != Tell())
110+
if (stream_.peek() == EOF && offset != Tell())
111111
log_fatal("Cannot seek %s; stream closed at EOF.", cur_file_.c_str());
112-
stream_->seekg(offset, std::ios_base::beg);
112+
stream_.seekg(offset, std::ios_base::beg);
113113
return offset;
114114
}
115115

116116
off_t G3Reader::Tell() {
117-
return stream_->tellg();
117+
return stream_.tellg();
118118
}
119119

120120
PYBINDINGS("core") {

core/src/G3Writer.cxx

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44

55
G3Writer::G3Writer(std::string filename,
66
std::vector<G3Frame::FrameType> streams,
7-
bool append) :
8-
filename_(filename), streams_(streams)
7+
bool append, size_t buffersize) :
8+
filename_(filename), stream_(nullptr), streams_(streams)
99
{
10-
g3_check_output_path(filename);
11-
stream_ = g3_ostream_to_path(filename, append);
10+
g3_ostream_to_path(stream_, filename, append, buffersize);
1211
}
1312

1413
void G3Writer::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
@@ -22,7 +21,7 @@ void G3Writer::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
2221
G3PythonContext ctx("G3Writer", false);
2322

2423
if (frame->type == G3Frame::EndProcessing)
25-
stream_.reset();
24+
stream_.flush();
2625
else if (streams_.size() == 0 ||
2726
std::find(streams_.begin(), streams_.end(), frame->type) !=
2827
streams_.end())
@@ -33,10 +32,7 @@ void G3Writer::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
3332

3433
void G3Writer::Flush()
3534
{
36-
try {
37-
g3_ostream_flush(stream_);
38-
} catch (...) {
39-
}
35+
stream_.flush();
4036
}
4137

4238
PYBINDINGS("core") {
@@ -51,9 +47,10 @@ PYBINDINGS("core") {
5147
"types to the second optional argument (streams). If no streams argument "
5248
"is given, writes all types of frames. If append is set to True, will "
5349
"append frames to its output file rather than overwriting it.",
54-
init<std::string, std::vector<G3Frame::FrameType>, bool>((arg("filename"),
55-
arg("streams")=std::vector<G3Frame::FrameType>(), arg("append")=false)))
56-
.def("Flush", &G3Writer::Flush)
57-
.def_readonly("__g3module__", true)
50+
init<std::string, std::vector<G3Frame::FrameType>, bool, size_t>((arg("filename"),
51+
arg("streams")=std::vector<G3Frame::FrameType>(), arg("append")=false,
52+
arg("buffersize")=1024*1024)))
53+
.def("Flush", &G3Writer::Flush)
54+
.def_readonly("__g3module__", true)
5855
;
5956
}

0 commit comments

Comments
 (0)