本文整理汇总了C++中OBMol::GetData方法的典型用法代码示例。如果您正苦于以下问题:C++ OBMol::GetData方法的具体用法?C++ OBMol::GetData怎么用?C++ OBMol::GetData使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类OBMol
的用法示例。
在下文中一共展示了OBMol::GetData方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: testSpaceGroupClean
void testSpaceGroupClean()
{
// See https://github.com/openbabel/openbabel/pull/254
OBConversion conv;
OBMol mol;
conv.SetInFormat("cif");
conv.SetOutFormat("pdb");
conv.ReadFile(&mol, GetFilename("test02.cif"));
OBUnitCell* pUC = (OBUnitCell*)mol.GetData(OBGenericDataType::UnitCell);
const SpaceGroup* pSG = pUC->GetSpaceGroup();
SpaceGroup* sg = new SpaceGroup(*pSG);
pSG = SpaceGroup::Find(sg);
OB_ASSERT( pSG != NULL );
// Check also for errors and warnings
string summary = obErrorLog.GetMessageSummary();
OB_ASSERT( summary.find("error") == string::npos);
OB_ASSERT( summary.find("warning") == string::npos);
OB_ASSERT( pSG->GetId() == 166 );
string pdb = conv.WriteString(&mol);
pdb = conv.WriteString(&mol);
OB_ASSERT(pdb.find("H -3 m") != string::npos);
}
示例2: WriteMolecule
bool ThermoFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
{
OBMol* pmol = dynamic_cast<OBMol*>(pOb);
string title(pmol->GetTitle());
OBNasaThermoData* pND = static_cast<OBNasaThermoData*>(pmol->GetData(ThermoData));
if(!pND)
{
obErrorLog.ThrowError(__FUNCTION__,"No thermo data in " + title, obWarning);
return false;
}
ostream &ofs = *pConv->GetOutStream();
unsigned int i;
#ifdef _MSC_VER
unsigned oldf = _set_output_format(_TWO_DIGIT_EXPONENT);
#endif
string formula = pmol->GetSpacedFormula();
vector<string> toks;
tokenize(toks,formula);
ofs << left << setw(24) << title.substr(0,24);
//Check that atom numbers are less than 999
bool toobig=toks.size()>8;
for(i=0;i<toks.size() && !toobig ;i+=2)
if(atoi(toks[i+1].c_str())>999)
toobig =true;
if(toobig)
//Reaction Design extension
ofs << string(20,' ');
else
{
toks.resize(8);
for(i=0;i<8;i+=2)
ofs << left << setw(2) << toks[i] << right << setw(3) << toks[i+1];
}
ofs << right << pND->GetPhase() << fixed << setprecision(3) << setw(10) << pND->GetLoT();
ofs << setw(10) << pND->GetHiT() << setw(9) << pND->GetMidT() << " 01";
if(toobig)
ofs << "&\n" << formula << '\n';
else
ofs << '\n';
ofs << scientific << setprecision(7);
for(i=0;i<5;++i)
ofs << setw(15) << pND->GetCoeff(i);
ofs << " 2\n";
for(i=5;i<10;++i)
ofs << setw(15) << pND->GetCoeff(i);
ofs << " 3\n";
for(i=10;i<14;++i)
ofs << setw(15) << pND->GetCoeff(i);
ofs << " 4\n";
#ifdef _MSC_VER
_set_output_format(oldf);
#endif
return true;
}
示例3:
OBMolAngleIter::OBMolAngleIter(OBMol &mol)
{
mol.FindAngles();
OBAngleData *ad = (OBAngleData *) mol.GetData(OBGenericDataType::AngleData);
ad->FillAngleArray(_vangle);
_parent = &mol;
if (!_vangle.empty()) {
_i = _vangle.begin();
_angle = *_i;
} else {
_i = _vangle.end();
}
}
示例4: exportVibrationData
void VibrationDialog::exportVibrationData(bool)
{
QFileInfo defaultFile(m_molecule->fileName());
QString defaultPath = defaultFile.canonicalPath();
if (defaultPath.isEmpty())
defaultPath = QDir::homePath();
QString defaultFileName = defaultPath + '/' + defaultFile.baseName() + ".tsv";
QString filename = QFileDialog::getSaveFileName(this, tr("Export Vibrational Data"), defaultFileName, tr("Tab Separated Values (*.tsv)"));
QFile file (filename);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qWarning() << "Cannot open file " << filename << " for writing!";
return;
}
OBMol obmol = m_molecule->OBMol();
m_vibrations = static_cast<OBVibrationData*>(obmol.GetData(OBGenericDataType::VibrationData));
if (!m_vibrations) {
qWarning("No vibration data, but export button is enabled? Something is broken.");
return;
}
vector<double> frequencies = m_vibrations->GetFrequencies();
vector<double> intensities = m_vibrations->GetIntensities();
QTextStream out(&file);
out << "Frequencies\tIntensities\n";
QString format = "%1\t%2\n";
for (unsigned int line = 0; line < frequencies.size(); ++line) {
QString intensity;
// we can't trust that we'll actually get intensities
// some formats don't report them
if (line >= intensities.size())
intensity = '-';
else
intensity = QString("%L1").arg(intensities[line], 0, 'f', 2);
out << format.arg(frequencies[line], 0, 'f', 2).arg(intensity);
}
file.close();
return;
}
示例5: testAlternativeOrigin
void testAlternativeOrigin()
{
// See https://github.com/openbabel/openbabel/pull/1558
OBConversion conv;
OBMol mol;
conv.SetInFormat("cif");
conv.ReadFile(&mol, GetFilename("test04.cif"));
OBUnitCell* pUC = (OBUnitCell*)mol.GetData(OBGenericDataType::UnitCell);
const SpaceGroup* pSG = pUC->GetSpaceGroup();
SpaceGroup* sg = new SpaceGroup(*pSG);
pSG = SpaceGroup::Find(sg);
string summary = obErrorLog.GetMessageSummary();
OB_ASSERT( summary.find("warning") == string::npos);
OB_ASSERT( pSG != NULL );
OB_ASSERT( pSG->GetOriginAlternative() == 1);
}
示例6: WriteReport
bool WriteReport(ostream &ofs,OBMol &mol)
{
char buffer[BUFF_SIZE];
ofs << "FILENAME: " << mol.GetTitle() << endl;
ofs << "MASS: ";
sprintf(buffer, "%5.4f", mol.GetMolWt());
ofs << buffer << endl;
ofs << "EXACT MASS: ";
sprintf(buffer, "%5.7f", mol.GetExactMass());
ofs << buffer << endl;
if (mol.GetTotalCharge() != 0)
{
ofs << "TOTAL CHARGE: ";
sprintf(buffer, "%d", mol.GetTotalCharge());
ofs << buffer << endl;
}
if (mol.GetTotalSpinMultiplicity() != 1)
{
ofs << "TOTAL SPIN: ";
sprintf(buffer, "%d", mol.GetTotalSpinMultiplicity());
ofs << buffer << endl;
}
ofs << "INTERATOMIC DISTANCES" << endl;
WriteDistanceMatrix(ofs, mol);
ofs << endl << endl << "ATOMIC CHARGES" << endl;
WriteCharges(ofs, mol);
ofs << endl << endl << "BOND ANGLES" << endl;
WriteAngles(ofs, mol);
ofs << endl << endl << "TORSION ANGLES" << endl;
WriteTorsions(ofs, mol);
if (mol.IsChiral())
{
ofs << endl << endl << "CHIRAL ATOMS" << endl;
WriteChiral(ofs, mol);
}
if (mol.HasData(obCommentData)) {
ofs << endl << endl << "COMMENTS" << endl;
OBCommentData *cd = (OBCommentData*)mol.GetData(obCommentData);
ofs << cd->GetData() << endl;
}
ofs << endl << endl;
return(true);
}
示例7: testDecayToP1
void testDecayToP1()
{
// See https://github.com/openbabel/openbabel/pull/261
OBConversion conv;
OBMol mol;
conv.SetInFormat("cif");
conv.ReadFile(&mol, GetFilename("test03.cif"));
OBUnitCell* pUC = (OBUnitCell*)mol.GetData(OBGenericDataType::UnitCell);
const SpaceGroup* pSG = pUC->GetSpaceGroup();
SpaceGroup* sg = new SpaceGroup(*pSG);
pSG = SpaceGroup::Find(sg);
OB_ASSERT( pSG != NULL );
// Check also for errors and warnings
string summary = obErrorLog.GetMessageSummary();
OB_ASSERT( summary.find("2 warnings") != string::npos);
OB_ASSERT( pSG->GetId() == 1 );
}
示例8: MakeCombinedMolecule
/*! Makes a new OBMol on the heap by combining two molecules according to the rule below.
If both have OBGenericData of the same type, or OBPairData with the
same attribute, the version from pFirst is used.
Returns a pointer to a new OBMol which will need deleting by the calling program
(probably by being sent to an output format).
If the molecules cannot be regarded as being the same structure a NULL
pointer is returned and an error message logged.
pFirst and pSecond and the objects they point to are not changed. (const
modifiers difficult because class OBMol not designed appropriately)
Combining molecules: rules for each of the three parts
Title:
Use the title of pFirst unless it has none, when use that of pSecond.
Warning if neither molecule has a title.
Structure
- a structure with atoms replaces one with no atoms
- a structure with bonds replaces one with no bonds,
provided the formula is the same, else an error.
- structures with atoms and bonds are compared by InChI; error if not the same.
- a structure with 3D coordinates replaces one with 2D coordinates
- a structure with 2D coordinates replace one with 0D coordinates
OBGenericData
OBPairData
*/
OBMol* OBMoleculeFormat::MakeCombinedMolecule(OBMol* pFirst, OBMol* pSecond)
{
//Decide on which OBMol provides the new title
string title("No title");
if(*pFirst->GetTitle()!=0)
title = pFirst->GetTitle();
else
{
if(*pSecond->GetTitle()!=0)
title = pSecond->GetTitle();
else
obErrorLog.ThrowError(__FUNCTION__,"Combined molecule has no title", obWarning);
}
//Decide on which OBMol provides the new structure
bool swap=false;
if(pFirst->NumAtoms()==0 && pSecond->NumAtoms()!=0)
swap=true;
else if(pSecond->NumAtoms()!=0)
{
if(pFirst->GetSpacedFormula()!=pSecond->GetSpacedFormula())
{
obErrorLog.ThrowError(__FUNCTION__,
"Molecules with name = " + title + " have different formula",obError);
return NULL;
}
else
{
if(pSecond->NumBonds()!=0 && pFirst->NumBonds()==0)
swap=true;
else
{
//Compare by inchi; error if different NOT YET IMPLEMENTED
//Use the one with the higher dimension
if(pSecond->GetDimension() > pFirst->GetDimension())
swap=true;
}
}
}
OBMol* pNewMol = new OBMol;
pNewMol->SetTitle(title);
OBMol* pMain = swap ? pSecond : pFirst;
OBMol* pOther = swap ? pFirst : pSecond;
*pNewMol = *pMain; //Now copies all data
//Copy some OBGenericData from the OBMol which did not provide the structure
vector<OBGenericData*>::iterator igd;
for(igd=pOther->BeginData();igd!=pOther->EndData();++igd)
{
//copy only if not already data of the same type from molecule already copied to pNewMol
unsigned datatype = (*igd)->GetDataType();
OBGenericData* pData = pNewMol->GetData(datatype);
if(datatype==OBGenericDataType::PairData)
{
if(pData->GetAttribute() == (*igd)->GetAttribute())
continue;
}
else if(pNewMol->GetData(datatype)!=NULL)
continue;
OBGenericData* pCopiedData = (*igd)->Clone(pNewMol);
pNewMol->SetData(pCopiedData);
}
return pNewMol;
}
示例9: WriteMolecule
bool PDBFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
{
OBMol* pmol = dynamic_cast<OBMol*>(pOb);
if(pmol==NULL)
return false;
//Define some references so we can use the old parameter names
ostream &ofs = *pConv->GetOutStream();
OBMol &mol = *pmol;
unsigned int i;
char buffer[BUFF_SIZE];
char type_name[10], padded_name[10];
char the_res[10];
char the_chain = ' ';
const char *element_name;
int res_num;
bool het=true;
int model_num = 0;
if (!pConv->IsLast() || pConv->GetOutputIndex() > 1)
{ // More than one molecule record
model_num = pConv->GetOutputIndex(); // MODEL 1-based index
snprintf(buffer, BUFF_SIZE, "MODEL %8d", model_num);
ofs << buffer << endl;
}
// write back all fields (REMARKS, HELIX, SHEET, SITE, ...)
bool compndWritten = false;
bool authorWritten = false;
std::vector<OBGenericData*> pairData = mol.GetAllData(OBGenericDataType::PairData);
for (std::vector<OBGenericData*>::iterator data = pairData.begin(); data != pairData.end(); ++data) {
OBPairData *pd = static_cast<OBPairData*>(*data);
string attr = pd->GetAttribute();
// filter to make sure we are writing pdb fields only
if (attr != "HEADER" && attr != "OBSLTE" && attr != "TITLE" && attr != "SPLIT" &&
attr != "CAVEAT" && attr != "COMPND" && attr != "SOURCE" && attr != "KEYWDS" &&
attr != "EXPDTA" && attr != "NUMMDL" && attr != "MDLTYP" && attr != "AUTHOR" &&
attr != "REVDAT" && attr != "SPRSDE" && attr != "JRNL" && attr != "REMARK" &&
attr != "DBREF" && attr != "DBREF1" && attr != "DBREF2" && attr != "SEQADV" &&
attr != "SEQRES" && attr != "MODRES" && attr != "HET" && attr != "HETNAM" &&
attr != "HETSYN" && attr != "FORMUL" && attr != "HELIX" && attr != "SHEET" &&
attr != "SSBOND" && attr != "LINK" && attr != "CISPEP" && attr != "SITE" &&
attr != "ORIGX1" && attr != "ORIGX2" && attr != "ORIGX3" && attr != "SCALE1" &&
attr != "SCALE2" && attr != "SCALE3" && attr != "MATRIX1" && attr != "MATRIX2" &&
attr != "MATRIX3" && attr != "MODEL")
continue;
if (attr == "COMPND")
compndWritten = true;
if (attr == "AUTHOR")
authorWritten = true;
// compute spacing needed. HELIX, SITE, HET, ... are trimmed when reading
int nSpacing = 6 - attr.size();
for (int i = 0; i < nSpacing; ++i)
attr += " ";
std::string lines = pd->GetValue();
string::size_type last = 0;
string::size_type pos = lines.find('\n');
while (last != string::npos) {
string line = lines.substr(last, pos - last);
if (pos == string::npos)
last = string::npos;
else
last = pos + 1;
pos = lines.find('\n', last);
ofs << attr << line << endl;
}
}
if (!compndWritten) {
if (strlen(mol.GetTitle()) > 0)
snprintf(buffer, BUFF_SIZE, "COMPND %s ",mol.GetTitle());
else
snprintf(buffer, BUFF_SIZE, "COMPND UNNAMED");
ofs << buffer << endl;
}
if (!authorWritten) {
snprintf(buffer, BUFF_SIZE, "AUTHOR GENERATED BY OPEN BABEL %s",BABEL_VERSION);
ofs << buffer << endl;
}
// Write CRYST1 record, containing unit cell parameters, space group
// and Z value (supposed to be 1)
if (pmol->HasData(OBGenericDataType::UnitCell))
{
OBUnitCell *pUC = (OBUnitCell*)pmol->GetData(OBGenericDataType::UnitCell);
if(pUC->GetSpaceGroup()){
string tmpHM=pUC->GetSpaceGroup()->GetHMName();
// Do we have an extended HM symbol, with origin choice as ":1" or ":2" ? If so, remove it.
size_t n=tmpHM.find(":");
if(n!=string::npos) tmpHM=tmpHM.substr(0,n);
snprintf(buffer, BUFF_SIZE,
"CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s 1",
pUC->GetA(), pUC->GetB(), pUC->GetC(),
//.........这里部分代码省略.........
示例10: setMolecule
void VibrationWidget::setMolecule(Molecule *molecule)
{
// update table
ui.vibrationTable->clearContents();
if (molecule == 0){
ui.vibrationTable->setRowCount(0);
ui.vibrationTable->horizontalHeader()->hide();
return;
}
m_molecule = molecule;
OBMol obmol = molecule->OBMol();
m_vibrations = static_cast<OBVibrationData*>(obmol.GetData(OBGenericDataType::VibrationData));
if (!m_vibrations) {
ui.vibrationTable->setRowCount(0);
ui.vibrationTable->horizontalHeader()->hide();
//ui.exportButton->setEnabled(false);
return;
}
ui.vibrationTable->horizontalHeader()->show();
ui.vibrationTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
// OK, we have valid vibrations, so add them to the table
vector<double> frequencies = m_vibrations->GetFrequencies();
vector<double> intensities = m_vibrations->GetIntensities();
m_frequencies = frequencies;
m_intensities = intensities;
vector<double> raman_activities = m_vibrations->GetRamanActivities();
if (raman_activities.size() == 0) {
//resize(274, height());
ui.vibrationTable->setColumnCount(2);
if(parentWidget())
parentWidget()->setMinimumWidth(274);
}
else {
//resize(310, height());
ui.vibrationTable->setColumnCount(3);
ui.vibrationTable->setHorizontalHeaderItem(2,
new QTableWidgetItem("Activity"));
if(parentWidget())
parentWidget()->setMinimumWidth(310);
}
// Generate an index vector to map sorted indicies to the old indices
m_indexMap->clear();
for (uint i = 0; i < frequencies.size(); i++)
m_indexMap->push_back(i);
// Setup progress dialog, just in case it takes longer than 2 seconds
QProgressDialog prog(tr("Sorting %1 vibrations by frequency...")
.arg(frequencies.size()), "", 0, frequencies.size());
prog.setWindowModality(Qt::WindowModal);
prog.setMinimumDuration(2000);
prog.setCancelButton(0);
// Simple selection sort
double tmp;
int tmp_int;
for (uint i = 0; i < frequencies.size(); i++) {
for (uint j = i; j < frequencies.size(); j++) {
if (i == j)
continue; // Save a bit of time...
if (frequencies.at(j) < frequencies.at(i)) {
tmp = frequencies.at(j);
frequencies.at(j) = frequencies.at(i);
frequencies.at(i) = tmp;
tmp = intensities.at(j);
intensities.at(j) = intensities.at(i);
intensities.at(i) = tmp;
tmp_int = m_indexMap->at(j);
m_indexMap->at(j) = m_indexMap->at(i);
m_indexMap->at(i) = tmp_int;
}
}
// Update progress bar
prog.setValue(i);
}
ui.vibrationTable->setRowCount(frequencies.size());
QString format("%1");
for (unsigned int row = 0; row < frequencies.size(); ++row) {
QTableWidgetItem *newFreq = new QTableWidgetItem(format.arg(frequencies[row], 0, 'f', 2));
newFreq->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
// Some codes don't provide intensity data. Display "-" in place of intensities.
QTableWidgetItem *newInten;
if (row >= intensities.size()) {
newInten = new QTableWidgetItem("-");
}
else {
newInten = new QTableWidgetItem(format.arg(intensities[row], 0, 'f', 3));
}
newInten->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
ui.vibrationTable->setItem(row, 0, newFreq);
ui.vibrationTable->setItem(row, 1, newInten);
if (raman_activities.size() != 0) {
QTableWidgetItem *newRaman;
if (row >= raman_activities.size()) {
//.........这里部分代码省略.........
示例11: ComputeCharges
//! \return whether partial charges were successfully assigned to this molecule
bool EQEqCharges::ComputeCharges(OBMol &mol)
{
int i, j, a, c, N = mol.NumAtoms();
double cellVolume;
VectorXf chi(N), J(N), b(N), x(N);
MatrixXf J_ij(N, N), A(N, N);
OBUnitCell *obuc;
matrix3x3 unitcell, fourier;
vector3 dx;
int numNeighbors[3];
OBAtom *atom;
// If parameters have not yet been loaded, do that
if (!_paramFileLoaded)
{
if (ParseParamFile())
{
_paramFileLoaded = true;
} else
{
return false;
}
}
// Calculate atomic properties based around their ionic charge
for (i = 0; i < N; i++)
{
atom = mol.GetAtom(i + 1);
a = atom->GetAtomicNum();
c = _chargeCenter[a];
// Fail if ionization data is missing for any atom in the molecule
if (_ionizations[a][c + 1] == -1 || _ionizations[a][c] == -1 || a > TABLE_OF_ELEMENTS_SIZE)
{
obErrorLog.ThrowError(__FUNCTION__, "Insufficient ionization data for atoms in the given molecule. Update `data/eqeqIonizations.txt` with missing information and re-run this function.", obError);
return false;
}
J(i) = _ionizations[a][c + 1] - _ionizations[a][c];
chi(i) = 0.5 * (_ionizations[a][c + 1] + _ionizations[a][c]) - (a == 1? 0 : c * J(i));
}
// If a unit cell is defined, use the periodic Ewald calculation
if (mol.HasData(OBGenericDataType::UnitCell))
{
// Get unit cell and calculate its Fourier transform + volume
obuc = (OBUnitCell *) mol.GetData(OBGenericDataType::UnitCell);
unitcell = obuc->GetCellMatrix();
fourier = (2 * PI * unitcell.inverse()).transpose();
cellVolume = obuc->GetCellVolume();
// Get the number of radial unit cells to use in x, y, and z
numNeighbors[0] = int(ceil(minCellLength / (2.0 * (obuc->GetA())))) - 1;
numNeighbors[1] = int(ceil(minCellLength / (2.0 * (obuc->GetB())))) - 1;
numNeighbors[2] = int(ceil(minCellLength / (2.0 * (obuc->GetC())))) - 1;
for (i = 0; i < N; i++)
{
atom = mol.GetAtom(i + 1);
for (j = 0; j < N; j++)
{
dx = atom->GetVector() - (mol.GetAtom(j + 1))->GetVector();
J_ij(i, j) = GetPeriodicEwaldJij(J(i), J(j), dx, (i == j), unitcell, fourier, cellVolume, numNeighbors);
}
}
// If no unit cell, use the simplified nonperiodic calculation
} else
{
for (i = 0; i < N; i++)
{
atom = mol.GetAtom(i + 1);
for (j = 0; j < N; j++)
{
J_ij(i, j) = GetNonperiodicJij(J(i), J(j), atom->GetDistance(j + 1), (i == j));
}
return false;
}
}
// Formulate problem as A x = b, where x is the calculated partial charges
// First equation is a simple overall balance: sum(Q) = 0
A.row(0) = VectorXf::Ones(N);
b(0) = 0;
// Remaining equations are based off of the fact that, at equilibrium, the
// energy of the system changes equally for a change in any charge:
// dE/dQ_1 = dE/dQ_2 = ... = dE/dQ_N
A.block(1, 0, N - 1, N) = J_ij.block(0, 0, N - 1, N) - J_ij.block(1, 0, N - 1, N);
b.tail(N - 1) = chi.tail(N - 1) - chi.head(N - 1);
// The solution is a list of charges in the system
x = A.colPivHouseholderQr().solve(b);
// Now we are done calculating, pass all this back to OpenBabel molecule
mol.SetPartialChargesPerceived();
OBPairData *dp = new OBPairData;
dp->SetAttribute("PartialCharges");
dp->SetValue("EQEq");
dp->SetOrigin(perceived);
//.........这里部分代码省略.........
示例12: Do
bool OpFillUC::Do(OBBase* pOb, const char* OptionText, OpMap* pOptions, OBConversion* pConv)
{
OBMol* pmol = dynamic_cast<OBMol*>(pOb);
if(!pmol)
return false;
if (!(pmol->HasData(OBGenericDataType::UnitCell)))
{
obErrorLog.ThrowError(__FUNCTION__, "Cannot fill unit cell without a unit cell !" , obWarning);
return false;
}
OBUnitCell *pUC = (OBUnitCell*)pmol->GetData(OBGenericDataType::UnitCell);
const SpaceGroup* pSG = pUC->GetSpaceGroup();
if (pSG == NULL)
{
obErrorLog.ThrowError(__FUNCTION__, "Cannot fill unit cell without spacegroup information !" , obWarning);
return false;
}
// Now loop over all symmetry operations, and generate symmetric atoms one at a time
// Avoid creating overlapping atoms (duplicate), and bring back atoms within the unit cell
// using two options:
// "--fillUC strict": keep only atoms that are strictly inside the unit cell
// (fractionnal coordinates 0<= <1)
// "--fillUC keepconnect": generate symmetrics of the molecule, and translate
// it back in the unit cell if necessary
std::map<OBAtom*,std::vector<vector3> > vatoms;// key: original atoms, value=all generated symmetrics
FOR_ATOMS_OF_MOL(atom, *pmol)
vatoms[&(*atom)]=std::vector<vector3>();
for(std::map<OBAtom*,std::vector<vector3> >:: iterator atom=vatoms.begin();
atom!=vatoms.end();++atom){
vector3 orig = atom->first->GetVector();
orig = pUC->CartesianToFractional(orig);// To fractionnal coordinates
// Loop over symmetry operators
transform3dIterator ti;
const transform3d *t = pSG->BeginTransform(ti);
while(t){
atom->second.push_back ( (transform3d)(*t) * orig);
t = pSG->NextTransform(ti);
}
}
if(0==strncasecmp(OptionText, "keepconnect", 11)){
// First, bring back all symmetrical molecules back in the UC
for(unsigned int i=0;i<vatoms.begin()->second.size();++i){
vector3 ccoord(0,0,0);//geometrical center
for(std::map<OBAtom*,std::vector<vector3> >:: iterator atom=vatoms.begin();
atom!=vatoms.end();++atom){
ccoord+=atom->second[i];
}
ccoord/=vatoms.size();
ccoord=transformedFractionalCoordinate2(ccoord)-ccoord;
for(std::map<OBAtom*,std::vector<vector3> >:: iterator atom=vatoms.begin();
atom!=vatoms.end();++atom){
atom->second[i]+=ccoord;
}
}
// Now add atoms that are not duplicates
for(std::map<OBAtom*,std::vector<vector3> >:: iterator atom=vatoms.begin();
atom!=vatoms.end();++atom){
for(unsigned int i=1;i<atom->second.size();++i){
bool foundDuplicate = false;
for(unsigned int j=0;j<i;++j){
if(atom->second[i].distSq(atom->second[j])<1e-4){
foundDuplicate=true;
break;
}
}
if(!foundDuplicate){
OBAtom *newAtom = pmol->NewAtom();
newAtom->Duplicate(atom->first);
newAtom->SetVector( pUC->FractionalToCartesian(atom->second[i]));
}
}
}
}
else{
if(0!=strncasecmp(OptionText, "strict", 6))
obErrorLog.ThrowError(__FUNCTION__, "fillUC: lacking \"strict\n or \"keepconnect\" option, using strict" , obWarning);
for(std::map<OBAtom*,std::vector<vector3> >:: iterator atom=vatoms.begin();
atom!=vatoms.end();++atom){
// Bring back within unit cell
for(unsigned int i=0;i<atom->second.size();++i){
atom->second[i]=transformedFractionalCoordinate2(atom->second[i]);
}
for(unsigned int i=1;i<atom->second.size();++i){
bool foundDuplicate = false;
for(unsigned int j=0;j<i;++j){
if(atom->second[i].distSq(atom->second[j])<1e-4){
foundDuplicate=true;
break;
}
}
if(!foundDuplicate){
OBAtom *newAtom = pmol->NewAtom();
newAtom->Duplicate(atom->first);
newAtom->SetVector( pUC->FractionalToCartesian(atom->second[i]));
}
}
//.........这里部分代码省略.........
示例13: WriteMolecule
bool PDBFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
{
OBMol* pmol = dynamic_cast<OBMol*>(pOb);
if(pmol==NULL)
return false;
//Define some references so we can use the old parameter names
ostream &ofs = *pConv->GetOutStream();
OBMol &mol = *pmol;
unsigned int i;
char buffer[BUFF_SIZE];
char type_name[10], padded_name[10];
char the_res[10];
char the_chain = ' ';
const char *element_name;
int res_num;
bool het=true;
int model_num = 0;
if (!pConv->IsLast() || pConv->GetOutputIndex() > 1)
{ // More than one molecule record
model_num = pConv->GetOutputIndex(); // MODEL 1-based index
snprintf(buffer, BUFF_SIZE, "MODEL %8d", model_num);
ofs << buffer << endl;
}
if (strlen(mol.GetTitle()) > 0)
snprintf(buffer, BUFF_SIZE, "COMPND %s ",mol.GetTitle());
else
snprintf(buffer, BUFF_SIZE, "COMPND UNNAMED");
ofs << buffer << endl;
snprintf(buffer, BUFF_SIZE, "AUTHOR GENERATED BY OPEN BABEL %s",BABEL_VERSION);
ofs << buffer << endl;
// Write CRYST1 record, containing unit cell parameters, space group
// and Z value (supposed to be 1)
if (pmol->HasData(OBGenericDataType::UnitCell))
{
OBUnitCell *pUC = (OBUnitCell*)pmol->GetData(OBGenericDataType::UnitCell);
snprintf(buffer, BUFF_SIZE,
"CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s 1",
pUC->GetA(), pUC->GetB(), pUC->GetC(),
pUC->GetAlpha(), pUC->GetBeta(), pUC->GetGamma(),
pUC->GetSpaceGroup() ?
pUC->GetSpaceGroup()->GetHMName().c_str() : "P1");
ofs << buffer << endl;
}
// before we write any records, we should check to see if any coord < -1000
// which will cause errors in the formatting
double minX, minY, minZ;
minX = minY = minZ = -999.0f;
FOR_ATOMS_OF_MOL(a, mol)
{
if (a->GetX() < minX)
minX = a->GetX();
if (a->GetY() < minY)
minY = a->GetY();
if (a->GetZ() < minZ)
minZ = a->GetZ();
}
vector3 transV = VZero;
if (minX < -999.0)
transV.SetX(-1.0*minX - 900.0);
if (minY < -999.0)
transV.SetY(-1.0*minY - 900.0);
if (minZ < -999.0)
transV.SetZ(-1.0*minZ - 900.0);
// if minX, minY, or minZ was never changed, shift will be 0.0f
// otherwise, move enough so that smallest coord is > -999.0f
mol.Translate(transV);
OBAtom *atom;
OBResidue *res;
for (i = 1; i <= mol.NumAtoms(); i++)
{
atom = mol.GetAtom(i);
strncpy(type_name, etab.GetSymbol(atom->GetAtomicNum()), sizeof(type_name));
type_name[sizeof(type_name) - 1] = '\0';
//two char. elements are on position 13 and 14 one char. start at 14
if (strlen(type_name) > 1)
type_name[1] = toupper(type_name[1]);
else
{
char tmp[10];
strncpy(tmp, type_name, 10);
snprintf(type_name, sizeof(type_name), " %-3s", tmp);
}
if ( (res = atom->GetResidue()) != 0 )
{
het = res->IsHetAtom(atom);
snprintf(the_res,4,"%s",(char*)res->GetName().c_str());
snprintf(type_name,5,"%s",(char*)res->GetAtomID(atom).c_str());
the_chain = res->GetChain();
//.........这里部分代码省略.........