Coverage Report

Created: 2026-02-26 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openbabel/src/formats/viewmolformat.cpp
Line
Count
Source
1
/**********************************************************************
2
Copyright (C) 2002-2006 by Geoffrey Hutchison
3
Based on code Copyright (C) 1999 Joerg-Ruediger Hill
4
Some portions Copyright (C) 2004 by Chris Morley
5
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation version 2 of the License.
9
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14
***********************************************************************/
15
#include <openbabel/babelconfig.h>
16
17
#include <openbabel/obmolecformat.h>
18
#include <openbabel/mol.h>
19
#include <openbabel/atom.h>
20
#include <openbabel/elements.h>
21
#include <cstdlib>
22
23
using namespace std;
24
namespace OpenBabel
25
{
26
27
class ViewMolFormat : public OBMoleculeFormat
28
{
29
public:
30
  //Register this format type ID
31
  ViewMolFormat()
32
6
  {
33
6
    OBConversion::RegisterFormat("vmol",this);
34
6
  }
35
36
  const char* Description() override  // required
37
0
  {
38
0
    return
39
0
      "ViewMol format\n"
40
0
      "Read Options e.g. -as\n"
41
0
      " s  Output single bonds only\n"
42
0
      " b  Disable bonding entirely\n\n";
43
0
  }
44
45
  const char* SpecificationURL() override  // optional
46
0
  { return "http://viewmol.sourceforge.net/"; }
47
48
    //Flags() can return be any the following combined by | or be omitted if none apply
49
    // NOTREADABLE  READONEONLY  NOTWRITABLE  WRITEONEONLY
50
    unsigned int Flags() override
51
6
    {
52
6
        return READONEONLY | WRITEONEONLY;
53
6
    }
54
55
    //*** This section identical for most OBMol conversions ***
56
    ////////////////////////////////////////////////////
57
    /// The "API" interface functions
58
    bool ReadMolecule(OBBase* pOb, OBConversion* pConv) override;
59
    bool WriteMolecule(OBBase* pOb, OBConversion* pConv) override;
60
};
61
//***
62
63
//Make an instance of the format class
64
ViewMolFormat theViewMolFormat;
65
66
/////////////////////////////////////////////////////////////////
67
bool ViewMolFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
68
0
{
69
0
    OBMol* pmol = pOb->CastAndClear<OBMol>();
70
0
    if (pmol == nullptr)
71
0
        return false;
72
73
    //Define some references so we can use the old parameter names
74
0
    istream &ifs = *pConv->GetInStream();
75
0
    OBMol &mol = *pmol;
76
0
    const char* title = pConv->GetTitle();
77
78
0
    char buffer[BUFF_SIZE];
79
0
    OBAtom *atom;
80
0
    double x,y,z, border;
81
0
    double factor = 1.0;
82
0
    int bgn, end, order;
83
0
    vector<string> vs;
84
0
    bool foundTitle = false;
85
0
    bool foundBonds = false;
86
87
0
    mol.Clear();
88
0
    mol.BeginModify();
89
90
0
    ifs.getline(buffer,BUFF_SIZE);
91
0
    while (ifs.peek() != EOF && ifs.good())
92
0
    {
93
0
        if (strstr(buffer, "$title") != nullptr)
94
0
        {
95
0
            if (!ifs.getline(buffer,BUFF_SIZE))
96
0
                return (false);
97
0
            mol.SetTitle(buffer);
98
0
            foundTitle = true;
99
0
      ifs.getline(buffer,BUFF_SIZE);
100
0
        }
101
0
        else if (strstr(buffer, "$coord") != nullptr)
102
0
        {
103
0
            tokenize(vs,buffer);
104
0
            if (vs.size() == 2)
105
0
                factor = atof((char*)vs[1].c_str()); // conversion to angstrom
106
0
            while (ifs.getline(buffer,BUFF_SIZE))
107
0
            {
108
109
0
                if (buffer[0] == '$')
110
0
                    break;
111
0
                tokenize(vs,buffer);
112
0
                if (vs.size() != 4)
113
0
      break;
114
0
                atom = mol.NewAtom();
115
0
                x = atof((char*)vs[0].c_str()) * factor;
116
0
                y = atof((char*)vs[1].c_str()) * factor;
117
0
                z = atof((char*)vs[2].c_str()) * factor;
118
0
                atom->SetVector(x,y,z); //set coordinates
119
0
                atom->SetAtomicNum(OBElements::GetAtomicNum(vs[3].c_str()));
120
0
            }
121
0
        }
122
0
        else if (strstr(buffer, "$bonds") != nullptr)
123
0
        {
124
0
            foundBonds = true;
125
0
            while (ifs.getline(buffer,BUFF_SIZE))
126
0
            {
127
0
                if (buffer[0] == '$')
128
0
                    break;
129
0
                sscanf(buffer,"%d %d %lf",&bgn,&end, &border);
130
0
                if (border > 1.0)
131
0
                    order = int(border);
132
0
                else
133
0
                    order = 1;
134
0
                mol.AddBond(bgn+1,end+1,order);
135
0
            }
136
0
        }
137
0
        else if (strstr(buffer, "$end") != nullptr)
138
0
    break;
139
0
  else // something else (i.e., garbage, blank lines, etc.)
140
0
    ifs.getline(buffer,BUFF_SIZE);
141
0
    } // while
142
143
0
    if (!foundBonds)
144
0
    {
145
0
      if (!pConv->IsOption("b",OBConversion::INOPTIONS))
146
0
  mol.ConnectTheDots();
147
0
      if (!pConv->IsOption("s",OBConversion::INOPTIONS) && !pConv->IsOption("b",OBConversion::INOPTIONS))
148
0
  mol.PerceiveBondOrders();
149
0
    }
150
151
0
    mol.EndModify();
152
153
0
    if (!foundTitle)
154
0
        mol.SetTitle(title);
155
0
    return(true);
156
0
}
157
158
////////////////////////////////////////////////////////////////
159
160
bool ViewMolFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
161
0
{
162
0
    OBMol* pmol = dynamic_cast<OBMol*>(pOb);
163
0
    if (pmol == nullptr)
164
0
        return false;
165
166
    //Define some references so we can use the old parameter names
167
0
    ostream &ofs = *pConv->GetOutStream();
168
0
    OBMol &mol = *pmol;
169
170
0
    unsigned int i;
171
0
    char buffer[BUFF_SIZE];
172
173
0
    if (strlen(mol.GetTitle()) > 0)
174
0
        ofs << "$title" << endl << mol.GetTitle() << endl;
175
176
0
    ofs << "$coord 1.0" << endl;
177
178
0
    OBAtom *atom;
179
0
    for(i = 1;i <= mol.NumAtoms(); i++)
180
0
    {
181
0
        atom = mol.GetAtom(i);
182
0
        snprintf(buffer, BUFF_SIZE, "%22.14f%22.14f%22.14f %s",
183
0
                atom->GetX(),
184
0
                atom->GetY(),
185
0
                atom->GetZ(),
186
0
                OBElements::GetSymbol(atom->GetAtomicNum()));
187
0
        ofs << buffer << endl;
188
0
    }
189
190
0
    ofs << "$end" << endl;
191
192
0
    return(true);
193
0
}
194
195
} //namespace OpenBabel