Initial import
This commit is contained in:
commit
56a50eead3
820 changed files with 192077 additions and 0 deletions
55
libLSS/data/angtools.hpp
Normal file
55
libLSS/data/angtools.hpp
Normal 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
23
libLSS/data/base.hpp
Normal 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
97
libLSS/data/galaxies.hpp
Normal 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
|
132
libLSS/data/integer_window3d.hpp
Normal file
132
libLSS/data/integer_window3d.hpp
Normal 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
|
213
libLSS/data/linear_selection.hpp
Normal file
213
libLSS/data/linear_selection.hpp
Normal 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
37
libLSS/data/postools.hpp
Normal 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
283
libLSS/data/projection.hpp
Normal 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
|
159
libLSS/data/schechter_completeness.hpp
Normal file
159
libLSS/data/schechter_completeness.hpp
Normal 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 ¶ms, double x) {
|
||||
return std::pow(x, params.alpha) * exp(-x);
|
||||
}
|
||||
|
||||
static inline double integral_luminosity(
|
||||
const SchechterParameters ¶ms, 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 ¶ms,
|
||||
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 ¶ms, 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
|
164
libLSS/data/spectro_gals.hpp
Normal file
164
libLSS/data/spectro_gals.hpp
Normal 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
|
81
libLSS/data/spectro_gals.tcc
Normal file
81
libLSS/data/spectro_gals.tcc
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
139
libLSS/data/survey_load_bin.hpp
Normal file
139
libLSS/data/survey_load_bin.hpp
Normal 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
|
108
libLSS/data/survey_load_txt.hpp
Normal file
108
libLSS/data/survey_load_txt.hpp
Normal 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
18
libLSS/data/toto.cpp
Normal 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
174
libLSS/data/window3d.hpp
Normal 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
|
105
libLSS/data/window3d_post.hpp
Normal file
105
libLSS/data/window3d_post.hpp
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue