bool MolSurfBuilder::init(MolCoordPtr pmol) { AtomIterator aiter(pmol); int i, natoms=0; // count atom number for (aiter.first(); aiter.hasMore(); aiter.next()) { MolAtomPtr pAtom = aiter.get(); MB_ASSERT(!pAtom.isnull()); ++natoms; } // copy to the m_data m_data.resize(natoms); m_tree.alloc(natoms); for (i=0,aiter.first(); aiter.hasMore()&&i<natoms; aiter.next(),++i) { MolAtomPtr pAtom = aiter.get(); m_data[i].pos = pAtom->getPos(); m_data[i].rad = 1.5; m_data[i].aid = pAtom->getID(); m_tree.setAt(i, m_data[i].pos, i); } // build BSP tree m_tree.build(); m_rmax = 1.5; m_rprobe = 1.2; return true; }
double TopparManager::getVdwRadius(MolAtomPtr pAtom, bool bExplH) { LString resn = pAtom->getResName(); TopoDB *pDB = getTopoDB(); // Resolve alias name ResiToppar *pTop = pDB->get(resn); if (pTop==NULL) return elemBasedVdw(pAtom->getElement()); LString aname = pAtom->getName(); TopAtom *pTA = pTop->getAtom(aname); if (pTA==NULL) return elemBasedVdw(pAtom->getElement()); LString atype = pTA->type; ParamDB *pPDB = getParamDB(); param::AtomVal *pPA = pPDB->getAtom(atype); if (pPA==NULL) return elemBasedVdw(pAtom->getElement()); if (bExplH) return pPA->vdwr; if (pPA->vdwhr > 0.0) return pPA->vdwhr; return pPA->vdwr; }
static void drawSelInterAtomLine(MolAtomPtr pAtom1, MolAtomPtr pAtom2, DisplayContext *pdl) { if (pAtom1.isnull() || pAtom2.isnull()) return; pdl->vertex(pAtom1->getPos()); pdl->vertex(pAtom2->getPos()); }
void BallStickRenderer::rendAtom(DisplayContext *pdl, MolAtomPtr pAtom, bool) { if (m_sphr>0.0) { pdl->color(ColSchmHolder::getColor(pAtom)); pdl->sphere(m_sphr, pAtom->getPos()); } checkRing(pAtom->getID()); }
bool TopparManager::getCharge(MolAtomPtr pAtom, bool bExplH, const LString &ns, double &rval) { LString resn = pAtom->getResName(); TopoDB *pDB = getTopoDB(); // Resolve alias name ResiToppar *pTop = pDB->get(resn); if (pTop==NULL) return false; LString aname = pAtom->getName(); return getChargeImpl(pTop, aname, ns, bExplH, rval); /* LString ns_aname = aname; if (!ns.isEmpty()) ns_aname = ns + ":" + aname; TopAtom *pTA = pTop->getAtom(ns_aname); if (pTA==NULL) return false; if (bExplH) { rval = pTA->charge; return true; } double prot_chg = 0.0; ResiToppar::BondList *pBL= pTop->getBondList(); BOOST_FOREACH (const TopBond *pBond, *pBL) { if (pBond->a1==pTA) { if (pBond->a2->elem.equals("H")) prot_chg += pBond->a2->charge; } else if (pBond->a2==pTA) { if (pBond->a1->elem.equals("H")) prot_chg += pBond->a1->charge; } } rval = pTA->charge + prot_chg; return true; */ }
void SimpleRenderer::drawAtom(MolAtomPtr pAtom, DisplayContext *pdl) { pdl->color(ColSchmHolder::getColor(pAtom)); const Vector4D pos = pAtom->getPos(); const double rad = 0.25; pdl->drawAster(pos, rad); ++m_nAtomDrawn; }
/// Convert from (persistent) string representation to aid int MolCoord::fromStrAID(const LString &strid) const { if (!m_reAid.match(strid)) { LOG_DPRINTLN("MolCoord> Invalid aid strid=%s (re match failed)", strid.c_str()); return -1; } // text type aid int nsc = m_reAid.getSubstrCount(); if (nsc<4) { LOG_DPRINTLN("MolCoord> Invalid aid strid=%s", strid.c_str()); return -1; } //elem.setAtomID(-1); LString sChainName = m_reAid.getSubstr(1); LString sResInd = m_reAid.getSubstr(2); ResidIndex nResInd; if (!sResInd.toInt(&nResInd.first)) { LOG_DPRINTLN("MolCoord> Invalid aid resid value=%s", sResInd.c_str()); return -1; } LString sInsCode = m_reAid.getSubstr(3); if (sInsCode.isEmpty()) nResInd.second = '\0'; else nResInd.second = sInsCode.getAt(0); LString sAtomName = m_reAid.getSubstr(4); char cAltLoc = '\0'; if (nsc>6) { LString sAltLoc = m_reAid.getSubstr(6); if (!sAltLoc.isEmpty()) cAltLoc = sAltLoc.getAt(0); } MolAtomPtr pAtom = getAtom(sChainName, nResInd, sAtomName, cAltLoc); if (pAtom.isnull()) { LOG_DPRINTLN("MolCoord> fromStrAID/ atom <%s %s %s %c> not found in %s", sChainName.c_str(), nResInd.toString().c_str(), sAtomName.c_str(), cAltLoc=='\0'?' ':cAltLoc, getName().c_str()); return -1; } return pAtom->getID(); }
void TubeRenderer::beginRend(DisplayContext *pdl) { if (!m_pts->isValid()) m_pts->setupSectionTable(); super_t::beginRend(pdl); if (m_nPuttyMode==TBR_PUTTY_OFF) { return; } // calc max bfac/occ in the putty mode SelectionPtr pSel; MolCoordPtr pMol = getClientMol(); //MolRenderer *pMolRend = dynamic_cast<MolRenderer *>(pRend); //if (pMolRend!=NULL && m_nAuto==BFA_REND) pSel = getSelection(); double dmin = 1.0e100, dmax = -1.0e100, val, dsum = 0.0; int nadd=0; ResidIterator iter(pMol, pSel); for (iter.first(); iter.hasMore(); iter.next()) { MolResiduePtr pRes = iter.get(); MolAtomPtr pAtom = getPivotAtom(pRes); if (pAtom.isnull()) continue; if (m_nPuttyMode==TBR_PUTTY_OCC) val = pAtom->getOcc(); else val = pAtom->getBfac(); dsum += val; dmin = qlib::min(dmin, val); dmax = qlib::max(dmax, val); ++nadd; } m_dParHi = dmax; m_dParLo = dmin; m_dParAver = dsum/double(nadd); MB_DPRINTLN("Tube> init high=%f, low=%f, aver=%f OK.", dmax, dmin, m_dParAver); }
void MolArrayMap::setup(MolCoordPtr pRefMol) { m_data.erase(m_data.begin(), m_data.end()); int i = 0; AtomIterator iter(pRefMol); for (iter.first(); iter.hasMore(); iter.next(), ++i) { MolAtomPtr pa = iter.get(); MolArrayMapElem a; a.chain = pa->getChainName().c_str(); a.resid = pa->getResIndex().toInt(); a.atom = pa->getName().c_str(); a.pA = pa; m_data.insert(data_t::value_type(a, -1)); //MB_DPRINTLN("fitref %s %d %s", a.chain.c_str(), a.resid, a.atom.c_str()); } setupIndex(); }
bool BfacColoring::init(MolCoordPtr pMol, Renderer *pRend) { if (m_nMode!=BFC_CENTER && !isAutoMode()) return true; m_parAutoLo = m_parAutoHi = 0.0; // MolCoordPtr pMol(pRend->getClientObj(), qlib::no_throw_tag()); if (pMol.isnull()) { return false; } if (m_nMode==BFC_CENTER) { m_vCenter = pMol->getCenterPos(false); if (!isAutoMode()) return true; } SelectionPtr pSel; MolRenderer *pMolRend = dynamic_cast<MolRenderer *>(pRend); if (pMolRend!=NULL && m_nAuto==BFA_REND) pSel = pMolRend->getSelection(); { double dmin = 1.0e100, dmax = -1.0e100, val; AtomIterator iter(pMol, pSel); for (iter.first(); iter.hasMore(); iter.next()) { MolAtomPtr pAtom = iter.get(); if (m_nMode==BFC_OCC) val = pAtom->getOcc(); else if (m_nMode==BFC_CENTER) val = (pAtom->getPos()-m_vCenter).length(); else val = pAtom->getBfac(); dmin = qlib::min(dmin, val); dmax = qlib::max(dmax, val); } MB_DPRINTLN("BfaxColoring> init high=%f, low=%f, OK.", dmax, dmin); m_parAutoHi = dmax; m_parAutoLo = dmin; } return true; }
void SelectionRenderer::rendAtom(DisplayContext *pdl, MolAtomPtr pAtom, bool fbonded) { if (m_nMode==0) { if (!fbonded) drawSelAtom(pAtom, pdl); } else { pdl->vertex(pAtom->getPos()); //Vector4D pos = pAtom->getPos(); //pdl->drawPixels(pos, m_boximg, *(m_color.get())); } }
int MolCoord::appendAtomScrHelper(MolAtomPtr pAtom, const LString &ch, ResidIndex resid, const LString &resn) { qlib::uid_t nuid = pAtom->getParentUID(); if (nuid!=qlib::invalid_uid) { // pAtom has been already belonged to other mol // --> ERROR!! MB_DPRINTLN("MolCoord.appendAtom> ERROR, pAtom already belongs to mol %d ().", nuid); return -1; } pAtom->setParentUID(getUID()); pAtom->setChainName(ch); pAtom->setResIndex(resid); if (resn.isEmpty()) { // res name is determined by chain name and resindex MolResiduePtr pRes = getResidue(ch, resid); if (pRes.isnull()) { // ERROR!! cannot determine the residue to append to return -1; } pAtom->setResName(pRes->getName()); } else { pAtom->setResName(resn); } return appendAtom(pAtom); }
LString PDBFileWriter::formatAtomName(MolAtomPtr pAtom) { LString atomnam = pAtom->getName(); char cConfID = pAtom->getConfID(); int elem = pAtom->getElement(); if (cConfID=='\0') cConfID = ' '; // invalid name case if (atomnam.length()>=4|| elem==ElemSym::XX) { return LString::format("%4s%c", atomnam.c_str(), cConfID); } LString elenam = ElemSym::symID2Str(elem); elenam = elenam.toUpperCase(); int elepos = atomnam.indexOf(elenam); if (elepos<0) { return LString::format("%4s%c", atomnam.c_str(), cConfID); } LString atommod; // if (atomnam.equals(elenam)) { // // atom name==elem name // shead += LString::format(" %2s ", elenam.c_str()); // break; // } elepos += elenam.length(); atommod = atomnam.substr(elepos); elenam = atomnam.substr(0, elepos); if (atommod.length()<=2) { return LString::format("%2s%-2s%c", elenam.c_str(), atommod.c_str(), cConfID); } return LString::format("%4s%c", atomnam.c_str(), cConfID); }
bool AtomPropColoring::getAtomColor(MolAtomPtr pAtom, gfx::ColorPtr &col) { MB_DPRINTLN("***** AtomPropCol getAtomColor called"); try { int ccode = pAtom->getAtomPropInt(m_propname); col = gfx::SolidColorPtr(new gfx::SolidColor(ccode)); } catch (...) { col = SolidColor::createRGB(0.5,0.5,0.5); //return false; } return true; }
void BallStickRenderer::drawInterAtomLine(MolAtomPtr pAtom1, MolAtomPtr pAtom2, DisplayContext *pdl) { if (pAtom1.isnull() || pAtom2.isnull()) return; const Vector4D pos1 = pAtom1->getPos(); const Vector4D pos2 = pAtom2->getPos(); ColorPtr pcol1 = ColSchmHolder::getColor(pAtom1); ColorPtr pcol2 = ColSchmHolder::getColor(pAtom2); if ( pcol1->equals(*pcol2.get()) ) { pdl->color(pcol1); pdl->cylinder(m_bondw, pos1, pos2); } else { const Vector4D mpos = (pos1 + pos2).divide(2.0); pdl->color(pcol1); pdl->cylinder(m_bondw, pos1, mpos); pdl->color(pcol2); pdl->cylinder(m_bondw, pos2, mpos); } }
bool BfacColoring::getAtomColor(MolAtomPtr pAtom, gfx::ColorPtr &col) { double par; if (m_nMode==BFC_OCC) par = pAtom->getOcc(); else if (m_nMode==BFC_CENTER) par = (pAtom->getPos()-m_vCenter).length(); else par = pAtom->getBfac(); col = m_colLow; double parLo = m_parLow; double parHi = m_parHigh; if (isAutoMode()) { parLo = m_parAutoLo; parHi = m_parAutoHi; } if (par<parLo) col = m_colLow; else if (par>parHi) col = m_colHigh; else { double ratio; if (qlib::isNear4(parHi, parLo)) ratio = 1.0; else ratio = (par-parLo)/(parHi-parLo); col = ColorPtr(MB_NEW gfx::GradientColor(m_colHigh, m_colLow, ratio)); } return true; }
bool MolCoord::removeAtom(int atomid) { MolAtomPtr pAtom = getAtom(atomid); if (pAtom.isnull() || pAtom->getParentUID()!=getUID()) return false; m_atomPool.remove(atomid); // invalidate ID pAtom->setID(-1); const LString &aname = pAtom->getName(); char cConfID = pAtom->getConfID(); ResidIndex nresid = pAtom->getResIndex(); const LString &cname = pAtom->getChainName(); MolChainPtr pCh = getChain(cname); if (pCh.isnull()) return false; MolResiduePtr pRes = getResidue(cname, nresid); if (pRes.isnull()) return false; // remove atom if (!pRes->removeAtom(aname, cConfID)) return false; if (pRes->getAtomSize()>0) return true; // purge the empty residue if (!pCh->removeResidue(nresid)) return false; // delete pRes; if (pCh->getSize()>0) return true; // purge the empty chain if (!removeChain(cname)) return false; // delete pCh; return true; }
/// Convert aid to (persistent) string representation LString MolCoord::toStrAID(int atomid) const { MolAtomPtr pAtom = getAtom(atomid); if (pAtom.isnull()) return LString(); LString value = LString::format("%s.%s.%s", pAtom->getChainName().c_str(), pAtom->getResIndex().toString().c_str(), pAtom->getName().c_str()); char conf_id = pAtom->getConfID(); if (conf_id) value += ":" + LString(conf_id); return value; }
void SimpleRenderer::drawInterAtomLine(MolAtomPtr pAtom1, MolAtomPtr pAtom2, MolBond *pMB, DisplayContext *pdl) { if (pAtom1.isnull() || pAtom2.isnull()) return; const Vector4D pos1 = pAtom1->getPos(); const Vector4D pos2 = pAtom2->getPos(); ColorPtr pcol1 = ColSchmHolder::getColor(pAtom1); ColorPtr pcol2 = ColSchmHolder::getColor(pAtom2); int nBondType = pMB->getType(); if (m_bValBond && (nBondType==MolBond::DOUBLE || nBondType==MolBond::TRIPLE)) { MolCoordPtr pMol = getClientMol(); Vector4D dvd = pMB->getDblBondDir(pMol); if (nBondType==MolBond::DOUBLE) { // double bond if ( pcol1->equals(*pcol2.get()) ) { pdl->color(pcol1); pdl->vertex(pos1 + dvd.scale(m_dCvScl1)); pdl->vertex(pos2 + dvd.scale(m_dCvScl1)); pdl->vertex(pos1 + dvd.scale(m_dCvScl2)); pdl->vertex(pos2 + dvd.scale(m_dCvScl2)); } else { const Vector4D minpos = (pos1 + pos2).divide(2.0); pdl->color(pcol1); pdl->vertex(pos1 + dvd.scale(m_dCvScl1)); pdl->vertex(minpos + dvd.scale(m_dCvScl1)); pdl->vertex(pos1 + dvd.scale(m_dCvScl2)); pdl->vertex(minpos + dvd.scale(m_dCvScl2)); pdl->color(pcol2); pdl->vertex(pos2 + dvd.scale(m_dCvScl1)); pdl->vertex(minpos + dvd.scale(m_dCvScl1)); pdl->vertex(pos2 + dvd.scale(m_dCvScl2)); pdl->vertex(minpos + dvd.scale(m_dCvScl2)); } } else { // triple bond if ( pcol1->equals(*pcol2.get()) ) { pdl->color(pcol1); pdl->vertex(pos1); pdl->vertex(pos2); pdl->vertex(pos1 + dvd.scale(m_dCvScl1)); pdl->vertex(pos2 + dvd.scale(m_dCvScl1)); pdl->vertex(pos1 + dvd.scale(-m_dCvScl1)); pdl->vertex(pos2 + dvd.scale(-m_dCvScl1)); } else { const Vector4D minpos = (pos1 + pos2).divide(2.0); pdl->color(pcol1); pdl->vertex(pos1); pdl->vertex(minpos); pdl->vertex(pos1 + dvd.scale(m_dCvScl1)); pdl->vertex(minpos + dvd.scale(m_dCvScl1)); pdl->vertex(pos1 + dvd.scale(-m_dCvScl1)); pdl->vertex(minpos + dvd.scale(-m_dCvScl1)); pdl->color(pcol2); pdl->vertex(pos2); pdl->vertex(minpos); pdl->vertex(pos2 + dvd.scale(m_dCvScl1)); pdl->vertex(minpos + dvd.scale(m_dCvScl1)); pdl->vertex(pos2 + dvd.scale(-m_dCvScl1)); pdl->vertex(minpos + dvd.scale(-m_dCvScl1)); } } ++m_nBondDrawn; return; } if ( pcol1->equals(*pcol2.get()) ) { pdl->color(pcol1); pdl->vertex(pos1); pdl->vertex(pos2); } else { const Vector4D minpos = (pos1 + pos2).divide(2.0); pdl->color(pcol1); pdl->vertex(pos1); pdl->vertex(minpos); pdl->color(pcol2); pdl->vertex(pos2); pdl->vertex(minpos); } ++m_nBondDrawn; return; }
void SimpleRenderer::renderVBO() { quint32 i, j; quint32 nbons = 0, natoms = 0, nmbons = 0, nva = 0; MolCoordPtr pMol = getClientMol(); // initialize the coloring scheme getColSchm()->start(pMol, this); pMol->getColSchm()->start(pMol, this); std::deque<int> isolated_atoms; // IntBondArray sbonds; // IntMBondArray mbonds; // IntAtomArray atoms; { // build bond data structure/estimate VBO size std::set<int> bonded_atoms; BondIterator biter(pMol, getSelection()); for (biter.first(); biter.hasMore(); biter.next()) { MolBond *pMB = biter.getBond(); int aid1 = pMB->getAtom1(); int aid2 = pMB->getAtom2(); bonded_atoms.insert(aid1); bonded_atoms.insert(aid2); MolAtomPtr pA1 = pMol->getAtom(aid1); MolAtomPtr pA2 = pMol->getAtom(aid2); if (pA1.isnull() || pA2.isnull()) continue; // skip invalid bonds int nBondType = pMB->getType(); if (m_bValBond && (nBondType==MolBond::DOUBLE || nBondType==MolBond::TRIPLE)) { ++nmbons; } else { ++nbons; } } m_sbonds.resize(nbons); m_mbonds.resize(nmbons); i=0; j=0; int iva = 0; for (biter.first(); biter.hasMore(); biter.next()) { MolBond *pMB = biter.getBond(); int aid1 = pMB->getAtom1(); int aid2 = pMB->getAtom2(); MolAtomPtr pA1 = pMol->getAtom(aid1); MolAtomPtr pA2 = pMol->getAtom(aid2); if (pA1.isnull() || pA2.isnull()) continue; // skip invalid bonds ColorPtr pcol1 = ColSchmHolder::getColor(pA1); ColorPtr pcol2 = ColSchmHolder::getColor(pA2); int nBondType = pMB->getType(); bool bSameCol = (pcol1->equals(*pcol2.get()))?true:false; if (m_bValBond && (nBondType==MolBond::DOUBLE || nBondType==MolBond::TRIPLE)) { Vector4D dvd = pMB->getDblBondDir(pMol); m_mbonds[j].aid1 = aid1; m_mbonds[j].aid2 = aid2; m_mbonds[j].vaind = iva; m_mbonds[j].nx = (qfloat32) dvd.x(); m_mbonds[j].ny = (qfloat32) dvd.y(); m_mbonds[j].nz = (qfloat32) dvd.z(); if (nBondType==MolBond::DOUBLE) { // double bond if ( bSameCol ) { // same color --> one double bond iva+=2*2; m_mbonds[j].itype = IBON_1C_2V; m_mbonds[j].nelems = 2*2; } else { // different color --> two double bonds iva+=4*2; m_mbonds[j].itype = IBON_2C_2V; m_mbonds[j].nelems = 4*2; } } else { // triple bond if ( bSameCol ) { // same color --> one triple bond iva+=2*3; m_mbonds[j].itype = IBON_1C_3V; m_mbonds[j].nelems = 2*3; } else { // different color --> two triple bonds iva+=4*3; m_mbonds[j].itype = IBON_2C_3V; m_mbonds[j].nelems = 4*3; } } ++j; } else { // single bond / valbond disabled m_sbonds[i].aid1 = aid1; m_sbonds[i].aid2 = aid2; m_sbonds[i].vaind = iva; if ( bSameCol ) { // same color --> one bond iva+=2; m_sbonds[i].itype = IBON_1C_1V; m_sbonds[i].nelems = 2; } else { // different color --> two bonds iva+=4; m_sbonds[i].itype = IBON_2C_1V; m_sbonds[i].nelems = 4; } ++i; } } // calculate isolated atoms AtomIterator aiter(pMol, getSelection()); for (aiter.first(); aiter.hasMore(); aiter.next()) { int aid = aiter.getID(); MolAtomPtr pAtom = pMol->getAtom(aid); if (pAtom.isnull()) continue; // ignore errors if (bonded_atoms.find(aid)!=bonded_atoms.end()) continue; // already bonded isolated_atoms.push_back(aid); } natoms = isolated_atoms.size(); m_atoms.resize(natoms); for (i=0; i<natoms; ++i) { m_atoms[i].aid1 = isolated_atoms[i]; m_atoms[i].vaind = iva; iva += 2*3; } nva = iva; } getColSchm()->end(); pMol->getColSchm()->end(); if (m_pVBO!=NULL) delete m_pVBO; m_pVBO = MB_NEW gfx::DrawElemVC(); m_pVBO->alloc(nva); m_pVBO->setDrawMode(gfx::DrawElemVC::DRAW_LINES); MB_DPRINTLN("SimpleRenderer> %d elems VBO created", nva); updateVBO(true); }
// read from stream void PsfReader::read(qlib::InStream &ins) { int i, ires; qlib::LineStream ls(ins); m_pls = &ls; // skip header line readLine(); readLine(); /////////////////// // read REMARK header line readLine(); removeComment(); int ncomment; if (!m_line.toInt(&ncomment)) { MB_THROW(qlib::FileFormatException, "Cannot read ncomment line"); return; } MB_DPRINTLN("ncomment=%d", ncomment); for (i=0; i<ncomment; ++i) { readLine(); m_line = m_line.trim("\r\n "); LOG_DPRINTLN("%s", m_line.c_str()); } readLine(); /////////////////// // read atoms readLine(); removeComment(); if (!m_line.toInt(&m_natom)) { MB_THROW(qlib::FileFormatException, "Cannot read natom line"); return; } MB_DPRINTLN("natoms=%d", m_natom); LString stmp; for (i=0; i<m_natom; ++i) { readLine(); // LOG_DPRINTLN("%s", m_line.c_str()); // chain name stmp = m_line.substr(9, 3); stmp = stmp.trim(" "); // stmp = stmp.toLowerCase(); LString chain(stmp.c_str()); // residue number stmp = m_line.substr(14, 4); int nresi; if (!stmp.toInt(&nresi)) { LString msg = LString::format("cannot convert resid number: %s", stmp.c_str()); MB_THROW(qlib::FileFormatException, msg); return; } ResidIndex residx(nresi); // residue name stmp = m_line.substr(19, 4); stmp = stmp.trim(" "); // stmp = stmp.toLowerCase(); LString resn(stmp.c_str()); // atom name stmp = m_line.substr(24, 4); stmp = stmp.trim(" "); // stmp = stmp.toLowerCase(); LString name(stmp.c_str()); // charge stmp = m_line.substr(34, 10); double charge; if (!stmp.toDouble(&charge)) { LString msg = LString::format("cannot convert charge %s", stmp.c_str()); MB_THROW(qlib::FileFormatException, msg); return; } // mass stmp = m_line.substr(50, 8); double mass; if (!stmp.toDouble(&mass)) { LString msg = LString::format("cannot convert mass <%s>", stmp.c_str()); MB_THROW(qlib::FileFormatException, msg); return; } ElemID eleid = convMassElem(mass); //LOG_DPRINTLN("ATOM %s %s %d %s", //(*pAtoms)[i].name.c_str(), //(*pAtoms)[i].resn.c_str(), //(*pAtoms)[i].resid, //(*pAtoms)[i].chain.c_str()); MolAtomPtr pAtom = MolAtomPtr(MB_NEW MolAtom()); pAtom->setParentUID(m_pMol->getUID()); pAtom->setName(name); pAtom->setElement(eleid); pAtom->setChainName(chain); pAtom->setResIndex(residx); pAtom->setResName(resn); if (m_pMol->appendAtom(pAtom)<0) { LString stmp = m_line; stmp = stmp.chomp(); // stmp = stmp.toUpperCase(); // m_nErrCount ++; // if (m_nErrCount<m_nErrMax) LOG_DPRINTLN("PsfReader> read ATOM line failed: %s", stmp.c_str()); } } readLine(); }
static void drawSelAtom(MolAtomPtr pAtom, DisplayContext *pdl) { pdl->drawAster(pAtom->getPos(), 0.25); }
void BallStickRenderer::drawRings(DisplayContext *pdl) { int i, j; MolCoordPtr pMol = getClientMol(); while (m_atoms.size()>0) { std::set<int>::iterator iter = m_atoms.begin(); int aid = *iter; m_atoms.erase(iter); MolAtomPtr pa = pMol->getAtom(aid); if (pa.isnull()) continue; MolResiduePtr pres = pa->getParentResidue(); ResiToppar *ptop = pres->getTopologyObj(); if (ptop==NULL) continue; // draw rings int nrings = ptop->getRingCount(); for (i=0; i<nrings; i++) { const ResiToppar::RingAtomArray *pmembs = ptop->getRing(i); std::list<int> ring_atoms; // completeness flag of the ring bool fcompl = true; for (j=0; j<pmembs->size(); j++) { LString nm = pmembs->at(j); int maid = pres->getAtomID(nm); if (maid<=0) { fcompl = false; break; } std::set<int>::const_iterator miter = m_atoms.find(maid); if (miter==m_atoms.end()) { if (aid!=maid) { fcompl = false; break; } else { ring_atoms.push_back(aid); continue; } } ring_atoms.push_back(*miter); } if (fcompl) drawRingImpl(ring_atoms, pdl); } // remove drawn ring members from m_atoms for (i=0; i<nrings; i++) { const ResiToppar::RingAtomArray *pmembs = ptop->getRing(i); for (j=0; j<pmembs->size(); j++) { LString nm = pmembs->at(j); int maid = pres->getAtomID(nm); if (maid<=0) continue; std::set<int>::iterator miter = m_atoms.find(maid); if (miter==m_atoms.end()) continue; m_atoms.erase(miter); } } } }
void BallStickRenderer::drawRingImpl(const std::list<int> atoms, DisplayContext *pdl) { MolCoordPtr pMol = getClientMol(); double len; int i, nsize = atoms.size(); Vector4D *pvecs = MB_NEW Vector4D[nsize]; Vector4D cen; std::list<int>::const_iterator iter = atoms.begin(); std::list<int>::const_iterator eiter = atoms.end(); MolAtomPtr pPivAtom, pAtom; for (i=0; iter!=eiter; ++iter, i++) { MolAtomPtr pAtom = pMol->getAtom(*iter); if (pAtom.isnull()) return; MolResiduePtr pres = pAtom->getParentResidue(); MolChainPtr pch = pAtom->getParentChain(); MB_DPRINTLN("RING %s %s", pres->toString().c_str(), pAtom->getName().c_str()); pvecs[i] = pAtom->getPos(); cen += pvecs[i]; if (pPivAtom.isnull() && pAtom->getElement()==ElemSym::C) pPivAtom = pAtom; } if (pPivAtom.isnull()) pPivAtom = pAtom; // no carbon atom --> last atom becomes pivot cen = cen.divide(nsize); // calculate the normal vector Vector4D norm; for (i=0; i<nsize; i++) { int ni = (i+1)%nsize; Vector4D v1 = pvecs[ni] - pvecs[i]; Vector4D v2 = cen - pvecs[i]; Vector4D ntmp; ntmp = v1.cross(v2); len = ntmp.length(); if (len<=F_EPS8) { LOG_DPRINTLN("BallStick> *****"); return; } //ntmp.scale(1.0/len); ntmp = ntmp.divide(len); norm += ntmp; } len = norm.length(); norm = norm.divide(len); Vector4D dv = norm.scale(m_tickness); ColorPtr col = evalMolColor(m_ringcol, ColSchmHolder::getColor(pPivAtom)); /* ColorPtr col = m_ringcol; // check molcol reference gfx::MolColorRef *pMolCol = dynamic_cast<gfx::MolColorRef *>(col.get()); if (pMolCol!=NULL) { // molcol ref case --> resolve the pivot's color col = ColSchmHolder::getColor(pPivAtom); } */ pdl->setPolygonMode(gfx::DisplayContext::POLY_FILL_NOEGLN); pdl->startTriangleFan(); pdl->normal(norm); pdl->color(col); pdl->vertex(cen+dv); for (i=0; i<=nsize; i++) { pdl->vertex(pvecs[i%nsize]+dv); } pdl->end(); pdl->startTriangleFan(); pdl->normal(-norm); pdl->color(col); pdl->vertex(cen-dv); for (i=nsize; i>=0; i--) { pdl->vertex(pvecs[i%nsize]-dv); } pdl->end(); pdl->setPolygonMode(gfx::DisplayContext::POLY_FILL); delete [] pvecs; }
// write PDB file to stream bool PDBFileWriter::write(qlib::OutStream &outs) { m_pMol = getTarget<MolCoord>(); if (m_pMol==NULL) { LOG_DPRINTLN("PDBWriter> MolCoord is not attached !!"); return false; } // check extension record handlers PDBFileReader::HndlrTab &htab = PDBFileReader::m_htab; bool bUseHndlr = htab.size()>0; MolCoord *pMol = m_pMol; qlib::PrintStream prs(outs); // // write header // //LString sbuf = pqsys->getVersion(); //prs.formatln("REMARK PDB File Generated by CueMol (ver %s)", sbuf.c_str()); prs.formatln("REMARK PDB File Generated by CueMol2"); // // write SSBOND record // writeSSBonds(prs); // // write LINK record // writeLinks(prs); writeSecstr(prs); // // write extension records (CRYST1) // if (bUseHndlr) { LString sbuf; PDBFileReader::HndlrTab::const_iterator iter = htab.begin(); for (; iter!=htab.end(); ++iter) { PDBFileReader::RecordHandler *ph = iter->second; if (ph!=NULL && ph->write(sbuf, pMol)) { prs.println(sbuf); } } } // // write body (ATOM/ANISOU records) // int nserial = 1; // Sort chain names by ASCII order // take care of '_' (empty) chain std::list<LString> chnames; { MolCoord::ChainIter iter = pMol->begin(); bool bHasEmptyChain = false; for (; iter!=pMol->end(); ++iter) { MolChainPtr pChn = iter->second; LString chnam = (pChn->getName().c_str()); if (chnam.equals("_")) { bHasEmptyChain = true; continue; } chnames.push_back(chnam); } chnames.sort(); if (bHasEmptyChain) chnames.push_back("_"); } std::list<LString>::const_iterator cniter = chnames.begin(); for (; cniter!=chnames.end(); ++cniter) { LString chnam = *cniter; MolChainPtr pChn = pMol->getChain(chnam); // format chain name char cch = convChainName(chnam); LString resnam; MolChain::ResidCursor2 riter = pChn->begin2(); // int nlastres = 0; for (; riter!=pChn->end2(); ++riter) { //MolResiduePtr pRes = *riter; MolResiduePtr pRes = riter->second; if (pRes.isnull()) continue; ResidIndex rindex = pRes->getIndex(); resnam = pRes->getName(); // format residue name // resnam = resnam.toUpperCase(); resnam = resnam.substr(0,3); // sort atom by AID std::list<int> atmlist; { MolResidue::AtomCursor aiter = pRes->atomBegin(); for (; aiter!=pRes->atomEnd(); ++aiter) { atmlist.push_back(aiter->second); } atmlist.sort(); } std::list<int>::const_iterator iter = atmlist.begin(); for (; iter!=atmlist.end(); ++iter) { int aid = *iter; MolAtomPtr pAtm = pMol->getAtom(aid); if (pAtm.isnull()) continue; if (!m_pSel.isnull()) { if (!m_pSel->isSelected(pAtm)) continue; // skip nonselected atom } writeAtomLine(nserial, rindex, resnam, cch, pAtm, prs); nserial++; } // nlastres = rindex.first; } // print TER record /*prs.formatln("TER " "%5d" " " "%3s " "%1s" "%4d" " ", nserial, resnam.c_str(), chnam.c_str(), nlastres);*/ prs.println("TER"); nserial ++; } //prs.println("END "); prs.println("END"); return true; }
bool PDBFileWriter::writeAtomLine(int nserial, const ResidIndex &rindex, const char *resnam, char chainch, MolAtomPtr pa, qlib::PrintStream &prs) { int resind = rindex.first; char inscode = rindex.second; LString atomnam = pa->getName().c_str(); // atomnam = atomnam.toUpperCase(); // conv ILE's CD name // (CD is converted to CD1 in PDBFileReader, so this should not occur) if (LChar::equals(resnam, "ILE") && atomnam.equals("CD")) atomnam = "CD1"; #ifdef QTL_CONV // conv nucl's prime to aster atomnam.replace('\'', '*'); // convert THY's C5A to C5M if (LChar::equals(resnam, "THY") && atomnam.equals("C5A")) { atomnam = "C5M"; } // conv nucl name if (LChar::equals(resnam, "ADE")) { resnam = " A"; } else if (LChar::equals(resnam, "THY")) { resnam = " T"; } else if (LChar::equals(resnam, "GUA")) { resnam = " G"; } else if (LChar::equals(resnam, "CYT")) { resnam = " C"; } else if (LChar::equals(resnam, "URI")) { resnam = " U"; } #endif LString shead; shead = LString::format("%5d ", nserial); // format atom name shead += formatAtomName(pa); shead += LString::format("%3s " "%c" "%4d" "%c", resnam, chainch, resind, (inscode=='\0') ? ' ' : inscode); ////////// // output to the stream prs.print("ATOM "); prs.print(shead); // Get atom position before applying xformMat, if xformMat is set Vector4D pos = pa->getRawPos(); prs.formatln(" " "%8.3f" "%8.3f" "%8.3f" "%6.2f" "%6.2f" " " " ", pos.x(), pos.y(), pos.z(), pa->getOcc(), pa->getBfac()); if (pa->hasAnIsoU()) { prs.print("ANISOU"); prs.print(shead); int u11 = int(pa->getU(0,0) * 1.0e4); int u22 = int(pa->getU(1,1) * 1.0e4); int u33 = int(pa->getU(2,2) * 1.0e4); int u12 = int(pa->getU(0,1) * 1.0e4); int u13 = int(pa->getU(0,2) * 1.0e4); int u23 = int(pa->getU(1,2) * 1.0e4); prs.formatln(" " " %6d" " %6d" " %6d" " %6d" " %6d" " %6d" " ", u11, u22, u33, u12, u13, u23); } return true; }
int MolCoord::appendAtom(MolAtomPtr pAtom) { pAtom->setParentUID(getUID()); const LString &cname = pAtom->getChainName(); const LString &rname = pAtom->getResName(); const LString &aname = pAtom->getName(); ResidIndex nresid = pAtom->getResIndex(); if (cname.length()<=0 || aname.length()<=0) { LString msg = LString::format("MolCoord> ERROR: appending atom with invalid properties" " (c:'%s' rn:'%s' ri:'%s' an:'%s')", cname.c_str(), rname.c_str(), nresid.toString().c_str(), aname.c_str()); MB_DPRINTLN(msg); MB_THROW(qlib::IllegalArgumentException, msg); return -1; } MolChainPtr pCh = getChain(cname); if (pCh.isnull()) { pCh = MolChainPtr(MB_NEW MolChain()); pCh->setParentUID(getUID()); pCh->setName(cname); appendChain(pCh); } MolResiduePtr pRes = pCh->getResidue(nresid); if (pRes.isnull()) { pRes = MolResiduePtr(MB_NEW MolResidue()); pRes->setParentUID(getUID()); pRes->setIndex(nresid); pRes->setName(rname); // pRes->setChainName(cname); pCh->appendResidue(pRes); } else { const LString &pre_rname = pRes->getName(); if (!pre_rname.equals(rname)) { MB_DPRINTLN("MolCoord> ERROR: appending an atom (%s %s%s %s) with inconsistent residue (%s)", cname.c_str(), rname.c_str(), nresid.toString().c_str(), aname.c_str(), pre_rname.c_str()); // TO DO: throw exception (???) // This is often the case, so is not an exception. // return -1; } } // // Append to the atompool --> assign the atom ID // int atomid = m_atomPool.put(pAtom); if (atomid<0) { // This isn't fail in normal situation. MB_THROW(qlib::RuntimeException, "append to the atompool failed"); return -1; } pAtom->setID(atomid); // MolResidue::appendAtom() must be called after setID(), // because MolResidue makes map from name to AID, which requires "AID". if (!pRes->appendAtom(pAtom)) { // This is often the case with malformed PDB files, so is not an exception. MB_DPRINTLN("MolCoord> ERROR: appending duplicated atom (%s %s%s %s)", cname.c_str(), rname.c_str(), nresid.toString().c_str(), aname.c_str()); // Remove the mis-appended atom from the pool. m_atomPool.remove(atomid); return -1; } // Update the cached xform matrix if required pAtom->resetXformMatrix(); if (!getXformMatrix().isIdent()) pAtom->setXformMatrix(getXformMatrix()); return atomid; }
/// read one MOL entry from stream bool MOL2MolReader::readMol(qlib::LineStream &lin, bool bskip) { LString sline; std::vector<LString> slist; for (;;) { sline = lin.readLine().chomp(); if (sline.isEmpty() && !lin.ready()) return false; // EOF if (sline.equals("@<TRIPOS>MOLECULE")) { break; } } // mol_name LString cmpd_name = lin.readLine().trim(" \t\r\n"); if (cmpd_name.isEmpty()) cmpd_name = "_"; // XXX // molecule info sline = lin.readLine().chomp(); split(sline, ' ', std::back_inserter(slist)); if (slist.size()<1) { MB_THROW(MOL2FormatException, "Invalid atom info record"); } int natoms; if (!slist[0].toInt(&natoms)) { MB_THROW(MOL2FormatException, "Invalid atom info record"); } int nbonds=0; if (slist.size()>1) { if (!slist[1].toInt(&nbonds)) { MB_THROW(MOL2FormatException, "Invalid atom info record"); } } // mol_type LString mol_type = lin.readLine().chomp(); bool bApplyTopo = false; if (mol_type.equals("PROTEIN") || mol_type.equals("NUCLEIC_ACID")) bApplyTopo = true; // Ignore charge_type // Ignore mol_comment // Search ATOM record for (;;) { sline = lin.readLine().chomp(); if (sline.isEmpty() && !lin.ready()) return false; // EOF if (sline.equals("@<TRIPOS>ATOM")) { break; } } int i, idot, iresid, naid, ind, prev_resid; ElemID eleid; double xx, yy, zz; LString aname, atype, satom, res_name; std::map<int,int> atommap; std::map<LString, int> aname_counts; std::map<LString, int>::iterator an_iter; // XXXX prev_resid = -999999; for (i=0; i<natoms; ++i) { //LOG_DPRINTLN("i=%d, natoms=%d", i, natoms); sline = lin.readLine().chomp(); slist.clear(); split(sline, ' ', std::back_inserter(slist)); if (slist.size()<8) { MB_THROW(MOL2FormatException, "Invalid atom record"); } if (!slist[0].toInt(&ind)) { MB_THROW(MOL2FormatException, "Invalid atom ID record"); } aname = slist[1]; an_iter = aname_counts.find(aname); if (an_iter==aname_counts.end()) { aname_counts.insert(std::pair<LString, int>(aname, 1)); } else { an_iter->second = an_iter->second + 1; aname = LString::format("%d%s", an_iter->second, aname.c_str()); } if (!slist[2].toRealNum(&xx)) { MB_THROW(MOL2FormatException, "Invalid atom coord record"); } if (!slist[3].toRealNum(&yy)) { MB_THROW(MOL2FormatException, "Invalid atom coord record"); } if (!slist[4].toRealNum(&zz)) { MB_THROW(MOL2FormatException, "Invalid atom coord record"); } atype = slist[5]; satom = ""; idot = atype.indexOf('.'); if (idot<0) { satom = atype; } else if (idot>0) { satom = atype.substr(0, idot); } else { MB_THROW(MOL2FormatException, "Invalid SYBYL atom type"); } iresid = 0; if (!slist[6].toInt(&iresid)) { MB_THROW(MOL2FormatException, "Invalid atom resid record"); } res_name = slist[7]; if (res_name.equals("<0>")) res_name = cmpd_name; if (bApplyTopo) { // protein or nucleic acid // strip residue number from res_name int ntmp; if (res_name.substr(3).toInt(&ntmp)) { res_name = res_name.substr(0, 3); iresid = ntmp; } if (iresid!=prev_resid) // residue is changed --> clear atom name count aname_counts.clear(); } eleid = ElemSym::str2SymID(satom); // LOG_DPRINTLN("Atom: %f, %f, %f, <%s> %d", xx, yy, zz, aname.c_str(), eleid); if (!bskip) { MolAtomPtr pAtom = MolAtomPtr(MB_NEW MolAtom()); pAtom->setParentUID(m_pMol->getUID()); pAtom->setName(aname); pAtom->setElement(eleid); pAtom->setChainName(m_sCurrChName); pAtom->setResIndex(iresid); pAtom->setResName(res_name); pAtom->setPos(Vector4D(xx,yy,zz)); pAtom->setBfac(0.0); pAtom->setOcc(1.0); naid = m_pMol->appendAtom(pAtom); if (naid<0) MB_THROW(MOL2FormatException, "appendAtom() failed"); atommap.insert(std::pair<int,int>(ind, naid)); m_nReadAtoms++; } prev_resid = iresid; } // Search BOND record for (;;) { sline = lin.readLine().chomp(); if (sline.isEmpty() && !lin.ready()) return false; // EOF if (sline.equals("@<TRIPOS>BOND")) { break; } } int natm1, natm2; int natm_id1, natm_id2; std::map<int,int>::const_iterator iter; for (i=0; i<nbonds; ++i) { sline = lin.readLine().chomp(); slist.clear(); split(sline, ' ', std::back_inserter(slist)); if (slist.size()<4) { MB_THROW(MOL2FormatException, "Invalid bond record"); } if (!slist[1].toInt(&natm1)) { MB_THROW(MOL2FormatException, "Invalid bond line (atom1)"); } if (!slist[2].toInt(&natm2)) { MB_THROW(MOL2FormatException, "Invalid bond line (atom2)"); } LString sbont = slist[3]; if (!bskip) { iter = atommap.find(natm1); if (iter==atommap.end()) MB_THROW(MOL2FormatException, "Invalid bond line (bond atom1 not found)"); natm_id1 = iter->second; iter = atommap.find(natm2); if (iter==atommap.end()) MB_THROW(MOL2FormatException, "Invalid bond line (bond atom2 not found)"); natm_id2 = iter->second; MolBond *pB = m_pMol->makeBond(natm_id1, natm_id2, true); if (pB==NULL) MB_THROW(MOL2FormatException, "makeBond failed"); if (sbont.equals("1")) pB->setType(MolBond::SINGLE); else if (sbont.equals("2")) pB->setType(MolBond::DOUBLE); else if (sbont.equals("3")) pB->setType(MolBond::TRIPLE); else if (sbont.equals("ar")||sbont.equals("am")) pB->setType(MolBond::DELOC); m_nReadBonds++; } //LOG_DPRINTLN("bond %d<-->%d: %d", natm_id1, natm_id2, nbont); } if (bApplyTopo) { m_pMol->applyTopology(); if (mol_type.equals("PROTEIN")) m_pMol->calcProt2ndry(-500.0); if (mol_type.equals("NUCLEIC_ACID")) m_pMol->calcBasePair(3.7, 30); } else { // Set noautogen prop to this residue, // to avoid topology autogen, when saved to and loaded from the qdf stream. if (!bskip) { iter = atommap.begin(); if (iter!=atommap.end()) { int aid0 = iter->second; MolAtomPtr pA = m_pMol->getAtom(aid0); if (!pA.isnull()) { MolResiduePtr pRes = pA->getParentResidue(); if (!pRes.isnull()) { pRes->setPropStr("noautogen", "true"); } } } } } /* */ return true; }
void MolSurfObj::createSESFromMol(MolCoordPtr pMol, SelectionPtr pSel, double density, double probe_r) { AtomIterator aiter(pMol, pSel); int i, natoms=0; // count atom number for (aiter.first(); aiter.hasMore(); aiter.next()) { MolAtomPtr pAtom = aiter.get(); if (!chkAltConf(pAtom)) continue; MB_ASSERT(!pAtom.isnull()); ++natoms; } std::vector< BALL::TSphere3<double> > spheres(natoms); TopparManager *pTM = TopparManager::getInstance(); const double vdw_default = 2.0; // copy to the m_data Vector4D pos; for (i=0,aiter.first(); aiter.hasMore()&&i<natoms; aiter.next()) { MolAtomPtr pAtom = aiter.get(); if (!chkAltConf(pAtom)) continue; pos = pAtom->getPos(); double vdw = pTM->getVdwRadius(pAtom, false); if (vdw<0) vdw = vdw_default; spheres.at(i) = BALL::TSphere3<double>(BALL::TVector3<double>(pos.x(), pos.y(), pos.z()), vdw); ++i; } double diff = probe_r < 1.5 ? 0.01 : -0.01; bool ok = false; double rad = probe_r; BALL::ReducedSurface *pRS = NULL; BALL::SolventExcludedSurface *pSES = NULL; for (int i=0; !ok && i<10; ++i) { pRS = new BALL::ReducedSurface(spheres, rad); pRS->compute(); pSES = new BALL::SolventExcludedSurface(pRS); pSES->compute(); if (pSES->check()) break; // failed --> retry with different probe radius delete pRS; pRS = NULL; delete pSES; pSES = NULL; rad += diff; LOG_DPRINTLN("MolSurfBuilder> SES check failed --> retry (%d) with different probe r=%f", i, rad); } if (pSES==NULL) { //std::cout << "ses check failed" << std::endl; LOG_DPRINTLN("MolSurfBuilder> SES generation failed."); MB_THROW(qlib::RuntimeException, "MolSurfBuilder> SES generation failed."); return; } MB_ASSERT(pSES!=NULL&&pRS!=NULL); BALL::TriangulatedSES surface(pSES, density); surface.compute(); int nverts = surface.getNumberOfPoints(); int nfaces = surface.getNumberOfTriangles(); setVertSize(nverts); setFaceSize(nfaces); { BALL::TriangulatedSES::ConstPointIterator iter = surface.beginPoint(); BALL::TriangulatedSES::ConstPointIterator eiter = surface.endPoint(); int i = 0; for (;iter != eiter; ++iter) { BALL::TrianglePoint& tri_point = **iter; Vector4D n(tri_point.normal_.x,tri_point.normal_.y,tri_point.normal_.z); Vector4D v(tri_point.point_.x,tri_point.point_.y,tri_point.point_.z); setVertex(i, v, n); tri_point.setIndex(i); i++; } } { BALL::TriangulatedSES::ConstTriangleIterator iter = surface.beginTriangle(); BALL::TriangulatedSES::ConstTriangleIterator eiter = surface.endTriangle(); int i=0; for (; iter!=eiter; ++iter, ++i) { //std::cout << (**iter) << std::endl; int v1 = (*iter)->getVertex(0)->getIndex(); int v2 = (*iter)->getVertex(1)->getIndex(); int v3 = (*iter)->getVertex(2)->getIndex(); //printf("%6d %6d %6d\n", v1, v2, v3); setFace(i, v1, v2, v3); } } delete pSES; delete pRS; }