cmb-s4 / spt3g_software Goto Github PK
View Code? Open in Web Editor NEWPublic Subset of Analysis Software Developed by the SPT-3G Collaboration
Home Page: https://cmb-s4.github.io/spt3g_software/
License: BSD 2-Clause "Simplified" License
Public Subset of Analysis Software Developed by the SPT-3G Collaboration
Home Page: https://cmb-s4.github.io/spt3g_software/
License: BSD 2-Clause "Simplified" License
CMake fails to find boost_python on my system, even though it seems to be looking in the right directory. I'm running OSX with Macports-installed Boost.
Here is output from CMake:
...
-- Found PythonInterp: /opt/local/bin/python (found version "3.7.2")
-- Found PythonLibs: /opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7m.dylib (found version "3.7.2")
CMake Error at /opt/local/share/cmake-3.13/Modules/FindBoost.cmake:2100 (message):
Unable to find the requested Boost libraries.
Boost version: 1.66.0
Boost include path: /opt/local/include
Could not find the following Boost libraries:
boost_python
Some (but not all) of the required Boost libraries were found. You may
need to install these additional Boost libraries. Alternatively, set
BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT
to the location of Boost.
Call Stack (most recent call first):
CMakeLists.txt:58 (find_package)
-- Boost Geometry Available
-- Could NOT find GSL (missing: GSL_LIBRARIES GSL_INCLUDES)
-- Found FFTW_THREADS: /opt/local/lib/libfftw3_threads.dylib
...
The library in question exists at /opt/local/lib/libboost_python3-mt.dylib
and it looks like there is code in CMakeLists.txt to handle this case: https://github.com/CMB-S4/spt3g_software/blob/master/CMakeLists.txt#L42-L57 but it is looking for libpython3.*\\.so
to get the version number. Replacing that glob with libpython3.*\\.dylib
fixes the issue on OSX-systems but breaks it for everyone else.
m = maps.HealpixSkyMap(16384)
m.angle_to_pixel(0, -pi / 2)
>>> 18446744073709551615
Need a working buffer interface so that numpy.asarray
doesn't require expanding to float64
.
Got errors like the ones shown below. On gcc version 12.2.0, boost 1.74.
Had to add -Wno-mismatched-new-delete flag. Happy to PR -- I don't know how safe it is to just add -Wno flags for everyone whenever things like this happen. Probably this is transient due to older boost / newer gcc.
In file included from /home/mhasse/code/public/anaconda3/envs/py38/include/boost/checked_delete.hpp:15,
from /home/mhasse/code/public/anaconda3/envs/py38/include/boost/smart_ptr/detail/sp_counted_impl.hpp:27,
from /home/mhasse/code/public/anaconda3/envs/py38/include/boost/smart_ptr/detail/shared_count.hpp:27,
from /home/mhasse/code/public/anaconda3/envs/py38/include/boost/smart_ptr/shared_ptr.hpp:17:
In function ‘void boost::checked_delete(T*) [with T = float]’,
inlined from ‘boost::detail::shared_count::shared_count(Y*) [with Y = float]’ at /home/mhasse/code/public/anaconda3/envs/py38/include/boost/smart_ptr/detail/shared_count.hpp:154:34,
inlined from ‘void boost::detail::sp_pointer_construct(boost::shared_ptr<X>*, Y*, shared_count&) [with T = float; Y = float]’ at /home/mhasse/code/public/anaconda3/envs/py38/include/boost/smart_ptr/shared_ptr.hpp:279:20,
inlined from ‘boost::shared_ptr<T>::shared_ptr(Y*) [with Y = float; T = float]’ at /home/mhasse/code/public/anaconda3/envs/py38/include/boost/smart_ptr/shared_ptr.hpp:373:44,
inlined from ‘static G3TimestreamPtr G3Timestream::G3TimestreamPythonHelpers::timestream_from_iterable(boost::python::api::object, G3Timestream::TimestreamUnits)’ at /home/mhasse/work/code/simonso/spt3g_software/core/src/G3Timestream.cxx:929:31:
/home/mhasse/code/public/anaconda3/envs/py38/include/boost/core/checked_delete.hpp:36:5: error: ‘void operator delete(void*, std::size_t)’ called on pointer returned from a mismatched allocation function [-Werror=mismatched-new-delete]
36 | delete x;
| ^~~~~~~~
G3SkyMap mask objects, which are essentially std::vector<bool>
objects with some extra features, are packed on disk as one byte per element, rather than 1 bit per element as one would expect. This is rather inefficient, especially when masks are used as input arguments to pipeline modules (and therefore end up in memory-intensive G3PipelineInfo
frames all over the place).
Consider storing boolean masks for healpix maps in a sparse data structure to save memory with maps with small sky coverage (<10%).
We should find a replacement for imp.load_dynamic
in spt3g.core.load_pybindings
. The imp
module will be removed in python 3.12.
Compiling with the latest version of boost now produces the following warning:
warning "The minimum language standard to use Boost.Math will be C++14 starting in July 2023 (Boost 1.82 release)
We should update the source to comply for the time being. In the long run, we'll want to put more effort into migrating away from Boost.
Create empty file:
In [3]: wr = core.G3Writer('empty.g3')
In [4]: del wr
Create non-empty file:
In [5]: fr = core.G3Frame()
In [6]: fr['A'] = 0
In [7]: wr = core.G3Writer('full.g3')
In [8]: wr(fr)
Out[8]: [<spt3g.core.G3Frame at 0x7fd5034ac450>]
In [9]: del wr
Read empty file only:
In [10]: p = core.G3Pipeline()
In [11]: p.Add(core.G3Reader, filename = ['empty.g3'])
In [12]: p.Run() #runs fine, no errors
Read full file first and then empty file:
In [13]: p = core.G3Pipeline()
In [14]: p.Add(core.G3Reader, filename = ['full.g3', 'empty.g3'])
In [15]: p.Run()
ERROR (G3Reader) 18-Jan-2024:11:11:52 CST: Exception raised while reading file empty.g3 (G3Reader.cxx:98 in virtual void G3Reader::Process(G3FramePtr, std::deque<boost::shared_ptr<G3Frame> >&))
WARN (Unknown) 18-Jan-2024:11:11:52 CST: Exception in module "spt3g.core.G3Reader" (N6cereal9ExceptionE): Failed to read 1 bytes from input stream! Read 0 (G3Pipeline.cxx:119 in size_t {anonymous}::PushFrameThroughQueue(G3FramePtr, bool, bool, rusage&, std::vector<{anonymous}::G3Pipeline_mod_data>&, std::vector<{anonymous}::G3Pipeline_mod_data>::iterator, int&, std::deque<{anonymous}::G3Pipeline_proc_data>&, G3FramePtr&))
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-15-ecb398338890> in <module>
----> 1 p.Run()
RuntimeError: Failed to read 1 bytes from input stream! Read 0
Note: other combinations (read full file only, read empty file first and full file second) also work fine.
See potential implementation in #69, which can be split off into a separate PR.
numpy repr of long arrays is abbreviated:
>>> numpy.zeros(10000)
array([0, 0, 0, ..., 0, 0, 0])
But G3Vector types just print every single element, making it easy to flood an interactive session with pages of unwanted output. Is there any objection to implementing a similar abbreviation in vec_repr? Since repr does not use Description(), the latter could continue to present a complete dump of the vector, in case that's needed.
I find timestamps on the core logging messages very useful for rudimentary profiling, especially for long running scripts. While the profile
option for G3Pipeline.Run()
provides similar functionality, it's only useful for scripts that are entirely pipeline-based, which is often not the case. Moreover, timestamps on log messages make it easy to track the progress of a script in real-time, rather than waiting until it has finished running to find out how long it took.
I would like to propose enabling timestamps by default for the G3PrintfLogger
class, or at the very least making it easier to turn that feature on quickly (e.g. with a root level function that doesn't require remembering where in the depths of the logging code that attribute is set).
G3 numeric types (and their vector equivalents) all seem to have some broken arithmetic operations, either with numpy and python scalars, or even with themselves. Here is a sampling of things that raise TypeError: unsupported operand...
:
G3Int + G3Int
int + G3Int
G3Int + int
G3VectorInt + int
G3VectorDouble + G3VectorDouble
float * G3VectorDouble
float + G3VectorDouble
G3VectorDouble + float
G3VectorComplexDouble * float
Notably, the follwing do work:
np.float64 * G3VectorDouble
G3VectorDouble * np.float64
G3VectorDouble * float
G3VectorComplexDouble * float64
Instantiating G3Timestream from a numpy array works, but only if the buffer is close-packed in memory. Passing a view into an array, where strides are not 1, yields a segfault.
import spt3g
from spt3g import core
import numpy as np
print(spt3g.version.gitrevision)
for n in [1, 2, -2]:
print(n)
data = np.zeros(100, 'float64')[::n]
print(core.G3Timestream(data))
Results in:
c45570b13da0cdaaab0b519344892d5053f99b20
1
100 samples at inf Hz
2
Segmentation fault (core dumped)
Expected result: the non-trivial stride should either quietly work, or raise an exception.
In:
print(fr["Wpol"]["QQ"].flat_pol)
w2 = fr['Wpol'].clone(False)
print(w2['QQ'].flat_pol)
Out:
True
False
When we save a flat-sky map in a FITS file via maps.fitsio.save_skymap_fits
, the default option for the argument compress
is 'GZIP_2'
. This compression scheme is supposed to be lossless, but that does not seem to be the case when I tested the compression scheme on an SPT-3G winter field coadd.
Here is an example:
In[4]: frame = core.G3File(path_to_a_coadd).next()
# Default save
In [5]: maps.fitsio.save_skymap_fits(output_path, frame["T"], Q=frame["Q"], U=frame["U"])
In [6]: frame_debug = maps.fitsio.load_skymap_fits(output_path)
In [7]: numpy.allclose(frame["T"], frame_debug["T"])
Out[7]: False
# No-compression save
In [18]: maps.fitsio.save_skymap_fits(output_path, frame["T"], Q=frame["Q"], U=frame["U"], compress=False, overwrite=True)
In [19]: frame_debug = maps.fitsio.load_skymap_fits(output_path)
In [20]: numpy.allclose(frame["T"], frame_debug["T"])
Out[20]: True
I'm finding that numpy is not detected when cmake is run a second time after the initial setup. This happens on my mac, but I don't think the issue is OS-specific.
The first time cmake is run I get this:
$ cmake ..
...
-- Found Python: /usr/local/Frameworks/Python.framework/Versions/3.11/bin/python3.11 (found version "3.11.4") found components: Interpreter Development Development.Module Development.Embed
-- Found NumPy: /usr/local/lib/python3.11/site-packages/numpy/core/include
-- Found SciPy: FOUND
-- Python modules will be installed to /usr/local/lib/python3.11/site-packages
...
The second time I get this:
$ cmake ..
-- Found NumPy: NOT FOUND
-- Found SciPy: FOUND
-- Python modules will be installed to /usr/local/lib/python3.11/site-packages
...
It would be very useful to have sequential version codes available through the python interface. In so3g we will often need to require / check for some minimum spt3g version that implements a feature or bug-fix.
I know it's onerous to be constantly tagging and releasing. If the commit-differential tags like "v0.1.2+23-g7ab341" are available, somehow, then that's sufficient to bridge even large gaps between releases (for my purposes).
Building with #95 breaks on the private SouthPoleTelescope/spt3g_software repo:
[ 79%] Building CXX object todfilter/CMakeFiles/todfilter.dir/src/fftutils.cpp.o
/github/actions-runner/_work/spt3g_software/spt3g_software/todfilter/src/fftutils.cpp: In function ‘void fft_filter_mem_friendly(const G3TimestreamMap&, const G3VectorComplexDouble&, G3TimestreamMap&, bool, G3MapDoubleConstPtr)’:
/github/actions-runner/_work/spt3g_software/spt3g_software/todfilter/src/fftutils.cpp:307:30: error: use of deleted function ‘G3TimestreamMap& G3TimestreamMap::operator=(const G3TimestreamMap&)’
out_data = G3TimestreamMap();
^
In file included from /github/actions-runner/_work/spt3g_software/spt3g_software/todfilter/include/todfilter/numericutils.h:9,
from /github/actions-runner/_work/spt3g_software/spt3g_software/todfilter/src/fftutils.cpp:3:
/github/actions-runner/_work/spt3g_software/spt3g_software/core/include/core/G3Timestream.h:176:7: note: ‘G3TimestreamMap& G3TimestreamMap::operator=(const G3TimestreamMap&)’ is implicitly declared as deleted because ‘G3TimestreamMap’ declares a move constructor or move assignment operator
class G3TimestreamMap : public G3FrameObject,
^~~~~~~~~~~~~~~
/github/actions-runner/_work/spt3g_software/spt3g_software/todfilter/src/fftutils.cpp: In function ‘void fft_filter_mem_friendly_w_multi_filters(G3TimestreamMap&, G3VectorDouble&, G3MapVectorComplexDouble&, G3TimestreamMap&)’:
/github/actions-runner/_work/spt3g_software/spt3g_software/todfilter/src/fftutils.cpp:433:43: error: use of deleted function ‘G3TimestreamMap& G3TimestreamMap::operator=(const G3TimestreamMap&)’
filtered_ts_map = G3TimestreamMap();
^
At global scope:
cc1plus: error: unrecognized command line option ‘-Wno-self-assign-overloaded’ [-Werror]
cc1plus: error: unrecognized command line option ‘-Wno-constant-conversion’ [-Werror]
cc1plus: error: unrecognized command line option ‘-Wno-deprecated-register’ [-Werror]
cc1plus: error: unrecognized command line option ‘-Wno-unknown-warning-option’ [-Werror]
cc1plus: all warnings being treated as errors
gmake[2]: *** [todfilter/CMakeFiles/todfilter.dir/build.make:115: todfilter/CMakeFiles/todfilter.dir/src/fftutils.cpp.o] Error 1
gmake[2]: *** Waiting for unfinished jobs....
gmake[1]: *** [CMakeFiles/Makefile2:10[88](https://github.com/SouthPoleTelescope/spt3g_software/actions/runs/4684229589/jobs/8300157535#step:7:89): todfilter/CMakeFiles/todfilter.dir/all] Error 2
gmake: *** [Makefile:141: all] Error 2
Error: Process completed with exit code 2.
Is there a fast way to convert between arrays of G3VectorTime and numpy float arrays? I find myself writing this a lot:
g3times = core.G3VectorTime([core.G3Time(t * core.G3Units.s) for t in timestamps])
and that's no fun. I am hoping for something like:
g3times = core.G3VectorTime(timestamps * core.G3Units.s)
timestamps = np.array(g3times) / core.G3Units.s
Cannot build documentation due to removal of deprecated functions inspect.getargspec()
and inspect.formatargspec()
in Python 3.11.
Hello @arahlin , just a heads up that the recent change to Spt3gBoostPython.cmake
:
has broken the ability for the so3g
package to get boost linking information by using the build/cmake-install/Spt3gConfig.cmake
file. Can you give more information about what problem that was trying to fix? I have not yet dug into this any deeper to see why the various Boost::filesystem
, Boost::python
, etc are no longer available, but thought I would try to get more information about this change first.
Slicing of G3Timetreams in python differs a bit from np.array slicing.
In python you are allowed to slice lists with stop
and step
being larger than the size of the array:
>>> import numpy as np
>>> x = np.arange(5.)
>>> x[:10]
array([0., 1., 2., 3., 4.])
>>> x[::10]
array([0.])
However G3Timestreams produce fatal errors when trying the same thing:
>>> from spt3g import core
>>> import numpy as np
>>> x = core.G3Timestream(np.arange(5.))
>>> x[:10]
FATAL (G3Timestream): Stop index 10 out of range (G3Timestream.cxx:822 in G3TimestreamPtr {anonymous}::G3Timestream_getslice(const G3Timestream&, boost::python::slice))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/mnt/so1/shared/software/spt3g_software/200627/build/spt3g/core/timestreamextensions.py", line 13, in G3Timestream_getitem
it = x._cxxslice(y)
RuntimeError: Stop index 10 out of range (in G3TimestreamPtr {anonymous}::G3Timestream_getslice(const G3Timestream&, boost::python::slice))
>>> x[::10]
FATAL (G3Timestream): Step index 10 out of range (G3Timestream.cxx:824 in G3TimestreamPtr {anonymous}::G3Timestream_getslice(const G3Timestream&, boost::python::slice))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/mnt/so1/shared/software/spt3g_software/200627/build/spt3g/core/timestreamextensions.py", line 13, in G3Timestream_getitem
it = x._cxxslice(y)
RuntimeError: Step index 10 out of range (in G3TimestreamPtr {anonymous}::G3Timestream_getslice(const G3Timestream&, boost::python::slice))
It would be great if we could change G3Timestream so slicing behavior is consistent with numpy arrays.
In file included from /Users/cweaver/Work/CMB-S4/spt3g_software-public-git/core/src/G3Vector.cxx:3:
In file included from /Users/cweaver/Work/CMB-S4/spt3g_software-public-git/core/include/core/container_pybindings.h:5:
In file included from /Users/cweaver/Work/CMB-S4/spt3g_software-public-git/core/include/core/G3Map.h:6:
In file included from /Users/cweaver/Work/CMB-S4/spt3g_software-public-git/core/include/core/G3Quat.h:6:
In file included from /usr/local/include/boost/math/quaternion.hpp:14:
/usr/local/include/boost/math/tools/config.hpp:23:6: error: "The minimum language standard to use Boost.Math will be C++14 starting in July 2023 (Boost 1.82 release)" [-Werror,-W#warnings]
# warning "The minimum language standard to use Boost.Math will be C++14 starting in July 2023 (Boost 1.82 release)"
^
1 error generated.
The simplest solution is to change the language mode to C++14, but I would like to first verify that this will be available on all platforms we consider supported.
Currently these use int32, which is inconsistent with G3VectorInt.
I suspect the recent buffs for buffer protocol may have broken G3VectorTime constructor. See below.
>>> from spt3g import core
>>> import numpy as np
>>> t0 = core.G3VectorTime(np.array([100000000, 200000000]))
>>> t0
spt3g.core.G3VectorTime([01-Jan-1970:00:00:01.000000000, 01-Jan-1970:00:00:02.000000000])
>>> t1 = core.G3VectorTime(t0)
>>> t1
spt3g.core.G3VectorTime([01-Jan-1970:00:00:01.000000000, 01-Jan-1970:00:00:02.000000000, 01-Jan-1970:00:00:00.000005290, 11-Jan-1970:21:29:27.377759360])
>>> len(t0), len(t1)
(2, 4)
Expected result: t1 should be a copy of t0.
Couple other observations:
It's often convenient to install packages rather than running them from the build directory. Can we get Makefile targets to help with that?
Using an installed Python package is one thing -- building against installed lib/include is another. Probably the installed Python package is the most immediately useful.
When creating G3VectorQuat from numpy array, it seems to check for shape (-1, 4) but does not handle non-trivial strides.
Consider test program:
from spt3g import core
import numpy as np
quats = np.array([[1., 2., 3., 4., 5.], # a
[0., 0., 0., 0., 0.], # b
[0., 0., 0., 0., 0.], # c
[0., 0., 0., 0., 0.]]) # d
for test in [
quats, # bad shape
quats[:,:4], # ok shape, non-trivial strides
quats.T, # ok shape, non-trivial strides
quats.T.copy(), # ok shape, trivial strides
]:
try:
print(repr(core.G3VectorQuat(test)))
except TypeError:
print('(TypeError)')
Produces output (on version 0.3-71-g613d0d4):
(TypeError)
(TypeError)
spt3g.core.G3VectorQuat([(1,2,3,4), (5,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0)])
spt3g.core.G3VectorQuat([(1,0,0,0), (2,0,0,0), (3,0,0,0), (4,0,0,0), (5,0,0,0)])
But expected output is:
(TypeError)
spt3g.core.G3VectorQuat([(1,2,3,4), (0,0,0,0), (0,0,0,0), (0,0,0,0)])
spt3g.core.G3VectorQuat([(1,0,0,0), (2,0,0,0), (3,0,0,0), (4,0,0,0), (5,0,0,0)])
spt3g.core.G3VectorQuat([(1,0,0,0), (2,0,0,0), (3,0,0,0), (4,0,0,0), (5,0,0,0)])
OR
(TypeError)
(TypeError)
(TypeError)
spt3g.core.G3VectorQuat([(1,0,0,0), (2,0,0,0), (3,0,0,0), (4,0,0,0), (5,0,0,0)])
(In the latter case, the code would simply rejecting anything that doesn't have simple C ordering.)
Mapmaker currently assumes that pol_angle
is fixed throughout the observation.
In [1]: from spt3g.core import quat, G3VectorQuat
...: import numpy as np
...: q = quat(1.0, 0.0, 0.0, 0.0)
...: v = G3VectorQuat([q, q, q, q])
In [2]: abs(v) # the builtin function has the correct behavior
Out[2]: spt3g.core.G3VectorDouble([1, 1, 1, 1])
In [3]: np.abs(v) # expect this to return a 1-d numpy array
Out[3]:
array([[1., 0., 0., 0.],
[1., 0., 0., 0.],
[1., 0., 0., 0.],
[1., 0., 0., 0.]])
Useful for allowing fseek on compressed frame files.
@arahlin I just tried to build spt3g on a new computer and it looks like we're missing src/maputils.cpp
. Did it not get added to your recent commit?
-- Found GSL: /usr/lib/x86_64-linux-gnu/libgsl.so;/usr/lib/x86_64-linux-gnu/libgslcblas.so
-- Found FFTW_THREADS: /usr/lib/x86_64-linux-gnu/libfftw3_threads.so
-- Found FFTW: /usr/lib/x86_64-linux-gnu/libfftw3.so
-- Could NOT find HDF5 (missing: HDF5_LIBRARIES HDF5_INCLUDES)
-- Found MPI_C: /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi.so (found version "3.1")
-- Found MPI_CXX: /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi_cxx.so (found version "3.1")
-- Found MPI: TRUE (found version "3.1")
-- + calibration
-- + coordinateutils
-- + core
-- Found Flac: /usr/lib/x86_64-linux-gnu/libFLAC.so
-- + dfmux
-- Found NetCDF: /usr/lib/x86_64-linux-gnu/libnetcdf.so
-- + gcp
-- Configuring done
CMake Error at coordinateutils/CMakeLists.txt:7 (add_library):
Cannot find source file:
src/maputils.cpp
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
.hxx .in .txx
CMake Error: CMake can not determine linker language for target: coordinateutils
CMake Error: Cannot determine link language for target "coordinateutils".
-- Generating done
-- Build files have been written to: /home/mcmlab/software/spt3g_software/build
Currently disabled as of PR #44, needs attention longer term.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.