How to segment out only some bundles#
The pyAFQ software can be configured to find all of its default set of white matter pathways, or bundles. Alternatively, it can be configured to find only some bundles. This example shows how to track and recognize only certain bundles that you are interested in, though note that ARC, pARC and VOF are all also part of the set of bundles that are segmented per default.
import AFQ.api.bundle_dict as abd
import AFQ.data.fetch as afd
from AFQ.api.group import GroupAFQ
from AFQ.definitions.image import RoiImage
import AFQ.utils.streamlines as aus
import os.path as op
afd.organize_stanford_data(clear_previous_afq="track")
bundle_names = [
"Left Arcuate", "Right Arcuate",
"Left Posterior Arcuate", "Right Posterior Arcuate",
"Left Vertical Occipital", "Right Vertical Occipital"]
bundle_dict = abd.default_bd()[bundle_names]
myafq = GroupAFQ(
op.join(afd.afq_home, 'stanford_hardi'),
bundle_info=bundle_dict,
dwi_preproc_pipeline='vistasoft',
t1_preproc_pipeline='freesurfer',
tracking_params={
"n_seeds": 50000,
"random_seeds": True,
"seed_mask": RoiImage(use_waypoints=True, use_endpoints=True),
}
)
for b_name in bundle_names:
b_len = len(aus.SegmentedSFT.fromfile(myafq.export("bundles")[
"01"]).get_bundle(b_name))
if b_len < 1:
raise ValueError(f"{b_name} not found")
myafq.export("all_bundles_figure")["01"][0]
2026-05-19 01:02:59,739 INFO util.py:154 -- Missing packages: ['ipywidgets']. Run `pip install -U ipywidgets`, then restart the notebook server for rich notebook output.
INFO:bidsschematools:No schema path specified, defaulting to the bundled schema, `/opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/bidsschematools/data/schema.json`.
INFO:AFQ:Using the following files for subject 01 and session 01:
INFO:AFQ: DWI: /home/runner/AFQ_data/stanford_hardi/derivatives/vistasoft/sub-01/ses-01/dwi/sub-01_ses-01_dwi.nii.gz
INFO:AFQ: BVAL: /home/runner/AFQ_data/stanford_hardi/derivatives/vistasoft/sub-01/ses-01/dwi/sub-01_ses-01_dwi.bval
INFO:AFQ: BVEC: /home/runner/AFQ_data/stanford_hardi/derivatives/vistasoft/sub-01/ses-01/dwi/sub-01_ses-01_dwi.bvec
INFO:AFQ: T1: /home/runner/AFQ_data/stanford_hardi/derivatives/freesurfer/sub-01/ses-01/anat/sub-01_ses-01_T1w.nii.gz
WARNING:AFQ:It is recommended to provide CSF/GM/WM segmentations using PVEImage or PVEImages in AFQ.definitions.image. Otherwise, SynthSeg2 will be used
INFO:AFQ:Calculating _desc-bundles_tractography...
INFO:AFQ:Calculating _desc-seed_mask.nii.gz...
2026-05-19 01:03:07.250668081 [W:onnxruntime:Default, device_discovery.cc:133 GetPciBusId] Skipping pci_bus_id for PCI path at "/sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0004:00/MSFT1000:00/5620e0c7-8062-4dce-aeb7-520c7ef76171" because filename "5620e0c7-8062-4dce-aeb7-520c7ef76171" did not match expected pattern of [0-9a-f]+:[0-9a-f]+:[0-9a-f]+[.][0-9a-f]+
INFO:AFQ:Calculating affine pre-alignment...
---------------------------------------------------------------------------
KeyboardInterrupt Traceback (most recent call last)
Cell In[1], line 31
27 }
28 )
29
30 for b_name in bundle_names:
---> 31 b_len = len(aus.SegmentedSFT.fromfile(myafq.export("bundles")[
32 "01"]).get_bundle(b_name))
33
34 if b_len < 1:
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/AFQ/api/group.py:647, in GroupAFQ.export(self, attr_name, collapse)
645 to_calc_list.append((subject, session))
646 else:
--> 647 results[subject][session] = val_from_plan(plans_dict, attr_name)
649 # if some need to be calculated, do those in parallel
650 if to_calc_list:
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/AFQ/api/utils.py:146, in val_from_plan(plan, attr_name)
144 def val_from_plan(plan, attr_name):
145 try:
--> 146 return plan[attr_name]
147 except Exception as err:
148 current_err = err
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/pcollections/_lazy.py:381, in ldict.__getitem__(self, key)
379 v = pdict.__getitem__(self, key)
380 if isinstance(v, lazy):
--> 381 v = v()
382 return v
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/pcollections/_lazy.py:143, in lazy.__call__(self)
141 val = self.value
142 else:
--> 143 val = part()
144 # We've successfully calculated the value; set the members
145 # appropriately.
146 object.__setattr__(self, 'value', val)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:855, in plan._source_lookup(inputtup, calctup, src)
853 (cidx, oidx) = src
854 lazycalc = calctup[cidx]
--> 855 val = lazycalc()[oidx]
856 else:
857 val = inputtup[src]()
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/pcollections/_lazy.py:143, in lazy.__call__(self)
141 val = self.value
142 else:
--> 143 val = part()
144 # We've successfully calculated the value; set the members
145 # appropriately.
146 object.__setattr__(self, 'value', val)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:884, in plan._make_calctup.<locals>.<lambda>(c, args)
881 # We take advantage of Python's weak closures here:
882 calctup = ()
883 calctup = tuple(
--> 884 lazy(lambda c,args: f(inputtup, calctup, c, args), c, args)
885 for (c,args) in zip(calcdata.calcs, calcdata.args))
886 return calctup
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:873, in plan._call_calc(inputtup, calctup, c, args)
871 else:
872 kwargs[p.name] = arg
--> 873 r = c.eager_call(*args, **kwargs)
874 if is_amap(r):
875 return tuple(map(r.__getitem__, c.outputs))
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:448, in calc.eager_call(self, *args, **kwargs)
432 """Eagerly calls the given calculation using the arguments.
433
434 ``c.eager_call(...)`` returns the result of calling the calculation
(...) 444 calc.eager_mapcall, calc.lazy_call, calc.lazy_mapcall
445 """
446 # Now we just pass these arguments along (the function itself has been
447 # given the caching code via decorators already).
--> 448 res = self.function(*args, **kwargs)
449 # Now interpret the result.
450 outs = self.outputs
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/AFQ/tasks/decorators.py:104, in as_file.<locals>._as_file.<locals>.wrapper_as_file(*args, **kwargs)
101 logger.info(f"Calculating {calculation_name}...")
103 try:
--> 104 results = func(*args, **kwargs)
106 if len(output_specs) == 1:
107 results = [results]
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/AFQ/tasks/segmentation.py:56, in segment(structural_imap, data_imap, mapping_imap, tractography_imap, segmentation_params)
54 bundle_dict = data_imap["bundle_dict"]
55 reg_template = data_imap["reg_template"]
---> 56 streamlines = tractography_imap["streamlines"]
57 if (
58 streamlines.endswith(".trk")
59 or streamlines.endswith(".tck")
60 or streamlines.endswith(".vtk")
61 ):
62 tg = load_tractogram(streamlines, data_imap["dwi"], bbox_valid_check=False)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/pcollections/_lazy.py:381, in ldict.__getitem__(self, key)
379 v = pdict.__getitem__(self, key)
380 if isinstance(v, lazy):
--> 381 v = v()
382 return v
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/pcollections/_lazy.py:143, in lazy.__call__(self)
141 val = self.value
142 else:
--> 143 val = part()
144 # We've successfully calculated the value; set the members
145 # appropriately.
146 object.__setattr__(self, 'value', val)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:855, in plan._source_lookup(inputtup, calctup, src)
853 (cidx, oidx) = src
854 lazycalc = calctup[cidx]
--> 855 val = lazycalc()[oidx]
856 else:
857 val = inputtup[src]()
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/pcollections/_lazy.py:143, in lazy.__call__(self)
141 val = self.value
142 else:
--> 143 val = part()
144 # We've successfully calculated the value; set the members
145 # appropriately.
146 object.__setattr__(self, 'value', val)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:884, in plan._make_calctup.<locals>.<lambda>(c, args)
881 # We take advantage of Python's weak closures here:
882 calctup = ()
883 calctup = tuple(
--> 884 lazy(lambda c,args: f(inputtup, calctup, c, args), c, args)
885 for (c,args) in zip(calcdata.calcs, calcdata.args))
886 return calctup
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:868, in plan._call_calc(inputtup, calctup, c, args)
866 kwargs = {}
867 c = to_calc(c)
--> 868 for (p,arg) in zip(c.signature.parameters.values(), argvals):
869 if p.kind == p.POSITIONAL_ONLY:
870 args.append[arg]
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:855, in plan._source_lookup(inputtup, calctup, src)
853 (cidx, oidx) = src
854 lazycalc = calctup[cidx]
--> 855 val = lazycalc()[oidx]
856 else:
857 val = inputtup[src]()
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/pcollections/_lazy.py:143, in lazy.__call__(self)
141 val = self.value
142 else:
--> 143 val = part()
144 # We've successfully calculated the value; set the members
145 # appropriately.
146 object.__setattr__(self, 'value', val)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:884, in plan._make_calctup.<locals>.<lambda>(c, args)
881 # We take advantage of Python's weak closures here:
882 calctup = ()
883 calctup = tuple(
--> 884 lazy(lambda c,args: f(inputtup, calctup, c, args), c, args)
885 for (c,args) in zip(calcdata.calcs, calcdata.args))
886 return calctup
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:873, in plan._call_calc(inputtup, calctup, c, args)
871 else:
872 kwargs[p.name] = arg
--> 873 r = c.eager_call(*args, **kwargs)
874 if is_amap(r):
875 return tuple(map(r.__getitem__, c.outputs))
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:448, in calc.eager_call(self, *args, **kwargs)
432 """Eagerly calls the given calculation using the arguments.
433
434 ``c.eager_call(...)`` returns the result of calling the calculation
(...) 444 calc.eager_mapcall, calc.lazy_call, calc.lazy_mapcall
445 """
446 # Now we just pass these arguments along (the function itself has been
447 # given the caching code via decorators already).
--> 448 res = self.function(*args, **kwargs)
449 # Now interpret the result.
450 outs = self.outputs
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/AFQ/tasks/decorators.py:104, in as_file.<locals>._as_file.<locals>.wrapper_as_file(*args, **kwargs)
101 logger.info(f"Calculating {calculation_name}...")
103 try:
--> 104 results = func(*args, **kwargs)
106 if len(output_specs) == 1:
107 results = [results]
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/AFQ/definitions/image.py:402, in RoiImage.get_image_getter.<locals>._image_getter_helper(mapping_imap, data_imap, structural_imap, tissue_imap, segmentation_params)
398 bundle_dict = bundle_dict
400 for bundle_name in bundle_dict:
401 bundle_entry = bundle_dict.transform_rois(
--> 402 bundle_name, mapping_imap["mapping"], data_imap["dwi"]
403 )
404 rois = {}
405 if self.use_endpoints:
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/pcollections/_lazy.py:381, in ldict.__getitem__(self, key)
379 v = pdict.__getitem__(self, key)
380 if isinstance(v, lazy):
--> 381 v = v()
382 return v
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/pcollections/_lazy.py:143, in lazy.__call__(self)
141 val = self.value
142 else:
--> 143 val = part()
144 # We've successfully calculated the value; set the members
145 # appropriately.
146 object.__setattr__(self, 'value', val)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:855, in plan._source_lookup(inputtup, calctup, src)
853 (cidx, oidx) = src
854 lazycalc = calctup[cidx]
--> 855 val = lazycalc()[oidx]
856 else:
857 val = inputtup[src]()
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/pcollections/_lazy.py:143, in lazy.__call__(self)
141 val = self.value
142 else:
--> 143 val = part()
144 # We've successfully calculated the value; set the members
145 # appropriately.
146 object.__setattr__(self, 'value', val)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:884, in plan._make_calctup.<locals>.<lambda>(c, args)
881 # We take advantage of Python's weak closures here:
882 calctup = ()
883 calctup = tuple(
--> 884 lazy(lambda c,args: f(inputtup, calctup, c, args), c, args)
885 for (c,args) in zip(calcdata.calcs, calcdata.args))
886 return calctup
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:873, in plan._call_calc(inputtup, calctup, c, args)
871 else:
872 kwargs[p.name] = arg
--> 873 r = c.eager_call(*args, **kwargs)
874 if is_amap(r):
875 return tuple(map(r.__getitem__, c.outputs))
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/immlib/workflow/_core.py:448, in calc.eager_call(self, *args, **kwargs)
432 """Eagerly calls the given calculation using the arguments.
433
434 ``c.eager_call(...)`` returns the result of calling the calculation
(...) 444 calc.eager_mapcall, calc.lazy_call, calc.lazy_mapcall
445 """
446 # Now we just pass these arguments along (the function itself has been
447 # given the caching code via decorators already).
--> 448 res = self.function(*args, **kwargs)
449 # Now interpret the result.
450 outs = self.outputs
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/AFQ/tasks/mapping.py:132, in mapping(base_fname, dwi_data_file, reg_subject, data_imap, mapping_definition)
128 if not isinstance(mapping_definition, Definition):
129 raise TypeError(
130 "mapping must be a mapping defined" + " in `AFQ.definitions.mapping`"
131 )
--> 132 return mapping_definition.get_for_subses(
133 base_fname,
134 data_imap["dwi"],
135 dwi_data_file,
136 reg_subject,
137 reg_template,
138 tmpl_name,
139 )
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/AFQ/definitions/mapping.py:339, in SynMap.get_for_subses(self, base_fname, dwi, dwi_data_file, reg_subject, reg_template, tmpl_name, subject_sls, template_sls)
337 start_time = time()
338 if self.use_prealign:
--> 339 reg_prealign = self.prealign(reg_subject, reg_template)
340 else:
341 reg_prealign = None
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/AFQ/definitions/mapping.py:216, in GeneratedMapMixin.prealign(self, reg_subject, reg_template)
214 def prealign(self, reg_subject, reg_template):
215 logger.info("Calculating affine pre-alignment...")
--> 216 _, aff = affine_registration(reg_subject, reg_template, **self.affine_kwargs)
217 return aff
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/testing/decorators.py:201, in warning_for_keywords.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
194 # Check if the current version is within the warning range
195 if (
196 version.parse(from_version)
197 <= version.parse(current_version)
198 <= version.parse(until_version)
199 ):
200 # Convert positional to keyword arguments and issue a warning
--> 201 return convert_positional_to_keyword(func, args, kwargs)
203 # If the version is greater than the until_version,
204 # pass the arguments as they are
205 elif version.parse(current_version) > version.parse(until_version):
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/testing/decorators.py:192, in warning_for_keywords.<locals>.decorator.<locals>.wrapper.<locals>.convert_positional_to_keyword(func, args, kwargs)
182 warnings.warn(
183 f"Pass {positionally_passed_kwonly_args} as keyword args. "
184 f"From version {until_version} passing these as positional "
(...) 187 stacklevel=3,
188 )
190 return func(*positional_args, **corrected_kwargs)
--> 192 return func(*args, **kwargs)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/align/_public.py:599, in affine_registration(moving, static, moving_affine, static_affine, pipeline, starting_affine, metric, level_iters, sigmas, factors, ret_metric, moving_mask, static_mask, optimizer_options, **metric_kwargs)
597 else:
598 transform = _METHOD_DICT[func][1]()
--> 599 xform, xopt, fopt = affreg.optimize(
600 static,
601 moving,
602 transform,
603 None,
604 static_grid2world=static_affine,
605 moving_grid2world=moving_affine,
606 starting_affine=starting_affine,
607 ret_metric=True,
608 static_mask=static_mask,
609 moving_mask=moving_mask,
610 )
611 starting_affine = xform.affine
613 # Copy the final affine into a final variable
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/testing/decorators.py:201, in warning_for_keywords.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
194 # Check if the current version is within the warning range
195 if (
196 version.parse(from_version)
197 <= version.parse(current_version)
198 <= version.parse(until_version)
199 ):
200 # Convert positional to keyword arguments and issue a warning
--> 201 return convert_positional_to_keyword(func, args, kwargs)
203 # If the version is greater than the until_version,
204 # pass the arguments as they are
205 elif version.parse(current_version) > version.parse(until_version):
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/testing/decorators.py:192, in warning_for_keywords.<locals>.decorator.<locals>.wrapper.<locals>.convert_positional_to_keyword(func, args, kwargs)
182 warnings.warn(
183 f"Pass {positionally_passed_kwonly_args} as keyword args. "
184 f"From version {until_version} passing these as positional "
(...) 187 stacklevel=3,
188 )
190 return func(*positional_args, **corrected_kwargs)
--> 192 return func(*args, **kwargs)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/align/imaffine.py:1331, in AffineRegistration.optimize(***failed resolving arguments***)
1328 else:
1329 self.options["maxiter"] = max_iter
-> 1331 opt = Optimizer(
1332 self.metric.distance_and_gradient,
1333 self.params0,
1334 method=self.method,
1335 jac=True,
1336 options=self.options,
1337 )
1338 params = opt.xopt
1340 # Update starting_affine matrix with optimal parameters
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/testing/decorators.py:201, in warning_for_keywords.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
194 # Check if the current version is within the warning range
195 if (
196 version.parse(from_version)
197 <= version.parse(current_version)
198 <= version.parse(until_version)
199 ):
200 # Convert positional to keyword arguments and issue a warning
--> 201 return convert_positional_to_keyword(func, args, kwargs)
203 # If the version is greater than the until_version,
204 # pass the arguments as they are
205 elif version.parse(current_version) > version.parse(until_version):
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/testing/decorators.py:192, in warning_for_keywords.<locals>.decorator.<locals>.wrapper.<locals>.convert_positional_to_keyword(func, args, kwargs)
182 warnings.warn(
183 f"Pass {positionally_passed_kwonly_args} as keyword args. "
184 f"From version {until_version} passing these as positional "
(...) 187 stacklevel=3,
188 )
190 return func(*positional_args, **corrected_kwargs)
--> 192 return func(*args, **kwargs)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/core/optimize.py:164, in Optimizer.__init__(self, fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options, evolution)
148 res = minimize(
149 fun,
150 x0,
(...) 160 options=options,
161 )
163 else:
--> 164 res = minimize(
165 fun,
166 x0,
167 args,
168 method,
169 jac,
170 hess,
171 hessp,
172 bounds,
173 constraints,
174 tol,
175 callback,
176 options,
177 )
179 self.res = res
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/scipy/optimize/_minimize.py:784, in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
781 res = _minimize_newtoncg(fun, x0, args, jac, hess, hessp, callback,
782 **options)
783 elif meth == 'l-bfgs-b':
--> 784 res = _minimize_lbfgsb(fun, x0, args, jac, bounds,
785 callback=callback, **options)
786 elif meth == 'tnc':
787 res = _minimize_tnc(fun, x0, args, jac, bounds, callback=callback,
788 **options)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/scipy/optimize/_lbfgsb_py.py:469, in _minimize_lbfgsb(fun, x0, args, jac, bounds, disp, maxcor, ftol, gtol, eps, maxfun, maxiter, iprint, callback, maxls, finite_diff_rel_step, workers, **unknown_options)
461 _lbfgsb.setulb(m, x, low_bnd, upper_bnd, nbd, f, g, factr, pgtol, wa,
462 iwa, task, lsave, isave, dsave, maxls, ln_task)
464 if task[0] == 3:
465 # The minimization routine wants f and g at the current x.
466 # Note that interruptions due to maxfun are postponed
467 # until the completion of the current minimization iteration.
468 # Overwrite f and g:
--> 469 f, g = func_and_grad(x)
470 elif task[0] == 1:
471 # new iteration
472 n_iterations += 1
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/scipy/optimize/_differentiable_functions.py:412, in ScalarFunction.fun_and_grad(self, x)
410 if not np.array_equal(x, self.x):
411 self._update_x(x)
--> 412 self._update_fun()
413 self._update_grad()
414 return self.f, self.g
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/scipy/optimize/_differentiable_functions.py:362, in ScalarFunction._update_fun(self)
360 def _update_fun(self):
361 if not self.f_updated:
--> 362 fx = self._wrapped_fun(self.x)
363 self._nfev += 1
364 if fx < self._lowest_f:
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/scipy/_lib/_util.py:603, in _ScalarFunctionWrapper.__call__(self, x)
600 def __call__(self, x):
601 # Send a copy because the user may overwrite it.
602 # The user of this class might want `x` to remain unchanged.
--> 603 fx = self.f(np.copy(x), *self.args)
604 self.nfev += 1
606 # Make sure the function returns a true scalar
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/scipy/optimize/_optimize.py:80, in MemoizeJac.__call__(self, x, *args)
78 def __call__(self, x, *args):
79 """ returns the function value """
---> 80 self._compute_if_needed(x, *args)
81 return self._value
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/scipy/optimize/_optimize.py:74, in MemoizeJac._compute_if_needed(self, x, *args)
72 if not np.all(x == self.x) or self._value is None or self.jac is None:
73 self.x = np.asarray(x).copy()
---> 74 fg = self.fun(x, *args)
75 self.jac = fg[1]
76 self._value = fg[0]
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/align/imaffine.py:888, in MutualInformationMetric.distance_and_gradient(self, params)
868 r"""Numeric value of the metric and its gradient at given parameters.
869
870 Parameters
(...) 885
886 """
887 try:
--> 888 self._update_mutual_information(params, update_gradient=True)
889 except (AffineInversionError, AffineInvalidValuesError):
890 return np.inf, 0 * self.metric_grad
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/testing/decorators.py:201, in warning_for_keywords.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
194 # Check if the current version is within the warning range
195 if (
196 version.parse(from_version)
197 <= version.parse(current_version)
198 <= version.parse(until_version)
199 ):
200 # Convert positional to keyword arguments and issue a warning
--> 201 return convert_positional_to_keyword(func, args, kwargs)
203 # If the version is greater than the until_version,
204 # pass the arguments as they are
205 elif version.parse(current_version) > version.parse(until_version):
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/testing/decorators.py:192, in warning_for_keywords.<locals>.decorator.<locals>.wrapper.<locals>.convert_positional_to_keyword(func, args, kwargs)
182 warnings.warn(
183 f"Pass {positionally_passed_kwonly_args} as keyword args. "
184 f"From version {until_version} passing these as positional "
(...) 187 stacklevel=3,
188 )
190 return func(*positional_args, **corrected_kwargs)
--> 192 return func(*args, **kwargs)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/align/imaffine.py:769, in MutualInformationMetric._update_mutual_information(self, params, update_gradient)
765 self.affine_map.set_affine(current_affine)
767 # Update the histogram with the current joint intensities
768 static_values, moving_values, static_mask_values, moving_mask_values = (
--> 769 self._update_histogram()
770 )
772 H = self.histogram # Shortcut to `self.histogram`
773 grad = None # Buffer to write the MI gradient into (if needed)
File /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/dipy/align/imaffine.py:718, in MutualInformationMetric._update_histogram(self)
713 if self.moving_mask is not None:
714 moving_mask_values = self.affine_map.transform(
715 self.moving_mask, interpolation="nearest"
716 ).astype(np.int32)
--> 718 self.histogram.update_pdfs_dense(
719 static_values,
720 moving_values,
721 smask=self.static_mask,
722 mmask=moving_mask_values,
723 )
724 else: # Sparse case
725 sp_to_moving = self.moving_world2grid.dot(self.affine_map.affine)
KeyboardInterrupt: