1 /**********************************************************************
2   stereofacade.cpp - OBStereoFacade
3 
4   Copyright (C) 2009 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 #include <openbabel/stereo/tetrahedral.h>
25 #include <openbabel/stereo/cistrans.h>
26 #include <openbabel/stereo/squareplanar.h>
27 #include <openbabel/mol.h>
28 #include <openbabel/atom.h>
29 #include <openbabel/bond.h>
30 #include <openbabel/obiter.h>
31 
32 namespace OpenBabel {
33 
NumTetrahedralStereo()34   unsigned int OBStereoFacade::NumTetrahedralStereo()
35   {
36     EnsureInit();
37     return static_cast<unsigned int> (m_tetrahedralMap.size());
38   }
39 
NumCisTransStereo()40   unsigned int OBStereoFacade::NumCisTransStereo()
41   {
42     EnsureInit();
43     return static_cast<unsigned int> (m_cistransMap.size());
44   }
45 
NumSquarePlanarStereo()46   unsigned int OBStereoFacade::NumSquarePlanarStereo()
47   {
48     EnsureInit();
49     return static_cast<unsigned int> (m_squarePlanarMap.size());
50   }
51 
GetAllTetrahedralStereo()52   std::vector<OBTetrahedralStereo*> OBStereoFacade::GetAllTetrahedralStereo()
53   {
54     EnsureInit();
55 
56     typedef std::map<unsigned long, OBTetrahedralStereo*>::iterator Iter;
57     std::vector<OBTetrahedralStereo*> result;
58     for (Iter it = m_tetrahedralMap.begin(); it != m_tetrahedralMap.end(); ++it)
59       result.push_back(it->second);
60 
61     return result;
62   }
63 
GetAllCisTransStereo()64   std::vector<OBCisTransStereo*> OBStereoFacade::GetAllCisTransStereo()
65   {
66     EnsureInit();
67 
68     typedef std::map<unsigned long, OBCisTransStereo*>::iterator Iter;
69     std::vector<OBCisTransStereo*> result;
70     for (Iter it = m_cistransMap.begin(); it != m_cistransMap.end(); ++it)
71       result.push_back(it->second);
72 
73     return result;
74   }
75 
GetAllSquarePlanarStereo()76   std::vector<OBSquarePlanarStereo*> OBStereoFacade::GetAllSquarePlanarStereo()
77   {
78     EnsureInit();
79 
80     typedef std::map<unsigned long, OBSquarePlanarStereo*>::iterator Iter;
81     std::vector<OBSquarePlanarStereo*> result;
82     for (Iter it = m_squarePlanarMap.begin(); it != m_squarePlanarMap.end(); ++it)
83       result.push_back(it->second);
84 
85     return result;
86   }
87 
HasTetrahedralStereo(unsigned long atomId)88   bool OBStereoFacade::HasTetrahedralStereo(unsigned long atomId)
89   {
90     EnsureInit();
91     if (m_tetrahedralMap.find(atomId) != m_tetrahedralMap.end())
92       return true;
93     return false;
94   }
95 
HasCisTransStereo(unsigned long bondId)96   bool OBStereoFacade::HasCisTransStereo(unsigned long bondId)
97   {
98     EnsureInit();
99     if (m_cistransMap.find(bondId) != m_cistransMap.end())
100       return true;
101     return false;
102   }
103 
HasSquarePlanarStereo(unsigned long atomId)104   bool OBStereoFacade::HasSquarePlanarStereo(unsigned long atomId)
105   {
106     EnsureInit();
107     if (m_squarePlanarMap.find(atomId) != m_squarePlanarMap.end())
108       return true;
109     return false;
110   }
111 
GetTetrahedralStereo(unsigned long atomId)112   OBTetrahedralStereo* OBStereoFacade::GetTetrahedralStereo(unsigned long atomId)
113   {
114     if (!HasTetrahedralStereo(atomId))
115       return nullptr;
116     return m_tetrahedralMap[atomId];
117   }
118 
GetCisTransStereo(unsigned long bondId)119   OBCisTransStereo* OBStereoFacade::GetCisTransStereo(unsigned long bondId)
120   {
121     if (!HasCisTransStereo(bondId))
122       return nullptr;
123     return m_cistransMap[bondId];
124   }
125 
GetSquarePlanarStereo(unsigned long atomId)126   OBSquarePlanarStereo* OBStereoFacade::GetSquarePlanarStereo(unsigned long atomId)
127   {
128     if (!HasSquarePlanarStereo(atomId))
129       return nullptr;
130     return m_squarePlanarMap[atomId];
131   }
132 
InitMaps()133   void OBStereoFacade::InitMaps()
134   {
135     if (m_perceive && !m_mol->HasChiralityPerceived())
136       PerceiveStereo(m_mol);
137 
138     std::vector<OBGenericData *> stereoData = m_mol->GetAllData(OBGenericDataType::StereoData);
139 
140     std::vector<OBGenericData*>::iterator data;
141     for (data = stereoData.begin(); data != stereoData.end(); ++data) {
142       OBStereo::Type type = ((OBStereoBase*)*data)->GetType();
143       if (type == OBStereo::Tetrahedral) {
144         OBTetrahedralStereo *ts = dynamic_cast<OBTetrahedralStereo*>(*data);
145         OBTetrahedralStereo::Config config = ts->GetConfig();
146         if (config.center == OBStereo::NoRef)
147           continue;
148         m_tetrahedralMap[config.center] = ts;
149       } else
150       if (type == OBStereo::SquarePlanar) {
151         OBSquarePlanarStereo *sp = dynamic_cast<OBSquarePlanarStereo*>(*data);
152         OBSquarePlanarStereo::Config config = sp->GetConfig();
153         if (config.center == OBStereo::NoRef)
154           continue;
155         m_squarePlanarMap[config.center] = sp;
156       } else
157       if (type == OBStereo::CisTrans) {
158         OBCisTransStereo *ct = dynamic_cast<OBCisTransStereo*>(*data);
159         OBCisTransStereo::Config config = ct->GetConfig();
160         // find the bond id from begin & end atom ids
161         unsigned long id = OBStereo::NoRef;
162         OBAtom *a = m_mol->GetAtomById(config.begin);
163         if (!a)
164           continue;
165         FOR_BONDS_OF_ATOM (bond, a) {
166           unsigned long beginId = bond->GetBeginAtom()->GetId();
167           unsigned long endId = bond->GetEndAtom()->GetId();
168           if ((beginId == config.begin && endId == config.end) ||
169               (beginId == config.end && endId == config.begin)) {
170             id = bond->GetId();
171             break;
172           }
173         }
174         if (id == OBStereo::NoRef)
175           continue;
176         m_cistransMap[id] = ct;
177       }
178     }
179 
180     m_init = true;
181   }
182 
183   template<>
HasStereo(unsigned long id)184   bool OBStereoFacade::HasStereo<OBStereo::Tetrahedral>(unsigned long id)
185   {
186     return HasTetrahedralStereo(id);
187   }
188 
189   template<>
HasStereo(unsigned long id)190   bool OBStereoFacade::HasStereo<OBStereo::CisTrans>(unsigned long id)
191   {
192     return HasCisTransStereo(id);
193   }
194 
195   template<>
GetStereo(unsigned long id)196   OBTetrahedralStereo* OBStereoFacade::GetStereo<OBTetrahedralStereo>(unsigned long id)
197   {
198     return GetTetrahedralStereo(id);
199   }
200 
201   template<>
GetStereo(unsigned long id)202   OBCisTransStereo* OBStereoFacade::GetStereo<OBCisTransStereo>(unsigned long id)
203   {
204     return GetCisTransStereo(id);
205   }
206 
207 
208 
209 
210 }
211 
212