mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-05 15:51:12 +00:00
Renamed directory mytools to pipeline_tools
This commit is contained in:
parent
b5ee1cc7a6
commit
f6fae36329
14 changed files with 0 additions and 0 deletions
42
pipeline_tools/FindHealpix.cmake
Normal file
42
pipeline_tools/FindHealpix.cmake
Normal file
|
@ -0,0 +1,42 @@
|
|||
OPTION(ENABLE_OPENMP "Set to Yes if Healpix and/or you need openMP" OFF)
|
||||
|
||||
#
|
||||
# OpenMP handling
|
||||
#
|
||||
|
||||
|
||||
INCLUDE(FindOpenMP)
|
||||
|
||||
IF(ENABLE_OPENMP)
|
||||
|
||||
IF (NOT OPENMP_FOUND)
|
||||
MESSAGE(ERROR "No known compiler option for enabling OpenMP")
|
||||
ENDIF(NOT OPENMP_FOUND)
|
||||
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKED_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
|
||||
ENDIF(ENABLE_OPENMP)
|
||||
|
||||
|
||||
|
||||
SET(HEALPIX_BASE_PATH $ENV{HEALPIX})
|
||||
SET(HEALPIX_TARGET $ENV{HEALPIX_TARGET})
|
||||
SET(HEALPIX_PATH ${HEALPIX_BASE_PATH}/src/cxx/${HEALPIX_TARGET})
|
||||
SET(HEALPIX_HINT_INCLUDE ${HEALPIX_PATH}/include)
|
||||
SET(HEALPIX_HINT_LIB ${HEALPIX_PATH}/lib)
|
||||
|
||||
find_path(HEALPIX_INCLUDE_PATH NAMES healpix_map.h PATHS ${HEALPIX_HINT_INCLUDE})
|
||||
|
||||
find_library(HEALPIX_LIBRARY healpix_cxx PATHS ${HEALPIX_HINT_LIB})
|
||||
find_library(FFTPACK_LIBRARY fftpack PATHS ${HEALPIX_HINT_LIB})
|
||||
find_library(CFITSIO_LIBRARY cfitsio PATHS ${HEALPIX_HINT_LIB})
|
||||
find_library(CXXSUPPORT_LIBRARY cxxsupport PATHS ${HEALPIX_HINT_LIB})
|
||||
find_library(PSHT_LIBRARY psht PATHS ${HEALPIX_HINT_LIB})
|
||||
find_library(CUTILS_LIBRARY c_utils PATHS ${HEALPIX_HINT_LIB})
|
||||
|
||||
SET(HEALPIX_LIBRARIES
|
||||
${HEALPIX_LIBRARY} ${EXTRA_HEALPIX_LIBRARIES}
|
||||
${FFTPACK_LIBRARY} ${CXXSUPPORT_LIBRARY} ${CFITSIO_LIBRARY}
|
||||
)
|
56
pipeline_tools/contour_pixels.cpp
Normal file
56
pipeline_tools/contour_pixels.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include <vector>
|
||||
#include <healpix_map.h>
|
||||
#include <healpix_map_fitsio.h>
|
||||
#include "contour_pixels.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const bool DEBUG = true;
|
||||
|
||||
void computeFilledPixels(Healpix_Map<float>& m, vector<int>& filled)
|
||||
{
|
||||
filled.clear();
|
||||
for (int p = 0; p < m.Npix(); p++)
|
||||
if (m[p] > 0)
|
||||
filled.push_back(p);
|
||||
}
|
||||
|
||||
void computeContourPixels(Healpix_Map<float>& m, vector<int>& contour)
|
||||
{
|
||||
contour.clear();
|
||||
for (int p = 0; p < m.Npix(); p++)
|
||||
{
|
||||
fix_arr<int, 8> result;
|
||||
|
||||
m.neighbors(p, result);
|
||||
for (int q = 0; q < 8; q++)
|
||||
{
|
||||
if (result[q] < 0)
|
||||
continue;
|
||||
|
||||
float delta = (m[p]-0.5)*(m[result[q]]-0.5);
|
||||
if (delta < 0)
|
||||
{
|
||||
contour.push_back(p);
|
||||
// This is boundary go to next pixel
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG)
|
||||
{
|
||||
Healpix_Map<int> contour_map;
|
||||
|
||||
contour_map.SetNside(m.Nside(), RING);
|
||||
contour_map.fill(0);
|
||||
for (int p = 0; p < contour.size(); p++)
|
||||
{
|
||||
contour_map[contour[p]]=1;
|
||||
}
|
||||
|
||||
fitshandle h;
|
||||
h.create("!contour_map.fits");
|
||||
write_Healpix_map_to_fits(h, contour_map, planckType<int>());
|
||||
}
|
||||
}
|
11
pipeline_tools/contour_pixels.hpp
Normal file
11
pipeline_tools/contour_pixels.hpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef __CONTOUR_PIXELS_HPP
|
||||
#define __CONTOUR_PIXELS_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <healpix_map.h>
|
||||
|
||||
|
||||
void computeContourPixels(Healpix_Map<float>& map, std::vector<int>& contour);
|
||||
void computeFilledPixels(Healpix_Map<float>& map, std::vector<int>& contour);
|
||||
|
||||
#endif
|
365
pipeline_tools/generateFromCatalog.cpp
Normal file
365
pipeline_tools/generateFromCatalog.cpp
Normal file
|
@ -0,0 +1,365 @@
|
|||
#include <healpix_map.h>
|
||||
#include <healpix_map_fitsio.h>
|
||||
#include <boost/format.hpp>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "generateFromCatalog_conf.h"
|
||||
#include "contour_pixels.hpp"
|
||||
#include <netcdfcpp.h>
|
||||
#include <CosmoTool/fortran.hpp>
|
||||
|
||||
using namespace std;
|
||||
using boost::format;
|
||||
using namespace CosmoTool;
|
||||
|
||||
struct NYU_Data
|
||||
{
|
||||
int index;
|
||||
int sector;
|
||||
int region;
|
||||
double ra, dec;
|
||||
double cz;
|
||||
double fgotten;
|
||||
double phi_z;
|
||||
};
|
||||
|
||||
struct Position
|
||||
{
|
||||
double xyz[3];
|
||||
};
|
||||
|
||||
struct ParticleData
|
||||
{
|
||||
vector<int> id_gal;
|
||||
int id_mask;
|
||||
vector<Position> pos;
|
||||
double box[3][2];
|
||||
double Lmax;
|
||||
};
|
||||
|
||||
typedef vector<NYU_Data> NYU_VData;
|
||||
|
||||
void loadData(const string& fname, NYU_VData & data)
|
||||
{
|
||||
ifstream f(fname.c_str());
|
||||
|
||||
while (!f.eof())
|
||||
{
|
||||
NYU_Data d;
|
||||
f >> d.index >> d.sector >> d.region >> d.ra >> d.dec >> d.cz >> d.fgotten >> d.phi_z;
|
||||
data.push_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
void generateGalaxiesInCube(NYU_VData& data, ParticleData& output_data)
|
||||
{
|
||||
double d2r = M_PI/180;
|
||||
|
||||
output_data.pos.resize(data.size());
|
||||
output_data.id_gal.resize(data.size());
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
output_data.box[j][0] = -INFINITY;
|
||||
output_data.box[j][1] = INFINITY;
|
||||
}
|
||||
|
||||
for (int i = 0; i < data.size(); i++)
|
||||
{
|
||||
double ra = data[i].ra*d2r, dec = data[i].dec*d2r;
|
||||
Position& p = output_data.pos[i];
|
||||
|
||||
p.xyz[0] = data[i].cz*cos(ra)*cos(dec);
|
||||
p.xyz[1] = data[i].cz*sin(ra)*cos(dec);
|
||||
p.xyz[2] = data[i].cz*sin(dec);
|
||||
output_data.id_gal[i] = data[i].index;
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
if (p.xyz[j] > output_data.box[j][0])
|
||||
output_data.box[j][0] = p.xyz[j];
|
||||
if (p.xyz[j] < output_data.box[j][1])
|
||||
output_data.box[j][1] = p.xyz[j];
|
||||
}
|
||||
}
|
||||
cout << format("Galaxy position generated: %d galaxies") % output_data.pos.size() << endl;
|
||||
cout << format("box is %g < x < %g; %g < y < %g; %g < z < %g")
|
||||
% (1e-2*output_data.box[0][1]) % (1e-2*output_data.box[0][0])
|
||||
% (1e-2*output_data.box[1][1]) % (1e-2*output_data.box[1][0])
|
||||
% (1e-2*output_data.box[2][1]) % (1e-2*output_data.box[2][0]) << endl;
|
||||
|
||||
}
|
||||
|
||||
static double cube(double x)
|
||||
{
|
||||
return x*x*x;
|
||||
}
|
||||
|
||||
void generateBoxMask(generateFromCatalog_info& args ,
|
||||
Healpix_Map<float>& mask,
|
||||
vector<int>& pixel_list,
|
||||
NYU_VData& data,
|
||||
ParticleData& output_data)
|
||||
{
|
||||
int idx = -1;
|
||||
int insertion = 0;
|
||||
double volume = pixel_list.size()*1.0/mask.Npix()*4*M_PI;
|
||||
int numToInsert;
|
||||
|
||||
idx = output_data.id_mask;
|
||||
|
||||
cout << "Generate box mask..." << endl;
|
||||
|
||||
double Rmax = output_data.Lmax, t = args.box_thickness_arg;
|
||||
output_data.Lmax += args.box_thickness_arg;
|
||||
|
||||
|
||||
volume *= Rmax*Rmax/1e6 * args.box_thickness_arg;
|
||||
numToInsert = (int)floor(volume*args.box_density_arg);
|
||||
|
||||
for (int i = 0; i < numToInsert; i++)
|
||||
{
|
||||
Position p;
|
||||
bool stop_here;
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
int p0 = (int)floor(drand48()*pixel_list.size());
|
||||
vec3 v = mask.pix2vec(pixel_list[p0]);
|
||||
double r = Rmax*pow(drand48()*(cube(1+t/Rmax)-1) + 1,1./3);
|
||||
|
||||
p.xyz[0] = v.x * r;
|
||||
p.xyz[1] = v.y * r;
|
||||
p.xyz[2] = v.z * r;
|
||||
|
||||
stop_here = true;
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
if (p.xyz[j] > output_data.box[j][0] ||
|
||||
p.xyz[j] < output_data.box[j][1])
|
||||
stop_here = false;
|
||||
}
|
||||
}
|
||||
while (!stop_here);
|
||||
|
||||
output_data.pos.push_back(p);
|
||||
output_data.id_gal.push_back(idx);
|
||||
insertion++;
|
||||
}
|
||||
}
|
||||
|
||||
void generateSurfaceMask(generateFromCatalog_info& args ,
|
||||
Healpix_Map<float>& mask,
|
||||
vector<int>& pixel_list,
|
||||
NYU_VData& data,
|
||||
ParticleData& output_data)
|
||||
{
|
||||
// Find the first free index
|
||||
int idx = -1;
|
||||
int insertion = 0;
|
||||
double volume = pixel_list.size()*1.0/mask.Npix()*4*M_PI;
|
||||
int numToInsert;
|
||||
|
||||
for (int i = 0; i < output_data.id_gal.size(); i++)
|
||||
{
|
||||
if (idx < output_data.id_gal[i])
|
||||
idx = output_data.id_gal[i]+1;
|
||||
}
|
||||
|
||||
output_data.id_mask = idx;
|
||||
|
||||
cout << "Generate surface mask..." << endl;
|
||||
|
||||
double Rmax = -1;
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
Rmax = max(Rmax, max(output_data.box[j][0], -output_data.box[j][1]));
|
||||
}
|
||||
|
||||
output_data.Lmax = Rmax;
|
||||
|
||||
|
||||
cout << format("Rmax is %g, surface volume is %g") % (Rmax/100) % (volume/(4*M_PI)) << endl;
|
||||
volume *= Rmax*Rmax*Rmax/3/1e6;
|
||||
numToInsert = (int)floor(volume*args.density_fake_arg);
|
||||
cout << format("3d volume to fill: %g (Mpc/h)^3") % volume << endl;
|
||||
|
||||
cout << format("Will insert %d particles") % numToInsert << endl;
|
||||
|
||||
double pct = 0;
|
||||
for (int i = 0; i < numToInsert; i++)
|
||||
{
|
||||
double new_pct = i*100./numToInsert;
|
||||
|
||||
if (new_pct-pct > 5.)
|
||||
{
|
||||
pct = new_pct;
|
||||
cout << format(" .. %3.0f %%") % pct << endl;
|
||||
}
|
||||
|
||||
Position p;
|
||||
bool stop_here;
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
int p0 = (int)floor(drand48()*pixel_list.size());
|
||||
vec3 v = mask.pix2vec(pixel_list[p0]);
|
||||
double r = Rmax*pow(drand48(),1./3);
|
||||
|
||||
p.xyz[0] = v.x * r;
|
||||
p.xyz[1] = v.y * r;
|
||||
p.xyz[2] = v.z * r;
|
||||
|
||||
stop_here = true;
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
if (p.xyz[j] > output_data.box[j][0] ||
|
||||
p.xyz[j] < output_data.box[j][1])
|
||||
stop_here = false;
|
||||
}
|
||||
}
|
||||
while (!stop_here);
|
||||
|
||||
output_data.pos.push_back(p);
|
||||
output_data.id_gal.push_back(idx);
|
||||
insertion++;
|
||||
}
|
||||
cout << format("Done. Inserted %d particles.") % insertion << endl;
|
||||
}
|
||||
|
||||
void saveData(ParticleData& pdata)
|
||||
{
|
||||
NcFile f("particles.nc", NcFile::Replace);
|
||||
|
||||
assert(f.is_valid());
|
||||
|
||||
NcDim *d = f.add_dim("space", 3);
|
||||
NcDim *p = f.add_dim("Np", pdata.pos.size());
|
||||
NcVar *v = f.add_var("particles", ncDouble, d, p);
|
||||
double *x = new double[pdata.pos.size()];
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
|
||||
for (int i = 0; i < pdata.pos.size(); i++)
|
||||
x[i] = pdata.pos[i].xyz[j];
|
||||
|
||||
v->put_rec(d, x, j);
|
||||
}
|
||||
|
||||
v = f.add_var("id_gal", ncInt, p);
|
||||
v->put(&pdata.id_gal[0], pdata.id_gal.size());
|
||||
|
||||
delete[] x;
|
||||
|
||||
}
|
||||
|
||||
void saveForZobov(ParticleData& pdata, const string& fname, const string& paramname)
|
||||
{
|
||||
UnformattedWrite f(fname);
|
||||
static const char axis[] = { 'X', 'Y', 'Z' };
|
||||
double Lmax = pdata.Lmax;
|
||||
|
||||
f.beginCheckpoint();
|
||||
f.writeInt32(pdata.pos.size());
|
||||
f.endCheckpoint();
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
cout << format("Writing %c components...") % axis[j] << endl;
|
||||
f.beginCheckpoint();
|
||||
for (uint32_t i = 0; i < pdata.pos.size(); i++)
|
||||
{
|
||||
f.writeReal32((pdata.pos[i].xyz[j]+Lmax)/(2*Lmax));
|
||||
}
|
||||
f.endCheckpoint();
|
||||
}
|
||||
|
||||
NcFile fp(paramname.c_str(), NcFile::Replace);
|
||||
|
||||
fp.add_att("range_x_min", -Lmax);
|
||||
fp.add_att("range_x_max", Lmax);
|
||||
fp.add_att("range_y_min", -Lmax);
|
||||
fp.add_att("range_y_max", Lmax);
|
||||
fp.add_att("range_z_min", -Lmax);
|
||||
fp.add_att("range_z_max", Lmax);
|
||||
|
||||
NcDim *NumPart_dim = fp.add_dim("numpart_dim", pdata.pos.size());
|
||||
NcVar *v = fp.add_var("particle_ids", ncInt, NumPart_dim);
|
||||
NcVar *v2 = fp.add_var("expansion", ncDouble, NumPart_dim);
|
||||
|
||||
double *expansion_fac = new double[pdata.pos.size()];
|
||||
|
||||
for (int i = 0; i < pdata.pos.size(); i++)
|
||||
expansion_fac[i] = 1.0;
|
||||
|
||||
v->put(&pdata.id_gal[0], pdata.id_gal.size());
|
||||
v2->put(expansion_fac, pdata.pos.size());
|
||||
|
||||
delete[] expansion_fac;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
generateFromCatalog_info args_info;
|
||||
generateFromCatalog_conf_params args_params;
|
||||
|
||||
generateFromCatalog_conf_init(&args_info);
|
||||
generateFromCatalog_conf_params_init(&args_params);
|
||||
|
||||
args_params.check_required = 0;
|
||||
if (generateFromCatalog_conf_ext (argc, argv, &args_info, &args_params))
|
||||
return 1;
|
||||
|
||||
if (!args_info.configFile_given)
|
||||
{
|
||||
if (generateFromCatalog_conf_required (&args_info, GENERATEFROMCATALOG_CONF_PACKAGE))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
args_params.check_required = 1;
|
||||
args_params.initialize = 0;
|
||||
if (generateFromCatalog_conf_config_file (args_info.configFile_arg,
|
||||
&args_info,
|
||||
&args_params))
|
||||
return 1;
|
||||
}
|
||||
|
||||
generateFromCatalog_conf_print_version();
|
||||
|
||||
cout << "Loading NYU data..." << endl;
|
||||
vector<NYU_Data> data;
|
||||
Healpix_Map<float> o_mask;
|
||||
vector<int> pixel_list;
|
||||
ParticleData output_data;
|
||||
|
||||
loadData(args_info.catalog_arg, data);
|
||||
|
||||
|
||||
cout << "Loading mask..." << endl;
|
||||
read_Healpix_map_from_fits(args_info.mask_arg, o_mask);
|
||||
|
||||
Healpix_Map<float> mask;
|
||||
|
||||
mask.SetNside(128, RING);
|
||||
mask.Import(o_mask);
|
||||
|
||||
computeContourPixels(mask,pixel_list);
|
||||
|
||||
// We compute a cube holding all the galaxies + the survey surface mask
|
||||
|
||||
generateGalaxiesInCube(data, output_data);
|
||||
generateSurfaceMask(args_info, mask, pixel_list, data, output_data);
|
||||
computeFilledPixels(mask,pixel_list);
|
||||
generateBoxMask(args_info, mask, pixel_list, data, output_data);
|
||||
|
||||
saveForZobov(output_data, args_info.output_arg, args_info.params_arg);
|
||||
// saveData(output_data);
|
||||
|
||||
return 0;
|
||||
}
|
14
pipeline_tools/generateFromCatalog.ggo
Normal file
14
pipeline_tools/generateFromCatalog.ggo
Normal file
|
@ -0,0 +1,14 @@
|
|||
package "generateFromCatalog"
|
||||
version "alpha"
|
||||
|
||||
option "configFile" - "Configuration filename" string optional
|
||||
|
||||
option "catalog" - "Input NYU-VAGC catalog" string required
|
||||
option "mask" - "Healpix mask of unobserved data (in Equatorial coordinates)" string required
|
||||
option "density_fake" - "Number density of boundary fake tracers (1 h^3/ Mpc^3)" double optional default="1"
|
||||
|
||||
option "output" - "Filename of particle datafile" string required
|
||||
option "params" - "Output parameters of the datacube" string required
|
||||
|
||||
option "box_thickness" - "Thickness of the limiting mask" double optional default="1"
|
||||
option "box_density" - "Fake Galaxy density on the box" double optional default="1"
|
568
pipeline_tools/generateMock.cpp
Normal file
568
pipeline_tools/generateMock.cpp
Normal file
|
@ -0,0 +1,568 @@
|
|||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <CosmoTool/loadSimu.hpp>
|
||||
#include <CosmoTool/loadRamses.hpp>
|
||||
#include <CosmoTool/loadGadget.hpp>
|
||||
#include <CosmoTool/loadFlash.hpp>
|
||||
#include <CosmoTool/interpolate.hpp>
|
||||
#include <CosmoTool/fortran.hpp>
|
||||
#include "generateMock_conf.h"
|
||||
#include "gslIntegrate.hpp"
|
||||
#include <netcdfcpp.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace CosmoTool;
|
||||
|
||||
#define LIGHT_SPEED 299792.458
|
||||
|
||||
static double gadgetUnit=1e-3;
|
||||
|
||||
SimuData *doLoadRamses(const char *basename, int baseid, int velAxis, bool goRedshift)
|
||||
{
|
||||
SimuData *d, *outd;
|
||||
|
||||
d = loadRamsesSimu(basename, baseid, -1, true, 0);
|
||||
outd = new SimuData;
|
||||
|
||||
outd->NumPart = d->TotalNumPart;
|
||||
outd->BoxSize = d->BoxSize;
|
||||
outd->TotalNumPart = outd->NumPart;
|
||||
outd->Hubble = d->Hubble;
|
||||
outd->Omega_Lambda = d->Omega_Lambda;
|
||||
outd->Omega_M = d->Omega_M;
|
||||
outd->time = d->time;
|
||||
|
||||
for (int k = 0; k < 3; k++)
|
||||
outd->Pos[k] = new float[outd->NumPart];
|
||||
outd->Vel[2] = new float[outd->NumPart];
|
||||
delete d;
|
||||
|
||||
int curCpu = 0;
|
||||
cout << "loading cpu 0 " << endl;
|
||||
while (d = loadRamsesSimu(basename, baseid, curCpu, true, NEED_POSITION|NEED_VELOCITY|NEED_GADGET_ID))
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
for (int i = 0; i < d->NumPart; i++)
|
||||
{
|
||||
assert(d->Id[i] >= 1);
|
||||
assert(d->Id[i] <= outd->TotalNumPart);
|
||||
outd->Pos[k][d->Id[i]-1] = d->Pos[k][i];
|
||||
outd->Vel[2][d->Id[i]-1] = d->Vel[velAxis][i];
|
||||
}
|
||||
|
||||
if (goRedshift)
|
||||
for (int i = 0; i < d->NumPart; i++)
|
||||
outd->Pos[velAxis][d->Id[i]-1] += d->Vel[velAxis][i]/100.;
|
||||
|
||||
delete d;
|
||||
curCpu++;
|
||||
cout << "loading cpu " << curCpu << endl;
|
||||
}
|
||||
|
||||
return outd;
|
||||
}
|
||||
|
||||
SimuData *myLoadGadget(const char *fname, int id, int flags)
|
||||
{
|
||||
SimuData *sim = loadGadgetMulti(fname, id, flags);
|
||||
sim->BoxSize *= gadgetUnit*1000;
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
if (sim->Pos[j] != 0) {
|
||||
for (long i = 0; i < sim->NumPart; i++)
|
||||
sim->Pos[j][i] *= gadgetUnit*1000;
|
||||
}
|
||||
}
|
||||
return sim;
|
||||
}
|
||||
|
||||
SimuData *doLoadSimulation(const char *gadgetname, int velAxis, bool goRedshift, SimuData *(*loadFunction)(const char *fname, int id, int flags))
|
||||
{
|
||||
SimuData *d, *outd;
|
||||
bool singleFile = false;
|
||||
|
||||
try
|
||||
{
|
||||
d = loadFunction(gadgetname, -1, 0);
|
||||
singleFile = true;
|
||||
}
|
||||
catch (const NoSuchFileException& e)
|
||||
{
|
||||
try
|
||||
{
|
||||
d = loadFunction(gadgetname, 0, 0);
|
||||
}
|
||||
catch(const NoSuchFileException& e)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
outd = new SimuData;
|
||||
|
||||
outd->NumPart = d->TotalNumPart;
|
||||
outd->BoxSize = d->BoxSize/1000;
|
||||
outd->TotalNumPart = outd->NumPart;
|
||||
outd->Hubble = d->Hubble;
|
||||
outd->Omega_Lambda = d->Omega_Lambda;
|
||||
outd->Omega_M = d->Omega_M;
|
||||
outd->time = d->time;
|
||||
|
||||
for (int k = 0; k < 3; k++)
|
||||
outd->Pos[k] = new float[outd->NumPart];
|
||||
outd->Vel[2] = new float[outd->NumPart];
|
||||
delete d;
|
||||
|
||||
int curCpu = singleFile ? -1 : 0;
|
||||
cout << "loading file 0 " << endl;
|
||||
try
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
d = loadFunction(gadgetname, curCpu, NEED_POSITION|NEED_VELOCITY|NEED_GADGET_ID);
|
||||
for (int k = 0; k < 3; k++)
|
||||
for (int i = 0; i < d->NumPart; i++)
|
||||
{
|
||||
assert(d->Id[i] >= 1);
|
||||
assert(d->Id[i] <= outd->TotalNumPart);
|
||||
outd->Pos[k][d->Id[i]-1] = d->Pos[k][i]/1000;
|
||||
outd->Vel[2][d->Id[i]-1] = d->Vel[velAxis][i];
|
||||
}
|
||||
|
||||
if (goRedshift)
|
||||
for (int i = 0; i < d->NumPart; i++)
|
||||
outd->Pos[velAxis][d->Id[i]-1] += d->Vel[velAxis][i]/100.;
|
||||
|
||||
delete d;
|
||||
if (singleFile)
|
||||
break;
|
||||
curCpu++;
|
||||
cout << "loading file " << curCpu << endl;
|
||||
}
|
||||
}
|
||||
catch (const NoSuchFileException& e)
|
||||
{
|
||||
}
|
||||
|
||||
return outd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static double cubic(double a)
|
||||
{
|
||||
return a*a*a;
|
||||
}
|
||||
|
||||
struct TotalExpansion
|
||||
{
|
||||
double Omega_M, Omega_L;
|
||||
|
||||
double operator()(double z)
|
||||
{
|
||||
return 1/sqrt(Omega_M*cubic(1+z) + Omega_L);
|
||||
}
|
||||
};
|
||||
|
||||
Interpolate make_cosmological_redshift(double OM, double OL, double z0, double z1, int N = 1000)
|
||||
{
|
||||
TotalExpansion e_computer;
|
||||
double D_tilde, Q, Qprime;
|
||||
InterpolatePairs pairs;
|
||||
|
||||
e_computer.Omega_M = OM;
|
||||
e_computer.Omega_L = OL;
|
||||
|
||||
pairs.resize(N);
|
||||
ofstream f("comoving_distance.txt");
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
double z = z0 + (z1-z0)/N*i;
|
||||
|
||||
pairs[i].second = z;
|
||||
pairs[i].first = gslIntegrate(e_computer, 0, z, 1e-3);
|
||||
f << z << " " << pairs[i].first << endl;
|
||||
}
|
||||
|
||||
return buildFromVector(pairs);
|
||||
}
|
||||
|
||||
void metricTransform(SimuData *data, int axis, bool reshift, bool pecvel, double*& expfact, bool cosmo_flag)
|
||||
{
|
||||
int x0, x1, x2;
|
||||
|
||||
switch (axis) {
|
||||
case 0:
|
||||
x0 = 1; x1 = 2; x2 = 0;
|
||||
break;
|
||||
case 1:
|
||||
x0 = 0; x1 = 2; x2 = 1;
|
||||
break;
|
||||
case 2:
|
||||
x0 = 0; x1 = 1; x2 = 2;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
double z0 = 1/data->time - 1;
|
||||
Interpolate z_vs_D = make_cosmological_redshift(data->Omega_M, data->Omega_Lambda, 0., z0+2*data->BoxSize*100/LIGHT_SPEED); // Redshift 2*z0 should be sufficient ?
|
||||
double z_base = reshift ? z0 : 0;
|
||||
TotalExpansion e_computer;
|
||||
double baseComovingDistance;
|
||||
float vmax = 0;
|
||||
|
||||
expfact = new double[data->NumPart];
|
||||
|
||||
cout << "Using base redshift z=" << z0 << endl;
|
||||
|
||||
e_computer.Omega_M = data->Omega_M;
|
||||
e_computer.Omega_L = data->Omega_Lambda;
|
||||
baseComovingDistance = LIGHT_SPEED/100.* gslIntegrate(e_computer, 0, z0, 1e-3);
|
||||
cout << "Comoving distance = " << baseComovingDistance << " Mpc/h" << endl;
|
||||
|
||||
cout << "Add peculiar velocities ? -> " << (pecvel ? " yes " : " no ") << endl;
|
||||
|
||||
for (uint32_t i = 0; i < data->NumPart; i++)
|
||||
{
|
||||
float& x = data->Pos[x0][i];
|
||||
float& y = data->Pos[x1][i];
|
||||
float& z = data->Pos[x2][i];
|
||||
float& v = data->Vel[2][i];
|
||||
float z_old = z;
|
||||
|
||||
double reduced_red = (z + baseComovingDistance)*100./LIGHT_SPEED;
|
||||
try
|
||||
{
|
||||
|
||||
// Distorted redshift
|
||||
if (reduced_red == 0)
|
||||
z = 0;
|
||||
else if (cosmo_flag)
|
||||
z = (z_vs_D.compute(reduced_red)-z_base)*LIGHT_SPEED/100.;
|
||||
else
|
||||
z = reduced_red*LIGHT_SPEED/100.0;
|
||||
|
||||
expfact[i] = z / z_old;
|
||||
// Add peculiar velocity
|
||||
if (pecvel) {
|
||||
vmax = std::max(v,vmax);
|
||||
z += v/100;
|
||||
}
|
||||
}
|
||||
catch(const InvalidRangeException& e) {
|
||||
cout << "Trying to interpolate out of the tabulated range." << endl;
|
||||
cout << "The offending value is z=" << reduced_red << endl;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
cout << "vmax=" << vmax << endl;
|
||||
}
|
||||
|
||||
void generateOutput(SimuData *data, int axis,
|
||||
const std::string& fname)
|
||||
{
|
||||
UnformattedWrite f(fname);
|
||||
|
||||
cout << "Generating output particles to " << fname << endl;
|
||||
|
||||
int x0, x1, x2;
|
||||
|
||||
switch (axis) {
|
||||
case 0:
|
||||
x0 = 1; x1 = 2; x2 = 0;
|
||||
break;
|
||||
case 1:
|
||||
x0 = 0; x1 = 2; x2 = 1;
|
||||
break;
|
||||
case 2:
|
||||
x0 = 0; x1 = 1; x2 = 2;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
f.beginCheckpoint();
|
||||
f.writeInt32(data->NumPart);
|
||||
f.endCheckpoint();
|
||||
|
||||
cout << "Writing X components..." << endl;
|
||||
f.beginCheckpoint();
|
||||
for (uint32_t i = 0; i < data->NumPart; i++)
|
||||
{
|
||||
f.writeReal32(data->Pos[x0][i]);
|
||||
}
|
||||
f.endCheckpoint();
|
||||
|
||||
cout << "Writing Y components..." << endl;
|
||||
f.beginCheckpoint();
|
||||
for (uint32_t i = 0; i < data->NumPart; i++)
|
||||
{
|
||||
f.writeReal32(data->Pos[x1][i]);
|
||||
}
|
||||
f.endCheckpoint();
|
||||
|
||||
cout << "Writing Z components..." << endl;
|
||||
f.beginCheckpoint();
|
||||
for (uint32_t i = 0; i < data->NumPart; i++)
|
||||
{
|
||||
f.writeReal32(data->Pos[x2][i]);
|
||||
}
|
||||
f.endCheckpoint();
|
||||
}
|
||||
|
||||
void makeBoxFromParameter(SimuData *simu, double *efac, SimuData* &boxed, generateMock_info& args_info)
|
||||
{
|
||||
NcFile f(args_info.inputParameter_arg);
|
||||
NcVar *v;
|
||||
int *particle_id;
|
||||
double *expansion_fac;
|
||||
|
||||
boxed = new SimuData;
|
||||
boxed->Hubble = simu->Hubble;
|
||||
boxed->Omega_M = simu->Omega_M;
|
||||
boxed->Omega_Lambda = simu->Omega_Lambda;
|
||||
boxed->time = simu->time;
|
||||
boxed->BoxSize = simu->BoxSize;
|
||||
|
||||
NcVar *v_id = f.get_var("particle_ids");
|
||||
long *edges1;
|
||||
double ranges[3][2];
|
||||
double mul[3];
|
||||
|
||||
edges1 = v_id->edges();
|
||||
assert(v_id->num_dims()==1);
|
||||
|
||||
boxed->NumPart = edges1[0];
|
||||
delete[] edges1;
|
||||
|
||||
particle_id = new int[boxed->NumPart];
|
||||
|
||||
v_id->get(particle_id, boxed->NumPart);
|
||||
|
||||
ranges[0][0] = f.get_att("range_x_min")->as_double(0);
|
||||
ranges[0][1] = f.get_att("range_x_max")->as_double(0);
|
||||
ranges[1][0] = f.get_att("range_y_min")->as_double(0);
|
||||
ranges[1][1] = f.get_att("range_y_max")->as_double(0);
|
||||
ranges[2][0] = f.get_att("range_z_min")->as_double(0);
|
||||
ranges[2][1] = f.get_att("range_z_max")->as_double(0);
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
boxed->Pos[j] = new float[boxed->NumPart];
|
||||
boxed->Vel[j] = 0;
|
||||
mul[j] = 1.0/(ranges[j][1] - ranges[j][0]);
|
||||
}
|
||||
|
||||
uint32_t k = 0;
|
||||
for (uint32_t i = 0; i < boxed->NumPart; i++)
|
||||
{
|
||||
int id = particle_id[i];
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
boxed->Pos[j][i] = (simu->Pos[j][id]-ranges[j][0])*mul[j];
|
||||
}
|
||||
}
|
||||
|
||||
delete[] particle_id;
|
||||
}
|
||||
|
||||
void makeBox(SimuData *simu, double *efac, SimuData *&boxed, generateMock_info& args_info)
|
||||
{
|
||||
float subsample = args_info.subsample_given ? args_info.subsample_arg : 1.0;
|
||||
uint32_t goodParticles = 0;
|
||||
double ranges[3][2] = {
|
||||
{ args_info.rangeX_min_arg, args_info.rangeX_max_arg },
|
||||
{ args_info.rangeY_min_arg, args_info.rangeY_max_arg },
|
||||
{ args_info.rangeZ_min_arg, args_info.rangeZ_max_arg }
|
||||
};
|
||||
double mul[3];
|
||||
float minmax[2][3];
|
||||
int *particle_id;
|
||||
bool *random_acceptance = 0;
|
||||
|
||||
boxed = new SimuData;
|
||||
boxed->Hubble = simu->Hubble;
|
||||
boxed->Omega_M = simu->Omega_M;
|
||||
boxed->Omega_Lambda = simu->Omega_Lambda;
|
||||
boxed->time = simu->time;
|
||||
boxed->BoxSize = simu->BoxSize;
|
||||
|
||||
random_acceptance = new bool[simu->NumPart];
|
||||
|
||||
for (int j = 0; j < 3; j++) minmax[1][j] = minmax[0][j] = simu->Pos[j][0];
|
||||
|
||||
for (uint32_t i = 0; i < simu->NumPart; i++)
|
||||
{
|
||||
bool acceptance = true;
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
acceptance =
|
||||
acceptance &&
|
||||
(simu->Pos[j][i] > ranges[j][0]) &&
|
||||
(simu->Pos[j][i] < ranges[j][1]);
|
||||
minmax[0][j] = min(simu->Pos[j][i], minmax[0][j]);
|
||||
minmax[1][j] = max(simu->Pos[j][i], minmax[1][j]);
|
||||
}
|
||||
|
||||
random_acceptance[i] = acceptance && (drand48() <= subsample);
|
||||
if (random_acceptance[i])
|
||||
goodParticles++;
|
||||
}
|
||||
|
||||
cout << "Min position = " << minmax[0][0] << " " << minmax[0][1] << " " << minmax[0][2] << endl;
|
||||
cout << "Max position = " << minmax[1][0] << " " << minmax[1][1] << " " << minmax[1][2] << endl;
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
boxed->Pos[j] = new float[goodParticles];
|
||||
boxed->Vel[j] = 0;
|
||||
mul[j] = 1.0/(ranges[j][1] - ranges[j][0]);
|
||||
}
|
||||
|
||||
boxed->NumPart = goodParticles;
|
||||
|
||||
particle_id = new int[goodParticles];
|
||||
double *expansion_fac = new double[goodParticles];
|
||||
|
||||
uint32_t k = 0;
|
||||
for (uint32_t i = 0; i < simu->NumPart; i++)
|
||||
{
|
||||
bool acceptance = random_acceptance[i];
|
||||
|
||||
if (acceptance)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
boxed->Pos[j][k] = (simu->Pos[j][i]-ranges[j][0])*mul[j];
|
||||
assert(boxed->Pos[j][k] > 0);
|
||||
assert(boxed->Pos[j][k] < 1);
|
||||
}
|
||||
particle_id[k] = i;
|
||||
expansion_fac[k] = efac[i];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] random_acceptance;
|
||||
|
||||
NcFile f(args_info.outputParameter_arg, NcFile::Replace);
|
||||
|
||||
f.add_att("range_x_min", ranges[0][0]);
|
||||
f.add_att("range_x_max", ranges[0][1]);
|
||||
f.add_att("range_y_min", ranges[1][0]);
|
||||
f.add_att("range_y_max", ranges[1][1]);
|
||||
f.add_att("range_z_min", ranges[2][0]);
|
||||
f.add_att("range_z_max", ranges[2][1]);
|
||||
|
||||
NcDim *NumPart_dim = f.add_dim("numpart_dim", boxed->NumPart);
|
||||
NcVar *v = f.add_var("particle_ids", ncInt, NumPart_dim);
|
||||
NcVar *v2 = f.add_var("expansion", ncDouble, NumPart_dim);
|
||||
|
||||
v->put(particle_id, boxed->NumPart);
|
||||
v2->put(expansion_fac, boxed->NumPart);
|
||||
|
||||
delete[] particle_id;
|
||||
delete[] expansion_fac;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
generateMock_info args_info;
|
||||
generateMock_conf_params args_params;
|
||||
SimuData *simu, *simuOut;
|
||||
|
||||
generateMock_conf_init(&args_info);
|
||||
generateMock_conf_params_init(&args_params);
|
||||
|
||||
args_params.check_required = 0;
|
||||
if (generateMock_conf_ext (argc, argv, &args_info, &args_params))
|
||||
return 1;
|
||||
|
||||
if (!args_info.configFile_given)
|
||||
{
|
||||
if (generateMock_conf_required (&args_info, GENERATEMOCK_CONF_PACKAGE))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
args_params.check_required = 1;
|
||||
args_params.initialize = 0;
|
||||
if (generateMock_conf_config_file (args_info.configFile_arg,
|
||||
&args_info,
|
||||
&args_params))
|
||||
return 1;
|
||||
}
|
||||
|
||||
generateMock_conf_print_version();
|
||||
|
||||
gadgetUnit=args_info.gadgetUnit_arg;
|
||||
|
||||
if (args_info.ramsesBase_given || args_info.ramsesId_given)
|
||||
{
|
||||
if (args_info.ramsesBase_given && args_info.ramsesId_given)
|
||||
simu = doLoadRamses(args_info.ramsesBase_arg,
|
||||
args_info.ramsesId_arg,
|
||||
args_info.axis_arg, false);
|
||||
else
|
||||
{
|
||||
cerr << "Both ramsesBase and ramsesId are required to be able to load snapshots" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (simu == 0)
|
||||
{
|
||||
cerr << "Error while loading" << endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (args_info.gadget_given || args_info.flash_given)
|
||||
{
|
||||
if (args_info.gadget_given && args_info.flash_given)
|
||||
{
|
||||
cerr << "Do not know which file to use: Gadget or Flash ?" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (args_info.gadget_given)
|
||||
simu = doLoadSimulation(args_info.gadget_arg, args_info.axis_arg, false, myLoadGadget);
|
||||
else
|
||||
simu = doLoadSimulation(args_info.flash_arg, args_info.axis_arg, false, loadFlashMulti);
|
||||
if (simu == 0)
|
||||
{
|
||||
cerr << "Error while loading " << endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Either a ramses snapshot or a gadget snapshot is required." << endl;
|
||||
return 1;
|
||||
}
|
||||
cout << "Hubble = " << simu->Hubble << endl;
|
||||
cout << "Boxsize = " << simu->BoxSize << endl;
|
||||
cout << "Omega_M = " << simu->Omega_M << endl;
|
||||
cout << "Omega_Lambda = " << simu->Omega_Lambda << endl;
|
||||
|
||||
double *expfact;
|
||||
|
||||
metricTransform(simu, args_info.axis_arg, args_info.preReShift_flag, args_info.peculiarVelocities_flag, expfact, args_info.cosmo_flag);
|
||||
|
||||
if (args_info.inputParameter_given)
|
||||
makeBoxFromParameter(simu, expfact, simuOut, args_info);
|
||||
else
|
||||
makeBox(simu, expfact, simuOut, args_info);
|
||||
|
||||
delete simu;
|
||||
|
||||
generateOutput(simuOut, args_info.axis_arg, args_info.output_arg);
|
||||
|
||||
delete simuOut;
|
||||
|
||||
return 0;
|
||||
}
|
33
pipeline_tools/generateMock.ggo
Normal file
33
pipeline_tools/generateMock.ggo
Normal file
|
@ -0,0 +1,33 @@
|
|||
package "generateMock"
|
||||
version "0"
|
||||
|
||||
option "configFile" - "Configuration file path" string optional
|
||||
|
||||
# Ramses data
|
||||
option "ramsesBase" - "Base directory for ramses" string optional
|
||||
option "ramsesId" - "Ramses snapshot id" int optional
|
||||
|
||||
option "gadget" - "Base name of gadget snapshot (without parallel writing extension)" string optional
|
||||
option "flash" - "Base name for FLASH snapshot" string optional
|
||||
|
||||
option "axis" - "Redshift axis (X=0, Y=1, Z=2)" int optional default="2"
|
||||
|
||||
option "output" - "Output filename for particles" string required
|
||||
option "outputParameter" - "Output geometry parameter file for postprocessing" string required
|
||||
|
||||
option "rangeX_min" - "Minimum range in X for making the box" double required
|
||||
option "rangeX_max" - "Maximum range in X for making the box" double required
|
||||
option "rangeY_min" - "Minimum range in Y for making the box" double required
|
||||
option "rangeY_max" - "Maximum range in Y for making the box" double required
|
||||
option "rangeZ_min" - "Minimum range in Z for making the box (after distortion)" double required
|
||||
option "rangeZ_max" - "Maximum range in Z for making the box (after distortion)" double required
|
||||
|
||||
option "preReShift" - "Reshift the zero of the Z axis" flag off
|
||||
option "peculiarVelocities" - "Added peculiar velocities distortion" flag off
|
||||
|
||||
option "cosmo" - "Apply cosmological redshift" flag on
|
||||
|
||||
option "subsample" - "Subsample the input simulation by the specified amount" double optional
|
||||
|
||||
option "inputParameter" - "Input geometry (optional, warning!)" string optional
|
||||
option "gadgetUnit" - "Unit of length in gadget file in Mpc/h" double optional default="0.001"
|
47
pipeline_tools/generateTestMock.cpp
Normal file
47
pipeline_tools/generateTestMock.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <CosmoTool/fortran.hpp>
|
||||
|
||||
using namespace CosmoTool;
|
||||
using namespace std;
|
||||
|
||||
#define LX 1.0
|
||||
#define LY 1.0
|
||||
#define LZ 1.0
|
||||
|
||||
#define NUMPART (16*16*16)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
UnformattedWrite f("particles.bin");
|
||||
|
||||
f.beginCheckpoint();
|
||||
f.writeInt32(NUMPART);
|
||||
f.endCheckpoint();
|
||||
|
||||
cout << "Writing X components..." << endl;
|
||||
f.beginCheckpoint();
|
||||
for (uint32_t i = 0; i < NUMPART; i++)
|
||||
{
|
||||
f.writeReal32(drand48()*LX);
|
||||
}
|
||||
f.endCheckpoint();
|
||||
|
||||
cout << "Writing Y components..." << endl;
|
||||
f.beginCheckpoint();
|
||||
for (uint32_t i = 0; i < NUMPART; i++)
|
||||
{
|
||||
f.writeReal32(drand48()*LY);
|
||||
}
|
||||
f.endCheckpoint();
|
||||
|
||||
cout << "Writing Z components..." << endl;
|
||||
f.beginCheckpoint();
|
||||
for (uint32_t i = 0; i < NUMPART; i++)
|
||||
{
|
||||
f.writeReal32(drand48()*LZ);
|
||||
}
|
||||
f.endCheckpoint();
|
||||
|
||||
return 0;
|
||||
}
|
33
pipeline_tools/gslIntegrate.hpp
Normal file
33
pipeline_tools/gslIntegrate.hpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef __MYGSL_INTEGRATE_HPP
|
||||
#define __MYGSL_INTEGRATE_HPP
|
||||
|
||||
#include <gsl/gsl_integration.h>
|
||||
|
||||
template<typename FunT>
|
||||
double gslSpecialFunction(double x, void *param)
|
||||
{
|
||||
FunT *f = (FunT *)param;
|
||||
|
||||
return (*f)(x);
|
||||
}
|
||||
|
||||
template<typename FunT>
|
||||
double gslIntegrate(FunT& v, double a, double b, double prec, int NPTS = 1024)
|
||||
{
|
||||
gsl_integration_workspace *w = gsl_integration_workspace_alloc(NPTS);
|
||||
gsl_function f;
|
||||
double result;
|
||||
double abserr;
|
||||
|
||||
f.function = &gslSpecialFunction<FunT>;
|
||||
f.params = &v;
|
||||
|
||||
gsl_integration_qag(&f, a, b, prec, 0, NPTS, GSL_INTEG_GAUSS61,
|
||||
w, &result, &abserr);
|
||||
|
||||
gsl_integration_workspace_free(w);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
210
pipeline_tools/loadZobov.cpp
Normal file
210
pipeline_tools/loadZobov.cpp
Normal file
|
@ -0,0 +1,210 @@
|
|||
#include <string>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include "loadZobov.hpp"
|
||||
#include <CosmoTool/fortran.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace CosmoTool;
|
||||
|
||||
bool loadZobov(const char *descName, const char *adjName, const char *voidsName,
|
||||
const char *volName, ZobovRep& z)
|
||||
{
|
||||
ifstream descFile(descName);
|
||||
ifstream adjFile(adjName);
|
||||
ifstream volFile(voidsName);
|
||||
int32_t numParticles, numZones, numPinZone;
|
||||
int32_t totalParticles;
|
||||
int32_t numVoids;
|
||||
int32_t minParticlesInZone, maxParticlesInZone;
|
||||
|
||||
adjFile.read((char *)&numParticles, sizeof(numParticles));
|
||||
adjFile.read((char *)&numZones, sizeof(numZones));
|
||||
if (!adjFile)
|
||||
return false;
|
||||
|
||||
cout << "Number of particles = " << numParticles << endl;
|
||||
cout << "Number of zones = " << numZones << endl;
|
||||
|
||||
totalParticles = 0;
|
||||
|
||||
minParticlesInZone = -1;
|
||||
maxParticlesInZone = -1;
|
||||
|
||||
z.allZones.resize(numZones);
|
||||
for (int zone = 0; zone < numZones; zone++)
|
||||
{
|
||||
adjFile.read((char *)&numPinZone, sizeof(numPinZone));
|
||||
if (!adjFile)
|
||||
{
|
||||
cout << "Problem on the zone " << zone << " / " << numZones << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
z.allZones[zone].pId.resize(numPinZone);
|
||||
adjFile.read((char *)&z.allZones[zone].pId[0], sizeof(int)*numPinZone);
|
||||
|
||||
if (maxParticlesInZone < 0 || numPinZone > maxParticlesInZone)
|
||||
maxParticlesInZone = numPinZone;
|
||||
|
||||
if (minParticlesInZone < 0 || numPinZone < minParticlesInZone)
|
||||
minParticlesInZone = numPinZone;
|
||||
|
||||
totalParticles += numPinZone;
|
||||
}
|
||||
cout << "Zoned " << totalParticles << endl;
|
||||
|
||||
cout << "Minimum number of particles in zone = " << minParticlesInZone << endl;
|
||||
cout << "Maximum number of particles in zone = " << maxParticlesInZone << endl;
|
||||
|
||||
if (totalParticles != numParticles)
|
||||
{
|
||||
cerr << "The numbers of particles are inconsistent ! (" << totalParticles << " vs " << numParticles << ")"<< endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
volFile.read((char *)&numVoids, sizeof(numVoids));
|
||||
if (!volFile)
|
||||
return false;
|
||||
|
||||
cout << "Number of voids = " << numVoids << endl;
|
||||
|
||||
z.allVoids.resize(numVoids);
|
||||
for (int v = 0; v < numVoids; v++)
|
||||
{
|
||||
int32_t numZinV;
|
||||
|
||||
volFile.read((char *)&numZinV, sizeof(numZinV));
|
||||
if (!volFile)
|
||||
return false;
|
||||
|
||||
z.allVoids[v].zId.resize(numZinV);
|
||||
|
||||
int *zId = new int[numZinV];
|
||||
|
||||
volFile.read((char *)zId, sizeof(int)*numZinV);
|
||||
for (int k = 0; k < numZinV; k++)
|
||||
z.allVoids[v].zId[k] = zId[k];
|
||||
std::sort(&z.allVoids[v].zId[0], &z.allVoids[v].zId[numZinV]);
|
||||
|
||||
delete[] zId;
|
||||
}
|
||||
|
||||
if (volName != 0)
|
||||
{
|
||||
cout << "Loading particle volumes (requested)" << endl;
|
||||
ifstream f(volName);
|
||||
int numParticles;
|
||||
|
||||
if (!f)
|
||||
{
|
||||
cerr << "No such file " << volName << endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
f.read((char *)&numParticles, sizeof(int));
|
||||
z.particleVolume.resize(numParticles);
|
||||
f.read((char *)&z.particleVolume[0], sizeof(float)*numParticles);
|
||||
}
|
||||
|
||||
cout << "Loading description" << endl;
|
||||
|
||||
string line;
|
||||
getline(descFile, line);
|
||||
getline(descFile, line);
|
||||
getline(descFile, line);
|
||||
while (!descFile.eof())
|
||||
{
|
||||
istringstream lineStream(line.c_str());
|
||||
int orderId, volId, coreParticle, numParticlesInZone, numZonesInVoid, numInVoid;
|
||||
float coreDensity, volumeZone, volumeVoid, densityContrast;
|
||||
float probability;
|
||||
|
||||
lineStream
|
||||
>> orderId
|
||||
>> volId
|
||||
>> coreParticle
|
||||
>> coreDensity
|
||||
>> volumeZone
|
||||
>> numParticlesInZone
|
||||
>> numZonesInVoid
|
||||
>> volumeVoid
|
||||
>> numInVoid
|
||||
>> densityContrast
|
||||
>> probability;
|
||||
if (!lineStream)
|
||||
{
|
||||
cerr << "Error in text stream" << endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
z.allVoids[volId].proba = probability;
|
||||
z.allVoids[volId].volume = volumeVoid;
|
||||
z.allVoids[volId].numParticles = numInVoid;
|
||||
z.allVoids[volId].coreParticle = coreParticle;
|
||||
|
||||
// Sanity check
|
||||
int actualNumber = 0;
|
||||
for (int j = 0; j < z.allVoids[volId].zId.size(); j++)
|
||||
{
|
||||
int zzid = z.allVoids[volId].zId[j];
|
||||
actualNumber += z.allZones[zzid].pId.size();
|
||||
}
|
||||
|
||||
if (actualNumber != numInVoid)
|
||||
{
|
||||
cerr << "Sanity check failed."
|
||||
<< " The number of particles in the description ("
|
||||
<< numInVoid
|
||||
<< ") is different from the one in the file ("
|
||||
<< actualNumber << ")" << endl;
|
||||
}
|
||||
getline(descFile, line);
|
||||
}
|
||||
|
||||
cout << "Done loading" << endl;
|
||||
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool loadZobovParticles(const char *fname, std::vector<ZobovParticle>& particles)
|
||||
{
|
||||
UnformattedRead f(fname);
|
||||
int N;
|
||||
|
||||
f.beginCheckpoint();
|
||||
N = f.readInt32();
|
||||
f.endCheckpoint();
|
||||
|
||||
particles.resize(N);
|
||||
|
||||
f.beginCheckpoint();
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
particles[i].x = f.readReal32();
|
||||
}
|
||||
f.endCheckpoint();
|
||||
|
||||
f.beginCheckpoint();
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
particles[i].y = f.readReal32();
|
||||
}
|
||||
f.endCheckpoint();
|
||||
|
||||
f.beginCheckpoint();
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
particles[i].z = f.readReal32();
|
||||
}
|
||||
f.endCheckpoint();
|
||||
|
||||
return true;
|
||||
}
|
37
pipeline_tools/loadZobov.hpp
Normal file
37
pipeline_tools/loadZobov.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef __LOAD_ZOBOV_HPP
|
||||
#define __LOAD_ZOBOV_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct ZobovZone
|
||||
{
|
||||
std::vector<int> pId;
|
||||
};
|
||||
|
||||
struct ZobovVoid
|
||||
{
|
||||
std::vector<int> zId;
|
||||
float proba;
|
||||
int numParticles, coreParticle;
|
||||
float volume;
|
||||
};
|
||||
|
||||
struct ZobovRep
|
||||
{
|
||||
std::vector<ZobovZone> allZones;
|
||||
std::vector<ZobovVoid> allVoids;
|
||||
std::vector<float> particleVolume;
|
||||
};
|
||||
|
||||
struct ZobovParticle
|
||||
{
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
bool loadZobov(const char *descName,
|
||||
const char *adjName, const char *voidName,
|
||||
const char *volName, ZobovRep& z);
|
||||
|
||||
bool loadZobovParticles(const char *fname, std::vector<ZobovParticle>& particles);
|
||||
|
||||
#endif
|
68
pipeline_tools/particleInfo.cpp
Normal file
68
pipeline_tools/particleInfo.cpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include <netcdfcpp.h>
|
||||
#include <CosmoTool/fortran.hpp>
|
||||
#include "particleInfo.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace CosmoTool;
|
||||
|
||||
bool loadParticleInfo(ParticleInfo& info,
|
||||
const std::string& particles,
|
||||
const std::string& extra_info)
|
||||
{
|
||||
int numpart;
|
||||
|
||||
NcFile f_info(extra_info.c_str());
|
||||
|
||||
if (!f_info.is_valid())
|
||||
return false;
|
||||
|
||||
info.ranges[0][0] = f_info.get_att("range_x_min")->as_double(0);
|
||||
info.ranges[0][1] = f_info.get_att("range_x_max")->as_double(0);
|
||||
info.ranges[1][0] = f_info.get_att("range_y_min")->as_double(0);
|
||||
info.ranges[1][1] = f_info.get_att("range_y_max")->as_double(0);
|
||||
info.ranges[2][0] = f_info.get_att("range_z_min")->as_double(0);
|
||||
info.ranges[2][1] = f_info.get_att("range_z_max")->as_double(0);
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
info.length[i] = info.ranges[i][1] - info.ranges[i][0];
|
||||
|
||||
try
|
||||
{
|
||||
UnformattedRead f(particles);
|
||||
|
||||
float mul, offset;
|
||||
|
||||
f.beginCheckpoint();
|
||||
numpart = f.readInt32();
|
||||
f.endCheckpoint();
|
||||
|
||||
info.particles.resize(numpart);
|
||||
|
||||
offset = info.ranges[0][0];
|
||||
mul = info.ranges[0][1] - info.ranges[0][0];
|
||||
f.beginCheckpoint();
|
||||
for (int i = 0; i < numpart; i++)
|
||||
info.particles[i].x = mul*f.readReal32();
|
||||
f.endCheckpoint();
|
||||
|
||||
offset = info.ranges[1][0];
|
||||
mul = info.ranges[1][1] - info.ranges[1][0];
|
||||
f.beginCheckpoint();
|
||||
for (int i = 0; i < numpart; i++)
|
||||
info.particles[i].y = mul*f.readReal32();
|
||||
f.endCheckpoint();
|
||||
|
||||
offset = info.ranges[2][0];
|
||||
mul = info.ranges[2][1] - info.ranges[2][0];
|
||||
f.beginCheckpoint();
|
||||
for (int i = 0; i < numpart; i++)
|
||||
info.particles[i].z = mul*f.readReal32();
|
||||
f.endCheckpoint();
|
||||
}
|
||||
catch (const NoSuchFileException& e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
24
pipeline_tools/particleInfo.hpp
Normal file
24
pipeline_tools/particleInfo.hpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef _PARTICLE_INFO_HEADER_HPP
|
||||
#define _PARTICLE_INFO_HEADER_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct ParticleData {
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
typedef std::vector<ParticleData> ParticleVector;
|
||||
|
||||
struct ParticleInfo
|
||||
{
|
||||
ParticleVector particles;
|
||||
float ranges[3][2];
|
||||
float length[3];
|
||||
};
|
||||
|
||||
bool loadParticleInfo(ParticleInfo& info,
|
||||
const std::string& particles,
|
||||
const std::string& extra_info);
|
||||
|
||||
#endif
|
346
pipeline_tools/voidTree.hpp
Normal file
346
pipeline_tools/voidTree.hpp
Normal file
|
@ -0,0 +1,346 @@
|
|||
#ifndef _VOID_TREE_HPP
|
||||
#define _VOID_TREE_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
#include "loadZobov.hpp"
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
struct VoidNode
|
||||
{
|
||||
int vid;
|
||||
VoidNode *parent;
|
||||
std::list<VoidNode *> children;
|
||||
};
|
||||
|
||||
struct VoidNodeOnDisk
|
||||
{
|
||||
int vid;
|
||||
int parent;
|
||||
};
|
||||
|
||||
class VoidTree
|
||||
{
|
||||
protected:
|
||||
uint32_t totalNumNodes, activeNodes;
|
||||
VoidNode *nodes;
|
||||
VoidNode *rootNode;
|
||||
ZobovRep& zobov;
|
||||
public:
|
||||
typedef std::list<VoidNode *> VoidList;
|
||||
|
||||
void dumpTree(std::ostream& o)
|
||||
{
|
||||
VoidNodeOnDisk data;
|
||||
|
||||
o.write((char*)&activeNodes, sizeof(uint32_t));
|
||||
for (uint32_t i = 0; i < activeNodes; i++)
|
||||
{
|
||||
data.vid = nodes[i].vid;
|
||||
if (nodes[i].parent == 0)
|
||||
data.parent = -1;
|
||||
else
|
||||
data.parent = nodes[i].parent - nodes;
|
||||
o.write((char *)&data, sizeof(VoidNodeOnDisk));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int lookupParent(int voidId, const std::vector<std::list<int> >& voids_for_zones)
|
||||
{
|
||||
int lastSize = 0x7fffffff;
|
||||
int goodParent = -1;
|
||||
ZobovVoid &ref_void = zobov.allVoids[voidId];
|
||||
const std::list<int>& candidateList = voids_for_zones[ref_void.zId.front()];
|
||||
std::list<int>::const_iterator iter_candidate = candidateList.begin();
|
||||
|
||||
// std::cout << "candidate list size is " << candidateList.size() << std::endl;
|
||||
|
||||
while (iter_candidate != candidateList.end())
|
||||
{
|
||||
int vid_candidate = *iter_candidate;
|
||||
|
||||
if (vid_candidate == voidId)
|
||||
break;
|
||||
++iter_candidate;
|
||||
}
|
||||
if (iter_candidate == candidateList.end())
|
||||
{
|
||||
// std::cout << "Failure to lookup parent" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// voidId must be in the list.
|
||||
// assert(iter_candidate != candidateList.end());
|
||||
// Go back
|
||||
|
||||
iter_candidate = candidateList.end();
|
||||
|
||||
int vid_good_candidate = -1;
|
||||
int old_good_candidate_size = zobov.allZones.size()+1;
|
||||
|
||||
do
|
||||
{
|
||||
int vid_candidate;
|
||||
|
||||
--iter_candidate;
|
||||
|
||||
vid_candidate = *iter_candidate;
|
||||
std::vector<int>& candidate_zIds = zobov.allVoids[vid_candidate].zId;
|
||||
|
||||
if (voidId == vid_candidate)
|
||||
continue;
|
||||
|
||||
if (candidate_zIds.size() < ref_void.zId.size())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int counter = 0;
|
||||
// All zones id are sorted in each void. So we just have parse the
|
||||
// vector of zones and check whether all the zones in ref_void.zId is
|
||||
// in iter_candidate->zId, the list is analyzed only once.
|
||||
// THOUGHT: candidateList may contain directly the information. It would suffice to have the void ids sorted according to volume. Then we just have to jump to the indice just smaller than voidId.
|
||||
|
||||
int k = 0;
|
||||
for (int j = 0; j < candidate_zIds.size() && k < ref_void.zId.size(); j++)
|
||||
{
|
||||
if (candidate_zIds[j] == ref_void.zId[k])
|
||||
k++;
|
||||
else if (candidate_zIds[j] > ref_void.zId[k])
|
||||
break;
|
||||
}
|
||||
if (k==ref_void.zId.size())
|
||||
{
|
||||
if (candidate_zIds.size() < old_good_candidate_size)
|
||||
{
|
||||
vid_good_candidate = vid_candidate;
|
||||
old_good_candidate_size = candidate_zIds.size();
|
||||
}
|
||||
// std::cout << "Found parent " << vid_candidate << std::endl;
|
||||
// return vid_candidate;
|
||||
}
|
||||
|
||||
// Go bigger, though I would say we should not to.
|
||||
}
|
||||
while (iter_candidate != candidateList.begin()) ;
|
||||
if (vid_good_candidate < 0)
|
||||
std::cout << "Failure to lookup parent (2)" << std::endl;
|
||||
return vid_good_candidate;
|
||||
}
|
||||
|
||||
VoidTree(ZobovRep& rep, std::istream& disk)
|
||||
: zobov(rep)
|
||||
{
|
||||
totalNumNodes = rep.allVoids.size();
|
||||
|
||||
disk.read((char *)&activeNodes, sizeof(uint32_t));
|
||||
nodes = new VoidNode[activeNodes];
|
||||
rootNode = 0;
|
||||
for (uint32_t i = 0; i < activeNodes; i++)
|
||||
{
|
||||
VoidNodeOnDisk data;
|
||||
|
||||
disk.read((char *)&data, sizeof(data));
|
||||
nodes[i].vid = data.vid;
|
||||
if (data.parent < 0)
|
||||
{
|
||||
if (rootNode != 0)
|
||||
{
|
||||
std::cerr << "Multiple root to the tree !!!" << std::endl;
|
||||
abort();
|
||||
}
|
||||
nodes[i].parent = 0;
|
||||
rootNode = &nodes[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
nodes[i].parent = nodes + data.parent;
|
||||
nodes[i].parent->children.push_back(&nodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
computeMaxDepth();
|
||||
computeChildrenByNode();
|
||||
}
|
||||
|
||||
VoidTree(ZobovRep& rep)
|
||||
: zobov(rep)
|
||||
{
|
||||
totalNumNodes = rep.allVoids.size();
|
||||
|
||||
std::vector<std::list<int> > voids_for_zones;
|
||||
|
||||
voids_for_zones.resize(rep.allZones.size());
|
||||
for (int i = 0; i < rep.allVoids.size(); i++)
|
||||
{
|
||||
ZobovVoid& v = rep.allVoids[i];
|
||||
for (int j = 0; j < v.zId.size(); j++)
|
||||
voids_for_zones[v.zId[j]].push_back(i);
|
||||
}
|
||||
|
||||
// One additional for the mega-root
|
||||
nodes = new VoidNode[totalNumNodes+1];
|
||||
|
||||
for (int i = 0; i <= totalNumNodes; i++)
|
||||
{
|
||||
nodes[i].vid = i;
|
||||
nodes[i].parent = 0;
|
||||
}
|
||||
|
||||
std::cout << "Linking voids together..." << std::endl;
|
||||
double volMin = 0;// 4*M_PI/3*pow(4.*512/500.,3);
|
||||
int inserted = 0;
|
||||
for (int i = 0; i < rep.allVoids.size(); i++)
|
||||
{
|
||||
if (rep.allVoids[i].volume < volMin) continue;
|
||||
|
||||
int p = lookupParent(i, voids_for_zones);
|
||||
if ((i % 1000) == 0) std::cout << i << std::endl;
|
||||
|
||||
if (p >= 0)
|
||||
{
|
||||
nodes[p].children.push_back(&nodes[i]);
|
||||
nodes[i].parent = &nodes[p];
|
||||
}
|
||||
|
||||
inserted++;
|
||||
}
|
||||
|
||||
assert(inserted <= totalNumNodes);
|
||||
rootNode = &nodes[inserted];
|
||||
rootNode->vid = -1;
|
||||
rootNode->parent = 0;
|
||||
|
||||
for (int i = 0; i < inserted; i++)
|
||||
if (nodes[i].parent == 0)
|
||||
{
|
||||
nodes[i].parent = rootNode;
|
||||
rootNode->children.push_back(&nodes[i]);
|
||||
}
|
||||
activeNodes = inserted+1;
|
||||
|
||||
computeMaxDepth();
|
||||
computeChildrenByNode();
|
||||
}
|
||||
|
||||
~VoidTree()
|
||||
{
|
||||
delete[] nodes;
|
||||
}
|
||||
|
||||
int _depth_computer(VoidNode *node)
|
||||
{
|
||||
VoidList::iterator i = node->children.begin();
|
||||
int d = 0;
|
||||
|
||||
while (i != node->children.end())
|
||||
{
|
||||
d = std::max(d,_depth_computer(*i));
|
||||
++i;
|
||||
}
|
||||
|
||||
return d+1;
|
||||
}
|
||||
|
||||
void computeMaxDepth()
|
||||
{
|
||||
std::cout << "maximum depth is " << _depth_computer(rootNode) << std::endl;
|
||||
}
|
||||
|
||||
struct _children_stat {
|
||||
int num, min_num, max_num, num_zero,num_one, num_multiple;
|
||||
};
|
||||
|
||||
void _children_computer(VoidNode *node, _children_stat& s)
|
||||
{
|
||||
VoidList::iterator i = node->children.begin();
|
||||
int d = 0, j = 0;
|
||||
|
||||
while (i != node->children.end())
|
||||
{
|
||||
_children_computer(*i, s);
|
||||
++i;
|
||||
++j;
|
||||
}
|
||||
s.num += j;
|
||||
if (j!= 0)
|
||||
s.min_num = std::min(s.min_num, j);
|
||||
else s.num_zero ++;
|
||||
if (j==1) s.num_one++;
|
||||
if (j>1) s.num_multiple++;
|
||||
s.max_num = std::max(s.max_num, j);
|
||||
}
|
||||
|
||||
void computeChildrenByNode()
|
||||
{
|
||||
_children_stat s;
|
||||
s.num = 0;
|
||||
s.min_num = activeNodes+1;
|
||||
s.max_num = s.num_zero = s.num_one =s.num_multiple= 0;
|
||||
_children_computer(rootNode, s);
|
||||
std::cout << "Average children by node " << s.num*1.0/activeNodes << " , " << s.min_num << " " << s.max_num << " " << s.num_zero << " " << s.num_one << " " << s.num_multiple << std::endl;
|
||||
}
|
||||
|
||||
int getParent(int vid) const
|
||||
{
|
||||
assert(nodes[vid].parent != 0);
|
||||
return nodes[vid].parent->vid;
|
||||
}
|
||||
|
||||
const VoidList& getChildren(int vid) const
|
||||
{
|
||||
return nodes[vid].children;
|
||||
}
|
||||
|
||||
|
||||
VoidNode *getRoot() { return rootNode; }
|
||||
|
||||
template<typename T>
|
||||
void walkNode(VoidNode *node, T& traverse)
|
||||
{
|
||||
if (!traverse(node))
|
||||
return;
|
||||
|
||||
VoidList::iterator i = node->children.begin();
|
||||
|
||||
while (i != node->children.end())
|
||||
{
|
||||
walkNode(*i, traverse);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void walk(T& traverse)
|
||||
{
|
||||
walkNode(rootNode, traverse);
|
||||
}
|
||||
|
||||
template<typename T, typename T2>
|
||||
void walkNodeWithMark(VoidNode *node, T& traverse, const T2& mark)
|
||||
{
|
||||
T2 new_mark = mark;
|
||||
|
||||
if (!traverse(node, new_mark))
|
||||
return;
|
||||
|
||||
VoidList::iterator i = node->children.begin();
|
||||
|
||||
while (i != node->children.end())
|
||||
{
|
||||
walkNodeWithMark(*i, traverse, new_mark);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T,typename T2>
|
||||
void walkWithMark(T& traverse, T2 mark)
|
||||
{
|
||||
walkNodeWithMark(rootNode, traverse, mark);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue