Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python interface for calling the C++ code #14

Open
wants to merge 166 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
166 commits
Select commit Hold shift + click to select a range
a6a2bb7
Compile all possible variants
misharash Nov 7, 2023
b7c9af9
Started planning a Python interface
misharash Nov 8, 2023
4f95a49
Created/deleted dirs in Makefile
misharash Nov 8, 2023
63448fa
Shortened repetitions in Makefile
misharash Nov 8, 2023
c641f0f
More interface clarifications & warnings
misharash Nov 8, 2023
d6114a0
Added xi_cut explanation for the interface
misharash Nov 8, 2023
bdc5c95
Continued interface planning and explanations
misharash Nov 9, 2023
29179ad
Renamed modes/variants
misharash Nov 9, 2023
e21d57d
Updated counts explanations
misharash Nov 9, 2023
2ee6101
Moved unused scripts to legacy folder
misharash Nov 16, 2023
eb28271
Refactored non-legacy scripts
misharash Nov 16, 2023
c7ec2a9
Retired one more script
misharash Nov 16, 2023
bdddf9a
Merge branch 'compat'
misharash Nov 16, 2023
8d637d1
Additional refactoring in convert_to_xyz
misharash Nov 16, 2023
e0edae7
Partial scripts bump from desi branch
misharash Nov 17, 2023
9d9ed0c
Script to collect C++ code output from text files
misharash Nov 23, 2023
6b48aa0
Merge branch 'compat'
misharash Nov 23, 2023
909cf89
Refactored the simpler post-processing scripts
misharash Nov 23, 2023
310396d
Unified the load_raw_covariances functions
misharash Nov 23, 2023
e861f58
New, simplified catenation script
misharash Nov 24, 2023
ed8572d
Refactored Legendre jackknife post-processing
misharash Nov 24, 2023
13e8ca6
Another small fix in jackknife logic
misharash Nov 24, 2023
c339420
Supplemented type annotation for matrix loading
misharash Nov 24, 2023
51f04b5
Small fix in weight normalization
misharash Nov 24, 2023
210dfdd
Refactored single-tracer matrix loading
misharash Nov 24, 2023
e662831
Renamed cov construction function and fixed usage
misharash Nov 25, 2023
cfe3906
Refactored default multi-tracer post-processing
misharash Nov 25, 2023
b2d40b2
Fixed and restructured default multi post-process
misharash Nov 25, 2023
07c9d1d
Moved multi-field utility functions
misharash Nov 25, 2023
c44c8ad
Refactored Legendre multi post-process
misharash Nov 25, 2023
9d29a32
More massaging of multi-tracer utilities
misharash Nov 25, 2023
78824dc
Refactored default multi mock post-processing
misharash Nov 25, 2023
60b0b6b
Cosmetic edits in multi post-processings
misharash Nov 25, 2023
3f5fad4
Shortened single-field c234 loading
misharash Nov 25, 2023
01c19db
Revisited s, mu jack post-process
misharash Nov 25, 2023
d4e07f4
Revisited mixed Legendre jack post-process
misharash Nov 25, 2023
b998473
Fixes in multi-tracer matrix loading
misharash Nov 25, 2023
1e1d99c
Refactored multi-tracer jack post-process
misharash Nov 25, 2023
411842b
Changed some operations with map
misharash Nov 25, 2023
c47e7a1
Retired the old catenation script
misharash Nov 25, 2023
f0bad26
Merge branch 'compat'
misharash Nov 25, 2023
c3ea7ec
Hopefully final scripts bump from desi branch
misharash Nov 26, 2023
0557cfa
Fixed imports and tuple typing
misharash Nov 27, 2023
275c8c4
Fixed the correction function scripts
misharash Nov 27, 2023
3544041
Merge branch 'master' into interface
misharash Nov 27, 2023
93a347f
Restructured the extra convergence check
misharash Nov 27, 2023
bf1ff55
Type annotations for mu bin Legendre factors
misharash Nov 27, 2023
5abf014
Working on the interface implementation
misharash Nov 27, 2023
10e0eca
Finished rough implementation of the interface
misharash Nov 28, 2023
ea0f16c
Implemented xi refinement logic
misharash Nov 28, 2023
04433a9
Resolved the s_edges redundancy
misharash Nov 29, 2023
b8013e5
More explanations on covariance/counts binning
misharash Nov 29, 2023
171cea5
Moved interface and full set of executables
misharash Nov 29, 2023
182c422
Merge branch 'interface'
misharash Nov 29, 2023
125d89b
Ignore the executable variants in git
misharash Nov 29, 2023
3ba8dc4
Post-processing fixes and improvements
misharash Dec 4, 2023
2b3a785
Further fixes
misharash Dec 5, 2023
8884141
Restructured cov conversion scripts
misharash Dec 6, 2023
d864623
Merge branch 'oliverphilcox:master' into master
misharash Dec 7, 2023
f143502
Correction in reported configuration counts
misharash Dec 7, 2023
4fc1bdc
Provided reference for expected runtime
misharash Dec 7, 2023
7755493
Expanded the runtime note
misharash Dec 7, 2023
4d30661
Explained the returned value in the interface
misharash Dec 7, 2023
94f6205
Featured interface in README
misharash Dec 11, 2023
5b0fd00
Fixes and restructuring
misharash Dec 11, 2023
762f7b1
Fixes in raw covariance matrix collection
misharash Dec 23, 2023
2a33697
Fix in convert_cov scripts
misharash Dec 23, 2023
4201392
Separated the library and made scripts executable
misharash Dec 24, 2023
a91fad6
Updated paths in the docs
misharash Dec 24, 2023
522046f
Merge branch 'oliverphilcox:master' into master
misharash Dec 26, 2023
50d9876
Fixes in Legendre multi to cat comb function
misharash Jan 10, 2024
8c84e21
Reorganized flags in the Makefile
misharash Jan 11, 2024
4030e41
Added diagnostics for xi rescaling
misharash Jan 12, 2024
a31f15c
Fixes for xi rescaling diagnostics
misharash Jan 13, 2024
fa2ca7d
Another diagnostic for xi rescaling
misharash Jan 13, 2024
f920ff2
Deleted unused source file
misharash Jan 13, 2024
9d65247
Multi-tracer post-processing fix
misharash Jan 13, 2024
64bf983
Changed small particle separation logic
misharash Jan 13, 2024
09f53b0
More fixes for multi-tracer post-processing
misharash Jan 13, 2024
266cf22
Inserted endline for xi rescaling diagnostics
misharash Jan 13, 2024
f1e55ea
Files from manodeep/Makefile-C-Python
misharash Jan 17, 2024
8d005ad
Renamed the imported license file
misharash Jan 18, 2024
03475d5
Legendre mocks post-processing fix
misharash Jan 19, 2024
f5f634b
Python package init file
misharash Feb 4, 2024
d3e2e44
Minimal working setup
misharash Feb 4, 2024
a005e15
Ignore the package build files
misharash Feb 4, 2024
26bdaca
Merge branch 'python_setup'
misharash Feb 4, 2024
c02dea2
Small clarification for interface output
misharash Feb 4, 2024
761663d
Cleanup and corrections in setup script
misharash Feb 4, 2024
b695e7f
Minimal python interface explanations in README
misharash Feb 6, 2024
89ce6b3
NERSC installation instruction
misharash Feb 6, 2024
81cb2e2
Corrections about installation
misharash Feb 6, 2024
914ec52
Note about the multi-threading precaution
misharash Feb 6, 2024
3e5bd63
Another small fix in README
misharash Feb 6, 2024
6279080
Added mode printouts in the interface
misharash Feb 6, 2024
afea66c
Added progress and time messages in the interface
misharash Feb 6, 2024
93098ba
Updated the run time explanation
misharash Feb 6, 2024
1f84f90
More diagnostic information in the interface
misharash Feb 6, 2024
c3e1f48
Moved the binning info to the output dir
misharash Feb 6, 2024
4993123
More explanations on the files/directories
misharash Feb 6, 2024
6638702
Fixes for installation instructions
misharash Feb 6, 2024
71df00b
Multi-threading fix and warning
misharash Feb 9, 2024
1f85434
Slash-safe output dir in the C++ code
misharash Feb 11, 2024
ac7e909
Removed the filename length limits
misharash Feb 11, 2024
7b978ea
Fixed uint64 format warning on Linux
misharash Feb 11, 2024
ed002c8
Accumulated fixes for the interface
misharash Feb 12, 2024
01cbcc3
Added extra convergence check into the interface
misharash Feb 13, 2024
3d7aec5
Added reference to script gallery
misharash Feb 14, 2024
c9faf42
Removed unused import
misharash Feb 18, 2024
2457c30
Included coordinate conversion in the interface
misharash Feb 18, 2024
7cdbe8a
Made jackknife number format more flexible
misharash Aug 5, 2022
1c51a5d
Ensured consistency of jackknife numbers
misharash Feb 18, 2024
ce7bfab
Added dtype for coordinate conversion
misharash Feb 18, 2024
d58d11d
Fix in combine_covs scripts
misharash Dec 25, 2023
9454ec2
Fixes in the raw covariance matrix catenation
misharash Feb 20, 2024
92b090f
More minimal compilation setup on Mac
misharash Feb 21, 2024
245e9c6
Merge branch 'oliverphilcox:master' into master
misharash Feb 22, 2024
4b5651b
Allowed already wrapped estimators in pycorr reshaping
misharash Feb 23, 2024
9449477
Optimized memory usage in pycorr sample covs
misharash Feb 23, 2024
d313357
Recovered counts renormalization in combine_covs
misharash Mar 8, 2024
c7bcdb8
Only positive shot-noise rescaling to optimize
misharash Mar 22, 2024
f3a8438
Ensured single-threaded jackknife assignment
misharash Apr 30, 2024
f901a14
position_type argument for xirunpc subsampler
misharash Apr 30, 2024
28288a7
Separated the comoving distance calculation
misharash Apr 30, 2024
afbc58f
Extra measure for single-threaded jack assignment
misharash Apr 30, 2024
82ff4b6
Enabled additional verbosity on progress
misharash May 1, 2024
ce9257e
Fix for the verbose executable variants
misharash May 1, 2024
69b2f45
Tutorial notebook (not finalized)
misharash May 1, 2024
26657ae
Linked the tutorial notebook to README
misharash May 1, 2024
13b9b1f
Some more details for the tutorial
misharash May 2, 2024
911f86b
More info on installation and dependencies
misharash May 2, 2024
4f93f50
A few fixes in README
misharash May 2, 2024
6d7940e
Re-framed the Corrfunc version reminder
misharash May 2, 2024
c866972
Fixed the spelling of jackknife in plural
misharash May 2, 2024
1a6a8e2
Option to run more reproducibly with a fixed seed
misharash May 2, 2024
65a901c
Propagated the RNG setup to 2PCF rescaling
misharash May 9, 2024
0b38799
Small fix for OpenMP pragma
misharash May 9, 2024
d5662c6
Fixed compilation for 3PCF mode
misharash May 9, 2024
39c6464
Eliminated sprintf/snprintf for 3PCF
misharash May 9, 2024
689a415
Fixed triple_counts
misharash May 9, 2024
fbf1beb
Propagated the RNG setup everywhere
misharash May 9, 2024
52a601a
Reset the mode back to Legendre mix jackknife
misharash May 9, 2024
2a0a66a
Added DESI NERSC setup guide to tutorial
misharash May 27, 2024
f7df658
Sample selection for raw cov loading/post-process
misharash May 29, 2024
e3a3970
Fixed logic and type checks/annotations
misharash May 29, 2024
2966a37
Fix for the raw covs cutting
misharash May 30, 2024
be27971
Fixed disappearing warnings in the tutorial
misharash Jun 22, 2024
79c5abd
Warning about directory paths
misharash Jun 24, 2024
1943020
Clean up the temporary files in the interface
misharash Jun 24, 2024
6d5c77f
Documented part of the utility functions
misharash Jun 24, 2024
ad9e4ac
Fixed and reorganized the correction functions
misharash Jun 24, 2024
6cb796d
Small fix of particles' reading logic
misharash Jun 25, 2024
8f364d4
Extra precaution in the tutorial's tricky part
misharash Jun 26, 2024
da60e79
Small reorganization of input 2PCF logic
misharash Jul 10, 2024
3c44134
Tiny fixes in the interface
misharash Jul 10, 2024
6045024
Created post-processing module index
misharash Jul 10, 2024
9b1f242
Minimal index of the pre-processing module
misharash Jul 10, 2024
8d86a28
Started docs on the Python library
misharash Jul 11, 2024
0698428
Added/updated installation instructions
misharash Jul 11, 2024
e1f3ef3
Added/corrected main function explanations
misharash Jul 11, 2024
ff994ba
Continued work on docs
misharash Jul 15, 2024
b1417c2
Set dtype for jackknife subsampler
misharash Jul 30, 2024
683dc81
Slight optimization for string_format
misharash Jul 30, 2024
f541673
Minimized repetition in string_format realizations
misharash Jul 31, 2024
5b3c606
Modernized the Python package installation
misharash Aug 12, 2024
12407be
Updated directory guidance and handling
misharash Aug 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

