This example shows one way of using the information about a partner atom in a connection, detailed in the the struct_conn category, to identify the atom in the atom_site category, and, in this case, to determine the (x,y,z) Cartesian coordinates of said atom. Given that the struct_conn table contains all of the information necessary to uniquely identify a partner atom, the basic idea is to find the row in the atom_site table that contains the exact same identifying information. In this case, we look for partner atoms involved in covalent bonds and report their (x,y,z) coordinates, although this program is easily extended to other connection types or connections involving specific atoms.
Save Connections3.C to/path/to/cifparse-obj-vX.X-prod-src/parser-test-app-vX.X/src/Save the CIF file anywhere, e.g.,/path/to/cifparse-obj-vX.X-prod-src/parser-test-app-vX.X/bin/Add Connections3.ext to the BASE_MAIN_FILES list in the Makefile in/path/to/cifparse-obj.vX.X-prod-src/parser-test-app-vX.XExecutemakein the same directory as the Makefilecdto bin, where the executable has been made, and run./Connections3 /path/to/5HVP.cif
#include "CifFile.h"
CifFile::GetBlockNames(vector<string>& blockNames). #include "ISTable.h"
void ISTable::GetRow(vector<string>& row, const unsigned int rowIndex, const string& fromColName = string(), const string& toColName = string())../Connections3 5HVP.cif
Found a covalent bond between atoms located at: (10.978, 24.553, 5.700) & (12.126, 24.878, 5.008)
Found a covalent bond between atoms located at: (15.234, 20.788, 5.209) & (15.468, 22.108, 5.234)
Found a covalent bond between atoms located at: (14.767, 21.286, 5.304) & (15.827, 20.674, 4.766)
Found a covalent bond between atoms located at: (11.557, 24.225, 5.627) & (10.971, 25.421, 5.774)
Found a covalent bond between atoms located at: (17.704, 19.162, 5.397) & (17.913, 18.389, 6.465)
Found a covalent bond between atoms located at: (8.709, 26.437, 5.751) & (7.475, 25.908, 5.659)
/*************************
* Connections3.C
*
* For some CIF file, determine the (x, y, z) Cartesian coordinates
* of every atom involved in a covalent linkage.
*
* Method: Using the identifying information in the struct_conn category table,
* whittle down the set of possible indices in the atom_site category table to one.
*
* Highlighted lines contain footnoted references or explanations.
*************************/
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include "CifFile.h"
#include "CifParserBase.h"
#include "ISTable.h"
void showUsage();
int main(int argc, char **argv)
{
if (argc != 2)
{
showUsage();
}
// The name of the CIF file
string cifFileName = argv[1];
// A string to hold any parsing diagnostics
string diagnostics;
// Create CIF file and parser objects
CifFile *cifFileP = new CifFile;
CifParser *cifParserP = new CifParser(cifFileP);
// Parse the CIF file
cifParserP->Parse(cifFileName, diagnostics);
// Delete the CIF parser, as it is no longer needed
delete cifParserP;
// Display any diagnostics
if (!diagnostics.empty())
{
std::cout << "Diagnostics: " << std::endl << diagnostics << std::endl;
}
// Get the first data block name in the CIF file
string firstBlockName = cifFileP->GetFirstBlockName();
// Retrieve the first data block
Block &block = cifFileP->GetBlock(firstBlockName);
// Retrieve the table corresponding to the struct_conn category, which delineates connections1
ISTable& struct_conn = block.GetTable("struct_conn");
// Retrieve the table corresponding to the atom_site category, which describes atomic constituents2
ISTable& atom_site = block.GetTable("atom_site");
// Iterate through every row in the struct_conn category table, where each row delineates an interatomic connection
for (unsigned int i = 0; i < struct_conn.GetNumRows(); ++i)
{
// Verify that the linkage is covalent3
if (struct_conn(i, "conn_type_id") != "covale")
{
continue;
}
std::cout << "\nFound a covalent bond between atoms located at: ";
// Analyze the current row twice, once per partner
for (unsigned int j = 0; j < 2; ++j)
{
// Determine which partner we are dealing with
string partner = (!j) ? "ptnr1_" : "ptnr2_";
// Will hold the index of the atom in the atom_site category table
vector<unsigned int> results;
// Holds the attribute names and target values for these attributes4
vector<string> colNames, targets;
colNames.push_back("label_alt_id");
targets.push_back(struct_conn(i, "pdbx_" + partner + "label_alt_id"));
colNames.push_back("auth_asym_id");
targets.push_back(struct_conn(i, partner + "auth_asym_id"));
colNames.push_back("label_atom_id");
targets.push_back(struct_conn(i, partner + "label_atom_id"));
colNames.push_back("auth_comp_id");
targets.push_back(struct_conn(i, partner + "auth_comp_id"));
colNames.push_back("auth_seq_id");
targets.push_back(struct_conn(i, partner + "auth_seq_id"));
// Perform a search on the atom_site table using the atom's unique identification information
atom_site.Search(results, targets, colNames);
// Retrieve and display the atom's coordinates
vector<string> temp;
atom_site.GetRow(temp, results[0], "Cartn_x", "Cartn_z");5
std::cout << "(" + temp[0] + ", " + temp[1] + ", " + temp[2] + ")";
// Add an 'and' before partner 2
if (!j)
{
std::cout << " & ";
}
}
}
std::cout << std::endl;
return 0;
}
void showUsage()
{
std::cout << "Usage: ./Connections3 /path/to/file.cif" << std::endl;
exit(1);
}