ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/applications/atom2md/atom2md.cpp
Revision: 1390
Committed: Wed Nov 25 20:02:06 2009 UTC (15 years, 5 months ago) by gezelter
File size: 16295 byte(s)
Log Message:
Almost all of the changes necessary to create OpenMD out of our old
project (OOPSE-4)

File Contents

# Content
1 /**********************************************************************
2 atom2md.cpp - OpenBabel-based conversion program to OpenMD 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 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 #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 OpenMD " <<
107 OPENMD_VERSION_MAJOR << "." << OPENMD_VERSION_MINOR <<
108 "." << OPENMD_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 return 0;
389 }
390
391 void DoOption(const char* p, OBConversion& Conv,
392 OBConversion::Option_type typ, int& arg, int argc, char *argv[])
393 {
394 while(p && *p) //can have multiple single char options
395 {
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 {
403 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 {
413 //...unless it is another option
414 cerr << "Option -" << ch << " takes a parameter" << endl;
415 exit(0);
416 }
417 }
418 }
419 Conv.AddOption(ch, typ, txt);
420 }
421 }
422
423 void usage()
424 {
425 cout << program_name << ": part of OpenMD " <<
426 OPENMD_VERSION_MAJOR << "." << OPENMD_VERSION_MINOR << "." <<
427 OPENMD_VERSION_TINY << " and OpenBabel " << BABEL_VERSION << " -- "
428 << __DATE__ << " -- " << __TIME__ << endl;
429 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 cout << program_name << " converts chemical structures from one file format to another"<< endl << endl;
445 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 if(pDefault)
463 cout << pDefault->TargetClassDescription();// some more options probably for OBMol
464
465 OBFormat* pAPI= OBConversion::FindFormat("obapi");
466 if(pAPI)
467 cout << pAPI->Description();
468
469 cout << "The following file formats are recognized:" << endl;
470 Formatpos pos;
471 OBFormat* pFormat;
472 const char* str=NULL;
473 while(OBConversion::GetNextFormat(pos,str,pFormat))
474 {
475 if((pFormat->Flags() & NOTWRITABLE) && (pFormat->Flags() & NOTREADABLE))
476 continue;
477 cout << " " << str << endl;
478 }
479 cout << "\nSee further specific info and options using -H<format-type>, e.g. -Hpdb" << endl;
480 }
481

Properties

Name Value
svn:executable *