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

55
libLSS/data/angtools.hpp Normal file
View file

@ -0,0 +1,55 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/angtools.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_ANGTOOLS_HPP
#define __LIBLSS_ANGTOOLS_HPP
#include <cmath>
namespace LibLSS {
template <typename T, typename Array>
void ang2vec(T ra, T dec, Array &xyz) {
T c_ra = std::cos(ra), s_ra = std::sin(ra), c_dec = std::cos(dec),
s_dec = std::sin(dec);
xyz[0] = c_ra * c_dec;
xyz[1] = s_ra * c_dec;
xyz[2] = s_dec;
}
template <typename T, typename Array>
void vec2ang(Array xyz, T &ra, T &dec) {
T c_r = std::sqrt(xyz[0] * xyz[0] + xyz[1] * xyz[1] + xyz[2] * xyz[2]);
ra = std::atan2(xyz[1], xyz[0]);
dec = 0.;
if (c_r > 0)
dec = std::asin(xyz[2] / c_r);
}
template <typename T, typename Array>
void vec2ang(Array xyz, T &ra, T &dec, T &r) {
r = std::sqrt(xyz[0] * xyz[0] + xyz[1] * xyz[1] + xyz[2] * xyz[2]);
ra = std::atan2(xyz[1], xyz[0]);
dec = 0.;
if (r > 0)
dec = std::asin(xyz[2] / r);
}
}; // namespace LibLSS
#endif

23
libLSS/data/base.hpp Normal file
View file

@ -0,0 +1,23 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/base.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 __ARES2_BASE_HPP
#define __ARES2_BASE_HPP
namespace LibLSS
{
class Base_Data {
public:
};
};
#endif

97
libLSS/data/galaxies.hpp Normal file
View file

@ -0,0 +1,97 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/galaxies.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_GALAXIES_HPP
#define __LIBLSS_GALAXIES_HPP
#include <CosmoTool/hdf5_array.hpp>
namespace LibLSS {
struct BaseGalaxyDescriptor {
unsigned long long id;
double phi, theta;
double zo;
double m;
double M_abs;
double Mgal;
double z;
double r;
double w;
double final_w;
double radius;
double spin;
double posx, posy ,posz;
double vx, vy, vz;
};
struct PhotoGalaxyDescriptor {
BaseGalaxyDescriptor base;
double sigma_z0;
int gridid;
};
enum GalaxySelectionType {
GALAXY_SELECTION_FILE,
GALAXY_SELECTION_SCHECHTER,
GALAXY_SELECTION_PIECEWISE,
HALO_SELECTION_NONE,
HALO_SELECTION_MASS,
HALO_SELECTION_RADIUS,
HALO_SELECTION_SPIN,
HALO_SELECTION_MIXED
};
};
CTOOL_ENUM_TYPE(LibLSS::GalaxySelectionType, HDF5T_GalaxySelectionType,
(LibLSS::GALAXY_SELECTION_FILE)
(LibLSS::GALAXY_SELECTION_SCHECHTER)
(LibLSS::GALAXY_SELECTION_PIECEWISE)
(LibLSS::HALO_SELECTION_NONE)
(LibLSS::HALO_SELECTION_MASS)
(LibLSS::HALO_SELECTION_RADIUS)
(LibLSS::HALO_SELECTION_SPIN)
(LibLSS::HALO_SELECTION_MIXED)
);
/* HDF5 complex type */
CTOOL_STRUCT_TYPE(LibLSS::BaseGalaxyDescriptor, HDF5T_BaseGalaxyDescriptor,
((unsigned long long, id))
((double, phi))
((double, theta))
((double, posx))
((double, posy))
((double, posz))
((double, radius))
((double, spin))
((double, zo))
((double, m))
((double, M_abs))
((double, Mgal))
((double, z))
((double, vx))
((double, vy))
((double, vz))
((double, r))
((double, w))
((double, final_w))
);
CTOOL_STRUCT_TYPE(LibLSS::PhotoGalaxyDescriptor, HDF5T_PhotoGalaxyDescriptor,
((LibLSS::BaseGalaxyDescriptor, base))
((double, sigma_z0))
((int, gridid))
);
#endif

View file

@ -0,0 +1,132 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/integer_window3d.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_MAJORITY_VOTE_WINDOW_3D_HPP
#define __LIBLSS_MAJORITY_VOTE_WINDOW_3D_HPP
#include <cassert>
#include <functional>
#include "libLSS/mpi/generic_mpi.hpp"
#include "libLSS/tools/openmp.hpp"
#include <CosmoTool/algo.hpp>
#include <boost/array.hpp>
#include <numeric>
#include <cmath>
namespace LibLSS {
namespace internalIntegerWindow {
template <typename SelFunction3d>
unsigned int selectionValue(
std::array<double, 3> const &x, SelFunction3d const &selfunc) {
double r = std::sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
// *WARNING:* We use a sum here
return selfunc.get_sky_completeness(x[0] / r, x[1] / r, x[2] / r) +
selfunc.getRadialSelection(r, 0);
}
} // namespace internalIntegerWindow
template <
typename RandomNum, typename IntegerWindow, typename SelFunction3d,
typename Dimension, typename IDimension>
void computeMajorityVoteWindow3d(
MPI_Communication *comm, RandomNum &rng, SelFunction3d const &selFuncData,
IntegerWindow &selfunc, const Dimension &L, const Dimension &d,
const Dimension &xmin, const IDimension &N, size_t numCalls = 6000) {
LIBLSS_AUTO_CONTEXT2(LOG_INFO, ctx, "computeMajorityVoteWindow3d");
using boost::format;
using boost::str;
boost::multi_array<int, 1> count_elements(
boost::extents[LibLSS::smp_get_max_threads()]);
size_t startN0 = selfunc.index_bases()[0];
size_t localN0 = selfunc.shape()[0], N1 = N[1], N2 = N[2];
double d0 = d[0];
double d1 = d[1];
double d2 = d[2];
double xmin0 = xmin[0];
double xmin1 = xmin[1];
double xmin2 = xmin[2];
size_t N0 = N[0];
size_t calls = 10;
auto &p = Console::instance().start_progress<LOG_STD>(
"3D Integer Window", localN0 * N1 * N2, 2);
ctx.format("Use %d calls integral / calls", numCalls);
std::fill(count_elements.begin(), count_elements.end(), 0);
long job_start = startN0 * N1 * N2;
long job_end = (startN0 + localN0) * N1 * N2;
ctx.format2<LOG_DEBUG>(
"Window computation, MPI job_start=%ld job_end=%ld", job_start,
job_end);
ctx.format2<LOG_DEBUG>(
"d=[%g,%g,%g], L=[%g,%g,%g]", d[0], d[1], d[2], L[0], L[1], L[2]);
double dV = d0 * d1 * d2;
typedef boost::multi_array_types::extent_range range;
boost::multi_array<bool, 3> dummy(
boost::extents[range(startN0, startN0 + localN0)][N1][N2]);
boost::multi_array<double, 3> all_err(
boost::extents[range(startN0, startN0 + localN0)][N1][N2]);
#pragma omp parallel
{
std::map<unsigned int, unsigned int> hitCount;
#pragma omp for schedule(dynamic, 100)
for (size_t i = job_start; i < job_end; i++) {
///get 3d indices
size_t ii = (size_t)(i / N1 / N2);
size_t jj = (size_t)(i / N2 - ii * N1);
size_t kk = (size_t)(i - jj * N2 - ii * N2 * N1);
double x = double(ii) * d0 + xmin0, y = double(jj) * d1 + xmin1,
z = double(kk) * d2 + xmin2;
double err;
std::array<double, 3> xl{x - 0.5 * d0, y - 0.5 * d1, z - 0.5 * d2}; // half voxel shift is for NGP in projection
std::array<double, 3> xu{x + 0.5 * d0, y + 0.5 * d1, z + 0.5 * d2};
hitCount.clear();
for (size_t c = 0; c < numCalls; c++) {
std::array<double, 3> x;
for (unsigned int j = 0; j < 3; j++)
x[j] = xl[j] + (xu[j] - xl[j]) * rng.uniform();
hitCount[internalIntegerWindow::selectionValue(x, selFuncData)]++;
}
// Find majority vote
selfunc[ii][jj][kk] = std::max_element(
hitCount.begin(), hitCount.end(),
[](auto const &x, auto const &y) {
return x.second < y.second;
})
->first;
assert(LibLSS::smp_get_thread_id() < LibLSS::smp_get_max_threads());
count_elements[LibLSS::smp_get_thread_id()]++;
if (LibLSS::smp_get_thread_id() == 0) {
int done =
std::accumulate(count_elements.begin(), count_elements.end(), 0);
p.update(done);
}
}
}
p.destroy();
}
}; // namespace LibLSS
#endif

