bool Cube::parseCoordinates(TextStream& textStream, unsigned nAtoms) { Data::Geometry* geometry(new Data::Geometry); bool ok; unsigned atomicNumber; qglviewer::Vec position; for (unsigned i = 0; i < nAtoms; ++i) { QStringList tokens(textStream.nextLineAsTokens()); if (tokens.size() != 5) return false; atomicNumber = tokens[0].toUInt(&ok); if (!ok) goto error; position.x = tokens[2].toDouble(&ok); if (!ok) goto error; position.y = tokens[3].toDouble(&ok); if (!ok) goto error; position.z = tokens[4].toDouble(&ok); if (!ok) goto error; geometry->append(atomicNumber, position); } geometry->scaleCoordinates(m_scale); geometry->computeGasteigerCharges(); m_dataBank.append(geometry); return true; error: QString msg("Incorrect format on line "); msg += QString::number(textStream.lineNumber()); delete geometry; return false; }
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(); }
bool Cube::parse(TextStream& textStream) { // Header information textStream.skipLine(2); int nAtoms(parseGridAxes(textStream)); if (nAtoms == 0) { QString msg("Incorrect format on line "); msg += QString::number(textStream.lineNumber()); msg += "\nExpected: <int> <double> <double> <double>"; m_errors.append(msg); return false; } if (!parseCoordinates(textStream, nAtoms)) return false; parseGridData(textStream); return m_errors.isEmpty(); }
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; }