[0b990d] | 1 | //
|
---|
| 2 | // formula.cc --- implementation of the MolecularFormula class
|
---|
| 3 | //
|
---|
| 4 | // Copyright (C) 1997 Limit Point Systems, Inc.
|
---|
| 5 | //
|
---|
| 6 | // Author: Edward Seidl <seidl@janed.com>
|
---|
| 7 | // Maintainer: LPS
|
---|
| 8 | //
|
---|
| 9 | // This file is part of the SC Toolkit.
|
---|
| 10 | //
|
---|
| 11 | // The SC Toolkit is free software; you can redistribute it and/or modify
|
---|
| 12 | // it under the terms of the GNU Library General Public License as published by
|
---|
| 13 | // the Free Software Foundation; either version 2, or (at your option)
|
---|
| 14 | // any later version.
|
---|
| 15 | //
|
---|
| 16 | // The SC Toolkit is distributed in the hope that it will be useful,
|
---|
| 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 19 | // GNU Library General Public License for more details.
|
---|
| 20 | //
|
---|
| 21 | // You should have received a copy of the GNU Library General Public License
|
---|
| 22 | // along with the SC Toolkit; see the file COPYING.LIB. If not, write to
|
---|
| 23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
| 24 | //
|
---|
| 25 |
|
---|
| 26 | #ifdef __GNUC__
|
---|
| 27 | #pragma implementation
|
---|
| 28 | #endif
|
---|
| 29 |
|
---|
| 30 | #include <sstream>
|
---|
| 31 | #include <map>
|
---|
| 32 | #include <chemistry/molecule/formula.h>
|
---|
| 33 |
|
---|
| 34 | using namespace sc;
|
---|
| 35 |
|
---|
| 36 | MolecularFormula::MolecularFormula(const Ref<Molecule>&m):
|
---|
| 37 | form_(0)
|
---|
| 38 | {
|
---|
| 39 | compute_form(m.pointer());
|
---|
| 40 | compute_atomtypes(m.pointer());
|
---|
| 41 | }
|
---|
| 42 |
|
---|
| 43 | MolecularFormula::MolecularFormula(const Molecule *m):
|
---|
| 44 | form_(0)
|
---|
| 45 | {
|
---|
| 46 | compute_form(m);
|
---|
| 47 | compute_atomtypes(m);
|
---|
| 48 | }
|
---|
| 49 |
|
---|
| 50 | MolecularFormula::~MolecularFormula()
|
---|
| 51 | {
|
---|
| 52 | delete[] form_;
|
---|
| 53 | delete[] Z_;
|
---|
| 54 | delete[] nZ_;
|
---|
| 55 | }
|
---|
| 56 |
|
---|
| 57 | void
|
---|
| 58 | MolecularFormula::compute_form(const Molecule *m)
|
---|
| 59 | {
|
---|
| 60 | const Molecule& mol = *m;
|
---|
| 61 |
|
---|
| 62 | std::map<std::string, int> count;
|
---|
| 63 |
|
---|
| 64 | for (int a=0; a < mol.natom(); a++) {
|
---|
| 65 | std::string symbol(mol.atom_symbol(a));
|
---|
| 66 | if (count.find(symbol) == count.end()) count[symbol] = 0;
|
---|
| 67 | count[symbol]++;
|
---|
| 68 | }
|
---|
| 69 |
|
---|
| 70 | std::ostringstream sstr;
|
---|
| 71 | if (count.find("Q") != count.end()) {
|
---|
| 72 | sstr << "Q";
|
---|
| 73 | if (count["Q"] > 1) sstr << count["Q"];
|
---|
| 74 | count.erase("Q");
|
---|
| 75 | }
|
---|
| 76 | if (count.find("C") != count.end()) {
|
---|
| 77 | sstr << "C";
|
---|
| 78 | if (count["C"] > 1) sstr << count["C"];
|
---|
| 79 | count.erase("C");
|
---|
| 80 | }
|
---|
| 81 | if (count.find("H") != count.end()) {
|
---|
| 82 | sstr << "H";
|
---|
| 83 | if (count["H"] > 1) sstr << count["H"];
|
---|
| 84 | count.erase("H");
|
---|
| 85 | }
|
---|
| 86 | for (std::map<std::string,int>::iterator i = count.begin();
|
---|
| 87 | i != count.end(); i++) {
|
---|
| 88 | sstr << i->first;
|
---|
| 89 | if (i->second > 1) sstr << i->second;
|
---|
| 90 | }
|
---|
| 91 | form_ = strcpy(new char[sstr.str().size()+1],sstr.str().c_str());
|
---|
| 92 | }
|
---|
| 93 |
|
---|
| 94 | void
|
---|
| 95 | MolecularFormula::compute_atomtypes(const Molecule *m)
|
---|
| 96 | {
|
---|
| 97 | std::map<int, int> atomtypeinfo;
|
---|
| 98 | int natoms = m->natom();
|
---|
| 99 | int i, Z;
|
---|
| 100 |
|
---|
| 101 | for (i=0; i< natoms; i++) {
|
---|
| 102 | // don't include ghost functions or point charges
|
---|
| 103 | if (m->charge(i) == 0.0) continue;
|
---|
| 104 | if (m->atom_symbol(i) == "Q") continue;
|
---|
| 105 | Z = m->Z(i);
|
---|
| 106 | if (atomtypeinfo.find(Z) != atomtypeinfo.end()) atomtypeinfo[Z]++;
|
---|
| 107 | else atomtypeinfo[Z] = 1;
|
---|
| 108 | }
|
---|
| 109 |
|
---|
| 110 | natomtypes_ = atomtypeinfo.size();
|
---|
| 111 |
|
---|
| 112 | Z_ = new int[natomtypes_];
|
---|
| 113 | nZ_ = new int[natomtypes_];
|
---|
| 114 |
|
---|
| 115 | std::map<int, int>::iterator iter;
|
---|
| 116 |
|
---|
| 117 | for (iter = atomtypeinfo.begin(), i=0; iter != atomtypeinfo.end(); iter++, i++) {
|
---|
| 118 | Z_[i] = iter->first;
|
---|
| 119 | nZ_[i] = iter->second;
|
---|
| 120 | }
|
---|
| 121 |
|
---|
| 122 | }
|
---|
| 123 |
|
---|
| 124 | const char *
|
---|
| 125 | MolecularFormula::formula() const
|
---|
| 126 | {
|
---|
| 127 | return form_;
|
---|
| 128 | }
|
---|
| 129 |
|
---|
| 130 | int
|
---|
| 131 | MolecularFormula::natomtypes()
|
---|
| 132 | {
|
---|
| 133 | return(natomtypes_);
|
---|
| 134 | }
|
---|
| 135 |
|
---|
| 136 | int
|
---|
| 137 | MolecularFormula::Z(int itype)
|
---|
| 138 | {
|
---|
| 139 | return Z_[itype];
|
---|
| 140 | }
|
---|
| 141 |
|
---|
| 142 | int
|
---|
| 143 | MolecularFormula::nZ(int itype)
|
---|
| 144 | {
|
---|
| 145 | return nZ_[itype];
|
---|
| 146 | }
|
---|