From: Magnus Lundborg Date: Mon, 26 May 2014 15:59:55 +0000 (+0200) Subject: Bug fix in the TNG library to improve reading. X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=758eba66aab63ff5697f07db6d62d5b48e90a0a8;p=alexxy%2Fgromacs.git Bug fix in the TNG library to improve reading. Reading single frame frame sets did not work properly. Fixes #1502 and partial fix of #1510. Reread frame set after getting stride length. Extra check to avoid reading past end of file when checking what data blocks are present. Change-Id: I5275382bd49b5b46ebfdebe535c53d2f09015bc0 --- diff --git a/src/external/tng_io/src/lib/tng_io.c b/src/external/tng_io/src/lib/tng_io.c index efcaaabea0..b6c6f22227 100644 --- a/src/external/tng_io/src/lib/tng_io.c +++ b/src/external/tng_io/src/lib/tng_io.c @@ -1029,6 +1029,41 @@ static tng_function_status tng_block_header_read // return(TNG_SUCCESS); // } */ + +static tng_function_status tng_reread_frame_set_at_file_pos + (tng_trajectory_t tng_data, + const int64_t pos) +{ + tng_gen_block_t block; + tng_function_status stat; + + tng_block_init(&block); + + fseek(tng_data->input_file, pos, SEEK_SET); + if(pos > 0) + { + stat = tng_block_header_read(tng_data, block); + if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET) + { + fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", pos, + __FILE__, __LINE__); + tng_block_destroy(&block); + return(TNG_FAILURE); + } + + if(tng_block_read_next(tng_data, block, + TNG_SKIP_HASH) != TNG_SUCCESS) + { + tng_block_destroy(&block); + return(TNG_CRITICAL); + } + } + + tng_block_destroy(&block); + + return(TNG_SUCCESS); +} + /** Write the header of a data block, regardless of its type * @param tng_data is a trajectory data container. * @param block is a general block container. @@ -16007,7 +16042,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length tng_function_status stat; tng_non_particle_data_t np_data; tng_particle_data_t p_data; - long file_pos; + long orig_file_pos, file_pos; int is_particle_data; if(tng_data->current_trajectory_frame_set_input_file_pos <= 0) @@ -16023,6 +16058,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length return(stat); } } + orig_file_pos = tng_data->current_trajectory_frame_set_input_file_pos; stat = tng_data_find(tng_data, block_id, &np_data); if(stat != TNG_SUCCESS) { @@ -16042,6 +16078,8 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length } if(stat != TNG_SUCCESS) { + tng_reread_frame_set_at_file_pos(tng_data, orig_file_pos); + return(stat); } stat = tng_data_find(tng_data, block_id, &np_data); @@ -16050,6 +16088,8 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length stat = tng_particle_data_find(tng_data, block_id, &p_data); if(stat != TNG_SUCCESS) { + tng_reread_frame_set_at_file_pos(tng_data, orig_file_pos); + return(stat); } else @@ -16079,6 +16119,8 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length { *stride_length = np_data->stride_length; } + tng_reread_frame_set_at_file_pos(tng_data, orig_file_pos); + return(TNG_SUCCESS); } @@ -16572,7 +16614,14 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read } else { - i = data->last_retrieved_frame + data->stride_length; + if(data->n_frames == 1) + { + i = data->last_retrieved_frame + 1; + } + else + { + i = data->last_retrieved_frame + data->stride_length; + } if(i < frame_set->first_frame || i >= frame_set->first_frame + frame_set->n_frames) { stat = tng_frame_set_of_frame_find(tng_data, i); @@ -16725,7 +16774,14 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read } else { - i = data->last_retrieved_frame + data->stride_length; + if(data->n_frames == 1) + { + i = data->last_retrieved_frame + 1; + } + else + { + i = data->last_retrieved_frame + data->stride_length; + } if(i < frame_set->first_frame || i >= frame_set->first_frame + frame_set->n_frames) { stat = tng_frame_set_of_frame_find(tng_data, i); @@ -18319,33 +18375,38 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat } } - if(frame_set->n_particle_data_blocks <= 0 || frame_set->n_data_blocks <= 0) + /* If no data blocks have been found in the frame set check what data blocks + * are present. If they have already been found do not read them again. */ + if(frame_set->n_particle_data_blocks <= 0 && frame_set->n_data_blocks <= 0) { - tng_block_init(&block); file_pos = ftell(tng_data->input_file); /* Read all blocks until next frame set block */ - stat = tng_block_header_read(tng_data, block); - while(file_pos < tng_data->input_file_len && - stat != TNG_CRITICAL && - block->id != TNG_TRAJECTORY_FRAME_SET) + if(file_pos < tng_data->input_file_len) { - stat = tng_block_read_next(tng_data, block, - TNG_USE_HASH); - if(stat != TNG_CRITICAL) + tng_block_init(&block); + stat = tng_block_header_read(tng_data, block); + while(file_pos < tng_data->input_file_len && + stat != TNG_CRITICAL && + block->id != TNG_TRAJECTORY_FRAME_SET) { - file_pos = ftell(tng_data->input_file); - if(file_pos < tng_data->input_file_len) + stat = tng_block_read_next(tng_data, block, + TNG_USE_HASH); + if(stat != TNG_CRITICAL) { - stat = tng_block_header_read(tng_data, block); + file_pos = ftell(tng_data->input_file); + if(file_pos < tng_data->input_file_len) + { + stat = tng_block_header_read(tng_data, block); + } } } - } - tng_block_destroy(&block); - if(stat == TNG_CRITICAL) - { - fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n", - file_pos, __FILE__, __LINE__); - return(stat); + tng_block_destroy(&block); + if(stat == TNG_CRITICAL) + { + fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n", + file_pos, __FILE__, __LINE__); + return(stat); + } } read_all = 1; }