Coverage Report

Created: 2026-01-16 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openbabel/src/formats/boxformat.cpp
Line
Count
Source
1
/**********************************************************************
2
Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
3
Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison
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 BoxFormat : public OBMoleculeFormat
28
{
29
public:
30
    //Register this format type ID
31
    BoxFormat()
32
6
    {
33
6
        OBConversion::RegisterFormat("box",this);
34
6
    }
35
36
  const char* Description() override  // required
37
0
  {
38
0
    return
39
0
      "Dock 3.5 Box format\n"
40
0
      "No comments yet\n";
41
0
  }
42
43
  const char* SpecificationURL() override
44
0
  { return "http://dock.compbio.ucsf.edu/"; }  // optional
45
46
    //Flags() can return be any the following combined by | or be omitted if none apply
47
    // NOTREADABLE  READONEONLY  NOTWRITABLE  WRITEONEONLY
48
    unsigned int Flags() override
49
6
    {
50
6
        return READONEONLY | WRITEONEONLY;
51
6
    }
52
53
    //*** This section identical for most OBMol conversions ***
54
    ////////////////////////////////////////////////////
55
    /// The "API" interface functions
56
    bool ReadMolecule(OBBase* pOb, OBConversion* pConv) override;
57
    bool WriteMolecule(OBBase* pOb, OBConversion* pConv) override;
58
};
59
//***
60
61
//Make an instance of the format class
62
BoxFormat theBoxFormat;
63
64
/////////////////////////////////////////////////////////////////
65
bool BoxFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
66
0
{
67
68
0
    OBMol* pmol = pOb->CastAndClear<OBMol>();
69
0
    if (pmol == nullptr)
70
0
        return false;
71
72
    //Define some references so we can use the old parameter names
73
0
    istream &ifs = *pConv->GetInStream();
74
0
    OBMol &mol = *pmol;
75
0
    const char* title = pConv->GetTitle();
76
77
0
    char buffer[BUFF_SIZE];
78
0
    vector<string> vs;
79
0
    vector<string>::iterator i;
80
0
    OBAtom atom;
81
82
0
    mol.BeginModify();
83
84
0
    while (ifs.getline(buffer,BUFF_SIZE) && !EQn(buffer,"END",3))
85
0
    {
86
0
        if (EQn(buffer,"ATOM",4))
87
0
        {
88
0
            string sbuf = &buffer[6];
89
            /* X, Y, Z */
90
0
            string x = sbuf.substr(24,8);
91
0
            string y = sbuf.substr(32,8);
92
0
            string z = sbuf.substr(40,8);
93
0
            vector3 v(atof(x.c_str()),atof(y.c_str()),atof(z.c_str()));
94
0
            atom.SetVector(v);
95
0
            if (!mol.AddAtom(atom))
96
0
                return(false);
97
0
        }
98
99
0
        if (EQn(buffer,"CONECT",6))
100
0
        {
101
0
            tokenize(vs,buffer);
102
0
            if (!vs.empty() && vs.size() > 2)
103
0
                for (i = vs.begin(),i+=2;i != vs.end();++i)
104
0
                    mol.AddBond(atoi(vs[1].c_str()),atoi((*i).c_str()),1);
105
0
        }
106
0
    }
107
108
0
    mol.EndModify();
109
0
    mol.SetTitle(title);
110
0
    return(true);
