Coverage Report

Created: 2026-09-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openbabel/include/openbabel/stereo/squareplanar.h
Line
Count
Source
1
/**********************************************************************
2
  squareplanar.h - Class for handling and storing squareplanar stereochemistry.
3
4
  Copyright (C) 2009-2010 by Tim Vandermeersch
5
6
  This file is part of the Open Babel project.
7
  For more information, see <http://openbabel.org/>
8
9
  This program is free software; you can redistribute it and/or modify
10
  it under the terms of the GNU General Public License as published by
11
  the Free Software Foundation; either version 2 of the License, or
12
  (at your option) any later version.
13
14
  This program is distributed in the hope that it will be useful,
15
  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
  GNU General Public License for more details.
18
19
  You should have received a copy of the GNU General Public License
20
  along with this program; if not, write to the Free Software
21
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22
  02110-1301, USA.
23
 **********************************************************************/
24
#ifndef OB_SQUAREPLANAR_H
25
#define OB_SQUAREPLANAR_H
26
27
#include <openbabel/stereo/tetraplanar.h>
28
#include <vector>
29
30
namespace OpenBabel {
31
32
///@addtogroup stereo Stereochemistry
33
///@{
34
/**
35
 * @class OBSquarePlanarStereo squareplanar.h <openbabel/stereo/squareplanar.h>
36
 * @brief Class for handling and storing square planar stereochemistry.
37
 *
38
 * @image html squareplanar.png
39
 *
40
 * The OBSquarePlanarStereo class is used to represent square planar stereochemistry.
41
 * Like all OBTetraPlanarStereo subclasses, it uses the OBStereo::Shape parameters
42
 * to set/get the reference ids.
43
 *
44
 * This class works with reference ids only, it never uses the molecule
45
 * to get more information. Like all stereo classes, errors,
46
 * warnings or info is reported using OBMessageHandler.
47
 */
48
class OBAPI OBSquarePlanarStereo : public OBTetraPlanarStereo
49
{
50
  public:
51
    /**
52
     * \struct Config squareplanar.h <openbabel/stereo/squareplanar.h>
53
     * \brief Stereochemical configuration for square planar stereocenters
54
     *
55
     * The config struct represents the stereochemistry in a well defined way.
56
     * For squareplanar stereocenters, the following data members define the spacial
57
     * arrengement of the atoms.
58
     *
59
     * - OBStereo::Ref @p center: The central atom.
60
     * - OBStereo::Refs @p refs: The 4 atoms connected to the double bond.
61
     * - OBStereo::Shape @p shape: The shape formed by the @p refs by connecting them
62
     *   in the same order as they occur in @p refs.
63
     *
64
     * @image html squareplanar.png
65
     * @image html SPshapes.png
66
     *
67
     * Only @p center are specific for OBSquarePlanarStereo::Config. The other
68
     * data members occur in all OBTetraPlanarStereo derived classes.
69
     */
70
#ifndef SWIG
71
    struct OBAPI Config
72
    {
73
      /**
74
       * Default constructor. Initializes @p center to OBStereo::NoRef
75
       * and @p shape to OBStereo::ShapeU.
76
       */
77
0
      Config() : center(OBStereo::NoRef), shape(OBStereo::ShapeU),
78
0
          specified(true)
79
0
      {  }
80
      /**
81
       * Constructor with all parameters.
82
       *
83
       * @param _center The atom id for the central atom.
84
       * @param _refs The 4 reference ids.
85
       * @param _shape The shape for the 4 reference ids.
86
       */
87
      Config(unsigned long _center, const OBStereo::Refs &_refs,
88
          OBStereo::Shape _shape = OBStereo::ShapeU) : center(_center),
89
          refs(_refs), shape(_shape), specified(true)
90
0
      {  }
91
      /**
92
       * Equal to operator. Comparing OBSquarePlanarStereo::Config structs
93
       * is done using the information stored in the struct's data members
94
       * (i.e. center, refs and shape).
95
       *
96
       * There are a number of cases resuling in false being returned:
97
       * - @p center atom ids don't match
98
       * - One of the Refs lists does not contain 4 elements.
99
       * - 2 or more OBStereo::ImplicitRef values in a single Config struct
100
       * - (The two @p refs don't share a single common element)
101
       *
102
       * In the simplest case where both @p refs contain exactly the same elements
103
       * (OBStereo::ContainsSameRefs()), coould include OBStereo::ImplicitRef), both Config
104
       * struct are normalized to OBStereo::ShapeU starting with the same element.
105
       * After this normalization, there are two possible orientations to overlay the
106
       * shape on the double bond. From the illustration below, it can be seen only
107
       * @p refs[2] has to be checked in order to conclude both Config structs
108
       * have the same stereochemistry.
109
       *
110
         @verbatim
111
         1   4    1      4    1------4
112
          \ /     |      |           |
113
           C      |      |           |
114
          / \     |      |           |
115
         2   3    2------3    2------3
116
117
                  1 2 3 4     1 2 3 4
118
                  |   |       |   |      <- in any case, refs[0] & refs[2] remain unchanged
119
                  1 2 3 4     1 4 3 2
120
        @endverbatim
121
       *
122
       * When comparing a Config struct with explicit hydrogen(s) to one with
123
       * implicit hydrogen(s), both @p refs are also normalized to OBStereo::ShapeU
124
       * starting with the same common element. This shared element cannot be
125
       * OBStereo::ImplicitRef. Depending on the position of the OBStereo::ImplicitRef
126
       * element(s) in the @p refs, 3 cases are possible:
127
       *
128
        @verbatim
129
130
         refs[2] != OBStereo::ImplicitId:
131
132
           (analog to the case above where they contained the same elements )
133
134
           1 2 3 4
135
           |   |      <- refs[0] & refs[2] remain unchanged
136
           1 H 3 H
137
138
         else:
139
140
           1 2 3 4
141
           |     |    <- refs[0] & refs[3] remain unchanged
142
           1 H H 4
143
144
           1 2 3 4
145
           | |        <- refs[0] & refs[1] remain unchanged
146
           1 2 H H
147
        @endverbatim
148
       *
149
       * In each case, the orientation of the U shape is also defined since
150
       * there can be only one OBStereo::ImplicitRef for each side of the
151
       * double bond.
152
       *
153
       * @return True if both Config structs represent the stereochemistry.
154
       */
155
      bool operator==(const Config &other) const;
156
      /**
157
       * Not equal to operator. This is the inverse of the Equal to operator==.
158
       *
159
       * @return True if the two Config structs represent a different stereochemistry.
160
       */
161
      bool operator!=(const Config &other) const
162
0
      {
163
0
        return !(*this == other);
164
0
      }
165
166
      /**
167
       * @name Data members defining stereochemistry.
168
       * @{
169
       */
170
      unsigned long center; //<! The central atom id.
171
      OBStereo::Refs refs; //!< The 4 reference ids.
172
      OBStereo::Shape shape; //!< The shape of the 4 reference ids.
173
      bool specified; //!< True if the stereochemistry is specified. When false, the described
174
                      //!< special orientation is only accidental (i.e. unspecified).
175
      //@}
176
    };
177
#endif
178
    /**
179
     * Constructor.
180
     */
181
    OBSquarePlanarStereo(OBMol *mol);
182
    /**
183
     * Destructor.
184
     */
185
    virtual ~OBSquarePlanarStereo();
186
187
    ///@name SquarePlanar stereochemistry
188
    ///@{
189
    /**
190
     * Get the OBStereo::Type for this object.
191
     * @return OBStereo::SquarePlanar
192
     */
193
0
    OBStereo::Type GetType() const { return OBStereo::SquarePlanar; }
194
    /**
195
     * @return True if this object is valid. This object is valid if all (center and
196
     * and 4 reference) atom ids are set.
197
     */
198
    bool IsValid() const;
199
200
    /**
201
     * Set the configuration using a Config struct.
202
     */
203
#ifndef SWIG
204
    void SetConfig(const Config &config);
205
    /**
206
     * Get the configuration as Config struct.
207
     */
208
    Config GetConfig(OBStereo::Shape shape = OBStereo::ShapeU) const;
209
    /**
210
     * Get the configuration as Config struct and ensure refs[0] is
211
     * equal to @p start.
212
     */
213
    Config GetConfig(unsigned long start,
214
        OBStereo::Shape shape = OBStereo::ShapeU) const;
215
#endif
216
    /**
217
     * Compare the stereochemistry stored in the Config struct with the
218
     * stereochemistry specified in the Config struct from @p other.
219
     *
220
     * @copydoc Config::operator==()
221
     */
222
    bool operator==(const OBSquarePlanarStereo &other) const;
223
    /**
224
     * Not equal to operator. This is the inverse of the Equal to operator==.
225
     *
226
     * @return True if the two Config structs represent a different stereochemistry.
227
     */
228
    bool operator!=(const OBSquarePlanarStereo &other) const
229
0
    {
230
0
      return !(*this == other);
231
0
    }
232
    ///@}
233
234
    /*
235
     * Implement OBGenericData::Clone().
236
     */
237
    OBGenericData* Clone(OBBase *mol) const;
238
239
    //! @name Query methods to compare stereochemistry.
240
    //@{
241
    /**
242
     * @return True if the two reference ids are placed trans configuration.
243
     */
244
    bool IsTrans(unsigned long id1, unsigned long id2) const;
245
    /**
246
     * @return True if the two reference ids are placed in a cis configuration.
247
     */
248
    bool IsCis(unsigned long id1, unsigned long id2) const;
249
    /**
250
     * @image html gettransref.png
251
     * Get the reference id trans from reference @p id.
252
     */
253
    unsigned long GetTransRef(unsigned long id) const;
254
    /**
255
     * Get the reference id cis from reference @p id.
256
     */
257
    std::vector<unsigned long> GetCisRefs(unsigned long id) const;
258
    //@}
259
260
  private:
261
    Config m_cfg; //!< internal configuration
262
    // The following function sits behind GetCisRef and GetTransRef
263
    unsigned long GetCisOrTransRef(unsigned long id, bool getcisref) const;
264
};
265
///@}
266
// end addtogroup doxygen
267
268
} // namespace OpenBabel
269
270
#ifndef SWIG
271
namespace std {
272
273
///@addtogroup stereo Stereochemistry
274
///@{
275
/**
276
 * @code
277
 * OBSquarePlanarStereo::Config cfg;
278
 * cfg.center = 0;
279
 * cfg.refs = OBStereo::MakeRefs(1, 2, 3, 4);
280
 * cfg.shape = OBStereo::ShapeU;
281
 *
282
 * OBSquarePlanarStereo ct(mol);
283
 * ct.SetConfig(cfg)
284
 *
285
 * cout << "ct = " << ct << endl;
286
 *
287
 * // output
288
 * OBSquarePlanarStereo(center = 0, refs = 1 2 3 4, shape = U)
289
 * @endcode
290
 */
291
OBAPI ostream& operator<<(ostream &out, const OpenBabel::OBSquarePlanarStereo &ct);
292
/**
293
 * @code
294
 * OBSquarePlanarStereo::Config cfg;
295
 * cfg.center = 0;
296
 * cfg.refs = OBStereo::MakeRefs(1, 2, 3, 4);
297
 * cfg.shape = OBStereo::ShapeU;
298
 *
299
 * cout << "cfg = " << cfg << endl;
300
 *
301
 * // output
302
 * OBSquarePlanarStereo::Config(center = 0, refs = 1 2 3 4, shape = U)
303
 * @endcode
304
 */
305
OBAPI ostream& operator<<(ostream &out, const OpenBabel::OBSquarePlanarStereo::Config &cfg);
306
307
///@}
308
309
} // namespace std
310
#endif // Not SWIG
311
312
#endif
313
314
//! \file squareplanar.h
315
//! \brief Store and convert square-planar stereochemistry