Initial import

This commit is contained in:
Guilhem Lavaux 2023-05-29 10:41:03 +02:00
commit 56a50eead3
820 changed files with 192077 additions and 0 deletions

39
src/CMakeLists.txt Normal file
View file

@ -0,0 +1,39 @@
set(DEP_LIBS
${COSMOTOOL_LIB}
${BOOST_LIBRARIES}
${HEALPIX_LIBRARIES}
${HDF5_CXX_LIBRARIES}
${HDF5_LIBRARIES}
${FFTW_LIBRARIES}
${GSL_LIBRARY}
${GSL_CBLAS_LIBRARY}
${ZLIB_LIBRARY}
${DL_LIBRARY}
${EXTRA_LIB}
)
IF(RT_LIBRARY)
SET(DEP_LIBS ${DEP_LIBS} ${RT_LIBRARY})
ENDIF(RT_LIBRARY)
include_directories(${ARES_INCLUDE_PATH}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${Boost_INCLUDE_DIRS})
add_executable(ares3 ares3.cpp)
target_link_libraries(ares3 LSS ${DEP_LIBS})
add_dependencies(ares3 ${ares_DEPS})
set_property(SOURCE ares3.cpp APPEND PROPERTY OBJECT_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/ares_mock_gen.hpp
${CMAKE_CURRENT_SOURCE_DIR}/ares_bundle.hpp
${CMAKE_CURRENT_SOURCE_DIR}/ares_bundle_init.hpp
${CMAKE_CURRENT_SOURCE_DIR}/ares_init.hpp)
foreach(module IN LISTS ARES_MODULES)
set(_fname ${CMAKE_SOURCE_DIR}/extra/${module}/src/tools.cmake)
if (EXISTS ${_fname})
SET(ARES_MODULE_DIR ${CMAKE_SOURCE_DIR}/extra/${module})
include(${_fname})
endif()
endforeach()

63
src/ares3.cpp Normal file
View file

@ -0,0 +1,63 @@
/*+
ARES/HADES/BORG Package -- ./src/ares3.cpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#define SAMPLER_DATA_INIT "../ares_init.hpp"
#define SAMPLER_BUNDLE "../ares_bundle.hpp"
#define SAMPLER_BUNDLE_INIT "../ares_bundle_init.hpp"
#define SAMPLER_NAME "ARES3"
#define SAMPLER_MOCK_GENERATOR "../ares_mock_gen.hpp"
#include "common/sampler_base.cpp"
#include "libLSS/tools/color_mod.hpp"
using namespace LibLSS::Color;
namespace {
void init_splash() {
static string splash_str[] = {
" ",
" o ",
" ,-.|____________________ ",
" O==+-|(>-------- -- - .> ",
" `- |\"\"\"\"\"\"\"d88b\"\"\"\"\"\"\"\"\" ",
" | o d8P 88b ",
" | \\ 98=, =88 ",
" | \\ 8b _, 88b ",
" `._ `. 8`..'888 ",
" | \\--'\\ `-8___ __________________________________",
" \\`-. \\ " +
fg(RED, "ARES3", BRIGHT) + " ",
" `. \\ - - / < (c) Jens Jasche 2012 - 2019 ",
" \\ `--- ___/|_-\\ Guilhem Lavaux 2014 - 2019 ",
" |._ _. |_-| __________________________________",
" \\ _ _ /.-\\ ",
" | -! . !- || | ",
" \\ \"| ^ |\" /\\ | ",
" =oO)<>(Oo= \\ / ",
" d8888888b < \\ ",
" d888888888b \\_/ ",
" d888888888b ",
"",
"Please acknowledge:",
" - Jasche, Kitaura, Wandelt, 2010, MNRAS, 406, 1 (arxiv 0911.2493)",
" - Jasche & Lavaux, 2015, MNRAS, 447, 2 (arxiv 1402.1763)",
" - Lavaux & Jasche, 2016, MNRAS, 455, 3 (arxiv 1509.05040)"};
static const int numSplashStr = sizeof(splash_str) / sizeof(splash_str[0]);
for (int i = 0; i < numSplashStr; i++)
Console::instance().print<LOG_STD>(splash_str[i]);
}
void close_splash() {}
RegisterStaticInit reg_splash(init_splash, close_splash, 12);
} // namespace

62
src/ares_bundle.hpp Normal file
View file

@ -0,0 +1,62 @@
/*+
ARES/HADES/BORG Package -- ./src/ares_bundle.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef _ARES_BUNDLE_HPP
#define _ARES_BUNDLE_HPP
#include "libLSS/samplers/ares/powerspectrum_a_sampler.hpp"
#include "libLSS/samplers/ares/powerspectrum_b_sampler.hpp"
#include "libLSS/samplers/ares/powerspectrum_c_sampler.hpp"
#include "libLSS/samplers/ares/gibbs_messenger.hpp"
#include "libLSS/samplers/ares/linbias_sampler.hpp"
#include "libLSS/samplers/ares/synthetic_selection.hpp"
#ifdef ARES_FOREGROUND_SUPPORT
#include "libLSS/samplers/ares/negative_foreground_sampler.hpp"
#endif
namespace LibLSS {
struct SamplerBundle {
PowerSpectrumSampler_a spectrum_a;
PowerSpectrumSampler_b spectrum_b;
PowerSpectrumSampler_c spectrum_c;
MessengerSampler sampler_t;
MessengerSignalSampler sampler_s;
CatalogProjectorSampler sampler_catalog_projector;
LinearBiasSampler lb_sampler;
BlockLoop foreground_block;
SyntheticSelectionUpdater sel_updater;
typedef std::list<MarkovSampler *> SamplerList;
SamplerList foreground_samplers;
SamplerBundle(MPI_Communication* comm)
: spectrum_a(comm), spectrum_b(comm), spectrum_c(comm), sampler_t(comm),
sampler_s(comm),
sampler_catalog_projector(comm), lb_sampler(comm), foreground_block(1) {}
void newForeground(int catalog, int fgmap) {
Console::instance().print<LOG_VERBOSE>("Adding new foreground sampler");
#ifdef ARES_FOREGROUND_SUPPORT
MarkovSampler *fg =
new NegativeForegroundSampler(comm, c, fgmap);
foreground_samplers.push_back(fg);
foreground_block << (*fg);
#endif
}
~SamplerBundle() {
for (SamplerList::iterator i = foreground_samplers.begin(); i != foreground_samplers.end();
++i) {
delete (*i);
}
}
};
}
#endif

56
src/ares_bundle_init.hpp Normal file
View file

@ -0,0 +1,56 @@
/*+
ARES/HADES/BORG Package -- ./src/ares_bundle_init.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef _ARES_BUNDLE_INIT_HPP
#define _ARES_BUNDLE_INIT_HPP
#include "ares_bundle.hpp"
namespace LibLSS {
template <typename ptree>
void sampler_bundle_init(
MPI_Communication *mpi_world, ptree &params, SamplerBundle &bundle,
MainLoop &loop, bool) {
int messenger_mixing =
params.template get<int>("system.messenger_mixing", 20);
int bias_mixing = params.template get<int>(
"system.bias_mixing",
6); //Push down. We are doing a 3 loop on FG+Nbar 20);
MarkovState &state = loop.get_state();
ptree system_params = params.get_child("system");
// Initialize foregrounds
LibLSS_prepare::initForegrounds(mpi_world, state, [&bundle](int c, int a) { bundle.newForeground(c, a); }, params);
adapt<bool>(state, system_params, "power_sampler_a_blocked", false);
adapt<bool>(state, system_params, "power_sampler_b_blocked", false);
adapt<bool>(state, system_params, "power_sampler_c_blocked", false);
adapt<bool>(state, system_params, "messenger_signal_blocked", false);
adapt<bool>(state, system_params, "bias_sampler_blocked", false);
// ==================
// MAIN LOOP PROGRAM
loop << bundle.sel_updater << bundle.sampler_catalog_projector
<< (BlockLoop(messenger_mixing)
<< bundle.sampler_t << bundle.sampler_s << bundle.spectrum_a
<< bundle.sampler_t << bundle.sampler_s << bundle.spectrum_b)
<< (BlockLoop(10) << bundle.foreground_block << bundle.sel_updater
<< (BlockLoop(bias_mixing) << bundle.lb_sampler))
<< bundle.spectrum_c;
}
template<typename ptree>
void sampler_setup_ic(SamplerBundle &bundle, MainLoop &loop, ptree const& params) {}
void sampler_bundle_cleanup() {}
} // namespace LibLSS
#endif

126
src/ares_init.hpp Normal file
View file

@ -0,0 +1,126 @@
/*+
ARES/HADES/BORG Package -- ./src/ares_init.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef __LIBLSS_ARES_COMMON_INIT_HPP
#define __LIBLSS_ARES_COMMON_INIT_HPP
#include "libLSS/mpi/generic_mpi.hpp"
#include "libLSS/tools/console.hpp"
#include "libLSS/samplers/core/main_loop.hpp"
#include "libLSS/mcmc/state_element.hpp"
#include "common/foreground.hpp"
namespace LibLSS_prepare {
template<typename PTree>
static bool check_is_simulation(PTree& params) {
return params.get_child("run").template get<bool>("SIMULATION", false);
}
template<typename PTree>
static void sampler_init_data(
MPI_Communication *mpi_world,
MarkovState& state, PTree& params)
{
LIBLSS_AUTO_CONTEXT(LOG_DEBUG, ctx);
long Ncat = state.getScalar<long>("NCAT");
// ==================
if (check_is_simulation(params)) {
for (int i = 0; i < Ncat; i++)
initializeHaloSimulationCatalog(
state,
params, i);
} else {
for (int i = 0; i < Ncat; i++)
initializeGalaxySurveyCatalog(
state,
params, i);
}
}
template<typename PTree>
static void sampler_load_data(
MPI_Communication *mpi_world,
MarkovState& state, PTree& params, MainLoop& loop)
{
LIBLSS_AUTO_CONTEXT(LOG_DEBUG, ctx);
CosmologicalParameters& cosmo = state.getScalar<CosmologicalParameters>("cosmology");
long Ncat = state.getScalar<long>("NCAT");
if (check_is_simulation(params)) {
for (int i = 0; i < Ncat; i++) {
loadHaloSimulationCatalog(
state, params,
i, cosmo);
}
} else {
for (int i = 0; i < Ncat; i++) {
loadGalaxySurveyCatalog(
state, params,
i, cosmo);
}
}
// Load&Build foregrounds
loadForegrounds(mpi_world, loop, params);
}
template<typename PTree>
static void sampler_setup_data(MPI_Communication *mpi_world,
MarkovState& state, PTree& params, MainLoop& loop)
{
LIBLSS_AUTO_CONTEXT(LOG_DEBUG, ctx);
long Ncat = state.getScalar<long>("NCAT");
CosmologicalParameters& cosmo = state.getScalar<CosmologicalParameters>("cosmology");
if (check_is_simulation(params)) {
for (int i = 0; i < Ncat; i++) {
SurveyPreparer preparer;
setupSimulationCatalog(state, params, i, cosmo, preparer);
state.newElement(boost::format("galaxy_preparer_%d") % i,
new TemporaryElement<SurveyPreparer>(preparer)
);
}
} else {
for (int i = 0; i < Ncat; i++) {
SurveyPreparer preparer;
setupGalaxySurveyCatalog(state, params, i, cosmo, preparer);
state.newElement(boost::format("galaxy_preparer_%d") % i,
new TemporaryElement<SurveyPreparer>(preparer)
);
}
}
}
template<typename PTree>
static void sampler_prepare_data(MPI_Communication *mpi_world,
MarkovState& state, PTree& params, MainLoop& loop)
{
long Ncat = state.getScalar<long>("NCAT");
CosmologicalParameters& cosmo = state.getScalar<CosmologicalParameters>("cosmology");
if (check_is_simulation(params)) {
for (int i = 0; i < Ncat; i++) {
auto& preparer = state.get<TemporaryElement<SurveyPreparer>>(boost::format("galaxy_preparer_%d") % i)->get();
prepareHaloSimulationData(mpi_world, state, i, cosmo, preparer, params);
}
} else {
for (int i = 0; i < Ncat; i++) {
auto& preparer = state.get<TemporaryElement<SurveyPreparer>>(boost::format("galaxy_preparer_%d") % i)->get();
prepareData(mpi_world, state, i, cosmo, preparer, params);
}
}
}
}
#endif

52
src/ares_mock_gen.hpp Normal file
View file

@ -0,0 +1,52 @@
/*+
ARES/HADES/BORG Package -- ./src/ares_mock_gen.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef __ARES_MOCK_GEN_HPP
#define __ARES_MOCK_GEN_HPP
namespace LibLSS {
template<typename PTree>
void prepareMockData(PTree& ptree, MPI_Communication *comm, MarkovState& state,
CosmologicalParameters& cosmo_params,
SamplerBundle& bundle
) {
ConsoleContext<LOG_INFO_SINGLE> ctx("prepareMockData");
using boost::format;
createCosmologicalPowerSpectrum(state, cosmo_params);
bundle.sel_updater.sample(state);
bundle.sampler_s.setMockGeneration(true);
bundle.sampler_catalog_projector.setMockGeneration(true);
// Generate the tau
bundle.sampler_catalog_projector.sample(state);
bundle.sampler_s.sample(state);
// Generate the data
bundle.sampler_catalog_projector.sample(state);
bundle.sampler_s.setMockGeneration(false);
bundle.sampler_t.setMockGeneration(false);
bundle.sampler_catalog_projector.setMockGeneration(false);
{
std::shared_ptr<H5::H5File> f;
if (comm->rank() == 0)
f = std::make_shared<H5::H5File>("mock_data.h5", H5F_ACC_TRUNC);
state.mpiSaveState(f, comm, false);
}
state.get<ArrayType>("s_field")->eigen().fill(0);
state.get<ArrayType>("x_field")->eigen().fill(0);
}
}
#endif

View file

@ -0,0 +1,180 @@
/*+
ARES/HADES/BORG Package -- ./src/common/configuration.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef _ARES3_CONFIGURATION_HPP
#define _ARES3_CONFIGURATION_HPP
#include <CosmoTool/algo.hpp>
#include <CosmoTool/fourier/fft/fftw_calls.hpp>
#include <cmath>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/algorithm/string.hpp>
#include "libLSS/tools/console.hpp"
#include "libLSS/samplers/core/main_loop.hpp"
#include "libLSS/samplers/core/types_samplers.hpp"
#include "libLSS/mcmc/state_sync.hpp"
#include <boost/algorithm/string.hpp>
#include "libLSS/data/projection.hpp"
#include "preparation_types.hpp"
#include "preparation_tools.hpp"
namespace LibLSS {
/**
* @brief This function loads the configuration stored in the property tree params and fills up
* the MarkovState dictionnary of the MainLoop
*
* @tparam PTree the property tree type, it will be deduced from parameter
* @param comm an MPI communicator
* @param loop the main loop to configure
* @param params the property tree filled up from a configuration file
*/
template <typename PTree>
inline void loadConfigurationFile(
MPI_Communication &comm, MainLoop &loop, PTree &params) {
using boost::format;
using boost::to_lower_copy;
using CosmoTool::square;
using details::property_accessor;
using std::sqrt;
long N0, N1, N2, Ndata0, Ndata1, Ndata2;
double L0, L1, L2;
double K_MAX, K_MIN;
Console &cons = Console::instance();
MarkovState &state = loop.get_state();
PTree system_params = params.get_child("system");
PTree cosmo_params = params.get_child("cosmology");
MPI_SyncBundle *syncBundle;
ptrdiff_t local_size, local_size1, localn0, startn0, localn1, startn1;
try {
cons.setVerboseLevel(
property_accessor<int>(system_params, "verbose_level"));
} catch (const boost::property_tree::ptree_bad_path &e) {
cons.print<LOG_INFO_SINGLE>(
"Missing option in configuration " +
e.path<typename PTree::path_type>().dump());
} catch (const ErrorParams &) {
cons.print<LOG_INFO_SINGLE>(
"Error ignored on VERBOSE_LEVEL"); // No parameter equal keep default value
}
if (auto o = system_params.template get_optional<int>("logfile_verbose_level")) {
cons.format<LOG_INFO_SINGLE>("Setting up logfile level to %d", *o);
cons.setLogfileVerboseLevel(*o);
}
// Load reconstruction box parameters
N0 = adapt<long>(state, system_params, "N0");
N1 = adapt<long>(state, system_params, "N1");
N2 = adapt<long>(state, system_params, "N2");
Ndata0 = adapt<long>(state, system_params, "Ndata0", N0);
Ndata1 = adapt<long>(state, system_params, "Ndata1", N1);
Ndata2 = adapt<long>(state, system_params, "Ndata2", N2);
cons.print<LOG_INFO_SINGLE>(
format("Got base resolution at %d x %d x %d") % N0 % N1 % N2);
state.newScalar<long>("N2_HC", N2 / 2 + 1);
size_t localNdata[6];
#ifdef ARES_MPI_FFTW
local_size =
MPI_FCalls::local_size_3d(N0, N1, N2, comm.comm(), &localn0, &startn0);
// Local size when first two dims are swapped
local_size1 =
MPI_FCalls::local_size_3d(N1, N0, N2, comm.comm(), &localn1, &startn1);
state.newScalar<long>("N2real", 2 * (N2 / 2 + 1));
{
ptrdiff_t data_localn0, data_startn0;
MPI_FCalls::local_size_3d(
Ndata0, Ndata1, Ndata2, comm.comm(), &data_localn0, &data_startn0);
localNdata[0] = data_startn0;
localNdata[1] = data_startn0 + data_localn0;
localNdata[2] = 0;
localNdata[3] = Ndata1;
localNdata[4] = 0;
localNdata[5] = Ndata2;
}
#else
state.newScalar<long>("N2real", N2);
local_size1 = local_size = N0 * N1 * (N2 / 2 + 1);
localn0 = N0;
startn0 = 0;
startn1 = 0;
localn1 = N1;
state.newScalar<long>("N2real", N2);
localNdata[0] = 0;
localNdata[1] = Ndata0;
localNdata[2] = 0;
localNdata[3] = Ndata1;
localNdata[4] = 0;
localNdata[5] = Ndata2;
#endif
for (int i = 0; i < 6; i++)
state.newScalar<long>(boost::format("localNdata%d") % i, localNdata[i])
->setDoNotRestore(true);
state.newScalar<long>("startN0", startn0);
state.newScalar<long>("localN0", localn0);
state.newScalar<long>("fourierLocalSize", local_size);
state.newScalar<long>("startN1", startn0);
state.newScalar<long>("localN1", localn0);
state.newScalar<long>("fourierLocalSize1", local_size1);
L0 = adapt<double>(state, system_params, "L0");
L1 = adapt<double>(state, system_params, "L1");
L2 = adapt<double>(state, system_params, "L2");
adapt<double>(state, system_params, "corner0");
adapt<double>(state, system_params, "corner1");
adapt<double>(state, system_params, "corner2");
K_MAX =
M_PI * sqrt(square(N0 / L0) + square(N1 / L1) + square(N2 / L2)) * 1.1;
K_MIN = 0;
state.newScalar<double>("K_MAX", K_MAX);
state.newScalar<double>("K_MIN", K_MIN);
adapt<long>(state, system_params, "NUM_MODES");
adapt<double>(state, system_params, "ares_heat", 1.0);
ScalarStateElement<CosmologicalParameters> *s_cosmo =
new ScalarStateElement<CosmologicalParameters>();
CosmologicalParameters &cosmo = s_cosmo->value;
// Load cosmology
cosmo.omega_r = property_accessor<double>(cosmo_params, "omega_r");
cosmo.omega_k = property_accessor<double>(cosmo_params, "omega_k");
cosmo.omega_m = property_accessor<double>(cosmo_params, "omega_m");
cosmo.omega_b = property_accessor<double>(cosmo_params, "omega_b");
cosmo.omega_q = property_accessor<double>(cosmo_params, "omega_q");
cosmo.w = property_accessor<double>(cosmo_params, "w");
cosmo.n_s = property_accessor<double>(cosmo_params, "n_s");
cosmo.fnl = property_accessor<double>(cosmo_params, "fnl");
cosmo.wprime = property_accessor<double>(cosmo_params, "wprime");
cosmo.sigma8 = property_accessor<double>(cosmo_params, "sigma8");
cosmo.h = property_accessor<double>(cosmo_params, "h100");
cosmo.beta = property_accessor<double>(cosmo_params, "beta");
cosmo.z0 = property_accessor<double>(cosmo_params, "z0");
cosmo.a0 = 1;
state.newElement("cosmology", s_cosmo, true); //true);
}
} // namespace LibLSS
#endif

