/* Create a TNG molecule representing the selection groups * to write */ static void add_selection_groups(tng_trajectory_t tng, const gmx_mtop_t *mtop) { const gmx_moltype_t *molType; const t_atoms *atoms; const t_atom *at; const t_resinfo *resInfo; const t_ilist *ilist; int nAtoms = 0, i = 0, j, molIt, atomIt, nameIndex; int atom_offset = 0; tng_molecule_t mol, iterMol; tng_chain_t chain; tng_residue_t res; tng_atom_t atom; tng_bond_t tngBond; gmx_int64_t nMols; char *groupName; /* The name of the TNG molecule containing the selection group is the * same as the name of the selection group. */ nameIndex = *mtop->groups.grps[egcCompressedX].nm_ind; groupName = *mtop->groups.grpname[nameIndex]; tng_molecule_alloc(tng, &mol); tng_molecule_name_set(tng, mol, groupName); tng_molecule_chain_add(tng, mol, "", &chain); for (molIt = 0; molIt < mtop->nmoltype; molIt++) { molType = &mtop->moltype[mtop->molblock[molIt].type]; atoms = &molType->atoms; for (j = 0; j < mtop->molblock[molIt].nmol; j++) { bool bAtomsAdded = FALSE; for (atomIt = 0; atomIt < atoms->nr; atomIt++, i++) { char *res_name; int res_id; if (ggrpnr(&mtop->groups, egcCompressedX, i) != 0) { continue; } at = &atoms->atom[atomIt]; if (atoms->nres > 0) { resInfo = &atoms->resinfo[at->resind]; /* FIXME: When TNG supports both residue index and residue * number the latter should be used. */ res_name = *resInfo->name; res_id = at->resind + 1; } else { res_name = (char *)""; res_id = 0; } if (tng_chain_residue_find(tng, chain, res_name, res_id, &res) != TNG_SUCCESS) { /* Since there is ONE chain for selection groups do not keep the * original residue IDs - otherwise there might be conflicts. */ tng_chain_residue_add(tng, chain, res_name, &res); } tng_residue_atom_w_id_add(tng, res, *(atoms->atomname[atomIt]), *(atoms->atomtype[atomIt]), atom_offset + atomIt, &atom); nAtoms++; bAtomsAdded = TRUE; } /* Add bonds. */ if (bAtomsAdded) { for (int k = 0; k < F_NRE; k++) { if (IS_CHEMBOND(k)) { ilist = &molType->ilist[k]; if (ilist) { int l = 1; while (l < ilist->nr) { int atom1, atom2; atom1 = ilist->iatoms[l] + atom_offset; atom2 = ilist->iatoms[l+1] + atom_offset; if (ggrpnr(&mtop->groups, egcCompressedX, atom1) == 0 && ggrpnr(&mtop->groups, egcCompressedX, atom2) == 0) { tng_molecule_bond_add(tng, mol, ilist->iatoms[l], ilist->iatoms[l+1], &tngBond); } l += 3; } } } } /* Settle is described using three atoms */ ilist = &molType->ilist[F_SETTLE]; if (ilist) { int l = 1; while (l < ilist->nr) { int atom1, atom2, atom3; atom1 = ilist->iatoms[l] + atom_offset; atom2 = ilist->iatoms[l+1] + atom_offset; atom3 = ilist->iatoms[l+2] + atom_offset; if (ggrpnr(&mtop->groups, egcCompressedX, atom1) == 0) { if (ggrpnr(&mtop->groups, egcCompressedX, atom2) == 0) { tng_molecule_bond_add(tng, mol, atom1, atom2, &tngBond); } if (ggrpnr(&mtop->groups, egcCompressedX, atom3) == 0) { tng_molecule_bond_add(tng, mol, atom1, atom3, &tngBond); } } l += 4; } } } atom_offset += atoms->nr; } } if (nAtoms != i) { tng_molecule_existing_add(tng, &mol); tng_molecule_cnt_set(tng, mol, 1); tng_num_molecule_types_get(tng, &nMols); for (gmx_int64_t k = 0; k < nMols; k++) { tng_molecule_of_index_get(tng, k, &iterMol); if (iterMol == mol) { continue; } tng_molecule_cnt_set(tng, iterMol, 0); } } else { tng_molecule_free(tng, &mol); } }
void gmx_tng_setup_atom_subgroup(tng_trajectory_t tng, const int nind, const int *ind, const char *name) { #if GMX_USE_TNG gmx_int64_t nAtoms, cnt, nMols; tng_molecule_t mol, iterMol; tng_chain_t chain; tng_residue_t res; tng_atom_t atom; tng_function_status stat; tng_num_particles_get(tng, &nAtoms); if (nAtoms == nind) { return; } stat = tng_molecule_find(tng, name, -1, &mol); if (stat == TNG_SUCCESS) { tng_molecule_num_atoms_get(tng, mol, &nAtoms); tng_molecule_cnt_get(tng, mol, &cnt); if (nAtoms == nind) { stat = TNG_SUCCESS; } else { stat = TNG_FAILURE; } } if (stat == TNG_FAILURE) { /* The indexed atoms are added to one separate molecule. */ tng_molecule_alloc(tng, &mol); tng_molecule_name_set(tng, mol, name); tng_molecule_chain_add(tng, mol, "", &chain); for (int i = 0; i < nind; i++) { char temp_name[256], temp_type[256]; /* Try to retrieve the residue name of the atom */ stat = tng_residue_name_of_particle_nr_get(tng, ind[i], temp_name, 256); if (stat != TNG_SUCCESS) { temp_name[0] = '\0'; } /* Check if the molecule of the selection already contains this residue */ if (tng_chain_residue_find(tng, chain, temp_name, -1, &res) != TNG_SUCCESS) { tng_chain_residue_add(tng, chain, temp_name, &res); } /* Try to find the original name and type of the atom */ stat = tng_atom_name_of_particle_nr_get(tng, ind[i], temp_name, 256); if (stat != TNG_SUCCESS) { temp_name[0] = '\0'; } stat = tng_atom_type_of_particle_nr_get(tng, ind[i], temp_type, 256); if (stat != TNG_SUCCESS) { temp_type[0] = '\0'; } tng_residue_atom_w_id_add(tng, res, temp_name, temp_type, ind[i], &atom); } tng_molecule_existing_add(tng, &mol); } /* Set the count of the molecule containing the selected atoms to 1 and all * other molecules to 0 */ tng_molecule_cnt_set(tng, mol, 1); tng_num_molecule_types_get(tng, &nMols); for (gmx_int64_t k = 0; k < nMols; k++) { tng_molecule_of_index_get(tng, k, &iterMol); if (iterMol == mol) { continue; } tng_molecule_cnt_set(tng, iterMol, 0); } #else GMX_UNUSED_VALUE(tng); GMX_UNUSED_VALUE(nind); GMX_UNUSED_VALUE(ind); GMX_UNUSED_VALUE(name); #endif }