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 #include <openbabel/babelconfig.h>
17 #include <openbabel/obmolecformat.h>
18 #include <openbabel/mol.h>
19 #include <openbabel/atom.h>
20 #include <openbabel/elements.h>
21 
22 
23 using namespace std;
24 namespace OpenBabel
25 {
26 
27   class CSRFormat : public OBMoleculeFormat
28   {
29   public:
30     //Register this format type ID
CSRFormat()31     CSRFormat()
32     {
33       OBConversion::RegisterFormat("csr",this);
34     }
35 
Description()36     virtual const char* Description() //required
37     {
38       return
39         "Accelrys/MSI Quanta CSR format\n"
40         "No comments yet\n";
41     };
42 
SpecificationURL()43     virtual const char* SpecificationURL()
44     {return "";}; //optional
45 
46     //Flags() can return be any the following combined by | or be omitted if none apply
47     // NOTREADABLE  READONEONLY  NOTWRITABLE  WRITEONEONLY
Flags()48     virtual unsigned int Flags()
49     {
50       return NOTREADABLE;
51     };
52 
53     //*** This section identical for most OBMol conversions ***
54     ////////////////////////////////////////////////////
55     /// The "API" interface functions
56     virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv);
57 
58   private:
59     //	static bool FirstTime = true; Use new framework functions
60     int MolCount; //was = 1;
61 
62     void WriteSize(int,ostream&);
63     char *PadString(char*,int);
64     void WriteCSRHeader(ostream&,OBMol&);
65     void WriteCSRCoords(ostream&,OBMol&);
66 
67 
68   };
69   //***
70 
71   //Make an instance of the format class
72   CSRFormat theCSRFormat;
73 
74   ////////////////////////////////////////////////////////////////
75 
WriteMolecule(OBBase * pOb,OBConversion * pConv)76   bool CSRFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
77   {
78     OBMol* pmol = dynamic_cast<OBMol*>(pOb);
79     if (pmol == nullptr)
80       return false;
81 
82     //Define some references so we can use the old parameter names
83     ostream &ofs = *pConv->GetOutStream();
84     OBMol &mol = *pmol;
85 
86     //  if (FirstTime)
87     if(pConv->GetOutputIndex()==1)
88       {
89         WriteCSRHeader(ofs,mol);
90         //FirstTime = false;
91         MolCount=1;
92       }
93 
94     WriteCSRCoords(ofs,mol);
95     MolCount++;
96 
97     return(true);
98   }
99 
WriteCSRHeader(ostream & ofs,OBMol & mol)100   void CSRFormat::WriteCSRHeader(ostream &ofs,OBMol &mol)
101   {
102     char *molnames;
103     int nmol, natom;
104 
105     molnames = PadString((char*)mol.GetTitle(),100);
106 
107     nmol = 1;
108     natom = mol.NumAtoms();
109 
110     WriteSize(4*sizeof(char),ofs);
111     ofs.write("V33 ",strlen("V33 ")*sizeof(char));
112     WriteSize(4*sizeof(char),ofs);
113 
114     WriteSize(2*sizeof(int),ofs);
115     ofs.write((char*)&natom,sizeof(int));
116     ofs.write((char*)&nmol,sizeof(int));
117     WriteSize(2*sizeof(int),ofs);
118 
119     WriteSize(100*sizeof(char),ofs);
120     ofs.write(molnames,100*sizeof(char));
121     WriteSize(100*sizeof(char),ofs);
122 
123     WriteSize(sizeof(int),ofs);
124     ofs.write((char*)&natom,sizeof(int));
125     WriteSize(sizeof(int),ofs);
126 
127     delete [] molnames;
128   }
129 
WriteCSRCoords(ostream & ofs,OBMol & mol)130   void CSRFormat::WriteCSRCoords(ostream &ofs,OBMol &mol)
131   {
132     int the_size,jconf;
133     double x,y,z,energy;
134     char title[100];
135     char *tag;
136 
137     the_size = sizeof(int) + sizeof(double) + (80 * sizeof(char));
138 
139     jconf = 1;
140     energy = -2.584565;
141 
142     snprintf(title, 80, "%s:%d",mol.GetTitle(),MolCount);
143     tag = PadString(title,80);
144 
145     WriteSize(the_size,ofs);
146     ofs.write((char*)&jconf,sizeof(int));
147     ofs.write((char*)&energy,sizeof(double));
148     ofs.write(tag,80*sizeof(char));
149     WriteSize(the_size,ofs);
150 
151     WriteSize(mol.NumAtoms()*sizeof(double),ofs);
152 
153     OBAtom *atom;
154     vector<OBAtom*>::iterator i;
155     for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
156       {
157         x = atom->x();
158         ofs.write((char*)&x,sizeof(double));
159       }
160     WriteSize(mol.NumAtoms()*sizeof(double),ofs);
161 
162     WriteSize(mol.NumAtoms()*sizeof(double),ofs);
163     for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
164       {
165         y = atom->y();
166         ofs.write((char*)&y,sizeof(double));
167       }
168     WriteSize(mol.NumAtoms()*sizeof(double),ofs);
169 
170     WriteSize(mol.NumAtoms()*sizeof(double),ofs);
171     for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
172       {
173         z = atom->z();
174         ofs.write((char*)&z,sizeof(double));
175       }
176     WriteSize(mol.NumAtoms()*sizeof(double),ofs);
177 
178     delete [] tag;
179   }
180 
WriteSize(int size,ostream & ofs)181   void CSRFormat::WriteSize(int size,ostream &ofs)
182   {
183     ofs.write((char*)&size,sizeof(int));
184   }
185 
PadString(char * input,int size)186   char* CSRFormat::PadString(char *input, int size)
187   {
188     char *output;
189 
190     output = new char[size];
191     memset(output, ' ', size);
192     strncpy(output, input, strlen(input));
193     output[ size - 1] = '\0';
194     return(output);
195   }
196 
197 } //namespace OpenBabel
198