mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-04 15:21:11 +00:00
Merge branch 'master' of https://bitbucket.org/cosmicvoids/vide_public
This commit is contained in:
commit
9485b2d720
14 changed files with 315 additions and 93 deletions
|
@ -695,7 +695,11 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
else if (args_info.gadget_given)
|
else if (args_info.gadget_given)
|
||||||
{
|
{
|
||||||
loader = gadgetLoader(args_info.gadget_arg, 1/args_info.gadgetUnit_arg, NEED_POSITION|NEED_VELOCITY|NEED_GADGET_ID, preselector);
|
loader = gadgetLoader(args_info.gadget_arg, 1/args_info.gadgetUnit_arg, NEED_POSITION|NEED_VELOCITY|NEED_GADGET_ID, 1, preselector);
|
||||||
|
}
|
||||||
|
else if (args_info.gadget2_given)
|
||||||
|
{
|
||||||
|
loader = gadgetLoader(args_info.gadget2_arg, 1/args_info.gadgetUnit_arg, NEED_POSITION|NEED_VELOCITY|NEED_GADGET_ID, 2, preselector);
|
||||||
}
|
}
|
||||||
else if (args_info.flash_given)
|
else if (args_info.flash_given)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,7 @@ option "ramsesBase" - "Base directory for ramses" string optional
|
||||||
option "ramsesId" - "Ramses snapshot id" int optional
|
option "ramsesId" - "Ramses snapshot id" int optional
|
||||||
|
|
||||||
option "gadget" - "Base name of gadget snapshot (without parallel writing extension)" string optional
|
option "gadget" - "Base name of gadget snapshot (without parallel writing extension)" string optional
|
||||||
|
option "gadget2" - "Base name of gadget snapshot (version 2, without parallel writing extension)" string optional
|
||||||
option "flash" - "Base name for FLASH snapshot" string optional
|
option "flash" - "Base name for FLASH snapshot" string optional
|
||||||
option "multidark" - "Base name for multidark snapshot" string optional
|
option "multidark" - "Base name for multidark snapshot" string optional
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,13 @@ private:
|
||||||
bool onefile;
|
bool onefile;
|
||||||
int _num_files;
|
int _num_files;
|
||||||
double unitMpc;
|
double unitMpc;
|
||||||
|
int gadgetFormat;
|
||||||
SimuData *gadget_header;
|
SimuData *gadget_header;
|
||||||
string snapshot_name;
|
string snapshot_name;
|
||||||
SimulationPreprocessor *preproc;
|
SimulationPreprocessor *preproc;
|
||||||
public:
|
public:
|
||||||
GadgetLoader(const string& basename, SimuData *header, int flags, bool singleFile, int _num, double unit, SimulationPreprocessor *p)
|
GadgetLoader(const string& basename, SimuData *header, int flags, bool singleFile, int _num, double unit, int gadgetFormat, SimulationPreprocessor *p)
|
||||||
: snapshot_name(basename), load_flags(flags), onefile(singleFile), _num_files(_num), unitMpc(1/unit), gadget_header(header), preproc(p)
|
: snapshot_name(basename), load_flags(flags), onefile(singleFile), _num_files(_num), unitMpc(1/unit), gadget_header(header), gadgetFormat(gadgetFormat), preproc(p)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,9 +68,9 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (onefile)
|
if (onefile)
|
||||||
d = loadGadgetMulti(snapshot_name.c_str(), -1, load_flags);
|
d = loadGadgetMulti(snapshot_name.c_str(), -1, load_flags, gadgetFormat);
|
||||||
else
|
else
|
||||||
d = loadGadgetMulti(snapshot_name.c_str(), id, load_flags);
|
d = loadGadgetMulti(snapshot_name.c_str(), id, load_flags, gadgetFormat);
|
||||||
|
|
||||||
if (d->Id != 0)
|
if (d->Id != 0)
|
||||||
{
|
{
|
||||||
|
@ -99,7 +100,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
SimulationLoader *gadgetLoader(const std::string& snapshot, double Mpc_unitLength, int flags, SimulationPreprocessor *p)
|
SimulationLoader *gadgetLoader(const std::string& snapshot, double Mpc_unitLength, int flags, int gadgetFormat, SimulationPreprocessor *p)
|
||||||
{
|
{
|
||||||
bool singleFile = false;
|
bool singleFile = false;
|
||||||
int num_files;
|
int num_files;
|
||||||
|
@ -109,7 +110,7 @@ SimulationLoader *gadgetLoader(const std::string& snapshot, double Mpc_unitLengt
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
d = loadGadgetMulti(snapshot.c_str(), -1, 0);
|
d = loadGadgetMulti(snapshot.c_str(), -1, 0, gadgetFormat);
|
||||||
singleFile = true;
|
singleFile = true;
|
||||||
num_files = 1;
|
num_files = 1;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +118,7 @@ SimulationLoader *gadgetLoader(const std::string& snapshot, double Mpc_unitLengt
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
d = loadGadgetMulti(snapshot.c_str(), 0, 0);
|
d = loadGadgetMulti(snapshot.c_str(), 0, 0, gadgetFormat);
|
||||||
num_files = 0;
|
num_files = 0;
|
||||||
}
|
}
|
||||||
catch(const NoSuchFileException& e)
|
catch(const NoSuchFileException& e)
|
||||||
|
@ -135,7 +136,7 @@ SimulationLoader *gadgetLoader(const std::string& snapshot, double Mpc_unitLengt
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while ((d = loadGadgetMulti(snapshot.c_str(), num_files, 0)) != 0)
|
while ((d = loadGadgetMulti(snapshot.c_str(), num_files, 0, gadgetFormat)) != 0)
|
||||||
{
|
{
|
||||||
num_files++;
|
num_files++;
|
||||||
delete d;
|
delete d;
|
||||||
|
@ -146,5 +147,5 @@ SimulationLoader *gadgetLoader(const std::string& snapshot, double Mpc_unitLengt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new GadgetLoader(snapshot, header, flags, singleFile, num_files, Mpc_unitLength, p);
|
return new GadgetLoader(snapshot, header, flags, singleFile, num_files, Mpc_unitLength, gadgetFormat, p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,7 @@ void delete_adaptor(void *ptr)
|
||||||
|
|
||||||
|
|
||||||
// Unit length is the size of one Mpc in the simulation units
|
// Unit length is the size of one Mpc in the simulation units
|
||||||
SimulationLoader *gadgetLoader(const std::string& snapshot, double Mpc_unitLength, int flags, SimulationPreprocessor *p);
|
SimulationLoader *gadgetLoader(const std::string& snapshot, double Mpc_unitLength, int flags, int gadgetFormat, SimulationPreprocessor *p);
|
||||||
SimulationLoader *flashLoader(const std::string& snapshot, int flags, SimulationPreprocessor *p);
|
SimulationLoader *flashLoader(const std::string& snapshot, int flags, SimulationPreprocessor *p);
|
||||||
SimulationLoader *multidarkLoader(const std::string& snapshot, SimulationPreprocessor *p);
|
SimulationLoader *multidarkLoader(const std::string& snapshot, SimulationPreprocessor *p);
|
||||||
SimulationLoader *ramsesLoader(const std::string& snapshot, int baseid, bool double_precision, int flags, SimulationPreprocessor *p);
|
SimulationLoader *ramsesLoader(const std::string& snapshot, int baseid, bool double_precision, int flags, SimulationPreprocessor *p);
|
||||||
|
|
4
external/cosmotool/CMakeLists.txt
vendored
4
external/cosmotool/CMakeLists.txt
vendored
|
@ -47,6 +47,10 @@ if (ENABLE_SHARP)
|
||||||
endif (ENABLE_SHARP)
|
endif (ENABLE_SHARP)
|
||||||
|
|
||||||
|
|
||||||
|
find_package(Boost 1.53)
|
||||||
|
mark_as_advanced(Boost_INCLUDE_DIRS Boost_LIBRARIES)
|
||||||
|
|
||||||
|
|
||||||
set(HDF5_FIND_COMPONENTS HL CXX)
|
set(HDF5_FIND_COMPONENTS HL CXX)
|
||||||
if(HDF5_ROOTDIR)
|
if(HDF5_ROOTDIR)
|
||||||
SET(ENV{HDF5_ROOT} ${HDF5_ROOTDIR})
|
SET(ENV{HDF5_ROOT} ${HDF5_ROOTDIR})
|
||||||
|
|
2
external/cosmotool/src/CMakeLists.txt
vendored
2
external/cosmotool/src/CMakeLists.txt
vendored
|
@ -55,7 +55,7 @@ SET(CosmoTool_SRCS ${CosmoTool_SRCS}
|
||||||
growthFactor.hpp
|
growthFactor.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(${GSL_INCLUDE_PATH} ${NETCDF_INCLUDE_PATH} ${NETCDFCPP_INCLUDE_PATH} ${CMAKE_BINARY_DIR}/src)
|
include_directories(${Boost_INCLUDE_DIRS} ${GSL_INCLUDE_PATH} ${NETCDF_INCLUDE_PATH} ${NETCDFCPP_INCLUDE_PATH} ${CMAKE_BINARY_DIR}/src)
|
||||||
|
|
||||||
set(CosmoTool_LIBS ${NETCDFCPP_LIBRARY} ${NETCDF_LIBRARY} ${GSL_LIBRARIES})
|
set(CosmoTool_LIBS ${NETCDFCPP_LIBRARY} ${NETCDF_LIBRARY} ${GSL_LIBRARIES})
|
||||||
if (HDF5_FOUND)
|
if (HDF5_FOUND)
|
||||||
|
|
32
external/cosmotool/src/fortran.cpp
vendored
32
external/cosmotool/src/fortran.cpp
vendored
|
@ -1,5 +1,5 @@
|
||||||
/*+
|
/*+
|
||||||
This is CosmoTool (./src/fortran.cpp) -- Copyright (C) Guilhem Lavaux (2007-2013)
|
This is CosmoTool (./src/fortran.cpp) -- Copyright (C) Guilhem Lavaux (2007-2014)
|
||||||
|
|
||||||
guilhem.lavaux@gmail.com
|
guilhem.lavaux@gmail.com
|
||||||
|
|
||||||
|
@ -71,6 +71,18 @@ UnformattedRead::~UnformattedRead()
|
||||||
delete f;
|
delete f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t UnformattedRead::position() const
|
||||||
|
{
|
||||||
|
return f->tellg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnformattedRead::seek(int64_t pos)
|
||||||
|
{
|
||||||
|
f->clear();
|
||||||
|
f->seekg(pos, istream::beg);
|
||||||
|
checkPointRef = checkPointAccum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Todo implement primitive description
|
// Todo implement primitive description
|
||||||
void UnformattedRead::setOrdering(Ordering o)
|
void UnformattedRead::setOrdering(Ordering o)
|
||||||
{
|
{
|
||||||
|
@ -112,7 +124,7 @@ void UnformattedRead::beginCheckpoint()
|
||||||
checkPointRef = (cSize == Check_32bits) ? 4 : 8;
|
checkPointRef = (cSize == Check_32bits) ? 4 : 8;
|
||||||
checkPointAccum = 0;
|
checkPointAccum = 0;
|
||||||
|
|
||||||
checkPointRef = (cSize == Check_32bits) ? readInt32() : readInt64();
|
checkPointRef = (cSize == Check_32bits) ? readUint32() : readInt64();
|
||||||
checkPointAccum = 0;
|
checkPointAccum = 0;
|
||||||
|
|
||||||
if (f->eof())
|
if (f->eof())
|
||||||
|
@ -144,7 +156,7 @@ void UnformattedRead::endCheckpoint(bool autodrop)
|
||||||
void UnformattedRead::readOrderedBuffer(void *buffer, int size)
|
void UnformattedRead::readOrderedBuffer(void *buffer, int size)
|
||||||
throw (InvalidUnformattedAccess)
|
throw (InvalidUnformattedAccess)
|
||||||
{
|
{
|
||||||
if ((checkPointAccum+size) > checkPointRef)
|
if ((checkPointAccum+(uint64_t)size) > checkPointRef)
|
||||||
throw InvalidUnformattedAccess();
|
throw InvalidUnformattedAccess();
|
||||||
|
|
||||||
f->read((char *)buffer, size);
|
f->read((char *)buffer, size);
|
||||||
|
@ -186,6 +198,20 @@ float UnformattedRead::readReal32()
|
||||||
return a.f;
|
return a.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t UnformattedRead::readUint32()
|
||||||
|
throw (InvalidUnformattedAccess)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
char b[4];
|
||||||
|
uint32_t i;
|
||||||
|
} a;
|
||||||
|
|
||||||
|
readOrderedBuffer(&a, 4);
|
||||||
|
|
||||||
|
return a.i;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t UnformattedRead::readInt32()
|
int32_t UnformattedRead::readInt32()
|
||||||
throw (InvalidUnformattedAccess)
|
throw (InvalidUnformattedAccess)
|
||||||
{
|
{
|
||||||
|
|
13
external/cosmotool/src/fortran.hpp
vendored
13
external/cosmotool/src/fortran.hpp
vendored
|
@ -1,5 +1,5 @@
|
||||||
/*+
|
/*+
|
||||||
This is CosmoTool (./src/fortran.hpp) -- Copyright (C) Guilhem Lavaux (2007-2013)
|
This is CosmoTool (./src/fortran.hpp) -- Copyright (C) Guilhem Lavaux (2007-2014)
|
||||||
|
|
||||||
guilhem.lavaux@gmail.com
|
guilhem.lavaux@gmail.com
|
||||||
|
|
||||||
|
@ -73,6 +73,8 @@ namespace CosmoTool
|
||||||
// Todo implement primitive description
|
// Todo implement primitive description
|
||||||
void setOrdering(Ordering o);
|
void setOrdering(Ordering o);
|
||||||
void setCheckpointSize(CheckpointSize cs);
|
void setCheckpointSize(CheckpointSize cs);
|
||||||
|
|
||||||
|
uint64_t getBlockSize() const { return checkPointRef; }
|
||||||
|
|
||||||
void beginCheckpoint()
|
void beginCheckpoint()
|
||||||
throw (InvalidUnformattedAccess,EndOfFileException);
|
throw (InvalidUnformattedAccess,EndOfFileException);
|
||||||
|
@ -83,6 +85,8 @@ namespace CosmoTool
|
||||||
throw (InvalidUnformattedAccess);
|
throw (InvalidUnformattedAccess);
|
||||||
float readReal32()
|
float readReal32()
|
||||||
throw (InvalidUnformattedAccess);
|
throw (InvalidUnformattedAccess);
|
||||||
|
uint32_t readUint32()
|
||||||
|
throw (InvalidUnformattedAccess);
|
||||||
int32_t readInt32()
|
int32_t readInt32()
|
||||||
throw (InvalidUnformattedAccess);
|
throw (InvalidUnformattedAccess);
|
||||||
int64_t readInt64()
|
int64_t readInt64()
|
||||||
|
@ -91,6 +95,11 @@ namespace CosmoTool
|
||||||
void skip(int64_t off)
|
void skip(int64_t off)
|
||||||
throw (InvalidUnformattedAccess);
|
throw (InvalidUnformattedAccess);
|
||||||
|
|
||||||
|
int64_t position() const;
|
||||||
|
void seek(int64_t pos);
|
||||||
|
|
||||||
|
void readOrderedBuffer(void *buffer, int size)
|
||||||
|
throw (InvalidUnformattedAccess);
|
||||||
protected:
|
protected:
|
||||||
bool swapOrdering;
|
bool swapOrdering;
|
||||||
CheckpointSize cSize;
|
CheckpointSize cSize;
|
||||||
|
@ -98,8 +107,6 @@ namespace CosmoTool
|
||||||
uint64_t checkPointAccum;
|
uint64_t checkPointAccum;
|
||||||
std::ifstream *f;
|
std::ifstream *f;
|
||||||
|
|
||||||
void readOrderedBuffer(void *buffer, int size)
|
|
||||||
throw (InvalidUnformattedAccess);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class UnformattedWrite: public FortranTypes
|
class UnformattedWrite: public FortranTypes
|
||||||
|
|
239
external/cosmotool/src/loadGadget.cpp
vendored
239
external/cosmotool/src/loadGadget.cpp
vendored
|
@ -1,5 +1,5 @@
|
||||||
/*+
|
/*+
|
||||||
This is CosmoTool (./src/loadGadget.cpp) -- Copyright (C) Guilhem Lavaux (2007-2013)
|
This is CosmoTool (./src/loadGadget.cpp) -- Copyright (C) Guilhem Lavaux (2007-2014)
|
||||||
|
|
||||||
guilhem.lavaux@gmail.com
|
guilhem.lavaux@gmail.com
|
||||||
|
|
||||||
|
@ -38,6 +38,8 @@ knowledge of the CeCILL license and that you accept its terms.
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
#include "load_data.hpp"
|
#include "load_data.hpp"
|
||||||
#include "loadGadget.hpp"
|
#include "loadGadget.hpp"
|
||||||
#include "fortran.hpp"
|
#include "fortran.hpp"
|
||||||
|
@ -65,9 +67,16 @@ void loadGadgetHeader(UnformattedRead *f, GadgetHeader& h, SimuData *data, int i
|
||||||
data->Omega_M = h.Omega0 = f->readReal64();
|
data->Omega_M = h.Omega0 = f->readReal64();
|
||||||
data->Omega_Lambda = h.OmegaLambda = f->readReal64();
|
data->Omega_Lambda = h.OmegaLambda = f->readReal64();
|
||||||
data->Hubble = h.HubbleParam = f->readReal64();
|
data->Hubble = h.HubbleParam = f->readReal64();
|
||||||
|
(int)f->readInt32(); // stellarage
|
||||||
|
(int)f->readInt32(); // metals
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
h.npartTotal[i] |= ((unsigned long)f->readInt32()) << 32;
|
||||||
|
(int)f->readInt32(); // entropy instead of u
|
||||||
|
h.flag_doubleprecision = f->readInt32();
|
||||||
|
|
||||||
f->endCheckpoint(true);
|
f->endCheckpoint(true);
|
||||||
|
|
||||||
long NumPart = 0, NumPartTotal = 0;
|
ssize_t NumPart = 0, NumPartTotal = 0;
|
||||||
for(int k=0; k<6; k++)
|
for(int k=0; k<6; k++)
|
||||||
{
|
{
|
||||||
NumPart += h.npart[k];
|
NumPart += h.npart[k];
|
||||||
|
@ -77,6 +86,22 @@ void loadGadgetHeader(UnformattedRead *f, GadgetHeader& h, SimuData *data, int i
|
||||||
data->TotalNumPart = NumPartTotal;
|
data->TotalNumPart = NumPartTotal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T myRead64(UnformattedRead *f) { return f->readReal64(); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T myRead32(UnformattedRead *f) { return f->readReal32(); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T myReadI64(UnformattedRead *f) { return f->readInt64(); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T myReadI32(UnformattedRead *f) { return f->readInt32(); }
|
||||||
|
|
||||||
|
struct BlockInfo {
|
||||||
|
int64_t position, size;
|
||||||
|
};
|
||||||
|
|
||||||
SimuData *CosmoTool::loadGadgetMulti(const char *fname, int id,
|
SimuData *CosmoTool::loadGadgetMulti(const char *fname, int id,
|
||||||
int loadflags, int GadgetFormat,
|
int loadflags, int GadgetFormat,
|
||||||
SimuFilter filter)
|
SimuFilter filter)
|
||||||
|
@ -86,6 +111,15 @@ SimuData *CosmoTool::loadGadgetMulti(const char *fname, int id,
|
||||||
UnformattedRead *f;
|
UnformattedRead *f;
|
||||||
GadgetHeader h;
|
GadgetHeader h;
|
||||||
float velmul;
|
float velmul;
|
||||||
|
boost::function0<double> readToDouble;
|
||||||
|
boost::function0<float> readToSingle;
|
||||||
|
boost::function0<int64_t> readID;
|
||||||
|
long float_size;
|
||||||
|
|
||||||
|
if (GadgetFormat > 2) {
|
||||||
|
cerr << "Unknown gadget format" << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (id >= 0) {
|
if (id >= 0) {
|
||||||
int k = snprintf(0, 0, "%s.%d", fname, id)+1;
|
int k = snprintf(0, 0, "%s.%d", fname, id)+1;
|
||||||
|
@ -96,7 +130,7 @@ SimuData *CosmoTool::loadGadgetMulti(const char *fname, int id,
|
||||||
if (f == 0)
|
if (f == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
delete out_fname;
|
delete[] out_fname;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -106,27 +140,72 @@ SimuData *CosmoTool::loadGadgetMulti(const char *fname, int id,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef std::map<std::string, BlockInfo> BlockMap;
|
||||||
|
BlockMap blockTable;
|
||||||
|
|
||||||
|
if (GadgetFormat == 2) {
|
||||||
|
int64_t startBlock = 0;
|
||||||
|
char block[5];
|
||||||
|
int32_t blocksize;
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
f->beginCheckpoint();
|
||||||
|
f->readOrderedBuffer(block, 4);
|
||||||
|
block[4] = 0;
|
||||||
|
blocksize = f->readInt32();
|
||||||
|
f->endCheckpoint();
|
||||||
|
blockTable[block].position = f->position();
|
||||||
|
blockTable[block].size = blocksize;
|
||||||
|
f->skip(blocksize);
|
||||||
|
}
|
||||||
|
} catch (EndOfFileException&) {}
|
||||||
|
|
||||||
|
f->seek(startBlock);
|
||||||
|
}
|
||||||
|
|
||||||
data = new SimuData;
|
data = new SimuData;
|
||||||
if (data == 0) {
|
if (data == 0) {
|
||||||
delete f;
|
delete f;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long NumPart = 0, NumPartTotal = 0;
|
ssize_t NumPart = 0, NumPartTotal = 0;
|
||||||
|
#define ENSURE2(name,out_sz) { \
|
||||||
|
if (GadgetFormat == 2) { \
|
||||||
|
BlockMap::iterator iter = blockTable.find(name); \
|
||||||
|
int64_t sz; \
|
||||||
|
if (iter == blockTable.end()) { \
|
||||||
|
std::cerr << "GADGET2: Cannot find block named '" << name << "'" << endl; \
|
||||||
|
if (data) delete data; \
|
||||||
|
delete f; \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
f->seek(iter->second.position); \
|
||||||
|
sz = iter->second.size; \
|
||||||
|
out_sz = sz;\
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#define ENSURE(name) ENSURE2(name,sz);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
ENSURE("HEAD");
|
||||||
loadGadgetHeader(f, h, data, id);
|
loadGadgetHeader(f, h, data, id);
|
||||||
|
|
||||||
if (GadgetFormat == 1)
|
velmul = sqrt(h.time);
|
||||||
velmul = sqrt(h.time);
|
|
||||||
else if (GadgetFormat == 2)
|
if (h.flag_doubleprecision) {
|
||||||
velmul = 1/(h.time);
|
//cout << "Gadget format with double precision" << endl;
|
||||||
else {
|
readToDouble = boost::bind(myRead64<double>, f);
|
||||||
cerr << "unknown gadget format" << endl;
|
readToSingle = boost::bind(myRead64<float>, f);
|
||||||
abort();
|
float_size = sizeof(double);
|
||||||
|
} else {
|
||||||
|
//cout << "Gadget format with single precision" << endl;
|
||||||
|
readToDouble = boost::bind(myRead32<double>, f);
|
||||||
|
readToSingle = boost::bind(myRead32<float>, f);
|
||||||
|
float_size = sizeof(float);
|
||||||
}
|
}
|
||||||
|
|
||||||
NumPart = data->NumPart;
|
NumPart = data->NumPart;
|
||||||
NumPartTotal = data->TotalNumPart;
|
NumPartTotal = data->TotalNumPart;
|
||||||
}
|
}
|
||||||
|
@ -138,34 +217,47 @@ SimuData *CosmoTool::loadGadgetMulti(const char *fname, int id,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (loadflags & NEED_TYPE)
|
if (loadflags & NEED_TYPE)
|
||||||
{
|
{
|
||||||
int p = 0;
|
int p = 0;
|
||||||
|
|
||||||
data->type = new int[data->NumPart];
|
data->type = new int[data->NumPart];
|
||||||
for (int k = 0; k < 6; k++)
|
for (int k = 0; k < 6; k++)
|
||||||
for (int n = 0; n < h.npart[k]; n++,p++)
|
for (int n = 0; n < h.npart[k]; n++,p++)
|
||||||
data->type[p] = k;
|
data->type[p] = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadflags & NEED_POSITION) {
|
if (loadflags & NEED_POSITION) {
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
data->Pos[i] = new float[data->NumPart];
|
data->Pos[i] = new float[data->NumPart];
|
||||||
if (data->Pos[i] == 0) {
|
if (data->Pos[i] == 0) {
|
||||||
delete data;
|
delete data;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
ENSURE("POS ");
|
||||||
f->beginCheckpoint();
|
f->beginCheckpoint();
|
||||||
|
if (f->getBlockSize() != NumPart*float_size*3) {
|
||||||
|
// Check that single would work
|
||||||
|
if (f->getBlockSize() == NumPart*sizeof(float)*3) {
|
||||||
|
// Change to single
|
||||||
|
cout << "Change back to single. Buggy header." << endl;
|
||||||
|
readToDouble = boost::bind(myRead32<double>, f);
|
||||||
|
readToSingle = boost::bind(myRead32<float>, f);
|
||||||
|
float_size = sizeof(float);
|
||||||
|
}
|
||||||
|
}
|
||||||
for(int k = 0, p = 0; k < 6; k++) {
|
for(int k = 0, p = 0; k < 6; k++) {
|
||||||
for(int n = 0; n < h.npart[k]; n++) {
|
for(int n = 0; n < h.npart[k]; n++) {
|
||||||
data->Pos[0][p] = f->readReal32();
|
// if ((n%1000000)==0) cout << n << endl;
|
||||||
data->Pos[1][p] = f->readReal32();
|
data->Pos[0][p] = readToSingle();
|
||||||
data->Pos[2][p] = f->readReal32();
|
data->Pos[1][p] = readToSingle();
|
||||||
|
data->Pos[2][p] = readToSingle();
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,15 +265,16 @@ SimuData *CosmoTool::loadGadgetMulti(const char *fname, int id,
|
||||||
}
|
}
|
||||||
catch (const InvalidUnformattedAccess& e)
|
catch (const InvalidUnformattedAccess& e)
|
||||||
{
|
{
|
||||||
cerr << "Invalid format while reading positions" << endl;
|
cerr << "Invalid format while reading positions" << endl;
|
||||||
delete f;
|
delete f;
|
||||||
delete data;
|
delete data;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
long float_size = (h.flag_doubleprecision) ? sizeof(double) : sizeof(float);
|
||||||
// Skip positions
|
// Skip positions
|
||||||
f->skip(NumPart * 3 * sizeof(float) + 2*4);
|
f->skip(NumPart * 3 * float_size + 2*4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadflags & NEED_VELOCITY) {
|
if (loadflags & NEED_VELOCITY) {
|
||||||
|
@ -198,13 +291,15 @@ SimuData *CosmoTool::loadGadgetMulti(const char *fname, int id,
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
ENSURE("VEL ");
|
||||||
f->beginCheckpoint();
|
f->beginCheckpoint();
|
||||||
for(int k = 0, p = 0; k < 6; k++) {
|
for(int k = 0, p = 0; k < 6; k++) {
|
||||||
for(int n = 0; n < h.npart[k]; n++) {
|
for(int n = 0; n < h.npart[k]; n++) {
|
||||||
// THIS IS GADGET 1
|
// THIS IS GADGET 1
|
||||||
data->Vel[0][p] = f->readReal32()*velmul;
|
// if ((n%1000000)==0) cout << n << endl;
|
||||||
data->Vel[1][p] = f->readReal32()*velmul;
|
data->Vel[0][p] = readToSingle()*velmul;
|
||||||
data->Vel[2][p] = f->readReal32()*velmul;
|
data->Vel[1][p] = readToSingle()*velmul;
|
||||||
|
data->Vel[2][p] = readToSingle()*velmul;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,13 +317,25 @@ SimuData *CosmoTool::loadGadgetMulti(const char *fname, int id,
|
||||||
/// // TODO: FIX THE UNITS OF THESE FUNKY VELOCITIES !!!
|
/// // TODO: FIX THE UNITS OF THESE FUNKY VELOCITIES !!!
|
||||||
} else {
|
} else {
|
||||||
// Skip velocities
|
// Skip velocities
|
||||||
f->skip(NumPart*3*sizeof(float)+2*4);
|
f->skip(NumPart*3*float_size+2*4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip ids
|
// Skip ids
|
||||||
if (loadflags & NEED_GADGET_ID) {
|
if (loadflags & NEED_GADGET_ID) {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
int64_t idSize;
|
||||||
|
ENSURE2("ID ", idSize);
|
||||||
|
|
||||||
|
if (idSize / data->NumPart == 8) {
|
||||||
|
readID = boost::bind(myReadI64<int64_t>, f);
|
||||||
|
} else
|
||||||
|
if (idSize / data->NumPart == 4) {
|
||||||
|
readID = boost::bind(myReadI32<int64_t>, f);
|
||||||
|
} else {
|
||||||
|
throw InvalidUnformattedAccess();
|
||||||
|
}
|
||||||
|
|
||||||
f->beginCheckpoint();
|
f->beginCheckpoint();
|
||||||
data->Id = new long[data->NumPart];
|
data->Id = new long[data->NumPart];
|
||||||
if (data->Id == 0)
|
if (data->Id == 0)
|
||||||
|
@ -242,7 +349,7 @@ SimuData *CosmoTool::loadGadgetMulti(const char *fname, int id,
|
||||||
{
|
{
|
||||||
for(int n = 0; n < h.npart[k]; n++)
|
for(int n = 0; n < h.npart[k]; n++)
|
||||||
{
|
{
|
||||||
data->Id[p] = f->readInt32();
|
data->Id[p] = readID();
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,11 +368,66 @@ SimuData *CosmoTool::loadGadgetMulti(const char *fname, int id,
|
||||||
f->skip(h.npart[k]*4);
|
f->skip(h.npart[k]*4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (loadflags & NEED_MASS) {
|
||||||
|
bool do_load = false;
|
||||||
|
|
||||||
|
for (int k = 0; k < 6; k++)
|
||||||
|
{
|
||||||
|
do_load = do_load || ((h.mass[k] == 0)&&(h.npart[k]>0));
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
long l = 0;
|
||||||
|
if (do_load) {
|
||||||
|
ENSURE("MASS");
|
||||||
|
f->beginCheckpoint();
|
||||||
|
}
|
||||||
|
data->Mass = new float[NumPart];
|
||||||
|
for (int k = 0; k < 6; k++)
|
||||||
|
{
|
||||||
|
if (h.mass[k] == 0) {
|
||||||
|
for(int n = 0; n < h.npart[k]; n++)
|
||||||
|
{
|
||||||
|
// if ((n%1000000)==0) cout << n << endl;
|
||||||
|
data->Mass[l++] = readToSingle();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(int n = 0; n < h.npart[k]; n++)
|
||||||
|
{
|
||||||
|
if ((n%1000000)==0) cout << n << endl;
|
||||||
|
data->Mass[l++] = h.mass[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (do_load)
|
||||||
|
f->endCheckpoint();
|
||||||
|
}
|
||||||
|
catch (const InvalidUnformattedAccess& e)
|
||||||
|
{
|
||||||
|
cerr << "Invalid unformatted access while reading ID" << endl;
|
||||||
|
delete f;
|
||||||
|
delete data;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (const EndOfFileException& e)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 6; k++)
|
||||||
|
cerr << "mass[" << k << "] = " << h.mass[k] << endl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
f->skip(2*4);
|
||||||
|
for (int k = 0; k < 6; k++)
|
||||||
|
if (h.mass[k] == 0)
|
||||||
|
f->skip(h.npart[k]*4);
|
||||||
|
}
|
||||||
|
|
||||||
delete f;
|
delete f;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef ENSURE
|
||||||
|
|
||||||
|
|
||||||
void CosmoTool::writeGadget(const std::string& fname, SimuData *data, int GadgetFormat)
|
void CosmoTool::writeGadget(const std::string& fname, SimuData *data, int GadgetFormat)
|
||||||
|
@ -274,12 +436,16 @@ void CosmoTool::writeGadget(const std::string& fname, SimuData *data, int Gadget
|
||||||
int npart[6], npartTotal[6];
|
int npart[6], npartTotal[6];
|
||||||
float mass[6];
|
float mass[6];
|
||||||
|
|
||||||
if (data->Pos[0] == 0 || data->Vel[0] == 0 || data->Id == 0)
|
if (data->Pos[0] == 0 || data->Vel[0] == 0 || data->Id == 0) {
|
||||||
|
cerr << "Invalid simulation data array" << endl;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
f = new UnformattedWrite(fname);
|
f = new UnformattedWrite(fname);
|
||||||
if (f == 0)
|
if (f == 0) {
|
||||||
|
cerr << "Cannot create file" << endl;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
|
@ -321,8 +487,7 @@ void CosmoTool::writeGadget(const std::string& fname, SimuData *data, int Gadget
|
||||||
f->endCheckpoint();
|
f->endCheckpoint();
|
||||||
|
|
||||||
float velmul = 1.0;
|
float velmul = 1.0;
|
||||||
if (GadgetFormat == 1)
|
velmul = sqrt(data->time);
|
||||||
velmul = sqrt(data->time);
|
|
||||||
|
|
||||||
f->beginCheckpoint();
|
f->beginCheckpoint();
|
||||||
for(int n = 0; n < data->NumPart; n++) {
|
for(int n = 0; n < data->NumPart; n++) {
|
||||||
|
|
2
external/cosmotool/src/loadGadget.hpp
vendored
2
external/cosmotool/src/loadGadget.hpp
vendored
|
@ -1,5 +1,5 @@
|
||||||
/*+
|
/*+
|
||||||
This is CosmoTool (./src/loadGadget.hpp) -- Copyright (C) Guilhem Lavaux (2007-2013)
|
This is CosmoTool (./src/loadGadget.hpp) -- Copyright (C) Guilhem Lavaux (2007-2014)
|
||||||
|
|
||||||
guilhem.lavaux@gmail.com
|
guilhem.lavaux@gmail.com
|
||||||
|
|
||||||
|
|
76
external/cosmotool/src/loadSimu.hpp
vendored
76
external/cosmotool/src/loadSimu.hpp
vendored
|
@ -1,5 +1,5 @@
|
||||||
/*+
|
/*+
|
||||||
This is CosmoTool (./src/loadSimu.hpp) -- Copyright (C) Guilhem Lavaux (2007-2013)
|
This is CosmoTool (./src/loadSimu.hpp) -- Copyright (C) Guilhem Lavaux (2007-2014)
|
||||||
|
|
||||||
guilhem.lavaux@gmail.com
|
guilhem.lavaux@gmail.com
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ knowledge of the CeCILL license and that you accept its terms.
|
||||||
#ifndef __COSMOTOOLBOX_HPP
|
#ifndef __COSMOTOOLBOX_HPP
|
||||||
#define __COSMOTOOLBOX_HPP
|
#define __COSMOTOOLBOX_HPP
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -45,6 +46,8 @@ namespace CosmoTool
|
||||||
static const int NEED_POSITION = 2;
|
static const int NEED_POSITION = 2;
|
||||||
static const int NEED_VELOCITY = 4;
|
static const int NEED_VELOCITY = 4;
|
||||||
static const int NEED_TYPE = 8;
|
static const int NEED_TYPE = 8;
|
||||||
|
static const int NEED_MASS = 16;
|
||||||
|
static const int NEED_DOUBLE_PRECISION = 32;
|
||||||
|
|
||||||
struct SimuParticle
|
struct SimuParticle
|
||||||
{
|
{
|
||||||
|
@ -64,6 +67,8 @@ namespace CosmoTool
|
||||||
typedef void (*FreeFunction)(void *);
|
typedef void (*FreeFunction)(void *);
|
||||||
typedef std::map<std::string, std::pair<void *, FreeFunction> > AttributeMap;
|
typedef std::map<std::string, std::pair<void *, FreeFunction> > AttributeMap;
|
||||||
|
|
||||||
|
bool noAuto;
|
||||||
|
|
||||||
float BoxSize;
|
float BoxSize;
|
||||||
float time;
|
float time;
|
||||||
float Hubble;
|
float Hubble;
|
||||||
|
@ -71,59 +76,60 @@ namespace CosmoTool
|
||||||
float Omega_M;
|
float Omega_M;
|
||||||
float Omega_Lambda;
|
float Omega_Lambda;
|
||||||
|
|
||||||
long NumPart;
|
ssize_t NumPart;
|
||||||
long TotalNumPart;
|
ssize_t TotalNumPart;
|
||||||
long *Id;
|
long *Id;
|
||||||
float *Pos[3];
|
float *Pos[3];
|
||||||
float *Vel[3];
|
float *Vel[3];
|
||||||
|
float *Mass;
|
||||||
int *type;
|
int *type;
|
||||||
|
|
||||||
AttributeMap attributes;
|
AttributeMap attributes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SimuData() : Id(0),NumPart(0),type(0) { Pos[0]=Pos[1]=Pos[2]=0; Vel[0]=Vel[1]=Vel[2]=0; }
|
SimuData() : Mass(0), Id(0),NumPart(0),type(0),noAuto(false) { Pos[0]=Pos[1]=Pos[2]=0; Vel[0]=Vel[1]=Vel[2]=0; }
|
||||||
~SimuData()
|
~SimuData()
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 3; j++)
|
if (!noAuto) {
|
||||||
{
|
for (int j = 0; j < 3; j++) {
|
||||||
if (Pos[j])
|
if (Pos[j])
|
||||||
delete[] Pos[j];
|
delete[] Pos[j];
|
||||||
if (Vel[j])
|
if (Vel[j])
|
||||||
delete[] Vel[j];
|
delete[] Vel[j];
|
||||||
}
|
}
|
||||||
if (type)
|
if (type)
|
||||||
delete[] type;
|
delete[] type;
|
||||||
if (Id)
|
if (Id)
|
||||||
delete[] Id;
|
delete[] Id;
|
||||||
|
if (Mass)
|
||||||
for (AttributeMap::iterator i = attributes.begin();
|
delete[] Mass;
|
||||||
i != attributes.end();
|
}
|
||||||
++i)
|
for (AttributeMap::iterator i = attributes.begin();
|
||||||
{
|
i != attributes.end();
|
||||||
if (i->second.second)
|
++i) {
|
||||||
i->second.second(i->second.first);
|
if (i->second.second)
|
||||||
}
|
i->second.second(i->second.first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T *as(const std::string& n)
|
T *as(const std::string& n)
|
||||||
{
|
{
|
||||||
AttributeMap::iterator i = attributes.find(n);
|
AttributeMap::iterator i = attributes.find(n);
|
||||||
if (i == attributes.end())
|
if (i == attributes.end())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return reinterpret_cast<T *>(i->second.first);
|
return reinterpret_cast<T *>(i->second.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
void new_attribute(const std::string& n, void *p, FreeFunction free_func)
|
void new_attribute(const std::string& n, void *p, FreeFunction free_func)
|
||||||
{
|
{
|
||||||
AttributeMap::iterator i = attributes.find(n);
|
AttributeMap::iterator i = attributes.find(n);
|
||||||
if (i != attributes.end())
|
if (i != attributes.end()) {
|
||||||
{
|
if (i->second.second)
|
||||||
if (i->second.second)
|
i->second.second(i->second.first);
|
||||||
i->second.second(i->second.first);
|
}
|
||||||
}
|
attributes[n] = std::make_pair(p, free_func);
|
||||||
attributes[n] = std::make_pair(p, free_func);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
8
external/cosmotool/src/load_data.hpp
vendored
8
external/cosmotool/src/load_data.hpp
vendored
|
@ -1,5 +1,5 @@
|
||||||
/*+
|
/*+
|
||||||
This is CosmoTool (./src/load_data.hpp) -- Copyright (C) Guilhem Lavaux (2007-2013)
|
This is CosmoTool (./src/load_data.hpp) -- Copyright (C) Guilhem Lavaux (2007-2014)
|
||||||
|
|
||||||
guilhem.lavaux@gmail.com
|
guilhem.lavaux@gmail.com
|
||||||
|
|
||||||
|
@ -55,7 +55,11 @@ namespace CosmoTool {
|
||||||
double Omega0;
|
double Omega0;
|
||||||
double OmegaLambda;
|
double OmegaLambda;
|
||||||
double HubbleParam;
|
double HubbleParam;
|
||||||
char fill[256- 6*4- 6*8- 2*8- 2*4- 6*4- 2*4 - 4*8]; /* fills to 256 Bytes */
|
int flag_doubleprecision;
|
||||||
|
int flag_ic_info;
|
||||||
|
float lpt_scalingfactor;
|
||||||
|
char fill[18]; /*!< fills to 256 Bytes */
|
||||||
|
char names[15][2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParticleState
|
struct ParticleState
|
||||||
|
|
2
external/external_build.cmake
vendored
2
external/external_build.cmake
vendored
|
@ -241,6 +241,8 @@ ExternalProject_Add(cosmotool
|
||||||
-DNETCDF_LIBRARY=${NETCDF_LIBRARY}
|
-DNETCDF_LIBRARY=${NETCDF_LIBRARY}
|
||||||
-DNETCDFCPP_LIBRARY=${NETCDFCPP_LIBRARY}
|
-DNETCDFCPP_LIBRARY=${NETCDFCPP_LIBRARY}
|
||||||
-DENABLE_SHARP=OFF
|
-DENABLE_SHARP=OFF
|
||||||
|
-DBOOST_INCLUDEDIR=${Boost_INCLUDE_DIRS}
|
||||||
|
|
||||||
)
|
)
|
||||||
SET(COSMOTOOL_LIBRARY ${CMAKE_BINARY_DIR}/ext_build/cosmotool/lib/libCosmoTool.a)
|
SET(COSMOTOOL_LIBRARY ${CMAKE_BINARY_DIR}/ext_build/cosmotool/lib/libCosmoTool.a)
|
||||||
set(COSMOTOOL_INCLUDE_PATH ${CMAKE_BINARY_DIR}/ext_build/cosmotool/include)
|
set(COSMOTOOL_INCLUDE_PATH ${CMAKE_BINARY_DIR}/ext_build/cosmotool/include)
|
||||||
|
|
|
@ -165,6 +165,8 @@ def launchGenerate(sample, binPath, workDir=None, inputDataDir=None,
|
||||||
dataFileLine = "multidark " + datafile
|
dataFileLine = "multidark " + datafile
|
||||||
elif sample.dataFormat == "gadget":
|
elif sample.dataFormat == "gadget":
|
||||||
dataFileLine = "gadget " + datafile
|
dataFileLine = "gadget " + datafile
|
||||||
|
elif sample.dataFormat == "gadget2":
|
||||||
|
dataFileLine = "gadget2 " + datafile
|
||||||
elif sample.dataFormat == "ahf":
|
elif sample.dataFormat == "ahf":
|
||||||
dataFileLine = "gadget " + datafile
|
dataFileLine = "gadget " + datafile
|
||||||
elif sample.dataFormat == "sdf":
|
elif sample.dataFormat == "sdf":
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue