ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/applications/atom2md/atom2md.cpp
Revision: 3319
Committed: Wed Jan 23 03:45:33 2008 UTC (16 years, 5 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 2969 /**********************************************************************
2 gezelter 2970 atom2md.cpp - OpenBabel-based conversion program to OOPSE MD file,
3     command-line handling.
4 gezelter 2969
5     Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
6 gezelter 3319 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 2969
10 gezelter 3319 This file is part of both the OOPSE and Open Babel projects.
11 gezelter 2970 For more information, see <http://oopse.org> and <http://openbabel.sourceforge.net/>
12 gezelter 2969
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 3319
25     // used to set import/export for Cygwin DLLs
26     #ifdef WIN32
27     #define USING_OBDLL
28 gezelter 2969 #endif
29    
30 gezelter 3319 #include <openbabel/babelconfig.h>
31    
32     #include <iostream>
33     #include <fstream>
34     #include <sstream>
35    
36 gezelter 2969 #include <string>
37     #include <map>
38     #if HAVE_CONIO_H
39     #include <conio.h>
40     #endif
41 gezelter 3319 #include <cstdlib>
42 gezelter 2969
43     #if !HAVE_STRNCASECMP
44     extern "C" int strncasecmp(const char *s1, const char *s2, size_t n);
45     #endif
46    
47 gezelter 3319 #include <openbabel/obconversion.h>
48 gezelter 2969
49     using namespace std;
50     using namespace OpenBabel;
51 gezelter 3319
52     void DoOption(const char* p, OBConversion& Conv,
53     OBConversion::Option_type typ, int& arg, int argc,
54     char *argv[]);
55 gezelter 2969 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 3319
65 gezelter 2969 OBFormat* pInFormat = NULL;
66     OBFormat* pOutFormat = NULL;
67     vector<string> FileList, OutputFileList;
68     string OutputFileName;
69 gezelter 3319
70 gezelter 2969 // Parse commandline
71     bool gotInType = false, gotOutType = false;
72 gezelter 3319 bool SplitOrBatch=false;
73    
74 gezelter 2969 char *oext;
75     char *iext;
76     string inputExt;
77     string outputExt;
78 gezelter 3319
79 gezelter 2969 //Save name of program without its path (and .exe)
80     string pn(argv[0]);
81 gezelter 3319 string::size_type pos;
82 gezelter 2969 #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 3319
93 gezelter 2970 const char* p;
94     int arg;
95 gezelter 3319 for (arg = 1; arg < argc; ++arg)
96 gezelter 2970 {
97     if (argv[arg])
98     {
99     if (argv[arg][0] == '-')
100     {
101     switch (argv[arg][1])
102     {
103 gezelter 3319
104 gezelter 2970 case 'V':
105     {
106 gezelter 3319 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 2970 << __DATE__ << " -- " << __TIME__ << endl;
111     exit(0);
112     }
113 gezelter 3319
114 gezelter 2970 case 'i':
115     gotInType = true;
116     iext = argv[arg] + 2;
117     if(!*iext)
118 gezelter 3319 iext = argv[++arg]; // space left after -i: use next
119     // argument
120    
121 gezelter 2970 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 3319 // The ID provided by the OBFormat class is used as the
130     // identifying file extension
131 gezelter 2970 pInFormat = Conv.FindFormat(iext);
132     }
133     if(pInFormat==NULL)
134     {
135 gezelter 3319 cerr << program_name << ": cannot read input format!"
136     << endl;
137 gezelter 2970 usage();
138     }
139     break;
140    
141     case 'o':
142     gotOutType = true;
143     oext = argv[arg] + 2;
144     if(!*oext)
145 gezelter 3319 oext = argv[++arg]; // space left after -i: use next
146     // argument
147    
148 gezelter 2970 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 3319
157 gezelter 2970 if(pOutFormat==NULL)
158     {
159 gezelter 3319 cerr << program_name << ": cannot write output format!"
160     << endl;
161 gezelter 2970 usage();
162     }
163 gezelter 3319 break;
164 gezelter 2970
165 gezelter 3319 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 2970 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 3319 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 2970 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 3319 // 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 2969 string formatName(program_name);
284     pos = formatName.find_first_of("2");
285     if(pos!=string::npos) {
286     if (!gotInType)
287 gezelter 2970 {
288 gezelter 2969 string tmpExt = formatName.substr(0, pos);
289     pInFormat = Conv.FindFormat(tmpExt.c_str());
290 gezelter 2970 if(pInFormat==NULL)
291     {
292     cerr << program_name << ": cannot read input format!" << endl;
293     usage();
294     } else
295     {
296 gezelter 2969 gotInType = true;
297     inputExt = tmpExt;
298 gezelter 2970 }
299     }
300 gezelter 3319
301 gezelter 2969 if (!gotOutType)
302 gezelter 2970 {
303 gezelter 2969 string tmpExt = formatName.substr(pos+1, string::npos);
304     pOutFormat = Conv.FindFormat(tmpExt.c_str());
305 gezelter 2970 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 2969 }
315 gezelter 2970
316 gezelter 3319 if (!gotInType)
317 gezelter 2969 {
318 gezelter 3319 if(FileList.empty())
319     {
320     cerr << "No input file or format spec!" <<endl;
321     usage();
322     }
323 gezelter 2969 }
324 gezelter 2970
325 gezelter 3319 if (!gotOutType)
326 gezelter 2970 {
327 gezelter 3319 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 2969 }
334    
335 gezelter 3319 Conv.SetInAndOutFormats(pInFormat, pOutFormat);
336 gezelter 2970
337 gezelter 3319 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 2970
361 gezelter 2969 // send info message to clog -- don't mess up cerr or cout for user programs
362 gezelter 3319 //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 2969 if(OutputFileList.size()>1)
373 gezelter 2970 {
374     clog << OutputFileList.size() << " files output. The first is " << OutputFileList[0] <<endl;
375     }
376    
377 gezelter 3319 std::string messageSummary = obErrorLog.GetMessageSummary();
378     if (messageSummary.size())
379     {
380     clog << messageSummary << endl;
381     }
382    
383 gezelter 2969 #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 3319 void DoOption(const char* p, OBConversion& Conv,
393     OBConversion::Option_type typ, int& arg, int argc, char *argv[])
394 gezelter 2969 {
395 gezelter 2970 while(p && *p) //can have multiple single char options
396 gezelter 3319 {
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 2970 {
404 gezelter 3319 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 2970 {
414 gezelter 3319 //...unless it is another option
415     cerr << "Option -" << ch << " takes a parameter" << endl;
416     exit(0);
417 gezelter 2970 }
418 gezelter 3319 }
419 gezelter 2970 }
420 gezelter 3319 Conv.AddOption(ch, typ, txt);
421     }
422 gezelter 2969 }
423    
424     void usage()
425     {
426 gezelter 3319 cout << program_name << ": part of OOPSE " <<
427 gezelter 2970 OOPSE_VERSION_MAJOR << "." << OOPSE_VERSION_MINOR << "." <<
428 gezelter 3319 OOPSE_VERSION_TINY << " and OpenBabel " << BABEL_VERSION << " -- "
429 gezelter 2970 << __DATE__ << " -- " << __TIME__ << endl;
430 gezelter 2969 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 3319 cout << program_name << " converts chemical structures from one file format to another"<< endl << endl;
446 gezelter 2969 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 2970 if(pDefault)
464     cout << pDefault->TargetClassDescription();// some more options probably for OBMol
465 gezelter 2969
466 gezelter 2970 OBFormat* pAPI= OBConversion::FindFormat("obapi");
467     if(pAPI)
468     cout << pAPI->Description();
469    
470     cout << "The following file formats are recognized:" << endl;
471 gezelter 2969 Formatpos pos;
472     OBFormat* pFormat;
473     const char* str=NULL;
474     while(OBConversion::GetNextFormat(pos,str,pFormat))
475 gezelter 2970 {
476     if((pFormat->Flags() & NOTWRITABLE) && (pFormat->Flags() & NOTREADABLE))
477 gezelter 3319 continue;
478 gezelter 2970 cout << " " << str << endl;
479     }
480 gezelter 2969 cout << "\nSee further specific info and options using -H<format-type>, e.g. -Hpdb" << endl;
481     }
482    

Properties

Name Value
svn:executable *