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();
}
Beispiel #3
0
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();
}
Beispiel #5
0
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