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(); }
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); } }
int Cube::parseGridAxes(TextStream& textStream) { int nAtoms(0); bool ok, xOk, yOk, zOk; double x, y, z, dx, dy, dz; double thresh(1e-6); // origin line QStringList tokens(textStream.nextLineAsTokens()); if (tokens.size() != 4) return 0; nAtoms = tokens[0].toInt(&ok); x = tokens[1].toDouble(&xOk); y = tokens[2].toDouble(&yOk); z = tokens[3].toDouble(&zOk); if (!(ok && xOk && yOk && zOk)) return 0; m_origin.setValue(x, y, z); // x line tokens = textStream.nextLineAsTokens(); if (tokens.size() != 4) return 0; m_nx = tokens[0].toInt(&ok); dx = tokens[1].toDouble(&xOk); y = tokens[2].toDouble(&yOk); z = tokens[3].toDouble(&zOk); if (!(ok && xOk && yOk && zOk)) return 0; if (std::abs(y) > thresh || std::abs(z) > thresh) goto axial_error; // y line tokens = textStream.nextLineAsTokens(); if (tokens.size() != 4) return 0; m_ny = tokens[0].toInt(&ok); x = tokens[1].toDouble(&xOk); dy = tokens[2].toDouble(&yOk); z = tokens[3].toDouble(&zOk); if (!(ok && xOk && yOk && zOk)) return 0; if (std::abs(x) > thresh || std::abs(z) > thresh) goto axial_error; // z line tokens = textStream.nextLineAsTokens(); if (tokens.size() != 4) return 0; m_nz = tokens[0].toInt(&ok); x = tokens[1].toDouble(&xOk); y = tokens[2].toDouble(&yOk); dz = tokens[3].toDouble(&zOk); if (!(ok && xOk && yOk && zOk)) return 0; if (std::abs(x) > thresh || std::abs(y) > thresh) goto axial_error; m_delta.setValue(dx, dy, dz); // Check what units we are using. if (m_nx < 0) { m_scale = 1.0; QLOG_TRACE() << "Leaving grid data units unscaled"; }else { m_scale = Constants::BohrToAngstrom; QLOG_TRACE() << "Scaling grid data units: Bohr -> Angstrom"; } m_nx = std::abs(m_nx); m_ny = std::abs(m_ny); m_nz = std::abs(m_nz); m_origin *= m_scale; m_delta *= m_scale; return nAtoms; axial_error: m_errors.append("Non-axial grid data not supported"); return 0; }