View file

@ -0,0 +1,213 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/linear_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_DATA_LINEAR_SELECTION_HPP
#define __LIBLSS_DATA_LINEAR_SELECTION_HPP
#include <boost/format.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/lexical_cast.hpp>
#include <H5Cpp.h>
#include <fstream>
#include <sstream>
#include <cmath>
#include <cfloat>
#include <healpix_cxx/pointing.h>
#include <healpix_cxx/healpix_map.h>
#include <healpix_cxx/healpix_map_fitsio.h>
#include <CosmoTool/hdf5_array.hpp>
#include "libLSS/tools/hdf5_type.hpp"
namespace LibLSS {
class LinearInterpolatedSelection {
protected:
boost::multi_array<double, 1> selection;
double dr, rmin, dmin, dmax;
Healpix_Map<double> sky;
public:
LinearInterpolatedSelection() : sky(1, RING, SET_NSIDE), rmin(0), dr(1) {
std::fill(
selection.data(), selection.data() + selection.num_elements(), 1);
this->dmin = 0;
this->dmax = 0;
}
~LinearInterpolatedSelection() {}
void loadSky(const std::string &fname, double threshold = 0) {
read_Healpix_map_from_fits(fname, sky);
for (long i = 0; i < sky.Npix(); i++)
if (sky[i] < threshold)
sky[i] = 0;
}
void fillSky(double v) { sky.fill(v); }
void clearSky() { sky.SetNside(1, RING); }
void setMinMaxDistances(double dmin, double dmax) {
this->dmin = dmin;
this->dmax = dmax;
}
void loadRadial(const std::string &fname) {
using namespace std;
using boost::format;
using boost::str;
ifstream f(fname.c_str());
string line;
if (!f) {
error_helper<ErrorIO>(
str(format("Failed to open '%s' to load radial") % fname));
}
{
int numPoints;
while (getline(f, line))
if (line[0] != '#')
break;
if (!f)
error_helper<ErrorIO>("Error finding the first line");
istringstream iss(line);
iss >> rmin >> dr >> numPoints;
selection.resize(boost::extents[numPoints]);
Console::instance().print<LOG_INFO>(
boost::format(
"Found selection with %d points from %g Mpc/h to %g Mpc/h") %
numPoints % rmin % (rmin + dr * numPoints));
this->dmax = rmin + dr * numPoints * 2;
}
for (long i = 0; i < selection.shape()[0]; i++) {
if (!getline(f, line))
error_helper<ErrorIO>(str(format("Error reading line %d") % (i + 2)));
if (line[0] == '#')
continue;
try {
boost::algorithm::trim(line);
selection[i] = boost::lexical_cast<double>(line);
} catch (const std::exception &e) {
error_helper<ErrorIO>(
str(format("Bad value cast on line %d") % (i + 2)));
}
}
}
void setArray(const boost::multi_array<double, 1> &a, double rmax) {
this->rmin = 0;
this->dr = rmax / a.num_elements();
selection.resize(boost::extents[a.num_elements()]);
selection = a;
}
double getRadialSelection(double r, int n) const {
double q = (r - rmin) / dr;
double q0 = std::floor(q);
int i = int(q0);
double f = q - q0;
//Console::instance().c_assert(r < rmax, "Box too large for radial selection table");
if ((i + 1) >= selection.shape()[0] || i < 0)
return 0;
if (r < dmin || r > dmax)
return 0;
return (1 - f) * selection[i] + f * selection[i + 1];
}
int getNumRadial() const { return 1; }
double get_sky_completeness(double x, double y, double z) const {
double r = std::max(std::sqrt(x * x + y * y + z * z), DBL_EPSILON);
return sky[sky.vec2pix(vec3(x / r, y / r, z / r))];
}
void saveFunction(H5_CommonFileGroup &fg) {
CosmoTool::get_hdf5_data_type<double> ht;
hsize_t Npix = sky.Npix();
{
H5::DataSpace dataspace(1, &Npix);
H5::DataSet dataset =
fg.createDataSet("completeness", ht.type(), dataspace);
dataset.write(&sky[0], ht.type());
}
{
hsize_t s = 1;
H5::DataSpace dataspace(1, &s);
H5::DataSet dataset = fg.createDataSet("dr", ht.type(), dataspace);
dataset.write(&dr, ht.type());
H5::DataSet dataset2 = fg.createDataSet("rmin", ht.type(), dataspace);
dataset2.write(&rmin, ht.type());
}
CosmoTool::hdf5_write_array(fg, "radial_selection", selection);
}
void loadFunction(H5_CommonFileGroup &fg) {
CosmoTool::get_hdf5_data_type<double> ht;
hsize_t Npix;
{
H5::DataSet dataset = fg.openDataSet("completeness");
H5::DataSpace dataspace = dataset.getSpace();
if (dataspace.getSimpleExtentNdims() != 1) {
error_helper<ErrorIO>("Invalid stored array");
}
dataspace.getSimpleExtentDims(&Npix);
sky.SetNside(sky.npix2nside(Npix), RING);
dataset.read(&sky[0], ht.type());
}
{
H5::DataSet dataset = fg.openDataSet("rmin");
H5::DataSpace dataspace = dataset.getSpace();
hsize_t n;
if (dataspace.getSimpleExtentNdims() != 1)
error_helper<ErrorIO>("Invalid stored rmin");
dataspace.getSimpleExtentDims(&n);
if (n != 1)
error_helper<ErrorIO>("Invalid stored rmin");
dataset.read(&rmin, ht.type());
}
{
H5::DataSet dataset = fg.openDataSet("dr");
H5::DataSpace dataspace = dataset.getSpace();
hsize_t n;
if (dataspace.getSimpleExtentNdims() != 1)
error_helper<ErrorIO>("Invalid stored dr");
dataspace.getSimpleExtentDims(&n);
if (n != 1)
error_helper<ErrorIO>("Invalid stored dr");
dataset.read(&dr, ht.type());
}
CosmoTool::hdf5_read_array(fg, "radial_selection", selection);
}
};
} // namespace LibLSS
#endif