111
0
}
112
113
////////////////////////////////////////////////////////////////
114
115
bool BoxFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
116
0
{
117
0
    OBMol* pmol = dynamic_cast<OBMol*>(pOb);
118
0
    if (pmol == nullptr)
119
0
        return false;
120
121
    //Define some references so we can use the old parameter names
122
0
    ostream &ofs = *pConv->GetOutStream();
123
0
    OBMol &mol = *pmol;
124
125
    //margin hardwired in new framework. Also was in old fileformat
126
0
    double margin=1.0;
127
128
0
    char buffer[BUFF_SIZE];
129
0
    vector3 vcenter,vmin,vmax,vmid,vdim;
130
131
0
    OBAtom *atom;
132
0
    vector<OBAtom*>::iterator i;
133
0
    vmax.Set(-10E10,-10E10,-10E10);
134
0
    vmin.Set( 10E10, 10E10, 10E10);
135
136
0
    for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
137
0
    {
138
0
        vcenter += atom->GetVector();
139
0
        if (atom->x() < vmin.x())
140
0
            vmin.SetX(atom->x());
141
0
        if (atom->y() < vmin.y())
142
0
            vmin.SetY(atom->y());
143
0
        if (atom->z() < vmin.z())
144
0
            vmin.SetZ(atom->z());
145
146
0
        if (atom->x() > vmax.x())
147
0
            vmax.SetX(atom->x());
148
0
        if (atom->y() > vmax.y())
149
0
            vmax.SetY(atom->y());
150
0
        if (atom->z() > vmax.z())
151
0
            vmax.SetZ(atom->z());
152
0
    }
153
0
    vcenter /= (double)mol.NumAtoms();
154
155
0
    vector3 vmarg(margin,margin,margin);
156
0
    vmin -= vmarg;
157
0
    vmax += vmarg;
158
0
    vdim = vmax - vmin;
159
0
    vmid = vmin+vmax;
160
0
    vmid /= 2.0;
161
162
0
    ofs << "HEADER    CORNERS OF BOX" << endl;
163
0
    snprintf(buffer, BUFF_SIZE, "REMARK    CENTER (X Y Z)      %10.3f %10.3f %10.3f",
164
0
            vmid.x(),vmid.y(),vmid.z());
165
0
    ofs << buffer << endl;
166
0
    snprintf(buffer, BUFF_SIZE, "REMARK    DIMENSIONS (X Y Z)  %10.3f %10.3f %10.3f",
167
0
            vdim.x(),vdim.y(),vdim.z());
168
0
    ofs << buffer << endl;
169
0
    vdim /= 2.0;
170
171
0
    vector3 vtmp;
172
0
    int j;
173
0
    for (j = 1;j <= 8;j++)
174
0
    {
175
0
        switch(j)
176
0
        {
177
0
        case 1:
178
0
            vtmp = vmid-vdim;
179
0
            break;
180
0
        case 2:
181
0
            vtmp.SetX(vmid.x()+vdim.x());
182
0
            break;
183
0
        case 3:
184
0
            vtmp.SetZ(vmid.z()+vdim.z());
185
0
            break;
186
0
        case 4:
187
0
            vtmp.SetX(vmid.x()-vdim.x());
188
0
            break;
189
0
        case 5:
190
0
            vtmp = vmid-vdim;
191
0
            vtmp.SetY(vmid.y()+vdim.y());
192
0
            break;
193
0
        case 6:
194
0
            vtmp = vmid+vdim;
195
0
            vtmp.SetZ(vmid.z()-vdim.z());
196
0
            break;
197
0
        case 7:
198
0
            vtmp = vmid+vdim;
199
0
            break;
200
0
        case 8:
201
0
            vtmp.SetX(vmid.x()-vdim.x());
202
0
            break;
203
0
        }
204
0
        snprintf(buffer, BUFF_SIZE, "ATOM      %d  DUA BOX     1    %8.3f%8.3f%8.3f",
205
0
                j,vtmp.x(),vtmp.y(),vtmp.z());
206
0
        ofs << buffer << endl;
207
0
    }
208
209
0
    ofs << "CONECT    1    2    4    5" << endl;
210
0
    ofs << "CONECT    2    1    3    6" << endl;
211
0
    ofs << "CONECT    3    2    4    7" << endl;
212
0
    ofs << "CONECT    4    1    3    8" << endl;
213
0
    ofs << "CONECT    5    1    6    8" << endl;
214
0
    ofs << "CONECT    6    2    5    7" << endl;
215
0
    ofs << "CONECT    7    3    6    8" << endl;
216
0
    ofs << "CONECT    8    4    5    7" << endl;
217
218
0
    return(true);
219
0
}
220
221
} //namespace OpenBabel