Ejemplo n.º 1
0
void clear_field(field_info *FFT) {
    size_t i_fft;
    for(i_fft = 0; i_fft < FFT->total_local_size; i_fft++)
        FFT->field_local[i_fft] = 0.;
    SID_Barrier(SID_COMM_WORLD);
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
void write_trend_ascii(trend_info *trend,const char *filename_output_root){

   // Set filename and open file
   char filename[MAX_FILENAME_LENGTH];
   sprintf(filename,"%s_%s.txt",filename_output_root,trend->ordinate->name);
   FILE *fp_out;
   SID_log("Writing trend to {%s}...",SID_LOG_OPEN,filename);
   SID_Barrier(SID.COMM_WORLD);
   if(SID.I_am_Master){
      fp_out=fopen(filename,"w");

      // Write header
      int i_column=1;
      fprintf(fp_out,"#  Column (%03d): Bin\n",        i_column++);
      fprintf(fp_out,"#         (%03d): %s bin - lo\n",i_column++,trend->ordinate->name);
      fprintf(fp_out,"#         (%03d): %s bin - hi\n",i_column++,trend->ordinate->name);
      fprintf(fp_out,"#         (%03d): n_all\n",      i_column++);
      // Loop over the properties
      trend_property_info *current_property=trend->coordinate_first;
      while(current_property!=NULL){
         fprintf(fp_out,"#         (%03d): n_hist (%s)\n",            i_column++,current_property->name);
         fprintf(fp_out,"#         (%03d): %s\n",                     i_column++,current_property->name);
         fprintf(fp_out,"#         (%03d): %s - 68%% confidence lo\n",i_column++,current_property->name);
         fprintf(fp_out,"#         (%03d): %s - 68%% confidence hi\n",i_column++,current_property->name);
         fprintf(fp_out,"#         (%03d): %s - 95%% confidence lo\n",i_column++,current_property->name);
         fprintf(fp_out,"#         (%03d): %s - 95%% confidence hi\n",i_column++,current_property->name);
         current_property=current_property->next;
      }
   }

   // Finalize the histograms and write results
   hist_info *hist_ordinate=trend->ordinate->hist;
   finalize_histogram(hist_ordinate);
   for(int i_bin=0;i_bin<hist_ordinate->n_bins;i_bin++){
      if(SID.I_am_Master)
         fprintf(fp_out,"%3d %le %le %d",
                        i_bin,
                        histogram_bin_x_lo(hist_ordinate,i_bin),
                        histogram_bin_x_hi(hist_ordinate,i_bin),
                        hist_ordinate->bin_count[i_bin]);

      // Loop over the properties
      trend_property_info *current_property=trend->coordinate_first;
      while(current_property!=NULL){
         double x_peak;
         double x_68_lo;
         double x_68_hi;
         double x_95_lo;
         double x_95_hi;
         hist_info *hist_i=&(current_property->hist[i_bin]);
         finalize_histogram(hist_i);
         compute_histogram_range(hist_i,68.,GBP_HISTOGRAM_RANGE_HIST,&x_peak,&x_68_lo,&x_68_hi);
         compute_histogram_range(hist_i,95.,GBP_HISTOGRAM_RANGE_HIST,&x_peak,&x_95_lo,&x_95_hi);
         if(SID.I_am_Master)
            fprintf(fp_out," %d %le %le %le %le %le",
                           hist_i->count_hist,
                           x_peak,
                           x_68_lo,
                           x_68_hi,
                           x_95_lo,
                           x_95_hi);
         current_property=current_property->next;
      }
      if(SID.I_am_Master) fprintf(fp_out,"\n");
   }
   if(SID.I_am_Master) fclose(fp_out);

   SID_log("Done.",SID_LOG_CLOSE);
}
Ejemplo n.º 4
0
void SID_exit(int status){
  int    i_args=0;
  int    n_days;
  int    n_hrs;
  int    n_mins; 
  int    n_secs;
  size_t max_RAM;
  size_t SID_max_RAM_local;
  int    i_rank;
  char   spacer[10];
  char   time_string[48];

  // Deal with I/O channels
  fflush(SID.fp_log);
  SID_Barrier(SID.COMM_WORLD);
  if(SID.fp_in!=stdin && SID.fp_in!=NULL)
    fclose(SID.fp_in);

  // Clean-up argument stuff
  if(SID.args!=NULL){ 
    while((SID_arg *)(SID.args[i_args])!=NULL){
      if(SID.arg_alloc[i_args])
        free(((SID_arg *)(SID.args[i_args]))->val);
      i_args++;
    }
    if(i_args>0){
      free(SID.arg_alloc);
      free(SID.arg_set);
    }
  }

  // Clean-up any memory still allocated

  // Report execution statistics
  if(status!=ERROR_SYNTAX){
  if(SID.I_am_Master){
    fprintf(SID.fp_log,"\n");
    fprintf(SID.fp_log,"Run statistics:\n");
    fprintf(SID.fp_log,"--------------\n");
    (void)time(&(SID.time_stop));
    n_secs =(int)(SID.time_stop-SID.time_start);
    seconds2ascii(n_secs,time_string);
    fprintf(SID.fp_log,"Time elapsed=%s.\n",time_string);
  }

  // Report memory usage
  if(SID.I_am_Master){
    fprintf(SID.fp_log,"\nMemory usage:\n");
    fprintf(SID.fp_log,"------------\n");
  }
  #if USE_MPI
    SID_Barrier(SID.COMM_WORLD);
    SID_Allreduce(&(SID.max_RAM_local),&max_RAM,1,SID_SIZE_T,SID_SUM,SID.COMM_WORLD);
    if(SID.n_proc>1){
      for(i_rank=0;i_rank<SID.n_proc;i_rank++){
        SID_max_RAM_local=SID.max_RAM_local;
        if(i_rank!=MASTER_RANK)
          SID_Bcast(&SID_max_RAM_local,sizeof(size_t),i_rank,SID.COMM_WORLD);
        if(SID.I_am_Master){
          if(SID.n_proc>1000){
            if((float)SID.max_RAM_local/(float)SIZE_OF_MEGABYTE>1.)
              fprintf(SID.fp_log,"Peak for rank %4d=%4.2lf Gb\n",i_rank,(float)SID_max_RAM_local/(float)SIZE_OF_GIGIBYTE);
            else if((float)SID.max_RAM_local/(float)SIZE_OF_KILOBYTE>1.)
              fprintf(SID.fp_log,"Peak for rank %4d=%4.2lf Mb\n",i_rank,(float)SID_max_RAM_local/(float)SIZE_OF_MEGABYTE);
            else
              fprintf(SID.fp_log,"Peak for rank %4d=%4.2lf kb\n",i_rank,(float)SID_max_RAM_local/(float)SIZE_OF_KILOBYTE);
            strcpy(spacer,"       ");
          }
          else if(SID.n_proc>100){
            if((float)SID.max_RAM_local/(float)SIZE_OF_MEGABYTE>1.)
              fprintf(SID.fp_log,"Peak for rank %3d=%4.2lf Gb\n",i_rank,(float)SID_max_RAM_local/(float)SIZE_OF_GIGIBYTE);
            else if((float)SID.max_RAM_local/(float)SIZE_OF_KILOBYTE>1.)
              fprintf(SID.fp_log,"Peak for rank %3d=%4.2lf Mb\n",i_rank,(float)SID_max_RAM_local/(float)SIZE_OF_MEGABYTE);
            else
              fprintf(SID.fp_log,"Peak for rank %3d=%4.2lf kb\n",i_rank,(float)SID_max_RAM_local/(float)SIZE_OF_KILOBYTE);
            strcpy(spacer,"      ");
          }
          else if(SID.n_proc>10){
            if((float)SID.max_RAM_local/(float)SIZE_OF_MEGABYTE>1.)
              fprintf(SID.fp_log,"Peak for rank %2d=%4.2lf Gb\n",i_rank,(float)SID_max_RAM_local/(float)SIZE_OF_GIGIBYTE);
            else if((float)SID.max_RAM_local/(float)SIZE_OF_KILOBYTE>1.)
              fprintf(SID.fp_log,"Peak for rank %2d=%4.2lf Mb\n",i_rank,(float)SID_max_RAM_local/(float)SIZE_OF_MEGABYTE);
            else
              fprintf(SID.fp_log,"Peak for rank %2d=%4.2lf kb\n",i_rank,(float)SID_max_RAM_local/(float)SIZE_OF_KILOBYTE);
            strcpy(spacer,"     ");
          }
          else{
            if((float)SID.max_RAM_local/(float)SIZE_OF_MEGABYTE>1.)
              fprintf(SID.fp_log,"Peak for rank %d=%4.2lf Gb\n",i_rank,(float)SID_max_RAM_local/(float)SIZE_OF_GIGIBYTE);
            else if((float)SID.max_RAM_local/(float)SIZE_OF_KILOBYTE>1.)
              fprintf(SID.fp_log,"Peak for rank %d=%4.2lf Mb\n",i_rank,(float)SID_max_RAM_local/(float)SIZE_OF_MEGABYTE);
            else
              fprintf(SID.fp_log,"Peak for rank %d=%4.2lf kb\n",i_rank,(float)SID_max_RAM_local/(float)SIZE_OF_KILOBYTE);
            strcpy(spacer,"    ");
          }
        }
        SID_Barrier(SID.COMM_WORLD);
      }
    }
  #else
    strcpy(spacer,"\0");
    max_RAM=SID.max_RAM_local;
  #endif
  if(SID.I_am_Master){
    if((float)max_RAM/(float)SIZE_OF_MEGABYTE>1.)
      fprintf(SID.fp_log,"Peak total %s=%4.2lf Gb\n",spacer,(float)max_RAM/(float)SIZE_OF_GIGIBYTE);
    else if((float)max_RAM/(float)SIZE_OF_KILOBYTE>1.)
      fprintf(SID.fp_log,"Peak total %s=%4.2lf Mb\n",spacer,(float)max_RAM/(float)SIZE_OF_MEGABYTE);
    else
      fprintf(SID.fp_log,"Peak total %s=%4.2lf kb\n",spacer,(float)max_RAM/(float)SIZE_OF_KILOBYTE);
  }
  }

  // Free some arrays
  SID_free(SID_FARG SID.time_start_level);
  SID_free(SID_FARG SID.time_stop_level);
  SID_free(SID_FARG SID.time_total_level);
  SID_free(SID_FARG SID.flag_use_timer);
  SID_free(SID_FARG SID.IO_size);
  SID_free(SID_FARG SID.My_node);

  // Finalize MPI
  SID_Comm_free(&(SID.COMM_WORLD));
  #if USE_MPI_IO
    MPI_Info_free(&(SID.file_info));
  #endif
  #if USE_MPI
    MPI_Finalize(); 
  #endif
  exit(status);
}
Ejemplo n.º 5
0
int main(int argc, char *argv[]) {
    int        snapshot;
    char       filename_out[256];
    char       filename_smooth[256];
    char       filename_snapshot[256];
    char *     species_name;
    double     h_Hubble;
    plist_info plist;
    size_t     i_particle;
    int        i_species;
    int        j_species;
    int        i_rank;
    size_t     n_particles;
    GBPREAL *  x_array;
    GBPREAL *  y_array;
    GBPREAL *  z_array;
    GBPREAL *  r_smooth_array;
    GBPREAL *  rho_array;
    GBPREAL *  sigma_v_array;
    FILE *     fp_out;

    SID_Init(&argc, &argv, NULL);

    strcpy(filename_snapshot, argv[1]);
    snapshot = atoi(argv[2]);
    strcpy(filename_smooth, argv[3]);
    strcpy(filename_out, argv[4]);

    SID_log("Creating ascii file {%s} from smmoth files {%s} and snapshot {%s}...",
            SID_LOG_OPEN | SID_LOG_TIMER,
            filename_out,
            filename_smooth,
            filename_snapshot);

    // Read snapshot files
    init_plist(&plist, NULL, GADGET_LENGTH, GADGET_MASS, GADGET_VELOCITY);
    read_gadget_binary(filename_snapshot, snapshot, &plist, READ_GADGET_DEFAULT);
    read_smooth(&plist, filename_smooth, 0, SMOOTH_DEFAULT);
    h_Hubble = ((double *)ADaPS_fetch(plist.data, "h_Hubble"))[0];

    // Loop over each species
    for(i_species = 0, j_species = 0; i_species < N_GADGET_TYPE; i_species++) {
        species_name = plist.species[i_species];
        if(ADaPS_exist(plist.data, "n_all_%s", species_name))
            n_particles = ((size_t *)ADaPS_fetch(plist.data, "n_all_%s", species_name))[0];
        else
            n_particles = 0;
        // If at least one rank has particles for this species ...
        if(n_particles > 0) {
            SID_log("Writting %s particles...", SID_LOG_OPEN, species_name);
            // ... then fetch arrays ...
            n_particles = ((size_t *)ADaPS_fetch(plist.data, "n_%s", species_name))[0];
            x_array     = (GBPREAL *)ADaPS_fetch(plist.data, "x_%s", species_name);
            y_array     = (GBPREAL *)ADaPS_fetch(plist.data, "y_%s", species_name);
            z_array     = (GBPREAL *)ADaPS_fetch(plist.data, "z_%s", species_name);
            if(ADaPS_exist(plist.data, "r_smooth_%s", species_name))
                r_smooth_array = (GBPREAL *)ADaPS_fetch(plist.data, "r_smooth_%s", species_name);
            else
                r_smooth_array = NULL;
            if(ADaPS_exist(plist.data, "rho_%s", species_name))
                rho_array = (GBPREAL *)ADaPS_fetch(plist.data, "rho_%s", species_name);
            else
                rho_array = NULL;
            if(ADaPS_exist(plist.data, "sigma_v_%s", species_name))
                sigma_v_array = (GBPREAL *)ADaPS_fetch(plist.data, "sigma_v_%s", species_name);
            else
                sigma_v_array = NULL;

            // ... and write this species' particles
            for(i_rank = 0; i_rank < SID.n_proc; i_rank++) {
                if(SID.My_rank == i_rank) {
                    if(j_species == 0 && i_rank == 0)
                        fp_out = fopen(filename_out, "w");
                    else
                        fp_out = fopen(filename_out, "a");
                    for(i_particle = 0; i_particle < n_particles; i_particle++) {
                        fprintf(fp_out,
                                "%2d %11.4le %11.4le %11.4le",
                                i_species,
                                (double)x_array[i_particle] * h_Hubble / M_PER_MPC,
                                (double)y_array[i_particle] * h_Hubble / M_PER_MPC,
                                (double)z_array[i_particle] * h_Hubble / M_PER_MPC);
                        if(r_smooth_array != NULL)
                            fprintf(fp_out, " %10.4le", (double)r_smooth_array[i_particle] * h_Hubble / M_PER_MPC);
                        if(rho_array != NULL)
                            fprintf(fp_out, " %10.4le", (double)rho_array[i_particle] / (M_SOL * pow(h_Hubble / M_PER_MPC, 3.)));
                        if(sigma_v_array != NULL)
                            fprintf(fp_out, " %10.4le", (double)sigma_v_array[i_particle] * 1e-3);
                        fprintf(fp_out, "\n");
                    }
                    fclose(fp_out);
                }
                SID_Barrier(SID_COMM_WORLD);
            }
            j_species++;
            SID_log("Done.", SID_LOG_CLOSE);
        }
    }

    // Clean-up
    free_plist(&plist);
    SID_log("Done.", SID_LOG_CLOSE);
    SID_Finalize();
}
Ejemplo n.º 6
0
void write_tree_branches(tree_info *      trees,
                         tree_node_info **list_in,
                         int              n_list_in,
                         int              mode,
                         const char *     filename_out_dir,
                         const char *     catalog_name) {
    SID_log("Processing %d halos in catalog {%s}...", SID_LOG_OPEN, n_list_in, catalog_name);

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

    // Are we processing groups?
    int                    flag_processing_groups = GBP_FALSE;
    halo_properties_info **halo_properties;
    if(mode == 1) {
        flag_processing_groups = GBP_TRUE;
        halo_properties        = group_properties;
    } else {
        flag_processing_groups = GBP_FALSE;
        halo_properties        = subgroup_properties;
    }

    // Take the halo pointers back to their start
    int              n_list      = n_list_in;
    tree_node_info **list        = (tree_node_info **)SID_malloc(sizeof(tree_node_info *) * n_list_in);
    int *            track_index = (int *)SID_malloc(sizeof(int) * n_list_in);
    for(int i_list = 0; i_list < n_list; i_list++) {
        track_index[i_list] = i_list; // default
        find_treenode_branch_leaf(trees, list_in[i_list], &(list[i_list]));
    }

    // Count fragmented halos
    int n_frag = 0;
    for(int i_list = 0; i_list < n_list_in; i_list++) {
        if(SID_CHECK_BITFIELD_SWITCH(list_in[i_list]->tree_case, TREE_CASE_FRAGMENTED_STRAYED) ||
                SID_CHECK_BITFIELD_SWITCH(list_in[i_list]->tree_case, TREE_CASE_FRAGMENTED_NORMAL) ||
                SID_CHECK_BITFIELD_SWITCH(list_in[i_list]->tree_case, TREE_CASE_FRAGMENTED_OTHER))
            n_frag++;
    }
    if(n_frag > 0)
        SID_log("%d fragmented...", SID_LOG_CONTINUE, n_frag);

    // Remove duplicates (These are ugly N^2 algorythms.  Fix them sometime.)
    for(int i_list = 0; i_list < n_list_in; i_list++)
        track_index[i_list] = i_list;
    for(int i_list = 0; i_list < n_list; i_list++) {
        for(int j_list = (i_list + 1); j_list < n_list; j_list++) {
            if(list[i_list] == list[j_list]) {
                n_list--;
                for(int k_list = j_list; k_list < n_list; k_list++)
                    list[k_list] = list[k_list + 1];
                int old_index = track_index[j_list];
                for(int k_list = 0; k_list < n_list; k_list++) {
                    if(track_index[k_list] > old_index)
                        track_index[k_list]--;
                }
                track_index[j_list] = track_index[i_list];
            }
        }
    }
    for(int i_list = 0; i_list < n_list_in; i_list++) {
        for(int j_list = 0; j_list < n_list; j_list++) {
            if(list_in[i_list] == list[j_list])
                track_index[i_list] = j_list;
        }
    }
    if(n_list != n_list_in)
        SID_log("%d removed as duplicates...", SID_LOG_CONTINUE, n_list_in - n_list);

    // Master Rank does all the writing
    FILE *fp_tracks_out = NULL;
    FILE *fp_props_out  = NULL;
    if(SID.I_am_Master) {
        // Create and open the output files
        char filename_tracks_out[SID_MAX_FILENAME_LENGTH];
        char filename_props_out[SID_MAX_FILENAME_LENGTH];
        sprintf(filename_tracks_out, "%s/%s_tracks.dat", filename_out_dir, catalog_name);
        sprintf(filename_props_out, "%s/%s_props.txt", filename_out_dir, catalog_name);
        fp_tracks_out = fopen(filename_tracks_out, "w");
        fp_props_out  = fopen(filename_props_out, "w");

        // Write header for tracks file
        fwrite(&n_list, sizeof(int), 1, fp_tracks_out);
        fwrite(&(trees->n_snaps), sizeof(int), 1, fp_tracks_out);
        fwrite(trees->snap_list, sizeof(int), trees->n_snaps, fp_tracks_out);
        fwrite(trees->z_list, sizeof(double), trees->n_snaps, fp_tracks_out);
        fwrite(trees->t_list, sizeof(double), trees->n_snaps, fp_tracks_out);

        // Write header for props file
        int n_write;
        int i_write;
        int i_column;
        if(!flag_processing_groups)
            n_write = 7;
        else
            n_write = 5; // Don't write the halos at the end which pertain only to subgroups
        for(i_write = 0, i_column = 1; i_write < n_write; i_write++) {
            char write_name[32];
            switch(i_write) {
                case 0:
                    sprintf(write_name, "select");
                    break;
                case 1:
                    sprintf(write_name, "main_progenitor");
                    break;
                case 2:
                    sprintf(write_name, "peak_mass");
                    break;
                case 3:
                    sprintf(write_name, "form");
                    break;
                case 4:
                    sprintf(write_name, "last");
                    break;
                case 5:
                    sprintf(write_name, "accrete_last");
                    break;
                case 6:
                    sprintf(write_name, "accrete_first");
                    break;
            }

            if(i_write == 0) {
                if(flag_processing_groups)
                    fprintf(fp_props_out, "# Properties for group catalog {%s}\n", catalog_name);
                else
                    fprintf(fp_props_out, "# Properties for subgroup catalog {%s}\n", catalog_name);
                fprintf(fp_props_out, "#\n");
                fprintf(fp_props_out, "# Column (%02d): Catalog item number\n", i_column);
                i_column++;
                fprintf(fp_props_out, "#        (%02d): Track index\n", i_column);
                i_column++;
            }
            fprintf(fp_props_out, "#        (%02d): Snapshot No. at t_%s\n", i_column, write_name);
            i_column++;
            fprintf(fp_props_out, "#        (%02d): Index No.    at t_%s\n", i_column, write_name);
            i_column++;
            fprintf(fp_props_out, "#        (%02d): t_%s\n", i_column, write_name);
            i_column++;
            fprintf(fp_props_out, "#        (%02d): z_%s\n", i_column, write_name);
            i_column++;
            fprintf(fp_props_out, "#        (%02d): log_10(M_%s(z=z_%s) [M_sol])\n", i_column, write_name, write_name);
            i_column++;
            fprintf(fp_props_out, "#        (%02d): n_p(z=z_%s)\n", i_column, write_name);
            i_column++;
            if(!flag_processing_groups) {
                fprintf(fp_props_out, "#        (%02d): log_10(M_parent_%s(z=z_%s) [M_sol])\n", i_column, write_name, write_name);
                i_column++;
            }
        }
    }

    // Allocate some temporary arrays for the tracks
    int *   i_z_track = (int *)SID_malloc(sizeof(int) * trees->n_snaps);
    int *   idx_track = (int *)SID_malloc(sizeof(int) * trees->n_snaps);
    int *   tc_track  = (int *)SID_malloc(sizeof(int) * trees->n_snaps);
    double *M_track   = (double *)SID_malloc(sizeof(double) * trees->n_snaps);
    double *x_track   = (double *)SID_malloc(sizeof(double) * trees->n_snaps);
    double *y_track   = (double *)SID_malloc(sizeof(double) * trees->n_snaps);
    double *z_track   = (double *)SID_malloc(sizeof(double) * trees->n_snaps);
    double *vx_track  = (double *)SID_malloc(sizeof(double) * trees->n_snaps);
    double *vy_track  = (double *)SID_malloc(sizeof(double) * trees->n_snaps);
    double *vz_track  = (double *)SID_malloc(sizeof(double) * trees->n_snaps);

    // Process z_obs halos
    int k_z_obs = 0;
    for(int i_rank = 0; i_rank < SID.n_proc; i_rank++) {
        if(SID.My_rank == i_rank || SID.I_am_Master) {
            int n_list_i;
            // Generate properties
            SID_Status status;
            if(i_rank == 0)
                n_list_i = n_list_in;
            else
                SID_Sendrecv(&n_list_in, 1, SID_INT, SID_MASTER_RANK, 1918270, &n_list_i, 1, SID_INT, i_rank, 1918270, SID_COMM_WORLD, &status);
            for(int i_list = 0; i_list < n_list_i; i_list++) {
                // Point to the halo to be processed
                tree_node_info *current_halo = list_in[i_list];

                // Find some special nodes for this listed halo
                tree_node_info *descendant_last            = NULL;
                tree_node_info *progenitor_main            = NULL;
                tree_node_info *progenitor_peak_mass       = NULL;
                tree_node_info *progenitor_formation       = NULL;
                tree_node_info *progenitor_first_accretion = NULL;
                tree_node_info *progenitor_last_accretion  = NULL;
                find_treenode_last_snapshot(trees, current_halo, &descendant_last);
                find_treenode_main_progenitor(trees, current_halo, &progenitor_main);
                find_treenode_accretion(trees, current_halo, &progenitor_first_accretion, &progenitor_last_accretion);
                find_treenode_M_peak(trees, descendant_last, &progenitor_peak_mass);
                find_treenode_formation(trees, progenitor_peak_mass, 0.5, &progenitor_formation);

                if(descendant_last->snap_tree == (trees->n_snaps - 1))
                    descendant_last = NULL;

                // Write properties
                int n_write;
                if(i_rank == 0)
                    fprintf(fp_props_out, "%4d %4d", i_list, track_index[i_list]);
                if(!flag_processing_groups)
                    n_write = 7;
                else
                    n_write = 5; // Don't write the halos at the end which pertain only to subgroups
                for(int i_write = 0; i_write < n_write; i_write++) {
                    // Compute properties
                    int    i_z_node;
                    int    idx_node;
                    int    idx_node_parent;
                    double t_node;
                    double z_node;
                    double M_node;
                    double M_node_parent;
                    int    n_p_node;
                    if(SID.My_rank == i_rank) {
                        tree_node_info *node_write;
                        char            write_name[32];
                        switch(i_write) {
                            case 0:
                                sprintf(write_name, "select");
                                node_write = current_halo;
                                break;
                            case 1:
                                sprintf(write_name, "main_progenitor");
                                node_write = progenitor_main;
                                break;
                            case 2:
                                sprintf(write_name, "peak_mass");
                                node_write = progenitor_peak_mass;
                                break;
                            case 3:
                                sprintf(write_name, "form");
                                node_write = progenitor_formation;
                                break;
                            case 4:
                                sprintf(write_name, "last");
                                node_write = descendant_last;
                                break;
                            case 5:
                                sprintf(write_name, "accrete_last");
                                node_write = progenitor_last_accretion;
                                break;
                            case 6:
                                sprintf(write_name, "accrete_first");
                                node_write = progenitor_first_accretion;
                                break;
                        }

                        if(node_write != NULL) {
                            i_z_node = node_write->snap_tree;
                            idx_node = node_write->neighbour_index;
                            t_node   = trees->t_list[i_z_node];
                            z_node   = trees->z_list[i_z_node];
                            M_node   = halo_properties[i_z_node][idx_node].M_vir;
                            n_p_node = halo_properties[i_z_node][idx_node].n_particles;
                            if(node_write->parent_top != NULL && !flag_processing_groups) {
                                idx_node_parent = node_write->parent_top->snap_tree;
                                M_node_parent   = group_properties[i_z_node][idx_node_parent].M_vir;
                            } else {
                                idx_node_parent = -1;
                                M_node_parent   = 0.;
                            }
                        } else {
                            i_z_node        = -1;
                            idx_node        = -1;
                            t_node          = -1.;
                            z_node          = -1.;
                            M_node          = 0.;
                            n_p_node        = 0;
                            idx_node_parent = -1;
                            M_node_parent   = 0.;
                        }
                    }

                    // Write properties
                    if(i_rank != 0) {
                        SID_Status status;
                        SID_Sendrecv(&i_z_node, 1, SID_INT, SID_MASTER_RANK, 1918271, &i_z_node, 1, SID_INT, i_rank, 1918271, SID_COMM_WORLD, &status);
                        SID_Sendrecv(&idx_node, 1, SID_INT, SID_MASTER_RANK, 1918272, &idx_node, 1, SID_INT, i_rank, 1918272, SID_COMM_WORLD, &status);
                        SID_Sendrecv(&t_node, 1, SID_DOUBLE, SID_MASTER_RANK, 1918273, &t_node, 1, SID_DOUBLE, i_rank, 1918273, SID_COMM_WORLD, &status);
                        SID_Sendrecv(&z_node, 1, SID_DOUBLE, SID_MASTER_RANK, 1918274, &z_node, 1, SID_DOUBLE, i_rank, 1918274, SID_COMM_WORLD, &status);
                        SID_Sendrecv(&M_node, 1, SID_DOUBLE, SID_MASTER_RANK, 1918275, &M_node, 1, SID_DOUBLE, i_rank, 1918275, SID_COMM_WORLD, &status);
                        SID_Sendrecv(
                            &M_node_parent, 1, SID_DOUBLE, SID_MASTER_RANK, 1918276, &M_node_parent, 1, SID_DOUBLE, i_rank, 1918276, SID_COMM_WORLD, &status);
                    }
                    if(SID.I_am_Master) {
                        int snap_node = -1;
                        if(i_z_node >= 0)
                            snap_node = trees->snap_list[i_z_node];
                        fprintf(fp_props_out,
                                " %4d %7d %10.3le %5.2lf %6.3lf %7d",
                                snap_node,
                                idx_node,
                                t_node / S_PER_YEAR,
                                z_node,
                                take_log10(M_node),
                                n_p_node);
                        if(!flag_processing_groups)
                            fprintf(fp_props_out, " %6.3lf", take_log10(M_node_parent));
                    }
                } // i_write
                if(SID.I_am_Master)
                    fprintf(fp_props_out, "\n");
            }

            // Generate tracks
            if(i_rank == 0)
                n_list_i = n_list;
            else {
                SID_Status status;
                SID_Sendrecv(&n_list, 1, SID_INT, SID_MASTER_RANK, 1918270, &n_list_i, 1, SID_INT, i_rank, 1918270,
                             SID_COMM_WORLD, &status);
            }
            for(int i_list = 0; i_list < n_list_i; i_list++) {
                // Point to the halo to be processed
                tree_node_info *current_halo = list[i_list];
                // Compute track
                int n_track = 0;
                if(SID.My_rank == i_rank) {
                    tree_node_info *current_track = current_halo;
                    while(current_track != NULL && check_treenode_if_main_progenitor(current_track)) {
                        i_z_track[n_track] = current_track->snap_tree;
                        idx_track[n_track] = current_track->neighbour_index;
                        tc_track[n_track]  = current_track->tree_case;
                        x_track[n_track]   = halo_properties[i_z_track[n_track]][idx_track[n_track]].position_MBP[0];
                        y_track[n_track]   = halo_properties[i_z_track[n_track]][idx_track[n_track]].position_MBP[1];
                        z_track[n_track]   = halo_properties[i_z_track[n_track]][idx_track[n_track]].position_MBP[2];
                        vx_track[n_track]  = halo_properties[i_z_track[n_track]][idx_track[n_track]].velocity_COM[0];
                        vy_track[n_track]  = halo_properties[i_z_track[n_track]][idx_track[n_track]].velocity_COM[1];
                        vz_track[n_track]  = halo_properties[i_z_track[n_track]][idx_track[n_track]].velocity_COM[2];
                        if(!SID_CHECK_BITFIELD_SWITCH(current_track->tree_case, TREE_CASE_MOST_MASSIVE) ||
                                SID_CHECK_BITFIELD_SWITCH(current_track->tree_case, TREE_CASE_DOMINANT))
                            M_track[n_track] = halo_properties[i_z_track[n_track]][idx_track[n_track]].M_vir;
                        else
                            M_track[n_track] = -1.;
                        n_track++;
                        current_track = current_track->descendant;
                    }
                }

                // Write track
                if(i_rank != 0) {
                    SID_Status status;
                    SID_Sendrecv(&n_track, 1, SID_INT, SID_MASTER_RANK, 1918370, &n_track, 1, SID_INT, i_rank, 1918370, SID_COMM_WORLD, &status);
                    SID_Sendrecv(i_z_track, n_track, SID_INT, SID_MASTER_RANK, 1918371, i_z_track, n_track, SID_INT, i_rank, 1918371, SID_COMM_WORLD, &status);
                    SID_Sendrecv(idx_track, n_track, SID_INT, SID_MASTER_RANK, 1918372, idx_track, n_track, SID_INT, i_rank, 1918372, SID_COMM_WORLD, &status);
                    SID_Sendrecv(tc_track, n_track, SID_INT, SID_MASTER_RANK, 1918373, tc_track, n_track, SID_INT, i_rank, 1918373, SID_COMM_WORLD, &status);
                    SID_Sendrecv(x_track, n_track, SID_INT, SID_MASTER_RANK, 1918374, x_track, n_track, SID_INT, i_rank, 1918374, SID_COMM_WORLD, &status);
                    SID_Sendrecv(y_track, n_track, SID_INT, SID_MASTER_RANK, 1918375, y_track, n_track, SID_INT, i_rank, 1918375, SID_COMM_WORLD, &status);
                    SID_Sendrecv(z_track, n_track, SID_INT, SID_MASTER_RANK, 1918376, z_track, n_track, SID_INT, i_rank, 1918376, SID_COMM_WORLD, &status);
                    SID_Sendrecv(vx_track, n_track, SID_INT, SID_MASTER_RANK, 1918377, vx_track, n_track, SID_INT, i_rank, 1918377, SID_COMM_WORLD, &status);
                    SID_Sendrecv(vy_track, n_track, SID_INT, SID_MASTER_RANK, 1918378, vy_track, n_track, SID_INT, i_rank, 1918378, SID_COMM_WORLD, &status);
                    SID_Sendrecv(vz_track, n_track, SID_INT, SID_MASTER_RANK, 1918379, vz_track, n_track, SID_INT, i_rank, 1918379, SID_COMM_WORLD, &status);
                    SID_Sendrecv(M_track, n_track, SID_INT, SID_MASTER_RANK, 1918380, M_track, n_track, SID_INT, i_rank, 1918380, SID_COMM_WORLD, &status);
                }
                if(SID.I_am_Master) {
                    fwrite(&n_track, sizeof(int), 1, fp_tracks_out);
                    fwrite(i_z_track, sizeof(int), n_track, fp_tracks_out);
                    fwrite(idx_track, sizeof(int), n_track, fp_tracks_out);
                    fwrite(tc_track, sizeof(int), n_track, fp_tracks_out);
                    fwrite(x_track, sizeof(double), n_track, fp_tracks_out);
                    fwrite(y_track, sizeof(double), n_track, fp_tracks_out);
                    fwrite(z_track, sizeof(double), n_track, fp_tracks_out);
                    fwrite(vx_track, sizeof(double), n_track, fp_tracks_out);
                    fwrite(vy_track, sizeof(double), n_track, fp_tracks_out);
                    fwrite(vz_track, sizeof(double), n_track, fp_tracks_out);
                    fwrite(M_track, sizeof(double), n_track, fp_tracks_out);
                }

            } // for i_list
        }     // if i_rank
        SID_Barrier(SID_COMM_WORLD);
    } // for i_rank
    if(SID.I_am_Master) {
        fclose(fp_tracks_out);
        fclose(fp_props_out);
    }

    // Clean-up
    SID_free(SID_FARG track_index);
    SID_free(SID_FARG list);
    SID_free(SID_FARG i_z_track);
    SID_free(SID_FARG idx_track);
    SID_free(SID_FARG tc_track);
    SID_free(SID_FARG M_track);
    SID_free(SID_FARG x_track);
    SID_free(SID_FARG y_track);
    SID_free(SID_FARG z_track);
    SID_free(SID_FARG vx_track);
    SID_free(SID_FARG vy_track);
    SID_free(SID_FARG vz_track);

    SID_log("Done.", SID_LOG_CLOSE);
}
Ejemplo n.º 7
0
size_t SID_fread_chunked_ordered(void   *buffer,
                                 size_t  n_x_read_local,
                                 SID_fp *fp){
  int    i_chunk;
  int    i_group;
  int    i_rank;
  size_t i_x_offset_local;
  size_t n_x_read_local_bcast;
  size_t i_x_read_chunk;
  size_t i_x_offset_global;
  size_t i_x_chunk;
  size_t n_skip;
  size_t n_x_chunk;
  size_t n_x_chunk_max;
  size_t header_size;
  size_t r_val=0;
  char   filename_chunk[256];

  // Operates the same way as SID_fread_chunked() except i_x_offset_local is 
  //   computed here under the assumption that reads are done in order by rank
  i_x_offset_local=0;
#if USE_MPI
  for(i_rank=0;i_rank<SID.n_proc;i_rank++){
    n_x_read_local_bcast=n_x_read_local;
    SID_Bcast(&n_x_read_local_bcast,sizeof(size_t),i_rank,SID.COMM_WORLD);
    if(i_rank<SID.My_rank)
      i_x_offset_local+=n_x_read_local_bcast;
  }
#endif

  i_x_offset_global=fp->last_item;
  for(i_chunk=0,i_x_read_chunk=0,i_x_chunk=i_x_offset_local+i_x_offset_global;
      i_chunk<fp->chunked_header.n_chunk;
      i_chunk++){
    if(fp->i_x_start_chunk[i_chunk]<=i_x_chunk && fp->i_x_last_chunk[i_chunk]>=i_x_chunk){
      n_skip   =i_x_chunk-fp->i_x_start_chunk[i_chunk];
      n_x_chunk=MIN(n_x_read_local-i_x_read_chunk,fp->i_x_step_chunk[i_chunk]-n_skip);
    }
    else{
      n_x_chunk=0;
      n_skip   =0;
    }
    SID_Allreduce(&n_x_chunk,&n_x_chunk_max,1,SID_SIZE_T,SID_MAX,SID.COMM_WORLD);
    if(n_x_chunk_max>0){
      sprintf(filename_chunk,"%s.%d",fp->filename_root,i_chunk);
#if !USE_MPI_IO
      for(i_group=0;i_group<SID.n_proc;i_group++){
        if(SID.My_group==i_group && n_x_chunk>0){
#endif
          SID_fopen(filename_chunk,"r",fp);
          if(n_x_chunk>0){
            SID_fseek(fp,
                      1,
                      fp->header_offset[i_chunk]+n_skip*fp->chunked_header.item_size,
                      SID_SEEK_SET);
            SID_fread((char *)buffer+i_x_read_chunk*fp->chunked_header.item_size,
                      fp->chunked_header.item_size,
                      n_x_chunk,
                      fp);
            i_x_chunk     +=n_x_chunk;
            i_x_read_chunk+=n_x_chunk;
          }
          SID_fclose(fp);
#if !USE_MPI_IO
        }
        SID_Barrier(SID.COMM_WORLD);
      }
#endif
    }
  }
  SID_Allreduce(&i_x_chunk,&(fp->last_item),1,SID_SIZE_T,SID_MAX,SID.COMM_WORLD);
  //fp->last_item--;
  return(r_val);
}
Ejemplo n.º 8
0
void read_smooth(plist_info *plist,
                 char       *filename_root_in,
                 int         snapshot_number,
                 int         mode){
  char    filename[256];
  size_t  n_particles_all_mem;
  size_t  n_particles_local;
  size_t  n_particles_total;
  int     i_quantity;
  int     n_quantities=3;
  int    *used;
  char   *species_name;
  char    var_name[256];
  char    unit_name[256];
  double  unit_factor;
  int     i_file;
  size_t *ids;
  size_t *ids_index;
  int     n_particles_file;
  int     offset;
  int     n_files;
  void      *id_buf;
  size_t    *id_buf_index=NULL;
  int       *id_buf_i;
  long long *id_buf_L;
  long long *mark;
  size_t  i_particle;
  size_t  j_particle;
  void   *buffer;
  float  *local_array;
  int     n_mark;
  float  *r_smooth_array;  
  float  *rho_array;  
  float  *sigma_v_array;  
  char   *read_array;  
  double  expansion_factor;
  double  h_Hubble;
  int     flag_filefound=FALSE;
  int     flag_multifile=FALSE;
  int     flag_file_type;
  int     flag_LONGIDs;
  int     read_rank=MASTER_RANK;
  int     flag_log_sigma=FALSE;
  int     flag_log_rho=FALSE;
  FILE   *fp;

  SID_log("Reading smooth file {%s}...",SID_LOG_OPEN|SID_LOG_TIMER,filename_root_in);

  // Read header info
  SID_log("Reading header information...",SID_LOG_OPEN);
  smooth_header_info header;
  flag_filefound   =init_smooth_read(filename_root_in,snapshot_number,&flag_multifile,&flag_file_type,&header);
  SID_log("n_files    =%d",  SID_LOG_COMMENT,header.n_files);
  SID_log("n_particles=%lld",SID_LOG_COMMENT,header.n_particles_total);
  SID_log("Done.",SID_LOG_CLOSE);

  // Interpret the mode passed to this function
  int flag_logs_used   =FALSE;
  int flag_log_quantity=FALSE;
  if(check_mode_for_flag(mode,READ_SMOOTH_LOG_SIGMA)){
     flag_log_sigma=TRUE;
     flag_logs_used=TRUE;
  }
  else
     flag_log_sigma=FALSE;
  if(check_mode_for_flag(mode,READ_SMOOTH_LOG_RHO)){
     flag_log_rho  =TRUE;
     flag_logs_used=TRUE;
  }
  else
     flag_log_rho=FALSE;

  // A file was found ... 
  if(flag_filefound){
     // Communicate the header
     n_particles_file =header.n_particles_file;
     offset           =header.offset;
     n_particles_total=header.n_particles_total;
     n_files          =MAX(1,header.n_files);
     SID_Bcast(&n_particles_file, (int)sizeof(int),      read_rank,SID.COMM_WORLD);
     SID_Bcast(&offset,           (int)sizeof(int),      read_rank,SID.COMM_WORLD);
     SID_Bcast(&n_particles_total,(int)sizeof(long long),read_rank,SID.COMM_WORLD);
     SID_Bcast(&n_files,          (int)sizeof(int),      read_rank,SID.COMM_WORLD);

     // Fetch the number of particles and their ids
     species_name     =plist->species[GADGET_TYPE_DARK];
     n_particles_local=((size_t *)ADaPS_fetch(plist->data,"n_%s",    species_name))[0]; 
     n_particles_all_mem  =((size_t *)ADaPS_fetch(plist->data,"n_all_%s",species_name))[0]; 
     ids              = (size_t *)ADaPS_fetch(plist->data,"id_%s",   species_name); 
     expansion_factor =((double *)ADaPS_fetch(plist->data,"expansion_factor"))[0]; 
     h_Hubble         =((double *)ADaPS_fetch(plist->data,"h_Hubble"))[0]; 

     // Check if we are dealing with LONG IDs or not
     if(ADaPS_exist(plist->data,"flag_LONGIDs"))
       flag_LONGIDs=TRUE;
     else
       flag_LONGIDs=FALSE;

     // Sort particle IDs
     SID_log("Sorting particle IDs...",SID_LOG_OPEN|SID_LOG_TIMER);
     merge_sort(ids,(size_t)n_particles_local,&ids_index,SID_SIZE_T,SORT_COMPUTE_INDEX,FALSE);
     SID_log("Done.",SID_LOG_CLOSE);

     // Allocate arrays
     SID_log("Allocating arrays...",SID_LOG_OPEN);
     read_array=(char *)SID_calloc(sizeof(char)*n_particles_local);
     for(i_quantity=0;i_quantity<n_quantities;i_quantity++){
       switch(i_quantity){
       case 0:
         r_smooth_array=(float *)SID_malloc(sizeof(float)*n_particles_local);
         ADaPS_store(&(plist->data),r_smooth_array,"r_smooth_%s",ADaPS_DEFAULT,species_name);
         break;
       case 1:
         rho_array=(float *)SID_malloc(sizeof(float)*n_particles_local);
         ADaPS_store(&(plist->data),rho_array,"rho_%s",ADaPS_DEFAULT,species_name);
         break;
       case 2:
         sigma_v_array=(float *)SID_malloc(sizeof(float)*n_particles_local);
         ADaPS_store(&(plist->data),sigma_v_array,"sigma_v_%s",ADaPS_DEFAULT,species_name);
         break;
       }
     }
     SID_log("Done.",SID_LOG_CLOSE);

     // Read each file in turn
     pcounter_info pcounter;
     size_t n_particles_read=0;
     SID_log("Performing read...",SID_LOG_OPEN|SID_LOG_TIMER);
     SID_init_pcounter(&pcounter,n_particles_total,10);
     for(i_file=0;i_file<n_files;i_file++){
       set_smooth_filename(filename_root_in,snapshot_number,i_file,flag_multifile,flag_file_type,filename);
       if((fp=fopen(filename,"r"))!=NULL){
          fread_verify(&(header.n_particles_file), sizeof(int),      1,fp);
          fread_verify(&(header.offset),           sizeof(int),      1,fp);
          fread_verify(&(header.n_particles_total),sizeof(long long),1,fp);
          fread_verify(&(header.n_files),          sizeof(int),      1,fp);
       }
       else
          SID_trap_error("Could not open smooth file {%s}",ERROR_IO_OPEN,filename);
       n_particles_file =header.n_particles_file;
       offset           =header.offset;
       n_particles_total=header.n_particles_total;
       n_files          =MAX(1,header.n_files);
       SID_Bcast(&n_particles_file, (int)sizeof(int),      read_rank,SID.COMM_WORLD);
       SID_Bcast(&offset,           (int)sizeof(int),      read_rank,SID.COMM_WORLD);
       SID_Bcast(&n_particles_total,(int)sizeof(long long),read_rank,SID.COMM_WORLD);
       SID_Bcast(&n_files,          (int)sizeof(int),      read_rank,SID.COMM_WORLD);

       // Read IDs
       if(flag_LONGIDs){
         if(i_file==0) SID_log("(long long) IDs...",SID_LOG_CONTINUE);
         id_buf  =SID_malloc(sizeof(long long)*n_particles_file);
         id_buf_L=(long long *)id_buf;
         if(SID.My_rank==read_rank){
           fseeko(fp,(size_t)(3*n_particles_file*sizeof(float)),SEEK_CUR);
           fread_verify(id_buf,sizeof(long long),n_particles_file,fp);
         }
         SID_Barrier(SID.COMM_WORLD);
         SID_Bcast(id_buf_L,(int)(n_particles_file*sizeof(long long)),read_rank,SID.COMM_WORLD);
         merge_sort(id_buf_L,(size_t)n_particles_file,&id_buf_index,SID_SIZE_T,SORT_COMPUTE_INDEX,FALSE);
       }
       else{
         if(i_file==0) SID_log("(int) IDs...",SID_LOG_CONTINUE);
         id_buf  =SID_malloc(sizeof(int)*n_particles_file);
         id_buf_i=(int *)id_buf;
         if(SID.My_rank==read_rank){
           fseeko(fp,(size_t)(3*n_particles_file*sizeof(float)),SEEK_CUR);
           fread_verify(id_buf,sizeof(int),n_particles_file,fp);
         }
         SID_Barrier(SID.COMM_WORLD);
         SID_Bcast(id_buf_i,(int)(n_particles_file*sizeof(int)),read_rank,SID.COMM_WORLD);
         merge_sort(id_buf_i,(size_t)n_particles_file,&id_buf_index,SID_INT,SORT_COMPUTE_INDEX,FALSE);
       }

       // Create local particle mapping
       int n_mark_i=0;
       mark=(long long *)SID_malloc(sizeof(long long)*n_particles_file);
       for(i_particle=0;i_particle<n_particles_file;i_particle++) 
         mark[i_particle]=-1;
       if(flag_LONGIDs){
         for(i_particle=0,j_particle=0,n_mark=0;i_particle<n_particles_file && j_particle<n_particles_local;i_particle++){
           while(j_particle<n_particles_local-1 && ids[ids_index[j_particle]]<id_buf_L[id_buf_index[i_particle]]) j_particle++;
           if(ids[ids_index[j_particle]]==id_buf_L[id_buf_index[i_particle]]){
             mark[id_buf_index[i_particle]]=(long long)ids_index[j_particle];
             n_mark++;
             n_mark_i++;
           }
         }
       }
       else{
         for(i_particle=0,j_particle=0,n_mark=0;i_particle<n_particles_file && j_particle<n_particles_local;i_particle++){
           while(j_particle<n_particles_local-1 && ids[ids_index[j_particle]]<id_buf_i[id_buf_index[i_particle]]) j_particle++;
           if(ids[ids_index[j_particle]]==id_buf_i[id_buf_index[i_particle]]){
             mark[id_buf_index[i_particle]]=(long long)ids_index[j_particle];
             n_mark++;
             n_mark_i++;
           }
         }
       }
       SID_free(SID_FARG id_buf);
       SID_free(SID_FARG id_buf_index);

       // Move to the start of the particle quantities
       if(SID.My_rank==read_rank){
         rewind(fp);
         fread_verify(&n_particles_file, sizeof(int),      1,fp);
         fread_verify(&offset,           sizeof(int),      1,fp);
         fread_verify(&n_particles_total,sizeof(long long),1,fp);
         fread_verify(&n_files,          sizeof(int),      1,fp);
         n_files=MAX(1,n_files);
       }
       SID_Bcast(&n_particles_file, (int)sizeof(int),      read_rank,SID.COMM_WORLD);
       SID_Bcast(&offset,           (int)sizeof(int),      read_rank,SID.COMM_WORLD);
       SID_Bcast(&n_particles_total,(int)sizeof(long long),read_rank,SID.COMM_WORLD);
       SID_Bcast(&n_files,          (int)sizeof(int),      read_rank,SID.COMM_WORLD);
       buffer=SID_malloc(sizeof(float)*n_particles_file);
       for(i_quantity=0;i_quantity<n_quantities;i_quantity++){
         int flag_log_quantity;
         switch(i_quantity){
         case 0:
           sprintf(var_name,"r_smooth_%s",species_name);
           sprintf(unit_name,"Mpc");
           unit_factor=plist->length_unit/h_Hubble;
           local_array=r_smooth_array;
           break;
         case 1:
           sprintf(var_name,"rho_%s",species_name);
           sprintf(unit_name,"Msol/Mpc^3");
           unit_factor=h_Hubble*h_Hubble*plist->mass_unit/pow(plist->length_unit,3.);
           local_array=rho_array;
           break;
         case 2:
           sprintf(var_name,"sigma_v_%s",species_name);
           sprintf(unit_name,"km/s");
           unit_factor=sqrt(expansion_factor)*plist->velocity_unit;
           local_array=sigma_v_array;
           break;
         }

         // Read next quantity
         if(SID.My_rank==read_rank)
           fread_verify(buffer,sizeof(float),n_particles_file,fp);
         SID_Barrier(SID.COMM_WORLD);
         SID_Bcast(buffer,(int)(n_particles_file*sizeof(float)),read_rank,SID.COMM_WORLD);

         // Place in final array
         if(n_mark_i>0){
           if(i_quantity==0){
             for(i_particle=0;i_particle<n_particles_file;i_particle++)
               if(mark[i_particle]>=0) read_array[mark[i_particle]]=TRUE;
           }
           for(i_particle=0;i_particle<n_particles_file;i_particle++)
             if(mark[i_particle]>=0) local_array[mark[i_particle]]=((float *)buffer)[i_particle]*unit_factor;
         }
       }
       SID_free(SID_FARG mark);
       SID_free(SID_FARG buffer);
       if(SID.My_rank==read_rank)
         fclose(fp);
       n_particles_read+=n_particles_file;
       if(n_files>1)
          SID_check_pcounter(&pcounter,n_particles_read);
     } // i_file
     SID_free(SID_FARG ids_index);
     SID_Barrier(SID.COMM_WORLD);
     SID_log("Done.",SID_LOG_CLOSE);

     // Check that all particles have been treated
     size_t sum_check=0;
     for(i_particle=0;i_particle<n_particles_local;i_particle++)
        sum_check+=(size_t)read_array[i_particle];
     SID_Allreduce(SID_IN_PLACE,&sum_check,1,SID_SIZE_T,SID_SUM,SID.COMM_WORLD);
     if(sum_check!=n_particles_all_mem)
        SID_trap_error("Only %lld of %lld particles were set.",ERROR_LOGIC,sum_check,n_particles_all_mem);
     SID_free(SID_FARG read_array);

     SID_log("Summary...",SID_LOG_OPEN);
     for(i_quantity=0;i_quantity<n_quantities;i_quantity++){
       char var_name[32];
       switch(i_quantity){
       case 0:
         sprintf(var_name,"Lengths:   ");
         sprintf(unit_name,"Mpc");
         unit_factor=1./M_PER_MPC;
         local_array=r_smooth_array;
         break;
       case 1:
         sprintf(var_name,"Densities: ");
         sprintf(unit_name,"Msol/Mpc^3");
         unit_factor=M_PER_MPC*M_PER_MPC*M_PER_MPC/M_SOL;
         local_array=rho_array;
         break;
       case 2:
         sprintf(var_name,"sigmas_v's:");
         sprintf(unit_name,"km/s");
         unit_factor=1e-3;
         local_array=sigma_v_array;
         break;
       }

       // Report some stats
       float var_min,var_max,var_mean;
       calc_min_global(local_array,
                       &var_min,
                       n_particles_local,
                       SID_FLOAT,
                       CALC_MODE_DEFAULT,
                       SID.COMM_WORLD);
       calc_max_global(local_array,
                       &var_max,
                       n_particles_local,
                       SID_FLOAT,
                       CALC_MODE_DEFAULT,
                       SID.COMM_WORLD);
       calc_mean_global(local_array,
                        &var_mean,
                        n_particles_local,
                        SID_FLOAT,
                        CALC_MODE_DEFAULT,
                        SID.COMM_WORLD);

       // Remove NaN's from sigma_v's if needed
       size_t n_NaN=0;
       for(i_particle=0;i_particle<n_particles_local;i_particle++){
          if(isnan(local_array[i_particle])){
             local_array[i_particle]=1000.*0.5*(var_min+var_max);
             n_NaN++;
          }
       }

       if(n_NaN>0)
          SID_log("%s min=%e max=%e mean=%e [%s] (%lld are NaN)",
                  SID_LOG_COMMENT,
                  var_name,
                  var_min*unit_factor,
                  var_max*unit_factor,
                  var_mean*unit_factor,
                  unit_name,
                  n_NaN);
       else
          SID_log("%s min=%e max=%e mean=%e [%s]",
                  SID_LOG_COMMENT,
                  var_name,
                  var_min*unit_factor,
                  var_max*unit_factor,
                  var_mean*unit_factor,
                  unit_name);
     }
     SID_log("",SID_LOG_CLOSE|SID_LOG_NOPRINT);

     if(flag_logs_used){
        SID_log("Taking needed logs of quantities...",SID_LOG_OPEN|SID_LOG_TIMER);   
        for(i_quantity=0;i_quantity<n_quantities;i_quantity++){
          switch(i_quantity){
          case 0:
            unit_factor=1./M_PER_MPC;
            local_array=r_smooth_array;
            flag_log_quantity=FALSE;
            break;
          case 1:
            unit_factor=M_PER_MPC*M_PER_MPC*M_PER_MPC/M_SOL;
            local_array=rho_array;
            flag_log_quantity=flag_log_rho;
            break;
          case 2:
            unit_factor=1e-3;
            local_array=sigma_v_array;
            flag_log_quantity=flag_log_sigma;
            break;
          }
          if(flag_log_quantity){
             for(i_particle=0;i_particle<n_particles_local;i_particle++)
                local_array[i_particle]=take_log10(local_array[i_particle]);
          }
        }
        SID_log("Done.",SID_LOG_CLOSE);
     }
     SID_Barrier(SID.COMM_WORLD);
     SID_log("Done.",SID_LOG_CLOSE);
  }
  else
    SID_trap_error("Could not find file with root {%s}",ERROR_IO_OPEN,filename_root_in);
}