45 finh.read((
char *)&intvar,
sizeof(intvar));
47 finh.read((
char *)&intvar,
sizeof(intvar));
49 finh.read((
char *)&intvar,
sizeof(intvar));
53 finh.read((
char *)&longvar,
sizeof(longvar));
55 finh.read((
char *)&intvar,
sizeof(intvar));
57 finh.read((
char *)&intvar,
sizeof(intvar));
59 finh.read((
char *)&intvar,
sizeof(intvar));
87 for (
int i=0; i<40; i++) temp.
la[i] =
ShortSwap(header.
la[i]);
112 finr.read((
char *)&m_blockheader,
sizeof(m_blockheader));
113 if (swap) m_blockheader =
IntSwap(m_blockheader);
119 finr.read((
char *)&check,
sizeof(check));
120 if (swap) check =
IntSwap(check);
121 if (check != m_blockheader)
ErrorCBL(
"block-headers of gadget snapshot do not match!",
"m_check_it_in",
"GadgetCatalogue.cpp");
126 cbl::catalogue::Catalogue::Catalogue (
const ObjectType objectType,
const std::string file_cn,
const bool snapformat,
const bool swap,
const double fact,
const bool read_catalogue,
const double nSub,
const std::string component_to_read,
const std::vector<std::vector<double>> edges)
128 std::string gdgt_head = file_cn+
".0";
129 std::ifstream finhead(gdgt_head.c_str(), std::ios::binary|std::ios::in);
checkIO(finhead, gdgt_head);
130 finhead.seekg(finhead.beg);
137 m_check_it_in(finhead, swap);
139 std::string stringvar;
140 for (
int i=0; i<4; i++) {
141 finhead.read((
char *)&charvar,
sizeof(charvar));
142 stringvar.push_back(charvar);
145 finhead.read((
char *)&intvar,
sizeof(intvar));
146 m_check_it_out(finhead, swap);
149 m_check_it_in(finhead,swap);
151 finhead.read((
char *)&header,
sizeof(header));
152 if (swap) header = m_swap_header(header);
153 m_check_it_out(finhead, swap);
154 finhead.clear(); finhead.close();
156 std::vector<std::string> components_name = {
"Gas",
"Halo",
"Disk",
"Bulge",
"Stars",
"Boundary"};
159 coutCBL <<
"------- Total Particles -------" << std::endl << std::endl;
162 coutCBL <<
"------- Mass Resolution -------" << std::endl << std::endl;
163 for (
int i = 0; i<6; i++)
if (header.
massarr[i] != 0)
coutCBL << components_name[i]+
": " << header.
massarr[i] <<
"" << std::endl;
165 coutCBL <<
"Age (normalized): " << header.
time << std::endl;
167 coutCBL <<
"Box Size: " << header.
boxsize <<
" kpc/h" << std::endl;
172 coutCBL <<
"Snapshot divided in " << header.
nfiles <<
" files." << std::endl;
175 if (read_catalogue) {
178 std::default_random_engine gen;
179 std::uniform_real_distribution<float> ran(0., 1.);
181 float num_float1, num_float2, num_float3;
182 for (
int i = 0; i<header.
nfiles; i++) {
184 std::ifstream finsnap(gdgt_snap.c_str(), std::ios::binary);
checkIO(finsnap, gdgt_snap);
185 coutCBL <<
"Reading file " << i+1 <<
" of " << header.
nfiles <<
" ..." << std::endl;
189 m_check_it_in(finsnap, swap);
191 std::string stringvar;
192 for (
int i=0; i<4; i++) {
193 finsnap.read((
char *)&charvar,
sizeof(charvar));
194 stringvar.push_back(charvar);
197 finsnap.read((
char *)&intvar,
sizeof(intvar));
198 m_check_it_out(finsnap, swap);
202 m_check_it_in(finsnap,swap);
203 finsnap.read((
char *)&data,
sizeof(data));
204 if (swap) data = m_swap_header(data);
205 m_check_it_out(finsnap,swap);
208 for (
int j = 0; j < 6; j++) dimsnap += data.
npart[j];
209 std::vector<bool> read (dimsnap,
false);
210 if (component_to_read ==
"ALL") std::replace(read.begin(), read.end(),
false,
true);
213 bool wrong_component_name =
true;
214 for (
size_t jj = 0; jj<components_name.size(); jj++) {
215 if (component_to_read == components_name[jj]) std::replace(read.begin()+offset,
216 read.begin()+offset+data.
npart[jj],
218 offset += data.
npart[jj];
219 if (component_to_read == components_name[jj]) wrong_component_name =
false;
221 if (wrong_component_name)
WarningMsgCBL(
"selected component is not available, available components are ALL, Gas, Halo, Disk, Bulge, Stars, Boundary",
"Catalogue",
"GadgetCatalogue.cpp");
222 if (offset != dimsnap)
ErrorCBL(
"something horrible happened...",
"Catalogue",
"GadgetCatalogue.cpp");
229 m_check_it_in(finsnap, swap);
231 std::string stringvar;
232 for (
int i=0; i<4; i++) {
233 finsnap.read((
char *)&charvar,
sizeof(charvar));
234 stringvar.push_back(charvar);
237 finsnap.read((
char *)&intvar,
sizeof(intvar));
238 m_check_it_out(finsnap, swap);
240 m_check_it_in(finsnap,swap);
241 for (
int h = 0; h<dimsnap; h++) {
242 comovingCoordinates coords;
243 finsnap.read((
char *)&num_float1,
sizeof(num_float1));
244 if (swap) num_float1 =
FloatSwap(num_float1);
245 coords.xx=(num_float1)*fact;
246 finsnap.read((
char *)&num_float2,
sizeof(num_float2));
247 if (swap) num_float2 =
FloatSwap(num_float2);
248 coords.yy=(num_float2)*fact;
249 finsnap.read((
char *)&num_float3,
sizeof(num_float3));
250 if (swap) num_float3 =
FloatSwap(num_float3);
251 coords.zz=(num_float3)*fact;
255 if (ran(gen)<nSub && coords.xx>edges[0][0] && coords.xx<edges[0][1] &&
256 coords.yy>edges[1][0] && coords.yy<edges[1][1] &&
257 coords.zz>edges[2][0] && coords.zz<edges[2][1] ) m_object.push_back(move(Object::Create(objectType, coords)));
260 if (ran(gen)<nSub) m_object.push_back(move(Object::Create(objectType, coords)));
263 m_check_it_out(finsnap,swap);
264 finsnap.clear(); finsnap.close();
268 else WarningMsgCBL(
"the catalogue is empty!",
"Catalogue",
"GadgetCatalogue.cpp");
274 cbl::catalogue::Catalogue::Catalogue (
const int snap,
const std::string basedir,
const bool swap,
const bool long_ids,
const double scaleFact,
const double massFact,
const EstimateCriterion estimate_crit,
const bool veldisp,
const bool masstab,
const bool add_satellites,
const bool verbose)
279 while (snap_str.size()!= 3) snap_str =
"0"+snap_str;
280 std::string file_base = basedir+
"/groups_"+snap_str+
"/subhalo_tab_"+snap_str+
".";
287 size_t NG=0, totNG=0, Nfiles=0, NS=0, totNS=0;
288 std::vector<std::shared_ptr<Object>> groups, subgroups;
289 unsigned int count_G = 0, count_S = 0;
291 unsigned int filenum = 0;
292 bool doneflag =
false;
296 std::string current_file = file_base +
conv(filenum,
par::fINT);
297 std::ifstream fincur (current_file.c_str(), std::ifstream::binary);
checkIO(fincur, current_file);
308 Nfiles = header.
Ntask;
311 coutCBL <<
"Building catalogue " << std::setprecision(2) << std::setiosflags(std::ios::fixed) << std::setw(8) << 100.*(filenum+1)/Nfiles <<
" % done \r"; std::cout.flush();
315 fincur.seekg(
sizeof(uint32_t)*NG, fincur.cur);
316 fincur.seekg(
sizeof(uint32_t)*NG, fincur.cur);
318 std::vector<float> vec_tot_mass;
321 std::vector<std::vector<float>> vec_pos;
322 for (
size_t ii = 0; ii < (size_t) NG; ii++) {
323 std::vector<float> pos;
325 vec_pos.push_back(pos);
328 std::vector<float> vec_mass_estimate, vec_radius_estimate, vec_veldisp_estimate;
330 switch (estimate_crit) {
332 case EstimateCriterion::_m200_:
335 fincur.seekg(
sizeof(
float)*4*NG, fincur.cur);
338 fincur.seekg(
sizeof(
float)*2*NG, fincur.cur);
342 case EstimateCriterion::_c200_:
343 fincur.seekg(
sizeof(
float)*2*NG, fincur.cur);
346 fincur.seekg(
sizeof(
float)*2*NG, fincur.cur);
348 fincur.seekg(
sizeof(
float)*NG, fincur.cur);
350 fincur.seekg(
sizeof(
float)*NG, fincur.cur);
354 case EstimateCriterion::_t200_:
355 fincur.seekg(
sizeof(
float)*4*NG, fincur.cur);
359 fincur.seekg(
sizeof(
float)*2*NG, fincur.cur);
365 ErrorCBL(
"wrong estimate criterion selected; available criteria are: _m200_, _c200_ and _t200_",
"Catalogue",
"GadgetCatalogue.cpp");
368 fincur.seekg(
sizeof(uint32_t)*NG, fincur.cur);
369 fincur.seekg(
sizeof(
float)*NG, fincur.cur);
371 std::vector<uint32_t> vec_nsubs;
374 fincur.seekg(
sizeof(uint32_t)*NG, fincur.cur);
377 size_t offset = groups.size();
378 if (verbose)
coutCBL <<
"Current dimension of catalogue: " << offset << std::endl;
379 for (
size_t ii = offset; ii < offset+(size_t)NG; ii++) {
382 comovingCoordinates coords = {scaleFact*vec_pos[ii-offset][0],
383 scaleFact*vec_pos[ii-offset][1],
384 scaleFact*vec_pos[ii-offset][2]};
385 groups.push_back(move(Object::Create(ObjectType::_HostHalo_, coords)));
388 groups[ii]->set_tot_mass(massFact*vec_tot_mass[ii-offset]);
391 groups[ii]->set_mass(massFact*vec_tot_mass[ii-offset]);
392 groups[ii]->set_mass_estimate(massFact*vec_mass_estimate[ii-offset]);
393 groups[ii]->set_radius_estimate(scaleFact*vec_radius_estimate[ii-offset]);
394 if (veldisp) groups[ii]->set_veldisp_estimate(vec_veldisp_estimate[ii-offset]);
395 groups[ii]->set_ID((
int) ii);
396 groups[ii]->set_nsub((
int) vec_nsubs[ii-offset]);
397 groups[ii]->set_parent(-1);
405 fincur.seekg(
sizeof(uint32_t)*NS, fincur.cur);
406 fincur.seekg(
sizeof(uint32_t)*NS, fincur.cur);
407 fincur.seekg(
sizeof(uint32_t)*NS, fincur.cur);
409 std::vector<float> vec_sub_mass;
412 std::vector<std::vector<float>> vec_sub_pos;
414 for (
size_t ii = 0; ii<NS; ii++) {
415 std::vector<float> vec;
417 vec_sub_pos.push_back(vec);
420 fincur.seekg(3*
sizeof(
float)*NS, fincur.cur);
422 std::vector<std::vector<float>> vec_sub_cm;
424 for (
size_t ii = 0; ii<NS; ii++) {
425 std::vector<float> vec;
427 vec_sub_cm.push_back(vec);
429 std::vector<std::vector<float>> vec_sub_spin;
431 for (
size_t ii = 0; ii<NS; ii++) {
432 std::vector<float> vec;
434 vec_sub_spin.push_back(vec);
436 std::vector<float> vec_sub_veldisp;
438 std::vector<float> vec_sub_vmax;
440 std::vector<float> vec_sub_vmax_rad;
442 std::vector<float> vec_halfmass_rad;
447 if (!long_ids) fincur.seekg(
sizeof(uint32_t)*NS, fincur.cur);
448 else fincur.seekg(
sizeof(uint64_t)*NS, fincur.cur);
450 std::vector<uint32_t> vec_grnr;
454 fincur.seekg(6*
sizeof(
float)*NS, fincur.cur);
458 size_t offset_sub = subgroups.size();
459 for (
unsigned int jj = offset_sub; jj < offset_sub+NS; jj++) {
462 comovingCoordinates coords = {scaleFact*vec_sub_pos[jj-offset_sub][0],
463 scaleFact*vec_sub_pos[jj-offset_sub][1],
464 scaleFact*vec_sub_pos[jj-offset_sub][2]};
465 subgroups.push_back(move(Object::Create(ObjectType::_HostHalo_, coords)));
468 subgroups[jj]->set_mass(massFact*vec_sub_mass[jj-offset_sub]);
471 subgroups[jj]->set_xcm(scaleFact*vec_sub_cm[jj-offset_sub][0]);
472 subgroups[jj]->set_ycm(scaleFact*vec_sub_cm[jj-offset_sub][1]);
473 subgroups[jj]->set_zcm(scaleFact*vec_sub_cm[jj-offset_sub][2]);
474 subgroups[jj]->set_spin_x(vec_sub_spin[jj-offset_sub][0]);
475 subgroups[jj]->set_spin_y(vec_sub_spin[jj-offset_sub][1]);
476 subgroups[jj]->set_spin_z(vec_sub_spin[jj-offset_sub][2]);
477 subgroups[jj]->set_veldisp(vec_sub_veldisp[jj-offset_sub]);
478 subgroups[jj]->set_vmax(vec_sub_vmax[jj-offset_sub]);
479 subgroups[jj]->set_vmax_rad(vec_sub_vmax_rad[jj-offset_sub]);
480 subgroups[jj]->set_radius(vec_halfmass_rad[jj-offset_sub]);
481 subgroups[jj]->set_ID((
int) jj);
482 subgroups[jj]->set_nsub(-1);
483 subgroups[jj]->set_parent((
int) vec_grnr[jj-offset_sub]);
489 int curpos = fincur.tellg();
490 fincur.seekg(0, fincur.end);
491 if (curpos != fincur.tellg())
WarningMsgCBL(
"finished reading before EOF for file "+current_file,
"Catalogue",
"GadgetCatalogue.cpp");
492 fincur.clear(); fincur.close();
494 if (filenum >= Nfiles) doneflag =
true;
497 if (count_G != totNG)
ErrorCBL(
"groups read do not match expected!",
"Catalogue",
"GadgetCatalogue.cpp");
498 if (count_S != totNS)
ErrorCBL(
"subGroups read do not match expected!",
"Catalogue",
"GadgetCatalogue.cpp");
501 coutCBL <<
"Now sorting sub-groups ..." << std::endl;
502 std::vector<int> parentIDs;
503 for (
size_t ii = 0; ii<subgroups.size(); ii++) parentIDs.push_back(subgroups[ii]->parent());
504 bool bubbleswap =
true;
507 for (
size_t jj = 0; jj<subgroups.size()-1; ++jj) {
508 if (parentIDs[jj] > parentIDs[jj+1]) {
509 int tempVar = parentIDs[jj];
510 parentIDs[jj] = parentIDs[jj+1];
511 parentIDs[jj+1] = tempVar;
512 std::shared_ptr<Object> tempObj = subgroups[jj];
513 subgroups[jj] = subgroups[jj+1];
514 subgroups[jj+1] = tempObj;
519 coutCBL <<
"... done!" << std::endl;
522 for (
size_t ii = 0; ii<groups.size(); ii++) {
524 coutCBL <<
"Identifying centrals and satellites " << std::setprecision(2) << std::setiosflags(std::ios::fixed) << std::setw(8) << 100.*(ii+1)/groups.size() <<
" % done \r"; std::cout.flush();
527 if (groups[ii]->nsub() > 0) {
528 int currentID = groups[ii]->ID();
529 std::pair<std::vector<int>::iterator, std::vector<int>::iterator> bounds = equal_range(parentIDs.begin(),
532 int index = bounds.first - parentIDs.begin();
534 coutCBL <<
"check coordinates: " << std::endl;
536 << groups[ii]->xx() <<
" "
537 << groups[ii]->yy() <<
" "
538 << groups[ii]->zz() << std::endl;
540 << subgroups[index]->xx() <<
" "
541 << subgroups[index]->yy() <<
" "
542 << subgroups[index]->zz() << std::endl;
544 groups[ii]->set_mass(subgroups[index]->mass());
545 groups[ii]->set_xcm(subgroups[index]->xcm());
546 groups[ii]->set_ycm(subgroups[index]->ycm());
547 groups[ii]->set_zcm(subgroups[index]->zcm());
548 groups[ii]->set_spin_x(subgroups[index]->spin_x());
549 groups[ii]->set_spin_y(subgroups[index]->spin_y());
550 groups[ii]->set_spin_z(subgroups[index]->spin_z());
551 groups[ii]->set_veldisp(subgroups[index]->veldisp());
552 groups[ii]->set_vmax(subgroups[index]->vmax());
553 groups[ii]->set_vmax_rad(subgroups[index]->vmax_rad());
554 groups[ii]->set_radius(subgroups[index]->radius());
555 m_object.push_back(groups[ii]);
556 int last_central = m_object.size() -1;
557 for (
int jj = 1; jj < bounds.second - bounds.first; jj++) {
559 index = bounds.first - parentIDs.begin() + jj;
560 subgroups[index]->set_tot_mass(groups[ii]->tot_mass());
561 subgroups[index]->set_mass_estimate(groups[ii]->mass_estimate());
562 subgroups[index]->set_radius_estimate(groups[ii]->radius_estimate());
563 if (veldisp) subgroups[index]->set_veldisp_estimate(groups[ii]->veldisp_estimate());
564 m_object[last_central]->set_satellite(subgroups[index]);
568 if (add_satellites) m_object.push_back(subgroups[index]);
570 if ((
int) m_object[last_central]->satellites().size() != m_object[last_central]->nsub()-1)
571 ErrorCBL(
"number of satellites do not match!",
"Catalogue",
"GadgetCatalogue.cpp");
576 else if (groups[ii]->nsub() == 0) m_object.push_back(groups[ii]);
Useful generic functions.
#define coutCBL
CBL print message.
Catalogue()=default
default constructor
Gadget_Header m_swap_header(Gadget_Header header)
swap endianism of the GADGET snapshot header
SubFindTab_Header m_read_header(std::ifstream &finh, const bool swap=false)
read the GADGET subfind table header
void m_check_it_out(std::ifstream &finr, const bool swap)
Ouput function to check consistency in reading block-headers in binary GADGET snapshots.
void m_check_it_in(std::ifstream &finr, const bool swap)
Input function to check consistency in reading block-headers in binary GADGET snapshots.
static const char fINT[]
conversion symbol for: int -> std::string
static const double defaultDouble
default double value
ObjectType
the object types
EstimateCriterion
method used to estimate mass, radius and velocity of a halo
The global namespace of the CosmoBolognaLib
void vectorReadFromBinary(std::ifstream &fin, std::vector< T > &vec, size_t NN)
reads a vector from a binary file
std::string conv(const T val, const char *fact)
convert a number to a std::string
void checkIO(const std::ifstream &fin, const std::string file="NULL")
check if an input file can be opened
int ErrorCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL, const cbl::glob::ExitCode exitCode=cbl::glob::ExitCode::_error_)
throw an exception: it is used for handling exceptions inside the CosmoBolognaLib
short ShortSwap(const short s)
endian conversion of a short variable
double DoubleSwap(const double d)
endian conversion of a double variable
void WarningMsgCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL)
internal CBL warning message
long long LongSwap(const long long i)
endian conversion of a long integer variable
float FloatSwap(const float f)
endian conversion of a float variable
int IntSwap(const int i)
endian conversion of an integer variable