Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
vlMOL2.cpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #include <vlCore/DiskFile.hpp>
33 #include <vlCore/MemoryFile.hpp>
34 #include <vlMolecule/Molecule.hpp>
36 #include <vlCore/TextStream.hpp>
37 #include <vlGraphics/Effect.hpp>
38 #include <vlGraphics/Scissor.hpp>
39 #include <vlGraphics/Texture.hpp>
40 #include <vlCore/Image.hpp>
41 #include <stdio.h>
42 
43 using namespace vl;
44 
45 //-----------------------------------------------------------------------------
46 namespace
47 {
48  ref<Molecule> parseStructure(TextStream& text_stream)
49  {
50  #define NAME_CHAR_COUNT 128
51 
52  ref<Molecule> structure = new Molecule;
53  std::string line;
54 
55  // find structure start
56  bool mol2_start = false;
57  while(text_stream.readLine(line))
58  {
59  if ( strstr(line.c_str(), "@<TRIPOS>MOLECULE") )
60  {
61  mol2_start = true;
62  break;
63  }
64  }
65  if (!mol2_start)
66  return NULL;
67 
68  // parse structure name
69  text_stream.readLine(line);
70  structure->setMoleculeName( String::trimStdString(line).c_str() );
71 
72  // skip lines until atom coordinates start
73  while(text_stream.readLine(line) && !strstr(line.c_str(), "@<TRIPOS>ATOM")) { /*skip lines*/ }
74 
75  // read atoms
76  char atom_name[NAME_CHAR_COUNT];
77  char atom_type[NAME_CHAR_COUNT];
78  while(text_stream.readLine(line) && !strstr(line.c_str(), "@<TRIPOS>BOND"))
79  {
80  fvec3 pos;
81  int id = 0;
82  int tokens = sscanf(line.c_str(), "%d %s %f %f %f %s", &id, atom_name, &pos.x(), &pos.y(), &pos.z(), atom_type);
83  // make sure they are zero-terminated.
84  atom_name[NAME_CHAR_COUNT-1] = 0;
85  atom_type[NAME_CHAR_COUNT-1] = 0;
86  if (tokens != 6)
87  continue;
88 
89  ref<Atom> atom = new Atom;
90  atom->setCoordinates( pos );
91  atom->setAtomName( atom_name );
92 
93  // detect atom type
94  char* ch = strstr(atom_type, ".");
95  if ( ch != NULL )
96  *ch = 0;
97  EAtomType atype = atomType(atom_type);
98  if (atype==AT_Unknown)
99  atype=atomType(atom_name);
100  atom->setAtomType( atype );
101  structure->addAtom( atom.get() );
102  }
103 
104  // read bonds
105  char bond_type[NAME_CHAR_COUNT];
106  unsigned bond_atom1;
107  unsigned bond_atom2;
108  while(text_stream.readLine(line))
109  {
110  if ( strstr(line.c_str(), "@<TRIPOS>") )
111  {
112  text_stream.ungetLine(line);
113  break;
114  }
115  int id = 0;
116  int tokens = sscanf(line.c_str(), "%d %d %d %s", &id, &bond_atom1, &bond_atom2, bond_type);
117  // make sure it is zero-terminated.
118  bond_type[NAME_CHAR_COUNT-1] = 0;
119  if (tokens != 4)
120  continue;
121  --bond_atom1;
122  --bond_atom2;
123  if ( !(bond_atom1 < structure->atoms().size() && bond_atom2 < structure->atoms().size()) )
124  {
125  Log::error( Say("Bond indices out of range: a1 = %n, a2 = %n, atom count = %n.\n") << bond_atom1 << bond_atom2 << structure->atoms().size() );
126  continue;
127  }
128  VL_CHECK( bond_atom1 < structure->atoms().size() )
129  VL_CHECK( bond_atom2 < structure->atoms().size() )
130  ref<Bond> bond = new Bond;
131  bond->setAtom1( structure->atom(bond_atom1) );
132  bond->setAtom2( structure->atom(bond_atom2) );
133  bond->setBondType( BT_None );
134  if (bond_type[0] == '1') bond->setBondType( BT_Single );
135  if (bond_type[0] == '2') bond->setBondType( BT_Double );
136  if (bond_type[0] == '3') bond->setBondType( BT_Triple );
137  if (strstr(bond_type, "ar")) bond->setBondType( BT_Aromatic );
138  if (strstr(bond_type, "am")) bond->setBondType( BT_Amide );
139  if (strstr(bond_type, "du")) bond->setBondType( BT_Dummy );
140  if (strstr(bond_type, "un")) bond->setBondType( BT_Unknown );
141  if (bond->bondType() == BT_Aromatic)
142  {
143  bond->setUseAtomColors(false);
144  bond->setColor(fvec4(0,1.0f,0,1.0f));
145  }
146  else
147  bond->setUseAtomColors(true);
148 
149  structure->addBond( bond.get() );
150  }
151 
152  // by default all the atom radii are set to be covalent
153  structure->setCovalentAtomRadii();
154 
155  // by default set cpk colors
156  structure->setCPKAtomColors();
157 
158  // compute adjacent atoms
159  structure->computeAtomAdjacency();
160 
161  // compute aromatic rings
162  RingExtractor ring_extractor(structure.get());
163  ring_extractor.run();
164  return structure;
165  }
166 }
167 //-----------------------------------------------------------------------------
168 bool vl::loadMOL2(const String& path, std::vector< ref<Molecule> >& structures)
169 {
170  ref<VirtualFile> dfile = locateFile(path);
171  ref<MemoryFile> mfile = new MemoryFile; // cache in the memory
172  mfile->copy(dfile.get());
173  if (!mfile->open(OM_ReadOnly))
174  {
175  Log::error( Say("Error opening file %s.\n") << path );
176  return false;
177  }
178  return loadMOL2(mfile.get(), structures);
179 }
180 //-----------------------------------------------------------------------------
181 bool vl::loadMOL2(VirtualFile* vfile, std::vector< ref<Molecule> >& structures)
182 {
183  structures.clear();
184 
185  TextStream text_stream;
186  text_stream.setInputFile(vfile);
187  std::string line;
188 
189  // detect tripos mol2 file
190  bool is_mol2 = false;
191  while(text_stream.readLine(line))
192  {
193  const char* pos = strstr(line.c_str(), "@<TRIPOS>MOLECULE");
194  if ( pos && line == pos )
195  {
196  is_mol2 = true;
197  break;
198  }
199  }
200  if ( !is_mol2 )
201  {
202  Log::error( Say("Invalid structure file: %s\n") << vfile->path() );
203  vfile->close();
204  return false;
205  }
206  text_stream.seek(0);
207 
208  // extract multi-mol2 structures
209  ref<Molecule> structure;
210  while( (structure = parseStructure(text_stream) ) )
211  {
212  if (structure->atoms().size())
213  {
214  structures.push_back(structure);
215  structure->tags()->set("MultiMol2Index") = Say("%n") << structures.size() - 1;
216  structure->tags()->set("FilePath") = vfile->path();
217  }
218  }
219 
220  vfile->close();
221  return true;
222 }
223 //-----------------------------------------------------------------------------
The Molecule class is used to manage and render 3D molecular structures.
Definition: Molecule.hpp:64
void addBond(Bond *bond)
Definition: Molecule.cpp:187
void setAtomName(const std::string &name)
Definition: Atom.hpp:115
const T * get() const
Definition: Object.hpp:128
An abstract class representing a file.
Definition: VirtualFile.hpp:60
bool readLine(std::string &utf8)
Definition: TextStream.hpp:67
Vector4< float > fvec4
A 4 components vector with float precision.
Definition: Vector4.hpp:279
void setCoordinates(const fvec3 &coordinates)
Definition: Atom.hpp:107
A simple String formatting class.
Definition: Say.hpp:124
The String class implements an advanced UTF16 (Unicode BMP) string manipulation engine.
Definition: String.hpp:62
const T_Scalar & z() const
Definition: Vector3.hpp:91
KeyValues * tags()
Definition: Molecule.hpp:82
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
Definition: Log.cpp:165
const std::vector< ref< Atom > > & atoms() const
Definition: Molecule.hpp:85
void setInputFile(VirtualFile *file)
virtual void close()=0
Closes the file.
const String & path() const
Returns the path of the file.
Definition: VirtualFile.hpp:98
void setMoleculeName(const String &name)
Definition: Molecule.hpp:76
Visualization Library main namespace.
void setUseAtomColors(bool use_atom_color)
Definition: Bond.hpp:91
The TextStream class can be used to conveniently read or parse utf8-encoded text files.
Definition: TextStream.hpp:46
A VirtualFile to manipulate files stored in memory.
Definition: MemoryFile.hpp:56
EAtomType atomType(const char *type)
Translates a string containing atom type name, atom symbol or a Sybyl type into an EAtomType...
const T_Scalar & y() const
Definition: Vector3.hpp:90
void seek(long long pos)
The RingExtractor class traverses a molecule&#39;s graph and detects various types of cycles...
#define NULL
Definition: OpenGLDefs.hpp:81
void setCovalentAtomRadii(float percentage=1.0f)
Sets all the atoms&#39; radii to their covalent atom radii.
Definition: Molecule.cpp:267
#define NAME_CHAR_COUNT
virtual bool open(EOpenMode mode)
Opens the file in the specified mode.
Definition: MemoryFile.cpp:47
void setAtomType(EAtomType type)
Definition: Atom.hpp:101
VLCORE_EXPORT ref< VirtualFile > locateFile(const String &path)
Utility function, equivalent to vl::defFileSystem()->locateFile(path)
Definition: VirtualFile.cpp:41
static std::string trimStdString(const std::string &text)
Remove the spaces before and after an std::string.
Definition: String.cpp:1471
void computeAtomAdjacency()
Definition: Molecule.cpp:224
void setCPKAtomColors()
Sets all the atoms&#39; color to their CPK color.
Definition: Molecule.cpp:243
void addAtom(Atom *atom)
Definition: Molecule.cpp:119
const T_Scalar & x() const
Definition: Vector3.hpp:89
The Bond class represents a bond to be used with the Molecule class.
Definition: Bond.hpp:62
EAtomType
Element types.
void ungetLine(const std::string &utf8)
Definition: TextStream.hpp:61
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
The Atom class represents an atom to be used with the Molecule class.
Definition: Atom.hpp:51
String & set(const String &key)
Definition: KeyValues.hpp:53
VLMOLECULE_EXPORT bool loadMOL2(const String &path, std::vector< ref< Molecule > > &structures)
Loads a Tripos MOL2 file.
Definition: vlMOL2.cpp:168
#define VL_CHECK(expr)
Definition: checks.hpp:73
void copy(VirtualFile *file)
Copies the data of any kind of VirtualFile.
Definition: MemoryFile.cpp:60