diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/tng_io.c | 1798 |
1 files changed, 1067 insertions, 731 deletions
diff --git a/src/lib/tng_io.c b/src/lib/tng_io.c index 527f456..37b0b75 100644 --- a/src/lib/tng_io.c +++ b/src/lib/tng_io.c @@ -201,9 +201,11 @@ struct tng_particle_data { int64_t codec_id; /** The multiplier used for getting integer values for compression */ double compression_multiplier; - /** A 3-dimensional array of values, sized - * n_frames * n_particles * n_values_per_frame */ - union data_values ***values; + /** A 1-dimensional array of values of length + * [sizeof (datatype)] * n_frames * n_particles * n_values_per_frame */ + void *values; + /** If storing character data store it in a 3-dimensional array */ + char ****strings; }; struct tng_non_particle_data { @@ -228,8 +230,11 @@ struct tng_non_particle_data { /** Compressed data is stored as integers. This compression multiplier is * the multiplication factor to convert from integer to float/double */ double compression_multiplier; - /** A 2-dimensional array of values, sized n_frames * n_values_per_frame */ - union data_values **values; + /** A 1-dimensional array of values of length + * [sizeof (datatype)] * n_frames * n_values_per_frame */ + void *values; + /** If storing character data store it in a 3-dimensional array */ + char ***strings; }; @@ -346,6 +351,216 @@ struct tng_trajectory { }; +tng_function_status tng_util_trajectory_open(const char *filename, + const char mode, + tng_trajectory_t *tng_data_p) +{ + if(mode != 'r' && mode != 'w' && mode != 'a') + { + return(TNG_FAILURE); + } + + if(tng_trajectory_init(tng_data_p) != TNG_SUCCESS) + { + tng_trajectory_destroy(tng_data_p); + return(TNG_CRITICAL); + } + + if(mode == 'r' || mode == 'a') + { + tng_input_file_set(*tng_data_p, filename); + + // Read the file headers + tng_file_headers_read(*tng_data_p, TNG_USE_HASH); + } + + if(mode == 'w' || mode == 'a') + { + tng_output_file_set(*tng_data_p, filename); + } + + return(TNG_SUCCESS); +} + +tng_function_status tng_util_trajectory_close(tng_trajectory_t *tng_data_p) +{ + return(tng_trajectory_destroy(tng_data_p)); +} + +tng_function_status tng_util_trajectory_molecules_get(tng_trajectory_t tng_data, + int64_t *n_mols, + int64_t *molecule_cnt_list, + tng_molecule_t *mols) +{ + /* FIXME: This should return a copy of the molecules instead */ + *n_mols = tng_data->n_molecules; + + molecule_cnt_list = tng_data->molecule_cnt_list; + mols = &tng_data->molecules; + + return(TNG_SUCCESS); +} + +tng_function_status tng_util_trajectory_molecule_add(tng_trajectory_t tng_data, + const char *name, + const int64_t cnt, + tng_molecule_t *mol) +{ + tng_function_status stat; + stat = tng_molecule_add(tng_data, name, mol); + if(stat != TNG_SUCCESS) + { + return(stat); + } + stat = tng_molecule_cnt_set(tng_data, *mol, cnt); + + return(stat); +} + +tng_function_status tng_util_molecule_particles_get(tng_trajectory_t tng_data, + const tng_molecule_t mol, + int64_t *n_particles, + char ***names, + char ***types, + char ***res_names, + int64_t **res_ids, + char ***chain_names, + int64_t **chain_ids) +{ + tng_atom_t atom; + tng_residue_t res; + tng_chain_t chain; + int64_t i; + + *n_particles = mol->n_atoms; + + **names = malloc(sizeof(char *) * *n_particles); + **types = malloc(sizeof(char *) * *n_particles); + **res_names = malloc(sizeof(char *) * *n_particles); + **chain_names = malloc(sizeof(char *) * *n_particles); + *res_ids = malloc(sizeof(int64_t) * *n_particles); + *chain_ids = malloc(sizeof(int64_t) * *n_particles); + + for(i = 0; i < *n_particles; i++) + { + atom = &mol->atoms[i]; + res = atom->residue; + chain = res->chain; + *names[i] = malloc(strlen(atom->name)); + strcpy(*names[i], atom->name); + *types[i] = malloc(strlen(atom->atom_type)); + strcpy(*types[i], atom->atom_type); + *res_names[i] = malloc(strlen(res->name)); + strcpy(*res_names[i], res->name); + *chain_names[i] = malloc(strlen(chain->name)); + strcpy(*chain_names[i], chain->name); + *res_ids[i] = res->id; + *chain_ids[i] = chain->id; + } + + return(TNG_SUCCESS); +} + +tng_function_status tng_util_molecule_particles_set(tng_trajectory_t tng_data, + tng_molecule_t mol, + const int64_t n_particles, + const char **names, + const char **types, + const char **res_names, + const int64_t *res_ids, + const char **chain_names, + const int64_t *chain_ids) +{ + int64_t i; + tng_chain_t chain; + tng_residue_t residue; + tng_atom_t atom; + tng_function_status stat; + + for(i = 0; i < n_particles; i++) + { + if(tng_molecule_chain_find(tng_data, mol, chain_names[i], chain_ids[i], + &chain) == TNG_FAILURE) + { + stat = tng_molecule_chain_add(tng_data, mol, chain_names[i], + &chain); + if(stat != TNG_SUCCESS) + { + return(stat); + } + } + if(tng_chain_residue_find(tng_data, chain, res_names[i], res_ids[i], + &residue) == TNG_FAILURE) + { + stat = tng_chain_residue_add(tng_data, chain, res_names[i], + &residue); + if(stat != TNG_SUCCESS) + { + return(stat); + } + } + stat = tng_residue_atom_add(tng_data, residue, names[i], types[i], &atom); + if(stat != TNG_SUCCESS) + { + return(stat); + } + } + return(TNG_SUCCESS); +} + +tng_function_status tng_util_pos_read(tng_trajectory_t tng_data, + float *positions) +{ +} + +tng_function_status tng_util_vel_read(tng_trajectory_t tng_data, + float *velocities) +{ +} + +tng_function_status tng_util_force_read(tng_trajectory_t tng_data, + float *forces) +{ +} + +tng_function_status tng_util_pos_read_range(tng_trajectory_t tng_data, + const int64_t first_frame, + const int64_t last_frame, + float *positions) +{ +} + +tng_function_status tng_util_vel_read_range(tng_trajectory_t tng_data, + const int64_t first_frame, + const int64_t last_frame, + float *velocities) +{ +} + +tng_function_status tng_util_force_read_range(tng_trajectory_t tng_data, + const int64_t first_frame, + const int64_t last_frame, + float *forces) +{ +} + +tng_function_status tng_util_pos_write(tng_trajectory_t tng_data, + const int64_t frame_nr, + const float *positions) +{ +} + +tng_function_status tng_util_vel_write(tng_trajectory_t tng_data, + const int64_t frame_nr, + const float *velocities) +{ +} + +tng_function_status tng_util_force_write(tng_trajectory_t tng_data, + const int64_t frame_nr, + const float *forces) +{ +} /** This function swaps the byte order of a 32 bit numerical variable @@ -3641,7 +3856,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data, n_frames, 0.01, 0, tng_data->compress_algo_pos, - &new_len); + &new_len); } else { @@ -3713,7 +3928,7 @@ static tng_function_status tng_uncompress(tng_trajectory_t tng_data, printf("Cannot uncompress TNG compressed block.\n"); return(TNG_FAILURE); } - + offset = start_pos - (void *)block->block_contents; @@ -3767,6 +3982,8 @@ static tng_function_status tng_gzip_compress(tng_trajectory_t tng_data, memcpy(start_pos, dest, max_len); + free(dest); + block->block_contents_size = max_len + (block->block_contents_size - len); temp = realloc(block->block_contents, block->block_contents_size); @@ -3862,67 +4079,95 @@ static tng_function_status tng_allocate_particle_data_mem const int64_t n_particles, const int64_t n_values_per_frame) { - union data_values ***values; - int64_t i, j, k; + void ***values; + int64_t i, j, k, size; - if(data->values) + if(data->strings && data->datatype == TNG_CHAR_DATA) { for(i = data->n_frames; i--;) { for(j = n_particles; j--;) { - free(data->values[i][j]); + for(k = data->n_values_per_frame; k--;) + { + if(data->strings[i][j][k]) + { + free(data->strings[i][j][k]); + data->strings[i][j][k] = 0; + } + } + free(data->strings[i][j]); + data->strings[i][j] = 0; } - free(data->values[i]); + free(data->strings[i]); } } data->n_frames = n_frames; n_frames = tng_max(1, n_frames); data->stride_length = tng_max(1, stride_length); data->n_values_per_frame = n_values_per_frame; - values = realloc(data->values, sizeof(union data_values **) * n_frames); - - if(!values) - { - printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - sizeof(union data_values **) * n_frames, - __FILE__, __LINE__); - free(data->values); - return(TNG_CRITICAL); - } - data->values = values; - for(i = n_frames; i-- ;) + if(data->datatype == TNG_CHAR_DATA) { - data->values[i] = malloc(sizeof(union data_values *) * - n_particles); - if(!data->values[i]) - { - printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - sizeof(union data_values *) * n_particles, - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - for(j = n_particles; j--;) + data->strings = malloc(sizeof(char ***) * n_frames); + for(i = n_frames; i-- ;) { - data->values[i][j] = malloc(sizeof(union data_values) * - n_values_per_frame); - if(!data->values[i][j]) + data->strings[i] = malloc(sizeof(char **) * + n_particles); + if(!data->strings[i]) { printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - sizeof(union data_values) * n_values_per_frame, + sizeof(union data_values *) * n_particles, __FILE__, __LINE__); return(TNG_CRITICAL); } - if(data->datatype == TNG_CHAR_DATA) + for(j = n_particles; j--;) { + data->strings[i][j] = malloc(sizeof(char *) * + n_values_per_frame); + if(!data->strings[i][j]) + { + printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + sizeof(union data_values) * n_values_per_frame, + __FILE__, __LINE__); + return(TNG_CRITICAL); + } for(k = n_values_per_frame; k--;) { - data->values[i][j][k].c = 0; + data->strings[i][j][k] = 0; } } } } + else + { + switch(data->datatype) + { + case TNG_INT_DATA: + size = sizeof(int64_t); + break; + case TNG_FLOAT_DATA: + size = sizeof(float); + break; + case TNG_DOUBLE_DATA: + default: + size = sizeof(double); + } + + values = realloc(data->values, + size * (n_frames/data->stride_length) * + n_particles * n_values_per_frame); + if(!values) + { + printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + size * (n_frames/data->stride_length) * + n_particles * n_values_per_frame, + __FILE__, __LINE__); + free(data->values); + return(TNG_CRITICAL); + } + data->values = values; + } return(TNG_SUCCESS); } @@ -3970,7 +4215,7 @@ static tng_function_status tng_particle_data_read int64_t block_index, i, j, k, tot_n_particles; int size, len; unsigned long data_size; - union data_values **first_dim_values, *second_dim_values; + char ***first_dim_values, **second_dim_values; tng_particle_data_t data; tng_trajectory_frame_set_t frame_set = &tng_data->current_trajectory_frame_set; @@ -4062,6 +4307,8 @@ static tng_function_status tng_particle_data_read data->datatype = datatype; data->values = 0; + /* FIXME: Memory leak from strings. */ + data->strings = 0; data->n_frames = 0; data->codec_id = codec_id; data->compression_multiplier = multiplier; @@ -4124,70 +4371,11 @@ static tng_function_status tng_particle_data_read n_frames = tng_max(1, n_frames / stride_length); - /* FIXME: If not using a union to store data a whole dimension - * or the whole block can be read at once if byte swapping is not needed */ - switch(datatype) + if(datatype == TNG_CHAR_DATA) { - case TNG_FLOAT_DATA: for(i = 0; i < n_frames; i++) { - first_dim_values = data->values[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) - { - second_dim_values = first_dim_values[j]; - for(k = 0; k < n_values; k++) - { - memcpy(&second_dim_values[k].f, - block->block_contents+*offset, - size); - if(tng_data->input_endianness_swap_func_32) - { - if(tng_data->input_endianness_swap_func_32(tng_data, - (int32_t *)&second_dim_values[k]) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - *offset += size; - } - } - } - break; - case TNG_INT_DATA: - for(i = 0; i < n_frames; i++) - { - first_dim_values = data->values[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) - { - second_dim_values = first_dim_values[j]; - for(k = 0; k < n_values; k++) - { - memcpy(&second_dim_values[k].i, - block->block_contents+*offset, - size); - if(tng_data->input_endianness_swap_func_64) - { - if(tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)&second_dim_values[k]) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - *offset += size; - } - } - } - break; - case TNG_CHAR_DATA: - for(i = 0; i < n_frames; i++) - { - first_dim_values = data->values[i]; + first_dim_values = data->strings[i]; for(j = num_first_particle; j < num_first_particle + n_particles; j++) { @@ -4196,51 +4384,63 @@ static tng_function_status tng_particle_data_read { len = tng_min(strlen(block->block_contents+*offset) + 1, TNG_MAX_STR_LEN); - if(second_dim_values[k].c) + if(second_dim_values[k]) { - free(second_dim_values[k].c); + free(second_dim_values[k]); } - second_dim_values[k].c = malloc(len); - if(!second_dim_values[k].c) + second_dim_values[k] = malloc(len); + if(!second_dim_values[k]) { printf("Cannot allocate memory (%d bytes). %s: %d\n", len, __FILE__, __LINE__); return(TNG_CRITICAL); } - strncpy(second_dim_values[k].c, + strncpy(second_dim_values[k], block->block_contents+*offset, len); *offset += len; } } } - break; - case TNG_DOUBLE_DATA: - default: - for(i = 0; i < n_frames; i++) + } + else + { + memcpy(data->values, block->block_contents + *offset, + block->block_contents_size - *offset); + switch(datatype) { - first_dim_values = data->values[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) + case TNG_FLOAT_DATA: + if(tng_data->input_endianness_swap_func_32) { - second_dim_values = first_dim_values[j]; - for(k = 0; k < n_values; k++) + for(i = 0; i < (block->block_contents_size - *offset); i+=size) { - memcpy(&second_dim_values[k].d, - block->block_contents+*offset, - size); - if(tng_data->input_endianness_swap_func_64) + if(tng_data->input_endianness_swap_func_32(tng_data, + (int32_t *)(data->values + i)) + != TNG_SUCCESS) { - if(tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)&second_dim_values[k]) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + printf("Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); + } + } + } + break; + case TNG_INT_DATA: + case TNG_DOUBLE_DATA: + if(tng_data->input_endianness_swap_func_64) + { + for(i = 0; i < (block->block_contents_size - *offset); i+=size) + { + if(tng_data->input_endianness_swap_func_64(tng_data, + (int64_t *)(data->values + i)) + != TNG_SUCCESS) + { + printf("Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } - *offset += size; } } + break; + case TNG_CHAR_DATA: + break; } } return(TNG_SUCCESS); @@ -4267,9 +4467,8 @@ static tng_function_status tng_particle_data_block_write int64_t n_particles, num_first_particle, n_frames, stride_length; int i, j, k, offset = 0, size, len, data_start_pos; char dependency, temp, *temp_name; - double multiplier, d_temp; - float f_temp; - union data_values **first_dim_values, *second_dim_values; + double multiplier; + char ***first_dim_values, **second_dim_values; tng_trajectory_frame_set_t frame_set = &tng_data->current_trajectory_frame_set; @@ -4396,7 +4595,7 @@ static tng_function_status tng_particle_data_block_write { for(i = n_frames; i--;) { - first_dim_values = data->values[i]; + first_dim_values = data->strings[i]; for(j = num_first_particle; j < num_first_particle + n_particles; j++) { @@ -4404,7 +4603,7 @@ static tng_function_status tng_particle_data_block_write for(k = data->n_values_per_frame; k--;) { block->block_contents_size += - strlen(second_dim_values[k].c) + 1; + strlen(second_dim_values[k]) + 1; } } } @@ -4555,152 +4754,96 @@ static tng_function_status tng_particle_data_block_write } offset += sizeof(n_particles); - - if(data->values) + if(data->datatype == TNG_CHAR_DATA) { - /* FIXME: If not using a union to store data a whole dimension or the - * whole block can be written at once if byte swapping is not needed */ - switch(data->datatype) + if(data->strings) { - case TNG_FLOAT_DATA: - /* For speed reasons the compression multiplier is not used if the data - * is not compressed. */ - if(data->codec_id == TNG_UNCOMPRESSED) + for(i = 0; i < data->n_frames / stride_length; i++) { - for(i = 0; i < data->n_frames / stride_length; i++) + first_dim_values = data->strings[i]; + for(j = num_first_particle; j < num_first_particle + n_particles; + j++) { - first_dim_values = data->values[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) + second_dim_values = first_dim_values[j]; + for(k = 0; k < data->n_values_per_frame; k++) { - second_dim_values = first_dim_values[j]; - for(k = 0; k < data->n_values_per_frame; k++) - { - memcpy(block->block_contents+offset, - &second_dim_values[k].f, - size); - if(tng_data->output_endianness_swap_func_32) - { - if(tng_data->output_endianness_swap_func_32(tng_data, - (int32_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - offset += size; - } + len = strlen(second_dim_values[k]) + 1; + strncpy(block->block_contents+offset, + second_dim_values[k], len); + offset += len; } } } - else + } + } + else if(data->values) + { + memcpy(block->block_contents + offset, data->values, + block->block_contents_size - offset); + switch(data->datatype) + { + case TNG_FLOAT_DATA: + if(data->codec_id == TNG_UNCOMPRESSED) { - multiplier = data->compression_multiplier; - for(i = 0; i < data->n_frames / stride_length; i++) + if(tng_data->input_endianness_swap_func_32) { - first_dim_values = data->values[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) + for(i = 0; i < (block->block_contents_size - offset) / size; i++) { - second_dim_values = first_dim_values[j]; - for(k = 0; k < data->n_values_per_frame; k++) + if(tng_data->input_endianness_swap_func_32(tng_data, + (int32_t *)(block->block_contents + i)) + != TNG_SUCCESS) { - f_temp = second_dim_values[k].f * multiplier; - memcpy(block->block_contents+offset, - &f_temp, size); - if(tng_data->output_endianness_swap_func_32) - { - if(tng_data->output_endianness_swap_func_32(tng_data, - (int32_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - offset += size; + printf("Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } } } } - break; - - case TNG_INT_DATA: - for(i = 0; i < data->n_frames / stride_length; i++) + else { - first_dim_values = data->values[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) + multiplier = data->compression_multiplier; + for(i = 0; i < (block->block_contents_size - offset) / size; i++) { - second_dim_values = first_dim_values[j]; - for(k = 0; k < data->n_values_per_frame; k++) + *(float *)(block->block_contents + i) *= multiplier; + if(tng_data->input_endianness_swap_func_32 && + tng_data->input_endianness_swap_func_32(tng_data, + (int32_t *)(block->block_contents + i)) + != TNG_SUCCESS) { - memcpy(block->block_contents+offset, - &second_dim_values[k].i, - size); - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - offset += size; + printf("Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } } } break; - case TNG_CHAR_DATA: - for(i = 0; i < data->n_frames / stride_length; i++) + case TNG_INT_DATA: + if(tng_data->input_endianness_swap_func_64) { - first_dim_values = data->values[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) + for(i = offset; i < block->block_contents_size; i+=size) { - second_dim_values = first_dim_values[j]; - for(k = 0; k < data->n_values_per_frame; k++) + if(tng_data->input_endianness_swap_func_64(tng_data, + (int64_t *)(block->block_contents + i)) + != TNG_SUCCESS) { - len = strlen(second_dim_values[k].c) + 1; - strncpy(block->block_contents+offset, - second_dim_values[k].c, len); - offset += len; + printf("Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } } } break; case TNG_DOUBLE_DATA: - default: - /* For speed reasons the compression multiplier is not used if the data - * is not compressed.*/ if(data->codec_id == TNG_UNCOMPRESSED) { - for(i = 0; i < data->n_frames / stride_length; i++) + if(tng_data->input_endianness_swap_func_64) { - first_dim_values = data->values[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) + for(i = offset; i < block->block_contents_size; i+=size) { - second_dim_values = first_dim_values[j]; - for(k = 0; k < data->n_values_per_frame; k++) + if(tng_data->input_endianness_swap_func_64(tng_data, + (int64_t *)(block->block_contents + i)) + != TNG_SUCCESS) { - memcpy(block->block_contents+offset, - &second_dim_values[k].d, - size); - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - offset += size; + printf("Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } } } @@ -4708,34 +4851,22 @@ static tng_function_status tng_particle_data_block_write else { multiplier = data->compression_multiplier; - for(i = 0; i < data->n_frames / stride_length; i++) + for(i = offset; i < block->block_contents_size; i+=size) { - first_dim_values = data->values[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) + *(double *)(block->block_contents + i) *= multiplier; + if(tng_data->input_endianness_swap_func_64 && + tng_data->input_endianness_swap_func_64(tng_data, + (int64_t *)(block->block_contents + i)) + != TNG_SUCCESS) { - second_dim_values = first_dim_values[j]; - for(k = 0; k < data->n_values_per_frame; k++) - { - d_temp = second_dim_values[k].d * multiplier; - memcpy(block->block_contents+offset, - &d_temp, - size); - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - offset += size; - } + printf("Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } } } + break; + case TNG_CHAR_DATA: + break; } } else @@ -4858,63 +4989,79 @@ static tng_function_status tng_allocate_data_mem int64_t stride_length, const int64_t n_values_per_frame) { - union data_values **values; - int64_t i, j; + void **values; + int64_t i, j, size; - if(data->values) + if(data->strings && data->datatype == TNG_CHAR_DATA) { for(i = data->n_frames; i--;) { - if(data->datatype == TNG_CHAR_DATA) + for(j = data->n_values_per_frame; j--;) { - for(j = data->n_values_per_frame; j--;) + if(data->strings[i][j]) { - if(data->values[i][j].c) - { - free(data->values[i][j].c); - data->values[i][j].c = 0; - } + free(data->strings[i][j]); + data->strings[i][j] = 0; } } - free(data->values[i]); + free(data->strings[i]); + data->strings[i] = 0; } } data->n_frames = n_frames; data->stride_length = tng_max(1, stride_length); n_frames = tng_max(1, n_frames); data->n_values_per_frame = n_values_per_frame; - values = realloc(data->values, - sizeof(union data_values *) * - n_frames); - if(!values) - { - printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - sizeof(union data_values *) * n_frames, - __FILE__, __LINE__); - free(data->values); - return(TNG_CRITICAL); - } - data->values = values; - for(i = n_frames; i-- ;) + if(data->datatype == TNG_CHAR_DATA) { - data->values[i] = malloc(sizeof(union data_values) * - n_values_per_frame); - if(!data->values[i]) - { - printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - sizeof(union data_values) * n_values_per_frame, - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - if(data->datatype == TNG_CHAR_DATA) + data->strings = malloc(sizeof(char **) * n_frames); + for(i = n_frames; i-- ;) { + data->strings[i] = malloc(sizeof(char *) * n_values_per_frame); + if(!data->strings[i]) + { + printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + n_values_per_frame, + __FILE__, __LINE__); + return(TNG_CRITICAL); + } for(j = n_values_per_frame; j--;) { - data->values[i][j].c = 0; + data->strings[i][j] = 0; } } } + else + { + switch(data->datatype) + { + case TNG_INT_DATA: + size = sizeof(int64_t); + break; + case TNG_FLOAT_DATA: + size = sizeof(float); + break; + case TNG_DOUBLE_DATA: + default: + size = sizeof(double); + } + + values = realloc(data->values, + size * (n_frames/data->stride_length) * + n_values_per_frame); + if(!values) + { + printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + size * (n_frames/data->stride_length) * + n_values_per_frame, + __FILE__, __LINE__); + free(data->values); + return(TNG_CRITICAL); + } + data->values = values; + } + return(TNG_SUCCESS); } @@ -5045,6 +5192,8 @@ static tng_function_status tng_data_read(tng_trajectory_t tng_data, data->datatype = datatype; data->values = 0; + /* FIXME: Memory leak from strings. */ + data->strings = 0; data->n_frames = 0; data->codec_id = codec_id; data->compression_multiplier = multiplier; @@ -5090,96 +5239,70 @@ static tng_function_status tng_data_read(tng_trajectory_t tng_data, n_frames = tng_max(1, n_frames / stride_length); - /* FIXME: If not using a union to store data a whole dimension - * or the whole block can be read at once if byte swapping is not needed */ - switch(datatype) + if(datatype == TNG_CHAR_DATA) { - case TNG_FLOAT_DATA: for(i = 0; i < n_frames; i++) { for(j = 0; j < n_values; j++) { - memcpy(&data->values[i][j].f, block->block_contents+*offset, - size); - if(tng_data->input_endianness_swap_func_32) + len = tng_min(strlen(block->block_contents+*offset) + 1, + TNG_MAX_STR_LEN); + if(data->strings[i][j]) { - if(tng_data->input_endianness_swap_func_32(tng_data, - (int32_t *)&data->values[i][j]) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + free(data->strings[i][j]); + } + data->strings[i][j] = malloc(len); + if(!data->strings[i][j]) + { + printf("Cannot allocate memory (%d bytes). %s: %d\n", + len, __FILE__, __LINE__); + return(TNG_CRITICAL); } - *offset += size; + strncpy(data->strings[i][j], block->block_contents+*offset, + len); + *offset += len; } } - break; - case TNG_INT_DATA: - for(i = 0; i < n_frames; i++) + } + else + { + memcpy(data->values, block->block_contents + *offset, + block->block_contents_size - *offset); + switch(datatype) { - for(j = 0; j < n_values; j++) + case TNG_FLOAT_DATA: + if(tng_data->input_endianness_swap_func_32) { - memcpy(&data->values[i][j].i, block->block_contents+*offset, - size); - if(tng_data->input_endianness_swap_func_64) + for(i = 0; i < (block->block_contents_size - *offset); i+=size) { - if(tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)&data->values[i][j]) + if(tng_data->input_endianness_swap_func_32(tng_data, + (int32_t *)(data->values + i)) != TNG_SUCCESS) { printf("Cannot swap byte order. %s: %d\n", __FILE__, __LINE__); } } - *offset += size; - } - } - break; - case TNG_CHAR_DATA: - for(i = 0; i < n_frames; i++) - { - for(j = 0; j < n_values; j++) - { - len = tng_min(strlen(block->block_contents+*offset) + 1, - TNG_MAX_STR_LEN); - if(data->values[i][j].c) - { - free(data->values[i][j].c); - } - data->values[i][j].c = malloc(len); - if(!data->values[i][j].c) - { - printf("Cannot allocate memory (%d bytes). %s: %d\n", - len, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - strncpy(data->values[i][j].c, block->block_contents+*offset, - len); - *offset += len; } - } - break; - case TNG_DOUBLE_DATA: - default: - for(i = 0; i < n_frames; i++) - { - for(j = 0; j < n_values; j++) + break; + case TNG_INT_DATA: + case TNG_DOUBLE_DATA: + if(tng_data->input_endianness_swap_func_64) { - memcpy(&data->values[i][j].d, block->block_contents+*offset, - size); - if(tng_data->input_endianness_swap_func_64) + for(i = 0; i < (block->block_contents_size - *offset); i+=size) { if(tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)&data->values[i][j]) + (int64_t *)(data->values + i)) != TNG_SUCCESS) { printf("Cannot swap byte order. %s: %d\n", __FILE__, __LINE__); } } - *offset += size; } + break; + case TNG_CHAR_DATA: + break; } } return(TNG_SUCCESS); @@ -5203,8 +5326,7 @@ static tng_function_status tng_data_block_write(tng_trajectory_t tng_data, int64_t n_frames, stride_length; int i, j, offset = 0, size, len, data_start_pos; char temp, dependency, *temp_name; - double multiplier, d_temp; - float f_temp; + double multiplier; tng_trajectory_frame_set_t frame_set = &tng_data->current_trajectory_frame_set; @@ -5300,7 +5422,7 @@ static tng_function_status tng_data_block_write(tng_trajectory_t tng_data, { for(j = data->n_values_per_frame; j--;) { - block->block_contents_size += strlen(data->values[i][j].c) + 1; + block->block_contents_size += strlen(data->strings[i][j]) + 1; } } } @@ -5435,145 +5557,113 @@ static tng_function_status tng_data_block_write(tng_trajectory_t tng_data, offset += sizeof(data->stride_length); } - if(data->values) + if(data->datatype == TNG_CHAR_DATA) { - /* FIXME: If not using a union to store data a whole dimension or the - * whole block can be written at once if byte swapping is not needed */ + if(data->strings) + { + for(i = 0; i < n_frames / stride_length; i++) + { + for(j = 0; j < data->n_values_per_frame; j++) + { + len = strlen(data->strings[i][j]) + 1; + strncpy(block->block_contents+offset, data->strings[i][j], + len); + offset += len; + } + } + } + } + else if(data->values) + { + memcpy(block->block_contents + offset, data->values, + block->block_contents_size - offset); switch(data->datatype) { case TNG_FLOAT_DATA: - /* For speed reasons the compression multiplier is not used if the data - * is not compressed.*/ if(data->codec_id == TNG_UNCOMPRESSED) { - for(i = 0; i < n_frames / stride_length; i++) + if(tng_data->input_endianness_swap_func_32) { - for(j = 0; j < data->n_values_per_frame; j++) + for(i = 0; i < (block->block_contents_size - offset) / size; i++) { - memcpy(block->block_contents+offset, &data->values[i][j].f, - size); - if(tng_data->output_endianness_swap_func_32) + if(tng_data->input_endianness_swap_func_32(tng_data, + (int32_t *)(block->block_contents + i)) + != TNG_SUCCESS) { - if(tng_data->output_endianness_swap_func_32(tng_data, - (int32_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + printf("Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } - offset += size; } } } else { multiplier = data->compression_multiplier; - for(i = 0; i < n_frames / stride_length; i++) + for(i = 0; i < (block->block_contents_size - offset) / size; i++) { - for(j = 0; j < data->n_values_per_frame; j++) + *(float *)(block->block_contents + i) *= multiplier; + if(tng_data->input_endianness_swap_func_32 && + tng_data->input_endianness_swap_func_32(tng_data, + (int32_t *)(block->block_contents + i)) + != TNG_SUCCESS) { - f_temp = data->values[i][j].f * multiplier; - memcpy(block->block_contents+offset, &f_temp, - size); - if(tng_data->output_endianness_swap_func_32) - { - if(tng_data->output_endianness_swap_func_32(tng_data, - (int32_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - offset += size; + printf("Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } } } break; case TNG_INT_DATA: - for(i = 0; i < n_frames / stride_length; i++) + if(tng_data->input_endianness_swap_func_64) { - for(j = 0; j < data->n_values_per_frame; j++) + for(i = offset; i < block->block_contents_size; i+=size) { - memcpy(block->block_contents+offset, &data->values[i][j].i, - size); - if(tng_data->output_endianness_swap_func_64) + if(tng_data->input_endianness_swap_func_64(tng_data, + (int64_t *)(block->block_contents + i)) + != TNG_SUCCESS) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + printf("Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } - offset += size; - } - } - break; - case TNG_CHAR_DATA: - for(i = 0; i < n_frames / stride_length; i++) - { - for(j = 0; j < data->n_values_per_frame; j++) - { - len = strlen(data->values[i][j].c) + 1; - strncpy(block->block_contents+offset, data->values[i][j].c, - len); - offset += len; } } break; case TNG_DOUBLE_DATA: - default: - /* For speed reasons the compression multiplier is not used if the data - * is not compressed.*/ if(data->codec_id == TNG_UNCOMPRESSED) { - for(i = 0; i < n_frames / stride_length; i++) + if(tng_data->input_endianness_swap_func_64) { - for(j = 0; j < data->n_values_per_frame; j++) + for(i = offset; i < block->block_contents_size; i+=size) { - memcpy(block->block_contents+offset, &data->values[i][j].d, - size); - if(tng_data->output_endianness_swap_func_64) + if(tng_data->input_endianness_swap_func_64(tng_data, + (int64_t *)(block->block_contents + i)) + != TNG_SUCCESS) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + printf("Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } - offset += size; } } } else { multiplier = data->compression_multiplier; - for(i = 0; i < n_frames / stride_length; i++) + for(i = offset; i < block->block_contents_size; i+=size) { - for(j = 0; j < data->n_values_per_frame; j++) + *(double *)(block->block_contents + i) *= multiplier; + if(tng_data->input_endianness_swap_func_64 && + tng_data->input_endianness_swap_func_64(tng_data, + (int64_t *)(block->block_contents + i)) + != TNG_SUCCESS) { - d_temp = data->values[i][j].d * multiplier; - memcpy(block->block_contents+offset, &d_temp, - size); - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - printf("Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - offset += size; + printf("Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } } } + break; + case TNG_CHAR_DATA: + break; } } else @@ -7480,8 +7570,8 @@ tng_function_status tng_trajectory_init(tng_trajectory_t *tng_data_p) tng_function_status tng_trajectory_destroy(tng_trajectory_t *tng_data_p) { - int64_t n_particles; - int i; + int i, j, k, l; + int64_t n_particles, n_values_per_frame; tng_trajectory_t tng_data = *tng_data_p; tng_trajectory_frame_set_t frame_set = &tng_data->current_trajectory_frame_set; @@ -7597,7 +7687,7 @@ tng_function_status tng_trajectory_destroy(tng_trajectory_t *tng_data_p) if(tng_data->var_num_atoms_flag) { - n_particles = tng_data->current_trajectory_frame_set.n_particles; + n_particles = frame_set->n_particles; } else { @@ -7608,14 +7698,44 @@ tng_function_status tng_trajectory_destroy(tng_trajectory_t *tng_data_p) { for(i = tng_data->n_particle_data_blocks; i--; ) { - tng_particle_data_values_free(tng_data, - tng_data->non_tr_particle_data[i]. - values, 1, - n_particles, - tng_data->non_tr_particle_data[i]. - n_values_per_frame, - tng_data->non_tr_particle_data[i]. - datatype); + if(tng_data->non_tr_particle_data[i].values) + { + free(tng_data->non_tr_particle_data[i].values); + tng_data->non_tr_particle_data[i].values = 0; + } + + if(tng_data->non_tr_particle_data[i].strings) + { + n_values_per_frame = tng_data->non_tr_particle_data[i]. + n_values_per_frame; + if(tng_data->non_tr_particle_data[i].strings[0]) + { + for(j = n_particles; j--;) + { + if(tng_data->non_tr_particle_data[i].strings[0][j]) + { + for(k = n_values_per_frame; k--;) + { + if(tng_data->non_tr_particle_data[i]. + strings[0][j][k]) + { + free(tng_data->non_tr_particle_data[i]. + strings[0][j][k]); + tng_data->non_tr_particle_data[i]. + strings[0][j][k] = 0; + } + } + free(tng_data->non_tr_particle_data[i]. + strings[0][j]); + tng_data->non_tr_particle_data[i].strings[0][j] = 0; + } + } + free(tng_data->non_tr_particle_data[i].strings[0]); + tng_data->non_tr_particle_data[i].strings[0] = 0; + } + free(tng_data->non_tr_particle_data[i].strings); + tng_data->non_tr_particle_data[i].strings = 0; + } if(tng_data->non_tr_particle_data[i].block_name) { @@ -7631,10 +7751,32 @@ tng_function_status tng_trajectory_destroy(tng_trajectory_t *tng_data_p) { for(i = tng_data->n_data_blocks; i--;) { - tng_data_values_free(tng_data, - tng_data->non_tr_data[i].values, 1, - tng_data->non_tr_data[i].n_values_per_frame, - tng_data->non_tr_data[i].datatype); + if(tng_data->non_tr_data[i].values) + { + free(tng_data->non_tr_data[i].values); + tng_data->non_tr_data[i].values = 0; + } + + if(tng_data->non_tr_data[i].strings) + { + n_values_per_frame = tng_data->non_tr_data[i]. + n_values_per_frame; + if(tng_data->non_tr_data[i].strings[0]) + { + for(j = n_values_per_frame; j--;) + { + if(tng_data->non_tr_data[i].strings[0][j]) + { + free(tng_data->non_tr_data[i].strings[0][j]); + tng_data->non_tr_data[i].strings[0][j] = 0; + } + } + free(tng_data->non_tr_data[i].strings[0]); + tng_data->non_tr_data[i].strings[0] = 0; + } + free(tng_data->non_tr_data[i].strings); + tng_data->non_tr_data[i].strings = 0; + } if(tng_data->non_tr_data[i].block_name) { @@ -7664,16 +7806,49 @@ tng_function_status tng_trajectory_destroy(tng_trajectory_t *tng_data_p) { for(i = frame_set->n_particle_data_blocks; i--; ) { - tng_particle_data_values_free(tng_data, - frame_set->tr_particle_data[i]. - values, - frame_set->tr_particle_data[i]. - n_frames, - n_particles, - frame_set->tr_particle_data[i]. - n_values_per_frame, - frame_set->tr_particle_data[i]. - datatype); + if(frame_set->tr_particle_data[i].values) + { + free(frame_set->tr_particle_data[i].values); + frame_set->tr_particle_data[i].values = 0; + } + + if(frame_set->tr_particle_data[i].strings) + { + n_values_per_frame = frame_set->tr_particle_data[i]. + n_values_per_frame; + for(j = frame_set->tr_particle_data[i].n_frames; j--;) + { + if(frame_set->tr_particle_data[i].strings[j]) + { + for(k = n_particles; k--;) + { + if(frame_set->tr_particle_data[i]. + strings[j][k]) + { + for(l = n_values_per_frame; l--;) + { + if(frame_set->tr_particle_data[i]. + strings[j][k][l]) + { + free(frame_set->tr_particle_data[i]. + strings[j][k][l]); + frame_set->tr_particle_data[i]. + strings[j][k][l] = 0; + } + } + free(frame_set->tr_particle_data[i]. + strings[j][k]); + frame_set->tr_particle_data[i]. + strings[j][k] = 0; + } + } + free(frame_set->tr_particle_data[i].strings[j]); + frame_set->tr_particle_data[i].strings[j] = 0; + } + } + free(frame_set->tr_particle_data[i].strings); + frame_set->tr_particle_data[i].strings = 0; + } if(frame_set->tr_particle_data[i].block_name) { @@ -7689,12 +7864,36 @@ tng_function_status tng_trajectory_destroy(tng_trajectory_t *tng_data_p) { for(i = frame_set->n_data_blocks; i--;) { - tng_data_values_free(tng_data, - frame_set->tr_data[i].values, - frame_set->tr_data[i].n_frames, - frame_set->tr_data[i]. - n_values_per_frame, - frame_set->tr_data[i].datatype); + if(frame_set->tr_data[i].values) + { + free(frame_set->tr_data[i].values); + frame_set->tr_data[i].values = 0; + } + + if(frame_set->tr_data[i].strings) + { + n_values_per_frame = frame_set->tr_data[i]. + n_values_per_frame; + for(j = frame_set->tr_data[i].n_frames; j--;) + { + if(frame_set->tr_data[i].strings[j]) + { + for(k = n_values_per_frame; k--;) + { + if(frame_set->tr_data[i].strings[j][k]) + { + free(frame_set->tr_data[i].strings[j][k]); + frame_set->tr_data[i].strings[j][k] = 0; + } + } + free(frame_set->tr_data[i].strings[j]); + frame_set->tr_data[i].strings[j] = 0; + } + } + free(frame_set->tr_data[i].strings); + frame_set->tr_data[i].strings = 0; + } + if(frame_set->tr_data[i].block_name) { free(frame_set->tr_data[i].block_name); @@ -10020,7 +10219,7 @@ tng_function_status tng_data_block_add(tng_trajectory_t tng_data, int i, j, block_index, size, len; tng_trajectory_frame_set_t frame_set; tng_non_particle_data_t data; - union data_values *first_dim_values; + char **first_dim_values; void *orig; frame_set = &tng_data->current_trajectory_frame_set; @@ -10091,6 +10290,8 @@ tng_function_status tng_data_block_add(tng_trajectory_t tng_data, data->stride_length = tng_max(stride_length, 1); data->values = 0; + /* FIXME: Memory leak from strings. */ + data->strings = 0; data->n_values_per_frame = n_values_per_frame; data->n_frames = n_frames; data->codec_id = codec_id; @@ -10105,8 +10306,6 @@ tng_function_status tng_data_block_add(tng_trajectory_t tng_data, case TNG_INT_DATA: size = sizeof(int64_t); break; - case TNG_CHAR_DATA: - size = sizeof(char); case TNG_DOUBLE_DATA: default: size = sizeof(double); @@ -10132,84 +10331,40 @@ tng_function_status tng_data_block_add(tng_trajectory_t tng_data, frame_set->n_written_frames = n_frames; } - switch(datatype) + if(datatype == TNG_CHAR_DATA) { - case TNG_FLOAT_DATA: for(i = 0; i < n_frames / stride_length; i++) { - first_dim_values = data->values[i]; - for(j = 0; j < n_values_per_frame; j++) - { - memcpy(&first_dim_values[j].f, - new_data, size); - new_data += size; - } - } - break; - case TNG_CHAR_DATA: - for(i = 0; i < n_frames / stride_length; i++) - { - first_dim_values = data->values[i]; + first_dim_values = data->strings[i]; for(j = 0; j < n_values_per_frame; j++) { len = tng_min(strlen(new_data) + 1, TNG_MAX_STR_LEN); - if(first_dim_values[j].c) + if(first_dim_values[j]) { - free(first_dim_values[j].c); + free(first_dim_values[j]); } - first_dim_values[j].c = malloc(len); - if(!first_dim_values[j].c) + first_dim_values[j] = malloc(len); + if(!first_dim_values[j]) { printf("Cannot allocate memory (%d bytes). %s: %d\n", len, __FILE__, __LINE__); return(TNG_CRITICAL); } - strncpy(first_dim_values[j].c, + strncpy(first_dim_values[j], new_data, len); new_data += len; } } - break; - case TNG_INT_DATA: - for(i = 0; i < n_frames / stride_length; i++) - { - first_dim_values = data->values[i]; - for(j = 0; j < n_values_per_frame; j++) - { - memcpy(&first_dim_values[j].i, - new_data, size); - new_data += size; - } - } - break; - case TNG_DOUBLE_DATA: - default: - for(i = 0; i < n_frames / stride_length; i++) - { - first_dim_values = data->values[i]; - for(j = 0; j < n_values_per_frame; j++) - { - memcpy(&first_dim_values[j].d, - new_data, size); - new_data += size; - } - } + } + else + { + memcpy(data->values, new_data, size * n_frames / stride_length * + n_values_per_frame); } new_data = orig; } -// else -// { -// for(i = 0; i < n_frames / stride_length; i++) -// { -// first_dim_values = data->values[i]; -// for(j = 0; j < n_values_per_frame; j++) -// { -// first_dim_values[j].d = 0; -// } -// } -// } return(TNG_SUCCESS); } @@ -10229,7 +10384,7 @@ tng_function_status tng_particle_data_block_add(tng_trajectory_t tng_data, { int i, j, k, block_index, size, len; int64_t tot_n_particles; - union data_values **first_dim_values, *second_dim_values; + char ***first_dim_values, **second_dim_values; tng_trajectory_frame_set_t frame_set; tng_particle_data_t data; void *orig; @@ -10304,6 +10459,8 @@ tng_function_status tng_particle_data_block_add(tng_trajectory_t tng_data, data->stride_length = tng_max(stride_length, 1); data->values = 0; + /* FIXME: Memory leak from strings. */ + data->strings = 0; data->n_values_per_frame = n_values_per_frame; data->n_frames = n_frames; data->codec_id = codec_id; @@ -10340,48 +10497,11 @@ tng_function_status tng_particle_data_block_add(tng_trajectory_t tng_data, frame_set->n_written_frames = n_frames; } - switch(datatype) + if(datatype == TNG_CHAR_DATA) { - case TNG_FLOAT_DATA: - size = sizeof(float); - for(i = 0; i < n_frames / stride_length; i++) - { - first_dim_values = data->values[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) - { - second_dim_values = first_dim_values[j]; - for(k = 0; k < n_values_per_frame; k++) - { - memcpy(&second_dim_values[k].f, - new_data, size); - new_data += size; - } - } - } - break; - case TNG_INT_DATA: - size = sizeof(int64_t); for(i = 0; i < n_frames / stride_length; i++) { - first_dim_values = data->values[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) - { - second_dim_values = first_dim_values[j]; - for(k = 0; k < n_values_per_frame; k++) - { - memcpy(&second_dim_values[k].i, - new_data, size); - new_data += size; - } - } - } - break; - case TNG_CHAR_DATA: - for(i = 0; i < n_frames / stride_length; i++) - { - first_dim_values = data->values[i]; + first_dim_values = data->strings[i]; for(j = num_first_particle; j < num_first_particle + n_particles; j++) { @@ -10390,65 +10510,46 @@ tng_function_status tng_particle_data_block_add(tng_trajectory_t tng_data, { len = tng_min(strlen(new_data) + 1, TNG_MAX_STR_LEN); - if(second_dim_values[k].c) + if(second_dim_values[k]) { - free(second_dim_values[k].c); + free(second_dim_values[k]); } - second_dim_values[k].c = malloc(len); - if(!second_dim_values[k].c) + second_dim_values[k] = malloc(len); + if(!second_dim_values[k]) { printf("Cannot allocate memory (%d bytes). %s: %d\n", len, __FILE__, __LINE__); return(TNG_CRITICAL); } - strncpy(second_dim_values[k].c, + strncpy(second_dim_values[k], new_data, len); new_data += len; } } } - break; - case TNG_DOUBLE_DATA: - default: - size = sizeof(double); - for(i = 0; i < n_frames / stride_length; i++) + } + else + { + switch(datatype) { - first_dim_values = data->values[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) - { - second_dim_values = first_dim_values[j]; - for(k = 0; k < n_values_per_frame; k++) - { - memcpy(&second_dim_values[k].d, - new_data, size); - new_data += size; - } - } + case TNG_CHAR_DATA: + break; + case TNG_INT_DATA: + size = sizeof(int64_t); + break; + case TNG_FLOAT_DATA: + size = sizeof(float); + break; + case TNG_DOUBLE_DATA: + default: + size = sizeof(double); } - break; + memcpy(data->values, new_data, size * n_frames / stride_length * + n_particles * n_values_per_frame); } new_data = orig; } - /* Otherwise fill the data block with zeroes */ -// else -// { -// for(i = 0; i < n_frames / stride_length; i++) -// { -// first_dim_values = data->values[i]; -// for(j = num_first_particle; j < num_first_particle + n_particles; -// j++) -// { -// second_dim_values = first_dim_values[j]; -// for(k = 0; k < n_values_per_frame; k++) -// { -// second_dim_values[k].d = 0; -// } -// } -// } -// } - return(TNG_SUCCESS); } @@ -11393,6 +11494,55 @@ tng_function_status tng_frame_particle_data_write(tng_trajectory_t tng_data, return(TNG_SUCCESS); } +static tng_function_status tng_data_values_alloc + (const tng_trajectory_t tng_data, + union data_values ***values, + const int64_t n_frames, + const int64_t n_values_per_frame, + const tng_data_type type) +{ + int64_t i; + tng_function_status stat; + + if(*values) + { + stat = tng_data_values_free(tng_data, *values, n_frames, + n_values_per_frame, + type); + if(stat != TNG_SUCCESS) + { + printf("Cannot free particle data values. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + } + *values = malloc(sizeof(union data_values **) * n_frames); + if(!*values) + { + printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + sizeof(union data_values **) * n_frames, + __FILE__, __LINE__); + return(TNG_CRITICAL); + + } + + for(i = n_frames; i--;) + { + (*values)[i] = malloc(sizeof(union data_values) * + n_values_per_frame); + if(!(*values)[i]) + { + printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + sizeof(union data_values) * n_values_per_frame, + __FILE__, __LINE__); + free(values); + values = 0; + return(TNG_CRITICAL); + } + } + return(TNG_SUCCESS); +} + tng_function_status tng_data_values_free(const tng_trajectory_t tng_data, union data_values **values, const int64_t n_frames, @@ -11429,6 +11579,71 @@ tng_function_status tng_data_values_free(const tng_trajectory_t tng_data, return(TNG_SUCCESS); } +static tng_function_status tng_particle_data_values_alloc + (const tng_trajectory_t tng_data, + union data_values ****values, + const int64_t n_frames, + const int64_t n_particles, + const int64_t n_values_per_frame, + const tng_data_type type) +{ + int64_t i, j; + tng_function_status stat; + + if(*values) + { + stat = tng_particle_data_values_free(tng_data, *values, n_frames, + n_particles, n_values_per_frame, + type); + if(stat != TNG_SUCCESS) + { + printf("Cannot free particle data values. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + } + *values = malloc(sizeof(union data_values **) * n_frames); + if(!*values) + { + printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + sizeof(union data_values **) * n_frames, + __FILE__, __LINE__); + return(TNG_CRITICAL); + + } + + for(i = n_frames; i--;) + { + (*values)[i] = malloc(sizeof(union data_values *) * + n_particles); + if(!(*values)[i]) + { + printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + sizeof(union data_values *) * n_particles, + __FILE__, __LINE__); + free(*values); + *values = 0; + return(TNG_CRITICAL); + } + for(j = n_particles; j--;) + { + (*values)[i][j] = malloc(sizeof(union data_values) * + n_values_per_frame); + if(!(*values)[i][j]) + { + printf("Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + sizeof(union data_values *) * n_particles, + __FILE__, __LINE__); + tng_particle_data_values_free(tng_data, *values, n_frames, + n_particles, n_values_per_frame, + type); + *values = 0; + return(TNG_CRITICAL); + } + } + } + return(TNG_SUCCESS); +} tng_function_status tng_particle_data_values_free (const tng_trajectory_t tng_data, @@ -11482,8 +11697,8 @@ tng_function_status tng_data_get(tng_trajectory_t tng_data, tng_data_type *type) { int64_t file_pos; - int i, j, block_index, len; - tng_non_particle_data_t data, new_data; + int i, j, block_index, len, size; + tng_non_particle_data_t data; tng_trajectory_frame_set_t frame_set = &tng_data->current_trajectory_frame_set; tng_gen_block_t block; @@ -11561,25 +11776,21 @@ tng_function_status tng_data_get(tng_trajectory_t tng_data, } } - /* A bit hackish to create a new data struct before returning the data */ - new_data = malloc(sizeof(struct tng_non_particle_data)); - - new_data->n_values_per_frame = 0; - new_data->n_frames = 0; - new_data->values = 0; - new_data->datatype = data->datatype; + *n_frames = tng_max(1, data->n_frames); *n_values_per_frame = data->n_values_per_frame; - if(tng_allocate_data_mem(tng_data, new_data, data->n_frames, - data->stride_length, *n_values_per_frame) - != TNG_SUCCESS) + *type = data->datatype; + + if(*values == 0) { - return(TNG_CRITICAL); + if(tng_data_values_alloc(tng_data, values, *n_frames, + *n_values_per_frame, + *type) + != TNG_SUCCESS) + { + return(TNG_CRITICAL); + } } - *n_frames = tng_max(1, data->n_frames); - - *values = new_data->values; - *type = data->datatype; switch(*type) { case TNG_CHAR_DATA: @@ -11587,42 +11798,163 @@ tng_function_status tng_data_get(tng_trajectory_t tng_data, { for(j=*n_values_per_frame; j--;) { - len = strlen(data->values[i][j].c) + 1; + len = strlen(data->strings[i][j]) + 1; (*values)[i][j].c = malloc(len); - strncpy((*values)[i][j].c, data->values[i][j].c, len); + strncpy((*values)[i][j].c, data->strings[i][j], len); } } break; case TNG_INT_DATA: + size = sizeof(int); for(i=*n_frames; i--;) { for(j=*n_values_per_frame; j--;) { - (*values)[i][j].i = data->values[i][j].i; + (*values)[i][j].i = *(int *)(data->values + size * + (i*(*n_values_per_frame) + j)); } } break; case TNG_FLOAT_DATA: + size = sizeof(float); for(i=*n_frames; i--;) { for(j=*n_values_per_frame; j--;) { - (*values)[i][j].f = data->values[i][j].f; + (*values)[i][j].f = *(float *)(data->values + size * + (i*(*n_values_per_frame) + j)); } } break; case TNG_DOUBLE_DATA: default: + size = sizeof(double); for(i=*n_frames; i--;) { for(j=*n_values_per_frame; j--;) { - (*values)[i][j].d = data->values[i][j].d; + (*values)[i][j].d = *(double *)(data->values + size * + (i*(*n_values_per_frame) + j)); } } } - free(new_data); + return(TNG_SUCCESS); +} + +tng_function_status tng_data_vector_get(tng_trajectory_t tng_data, + const int64_t block_id, + void **values, + int64_t *n_frames, + int64_t *n_values_per_frame, + tng_data_type *type) +{ + int64_t file_pos; + int i, block_index, data_size, size; + tng_non_particle_data_t data; + tng_trajectory_frame_set_t frame_set = + &tng_data->current_trajectory_frame_set; + tng_gen_block_t block; + tng_function_status stat; + + block_index = -1; + /* See if there is a data block of this ID. + * Start checking the last read frame set */ + for(i = frame_set->n_data_blocks; i-- ;) + { + data = &frame_set->tr_data[i]; + if(data->block_id == block_id) + { + block_index = i; + break; + } + } + + if(block_index < 0) + { + /* If the data block was not found in the frame set + * look for it in the non-trajectory data (in tng_data). */ + for(i = tng_data->n_data_blocks; i-- ;) + { + data = &tng_data->non_tr_data[i]; + if(data->block_id == block_id) + { + block_index = i; + break; + } + } + if(block_index < 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) + { + /* Use hash by default */ + stat = tng_block_read_next(tng_data, block, + TNG_USE_HASH); + if(stat != TNG_CRITICAL) + { + 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) + { + printf("Cannot read block header at pos %"PRId64". %s: %d\n", + file_pos, __FILE__, __LINE__); + return(stat); + } + + for(i = frame_set->n_data_blocks; i-- ;) + { + data = &frame_set->tr_data[i]; + if(data->block_id == block_id) + { + block_index = i; + break; + } + } + if(block_index < 0) + { + return(TNG_FAILURE); + } + } + } + + *type = data->datatype; + + switch(*type) + { + case TNG_CHAR_DATA: + return(TNG_FAILURE); + case TNG_INT_DATA: + size = sizeof(int64_t); + break; + case TNG_FLOAT_DATA: + size = sizeof(float); + break; + case TNG_DOUBLE_DATA: + default: + size = sizeof(double); + } + + *n_frames = tng_max(1, data->n_frames); + *n_values_per_frame = data->n_values_per_frame; + + data_size = (*n_frames / data->stride_length) * size * + *n_values_per_frame; + + *values = malloc(data_size); + + memcpy(values, data->values, data_size); return(TNG_SUCCESS); } @@ -11637,8 +11969,8 @@ tng_function_status tng_data_interval_get(tng_trajectory_t tng_data, tng_data_type *type) { int64_t i, j, n_frames, file_pos, current_frame_pos; - int block_index, len; - tng_non_particle_data_t data, new_data; + int block_index, len, size; + tng_non_particle_data_t data; tng_trajectory_frame_set_t frame_set; tng_gen_block_t block; tng_function_status stat; @@ -11701,32 +12033,19 @@ tng_function_status tng_data_interval_get(tng_trajectory_t tng_data, } n_frames = end_frame_nr - start_frame_nr + 1; - - /* A bit hackish to create a new data struct before returning the data */ + *n_values_per_frame = data->n_values_per_frame; + *type = data->datatype; if(*values == 0) { - new_data = malloc(sizeof(struct tng_non_particle_data)); - - new_data->n_values_per_frame = 0; - new_data->n_frames = 0; - new_data->values = 0; - new_data->datatype = data->datatype; - *n_values_per_frame = data->n_values_per_frame; - if(tng_allocate_data_mem(tng_data, new_data, n_frames, - data->stride_length, - data->n_values_per_frame) != TNG_SUCCESS) + if(tng_data_values_alloc(tng_data, values, n_frames, + *n_values_per_frame, + *type) != TNG_SUCCESS) { - free(new_data); return(TNG_CRITICAL); } - - *values = new_data->values; - - free(new_data); } - *type = data->datatype; current_frame_pos = start_frame_nr - frame_set->first_frame; /* It's not very elegant to reuse so much of the code in the different case * statements, but it's unnecessarily slow to have the switch-case block @@ -11747,14 +12066,15 @@ tng_function_status tng_data_interval_get(tng_trajectory_t tng_data, } for(j=*n_values_per_frame; j--;) { - len = strlen(data->values[current_frame_pos][j].c) + 1; + len = strlen(data->strings[current_frame_pos][j]) + 1; (*values)[i][j].c = malloc(len); - strncpy((*values)[i][j].c, data->values[current_frame_pos][j].c, len); + strncpy((*values)[i][j].c, data->strings[current_frame_pos][j], len); } current_frame_pos++; } break; case TNG_INT_DATA: + size = sizeof(int); for(i=0; i<n_frames; i++) { if(current_frame_pos == frame_set->n_frames) @@ -11768,12 +12088,15 @@ tng_function_status tng_data_interval_get(tng_trajectory_t tng_data, } for(j=*n_values_per_frame; j--;) { - (*values)[i][j].i = data->values[current_frame_pos][j].i; + (*values)[i][j].i = *(int *)(data->values + size * + (current_frame_pos * + (*n_values_per_frame) + j)); } current_frame_pos++; } break; case TNG_FLOAT_DATA: + size = sizeof(float); for(i=0; i<n_frames; i++) { if(current_frame_pos == frame_set->n_frames) @@ -11787,13 +12110,16 @@ tng_function_status tng_data_interval_get(tng_trajectory_t tng_data, } for(j=*n_values_per_frame; j--;) { - (*values)[i][j].f = data->values[current_frame_pos][j].f; + (*values)[i][j].f = *(float *)(data->values + size * + (current_frame_pos * + (*n_values_per_frame) + j)); } current_frame_pos++; } break; case TNG_DOUBLE_DATA: default: + size = sizeof(double); for(i=0; i<n_frames; i++) { if(current_frame_pos == frame_set->n_frames) @@ -11807,7 +12133,9 @@ tng_function_status tng_data_interval_get(tng_trajectory_t tng_data, } for(j=*n_values_per_frame; j--;) { - (*values)[i][j].d = data->values[current_frame_pos][j].d; + (*values)[i][j].d = *(double *)(data->values + size * + (current_frame_pos * + (*n_values_per_frame) + j)); } current_frame_pos++; } @@ -11825,9 +12153,9 @@ tng_function_status tng_particle_data_get(tng_trajectory_t tng_data, int64_t *n_values_per_frame, tng_data_type *type) { - int64_t i, j, k, mapping, file_pos; - int block_index, len; - tng_particle_data_t data, new_data; + int64_t i, j, k, mapping, file_pos, i_step; + int block_index, len, size; + tng_particle_data_t data; tng_trajectory_frame_set_t frame_set = &tng_data->current_trajectory_frame_set; tng_gen_block_t block; @@ -11921,34 +12249,21 @@ tng_function_status tng_particle_data_get(tng_trajectory_t tng_data, *n_particles = tng_data->n_particles; } - /* A bit hackish to create a new data struct before returning the data */ + *n_frames = tng_max(1, data->n_frames); + *n_values_per_frame = data->n_values_per_frame; + *type = data->datatype; if(*values == 0) { - new_data = malloc(sizeof(struct tng_particle_data)); - - new_data->n_values_per_frame = 0; - new_data->n_frames = 0; - new_data->values = 0; - new_data->datatype = data->datatype; - *n_values_per_frame = data->n_values_per_frame; - if(tng_allocate_particle_data_mem(tng_data, new_data, data->n_frames, - data->stride_length, - *n_particles, data->n_values_per_frame) + if(tng_particle_data_values_alloc(tng_data, values, *n_frames, + *n_particles, *n_values_per_frame, + *type) != TNG_SUCCESS) { - free(new_data); return(TNG_CRITICAL); } - - *n_frames = tng_max(1, data->n_frames); - - *values = new_data->values; - - free(new_data); } - *type = data->datatype; /* It's not very elegant to reuse so much of the code in the different case * statements, but it's unnecessarily slow to have the switch-case block * inside the for loops. */ @@ -11962,14 +12277,17 @@ tng_function_status tng_particle_data_get(tng_trajectory_t tng_data, tng_particle_mapping_get_real_particle(frame_set, j, &mapping); for(k=*n_values_per_frame; k--;) { - len = strlen(data->values[i][j][k].c) + 1; - (*values)[i][j][k].c = malloc(len); - strncpy((*values)[i][mapping][k].c, data->values[i][j][k].c, len); + len = strlen(data->strings[i][j][k]) + 1; + (*values)[i][mapping][k].c = malloc(len); + strncpy((*values)[i][mapping][k].c, + data->strings[i][j][k], len); } } } break; case TNG_INT_DATA: + size = sizeof(int); + i_step = (*n_particles) * (*n_values_per_frame); for(i=*n_frames; i--;) { for(j=*n_particles; j--;) @@ -11977,12 +12295,17 @@ tng_function_status tng_particle_data_get(tng_trajectory_t tng_data, tng_particle_mapping_get_real_particle(frame_set, j, &mapping); for(k=*n_values_per_frame; k--;) { - (*values)[i][mapping][k].i = data->values[i][j][k].i; + (*values)[i][mapping][k].i = *(int *) + (data->values + size * + (i * i_step + j * + (*n_values_per_frame) + k)); } } } break; case TNG_FLOAT_DATA: + size = sizeof(float); + i_step = (*n_particles) * (*n_values_per_frame); for(i=*n_frames; i--;) { for(j=*n_particles; j--;) @@ -11990,13 +12313,18 @@ tng_function_status tng_particle_data_get(tng_trajectory_t tng_data, tng_particle_mapping_get_real_particle(frame_set, j, &mapping); for(k=*n_values_per_frame; k--;) { - (*values)[i][mapping][k].f = data->values[i][j][k].f; + (*values)[i][mapping][k].f = *(float *) + (data->values + size * + (i * i_step + j * + (*n_values_per_frame) + k)); } } } break; case TNG_DOUBLE_DATA: default: + size = sizeof(double); + i_step = (*n_particles) * (*n_values_per_frame); for(i=*n_frames; i--;) { for(j=*n_particles; j--;) @@ -12004,7 +12332,10 @@ tng_function_status tng_particle_data_get(tng_trajectory_t tng_data, tng_particle_mapping_get_real_particle(frame_set, j, &mapping); for(k=*n_values_per_frame; k--;) { - (*values)[i][mapping][k].d = data->values[i][j][k].d; + (*values)[i][mapping][k].d = *(double *) + (data->values + size * + (i * i_step + j * + (*n_values_per_frame) + k)); } } } @@ -12024,9 +12355,9 @@ tng_function_status tng_particle_data_interval_get(tng_trajectory_t tng_data, int64_t *n_values_per_frame, tng_data_type *type) { - int64_t i, j, k, mapping, n_frames, file_pos, current_frame_pos; - int block_index, len; - tng_particle_data_t data, new_data; + int64_t i, j, k, mapping, n_frames, file_pos, current_frame_pos, i_step; + int block_index, len, size; + tng_particle_data_t data; tng_trajectory_frame_set_t frame_set; tng_gen_block_t block; tng_function_status stat; @@ -12101,33 +12432,20 @@ tng_function_status tng_particle_data_interval_get(tng_trajectory_t tng_data, } n_frames = end_frame_nr - start_frame_nr + 1; - - /* A bit hackish to create a new data struct before returning the data */ + *n_values_per_frame = data->n_values_per_frame; + *type = data->datatype; if(*values == 0) { - new_data = malloc(sizeof(struct tng_particle_data)); - - new_data->n_values_per_frame = 0; - new_data->n_frames = 0; - new_data->values = 0; - new_data->datatype = data->datatype; - *n_values_per_frame = data->n_values_per_frame; - if(tng_allocate_particle_data_mem(tng_data, new_data, n_frames, - data->stride_length, - *n_particles, data->n_values_per_frame) != - TNG_SUCCESS) + if(tng_particle_data_values_alloc(tng_data, values, n_frames, + *n_particles, *n_values_per_frame, + *type) + != TNG_SUCCESS) { - free(new_data); return(TNG_CRITICAL); } - - *values = new_data->values; - - free(new_data); } - *type = data->datatype; current_frame_pos = start_frame_nr - frame_set->first_frame; /* It's not very elegant to reuse so much of the code in the different case * statements, but it's unnecessarily slow to have the switch-case block @@ -12151,15 +12469,17 @@ tng_function_status tng_particle_data_interval_get(tng_trajectory_t tng_data, tng_particle_mapping_get_real_particle(frame_set, j, &mapping); for(k=*n_values_per_frame; k--;) { - len = strlen(data->values[current_frame_pos][j][k].c) + 1; - (*values)[i][j][k].c = malloc(len); - strncpy((*values)[i][j][k].c, data->values[current_frame_pos][j][k].c, len); + len = strlen(data->strings[current_frame_pos][j][k]) + 1; + (*values)[i][mapping][k].c = malloc(len); + strncpy((*values)[i][mapping][k].c, data->strings[current_frame_pos][j][k], len); } } current_frame_pos++; } break; case TNG_INT_DATA: + size = sizeof(int); + i_step = (*n_particles) * (*n_values_per_frame); for(i=0; i<n_frames; i++) { if(current_frame_pos == frame_set->n_frames) @@ -12176,13 +12496,19 @@ tng_function_status tng_particle_data_interval_get(tng_trajectory_t tng_data, tng_particle_mapping_get_real_particle(frame_set, j, &mapping); for(k=*n_values_per_frame; k--;) { - (*values)[i][mapping][k].i = data->values[current_frame_pos][j][k].i; + (*values)[i][mapping][k].i = *(int *) + (data->values + size * + (current_frame_pos * + i_step + j * + (*n_values_per_frame) + k)); } } current_frame_pos++; } break; case TNG_FLOAT_DATA: + size = sizeof(float); + i_step = (*n_particles) * (*n_values_per_frame); for(i=0; i<n_frames; i++) { if(current_frame_pos == frame_set->n_frames) @@ -12199,7 +12525,11 @@ tng_function_status tng_particle_data_interval_get(tng_trajectory_t tng_data, tng_particle_mapping_get_real_particle(frame_set, j, &mapping); for(k=*n_values_per_frame; k--;) { - (*values)[i][mapping][k].f = data->values[current_frame_pos][j][k].f; + (*values)[i][mapping][k].f = *(float *) + (data->values + size * + (current_frame_pos * + i_step + j * + (*n_values_per_frame) + k)); } } current_frame_pos++; @@ -12207,6 +12537,8 @@ tng_function_status tng_particle_data_interval_get(tng_trajectory_t tng_data, break; case TNG_DOUBLE_DATA: default: + size = sizeof(double); + i_step = (*n_particles) * (*n_values_per_frame); for(i=0; i<n_frames; i++) { if(current_frame_pos == frame_set->n_frames) @@ -12223,7 +12555,11 @@ tng_function_status tng_particle_data_interval_get(tng_trajectory_t tng_data, tng_particle_mapping_get_real_particle(frame_set, j, &mapping); for(k=*n_values_per_frame; k--;) { - (*values)[i][mapping][k].d = data->values[current_frame_pos][j][k].d; + (*values)[i][mapping][k].d = *(double *) + (data->values + size * + (current_frame_pos * + i_step + j * + (*n_values_per_frame) + k)); } } current_frame_pos++; |