37
libLSS/data/postools.hpp Normal file
View file

@ -0,0 +1,37 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/postools.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_POSTOOLS_HPP
#define __LIBLSS_POSTOOLS_HPP
#include <cmath>
namespace LibLSS {
template<typename T, typename Array>
void loadPosition(T x, T y, T z, Array& xyz) {
xyz[0] = x;
xyz[1] = y;
xyz[2] = z;
}
template<typename T, typename Array>
void loadVelocity(T vx, T vy, T vz, Array& vxyz) {
vxyz[0] = vx;
vxyz[1] = vy;
vxyz[2] = vz;
}
//template<typename T, typename Array>
//void ComputeRedshiftSpacePosition(Array& xyz, Array& vxyz) {
//}
};
#endif

283
libLSS/data/projection.hpp Normal file
View file

@ -0,0 +1,283 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/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 __LIBLSS_PROJECTION_HPP
#define __LIBLSS_PROJECTION_HPP
#include <algorithm>
#include <array>
#include <boost/array.hpp>
#include <boost/multi_array.hpp>
#include <boost/lambda/lambda.hpp>
#include "angtools.hpp"
#include "postools.hpp"
#include "libLSS/tools/array_tools.hpp"
#include "libLSS/physics/generic_cic.hpp"
namespace LibLSS {
enum ProjectionDataModel { NGP_PROJECTION, LUMINOSITY_CIC_PROJECTION };
static const int LSS_DIMENSIONS = 3;
static const int NR_CELLS_DIM = 2;
static const int NR_CELLS_SLICE = 4;
static const int NR_CELLS_TOTAL = 8;
static const double TOTAL_WEIGHT = 1.;
struct Dimension {
union {
double length[LSS_DIMENSIONS];
double position[LSS_DIMENSIONS];
};
};
struct Grid {
size_t resolution[LSS_DIMENSIONS];
};
namespace details {
template <typename GSurvey>
struct ProjectionAcceptAll {
bool operator()(const typename GSurvey::GalaxyType &g) { return true; }
};
}; // namespace details
template <
typename Kernel, typename Periodic, class GSurvey, typename DensityField,
typename Dimension, typename IDimension, typename Condition,
typename PreRun = std::function<void()>>
size_t galaxySurveyToGridGeneric(
const GSurvey &survey, DensityField &field, const IDimension &N,
const Dimension &corner, const Dimension &L, const Dimension &d,
Condition condition, PreRun prerun = PreRun()) {
const typename DensityField::size_type *localN = field.shape();
const typename DensityField::index *base = field.index_bases();
using boost::format;
using boost::lambda::_1;
size_t accepted = 0;
double found_corners[LSS_DIMENSIONS][2];
boost::multi_array<double, 2> xyz(boost::extents[survey.surveySize()][3]);
boost::multi_array<double, 1> weights(boost::extents[survey.surveySize()]);
// prerun must not be empty
if (prerun)
prerun();
for (int i = 0; i < LSS_DIMENSIONS; i++) {
found_corners[i][0] = std::numeric_limits<double>::infinity();
found_corners[i][1] = -std::numeric_limits<double>::infinity();
}
array::fill(field, 0);
for (long i = 0; i < survey.surveySize(); i++) {
typename GSurvey::ConstRefGalaxyType g = survey[i];
boost::array<typename DensityField::index, LSS_DIMENSIONS> ii;
boost::array<double, LSS_DIMENSIONS> loc_xyz;
if (!condition(g))
continue;
ang2vec(g.phi, g.theta, loc_xyz);
for (int j = 0; j < LSS_DIMENSIONS; j++) {
loc_xyz[j] = loc_xyz[j] * g.r - corner[j];
found_corners[j][0] = std::min(loc_xyz[j], found_corners[j][0]);
found_corners[j][1] = std::max(loc_xyz[j], found_corners[j][1]);
}
std::copy(loc_xyz.begin(), loc_xyz.end(), xyz[accepted].begin());
weights[accepted] = g.final_w;
accepted++;
}
Console::instance().format<LOG_VERBOSE>(
"Using type %s for projection", typeid(Periodic).name());
Kernel::projection(
xyz, field, L[0], L[1], L[2], N[0], N[1], N[2],
Periodic(N[0], N[1], N[2]), weights, accepted);
Console::instance().print<LOG_VERBOSE>(
format("Project to grid: accepted %d galaxies") % accepted);
{
std::string cstr;
for (int j = 0; j < LSS_DIMENSIONS; j++)
cstr += str(
format("(%lg - %lg) ") % found_corners[j][0] % found_corners[j][1]);
Console::instance().print<LOG_VERBOSE>(
"Project to grid: found corners " + cstr);
}
return accepted;
}
template <
typename Kernel, typename Periodic, class GSurvey, typename DensityField,
typename Dimension, typename IDimension>
size_t galaxySurveyToGrid_all(
const GSurvey &survey, DensityField &field, const IDimension &N,
const Dimension &corner, const Dimension &L, const Dimension &d) {
details::ProjectionAcceptAll<GSurvey> condition;
return galaxySurveyToGridGeneric<Kernel, Periodic>(
survey, field, N, corner, L, d, condition);
}
/* This function create a mock survey based on the selection function hold in survey_in and the full density field in field.
*/
template <class GSurvey, typename DensityField, typename Dimension>
void createMockSurvey(
const GSurvey &survey_in, GSurvey &survey_out, DensityField &field,
const Dimension &corner, const Dimension &L) {}
template <
class GSurvey, typename DensityField, typename Grid, typename Dimension,
typename Condition>
size_t haloSimToGridGeneric(
const GSurvey &sim, DensityField &field, const Grid &M,
const Dimension &corner, const Dimension &L, const Dimension &d,
Condition condition) {
const typename DensityField::size_type *N = field.shape();
const typename DensityField::index *base = field.index_bases();
using boost::format;
using boost::lambda::_1;
size_t accepted = 0;
double found_corners[LSS_DIMENSIONS][2];
for (auto i = 0; i < LSS_DIMENSIONS; i++) {
found_corners[i][0] = std::numeric_limits<double>::infinity();
found_corners[i][1] = -std::numeric_limits<double>::infinity();
}
for (auto i = 0; i < sim.surveySize(); i++) {
typename GSurvey::ConstRefGalaxyType h = sim[i];
std::array<
std::array<typename DensityField::index, LSS_DIMENSIONS>,
NR_CELLS_TOTAL>
ii;
std::array<double, LSS_DIMENSIONS> xyz;
bool validLowerSlice = true;
bool validUpperSlice = true;
if (!condition(h))
continue;
loadPosition(h.posx, h.posy, h.posz, xyz);
for (int j = 0; j < LSS_DIMENSIONS; j++) {
ii[0][j] = (int)std::floor((xyz[j] - corner[j]) / d[j]);
found_corners[j][0] = std::min(xyz[j], found_corners[j][0]);
found_corners[j][1] = std::max(xyz[j], found_corners[j][1]);
}
std::array<double, NR_CELLS_TOTAL> weight;
std::array<std::array<double, LSS_DIMENSIONS>, NR_CELLS_DIM> wxyz;
for (auto j = 0; j < LSS_DIMENSIONS; j++) {
wxyz[1][j] = ((xyz[j] - corner[j]) / d[j]) - ii[0][j];
wxyz[0][j] = TOTAL_WEIGHT - wxyz[1][j];
}
weight[0] = wxyz[0][0] * wxyz[0][1] * wxyz[0][2];
weight[1] = wxyz[0][0] * wxyz[1][1] * wxyz[0][2];
weight[2] = wxyz[0][0] * wxyz[0][1] * wxyz[1][2];
weight[3] = wxyz[0][0] * wxyz[1][1] * wxyz[1][2];
weight[4] = wxyz[1][0] * wxyz[0][1] * wxyz[0][2];
weight[5] = wxyz[1][0] * wxyz[1][1] * wxyz[0][2];
weight[6] = wxyz[1][0] * wxyz[0][1] * wxyz[1][2];
weight[7] = wxyz[1][0] * wxyz[1][1] * wxyz[1][2];
for (auto j = 0; j < LSS_DIMENSIONS; j++) {
if ((ii[0][j] == -1) || (ii[0][j] == M[j]))
ii[0][j] = M[j] - 1;
}
for (auto cell = 1; cell < NR_CELLS_TOTAL; cell++) {
std::copy(std::begin(ii[0]), std::end(ii[0]), std::begin(ii[cell]));
}
ii[1][1]++;
ii[1][1] = (size_t)std::fmod(ii[1][1], M[1]);
ii[2][2]++;
ii[2][2] = (size_t)std::fmod(ii[2][2], M[2]);
ii[3][1]++;
ii[3][1] = (size_t)std::fmod(ii[3][1], M[1]);
ii[3][2]++;
ii[3][2] = (size_t)std::fmod(ii[3][2], M[2]);
ii[4][0]++;
ii[4][0] = (size_t)std::fmod(ii[4][0], M[0]);
ii[5][0]++;
ii[5][0] = (size_t)std::fmod(ii[5][0], M[0]);
ii[5][1]++;
ii[5][1] = (size_t)std::fmod(ii[5][1], M[1]);
ii[6][0]++;
ii[6][0] = (size_t)std::fmod(ii[6][0], M[0]);
ii[6][2]++;
ii[6][2] = (size_t)std::fmod(ii[6][2], M[2]);
for (auto j = 0; j < LSS_DIMENSIONS; j++) {
ii[7][j]++;
ii[7][j] = (size_t)std::fmod(ii[7][j], M[j]);
}
for (auto j = 0; j < LSS_DIMENSIONS; j++) {
validLowerSlice = validLowerSlice &&
(ii[0][j] >= base[j] && ii[0][j] < (base[j] + N[j]));
validUpperSlice = validUpperSlice &&
(ii[4][j] >= base[j] && ii[4][j] < (base[j] + N[j]));
}
if (validLowerSlice) {
for (auto cell = 0; cell < NR_CELLS_SLICE; cell++) {
field(ii[cell]) += weight[cell] * h.w;
accepted++;
}
}
if (validUpperSlice) {
for (auto cell = NR_CELLS_SLICE; cell < NR_CELLS_TOTAL; cell++) {
field(ii[cell]) += weight[cell] * h.w;
accepted++;
}
}
}
Console::instance().print<LOG_VERBOSE>(
format("Project to grid: accept and assign halos to %d cells") %
accepted);
{
std::string cstr;
for (auto j = 0; j < LSS_DIMENSIONS; j++)
cstr += str(
format("(%lg - %lg) ") % found_corners[j][0] % found_corners[j][1]);
Console::instance().print<LOG_VERBOSE>(
"Project to grid: found corners " + cstr);
}
return accepted;
}
template <
class GSurvey, typename DensityField, typename Grid, typename Dimension>
size_t haloSimToGrid_all(
const GSurvey &sim, DensityField &field, const Grid &M,
const Dimension &corner, const Dimension &L, const Dimension &d) {
details::ProjectionAcceptAll<GSurvey> condition;
return haloSimToGridGeneric<
GSurvey, DensityField, Grid, Dimension,
details::ProjectionAcceptAll<GSurvey>>(
sim, field, M, corner, L, d, condition);
}
}; // namespace LibLSS
CTOOL_ENUM_TYPE(
LibLSS::ProjectionDataModel, HDF5T_ProjectionDataModel,
(LibLSS::NGP_PROJECTION)(LibLSS::LUMINOSITY_CIC_PROJECTION))
#endif

