コード例 #1
0
ファイル: init_field.c プロジェクト: gbpoole/gbpCode
void init_field(int n_d, int *n, double *L, field_info *FFT) {
    ptrdiff_t  n_x_local;
    ptrdiff_t  i_x_start_local;
    ptrdiff_t  n_y_transpose_local;
    ptrdiff_t  i_y_start_transpose_local;
    ptrdiff_t *n_x_rank;

    int  flag_active;
    int  n_active;
    int  min_size, max_size;

    SID_log("Initializing ", SID_LOG_OPEN);
    for(ptrdiff_t i_d = 0; i_d < n_d; i_d++) {
        if(i_d < (n_d - 1))
            SID_log("%dx", SID_LOG_CONTINUE, n[i_d]);
        else
            SID_log("%d element %d-d FFT ", SID_LOG_CONTINUE, n[i_d], n_d);
    }
    SID_log("(%d byte precision)...", SID_LOG_CONTINUE, (int)sizeof(GBPREAL));

    // Initialize FFT sizes
    FFT->n_d             = n_d;
    FFT->n               = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    FFT->L               = (double *)SID_calloc(sizeof(double) * FFT->n_d);
    FFT->n_k_local       = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    FFT->n_R_local       = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    FFT->i_R_start_local = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    FFT->i_k_start_local = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    FFT->i_R_stop_local  = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    FFT->i_k_stop_local  = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) {
        FFT->n[i_d]               = n[i_d];
        FFT->L[i_d]               = L[i_d];
        FFT->i_R_start_local[i_d] = 0;
        FFT->i_k_start_local[i_d] = 0;
        FFT->n_R_local[i_d]       = FFT->n[i_d];
        FFT->n_k_local[i_d]       = FFT->n[i_d];
    }
    FFT->n_k_local[FFT->n_d - 1] = FFT->n[FFT->n_d - 1] / 2 + 1;

    // Initialize FFTW

    // Create an integer version of FFT->n[] to pass to ..._create_plan
    int *n_int=(int *)SID_malloc(sizeof(int)*FFT->n_d);
    for(int i_d=0;i_d<FFT->n_d;i_d++)
        n_int[i_d]=(int)FFT->n[i_d];
#if FFTW_V2
#if USE_MPI
    int total_local_size_int;
    int n_x_local_int;
    int i_x_start_local_int;
    int n_y_transpose_local_int;
    int i_y_start_transpose_local_int;
    FFT->plan  = rfftwnd_mpi_create_plan(SID.COMM_WORLD->comm, FFT->n_d, n_int, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
    FFT->iplan = rfftwnd_mpi_create_plan(SID.COMM_WORLD->comm, FFT->n_d, n_int, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE);
    rfftwnd_mpi_local_sizes(FFT->plan,
                            &(n_x_local_int),
                            &(i_x_start_local_int),
                            &(n_y_transpose_local_int),
                            &(i_y_start_transpose_local_int),
                            &total_local_size_int);
    n_x_local =  (ptrdiff_t)n_x_local_int;
    i_x_start_local = (ptrdiff_t)i_x_start_local_int;
    n_y_transpose_local = (ptrdiff_t)n_y_transpose_local_int;
    i_y_start_transpose_local = (ptrdiff_t)i_y_start_transpose_local_int;
    FFT->total_local_size = (size_t)total_local_size_int;
#else
    FFT->total_local_size = 1;
    for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) {
        if(i_d < FFT->n_d - 1)
            FFT->total_local_size *= FFT->n[i_d];
        else
            FFT->total_local_size *= 2 * (FFT->n[i_d] / 2 + 1);
    }
#if USE_DOUBLE
    FFT->plan  = fftwnd_create_plan(FFT->n_d, n_int, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE | FFTW_IN_PLACE);
    FFT->iplan = fftwnd_create_plan(FFT->n_d, n_int, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE | FFTW_IN_PLACE);
#else
    FFT->plan  = rfftwnd_create_plan(FFT->n_d, n_int, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE | FFTW_IN_PLACE);
    FFT->iplan = rfftwnd_create_plan(FFT->n_d, n_int, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE | FFTW_IN_PLACE);
#endif
#endif
#else
#if USE_MPI
#if USE_DOUBLE
    fftw_mpi_init();
    FFT->total_local_size = fftw_mpi_local_size_many_transposed(FFT->n_d,
                                                                FFT->n,
                                                                1,
                                                                FFTW_MPI_DEFAULT_BLOCK,
                                                                FFTW_MPI_DEFAULT_BLOCK,
                                                                SID_COMM_WORLD->comm,
                                                                &(n_x_local),
                                                                &(i_x_start_local),
                                                                &(n_y_transpose_local),
                                                                &(i_y_start_transpose_local));
    FFT->plan  = fftw_mpi_plan_dft_r2c(FFT->n_d, FFT->n, FFT->field_local, FFT->cfield_local, SID_COMM_WORLD->comm, FFTW_ESTIMATE);
    FFT->iplan = fftw_mpi_plan_dft_c2r(FFT->n_d, FFT->n, FFT->cfield_local, FFT->field_local, SID_COMM_WORLD->comm, FFTW_ESTIMATE);
#else
    fftwf_mpi_init();
    FFT->total_local_size   = fftwf_mpi_local_size_many_transposed(FFT->n_d,
                                                                 FFT->n,
                                                                 1,
                                                                 FFTW_MPI_DEFAULT_BLOCK,
                                                                 FFTW_MPI_DEFAULT_BLOCK,
                                                                 SID_COMM_WORLD->comm,
                                                                 &(n_x_local),
                                                                 &(i_x_start_local),
                                                                 &(n_y_transpose_local),
                                                                 &(i_y_start_transpose_local));
    FFT->plan  = fftwf_mpi_plan_dft_r2c(FFT->n_d, FFT->n, FFT->field_local, FFT->cfield_local, SID_COMM_WORLD->comm, FFTW_ESTIMATE);
    FFT->iplan = fftwf_mpi_plan_dft_c2r(FFT->n_d, FFT->n, FFT->cfield_local, FFT->field_local, SID_COMM_WORLD->comm, FFTW_ESTIMATE);
#endif
#else
    FFT->total_local_size = 1;
    for(ptrdiff_t i_d=0; i_d < FFT->n_d; i_d++) {
        if(i_d < FFT->n_d - 1)
            FFT->total_local_size *= FFT->n[i_d];
        else
            FFT->total_local_size *= 2 * (FFT->n[i_d] / 2 + 1);
    }
#if USE_DOUBLE
    FFT->plan  = fftw_plan_dft_r2c(FFT->n_d, FFT->n, FFT->field_local, FFT->cfield_local, FFTW_ESTIMATE);
    FFT->iplan = fftw_plan_dft_c2r(FFT->n_d, FFT->n, FFT->cfield_local, FFT->field_local, FFTW_ESTIMATE);
#else
    FFT->plan  = fftwf_plan_dft_r2c(FFT->n_d, FFT->n, FFT->field_local, FFT->cfield_local, FFTW_ESTIMATE);
    FFT->iplan = fftwf_plan_dft_c2r(FFT->n_d, FFT->n, FFT->cfield_local, FFT->field_local, FFTW_ESTIMATE);
#endif
#endif
#endif

    SID_free(SID_FARG n_int);


    // Set empty slabs to start at 0 to make ignoring them simple.
    if(n_x_local == 0)
        i_x_start_local = 0;
    if(n_y_transpose_local == 0)
        i_y_start_transpose_local = 0;

    // Modify the local slab dimensions according to what FFTW chose.
    FFT->i_R_start_local[0] = i_x_start_local;
    FFT->n_R_local[0]       = n_x_local;
    if(FFT->n_d > 1) {
        FFT->i_k_start_local[1] = i_y_start_transpose_local;
        FFT->n_k_local[1]       = n_y_transpose_local;
    }

    // Allocate field
#if USE_FFTW3
    FFT->field_local  = (gbpFFT_real    *)fftwf_alloc_real(FFT->total_local_size);
#else
    FFT->field_local  = (gbpFFT_real    *)SID_malloc(sizeof(gbpFFT_real)*FFT->total_local_size);