# Executables
cov
bin
triple
*.exe
*.out
Expand All @@ -47,6 +48,11 @@ _build
_static
_templates

# Python package build files
build
dist
*.egg-info

# IPython/Jupyter notebook checkpoints
.ipynb_checkpoints

Expand Down
23 changes: 13 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
## MAKEFILE FOR RascalC. This compiles the grid_covariance.cpp file into the ./cov exececutable.

CC = gcc
CFLAGS = -g -O3 -Wall -MMD
CXXFLAGS = -O3 -Wall -MMD -DOPENMP -DLEGENDRE_MIX -DJACKKNIFE -DPRINTPERCENTS
CFLAGS = -O3 -Wall -MMD
CXX = g++
CXXFLAGS = -O3 -Wall -MMD -std=c++11 -ffast-math $(shell pkg-config --cflags gsl)
CXXFLAGS += -DOPENMP -DLEGENDRE_MIX -DJACKKNIFE -DPRINTPERCENTS
#-DOPENMP # use this to run multi-threaded with OPENMP
#-DPERIODIC # use this to enable periodic behavior
#-DLEGENDRE # use this to compute 2PCF covariances in Legendre bins (original mode, corresponding to direct accumulation into multipoles from pair counts)
Expand All @@ -12,25 +14,26 @@ CXXFLAGS = -O3 -Wall -MMD -DOPENMP -DLEGENDRE_MIX -DJACKKNIFE -DPRINTPERCENTS
#-DTHREE_PCF # use this to compute 3PCF autocovariances
#-DPRINTPERCENTS # use this to print percentage of progress in each loop. This can be a lot of output

