ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/applications/atom2md/atom2md.cpp
Revision: 3446
Committed: Wed Sep 10 19:51:45 2008 UTC (15 years, 9 months ago) by cli2
File size: 16284 byte(s)
Log Message:
Inversion fixes and amber mostly working

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 cli2 3446
383 gezelter 2969 #ifdef _DEBUG
384     //CM keep window open
385     cout << "Press any key to finish" <<endl;
386     getch();
387     #endif
388     return 0;
389     }
390    
391 gezelter 3319 void DoOption(const char* p, OBConversion& Conv,
392     OBConversion::Option_type typ, int& arg, int argc, char *argv[])
393 gezelter 2969 {
394 gezelter 2970 while(p && *p) //can have multiple single char options
395 gezelter 3319 {
396     char ch[2]="?";
397     *ch = *p++;
398     const char* txt=NULL;
399     //Get the option text if needed
400     int nParams = Conv.GetOptionParams(ch, typ);
401     if(nParams)
402 gezelter 2970 {
403 gezelter 3319 if(*p)
404     {
405     txt = p; //use text immediately following the option letter
406     p=NULL; //no more single char options
407     }
408     else if(arg<argc-1)
409     {
410     txt = argv[++arg]; //use text from next arg
411     if(*txt=='-')
412 gezelter 2970 {
413 gezelter 3319 //...unless it is another option
414     cerr << "Option -" << ch << " takes a parameter" << endl;
415     exit(0);
416 gezelter 2970 }
417 gezelter 3319 }
418 gezelter 2970 }
419 gezelter 3319 Conv.AddOption(ch, typ, txt);
420     }
421 gezelter 2969 }
422    
423     void usage()
424     {
425 gezelter 3319 cout << program_name << ": part of OOPSE " <<
426 gezelter 2970 OOPSE_VERSION_MAJOR << "." << OOPSE_VERSION_MINOR << "." <<
427 gezelter 3319 OOPSE_VERSION_TINY << " and OpenBabel " << BABEL_VERSION << " -- "
428 gezelter 2970 << __DATE__ << " -- " << __TIME__ << endl;
429 gezelter 2969 cout << "Usage: " << program_name
430     << " [-i<input-type>] <name> [-o<output-type>] <name>" << endl;
431     cout << "Try -H option for more information." << endl;
432     /*
433     #ifdef _DEBUG
434     //CM keep window open
435     cout << "Press any key to finish" <<endl;
436     getch();
437     #endif
438     */
439     exit (0);
440     }
441    
442     void help()
443     {
444 gezelter 3319 cout << program_name << " converts chemical structures from one file format to another"<< endl << endl;
445 gezelter 2969 cout << "Usage: " << program_name << " <input spec> <output spec> [Options]" << endl << endl;
446     cout << "Each spec can be a file whose extension decides the format." << endl;
447     cout << "Optionally the format can be specified by preceding the file by" << endl;
448     cout << "-i<format-type> e.g. -ipdb, for input and -o<format-type> for output" << endl << endl;
449     cout << "See below for available format-types, which are the same as the " << endl;
450     cout << "file extensions and are case independent." << endl;
451     cout << "If no input or output file is given stdin or stdout are used instead." << endl << endl;
452     cout << "More than one input file can be specified and their names can contain" <<endl;
453     cout << "wildcard chars (* and ?).The molecules are aggregated in the output file.\n" << endl;
454     cout << OBConversion::Description(); // Conversion options
455     cout << " -H Outputs this help text" << endl;
456     cout << " -Hxxx (xxx is file format ID e.g. -Hpdb) gives format info" <<endl;
457     cout << " -Hall Outputs details of all formats" <<endl;
458     cout << " -V Outputs version number" <<endl;
459    
460    
461     OBFormat* pDefault = OBConversion::GetDefaultFormat();
462 gezelter 2970 if(pDefault)
463     cout << pDefault->TargetClassDescription();// some more options probably for OBMol
464 gezelter 2969
465 gezelter 2970 OBFormat* pAPI= OBConversion::FindFormat("obapi");
466     if(pAPI)
467     cout << pAPI->Description();
468    
469     cout << "The following file formats are recognized:" << endl;
470 gezelter 2969 Formatpos pos;
471     OBFormat* pFormat;
472     const char* str=NULL;
473     while(OBConversion::GetNextFormat(pos,str,pFormat))
474 gezelter 2970 {
475     if((pFormat->Flags() & NOTWRITABLE) && (pFormat->Flags() & NOTREADABLE))
476 gezelter 3319 continue;
477 gezelter 2970 cout << " " << str << endl;
478     }
479 gezelter 2969 cout << "\nSee further specific info and options using -H<format-type>, e.g. -Hpdb" << endl;
480     }
481    

Properties

Name Value
svn:executable *