void OpenBabel::onPerceiveBondsFinished(const QByteArray &output) { m_progress->setLabelText(tr("Updating molecule from CML...")); // CML --> molecule Core::Molecule mol; if (!Io::FileFormatManager::instance().readString(mol, output.constData(), "cml")) { m_progress->reset(); QMessageBox::critical(qobject_cast<QWidget*>(parent()), tr("Error"), tr("Error interpreting obabel CML output."), QMessageBox::Ok); return; } /// @todo cache a pointer to the current molecule in the above slot, and /// verify that we're still operating on the same molecule. // Check that the atom count hasn't changed: if (mol.atomCount() != m_molecule->atomCount()) { m_progress->reset(); QMessageBox::critical(qobject_cast<QWidget*>(parent()), tr("Error"), tr("Number of atoms in obabel output (%1) does not " "match the number of atoms in the original " "molecule (%2).") .arg(mol.atomCount()).arg(m_molecule->atomCount()), QMessageBox::Ok); return; } m_molecule->clearBonds(); for (size_t i = 0; i < mol.bondCount(); ++i) { Avogadro::Core::Bond bond = mol.bond(i); m_molecule->addBond(m_molecule->atom(bond.atom1().index()), m_molecule->atom(bond.atom2().index()), bond.order()); } m_molecule->emitChanged(Molecule::Bonds | Molecule::Added | Molecule::Removed | Molecule::Modified); m_progress->reset(); }
void OpenBabel::onOptimizeGeometryFinished(const QByteArray &output) { m_progress->setLabelText(tr("Updating molecule...")); // CML --> molecule Core::Molecule mol; if (!Io::FileFormatManager::instance().readString(mol, output.constData(), "mol")) { m_progress->reset(); QMessageBox::critical(qobject_cast<QWidget*>(parent()), tr("Error"), tr("Error interpreting obabel MDL output."), QMessageBox::Ok); return; } /// @todo cache a pointer to the current molecule in the above slot, and /// verify that we're still operating on the same molecule. // Check that the atom count hasn't changed: if (mol.atomCount() != m_molecule->atomCount()) { m_progress->reset(); QMessageBox::critical(qobject_cast<QWidget*>(parent()), tr("Error"), tr("Number of atoms in obabel output (%1) does not " "match the number of atoms in the original " "molecule (%2).") .arg(mol.atomCount()).arg(m_molecule->atomCount()), QMessageBox::Ok); return; } std::swap(mol.atomPositions3d(), m_molecule->atomPositions3d()); m_molecule->emitChanged(QtGui::Molecule::Atoms | QtGui::Molecule::Modified); m_progress->reset(); }
void VanDerWaals::process(const Core::Molecule &molecule, Rendering::GroupNode &node) { // Add a sphere node to contain all of the VdW spheres. GeometryNode *geometry = new GeometryNode; node.addChild(geometry); SphereGeometry *spheres = new SphereGeometry; spheres->identifier().molecule = &molecule; spheres->identifier().type = Rendering::AtomType; geometry->addDrawable(spheres); for (size_t i = 0; i < molecule.atomCount(); ++i) { Core::Atom atom = molecule.atom(i); unsigned char atomicNumber = atom.atomicNumber(); const unsigned char *c = Elements::color(atomicNumber); Vector3ub color(c[0], c[1], c[2]); spheres->addSphere(atom.position3d().cast<float>(), color, static_cast<float>(Elements::radiusVDW(atomicNumber))); } }
void OpenBabel::onHydrogenOperationFinished(const QByteArray &mdl) { m_progress->setLabelText(tr("Reading obabel output...")); // MDL --> molecule Core::Molecule mol; if (!Io::FileFormatManager::instance().readString(mol, mdl.constData(), "mol")) { m_progress->reset(); qWarning() << "Bad MDL: " << mdl; QMessageBox::critical(qobject_cast<QWidget*>(parent()), tr("Error"), tr("Error interpreting obabel MDL output."), QMessageBox::Ok); return; } /// @todo cache a pointer to the current molecule in the above slot, and /// verify that we're still operating on the same molecule. // Update molecule m_molecule->clearAtoms(); for (Index i = 0; i < mol.atomCount(); ++i) { Core::Atom atom = mol.atom(i); m_molecule->addAtom(atom.atomicNumber()).setPosition3d(atom.position3d()); } for (Index i = 0; i < mol.bondCount(); ++i) { Core::Bond bond = mol.bond(i); m_molecule->addBond(m_molecule->atom(bond.atom1().index()), m_molecule->atom(bond.atom2().index()), bond.order()); } m_molecule->emitChanged(Molecule::Atoms | Molecule::Bonds | Molecule::Added | Molecule::Removed | Molecule::Modified); m_progress->reset(); }
bool PdbFormat::read(std::istream& in, Core::Molecule& mol) { string buffer; std::vector<int> terList; Residue* r; size_t currentResidueId = 0; bool ok(false); int coordSet = 0; Array<Vector3> positions; while (getline(in, buffer)) { // Read Each line one by one if (startsWith(buffer, "ENDMDL")) { if (coordSet == 0) { mol.setCoordinate3d(mol.atomPositions3d(), coordSet++); positions.reserve(mol.atomCount()); } else { mol.setCoordinate3d(positions, coordSet++); positions.clear(); } } else if (startsWith(buffer, "ATOM") || startsWith(buffer, "HETATM")) { // First we initialize the residue instance size_t residueId = lexicalCast<size_t>(buffer.substr(22, 4), ok); if (!ok) { appendError("Failed to parse residue sequence number: " + buffer.substr(22, 4)); return false; } if (residueId != currentResidueId) { currentResidueId = residueId; string residueName = lexicalCast<string>(buffer.substr(17, 3), ok); if (!ok) { appendError("Failed to parse residue name: " + buffer.substr(17, 3)); return false; } char chainId = lexicalCast<char>(buffer.substr(21, 1), ok); if (!ok) { appendError("Failed to parse chain identifier: " + buffer.substr(21, 1)); return false; } r = &mol.addResidue(residueName, currentResidueId, chainId); } string atomName = lexicalCast<string>(buffer.substr(12, 4), ok); if (!ok) { appendError("Failed to parse atom name: " + buffer.substr(12, 4)); return false; } Vector3 pos; // Coordinates pos.x() = lexicalCast<Real>(buffer.substr(30, 8), ok); if (!ok) { appendError("Failed to parse x coordinate: " + buffer.substr(30, 8)); return false; } pos.y() = lexicalCast<Real>(buffer.substr(38, 8), ok); if (!ok) { appendError("Failed to parse y coordinate: " + buffer.substr(38, 8)); return false; } pos.z() = lexicalCast<Real>(buffer.substr(46, 8), ok); if (!ok) { appendError("Failed to parse z coordinate: " + buffer.substr(46, 8)); return false; } string element; // Element symbol, right justififed element = buffer.substr(76, 2); element = trimmed(element); if (element == "SE") // For Sulphur element = 'S'; unsigned char atomicNum = Elements::atomicNumberFromSymbol(element); if (atomicNum == 255) appendError("Invalid element"); if (coordSet == 0) { Atom newAtom = mol.addAtom(atomicNum); newAtom.setPosition3d(pos); if (r) { r->addResidueAtom(atomName, newAtom); } } else { positions.push_back(pos); } } else if (startsWith(buffer, "TER")) { // This is very important, each TER // record also counts in the serial. // Need to account for that when comparing with CONECT terList.push_back(lexicalCast<int>(buffer.substr(6, 5), ok)); if (!ok) { appendError("Failed to parse TER serial"); return false; } } else if (startsWith(buffer, "CONECT")) { int a = lexicalCast<int>(buffer.substr(6, 5), ok); if (!ok) { appendError("Failed to parse coordinate a " + buffer.substr(6, 5)); return false; } --a; size_t terCount; for (terCount = 0; terCount < terList.size() && a > terList[terCount]; ++terCount) ; // semicolon is intentional a = a - terCount; int bCoords[] = { 11, 16, 21, 26 }; for (int i = 0; i < 4; i++) { if (trimmed(buffer.substr(bCoords[i], 5)) == "") break; else { int b = lexicalCast<int>(buffer.substr(bCoords[i], 5), ok) - 1; if (!ok) { appendError("Failed to parse coordinate b" + std::to_string(i) + " " + buffer.substr(bCoords[i], 5)); return false; } for (terCount = 0; terCount < terList.size() && b > terList[terCount]; ++terCount) ; // semicolon is intentional b = b - terCount; if (a < b) { mol.Avogadro::Core::Molecule::addBond(a, b, 1); } } } } } // End while loop mol.perceiveBondsSimple(); mol.perceiveBondsFromResidueData(); return true; } // End read