00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00019
00034
00035
00036
00038
00039
00040 #include <cmath>
00041 #include <iostream>
00042
00043
00044 #include <qfiledialog.h>
00045 #include <qmessagebox.h>
00046 #include <qstring.h>
00047 #include <qstringlist.h>
00048
00049 #include <qdatetime.h>
00050
00051 #ifdef USE_OPENBABEL1
00052
00053 #ifdef Q_OS_WIN32
00054 #include <mol.h>
00055 #include <molvector.h>
00056 #include <obutil.h>
00057 #include <parsmart.h>
00058 #include <rotor.h>
00059 #include <binary.h>
00060 #else
00061 #include <openbabel/mol.h>
00062 #include <openbabel/molvector.h>
00063 #include <openbabel/obutil.h>
00064 #include <openbabel/parsmart.h>
00065 #include <openbabel/rotor.h>
00066 #include <openbabel/binary.h>
00067 #endif
00068 using namespace OpenBabel;
00069 #endif
00070 #ifdef USE_OPENBABEL2
00071
00072 #ifdef Q_OS_WIN32
00073 #include <mol.h>
00074 #include <obconversion.h>
00075 #else
00076 #include <openbabel/mol.h>
00077 #include <openbabel/obconversion.h>
00078 #endif
00079 using namespace OpenBabel;
00080 #endif
00081
00082
00083 #include "atomset.h"
00084 #include "crdfactory.h"
00085 #include "version.h"
00086
00087
00091
00093 CrdFactory::~CrdFactory()
00095 {
00096
00097 }
00098
00100 unsigned int CrdFactory::readFromFile(AtomSet* atoms, QString filename)
00104 {
00105
00106 if(filename.isEmpty())
00107 {
00108 QStringList filterList = supportedInputFormats();
00109 QString fileFilter = filterList.join(";;");
00110 QString fileTitle = QFileDialog::tr("Choose coordinates");
00111 filename = QFileDialog::getOpenFileName(QString::null, fileFilter, 0, 0, fileTitle);
00112 if(filename.isEmpty())
00113 return Cancelled;
00114 }
00115
00116
00117 if(!validInputFormat(filename))
00118 return UnknownExtension;
00119
00120
00121 if(braboExtension(filename))
00122 {
00124 return readBraboFile(atoms, filename);
00125 }
00126 else if(xmolExtension(filename))
00127 {
00129 return readXmolFile(atoms, filename);
00130 }
00131 else if(gaussianExtension(filename))
00132 {
00134 return readGaussianFile(atoms, filename);
00135 }
00136 #ifdef USE_OPENBABEL1
00137 else
00138 {
00140
00141 char* fn = qstrdup(filename.latin1());
00142 io_type fileType = extab.FilenameToType(fn);
00143 delete fn;
00144 std::ifstream inFileStream;
00145 inFileStream.open(filename.latin1());
00146 if(!inFileStream)
00147 return ErrorOpen;
00148 OBMol* mol = new OBMol(fileType);
00149 if(!OBFileFormat::ReadMolecule(inFileStream, *mol))
00150 {
00151 delete mol;
00152 return ErrorRead;
00153 }
00154
00155 atoms->clear();
00156 atoms->reserve(mol->NumAtoms());
00157 vector<OBNodeBase*>::iterator it;
00158 for(OBAtom* atom = mol->BeginAtom(it); atom; atom = mol->NextAtom(it))
00159 atoms->addAtom(atom->GetX(), atom->GetY(), atom->GetZ(), static_cast<unsigned int>(atom->GetAtomicNum()));
00160 delete mol;
00161 }
00162 #endif
00163 #ifdef USE_OPENBABEL2
00164 else
00165 {
00167 QTime timer;
00168 timer.start();
00169
00170 OBConversion conv;
00171 OBFormat* fileFormat = conv.FormatFromExt(filename.latin1());
00172 if(!fileFormat || !conv.SetInFormat(fileFormat))
00173 return UnknownExtension;
00174
00175 std::ifstream inFileStream;
00176 inFileStream.open(filename.latin1());
00177 if(!inFileStream)
00178 return ErrorOpen;
00179 OBMol mol;
00180 if(!conv.Read(&mol, &inFileStream))
00181 return ErrorRead;
00182 qDebug("time to read the OpenBabel file: %f seconds", timer.restart()/1000.f);
00183
00184 atoms->clear();
00185 atoms->reserve(mol.NumAtoms());
00186 for(OBMolAtomIter atom(mol); atom; atom++)
00187 atoms->addAtom(atom->x(), atom->y(), atom->z(), atom->GetAtomicNum());
00188 qDebug("time to fill the AtomSet: %f seconds", timer.restart()/1000.f);
00189 }
00190 #endif
00191 return OK;
00192 }
00193
00195 unsigned int CrdFactory::readFromFile(AtomSet* atoms)
00199 {
00200 QString emptyString;
00201 return readFromFile(atoms, QString::null);
00202 }
00203
00205 unsigned int CrdFactory::writeToFile(AtomSet* atoms, QString filename, bool extendedFormat)
00210 {
00211 if(filename.isEmpty())
00212 {
00214 QStringList filterList = supportedOutputFormats();
00215 QString fileFilter = filterList.join(";;");
00216 QString fileTitle = QFileDialog::tr("Choose a filename");
00217 QString selectedFilter;
00218 filename = QFileDialog::getSaveFileName(0, fileFilter, 0, 0, fileTitle, &selectedFilter);
00219 if(filename.isEmpty())
00220 return Cancelled;
00221
00222
00223 QString selectedExtension = selectedFilter.section(".", -1).section(")",0);
00224 if(!filename.section(".", -1).contains(selectedExtension))
00225 filename += "." + selectedExtension;
00226
00227
00228 if(braboExtension(filename))
00229 {
00230 extendedFormat = false;
00231
00232
00233 if(atoms->needsExtendedFormat())
00234 extendedFormat = true;
00235 else if(QMessageBox::information(0, Version::appName,
00236 QMessageBox::tr("Do you want to save the coordinates in extended or normal format?"),
00237 QMessageBox::tr("Extended format"), QMessageBox::tr("Normal format")) == 0)
00238 extendedFormat = true;
00239 }
00240 }
00241 else
00242 {
00244
00245 if(!validOutputFormat(filename))
00246 return UnknownExtension;
00247 }
00248
00249
00250 if(braboExtension(filename))
00251 {
00253 return writeBraboFile(atoms, filename, extendedFormat);
00254 }
00255 #ifdef USE_OPENBABEL1
00256 else
00257 {
00259
00260 char* fn = qstrdup(filename.latin1());
00261 io_type fileType = extab.FilenameToType(fn);
00262 delete fn;
00263
00264 OBMol* mol = new OBMol(fileType, fileType);
00265 OBAtom* atom;
00266 for(unsigned int i = 0; i < atoms->count(); i++)
00267 {
00268 atom = mol->NewAtom();
00269 atom->SetVector(atoms->x(i), atoms->y(i), atoms->z(i));
00270 atom->SetAtomicNum(atoms->atomicNumber(i));
00271 }
00272
00273 std::ofstream outFileStream;
00274 outFileStream.open(filename.latin1());
00275 if(!outFileStream)
00276 return ErrorOpen;
00277 if(!OBFileFormat::WriteMolecule(outFileStream, *mol))
00278 {
00279 delete mol;
00280 return ErrorWrite;
00281 }
00282 delete mol;
00283 }
00284 #endif
00285 #ifdef USE_OPENBABEL2
00286 else
00287 {
00289
00290 OBConversion conv;
00291 OBFormat* fileFormat = conv.FormatFromExt(filename.latin1());
00292 if(!fileFormat || !conv.SetOutFormat(fileFormat))
00293 return UnknownExtension;
00294
00295 std::ofstream outFileStream;
00296 outFileStream.open(filename.latin1());
00297 if(!outFileStream)
00298 return ErrorOpen;
00299 OBMol mol;
00300 OBAtom* atom;
00301 for(unsigned int i = 0; i < atoms->count(); i++)
00302 {
00303 atom = mol.NewAtom();
00304 atom->SetVector(atoms->x(i), atoms->y(i), atoms->z(i));
00305 atom->SetAtomicNum(atoms->atomicNumber(i));
00306 }
00307 if(!conv.Write(&mol, &outFileStream))
00308 return ErrorWrite;
00309 }
00310 #endif
00311 return OK;
00312 }
00313
00315 unsigned int CrdFactory::convert(const QString inputFileName, const QString outputFileName, const bool extendedFormat)
00317 {
00319 if(!validInputFormat(inputFileName))
00320 return UnknownExtension;
00321 if(!validOutputFormat(outputFileName))
00322 return UnknownExtension;
00323
00325 if(braboExtension(inputFileName) || braboExtension(outputFileName) || xmolExtension(inputFileName))
00326 {
00328
00329
00330 AtomSet* atoms = new AtomSet();
00331 QString tempInput = inputFileName;
00332 unsigned int result = readFromFile(atoms, tempInput);
00333 if(result != OK)
00334 return result;
00335
00336
00337 return writeToFile(atoms, outputFileName, extendedFormat);
00338
00339 }
00340 #ifdef USE_OPENBABEL1
00341 else
00342 {
00344
00345
00346 char* inFile = qstrdup(inputFileName.latin1());
00347 io_type inFileType = extab.FilenameToType(inFile);
00348 delete inFile;
00349 char* outFile = qstrdup(outputFileName.latin1());
00350 io_type outFileType = extab.FilenameToType(outFile);
00351 delete outFile;
00352
00353
00354 std::ifstream inFileStream;
00355 inFileStream.open(inputFileName.latin1());
00356 if(!inFileStream)
00357 return ErrorOpen;
00358 std::ofstream outFileStream;
00359 outFileStream.open(outputFileName.latin1());
00360 if(!outFileStream)
00361 return ErrorOpen;
00362
00363
00364 OBMol* mol = new OBMol(inFileType, outFileType);
00365
00366
00367 if(!OBFileFormat::ReadMolecule(inFileStream, *mol))
00368 {
00369 delete mol;
00370 return ErrorRead;
00371 }
00372
00373
00374 if(!OBFileFormat::WriteMolecule(outFileStream, *mol))
00375 {
00376 delete mol;
00377 return ErrorWrite;
00378 }
00379
00380
00381 delete mol;
00382 }
00383 #endif
00384 #ifdef USE_OPENBABEL2
00385 else
00386 {
00388
00389 std::ifstream inFileStream;
00390 inFileStream.open(inputFileName.latin1());
00391 if(!inFileStream)
00392 return ErrorOpen;
00393 std::ofstream outFileStream;
00394 outFileStream.open(outputFileName.latin1());
00395 if(!outFileStream)
00396 return ErrorOpen;
00397
00398 OBConversion conv(&inFileStream, &outFileStream);
00399
00400 OBFormat* inFormat = conv.FormatFromExt(inputFileName.latin1());
00401 OBFormat* outFormat = conv.FormatFromExt(outputFileName.latin1());
00402 if(!inFormat || !outFormat || !conv.SetInAndOutFormats(inFormat, outFormat))
00403 return UnknownExtension;
00404 conv.Convert();
00405 }
00406 #endif
00407 return OK;
00408 }
00409
00411 unsigned int CrdFactory::readForces(AtomSet* atoms, QString filename)
00414 {
00415
00416 if(!validForceInputFormat(filename))
00417 return UnknownExtension;
00418
00419
00420 if(braboExtension(filename))
00421 {
00423 return readBraboForces(atoms, filename);
00424 }
00425
00426 return OK;
00427 }
00428
00432
00434 CrdFactory::CrdFactory()
00437 {
00438
00439 }
00440
00442 QStringList CrdFactory::supportedInputFormats()
00445 {
00446 QStringList result = "Brabo (*.crd *.c00)";
00447 result += "Gaussian Checkpoint (*.fchk)";
00448 #ifdef USE_OPENBABEL1
00449 for(unsigned int i = 0; i < extab.Count(); i++)
00450 {
00451 if(extab.IsReadable(i))
00452 {
00453 QString inputFormat = ";;";
00454 inputFormat += extab.GetDescription(i);
00455 inputFormat += " (*.";
00456 inputFormat += extab.GetExtension(i);
00457 inputFormat += ")";
00458 result += inputFormat;
00459 }
00460 }
00461 #endif
00462 #ifdef USE_OPENBABEL2
00463 OBConversion conv;
00464
00465
00466 const char* str = NULL;
00467 Formatpos pos;
00468 OBFormat* format;
00469 while(OBConversion::GetNextFormat(pos, str, format))
00470 {
00471 if(!(format->Flags() & NOTREADABLE))
00472 {
00473
00474 QString desc = QString(format->Description());
00475 desc.truncate(desc.find("\n"));
00476 desc = desc.remove("format", false).stripWhiteSpace();
00477
00478 QString ext = QString(str);
00479 ext.truncate(ext.find(" "));
00480
00481 result += QString(";;" + desc + " (*." + ext + ")");
00482 }
00483 }
00484 #endif
00485 return result;
00486 }
00487
00489 QStringList CrdFactory::supportedOutputFormats()
00492 {
00493 QStringList result = "Brabo (*.crd)";
00494 #ifdef USE_OPENBABEL1
00495 for(unsigned int i = 0; i < extab.Count(); i++)
00496 {
00497 if(extab.IsWritable(i))
00498 {
00499 QString outputFormat = ";;";
00500 outputFormat += extab.GetDescription(i);
00501 outputFormat += " (*.";
00502 outputFormat += extab.GetExtension(i);
00503 outputFormat += ")";
00504 result += outputFormat;
00505 }
00506 }
00507 #endif
00508 #ifdef USE_OPENBABEL2
00509 const char* str = NULL;
00510 Formatpos pos;
00511 OBFormat* format;
00512 OBConversion conv;
00513 while(OBConversion::GetNextFormat(pos, str, format))
00514 {
00515 if(!(format->Flags() & NOTWRITABLE))
00516 {
00517
00518 QString desc = QString(format->Description());
00519 desc.truncate(desc.find("\n"));
00520 desc = desc.remove("format", false).stripWhiteSpace();
00521
00522 QString ext = QString(str);
00523 ext.truncate(ext.find(" "));
00524
00525 result += QString(";;" + desc + " (*." + ext + ")");
00526 }
00527 }
00528 #endif
00529 return result;
00530 }
00531
00533 bool CrdFactory::validInputFormat(const QString filename)
00535 {
00536
00537 if(braboExtension(filename) || xmolExtension(filename) || gaussianExtension(filename))
00538 return true;
00539
00540 #ifdef USE_OPENBABEL1
00541
00542 char* fn = qstrdup(filename.latin1());
00543 if(extab.CanReadExtension(fn))
00544 {
00545 delete fn;
00546 return true;
00547 }
00548 delete fn;
00549 #endif
00550 #ifdef USE_OPENBABEL2
00551
00552 OBConversion conv;
00553 OBFormat* format = OBConversion::FormatFromExt(filename.latin1());
00554 if(format || !(format->Flags() | NOTREADABLE))
00555 return true;
00556 #endif
00557 return false;
00558 }
00559
00561 bool CrdFactory::validForceInputFormat(const QString filename)
00563 {
00564
00565 if(braboExtension(filename))
00566 return true;
00567
00568 return false;
00569 }
00570
00572 bool CrdFactory::validOutputFormat(const QString filename)
00574 {
00575
00576 if(braboExtension(filename))
00577 return true;
00578
00579 #ifdef USE_OPENBABEL1
00580
00581 char* fn = qstrdup(filename.latin1());
00582 if(extab.CanWriteExtension(fn))
00583 {
00584 delete fn;
00585 return true;
00586 }
00587 delete fn;
00588 #endif
00589 #ifdef USE_OPENBABEL2
00590
00591 OBConversion conv;
00592 OBFormat* format = OBConversion::FormatFromExt(filename.latin1());
00593 if(format || !(format->Flags() | NOTWRITABLE))
00594 return true;
00595 #endif
00596 return false;
00597 }
00598
00600 bool CrdFactory::braboExtension(const QString filename)
00603 {
00604 QString extension = filename.section(".", -1).lower();
00605 if(extension == "crd" || extension == "c00" || extension == "ncr" || extension == "crdcrd" ||
00606 extension == "pun" || extension == "f00")
00607 return true;
00608
00609 return false;
00610 }
00611
00613 bool CrdFactory::xmolExtension(const QString filename)
00616 {
00617 QString extension = filename.section(".", -1).lower();
00618 if(extension == "xyz")
00619 return true;
00620
00621 return false;
00622 }
00623
00625 bool CrdFactory::gaussianExtension(const QString filename)
00628 {
00629 QString extension = filename.section(".", -1).lower();
00630 if(extension == "fchk")
00631 return true;
00632
00633 return false;
00634 }
00635
00637 unsigned int CrdFactory::readBraboFile(AtomSet* atoms, const QString filename)
00640 {
00641 QTime timer;
00642 timer.start();
00643 QFile file(filename);
00644 if(!file.open(IO_ReadOnly))
00645 return ErrorOpen;
00646
00648 QTextStream stream(&file);
00649 QStringList allLines;
00650 QString line;
00651 while(!stream.eof() && allLines.size() < 101)
00652 {
00653 line = stream.readLine();
00654 if(line.left(4).lower() == "stop")
00655 break;
00656 else if(line.left(1).lower() == "n" && line.mid(1,1) == "=")
00657 allLines += line;
00658 }
00659
00661 unsigned int format = determineCrdFormat(allLines);
00662 if(format == UnknownFormat)
00663 return UnknownFormat;
00664
00666 if(format == NormalFormat)
00667 readCrdAtoms(atoms, allLines, false);
00668 else if(format == ExtendedFormat)
00669 readCrdAtoms(atoms, allLines, true);
00670
00672 vector<unsigned int>* bonds1;
00673 vector<unsigned int>* bonds2;
00674 atoms->bonds(bonds1, bonds2);
00675 double toAngstrom = 1.0;
00676 if(bonds1->empty() && atoms->count() > 1)
00677 {
00678
00679 toAngstrom = 0.529177249;
00680 for(unsigned int i = 0; i < atoms->count(); i++)
00681 {
00682 atoms->setX(i,atoms->x(i) * toAngstrom);
00683 atoms->setY(i,atoms->y(i) * toAngstrom);
00684 atoms->setZ(i,atoms->z(i) * toAngstrom);
00685 }
00686 }
00687
00689 if(line.left(4).lower() != "stop" && !stream.eof())
00690 {
00691 double x, y, z, atomNum;
00692 unsigned int atomicNumber;
00693
00694 while(!stream.eof())
00695 {
00696 line = stream.readLine();
00697 if(line.left(4).lower() == "stop")
00698 break;
00699 else if(line.left(1).lower() == "n" && line.mid(1,1) == "=")
00700 {
00701 atomNum = line.mid(10,10).toDouble();
00702 if(atomNum < 1.0)
00703 atomicNumber = 0;
00704 else
00705 {
00707 if(atomNum - floor(atomNum) > 0.00001)
00708 atomicNumber = 0;
00709 else
00710 atomicNumber = static_cast<unsigned int>(atomNum);
00711 }
00712 if(format == NormalFormat)
00713 {
00714 x = line.mid(20,10).toDouble() * toAngstrom;
00715 y = line.mid(30,10).toDouble() * toAngstrom;
00716 z = line.mid(40,10).toDouble() * toAngstrom;
00717 }
00718 else
00719 {
00720 x = line.mid(20,20).toDouble() * toAngstrom;
00721 y = line.mid(40,20).toDouble() * toAngstrom;
00722 z = line.mid(60,20).toDouble() * toAngstrom;
00723 }
00724 atoms->addAtom(x, y, z, atomicNumber);
00725 }
00726 }
00727 }
00728
00729 qDebug("time to read the BRABO file: %f seconds", timer.restart()/1000.f);
00730 return OK;
00731 }
00732
00734 unsigned int CrdFactory::writeBraboFile(AtomSet* atoms, const QString filename, const bool extendedFormat)
00737 {
00738 QFile file(filename);
00739 if(!file.open(IO_WriteOnly))
00740 return ErrorOpen;
00741
00742 QTextStream stream(&file);
00743 QString line;
00744
00745 for(unsigned int i = 0; i < atoms->count(); i++)
00746 {
00747 if(extendedFormat)
00748 line = QString("N=%1 %2%3%4%5").arg(AtomSet::numToAtom(atoms->atomicNumber(i)), 2)
00749 .arg(static_cast<double>(atoms->atomicNumber(i)), -10, 'f', 1)
00750 .arg(atoms->x(i), 20, 'f', 12)
00751 .arg(atoms->y(i), 20, 'f', 12)
00752 .arg(atoms->z(i), 20, 'f', 12);
00753 else
00754 line = QString("N=%1 %2%3%4%5").arg(AtomSet::numToAtom(atoms->atomicNumber(i)), 2)
00755 .arg(static_cast<double>(atoms->atomicNumber(i)), -10, 'f', 1)
00756 .arg(atoms->x(i), 10, 'f', 7)
00757 .arg(atoms->y(i), 10, 'f', 7)
00758 .arg(atoms->z(i), 10, 'f', 7);
00759 stream << line << "\n";
00760 }
00761 stream << "STOP\n";
00762 file.close();
00763 return OK;
00764 }
00765
00767 unsigned int CrdFactory::readBraboForces(AtomSet* atoms, const QString filename)
00770 {
00771
00772 QFile file(filename);
00773 if(!file.open(IO_ReadOnly))
00774 return ErrorOpen;
00775
00777 QTextStream stream(&file);
00778 QStringList allLines;
00779 QString line;
00781 while(!stream.eof())
00782 {
00783 line = stream.readLine();
00784 if(line.left(8).lower() == "****forc")
00785 break;
00786 }
00787 while(!stream.eof())
00788 {
00789 line = stream.readLine();
00790 if(line.left(4) == "****")
00791 break;
00792 allLines += line;
00793 }
00794 file.close();
00795
00797 unsigned int format = determinePunchFormat(allLines);
00798 if(format == UnknownFormat)
00799 return UnknownFormat;
00800
00802 if(format == NormalFormat)
00803 readPunchForces(atoms, allLines, false);
00804 else if(format == ExtendedFormat)
00805 readPunchForces(atoms, allLines, true);
00806
00807 return OK;
00808 }
00809
00811 void CrdFactory::readCrdAtoms(AtomSet* atoms, QStringList &lines, const bool extendedFormat)
00814 {
00815 double x, y, z, atomNum;
00816 unsigned int atomicNumber;
00817 QString line;
00818
00819 atoms->clear();
00820 atoms->reserve(lines.size());
00821 for(QStringList::iterator it = lines.begin(); it != lines.end(); it++)
00822 {
00823 line = *it;
00825 atomNum = line.mid(10,10).toDouble();
00826 if(atomNum < 1.0)
00827 atomicNumber = 0;
00828 else
00829 {
00831 if(atomNum - floor(atomNum) > 0.00001)
00832 atomicNumber = 0;
00833 else
00834 atomicNumber = static_cast<unsigned int>(atomNum);
00835 }
00836
00837 if(!extendedFormat)
00838 {
00839 x = line.mid(20,10).toDouble();
00840 y = line.mid(30,10).toDouble();
00841 z = line.mid(40,10).toDouble();
00842 }
00843 else
00844 {
00845 x = line.mid(20,20).toDouble();
00846 y = line.mid(40,20).toDouble();
00847 z = line.mid(60,20).toDouble();
00848 }
00849 atoms->addAtom(x, y, z, atomicNumber);
00850 }
00851 }
00852
00854 void CrdFactory::readPunchForces(AtomSet* atoms, QStringList &lines, const bool extendedFormat)
00857 {
00858 double dx, dy, dz;
00859 QString line;
00860 unsigned int index = 0;
00861
00862 for(QStringList::iterator it = lines.begin(); it != lines.end(); it++)
00863 {
00864 line = *it;
00865 if(!extendedFormat)
00866 {
00867 dx = line.mid(0,10).toDouble();
00868 dy = line.mid(10,10).toDouble();
00869 dz = line.mid(20,10).toDouble();
00870 }
00871 else
00872 {
00873 dx = line.mid(0,20).toDouble();
00874 dy = line.mid(20,20).toDouble();
00875 dz = line.mid(40,20).toDouble();
00876 }
00877 atoms->setForces(index++, dx, dy, dz);
00878 }
00879 }
00880
00882 unsigned int CrdFactory::determineCrdFormat(QStringList& lines)
00885 {
00886 QString line;
00887 unsigned int returnVal = UnknownFormat;
00888 unsigned int linesChecked = 0;
00889
00890 for(QStringList::iterator it = lines.begin(); it != lines.end(); it++)
00891 {
00892 line = *it;
00893 if(possiblyNormalCrd(line.mid(20,30)))
00894 {
00895 if(!possiblyExtendedCrd(line.mid(20,60)))
00896 {
00897 if(returnVal != 1)
00898 returnVal = NormalFormat;
00899 else
00900 return UnknownFormat;
00901 }
00902 }
00903 else
00904 {
00905 if(possiblyExtendedCrd(line.mid(20,60)))
00906 {
00907 if(returnVal != 0)
00908 returnVal = ExtendedFormat;
00909 else
00910 return UnknownFormat;
00911 }
00912 else
00913 return UnknownFormat;
00914 }
00915 if(++linesChecked == 100)
00916 return returnVal;
00917 }
00918
00919 return returnVal;
00920 }
00921
00923 unsigned int CrdFactory::determinePunchFormat(QStringList& lines)
00926 {
00927 QString line;
00928 unsigned int returnVal = UnknownFormat;
00929 unsigned int linesChecked = 0;
00930
00931 for(QStringList::iterator it = lines.begin(); it != lines.end(); it++)
00932 {
00933 line = *it;
00934 if(possiblyNormalCrd(line.mid(0,30)))
00935 {
00936 if(!possiblyExtendedCrd(line.mid(0,60)))
00937 {
00938 if(returnVal != 1)
00939 returnVal = NormalFormat;
00940 else
00941 return UnknownFormat;
00942 }
00943 }
00944 else
00945 {
00946 if(possiblyExtendedCrd(line.mid(0,60)))
00947 {
00948 if(returnVal != 0)
00949 returnVal = ExtendedFormat;
00950 else
00951 return UnknownFormat;
00952 }
00953 else
00954 return UnknownFormat;
00955 }
00956 if(++linesChecked == 100)
00957 return returnVal;
00958 }
00959
00960 return returnVal;
00961 }
00962
00964 bool CrdFactory::possiblyNormalCrd(const QString line)
00966 {
00967 QString field1 = line.mid(0,10).stripWhiteSpace();
00968 QString field2 = line.mid(10,10).stripWhiteSpace();
00969 QString field3 = line.mid(20,10).stripWhiteSpace();
00970
00971 if(field1.contains(".", false) != 1 && !field1.isEmpty())
00972 return false;
00973 if(field2.contains(".", false) != 1 && !field2.isEmpty())
00974 return false;
00975 if(field3.contains(".", false) != 1 && !field3.isEmpty())
00976 return false;
00977
00978 return true;
00979 }
00980
00982 bool CrdFactory::possiblyExtendedCrd(const QString line)
00984 {
00985 QString field1 = line.mid(0,20).stripWhiteSpace();
00986 QString field2 = line.mid(20,20).stripWhiteSpace();
00987 QString field3 = line.mid(40,20).stripWhiteSpace();
00988
00989 if(field1.contains(".", false) != 1 && !field1.isEmpty())
00990 return false;
00991 if(field2.contains(".", false) != 1 && !field2.isEmpty())
00992 return false;
00993 if(field3.contains(".", false) != 1 && !field3.isEmpty())
00994 return false;
00995
00996 return true;
00997 }
00998
01000 unsigned int CrdFactory::readXmolFile(AtomSet* atoms, const QString filename)
01003 {
01005 QFile file(filename);
01006 if(!file.open(IO_ReadOnly))
01007 return ErrorOpen;
01008
01010 QTextStream stream(&file);
01011 bool convOK;
01012 unsigned int natoms = stream.readLine().toUInt(&convOK);
01013 if(!convOK || natoms == 0)
01014 return ErrorRead;
01015
01017 stream.readLine();
01018
01020 QStringList allLines;
01021 for(unsigned int i = 0; i < natoms; i++)
01022 {
01023
01024 QString line = stream.readLine().simplifyWhiteSpace();
01025 if(line.isEmpty())
01026 return ErrorRead;
01027
01028 allLines += line;
01029 }
01030 file.close();
01031
01033 for(QStringList::iterator it = allLines.begin(); it != allLines.end(); it++)
01034 {
01035
01036 QStringList sections = QStringList::split(" ", *it);
01037 if(sections.count() != 4 && sections.count() != 7)
01038 return ErrorRead;
01039 }
01040
01042 atoms->clear();
01043 atoms->reserve(allLines.size());
01044 for(QStringList::iterator it = allLines.begin(); it != allLines.end(); it++)
01045 {
01046
01047 QStringList sections = QStringList::split(" ", *it);
01048
01049 QStringList::iterator it2 = sections.begin();
01050 unsigned int atomnum = AtomSet::atomToNum(*it2);
01051 double x = (*(++it2)).toDouble();
01052 double y = (*(++it2)).toDouble();
01053 double z = (*(++it2)).toDouble();
01054 atoms->addAtom(x, y, z, atomnum);
01055 }
01056 return OK;
01057 }
01058
01060 unsigned int CrdFactory::readGaussianFile(AtomSet* atoms, const QString filename)
01063 {
01065 QFile file(filename);
01066 if(!file.open(IO_ReadOnly))
01067 return ErrorOpen;
01068
01070 QTextStream stream(&file);
01071 QString line;
01072 while(line.left(15) != "Number of atoms")
01073 line = stream.readLine();
01074 bool convOK;
01075 unsigned int natoms = line.mid(49,12).toUInt(&convOK);
01076 if(!convOK || natoms == 0)
01077 return ErrorRead;
01078
01080 while(line.left(14) != "Atomic numbers")
01081 line = stream.readLine();
01082 unsigned int natoms2 = line.mid(49,12).toUInt(&convOK);
01083 if(!convOK || natoms2 != natoms)
01084 return ErrorRead;
01085
01087 vector<unsigned int> atomnums;
01088 unsigned int atomnum;
01089 for(unsigned int i = 0; i < natoms; i++)
01090 {
01091 stream >> atomnum;
01092 atomnums.push_back(atomnum);
01093 }
01094
01096 while(line.left(29) != "Current cartesian coordinates")
01097 line = stream.readLine();
01098 unsigned int natoms3 = line.mid(49,12).toUInt(&convOK);
01099 if(!convOK || natoms3 != 3*natoms)
01100 return ErrorRead;
01101
01103 atoms->clear();
01104 atoms->reserve(natoms);
01105 double x, y, z;
01106 for(unsigned int i = 0; i < natoms; i++)
01107 {
01108 stream >> x >> y >> z;
01109 x *= AUTOANG;
01110 y *= AUTOANG;
01111 z *= AUTOANG;
01112 atoms->addAtom(x, y, z, atomnums[i]);
01113 }
01114
01115 return OK;
01116 }
01117
01121 const double CrdFactory::AUTOANG = 1.0/1.889726342;
01122