ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/applications/atom2md/atom2md.cpp
Revision: 1210
Committed: Wed Jan 23 03:45:33 2008 UTC (17 years, 3 months ago) by gezelter
File size: 16289 byte(s)
Log Message:
Removed older version of openbabel from our code.  We now have a
configure check to see if openbabel is installed and then we link to
the stuff we need.  Conversion to OOPSE's md format is handled by only
one application (atom2md), so most of the work went on there.
ElementsTable still needs some work to function in parallel.

File Contents

# User Rev Content
1 gezelter 1020 /**********************************************************************
2 gezelter 1021 atom2md.cpp - OpenBabel-based conversion program to OOPSE MD file,
3     command-line handling.
4 gezelter 1020
5     Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
6 gezelter 1210 Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison
7     Some portions Copyright (C) 2004-2006 by Chris Morley
8     Some portions Copyright (C) 2008 by J. Daniel Gezelter
9 gezelter 1020
10 gezelter 1210 This file is part of both the OOPSE and Open Babel projects.
11 gezelter 1021 For more information, see <http://oopse.org> and <http://openbabel.sourceforge.net/>
12 gezelter 1020
13     This program is free software; you can redistribute it and/or modify
14     it under the terms of the GNU General Public License as published by
15     the Free Software Foundation version 2 of the License.
16    
17     This program is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20     GNU General Public License for more details.
21     ***********************************************************************/
22    
23     #include "config.h"
24 gezelter 1210
25     // used to set import/export for Cygwin DLLs
26     #ifdef WIN32
27     #define USING_OBDLL
28 gezelter 1020 #endif
29    
30 gezelter 1210 #include <openbabel/babelconfig.h>
31    
32     #include <iostream>
33     #include <fstream>
34     #include <sstream>
35    
36 gezelter 1020 #include <string>
37     #include <map>
38     #if HAVE_CONIO_H
39     #include <conio.h>
40     #endif
41 gezelter 1210 #include <cstdlib>
42 gezelter 1020
43     #if !HAVE_STRNCASECMP
44     extern "C" int strncasecmp(const char *s1, const char *s2, size_t n);
45     #endif
46    
47 gezelter 1210 #include <openbabel/obconversion.h>
48 gezelter 1020
49     using namespace std;
50     using namespace OpenBabel;
51 gezelter 1210
52     void DoOption(const char* p, OBConversion& Conv,
53     OBConversion::Option_type typ, int& arg, int argc,
54     char *argv[]);
55 gezelter 1020 void usage();
56     void help();
57    
58     // There isn't a great way to do this -- we need to save argv[0] for usage()
59     static char *program_name;
60    
61     int main(int argc,char *argv[])
62     {
63     OBConversion Conv(&cin, &cout); //default input and output are console
64 gezelter 1210
65 gezelter 1020 OBFormat* pInFormat = NULL;
66     OBFormat* pOutFormat = NULL;
67     vector<string> FileList, OutputFileList;
68     string OutputFileName;
69 gezelter 1210
70 gezelter 1020 // Parse commandline
71     bool gotInType = false, gotOutType = false;
72 gezelter 1210 bool SplitOrBatch=false;
73    
74 gezelter 1020 char *oext;
75     char *iext;
76     string inputExt;
77     string outputExt;
78 gezelter 1210
79 gezelter 1020 //Save name of program without its path (and .exe)
80     string pn(argv[0]);
81 gezelter 1210 string::size_type pos;
82 gezelter 1020 #ifdef _WIN32
83     pos = pn.find(".exe");
84     if(pos!=string::npos)
85     argv[0][pos]='\0';
86     #endif
87     pos = pn.find_last_of("/\\");
88     if(pos==string::npos)
89     program_name=argv[0];
90     else
91     program_name=argv[0]+pos+1;
92 gezelter 1210
93 gezelter 1021 const char* p;
94     int arg;
95 gezelter 1210 for (arg = 1; arg < argc; ++arg)
96 gezelter 1021 {
97     if (argv[arg])
98     {
99     if (argv[arg][0] == '-')
100     {
101     switch (argv[arg][1])
102     {
103 gezelter 1210
104 gezelter 1021 case 'V':
105     {
106 gezelter 1210 cout << program_name << ": part of OOPSE " <<
107     OOPSE_VERSION_MAJOR << "." << OOPSE_VERSION_MINOR <<
108     "." << OOPSE_VERSION_TINY <<
109     " and Open Babel " << BABEL_VERSION << " -- "
110 gezelter 1021 << __DATE__ << " -- " << __TIME__ << endl;
111     exit(0);
112     }
113 gezelter 1210
114 gezelter 1021 case 'i':
115     gotInType = true;
116     iext = argv[arg] + 2;
117     if(!*iext)
118 gezelter 1210 iext = argv[++arg]; // space left after -i: use next
119     // argument
120    
121 gezelter 1021 if (strncasecmp(iext, "MIME", 4) == 0)
122     {
123     // get the MIME type from the next argument
124     iext = argv[++arg];
125     pInFormat = Conv.FormatFromMIME(iext);
126     }
127     else
128     {
129 gezelter 1210 // The ID provided by the OBFormat class is used as the
130     // identifying file extension
131 gezelter 1021 pInFormat = Conv.FindFormat(iext);
132     }
133     if(pInFormat==NULL)
134     {
135 gezelter 1210 cerr << program_name << ": cannot read input format!"
136     << endl;
137 gezelter 1021 usage();
138     }
139     break;
140    
141     case 'o':
142     gotOutType = true;
143     oext = argv[arg] + 2;
144     if(!*oext)
145 gezelter 1210 oext = argv[++arg]; // space left after -i: use next
146     // argument
147    
148 gezelter 1021 if (strncasecmp(oext, "MIME", 4) == 0)
149     {
150     // get the MIME type from the next argument
151     oext = argv[++arg];
152     pOutFormat = Conv.FormatFromMIME(oext);
153     }
154     else
155     pOutFormat = Conv.FindFormat(oext);
156 gezelter 1210
157 gezelter 1021 if(pOutFormat==NULL)
158     {
159 gezelter 1210 cerr << program_name << ": cannot write output format!"
160     << endl;
161 gezelter 1021 usage();
162     }
163 gezelter 1210 break;
164 gezelter 1021
165 gezelter 1210 case 'F':
166     if(!Conv.SetOutFormat("fpt"))
167     cout << "FingerprintFormat needs to be loaded" << endl;
168     else
169     {
170     Conv.AddOption("F",OBConversion::OUTOPTIONS);
171     Conv.Write(NULL);
172     }
173     return 0;
174    
175 gezelter 1021 case '?':
176     case 'H':
177     if(isalnum(argv[arg][2]))
178     {
179     if(strncasecmp(argv[arg]+2,"all",3))
180     {
181     OBFormat* pFormat = Conv.FindFormat(argv[arg]+2);
182     if(pFormat)
183     {
184     cout << argv[arg]+2 << " " << pFormat->Description() << endl;
185     if(strlen(pFormat->SpecificationURL()))
186     cout << "Specification at: " << pFormat->SpecificationURL() << endl;
187     }
188     else
189     cout << "Format type: " << argv[arg]+2 << " was not recognized" <<endl;
190     }
191     else
192     {
193     Formatpos pos;
194     OBFormat* pFormat;
195     const char* str=NULL;
196     while(OBConversion::GetNextFormat(pos,str,pFormat))
197     {
198     if((pFormat->Flags() & NOTWRITABLE) && (pFormat->Flags() & NOTREADABLE))
199     continue;
200     cout << str << endl;
201     const char* p = strchr(pFormat->Description(),'\n');
202     cout << p+1; //second line of description
203     if(strlen(pFormat->SpecificationURL()))
204     cout << "Specification at: " << pFormat->SpecificationURL();
205     cout << endl << endl;
206     }
207     }
208     }
209     else
210     help();
211 gezelter 1210 exit(0);
212    
213     case '-': //long option --name text
214     {
215     //Do nothing if name is empty
216     //Option's text is the next arg provided it doesn't start with -
217     char* nam = argv[arg]+2;
218     if(*nam != '\0')
219     {
220     string txt;
221     int i;
222     for(i=0; i<Conv.GetOptionParams(nam, OBConversion::GENOPTIONS)
223     && arg<argc-1 && argv[arg+1];++i) //removed && *argv[arg+1]!='-'
224     {
225     if(!txt.empty()) txt+=' ';
226     txt += argv[++arg];
227     }
228     if(*nam=='-')
229     {
230     // Is a API directive, e.g.---errorlevel
231     //Send to the pseudoformat "obapi" (without any leading -)
232     OBConversion apiConv;
233     OBFormat* pAPI= OBConversion::FindFormat("obapi");
234     if(pAPI)
235     {
236     apiConv.SetOutFormat(pAPI);
237     apiConv.AddOption(nam+1, OBConversion::GENOPTIONS, txt.c_str());
238     apiConv.Write(NULL, &std::cout);
239     }
240     }
241     else
242     // Is a long option name, e.g --addtotitle
243     Conv.AddOption(nam,OBConversion::GENOPTIONS,txt.c_str());
244     }
245     }
246     break;
247    
248     case 'm': //multiple output files
249     SplitOrBatch=true;
250     break;
251    
252     case 'a': //single character input option
253     p = argv[arg]+2;
254     DoOption(p,Conv,OBConversion::INOPTIONS,arg,argc,argv);
255     break;
256    
257     case 'x': //single character output option
258     p = argv[arg]+2;
259     DoOption(p,Conv,OBConversion::OUTOPTIONS,arg,argc,argv);
260     break;
261    
262 gezelter 1021 default: //single character general option
263     p = argv[arg]+1;
264     DoOption(p,Conv,OBConversion::GENOPTIONS,arg,argc,argv);
265     break;
266     }
267     }
268     else
269     {
270     //filenames
271     if(!gotOutType)
272     FileList.push_back(argv[arg]);
273     else
274     OutputFileName = argv[arg];
275     }
276     }
277     }
278    
279 gezelter 1210 // user didn't specify input and output format in commandline option
280     // try to parse it from program name (pdb2mdin means input format is pdb,
281     // output format is mdin)
282    
283 gezelter 1020 string formatName(program_name);
284     pos = formatName.find_first_of("2");
285     if(pos!=string::npos) {
286     if (!gotInType)
287 gezelter 1021 {
288 gezelter 1020 string tmpExt = formatName.substr(0, pos);
289     pInFormat = Conv.FindFormat(tmpExt.c_str());
290 gezelter 1021 if(pInFormat==NULL)
291     {
292     cerr << program_name << ": cannot read input format!" << endl;
293     usage();
294     } else
295     {
296 gezelter 1020 gotInType = true;
297     inputExt = tmpExt;
298 gezelter 1021 }
299     }
300 gezelter 1210
301 gezelter 1020 if (!gotOutType)
302 gezelter 1021 {
303 gezelter 1020 string tmpExt = formatName.substr(pos+1, string::npos);
304     pOutFormat = Conv.FindFormat(tmpExt.c_str());
305 gezelter 1021 if(pOutFormat==NULL)
306     {
307     cerr << program_name << ": cannot write output format!" << endl;
308     usage();
309     }else {
310     gotOutType = true;
311     outputExt = tmpExt;
312     }
313     }
314 gezelter 1020 }
315 gezelter 1021
316 gezelter 1210 if (!gotInType)
317 gezelter 1020 {
318 gezelter 1210 if(FileList.empty())
319     {
320     cerr << "No input file or format spec!" <<endl;
321     usage();
322     }
323 gezelter 1020 }
324 gezelter 1021
325 gezelter 1210 if (!gotOutType)
326 gezelter 1021 {
327 gezelter 1210 pOutFormat = Conv.FormatFromExt(OutputFileName.c_str());
328     if(pOutFormat==NULL)
329     {
330     cerr << program_name << ": cannot write output format!" << endl;
331     usage();
332     }
333 gezelter 1020 }
334    
335 gezelter 1210 Conv.SetInAndOutFormats(pInFormat, pOutFormat);
336 gezelter 1021
337 gezelter 1210 if(SplitOrBatch)
338     {
339     //Put * into output file name before extension (or ext.gz)
340     if(OutputFileName.empty())
341     {
342     OutputFileName = "*.";
343     OutputFileName += oext;
344     }
345     else
346     {
347     string::size_type pos = OutputFileName.rfind(".gz");
348     if(pos==string::npos)
349     pos = OutputFileName.rfind('.');
350     else
351     pos = OutputFileName.rfind('.',pos-1);
352     if(pos==string::npos)
353     OutputFileName += '*';
354     else
355     OutputFileName.insert(pos,"*");
356     }
357     }
358    
359     int count = Conv.FullConvert(FileList, OutputFileName, OutputFileList);
360 gezelter 1021
361 gezelter 1020 // send info message to clog -- don't mess up cerr or cout for user programs
362 gezelter 1210 //Get the last word on the first line of the description which should
363     //be "molecules", "reactions", etc and remove the s if only one object converted
364     std::string objectname(pOutFormat->TargetClassDescription());
365     pos = objectname.find('\n');
366     if(count==1) --pos;
367     objectname.erase(pos);
368     pos = objectname.rfind(' ');
369     if(pos==std::string::npos)
370     pos=0;
371     std::clog << count << objectname.substr(pos) << " converted" << endl;
372 gezelter 1020 if(OutputFileList.size()>1)
373 gezelter 1021 {
374     clog << OutputFileList.size() << " files output. The first is " << OutputFileList[0] <<endl;
375     }
376    
377 gezelter 1210 std::string messageSummary = obErrorLog.GetMessageSummary();
378     if (messageSummary.size())
379     {
380     clog << messageSummary << endl;
381     }
382    
383 gezelter 1020 #ifdef _DEBUG
384     //CM keep window open
385     cout << "Press any key to finish" <<endl;
386     getch();
387     #endif
388    
389     return 0;
390     }
391    
392 gezelter 1210 void DoOption(const char* p, OBConversion& Conv,
393     OBConversion::Option_type typ, int& arg, int argc, char *argv[])
394 gezelter 1020 {
395 gezelter 1021 while(p && *p) //can have multiple single char options
396 gezelter 1210 {
397     char ch[2]="?";
398     *ch = *p++;
399     const char* txt=NULL;
400     //Get the option text if needed
401     int nParams = Conv.GetOptionParams(ch, typ);
402     if(nParams)
403 gezelter 1021 {
404 gezelter 1210 if(*p)
405     {
406     txt = p; //use text immediately following the option letter
407     p=NULL; //no more single char options
408     }
409     else if(arg<argc-1)
410     {
411     txt = argv[++arg]; //use text from next arg
412     if(*txt=='-')
413 gezelter 1021 {
414 gezelter 1210 //...unless it is another option
415     cerr << "Option -" << ch << " takes a parameter" << endl;
416     exit(0);
417 gezelter 1021 }
418 gezelter 1210 }
419 gezelter 1021 }
420 gezelter 1210 Conv.AddOption(ch, typ, txt);
421     }
422 gezelter 1020 }
423    
424     void usage()
425     {
426 gezelter 1210 cout << program_name << ": part of OOPSE " <<
427 gezelter 1021 OOPSE_VERSION_MAJOR << "." << OOPSE_VERSION_MINOR << "." <<
428 gezelter 1210 OOPSE_VERSION_TINY << " and OpenBabel " << BABEL_VERSION << " -- "
429 gezelter 1021 << __DATE__ << " -- " << __TIME__ << endl;
430 gezelter 1020 cout << "Usage: " << program_name
431     << " [-i<input-type>] <name> [-o<output-type>] <name>" << endl;
432     cout << "Try -H option for more information." << endl;
433     /*
434     #ifdef _DEBUG
435     //CM keep window open
436     cout << "Press any key to finish" <<endl;
437     getch();
438     #endif
439     */
440     exit (0);
441     }
442    
443     void help()
444     {
445 gezelter 1210 cout << program_name << " converts chemical structures from one file format to another"<< endl << endl;
446 gezelter 1020 cout << "Usage: " << program_name << " <input spec> <output spec> [Options]" << endl << endl;
447     cout << "Each spec can be a file whose extension decides the format." << endl;
448     cout << "Optionally the format can be specified by preceding the file by" << endl;
449     cout << "-i<format-type> e.g. -ipdb, for input and -o<format-type> for output" << endl << endl;
450     cout << "See below for available format-types, which are the same as the " << endl;
451     cout << "file extensions and are case independent." << endl;
452     cout << "If no input or output file is given stdin or stdout are used instead." << endl << endl;
453     cout << "More than one input file can be specified and their names can contain" <<endl;
454     cout << "wildcard chars (* and ?).The molecules are aggregated in the output file.\n" << endl;
455     cout << OBConversion::Description(); // Conversion options
456     cout << " -H Outputs this help text" << endl;
457     cout << " -Hxxx (xxx is file format ID e.g. -Hpdb) gives format info" <<endl;
458     cout << " -Hall Outputs details of all formats" <<endl;
459     cout << " -V Outputs version number" <<endl;
460    
461    
462     OBFormat* pDefault = OBConversion::GetDefaultFormat();
463 gezelter 1021 if(pDefault)
464     cout << pDefault->TargetClassDescription();// some more options probably for OBMol
465 gezelter 1020
466 gezelter 1021 OBFormat* pAPI= OBConversion::FindFormat("obapi");
467     if(pAPI)
468     cout << pAPI->Description();
469    
470     cout << "The following file formats are recognized:" << endl;
471 gezelter 1020 Formatpos pos;
472     OBFormat* pFormat;
473     const char* str=NULL;
474     while(OBConversion::GetNextFormat(pos,str,pFormat))
475 gezelter 1021 {
476     if((pFormat->Flags() & NOTWRITABLE) && (pFormat->Flags() & NOTREADABLE))
477 gezelter 1210 continue;
478 gezelter 1021 cout << " " << str << endl;
479     }
480 gezelter 1020 cout << "\nSee further specific info and options using -H<format-type>, e.g. -Hpdb" << endl;
481     }
482    

Properties

Name Value
svn:executable *