summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/tng_io.c189
-rw-r--r--src/lib/tng_io.h2
2 files changed, 188 insertions, 3 deletions
diff --git a/src/lib/tng_io.c b/src/lib/tng_io.c
index 5c858f0..066b1ad 100644
--- a/src/lib/tng_io.c
+++ b/src/lib/tng_io.c
@@ -8223,7 +8223,194 @@ tng_function_status tng_data_interval_get(tng_trajectory_t tng_data,
int64_t *n_values_per_frame,
tng_data_type *type)
{
- /* STUB */
+ int64_t i, j, n_frames, file_pos, current_frame_pos;
+ int block_index, len;
+ tng_non_particle_data_t data, new_data;
+ tng_trajectory_frame_set_t frame_set;
+ tng_gen_block_t block;
+ tng_function_status stat;
+
+ block_index = -1;
+
+ stat = tng_frame_set_find(tng_data, start_frame_nr);
+ if(stat != TNG_SUCCESS)
+ {
+ return(stat);
+ }
+
+
+ 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)
+ {
+ stat = tng_block_read_next(tng_data, block,
+ TNG_SKIP_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)
+ {
+ return(stat);
+ }
+
+ frame_set = &tng_data->current_trajectory_frame_set;
+
+ /* 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-- ;)
+ {
+ 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)
+ {
+ printf("Could not find non-particle data block with id %"PRId64". %s: %d\n",
+ block_id, __FILE__, __LINE__);
+ return(TNG_FAILURE);
+ }
+ }
+
+ n_frames = end_frame_nr - start_frame_nr + 1;
+
+ /* A bit hackish to create a new data struct before returning the data */
+
+ 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_data_mem(tng_data, new_data, n_frames,
+ data->n_values_per_frame) != 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
+ * inside the for loops. */
+ switch(*type)
+ {
+ case TNG_CHAR_DATA:
+ for(i=0; i<n_frames; i++)
+ {
+ for(j=*n_values_per_frame; j--;)
+ {
+ len = strlen(data->values[current_frame_pos][j].c) + 1;
+ (*values)[i][j].c = malloc(len);
+ strncpy((*values)[i][j].c, data->values[current_frame_pos][j].c, len);
+ }
+ current_frame_pos++;
+ if(current_frame_pos == frame_set->n_frames)
+ {
+ stat = tng_frame_set_read_next(tng_data, TNG_SKIP_HASH);
+ if(stat != TNG_SUCCESS)
+ {
+ return(stat);
+ }
+ current_frame_pos = 0;
+ }
+ }
+ break;
+ case TNG_INT_DATA:
+ for(i=0; i<n_frames; i++)
+ {
+ for(j=*n_values_per_frame; j--;)
+ {
+ (*values)[i][j].i = data->values[current_frame_pos][j].i;
+ }
+ current_frame_pos++;
+ if(current_frame_pos == frame_set->n_frames)
+ {
+ stat = tng_frame_set_read_next(tng_data, TNG_SKIP_HASH);
+ if(stat != TNG_SUCCESS)
+ {
+ return(stat);
+ }
+ current_frame_pos = 0;
+ }
+ }
+ break;
+ case TNG_FLOAT_DATA:
+ for(i=0; i<n_frames; i++)
+ {
+ for(j=*n_values_per_frame; j--;)
+ {
+ (*values)[i][j].f = data->values[current_frame_pos][j].f;
+ }
+ current_frame_pos++;
+ if(current_frame_pos == frame_set->n_frames)
+ {
+ stat = tng_frame_set_read_next(tng_data, TNG_SKIP_HASH);
+ if(stat != TNG_SUCCESS)
+ {
+ return(stat);
+ }
+ current_frame_pos = 0;
+ }
+ }
+ break;
+ case TNG_DOUBLE_DATA:
+ default:
+ for(i=0; i<n_frames; i++)
+ {
+ for(j=*n_values_per_frame; j--;)
+ {
+ (*values)[i][j].d = data->values[current_frame_pos][j].d;
+ }
+ current_frame_pos++;
+ if(current_frame_pos == frame_set->n_frames)
+ {
+ stat = tng_frame_set_read_next(tng_data, TNG_SKIP_HASH);
+ if(stat != TNG_SUCCESS)
+ {
+ return(stat);
+ }
+ current_frame_pos = 0;
+ }
+ }
+ }
+
return(TNG_SUCCESS);
}
diff --git a/src/lib/tng_io.h b/src/lib/tng_io.h
index c15bb66..894f399 100644
--- a/src/lib/tng_io.h
+++ b/src/lib/tng_io.h
@@ -914,7 +914,6 @@ tng_function_status tng_data_get(tng_trajectory_t tng_data,
/**
* @brief Read and retrieve non-particle data, in a specific interval.
- * @details Not implemented yet!
* @param tng_data is a trajectory data container. tng_data->input_file_path specifies
* which file to read from. If the file (input_file) is not open it will be
* opened.
@@ -974,7 +973,6 @@ tng_function_status tng_particle_data_get(tng_trajectory_t tng_data,
/**
* @brief Read and retrieve particle data, in a specific interval.
- * @details Not implemented yet!
* @details The particle dimension of the returned values array is translated
* to real particle numbering, i.e. the numbering of the actual molecular
* system.
contact: Jan Huwald // Impressum