#include #include #include #include #include #include "gravitational_consistency.h" #include "gravitational_consistency_vars.h" #include "halo_io.h" #include "grav_config.h" #include "check_syscalls.h" #include "masses.h" #include "halo_io.h" #include "resort_outputs.h" #include "inthash.h" #include "universe_time.h" #ifndef NO_FORK #include #include #include #endif /* NO_FORK */ #include "version.h" #define forest_id tidal_id #define CRITICAL_DENSITY 2.77459457e11 // 3H^2/8piG in (Msun / h) / (Mpc / h)^3 #define NIFTYOFFSET ((int64_t)1000000000000) //#define FIX_BOLSHOI_SPIN struct halo_stash now={0}, evolved = {0}; int64_t *forest_list = NULL; int64_t num_forests = 0; float box_size=0; float max_mvir=0; float min_mvir=0; int64_t children = 0; void write_ahf_halos(struct halo_stash *h, int64_t onum, float scale); void wait_for_children(int all); int sort_by_forest(const void *a, const void *b); void load_forests(struct halo_stash *h, int64_t onum); void reindex_halos(struct halo_stash *h, int onum); struct id_num { int64_t id, num; }; int main(int argc, char **argv) { int64_t i, j, num_outputs=0; float *output_scales=NULL; int64_t *outputs=NULL; char buffer[1024]; int64_t full_halo_count=0; if (argc==1) { fprintf(stderr, "Consistent Trees, Version %s\n", TREE_VERSION); fprintf(stderr, "%s. See the LICENSE file for redistribution details.\n", TREE_COPYRIGHT); fprintf(stderr, "Usage: %s options.cfg\n", argv[0]); exit(1); } if (argc>1) grav_config(argv[1], 1); read_outputs(&output_scales, &outputs, &num_outputs); gen_ff_cache(); clear_halo_stash(&now); init_time_table(Om, h0); snprintf(buffer, 1024, "%s/really_consistent_%"PRId64".list", OUTBASE, outputs[num_outputs-1]); load_halos(buffer, &now, output_scales[num_outputs-1], 0); reindex_halos(&now, num_outputs-1); build_id_conv_list(&now); load_forests(&now, num_outputs-1); qsort(now.halos, now.num_halos, sizeof(struct tree_halo), sort_by_forest); build_id_conv_list(&now); write_ahf_halos(&now, num_outputs-1, output_scales[num_outputs-1]); snprintf(buffer, sizeof buffer, "%s/sussing_index.lst", TREE_OUTBASE); FILE *sindex = check_fopen(buffer, "w"); fprintf(sindex, "#%11s %12s %12s %12s %12s %s\n", "snapnum", "a", "z", "t(t0)", "t(year)", "file"); double t0 = scale_to_years(0.0); for (i=0; i=0; i--) { clear_halo_stash(&evolved); evolved = now; zero_halo_stash(&now); if (i>0) { snprintf(buffer, 1024, "%s/really_consistent_%"PRId64".list", OUTBASE, outputs[i-1]); load_halos(buffer, &now, output_scales[i-1], 0); reindex_halos(&now, i-1); build_id_conv_list(&now); for (j=0; j -1); now.halos[j].forest_id = evolved.halos[desc_index].forest_id; } qsort(now.halos, now.num_halos, sizeof(struct tree_halo), sort_by_forest); build_id_conv_list(&now); write_ahf_halos(&now, i-1, output_scales[i-1]); } snprintf(buffer, 1024, "%s/sussing_%"PRId64".list", TREE_OUTBASE, i); FILE *output = check_fopen(buffer, "w"); int64_t k=0, last_k=0, l=0, last_l=0; for (j=0; jnum_halos, "Subcounts"); memset(num_subs, 0, sizeof(int64_t)*h->num_halos); int64_t n,i,j; for (i=0; inum_halos; i++) { int64_t upid = i; while (h->halos[upid].upid > -1) upid = id_to_index(*h, h->halos[upid].upid); num_subs[upid]++; } char buffer[1024]; snprintf(buffer, 1024, "%s/sussing_%03"PRId64".z%.3f.AHF_halos", TREE_OUTBASE, onum, 1.0/scale-1.0); FILE *output = check_fopen(buffer, "w"); fprintf(output, "#ID(1) hostHalo(2) numSubStruct(3) M200c(4) npart(5) Xc(6) Yc(7) Zc(8) VXc(9) VYc(10) VZc(11) R200c(12) Rmax(13) r2(14) mbp_offset(15) com_offset(16) Vmax(17) v_esc(18) sigV(19) lambda(20) lambdaE(21) Lx(22) Ly(23) Lz(24) cNFW(25)\n"); float dens = dens_200c(1.0/scale - 1.0)*(4.0*M_PI/3.0); //SUSSING_MASS_FIELD = 3; for (n=0; nnum_halos; n++) { i = n; //sort_order[n]; struct tree_halo *th = h->halos+i; int64_t upid = i; while (h->halos[upid].upid > -1) upid = id_to_index(*h, h->halos[upid].upid); upid = (upid == i) ? 0 : h->halos[upid].id; float L[3] = {0}, Ln=0; float mass = th->mvir; float radius = th->rvir; if (SUSSING_MASS_FIELD > -1) { mass = th->extra_params[SUSSING_MASS_FIELD]; if (!(mass>0)) { convert_mvir_to_delta(th->mvir, th->rvir, th->rs, scale, 200, 'c', &mass, &radius); } radius = cbrt(mass/dens)*1e3; } float spin = th->spin; for (j=0; j<3; j++) Ln+=th->J[j]*th->J[j]; Ln = sqrt(Ln); if (Ln) for (j=0; j<3; j++) L[j] = th->J[j]/Ln; #ifdef FIX_BOLSHOI_SPIN float t_u = th->extra_params[19]; if (fabs(1.0-t_u) != 0) spin *= sqrt(fabs(1.0-t_u*2.0)) / sqrt(fabs(1.0-t_u)); #endif float cNFW = 10; if (th->rs > 0) cNFW = radius / th->rs; fprintf(output, "%"PRId64" %"PRId64" %"PRId64" %e %"PRId64" %.6f %.6f %.6f %f %f %f %f %f 2e38 2e38 2e38 %f 2e38 %f 2e38 %f %f %f %f %f\n", th->id, upid, num_subs[i], mass, th->np, th->pos[0]*1e3, th->pos[1]*1e3, th->pos[2]*1e3, th->vel[0], th->vel[1], th->vel[2], radius, th->rs*2.1626, th->vmax, th->vrms, spin, L[0], L[1], L[2], cNFW); } fclose(output); free(num_subs); } int sort_ascending(const void *a, const void *b) { const int64_t *c = a; const int64_t *d = b; if (*c < *d) return -1; return 1; } void load_forests(struct halo_stash *h, int64_t onum) { int64_t key, val; char buffer[1024]; snprintf(buffer, 1024, "%s/forests.list", TREE_OUTBASE); FILE *input = check_fopen(buffer, "r"); fgets(buffer, 1024, input); //Header struct inthash *forests = new_inthash(); for (key=0; keynum_halos; key++) h->halos[key].forest_id = -1; while (fgets(buffer, 1024, input)) { if (sscanf(buffer, "%"SCNd64" %"SCNd64, &key, &val) != 2) continue; key += NIFTYOFFSET*onum; val += NIFTYOFFSET*onum; int64_t idx = id_to_index(*h, key); assert(idx > -1); h->halos[idx].forest_id = val; ih_setint64(forests, val, 1); } fclose(input); for (key=0; keynum_halos; key++) assert(h->halos[key].forest_id != -1); forest_list = ih_keylist(forests); num_forests = forests->elems; free_inthash(forests); qsort(forest_list, num_forests, sizeof(int64_t), sort_ascending); } inline int64_t id_to_index(struct halo_stash h, int64_t id) { if (id < h.min_id || id > h.max_id) return -1; return (h.id_conv[id-h.min_id]); } int sort_by_forest(const void *a, const void *b) { const struct tree_halo *c = a; //now.halos + *((int64_t *)a); const struct tree_halo *d = b; //now.halos + *((int64_t *)b); if (c->forest_id < d->forest_id) return -1; if (c->forest_id > d->forest_id) return 1; if (c->descid > -1) { assert(d->descid > -1); int64_t c_idx = id_to_index(evolved, c->descid); int64_t d_idx = id_to_index(evolved, d->descid); if (c_idx < d_idx) return -1; if (c_idx > d_idx) return 1; } if (c->mvir > d->mvir) return -1; if (c->mvir < d->mvir) return 1; if (c->vmax > d->vmax) return -1; if (c->vmax < d->vmax) return 1; if (c->id < d->id) return -1; return 1; } void clear_halo_stash(struct halo_stash *h) { if (h->halos) h->halos = (struct tree_halo *)realloc(h->halos, 0); if (h->id_conv) h->id_conv = (int64_t *)realloc(h->id_conv, 0); h->max_id = h->min_id = h->num_halos = 0; } void zero_halo_stash(struct halo_stash *h) { h->halos = 0; h->id_conv = 0; h->max_id = h->min_id = h->num_halos = 0; } void reindex_halos(struct halo_stash *h, int onum) { int64_t n; for (n=0; nnum_halos; n++) { h->halos[n].id += onum*NIFTYOFFSET; if (h->halos[n].upid >= 0) h->halos[n].upid += onum*NIFTYOFFSET; if (h->halos[n].descid >= 0) h->halos[n].descid += (onum+1)*NIFTYOFFSET; } }