View file

@ -0,0 +1,159 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/schechter_completeness.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_SCHECHTER_COMPLETENESS_HPP
#define __LIBLSS_SCHECHTER_COMPLETENESS_HPP
#include <cmath>
#include <functional>
#include <boost/format.hpp>
#include "libLSS/tools/console.hpp"
#include "libLSS/physics/cosmo.hpp"
#include "libLSS/tools/gslIntegrate.hpp"
#include <CosmoTool/hdf5_array.hpp>
#include "libLSS/data/spectro_gals.hpp"
#include "libLSS/data/galaxies.hpp"
#include "libLSS/data/projection.hpp"
namespace LibLSS {
typedef std::function<bool(const BaseGalaxyDescriptor &)> GalaxySelector;
struct GalaxySampleSelection {
double bright_apparent_magnitude_cut;
double faint_apparent_magnitude_cut;
double bright_absolute_magnitude_cut;
double faint_absolute_magnitude_cut;
double zmin, zmax;
double dmin, dmax;
double low_mass_cut;
double high_mass_cut;
double small_radius_cut;
double large_radius_cut;
double low_spin_cut;
double high_spin_cut;
// This is required to satisfy C++ object layout
// Otherwise the struct GalaxySampleSelection is not "trivial".
std::shared_ptr<GalaxySelector> selector;
ProjectionDataModel projection;
};
static inline std::shared_ptr<GalaxySelector> makeSelector(GalaxySelector f) {
return std::make_shared<GalaxySelector>(f);
}
struct SchechterParameters {
double Mstar, alpha;
};
namespace details {
static inline double
_integrand_luminosity(const SchechterParameters &params, double x) {
return std::pow(x, params.alpha) * exp(-x);
}
static inline double integral_luminosity(
const SchechterParameters &params, double x_min, double x_max) {
return gslIntegrate(
std::bind(_integrand_luminosity, params, std::placeholders::_1),
x_min, x_max, 1e-8);
}
static inline double computeSchechterCompleteness(
const Cosmology &cosmo, double z, double d_comoving,
const GalaxySampleSelection &selection,
const SchechterParameters &params,
CorrectionFunction zcorrection = nullCorrection) {
using boost::format;
ConsoleContext<LOG_DEBUG> ctx("computeSchechterCompleteness");
double d_lum = cosmo.d2dlum(z, d_comoving);
double corr = zcorrection(z);
double absolute_mu0 = selection.faint_apparent_magnitude_cut -
5 * std::log10(d_lum) - 25 - corr;
double absolute_ml0 = selection.bright_apparent_magnitude_cut -
5 * std::log10(d_lum) - 25 - corr;
double abmu =
std::min(absolute_mu0, selection.faint_absolute_magnitude_cut);
double abml =
std::max(absolute_ml0, selection.bright_absolute_magnitude_cut);
ctx.print(
format("z = %lg d_lum = %lg abmu = %lg abml = %lg") % z % d_lum %
abmu % abml);
abmu = std::max(abmu, abml);
double xl0 = std::pow(10.0, 0.4 * (params.Mstar - abmu));
double xu0 = std::pow(10.0, 0.4 * (params.Mstar - abml));
double xl1 = std::pow(
10.0, 0.4 * (params.Mstar - selection.faint_absolute_magnitude_cut));
double xu1 = std::pow(
10.0, 0.4 * (params.Mstar - selection.bright_absolute_magnitude_cut));
ctx.print(
format("xl0 = %lg, xu0 = %lg, xl1 = %lg, xu1 = %lg") % xl0 % xu0 %
xl1 % xu1);
double Phi0 = integral_luminosity(params, xl0, xu0);
double Phi1 = integral_luminosity(params, xl1, xu1);
return std::max(0.0, Phi0 / Phi1);
}
} // namespace details
template <typename Array>
void buildCompletenessFromSchechterFunction(
const Cosmology &cosmo, const GalaxySampleSelection &selection,
const SchechterParameters &params, Array &completeness, double Dmax,
CorrectionFunction zcorr = details::nullCorrection) {
ConsoleContext<LOG_DEBUG> ctx("buildCompletenessFromSchechterFunction");
long N = completeness.num_elements();
for (long i = 1; i < N; i++) {
double d = i * Dmax / N;
double z = cosmo.a2z(cosmo.com2a(cosmo.comph2com(d)));
if (z < selection.zmin || z > selection.zmax)
completeness[i] = 0;
else
completeness[i] = details::computeSchechterCompleteness(
cosmo, z, d, selection, params, zcorr);
//ctx.print(boost::format("d = %lg, z = %lg, C = %lg") % d % z % completeness[i]);
}
// zero distance is hard, just copy the one next to it. If sampling is sufficient that will not matter.
completeness[0] = completeness[1];
}
} // namespace LibLSS
CTOOL_STRUCT_TYPE(
LibLSS::GalaxySampleSelection, HDF5T_GalaxySampleSelection,
((double,
bright_apparent_magnitude_cut))((double, faint_apparent_magnitude_cut))(
(double, bright_absolute_magnitude_cut))(
(double, faint_absolute_magnitude_cut))((double, zmin))((double, zmax))(
(double, dmin))((double, dmax))((double, low_mass_cut))(
(double, high_mass_cut))((double, small_radius_cut))(
(double, large_radius_cut))((double, low_spin_cut))(
(double, high_spin_cut))((LibLSS::ProjectionDataModel, projection)));
CTOOL_STRUCT_TYPE(
LibLSS::SchechterParameters, HDF5T_SchechterParameters,
((double, Mstar))((double, alpha)));
#endif

