bool TinkerFormat::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; bool mmffTypes = pConv->IsOption("m",OBConversion::OUTOPTIONS) != NULL; unsigned int i; char buffer[BUFF_SIZE]; OBBond *bond; vector<OBBond*>::iterator j; // Before we try output of MMFF94 atom types, check if it works OBForceField *ff = OpenBabel::OBForceField::FindForceField("MMFF94"); if (mmffTypes && ff && ff->Setup(mol)) mmffTypes = ff->GetAtomTypes(mol); else mmffTypes = false; // either the force field isn't available, or it doesn't work if (!mmffTypes) snprintf(buffer, BUFF_SIZE, "%6d %-20s MM2 parameters\n",mol.NumAtoms(),mol.GetTitle()); else snprintf(buffer, BUFF_SIZE, "%6d %-20s MMFF94 parameters\n",mol.NumAtoms(),mol.GetTitle()); ofs << buffer; ttab.SetFromType("INT"); OBAtom *atom; string str,str1; for(i = 1;i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); str = atom->GetType(); ttab.SetToType("MM2"); ttab.Translate(str1,str); if (mmffTypes) { // Override the MM2 typing OBPairData *type = (OpenBabel::OBPairData*)atom->GetData("FFAtomType"); if (type) str1 = type->GetValue().c_str(); } snprintf(buffer, BUFF_SIZE, "%6d %2s %12.6f%12.6f%12.6f %5d", i, etab.GetSymbol(atom->GetAtomicNum()), atom->GetX(), atom->GetY(), atom->GetZ(), atoi((char*)str1.c_str())); ofs << buffer; for (bond = atom->BeginBond(j); bond; bond = atom->NextBond(j)) { snprintf(buffer, BUFF_SIZE, "%6d", (bond->GetNbrAtom(atom))->GetIdx()); ofs << buffer; } ofs << endl; } return(true); }
bool TinkerFormat::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; bool mm2Types = false; bool mmffTypes = pConv->IsOption("m",OBConversion::OUTOPTIONS) != NULL; bool mm3Types = pConv->IsOption("3",OBConversion::OUTOPTIONS) != NULL; bool classTypes = pConv->IsOption("c", OBConversion::OUTOPTIONS) != NULL; unsigned int i; char buffer[BUFF_SIZE]; OBBond *bond; vector<OBBond*>::iterator j; // Before we try output of MMFF94 atom types, check if it works OBForceField *ff = OpenBabel::OBForceField::FindForceField("MMFF94"); if (mmffTypes && ff && ff->Setup(mol)) mmffTypes = ff->GetAtomTypes(mol); else mmffTypes = false; // either the force field isn't available, or it doesn't work if (!mmffTypes && !mm3Types && !classTypes) { snprintf(buffer, BUFF_SIZE, "%6d %-20s MM2 parameters\n",mol.NumAtoms(),mol.GetTitle()); mm2Types = true; } else if (mm3Types) snprintf(buffer, BUFF_SIZE, "%6d %-20s MM3 parameters\n",mol.NumAtoms(),mol.GetTitle()); else if (classTypes) snprintf(buffer, BUFF_SIZE, "%6d %-20s Custom parameters\n",mol.NumAtoms(),mol.GetTitle()); else snprintf(buffer, BUFF_SIZE, "%6d %-20s MMFF94 parameters\n",mol.NumAtoms(),mol.GetTitle()); ofs << buffer; ttab.SetFromType("INT"); OBAtom *atom; string str,str1; int atomType; for(i = 1;i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); str = atom->GetType(); atomType = 0; // Something is very wrong if this doesn't get set below if (mm2Types) { ttab.SetToType("MM2"); ttab.Translate(str1,str); atomType = atoi((char*)str1.c_str()); } if (mmffTypes) { // Override the MM2 typing OBPairData *type = (OpenBabel::OBPairData*)atom->GetData("FFAtomType"); if (type) { str1 = type->GetValue().c_str(); atomType = atoi((char*)str1.c_str()); } } if (mm3Types) { // convert to integer for MM3 typing atomType = SetMM3Type(atom); } if (classTypes) { // Atom classes are set by the user, so use those OBGenericData *data = atom->GetData("Atom Class"); if (data) { OBPairInteger* acdata = dynamic_cast<OBPairInteger*>(data); // Could replace with C-style cast if willing to live dangerously if (acdata) { int ac = acdata->GetGenericValue(); if (ac >= 0) atomType = ac; } } } snprintf(buffer, BUFF_SIZE, "%6d %2s %12.6f%12.6f%12.6f %5d", i, OBElements::GetSymbol(atom->GetAtomicNum()), atom->GetX(), atom->GetY(), atom->GetZ(), atomType); ofs << buffer; for (bond = atom->BeginBond(j); bond; bond = atom->NextBond(j)) { snprintf(buffer, BUFF_SIZE, "%6d", (bond->GetNbrAtom(atom))->GetIdx()); ofs << buffer; } ofs << endl; } return(true); }
bool OBDepict::DrawMolecule(OBMol *mol) { if (!d->painter) return false; d->mol = mol; double width=0.0, height=0.0; OBAtom *atom; OBBondIterator j; OBAtomIterator i; if(mol->NumAtoms()>0) { // scale bond lengths double bondLengthSum = 0.0; for (OBBond *bond = mol->BeginBond(j); bond; bond = mol->NextBond(j)) bondLengthSum += bond->GetLength(); const double averageBondLength = bondLengthSum / mol->NumBonds(); const double f = mol->NumBonds() ? d->bondLength / averageBondLength : 1.0; for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i)) atom->SetVector(atom->GetX() * f, atom->GetY() * f, 0.0); // find min/max values double min_x, max_x; double min_y, max_y; atom = mol->BeginAtom(i); min_x = max_x = atom->GetX(); min_y = max_y = atom->GetY(); for (atom = mol->NextAtom(i); atom; atom = mol->NextAtom(i)) { min_x = std::min(min_x, atom->GetX()); max_x = std::max(max_x, atom->GetX()); min_y = std::min(min_y, atom->GetY()); max_y = std::max(max_y, atom->GetY()); } const double margin = 40.0; // translate all atoms so the bottom-left atom is at margin,margin for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i)) atom->SetVector(atom->GetX() - min_x + margin, atom->GetY() - min_y + margin, 0.0); width = max_x - min_x + 2*margin; height = max_y - min_y + 2*margin; //d->painter->SetPenWidth(d->penWidth); //d->painter->SetPenColor(d->pen)); //d->painter->SetFillColor(OBColor("black")); } d->painter->NewCanvas(width, height); // draw bonds if(d->options & genWedgeHash) d->SetWedgeAndHash(mol); for (OBBond *bond = mol->BeginBond(j); bond; bond = mol->NextBond(j)) { OBAtom *begin = bond->GetBeginAtom(); OBAtom *end = bond->GetEndAtom(); if((d->options & internalColor) && bond->HasData("color")) d->painter->SetPenColor(OBColor(bond->GetData("color")->GetValue())); else d->painter->SetPenColor(d->bondColor); if (bond->IsWedge()) { d->DrawWedge(begin, end); } else if (bond->IsHash()) { d->DrawHash(begin, end); } else if (!bond->IsInRing()) { d->DrawSimpleBond(begin, end, bond->GetBO()); } } // draw ring bonds std::vector<OBRing*> rings(mol->GetSSSR()); OBBitVec drawnBonds; for (std::vector<OBRing*>::iterator k = rings.begin(); k != rings.end(); ++k) { OBRing *ring = *k; std::vector<int> indexes = ring->_path; vector3 center(VZero); for (std::vector<int>::iterator l = indexes.begin(); l != indexes.end(); ++l) { center += mol->GetAtom(*l)->GetVector(); } center /= indexes.size(); for (unsigned int l = 0; l < indexes.size(); ++l) { OBAtom *begin = mol->GetAtom(indexes[l]); OBAtom *end; if (l+1 < indexes.size()) end = mol->GetAtom(indexes[l+1]); else end = mol->GetAtom(indexes[0]); OBBond *ringBond = mol->GetBond(begin, end); if (drawnBonds.BitIsSet(ringBond->GetId())) continue; if((d->options & internalColor) && ringBond->HasData("color")) d->painter->SetPenColor(OBColor(ringBond->GetData("color")->GetValue())); else d->painter->SetPenColor(d->bondColor); d->DrawRingBond(begin, end, center, ringBond->GetBO()); drawnBonds.SetBitOn(ringBond->GetId()); } } // draw atom labels for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i)) { double x = atom->GetX(); double y = atom->GetY(); int alignment = GetLabelAlignment(atom); bool rightAligned = false; switch (alignment) { case TopRight: case CenterRight: case BottomRight: rightAligned = true; default: break; } if((d->options & internalColor) && atom->HasData("color")) d->painter->SetPenColor(OBColor(atom->GetData("color")->GetValue())); else if(d->options & bwAtoms) d->painter->SetPenColor(d->bondColor); else d->painter->SetPenColor(OBColor(etab.GetRGB(atom->GetAtomicNum()))); //charge and radical int charge = atom->GetFormalCharge(); int spin = atom->GetSpinMultiplicity(); if(charge || spin) { OBFontMetrics metrics = d->painter->GetFontMetrics("N"); double yoffset = d->HasLabel(atom) ? 0.4 * metrics.height : 0.0; switch (GetLabelAlignment(atom)) { case TopCenter: case TopRight: case TopLeft: case CenterLeft: case CenterRight: yoffset = - 1.2 * metrics.height; } stringstream ss; if(charge) { if(abs(charge)!=1) ss << abs(charge); ss << (charge>0 ? "+" : "-") ; } if(spin) { ss << (spin==2 ? "." : ".."); yoffset += 0.5 * metrics.height; } if(spin || charge<0) d->painter->SetFontSize(2 * metrics.fontSize); d->painter->DrawText(x-0.4*metrics.width, y-yoffset, ss.str()); d->painter->SetFontSize(metrics.fontSize);//restore } if (atom->IsCarbon()) { if(!(d->options & drawAllC)) { if (atom->GetValence() > 1) continue; if ((atom->GetValence() == 1) && !(d->options & drawTermC))//!d->drawTerminalC) continue; } } stringstream ss; AliasData* ad = NULL; if(d->aliasMode && atom->HasData(AliasDataType)) ad = static_cast<AliasData*>(atom->GetData(AliasDataType)); //For unexpanded aliases use appropriate form of alias instead of element symbol, Hs, etc if(ad && !ad->IsExpanded()) { ss <<ad->GetAlias(rightAligned); OBColor aliasColor = !ad->GetColor().empty() ? ad->GetColor() : d->bondColor; d->painter->SetPenColor(aliasColor); } else { const char* atomSymbol; if(atom->IsHydrogen() && atom->GetIsotope()>1) atomSymbol = atom->GetIsotope()==2 ? "D" : "T"; else atomSymbol = etab.GetSymbol(atom->GetAtomicNum()); unsigned int hCount = atom->ImplicitHydrogenCount(); // rightAligned: // false CH3 // true H3C if (hCount && rightAligned) ss << "H"; if ((hCount > 1) && rightAligned) ss << hCount; ss << atomSymbol; if (hCount && !rightAligned) ss << "H"; if ((hCount > 1) && !rightAligned) ss << hCount; } d->DrawAtomLabel(ss.str(), alignment, vector3(x, y, 0.0)); } return true; }
int main(int argc,char **argv) { char *program_name= argv[0]; char *FileIn = NULL; if (argc != 2) { cout << "Usage: " << program_name << " <filename>" << endl; exit(-1); } else { FileIn = argv[1]; // const char* p = strrchr(FileIn,'.'); } // Find Input filetype OBConversion conv; OBFormat *format = conv.FormatFromExt(FileIn); if (!format || !conv.SetInAndOutFormats(format, format)) { cerr << program_name << ": cannot read input format!" << endl; exit (-1); } ifstream ifs; // Read the file ifs.open(FileIn); if (!ifs) { cerr << program_name << ": cannot read input file!" << endl; exit (-1); } OBMol mol; OBAtom *atom; for (int c=1;;++c) // big for loop (replace with do while?) { mol.Clear(); conv.Read(&mol, &ifs); if (mol.Empty()) break; cout << "Molecule "<< c << ": " << mol.GetTitle() << endl; //mol.FindChiralCenters(); // labels all chiral atoms vector<OBAtom*>::iterator i; // iterate over all atoms for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) { if(!atom->IsChiral())continue; // aborts if atom isn't chiral cout << "Atom " << atom->GetIdx() << " Is Chiral "; cout << atom->GetType()<<endl; OBChiralData* cd = (OBChiralData*)atom->GetData(OBGenericDataType::ChiralData); if (cd){ vector<unsigned int> x=cd->GetAtom4Refs(input); size_t n=0; cout <<"Atom4refs:"; for (n=0;n<x.size();++n) cout <<" "<<x[n]; cout <<endl; } else{cd=new OBChiralData;atom->SetData(cd);} vector<unsigned int> _output; unsigned int n; for(n=1;n<5;++n) _output.push_back(n); cd->SetAtom4Refs(_output,output); /* // MOLV3000 uses 1234 unless an H then 123H if (atom->GetHvyValence()==3) { OBAtom *nbr; int Hid=1000;// max Atom ID +1 should be used here vector<unsigned int> nbr_atms; vector<OBBond*>::iterator i; for (nbr = atom->BeginNbrAtom(i);nbr;nbr = atom->NextNbrAtom(i)) { if (nbr->IsHydrogen()){Hid=nbr->GetIdx();continue;} nbr_atms.push_back(nbr->GetIdx()); } sort(nbr_atms.begin(),nbr_atms.end()); nbr_atms.push_back(Hid); OBChiralData* cd=(OBChiralData*)atom->GetData(OBGenericDataType::ChiralData); cd->SetAtom4Refs(nbr_atms,output); } else if (atom->GetHvyValence()==4) { OBChiralData* cd=(OBChiralData*)atom->GetData(OBGenericDataType::ChiralData); vector<unsigned int> nbr_atms; int n; for(n=1;n<5;++n)nbr_atms.push_back(n); cd->SetAtom4Refs(nbr_atms,output); } */ /* FIXME if (!mol.HasNonZeroCoords()) { cout << "Calcing 0D chirality "<< CorrectChirality(mol,atom)<<endl; } else { cout << "Volume= "<< CalcSignedVolume(mol,atom) << endl; OBChiralData* cd=(OBChiralData*)atom->GetData(OBGenericDataType::ChiralData); size_t n; vector<unsigned int> refs=cd->GetAtom4Refs(output); cout<<"Atom refs="; for(n=0;n<refs.size();++n)cout<<" "<<refs[n]; cout<<endl; } cout << "Clockwise? " << atom->IsClockwise() << endl; */ } // end iterating over atoms } // end big for loop return(0); } // end main