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

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

Properties

Name Value
svn:executable *