View file

@ -0,0 +1,164 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/spectro_gals.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_DATA_GALACTIC_HPP
#define __LIBLSS_DATA_GALACTIC_HPP
#include <H5Cpp.h>
#include <boost/utility/base_from_member.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/multi_array.hpp>
#include <boost/function.hpp>
#include <healpix_cxx/pointing.h>
#include "libLSS/data/base.hpp"
#include "libLSS/tools/allocator_policy.hpp"
#include "libLSS/tools/checkmem.hpp"
#include "libLSS/physics/cosmo.hpp"
#include "libLSS/tools/hdf5_type.hpp"
namespace LibLSS
{
class NoSelection {
public:
int getNumRadial() const {return 1;}
double getRadialSelection(double r, int n) const { return 1; }
double get_sky_completeness(double x, double y, double z) const { return 1; }
};
HAS_MEM_FUNC(saveFunction, has_save_function);
HAS_MEM_FUNC(loadFunction, has_load_function);
/* These are two helper functions. Depending on the availability of the
* member function void T::saveFunction(H5_CommonFileGroup&), the function
* will be executed (or not if it does not exist). This ensures
* that GalaxySurvey always try to save the maximum but still is
* compatible with restricted selection functions.
*/
namespace details {
template<typename T>
typename boost::enable_if< has_save_function<T, void (T::*)(H5_CommonFileGroup&)> >::type
saveRadialCompleteness(H5_CommonFileGroup& fg, T& func)
{
func.saveFunction(fg);
}
template<typename T>
typename boost::disable_if< has_load_function<T, void (T::*)(H5_CommonFileGroup&)> >::type
saveRadialCompleteness(H5_CommonFileGroup& fg, T& func)
{
}
template<typename T>
typename boost::enable_if< has_load_function<T, void (T::*)(H5_CommonFileGroup&)> >::type
loadRadialCompleteness(H5_CommonFileGroup& fg, T& func)
{
func.loadFunction(fg);
}
template<typename T>
typename boost::disable_if< has_save_function<T, void (T::*)(H5_CommonFileGroup&)> >::type
loadRadialCompleteness(H5_CommonFileGroup& fg, T& func)
{
}
static double nullCorrection(double d) { return 0; }
};
typedef boost::function1<double, double> CorrectionFunction;
template<typename SelFunction, class GT, class AllocationPolicy = DefaultAllocationPolicy>
class GalaxySurvey: virtual LibLSS::Base_Data
{
public:
typedef GT GalaxyType;
typedef GT& RefGalaxyType;
typedef const GT& ConstRefGalaxyType;
typedef typename boost::multi_array<GalaxyType, 1> GalaxyArray;
protected:
GalaxyArray galaxies;
long numGalaxies;
SelFunction radialSelection;
bool is_reference_survey;
CorrectionFunction zcorrection;
public:
GalaxySurvey(bool ref_survey = false) : numGalaxies(0), is_reference_survey(ref_survey) {}
~GalaxySurvey() {}
SelFunction& selection() { return radialSelection; }
const SelFunction& selection() const { return radialSelection; }
double getCompleteness(double phi, double theta) {
vec3 v(pointing(0.5*M_PI - theta, phi));
return radialSelection.get_sky_completeness(v.x, v.y, v.z);
}
void setSelectionFunction(SelFunction f) {
radialSelection = f;
}
bool isReferenceSurvey() const { return is_reference_survey; }
RefGalaxyType operator[](size_t i) {
return galaxies[i];
}
ConstRefGalaxyType operator[](size_t i) const {
return galaxies[i];
}
void optimize() {
galaxies.resize(boost::extents[numGalaxies]);
}
long surveySize() const { return numGalaxies; }
// Methods defined in the tcc file
void addGalaxy(const GalaxyType& g);
// I/O support for galaxy surveys
void saveMain(H5_CommonFileGroup& fg);
void restoreMain(H5_CommonFileGroup& fg);
void save(H5_CommonFileGroup& fg) {
saveMain(fg);
details::saveRadialCompleteness(fg, radialSelection);
}
void restore(H5_CommonFileGroup& fg) {
restoreMain(fg);
details::loadRadialCompleteness(fg, radialSelection);
}
void updateComovingDistance(const Cosmology& cosmo, const CorrectionFunction& zcorrection = details::nullCorrection);
void useLuminosityAsWeight();
void resetWeight();
void setCorrections(const CorrectionFunction& zcorrection = details::nullCorrection) { this->zcorrection = zcorrection; }
//
GalaxyArray& getGalaxies() { return galaxies; }
const GalaxyArray& getGalaxies() const { return galaxies; }
GalaxyArray& allocateGalaxies(size_t numGals) {
numGalaxies = numGals;
galaxies.resize(boost::extents[numGals]);
return galaxies;
}
};
};
#include "spectro_gals.tcc"
#endif

