diff options
-rw-r--r-- | include/tng_io.h | 29 | ||||
-rw-r--r-- | src/lib/tng_io.c | 277 |
2 files changed, 249 insertions, 57 deletions
diff --git a/include/tng_io.h b/include/tng_io.h index 9cc8a8a..e46cd60 100644 --- a/include/tng_io.h +++ b/include/tng_io.h @@ -4293,6 +4293,35 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_double_write const double time, const double *box_shape); +/** + * @brief High-level function for getting the compression method and + * multiplication factor of the next frame of a specific data block. + * @param tng_data is the trajectory to use. + * @param block_id is the ID number of the block containing the data of + * interest. + * @param codec_id will be set to the value of the codec_id of the + * compression of the data block. See tng_compression for more details. + * @param factor will be set to the multiplication factor applied to + * the values before compression, in order to get integers from them. + * factor is 1/precision. + * @pre \code tng_data != 0 \endcode The trajectory container (tng_data) + * must be initialised before using it. + * @pre \code codec_id != 0 \endcode The pointer to the returned codec id + * must not be a NULL pointer. + * @pre \code factor != 0 \endcode The pointer to the returned multiplication + * factor must not be a NULL pointer. + * @details This function reads ahead until a data block of the requested ID + * is found. + * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if a minor error + * has occured (such as invalid mode) or TNG_CRITICAL (2) if a major error + * has occured. + */ +tng_function_status DECLSPECDLLEXPORT tng_util_compression_next_frame_get + (tng_trajectory_t tng_data, + const int64_t block_id, + char *codec_id, + float *factor); + /** @} */ /* end of group2 */ diff --git a/src/lib/tng_io.c b/src/lib/tng_io.c index e60aab5..97fb283 100644 --- a/src/lib/tng_io.c +++ b/src/lib/tng_io.c @@ -722,6 +722,35 @@ static tng_function_status tng_output_file_init(tng_trajectory_t tng_data) return(TNG_SUCCESS); } +static tng_function_status DECLSPECDLLEXPORT tng_frame_set_particle_mapping_free(tng_trajectory_t tng_data) +{ + tng_trajectory_frame_set_t frame_set; + tng_particle_mapping_t mapping; + int64_t i; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + + frame_set = &tng_data->current_trajectory_frame_set; + + if(frame_set->n_mapping_blocks && frame_set->mappings) + { + for(i = frame_set->n_mapping_blocks; i--;) + { + mapping = &frame_set->mappings[i]; + if(mapping->real_particle_numbers) + { + free(mapping->real_particle_numbers); + mapping->real_particle_numbers = 0; + } + } + free(frame_set->mappings); + frame_set->mappings = 0; + frame_set->n_mapping_blocks = 0; + } + + return(TNG_SUCCESS); +} + /** Setup a file block container. * @param block_p a pointer to memory to initialise as a file block container. * @details Memory is allocated during initialisation. @@ -2974,7 +3003,6 @@ static tng_function_status tng_frame_set_block_read tng_bool same_hash; tng_trajectory_frame_set_t frame_set = &tng_data->current_trajectory_frame_set; - tng_particle_mapping_t mapping; if(tng_input_file_init(tng_data) != TNG_SUCCESS) { @@ -3023,21 +3051,7 @@ static tng_function_status tng_frame_set_block_read tng_data->current_trajectory_frame_set_input_file_pos = file_pos; - if(frame_set->n_mapping_blocks && frame_set->mappings) - { - for(i = frame_set->n_mapping_blocks; i--;) - { - mapping = &frame_set->mappings[i]; - if(mapping->real_particle_numbers) - { - free(mapping->real_particle_numbers); - mapping->real_particle_numbers = 0; - } - } - free(frame_set->mappings); - frame_set->mappings = 0; - frame_set->n_mapping_blocks = 0; - } + tng_frame_set_particle_mapping_free(tng_data); if(tng_data->first_trajectory_frame_set_input_file_pos <= 0) { @@ -3847,6 +3861,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data, { int nalgo; int new_len; + int *alt_algo = 0; char *dest, *temp; int64_t algo_find_n_frames; unsigned long offset; @@ -3866,7 +3881,32 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data, if(block->id == TNG_TRAJ_POSITIONS) { - if(!tng_data->compress_algo_pos) + /* If there is only one frame in this frame set and there might be more + * do not store the algorithm as the compression algorithm, but find + * the best one without storing it */ + if(n_frames == 1 && tng_data->frame_set_n_frames > 1) + { + nalgo = tng_compress_nalgo(); + alt_algo=malloc(nalgo * sizeof *tng_data->compress_algo_pos); + if(type == TNG_FLOAT_DATA) + { + dest = tng_compress_pos_float_find_algo(start_pos, (int)n_particles, + (int)n_frames, + (float)tng_data->compression_precision, + 0, alt_algo, + &new_len); + + } + else + { + dest = tng_compress_pos_find_algo(start_pos, (int)n_particles, + (int)n_frames, + tng_data->compression_precision, + 0, alt_algo, + &new_len); + } + } + else if(!tng_data->compress_algo_pos) { if(n_frames > 10) { @@ -3938,7 +3978,32 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data, } else if(block->id == TNG_TRAJ_VELOCITIES) { - if(!tng_data->compress_algo_vel) + /* If there is only one frame in this frame set and there might be more + * do not store the algorithm as the compression algorithm, but find + * the best one without storing it */ + if(n_frames == 1 && tng_data->frame_set_n_frames > 1) + { + nalgo = tng_compress_nalgo(); + alt_algo=malloc(nalgo * sizeof *tng_data->compress_algo_pos); + if(type == TNG_FLOAT_DATA) + { + dest = tng_compress_vel_float_find_algo(start_pos, (int)n_particles, + (int)n_frames, + (float)tng_data->compression_precision, + 0, alt_algo, + &new_len); + + } + else + { + dest = tng_compress_vel_find_algo(start_pos, (int)n_particles, + (int)n_frames, + tng_data->compression_precision, + 0, alt_algo, + &new_len); + } + } + else if(!tng_data->compress_algo_vel) { if(n_frames > 10) { @@ -4017,6 +4082,11 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data, offset = (unsigned long)((char *)start_pos - block->block_contents); + if(alt_algo) + { + free(alt_algo); + } + block->block_contents_size = new_len + offset; temp = realloc(block->block_contents, block->block_contents_size); @@ -4859,6 +4929,8 @@ static tng_function_status tng_particle_data_block_write /* If the frame set is finished before writing the full number of frames make sure the data block is not longer than the frame set. */ n_frames = tng_min_i64(n_frames, frame_set->n_frames); + + n_frames -= (data->first_frame_with_data - frame_set->first_frame); } frame_step = (n_frames % stride_length) ? n_frames / stride_length + 1: @@ -5775,6 +5847,8 @@ static tng_function_status tng_data_block_write(tng_trajectory_t tng_data, /* If the frame set is finished before writing the full number of frames make sure the data block is not longer than the frame set. */ n_frames = tng_min_i64(n_frames, frame_set->n_frames); + + n_frames -= (data->first_frame_with_data - frame_set->first_frame); } frame_step = (n_frames % stride_length) ? n_frames / stride_length + 1: @@ -6285,13 +6359,15 @@ static tng_function_status tng_data_block_contents_read } } offset += sizeof(stride_length); + n_frames = first_frame_with_data - + tng_data->current_trajectory_frame_set.n_frames; } else { first_frame_with_data = 0; stride_length = 1; + n_frames = tng_data->current_trajectory_frame_set.n_frames; } - n_frames = tng_data->current_trajectory_frame_set.n_frames; } else { @@ -8699,8 +8775,6 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *t tng_trajectory_t tng_data = *tng_data_p; tng_trajectory_frame_set_t frame_set; - tng_particle_mapping_t mapping; - if(!*tng_data_p) { return(TNG_SUCCESS); @@ -8788,21 +8862,7 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *t tng_data->forcefield_name = 0; } - if(frame_set->mappings) - { - for(i = frame_set->n_mapping_blocks; i--;) - { - mapping = &frame_set->mappings[i]; - if(mapping->real_particle_numbers) - { - free(mapping->real_particle_numbers); - mapping->real_particle_numbers = 0; - } - } - free(frame_set->mappings); - frame_set->mappings = 0; - frame_set->n_mapping_blocks = 0; - } + tng_frame_set_particle_mapping_free(tng_data); if(frame_set->molecule_cnt_list) { @@ -11804,10 +11864,8 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_new const int64_t first_frame, const int64_t n_frames) { - int64_t i; tng_gen_block_t block; tng_trajectory_frame_set_t frame_set; - tng_particle_mapping_t mapping; FILE *temp = tng_data->input_file; int64_t curr_pos; @@ -11838,21 +11896,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_new ftell(tng_data->output_file); /* Clear mappings if they remain. */ - if(frame_set->n_mapping_blocks && frame_set->mappings) - { - for(i = frame_set->n_mapping_blocks; i--;) - { - mapping = &frame_set->mappings[i]; - if(mapping->real_particle_numbers) - { - free(mapping->real_particle_numbers); - mapping->real_particle_numbers = 0; - } - } - free(frame_set->mappings); - frame_set->mappings = 0; - frame_set->n_mapping_blocks = 0; - } + tng_frame_set_particle_mapping_free(tng_data); tng_data->n_trajectory_frame_sets++; @@ -12168,6 +12212,8 @@ tng_function_status DECLSPECDLLEXPORT tng_data_block_add data->n_frames = n_frames; data->codec_id = codec_id; data->compression_multiplier = 1.0; + /* FIXME: This can cause problems. */ + data->first_frame_with_data = frame_set->first_frame; switch(datatype) { @@ -12320,6 +12366,8 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_block_add data->n_frames = n_frames; data->codec_id = codec_id; data->compression_multiplier = 1.0; + /* FIXME: This can cause problems. */ + data->first_frame_with_data = frame_set->first_frame; if(block_type_flag == TNG_TRAJECTORY_BLOCK && tng_data->var_num_atoms_flag) { @@ -15703,8 +15751,6 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read *retrieved_time = 0; } -// printf("TEMP: First frame time: %e, i: %"PRId64", First frame: %"PRId64", Time per frame: %e\n", -// frame_set->first_frame_time, i, frame_set->first_frame, tng_data->time_per_frame); // printf("TNG library: TEMP: first_frame_with_data: %"PRId64"\n", data->first_frame_with_data); if(data->stride_length > 1) @@ -15713,7 +15759,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read } else { - i = (i - frame_set->first_frame) / data->stride_length; + i = (i - frame_set->first_frame); } tng_num_particles_get(tng_data, &n_particles); @@ -15845,7 +15891,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read } else { - i = (i - frame_set->first_frame) / data->stride_length; + i = (i - frame_set->first_frame); } *data_type = data->datatype; @@ -17189,3 +17235,120 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_double_write TNG_GZIP_COMPRESSION)); } +tng_function_status DECLSPECDLLEXPORT tng_util_compression_next_frame_get + (tng_trajectory_t tng_data, + const int64_t block_id, + char *codec_id, + float *factor) +{ + tng_trajectory_frame_set_t frame_set; + tng_particle_data_t p_data; + tng_non_particle_data_t np_data; + tng_function_status stat; + int64_t i; + long file_pos; + int block_type = -1; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(codec_id, "TNG library: The pointer to the returned codec id must not be a NULL pointer."); + TNG_ASSERT(factor, "TNG library: The pointer to the returned multiplication factor must not be a NULL pointer."); + + frame_set = &tng_data->current_trajectory_frame_set; + + stat = tng_particle_data_find(tng_data, block_id, &p_data); + if(stat == TNG_SUCCESS) + { + block_type = TNG_PARTICLE_BLOCK_DATA; + } + else + { + stat = tng_data_find(tng_data, block_id, &np_data); + if(stat == TNG_SUCCESS) + { + block_type = TNG_NON_PARTICLE_BLOCK_DATA; + } + else + { + stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id); + file_pos = ftell(tng_data->input_file); + while(stat != TNG_SUCCESS && file_pos < tng_data->input_file_len) + { + stat = tng_frame_set_read_next_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id); + file_pos = ftell(tng_data->input_file); + } + if(stat != TNG_SUCCESS) + { + return(stat); + } + stat = tng_particle_data_find(tng_data, block_id, &p_data); + if(stat == TNG_SUCCESS) + { + block_type = TNG_PARTICLE_BLOCK_DATA; + } + else + { + stat = tng_data_find(tng_data, block_id, &np_data); + if(stat == TNG_SUCCESS) + { + block_type = TNG_NON_PARTICLE_BLOCK_DATA; + } + else + { + return(stat); + } + } + } + } + if(block_type == TNG_PARTICLE_BLOCK_DATA) + { + if(p_data->last_retrieved_frame < 0) + { + i = p_data->first_frame_with_data; + } + else + { + i = p_data->last_retrieved_frame + p_data->stride_length; + } + } + else if(block_type == TNG_NON_PARTICLE_BLOCK_DATA) + { + if(np_data->last_retrieved_frame < 0) + { + i = np_data->first_frame_with_data; + } + else + { + i = np_data->last_retrieved_frame + np_data->stride_length; + } + } + else + { + return(TNG_FAILURE); + } + 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); + if(stat != TNG_SUCCESS) + { + return(stat); + } + stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id); + if(stat != TNG_SUCCESS) + { + printf("Cannot read data blocks of frame set. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + } + if(block_type == TNG_PARTICLE_BLOCK_DATA) + { + *codec_id = p_data->codec_id; + *factor = p_data->compression_multiplier; + } + else if(block_type == TNG_NON_PARTICLE_BLOCK_DATA) + { + *codec_id = np_data->codec_id; + *factor = np_data->compression_multiplier; + } + return(TNG_SUCCESS); +} |