#endif
    FFT->cfield_local = (gbpFFT_complex *)FFT->field_local;

    // Upper limits of slab decomposition
    for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) {
        FFT->i_R_stop_local[i_d] = FFT->i_R_start_local[i_d] + FFT->n_R_local[i_d] - 1;
        FFT->i_k_stop_local[i_d] = FFT->i_k_start_local[i_d] + FFT->n_k_local[i_d] - 1;
    }

    // FFTW padding sizes
    if(FFT->n_d > 1) {
        FFT->pad_size_R = 2 * (FFT->n_R_local[FFT->n_d - 1] / 2 + 1) - FFT->n_R_local[FFT->n_d - 1];
        FFT->pad_size_k = 0;
    } else {
        FFT->pad_size_R = 0;
        FFT->pad_size_k = 0;
    }

    // Number of elements (global and local) in the FFT
    ptrdiff_t i_d = 0;
    for(FFT->n_field = 1, FFT->n_field_R_local = 1, FFT->n_field_k_local = 1; i_d < FFT->n_d; i_d++) {
        FFT->n_field *= (size_t)FFT->n[i_d];
        FFT->n_field_R_local *= (size_t)FFT->n_R_local[i_d];
        FFT->n_field_k_local *= (size_t)FFT->n_k_local[i_d];
    }

    // Clear the field
    clear_field(FFT);

    // Initialize the FFT's real-space grid
    FFT->R_field = (double **)SID_malloc(sizeof(double *) * FFT->n_d);
    FFT->dR      = (double *)SID_malloc(sizeof(double *) * FFT->n_d);
    for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) {
        FFT->R_field[i_d] = (double *)SID_malloc(sizeof(double) * (FFT->n[i_d] + 1));
        FFT->dR[i_d]      = FFT->L[i_d] / (double)(FFT->n[i_d]);
        for(ptrdiff_t i_i = 0; i_i < FFT->n[i_d]; i_i++)
            FFT->R_field[i_d][i_i] = FFT->L[i_d] * ((double)i_i / (double)(FFT->n[i_d]));
        FFT->R_field[i_d][FFT->n[i_d]] = FFT->L[i_d];
    }

    // Initialize the FFT's k-space grid
    FFT->k_field   = (double **)SID_malloc(sizeof(double *) * FFT->n_d);
    FFT->dk        = (double *)SID_malloc(sizeof(double *) * FFT->n_d);
    FFT->k_Nyquist = (double *)SID_malloc(sizeof(double *) * FFT->n_d);
    for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) {
        FFT->k_field[i_d]   = (double *)SID_malloc(sizeof(double) * FFT->n[i_d]);
        FFT->dk[i_d]        = TWO_PI / FFT->L[i_d];
        FFT->k_Nyquist[i_d] = TWO_PI * (double)(FFT->n[i_d]) / FFT->L[i_d] / 2.;
        for(ptrdiff_t i_i = 0; i_i < FFT->n[i_d]; i_i++) {
            if(i_i >= FFT->n[i_d] / 2)
                FFT->k_field[i_d][i_i] = TWO_PI * (double)(i_i - FFT->n[i_d]) / FFT->L[i_d];
            else
                FFT->k_field[i_d][i_i] = TWO_PI * (double)(i_i) / FFT->L[i_d];
        }
    }

    // Flags
    FFT->flag_padded = GBP_FALSE;

    // Slab info
    FFT->slab.n_x_local       = FFT->n_R_local[0];
    FFT->slab.i_x_start_local = FFT->i_R_start_local[0];
    FFT->slab.i_x_stop_local  = FFT->i_R_stop_local[0];
    FFT->slab.x_min_local     = FFT->R_field[0][FFT->i_R_start_local[0]];
    if(FFT->slab.n_x_local > 0)
        FFT->slab.x_max_local = FFT->R_field[0][FFT->i_R_stop_local[0] + 1];
    else
        FFT->slab.x_max_local = FFT->slab.x_min_local;
    SID_Allreduce(&(FFT->slab.x_max_local), &(FFT->slab.x_max), 1, SID_DOUBLE, SID_MAX, SID_COMM_WORLD);

#if USE_MPI
    // All ranks are not necessarily assigned any slices, so
    //   we need to figure out what ranks are to the right and the left for
    //   buffer exchanges
    n_x_rank              = (ptrdiff_t *)SID_malloc(sizeof(ptrdiff_t) * SID.n_proc);
    n_x_rank[SID.My_rank] = (ptrdiff_t)FFT->slab.n_x_local;
    if(n_x_rank[SID.My_rank] > 0)
        flag_active = GBP_TRUE;
    else
        flag_active = GBP_FALSE;
    SID_Allreduce(&flag_active, &n_active, 1, SID_INT, SID_SUM, SID_COMM_WORLD);
    SID_Allreduce(&n_x_rank[SID.My_rank], &min_size, 1, SID_INT, SID_MIN, SID_COMM_WORLD);
    SID_Allreduce(&n_x_rank[SID.My_rank], &max_size, 1, SID_INT, SID_MAX, SID_COMM_WORLD);
    for(int i_rank = 0; i_rank < SID.n_proc; i_rank++)
        SID_Bcast(&(n_x_rank[i_rank]), 1, SID_INT, i_rank, SID_COMM_WORLD);
    FFT->slab.rank_to_right = -1;
    for(int i_rank = SID.My_rank + 1; i_rank < SID.My_rank + SID.n_proc && FFT->slab.rank_to_right < 0; i_rank++) {
        int j_rank = i_rank % SID.n_proc;
        if(n_x_rank[j_rank] > 0)
            FFT->slab.rank_to_right = j_rank;
    }
    if(FFT->slab.rank_to_right < 0)
        FFT->slab.rank_to_right = SID.My_rank;
    FFT->slab.rank_to_left = -1;
    for(int i_rank = SID.My_rank - 1; i_rank > SID.My_rank - SID.n_proc && FFT->slab.rank_to_left < 0; i_rank--) {
        int j_rank = i_rank;
        if(i_rank < 0)
            j_rank = i_rank + SID.n_proc;
        if(n_x_rank[j_rank] > 0)
            FFT->slab.rank_to_left = j_rank;
    }
    if(FFT->slab.rank_to_left < 0)
        FFT->slab.rank_to_left = SID.My_rank;
    free(n_x_rank);
    SID_log("(%d cores unused, min/max slab size=%d/%d)...", SID_LOG_CONTINUE, SID.n_proc - n_active, min_size, max_size);
#else
    FFT->slab.rank_to_right = SID.My_rank;
    FFT->slab.rank_to_left  = SID.My_rank;
    if(FFT->slab.n_x_local > 0) {
        flag_active = GBP_TRUE;
        n_active    = 1;
        min_size    = FFT->slab.n_x_local;
        max_size    = FFT->slab.n_x_local;
    } else {
        flag_active = GBP_FALSE;
        n_active    = 0;
        min_size    = 0;
        max_size    = 0;
    }