View file

@ -0,0 +1,81 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/spectro_gals.tcc
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 <iostream>
#include <CosmoTool/hdf5_array.hpp>
#include "libLSS/tools/hdf5_scalar.hpp"
#include "libLSS/tools/hdf5_type.hpp"
namespace LibLSS {
template<typename SelFunction, class GalaxyType, class AllocationPolicy>
void GalaxySurvey<SelFunction,GalaxyType,AllocationPolicy>::addGalaxy(const GalaxyType& galaxy) {
if (numGalaxies == galaxies.size()) {
galaxies.resize(boost::extents[numGalaxies+AllocationPolicy::getIncrement()]);
}
galaxies[numGalaxies] = galaxy;
numGalaxies++;
}
template<typename SelFunction, class GalaxyType, class AllocationPolicy>
void GalaxySurvey<SelFunction,GalaxyType,AllocationPolicy>::resetWeight() {
for (size_t i = 0; i < numGalaxies; i++) {
galaxies[i].final_w = galaxies[i].w;
}
}
template<typename SelFunction, class GalaxyType, class AllocationPolicy>
void GalaxySurvey<SelFunction,GalaxyType,AllocationPolicy>::useLuminosityAsWeight() {
for (size_t i = 0; i < numGalaxies; i++) {
// Add a 10^8 scaling to put the values within a reasonable range scales for the MCMC.
double L = std::pow(10, -0.4*galaxies[i].M_abs)/1e8;
galaxies[i].final_w = galaxies[i].w * L;
}
}
template<typename SelFunction, class GalaxyType, class AllocationPolicy>
void GalaxySurvey<SelFunction,GalaxyType,AllocationPolicy>::saveMain(H5_CommonFileGroup& fg)
{
optimize();
CosmoTool::hdf5_write_array(fg, "galaxies", galaxies );
hdf5_save_scalar(fg, "is_reference_survey", is_reference_survey);
}
template<typename SelFunction, class GalaxyType, class AllocationPolicy>
void GalaxySurvey<SelFunction,GalaxyType,AllocationPolicy>::restoreMain(H5_CommonFileGroup& fg)
{
CosmoTool::hdf5_read_array(fg, "galaxies", galaxies );
numGalaxies = galaxies.size();
is_reference_survey = hdf5_load_scalar<bool>(fg, "is_reference_survey");
}
template<typename SelFunction, class GalaxyType, class AllocationPolicy>
void GalaxySurvey<SelFunction,GalaxyType,AllocationPolicy>::updateComovingDistance(const Cosmology& cosmo, const CorrectionFunction& zcorrection)
{
LibLSS::ConsoleContext<LOG_DEBUG> ctx("Updating comoving positions of galaxies");
#pragma omp parallel for
for (size_t i = 0; i < numGalaxies; i++) {
if (galaxies[i].z < 0) {
galaxies[i].r = 0;
galaxies[i].M_abs = std::numeric_limits<double>::infinity();
continue;
}
galaxies[i].r = cosmo.com2comph(cosmo.a2com(cosmo.z2a(galaxies[i].z)));
double dlum = cosmo.d2dlum(galaxies[i].z, galaxies[i].r);
double zcorr = zcorrection(galaxies[i].z);
// ctx.print(boost::format("z[%d] = %lg, m_correction = %lg") % i % galaxies[i].z % zcorr);
galaxies[i].M_abs = galaxies[i].m - 5 * std::log10(dlum) - 25 - zcorr;
}
}
};

View file

@ -0,0 +1,139 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/survey_load_bin.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_GALAXY_LOAD_BIN_HPP
#define __LIBLSS_GALAXY_LOAD_BIN_HPP
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <boost/format.hpp>
#include "libLSS/tools/console.hpp"
#include "libLSS/tools/errors.hpp"
#include <CosmoTool/hdf5_array.hpp>
#include <H5Cpp.h>
namespace LibLSS {
struct BinGalaxyStruct {
size_t id;
double phi, theta;
double zo;
double m;
double M_abs;
double z;
double w;
};
struct BinHaloStruct {
size_t id;
double Mgal, radius, spin, posx, posy, posz, vx, vy, vz;
double w;
};
}
CTOOL_STRUCT_TYPE(LibLSS::BinGalaxyStruct, HDF5T_LibLSS_BinGalaxyStruct,
((size_t, id))
((double, phi))
((double, theta))
((double, zo))
((double, m))
((double, M_abs))
((double, z))
((double, w))
);
CTOOL_STRUCT_TYPE(LibLSS::BinHaloStruct, HDF5T_LibLSS_BinHaloStruct,
((size_t, id))
((double, Mgal))
((double, radius))
((double, spin))
((double, posx))
((double, posy))
((double, posz))
((double, vx))
((double, vy))
((double, vz))
((double, w))
);
namespace LibLSS {
template<typename GalaxySurvey>
void loadCatalogFromHDF5(
const std::string& fname,
const std::string& key,
GalaxySurvey& sim) {
using namespace std;
using boost::format;
Console& cons = Console::instance();
long originalSize = sim.surveySize();
cons.print<LOG_STD>(format("Reading HDF5 catalog file '%s' / key '%s'") % fname % key);
bool warningDefault = false;
boost::multi_array<BinGalaxyStruct, 1> halos;
H5::H5File f(fname, H5F_ACC_RDONLY) ;
CosmoTool::hdf5_read_array(f, key, halos);
auto& gals = sim.allocateGalaxies(halos.shape()[0]);
for (size_t i = 0; i < halos.num_elements(); i++) {
gals[i].id = halos[i].id;
gals[i].phi = halos[i].phi;
gals[i].theta = halos[i].theta;
gals[i].final_w = gals[i].w = halos[i].w;
gals[i].m = halos[i].m;
gals[i].M_abs = halos[i].M_abs;
gals[i].z = halos[i].z;
gals[i].zo = halos[i].zo;
}
cons.print<LOG_STD>(format("Got %d halos") % gals.num_elements());
}
template<typename GalaxySurvey>
void loadHaloSimulationFromHDF5(
const std::string& fname,
const std::string& key,
GalaxySurvey& sim) {
using namespace std;
using boost::format;
Console& cons = Console::instance();
long originalSize = sim.surveySize();
cons.format<LOG_STD>("Reading HDF5 catalog file '%s' / key '%s'", fname , key);
bool warningDefault = false;
boost::multi_array<BinHaloStruct, 1> halos;
H5::H5File f(fname, H5F_ACC_RDONLY) ;
cons.print<LOG_STD>("Reading data file");
CosmoTool::hdf5_read_array(f, key, halos);
cons.print<LOG_STD>("Transfering to internal structure");
auto& gals = sim.allocateGalaxies(halos.num_elements());
for (size_t i = 0; i < halos.num_elements(); i++) {
gals[i].id = halos[i].id;
gals[i].final_w = gals[i].w = halos[i].w;
gals[i].posx = halos[i].posx;
gals[i].posy = halos[i].posy;
gals[i].posz = halos[i].posz;
gals[i].vx = halos[i].vx;
gals[i].vy = halos[i].vy;
gals[i].vz = halos[i].vz;
gals[i].spin = halos[i].spin;
gals[i].radius = halos[i].radius;
gals[i].Mgal = halos[i].Mgal;
vec2ang(std::array<double,3>{halos[i].posx,halos[i].posy,halos[i].posz}, gals[i].phi, gals[i].theta, gals[i].r);
}
cons.print<LOG_STD>(format("Got %d halos") % gals.num_elements());
}
}
#endif

