Coverage Report

Created: 2025-12-14 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openbabel/src/formats/unichemformat.cpp
Line
Count
Source
1
/**********************************************************************
2
Copyright (C) 2000 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
22
#include <cstdlib>
23
24
using namespace std;
25
namespace OpenBabel
26
{
27
28
class UniChemFormat : public OBMoleculeFormat
29
{
30
public:
31
    //Register this format type ID
32
    UniChemFormat()
33
6
    {
34
6
        OBConversion::RegisterFormat("unixyz",this);
35
6
    }
36
37
  const char* Description() override  // required
38
0
  {
39
0
    return
40
0
      "UniChem XYZ format\n"
41
0
      "Read Options e.g. -as\n"
42
0
      " s  Output single bonds only\n"
43
0
      " b  Disable bonding entirely\n\n";
44
0
  }
45
46
    const char* SpecificationURL() override
47
0
    { return ""; }  // optional
48
49
    //Flags() can return be any the following combined by | or be omitted if none apply
50
    // NOTREADABLE  READONEONLY  NOTWRITABLE  WRITEONEONLY
51
    unsigned int Flags() override
52
6
    {
53
6
      return READONEONLY | WRITEONEONLY;
54
6
    }
55
56
    //*** This section identical for most OBMol conversions ***
57
    ////////////////////////////////////////////////////
58
    /// The "API" interface functions
59
    bool ReadMolecule(OBBase* pOb, OBConversion* pConv) override;
60
    bool WriteMolecule(OBBase* pOb, OBConversion* pConv) override;
61
};
62
//***
63
64
//Make an instance of the format class
65
UniChemFormat theUniChemFormat;
66
67
/////////////////////////////////////////////////////////////////
68
bool UniChemFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
69
0
{
70
71
0
    OBMol* pmol = pOb->CastAndClear<OBMol>();
72
0
    if (pmol == nullptr)
73
0
        return false;
74
75
    //Define some references so we can use the old parameter names
76
0
    istream &ifs = *pConv->GetInStream();
77
0
    OBMol &mol = *pmol;
78
0
    const char* title = pConv->GetTitle();
79
80
0
    int i;
81
0
    int natoms;
82
0
    char buffer[BUFF_SIZE];
83
84
0
    ifs.getline(buffer,BUFF_SIZE);
85
0
    ifs.getline(buffer,BUFF_SIZE);
86
0
    sscanf(buffer,"%d", &natoms);
87
0
    if (!natoms)
88
0
        return(false);
89
90
0
    mol.ReserveAtoms(natoms);
91
0
    mol.BeginModify();
92
93
0
    string str;
94
0
    double x,y,z;
95
0
    OBAtom *atom;
96
0
    vector<string> vs;
97
98
0
    for (i = 1; i <= natoms; i ++)
99
0
    {
100
0
        if (!ifs.getline(buffer,BUFF_SIZE))
101
0
            return(false);
102
0
        tokenize(vs,buffer);
103
0
        if (vs.size() != 4)
104
0
            return(false);
105
0
        atom = mol.NewAtom();
106
0
        x = atof((char*)vs[1].c_str());
107
0
        y = atof((char*)vs[2].c_str());
108
0
        z = atof((char*)vs[3].c_str());
109
0
        atom->SetVector(x,y,z); //set coordinates
110
111
        //set atomic number
112
0
        atom->SetAtomicNum(atoi((char*)vs[0].c_str()));
113
0
    }
114
0
    if (!pConv->IsOption("b",OBConversion::INOPTIONS))
115
0
      mol.ConnectTheDots();
116
0
    if (!pConv->IsOption("s",OBConversion::INOPTIONS) && !pConv->IsOption("b",OBConversion::INOPTIONS))
117
0
      mol.PerceiveBondOrders();
118
119
    // clean out remaining blank lines
120
0
    std::streampos ipos;
121
0
    do
122
0
    {
123
0
      ipos = ifs.tellg();
124
0
      ifs.getline(buffer,BUFF_SIZE);
125
0
    }
126
0
    while(strlen(buffer) == 0 && !ifs.eof() );
127
0
    ifs.seekg(ipos);
128
129
0
    mol.EndModify();
130
0
    mol.SetTitle(title);
131
0
    return(true);
132
0
}
133
134
////////////////////////////////////////////////////////////////
135
136
bool UniChemFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
137
0
{
138
0
    OBMol* pmol = dynamic_cast<OBMol*>(pOb);
139
0
    if (pmol == nullptr)
140
0
        return false;
141
142
    //Define some references so we can use the old parameter names
143
0
    ostream &ofs = *pConv->GetOutStream();
144
0
    OBMol &mol = *pmol;
145
146
0
    unsigned int i;
147
0
    char buffer[BUFF_SIZE];
148
149
0
    ofs << mol.GetTitle() << endl;
150
0
    ofs << mol.NumAtoms() << endl;
151
152
0
    OBAtom *atom;
153
0
    string str,str1;
154
0
    for(i = 1;i <= mol.NumAtoms(); i++)
155
0
    {
156
0
        atom = mol.GetAtom(i);
157
0
        snprintf(buffer, BUFF_SIZE,
158
0
    "%3d%15.5f%15.5f%15.5f",
159
0
                atom->GetAtomicNum(),
160
0
                atom->GetX(),
161
0
                atom->GetY(),
162
0
                atom->GetZ());
163
0
        ofs << buffer << endl;
164
0
    }
165
166
0
    return(true);
167
0
}
168
169
} //namespace OpenBabel