Example #1
0
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);
}
Example #2
0
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));
}
Example #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);
}
Example #4
0
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;
  }
}
Example #5
0
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));
}
Example #6
0
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));
}
Example #7
0
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();
}
Example #8
0
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);
}
Example #10
0
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);
}
Example #11
0
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);
}
Example #12
0
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();
}
Example #13
0
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);
}
Example #14
0
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);
}
Example #15
0
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);
}
Example #16
0
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);
}
Example #18
0
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);
}
Example #19
0
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 *)(&params);
   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);
}
Example #20
0
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);
}
Example #21
0
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);
}
Example #22
0
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);
}
Example #23
0
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,
                        &params,
                        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,
                        &params,
                        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();
}
Example #24
0
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);
}
Example #25
0
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);
}
Example #26
0
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));
      }
    }
  }

};
Example #27
0
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();
}
Example #28
0
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);
}
Example #29
0
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);
}