Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <vlCore/DiskFile.hpp>
00033 #include <vlCore/MemoryFile.hpp>
00034 #include <vlMolecule/Molecule.hpp>
00035 #include <vlMolecule/RingExtractor.hpp>
00036 #include <vlCore/TextStream.hpp>
00037 #include <vlGraphics/Effect.hpp>
00038 #include <vlGraphics/Scissor.hpp>
00039 #include <vlGraphics/Texture.hpp>
00040 #include <vlCore/Image.hpp>
00041 #include <stdio.h>
00042
00043 using namespace vl;
00044
00045
00046 namespace
00047 {
00048 ref<Molecule> parseStructure(TextStream& text_stream)
00049 {
00050 #define NAME_CHAR_COUNT 128
00051
00052 ref<Molecule> structure = new Molecule;
00053 std::string line;
00054
00055
00056 bool mol2_start = false;
00057 while(text_stream.readLine(line))
00058 {
00059 if ( strstr(line.c_str(), "@<TRIPOS>MOLECULE") )
00060 {
00061 mol2_start = true;
00062 break;
00063 }
00064 }
00065 if (!mol2_start)
00066 return NULL;
00067
00068
00069 text_stream.readLine(line);
00070 structure->setMoleculeName( String::trimStdString(line).c_str() );
00071
00072
00073 while(text_stream.readLine(line) && !strstr(line.c_str(), "@<TRIPOS>ATOM")) { }
00074
00075
00076 char atom_name[NAME_CHAR_COUNT];
00077 char atom_type[NAME_CHAR_COUNT];
00078 while(text_stream.readLine(line) && !strstr(line.c_str(), "@<TRIPOS>BOND"))
00079 {
00080 fvec3 pos;
00081 int id = 0;
00082 int tokens = sscanf(line.c_str(), "%d %s %f %f %f %s", &id, atom_name, &pos.x(), &pos.y(), &pos.z(), atom_type);
00083
00084 atom_name[NAME_CHAR_COUNT-1] = 0;
00085 atom_type[NAME_CHAR_COUNT-1] = 0;
00086 if (tokens != 6)
00087 continue;
00088
00089 ref<Atom> atom = new Atom;
00090 atom->setCoordinates( pos );
00091 atom->setAtomName( atom_name );
00092
00093
00094 char* ch = strstr(atom_type, ".");
00095 if ( ch != NULL )
00096 *ch = 0;
00097 EAtomType atype = atomType(atom_type);
00098 if (atype==AT_Unknown)
00099 atype=atomType(atom_name);
00100 atom->setAtomType( atype );
00101 structure->addAtom( atom.get() );
00102 }
00103
00104
00105 char bond_type[NAME_CHAR_COUNT];
00106 unsigned bond_atom1;
00107 unsigned bond_atom2;
00108 while(text_stream.readLine(line))
00109 {
00110 if ( strstr(line.c_str(), "@<TRIPOS>") )
00111 {
00112 text_stream.ungetLine(line);
00113 break;
00114 }
00115 int id = 0;
00116 int tokens = sscanf(line.c_str(), "%d %d %d %s", &id, &bond_atom1, &bond_atom2, bond_type);
00117
00118 bond_type[NAME_CHAR_COUNT-1] = 0;
00119 if (tokens != 4)
00120 continue;
00121 --bond_atom1;
00122 --bond_atom2;
00123 if ( !(bond_atom1 < structure->atoms().size() && bond_atom2 < structure->atoms().size()) )
00124 {
00125 Log::error( Say("Bond indices out of range: a1 = %n, a2 = %n, atom count = %n.\n") << bond_atom1 << bond_atom2 << structure->atoms().size() );
00126 continue;
00127 }
00128 VL_CHECK( bond_atom1 < structure->atoms().size() )
00129 VL_CHECK( bond_atom2 < structure->atoms().size() )
00130 ref<Bond> bond = new Bond;
00131 bond->setAtom1( structure->atom(bond_atom1) );
00132 bond->setAtom2( structure->atom(bond_atom2) );
00133 bond->setBondType( BT_None );
00134 if (bond_type[0] == '1') bond->setBondType( BT_Single );
00135 if (bond_type[0] == '2') bond->setBondType( BT_Double );
00136 if (bond_type[0] == '3') bond->setBondType( BT_Triple );
00137 if (strstr(bond_type, "ar")) bond->setBondType( BT_Aromatic );
00138 if (strstr(bond_type, "am")) bond->setBondType( BT_Amide );
00139 if (strstr(bond_type, "du")) bond->setBondType( BT_Dummy );
00140 if (strstr(bond_type, "un")) bond->setBondType( BT_Unknown );
00141 if (bond->bondType() == BT_Aromatic)
00142 {
00143 bond->setUseAtomColors(false);
00144 bond->setColor(fvec4(0,1.0f,0,1.0f));
00145 }
00146 else
00147 bond->setUseAtomColors(true);
00148
00149 structure->addBond( bond.get() );
00150 }
00151
00152
00153 structure->setCovalentAtomRadii();
00154
00155
00156 structure->setCPKAtomColors();
00157
00158
00159 structure->computeAtomAdjacency();
00160
00161
00162 RingExtractor ring_extractor(structure.get());
00163 ring_extractor.run();
00164 return structure;
00165 }
00166 }
00167
00168 bool vl::loadMOL2(const String& path, std::vector< ref<Molecule> >& structures)
00169 {
00170 ref<VirtualFile> dfile = locateFile(path);
00171 ref<MemoryFile> mfile = new MemoryFile;
00172 mfile->copy(dfile.get());
00173 if (!mfile->open(OM_ReadOnly))
00174 {
00175 Log::error( Say("Error opening file %s.\n") << path );
00176 return false;
00177 }
00178 return loadMOL2(mfile.get(), structures);
00179 }
00180
00181 bool vl::loadMOL2(VirtualFile* vfile, std::vector< ref<Molecule> >& structures)
00182 {
00183 structures.clear();
00184
00185 TextStream text_stream;
00186 text_stream.setInputFile(vfile);
00187 std::string line;
00188
00189
00190 bool is_mol2 = false;
00191 while(text_stream.readLine(line))
00192 {
00193 const char* pos = strstr(line.c_str(), "@<TRIPOS>MOLECULE");
00194 if ( pos && line == pos )
00195 {
00196 is_mol2 = true;
00197 break;
00198 }
00199 }
00200 if ( !is_mol2 )
00201 {
00202 Log::error( Say("Invalid structure file: %s\n") << vfile->path() );
00203 vfile->close();
00204 return false;
00205 }
00206 text_stream.seek(0);
00207
00208
00209 ref<Molecule> structure;
00210 while( (structure = parseStructure(text_stream) ) )
00211 {
00212 if (structure->atoms().size())
00213 {
00214 structures.push_back(structure);
00215 structure->tags()->set("MultiMol2Index") = Say("%n") << structures.size() - 1;
00216 structure->tags()->set("FilePath") = vfile->path();
00217 }
00218 }
00219
00220 vfile->close();
00221 return true;
00222 }
00223