double M_sc(double z, cosmo_info **cosmo, int mode, int component){ int i; int n_k; size_t n_k_dim; double *lM_k; double *lk_P; double *sigma2; interp_info *interp; double delta_sc=1.686; double b_z; double r_val; char mode_name[ADaPS_NAME_LENGTH]; char component_name[ADaPS_NAME_LENGTH]; char sigma2_name[ADaPS_NAME_LENGTH]; static double M_sc_last; static double z_last=-42.; if(z!=z_last){ // Set/initialize variance pspec_names(mode,component,mode_name,component_name); sprintf(sigma2_name,"sigma2_k_%s_%s_interp",mode_name,component_name); if(!ADaPS_exist(*cosmo,sigma2_name)) init_power_spectrum_variance(cosmo,z,mode,component); interp =(interp_info *)ADaPS_fetch(*cosmo,sigma2_name); b_z =linear_growth_factor(z,*cosmo); r_val =bisect_array(interp,delta_sc*delta_sc/(b_z*b_z),1e-4); M_sc_last=M_of_k(take_alog10(r_val),z,*cosmo); z_last =z; } return(M_sc_last); }
double dDplus_da(double a, cosmo_info *cosmo){ double h_Hubble; double Ez; h_Hubble=((double *)ADaPS_fetch(cosmo,"h_Hubble"))[0]; Ez =H_z(z_of_a(a),cosmo)/(1e2*h_Hubble); return(1.0/pow(a*Ez,3.0)); }
double M_of_R(double R,double z,cosmo_info *cosmo){ double Omega_M; double M; double rho_bar; Omega_M=((double *)ADaPS_fetch((ADaPS *)(cosmo),"Omega_M"))[0]; rho_bar=Omega_M*rho_crit_z(0.,cosmo); M =FOUR_THIRDS_PI*pow(R,3.)*rho_bar; return(M); }
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; } }
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)); }
double deltat_a(cosmo_info **cosmo,double a_1,double a_2){ double a_lo; double a_hi; interp_info *interp; if(!ADaPS_exist(*cosmo,"deltat_a_interp")) init_deltat_a(cosmo); interp=(interp_info *)ADaPS_fetch(*cosmo,"deltat_a_interp"); a_lo=MAX(MIN(a_1,a_2),DELTAT_A_MIN_A); a_hi=MAX(a_1,a_2); return(interpolate_integral(interp,a_lo,a_hi)); }
int main(int argc, char *argv[]) { SID_Init(&argc, &argv, NULL); // Parse arguments and initialize double z; if(argc < 2 || argc > 3) { fprintf(stderr, "\n Syntax: %s z [gbpCosmo_file.txt]\n", argv[0]); fprintf(stderr, " ------\n\n"); return (SID_ERROR_SYNTAX); } else z = (double)atof(argv[1]); SID_log("Computing cosmology information for z=%.2lf...", SID_LOG_OPEN, z); // Initialize cosmology ADaPS *cosmo = NULL; if(argc == 2) init_cosmo_default(&cosmo); else if(argc == 3) read_gbpCosmo_file(&cosmo, argv[2]); // Output results double h_Hubble = ((double *)ADaPS_fetch(cosmo, "h_Hubble"))[0]; SID_log("R_NL(z) = %10.3lf Mpc", SID_LOG_COMMENT, R_NL_z(z, &cosmo) / M_PER_MPC); SID_log("rho_crit = %13.6le Msol/(Mpc^3)", SID_LOG_COMMENT, rho_crit_z(z, cosmo) * (M_PER_MPC / M_SOL) * M_PER_MPC * M_PER_MPC); SID_log("D_angular = %10.3lf Mpc", SID_LOG_COMMENT, D_angular(z, cosmo) / M_PER_MPC); SID_log("D_luminosity = %10.3lf Mpc", SID_LOG_COMMENT, D_luminosity(z, cosmo) / M_PER_MPC); SID_log("D_comoving = %10.3lf Mpc", SID_LOG_COMMENT, D_comove(z, cosmo) / M_PER_MPC); SID_log("D_horizon = %10.3lf Mpc", SID_LOG_COMMENT, C_VACUUM * deltat_a(&cosmo, 0., a_of_z(z)) / M_PER_MPC); SID_log("D_V = %10.3lf Mpc", SID_LOG_COMMENT, pow((1 + z) * D_angular(z, cosmo) * (1 + z) * D_angular(z, cosmo) * z * C_VACUUM / H_convert(H_z(z, cosmo)), ONE_THIRD) / M_PER_MPC); SID_log("H(z) = %10.3lf km/s/Mpc", SID_LOG_COMMENT, H_z(z, cosmo)); SID_log("t_age(z) = %10.3le years", SID_LOG_COMMENT, t_age_z(z, &cosmo) / S_PER_YEAR); SID_log("t_Hubble(z) = %10.3le years", SID_LOG_COMMENT, t_Hubble_z(z, cosmo) / S_PER_YEAR); SID_log("t_dyn(z) = %10.3le years", SID_LOG_COMMENT, t_dyn_z(z, cosmo) / S_PER_YEAR); SID_log("n_dyn(<z) = %10.3le", SID_LOG_COMMENT, n_dyn_ztoz(0., z, cosmo)); SID_log("Done.", SID_LOG_CLOSE); // Clean-up free_cosmo(&cosmo); SID_Finalize(); }
double R_of_M(double M,cosmo_info *cosmo){ double Omega_M=((double *)ADaPS_fetch((ADaPS *)(cosmo),"Omega_M"))[0]; double rho_bar=Omega_M*rho_crit_z(0,cosmo); double R =pow(M/(FOUR_THIRDS_PI*rho_bar),ONE_THIRD); return(R); }
void analyze_halos_and_N_subhalos(tree_info *trees, const char *filename_out_root, const char *catalog_root, double z_select_exact, double M_cut_lo, double M_cut_hi, int n_subgroups_track_max){ // Compute merger rates ... SID_log("Constructing catalogs...",SID_LOG_OPEN|SID_LOG_TIMER); // Fetch halo 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"); // Determine the best z_select snapshot int i_z_select=find_treesnap_z(trees,z_select_exact); int i_z_0 =trees->n_snaps-1; double z_select =trees->z_list[i_z_select]; double t_select =trees->t_list[i_z_select]; SID_log("The snapshot corresponding best to z=%4.2f is #%03d (z=%4.2f).",SID_LOG_COMMENT,z_select_exact,trees->snap_list[i_z_select],z_select); // Allocate the list arrays tree_node_info **list_groups =(tree_node_info **)SID_malloc(sizeof(tree_node_info *)*trees->n_groups_snap_local[i_z_select]); tree_node_info **list_subgroups_all=(tree_node_info **)SID_malloc(sizeof(tree_node_info *)*trees->n_groups_snap_local[i_z_select]); tree_node_info ***list_subgroups =(tree_node_info ***)SID_malloc(sizeof(tree_node_info **)*n_subgroups_track_max); for(int i_track=0;i_track<n_subgroups_track_max;i_track++) list_subgroups[i_track]=(tree_node_info **)SID_malloc(sizeof(tree_node_info *)*trees->n_groups_snap_local[i_z_select]); // Select z_select systems tree_node_info *current_group; int n_list_groups =0; int n_list_subgroups_all=0; int *n_list_subgroups =(int *)SID_calloc(sizeof(int)*n_subgroups_track_max); SID_log("Selecting z=%4.2f systems...",SID_LOG_OPEN,trees->z_list[i_z_select]); current_group=trees->first_neighbour_groups[i_z_select]; while(current_group!=NULL){ halo_properties_info *current_group_properties=&(group_properties[current_group->snap_tree][current_group->neighbour_index]); if(current_group_properties->M_vir>=M_cut_lo && current_group_properties->M_vir<=M_cut_hi){ list_groups[n_list_groups++]=current_group; tree_node_info *current_subgroup=current_group->substructure_first; int i_subgroup =0; int i_subgroups_track=0; while(current_subgroup!=NULL && i_subgroups_track<n_subgroups_track_max){ if(!check_treenode_if_fragmented(current_subgroup)){ if(i_subgroup>0) list_subgroups_all[n_list_subgroups_all++]=current_subgroup; list_subgroups[i_subgroups_track][n_list_subgroups[i_subgroups_track]++]=current_subgroup; i_subgroups_track++; } i_subgroup++; current_subgroup=current_subgroup->substructure_next; } } current_group=current_group->next_neighbour; } SID_log("%d groups found...",SID_LOG_CONTINUE,n_list_groups); SID_log("Done.",SID_LOG_CLOSE); // Write properties and tracks for selected z_select groups and subgroups char catalog_name[32]; sprintf(catalog_name,"%s_groups",catalog_root); write_tree_branches(trees,list_groups,n_list_groups,TRUE,filename_out_root,catalog_name); average_tree_branches(catalog_name); for(int i_track=0;i_track<n_subgroups_track_max;i_track++){ if(i_track==0){ sprintf(catalog_name,"%s_subgroups_all",catalog_root); write_tree_branches(trees,list_subgroups_all,n_list_subgroups_all,FALSE,filename_out_root,catalog_name); average_tree_branches(catalog_name); } sprintf(catalog_name,"%s_subgroups_%02d",catalog_root,i_track); write_tree_branches(trees,list_subgroups[i_track],n_list_subgroups[i_track],FALSE,filename_out_root,catalog_name); average_tree_branches(catalog_name); } // Clean-up SID_free(SID_FARG n_list_subgroups); for(int i_track=0;i_track<n_subgroups_track_max;i_track++) SID_free(SID_FARG list_subgroups[i_track]); SID_free(SID_FARG list_subgroups); SID_free(SID_FARG list_subgroups_all); SID_free(SID_FARG list_groups); SID_log("Done.",SID_LOG_CLOSE); }
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); }
void write_match_results(char * filename_out_dir, char * filename_out_root, int i_read, int j_read, const char *filename_cat1, const char *filename_cat2, plist_info *plist1, plist_info *plist2, int k_match, float match_weight_rank_index, int mode) { char filename_out[256]; char filename_out_dir_snap[256]; FILE * fp_out; int k_read, l_read; int flag_go; int i_read_start_file; int i_read_stop_file; int i_read_step_file; int n_search_file; int n_search_total; int n_k_match; int flag_match_subgroups; char group_text_prefix[5]; int n_matches; int n_files; int n_groups_1; int n_groups_1_local; int n_groups_2; int n_groups_2_local; int i_group; int buffered_count; int buffered_count_local; int j_group; int index_test; int i_rank; int * n_particles; int * n_sub_group; int * file_index_1; int * match_id = NULL; float * match_score = NULL; int * match_count = NULL; char cat_name_1[20]; char cat_name_2[20]; size_t *match_rank = NULL; size_t *match_index = NULL; size_t offset; int * n_return; void * buffer; int * buffer_int; size_t *buffer_size_t; float * buffer_float; int n_buffer_max = 131072; // 32*32k=1MB for 8-byte values int n_buffer; int i_buffer; int j_buffer; switch(k_match) { case 0: flag_match_subgroups = MATCH_SUBGROUPS; sprintf(group_text_prefix, "sub"); break; case 1: flag_match_subgroups = MATCH_GROUPS; sprintf(group_text_prefix, ""); break; } // Intialize filenames if(SID_CHECK_BITFIELD_SWITCH(mode, WRITE_MATCHES_MODE_TREES)) { sprintf(filename_out_dir_snap, "%s/%s", filename_out_dir, filename_cat1); // Create output directory if need-be if(filename_out_dir != NULL) mkdir(filename_out_dir, 02755); } else if(SID_CHECK_BITFIELD_SWITCH(mode, WRITE_MATCHES_MODE_SINGLE)) sprintf(filename_out_dir_snap, "%s/", filename_out_dir); else SID_exit_error("Invalid write mode flag (%d).", SID_ERROR_LOGIC, mode); if(filename_out_dir != NULL) sprintf(filename_out, "%s/%sgroup_matches_%s_%s.dat", filename_out_dir_snap, group_text_prefix, filename_cat1, filename_cat2); else sprintf(filename_out, "%s_%sgroup_matches_%s_%s.dat", filename_out_root, group_text_prefix, filename_cat1, filename_cat2); SID_log("Writing match results to {%s}...", SID_LOG_OPEN | SID_LOG_TIMER, filename_out); // Fetch halo counts ... n_groups_1 = ((int *)ADaPS_fetch(plist1->data, "n_%sgroups_all_%s", group_text_prefix, filename_cat1))[0]; n_groups_2 = ((int *)ADaPS_fetch(plist2->data, "n_%sgroups_all_%s", group_text_prefix, filename_cat2))[0]; // Write header. if(SID.I_am_Master) { if(filename_out_dir != NULL) mkdir(filename_out_dir_snap, 02755); if((fp_out = fopen(filename_out, "w")) == NULL) SID_exit_error("Could not open {%s} for writing.", SID_ERROR_IO_OPEN, filename_out); fwrite(&i_read, sizeof(int), 1, fp_out); fwrite(&j_read, sizeof(int), 1, fp_out); fwrite(&n_groups_1, sizeof(int), 1, fp_out); fwrite(&n_groups_2, sizeof(int), 1, fp_out); fwrite(&match_weight_rank_index, sizeof(float), 1, fp_out); } // Everything else only needs to be written if there are halos to match with if(n_groups_1 > 0) { // Fetch catalog and matching info ... n_groups_1_local = ((int *)ADaPS_fetch(plist1->data, "n_%sgroups_%s", group_text_prefix, filename_cat1))[0]; file_index_1 = (int *)ADaPS_fetch(plist1->data, "file_index_%sgroups_%s", group_text_prefix, filename_cat1); n_groups_2_local = ((int *)ADaPS_fetch(plist2->data, "n_%sgroups_%s", group_text_prefix, filename_cat2))[0]; match_id = (int *)ADaPS_fetch(plist1->data, "match_match"); match_score = (float *)ADaPS_fetch(plist1->data, "match_score_match"); match_count = (int *)ADaPS_fetch(plist1->data, "match_count_match"); // Generate ranking of matches sort(match_id, (size_t)n_groups_1_local, &match_index, SID_INT, SORT_GLOBAL, SORT_COMPUTE_INDEX, SORT_COMPUTE_NOT_INPLACE); sort(match_index, (size_t)n_groups_1_local, &match_rank, SID_SIZE_T, SORT_GLOBAL, SORT_COMPUTE_INDEX, SORT_COMPUTE_NOT_INPLACE); SID_free(SID_FARG match_index); // Now we write the matching results. We need to write back to the file in the // order that it was read from the halo catalogs, not necessarily the PH order // that it is stored in RAM. This requires some buffer trickery. buffer = SID_malloc(n_buffer_max * sizeof(size_t)); buffer_int = (int *)buffer; buffer_size_t = (size_t *)buffer; buffer_float = (float *)buffer; // Write match_ids ... // ... loop over all the groups in buffer-sized batches SID_log("Writing match IDs...", SID_LOG_OPEN | SID_LOG_TIMER); for(i_group = 0, buffered_count_local = 0; i_group < n_groups_1; i_group += n_buffer) { // Decide this buffer iteration's size n_buffer = GBP_MIN(n_buffer_max, n_groups_1 - i_group); // Set the buffer to a default value smaller than the smallest possible data size for(i_buffer = 0; i_buffer < n_buffer; i_buffer++) buffer_int[i_buffer] = -2; // Min value of match_id is -1 // Determine if any of the local data is being used for this buffer for(j_group = 0; j_group < n_groups_1_local; j_group++) { index_test = file_index_1[j_group] - i_group; // ... if so, set the appropriate buffer value if(index_test >= 0 && index_test < n_buffer) { buffer_int[index_test] = match_id[j_group]; buffered_count_local++; } } // Doing a global max on the buffer yields the needed buffer on all ranks SID_Allreduce(SID_IN_PLACE, buffer_int, n_buffer, SID_INT, SID_MAX, SID_COMM_WORLD); if(SID.I_am_Master) { // Sanity check for(i_buffer = 0; i_buffer < n_buffer; i_buffer++) { if(buffer_int[i_buffer] < -1 || buffer_int[i_buffer] >= n_groups_2) SID_exit_error( "Illegal match_id result (%d) for group No. %d. There are %d groups in the target catalog.", SID_ERROR_LOGIC, buffer_int[i_buffer], i_group + i_buffer, n_groups_2); } // Write the buffer fwrite(buffer_int, sizeof(int), (size_t)n_buffer, fp_out); } } // Sanity check calc_sum_global(&buffered_count_local, &buffered_count, 1, SID_INT, CALC_MODE_DEFAULT, SID_COMM_WORLD); if(buffered_count != n_groups_1) SID_exit_error("Buffer counts don't make sense (ie %d!=%d) after writing match IDs.", SID_ERROR_LOGIC, buffered_count, n_groups_1); SID_log("Done.", SID_LOG_CLOSE); // Write match_score ... // ... loop over all the groups in buffer-sized batches SID_log("Writing match scores...", SID_LOG_OPEN | SID_LOG_TIMER); for(i_group = 0, buffered_count_local = 0; i_group < n_groups_1; i_group += n_buffer) { // Decide this buffer iteration's size n_buffer = GBP_MIN(n_buffer_max, n_groups_1 - i_group); // Set the buffer to a default value smaller than the smallest possible data size for(i_buffer = 0; i_buffer < n_buffer; i_buffer++) buffer_float[i_buffer] = -1.; // Min value of match_score is 0. // Determine if any of the local data is being used for this buffer for(j_group = 0; j_group < n_groups_1_local; j_group++) { index_test = file_index_1[j_group] - i_group; // ... if so, set the appropriate buffer value if(index_test >= 0 && index_test < n_buffer) { buffer_float[index_test] = match_score[j_group]; buffered_count_local++; } } // Doing a global max on the buffer yields the needed buffer on all ranks SID_Allreduce(SID_IN_PLACE, buffer_float, n_buffer, SID_FLOAT, SID_MAX, SID_COMM_WORLD); if(SID.I_am_Master) { // Sanity check for(i_buffer = 0; i_buffer < n_buffer; i_buffer++) { if(buffer_float[i_buffer] < 0.) SID_exit_error("Illegal match_score result (%f) for group No. %d.", SID_ERROR_LOGIC, buffer_float[i_buffer], i_group + i_buffer); } // Write the buffer fwrite(buffer, sizeof(float), (size_t)n_buffer, fp_out); } } // Sanity check calc_sum_global(&buffered_count_local, &buffered_count, 1, SID_INT, CALC_MODE_DEFAULT, SID_COMM_WORLD); if(buffered_count != n_groups_1) SID_exit_error("Buffer counts don't make sense (ie %d!=%d) after writing match scores.", SID_ERROR_LOGIC, buffered_count, n_groups_1); SID_log("Done.", SID_LOG_CLOSE); // Write match_count ... // ... loop over all the groups in buffer-sized batches SID_log("Writing match counts...", SID_LOG_OPEN | SID_LOG_TIMER); for(i_group = 0, buffered_count_local = 0; i_group < n_groups_1; i_group += n_buffer) { // Decide this buffer iteration's size n_buffer = GBP_MIN(n_buffer_max, n_groups_1 - i_group); // Set the buffer to a default value smaller than the smallest possible data size for(i_buffer = 0; i_buffer < n_buffer; i_buffer++) buffer_int[i_buffer] = -1; // Min value of match_count is 0. // Determine if any of the local data is being used for this buffer for(j_group = 0; j_group < n_groups_1_local; j_group++) { index_test = file_index_1[j_group] - i_group; // ... if so, set the appropriate buffer value if(index_test >= 0 && index_test < n_buffer) { buffer_int[index_test] = match_count[j_group]; buffered_count_local++; } } // Doing a global max on the buffer yields the needed buffer on all ranks SID_Allreduce(SID_IN_PLACE, buffer_int, n_buffer, SID_INT, SID_MAX, SID_COMM_WORLD); if(SID.I_am_Master) { // Sanity check for(i_buffer = 0; i_buffer < n_buffer; i_buffer++) { if(buffer_int[i_buffer] < 0.) SID_exit_error("Illegal match_count result (%f) for group No. %d.", SID_ERROR_LOGIC, buffer_int[i_buffer], i_group + i_buffer); } // Write the buffer fwrite(buffer, sizeof(int), (size_t)n_buffer, fp_out); } } // Sanity check calc_sum_global(&buffered_count_local, &buffered_count, 1, SID_INT, CALC_MODE_DEFAULT, SID_COMM_WORLD); if(buffered_count != n_groups_1) SID_exit_error("Buffer counts don't make sense (ie %d!=%d) after writing match scores.", SID_ERROR_LOGIC, buffered_count, n_groups_1); SID_log("Done.", SID_LOG_CLOSE); // Clean-up SID_log("Cleaning-up...", SID_LOG_OPEN); SID_free(SID_FARG buffer); SID_free(SID_FARG match_rank); SID_log("Done.", SID_LOG_CLOSE); } // Close the file if(SID.I_am_Master) fclose(fp_out); SID_log("Done.", SID_LOG_CLOSE); }
int main(int argc, char *argv[]) { plist_info plist; char filename_root[256]; char filename_log[256]; char filename_number[256]; char filename_in_halos[256]; char filename_out_groups[256]; char filename_out_groups_A[256]; char filename_out_groups_B[256]; char filename_out_groups_C[256]; char filename_out_subgroups[256]; char filename_out_subgroups_A[256]; char filename_out_subgroups_B[256]; char filename_out_hierarchy[256]; char filename_out_hierarchy_A[256]; char filename_out_hierarchy_B[256]; char filename_out_particles[256]; char i_match_txt[5]; int n_groups_AHF; int n_groups; int n_subgroups; int n_subgroups_matched; int n_subgroups_group; size_t n_particles; size_t n_particles_in_groups; size_t n_particles_in_subgroups; size_t n_particles_AHF_not_used; int n_particles_temp; int * n_p_1 = NULL; int flag_continue; int flag_long_ids; int i_match; int match_id_next; int * match_id = NULL; int * match_id_initial = NULL; FILE * fp = NULL; FILE * fp_in_halos = NULL; FILE * fp_out = NULL; int n_match; int * id_2 = NULL; size_t * particle_ids_AHF = NULL; size_t * particle_ids_AHF_index = NULL; size_t id_largest; int id_byte_size; size_t * group_particles = NULL; int group_id; int subgroup_id; int i_group; int j_group; int k_group; size_t n_particles_AHF; int * subgroup_size = NULL; int * hierarchy_level = NULL; int * hierarchy_match = NULL; int subgroup_size_max; int * subgroup_size_list = NULL; int * subgroup_index_list = NULL; size_t * subgroup_size_list_index = NULL; int * group_offsets = NULL; size_t group_index; int * group_size = NULL; int * group_size_AHF = NULL; int * group_offsets_AHF = NULL; int max_subgroup_size; int i_subgroup; int j_subgroup; int n_subgroups_group_max; size_t * group_size_index = NULL; size_t * match_id_index = NULL; size_t subgroup_index; int group_offset; int subgroup_offset; int group_count; size_t * group_particles_index = NULL; size_t * subgroup_particles = NULL; int * particle_group = NULL; size_t * particle_group_index = NULL; size_t i_particle; size_t j_particle; size_t k_particle; int i_file; int i_file_start; int i_file_stop; size_t * match_index = NULL; int flag_match_subgroups; FILE * fp_log = NULL; FILE * fp_in = NULL; FILE * fp_out_particles = NULL; FILE * fp_out_groups = NULL; FILE * fp_out_groups_A = NULL; FILE * fp_out_groups_B = NULL; FILE * fp_out_groups_C = NULL; FILE * fp_out_subgroups_A = NULL; FILE * fp_out_subgroups_B = NULL; FILE * fp_out_hierarchy_A = NULL; FILE * fp_out_hierarchy_B = NULL; FILE * fp_test = NULL; int substructure_level; int substructure_level_max; halo_properties_info *properties = NULL; void * particle_buffer = NULL; int flag_found; SID_Init(&argc, &argv, NULL); strcpy(filename_root, argv[1]); i_file_start = atoi(argv[2]); i_file_stop = atoi(argv[3]); SID_log("Converting files #%d->#%d from AHF to subfind format...", SID_LOG_OPEN | SID_LOG_TIMER, i_file_start, i_file_stop); sprintf(filename_log, "%s_%dto%d.convert_AHF_log", filename_root, i_file_start, i_file_stop); // Loop over all files for(i_file = i_file_start; i_file <= i_file_stop; i_file++) { SID_log("Processing file #%d...", SID_LOG_OPEN | SID_LOG_TIMER, i_file); // Read catalogs if(i_file < 10) sprintf(filename_number, "00%1d", i_file); else if(i_file < 100) sprintf(filename_number, "0%2d", i_file); else sprintf(filename_number, "%3d", i_file); // Read AHF group file init_plist(&plist, NULL, GADGET_LENGTH, GADGET_MASS, GADGET_VELOCITY); read_groups_AHF(filename_root, i_file, READ_GROUPS_ALL, &plist, filename_number); n_groups_AHF = ((int *)ADaPS_fetch(plist.data, "n_groups_%s", filename_number))[0]; n_groups = 0; n_subgroups = 0; n_subgroups_matched = 0; n_subgroups_group = 0; n_particles = 0; n_particles_in_groups = 0; n_particles_in_subgroups = 0; n_particles_AHF_not_used = 0; n_subgroups_group_max = 0; if(n_groups_AHF > 0) { n_particles_AHF = (size_t)((size_t *)ADaPS_fetch(plist.data, "n_particles_%s", filename_number))[0]; group_size_AHF = (int *)ADaPS_fetch(plist.data, "n_particles_group_%s", filename_number); group_offsets_AHF = (int *)ADaPS_fetch(plist.data, "particle_offset_group_%s", filename_number); particle_ids_AHF = (size_t *)ADaPS_fetch(plist.data, "particle_ids_%s", filename_number); // Find largest id so we know what size to write the ids with for(i_particle = 0, id_largest = 0; i_particle < n_particles_AHF; i_particle++) id_largest = GBP_MAX(id_largest, particle_ids_AHF[i_particle]); if(id_largest > INT_MAX) { flag_long_ids = GBP_TRUE; id_byte_size = sizeof(size_t); } else { flag_long_ids = GBP_FALSE; id_byte_size = sizeof(int); } // Match AHF groups against themselves to find substructure match_halos(&plist, NULL, i_file, NULL, 0, &plist, NULL, i_file, NULL, 0, "substructure", MATCH_SUBSTRUCTURE, MATCH_SCORE_RANK_INDEX); match_id_initial = (int *)ADaPS_fetch(plist.data, "match_substructure"); hierarchy_match = match_id_initial; // Fore readability // Assign sub-...-sub-structures to parent (ie. top-level) halos SID_log("Assigning substructures to groups...", SID_LOG_OPEN); group_size = (int *)SID_malloc(sizeof(int) * n_groups_AHF); subgroup_size = (int *)SID_malloc(sizeof(int) * n_groups_AHF); hierarchy_level = (int *)SID_malloc(sizeof(int) * n_groups_AHF); particle_group = (int *)SID_malloc(sizeof(int) * n_particles_AHF); for(i_group = 0, i_particle = 0; i_group < n_groups_AHF; i_group++) { group_size[i_group] = 0; subgroup_size[i_group] = 0; for(j_particle = 0; j_particle < group_size_AHF[i_group]; i_particle++, j_particle++) particle_group[i_particle] = i_group; } match_id = (int *)SID_malloc(sizeof(int) * n_groups_AHF); for(i_group = 0, substructure_level_max = 0; i_group < n_groups_AHF; i_group++) { substructure_level = 0; match_id_next = match_id_initial[i_group]; match_id[i_group] = match_id_next; while(match_id_next >= 0) { substructure_level++; match_id[i_group] = match_id_next; // Tie subgroups to their top-level group match_id_next = match_id_initial[match_id_next]; } if(match_id[i_group] < 0) match_id[i_group] = i_group; // Unmatched halos should be matched to themselves hierarchy_level[i_group] = substructure_level; substructure_level_max = GBP_MAX(substructure_level, substructure_level_max); } // needed? ADaPS_store(&(plist.data),(void *)(match_id),"match_substructure",ADaPS_DEFAULT); SID_log("Done.", SID_LOG_CLOSE); // Make sure the deepest substructures are given particle ownership SID_log("Assigning particles to subgroups...", SID_LOG_OPEN); merge_sort( (void *)particle_ids_AHF, (size_t)n_particles_AHF, &particle_ids_AHF_index, SID_SIZE_T, SORT_COMPUTE_INDEX, SORT_COMPUTE_NOT_INPLACE); for(i_particle = 0, n_particles_AHF_not_used = 0; i_particle < n_particles_AHF; i_particle += k_particle) { // Count the number of times this particle id is used j_particle = i_particle; while(particle_ids_AHF[particle_ids_AHF_index[j_particle]] == particle_ids_AHF[particle_ids_AHF_index[i_particle]] && j_particle < (n_particles_AHF - 2)) j_particle++; if(particle_ids_AHF[particle_ids_AHF_index[j_particle]] == particle_ids_AHF[particle_ids_AHF_index[i_particle]]) j_particle++; k_particle = j_particle - i_particle; // Find the deepest substructure using this particle id... i_group = particle_group[particle_ids_AHF_index[i_particle]]; for(j_particle = 1; j_particle < k_particle; j_particle++) { j_group = particle_group[particle_ids_AHF_index[i_particle + j_particle]]; if(group_size_AHF[j_group] < group_size_AHF[i_group]) i_group = j_group; } // ... and set particle's group to a dummy value if this particle instance is not from the deepest group for(j_particle = 0, flag_found = GBP_FALSE; j_particle < k_particle; j_particle++) { if(particle_group[particle_ids_AHF_index[i_particle + j_particle]] != i_group || flag_found) { particle_group[particle_ids_AHF_index[i_particle + j_particle]] = -1; n_particles_AHF_not_used++; } else flag_found = GBP_TRUE; } } SID_free((void **)&particle_ids_AHF_index); SID_log("Done.", SID_LOG_CLOSE); // Generate subgroup_size array for(i_group = 0; i_group < n_groups_AHF; i_group++) subgroup_size[i_group] = 0; for(i_particle = 0; i_particle < n_particles_AHF; i_particle++) { i_group = particle_group[i_particle]; if(i_group >= 0) subgroup_size[i_group]++; } // Get rid of groups that are too small for(i_particle = 0; i_particle < n_particles_AHF; i_particle++) { i_group = particle_group[i_particle]; if(i_group >= 0) { if(subgroup_size[i_group] < 20) { n_particles_AHF_not_used++; particle_group[i_particle] = -1; } } } // Regenerate subgroup_size array for(i_group = 0; i_group < n_groups_AHF; i_group++) subgroup_size[i_group] = 0; for(i_particle = 0; i_particle < n_particles_AHF; i_particle++) { i_group = particle_group[i_particle]; if(i_group >= 0) subgroup_size[i_group]++; } // Find the largest subgroup's size for(i_group = 0, n_subgroups = 0, subgroup_size_max = 0; i_group < n_groups_AHF; i_group++) subgroup_size_max = GBP_MAX(subgroup_size[i_group], subgroup_size_max); // Generate group_size array for(i_group = 0; i_group < n_groups_AHF; i_group++) group_size[match_id[i_group]] += subgroup_size[i_group]; // update group size // Sort groups in order of size merge_sort((void *)group_size, (size_t)n_groups_AHF, &group_size_index, SID_INT, SORT_COMPUTE_INDEX, SORT_COMPUTE_NOT_INPLACE); merge_sort((void *)match_id, (size_t)n_groups_AHF, &match_id_index, SID_INT, SORT_COMPUTE_INDEX, SORT_COMPUTE_NOT_INPLACE); // Count groups, subgroups, etc. SID_log("Counting groups & subgroups...", SID_LOG_OPEN); for(i_group = 0, n_groups = 0, n_subgroups = 0; i_group < n_groups_AHF; i_group++) { group_index = group_size_index[n_groups_AHF - i_group - 1]; // Find start of subgroup list for this group j_group = find_index_int(match_id, group_index, n_groups_AHF, match_id_index); while(group_index > match_id[match_id_index[j_group]] && j_group < (n_groups_AHF - 2)) j_group++; if(group_index > match_id[match_id_index[j_group]]) j_group++; // Count subgroups n_subgroups_group = 0; while(match_id[match_id_index[j_group]] == group_index && j_group < (n_groups_AHF - 2)) { if(subgroup_size[match_id_index[j_group]] > 0) n_subgroups_group++; j_group++; } if(match_id[match_id_index[j_group]] == group_index) { if(subgroup_size[match_id_index[j_group]] > 0) n_subgroups_group++; j_group++; } n_subgroups += n_subgroups_group; // Largest number of subgroups n_subgroups_group_max = GBP_MAX(n_subgroups_group_max, n_subgroups_group); // Count groups if(n_subgroups_group > 0) n_groups++; } SID_log("Done.", SID_LOG_CLOSE); } // Find largest subgroup and count the number of particles in groups for(i_group = 0, max_subgroup_size = 0, n_particles_in_groups = 0; i_group < n_groups_AHF; i_group++) { max_subgroup_size = GBP_MAX(max_subgroup_size, subgroup_size[i_group]); if(subgroup_size[i_group] > 0) n_particles_in_groups += (size_t)subgroup_size[i_group]; } // Write some statistics SID_log("Substructure statistics:", SID_LOG_OPEN); SID_log("Number of groups =%d", SID_LOG_COMMENT, n_groups); SID_log("Number of subgroups =%d", SID_LOG_COMMENT, n_subgroups); SID_log("Max number of subgroups per group=%d", SID_LOG_COMMENT, n_subgroups_group_max); SID_log("Largest subgroup =%d particles", SID_LOG_COMMENT, subgroup_size_max); SID_log("Depth of substructure heirarchy =%d levels", SID_LOG_COMMENT, substructure_level_max); SID_log("Number of AHF particles used =%lld", SID_LOG_COMMENT, n_particles_in_groups); SID_log("Number of AHF particles NOT used =%lld", SID_LOG_COMMENT, n_particles_AHF_not_used); SID_log("", SID_LOG_CLOSE | SID_LOG_NOPRINT); // Open files SID_set_verbosity(SID_SET_VERBOSITY_RELATIVE, 0); SID_log("Writing %d groups, %d subgroups and %lld particles to files...", SID_LOG_OPEN | SID_LOG_TIMER, n_groups, n_subgroups, n_particles_in_groups); sprintf(filename_out_groups, "%s_%s.catalog_groups", filename_root, filename_number); sprintf(filename_out_groups_A, "%s_%s.catalog_groups_A", filename_root, filename_number); sprintf(filename_out_groups_B, "%s_%s.catalog_groups_B", filename_root, filename_number); sprintf(filename_out_groups_C, "%s_%s.catalog_groups_C", filename_root, filename_number); sprintf(filename_out_subgroups, "%s_%s.catalog_subgroups", filename_root, filename_number); sprintf(filename_out_subgroups_A, "%s_%s.catalog_subgroups_A", filename_root, filename_number); sprintf(filename_out_subgroups_B, "%s_%s.catalog_subgroups_B", filename_root, filename_number); sprintf(filename_out_hierarchy, "%s_%s.catalog_hierarchy", filename_root, filename_number); sprintf(filename_out_hierarchy_A, "%s_%s.catalog_hierarchy_A", filename_root, filename_number); sprintf(filename_out_hierarchy_B, "%s_%s.catalog_hierarchy_B", filename_root, filename_number); sprintf(filename_out_particles, "%s_%s.catalog_particles", filename_root, filename_number); fp_out_groups_A = fopen(filename_out_groups_A, "w"); fp_out_groups_B = fopen(filename_out_groups_B, "w"); fp_out_groups_C = fopen(filename_out_groups_C, "w"); fp_out_subgroups_A = fopen(filename_out_subgroups_A, "w"); fp_out_subgroups_B = fopen(filename_out_subgroups_B, "w"); fp_out_hierarchy_A = fopen(filename_out_hierarchy_A, "w"); fp_out_hierarchy_B = fopen(filename_out_hierarchy_B, "w"); fp_out_particles = fopen(filename_out_particles, "w"); // Write headers fwrite(&n_groups, sizeof(int), 1, fp_out_groups_A); fwrite(&n_subgroups, sizeof(int), 1, fp_out_subgroups_A); fwrite(&n_subgroups, sizeof(int), 1, fp_out_hierarchy_A); fwrite(&id_byte_size, sizeof(int), 1, fp_out_particles); switch(flag_long_ids) { case GBP_TRUE: fwrite(&n_particles_in_groups, sizeof(size_t), 1, fp_out_particles); break; default: n_particles_temp = (int)n_particles_in_groups; fwrite(&n_particles_temp, sizeof(int), 1, fp_out_particles); break; } // Write files; group and subgroup files in parts (to be concatinated together later) subgroup_size_list = (int *)SID_malloc(sizeof(int) * n_subgroups_group_max); subgroup_index_list = (int *)SID_malloc(sizeof(int) * n_subgroups_group_max); particle_buffer = (void *)SID_malloc(id_byte_size * subgroup_size_max); subgroup_offset = 0; group_offset = 0; for(i_group = n_groups_AHF - 1; i_group >= n_groups_AHF - n_groups; i_group--) { group_index = group_size_index[i_group]; // Find start of subgroup list for this group i_subgroup = find_index_int(match_id, group_index, n_groups_AHF, match_id_index); while(group_index > match_id[match_id_index[i_subgroup]] && i_subgroup < (n_groups_AHF - 2)) i_subgroup++; if(group_index > match_id[match_id_index[i_subgroup]]) i_subgroup++; // Create a list of subgroups for this group and sort it by size n_subgroups_group = 0; subgroup_index = match_id_index[i_subgroup]; while(match_id[subgroup_index] == group_index && i_subgroup < (n_groups_AHF - 2)) { if(subgroup_size[subgroup_index] > 0) { subgroup_size_list[n_subgroups_group] = subgroup_size[subgroup_index]; subgroup_index_list[n_subgroups_group] = (int)subgroup_index; n_subgroups_group++; } i_subgroup++; subgroup_index = match_id_index[i_subgroup]; } if(match_id[subgroup_index] == group_index) { if(subgroup_size[subgroup_index] > 0) { subgroup_size_list[n_subgroups_group] = subgroup_size[subgroup_index]; subgroup_index_list[n_subgroups_group] = (int)subgroup_index; n_subgroups_group++; } i_subgroup++; subgroup_index = match_id_index[i_subgroup]; } merge_sort((void *)subgroup_size_list, (size_t)n_subgroups_group, &subgroup_size_list_index, SID_INT, SORT_COMPUTE_INDEX, SORT_COMPUTE_NOT_INPLACE); // Perform writes for subgroups and particle lists for(i_subgroup = 0, i_particle = 0; i_subgroup < n_subgroups_group; i_subgroup++) { j_subgroup = subgroup_index_list[subgroup_size_list_index[n_subgroups_group - i_subgroup - 1]]; // ... subgroups ... fwrite(&(subgroup_size[j_subgroup]), sizeof(int), 1, fp_out_subgroups_A); fwrite(&(subgroup_offset), sizeof(int), 1, fp_out_subgroups_B); fwrite(&(hierarchy_match[j_subgroup]), sizeof(int), 1, fp_out_hierarchy_A); fwrite(&(hierarchy_level[j_subgroup]), sizeof(int), 1, fp_out_hierarchy_B); subgroup_offset += subgroup_size[j_subgroup]; // ... and particles for(j_particle = group_offsets_AHF[j_subgroup], k_particle = 0, i_particle = 0; k_particle < group_size_AHF[j_subgroup]; j_particle++, k_particle++) { if(particle_group[j_particle] == j_subgroup) { switch(flag_long_ids) { case GBP_TRUE: ((size_t *)particle_buffer)[i_particle++] = (size_t)(particle_ids_AHF[j_particle]); break; default: ((int *)particle_buffer)[i_particle++] = (int)(particle_ids_AHF[j_particle]); break; } } } if(i_particle == subgroup_size[j_subgroup]) fwrite(particle_buffer, id_byte_size, i_particle, fp_out_particles); else SID_exit_error("Subgroup size mismatch!", SID_ERROR_LOGIC); } SID_free((void **)&subgroup_size_list_index); // Perform writes for groups fwrite(&(group_size[group_index]), sizeof(int), 1, fp_out_groups_A); fwrite(&group_offset, sizeof(int), 1, fp_out_groups_B); fwrite(&n_subgroups_group, sizeof(int), 1, fp_out_groups_C); group_offset += group_size[group_index]; } SID_free((void **)&subgroup_size_list); SID_free((void **)&subgroup_index_list); SID_free((void **)&particle_buffer); fclose(fp_out_groups_A); fclose(fp_out_groups_B); fclose(fp_out_groups_C); fclose(fp_out_subgroups_A); fclose(fp_out_subgroups_B); fclose(fp_out_hierarchy_A); fclose(fp_out_hierarchy_B); fclose(fp_out_particles); // Concatinate group and subgroup temp files into final files SID_cat_files(filename_out_groups, SID_CAT_CLEAN, 3, filename_out_groups_A, filename_out_groups_B, filename_out_groups_C); SID_cat_files(filename_out_subgroups, SID_CAT_CLEAN, 2, filename_out_subgroups_A, filename_out_subgroups_B); SID_cat_files(filename_out_hierarchy, SID_CAT_CLEAN, 2, filename_out_hierarchy_A, filename_out_hierarchy_B); // Clean-up SID_free((void **)&subgroup_size); SID_free((void **)&hierarchy_level); SID_free((void **)&group_size); SID_free((void **)&group_size_index); SID_free((void **)&match_id_index); free_plist(&plist); SID_set_verbosity(SID_SET_VERBOSITY_DEFAULT); SID_log("Done.", SID_LOG_CLOSE); // Write log file SID_log("Writing to log file...", SID_LOG_OPEN); // Write a header for the log file if(i_file == i_file_start) { fp_log = fopen(filename_log, "w"); fprintf(fp_log, "# (1): filenumber\n"); fprintf(fp_log, "# (2): n_groups_AHF\n"); fprintf(fp_log, "# (3): n_particles_AHF\n"); fprintf(fp_log, "# (4): n_groups\n"); fprintf(fp_log, "# (5): n_subgroups\n"); fprintf(fp_log, "# (6): max number of subgroups per group\n"); fprintf(fp_log, "# (7): largest subgroup\n"); fprintf(fp_log, "# (8): depth of substructure heirarchy\n"); fprintf(fp_log, "# (9): number of AHF particles used\n"); fprintf(fp_log, "# (10): number of AHF particles NOT used\n"); } else fp_log = fopen(filename_log, "a"); fprintf(fp_log, "%4d %9d %12zd %9d %9d %9d %9d %9d %12zd %12zd\n", i_file, n_groups_AHF, n_particles_AHF, n_groups, n_subgroups, n_subgroups_group_max, subgroup_size_max, substructure_level_max, n_particles_in_groups, n_particles_AHF_not_used); fclose(fp_log); SID_log("Done.", SID_LOG_CLOSE); SID_log("Done.", SID_LOG_CLOSE); } SID_log("Done.", SID_LOG_CLOSE); SID_Finalize(); }
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); }
void write_cfunc(cfunc_info *cfunc, const char *filename_out_root, plist_info *plist, const char *species_name, const char *randoms_name, int i_run) { // Now that all 4 runs are done, let's write the results SID_log("Writing correlation functions...", SID_LOG_OPEN | SID_LOG_TIMER); if(SID.I_am_Master) { // Set output filenames char filename_out_1D_ascii[SID_MAX_FILENAME_LENGTH]; char filename_out_1D[SID_MAX_FILENAME_LENGTH]; char filename_out_2D[SID_MAX_FILENAME_LENGTH]; sprintf(filename_out_1D_ascii, "%s_1D_cfunc.ascii", filename_out_root); sprintf(filename_out_1D, "%s_1D_cfunc.dat", filename_out_root); sprintf(filename_out_2D, "%s_2D_cfunc.dat", filename_out_root); // Fetch the number of objects that contributed to the calculation size_t n_species; size_t n_randoms; n_species = ((size_t *)ADaPS_fetch(plist->data, "n_all_%s", species_name))[0]; n_randoms = ((size_t *)ADaPS_fetch(plist->data, "n_all_%s", randoms_name))[0]; // Write 1-D Results to an ascii file FILE *fp_out; int i_r; char grouping_name[SID_MAX_FILENAME_LENGTH]; strcpy(grouping_name, filename_out_root); strip_path(grouping_name); fp_out = fopen(filename_out_1D_ascii, "w"); fprintf(fp_out, "# 1D Correlation functions for grouping {%s}\n", grouping_name); fprintf(fp_out, "#\n"); fprintf(fp_out, "# No. of objects: %zd\n", n_species); fprintf(fp_out, "# No. of randoms: %zd\n", n_randoms); fprintf(fp_out, "# Redshift: %5.3lf\n", cfunc->redshift); fprintf(fp_out, "# Box size: %9.3le [Mpc/h]\n", cfunc->box_size); fprintf(fp_out, "# No. of jack-knifes: %d^3\n", cfunc->n_jack); fprintf(fp_out, "#\n"); fprintf(fp_out, "# Start of first log-bin: %9.3le [Mpc/h]\n", cfunc->r_min_l1D); fprintf(fp_out, "# Size of linear 1D bins: %9.3le [Mpc/h]\n", cfunc->dr_1D); fprintf(fp_out, "# Size of linear 2D bins: %9.3le [Mpc/h]\n", cfunc->dr_2D); int i_column = 1; int j_run; fprintf(fp_out, "#\n"); fprintf(fp_out, "# Column: (%02d) r_log [Mpc/h]; Logarithmically spaced bins\n", i_column++); fprintf(fp_out, "# (%02d) r_lin [Mpc/h]; Linearly spaced bins\n", i_column++); for(j_run = 0; j_run <= i_run; j_run++) { char run_name[128]; switch(j_run) { case 0: sprintf(run_name, "real"); break; case 1: sprintf(run_name, "x-projected z"); break; case 2: sprintf(run_name, "y-projected z"); break; case 3: sprintf(run_name, "z-projected z"); break; } fprintf(fp_out, "# (%02d) xi(r_log); %s-space\n", i_column++, run_name); fprintf(fp_out, "# (%02d) dxi(r_log); %s-space\n", i_column++, run_name); fprintf(fp_out, "# (%02d) xi(r_lin); %s-space\n", i_column++, run_name); fprintf(fp_out, "# (%02d) dxi(r_lin); %s-space\n", i_column++, run_name); } fprintf(fp_out, "#\n"); double r_log; double r_lin; r_log = cfunc->lr_min_l1D + 0.5 * cfunc->dr_l1D; r_lin = 0.5 * cfunc->dr_1D; for(i_r = 0; i_r < cfunc->n_1D; i_r++, r_log += cfunc->dr_l1D, r_lin += cfunc->dr_1D) { fprintf(fp_out, "%9.4le %9.3le ", take_alog10(r_log), r_lin); for(j_run = 0; j_run <= i_run; j_run++) fprintf(fp_out, " %le %le %le %le", cfunc->CFUNC_l1D[j_run][i_r], cfunc->dCFUNC_l1D[j_run][i_r], cfunc->CFUNC_1D[j_run][i_r], cfunc->dCFUNC_1D[j_run][i_r]); fprintf(fp_out, "\n"); } fclose(fp_out); // Write 1-D Results to a binary file int i_jack; if(i_run == 0) { fp_out = fopen(filename_out_1D, "w"); fwrite(&(cfunc->n_1D), sizeof(int), 1, fp_out); fwrite(&(cfunc->n_jack), sizeof(int), 1, fp_out); fwrite(&(cfunc->r_min_l1D), sizeof(double), 1, fp_out); fwrite(&(cfunc->r_max_1D), sizeof(double), 1, fp_out); fwrite(&(cfunc->n_data), sizeof(int), 1, fp_out); fwrite(&(cfunc->n_random), sizeof(int), 1, fp_out); } else fp_out = fopen(filename_out_1D, "a"); fwrite(cfunc->CFUNC_1D[i_run], sizeof(double), cfunc->n_1D, fp_out); fwrite(cfunc->dCFUNC_1D[i_run], sizeof(double), cfunc->n_1D, fp_out); fwrite(cfunc->COVMTX_1D[i_run], sizeof(double), cfunc->n_1D * cfunc->n_1D, fp_out); for(i_jack = 0; i_jack <= cfunc->n_jack_total; i_jack++) { fwrite(cfunc->DD_1D[i_jack], sizeof(long long), cfunc->n_1D, fp_out); fwrite(cfunc->DR_1D[i_jack], sizeof(long long), cfunc->n_1D, fp_out); fwrite(cfunc->RR_1D[i_jack], sizeof(long long), cfunc->n_1D, fp_out); } fwrite(cfunc->CFUNC_l1D[i_run], sizeof(double), cfunc->n_1D, fp_out); fwrite(cfunc->dCFUNC_l1D[i_run], sizeof(double), cfunc->n_1D, fp_out); fwrite(cfunc->COVMTX_l1D[i_run], sizeof(double), cfunc->n_1D * cfunc->n_1D, fp_out); for(i_jack = 0; i_jack <= cfunc->n_jack_total; i_jack++) { fwrite(cfunc->DD_l1D[i_jack], sizeof(long long), cfunc->n_1D, fp_out); fwrite(cfunc->DR_l1D[i_jack], sizeof(long long), cfunc->n_1D, fp_out); fwrite(cfunc->RR_l1D[i_jack], sizeof(long long), cfunc->n_1D, fp_out); } fclose(fp_out); // Write 2D correlation functions to a binary file if(i_run == 0) { fp_out = fopen(filename_out_2D, "w"); fwrite(&(cfunc->n_2D), sizeof(int), 1, fp_out); fwrite(&(cfunc->n_jack), sizeof(int), 1, fp_out); fwrite(&(cfunc->r_min_2D), sizeof(double), 1, fp_out); fwrite(&(cfunc->r_max_2D), sizeof(double), 1, fp_out); fwrite(&(cfunc->n_data), sizeof(int), 1, fp_out); fwrite(&(cfunc->n_random), sizeof(int), 1, fp_out); } else fp_out = fopen(filename_out_2D, "a"); fwrite(cfunc->CFUNC_2D[i_run], sizeof(double), cfunc->n_2D_total, fp_out); fwrite(cfunc->dCFUNC_2D[i_run], sizeof(double), cfunc->n_2D_total, fp_out); fwrite(cfunc->COVMTX_2D[i_run], sizeof(double), cfunc->n_2D_total * cfunc->n_2D_total, fp_out); for(i_jack = 0; i_jack <= cfunc->n_jack_total; i_jack++) { fwrite(cfunc->DD_2D[i_jack], sizeof(long long), cfunc->n_2D_total, fp_out); fwrite(cfunc->DR_2D[i_jack], sizeof(long long), cfunc->n_2D_total, fp_out); fwrite(cfunc->RR_2D[i_jack], sizeof(long long), cfunc->n_2D_total, fp_out); } fclose(fp_out); } SID_log("Done.", SID_LOG_CLOSE); }
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[]) { int snapshot; char filename_out[256]; char filename_smooth[256]; char filename_snapshot[256]; char * species_name; double h_Hubble; plist_info plist; size_t i_particle; int i_species; int j_species; int i_rank; size_t n_particles; GBPREAL * x_array; GBPREAL * y_array; GBPREAL * z_array; GBPREAL * r_smooth_array; GBPREAL * rho_array; GBPREAL * sigma_v_array; FILE * fp_out; SID_Init(&argc, &argv, NULL); strcpy(filename_snapshot, argv[1]); snapshot = atoi(argv[2]); strcpy(filename_smooth, argv[3]); strcpy(filename_out, argv[4]); SID_log("Creating ascii file {%s} from smmoth files {%s} and snapshot {%s}...", SID_LOG_OPEN | SID_LOG_TIMER, filename_out, filename_smooth, filename_snapshot); // Read snapshot files init_plist(&plist, NULL, GADGET_LENGTH, GADGET_MASS, GADGET_VELOCITY); read_gadget_binary(filename_snapshot, snapshot, &plist, READ_GADGET_DEFAULT); read_smooth(&plist, filename_smooth, 0, SMOOTH_DEFAULT); h_Hubble = ((double *)ADaPS_fetch(plist.data, "h_Hubble"))[0]; // Loop over each species for(i_species = 0, j_species = 0; i_species < N_GADGET_TYPE; i_species++) { species_name = plist.species[i_species]; if(ADaPS_exist(plist.data, "n_all_%s", species_name)) n_particles = ((size_t *)ADaPS_fetch(plist.data, "n_all_%s", species_name))[0]; else n_particles = 0; // If at least one rank has particles for this species ... if(n_particles > 0) { SID_log("Writting %s particles...", SID_LOG_OPEN, species_name); // ... then fetch arrays ... n_particles = ((size_t *)ADaPS_fetch(plist.data, "n_%s", species_name))[0]; x_array = (GBPREAL *)ADaPS_fetch(plist.data, "x_%s", species_name); y_array = (GBPREAL *)ADaPS_fetch(plist.data, "y_%s", species_name); z_array = (GBPREAL *)ADaPS_fetch(plist.data, "z_%s", species_name); if(ADaPS_exist(plist.data, "r_smooth_%s", species_name)) r_smooth_array = (GBPREAL *)ADaPS_fetch(plist.data, "r_smooth_%s", species_name); else r_smooth_array = NULL; if(ADaPS_exist(plist.data, "rho_%s", species_name)) rho_array = (GBPREAL *)ADaPS_fetch(plist.data, "rho_%s", species_name); else rho_array = NULL; if(ADaPS_exist(plist.data, "sigma_v_%s", species_name)) sigma_v_array = (GBPREAL *)ADaPS_fetch(plist.data, "sigma_v_%s", species_name); else sigma_v_array = NULL; // ... and write this species' particles for(i_rank = 0; i_rank < SID.n_proc; i_rank++) { if(SID.My_rank == i_rank) { if(j_species == 0 && i_rank == 0) fp_out = fopen(filename_out, "w"); else fp_out = fopen(filename_out, "a"); for(i_particle = 0; i_particle < n_particles; i_particle++) { fprintf(fp_out, "%2d %11.4le %11.4le %11.4le", i_species, (double)x_array[i_particle] * h_Hubble / M_PER_MPC, (double)y_array[i_particle] * h_Hubble / M_PER_MPC, (double)z_array[i_particle] * h_Hubble / M_PER_MPC); if(r_smooth_array != NULL) fprintf(fp_out, " %10.4le", (double)r_smooth_array[i_particle] * h_Hubble / M_PER_MPC); if(rho_array != NULL) fprintf(fp_out, " %10.4le", (double)rho_array[i_particle] / (M_SOL * pow(h_Hubble / M_PER_MPC, 3.))); if(sigma_v_array != NULL) fprintf(fp_out, " %10.4le", (double)sigma_v_array[i_particle] * 1e-3); fprintf(fp_out, "\n"); } fclose(fp_out); } SID_Barrier(SID_COMM_WORLD); } j_species++; SID_log("Done.", SID_LOG_CLOSE); } } // Clean-up free_plist(&plist); SID_log("Done.", SID_LOG_CLOSE); SID_Finalize(); }
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); }
int main(int argc, char *argv[]){ int n_species; int n_load; int n_used; int flag_used[N_GADGET_TYPE]; char species_name[256]; double h_Hubble; double n_spec; double redshift; int i_species; char n_string[64]; int n[3]; double L[3]; FILE *fp_1D; FILE *fp_2D; cosmo_info *cosmo; field_info *field[N_GADGET_TYPE]; field_info *field_norm[N_GADGET_TYPE]; plist_info plist_header; plist_info plist; FILE *fp; int i_temp; int n_temp; double *k_temp; double *kmin_temp; double *kmax_temp; double *P_temp; size_t *n_mode_temp; double *sigma_P_temp; double *shot_noise_temp; double *dP_temp; int snapshot_number; int i_compute; int distribution_scheme; double k_min_1D; double k_max_1D; double k_min_2D; double k_max_2D; int n_k_1D; int n_k_2D; double *k_1D; double *P_k_1D; double *dP_k_1D; int *n_modes_1D; double *P_k_2D; double *dP_k_2D; int *n_modes_2D; int n_groups=1; double dk_1D; double dk_2D; char *grid_identifier; // Initialization -- MPI etc. SID_init(&argc,&argv,NULL,NULL); // Parse arguments int grid_size; char filename_in_root[MAX_FILENAME_LENGTH]; char filename_out_root[MAX_FILENAME_LENGTH]; strcpy(filename_in_root, argv[1]); snapshot_number=(int)atoi(argv[2]); strcpy(filename_out_root, argv[3]); grid_size =(int)atoi(argv[4]); if(!strcmp(argv[5],"ngp") || !strcmp(argv[5],"NGP")) distribution_scheme=MAP2GRID_DIST_NGP; else if(!strcmp(argv[5],"cic") || !strcmp(argv[5],"CIC")) distribution_scheme=MAP2GRID_DIST_CIC; else if(!strcmp(argv[5],"tsc") || !strcmp(argv[5],"TSC")) distribution_scheme=MAP2GRID_DIST_TSC; else if(!strcmp(argv[5],"d12") || !strcmp(argv[5],"D12")) distribution_scheme=MAP2GRID_DIST_DWT12; else if(!strcmp(argv[5],"d20") || !strcmp(argv[5],"D20")) distribution_scheme=MAP2GRID_DIST_DWT20; else SID_trap_error("Invalid distribution scheme {%s} specified.",ERROR_SYNTAX,argv[5]); SID_log("Smoothing Gadget file {%s;snapshot=#%d} to a %dx%dx%d grid with %s kernel...",SID_LOG_OPEN|SID_LOG_TIMER, filename_in_root,snapshot_number,grid_size,grid_size,grid_size,argv[5]); // Initialization -- fetch header info SID_log("Reading Gadget header...",SID_LOG_OPEN); gadget_read_info fp_gadget; int flag_filefound=init_gadget_read(filename_in_root,snapshot_number,&fp_gadget); int flag_multifile=fp_gadget.flag_multifile; int flag_file_type=fp_gadget.flag_file_type; gadget_header_info header =fp_gadget.header; double box_size =(double)(header.box_size); size_t *n_all =(size_t *)SID_calloc(sizeof(size_t)*N_GADGET_TYPE); size_t n_total; if(flag_filefound){ if(SID.I_am_Master){ FILE *fp_in; char filename[MAX_FILENAME_LENGTH]; int block_length_open; int block_length_close; set_gadget_filename(&fp_gadget,0,filename); fp_in=fopen(filename,"r"); fread_verify(&block_length_open, sizeof(int),1,fp_in); fread_verify(&header, sizeof(gadget_header_info),1,fp_in); fread_verify(&block_length_close,sizeof(int),1,fp_in); fclose(fp_in); if(block_length_open!=block_length_close) SID_trap_error("Block lengths don't match (ie. %d!=%d).",ERROR_LOGIC,block_length_open,block_length_close); } SID_Bcast(&header,sizeof(gadget_header_info),MASTER_RANK,SID.COMM_WORLD); redshift=header.redshift; h_Hubble=header.h_Hubble; box_size=header.box_size; if(SID.n_proc>1) n_load=1; else n_load=header.n_files; for(i_species=0,n_total=0,n_used=0;i_species<N_GADGET_TYPE;i_species++){ n_all[i_species]=(size_t)header.n_all_lo_word[i_species]+((size_t)header.n_all_hi_word[i_species])<<32; n_total+=n_all[i_species]; if(n_all[i_species]>0){ n_used++; flag_used[i_species]=TRUE; } else flag_used[i_species]=FALSE; } // Initialize cosmology double box_size =((double *)ADaPS_fetch(plist.data,"box_size"))[0]; double h_Hubble =((double *)ADaPS_fetch(plist.data,"h_Hubble"))[0]; double redshift =((double *)ADaPS_fetch(plist.data,"redshift"))[0]; double expansion_factor=((double *)ADaPS_fetch(plist.data,"expansion_factor"))[0]; double Omega_M =((double *)ADaPS_fetch(plist.data,"Omega_M"))[0]; double Omega_Lambda =((double *)ADaPS_fetch(plist.data,"Omega_Lambda"))[0]; double Omega_k =1.-Omega_Lambda-Omega_M; double Omega_b=0.; // not needed, so doesn't matter double f_gas =Omega_b/Omega_M; double sigma_8=0.; // not needed, so doesn't matter double n_spec =0.; // not needed, so doesn't matter char cosmo_name[16]; sprintf(cosmo_name,"Gadget file's"); init_cosmo(&cosmo, cosmo_name, Omega_Lambda, Omega_M, Omega_k, Omega_b, f_gas, h_Hubble, sigma_8, n_spec); } SID_log("Done.",SID_LOG_CLOSE); grid_identifier=(char *)SID_calloc(GRID_IDENTIFIER_SIZE*sizeof(char)); // Only process if there are >0 particles present if(n_used>0){ // Loop over ithe real-space and 3 redshift-space frames int i_write; int i_run; int n_run; int n_grids_total; n_grids_total=4; // For now, hard-wire real-space density and velocity grids only n_run=1; // For now, hard-wire real-space calculation only for(i_run=0,i_write=0;i_run<n_run;i_run++){ // Read catalog int n_grid; char i_run_identifier[8]; switch(i_run){ case 0: SID_log("Processing real-space ...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_run_identifier,"r"); n_grid=4; break; case 1: SID_log("Processing v_x redshift space...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_run_identifier,"x"); n_grid=1; break; case 2: SID_log("Processing v_y redshift space...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_run_identifier,"y"); n_grid=1; break; case 3: SID_log("Processing v_z redsift space...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_run_identifier,"z"); n_grid=1; break; } // For each i_run case, loop over the fields we want to produce int i_grid; for(i_grid=0;i_grid<n_grid;i_grid++){ char i_grid_identifier[8]; switch(i_grid){ case 0: SID_log("Processing density grid ...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_grid_identifier,"rho"); break; case 1: SID_log("Processing v_x velocity grid...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_grid_identifier,"v_x"); break; case 2: SID_log("Processing v_y velocity grid...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_grid_identifier,"v_y"); break; case 3: SID_log("Processing v_z velocity grid...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_grid_identifier,"v_z"); break; } // Initialize the field that will hold the grid int n[]={grid_size,grid_size,grid_size}; double L[]={box_size, box_size, box_size}; int i_init; for(i_species=0;i_species<N_GADGET_TYPE;i_species++){ if(flag_used[i_species]){ field[i_species] =(field_info *)SID_malloc(sizeof(field_info)); field_norm[i_species]=(field_info *)SID_malloc(sizeof(field_info)); init_field(3,n,L,field[i_species]); init_field(3,n,L,field_norm[i_species]); i_init=i_species; } else{ field[i_species] =NULL; field_norm[i_species]=NULL; } } // Loop over all the files that this rank will read int i_load; for(i_load=0;i_load<n_load;i_load++){ if(n_load>1) SID_log("Processing file No. %d of %d...",SID_LOG_OPEN|SID_LOG_TIMER,i_load+1,n_load); // Initialization -- read gadget file GBPREAL mass_array[N_GADGET_TYPE]; init_plist(&plist,&((field[i_init])->slab),GADGET_LENGTH,GADGET_MASS,GADGET_VELOCITY); char filename_root[MAX_FILENAME_LENGTH]; read_gadget_binary_local(filename_in_root, snapshot_number, i_run, i_load, n_load, mass_array, &(field[i_init]->slab), cosmo, &plist); // Generate power spectra for(i_species=0;i_species<plist.n_species;i_species++){ // Determine how many particles of species i_species there are if(n_all[i_species]>0){ // Fetch the needed information size_t n_particles; size_t n_particles_local; int flag_alloc_m; GBPREAL *x_particles_local; GBPREAL *y_particles_local; GBPREAL *z_particles_local; GBPREAL *vx_particles_local; GBPREAL *vy_particles_local; GBPREAL *vz_particles_local; GBPREAL *m_particles_local; GBPREAL *v_particles_local; GBPREAL *w_particles_local; n_particles =((size_t *)ADaPS_fetch(plist.data,"n_all_%s",plist.species[i_species]))[0]; n_particles_local=((size_t *)ADaPS_fetch(plist.data,"n_%s", plist.species[i_species]))[0]; x_particles_local= (GBPREAL *)ADaPS_fetch(plist.data,"x_%s", plist.species[i_species]); y_particles_local= (GBPREAL *)ADaPS_fetch(plist.data,"y_%s", plist.species[i_species]); z_particles_local= (GBPREAL *)ADaPS_fetch(plist.data,"z_%s", plist.species[i_species]); vx_particles_local=(GBPREAL *)ADaPS_fetch(plist.data,"vx_%s", plist.species[i_species]); vy_particles_local=(GBPREAL *)ADaPS_fetch(plist.data,"vy_%s", plist.species[i_species]); vz_particles_local=(GBPREAL *)ADaPS_fetch(plist.data,"vz_%s", plist.species[i_species]); if(ADaPS_exist(plist.data,"M_%s",plist.species[i_species])){ flag_alloc_m=FALSE; m_particles_local=(GBPREAL *)ADaPS_fetch(plist.data,"M_%s",plist.species[i_species]); } else{ flag_alloc_m=TRUE; m_particles_local=(GBPREAL *)SID_malloc(n_particles_local*sizeof(GBPREAL)); int i_particle; for(i_particle=0;i_particle<n_particles_local;i_particle++) m_particles_local[i_particle]=mass_array[i_species]; } // Decide the map_to_grid() mode int mode; if(n_load==1) mode=MAP2GRID_MODE_DEFAULT; else if(i_load==0 || n_load==1) mode=MAP2GRID_MODE_DEFAULT|MAP2GRID_MODE_NONORM; else if(i_load==(n_load-1)) mode=MAP2GRID_MODE_NOCLEAN; else mode=MAP2GRID_MODE_NOCLEAN|MAP2GRID_MODE_NONORM; // Set the array that will weight the grid field_info *field_i; field_info *field_norm_i; double factor; switch(i_grid){ case 0: v_particles_local=m_particles_local; w_particles_local=NULL; field_i =field[i_species]; field_norm_i =NULL; mode|=MAP2GRID_MODE_APPLYFACTOR; factor=pow((double)grid_size/box_size,3.); break; case 1: v_particles_local=vx_particles_local; w_particles_local=m_particles_local; field_i =field[i_species]; field_norm_i =field_norm[i_species]; factor=1.; break; case 2: v_particles_local=vy_particles_local; w_particles_local=m_particles_local; field_i =field[i_species]; field_norm_i =field_norm[i_species]; factor=1.; break; case 3: v_particles_local=vz_particles_local; w_particles_local=m_particles_local; field_i =field[i_species]; field_norm_i =field_norm[i_species]; factor=1.; break; } // Generate grid map_to_grid(n_particles_local, x_particles_local, y_particles_local, z_particles_local, v_particles_local, w_particles_local, cosmo, redshift, distribution_scheme, factor, field_i, field_norm_i, mode); if(flag_alloc_m) SID_free(SID_FARG m_particles_local); } } // Clean-up free_plist(&plist); if(n_load>1) SID_log("Done.",SID_LOG_CLOSE); } // loop over i_load // Write results to disk char filename_out_species[MAX_FILENAME_LENGTH]; init_plist(&plist,NULL,GADGET_LENGTH,GADGET_MASS,GADGET_VELOCITY); for(i_species=0;i_species<plist.n_species;i_species++){ if(flag_used[i_species]){ sprintf(grid_identifier,"%s_%s_%s",i_grid_identifier,i_run_identifier,plist.species[i_species]); sprintf(filename_out_species,"%s_%s",filename_out_root,plist.species[i_species]); write_grid(field[i_species], filename_out_species, i_write, n_grids_total, distribution_scheme, grid_identifier, header.box_size); free_field(field[i_species]); free_field(field_norm[i_species]); SID_free(SID_FARG field[i_species]); SID_free(SID_FARG field_norm[i_species]); i_write++; } } // Clean-up free_plist(&plist); SID_log("Done.",SID_LOG_CLOSE); } // loop over i_grid SID_log("Done.",SID_LOG_CLOSE); } // loop over i_run } // if n_used>0 // Clean-up free_cosmo(&cosmo); SID_free(SID_FARG grid_identifier); SID_free(SID_FARG n_all); SID_log("Done.",SID_LOG_CLOSE); SID_exit(ERROR_NONE); }
void init_gbpCosmo2gbpCosmo(cosmo_info **cosmo_source, cosmo_info **cosmo_target, double z_min, double M_min, double M_max, gbpCosmo2gbpCosmo_info *gbpCosmo2gbpCosmo){ SID_log("Initializing cosmology scaling...",SID_LOG_OPEN|SID_LOG_TIMER); SID_set_verbosity(SID_SET_VERBOSITY_RELATIVE,-1); // Store some infor in the gbpCosmo2gbpCosmo_info structure gbpCosmo2gbpCosmo->M_min =M_min; gbpCosmo2gbpCosmo->M_max =M_max; gbpCosmo2gbpCosmo->z_min =z_min; gbpCosmo2gbpCosmo->cosmo_source=(*cosmo_source); gbpCosmo2gbpCosmo->cosmo_target=(*cosmo_target); // Perform minimization //const gsl_multimin_fminimizer_type *T=gsl_multimin_fminimizer_nmsimplex2; const gsl_multimin_fminimizer_type *T=gsl_multimin_fminimizer_nmsimplex; gsl_multimin_fminimizer *s = NULL; gsl_vector *ss, *x; gsl_multimin_function minex_func; // Starting point x = gsl_vector_alloc (2); gsl_vector_set (x, 0, 1.); // inv_s gsl_vector_set (x, 1, z_min); // z_scaled // Set initial step sizes to 1 ss = gsl_vector_alloc (2); gsl_vector_set_all (ss, 1.0); // Set parameters init_gbpCosmo2gbpCosmo_integrand_params params; params.cosmo_source=cosmo_source; params.cosmo_target=cosmo_target; params.z_source =z_min; params.R_1 =R_of_M(M_min,*cosmo_source); params.R_2 =R_of_M(M_max,*cosmo_source); params.inv_s =gsl_vector_get(x,0); params.z_target =gsl_vector_get(x,1); params.n_int =100; params.wspace =gsl_integration_workspace_alloc(params.n_int); // Initialize method minex_func.n = 2; minex_func.f = init_gbpCosmo2gbpCosmo_minimize_function; minex_func.params = (void *)(¶ms); s = gsl_multimin_fminimizer_alloc (T, 2); gsl_multimin_fminimizer_set(s,&minex_func,x,ss); // Perform minimization double size; int status; size_t iter = 0; size_t iter_max=200; do{ iter++; status=gsl_multimin_fminimizer_iterate(s); if(status) SID_trap_error("Error encountered during minimisation in init_gbpCosmo2gbpCosmo() (status=%d).",ERROR_LOGIC,status); size = gsl_multimin_fminimizer_size(s); status = gsl_multimin_test_size(size,1e-2); } while(status==GSL_CONTINUE && iter<=iter_max); if(status!=GSL_SUCCESS) SID_trap_error("Failed to converge during minimisation in init_gbpCosmo2gbpCosmo() (status=%d,iter=%d).",ERROR_LOGIC,status,iter); // Finalize results double Omega_M_source = ((double *)ADaPS_fetch(*cosmo_source,"Omega_M") )[0]; double H_Hubble_source=1e2*((double *)ADaPS_fetch(*cosmo_source,"h_Hubble"))[0]; double Omega_M_target = ((double *)ADaPS_fetch(*cosmo_target,"Omega_M") )[0]; double H_Hubble_target=1e2*((double *)ADaPS_fetch(*cosmo_target,"h_Hubble"))[0]; gbpCosmo2gbpCosmo->s_L =1./gsl_vector_get(s->x,0); gbpCosmo2gbpCosmo->s_M =(Omega_M_target*H_Hubble_target)/(Omega_M_source*H_Hubble_source)*pow((gbpCosmo2gbpCosmo->s_L),3.); gbpCosmo2gbpCosmo->z_min_scaled=gsl_vector_get(s->x,1);; // Calculate growth factors needed for // determining redshift mappings gbpCosmo2gbpCosmo->D_prime_z_min=linear_growth_factor(z_min, *cosmo_target); gbpCosmo2gbpCosmo->D_z_scaled =linear_growth_factor(gbpCosmo2gbpCosmo->z_min_scaled,*cosmo_source); gbpCosmo2gbpCosmo->D_ratio =gbpCosmo2gbpCosmo->D_prime_z_min/gbpCosmo2gbpCosmo->D_z_scaled; // Clean-up gsl_vector_free(x); gsl_vector_free(ss); gsl_multimin_fminimizer_free(s); gsl_integration_workspace_free(params.wspace); SID_set_verbosity(SID_SET_VERBOSITY_DEFAULT); SID_log("Done.",SID_LOG_CLOSE); }
int main(int argc, char *argv[]){ SID_init(&argc,&argv,NULL,NULL); char filename_cosmology[MAX_FILENAME_LENGTH]; char paramterization[MAX_FILENAME_LENGTH]; double log_M_min =atof(argv[1]); double log_M_max =atof(argv[2]); int n_M_bins =atoi(argv[3]); double redshift =atof(argv[4]); strcpy(filename_cosmology,argv[5]); strcpy(paramterization, argv[6]); SID_log("Constructing mass function between log(M)=%5.3lf->%5.3lf at z=%5.3lf...",SID_LOG_OPEN,log_M_min,log_M_max,redshift); // Initialize cosmology cosmo_info *cosmo=NULL; read_gbpCosmo_file(&cosmo,filename_cosmology); // Decide which parameterization we are going to use int select_flag; char mfn_text[32]; if(!strcmp(paramterization,"JENKINS")){ sprintf(mfn_text,"Jenkins"); select_flag=MF_JENKINS; } else if(!strcmp(paramterization,"PS")){ sprintf(mfn_text,"Press & Schechter"); select_flag=MF_PS; } else if(!strcmp(paramterization,"ST")){ sprintf(mfn_text,"Sheth & Tormen"); select_flag=MF_ST; } else SID_trap_error("Invalid parameterization selected {%s}. Should be {JENKINS,PS or ST}.",ERROR_SYNTAX,paramterization); // Create output filename char filename_out[MAX_FILENAME_LENGTH]; char redshift_text[64]; char *cosmology_name=(char *)ADaPS_fetch(cosmo,"name"); float_to_text(redshift,3,redshift_text); sprintf(filename_out,"mass_function_z%s_%s_%s.txt",redshift_text,cosmology_name,paramterization); // Open file and write header FILE *fp_out=NULL; fp_out=fopen(filename_out,"w"); int i_column=1; fprintf(fp_out,"# Mass function (%s) for %s cosmology at z=%lf\n",mfn_text,filename_cosmology,redshift); fprintf(fp_out,"# \n"); fprintf(fp_out,"# Column (%02d): log M [h^-1 M_sol]\n", i_column++); fprintf(fp_out,"# (%02d): Mass function [(h^{-1} Mpc]^{-3} per dlogM]\n", i_column++); fprintf(fp_out,"# (%02d): Cumulative Mass function(>M) [(h^{-1} Mpc]^{-3}]\n",i_column++); // Create the mass function SID_log("Writing results to {%s}...",SID_LOG_OPEN|SID_LOG_TIMER,filename_out); pcounter_info pcounter; SID_init_pcounter(&pcounter,n_M_bins,10); double h_Hubble =((double *)ADaPS_fetch(cosmo,"h_Hubble"))[0]; double mass_factor=M_SOL/h_Hubble; double MFct_factor=pow(M_PER_MPC,3.0); for(int i_bin=0;i_bin<n_M_bins;i_bin++){ double log_M; if(i_bin==0) log_M=log_M_min; else if(i_bin==(n_M_bins-1)) log_M=log_M_max; else log_M=log_M_min+(((double)(i_bin))/((double)(n_M_bins-1)))*(log_M_max-log_M_min); fprintf(fp_out,"%le %le %le\n",log_M, MFct_factor*mass_function (mass_factor*take_alog10(log_M),redshift,&cosmo,select_flag), MFct_factor*mass_function_cumulative(mass_factor*take_alog10(log_M),redshift,&cosmo,select_flag)); SID_check_pcounter(&pcounter,i_bin); } fclose(fp_out); SID_log("Done.",SID_LOG_CLOSE); // Clean-up free_cosmo(&cosmo); SID_log("Done.",SID_LOG_CLOSE); SID_exit(ERROR_NONE); }
int main(int argc, char *argv[]){ SID_init(&argc,&argv,NULL,NULL); // Fetch user inputs char filename_SSimPL_dir[MAX_FILENAME_LENGTH]; char filename_halo_version_root[MAX_FILENAME_LENGTH]; char filename_trees_root[MAX_FILENAME_LENGTH]; char filename_trees_name[MAX_FILENAME_LENGTH]; char filename_halos_root[MAX_FILENAME_LENGTH]; char filename_out_root[MAX_FILENAME_LENGTH]; strcpy(filename_SSimPL_dir, argv[1]); strcpy(filename_halo_version_root,argv[2]); strcpy(filename_trees_name, argv[3]); double z_lo =(double)atof(argv[4]); double z_hi =(double)atof(argv[5]); double M_cut_min =(double)atof(argv[6]); strcpy(filename_out_root, argv[7]); // Set some filenames sprintf(filename_trees_root,"%s/trees/%s",filename_SSimPL_dir,filename_trees_name); sprintf(filename_halos_root,"%s/halos/%s",filename_SSimPL_dir,filename_halo_version_root); SID_log("Creating a catalog matched across redshifts z_lo~%lf and z_hi~%lf...",SID_LOG_OPEN|SID_LOG_TIMER,z_lo,z_hi); // Perform analysis tree_info *trees; read_trees(filename_SSimPL_dir, filename_halo_version_root, filename_trees_name, TREE_MODE_DEFAULT|TREE_READ_EXTENDED_POINTERS, &trees); // Read ancillary data read_trees_catalogs(trees,READ_TREES_CATALOGS_GROUPS|READ_TREES_CATALOGS_SUBGROUPS); // Determine which snapshots best match the given redshifts int i_z_lo=find_treesnap_z(trees,z_lo); int i_z_hi=find_treesnap_z(trees,z_hi); // Generate two catalogs SID_log("Compiling catalogs...",SID_LOG_OPEN|SID_LOG_TIMER); for(int i_cat=0;i_cat<2;i_cat++){ char filename_out[MAX_FILENAME_LENGTH]; switch(i_cat){ case 0: SID_log("Processing group catalog...",SID_LOG_OPEN); sprintf(filename_out,"%s_groups.txt",filename_out_root); break; case 1: SID_log("Processing subgroup catalog...",SID_LOG_OPEN); sprintf(filename_out,"%s_subgroups.txt",filename_out_root); break; } // Open file and write header FILE *fp_out =fopen(filename_out,"w"); int i_column=1; fprintf(fp_out,"# Catalog matched from z_hi=%lf to z_lo=%lf\n",trees->z_list[i_z_hi],trees->z_list[i_z_lo]); fprintf(fp_out,"# SSiMPL_dir ={%s}\n",filename_SSimPL_dir); fprintf(fp_out,"# halo_version={%s}\n",filename_halo_version_root); fprintf(fp_out,"# tree_version={%s}\n",filename_trees_name); fprintf(fp_out,"#\n"); if(i_cat==0){ fprintf(fp_out,"# Column (%02d): FoF index (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): FoF index (z_lo)\n",i_column++); } else{ fprintf(fp_out,"# Column (%02d): subgroup index (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): subgroup index (z_lo)\n",i_column++); fprintf(fp_out,"# (%02d): FoF index (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): FoF index (z_lo)\n",i_column++); } fprintf(fp_out,"# (%02d): n_particles (z_hi)\n",i_column++); if(i_cat==0){ fprintf(fp_out,"# (%02d): n_subgroups (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): n_subgroups (z_lo)\n",i_column++); fprintf(fp_out,"# (%02d): sig_v_1D [km/s] (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): sig_v_1D [km/s] (z_lo)\n",i_column++); fprintf(fp_out,"# (%02d): sig_v_1Dp [km/s] (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): sig_v_1Dp [km/s] (z_lo)\n",i_column++); } else{ fprintf(fp_out,"# (%02d): M_vir_sub (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): M_vir_sub (z_lo)\n",i_column++); } fprintf(fp_out,"# (%02d): M_vir_FoF (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): M_vir_FoF (z_lo)\n",i_column++); fprintf(fp_out,"# (%02d): x (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): y (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): z (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): x (z_lo)\n",i_column++); fprintf(fp_out,"# (%02d): y (z_lo)\n",i_column++); fprintf(fp_out,"# (%02d): z (z_lo)\n",i_column++); fprintf(fp_out,"# (%02d): v_x (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): v_y (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): v_z (z_hi)\n",i_column++); fprintf(fp_out,"# (%02d): v_x (z_lo)\n",i_column++); fprintf(fp_out,"# (%02d): v_y (z_lo)\n",i_column++); fprintf(fp_out,"# (%02d): v_z (z_lo)\n",i_column++); // Write catalog tree_node_info *current; 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"); if(i_cat==0) current=trees->first_neighbour_groups[i_z_hi]; else current=trees->first_neighbour_subgroups[i_z_hi]; while(current!=NULL){ tree_node_info *current_subgroup; tree_node_info *current_group; halo_properties_info *current_properties; halo_properties_info *current_group_properties; halo_properties_info *current_subgroup_properties; if(i_cat==0){ current_subgroup =NULL; current_group =current; current_group_properties =&(group_properties[current_group->snap_tree][current_group->neighbour_index]); current_subgroup_properties=&(subgroup_properties[current->snap_tree][current->neighbour_index]); current_properties =current_group_properties; } else{ current_subgroup =current; current_group =current->parent_top; current_group_properties =&(group_properties[current_group->snap_tree][current_group->neighbour_index]); current_subgroup_properties=&(subgroup_properties[current->snap_tree][current->neighbour_index]); current_properties =current_subgroup_properties; } if(current_properties->M_vir>=M_cut_min){ tree_node_info *matched; int flag_exact=find_treenode_snap_equals_given(trees,current,i_z_lo,&matched,TREE_PROGENITOR_ORDER_N_PARTICLES_PEAK); if(matched!=NULL && flag_exact){ int n_sub_lo; int n_sub_hi; tree_node_info *matched_group; tree_node_info *matched_subgroup; halo_properties_info *matched_group_properties; halo_properties_info *matched_subgroup_properties; double current_group_sigma_v=0.; double matched_group_sigma_v=0.; if(i_cat==0){ double v_mean; matched_subgroup =NULL; matched_group =matched; matched_subgroup_properties=NULL; matched_group_properties =&(group_properties[matched_group->snap_tree][matched_group->neighbour_index]); tree_node_info *current_j; // Compute 1D velocity dispersion for current group current_j=current_group->substructure_first; v_mean =0.; n_sub_hi =0; while(current_j!=NULL){ double M_i=subgroup_properties[current_j->snap_tree][current_j->neighbour_index].M_vir; if(M_i>M_cut_min){ float v_i=subgroup_properties[current_j->snap_tree][current_j->neighbour_index].velocity_COM[0]; v_mean+=v_i; n_sub_hi++; } current_j=current_j->substructure_next; } current_j=current_group->substructure_first; current_group_sigma_v=0.; if(n_sub_hi>1){ v_mean/=(double)n_sub_hi; while(current_j!=NULL){ double M_i=subgroup_properties[current_j->snap_tree][current_j->neighbour_index].M_vir; if(M_i>M_cut_min){ float v_i=subgroup_properties[current_j->snap_tree][current_j->neighbour_index].velocity_COM[0]; current_group_sigma_v+=pow(v_i-v_mean,2.); } current_j=current_j->substructure_next; } current_group_sigma_v=sqrt(current_group_sigma_v/(double)(n_sub_hi-1)); } // Compute 1D velocity dispersion for matched group current_j=matched_group->substructure_first; v_mean =0.; n_sub_lo =0; while(current_j!=NULL){ double M_i=subgroup_properties[current_j->snap_tree][current_j->neighbour_index].M_vir; if(M_i>M_cut_min){ float v_i=subgroup_properties[current_j->snap_tree][current_j->neighbour_index].velocity_COM[0]; v_mean+=v_i; n_sub_lo++; } current_j=current_j->substructure_next; } current_j=matched_group->substructure_first; matched_group_sigma_v=0.; if(n_sub_lo>1){ v_mean/=(double)n_sub_lo; while(current_j!=NULL){ double M_i=subgroup_properties[current_j->snap_tree][current_j->neighbour_index].M_vir; if(M_i>M_cut_min){ float v_i=subgroup_properties[current_j->snap_tree][current_j->neighbour_index].velocity_COM[0]; matched_group_sigma_v+=pow(v_i-v_mean,2.); } current_j=current_j->substructure_next; } matched_group_sigma_v=sqrt(matched_group_sigma_v/(double)(n_sub_lo-1)); } } else{ matched_subgroup =matched; matched_group =matched_subgroup->parent_top; matched_subgroup_properties=&(subgroup_properties[matched_subgroup->snap_tree][matched_subgroup->neighbour_index]); matched_group_properties =&(group_properties[matched_group->snap_tree][matched_group->neighbour_index]); } if(i_cat==0) fprintf(fp_out,"%7d %7d %6d %5d %5d %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le\n", current_group->neighbour_index, matched_group->neighbour_index, current_group_properties->n_particles, n_sub_hi, n_sub_lo, current_group_sigma_v, matched_group_sigma_v, current_group_properties->sigma_v, matched_group_properties->sigma_v, current_group_properties->M_vir, matched_group_properties->M_vir, current_group_properties->position_MBP[0], current_group_properties->position_MBP[1], current_group_properties->position_MBP[2], matched_group_properties->position_MBP[0], matched_group_properties->position_MBP[1], matched_group_properties->position_MBP[2], current_group_properties->velocity_COM[0], current_group_properties->velocity_COM[1], current_group_properties->velocity_COM[2], matched_group_properties->velocity_COM[0], matched_group_properties->velocity_COM[1], matched_group_properties->velocity_COM[2]); else fprintf(fp_out,"%7d %7d %7d %7d %6d %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le %10.3le\n", current_subgroup->neighbour_index, matched_subgroup->neighbour_index, current_group->neighbour_index, matched_group->neighbour_index, current_subgroup_properties->n_particles, current_subgroup_properties->M_vir, matched_subgroup_properties->M_vir, current_group_properties->M_vir, matched_group_properties->M_vir, current_subgroup_properties->position_MBP[0], current_subgroup_properties->position_MBP[1], current_subgroup_properties->position_MBP[2], matched_subgroup_properties->position_MBP[0], matched_subgroup_properties->position_MBP[1], matched_subgroup_properties->position_MBP[2], current_subgroup_properties->velocity_COM[0], current_subgroup_properties->velocity_COM[1], current_subgroup_properties->velocity_COM[2], matched_subgroup_properties->velocity_COM[0], matched_subgroup_properties->velocity_COM[1], matched_subgroup_properties->velocity_COM[2]); } } current=current->next_neighbour; } fclose(fp_out); SID_log("Done.",SID_LOG_CLOSE); } SID_log("Done.",SID_LOG_CLOSE); // Clean-up free_trees(&trees); SID_log("Done.",SID_LOG_CLOSE); SID_exit(ERROR_NONE); }
void read_mark_file(plist_info *plist, const char *mark_name, const char *filename_in, int mode){ int i_species; size_t i_particle; size_t j_particle; size_t k_particle; int i_rank; size_t i_mark; size_t n_particles_local; size_t *mark_list_buffer; int *mark_list; size_t *ids_local; size_t *mark_list_local; size_t n_mark_total; size_t n_mark_total_check; size_t n_mark_type_local[N_GADGET_TYPE]; size_t n_mark_local; size_t n_particle_local; SID_fp fp_mark_file; size_t i_start_local[N_GADGET_TYPE]; size_t n_mark_bcast; size_t *ids_local_index; size_t n_buffer; int flag_allocate; int flag_read_mode; int flag_mark_mode; int flag_op_mode; markfile_header_info header={N_GADGET_TYPE}; SID_log("Reading mark file...",SID_LOG_OPEN); // Interpret run mode if(check_mode_for_flag(mode,MARK_READ_ALL)) flag_read_mode=MARK_READ_ALL; else flag_read_mode=MARK_DEFAULT; if(check_mode_for_flag(mode,MARK_LIST_ONLY)) flag_mark_mode=MARK_LIST_ONLY; else flag_mark_mode=MARK_DEFAULT; if(check_mode_for_flag(mode,MARK_INIT) || check_mode_for_flag(mode,MARK_OR)) flag_op_mode=MARK_DEFAULT; else flag_op_mode=MARK_AND; // Open mark list and read header SID_fopen_chunked(filename_in, "r", &fp_mark_file, &header); if(header.n_type!=N_GADGET_TYPE) SID_trap_error("Inconsistant number of species in mark file (ie. %d!=%d)!",ERROR_LOGIC,header.n_type,N_GADGET_TYPE); // List numbers of particles in the log output size_t n_particles_all; int n_non_zero; for(i_species=0,n_particles_all=0,n_non_zero=0;i_species<header.n_type;i_species++){ if(header.n_mark_species[i_species]>0){ n_particles_all+=header.n_mark_species[i_species]; n_non_zero++; } } SID_log("%lld",SID_LOG_CONTINUE,n_particles_all); if(n_non_zero>0) SID_log(" (",SID_LOG_CONTINUE,n_particles_all); for(i_species=0;i_species<N_GADGET_TYPE;i_species++){ if(header.n_mark_species[i_species]>0){ if(i_species==n_non_zero-1){ if(n_non_zero>1) SID_log("and %lld %s",SID_LOG_CONTINUE,header.n_mark_species[i_species],plist->species[i_species]); else SID_log("%lld %s",SID_LOG_CONTINUE,header.n_mark_species[i_species],plist->species[i_species]); } else{ if(n_non_zero>1) SID_log("%lld %s, ",SID_LOG_CONTINUE,header.n_mark_species[i_species],plist->species[i_species]); else SID_log("%lld %s",SID_LOG_CONTINUE,header.n_mark_species[i_species],plist->species[i_species]); } } } if(n_non_zero>0) SID_log(") particles...",SID_LOG_CONTINUE); else SID_log(" particles...",SID_LOG_CONTINUE); // Set list sizes and prep offsets for reading for(i_species=0,n_mark_local=0,n_mark_total_check=0;i_species<header.n_type;i_species++){ if(header.n_mark_species[i_species]>0){ ADaPS_store(&(plist->data),(void *)(&(header.n_mark_species[i_species])),"n_%s_%s",ADaPS_SCALAR_SIZE_T,mark_name,plist->species[i_species]); switch(flag_read_mode){ case MARK_READ_ALL: n_mark_type_local[i_species]=header.n_mark_species[i_species]; i_start_local[i_species] =0; break; default: n_mark_type_local[i_species]=header.n_mark_species[i_species]/SID.n_proc; i_start_local[i_species] =(SID.My_rank)*n_mark_type_local[i_species]; if(SID.I_am_last_rank) n_mark_type_local[i_species]=header.n_mark_species[i_species]-i_start_local[i_species]; break; } ADaPS_store(&(plist->data),(void *)(&(n_mark_type_local[i_species])),"n_local_%s_%s",ADaPS_SCALAR_SIZE_T,mark_name,plist->species[i_species]); n_mark_local +=n_mark_type_local[i_species]; n_mark_total_check+=header.n_mark_species[i_species]; } } // Sanity check SID_Allreduce(&n_mark_local,&n_mark_total,1,SID_SIZE_T,SID_SUM,SID.COMM_WORLD); if(n_mark_total!=n_mark_total_check) SID_trap_error("Particle numbers don't add-up right in read_mark_file!",ERROR_LOGIC); // Read file and create/store mark arrays switch(flag_mark_mode){ case MARK_LIST_ONLY: for(i_species=0;i_species<header.n_type;i_species++){ if(header.n_mark_species[i_species]>0){ // Allocate array if(n_mark_type_local[i_species]>0) mark_list_local=(size_t *)SID_malloc(sizeof(size_t)*n_mark_type_local[i_species]); else mark_list_local=NULL; // Perform read SID_fread_chunked(mark_list_local, n_mark_type_local[i_species], i_start_local[i_species], &fp_mark_file); // Sort marked particles if(n_mark_type_local[i_species]>0){ merge_sort(mark_list_local,n_mark_type_local[i_species],NULL,SID_SIZE_T,SORT_INPLACE_ONLY,SORT_COMPUTE_INPLACE); ADaPS_store(&(plist->data),(void *)(mark_list_local),"%s_%s",ADaPS_DEFAULT,mark_name,plist->species[i_species]); } } } break; default: mark_list_buffer=(size_t *)SID_malloc(sizeof(size_t)*MAX_MARK_BUFFER_SIZE); for(i_species=0;i_species<header.n_type;i_species++){ if(header.n_mark_species[i_species]>0){ n_particles_local=((size_t *)ADaPS_fetch(plist->data,"n_%s",plist->species[i_species]))[0]; // Initialize arrays ids_local=(size_t *)ADaPS_fetch(plist->data,"id_%s",plist->species[i_species]); if(ADaPS_exist(plist->data,"%s_%s",mark_name,plist->species[i_species])){ mark_list=(int *)ADaPS_fetch(plist->data,"%s_%s",mark_name,plist->species[i_species]); flag_allocate=FALSE; } else{ mark_list=(int *)SID_malloc(sizeof(int)*n_particles_local); for(i_particle=0;i_particle<n_particles_local;i_particle++) mark_list[i_particle]=FALSE; flag_allocate=TRUE; } merge_sort(ids_local,n_particles_local,&ids_local_index,SID_SIZE_T,SORT_COMPUTE_INDEX,SORT_COMPUTE_NOT_INPLACE); // Use a buffer to increase speed for(i_particle=0;i_particle<header.n_mark_species[i_species];){ n_buffer=MIN(header.n_mark_species[i_species]-i_particle,MAX_MARK_BUFFER_SIZE); SID_fread_chunked_all(mark_list_local, n_buffer, &fp_mark_file); merge_sort(mark_list_local,n_buffer,NULL,SID_SIZE_T,SORT_INPLACE_ONLY,SORT_COMPUTE_INPLACE); for(j_particle=0,k_particle=find_index(ids_local,mark_list_buffer[0],n_particles_local,ids_local_index); j_particle<n_buffer; j_particle++,i_particle++){ while(ids_local[ids_local_index[k_particle]]<mark_list_local[j_particle] && k_particle<n_buffer-1) k_particle++; if(ids_local[ids_local_index[k_particle]]==mark_list_local[j_particle]){ switch(flag_op_mode){ case MARK_INIT: case MARK_AND: case MARK_OR: mark_list[i_particle]=TRUE; break; } } } } SID_free((void **)&ids_local_index); ADaPS_store(&(plist->data),(void *)mark_list,"%s_%s",ADaPS_DEFAULT,mark_name,plist->species[i_species]); } } SID_free((void **)&mark_list_buffer); break; } SID_fclose_chunked(&fp_mark_file); SID_log("Done.",SID_LOG_CLOSE); }
int main(int argc, char *argv[]) { SID_Init(&argc, &argv, NULL); // Parse command line select_gadget_ids_params_info params; int snapshot; int halo_index; int halo_type; int n_files_out; int select_mode; char filename_SSimPL_root[SID_MAX_FILENAME_LENGTH]; char filename_halo_version[SID_MAX_FILENAME_LENGTH]; char filename_in_root[SID_MAX_FILENAME_LENGTH]; char filename_out_root[SID_MAX_FILENAME_LENGTH]; GBPREAL cen_select[3]; GBPREAL select_size; strcpy(filename_SSimPL_root, argv[1]); strcpy(filename_halo_version, argv[2]); snapshot = atoi(argv[3]); halo_index = atoi(argv[4]); halo_type = atoi(argv[5]); strcpy(filename_out_root, argv[6]); n_files_out = atoi(argv[7]); SID_log("Writing halo particles to ascii file {%s;snapshot=%d;halo_index=%d}...", SID_LOG_OPEN | SID_LOG_TIMER, filename_SSimPL_root, snapshot, halo_index); // Initialize the plist data structure plist_info plist; params.plist = &plist; init_plist(&plist, NULL, GADGET_LENGTH, GADGET_MASS, GADGET_VELOCITY); // Read the halo ID list. Generate sort indicies and copy the // list to a duplicate array. Make sure this is the one added // to params. Pass this to write_gadget_ascii below, so that // the particles get written in the same order that they are // in the halo catalog. char filename_halos[SID_MAX_FILENAME_LENGTH]; if(halo_type == 0) sprintf(filename_halos, "%s/halos/%s_%03d.catalog_groups", filename_SSimPL_root, filename_halo_version, snapshot); else sprintf(filename_halos, "%s/halos/%s_%03d.catalog_subgroups", filename_SSimPL_root, filename_halo_version, snapshot); FILE * fp_groups = fopen(filename_halos, "r"); int n_groups; int offset_size; int halo_length; size_t halo_offset; SID_fread_verify(&n_groups, sizeof(int), 1, fp_groups); SID_fread_verify(&offset_size, sizeof(int), 1, fp_groups); fseeko(fp_groups, (off_t)(2 * sizeof(int) + halo_index * sizeof(int)), SEEK_SET); SID_fread_verify(&halo_length, sizeof(int), 1, fp_groups); fseeko(fp_groups, (off_t)(2 * sizeof(int) + n_groups * sizeof(int) + halo_index * offset_size), SEEK_SET); if(offset_size == sizeof(int)) { int halo_offset_i; SID_fread_verify(&halo_offset_i, offset_size, 1, fp_groups); halo_offset = (size_t)halo_offset_i; } else SID_fread_verify(&halo_offset, offset_size, 1, fp_groups); fclose(fp_groups); char filename_ids[SID_MAX_FILENAME_LENGTH]; sprintf(filename_ids, "%s/halos/%s_%03d.catalog_particles", filename_SSimPL_root, filename_halo_version, snapshot); FILE * fp_ids = fopen(filename_ids, "r"); int id_byte_size; size_t n_ids; SID_fread_verify(&id_byte_size, sizeof(int), 1, fp_ids); SID_log("%d %d-byte IDs to be read (offset=%d)", SID_LOG_COMMENT, halo_length, id_byte_size, halo_offset); if(id_byte_size == sizeof(int)) { int n_ids_i; SID_fread_verify(&n_ids_i, sizeof(int), 1, fp_ids); n_ids = (size_t)n_ids_i; } else SID_fread_verify(&n_ids, sizeof(size_t), 1, fp_ids); fseeko(fp_ids, (off_t)(sizeof(int) + id_byte_size + halo_offset * id_byte_size), SEEK_SET); params.n_ids = halo_length; params.id_list = (size_t *)SID_malloc(sizeof(size_t) * halo_length); size_t *id_list_unsorted = (size_t *)SID_malloc(sizeof(size_t) * halo_length); int flag_long_ids = GBP_TRUE; if(id_byte_size == sizeof(int)) { flag_long_ids = GBP_FALSE; int *id_list_i = (int *)SID_malloc(sizeof(int) * halo_length); SID_fread_verify(id_list_i, id_byte_size, halo_length, fp_ids); for(int i_p = 0; i_p < halo_length; i_p++) id_list_unsorted[i_p] = (size_t)id_list_i[i_p]; SID_free(SID_FARG id_list_i); } else SID_fread_verify(id_list_unsorted, id_byte_size, halo_length, fp_ids); fclose(fp_ids); memcpy(params.id_list, id_list_unsorted, sizeof(size_t) * halo_length); merge_sort(params.id_list, halo_length, NULL, SID_SIZE_T, SORT_INPLACE_ONLY, SORT_COMPUTE_INPLACE); // Count the particles size_t n_particles_type_local[N_GADGET_TYPE]; size_t n_particles_type[N_GADGET_TYPE]; int flag_long_IDs; sprintf(filename_in_root, "%s/snapshots/snapshot", filename_SSimPL_root); process_gadget_file("Counting particles in selection...", filename_in_root, snapshot, select_gadget_all, process_gadget_file_fctn_null, ¶ms, n_particles_type_local, n_particles_type, &flag_long_IDs, PROCESS_GADGET_BINARY_DEFAULT); // Allocate RAM for the particles allocate_gadget_particles(&plist, n_particles_type_local, n_particles_type, flag_long_IDs); // Read the particles process_gadget_file("Performing read...", filename_in_root, snapshot, select_gadget_all, store_gadget_particles, ¶ms, NULL, NULL, &flag_long_IDs, PROCESS_GADGET_BINARY_DEFAULT); // Write the snapshot if(SID.I_am_Master) { char filename_out[SID_MAX_FILENAME_LENGTH]; sprintf(filename_out, "%s_%03d_%08d.ascii", filename_out_root, snapshot, halo_index); FILE *fp = fopen(filename_out, "w"); fprintf(fp, "#Columns:\n"); fprintf(fp, "# 1) Gadget particle type\n"); fprintf(fp, "# 2) x [Mpc/h]\n"); fprintf(fp, "# 3) y [Mpc/h]\n"); fprintf(fp, "# 4) z [Mpc/h]\n"); fprintf(fp, "# 5) v_x [km/s]\n"); fprintf(fp, "# 6) v_y [km/s]\n"); fprintf(fp, "# 7) v_z [km/s]\n"); fprintf(fp, "# 8) id\n"); int i_species = GADGET_TYPE_DARK; size_t n_p = ((size_t *)ADaPS_fetch(plist.data, "n_%s", plist.species[i_species]))[0]; GBPREAL *x = (GBPREAL *)ADaPS_fetch(plist.data, "x_%s", plist.species[i_species]); GBPREAL *y = (GBPREAL *)ADaPS_fetch(plist.data, "y_%s", plist.species[i_species]); GBPREAL *z = (GBPREAL *)ADaPS_fetch(plist.data, "z_%s", plist.species[i_species]); GBPREAL *vx = (GBPREAL *)ADaPS_fetch(plist.data, "vx_%s", plist.species[i_species]); GBPREAL *vy = (GBPREAL *)ADaPS_fetch(plist.data, "vy_%s", plist.species[i_species]); GBPREAL *vz = (GBPREAL *)ADaPS_fetch(plist.data, "vz_%s", plist.species[i_species]); size_t * id = (size_t *)ADaPS_fetch(plist.data, "id_%s", plist.species[i_species]); size_t * id_indices = NULL; SID_log("Sorting IDs...", SID_LOG_OPEN); merge_sort(id, n_p, &id_indices, SID_SIZE_T, SORT_COMPUTE_INDEX, SORT_COMPUTE_NOT_INPLACE); SID_log("Done.", SID_LOG_CLOSE); SID_log("Writing particles...", SID_LOG_OPEN); pcounter_info pcounter; SID_Init_pcounter(&pcounter, halo_length, 10); int n_unfound = 0; for(int i_p = 0; i_p < halo_length; i_p++) { size_t k_p = id_indices[find_index(id, id_list_unsorted[i_p], n_p, id_indices)]; if(id[k_p] != id_list_unsorted[i_p]) n_unfound++; else fprintf(fp, "%1d %11.4e %11.4e %11.4e %11.4e %11.4e %11.4e %7zd\n", i_species, (double)(x[k_p]), (double)(y[k_p]), (double)(z[k_p]), (double)(vx[k_p]), (double)(vy[k_p]), (double)(vz[k_p]), id[k_p]); SID_check_pcounter(&pcounter, i_p); } fclose(fp); if(n_unfound != 0) SID_log("(%d unfound)...", SID_LOG_CONTINUE, n_unfound); SID_log("Done.", SID_LOG_CLOSE); SID_free(SID_FARG id_indices); } // Clean-up SID_free(SID_FARG id_list_unsorted); SID_free(SID_FARG params.id_list); free_plist(&plist); SID_log("Done.", SID_LOG_CLOSE); SID_Finalize(); }
void map_to_grid(size_t n_particles_local, GBPREAL * x_particles_local, GBPREAL * y_particles_local, GBPREAL * z_particles_local, GBPREAL * v_particles_local, GBPREAL * w_particles_local, cosmo_info *cosmo, double redshift, int distribution_scheme, double normalization_constant, field_info *field, field_info *field_norm, int mode) { size_t i_p; int i_k; size_t i_b; size_t i_grid; int i_coord; int i_i[3]; int j_i[3]; int k_i[3]; size_t n_particles; double v_p; double w_p; int flag_valued_particles; int flag_weight_particles; int flag_weight; int flag_active; int flag_viable; double k_mag; double dk; int n_powspec; int mode_powspec; size_t * n_mode_powspec; double * k_powspec; double * kmin_powspec; double * kmax_powspec; double * k_powspec_bin; double * P_powspec; double * dP_powspec; double k_min; double k_max; double norm_local; double normalization; GBPREAL x_i; GBPREAL x_particle_i; GBPREAL y_particle_i; GBPREAL z_particle_i; double kernal_offset; int W_search_lo; int W_search_hi; size_t receive_left_size = 0; size_t receive_right_size = 0; size_t index_best; int n_buffer[3]; size_t n_send_left; size_t n_send_right; size_t send_size_left; size_t send_size_right; GBPREAL * send_left = NULL; GBPREAL * send_right = NULL; GBPREAL * receive_left = NULL; GBPREAL * receive_right = NULL; GBPREAL * send_left_norm = NULL; GBPREAL * send_right_norm = NULL; GBPREAL * receive_left_norm = NULL; GBPREAL * receive_right_norm = NULL; double r_i, r_min, r_i_max = 0; double W_i; int index_i; interp_info *P_k_interp; double * r_Daub; double * W_Daub; double h_Hubble; int n_Daub; interp_info *W_r_Daub_interp = NULL; int i_rank; size_t buffer_index; int i_test; double accumulator; // Compute the total poulation size and print a status message calc_sum_global(&n_particles_local, &n_particles, 1, SID_SIZE_T, CALC_MODE_DEFAULT, SID_COMM_WORLD); SID_log("Distributing %zu items onto a %dx%dx%d grid...", SID_LOG_OPEN, n_particles, field->n[0], field->n[1], field->n[2]); // If we've been given a normalization field, make sure it's got the same geometry as the results field if(field_norm != NULL) { if(field->n_d != field_norm->n_d) SID_exit_error("grid dimension counts don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->n_d, field_norm->n_d); int i_d; for(i_d = 0; i_d < field->n_d; i_d++) { if(field->n[i_d] != field_norm->n[i_d]) SID_exit_error("grid dimension No. %d's sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, i_d, field->n[i_d], field_norm->n[i_d]); if(field->n_R_local[i_d] != field_norm->n_R_local[i_d]) SID_exit_error("grid dimension No. %d's slab sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, i_d, field->n_R_local[i_d], field_norm->n_R_local[i_d]); if(field->i_R_start_local[i_d] != field_norm->i_R_start_local[i_d]) SID_exit_error("grid dimension No. %d's start positions don't match (ie. %le!=%le)", SID_ERROR_LOGIC, i_d, field->i_R_start_local[i_d], field_norm->i_R_start_local[i_d]); if(field->i_R_stop_local[i_d] != field_norm->i_R_stop_local[i_d]) SID_exit_error("grid dimension No. %d's stop positions don't match (ie. %le!=%le)", SID_ERROR_LOGIC, i_d, field->i_R_stop_local[i_d], field_norm->i_R_stop_local[i_d]); } if(field->n_field != field_norm->n_field) SID_exit_error("grid field sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->n_field, field_norm->n_field); if(field->n_field_R_local != field_norm->n_field_R_local) SID_exit_error("grid local field sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->n_field_R_local, field_norm->n_field_R_local); if(field->total_local_size != field_norm->total_local_size) SID_exit_error("grid total local sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->total_local_size, field_norm->total_local_size); } // Set some variables if(v_particles_local != NULL) flag_valued_particles = GBP_TRUE; else { flag_valued_particles = GBP_FALSE; v_p = 1.; } if(w_particles_local != NULL) flag_weight_particles = GBP_TRUE; else { flag_weight_particles = GBP_FALSE; w_p = 1.; } h_Hubble = ((double *)ADaPS_fetch(cosmo, "h_Hubble"))[0]; // Initializing the mass assignment scheme switch(distribution_scheme) { case MAP2GRID_DIST_DWT20: W_search_lo = 2; W_search_hi = 7; kernal_offset = 2.5; compute_Daubechies_scaling_fctns(20, 5, &r_Daub, &W_Daub, &n_Daub); init_interpolate(r_Daub, W_Daub, n_Daub, gsl_interp_cspline, &W_r_Daub_interp); SID_free(SID_FARG r_Daub); SID_free(SID_FARG W_Daub); SID_log("(using D20 scale function kernal)...", SID_LOG_CONTINUE); break; case MAP2GRID_DIST_DWT12: W_search_lo = 1; W_search_hi = 6; kernal_offset = 1.75; compute_Daubechies_scaling_fctns(12, 5, &r_Daub, &W_Daub, &n_Daub); init_interpolate(r_Daub, W_Daub, (size_t)n_Daub, gsl_interp_cspline, &W_r_Daub_interp); SID_free(SID_FARG r_Daub); SID_free(SID_FARG W_Daub); SID_log("(using D12 scale function kernal)...", SID_LOG_CONTINUE); break; case MAP2GRID_DIST_TSC: W_search_lo = 2; W_search_hi = 2; SID_log("(using triangular shaped function kernal)...", SID_LOG_CONTINUE); break; case MAP2GRID_DIST_CIC: SID_log("(using cloud-in-cell kernal)...", SID_LOG_CONTINUE); case MAP2GRID_DIST_NGP: default: W_search_lo = 1; W_search_hi = 1; SID_log("(using nearest grid point kernal)...", SID_LOG_CONTINUE); break; } // Initializing slab buffers n_send_left = (size_t)(field->n[0] * field->n[1] * W_search_lo); n_send_right = (size_t)(field->n[0] * field->n[1] * W_search_hi); send_size_left = n_send_left * sizeof(GBPREAL); send_size_right = n_send_right * sizeof(GBPREAL); send_left = (GBPREAL *)SID_calloc(send_size_left); send_right = (GBPREAL *)SID_calloc(send_size_right); receive_left = (GBPREAL *)SID_calloc(send_size_right); receive_right = (GBPREAL *)SID_calloc(send_size_left); if(field_norm != NULL) { send_left_norm = (GBPREAL *)SID_calloc(send_size_left); send_right_norm = (GBPREAL *)SID_calloc(send_size_right); receive_left_norm = (GBPREAL *)SID_calloc(send_size_right); receive_right_norm = (GBPREAL *)SID_calloc(send_size_left); } // Clear the field if(!SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_NOCLEAN)) { SID_log("Clearing fields...", SID_LOG_OPEN); clear_field(field); if(field_norm != NULL) clear_field(field); SID_log("Done.", SID_LOG_CLOSE); } // It is essential that we not pad the field for the simple way that we add-in the boundary buffers below set_FFT_padding_state(field, GBP_FALSE); if(field_norm != NULL) set_FFT_padding_state(field_norm, GBP_FALSE); // Create the mass distribution SID_log("Performing grid assignment...", SID_LOG_OPEN | SID_LOG_TIMER); // Loop over all the objects pcounter_info pcounter; SID_Init_pcounter(&pcounter, n_particles_local, 10); for(i_p = 0, norm_local = 0.; i_p < n_particles_local; i_p++) { double norm_i; double value_i; if(flag_valued_particles) v_p = (double)(v_particles_local[i_p]); if(flag_weight_particles) w_p = (double)(w_particles_local[i_p]); norm_i = w_p; value_i = v_p * norm_i; // Particle's position x_particle_i = (GBPREAL)x_particles_local[i_p]; y_particle_i = (GBPREAL)y_particles_local[i_p]; z_particle_i = (GBPREAL)z_particles_local[i_p]; // Quantize it onto the grid x_particle_i /= (GBPREAL)field->dR[0]; y_particle_i /= (GBPREAL)field->dR[1]; z_particle_i /= (GBPREAL)field->dR[2]; i_i[0] = (int)x_particle_i; // position in grid-coordinates i_i[1] = (int)y_particle_i; // position in grid-coordinates i_i[2] = (int)z_particle_i; // position in grid-coordinates // Apply the kernel flag_viable = GBP_TRUE; double x_i_effective; for(j_i[0] = -W_search_lo; j_i[0] <= W_search_hi; j_i[0]++) { for(j_i[1] = -W_search_lo; j_i[1] <= W_search_hi; j_i[1]++) { for(j_i[2] = -W_search_lo; j_i[2] <= W_search_hi; j_i[2]++) { // Compute distance to each grid point being searched against ... flag_active = GBP_TRUE; for(i_coord = 0, W_i = 1.; i_coord < 3; i_coord++) { switch(i_coord) { case 0: x_i = (GBPREAL)(i_i[0] + j_i[0]) - x_particle_i; break; case 1: x_i = (GBPREAL)(i_i[1] + j_i[1]) - y_particle_i; break; case 2: x_i = (GBPREAL)(i_i[2] + j_i[2]) - z_particle_i; break; } switch(distribution_scheme) { // Distribute with a Daubechies wavelet transform of 12th or 20th order a la Cui et al '08 case MAP2GRID_DIST_DWT12: case MAP2GRID_DIST_DWT20: x_i_effective = x_i + kernal_offset; if(x_i_effective > 0.) W_i *= interpolate(W_r_Daub_interp, x_i_effective); else flag_active = GBP_FALSE; break; // Distribute using the triangular shaped cloud (TSC) method case MAP2GRID_DIST_TSC: if(x_i < 0.5) W_i *= (0.75 - x_i * x_i); else if(x_i < 1.5) W_i *= 0.5 * (1.5 - fabs(x_i)) * (1.5 - fabs(x_i)); else flag_active = GBP_FALSE; break; // Distribute using the cloud-in-cell (CIC) method case MAP2GRID_DIST_CIC: if(fabs(x_i) < 1.) W_i *= (1. - fabs(x_i)); else flag_active = GBP_FALSE; break; // Distribute using "nearest grid point" (NGP; ie. the simplest and default) method case MAP2GRID_DIST_NGP: default: if(fabs(x_i) <= 0.5 && flag_viable) W_i *= 1.; else flag_active = GBP_FALSE; break; } } if(flag_active) { // This flags-out regions of the kernal with no support to save some time // Set the grid indices (enforce periodic BCs; do x-coordinate last) ... // ... y-coordinate ... k_i[1] = (i_i[1] + j_i[1]); if(k_i[1] < 0) k_i[1] += field->n[1]; else k_i[1] = k_i[1] % field->n[1]; // ... z-coordinate ... k_i[2] = i_i[2] + j_i[2]; if(k_i[2] < 0) k_i[2] += field->n[2]; else k_i[2] = k_i[2] % field->n[2]; // ... x-coordinate ... // Depending on x-index, add contribution to the // local array or to the slab buffers. k_i[0] = (i_i[0] + j_i[0]); if(k_i[0] < field->i_R_start_local[0]) { k_i[0] -= (field->i_R_start_local[0] - W_search_lo); if(k_i[0] < 0) SID_exit_error("Left slab buffer limit exceeded by %d element(s).", SID_ERROR_LOGIC, -k_i[0]); send_left[index_FFT_R(field, k_i)] += W_i * value_i; if(field_norm != NULL) send_left_norm[index_FFT_R(field_norm, k_i)] += W_i * norm_i; } else if(k_i[0] > field->i_R_stop_local[0]) { k_i[0] -= (field->i_R_stop_local[0] + 1); if(k_i[0] >= W_search_hi) SID_exit_error("Right slab buffer limit exceeded by %d element(s).", SID_ERROR_LOGIC, k_i[0] - W_search_hi + 1); else { send_right[index_FFT_R(field, k_i)] += W_i * value_i; if(field_norm != NULL) send_right_norm[index_FFT_R(field_norm, k_i)] += W_i * norm_i; } } else { field->field_local[index_local_FFT_R(field, k_i)] += W_i * value_i; if(field_norm != NULL) field_norm->field_local[index_local_FFT_R(field_norm, k_i)] += W_i * norm_i; } flag_viable = GBP_FALSE; } } } } // Report the calculation's progress SID_check_pcounter(&pcounter, i_p); } SID_log("Done.", SID_LOG_CLOSE); // Perform exchange of slab buffers and add them to the local mass distribution. // Note: it's important that the FFT field not be padded (see above, where // this is set) for this to work the way it's done. SID_log("Adding-in the slab buffers...", SID_LOG_OPEN | SID_LOG_TIMER); // Numerator first ... exchange_slab_buffer_left(send_left, send_size_left, receive_right, &receive_right_size, &(field->slab)); exchange_slab_buffer_right(send_right, send_size_right, receive_left, &receive_left_size, &(field->slab)); for(i_b = 0; i_b < n_send_right; i_b++) field->field_local[i_b] += receive_left[i_b]; for(i_b = 0; i_b < n_send_left; i_b++) field->field_local[field->n_field_R_local - n_send_left + i_b] += receive_right[i_b]; // ... then denominator (if it's being used) if(field_norm != NULL) { exchange_slab_buffer_left(send_left_norm, send_size_left, receive_right_norm, &receive_right_size, &(field_norm->slab)); exchange_slab_buffer_right(send_right_norm, send_size_right, receive_left_norm, &receive_left_size, &(field_norm->slab)); for(i_b = 0; i_b < n_send_right; i_b++) field_norm->field_local[i_b] += receive_left_norm[i_b]; for(i_b = 0; i_b < n_send_left; i_b++) field_norm->field_local[field_norm->n_field_R_local - n_send_left + i_b] += receive_right[i_b]; } SID_free(SID_FARG send_left); SID_free(SID_FARG send_right); SID_free(SID_FARG receive_left); SID_free(SID_FARG receive_right); if(field_norm != NULL) { SID_free(SID_FARG send_left_norm); SID_free(SID_FARG send_right_norm); SID_free(SID_FARG receive_left_norm); SID_free(SID_FARG receive_right_norm); } SID_log("Done.", SID_LOG_CLOSE); // Recompute local normalization (more accurate for large sample sizes) if(!SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_NONORM)) { SID_log("Applying normalization...", SID_LOG_OPEN); if(field_norm != NULL) { for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++) { if(field_norm->field_local[i_grid] != 0) field->field_local[i_grid] /= field_norm->field_local[i_grid]; } } if(SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_APPLYFACTOR)) { for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++) field->field_local[i_grid] *= normalization_constant; } if(SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_FORCENORM)) { norm_local = 0; for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++) norm_local += (double)field->field_local[i_grid]; calc_sum_global(&norm_local, &normalization, 1, SID_DOUBLE, CALC_MODE_DEFAULT, SID_COMM_WORLD); double normalization_factor; normalization_factor = normalization_constant / normalization; for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++) field->field_local[i_grid] *= normalization_factor; } SID_log("Done.", SID_LOG_CLOSE, normalization); } if(W_r_Daub_interp != NULL) free_interpolate(SID_FARG W_r_Daub_interp, NULL); SID_log("Done.", SID_LOG_CLOSE); }
int main(int argc, char *argv[]){ SID_init(&argc,&argv,NULL,NULL); // Parse arguments and initialize double z; if(argc<2 || argc>3){ fprintf(stderr,"\n Syntax: %s z [gbpCosmo_file.txt]\n",argv[0]); fprintf(stderr," ------\n\n"); return(ERROR_SYNTAX); } else z=(double)atof(argv[1]); SID_log("Computing clustering information for z=%.2lf...",SID_LOG_OPEN,z); // Initialize cosmology cosmo_info *cosmo=NULL; if(argc==2) init_cosmo_default(&cosmo); else if(argc==3) read_gbpCosmo_file(&cosmo,argv[2]); // Initialize int mode =PSPEC_LINEAR_TF; int component=PSPEC_ALL_MATTER; init_sigma_M(&cosmo,z,mode,component); int n_k =((int *)ADaPS_fetch(cosmo,"n_k"))[0]; double *lk_P = (double *)ADaPS_fetch(cosmo,"lk_P"); double h_Hubble=((double *)ADaPS_fetch(cosmo,"h_Hubble"))[0]; SID_log("Done.",SID_LOG_CLOSE); // Generate file SID_log("Writing table to stdout...",SID_LOG_OPEN); double delta_c =1.686; double m_per_mpc_h=M_PER_MPC/h_Hubble; printf("# Column (01): k [h Mpc^-1]\n"); printf("# (02): R [h^-1 Mpc] \n"); printf("# (03): M [h^-1 M_sol]\n"); printf("# (04): V_max [km/s] \n"); printf("# (05): P_k [(h^-1 Mpc)^3]\n"); printf("# (06): sigma\n"); printf("# (07): nu (peak height)\n"); printf("# (08): b_BPR\n"); printf("# (09): b_TRK\n"); printf("# (10): z-space boost Kaiser '87 (applied to b_TRK)\n"); printf("# (11): b_TRK total (w/ Kaiser boost)\n"); printf("# (12): b_halo_Poole \n"); printf("# (13): z-space boost Poole \n"); printf("# (14): b_total_Poole \n"); printf("# (15): b_halo_Poole (substructure)\n"); printf("# (16): z-space boost Poole (substructure)\n"); printf("# (17): b_total_Poole (substructure)\n"); for(int i_k=0;i_k<n_k;i_k++){ double k_P =take_alog10(lk_P[i_k]); double R_P =R_of_k(k_P); double M_R =M_of_k(k_P,z,cosmo); double P_k =power_spectrum(k_P,z,&cosmo,mode,component); double sigma=sqrt(power_spectrum_variance(k_P,z,&cosmo,mode,component)); double V_max=V_max_NFW(M_R,z,NFW_MODE_DEFAULT,&cosmo); double nu =delta_c/sigma; double bias =1.; if(M_R<1e16*M_SOL){ printf("%10.5le %10.5le %10.5le %10.5le %10.5le %10.5le %10.5le %10.5le %10.5le %10.5le %10.5le %10.5le %10.5le %10.5le %10.5le %10.5le %10.5le\n", k_P*m_per_mpc_h, R_P/m_per_mpc_h, M_R/(M_SOL/h_Hubble), V_max*1e-3, P_k/pow(m_per_mpc_h,3.), sigma, nu, bias_model(M_R,delta_c,z,&cosmo,BIAS_MODEL_BPR), bias_model(M_R,delta_c,z,&cosmo,BIAS_MODEL_TRK), bias_model(M_R,delta_c,z,&cosmo,BIAS_MODEL_TRK|BIAS_MODEL_KAISER_BOOST), bias_model(M_R,delta_c,z,&cosmo,BIAS_MODEL_TRK|BIAS_MODEL_KAISER), bias_model(M_R,delta_c,z,&cosmo,BIAS_MODEL_POOLE_HALO), bias_model(M_R,delta_c,z,&cosmo,BIAS_MODEL_POOLE_ZSPACE), bias_model(M_R,delta_c,z,&cosmo,BIAS_MODEL_POOLE_TOTAL), bias_model(M_R,delta_c,z,&cosmo,BIAS_MODEL_POOLE_SUBSTRUCTURE|BIAS_MODEL_POOLE_HALO), bias_model(M_R,delta_c,z,&cosmo,BIAS_MODEL_POOLE_SUBSTRUCTURE|BIAS_MODEL_POOLE_ZSPACE), bias_model(M_R,delta_c,z,&cosmo,BIAS_MODEL_POOLE_SUBSTRUCTURE|BIAS_MODEL_POOLE_TOTAL)); } } SID_log("Done.",SID_LOG_CLOSE); // Clean-up free_cosmo(&cosmo); SID_log("Done.",SID_LOG_CLOSE); SID_exit(ERROR_NONE); }
void display_gadget_header(plist_info *plist){ FILE *fp; char **pname; int i,j,k; int counter; size_t n_of_type[N_GADGET_TYPE]; int n_of_type_tmp[N_GADGET_TYPE]; int flag_used[N_GADGET_TYPE]; size_t n_particles; int unused[256]; size_t n_all[N_GADGET_TYPE]; int n_all_tmp[N_GADGET_TYPE]; int n_files; int junk; double d_value; double *d_array; double *d1_array; double *d2_array; double *d3_array; int min_i; int max_i; double mean; double min; double max; double median; double std_dev; double mass_array; float f_temp; float f1_temp; float f2_temp; float f3_temp; int i_value; int *i_array; int i_temp; int i1_temp; int i2_temp; int n_type_used; long record_length; int n_return; int s_load; int flag_alloc_d1_array; size_t n_all_species; char var_name[256]; char var_name2[256]; double redshift; double h_Hubble; double Omega_M; double Omega_Lambda; double rho_crit; pname=plist->species; // Determine which species are present n_particles=0; for(i=0,n_type_used=0;i<plist->n_species;i++) { if(ADaPS_exist(plist->data,"n_%s",pname[i])){ n_of_type[i]=((size_t *)ADaPS_fetch(plist->data,"n_%s",pname[i]))[0]; if(n_of_type[i]>0){ n_particles+=n_of_type[i]; flag_used[i]=TRUE; n_type_used++; } else{ n_of_type[i]=0; flag_used[i]=FALSE; } } else{ n_of_type[i]=0; flag_used[i]=FALSE; } } h_Hubble=((double *)ADaPS_fetch(plist->data,"h_Hubble"))[0]; fprintf(stderr,"\n"); // Expansion factor (or time) if(ADaPS_exist(plist->data,"expansion_factor")) fprintf(stderr,"%20s = %le\n","Expansion factor",((double *)ADaPS_fetch(plist->data,"expansion_factor"))[0]); else if(ADaPS_exist(plist->data,"time")) fprintf(stderr,"%20s = %le Myrs\n","Time",((double *)ADaPS_fetch(plist->data,"time"))[0]/(S_PER_MYR)); else fprintf(stderr,"time/expansion factor not set!\n"); // Redshift if(ADaPS_exist(plist->data,"redshift")){ redshift=((double *)ADaPS_fetch(plist->data,"redshift"))[0]; fprintf(stderr,"%20s = %le\n","Redshift",redshift); } else{ fprintf(stderr,"redshift not set!\n"); redshift=0.; } // Some flags if(ADaPS_exist(plist->data,"flag_Sfr")) fprintf(stderr,"%20s = %d\n","flag_Sfr",((int *)ADaPS_fetch(plist->data,"flag_Sfr"))[0]); else fprintf(stderr,"flag_Sfr not set!\n"); if(ADaPS_exist(plist->data,"flag_feedback")) fprintf(stderr,"%20s = %d\n","flag_feedback",((int *)ADaPS_fetch(plist->data,"flag_feedback"))[0]); else fprintf(stderr,"flag_feedback not set!\n"); // Another flag if(ADaPS_exist(plist->data,"flag_cooling")) fprintf(stderr,"%20s = %d\n","flag_cooling",((int *)ADaPS_fetch(plist->data,"flag_cooling"))[0]); else fprintf(stderr,"flag_cooling not set!\n"); // Number of files per snapshot if(ADaPS_exist(plist->data,"n_files")) fprintf(stderr,"%20s = %d\n","files per snap",((int *)ADaPS_fetch(plist->data,"n_files"))[0]); else fprintf(stderr,"files per snapshot not set!\n"); // Box size if(ADaPS_exist(plist->data,"box_size")) fprintf(stderr,"%20s = %le [kpc/h]\n","box size",((double *)ADaPS_fetch(plist->data,"box_size"))[0]/(M_PER_KPC/h_Hubble)); else fprintf(stderr,"box size not set!\n"); // Cosmology if(ADaPS_exist(plist->data,"h_Hubble")){ fprintf(stderr,"%20s = %le\n","h_Hubble",h_Hubble); } else{ h_Hubble=1.; fprintf(stderr,"h_Hubble not set!\n"); } if(ADaPS_exist(plist->data,"Omega_M")){ Omega_M=((double *)ADaPS_fetch(plist->data,"Omega_M"))[0]; fprintf(stderr,"%20s = %le\n","Omega_M",Omega_M); } else fprintf(stderr,"Omega_M not set!\n"); if(Omega_M<=0.) Omega_M=0.3; if(ADaPS_exist(plist->data,"Omega_Lambda")){ Omega_Lambda=((double *)ADaPS_fetch(plist->data,"Omega_Lambda"))[0]; fprintf(stderr,"%20s = %le\n","Omega_Lambda",Omega_Lambda); } else fprintf(stderr,"Omega_Lambda not set!\n"); /* Number of particles */ for(i=0;i<plist->n_species;i++){ sprintf(var_name,"n_%s",pname[i]); if(ADaPS_exist(plist->data,var_name)){ sprintf(var_name2,"n_[%s]",pname[i]); fprintf(stderr,"%20s = %zd\n",var_name2,((size_t *)ADaPS_fetch(plist->data,var_name))[0]); } } for(i=0;i<plist->n_species;i++){ sprintf(var_name,"n_all_%s",pname[i]); if(ADaPS_exist(plist->data,var_name)){ sprintf(var_name2,"n_all_[%s]",pname[i]); fprintf(stderr,"%20s = %zd\n",var_name2,((size_t *)ADaPS_fetch(plist->data,var_name))[0]); } } /* Particle mass array */ for(i=0;i<plist->n_species;i++){ if(flag_used[i]){ sprintf(var_name,"mass_array_%s",pname[i]); if(ADaPS_exist(plist->data,var_name)){ sprintf(var_name2,"mass_array_[%s]",pname[i]); fprintf(stderr,"%20s = %le [M_sol/h]\n",var_name2,((double *)ADaPS_fetch(plist->data,var_name))[0]/(M_SOL/h_Hubble)); } } } };
int main(int argc, char *argv[]) { SID_Init(&argc, &argv, NULL); // Fetch user inputs char filename_halos_root[256]; char filename_catalog_root[256]; char filename_PHKs_root[256]; double box_size; double dx; int i_file_lo_in; int i_file_hi_in; int i_file_skip; strcpy(filename_halos_root, argv[1]); strcpy(filename_catalog_root, argv[2]); strcpy(filename_PHKs_root, argv[3]); box_size = atof(argv[4]); dx = atof(argv[5]); i_file_lo_in = atoi(argv[6]); i_file_hi_in = atoi(argv[7]); i_file_skip = atoi(argv[8]); int i_file_lo; int i_file_hi; if(i_file_lo_in < i_file_hi_in) { i_file_lo = i_file_lo_in; i_file_hi = i_file_hi_in; } else { i_file_lo = i_file_hi_in; i_file_hi = i_file_lo_in; } SID_log("Generating group PH keys for files #%d->#%d...", SID_LOG_OPEN | SID_LOG_TIMER, i_file_lo, i_file_hi); for(int i_file = i_file_lo; i_file <= i_file_hi; i_file += i_file_skip) { SID_log("Processing file #%03d...", SID_LOG_OPEN | SID_LOG_TIMER, i_file); SID_set_verbosity(SID_SET_VERBOSITY_RELATIVE, 0); // Read group info from the halo catalogs plist_info plist; int * PHK_group = NULL; size_t * PHK_group_index = NULL; char * filename_number = (char *)SID_malloc(sizeof(char) * 10); init_plist(&plist, NULL, GADGET_LENGTH, GADGET_MASS, GADGET_VELOCITY); sprintf(filename_number, "%03d", i_file); ADaPS_store(&(plist.data), (void *)filename_number, "read_catalog", ADaPS_DEFAULT); read_groups(filename_halos_root, i_file, READ_GROUPS_ALL | READ_GROUPS_MBP_IDS_ONLY, &plist, filename_number); int n_groups_all = ((int *)ADaPS_fetch(plist.data, "n_groups_all_%s", filename_number))[0]; int n_groups = ((int *)ADaPS_fetch(plist.data, "n_groups_%s", filename_number))[0]; // If there's any groups to analyze ... int * n_particles_groups = NULL; size_t n_particles_cumulative = 0; int n_bits = 0; // Default value if there are no groups if(n_groups > 0) { // Fetch the halo sizes n_particles_groups = (int *)ADaPS_fetch(plist.data, "n_particles_group_%s", filename_number); // Read MBP data from halo catalogs SID_log("Reading most-bound-particle positions...", SID_LOG_OPEN); halo_properties_info group_properties; fp_catalog_info fp_group_properties; double * x_array = (double *)SID_malloc(sizeof(double) * n_groups); double * y_array = (double *)SID_malloc(sizeof(double) * n_groups); double * z_array = (double *)SID_malloc(sizeof(double) * n_groups); fopen_catalog(filename_catalog_root, i_file, READ_CATALOG_GROUPS | READ_CATALOG_PROPERTIES, &fp_group_properties); if(fp_group_properties.n_halos_total != n_groups) SID_exit_error("Halo counts in group files and catalogs don't match (ie. %d!=%d)", SID_ERROR_LOGIC, fp_group_properties.n_halos_total, n_groups); for(int i_group = 0; i_group < n_groups; i_group++) { fread_catalog_file(&fp_group_properties, NULL, NULL, &group_properties, NULL, i_group); x_array[i_group] = group_properties.position_MBP[0]; y_array[i_group] = group_properties.position_MBP[1]; z_array[i_group] = group_properties.position_MBP[2]; // Enforce periodic BCs if(x_array[i_group] < 0.) x_array[i_group] += box_size; if(x_array[i_group] >= box_size) x_array[i_group] -= box_size; if(y_array[i_group] < 0.) y_array[i_group] += box_size; if(y_array[i_group] >= box_size) y_array[i_group] -= box_size; if(z_array[i_group] < 0.) z_array[i_group] += box_size; if(z_array[i_group] >= box_size) z_array[i_group] -= box_size; } fclose_catalog(&fp_group_properties); SID_log("Done.", SID_LOG_CLOSE); // Determine the number of bits to use for the PHKs for(n_bits = N_BITS_MIN; (box_size / pow(2., (double)(n_bits + 1))) > dx && n_bits <= 20;) n_bits++; // Compute PHKs SID_log("Computing PHKs (using %d bits per dimension)...", SID_LOG_OPEN, n_bits); PHK_group = (int *)SID_malloc(sizeof(int) * n_groups); for(int i_group = 0; i_group < n_groups; i_group++) { // Compute the key for this group PHK_group[i_group] = compute_PHK_from_Cartesian( n_bits, 3, (double)x_array[i_group] / box_size, (double)y_array[i_group] / box_size, (double)z_array[i_group] / box_size); } SID_free(SID_FARG x_array); SID_free(SID_FARG y_array); SID_free(SID_FARG z_array); SID_log("Done.", SID_LOG_CLOSE); // Sort PHKs SID_log("Sorting PHKs...", SID_LOG_OPEN); merge_sort((void *)PHK_group, n_groups, &PHK_group_index, SID_INT, SORT_COMPUTE_INDEX, GBP_FALSE); SID_log("Done.", SID_LOG_CLOSE); // Count the number of particles for(int i_group = 0; i_group < n_groups; i_group++) n_particles_cumulative += n_particles_groups[PHK_group_index[i_group]]; } // Write results SID_log("Writing results for %d groups...", SID_LOG_OPEN, n_groups); char filename_output_properties[256]; sprintf(filename_output_properties, "%s_%s.catalog_PHKs", filename_PHKs_root, filename_number); FILE *fp_PHKs = fopen(filename_output_properties, "w"); fwrite(&n_groups, sizeof(int), 1, fp_PHKs); fwrite(&n_bits, sizeof(int), 1, fp_PHKs); fwrite(&n_particles_cumulative, sizeof(size_t), 1, fp_PHKs); n_particles_cumulative = 0; for(int i_group = 0; i_group < n_groups; i_group++) { int index_temp = (int)PHK_group_index[i_group]; n_particles_cumulative += n_particles_groups[index_temp]; fwrite(&(PHK_group[index_temp]), sizeof(int), 1, fp_PHKs); fwrite(&index_temp, sizeof(int), 1, fp_PHKs); fwrite(&n_particles_cumulative, sizeof(size_t), 1, fp_PHKs); } fclose(fp_PHKs); SID_log("Done.", SID_LOG_CLOSE); // Clean-up free_plist(&plist); if(n_groups > 0) { SID_free(SID_FARG PHK_group); SID_free(SID_FARG PHK_group_index); } SID_set_verbosity(SID_SET_VERBOSITY_DEFAULT); SID_log("Done.", SID_LOG_CLOSE); } SID_log("Done.", SID_LOG_CLOSE); SID_Finalize(); }
size_t mark_particles(plist_info *plist, int run_mode, double *input_vals, const char *mark_name) { size_t n_particles; size_t n_particles_local; size_t i_particle; int i_species; size_t * id; GBPREAL *x; GBPREAL *y; GBPREAL *z; GBPREAL r; int * mark_array; int flag_volume; int flag_volume_sphere; size_t n_marked_local = 0; size_t n_marked = 0; // Interpret run-mode flag_volume = SID_CHECK_BITFIELD_SWITCH(run_mode, VOLUME_BOX) || SID_CHECK_BITFIELD_SWITCH(run_mode, VOLUME_SPHERE); flag_volume_sphere = SID_CHECK_BITFIELD_SWITCH(run_mode, VOLUME_SPHERE); // Loop over all species for(i_species = 0; i_species < N_GADGET_TYPE; i_species++) { if(ADaPS_exist(plist->data, "n_all_%s", plist->species[i_species])) { n_particles = ((size_t *)ADaPS_fetch(plist->data, "n_all_%s", plist->species[i_species]))[0]; n_particles_local = ((size_t *)ADaPS_fetch(plist->data, "n_%s", plist->species[i_species]))[0]; // If this species has local particles if(n_particles_local > 0) { mark_array = (int *)SID_malloc(sizeof(int) * n_particles_local); // Mark particles in a volume if(flag_volume) { x = (GBPREAL *)ADaPS_fetch(plist->data, "x_%s", plist->species[i_species]); y = (GBPREAL *)ADaPS_fetch(plist->data, "y_%s", plist->species[i_species]); z = (GBPREAL *)ADaPS_fetch(plist->data, "z_%s", plist->species[i_species]); // Loop over all particles for(i_particle = 0; i_particle < n_particles_local; i_particle++) { mark_array[i_particle] = GBP_FALSE; switch(flag_volume_sphere) { case GBP_TRUE: if(add_quad(3, (double)(x[i_particle]) - input_vals[0], (double)(y[i_particle]) - input_vals[1], (double)(z[i_particle]) - input_vals[2]) <= input_vals[3]) mark_array[i_particle] = GBP_TRUE; break; case GBP_FALSE: if(x[i_particle] >= (GBPREAL)input_vals[0] && x[i_particle] <= (GBPREAL)input_vals[1]) { if(y[i_particle] >= (GBPREAL)input_vals[2] && y[i_particle] <= (GBPREAL)input_vals[3]) { if(z[i_particle] >= (GBPREAL)input_vals[4] && z[i_particle] <= (GBPREAL)input_vals[5]) { mark_array[i_particle] = GBP_TRUE; } } } break; } } } // Mark particles by property else { } for(i_particle = 0; i_particle < n_particles_local; i_particle++) if(mark_array[i_particle]) n_marked_local++; ADaPS_store(&(plist->data), (void *)mark_array, "%s_%s", ADaPS_DEFAULT, mark_name, plist->species[i_species]); } } } calc_sum_global(&n_marked_local, &n_marked, 1, SID_SIZE_T, CALC_MODE_DEFAULT, SID_COMM_WORLD); return (n_marked); }
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); }