crdfactory.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                         crdfactory.cpp  -  description
00003                              -------------------
00004     begin                : Sat Jan 17 2004
00005     copyright            : (C) 2004-2006 by Ben Swerts
00006     email                : bswerts@users.sourceforge.net
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00019 
00034 
00035 
00036 
00038 
00039 // C++ header files
00040 #include <cmath>
00041 #include <iostream>
00042 
00043 // Qt header files
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  // Open Babel 1.100.2 header files
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; // to be changed to a number of 'using <class>' lines
00069 #endif
00070 #ifdef USE_OPENBABEL2
00071   // Open Babel 2.x header files
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 // CrdView header files
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   // choose a filename if none was specified
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   // validate the filename
00117   if(!validInputFormat(filename))    
00118     return UnknownExtension; 
00119   
00120   // check whether the Xbrabo or Open Babel reading routines should be used
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     // read the file
00141     char* fn = qstrdup(filename.latin1()); // put the filename QString into a non-const char*
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)) // only read the first molecule
00150     {
00151       delete mol;
00152       return ErrorRead;
00153     }
00154     // fill the AtomSet
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     // read the file
00170     OBConversion conv;
00171     OBFormat* fileFormat = conv.FormatFromExt(filename.latin1());
00172     if(!fileFormat || !conv.SetInFormat(fileFormat))
00173       return UnknownExtension;
00174     // delete fileFormat; ???
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     // fill the AtomSet
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     // fix the extension
00223     QString selectedExtension = selectedFilter.section(".", -1).section(")",0);
00224     if(!filename.section(".", -1).contains(selectedExtension))
00225       filename += "." + selectedExtension;
00226 
00227     // ask the format if it's a Brabo extension
00228     if(braboExtension(filename))
00229     {
00230       extendedFormat = false;
00231       // check whether the coordinates fit in normal format
00232       // if not force extended format
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     // validate the filename
00245     if(!validOutputFormat(filename))
00246       return UnknownExtension; 
00247   }   
00248 
00249   // check whether the Xbrabo or Open Babel writing routines should be used
00250   if(braboExtension(filename))
00251   {
00253     return writeBraboFile(atoms, filename, extendedFormat);
00254   }
00255 #ifdef USE_OPENBABEL1  
00256   else
00257   {
00259     // determine the Open Babel file type
00260     char* fn = qstrdup(filename.latin1()); // put the filename QString into a non-const char*
00261     io_type fileType = extab.FilenameToType(fn);
00262     delete fn;   
00263     // construct an Open Babel molecule and fill it with the contents of the AtomSet
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     // write the file
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     // determine the Open Babel file type
00290     OBConversion conv;
00291     OBFormat* fileFormat = conv.FormatFromExt(filename.latin1());
00292     if(!fileFormat || !conv.SetOutFormat(fileFormat))
00293       return UnknownExtension;
00294     // delete fileFormat; ???
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     // read the input file into the AtomSet
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     // save the AtomSet to the output file
00337     return writeToFile(atoms, outputFileName, extendedFormat);
00338        
00339   }
00340 #ifdef USE_OPENBABEL1  
00341   else
00342   {
00344     
00345     // determine the file types of the in- & output files
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     // open both files
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     // construct an OBMol object
00364     OBMol* mol = new OBMol(inFileType, outFileType);
00365 
00366     // read the coordinates   
00367     if(!OBFileFormat::ReadMolecule(inFileStream, *mol)) // only read the first molecule
00368     {
00369       delete mol;
00370       return ErrorRead;
00371     }
00372 
00373     // write the coordinates
00374     if(!OBFileFormat::WriteMolecule(outFileStream, *mol))
00375     {
00376       delete mol;
00377       return ErrorWrite;
00378     }
00379 
00380     // delete the OBMol object again
00381     delete mol;        
00382   }
00383 #endif  
00384 #ifdef USE_OPENBABEL2 
00385   else
00386   {
00388     // open both files
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     // create a conversion object
00398     OBConversion conv(&inFileStream, &outFileStream);
00399     // set the filetypes
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   // validate the filename
00416   if(!validForceInputFormat(filename))
00417     return UnknownExtension;
00418 
00419   // check whether the Xbrabo or Open Babel reading routines should be used
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; // here only because of initialisation bug in OBConversion::GetNextFormat (v2.0.0)
00464   //OBConversion::RegisterFormat("alc",this, "chemical/x-alchemy"); // test for initialisation of OBConversion
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       // description
00474       QString desc = QString(format->Description());
00475       desc.truncate(desc.find("\n")); // stop at the first newline
00476       desc = desc.remove("format", false).stripWhiteSpace(); // remove unnecessary stuff
00477       // extension
00478       QString ext = QString(str);
00479       ext.truncate(ext.find(" "));
00480       // combined
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; // here only because of initialisation bug in OBConversion::GetNextFormat (v2.0.0)
00513   while(OBConversion::GetNextFormat(pos, str, format))
00514   {
00515     if(!(format->Flags() & NOTWRITABLE))
00516     {
00517       // description
00518       QString desc = QString(format->Description());
00519       desc.truncate(desc.find("\n")); // stop at the first newline
00520       desc = desc.remove("format", false).stripWhiteSpace(); // remove unnecessary stuff
00521       // extension
00522       QString ext = QString(str);
00523       ext.truncate(ext.find(" "));
00524       // combined
00525       result += QString(";;" + desc + " (*." + ext + ")");
00526     }
00527   }
00528 #endif
00529   return result;
00530 }
00531 
00533 bool CrdFactory::validInputFormat(const QString filename)
00535 {
00536   // check for Brabo formats
00537   if(braboExtension(filename) || xmolExtension(filename) || gaussianExtension(filename))
00538     return true;
00539 
00540 #ifdef USE_OPENBABEL1    
00541   // check for Open Babel formats
00542   char* fn = qstrdup(filename.latin1()); // put the filename QString into a non-const char*
00543   if(extab.CanReadExtension(fn))
00544   {
00545     delete fn;
00546     return true;
00547   }  
00548   delete fn;
00549 #endif
00550 #ifdef USE_OPENBABEL2    
00551   // check for Open Babel formats
00552   OBConversion conv; // here only because of initialisation bug in OBConversion::FileFormat (called by FormatFromExt) (v2.0.0)
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   // check for Brabo formats
00565   if(braboExtension(filename))
00566     return true;
00567 
00568   return false;
00569 }
00570 
00572 bool CrdFactory::validOutputFormat(const QString filename)
00574 {  
00575   // check for Brabo formats
00576   if(braboExtension(filename))
00577     return true;
00578 
00579 #ifdef USE_OPENBABEL1
00580   // check for Open Babel formats
00581   char* fn = qstrdup(filename.latin1()); // put the filename QString into a non-const char*
00582   if(extab.CanWriteExtension(fn))
00583   {
00584     delete fn;
00585     return true;
00586   }
00587   delete fn;
00588 #endif
00589 #ifdef USE_OPENBABEL2    
00590   // check for Open Babel formats
00591   OBConversion conv; // here only because of initialisation bug in OBConversion::FileFormat (called by FormatFromExt) (v2.0.0)
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) // format not determinable => error out or ask format
00663     return UnknownFormat;
00664   
00666   if(format == NormalFormat)
00667     readCrdAtoms(atoms, allLines, false); // using normal format
00668   else if(format == ExtendedFormat)
00669     readCrdAtoms(atoms, allLines, true); // using extended format
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     // rescale all coordinates
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   //qDebug("CrdFactory:: readBraboForces - entering");
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) // format not determinable => error out or ask format
00799     return UnknownFormat;
00800 
00802   if(format == NormalFormat)
00803     readPunchForces(atoms, allLines, false); // using normal format
00804   else if(format == ExtendedFormat)
00805     readPunchForces(atoms, allLines, true); // using extended format
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     //atomicNumber = static_cast<unsigned int>(line.mid(10,10).toDouble());
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     // read the next line
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     // split it by whitespace
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     // split it again by whitespace
01047     QStringList sections = QStringList::split(" ", *it);
01048     // only read the coordinates ATM, ignoring the forces
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 

Generated on Fri May 19 14:31:54 2006 for Brabosphere by  doxygen 1.4.6-NO