188
src/common/foreground.hpp Normal file
View file

@ -0,0 +1,188 @@
/*+
ARES/HADES/BORG Package -- ./src/common/foreground.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef __ARES_FOREGROUND_HPP
#define __ARES_FOREGROUND_HPP
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/split.hpp>
#include <cmath>
#include <string>
#include <healpix_cxx/pointing.h>
#include <healpix_cxx/healpix_map.h>
#include <healpix_cxx/healpix_map_fitsio.h>
#include "libLSS/samplers/core/main_loop.hpp"
#include "libLSS/samplers/ares/ares_sampler_option.hpp"
#include "libLSS/mpi/generic_mpi.hpp"
#include "libLSS/samplers/core/main_loop.hpp"
#include "preparation_tools.hpp"
namespace LibLSS_prepare {
namespace details {
class ForegroundAdaptor {
protected:
Healpix_Map<double> sky;
public:
// Use concepts of sky selection
void loadSky(const std::string &fname) {
read_Healpix_map_from_fits(fname, sky);
for (long n = 0; n < sky.Npix(); n++) {
if (std::isnan(sky[n]))
sky[n] = 0;
}
}
double get_sky_completeness(double x, double y, double z) const {
return sky[sky.vec2pix(vec3(x, y, z))];
}
int getNumRadial() const { return 0; }
double getRadialSelection(double r, int n) const { return 1; }
};
} // namespace details
inline std::string get_foreground_group_name(int fg) {
return boost::str(boost::format("foreground_%d") % fg);
}
template <typename ptree>
void initForegrounds(
LibLSS::MPI_Communication *comm, MarkovState &state,
std::function<void(int, int)> add_combo, ptree &params) {
using boost::format;
using boost::str;
using PrepareDetail::ArrayDimension;
using namespace LibLSS;
using namespace boost::algorithm;
using std::string;
ConsoleContext<LOG_INFO> ctx("initForegrounds");
int Nforegrounds;
long N0 = static_cast<SLong &>(state["N0"]),
N1 = static_cast<SLong &>(state["N1"]),
N2 = static_cast<SLong &>(state["N2"]),
localN0 = static_cast<SLong &>(state["localN0"]),
startN0 = static_cast<SLong &>(state["startN0"]);
int Ncatalog = static_cast<SLong &>(state["NCAT"]);
ptree sys_params = params.get_child("system");
Nforegrounds = adapt<int>(state, sys_params, "NFOREGROUNDS", 0);
ctx.print(format("Loading %d foreground data") % Nforegrounds);
for (int fg = 0; fg < Nforegrounds; fg++) {
ptree fg_params = params.get_child(get_foreground_group_name(fg));
string fgmapname = fg_params.template get<std::string>("fgmap");
ctx.print2<LOG_DEBUG>(format("Allocating 3d foreground %d") % fg);
ArrayType *mask_grid = new ArrayType(
boost::extents[range(startN0, startN0 + localN0)][N1][N2]);
mask_grid->setRealDims(ArrayDimension(N0, N1, N2));
state.newElement(format("foreground_3d_%d") % fg, mask_grid);
}
for (int c = 0; c < Ncatalog; c++) {
ptree cat_params = params.get_child(get_catalog_group_name(c));
int Ncoef;
std::vector<string> fg_map_list_str, fg_map_values_str;
bool value_provided = false;
if (boost::optional<string> fg_option =
cat_params.template get_optional<string>(
"fg_map_negative_list")) {
ctx.print("Splitting '" + *fg_option + "'");
split(fg_map_list_str, *fg_option, is_any_of(", "), token_compress_on);
}
if (boost::optional<string> fg_option =
cat_params.template get_optional<string>(
"fg_map_negative_values")) {
ctx.print("Splitting '" + *fg_option + "'");
split(
fg_map_values_str, *fg_option, is_any_of(", "), token_compress_on);
value_provided = true;
if (fg_map_values_str.size() != fg_map_list_str.size()) {
error_helper<ErrorParams>(
"If foreground values are provided they must have the same size "
"as the foreground set");
}
}
Ncoef = fg_map_list_str.size();
ArrayType1d *fg_coefficient = new ArrayType1d(boost::extents[Ncoef]);
IArrayType1d *fg_map = new IArrayType1d(boost::extents[Ncoef]);
for (int e = 0; e < Ncoef; e++) {
(*fg_map->array)[e] = boost::lexical_cast<int>(fg_map_list_str[e]);
(*fg_coefficient->array)[e] =
value_provided ? (boost::lexical_cast<double>(fg_map_values_str[e]))
: 0;
adapt<bool>(
state, sys_params,
str(format("negative_foreground_%d_%d_blocked") % c % e), false);
// Add a new (catalog,foreground) combo
add_combo(c, (*fg_map->array)[e]);
}
state.newElement(
format("catalog_foreground_coefficient_%d") % c, fg_coefficient,
true);
state.newElement(format("catalog_foreground_maps_%d") % c, fg_map);
}
adapt<bool>(state, sys_params, "total_foreground_blocked", false);
}
template <typename ptree>
void loadForegrounds(
LibLSS::MPI_Communication *comm, LibLSS::MainLoop &loop, ptree &params) {
using boost::format;
using boost::str;
using PrepareDetail::ArrayDimension;
using std::string;
using namespace LibLSS;
ConsoleContext<LOG_INFO> ctx("loadForegrounds");
MarkovState &state = loop.get_state();
int Nforegrounds;
ptree sys_params = params.get_child("system");
Nforegrounds = state.getScalar<int>("NFOREGROUNDS");
ctx.print(format("Loading %d foregrounds") % Nforegrounds);
for (int fg = 0; fg < Nforegrounds; fg++) {
ptree fg_params = params.get_child(get_foreground_group_name(fg));
string fgmapname = fg_params.template get<std::string>("fgmap");
details::ForegroundAdaptor fg_a;
fg_a.loadSky(fgmapname);
ArrayType *mask_grid =
state.get<ArrayType>(format("foreground_3d_%d") % fg);
PrepareDetail::compute_window(
sys_params, comm, fg_a, state, *mask_grid->array, false);
mask_grid->loaded();
}
}
} // namespace LibLSS_prepare
#endif

43
src/common/ketable.hpp Normal file
View file

@ -0,0 +1,43 @@
/*+
ARES/HADES/BORG Package -- ./src/common/ketable.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef __LIBLSS_KETABLE_HPP
#define __LIBLSS_KETABLE_HPP
#include <CosmoTool/interpolate.hpp>
#include <string>
#include <H5Cpp.h>
namespace LibLSS {
class KETableCorrection {
protected:
bool no_correction;
CosmoTool::Interpolate data;
public:
KETableCorrection() { no_correction = true; }
KETableCorrection(const std::string &fname)
: data(CosmoTool::buildInterpolateFromFile(fname.c_str())),
no_correction(false) {}
double getZCorrection(double z) {
if (no_correction)
return 0;
else
return data.compute(z);
}
void save(H5_CommonFileGroup &fg) {}
void restore(H5_CommonFileGroup &fg) {}
};
} // namespace LibLSS
#endif

23
src/common/mock_gen.hpp Normal file
View file

@ -0,0 +1,23 @@
/*+
ARES/HADES/BORG Package -- ./src/common/mock_gen.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef __ARES_MOCK_DATA_HPP
#define __ARES_MOCK_DATA_HPP
#include <CosmoTool/algo.hpp>
#include <CosmoTool/cosmopower.hpp>
#include "libLSS/tools/console.hpp"
#include "libLSS/tools/log_traits.hpp"
#include <boost/format.hpp>
#include "configuration.hpp"
#include "libLSS/physics/cosmo_power.hpp"
#include SAMPLER_MOCK_GENERATOR
#endif

View file

@ -0,0 +1,65 @@
/*+
ARES/HADES/BORG Package -- ./src/common/piecewise_selection.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef __LIBLSS_PIECEWISE_SELECTION_HPP
#define __LIBLSS_PIECEWISE_SELECTION_HPP
/*
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/density.hpp>
*/
#include <CosmoTool/algo.hpp>
#include "libLSS/tools/console.hpp"
#include "libLSS/data/spectro_gals.hpp"
#include "libLSS/data/spectro_gals.hpp"
#include "libLSS/data/galaxies.hpp"
#include "libLSS/samplers/core/types_samplers.hpp"
namespace LibLSS {
template <typename GalaxySurvey>
void computeEmpiricalSelection(
GalaxySurvey *survey, GalaxySampleSelection &infosel, double dMin,
double dMax, int Nbins) {
using CosmoTool::cube;
boost::multi_array<double, 1> completeness(boost::extents[Nbins]);
std::fill(
completeness.data(), completeness.data() + completeness.num_elements(),
0);
for (int i = 0; i < survey->surveySize(); i++) {
if (!(*infosel.selector)((*survey)[i]))
continue;
double d = (*survey)[i].r;
int iD = (int)floor((d - dMin) * (Nbins) / (dMax - dMin));
if (iD < Nbins && iD >= 0)
completeness[iD]++;
}
double c_max = 0;
for (int i = 0; i < Nbins; i++) {
double r0 = dMin + i * (dMax - dMin) / (Nbins);
double r1 = dMin + (i + 1) * (dMax - dMin) / (Nbins);
completeness[i] /= cube(r1) - cube(r0);
c_max = std::max(completeness[i], c_max);
}
for (int i = 0; i < Nbins; i++) {
completeness[i] /= c_max;
}
survey->selection().setArray(completeness, dMax);
survey->selection().setMinMaxDistances(0, dMax);
}
}; // namespace LibLSS
#endif

