MoleculeExporter.cpp (pymol-v1.8.6.0.tar.bz2) | : | MoleculeExporter.cpp (pymol-v2.1.0.tar.bz2) | ||
---|---|---|---|---|
/* | /* | |||
* Molecular file formats export | * Molecular file formats export | |||
* | * | |||
* (c) 2016 Schrodinger, Inc. | * (c) 2016 Schrodinger, Inc. | |||
*/ | */ | |||
#include <vector> | #include <vector> | |||
#include <map> | #include <map> | |||
#include <algorithm> | #include <algorithm> | |||
#include <cstdarg> | #include <cstdarg> | |||
#include <clocale> | ||||
#include "os_std.h" | #include "os_std.h" | |||
#include "MoleculeExporter.h" | #include "MoleculeExporter.h" | |||
#include "Selector.h" | #include "Selector.h" | |||
#include "SelectorDef.h" | #include "SelectorDef.h" | |||
#include "Executive.h" | #include "Executive.h" | |||
#include "Vector.h" | #include "Vector.h" | |||
#include "ObjectMolecule.h" | #include "ObjectMolecule.h" | |||
#include "CoordSet.h" | #include "CoordSet.h" | |||
skipping to change at line 157 | skipping to change at line 158 | |||
std::vector<int> m_tmpids; | std::vector<int> m_tmpids; | |||
public: | public: | |||
// quasi constructor (easier to inherit than a real constructor) | // quasi constructor (easier to inherit than a real constructor) | |||
virtual void init(PyMOLGlobals * G_) { | virtual void init(PyMOLGlobals * G_) { | |||
G = G_; | G = G_; | |||
m_buffer = VLAlloc(char, 1280); | m_buffer = VLAlloc(char, 1280); | |||
m_buffer[0] = '\0'; | m_buffer[0] = '\0'; | |||
m_mat_ref.ptr = NULL; | ||||
m_offset = 0; | m_offset = 0; | |||
m_last_cs = NULL; | m_last_cs = NULL; | |||
m_last_obj = NULL; | m_last_obj = NULL; | |||
m_last_state = -1; | m_last_state = -1; | |||
m_retain_ids = false; | m_retain_ids = false; | |||
m_id = 0; | m_id = 0; | |||
setMulti(getMultiDefault()); | setMulti(getMultiDefault()); | |||
} | } | |||
skipping to change at line 215 | skipping to change at line 217 | |||
* Get the running index for the given atom. | * Get the running index for the given atom. | |||
*/ | */ | |||
int getTmpID(int atm) { | int getTmpID(int atm) { | |||
return m_tmpids[atm]; | return m_tmpids[atm]; | |||
} | } | |||
/* | /* | |||
* Get the current state title if not empty, or the object name otherwise. | * Get the current state title if not empty, or the object name otherwise. | |||
*/ | */ | |||
const char * getTitleOrName() { | const char * getTitleOrName() { | |||
if (!m_iter.cs) | ||||
return "untitled"; | ||||
return m_iter.cs->Name[0] ? m_iter.cs->Name : m_iter.obj->Obj.Name; | return m_iter.cs->Name[0] ? m_iter.cs->Name : m_iter.obj->Obj.Name; | |||
} | } | |||
public: | public: | |||
/* | /* | |||
* Set the reference coordinate frame to the inverse of the given | * Set the reference coordinate frame to the inverse of the given | |||
* object's transformation matrix. | * object's transformation matrix. | |||
*/ | */ | |||
void setRefObject(const char * ref_object, int ref_state); | void setRefObject(const char * ref_object, int ref_state); | |||
skipping to change at line 344 | skipping to change at line 348 | |||
m_coord = m_coord_tmp; | m_coord = m_coord_tmp; | |||
} | } | |||
writeAtom(); | writeAtom(); | |||
} | } | |||
if (m_last_cs) | if (m_last_cs) | |||
endCoordSet(); | endCoordSet(); | |||
if (m_last_obj) | if (m_last_obj) | |||
endObject(); | endObject(); | |||
else if (m_multi == cMolExportGlobal) | ||||
// empty selection | ||||
beginMolecule(); | ||||
if (m_multi == cMolExportGlobal) { | if (m_multi == cMolExportGlobal) { | |||
writeBonds(); | writeBonds(); | |||
} | } | |||
} | } | |||
void MoleculeExporter::setRefObject(const char * ref_object, int ref_state) { | void MoleculeExporter::setRefObject(const char * ref_object, int ref_state) { | |||
double matrix[16]; | double matrix[16]; | |||
m_mat_ref.ptr = NULL; | m_mat_ref.ptr = NULL; | |||
skipping to change at line 684 | skipping to change at line 691 | |||
ai->resv, | ai->resv, | |||
cifrepr(ai->inscode, "?"), | cifrepr(ai->inscode, "?"), | |||
m_coord[0], m_coord[1], m_coord[2], | m_coord[0], m_coord[1], m_coord[2], | |||
ai->q, ai->b, ai->formalCharge, | ai->q, ai->b, ai->formalCharge, | |||
cifrepr(LexStr(G, ai->chain)), | cifrepr(LexStr(G, ai->chain)), | |||
m_iter.state + 1); | m_iter.state + 1); | |||
} | } | |||
void writeBonds() { | void writeBonds() { | |||
// TODO | // TODO | |||
// Bond categories: | ||||
// 1) within residue -> _chem_comp_bond | ||||
// 2) polymer links -> implicit | ||||
// 3) others -> _struct_conn | ||||
m_bonds.clear(); | m_bonds.clear(); | |||
} | } | |||
bool isExcludedBond(int atm1, int atm2) { | bool isExcludedBond(int atm1, int atm2) { | |||
// TODO | // TODO | |||
// polymer links | ||||
return true; | return true; | |||
} | } | |||
}; | }; | |||
// ----------------------------------------------------------------------------- ----- // | // ----------------------------------------------------------------------------- ----- // | |||
/* | ||||
* Experimental PyMOL style annotated mmCIF. Exports colors, representation, | ||||
* and secondary structure. | ||||
*/ | ||||
struct MoleculeExporterPMCIF : public MoleculeExporterCIF { | ||||
void beginMolecule() { | ||||
MoleculeExporterCIF::beginMolecule(); | ||||
m_offset += VLAprintf(m_buffer, m_offset, "#\n" | ||||
"_atom_site.pymol_color\n" | ||||
"_atom_site.pymol_reps\n" | ||||
"_atom_site.pymol_ss\n"); | ||||
} | ||||
void writeAtom() { | ||||
MoleculeExporterCIF::writeAtom(); | ||||
const AtomInfoType * ai = m_iter.getAtomInfo(); | ||||
m_offset += VLAprintf(m_buffer, m_offset, | ||||
"%d %d %s\n", | ||||
ai->color, | ||||
ai->visRep, | ||||
cifrepr(ai->ssType)); | ||||
} | ||||
void writeBonds() { | ||||
if (m_bonds.empty()) | ||||
return; | ||||
m_offset += VLAprintf(m_buffer, m_offset, "#\n" | ||||
"loop_\n" | ||||
"_pymol_bond.atom_site_id_1\n" | ||||
"_pymol_bond.atom_site_id_2\n" | ||||
"_pymol_bond.order\n"); | ||||
for (auto bond_it = m_bonds.begin(); bond_it != m_bonds.end(); ++bond_it) { | ||||
const auto& bond = *bond_it; | ||||
m_offset += VLAprintf(m_buffer, m_offset, "%d %d %d\n", | ||||
bond.id1, bond.id2, bond.ref->order); | ||||
} | ||||
m_bonds.clear(); | ||||
} | ||||
bool isExcludedBond(int atm1, int atm2) { | ||||
return false; | ||||
} | ||||
}; | ||||
// ----------------------------------------------------------------------------- | ||||
----- // | ||||
struct MoleculeExporterMOL : public MoleculeExporter { | struct MoleculeExporterMOL : public MoleculeExporter { | |||
int m_chiral_flag; | int m_chiral_flag; | |||
std::vector<AtomRef> m_atoms; | std::vector<AtomRef> m_atoms; | |||
ElemCanonicalizer elemGetter; | ElemCanonicalizer elemGetter; | |||
int getMultiDefault() const { | int getMultiDefault() const { | |||
// single entry format | // single entry format | |||
return cMolExportGlobal; | return cMolExportGlobal; | |||
} | } | |||
skipping to change at line 808 | skipping to change at line 872 | |||
writeCTabV3000(); | writeCTabV3000(); | |||
} else { | } else { | |||
writeCTabV2000(); | writeCTabV2000(); | |||
} | } | |||
} | } | |||
void beginMolecule() { | void beginMolecule() { | |||
MoleculeExporter::beginMolecule(); | MoleculeExporter::beginMolecule(); | |||
m_offset += VLAprintf(m_buffer, m_offset, | m_offset += VLAprintf(m_buffer, m_offset, | |||
"%s\n PyMOL%03d 3D 0\n\n", | "%s\n PyMOL%3.3s 3D 0\n\n", | |||
getTitleOrName(), (_PyMOL_VERSION_int / 10) % 1000); | getTitleOrName(), _PyMOL_VERSION); | |||
m_chiral_flag = 0; | m_chiral_flag = 0; | |||
} | } | |||
}; | }; | |||
// ----------------------------------------------------------------------------- ----- // | // ----------------------------------------------------------------------------- ----- // | |||
struct MoleculeExporterSDF : public MoleculeExporterMOL { | struct MoleculeExporterSDF : public MoleculeExporterMOL { | |||
int getMultiDefault() const { | int getMultiDefault() const { | |||
skipping to change at line 1035 | skipping to change at line 1099 | |||
void writeAtom() { | void writeAtom() { | |||
const auto ai = m_iter.getAtomInfo(); | const auto ai = m_iter.getAtomInfo(); | |||
const float * rgb = ColorGet(G, ai->color); | const float * rgb = ColorGet(G, ai->color); | |||
char inscode[3] = { ai->inscode, 0 }; | char inscode[3] = { ai->inscode, 0 }; | |||
if (!inscode[0]) { | if (!inscode[0]) { | |||
strcpy(inscode, "<>"); | strcpy(inscode, "<>"); | |||
} | } | |||
ResName resn = ""; | ||||
AtomName name = "X"; | ||||
if (ai->resn) | ||||
AtomInfoGetAlignedPDBResidueName(G, ai, resn); | ||||
if (ai->name) | ||||
AtomInfoGetAlignedPDBAtomName(G, ai, resn, name); | ||||
m_offset += VLAprintf(m_buffer, m_offset, | m_offset += VLAprintf(m_buffer, m_offset, | |||
"%d %d %.3f %.3f %.3f %d %s %s %s %s %d %d %02X%02X%02X %d %.2f %d\n", / / %d %d\n", | "%d %d %.3f %.3f %.3f %d %s %s \"%-4s\" \"%-4s\" %d %d %02X%02X%02X %d % .2f %d\n", | |||
getTmpID(), | getTmpID(), | |||
getMacroModelAtomType(ai), | getMacroModelAtomType(ai), | |||
m_coord[0], m_coord[1], m_coord[2], | m_coord[0], m_coord[1], m_coord[2], | |||
ai->resv, | ai->resv, | |||
inscode, | inscode, | |||
ai->chain ? LexStr(G, ai->chain) : "\" \"", | ai->chain ? LexStr(G, ai->chain) : "\" \"", | |||
ai->resn ? LexStr(G, ai->resn) : "\"\"", | resn, | |||
ai->name ? LexStr(G, ai->name) : "X", | name, | |||
ai->protons, | ai->protons, | |||
ai->formalCharge, | ai->formalCharge, | |||
int(rgb[0] * 255), | int(rgb[0] * 255), | |||
int(rgb[1] * 255), | int(rgb[1] * 255), | |||
int(rgb[2] * 255), | int(rgb[2] * 255), | |||
ai->ssType[0] == 'H' ? 1 : ai->ssType[0] == 'S' ? 2 : 0, | ai->ssType[0] == 'H' ? 1 : ai->ssType[0] == 'S' ? 2 : 0, | |||
ai->q, | ai->q, | |||
ai->id); | ai->id); | |||
++m_n_atoms; | ++m_n_atoms; | |||
skipping to change at line 1199 | skipping to change at line 1270 | |||
if (ref_state < -1) | if (ref_state < -1) | |||
ref_state = state; | ref_state = state; | |||
// do "effective" current states | // do "effective" current states | |||
if (state == -2) | if (state == -2) | |||
state = -3; | state = -3; | |||
if (strcmp(format, "pdb") == 0) { | if (strcmp(format, "pdb") == 0) { | |||
exporter = new MoleculeExporterPDB; | exporter = new MoleculeExporterPDB; | |||
} else if (strcmp(format, "pmcif") == 0) { | ||||
exporter = new MoleculeExporterPMCIF; | ||||
} else if (strcmp(format, "cif") == 0) { | } else if (strcmp(format, "cif") == 0) { | |||
exporter = new MoleculeExporterCIF; | exporter = new MoleculeExporterCIF; | |||
} else if (strcmp(format, "sdf") == 0) { | } else if (strcmp(format, "sdf") == 0) { | |||
exporter = new MoleculeExporterSDF; | exporter = new MoleculeExporterSDF; | |||
} else if (strcmp(format, "pqr") == 0) { | } else if (strcmp(format, "pqr") == 0) { | |||
exporter = new MoleculeExporterPQR; | exporter = new MoleculeExporterPQR; | |||
} else if (strcmp(format, "mol2") == 0) { | } else if (strcmp(format, "mol2") == 0) { | |||
exporter = new MoleculeExporterMOL2; | exporter = new MoleculeExporterMOL2; | |||
} else if (strcmp(format, "mol") == 0) { | } else if (strcmp(format, "mol") == 0) { | |||
exporter = new MoleculeExporterMOL; | exporter = new MoleculeExporterMOL; | |||
} else if (strcmp(format, "xyz") == 0) { | } else if (strcmp(format, "xyz") == 0) { | |||
exporter = new MoleculeExporterXYZ; | exporter = new MoleculeExporterXYZ; | |||
} else if (strcmp(format, "mae") == 0) { | } else if (strcmp(format, "mae") == 0) { | |||
exporter = new MoleculeExporterMAE; | exporter = new MoleculeExporterMAE; | |||
} else { | } else { | |||
PRINTFB(G, FB_ObjectMolecule, FB_Errors) | PRINTFB(G, FB_ObjectMolecule, FB_Errors) | |||
" Error: unknown format: '%s'\n", format ENDFB(G); | " Error: unknown format: '%s'\n", format ENDFB(G); | |||
return NULL; | return NULL; | |||
} | } | |||
// Ensure "." decimal point in printf. It's possible to change this from | ||||
// Python, so don't rely on a persistent global value. | ||||
std::setlocale(LC_NUMERIC, "C"); | ||||
exporter->init(G); | exporter->init(G); | |||
exporter->setMulti(multi); | exporter->setMulti(multi); | |||
exporter->setRefObject(ref_object, ref_state); | exporter->setRefObject(ref_object, ref_state); | |||
exporter->execute(sele, state); | exporter->execute(sele, state); | |||
char * charVLA = NULL; | char * charVLA = NULL; | |||
std::swap(charVLA, exporter->m_buffer); | std::swap(charVLA, exporter->m_buffer); | |||
delete exporter; | delete exporter; | |||
return charVLA; | return charVLA; | |||
} | } | |||
/*========================================================================*/ | /*========================================================================*/ | |||
#ifndef _PYMOL_NOPY | #ifndef _PYMOL_NOPY | |||
/* | /* | |||
* See MoleculeExporterGetPyBonds | ||||
*/ | ||||
struct MoleculeExporterPyBonds : public MoleculeExporter { | ||||
PyObject *m_bond_list; // out | ||||
protected: | ||||
int getMultiDefault() const { | ||||
// single-entry format | ||||
return cMolExportGlobal; | ||||
} | ||||
void writeAtom() {} | ||||
void writeBonds() { | ||||
size_t nBond = m_bonds.size(); | ||||
m_bond_list = PyList_New(nBond); | ||||
for (size_t b = 0; b < nBond; ++b) { | ||||
const auto& bond = m_bonds[b]; | ||||
PyList_SetItem(m_bond_list, b, Py_BuildValue("iii", | ||||
bond.id1 - 1, bond.id2 - 1, bond.ref->order)); | ||||
} | ||||
m_bonds.clear(); | ||||
} | ||||
}; | ||||
/*========================================================================*/ | ||||
/* | ||||
* Get all bonds within the given selection. | ||||
* | ||||
* Returns a list of (atm1, atm2, order) tuples, where atm1 and atm2 are | ||||
* the 0-based atom indices within the selection. | ||||
* | ||||
* Return value: New reference | ||||
*/ | ||||
PyObject *MoleculeExporterGetPyBonds(PyMOLGlobals * G, | ||||
const char *selection, int state) | ||||
{ | ||||
SelectorTmp tmpsele1(G, selection); | ||||
int sele = tmpsele1.getIndex(); | ||||
if (sele < 0) | ||||
return NULL; | ||||
int unblock = PAutoBlock(G); | ||||
MoleculeExporterPyBonds exporter; | ||||
exporter.init(G); | ||||
exporter.execute(sele, state); | ||||
if (PyErr_Occurred()) | ||||
PyErr_Print(); | ||||
PAutoUnblock(G, unblock); | ||||
return exporter.m_bond_list; | ||||
} | ||||
/*========================================================================*/ | ||||
/* | ||||
* Creates a `chempy.models.Indexed` instance from a selection. | * Creates a `chempy.models.Indexed` instance from a selection. | |||
* | * | |||
* Changes from the old implementation (SelectorGetChemPyModel): | * Changes from the old implementation (SelectorGetChemPyModel): | |||
* - drops support for `cs->Spheroid` | * - drops support for `cs->Spheroid` | |||
* | * | |||
*/ | */ | |||
struct MoleculeExporterChemPy : public MoleculeExporter { | struct MoleculeExporterChemPy : public MoleculeExporter { | |||
PyObject *m_model; // out | PyObject *m_model; // out | |||
protected: | protected: | |||
End of changes. 14 change blocks. | ||||
5 lines changed or deleted | 145 lines changed or added |