Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ExpData __repr__ #1948

Merged
merged 12 commits into from
Jan 24, 2023
8 changes: 8 additions & 0 deletions python/sdist/amici/numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@ def __deepcopy__(self, memo):
other._cache = copy.deepcopy(self._cache)
return other

def __repr__(self):
"""
String representation of the object

:returns: string representation
"""
return f'{self.__class__.__name__}({self._swigptr})'
FFroehlich marked this conversation as resolved.
Show resolved Hide resolved


class ReturnDataView(SwigPtrView):
"""
Expand Down
29 changes: 24 additions & 5 deletions python/tests/test_swig_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,12 +406,31 @@ def test_model_instance_settings_custom_x0(pysb_example_presimulation_module):

def test_solver_repr():
for solver in (amici.CVodeSolver(), amici.IDASolver()):
assert "maxsteps" in str(solver)
assert "maxsteps" in repr(solver)

solver_ptr = amici.SolverPtr(solver.this)
assert "maxsteps" in str(solver_ptr)
assert "maxsteps" in repr(solver_ptr)
for s in (solver, solver_ptr):
assert "maxsteps" in str(s)
assert "maxsteps" in repr(s)
# avoid double delete!!
solver_ptr.release()


def test_edata_repr():
ny = 1
nz = 2
ne = 3
nt = 4
edata = amici.ExpData(ny, nz, ne, range(nt))
edata_ptr = amici.ExpDataPtr(edata.this)
expected_strs = (
f'{nt}x{ny} time-resolved datapoints',
f'{ne}x{nz} event-resolved datapoints',
f'(0/{ny * nt} measurements',
f'(0/{nz * ne} measurements'
)
for e in [edata, edata_ptr]:
for expected_str in expected_strs:
assert expected_str in str(e)
assert expected_str in repr(e)
# avoid double delete!!
edata_ptr.release()

76 changes: 76 additions & 0 deletions swig/edata.i
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,81 @@ using namespace amici;

%ignore ConditionContext;

// ExpData.__repr__
%pythoncode %{
def _edata_repr(self: "ExpData"):
n_data_y = sum(
self.isSetObservedData(it, iy)
for it in range(self.nt()) for
iy in range(self.nytrue())
)
n_sigma_y = sum(
self.isSetObservedDataStdDev(it, iy)
for it in range(self.nt())
for iy in range(self.nytrue())
)
n_data_z = sum(
self.isSetObservedEvents(ie, iz)
for ie in range(self.nmaxevent())
for iz in range(self.nztrue())
)
n_sigma_z = sum(
self.isSetObservedEventsStdDev(ie, iz)
for ie in range(self.nmaxevent())
for iz in range(self.nztrue())
)

custom_simulation_settings = []
if self.pscale:
custom_simulation_settings.append(f"parameter scales")
if self.fixedParameters:
custom_simulation_settings.append(f"constants")
if self.fixedParametersPreequilibration:
custom_simulation_settings.append(f"pre-equilibration condition")
if self.t_presim:
tmp = f"pre-simulation condition (t={self.t_presim})"
if self.fixedParametersPresimulation:
tmp += " with custom constants"
custom_simulation_settings.append(tmp)
if self.reinitializeFixedParameterInitialStates and self.reinitialization_state_idxs_sim:
custom_simulation_settings.append(f"{len(self.reinitialization_state_idxs_sim)} reinitialized states (simulation)")
if self.reinitializeFixedParameterInitialStates and self.reinitialization_state_idxs_presim:
custom_simulation_settings.append(f"{len(self.reinitialization_state_idxs_presim)} reinitialized states (presimulation)")
if self.parameters:
custom_simulation_settings.append(f"parameters")
if self.x0:
custom_simulation_settings.append(f"initial states")
if self.sx0:
custom_simulation_settings.append(f"initial state sensitivities")

if custom_simulation_settings:
custom_simulation_settings = " with custom " + ", ".join(custom_simulation_settings)
else:
custom_simulation_settings = " without custom settings"

return "\n".join([
self.this.__repr__()[:-1],
f" condition {id} starting at t={self.tstart_}" + custom_simulation_settings,
f" {self.nt()}x{self.nytrue()} time-resolved datapoints",
f" ({n_data_y}/{self.nt()*self.nytrue()} measurements & {n_sigma_y}/{self.nt()*self.nytrue()} sigmas set)",
f" {self.nmaxevent()}x{self.nztrue()} event-resolved datapoints",
f" ({n_data_z}/{self.nmaxevent()*self.nztrue()} measurements & {n_sigma_z}/{self.nmaxevent()*self.nztrue()} sigmas set)",
">"
FFroehlich marked this conversation as resolved.
Show resolved Hide resolved
])
%}
%extend amici::ExpData {
%pythoncode %{
def __repr__(self):
FFroehlich marked this conversation as resolved.
Show resolved Hide resolved
return _edata_repr(self)
%}
};
%extend std::unique_ptr<amici::ExpData> {
%pythoncode %{
def __repr__(self):
return _edata_repr(self)
%}
};


// Process symbols in header
%include "amici/edata.h"