void bootstrap() { if (!molecule()->atoms().empty()) { molecule()->computeAtomAdjacency(); for(int i=0; i<molecule()->atomCount(); ++i) molecule()->atom(i)->setVisited(false); std::vector< ref<Atom> > current_path; depthFirstVisit( molecule()->atoms()[0].get(), current_path ); } }
void depthFirstVisit(Atom* atom, std::vector< ref<Atom> >& current_path) { if ( !atom->visited() || current_path.empty()) { atom->setVisited(true); current_path.push_back(atom); for(unsigned i=0; i<atom->adjacentAtoms().size(); ++i) depthFirstVisit( atom->adjacentAtoms()[i], current_path ); current_path.pop_back(); atom->setVisited(false); } else // cycle found { /* condition: atom->visited() && !current_path.empty() */ for(size_t i = current_path.size()-1; i--; ) { if ( current_path[i] == atom ) { std::vector< ref<Atom> > cycle; for(; i<current_path.size(); ++i) cycle.push_back( current_path[i] ); if (cycle.size() > 2) molecule()->cycles().push_back(cycle); break; } } } }
void RemoveBondCommand::redo() { Bond *bond = editor()->bond(m_atomId1, m_atomId2); Q_ASSERT(bond != 0); molecule()->removeBond(bond); }
void AddBondCommand::undo() { Bond *bond = editor()->bond(m_atomId1, m_atomId2); assert(bond); molecule()->removeBond(bond); }
/// Returns the fragment the atom is a part of. Fragment* Atom::fragment() const { if(m_fragment) return m_fragment; else return molecule()->fragment(this); }
void RemoveAtomCommand::redo() { Atom *atom = editor()->atom(m_atomId); Q_ASSERT(atom); molecule()->removeAtom(atom); }
void AddAtomCommand::undo() { Atom *atom = editor()->atom(m_atomId); assert(atom); molecule()->removeAtom(atom); }
long int Assembly::addMolecule(std::string _name, std::string alt_name) { Molecule molecule(_name, alt_name); long int result = molecules.size(); molecules.push_back(molecule); return result; }
void RemoveAtomCommand::undo() { Atom *atom = molecule()->addAtom(m_atomicNumber); Q_ASSERT(atom); atom->setPosition(m_position); editor()->setId(atom, m_atomId); }
void File::Mol::parse(bool doAutoRebond) { parseBasis(); parseGeneralString(); parseAtoms(); if (doAutoRebond) molecule().rebond(); }
void RemoveBondCommand::undo() { Atom *atom1 = editor()->atom(m_atomId1); Atom *atom2 = editor()->atom(m_atomId2); Q_ASSERT(!atom1->isBondedTo(atom2)); molecule()->addBond(atom1, atom2, m_bondOrder); }
void AddBondCommand::redo() { Atom *atom1 = editor()->atom(m_atomId1); Atom *atom2 = editor()->atom(m_atomId2); Q_ASSERT(atom1); Q_ASSERT(atom2); m_bond = molecule()->addBond(atom1, atom2); }
void removeDoubles() { for(unsigned icycle=0; icycle<molecule()->cycles().size(); ++icycle) std::stable_sort(molecule()->cycle(icycle).begin(), molecule()->cycle(icycle).end()); std::stable_sort(molecule()->cycles().begin(), molecule()->cycles().end()); std::vector< std::vector< ref<Atom> > >::iterator new_end = std::unique(molecule()->cycles().begin(), molecule()->cycles().end()); std::vector< std::vector< ref<Atom> > > unique_cycles; for(std::vector< std::vector< ref<Atom> > >::iterator it = molecule()->cycles().begin(); it != new_end; ++it) unique_cycles.push_back(*it); molecule()->cycles() = unique_cycles; }
void MCAgent_STube::pertAtom(double _dxmax, int _id, double _new_x[3]) { const AMod::Atom& atom = molecule().atom(_id); _new_id = _id; _new_th = _th[_id]; if(_id != _thFixID) _new_th += (_dxmax/_r)*urand(-1,1); _new_x[0] = _r*cos(_new_th); _new_x[1] = _r*sin(_new_th); _new_x[2] = atom->x[2]+_dxmax*urand(-1,1); }
void File::Mol::parseGeneralString() { int n = 0; bool ok; QRegExp regExp; regExp.setPattern("Atomtypes=(\\d+)"); n = regExp.indexIn(string(generalStringIndex_)); if (n != -1) setAtomTypes(regExp.cap(1).toInt(&ok, 10)); else addParseError(File::ParseError(generalStringIndex_, "Couldn't find Atomtypes keyword.\n\n" "Hint: QDalton 0.1 recognizes only full names of Dalton keywords!")); regExp.setPattern("Generators=[123]{1}"); n = regExp.indexIn(string(generalStringIndex_)); if (n != -1) addParseError(File::ParseError(generalStringIndex_, "Generators keyword was found.\n\n" "Hint: QDalton 0.1 doesn't support generators!")); regExp.setPattern("Angstrom"); n = regExp.indexIn(string(generalStringIndex_)); if (n != -1) setUnitOfLength(UnitOfLengthAngstrom); else setUnitOfLength(UnitOfLengthBohr); regExp.setPattern("Cartesian"); n = regExp.indexIn(string(generalStringIndex_)); if (n != -1) setGaussiansType(GaussiansTypeCartesian); else setGaussiansType(GaussiansTypeSpherical); regExp.setPattern("Charge=(\\d+)"); n = regExp.indexIn(string(generalStringIndex_)); if (n != -1) molecule().setCharge(regExp.cap(1).toInt(&ok)); else molecule().setCharge(0); }
std::ostream& operator<<(std::ostream& output, const Molecule& molecule) { for (uint i = 0; i < molecule.size(); ++i) { output << molecule._atoms[i] << "\t"; output.width(20); output.precision(5); output << std::left << molecule(i, 0) << '\t'; output.width(20); output.precision(5); output << std::left << molecule(i, 1) << '\t'; output.width(20); output.precision(5); output << std::left << molecule(i, 2) << std::endl; } return output; }
void AddAtomCommand::redo() { m_atom = molecule()->addAtom(m_element); if(m_atomId){ editor()->setId(m_atom, m_atomId); } else{ m_atomId = editor()->id(m_atom); } }
void MassDescriptorsTest::test() { QFETCH(QString, formulaString); QFETCH(int, mass); QByteArray formula = formulaString.toAscii(); chemkit::Molecule molecule(formula.constData(), "formula"); QCOMPARE(molecule.formula().c_str(), formula.constData()); QCOMPARE(molecule.descriptor("mass").toInt(), mass); }
// --- Ring Perception ----------------------------------------------------- // /// Returns a list of rings the bond is a member of. std::vector<Ring *> Bond::rings() const { std::vector<Ring *> rings; foreach(Ring *ring, molecule()->rings()){ if(ring->contains(this)){ rings.push_back(ring); } } return rings; }
void run() { if (!molecule()->atoms().empty()) { bootstrap(); removeDoubles(); sortCycles(); keepMinimalCycles(); keepAromaticCycles(); /*keepPlanarCycles(0.10f);*/ } }
void sortCycles() { for(unsigned icycle=0; icycle<molecule()->cycles().size(); ++icycle) { std::vector< ref<Atom> >& cycle = molecule()->cycle(icycle); for(unsigned iatom=0; iatom<cycle.size()-1; ++iatom) { Atom* atom = cycle[iatom].get(); for(unsigned j=iatom+1; j<cycle.size(); ++j) { if (atom->isAtomAdjacent(cycle[j].get())) { Atom* tmp = cycle[iatom+1].get(); cycle[iatom+1] = cycle[j]; cycle[j] = tmp; break; } } } } }
bool XyzFileFormat::read(std::istream &input, chemkit::MoleculeFile *file) { // atom count line int atomCount = 0; input >> atomCount; input.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // comment line (unused) std::string commentLine; std::getline(input, commentLine); CHEMKIT_UNUSED(commentLine); // create molecule boost::shared_ptr<chemkit::Molecule> molecule(new chemkit::Molecule); // read atoms and coordinates for(int i = 0; i < atomCount; i++){ std::string symbol; double x = 0; double y = 0; double z = 0; input >> symbol >> x >> y >> z; if(input.fail()){ input.clear(); } // add atom from symbol or atomic number chemkit::Atom *atom = 0; if(symbol.empty()){ continue; } else if(isdigit(symbol.at(0))){ int atomicNumber = boost::lexical_cast<int>(symbol); atom = molecule->addAtom(atomicNumber); } else{ atom = molecule->addAtom(symbol); } // set atom position if(atom){ atom->setPosition(x, y, z); } } // add molecule to file file->addMolecule(molecule); return true; }
bool KalziumGLWidget::openFile(const QString &file) { Avogadro::Molecule* mol = OpenBabel2Wrapper::readMolecule(file); if (!mol) { return false; } Avogadro::Molecule* oldmol = molecule(); if (oldmol) { oldmol->deleteLater(); } setMolecule(mol); update(); return true; }
void keepAromaticCycles() { std::vector< std::vector< ref<Atom> > > kept_cycles; for(unsigned icycle=0; icycle<molecule()->cycles().size(); ++icycle) { int ok = true; for(unsigned iatom=0; iatom<molecule()->cycle(icycle).size(); ++iatom) { int iatom2 = (iatom+1) % molecule()->cycle(icycle).size(); Atom* atom1 = molecule()->cycle(icycle)[iatom].get(); Atom* atom2 = molecule()->cycle(icycle)[iatom2].get(); Bond* bond = molecule()->bond(atom1, atom2); if (bond && bond->bondType() != BT_Aromatic) { ok = false; break; } } if (ok && molecule()->cycle(icycle).size()) kept_cycles.push_back(molecule()->cycle(icycle)); } molecule()->cycles() = kept_cycles; }
void CountDescriptorsTest::test() { QFETCH(QString, smilesString); QFETCH(QString, formulaString); QFETCH(int, atomCount); QFETCH(int, heavyAtomCount); QFETCH(int, bondCount); QFETCH(int, ringCount); QByteArray smiles = smilesString.toAscii(); QByteArray formula = formulaString.toAscii(); chemkit::Molecule molecule(smiles.constData(), "smiles"); QCOMPARE(molecule.formula().c_str(), formula.constData()); QCOMPARE(molecule.descriptor("atom-count").toInt(), atomCount); QCOMPARE(molecule.descriptor("heavy-atom-count").toInt(), heavyAtomCount); QCOMPARE(molecule.descriptor("bond-count").toInt(), bondCount); QCOMPARE(molecule.descriptor("ring-count").toInt(), ringCount); }
void MCAgent_STube::pertAxes(double _dhmax) { AMod::Molecule& mol = molecule(); int i, natoms = mol.natoms(); //old_r & old_lz //new_r & new_lz _new_r = _r+_dhmax*urand(-1,1); _new_lz = _lz+_dhmax*urand(-1,1); //perturb axes mol.axis(2).x[2] = _new_lz; //perturb atoms for(i = 0; i < natoms; i++) { mol.atom(i)->x[0] *= _new_r/_r; mol.atom(i)->x[1] *= _new_r/_r; mol.atom(i)->x[2] *= _new_lz/_lz; } }
void MlogPTest::mlogp() { QFETCH(QString, smilesString); QFETCH(QString, formulaString); QFETCH(double, mlogp); QByteArray smiles = smilesString.toAscii(); QByteArray formula = formulaString.toAscii(); chemkit::Molecule molecule(smiles.constData(), "smiles"); QCOMPARE(molecule.formula().c_str(), formula.constData()); double tolerance = 0.1; double actual = molecule.descriptor("mlogp").toDouble(); bool equal = std::abs(mlogp - actual) < tolerance; if(!equal){ qDebug() << "Actual: " << actual; qDebug() << "Expected: " << mlogp; } QVERIFY(equal); }
Data::Geometry* QChemInput::parseGeometry(QStringList const& lines, int offset, bool zmat) { Data::Geometry* geom(0); QString line(lines.join("\n")); if (zmat) { ZMatrixCoordinates parser; geom = parser.parse(line); if (!parser.error().isEmpty()) { m_errors.append(parser.error()); } }else { TextStream molecule(&line); molecule.setOffset(offset); CartesianCoordinates parser(lines.size()); geom = parser.parse(molecule); if (!parser.error().isEmpty()) { m_errors.append(parser.error()); } } return geom; }
void MCAgent_STube::init() { AMod::Molecule& mol = molecule(); int i, natoms = mol.natoms(); double score = 0.0, tscore = 0.0; _r = 0.0; _lz = mol.axis(2).x[2]; _th.resize(natoms); for(i = 0; i < natoms; i++) { const AMod::Atom& atom = mol.atom(i); _r += std::sqrt(Util::square(atom->x[0])+Util::square(atom->x[1])); _th[i] = std::atan2(atom->x[1],atom->x[0]); tscore = Util::abs(atom->x[2]-_lz/2.0); if(i == 0 || score > tscore) { _thFixID = i; score = tscore; } } _r = _r/natoms; for(i = 0; i < natoms; i++) { AMod::Atom& atom = mol.atom(i); atom->x[0] = _r*cos(_th[i]); atom->x[1] = _r*sin(_th[i]); } }
int main(int argc, char *argv[]) { std::string inputFormula; std::string inputFormatName; std::string outputFileName; std::string outputFormatName; boost::program_options::options_description options; options.add_options() ("formula", boost::program_options::value<std::string>(&inputFormula), "The input formula.") ("output-file", boost::program_options::value<std::string>(&outputFileName), "The output file.") ("input-format,i", boost::program_options::value<std::string>(&inputFormatName), "Sets the input format.") ("output-format,o", boost::program_options::value<std::string>(&outputFormatName), "Sets the output format.") ("help,h", "Shows this help message"); boost::program_options::positional_options_description positionalOptions; positionalOptions.add("formula", 1).add("output-file", 1); boost::program_options::variables_map variables; boost::program_options::store( boost::program_options::command_line_parser(argc, argv) .options(options) .positional(positionalOptions).run(), variables); boost::program_options::notify(variables); if(variables.count("help")){ printHelp(argv, options); return 0; } else if(inputFormula.empty()){ printHelp(argv, options); std::cerr << "Error: No input formula specified." << std::endl; return -1; } else if(outputFileName.empty()){ printHelp(argv, options); std::cerr << "Error: No output file specified." << std::endl; return -1; } // check input format if(inputFormatName.empty()){ // default to smiles if not format specified inputFormatName = "smiles"; } // create input line format boost::scoped_ptr<chemkit::LineFormat> inputFormat(chemkit::LineFormat::create(inputFormatName)); if(!inputFormat){ if(inputFormatName.empty()){ std::cerr << "Failed to guess input format." << std::endl; } else{ std::cerr << "Input format: " << inputFormatName << " is not supported." << std::endl; } return -1; } // read input formula boost::shared_ptr<chemkit::Molecule> molecule(inputFormat->read(inputFormula)); if(!molecule){ std::cerr << "Failed to parse formula: " << inputFormat->errorString() << std::endl; return -1; } // generate 3d coordinates chemkit::CoordinatePredictor::predictCoordinates(molecule.get()); // optimize 3d coordinates chemkit::MoleculeGeometryOptimizer::optimizeCoordinates(molecule.get()); // set center to origin molecule->setCenter(0, 0, 0); // write output file chemkit::MoleculeFile outputFile(outputFileName); outputFile.addMolecule(molecule); if(!outputFormatName.empty()){ if(!outputFile.setFormat(outputFormatName)){ std::cerr << "File format '" << outputFormatName << "' is not supported." << std::endl; return -1; } } if(!outputFile.write()){ std::cerr << "Error: failed to write output file: " << outputFile.errorString() << std::endl; return -1; } return 0; }