From 909cf6a300b5a981e12cb4fee35da19b4af77820 Mon Sep 17 00:00:00 2001 From: Magnus Lundborg Date: Wed, 5 Jun 2013 14:45:04 +0200 Subject: Added functions to set ID when adding molecular data. When creating molecules, chains, residues and atoms it is now possible to specify the IDs. Raised the version number to 1.1. 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 * #include * #include - * + * * 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); } -- cgit v0.10.1