CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
GadgetCatalogue.cpp
Go to the documentation of this file.
1 /********************************************************************
2  * Copyright (C) 2016 by Federico Marulli, Tommaso Ronconi *
3  * federico.marulli3@unibo.it tommaso.ronconi@studio.unibo.it *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public *
16  * License along with this program; if not, write to the Free *
17  * Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ********************************************************************/
20 
33 #include "Func.h"
34 #include "Catalogue.h"
35 #include "Object.h"
36 #include "Halo.h"
37 #include "HostHalo.h"
38 using namespace cbl;
39 
41 {
43  //int intvar;
44  uint32_t intvar;
45  finh.read((char *)&intvar, sizeof(intvar));
46  header.Ngroups = (swap) ? IntSwap(intvar) : intvar;
47  finh.read((char *)&intvar, sizeof(intvar));
48  header.totNgroups = (swap) ? IntSwap(intvar) : intvar;
49  finh.read((char *)&intvar, sizeof(intvar));
50  header.Nids = (swap) ? IntSwap(intvar) : intvar;
51  //long longvar;
52  uint64_t longvar;
53  finh.read((char *)&longvar, sizeof(longvar));
54  header.totNids = (swap) ? LongSwap(longvar) : longvar;
55  finh.read((char *)&intvar, sizeof(intvar));
56  header.Ntask = (swap) ? IntSwap(intvar) : intvar;
57  finh.read((char *)&intvar, sizeof(intvar));
58  header.Nsubs = (swap) ? IntSwap(intvar) : intvar;
59  finh.read((char *)&intvar, sizeof(intvar));
60  header.totNsubs = (swap) ? IntSwap(intvar) : intvar;
61 
62  return header;
63 }
64 
65 //==============================================================================================
66 
68 {
70  for (int i=0; i<6; i++) temp.npart[i] = IntSwap(header.npart[i]);
71  for (int i=0; i<6; i++) temp.massarr[i] = DoubleSwap(header.massarr[i]);
72  temp.time = DoubleSwap(header.time);
73  temp.redshift = DoubleSwap(header.redshift);
74  temp.flag_sfr = IntSwap(header.flag_sfr);
75  temp.flag_feedback = IntSwap(header.flag_feedback);
76  for (int i=0; i<6; i++) temp.npartTotal[i] = IntSwap(header.npartTotal[i]);
77  temp.flag_cool = IntSwap(header.flag_cool);
78  temp.nfiles = IntSwap(header.nfiles);
79  temp.boxsize = DoubleSwap(header.boxsize);
80  temp.omega0 = DoubleSwap(header.omega0);
81  temp.omegaLambda = DoubleSwap(header.omegaLambda);
82  temp.hubblePar = DoubleSwap(header.hubblePar);
83  temp.flag_stAge = IntSwap(header.flag_stAge);
84  temp.flag_Metals = IntSwap(header.flag_Metals);
85  temp.npart_totHW = IntSwap(header.npart_totHW);
86  temp.flag_entr_ics = IntSwap(header.flag_entr_ics);
87  for (int i=0; i<40; i++) temp.la[i] = ShortSwap(header.la[i]);
88 
89  return temp;
90 }
91 
92 //==============================================================================================
93 
95 {
97  temp.Ngroups = IntSwap(header.Ngroups);
98  temp.totNgroups = IntSwap(header.totNgroups);
99  temp.Nids = IntSwap(header.Nids);
100  temp.totNids = LongSwap(header.totNids);
101  temp.Ntask = IntSwap(header.Ntask);
102  temp.Nsubs = IntSwap(header.Nsubs);
103  temp.totNsubs = IntSwap(header.totNsubs);
104 
105  return temp;
106 }
107 
108 //==============================================================================================
109 
110 void cbl::catalogue::Catalogue::m_check_it_in (std::ifstream& finr, const bool swap)
111 {
112  finr.read((char *)&m_blockheader, sizeof(m_blockheader));
113  if (swap) m_blockheader = IntSwap(m_blockheader);
114 }
115 
116 void cbl::catalogue::Catalogue::m_check_it_out (std::ifstream& finr, const bool swap)
117 {
118  int check;
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");
122 }
123 
124 //==============================================================================================
125 
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)
127 {
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);
131  bool cut=false;
132  if (edges[0][0]!=par::defaultDouble && edges[0][1]!=par::defaultDouble && edges[1][0]!=par::defaultDouble && edges[1][1]!=par::defaultDouble
133  && edges[2][0]!=par::defaultDouble && edges[2][1]!=par::defaultDouble) cut=true;
134 
135  // for snapformat = 2:
136  if (snapformat) {
137  m_check_it_in(finhead, swap);
138  char charvar;
139  std::string stringvar;
140  for (int i=0; i<4; i++) {
141  finhead.read((char *)&charvar, sizeof(charvar));
142  stringvar.push_back(charvar);
143  }
144  int intvar;
145  finhead.read((char *)&intvar, sizeof(intvar));
146  m_check_it_out(finhead, swap);
147  }
148 
149  m_check_it_in(finhead,swap);
150  Gadget_Header header;
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();
155 
156  std::vector<std::string> components_name = {"Gas", "Halo", "Disk", "Bulge", "Stars", "Boundary"};
157 
158  coutCBL<< std::endl;
159  coutCBL << "------- Total Particles -------" << std::endl << std::endl;
160  for (int i = 0; i<6; i++) if (header.npartTotal[i] != 0) coutCBL << components_name[i]+": " << header.npartTotal[i] << std::endl;
161  coutCBL<< 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;
164  coutCBL<< std::endl;
165  coutCBL << "Age (normalized): " << header.time << std::endl;
166  coutCBL << "Redshift: " << header.redshift << std::endl;
167  coutCBL << "Box Size: " << header.boxsize << " kpc/h" << std::endl;
168  coutCBL << "Omega_M,0 = " << header.omega0 << std::endl;
169  coutCBL << "Omega_Lambda = " << header.omegaLambda << std::endl;
170  coutCBL << "h_0 = " << header.hubblePar << std::endl;
171  coutCBL<< std::endl;
172  coutCBL << "Snapshot divided in " << header.nfiles << " files." << std::endl;
173  coutCBL<< std::endl;
174 
175  if (read_catalogue) {
176 
177  // parameters for random numbers used in case nSub!=1
178  std::default_random_engine gen;
179  std::uniform_real_distribution<float> ran(0., 1.);
180 
181  float num_float1, num_float2, num_float3;
182  for (int i = 0; i<header.nfiles; i++) {
183  std::string gdgt_snap = file_cn+"."+conv(i, par::fINT);
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;
186 
187  // for snapformat = 2:
188  if (snapformat) {
189  m_check_it_in(finsnap, swap);
190  char charvar;
191  std::string stringvar;
192  for (int i=0; i<4; i++) {
193  finsnap.read((char *)&charvar, sizeof(charvar));
194  stringvar.push_back(charvar);
195  }
196  int intvar;
197  finsnap.read((char *)&intvar, sizeof(intvar));
198  m_check_it_out(finsnap, swap);
199  }
200 
201  Gadget_Header data;
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);
206 
207  int dimsnap = 0;
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);
211  else {
212  int offset = 0;
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],
217  false, true);
218  offset += data.npart[jj];
219  if (component_to_read == components_name[jj]) wrong_component_name = false;
220  }
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");
223  }
224 
225  // reading particle positions
226 
227  // for snapformat = 2:
228  if (snapformat) {
229  m_check_it_in(finsnap, swap);
230  char charvar;
231  std::string stringvar;
232  for (int i=0; i<4; i++) {
233  finsnap.read((char *)&charvar, sizeof(charvar));
234  stringvar.push_back(charvar);
235  }
236  int intvar;
237  finsnap.read((char *)&intvar, sizeof(intvar));
238  m_check_it_out(finsnap, swap);
239  }
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;
252 
253  if (read[h]) {
254  if (cut) {
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)));
258  }
259  else
260  if (ran(gen)<nSub) m_object.push_back(move(Object::Create(objectType, coords)));
261  }
262  }
263  m_check_it_out(finsnap,swap);
264  finsnap.clear(); finsnap.close();
265  }
266  }//read_catalogue=true
267 
268  else WarningMsgCBL("the catalogue is empty!", "Catalogue", "GadgetCatalogue.cpp"); //read_catalogue=false
269 
270 }
271 
272 //==============================================================================================
273 
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)
275 {
276 
277  // defines the name of the catalogue files
278  std::string snap_str = conv(snap, par::fINT);
279  while (snap_str.size()!= 3) snap_str = "0"+snap_str;
280  std::string file_base = basedir+"/groups_"+snap_str+"/subhalo_tab_"+snap_str+".";
281 
282  //typedef conditional<long_ids,
283  // uint64_t,
284  // uint32_t>::type ids_type;
285 
286  // begin a cicle to read and store data from the group files
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;
290 
291  unsigned int filenum = 0;
292  bool doneflag = false;
293  while (!doneflag) {
294 
295  // try open file and check it works
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);
298 
299  // read file header
300  SubFindTab_Header header = m_read_header(fincur, swap);
301 
302  // store infos from header
303  NG = header.Ngroups;
304  NS = header.Nsubs;
305  if (filenum == 0) {
306  totNG = header.totNgroups;
307  totNS = header.totNsubs;
308  Nfiles = header.Ntask;
309  }
310 
311  coutCBL << "Building catalogue " << std::setprecision(2) << std::setiosflags(std::ios::fixed) << std::setw(8) << 100.*(filenum+1)/Nfiles << " % done \r"; std::cout.flush();
312 
313  if (NG > 0) {
314  // read data blocks, store those necessary
315  fincur.seekg(sizeof(uint32_t)*NG, fincur.cur); // jumps the 'lenght' block
316  fincur.seekg(sizeof(uint32_t)*NG, fincur.cur); // jumps the 'offset' block
317 
318  std::vector<float> vec_tot_mass;
319  vectorReadFromBinary(fincur, vec_tot_mass, NG);
320 
321  std::vector<std::vector<float>> vec_pos;
322  for (size_t ii = 0; ii < (size_t) NG; ii++) {
323  std::vector<float> pos;
324  vectorReadFromBinary(fincur, pos, 3);
325  vec_pos.push_back(pos);
326  }
327 
328  std::vector<float> vec_mass_estimate, vec_radius_estimate, vec_veldisp_estimate;
329 
330  switch (estimate_crit) {
331 
332  case EstimateCriterion::_m200_:
333  vectorReadFromBinary(fincur, vec_mass_estimate, NG);
334  vectorReadFromBinary(fincur, vec_radius_estimate, NG);
335  fincur.seekg(sizeof(float)*4*NG, fincur.cur);
336  if (veldisp) {
337  vectorReadFromBinary(fincur, vec_veldisp_estimate, NG);
338  fincur.seekg(sizeof(float)*2*NG, fincur.cur);
339  }
340  break;
341 
342  case EstimateCriterion::_c200_:
343  fincur.seekg(sizeof(float)*2*NG, fincur.cur);
344  vectorReadFromBinary(fincur, vec_mass_estimate, NG);
345  vectorReadFromBinary(fincur, vec_radius_estimate, NG);
346  fincur.seekg(sizeof(float)*2*NG, fincur.cur);
347  if (veldisp) {
348  fincur.seekg(sizeof(float)*NG, fincur.cur);
349  vectorReadFromBinary(fincur, vec_veldisp_estimate, NG);
350  fincur.seekg(sizeof(float)*NG, fincur.cur);
351  }
352  break;
353 
354  case EstimateCriterion::_t200_:
355  fincur.seekg(sizeof(float)*4*NG, fincur.cur);
356  vectorReadFromBinary(fincur, vec_mass_estimate, NG);
357  vectorReadFromBinary(fincur, vec_radius_estimate, NG);
358  if (veldisp) {
359  fincur.seekg(sizeof(float)*2*NG, fincur.cur);
360  vectorReadFromBinary(fincur, vec_veldisp_estimate, NG);
361  }
362  break;
363 
364  default:
365  ErrorCBL("wrong estimate criterion selected; available criteria are: _m200_, _c200_ and _t200_", "Catalogue", "GadgetCatalogue.cpp");
366  } // endswitch (estimate_crit)
367 
368  fincur.seekg(sizeof(uint32_t)*NG, fincur.cur); // jumps the 'contamination count' block
369  fincur.seekg(sizeof(float)*NG, fincur.cur); // jumps the 'contamination mass' block
370 
371  std::vector<uint32_t> vec_nsubs;
372  vectorReadFromBinary(fincur, vec_nsubs, NG);
373 
374  fincur.seekg(sizeof(uint32_t)*NG, fincur.cur); // end of Group data block
375 
376  // add data to group catalogue:
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++) {
380 
381  // add ii-th object to group catalogue
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)));
386 
387  // set _Halo_ variables of the ii-th object
388  groups[ii]->set_tot_mass(massFact*vec_tot_mass[ii-offset]);
389 
390  // set _HostHalo_ variables of the ii-th object
391  groups[ii]->set_mass(massFact*vec_tot_mass[ii-offset]); // temporarily = to total mass of the halo
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);
398  count_G++;
399  } // endfor (int ii = offset; ii < offset+NG; ii++)
400  } // endif (NG > 0)
401 
402  if (NS > 0) {
403 
404  // read data blocks, store those necessary
405  fincur.seekg(sizeof(uint32_t)*NS, fincur.cur); // jumps the 'lenght' block
406  fincur.seekg(sizeof(uint32_t)*NS, fincur.cur); // jumps the 'offset' block
407  fincur.seekg(sizeof(uint32_t)*NS, fincur.cur); // jumps the 'parent' block
408 
409  std::vector<float> vec_sub_mass;
410  vectorReadFromBinary(fincur, vec_sub_mass, NS); // reads the 'mass' block
411 
412  std::vector<std::vector<float>> vec_sub_pos;
413  // reads the 'pos' block:
414  for (size_t ii = 0; ii<NS; ii++) {
415  std::vector<float> vec;
416  vectorReadFromBinary(fincur, vec, 3);
417  vec_sub_pos.push_back(vec);
418  }
419 
420  fincur.seekg(3*sizeof(float)*NS, fincur.cur); // jumps the 'vel' block
421 
422  std::vector<std::vector<float>> vec_sub_cm;
423  // reads the 'cm' block:
424  for (size_t ii = 0; ii<NS; ii++) {
425  std::vector<float> vec;
426  vectorReadFromBinary(fincur, vec, 3);
427  vec_sub_cm.push_back(vec);
428  }
429  std::vector<std::vector<float>> vec_sub_spin;
430  // reads the 'spin' block:
431  for (size_t ii = 0; ii<NS; ii++) {
432  std::vector<float> vec;
433  vectorReadFromBinary(fincur, vec, 3);
434  vec_sub_spin.push_back(vec);
435  }
436  std::vector<float> vec_sub_veldisp;
437  vectorReadFromBinary(fincur, vec_sub_veldisp, NS); // reads the 'veldisp' block
438  std::vector<float> vec_sub_vmax;
439  vectorReadFromBinary(fincur, vec_sub_vmax, NS); // reads the 'vmax' block
440  std::vector<float> vec_sub_vmax_rad;
441  vectorReadFromBinary(fincur, vec_sub_vmax_rad, NS); // reads the 'vmax_rad' block
442  std::vector<float> vec_halfmass_rad;
443  vectorReadFromBinary(fincur, vec_halfmass_rad, NS); //reads the 'halfmass_rad' block
444  //fincur.seekg(sizeof(float)*NS, fincur.cur); // jumps the 'halfmass_rad' block
445 
446  // jumps the 'ID_most_bound' block:
447  if (!long_ids) fincur.seekg(sizeof(uint32_t)*NS, fincur.cur);
448  else fincur.seekg(sizeof(uint64_t)*NS, fincur.cur);
449 
450  std::vector<uint32_t> vec_grnr;
451  vectorReadFromBinary(fincur, vec_grnr, NS); // reads the 'GrNr' block
452 
453  if (masstab) {
454  fincur.seekg(6*sizeof(float)*NS, fincur.cur); // jumps the 'masstab' block, if present
455  } // endif (masstab)
456 
457  // add data to catalogue:
458  size_t offset_sub = subgroups.size();
459  for (unsigned int jj = offset_sub; jj < offset_sub+NS; jj++) {
460 
461  // add jj-th object to sub-group catalogue
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)));
466 
467  // set _Halo_ variables of the jj-th object
468  subgroups[jj]->set_mass(massFact*vec_sub_mass[jj-offset_sub]);
469 
470  // set _HostHalo_ variables of the jj-th object
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]);
484  count_S++;
485  } // endfor (int jj = offset_sub; jj < offset_sub+NS; jj++)
486  } // endif (NS > 0)
487 
488  // final check
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();
493  filenum ++;
494  if (filenum >= Nfiles) doneflag = true;
495 
496  } // endwhile (!doneflag)
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");
499 
500  // sorting the sub-groups according to their parent ID
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;
505  while (bubbleswap) {
506  bubbleswap = false;
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;
515  bubbleswap = true;
516  }
517  }
518  }
519  coutCBL << "... done!" << std::endl;
520 
521  // building the catalogue with dependencies central/satellite
522  for (size_t ii = 0; ii<groups.size(); ii++) {
523 
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();
525 
526  // groups with sub-groups within are linked to their satellites:
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(),
530  parentIDs.end(),
531  currentID);
532  int index = bounds.first - parentIDs.begin();
533  if (verbose) {
534  coutCBL << "check coordinates: " << std::endl;
535  coutCBL << "\t Central: "
536  << groups[ii]->xx() << " "
537  << groups[ii]->yy() << " "
538  << groups[ii]->zz() << std::endl;
539  coutCBL << "\t Satellite: "
540  << subgroups[index]->xx() << " "
541  << subgroups[index]->yy() << " "
542  << subgroups[index]->zz() << std::endl;
543  }
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]); // adds a central halo to the catalogue.
556  int last_central = m_object.size() -1; // remembers the central index
557  for (int jj = 1; jj < bounds.second - bounds.first; jj++) {
558 
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]);
565  // - if add_satellites = true adds the satellite to the catalogue as an HostHalo object,
566  // - if add_satellites = false, satellites can be only retrieved by the 'satellites'
567  // member of the central HostHalo object:
568  if (add_satellites) m_object.push_back(subgroups[index]);
569  } // endfor jj
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");
572  } // endif (m_object[ii]->nsub() > 0)
573 
574  // groups without sub-groups added as-they-are to the catalogue
575  // [will lack of sub-group properties (e.g. CM coords, Spin, ...)]
576  else if (groups[ii]->nsub() == 0) m_object.push_back(groups[ii]);
577 
578  } //endfor ii
579 
580 }
The class Catalogue
Useful generic functions.
The class Halo.
The class HostHalo.
#define coutCBL
CBL print message.
Definition: Kernel.h:734
The class Object.
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
Definition: Constants.h:121
static const double defaultDouble
default double value
Definition: Constants.h:348
ObjectType
the object types
Definition: Object.h:51
EstimateCriterion
method used to estimate mass, radius and velocity of a halo
Definition: Catalogue.h:499
The global namespace of the CosmoBolognaLib
Definition: CAMB.h:38
void vectorReadFromBinary(std::ifstream &fin, std::vector< T > &vec, size_t NN)
reads a vector from a binary file
Definition: Func.h:867
std::string conv(const T val, const char *fact)
convert a number to a std::string
Definition: Kernel.h:903
void checkIO(const std::ifstream &fin, const std::string file="NULL")
check if an input file can be opened
Definition: Kernel.cpp:160
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
Definition: Kernel.h:780
short ShortSwap(const short s)
endian conversion of a short variable
Definition: Kernel.cpp:45
double DoubleSwap(const double d)
endian conversion of a double variable
Definition: Kernel.cpp:109
void WarningMsgCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL)
internal CBL warning message
Definition: Kernel.h:747
long long LongSwap(const long long i)
endian conversion of a long integer variable
Definition: Kernel.cpp:71
float FloatSwap(const float f)
endian conversion of a float variable
Definition: Kernel.cpp:89
int IntSwap(const int i)
endian conversion of an integer variable
Definition: Kernel.cpp:57
This structure allows to store GADGET header.
Definition: Catalogue.h:561
int nfiles
number of files in each snapshot
Definition: Catalogue.h:588
double time
time of output, or expansion factor for cosmological simulations
Definition: Catalogue.h:570
int flag_entr_ics
flags that the initial conditions contain entropy instead of thermal energy in the u block
Definition: Catalogue.h:612
int flag_cool
flag for cooling (unused)
Definition: Catalogue.h:585
int flag_stAge
creation time of stars (unused)
Definition: Catalogue.h:603
double redshift
z = 1/a-1 (only set for cosmological integrations)
Definition: Catalogue.h:573
int flag_feedback
flag for feedback (unused)
Definition: Catalogue.h:579
double omega0
matter density at z=0 in units of the critical density
Definition: Catalogue.h:594
int npartTotal[6]
total number of particles of each type in the simulation
Definition: Catalogue.h:582
double boxsize
gives the box size if periodic boundary conditions are used
Definition: Catalogue.h:591
short la[40]
currently unused space which fills the header to a total length of 256 bytes leaving room for future ...
Definition: Catalogue.h:615
double omegaLambda
vacuum energy density at z=0 in units of the critical density
Definition: Catalogue.h:597
int flag_Metals
flag for metallicity values (unused)
Definition: Catalogue.h:606
int npart_totHW
internal variable for simulations that use more than 2^32 particles
Definition: Catalogue.h:609
double hubblePar
gives the Hubble constant in units of 100 km/(s Mpc)
Definition: Catalogue.h:600
int npart[6]
the number of particles of each type in the snapshot file
Definition: Catalogue.h:564
int flag_sfr
flag for star formation (unused in the public version of GADGET-2)
Definition: Catalogue.h:576
double massarr[6]
the mass of each particle type
Definition: Catalogue.h:567
This structure allows to store SUBFIND Tab file header.
Definition: Catalogue.h:622
uint64_t totNids
total number of particle IDs
Definition: Catalogue.h:634
uint32_t Nids
number of particle IDs in corresponding file
Definition: Catalogue.h:631
uint32_t totNsubs
total number of subgroups
Definition: Catalogue.h:643
uint32_t Nsubs
number of subgroups in file
Definition: Catalogue.h:640
uint32_t Ngroups
number of groups in file
Definition: Catalogue.h:625
uint32_t Ntask
number of files in which the groups/subgroups are stored
Definition: Catalogue.h:637
uint32_t totNgroups
total number of groups
Definition: Catalogue.h:628