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); }
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); }
void read_gbpCosmo_file(cosmo_info **cosmo, const char *filename_in) { char Name[PARAMETER_STRING_LENGTH]; double Omega_M; double Omega_k; double Omega_Lambda; double Omega_b; double f_gas; double h_Hubble; double sigma_8; double n_spectral; // In some cases we may want to tell a code not to // execute this routine. This gives us a way to do that. int flag_skip = GBP_FALSE; if(filename_in != NULL) { if(!strcmp(filename_in, "skip")) flag_skip = GBP_TRUE; } // If we are not skipping this routine ... if(!flag_skip) { // Define the parameter file parameter_list_info *parameter_list = NULL; init_parameter_list(¶meter_list); add_parameter_to_list(parameter_list, "Name", SID_CHAR, PARAMETER_MODE_OPTIONAL); add_parameter_to_list(parameter_list, "Omega_Lambda", SID_DOUBLE, PARAMETER_MODE_DEFAULT); add_parameter_to_list(parameter_list, "Omega_M", SID_DOUBLE, PARAMETER_MODE_DEFAULT); add_parameter_to_list(parameter_list, "Omega_k", SID_DOUBLE, PARAMETER_MODE_DEFAULT); add_parameter_to_list(parameter_list, "Omega_b", SID_DOUBLE, PARAMETER_MODE_DEFAULT); add_parameter_to_list(parameter_list, "h_Hubble", SID_DOUBLE, PARAMETER_MODE_DEFAULT); add_parameter_to_list(parameter_list, "sigma_8", SID_DOUBLE, PARAMETER_MODE_DEFAULT); add_parameter_to_list(parameter_list, "n_spectral", SID_DOUBLE, PARAMETER_MODE_DEFAULT); add_parameter_to_list(parameter_list, "f_gas", SID_DOUBLE, PARAMETER_MODE_OPTIONAL); // Read the cosmology from file char filename_cosmo[SID_MAX_FILENAME_LENGTH]; char filename_TF[SID_MAX_FILENAME_LENGTH]; if(filename_in == NULL) { sprintf(filename_cosmo, "%s/cosmology_%s.txt", GBP_DATA_DIR, GBP_COSMOLOGY_DEFAULT); sprintf(filename_TF, "%s/transfer_function_%s.txt", GBP_DATA_DIR, GBP_COSMOLOGY_DEFAULT); } else { if(!strcmp(filename_in, "default")) { sprintf(filename_cosmo, "%s/cosmology_%s.txt", GBP_DATA_DIR, GBP_COSMOLOGY_DEFAULT); sprintf(filename_TF, "%s/transfer_function_%s.txt", GBP_DATA_DIR, GBP_COSMOLOGY_DEFAULT); } else if(!strcmp(filename_in, "WMAP-1") || !strcmp(filename_in, "WMAP-5") || !strcmp(filename_in, "WMAP-7") || !strcmp(filename_in, "Planck-2013") || !strcmp(filename_in, "Planck-2015")) { sprintf(filename_cosmo, "%s/cosmology_%s.txt", GBP_DATA_DIR, filename_in); sprintf(filename_TF, "%s/transfer_function_%s.txt", GBP_DATA_DIR, filename_in); } else { sprintf(filename_cosmo, "%s/cosmology.txt", filename_in); sprintf(filename_TF, "%s/transfer_function.txt", filename_in); } } // Ininitalize ADaPS_init(cosmo); // Store the transfer function filename ADaPS_store(cosmo, filename_TF, "filename_transfer_function", ADaPS_COPY, SID_MAX_FILENAME_LENGTH); // Initialize the cosmology file description read_gbpParam_file(filename_cosmo, parameter_list); fetch_parameter_data(parameter_list, "Omega_Lambda", &Omega_Lambda); fetch_parameter_data(parameter_list, "Omega_M", &Omega_M); fetch_parameter_data(parameter_list, "Omega_k", &Omega_k); fetch_parameter_data(parameter_list, "Omega_b", &Omega_b); fetch_parameter_data(parameter_list, "h_Hubble", &h_Hubble); fetch_parameter_data(parameter_list, "sigma_8", &sigma_8); fetch_parameter_data(parameter_list, "n_spectral", &n_spectral); // Set defaults for optional paramaters char *Name_pass = NULL; if(fetch_parameter_data(parameter_list, "Name", Name)) Name_pass = Name; if(!fetch_parameter_data(parameter_list, "f_gas", &f_gas)) f_gas = Omega_b / Omega_M; // Perform initialization init_cosmo(cosmo, Name_pass, Omega_Lambda, Omega_M, Omega_k, Omega_b, f_gas, h_Hubble, sigma_8, n_spectral); // Clean-up free_parameter_list(¶meter_list); } }
void read_gadget_binary_local(char *filename_root_in, int snapshot_number, int i_coord, int i_load, int n_load, GBPREAL mass_array[N_GADGET_TYPE], slab_info *slab, cosmo_info *cosmo, plist_info *plist){ size_t n_of_type_local[N_GADGET_TYPE]; size_t n_of_type[N_GADGET_TYPE]; size_t type_counter[N_GADGET_TYPE]; GBPREAL *x_array[N_GADGET_TYPE]; GBPREAL *y_array[N_GADGET_TYPE]; GBPREAL *z_array[N_GADGET_TYPE]; GBPREAL *vx_array[N_GADGET_TYPE]; GBPREAL *vy_array[N_GADGET_TYPE]; GBPREAL *vz_array[N_GADGET_TYPE]; int i_type; // Determine file format and read the header gadget_read_info fp_gadget; int flag_filefound=init_gadget_read(filename_root_in,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; // A file was found ... if(flag_filefound){ char **pname; SID_log("Reading GADGET binary file...",SID_LOG_OPEN|SID_LOG_TIMER); pname=plist->species; // Expansion factor (or time) ADaPS_store(&(plist->data),(void *)(&(header.time)),"expansion_factor",ADaPS_SCALAR_DOUBLE); ADaPS_store(&(plist->data),(void *)(&(header.time)),"time", ADaPS_SCALAR_DOUBLE); // Redshift double d_value; d_value=(double)header.redshift; ADaPS_store(&(plist->data),(void *)(&d_value),"redshift",ADaPS_SCALAR_DOUBLE); // Number of particles and masses for each species in all files size_t n_all[N_GADGET_TYPE]; for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ n_all[i_type] =(size_t)header.n_all_lo_word[i_type]+((size_t)header.n_all_hi_word[i_type])<<32; mass_array[i_type]=(GBPREAL)header.mass_array[i_type]; } // Number of files in this snapshot int n_files; ADaPS_store(&(plist->data),(void *)(&(header.n_files)),"n_files",ADaPS_SCALAR_INT); n_files=header.n_files; // Cosmology // Omega_o d_value=(double)header.Omega_M; ADaPS_store(&(plist->data),(void *)(&d_value),"Omega_M",ADaPS_SCALAR_DOUBLE); // Omega_Lambda d_value=(double)header.Omega_Lambda; ADaPS_store(&(plist->data),(void *)(&d_value),"Omega_Lambda",ADaPS_SCALAR_DOUBLE); // Hubble parameter double h_Hubble; double redshift; h_Hubble=(double)header.h_Hubble; if(h_Hubble<1e-10) h_Hubble=1.; ADaPS_store(&(plist->data),(void *)(&h_Hubble),"h_Hubble",ADaPS_SCALAR_DOUBLE); redshift=header.redshift; ADaPS_store(&(plist->data),(void *)(&redshift),"redshift",ADaPS_SCALAR_DOUBLE); // Count and report the total number of particles size_t n_particles_all; int n_non_zero; n_particles_all=0; for(i_type=0,n_non_zero=0;i_type<N_GADGET_TYPE;i_type++){ if(n_all[i_type]>0){ n_particles_all+=n_all[i_type]; n_non_zero++; } } SID_log("%zd",SID_LOG_CONTINUE,n_particles_all); if(n_non_zero>0) SID_log(" (",SID_LOG_CONTINUE,n_particles_all); for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ if(n_all[i_type]>0){ if(i_type==n_non_zero-1){ if(n_non_zero>1) SID_log("and %lld %s",SID_LOG_CONTINUE,n_all[i_type],pname[i_type]); else SID_log("%lld %s",SID_LOG_CONTINUE,n_all[i_type],pname[i_type]); } else{ if(n_non_zero>1) SID_log("%lld %s, ",SID_LOG_CONTINUE,n_all[i_type],pname[i_type]); else SID_log("%lld %s",SID_LOG_CONTINUE,n_all[i_type],pname[i_type]); } } } if(n_non_zero>0) SID_log(") particles...",SID_LOG_CONTINUE); else SID_log(" particles...",SID_LOG_CONTINUE); // Count the number of particles that will be scattered to each rank char filename[MAX_FILENAME_LENGTH]; size_t k_particle; int i_file; int record_length_open; int record_length_close; size_t i_particle; size_t i_buffer; size_t i_step; int i_type; size_t index; GBPREAL *pos_buffer; GBPREAL *vel_buffer; double pos_test; // Initialize some arrays pos_buffer=(GBPREAL *)SID_malloc(sizeof(GBPREAL)*READ_BUFFER_ALLOC_LOCAL); vel_buffer=(GBPREAL *)SID_malloc(sizeof(GBPREAL)*READ_BUFFER_ALLOC_LOCAL); for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ n_of_type_local[i_type]=0; n_of_type[i_type] =0; type_counter[i_type] =0; } // Determine how many particles of each type will end-up on each core SID_log("Performing domain decomposition...",SID_LOG_OPEN|SID_LOG_TIMER); int n_read; if(n_load<n_files) n_read=n_files; else n_read=1; for(i_file=i_load;i_file<(i_load+n_read);i_file++){ set_gadget_filename(&fp_gadget,i_file,filename); // Read header and move to the positions FILE *fp_pos; FILE *fp_vel; fp_pos=fopen(filename,"r"); fread_verify(&record_length_open,4,1,fp_pos); fread_verify(&header,sizeof(gadget_header_info),1,fp_pos); fread_verify(&record_length_close,4,1,fp_pos); if(record_length_open!=record_length_close) SID_log_warning("Problem with GADGET record size (close of header)",ERROR_LOGIC); fread_verify(&record_length_open,4,1,fp_pos); // Create a file pointer to the velocities fp_vel=fopen(filename,"r"); fread_verify(&record_length_open,4,1,fp_vel); fseeko(fp_vel,(off_t)(record_length_open),SEEK_CUR); fread_verify(&record_length_close,4,1,fp_vel); fread_verify(&record_length_open,4,1,fp_vel); fseeko(fp_vel,(off_t)(record_length_open),SEEK_CUR); fread_verify(&record_length_close,4,1,fp_vel); if(record_length_open!=record_length_close) SID_log_warning("Problem with GADGET record size (close of positons)",ERROR_LOGIC); fread_verify(&record_length_open,4,1,fp_vel); // We only have to worry about z-space effects for domain decomposition in this one case. if(i_coord==1){ for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ for(i_particle=0;i_particle<header.n_file[i_type];i_particle+=i_step){ i_step=MIN(READ_BUFFER_SIZE_LOCAL,header.n_file[i_type]-i_particle); if(SID.I_am_Master){ fread_verify(pos_buffer,sizeof(GBPREAL),3*i_step,fp_pos); fread_verify(vel_buffer,sizeof(GBPREAL),3*i_step,fp_vel); } SID_Bcast(pos_buffer,sizeof(GBPREAL)*3*i_step,MASTER_RANK,SID.COMM_WORLD); SID_Bcast(vel_buffer,sizeof(GBPREAL)*3*i_step,MASTER_RANK,SID.COMM_WORLD); for(i_buffer=0;i_buffer<i_step;i_buffer++){ index=3*i_buffer; pos_test =(double)(pos_buffer[index]); pos_test+=(double)(1e3*h_Hubble*((double)vel_buffer[index])/(a_of_z(redshift)*M_PER_MPC*H_convert(H_z(redshift,cosmo)))); if(pos_test<0) pos_test+=header.box_size; if(pos_test>=header.box_size) pos_test-=header.box_size; if(pos_test>=slab->x_min_local && pos_test<slab->x_max_local) n_of_type_local[i_type]++; } } } } else{ for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ for(i_particle=0;i_particle<header.n_file[i_type];i_particle+=i_step){ i_step=MIN(READ_BUFFER_SIZE_LOCAL,header.n_file[i_type]-i_particle); if(SID.I_am_Master){ fread_verify(pos_buffer,sizeof(GBPREAL),3*i_step,fp_pos); fread_verify(vel_buffer,sizeof(GBPREAL),3*i_step,fp_vel); } SID_Bcast(pos_buffer,sizeof(GBPREAL)*3*i_step,MASTER_RANK,SID.COMM_WORLD); SID_Bcast(vel_buffer,sizeof(GBPREAL)*3*i_step,MASTER_RANK,SID.COMM_WORLD); for(i_buffer=0;i_buffer<i_step;i_buffer++){ pos_test=pos_buffer[3*i_buffer]; if(pos_test>=slab->x_min_local && pos_test<slab->x_max_local) n_of_type_local[i_type]++; } } i_step=MIN(READ_BUFFER_SIZE_LOCAL,header.n_file[i_type]-i_particle); } } fclose(fp_pos); fclose(fp_vel); } SID_log("Done.",SID_LOG_CLOSE); // Allocate arrays for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ if(n_all[i_type]>0){ x_array[i_type] =(GBPREAL *)SID_malloc(sizeof(GBPREAL)*n_of_type_local[i_type]); y_array[i_type] =(GBPREAL *)SID_malloc(sizeof(GBPREAL)*n_of_type_local[i_type]); z_array[i_type] =(GBPREAL *)SID_malloc(sizeof(GBPREAL)*n_of_type_local[i_type]); vx_array[i_type]=(GBPREAL *)SID_malloc(sizeof(GBPREAL)*n_of_type_local[i_type]); vy_array[i_type]=(GBPREAL *)SID_malloc(sizeof(GBPREAL)*n_of_type_local[i_type]); vz_array[i_type]=(GBPREAL *)SID_malloc(sizeof(GBPREAL)*n_of_type_local[i_type]); } } // Perform read SID_log("Performing read...",SID_LOG_OPEN|SID_LOG_TIMER); for(i_file=i_load;i_file<(i_load+n_read);i_file++){ set_gadget_filename(&fp_gadget,i_file,filename); // Read header and move to the positions FILE *fp_pos; FILE *fp_vel; fp_pos=fopen(filename,"r"); fread_verify(&record_length_open,4,1,fp_pos); fread_verify(&header,sizeof(gadget_header_info),1,fp_pos); fread_verify(&record_length_close,4,1,fp_pos); if(record_length_open!=record_length_close) SID_log_warning("Problem with GADGET record size (close of header)",ERROR_LOGIC); fread_verify(&record_length_open,4,1,fp_pos); // Create a file pointer to the velocities fp_vel=fopen(filename,"r"); fread_verify(&record_length_open,4,1,fp_vel); fseeko(fp_vel,(off_t)(record_length_open),SEEK_CUR); fread_verify(&record_length_close,4,1,fp_vel); fread_verify(&record_length_open,4,1,fp_vel); fseeko(fp_vel,(off_t)(record_length_open),SEEK_CUR); fread_verify(&record_length_close,4,1,fp_vel); if(record_length_open!=record_length_close) SID_log_warning("Problem with GADGET record size (close of positions)",ERROR_LOGIC); fread_verify(&record_length_open,4,1,fp_vel); // Perform the read and populate the local position arrays size_t i_particle; size_t i_step; int i_type; for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ for(i_particle=0;i_particle<header.n_file[i_type];i_particle+=i_step){ i_step=MIN(READ_BUFFER_SIZE_LOCAL,header.n_file[i_type]-i_particle); if(SID.I_am_Master){ fread_verify(pos_buffer,sizeof(GBPREAL),3*i_step,fp_pos); fread_verify(vel_buffer,sizeof(GBPREAL),3*i_step,fp_vel); } SID_Bcast(pos_buffer,sizeof(GBPREAL)*3*i_step,MASTER_RANK,SID.COMM_WORLD); SID_Bcast(vel_buffer,sizeof(GBPREAL)*3*i_step,MASTER_RANK,SID.COMM_WORLD); for(i_buffer=0;i_buffer<i_step;i_buffer++){ double x_test; double y_test; double z_test; double vx_test; double vy_test; double vz_test; index=3*i_buffer; x_test =(double)pos_buffer[index+0]; y_test =(double)pos_buffer[index+1]; z_test =(double)pos_buffer[index+2]; vx_test=(double)vel_buffer[index+0]; vy_test=(double)vel_buffer[index+1]; vz_test=(double)vel_buffer[index+2]; switch(i_coord){ case 1: x_test+=(1e3*h_Hubble*vx_test/(a_of_z(redshift)*M_PER_MPC*H_convert(H_z(redshift,cosmo)))); if(x_test<0) x_test+=header.box_size; if(x_test>=header.box_size) x_test-=header.box_size; break; case 2: y_test+=(1e3*h_Hubble*vy_test/(a_of_z(redshift)*M_PER_MPC*H_convert(H_z(redshift,cosmo)))); if(y_test<0) y_test+=header.box_size; if(y_test>=header.box_size) y_test-=header.box_size; break; case 3: z_test+=(1e3*h_Hubble*vz_test/(a_of_z(redshift)*M_PER_MPC*H_convert(H_z(redshift,cosmo)))); if(z_test<0) z_test+=header.box_size; if(z_test>=header.box_size) z_test-=header.box_size; break; } if(x_test>=slab->x_min_local && x_test<slab->x_max_local){ x_array[i_type][type_counter[i_type]] =x_test; y_array[i_type][type_counter[i_type]] =y_test; z_array[i_type][type_counter[i_type]] =z_test; vx_array[i_type][type_counter[i_type]]=vx_test; vy_array[i_type][type_counter[i_type]]=vy_test; vz_array[i_type][type_counter[i_type]]=vz_test; type_counter[i_type]++; } } } } // Close file pointers fclose(fp_pos); fclose(fp_vel); } SID_free(SID_FARG pos_buffer); SID_free(SID_FARG vel_buffer); SID_log("Done.",SID_LOG_CLOSE); // Sanity checks size_t n_particles_local; size_t n_particles_read; size_t n_particles_test; for(i_type=0,n_particles_local=0,n_particles_test=0;i_type<N_GADGET_TYPE;i_type++){ n_particles_local+=n_of_type_local[i_type]; n_particles_test +=n_all[i_type]; } SID_Allreduce(&n_particles_local,&n_particles_read,1,SID_SIZE_T,SID_SUM,SID.COMM_WORLD); if(n_particles_read!=n_particles_test && n_load==1) SID_trap_error("Total particle counts don't make sense after read_gadget (ie. %zd!=%zd).",ERROR_LOGIC,n_particles_read,n_particles_test); for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ SID_Allreduce(&(n_of_type_local[i_type]),&(n_of_type[i_type]),1,SID_SIZE_T,SID_SUM,SID.COMM_WORLD); if(n_of_type[i_type]!=n_all[i_type] && n_load==1) SID_trap_error("Particle counts don't make sense after read_gadget (ie. %zd!=%zd).",ERROR_LOGIC,n_of_type[i_type],n_all[i_type]); } // Store results for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ if(n_of_type[i_type]>0){ ADaPS_store(&(plist->data),(void *)(&(n_of_type_local[i_type])),"n_%s", ADaPS_SCALAR_SIZE_T,pname[i_type]); ADaPS_store(&(plist->data),(void *)(&(n_of_type[i_type])), "n_all_%s", ADaPS_SCALAR_SIZE_T,pname[i_type]); } } ADaPS_store(&(plist->data),(void *)(&n_particles_all),"n_particles_all",ADaPS_SCALAR_SIZE_T); for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ if(n_of_type_local[i_type]>0){ ADaPS_store(&(plist->data),(void *)x_array[i_type], "x_%s", ADaPS_DEFAULT, pname[i_type]); ADaPS_store(&(plist->data),(void *)y_array[i_type], "y_%s", ADaPS_DEFAULT, pname[i_type]); ADaPS_store(&(plist->data),(void *)z_array[i_type], "z_%s", ADaPS_DEFAULT, pname[i_type]); ADaPS_store(&(plist->data),(void *)vx_array[i_type],"vx_%s",ADaPS_DEFAULT,pname[i_type]); ADaPS_store(&(plist->data),(void *)vy_array[i_type],"vy_%s",ADaPS_DEFAULT,pname[i_type]); ADaPS_store(&(plist->data),(void *)vz_array[i_type],"vz_%s",ADaPS_DEFAULT,pname[i_type]); } } SID_log("Done.",SID_LOG_CLOSE); } }
void read_smooth(plist_info *plist, char *filename_root_in, int snapshot_number, int mode){ char filename[256]; size_t n_particles_all_mem; size_t n_particles_local; size_t n_particles_total; int i_quantity; int n_quantities=3; int *used; char *species_name; char var_name[256]; char unit_name[256]; double unit_factor; int i_file; size_t *ids; size_t *ids_index; int n_particles_file; int offset; int n_files; void *id_buf; size_t *id_buf_index=NULL; int *id_buf_i; long long *id_buf_L; long long *mark; size_t i_particle; size_t j_particle; void *buffer; float *local_array; int n_mark; float *r_smooth_array; float *rho_array; float *sigma_v_array; char *read_array; double expansion_factor; double h_Hubble; int flag_filefound=FALSE; int flag_multifile=FALSE; int flag_file_type; int flag_LONGIDs; int read_rank=MASTER_RANK; int flag_log_sigma=FALSE; int flag_log_rho=FALSE; FILE *fp; SID_log("Reading smooth file {%s}...",SID_LOG_OPEN|SID_LOG_TIMER,filename_root_in); // Read header info SID_log("Reading header information...",SID_LOG_OPEN); smooth_header_info header; flag_filefound =init_smooth_read(filename_root_in,snapshot_number,&flag_multifile,&flag_file_type,&header); SID_log("n_files =%d", SID_LOG_COMMENT,header.n_files); SID_log("n_particles=%lld",SID_LOG_COMMENT,header.n_particles_total); SID_log("Done.",SID_LOG_CLOSE); // Interpret the mode passed to this function int flag_logs_used =FALSE; int flag_log_quantity=FALSE; if(check_mode_for_flag(mode,READ_SMOOTH_LOG_SIGMA)){ flag_log_sigma=TRUE; flag_logs_used=TRUE; } else flag_log_sigma=FALSE; if(check_mode_for_flag(mode,READ_SMOOTH_LOG_RHO)){ flag_log_rho =TRUE; flag_logs_used=TRUE; } else flag_log_rho=FALSE; // A file was found ... if(flag_filefound){ // Communicate the header n_particles_file =header.n_particles_file; offset =header.offset; n_particles_total=header.n_particles_total; n_files =MAX(1,header.n_files); SID_Bcast(&n_particles_file, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&offset, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&n_particles_total,(int)sizeof(long long),read_rank,SID.COMM_WORLD); SID_Bcast(&n_files, (int)sizeof(int), read_rank,SID.COMM_WORLD); // Fetch the number of particles and their ids species_name =plist->species[GADGET_TYPE_DARK]; n_particles_local=((size_t *)ADaPS_fetch(plist->data,"n_%s", species_name))[0]; n_particles_all_mem =((size_t *)ADaPS_fetch(plist->data,"n_all_%s",species_name))[0]; ids = (size_t *)ADaPS_fetch(plist->data,"id_%s", species_name); expansion_factor =((double *)ADaPS_fetch(plist->data,"expansion_factor"))[0]; h_Hubble =((double *)ADaPS_fetch(plist->data,"h_Hubble"))[0]; // Check if we are dealing with LONG IDs or not if(ADaPS_exist(plist->data,"flag_LONGIDs")) flag_LONGIDs=TRUE; else flag_LONGIDs=FALSE; // Sort particle IDs SID_log("Sorting particle IDs...",SID_LOG_OPEN|SID_LOG_TIMER); merge_sort(ids,(size_t)n_particles_local,&ids_index,SID_SIZE_T,SORT_COMPUTE_INDEX,FALSE); SID_log("Done.",SID_LOG_CLOSE); // Allocate arrays SID_log("Allocating arrays...",SID_LOG_OPEN); read_array=(char *)SID_calloc(sizeof(char)*n_particles_local); for(i_quantity=0;i_quantity<n_quantities;i_quantity++){ switch(i_quantity){ case 0: r_smooth_array=(float *)SID_malloc(sizeof(float)*n_particles_local); ADaPS_store(&(plist->data),r_smooth_array,"r_smooth_%s",ADaPS_DEFAULT,species_name); break; case 1: rho_array=(float *)SID_malloc(sizeof(float)*n_particles_local); ADaPS_store(&(plist->data),rho_array,"rho_%s",ADaPS_DEFAULT,species_name); break; case 2: sigma_v_array=(float *)SID_malloc(sizeof(float)*n_particles_local); ADaPS_store(&(plist->data),sigma_v_array,"sigma_v_%s",ADaPS_DEFAULT,species_name); break; } } SID_log("Done.",SID_LOG_CLOSE); // Read each file in turn pcounter_info pcounter; size_t n_particles_read=0; SID_log("Performing read...",SID_LOG_OPEN|SID_LOG_TIMER); SID_init_pcounter(&pcounter,n_particles_total,10); for(i_file=0;i_file<n_files;i_file++){ set_smooth_filename(filename_root_in,snapshot_number,i_file,flag_multifile,flag_file_type,filename); if((fp=fopen(filename,"r"))!=NULL){ fread_verify(&(header.n_particles_file), sizeof(int), 1,fp); fread_verify(&(header.offset), sizeof(int), 1,fp); fread_verify(&(header.n_particles_total),sizeof(long long),1,fp); fread_verify(&(header.n_files), sizeof(int), 1,fp); } else SID_trap_error("Could not open smooth file {%s}",ERROR_IO_OPEN,filename); n_particles_file =header.n_particles_file; offset =header.offset; n_particles_total=header.n_particles_total; n_files =MAX(1,header.n_files); SID_Bcast(&n_particles_file, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&offset, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&n_particles_total,(int)sizeof(long long),read_rank,SID.COMM_WORLD); SID_Bcast(&n_files, (int)sizeof(int), read_rank,SID.COMM_WORLD); // Read IDs if(flag_LONGIDs){ if(i_file==0) SID_log("(long long) IDs...",SID_LOG_CONTINUE); id_buf =SID_malloc(sizeof(long long)*n_particles_file); id_buf_L=(long long *)id_buf; if(SID.My_rank==read_rank){ fseeko(fp,(size_t)(3*n_particles_file*sizeof(float)),SEEK_CUR); fread_verify(id_buf,sizeof(long long),n_particles_file,fp); } SID_Barrier(SID.COMM_WORLD); SID_Bcast(id_buf_L,(int)(n_particles_file*sizeof(long long)),read_rank,SID.COMM_WORLD); merge_sort(id_buf_L,(size_t)n_particles_file,&id_buf_index,SID_SIZE_T,SORT_COMPUTE_INDEX,FALSE); } else{ if(i_file==0) SID_log("(int) IDs...",SID_LOG_CONTINUE); id_buf =SID_malloc(sizeof(int)*n_particles_file); id_buf_i=(int *)id_buf; if(SID.My_rank==read_rank){ fseeko(fp,(size_t)(3*n_particles_file*sizeof(float)),SEEK_CUR); fread_verify(id_buf,sizeof(int),n_particles_file,fp); } SID_Barrier(SID.COMM_WORLD); SID_Bcast(id_buf_i,(int)(n_particles_file*sizeof(int)),read_rank,SID.COMM_WORLD); merge_sort(id_buf_i,(size_t)n_particles_file,&id_buf_index,SID_INT,SORT_COMPUTE_INDEX,FALSE); } // Create local particle mapping int n_mark_i=0; mark=(long long *)SID_malloc(sizeof(long long)*n_particles_file); for(i_particle=0;i_particle<n_particles_file;i_particle++) mark[i_particle]=-1; if(flag_LONGIDs){ for(i_particle=0,j_particle=0,n_mark=0;i_particle<n_particles_file && j_particle<n_particles_local;i_particle++){ while(j_particle<n_particles_local-1 && ids[ids_index[j_particle]]<id_buf_L[id_buf_index[i_particle]]) j_particle++; if(ids[ids_index[j_particle]]==id_buf_L[id_buf_index[i_particle]]){ mark[id_buf_index[i_particle]]=(long long)ids_index[j_particle]; n_mark++; n_mark_i++; } } } else{ for(i_particle=0,j_particle=0,n_mark=0;i_particle<n_particles_file && j_particle<n_particles_local;i_particle++){ while(j_particle<n_particles_local-1 && ids[ids_index[j_particle]]<id_buf_i[id_buf_index[i_particle]]) j_particle++; if(ids[ids_index[j_particle]]==id_buf_i[id_buf_index[i_particle]]){ mark[id_buf_index[i_particle]]=(long long)ids_index[j_particle]; n_mark++; n_mark_i++; } } } SID_free(SID_FARG id_buf); SID_free(SID_FARG id_buf_index); // Move to the start of the particle quantities if(SID.My_rank==read_rank){ rewind(fp); fread_verify(&n_particles_file, sizeof(int), 1,fp); fread_verify(&offset, sizeof(int), 1,fp); fread_verify(&n_particles_total,sizeof(long long),1,fp); fread_verify(&n_files, sizeof(int), 1,fp); n_files=MAX(1,n_files); } SID_Bcast(&n_particles_file, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&offset, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&n_particles_total,(int)sizeof(long long),read_rank,SID.COMM_WORLD); SID_Bcast(&n_files, (int)sizeof(int), read_rank,SID.COMM_WORLD); buffer=SID_malloc(sizeof(float)*n_particles_file); for(i_quantity=0;i_quantity<n_quantities;i_quantity++){ int flag_log_quantity; switch(i_quantity){ case 0: sprintf(var_name,"r_smooth_%s",species_name); sprintf(unit_name,"Mpc"); unit_factor=plist->length_unit/h_Hubble; local_array=r_smooth_array; break; case 1: sprintf(var_name,"rho_%s",species_name); sprintf(unit_name,"Msol/Mpc^3"); unit_factor=h_Hubble*h_Hubble*plist->mass_unit/pow(plist->length_unit,3.); local_array=rho_array; break; case 2: sprintf(var_name,"sigma_v_%s",species_name); sprintf(unit_name,"km/s"); unit_factor=sqrt(expansion_factor)*plist->velocity_unit; local_array=sigma_v_array; break; } // Read next quantity if(SID.My_rank==read_rank) fread_verify(buffer,sizeof(float),n_particles_file,fp); SID_Barrier(SID.COMM_WORLD); SID_Bcast(buffer,(int)(n_particles_file*sizeof(float)),read_rank,SID.COMM_WORLD); // Place in final array if(n_mark_i>0){ if(i_quantity==0){ for(i_particle=0;i_particle<n_particles_file;i_particle++) if(mark[i_particle]>=0) read_array[mark[i_particle]]=TRUE; } for(i_particle=0;i_particle<n_particles_file;i_particle++) if(mark[i_particle]>=0) local_array[mark[i_particle]]=((float *)buffer)[i_particle]*unit_factor; } } SID_free(SID_FARG mark); SID_free(SID_FARG buffer); if(SID.My_rank==read_rank) fclose(fp); n_particles_read+=n_particles_file; if(n_files>1) SID_check_pcounter(&pcounter,n_particles_read); } // i_file SID_free(SID_FARG ids_index); SID_Barrier(SID.COMM_WORLD); SID_log("Done.",SID_LOG_CLOSE); // Check that all particles have been treated size_t sum_check=0; for(i_particle=0;i_particle<n_particles_local;i_particle++) sum_check+=(size_t)read_array[i_particle]; SID_Allreduce(SID_IN_PLACE,&sum_check,1,SID_SIZE_T,SID_SUM,SID.COMM_WORLD); if(sum_check!=n_particles_all_mem) SID_trap_error("Only %lld of %lld particles were set.",ERROR_LOGIC,sum_check,n_particles_all_mem); SID_free(SID_FARG read_array); SID_log("Summary...",SID_LOG_OPEN); for(i_quantity=0;i_quantity<n_quantities;i_quantity++){ char var_name[32]; switch(i_quantity){ case 0: sprintf(var_name,"Lengths: "); sprintf(unit_name,"Mpc"); unit_factor=1./M_PER_MPC; local_array=r_smooth_array; break; case 1: sprintf(var_name,"Densities: "); sprintf(unit_name,"Msol/Mpc^3"); unit_factor=M_PER_MPC*M_PER_MPC*M_PER_MPC/M_SOL; local_array=rho_array; break; case 2: sprintf(var_name,"sigmas_v's:"); sprintf(unit_name,"km/s"); unit_factor=1e-3; local_array=sigma_v_array; break; } // Report some stats float var_min,var_max,var_mean; calc_min_global(local_array, &var_min, n_particles_local, SID_FLOAT, CALC_MODE_DEFAULT, SID.COMM_WORLD); calc_max_global(local_array, &var_max, n_particles_local, SID_FLOAT, CALC_MODE_DEFAULT, SID.COMM_WORLD); calc_mean_global(local_array, &var_mean, n_particles_local, SID_FLOAT, CALC_MODE_DEFAULT, SID.COMM_WORLD); // Remove NaN's from sigma_v's if needed size_t n_NaN=0; for(i_particle=0;i_particle<n_particles_local;i_particle++){ if(isnan(local_array[i_particle])){ local_array[i_particle]=1000.*0.5*(var_min+var_max); n_NaN++; } } if(n_NaN>0) SID_log("%s min=%e max=%e mean=%e [%s] (%lld are NaN)", SID_LOG_COMMENT, var_name, var_min*unit_factor, var_max*unit_factor, var_mean*unit_factor, unit_name, n_NaN); else SID_log("%s min=%e max=%e mean=%e [%s]", SID_LOG_COMMENT, var_name, var_min*unit_factor, var_max*unit_factor, var_mean*unit_factor, unit_name); } SID_log("",SID_LOG_CLOSE|SID_LOG_NOPRINT); if(flag_logs_used){ SID_log("Taking needed logs of quantities...",SID_LOG_OPEN|SID_LOG_TIMER); for(i_quantity=0;i_quantity<n_quantities;i_quantity++){ switch(i_quantity){ case 0: unit_factor=1./M_PER_MPC; local_array=r_smooth_array; flag_log_quantity=FALSE; break; case 1: unit_factor=M_PER_MPC*M_PER_MPC*M_PER_MPC/M_SOL; local_array=rho_array; flag_log_quantity=flag_log_rho; break; case 2: unit_factor=1e-3; local_array=sigma_v_array; flag_log_quantity=flag_log_sigma; break; } if(flag_log_quantity){ for(i_particle=0;i_particle<n_particles_local;i_particle++) local_array[i_particle]=take_log10(local_array[i_particle]); } } SID_log("Done.",SID_LOG_CLOSE); } SID_Barrier(SID.COMM_WORLD); SID_log("Done.",SID_LOG_CLOSE); } else SID_trap_error("Could not find file with root {%s}",ERROR_IO_OPEN,filename_root_in); }
int 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(); }