Coverage Report

Created: 2025-10-28 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openbabel/src/formats/featformat.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 <openbabel/obutil.h>
22
23
using namespace std;
24
namespace OpenBabel
25
{
26
27
  class FEATFormat : public OBMoleculeFormat
28
  {
29
  public:
30
    //Register this format type ID
31
    FEATFormat()
32
6
    {
33
6
      OBConversion::RegisterFormat("feat",this);
34
6
    }
35
36
    const char* Description() override  // required
37
0
    {
38
0
      return
39
0
        "Feature 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
46
0
    { return ""; }  // optional
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
  FEATFormat theFEATFormat;
65
66
  /////////////////////////////////////////////////////////////////
67
  bool FEATFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
68
0
  {
69
70
0
    OBMol* pmol = pOb->CastAndClear<OBMol>();
71
0
    if (pmol == nullptr)
72
0
      return false;
73
74
    //Define some references so we can use the old parameter names
75
0
    istream &ifs = *pConv->GetInStream();
76
0
    OBMol &mol = *pmol;
77
0
    mol.SetTitle( pConv->GetTitle()); //default title is the filename
78
79
0
    char buffer[BUFF_SIZE];
80
0
    int i,natoms;
81
82
0
    ifs.getline(buffer,BUFF_SIZE);
83
0
    sscanf(buffer,"%d",&natoms);
84
85
0
    mol.ReserveAtoms(natoms);
86
0
    mol.BeginModify();
87
88
0
    if (!ifs.getline(buffer,BUFF_SIZE))
89
0
      return(false);
90
0
    mol.SetTitle(buffer);
91
92
0
    double x,y,z;
93
0
    char type[32];
94
0
    OBAtom *atom;
95
0
    for (i = 0; i < natoms;i++)
96
0
      {
97
0
        if (!ifs.getline(buffer,BUFF_SIZE))
98
0
          return(false);
99
0
        sscanf(buffer,"%30s %lf %lf %lf",
100
0
               type,
101
0
               &x,
102
0
               &y,
103
0
               &z);
104
0
        CleanAtomType(type);
105
0
        atom = mol.NewAtom();
106
0
        atom->SetVector(x,y,z);
107
0
        atom->SetAtomicNum(OBElements::GetAtomicNum(type));
108
0
      }
109
110
    // clean out remaining blank lines
111
0
    std::streampos ipos;
112
0
    do
113
0
    {
114
0
      ipos = ifs.tellg();
115
0
      ifs.getline(buffer,BUFF_SIZE);
116
0
    }
117
0
    while(strlen(buffer) == 0 && !ifs.eof() );
118
0
    ifs.seekg(ipos);
119
120
0
    if (!pConv->IsOption("b",OBConversion::INOPTIONS))
121
0
      mol.ConnectTheDots();
122
0
    if (!pConv->IsOption("s",OBConversion::INOPTIONS) && !pConv->IsOption("b",OBConversion::INOPTIONS))
123
0
      mol.PerceiveBondOrders();
124
125
0
    mol.EndModify();
126
0
    return(true);
127
0
  }
128
129
  ////////////////////////////////////////////////////////////////
130
131
  bool FEATFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
132
0
  {
133
0
    OBMol* pmol = dynamic_cast<OBMol*>(pOb);
134
0
    if (pmol == nullptr)
135
0
      return false;
136
137
    //Define some references so we can use the old parameter names
138
0
    ostream &ofs = *pConv->GetOutStream();
139
0
    OBMol &mol = *pmol;
140
141
0
    char buffer[BUFF_SIZE];
142
143
0
    ofs << mol.NumAtoms() << endl;
144
0
    ofs << mol.GetTitle() << endl;
145
146
0
    OBAtom *atom;
147
0
    vector<OBAtom*>::iterator i;
148
0
    for(atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
149
0
      {
150
0
        snprintf(buffer, BUFF_SIZE, "%-3s %8.5f  %8.5f  %8.5f ",
151
0
                 OBElements::GetSymbol(atom->GetAtomicNum()),
152
0
                 atom->x(),
153
0
                 atom->y(),
154
0
                 atom->z());
155
0
        ofs << buffer << endl;
156
0
      }
157
158
0
    return(true);
159
0
  }
160
161
} //namespace OpenBabel