View file

@ -0,0 +1,108 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/survey_load_txt.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_GALAXY_LOAD_TXT_HPP
#define __LIBLSS_GALAXY_LOAD_TXT_HPP
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <boost/format.hpp>
#include "libLSS/tools/console.hpp"
#include "libLSS/tools/errors.hpp"
namespace LibLSS {
template <typename GalaxySurvey>
void
loadGalaxySurveyFromText(const std::string &fname, GalaxySurvey &survey) {
using namespace std;
using boost::format;
Console &cons = Console::instance();
long originalSize = survey.surveySize();
string line;
ifstream f(fname.c_str());
if (!f) {
error_helper<ErrorIO>(format("Cannot open file '%s'") % fname);
}
cons.print<LOG_STD>(format("Reading galaxy survey file '%s'") % fname);
bool warningDefault = false;
while (getline(f, line)) {
istringstream ss(line);
typename GalaxySurvey::GalaxyType g;
ss >> g.id >> g.phi >> g.theta >> g.zo >> g.m >> g.M_abs >> g.z;
g.Mgal = 0;
g.r = 0;
g.radius = 0;
g.spin = 0;
g.posx = g.posy = g.posz = 0;
g.vx = g.vy = g.vz = 0;
if (!(ss >> g.w)) {
g.w = 1;
warningDefault = true;
}
g.final_w = g.w;
survey.addGalaxy(g);
}
if (warningDefault)
cons.print<LOG_WARNING>("I used a default weight of 1");
cons.print<LOG_STD>(
format("Receive %d galaxies in total") %
(survey.surveySize() - originalSize));
survey.optimize();
}
template <typename GalaxySurvey>
void loadHaloSimulationFromText(const std::string &fname, GalaxySurvey &sim) {
using namespace std;
using boost::format;
Console &cons = Console::instance();
long originalSize = sim.surveySize();
string line;
ifstream f(fname.c_str());
if (!f) {
error_helper<ErrorIO>(format("Cannot open file '%s'") % fname);
}
cons.print<LOG_STD>(format("Read halo catalog file '%s'") % fname);
bool warningDefault = false;
while (getline(f, line)) {
istringstream ss(line);
typename GalaxySurvey::GalaxyType h;
ss >> h.id >> h.Mgal >> h.radius >> h.spin >> h.posx >> h.posy >>
h.posz >> h.vx >> h.vy >> h.vz;
if (!(ss >> h.w)) {
h.w = 1;
warningDefault = true;
}
h.final_w = h.w;
vec2ang(
std::array<double, 3>{h.posx, h.posy, h.posz}, h.phi, h.theta, h.r);
sim.addGalaxy(h);
}
sim.optimize();
if (warningDefault)
cons.print<LOG_WARNING>("Use default weight of 1 for all halos");
cons.print<LOG_STD>(
format("Receive %d halos in total") %
(sim.surveySize() - originalSize));
}
} // namespace LibLSS
#endif

18
libLSS/data/toto.cpp Normal file
View file

@ -0,0 +1,18 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/toto.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 <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/stringize.hpp>
#define SEQ (z)(x)(y)(z)
#define MACRO(r, data, elem) BOOST_PP_CAT(BOOST_PP_STRINGIZE(elem), data)
BOOST_PP_SEQ_FOR_EACH(MACRO, _, SEQ) // expands to w_ x_ y_ z_

174
libLSS/data/window3d.hpp Normal file
View file

