bool JaguarInputFormat::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; unsigned int i; char buffer[BUFF_SIZE]; OBAtom *atom; ofs << mol.GetTitle() << endl << endl; ofs << "&gen" << endl; ofs << "&" << endl; ofs << "&zmat" << endl; for (i = 1;i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); snprintf(buffer, BUFF_SIZE, " %s%d %12.7f %12.7f %12.7f", etab.GetSymbol(atom->GetAtomicNum()), i, atom->GetX(), atom->GetY(), atom->GetZ()); ofs << buffer << endl; } ofs << "&" << endl; return(true); }
bool WriteXYZ(ostream &ofs,OBMol &mol) { unsigned int i; char buffer[BUFF_SIZE]; sprintf(buffer,"%d", mol.NumAtoms()); ofs << buffer << endl; sprintf(buffer,"%s\tEnergy: %15.7f", mol.GetTitle(), mol.GetEnergy()); ofs << buffer << endl; OBAtom *atom; string str,str1; for(i = 1;i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); sprintf(buffer,"%3s%15.5f%15.5f%15.5f", etab.GetSymbol(atom->GetAtomicNum()), atom->GetX(), atom->GetY(), atom->GetZ()); ofs << buffer << endl; } return(true); }
bool WriteViewMol(ostream &ofs,OBMol &mol) { unsigned int i; char buffer[BUFF_SIZE]; if (strlen(mol.GetTitle()) > 0) ofs << "$title" << endl << mol.GetTitle() << endl; ofs << "$coord 1.0" << endl; OBAtom *atom; for(i = 1;i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); sprintf(buffer,"%22.14f%22.14f%22.14f %s", atom->GetX(), atom->GetY(), atom->GetZ(), etab.GetSymbol(atom->GetAtomicNum())); ofs << buffer << endl; } ofs << "$end" << endl; return(true); }
bool PQSFormat::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; unsigned int i; char buffer[BUFF_SIZE]; OBAtom *atom; ofs<<"TEXT="<<mol.GetTitle()<<endl; ofs<<"GEOM=PQS"<<endl; for (i=1; i<=mol.NumAtoms(); i++) { atom=mol.GetAtom(i); snprintf(buffer, BUFF_SIZE, "%s %10.6lf %10.6lf %10.6lf", OBElements::GetSymbol(atom->GetAtomicNum()), atom->GetX(), atom->GetY(), atom->GetZ()); ofs<<buffer<<endl; } return(true); }
bool TurbomoleFormat::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; double UnitConv=AAU; if(pConv->IsOption("a")) UnitConv=1; ofs << "$coord" <<endl; char buffer[BUFF_SIZE]; OBAtom *atom; vector<OBAtom*>::iterator i; for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) { char symb[8]; strcpy(symb,OBElements::GetSymbol(atom->GetAtomicNum())); snprintf(buffer, BUFF_SIZE, "%20.14f %20.14f %20.14f %s", atom->GetX()/UnitConv, atom->GetY()/UnitConv, atom->GetZ()/UnitConv, strlwr(symb) ); ofs << buffer << endl; } ofs << "$end" << endl; return true; }
bool WriteAlchemy(ostream &ofs,OBMol &mol) { unsigned int i; char buffer[BUFF_SIZE]; char bond_string[10]; snprintf(buffer, BUFF_SIZE, "%5d ATOMS, %5d BONDS, 0 CHARGES", mol.NumAtoms(), mol.NumBonds()); ofs << buffer << endl; ttab.SetFromType("INT"); ttab.SetToType("ALC"); OBAtom *atom; string str,str1; for(i = 1;i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); str = atom->GetType(); ttab.Translate(str1,str); snprintf(buffer, BUFF_SIZE, "%5d %-6s%8.4f %8.4f %8.4f 0.0000", i, (char*)str1.c_str(), atom->GetX(), atom->GetY(), atom->GetZ()); ofs << buffer << endl; } OBBond *bond; vector<OBEdgeBase*>::iterator j; for (bond = mol.BeginBond(j);bond;bond = mol.NextBond(j)) { switch(bond->GetBO()) { case 1 : strcpy(bond_string,"SINGLE"); break; case 2 : strcpy(bond_string,"DOUBLE"); break; case 3 : strcpy(bond_string,"TRIPLE"); break; case 5 : strcpy(bond_string,"AROMATIC"); break; default : strcpy(bond_string,"SINGLE"); } snprintf(buffer, BUFF_SIZE, "%5d %4d %4d %s", bond->GetIdx()+1, bond->GetBeginAtomIdx(), bond->GetEndAtomIdx(), bond_string); ofs << buffer << endl; } return(true); }
BoundingBox NXOpenGLRenderingEngine::GetBoundingBox(OBMol *const molPtr) { BoundingBox bbox; OBAtomIterator atomIter; OBAtom *atomPtr = NULL; for(atomPtr = molPtr->BeginAtom(atomIter); atomPtr != NULL; atomPtr = molPtr->NextAtom(atomIter)) { Vector atomPos(real(atomPtr->GetX()), real(atomPtr->GetY()), real(atomPtr->GetZ())); bbox += atomPos; } return bbox; }
bool WriteHIN(ostream &ofs,OBMol &mol) { unsigned int i, file_num = 1; string str,str1; char buffer[BUFF_SIZE]; OBAtom *atom; OBBond *bond; vector<OBEdgeBase*>::iterator j; char bond_char; ofs << "mol " << file_num << " " << mol.GetTitle() << endl;; for(i = 1;i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); sprintf(buffer,"atom %d - %-3s ** - %8.5f %8.5f %8.5f %8.5f %d ", i, etab.GetSymbol(atom->GetAtomicNum()), atom->GetPartialCharge(), atom->GetX(), atom->GetY(), atom->GetZ(), atom->GetValence()); ofs << buffer; for (bond = atom->BeginBond(j); bond; bond = atom->NextBond(j)) { switch(bond->GetBO()) { case 1 : bond_char = 's'; break; case 2 : bond_char = 'd'; break; case 3 : bond_char = 't'; break; case 5 : bond_char = 'a'; break; default: bond_char = 's'; break; } sprintf(buffer,"%d %c ", (bond->GetNbrAtom(atom))->GetIdx(), bond_char); ofs << buffer; } ofs << endl; } ofs << "endmol " << file_num << 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 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 PDBFormat::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; unsigned int i; char buffer[BUFF_SIZE]; char type_name[10], padded_name[10]; char the_res[10]; char the_chain = ' '; const char *element_name; int res_num; bool het=true; int model_num = 0; if (!pConv->IsLast() || pConv->GetOutputIndex() > 1) { // More than one molecule record model_num = pConv->GetOutputIndex(); // MODEL 1-based index snprintf(buffer, BUFF_SIZE, "MODEL %8d", model_num); ofs << buffer << endl; } // write back all fields (REMARKS, HELIX, SHEET, SITE, ...) bool compndWritten = false; bool authorWritten = false; std::vector<OBGenericData*> pairData = mol.GetAllData(OBGenericDataType::PairData); for (std::vector<OBGenericData*>::iterator data = pairData.begin(); data != pairData.end(); ++data) { OBPairData *pd = static_cast<OBPairData*>(*data); string attr = pd->GetAttribute(); // filter to make sure we are writing pdb fields only if (attr != "HEADER" && attr != "OBSLTE" && attr != "TITLE" && attr != "SPLIT" && attr != "CAVEAT" && attr != "COMPND" && attr != "SOURCE" && attr != "KEYWDS" && attr != "EXPDTA" && attr != "NUMMDL" && attr != "MDLTYP" && attr != "AUTHOR" && attr != "REVDAT" && attr != "SPRSDE" && attr != "JRNL" && attr != "REMARK" && attr != "DBREF" && attr != "DBREF1" && attr != "DBREF2" && attr != "SEQADV" && attr != "SEQRES" && attr != "MODRES" && attr != "HET" && attr != "HETNAM" && attr != "HETSYN" && attr != "FORMUL" && attr != "HELIX" && attr != "SHEET" && attr != "SSBOND" && attr != "LINK" && attr != "CISPEP" && attr != "SITE" && attr != "ORIGX1" && attr != "ORIGX2" && attr != "ORIGX3" && attr != "SCALE1" && attr != "SCALE2" && attr != "SCALE3" && attr != "MATRIX1" && attr != "MATRIX2" && attr != "MATRIX3" && attr != "MODEL") continue; if (attr == "COMPND") compndWritten = true; if (attr == "AUTHOR") authorWritten = true; // compute spacing needed. HELIX, SITE, HET, ... are trimmed when reading int nSpacing = 6 - attr.size(); for (int i = 0; i < nSpacing; ++i) attr += " "; std::string lines = pd->GetValue(); string::size_type last = 0; string::size_type pos = lines.find('\n'); while (last != string::npos) { string line = lines.substr(last, pos - last); if (pos == string::npos) last = string::npos; else last = pos + 1; pos = lines.find('\n', last); ofs << attr << line << endl; } } if (!compndWritten) { if (strlen(mol.GetTitle()) > 0) snprintf(buffer, BUFF_SIZE, "COMPND %s ",mol.GetTitle()); else snprintf(buffer, BUFF_SIZE, "COMPND UNNAMED"); ofs << buffer << endl; } if (!authorWritten) { snprintf(buffer, BUFF_SIZE, "AUTHOR GENERATED BY OPEN BABEL %s",BABEL_VERSION); ofs << buffer << endl; } // Write CRYST1 record, containing unit cell parameters, space group // and Z value (supposed to be 1) if (pmol->HasData(OBGenericDataType::UnitCell)) { OBUnitCell *pUC = (OBUnitCell*)pmol->GetData(OBGenericDataType::UnitCell); if(pUC->GetSpaceGroup()){ string tmpHM=pUC->GetSpaceGroup()->GetHMName(); // Do we have an extended HM symbol, with origin choice as ":1" or ":2" ? If so, remove it. size_t n=tmpHM.find(":"); if(n!=string::npos) tmpHM=tmpHM.substr(0,n); snprintf(buffer, BUFF_SIZE, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s 1", pUC->GetA(), pUC->GetB(), pUC->GetC(), pUC->GetAlpha(), pUC->GetBeta(), pUC->GetGamma(), tmpHM.c_str()); } else snprintf(buffer, BUFF_SIZE, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s 1", pUC->GetA(), pUC->GetB(), pUC->GetC(), pUC->GetAlpha(), pUC->GetBeta(), pUC->GetGamma(), "P1"); ofs << buffer << endl; } // before we write any records, we should check to see if any coord < -1000 // which will cause errors in the formatting double minX, minY, minZ; minX = minY = minZ = -999.0f; FOR_ATOMS_OF_MOL(a, mol) { if (a->GetX() < minX) minX = a->GetX(); if (a->GetY() < minY) minY = a->GetY(); if (a->GetZ() < minZ) minZ = a->GetZ(); } vector3 transV = VZero; if (minX < -999.0) transV.SetX(-1.0*minX - 900.0); if (minY < -999.0) transV.SetY(-1.0*minY - 900.0); if (minZ < -999.0) transV.SetZ(-1.0*minZ - 900.0); // if minX, minY, or minZ was never changed, shift will be 0.0f // otherwise, move enough so that smallest coord is > -999.0f mol.Translate(transV); OBAtom *atom; OBResidue *res; for (i = 1; i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); strncpy(type_name, etab.GetSymbol(atom->GetAtomicNum()), sizeof(type_name)); type_name[sizeof(type_name) - 1] = '\0'; //two char. elements are on position 13 and 14 one char. start at 14 if (strlen(type_name) > 1) type_name[1] = toupper(type_name[1]); else { char tmp[10]; strncpy(tmp, type_name, 9); // make sure to null-terminate tmp snprintf(type_name, sizeof(type_name), " %-3s", tmp); } if ( (res = atom->GetResidue()) != 0 ) { het = res->IsHetAtom(atom); snprintf(the_res,4,"%s",(char*)res->GetName().c_str()); the_res[4] = '\0'; snprintf(type_name,5,"%s",(char*)res->GetAtomID(atom).c_str()); the_chain = res->GetChain(); //two char. elements are on position 13 and 14 one char. start at 14 if (strlen(etab.GetSymbol(atom->GetAtomicNum())) == 1) { if (strlen(type_name) < 4) { char tmp[10]; strncpy(tmp, type_name, 9); // make sure to null-terminate tmp snprintf(padded_name, sizeof(padded_name), " %-3s", tmp); strncpy(type_name,padded_name,4); type_name[4] = '\0'; } else { /* type_name[4] = type_name[3]; type_name[3] = type_name[2]; type_name[2] = type_name[1]; type_name[1] = type_name[0]; type_name[0] = type_name[4]; */ type_name[4] = '\0'; } } res_num = res->GetNum(); } else { strcpy(the_res,"UNK"); the_res[3] = '\0'; snprintf(padded_name,sizeof(padded_name), "%s",type_name); strncpy(type_name,padded_name,4); type_name[4] = '\0'; res_num = 1; } element_name = etab.GetSymbol(atom->GetAtomicNum()); int charge = atom->GetFormalCharge(); char scharge[3] = { ' ', ' ', '\0' }; if(0 != charge) { snprintf(scharge, 3, "%+d", charge); char tmp = scharge[1]; scharge[1] = scharge[0]; scharge[0] = tmp; } snprintf(buffer, BUFF_SIZE, "%s%5d %-4s %-3s %c%4d %8.3f%8.3f%8.3f 1.00 0.00 %2s%2s\n", het?"HETATM":"ATOM ", i, type_name, the_res, the_chain, res_num, atom->GetX(), atom->GetY(), atom->GetZ(), element_name, scharge); ofs << buffer; } OBAtom *nbr; vector<OBBond*>::iterator k; for (i = 1; i <= mol.NumAtoms(); i ++) { atom = mol.GetAtom(i); if (atom->GetValence() == 0) continue; // no need to write a CONECT record -- no bonds snprintf(buffer, BUFF_SIZE, "CONECT%5d", i); ofs << buffer; // Write out up to 4 real bonds per line PR#1711154 int currentValence = 0; for (nbr = atom->BeginNbrAtom(k);nbr;nbr = atom->NextNbrAtom(k)) { snprintf(buffer, BUFF_SIZE, "%5d", nbr->GetIdx()); ofs << buffer; if (++currentValence % 4 == 0) { // Add the trailing space to finish this record ofs << " \n"; // write the start of a new CONECT record snprintf(buffer, BUFF_SIZE, "CONECT%5d", i); ofs << buffer; } } // Add trailing spaces int remainingValence = atom->GetValence() % 4; for (int count = 0; count < (4 - remainingValence); count++) { snprintf(buffer, BUFF_SIZE, " "); ofs << buffer; } ofs << " \n"; } snprintf(buffer, BUFF_SIZE, "MASTER 0 0 0 0 0 0 0 0 "); ofs << buffer; snprintf(buffer, BUFF_SIZE, "%4d 0 %4d 0\n",mol.NumAtoms(),mol.NumAtoms()); ofs << buffer; ofs << "END\n"; if (model_num) { ofs << "ENDMDL" << endl; } return(true); }
bool PDBFormat::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; unsigned int i; char buffer[BUFF_SIZE]; char type_name[10], padded_name[10]; char the_res[10]; char the_chain = ' '; const char *element_name; int res_num; bool het=true; int model_num = 0; if (!pConv->IsLast() || pConv->GetOutputIndex() > 1) { // More than one molecule record model_num = pConv->GetOutputIndex(); // MODEL 1-based index snprintf(buffer, BUFF_SIZE, "MODEL %8d", model_num); ofs << buffer << endl; } if (strlen(mol.GetTitle()) > 0) snprintf(buffer, BUFF_SIZE, "COMPND %s ",mol.GetTitle()); else snprintf(buffer, BUFF_SIZE, "COMPND UNNAMED"); ofs << buffer << endl; snprintf(buffer, BUFF_SIZE, "AUTHOR GENERATED BY OPEN BABEL %s",BABEL_VERSION); ofs << buffer << endl; // Write CRYST1 record, containing unit cell parameters, space group // and Z value (supposed to be 1) if (pmol->HasData(OBGenericDataType::UnitCell)) { OBUnitCell *pUC = (OBUnitCell*)pmol->GetData(OBGenericDataType::UnitCell); snprintf(buffer, BUFF_SIZE, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s 1", pUC->GetA(), pUC->GetB(), pUC->GetC(), pUC->GetAlpha(), pUC->GetBeta(), pUC->GetGamma(), pUC->GetSpaceGroup() ? pUC->GetSpaceGroup()->GetHMName().c_str() : "P1"); ofs << buffer << endl; } // before we write any records, we should check to see if any coord < -1000 // which will cause errors in the formatting double minX, minY, minZ; minX = minY = minZ = -999.0f; FOR_ATOMS_OF_MOL(a, mol) { if (a->GetX() < minX) minX = a->GetX(); if (a->GetY() < minY) minY = a->GetY(); if (a->GetZ() < minZ) minZ = a->GetZ(); } vector3 transV = VZero; if (minX < -999.0) transV.SetX(-1.0*minX - 900.0); if (minY < -999.0) transV.SetY(-1.0*minY - 900.0); if (minZ < -999.0) transV.SetZ(-1.0*minZ - 900.0); // if minX, minY, or minZ was never changed, shift will be 0.0f // otherwise, move enough so that smallest coord is > -999.0f mol.Translate(transV); OBAtom *atom; OBResidue *res; for (i = 1; i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); strncpy(type_name, etab.GetSymbol(atom->GetAtomicNum()), sizeof(type_name)); type_name[sizeof(type_name) - 1] = '\0'; //two char. elements are on position 13 and 14 one char. start at 14 if (strlen(type_name) > 1) type_name[1] = toupper(type_name[1]); else { char tmp[10]; strncpy(tmp, type_name, 10); snprintf(type_name, sizeof(type_name), " %-3s", tmp); } if ( (res = atom->GetResidue()) != 0 ) { het = res->IsHetAtom(atom); snprintf(the_res,4,"%s",(char*)res->GetName().c_str()); snprintf(type_name,5,"%s",(char*)res->GetAtomID(atom).c_str()); the_chain = res->GetChain(); //two char. elements are on position 13 and 14 one char. start at 14 if (strlen(etab.GetSymbol(atom->GetAtomicNum())) == 1) { if (strlen(type_name) < 4) { char tmp[16]; strncpy(tmp, type_name, 16); snprintf(padded_name, sizeof(padded_name), " %-3s", tmp); strncpy(type_name,padded_name,4); type_name[4] = '\0'; } else { /* type_name[4] = type_name[3]; type_name[3] = type_name[2]; type_name[2] = type_name[1]; type_name[1] = type_name[0]; type_name[0] = type_name[4]; */ type_name[4] = '\0'; } } res_num = res->GetNum(); } else { strcpy(the_res,"UNK"); snprintf(padded_name,sizeof(padded_name), "%s",type_name); strncpy(type_name,padded_name,4); type_name[4] = '\0'; res_num = 1; } element_name = etab.GetSymbol(atom->GetAtomicNum()); int charge = atom->GetFormalCharge(); char scharge[3] = { ' ', ' ', '\0' }; if(0 != charge) { snprintf(scharge, 3, "%+d", charge); char tmp = scharge[1]; scharge[1] = scharge[0]; scharge[0] = tmp; } snprintf(buffer, BUFF_SIZE, "%s%5d %-4s %-3s %c%4d %8.3f%8.3f%8.3f 1.00 0.00 %2s%2s\n", het?"HETATM":"ATOM ", i, type_name, the_res, the_chain, res_num, atom->GetX(), atom->GetY(), atom->GetZ(), element_name, scharge); ofs << buffer; } OBAtom *nbr; vector<OBBond*>::iterator k; for (i = 1; i <= mol.NumAtoms(); i ++) { atom = mol.GetAtom(i); if (atom->GetValence() == 0) continue; // no need to write a CONECT record -- no bonds snprintf(buffer, BUFF_SIZE, "CONECT%5d", i); ofs << buffer; // Write out up to 4 real bonds per line PR#1711154 unsigned int currentValence = 0; for (nbr = atom->BeginNbrAtom(k);nbr;nbr = atom->NextNbrAtom(k)) { unsigned int order = mol.GetBond(atom, nbr)->GetBondOrder(); unsigned int it_order = 0; for( it_order = 0; it_order < order; it_order++ ) { if (0 != currentValence && 0 == currentValence % 4) { // Add the trailing space to finish this record ofs << " \n"; // write the start of a new CONECT record snprintf(buffer, BUFF_SIZE, "CONECT%5d", i); ofs << buffer; } currentValence++; snprintf(buffer, BUFF_SIZE, "%5d", nbr->GetIdx()); ofs << buffer; } } // Add trailing spaces unsigned int remainingValence = currentValence % 4; if( 0 < remainingValence ) { for (int count = 0; count < (4 - remainingValence); count++) { snprintf(buffer, BUFF_SIZE, " "); ofs << buffer; } } ofs << " \n"; } snprintf(buffer, BUFF_SIZE, "MASTER 0 0 0 0 0 0 0 0 "); ofs << buffer; snprintf(buffer, BUFF_SIZE, "%4d 0 %4d 0\n",mol.NumAtoms(),mol.NumAtoms()); ofs << buffer; ofs << "END\n"; if (model_num) { ofs << "ENDMDL" << endl; } return(true); }
bool HINFormat::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; unsigned int i, file_num = 1; string str,str1; char buffer[BUFF_SIZE]; OBAtom *atom; OBBond *bond; vector<OBBond*>::iterator j; char bond_char; // make sure to escape titles in double quotes // PR#1501694 ofs << "mol " << file_num << " \"" << mol.GetTitle() << "\"\n"; for(i = 1;i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); snprintf(buffer, BUFF_SIZE, "atom %d - %-3s ** - %8.5f %8.5f %8.5f %8.5f %d ", i, etab.GetSymbol(atom->GetAtomicNum()), atom->GetPartialCharge(), atom->GetX(), atom->GetY(), atom->GetZ(), atom->GetValence()); ofs << buffer; for (bond = atom->BeginBond(j); bond; bond = atom->NextBond(j)) { switch(bond->GetBO()) { case 1 : bond_char = 's'; break; case 2 : bond_char = 'd'; break; case 3 : bond_char = 't'; break; case 5 : bond_char = 'a'; break; default: bond_char = 's'; break; } if (bond->IsAromatic()) bond_char = 'a'; snprintf(buffer,BUFF_SIZE, "%d %c ", (bond->GetNbrAtom(atom))->GetIdx(), bond_char); ofs << buffer; } ofs << endl; } ofs << "endmol " << file_num << 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 AlchemyFormat::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; unsigned int i; char buffer[BUFF_SIZE]; char bond_string[10]; snprintf(buffer, BUFF_SIZE, "%5d ATOMS, %5d BONDS, 0 CHARGES", mol.NumAtoms(), mol.NumBonds()); ofs << buffer << endl; OBAtom *atom; string str,str1; for(i = 1;i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); str = atom->GetType(); ttab.SetFromType("INT"); ttab.SetToType("ALC"); ttab.Translate(str1,str); snprintf(buffer, BUFF_SIZE, "%5d %-6s%8.4f %8.4f %8.4f 0.0000", i, (char*)str1.c_str(), atom->GetX(), atom->GetY(), atom->GetZ()); ofs << buffer << endl; } OBBond *bond; vector<OBBond*>::iterator j; for (bond = mol.BeginBond(j);bond;bond = mol.NextBond(j)) { switch(bond->GetBO()) { case 1 : strcpy(bond_string,"SINGLE"); break; case 2 : strcpy(bond_string,"DOUBLE"); break; case 3 : strcpy(bond_string,"TRIPLE"); break; case 5 : strcpy(bond_string,"AROMATIC"); break; default : strcpy(bond_string,"SINGLE"); } snprintf(buffer, BUFF_SIZE, "%5d %4d %4d %s", bond->GetIdx()+1, bond->GetBeginAtomIdx(), bond->GetEndAtomIdx(), bond_string); ofs << buffer << endl; } return(true); }
bool ZINDOFormat::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; char buffer[BUFF_SIZE]; int orbitals, valenceE = 0; vector<OBAtom*>::iterator i; OBAtom *atom; bool charged = false; for (atom = mol.BeginAtom(i); atom; atom = mol.NextAtom(i)) { switch (atom->GetAtomicNum()) { case 1: valenceE += 1; break; case 5: case 13: valenceE += 3; break; case 6: case 14: valenceE += 4; break; case 7: case 15: case 33: valenceE += 5; break; case 8: case 16: case 34: valenceE += 6; break; case 9: case 17: case 35: valenceE += 7; break; default: break; } } orbitals = valenceE / 2; if (charged) { orbitals = (valenceE / 2) - 1; valenceE -= 1; } ofs << " $TITLEI" << endl; ofs << endl; ofs << " " << mol.GetTitle() << endl; ofs << endl; ofs << " $END" << endl; ofs << endl; ofs << " $CONTRL" << endl; ofs << endl; if (charged) ofs << " SCFTYP ROHF RUNTYP CI ENTTYP COORD" << endl; else ofs << " SCFTYP RHF RUNTYP CI ENTTYP COORD" << endl; ofs << " UNITS ANGS INTTYP 1 IAPX 3" << endl; if (charged) { ofs << endl; ofs << " NOP = 1 " << endl; ofs << " NDT = 1 " << endl; snprintf(buffer, BUFF_SIZE, " FOP(1) =% 4d% 10.6f", valenceE - 1, 1.0); ofs << buffer << endl; } snprintf(buffer, BUFF_SIZE, " NAT %4d NEL %4d MULT 1", mol.NumAtoms(), valenceE); ofs << buffer << endl; ofs << " IPRINT -1 ITMAX 100" << endl; ofs << endl; ofs << "! ***** BASIS SET AND C. I. SIZE INFORMATION ***** " << endl; ofs << endl; snprintf(buffer, BUFF_SIZE, " DYNAL(1) = 0%5d%5d 0 0 1200%5d", mol.NumAtoms() - mol.NumHvyAtoms(), mol.NumHvyAtoms(), orbitals + 25); ofs << buffer << endl; ofs << endl; ofs << " INTFA(1) = 1.000000 1.267000 0.680000 1.000000 1.000000 " << endl; ofs << endl; ofs << "! ***** OUTPUT FILE NAME ***** " << endl; ofs << endl; ofs << " ONAME = zindo " << endl; ofs << endl; ofs << " $END" << endl; ofs << endl; ofs << " $DATAIN " << endl; ofs << endl; for (atom = mol.BeginAtom(i); atom; atom = mol.NextAtom(i)) { snprintf(buffer, BUFF_SIZE, "% 10.6f% 10.6f% 10.6f%5d", atom->GetX(), atom->GetY(), atom->GetZ(), atom->GetAtomicNum()); ofs << buffer << endl; } ofs << endl; ofs << " $END " << endl; ofs << endl; ofs << " $CIINPU" << endl; ofs << endl; ofs << "! ***** C. I. SPECIFICATION *****" << endl; ofs << endl; ofs << " 2 1 25 1 0 0 0 1 10 1 10" << endl; ofs << " -60000.0 0.0000000" << endl; ofs << endl; if (charged) snprintf(buffer, BUFF_SIZE, "%5d%5d%5d%5d", 1, orbitals, orbitals, orbitals + 1); else snprintf(buffer, BUFF_SIZE, "%5d%5d%5d", 1, orbitals, orbitals); ofs << buffer << endl; if (charged) snprintf(buffer, BUFF_SIZE, "%5d%5d%5d%5d%5d", 21, (orbitals - 8), orbitals + 1, orbitals + 1, orbitals + 11); else snprintf(buffer, BUFF_SIZE, "%5d%5d%5d%5d%5d", 21, (orbitals - 9), orbitals, orbitals + 1, orbitals + 10); ofs << buffer << endl; ofs << endl; ofs << " $END" << endl; return(true); }
NXSGOpenGLNode* NXOpenGLRenderingEngine::createOpenGLSceneGraph(OBMol *const molPtr) { assert(!molPtr->Empty()); #if 0 /// @todo Post-FNANO08 (Dna rendering) /// @fixme r1.0.0 hacks // -- begin hacks -- if(inDnaGroup && inDnaSegment) { NXSGOpenGLNode *molSceneGraphNode = createOpenGLDnaSegmentSceneGraph(molPtr); if(molSceneGraphNode != NULL) return molSceneGraphNode; } else if(inDnaGroup && inDnaStrand) { NXSGOpenGLNode *molSceneGraphNode = createOpenGLDnaStrandSceneGraph(molPtr); if(molSceneGraphNode != NULL) return molSceneGraphNode; } // -- end hacks -- #endif Vector const canonicalZAxis(0.0, 0.0, 1.0); OBAtomIterator atomIter; // Find first atom that is not already rendered // Necessary because bonds can bridge molecules and molecule-sets and in // the case of the second to last molecules rendered, their first atoms // may have been rendered while traversing the previous molecules. OBAtom *firstAtomPtr = molPtr->BeginAtom(atomIter); if(firstAtomPtr == (OBAtom*) NULL) { string const source("Molecule scenegraph creation"); string const msg("empty molecule slipped past check"); SetResult(commandResult, NX_INTERNAL_ERROR, source + " - " + msg); NX_DEBUG_FAIL; return (NXSGOpenGLNode*) NULL; } while(firstAtomPtr != (OBAtom*) NULL && isRendered(firstAtomPtr)) firstAtomPtr = molPtr->NextAtom(atomIter); if(firstAtomPtr == (OBAtom*) NULL) { NXSGOpenGLNode *nullFirstAtomNode = new NXSGOpenGLNode; SET_SCENEGRAPH_NAME(nullFirstAtomNode, "Null_first_atom"); return nullFirstAtomNode; } Vector const firstAtomPosition(firstAtomPtr->GetX(), firstAtomPtr->GetY(), firstAtomPtr->GetZ()); NXSGOpenGLTranslate *rootMoleculeNode = NULL; try { rootMoleculeNode = new NXSGOpenGLTranslate(firstAtomPosition.x(), firstAtomPosition.y(), firstAtomPosition.z()); SET_SCENEGRAPH_NAME(rootMoleculeNode, "First_atom_position"); } catch(...) { if(rootMoleculeNode != NULL) delete rootMoleculeNode; rootMoleculeNode = NULL; SetResult(commandResult, NX_INTERNAL_ERROR, "Error translating to first atom position"); NX_DEBUG_FAIL; return NULL; } NXSGOpenGLNode *firstAtomNode = createOpenGLSceneGraph(molPtr, firstAtomPtr, canonicalZAxis); if(firstAtomNode != NULL && commandResult.getResult() == (int) NX_CMD_SUCCESS) { // submolecule scenegraph created completely and successfully bool childAdded = rootMoleculeNode->addChild(firstAtomNode); if(!childAdded) { SetResult(commandResult, NX_INTERNAL_ERROR, "Error adding child to first atom node"); NX_DEBUG_FAIL; return rootMoleculeNode; } } else { NX_DEBUG_FAIL; // either scenegraph could not be created or was created partially // commandResult should hold the error return rootMoleculeNode; } /// @todo POST-FNANO delete firstAtomNode upon failures? // rest of the atoms OBAtom *atomPtr = molPtr->NextAtom(atomIter); for(; atomPtr != (OBAtom*) NULL; atomPtr = molPtr->NextAtom(atomIter)) { if(isRendered(atomPtr)) // atom already rendered continue; Vector const atomPosition(atomPtr->GetX(), atomPtr->GetY(), atomPtr->GetZ()); Vector const atomRelativePosition = (atomPosition - firstAtomPosition); // move scenegraph "cursor" to this atom NXSGOpenGLTranslate *translateToAtomNode = NULL; try { translateToAtomNode = new NXSGOpenGLTranslate(atomRelativePosition.x(), atomRelativePosition.y(), atomRelativePosition.z()); SET_SCENEGRAPH_NAME(translateToAtomNode, "Translate_to_" + get_atom_scenegraph_name(atomPtr)); } catch(...) { if(translateToAtomNode != NULL) delete translateToAtomNode; SetResult(commandResult, NX_INTERNAL_ERROR, "Error translating to atom"); NX_DEBUG_FAIL; return rootMoleculeNode; } bool childAdded = rootMoleculeNode->addChild(translateToAtomNode); if(!childAdded) { SetResult(commandResult, NX_INTERNAL_ERROR, "Error adding translate-to-atom node to molecule root"); NX_DEBUG_FAIL; return rootMoleculeNode; } /// @todo POST-FNANO delete translateToAtomNode upon failure? // render subscenegraph rooted at this atom NXSGOpenGLNode *atomNode = createOpenGLSceneGraph(molPtr, atomPtr, canonicalZAxis); if(atomNode != NULL && commandResult.getResult() == (int) NX_CMD_SUCCESS) { bool childAdded = translateToAtomNode->addChild(atomNode); if(!childAdded) { SetResult(commandResult, NX_INTERNAL_ERROR, "Error submolecule scenegraph as child of " "translation"); NX_DEBUG_FAIL; return rootMoleculeNode; } } else { NX_DEBUG_FAIL; return rootMoleculeNode; } /// @todo POST-FNANO delete atomNode upon failures? } // loop over atoms return rootMoleculeNode; }
bool MOL2Format::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 ligandsOnly = pConv->IsOption("l", OBConversion::OUTOPTIONS)!=NULL; //The old code follows.... string str,str1; char buffer[BUFF_SIZE],label[BUFF_SIZE]; char rnum[BUFF_SIZE],rlabel[BUFF_SIZE]; ofs << "@<TRIPOS>MOLECULE" << endl; str = mol.GetTitle(); if (str.empty()) ofs << "*****" << endl; else ofs << str << endl; snprintf(buffer, BUFF_SIZE," %d %d 0 0 0", mol.NumAtoms(),mol.NumBonds()); ofs << buffer << endl; ofs << "SMALL" << endl; OBPairData *dp = (OBPairData*)mol.GetData("PartialCharges"); if (dp != NULL) { // Tripos spec says: // NO_CHARGES, DEL_RE, GASTEIGER, GAST_HUCK, HUCKEL, PULLMAN, // GAUSS80_CHARGES, AMPAC_CHARGES, MULLIKEN_CHARGES, DICT_ CHARGES, // MMFF94_CHARGES, USER_CHARGES if (dp->GetValue() == "Mulliken") ofs << "MULLIKEN_CHARGES" << endl; else // should pick from the Tripos types ofs << "GASTEIGER" << endl; } else { // No idea what these charges are... all our code sets "PartialCharges" ofs << "GASTEIGER" << endl; } ofs << "Energy = " << mol.GetEnergy() << endl; if (mol.HasData(OBGenericDataType::CommentData)) { OBCommentData *cd = (OBCommentData*)mol.GetData(OBGenericDataType::CommentData); ofs << cd->GetData(); } ofs << endl; ofs << "@<TRIPOS>ATOM" << endl; OBAtom *atom; OBResidue *res; vector<OBAtom*>::iterator i; vector<int> labelcount; labelcount.resize( etab.GetNumberOfElements() ); ttab.SetFromType("INT"); ttab.SetToType("SYB"); for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) { // // Use sequentially numbered atom names if no residues // snprintf(label,BUFF_SIZE, "%s%d", etab.GetSymbol(atom->GetAtomicNum()), ++labelcount[atom->GetAtomicNum()]); strcpy(rlabel,"<1>"); strcpy(rnum,"1"); str = atom->GetType(); ttab.Translate(str1,str); // // Use original atom names if there are residues // if (!ligandsOnly && (res = atom->GetResidue()) ) { // use original atom names defined by residue snprintf(label,BUFF_SIZE,"%s",(char*)res->GetAtomID(atom).c_str()); // make sure that residue name includes its number snprintf(rlabel,BUFF_SIZE,"%s%d",res->GetName().c_str(), res->GetNum()); snprintf(rnum,BUFF_SIZE,"%d",res->GetNum()); } snprintf(buffer,BUFF_SIZE,"%7d%1s%-6s%12.4f%10.4f%10.4f%1s%-5s%4s%1s %-8s%10.4f", atom->GetIdx(),"",label, atom->GetX(),atom->GetY(),atom->GetZ(), "",str1.c_str(), rnum,"",rlabel, atom->GetPartialCharge()); ofs << buffer << endl; } ofs << "@<TRIPOS>BOND" << endl; OBBond *bond; vector<OBBond*>::iterator j; OBSmartsPattern pat; string s1, s2; for (bond = mol.BeginBond(j);bond;bond = mol.NextBond(j)) { s1 = bond->GetBeginAtom()->GetType(); s2 = bond->GetEndAtom()->GetType(); if (bond->IsAromatic() || s1 == "O.co2" || s2 == "O.co2") strcpy(label,"ar"); else if (bond->IsAmide()) strcpy(label,"am"); else snprintf(label,BUFF_SIZE,"%d",bond->GetBO()); snprintf(buffer, BUFF_SIZE,"%6d%6d%6d%3s%2s", bond->GetIdx()+1,bond->GetBeginAtomIdx(),bond->GetEndAtomIdx(), "",label); ofs << buffer << endl; } // NO trailing blank line (PR#1868929). // ofs << endl; return(true); }
bool BGFFormat::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; vector<OBAtom*>::iterator i; int max_val; OBAtom *atom; char buffer[BUFF_SIZE]; char elmnt_typ[8], dreid_typ[8], atm_sym[16], max_val_str[8]; mol.Kekulize(); ofs << "BIOGRF 200\n"; snprintf(buffer, BUFF_SIZE, "DESCRP %s\n",mol.GetTitle()); ofs << buffer; snprintf(buffer, BUFF_SIZE, "REMARK BGF file created by Open Babel %s\n",BABEL_VERSION); ofs << "FORCEFIELD DREIDING \n"; // write unit cell if available if (mol.HasData(OBGenericDataType::UnitCell)) { OBUnitCell *uc = (OBUnitCell*)mol.GetData(OBGenericDataType::UnitCell); // e.g. CRYSTX 49.30287 49.23010 25.45631 90.00008 89.99995 57.10041 snprintf(buffer, BUFF_SIZE, "CRYSTX%12.5f%12.5f%12.5f%12.5f%12.5f%12.5f", uc->GetA(), uc->GetB(), uc->GetC(), uc->GetAlpha() , uc->GetBeta(), uc->GetGamma()); ofs << buffer << "\n"; } ofs << "FORMAT ATOM (a6,1x,i5,1x,a5,1x,a3,1x,a1,1x,a5,3f10.5,1x,a5,i3,i2,1x,f8.5)\n"; ttab.SetFromType("INT"); for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) { strncpy(elmnt_typ,etab.GetSymbol(atom->GetAtomicNum()), 7); // make sure to null-terminate elmnt_typ[sizeof(elmnt_typ) - 1] = '0'; ToUpper(elmnt_typ); ttab.SetToType("DRE"); ttab.Translate(dreid_typ,atom->GetType()); ttab.SetToType("HAD"); ttab.Translate(max_val_str,atom->GetType()); max_val = atoi(max_val_str); if (max_val == 0) max_val = 1; snprintf(atm_sym,16,"%s%d",elmnt_typ,atom->GetIdx()); snprintf(buffer,BUFF_SIZE,"%6s %5d %-5s %3s %1s %5s%10.5f%10.5f%10.5f %-5s%3d%2d %8.5f\n", "HETATM", atom->GetIdx(), atm_sym, "RES", "A", "444", atom->GetX(), atom->GetY(), atom->GetZ(), dreid_typ, max_val, 0, atom->GetPartialCharge()); ofs << buffer; } ofs<< "FORMAT CONECT (a6,12i6)\n\n"; OBAtom *nbr; vector<OBBond*>::iterator j; for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) if (atom->GetValence()) { snprintf(buffer,BUFF_SIZE,"CONECT%6d",atom->GetIdx()); ofs << buffer; for (nbr = atom->BeginNbrAtom(j);nbr;nbr = atom->NextNbrAtom(j)) { snprintf(buffer,BUFF_SIZE,"%6d",nbr->GetIdx()); ofs << buffer; } ofs << endl; snprintf(buffer,BUFF_SIZE,"ORDER %6d",atom->GetIdx()); ofs << buffer; for (nbr = atom->BeginNbrAtom(j);nbr;nbr = atom->NextNbrAtom(j)) { snprintf(buffer,BUFF_SIZE,"%6d",(*j)->GetBO()); ofs << buffer; } ofs << endl; } ofs << "END" << endl; return(true); }