Skip to content

Commit

Permalink
Fix Python WeightedProfileFitterChi.compute_score
Browse files Browse the repository at this point in the history
Fix the wrapper for compute_score so that it can be
used from Python. In Python, the determined weights
will be returned as a second return value, rather
than modifying a passed-in vector. Add a simple test.
  • Loading branch information
benmwebb committed Nov 21, 2024
1 parent 6758bca commit d97d4ea
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
16 changes: 16 additions & 0 deletions modules/saxs/include/WeightedProfileFitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ class WeightedProfileFitter : public ProfileFitter<ScoringFunctionT> {
Wb_ = W_.asDiagonal() * Wb_;
}

// When used from Python, compute_score will return the weights as a second
// return value, rather than modifying a passed-in vector
#ifdef SWIG
%typemap(in, numinputs=0) Vector<double>& weights (Vector<double> temp) {
$1 = &temp;
}
%typemap(argout) Vector<double>& weights {
PyObject *obj = ConvertSequence<Vector<double>, Convert<double>>::create_python_object(ValueOrObject<Vector<double>>::get(*$1), $descriptor(double*), SWIG_POINTER_OWN);
$result = SWIG_AppendOutput($result, obj);
}
#endif

//! compute a weighted score that minimizes chi
/**
it is assumed that the q values of the profiles are the same as
Expand All @@ -56,6 +68,10 @@ class WeightedProfileFitter : public ProfileFitter<ScoringFunctionT> {
double compute_score(const ProfilesTemp& profiles, Vector<double>& weights,
bool use_offset = false, bool NNLS = true) const;

#ifdef SWIG
%clear Vector<double>& weights;
#endif

//! fit profiles by optimization of c1/c2 and weights
/**
it is assumed that the q values of the profiles are the same as
Expand Down
13 changes: 13 additions & 0 deletions modules/saxs/test/test_weighted_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ def test_weighted_profile(self):
saxs_score = IMP.saxs.WeightedProfileFitterChi(weighted_profile)

profile_list = [resampled_profile1, resampled_profile2]
# Get score for single profile
score, weights = saxs_score.compute_score(profile_list[:1],
False, False)
self.assertAlmostEqual(score, 81.765, delta=0.001)
self.assertEqual(len(weights), 1)
self.assertAlmostEqual(weights[0], 1.0, delta=0.001)

# Get score for both profiles
score, weights = saxs_score.compute_score(profile_list, False, False)
self.assertAlmostEqual(score, 3.031, delta=0.001)
self.assertEqual(len(weights), 2)
self.assertAlmostEqual(weights[0], 0.297, delta=0.001)
self.assertAlmostEqual(weights[1], 0.703, delta=0.001)

wfp = saxs_score.fit_profile(profile_list, 0.95, 1.05, -2.0, 4.0)
chi = wfp.get_chi_square()
Expand Down

0 comments on commit d97d4ea

Please sign in to comment.