diff options
-rw-r--r-- | include/tng_io.h | 122 | ||||
-rw-r--r-- | src/lib/tng_io.c | 238 |
2 files changed, 264 insertions, 96 deletions
diff --git a/include/tng_io.h b/include/tng_io.h index 0bd15a0..c7cb9ba 100644 --- a/include/tng_io.h +++ b/include/tng_io.h @@ -1,6 +1,6 @@ /* This code is part of the tng binary trajectory format. * - * VERSION 1.0 + * VERSION 1.1 * * Written by Magnus Lundborg * Copyright (c) 2012, The GROMACS development team. @@ -25,7 +25,7 @@ * Each block can contain MD5 hashes to verify data integrity and the file * can be signed by the user to ensure that the origin is correct. * - * This is version 1.0 of the TNG API. The intention is that this version of + * This is version 1.1 of the TNG API. The intention is that this version of * the API and ABI should be stable, but it is still possible that future * changes might make that impossible, in which case that will be clarified. * @@ -124,7 +124,7 @@ * for ( step = 1; step < step_num; step++ ) * { * compute ( np, nd, pos, vel, mass, force, &potential, &kinetic ); - * + * * if(step % step_save == 0) * { * // Write positions, velocities and forces @@ -153,7 +153,7 @@ * #include <stdlib.h> * #include <stdio.h> * #include <tng_io.h> - * + * * int main(int argc, char **argv) * { * tng_trajectory_t traj; @@ -164,31 +164,31 @@ * // Set a default frame range * int64_t first_frame = 0, last_frame = 5000; * int k; - * + * * // A reference must be passed to allocate memory * tng_util_trajectory_open(argv[1], 'r', &traj); - * + * * if(tng_num_frames_get(traj, &tot_n_frames) != TNG_SUCCESS) * { * printf("Cannot determine the number of frames in the file\n"); * tng_util_trajectory_close(&traj); * exit(1); * } - * + * * if(tng_num_particles_get(traj, &n_particles) != TNG_SUCCESS) * { * printf("Cannot determine the number of particles in the file\n"); * tng_util_trajectory_close(&traj); * exit(1); * } - * + * * printf("%"PRId64" frames in file\n", tot_n_frames); - * + * * if(last_frame > tot_n_frames - 1) * { * last_frame = tot_n_frames - 1; * } - * + * * if(tng_util_box_shape_read(traj, &box_shape, &stride_length) == * TNG_SUCCESS) * { @@ -203,10 +203,10 @@ * { * printf("Simulation box shape not set in the file (or could not be read)\n"); * } - * + * * n_frames = last_frame - first_frame + 1; - * - * + * + * * // Get the positions of all particles in the requested frame range. * // The positions are stored in the positions array. * // N.B. No proper error checks. @@ -233,14 +233,14 @@ * { * printf("Cannot read positions\n"); * } - * + * * // Free memory * if(positions) * { * free(positions); * } * tng_util_trajectory_close(&traj); - * + * * return(0); * } * @@ -1064,8 +1064,8 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_destroy * @param tng_data is the trajectory data container containing the block.. * @param name is a pointer to the string containing the name of the new molecule. * @param molecule is a pointer to the newly created molecule. - * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major - * error has occured. + * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the ID could + * not be set properly or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_add (tng_trajectory_t tng_data, @@ -1073,6 +1073,21 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_add tng_molecule_t *molecule); /** + * @brief Add a molecule with a specific ID to the trajectory. + * @param tng_data is the trajectory data container containing the block.. + * @param name is a pointer to the string containing the name of the new molecule. + * @param id is the ID of the created molecule. + * @param molecule is a pointer to the newly created molecule. + * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the ID could + * not be set properly or TNG_CRITICAL (2) if a major error has occured. + */ +tng_function_status DECLSPECDLLEXPORT tng_molecule_w_id_add + (tng_trajectory_t tng_data, + const char *name, + const int64_t id, + tng_molecule_t *molecule); + +/** * @brief Set the name of a molecule. * @param tng_data is the trajectory data container containing the molecule.. * @param molecule is the molecule to rename. @@ -1138,8 +1153,8 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_find * @param molecule is the molecule to add a chain to. * @param name is a string containing the name of the chain. * @param chain is a pointer to the newly created chain. - * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major - * error has occured. + * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the ID could + * not be set properly or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_add (tng_trajectory_t tng_data, @@ -1148,6 +1163,23 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_add tng_chain_t *chain); /** + * @brief Add a chain with a specific id to a molecule. + * @param tng_data is the trajectory data container containing the molecule.. + * @param molecule is the molecule to add a chain to. + * @param name is a string containing the name of the chain. + * @param id is the ID of the created chain. + * @param chain is a pointer to the newly created chain. + * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the ID could + * not be set properly or TNG_CRITICAL (2) if a major error has occured. + */ +tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_w_id_add + (tng_trajectory_t tng_data, + tng_molecule_t molecule, + const char *name, + const int64_t id, + tng_chain_t *chain); + +/** * @brief Set the name of a chain. * @param tng_data is the trajectory data container containing the atom.. * @param chain is the chain to rename. @@ -1185,8 +1217,8 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_find * @param chain is the chain to add a residue to. * @param name is a string containing the name of the residue. * @param residue is a pointer to the newly created residue. - * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major - * error has occured. + * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the ID could + * not be set properly or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_add (tng_trajectory_t tng_data, @@ -1195,6 +1227,23 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_add tng_residue_t *residue); /** + * @brief Add a residue with a specific ID to a chain. + * @param tng_data is the trajectory data container containing the chain.. + * @param chain is the chain to add a residue to. + * @param name is a string containing the name of the residue. + * @param id is the ID of the created residue. + * @param residue is a pointer to the newly created residue. + * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the ID could + * not be set properly or TNG_CRITICAL (2) if a major error has occured. + */ +tng_function_status DECLSPECDLLEXPORT tng_chain_residue_w_id_add + (tng_trajectory_t tng_data, + tng_chain_t chain, + const char *name, + const int64_t id, + tng_residue_t *residue); + +/** * @brief Set the name of a residue. * @param tng_data is the trajectory data container containing the residue. * @param residue is the residue to rename. @@ -1214,8 +1263,8 @@ tng_function_status DECLSPECDLLEXPORT tng_residue_name_set * @param atom_name is a string containing the name of the atom. * @param atom_type is a string containing the atom type of the atom. * @param atom is a pointer to the newly created atom. - * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major - * error has occured. + * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the ID could + * not be set properly or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_residue_atom_add (tng_trajectory_t tng_data, @@ -1225,6 +1274,25 @@ tng_function_status DECLSPECDLLEXPORT tng_residue_atom_add tng_atom_t *atom); /** + * @brief Add an atom with a specific ID to a residue. + * @param tng_data is the trajectory containing the residue. + * @param residue is the residue to add an atom to. + * @param atom_name is a string containing the name of the atom. + * @param atom_type is a string containing the atom type of the atom. + * @param id is the ID of the created atom. + * @param atom is a pointer to the newly created atom. + * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the ID could + * not be set properly or TNG_CRITICAL (2) if a major error has occured. + */ +tng_function_status DECLSPECDLLEXPORT tng_residue_atom_w_id_add + (tng_trajectory_t tng_data, + tng_residue_t residue, + const char *atom_name, + const char *atom_type, + const int64_t id, + tng_atom_t *atom); + +/** * @brief Set the name of an atom. * @param tng_data is the trajectory data container containing the atom. * @param atom is the atom to rename. @@ -1941,13 +2009,13 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_close // int64_t *n_mols, // int64_t *molecule_cnt_list, // tng_molecule_t *mols); -// +// // tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_molecule_add // (tng_trajectory_t tng_data, // const char *name, // const int64_t cnt, // tng_molecule_t *mol); -// +// // tng_function_status DECLSPECDLLEXPORT tng_util_molecule_particles_get // (tng_trajectory_t tng_data, // const tng_molecule_t mol, @@ -1958,7 +2026,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_close // int64_t **res_ids, // char ***chain_names, // int64_t **chain_ids); -// +// // tng_function_status DECLSPECDLLEXPORT tng_util_molecule_particles_set // (tng_trajectory_t tng_data, // tng_molecule_t mol, @@ -1969,7 +2037,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_close // const int64_t *res_ids, // const char **chain_names, // const int64_t *chain_ids); - + /** * @brief High-level function for reading the positions of all particles * from all frames. diff --git a/src/lib/tng_io.c b/src/lib/tng_io.c index 055507c..478c804 100644 --- a/src/lib/tng_io.c +++ b/src/lib/tng_io.c @@ -1,6 +1,6 @@ /* This code is part of the tng binary trajectory format. * - * VERSION 1.0 + * VERSION 1.1 * * Written by Magnus Lundborg * Copyright (c) 2012, The GROMACS development team. @@ -6625,15 +6625,46 @@ static tng_function_status tng_atom_destroy(tng_atom_t atom) return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_add(tng_trajectory_t tng_data, - const char *name, - tng_molecule_t *molecule) +tng_function_status DECLSPECDLLEXPORT tng_molecule_add + (tng_trajectory_t tng_data, + const char *name, + tng_molecule_t *molecule) { - tng_molecule_t new_molecules; - int64_t *new_molecule_cnt_list; int id, i; tng_bool found_id = TNG_TRUE; + /* Find an unused ID */ + id = 0; + while(found_id) + { + found_id = TNG_FALSE; + for(i = tng_data->n_molecules; i--;) + { + if(tng_data->molecules[i].id == id) + { + found_id = TNG_TRUE; + i = 0; + } + } + if(found_id) + { + id++; + } + } + + return(tng_molecule_w_id_add(tng_data, name, id, molecule)); +} + +tng_function_status DECLSPECDLLEXPORT tng_molecule_w_id_add + (tng_trajectory_t tng_data, + const char *name, + const int64_t id, + tng_molecule_t *molecule) +{ + tng_molecule_t new_molecules; + int64_t *new_molecule_cnt_list, i; + tng_function_status stat = TNG_SUCCESS; + new_molecules = realloc(tng_data->molecules, sizeof(struct tng_molecule) * (tng_data->n_molecules + 1)); @@ -6671,22 +6702,13 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_add(tng_trajectory_t tng_data /* FIXME: Should this be a function argument instead? */ tng_data->molecule_cnt_list[tng_data->n_molecules] = 0; - /* Find an unused ID */ - id = 0; - while(found_id) + for(i = tng_data->n_molecules; i--;) { - found_id = TNG_FALSE; - for(i = tng_data->n_molecules; i--;) + if(tng_data->molecules[i].id == id) { - if(tng_data->molecules[i].id == id) - { - found_id = TNG_TRUE; - i = 0; - } - } - if(found_id) - { - id++; + stat = TNG_FAILURE; + printf("Molecule ID already in use. %s: %d\n", __FILE__, __LINE__); + break; } } @@ -6694,12 +6716,13 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_add(tng_trajectory_t tng_data tng_data->n_molecules++; - return(TNG_SUCCESS); + return(stat); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_name_set(tng_trajectory_t tng_data, - tng_molecule_t molecule, - const char *new_name) +tng_function_status DECLSPECDLLEXPORT tng_molecule_name_set + (tng_trajectory_t tng_data, + tng_molecule_t molecule, + const char *new_name) { int len; @@ -6728,9 +6751,10 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_name_set(tng_trajectory_t tng return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_get(tng_trajectory_t tng_data, - tng_molecule_t molecule, - int64_t *cnt) +tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_get + (tng_trajectory_t tng_data, + tng_molecule_t molecule, + int64_t *cnt) { int i, index = -1; @@ -6751,9 +6775,10 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_get(tng_trajectory_t tng_ return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_set(tng_trajectory_t tng_data, - tng_molecule_t molecule, - const int64_t cnt) +tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_set + (tng_trajectory_t tng_data, + tng_molecule_t molecule, + const int64_t cnt) { int i, index = -1, old_cnt; @@ -6778,11 +6803,12 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_set(tng_trajectory_t tng_ return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_find(tng_trajectory_t tng_data, - tng_molecule_t molecule, - const char *name, - int64_t nr, - tng_chain_t *chain) +tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_find + (tng_trajectory_t tng_data, + tng_molecule_t molecule, + const char *name, + int64_t nr, + tng_chain_t *chain) { int i, n_chains; @@ -6805,12 +6831,26 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_find(tng_trajectory_t t return(TNG_FAILURE); } -/* FIXME: For v. 2 the chain nr should also be possible to specify. */ -tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_add(tng_trajectory_t tng_data, - tng_molecule_t molecule, - const char *name, - tng_chain_t *chain) +tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_add + (tng_trajectory_t tng_data, + tng_molecule_t molecule, + const char *name, + tng_chain_t *chain) { + return(tng_molecule_chain_w_id_add(tng_data, molecule, name, + molecule->n_chains + 1, chain)); +} + +tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_w_id_add + (tng_trajectory_t tng_data, + tng_molecule_t molecule, + const char *name, + const int64_t id, + tng_chain_t *chain) +{ + int64_t i; + tng_function_status stat = TNG_SUCCESS; + tng_chain_t new_chains; new_chains = realloc(molecule->chains, @@ -6836,16 +6876,28 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_add(tng_trajectory_t tn (*chain)->molecule = molecule; (*chain)->n_residues = 0; + + for(i = molecule->n_chains; i--;) + { + if(molecule->chains[i].id == id) + { + stat = TNG_FAILURE; + printf("Chain ID already in use. %s: %d\n", __FILE__, __LINE__); + break; + } + } + molecule->n_chains++; - (*chain)->id = molecule->n_chains; + (*chain)->id = id; - return(TNG_SUCCESS); + return(stat); } -tng_function_status DECLSPECDLLEXPORT tng_chain_name_set(tng_trajectory_t tng_data, - tng_chain_t chain, - const char *new_name) +tng_function_status DECLSPECDLLEXPORT tng_chain_name_set + (tng_trajectory_t tng_data, + tng_chain_t chain, + const char *new_name) { int len; @@ -6874,11 +6926,12 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_name_set(tng_trajectory_t tng_da return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_chain_residue_find(tng_trajectory_t tng_data, - tng_chain_t chain, - const char *name, - int64_t id, - tng_residue_t *residue) +tng_function_status DECLSPECDLLEXPORT tng_chain_residue_find + (tng_trajectory_t tng_data, + tng_chain_t chain, + const char *name, + int64_t id, + tng_residue_t *residue) { int i, n_residues; @@ -6901,15 +6954,28 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_find(tng_trajectory_t tn return(TNG_FAILURE); } -/* FIXME: For v. 2 the residue nr should also be possible to specify. */ -tng_function_status DECLSPECDLLEXPORT tng_chain_residue_add(tng_trajectory_t tng_data, - tng_chain_t chain, - const char *name, - tng_residue_t *residue) +tng_function_status DECLSPECDLLEXPORT tng_chain_residue_add + (tng_trajectory_t tng_data, + tng_chain_t chain, + const char *name, + tng_residue_t *residue) +{ + return(tng_chain_residue_w_id_add(tng_data, chain, name, + chain->n_residues + 1, residue)); +} + +tng_function_status DECLSPECDLLEXPORT tng_chain_residue_w_id_add + (tng_trajectory_t tng_data, + tng_chain_t chain, + const char *name, + const int64_t id, + tng_residue_t *residue) { + int64_t i; int curr_index; tng_residue_t new_residues, temp_residue, last_residue; tng_molecule_t molecule = chain->molecule; + tng_function_status stat; if(chain->n_residues) { @@ -6972,12 +7038,22 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_add(tng_trajectory_t tng (*residue)->n_atoms = 0; (*residue)->atoms_offset = 0; + for(i = chain->n_residues; i--;) + { + if(chain->residues[i].id == id) + { + stat = TNG_FAILURE; + printf("Residue ID already in use. %s: %d\n", __FILE__, __LINE__); + break; + } + } + chain->n_residues++; molecule->n_residues++; - (*residue)->id = chain->n_residues; + (*residue)->id = id; - return(TNG_SUCCESS); + return(stat); } tng_function_status DECLSPECDLLEXPORT tng_residue_name_set(tng_trajectory_t tng_data, @@ -7011,15 +7087,30 @@ tng_function_status DECLSPECDLLEXPORT tng_residue_name_set(tng_trajectory_t tng_ return(TNG_SUCCESS); } -/* FIXME: For v. 2 the atom nr should also be possible to specify. */ -tng_function_status DECLSPECDLLEXPORT tng_residue_atom_add(tng_trajectory_t tng_data, - tng_residue_t residue, - const char *atom_name, - const char *atom_type, - tng_atom_t *atom) +tng_function_status DECLSPECDLLEXPORT tng_residue_atom_add + (tng_trajectory_t tng_data, + tng_residue_t residue, + const char *atom_name, + const char *atom_type, + tng_atom_t *atom) +{ + return(tng_residue_atom_w_id_add(tng_data, residue, atom_name, atom_type, + residue->chain->molecule->n_atoms + 1, + atom)); +} + +tng_function_status DECLSPECDLLEXPORT tng_residue_atom_w_id_add + (tng_trajectory_t tng_data, + tng_residue_t residue, + const char *atom_name, + const char *atom_type, + const int64_t id, + tng_atom_t *atom) { + int64_t i; tng_atom_t new_atoms; tng_molecule_t molecule = residue->chain->molecule; + tng_function_status stat; if(!residue->n_atoms) { @@ -7049,15 +7140,24 @@ tng_function_status DECLSPECDLLEXPORT tng_residue_atom_add(tng_trajectory_t tng_ (*atom)->residue = residue; + for(i = molecule->n_atoms; i--;) + { + if(molecule->atoms[i].id == id) + { + stat = TNG_FAILURE; + printf("Atom ID already in use. %s: %d\n", __FILE__, __LINE__); + break; + } + } + residue->n_atoms++; molecule->n_atoms++; - (*atom)->id = molecule->n_atoms; + (*atom)->id = id; - return(TNG_SUCCESS); + return(stat); } - tng_function_status DECLSPECDLLEXPORT tng_molecule_init(const tng_trajectory_t tng_data, tng_molecule_t molecule) { @@ -12196,7 +12296,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_vector_interval_get { tot_n_frames = end_frame_nr - start_frame_nr + 1; } - + switch(*type) { case TNG_CHAR_DATA: @@ -13512,7 +13612,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write else { block_type_flag = TNG_TRAJECTORY_BLOCK; - + if(!frame_set || tng_data->n_trajectory_frame_sets <= 0) { stat = tng_frame_set_new(tng_data, 0, n_frames); @@ -13635,7 +13735,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write frame_pos = (frame_nr - frame_set->first_frame) / stride_length; - memcpy(np_data->values + sizeof(float) * frame_pos * + memcpy(np_data->values + sizeof(float) * frame_pos * n_values_per_frame, values, sizeof(float) * n_values_per_frame); } |