Skip to content

Commit 4537409

Browse files
authored
Merge pull request #513 from cloudx123789/cloudx123789/fix-blr-transfer-unboundlocalerror
fix: define y for unwarped BLR.transfer()
2 parents 962e260 + 100d0de commit 4537409

3 files changed

Lines changed: 52 additions & 6 deletions

File tree

pcntoolkit/regression_model/blr.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,8 @@ def transfer(
461461

462462
if self.warp:
463463
y = self.warp.f(Y.values, self.gamma)
464+
else:
465+
y = Y.values
464466

465467
transfered_model = copy.deepcopy(self)
466468
transfered_model.correction_coefficients = {}

test/fixtures/blr_model_fixtures.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def savemodel():
4242

4343
@pytest.fixture
4444
def blr_model_factory() -> Callable:
45-
"""Allow tests to build BLR models with custom overrides. By default,
45+
"""Allow tests to build BLR models with custom overrides. By default,
4646
the factory builds a BLR with the settings in BLR_BASE_CONFIG.
4747
4848
Examples

test/test_norm/test_normative_model_transfer.py

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1+
import os
12
import re
3+
import shutil
4+
from collections.abc import Callable
25

36
import pytest
47

58
from pcntoolkit.dataio.norm_data import NormData
69
from pcntoolkit.normative_model import NormativeModel
710
from pcntoolkit.util.output import Output, Warnings
8-
from test.fixtures.blr_model_fixtures import * # noqa: F401,F403
9-
from test.fixtures.data_fixtures import * # noqa: F401,F403
10-
from test.fixtures.norm_data_fixtures import * # noqa: F401,F403
11-
from test.fixtures.path_fixtures import * # noqa: F401,F403
11+
from test.fixtures.blr_model_fixtures import *
12+
from test.fixtures.data_fixtures import *
13+
from test.fixtures.norm_data_fixtures import *
14+
from test.fixtures.path_fixtures import *
1215

1316
"""
1417
Tests for NormativeModel.transfer()
@@ -25,7 +28,7 @@ def transfer_norm_data_1be(
2528
n_response_vars: int,
2629
batch_effect_values: list[list[int]],
2730
) -> NormData:
28-
"""Build a transfer NormData with 1 batch effect column which is fewer
31+
"""Build a transfer NormData with 1 batch effect column which is fewer
2932
than the training data that has 2.
3033
3134
Parameters
@@ -126,3 +129,44 @@ def test_003_transfer_should_warn_when_fewerBatchEffects(
126129
fitted_norm_blr_model.transfer(
127130
transfer_norm_data_1be,
128131
)
132+
133+
134+
def test_004_transfer_should_fit_when_unwarped(
135+
blr_model_factory: Callable,
136+
save_dir_blr: str,
137+
norm_data_from_arrays: NormData,
138+
transfer_norm_data_from_arrays: NormData,
139+
) -> None:
140+
"""Transfer must succeed for a BLR model with no warp function.
141+
142+
Regression test for #437: BLR.transfer() raised UnboundLocalError
143+
when self.warp was None, because y was only assigned inside the
144+
`if self.warp:` branch.
145+
146+
Parameters
147+
----------
148+
blr_model_factory : Callable
149+
Fixture that builds BLR models with optional overrides.
150+
save_dir_blr : str
151+
Save directory for BLR tests. The fixture selects the temp dir,
152+
otherwise NormativeModel will save to its default directory.
153+
norm_data_from_arrays : NormData
154+
Training dataset.
155+
transfer_norm_data_from_arrays : NormData
156+
Transfer dataset.
157+
"""
158+
blr_model = blr_model_factory(warp_name=None)
159+
if os.path.exists(save_dir_blr):
160+
shutil.rmtree(save_dir_blr)
161+
os.makedirs(save_dir_blr, exist_ok=True)
162+
model = NormativeModel(
163+
blr_model,
164+
save_dir=save_dir_blr,
165+
inscaler="standardize",
166+
outscaler="standardize",
167+
)
168+
model.fit(norm_data_from_arrays)
169+
170+
transferred = model.transfer(transfer_norm_data_from_arrays)
171+
172+
assert transferred.is_fitted

0 commit comments

Comments
 (0)