12#include "gadgetconfig.h"
16#include <gsl/gsl_rng.h>
27#include "../data/allvars.h"
28#include "../data/dtypes.h"
29#include "../data/mymalloc.h"
30#include "../fof/fof.h"
31#include "../io/hdf5_util.h"
33#include "../logs/timer.h"
34#include "../main/simulation.h"
35#include "../mergertree/io_halotrees.h"
36#include "../mergertree/mergertree.h"
37#include "../mpi_utils/mpi_utils.h"
38#include "../sort/parallel_sort.h"
39#include "../subfind/subfind.h"
40#include "../system/system.h"
42halotrees_io::halotrees_io(mergertree *MergerTree_ptr, MPI_Comm comm,
int format) :
IO_Def(comm, format)
44 MergerTree = MergerTree_ptr;
46 this->N_IO_Fields = 0;
47 this->N_DataGroups = 3;
48 this->header_size =
sizeof(header);
49 this->header_buf = &header;
51 sprintf(this->info,
"MERGERTREE: writing mergertrees");
55 init_field(
"MTRL",
"Length",
MEM_INT,
FILE_INT,
SKIP_ON_READ, 1,
A_TT, &MergerTree->TreeTable[0].HaloCount, NULL,
TREELENGTH, 0, 0,
59 init_field(
"MTRI",
"TreeID",
MEM_INT64,
FILE_INT64,
SKIP_ON_READ, 1,
A_TT, &MergerTree->TreeTable[0].TreeID, NULL,
TREELENGTH, 0, 0,
66 init_field(
"TDES",
"TreeDescendant",
MEM_INT,
FILE_INT,
SKIP_ON_READ, 1,
A_H, &MergerTree->Halos[0].TreeDescendant, NULL,
TREEHALOS,
67 0, 0, 0, 0, 0, 0, 0,
true);
73 NULL,
TREEHALOS, 0, 0, 0, 0, 0, 0, 0,
true);
76 init_field(
"TPRO",
"TreeProgenitor",
MEM_INT,
FILE_INT,
SKIP_ON_READ, 1,
A_H, &MergerTree->Halos[0].TreeProgenitor, NULL,
TREEHALOS,
77 0, 0, 0, 0, 0, 0, 0,
true);
102 &MergerTree->Halos[0].SubProp.SubHalfMassRad, NULL,
TREEHALOS, 0, 0, 0, 0, 0, 0, 0);
106 &MergerTree->Halos[0].SubProp.SubMostBoundID, NULL,
TREEHALOS, 0, 0, 0, 0, 0, 0, 0,
true);
110 init_field(
"TSNP",
"SnapNum",
MEM_INT,
FILE_INT,
SKIP_ON_READ, 1,
A_H, &MergerTree->Halos[0].SnapNum, NULL,
TREEHALOS, 0, 0, 0, 0, 0,
112 init_field(
"TSNR",
"SubhaloNr",
MEM_INT64,
FILE_INT64,
SKIP_ON_READ, 1,
A_H, &MergerTree->Halos[0].SubhaloNr, NULL,
TREEHALOS, 0, 0,
113 0, 0, 0, 0, 0,
true);
114 init_field(
"GRNR",
"GroupNr",
MEM_INT64,
FILE_INT64,
SKIP_ON_READ, 1,
A_H, &MergerTree->Halos[0].GroupNr, NULL,
TREEHALOS, 0, 0, 0,
119 init_field(
"TRID",
"TreeID",
MEM_INT64,
FILE_INT64,
SKIP_ON_READ, 1,
A_H, &MergerTree->Halos[0].TreeID, NULL,
TREEHALOS, 0, 0, 0, 0,
121 init_field(
"TRIX",
"TreeIndex",
MEM_INT,
FILE_INT,
SKIP_ON_READ, 1,
A_H, &MergerTree->Halos[0].TreeIndex, NULL,
TREEHALOS, 0, 0, 0,
126 init_field(
"REDS",
"Redshift",
MEM_DOUBLE,
FILE_DOUBLE,
SKIP_ON_READ, 1,
A_CT, &MergerTree->CatTimes[0].Redshift, NULL,
TREETIMES, 0,
129 init_field(
"OUTT",
"Time",
MEM_DOUBLE,
FILE_DOUBLE,
SKIP_ON_READ, 1,
A_CT, &MergerTree->CatTimes[0].Time, NULL,
TREETIMES, 0, 0, 0,
133void halotrees_io::halotrees_save_trees(
void)
145 MPI_Barrier(Communicator);
156void halotrees_io::fill_file_header(
int writeTask,
int lastTask,
long long *n_type,
long long *ntot_type)
160 n_type[0] = MergerTree->Ntrees;
161 n_type[1] = MergerTree->Nhalos;
162 if(ThisTask == writeTask)
163 n_type[2] = MergerTree->LastSnapShotNr + 1;
167 if(ThisTask == writeTask)
169 for(
int n = 0; n < N_DataGroups; n++)
170 ntot_type[n] = n_type[n];
172 for(
int task = writeTask + 1; task <= lastTask; task++)
174 long long nn[N_DataGroups];
175 MPI_Recv(&nn[0], N_DataGroups, MPI_LONG_LONG, task,
TAG_LOCALN, Communicator, MPI_STATUS_IGNORE);
176 for(
int n = 0; n < N_DataGroups; n++)
177 ntot_type[n] += nn[n];
180 for(
int task = writeTask + 1; task <= lastTask; task++)
181 MPI_Send(&ntot_type[0], N_DataGroups, MPI_LONG_LONG, task,
TAG_N, Communicator);
185 MPI_Send(&n_type[0], N_DataGroups, MPI_LONG_LONG, writeTask,
TAG_LOCALN, Communicator);
186 MPI_Recv(&ntot_type[0], N_DataGroups, MPI_LONG_LONG, writeTask,
TAG_N, Communicator, MPI_STATUS_IGNORE);
190 header.Ntrees = ntot_type[0];
191 header.Nhalos = ntot_type[1];
193 header.TotNtrees = MergerTree->TotNtrees;
194 header.TotNhalos = MergerTree->TotNhalos;
196 header.lastsnapshotnr = MergerTree->LastSnapShotNr;
201void halotrees_io::write_header_fields(hid_t handle)
214int halotrees_io::get_filenr_from_header(
void) {
return header.num_files; }
216void halotrees_io::set_filenr_in_header(
int numfiles) { header.num_files = numfiles; }
218void halotrees_io::read_increase_numbers(
int type,
int n_for_this_task)
223 MergerTree->Ntrees += n_for_this_task;
226 MergerTree->Nhalos += n_for_this_task;
229 MergerTree->CatTimes += n_for_this_task;
238void halotrees_io::read_file_header(
const char *fname,
int filenr,
int readTask,
int lastTask,
long long *n_type,
long long *ntot_type,
241 if(ThisTask == readTask)
243 if(filenr == 0 && nstart == NULL)
246 "\nREAD-TREES: filenr=%d, '%s' contains %lld trees out of a total of %lld, and %lld halos out of a total of %lld\n",
247 filenr, fname, header.Ntrees, header.TotNtrees, header.Nhalos, header.TotNhalos);
251 if(MergerTree->TotNtrees == 0)
253 MergerTree->TotNtrees = header.TotNtrees;
254 MergerTree->TotNhalos = header.TotNhalos;
257 for(
int k = 0; k < 2; k++)
258 n_type[k] = ntot_type[k] = 0;
261 ntot_type[0] = header.Ntrees;
262 long long n_in_file = header.Ntrees;
263 int ntask = lastTask - readTask + 1;
264 int n_for_this_task = n_in_file / ntask;
265 if((ThisTask - readTask) < (n_in_file % ntask))
267 n_type[0] = n_for_this_task;
270 memmove(&MergerTree->TreeTable[n_for_this_task], &MergerTree->TreeTable[0], MergerTree->Ntrees *
sizeof(
halotrees_table));
274 ntot_type[1] = header.Nhalos;
275 long long n_in_file = header.Nhalos;
276 int ntask = lastTask - readTask + 1;
277 int n_for_this_task = n_in_file / ntask;
278 if((ThisTask - readTask) < (n_in_file % ntask))
280 n_type[1] = n_for_this_task;
283 memmove(&MergerTree->Halos[n_for_this_task], &MergerTree->Halos[0], MergerTree->Nhalos *
sizeof(treehalo_type));
290void halotrees_io::read_header_fields(
const char *fname)
292 memset(&header, 0,
sizeof(header));
294 hid_t hdf5_file =
my_H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
295 hid_t handle =
my_H5Gopen(hdf5_file,
"/Header");
311void halotrees_io::get_datagroup_name(
int type,
char *buf)
316 sprintf(buf,
"/TreeTable");
319 sprintf(buf,
"/TreeHalos");
322 sprintf(buf,
"/TreeTimes");
330int halotrees_io::get_type_of_element(
int index)
336void halotrees_io::set_type_of_element(
int index,
int type)
340void *halotrees_io::get_base_address_of_structure(
enum arrays array,
int index)
345 return (
void *)(MergerTree->TreeTable + index);
347 return (
void *)(MergerTree->Halos + index);
349 return (
void *)(MergerTree->CatTimes + index);
351 Terminate(
"strange, we don't expect to get here");
global_data_all_processes All
#define MAXLEN_PATH_EXTRA
hid_t my_H5Gopen(hid_t loc_id, const char *groupname)
hid_t my_H5Fopen(const char *fname, unsigned int flags, hid_t fapl_id)
herr_t my_H5Gclose(hid_t group_id, const char *groupname)
herr_t my_H5Fclose(hid_t file_id, const char *fname)
void write_scalar_attribute(hid_t handle, const char *attr_name, const void *buf, hid_t mem_type_id)
void read_scalar_attribute(hid_t handle, const char *attr_name, void *buf, hid_t mem_type_id)
const types_in_memory mem_len_type
const types_in_file file_len_type
char OutputDir[MAXLEN_PATH]