Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions corelib/src/libs/SireMol/molid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ QList<MolNum> MolIdx::map(const Molecules &molecules) const
molnums.append(it.key());
break;
}

--i;
}

BOOST_ASSERT(not molnums.isEmpty());
Expand Down
58 changes: 56 additions & 2 deletions corelib/src/libs/SireSearch/idengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
#include "SireBase/booleanproperty.h"
#include "SireBase/parallel.h"

#include "SireMol/atomelements.h"
#include "SireMol/atomcoords.h"
#include "SireMol/atomelements.h"
#include "SireMol/core.h"
#include "SireMol/iswater.h"

Expand Down Expand Up @@ -1155,9 +1155,63 @@ SelectResult IDIndexEngine::searchMolIdx(const SelectResult &mols, const SelectR
{
QList<Molecule> matches;

int idx = 0;
int count = context.listCount();

if (_is_single_value(this->vals))
{
// For a single index value, apply Python-style negative-index mapping
// and do a strict bounds check. Out-of-bounds returns no match,
// consistent with residx/atomidx behaviour.
// We read the raw start value from RangeValue directly, bypassing the
// _to_single_value helper which maps against INT_MAX and corrupts
// negative indices.
auto rv = boost::get<RangeValue>(this->vals[0]);

if (not rv.start)
return SelectResult(matches);

int v = *rv.start;

if (v < 0)
v = count + v;

if (v < 0 or v >= count)
return SelectResult(matches);

int idx = 0;

for (const auto &mol : context)
{
if (idx == v)
{
if (&mols == &context)
{
matches.append(mol->molecule());
}
else
{
const auto molnum = mol->data().number();

for (const auto &m : mols)
{
if (m->data().number() == molnum)
{
matches.append(m->molecule());
break;
}
}
}
break;
}

idx += 1;
}

return SelectResult(matches);
}

int idx = 0;

for (const auto &mol : context)
{
if (this->match(idx, count))
Expand Down
4 changes: 4 additions & 0 deletions doc/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ organisation on `GitHub <https://github.com/openbiosim/sire>`__.

* Map the end-state ``element`` property when performing hydrogen mass repartitioning on perturbable molecules.

* Fixed out-of-bounds ``molidx`` searches silently returning the last molecule instead of
raising a ``KeyError``. Out-of-bounds positive and negative single-index values now
behave consistently with ``residx`` and ``atomidx``.

`2025.4.0 <https://github.com/openbiosim/sire/compare/2025.3.0...2025.4.0>`__ - February 2026
---------------------------------------------------------------------------------------------

Expand Down