Example #1
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 #2
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 #3
0
void init_cfunc(cfunc_info *cfunc,const char *filename_cosmology,int    n_data,  int    n_random,int    n_bits_PHK,
                double redshift,  double box_size,int    n_jack,
                double r_min_l1D, double r_max_1D,double dr_1D,
                double r_min_2D,  double r_max_2D,double dr_2D){
  SID_log("Initializing correlation function...",SID_LOG_OPEN);

  // Initialize flags
  cfunc->initialized    =TRUE;
  cfunc->flag_compute_RR=TRUE;

  // Initialize constants
  cfunc->n_data    =n_data;
  cfunc->n_random  =n_random;
  cfunc->F_random  =(double)n_random/(double)n_data;
  cfunc->redshift  =redshift;
  cfunc->box_size  =box_size;
  cfunc->n_jack    =n_jack;
  cfunc->r_min_l1D =r_min_l1D;
  cfunc->lr_min_l1D=take_log10(r_min_l1D);
  cfunc->r_max_1D  =r_max_1D;
  cfunc->r_min_2D  =r_min_2D;
  cfunc->r_max_2D  =r_max_2D;
  cfunc->r_max     =MAX(cfunc->r_max_1D,cfunc->r_max_2D);
  cfunc->dr_1D     =dr_1D;
  cfunc->dr_2D     =dr_2D;

  // Decide on PHK boundary widths
  cfunc->n_bits_PHK=n_bits_PHK;
  for(cfunc->PHK_width=1;cfunc->PHK_width<20 && (double)cfunc->PHK_width*(cfunc->box_size/pow(2.,(double)(cfunc->n_bits_PHK)))<cfunc->r_max;) 
     cfunc->PHK_width++;

  // Initialize the number of bins
  cfunc->n_1D        =(int)(0.5+(cfunc->r_max_1D)/cfunc->dr_1D);
  cfunc->n_2D        =(int)(0.5+(cfunc->r_max_2D-cfunc->r_min_2D)/cfunc->dr_2D);
  cfunc->n_2D_total  =cfunc->n_2D*cfunc->n_2D;
  cfunc->n_jack_total=cfunc->n_jack*cfunc->n_jack*cfunc->n_jack;
  SID_log("keys        =%d-bit", SID_LOG_COMMENT,cfunc->n_bits_PHK);
  SID_log("boundries   =%d keys",SID_LOG_COMMENT,cfunc->PHK_width);
  SID_log("# of 1D bins=%d",     SID_LOG_COMMENT,cfunc->n_1D);
  SID_log("# of 2D bins=%d",     SID_LOG_COMMENT,cfunc->n_2D);

  // Initialize logarythmic bin sizes
  cfunc->dr_l1D=(take_log10(cfunc->r_max_1D)-cfunc->lr_min_l1D)/(double)cfunc->n_1D;

  // Initialize arrays
  cfunc->CFUNC_l1D =(double **)SID_malloc(sizeof(double *)*4);
  cfunc->dCFUNC_l1D=(double **)SID_malloc(sizeof(double *)*4);
  cfunc->COVMTX_l1D=(double **)SID_malloc(sizeof(double *)*4);
  cfunc->CFUNC_1D  =(double **)SID_malloc(sizeof(double *)*4);
  cfunc->dCFUNC_1D =(double **)SID_malloc(sizeof(double *)*4);
  cfunc->COVMTX_1D =(double **)SID_malloc(sizeof(double *)*4);
  cfunc->CFUNC_2D  =(double **)SID_malloc(sizeof(double *)*4);
  cfunc->dCFUNC_2D =(double **)SID_malloc(sizeof(double *)*4);
  cfunc->COVMTX_2D =(double **)SID_malloc(sizeof(double *)*4);
  int i_run;
  for(i_run=0;i_run<4;i_run++){
     cfunc->CFUNC_l1D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_1D));
     cfunc->dCFUNC_l1D[i_run]=(double *)SID_malloc(sizeof(double)*(cfunc->n_1D));
     cfunc->COVMTX_l1D[i_run]=(double *)SID_malloc(sizeof(double)*(cfunc->n_1D*cfunc->n_1D));
     cfunc->CFUNC_1D[i_run]  =(double *)SID_malloc(sizeof(double)*(cfunc->n_1D));
     cfunc->dCFUNC_1D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_1D));
     cfunc->COVMTX_1D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_1D*cfunc->n_1D));
     cfunc->CFUNC_2D[i_run]  =(double *)SID_malloc(sizeof(double)*(cfunc->n_2D)*(cfunc->n_2D));
     cfunc->dCFUNC_2D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_2D)*(cfunc->n_2D));
     cfunc->COVMTX_2D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_2D_total*cfunc->n_2D_total));
  }

  cfunc->DD_l1D    =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1));
  cfunc->DR_l1D    =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1));
  cfunc->RR_l1D    =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1));
  cfunc->DD_1D     =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1));
  cfunc->DR_1D     =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1));
  cfunc->RR_1D     =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1));
  cfunc->DD_2D     =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1));
  cfunc->DR_2D     =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1));
  cfunc->RR_2D     =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1));
  int i_jack;
  for(i_jack=0;i_jack<=cfunc->n_jack_total;i_jack++){
    cfunc->DD_l1D[i_jack]=(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D);
    cfunc->DR_l1D[i_jack]=(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D);
    cfunc->RR_l1D[i_jack]=(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D);
    cfunc->DD_1D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D);
    cfunc->DR_1D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D);
    cfunc->RR_1D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D);
    cfunc->DD_2D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_2D*cfunc->n_2D);
    cfunc->DR_2D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_2D*cfunc->n_2D);
    cfunc->RR_2D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_2D*cfunc->n_2D);
  }

  // Initialize the cosmology
  if(filename_cosmology==NULL)
     init_cosmo_default(&(cfunc->cosmo));
  else
     read_gbpCosmo_file(&(cfunc->cosmo),filename_cosmology);

  SID_log("Done.",SID_LOG_CLOSE);
}
Example #4
0
void average_tree_branches(const char *catalog_name){
  SID_log("Processing tree tracks in catalog {%s}...",SID_LOG_OPEN,catalog_name);

  // Master Rank does all the work
  FILE *fp_tracks_in=NULL;
  if(SID.I_am_Master){
     // Create and open the output files
     char   filename_tracks_in[MAX_FILENAME_LENGTH];
     sprintf(filename_tracks_in,"%s_tracks.dat",catalog_name);
     SID_log("Processing {%s}...",SID_LOG_OPEN,filename_tracks_in);
     fp_tracks_in=fopen(filename_tracks_in,"r");

     // Write header for tracks file
     int n_list;
     int n_snaps;
     fread_verify(&n_list, sizeof(int),1,fp_tracks_in);
     fread_verify(&n_snaps,sizeof(int),1,fp_tracks_in);
     int    *snap_list=(int    *)SID_malloc(sizeof(int)   *n_snaps);
     double *z_list   =(double *)SID_malloc(sizeof(double)*n_snaps);
     double *t_list   =(double *)SID_malloc(sizeof(double)*n_snaps);
     fread_verify(snap_list,sizeof(int),   n_snaps,fp_tracks_in);
     fread_verify(z_list,   sizeof(double),n_snaps,fp_tracks_in);
     fread_verify(t_list,   sizeof(double),n_snaps,fp_tracks_in);

     // Allocate some temporary arrays for the tracks
     double   M_min   = 6.;
     double   M_max   =16.;
     int      n_M_bins=200;
     double   dM      =(M_max-M_min)/(double)n_M_bins;
     double   inv_dM  =1./dM;
     int    **M_hist  =(int **)SID_malloc(sizeof(int *)*n_snaps);
     for(int i_snap=0;i_snap<n_snaps;i_snap++)
        M_hist[i_snap]=(int *)SID_calloc(sizeof(int)*n_M_bins);
     int    *i_z_track=(int    *)SID_malloc(sizeof(int)*n_snaps);;
     int    *idx_track=(int    *)SID_malloc(sizeof(int)*n_snaps);;
     double *M_track  =(double *)SID_malloc(sizeof(double)*n_snaps);
     double *x_track  =(double *)SID_malloc(sizeof(double)*n_snaps);
     double *y_track  =(double *)SID_malloc(sizeof(double)*n_snaps);
     double *z_track  =(double *)SID_malloc(sizeof(double)*n_snaps);
     double *vx_track =(double *)SID_malloc(sizeof(double)*n_snaps);
     double *vy_track =(double *)SID_malloc(sizeof(double)*n_snaps);
     double *vz_track =(double *)SID_malloc(sizeof(double)*n_snaps);

     // Process each track in turn
     for(int i_list=0;i_list<n_list;i_list++){
        int n_track;
        // Read track
        fread_verify(&n_track, sizeof(int),   1,      fp_tracks_in);
        fread_verify(i_z_track,sizeof(int),   n_track,fp_tracks_in);
        fread_verify(idx_track,sizeof(int),   n_track,fp_tracks_in);
        fread_verify(x_track,  sizeof(double),n_track,fp_tracks_in);
        fread_verify(y_track,  sizeof(double),n_track,fp_tracks_in);
        fread_verify(z_track,  sizeof(double),n_track,fp_tracks_in);
        fread_verify(vx_track, sizeof(double),n_track,fp_tracks_in);
        fread_verify(vy_track, sizeof(double),n_track,fp_tracks_in);
        fread_verify(vz_track, sizeof(double),n_track,fp_tracks_in);
        fread_verify(M_track,  sizeof(double),n_track,fp_tracks_in);
        // Build the M-histograms
        for(int i_track=0;i_track<n_track;i_track++){
           int i_bin=(int)((take_log10(M_track[i_track])-M_min)*inv_dM);
           if(i_bin>=0 && i_bin<n_M_bins)
              M_hist[i_z_track[i_track]][i_bin]++;
        }
     } // for i_list
     fclose(fp_tracks_in);

     // Build confidence intervals for M-track
     int    *n_i    =(int    *)SID_calloc(sizeof(int)*n_snaps);
     double *M_peak =(double *)SID_calloc(sizeof(double)*n_snaps);
     double *M_68_lo=(double *)SID_calloc(sizeof(double)*n_snaps);
     double *M_68_hi=(double *)SID_calloc(sizeof(double)*n_snaps);
     for(int i_snap=0;i_snap<n_snaps;i_snap++){
        size_t *M_hist_index=NULL;
        for(int i_bin=0;i_bin<n_M_bins;i_bin++)
           n_i[i_snap]+=M_hist[i_snap][i_bin];
        if(n_i[i_snap]>0){
           merge_sort(M_hist[i_snap],(size_t)n_M_bins,&M_hist_index,SID_INT,SORT_COMPUTE_INDEX,FALSE);
           int i_peak =M_hist_index[n_M_bins-1];
           int i_68_lo=M_hist_index[n_M_bins-1];
           int i_68_hi=M_hist_index[n_M_bins-1];
           int target =(int)(0.68*(double)n_i[i_snap]);
           int accum  =0;
           int i_bin  =0;
           while(accum<=target && i_bin<n_M_bins){
              size_t idx_i=M_hist_index[n_M_bins-i_bin-1];
              if(idx_i<i_68_lo) i_68_lo=idx_i;
              if(idx_i>i_68_hi) i_68_hi=idx_i;
              accum+=M_hist[i_snap][idx_i];
              i_bin++;
           }
           M_peak[i_snap] =M_min+((double)i_peak +0.5)*dM;
           M_68_lo[i_snap]=M_min+((double)i_68_lo+0.5)*dM;
           M_68_hi[i_snap]=M_min+((double)i_68_hi+0.5)*dM;
           SID_free(SID_FARG M_hist_index);
        }
        else{
           M_peak[i_snap] =-1;
           M_68_lo[i_snap]=-1;
           M_68_hi[i_snap]=-1;
        }
     }

     // Write results
     char  filename_out[MAX_FILENAME_LENGTH];
     FILE *fp_out;
     sprintf(filename_out,"%s_tracks.txt",catalog_name);
     fp_out=fopen(filename_out,"w");
     for(int i_snap=0;i_snap<n_snaps;i_snap++)
        fprintf(fp_out,"%le %le %d %le %le %le\n",
                       z_list[i_snap],
                       t_list[i_snap]/S_PER_YEAR,
                       n_i[i_snap],
                       M_peak[i_snap],
                       M_68_lo[i_snap],
                       M_68_hi[i_snap]);
     fclose(fp_out);

     // Clean-up
     for(int i_snap=0;i_snap<n_snaps;i_snap++)
        SID_free(SID_FARG M_hist[i_snap]);
     SID_free(SID_FARG M_hist);
     SID_free(SID_FARG n_i);
     SID_free(SID_FARG M_peak);
     SID_free(SID_FARG M_68_lo);
     SID_free(SID_FARG M_68_hi);
     SID_free(SID_FARG i_z_track);
     SID_free(SID_FARG idx_track);
     SID_free(SID_FARG M_track);
     SID_free(SID_FARG x_track);
     SID_free(SID_FARG y_track);
     SID_free(SID_FARG z_track);
     SID_free(SID_FARG vx_track);
     SID_free(SID_FARG vy_track);
     SID_free(SID_FARG vz_track);
     SID_free(SID_FARG snap_list);
     SID_free(SID_FARG z_list);
     SID_free(SID_FARG t_list);
     SID_log("Done.",SID_LOG_CLOSE);
  } // if I_am_Master
  SID_Barrier(SID.COMM_WORLD);

  SID_log("Done.",SID_LOG_CLOSE);
}
int calc_tree_property_index_logM(trend_property_info *property, hist_info *hist, void *halo_in) {
    tree_info *     trees = (tree_info *)(property->params);
    tree_node_info *halo  = (tree_node_info *)(halo_in);
    return (calc_histogram_index(hist, take_log10(fetch_treenode_M_vir(trees, halo))));
}
void compute_treenode_list_marker_stats(tree_info *trees,treenode_list_info *list,tree_markers_info **markers_all,tree_markers_stats_info *stats,int **n_hist_count,int *n_hist){

   int n_stats=3;
   int n_M    =2;
   (*n_hist)  =n_stats+n_M;

   // Allocate histogram arrays -- stats
   int   i_hist=0;
   int **hist  =(int **)SID_calloc(sizeof(int *)*(*n_hist));
   int  *n_bins=(int  *)SID_calloc(sizeof(int)*(*n_hist));
   for(int i_stat=0;i_stat<n_stats;i_stat++){
      n_bins[i_hist]=trees->n_snaps;
      hist[i_hist++]=(int *)SID_calloc(sizeof(int)*n_bins[i_hist]);
   }

   // Allocate histogram arrays -- mass
   double logM_min=7.;
   int    n_M_bins=90;
   double dlogM   =0.1;
   for(int i_M=0;i_M<n_M;i_M++){
      n_bins[i_hist]=n_M_bins;
      hist[i_hist++]=(int *)SID_calloc(sizeof(int)*n_bins[i_hist]);
   }

   // Allocate histogram counts
   if((*n_hist_count)==NULL)
      (*n_hist_count)=(int *)SID_calloc(sizeof(int)*(*n_hist));
   else{
      for(i_hist=0;i_hist<(*n_hist);i_hist++)
         (*n_hist_count)[i_hist]=0;
   }

   // Work with a precompiled markers array if it's been given
   tree_markers_info *markers;
   if(markers_all==NULL)
      markers=(tree_markers_info *)SID_malloc(sizeof(tree_markers_info));

   // Create histograms
   for(int i_list=0;i_list<list->n_list_local;i_list++){
      markers=fetch_treenode_precomputed_markers(trees,list->list[i_list]);
      // Build histogram
      int i_bin;
      for(int i_hist=0;i_hist<(*n_hist);i_hist++){
         i_bin=-1;
         if(i_hist<n_stats){
            tree_node_info *marker=NULL;
            if(i_hist==0)
               marker=markers->half_peak_mass;
            else if(i_hist==1)
               marker=markers->merger_33pc_remnant;
            else if(i_hist==2)
               marker=markers->merger_10pc_remnant;
            else
               SID_trap_error("Behaviour undefined in compute_treenode_list_marker_stats()",ERROR_LOGIC);
            if(marker!=NULL)
               i_bin=marker->snap_tree;
            else
               i_bin=-1;
         }
         else{
            if(i_hist==(n_stats+0)){
               halo_properties_info *properties=fetch_treenode_properties(trees,list->list[i_list]);
               i_bin=(take_log10(properties->M_vir)-logM_min)/dlogM;
            }
            else if(i_hist==(n_stats+1))
               i_bin=(take_log10(markers->M_peak)-logM_min)/dlogM;
            else
               SID_trap_error("Behaviour undefined in compute_treenode_list_marker_stats()",ERROR_LOGIC);
         }
         if(i_bin>=0 && i_bin<n_bins[i_hist]){
            hist[i_hist][i_bin]++;
            (*n_hist_count)[i_hist]++;
         }
      }
   }
   if(markers_all==NULL)
      SID_free(SID_FARG markers);
   for(int i_hist=0;i_hist<(*n_hist);i_hist++){
      SID_Allreduce(SID_IN_PLACE,hist[i_hist],n_bins[i_hist],SID_INT,SID_SUM,SID.COMM_WORLD);
      SID_Allreduce(SID_IN_PLACE,&((*n_hist_count)[i_hist]),1,SID_INT,SID_SUM,SID.COMM_WORLD);
   }

   // Find 68 and 95 percent confidence ranges
   for(int i_hist=0;i_hist<(*n_hist);i_hist++){
      int sum=0;
      for(int i_bin=0;i_bin<n_bins[i_hist];i_bin++)
         sum+=hist[i_hist][i_bin];
      size_t *hist_index=NULL;
      merge_sort(hist[i_hist],(size_t)(n_bins[i_hist]),&hist_index,SID_INT,SORT_COMPUTE_INDEX,FALSE);
      int i_peak =hist_index[n_bins[i_hist]-1];
      int i_68_lo=hist_index[n_bins[i_hist]-1];
      int i_68_hi=hist_index[n_bins[i_hist]-1];
      int target =(int)(0.68*(double)sum);
      int accum  =0;
      int i_bin  =0;
      while(accum<=target && i_bin<n_bins[i_hist]){
         size_t idx_i=hist_index[n_bins[i_hist]-i_bin-1];
         if(idx_i<i_68_lo) i_68_lo=idx_i;
         if(idx_i>i_68_hi) i_68_hi=idx_i;
         accum+=hist[i_hist][idx_i];
         i_bin++;
      }
      int i_95_lo=i_68_lo;
      int i_95_hi=i_68_hi;
      target=(int)(0.95*(double)sum);
      while(accum<=target && i_bin<n_bins[i_hist]){
         size_t idx_i=hist_index[n_bins[i_hist]-i_bin-1];
         if(idx_i<i_95_lo) i_95_lo=idx_i;
         if(idx_i>i_95_hi) i_95_hi=idx_i;
         accum+=hist[i_hist][idx_i];
         i_bin++;
      }
      SID_free(SID_FARG hist_index);

      if(i_hist==0){
         stats->t_half_peak_mass_ranges[0][0]=trees->t_list[i_68_lo];
         stats->t_half_peak_mass_ranges[0][1]=trees->t_list[i_68_hi];
         stats->t_half_peak_mass_ranges[1][0]=trees->t_list[i_95_lo];
         stats->t_half_peak_mass_ranges[1][1]=trees->t_list[i_95_hi];
         stats->t_half_peak_mass_peak        =trees->t_list[i_peak];
      }
      else if(i_hist==1){
         stats->t_merger_33pc_ranges[0][0]=trees->t_list[i_68_lo];
         stats->t_merger_33pc_ranges[0][1]=trees->t_list[i_68_hi];
         stats->t_merger_33pc_ranges[1][0]=trees->t_list[i_95_lo];
         stats->t_merger_33pc_ranges[1][1]=trees->t_list[i_95_hi];
         stats->t_merger_33pc_peak        =trees->t_list[i_peak];
      }
      else if(i_hist==2){
         stats->t_merger_10pc_ranges[0][0]=trees->t_list[i_68_lo];
         stats->t_merger_10pc_ranges[0][1]=trees->t_list[i_68_hi];
         stats->t_merger_10pc_ranges[1][0]=trees->t_list[i_95_lo];
         stats->t_merger_10pc_ranges[1][1]=trees->t_list[i_95_hi];
         stats->t_merger_10pc_peak        =trees->t_list[i_peak];
      }
      else if(i_hist==3){
         stats->M_peak_ranges[0][0]=logM_min+(double)(i_68_lo)*dlogM;
         stats->M_peak_ranges[0][1]=logM_min+(double)(i_68_hi)*dlogM;
         stats->M_peak_ranges[1][0]=logM_min+(double)(i_95_lo)*dlogM;
         stats->M_peak_ranges[1][1]=logM_min+(double)(i_95_hi)*dlogM;
         stats->M_peak_peak        =logM_min+(double)( i_peak)*dlogM;
      }
      else if(i_hist==4){
         stats->M_vir_ranges[0][0]=logM_min+(double)(i_68_lo)*dlogM;
         stats->M_vir_ranges[0][1]=logM_min+(double)(i_68_hi)*dlogM;
         stats->M_vir_ranges[1][0]=logM_min+(double)(i_95_lo)*dlogM;
         stats->M_vir_ranges[1][1]=logM_min+(double)(i_95_hi)*dlogM;
         stats->M_vir_peak        =logM_min+(double)( i_peak)*dlogM;
      }
      else
         SID_trap_error("Behaviour undefined in compute_treenode_list_marker_stats()",ERROR_LOGIC);
   }

   // Clean-up
   for(int i_hist=0;i_hist<(*n_hist);i_hist++)
      SID_free(SID_FARG hist[i_hist]);
   SID_free(SID_FARG hist);
   SID_free(SID_FARG n_bins);

}
Example #7
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);
}
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 #9
0
void process_local(tree_info *           trees,
                   int                   i_pass,
                   char *                filename_out_root,
                   double                radius2,
                   double                M_min,
                   int                   i_snap,
                   int                   i_halo,
                   int                   j_subgroup,
                   int                   i_group,
                   int                   halo_id,
                   int                   halo_file_offset,
                   int                   halo_type,
                   int                   halo_n_particles_peak,
                   int                   halo_tree_id,
                   int                   halo_index,
                   int                   halo_descendant_id,
                   int                   bridge_forematch_first_index,
                   int                   bridge_forematch_first_file,
                   int                   bridge_backmatch_index,
                   int                   bridge_backmatch_file,
                   int                   group_id,
                   halo_properties_info *properties,
                   halo_properties_info *properties_group,
                   int *                 n_list,
                   int *                 halo_list,
                   double                x_cen,
                   double                y_cen,
                   double                z_cen) {
    int flag_found = GBP_FALSE;
    int i_type     = !(properties_group == NULL);
    // Perform search
    if(i_pass < 2) {
        double dx_i = d_periodic(((double)properties->position_MBP[0] - x_cen), trees->box_size);
        double dy_i = d_periodic(((double)properties->position_MBP[1] - y_cen), trees->box_size);
        double dz_i = d_periodic(((double)properties->position_MBP[2] - z_cen), trees->box_size);
        double r2_i = dx_i * dx_i + dy_i * dy_i + dz_i * dz_i;
        if(r2_i < radius2 && properties->M_vir >= M_min) {
            flag_found = GBP_TRUE;
            if(i_pass == 0)
                (*n_list)++;
            else {
                // Check if we have added this halo ID yet
                for(int i_scan = 0; i_scan < (*n_list) && flag_found; i_scan++) {
                    if(halo_list[i_scan] == halo_id)
                        flag_found = GBP_FALSE;
                }
                // Add halo ID if it isn't in the list
                if(flag_found)
                    halo_list[(*n_list)++] = halo_id;
            }
        }
    }
    // Perform write
    else if(i_pass == 2) {
        int flag_keep = GBP_FALSE;
        for(int j_list = 0; j_list < (*n_list) && !flag_keep; j_list++)
            if(halo_id == halo_list[j_list])
                flag_keep = GBP_TRUE;
        if(flag_keep) {
            char filename_out[SID_MAX_FILENAME_LENGTH];
            if(i_type == 0)
                sprintf(filename_out, "%s_group_%09d.txt", filename_out_root, halo_id);
            else
                sprintf(filename_out, "%s_subgroup_%09d.txt", filename_out_root, halo_id);
            FILE *fp_out                      = fopen(filename_out, "a");
            int   descendant_snap             = -1;
            int   bridge_forematch_first_snap = -1;
            int   bridge_backmatch_snap       = -1;
            if(halo_file_offset > 0)
                descendant_snap = trees->snap_list[i_snap + halo_file_offset];
            if(bridge_forematch_first_file >= 0)
                bridge_forematch_first_snap = trees->snap_list[bridge_forematch_first_file];
            if(bridge_backmatch_file >= 0)
                bridge_backmatch_snap = trees->snap_list[bridge_backmatch_file];

            char *halo_type_string = NULL;
            tree_case_flags_text(halo_type, "+", &halo_type_string);
            fprintf(fp_out,
                    "%le %7.3lf %3d %7d %7d %5.2lf %6d %6d %10.3le %10.3le %10.3le %10.3le %7d %2d %3d %7d %7d %3d %7d %3d %7d %7d %s",
                    trees->a_list[i_snap],
                    trees->z_list[i_snap],
                    trees->snap_list[i_snap],
                    i_halo,
                    halo_id,
                    take_log10(properties->M_vir),
                    properties->n_particles,
                    halo_n_particles_peak,
                    properties->position_MBP[0],
                    properties->position_MBP[1],
                    properties->position_MBP[2],
                    properties->R_vir,
                    halo_tree_id,
                    halo_file_offset,
                    descendant_snap,
                    halo_index,
                    halo_descendant_id,
                    bridge_forematch_first_snap,
                    bridge_forematch_first_index,
                    bridge_backmatch_snap,
                    bridge_backmatch_index,
                    halo_type,
                    halo_type_string);
            SID_free(SID_FARG halo_type_string);
            if(i_type == 1)
                fprintf(fp_out,
                        " %7d %5d %7d %10.3le %10.3le %10.3le\n",
                        i_group,
                        group_id,
                        j_subgroup,
                        properties->position_MBP[0] - properties_group->position_MBP[0],
                        properties->position_MBP[1] - properties_group->position_MBP[1],
                        properties->position_MBP[2] - properties_group->position_MBP[2]);
            else
                fprintf(fp_out, "\n");
            // Write subgroup-specific stuff
            if(i_type == 1) {
            }
            fclose(fp_out);
        }
    }
    // Sanity check
    else
        SID_exit_error("Invalid mode passed to process_local.", SID_ERROR_LOGIC);
}
int calc_halo_trend_property_index_logM_FoF(trend_property_info *property,hist_info *hist,void *halo_in){
   halo_trend_info *halo_trend_data=(halo_trend_info *)(property->params);
   halo_info       *halo           =(halo_info       *)(halo_in);
   return(calc_histogram_index(hist,take_log10(halo->properties_group->n_particles*halo_trend_data->m_p)));
}
Example #11
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 #12
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 #13
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);
}