int colvarproxy_namd::load_atoms(char const *pdb_filename, cvm::atom_group &atoms, std::string const &pdb_field_str, double const pdb_field_value) { if (pdb_field_str.size() == 0) cvm::error("Error: must define which PDB field to use " "in order to define atoms from a PDB file.\n", INPUT_ERROR); PDB *pdb = new PDB(pdb_filename); size_t const pdb_natoms = pdb->num_atoms(); e_pdb_field pdb_field_index = pdb_field_str2enum(pdb_field_str); for (size_t ipdb = 0; ipdb < pdb_natoms; ipdb++) { double atom_pdb_field_value = 0.0; switch (pdb_field_index) { case e_pdb_occ: atom_pdb_field_value = (pdb->atom(ipdb))->occupancy(); break; case e_pdb_beta: atom_pdb_field_value = (pdb->atom(ipdb))->temperaturefactor(); break; case e_pdb_x: atom_pdb_field_value = (pdb->atom(ipdb))->xcoor(); break; case e_pdb_y: atom_pdb_field_value = (pdb->atom(ipdb))->ycoor(); break; case e_pdb_z: atom_pdb_field_value = (pdb->atom(ipdb))->zcoor(); break; default: break; } if ( (pdb_field_value) && (atom_pdb_field_value != pdb_field_value) ) { continue; } else if (atom_pdb_field_value == 0.0) { continue; } if (atoms.is_enabled(colvardeps::f_ag_scalable)) { atoms.add_atom_id(ipdb); } else { atoms.add_atom(cvm::atom(ipdb+1)); } } delete pdb; return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); }
int colvarproxy_namd::load_coords(char const *pdb_filename, std::vector<cvm::atom_pos> &pos, const std::vector<int> &indices, std::string const &pdb_field_str, double const pdb_field_value) { if (pdb_field_str.size() == 0 && indices.size() == 0) { cvm::error("Bug alert: either PDB field should be defined or list of " "atom IDs should be available when loading atom coordinates!\n", BUG_ERROR); } e_pdb_field pdb_field_index; bool const use_pdb_field = (pdb_field_str.size() > 0); if (use_pdb_field) { pdb_field_index = pdb_field_str2enum(pdb_field_str); } // next index to be looked up in PDB file (if list is supplied) std::vector<int>::const_iterator current_index = indices.begin(); PDB *pdb = new PDB(pdb_filename); size_t const pdb_natoms = pdb->num_atoms(); if (pos.size() != pdb_natoms) { bool const pos_allocated = (pos.size() > 0); size_t ipos = 0, ipdb = 0; for ( ; ipdb < pdb_natoms; ipdb++) { if (use_pdb_field) { // PDB field mode: skip atoms with wrong value in PDB field double atom_pdb_field_value = 0.0; switch (pdb_field_index) { case e_pdb_occ: atom_pdb_field_value = (pdb->atom(ipdb))->occupancy(); break; case e_pdb_beta: atom_pdb_field_value = (pdb->atom(ipdb))->temperaturefactor(); break; case e_pdb_x: atom_pdb_field_value = (pdb->atom(ipdb))->xcoor(); break; case e_pdb_y: atom_pdb_field_value = (pdb->atom(ipdb))->ycoor(); break; case e_pdb_z: atom_pdb_field_value = (pdb->atom(ipdb))->zcoor(); break; default: break; } if ( (pdb_field_value) && (atom_pdb_field_value != pdb_field_value) ) { continue; } else if (atom_pdb_field_value == 0.0) { continue; } } else { // Atom ID mode: use predefined atom IDs from the atom group if (((int) ipdb) != *current_index) { // Skip atoms not in the list continue; } else { current_index++; } } if (!pos_allocated) { pos.push_back(cvm::atom_pos(0.0, 0.0, 0.0)); } else if (ipos >= pos.size()) { cvm::error("Error: the PDB file \""+ std::string(pdb_filename)+ "\" contains coordinates for " "more atoms than needed.\n", BUG_ERROR); } pos[ipos] = cvm::atom_pos((pdb->atom(ipdb))->xcoor(), (pdb->atom(ipdb))->ycoor(), (pdb->atom(ipdb))->zcoor()); ipos++; if (!use_pdb_field && current_index == indices.end()) break; } if (ipos < pos.size() || (!use_pdb_field && current_index != indices.end())) { size_t n_requested = use_pdb_field ? pos.size() : indices.size(); cvm::error("Error: number of matching records in the PDB file \""+ std::string(pdb_filename)+"\" ("+cvm::to_str(ipos)+ ") does not match the number of requested coordinates ("+ cvm::to_str(n_requested)+").\n", INPUT_ERROR); return COLVARS_ERROR; } } else { // when the PDB contains exactly the number of atoms of the array, // ignore the fields and just read coordinates for (size_t ia = 0; ia < pos.size(); ia++) { pos[ia] = cvm::atom_pos((pdb->atom(ia))->xcoor(), (pdb->atom(ia))->ycoor(), (pdb->atom(ia))->zcoor()); } } delete pdb; return COLVARS_OK; }