LFLAGS = $(shell pkg-config --libs gsl) # common part

# Known OS-specific choices
ifeq ($(shell uname -s),Darwin)
# Here we use LLVM compiler to load the Mac OpenMP. Tested after installation commands:
# brew install llvm
# Here we load the Mac OpenMP. Tested after installation commands:
# brew install libomp
# This may need to be modified with a different installation
ifndef HOMEBREW_PREFIX
HOMEBREW_PREFIX = /usr/local
endif
CXX = ${HOMEBREW_PREFIX}/opt/llvm/bin/clang++ -std=c++0x -fopenmp -ffast-math $(shell pkg-config --cflags gsl)
LD = ${HOMEBREW_PREFIX}/opt/llvm/bin/clang++
LFLAGS = $(shell pkg-config --libs gsl) -fopenmp -lomp
CXXFLAGS += -I$(HOMEBREW_PREFIX)/opt/libomp/include
LFLAGS += -L$(HOMEBREW_PREFIX)/opt/libomp/lib -lomp
else
# default (Linux) case
CXX = g++ -fopenmp -lgomp -std=c++0x -ffast-math $(shell pkg-config --cflags gsl)
LD = g++
LFLAGS = -L/usr/local/lib -L/usr/lib/x86_64-linux-gnu $(shell pkg-config --libs gsl) -lgomp
CXXFLAGS += -fopenmp
LFLAGS += -lgomp
endif

