1 /********************************************************************** 2 Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc. 3 Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison 4 Some portions Copyright (C) 2004 by Chris Morley 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation version 2 of the License. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 ***********************************************************************/ 15 #include <openbabel/babelconfig.h> 16 #include <openbabel/obmolecformat.h> 17 #include <openbabel/mol.h> 18 #include <openbabel/atom.h> 19 #include <openbabel/bond.h> 20 #include <openbabel/elements.h> 21 22 #include <cstdlib> 23 24 using namespace std; 25 namespace OpenBabel 26 { 27 28 class ChemDrawFormat : public OBMoleculeFormat 29 { 30 public: 31 //Register this format type ID ChemDrawFormat()32 ChemDrawFormat() 33 { 34 OBConversion::RegisterFormat("ct",this); 35 } 36 Description()37 virtual const char* Description() //required 38 { 39 return 40 "ChemDraw Connection Table format\n" 41 "No comments yet\n"; 42 }; 43 SpecificationURL()44 virtual const char* SpecificationURL() 45 {return "";}; //optional 46 47 //Flags() can return be any the following combined by | or be omitted if none apply 48 // NOTREADABLE READONEONLY NOTWRITABLE WRITEONEONLY Flags()49 virtual unsigned int Flags() 50 { 51 return READONEONLY | WRITEONEONLY; 52 }; 53 54 //*** This section identical for most OBMol conversions *** 55 //////////////////////////////////////////////////// 56 /// The "API" interface functions 57 virtual bool ReadMolecule(OBBase* pOb, OBConversion* pConv); 58 virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv); 59 }; 60 //*** 61 62 //Make an instance of the format class 63 ChemDrawFormat theChemDrawFormat; 64 65 //////////////////////////////////////////////////////////////// 66 WriteMolecule(OBBase * pOb,OBConversion * pConv)67 bool ChemDrawFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv) 68 { 69 OBMol* pmol = dynamic_cast<OBMol*>(pOb); 70 if (pmol == nullptr) 71 return false; 72 73 //Define some references so we can use the old parameter names 74 ostream &ofs = *pConv->GetOutStream(); 75 OBMol &mol = *pmol; 76 77 char buffer[BUFF_SIZE]; 78 79 ofs << mol.GetTitle() << endl; 80 ofs << " " << mol.NumAtoms() << " " << mol.NumBonds() << endl; 81 82 OBAtom *atom; 83 vector<OBAtom*>::iterator i; 84 85 for(atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) 86 { 87 snprintf(buffer, BUFF_SIZE, " %9.4f %9.4f 0.0000 %-1s", 88 atom->x(), 89 atom->y(), 90 OBElements::GetSymbol(atom->GetAtomicNum())); 91 ofs << buffer << endl; 92 } 93 94 OBBond *bond; 95 vector<OBBond*>::iterator j; 96 97 for(bond = mol.BeginBond(j);bond;bond = mol.NextBond(j)) 98 { 99 snprintf(buffer, BUFF_SIZE, "%3d%3d%3d%3d", 100 bond->GetBeginAtomIdx(), 101 bond->GetEndAtomIdx(), 102 bond->GetBondOrder(), bond->GetBondOrder()); 103 ofs << buffer << endl; 104 } 105 return(true); 106 } 107 ReadMolecule(OBBase * pOb,OBConversion * pConv)108 bool ChemDrawFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv) 109 { 110 OBMol* pmol = pOb->CastAndClear<OBMol>(); 111 if (pmol == nullptr) 112 return false; 113 114 //Define some references so we can use the old parameter names 115 istream &ifs = *pConv->GetInStream(); 116 OBMol &mol = *pmol; 117 const char* title = pConv->GetTitle(); 118 119 char buffer[BUFF_SIZE]; 120 unsigned int natoms, nbonds; 121 unsigned int bgn, end, order; 122 vector<string> vs; 123 OBAtom *atom; 124 double x, y, z; 125 126 mol.SetDimension(2); 127 mol.BeginModify(); 128 129 ifs.getline(buffer,BUFF_SIZE); 130 if (strlen(buffer) == 0) 131 mol.SetTitle(buffer); 132 else 133 mol.SetTitle(title); 134 135 ifs.getline(buffer,BUFF_SIZE); 136 sscanf(buffer," %d %d", &natoms, &nbonds); 137 138 for (unsigned int i = 1; i <= natoms; i ++) 139 { 140 if (!ifs.getline(buffer,BUFF_SIZE)) return(false); 141 tokenize(vs,buffer); 142 if (vs.size() != 4) return(false); 143 atom = mol.NewAtom(); 144 145 x = atof((char*)vs[0].c_str()); 146 y = atof((char*)vs[1].c_str()); 147 z = atof((char*)vs[2].c_str()); 148 149 atom->SetVector(x,y,z); //set coordinates 150 atom->SetAtomicNum(OBElements::GetAtomicNum(vs[3].c_str())); 151 } 152 153 if (nbonds != 0) 154 for (unsigned int i = 0; i < nbonds; i++) 155 { 156 if (!ifs.getline(buffer,BUFF_SIZE)) return(false); 157 tokenize(vs,buffer); 158 if (vs.size() != 4) return(false); 159 if (!sscanf(buffer,"%d%d%d%*d",&bgn,&end,&order)) return (false); 160 mol.AddBond(bgn,end,order); 161 } 162 163 // clean out remaining blank lines 164 std::streampos ipos; 165 do 166 { 167 ipos = ifs.tellg(); 168 ifs.getline(buffer,BUFF_SIZE); 169 } 170 while(strlen(buffer) == 0 && !ifs.eof() ); 171 ifs.seekg(ipos); 172 173 mol.EndModify(); 174 return(true); 175 } 176 177 178 } //namespace OpenBabel 179