Coverage Report

Created: 2025-11-11 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openbabel/src/formats/shelxformat.cpp
Line
Count
Source
1
/**********************************************************************
2
Copyright (C) 1998-2003 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/math/matrix3x3.h>
18
#include <openbabel/obmolecformat.h>
19
#include <openbabel/mol.h>
20
#include <openbabel/atom.h>
21
#include <openbabel/elements.h>
22
#include <openbabel/generic.h>
23
24
#include <cstdlib>
25
26
using namespace std;
27
namespace OpenBabel
28
{
29
30
  class ShelXFormat : public OBMoleculeFormat
31
  {
32
  public:
33
    //Register this format type ID
34
    ShelXFormat()
35
6
    {
36
6
      OBConversion::RegisterFormat("res",this, "chemical/x-shelx");
37
6
      OBConversion::RegisterFormat("ins",this, "chemical/x-shelx");
38
6
    }
39
40
    const char* Description() override  // required
41
0
    {
42
0
      return
43
0
        "ShelX format\n"
44
0
        "Read Options e.g. -as\n"
45
0
        " s  Output single bonds only\n"
46
0
        " b  Disable bonding entirely\n\n";
47
0
    }
48
49
    const char* SpecificationURL() override
50
0
    { return "http://shelx.uni-ac.gwdg.de/SHELX/"; }  // optional
51
52
    const char* GetMIMEType() override
53
0
    { return "chemical/x-shelx"; }
54
55
    //Flags() can return be any the following combined by | or be omitted if none apply
56
    // NOTREADABLE  READONEONLY  NOTWRITABLE  WRITEONEONLY
57
    unsigned int Flags() override
58
43
    {
59
43
      return NOTWRITABLE;
60
43
    }
61
62
    ////////////////////////////////////////////////////
63
    /// The "API" interface functions
64
    bool ReadMolecule(OBBase* pOb, OBConversion* pConv) override;
65
66
  };
67
68
  //Make an instance of the format class
69
  ShelXFormat theShelXFormat;
70
71
  /////////////////////////////////////////////////////////////////
72
  bool ShelXFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
73
3
  {
74
75
3
    OBMol* pmol = pOb->CastAndClear<OBMol>();
76
3
    if (pmol == nullptr)
77
0
      return false;
78
79
    //Define some references so we can use the old parameter names
80
3
    istream &ifs = *pConv->GetInStream();
81
3
    OBMol &mol = *pmol;
82
3
    mol.SetTitle( pConv->GetTitle()); //default title is the filename
83
84
3
    char buffer[BUFF_SIZE];
85
    //  int natoms; CM
86
3
    double A,B,C,Alpha,Beta,Gamma;
87
3
    matrix3x3 m;
88
89
3
    ifs.getline(buffer,BUFF_SIZE);
90
3
    mol.SetTitle(buffer);
91
375
    while (ifs.getline(buffer,BUFF_SIZE) &&!EQn(buffer,"CELL",4))
92
372
      ;
93
94
3
    if (!EQn(buffer,"CELL",4))
95
3
      return(false);
96
0
    vector<string> vs;
97
0
    tokenize(vs,buffer," \n\t,");
98
0
    if (vs.size() != 8)
99
0
      return(false);
100
101
    //parse cell values
102
0
    A = atof((char*)vs[2].c_str());
103
0
    B = atof((char*)vs[3].c_str());
104
0
    C = atof((char*)vs[4].c_str());
105
0
    Alpha = atof((char*)vs[5].c_str());
106
0
    Beta  = atof((char*)vs[6].c_str());
107
0
    Gamma = atof((char*)vs[7].c_str());
108
0
    OBUnitCell *uc = new OBUnitCell;
109
0
    uc->SetOrigin(fileformatInput);
110
0
    uc->SetData(A, B, C, Alpha, Beta, Gamma);
111
0
    mol.SetData(uc);
112
113
    //  int i; CM
114
0
    double x,y,z;
115
0
    char type[16], *j;
116
0
    OBAtom *atom;
117
0
    vector3 v;
118
119
    //skip until FVAR found
120
0
    while (ifs.getline(buffer,BUFF_SIZE) &&!EQn(buffer,"FVAR",4))
121
0
      ;
122
123
0
    mol.BeginModify();
124
125
    //read atom records
126
0
    while (ifs.getline(buffer,BUFF_SIZE) &&!EQn(buffer,"HKLF",4))
127
0
      {
128
0
        tokenize(vs,buffer," \n\t,");
129
130
        //skip AFIX and PART instructions
131
0
        if (vs.size() < 7)
132
0
          continue;
133
0
        atom = mol.NewAtom();
134
135
0
        x = atof((char*)vs[2].c_str());
136
0
        y = atof((char*)vs[3].c_str());
137
0
        z = atof((char*)vs[4].c_str());
138
0
        v.Set(x,y,z);
139
0
        v = uc->FractionalToCartesian(v);
140
141
0
        strncpy(type,vs[0].c_str(), sizeof(type));
142
0
        type[sizeof(type) - 1] = '\0';
143
0
        j = strpbrk(type, "0123456789");
144
0
        j[0] = '\0';
145
0
        atom->SetAtomicNum(OBElements::GetAtomicNum(type));
146
0
        atom->SetVector(v);
147
148
        //skip next line if anisotropic atoms.
149
0
        if (vs.size() == 9)
150
0
          ifs.getline(buffer,BUFF_SIZE);
151
0
      } //while
152
153
0
    if (!pConv->IsOption("b",OBConversion::INOPTIONS))
154
0
      mol.ConnectTheDots();
155
0
    if (!pConv->IsOption("s",OBConversion::INOPTIONS) && !pConv->IsOption("b",OBConversion::INOPTIONS))
156
0
      mol.PerceiveBondOrders();
157
158
0
    mol.EndModify();
159
0
    return(true);
160
0
  }
161
162
} //namespace OpenBabel