diff --git a/corelib/src/libs/SireIO/gro87.cpp b/corelib/src/libs/SireIO/gro87.cpp index 7f1c84b88..adb44d753 100644 --- a/corelib/src/libs/SireIO/gro87.cpp +++ b/corelib/src/libs/SireIO/gro87.cpp @@ -693,54 +693,75 @@ Frame Gro87::getFrame(int i) const { i = SireID::Index(i).map(this->nFrames()); - return SireMol::Frame(); -} + QVector frame_coords; + if (not this->coords.isEmpty()) + { + frame_coords = this->coords[i]; + } -/** Return the Gro87 object that contains only the information for the ith - frame. This allows you to extract and create a system for the ith frame - from a trajectory */ -Gro87 Gro87::operator[](int i) const -{ - i = Index(i).map(this->nFrames()); + QVector frame_vels; - if (nFrames() == 1) - return *this; + if (not this->vels.isEmpty()) + { + const auto velocities = this->vels[i]; + const int nats = frame_vels.count(); - Gro87 ret(*this); + frame_vels = QVector(nats); - if (not coords.isEmpty()) - { - ret.coords = {coords[i]}; - } + auto velocities_data = frame_vels.data(); + const auto vels_data = velocities.constData(); - if (not vels.isEmpty()) - { - ret.vels = {vels[i]}; - } + // velocity is Angstroms per 1/20.455 ps + const auto vel_unit = (1.0 / 20.455) * angstrom / picosecond; - if (not current_time.isEmpty()) - { - ret.current_time = {current_time[i]}; + for (int i = 0; i < nats; ++i) + { + const Vector &vel = vels_data[i]; + velocities_data[i] = Velocity3D(vel.x() * vel_unit, vel.y() * vel_unit, vel.z() * vel_unit); + } } - if (not box_v1.isEmpty()) + // Convert the box vectors into a Space object. + SpacePtr space; + if (not this->box_v1.isEmpty() and not this->box_v2.isEmpty() and not this->box_v3.isEmpty()) { - ret.box_v1 = {box_v1[i]}; - } + Vector v1 = this->box_v1[i]; + Vector v2 = this->box_v2[i]; + Vector v3 = this->box_v3[i]; - if (not box_v2.isEmpty()) + if (v1.y() == 0 and v1.z() == 0 and v2.x() == 0 and v2.z() == 0 and v3.x() == 0 and v3.y() == 0) + { + // PeridicBox + space = SpacePtr(new PeriodicBox(Vector(v1.x(), v2.y(), v3.z()))); + } + else + { + // TriclinicBox + space = SpacePtr(new TriclinicBox(v1, v2, v3)); + } + } + else { - ret.box_v2 = {box_v2[i]}; + // no box information + space = SpacePtr(new Cartesian()); } - if (not box_v3.isEmpty()) + Time frame_time; + if (not this->current_time.isEmpty()) { - ret.box_v3 = {box_v3[i]}; + frame_time = this->current_time[i] * SireUnits::picosecond; } - ret.assertSane(); + return SireMol::Frame(frame_coords, frame_vels, space.read(), frame_time); +} - return ret; +/** Return the Gro87 object that contains only the information for the ith + frame. This allows you to extract and create a system for the ith frame + from a trajectory */ +Gro87 Gro87::operator[](int i) const +{ + throw SireError::unsupported( + QObject::tr("Gro87::operator[] is not yet implemented!"), CODELOC); } /** Return the parser that has been constructed by reading in the passed diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index 391bfeb36..a8f80aedf 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -25,6 +25,9 @@ organisation on `GitHub `__. * Add missing dihedrals for all 1-4 atom paths in ``Sire::MM::AmberParams::validateAndFix``, not just the first one found. +* Fix missing ``Sire::IO::Gro87::getFrame`` implementation to allow creation of + trajectory frames from GROMACS coordinate file data. + `2025.2.0 `__ - October 2025 --------------------------------------------------------------------------------------------