ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-3.0/src/applications/mdinConverter/mdinConverter.cpp
Revision: 2446
Committed: Wed Nov 16 21:24:34 2005 UTC (18 years, 8 months ago) by tim
File size: 19029 byte(s)
Log Message:
adding mdinConverter

File Contents

# Content
1 /**********************************************************************
2 main.cpp - Main conversion program, command-line handling.
3
4 Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
5 Some portions Copyright (C) 2001-2005 by Geoffrey R. Hutchison
6 Some portions Copyright (C) 2004-2005 by Chris Morley
7
8 This file is part of the Open Babel project.
9 For more information, see <http://openbabel.sourceforge.net/>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation version 2 of the License.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19 ***********************************************************************/
20
21 #include "openbabel/babelconfig.hpp"
22 #if HAVE_IOSTREAM
23 #include <iostream>
24 #elif HAVE_IOSTREAM_H
25 #include <iostream.h>
26 #endif
27 #if HAVE_FSTREAM
28 #include <fstream>
29 #elif HAVE_FSTREAM_H
30 #include <fstream.h>
31 #endif
32 #if HAVE_SSTREAM
33 #include <sstream>
34 #elif
35 #include <sstream.h>
36 #endif
37
38 #include <string>
39 #include <map>
40 #if HAVE_CONIO_H
41 #include <conio.h>
42 #endif
43
44 #if !HAVE_STRNCASECMP
45 extern "C" int strncasecmp(const char *s1, const char *s2, size_t n);
46 #endif
47
48 #include "openbabel/obconversion.hpp"
49 #include "brains/Register.hpp"
50
51 using namespace std;
52 using namespace OpenBabel;
53 using namespace oopse;
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 registerOBFormats();
65 OBConversion Conv(&cin, &cout); //default input and output are console
66
67 // string GenOptions;
68 OBFormat* pInFormat = NULL;
69 OBFormat* pOutFormat = NULL;
70 vector<string> FileList, OutputFileList;
71 string OutputFileName;
72 // obMessageLevel filterLevel = obWarning; // 2 out of 5
73
74 // Parse commandline
75 bool gotInType = false, gotOutType = false;
76 bool UseSavedOptions = false;
77 bool SplitOrBatch=false;
78
79 char *oext;
80 char *iext;
81
82 //Save name of program without its path (and .exe)
83 string pn(argv[0]);
84 unsigned int 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 << "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 argument
119
120 if (strncasecmp(iext, "MIME", 4) == 0)
121 {
122 // get the MIME type from the next argument
123 iext = argv[++arg];
124 pInFormat = Conv.FormatFromMIME(iext);
125 }
126 else
127 {
128 //The ID provided by the OBFormat class is used as the identifying file extension
129 pInFormat = Conv.FindFormat(iext);
130 }
131 if(pInFormat==NULL)
132 {
133 cerr << program_name << ": cannot read input format!" << endl;
134 usage();
135 }
136 break;
137
138 case 'o':
139 gotOutType = true;
140 oext = argv[arg] + 2;
141 if(!*oext)
142 oext = argv[++arg]; //space left after -i: use next argument
143
144 if (strncasecmp(oext, "MIME", 4) == 0)
145 {
146 // get the MIME type from the next argument
147 oext = argv[++arg];
148 pOutFormat = Conv.FormatFromMIME(oext);
149 }
150 else
151 pOutFormat = Conv.FindFormat(oext);
152
153 if(pOutFormat==NULL)
154 {
155 cerr << program_name << ": cannot write output format!" << endl;
156 usage();
157 }
158 break;
159
160 case 'F':
161 if(!Conv.SetOutFormat("fpt"))
162 cout << "FingerprintFormat needs to be loaded" << endl;
163 else
164 {
165 Conv.AddOption("F",OBConversion::OUTOPTIONS);
166 Conv.Write(NULL);
167 }
168 return 0;
169
170 case '?':
171 case 'H':
172 if(isalnum(argv[arg][2]))
173 {
174 if(strncasecmp(argv[arg]+2,"all",3))
175 {
176 OBFormat* pFormat = Conv.FindFormat(argv[arg]+2);
177 if(pFormat)
178 {
179 cout << argv[arg]+2 << " " << pFormat->Description() << endl;
180 if(strlen(pFormat->SpecificationURL()))
181 cout << "Specification at: " << pFormat->SpecificationURL() << endl;
182 }
183 else
184 cout << "Format type: " << argv[arg]+2 << " was not recognized" <<endl;
185 }
186 else
187 {
188 Formatpos pos;
189 OBFormat* pFormat;
190 const char* str=NULL;
191 while(OBConversion::GetNextFormat(pos,str,pFormat))
192 {
193 if((pFormat->Flags() & NOTWRITABLE) && (pFormat->Flags() & NOTREADABLE))
194 continue;
195 cout << str << endl;
196 const char* p = strchr(pFormat->Description(),'\n');
197 cout << p+1; //second line of description
198 if(strlen(pFormat->SpecificationURL()))
199 cout << "Specification at: " << pFormat->SpecificationURL();
200 cout << endl << endl;
201 }
202 }
203 }
204 else
205 help();
206 exit(0);
207
208 case '-': //long option --name text
209 {
210 //Do nothing if name is empty
211 //Option's text is the next arg provided it doesn't start with -
212 char* nam = argv[arg]+2;
213 if(*nam != '\0')
214 {
215 const char* txt=NULL;
216 if(Conv.GetOptionParams(nam, OBConversion::OUTOPTIONS)
217 && arg<argc-1 && argv[arg+1] && *argv[arg+1]!='-')
218 txt = argv[++arg];
219 if(*nam=='-')
220 {
221 // Is a API directive, e.g.---errorlevel
222 //Send to the pseudoformat "obapi" (without any leading -)
223 OBConversion apiConv;
224 OBFormat* pAPI= OBConversion::FindFormat("obapi");
225 if(pAPI)
226 {
227 apiConv.SetOutFormat(pAPI);
228 apiConv.AddOption(nam+1, OBConversion::OUTOPTIONS, txt);
229 apiConv.Write(NULL);
230 }
231 }
232 else
233 // Is a long option name, e.g --addtotitle
234 Conv.AddOption(nam,OBConversion::GENOPTIONS,txt);
235 }
236 }
237 break;
238
239 case 'm': //multiple output files
240 SplitOrBatch=true;
241 break;
242
243 case 'a': //single character input option
244 p = argv[arg]+2;
245 DoOption(p,Conv,OBConversion::INOPTIONS,arg,argc,argv);
246 break;
247
248 case 'x': //single character output option
249 p = argv[arg]+2;
250 DoOption(p,Conv,OBConversion::OUTOPTIONS,arg,argc,argv);
251 break;
252
253 default: //single character general option
254 p = argv[arg]+1;
255 DoOption(p,Conv,OBConversion::GENOPTIONS,arg,argc,argv);
256 break;
257 }
258 }
259 else
260 {
261 //filenames
262 if(!gotOutType)
263 FileList.push_back(argv[arg]);
264 else
265 OutputFileName = argv[arg];
266 }
267 }
268 }
269
270 if(!gotOutType) //the last file is the output
271 {
272 if(FileList.empty())
273 {
274 cerr << "No output file or format spec!" << endl;
275 usage();
276 }
277 OutputFileName = FileList.back();
278 FileList.pop_back();
279 }
280
281 #ifdef _WIN32
282 //Expand wildcards in input filenames and add to FileList
283 vector<string> tempFileList(FileList);
284 FileList.clear();
285 vector<string>::iterator itr;
286 for(itr=tempFileList.begin();itr!=tempFileList.end();itr++)
287 DLHandler::findFiles (FileList, *itr);
288 #endif
289
290 // Conv.SetGeneralOptions(GenOptions.c_str());
291
292 if (!gotInType)
293 {
294 if(FileList.empty())
295 {
296 cerr << "No input file or format spec!" <<endl;
297 usage();
298 }
299 }
300
301 if (!gotOutType)
302 {
303 pOutFormat = Conv.FormatFromExt(OutputFileName.c_str());
304 if(pOutFormat==NULL)
305 {
306 cerr << program_name << ": cannot write output format!" << endl;
307 usage();
308 }
309 }
310
311 Conv.SetInAndOutFormats(pInFormat,pOutFormat);
312
313 if(SplitOrBatch)
314 {
315 //Put * into output file name before extension (or ext.gz)
316 if(OutputFileName.empty())
317 {
318 OutputFileName = "*.";
319 OutputFileName += oext;
320 }
321 else
322 {
323 unsigned int pos = OutputFileName.rfind(".gz");
324 if(pos==string::npos)
325 pos = OutputFileName.rfind('.');
326 else
327 pos = OutputFileName.rfind('.',pos-1);
328 if(pos==string::npos)
329 OutputFileName += '*';
330 else
331 OutputFileName.insert(pos,"*");
332 }
333 }
334
335 // send info message to clog -- don't mess up cerr or cout for user programs
336 int count = Conv.FullConvert(FileList, OutputFileName, OutputFileList);
337 if ( count == 1 )
338 clog << count << " molecule converted" << endl;
339 else
340 clog << count << " molecules converted" << endl;
341
342 if(OutputFileList.size()>1)
343 {
344 clog << OutputFileList.size() << " files output. The first is " << OutputFileList[0] <<endl;
345 }
346
347 #ifdef _DEBUG
348 //CM keep window open
349 cout << "Press any key to finish" <<endl;
350 getch();
351 #endif
352
353 return 0;
354 };
355
356 void DoOption(const char* p, OBConversion& Conv, OBConversion::Option_type typ, int& arg, int argc, char *argv[])
357 {
358 while(p && *p) //can have multiple single char options
359 {
360 char ch[2]="?";
361 *ch = *p++;
362 const char* txt=NULL;
363 //Get the option text if needed
364 int nParams = Conv.GetOptionParams(ch, typ);
365 if(nParams)
366 {
367 if(*p)
368 {
369 txt = p; //use text immediately following the option letter
370 p=NULL; //no more single char options
371 }
372 else if(arg<argc-1)
373 {
374 txt = argv[++arg]; //use text from next arg
375 if(*txt=='-')
376 {
377 //...unless it is another option
378 cerr << "Option -" << ch << " takes a parameter" << endl;
379 exit(0);
380 }
381 }
382 }
383 Conv.AddOption(ch, typ, txt);
384 }
385 }
386
387 void usage()
388 {
389 cout << "Open Babel " << BABEL_VERSION << " -- " << __DATE__ << " -- "
390 << __TIME__ << endl;
391 cout << "Usage: " << program_name
392 << " [-i<input-type>] <name> [-o<output-type>] <name>" << endl;
393 cout << "Try -H option for more information." << endl;
394 /*
395 #ifdef _DEBUG
396 //CM keep window open
397 cout << "Press any key to finish" <<endl;
398 getch();
399 #endif
400 */
401 exit (0);
402 }
403
404 void help()
405 {
406 cout << "Open Babel converts chemical structures from one file format to another"<< endl << endl;
407 cout << "Usage: " << program_name << " <input spec> <output spec> [Options]" << endl << endl;
408 cout << "Each spec can be a file whose extension decides the format." << endl;
409 cout << "Optionally the format can be specified by preceding the file by" << endl;
410 cout << "-i<format-type> e.g. -icml, for input and -o<format-type> for output" << endl << endl;
411 cout << "See below for available format-types, which are the same as the " << endl;
412 cout << "file extensions and are case independent." << endl;
413 cout << "If no input or output file is given stdin or stdout are used instead." << endl << endl;
414 cout << "More than one input file can be specified and their names can contain" <<endl;
415 cout << "wildcard chars (* and ?).The molecules are aggregated in the output file.\n" << endl;
416 cout << OBConversion::Description(); // Conversion options
417 cout << " -H Outputs this help text" << endl;
418 cout << " -Hxxx (xxx is file format ID e.g. -Hcml) gives format info" <<endl;
419 cout << " -Hall Outputs details of all formats" <<endl;
420 cout << " -V Outputs version number" <<endl;
421 cout << " -F Outputs the available fingerprint types" <<endl;
422 cout << " -m Produces multiple output files, to allow:" <<endl;
423 cout << " Splitting: e.g. " << program_name << " infile.mol new.smi -m" <<endl;
424 cout << " puts each molecule into new1.smi new2.smi etc" <<endl;
425 cout << " Batch conversion: e.g. " << program_name << " *.mol -osmi -m" <<endl;
426 cout << " converts each input file to a .smi file" << endl;
427 #ifdef _WIN32
428 cout << " In Windows these can also be done using the forms" <<endl;
429 cout << " " << program_name << " infile.mol new*.smi and " << program_name << " *.mol *.smi respectively.\n" <<endl;
430 #endif
431
432 OBFormat* pDefault = OBConversion::GetDefaultFormat();
433 if(pDefault)
434 cout << pDefault->TargetClassDescription();// some more options probably for OBMol
435
436 OBFormat* pAPI= OBConversion::FindFormat("obapi");
437 if(pAPI)
438 cout << pAPI->Description();
439
440 cout << "The following file formats are recognized:" << endl;
441 Formatpos pos;
442 OBFormat* pFormat;
443 const char* str=NULL;
444 while(OBConversion::GetNextFormat(pos,str,pFormat))
445 {
446 if((pFormat->Flags() & NOTWRITABLE) && (pFormat->Flags() & NOTREADABLE))
447 continue;
448 cout << " " << str << endl;
449 }
450 cout << "\nSee further specific info and options using -H<format-type>, e.g. -Hcml" << endl;
451 }
452
453 /* OpenBabel man page*/
454 /** \page babel a converter for chemistry and molecular modeling data files
455 *
456 * \n
457 * \par SYNOPSIS
458 *
459 * \b babel [-H<help-options>] [-V] [-m] [-d] [-h] [-p] [-s<SMARTS-pattern>] [-v<SMARTS-pattern>] [-f<#> -l<#>] [-c] [-x<format-options>] [-i<input-type>] \<infile\> [-o<output-type>] \<outfile\>
460 *
461 * \par DESCRIPTION
462 *
463 * Open Babel is a program designed to interconvert a number of
464 * file formats currently used in molecular modeling software. \n\n
465 *
466 * Note that Open Babel can also be used as a library to interconvert
467 * many file formats and to provide standard chemistry software routines.
468 * See the Open Babel web pages (http://openbabel.sourceforge.net) for more
469 * information.
470 *
471 * \par OPTIONS
472 *
473 * If only input and ouput files are given, Open Babel will guess
474 * the file type from the filename extension. \n\n
475 *
476 * \b -V :
477 * Output version number and exit \n\n
478 * \b -H :
479 * Output usage information \n\n
480 * \b -H\<format-ID\> :
481 * Output formatting information and options for format specified\n\n
482 * \b -Hall :
483 * Output formatting information and options for all formats\n\n
484 * \b -i :
485 * Specifies input format, see below for the available formats \n\n
486 * \b -o :
487 * Specifies output format, see below for the available formats \n\n
488 * \b -m :
489 * Produce multiple output files, to allow:\n
490 * * Splitting one input file - put each molecule into consecutively numbered output files \n
491 * * Batch conversion - convert each of multiple input files into a specified output format \n
492 * See examples below \n\n
493 * \b -d :
494 * Delete Hydrogens \n\n
495 * \b -h :
496 * Add Hydrogens \n\n
497 * \b -p :
498 * Add Hydrogens appropriate for pH (use transforms in phmodel.txt) \n\n
499 * \b -t :
500 * All input files describe a single molecule \n\n
501 * \b -f\<#\> :
502 * For multiple entries input, start import at molecule # \n\n
503 * \b -l\<#\> :
504 * For multiple entries input, stop import at molecule # \n\n
505 * \b -c :
506 * Center atomic coordinates at (0,0,0) \n\n
507 * \b -s\<SMARTS\> :
508 * Convert only molecules matching the SMARTS pattern specified \n\n
509 * \b -v\<SMARTS\> :
510 * Convert only molecules \b NOT matching SMARTS pattern specified \n\n
511 *
512 * \par FILE FORMATS
513 *
514 * The following formats are currently supported by Open Babel:
515 * \n alc -- Alchemy format
516 * \n bgf -- BGF format
517 * \n box -- Dock 3.5 Box format
518 * \n bs -- Ball and Stick format
519 * \n c3d1 -- Chem3D Cartesian 1 format
520 * \n c3d2 -- Chem3D Cartesian2 format
521 * \n caccrt -- Cacao format
522 * \n cache -- CAChe format [Writeonly]
523 * \n cacint -- CacaoInternal format [Writeonly]
524 * \n car -- MSI Biosym/Insight II CAR format [Readonly]
525 * \n ccc -- CCC format [Readonly]
526 * \n cht -- ChemTool format [Writeonly]
527 * \n cml -- Chemical Markup Language
528 * \n crk2d -- Chemical Resource Kit diagram format (2D)
529 * \n crk3d -- Chemical Resource Kit 3D format
530 * \n csr -- CSR format [Writeonly]
531 * \n cssr -- CSD CSSR format [Writeonly]
532 * \n ct -- ChemDraw Connection Table format
533 * \n dmol -- DMol3 coordinates format
534 * \n ent -- Protein Data Bank format
535 * \n feat -- Feature format
536 * \n fh -- Fenske-Hall Z-Matrix format [Writeonly]
537 * \n fix -- FIX format [Writeonly]
538 * \n g03 -- Gaussian98/03 Cartesian [Writeonly]
539 * \n g98 -- Gaussian98/03 Cartesian [Writeonly]
540 * \n gam -- GAMESS Output
541 * \n gamout -- GAMESS Output
542 * \n gau -- Gaussian98/03 Cartesian [Writeonly]
543 * \n gpr -- Ghemical format
544 * \n gr96 -- GROMOS96 format [Writeonly]
545 * \n hin -- HyperChem Input format
546 * \n ins -- ShelX format [Readonly]
547 * \n jout -- Jaguar output format
548 * \n mdl -- MDL MOL format
549 * \n mm1gp -- Ghemical format
550 * \n mm3 -- MM3 format [Writeonly]
551 * \n mmd -- MacroMod format
552 * \n mmod -- MacroMod format
553 * \n mol -- MDL MOL format
554 * \n mol2 -- Sybyl Mol2 format
555 * \n mopcrt -- MOPAC Cartesian format
556 * \n mopout -- MOPAC Output format [Readonly]
557 * \n mpqc -- MPQC format [Readonly]
558 * \n nwo -- NWChem format
559 * \n pdb -- Protein Data Bank format
560 * \n pov -- POV-Ray input format [Writeonly]
561 * \n pqs -- Parallel Quantum Solutions format
562 * \n prep -- Amber Prep format [Readonly]
563 * \n qcout -- QChem output format
564 * \n qm1gp -- Ghemical format
565 * \n report -- Report format [Writeonly]
566 * \n res -- ShelX format [Readonly]
567 * \n rxn -- MDL RXN format
568 * \n sd -- MDL MOL format
569 * \n sdf -- MDL MOL format
570 * \n smi -- SMILES format
571 * \n tmol -- TurboMole Coordinate format
572 * \n txyz -- Tinker format [Writeonly]
573 * \n unixyz -- UniChem XYZ format
574 * \n vmol -- ViewMol format
575 * \n xed -- XED format [Writeonly]
576 * \n xyz -- XYZ cartesian coordinates format
577 * \n zin -- ZINDO input format [Writeonly]
578 *
579 * \par FORMAT OPTIONS
580 * Individual file formats may have additional formatting options. \n
581 * Input format options are preceded by 'a', e.g. -as \n
582 * Output format options are preceded by 'x', e.g. -xn \n
583 * For further specific information and options, use -H<format-type> \n
584 * e.g., -Hcml
585 *
586 * \par EXAMPLES
587 * - Standard conversion \n
588 * babel -ixyz ethanol.xyz -opdb ethanol.pdb \n
589 * - Conversion from a SMI file in STDIN to a Mol2 file written to STDOUT \n
590 * babel -ismi -omol2 \n
591 * - Split a multi-molecule file into new1.smi, new2.smi, etc. \n
592 * babel infile.mol new.smi -m \n
593 *
594 * \par AUTHORS
595 *
596 * Open Babel is currently maintained by \b Geoff \b Hutchison, \b Chris \b Morley and \b Michael \b Banck.
597 *
598 * For more contributors to Open Babel, see http://openbabel.sourceforge.net/THANKS.shtml
599 *
600 * \par COPYRIGHT
601 * Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
602 * Some portions Copyright (C) 2001-2005 by Geoffrey R. Hutchison \n \n
603 * This program is free software; you can redistribute it and/or modify
604 * it under the terms of the GNU General Public License as published by
605 * the Free Software Foundation version 2 of the License.\n \n
606 * This program is distributed in the hope that it will be useful,
607 * but WITHOUT ANY WARRANTY; without even the implied warranty of
608 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
609 * GNU General Public License for more details.
610 *
611 * \par SEE ALSO
612 * The web pages for Open Babel can be found at http://openbabel.sourceforge.net/
613 **/