1 /********************************************************************** 2 Copyright (C) 2005-2006 by Geoffrey R. Hutchison 3 4 Thanks to Kevin Gilbert from Serena Software for documentation and examples! 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 16 #include <openbabel/obmolecformat.h> 17 #include <openbabel/mol.h> 18 #include <openbabel/atom.h> 19 #include <openbabel/elements.h> 20 #include <openbabel/data.h> 21 #include <openbabel/obiter.h> 22 #include <openbabel/bond.h> 23 #include <cstdlib> 24 25 26 using namespace std; 27 namespace OpenBabel 28 { 29 30 class PCModelFormat : public OBMoleculeFormat 31 { 32 public: 33 //Register this format type ID PCModelFormat()34 PCModelFormat() 35 { 36 OBConversion::RegisterFormat("pcm", this); 37 } 38 Description()39 virtual const char* Description() //required 40 { 41 return 42 "PCModel Format\n" 43 "No comments yet\n"; 44 }; 45 46 //Flags() can return be any the following combined by | or be omitted if none apply 47 // NOTREADABLE READONEONLY NOTWRITABLE WRITEONEONLY 48 // virtual unsigned int Flags() 49 // { 50 // return NOTREADABLE; 51 // }; 52 SpecificationURL()53 virtual const char* SpecificationURL() 54 {return "http://www.serenasoft.com/";}; //optional 55 56 //*** This section identical for most OBMol conversions *** 57 //////////////////////////////////////////////////// 58 /// The "API" interface functions 59 virtual bool ReadMolecule(OBBase* pOb, OBConversion* pConv); 60 virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv); 61 }; 62 //*** 63 64 //Make an instance of the format class 65 PCModelFormat thePCModelFormat; 66 67 ///////////////////////////////////////////////////////////////// ReadMolecule(OBBase * pOb,OBConversion * pConv)68 bool PCModelFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv) 69 { 70 71 OBMol* pmol = dynamic_cast<OBMol*>(pOb); 72 if (pmol == nullptr) 73 return false; 74 75 //Define some references so we can use the old parameter names 76 istream &ifs = *pConv->GetInStream(); 77 OBMol &mol = *pmol; 78 const char* title = pConv->GetTitle(); 79 char buffer[BUFF_SIZE]; 80 string temp, temp2; 81 82 OBAtom *atom; 83 vector<string> vs; 84 double x, y, z; 85 unsigned int token; 86 int bondNbr, bondOrder; 87 bool parsingBonds, readingMol = false; 88 bool hasPartialCharges = false; 89 90 ttab.SetFromType("PCM"); 91 92 mol.BeginModify(); 93 94 while (ifs.getline(buffer,BUFF_SIZE)) 95 { 96 if(strncmp(buffer,"{PCM", 4) == 0) 97 { 98 temp = buffer; 99 temp = temp.substr(4, temp.length()); 100 mol.SetTitle(temp); 101 readingMol = true; 102 } 103 else if (readingMol && strncmp(buffer,"}", 1) == 0) 104 { 105 readingMol = false; 106 break; 107 } 108 else if (readingMol && strncmp(buffer,"AT ",3) == 0) 109 { 110 tokenize(vs,buffer, "\n\r\t ,:"); 111 if (vs.size() < 3) 112 return false; 113 114 atom = mol.NewAtom(); 115 temp = vs[2].c_str(); 116 ttab.SetToType("INT"); 117 ttab.Translate(temp2, temp); 118 atom->SetType(temp2); 119 120 ttab.SetToType("ATN"); 121 ttab.Translate(temp2, temp); 122 atom->SetAtomicNum(atoi(temp2.c_str())); 123 x = atof(vs[3].c_str()); 124 y = atof(vs[4].c_str()); 125 z = atof(vs[5].c_str()); 126 atom->SetVector(x,y,z); //set coordinates 127 128 token = 6; 129 parsingBonds = false; 130 while(token < vs.size()) 131 { 132 if (vs[token] == "B") 133 parsingBonds = true; 134 else if (vs[token][0] == 'C') 135 { 136 parsingBonds = false; 137 hasPartialCharges = true; 138 if (vs[token].size() > 1) 139 temp = vs[token].substr(1,vs[token].size()); 140 else 141 { 142 token++; 143 temp = vs[token]; 144 } 145 atom->SetPartialCharge(atof(temp.c_str())); 146 } 147 148 else if (parsingBonds && token < vs.size() - 1 && 149 isdigit(vs[token][0])) 150 { 151 bondNbr = atoi(vs[token++].c_str()); // advance to bond order 152 bondOrder = atoi(vs[token].c_str()); 153 if (bondOrder == 9) 154 bondOrder = 1; 155 mol.AddBond(atom->GetIdx(), bondNbr, bondOrder, 0); 156 } 157 else 158 parsingBonds = false; // any other token 159 160 token++; 161 } // end atom fields 162 } // end AT line 163 } // end reading 164 165 // clean out remaining blank lines 166 std::streampos ipos; 167 do 168 { 169 ipos = ifs.tellg(); 170 ifs.getline(buffer,BUFF_SIZE); 171 } 172 while(strlen(buffer) == 0 && !ifs.eof() ); 173 ifs.seekg(ipos); 174 175 mol.EndModify(); 176 if (hasPartialCharges) 177 mol.SetPartialChargesPerceived(); 178 mol.SetTitle(title); 179 return(true); 180 } 181 182 //////////////////////////////////////////////////////////////// 183 WriteMolecule(OBBase * pOb,OBConversion * pConv)184 bool PCModelFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv) 185 { 186 OBMol* pmol = dynamic_cast<OBMol*>(pOb); 187 if (pmol == nullptr) 188 return false; 189 190 //Define some references so we can use the old parameter names 191 ostream &ofs = *pConv->GetOutStream(); 192 OBMol &mol = *pmol; 193 OBAtom *nbr; 194 vector<OBBond*>::iterator j; 195 string type, temp; 196 int nbrIdx, atomIdx; 197 198 temp = mol.GetTitle(); 199 ofs << "{PCM " << temp.substr(0,60) << endl; 200 ofs << "NA " << mol.NumAtoms() << endl; 201 ofs << "ATOMTYPES 1" << endl; // MMX atom types 202 203 ttab.SetFromType("INT"); 204 ttab.SetToType("PCM"); 205 206 string str,str1; 207 FOR_ATOMS_OF_MOL(atom, mol) 208 { 209 ttab.Translate(type,atom->GetType()); 210 atomIdx = atom->GetIdx(); 211 212 ofs << "AT " << atom->GetIdx() << "," << type << ":"; 213 ofs << atom->GetX() << "," << atom->GetY() << "," << atom->GetZ(); 214 215 if (atom->GetExplicitDegree() > 0) 216 { 217 ofs << " B"; 218 for (nbr = atom->BeginNbrAtom(j);nbr;nbr = atom->NextNbrAtom(j)) 219 { 220 nbrIdx = nbr->GetIdx(); 221 ofs << " " << nbrIdx << "," 222 << (mol.GetBond(nbrIdx, atomIdx))->GetBondOrder(); 223 } 224 } 225 226 ofs << " C " << atom->GetPartialCharge(); 227 228 ofs << endl; 229 } 230 231 ofs << "}" << endl; 232 233 return(true); 234 } 235 236 } //namespace OpenBabel 237