summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Lundborg <lundborg.magnus@gmail.com>2012-12-21 16:07:09 (GMT)
committerMagnus Lundborg <lundborg.magnus@gmail.com>2012-12-21 16:07:09 (GMT)
commit076cdb5ad3e91e074bf29c5bf2d2b47ba80119ca (patch)
tree8a70e0a72ac6dc14e224ea196a5cfd9fd1f59d1e
parente9e701487d602e494ff262af1bd4ce8b6c221f75 (diff)
Make data writing work for one frame at a time. Other minor fixes.
-rw-r--r--src/lib/tng_io.c470
-rw-r--r--src/lib/tng_io.h21
-rw-r--r--src/tests/tng_io_testing.c115
3 files changed, 522 insertions, 84 deletions
diff --git a/src/lib/tng_io.c b/src/lib/tng_io.c
index bd8b6fd..0319ce2 100644
--- a/src/lib/tng_io.c
+++ b/src/lib/tng_io.c
@@ -5078,7 +5078,7 @@ tng_function_status tng_atom_type_set(tng_trajectory_t tng_data,
return(TNG_SUCCESS);
}
-tng_function_status tng_init_atom(tng_atom_t atom)
+static tng_function_status tng_atom_init(tng_atom_t atom)
{
atom->name = 0;
atom->atom_type = 0;
@@ -5086,7 +5086,7 @@ tng_function_status tng_init_atom(tng_atom_t atom)
return(TNG_SUCCESS);
}
-tng_function_status tng_destroy_atom(tng_atom_t atom)
+static tng_function_status tng_atom_destroy(tng_atom_t atom)
{
if(atom->name)
{
@@ -5490,7 +5490,7 @@ tng_function_status tng_residue_atom_add(tng_trajectory_t tng_data,
residue->atoms = *atom;
}
- tng_init_atom(*atom);
+ tng_atom_init(*atom);
tng_atom_name_set(tng_data, *atom, atom_name);
tng_atom_type_set(tng_data, *atom, atom_type);
@@ -5564,7 +5564,7 @@ tng_function_status tng_molecule_destroy(tng_molecule_t molecule)
{
for(i = molecule->n_atoms; i--;)
{
- tng_destroy_atom(&molecule->atoms[i]);
+ tng_atom_destroy(&molecule->atoms[i]);
}
free(molecule->atoms);
molecule->atoms = 0;
@@ -6569,9 +6569,7 @@ tng_function_status tng_frame_set_find(tng_trajectory_t tng_data,
file_pos = frame_set->long_stride_next_frame_set_file_pos;
if(file_pos > 0)
{
- fseek(tng_data->input_file,
- file_pos,
- SEEK_SET);
+ fseek(tng_data->input_file, file_pos, SEEK_SET);
/* Read block headers first to see what block is found. */
stat = tng_block_header_read(tng_data, block);
if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -7107,7 +7105,6 @@ tng_function_status tng_frame_set_write(tng_trajectory_t tng_data,
}
tng_block_init(&block);
- block->id = TNG_TRAJECTORY_FRAME_SET;
if(tng_frame_set_block_write(tng_data, block, hash_mode) != TNG_SUCCESS)
{
@@ -7765,14 +7762,15 @@ tng_function_status tng_frame_data_write(tng_trajectory_t tng_data,
const void *values,
const tng_hash_mode hash_mode)
{
- int64_t i, block_index, header_pos, file_pos;
+ int64_t header_pos, file_pos;
int64_t output_file_len, n_values_per_frame, size, contents_size;
- int64_t header_size;
+ int64_t header_size, temp_first, temp_last, temp_current;
tng_gen_block_t block;
tng_trajectory_frame_set_t frame_set;
FILE *temp = tng_data->input_file;
- tng_non_particle_data_t data;
+ struct tng_non_particle_data data;
tng_function_status stat;
+ char dependency, sparse_data, datatype;
if(tng_output_file_init(tng_data, FALSE) != TNG_SUCCESS)
{
@@ -7781,26 +7779,54 @@ tng_function_status tng_frame_data_write(tng_trajectory_t tng_data,
return(TNG_CRITICAL);
}
+ temp_first = tng_data->first_trajectory_frame_set_input_file_pos;
+ temp_last = tng_data->last_trajectory_frame_set_input_file_pos;
+ temp_current = tng_data->current_trajectory_frame_set_input_file_pos;
+ tng_data->first_trajectory_frame_set_input_file_pos =
+ tng_data->first_trajectory_frame_set_output_file_pos;
+ tng_data->last_trajectory_frame_set_input_file_pos =
+ tng_data->last_trajectory_frame_set_output_file_pos;
+ tng_data->current_trajectory_frame_set_input_file_pos =
+ tng_data->current_trajectory_frame_set_output_file_pos;
+
tng_data->input_file = tng_data->output_file;
stat = tng_frame_set_find(tng_data, frame_nr);
if(stat != TNG_SUCCESS)
{
+ tng_data->input_file = temp;
+ tng_data->first_trajectory_frame_set_input_file_pos = temp_first;
+ tng_data->last_trajectory_frame_set_input_file_pos = temp_last;
+ tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
return(stat);
}
- tng_data->input_file = temp;
+ tng_block_init(&block);
file_pos = ftell(tng_data->output_file);
fseek(tng_data->output_file, 0, SEEK_END);
output_file_len = ftell(tng_data->output_file);
fseek(tng_data->output_file, file_pos, SEEK_SET);
-
- tng_block_init(&block);
- /* Read all block headers until next frame set block */
+ /* Read past the frame set block first */
+ stat = tng_block_header_read(tng_data, block);
+ if(stat == TNG_CRITICAL)
+ {
+ tng_block_destroy(&block);
+ tng_data->input_file = temp;
+
+ tng_data->first_trajectory_frame_set_input_file_pos = temp_first;
+ tng_data->last_trajectory_frame_set_input_file_pos = temp_last;
+ tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
+ return(stat);
+ }
+ fseek(tng_data->output_file, block->block_contents_size,
+ SEEK_CUR);
+
+ /* Read all block headers until next frame set block or
+ * until the wanted block id is found */
stat = tng_block_header_read(tng_data, block);
while(file_pos < output_file_len &&
stat != TNG_CRITICAL &&
@@ -7817,6 +7843,10 @@ tng_function_status tng_frame_data_write(tng_trajectory_t tng_data,
if(stat == TNG_CRITICAL)
{
tng_block_destroy(&block);
+ tng_data->input_file = temp;
+ tng_data->first_trajectory_frame_set_input_file_pos = temp_first;
+ tng_data->last_trajectory_frame_set_input_file_pos = temp_last;
+ tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
return(stat);
}
@@ -7826,26 +7856,106 @@ tng_function_status tng_frame_data_write(tng_trajectory_t tng_data,
header_pos = file_pos;
frame_set = &tng_data->current_trajectory_frame_set;
- block_index = -1;
- /* See if there is already a data block of this ID.
- * Start checking the last read frame set */
- for(i = frame_set->n_data_blocks; i--;)
+ fread(&datatype, sizeof(datatype), 1, tng_data->input_file);
+ fread(&dependency, sizeof(dependency), 1, tng_data->input_file);
+ data.datatype = datatype;
+
+ if(!(dependency & TNG_FRAME_DEPENDENT) ||
+ (dependency & TNG_PARTICLE_DEPENDENT))
{
- data = &frame_set->tr_data[i];
- if(data->block_id == block_id)
+ tng_block_destroy(&block);
+ tng_data->input_file = temp;
+
+ tng_data->first_trajectory_frame_set_input_file_pos = temp_first;
+ tng_data->last_trajectory_frame_set_input_file_pos = temp_last;
+ tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
+ return(TNG_FAILURE);
+ }
+
+ fread(&sparse_data, sizeof(sparse_data), 1, tng_data->input_file);
+
+ fread(&data.n_values_per_frame, sizeof(data.n_values_per_frame), 1,
+ tng_data->input_file);
+ if(tng_data->endianness_64 != TNG_BIG_ENDIAN_64)
+ {
+ if(tng_swap_byte_order_64(tng_data, &data.n_values_per_frame) != TNG_SUCCESS)
{
- block_index = i;
- break;
+ printf("Cannot swap byte order to get big endian. %s: %d\n",
+ __FILE__, __LINE__);
}
}
- if(block_index < 0)
+ fread(&data.codec_id, sizeof(data.codec_id), 1,
+ tng_data->input_file);
+ if(tng_data->endianness_64 != TNG_BIG_ENDIAN_64)
{
- tng_block_destroy(&block);
- return(TNG_FAILURE);
+ if(tng_swap_byte_order_64(tng_data, &data.codec_id) != TNG_SUCCESS)
+ {
+ printf("Cannot swap byte order to get big endian. %s: %d\n",
+ __FILE__, __LINE__);
+ }
}
-
- switch(data->datatype)
+
+ if(data.codec_id != TNG_UNCOMPRESSED)
+ {
+ fread(&data.compression_multiplier,
+ sizeof(data.compression_multiplier), 1, tng_data->input_file);
+ if(tng_data->endianness_64 != TNG_BIG_ENDIAN_64)
+ {
+ if(tng_swap_byte_order_64(tng_data, (int64_t *)
+ &data.compression_multiplier) !=
+ TNG_SUCCESS)
+ {
+ printf("Cannot swap byte order to get big endian. %s: %d\n",
+ __FILE__, __LINE__);
+ }
+ }
+ }
+ else
+ {
+ data.compression_multiplier = 1;
+ }
+
+ if(sparse_data)
+ {
+ fread(&data.first_frame_with_data, sizeof(data.first_frame_with_data),
+ 1, tng_data->input_file);
+ if(tng_data->endianness_64 != TNG_BIG_ENDIAN_64)
+ {
+ if(tng_swap_byte_order_64(tng_data, &data.first_frame_with_data) !=
+ TNG_SUCCESS)
+ {
+ printf("Cannot swap byte order to get big endian. %s: %d\n",
+ __FILE__, __LINE__);
+ }
+ }
+
+ fread(&data.stride_length, sizeof(data.stride_length),
+ 1, tng_data->input_file);
+ if(tng_data->endianness_64 != TNG_BIG_ENDIAN_64)
+ {
+ if(tng_swap_byte_order_64(tng_data, &data.stride_length) !=
+ TNG_SUCCESS)
+ {
+ printf("Cannot swap byte order to get big endian. %s: %d\n",
+ __FILE__, __LINE__);
+ }
+ }
+ }
+ else
+ {
+ data.first_frame_with_data = 0;
+ data.stride_length = 1;
+ }
+ data.n_frames = tng_data->current_trajectory_frame_set.n_frames;
+
+ tng_data->input_file = temp;
+
+ tng_data->first_trajectory_frame_set_input_file_pos = temp_first;
+ tng_data->last_trajectory_frame_set_input_file_pos = temp_last;
+ tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
+
+ switch(data.datatype)
{
case(TNG_INT_DATA):
size = sizeof(int64_t);
@@ -7863,12 +7973,12 @@ tng_function_status tng_frame_data_write(tng_trajectory_t tng_data,
return(TNG_FAILURE);
}
- size *= data->n_values_per_frame;
-
- n_values_per_frame = data->n_values_per_frame;
+ n_values_per_frame = data.n_values_per_frame;
- file_pos = (frame_nr - data->first_frame_with_data) * n_values_per_frame /
- data->stride_length;
+ file_pos = (frame_nr - (frame_set->first_frame +
+ data.first_frame_with_data)) /
+ data.stride_length;
+ file_pos *= size * n_values_per_frame;
if(file_pos > contents_size)
{
@@ -7882,9 +7992,11 @@ tng_function_status tng_frame_data_write(tng_trajectory_t tng_data,
fwrite(values, n_values_per_frame, size, tng_data->output_file);
+ fflush(tng_data->output_file);
+
/* If the last frame has been written update the hash */
- if(hash_mode == TNG_USE_HASH && (frame_nr + data->stride_length -
- data->first_frame_with_data) / data->stride_length >=
+ if(hash_mode == TNG_USE_HASH && (frame_nr + data.stride_length -
+ data.first_frame_with_data) / data.stride_length >=
frame_set->n_frames)
{
tng_md5_hash_update(tng_data, block, header_pos, header_pos +
@@ -7899,17 +8011,22 @@ tng_function_status tng_frame_data_write(tng_trajectory_t tng_data,
tng_function_status tng_frame_particle_data_write(tng_trajectory_t tng_data,
const int64_t frame_nr,
const int64_t block_id,
- const void **values,
+ const int64_t val_first_particle,
+ const int64_t val_n_particles,
+ const void *values,
const tng_hash_mode hash_mode)
{
- int64_t i, block_index, header_pos, file_pos, n_particles;
+ int64_t header_pos, file_pos, tot_n_particles;
int64_t output_file_len, n_values_per_frame, size, contents_size;
- int64_t header_size;
+ int64_t header_size, temp_first, temp_last, temp_current;
+ int64_t mapping_block_end_pos, num_first_particle, block_n_particles;
tng_gen_block_t block;
tng_trajectory_frame_set_t frame_set;
FILE *temp = tng_data->input_file;
- tng_particle_data_t data;
+ struct tng_particle_data data;
tng_function_status stat;
+ tng_particle_mapping_t mapping;
+ char dependency, sparse_data, datatype;
if(tng_output_file_init(tng_data, FALSE) != TNG_SUCCESS)
{
@@ -7918,31 +8035,130 @@ tng_function_status tng_frame_particle_data_write(tng_trajectory_t tng_data,
return(TNG_CRITICAL);
}
+ temp_first = tng_data->first_trajectory_frame_set_input_file_pos;
+ temp_last = tng_data->last_trajectory_frame_set_input_file_pos;
+ temp_current = tng_data->current_trajectory_frame_set_input_file_pos;
+ tng_data->first_trajectory_frame_set_input_file_pos =
+ tng_data->first_trajectory_frame_set_output_file_pos;
+ tng_data->last_trajectory_frame_set_input_file_pos =
+ tng_data->last_trajectory_frame_set_output_file_pos;
+ tng_data->current_trajectory_frame_set_input_file_pos =
+ tng_data->current_trajectory_frame_set_output_file_pos;
+
tng_data->input_file = tng_data->output_file;
stat = tng_frame_set_find(tng_data, frame_nr);
-
+
if(stat != TNG_SUCCESS)
{
+ tng_data->input_file = temp;
+
+ tng_data->first_trajectory_frame_set_input_file_pos = temp_first;
+ tng_data->last_trajectory_frame_set_input_file_pos = temp_last;
+ tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
return(stat);
}
+ tng_block_init(&block);
+
frame_set = &tng_data->current_trajectory_frame_set;
-
- tng_data->input_file = temp;
-
- file_pos = ftell(tng_data->output_file);
+
+ file_pos = tng_data->current_trajectory_frame_set_output_file_pos;
fseek(tng_data->output_file, 0, SEEK_END);
output_file_len = ftell(tng_data->output_file);
fseek(tng_data->output_file, file_pos, SEEK_SET);
+
+ /* Read past the frame set block first */
+ stat = tng_block_header_read(tng_data, block);
+ if(stat == TNG_CRITICAL)
+ {
+ tng_block_destroy(&block);
+ tng_data->input_file = temp;
+
+ tng_data->first_trajectory_frame_set_input_file_pos = temp_first;
+ tng_data->last_trajectory_frame_set_input_file_pos = temp_last;
+ tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
+ return(stat);
+ }
+ fseek(tng_data->output_file, block->block_contents_size,
+ SEEK_CUR);
- tng_block_init(&block);
- /* Read all block headers until next frame set block */
+ if(tng_data->var_num_atoms_flag)
+ {
+ tot_n_particles = frame_set->n_particles;
+ }
+ else
+ {
+ tot_n_particles = tng_data->n_particles;
+ }
+
+ if(val_n_particles < tot_n_particles)
+ {
+ mapping_block_end_pos = -1;
+ /* Read all mapping blocks to find the right place to put the data */
+ stat = tng_block_header_read(tng_data, block);
+ while(file_pos < output_file_len &&
+ stat != TNG_CRITICAL &&
+ block->id != TNG_TRAJECTORY_FRAME_SET)
+ {
+ if(block->id == TNG_PARTICLE_MAPPING)
+ {
+ tng_trajectory_mapping_block_read(tng_data, block, hash_mode);
+ }
+ else
+ {
+ fseek(tng_data->output_file, block->block_contents_size,
+ SEEK_CUR);
+ }
+ file_pos = ftell(tng_data->output_file);
+ if(block->id == TNG_PARTICLE_MAPPING)
+ {
+ mapping = &frame_set->mappings[frame_set->n_mapping_blocks - 1];
+ if(val_first_particle >= mapping->num_first_particle &&
+ val_first_particle < mapping->num_first_particle +
+ mapping->n_particles &&
+ val_first_particle + val_n_particles <=
+ mapping->num_first_particle + mapping->n_particles)
+ {
+ mapping_block_end_pos = file_pos;
+ }
+ }
+ if(file_pos < output_file_len)
+ {
+ stat = tng_block_header_read(tng_data, block);
+ }
+ }
+ if(stat == TNG_CRITICAL)
+ {
+ tng_block_destroy(&block);
+ tng_data->input_file = temp;
+
+ tng_data->first_trajectory_frame_set_input_file_pos = temp_first;
+ tng_data->last_trajectory_frame_set_input_file_pos = temp_last;
+ tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
+ return(stat);
+ }
+ if(mapping_block_end_pos < 0)
+ {
+ tng_block_destroy(&block);
+ tng_data->input_file = temp;
+
+ tng_data->first_trajectory_frame_set_input_file_pos = temp_first;
+ tng_data->last_trajectory_frame_set_input_file_pos = temp_last;
+ tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
+ return(TNG_FAILURE);
+ }
+ fseek(tng_data->output_file, mapping_block_end_pos, SEEK_SET);
+ }
+
+ /* Read all block headers until next frame set block or
+ * until the wanted block id is found */
stat = tng_block_header_read(tng_data, block);
while(file_pos < output_file_len &&
stat != TNG_CRITICAL &&
block->id != block_id &&
+ block->id != TNG_PARTICLE_MAPPING &&
block->id != TNG_TRAJECTORY_FRAME_SET)
{
fseek(tng_data->output_file, block->block_contents_size, SEEK_CUR);
@@ -7955,6 +8171,11 @@ tng_function_status tng_frame_particle_data_write(tng_trajectory_t tng_data,
if(stat == TNG_CRITICAL)
{
tng_block_destroy(&block);
+ tng_data->input_file = temp;
+
+ tng_data->first_trajectory_frame_set_input_file_pos = temp_first;
+ tng_data->last_trajectory_frame_set_input_file_pos = temp_last;
+ tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
return(stat);
}
@@ -7964,26 +8185,130 @@ tng_function_status tng_frame_particle_data_write(tng_trajectory_t tng_data,
header_pos = file_pos;
frame_set = &tng_data->current_trajectory_frame_set;
- block_index = -1;
- /* See if there is already a data block of this ID.
- * Start checking the last read frame set */
- for(i = frame_set->n_data_blocks; i--;)
+ fread(&datatype, sizeof(datatype), 1, tng_data->input_file);
+ fread(&dependency, sizeof(dependency), 1, tng_data->input_file);
+ data.datatype = datatype;
+
+ if(!(dependency & TNG_FRAME_DEPENDENT) ||
+ !(dependency & TNG_PARTICLE_DEPENDENT))
{
- data = &frame_set->tr_particle_data[i];
- if(data->block_id == block_id)
+ tng_block_destroy(&block);
+ tng_data->input_file = temp;
+
+ tng_data->first_trajectory_frame_set_input_file_pos = temp_first;
+ tng_data->last_trajectory_frame_set_input_file_pos = temp_last;
+ tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
+ return(TNG_FAILURE);
+ }
+
+ fread(&sparse_data, sizeof(sparse_data), 1, tng_data->input_file);
+
+ fread(&data.n_values_per_frame, sizeof(data.n_values_per_frame), 1,
+ tng_data->input_file);
+ if(tng_data->endianness_64 != TNG_BIG_ENDIAN_64)
+ {
+ if(tng_swap_byte_order_64(tng_data, &data.n_values_per_frame) != TNG_SUCCESS)
{
- block_index = i;
- break;
+ printf("Cannot swap byte order to get big endian. %s: %d\n",
+ __FILE__, __LINE__);
}
}
- if(block_index < 0)
+ fread(&data.codec_id, sizeof(data.codec_id), 1,
+ tng_data->input_file);
+ if(tng_data->endianness_64 != TNG_BIG_ENDIAN_64)
{
- tng_block_destroy(&block);
- return(TNG_FAILURE);
+ if(tng_swap_byte_order_64(tng_data, &data.codec_id) != TNG_SUCCESS)
+ {
+ printf("Cannot swap byte order to get big endian. %s: %d\n",
+ __FILE__, __LINE__);
+ }
+ }
+
+ if(data.codec_id != TNG_UNCOMPRESSED)
+ {
+ fread(&data.compression_multiplier,
+ sizeof(data.compression_multiplier), 1, tng_data->input_file);
+ if(tng_data->endianness_64 != TNG_BIG_ENDIAN_64)
+ {
+ if(tng_swap_byte_order_64(tng_data, (int64_t *)
+ &data.compression_multiplier) !=
+ TNG_SUCCESS)
+ {
+ printf("Cannot swap byte order to get big endian. %s: %d\n",
+ __FILE__, __LINE__);
+ }
+ }
+ }
+ else
+ {
+ data.compression_multiplier = 1;
}
- switch(data->datatype)
+ if(sparse_data)
+ {
+ fread(&data.first_frame_with_data, sizeof(data.first_frame_with_data),
+ 1, tng_data->input_file);
+ if(tng_data->endianness_64 != TNG_BIG_ENDIAN_64)
+ {
+ if(tng_swap_byte_order_64(tng_data, &data.first_frame_with_data) !=
+ TNG_SUCCESS)
+ {
+ printf("Cannot swap byte order to get big endian. %s: %d\n",
+ __FILE__, __LINE__);
+ }
+ }
+
+ fread(&data.stride_length, sizeof(data.stride_length),
+ 1, tng_data->input_file);
+ if(tng_data->endianness_64 != TNG_BIG_ENDIAN_64)
+ {
+ if(tng_swap_byte_order_64(tng_data, &data.stride_length) !=
+ TNG_SUCCESS)
+ {
+ printf("Cannot swap byte order to get big endian. %s: %d\n",
+ __FILE__, __LINE__);
+ }
+ }
+ }
+ else
+ {
+ data.first_frame_with_data = 0;
+ data.stride_length = 1;
+ }
+ data.n_frames = tng_data->current_trajectory_frame_set.n_frames;
+
+ fread(&num_first_particle, sizeof(num_first_particle), 1, tng_data->input_file);
+ if(tng_data->endianness_64 != TNG_BIG_ENDIAN_64)
+ {
+ if(tng_swap_byte_order_64(tng_data, &num_first_particle) !=
+ TNG_SUCCESS)
+ {
+ printf("Cannot swap byte order to get big endian. %s: %d\n",
+ __FILE__, __LINE__);
+ }
+ }
+
+ fread(&block_n_particles, sizeof(block_n_particles), 1, tng_data->input_file);
+ if(tng_data->endianness_64 != TNG_BIG_ENDIAN_64)
+ {
+ if(tng_swap_byte_order_64(tng_data, &block_n_particles) !=
+ TNG_SUCCESS)
+ {
+ printf("Cannot swap byte order to get big endian. %s: %d\n",
+ __FILE__, __LINE__);
+ }
+ }
+
+
+ tng_data->input_file = temp;
+
+ tng_data->first_trajectory_frame_set_input_file_pos = temp_first;
+ tng_data->last_trajectory_frame_set_input_file_pos = temp_last;
+ tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
+
+
+ switch(data.datatype)
{
case(TNG_INT_DATA):
size = sizeof(int64_t);
@@ -8001,20 +8326,12 @@ tng_function_status tng_frame_particle_data_write(tng_trajectory_t tng_data,
return(TNG_FAILURE);
}
- size *= data->n_values_per_frame;
-
- if(tng_data->var_num_atoms_flag)
- {
- n_particles = frame_set->n_particles;
- }
- else
- {
- n_particles = tng_data->n_particles;
- }
- n_values_per_frame = data->n_values_per_frame;
+ n_values_per_frame = data.n_values_per_frame;
- file_pos = (frame_nr - data->first_frame_with_data) / data->stride_length;
- file_pos *= n_particles * n_values_per_frame;
+ file_pos = (frame_nr - (frame_set->first_frame +
+ data.first_frame_with_data)) /
+ data.stride_length;
+ file_pos *= block_n_particles * size * n_values_per_frame;
if(file_pos > contents_size)
{
@@ -8026,14 +8343,13 @@ tng_function_status tng_frame_particle_data_write(tng_trajectory_t tng_data,
fseek(tng_data->output_file, file_pos, SEEK_CUR);
- for(i = 0; i < n_particles; i++)
- {
- fwrite(values[i], n_values_per_frame, size, tng_data->output_file);
- }
+ fwrite(values, val_n_particles * n_values_per_frame, size,
+ tng_data->output_file);
+ fflush(tng_data->output_file);
/* If the last frame has been written update the hash */
- if(hash_mode == TNG_USE_HASH && (frame_nr + data->stride_length -
- data->first_frame_with_data) / data->stride_length >=
+ if(hash_mode == TNG_USE_HASH && (frame_nr + data.stride_length -
+ data.first_frame_with_data) / data.stride_length >=
frame_set->n_frames)
{
tng_md5_hash_update(tng_data, block, header_pos, header_pos +
diff --git a/src/lib/tng_io.h b/src/lib/tng_io.h
index c049218..97c590f 100644
--- a/src/lib/tng_io.h
+++ b/src/lib/tng_io.h
@@ -1322,7 +1322,10 @@ tng_function_status tng_frame_data_write_(tng_trajectory_t tng_data,
* will be opened.
* @param frame_nr is the index number of the frame to write.
* @param block_id is the ID of the data block to write the data to.
- * @param data is a 2D-array of data to write. The length of the array should
+ * @param val_first_particle is the number of the first particle in the data
+ * array.
+ * @param val_n_particles is the number of particles in the data array.
+ * @param data is a 1D-array of data to write. The length of the array should
* equal n_particles * n_values_per_frame.
* @param hash_mode is an option to decide whether to use the md5 hash or not.
* If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
@@ -1333,15 +1336,21 @@ tng_function_status tng_frame_data_write_(tng_trajectory_t tng_data,
tng_function_status tng_frame_particle_data_write(tng_trajectory_t tng_data,
const int64_t frame_nr,
const int64_t block_id,
- const void **data,
- const tng_hash_mode hash_mode);
+ const int64_t val_first_particle,
+ const int64_t val_n_particles,
+ const void *data,
+ const tng_hash_mode hash_mode);
tng_function_status tng_frame_particle_data_write_(tng_trajectory_t tng_data,
const int64_t *frame_nr,
const int64_t *block_id,
- const void **data,
- const tng_hash_mode *hash_mode)
+ const int64_t *val_first_particle,
+ const int64_t *val_n_particles,
+ const void *data,
+ const tng_hash_mode *hash_mode)
{
- return(tng_frame_particle_data_write(tng_data, *frame_nr, *block_id, data, *hash_mode));
+ return(tng_frame_particle_data_write(tng_data, *frame_nr, *block_id,
+ *val_first_particle, *val_n_particles,
+ data, *hash_mode));
}
/**
diff --git a/src/tests/tng_io_testing.c b/src/tests/tng_io_testing.c
index c8d48a7..c0bc595 100644
--- a/src/tests/tng_io_testing.c
+++ b/src/tests/tng_io_testing.c
@@ -128,7 +128,8 @@ static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t traj)
{
int i, j, k, nr, cnt;
float *data, *molpos;
- int64_t mapping[150], n_particles, n_frames_per_frame_set, tot_n_mols;
+ int64_t mapping[300], n_particles, n_frames_per_frame_set, tot_n_mols;
+ int64_t frame_nr;
tng_function_status stat;
tng_medium_stride_length_set(traj, 10);
@@ -276,7 +277,119 @@ static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t traj)
return(TNG_CRITICAL);
}
}
+
+ /* Write one more frame set one frame at a time */
+ cnt = 0;
+ for(j = 0; j < n_frames_per_frame_set; j++)
+ {
+ for(k = 0; k < tot_n_mols; k++)
+ {
+ data[cnt++] = 0;
+ data[cnt++] = 0;
+ data[cnt++] = 0;
+ data[cnt++] = 0;
+ data[cnt++] = 0;
+ data[cnt++] = 0;
+ data[cnt++] = 0;
+ data[cnt++] = 0;
+ data[cnt++] = 0;
+ }
+ }
+ if(tng_frame_set_new(traj, i * n_frames_per_frame_set,
+ n_frames_per_frame_set) != TNG_SUCCESS)
+ {
+ printf("Error creating frame set %d. %s: %d\n",
+ i, __FILE__, __LINE__);
+ free(molpos);
+ free(data);
+ return(TNG_CRITICAL);
+ }
+
+ frame_nr = i * n_frames_per_frame_set;
+
+ for(k=0; k<300; k++)
+ {
+ mapping[k]=k;
+ }
+ if(tng_particle_mapping_add(traj, 0, 300, mapping) != TNG_SUCCESS)
+ {
+ printf("Error creating particle mapping. %s: %d\n",
+ __FILE__, __LINE__);
+ free(molpos);
+ free(data);
+ return(TNG_CRITICAL);
+ }
+ for(k=0; k<300; k++)
+ {
+ mapping[k]=599-k;
+ }
+ if(tng_particle_mapping_add(traj, 300, 300, mapping) != TNG_SUCCESS)
+ {
+ printf("Error creating particle mapping. %s: %d\n",
+ __FILE__, __LINE__);
+ free(molpos);
+ free(data);
+ return(TNG_CRITICAL);
+ }
+
+ if(tng_particle_data_block_add(traj, TNG_TRAJ_POSITIONS,
+ "POSITIONS",
+ TNG_FLOAT_DATA,
+ TNG_TRAJECTORY_BLOCK,
+ n_frames_per_frame_set, 3,
+ 1, 0, n_particles,
+ TNG_UNCOMPRESSED,
+ data) != TNG_SUCCESS)
+ {
+ printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
+ free(molpos);
+ free(data);
+ return(TNG_CRITICAL);
+ }
+
+ if(tng_frame_set_write(traj, TNG_SKIP_HASH) != TNG_SUCCESS)
+ {
+ printf("Error writing frame set. %s: %d\n", __FILE__, __LINE__);
+ free(molpos);
+ free(data);
+ return(TNG_CRITICAL);
+ }
+
+ for(i = 0; i < n_frames_per_frame_set; i++)
+ {
+ for(j = 0; j < 2; j++)
+ {
+ cnt = 0;
+ for(k = 0; k < tot_n_mols/2; k++)
+ {
+ nr = k * 3;
+ /* Move -1 to 1 */
+ molpos[nr] += 2 * (rand() / (RAND_MAX + 1.0)) - 1;
+ molpos[nr+1] += 2 * (rand() / (RAND_MAX + 1.0)) - 1;
+ molpos[nr+2] += 2 * (rand() / (RAND_MAX + 1.0)) - 1;
+ data[cnt++] = molpos[nr];
+ data[cnt++] = molpos[nr + 1];
+ data[cnt++] = molpos[nr + 2];
+ data[cnt++] = molpos[nr] + 1;
+ data[cnt++] = molpos[nr + 1] + 1;
+ data[cnt++] = molpos[nr + 2] + 1;
+ data[cnt++] = molpos[nr] - 1;
+ data[cnt++] = molpos[nr + 1] - 1;
+ data[cnt++] = molpos[nr + 2] - 1;
+ }
+ if(tng_frame_particle_data_write(traj, frame_nr + i,
+ TNG_TRAJ_POSITIONS, j * 300, 300,
+ data, TNG_SKIP_HASH) != TNG_SUCCESS)
+ {
+ printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
+ free(molpos);
+ free(data);
+ return(TNG_CRITICAL);
+ }
+ }
+ }
+
free(molpos);
free(data);
contact: Jan Huwald // Impressum