diff options
| author | Magnus Lundborg <magnus.lundborg@scilifelab.se> | 2013-01-15 15:38:48 (GMT) | 
|---|---|---|
| committer | Magnus Lundborg <magnus.lundborg@scilifelab.se> | 2013-01-15 15:38:48 (GMT) | 
| commit | 4e19acea5ae1286f1f5161a0aea94b978fb6374f (patch) | |
| tree | 3b21148245896b6715826e4325a1499b576888f0 /src/lib | |
| parent | c5f104e395ea4b2635adaba462bbaba766ab5f0d (diff) | |
Test parallel i/o (not very quick atm).
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/tng_io.c | 429 | ||||
| -rw-r--r-- | src/lib/tng_io.h | 20 | 
2 files changed, 390 insertions, 59 deletions
| diff --git a/src/lib/tng_io.c b/src/lib/tng_io.c index cb24104..3da1ceb 100644 --- a/src/lib/tng_io.c +++ b/src/lib/tng_io.c @@ -303,7 +303,8 @@ struct tng_trajectory {      long int current_trajectory_frame_set_input_file_pos;      /** The pos in the dest file of the current frame set */      long int current_trajectory_frame_set_output_file_pos; -    /** The number of frame sets in the trajectory */ +    /** The number of frame sets in the trajectory N.B. Not saved in file and +     *  cannot be trusted to be up-to-date */      int64_t n_trajectory_frame_sets;      /** The number of trajectory blocks in the file */ @@ -5773,7 +5774,7 @@ tng_function_status tng_particle_mapping_add      return(TNG_SUCCESS);  } -tng_function_status tng_trajectory_init(struct tng_trajectory **tng_data_p) +tng_function_status tng_trajectory_init(tng_trajectory_t *tng_data_p)  {      time_t seconds;      tng_trajectory_frame_set_t frame_set; @@ -5919,7 +5920,7 @@ tng_function_status tng_trajectory_init(struct tng_trajectory **tng_data_p)      return(TNG_SUCCESS);  } -tng_function_status tng_trajectory_destroy(struct tng_trajectory **tng_data_p) +tng_function_status tng_trajectory_destroy(tng_trajectory_t *tng_data_p)  {      int64_t n_particles;      int i; @@ -6159,6 +6160,113 @@ tng_function_status tng_trajectory_destroy(struct tng_trajectory **tng_data_p)      return(TNG_SUCCESS);  } +tng_function_status tng_trajectory_copy(tng_trajectory_t src, +                                        tng_trajectory_t *dest_p) +{ +    tng_trajectory_frame_set_t frame_set; +    tng_trajectory_t dest; + +    *dest_p = malloc(sizeof(struct tng_trajectory)); +    if(!dest_p) +    { +        printf("Cannot allocate memory (%lu bytes). %s: %d\n", +               sizeof(struct tng_trajectory), __FILE__, __LINE__); +        return(TNG_CRITICAL); +    } + +    dest = *dest_p; + +    frame_set = &dest->current_trajectory_frame_set; + +    dest->input_file_path = 0; +    if(src->input_file) +    { +        dest->input_file = fopen(src->input_file_path, "r"); +    } +    else +    { +        dest->input_file = 0; +    } +     +    dest->input_file_len = src->input_file_len; +    dest->output_file_path = 0; +    if(src->output_file) +    { +        dest->output_file = fopen(src->output_file_path, "w+"); +    } +    else +    { +        dest->output_file = 0; +    } + +    dest->first_program_name = 0; +    dest->first_user_name = 0; +    dest->first_computer_name = 0; +    dest->first_pgp_signature = 0; +    dest->last_program_name = 0; +    dest->last_user_name = 0; +    dest->last_computer_name = 0; +    dest->last_pgp_signature = 0; +    dest->forcefield_name = 0; + +    dest->var_num_atoms_flag = src->var_num_atoms_flag; +    dest->first_trajectory_frame_set_input_file_pos = +    src->first_trajectory_frame_set_input_file_pos; +    dest->last_trajectory_frame_set_input_file_pos = +    src->last_trajectory_frame_set_input_file_pos; +    dest->current_trajectory_frame_set_input_file_pos = +    src->current_trajectory_frame_set_input_file_pos; +    dest->first_trajectory_frame_set_output_file_pos = +    src->first_trajectory_frame_set_output_file_pos; +    dest->last_trajectory_frame_set_output_file_pos = +    src->last_trajectory_frame_set_output_file_pos; +    dest->current_trajectory_frame_set_output_file_pos = +    src->current_trajectory_frame_set_output_file_pos; +    dest->frame_set_n_frames = src->frame_set_n_frames; +    dest->n_trajectory_frame_sets = src->n_trajectory_frame_sets; +    dest->n_trajectory_blocks = src->n_trajectory_blocks; +    dest->medium_stride_length = src->medium_stride_length; +    dest->long_stride_length = src->long_stride_length; + +    dest->n_particle_data_blocks = src->n_particle_data_blocks; +    dest->n_data_blocks = src->n_data_blocks; + +    dest->non_tr_particle_data = src->non_tr_particle_data; +    dest->non_tr_data = src->non_tr_data; + +    frame_set->first_frame = -1; +    frame_set->n_mapping_blocks = 0; +    frame_set->mappings = 0; +    frame_set->molecule_cnt_list = 0; + +    frame_set->n_particle_data_blocks = 0; +    frame_set->n_data_blocks = 0; + +    frame_set->tr_particle_data = 0; +    frame_set->tr_data = 0; + +    frame_set->next_frame_set_file_pos = -1; +    frame_set->prev_frame_set_file_pos = -1; +    frame_set->medium_stride_next_frame_set_file_pos = -1; +    frame_set->medium_stride_prev_frame_set_file_pos = -1; +    frame_set->long_stride_next_frame_set_file_pos = -1; +    frame_set->long_stride_prev_frame_set_file_pos = -1; + +    dest->n_molecules = 0; +    dest->molecules = 0; +    dest->molecule_cnt_list = 0; +    dest->n_particles = src->n_particles; + +    dest->endianness_32 = src->endianness_32; +    dest->endianness_64 = src->endianness_64; + +    dest->current_trajectory_frame_set.next_frame_set_file_pos = -1; +    dest->current_trajectory_frame_set.prev_frame_set_file_pos = -1; +    dest->current_trajectory_frame_set.n_frames = 0; + +    return(TNG_SUCCESS); +} +  tng_function_status tng_input_file_get(const tng_trajectory_t tng_data,                                         char *file_name, const int max_len)  { @@ -6737,7 +6845,130 @@ tng_function_status tng_num_frames_per_frame_set_get  tng_function_status tng_num_frame_sets_get(const tng_trajectory_t tng_data,                                             int64_t *n)  { -    *n = tng_data->n_trajectory_frame_sets; +    int64_t long_stride_length, medium_stride_length; +    int64_t file_pos; +    tng_trajectory_frame_set_t frame_set = +    &tng_data->current_trajectory_frame_set; +    tng_gen_block_t block; +    tng_function_status stat; +    int64_t cnt = 0; +     +    file_pos = tng_data->first_trajectory_frame_set_input_file_pos; +     +    tng_block_init(&block); +    fseek(tng_data->input_file, +        file_pos, +        SEEK_SET); +    tng_data->current_trajectory_frame_set_input_file_pos = file_pos; +    /* 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) +    { +        tng_block_destroy(&block); +        return(TNG_CRITICAL); +    } + +    if(tng_block_read_next(tng_data, block, +                        TNG_SKIP_HASH) != TNG_SUCCESS) +    { +        tng_block_destroy(&block); +        return(TNG_CRITICAL); +    } + +    ++cnt; +     +    file_pos = tng_data->current_trajectory_frame_set_input_file_pos; + +    long_stride_length = tng_data->long_stride_length; +    medium_stride_length = tng_data->medium_stride_length; + +    /* Take long steps forward until a long step forward would be too long or +     * the right frame set is found */ +    file_pos = frame_set->long_stride_next_frame_set_file_pos; +    while(file_pos > 0) +    { +        if(file_pos > 0) +        { +            cnt += long_stride_length; +            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) +            { +                tng_block_destroy(&block); +                return(TNG_CRITICAL); +            } + +            if(tng_block_read_next(tng_data, block, +                                TNG_SKIP_HASH) != TNG_SUCCESS) +            { +                tng_block_destroy(&block); +                return(TNG_CRITICAL); +            } +        } +        file_pos = frame_set->long_stride_next_frame_set_file_pos; +    } + +    /* Take medium steps forward until a medium step forward would be too long +     * or the right frame set is found */ +    file_pos = frame_set->medium_stride_next_frame_set_file_pos; +    while(file_pos > 0) +    { +        if(file_pos > 0) +        { +            cnt += medium_stride_length; +            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) +            { +                tng_block_destroy(&block); +                return(TNG_CRITICAL); +            } + +            if(tng_block_read_next(tng_data, block, +                                TNG_SKIP_HASH) != TNG_SUCCESS) +            { +                tng_block_destroy(&block); +                return(TNG_CRITICAL); +            } +        } +        file_pos = frame_set->medium_stride_next_frame_set_file_pos; +    } + +    /* Take one step forward until the right frame set is found */ +    file_pos = frame_set->next_frame_set_file_pos; +    while(file_pos > 0) +    { +        if(file_pos > 0) +        { +            ++cnt; +            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) +            { +                tng_block_destroy(&block); +                return(TNG_CRITICAL); +            } + +            if(tng_block_read_next(tng_data, block, +                                TNG_SKIP_HASH) != TNG_SUCCESS) +            { +                tng_block_destroy(&block); +                return(TNG_CRITICAL); +            } +        } +        file_pos = frame_set->next_frame_set_file_pos; +    } + +    tng_block_destroy(&block); +     +    *n = tng_data->n_trajectory_frame_sets = cnt;      return(TNG_SUCCESS);  } @@ -6755,13 +6986,15 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,                                         const int64_t nr)  {      int64_t long_stride_length, medium_stride_length; -    int64_t file_pos, curr_nr = 0; +    int64_t file_pos, curr_nr = 0, n_frame_sets;      tng_trajectory_frame_set_t frame_set =      &tng_data->current_trajectory_frame_set;      tng_gen_block_t block;      tng_function_status stat; -    if(nr > tng_data->n_trajectory_frame_sets) +    stat = tng_num_frame_sets_get(tng_data, &n_frame_sets); +     +    if(nr >= n_frame_sets)      {          return(TNG_FAILURE);      } @@ -6771,7 +7004,7 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,      /* FIXME: The frame set number of the current frame set is not stored */ -    if(nr < tng_data->n_trajectory_frame_sets - 1 - nr) +    if(nr < n_frame_sets - 1 - nr)      {          /* Start from the beginning */          file_pos = tng_data->first_trajectory_frame_set_input_file_pos; @@ -6780,7 +7013,7 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,      {          /* Start from the end */          file_pos = tng_data->last_trajectory_frame_set_input_file_pos; -        curr_nr = tng_data->n_trajectory_frame_sets - 1; +        curr_nr = n_frame_sets - 1;      }      if(file_pos <= 0)      { @@ -6820,9 +7053,9 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,      while(file_pos > 0 && curr_nr + long_stride_length <= nr)      {          file_pos = frame_set->long_stride_next_frame_set_file_pos; -        curr_nr += long_stride_length;          if(file_pos > 0)          { +            curr_nr += long_stride_length;              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); @@ -6838,11 +7071,11 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,                  tng_block_destroy(&block);                  return(TNG_CRITICAL);              } -        } -        if(curr_nr == nr) -        { -            tng_block_destroy(&block); -            return(TNG_SUCCESS); +            if(curr_nr == nr) +            { +                tng_block_destroy(&block); +                return(TNG_SUCCESS); +            }          }      } @@ -6851,9 +7084,9 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,      while(file_pos > 0 && curr_nr + medium_stride_length <= nr)      {          file_pos = frame_set->medium_stride_next_frame_set_file_pos; -        curr_nr += medium_stride_length;          if(file_pos > 0)          { +            curr_nr += medium_stride_length;              fseek(tng_data->input_file,                  file_pos,                  SEEK_SET); @@ -6871,11 +7104,11 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,                  tng_block_destroy(&block);                  return(TNG_CRITICAL);              } -        } -        if(curr_nr == nr) -        { -            tng_block_destroy(&block); -            return(TNG_SUCCESS); +            if(curr_nr == nr) +            { +                tng_block_destroy(&block); +                return(TNG_SUCCESS); +            }          }      } @@ -6883,10 +7116,10 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,      while(file_pos > 0 && curr_nr < nr)      {          file_pos = frame_set->next_frame_set_file_pos; -        ++curr_nr;          if(file_pos > 0)          { +            ++curr_nr;              fseek(tng_data->input_file,                  file_pos,                  SEEK_SET); @@ -6904,11 +7137,11 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,                  tng_block_destroy(&block);                  return(TNG_CRITICAL);              } -        } -        if(curr_nr == nr) -        { -            tng_block_destroy(&block); -            return(TNG_SUCCESS); +            if(curr_nr == nr) +            { +                tng_block_destroy(&block); +                return(TNG_SUCCESS); +            }          }      } @@ -6917,9 +7150,9 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,      while(file_pos > 0 && curr_nr - long_stride_length >= nr)      {          file_pos = frame_set->long_stride_prev_frame_set_file_pos; -        curr_nr -= long_stride_length;          if(file_pos > 0)          { +            curr_nr -= long_stride_length;              fseek(tng_data->input_file,                  file_pos,                  SEEK_SET); @@ -6937,11 +7170,11 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,                  tng_block_destroy(&block);                  return(TNG_CRITICAL);              } -        } -        if(curr_nr == nr) -        { -            tng_block_destroy(&block); -            return(TNG_SUCCESS); +            if(curr_nr == nr) +            { +                tng_block_destroy(&block); +                return(TNG_SUCCESS); +            }          }      } @@ -6950,9 +7183,9 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,      while(file_pos > 0 && curr_nr - medium_stride_length >= nr)      {          file_pos = frame_set->medium_stride_prev_frame_set_file_pos; -        curr_nr -= medium_stride_length;          if(file_pos > 0)          { +            curr_nr -= medium_stride_length;              fseek(tng_data->input_file,                  file_pos,                  SEEK_SET); @@ -6970,11 +7203,11 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,                  tng_block_destroy(&block);                  return(TNG_CRITICAL);              } -        } -        if(curr_nr == nr) -        { -            tng_block_destroy(&block); -            return(TNG_SUCCESS); +            if(curr_nr == nr) +            { +                tng_block_destroy(&block); +                return(TNG_SUCCESS); +            }          }      } @@ -6982,9 +7215,9 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,      while(file_pos > 0 && curr_nr > nr)      {          file_pos = frame_set->prev_frame_set_file_pos; -        --curr_nr;          if(file_pos > 0)          { +            --curr_nr;              fseek(tng_data->input_file,                  file_pos,                  SEEK_SET); @@ -7002,11 +7235,11 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,                  tng_block_destroy(&block);                  return(TNG_CRITICAL);              } -        } -        if(curr_nr == nr) -        { -            tng_block_destroy(&block); -            return(TNG_SUCCESS); +            if(curr_nr == nr) +            { +                tng_block_destroy(&block); +                return(TNG_SUCCESS); +            }          }      } @@ -7015,9 +7248,9 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,      while(file_pos > 0 && curr_nr < nr)      {          file_pos = frame_set->next_frame_set_file_pos; -        ++curr_nr;          if(file_pos > 0)          { +            ++curr_nr;              fseek(tng_data->input_file,                  file_pos,                  SEEK_SET); @@ -7035,11 +7268,11 @@ tng_function_status tng_frame_set_nr_find(tng_trajectory_t tng_data,                  tng_block_destroy(&block);                  return(TNG_CRITICAL);              } -        } -        if(curr_nr == nr) -        { -            tng_block_destroy(&block); -            return(TNG_SUCCESS); +            if(curr_nr == nr) +            { +                tng_block_destroy(&block); +                return(TNG_SUCCESS); +            }          }      } @@ -9273,13 +9506,16 @@ tng_function_status tng_data_get(tng_trajectory_t tng_data,                                   int64_t *n_values_per_frame,                                   tng_data_type *type)  { +    int64_t file_pos;      int i, j, block_index, len;      tng_non_particle_data_t data, new_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 already a data block of this ID. +    /* 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-- ;)      { @@ -9306,7 +9542,45 @@ tng_function_status tng_data_get(tng_trajectory_t tng_data,          }          if(block_index < 0)          { -            return(TNG_FAILURE); +            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) +            { +                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); +            }          }      } @@ -9427,7 +9701,7 @@ tng_function_status tng_data_interval_get(tng_trajectory_t tng_data,      frame_set = &tng_data->current_trajectory_frame_set; -    /* See if there is already a data block of this ID. +    /* 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-- ;)      { @@ -9570,11 +9844,13 @@ 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; +    int64_t i, j, k, mapping, file_pos;      int block_index, len;      tng_particle_data_t data, new_data;      tng_trajectory_frame_set_t frame_set =      &tng_data->current_trajectory_frame_set; +    tng_gen_block_t block; +    tng_function_status stat;      tng_block_type block_type_flag; @@ -9609,9 +9885,46 @@ tng_function_status tng_particle_data_get(tng_trajectory_t tng_data,          }          if(block_index < 0)          { -            printf("Could not find particle data block with id %"PRId64". %s: %d\n", -                   block_id, __FILE__, __LINE__); -            return(TNG_FAILURE); +            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) +            { +                return(stat); +            } + +            for(i = frame_set->n_particle_data_blocks; i-- ;) +            { +                data = &frame_set->tr_particle_data[i]; +                if(data->block_id == block_id) +                { +                    block_index = i; +                    block_type_flag = TNG_TRAJECTORY_BLOCK; +                    break; +                } +            } +            if(block_index < 0) +            { +                return(TNG_FAILURE); +            }          }      } diff --git a/src/lib/tng_io.h b/src/lib/tng_io.h index 3de8d67..a5af682 100644 --- a/src/lib/tng_io.h +++ b/src/lib/tng_io.h @@ -352,6 +352,22 @@ tng_function_status tng_trajectory_destroy_(tng_trajectory_t *tng_data_p)  }  /** + * @brief Copy a trajectory data container (dest is setup as well). + * @param src the original trajectory. + * @param dest_p a pointer to memory to initialise as a trajectory. + * @details Memory is allocated during initialisation. + * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major + * error has occured. + */ +tng_function_status tng_trajectory_copy(tng_trajectory_t src, +                                        tng_trajectory_t *dest_p); +tng_function_status tng_trajectory_copy_(tng_trajectory_t src, +                                         tng_trajectory_t *dest_p) +{ +    return(tng_trajectory_copy(src, dest_p)); +} + +/**   * @brief Get the name of the input file.   * @param tng_data the trajectory of which to get the input file name.   * @param file_name the string to fill with the name of the input file, @@ -925,9 +941,11 @@ tng_function_status tng_num_frames_per_frame_set_get_  /**   * @brief Get the number of frame sets. + * @details This updates tng_data->n_trajectory_frame_sets before returning it.   * @param tng_data is the trajectory from which to get the number of frame sets.   * @param n is pointing to a value set to the number of frame sets. - * @return TNG_SUCCESS (0) if successful. + * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if a minor error + * has occurred or TNG_CRITICAL (2) if a major error has occured.   */  tng_function_status tng_num_frame_sets_get                  (const tng_trajectory_t tng_data, | 
