void LFont::text_out( int x, int y, SDL_Surface *thisSurface, string text, unsigned long int flags ) ////////////////////////////////////////////////////////////////////////////////////////////////////// { //get the new x and y coordinates this->y = y; this->x = x; //the part of the text image going to be used SDL_Rect textImage; //align x offset if( bool( flags & LFONT_HCENTER ) ) { x = ( thisSurface->w - calc_width( text, thisSurface ) ) / 2; } else if( bool( flags & LFONT_LEFT ) ) { x = 0; } else if( bool( flags & LFONT_RIGHT ) ) { x = ( thisSurface->w - calc_width( text, thisSurface ) ); } //align the y off set if( bool( flags & LFONT_VCENTER ) ) { y = ( thisSurface->h - calc_max( text, thisSurface ).h ) / 2; } else if( bool( flags & LFONT_TOP ) ) { y = 0; } else if( bool( flags & LFONT_BOTTOM ) ) { y = ( thisSurface->h - calc_max( text, thisSurface ).h ); } //go through the string for( int stringPosition = 0; text[ stringPosition ] != '\0'; stringPosition++ )//while the current postion in the string is not a null character, keep going through the string { switch( text[ stringPosition ] )//the current postion in the string { //assign the proper surface case 'A': textImage = textSurfaces[ LFONT_A ]; break; case 'B': textImage = textSurfaces[ LFONT_B ]; break; case 'C': textImage = textSurfaces[ LFONT_C ]; break; case 'D': textImage = textSurfaces[ LFONT_D ]; break; case 'E': textImage = textSurfaces[ LFONT_E ]; break; case 'F': textImage = textSurfaces[ LFONT_F ]; break; case 'G': textImage = textSurfaces[ LFONT_G ]; break; case 'H': textImage = textSurfaces[ LFONT_H ]; break; case 'I': textImage = textSurfaces[ LFONT_I ]; break; case 'J': textImage = textSurfaces[ LFONT_J ]; break; case 'K': textImage = textSurfaces[ LFONT_K ]; break; case 'L': textImage = textSurfaces[ LFONT_L ]; break; case 'M': textImage = textSurfaces[ LFONT_M ]; break; case 'N': textImage = textSurfaces[ LFONT_N ]; break; case 'O': textImage = textSurfaces[ LFONT_O ]; break; case 'P': textImage = textSurfaces[ LFONT_P ]; break; case 'Q': textImage = textSurfaces[ LFONT_Q ]; break; case 'R': textImage = textSurfaces[ LFONT_R ]; break; case 'S': textImage = textSurfaces[ LFONT_S ]; break; case 'T': textImage = textSurfaces[ LFONT_T ]; break; case 'U': textImage = textSurfaces[ LFONT_U ]; break; case 'V': textImage = textSurfaces[ LFONT_V ]; break; case 'W': textImage = textSurfaces[ LFONT_W ]; break; case 'X': textImage = textSurfaces[ LFONT_X ]; break; case 'Y': textImage = textSurfaces[ LFONT_Y ]; break; case 'Z': textImage = textSurfaces[ LFONT_Z ]; break; case 'a': textImage = textSurfaces[ LFONT_a ]; break; case 'b': textImage = textSurfaces[ LFONT_b ]; break; case 'c': textImage = textSurfaces[ LFONT_c ]; break; case 'd': textImage = textSurfaces[ LFONT_d ]; break; case 'e': textImage = textSurfaces[ LFONT_e ]; break; case 'f': textImage = textSurfaces[ LFONT_f ]; break; case 'g': textImage = textSurfaces[ LFONT_g ]; break; case 'h': textImage = textSurfaces[ LFONT_h ]; break; case 'i': textImage = textSurfaces[ LFONT_i ]; break; case 'j': textImage = textSurfaces[ LFONT_j ]; break; case 'k': textImage = textSurfaces[ LFONT_k ]; break; case 'l': textImage = textSurfaces[ LFONT_l ]; break; case 'm': textImage = textSurfaces[ LFONT_m ]; break; case 'n': textImage = textSurfaces[ LFONT_n ]; break; case 'o': textImage = textSurfaces[ LFONT_o ]; break; case 'p': textImage = textSurfaces[ LFONT_p ]; break; case 'q': textImage = textSurfaces[ LFONT_q ]; break; case 'r': textImage = textSurfaces[ LFONT_r ]; break; case 's': textImage = textSurfaces[ LFONT_s ]; break; case 't': textImage = textSurfaces[ LFONT_t ]; break; case 'u': textImage = textSurfaces[ LFONT_u ]; break; case 'v': textImage = textSurfaces[ LFONT_v ]; break; case 'w': textImage = textSurfaces[ LFONT_w ]; break; case 'x': textImage = textSurfaces[ LFONT_x ]; break; case 'y': textImage = textSurfaces[ LFONT_y ]; break; case 'z': textImage = textSurfaces[ LFONT_z ]; break; case '0': textImage = textSurfaces[ LFONT_0 ]; break; case '1': textImage = textSurfaces[ LFONT_1 ]; break; case '2': textImage = textSurfaces[ LFONT_2 ]; break; case '3': textImage = textSurfaces[ LFONT_3 ]; break; case '4': textImage = textSurfaces[ LFONT_4 ]; break; case '5': textImage = textSurfaces[ LFONT_5 ]; break; case '6': textImage = textSurfaces[ LFONT_6 ]; break; case '7': textImage = textSurfaces[ LFONT_7 ]; break; case '8': textImage = textSurfaces[ LFONT_8 ]; break; case '9': textImage = textSurfaces[ LFONT_9 ]; break; case '!': textImage = textSurfaces[ LFONT_EXCLAIM ]; break; case '@': textImage = textSurfaces[ LFONT_AT ]; break; case '#': textImage = textSurfaces[ LFONT_HASH ]; break; case '$': textImage = textSurfaces[ LFONT_DOLLAR ]; break; case '%': textImage = textSurfaces[ LFONT_PERCENT ]; break; case '^': textImage = textSurfaces[ LFONT_CARET ]; break; case '&': textImage = textSurfaces[ LFONT_AMPERSAND ]; break; case '*': textImage = textSurfaces[ LFONT_ASTERISK ]; break; case '(': textImage = textSurfaces[ LFONT_LEFTPAREN ]; break; case ')': textImage = textSurfaces[ LFONT_RIGHTPAREN ]; break; case '-': textImage = textSurfaces[ LFONT_MINUS ]; break; case '_': textImage = textSurfaces[ LFONT_UNDERSCORE ]; break; case '=': textImage = textSurfaces[ LFONT_EQUALS ]; break; case '+': textImage = textSurfaces[ LFONT_PLUS ]; break; case '[': textImage = textSurfaces[ LFONT_LEFTBRACKET ]; break; case ']': textImage = textSurfaces[ LFONT_RIGHTBRACKET ]; break; case '{': textImage = textSurfaces[ LFONT_LEFTBRACE ]; break; case '}': textImage = textSurfaces[ LFONT_RIGHTBRACE ]; break; case ';': textImage = textSurfaces[ LFONT_SEMICOLON ]; break; case ':': textImage = textSurfaces[ LFONT_COLON ]; break; case '\'': textImage = textSurfaces[ LFONT_QUOTE ]; break; case '\"': textImage = textSurfaces[ LFONT_DBLQUOTE ]; break; case ',': textImage = textSurfaces[ LFONT_COMMA ]; break; case '.': textImage = textSurfaces[ LFONT_PERIOD ]; break; case '<': textImage = textSurfaces[ LFONT_LESS ]; break; case '>': textImage = textSurfaces[ LFONT_GREATER ]; break; case '?': textImage = textSurfaces[ LFONT_QUESTION ]; break; case '/': textImage = textSurfaces[ LFONT_SLASH ]; break; case '|': textImage = textSurfaces[ LFONT_LINE ]; break; case '\\': textImage = textSurfaces[ LFONT_BACKSLASH ]; break; case '`': textImage = textSurfaces[ LFONT_BACKQUOTE ]; break; case '~': textImage = textSurfaces[ LFONT_TILDE ]; break; case ' ': x += w; break;//if there's a space move overthe space width case '\n': x = 0; y += h; break;//if there's newline, move down the text height } // if the current character is not null, a newline or a space if( ( text[ stringPosition ] != '\0' ) && ( text[ stringPosition ] != '\n' ) && ( text[ stringPosition ] != ' ' ) ) { //if the text surface will go off the screen if( x + textImage.w > thisSurface->w ) { //if wrap is enabled if( bool( flags & LFONT_WRAP ) ) { //move down x = 0; y += h; //and align the x offset if( bool( flags & LFONT_HCENTER ) ) { x = ( thisSurface->w - calc_width( &text[ stringPosition + 1 ], thisSurface ) ) / 2; } else if( bool( flags & LFONT_LEFT ) ) { x = 0; } else if( bool( flags & LFONT_RIGHT ) ) { x = ( thisSurface->w - calc_width( &text[ stringPosition + 1 ], thisSurface ) ); } } } //stick the text surface onto the surface apply_surface( x, y, font, thisSurface, &textImage ); //and move over the x offset the width of the surface x += textImage.w; } else { //if there's a new line if( text[ stringPosition ] == '\n' ) { //align the x offset if( bool( flags & LFONT_HCENTER ) ) { x = ( thisSurface->w - calc_width( &text[ stringPosition + 1 ], thisSurface ) ) / 2; } else if( bool( flags & LFONT_LEFT ) ) { x = 0; } else if( bool( flags & LFONT_RIGHT ) ) { x = ( thisSurface->w - calc_width( &text[ stringPosition + 1 ], thisSurface ) ); } } } } }
int read_matches_header(char *filename_root_in, int i_read_start, int i_read_stop, int i_read_step, int * n_files_return, int **n_subgroups_return, int **n_groups_return, int * n_subgroups_max, int * n_groups_max, int * n_halos_max) { char filename_out[256]; char filename_out_dir[256]; char filename_out_name[256]; FILE * fp_test; FILE * fp_out; SID_fp fp_in; int i_read, k_read, l_read; int i_read_start_file; int i_read_stop_file; int i_read_step_file; int k_match; int n_k_match; char group_text_prefix[5]; int n_matches; int j_read; char filename_cat1[256]; char filename_cat2[256]; char filename_cat1_order[256]; char filename_cat2_order[256]; char filename_out_dir_snap[256]; int n_groups_1; int n_groups_1_local; int n_groups_2; int n_groups_2_local; int i_group; int buffered_count; int buffered_count_local; int j_group; int index_test; int i_rank; int * n_particles; int * n_sub_group; int * match_id = NULL; float * match_score = NULL; char cat_name_1[20]; char cat_name_2[20]; size_t * match_rank = NULL; size_t * match_index = NULL; size_t offset; plist_info plist1; plist_info plist2; void * buffer; int * buffer_int; size_t * buffer_size_t; float * buffer_float; int n_buffer_max = 1000; int n_buffer; int i_buffer; int j_buffer; int flag_sucessful_completion = GBP_TRUE; SID_log("Reading header information...", SID_LOG_OPEN); // Count the number of snapshots we are going to use and // initialize the arrays that are to be returned for(i_read = i_read_stop, (*n_files_return) = 0; i_read >= i_read_start; i_read -= i_read_step) (*n_files_return)++; (*n_subgroups_return) = (int *)SID_malloc(sizeof(int) * (*n_files_return)); (*n_groups_return) = (int *)SID_malloc(sizeof(int) * (*n_files_return)); if(SID.I_am_Master) { FILE *fp_read_header; // Loop for subgroups and then groups for(k_match = 0; k_match < 2; k_match++) { switch(k_match) { case 0: sprintf(group_text_prefix, "sub"); break; case 1: sprintf(group_text_prefix, ""); break; } // Open file and read header int i_read_start_in; int i_read_stop_in; int n_search_total_in; int n_files_in; int i_read_in; sprintf(filename_out, "%s/%sgroup_matches_header.dat", filename_root_in, group_text_prefix); if((fp_read_header = fopen(filename_out, "r")) == NULL) SID_exit_error("Could not open file {%s} when reading header information.", SID_ERROR_IO_OPEN, filename_out); SID_fread_verify(&i_read_start_in, sizeof(int), 1, fp_read_header); SID_fread_verify(&i_read_stop_in, sizeof(int), 1, fp_read_header); SID_fread_verify(&n_search_total_in, sizeof(int), 1, fp_read_header); SID_fread_verify(&n_files_in, sizeof(int), 1, fp_read_header); i_read_in = i_read_stop_in + 1; // Loop for each snapshot we want to keep int i_read_next; for(j_read = 0, i_read_next = i_read_stop; j_read < (*n_files_return); j_read++, i_read_next -= i_read_step) { // Read-forward to the desired snapshot int flag_continue = GBP_TRUE; while(flag_continue && i_read_in > i_read_start_in) { SID_fread_verify(&i_read_in, sizeof(int), 1, fp_read_header); SID_fread_verify(&n_groups_1, sizeof(int), 1, fp_read_header); fseek(fp_read_header, n_groups_1 * sizeof(int), SEEK_CUR); // Skip halo sizes if(k_match == 1) fseek(fp_read_header, n_groups_1 * sizeof(int), SEEK_CUR); // Skip n_sub_per_group if(i_read_in == i_read_next) { switch(k_match) { case 0: (*n_subgroups_return)[j_read] = n_groups_1; break; case 1: (*n_groups_return)[j_read] = n_groups_1; break; } flag_continue = GBP_FALSE; } } } fclose(fp_read_header); if(j_read != (*n_files_return)) SID_exit_error("Was not able to read the appriate number of group/subgroup sizes (i.e. %d!=%d)", SID_ERROR_LOGIC, j_read, (*n_files_return)); } } SID_Bcast((*n_subgroups_return), (*n_files_return), SID_INT, SID_MASTER_RANK, SID_COMM_WORLD); SID_Bcast((*n_groups_return), (*n_files_return), SID_INT, SID_MASTER_RANK, SID_COMM_WORLD); // Compute some maxs (useful for array allocation) calc_max((*n_subgroups_return), n_subgroups_max, (*n_files_return), SID_INT, CALC_MODE_DEFAULT); calc_max((*n_groups_return), n_groups_max, (*n_files_return), SID_INT, CALC_MODE_DEFAULT); (*n_halos_max) = GBP_MAX((*n_subgroups_max), (*n_groups_max)); SID_log("Done.", SID_LOG_CLOSE); return (flag_sucessful_completion); }
int main(int argc, char *argv[]){ char filename_tree_in[256]; int n_trees; int n_halos_total; int *n_halos; int i_tree; FILE *fp; halo_properties_SAGE_info *halos; halo_properties_SAGE_info halo; int *snap_num; size_t *snap_num_index; int i_snap,i_halo,j_halo,k_halo; int n_halos_snap; int *group_halo_first; int group_halo_last; size_t *group_halo_first_index; int *snap_index; int descendant_min,descendant_max; int progenitor_first_min,progenitor_first_max; int progenitor_next_min,progenitor_next_max; int group_halo_first_min,group_halo_first_max; int group_halo_next_min,group_halo_next_max; int snap_num_min,snap_num_max; int halo_index_min,halo_index_max; int n_gal=0; int max_snap=0; int n_halos_max; int n_subtrees; int halo_search; int flag_search; SID_init(&argc,&argv,NULL,NULL); // Fetch user inputs strcpy(filename_tree_in,argv[1]); halo_search=atoi(argv[2]); SID_log("Finding halo #%d's tree in {%s}...",SID_LOG_OPEN|SID_LOG_TIMER,halo_search,filename_tree_in); fp=fopen(filename_tree_in,"r"); fread_verify(&n_trees, sizeof(int),1,fp); fread_verify(&n_halos_total,sizeof(int),1,fp); SID_log("%d trees and %d halos",SID_LOG_COMMENT,n_trees,n_halos_total); n_halos=(int *)SID_malloc(sizeof(int)*n_trees); fread_verify(n_halos,sizeof(int),n_trees,fp); calc_max(n_halos,&n_halos_max,n_trees,SID_INT,CALC_MODE_DEFAULT); halos =(halo_properties_SAGE_info *)SID_malloc(sizeof(halo_properties_SAGE_info)*n_halos_max); for(i_tree=0,flag_search=TRUE;i_tree<n_trees && flag_search;i_tree++){ fread_verify(halos,sizeof(halo_properties_SAGE_info),n_halos[i_tree],fp); for(i_halo=0,n_subtrees=0;i_halo<n_halos[i_tree];i_halo++){ if(halos[i_halo].halo_id==halo_search){ flag_search=FALSE; SID_log("Found it in tree #%d",SID_LOG_COMMENT,i_tree); } } } if(flag_search) SID_log("COULD NOT FIND HALO #%d IN THIS FILE!",SID_LOG_COMMENT,halo_search); // Clean-up fclose(fp); SID_free((void **)&halos); SID_log("Done.",SID_LOG_CLOSE); SID_exit(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); }