opencosmo 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opencosmo-1.0.0/LICENSE.md +11 -0
- opencosmo-1.0.0/PKG-INFO +182 -0
- opencosmo-1.0.0/README.md +160 -0
- opencosmo-1.0.0/pyproject.toml +121 -0
- opencosmo-1.0.0/src/opencosmo/__init__.py +26 -0
- opencosmo-1.0.0/src/opencosmo/analysis/__init__.py +42 -0
- opencosmo-1.0.0/src/opencosmo/analysis/cli.py +32 -0
- opencosmo-1.0.0/src/opencosmo/analysis/diffsky.py +20 -0
- opencosmo-1.0.0/src/opencosmo/analysis/install/__init__.py +5 -0
- opencosmo-1.0.0/src/opencosmo/analysis/install/install.py +91 -0
- opencosmo-1.0.0/src/opencosmo/analysis/install/source.py +52 -0
- opencosmo-1.0.0/src/opencosmo/analysis/install/specs/__init__.py +50 -0
- opencosmo-1.0.0/src/opencosmo/analysis/install/specs/diffsky.json +39 -0
- opencosmo-1.0.0/src/opencosmo/analysis/install/specs/vizualize.json +16 -0
- opencosmo-1.0.0/src/opencosmo/analysis/install/versions.py +23 -0
- opencosmo-1.0.0/src/opencosmo/analysis/yt_utils.py +282 -0
- opencosmo-1.0.0/src/opencosmo/analysis/yt_viz.py +543 -0
- opencosmo-1.0.0/src/opencosmo/collection/__init__.py +16 -0
- opencosmo-1.0.0/src/opencosmo/collection/io.py +85 -0
- opencosmo-1.0.0/src/opencosmo/collection/lightcone/__init__.py +4 -0
- opencosmo-1.0.0/src/opencosmo/collection/lightcone/healpix_map.py +1075 -0
- opencosmo-1.0.0/src/opencosmo/collection/lightcone/lightcone.py +1161 -0
- opencosmo-1.0.0/src/opencosmo/collection/lightcone/stack.py +222 -0
- opencosmo-1.0.0/src/opencosmo/collection/protocols.py +53 -0
- opencosmo-1.0.0/src/opencosmo/collection/simulation/__init__.py +3 -0
- opencosmo-1.0.0/src/opencosmo/collection/simulation/simulation.py +477 -0
- opencosmo-1.0.0/src/opencosmo/collection/structure/__init__.py +5 -0
- opencosmo-1.0.0/src/opencosmo/collection/structure/evaluate.py +218 -0
- opencosmo-1.0.0/src/opencosmo/collection/structure/handler.py +290 -0
- opencosmo-1.0.0/src/opencosmo/collection/structure/io.py +242 -0
- opencosmo-1.0.0/src/opencosmo/collection/structure/structure.py +1314 -0
- opencosmo-1.0.0/src/opencosmo/column/__init__.py +4 -0
- opencosmo-1.0.0/src/opencosmo/column/cache.py +300 -0
- opencosmo-1.0.0/src/opencosmo/column/column.py +633 -0
- opencosmo-1.0.0/src/opencosmo/column/evaluate.py +131 -0
- opencosmo-1.0.0/src/opencosmo/column/stock.py +145 -0
- opencosmo-1.0.0/src/opencosmo/cosmology.py +80 -0
- opencosmo-1.0.0/src/opencosmo/dataset/__init__.py +3 -0
- opencosmo-1.0.0/src/opencosmo/dataset/build.py +116 -0
- opencosmo-1.0.0/src/opencosmo/dataset/dataset.py +854 -0
- opencosmo-1.0.0/src/opencosmo/dataset/derived.py +189 -0
- opencosmo-1.0.0/src/opencosmo/dataset/evaluate.py +185 -0
- opencosmo-1.0.0/src/opencosmo/dataset/formats.py +110 -0
- opencosmo-1.0.0/src/opencosmo/dataset/handler.py +203 -0
- opencosmo-1.0.0/src/opencosmo/dataset/im.py +31 -0
- opencosmo-1.0.0/src/opencosmo/dataset/mpi.py +50 -0
- opencosmo-1.0.0/src/opencosmo/dataset/state.py +622 -0
- opencosmo-1.0.0/src/opencosmo/evaluate.py +67 -0
- opencosmo-1.0.0/src/opencosmo/file.py +108 -0
- opencosmo-1.0.0/src/opencosmo/header.py +374 -0
- opencosmo-1.0.0/src/opencosmo/index/__init__.py +35 -0
- opencosmo-1.0.0/src/opencosmo/index/build.py +31 -0
- opencosmo-1.0.0/src/opencosmo/index/get.py +73 -0
- opencosmo-1.0.0/src/opencosmo/index/in_range.py +74 -0
- opencosmo-1.0.0/src/opencosmo/index/mask.py +58 -0
- opencosmo-1.0.0/src/opencosmo/index/project.py +56 -0
- opencosmo-1.0.0/src/opencosmo/index/take.py +139 -0
- opencosmo-1.0.0/src/opencosmo/index/unary.py +61 -0
- opencosmo-1.0.0/src/opencosmo/io/__init__.py +20 -0
- opencosmo-1.0.0/src/opencosmo/io/file.py +152 -0
- opencosmo-1.0.0/src/opencosmo/io/io.py +274 -0
- opencosmo-1.0.0/src/opencosmo/io/mpi.py +473 -0
- opencosmo-1.0.0/src/opencosmo/io/parquet.py +90 -0
- opencosmo-1.0.0/src/opencosmo/io/protocols.py +53 -0
- opencosmo-1.0.0/src/opencosmo/io/schema.py +48 -0
- opencosmo-1.0.0/src/opencosmo/io/serial.py +33 -0
- opencosmo-1.0.0/src/opencosmo/io/updaters.py +77 -0
- opencosmo-1.0.0/src/opencosmo/io/verify.py +164 -0
- opencosmo-1.0.0/src/opencosmo/io/writer.py +169 -0
- opencosmo-1.0.0/src/opencosmo/mpi.py +18 -0
- opencosmo-1.0.0/src/opencosmo/parameters/__init__.py +12 -0
- opencosmo-1.0.0/src/opencosmo/parameters/cosmology.py +74 -0
- opencosmo-1.0.0/src/opencosmo/parameters/diffsky.py +15 -0
- opencosmo-1.0.0/src/opencosmo/parameters/dtype.py +23 -0
- opencosmo-1.0.0/src/opencosmo/parameters/file.py +83 -0
- opencosmo-1.0.0/src/opencosmo/parameters/hacc.py +276 -0
- opencosmo-1.0.0/src/opencosmo/parameters/origin.py +8 -0
- opencosmo-1.0.0/src/opencosmo/parameters/parameters.py +52 -0
- opencosmo-1.0.0/src/opencosmo/parameters/units.py +70 -0
- opencosmo-1.0.0/src/opencosmo/spatial/__init__.py +5 -0
- opencosmo-1.0.0/src/opencosmo/spatial/builders.py +118 -0
- opencosmo-1.0.0/src/opencosmo/spatial/check.py +102 -0
- opencosmo-1.0.0/src/opencosmo/spatial/healpix.py +50 -0
- opencosmo-1.0.0/src/opencosmo/spatial/models.py +26 -0
- opencosmo-1.0.0/src/opencosmo/spatial/octree.py +268 -0
- opencosmo-1.0.0/src/opencosmo/spatial/protocols.py +70 -0
- opencosmo-1.0.0/src/opencosmo/spatial/region.py +390 -0
- opencosmo-1.0.0/src/opencosmo/spatial/tree.py +245 -0
- opencosmo-1.0.0/src/opencosmo/spatial/utils.py +33 -0
- opencosmo-1.0.0/src/opencosmo/units/__init__.py +13 -0
- opencosmo-1.0.0/src/opencosmo/units/convention.py +14 -0
- opencosmo-1.0.0/src/opencosmo/units/converters.py +209 -0
- opencosmo-1.0.0/src/opencosmo/units/get.py +192 -0
- opencosmo-1.0.0/src/opencosmo/units/handler.py +217 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, OpenCosmo Project All rights reserved.
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
8
|
+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
9
|
+
Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
10
|
+
|
|
11
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
opencosmo-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: opencosmo
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: OpenCosmo Python Toolkit
|
|
5
|
+
Author: Patrick Wells, Will Hicks, Patricia Larsen, Michael Buehlmann
|
|
6
|
+
Author-email: Patrick Wells <pwells@anl.gov>, Will Hicks <whicks@anl.gov>, Patricia Larsen <prlarsen@anl.gov>, Michael Buehlmann <mbuehlmann@anl.gov>
|
|
7
|
+
Requires-Dist: h5py>=3.12.1,<4.0.0
|
|
8
|
+
Requires-Dist: astropy>=7.2.0,<8.0.0
|
|
9
|
+
Requires-Dist: pydantic>=2.10.6,<3.0.0
|
|
10
|
+
Requires-Dist: hdf5plugin>=5.0.0,<6.0.0
|
|
11
|
+
Requires-Dist: healpy>=1.18.1,<2.0.0
|
|
12
|
+
Requires-Dist: healsparse==1.11.1
|
|
13
|
+
Requires-Dist: deprecated>=1.2.18,<2.0.0
|
|
14
|
+
Requires-Dist: numpy>=2.0,<2.4
|
|
15
|
+
Requires-Dist: click>=8.2.1,<9.0.0
|
|
16
|
+
Requires-Dist: numba>=0.62.1
|
|
17
|
+
Requires-Dist: rustworkx>=0.17.1
|
|
18
|
+
Requires-Dist: pyarrow>=21.0.0 ; extra == 'io'
|
|
19
|
+
Requires-Python: >=3.11, <3.15
|
|
20
|
+
Provides-Extra: io
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
<h1 align="center">
|
|
24
|
+
<picture>
|
|
25
|
+
<source srcset="https://raw.githubusercontent.com/ArgonneCPAC/opencosmo/main/branding/opencosmo_dark.png" media="(prefers-color-scheme: dark)">
|
|
26
|
+
<source srcset="https://raw.githubusercontent.com/ArgonneCPAC/opencosmo/main/branding/opencosmo_light.png" media="(prefers-color-scheme: light)">
|
|
27
|
+
<img src="https://raw.githubusercontent.com/ArgonneCPAC/opencosmo/main/branding/opencosmo_light.png" alt="OpenCosmo">
|
|
28
|
+
</picture>
|
|
29
|
+
</h1><br>
|
|
30
|
+
|
|
31
|
+
[](https://github.com/ArgonneCPAC/OpenCosmo/actions/workflows/merge.yaml)
|
|
32
|
+
[](https://pypi.org/project/opencosmo/)
|
|
33
|
+
[](https://anaconda.org/conda-forge/opencosmo)
|
|
34
|
+
[](https://github.com/ArgonneCPAC/OpenCosmo/blob/main/LICENSE.md)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
The OpenCosmo Python Toolkit provides utilities for reading, writing and manipulating data from cosmological simulations produced by the Cosmolgical Physics and Advanced Computing (CPAC) group at Argonne National Laboratory. It can be used to work with smaller quantities data retrieved with the CosmoExplorer, as well as the much larget datasets these queries draw from. The OpenCosmo toolkit integrates with standard tools such as AstroPy, and allows you to manipulate data in a fully-consistent cosmological context.
|
|
38
|
+
|
|
39
|
+
### Installation
|
|
40
|
+
|
|
41
|
+
The OpenCosmo library is available for Python 3.11 and up on Linux and MacOS (and Windows via [WSL](https://learn.microsoft.com/en-us/windows/wsl/setup/environment)). It can be installed easily with `pip`:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install opencosmo
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
There's a good chance the default version of Python on your system is less than 3.11. Whether or not this is the case, we recommend installing `opencosmo` into a virtual environment. If you're using [Conda](https://docs.conda.io/projects/conda/en/stable/user-guide/getting-started.html), you can create a new environment and install `opencosmo` into it automatically:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
conda create -n opencosmo_env conda-forge::opencosmo
|
|
52
|
+
conda activate opencosmo_env
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
or if you already have a virtual environment to use:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
conda install conda-forge::opencosmo
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
If you plan to use `opencosmo` in a Jupyter notebook, you can install the `ipykernel` package to make the environment available as a kernel:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install ipykernel # can also be installed with conda
|
|
65
|
+
python -m ipykernel install --user --name=opencosmo
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Be sure you have run the "activate" command shown above before running the `ipykernel` command.
|
|
69
|
+
|
|
70
|
+
## Getting Started
|
|
71
|
+
|
|
72
|
+
To get started, download the "haloproperites.hdf5" from the [OpenCosmo Google Drive](https://drive.google.com/drive/folders/1CYmZ4sE-RdhRdLhGuYR3rFfgyA3M1mU-?usp=sharing). This file contains properties of dark-matter halos from a small hydrodynamical simulation run with HACC. You can easily open the data with the `open` command:
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
import opencosmo as oc
|
|
76
|
+
|
|
77
|
+
dataset = oc.open("haloproperties.hdf5")
|
|
78
|
+
print(dataset)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
OpenCosmo Dataset (length=237441)
|
|
83
|
+
Cosmology: FlatLambdaCDM(name=None, H0=<Quantity 67.66 km / (Mpc s)>, Om0=0.3096446816186967, Tcmb0=<Quantity 0. K>, Neff=3.04, m_nu=None, Ob0=0.04897468161869667)
|
|
84
|
+
First 10 rows:
|
|
85
|
+
block fof_halo_1D_vel_disp fof_halo_center_x ... sod_halo_sfr unique_tag
|
|
86
|
+
km / s Mpc ... solMass / yr
|
|
87
|
+
int32 float32 float32 ... float32 int64
|
|
88
|
+
----- -------------------- ----------------- ... ------------ ----------
|
|
89
|
+
0 32.088795 1.4680439 ... -101.0 21674
|
|
90
|
+
0 41.14525 0.19616994 ... -101.0 44144
|
|
91
|
+
0 73.82962 1.5071135 ... 3.1447952 48226
|
|
92
|
+
0 31.17231 0.7526525 ... -101.0 58472
|
|
93
|
+
0 23.038841 5.3246417 ... -101.0 60550
|
|
94
|
+
0 37.071426 0.5153746 ... -101.0 537760
|
|
95
|
+
0 26.203058 2.1734374 ... -101.0 542858
|
|
96
|
+
0 78.7636 2.1477687 ... 0.0 548994
|
|
97
|
+
0 37.12636 6.9660196 ... -101.0 571540
|
|
98
|
+
0 58.09235 6.072006 ... 1.5439711 576648
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The `open` function returns a `Dataset` object, which holds the raw data as well as information about the simulation. You can easily access the data and cosmology as Astropy objects:
|
|
102
|
+
```python
|
|
103
|
+
dataset.data
|
|
104
|
+
dataset.cosmology
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The first will return an astropy table of the data, with all associated units already applied. The second will return the astropy cosmology object that represents the cosmology the simulation was run with.
|
|
108
|
+
|
|
109
|
+
### Basic Querying
|
|
110
|
+
|
|
111
|
+
Although you can access data directly, `opencosmo` provides tools for querying and transforming the data in a fully cosmology-aware context. For example, suppose we wanted to plot the concentration-mass relationship for the halos in our simulation above a certain mass. One way to perform this would be as follows:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
dataset = dataset
|
|
115
|
+
.filter(oc.col("fof_halo_mass") > 1e13)
|
|
116
|
+
.take(1000, at="random")
|
|
117
|
+
.select(("fof_halo_mass", "sod_halo_cdelta"))
|
|
118
|
+
|
|
119
|
+
print(dataset)
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
OpenCosmo Dataset (length=1000)
|
|
125
|
+
Cosmology: FlatLambdaCDM(name=None, H0=<Quantity 67.66 km / (Mpc s)>, Om0=0.3096446816186967, Tcmb0=<Quantity 0. K>, Neff=3.04, m_nu=None, Ob0=0.04897468161869667)
|
|
126
|
+
First 10 rows:
|
|
127
|
+
fof_halo_mass sod_halo_cdelta
|
|
128
|
+
solMass
|
|
129
|
+
float32 float32
|
|
130
|
+
---------------- ---------------
|
|
131
|
+
11220446000000.0 4.5797048
|
|
132
|
+
17266723000000.0 7.4097505
|
|
133
|
+
51242150000000.0 1.8738283
|
|
134
|
+
70097712000000.0 4.2764015
|
|
135
|
+
51028305000000.0 2.678151
|
|
136
|
+
11960567000000.0 3.9594727
|
|
137
|
+
15276915000000.0 5.793542
|
|
138
|
+
16002001000000.0 2.4318497
|
|
139
|
+
47030307000000.0 3.7146702
|
|
140
|
+
15839942000000.0 3.245569
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
We could then plot the data, or perform further transformations. This is cool on its own, but the real power of `opencosmo` comes from its ability to work with different data types. Go ahead and download the "haloparticles" file from the [OpenCosmo Google Drive](https://drive.google.com/drive/folders/1CYmZ4sE-RdhRdLhGuYR3rFfgyA3M1mU-?usp=sharing) and try the following:
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
import opencosmo as oc
|
|
147
|
+
|
|
148
|
+
data = oc.open("haloproperties.hdf5", "haloparticles.hdf5")
|
|
149
|
+
```
|
|
150
|
+
This will return a data *collection* that will allow you to query and transform the data as before, but will associate the halos with their particles.
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
|
|
154
|
+
data = data
|
|
155
|
+
.filter(oc.col("fof_halo_mass") > 1e13)
|
|
156
|
+
.take(1000, at="random")
|
|
157
|
+
|
|
158
|
+
for halo in data.halos():
|
|
159
|
+
halo_properties = halo["halo_properties"]
|
|
160
|
+
dm_particles = halo["dm_particles"]
|
|
161
|
+
star_particles = halo["star_particles"]
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
In each iteration, "halo properties" will be a dictionary containing the properties of the halo (such as its total mass), while "dm_particles" and "star_particles" will be OpenCosmo datasets containing the dark matter and stars associated with the halo, respectively. Because these are just like the dataset object we saw eariler, we can further query and transform the particles as needed for our analysis. For more details on how to use the library, check out the [full documentation](https://opencosmo.readthedocs.io/en/latest/).
|
|
165
|
+
|
|
166
|
+
### Testing
|
|
167
|
+
|
|
168
|
+
To run tests, first download the test data [from Google Drive](https://drive.google.com/drive/folders/1CYmZ4sE-RdhRdLhGuYR3rFfgyA3M1mU-?usp=sharing). Set environment variable `OPENCOSMO_DATA_PATH` to the path where the data is stored. Then run the tests with `pytest`:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
export OPENCOSMO_DATA_PATH=/path/to/data
|
|
172
|
+
# From the repository root
|
|
173
|
+
pytest --ignore test/parallel
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Although opencosmo does support multi-core processing via MPI, the default installation does not include the necessary dependencies to work in an MPI environment. If you need these capabilities, check out the guide in our documentation.
|
|
177
|
+
|
|
178
|
+
### Contributing
|
|
179
|
+
|
|
180
|
+
We welcome bug reports and feature requests from the community. If you would like to contribute to the project, please check out the [contributing guide](CONTRIBUTING.md) for more information.
|
|
181
|
+
|
|
182
|
+
```
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source srcset="https://raw.githubusercontent.com/ArgonneCPAC/opencosmo/main/branding/opencosmo_dark.png" media="(prefers-color-scheme: dark)">
|
|
4
|
+
<source srcset="https://raw.githubusercontent.com/ArgonneCPAC/opencosmo/main/branding/opencosmo_light.png" media="(prefers-color-scheme: light)">
|
|
5
|
+
<img src="https://raw.githubusercontent.com/ArgonneCPAC/opencosmo/main/branding/opencosmo_light.png" alt="OpenCosmo">
|
|
6
|
+
</picture>
|
|
7
|
+
</h1><br>
|
|
8
|
+
|
|
9
|
+
[](https://github.com/ArgonneCPAC/OpenCosmo/actions/workflows/merge.yaml)
|
|
10
|
+
[](https://pypi.org/project/opencosmo/)
|
|
11
|
+
[](https://anaconda.org/conda-forge/opencosmo)
|
|
12
|
+
[](https://github.com/ArgonneCPAC/OpenCosmo/blob/main/LICENSE.md)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
The OpenCosmo Python Toolkit provides utilities for reading, writing and manipulating data from cosmological simulations produced by the Cosmolgical Physics and Advanced Computing (CPAC) group at Argonne National Laboratory. It can be used to work with smaller quantities data retrieved with the CosmoExplorer, as well as the much larget datasets these queries draw from. The OpenCosmo toolkit integrates with standard tools such as AstroPy, and allows you to manipulate data in a fully-consistent cosmological context.
|
|
16
|
+
|
|
17
|
+
### Installation
|
|
18
|
+
|
|
19
|
+
The OpenCosmo library is available for Python 3.11 and up on Linux and MacOS (and Windows via [WSL](https://learn.microsoft.com/en-us/windows/wsl/setup/environment)). It can be installed easily with `pip`:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install opencosmo
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
There's a good chance the default version of Python on your system is less than 3.11. Whether or not this is the case, we recommend installing `opencosmo` into a virtual environment. If you're using [Conda](https://docs.conda.io/projects/conda/en/stable/user-guide/getting-started.html), you can create a new environment and install `opencosmo` into it automatically:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
conda create -n opencosmo_env conda-forge::opencosmo
|
|
30
|
+
conda activate opencosmo_env
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
or if you already have a virtual environment to use:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
conda install conda-forge::opencosmo
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If you plan to use `opencosmo` in a Jupyter notebook, you can install the `ipykernel` package to make the environment available as a kernel:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install ipykernel # can also be installed with conda
|
|
43
|
+
python -m ipykernel install --user --name=opencosmo
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Be sure you have run the "activate" command shown above before running the `ipykernel` command.
|
|
47
|
+
|
|
48
|
+
## Getting Started
|
|
49
|
+
|
|
50
|
+
To get started, download the "haloproperites.hdf5" from the [OpenCosmo Google Drive](https://drive.google.com/drive/folders/1CYmZ4sE-RdhRdLhGuYR3rFfgyA3M1mU-?usp=sharing). This file contains properties of dark-matter halos from a small hydrodynamical simulation run with HACC. You can easily open the data with the `open` command:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
import opencosmo as oc
|
|
54
|
+
|
|
55
|
+
dataset = oc.open("haloproperties.hdf5")
|
|
56
|
+
print(dataset)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
OpenCosmo Dataset (length=237441)
|
|
61
|
+
Cosmology: FlatLambdaCDM(name=None, H0=<Quantity 67.66 km / (Mpc s)>, Om0=0.3096446816186967, Tcmb0=<Quantity 0. K>, Neff=3.04, m_nu=None, Ob0=0.04897468161869667)
|
|
62
|
+
First 10 rows:
|
|
63
|
+
block fof_halo_1D_vel_disp fof_halo_center_x ... sod_halo_sfr unique_tag
|
|
64
|
+
km / s Mpc ... solMass / yr
|
|
65
|
+
int32 float32 float32 ... float32 int64
|
|
66
|
+
----- -------------------- ----------------- ... ------------ ----------
|
|
67
|
+
0 32.088795 1.4680439 ... -101.0 21674
|
|
68
|
+
0 41.14525 0.19616994 ... -101.0 44144
|
|
69
|
+
0 73.82962 1.5071135 ... 3.1447952 48226
|
|
70
|
+
0 31.17231 0.7526525 ... -101.0 58472
|
|
71
|
+
0 23.038841 5.3246417 ... -101.0 60550
|
|
72
|
+
0 37.071426 0.5153746 ... -101.0 537760
|
|
73
|
+
0 26.203058 2.1734374 ... -101.0 542858
|
|
74
|
+
0 78.7636 2.1477687 ... 0.0 548994
|
|
75
|
+
0 37.12636 6.9660196 ... -101.0 571540
|
|
76
|
+
0 58.09235 6.072006 ... 1.5439711 576648
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The `open` function returns a `Dataset` object, which holds the raw data as well as information about the simulation. You can easily access the data and cosmology as Astropy objects:
|
|
80
|
+
```python
|
|
81
|
+
dataset.data
|
|
82
|
+
dataset.cosmology
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The first will return an astropy table of the data, with all associated units already applied. The second will return the astropy cosmology object that represents the cosmology the simulation was run with.
|
|
86
|
+
|
|
87
|
+
### Basic Querying
|
|
88
|
+
|
|
89
|
+
Although you can access data directly, `opencosmo` provides tools for querying and transforming the data in a fully cosmology-aware context. For example, suppose we wanted to plot the concentration-mass relationship for the halos in our simulation above a certain mass. One way to perform this would be as follows:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
dataset = dataset
|
|
93
|
+
.filter(oc.col("fof_halo_mass") > 1e13)
|
|
94
|
+
.take(1000, at="random")
|
|
95
|
+
.select(("fof_halo_mass", "sod_halo_cdelta"))
|
|
96
|
+
|
|
97
|
+
print(dataset)
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```text
|
|
102
|
+
OpenCosmo Dataset (length=1000)
|
|
103
|
+
Cosmology: FlatLambdaCDM(name=None, H0=<Quantity 67.66 km / (Mpc s)>, Om0=0.3096446816186967, Tcmb0=<Quantity 0. K>, Neff=3.04, m_nu=None, Ob0=0.04897468161869667)
|
|
104
|
+
First 10 rows:
|
|
105
|
+
fof_halo_mass sod_halo_cdelta
|
|
106
|
+
solMass
|
|
107
|
+
float32 float32
|
|
108
|
+
---------------- ---------------
|
|
109
|
+
11220446000000.0 4.5797048
|
|
110
|
+
17266723000000.0 7.4097505
|
|
111
|
+
51242150000000.0 1.8738283
|
|
112
|
+
70097712000000.0 4.2764015
|
|
113
|
+
51028305000000.0 2.678151
|
|
114
|
+
11960567000000.0 3.9594727
|
|
115
|
+
15276915000000.0 5.793542
|
|
116
|
+
16002001000000.0 2.4318497
|
|
117
|
+
47030307000000.0 3.7146702
|
|
118
|
+
15839942000000.0 3.245569
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
We could then plot the data, or perform further transformations. This is cool on its own, but the real power of `opencosmo` comes from its ability to work with different data types. Go ahead and download the "haloparticles" file from the [OpenCosmo Google Drive](https://drive.google.com/drive/folders/1CYmZ4sE-RdhRdLhGuYR3rFfgyA3M1mU-?usp=sharing) and try the following:
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
import opencosmo as oc
|
|
125
|
+
|
|
126
|
+
data = oc.open("haloproperties.hdf5", "haloparticles.hdf5")
|
|
127
|
+
```
|
|
128
|
+
This will return a data *collection* that will allow you to query and transform the data as before, but will associate the halos with their particles.
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
|
|
132
|
+
data = data
|
|
133
|
+
.filter(oc.col("fof_halo_mass") > 1e13)
|
|
134
|
+
.take(1000, at="random")
|
|
135
|
+
|
|
136
|
+
for halo in data.halos():
|
|
137
|
+
halo_properties = halo["halo_properties"]
|
|
138
|
+
dm_particles = halo["dm_particles"]
|
|
139
|
+
star_particles = halo["star_particles"]
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
In each iteration, "halo properties" will be a dictionary containing the properties of the halo (such as its total mass), while "dm_particles" and "star_particles" will be OpenCosmo datasets containing the dark matter and stars associated with the halo, respectively. Because these are just like the dataset object we saw eariler, we can further query and transform the particles as needed for our analysis. For more details on how to use the library, check out the [full documentation](https://opencosmo.readthedocs.io/en/latest/).
|
|
143
|
+
|
|
144
|
+
### Testing
|
|
145
|
+
|
|
146
|
+
To run tests, first download the test data [from Google Drive](https://drive.google.com/drive/folders/1CYmZ4sE-RdhRdLhGuYR3rFfgyA3M1mU-?usp=sharing). Set environment variable `OPENCOSMO_DATA_PATH` to the path where the data is stored. Then run the tests with `pytest`:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
export OPENCOSMO_DATA_PATH=/path/to/data
|
|
150
|
+
# From the repository root
|
|
151
|
+
pytest --ignore test/parallel
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Although opencosmo does support multi-core processing via MPI, the default installation does not include the necessary dependencies to work in an MPI environment. If you need these capabilities, check out the guide in our documentation.
|
|
155
|
+
|
|
156
|
+
### Contributing
|
|
157
|
+
|
|
158
|
+
We welcome bug reports and feature requests from the community. If you would like to contribute to the project, please check out the [contributing guide](CONTRIBUTING.md) for more information.
|
|
159
|
+
|
|
160
|
+
```
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "opencosmo"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "OpenCosmo Python Toolkit"
|
|
5
|
+
authors = [
|
|
6
|
+
{ name = "Patrick Wells", email = "pwells@anl.gov" },
|
|
7
|
+
{ name = "Will Hicks", email = "whicks@anl.gov"},
|
|
8
|
+
{ name = "Patricia Larsen", email = "prlarsen@anl.gov" },
|
|
9
|
+
{ name = "Michael Buehlmann", email = "mbuehlmann@anl.gov" }
|
|
10
|
+
|
|
11
|
+
]
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.11,<3.15"
|
|
14
|
+
|
|
15
|
+
dependencies = [
|
|
16
|
+
"h5py>=3.12.1,<4.0.0",
|
|
17
|
+
"astropy>=7.2.0,<8.0.0",
|
|
18
|
+
"pydantic>=2.10.6,<3.0.0",
|
|
19
|
+
"hdf5plugin>=5.0.0,<6.0.0",
|
|
20
|
+
"healpy>=1.18.1,<2.0.0",
|
|
21
|
+
"healsparse==1.11.1",
|
|
22
|
+
"deprecated>=1.2.18,<2.0.0",
|
|
23
|
+
"numpy>=2.0,<2.4",
|
|
24
|
+
"click (>=8.2.1,<9.0.0)",
|
|
25
|
+
"numba>=0.62.1",
|
|
26
|
+
"rustworkx>=0.17.1",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[dependency-groups]
|
|
30
|
+
dev = [
|
|
31
|
+
"ruff>=0.9.4,<1.0.0",
|
|
32
|
+
"mypy>=1.15,<2.0.0",
|
|
33
|
+
"types-deprecated>=1.2.15.20250304",
|
|
34
|
+
"pre-commit>=4.2.0,<5.0.0",
|
|
35
|
+
"towncrier (>=24.8.0,<25.0.0)",
|
|
36
|
+
"pip>=25.1.1",
|
|
37
|
+
"pytest>=8.3.4,<9.0.0",
|
|
38
|
+
"pytest-timeout>=2.4.0",
|
|
39
|
+
]
|
|
40
|
+
docs = [
|
|
41
|
+
"sphinx>=9.0.0",
|
|
42
|
+
"sphinx-rtd-theme>=3.0.2,<4.0.0",
|
|
43
|
+
"autodoc-pydantic>=2.2.0,<3.0.0",
|
|
44
|
+
]
|
|
45
|
+
mpi = [
|
|
46
|
+
"mpi4py>=3.1.0,<5.0.0"
|
|
47
|
+
]
|
|
48
|
+
test = [
|
|
49
|
+
"pandas>=2.3.3",
|
|
50
|
+
"pandas-stubs>=2.3.2.250926",
|
|
51
|
+
"polars>=1.35.2",
|
|
52
|
+
"pyarrow>=21.0.0",
|
|
53
|
+
"pyxsim>=4.4.3",
|
|
54
|
+
"yt>=4.4.1",
|
|
55
|
+
]
|
|
56
|
+
test-mpi = [
|
|
57
|
+
"mpi-pytest>=2025.4.0,<2026.0.0"
|
|
58
|
+
]
|
|
59
|
+
[project.scripts]
|
|
60
|
+
opencosmo = "opencosmo.analysis.cli:cli"
|
|
61
|
+
|
|
62
|
+
[project.optional-dependencies]
|
|
63
|
+
io = [
|
|
64
|
+
"pyarrow>=21.0.0",
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
[build-system]
|
|
68
|
+
requires = ["uv_build>=0.8.2,<0.9.0", "pip"]
|
|
69
|
+
build-backend = "uv_build"
|
|
70
|
+
|
|
71
|
+
[tool.uv.build-backend]
|
|
72
|
+
source-include = ["LICENSE.md"]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
[[tool.mypy.overrides]]
|
|
76
|
+
module = ["h5py", "astropy.*", "healpy", "healsparse", "numba"]
|
|
77
|
+
ignore_missing_imports = true
|
|
78
|
+
|
|
79
|
+
[tool.towncrier]
|
|
80
|
+
directory = "changes"
|
|
81
|
+
package = "opencosmo"
|
|
82
|
+
filename = "docs/source/changelog.rst"
|
|
83
|
+
|
|
84
|
+
[tool.pytest.ini_options]
|
|
85
|
+
testpaths = ["test"]
|
|
86
|
+
log_cli = true
|
|
87
|
+
log_cli_level = "INFO"
|
|
88
|
+
|
|
89
|
+
[tool.pyrefly]
|
|
90
|
+
project-includes = [
|
|
91
|
+
"**/*.py*",
|
|
92
|
+
]
|
|
93
|
+
replace-imports-with-any = ["astropy.units", "astropy.constants"]
|
|
94
|
+
|
|
95
|
+
[lint.pycodestyle]
|
|
96
|
+
max-doc-length = 90
|
|
97
|
+
|
|
98
|
+
[tool.ruff.lint]
|
|
99
|
+
future-annotations = true
|
|
100
|
+
preview = true
|
|
101
|
+
extend-select = ["TC"]
|
|
102
|
+
|
|
103
|
+
[tool.towncrier.fragment.improvement]
|
|
104
|
+
name = "Improvements"
|
|
105
|
+
showcontent = true
|
|
106
|
+
|
|
107
|
+
[tool.towncrier.fragment.feature]
|
|
108
|
+
name = "New Features"
|
|
109
|
+
|
|
110
|
+
[tool.towncrier.fragment.bugfix]
|
|
111
|
+
name = "Bugfixes"
|
|
112
|
+
|
|
113
|
+
[tool.towncrier.fragment.doc]
|
|
114
|
+
name = "Documentation"
|
|
115
|
+
|
|
116
|
+
[tool.towncrier.fragment.removal]
|
|
117
|
+
name = "Deprecations and Removals"
|
|
118
|
+
|
|
119
|
+
[tool.towncrier.fragment.misc]
|
|
120
|
+
name = "Miscellaneous"
|
|
121
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from .collection import (
|
|
2
|
+
HealpixMap,
|
|
3
|
+
Lightcone,
|
|
4
|
+
SimulationCollection,
|
|
5
|
+
StructureCollection,
|
|
6
|
+
)
|
|
7
|
+
from .column import col
|
|
8
|
+
from .dataset import Dataset
|
|
9
|
+
from .io import open, write
|
|
10
|
+
from .spatial import make_box, make_cone
|
|
11
|
+
|
|
12
|
+
__version__ = "1.0.0"
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"write",
|
|
16
|
+
"col",
|
|
17
|
+
"open",
|
|
18
|
+
"Dataset",
|
|
19
|
+
"StructureCollection",
|
|
20
|
+
"SimulationCollection",
|
|
21
|
+
"Lightcone",
|
|
22
|
+
"HealpixMap",
|
|
23
|
+
"make_box",
|
|
24
|
+
"make_cone",
|
|
25
|
+
"__version__",
|
|
26
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# ruff: noqa
|
|
2
|
+
from importlib import import_module
|
|
3
|
+
|
|
4
|
+
known_yt_tools = [
|
|
5
|
+
"create_yt_dataset",
|
|
6
|
+
"ProjectionPlot",
|
|
7
|
+
"SlicePlot",
|
|
8
|
+
"ParticleProjectionPlot",
|
|
9
|
+
"ProfilePlot",
|
|
10
|
+
"PhasePlot",
|
|
11
|
+
"visualize_halo",
|
|
12
|
+
"halo_projection_array",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
Right now, we have only have two analysis modules so we can handle them directly. In the
|
|
18
|
+
future we will need to implement a more robust system that handles things automatically.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def __getattr__(name):
|
|
23
|
+
if name in known_yt_tools:
|
|
24
|
+
yt_viz = import_module(".yt_viz", package="opencosmo.analysis")
|
|
25
|
+
yt_utils = import_module(".yt_utils", package="opencosmo.analysis")
|
|
26
|
+
try:
|
|
27
|
+
return getattr(yt_viz, name)
|
|
28
|
+
except AttributeError:
|
|
29
|
+
pass
|
|
30
|
+
try:
|
|
31
|
+
return getattr(yt_utils, name)
|
|
32
|
+
except AttributError:
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
# except ImportError as ie:
|
|
36
|
+
# raise ImportError(
|
|
37
|
+
# "You tried to import one of the OpenCosmo YT tools, but your python "
|
|
38
|
+
# "environment does not have the necessary dependencies. You can do install "
|
|
39
|
+
# "them with `pip install opencosmo[analysis]`\n"
|
|
40
|
+
# f"{ie}"
|
|
41
|
+
# )
|
|
42
|
+
raise ImportError(f"Cannot import name '{name}' from opencosmo.analysis")
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
from opencosmo.analysis.install import get_file_versions, install_spec
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@click.group()
|
|
14
|
+
def cli():
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@cli.command(name="install")
|
|
19
|
+
@click.argument("spec_name", required=True)
|
|
20
|
+
@click.option("--file", type=click.Path(exists=True), required=False)
|
|
21
|
+
@click.option("--dev", is_flag=True)
|
|
22
|
+
def install(spec_name: str, file: Optional[Path] = None, dev: bool = False):
|
|
23
|
+
if file is not None:
|
|
24
|
+
versions = get_file_versions(spec_name, file)
|
|
25
|
+
else:
|
|
26
|
+
versions = {}
|
|
27
|
+
|
|
28
|
+
install_spec(spec_name, versions, dev=dev)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
cli()
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections import namedtuple
|
|
4
|
+
from typing import TYPE_CHECKING, NamedTuple, Type, TypeVar
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from opencosmo import Dataset
|
|
8
|
+
|
|
9
|
+
DIFFMAH_INPUT = namedtuple(
|
|
10
|
+
"DIFFMAH_INPUT", ["logm0", "logtc", "early_index", "late_index", "t_peak"]
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
T = TypeVar("T", bound=NamedTuple)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def make_named_tuple(dataset: Dataset, input_tuple: Type[T]) -> T:
|
|
17
|
+
required_columns = input_tuple._fields
|
|
18
|
+
data = dataset.select(required_columns).data
|
|
19
|
+
output = {c: data[c].value for c in required_columns}
|
|
20
|
+
return input_tuple(**output) # type: ignore
|