bool GaussianOutputFile::readInputOrientationGeometries(vector<Molecule>& molecules) { Atom atom; Molecule mol; string line; bool ok; ok = false; int i; i = 0; while(isStringInFile("Input orientation")) { // if(isStringInFile("Input orientation")) // { /* * Jumping four lines that contains the orientation header * */ for(size_t i = 0; i < 4; i++) line = readLine(); /* * Reading the atoms * */ line = readLine(); while(line.find("-------") == string::npos) { atom.clear(); atom.setName(line.substr(13,16)); atom.setX(atof(line.substr(33,46).c_str())); atom.setY(atof(line.substr(47,59).c_str())); atom.setZ(atof(line.substr(60,70).c_str())); mol.addAtom(atom); line = readLine(); } molecules.push_back(mol); mol.clear(); ok = true; // } } if(ok) return true; else return false; }
bool AbbreviationExpander::expand (const char *label, int input_order, int output_order, Molecule &m) { TokenChain tokens; if (!tokensizeAbbreviation(label, tokens)) return false; if (expand_direction == LEFT) std::reverse(tokens.begin(), tokens.end()); m.clear(); AttPoint begin_att_point(-1, input_order); AttPoint end_att_point = begin_att_point; if (!expandParsedTokens(tokens, m, end_att_point)) return false; if (end_att_point.order != output_order) return false; output_index = end_att_point.index; return true; }
void CmfLoader::loadMolecule (Molecule &mol) { int code; mol.clear(); QS_DEF(Array<int>, cycle_numbers); QS_DEF(Array<int>, atom_stack); _atoms.clear(); _bonds.clear(); _pseudo_labels.clear(); _attachments.clear(); cycle_numbers.clear(); atom_stack.clear(); bool first_atom = true; if (!_getNextCode(code)) return; bool has_ext_part = false; /* Main loop */ do { _BondDesc *bond = 0; if (code > CMF_ALPHABET_SIZE) throw Error("unexpected code"); if (code == CMF_TERMINATOR) break; if (code == CMF_EXT) { has_ext_part = true; // Ext part has to be read till CMF_TERMINATOR break; } if (!first_atom) { int number; while (_readCycleNumber(code, number)) { while (cycle_numbers.size() <= number) cycle_numbers.push(-1); if (cycle_numbers[number] >= 0) throw Error("cycle #%d already in use", number); cycle_numbers[number] = atom_stack.top(); if (!_getNextCode(code)) break; } } if (code == CMF_SEPARATOR) { atom_stack.pop(); first_atom = true; if (!_getNextCode(code)) break; continue; } if (code == CMF_OPEN_BRACKET) { atom_stack.push(atom_stack.top()); if (!_getNextCode(code)) break; continue; } if (code == CMF_CLOSE_BRACKET) { atom_stack.pop(); if (!_getNextCode(code)) break; continue; } if (!first_atom) { bond = &_bonds.push(); bond->beg = atom_stack.top(); } if (bond != 0) { _readBond(code, *bond); int number; if (_readCycleNumber(code, number)) { if (cycle_numbers[number] < 0) throw Error("bad cycle number after bond symbol"); bond->end = cycle_numbers[number]; cycle_numbers[number] = -1; if (!_getNextCode(code)) break; continue; } } _AtomDesc &atom = _atoms.push(); if (!first_atom) atom_stack.pop(); atom_stack.push(_atoms.size() - 1); first_atom = false; if (bond != 0) bond->end = _atoms.size() - 1; memset(&atom, 0, sizeof(_AtomDesc)); atom.hydrogens = -1; atom.valence = -1; atom.pseudo_atom_idx = -1; atom.rsite = false; if (code > 0 && (code < ELEM_MAX || code == CMF_PSEUDOATOM || code == CMF_RSITE || code == CMF_RSITE_EXT)) { if (!_readAtom(code, atom, _atoms.size() - 1)) break; continue; } if (!_getNextCode(code)) break; } while (true); // if have internal decoder, finish it /* if (_decoder_obj.get() != 0) _decoder_obj->finish(); */ /* Reading finished, filling molecule */ int i; for (i = 0; i < _atoms.size(); i++) { mol.addAtom(_atoms[i].label); if (_atoms[i].pseudo_atom_idx >= 0) mol.setPseudoAtom(i, _pseudo_labels.at(_atoms[i].pseudo_atom_idx)); if (_atoms[i].rsite_bits > 0) mol.setRSiteBits(i, _atoms[i].rsite_bits); mol.setAtomCharge(i, _atoms[i].charge); mol.setAtomIsotope(i, _atoms[i].isotope); if (_atoms[i].hydrogens >= 0) mol.setImplicitH(i, _atoms[i].hydrogens); mol.setAtomRadical(i, _atoms[i].radical); if (_atoms[i].highlighted) mol.highlightAtom(i); } for (i = 0; i < _bonds.size(); i++) { int type = _bonds[i].type; int beg = _bonds[i].beg; int end = _bonds[i].end; int tmp; if (_bonds[i].swap) __swap(beg, end, tmp); int idx = mol.addBond_Silent(beg, end, type); if (_bonds[i].in_ring) mol.setEdgeTopology(idx, TOPOLOGY_RING); else mol.setEdgeTopology(idx, TOPOLOGY_CHAIN); if (_bonds[i].direction != 0) mol.setBondDirection(idx, _bonds[i].direction); if (_bonds[i].highlighted) mol.highlightBond(idx); } for (i = 0; i < _attachments.size(); i++) mol.addAttachmentPoint(_attachments[i].index, _attachments[i].atom); mol.validateEdgeTopologies(); if (has_ext_part) _readExtSection(mol); if (atom_flags != 0) { atom_flags->clear(); for (i = 0; i < _atoms.size(); i++) atom_flags->push(_atoms[i].flags); } if (bond_flags != 0) { bond_flags->clear(); for (i = 0; i < _bonds.size(); i++) bond_flags->push(_bonds[i].flags); } if (!skip_cistrans) { for (i = 0; i < _bonds.size(); i++) { if (_bonds[i].cis_trans != 0) { int parity = _bonds[i].cis_trans; if (parity > 0) mol.cis_trans.setParity(i, _bonds[i].cis_trans); else mol.cis_trans.ignore(i); mol.cis_trans.restoreSubstituents(i); } } } if (!skip_valence) { for (i = 0; i < _atoms.size(); i++) { if (_atoms[i].valence >= 0) mol.setValence(i, _atoms[i].valence); } } if (!skip_stereocenters) { for (i = 0; i < _atoms.size(); i++) { if (_atoms[i].stereo_type != 0) mol.stereocenters.add(i, _atoms[i].stereo_type, _atoms[i].stereo_group, _atoms[i].stereo_invert_pyramid); } } for (i = 0; i < _atoms.size(); i++) { if (_atoms[i].allene_stereo_parity != 0) { int left, right, subst[4]; bool pure_h[4]; int parity = _atoms[i].allene_stereo_parity; int tmp; if (!MoleculeAlleneStereo::possibleCenter(mol, i, left, right, subst, pure_h)) throw Error("invalid molecule allene stereo marker"); if (subst[1] != -1 && subst[1] < subst[0]) __swap(subst[1], subst[0], tmp); if (subst[3] != -1 && subst[3] < subst[2]) __swap(subst[3], subst[2], tmp); if (pure_h[0]) { __swap(subst[1], subst[0], tmp); parity = 3 - parity; } if (pure_h[2]) { __swap(subst[2], subst[3], tmp); parity = 3 - parity; } mol.allene_stereo.add(i, left, right, subst, parity); } } // for loadXyz() _mol = &mol; // Check if atom mapping was used if (has_mapping) { // Compute inv_atom_mapping_to_restore inv_atom_mapping_to_restore.clear_resize(atom_mapping_to_restore.size()); for (int i = 0; i < atom_mapping_to_restore.size(); i++) inv_atom_mapping_to_restore[atom_mapping_to_restore[i]] = i; // Compute inv_bond_mapping_to_restore inv_bond_mapping_to_restore.clear_resize(bond_mapping_to_restore.size()); for (int i = 0; i < bond_mapping_to_restore.size(); i++) inv_bond_mapping_to_restore[bond_mapping_to_restore[i]] = i; QS_DEF(Molecule, tmp); tmp.makeEdgeSubmolecule(mol, atom_mapping_to_restore, bond_mapping_to_restore, NULL); mol.clone(tmp, NULL, NULL); } }
void IndigoInchi::parseInchiOutput (const inchi_OutputStruct &inchi_output, Molecule &mol) { mol.clear(); Array<int> atom_indices; atom_indices.clear(); // Add atoms for (AT_NUM i = 0; i < inchi_output.num_atoms; i ++) { const inchi_Atom &inchi_atom = inchi_output.atom[i]; int idx = mol.addAtom(Element::fromString(inchi_atom.elname)); atom_indices.push(idx); } // Add bonds for (AT_NUM i = 0; i < inchi_output.num_atoms; i ++) { const inchi_Atom &inchi_atom = inchi_output.atom[i]; for (AT_NUM bi = 0; bi < inchi_atom.num_bonds; bi++) { AT_NUM nei = inchi_atom.neighbor[bi]; if (i > nei) // Add bond only once continue; int bond_order = inchi_atom.bond_type[bi]; if (bond_order == INCHI_BOND_TYPE_NONE) throw Molecule::Error("Indigo-InChI: NONE-typed bonds are not supported"); if (bond_order >= INCHI_BOND_TYPE_ALTERN) throw Molecule::Error("Indigo-InChI: ALTERN-typed bonds are not supported"); int bond = mol.addBond(atom_indices[i], atom_indices[nei], bond_order); } } // Add Hydrogen isotope atoms at the end to preserver // the same atom ordering for (AT_NUM i = 0; i < inchi_output.num_atoms; i ++) { const inchi_Atom &inchi_atom = inchi_output.atom[i]; int root_atom = atom_indices[i]; for (int iso = 1; iso <= NUM_H_ISOTOPES; iso++) { int count = inchi_atom.num_iso_H[iso]; while (count-- > 0) { int h = mol.addAtom(ELEM_H); mol.setAtomIsotope(h, iso); mol.addBond(root_atom, h, BOND_SINGLE); } } } // Set atom charges, radicals and etc. for (int i = 0; i < inchi_output.num_atoms; i++) { const inchi_Atom &inchi_atom = inchi_output.atom[i]; int idx = atom_indices[i]; mol.setAtomCharge(idx, inchi_atom.charge); if (inchi_atom.isotopic_mass) mol.setAtomIsotope(idx, inchi_atom.isotopic_mass); if (inchi_atom.radical) mol.setAtomRadical(idx, inchi_atom.radical); mol.setImplicitH(idx, inchi_atom.num_iso_H[0]); } neutralizeV5Nitrogen(mol); // Process stereoconfiguration for (int i = 0; i < inchi_output.num_stereo0D; i++) { inchi_Stereo0D &stereo0D = inchi_output.stereo0D[i]; if (stereo0D.type == INCHI_StereoType_DoubleBond) { if (stereo0D.parity != INCHI_PARITY_ODD && stereo0D.parity != INCHI_PARITY_EVEN) continue; int bond = mol.findEdgeIndex(stereo0D.neighbor[1], stereo0D.neighbor[2]); bool valid = mol.cis_trans.registerBondAndSubstituents(bond); if (!valid) throw IndigoError("Indigo-InChI: Unsupported cis-trans configuration for " "bond %d (atoms %d-%d-%d-%d)", bond, stereo0D.neighbor[0], stereo0D.neighbor[1], stereo0D.neighbor[2], stereo0D.neighbor[3]); int vb, ve; const Edge &edge = mol.getEdge(bond); if (edge.beg == stereo0D.neighbor[1]) { vb = stereo0D.neighbor[0]; ve = stereo0D.neighbor[3]; } else if (edge.beg == stereo0D.neighbor[2]) { vb = stereo0D.neighbor[3]; ve = stereo0D.neighbor[0]; } else throw IndigoError("Indigo-InChI: Internal error: cannot find cis-trans bond indices"); const int *subst = mol.cis_trans.getSubstituents(bond); bool same_side; if (subst[0] == vb) same_side = (subst[2] == ve); else if (subst[1] == vb) same_side = (subst[3] == ve); else throw IndigoError("Indigo-InChI: Internal error: cannot find cis-trans bond indices (#2)"); if (stereo0D.parity == INCHI_PARITY_EVEN) same_side = !same_side; mol.cis_trans.setParity(bond, same_side ? MoleculeCisTrans::CIS : MoleculeCisTrans::TRANS); } else if (stereo0D.type == INCHI_StereoType_Tetrahedral) { if (stereo0D.parity != INCHI_PARITY_ODD && stereo0D.parity != INCHI_PARITY_EVEN) continue; int pyramid[4]; if (stereo0D.central_atom == stereo0D.neighbor[0]) { pyramid[1] = stereo0D.neighbor[1]; pyramid[0] = stereo0D.neighbor[2]; pyramid[2] = stereo0D.neighbor[3]; pyramid[3] = -1; } else { pyramid[0] = stereo0D.neighbor[0]; pyramid[1] = stereo0D.neighbor[1]; pyramid[2] = stereo0D.neighbor[2]; pyramid[3] = stereo0D.neighbor[3]; } if (stereo0D.parity == INCHI_PARITY_ODD) std::swap(pyramid[0], pyramid[1]); mol.stereocenters.add(stereo0D.central_atom, MoleculeStereocenters::ATOM_ABS, 0, pyramid); } } }