diff options
author | Magnus Lundborg <lundborg.magnus@gmail.com> | 2012-12-19 16:12:09 (GMT) |
---|---|---|
committer | Magnus Lundborg <lundborg.magnus@gmail.com> | 2012-12-19 16:12:09 (GMT) |
commit | 698d34f4a1195f9fc591877bb933dfc269eda1e8 (patch) | |
tree | 752274ffd545b0246554e2c1793b893d61aecb72 /src/lib/tng_io.c | |
parent | 5861fae3340d367b7e1d4b5020023aa6dd451b3b (diff) |
Get non-particle data from frame range.
Diffstat (limited to 'src/lib/tng_io.c')
-rw-r--r-- | src/lib/tng_io.c | 189 |
1 files changed, 188 insertions, 1 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); } |