/src/openbabel/src/formats/gromos96format.cpp
Line | Count | Source |
1 | | /********************************************************************** |
2 | | Copyright (C) 1998-2001 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 | | |
16 | | /* contributed by Walter Scott (wscott@igc.phys.chem.ethz.ch) |
17 | | |
18 | | (Actually the routine was copied from write_xyz and and write_pdb and |
19 | | then modified...) |
20 | | |
21 | | This is a small routine to write a GROMOS96 formatted |
22 | | "position coordinate block" (POSITION) or a |
23 | | "reduced position coordinate block" (POSITIONRED) |
24 | | The former has name information (atom and residue names) while |
25 | | the latter only has coordinates. |
26 | | This version does not support the writing of binary |
27 | | GROMOS files. |
28 | | |
29 | | NOTE 1: the actual formats used in writing out the coordinates |
30 | | do not matter, as GROMOS96 uses free formatted reads. |
31 | | Each line may not be longer than 80 characters. |
32 | | |
33 | | (Note, however, in the POSITION block, the first 24 (twenty four) |
34 | | character on each line are ignored when the line is read in by GROMOS) |
35 | | Comments lines, beginning with hash (#) may occur within a block and are |
36 | | used as delimiters for easier reading. |
37 | | |
38 | | NOTE 2: Many programs specify the units of the coordinates (e.g. Angstrom). |
39 | | GROMOS96 does NOT, as all physical constants, from K_B to EPS are |
40 | | NOT hardwired into the code, but specified by the user. |
41 | | This allows some (mostly Americans) to use GROMOS96 in KCal and |
42 | | Angstrom and the rest of us to use kJoule and nm. |
43 | | It also makes it easy to use reduced units. |
44 | | |
45 | | We get around this by supplying a routine, wr_sco_gr96, which |
46 | | will scale the coordinates by a factor before writing. |
47 | | This routine is then called with the factor set to 1.0 in |
48 | | write_gr96A, or to 0.1 in write_gr96N depending on the users choice. |
49 | | Thus, we always assume that we have read coordinates in Angstrom. |
50 | | *** But now handled by a command line option in new framework. |
51 | | */ |
52 | | |
53 | | #include <openbabel/babelconfig.h> |
54 | | #include <openbabel/obmolecformat.h> |
55 | | #include <openbabel/mol.h> |
56 | | #include <openbabel/atom.h> |
57 | | #include <openbabel/elements.h> |
58 | | |
59 | | |
60 | | using namespace std; |
61 | | namespace OpenBabel |
62 | | { |
63 | | |
64 | | class GROMOS96Format : public OBMoleculeFormat |
65 | | { |
66 | | public: |
67 | | //Register this format type ID |
68 | | GROMOS96Format() |
69 | 6 | { |
70 | 6 | OBConversion::RegisterFormat("gr96",this); |
71 | 6 | } |
72 | | |
73 | | const char* Description() override // required |
74 | 0 | { |
75 | 0 | return |
76 | 0 | "GROMOS96 format\n" |
77 | 0 | "Write Options e.g. -xn\n" |
78 | 0 | " n output nm (not Angstroms)\n"; |
79 | 0 | } |
80 | | |
81 | | const char* SpecificationURL() override |
82 | 0 | { |
83 | 0 | return "http://manual.gromacs.org/documentation/current/reference-manual/file-formats.html#g96"; |
84 | 0 | } |
85 | | |
86 | | //Flags() can return be any the following combined by | or be omitted if none apply |
87 | | // NOTREADABLE READONEONLY NOTWRITABLE WRITEONEONLY |
88 | | unsigned int Flags() override |
89 | 6 | { |
90 | 6 | return NOTREADABLE | WRITEONEONLY; |
91 | 6 | } |
92 | | |
93 | | //////////////////////////////////////////////////// |
94 | | /// The "API" interface functions |
95 | | bool WriteMolecule(OBBase* pOb, OBConversion* pConv) override; |
96 | | |
97 | | }; |
98 | | |
99 | | //Make an instance of the format class |
100 | | GROMOS96Format theGROMOS96Format; |
101 | | |
102 | | //////////////////////////////////////////////////////////////// |
103 | | |
104 | | bool GROMOS96Format::WriteMolecule(OBBase* pOb, OBConversion* pConv) |
105 | 0 | { |
106 | 0 | OBMol* pmol = dynamic_cast<OBMol*>(pOb); |
107 | 0 | if (pmol == nullptr) |
108 | 0 | return false; |
109 | | |
110 | | //Define some references so we can use the old parameter names |
111 | 0 | ostream &ofs = *pConv->GetOutStream(); |
112 | 0 | OBMol &mol = *pmol; |
113 | 0 | double fac = pConv->IsOption("n") ? 0.1 : 1.0; //new framework |
114 | |
|
115 | 0 | char type_name[16]; |
116 | 0 | char res_name[16]; |
117 | 0 | char buffer[BUFF_SIZE]; |
118 | 0 | string res_num; |
119 | |
|
120 | 0 | snprintf(buffer, BUFF_SIZE, "#GENERATED BY OPEN BABEL %s\n",BABEL_VERSION); |
121 | 0 | ofs << buffer; |
122 | | |
123 | | /* GROMOS wants a TITLE block, so let's write one*/ |
124 | 0 | ofs << "TITLE\n" << mol.GetTitle() << "\nEND\n"; |
125 | 0 | ofs << "POSITION\n"; |
126 | |
|
127 | 0 | OBAtom *atom; |
128 | 0 | OBResidue *res; |
129 | 0 | vector<OBAtom*>::iterator i; |
130 | |
|
131 | 0 | for(atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) |
132 | 0 | { |
133 | 0 | if ( (res = atom->GetResidue()) ) |
134 | 0 | { |
135 | | // 16 = sizeof(res_name) and sizeof(type_name) |
136 | 0 | strncpy(res_name,(char*)res->GetName().c_str(), 16); |
137 | 0 | res_name[15] = '\0'; |
138 | 0 | strncpy(type_name,(char*)res->GetAtomID(atom).c_str(), 16); |
139 | 0 | type_name[15] = '\0'; |
140 | 0 | res_num = res->GetNumString(); |
141 | 0 | } |
142 | 0 | else |
143 | 0 | { |
144 | 0 | strncpy(type_name,OBElements::GetSymbol(atom->GetAtomicNum()), 16); |
145 | 0 | strcpy(res_name,"UNK"); |
146 | 0 | res_num = "1"; |
147 | 0 | } |
148 | |
|
149 | 0 | snprintf(buffer, BUFF_SIZE, "%5s %5s %5s %6d %15.5f %15.5f %15.5f\n", |
150 | 0 | res_num.c_str(),res_name,type_name,atom->GetIdx(), |
151 | 0 | atom->x()*fac,atom->y()*fac,atom->z()*fac); |
152 | 0 | ofs << buffer; |
153 | |
|
154 | 0 | if (!(atom->GetIdx()%10)) |
155 | 0 | { |
156 | 0 | snprintf(buffer, BUFF_SIZE, "# %d\n",atom->GetIdx()); |
157 | 0 | ofs << buffer; |
158 | 0 | } |
159 | 0 | } |
160 | |
|
161 | 0 | ofs << "END\n"; |
162 | |
|
163 | 0 | return(true); |
164 | 0 | } |
165 | | |
166 | | } //namespace OpenBabel |