@ -0,0 +1,174 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/window3d.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_WINDOW_3D_HPP
#define __LIBLSS_WINDOW_3D_HPP
#include <cassert>
#include <functional>
#include "libLSS/mpi/generic_mpi.hpp"
#include "libLSS/tools/openmp.hpp"
#include "libLSS/samplers/rgen/gsl_miser.hpp"
#include <CosmoTool/algo.hpp>
#include <boost/array.hpp>
#include <numeric>
#include <cmath>
namespace LibLSS {
namespace internalWindow {
template<typename SelFunction3d>
double selectionValue(double *k, const SelFunction3d& selfunc) {
double r = std::sqrt(k[0]*k[0]+k[1]*k[1]+k[2]*k[2]);
return selfunc.get_sky_completeness(k[0]/r, k[1]/r, k[2]/r) * selfunc.getRadialSelection(r, 0);
}
template<typename SelFunction3d>
double selectionValue_just_sky(double *k, const SelFunction3d& selfunc) {
return selfunc.get_sky_completeness(k[0], k[1], k[2]);
}
}
template<typename RandomNum, typename SelFunction3d, typename SelFuncMask, typename Dimension>
void compute_window_value_elem(
MPI_Communication *comm,
RandomNum& rng,
const SelFunction3d& selfunc,
SelFuncMask& selfuncData,
const Dimension& L,
const Dimension& d,
const Dimension& xmin, bool filter_mask,
double precision = 0.01)
{
using boost::str;
using boost::format;
Console& cons = Console::instance();
boost::multi_array<int,1> count_elements(boost::extents[LibLSS::smp_get_max_threads()]);
size_t startN0 = selfuncData.index_bases()[0];
size_t localN0 = selfuncData.shape()[0], N1 = selfuncData.shape()[1], N2 = selfuncData.shape()[2];
double d0=d[0];
double d1=d[1];
double d2=d[2];
double xmin0 = xmin[0];
double xmin1 = xmin[1];
double xmin2 = xmin[2];
size_t N0 = L[0]/d0; // This is HACK
double refVolume = CosmoTool::square(precision/0.01)*CosmoTool::cube(3); // Ref is 3 Mpc,
size_t calls = 10 + size_t(1000 * (d0*d1*d2 / refVolume));
cons.indent();
Progress<LOG_STD>& p = cons.start_progress<LOG_STD>("3D Window", localN0*N1*N2, 2);
cons.print<LOG_INFO>(
format("Use a tolerance of %g on window function integral / calls = %d")
% precision % calls);
std::fill(count_elements.begin(), count_elements.end(), 0);
long job_start = startN0*N1*N2;
long job_end = (startN0+localN0)*N1*N2;
cons.print<LOG_DEBUG>(
format("Window computation, MPI job_start=%ld job_end=%ld") % job_start % job_end
);
cons.print<LOG_DEBUG>(
format("Max threads = %d, ID = %d") % LibLSS::smp_get_max_threads() % LibLSS::smp_get_thread_id());
cons.print<LOG_DEBUG>(
format("d=[%g,%g,%g], L=[%g,%g,%g]") % d[0] % d[1] % d[2] % L[0] % L[1] % L[2]
);
double dV = d0*d1*d2;
typedef boost::multi_array_types::extent_range range;
boost::multi_array<bool,3> dummy(boost::extents[range(startN0,startN0+localN0)][N1][N2]);
boost::multi_array<double,3> all_err(boost::extents[range(startN0,startN0+localN0)][N1][N2]);
double mask_th = 0.5; //the voxel should have been observed at least to 50 percent
#pragma omp parallel
{
GSL_Miser miser(3);
#pragma omp for schedule(dynamic,100)
for(size_t i=job_start;i<job_end;i++) {
///get 3d indices
size_t ii=(size_t) (i/N1/N2);
size_t jj=(size_t) (i/N2 - ii *N1);
size_t kk=(size_t) (i-jj*N2-ii*N2*N1);
double
x = double(ii)*d0+xmin0,
y = double(jj)*d1+xmin1,
z = double(kk)*d2+xmin2;
double err;
boost::array<double, 3> xl{x - 0.5*d0, y-0.5*d1, z-0.5*d2};
boost::array<double, 3> xu{x + 0.5*d0, y + 0.5*d1, z + 0.5*d2};
//here we do a pre-run, where we project the sky completeness into 3d
double auxval;
if (filter_mask) {
auxval = miser.integrate(rng,
std::bind(&internalWindow::selectionValue_just_sky<SelFunction3d>, std::placeholders::_1, std::cref(selfunc)),
xl, xu, calls, err) / (dV);
} else {
auxval = mask_th*2;
}
//avoid double calculations for uninteresting mask regions
if(auxval > mask_th) {
dummy[ii][jj][kk]=true;
selfuncData[ii][jj][kk] =
miser.integrate(rng,
std::bind(&internalWindow::selectionValue<SelFunction3d>, std::placeholders::_1, std::cref(selfunc)),
xl, xu, calls, err) / (dV);
all_err[ii][jj][kk] = err;
} else {
selfuncData[ii][jj][kk] = 0.;
}
assert(LibLSS::smp_get_thread_id() < LibLSS::smp_get_max_threads());
count_elements[LibLSS::smp_get_thread_id()]++;
if (LibLSS::smp_get_thread_id() == 0) {
int done = std::accumulate(count_elements.begin(), count_elements.end(), 0);
p.update(done);
}
}
}
cons.unindent();
p.destroy();
if (false)
{
H5::H5File f("window_err.h5", H5F_ACC_TRUNC);
CosmoTool::hdf5_write_array(f, "errors", all_err);
CosmoTool::hdf5_write_array(f, "sel", selfuncData);
}
///now delete from mask
#pragma omp parallel for collapse(3)
for (size_t n0 = startN0; n0 < startN0+localN0; n0++) {
for (size_t n1 = 0; n1 < N1; n1++) {
for (size_t n2 = 0; n2 < N2; n2++) {
if(!dummy[n0][n1][n2])
selfuncData[n0][n1][n2] = 0.;
}
}
}
}
};
#endif

View file

@ -0,0 +1,105 @@
/*+
ARES/HADES/BORG Package -- ./libLSS/data/window3d_post.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_DATA_WINDOW_3D_POST_HPP
#define __LIBLSS_DATA_WINDOW_3D_POST_HPP
#include <cassert>
#include <functional>
#include "libLSS/mpi/generic_mpi.hpp"
#include "libLSS/tools/openmp.hpp"
#include <CosmoTool/algo.hpp>
#include <boost/array.hpp>
#include <numeric>
#include <cmath>
#include "libLSS/tools/console.hpp"
#include "libLSS/samplers/core/types_samplers.hpp"
#include "libLSS/tools/mpi_fftw_helper.hpp"
#include "libLSS/tools/fusewrapper.hpp"
namespace LibLSS {
namespace convolveDetails {
template<typename RealArray>
void buildKernel(FFTW_Manager_3d<double>& mgr, RealArray& real_data) {
constexpr double KernelCore[2] = {1, 0.5};
decltype(mgr.N0) N[3] = {mgr.N0, mgr.N1, mgr.N2};
for (int i = -1; i <= 1; i++) {
size_t ri = (i < 0) ? (N[0]+i) : i;
if (!mgr.on_core(ri))
continue;
size_t ai = std::abs(i);
for (int j = -1; j<= 1; j++) {
size_t rj = (j < 0) ? (N[1]+j) : j;
size_t aj = std::abs(j);
for (int k = -1; k <= 1; k++) {
size_t rk = (k < 0) ? (N[2]+k) : k;
size_t ak = std::abs(k);
real_data[ri][rj][rk] = KernelCore[ai]*KernelCore[aj]*KernelCore[ak];
}
}
}
}
}
template<typename SelectionArray, typename T>
void convolve_selection_cic(MPI_Communication *comm, SelectionArray& sel_array, T const* N)
{
typedef FFTW_Manager_3d<double> DFT_Manager;
typedef typename DFT_Manager::plan_type plan_type;
ConsoleContext<LOG_DEBUG> ctx("convolution of selection function");
DFT_Manager mgr(N[0], N[1], N[2], comm);
Uninit_FFTW_Real_Array real_data_p(mgr.extents_real(), mgr.allocator_real);
Uninit_FFTW_Complex_Array complex_data_p(mgr.extents_complex(), mgr.allocator_complex);
Uninit_FFTW_Complex_Array kernel_data_p(mgr.extents_complex(), mgr.allocator_complex);
auto real_data = real_data_p.get_array();
auto complex_data = complex_data_p.get_array();
auto kernel_data = kernel_data_p.get_array();
auto wc = fwrap(complex_data);
auto wr = fwrap(real_data);
auto kc = fwrap(kernel_data);
ctx.print("Create plans");
plan_type analysis_plan = mgr.create_r2c_plan(real_data.data(), complex_data.data());
plan_type synthesis_plan = mgr.create_c2r_plan(complex_data.data(), real_data.data());
ctx.print("Kernel building");
wr = 0;
convolveDetails::buildKernel(mgr, real_data);
mgr.execute_r2c(analysis_plan, real_data.data(), kernel_data.data());
ctx.print("Convolve");
LibLSS::copy_array(real_data, sel_array);
mgr.execute_r2c(analysis_plan, real_data.data(), complex_data.data());
wc = wc * kc * (1.0/(N[0]*N[1]*N[2]));
mgr.execute_c2r(synthesis_plan, complex_data.data(), real_data.data());
auto S = fwrap(sel_array) ;
// This is a mask operation, if the condition is true, then S is copied on itself (thus noop).
// If the condition is false, then the value is cleared with zero. The wrapping of constant
// is not trivial at the moment.
S = mask((S>0)&&(wr>=0), S, fwrap(S.fautowrap(0)));
ctx.print("Cleaning up");
mgr.destroy_plan(analysis_plan);
mgr.destroy_plan(synthesis_plan);
}
}
#endif