#endif

    SID_log("Done.", SID_LOG_CLOSE);
}
コード例 #2
0
ファイル: init_cfunc.c プロジェクト: manodeep/gbpCode
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);
}
コード例 #3
0
ファイル: map_to_grid.c プロジェクト: gbpoole/gbpCode
void map_to_grid(size_t      n_particles_local,
                 GBPREAL *   x_particles_local,
                 GBPREAL *   y_particles_local,
                 GBPREAL *   z_particles_local,
                 GBPREAL *   v_particles_local,
                 GBPREAL *   w_particles_local,
                 cosmo_info *cosmo,
                 double      redshift,
                 int         distribution_scheme,
                 double      normalization_constant,
                 field_info *field,
                 field_info *field_norm,
                 int         mode) {
    size_t       i_p;
    int          i_k;
    size_t       i_b;
    size_t       i_grid;
    int          i_coord;
    int          i_i[3];
    int          j_i[3];
    int          k_i[3];
    size_t       n_particles;
    double       v_p;
    double       w_p;
    int          flag_valued_particles;
    int          flag_weight_particles;
    int          flag_weight;
    int          flag_active;
    int          flag_viable;
    double       k_mag;
    double       dk;
    int          n_powspec;
    int          mode_powspec;
    size_t *     n_mode_powspec;
    double *     k_powspec;
    double *     kmin_powspec;
    double *     kmax_powspec;
    double *     k_powspec_bin;
    double *     P_powspec;
    double *     dP_powspec;
    double       k_min;
    double       k_max;
    double       norm_local;
    double       normalization;
    GBPREAL      x_i;
    GBPREAL      x_particle_i;
    GBPREAL      y_particle_i;
    GBPREAL      z_particle_i;
    double       kernal_offset;
    int          W_search_lo;
    int          W_search_hi;
    size_t       receive_left_size  = 0;
    size_t       receive_right_size = 0;
    size_t       index_best;
    int          n_buffer[3];
    size_t       n_send_left;
    size_t       n_send_right;
    size_t       send_size_left;
    size_t       send_size_right;
    GBPREAL *    send_left          = NULL;
    GBPREAL *    send_right         = NULL;
    GBPREAL *    receive_left       = NULL;
    GBPREAL *    receive_right      = NULL;
    GBPREAL *    send_left_norm     = NULL;
    GBPREAL *    send_right_norm    = NULL;
    GBPREAL *    receive_left_norm  = NULL;
    GBPREAL *    receive_right_norm = NULL;
    double       r_i, r_min, r_i_max = 0;
    double       W_i;
    int          index_i;
    interp_info *P_k_interp;
    double *     r_Daub;
    double *     W_Daub;
    double       h_Hubble;
    int          n_Daub;
    interp_info *W_r_Daub_interp = NULL;
    int          i_rank;
    size_t       buffer_index;
    int          i_test;
    double       accumulator;

    // Compute the total poulation size and print a status message
    calc_sum_global(&n_particles_local, &n_particles, 1, SID_SIZE_T, CALC_MODE_DEFAULT, SID_COMM_WORLD);
    SID_log("Distributing %zu items onto a %dx%dx%d grid...", SID_LOG_OPEN, n_particles, field->n[0], field->n[1], field->n[2]);

    // If we've been given a normalization field, make sure it's got the same geometry as the results field
    if(field_norm != NULL) {
        if(field->n_d != field_norm->n_d)
            SID_exit_error("grid dimension counts don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->n_d,
                           field_norm->n_d);
        int i_d;
        for(i_d = 0; i_d < field->n_d; i_d++) {
            if(field->n[i_d] != field_norm->n[i_d])
                SID_exit_error("grid dimension No. %d's sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, i_d,
                               field->n[i_d], field_norm->n[i_d]);
            if(field->n_R_local[i_d] != field_norm->n_R_local[i_d])
                SID_exit_error("grid dimension No. %d's slab sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, i_d,
                               field->n_R_local[i_d], field_norm->n_R_local[i_d]);
            if(field->i_R_start_local[i_d] != field_norm->i_R_start_local[i_d])
                SID_exit_error("grid dimension No. %d's start positions don't match (ie. %le!=%le)", SID_ERROR_LOGIC,
                               i_d, field->i_R_start_local[i_d], field_norm->i_R_start_local[i_d]);
            if(field->i_R_stop_local[i_d] != field_norm->i_R_stop_local[i_d])
                SID_exit_error("grid dimension No. %d's stop positions don't match (ie. %le!=%le)", SID_ERROR_LOGIC,
                               i_d, field->i_R_stop_local[i_d], field_norm->i_R_stop_local[i_d]);
        }
        if(field->n_field != field_norm->n_field)
            SID_exit_error("grid field sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->n_field,
                           field_norm->n_field);
        if(field->n_field_R_local != field_norm->n_field_R_local)
            SID_exit_error("grid local field sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->n_field_R_local,
                           field_norm->n_field_R_local);
        if(field->total_local_size != field_norm->total_local_size)
            SID_exit_error("grid total local sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->total_local_size,
                           field_norm->total_local_size);
    }

    // Set some variables
    if(v_particles_local != NULL)
        flag_valued_particles = GBP_TRUE;
    else {
        flag_valued_particles = GBP_FALSE;
        v_p                   = 1.;
    }
    if(w_particles_local != NULL)
        flag_weight_particles = GBP_TRUE;
    else {
        flag_weight_particles = GBP_FALSE;
        w_p                   = 1.;
    }
    h_Hubble = ((double *)ADaPS_fetch(cosmo, "h_Hubble"))[0];

    // Initializing the mass assignment scheme
    switch(distribution_scheme) {
        case MAP2GRID_DIST_DWT20:
            W_search_lo   = 2;
            W_search_hi   = 7;
            kernal_offset = 2.5;
            compute_Daubechies_scaling_fctns(20, 5, &r_Daub, &W_Daub, &n_Daub);
            init_interpolate(r_Daub, W_Daub, n_Daub, gsl_interp_cspline, &W_r_Daub_interp);
            SID_free(SID_FARG r_Daub);
            SID_free(SID_FARG W_Daub);
            SID_log("(using D20 scale function kernal)...", SID_LOG_CONTINUE);
            break;
        case MAP2GRID_DIST_DWT12:
            W_search_lo   = 1;
            W_search_hi   = 6;
            kernal_offset = 1.75;
            compute_Daubechies_scaling_fctns(12, 5, &r_Daub, &W_Daub, &n_Daub);
            init_interpolate(r_Daub, W_Daub, (size_t)n_Daub, gsl_interp_cspline, &W_r_Daub_interp);
            SID_free(SID_FARG r_Daub);
            SID_free(SID_FARG W_Daub);
            SID_log("(using D12 scale function kernal)...", SID_LOG_CONTINUE);
            break;
        case MAP2GRID_DIST_TSC:
            W_search_lo = 2;
            W_search_hi = 2;
            SID_log("(using triangular shaped function kernal)...", SID_LOG_CONTINUE);
            break;
        case MAP2GRID_DIST_CIC:
            SID_log("(using cloud-in-cell kernal)...", SID_LOG_CONTINUE);
        case MAP2GRID_DIST_NGP:
        default:
            W_search_lo = 1;
            W_search_hi = 1;
            SID_log("(using nearest grid point kernal)...", SID_LOG_CONTINUE);
            break;
    }

    // Initializing slab buffers
    n_send_left     = (size_t)(field->n[0] * field->n[1] * W_search_lo);
    n_send_right    = (size_t)(field->n[0] * field->n[1] * W_search_hi);
    send_size_left  = n_send_left * sizeof(GBPREAL);
    send_size_right = n_send_right * sizeof(GBPREAL);
    send_left       = (GBPREAL *)SID_calloc(send_size_left);
    send_right      = (GBPREAL *)SID_calloc(send_size_right);
    receive_left    = (GBPREAL *)SID_calloc(send_size_right);
    receive_right   = (GBPREAL *)SID_calloc(send_size_left);
    if(field_norm != NULL) {
        send_left_norm     = (GBPREAL *)SID_calloc(send_size_left);
        send_right_norm    = (GBPREAL *)SID_calloc(send_size_right);
        receive_left_norm  = (GBPREAL *)SID_calloc(send_size_right);
        receive_right_norm = (GBPREAL *)SID_calloc(send_size_left);
    }

    // Clear the field
    if(!SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_NOCLEAN)) {
        SID_log("Clearing fields...", SID_LOG_OPEN);
        clear_field(field);
        if(field_norm != NULL)
            clear_field(field);
        SID_log("Done.", SID_LOG_CLOSE);
    }

    // It is essential that we not pad the field for the simple way that we add-in the boundary buffers below
    set_FFT_padding_state(field, GBP_FALSE);
    if(field_norm != NULL)
        set_FFT_padding_state(field_norm, GBP_FALSE);

    // Create the mass distribution
    SID_log("Performing grid assignment...", SID_LOG_OPEN | SID_LOG_TIMER);

    // Loop over all the objects
    pcounter_info pcounter;
    SID_Init_pcounter(&pcounter, n_particles_local, 10);
    for(i_p = 0, norm_local = 0.; i_p < n_particles_local; i_p++) {
        double norm_i;
        double value_i;
        if(flag_valued_particles)
            v_p = (double)(v_particles_local[i_p]);
        if(flag_weight_particles)
            w_p = (double)(w_particles_local[i_p]);
        norm_i  = w_p;
        value_i = v_p * norm_i;

        // Particle's position
        x_particle_i = (GBPREAL)x_particles_local[i_p];
        y_particle_i = (GBPREAL)y_particles_local[i_p];
        z_particle_i = (GBPREAL)z_particles_local[i_p];

        // Quantize it onto the grid
        x_particle_i /= (GBPREAL)field->dR[0];
        y_particle_i /= (GBPREAL)field->dR[1];
        z_particle_i /= (GBPREAL)field->dR[2];
        i_i[0] = (int)x_particle_i; // position in grid-coordinates
        i_i[1] = (int)y_particle_i; // position in grid-coordinates
        i_i[2] = (int)z_particle_i; // position in grid-coordinates

        // Apply the kernel
        flag_viable = GBP_TRUE;
        double x_i_effective;
        for(j_i[0] = -W_search_lo; j_i[0] <= W_search_hi; j_i[0]++) {
            for(j_i[1] = -W_search_lo; j_i[1] <= W_search_hi; j_i[1]++) {
                for(j_i[2] = -W_search_lo; j_i[2] <= W_search_hi; j_i[2]++) {
                    // Compute distance to each grid point being searched against ...
                    flag_active = GBP_TRUE;
                    for(i_coord = 0, W_i = 1.; i_coord < 3; i_coord++) {
                        switch(i_coord) {
                            case 0:
                                x_i = (GBPREAL)(i_i[0] + j_i[0]) - x_particle_i;
                                break;
                            case 1:
                                x_i = (GBPREAL)(i_i[1] + j_i[1]) - y_particle_i;
                                break;
                            case 2:
                                x_i = (GBPREAL)(i_i[2] + j_i[2]) - z_particle_i;
                                break;
                        }
                        switch(distribution_scheme) {
                                // Distribute with a Daubechies wavelet transform of 12th or 20th order a la Cui et al '08
                            case MAP2GRID_DIST_DWT12:
                            case MAP2GRID_DIST_DWT20:
                                x_i_effective = x_i + kernal_offset;
                                if(x_i_effective > 0.)
                                    W_i *= interpolate(W_r_Daub_interp, x_i_effective);
                                else
                                    flag_active = GBP_FALSE;
                                break;
                                // Distribute using the triangular shaped cloud (TSC) method
                            case MAP2GRID_DIST_TSC:
                                if(x_i < 0.5)
                                    W_i *= (0.75 - x_i * x_i);
                                else if(x_i < 1.5)
                                    W_i *= 0.5 * (1.5 - fabs(x_i)) * (1.5 - fabs(x_i));
                                else
                                    flag_active = GBP_FALSE;
                                break;
                                // Distribute using the cloud-in-cell (CIC) method
                            case MAP2GRID_DIST_CIC:
                                if(fabs(x_i) < 1.)
                                    W_i *= (1. - fabs(x_i));
                                else
                                    flag_active = GBP_FALSE;
                                break;
                                // Distribute using "nearest grid point" (NGP; ie. the simplest and default) method
                            case MAP2GRID_DIST_NGP:
                            default:
                                if(fabs(x_i) <= 0.5 && flag_viable)
                                    W_i *= 1.;
                                else
                                    flag_active = GBP_FALSE;
                                break;
                        }
                    }
                    if(flag_active) { // This flags-out regions of the kernal with no support to save some time
                        // Set the grid indices (enforce periodic BCs; do x-coordinate last) ...
                        //   ... y-coordinate ...
                        k_i[1] = (i_i[1] + j_i[1]);
                        if(k_i[1] < 0)
                            k_i[1] += field->n[1];
                        else
                            k_i[1] = k_i[1] % field->n[1];
                        //   ... z-coordinate ...
                        k_i[2] = i_i[2] + j_i[2];
                        if(k_i[2] < 0)
                            k_i[2] += field->n[2];
                        else
                            k_i[2] = k_i[2] % field->n[2];
                        //   ... x-coordinate ...
                        //     Depending on x-index, add contribution to the
                        //     local array or to the slab buffers.
                        k_i[0] = (i_i[0] + j_i[0]);
                        if(k_i[0] < field->i_R_start_local[0]) {
                            k_i[0] -= (field->i_R_start_local[0] - W_search_lo);
                            if(k_i[0] < 0)
                                SID_exit_error("Left slab buffer limit exceeded by %d element(s).", SID_ERROR_LOGIC,
                                               -k_i[0]);
                            send_left[index_FFT_R(field, k_i)] += W_i * value_i;
                            if(field_norm != NULL)
                                send_left_norm[index_FFT_R(field_norm, k_i)] += W_i * norm_i;
                        } else if(k_i[0] > field->i_R_stop_local[0]) {
                            k_i[0] -= (field->i_R_stop_local[0] + 1);
                            if(k_i[0] >= W_search_hi)
                                SID_exit_error("Right slab buffer limit exceeded by %d element(s).", SID_ERROR_LOGIC,
                                               k_i[0] - W_search_hi + 1);
                            else {
                                send_right[index_FFT_R(field, k_i)] += W_i * value_i;
                                if(field_norm != NULL)
                                    send_right_norm[index_FFT_R(field_norm, k_i)] += W_i * norm_i;
                            }
                        } else {
                            field->field_local[index_local_FFT_R(field, k_i)] += W_i * value_i;
                            if(field_norm != NULL)
                                field_norm->field_local[index_local_FFT_R(field_norm, k_i)] += W_i * norm_i;
                        }
                        flag_viable = GBP_FALSE;
                    }
                }
            }
        }
        // Report the calculation's progress
        SID_check_pcounter(&pcounter, i_p);
    }
    SID_log("Done.", SID_LOG_CLOSE);

    // Perform exchange of slab buffers and add them to the local mass distribution.
    //    Note: it's important that the FFT field not be padded (see above, where
    //          this is set) for this to work the way it's done.
    SID_log("Adding-in the slab buffers...", SID_LOG_OPEN | SID_LOG_TIMER);
    // Numerator first ...
    exchange_slab_buffer_left(send_left, send_size_left, receive_right, &receive_right_size, &(field->slab));
    exchange_slab_buffer_right(send_right, send_size_right, receive_left, &receive_left_size, &(field->slab));
    for(i_b = 0; i_b < n_send_right; i_b++)
        field->field_local[i_b] += receive_left[i_b];
    for(i_b = 0; i_b < n_send_left; i_b++)
        field->field_local[field->n_field_R_local - n_send_left + i_b] += receive_right[i_b];
    // ... then denominator (if it's being used)
    if(field_norm != NULL) {
        exchange_slab_buffer_left(send_left_norm, send_size_left, receive_right_norm, &receive_right_size, &(field_norm->slab));
        exchange_slab_buffer_right(send_right_norm, send_size_right, receive_left_norm, &receive_left_size, &(field_norm->slab));
        for(i_b = 0; i_b < n_send_right; i_b++)
            field_norm->field_local[i_b] += receive_left_norm[i_b];
        for(i_b = 0; i_b < n_send_left; i_b++)
            field_norm->field_local[field_norm->n_field_R_local - n_send_left + i_b] += receive_right[i_b];
    }
    SID_free(SID_FARG send_left);
    SID_free(SID_FARG send_right);
    SID_free(SID_FARG receive_left);
    SID_free(SID_FARG receive_right);
    if(field_norm != NULL) {
        SID_free(SID_FARG send_left_norm);
        SID_free(SID_FARG send_right_norm);
        SID_free(SID_FARG receive_left_norm);
        SID_free(SID_FARG receive_right_norm);
    }
    SID_log("Done.", SID_LOG_CLOSE);

    // Recompute local normalization (more accurate for large sample sizes)
    if(!SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_NONORM)) {
        SID_log("Applying normalization...", SID_LOG_OPEN);
        if(field_norm != NULL) {
            for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++) {
                if(field_norm->field_local[i_grid] != 0)
                    field->field_local[i_grid] /= field_norm->field_local[i_grid];
            }
        }
        if(SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_APPLYFACTOR)) {
            for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++)
                field->field_local[i_grid] *= normalization_constant;
        }
        if(SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_FORCENORM)) {
            norm_local = 0;
            for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++)
                norm_local += (double)field->field_local[i_grid];
            calc_sum_global(&norm_local, &normalization, 1, SID_DOUBLE, CALC_MODE_DEFAULT, SID_COMM_WORLD);
            double normalization_factor;
            normalization_factor = normalization_constant / normalization;
            for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++)
                field->field_local[i_grid] *= normalization_factor;
        }
        SID_log("Done.", SID_LOG_CLOSE, normalization);
    }

    if(W_r_Daub_interp != NULL)
        free_interpolate(SID_FARG W_r_Daub_interp, NULL);

    SID_log("Done.", SID_LOG_CLOSE);
}
コード例 #4
0
void compute_trees_horizontal(char        *filename_halo_root_in,
                              char        *filename_cat_root_in,
                              char        *filename_snap_list_in,
                              char        *filename_root_matches,
                              char        *filename_output_dir,
                              cosmo_info **cosmo,
                              int          i_read_start,
                              int          i_read_stop,
                              int          i_read_step,
                              int          n_search,
                              int          flag_fix_bridges,
                              int         *flag_clean){
  char        group_text_prefix[5];
  FILE       *fp;
  char       *line=NULL;
  int         line_length=0;
  int         n_strays;
  int         n_strays_drop;
  int         n_strays_bridge;
  int         i_stray;
  int         n_match;
  int         n_match_halos;
  int         n_back_match;
  int         i_match;
  int         j_match;
  int         k_match;
  int         n_groups_1;
  int         n_groups_2;
  int         n_groups_3;
  int         i_group;
  int         j_group;
  int         k_group;
  int         l_group;
  int         n_subgroups_1;
  int         n_subgroups_2;
  int         i_subgroup;
  int         j_subgroup;
  int         i_drop;
  int         j_drop;
  int         k_drop;
  int         i_bridge;
  int         j_bridge;
  int         n_lines;
  int         i_file;
  int         j_file;
  int         i_write;
  int         j_write;
  int         l_write;
  int         l_read;
  int         j_file_1;
  int         j_file_2;
  int         i_read;
  int         j_read;
  int         j_read_1;
  int         j_read_2;
  int         n_descendant;
  int         n_progenitor;
  int         descendant_index;
  int         progenitor_index;
  int         my_descendant_index,my_descendant_id,my_descendant_list,my_index;
  int         index;
  int         max_id         =0;
  int         max_id_group   =0;
  int         max_id_subgroup=0;
  int        *my_descendant;
  int        *n_particles;
  int        *n_particles_groups;
  int        *n_particles_subgroups;
  int         my_trunk;
  double      expansion_factor;
  int         n_found;
  int         n_found_bridge;
  double      delta_r;
  double      delta_M;
  double      R_vir_p;
  double      R_vir_d;
  int         i_find,n_find;
  int         flag_continue;
  int         flag_drop;
  int        *match_id=NULL;
  int        *search_id=NULL;
  int         n_progenitors_max;
  int         i_search;
  int         flag_dropped;
  int         flag_first;
  int         n_particles_max;
  int         trunk_index;
  int        *n_groups=NULL;
  int        *n_subgroups=NULL;
  int         max_tree_id_group;
  int         max_tree_id_subgroup;
  int         max_tree_id;
  int       **n_subgroups_group=NULL;
  int        *n_subgroups_group_1=NULL;
  size_t    **sort_id=NULL;
  size_t    **sort_group_id=NULL;
  size_t    **sort_subgroup_id=NULL;
  size_t     *match_index=NULL;
  size_t     *bridge_index=NULL;
  size_t     *search_index=NULL;
  float      *match_score=NULL;
  char       *match_flag_two_way=NULL;
  int        *bridge_keep=NULL;
  int         flag_match_subgroups;
  int         flag_keep_strays=FALSE;
  int         n_k_match=2;
  int         n_snap;
  
  tree_horizontal_info **subgroups;
  tree_horizontal_info **groups;
  tree_horizontal_info **halos;
  tree_horizontal_info  *halos_i;
  match_info           **back_matches_groups;
  match_info           **back_matches_subgroups;
  match_info           **back_matches;

  int     n_files;
  int     n_subgroups_max;
  int     n_groups_max;
  int    *n_halos;
  int     n_halos_max;
  int     n_halos_i;
  int     i_halo;
  int     n_halos_1_matches;
  int     n_halos_2_matches;
  int     j_halo;
  int     k_halo;
  int     l_halo;

  int     n_list;
  int     k_file;
  int     l_file;
  int     k_index;
  int     k_file_temp;
  int     k_index_temp;

  int     n_wrap;
  int     i_file_start;
  
  char  filename_output_dir_horizontal[MAX_FILENAME_LENGTH];
  char  filename_output_dir_horizontal_cases[MAX_FILENAME_LENGTH];
  char  filename_output_file_root[MAX_FILENAME_LENGTH];
  char  filename_matching_out[MAX_FILENAME_LENGTH];
  FILE *fp_matching_out;
  int   i_column;

  SID_log("Constructing horizontal merger trees for snapshots #%d->#%d (step=%d)...",SID_LOG_OPEN|SID_LOG_TIMER,i_read_start,i_read_stop,i_read_step);

  if(n_search<1)
    SID_trap_error("n_search=%d but must be at least 1",ERROR_LOGIC,n_search);

  int flag_compute_fragmented=TRUE;
  int flag_compute_ghosts    =FALSE;

  if(!flag_fix_bridges)
    SID_log("Bridge-fixing is turned off.",SID_LOG_COMMENT);
  if(!flag_compute_fragmented)
    SID_log("Fragmented-halo propagation is turned off.",SID_LOG_COMMENT);
  if(!flag_compute_ghosts)
    SID_log("Ghost-populated tree construction is turned off.",SID_LOG_COMMENT);

  // Create the output directory
  mkdir(filename_output_dir,02755);

  // Create snapshot expansion factor list
  double *a_list=NULL;
  int     n_a_list_in;
  write_a_list(filename_snap_list_in,
               filename_output_dir,
               i_read_start,
               i_read_stop,
               i_read_step);
  read_a_list(filename_output_dir,
              &a_list,
              &n_a_list_in);

  write_tree_run_parameters(filename_output_dir,
                            i_read_start,
                            i_read_stop,
                            i_read_step,
                            n_search,
                            flag_fix_bridges,
                            flag_compute_fragmented,
                            flag_compute_ghosts);

  // Validate existing matching files &/or perfrom matching
  //if(!compute_trees_matches(filename_halo_root_in,
  //                          filename_root_matches,
  //                          i_read_start,
  //                          i_read_stop,
  //                          i_read_step,
  //                          n_search,
  //                          WRITE_MATCHES_MODE_TREES|WRITE_MATCHES_PERFORM_CHECK))
  //   SID_trap_error("Matching could not be completed.  Terminating.",ERROR_LOGIC);
  read_matches_header(filename_root_matches,
                      i_read_start,
                      i_read_stop,
                      i_read_step,
                      &n_files,
                      &n_subgroups,
                      &n_groups,
                      &n_subgroups_max,
                      &n_groups_max,
                      &n_halos_max);

  // We need these for allocating arrays
  calc_max(n_subgroups,&n_subgroups_max,n_files,SID_INT,CALC_MODE_DEFAULT);
  calc_max(n_groups,   &n_groups_max,   n_files,SID_INT,CALC_MODE_DEFAULT);
  n_halos_max=MAX(n_subgroups_max,n_groups_max);

  // We need enough indices to allow us to hold-on to descendants until outputing
  //   and for the current and last i_file as well
  n_wrap      =2*n_search+2;
  i_file_start=n_files-1;

  // Initialize arrays
  SID_log("Creating arrays...",SID_LOG_OPEN);
  n_particles_groups    =(int    *)SID_malloc(sizeof(int)   *n_halos_max);
  n_particles_subgroups =(int    *)SID_malloc(sizeof(int)   *n_halos_max);
  match_id              =(int    *)SID_malloc(sizeof(int)   *n_halos_max);
  match_score           =(float  *)SID_malloc(sizeof(float) *n_halos_max);
  match_index           =(size_t *)SID_malloc(sizeof(size_t)*n_halos_max);
  match_flag_two_way    =(char   *)SID_malloc(sizeof(char)  *n_halos_max);
  subgroups             =(tree_horizontal_info **)SID_malloc(sizeof(tree_horizontal_info *)*n_wrap);
  groups                =(tree_horizontal_info **)SID_malloc(sizeof(tree_horizontal_info *)*n_wrap);
  n_subgroups_group     =(int                  **)SID_malloc(sizeof(int                  *)*n_wrap);
  back_matches_subgroups=(match_info           **)SID_malloc(sizeof(match_info *)          *n_wrap);
  back_matches_groups   =(match_info           **)SID_malloc(sizeof(match_info *)          *n_wrap);
  for(i_search=0;i_search<n_wrap;i_search++){
     subgroups[i_search]             =(tree_horizontal_info *)SID_calloc(sizeof(tree_horizontal_info)*n_subgroups_max);
     groups[i_search]                =(tree_horizontal_info *)SID_calloc(sizeof(tree_horizontal_info)*n_groups_max);       
     n_subgroups_group[i_search]     =(int                  *)SID_calloc(sizeof(int)                 *n_groups_max);       
     back_matches_subgroups[i_search]=NULL;
     back_matches_groups[i_search]   =NULL;
  }
  SID_log("Done.",SID_LOG_CLOSE);

  // Process the first file separately
  //   (just give everything ids from a running index.  Also adds MMS flags.) ...
  init_trees_horizontal_roots(groups,
                              subgroups,
                              match_id,
                              match_score,
                              match_index,
                              match_flag_two_way,
                              n_particles_groups,
                              n_particles_subgroups,
                              n_subgroups_group,
                              n_groups_max,
                              n_subgroups_max,
                              filename_root_matches,
                              i_read_start,
                              i_read_stop,
                              i_read_step,
                              i_file_start,
                              n_wrap,
                              n_halos_max,
                              &max_id_group,
                              &max_tree_id_group,
                              &max_id_subgroup,
                              &max_tree_id_subgroup);

  // The first snapshot is done now (set to defaults as the roots of trees) ... now loop over all other snapshots ...
  //   There are a bunch of counters at work here.  Because we aren't necessarily using every 
  //     snapshot (if i_read_step>1), we need counters to keep track of which snapshots we
  //     are working with (i_read_*,j_read_*, etc), counters to keep track of which
  //     files's we're dealing with as far as the trees indices are concerned (i_file_*,j_file_*,etc), and
  //     counters to keep track of which files are being/have been written (i_write_*,j_write_* etc).
  //     We can't write files right away because previously processed snapshots can be changed
  //     when we deal with dropped and bridged halos.
  for(i_read   =i_read_stop-i_read_step,
        i_file =i_file_start-1, 
        j_file =1,             
        i_write=i_file_start,      
        j_write=i_read_stop,
        l_write=0;      
      i_read>=i_read_start;
      i_read-=i_read_step,    
         i_file--, 
         j_file++){
    SID_log("Processing snapshot #%d...",SID_LOG_OPEN|SID_LOG_TIMER,i_read);

    // Loop twice (1st to process subgroups, 2nd to process groups)
    for(k_match=0;k_match<n_k_match;k_match++){

       // Initialize a bunch of stuff which depends on whether
       //   we are processing groups or subgroups.
       // Do the groups first, so that we have access to n_subgroups_group,
       //   which we need for setting MOST_MASSIVE flags, etc
       switch(k_match){
          case 0:
          sprintf(group_text_prefix,"");
          flag_match_subgroups=MATCH_GROUPS;
          halos               =groups;
          back_matches        =back_matches_groups;
          n_halos             =n_groups;
          n_halos_max         =n_groups_max;
          max_id              =max_id_group;
          max_tree_id         =max_tree_id_group;
          n_particles         =n_particles_groups;
          break;
          case 1:
          sprintf(group_text_prefix,"sub");
          flag_match_subgroups=MATCH_SUBGROUPS;
          halos               =subgroups;
          back_matches        =back_matches_subgroups;
          n_halos             =n_subgroups;
          n_halos_max         =n_subgroups_max;
          max_id              =max_id_subgroup;
          max_tree_id         =max_tree_id_subgroup;
          n_particles         =n_particles_subgroups;
          break;
       }
       halos_i  =halos[i_file%n_wrap];
       n_halos_i=n_halos[j_file];

       SID_log("Processing %d %sgroups...",SID_LOG_OPEN|SID_LOG_TIMER,n_halos_i,group_text_prefix);

       // Initialize tree pointer-arrays with dummy values
       init_trees_horizontal_snapshot(halos_i,
                                      &(back_matches[i_file%n_wrap]),
                                      i_read,
                                      i_file,
                                      n_groups[j_file],
                                      n_groups_max,
                                      n_subgroups[j_file],
                                      n_subgroups_max,
                                      flag_match_subgroups);

       // Identify matches that will be used for progenitor building (and read halo sizes)
       if(flag_fix_bridges)
          identify_back_matches(halos,
                                halos_i,
                                &(back_matches[i_file%n_wrap]),
                                n_halos_i,
                                match_id,
                                match_score,
                                match_index,
                                match_flag_two_way,
                                n_particles,
                                i_file,
                                i_read,
                                i_read_start,
                                i_read_stop,
                                i_read_step,
                                n_search,
                                n_wrap,
                                n_halos_max,
                                n_files,
                                filename_root_matches,
                                flag_match_subgroups);

       // Perform forward-matching
       identify_progenitors(halos,
                            halos_i,
                            n_subgroups_group,
                            n_halos_i,
                            match_id,
                            match_score,
                            match_index,
                            match_flag_two_way,
                            n_particles,
                            i_file,
                            i_read,
                            i_read_start,
                            i_read_stop,
                            i_read_step,
                            n_search,
                            n_wrap,
                            n_halos_max,
                            n_files,
                            flag_fix_bridges,
                            &max_id,
                            &n_halos_1_matches,
                            &n_halos_2_matches,
                            filename_root_matches,
                            group_text_prefix,
                            flag_match_subgroups);

       // Add MOST_MASSIVE substructure flags
       if(flag_match_subgroups==MATCH_SUBGROUPS)
          add_substructure_info(subgroups[i_file%n_wrap],
                                n_subgroups_group[i_file%n_wrap],
                                n_particles_groups,
                                n_groups[j_file],
                                n_subgroups[j_file],
                                flag_match_subgroups);
      
       // Finalize matches to unprocessed halos.  In particular,
       //    resolve matches to bridged halos that were not matched
       //    to any emerged candidates.
       finalize_trees_horizontal(n_halos_1_matches,
                                 n_halos_i,
                                 halos,
                                 halos_i,
                                 i_file,
                                 n_search,
                                 n_wrap,
                                 &max_id,
                                 &max_tree_id);
 
       // Now that we know which halos are main progenitors, we
       //    can set the n_partices_largest_descendant values.
       set_largest_descendants(halos_i,n_halos_i);

       // Now that we know which halos are the main progenitors of this
       //    snapshot's bridged halos, we can mark any other back matches
       //    as candidate emerged halos and identify bridges.
       if(flag_fix_bridges)
          identify_bridges(halos_i,n_halos_i,n_search);

       // Report some statistics
       //   n.b.: This is only an estimate in some cases, since subsequent snapshots may alter this snapshot.  
       //         See the final written log.txt file for accurate numbers.
       write_trees_horizontal_report(n_halos_i,n_halos_max,halos_i);

       // Update the max_id variables
       switch(flag_match_subgroups){
          case MATCH_SUBGROUPS:
            max_id_subgroup=max_id;
            max_tree_id_subgroup=max_tree_id;
            break;
          case MATCH_GROUPS:
            max_id_group   =max_id;
            max_tree_id_group=max_tree_id;
            break;
       }
       SID_log("Done.",SID_LOG_CLOSE);
    } // k_match
 
    // Write trees once a few files have been processed
    //   and no more dropped groups etc. need to be given ids
    if(j_file>n_search){
       int mode_write;
       if(flag_compute_ghosts || flag_compute_fragmented)
          mode_write=TREE_HORIZONTAL_WRITE_EXTENDED|TREE_HORIZONTAL_WRITE_ALLCASES|TREE_HORIZONTAL_WRITE_CHECK_FRAGMENTED;
       else
          mode_write=TREE_HORIZONTAL_WRITE_ALLCASES|TREE_HORIZONTAL_WRITE_CHECK_FRAGMENTED;
       write_trees_horizontal((void **)groups, 
                              (void **)subgroups,
                              n_groups[l_write],   n_groups_max,   
                              n_subgroups[l_write],n_subgroups_max,
                              n_subgroups_group,
                              max_tree_id_subgroup,
                              max_tree_id_group,
                              i_write,
                              j_write,
                              l_write,
                              i_read_step,
                              n_search,
                              n_wrap,
                              i_file_start,
                              filename_cat_root_in,
                              filename_output_dir,
                              a_list,
                              cosmo,
                              n_k_match,
                              l_write==0,
                              mode_write);
       i_write--;
       l_write++;
       j_write-=i_read_step;
    }
    SID_log("Done.",SID_LOG_CLOSE);
  } // loop over snaps

  // Write the remaining snapshots
  for(;j_write>=i_read_start;i_write--,j_write-=i_read_step,l_write++){
     int mode_write;
     if(flag_compute_ghosts || flag_compute_fragmented)
        mode_write=TREE_HORIZONTAL_WRITE_EXTENDED|TREE_HORIZONTAL_WRITE_ALLCASES|TREE_HORIZONTAL_WRITE_CHECK_FRAGMENTED;
     else
        mode_write=TREE_HORIZONTAL_WRITE_ALLCASES|TREE_HORIZONTAL_WRITE_CHECK_FRAGMENTED;
     write_trees_horizontal((void **)groups,   
                            (void **)subgroups,
                            n_groups[l_write],   n_groups_max,   
                            n_subgroups[l_write],n_subgroups_max,
                            n_subgroups_group,
                            max_tree_id_subgroup,
                            max_tree_id_group,
                            i_write,
                            j_write,
                            l_write,
                            i_read_step,
                            n_search,
                            n_wrap,
                            i_file_start,
                            filename_cat_root_in,
                            filename_output_dir,
                            a_list,
                            cosmo,
                            n_k_match,
                            l_write==0,
                            mode_write);
  }
  int i_write_last;
  int l_write_last;
  int j_write_last;
  i_write_last=i_write+1;
  j_write_last=j_write+i_read_step;
  l_write_last=l_write-1;

  // Clean-up
  SID_log("Freeing arrays...",SID_LOG_OPEN);
  for(i_search=0;i_search<n_wrap;i_search++){
     // Free subgroup information
     SID_free(SID_FARG subgroups[i_search]);
     SID_free(SID_FARG back_matches_subgroups[i_search]);
     // Free group information
     SID_free(SID_FARG groups[i_search]);
     SID_free(SID_FARG back_matches_groups[i_search]);
  }
  SID_free(SID_FARG subgroups);
  SID_free(SID_FARG groups);
  SID_free(SID_FARG back_matches_subgroups);
  SID_free(SID_FARG back_matches_groups);
  SID_free(SID_FARG match_id);
  SID_free(SID_FARG match_score);
  SID_free(SID_FARG match_index);
  SID_free(SID_FARG match_flag_two_way);
  SID_free(SID_FARG n_particles_groups);
  SID_free(SID_FARG n_particles_subgroups);
  SID_log("Done.",SID_LOG_CLOSE);

  // Any information that needs to be communicated up the trees from the
  //    roots will be done here.  This includes any information needed
  //    for tracking mergers and fragmented halos.
  // Because fragmented halos might persist longer than the search interval, we have to
  //    walk the trees forward in time to propagate the TREE_CASE_FRAGMENTED_* flags.
  // At this point, fragmented halos are only labeled when they appear.
  //    This will propagate the fragmented halo flags forward in time.
  propagate_progenitor_info(n_groups,
                            n_subgroups,
                            n_subgroups_group,
                            i_file_start,
                            i_write_last,
                            j_write_last,
                            l_write_last,
                            i_read_stop,
                            i_read_step,
                            max_tree_id_subgroup,
                            max_tree_id_group,
                            n_subgroups_max,
                            n_groups_max,
                            n_search,
                            n_files,
                            n_wrap,
                            n_k_match,
                            a_list,
                            cosmo,
                            filename_output_dir,
                            flag_compute_fragmented);

  // If extended horizontal tree files were written for fragmented
  //    halo propagation or ghost tree construction, remove them.
  if(flag_compute_ghosts || flag_compute_fragmented){
     SID_log("Removing temporary tree files...",SID_LOG_OPEN);
     for(j_write=i_read_stop;j_write>=i_read_start;j_write-=i_read_step){
        char filename_output_dir_horizontal[MAX_FILENAME_LENGTH];
        char filename_output_dir_horizontal_trees[MAX_FILENAME_LENGTH];
        char filename_remove[MAX_FILENAME_LENGTH];
        sprintf(filename_output_dir_horizontal,      "%s/horizontal",filename_output_dir);
        sprintf(filename_output_dir_horizontal_trees,"%s/trees",     filename_output_dir_horizontal);
        sprintf(filename_remove,"%s/horizontal_trees_tmp_%03d.dat",filename_output_dir_horizontal_trees,j_write);
        remove(filename_remove);
     }
     SID_log("Done.",SID_LOG_CLOSE);
  }

  // Some final clean-up
  SID_log("Cleaning up...",SID_LOG_OPEN);
  SID_free(SID_FARG n_groups);
  SID_free(SID_FARG n_subgroups);
  for(i_search=0;i_search<n_wrap;i_search++)
     SID_free(SID_FARG n_subgroups_group[i_search]);
  SID_free(SID_FARG n_subgroups_group);
  SID_free(SID_FARG a_list);
  SID_log("Done.",SID_LOG_CLOSE);

  // Force the forest construction to use all snapshots
  int n_search_forests=i_read_stop;

  // Construct tree->forest mappings
  compute_forests(filename_output_dir,n_search_forests);

  SID_log("Done.",SID_LOG_CLOSE);
}
コード例 #5
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);
}
コード例 #6
0
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);

}
コード例 #7
0
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);
}
コード例 #8
0
ファイル: make_gadget_grid.c プロジェクト: manodeep/gbpCode
int main(int argc, char *argv[]){
  int     n_species;
  int     n_load;
  int     n_used;
  int     flag_used[N_GADGET_TYPE];
  char    species_name[256];
  double  h_Hubble;
  double  n_spec;
  double  redshift;
  int     i_species;
  char    n_string[64];
  int             n[3];
  double          L[3];
  FILE           *fp_1D;
  FILE           *fp_2D;
  cosmo_info     *cosmo;
  field_info     *field[N_GADGET_TYPE];
  field_info     *field_norm[N_GADGET_TYPE];
  plist_info      plist_header;
  plist_info      plist;
  FILE           *fp;
  int     i_temp;
  int     n_temp;
  double *k_temp;
  double *kmin_temp;
  double *kmax_temp;
  double *P_temp;
  size_t *n_mode_temp;
  double *sigma_P_temp;
  double *shot_noise_temp;
  double *dP_temp;
  int     snapshot_number;
  int     i_compute;
  int     distribution_scheme;
  double  k_min_1D;
  double  k_max_1D;
  double  k_min_2D;
  double  k_max_2D;
  int     n_k_1D;
  int     n_k_2D;
  double *k_1D;
  double *P_k_1D;
  double *dP_k_1D;
  int    *n_modes_1D;
  double *P_k_2D;
  double *dP_k_2D;
  int    *n_modes_2D;
  int     n_groups=1;
  double  dk_1D;
  double  dk_2D;
  char   *grid_identifier;

  // Initialization -- MPI etc.
  SID_init(&argc,&argv,NULL,NULL);

  // Parse arguments
  int grid_size;
  char filename_in_root[MAX_FILENAME_LENGTH];
  char filename_out_root[MAX_FILENAME_LENGTH];
  strcpy(filename_in_root,  argv[1]);
  snapshot_number=(int)atoi(argv[2]);
  strcpy(filename_out_root, argv[3]);
  grid_size      =(int)atoi(argv[4]);
  if(!strcmp(argv[5],"ngp") || !strcmp(argv[5],"NGP"))
     distribution_scheme=MAP2GRID_DIST_NGP;
  else if(!strcmp(argv[5],"cic") || !strcmp(argv[5],"CIC"))
     distribution_scheme=MAP2GRID_DIST_CIC;
  else if(!strcmp(argv[5],"tsc") || !strcmp(argv[5],"TSC"))
     distribution_scheme=MAP2GRID_DIST_TSC;
  else if(!strcmp(argv[5],"d12") || !strcmp(argv[5],"D12"))
     distribution_scheme=MAP2GRID_DIST_DWT12;
  else if(!strcmp(argv[5],"d20") || !strcmp(argv[5],"D20"))
     distribution_scheme=MAP2GRID_DIST_DWT20;
  else
     SID_trap_error("Invalid distribution scheme {%s} specified.",ERROR_SYNTAX,argv[5]);

  SID_log("Smoothing Gadget file {%s;snapshot=#%d} to a %dx%dx%d grid with %s kernel...",SID_LOG_OPEN|SID_LOG_TIMER,
          filename_in_root,snapshot_number,grid_size,grid_size,grid_size,argv[5]);

  // Initialization -- fetch header info
  SID_log("Reading Gadget header...",SID_LOG_OPEN);
  gadget_read_info   fp_gadget;
  int                flag_filefound=init_gadget_read(filename_in_root,snapshot_number,&fp_gadget);
  int                flag_multifile=fp_gadget.flag_multifile;
  int                flag_file_type=fp_gadget.flag_file_type;
  gadget_header_info header        =fp_gadget.header;
  double             box_size      =(double)(header.box_size);
  size_t            *n_all         =(size_t *)SID_calloc(sizeof(size_t)*N_GADGET_TYPE);
  size_t             n_total;
  if(flag_filefound){
     if(SID.I_am_Master){
        FILE *fp_in;
        char  filename[MAX_FILENAME_LENGTH];
        int   block_length_open;
        int   block_length_close;
        set_gadget_filename(&fp_gadget,0,filename);
        fp_in=fopen(filename,"r");
        fread_verify(&block_length_open, sizeof(int),1,fp_in);
        fread_verify(&header,            sizeof(gadget_header_info),1,fp_in);
        fread_verify(&block_length_close,sizeof(int),1,fp_in);
        fclose(fp_in);
        if(block_length_open!=block_length_close)
           SID_trap_error("Block lengths don't match (ie. %d!=%d).",ERROR_LOGIC,block_length_open,block_length_close);
     }
     SID_Bcast(&header,sizeof(gadget_header_info),MASTER_RANK,SID.COMM_WORLD);
     redshift=header.redshift;
     h_Hubble=header.h_Hubble;
     box_size=header.box_size;
     if(SID.n_proc>1)
        n_load=1;
     else
        n_load=header.n_files;
     for(i_species=0,n_total=0,n_used=0;i_species<N_GADGET_TYPE;i_species++){
        n_all[i_species]=(size_t)header.n_all_lo_word[i_species]+((size_t)header.n_all_hi_word[i_species])<<32;
        n_total+=n_all[i_species];
        if(n_all[i_species]>0){
           n_used++;
           flag_used[i_species]=TRUE;
        }
        else
           flag_used[i_species]=FALSE;
     }

     // Initialize cosmology
     double box_size        =((double *)ADaPS_fetch(plist.data,"box_size"))[0];
     double h_Hubble        =((double *)ADaPS_fetch(plist.data,"h_Hubble"))[0];
     double redshift        =((double *)ADaPS_fetch(plist.data,"redshift"))[0];
     double expansion_factor=((double *)ADaPS_fetch(plist.data,"expansion_factor"))[0];
     double Omega_M         =((double *)ADaPS_fetch(plist.data,"Omega_M"))[0];
     double Omega_Lambda    =((double *)ADaPS_fetch(plist.data,"Omega_Lambda"))[0];
     double Omega_k         =1.-Omega_Lambda-Omega_M;
     double Omega_b=0.; // not needed, so doesn't matter
     double f_gas  =Omega_b/Omega_M;
     double sigma_8=0.; // not needed, so doesn't matter
     double n_spec =0.; // not needed, so doesn't matter
     char   cosmo_name[16];
     sprintf(cosmo_name,"Gadget file's");
     init_cosmo(&cosmo,
                cosmo_name,
                Omega_Lambda,
                Omega_M,
                Omega_k,
                Omega_b,
                f_gas,
                h_Hubble,
                sigma_8,
                n_spec);
  }
  SID_log("Done.",SID_LOG_CLOSE);

  grid_identifier=(char *)SID_calloc(GRID_IDENTIFIER_SIZE*sizeof(char));

  // Only process if there are >0 particles present
  if(n_used>0){

     // Loop over ithe real-space and 3 redshift-space frames
     int i_write;
     int i_run;
     int n_run;
     int n_grids_total; 
     n_grids_total=4; // For now, hard-wire real-space density and velocity grids only
     n_run=1;         // For now, hard-wire real-space calculation only
     for(i_run=0,i_write=0;i_run<n_run;i_run++){

        // Read catalog
        int  n_grid;
        char i_run_identifier[8];
        switch(i_run){
        case 0:
           SID_log("Processing real-space ...",SID_LOG_OPEN|SID_LOG_TIMER);
           sprintf(i_run_identifier,"r");
           n_grid=4;
           break;
        case 1:
           SID_log("Processing v_x redshift space...",SID_LOG_OPEN|SID_LOG_TIMER);
           sprintf(i_run_identifier,"x");
           n_grid=1;
           break;
        case 2:
           SID_log("Processing v_y redshift space...",SID_LOG_OPEN|SID_LOG_TIMER);
           sprintf(i_run_identifier,"y");
           n_grid=1;
           break;
        case 3:
           SID_log("Processing v_z redsift space...",SID_LOG_OPEN|SID_LOG_TIMER);
           sprintf(i_run_identifier,"z");
           n_grid=1;
           break;
        }

        // For each i_run case, loop over the fields we want to produce
        int i_grid;
        for(i_grid=0;i_grid<n_grid;i_grid++){

           char i_grid_identifier[8];
           switch(i_grid){
           case 0:
              SID_log("Processing density grid ...",SID_LOG_OPEN|SID_LOG_TIMER);
              sprintf(i_grid_identifier,"rho");
              break;
           case 1:
              SID_log("Processing v_x velocity grid...",SID_LOG_OPEN|SID_LOG_TIMER);
              sprintf(i_grid_identifier,"v_x");
              break;
           case 2:
              SID_log("Processing v_y velocity grid...",SID_LOG_OPEN|SID_LOG_TIMER);
              sprintf(i_grid_identifier,"v_y");
              break;
           case 3:
              SID_log("Processing v_z velocity grid...",SID_LOG_OPEN|SID_LOG_TIMER);
              sprintf(i_grid_identifier,"v_z");
              break;
           }

           // Initialize the field that will hold the grid
           int        n[]={grid_size,grid_size,grid_size};
           double     L[]={box_size, box_size, box_size};
           int        i_init;
           for(i_species=0;i_species<N_GADGET_TYPE;i_species++){
              if(flag_used[i_species]){
                 field[i_species]     =(field_info *)SID_malloc(sizeof(field_info));
                 field_norm[i_species]=(field_info *)SID_malloc(sizeof(field_info));
                 init_field(3,n,L,field[i_species]);
                 init_field(3,n,L,field_norm[i_species]);
                 i_init=i_species;
              }
              else{
                 field[i_species]     =NULL;
                 field_norm[i_species]=NULL;
              }
           }

           // Loop over all the files that this rank will read
           int i_load;
           for(i_load=0;i_load<n_load;i_load++){
              if(n_load>1)
                 SID_log("Processing file No. %d of %d...",SID_LOG_OPEN|SID_LOG_TIMER,i_load+1,n_load);

              // Initialization -- read gadget file
              GBPREAL mass_array[N_GADGET_TYPE];
              init_plist(&plist,&((field[i_init])->slab),GADGET_LENGTH,GADGET_MASS,GADGET_VELOCITY);
              char filename_root[MAX_FILENAME_LENGTH];
              read_gadget_binary_local(filename_in_root,
                                       snapshot_number,
                                       i_run,
                                       i_load,
                                       n_load,
                                       mass_array,
                                       &(field[i_init]->slab),
                                       cosmo,
                                       &plist);

              // Generate power spectra
              for(i_species=0;i_species<plist.n_species;i_species++){

                 // Determine how many particles of species i_species there are
                 if(n_all[i_species]>0){
                    // Fetch the needed information
                    size_t   n_particles;
                    size_t   n_particles_local;
                    int      flag_alloc_m;
                    GBPREAL *x_particles_local;
                    GBPREAL *y_particles_local;
                    GBPREAL *z_particles_local;
                    GBPREAL *vx_particles_local;
                    GBPREAL *vy_particles_local;
                    GBPREAL *vz_particles_local;
                    GBPREAL *m_particles_local;
                    GBPREAL *v_particles_local;
                    GBPREAL *w_particles_local;
                    n_particles      =((size_t  *)ADaPS_fetch(plist.data,"n_all_%s",plist.species[i_species]))[0];
                    n_particles_local=((size_t  *)ADaPS_fetch(plist.data,"n_%s",    plist.species[i_species]))[0];
                    x_particles_local= (GBPREAL *)ADaPS_fetch(plist.data,"x_%s",    plist.species[i_species]);
                    y_particles_local= (GBPREAL *)ADaPS_fetch(plist.data,"y_%s",    plist.species[i_species]);
                    z_particles_local= (GBPREAL *)ADaPS_fetch(plist.data,"z_%s",    plist.species[i_species]);
                    vx_particles_local=(GBPREAL *)ADaPS_fetch(plist.data,"vx_%s",   plist.species[i_species]);
                    vy_particles_local=(GBPREAL *)ADaPS_fetch(plist.data,"vy_%s",   plist.species[i_species]);
                    vz_particles_local=(GBPREAL *)ADaPS_fetch(plist.data,"vz_%s",   plist.species[i_species]);
                    if(ADaPS_exist(plist.data,"M_%s",plist.species[i_species])){
                       flag_alloc_m=FALSE;
                       m_particles_local=(GBPREAL *)ADaPS_fetch(plist.data,"M_%s",plist.species[i_species]);
                    }
                    else{
                       flag_alloc_m=TRUE;
                       m_particles_local=(GBPREAL *)SID_malloc(n_particles_local*sizeof(GBPREAL));
                       int i_particle;
                       for(i_particle=0;i_particle<n_particles_local;i_particle++)
                          m_particles_local[i_particle]=mass_array[i_species];
                    }

                    // Decide the map_to_grid() mode
                    int mode;
                    if(n_load==1)
                       mode=MAP2GRID_MODE_DEFAULT;
                    else if(i_load==0 || n_load==1)
                       mode=MAP2GRID_MODE_DEFAULT|MAP2GRID_MODE_NONORM;
                    else if(i_load==(n_load-1))
                       mode=MAP2GRID_MODE_NOCLEAN;
                    else
                       mode=MAP2GRID_MODE_NOCLEAN|MAP2GRID_MODE_NONORM;

                    // Set the array that will weight the grid
                    field_info *field_i;
                    field_info *field_norm_i;
                    double factor;
                    switch(i_grid){
                    case 0:
                       v_particles_local=m_particles_local;
                       w_particles_local=NULL;
                       field_i          =field[i_species];
                       field_norm_i     =NULL;
                       mode|=MAP2GRID_MODE_APPLYFACTOR;
                       factor=pow((double)grid_size/box_size,3.);
                       break;
                    case 1:
                       v_particles_local=vx_particles_local;
                       w_particles_local=m_particles_local;
                       field_i          =field[i_species];
                       field_norm_i     =field_norm[i_species];
                       factor=1.;
                       break;
                    case 2:
                       v_particles_local=vy_particles_local;
                       w_particles_local=m_particles_local;
                       field_i          =field[i_species];
                       field_norm_i     =field_norm[i_species];
                       factor=1.;
                       break;
                    case 3:
                       v_particles_local=vz_particles_local;
                       w_particles_local=m_particles_local;
                       field_i          =field[i_species];
                       field_norm_i     =field_norm[i_species];
                       factor=1.;
                       break;
                    }

                    // Generate grid
                    map_to_grid(n_particles_local,
                                x_particles_local,
                                y_particles_local,
                                z_particles_local,
                                v_particles_local,
                                w_particles_local,
                                cosmo,
                                redshift,
                                distribution_scheme,
                                factor,
                                field_i,
                                field_norm_i,
                                mode);
                    if(flag_alloc_m)
                       SID_free(SID_FARG m_particles_local);
                 }
              }

              // Clean-up
              free_plist(&plist);
              if(n_load>1)
                 SID_log("Done.",SID_LOG_CLOSE);
           } // loop over i_load
           
           // Write results to disk
           char filename_out_species[MAX_FILENAME_LENGTH];
           init_plist(&plist,NULL,GADGET_LENGTH,GADGET_MASS,GADGET_VELOCITY);
           for(i_species=0;i_species<plist.n_species;i_species++){
              if(flag_used[i_species]){
                 sprintf(grid_identifier,"%s_%s_%s",i_grid_identifier,i_run_identifier,plist.species[i_species]);
                 sprintf(filename_out_species,"%s_%s",filename_out_root,plist.species[i_species]);
                 write_grid(field[i_species],
                            filename_out_species,
                            i_write,
                            n_grids_total,
                            distribution_scheme,
                            grid_identifier,
                            header.box_size);
                 free_field(field[i_species]);
                 free_field(field_norm[i_species]);
                 SID_free(SID_FARG field[i_species]);
                 SID_free(SID_FARG field_norm[i_species]);
                 i_write++;
              }
           }

           // Clean-up
           free_plist(&plist);
           SID_log("Done.",SID_LOG_CLOSE);

        } // loop over i_grid

        SID_log("Done.",SID_LOG_CLOSE);
     } // loop over i_run
  } // if n_used>0 

  // Clean-up
  free_cosmo(&cosmo);
  SID_free(SID_FARG grid_identifier);
  SID_free(SID_FARG n_all);

  SID_log("Done.",SID_LOG_CLOSE);

  SID_exit(ERROR_NONE);
}
コード例 #9
0
ファイル: read_smooth.c プロジェクト: webbjj/gbpCode
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);
}
コード例 #10
0
void analyze_halos_and_N_subhalos(tree_info  *trees,
                                  const char *filename_out_root,
                                  const char *catalog_root,
                                  double      z_select_exact,
                                  double      M_cut_lo,
                                  double      M_cut_hi,
                                  int         n_subgroups_track_max){

  // Compute merger rates ...
  SID_log("Constructing catalogs...",SID_LOG_OPEN|SID_LOG_TIMER);

  // Fetch halo properties
  halo_properties_info **group_properties   =(halo_properties_info **)ADaPS_fetch(trees->data,"properties_groups");
  halo_properties_info **subgroup_properties=(halo_properties_info **)ADaPS_fetch(trees->data,"properties_subgroups");

  // Determine the best z_select snapshot
  int    i_z_select=find_treesnap_z(trees,z_select_exact);
  int    i_z_0     =trees->n_snaps-1;
  double z_select  =trees->z_list[i_z_select];
  double t_select  =trees->t_list[i_z_select];
  SID_log("The snapshot corresponding best to z=%4.2f is #%03d (z=%4.2f).",SID_LOG_COMMENT,z_select_exact,trees->snap_list[i_z_select],z_select);

  // Allocate the list arrays
  tree_node_info  **list_groups       =(tree_node_info  **)SID_malloc(sizeof(tree_node_info  *)*trees->n_groups_snap_local[i_z_select]);
  tree_node_info  **list_subgroups_all=(tree_node_info  **)SID_malloc(sizeof(tree_node_info  *)*trees->n_groups_snap_local[i_z_select]);
  tree_node_info ***list_subgroups    =(tree_node_info ***)SID_malloc(sizeof(tree_node_info **)*n_subgroups_track_max);
  for(int i_track=0;i_track<n_subgroups_track_max;i_track++)
     list_subgroups[i_track]=(tree_node_info **)SID_malloc(sizeof(tree_node_info *)*trees->n_groups_snap_local[i_z_select]);

  // Select z_select systems
  tree_node_info *current_group;
  int  n_list_groups       =0;
  int  n_list_subgroups_all=0;
  int *n_list_subgroups    =(int *)SID_calloc(sizeof(int)*n_subgroups_track_max);
  SID_log("Selecting z=%4.2f systems...",SID_LOG_OPEN,trees->z_list[i_z_select]);
  current_group=trees->first_neighbour_groups[i_z_select];
  while(current_group!=NULL){
     halo_properties_info *current_group_properties=&(group_properties[current_group->snap_tree][current_group->neighbour_index]);
     if(current_group_properties->M_vir>=M_cut_lo && current_group_properties->M_vir<=M_cut_hi){
        list_groups[n_list_groups++]=current_group;
        tree_node_info *current_subgroup=current_group->substructure_first;
        int i_subgroup       =0;
        int i_subgroups_track=0;
        while(current_subgroup!=NULL && i_subgroups_track<n_subgroups_track_max){
           if(!check_treenode_if_fragmented(current_subgroup)){
              if(i_subgroup>0)
                 list_subgroups_all[n_list_subgroups_all++]=current_subgroup;
              list_subgroups[i_subgroups_track][n_list_subgroups[i_subgroups_track]++]=current_subgroup;
              i_subgroups_track++;
           }
           i_subgroup++;
           current_subgroup=current_subgroup->substructure_next;
        }
     }
     current_group=current_group->next_neighbour;
  }
  SID_log("%d groups found...",SID_LOG_CONTINUE,n_list_groups);
  SID_log("Done.",SID_LOG_CLOSE);

  // Write properties and tracks for selected z_select groups and subgroups
  char catalog_name[32];
  sprintf(catalog_name,"%s_groups",catalog_root);
  write_tree_branches(trees,list_groups,n_list_groups,TRUE,filename_out_root,catalog_name);
  average_tree_branches(catalog_name);
  for(int i_track=0;i_track<n_subgroups_track_max;i_track++){
     if(i_track==0){
        sprintf(catalog_name,"%s_subgroups_all",catalog_root);
        write_tree_branches(trees,list_subgroups_all,n_list_subgroups_all,FALSE,filename_out_root,catalog_name);
        average_tree_branches(catalog_name);
     }
     sprintf(catalog_name,"%s_subgroups_%02d",catalog_root,i_track);
     write_tree_branches(trees,list_subgroups[i_track],n_list_subgroups[i_track],FALSE,filename_out_root,catalog_name);
     average_tree_branches(catalog_name);
  }

  // Clean-up
  SID_free(SID_FARG n_list_subgroups);
  for(int i_track=0;i_track<n_subgroups_track_max;i_track++)
     SID_free(SID_FARG list_subgroups[i_track]);
  SID_free(SID_FARG list_subgroups);
  SID_free(SID_FARG list_subgroups_all);
  SID_free(SID_FARG list_groups);

  SID_log("Done.",SID_LOG_CLOSE);
}