LD = $(CXX)

AUNTIE = cov
AOBJS = grid_covariance.o ./cubature/hcubature.o ./ransampl/ransampl.o
ADEPS = ${AOBJS:.o=.d}
Expand Down
58 changes: 57 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,61 @@ Any usage of this code should cite [Philcox et al. 2019](https://arxiv.org/abs/1

***New for version 2***: Legendre moment covariances and the 3PCF

## Python interface and [Jupyter notebook tutorial](https://github.com/misharash/RascalC/blob/master/tutorial.ipynb) (alpha-testing before version 3.0)

### Installation for DESI members at NERSC

Recommended to use with `cosmodesi` environment.
In particular, load it before installing:
```
source /global/common/software/desi/users/adematti/cosmodesi_environment.sh main
pip install -e /global/common/software/desi/users/mrash/RascalC
```
This installs the library from my software folder in the development mode, so that after I update it e.g. with some fix, you will have the new version without the need to re-install or any other action.

### Generic installation (if the above is unavailable)

```
git clone https://github.com/misharash/RascalC
cd RascalC
python3 -m pip install .
```
Make sure to reinstall after pulling updates.
At this early stage, the fixes might be needed quite often.

Or you can install with just one command:
```
python3 -m pip install https://github.com/misharash/RascalC.git
```

The code requires [`pycorr`](https://github.com/cosmodesi/pycorr) to deal with pair counts and data correlation function estimators.
To compute pair counts of catalogs, you need a [custom version of `Corrfunc`](https://github.com/adematti/Corrfunc) (see also [`pycorr` installation instructions](https://py2pcf.readthedocs.io/en/latest/user/building.html)).
Both can be installed quickly via
```
python3 -m pip install 'git+https://github.com/cosmodesi/pycorr#egg=pycorr[corrfunc]'
```

### Usage guide

```
import RascalC
result = RascalC.run_cov(...)
```

`run_cov` is the main function for the covariance matrix computation.
Use `help(RascalC.run_cov)` to learn more about the inputs and outputs; many of them are similar to [pycorr](https://github.com/cosmodesi/pycorr) `TwoPointCorrelationFunction` and some others are `pycorr.TwoPointEstimator`s.

An example pipeline is showcased in a [tutorial notebook](https://github.com/misharash/RascalC/blob/master/tutorial.ipynb) (will be smoothed out soon).

It is strongly recommended NOT to use multi-threaded operations in the `python` process before launching `RascalC.run_cov` – this may cause the code to run effectively single-threaded.
E.g. at NERSC this would mean not setting `OMP_*` and other `*_THREADS` environment variables; the code will set them by itself according to the number of threads you passed.
This caveat does not seem to be unique for RascalC – different multi-threading backends can interfere.

Some specific examples are also available in the new separate script gallery: <https://github.com/misharash/RascalC-scripts>.

More documentation is coming, in the meantime please contact Michael 'Misha' Rashkovetskyi <mrashkovetskyi@cfa.harvard.edu> with any questions.
Please also feel free to open [GitHub issues](https://github.com/misharash/RascalC/issues) both for problems and clarification requests.

## Authors

- Oliver Philcox (Columbia / Simons Foundation)
Expand All @@ -17,4 +72,5 @@ Any usage of this code should cite [Philcox et al. 2019](https://arxiv.org/abs/1
- Alexander Wiegand (Garching)
- Misha Rashkovetskyi (Harvard)

We thank Yuting Wang and Ryuichiro Hada for pointing out and fixing a number of issues with the code and its documentation. We are particularly grateful to Uendert Andrade for finding a wide variety of improvements and bugs!
We thank Yuting Wang and Ryuichiro Hada for pointing out and fixing a number of issues with the code and its documentation.
We are particularly grateful to Uendert Andrade for finding a wide variety of improvements and bugs, and to Jiaxi Yu for feedback on the Python interface and Jupyter notebook tutorial!
102 changes: 102 additions & 0 deletions RascalC/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
## MAKEFILE FOR RascalC. This compiles the grid_covariance.cpp file into the ./cov exececutable.

CC = gcc
CFLAGS = -O3 -Wall -MMD
CXX = g++
CXXFLAGS = -O3 -Wall -MMD -std=c++11 -ffast-math $(shell pkg-config --cflags gsl)
CXXFLAGS += -DOPENMP
#-DOPENMP # use this to run multi-threaded with OPENMP
#-DPERIODIC # use this to enable periodic behavior
#-DLEGENDRE # use this to compute 2PCF covariances in Legendre bins (original mode, corresponding to direct accumulation into multipoles from pair counts)
#-DLEGENDRE_MIX # also compute 2PCF covariances in Legendre bins, but in other, "mixed" mode, corresponding to projection of s,µ bins into multipoles
# without either of the two Legendre flags above, the covariance is computed in s,µ bins
#-DJACKKNIFE # use this to compute (r,mu)-space 2PCF covariances and jackknife covariances. Incompatible with -DLEGENDRE but works with -DLEGENDRE_MIX
#-DTHREE_PCF # use this to compute 3PCF autocovariances
#-DPRINTPERCENTS # use this to print percentage of progress in each loop. This can be a lot of output

LFLAGS = $(shell pkg-config --libs gsl) # common part

# Known OS-specific choices
ifeq ($(shell uname -s),Darwin)
# Here we load the Mac OpenMP. Tested after installation commands:
# brew install libomp
# This may need to be modified with a different installation
ifndef HOMEBREW_PREFIX
HOMEBREW_PREFIX = /usr/local
endif
CXXFLAGS += -I$(HOMEBREW_PREFIX)/opt/libomp/include
LFLAGS += -L$(HOMEBREW_PREFIX)/opt/libomp/lib -lomp
else
# default (Linux) case
CXXFLAGS += -fopenmp
LFLAGS += -lgomp
endif

LD = $(CXX)

# The code below compiles all the valid variants for the 2PCF covariance

BASE_VARIANTS = s_mu s_mu_jackknife legendre_accumulated legendre_projected legendre_projected_jackknife

DEFINES_FOR_s_mu=
DEFINES_FOR_s_mu_jackknife=-DJACKKNIFE
DEFINES_FOR_legendre_accumulated=-DLEGENDRE
DEFINES_FOR_legendre_projected=-DLEGENDRE_MIX
DEFINES_FOR_legendre_projected_jackknife=-DLEGENDRE_MIX -DJACKKNIFE

define add_periodic_variant
DEFINES_FOR_$(1)_periodic = $$(DEFINES_FOR_$(1)) -DPERIODIC
VARIANTS_INT += $(1) $(1)_periodic
endef

$(foreach variant,$(BASE_VARIANTS),$(eval $(call add_periodic_variant,$(variant))))

define add_verbose_variant
DEFINES_FOR_$(1)_verbose = $$(DEFINES_FOR_$(1)) -DPRINTPERCENTS
VARIANTS += $(1) $(1)_verbose
endef

$(foreach variant,$(VARIANTS_INT),$(eval $(call add_verbose_variant,$(variant))))

OBJDIR = obj
EXECDIR = bin

VAR_SRC_BASE = grid_covariance
VAR_SRC = ../$(VAR_SRC_BASE).cpp
VAR_OBJ_BASE = $(OBJDIR)/$(VAR_SRC_BASE)

EXEC_BASE = $(EXECDIR)/cov
COMMON_OBJS = ../cubature/hcubature.o ../ransampl/ransampl.o

ALL_OBJS = $(COMMON_OBJS)

define make_targets
OBJ_$(1) = $$(VAR_OBJ_BASE).$(1).o
ALL_OBJS += $$(OBJ_$(1))
EXEC_$(1) = $$(EXEC_BASE).$(1)
ALL_EXECS += $$(EXEC_$(1))

$$(OBJ_$(1)): $$(VAR_SRC)
mkdir -p $$(OBJDIR)
$$(CXX) $$(CXXFLAGS) $$(DEFINES_FOR_$(1)) -c $$(VAR_SRC) -o $$@

$$(EXEC_$(1)): $$(OBJ_$(1)) $$(COMMON_OBJS)
mkdir -p $$(EXECDIR)
$$(LD) $$(OBJ_$(1)) $$(COMMON_OBJS) $$(LFLAGS) -o $$@

endef

$(foreach variant,$(VARIANTS),$(eval $(call make_targets,$(variant))))

.PHONY: all clean

all: $(ALL_EXECS)
.DEFAULT_GOAL := all

clean:
rm -f $(ALL_EXECS) $(ALL_OBJS) ${ALL_DEPS}
rm -rf $(OBJDIR) $(EXECDIR)

$(ALL_OBJS): Makefile
ALL_DEPS = ${ALL_OBJS:.o=.d}
-include ${ALL_DEPS}
3 changes: 3 additions & 0 deletions RascalC/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__version__ = "3.0.alpha1"

from .interface import run_cov
28 changes: 28 additions & 0 deletions RascalC/comb/combine_covs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"This reads two sets of RascalC results and two cosmodesi/pycorr .npy files to combine two covs following NS/GCcomb procedure. Covariance of N and S 2PCF is neglected."

from pycorr import TwoPointCorrelationFunction
import numpy as np
from ..pycorr_utils.utils import reshape_pycorr
from ..cov_utils import get_cov_header, load_cov
from ..pycorr_utils.counts import get_counts_from_pycorr


def combine_covs(rascalc_results1: str, rascalc_results2: str, pycorr_file1: str, pycorr_file2: str, output_cov_file: str, n_mu_bins: int | None = None, r_step: float = 1, skip_r_bins: int = 0, output_cov_file1: str | None = None, output_cov_file2: str | None = None, print_function = print):
# Read RascalC results
header1 = get_cov_header(rascalc_results1)
cov1 = load_cov(rascalc_results1, print_function)
header2 = get_cov_header(rascalc_results2)
cov2 = load_cov(rascalc_results2, print_function)
# Save to their files if any
if output_cov_file1: np.savetxt(output_cov_file1, cov1, header = header1)
if output_cov_file2: np.savetxt(output_cov_file2, cov2, header = header2)
header = f"combined from {rascalc_results1} with {header1} and {rascalc_results2} with {header2}" # form the final header to include both

# Read pycorr files to figure out weights
weight1 = get_counts_from_pycorr(reshape_pycorr(TwoPointCorrelationFunction.load(pycorr_file1), n_mu_bins, r_step, skip_r_bins = skip_r_bins).normalize(), counts_factor = 1).ravel()
weight2 = get_counts_from_pycorr(reshape_pycorr(TwoPointCorrelationFunction.load(pycorr_file2), n_mu_bins, r_step, skip_r_bins = skip_r_bins).normalize(), counts_factor = 1).ravel()

# Produce and save combined cov
# following xi = (xi1 * weight1 + xi2 * weight2) / (weight1 + weight2)
cov = (cov1 * weight1[None, :] * weight1[:, None] + cov2 * weight2[None, :] * weight2[:, None]) / (weight1 + weight2)[None, :] / (weight1 + weight2)[:, None]
np.savetxt(output_cov_file, cov, header = header) # includes source parts and their shot-noise rescaling values in the header
47 changes: 47 additions & 0 deletions RascalC/comb/combine_covs_legendre.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"This reads two sets of RascalC results and two cosmodesi/pycorr .npy files to combine two covs following NS/GCcomb procedure in Legendre mode. Covariance of N and S 2PCF is neglected."

from pycorr import TwoPointCorrelationFunction
import numpy as np
from ..pycorr_utils.utils import reshape_pycorr
from ..cov_utils import get_cov_header, load_cov_legendre
from ..pycorr_utils.counts import get_counts_from_pycorr
from ..mu_bin_legendre_factors import compute_mu_bin_legendre_factors


def combine_covs_legendre(rascalc_results1: str, rascalc_results2: str, pycorr_file1: str, pycorr_file2: str, output_cov_file: str, max_l: int, r_step: float = 1, skip_r_bins: int = 0, output_cov_file1: str | None = None, output_cov_file2: str | None = None, print_function = print):
# Read RascalC results
header1 = get_cov_header(rascalc_results1)
cov1 = load_cov_legendre(rascalc_results1, max_l, print_function)
n_bins = len(cov1)
header2 = get_cov_header(rascalc_results2)
cov2 = load_cov_legendre(rascalc_results2, max_l, print_function)
# Save to their files if any
if output_cov_file1: np.savetxt(output_cov_file1, cov1, header = header1)
if output_cov_file2: np.savetxt(output_cov_file2, cov2, header = header2)
header = f"combined from {rascalc_results1} with {header1} and {rascalc_results2} with {header2}" # form the final header to include both

# Read pycorr files to figure out weights of s, mu binned 2PCF
xi_estimator1 = reshape_pycorr(TwoPointCorrelationFunction.load(pycorr_file1), n_mu = None, r_step = r_step, skip_r_bins = skip_r_bins).normalize()
n_r_bins = xi_estimator1.shape[0]
mu_edges = xi_estimator1.edges[1]
weight1 = get_counts_from_pycorr(xi_estimator1, counts_factor = 1)
weight2 = get_counts_from_pycorr(reshape_pycorr(TwoPointCorrelationFunction.load(pycorr_file2).normalize(), n_mu = None, r_step = r_step, skip_r_bins = skip_r_bins), counts_factor = 1)

# Normalize weights
sum_weight = weight1 + weight2
weight1 /= sum_weight
weight2 /= sum_weight

mu_leg_factors, leg_mu_factors = compute_mu_bin_legendre_factors(mu_edges, max_l, do_inverse = True)

# Derivatives of angularly binned 2PCF wrt Legendre are leg_mu_factors[ell//2, mu_bin]
# Angularly binned 2PCF are added with weights (normalized) weight1/2[r_bin, mu_bin]
# Derivatives of Legendre wrt binned 2PCF are mu_leg_factors[mu_bin, ell//2]
# So we need to sum such product over mu bins, while radial bins stay independent, and the partial derivative of combined 2PCF wrt the 2PCFs 1/2 will be
pd1 = np.einsum('il,kl,lj,km->ikjm', leg_mu_factors, weight1, mu_leg_factors, np.eye(n_r_bins)).reshape(n_bins, n_bins)
pd2 = np.einsum('il,kl,lj,km->ikjm', leg_mu_factors, weight2, mu_leg_factors, np.eye(n_r_bins)).reshape(n_bins, n_bins)
# We have correct [l_in, r_in, l_out, r_out] ordering and want to make these matrices in the end thus the reshape

# Produce and save combined cov
cov = pd1.T.dot(cov1).dot(pd1) + pd2.T.dot(cov2).dot(pd2)
np.savetxt(output_cov_file, cov, header=header) # includes source parts and their shot-noise rescaling values in the header
55 changes: 55 additions & 0 deletions RascalC/comb/combine_covs_legendre_multi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"This reads two sets of RascalC results and two triplets of cosmodesi/pycorr .npy files to combine two full 2-tracer covs following NS/GCcomb procedure for 2 tracers in Legendre mode. Covariance of N(GC) and S(GC) 2PCF is neglected."

from pycorr import TwoPointCorrelationFunction
import numpy as np
from ..pycorr_utils.utils import reshape_pycorr
from ..cov_utils import get_cov_header, load_cov_legendre_multi
from ..pycorr_utils.counts import get_counts_from_pycorr
from ..mu_bin_legendre_factors import compute_mu_bin_legendre_factors


def combine_covs_legendre_multi(rascalc_results1: str, rascalc_results2: str, pycorr_files1: list[str], pycorr_files2: list[str], output_cov_file: str, max_l: int, r_step: float = 1, skip_r_bins: int = 0, output_cov_file1: str | None = None, output_cov_file2: str | None = None, print_function = print):
# Read RascalC results
header1 = get_cov_header(rascalc_results1)
cov1 = load_cov_legendre_multi(rascalc_results1, max_l, print_function)
n_bins = len(cov1)
header2 = get_cov_header(rascalc_results2)
cov2 = load_cov_legendre_multi(rascalc_results2, max_l, print_function)
# Save to their files if any
if output_cov_file1: np.savetxt(output_cov_file1, cov1, header = header1)
if output_cov_file2: np.savetxt(output_cov_file2, cov2, header = header2)
header = f"combined from {rascalc_results1} with {header1} and {rascalc_results2} with {header2}" # form the final header to include both

# Read pycorr files to figure out weights
weight1 = []
for pycorr_file1 in pycorr_files1:
xi_estimator1 = reshape_pycorr(TwoPointCorrelationFunction.load(pycorr_file1), n_mu = None, r_step = r_step, skip_r_bins = skip_r_bins).normalize()
weight1.append(get_counts_from_pycorr(xi_estimator1, counts_factor = 1))
weight1 = np.array(weight1)

n_r_bins = xi_estimator1.shape[0]
mu_edges = xi_estimator1.edges[1]

weight2 = []
for pycorr_file2 in pycorr_files2:
weight2.append(get_counts_from_pycorr(reshape_pycorr(TwoPointCorrelationFunction.load(pycorr_file2), n_mu = None, r_step = r_step, skip_r_bins = skip_r_bins).normalize(), counts_factor = 1))
weight2 = np.array(weight2)

# Normalize weights
sum_weight = weight1 + weight2
weight1 /= sum_weight
weight2 /= sum_weight

mu_leg_factors, leg_mu_factors = compute_mu_bin_legendre_factors(mu_edges, max_l, do_inverse = True)

# Derivatives of angularly binned 2PCF wrt Legendre are leg_mu_factors[ell//2, mu_bin]
# Angularly binned 2PCF are added with weights (normalized) weight1/2[tracer, r_bin, mu_bin]
# Derivatives of Legendre wrt binned 2PCF are mu_leg_factors[mu_bin, ell//2]
# So we need to sum such product over mu bins, while tracers and radial bins stay independent, and the partial derivative of combined 2PCF wrt the 2PCFs 1/2 will be
pd1 = np.einsum('il,tkl,lj,km,tr->tikrjm', leg_mu_factors, weight1, mu_leg_factors, np.eye(n_r_bins), np.eye(3)).reshape(n_bins, n_bins)
pd2 = np.einsum('il,tkl,lj,km,tr->tikrjm', leg_mu_factors, weight2, mu_leg_factors, np.eye(n_r_bins), np.eye(3)).reshape(n_bins, n_bins)
# We have correct [t_in, l_in, r_in, t_out, l_out, r_out] ordering and want to make these matrices in the end thus the reshape

# Produce and save combined cov
cov = pd1.T.dot(cov1).dot(pd1) + pd2.T.dot(cov2).dot(pd2)
np.savetxt(output_cov_file, cov, header=header) # includes source parts and their shot-noise rescaling values in the header
Loading