void Cube::parseGridData(TextStream& textStream) { QList<double> data; while (!textStream.atEnd()) { data += textStream.nextLineAsDoubles(); } QList<Data::Geometry*> geometryList(m_dataBank.findData<Data::Geometry>()); if (geometryList.isEmpty()) { m_errors.append("Geometry data not found in cube file"); return; } try { Data::SurfaceType type(Data::SurfaceType::CubeData); Data::GridSize size(m_origin, m_delta, m_nx, m_ny, m_nz); Data::CubeData* cube(new Data::CubeData(*(geometryList.last()),size, type, data)); m_dataBank.append(cube); QFileInfo info(m_filePath); cube->setLabel(info.completeBaseName()); } catch (std::out_of_range const& err) { m_errors.append("Invalid grid data in cube file"); } }
void QChemInput::readEfpParamsSection(TextStream& textStream) { EfpFragment parser; while (!textStream.atEnd()) { parser.loadNextFragment(textStream); if (textStream.previousLine().contains("$end", Qt::CaseInsensitive)) break; } }
bool PovRay::parse(TextStream& textStream) { Data::PovRay* povray(new Data::PovRay); while (!textStream.atEnd()) { readNextDeclaration(textStream, povray); } m_dataBank.append(povray); return m_errors.isEmpty(); }
void QChemInput::readEfpFragmentSection(TextStream& textStream) { // Check for an existing list from the $molecule section Data::EfpFragmentList* efps(0); QList<Data::EfpFragmentList*> lists = m_dataBank.findData<Data::EfpFragmentList>(); if (lists.isEmpty()) { efps = new Data::EfpFragmentList; m_dataBank.append(efps); }else { efps = lists.last(); } QString msg("Invalid $efp_fragments format on line "); QStringList tokens; bool ok, allOk; int count(1); while (!textStream.atEnd()) { tokens = textStream.nextLineAsTokens(); if (tokens.size() == 1 && tokens[0].contains("$end", Qt::CaseInsensitive)) { break; }else if (tokens.size() < 7) { Data::EfpFragment* efp(0); if (count <= efps->size()) { efp = efps->at(count-1); }else { efp = new Data::EfpFragment; efps->append(efp); } efp->setName(tokens[0]); }else { allOk = true; QString name(tokens[0]); double x, y, z, a, b, c; if (allOk) x = tokens[1].toDouble(&ok); allOk = allOk && ok; if (allOk) y = tokens[2].toDouble(&ok); allOk = allOk && ok; if (allOk) z = tokens[3].toDouble(&ok); allOk = allOk && ok; if (allOk) a = tokens[4].toDouble(&ok); allOk = allOk && ok; if (allOk) b = tokens[5].toDouble(&ok); allOk = allOk && ok; if (allOk) c = tokens[6].toDouble(&ok); allOk = allOk && ok; if (allOk) { efps->append(new Data::EfpFragment(name, qglviewer::Vec(x,y,z), a, b, c)); }else { m_errors.append(msg += QString::number(textStream.lineNumber())); } } ++count; } }
bool ExternalCharges::parse(TextStream& textStream) { int max(INT_MAX); bool allOk(true), isDouble; bool maxSet(false), invalidFormat(false); double x, y, z, q; QStringList tokens; Data::PointChargeList* charges(new Data::PointChargeList); while (!textStream.atEnd() && charges->size() < max) { tokens = textStream.nextLineAsTokens(); if (tokens.size() >= 4) { x = tokens[0].toDouble(&isDouble); allOk = allOk && isDouble; y = tokens[1].toDouble(&isDouble); allOk = allOk && isDouble; z = tokens[2].toDouble(&isDouble); allOk = allOk && isDouble; q = tokens[3].toDouble(&isDouble); allOk = allOk && isDouble; if (allOk) { charges->append(new Data::PointCharge(q, qglviewer::Vec(x,y,z))); }else { invalidFormat = true; break; } }else if (tokens.size() >= 1) { if (tokens.first().contains("$end", Qt::CaseInsensitive) || maxSet) { break; }else { max = tokens[0].toInt(&maxSet); } } } if (maxSet && charges->size() != max) { if (invalidFormat) { QString msg("Invalid format on line "); m_errors.append(msg += QString::number(textStream.lineNumber())); }else { m_errors.append("End of stream encountered"); } delete charges; }else if (charges->isEmpty()) { m_errors.append("No charges found"); delete charges; }else { m_dataBank.append(charges); } return m_errors.isEmpty(); }
void PovRay::readNextDeclaration(TextStream& textStream, Data::PovRay* povray) { // looks for '#declare TextureName = ' const QRegExp declare("^#declare\\s+(\\S+)\\s?="); QString line(textStream.nextLine()); if (!line.contains(declare)) line = textStream.seek(declare); if (!textStream.atEnd() && declare.indexIn(line) > -1) { QString name(declare.cap(1)); // remove the initial IQmol_Texture_ name.remove(0,14); name.replace("_", " "); line = textStream.nextBlock(); povray->addTexture(name,line); } }
QString EfpFragment::loadNextFragment(TextStream& textStream) { QString line(textStream.previousLine()); if (!line.contains("fragment", Qt::CaseInsensitive)) { line = textStream.seek("fragment", Qt::CaseInsensitive); } QStringList tokens(TextStream::tokenize(line)); QString name; if (tokens.size() >= 2 && tokens[0].toLower() == "fragment") { name = tokens[1]; }else { return QString(); } CartesianCoordinates parser; Data::Geometry* geom(parser.parse(textStream)); if ( !geom || !parser.error().isEmpty()) { m_errors.append("Invalid EFP file, no coordinates found"); delete geom; return QString(); } if (name.endsWith("_L", Qt::CaseInsensitive)) { Data::EfpFragmentLibrary::instance().add(name, geom); }else { // We assume the fragment is not in the library and so we need to collect // the additional guff so we can add it to the input file if required. QString line; QStringList guff; while ( !textStream.atEnd() && !line.contains("fragment", Qt::CaseInsensitive) && !line.contains("$end", Qt::CaseInsensitive) ) { guff << line; } Data::EfpFragmentLibrary::instance().add(name, geom, guff.join("\n")); } return name; }
bool QChemInput::parse(TextStream& textStream) { QString line; m_geometryList = new Data::GeometryList; while (!textStream.atEnd()) { line = textStream.nextLine(); if (line.contains("@@@", Qt::CaseInsensitive)) { // Any need to demarkate jobs? }else if (line.contains("$rem", Qt::CaseInsensitive)) { readRemSection(textStream); }else if (line.contains("$molecule", Qt::CaseInsensitive)) { readMoleculeSection(textStream); }else if (line.contains("$efp_params", Qt::CaseInsensitive)) { //readEfpParamsSection(textStream); }else if (line.contains("$efp_fragments", Qt::CaseInsensitive)) { readEfpFragmentSection(textStream); }else if (line.contains("$external_charges", Qt::CaseInsensitive)) { readExternalChargesSection(textStream); }else if (line.contains("------------------------")) { // Assume this is the end of the input echoed in an output file. break; } } if (m_geometryList->isEmpty()) { delete m_geometryList; }else { m_dataBank.append(m_geometryList); } return m_errors.isEmpty(); }
QList<Data::SurfaceType> QChemPlot::parseForProperties(TextStream& textStream) { QString firstLine; while (!textStream.atEnd() && !firstLine.contains("Grid point positions")) { firstLine = textStream.nextLine(); } bool esp(firstLine.contains("esp values")); bool rho(firstLine.contains("electronic density values")); textStream.skipLine(); QString secondLine(textStream.nextLine()); QList<Data::SurfaceType> surfaceTypes; unsigned count(1); while (!secondLine.isEmpty()) { QString field(secondLine.left(13)); secondLine.remove(0, 13); field = field.trimmed(); if (field == "X" || field == "Y" || field == "Z") { // ignore }else if(field.contains("ALPHA")) { surfaceTypes.append( Data::SurfaceType(Data::SurfaceType::AlphaOrbital, count++)); }else if(field.contains("BETA")) { surfaceTypes.append( Data::SurfaceType(Data::SurfaceType::BetaOrbital, count++)); }else if (esp) { surfaceTypes.append( Data::SurfaceType(Data::SurfaceType::ElectrostaticPotential, count++)); }else if (rho) { surfaceTypes.append( Data::SurfaceType(Data::SurfaceType::TotalDensity, count++)); } } return surfaceTypes; }
void QChemInput::readRemSection(TextStream& textStream) { QString line; QStringList tokens; bool finished(false); Data::RemSection* rem = new Data::RemSection; while (!textStream.atEnd() && !finished) { line = textStream.nextLine(); line = line.replace('=', ' '); tokens = TextStream::tokenize(line); switch (tokens.size()) { case 0: // Ignore empty lines break; case 1: if (tokens[0].contains("$end", Qt::CaseInsensitive)) { finished = true; }else if (tokens[0].contains("$rem", Qt::CaseInsensitive)) { // carry on }else { m_errors.append("Invalid $rem format, line " + QString::number(textStream.lineNumber())); delete rem; rem = 0; finished = true; } break; default: rem->insert(tokens[0].toLower(), tokens[1].toLower()); break; } } if (rem) m_dataBank.append(rem); }
void QChemInput::readMoleculeSection(TextStream& textStream) { QString msg("Invalid $molecule format on line "); int charge(0); unsigned multiplicity(1); bool ok; // First line can only contain the charge and multiplicity or 'read' QString line(textStream.nextLine()); line = line.replace(',', ' '); QStringList tokens(TextStream::tokenize(line)); switch (tokens.size()) { case 0: // Error m_errors.append(msg + QString::number(textStream.lineNumber())); return; break; case 1: // Could be reading in previous geometry if (tokens[0].contains("read", Qt::CaseInsensitive)) { if (m_geometryList->size() > 0) { // copy previous geometry Data::Geometry* geometry(new Data::Geometry(*(m_geometryList->last()))); m_geometryList->append(geometry); }else { // We assume we are reading an input section from // an output file, so there is no new geometry. } }else { m_errors.append(msg + QString::number(textStream.lineNumber())); } return; break; default: charge = tokens[0].toInt(&ok); if (ok) multiplicity = tokens[1].toUInt(&ok); if (!ok) { m_errors.append(msg + QString::number(textStream.lineNumber())); return; } break; } // Second line could be a 'read' token or the first atom line = textStream.nextLine(); // offset is passed to the CartesianCoordinates parser to give // an accurate line number if an error occurs. int offset(textStream.lineNumber()-1); if (line.isEmpty()) { m_errors.append(msg + QString::number(textStream.lineNumber())); return; } // Special case: read previous geometry if (line.contains("read", Qt::CaseInsensitive)) { if (m_geometryList->size() > 0) { // copy last geometry Data::Geometry* geometry(new Data::Geometry(*(m_geometryList->last()))); geometry->setChargeAndMultiplicity(charge, multiplicity); m_geometryList->append(geometry); }else { m_errors.append(msg + QString::number(textStream.lineNumber())); } return; } // Special case: EFP only fragments if (line.contains("--")) { // Check for an existing list which may have been created if the // $efp_fragments section was parsed before $molecule. Data::EfpFragmentList* efps(0); QList<Data::EfpFragmentList*> lists = m_dataBank.findData<Data::EfpFragmentList>(); if (lists.isEmpty()) { efps = new Data::EfpFragmentList; m_dataBank.append(efps); }else { efps = lists.last(); } int count(1); while (!textStream.atEnd()) { tokens = textStream.nextLineAsTokens(); if (tokens.size() == 1 && tokens[0].contains("$end", Qt::CaseInsensitive)) { break; }else if (tokens.size() == 6) { bool allOk(true); double x, y, z, a, b, c; if (allOk) x = tokens[0].toDouble(&ok); allOk = allOk && ok; if (allOk) y = tokens[1].toDouble(&ok); allOk = allOk && ok; if (allOk) z = tokens[2].toDouble(&ok); allOk = allOk && ok; if (allOk) a = tokens[3].toDouble(&ok); allOk = allOk && ok; if (allOk) b = tokens[4].toDouble(&ok); allOk = allOk && ok; if (allOk) c = tokens[5].toDouble(&ok); allOk = allOk && ok; if (allOk) { Data::EfpFragment* efp(0); if (count <= efps->size()) { efp = efps->at(count-1); }else { efp = new Data::EfpFragment; efps->append(efp); } efp->setPosition(Vec(x,y,z)); efp->setEulerAngles(a,b,c); } ++count; } } return; } tokens = TextStream::tokenize(line); bool zmat(tokens.size() == 1); QStringList lines; while (!textStream.atEnd() && !line.contains("$end", Qt::CaseInsensitive)) { // Account for the possibility of a FSM job, which has two geometries // separated by the **** token. if (line.contains("****")) { Data::Geometry* geom(parseGeometry(lines, offset, zmat)); if (geom) { geom->setChargeAndMultiplicity(charge, multiplicity); m_geometryList->append(geom); } offset = textStream.lineNumber(); lines.clear(); }else { lines.append(line); } line = textStream.nextLine(); } Data::Geometry* geom(parseGeometry(lines, offset, zmat)); if (geom) { geom->setChargeAndMultiplicity(charge, multiplicity); m_geometryList->append(geom); } }
// Note the grid data is read in as bohr, but converted to angstroms in the // Grid constructor bool QChemPlot::parse(TextStream& textStream) { QList<double> values; QList<Data::SurfaceType> surfaceTypes(parseForProperties(textStream)); unsigned nProperties(surfaceTypes.size()); if (nProperties < 1) goto error; values = textStream.nextLineAsDoubles(); if ((unsigned)values.size() != 3 + nProperties) goto error; {/**/ double xMin(values[0]); double yMin(values[1]); double zMin(values[2]); double xMax(xMin); double yMax(yMin); double zMax(zMin); typedef QList<double> List; List* data = new List[nProperties]; for (unsigned i = 0; i < nProperties; ++i) { data[i].append(values[i+3]); } unsigned nx(1), ny(1), nz(1); while (!textStream.atEnd()) { if ((unsigned)values.size() == 3 + nProperties) { if (values[0] > xMax) { xMax = values[0]; ++nx; } if (values[1] > yMax) { yMax = values[1]; ++ny; } if (values[2] > zMax) { zMax = values[2]; ++nz; } for (unsigned i = 0; i < nProperties; ++i) { data[i].append(values[i+3]); } } values = textStream.nextLineAsDoubles(); } qglviewer::Vec delta((xMax-xMin)/nx, (yMax-yMin)/ny, (zMax-zMin)/nz); qglviewer::Vec origin(xMin, yMin, zMin); Data::GridDataList* gridList(new Data::GridDataList); try { for (unsigned i = 0; i < nProperties; ++i) { Data::GridSize size(origin, delta, nx, ny, nz); gridList->append(new Data::GridData(size, surfaceTypes[i])); } m_dataBank.append(gridList); } catch (...) { m_errors.append("Problem creating QChem plot data"); delete gridList; } delete[] data; }/**/ return m_errors.isEmpty(); error: QString msg("Problem parsing QChem plot data, line "); m_errors.append(msg += QString::number(textStream.lineNumber())); return false; }