Coverage Report

Created: 2026-09-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openbabel/src/formats/carformat.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
Some portions Copyright (C) 2013 by Schrodinger Inc.
6
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation version 2 of the License.
10
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
***********************************************************************/
16
#include <openbabel/babelconfig.h>
17
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
#include <cstdlib>
24
25
26
using namespace std;
27
namespace OpenBabel
28
{
29
30
  class CARFormat : public OBMoleculeFormat
31
  {
32
  public:
33
    //Register this format type ID
34
    CARFormat()
35
12
    {
36
12
      OBConversion::RegisterFormat("car",this, "chemical/x-msi-car");
37
12
      OBConversion::RegisterFormat("arc",this, "chemical/x-msi-car");
38
12
    }
39
40
    const char* Description() override  // required
41
0
    {
42
0
      return
43
0
        "Accelrys/MSI Biosym/Insight II CAR 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
0
    const char* SpecificationURL() override {
50
0
      return "http://www.centrcn.umontreal.ca/accelrys/life/insight2000.1/formats980/Files980TOC.doc.html"; // XXX dead
51
0
    }
52
53
    const char* GetMIMEType() override
54
0
    { return "chemical/x-msi-car"; }
55
56
    unsigned int Flags() override
57
26
    {
58
26
      return NOTWRITABLE;
59
26
    }
60
61
    ////////////////////////////////////////////////////
62
    /// The "API" interface functions
63
    bool ReadMolecule(OBBase* pOb, OBConversion* pConv) override;
64
  };
65
66
  //Make an instance of the format class
67
  CARFormat theCARFormat;
68
69
  /////////////////////////////////////////////////////////////////
70
  bool CARFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
71
0
  {
72
73
0
    OBMol* pmol = pOb->CastAndClear<OBMol>();
74
0
    if (pmol == nullptr)
75
0
      return false;
76
77
    //Define some references so we can use the old parameter names
78
0
    istream &ifs = *pConv->GetInStream();
79
0
    OBMol &mol = *pmol;
80
0
    const char* title = pConv->GetTitle();
81
82
0
    bool hasPartialCharges = false;
83
0
    char buffer[BUFF_SIZE];
84
0
    string str;
85
0
    double x,y,z;
86
0
    OBAtom *atom;
87
0
    vector<string> vs;
88
89
0
    mol.BeginModify();
90
91
0
    while (ifs.getline(buffer,BUFF_SIZE))
92
0
      {
93
0
        if(strstr(buffer, "end") != nullptr)
94
0
          {
95
0
            if (mol.NumAtoms() > 0) // we've already read in a molecule, so exit
96
0
              break;
97
            // else, we hit the end of the previous molecular system
98
            // (in a multimolecule file)
99
0
            ifs.getline(buffer,BUFF_SIZE); // title
100
0
            ifs.getline(buffer,BUFF_SIZE); // DATE
101
0
          }
102
103
0
        if (strncmp(buffer, "!BIOSYM", 7) == 0)
104
0
          {
105
0
            continue;
106
0
          }
107
108
0
        if (strstr(buffer, "PBC") != nullptr)
109
0
          {
110
0
            if (strstr(buffer, "ON") != nullptr)
111
0
              {
112
0
                ifs.getline(buffer,BUFF_SIZE); // title
113
0
                ifs.getline(buffer,BUFF_SIZE); // DATE
114
0
                ifs.getline(buffer,BUFF_SIZE); // PBC a b c alpha beta gamma SG
115
116
0
                string str = buffer;
117
                // parse cell parameters
118
0
                tokenize(vs,str," \t\r\n", 7);
119
0
                if (vs.size() >= 7)
120
0
                  {
121
                    //parse cell values
122
0
                    double A,B,C,Alpha,Beta,Gamma;
123
0
                    A = atof((char*)vs[1].c_str());
124
0
                    B = atof((char*)vs[2].c_str());
125
0
                    C = atof((char*)vs[3].c_str());
126
0
                    Alpha = atof((char*)vs[4].c_str());
127
0
                    Beta  = atof((char*)vs[5].c_str());
128
0
                    Gamma = atof((char*)vs[6].c_str());
129
0
                    OBUnitCell *uc = new OBUnitCell;
130
0
                    uc->SetOrigin(fileformatInput);
131
0
                    uc->SetData(A, B, C, Alpha, Beta, Gamma);
132
0
                    if(vs.size() > 7) 
133
0
                      {
134
0
                        string& space_group = vs[7];
135
136
                        // Remove parentheses enclosing the space
137
                        // group and remove white space from front
138
                        // and back of string.
139
0
                        Trim(space_group);
140
0
                        if(space_group[0] == '(')
141
0
                          {
142
0
                            space_group.erase(0, 1);
143
0
                            space_group.erase(space_group.size()-1); 
144
0
                          }
145
0
                        Trim(space_group);
146
147
0
                        uc->SetSpaceGroup(space_group);
148
0
                      }
149
0
                    mol.SetData(uc);
150
0
                  }
151
0
              }
152
0
            else // PBC=OFF
153
0
              {
154
0
                ifs.getline(buffer,BUFF_SIZE); // title
155
0
                ifs.getline(buffer,BUFF_SIZE); // !DATE
156
0
              }
157
0
            continue;
158
0
          } // PBC
159
160
        // reading real data!
161
0
        tokenize(vs,buffer);
162
0
        if (vs.size() < 8) {
163
0
          break;
164
0
        }
165
166
0
        atom = mol.NewAtom();
167
168
0
        atom->SetAtomicNum(OBElements::GetAtomicNum(vs[7].c_str()));
169
0
        x = atof((char*)vs[1].c_str());
170
0
        y = atof((char*)vs[2].c_str());
171
0
        z = atof((char*)vs[3].c_str());
172
0
        atom->SetVector(x,y,z);
173
174
        // vs[0] contains atom label
175
        // vs[4] contains "type of residue containing atom"
176
        // vs[5] contains "residue sequence name"
177
        // vs[6] contains "potential type of atom"
178
179
0
        if (vs.size() == 9)
180
0
          {
181
0
            atom->SetPartialCharge(atof((char*)vs[8].c_str()));
182
0
            hasPartialCharges = true;
183
0
          }
184
0
      }
185
186
0
    if (!pConv->IsOption("b",OBConversion::INOPTIONS))
187
0
      mol.ConnectTheDots();
188
0
    if (!pConv->IsOption("s",OBConversion::INOPTIONS) && !pConv->IsOption("b",OBConversion::INOPTIONS))
189
0
      mol.PerceiveBondOrders();
190
191
0
    mol.EndModify();
192
0
    if (hasPartialCharges)
193
0
      mol.SetPartialChargesPerceived();
194
0
    mol.SetTitle(title);
195
0
    return(true);
196
0
  }
197
198
} //namespace OpenBabel