double bias_model_BPR_integral(cosmo_info **cosmo, double z) { double z_max = 10000.; interp_info *interp; if(!ADaPS_exist(*cosmo, "bias_model_BPR_Iz_interp")) { int n_int; int i_int; double dz; double Omega_M, Omega_k, Omega_Lambda; double z_temp; double *x_int; double *y_int; double log_z; double dlog_z; n_int = 250; Omega_M = ((double *)ADaPS_fetch(*cosmo, "Omega_M"))[0]; Omega_k = ((double *)ADaPS_fetch(*cosmo, "Omega_k"))[0]; Omega_Lambda = ((double *)ADaPS_fetch(*cosmo, "Omega_Lambda"))[0]; x_int = (double *)SID_malloc(sizeof(double) * n_int); y_int = (double *)SID_malloc(sizeof(double) * n_int); i_int = 0; x_int[i_int] = 0.; y_int[i_int] = pow((1. + x_int[i_int]) / E_z(Omega_M, Omega_k, Omega_Lambda, x_int[i_int]), 3.); i_int++; x_int[i_int] = take_log10(z_max) / (double)(n_int - 1); y_int[i_int] = pow((1. + x_int[i_int]) / E_z(Omega_M, Omega_k, Omega_Lambda, x_int[i_int]), 3.); log_z = take_log10(x_int[i_int]); dlog_z = (take_log10(z_max) - log_z) / (double)(n_int - 2); for(i_int++, log_z += dlog_z; i_int < (n_int - 1); i_int++, log_z += dlog_z) { x_int[i_int] = take_alog10(log_z); y_int[i_int] = pow((1. + x_int[i_int]) / E_z(Omega_M, Omega_k, Omega_Lambda, x_int[i_int]), 3.); } x_int[i_int] = z_max; y_int[i_int] = pow((1. + x_int[i_int]) / E_z(Omega_M, Omega_k, Omega_Lambda, x_int[i_int]), 3.); init_interpolate(x_int, y_int, (size_t)n_int, gsl_interp_cspline, &interp); SID_free(SID_FARG x_int); SID_free(SID_FARG y_int); ADaPS_store_interp(cosmo, (void *)(interp), "bias_model_BPR_Iz_interp"); } else interp = (interp_info *)ADaPS_fetch(*cosmo, "bias_model_BPR_Iz_interp"); return (interpolate_integral(interp, z, z_max)); }
void set_NFW_params(double M, double z, int mode, cosmo_info **cosmo, double *c_vir, double *R_vir){ double M_o; double Delta; double h_Hubble; double Omega_M; if(mode!=NFW_MODE_DEFAULT) SID_trap_error("Unknown mode (%d) in set_NFW_params()",ERROR_LOGIC,mode); switch(ADaPS_exist(*cosmo,"M_WDM")){ case FALSE: { Omega_M =((double *)ADaPS_fetch(*cosmo,"Omega_M"))[0]; h_Hubble=((double *)ADaPS_fetch(*cosmo,"h_Hubble"))[0]; M_o =M_sc(z,cosmo,PSPEC_LINEAR_TF,PSPEC_ALL_MATTER); // Mass-concentration from Munoz-Cuartas et al 2010 //(*c_vir)=(11./(1.+z))*pow(M/M_o,-0.13); // Bullock et al '01 & Zehavi et al '04 double w = 0.029; double m = 0.097; double alpha=-110.001; double beta =2469.720; double gamma= 16.885; double a_z =w*z-m; double b_z =alpha/(z+gamma)+beta/pow(z+gamma,2.); (*c_vir) =take_alog10(a_z*take_log10(M/(M_SOL/h_Hubble))+b_z); Delta =Delta_vir(z,*cosmo); Delta=200.; (*R_vir)=R_Delta_z(M,Delta,z,*cosmo); // Bullock et al '01 } break; case TRUE: SID_trap_error("ENS not working.",ERROR_LOGIC); //(*c_vir)=c_ENS(M,z,*cosmo); // Eke, Navarro and Steinmetz //(*R_vir)=R_Delta_z(M,200.,z,*cosmo); // R_200 break; } }
void init_cfunc(cfunc_info *cfunc,const char *filename_cosmology,int n_data, int n_random,int n_bits_PHK, double redshift, double box_size,int n_jack, double r_min_l1D, double r_max_1D,double dr_1D, double r_min_2D, double r_max_2D,double dr_2D){ SID_log("Initializing correlation function...",SID_LOG_OPEN); // Initialize flags cfunc->initialized =TRUE; cfunc->flag_compute_RR=TRUE; // Initialize constants cfunc->n_data =n_data; cfunc->n_random =n_random; cfunc->F_random =(double)n_random/(double)n_data; cfunc->redshift =redshift; cfunc->box_size =box_size; cfunc->n_jack =n_jack; cfunc->r_min_l1D =r_min_l1D; cfunc->lr_min_l1D=take_log10(r_min_l1D); cfunc->r_max_1D =r_max_1D; cfunc->r_min_2D =r_min_2D; cfunc->r_max_2D =r_max_2D; cfunc->r_max =MAX(cfunc->r_max_1D,cfunc->r_max_2D); cfunc->dr_1D =dr_1D; cfunc->dr_2D =dr_2D; // Decide on PHK boundary widths cfunc->n_bits_PHK=n_bits_PHK; for(cfunc->PHK_width=1;cfunc->PHK_width<20 && (double)cfunc->PHK_width*(cfunc->box_size/pow(2.,(double)(cfunc->n_bits_PHK)))<cfunc->r_max;) cfunc->PHK_width++; // Initialize the number of bins cfunc->n_1D =(int)(0.5+(cfunc->r_max_1D)/cfunc->dr_1D); cfunc->n_2D =(int)(0.5+(cfunc->r_max_2D-cfunc->r_min_2D)/cfunc->dr_2D); cfunc->n_2D_total =cfunc->n_2D*cfunc->n_2D; cfunc->n_jack_total=cfunc->n_jack*cfunc->n_jack*cfunc->n_jack; SID_log("keys =%d-bit", SID_LOG_COMMENT,cfunc->n_bits_PHK); SID_log("boundries =%d keys",SID_LOG_COMMENT,cfunc->PHK_width); SID_log("# of 1D bins=%d", SID_LOG_COMMENT,cfunc->n_1D); SID_log("# of 2D bins=%d", SID_LOG_COMMENT,cfunc->n_2D); // Initialize logarythmic bin sizes cfunc->dr_l1D=(take_log10(cfunc->r_max_1D)-cfunc->lr_min_l1D)/(double)cfunc->n_1D; // Initialize arrays cfunc->CFUNC_l1D =(double **)SID_malloc(sizeof(double *)*4); cfunc->dCFUNC_l1D=(double **)SID_malloc(sizeof(double *)*4); cfunc->COVMTX_l1D=(double **)SID_malloc(sizeof(double *)*4); cfunc->CFUNC_1D =(double **)SID_malloc(sizeof(double *)*4); cfunc->dCFUNC_1D =(double **)SID_malloc(sizeof(double *)*4); cfunc->COVMTX_1D =(double **)SID_malloc(sizeof(double *)*4); cfunc->CFUNC_2D =(double **)SID_malloc(sizeof(double *)*4); cfunc->dCFUNC_2D =(double **)SID_malloc(sizeof(double *)*4); cfunc->COVMTX_2D =(double **)SID_malloc(sizeof(double *)*4); int i_run; for(i_run=0;i_run<4;i_run++){ cfunc->CFUNC_l1D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_1D)); cfunc->dCFUNC_l1D[i_run]=(double *)SID_malloc(sizeof(double)*(cfunc->n_1D)); cfunc->COVMTX_l1D[i_run]=(double *)SID_malloc(sizeof(double)*(cfunc->n_1D*cfunc->n_1D)); cfunc->CFUNC_1D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_1D)); cfunc->dCFUNC_1D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_1D)); cfunc->COVMTX_1D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_1D*cfunc->n_1D)); cfunc->CFUNC_2D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_2D)*(cfunc->n_2D)); cfunc->dCFUNC_2D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_2D)*(cfunc->n_2D)); cfunc->COVMTX_2D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_2D_total*cfunc->n_2D_total)); } cfunc->DD_l1D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->DR_l1D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->RR_l1D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->DD_1D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->DR_1D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->RR_1D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->DD_2D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->DR_2D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->RR_2D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); int i_jack; for(i_jack=0;i_jack<=cfunc->n_jack_total;i_jack++){ cfunc->DD_l1D[i_jack]=(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D); cfunc->DR_l1D[i_jack]=(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D); cfunc->RR_l1D[i_jack]=(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D); cfunc->DD_1D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D); cfunc->DR_1D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D); cfunc->RR_1D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D); cfunc->DD_2D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_2D*cfunc->n_2D); cfunc->DR_2D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_2D*cfunc->n_2D); cfunc->RR_2D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_2D*cfunc->n_2D); } // Initialize the cosmology if(filename_cosmology==NULL) init_cosmo_default(&(cfunc->cosmo)); else read_gbpCosmo_file(&(cfunc->cosmo),filename_cosmology); SID_log("Done.",SID_LOG_CLOSE); }
void average_tree_branches(const char *catalog_name){ SID_log("Processing tree tracks in catalog {%s}...",SID_LOG_OPEN,catalog_name); // Master Rank does all the work FILE *fp_tracks_in=NULL; if(SID.I_am_Master){ // Create and open the output files char filename_tracks_in[MAX_FILENAME_LENGTH]; sprintf(filename_tracks_in,"%s_tracks.dat",catalog_name); SID_log("Processing {%s}...",SID_LOG_OPEN,filename_tracks_in); fp_tracks_in=fopen(filename_tracks_in,"r"); // Write header for tracks file int n_list; int n_snaps; fread_verify(&n_list, sizeof(int),1,fp_tracks_in); fread_verify(&n_snaps,sizeof(int),1,fp_tracks_in); int *snap_list=(int *)SID_malloc(sizeof(int) *n_snaps); double *z_list =(double *)SID_malloc(sizeof(double)*n_snaps); double *t_list =(double *)SID_malloc(sizeof(double)*n_snaps); fread_verify(snap_list,sizeof(int), n_snaps,fp_tracks_in); fread_verify(z_list, sizeof(double),n_snaps,fp_tracks_in); fread_verify(t_list, sizeof(double),n_snaps,fp_tracks_in); // Allocate some temporary arrays for the tracks double M_min = 6.; double M_max =16.; int n_M_bins=200; double dM =(M_max-M_min)/(double)n_M_bins; double inv_dM =1./dM; int **M_hist =(int **)SID_malloc(sizeof(int *)*n_snaps); for(int i_snap=0;i_snap<n_snaps;i_snap++) M_hist[i_snap]=(int *)SID_calloc(sizeof(int)*n_M_bins); int *i_z_track=(int *)SID_malloc(sizeof(int)*n_snaps);; int *idx_track=(int *)SID_malloc(sizeof(int)*n_snaps);; double *M_track =(double *)SID_malloc(sizeof(double)*n_snaps); double *x_track =(double *)SID_malloc(sizeof(double)*n_snaps); double *y_track =(double *)SID_malloc(sizeof(double)*n_snaps); double *z_track =(double *)SID_malloc(sizeof(double)*n_snaps); double *vx_track =(double *)SID_malloc(sizeof(double)*n_snaps); double *vy_track =(double *)SID_malloc(sizeof(double)*n_snaps); double *vz_track =(double *)SID_malloc(sizeof(double)*n_snaps); // Process each track in turn for(int i_list=0;i_list<n_list;i_list++){ int n_track; // Read track fread_verify(&n_track, sizeof(int), 1, fp_tracks_in); fread_verify(i_z_track,sizeof(int), n_track,fp_tracks_in); fread_verify(idx_track,sizeof(int), n_track,fp_tracks_in); fread_verify(x_track, sizeof(double),n_track,fp_tracks_in); fread_verify(y_track, sizeof(double),n_track,fp_tracks_in); fread_verify(z_track, sizeof(double),n_track,fp_tracks_in); fread_verify(vx_track, sizeof(double),n_track,fp_tracks_in); fread_verify(vy_track, sizeof(double),n_track,fp_tracks_in); fread_verify(vz_track, sizeof(double),n_track,fp_tracks_in); fread_verify(M_track, sizeof(double),n_track,fp_tracks_in); // Build the M-histograms for(int i_track=0;i_track<n_track;i_track++){ int i_bin=(int)((take_log10(M_track[i_track])-M_min)*inv_dM); if(i_bin>=0 && i_bin<n_M_bins) M_hist[i_z_track[i_track]][i_bin]++; } } // for i_list fclose(fp_tracks_in); // Build confidence intervals for M-track int *n_i =(int *)SID_calloc(sizeof(int)*n_snaps); double *M_peak =(double *)SID_calloc(sizeof(double)*n_snaps); double *M_68_lo=(double *)SID_calloc(sizeof(double)*n_snaps); double *M_68_hi=(double *)SID_calloc(sizeof(double)*n_snaps); for(int i_snap=0;i_snap<n_snaps;i_snap++){ size_t *M_hist_index=NULL; for(int i_bin=0;i_bin<n_M_bins;i_bin++) n_i[i_snap]+=M_hist[i_snap][i_bin]; if(n_i[i_snap]>0){ merge_sort(M_hist[i_snap],(size_t)n_M_bins,&M_hist_index,SID_INT,SORT_COMPUTE_INDEX,FALSE); int i_peak =M_hist_index[n_M_bins-1]; int i_68_lo=M_hist_index[n_M_bins-1]; int i_68_hi=M_hist_index[n_M_bins-1]; int target =(int)(0.68*(double)n_i[i_snap]); int accum =0; int i_bin =0; while(accum<=target && i_bin<n_M_bins){ size_t idx_i=M_hist_index[n_M_bins-i_bin-1]; if(idx_i<i_68_lo) i_68_lo=idx_i; if(idx_i>i_68_hi) i_68_hi=idx_i; accum+=M_hist[i_snap][idx_i]; i_bin++; } M_peak[i_snap] =M_min+((double)i_peak +0.5)*dM; M_68_lo[i_snap]=M_min+((double)i_68_lo+0.5)*dM; M_68_hi[i_snap]=M_min+((double)i_68_hi+0.5)*dM; SID_free(SID_FARG M_hist_index); } else{ M_peak[i_snap] =-1; M_68_lo[i_snap]=-1; M_68_hi[i_snap]=-1; } } // Write results char filename_out[MAX_FILENAME_LENGTH]; FILE *fp_out; sprintf(filename_out,"%s_tracks.txt",catalog_name); fp_out=fopen(filename_out,"w"); for(int i_snap=0;i_snap<n_snaps;i_snap++) fprintf(fp_out,"%le %le %d %le %le %le\n", z_list[i_snap], t_list[i_snap]/S_PER_YEAR, n_i[i_snap], M_peak[i_snap], M_68_lo[i_snap], M_68_hi[i_snap]); fclose(fp_out); // Clean-up for(int i_snap=0;i_snap<n_snaps;i_snap++) SID_free(SID_FARG M_hist[i_snap]); SID_free(SID_FARG M_hist); SID_free(SID_FARG n_i); SID_free(SID_FARG M_peak); SID_free(SID_FARG M_68_lo); SID_free(SID_FARG M_68_hi); SID_free(SID_FARG i_z_track); SID_free(SID_FARG idx_track); SID_free(SID_FARG M_track); SID_free(SID_FARG x_track); SID_free(SID_FARG y_track); SID_free(SID_FARG z_track); SID_free(SID_FARG vx_track); SID_free(SID_FARG vy_track); SID_free(SID_FARG vz_track); SID_free(SID_FARG snap_list); SID_free(SID_FARG z_list); SID_free(SID_FARG t_list); SID_log("Done.",SID_LOG_CLOSE); } // if I_am_Master SID_Barrier(SID.COMM_WORLD); SID_log("Done.",SID_LOG_CLOSE); }
int calc_tree_property_index_logM(trend_property_info *property, hist_info *hist, void *halo_in) { tree_info * trees = (tree_info *)(property->params); tree_node_info *halo = (tree_node_info *)(halo_in); return (calc_histogram_index(hist, take_log10(fetch_treenode_M_vir(trees, halo)))); }
void compute_treenode_list_marker_stats(tree_info *trees,treenode_list_info *list,tree_markers_info **markers_all,tree_markers_stats_info *stats,int **n_hist_count,int *n_hist){ int n_stats=3; int n_M =2; (*n_hist) =n_stats+n_M; // Allocate histogram arrays -- stats int i_hist=0; int **hist =(int **)SID_calloc(sizeof(int *)*(*n_hist)); int *n_bins=(int *)SID_calloc(sizeof(int)*(*n_hist)); for(int i_stat=0;i_stat<n_stats;i_stat++){ n_bins[i_hist]=trees->n_snaps; hist[i_hist++]=(int *)SID_calloc(sizeof(int)*n_bins[i_hist]); } // Allocate histogram arrays -- mass double logM_min=7.; int n_M_bins=90; double dlogM =0.1; for(int i_M=0;i_M<n_M;i_M++){ n_bins[i_hist]=n_M_bins; hist[i_hist++]=(int *)SID_calloc(sizeof(int)*n_bins[i_hist]); } // Allocate histogram counts if((*n_hist_count)==NULL) (*n_hist_count)=(int *)SID_calloc(sizeof(int)*(*n_hist)); else{ for(i_hist=0;i_hist<(*n_hist);i_hist++) (*n_hist_count)[i_hist]=0; } // Work with a precompiled markers array if it's been given tree_markers_info *markers; if(markers_all==NULL) markers=(tree_markers_info *)SID_malloc(sizeof(tree_markers_info)); // Create histograms for(int i_list=0;i_list<list->n_list_local;i_list++){ markers=fetch_treenode_precomputed_markers(trees,list->list[i_list]); // Build histogram int i_bin; for(int i_hist=0;i_hist<(*n_hist);i_hist++){ i_bin=-1; if(i_hist<n_stats){ tree_node_info *marker=NULL; if(i_hist==0) marker=markers->half_peak_mass; else if(i_hist==1) marker=markers->merger_33pc_remnant; else if(i_hist==2) marker=markers->merger_10pc_remnant; else SID_trap_error("Behaviour undefined in compute_treenode_list_marker_stats()",ERROR_LOGIC); if(marker!=NULL) i_bin=marker->snap_tree; else i_bin=-1; } else{ if(i_hist==(n_stats+0)){ halo_properties_info *properties=fetch_treenode_properties(trees,list->list[i_list]); i_bin=(take_log10(properties->M_vir)-logM_min)/dlogM; } else if(i_hist==(n_stats+1)) i_bin=(take_log10(markers->M_peak)-logM_min)/dlogM; else SID_trap_error("Behaviour undefined in compute_treenode_list_marker_stats()",ERROR_LOGIC); } if(i_bin>=0 && i_bin<n_bins[i_hist]){ hist[i_hist][i_bin]++; (*n_hist_count)[i_hist]++; } } } if(markers_all==NULL) SID_free(SID_FARG markers); for(int i_hist=0;i_hist<(*n_hist);i_hist++){ SID_Allreduce(SID_IN_PLACE,hist[i_hist],n_bins[i_hist],SID_INT,SID_SUM,SID.COMM_WORLD); SID_Allreduce(SID_IN_PLACE,&((*n_hist_count)[i_hist]),1,SID_INT,SID_SUM,SID.COMM_WORLD); } // Find 68 and 95 percent confidence ranges for(int i_hist=0;i_hist<(*n_hist);i_hist++){ int sum=0; for(int i_bin=0;i_bin<n_bins[i_hist];i_bin++) sum+=hist[i_hist][i_bin]; size_t *hist_index=NULL; merge_sort(hist[i_hist],(size_t)(n_bins[i_hist]),&hist_index,SID_INT,SORT_COMPUTE_INDEX,FALSE); int i_peak =hist_index[n_bins[i_hist]-1]; int i_68_lo=hist_index[n_bins[i_hist]-1]; int i_68_hi=hist_index[n_bins[i_hist]-1]; int target =(int)(0.68*(double)sum); int accum =0; int i_bin =0; while(accum<=target && i_bin<n_bins[i_hist]){ size_t idx_i=hist_index[n_bins[i_hist]-i_bin-1]; if(idx_i<i_68_lo) i_68_lo=idx_i; if(idx_i>i_68_hi) i_68_hi=idx_i; accum+=hist[i_hist][idx_i]; i_bin++; } int i_95_lo=i_68_lo; int i_95_hi=i_68_hi; target=(int)(0.95*(double)sum); while(accum<=target && i_bin<n_bins[i_hist]){ size_t idx_i=hist_index[n_bins[i_hist]-i_bin-1]; if(idx_i<i_95_lo) i_95_lo=idx_i; if(idx_i>i_95_hi) i_95_hi=idx_i; accum+=hist[i_hist][idx_i]; i_bin++; } SID_free(SID_FARG hist_index); if(i_hist==0){ stats->t_half_peak_mass_ranges[0][0]=trees->t_list[i_68_lo]; stats->t_half_peak_mass_ranges[0][1]=trees->t_list[i_68_hi]; stats->t_half_peak_mass_ranges[1][0]=trees->t_list[i_95_lo]; stats->t_half_peak_mass_ranges[1][1]=trees->t_list[i_95_hi]; stats->t_half_peak_mass_peak =trees->t_list[i_peak]; } else if(i_hist==1){ stats->t_merger_33pc_ranges[0][0]=trees->t_list[i_68_lo]; stats->t_merger_33pc_ranges[0][1]=trees->t_list[i_68_hi]; stats->t_merger_33pc_ranges[1][0]=trees->t_list[i_95_lo]; stats->t_merger_33pc_ranges[1][1]=trees->t_list[i_95_hi]; stats->t_merger_33pc_peak =trees->t_list[i_peak]; } else if(i_hist==2){ stats->t_merger_10pc_ranges[0][0]=trees->t_list[i_68_lo]; stats->t_merger_10pc_ranges[0][1]=trees->t_list[i_68_hi]; stats->t_merger_10pc_ranges[1][0]=trees->t_list[i_95_lo]; stats->t_merger_10pc_ranges[1][1]=trees->t_list[i_95_hi]; stats->t_merger_10pc_peak =trees->t_list[i_peak]; } else if(i_hist==3){ stats->M_peak_ranges[0][0]=logM_min+(double)(i_68_lo)*dlogM; stats->M_peak_ranges[0][1]=logM_min+(double)(i_68_hi)*dlogM; stats->M_peak_ranges[1][0]=logM_min+(double)(i_95_lo)*dlogM; stats->M_peak_ranges[1][1]=logM_min+(double)(i_95_hi)*dlogM; stats->M_peak_peak =logM_min+(double)( i_peak)*dlogM; } else if(i_hist==4){ stats->M_vir_ranges[0][0]=logM_min+(double)(i_68_lo)*dlogM; stats->M_vir_ranges[0][1]=logM_min+(double)(i_68_hi)*dlogM; stats->M_vir_ranges[1][0]=logM_min+(double)(i_95_lo)*dlogM; stats->M_vir_ranges[1][1]=logM_min+(double)(i_95_hi)*dlogM; stats->M_vir_peak =logM_min+(double)( i_peak)*dlogM; } else SID_trap_error("Behaviour undefined in compute_treenode_list_marker_stats()",ERROR_LOGIC); } // Clean-up for(int i_hist=0;i_hist<(*n_hist);i_hist++) SID_free(SID_FARG hist[i_hist]); SID_free(SID_FARG hist); SID_free(SID_FARG n_bins); }
void write_tree_branches(tree_info * trees, tree_node_info **list_in, int n_list_in, int mode, const char * filename_out_dir, const char * catalog_name) { SID_log("Processing %d halos in catalog {%s}...", SID_LOG_OPEN, n_list_in, catalog_name); // Fetch properties halo_properties_info **group_properties = (halo_properties_info **)ADaPS_fetch(trees->data, "properties_groups"); halo_properties_info **subgroup_properties = (halo_properties_info **)ADaPS_fetch(trees->data, "properties_subgroups"); // Are we processing groups? int flag_processing_groups = GBP_FALSE; halo_properties_info **halo_properties; if(mode == 1) { flag_processing_groups = GBP_TRUE; halo_properties = group_properties; } else { flag_processing_groups = GBP_FALSE; halo_properties = subgroup_properties; } // Take the halo pointers back to their start int n_list = n_list_in; tree_node_info **list = (tree_node_info **)SID_malloc(sizeof(tree_node_info *) * n_list_in); int * track_index = (int *)SID_malloc(sizeof(int) * n_list_in); for(int i_list = 0; i_list < n_list; i_list++) { track_index[i_list] = i_list; // default find_treenode_branch_leaf(trees, list_in[i_list], &(list[i_list])); } // Count fragmented halos int n_frag = 0; for(int i_list = 0; i_list < n_list_in; i_list++) { if(SID_CHECK_BITFIELD_SWITCH(list_in[i_list]->tree_case, TREE_CASE_FRAGMENTED_STRAYED) || SID_CHECK_BITFIELD_SWITCH(list_in[i_list]->tree_case, TREE_CASE_FRAGMENTED_NORMAL) || SID_CHECK_BITFIELD_SWITCH(list_in[i_list]->tree_case, TREE_CASE_FRAGMENTED_OTHER)) n_frag++; } if(n_frag > 0) SID_log("%d fragmented...", SID_LOG_CONTINUE, n_frag); // Remove duplicates (These are ugly N^2 algorythms. Fix them sometime.) for(int i_list = 0; i_list < n_list_in; i_list++) track_index[i_list] = i_list; for(int i_list = 0; i_list < n_list; i_list++) { for(int j_list = (i_list + 1); j_list < n_list; j_list++) { if(list[i_list] == list[j_list]) { n_list--; for(int k_list = j_list; k_list < n_list; k_list++) list[k_list] = list[k_list + 1]; int old_index = track_index[j_list]; for(int k_list = 0; k_list < n_list; k_list++) { if(track_index[k_list] > old_index) track_index[k_list]--; } track_index[j_list] = track_index[i_list]; } } } for(int i_list = 0; i_list < n_list_in; i_list++) { for(int j_list = 0; j_list < n_list; j_list++) { if(list_in[i_list] == list[j_list]) track_index[i_list] = j_list; } } if(n_list != n_list_in) SID_log("%d removed as duplicates...", SID_LOG_CONTINUE, n_list_in - n_list); // Master Rank does all the writing FILE *fp_tracks_out = NULL; FILE *fp_props_out = NULL; if(SID.I_am_Master) { // Create and open the output files char filename_tracks_out[SID_MAX_FILENAME_LENGTH]; char filename_props_out[SID_MAX_FILENAME_LENGTH]; sprintf(filename_tracks_out, "%s/%s_tracks.dat", filename_out_dir, catalog_name); sprintf(filename_props_out, "%s/%s_props.txt", filename_out_dir, catalog_name); fp_tracks_out = fopen(filename_tracks_out, "w"); fp_props_out = fopen(filename_props_out, "w"); // Write header for tracks file fwrite(&n_list, sizeof(int), 1, fp_tracks_out); fwrite(&(trees->n_snaps), sizeof(int), 1, fp_tracks_out); fwrite(trees->snap_list, sizeof(int), trees->n_snaps, fp_tracks_out); fwrite(trees->z_list, sizeof(double), trees->n_snaps, fp_tracks_out); fwrite(trees->t_list, sizeof(double), trees->n_snaps, fp_tracks_out); // Write header for props file int n_write; int i_write; int i_column; if(!flag_processing_groups) n_write = 7; else n_write = 5; // Don't write the halos at the end which pertain only to subgroups for(i_write = 0, i_column = 1; i_write < n_write; i_write++) { char write_name[32]; switch(i_write) { case 0: sprintf(write_name, "select"); break; case 1: sprintf(write_name, "main_progenitor"); break; case 2: sprintf(write_name, "peak_mass"); break; case 3: sprintf(write_name, "form"); break; case 4: sprintf(write_name, "last"); break; case 5: sprintf(write_name, "accrete_last"); break; case 6: sprintf(write_name, "accrete_first"); break; } if(i_write == 0) { if(flag_processing_groups) fprintf(fp_props_out, "# Properties for group catalog {%s}\n", catalog_name); else fprintf(fp_props_out, "# Properties for subgroup catalog {%s}\n", catalog_name); fprintf(fp_props_out, "#\n"); fprintf(fp_props_out, "# Column (%02d): Catalog item number\n", i_column); i_column++; fprintf(fp_props_out, "# (%02d): Track index\n", i_column); i_column++; } fprintf(fp_props_out, "# (%02d): Snapshot No. at t_%s\n", i_column, write_name); i_column++; fprintf(fp_props_out, "# (%02d): Index No. at t_%s\n", i_column, write_name); i_column++; fprintf(fp_props_out, "# (%02d): t_%s\n", i_column, write_name); i_column++; fprintf(fp_props_out, "# (%02d): z_%s\n", i_column, write_name); i_column++; fprintf(fp_props_out, "# (%02d): log_10(M_%s(z=z_%s) [M_sol])\n", i_column, write_name, write_name); i_column++; fprintf(fp_props_out, "# (%02d): n_p(z=z_%s)\n", i_column, write_name); i_column++; if(!flag_processing_groups) { fprintf(fp_props_out, "# (%02d): log_10(M_parent_%s(z=z_%s) [M_sol])\n", i_column, write_name, write_name); i_column++; } } } // Allocate some temporary arrays for the tracks int * i_z_track = (int *)SID_malloc(sizeof(int) * trees->n_snaps); int * idx_track = (int *)SID_malloc(sizeof(int) * trees->n_snaps); int * tc_track = (int *)SID_malloc(sizeof(int) * trees->n_snaps); double *M_track = (double *)SID_malloc(sizeof(double) * trees->n_snaps); double *x_track = (double *)SID_malloc(sizeof(double) * trees->n_snaps); double *y_track = (double *)SID_malloc(sizeof(double) * trees->n_snaps); double *z_track = (double *)SID_malloc(sizeof(double) * trees->n_snaps); double *vx_track = (double *)SID_malloc(sizeof(double) * trees->n_snaps); double *vy_track = (double *)SID_malloc(sizeof(double) * trees->n_snaps); double *vz_track = (double *)SID_malloc(sizeof(double) * trees->n_snaps); // Process z_obs halos int k_z_obs = 0; for(int i_rank = 0; i_rank < SID.n_proc; i_rank++) { if(SID.My_rank == i_rank || SID.I_am_Master) { int n_list_i; // Generate properties SID_Status status; if(i_rank == 0) n_list_i = n_list_in; else SID_Sendrecv(&n_list_in, 1, SID_INT, SID_MASTER_RANK, 1918270, &n_list_i, 1, SID_INT, i_rank, 1918270, SID_COMM_WORLD, &status); for(int i_list = 0; i_list < n_list_i; i_list++) { // Point to the halo to be processed tree_node_info *current_halo = list_in[i_list]; // Find some special nodes for this listed halo tree_node_info *descendant_last = NULL; tree_node_info *progenitor_main = NULL; tree_node_info *progenitor_peak_mass = NULL; tree_node_info *progenitor_formation = NULL; tree_node_info *progenitor_first_accretion = NULL; tree_node_info *progenitor_last_accretion = NULL; find_treenode_last_snapshot(trees, current_halo, &descendant_last); find_treenode_main_progenitor(trees, current_halo, &progenitor_main); find_treenode_accretion(trees, current_halo, &progenitor_first_accretion, &progenitor_last_accretion); find_treenode_M_peak(trees, descendant_last, &progenitor_peak_mass); find_treenode_formation(trees, progenitor_peak_mass, 0.5, &progenitor_formation); if(descendant_last->snap_tree == (trees->n_snaps - 1)) descendant_last = NULL; // Write properties int n_write; if(i_rank == 0) fprintf(fp_props_out, "%4d %4d", i_list, track_index[i_list]); if(!flag_processing_groups) n_write = 7; else n_write = 5; // Don't write the halos at the end which pertain only to subgroups for(int i_write = 0; i_write < n_write; i_write++) { // Compute properties int i_z_node; int idx_node; int idx_node_parent; double t_node; double z_node; double M_node; double M_node_parent; int n_p_node; if(SID.My_rank == i_rank) { tree_node_info *node_write; char write_name[32]; switch(i_write) { case 0: sprintf(write_name, "select"); node_write = current_halo; break; case 1: sprintf(write_name, "main_progenitor"); node_write = progenitor_main; break; case 2: sprintf(write_name, "peak_mass"); node_write = progenitor_peak_mass; break; case 3: sprintf(write_name, "form"); node_write = progenitor_formation; break; case 4: sprintf(write_name, "last"); node_write = descendant_last; break; case 5: sprintf(write_name, "accrete_last"); node_write = progenitor_last_accretion; break; case 6: sprintf(write_name, "accrete_first"); node_write = progenitor_first_accretion; break; } if(node_write != NULL) { i_z_node = node_write->snap_tree; idx_node = node_write->neighbour_index; t_node = trees->t_list[i_z_node]; z_node = trees->z_list[i_z_node]; M_node = halo_properties[i_z_node][idx_node].M_vir; n_p_node = halo_properties[i_z_node][idx_node].n_particles; if(node_write->parent_top != NULL && !flag_processing_groups) { idx_node_parent = node_write->parent_top->snap_tree; M_node_parent = group_properties[i_z_node][idx_node_parent].M_vir; } else { idx_node_parent = -1; M_node_parent = 0.; } } else { i_z_node = -1; idx_node = -1; t_node = -1.; z_node = -1.; M_node = 0.; n_p_node = 0; idx_node_parent = -1; M_node_parent = 0.; } } // Write properties if(i_rank != 0) { SID_Status status; SID_Sendrecv(&i_z_node, 1, SID_INT, SID_MASTER_RANK, 1918271, &i_z_node, 1, SID_INT, i_rank, 1918271, SID_COMM_WORLD, &status); SID_Sendrecv(&idx_node, 1, SID_INT, SID_MASTER_RANK, 1918272, &idx_node, 1, SID_INT, i_rank, 1918272, SID_COMM_WORLD, &status); SID_Sendrecv(&t_node, 1, SID_DOUBLE, SID_MASTER_RANK, 1918273, &t_node, 1, SID_DOUBLE, i_rank, 1918273, SID_COMM_WORLD, &status); SID_Sendrecv(&z_node, 1, SID_DOUBLE, SID_MASTER_RANK, 1918274, &z_node, 1, SID_DOUBLE, i_rank, 1918274, SID_COMM_WORLD, &status); SID_Sendrecv(&M_node, 1, SID_DOUBLE, SID_MASTER_RANK, 1918275, &M_node, 1, SID_DOUBLE, i_rank, 1918275, SID_COMM_WORLD, &status); SID_Sendrecv( &M_node_parent, 1, SID_DOUBLE, SID_MASTER_RANK, 1918276, &M_node_parent, 1, SID_DOUBLE, i_rank, 1918276, SID_COMM_WORLD, &status); } if(SID.I_am_Master) { int snap_node = -1; if(i_z_node >= 0) snap_node = trees->snap_list[i_z_node]; fprintf(fp_props_out, " %4d %7d %10.3le %5.2lf %6.3lf %7d", snap_node, idx_node, t_node / S_PER_YEAR, z_node, take_log10(M_node), n_p_node); if(!flag_processing_groups) fprintf(fp_props_out, " %6.3lf", take_log10(M_node_parent)); } } // i_write if(SID.I_am_Master) fprintf(fp_props_out, "\n"); } // Generate tracks if(i_rank == 0) n_list_i = n_list; else { SID_Status status; SID_Sendrecv(&n_list, 1, SID_INT, SID_MASTER_RANK, 1918270, &n_list_i, 1, SID_INT, i_rank, 1918270, SID_COMM_WORLD, &status); } for(int i_list = 0; i_list < n_list_i; i_list++) { // Point to the halo to be processed tree_node_info *current_halo = list[i_list]; // Compute track int n_track = 0; if(SID.My_rank == i_rank) { tree_node_info *current_track = current_halo; while(current_track != NULL && check_treenode_if_main_progenitor(current_track)) { i_z_track[n_track] = current_track->snap_tree; idx_track[n_track] = current_track->neighbour_index; tc_track[n_track] = current_track->tree_case; x_track[n_track] = halo_properties[i_z_track[n_track]][idx_track[n_track]].position_MBP[0]; y_track[n_track] = halo_properties[i_z_track[n_track]][idx_track[n_track]].position_MBP[1]; z_track[n_track] = halo_properties[i_z_track[n_track]][idx_track[n_track]].position_MBP[2]; vx_track[n_track] = halo_properties[i_z_track[n_track]][idx_track[n_track]].velocity_COM[0]; vy_track[n_track] = halo_properties[i_z_track[n_track]][idx_track[n_track]].velocity_COM[1]; vz_track[n_track] = halo_properties[i_z_track[n_track]][idx_track[n_track]].velocity_COM[2]; if(!SID_CHECK_BITFIELD_SWITCH(current_track->tree_case, TREE_CASE_MOST_MASSIVE) || SID_CHECK_BITFIELD_SWITCH(current_track->tree_case, TREE_CASE_DOMINANT)) M_track[n_track] = halo_properties[i_z_track[n_track]][idx_track[n_track]].M_vir; else M_track[n_track] = -1.; n_track++; current_track = current_track->descendant; } } // Write track if(i_rank != 0) { SID_Status status; SID_Sendrecv(&n_track, 1, SID_INT, SID_MASTER_RANK, 1918370, &n_track, 1, SID_INT, i_rank, 1918370, SID_COMM_WORLD, &status); SID_Sendrecv(i_z_track, n_track, SID_INT, SID_MASTER_RANK, 1918371, i_z_track, n_track, SID_INT, i_rank, 1918371, SID_COMM_WORLD, &status); SID_Sendrecv(idx_track, n_track, SID_INT, SID_MASTER_RANK, 1918372, idx_track, n_track, SID_INT, i_rank, 1918372, SID_COMM_WORLD, &status); SID_Sendrecv(tc_track, n_track, SID_INT, SID_MASTER_RANK, 1918373, tc_track, n_track, SID_INT, i_rank, 1918373, SID_COMM_WORLD, &status); SID_Sendrecv(x_track, n_track, SID_INT, SID_MASTER_RANK, 1918374, x_track, n_track, SID_INT, i_rank, 1918374, SID_COMM_WORLD, &status); SID_Sendrecv(y_track, n_track, SID_INT, SID_MASTER_RANK, 1918375, y_track, n_track, SID_INT, i_rank, 1918375, SID_COMM_WORLD, &status); SID_Sendrecv(z_track, n_track, SID_INT, SID_MASTER_RANK, 1918376, z_track, n_track, SID_INT, i_rank, 1918376, SID_COMM_WORLD, &status); SID_Sendrecv(vx_track, n_track, SID_INT, SID_MASTER_RANK, 1918377, vx_track, n_track, SID_INT, i_rank, 1918377, SID_COMM_WORLD, &status); SID_Sendrecv(vy_track, n_track, SID_INT, SID_MASTER_RANK, 1918378, vy_track, n_track, SID_INT, i_rank, 1918378, SID_COMM_WORLD, &status); SID_Sendrecv(vz_track, n_track, SID_INT, SID_MASTER_RANK, 1918379, vz_track, n_track, SID_INT, i_rank, 1918379, SID_COMM_WORLD, &status); SID_Sendrecv(M_track, n_track, SID_INT, SID_MASTER_RANK, 1918380, M_track, n_track, SID_INT, i_rank, 1918380, SID_COMM_WORLD, &status); } if(SID.I_am_Master) { fwrite(&n_track, sizeof(int), 1, fp_tracks_out); fwrite(i_z_track, sizeof(int), n_track, fp_tracks_out); fwrite(idx_track, sizeof(int), n_track, fp_tracks_out); fwrite(tc_track, sizeof(int), n_track, fp_tracks_out); fwrite(x_track, sizeof(double), n_track, fp_tracks_out); fwrite(y_track, sizeof(double), n_track, fp_tracks_out); fwrite(z_track, sizeof(double), n_track, fp_tracks_out); fwrite(vx_track, sizeof(double), n_track, fp_tracks_out); fwrite(vy_track, sizeof(double), n_track, fp_tracks_out); fwrite(vz_track, sizeof(double), n_track, fp_tracks_out); fwrite(M_track, sizeof(double), n_track, fp_tracks_out); } } // for i_list } // if i_rank SID_Barrier(SID_COMM_WORLD); } // for i_rank if(SID.I_am_Master) { fclose(fp_tracks_out); fclose(fp_props_out); } // Clean-up SID_free(SID_FARG track_index); SID_free(SID_FARG list); SID_free(SID_FARG i_z_track); SID_free(SID_FARG idx_track); SID_free(SID_FARG tc_track); SID_free(SID_FARG M_track); SID_free(SID_FARG x_track); SID_free(SID_FARG y_track); SID_free(SID_FARG z_track); SID_free(SID_FARG vx_track); SID_free(SID_FARG vy_track); SID_free(SID_FARG vz_track); SID_log("Done.", SID_LOG_CLOSE); }
int main(int argc, char *argv[]){ double redshift; char filename_in[MAX_FILENAME_LENGTH]; char filename_out[MAX_FILENAME_LENGTH]; char filename_cosmology[MAX_FILENAME_LENGTH]; double box_size; double lM_min,dlM; char *line=NULL; size_t line_length=0; int M_column; int n_bins; int flag_log; // Initialization -- MPI etc. SID_init(&argc,&argv,NULL,NULL); if(argc!=11) SID_trap_error("Incorrect syntax.",ERROR_SYNTAX); // Parse arguments strcpy(filename_in, argv[1]); strcpy(filename_out,argv[2]); redshift=(double)atof(argv[3]); strcpy(filename_cosmology,argv[4]); box_size=(double)atof(argv[5]); M_column=(int) atoi(argv[6]); flag_log=(int) atoi(argv[7]); lM_min =(double)atof(argv[8]); dlM =(double)atof(argv[9]); n_bins =(int) atoi(argv[10]); SID_log("Producing a mass function for ascii file {%s}...",SID_LOG_OPEN|SID_LOG_TIMER,filename_in); // Initialize cosmology cosmo_info *cosmo; read_gbpCosmo_file(&cosmo,filename_cosmology); double h_Hubble=((double *)ADaPS_fetch(cosmo,"h_Hubble"))[0]; // Open file FILE *fp_in; if((fp_in=fopen(filename_in,"r"))==NULL) SID_trap_error("Could not open {%s} for reading.",ERROR_IO_OPEN,filename_in); // Allocate memory for the data. Read it and sort it in ascending order SID_log("Reading data...",SID_LOG_OPEN|SID_LOG_TIMER); int n_data_in=count_lines_data(fp_in); SID_log("(%d items)...",SID_LOG_CONTINUE,n_data_in); double *data =(double *)malloc(sizeof(double)*n_data_in); int n_data=0; for(int i=0;i<n_data_in;i++){ double data_in; grab_next_line_data(fp_in,&line,&line_length); grab_double(line,M_column,&data_in); if(!flag_log) data_in=take_log10(data_in); if(data_in>=lM_min) data[n_data++]=data_in; } SID_log("(%d will be used)...",SID_LOG_CONTINUE,n_data); fclose(fp_in); SID_free(SID_FARG line); SID_log("Done.",SID_LOG_CLOSE); // Perform sort SID_log("Sorting data...",SID_LOG_OPEN|SID_LOG_TIMER); merge_sort(data,n_data,NULL,SID_DOUBLE,SORT_INPLACE_ONLY,SORT_COMPUTE_INPLACE); SID_log("Done.",SID_LOG_CLOSE); // Compile histogram SID_log("Computing mass function...",SID_LOG_OPEN|SID_LOG_TIMER); double *bin =(double *)SID_malloc(sizeof(double)*(n_bins+1)); double *bin_median=(double *)SID_malloc(sizeof(double)*n_bins); int *hist =(int *)SID_calloc(sizeof(int) *n_bins); double lM_bin_min=lM_min; double lM_bin_max=lM_min; int i_data_lo=-1; int i_data_hi=-1; int i_bin =0; int i_data=0; for(i_bin=0;i_bin<n_bins;i_bin++){ lM_bin_min=lM_bin_max; lM_bin_max=lM_min+((double)(i_bin+1))*dlM; bin[i_bin]=lM_bin_min; i_data_lo=i_data; i_data_hi=i_data; while(data[i_data]<lM_bin_max && i_data<n_data){ hist[i_bin]++; i_data_hi=i_data; i_data++; if(i_data>=n_data) break; } int i_data_mid=(i_data_lo+i_data_hi)/2; if(hist[i_bin]>0){ if(hist[i_bin]%2) bin_median[i_bin]=data[i_data_mid]; else bin_median[i_bin]=0.5*(data[i_data_mid]+data[i_data_mid+1]); } else bin_median[i_bin]=0.5*(lM_bin_max+lM_bin_min); } bin[i_bin]=lM_bin_max; SID_log("Done.",SID_LOG_CLOSE); // Write mass function FILE *fp_out; if((fp_out=fopen(filename_out,"w"))==NULL){ fprintf(stderr,"Error opening output file {%s}.\n",filename_out); SID_free(SID_FARG data); return(1); } SID_log("Writing results to {%s}...",SID_LOG_OPEN|SID_LOG_TIMER,filename_out); double box_volume=box_size*box_size*box_size; fprintf(fp_out,"# Mass function for column %d in {%s}\n",M_column,filename_in); fprintf(fp_out,"# Column (01): M_lo [source units]\n"); fprintf(fp_out,"# (02): M_median [source units]\n"); fprintf(fp_out,"# (03): M_hi [source units]\n"); fprintf(fp_out,"# (04): No. in bin\n"); fprintf(fp_out,"# (05): MFn (per unit volume, per dlogM)\n"); fprintf(fp_out,"# (06): +/- MFn\n"); fprintf(fp_out,"# (07): Sheth & Tormen MFn\n"); fprintf(fp_out,"# (08): Watson MFn\n"); fprintf(fp_out,"# (09): No. w/ M>M_lo\n"); fprintf(fp_out,"# (10): Cumulative MFn (per unit volume)\n"); fprintf(fp_out,"# (11): +/- Cumulative MFn\n"); fprintf(fp_out,"# (12): Sheth & Tormen Cumulative MFn\n"); fprintf(fp_out,"# (13): Watson Cumulative MFn\n"); double M_sol_inv_h=M_SOL/h_Hubble; double Mpc_inv_h =M_PER_MPC/h_Hubble; for(int i=0;i<n_bins;i++){ double dn_dlogM_theory_1=mass_function(take_alog10(bin_median[i])*M_sol_inv_h, redshift, &cosmo, MF_ST)*pow(Mpc_inv_h,3.0); double n_theory_1=mass_function_cumulative(take_alog10(bin[i])*M_sol_inv_h, redshift, &cosmo, MF_ST)*pow(Mpc_inv_h,3.0); double dn_dlogM_theory_2=mass_function(take_alog10(bin_median[i])*M_sol_inv_h, redshift, &cosmo, MF_WATSON)*pow(Mpc_inv_h,3.0); double n_theory_2=mass_function_cumulative(take_alog10(bin[i])*M_sol_inv_h, redshift, &cosmo, MF_WATSON)*pow(Mpc_inv_h,3.0); // Compute cumulative histogram int cumulative_hist=0; for(int j_bin=i;j_bin<n_bins;j_bin++) cumulative_hist+=hist[j_bin]; fprintf(fp_out,"%11.4le %11.4le %11.4le %6d %11.4le %11.4le %10.4le %10.4le %6d %10.4le %10.4le %10.4le %10.4le\n", bin[i], bin_median[i], bin[i+1], hist[i], (double)(hist[i])/(box_volume*dlM), sqrt((double)(hist[i]))/(box_volume*dlM), dn_dlogM_theory_1,dn_dlogM_theory_2, cumulative_hist, (double)(cumulative_hist)/box_volume, sqrt((double)(cumulative_hist))/box_volume, n_theory_1,n_theory_2); } fclose(fp_out); SID_log("Done.",SID_LOG_CLOSE); // Free allocated memory SID_free(SID_FARG data); SID_free(SID_FARG bin); SID_free(SID_FARG bin_median); SID_free(SID_FARG hist); SID_log("Done.",SID_LOG_CLOSE); SID_exit(ERROR_NONE); }
void process_local(tree_info * trees, int i_pass, char * filename_out_root, double radius2, double M_min, int i_snap, int i_halo, int j_subgroup, int i_group, int halo_id, int halo_file_offset, int halo_type, int halo_n_particles_peak, int halo_tree_id, int halo_index, int halo_descendant_id, int bridge_forematch_first_index, int bridge_forematch_first_file, int bridge_backmatch_index, int bridge_backmatch_file, int group_id, halo_properties_info *properties, halo_properties_info *properties_group, int * n_list, int * halo_list, double x_cen, double y_cen, double z_cen) { int flag_found = GBP_FALSE; int i_type = !(properties_group == NULL); // Perform search if(i_pass < 2) { double dx_i = d_periodic(((double)properties->position_MBP[0] - x_cen), trees->box_size); double dy_i = d_periodic(((double)properties->position_MBP[1] - y_cen), trees->box_size); double dz_i = d_periodic(((double)properties->position_MBP[2] - z_cen), trees->box_size); double r2_i = dx_i * dx_i + dy_i * dy_i + dz_i * dz_i; if(r2_i < radius2 && properties->M_vir >= M_min) { flag_found = GBP_TRUE; if(i_pass == 0) (*n_list)++; else { // Check if we have added this halo ID yet for(int i_scan = 0; i_scan < (*n_list) && flag_found; i_scan++) { if(halo_list[i_scan] == halo_id) flag_found = GBP_FALSE; } // Add halo ID if it isn't in the list if(flag_found) halo_list[(*n_list)++] = halo_id; } } } // Perform write else if(i_pass == 2) { int flag_keep = GBP_FALSE; for(int j_list = 0; j_list < (*n_list) && !flag_keep; j_list++) if(halo_id == halo_list[j_list]) flag_keep = GBP_TRUE; if(flag_keep) { char filename_out[SID_MAX_FILENAME_LENGTH]; if(i_type == 0) sprintf(filename_out, "%s_group_%09d.txt", filename_out_root, halo_id); else sprintf(filename_out, "%s_subgroup_%09d.txt", filename_out_root, halo_id); FILE *fp_out = fopen(filename_out, "a"); int descendant_snap = -1; int bridge_forematch_first_snap = -1; int bridge_backmatch_snap = -1; if(halo_file_offset > 0) descendant_snap = trees->snap_list[i_snap + halo_file_offset]; if(bridge_forematch_first_file >= 0) bridge_forematch_first_snap = trees->snap_list[bridge_forematch_first_file]; if(bridge_backmatch_file >= 0) bridge_backmatch_snap = trees->snap_list[bridge_backmatch_file]; char *halo_type_string = NULL; tree_case_flags_text(halo_type, "+", &halo_type_string); fprintf(fp_out, "%le %7.3lf %3d %7d %7d %5.2lf %6d %6d %10.3le %10.3le %10.3le %10.3le %7d %2d %3d %7d %7d %3d %7d %3d %7d %7d %s", trees->a_list[i_snap], trees->z_list[i_snap], trees->snap_list[i_snap], i_halo, halo_id, take_log10(properties->M_vir), properties->n_particles, halo_n_particles_peak, properties->position_MBP[0], properties->position_MBP[1], properties->position_MBP[2], properties->R_vir, halo_tree_id, halo_file_offset, descendant_snap, halo_index, halo_descendant_id, bridge_forematch_first_snap, bridge_forematch_first_index, bridge_backmatch_snap, bridge_backmatch_index, halo_type, halo_type_string); SID_free(SID_FARG halo_type_string); if(i_type == 1) fprintf(fp_out, " %7d %5d %7d %10.3le %10.3le %10.3le\n", i_group, group_id, j_subgroup, properties->position_MBP[0] - properties_group->position_MBP[0], properties->position_MBP[1] - properties_group->position_MBP[1], properties->position_MBP[2] - properties_group->position_MBP[2]); else fprintf(fp_out, "\n"); // Write subgroup-specific stuff if(i_type == 1) { } fclose(fp_out); } } // Sanity check else SID_exit_error("Invalid mode passed to process_local.", SID_ERROR_LOGIC); }
int calc_halo_trend_property_index_logM_FoF(trend_property_info *property,hist_info *hist,void *halo_in){ halo_trend_info *halo_trend_data=(halo_trend_info *)(property->params); halo_info *halo =(halo_info *)(halo_in); return(calc_histogram_index(hist,take_log10(halo->properties_group->n_particles*halo_trend_data->m_p))); }
void read_smooth(plist_info *plist, char *filename_root_in, int snapshot_number, int mode){ char filename[256]; size_t n_particles_all_mem; size_t n_particles_local; size_t n_particles_total; int i_quantity; int n_quantities=3; int *used; char *species_name; char var_name[256]; char unit_name[256]; double unit_factor; int i_file; size_t *ids; size_t *ids_index; int n_particles_file; int offset; int n_files; void *id_buf; size_t *id_buf_index=NULL; int *id_buf_i; long long *id_buf_L; long long *mark; size_t i_particle; size_t j_particle; void *buffer; float *local_array; int n_mark; float *r_smooth_array; float *rho_array; float *sigma_v_array; char *read_array; double expansion_factor; double h_Hubble; int flag_filefound=FALSE; int flag_multifile=FALSE; int flag_file_type; int flag_LONGIDs; int read_rank=MASTER_RANK; int flag_log_sigma=FALSE; int flag_log_rho=FALSE; FILE *fp; SID_log("Reading smooth file {%s}...",SID_LOG_OPEN|SID_LOG_TIMER,filename_root_in); // Read header info SID_log("Reading header information...",SID_LOG_OPEN); smooth_header_info header; flag_filefound =init_smooth_read(filename_root_in,snapshot_number,&flag_multifile,&flag_file_type,&header); SID_log("n_files =%d", SID_LOG_COMMENT,header.n_files); SID_log("n_particles=%lld",SID_LOG_COMMENT,header.n_particles_total); SID_log("Done.",SID_LOG_CLOSE); // Interpret the mode passed to this function int flag_logs_used =FALSE; int flag_log_quantity=FALSE; if(check_mode_for_flag(mode,READ_SMOOTH_LOG_SIGMA)){ flag_log_sigma=TRUE; flag_logs_used=TRUE; } else flag_log_sigma=FALSE; if(check_mode_for_flag(mode,READ_SMOOTH_LOG_RHO)){ flag_log_rho =TRUE; flag_logs_used=TRUE; } else flag_log_rho=FALSE; // A file was found ... if(flag_filefound){ // Communicate the header n_particles_file =header.n_particles_file; offset =header.offset; n_particles_total=header.n_particles_total; n_files =MAX(1,header.n_files); SID_Bcast(&n_particles_file, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&offset, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&n_particles_total,(int)sizeof(long long),read_rank,SID.COMM_WORLD); SID_Bcast(&n_files, (int)sizeof(int), read_rank,SID.COMM_WORLD); // Fetch the number of particles and their ids species_name =plist->species[GADGET_TYPE_DARK]; n_particles_local=((size_t *)ADaPS_fetch(plist->data,"n_%s", species_name))[0]; n_particles_all_mem =((size_t *)ADaPS_fetch(plist->data,"n_all_%s",species_name))[0]; ids = (size_t *)ADaPS_fetch(plist->data,"id_%s", species_name); expansion_factor =((double *)ADaPS_fetch(plist->data,"expansion_factor"))[0]; h_Hubble =((double *)ADaPS_fetch(plist->data,"h_Hubble"))[0]; // Check if we are dealing with LONG IDs or not if(ADaPS_exist(plist->data,"flag_LONGIDs")) flag_LONGIDs=TRUE; else flag_LONGIDs=FALSE; // Sort particle IDs SID_log("Sorting particle IDs...",SID_LOG_OPEN|SID_LOG_TIMER); merge_sort(ids,(size_t)n_particles_local,&ids_index,SID_SIZE_T,SORT_COMPUTE_INDEX,FALSE); SID_log("Done.",SID_LOG_CLOSE); // Allocate arrays SID_log("Allocating arrays...",SID_LOG_OPEN); read_array=(char *)SID_calloc(sizeof(char)*n_particles_local); for(i_quantity=0;i_quantity<n_quantities;i_quantity++){ switch(i_quantity){ case 0: r_smooth_array=(float *)SID_malloc(sizeof(float)*n_particles_local); ADaPS_store(&(plist->data),r_smooth_array,"r_smooth_%s",ADaPS_DEFAULT,species_name); break; case 1: rho_array=(float *)SID_malloc(sizeof(float)*n_particles_local); ADaPS_store(&(plist->data),rho_array,"rho_%s",ADaPS_DEFAULT,species_name); break; case 2: sigma_v_array=(float *)SID_malloc(sizeof(float)*n_particles_local); ADaPS_store(&(plist->data),sigma_v_array,"sigma_v_%s",ADaPS_DEFAULT,species_name); break; } } SID_log("Done.",SID_LOG_CLOSE); // Read each file in turn pcounter_info pcounter; size_t n_particles_read=0; SID_log("Performing read...",SID_LOG_OPEN|SID_LOG_TIMER); SID_init_pcounter(&pcounter,n_particles_total,10); for(i_file=0;i_file<n_files;i_file++){ set_smooth_filename(filename_root_in,snapshot_number,i_file,flag_multifile,flag_file_type,filename); if((fp=fopen(filename,"r"))!=NULL){ fread_verify(&(header.n_particles_file), sizeof(int), 1,fp); fread_verify(&(header.offset), sizeof(int), 1,fp); fread_verify(&(header.n_particles_total),sizeof(long long),1,fp); fread_verify(&(header.n_files), sizeof(int), 1,fp); } else SID_trap_error("Could not open smooth file {%s}",ERROR_IO_OPEN,filename); n_particles_file =header.n_particles_file; offset =header.offset; n_particles_total=header.n_particles_total; n_files =MAX(1,header.n_files); SID_Bcast(&n_particles_file, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&offset, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&n_particles_total,(int)sizeof(long long),read_rank,SID.COMM_WORLD); SID_Bcast(&n_files, (int)sizeof(int), read_rank,SID.COMM_WORLD); // Read IDs if(flag_LONGIDs){ if(i_file==0) SID_log("(long long) IDs...",SID_LOG_CONTINUE); id_buf =SID_malloc(sizeof(long long)*n_particles_file); id_buf_L=(long long *)id_buf; if(SID.My_rank==read_rank){ fseeko(fp,(size_t)(3*n_particles_file*sizeof(float)),SEEK_CUR); fread_verify(id_buf,sizeof(long long),n_particles_file,fp); } SID_Barrier(SID.COMM_WORLD); SID_Bcast(id_buf_L,(int)(n_particles_file*sizeof(long long)),read_rank,SID.COMM_WORLD); merge_sort(id_buf_L,(size_t)n_particles_file,&id_buf_index,SID_SIZE_T,SORT_COMPUTE_INDEX,FALSE); } else{ if(i_file==0) SID_log("(int) IDs...",SID_LOG_CONTINUE); id_buf =SID_malloc(sizeof(int)*n_particles_file); id_buf_i=(int *)id_buf; if(SID.My_rank==read_rank){ fseeko(fp,(size_t)(3*n_particles_file*sizeof(float)),SEEK_CUR); fread_verify(id_buf,sizeof(int),n_particles_file,fp); } SID_Barrier(SID.COMM_WORLD); SID_Bcast(id_buf_i,(int)(n_particles_file*sizeof(int)),read_rank,SID.COMM_WORLD); merge_sort(id_buf_i,(size_t)n_particles_file,&id_buf_index,SID_INT,SORT_COMPUTE_INDEX,FALSE); } // Create local particle mapping int n_mark_i=0; mark=(long long *)SID_malloc(sizeof(long long)*n_particles_file); for(i_particle=0;i_particle<n_particles_file;i_particle++) mark[i_particle]=-1; if(flag_LONGIDs){ for(i_particle=0,j_particle=0,n_mark=0;i_particle<n_particles_file && j_particle<n_particles_local;i_particle++){ while(j_particle<n_particles_local-1 && ids[ids_index[j_particle]]<id_buf_L[id_buf_index[i_particle]]) j_particle++; if(ids[ids_index[j_particle]]==id_buf_L[id_buf_index[i_particle]]){ mark[id_buf_index[i_particle]]=(long long)ids_index[j_particle]; n_mark++; n_mark_i++; } } } else{ for(i_particle=0,j_particle=0,n_mark=0;i_particle<n_particles_file && j_particle<n_particles_local;i_particle++){ while(j_particle<n_particles_local-1 && ids[ids_index[j_particle]]<id_buf_i[id_buf_index[i_particle]]) j_particle++; if(ids[ids_index[j_particle]]==id_buf_i[id_buf_index[i_particle]]){ mark[id_buf_index[i_particle]]=(long long)ids_index[j_particle]; n_mark++; n_mark_i++; } } } SID_free(SID_FARG id_buf); SID_free(SID_FARG id_buf_index); // Move to the start of the particle quantities if(SID.My_rank==read_rank){ rewind(fp); fread_verify(&n_particles_file, sizeof(int), 1,fp); fread_verify(&offset, sizeof(int), 1,fp); fread_verify(&n_particles_total,sizeof(long long),1,fp); fread_verify(&n_files, sizeof(int), 1,fp); n_files=MAX(1,n_files); } SID_Bcast(&n_particles_file, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&offset, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&n_particles_total,(int)sizeof(long long),read_rank,SID.COMM_WORLD); SID_Bcast(&n_files, (int)sizeof(int), read_rank,SID.COMM_WORLD); buffer=SID_malloc(sizeof(float)*n_particles_file); for(i_quantity=0;i_quantity<n_quantities;i_quantity++){ int flag_log_quantity; switch(i_quantity){ case 0: sprintf(var_name,"r_smooth_%s",species_name); sprintf(unit_name,"Mpc"); unit_factor=plist->length_unit/h_Hubble; local_array=r_smooth_array; break; case 1: sprintf(var_name,"rho_%s",species_name); sprintf(unit_name,"Msol/Mpc^3"); unit_factor=h_Hubble*h_Hubble*plist->mass_unit/pow(plist->length_unit,3.); local_array=rho_array; break; case 2: sprintf(var_name,"sigma_v_%s",species_name); sprintf(unit_name,"km/s"); unit_factor=sqrt(expansion_factor)*plist->velocity_unit; local_array=sigma_v_array; break; } // Read next quantity if(SID.My_rank==read_rank) fread_verify(buffer,sizeof(float),n_particles_file,fp); SID_Barrier(SID.COMM_WORLD); SID_Bcast(buffer,(int)(n_particles_file*sizeof(float)),read_rank,SID.COMM_WORLD); // Place in final array if(n_mark_i>0){ if(i_quantity==0){ for(i_particle=0;i_particle<n_particles_file;i_particle++) if(mark[i_particle]>=0) read_array[mark[i_particle]]=TRUE; } for(i_particle=0;i_particle<n_particles_file;i_particle++) if(mark[i_particle]>=0) local_array[mark[i_particle]]=((float *)buffer)[i_particle]*unit_factor; } } SID_free(SID_FARG mark); SID_free(SID_FARG buffer); if(SID.My_rank==read_rank) fclose(fp); n_particles_read+=n_particles_file; if(n_files>1) SID_check_pcounter(&pcounter,n_particles_read); } // i_file SID_free(SID_FARG ids_index); SID_Barrier(SID.COMM_WORLD); SID_log("Done.",SID_LOG_CLOSE); // Check that all particles have been treated size_t sum_check=0; for(i_particle=0;i_particle<n_particles_local;i_particle++) sum_check+=(size_t)read_array[i_particle]; SID_Allreduce(SID_IN_PLACE,&sum_check,1,SID_SIZE_T,SID_SUM,SID.COMM_WORLD); if(sum_check!=n_particles_all_mem) SID_trap_error("Only %lld of %lld particles were set.",ERROR_LOGIC,sum_check,n_particles_all_mem); SID_free(SID_FARG read_array); SID_log("Summary...",SID_LOG_OPEN); for(i_quantity=0;i_quantity<n_quantities;i_quantity++){ char var_name[32]; switch(i_quantity){ case 0: sprintf(var_name,"Lengths: "); sprintf(unit_name,"Mpc"); unit_factor=1./M_PER_MPC; local_array=r_smooth_array; break; case 1: sprintf(var_name,"Densities: "); sprintf(unit_name,"Msol/Mpc^3"); unit_factor=M_PER_MPC*M_PER_MPC*M_PER_MPC/M_SOL; local_array=rho_array; break; case 2: sprintf(var_name,"sigmas_v's:"); sprintf(unit_name,"km/s"); unit_factor=1e-3; local_array=sigma_v_array; break; } // Report some stats float var_min,var_max,var_mean; calc_min_global(local_array, &var_min, n_particles_local, SID_FLOAT, CALC_MODE_DEFAULT, SID.COMM_WORLD); calc_max_global(local_array, &var_max, n_particles_local, SID_FLOAT, CALC_MODE_DEFAULT, SID.COMM_WORLD); calc_mean_global(local_array, &var_mean, n_particles_local, SID_FLOAT, CALC_MODE_DEFAULT, SID.COMM_WORLD); // Remove NaN's from sigma_v's if needed size_t n_NaN=0; for(i_particle=0;i_particle<n_particles_local;i_particle++){ if(isnan(local_array[i_particle])){ local_array[i_particle]=1000.*0.5*(var_min+var_max); n_NaN++; } } if(n_NaN>0) SID_log("%s min=%e max=%e mean=%e [%s] (%lld are NaN)", SID_LOG_COMMENT, var_name, var_min*unit_factor, var_max*unit_factor, var_mean*unit_factor, unit_name, n_NaN); else SID_log("%s min=%e max=%e mean=%e [%s]", SID_LOG_COMMENT, var_name, var_min*unit_factor, var_max*unit_factor, var_mean*unit_factor, unit_name); } SID_log("",SID_LOG_CLOSE|SID_LOG_NOPRINT); if(flag_logs_used){ SID_log("Taking needed logs of quantities...",SID_LOG_OPEN|SID_LOG_TIMER); for(i_quantity=0;i_quantity<n_quantities;i_quantity++){ switch(i_quantity){ case 0: unit_factor=1./M_PER_MPC; local_array=r_smooth_array; flag_log_quantity=FALSE; break; case 1: unit_factor=M_PER_MPC*M_PER_MPC*M_PER_MPC/M_SOL; local_array=rho_array; flag_log_quantity=flag_log_rho; break; case 2: unit_factor=1e-3; local_array=sigma_v_array; flag_log_quantity=flag_log_sigma; break; } if(flag_log_quantity){ for(i_particle=0;i_particle<n_particles_local;i_particle++) local_array[i_particle]=take_log10(local_array[i_particle]); } } SID_log("Done.",SID_LOG_CLOSE); } SID_Barrier(SID.COMM_WORLD); SID_log("Done.",SID_LOG_CLOSE); } else SID_trap_error("Could not find file with root {%s}",ERROR_IO_OPEN,filename_root_in); }
int compute_group_analysis(halo_properties_info *properties, halo_profile_info *profile, double (*p_i_fctn) (void *,int,int), double (*v_i_fctn) (void *,int,int), size_t (*id_i_fctn)(void *,int), void *params, double box_size, double particle_mass, int n_particles, double expansion_factor, double *x, double *y, double *z, double *vx, double *vy, double *vz, double *R, size_t **R_index_in, int flag_manual_centre, int flag_compute_shapes, cosmo_info *cosmo){ size_t *R_index; int i,j; int i_profile; int j_profile; int k_profile; int n_profile; size_t i_particle; size_t j_particle; size_t k_particle; int next_bin_particle; interp_info *V_R_interpolate; interp_info *vir_interpolate; int i_bin; int n_in_bin; double n_per_bin; int n_cumulative; double V1; double V2; double dV; double dM; double sigma_r_mean; double sigma_t_mean; double sigma_T_mean; double sigma_P_mean; double sigma_mean; double x_COM_accumulator; double y_COM_accumulator; double z_COM_accumulator; double vx_COM_accumulator; double vy_COM_accumulator; double vz_COM_accumulator; double spin_x_accumulator; double spin_y_accumulator; double spin_z_accumulator; double r_xy; double v_tot,v_rad,v_tan; double v_x_mean,v_y_mean,v_z_mean,v_rad_mean; double shape_eigen_values[3]; double shape_eigen_vectors[3][3]; double x_COM,y_COM,z_COM,R_COM; double r_c[MAX_PROFILE_BINS_P1]; double v_c[MAX_PROFILE_BINS_P1]; double r_interp[MAX_PROFILE_BINS]; double y_interp[MAX_PROFILE_BINS]; size_t n_bins_temp; double V_max,R_max; double Delta,Omega; double norm; int flag_interpolated=FALSE; const gsl_interp_type *interp_type; double sigma_cor,sigma_halo; double M_cor,M_halo; double x_vir,gamma; double h_Hubble=((double *)ADaPS_fetch(cosmo,"h_Hubble"))[0]; double Omega_M =((double *)ADaPS_fetch(cosmo,"Omega_M"))[0]; double redshift=z_of_a(expansion_factor); Delta=Delta_vir(redshift,cosmo); Omega=1.; // Initialize properties properties->id_MBP =id_i_fctn(params,0);//id_array[index_MBP]; properties->n_particles =n_particles; properties->position_COM[0]=0.; properties->position_COM[1]=0.; properties->position_COM[2]=0.; properties->position_MBP[0]=(float)p_i_fctn(params,0,0);//(x_array[index_MBP]); properties->position_MBP[1]=(float)p_i_fctn(params,1,0);//(y_array[index_MBP]); properties->position_MBP[2]=(float)p_i_fctn(params,2,0);//(z_array[index_MBP]); properties->velocity_COM[0]=0.; properties->velocity_COM[1]=0.; properties->velocity_COM[2]=0.; properties->velocity_MBP[0]=(float)v_i_fctn(params,0,0);//(vx_array[index_MBP]); properties->velocity_MBP[1]=(float)v_i_fctn(params,1,0);//(vy_array[index_MBP]); properties->velocity_MBP[2]=(float)v_i_fctn(params,2,0);//(vz_array[index_MBP]); properties->M_vir =0.; properties->R_vir =0.; properties->R_halo =0.; properties->R_max =0.; properties->V_max =0.; properties->sigma_v =0.; properties->spin[0] =0.; properties->spin[1] =0.; properties->spin[2] =0.; properties->q_triaxial =1.; properties->s_triaxial =1.; for(i=0;i<3;i++){ for(j=0;j<3;j++) properties->shape_eigen_vectors[i][j]=0.; properties->shape_eigen_vectors[i][i]=1.; } // Set the number of profile bins and the number of particles per bin profile->n_bins=MAX(MIN_PROFILE_BINS,MIN((int)((6.2*log10((double)n_particles)-3.5)+((double)n_particles/1000.)+1),MAX_PROFILE_BINS)); n_per_bin =(double)(n_particles)/(double)profile->n_bins; // There's nothing to do if there are no particles if(n_particles==0) profile->n_bins=0; else{ // Create a v_c(0)=0 bin r_c[0]=0.; v_c[0]=0.; // Initialize profiles for(i_bin=0;i_bin<profile->n_bins;i_bin++){ profile->bins[i_bin].r_med =0.; profile->bins[i_bin].r_max =0.; profile->bins[i_bin].n_particles =0; profile->bins[i_bin].M_r =0.; profile->bins[i_bin].rho =0.; profile->bins[i_bin].overdensity =0.; profile->bins[i_bin].position_COM[0] =0.; profile->bins[i_bin].position_COM[1] =0.; profile->bins[i_bin].position_COM[2] =0.; profile->bins[i_bin].velocity_COM[0] =0.; profile->bins[i_bin].velocity_COM[1] =0.; profile->bins[i_bin].velocity_COM[2] =0.; profile->bins[i_bin].sigma_rad =0.; profile->bins[i_bin].sigma_tan =0.; profile->bins[i_bin].sigma_tot =0.; profile->bins[i_bin].spin[0] =0.; profile->bins[i_bin].spin[1] =0.; profile->bins[i_bin].spin[2] =0.; profile->bins[i_bin].q_triaxial =1.; profile->bins[i_bin].s_triaxial =1.; for(i=0;i<3;i++){ for(j=0;j<3;j++) profile->bins[i_bin].shape_eigen_vectors[i][j]=0.; profile->bins[i_bin].shape_eigen_vectors[i][i]=1.; } } // Fill temporary arrays for particle positions, radii (all w.r.t MBP) and velocities // Also, enforce periodic box on particle positions double x_cen; double y_cen; double z_cen; x_cen=(double)properties->position_MBP[0]; y_cen=(double)properties->position_MBP[1]; z_cen=(double)properties->position_MBP[2]; if(flag_manual_centre){ double x_cen_manual; double y_cen_manual; double z_cen_manual; // Compute a rough comoving centre for(j_particle=0;j_particle<n_particles;j_particle++){ x[j_particle]=d_periodic(p_i_fctn(params,0,j_particle)-x_cen,box_size);//(double)(x_array[k_particle])-x_cen,box_size); y[j_particle]=d_periodic(p_i_fctn(params,1,j_particle)-y_cen,box_size);//(double)(y_array[k_particle])-y_cen,box_size); z[j_particle]=d_periodic(p_i_fctn(params,2,j_particle)-z_cen,box_size);//(double)(z_array[k_particle])-z_cen,box_size); } // Refine it with shrinking spheres int n_iterations; n_iterations=compute_centroid3D(NULL, x, y, z, n_particles, 1e-3, // 1 kpc 0.75, 30, CENTROID3D_MODE_FACTOR|CENTROID3D_MODE_INPLACE, &x_cen_manual, &y_cen_manual, &z_cen_manual); x_cen+=x_cen_manual; y_cen+=y_cen_manual; z_cen+=z_cen_manual; properties->position_MBP[0]=x_cen; properties->position_MBP[1]=y_cen; properties->position_MBP[2]=z_cen; if(properties->position_MBP[0]< box_size) properties->position_MBP[0]+=box_size; if(properties->position_MBP[1]< box_size) properties->position_MBP[1]+=box_size; if(properties->position_MBP[2]< box_size) properties->position_MBP[2]+=box_size; if(properties->position_MBP[0]>=box_size) properties->position_MBP[0]-=box_size; if(properties->position_MBP[1]>=box_size) properties->position_MBP[1]-=box_size; if(properties->position_MBP[2]>=box_size) properties->position_MBP[2]-=box_size; } for(j_particle=0;j_particle<n_particles;j_particle++){ // ... halo-centric particle positions ... x[j_particle]=expansion_factor*d_periodic(p_i_fctn(params,0,j_particle)-x_cen,box_size);//((double)x_array[k_particle])-x_cen,box_size); y[j_particle]=expansion_factor*d_periodic(p_i_fctn(params,1,j_particle)-y_cen,box_size);//((double)y_array[k_particle])-y_cen,box_size); z[j_particle]=expansion_factor*d_periodic(p_i_fctn(params,2,j_particle)-z_cen,box_size);//((double)z_array[k_particle])-z_cen,box_size); // ... velocities ... vx[j_particle]=v_i_fctn(params,0,j_particle);//(double)(vx_array[k_particle]); vy[j_particle]=v_i_fctn(params,1,j_particle);//(double)(vy_array[k_particle]); vz[j_particle]=v_i_fctn(params,2,j_particle);//(double)(vz_array[k_particle]); // ... particle radii ... R[j_particle]=sqrt(x[j_particle]*x[j_particle]+y[j_particle]*y[j_particle]+z[j_particle]*z[j_particle]); } // Sort particles by radius merge_sort((void *)R,(size_t)n_particles,R_index_in,SID_DOUBLE,SORT_COMPUTE_INDEX,SORT_COMPUTE_NOT_INPLACE); R_index=(*R_index_in); // Use the average of the central 30 particles for the MBP velocity if we are // manually computing centres if(flag_manual_centre){ double vx_cen_temp=0.; double vy_cen_temp=0.; double vz_cen_temp=0.; int n_cen =0; for(i_particle=0;i_particle<MIN(30,n_particles);i_particle++){ vx_cen_temp+=vx[i_particle]; vy_cen_temp+=vy[i_particle]; vz_cen_temp+=vz[i_particle]; n_cen++; } properties->velocity_MBP[0]=vx_cen_temp/(double)n_cen; properties->velocity_MBP[1]=vy_cen_temp/(double)n_cen; properties->velocity_MBP[2]=vz_cen_temp/(double)n_cen; } // We need the COM velocity at R_vir before we can get halo centric velocities. Thus, // we need the overdensity profile first x_COM_accumulator =0.; y_COM_accumulator =0.; z_COM_accumulator =0.; vx_COM_accumulator =0.; vy_COM_accumulator =0.; vz_COM_accumulator =0.; V2 =0.; n_cumulative =0; for(i_bin=0,i_particle=0;i_bin<profile->n_bins;i_bin++,i_particle+=n_in_bin){ V1=V2; // Volumes // ... particle numbers ... if(i_bin<profile->n_bins-1) n_in_bin=(int)((double)(i_bin+1)*n_per_bin)-i_particle; else n_in_bin=n_particles-i_particle; n_cumulative +=n_in_bin; profile->bins[i_bin].n_particles =n_in_bin; // ... mass profile ... profile->bins[i_bin].M_r=particle_mass*(double)n_cumulative; // ... binning radii ... if(n_in_bin%2==1) profile->bins[i_bin].r_med=(float)R[R_index[i_particle+n_in_bin/2]]; else profile->bins[i_bin].r_med=0.5*(float)(R[R_index[i_particle+n_in_bin/2-1]]+R[R_index[i_particle+n_in_bin/2]]); profile->bins[i_bin].r_max=(float)R[R_index[i_particle+n_in_bin-1]]; // ... COM positions and velocities ... for(j_particle=0;j_particle<n_in_bin;j_particle++){ k_particle=R_index[i_particle+j_particle]; x_COM_accumulator += x[k_particle]; y_COM_accumulator += y[k_particle]; z_COM_accumulator += z[k_particle]; vx_COM_accumulator+=vx[k_particle]; vy_COM_accumulator+=vy[k_particle]; vz_COM_accumulator+=vz[k_particle]; } profile->bins[i_bin].position_COM[0]=(float)(x_COM_accumulator/(double)n_cumulative); profile->bins[i_bin].position_COM[1]=(float)(y_COM_accumulator/(double)n_cumulative); profile->bins[i_bin].position_COM[2]=(float)(z_COM_accumulator/(double)n_cumulative); profile->bins[i_bin].velocity_COM[0]=(float)(vx_COM_accumulator/(double)n_cumulative); profile->bins[i_bin].velocity_COM[1]=(float)(vy_COM_accumulator/(double)n_cumulative); profile->bins[i_bin].velocity_COM[2]=(float)(vz_COM_accumulator/(double)n_cumulative); // ... density ... V2=FOUR_THIRDS_PI*profile->bins[i_bin].r_max*profile->bins[i_bin].r_max*profile->bins[i_bin].r_max; // Volume dV=V2-V1; dM=particle_mass*(double)n_in_bin; profile->bins[i_bin].rho =(float)(dM/dV); profile->bins[i_bin].overdensity=(float)(profile->bins[i_bin].M_r/(V2*Omega*rho_crit_z(redshift,cosmo))); /// ... triaxiality ... if(flag_compute_shapes){ compute_triaxiality(x, y, z, (double)profile->bins[i_bin].position_COM[0], (double)profile->bins[i_bin].position_COM[1], (double)profile->bins[i_bin].position_COM[2], box_size, n_cumulative, R_index, shape_eigen_values, shape_eigen_vectors); profile->bins[i_bin].q_triaxial=(float)(shape_eigen_values[1]/shape_eigen_values[0]); profile->bins[i_bin].s_triaxial=(float)(shape_eigen_values[2]/shape_eigen_values[0]); for(i=0;i<3;i++) for(j=0;j<3;j++) profile->bins[i_bin].shape_eigen_vectors[i][j]=(float)shape_eigen_vectors[i][j]; } } // Interpolate to get R_vir flag_interpolated=FALSE; properties->R_halo=profile->bins[profile->n_bins-1].r_max; if(profile->n_bins>1){ // Remove any small-radius monotonic increases from the interpolation interval j_profile=0; while(profile->bins[j_profile].overdensity<=profile->bins[j_profile+1].overdensity && j_profile<profile->n_bins-2) j_profile++; // Only keep decreasing bins n_bins_temp=0; r_interp[n_bins_temp]=take_log10((double)profile->bins[j_profile].r_max); y_interp[n_bins_temp]=take_log10((double)profile->bins[j_profile].overdensity); n_bins_temp++; for(i_profile=j_profile+1;i_profile<profile->n_bins;i_profile++){ if(take_log10((double)profile->bins[i_profile].overdensity)<y_interp[n_bins_temp-1]){ r_interp[n_bins_temp]=take_log10((double)profile->bins[i_profile].r_max); y_interp[n_bins_temp]=take_log10((double)profile->bins[i_profile].overdensity); n_bins_temp++; } } if(n_bins_temp>1){ // Perform interpolation if(y_interp[0]>=take_log10(Delta) && y_interp[n_bins_temp-1]<=take_log10(Delta)){ if(n_bins_temp>9) interp_type=gsl_interp_cspline; else interp_type=gsl_interp_linear; interp_type=gsl_interp_linear; init_interpolate(y_interp,r_interp,n_bins_temp,interp_type,&vir_interpolate); properties->R_vir =(float)take_alog10(interpolate(vir_interpolate,take_log10(Delta))); free_interpolate(SID_FARG vir_interpolate,NULL); flag_interpolated=TRUE; } else if(y_interp[0]<take_log10(Delta)){ properties->R_vir=(float)take_alog10(r_interp[0]); flag_interpolated=FLAG_INTERP_MIN_BIN; } else{ properties->R_vir=(float)take_alog10(r_interp[n_bins_temp-1]); flag_interpolated=FLAG_INTERP_MAX_BIN; } } else{ properties->R_vir=(float)take_alog10(r_interp[0]); flag_interpolated=FLAG_INTERP_MIN_BIN; } } else{ properties->R_vir=profile->bins[0].r_max; flag_interpolated=FLAG_INTERP_MIN_BIN; } // Set the interpolation method if(n_bins_temp>9) interp_type=gsl_interp_cspline; else interp_type=gsl_interp_linear; interp_type=gsl_interp_linear; // Compute v_COM(R_vir) for(i_profile=0;i_profile<profile->n_bins;i_profile++) r_interp[i_profile]=(double)profile->bins[i_profile].r_max; if(flag_interpolated==TRUE){ for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].velocity_COM[0]; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->velocity_COM[0]=(float)interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].velocity_COM[1]; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->velocity_COM[1]=(float)interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].velocity_COM[2]; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->velocity_COM[2]=(float)interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); } else{ if(flag_interpolated==FLAG_INTERP_MIN_BIN) i_profile=0; else if(flag_interpolated==FLAG_INTERP_MAX_BIN) i_profile=profile->n_bins-1; else SID_trap_error("Unrecognized value for flag_interpolated {%d}.",flag_interpolated); properties->velocity_COM[0]=(float)profile->bins[i_profile].velocity_COM[0]; properties->velocity_COM[1]=(float)profile->bins[i_profile].velocity_COM[1]; properties->velocity_COM[2]=(float)profile->bins[i_profile].velocity_COM[2]; } // Compute halo-centric particle velocities // Subtract COM mean and add Hubble flow for(j_particle=0;j_particle<n_particles;j_particle++){ vx[j_particle]+=x[j_particle]*H_convert(H_z(redshift,cosmo))-(double)properties->velocity_COM[0]; vy[j_particle]+=y[j_particle]*H_convert(H_z(redshift,cosmo))-(double)properties->velocity_COM[1]; vz[j_particle]+=z[j_particle]*H_convert(H_z(redshift,cosmo))-(double)properties->velocity_COM[2]; } // Compute remaining profiles ... spin_x_accumulator=0.; spin_y_accumulator=0.; spin_z_accumulator=0.; V2 =0.; n_cumulative =0; for(i_bin=0,i_particle=0;i_bin<profile->n_bins;i_bin++,i_particle+=n_in_bin){ V1=V2; // Volumes // ... particle numbers ... if(i_bin<profile->n_bins-1) n_in_bin=(int)((double)(i_bin+1)*n_per_bin)-i_particle; else n_in_bin=n_particles-i_particle; n_cumulative+=n_in_bin; // ... spins and mean velocities ... v_x_mean =0.; v_y_mean =0.; v_z_mean =0.; v_rad_mean=0.; for(j_particle=0;j_particle<n_in_bin;j_particle++){ k_particle=R_index[i_particle+j_particle]; // ... spins ... spin_x_accumulator+=(double)(y[k_particle]*vz[k_particle]-z[k_particle]*vy[k_particle]); spin_y_accumulator+=(double)(z[k_particle]*vx[k_particle]-x[k_particle]*vz[k_particle]); spin_z_accumulator+=(double)(x[k_particle]*vy[k_particle]-y[k_particle]*vx[k_particle]); // ... mean velocities (needed below for velocity dispersions) ... if(R[k_particle]>0.){ v_rad =(x[k_particle]*vx[k_particle]+y[k_particle]*vy[k_particle]+z[k_particle]*vz[k_particle])/R[k_particle]; v_x_mean +=vx[k_particle]; v_y_mean +=vy[k_particle]; v_z_mean +=vz[k_particle]; v_rad_mean+=v_rad; } } profile->bins[i_bin].spin[0]=(float)(spin_x_accumulator)/n_cumulative; profile->bins[i_bin].spin[1]=(float)(spin_y_accumulator)/n_cumulative; profile->bins[i_bin].spin[2]=(float)(spin_z_accumulator)/n_cumulative; v_x_mean /=(double)n_in_bin; v_y_mean /=(double)n_in_bin; v_z_mean /=(double)n_in_bin; v_rad_mean/=(double)n_in_bin; // ... velocity dispersions ... for(j_particle=0;j_particle<n_in_bin;j_particle++){ k_particle=R_index[i_particle+j_particle]; if(R[k_particle]>0.){ v_tot=sqrt(pow(vx[k_particle]-v_x_mean,2.)+pow(vy[k_particle]-v_y_mean,2.)+pow(vz[k_particle]-v_z_mean,2.)); v_rad=(x[k_particle]*(vx[k_particle]-v_x_mean)+y[k_particle]*(vy[k_particle]-v_y_mean)+z[k_particle]*(vz[k_particle]-v_z_mean))/R[k_particle]; v_tan=sqrt(v_tot*v_tot-v_rad*v_rad); profile->bins[i_bin].sigma_tot+=(float)((v_tot)*(v_tot)); profile->bins[i_bin].sigma_rad+=(float)((v_rad-v_rad_mean)*(v_rad-v_rad_mean)); profile->bins[i_bin].sigma_tan+=(float)((v_tan)*(v_tan)); } } profile->bins[i_bin].sigma_tot=(float)sqrt((double)profile->bins[i_bin].sigma_tot/(double)n_in_bin); profile->bins[i_bin].sigma_rad=(float)sqrt((double)profile->bins[i_bin].sigma_rad/(double)n_in_bin); profile->bins[i_bin].sigma_tan=(float)sqrt((double)profile->bins[i_bin].sigma_tan/(double)n_in_bin); // ... circular velocity; v_c(R) ... r_c[i_bin+1]=profile->bins[i_bin].r_max; v_c[i_bin+1]=sqrt(G_NEWTON*profile->bins[i_bin].M_r/(double)profile->bins[i_bin].r_max); } // Determine R_max and V_max from v_c(R)... R_max=(double)r_c[1]; // default for a monotonically increasing V_c(r) V_max=(double)v_c[1]; // default for a monotonically increasing V_c(r) if(profile->n_bins>1){ // Remove any large-radius monotonic increases from the interpolation interval k_profile=profile->n_bins; while(v_c[k_profile-1]<=v_c[k_profile] && k_profile>1) k_profile--; if(v_c[0]<=v_c[1] && k_profile==1) k_profile--; // If the profile is not monotonically increasing ... if(k_profile>0){ n_bins_temp=k_profile+1; // ...find the maximum (call its index j_profile) for(i_profile=0,j_profile=0;i_profile<n_bins_temp;i_profile++){ if(v_c[i_profile]>v_c[j_profile]) j_profile=i_profile; } // ...find bottom of range in which to search for maximum (call its index i_profile) i_profile=j_profile-1; while(v_c[i_profile]>=v_c[j_profile] && i_profile>0) i_profile--; // ...find top of range in which to search for maximum (call its index k_profile) k_profile=j_profile+1; while(v_c[k_profile]>=v_c[j_profile] && k_profile<n_bins_temp-1) k_profile++; // ... perform interpolation V_max=(double)v_c[j_profile]; R_max=(double)r_c[j_profile]; if(i_profile<j_profile && j_profile<k_profile){ if(n_bins_temp>9) interp_type=gsl_interp_cspline; else interp_type=gsl_interp_linear; interp_type=gsl_interp_linear; init_interpolate(r_c,v_c,n_bins_temp,gsl_interp_cspline,&V_R_interpolate); interpolate_maximum(V_R_interpolate, r_c[i_profile], r_c[j_profile], r_c[k_profile], 0.05, &R_max, &V_max); free_interpolate(SID_FARG V_R_interpolate,NULL); } } } properties->R_max=(float)R_max; properties->V_max=(float)V_max; if(profile->n_bins>9) interp_type=gsl_interp_cspline; else interp_type=gsl_interp_linear; interp_type=gsl_interp_linear; // Perform normal interpolation from profiles to get the rest of the global quantities if(flag_interpolated==TRUE){ // ... COM positions ... for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].position_COM[0]/expansion_factor; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->position_COM[0]=(float)interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].position_COM[1]/expansion_factor; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->position_COM[1]=(float)interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].position_COM[2]/expansion_factor; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->position_COM[2]=(float)interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); // ... M_vir ... for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].M_r; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->M_vir=interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); // ... sigma_v ... for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].sigma_tot; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->sigma_v=(float)interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); // ... spin ... for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].spin[0]; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->spin[0]=(float)interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].spin[1]; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->spin[1]=(float)interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].spin[2]; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->spin[2]=(float)interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); // ... triaxial axes ratios ... for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].q_triaxial; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->q_triaxial=(float)interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)profile->bins[i_profile].s_triaxial; init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->s_triaxial=(float)interpolate(vir_interpolate,properties->R_vir); free_interpolate(SID_FARG vir_interpolate,NULL); // ... shape eigen vectors ... for(i=0;i<3;i++){ for(j=0;j<3;j++){ for(i_profile=0;i_profile<profile->n_bins;i_profile++) y_interp[i_profile]=(double)cos(profile->bins[i_profile].shape_eigen_vectors[i][j]); init_interpolate(r_interp,y_interp,profile->n_bins,interp_type,&vir_interpolate); properties->shape_eigen_vectors[i][j]=(float)acos(MAX(0,MIN(1.,interpolate(vir_interpolate,properties->R_vir)))); free_interpolate(SID_FARG vir_interpolate,NULL); } norm=sqrt(properties->shape_eigen_vectors[i][0]*properties->shape_eigen_vectors[i][0]+ properties->shape_eigen_vectors[i][1]*properties->shape_eigen_vectors[i][1]+ properties->shape_eigen_vectors[i][2]*properties->shape_eigen_vectors[i][2]); for(j=0;j<3;j++) properties->shape_eigen_vectors[i][j]/=norm; } } // ... else apply defaults to faulty cases. else{ if(flag_interpolated==FLAG_INTERP_MIN_BIN) i_profile=0; else if(flag_interpolated==FLAG_INTERP_MAX_BIN) i_profile=profile->n_bins-1; else SID_trap_error("Unrecognized value for flag_interpolated {%d}.",flag_interpolated); // ... COM positions ... properties->position_COM[0]=(double)(profile->bins[i_profile].position_COM[0])/expansion_factor; properties->position_COM[1]=(double)(profile->bins[i_profile].position_COM[1])/expansion_factor; properties->position_COM[2]=(double)(profile->bins[i_profile].position_COM[2])/expansion_factor; // ... M_vir ... properties->M_vir=(double)profile->bins[i_profile].M_r; // ... sigma_v ... properties->sigma_v=(float)profile->bins[i_profile].sigma_tot; // ... spin ... properties->spin[0]=(float)profile->bins[i_profile].spin[0]; properties->spin[1]=(float)profile->bins[i_profile].spin[1]; properties->spin[2]=(float)profile->bins[i_profile].spin[2]; // ... triaxial axes ratios ... properties->q_triaxial=(float)profile->bins[i_profile].q_triaxial; properties->s_triaxial=(float)profile->bins[i_profile].s_triaxial; // ... shape eigen vectors ... for(i=0;i<3;i++){ for(j=0;j<3;j++) properties->shape_eigen_vectors[i][j]=(float)profile->bins[i_profile].shape_eigen_vectors[i][j]; norm=sqrt(properties->shape_eigen_vectors[i][0]*properties->shape_eigen_vectors[i][0]+ properties->shape_eigen_vectors[i][1]*properties->shape_eigen_vectors[i][1]+ properties->shape_eigen_vectors[i][2]*properties->shape_eigen_vectors[i][2]); for(j=0;j<3;j++) properties->shape_eigen_vectors[i][j]/=norm; } } // Enforce periodic box on COM position properties->position_COM[0]+=x_cen; properties->position_COM[1]+=y_cen; properties->position_COM[2]+=z_cen; if(properties->position_COM[0]< box_size) properties->position_COM[0]+=box_size; if(properties->position_COM[1]< box_size) properties->position_COM[1]+=box_size; if(properties->position_COM[2]< box_size) properties->position_COM[2]+=box_size; if(properties->position_COM[0]>=box_size) properties->position_COM[0]-=box_size; if(properties->position_COM[1]>=box_size) properties->position_COM[1]-=box_size; if(properties->position_COM[2]>=box_size) properties->position_COM[2]-=box_size; // Perform unit conversions // ... properties first ... properties->position_COM[0]*=h_Hubble/M_PER_MPC; properties->position_COM[1]*=h_Hubble/M_PER_MPC; properties->position_COM[2]*=h_Hubble/M_PER_MPC; properties->position_MBP[0]*=h_Hubble/M_PER_MPC; properties->position_MBP[1]*=h_Hubble/M_PER_MPC; properties->position_MBP[2]*=h_Hubble/M_PER_MPC; properties->velocity_COM[0]*=1e-3; properties->velocity_COM[1]*=1e-3; properties->velocity_COM[2]*=1e-3; properties->velocity_MBP[0]*=1e-3; properties->velocity_MBP[1]*=1e-3; properties->velocity_MBP[2]*=1e-3; properties->M_vir *=h_Hubble/M_SOL; properties->R_vir *=h_Hubble/M_PER_MPC; properties->R_halo *=h_Hubble/M_PER_MPC; properties->R_max *=h_Hubble/M_PER_MPC; properties->V_max *=1e-3; properties->sigma_v *=1e-3; properties->spin[0] *=1e-3*h_Hubble/M_PER_MPC; properties->spin[1] *=1e-3*h_Hubble/M_PER_MPC; properties->spin[2] *=1e-3*h_Hubble/M_PER_MPC; // ... then profiles ... for(i_bin=0;i_bin<profile->n_bins;i_bin++){ profile->bins[i_bin].r_med *=h_Hubble/M_PER_MPC; profile->bins[i_bin].r_max *=h_Hubble/M_PER_MPC; profile->bins[i_bin].M_r *=h_Hubble/M_SOL; profile->bins[i_bin].rho *=M_PER_MPC*M_PER_MPC*M_PER_MPC/(h_Hubble*h_Hubble*M_SOL); profile->bins[i_bin].position_COM[0]*=h_Hubble/M_PER_MPC; profile->bins[i_bin].position_COM[1]*=h_Hubble/M_PER_MPC; profile->bins[i_bin].position_COM[2]*=h_Hubble/M_PER_MPC; profile->bins[i_bin].velocity_COM[0]*=1e-3; profile->bins[i_bin].velocity_COM[1]*=1e-3; profile->bins[i_bin].velocity_COM[2]*=1e-3; profile->bins[i_bin].sigma_rad *=1e-3; profile->bins[i_bin].sigma_tan *=1e-3; profile->bins[i_bin].sigma_tot *=1e-3; profile->bins[i_bin].spin[0] *=1e-3*h_Hubble/M_PER_MPC; profile->bins[i_bin].spin[1] *=1e-3*h_Hubble/M_PER_MPC; profile->bins[i_bin].spin[2] *=1e-3*h_Hubble/M_PER_MPC; } } return(flag_interpolated); }
double bias_model(double x_in, double delta_c, double z, cosmo_info **cosmo, int mode) { // Decide what the input is int flag_Vmax_ordinate = SID_CHECK_BITFIELD_SWITCH(mode, BIAS_MODEL_VMAX_ORDINATE); double M_R; double V_max; if(flag_Vmax_ordinate) V_max = x_in; else M_R = x_in; double bias; int flag_done = GBP_FALSE; // Tinker et al 2010 if(SID_CHECK_BITFIELD_SWITCH(mode, BIAS_MODEL_TRK)) { if(flag_done) SID_exit_error("Mode flag (%d) is invalid in bias_model(). Multiple model definitions.", SID_ERROR_LOGIC, mode); flag_done = GBP_TRUE; if(flag_Vmax_ordinate) M_R = Vmax_to_Mvir_NFW(V_max, z, NFW_MODE_DEFAULT, cosmo); double y = take_log10(Delta_vir(z, *cosmo)); double A = 1. + 0.24 * y * exp(-pow(4. / y, 4.)); double B = 0.183; double C = 0.019 + 0.107 * y + 0.19 * exp(-pow(4. / y, 4.)); double a = 0.44 * y - 0.88; double b = 1.5; double c = 2.4; double sigma = sigma_M(cosmo, M_R, z, PSPEC_LINEAR_TF, PSPEC_ALL_MATTER); double nu = delta_c / sigma; bias = 1. - A * pow(nu, a) / (pow(nu, a) + pow(delta_c, a)) + B * pow(nu, b) + C * pow(nu, c); } // Basilakos and Plionis (2001;2003) w/ Papageorgiou et al 2013 coeeficients if(SID_CHECK_BITFIELD_SWITCH(mode, BIAS_MODEL_BPR)) { if(flag_done) SID_exit_error("Mode flag (%d) is invalid in bias_model(). Multiple model definitions.", SID_ERROR_LOGIC, mode); flag_done = GBP_TRUE; if(flag_Vmax_ordinate) M_R = Vmax_to_Mvir_NFW(V_max, z, NFW_MODE_DEFAULT, cosmo); double alpha_1 = 4.53; double alpha_2 = -0.41; double beta_1 = 0.37; double beta_2 = 0.36; double I_z; double C_1; double C_2; double Omega_M, Omega_k, Omega_Lambda, h_Hubble; double Ez; Omega_M = ((double *)ADaPS_fetch(*cosmo, "Omega_M"))[0]; Omega_k = ((double *)ADaPS_fetch(*cosmo, "Omega_k"))[0]; Omega_Lambda = ((double *)ADaPS_fetch(*cosmo, "Omega_Lambda"))[0]; h_Hubble = ((double *)ADaPS_fetch(*cosmo, "h_Hubble"))[0]; Ez = E_z(Omega_M, Omega_k, Omega_Lambda, z); I_z = bias_model_BPR_integral(cosmo, z); C_1 = alpha_1 * pow(M_R / (1e13 * M_SOL / h_Hubble), beta_1); C_2 = alpha_2 * pow(M_R / (1e13 * M_SOL / h_Hubble), beta_2); bias = (C_1 + C_2 * I_z) * Ez + 1.; } // Poole et al 2014 if(SID_CHECK_BITFIELD_SWITCH(mode, BIAS_MODEL_POOLE_HALO)) { if(flag_done) SID_exit_error("Mode flag (%d) is invalid in bias_model(). Multiple model definitions.", SID_ERROR_LOGIC, mode); flag_done = GBP_TRUE; if(!flag_Vmax_ordinate) V_max = V_max_NFW(M_R, z, NFW_MODE_DEFAULT, cosmo) * 1e-3; else V_max *= 1e-3; double V_SF_o; double V_SF_z; double s_V_o; double s_V_z; double b_o_o; double b_o_z; double b_V_o; double b_V_z; if(SID_CHECK_BITFIELD_SWITCH(mode, BIAS_MODEL_POOLE_SUBSTRUCTURE)) { V_SF_o = 5.326176e-02; V_SF_z = -1.673868e-01; s_V_o = 4.026941e-01; s_V_z = 6.096567e-01; b_o_o = -1.974311e-01; b_o_z = 2.138219e-01; b_V_o = 2.707540e-01; b_V_z = 8.202001e-02; } else { V_SF_o = 2.819063e-02; V_SF_z = -1.381993e-01; s_V_o = 3.685953e-01; s_V_z = 6.154695e-01; b_o_o = -3.793559e-01; b_o_z = 3.074326e-01; b_V_o = 3.147507e-01; b_V_z = 6.072666e-02; } double b_o = b_o_o + b_o_z * z; double b_V = (b_V_o + b_V_z * z) / 220.; double V_SF = take_alog10(V_SF_o + V_SF_z * z) * 220.; double s_V = (s_V_o + s_V_z * z) / 220.; double s = s_V * fabs(V_max - V_SF); bias = take_alog10(0.5 * (b_o + b_V * V_max)); } if(SID_CHECK_BITFIELD_SWITCH(mode, BIAS_MODEL_POOLE_ZSPACE)) { if(flag_done) SID_exit_error("Mode flag (%d) is invalid in bias_model(). Multiple model definitions.", SID_ERROR_LOGIC, mode); flag_done = GBP_TRUE; if(!flag_Vmax_ordinate) V_max = V_max_NFW(M_R, z, NFW_MODE_DEFAULT, cosmo) * 1e-3; else V_max *= 1e-3; double V_SF_o; double V_SF_z; double s_V_o; double s_V_zz; double b_o_o; double b_o_zz; double b_V_o; double b_V_z; double z_b_c; if(SID_CHECK_BITFIELD_SWITCH(mode, BIAS_MODEL_POOLE_SUBSTRUCTURE)) { V_SF_o = 3.173152e-01; V_SF_z = -1.599133e-01; s_V_o = 5.344408e-01; s_V_zz = 7.102406e-02; b_o_o = 2.198795e-01; b_o_zz = -3.749491e-02; b_V_o = -4.628602e-02; b_V_z = -1.832620e-02; z_b_c = 9.292014e-01; } else { V_SF_o = 3.100167e-01; V_SF_z = -2.026411e-01; s_V_o = 3.342258e-01; s_V_zz = 9.233431e-02; b_o_o = 2.206163e-01; b_o_zz = -4.419126e-02; b_V_o = -4.804747e-02; b_V_z = -1.454479e-02; z_b_c = 7.852721e-01; } double b_o = b_o_o + b_o_zz * (z - z_b_c) * (z - z_b_c); double b_V = (b_V_o + b_V_z * z) / 220.; double V_SF = 220. * take_alog10(V_SF_o + V_SF_z * z); double s_V = (s_V_o + s_V_zz * z * z) / 220.; double s = s_V * fabs(V_max - V_SF); bias = take_alog10(0.5 * (b_o + b_V * V_max)); } if(SID_CHECK_BITFIELD_SWITCH(mode, BIAS_MODEL_POOLE_TOTAL)) { if(flag_done) SID_exit_error("Mode flag (%d) is invalid in bias_model(). Multiple model definitions.", SID_ERROR_LOGIC, mode); flag_done = GBP_TRUE; if(!flag_Vmax_ordinate) V_max = V_max_NFW(M_R, z, NFW_MODE_DEFAULT, cosmo) * 1e-3; else V_max *= 1e-3; double V_SF_o; double V_SF_z; double s_V_o; double s_V_z; double b_o_o; double b_o_z; double b_V_o; double b_V_z; if(SID_CHECK_BITFIELD_SWITCH(mode, BIAS_MODEL_POOLE_SUBSTRUCTURE)) { V_SF_o = 2.128681e-01; V_SF_z = -2.280569e-01; s_V_o = 1.118792e+00; s_V_z = 6.121383e-01; b_o_o = 1.198136e-02; b_o_z = 2.112670e-01; b_V_o = 2.153513e-01; b_V_z = 7.763461e-02; } else { V_SF_o = 2.041659e-01; V_SF_z = -2.966696e-01; s_V_o = 9.408169e-01; s_V_z = 4.514711e-01; b_o_o = -1.534952e-01; b_o_z = 2.799483e-01; b_V_o = 2.547096e-01; b_V_z = 6.760491e-02; } double b_o = b_o_o + b_o_z * z; double b_V = (b_V_o + b_V_z * z) / 220.; double V_SF = V_SF_o + V_SF_z * z; double s_V = (s_V_o + s_V_z * z) / 220.; double s = s_V * fabs(V_max - V_SF); bias = take_alog10(0.5 * (b_o + b_V * V_max)); } if(!flag_done) SID_exit_error("Mode flag (%d) is invalid in bias_model(). No model definition.", SID_ERROR_LOGIC, mode); // Apply the Kaiser '87 model to whatever model has been processed above. Be careful, there // are some mode flags (such as BIAS_MODE_POOLE_ZSPACE) for which this does not make sence // and we presently don't check for this. if(SID_CHECK_BITFIELD_SWITCH(mode, BIAS_MODEL_KAISER_BOOST)) { double Omega_M_z = Omega_z(z, (*cosmo)); double f = pow(Omega_M_z, 0.55); double beta = f / bias; double boost = pow(1. + TWO_THIRDS * beta + 0.2 * beta * beta, 0.5); bias = boost; } if(SID_CHECK_BITFIELD_SWITCH(mode, BIAS_MODEL_KAISER)) { double Omega_M_z = Omega_z(z, (*cosmo)); double f = pow(Omega_M_z, 0.55); double beta = f / bias; double boost = pow(1. + TWO_THIRDS * beta + 0.2 * beta * beta, 0.5); bias *= boost; } return (bias); }