ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/applications/atom2md/atom2md.cpp
Revision: 1767
Committed: Fri Jul 6 22:01:58 2012 UTC (12 years, 9 months ago) by gezelter
File size: 16298 byte(s)
Log Message:
Various fixes required to compile OpenMD with the MS Visual C++ compiler

File Contents

# Content
1 /**********************************************************************
2 atom2md.cpp - OpenBabel-based conversion program to OpenMD 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-2009 by J. Daniel Gezelter
9
10 This file is part of both the OpenMD and Open Babel projects.
11 For more information, see <http://openmd.net> 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
42 #ifdef _MSC_VER
43 #define strncasecmp _strnicmp
44 #endif
45
46 #include <openbabel/obconversion.h>
47 #include <openbabel/plugin.h>
48 #include <cstdlib>
49 #include <cstring>
50
51 using namespace std;
52 using namespace OpenBabel;
53
54 void DoOption(const char* p, OBConversion& Conv, OBConversion::Option_type typ,
55 int& arg, int argc, char *argv[]);
56 void usage();
57 void help();
58
59 // There isn't a great way to do this -- we need to save argv[0] for usage()
60 static char *program_name;
61
62 int main(int argc,char *argv[])
63 {
64 OBConversion Conv(&cin, &cout); //default input and output are console
65
66 OBFormat* pInFormat = NULL;
67 OBFormat* pOutFormat = NULL;
68 vector<string> FileList, OutputFileList;
69 string OutputFileName;
70
71 // Parse commandline
72 bool gotInType = false, gotOutType = false;
73 bool SplitOrBatch=false;
74
75 char *oext = NULL;
76 char *iext = NULL;
77
78 // for use with command name to type conversion
79 string inputExt;
80 string outputExt;
81
82 //Save name of program without its path (and .exe)
83 string pn(argv[0]);
84 string::size_type pos;
85 #ifdef _WIN32
86 pos = pn.find(".exe");
87 if(pos!=string::npos)
88 argv[0][pos]='\0';
89 #endif
90 pos = pn.find_last_of("/\\");
91 if(pos==string::npos)
92 program_name=argv[0];
93 else
94 program_name=argv[0]+pos+1;
95
96 const char* p;
97 int arg;
98 for (arg = 1; arg < argc; ++arg)
99 {
100 if (argv[arg])
101 {
102 if (argv[arg][0] == '-')
103 {
104 switch (argv[arg][1])
105 {
106
107 case 'V':
108 {
109 cout << program_name << ": part of OpenMD " <<
110 OPENMD_VERSION_MAJOR << "." << OPENMD_VERSION_MINOR <<
111 "." << OPENMD_VERSION_TINY <<
112 " and Open Babel " << BABEL_VERSION << " -- "
113 << __DATE__ << " -- " << __TIME__ << endl;
114 exit(0);
115 }
116
117 case 'i':
118 gotInType = true;
119 iext = argv[arg] + 2;
120 if(!*iext)
121 iext = argv[++arg]; //space left after -i: use next argument
122
123 if (strncasecmp(iext, "MIME", 4) == 0)
124 {
125 // get the MIME type from the next argument
126 iext = argv[++arg];
127 pInFormat = Conv.FormatFromMIME(iext);
128 }
129 else
130 {
131 //The ID provided by the OBFormat class is used as the identifying file extension
132 pInFormat = Conv.FindFormat(iext);
133 }
134 if(pInFormat==NULL)
135 {
136 cerr << program_name << ": cannot read input format!" << 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 argument
146
147 if (strncasecmp(oext, "MIME", 4) == 0)
148 {
149 // get the MIME type from the next argument
150 oext = argv[++arg];
151 pOutFormat = Conv.FormatFromMIME(oext);
152 }
153 else
154 pOutFormat = Conv.FindFormat(oext);
155
156 if(pOutFormat==NULL)
157 {
158 cerr << program_name << ": cannot write output format!" << endl;
159 usage();
160 }
161 break;
162
163 /*case 'F':
164 if(!Conv.SetOutFormat("fpt"))
165 cout << "FingerprintFormat needs to be loaded" << endl;
166 else
167 {
168 Conv.AddOption("F",OBConversion::OUTOPTIONS);
169 Conv.Write(NULL);
170 }
171 return 0;
172 */
173 case 'L': //display a list of plugin type or classes
174 {
175 const char* param=NULL;
176 if(argc>arg+1)
177 param = argv[arg+2];
178 OBPlugin::List(argv[arg+1], param);
179 return 0;
180 }
181 case '?':
182 case 'H':
183 if(isalnum(argv[arg][2]) || arg==argc-2)
184 {
185 if(strncasecmp(argv[arg]+2,"all",3))
186 {
187 const char* pID= (arg==argc-2) ? argv[arg+1] : argv[arg]+2;
188 OBFormat* pFormat = Conv.FindFormat(pID);
189 if(pFormat)
190 {
191 cout << pID << " " << pFormat->Description() << endl;
192 if(pFormat->Flags() & NOTWRITABLE)
193 cout << " This format is Read-only" << endl;
194 if(pFormat->Flags() & NOTREADABLE)
195 cout << " This format is Write-only" << endl;
196
197 if(strlen(pFormat->SpecificationURL()))
198 cout << "Specification at: " << pFormat->SpecificationURL() << endl;
199 }
200 else
201 cout << "Format type: " << pID << " was not recognized" <<endl;
202 }
203 else
204 {
205 OBPlugin::List("formats","verbose");
206 }
207 }
208 else
209 help();
210 return 0;
211
212 case '-': //long option --name text
213 {
214 //Do nothing if name is empty
215 //Option's text is the next arg provided it doesn't start with -
216 char* nam = argv[arg]+2;
217 if(*nam != '\0')
218 {
219 string txt;
220 int i;
221 for(i=0; i<Conv.GetOptionParams(nam, OBConversion::GENOPTIONS)
222 && arg<argc-1 && argv[arg+1];++i) //removed && *argv[arg+1]!='-'
223 {
224 if(!txt.empty()) txt+=' ';
225 txt += argv[++arg];
226 }
227 if(*nam=='-')
228 {
229 // Is a API directive, e.g.---errorlevel
230 //Send to the pseudoformat "obapi" (without any leading -)
231 OBConversion apiConv;
232 OBFormat* pAPI= OBConversion::FindFormat("obapi");
233 if(pAPI)
234 {
235 apiConv.SetOutFormat(pAPI);
236 apiConv.AddOption(nam+1, OBConversion::GENOPTIONS, txt.c_str());
237 apiConv.Write(NULL, &std::cout);
238 }
239 }
240 else
241 // Is a long option name, e.g --addtotitle
242 Conv.AddOption(nam,OBConversion::GENOPTIONS,txt.c_str());
243 }
244 }
245 break;
246
247 case 'm': //multiple output files
248 SplitOrBatch=true;
249 break;
250
251 case 'a': //single character input option
252 p = argv[arg]+2;
253 DoOption(p,Conv,OBConversion::INOPTIONS,arg,argc,argv);
254 break;
255
256 case 'x': //single character output option
257 p = argv[arg]+2;
258 DoOption(p,Conv,OBConversion::OUTOPTIONS,arg,argc,argv);
259 break;
260
261 default: //single character general option
262 p = argv[arg]+1;
263 DoOption(p,Conv,OBConversion::GENOPTIONS,arg,argc,argv);
264 break;
265 }
266 }
267 else
268 {
269 //filenames
270 if(!gotOutType)
271 FileList.push_back(argv[arg]);
272 else
273 OutputFileName = argv[arg];
274 }
275 }
276 }
277
278 // user didn't specify input and output format in commandline option
279 // try to parse it from program name (pdb2md means input format is pdb,
280 // output format is md)
281
282 string formatName(program_name);
283 pos = formatName.find_first_of("2");
284 if(pos!=string::npos) {
285 if (!gotInType)
286 {
287 string tmpExt = formatName.substr(0, pos);
288 pInFormat = Conv.FindFormat(tmpExt.c_str());
289 if(pInFormat==NULL)
290 {
291 cerr << program_name << ": cannot read input format!" << endl;
292 usage();
293 } else
294 {
295 gotInType = true;
296 inputExt = tmpExt;
297 }
298 }
299
300 if (!gotOutType)
301 {
302 string tmpExt = formatName.substr(pos+1, string::npos);
303 pOutFormat = Conv.FindFormat(tmpExt.c_str());
304 if(pOutFormat==NULL)
305 {
306 cerr << program_name << ": cannot write output format!" << endl;
307 usage();
308 }else {
309 gotOutType = true;
310 outputExt = tmpExt;
311 }
312 }
313 }
314
315 if(!gotOutType) //the last file is the output
316 {
317 if(FileList.empty())
318 {
319 cerr << "No output file or format spec!" << endl;
320 usage();
321 }
322 OutputFileName = FileList.back();
323 FileList.pop_back();
324 }
325
326 #ifdef _WIN32
327 //Expand wildcards in input filenames and add to FileList
328 vector<string> tempFileList(FileList);
329 FileList.clear();
330 vector<string>::iterator itr;
331 for(itr=tempFileList.begin();itr!=tempFileList.end();++itr)
332 DLHandler::findFiles (FileList, *itr);
333 #endif
334
335 if (!gotInType)
336 {
337 if(FileList.empty())
338 {
339 cerr << "No input file or format spec!" <<endl;
340 usage();
341 }
342 }
343
344 if (!gotOutType)
345 {
346 pOutFormat = Conv.FormatFromExt(OutputFileName.c_str());
347 if(pOutFormat==NULL)
348 {
349 cerr << program_name << ": cannot write output format!" << endl;
350 usage();
351 }
352 }
353
354 if(!Conv.SetInFormat(pInFormat))
355 {
356 cerr << "Invalid input format" << endl;
357 usage();
358 }
359 if(!Conv.SetOutFormat(pOutFormat))
360 {
361 cerr << "Invalid output format" << endl;
362 usage();
363 }
364
365 if(SplitOrBatch)
366 {
367 //Put * into output file name before extension (or ext.gz)
368 if(OutputFileName.empty())
369 {
370 OutputFileName = "*.";
371 if (oext != NULL)
372 OutputFileName += oext;
373 }
374 else
375 {
376 string::size_type pos = OutputFileName.rfind(".gz");
377 if(pos==string::npos)
378 pos = OutputFileName.rfind('.');
379 else
380 pos = OutputFileName.rfind('.',pos-1);
381 if(pos==string::npos)
382 OutputFileName += '*';
383 else
384 OutputFileName.insert(pos,"*");
385 }
386 }
387
388 int count = Conv.FullConvert(FileList, OutputFileName, OutputFileList);
389
390 Conv.ReportNumberConverted(count);
391
392 if(OutputFileList.size()>1)
393 {
394 clog << OutputFileList.size() << " files output. The first is " << OutputFileList[0] <<endl;
395 }
396
397 std::string messageSummary = obErrorLog.GetMessageSummary();
398 if (messageSummary.size())
399 {
400 clog << messageSummary << endl;
401 }
402
403 #ifdef DEBUG
404 //CM keep window open
405 cout << "Press any key to finish" <<endl;
406 getch();
407 #endif
408
409 return 0;
410 }
411
412 void DoOption(const char* p, OBConversion& Conv,
413 OBConversion::Option_type typ, int& arg, int argc, char *argv[])
414 {
415 while(p && *p) //can have multiple single char options
416 {
417 char ch[2]="?";
418 *ch = *p++;
419 const char* txt=NULL;
420 //Get the option text if needed
421 int nParams = Conv.GetOptionParams(ch, typ);
422 if(nParams)
423 {
424 if(*p)
425 {
426 txt = p; //use text immediately following the option letter
427 p=NULL; //no more single char options
428 }
429 else if(arg<argc-1)
430 {
431 txt = argv[++arg]; //use text from next arg
432 if(*txt=='-')
433 {
434 //...unless it is another option
435 cerr << "Option -" << ch << " takes a parameter" << endl;
436 exit(0);
437 }
438 }
439 }
440 Conv.AddOption(ch, typ, txt);
441 }
442 }
443
444 void usage()
445 {
446 cout << program_name << ": part of OpenMD " <<
447 OPENMD_VERSION_MAJOR << "." << OPENMD_VERSION_MINOR << "." <<
448 OPENMD_VERSION_TINY << " and OpenBabel " << BABEL_VERSION << " -- "
449 << __DATE__ << " -- " << __TIME__ << endl;
450 cout << "Usage: " << program_name
451 << " [-i<input-type>] <name> [-o<output-type>] <name>" << endl;
452 cout << "Try -H option for more information." << endl;
453
454 #ifdef DEBUG
455 //CM keep window open
456 cout << "Press any key to finish" <<endl;
457 getch();
458 #endif
459 exit (0);
460 }
461
462 void help()
463 {
464 cout << program_name << " converts chemical structures from one file format to another"<< endl << endl;
465 cout << "Usage: " << program_name << " <input spec> <output spec> [Options]" << endl << endl;
466 cout << "Each spec can be a file whose extension decides the format." << endl;
467 cout << "Optionally the format can be specified by preceding the file by" << endl;
468 cout << "-i<format-type> e.g. -ipdb, for input and -o<format-type> for output" << endl << endl;
469 cout << "See below for available format-types, which are the same as the " << endl;
470 cout << "file extensions and are case independent." << endl;
471 cout << "If no input or output file is given stdin or stdout are used instead." << endl << endl;
472 cout << "More than one input file can be specified and their names can contain" <<endl;
473 cout << "wildcard chars (* and ?).The molecules are aggregated in the output file.\n" << endl;
474 cout << OBConversion::Description(); // Conversion options
475 cout << " -H Outputs this help text" << endl;
476 cout << " -Hxxx (xxx is file format ID e.g. -Hpdb) gives format info" <<endl;
477 cout << " -Hall Outputs details of all formats" <<endl;
478 cout << " -V Outputs version number" <<endl;
479
480
481 OBFormat* pDefault = OBConversion::GetDefaultFormat();
482 if(pDefault)
483 cout << pDefault->TargetClassDescription();// some more options probably for OBMol
484
485 OBFormat* pAPI= OBConversion::FindFormat("obapi");
486 if(pAPI)
487 cout << pAPI->Description();
488
489 cout << "The following file formats are recognized:" << endl;
490 Formatpos pos;
491 OBFormat* pFormat;
492 const char* str=NULL;
493 while(OBConversion::GetNextFormat(pos,str,pFormat))
494 {
495 if((pFormat->Flags() & NOTWRITABLE) && (pFormat->Flags() & NOTREADABLE))
496 continue;
497 cout << " " << str << endl;
498 }
499 cout << "\nSee further specific info and options using -H<format-type>, e.g. -Hpdb" << endl;
500 }
501

Properties

Name Value
svn:executable *
svn:keywords Author Id Revision Date