540
src/common/preparation.hpp Normal file
View file

@ -0,0 +1,540 @@
/*+
ARES/HADES/BORG Package -- ./src/common/preparation.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef __LIBLSS_ARES_PREPARATION_HPP
#define __LIBLSS_ARES_PREPARATION_HPP
#include <functional>
#include "libLSS/tools/console.hpp"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include "libLSS/tools/ptree_translators.hpp"
#include <boost/algorithm/string.hpp>
#include "libLSS/data/spectro_gals.hpp"
#include "libLSS/data/galaxies.hpp"
#include "libLSS/data/survey_load_txt.hpp"
#include "libLSS/data/survey_load_bin.hpp"
#include "libLSS/data/projection.hpp"
#include "libLSS/data/linear_selection.hpp"
#include "libLSS/data/window3d.hpp"
#include "libLSS/data/window3d_post.hpp"
#include "libLSS/data/schechter_completeness.hpp"
#include "survey_cutters.hpp"
#include "piecewise_selection.hpp"
#include "ketable.hpp"
#include <CosmoTool/interpolate.hpp>
#include "libLSS/tools/ptree_vectors.hpp"
#include "libLSS/tools/fused_array.hpp"
#include "libLSS/tools/fused_assign.hpp"
#include "libLSS/tools/fusewrapper.hpp"
#include "libLSS/physics/modified_ngp.hpp"
#include "libLSS/physics/classic_cic.hpp"
#include "preparation_types.hpp"
#include "preparation_tools.hpp"
namespace LibLSS_prepare {
static void
initSchechterVariables(MarkovState &state, ptree &params, int cat_idx) {
state.newElement(
format("galaxy_selection_info_%d") % cat_idx,
new InfoSampleSelection());
state.newElement(
format("galaxy_schechter_%d") % cat_idx, new InfoSchechter());
}
static GalaxySurveyType &
getGalaxyCatalog(MarkovState &state, size_t cat_idx) {
return *state.get<GalaxyElement>(format("galaxy_catalog_%d") % cat_idx)
->obj;
}
template <typename Function>
SurveyPreparer resolveGalaxySurvey(MarkovState &state, Function f) {
return [f, &state](
size_t cat_idx, ArrayType::ArrayType &grid, size_t *const &N,
double *const &corner, double *const &L, double *const &delta) {
return f(getGalaxyCatalog(state, cat_idx), grid, N, corner, L, delta);
};
}
static void initializeGalaxySurveyCatalog(
MarkovState &state, ptree &main_params, int cat_idx) {
using PrepareDetail::ArrayDimension;
std::array<size_t, 3> Ndata, N;
std::array<size_t, 6> localNdata;
size_t startN0, localN0;
Console &cons = Console::instance();
ptree &params = main_params.get_child(get_catalog_group_name(cat_idx));
state.getScalarArray<long, 3>("Ndata", Ndata);
state.getScalarArray<long, 6>("localNdata", localNdata);
GalaxyElement *survey = new GalaxyElement();
survey->obj = new GalaxySurveyType();
// Add a catalog in the state structure
state.newElement(format("galaxy_catalog_%d") % cat_idx, survey);
// Add its linear bias in the MCMC structure
ArrayType1d *bias = new ArrayType1d(boost::extents[0]);
state.newElement(format("galaxy_bias_%d") % cat_idx, bias, true);
double &nmean =
state.newScalar<double>(format("galaxy_nmean_%d") % cat_idx, 1.0, true)
->value;
bias->setAutoResize(true);
auto data_ext = boost::extents[range(localNdata[0], localNdata[1])][range(
localNdata[2], localNdata[3])][range(localNdata[4], localNdata[5])];
auto data_dim = ArrayDimension(Ndata[0], Ndata[1], Ndata[2]);
SelArrayType *sel_grid = new SelArrayType(data_ext);
ArrayType *data_grid = new ArrayType(data_ext);
cons.format<LOG_VERBOSE>(
"Catalog %d: data grid is %dx%dx%d", cat_idx, Ndata[0], Ndata[1],
Ndata[2]);
data_grid->setRealDims(data_dim);
sel_grid->setRealDims(data_dim);
state.newScalar(format("galaxy_bias_ref_%d") % cat_idx, false);
state.newElement(format("galaxy_sel_window_%d") % cat_idx, sel_grid);
state.newElement(format("galaxy_data_%d") % cat_idx, data_grid);
KECorrectionStateElement *ke_obj = new KECorrectionStateElement();
KETableCorrection *ke;
state.newElement(format("galaxy_kecorrection_%d") % cat_idx, ke_obj);
if (boost::optional<string> ketable =
params.get_optional<string>("ke_correction")) {
cons.print<LOG_INFO_SINGLE>("Applying correction from file " + *ketable);
ke = new KETableCorrection(*ketable);
} else {
ke = new KETableCorrection();
}
ke_obj->obj = ke;
string radtype = to_lower_copy(params.get<string>("radial_selection"));
if (radtype == "schechter") {
cons.print<LOG_DEBUG>("initializing Schechter radial selection");
initSchechterVariables(state, params, cat_idx);
} else if (radtype == "piecewise") {
cons.print<LOG_DEBUG>("initializing Piecewise selection");
state.newElement(
format("galaxy_selection_info_%d") % cat_idx,
new InfoSampleSelection());
} else if (radtype == "file") {
state.newElement(
format("galaxy_selection_info_%d") % cat_idx,
new InfoSampleSelection());
}
}
static void buildSchechterSelectionForSurvey(
GalaxySurveyType &survey, MarkovState &state, ptree &params, int cat_idx,
CosmologicalParameters &cosmo_params, SurveyPreparer &preparer,
CorrectionFunction zcorr = LibLSS::details::nullCorrection) {
ConsoleContext<LOG_INFO_SINGLE> ctx("schechter completeness for survey");
Cosmology cosmo(cosmo_params);
int Nsample = params.get<int>("schechter_sampling_rate");
double Dmax = params.get<double>("schechter_dmax");
boost::multi_array<double, 1> completeness(boost::extents[Nsample]);
namespace ph = std::placeholders;
GalaxySampleSelection &infosel =
state
.get<InfoSampleSelection>(
format("galaxy_selection_info_%d") % cat_idx)
->value;
SchechterParameters &infolum =
state.get<InfoSchechter>(format("galaxy_schechter_%d") % cat_idx)
->value;
KETableCorrection &ke = state
.get<KECorrectionStateElement>(
format("galaxy_kecorrection_%d") % cat_idx)
->get();
infosel.bright_apparent_magnitude_cut =
params.get<double>("galaxy_bright_apparent_magnitude_cut");
infosel.faint_apparent_magnitude_cut =
params.get<double>("galaxy_faint_apparent_magnitude_cut");
infosel.bright_absolute_magnitude_cut =
params.get<double>("galaxy_bright_absolute_magnitude_cut");
infosel.faint_absolute_magnitude_cut =
params.get<double>("galaxy_faint_absolute_magnitude_cut");
infosel.zmin = params.get<double>("zmin", 0);
infosel.zmax = params.get<double>("zmax", 100000);
infosel.projection =
state.getScalar<ProjectionDataModel>("projection_model");
infolum.Mstar = params.get<double>("schechter_mstar");
infolum.alpha = params.get<double>("schechter_alpha");
buildCompletenessFromSchechterFunction(
cosmo, infosel, infolum, completeness, Dmax,
std::bind(
&KETableCorrection::getZCorrection, &ke, std::placeholders::_1));
survey.selection().setArray(completeness, Dmax);
survey.selection().setMinMaxDistances(0, Dmax);
switch (infosel.projection) {
case NGP_PROJECTION:
preparer = resolveGalaxySurvey(
state,
std::bind<size_t>(
galaxySurveyToGridGeneric<
ModifiedNGP<double, NGPGrid::NGP, true>,
CIC_Tools::NonPeriodic, GalaxySurveyType,
ArrayType::ArrayType, double *, size_t *,
RedshiftMagnitudeCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
RedshiftMagnitudeCutter<GalaxySurveyType>(infosel, &survey),
std::function<void()>()));
break;
case LUMINOSITY_CIC_PROJECTION: {
preparer = resolveGalaxySurvey(
state,
std::bind<size_t>(
galaxySurveyToGridGeneric<
ClassicCloudInCell<double, true>, CIC_Tools::NonPeriodic,
GalaxySurveyType, ArrayType::ArrayType, double *, size_t *,
RedshiftMagnitudeCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
RedshiftMagnitudeCutter<GalaxySurveyType>(infosel, &survey),
std::function<void()>(std::bind(
&GalaxySurveyType::useLuminosityAsWeight, &survey))));
break;
}
default:
error_helper<ErrorParams>("Unsupported data projection");
break;
}
}
static void buildPiecewiseSelection(
GalaxySurveyType &survey, MarkovState &state, ptree &params, int cat_idx,
CosmologicalParameters &cosmo_params, SurveyPreparer &preparer) {
namespace ph = std::placeholders;
GalaxySampleSelection &infosel =
state
.get<InfoSampleSelection>(
format("galaxy_selection_info_%d") % cat_idx)
->value;
infosel.bright_apparent_magnitude_cut =
params.get<double>("galaxy_bright_apparent_magnitude_cut");
infosel.faint_apparent_magnitude_cut =
params.get<double>("galaxy_faint_apparent_magnitude_cut");
infosel.bright_absolute_magnitude_cut =
params.get<double>("galaxy_bright_absolute_magnitude_cut");
infosel.faint_absolute_magnitude_cut =
params.get<double>("galaxy_faint_absolute_magnitude_cut");
infosel.zmin = params.get<double>("zmin");
infosel.zmax = params.get<double>("zmax");
infosel.projection =
state.getScalar<ProjectionDataModel>("projection_model");
infosel.selector = makeSelector(cutterFunction(
RedshiftMagnitudeCutter<GalaxySurveyType>(infosel, &survey)));
switch (state.getScalar<ProjectionDataModel>("projection_model")) {
case NGP_PROJECTION:
preparer = resolveGalaxySurvey(
state,
std::bind<size_t>(
galaxySurveyToGridGeneric<
ModifiedNGP<double, NGPGrid::NGP, true>,
CIC_Tools::NonPeriodic, GalaxySurveyType,
ArrayType::ArrayType, double *, size_t *,
RedshiftMagnitudeCutter<GalaxySurveyType>,
std::function<void()>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
RedshiftMagnitudeCutter<GalaxySurveyType>(infosel, &survey),
std::function<void()>()));
break;
// If the projection is LUMINOSITY_CIC, then we have to use a CIC kernel
case LUMINOSITY_CIC_PROJECTION:
preparer = resolveGalaxySurvey(
state,
std::bind<size_t>(
galaxySurveyToGridGeneric<
ClassicCloudInCell<double, true>, CIC_Tools::NonPeriodic,
GalaxySurveyType, ArrayType::ArrayType, double *, size_t *,
RedshiftMagnitudeCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
RedshiftMagnitudeCutter<GalaxySurveyType>(infosel, &survey),
std::function<void()>(std::bind(
&GalaxySurveyType::useLuminosityAsWeight, &survey))));
break;
}
}
static void buildFileSelectionForSurvey(
GalaxySurveyType &survey, MarkovState &state, ptree &params, int cat_idx,
CosmologicalParameters &cosmo_params, SurveyPreparer &preparer) {
using LibLSS::details::safe_get;
namespace ph = std::placeholders;
ConsoleContext<LOG_INFO_SINGLE> ctx("file completeness for survey");
string radial_map = params.get<string>("radial_file");
ctx.print(format("Load radial selection function '%s'") % radial_map);
survey.selection().loadRadial(radial_map);
GalaxySampleSelection &selection =
state
.get<InfoSampleSelection>(
format("galaxy_selection_info_%d") % cat_idx)
->value;
selection.zmin = params.get<double>("zmin", 0);
selection.zmax = params.get<double>("zmax", 100000);
selection.projection =
state.getScalar<ProjectionDataModel>("projection_model");
if (!safe_get(
params, "galaxy_bright_apparent_magnitude_cut",
selection.bright_apparent_magnitude_cut) ||
!safe_get(
params, "galaxy_faint_apparent_magnitude_cut",
selection.faint_apparent_magnitude_cut) ||
!safe_get(
params, "galaxy_bright_absolute_magnitude_cut",
selection.bright_absolute_magnitude_cut) ||
!safe_get(
params, "galaxy_faint_absolute_magnitude_cut",
selection.faint_absolute_magnitude_cut)) {
ctx.print("No information on luminosity cuts. Taking all galaxies inside "
"a d range");
bool no_cut_catalog = true;
if (!safe_get(params, "no_cut_catalog", no_cut_catalog) && no_cut_catalog)
error_helper<ErrorParams>(
boost::format(
"You have to confirm not to cut properly your catalog %d") %
cat_idx);
try {
selection.dmin = params.get<double>("file_dmin", 0);
selection.dmax =
params.get<double>("file_dmax", 1e6); // No cut effectively
survey.selection().setMinMaxDistances(selection.dmin, selection.dmax);
} catch (const std::runtime_error &) {
error_helper<ErrorParams>(
"Incorrect/Unknown file_dmin or file_dmax in configuration file");
}
preparer = resolveGalaxySurvey(
state, std::bind<size_t>(
galaxySurveyToGridGeneric<
ModifiedNGP<double, NGPGrid::NGP, true>,
CIC_Tools::NonPeriodic, GalaxySurveyType,
ArrayType::ArrayType, double *, size_t *,
DistanceCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
DistanceCutter<GalaxySurveyType>(selection, &survey),
std::function<void()>()));
} else {
Cosmology cosmo(cosmo_params);
selection.dmin = cosmo.com2comph(cosmo.a2com(cosmo.z2a(selection.zmin)));
selection.dmax = cosmo.com2comph(cosmo.a2com(cosmo.z2a(selection.zmax)));
survey.selection().setMinMaxDistances(selection.dmin, selection.dmax);
preparer = resolveGalaxySurvey(
state,
std::bind<size_t>(
galaxySurveyToGridGeneric<
ModifiedNGP<double, NGPGrid::NGP, true>,
CIC_Tools::NonPeriodic, GalaxySurveyType,
ArrayType::ArrayType, double *, size_t *,
RedshiftMagnitudeCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
RedshiftMagnitudeCutter<GalaxySurveyType>(selection, &survey),
std::function<void()>()));
}
}
static void loadGalaxySurveyCatalog(
MarkovState &state, ptree &main_params, int cat_idx,
CosmologicalParameters &cosmo) {
ConsoleContext<LOG_INFO_SINGLE> ctx(
str(format("loadGalaxySurveyCatalog(%d)") % cat_idx));
GalaxyElement *survey =
state.get<GalaxyElement>(format("galaxy_catalog_%d") % cat_idx);
ptree &params = main_params.get_child(get_catalog_group_name(cat_idx));
std::string data_format = params.get<std::string>("dataformat", "TXT");
if (data_format == "TXT") {
loadGalaxySurveyFromText(params.get<string>("datafile"), survey->get());
} else if (data_format == "HDF5") {
loadCatalogFromHDF5(
params.get<string>("datafile"), params.get<string>("datakey"),
survey->get());
} else {
error_helper<ErrorParams>(
format("data_format has value %s, which is not recognized") %
data_format);
}
state.getScalar<bool>(format("galaxy_bias_ref_%d") % cat_idx) =
params.get<bool>("refbias");
ArrayType1d::ArrayType &gbias =
*(state.get<ArrayType1d>(format("galaxy_bias_%d") % cat_idx)->array);
if (boost::optional<std::string> bvalue =
params.get_optional<std::string>("bias")) {
auto bias_double = string_as_vector<double>(*bvalue, ", ");
gbias.resize(boost::extents[bias_double.size()]);
std::copy(bias_double.begin(), bias_double.end(), gbias.begin());
ctx.print("Set the bias to [" + to_string(gbias) + "]");
} else {
ctx.print("No initial bias value set, use bias=1");
gbias.resize(boost::extents[1]);
gbias[0] = 1;
}
double &nmean =
state.get<SDouble>(format("galaxy_nmean_%d") % cat_idx)->value;
if (boost::optional<double> nvalue = params.get_optional<double>("nmean")) {
nmean = *nvalue;
} else {
ctx.print("No initial mean density value set, use nmean=1");
nmean = 1;
}
string compl_map = params.get<string>("maskdata");
ctx.print(format("Load sky completeness map '%s'") % compl_map);
survey->get().selection().loadSky(
compl_map, params.get<double>("sky_threshold", 0));
}
static void setupGalaxySurveyCatalog(
MarkovState &state, ptree &main_params, int cat_idx,
CosmologicalParameters &cosmo_params, SurveyPreparer &preparer) {
ConsoleContext<LOG_INFO_SINGLE> ctx(
str(format("loadGalaxySurveyCatalog(%d)") % cat_idx));
auto &survey = getGalaxyCatalog(state, cat_idx);
ptree &params = main_params.get_child(get_catalog_group_name(cat_idx));
string radtype = to_lower_copy(params.get<string>("radial_selection"));
GalaxySelectionType &gsel_type =
state
.newScalar<GalaxySelectionType>(
format("galaxy_selection_type_%d") % cat_idx,
GALAXY_SELECTION_FILE)
->value;
if (radtype == "file") {
buildFileSelectionForSurvey(
survey, state, params, cat_idx, cosmo_params, preparer);
gsel_type = GALAXY_SELECTION_FILE;
} else if (radtype == "schechter") {
buildSchechterSelectionForSurvey(
survey, state, params, cat_idx, cosmo_params, preparer);
gsel_type = GALAXY_SELECTION_SCHECHTER;
} else if (radtype == "piecewise") {
gsel_type = GALAXY_SELECTION_PIECEWISE;
buildPiecewiseSelection(
survey, state, params, cat_idx, cosmo_params, preparer);
} else {
error_helper<ErrorParams>(
format("radtype has value %s, which is not recognized") % radtype);
}
}
template <typename ptree>
void prepareData(
MPI_Communication *comm, MarkovState &state, int cat_idx,
CosmologicalParameters &cosmo_params, const SurveyPreparer &preparer,
ptree &main_params) {
ConsoleContext<LOG_INFO_SINGLE> ctx("data preparation");
using CosmoTool::InvalidRangeException;
size_t Ndata[3], localNdata[6];
double L[3], delta[3], corner[3];
state.getScalarArray<long, 3>("Ndata", Ndata);
state.getScalarArray<long, 6>("localNdata", localNdata);
state.getScalarArray<double, 3>("L", L);
state.getScalarArray<double, 3>("corner", corner);
size_t N2_HC = static_cast<SLong &>(state["N2_HC"]),
localN0 = static_cast<SLong &>(state["localN0"]),
startN0 = static_cast<SLong &>(state["startN0"]);
Cosmology cosmo(cosmo_params);
ptree &sys_params = main_params.get_child("system");
ptree &g_params = main_params.get_child(get_catalog_group_name(cat_idx));
ctx.print(
format("Project data to density field grid (catalog %d)") % cat_idx);
GalaxySurveyType &survey =
state.get<GalaxyElement>(str(format("galaxy_catalog_%d") % cat_idx))
->get();
KECorrectionStateElement *ke = state.get<KECorrectionStateElement>(
format("galaxy_kecorrection_%d") % cat_idx);
try {
survey.updateComovingDistance(
cosmo, std::bind(
&KETableCorrection::getZCorrection, ke->obj,
std::placeholders::_1));
} catch (const InvalidRangeException &e) {
error_helper<ErrorBadState>(
"Invalid range access in KE correction interpolation");
}
ArrayType *data_grid =
state.get<ArrayType>(format("galaxy_data_%d") % cat_idx);
delta[0] = L[0] / Ndata[0];
delta[1] = L[1] / Ndata[1];
delta[2] = L[2] / Ndata[2];
size_t numGals =
preparer(cat_idx, *(data_grid->array), Ndata, corner, L, delta);
comm->all_reduce_t(MPI_IN_PLACE, &numGals, 1, MPI_SUM);
if (numGals == 0) {
error_helper<ErrorBadState>(
format("No galaxy at all in catalog %d") % cat_idx);
}
GalaxySelectionType &gsel_type = state.getScalar<GalaxySelectionType>(
format("galaxy_selection_type_%d") % cat_idx);
GalaxySampleSelection &infosel =
state
.get<InfoSampleSelection>(
format("galaxy_selection_info_%d") % cat_idx)
->value;
if (gsel_type == GALAXY_SELECTION_PIECEWISE) {
computeEmpiricalSelection(
&survey, infosel, g_params.template get<double>("piecewise_dmin"),
g_params.template get<double>("piecewise_dmax"),
g_params.template get<int>("piecewise_Nbins"));
}
SelArrayType *sel_grid =
state.get<SelArrayType>(format("galaxy_sel_window_%d") % cat_idx);
PrepareDetail::compute_window(
sys_params, comm, survey.selection(), state, *sel_grid->array, true);
if (infosel.projection == LUMINOSITY_CIC_PROJECTION) {
convolve_selection_cic(comm, *sel_grid->array, Ndata);
}
auto fsel = fwrap(*sel_grid->array);
fsel = mask(fsel > 0.05, fsel, fwrap(fsel.fautowrap(0)));
PrepareDetail::cleanup_data(*data_grid->array, *sel_grid->array);
// Free memory at the expense of information in logs
survey.selection().clearSky();
}
} // namespace LibLSS_prepare
#endif

View file

@ -0,0 +1,502 @@
/*+
ARES/HADES/BORG Package -- ./src/common/preparation_simulation.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef __LIBLSS_ARES_PREPARATION_SIMULATION_HPP
#define __LIBLSS_ARES_PREPARATION_SIMULATION_HPP
#include "libLSS/tools/console.hpp"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include "libLSS/tools/ptree_translators.hpp"
#include <boost/algorithm/string.hpp>
#include "libLSS/data/spectro_gals.hpp"
#include "libLSS/data/galaxies.hpp"
#include "libLSS/data/survey_load_txt.hpp"
#include "libLSS/data/survey_load_bin.hpp"
#include "libLSS/data/projection.hpp"
#include "libLSS/data/schechter_completeness.hpp"
#include "survey_cutters.hpp"
#include <CosmoTool/interpolate.hpp>
#include "libLSS/tools/ptree_vectors.hpp"
#include "libLSS/tools/fused_array.hpp"
#include "libLSS/tools/fused_assign.hpp"
#include "preparation.hpp"
#include <boost/tokenizer.hpp>
#include <string>
namespace LibLSS_prepare {
using namespace LibLSS;
typedef boost::multi_array_types::extent_range range;
typedef RandomNumberMPI<GSL_RandomNumber> RGenType;
typedef ScalarStateElement<GalaxySampleSelection> InfoSampleSelection;
static GalaxySurveyType &getHaloCatalog(MarkovState &state, size_t cat_idx) {
return state.get<GalaxyElement>(str(format("halo_catalog_%d") % cat_idx))
->get();
}
template <typename Function>
SurveyPreparer resolveHaloSurvey(MarkovState &state, Function f) {
return SurveyPreparer(
[f, &state](
size_t cat_idx, ArrayType::ArrayType &grid, size_t *const &N,
double *const &corner, double *const &L,
double *const &delta) -> size_t {
//return 0;
return f(getHaloCatalog(state, cat_idx), grid, N, corner, L, delta);
});
}
static void initializeHaloSimulationCatalog(
MarkovState &state, ptree &main_params, int cat_idx) {
using PrepareDetail::ArrayDimension;
size_t N[3], localNdata[6], Ndata[3];
state.getScalarArray<long, 3>("N", N);
state.getScalarArray<long, 3>("Ndata", Ndata);
state.getScalarArray<long, 6>("localNdata", localNdata);
Console &cons = Console::instance();
ptree &params = main_params.get_child(get_catalog_group_name(cat_idx));
// Add a catalog in the state structure
state.newElement(
format("halo_catalog_%d") % cat_idx,
new GalaxyElement(new GalaxySurveyType()));
// Add its linear bias in the MCMC structure
SDouble *nmean = new SDouble();
ArrayType1d *bias = new ArrayType1d(boost::extents[0]);
state.newElement(format("galaxy_bias_%d") % cat_idx, bias, true);
state.newElement(format("galaxy_nmean_%d") % cat_idx, nmean, true);
bias->setAutoResize(true);
auto data_ext = boost::extents[range(localNdata[0], localNdata[1])][range(
localNdata[2], localNdata[3])][range(localNdata[4], localNdata[5])];
auto data_dim = ArrayDimension(Ndata[0], Ndata[1], Ndata[2]);
SelArrayType *sel_grid = new SelArrayType(data_ext);
ArrayType *data_grid = new ArrayType(data_ext);
data_grid->setRealDims(data_dim);
sel_grid->setRealDims(data_dim);
state.newScalar<bool>(format("galaxy_bias_ref_%d") % cat_idx, false);
state.newElement(format("galaxy_sel_window_%d") % cat_idx, sel_grid);
state.newElement(format("galaxy_data_%d") % cat_idx, data_grid);
string halocut =
to_lower_copy(params.get<string>("halo_selection", "none"));
auto info_sel = new InfoSampleSelection();
info_sel->value.projection =
state.getScalar<ProjectionDataModel>("projection_model");
state.newElement(format("galaxy_selection_info_%d") % cat_idx, info_sel);
if (halocut == "none") {
cons.print<LOG_DEBUG>("Apply no cut on halo catalog");
} else if (halocut == "mass") {
cons.print<LOG_DEBUG>("Apply mass cuts on halo catalog");
} else if (halocut == "radius") {
cons.print<LOG_DEBUG>("Apply radius cuts on halo catalog");
} else if (halocut == "spin") {
cons.print<LOG_DEBUG>("Apply spin cuts on halo catalog");
} else if (halocut == "mixed") {
cons.print<LOG_DEBUG>("Apply mixed cuts on halo catalog");
}
}
static void buildNoneSelectionForSimulation(
GalaxySurveyType &sim, MarkovState &state, ptree &params, int cat_idx,
CosmologicalParameters &cosmo_params, SurveyPreparer &preparer) {
namespace ph = std::placeholders;
GalaxySampleSelection &infosel =
state
.get<InfoSampleSelection>(
format("galaxy_selection_info_%d") % cat_idx)
->value;
infosel.selector = makeSelector(
cutterFunction(NoneCutter<GalaxySurveyType>(infosel, &sim)));
switch (infosel.projection) {
case NGP_PROJECTION:
preparer = resolveHaloSurvey(
state,
std::bind(
galaxySurveyToGridGeneric<
ModifiedNGP<double, NGPGrid::NGP, true>, CIC_Tools::Periodic,
GalaxySurveyType, ArrayType::ArrayType, double *, size_t *,
NoneCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
NoneCutter<GalaxySurveyType>(infosel, &sim),
std::function<void()>()));
break;
case LUMINOSITY_CIC_PROJECTION:
preparer = resolveHaloSurvey(
state, std::bind(
galaxySurveyToGridGeneric<
ClassicCloudInCell<double, true>, CIC_Tools::Periodic,
GalaxySurveyType, ArrayType::ArrayType, double *,
size_t *, NoneCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
NoneCutter<GalaxySurveyType>(infosel, &sim),
std::function<void()>()));
break;
default:
error_helper<ErrorParams>("Unsupported data projection");
break;
}
}
static void buildMassSelectionForSimulation(
GalaxySurveyType &sim, MarkovState &state, ptree &params, int cat_idx,
CosmologicalParameters &cosmo_params, SurveyPreparer &preparer) {
namespace ph = std::placeholders;
LIBLSS_AUTO_DEBUG_CONTEXT(ctx);
GalaxySampleSelection &infosel =
state
.get<InfoSampleSelection>(
format("galaxy_selection_info_%d") % cat_idx)
->value;
infosel.low_mass_cut = params.get<double>("halo_low_mass_cut");
infosel.high_mass_cut = params.get<double>("halo_high_mass_cut");
infosel.selector = makeSelector(
cutterFunction(MassCutter<GalaxySurveyType>(infosel, &sim)));
switch (infosel.projection) {
case NGP_PROJECTION:
preparer = resolveHaloSurvey(
state,
std::bind(
galaxySurveyToGridGeneric<
ModifiedNGP<double, NGPGrid::NGP, true>, CIC_Tools::Periodic,
GalaxySurveyType, ArrayType::ArrayType, double *, size_t *,
MassCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
MassCutter<GalaxySurveyType>(infosel, &sim),
std::function<void()>()));
break;
case LUMINOSITY_CIC_PROJECTION:
ctx.print("Using cic mass projection");
preparer = resolveHaloSurvey(
state, std::bind(
galaxySurveyToGridGeneric<
ClassicCloudInCell<double, true>, CIC_Tools::Periodic,
GalaxySurveyType, ArrayType::ArrayType, double *,
size_t *, MassCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
MassCutter<GalaxySurveyType>(infosel, &sim),
std::function<void()>()));
break;
default:
error_helper<ErrorParams>("Unsupported data projection");
break;
}
}
static void buildRadiusSelectionForSimulation(
GalaxySurveyType &sim, MarkovState &state, ptree &params, int cat_idx,
CosmologicalParameters &cosmo_params, SurveyPreparer &preparer) {
GalaxySampleSelection &infosel =
state
.get<InfoSampleSelection>(
format("galaxy_selection_info_%d") % cat_idx)
->value;
infosel.small_radius_cut = params.get<double>("small_radius_cut");
infosel.large_radius_cut = params.get<double>("large_radius_cut");
infosel.selector = makeSelector(
cutterFunction(RadiusCutter<GalaxySurveyType>(infosel, &sim)));
namespace ph = std::placeholders;
switch (infosel.projection) {
case NGP_PROJECTION:
preparer = resolveHaloSurvey(
state,
std::bind(
galaxySurveyToGridGeneric<
ModifiedNGP<double, NGPGrid::NGP, true>, CIC_Tools::Periodic,
GalaxySurveyType, ArrayType::ArrayType, double *, size_t *,
RadiusCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
RadiusCutter<GalaxySurveyType>(infosel, &sim),
std::function<void()>()));
break;
case LUMINOSITY_CIC_PROJECTION:
preparer = resolveHaloSurvey(
state, std::bind(
galaxySurveyToGridGeneric<
ClassicCloudInCell<double, true>, CIC_Tools::Periodic,
GalaxySurveyType, ArrayType::ArrayType, double *,
size_t *, RadiusCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
RadiusCutter<GalaxySurveyType>(infosel, &sim),
std::function<void()>()));
break;
default:
error_helper<ErrorParams>("Unsupported data projection");
break;
}
}
static void buildSpinSelectionForSimulation(
GalaxySurveyType &sim, MarkovState &state, ptree &params, int cat_idx,
CosmologicalParameters &cosmo_params, SurveyPreparer &preparer) {
GalaxySampleSelection &infosel =
state
.get<InfoSampleSelection>(
format("galaxy_selection_info_%d") % cat_idx)
->value;
infosel.low_spin_cut = params.get<double>("halo_low_spin_cut");
infosel.high_spin_cut = params.get<double>("halo_high_spin_cut");
infosel.selector = makeSelector(
cutterFunction(SpinCutter<GalaxySurveyType>(infosel, &sim)));
namespace ph = std::placeholders;
switch (infosel.projection) {
case NGP_PROJECTION:
preparer = resolveHaloSurvey(
state,
std::bind(
galaxySurveyToGridGeneric<
ModifiedNGP<double, NGPGrid::NGP, true>, CIC_Tools::Periodic,
GalaxySurveyType, ArrayType::ArrayType, double *, size_t *,
SpinCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
SpinCutter<GalaxySurveyType>(infosel, &sim),
std::function<void()>()));
break;
case LUMINOSITY_CIC_PROJECTION:
preparer = resolveHaloSurvey(
state, std::bind(
galaxySurveyToGridGeneric<
ClassicCloudInCell<double, true>, CIC_Tools::Periodic,
GalaxySurveyType, ArrayType::ArrayType, double *,
size_t *, SpinCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6,
SpinCutter<GalaxySurveyType>(infosel, &sim),
std::function<void()>()));
break;
default:
error_helper<ErrorParams>("Unsupported data projection");
break;
}
}
static void buildMixedSelectionForSimulation(
GalaxySurveyType &sim, MarkovState &state, ptree &params, int cat_idx,
CosmologicalParameters &cosmo_params, SurveyPreparer &preparer,
boost::tokenizer<> &tokenList) {
namespace ph = std::placeholders;
GalaxySampleSelection &infosel =
state
.get<InfoSampleSelection>(
format("galaxy_selection_info_%d") % cat_idx)
->value;
MixedCutter<GalaxySurveyType> mixer;
for (auto &tok : tokenList) {
if (tok == "mass") {
mixer.addCutter(MassCutter<GalaxySurveyType>(infosel, &sim));
infosel.low_mass_cut = params.get<double>("halo_low_mass_cut");
infosel.high_mass_cut = params.get<double>("halo_high_mass_cut");
} else if (tok == "radius") {
mixer.addCutter(RadiusCutter<GalaxySurveyType>(infosel, &sim));
infosel.small_radius_cut = params.get<double>("halo_small_radius_cut");
infosel.large_radius_cut = params.get<double>("halo_large_radius_cut");
} else if (tok == "spin") {
mixer.addCutter(SpinCutter<GalaxySurveyType>(infosel, &sim));
infosel.low_spin_cut = params.get<double>("halo_low_spin_cut");
infosel.high_spin_cut = params.get<double>("halo_high_spin_cut");
} else {
error_helper<ErrorParams>(
format("Request to cut based on %s, which is not a recognized "
"option") %
tok);
}
}
infosel.selector = makeSelector(cutterFunction(mixer));
switch (infosel.projection) {
case NGP_PROJECTION:
preparer = resolveHaloSurvey(
state,
std::bind(
galaxySurveyToGridGeneric<
ModifiedNGP<double, NGPGrid::NGP, true>, CIC_Tools::Periodic,
GalaxySurveyType, ArrayType::ArrayType, double *, size_t *,
MixedCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6, mixer,
std::function<void()>()));
break;
case LUMINOSITY_CIC_PROJECTION:
preparer = resolveHaloSurvey(
state, std::bind(
galaxySurveyToGridGeneric<
ClassicCloudInCell<double, true>, CIC_Tools::Periodic,
GalaxySurveyType, ArrayType::ArrayType, double *,
size_t *, MixedCutter<GalaxySurveyType>>,
ph::_1, ph::_2, ph::_3, ph::_4, ph::_5, ph::_6, mixer,
std::function<void()>()));
break;
default:
error_helper<ErrorParams>("Unsupported data projection");
break;
}
}
static void loadHaloSimulationCatalog(
MarkovState &state, ptree &main_params, int cat_idx,
CosmologicalParameters &cosmo_params) {
ConsoleContext<LOG_INFO_SINGLE> ctx(
str(format("loadHaloSimulationCatalog(%d)") % cat_idx));
auto &sim = getHaloCatalog(state, cat_idx);
ptree &params = main_params.get_child(get_catalog_group_name(cat_idx));
std::string data_format = params.get<std::string>("dataformat", "TXT");
if (data_format == "TXT") {
loadHaloSimulationFromText(params.get<string>("datafile"), sim);
} else if (data_format == "HDF5") {
loadHaloSimulationFromHDF5(
params.get<string>("datafile"), params.get<string>("datakey"), sim);
} else if (data_format == "NONE") {
Console::instance().print<LOG_INFO_SINGLE>("No data to be loaded");
} else {
error_helper<ErrorParams>(
boost::format("Unknown data format '%s'") % data_format);
}
sim.resetWeight();
state.getScalar<bool>(format("galaxy_bias_ref_%d") % cat_idx) =
params.get<bool>("refbias");
ArrayType1d::ArrayType &hbias =
*(state.get<ArrayType1d>(format("galaxy_bias_%d") % cat_idx)->array);
if (boost::optional<std::string> bvalue =
params.get_optional<std::string>("bias")) {
auto bias_double = string_as_vector<double>(*bvalue, ", ");
hbias.resize(boost::extents[bias_double.size()]);
std::copy(bias_double.begin(), bias_double.end(), hbias.begin());
ctx.print("Set the bias to [" + to_string(bias_double) + "]");
} else {
ctx.print("No initial bias value set, use bias=1");
hbias.resize(boost::extents[1]);
hbias[0] = 1;
}
double &nmean =
state.get<SDouble>(format("galaxy_nmean_%d") % cat_idx)->value;
if (boost::optional<double> nvalue = params.get_optional<double>("nmean")) {
nmean = *nvalue;
} else {
ctx.print("No initial mean density value set, use nmean=1");
nmean = 1;
}
}
static void setupSimulationCatalog(
MarkovState &state, ptree &main_params, int cat_idx,
CosmologicalParameters &cosmo_params, SurveyPreparer &preparer) {
ptree &params = main_params.get_child(get_catalog_group_name(cat_idx));
string halocut = to_lower_copy(params.get<string>("halo_selection"));
auto &sim = getHaloCatalog(state, cat_idx);
GalaxySelectionType &gsel_type =
state
.newScalar<GalaxySelectionType>(
format("galaxy_selection_type_%d") % cat_idx,
GALAXY_SELECTION_FILE)
->value;
if (halocut == "none") {
gsel_type = HALO_SELECTION_NONE;
buildNoneSelectionForSimulation(
sim, state, params, cat_idx, cosmo_params, preparer);
} else if (halocut == "mass") {
gsel_type = HALO_SELECTION_MASS;
buildMassSelectionForSimulation(
sim, state, params, cat_idx, cosmo_params, preparer);
} else if (halocut == "radius") {
gsel_type = HALO_SELECTION_RADIUS;
buildRadiusSelectionForSimulation(
sim, state, params, cat_idx, cosmo_params, preparer);
} else if (halocut == "spin") {
gsel_type = HALO_SELECTION_SPIN;
buildSpinSelectionForSimulation(
sim, state, params, cat_idx, cosmo_params, preparer);
} else if (halocut == "mixed") {
gsel_type = HALO_SELECTION_MIXED;
string cutList = to_lower_copy(params.get<string>("list_of_cuts"));
boost::tokenizer<> tokenList(cutList);
buildMixedSelectionForSimulation(
sim, state, params, cat_idx, cosmo_params, preparer, tokenList);
} else {
error_helper<ErrorParams>(
format("halocut has value %s, which is not recognized") % halocut);
}
}
void prepareHaloSimulationData(
MPI_Communication *comm, MarkovState &state, int cat_idx,
CosmologicalParameters &cosmo_params, SurveyPreparer const &preparer,
ptree &main_params) {
using CosmoTool::InvalidRangeException;
size_t Ndata[3], localNdata[6];
double L[3], delta[3], corner[3];
state.getScalarArray<long, 3>("Ndata", Ndata);
state.getScalarArray<long, 6>("localNdata", localNdata);
state.getScalarArray<double, 3>("L", L);
state.getScalarArray<double, 3>("corner", corner);
ConsoleContext<LOG_INFO_SINGLE> ctx("data preparation");
Cosmology cosmo(cosmo_params);
ptree &sys_params = main_params.get_child("system");
ptree &g_params = main_params.get_child(get_catalog_group_name(cat_idx));
ctx.print(
format("Project data to density field grid (catalog %d)") % cat_idx);
GalaxySurveyType &sim =
state.get<GalaxyElement>(str(format("halo_catalog_%d") % cat_idx))
->get();
ArrayType *data_grid =
state.get<ArrayType>(format("galaxy_data_%d") % cat_idx);
delta[0] = L[0] / Ndata[0];
delta[1] = L[1] / Ndata[1];
delta[2] = L[2] / Ndata[2];
fwrap(*(data_grid->array)) = 0;
size_t numHalos =
preparer(cat_idx, *(data_grid->array), Ndata, corner, L, delta);
comm->all_reduce_t(MPI_IN_PLACE, &numHalos, 1, MPI_SUM);
if (numHalos == 0) {
error_helper<ErrorBadState>(
format("No halo at all in catalog %d") % cat_idx);
}
GalaxySelectionType &gsel_type = state.getScalar<GalaxySelectionType>(
format("galaxy_selection_type_%d") % cat_idx);
SelArrayType *sel_grid =
state.get<SelArrayType>(format("galaxy_sel_window_%d") % cat_idx);
LibLSS::array::fill(
*sel_grid->array, 1); //fixes ambiguity when using VIRBIUS
PrepareDetail::cleanup_data(*data_grid->array, *sel_grid->array);
}
} // namespace LibLSS_prepare
#endif

View file

@ -0,0 +1,178 @@
/*+
ARES/HADES/BORG Package -- ./src/common/preparation_tools.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef __LIBLSS_ARES_COMMON_PREPARATION_TOOLS_HPP
#define __LIBLSS_ARES_COMMON_PREPARATION_TOOLS_HPP
#include <functional>
#include "libLSS/tools/console.hpp"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include "libLSS/tools/ptree_translators.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/optional/optional.hpp>
#include "libLSS/data/spectro_gals.hpp"
#include "libLSS/data/galaxies.hpp"
#include "libLSS/data/projection.hpp"
#include "libLSS/data/linear_selection.hpp"
#include "libLSS/data/window3d.hpp"
#include "libLSS/data/window3d_post.hpp"
#include "libLSS/mcmc/global_state.hpp"
#include "libLSS/data/schechter_completeness.hpp"
#include <CosmoTool/interpolate.hpp>
#include "libLSS/tools/fused_array.hpp"
#include "libLSS/tools/fused_assign.hpp"
#include "libLSS/tools/fusewrapper.hpp"
#include "preparation_types.hpp"
namespace LibLSS_prepare {
namespace PrepareDetail {
static boost::array<int, 3> ArrayDimension(int a, int b, int c) {
boost::array<int, 3> A;
A[0] = a;
A[1] = b;
A[2] = c;
return A;
}
static boost::array<int, 4> ArrayDimension(int a, int b, int c, int d) {
boost::array<int, 4> A;
A[0] = a;
A[1] = b;
A[2] = c;
A[3] = d;
return A;
}
template <typename ptree, typename SelFunction3d, typename SelGrid>
void compute_window(
ptree &sys_params, MPI_Communication *comm, SelFunction3d &fg,
LibLSS::MarkovState &state, SelGrid &sel_grid, bool filter_mask) {
ConsoleContext<LOG_DEBUG> ctx("compute_window");
size_t N[3];
double L[3], delta[3], corner[3];
N[0] = state.getScalar<long>("Ndata0");
N[1] = state.getScalar<long>("Ndata1");
N[2] = state.getScalar<long>("Ndata2");
L[0] = state.getScalar<double>("L0");
L[1] = state.getScalar<double>("L1");
L[2] = state.getScalar<double>("L2");
corner[0] = state.getScalar<double>("corner0");
corner[1] = state.getScalar<double>("corner1");
corner[2] = state.getScalar<double>("corner2");
delta[0] = L[0] / N[0];
delta[1] = L[1] / N[1];
delta[2] = L[2] / N[2];
double precision = sys_params.get("mask_precision", 0.01);
RGenType &rng = dynamic_cast<RGenType &>(
state.get<RandomGen>("random_generator")->get());
ctx.print(format("Use precision=%lg") % precision);
compute_window_value_elem(
comm, rng, fg, sel_grid, L, delta, corner, filter_mask, precision);
}
template <typename DataGrid, typename SelGrid>
void cleanup_data(DataGrid &data, SelGrid &sel_grid) {
LibLSS::copy_array(
data,
b_fused<double>(data, sel_grid, [](double d, double s) -> double {
if (s <= 0)
return 0;
else
return d;
}));
}
} // namespace PrepareDetail
static void
buildGrowthFactor(MarkovState &state, CosmologicalParameters &cosmo_param) {
Cosmology cosmo(cosmo_param);
ArrayType::ArrayType &growth =
*state.get<ArrayType>("growth_factor")->array;
// No growth factor here
std::fill(growth.data(), growth.data() + growth.num_elements(), 1);
}
} // namespace LibLSS_prepare
namespace LibLSS {
inline std::string get_catalog_group_name(int i) {
return boost::str(boost::format("catalog_%d") % i);
}
enum RestoreOption { RESTORE, DO_NOT_RESTORE };
template <typename T, typename PTree>
T adapt_optional(
MarkovState &state, boost::optional<PTree> &params,
const std::string &name, T const &defval, RestoreOption restore = RESTORE,
std::string const &target_name = "") {
T r = defval;
std::string target = (target_name == "") ? name : target_name;
if (params) {
r = params->template get<T>(name, defval);
}
auto state_scalar = state.newScalar<T>(target, r);
state_scalar->setDoNotRestore(restore == DO_NOT_RESTORE);
return r;
}
template <typename T, typename PTree>
T adapt(
MarkovState &state, PTree &params, const std::string &name,
RestoreOption restore = RESTORE, std::string const &target_name = "") {
std::string target = (target_name == "") ? name : target_name;
T r = params.template get<T>(name);
state.newScalar<T>(target, r)->setDoNotRestore(restore == DO_NOT_RESTORE);
return r;
}
template <typename T, typename PTree>
T adapt(
MarkovState &state, PTree &params, const std::string &name,
const T &defval, RestoreOption restore = RESTORE,
std::string const &target_name = "") {
std::string target = (target_name == "") ? name : target_name;
T r = params.template get<T>(name, defval);
state.newScalar<T>(target, r)->setDoNotRestore(restore == DO_NOT_RESTORE);
return r;
}
namespace details {
template <typename T, typename PTree>
bool safe_get(PTree &t, const std::string &n, T &value) {
boost::optional<T> v = t.template get_optional<T>(n);
if (!v)
return false;
value = *v;
return true;
}
template <typename T, typename PTree>
T property_accessor(PTree &t, const std::string &n) {
return t.template get<T>(n);
}
} // namespace details
} // namespace LibLSS
#endif

View file

@ -0,0 +1,55 @@
/*+
ARES/HADES/BORG Package -- ./src/common/preparation_types.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef _LIBLSS_PREPARATION_TYPES_HPP
#define _LIBLSS_PREPARATION_TYPES_HPP
#include <functional>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/algorithm/string.hpp>
#include "libLSS/data/spectro_gals.hpp"
#include "libLSS/data/galaxies.hpp"
#include "libLSS/data/projection.hpp"
#include "libLSS/data/linear_selection.hpp"
#include "libLSS/data/schechter_completeness.hpp"
#include "piecewise_selection.hpp"
#include "ketable.hpp"
#include "libLSS/samplers/rgen/gsl_random_number.hpp"
namespace LibLSS_prepare {
using namespace LibLSS;
typedef boost::multi_array_types::extent_range range;
#ifndef SAMPLER_GALAXY_TYPE
# define SAMPLER_GALAXY_TYPE BaseGalaxyDescriptor
#endif
typedef GalaxySurvey<LinearInterpolatedSelection, SAMPLER_GALAXY_TYPE>
GalaxySurveyType;
typedef ObjectStateElement<GalaxySurveyType, true> GalaxyElement;
typedef RandomNumberMPI<GSL_RandomNumber> RGenType;
typedef ScalarStateElement<GalaxySampleSelection> InfoSampleSelection;
typedef ScalarStateElement<SchechterParameters> InfoSchechter;
typedef std::function<size_t(
size_t, ArrayType::ArrayType &, size_t *const &, double *const &,
double *const &, double *const &)>
SurveyPreparer;
typedef ObjectStateElement<KETableCorrection, true> KECorrectionStateElement;
using boost::format;
using boost::to_lower_copy;
using std::string;
typedef boost::property_tree::iptree ptree;
} // namespace LibLSS_prepare
#endif

56
src/common/projection.hpp Normal file
View file

@ -0,0 +1,56 @@
/*+
ARES/HADES/BORG Package -- ./src/common/projection.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef _ARES_PROJECTION_SETUP_HPP
#define _ARES_PROJECTION_SETUP_HPP
#include <CosmoTool/algo.hpp>
#include <cmath>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/algorithm/string.hpp>
#include "libLSS/tools/console.hpp"
#include "libLSS/samplers/core/main_loop.hpp"
#include "libLSS/samplers/core/types_samplers.hpp"
#include "libLSS/data/projection.hpp"
namespace LibLSS {
template <typename PTree>
inline void
setupProjection(MPI_Communication &comm, MainLoop &loop, PTree &params) {
using boost::to_lower_copy;
PTree system_params = params.get_child("system");
std::string projtype =
to_lower_copy(system_params.template get<std::string>(
"projection_model", "number_ngp"));
ProjectionDataModel projmodel = NGP_PROJECTION;
std::string projmodel_name;
Console &cons = Console::instance();
MarkovState &state = loop.get_state();
if (projtype == "number_ngp") {
projmodel = NGP_PROJECTION;
projmodel_name = "Nearest Grid point number count";
} else if (projtype == "luminosity_cic") {
projmodel = LUMINOSITY_CIC_PROJECTION;
projmodel_name = "Luminosity weighted CIC field";
} else {
error_helper<ErrorParams>("Unknown specified projection model");
}
cons.print<LOG_INFO_SINGLE>(
boost::format("Data and model will use the folllowing method: '%s'") %
projmodel_name);
state.newScalar<ProjectionDataModel>("projection_model", projmodel);
}
} // namespace LibLSS
#endif

310
src/common/sampler_base.cpp Normal file
View file

@ -0,0 +1,310 @@
/*+
ARES/HADES/BORG Package -- ./src/common/sampler_base.cpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#include "libLSS/cconfig.h"
#include "libLSS/mpi/generic_mpi.hpp"
#include <boost/optional.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/function.hpp>
#include <boost/random/random_device.hpp>
#include <CosmoTool/algo.hpp>
#include <CosmoTool/fourier/fft/fftw_calls.hpp>
#include "libLSS/physics/cosmo.hpp"
#include "libLSS/tools/static_init.hpp"
#include "libLSS/tools/console.hpp"
#include "libLSS/tools/hdf5_error.hpp"
#include "libLSS/samplers/core/main_loop.hpp"
#include "libLSS/mcmc/state_element.hpp"
#include "libLSS/samplers/core/random_number.hpp"
#include "libLSS/samplers/rgen/gsl_random_number.hpp"
#include "preparation_types.hpp"
#include "preparation_tools.hpp"
#include "configuration.hpp"
#ifdef SAMPLER_BUNDLE
# include SAMPLER_BUNDLE
#endif
#ifndef ARES_EXTRA_CATCH_CLAUSE
# define ARES_EXTRA_CATCH_CLAUSE
#endif
#include "preparation.hpp"
#include "preparation_simulation.hpp"
#include "mock_gen.hpp"
#include "projection.hpp"
#include "libLSS/ares_version.hpp"
#include "libLSS/tools/string_tools.hpp"
#include "libLSS/tools/cpu/feature_check.hpp"
#include SAMPLER_DATA_INIT
#ifdef SAMPLER_BUNDLE
# include SAMPLER_BUNDLE_INIT
#endif
using namespace LibLSS;
using namespace LibLSS_prepare;
using boost::format;
using boost::optional;
using boost::str;
using CosmoTool::square;
using std::string;
namespace {
#if defined(ARES_MPI_FFTW)
RegisterStaticInit reg0(fftw_mpi_init, fftw_mpi_cleanup, 9, "MPI/FFTW");
#endif
// WISDOM must come at the end. Otherwise it is reset
RegisterStaticInit reg1(
CosmoTool::init_fftw_wisdom, CosmoTool::save_fftw_wisdom, 12,
"FFTW/WISDOM");
#if !defined(ARES_MPI_FFTW) && \
defined( \
_OPENMP) // Do not use MPI and Threaded FFTW at the same time for the moment.
RegisterStaticInit
reg2(fftw_init_threads, fftw_cleanup_threads, 11, "FFTW/THREADS");
#endif
} // namespace
template <typename RandGen>
void reseed(RandGen &rgen) {
rgen.seed(rgen.get());
}
int main(int argc, char **argv) {
using std::string;
MPI_Communication *mpi_world = setupMPI(argc, argv);
Console &cons = Console::instance();
StaticInit::execute();
#if !defined(ARES_MPI_FFTW) && defined(_OPENMP)
fftw_plan_with_nthreads(smp_get_max_threads());
#endif
cons.print<LOG_INFO>(
format("Starting " SAMPLER_NAME ". rank=%d, size=%d") %
mpi_world->rank() % mpi_world->size());
cons.print<LOG_INFO_SINGLE>("ARES3 base version " + ARES_GIT_VERSION);
cons.print<LOG_INFO_SINGLE>(LibLSS::tokenize(ARES_GIT_REPORT, "\n"));
{
std::string cpu_features;
bool result = LibLSS::check_compatibility(cpu_features);
cons.format<LOG_INFO>("CPU features: %s", cpu_features);
if (!result) {
cons.print<LOG_ERROR>("Binary is incompatible with your CPU. Stop here.");
mpi_world->abort();
return 1;
}
}
try {
MainLoop loop;
if (argc != 3) {
cons.print<LOG_ERROR>(
SAMPLER_NAME
" requires exactly two parameters: INIT or RESUME as first"
" parameter and the configuration file as second parameter.");
return 1;
}
LibLSS_prepare::ptree params;
cons.print<LOG_DEBUG>("Parsing ini file");
try {
read_ini(argv[2], params);
} catch (const boost::property_tree::ini_parser::ini_parser_error &e) {
error_helper<ErrorParams>(
string("I could not read INI file. Error was: ") + e.what());
}
cons.print<LOG_DEBUG>("Retrieving system tree");
ptree system_params = params.get_child("system");
cons.print<LOG_DEBUG>("Retrieving run tree");
ptree run_params = params.get_child("run");
if (optional<string> console_output_file =
system_params.get_optional<string>("console_output")) {
cons.outputToFile(
str(format("%s_rank_%d") % *console_output_file % mpi_world->rank()));
}
string action = argv[1];
SamplerBundle bundle(mpi_world);
MarkovState &state = loop.get_state();
state.newScalar("ARES_version", ARES_GIT_VERSION);
// Load common configuration file options
loadConfigurationFile(*mpi_world, loop, params);
setupProjection(*mpi_world, loop, params);
CosmologicalParameters &cosmo =
state.getScalar<CosmologicalParameters>("cosmology");
RGenType randgen(mpi_world, -1);
randgen.seed(system_params.get<unsigned long int>("seed", 24032015));
bool furiousSeed;
int Ncat, savePeriodicity;
long N_MC_LOOP;
long N0, N1, N2, localN0, startN0;
SLong *mcmc_step;
boost::random::random_device rng_dev;
// furious seeding disables deterministic seeding and use a true source
// of entropy to reseed the Pseudo-RNG at each MCMC loop.
// This could deprive quickly the amount of available entropy for small runs
// and could actually cause a stale and performance reduction in that
// case.
// furiousSeeding is thus not enabled by default.
furiousSeed = system_params.get<bool>("furious_seeding", false);
Ncat = adapt<long>(state, run_params, "NCAT", true);
// Initialize the input data structures. They need to be in place
// in state to have the RESUME action functioning correctly.
sampler_init_data(mpi_world, state, params);
savePeriodicity = system_params.get<int>("savePeriodicity", 1);
N_MC_LOOP = params.get<long>("mcmc.number_to_generate");
cons.print<LOG_VERBOSE>(
format("We will compute %d MCMC samples") % N_MC_LOOP);
N0 = state.getScalar<long>("N0");
N1 = state.getScalar<long>("N1");
N2 = state.getScalar<long>("N2");
localN0 = state.getScalar<long>("localN0");
startN0 = state.getScalar<long>("startN0");
// MCMC step id
state.newElement("MCMC_STEP", mcmc_step = new SLong());
// Create growth factor field
ArrayType *growth;
state.newElement(
"growth_factor",
growth = new ArrayType(
boost::extents[range(startN0, startN0 + localN0)][N1][N2]));
growth->setRealDims(PrepareDetail::ArrayDimension(N0, N1, N2));
// Insert random number generator into the state variable
state.newElement(
"random_generator", new RandomStateElement<RandomNumber>(&randgen));
// Initialize the program bundle.
sampler_bundle_init(
mpi_world, params, bundle, loop,
(action == "SPECIAL_RESUME") or (action == "RESUME") or
(action == "RESUME_RESEED"));
sampler_setup_data(mpi_world, state, params, loop);
// Here we have the different action. We can either reload a previous
// run or start from scratch.
if (action == "SPECIAL_RESUME") {
loop.restore("restart.h5", true);
reseed(state.get<RandomStateElement<RandomNumber>>("random_generator")
->get());
loop.setStepID(mcmc_step->value);
} else if (action == "RESUME" || action == "RESUME_RESEED") {
loop.restore("restart.h5", false);
if (action == "RESUME_RESEED") {
// Force reseeding after restart
state.get<RandomStateElement<RandomNumber>>("random_generator")
->get()
.seed(system_params.get<unsigned long int>("seed", 24032015));
}
loop.setStepID(mcmc_step->value);
} else if (action == "INIT") {
// Load survey data.
sampler_load_data(mpi_world, state, params, loop);
sampler_prepare_data(mpi_world, state, params, loop);
mcmc_step->value = 0;
} else {
error_helper<ErrorParams>("Invalid parameter " + action);
}
buildGrowthFactor(state, cosmo);
// Initiate samplers
loop.initialize();
// Save some wisdom here just in case.
CosmoTool::save_fftw_wisdom();
loop.save();
if (action == "INIT" && system_params.get<bool>("test_mode", false)) {
cons.print<LOG_INFO_SINGLE>("Prepare mock data");
if (furiousSeed) {
randgen.seed(rng_dev());
}
prepareMockData(params, mpi_world, state, cosmo, bundle);
}
// Powerspectrum is not sampled that way anymore.
// if (system_params.get<bool>("seed_cpower", false)) {
// createCosmologicalPowerSpectrum(state, cosmo);
// } else {
// Console::instance().print<LOG_INFO_SINGLE>("Reseting powerspectrum");
// createCosmologicalPowerSpectrum(state, cosmo, 10);
// }
if (action == "INIT")
sampler_setup_ic(bundle, loop, params);
loop.save();
int last_save = 0;
try {
for (int i = 0; i < N_MC_LOOP; i++) {
if (furiousSeed) {
randgen.seed(rng_dev());
}
loop.run();
loop.snap();
if ((i % savePeriodicity) == 0) {
last_save = i;
loop.save();
}
mcmc_step->value++;
timings::trigger_dump();
}
} catch (const ErrorBase &e) {
loop.save_crash();
throw;
}
if (last_save < N_MC_LOOP) {
cons.print<LOG_STD>("Reached end of the loop. Writing restart file.");
loop.save();
}
} catch (const ErrorBase &e) {
cons.print<LOG_ERROR>(
"An error was raised (msg=" + std::string(e.what()) + "). Exiting.");
MPI_Communication::instance()->abort();
} catch (const boost::property_tree::ptree_bad_path &e) {
cons.print<LOG_ERROR>(
"Missing option in configuration " + e.path<ptree::path_type>().dump());
} catch (const boost::property_tree::ptree_bad_data &e) {
cons.print<LOG_ERROR>(
"Error converting this parameter " + e.data<string>());
}
ARES_EXTRA_CATCH_CLAUSE
sampler_bundle_cleanup();
StaticInit::finalize();
doneMPI();
return 0;
}

View file

@ -0,0 +1,169 @@
/*+
ARES/HADES/BORG Package -- ./src/common/survey_cutters.hpp
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
Additional contributions from:
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
+*/
#ifndef __SURVEY_CUTTERS_HPP
#define __SURVEY_CUTTERS_HPP
#include <cmath>
namespace LibLSS {
template <typename GalaxySurvey>
class MagnitudeCutter {
public:
GalaxySampleSelection selection;
GalaxySurvey *g_el;
MagnitudeCutter(GalaxySampleSelection sel, GalaxySurvey *e)
: selection(sel), g_el(e) {}
virtual bool operator()(const BaseGalaxyDescriptor &g) const {
double f = g_el->getCompleteness(g.phi, g.theta);
bool flag = (f > 0.) && (g.m > selection.bright_apparent_magnitude_cut) &&
(g.m <= selection.faint_apparent_magnitude_cut) &&
(g.M_abs > selection.bright_absolute_magnitude_cut) &&
(g.M_abs <= selection.faint_absolute_magnitude_cut) &&
(g.z > 0);
return flag;
}
};
template <typename GalaxySurvey>
class RedshiftMagnitudeCutter {
public:
GalaxySampleSelection selection;
GalaxySurvey *g_el;
RedshiftMagnitudeCutter(GalaxySampleSelection sel, GalaxySurvey *e)
: selection(sel), g_el(e) {}
bool operator()(const BaseGalaxyDescriptor &g) const {
double f = g_el->getCompleteness(g.phi, g.theta);
return (f > 0.) && (g.z >= selection.zmin) && (g.z < selection.zmax) &&
(g.m > selection.bright_apparent_magnitude_cut) &&
(g.m <= selection.faint_apparent_magnitude_cut) &&
(g.M_abs > selection.bright_absolute_magnitude_cut) &&
(g.M_abs <= selection.faint_absolute_magnitude_cut);
}
};
template <typename GalaxySurvey>
class DistanceCutter {
public:
GalaxySurvey *g_el;
GalaxySampleSelection selection;
DistanceCutter(GalaxySampleSelection sel, GalaxySurvey *e)
: selection(sel), g_el(e) {}
bool operator()(const BaseGalaxyDescriptor &g) const {
return (g.r >= selection.dmin) && (g.r <= selection.dmax);
}
};
template <typename DMSimulation>
class MixedCutter {
private:
typedef std::function<bool(const BaseGalaxyDescriptor &)> Functor;
std::list<Functor> cutter_list;
public:
MixedCutter() {}
void addCutter(Functor f) { cutter_list.push_back(f); }
bool operator()(const BaseGalaxyDescriptor &g) const {
for (auto &c : cutter_list) {
if (!c(g))
return false;
}
return true;
}
};
template <typename DMSimulation>
class NoneCutter {
public:
GalaxySampleSelection selection;
DMSimulation *h_el;
NoneCutter(GalaxySampleSelection sel, DMSimulation *e)
: selection(sel), h_el(e) {}
virtual bool operator()(const BaseGalaxyDescriptor &h) const {
return true;
}
};
template <typename DMSimulation>
class MassCutter {
public:
GalaxySampleSelection selection;
DMSimulation *h_el;
MassCutter(GalaxySampleSelection sel, DMSimulation *e)
: selection(sel), h_el(e) {}
virtual bool operator()(const BaseGalaxyDescriptor &h) const {
bool massCut = (std::log10(h.Mgal) >= selection.low_mass_cut) &&
(std::log10(h.Mgal) < selection.high_mass_cut);
return massCut;
}
};
template <typename DMSimulation>
class RadiusCutter {
public:
GalaxySampleSelection selection;
DMSimulation *h_el;
RadiusCutter(GalaxySampleSelection sel, DMSimulation *e)
: selection(sel), h_el(e) {}
virtual bool operator()(const BaseGalaxyDescriptor &h) const {
bool radiusCut = (h.radius >= selection.small_radius_cut) &&
(h.radius < selection.large_radius_cut);
return radiusCut;
}
};
template <typename DMSimulation>
class SpinCutter {
public:
GalaxySampleSelection selection;
DMSimulation *h_el;
SpinCutter(GalaxySampleSelection sel, DMSimulation *e)
: selection(sel), h_el(e) {}
virtual bool operator()(const BaseGalaxyDescriptor &h) const {
bool spinCut = (h.spin >= selection.low_spin_cut) &&
(h.spin < selection.high_spin_cut);
return spinCut;
}
};
namespace details_cutter {
template <typename Cutter>
bool _internal_cutter(const BaseGalaxyDescriptor &g, const Cutter &cutter) {
return cutter(g);
}
template <typename Cutter>
GalaxySelector cutterFunction(Cutter cutter) {
return std::bind(_internal_cutter<Cutter>, std::placeholders::_1, cutter);
}
}; // namespace details_cutter
using details_cutter::cutterFunction;
}; // namespace LibLSS
#endif